OILS / core / util.py View on Github | oilshell.org

161 lines, 80 significant
1#t!/usr/bin/env python2
2# Copyright 2016 Andy Chu. All rights reserved.
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8"""
9util.py - Common infrastructure.
10"""
11from __future__ import print_function
12
13from core import ansi
14from core import pyutil
15from mycpp import mylib
16
17import libc
18
19from typing import List
20
21
22def RegexGroups(s, indices):
23 # type: (str, List[int]) -> List[str]
24 groups = [] # type: List[str]
25 n = len(indices)
26 for i in xrange(n / 2):
27 start = indices[2 * i]
28 end = indices[2 * i + 1]
29 if start == -1:
30 groups.append(None)
31 else:
32 groups.append(s[start:end])
33 return groups
34
35
36def simple_regex_search(pat, s):
37 # type: (str, str) -> List[str]
38 """Convenience wrapper around libc."""
39 indices = libc.regex_search(pat, 0, s, 0)
40 if indices is None:
41 return None
42 return RegexGroups(s, indices)
43
44
45class UserExit(Exception):
46 """For explicit 'exit'."""
47
48 def __init__(self, status):
49 # type: (int) -> None
50 self.status = status
51
52
53class HistoryError(Exception):
54
55 def __init__(self, msg):
56 # type: (str) -> None
57 self.msg = msg
58
59 def UserErrorString(self):
60 # type: () -> str
61 return 'history: %s' % self.msg
62
63
64class _DebugFile(object):
65
66 def __init__(self):
67 # type: () -> None
68 pass
69
70 def write(self, s):
71 # type: (str) -> None
72 pass
73
74 def writeln(self, s):
75 # type: (str) -> None
76 pass
77
78 def isatty(self):
79 # type: () -> bool
80 return False
81
82
83class NullDebugFile(_DebugFile):
84
85 def __init__(self):
86 # type: () -> None
87 """Empty constructor for mycpp."""
88 _DebugFile.__init__(self)
89
90
91class DebugFile(_DebugFile):
92 """Trivial wrapper with writeln() method
93
94 Can we turn this into a plain mylib::File? Right now that type only exists
95 in C++, but it should probably exist in Python too.
96 """
97
98 def __init__(self, f):
99 # type: (mylib.Writer) -> None
100 _DebugFile.__init__(self)
101 self.f = f
102
103 def write(self, s):
104 # type: (str) -> None
105 """Used by dev::Tracer and ASDL node.PrettyPrint()."""
106 self.f.write(s)
107
108 def writeln(self, s):
109 # type: (str) -> None
110 self.write(s + '\n')
111 self.f.flush()
112
113 def isatty(self):
114 # type: () -> bool
115 """Used by node.PrettyPrint()."""
116 return self.f.isatty()
117
118
119def PrintTopicHeader(topic_id, f):
120 # type: (str, mylib.Writer) -> None
121 if f.isatty():
122 f.write('%s %s %s\n' % (ansi.REVERSE, topic_id, ansi.RESET))
123 else:
124 f.write('~~~ %s ~~~\n' % topic_id)
125
126 f.write('\n')
127
128
129def PrintEmbeddedHelp(loader, topic_id, f):
130 # type: (pyutil._ResourceLoader, str, mylib.Writer) -> bool
131 try:
132 contents = loader.Get('_devbuild/help/%s' % topic_id)
133 except (IOError, OSError):
134 return False
135
136 PrintTopicHeader(topic_id, f)
137 f.write(contents)
138 f.write('\n')
139 return True # found
140
141
142def _PrintVersionLine(loader, f):
143 # type: (pyutil._ResourceLoader, mylib.Writer) -> None
144 v = pyutil.GetVersion(loader)
145 f.write('Oils %s\t\thttps://www.oilshell.org/\n' % v)
146
147
148def HelpFlag(loader, topic_id, f):
149 # type: (pyutil._ResourceLoader, str, mylib.Writer) -> None
150 _PrintVersionLine(loader, f)
151 f.write('\n')
152 found = PrintEmbeddedHelp(loader, topic_id, f)
153 # Note: could assert this in C++ too
154 assert found, 'Missing %s' % topic_id
155
156
157def VersionFlag(loader, f):
158 # type: (pyutil._ResourceLoader, mylib.Writer) -> None
159 _PrintVersionLine(loader, f)
160 f.write('\n')
161 pyutil.PrintVersionDetails(loader)