/home/andy/git/oilshell/oil/mycpp/leaky_mylib.h
Line | Count | Source (jump to first uncovered line) |
1 | | #ifndef LEAKY_MYLIB_H |
2 | | #define LEAKY_MYLIB_H |
3 | | |
4 | | template <class K, class V> |
5 | | class Dict; |
6 | | |
7 | | // https://stackoverflow.com/questions/3919995/determining-sprintf-buffer-size-whats-the-standard/11092994#11092994 |
8 | | // Notes: |
9 | | // - Python 2.7's intobject.c has an erroneous +6 |
10 | | // - This is 13, but len('-2147483648') is 11, which means we only need 12? |
11 | | // - This formula is valid for octal(), because 2^(3 bits) = 8 |
12 | | |
13 | | const int kIntBufSize = CHAR_BIT * sizeof(int) / 3 + 3; |
14 | | |
15 | | template <typename K, typename V> |
16 | | void dict_remove(Dict<K, V>* haystack, K needle); |
17 | | |
18 | | namespace mylib { |
19 | | |
20 | | Tuple2<Str*, Str*> split_once(Str* s, Str* delim); |
21 | | |
22 | | // Used by generated _build/cpp/osh_eval.cc |
23 | 0 | inline Str* StrFromC(const char* s) { |
24 | 0 | return ::StrFromC(s); |
25 | 0 | } |
26 | | |
27 | | template <typename K, typename V> |
28 | 1 | void dict_remove(Dict<K, V>* haystack, K needle) { |
29 | 1 | ::dict_remove(haystack, needle); |
30 | 1 | } _ZN5mylib11dict_removeIP3StriEEvP4DictIT_T0_ES4_ Line | Count | Source | 28 | 1 | void dict_remove(Dict<K, V>* haystack, K needle) { | 29 | 1 | ::dict_remove(haystack, needle); | 30 | 1 | } |
Unexecuted instantiation: _ZN5mylib11dict_removeIP3StrS2_EEvP4DictIT_T0_ES4_ |
31 | | |
32 | | // NOTE: Can use OverAllocatedStr for all of these, rather than copying |
33 | | |
34 | 4 | inline Str* hex_lower(int i) { |
35 | 4 | char buf[kIntBufSize]; |
36 | 4 | int len = snprintf(buf, kIntBufSize, "%x", i); |
37 | 4 | return ::StrFromC(buf, len); |
38 | 4 | } |
39 | | |
40 | 4 | inline Str* hex_upper(int i) { |
41 | 4 | char buf[kIntBufSize]; |
42 | 4 | int len = snprintf(buf, kIntBufSize, "%X", i); |
43 | 4 | return ::StrFromC(buf, len); |
44 | 4 | } |
45 | | |
46 | 4 | inline Str* octal(int i) { |
47 | 4 | char buf[kIntBufSize]; |
48 | 4 | int len = snprintf(buf, kIntBufSize, "%o", i); |
49 | 4 | return ::StrFromC(buf, len); |
50 | 4 | } |
51 | | |
52 | | class LineReader : Obj { |
53 | | public: |
54 | | // Abstract type with no fields: unknown size |
55 | | LineReader(uint16_t field_mask, int obj_len) |
56 | 5 | : Obj(Tag::FixedSize, field_mask, obj_len) { |
57 | 5 | } |
58 | | virtual Str* readline() = 0; |
59 | 1 | virtual bool isatty() { |
60 | 1 | return false; |
61 | 1 | } |
62 | 0 | virtual int fileno() { |
63 | 0 | NotImplemented(); // Uncalled |
64 | 0 | } |
65 | | }; |
66 | | |
67 | | class BufLineReader : public LineReader { |
68 | | public: |
69 | | explicit BufLineReader(Str* s); |
70 | | virtual Str* readline(); |
71 | | |
72 | | Str* s_; |
73 | | int pos_; |
74 | | |
75 | | DISALLOW_COPY_AND_ASSIGN(BufLineReader) |
76 | | }; |
77 | | |
78 | 1 | constexpr uint16_t maskof_BufLineReader() { |
79 | 1 | return maskbit_v(offsetof(BufLineReader, s_)); |
80 | 1 | } |
81 | | |
82 | | inline BufLineReader::BufLineReader(Str* s) |
83 | | : LineReader(maskof_BufLineReader(), sizeof(BufLineReader)), |
84 | | s_(s), |
85 | 1 | pos_(0) { |
86 | 1 | } |
87 | | |
88 | | // Wrap a FILE* |
89 | | class CFileLineReader : public LineReader { |
90 | | public: |
91 | | explicit CFileLineReader(FILE* f); |
92 | | virtual Str* readline(); |
93 | 1 | virtual int fileno() { |
94 | 1 | return ::fileno(f_); |
95 | 1 | } |
96 | | |
97 | | private: |
98 | | FILE* f_; |
99 | | |
100 | | DISALLOW_COPY_AND_ASSIGN(CFileLineReader) |
101 | | }; |
102 | | |
103 | | inline CFileLineReader::CFileLineReader(FILE* f) |
104 | 4 | : LineReader(kZeroMask, sizeof(CFileLineReader)), f_(f) { |
105 | 4 | } |
106 | | |
107 | | extern LineReader* gStdin; |
108 | | |
109 | 1 | inline LineReader* Stdin() { |
110 | 1 | if (gStdin == nullptr) { |
111 | 1 | gStdin = Alloc<CFileLineReader>(stdin); |
112 | 1 | } |
113 | 1 | return gStdin; |
114 | 1 | } |
115 | | |
116 | | LineReader* open(Str* path); |
117 | | |
118 | | class Writer : public Obj { |
119 | | public: |
120 | | Writer(uint8_t heap_tag, uint16_t field_mask, int obj_len) |
121 | 77 | : Obj(heap_tag, field_mask, obj_len) { |
122 | 77 | } |
123 | | virtual void write(Str* s) = 0; |
124 | | virtual void flush() = 0; |
125 | | virtual bool isatty() = 0; |
126 | | }; |
127 | | |
128 | | class BufWriter : public Writer { |
129 | | public: |
130 | | BufWriter() |
131 | | : Writer(Tag::FixedSize, kZeroMask, sizeof(BufWriter)), |
132 | | data_(nullptr), |
133 | 73 | len_(0) { |
134 | 73 | } |
135 | | void write(Str* s) override; |
136 | 0 | void flush() override { |
137 | 0 | } |
138 | 0 | bool isatty() override { |
139 | 0 | return false; |
140 | 0 | } |
141 | | // For cStringIO API |
142 | | Str* getvalue(); |
143 | | |
144 | | // Methods to compile printf format strings to |
145 | | |
146 | | // Called before reusing the global gBuf instance for fmtX() functions |
147 | | // |
148 | | // Problem with globals: '%r' % obj will recursively call asdl/format.py, |
149 | | // which has its own % operations |
150 | 642 | void reset() { |
151 | 642 | if (data_) { |
152 | 326 | free(data_); |
153 | 326 | } |
154 | 642 | data_ = nullptr; // arg to next realloc() |
155 | 642 | len_ = 0; |
156 | 642 | } |
157 | | |
158 | | // Note: we do NOT need to instantiate a Str() to append |
159 | | void write_const(const char* s, int len); |
160 | | |
161 | | // strategy: snprintf() based on sizeof(int) |
162 | | void format_d(int i); |
163 | | void format_o(int i); |
164 | | void format_s(Str* s); |
165 | | void format_r(Str* s); // formats with quotes |
166 | | |
167 | | // looks at arbitrary type tags? Is this possible |
168 | | // Passes "this" to functions generated by ASDL? |
169 | | void format_r(void* s); |
170 | | |
171 | | private: |
172 | | // Just like a string, except it's mutable |
173 | | char* data_; |
174 | | int len_; |
175 | | }; |
176 | | |
177 | | // Wrap a FILE* |
178 | | class CFileWriter : public Writer { |
179 | | public: |
180 | | explicit CFileWriter(FILE* f) |
181 | 4 | : Writer(Tag::FixedSize, kZeroMask, sizeof(BufWriter)), f_(f) { |
182 | 4 | } |
183 | | void write(Str* s) override; |
184 | | void flush() override; |
185 | | bool isatty() override; |
186 | | |
187 | | private: |
188 | | FILE* f_; |
189 | | |
190 | | DISALLOW_COPY_AND_ASSIGN(CFileWriter) |
191 | | }; |
192 | | |
193 | | extern Writer* gStdout; |
194 | | |
195 | 11 | inline Writer* Stdout() { |
196 | 11 | if (gStdout == nullptr) { |
197 | 4 | gStdout = Alloc<CFileWriter>(stdout); |
198 | 4 | } |
199 | 11 | return gStdout; |
200 | 11 | } |
201 | | |
202 | | extern Writer* gStderr; |
203 | | |
204 | 0 | inline Writer* Stderr() { |
205 | 0 | if (gStderr == nullptr) { |
206 | 0 | gStderr = Alloc<CFileWriter>(stderr); |
207 | 0 | } |
208 | 0 | return gStderr; |
209 | 0 | } |
210 | | |
211 | | } // namespace mylib |
212 | | |
213 | | extern mylib::BufWriter gBuf; |
214 | | |
215 | | #endif // LEAKY_MYLIB_H |