cpp

Coverage Report

Created: 2022-07-20 01:16

/home/uke/oil/mycpp/mylib2.h
Line
Count
Source (jump to first uncovered line)
1
// mylib2.h
2
//
3
// Rewrites of mylib.py in C++.
4
// TODO: Remove mylib.{h,cc}, and make this the main copy.
5
6
#ifndef MYLIB2_H
7
#define MYLIB2_H
8
9
#include "gc_heap.h"
10
#include "my_runtime.h"  // Tuple2
11
12
using gc_heap::Alloc;
13
using gc_heap::kZeroMask;
14
using gc_heap::maskbit;
15
using gc_heap::maskbit_v;
16
using gc_heap::StackRoots;
17
18
namespace mylib {
19
20
Tuple2<Str*, Str*> split_once(Str* s, Str* delim);
21
22
template <typename V>
23
0
void dict_remove(Dict<Str*, V>* haystack, Str* needle) {
24
0
  int pos = haystack->position_of_key(needle);
25
0
  if (pos == -1) {
26
0
    return;
27
0
  }
28
0
  haystack->entry_->items_[pos] = gc_heap::kDeletedEntry;
29
  // Zero out for GC.  These could be nullptr or 0
30
0
  haystack->keys_->items_[pos] = 0;
31
0
  haystack->values_->items_[pos] = 0;
32
0
  haystack->len_--;
33
0
}
Unexecuted instantiation: _ZN5mylib11dict_removeIiEEvPN7gc_heap4DictIPNS1_3StrET_EES4_
Unexecuted instantiation: _ZN5mylib11dict_removeIPN7gc_heap3StrEEEvPNS1_4DictIS3_T_EES3_
34
35
// These 3 functions use a static buffer first because we don't know what n is
36
// until we call snprintf().
37
38
4
inline Str* hex_lower(int i) {
39
4
  char buf[kIntBufSize];
40
4
  int length = snprintf(buf, kIntBufSize, "%x", i);
41
4
  return CopyStr(buf, length);
42
4
}
43
44
4
inline Str* hex_upper(int i) {
45
4
  char buf[kIntBufSize];
46
4
  int length = snprintf(buf, kIntBufSize, "%X", i);
47
4
  return CopyStr(buf, length);
48
4
}
49
50
4
inline Str* octal(int i) {
51
4
  char buf[kIntBufSize];
52
4
  int length = snprintf(buf, kIntBufSize, "%o", i);
53
4
  return CopyStr(buf, length);
54
4
}
55
56
class LineReader : gc_heap::Obj {
57
 public:
58
  // Abstract type with no fields: unknown size
59
  LineReader(uint16_t field_mask, int obj_len)
60
5
      : gc_heap::Obj(Tag::FixedSize, field_mask, obj_len) {
61
5
  }
62
  virtual Str* readline() = 0;
63
1
  virtual bool isatty() {
64
1
    return false;
65
1
  }
66
0
  virtual int fileno() {
67
0
    NotImplemented();  // Uncalled
68
0
  }
69
};
70
71
class BufLineReader : public LineReader {
72
 public:
73
  explicit BufLineReader(Str* s);
74
  virtual Str* readline();
75
76
  Str* s_;
77
  int pos_;
78
79
  DISALLOW_COPY_AND_ASSIGN(BufLineReader)
80
};
81
82
1
constexpr uint16_t maskof_BufLineReader() {
83
1
  return maskbit_v(offsetof(BufLineReader, s_));
84
1
}
85
86
inline BufLineReader::BufLineReader(Str* s)
87
    : LineReader(maskof_BufLineReader(), sizeof(BufLineReader)),
88
      s_(s),
89
1
      pos_(0) {
90
1
}
91
92
// Wrap a FILE*
93
class CFileLineReader : public LineReader {
94
 public:
95
  explicit CFileLineReader(FILE* f);
96
  virtual Str* readline();
97
1
  virtual int fileno() {
98
1
    return ::fileno(f_);
99
1
  }
100
101
 private:
102
  FILE* f_;
103
104
  DISALLOW_COPY_AND_ASSIGN(CFileLineReader)
105
};
106
107
inline CFileLineReader::CFileLineReader(FILE* f)
108
4
    : LineReader(kZeroMask, sizeof(CFileLineReader)), f_(f) {
109
4
}
110
111
extern LineReader* gStdin;
112
113
1
inline LineReader* Stdin() {
114
1
  if (gStdin == nullptr) {
115
1
    gStdin = new CFileLineReader(stdin);
116
1
  }
117
1
  return gStdin;
118
1
}
119
120
2
inline LineReader* open(Str* path) {
121
2
  StackRoots _roots({&path});
122
123
2
  FILE* f = fopen(path->data_, "r");
124
125
  // TODO: Better error checking.  IOError?
126
2
  if (!f) {
127
0
    throw new AssertionError("file not found");
128
0
  }
129
2
  return Alloc<CFileLineReader>(f);
130
2
}
131
132
class Writer : public gc_heap::Obj {
133
 public:
134
  Writer(uint8_t heap_tag, uint16_t field_mask, int obj_len)
135
61
      : gc_heap::Obj(heap_tag, field_mask, obj_len) {
136
61
  }
137
  virtual void write(Str* s) = 0;
138
  virtual void flush() = 0;
139
  virtual bool isatty() = 0;
140
};
141
142
class BufWriter : public Writer {
143
 public:
144
  BufWriter()
145
      : Writer(Tag::FixedSize, gc_heap::kZeroMask, sizeof(BufWriter)),
146
        data_(nullptr),
147
60
        len_(0) {
148
60
  }
149
  virtual void write(Str* s) override;
150
0
  virtual void flush() override {
151
0
  }
152
0
  virtual bool isatty() override {
153
0
    return false;
154
0
  }
155
  // For cStringIO API
156
317
  Str* getvalue() {
157
317
    if (data_) {
158
317
      Str* ret = gc_heap::CopyStr(data_, len_);
159
317
      reset();  // Invalidate this instance
160
317
      return ret;
161
317
    } else {
162
      // log('') translates to this
163
      // Strings are immutable so we can do this.
164
0
      return gc_heap::kEmptyString;
165
0
    }
166
317
  }
167
168
  // Methods to compile printf format strings to
169
170
  // To reuse the global gBuf instance
171
  // problem: '%r' % obj will recursively call asdl/format.py, which has its
172
  // own % operations
173
610
  void reset() {
174
610
    data_ = nullptr;  // make sure we get a new buffer next time
175
610
    len_ = 0;
176
610
  }
177
178
  // Note: we do NOT need to instantiate a Str() to append
179
  void write_const(const char* s, int len);
180
181
  // strategy: snprintf() based on sizeof(int)
182
  void format_d(int i);
183
  void format_s(Str* s);
184
  void format_r(Str* s);  // formats with quotes
185
186
  // looks at arbitrary type tags?  Is this possible
187
  // Passes "this" to functions generated by ASDL?
188
  void format_r(void* s);
189
190
 private:
191
  // Just like a string, except it's mutable
192
  char* data_;
193
  int len_;
194
};
195
196
// Wrap a FILE*
197
class CFileWriter : public Writer {
198
 public:
199
  explicit CFileWriter(FILE* f)
200
4
      : Writer(Tag::FixedSize, gc_heap::kZeroMask, sizeof(BufWriter)), f_(f) {
201
4
  }
202
  virtual void write(Str* s) override;
203
  virtual void flush() override;
204
  virtual bool isatty() override;
205
206
 private:
207
  FILE* f_;
208
209
  DISALLOW_COPY_AND_ASSIGN(CFileWriter)
210
};
211
212
extern Writer* gStdout;
213
214
11
inline Writer* Stdout() {
215
11
  if (gStdout == nullptr) {
216
4
    gStdout = new CFileWriter(stdout);
217
4
  }
218
11
  return gStdout;
219
11
}
220
221
extern Writer* gStderr;
222
223
0
inline Writer* Stderr() {
224
0
  if (gStderr == nullptr) {
225
0
    gStderr = new CFileWriter(stderr);
226
0
  }
227
0
  return gStderr;
228
0
}
229
230
}  // namespace mylib
231
232
// Global formatter
233
extern mylib::BufWriter gBuf;
234
235
#endif  // MYLIB2_H