cpp

Coverage Report

Created: 2022-11-10 11:34

/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
2
inline Str* hex_lower(int i) {
35
2
  char buf[kIntBufSize];
36
2
  int len = snprintf(buf, kIntBufSize, "%x", i);
37
2
  return ::StrFromC(buf, len);
38
2
}
39
40
2
inline Str* hex_upper(int i) {
41
2
  char buf[kIntBufSize];
42
2
  int len = snprintf(buf, kIntBufSize, "%X", i);
43
2
  return ::StrFromC(buf, len);
44
2
}
45
46
2
inline Str* octal(int i) {
47
2
  char buf[kIntBufSize];
48
2
  int len = snprintf(buf, kIntBufSize, "%o", i);
49
2
  return ::StrFromC(buf, len);
50
2
}
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
40
      : Obj(heap_tag, field_mask, obj_len) {
122
40
  }
123
  virtual void write(Str* s) = 0;
124
  virtual void flush() = 0;
125
  virtual bool isatty() = 0;
126
};
127
128
class Buf;  // forward declaration
129
130
Str* StrFromBuf(const Buf&);
131
Buf* NewBuf(int);
132
133
constexpr uint16_t maskof_BufWriter();
134
135
class BufWriter : public Writer {
136
 public:
137
36
  BufWriter() : Writer(Tag::FixedSize, maskof_BufWriter(), sizeof(BufWriter)) {
138
36
  }
139
  void write(Str* s) override;
140
0
  void flush() override {
141
0
  }
142
0
  bool isatty() override {
143
0
    return false;
144
0
  }
145
  // For cStringIO API
146
  Str* getvalue();
147
148
 private:
149
  friend constexpr uint16_t maskof_BufWriter();
150
  Buf* EnsureCapacity(int n);
151
152
  Buf* buf_ = nullptr;
153
  bool is_valid_ = true;  // It becomes invalid after getvalue() is called
154
};
155
156
36
constexpr uint16_t maskof_BufWriter() {
157
  // maskvit_v() because BufWriter has virtual methods
158
36
  return maskbit_v(offsetof(BufWriter, buf_));
159
36
}
160
161
class FormatStringer {
162
 public:
163
39
  FormatStringer() : data_(nullptr), len_(0) {
164
39
  }
165
  Str* getvalue();
166
167
  // Called before reusing the global gBuf instance for fmtX() functions
168
  //
169
  // Problem with globals: '%r' % obj will recursively call asdl/format.py,
170
  // which has its own % operations
171
648
  void reset() {
172
648
    if (data_) {
173
317
      free(data_);
174
317
    }
175
648
    data_ = nullptr;  // arg to next realloc()
176
648
    len_ = 0;
177
648
  }
178
179
  // Note: we do NOT need to instantiate a Str() to append
180
  void write_const(const char* s, int len);
181
182
  // strategy: snprintf() based on sizeof(int)
183
  void format_d(int i);
184
  void format_o(int i);
185
  void format_s(Str* s);
186
  void format_r(Str* s);  // formats with quotes
187
188
  // looks at arbitrary type tags?  Is this possible
189
  // Passes "this" to functions generated by ASDL?
190
  void format_r(void* s);
191
192
 private:
193
  // Just like a string, except it's mutable
194
  char* data_;
195
  int len_;
196
};
197
198
// Wrap a FILE*
199
class CFileWriter : public Writer {
200
 public:
201
  explicit CFileWriter(FILE* f)
202
4
      : Writer(Tag::FixedSize, kZeroMask, sizeof(BufWriter)), f_(f) {
203
4
  }
204
  void write(Str* s) override;
205
  void flush() override;
206
  bool isatty() override;
207
208
 private:
209
  FILE* f_;
210
211
  DISALLOW_COPY_AND_ASSIGN(CFileWriter)
212
};
213
214
extern Writer* gStdout;
215
216
11
inline Writer* Stdout() {
217
11
  if (gStdout == nullptr) {
218
    // TODO: global instance needs rooting
219
4
    gStdout = Alloc<CFileWriter>(stdout);
220
4
  }
221
11
  return gStdout;
222
11
}
223
224
extern Writer* gStderr;
225
226
0
inline Writer* Stderr() {
227
0
  if (gStderr == nullptr) {
228
0
    // TODO: global instance needs rooting
229
0
    gStderr = Alloc<CFileWriter>(stderr);
230
0
  }
231
0
  return gStderr;
232
0
}
233
234
}  // namespace mylib
235
236
extern mylib::FormatStringer gBuf;
237
238
#endif  // LEAKY_MYLIB_H