mycpp-examples

Coverage Report

Created: 2022-07-15 02:23

/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
void dict_remove(Dict<Str*, V>* haystack, Str* needle) {
24
  int pos = haystack->position_of_key(needle);
25
  if (pos == -1) {
26
    return;
27
  }
28
  haystack->entry_->items_[pos] = gc_heap::kDeletedEntry;
29
  // Zero out for GC.  These could be nullptr or 0
30
  haystack->keys_->items_[pos] = 0;
31
  haystack->values_->items_[pos] = 0;
32
  haystack->len_--;
33
}
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
0
inline Str* hex_lower(int i) {
39
0
  char buf[kIntBufSize];
40
0
  int length = snprintf(buf, kIntBufSize, "%x", i);
41
0
  return CopyStr(buf, length);
42
0
}
43
44
0
inline Str* hex_upper(int i) {
45
0
  char buf[kIntBufSize];
46
0
  int length = snprintf(buf, kIntBufSize, "%X", i);
47
0
  return CopyStr(buf, length);
48
0
}
49
50
0
inline Str* octal(int i) {
51
0
  char buf[kIntBufSize];
52
0
  int length = snprintf(buf, kIntBufSize, "%o", i);
53
0
  return CopyStr(buf, length);
54
0
}
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
0
      : gc_heap::Obj(Tag::FixedSize, field_mask, obj_len) {
61
0
  }
62
  virtual Str* readline() = 0;
63
0
  virtual bool isatty() {
64
0
    return false;
65
0
  }
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
0
constexpr uint16_t maskof_BufLineReader() {
83
0
  return maskbit_v(offsetof(BufLineReader, s_));
84
0
}
85
86
inline BufLineReader::BufLineReader(Str* s)
87
    : LineReader(maskof_BufLineReader(), sizeof(BufLineReader)),
88
      s_(s),
89
      pos_(0) {
90
}
91
92
// Wrap a FILE*
93
class CFileLineReader : public LineReader {
94
 public:
95
  explicit CFileLineReader(FILE* f);
96
  virtual Str* readline();
97
0
  virtual int fileno() {
98
0
    return ::fileno(f_);
99
0
  }
100
101
 private:
102
  FILE* f_;
103
104
  DISALLOW_COPY_AND_ASSIGN(CFileLineReader)
105
};
106
107
inline CFileLineReader::CFileLineReader(FILE* f)
108
    : LineReader(kZeroMask, sizeof(CFileLineReader)), f_(f) {
109
}
110
111
extern LineReader* gStdin;
112
113
0
inline LineReader* Stdin() {
114
0
  if (gStdin == nullptr) {
115
0
    gStdin = new CFileLineReader(stdin);
116
0
  }
117
0
  return gStdin;
118
0
}
119
120
0
inline LineReader* open(Str* path) {
121
0
  StackRoots _roots({&path});
122
0
123
0
  FILE* f = fopen(path->data_, "r");
124
0
125
0
  // TODO: Better error checking.  IOError?
126
0
  if (!f) {
127
0
    throw new AssertionError("file not found");
128
0
  }
129
0
  return Alloc<CFileLineReader>(f);
130
0
}
131
132
class Writer : public gc_heap::Obj {
133
 public:
134
  Writer(uint8_t heap_tag, uint16_t field_mask, int obj_len)
135
58
      : gc_heap::Obj(heap_tag, field_mask, obj_len) {
136
58
  }
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
55
        len_(0) {
148
55
  }
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
3
      : Writer(Tag::FixedSize, gc_heap::kZeroMask, sizeof(BufWriter)), f_(f) {
201
3
  }
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
10
inline Writer* Stdout() {
215
10
  if (gStdout == nullptr) {
216
3
    gStdout = new CFileWriter(stdout);
217
3
  }
218
10
  return gStdout;
219
10
}
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