cpp

Coverage Report

Created: 2022-09-21 22:22

/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