rapidyaml 0.15.2
parse and emit YAML, and do it fast
Loading...
Searching...
No Matches
quickstart-ints.cpp File Reference

Go to the source code of this file.

Classes

struct  IntsResult
struct  IntsParser
struct  Args

Functions

void print_usage (c4::csubstr basename)
bool parse_args (int argc, const char **argv, Args *args, int &status)
int main (int argc, const char *argv[])

Function Documentation

◆ print_usage()

void print_usage ( c4::csubstr basename)

Definition at line 96 of file quickstart-ints.cpp.

97{
98 Args defaults = {};
99 printf(R"(usage: %.*s [options] [<filename>]
100
101 if filename is missing, we default to a preset example.
102
103options:
104
105 -e <size>,--events-size <size> set size of events buffer. -1 means

Referenced by main().

◆ parse_args()

bool parse_args ( int argc,
const char ** argv,
Args * args,
int & status )

Definition at line 106 of file quickstart-ints.cpp.

117 : "do not retry",
118 defaults.quiet ? "quiet" : "print events");
119}
120bool parse_args(int argc, const char **argv, Args *args, int &status)
121{
122 c4::csubstr basename = argv[0];
123 // read left-to-right until we find an arg that is not an option
124 int remaining = argc - 1;
125 ++argv;
126 auto advance = [&](int num) { argv += num; remaining -= num; };
127 auto parse_arg = [&](const char *name, int *dst) {
128 if(remaining > 1)
129 {
130 c4::csubstr val = argv[1];
131 if(!c4::atoi(val, dst))
132 {
133 status = -1;
134 printf("error: could not parse %s value: %.*s\n", name, static_cast<int>(val.len), val.str);
135 }
136 advance(2);
137 }
138 else
139 {
140 status = -1;
141 printf("error: missing value: %s\n", name);
142 }
143 return true;
144 };
145 while(remaining > 0 && status == 0)
146 {
147 c4::csubstr arg = argv[0];
148 if(arg == "-h" || arg == "--help")
149 {
150 print_usage(basename);
151 status = 0;
152 return false;
153 }
154 else if(arg == "-e" || arg == "--events-size")
155 {
156 parse_arg("--events-size", &args->events_size);
157 }
158 else if(arg == "-a" || arg == "--arena-size")
159 {
160 parse_arg("--arena-size", &args->arena_size);
161 }
162 else if(arg == "-n" || arg == "--no-retry")
163 {
164 args->retry = false;
165 advance(1);
166 }
167 else if(arg == "-q" || arg == "--quiet")
168 {
169 args->quiet = false;
170 advance(1);
171 }
172 else
173 break;
bool atoi(csubstr str, T *v) noexcept
Convert a trimmed string to a signed integral value.
basic_substring< const char > csubstr
an immutable string view
Definition substr.hpp:2356
void print_usage(c4::csubstr basename)
bool parse_args(int argc, const char **argv, Args *args, int &status)
int events_size
size_t len
the length of the substring
Definition substr.hpp:218
C * str
a restricted pointer to the first character of the substring
Definition substr.hpp:216

◆ main()

int main ( int argc,
const char * argv[] )

Definition at line 180 of file quickstart-ints.cpp.

181 {
182 print_usage(basename);
183 printf("error: too many arguments\n");
184 status = -1;
185 }
186 return status == 0;
187}
188
189
190//-----------------------------------------------------------------------------
191
192// NOLINTBEGIN(hicpp-signed-bitwise)
193
194int main(int argc, const char *argv[])
195{
196 Args args = {};
197 int status = 0;
198 if(!parse_args(argc, argv, &args, status))
199 return status;
200
201 // if no filename is given, we run a demo,
202 // and show the result is as expected.
203 bool is_demo = args.filename == nullptr;
204
205 // YAML code to be parsed in place
206 char demo_yaml[] = ""
207 "doe: a deer, a female deer\n"
208 "ray: a drop of golden sun\n"
209 "me : a name I call myself\n"
210 "far: a long long way to run\n"
211 "";
212
213 // these are the events we expect from parsing the demo YAML
214 auto STR = c4::yml::extra::ievt::PSTR; // PSTR does not work in windows
215 const int demo_expected[] = {
216 BSTR,
217 BDOC,
218 VAL_|BMAP|BLCK,
219 KEY_|SCLR|PLAI, 0, 3, // "doe"
220 VAL_|SCLR|PLAI|STR, 5, 21, // "a deer, a female deer"
221 KEY_|SCLR|PLAI|STR, 27, 3, // "ray"
222 VAL_|SCLR|PLAI|STR, 32, 20, // "a drop of golden sun"
223 KEY_|SCLR|PLAI|STR, 53, 2, // "me"
224 VAL_|SCLR|PLAI|STR, 58, 20, // "a name I call myself"
225 KEY_|SCLR|PLAI|STR, 79, 3, // "far"
226 VAL_|SCLR|PLAI|STR, 84, 22, // "a long long way to run"
227 EMAP|STR,
228 EDOC,
229 ESTR,
230 };
231
232 /* the output should be this:
233 *
234 * pos=0 event[0]: BSTR = 0x00000001
235 * pos=1 event[1]: BDOC = 0x00000004
236 * pos=2 event[2]: VAL_|BMAP|BLCK = 0x00140010
237 * pos=3 event[3]: KEY_|SCLR|PLAI = 0x00081100 str=(0,3) 'doe'
238 * pos=6 event[4]: VAL_|SCLR|PLAI|PSTR = 0x04101100 str=(5,21) 'a deer, a female deer'
239 * pos=9 event[5]: KEY_|SCLR|PLAI|PSTR = 0x04081100 str=(27,3) 'ray'
240 * pos=12 event[6]: VAL_|SCLR|PLAI|PSTR = 0x04101100 str=(32,20) 'a drop of golden sun'
241 * pos=15 event[7]: KEY_|SCLR|PLAI|PSTR = 0x04081100 str=(53,2) 'me'
242 * pos=18 event[8]: VAL_|SCLR|PLAI|PSTR = 0x04101100 str=(58,20) 'a name I call myself'
243 * pos=21 event[9]: KEY_|SCLR|PLAI|PSTR = 0x04081100 str=(79,3) 'far'
244 * pos=24 event[10]: VAL_|SCLR|PLAI|PSTR = 0x04101100 str=(84,22) 'a long long way to run'
245 * pos=27 event[11]: EMAP|PSTR = 0x04000020
246 * pos=28 event[12]: EDOC = 0x00000008
247 * pos=29 event[13]: ESTR = 0x00000002
248 */
249
250 IntsParser parser;
251 IntsResult result;
252
253 const char *filename = args.filename;
254 std::vector<char> yaml_file;
255 c4::substr yaml;
256
257 if(is_demo)
258 {
259 yaml = demo_yaml;
260 filename = "demo";
261 }
262 else
263 {
264 c4::csubstr filename_ = c4::to_csubstr(filename);
265 if(filename_ == "-" || filename_ == "stdin")
266 c4::yml::stdin_get_contents(&yaml_file); // LCOV_EXCL_LINE lcov fail
267 else
268 c4::yml::file_get_contents(&yaml_file, args.filename);
269 yaml = c4::to_substr(yaml_file);
270 }
271
272 if(args.events_size == -1)
274 if(args.arena_size == -1)
275 args.arena_size = static_cast<int>(yaml.size());
276
277 result.resize_buffers(args.events_size, static_cast<size_t>(args.arena_size));
278
279 // parse now. since we did not set up the error callbacks, if
280 // there is a parse error, we will get the default behavior, which
281 // is abort on error
282 if( ! args.retry)
283 {
284 if( ! parser.parse_in_place(filename, yaml, &result))
285 return 1;
286 }
287 else
288 {
289 if( ! parser.parse_or_resize_and_then_parse(filename, yaml, &result))
290 return 1; // this is really not expected LCOV_EXCL_LINE
291 }
292
293 if( ! is_demo)
294 {
295 if( ! args.quiet)
296 {
297 c4::csubstr actual_buffer = args.retry ? yaml : c4::to_csubstr(result.yaml);
299 result.events.data(),
300 static_cast<c4::yml::extra::evt_size>(result.events.size()));
301 }
302 return 0;
303 }
304
305 // we have the demo. ensure the result is as expected
306 bool success = true;
307
308 // example iterating through the events array: compare and print
309 // the result
310 char flags[100]; // buffer for converting event flags to string
311 for (size_t pos = 0, evt = 0, sz = static_cast<size_t>(parser.handler.required_size_events());
312 pos < sz;
313 ++pos, ++evt)
314 {
315 bool ok = (result.events[pos] == demo_expected[pos]);
316 // print the event
317 if( ! args.quiet)
318 {
319 // let's format the event flags to print them as string.
320 size_t len = c4::yml::extra::ievt::to_str(flags, result.events[pos]);
321 printf("pos=%zu\tevent[%zu]:\t%.*s = 0x%08x", pos, evt, static_cast<int>(len), flags, result.events[pos]);
322 }
323 if(result.events[pos] & WSTR) // the event has a string following it
324 {
325 int offset = result.events[pos + 1];
326 int length = result.events[pos + 2];
327 bool in_arena = (result.events[pos] & AREN);
328 // WATCHOUT! the string is NOT ZERO TERMINATED!
329 const char *ptr = in_arena ? result.arena.data() : yaml.str;
330 const char *str = ptr + offset;
331 if( ! args.quiet)
332 printf("\tstr=(%d,%d)\t'%.*s'", offset, length, length, str);
333 ok = ok && (offset == demo_expected[pos + 1]);
334 ok = ok && (length == demo_expected[pos + 2]);
int32_t evt_size
data type for integer events size.
void events_ints_print(csubstr parsed_yaml, csubstr arena, ievt::evt_bits const *evts, ievt::evt_bits evts_sz)
Print integer events to stdout.
evt_size estimate_events_ints_size(csubstr src)
Read YAML source and, without undergoing a full parse, estimate the size of the integer buffer requir...
void file_get_contents(const char *filename, FILE *fp, size_t filesz, void *buf, size_t bufsz)
load a file of specified size from disk into an existing contiguous buffer.
Definition file.hpp:106
void stdin_get_contents(ContiguousContainer *cont, FILE *f=stdin)
load a file from stdin (or similar stream-like file) and return a newly created ContiguousContainer w...
Definition file.hpp:193
substr to_substr(char(&s)[N]) noexcept
Definition substr.hpp:2376
csubstr to_csubstr(const char(&s)[N]) noexcept
Definition substr.hpp:2380
basic_substring< char > substr
a mutable string view
Definition substr.hpp:2355
size_t to_str(substr buf, ievt::evt_bits flags) noexcept
Convert bit mask of ievt::EventBits to text.
@ PSTR
Special flag to enable look-back in the event array. It signifies that the previous event has a strin...
@ SCLR
scalar (=VAL in test suite events)
@ EMAP
end map (-MAP in test suite events)
@ BMAP
begin map (+MAP in test suite events)
@ ESTR
end stream (-STR in test suite events)
@ BSTR
begin stream (+STR in test suite events)
@ WSTR
WithSTRing: mask of all events that encode a string following the event. For such events,...
@ BDOC
begin doc (+DOC in test suite events)
@ AREN
Special flag to mark events whose string was placed in the arena. This happens when the filtered stri...
@ EDOC
end doc (-DOC in test suite events)
int main(int argc, const char *argv[])
const char * filename
bool parse_in_place(const char *filename, c4::substr yaml, IntsResult *result)
c4::yml::extra::EventHandlerInts handler
bool parse_or_resize_and_then_parse(const char *filename, c4::csubstr yaml, IntsResult *result)
std::vector< char > yaml
source buffer
std::vector< evt_bits > events
result buffer with events
std::vector< char > arena
arena to place out-of-source filtered scalars or tags
void resize_buffers(c4::yml::extra::evt_size esz, size_t arena_size)
size_t size() const noexcept
Definition substr.hpp:358
evt_size required_size_events() const
get the size needed for the event buffer from the previous parse