rapidyaml  0.16.0
parseandemitYAML,anddoitfast
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

void print_usage ( c4::csubstr  basename)

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

Referenced by parse_args().

97 {
98  Args defaults = {};
99  printf(R"(usage: %.*s [options] [<filename>]
100 
101  if filename is missing, we default to a preset example.
102 
103 options:
104 
105  -e <size>,--events-size <size> set size of events buffer. -1 means
106  estimate size. default=%d
107  -a <size>,--arena-size <size> set size of arena buffer. -1 means
108  take the source size as the arena size.
109  default=%d
110  -n,--no-retry do not retry parsing if any buffer size
111  was insufficient. default=%s
112  -q,--quiet do not print events. default=%s
113 )",
114  static_cast<int>(basename.len), basename.str,
115  defaults.events_size,
116  defaults.arena_size,
117  defaults.retry ? "retry" : "do not retry",
118  defaults.quiet ? "quiet" : "print events");
119 }
C * str
a restricted pointer to the first character of the substring
Definition: substr.hpp:216
bool quiet
size_t len
the length of the substring
Definition: substr.hpp:218
int arena_size
int events_size
bool retry
bool parse_args ( int  argc,
const char **  argv,
Args *  args,
int &  status 
)

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

Referenced by main().

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;
174  }
175  if(remaining == 1)
176  {
177  if(status == 0)
178  args->filename = argv[0];
179  }
180  else if(remaining > 1)
181  {
182  print_usage(basename);
183  printf("error: too many arguments\n");
184  status = -1;
185  }
186  return status == 0;
187 }
C * str
a restricted pointer to the first character of the substring
Definition: substr.hpp:216
bool quiet
bool atoi(csubstr str, T *v) noexcept
Convert a trimmed string to a signed integral value.
Definition: charconv.hpp:1466
size_t len
the length of the substring
Definition: substr.hpp:218
const char * filename
int arena_size
int events_size
void print_usage(c4::csubstr basename)
bool retry
int main ( int  argc,
const char *  argv[] 
)

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

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 
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]);
335  pos += 2; // advance the two ints from the string
336  }
337  if(!ok)
338  {
339  if( ! args.quiet) // LCOV_EXCL_LINE
340  printf(" ... fail!"); // LCOV_EXCL_LINE
341  success = false; // LCOV_EXCL_LINE
342  }
343  if( ! args.quiet) // LCOV_EXCL_LINE
344  printf("\n");
345  }
346 
347  return success ? 0 : 1;
348 }
begin doc (+DOC in test suite events)
std::vector< evt_bits > events
result buffer with events
bool parse_in_place(const char *filename, c4::substr yaml, IntsResult *result)
c4::yml::extra::EventHandlerInts handler
WithSTRing: mask of all events that encode a string following the event. For such events...
C * str
a restricted pointer to the first character of the substring
Definition: substr.hpp:216
EventBits flags
Definition: ints_utils.cpp:27
substr to_substr(char(&s)[N]) noexcept
Definition: substr.hpp:2376
const char * str
Definition: node_type.cpp:70
size_t to_str(substr buf, ievt::evt_bits flags) noexcept
Convert bit mask of ievt::EventBits to text.
Definition: ints_utils.cpp:60
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
evt_size required_size_events() const
get the size needed for the event buffer from the previous parse
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 events_ints_print(csubstr parsed_yaml, csubstr arena, ievt::evt_bits const *evts, ievt::evt_bits evts_sz)
Print integer events to stdout.
Definition: ints_utils.cpp:103
size_t size() const noexcept
Definition: substr.hpp:358
Special flag to enable look-back in the event array. It signifies that the previous event has a strin...
std::vector< char > arena
arena to place out-of-source filtered scalars or tags
csubstr to_csubstr(const char(&s)[N]) noexcept
Definition: substr.hpp:2380
Parser parser
Definition: parse.cpp:117
bool quiet
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 resize_buffers(c4::yml::extra::evt_size esz, size_t arena_size)
end stream (-STR in test suite events)
const char * filename
int32_t evt_size
data type for integer events size.
int arena_size
end doc (-DOC in test suite events)
int events_size
begin map (+MAP in test suite events)
bool parse_or_resize_and_then_parse(const char *filename, c4::csubstr yaml, IntsResult *result)
Special flag to mark events whose string was placed in the arena. This happens when the filtered stri...
std::vector< char > yaml
source buffer
bool retry
scalar (=VAL in test suite events)
end map (-MAP in test suite events)
bool parse_args(int argc, const char **argv, Args *args, int &status)
begin stream (+STR in test suite events)