This is Unofficial EPICS BASE Doxygen Site
yajl_lex.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2007-2011, Lloyd Hilaiel <lloyd@hilaiel.com>
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <assert.h>
20 #include <string.h>
21 
22 #include "yajl_lex.h"
23 #include "yajl_buf.h"
24 
25 #ifdef YAJL_LEXER_DEBUG
26 static const char *
27 tokToStr(yajl_tok tok)
28 {
29  switch (tok) {
30  case yajl_tok_bool: return "bool";
31  case yajl_tok_colon: return "colon";
32  case yajl_tok_comma: return "comma";
33  case yajl_tok_eof: return "eof";
34  case yajl_tok_error: return "error";
35  case yajl_tok_left_brace: return "brace";
36  case yajl_tok_left_bracket: return "bracket";
37  case yajl_tok_null: return "null";
38  case yajl_tok_integer: return "integer";
39  case yajl_tok_double: return "double";
40  case yajl_tok_right_brace: return "brace";
41  case yajl_tok_right_bracket: return "bracket";
42  case yajl_tok_string: return "string";
43  case yajl_tok_string_with_escapes: return "string_with_escapes";
44  }
45  return "unknown";
46 }
47 #endif
48 
49 /* Impact of the stream parsing feature on the lexer:
50  *
51  * YAJL support stream parsing. That is, the ability to parse the first
52  * bits of a chunk of JSON before the last bits are available (still on
53  * the network or disk). This makes the lexer more complex. The
54  * responsibility of the lexer is to handle transparently the case where
55  * a chunk boundary falls in the middle of a token. This is
56  * accomplished is via a buffer and a character reading abstraction.
57  *
58  * Overview of implementation
59  *
60  * When we lex to end of input string before end of token is hit, we
61  * copy all of the input text composing the token into our lexBuf.
62  *
63  * Every time we read a character, we do so through the readChar function.
64  * readChar's responsibility is to handle pulling all chars from the buffer
65  * before pulling chars from input text
66  */
67 
68 struct yajl_lexer_t {
69  /* the overal line and char offset into the data */
70  size_t lineOff;
71  size_t charOff;
72 
73  /* error */
75 
76  /* a input buffer to handle the case where a token is spread over
77  * multiple chunks */
79 
80  /* in the case where we have data in the lexBuf, bufOff holds
81  * the current offset into the lexBuf. */
82  size_t bufOff;
83 
84  /* are we using the lex buf? */
85  unsigned int bufInUse;
86 
87  /* shall we allow comments? */
88  unsigned int allowComments;
89 
90  /* shall we validate utf8 inside strings? */
91  unsigned int validateUTF8;
92 
94 };
95 
96 #define readChar(lxr, txt, off) \
97  (((lxr)->bufInUse && yajl_buf_len((lxr)->buf) && lxr->bufOff < yajl_buf_len((lxr)->buf)) ? \
98  (*((const unsigned char *) yajl_buf_data((lxr)->buf) + ((lxr)->bufOff)++)) : \
99  ((txt)[(*(off))++]))
100 
101 #define unreadChar(lxr, off) ((*(off) > 0) ? (*(off))-- : ((lxr)->bufOff--))
102 
105  unsigned int allowComments, unsigned int validateUTF8)
106 {
107  yajl_lexer lxr = (yajl_lexer) YA_MALLOC(alloc, sizeof(struct yajl_lexer_t));
108  if (lxr == NULL) {
109  return NULL;
110  }
111 
112  memset((void *) lxr, 0, sizeof(struct yajl_lexer_t));
113  lxr->buf = yajl_buf_alloc(alloc);
115  lxr->validateUTF8 = validateUTF8;
116  lxr->alloc = alloc;
117  return lxr;
118 }
119 
120 void
122 {
123  yajl_buf_free(lxr->buf);
124  YA_FREE(lxr->alloc, lxr);
125  return;
126 }
127 
128 /* a lookup table which lets us quickly determine three things:
129  * VEC - valid escaped control char
130  * note. the solidus '/' may be escaped or not.
131  * IJC - invalid json char
132  * VHC - valid hex char
133  * NFP - needs further processing (from a string scanning perspective)
134  * NUC - needs utf8 checking when enabled (from a string scanning perspective)
135  */
136 #define VEC 0x01
137 #define IJC 0x02
138 #define VHC 0x04
139 #define NFP 0x08
140 #define NUC 0x10
141 
142 static const char charLookupTable[256] =
143 {
144 /*00*/ IJC , IJC , IJC , IJC , IJC , IJC , IJC , IJC ,
145 /*08*/ IJC , IJC , IJC , IJC , IJC , IJC , IJC , IJC ,
146 /*10*/ IJC , IJC , IJC , IJC , IJC , IJC , IJC , IJC ,
147 /*18*/ IJC , IJC , IJC , IJC , IJC , IJC , IJC , IJC ,
148 
149 /*20*/ 0 , 0 , NFP|VEC|IJC, 0 , 0 , 0 , 0 , 0 ,
150 /*28*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , VEC ,
151 /*30*/ VHC , VHC , VHC , VHC , VHC , VHC , VHC , VHC ,
152 /*38*/ VHC , VHC , 0 , 0 , 0 , 0 , 0 , 0 ,
153 
154 /*40*/ 0 , VHC , VHC , VHC , VHC , VHC , VHC , 0 ,
155 /*48*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
156 /*50*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
157 /*58*/ 0 , 0 , 0 , 0 , NFP|VEC|IJC, 0 , 0 , 0 ,
158 
159 /*60*/ 0 , VHC , VEC|VHC, VHC , VHC , VHC , VEC|VHC, 0 ,
160 /*68*/ 0 , 0 , 0 , 0 , 0 , 0 , VEC , 0 ,
161 /*70*/ 0 , 0 , VEC , 0 , VEC , 0 , 0 , 0 ,
162 /*78*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
163 
164  NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
165  NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
166  NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
167  NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
168 
169  NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
170  NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
171  NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
172  NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
173 
174  NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
175  NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
176  NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
177  NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
178 
179  NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
180  NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
181  NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC ,
182  NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC
183 };
184 
196 #define UTF8_CHECK_EOF if (*offset >= jsonTextLen) { return yajl_tok_eof; }
197 
198 static yajl_tok
199 yajl_lex_utf8_char(yajl_lexer lexer, const unsigned char * jsonText,
200  size_t jsonTextLen, size_t * offset,
201  unsigned char curChar)
202 {
203  if (curChar <= 0x7f) {
204  /* single byte */
205  return yajl_tok_string;
206  } else if ((curChar >> 5) == 0x6) {
207  /* two byte */
209  curChar = readChar(lexer, jsonText, offset);
210  if ((curChar >> 6) == 0x2) return yajl_tok_string;
211  } else if ((curChar >> 4) == 0x0e) {
212  /* three byte */
214  curChar = readChar(lexer, jsonText, offset);
215  if ((curChar >> 6) == 0x2) {
217  curChar = readChar(lexer, jsonText, offset);
218  if ((curChar >> 6) == 0x2) return yajl_tok_string;
219  }
220  } else if ((curChar >> 3) == 0x1e) {
221  /* four byte */
223  curChar = readChar(lexer, jsonText, offset);
224  if ((curChar >> 6) == 0x2) {
226  curChar = readChar(lexer, jsonText, offset);
227  if ((curChar >> 6) == 0x2) {
229  curChar = readChar(lexer, jsonText, offset);
230  if ((curChar >> 6) == 0x2) return yajl_tok_string;
231  }
232  }
233  }
234 
235  return yajl_tok_error;
236 }
237 
238 /* lex a string. input is the lexer, pointer to beginning of
239  * json text, and start of string (offset).
240  * a token is returned which has the following meanings:
241  * yajl_tok_string: lex of string was successful. offset points to
242  * terminating '"'.
243  * yajl_tok_eof: end of text was encountered before we could complete
244  * the lex.
245  * yajl_tok_error: embedded in the string were unallowable chars. offset
246  * points to the offending char
247  */
248 #define STR_CHECK_EOF \
249 if (*offset >= jsonTextLen) { \
250  tok = yajl_tok_eof; \
251  goto finish_string_lex; \
252 }
253 
258 static size_t
259 yajl_string_scan(const unsigned char * buf, size_t len, int utf8check)
260 {
261  unsigned char mask = IJC|NFP|(utf8check ? NUC : 0);
262  size_t skip = 0;
263  while (skip < len && !(charLookupTable[*buf] & mask))
264  {
265  skip++;
266  buf++;
267  }
268  return skip;
269 }
270 
271 static yajl_tok
272 yajl_lex_string(yajl_lexer lexer, const unsigned char * jsonText,
273  size_t jsonTextLen, size_t * offset)
274 {
275  yajl_tok tok = yajl_tok_error;
276  int hasEscapes = 0;
277 
278  for (;;) {
279  unsigned char curChar;
280 
281  /* now jump into a faster scanning routine to skip as much
282  * of the buffers as possible */
283  {
284  const unsigned char * p;
285  size_t len;
286 
287  if ((lexer->bufInUse && yajl_buf_len(lexer->buf) &&
288  lexer->bufOff < yajl_buf_len(lexer->buf)))
289  {
290  p = ((const unsigned char *) yajl_buf_data(lexer->buf) +
291  (lexer->bufOff));
292  len = yajl_buf_len(lexer->buf) - lexer->bufOff;
293  lexer->bufOff += yajl_string_scan(p, len, lexer->validateUTF8);
294  }
295  else if (*offset < jsonTextLen)
296  {
297  p = jsonText + *offset;
298  len = jsonTextLen - *offset;
299  *offset += yajl_string_scan(p, len, lexer->validateUTF8);
300  }
301  }
302 
304 
305  curChar = readChar(lexer, jsonText, offset);
306 
307  /* quote terminates */
308  if (curChar == '"') {
309  tok = yajl_tok_string;
310  break;
311  }
312  /* backslash escapes a set of control chars, */
313  else if (curChar == '\\') {
314  hasEscapes = 1;
316 
317  /* special case \u */
318  curChar = readChar(lexer, jsonText, offset);
319  if (curChar == 'u') {
320  unsigned int i = 0;
321 
322  for (i=0;i<4;i++) {
324  curChar = readChar(lexer, jsonText, offset);
325  if (!(charLookupTable[curChar] & VHC)) {
326  /* back up to offending char */
327  unreadChar(lexer, offset);
329  goto finish_string_lex;
330  }
331  }
332  } else if (!(charLookupTable[curChar] & VEC)) {
333  /* back up to offending char */
334  unreadChar(lexer, offset);
336  goto finish_string_lex;
337  }
338  }
339  /* when not validating UTF8 it's a simple table lookup to determine
340  * if the present character is invalid */
341  else if(charLookupTable[curChar] & IJC) {
342  /* back up to offending char */
343  unreadChar(lexer, offset);
345  goto finish_string_lex;
346  }
347  /* when in validate UTF8 mode we need to do some extra work */
348  else if (lexer->validateUTF8) {
349  yajl_tok t = yajl_lex_utf8_char(lexer, jsonText, jsonTextLen,
350  offset, curChar);
351 
352  if (t == yajl_tok_eof) {
353  tok = yajl_tok_eof;
354  goto finish_string_lex;
355  } else if (t == yajl_tok_error) {
357  goto finish_string_lex;
358  }
359  }
360  /* accept it, and move on */
361  }
362  finish_string_lex:
363  /* tell our buddy, the parser, wether he needs to process this string
364  * again */
365  if (hasEscapes && tok == yajl_tok_string) {
367  }
368 
369  return tok;
370 }
371 
372 #define RETURN_IF_EOF if (*offset >= jsonTextLen) return yajl_tok_eof;
373 
374 static yajl_tok
375 yajl_lex_number(yajl_lexer lexer, const unsigned char * jsonText,
376  size_t jsonTextLen, size_t * offset)
377 {
382  unsigned char c;
383 
385 
387  c = readChar(lexer, jsonText, offset);
388 
389  /* optional leading minus */
390  if (c == '-') {
392  c = readChar(lexer, jsonText, offset);
393  }
394 
395  /* a single zero, or a series of integers */
396  if (c == '0') {
398  c = readChar(lexer, jsonText, offset);
399  } else if (c >= '1' && c <= '9') {
400  do {
402  c = readChar(lexer, jsonText, offset);
403  } while (c >= '0' && c <= '9');
404  } else {
405  unreadChar(lexer, offset);
407  return yajl_tok_error;
408  }
409 
410  /* optional fraction (indicates this is floating point) */
411  if (c == '.') {
412  int numRd = 0;
413 
415  c = readChar(lexer, jsonText, offset);
416 
417  while (c >= '0' && c <= '9') {
418  numRd++;
420  c = readChar(lexer, jsonText, offset);
421  }
422 
423  if (!numRd) {
424  unreadChar(lexer, offset);
426  return yajl_tok_error;
427  }
428  tok = yajl_tok_double;
429  }
430 
431  /* optional exponent (indicates this is floating point) */
432  if (c == 'e' || c == 'E') {
434  c = readChar(lexer, jsonText, offset);
435 
436  /* optional sign */
437  if (c == '+' || c == '-') {
439  c = readChar(lexer, jsonText, offset);
440  }
441 
442  if (c >= '0' && c <= '9') {
443  do {
445  c = readChar(lexer, jsonText, offset);
446  } while (c >= '0' && c <= '9');
447  } else {
448  unreadChar(lexer, offset);
450  return yajl_tok_error;
451  }
452  tok = yajl_tok_double;
453  }
454 
455  /* we always go "one too far" */
456  unreadChar(lexer, offset);
457 
458  return tok;
459 }
460 
461 static yajl_tok
462 yajl_lex_comment(yajl_lexer lexer, const unsigned char * jsonText,
463  size_t jsonTextLen, size_t * offset)
464 {
465  unsigned char c;
466 
468 
470  c = readChar(lexer, jsonText, offset);
471 
472  /* either slash or star expected */
473  if (c == '/') {
474  /* now we throw away until end of line */
475  do {
477  c = readChar(lexer, jsonText, offset);
478  } while (c != '\n');
479  } else if (c == '*') {
480  /* now we throw away until end of comment */
481  for (;;) {
483  c = readChar(lexer, jsonText, offset);
484  if (c == '*') {
486  c = readChar(lexer, jsonText, offset);
487  if (c == '/') {
488  break;
489  } else {
490  unreadChar(lexer, offset);
491  }
492  }
493  }
494  } else {
495  lexer->error = yajl_lex_invalid_char;
496  tok = yajl_tok_error;
497  }
498 
499  return tok;
500 }
501 
502 yajl_tok
503 yajl_lex_lex(yajl_lexer lexer, const unsigned char * jsonText,
504  size_t jsonTextLen, size_t * offset,
505  const unsigned char ** outBuf, size_t * outLen)
506 {
507  yajl_tok tok = yajl_tok_error;
508  unsigned char c;
509  size_t startOffset = *offset;
510 
511  *outBuf = NULL;
512  *outLen = 0;
513 
514  for (;;) {
515  assert(*offset <= jsonTextLen);
516 
517  if (*offset >= jsonTextLen) {
518  tok = yajl_tok_eof;
519  goto lexed;
520  }
521 
522  c = readChar(lexer, jsonText, offset);
523 
524  switch (c) {
525  case '{':
526  tok = yajl_tok_left_brace;
527  goto lexed;
528  case '}':
529  tok = yajl_tok_right_brace;
530  goto lexed;
531  case '[':
532  tok = yajl_tok_left_bracket;
533  goto lexed;
534  case ']':
536  goto lexed;
537  case ',':
538  tok = yajl_tok_comma;
539  goto lexed;
540  case ':':
541  tok = yajl_tok_colon;
542  goto lexed;
543  case '\t': case '\n': case '\v': case '\f': case '\r': case ' ':
544  startOffset++;
545  break;
546  case 't': {
547  const char * want = "rue";
548  do {
549  if (*offset >= jsonTextLen) {
550  tok = yajl_tok_eof;
551  goto lexed;
552  }
553  c = readChar(lexer, jsonText, offset);
554  if (c != *want) {
555  unreadChar(lexer, offset);
557  tok = yajl_tok_error;
558  goto lexed;
559  }
560  } while (*(++want));
561  tok = yajl_tok_bool;
562  goto lexed;
563  }
564  case 'f': {
565  const char * want = "alse";
566  do {
567  if (*offset >= jsonTextLen) {
568  tok = yajl_tok_eof;
569  goto lexed;
570  }
571  c = readChar(lexer, jsonText, offset);
572  if (c != *want) {
573  unreadChar(lexer, offset);
575  tok = yajl_tok_error;
576  goto lexed;
577  }
578  } while (*(++want));
579  tok = yajl_tok_bool;
580  goto lexed;
581  }
582  case 'n': {
583  const char * want = "ull";
584  do {
585  if (*offset >= jsonTextLen) {
586  tok = yajl_tok_eof;
587  goto lexed;
588  }
589  c = readChar(lexer, jsonText, offset);
590  if (c != *want) {
591  unreadChar(lexer, offset);
593  tok = yajl_tok_error;
594  goto lexed;
595  }
596  } while (*(++want));
597  tok = yajl_tok_null;
598  goto lexed;
599  }
600  case '"': {
601  tok = yajl_lex_string(lexer, (const unsigned char *) jsonText,
602  jsonTextLen, offset);
603  goto lexed;
604  }
605  case '-':
606  case '0': case '1': case '2': case '3': case '4':
607  case '5': case '6': case '7': case '8': case '9': {
608  /* integer parsing wants to start from the beginning */
609  unreadChar(lexer, offset);
610  tok = yajl_lex_number(lexer, (const unsigned char *) jsonText,
611  jsonTextLen, offset);
612  goto lexed;
613  }
614  case '/':
615  /* hey, look, a probable comment! If comments are disabled
616  * it's an error. */
617  if (!lexer->allowComments) {
618  unreadChar(lexer, offset);
620  tok = yajl_tok_error;
621  goto lexed;
622  }
623  /* if comments are enabled, then we should try to lex
624  * the thing. possible outcomes are
625  * - successful lex (tok_comment, which means continue),
626  * - malformed comment opening (slash not followed by
627  * '*' or '/') (tok_error)
628  * - eof hit. (tok_eof) */
629  tok = yajl_lex_comment(lexer, (const unsigned char *) jsonText,
630  jsonTextLen, offset);
631  if (tok == yajl_tok_comment) {
632  /* "error" is silly, but that's the initial
633  * state of tok. guilty until proven innocent. */
634  tok = yajl_tok_error;
635  yajl_buf_clear(lexer->buf);
636  lexer->bufInUse = 0;
637  startOffset = *offset;
638  break;
639  }
640  /* hit error or eof, bail */
641  goto lexed;
642  default:
643  lexer->error = yajl_lex_invalid_char;
644  tok = yajl_tok_error;
645  goto lexed;
646  }
647  }
648 
649 
650  lexed:
651  /* need to append to buffer if the buffer is in use or
652  * if it's an EOF token */
653  if (tok == yajl_tok_eof || lexer->bufInUse) {
654  if (!lexer->bufInUse) yajl_buf_clear(lexer->buf);
655  lexer->bufInUse = 1;
656  yajl_buf_append(lexer->buf, jsonText + startOffset, *offset - startOffset);
657  lexer->bufOff = 0;
658 
659  if (tok != yajl_tok_eof) {
660  *outBuf = yajl_buf_data(lexer->buf);
661  *outLen = yajl_buf_len(lexer->buf);
662  lexer->bufInUse = 0;
663  }
664  } else if (tok != yajl_tok_error) {
665  *outBuf = jsonText + startOffset;
666  *outLen = *offset - startOffset;
667  }
668 
669  /* special case for strings. skip the quotes. */
670  if (tok == yajl_tok_string || tok == yajl_tok_string_with_escapes)
671  {
672  assert(*outLen >= 2);
673  (*outBuf)++;
674  *outLen -= 2;
675  }
676 
677 
678 #ifdef YAJL_LEXER_DEBUG
679  if (tok == yajl_tok_error) {
680  printf("lexical error: %s\n",
682  } else if (tok == yajl_tok_eof) {
683  printf("EOF hit\n");
684  } else {
685  printf("lexed %s: '", tokToStr(tok));
686  fwrite(*outBuf, 1, *outLen, stdout);
687  printf("'\n");
688  }
689 #endif
690 
691  return tok;
692 }
693 
694 const char *
696 {
697  switch (error) {
698  case yajl_lex_e_ok:
699  return "ok, no error";
701  return "invalid bytes in UTF8 string.";
703  return "inside a string, '\\' occurs before a character "
704  "which it may not.";
706  return "invalid character inside string.";
708  return "invalid (non-hex) character occurs after '\\u' inside "
709  "string.";
711  return "invalid char in json text.";
713  return "invalid string in json text.";
715  return "malformed number, a digit is required after the exponent.";
717  return "malformed number, a digit is required after the "
718  "decimal point.";
720  return "malformed number, a digit is required after the "
721  "minus sign.";
723  return "probable comment found in input text, comments are "
724  "not enabled.";
725  }
726  return "unknown error code";
727 }
728 
729 
734 {
735  if (lexer == NULL) return (yajl_lex_error) -1;
736  return lexer->error;
737 }
738 
740 {
741  return lexer->lineOff;
742 }
743 
745 {
746  return lexer->charOff;
747 }
748 
749 yajl_tok yajl_lex_peek(yajl_lexer lexer, const unsigned char * jsonText,
750  size_t jsonTextLen, size_t offset)
751 {
752  const unsigned char * outBuf;
753  size_t outLen;
754  size_t bufLen = yajl_buf_len(lexer->buf);
755  size_t bufOff = lexer->bufOff;
756  unsigned int bufInUse = lexer->bufInUse;
757  yajl_tok tok;
758 
759  tok = yajl_lex_lex(lexer, jsonText, jsonTextLen, &offset,
760  &outBuf, &outLen);
761 
762  lexer->bufOff = bufOff;
763  lexer->bufInUse = bufInUse;
764  yajl_buf_truncate(lexer->buf, bufLen);
765 
766  return tok;
767 }
size_t bufOff
Definition: yajl_lex.c:82
#define YA_MALLOC(afs, sz)
Definition: yajl_alloc.h:32
#define IJC
Definition: yajl_lex.c:137
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
yajl_lex_error yajl_lex_get_error(yajl_lexer lexer)
Definition: yajl_lex.c:733
#define YA_FREE(afs, ptr)
Definition: yajl_alloc.h:33
const char * yajl_lex_error_to_string(yajl_lex_error error)
Definition: yajl_lex.c:695
#define RETURN_IF_EOF
Definition: yajl_lex.c:372
int i
Definition: scan.c:967
yajl_lex_error error
Definition: yajl_lex.c:74
size_t charOff
Definition: yajl_lex.c:71
#define printf
Definition: epicsStdio.h:41
#define VHC
Definition: yajl_lex.c:138
yajl_buf yajl_buf_alloc(yajl_alloc_funcs *alloc)
Definition: yajl_buf.c:56
unsigned int validateUTF8
Definition: yajl_lex.c:91
#define NULL
Definition: catime.c:38
yajl_alloc_funcs * alloc
Definition: yajl_lex.c:93
size_t yajl_buf_len(yajl_buf buf)
Definition: yajl_buf.c:97
size_t yajl_lex_current_line(yajl_lexer lexer)
Definition: yajl_lex.c:739
struct yajl_lexer_t * yajl_lexer
Definition: yajl_lex.h:48
size_t yajl_lex_current_char(yajl_lexer lexer)
Definition: yajl_lex.c:744
void yajl_buf_append(yajl_buf buf, const void *data, size_t len)
Definition: yajl_buf.c:75
yajl_tok yajl_lex_lex(yajl_lexer lexer, const unsigned char *jsonText, size_t jsonTextLen, size_t *offset, const unsigned char **outBuf, size_t *outLen)
Definition: yajl_lex.c:503
void yajl_buf_truncate(yajl_buf buf, size_t len)
Definition: yajl_buf.c:103
yajl_buf buf
Definition: yajl_lex.c:78
#define UTF8_CHECK_EOF
Definition: yajl_lex.c:196
yajl_tok
Definition: yajl_lex.h:22
#define STR_CHECK_EOF
Definition: yajl_lex.c:248
yajl_tok yajl_lex_peek(yajl_lexer lexer, const unsigned char *jsonText, size_t jsonTextLen, size_t offset)
Definition: yajl_lex.c:749
void yajl_buf_clear(yajl_buf buf)
Definition: yajl_buf.c:86
#define NFP
Definition: yajl_lex.c:139
#define stdout
Definition: epicsStdio.h:30
yajl_lexer yajl_lex_alloc(yajl_alloc_funcs *alloc, unsigned int allowComments, unsigned int validateUTF8)
Definition: yajl_lex.c:104
void yajl_buf_free(yajl_buf buf)
Definition: yajl_buf.c:68
unsigned int allowComments
Definition: yajl_lex.c:88
size_t lineOff
Definition: yajl_lex.c:70
#define readChar(lxr, txt, off)
Definition: yajl_lex.c:96
#define NUC
Definition: yajl_lex.c:140
unsigned int bufInUse
Definition: yajl_lex.c:85
void yajl_lex_free(yajl_lexer lxr)
Definition: yajl_lex.c:121
yajl_lex_error
Definition: yajl_lex.h:91
const unsigned char * yajl_buf_data(yajl_buf buf)
Definition: yajl_buf.c:92
#define VEC
Definition: yajl_lex.c:136
#define unreadChar(lxr, off)
Definition: yajl_lex.c:101