jsonsl.c 51 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661
  1. /* Copyright (C) 2012-2015 Mark Nunberg.
  2. *
  3. * See included LICENSE file for license details.
  4. */
  5. #include "jsonsl.h"
  6. #include <assert.h>
  7. #include <limits.h>
  8. #include <ctype.h>
  9. #ifdef JSONSL_USE_METRICS
  10. #define XMETRICS \
  11. X(STRINGY_INSIGNIFICANT) \
  12. X(STRINGY_SLOWPATH) \
  13. X(ALLOWED_WHITESPACE) \
  14. X(QUOTE_FASTPATH) \
  15. X(SPECIAL_FASTPATH) \
  16. X(SPECIAL_WSPOP) \
  17. X(SPECIAL_SLOWPATH) \
  18. X(GENERIC) \
  19. X(STRUCTURAL_TOKEN) \
  20. X(SPECIAL_SWITCHFIRST) \
  21. X(STRINGY_CATCH) \
  22. X(NUMBER_FASTPATH) \
  23. X(ESCAPES) \
  24. X(TOTAL) \
  25. struct jsonsl_metrics_st {
  26. #define X(m) \
  27. unsigned long metric_##m;
  28. XMETRICS
  29. #undef X
  30. };
  31. static struct jsonsl_metrics_st GlobalMetrics = { 0 };
  32. static unsigned long GenericCounter[0x100] = { 0 };
  33. static unsigned long StringyCatchCounter[0x100] = { 0 };
  34. #define INCR_METRIC(m) \
  35. GlobalMetrics.metric_##m++;
  36. #define INCR_GENERIC(c) \
  37. INCR_METRIC(GENERIC); \
  38. GenericCounter[c]++; \
  39. #define INCR_STRINGY_CATCH(c) \
  40. INCR_METRIC(STRINGY_CATCH); \
  41. StringyCatchCounter[c]++;
  42. JSONSL_API
  43. void jsonsl_dump_global_metrics(void)
  44. {
  45. int ii;
  46. printf("JSONSL Metrics:\n");
  47. #define X(m) \
  48. printf("\t%-30s %20lu (%0.2f%%)\n", #m, GlobalMetrics.metric_##m, \
  49. (float)((float)(GlobalMetrics.metric_##m/(float)GlobalMetrics.metric_TOTAL)) * 100);
  50. XMETRICS
  51. #undef X
  52. printf("Generic Characters:\n");
  53. for (ii = 0; ii < 0xff; ii++) {
  54. if (GenericCounter[ii]) {
  55. printf("\t[ %c ] %lu\n", ii, GenericCounter[ii]);
  56. }
  57. }
  58. printf("Weird string loop\n");
  59. for (ii = 0; ii < 0xff; ii++) {
  60. if (StringyCatchCounter[ii]) {
  61. printf("\t[ %c ] %lu\n", ii, StringyCatchCounter[ii]);
  62. }
  63. }
  64. }
  65. #else
  66. #define INCR_METRIC(m)
  67. #define INCR_GENERIC(c)
  68. #define INCR_STRINGY_CATCH(c)
  69. JSONSL_API
  70. void jsonsl_dump_global_metrics(void) { }
  71. #endif /* JSONSL_USE_METRICS */
  72. #define CASE_DIGITS \
  73. case '1': \
  74. case '2': \
  75. case '3': \
  76. case '4': \
  77. case '5': \
  78. case '6': \
  79. case '7': \
  80. case '8': \
  81. case '9': \
  82. case '0':
  83. static unsigned extract_special(unsigned);
  84. static int is_special_end(unsigned);
  85. static int is_allowed_whitespace(unsigned);
  86. static int is_allowed_escape(unsigned);
  87. static int is_simple_char(unsigned);
  88. static char get_escape_equiv(unsigned);
  89. JSONSL_API
  90. size_t jsonsl_get_size(int nlevels)
  91. {
  92. return sizeof (struct jsonsl_st) + ( (nlevels-1) * sizeof (struct jsonsl_state_st)) ;
  93. }
  94. JSONSL_API
  95. jsonsl_t jsonsl_init(jsonsl_t jsn, int nlevels)
  96. {
  97. unsigned int ii;
  98. memset(jsn, 0, jsonsl_get_size(nlevels));
  99. jsn->levels_max = nlevels;
  100. jsn->max_callback_level = -1;
  101. jsonsl_reset(jsn);
  102. for (ii = 0; ii < jsn->levels_max; ii++) {
  103. jsn->stack[ii].level = ii;
  104. }
  105. return jsn;
  106. }
  107. JSONSL_API
  108. jsonsl_t jsonsl_new(int nlevels)
  109. {
  110. struct jsonsl_st *jsn = (struct jsonsl_st *)
  111. calloc(1, jsonsl_get_size(nlevels));
  112. if (jsn) {
  113. jsonsl_init(jsn, nlevels);
  114. }
  115. return jsn;
  116. }
  117. JSONSL_API
  118. void jsonsl_reset(jsonsl_t jsn)
  119. {
  120. jsn->tok_last = 0;
  121. jsn->can_insert = 1;
  122. jsn->pos = 0;
  123. jsn->level = 0;
  124. jsn->stopfl = 0;
  125. jsn->in_escape = 0;
  126. jsn->expecting = 0;
  127. }
  128. JSONSL_API
  129. void jsonsl_destroy(jsonsl_t jsn)
  130. {
  131. if (jsn) {
  132. free(jsn);
  133. }
  134. }
  135. #define FASTPARSE_EXHAUSTED 1
  136. #define FASTPARSE_BREAK 0
  137. /*
  138. * This function is meant to accelerate string parsing, reducing the main loop's
  139. * check if we are indeed a string.
  140. *
  141. * @param jsn the parser
  142. * @param[in,out] bytes_p A pointer to the current buffer (i.e. current position)
  143. * @param[in,out] nbytes_p A pointer to the current size of the buffer
  144. * @return true if all bytes have been exhausted (and thus the main loop can
  145. * return), false if a special character was examined which requires greater
  146. * examination.
  147. */
  148. static int
  149. jsonsl__str_fastparse(jsonsl_t jsn,
  150. const jsonsl_uchar_t **bytes_p, size_t *nbytes_p)
  151. {
  152. const jsonsl_uchar_t *bytes = *bytes_p;
  153. const jsonsl_uchar_t *end;
  154. for (end = bytes + *nbytes_p; bytes != end; bytes++) {
  155. if (
  156. #ifdef JSONSL_USE_WCHAR
  157. *bytes >= 0x100 ||
  158. #endif /* JSONSL_USE_WCHAR */
  159. (is_simple_char(*bytes))) {
  160. INCR_METRIC(TOTAL);
  161. INCR_METRIC(STRINGY_INSIGNIFICANT);
  162. } else {
  163. /* Once we're done here, re-calculate the position variables */
  164. jsn->pos += (bytes - *bytes_p);
  165. *nbytes_p -= (bytes - *bytes_p);
  166. *bytes_p = bytes;
  167. return FASTPARSE_BREAK;
  168. }
  169. }
  170. /* Once we're done here, re-calculate the position variables */
  171. jsn->pos += (bytes - *bytes_p);
  172. return FASTPARSE_EXHAUSTED;
  173. }
  174. /* Functions exactly like str_fastparse, except it also accepts a 'state'
  175. * argument, since the number's value is updated in the state. */
  176. static int
  177. jsonsl__num_fastparse(jsonsl_t jsn,
  178. const jsonsl_uchar_t **bytes_p, size_t *nbytes_p,
  179. struct jsonsl_state_st *state)
  180. {
  181. int exhausted = 1;
  182. size_t nbytes = *nbytes_p;
  183. const jsonsl_uchar_t *bytes = *bytes_p;
  184. for (; nbytes; nbytes--, bytes++) {
  185. jsonsl_uchar_t c = *bytes;
  186. if (isdigit(c)) {
  187. INCR_METRIC(TOTAL);
  188. INCR_METRIC(NUMBER_FASTPATH);
  189. state->nelem = (state->nelem * 10) + (c - 0x30);
  190. } else {
  191. exhausted = 0;
  192. break;
  193. }
  194. }
  195. jsn->pos += (*nbytes_p - nbytes);
  196. if (exhausted) {
  197. return FASTPARSE_EXHAUSTED;
  198. }
  199. *nbytes_p = nbytes;
  200. *bytes_p = bytes;
  201. return FASTPARSE_BREAK;
  202. }
  203. JSONSL_API
  204. void
  205. jsonsl_feed(jsonsl_t jsn, const jsonsl_char_t *bytes, size_t nbytes)
  206. {
  207. #define INVOKE_ERROR(eb) \
  208. if (jsn->error_callback(jsn, JSONSL_ERROR_##eb, state, (char*)c)) { \
  209. goto GT_AGAIN; \
  210. } \
  211. return;
  212. #define STACK_PUSH \
  213. if (jsn->level >= (levels_max-1)) { \
  214. jsn->error_callback(jsn, JSONSL_ERROR_LEVELS_EXCEEDED, state, (char*)c); \
  215. return; \
  216. } \
  217. state = jsn->stack + (++jsn->level); \
  218. state->ignore_callback = jsn->stack[jsn->level-1].ignore_callback; \
  219. state->pos_begin = jsn->pos;
  220. #define STACK_POP_NOPOS \
  221. state->pos_cur = jsn->pos; \
  222. state = jsn->stack + (--jsn->level);
  223. #define STACK_POP \
  224. STACK_POP_NOPOS; \
  225. state->pos_cur = jsn->pos;
  226. #define CALLBACK_AND_POP_NOPOS(T) \
  227. state->pos_cur = jsn->pos; \
  228. DO_CALLBACK(T, POP); \
  229. state->nescapes = 0; \
  230. state = jsn->stack + (--jsn->level);
  231. #define CALLBACK_AND_POP(T) \
  232. CALLBACK_AND_POP_NOPOS(T); \
  233. state->pos_cur = jsn->pos;
  234. #define SPECIAL_POP \
  235. CALLBACK_AND_POP(SPECIAL); \
  236. jsn->expecting = 0; \
  237. jsn->tok_last = 0; \
  238. #define CUR_CHAR (*(jsonsl_uchar_t*)c)
  239. #define DO_CALLBACK(T, action) \
  240. if (jsn->call_##T && \
  241. jsn->max_callback_level > state->level && \
  242. state->ignore_callback == 0) { \
  243. \
  244. if (jsn->action_callback_##action) { \
  245. jsn->action_callback_##action(jsn, JSONSL_ACTION_##action, state, (jsonsl_char_t*)c); \
  246. } else if (jsn->action_callback) { \
  247. jsn->action_callback(jsn, JSONSL_ACTION_##action, state, (jsonsl_char_t*)c); \
  248. } \
  249. if (jsn->stopfl) { return; } \
  250. }
  251. /**
  252. * Verifies that we are able to insert the (non-string) item into a hash.
  253. */
  254. #define ENSURE_HVAL \
  255. if (state->nelem % 2 == 0 && state->type == JSONSL_T_OBJECT) { \
  256. INVOKE_ERROR(HKEY_EXPECTED); \
  257. }
  258. #define VERIFY_SPECIAL(lit) \
  259. if (CUR_CHAR != (lit)[jsn->pos - state->pos_begin]) { \
  260. INVOKE_ERROR(SPECIAL_EXPECTED); \
  261. }
  262. #define STATE_SPECIAL_LENGTH \
  263. (state)->nescapes
  264. #define IS_NORMAL_NUMBER \
  265. ((state)->special_flags == JSONSL_SPECIALf_UNSIGNED || \
  266. (state)->special_flags == JSONSL_SPECIALf_SIGNED)
  267. #define STATE_NUM_LAST jsn->tok_last
  268. #define CONTINUE_NEXT_CHAR() continue
  269. const jsonsl_uchar_t *c = (jsonsl_uchar_t*)bytes;
  270. size_t levels_max = jsn->levels_max;
  271. struct jsonsl_state_st *state = jsn->stack + jsn->level;
  272. jsn->base = bytes;
  273. for (; nbytes; nbytes--, jsn->pos++, c++) {
  274. unsigned state_type;
  275. INCR_METRIC(TOTAL);
  276. GT_AGAIN:
  277. state_type = state->type;
  278. /* Most common type is typically a string: */
  279. if (state_type & JSONSL_Tf_STRINGY) {
  280. /* Special escape handling for some stuff */
  281. if (jsn->in_escape) {
  282. jsn->in_escape = 0;
  283. if (!is_allowed_escape(CUR_CHAR)) {
  284. INVOKE_ERROR(ESCAPE_INVALID);
  285. } else if (CUR_CHAR == 'u') {
  286. DO_CALLBACK(UESCAPE, UESCAPE);
  287. if (jsn->return_UESCAPE) {
  288. return;
  289. }
  290. }
  291. CONTINUE_NEXT_CHAR();
  292. }
  293. if (jsonsl__str_fastparse(jsn, &c, &nbytes) ==
  294. FASTPARSE_EXHAUSTED) {
  295. /* No need to readjust variables as we've exhausted the iterator */
  296. return;
  297. } else {
  298. if (CUR_CHAR == '"') {
  299. goto GT_QUOTE;
  300. } else if (CUR_CHAR == '\\') {
  301. goto GT_ESCAPE;
  302. } else {
  303. INVOKE_ERROR(WEIRD_WHITESPACE);
  304. }
  305. }
  306. INCR_METRIC(STRINGY_SLOWPATH);
  307. } else if (state_type == JSONSL_T_SPECIAL) {
  308. /* Fast track for signed/unsigned */
  309. if (IS_NORMAL_NUMBER) {
  310. if (jsonsl__num_fastparse(jsn, &c, &nbytes, state) ==
  311. FASTPARSE_EXHAUSTED) {
  312. return;
  313. } else {
  314. goto GT_SPECIAL_NUMERIC;
  315. }
  316. } else if (state->special_flags == JSONSL_SPECIALf_DASH) {
  317. if (!isdigit(CUR_CHAR)) {
  318. INVOKE_ERROR(INVALID_NUMBER);
  319. }
  320. if (CUR_CHAR == '0') {
  321. state->special_flags = JSONSL_SPECIALf_ZERO|JSONSL_SPECIALf_SIGNED;
  322. } else if (isdigit(CUR_CHAR)) {
  323. state->special_flags = JSONSL_SPECIALf_SIGNED;
  324. state->nelem = CUR_CHAR - 0x30;
  325. } else {
  326. INVOKE_ERROR(INVALID_NUMBER);
  327. }
  328. CONTINUE_NEXT_CHAR();
  329. } else if (state->special_flags == JSONSL_SPECIALf_ZERO) {
  330. if (isdigit(CUR_CHAR)) {
  331. /* Following a zero! */
  332. INVOKE_ERROR(INVALID_NUMBER);
  333. }
  334. /* Unset the 'zero' flag: */
  335. if (state->special_flags & JSONSL_SPECIALf_SIGNED) {
  336. state->special_flags = JSONSL_SPECIALf_SIGNED;
  337. } else {
  338. state->special_flags = JSONSL_SPECIALf_UNSIGNED;
  339. }
  340. goto GT_SPECIAL_NUMERIC;
  341. }
  342. if (state->special_flags & JSONSL_SPECIALf_NUMERIC) {
  343. GT_SPECIAL_NUMERIC:
  344. switch (CUR_CHAR) {
  345. CASE_DIGITS
  346. STATE_NUM_LAST = '1';
  347. CONTINUE_NEXT_CHAR();
  348. case '.':
  349. if (state->special_flags & JSONSL_SPECIALf_FLOAT) {
  350. INVOKE_ERROR(INVALID_NUMBER);
  351. }
  352. state->special_flags |= JSONSL_SPECIALf_FLOAT;
  353. STATE_NUM_LAST = '.';
  354. CONTINUE_NEXT_CHAR();
  355. case 'e':
  356. case 'E':
  357. if (state->special_flags & JSONSL_SPECIALf_EXPONENT) {
  358. INVOKE_ERROR(INVALID_NUMBER);
  359. }
  360. state->special_flags |= JSONSL_SPECIALf_EXPONENT;
  361. STATE_NUM_LAST = 'e';
  362. CONTINUE_NEXT_CHAR();
  363. case '-':
  364. case '+':
  365. if (STATE_NUM_LAST != 'e') {
  366. INVOKE_ERROR(INVALID_NUMBER);
  367. }
  368. STATE_NUM_LAST = '-';
  369. CONTINUE_NEXT_CHAR();
  370. default:
  371. if (is_special_end(CUR_CHAR)) {
  372. goto GT_SPECIAL_POP;
  373. }
  374. INVOKE_ERROR(INVALID_NUMBER);
  375. break;
  376. }
  377. }
  378. /* else if (!NUMERIC) */
  379. if (!is_special_end(CUR_CHAR)) {
  380. STATE_SPECIAL_LENGTH++;
  381. /* Verify TRUE, FALSE, NULL */
  382. if (state->special_flags == JSONSL_SPECIALf_TRUE) {
  383. VERIFY_SPECIAL("true");
  384. } else if (state->special_flags == JSONSL_SPECIALf_FALSE) {
  385. VERIFY_SPECIAL("false");
  386. } else if (state->special_flags == JSONSL_SPECIALf_NULL) {
  387. VERIFY_SPECIAL("null");
  388. }
  389. INCR_METRIC(SPECIAL_FASTPATH);
  390. CONTINUE_NEXT_CHAR();
  391. }
  392. GT_SPECIAL_POP:
  393. jsn->can_insert = 0;
  394. if (IS_NORMAL_NUMBER) {
  395. /* Nothing */
  396. } else if (state->special_flags == JSONSL_SPECIALf_ZERO ||
  397. state->special_flags == (JSONSL_SPECIALf_ZERO|JSONSL_SPECIALf_SIGNED)) {
  398. /* 0 is unsigned! */
  399. state->special_flags = JSONSL_SPECIALf_UNSIGNED;
  400. } else if (state->special_flags == JSONSL_SPECIALf_DASH) {
  401. /* Still in dash! */
  402. INVOKE_ERROR(INVALID_NUMBER);
  403. } else if (state->special_flags & JSONSL_SPECIALf_NUMERIC) {
  404. /* Check that we're not at the end of a token */
  405. if (STATE_NUM_LAST != '1') {
  406. INVOKE_ERROR(INVALID_NUMBER);
  407. }
  408. } else if (state->special_flags == JSONSL_SPECIALf_TRUE) {
  409. if (STATE_SPECIAL_LENGTH != 4) {
  410. INVOKE_ERROR(SPECIAL_INCOMPLETE);
  411. }
  412. state->nelem = 1;
  413. } else if (state->special_flags == JSONSL_SPECIALf_FALSE) {
  414. if (STATE_SPECIAL_LENGTH != 5) {
  415. INVOKE_ERROR(SPECIAL_INCOMPLETE);
  416. }
  417. } else if (state->special_flags == JSONSL_SPECIALf_NULL) {
  418. if (STATE_SPECIAL_LENGTH != 4) {
  419. INVOKE_ERROR(SPECIAL_INCOMPLETE);
  420. }
  421. }
  422. SPECIAL_POP;
  423. jsn->expecting = ',';
  424. if (is_allowed_whitespace(CUR_CHAR)) {
  425. CONTINUE_NEXT_CHAR();
  426. }
  427. /**
  428. * This works because we have a non-whitespace token
  429. * which is not a special token. If this is a structural
  430. * character then it will be gracefully handled by the
  431. * switch statement. Otherwise it will default to the 'special'
  432. * state again,
  433. */
  434. goto GT_STRUCTURAL_TOKEN;
  435. } else if (is_allowed_whitespace(CUR_CHAR)) {
  436. INCR_METRIC(ALLOWED_WHITESPACE);
  437. /* So we're not special. Harmless insignificant whitespace
  438. * passthrough
  439. */
  440. CONTINUE_NEXT_CHAR();
  441. } else if (extract_special(CUR_CHAR)) {
  442. /* not a string, whitespace, or structural token. must be special */
  443. goto GT_SPECIAL_BEGIN;
  444. }
  445. INCR_GENERIC(CUR_CHAR);
  446. if (CUR_CHAR == '"') {
  447. GT_QUOTE:
  448. jsn->can_insert = 0;
  449. switch (state_type) {
  450. /* the end of a string or hash key */
  451. case JSONSL_T_STRING:
  452. CALLBACK_AND_POP(STRING);
  453. CONTINUE_NEXT_CHAR();
  454. case JSONSL_T_HKEY:
  455. CALLBACK_AND_POP(HKEY);
  456. CONTINUE_NEXT_CHAR();
  457. case JSONSL_T_OBJECT:
  458. state->nelem++;
  459. if ( (state->nelem-1) % 2 ) {
  460. /* Odd, this must be a hash value */
  461. if (jsn->tok_last != ':') {
  462. INVOKE_ERROR(MISSING_TOKEN);
  463. }
  464. jsn->expecting = ','; /* Can't figure out what to expect next */
  465. jsn->tok_last = 0;
  466. STACK_PUSH;
  467. state->type = JSONSL_T_STRING;
  468. DO_CALLBACK(STRING, PUSH);
  469. } else {
  470. /* hash key */
  471. if (jsn->expecting != '"') {
  472. INVOKE_ERROR(STRAY_TOKEN);
  473. }
  474. jsn->tok_last = 0;
  475. jsn->expecting = ':';
  476. STACK_PUSH;
  477. state->type = JSONSL_T_HKEY;
  478. DO_CALLBACK(HKEY, PUSH);
  479. }
  480. CONTINUE_NEXT_CHAR();
  481. case JSONSL_T_LIST:
  482. state->nelem++;
  483. STACK_PUSH;
  484. state->type = JSONSL_T_STRING;
  485. jsn->expecting = ',';
  486. jsn->tok_last = 0;
  487. DO_CALLBACK(STRING, PUSH);
  488. CONTINUE_NEXT_CHAR();
  489. case JSONSL_T_SPECIAL:
  490. INVOKE_ERROR(STRAY_TOKEN);
  491. break;
  492. default:
  493. INVOKE_ERROR(STRING_OUTSIDE_CONTAINER);
  494. break;
  495. } /* switch(state->type) */
  496. } else if (CUR_CHAR == '\\') {
  497. GT_ESCAPE:
  498. INCR_METRIC(ESCAPES);
  499. /* Escape */
  500. if ( (state->type & JSONSL_Tf_STRINGY) == 0 ) {
  501. INVOKE_ERROR(ESCAPE_OUTSIDE_STRING);
  502. }
  503. state->nescapes++;
  504. jsn->in_escape = 1;
  505. CONTINUE_NEXT_CHAR();
  506. } /* " or \ */
  507. GT_STRUCTURAL_TOKEN:
  508. switch (CUR_CHAR) {
  509. case ':':
  510. INCR_METRIC(STRUCTURAL_TOKEN);
  511. if (jsn->expecting != CUR_CHAR) {
  512. INVOKE_ERROR(STRAY_TOKEN);
  513. }
  514. jsn->tok_last = ':';
  515. jsn->can_insert = 1;
  516. jsn->expecting = '"';
  517. CONTINUE_NEXT_CHAR();
  518. case ',':
  519. INCR_METRIC(STRUCTURAL_TOKEN);
  520. /**
  521. * The comma is one of the more generic tokens.
  522. * In the context of an OBJECT, the can_insert flag
  523. * should never be set, and no other action is
  524. * necessary.
  525. */
  526. if (jsn->expecting != CUR_CHAR) {
  527. /* make this branch execute only when we haven't manually
  528. * just placed the ',' in the expecting register.
  529. */
  530. INVOKE_ERROR(STRAY_TOKEN);
  531. }
  532. if (state->type == JSONSL_T_OBJECT) {
  533. /* end of hash value, expect a string as a hash key */
  534. jsn->expecting = '"';
  535. } else {
  536. jsn->can_insert = 1;
  537. }
  538. jsn->tok_last = ',';
  539. jsn->expecting = '"';
  540. CONTINUE_NEXT_CHAR();
  541. /* new list or object */
  542. /* hashes are more common */
  543. case '{':
  544. case '[':
  545. INCR_METRIC(STRUCTURAL_TOKEN);
  546. if (!jsn->can_insert) {
  547. INVOKE_ERROR(CANT_INSERT);
  548. }
  549. ENSURE_HVAL;
  550. state->nelem++;
  551. STACK_PUSH;
  552. /* because the constants match the opening delimiters, we can do this: */
  553. state->type = CUR_CHAR;
  554. state->nelem = 0;
  555. jsn->can_insert = 1;
  556. if (CUR_CHAR == '{') {
  557. /* If we're a hash, we expect a key first, which is quouted */
  558. jsn->expecting = '"';
  559. }
  560. if (CUR_CHAR == JSONSL_T_OBJECT) {
  561. DO_CALLBACK(OBJECT, PUSH);
  562. } else {
  563. DO_CALLBACK(LIST, PUSH);
  564. }
  565. jsn->tok_last = 0;
  566. CONTINUE_NEXT_CHAR();
  567. /* closing of list or object */
  568. case '}':
  569. case ']':
  570. INCR_METRIC(STRUCTURAL_TOKEN);
  571. if (jsn->tok_last == ',' && jsn->options.allow_trailing_comma == 0) {
  572. INVOKE_ERROR(TRAILING_COMMA);
  573. }
  574. jsn->can_insert = 0;
  575. jsn->level--;
  576. jsn->expecting = ',';
  577. jsn->tok_last = 0;
  578. if (CUR_CHAR == ']') {
  579. if (state->type != '[') {
  580. INVOKE_ERROR(BRACKET_MISMATCH);
  581. }
  582. DO_CALLBACK(LIST, POP);
  583. } else {
  584. if (state->type != '{') {
  585. INVOKE_ERROR(BRACKET_MISMATCH);
  586. } else if (state->nelem && state->nelem % 2 != 0) {
  587. INVOKE_ERROR(VALUE_EXPECTED);
  588. }
  589. DO_CALLBACK(OBJECT, POP);
  590. }
  591. state = jsn->stack + jsn->level;
  592. state->pos_cur = jsn->pos;
  593. CONTINUE_NEXT_CHAR();
  594. default:
  595. GT_SPECIAL_BEGIN:
  596. /**
  597. * Not a string, not a structural token, and not benign whitespace.
  598. * Technically we should iterate over the character always, but since
  599. * we are not doing full numerical/value decoding anyway (but only hinting),
  600. * we only check upon entry.
  601. */
  602. if (state->type != JSONSL_T_SPECIAL) {
  603. int special_flags = extract_special(CUR_CHAR);
  604. if (!special_flags) {
  605. /**
  606. * Try to do some heuristics here anyway to figure out what kind of
  607. * error this is. The 'special' case is a fallback scenario anyway.
  608. */
  609. if (CUR_CHAR == '\0') {
  610. INVOKE_ERROR(FOUND_NULL_BYTE);
  611. } else if (CUR_CHAR < 0x20) {
  612. INVOKE_ERROR(WEIRD_WHITESPACE);
  613. } else {
  614. INVOKE_ERROR(SPECIAL_EXPECTED);
  615. }
  616. }
  617. ENSURE_HVAL;
  618. state->nelem++;
  619. if (!jsn->can_insert) {
  620. INVOKE_ERROR(CANT_INSERT);
  621. }
  622. STACK_PUSH;
  623. state->type = JSONSL_T_SPECIAL;
  624. state->special_flags = special_flags;
  625. STATE_SPECIAL_LENGTH = 1;
  626. if (special_flags == JSONSL_SPECIALf_UNSIGNED) {
  627. state->nelem = CUR_CHAR - 0x30;
  628. STATE_NUM_LAST = '1';
  629. } else {
  630. STATE_NUM_LAST = '-';
  631. state->nelem = 0;
  632. }
  633. DO_CALLBACK(SPECIAL, PUSH);
  634. }
  635. CONTINUE_NEXT_CHAR();
  636. }
  637. }
  638. }
  639. JSONSL_API
  640. const char* jsonsl_strerror(jsonsl_error_t err)
  641. {
  642. if (err == JSONSL_ERROR_SUCCESS) {
  643. return "SUCCESS";
  644. }
  645. #define X(t) \
  646. if (err == JSONSL_ERROR_##t) \
  647. return #t;
  648. JSONSL_XERR;
  649. #undef X
  650. return "<UNKNOWN_ERROR>";
  651. }
  652. JSONSL_API
  653. const char *jsonsl_strtype(jsonsl_type_t type)
  654. {
  655. #define X(o,c) \
  656. if (type == JSONSL_T_##o) \
  657. return #o;
  658. JSONSL_XTYPE
  659. #undef X
  660. return "UNKNOWN TYPE";
  661. }
  662. /*
  663. *
  664. * JPR/JSONPointer functions
  665. *
  666. *
  667. */
  668. #ifndef JSONSL_NO_JPR
  669. static
  670. jsonsl_jpr_type_t
  671. populate_component(char *in,
  672. struct jsonsl_jpr_component_st *component,
  673. char **next,
  674. jsonsl_error_t *errp)
  675. {
  676. unsigned long pctval;
  677. char *c = NULL, *outp = NULL, *end = NULL;
  678. size_t input_len;
  679. jsonsl_jpr_type_t ret = JSONSL_PATH_NONE;
  680. if (*next == NULL || *(*next) == '\0') {
  681. return JSONSL_PATH_NONE;
  682. }
  683. /* Replace the next / with a NULL */
  684. *next = strstr(in, "/");
  685. if (*next != NULL) {
  686. *(*next) = '\0'; /* drop the forward slash */
  687. input_len = *next - in;
  688. end = *next;
  689. *next += 1; /* next character after the '/' */
  690. } else {
  691. input_len = strlen(in);
  692. end = in + input_len + 1;
  693. }
  694. component->pstr = in;
  695. /* Check for special components of interest */
  696. if (*in == JSONSL_PATH_WILDCARD_CHAR && input_len == 1) {
  697. /* Lone wildcard */
  698. ret = JSONSL_PATH_WILDCARD;
  699. goto GT_RET;
  700. } else if (isdigit(*in)) {
  701. /* ASCII Numeric */
  702. char *endptr;
  703. component->idx = strtoul(in, &endptr, 10);
  704. if (endptr && *endptr == '\0') {
  705. ret = JSONSL_PATH_NUMERIC;
  706. goto GT_RET;
  707. }
  708. }
  709. /* Default, it's a string */
  710. ret = JSONSL_PATH_STRING;
  711. for (c = outp = in; c < end; c++, outp++) {
  712. char origc;
  713. if (*c != '%') {
  714. goto GT_ASSIGN;
  715. }
  716. /*
  717. * c = { [+0] = '%', [+1] = 'b', [+2] = 'e', [+3] = '\0' }
  718. */
  719. /* Need %XX */
  720. if (c+2 >= end) {
  721. *errp = JSONSL_ERROR_PERCENT_BADHEX;
  722. return JSONSL_PATH_INVALID;
  723. }
  724. if (! (isxdigit(*(c+1)) && isxdigit(*(c+2))) ) {
  725. *errp = JSONSL_ERROR_PERCENT_BADHEX;
  726. return JSONSL_PATH_INVALID;
  727. }
  728. /* Temporarily null-terminate the characters */
  729. origc = *(c+3);
  730. *(c+3) = '\0';
  731. pctval = strtoul(c+1, NULL, 16);
  732. *(c+3) = origc;
  733. *outp = (char) pctval;
  734. c += 2;
  735. continue;
  736. GT_ASSIGN:
  737. *outp = *c;
  738. }
  739. /* Null-terminate the string */
  740. for (; outp < c; outp++) {
  741. *outp = '\0';
  742. }
  743. GT_RET:
  744. component->ptype = ret;
  745. if (ret != JSONSL_PATH_WILDCARD) {
  746. component->len = strlen(component->pstr);
  747. }
  748. return ret;
  749. }
  750. JSONSL_API
  751. jsonsl_jpr_t
  752. jsonsl_jpr_new(const char *path, jsonsl_error_t *errp)
  753. {
  754. char *my_copy = NULL;
  755. int count, curidx;
  756. struct jsonsl_jpr_st *ret = NULL;
  757. struct jsonsl_jpr_component_st *components = NULL;
  758. size_t origlen;
  759. jsonsl_error_t errstacked;
  760. #define JPR_BAIL(err) *errp = err; goto GT_ERROR;
  761. if (errp == NULL) {
  762. errp = &errstacked;
  763. }
  764. if (path == NULL || *path != '/') {
  765. JPR_BAIL(JSONSL_ERROR_JPR_NOROOT);
  766. return NULL;
  767. }
  768. count = 1;
  769. path++;
  770. {
  771. const char *c = path;
  772. for (; *c; c++) {
  773. if (*c == '/') {
  774. count++;
  775. if (*(c+1) == '/') {
  776. JPR_BAIL(JSONSL_ERROR_JPR_DUPSLASH);
  777. }
  778. }
  779. }
  780. }
  781. if(*path) {
  782. count++;
  783. }
  784. components = (struct jsonsl_jpr_component_st *)
  785. malloc(sizeof(*components) * count);
  786. if (!components) {
  787. JPR_BAIL(JSONSL_ERROR_ENOMEM);
  788. }
  789. my_copy = (char *)malloc(strlen(path) + 1);
  790. if (!my_copy) {
  791. JPR_BAIL(JSONSL_ERROR_ENOMEM);
  792. }
  793. strcpy(my_copy, path);
  794. components[0].ptype = JSONSL_PATH_ROOT;
  795. if (*my_copy) {
  796. char *cur = my_copy;
  797. int pathret = JSONSL_PATH_STRING;
  798. curidx = 1;
  799. while (pathret > 0 && curidx < count) {
  800. pathret = populate_component(cur, components + curidx, &cur, errp);
  801. if (pathret > 0) {
  802. curidx++;
  803. } else {
  804. break;
  805. }
  806. }
  807. if (pathret == JSONSL_PATH_INVALID) {
  808. JPR_BAIL(JSONSL_ERROR_JPR_BADPATH);
  809. }
  810. } else {
  811. curidx = 1;
  812. }
  813. path--; /*revert path to leading '/' */
  814. origlen = strlen(path) + 1;
  815. ret = (struct jsonsl_jpr_st *)malloc(sizeof(*ret));
  816. if (!ret) {
  817. JPR_BAIL(JSONSL_ERROR_ENOMEM);
  818. }
  819. ret->orig = (char *)malloc(origlen);
  820. if (!ret->orig) {
  821. JPR_BAIL(JSONSL_ERROR_ENOMEM);
  822. }
  823. ret->components = components;
  824. ret->ncomponents = curidx;
  825. ret->basestr = my_copy;
  826. ret->norig = origlen-1;
  827. strcpy(ret->orig, path);
  828. return ret;
  829. GT_ERROR:
  830. free(my_copy);
  831. free(components);
  832. if (ret) {
  833. free(ret->orig);
  834. }
  835. free(ret);
  836. return NULL;
  837. #undef JPR_BAIL
  838. }
  839. void jsonsl_jpr_destroy(jsonsl_jpr_t jpr)
  840. {
  841. free(jpr->components);
  842. free(jpr->basestr);
  843. free(jpr->orig);
  844. free(jpr);
  845. }
  846. /**
  847. * Call when there is a possibility of a match, either as a final match or
  848. * as a path within a match
  849. * @param jpr The JPR path
  850. * @param component Component corresponding to the current element
  851. * @param prlevel The level of the *parent*
  852. * @param chtype The type of the child
  853. * @return Match status
  854. */
  855. static jsonsl_jpr_match_t
  856. jsonsl__match_continue(jsonsl_jpr_t jpr,
  857. const struct jsonsl_jpr_component_st *component,
  858. unsigned prlevel, unsigned chtype)
  859. {
  860. const struct jsonsl_jpr_component_st *next_comp = component + 1;
  861. if (prlevel == jpr->ncomponents - 1) {
  862. /* This is the match. Check the expected type of the match against
  863. * the child */
  864. if (jpr->match_type == 0 || jpr->match_type == chtype) {
  865. return JSONSL_MATCH_COMPLETE;
  866. } else {
  867. return JSONSL_MATCH_TYPE_MISMATCH;
  868. }
  869. }
  870. if (chtype == JSONSL_T_LIST) {
  871. if (next_comp->ptype == JSONSL_PATH_NUMERIC) {
  872. return JSONSL_MATCH_POSSIBLE;
  873. } else {
  874. return JSONSL_MATCH_TYPE_MISMATCH;
  875. }
  876. } else if (chtype == JSONSL_T_OBJECT) {
  877. if (next_comp->ptype == JSONSL_PATH_NUMERIC) {
  878. return JSONSL_MATCH_TYPE_MISMATCH;
  879. } else {
  880. return JSONSL_MATCH_POSSIBLE;
  881. }
  882. } else {
  883. return JSONSL_MATCH_TYPE_MISMATCH;
  884. }
  885. }
  886. JSONSL_API
  887. jsonsl_jpr_match_t
  888. jsonsl_path_match(jsonsl_jpr_t jpr,
  889. const struct jsonsl_state_st *parent,
  890. const struct jsonsl_state_st *child,
  891. const char *key, size_t nkey)
  892. {
  893. const struct jsonsl_jpr_component_st *comp;
  894. if (!parent) {
  895. /* No parent. Return immediately since it's always a match */
  896. return jsonsl__match_continue(jpr, jpr->components, 0, child->type);
  897. }
  898. comp = jpr->components + parent->level;
  899. /* note that we don't need to verify the type of the match, this is
  900. * always done through the previous call to jsonsl__match_continue.
  901. * If we are in a POSSIBLE tree then we can be certain the types (at
  902. * least at this level) are correct */
  903. if (parent->type == JSONSL_T_OBJECT) {
  904. if (comp->len != nkey || strncmp(key, comp->pstr, nkey) != 0) {
  905. return JSONSL_MATCH_NOMATCH;
  906. }
  907. } else {
  908. if (comp->idx != parent->nelem - 1) {
  909. return JSONSL_MATCH_NOMATCH;
  910. }
  911. }
  912. return jsonsl__match_continue(jpr, comp, parent->level, child->type);
  913. }
  914. JSONSL_API
  915. jsonsl_jpr_match_t
  916. jsonsl_jpr_match(jsonsl_jpr_t jpr,
  917. unsigned int parent_type,
  918. unsigned int parent_level,
  919. const char *key,
  920. size_t nkey)
  921. {
  922. /* find our current component. This is the child level */
  923. int cmpret;
  924. struct jsonsl_jpr_component_st *p_component;
  925. p_component = jpr->components + parent_level;
  926. if (parent_level >= jpr->ncomponents) {
  927. return JSONSL_MATCH_NOMATCH;
  928. }
  929. /* Lone query for 'root' element. Always matches */
  930. if (parent_level == 0) {
  931. if (jpr->ncomponents == 1) {
  932. return JSONSL_MATCH_COMPLETE;
  933. } else {
  934. return JSONSL_MATCH_POSSIBLE;
  935. }
  936. }
  937. /* Wildcard, always matches */
  938. if (p_component->ptype == JSONSL_PATH_WILDCARD) {
  939. if (parent_level == jpr->ncomponents-1) {
  940. return JSONSL_MATCH_COMPLETE;
  941. } else {
  942. return JSONSL_MATCH_POSSIBLE;
  943. }
  944. }
  945. /* Check numeric array index. This gets its special block so we can avoid
  946. * string comparisons */
  947. if (p_component->ptype == JSONSL_PATH_NUMERIC) {
  948. if (parent_type == JSONSL_T_LIST) {
  949. if (p_component->idx != nkey) {
  950. /* Wrong index */
  951. return JSONSL_MATCH_NOMATCH;
  952. } else {
  953. if (parent_level == jpr->ncomponents-1) {
  954. /* This is the last element of the path */
  955. return JSONSL_MATCH_COMPLETE;
  956. } else {
  957. /* Intermediate element */
  958. return JSONSL_MATCH_POSSIBLE;
  959. }
  960. }
  961. } else if (p_component->is_arridx) {
  962. /* Numeric and an array index (set explicitly by user). But not
  963. * a list for a parent */
  964. return JSONSL_MATCH_TYPE_MISMATCH;
  965. }
  966. } else if (parent_type == JSONSL_T_LIST) {
  967. return JSONSL_MATCH_TYPE_MISMATCH;
  968. }
  969. /* Check lengths */
  970. if (p_component->len != nkey) {
  971. return JSONSL_MATCH_NOMATCH;
  972. }
  973. /* Check string comparison */
  974. cmpret = strncmp(p_component->pstr, key, nkey);
  975. if (cmpret == 0) {
  976. if (parent_level == jpr->ncomponents-1) {
  977. return JSONSL_MATCH_COMPLETE;
  978. } else {
  979. return JSONSL_MATCH_POSSIBLE;
  980. }
  981. }
  982. return JSONSL_MATCH_NOMATCH;
  983. }
  984. JSONSL_API
  985. void jsonsl_jpr_match_state_init(jsonsl_t jsn,
  986. jsonsl_jpr_t *jprs,
  987. size_t njprs)
  988. {
  989. size_t ii, *firstjmp;
  990. if (njprs == 0) {
  991. return;
  992. }
  993. jsn->jprs = (jsonsl_jpr_t *)malloc(sizeof(jsonsl_jpr_t) * njprs);
  994. jsn->jpr_count = njprs;
  995. jsn->jpr_root = (size_t*)calloc(1, sizeof(size_t) * njprs * jsn->levels_max);
  996. memcpy(jsn->jprs, jprs, sizeof(jsonsl_jpr_t) * njprs);
  997. /* Set the initial jump table values */
  998. firstjmp = jsn->jpr_root;
  999. for (ii = 0; ii < njprs; ii++) {
  1000. firstjmp[ii] = ii+1;
  1001. }
  1002. }
  1003. JSONSL_API
  1004. void jsonsl_jpr_match_state_cleanup(jsonsl_t jsn)
  1005. {
  1006. if (jsn->jpr_count == 0) {
  1007. return;
  1008. }
  1009. free(jsn->jpr_root);
  1010. free(jsn->jprs);
  1011. jsn->jprs = NULL;
  1012. jsn->jpr_root = NULL;
  1013. jsn->jpr_count = 0;
  1014. }
  1015. /**
  1016. * This function should be called exactly once on each element...
  1017. * This should also be called in recursive order, since we rely
  1018. * on the parent having been initalized for a match.
  1019. *
  1020. * Since the parent is checked for a match as well, we maintain a 'serial' counter.
  1021. * Whenever we traverse an element, we expect the serial to be the same as a global
  1022. * integer. If they do not match, we re-initialize the context, and set the serial.
  1023. *
  1024. * This ensures a type of consistency without having a proactive reset by the
  1025. * main lexer itself.
  1026. *
  1027. */
  1028. JSONSL_API
  1029. jsonsl_jpr_t jsonsl_jpr_match_state(jsonsl_t jsn,
  1030. struct jsonsl_state_st *state,
  1031. const char *key,
  1032. size_t nkey,
  1033. jsonsl_jpr_match_t *out)
  1034. {
  1035. struct jsonsl_state_st *parent_state;
  1036. jsonsl_jpr_t ret = NULL;
  1037. /* Jump and JPR tables for our own state and the parent state */
  1038. size_t *jmptable, *pjmptable;
  1039. size_t jmp_cur, ii, ourjmpidx;
  1040. if (!jsn->jpr_root) {
  1041. *out = JSONSL_MATCH_NOMATCH;
  1042. return NULL;
  1043. }
  1044. pjmptable = jsn->jpr_root + (jsn->jpr_count * (state->level-1));
  1045. jmptable = pjmptable + jsn->jpr_count;
  1046. /* If the parent cannot match, then invalidate it */
  1047. if (*pjmptable == 0) {
  1048. *jmptable = 0;
  1049. *out = JSONSL_MATCH_NOMATCH;
  1050. return NULL;
  1051. }
  1052. parent_state = jsn->stack + state->level - 1;
  1053. if (parent_state->type == JSONSL_T_LIST) {
  1054. nkey = (size_t) parent_state->nelem;
  1055. }
  1056. *jmptable = 0;
  1057. ourjmpidx = 0;
  1058. memset(jmptable, 0, sizeof(int) * jsn->jpr_count);
  1059. for (ii = 0; ii < jsn->jpr_count; ii++) {
  1060. jmp_cur = pjmptable[ii];
  1061. if (jmp_cur) {
  1062. jsonsl_jpr_t jpr = jsn->jprs[jmp_cur-1];
  1063. *out = jsonsl_jpr_match(jpr,
  1064. parent_state->type,
  1065. parent_state->level,
  1066. key, nkey);
  1067. if (*out == JSONSL_MATCH_COMPLETE) {
  1068. ret = jpr;
  1069. *jmptable = 0;
  1070. return ret;
  1071. } else if (*out == JSONSL_MATCH_POSSIBLE) {
  1072. jmptable[ourjmpidx] = ii+1;
  1073. ourjmpidx++;
  1074. }
  1075. } else {
  1076. break;
  1077. }
  1078. }
  1079. if (!*jmptable) {
  1080. *out = JSONSL_MATCH_NOMATCH;
  1081. }
  1082. return NULL;
  1083. }
  1084. JSONSL_API
  1085. const char *jsonsl_strmatchtype(jsonsl_jpr_match_t match)
  1086. {
  1087. #define X(T,v) \
  1088. if ( match == JSONSL_MATCH_##T ) \
  1089. return #T;
  1090. JSONSL_XMATCH
  1091. #undef X
  1092. return "<UNKNOWN>";
  1093. }
  1094. #endif /* JSONSL_WITH_JPR */
  1095. static char *
  1096. jsonsl__writeutf8(uint32_t pt, char *out)
  1097. {
  1098. #define ADD_OUTPUT(c) *out = (char)(c); out++;
  1099. if (pt < 0x80) {
  1100. ADD_OUTPUT(pt);
  1101. } else if (pt < 0x800) {
  1102. ADD_OUTPUT((pt >> 6) | 0xC0);
  1103. ADD_OUTPUT((pt & 0x3F) | 0x80);
  1104. } else if (pt < 0x10000) {
  1105. ADD_OUTPUT((pt >> 12) | 0xE0);
  1106. ADD_OUTPUT(((pt >> 6) & 0x3F) | 0x80);
  1107. ADD_OUTPUT((pt & 0x3F) | 0x80);
  1108. } else {
  1109. ADD_OUTPUT((pt >> 18) | 0xF0);
  1110. ADD_OUTPUT(((pt >> 12) & 0x3F) | 0x80);
  1111. ADD_OUTPUT(((pt >> 6) & 0x3F) | 0x80);
  1112. ADD_OUTPUT((pt & 0x3F) | 0x80);
  1113. }
  1114. return out;
  1115. #undef ADD_OUTPUT
  1116. }
  1117. /* Thanks snej (https://github.com/mnunberg/jsonsl/issues/9) */
  1118. static int
  1119. jsonsl__digit2int(char ch) {
  1120. int d = ch - '0';
  1121. if ((unsigned) d < 10) {
  1122. return d;
  1123. }
  1124. d = ch - 'a';
  1125. if ((unsigned) d < 6) {
  1126. return d + 10;
  1127. }
  1128. d = ch - 'A';
  1129. if ((unsigned) d < 6) {
  1130. return d + 10;
  1131. }
  1132. return -1;
  1133. }
  1134. /* Assume 's' is at least 4 bytes long */
  1135. static int
  1136. jsonsl__get_uescape_16(const char *s)
  1137. {
  1138. int ret = 0;
  1139. int cur;
  1140. #define GET_DIGIT(off) \
  1141. cur = jsonsl__digit2int(s[off]); \
  1142. if (cur == -1) { return -1; } \
  1143. ret |= (cur << (12 - (off * 4)));
  1144. GET_DIGIT(0);
  1145. GET_DIGIT(1);
  1146. GET_DIGIT(2);
  1147. GET_DIGIT(3);
  1148. #undef GET_DIGIT
  1149. return ret;
  1150. }
  1151. /**
  1152. * Utility function to convert escape sequences
  1153. */
  1154. JSONSL_API
  1155. size_t jsonsl_util_unescape_ex(const char *in,
  1156. char *out,
  1157. size_t len,
  1158. const int toEscape[128],
  1159. unsigned *oflags,
  1160. jsonsl_error_t *err,
  1161. const char **errat)
  1162. {
  1163. const unsigned char *c = (const unsigned char*)in;
  1164. char *begin_p = out;
  1165. unsigned oflags_s;
  1166. uint16_t last_codepoint = 0;
  1167. if (!oflags) {
  1168. oflags = &oflags_s;
  1169. }
  1170. *oflags = 0;
  1171. #define UNESCAPE_BAIL(e,offset) \
  1172. *err = JSONSL_ERROR_##e; \
  1173. if (errat) { \
  1174. *errat = (const char*)(c+ (ptrdiff_t)(offset)); \
  1175. } \
  1176. return 0;
  1177. for (; len; len--, c++, out++) {
  1178. int uescval;
  1179. if (*c != '\\') {
  1180. /* Not an escape, so we don't care about this */
  1181. goto GT_ASSIGN;
  1182. }
  1183. if (len < 2) {
  1184. UNESCAPE_BAIL(ESCAPE_INVALID, 0);
  1185. }
  1186. if (!is_allowed_escape(c[1])) {
  1187. UNESCAPE_BAIL(ESCAPE_INVALID, 1)
  1188. }
  1189. if ((toEscape && toEscape[(unsigned char)c[1] & 0x7f] == 0 &&
  1190. c[1] != '\\' && c[1] != '"')) {
  1191. /* if we don't want to unescape this string, write the escape sequence to the output */
  1192. *out++ = *c++;
  1193. if (--len == 0)
  1194. break;
  1195. goto GT_ASSIGN;
  1196. }
  1197. if (c[1] != 'u') {
  1198. /* simple skip-and-replace using pre-defined maps.
  1199. * TODO: should the maps actually reflect the desired
  1200. * replacement character in toEscape?
  1201. */
  1202. char esctmp = get_escape_equiv(c[1]);
  1203. if (esctmp) {
  1204. /* Check if there is a corresponding replacement */
  1205. *out = esctmp;
  1206. } else {
  1207. /* Just gobble up the 'reverse-solidus' */
  1208. *out = c[1];
  1209. }
  1210. len--;
  1211. c++;
  1212. /* do not assign, just continue */
  1213. continue;
  1214. }
  1215. /* next == 'u' */
  1216. if (len < 6) {
  1217. /* Need at least six characters.. */
  1218. UNESCAPE_BAIL(UESCAPE_TOOSHORT, 2);
  1219. }
  1220. uescval = jsonsl__get_uescape_16((const char *)c + 2);
  1221. if (uescval == -1) {
  1222. UNESCAPE_BAIL(PERCENT_BADHEX, -1);
  1223. } else if (uescval == 0) {
  1224. UNESCAPE_BAIL(INVALID_CODEPOINT, 2);
  1225. }
  1226. if (last_codepoint) {
  1227. uint16_t w1 = last_codepoint, w2 = (uint16_t)uescval;
  1228. uint32_t cp;
  1229. if (uescval < 0xDC00 || uescval > 0xDFFF) {
  1230. UNESCAPE_BAIL(INVALID_CODEPOINT, -1);
  1231. }
  1232. cp = (w1 & 0x3FF) << 10;
  1233. cp |= (w2 & 0x3FF);
  1234. cp += 0x10000;
  1235. out = jsonsl__writeutf8(cp, out) - 1;
  1236. last_codepoint = 0;
  1237. } else if (uescval < 0xD800 || uescval > 0xDFFF) {
  1238. *oflags |= JSONSL_SPECIALf_NONASCII;
  1239. out = jsonsl__writeutf8(uescval, out) - 1;
  1240. } else if (uescval > 0xD7FF && uescval < 0xDC00) {
  1241. *oflags |= JSONSL_SPECIALf_NONASCII;
  1242. last_codepoint = (uint16_t)uescval;
  1243. out--;
  1244. } else {
  1245. UNESCAPE_BAIL(INVALID_CODEPOINT, 2);
  1246. }
  1247. /* Post uescape cleanup */
  1248. len -= 5; /* Gobble up 5 chars after 'u' */
  1249. c += 5;
  1250. continue;
  1251. /* Only reached by previous branches */
  1252. GT_ASSIGN:
  1253. *out = *c;
  1254. }
  1255. if (last_codepoint) {
  1256. *err = JSONSL_ERROR_INVALID_CODEPOINT;
  1257. return 0;
  1258. }
  1259. *err = JSONSL_ERROR_SUCCESS;
  1260. return out - begin_p;
  1261. }
  1262. /**
  1263. * Character Table definitions.
  1264. * These were all generated via srcutil/genchartables.pl
  1265. */
  1266. /**
  1267. * This table contains the beginnings of non-string
  1268. * allowable (bareword) values.
  1269. */
  1270. static const unsigned short Special_Table[0x80] = {
  1271. /* 0x00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x1f */
  1272. /* 0x20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x2c */
  1273. /* 0x2d */ JSONSL_SPECIALf_DASH /* <-> */, /* 0x2d */
  1274. /* 0x2e */ 0,0, /* 0x2f */
  1275. /* 0x30 */ JSONSL_SPECIALf_ZERO /* <0> */, /* 0x30 */
  1276. /* 0x31 */ JSONSL_SPECIALf_UNSIGNED /* <1> */, /* 0x31 */
  1277. /* 0x32 */ JSONSL_SPECIALf_UNSIGNED /* <2> */, /* 0x32 */
  1278. /* 0x33 */ JSONSL_SPECIALf_UNSIGNED /* <3> */, /* 0x33 */
  1279. /* 0x34 */ JSONSL_SPECIALf_UNSIGNED /* <4> */, /* 0x34 */
  1280. /* 0x35 */ JSONSL_SPECIALf_UNSIGNED /* <5> */, /* 0x35 */
  1281. /* 0x36 */ JSONSL_SPECIALf_UNSIGNED /* <6> */, /* 0x36 */
  1282. /* 0x37 */ JSONSL_SPECIALf_UNSIGNED /* <7> */, /* 0x37 */
  1283. /* 0x38 */ JSONSL_SPECIALf_UNSIGNED /* <8> */, /* 0x38 */
  1284. /* 0x39 */ JSONSL_SPECIALf_UNSIGNED /* <9> */, /* 0x39 */
  1285. /* 0x3a */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x59 */
  1286. /* 0x5a */ 0,0,0,0,0,0,0,0,0,0,0,0, /* 0x65 */
  1287. /* 0x66 */ JSONSL_SPECIALf_FALSE /* <f> */, /* 0x66 */
  1288. /* 0x67 */ 0,0,0,0,0,0,0, /* 0x6d */
  1289. /* 0x6e */ JSONSL_SPECIALf_NULL /* <n> */, /* 0x6e */
  1290. /* 0x6f */ 0,0,0,0,0, /* 0x73 */
  1291. /* 0x74 */ JSONSL_SPECIALf_TRUE /* <t> */ /* 0x74 */
  1292. };
  1293. // Bit tables are order such that the MSB is bit 0.
  1294. //
  1295. /**
  1296. * Contains characters which signal the termination of any of the 'special' bareword
  1297. * values.
  1298. */
  1299. static const char Special_Endings[0x100] = {
  1300. /* 0x00 */ 0,0,0,0,0,0,0,0,0, /* 0x08 */
  1301. /* 0x09 */ 1 /* <TAB> */, /* 0x09 */
  1302. /* 0x0a */ 1 /* <LF> */, /* 0x0a */
  1303. /* 0x0b */ 0,0, /* 0x0c */
  1304. /* 0x0d */ 1 /* <CR> */, /* 0x0d */
  1305. /* 0x0e */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x1f */
  1306. /* 0x20 */ 1 /* <SP> */, /* 0x20 */
  1307. /* 0x21 */ 0, /* 0x21 */
  1308. /* 0x22 */ 1 /* " */, /* 0x22 */
  1309. /* 0x23 */ 0,0,0,0,0,0,0,0,0, /* 0x2b */
  1310. /* 0x2c */ 1 /* , */, /* 0x2c */
  1311. /* 0x2d */ 0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x39 */
  1312. /* 0x3a */ 1 /* : */, /* 0x3a */
  1313. /* 0x3b */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x5a */
  1314. /* 0x5b */ 1 /* [ */, /* 0x5b */
  1315. /* 0x5c */ 1 /* \ */, /* 0x5c */
  1316. /* 0x5d */ 1 /* ] */, /* 0x5d */
  1317. /* 0x5e */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x7a */
  1318. /* 0x7b */ 1 /* { */, /* 0x7b */
  1319. /* 0x7c */ 0, /* 0x7c */
  1320. /* 0x7d */ 1 /* } */, /* 0x7d */
  1321. /* 0x7e */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x9d */
  1322. /* 0x9e */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xbd */
  1323. /* 0xbe */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xdd */
  1324. /* 0xde */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xfd */
  1325. /* 0xfe */ 0 /* 0xfe */
  1326. };
  1327. static const uint32_t Special_Endings_bits[0x80 / 32] = {
  1328. 0b00000000011001000000000000000000,
  1329. 0b10100000000010000000000000100000,
  1330. 0b00000000000000000000000000011100,
  1331. 0b00000000000000000000000000010100
  1332. };
  1333. /**
  1334. * This table contains entries for the allowed whitespace as per RFC 4627
  1335. */
  1336. static const char Allowed_Whitespace[0x100] = {
  1337. /* 0x00 */ 0,0,0,0,0,0,0,0,0, /* 0x08 */
  1338. /* 0x09 */ 1 /* <TAB> */, /* 0x09 */
  1339. /* 0x0a */ 1 /* <LF> */, /* 0x0a */
  1340. /* 0x0b */ 0,0, /* 0x0c */
  1341. /* 0x0d */ 1 /* <CR> */, /* 0x0d */
  1342. /* 0x0e */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x1f */
  1343. /* 0x20 */ 1 /* <SP> */, /* 0x20 */
  1344. /* 0x21 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x40 */
  1345. /* 0x41 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x60 */
  1346. /* 0x61 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x80 */
  1347. /* 0x81 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xa0 */
  1348. /* 0xa1 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xc0 */
  1349. /* 0xc1 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xe0 */
  1350. /* 0xe1 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* 0xfe */
  1351. };
  1352. static const uint32_t Allowed_Whitespace_bits = 0b00000000011001000000000000000000;
  1353. static const char String_No_Passthrough[0x100] = {
  1354. /* 0x00 */ 1 /* <NUL> */, /* 0x00 */
  1355. /* 0x01 */ 1 /* <SOH> */, /* 0x01 */
  1356. /* 0x02 */ 1 /* <STX> */, /* 0x02 */
  1357. /* 0x03 */ 1 /* <ETX> */, /* 0x03 */
  1358. /* 0x04 */ 1 /* <EOT> */, /* 0x04 */
  1359. /* 0x05 */ 1 /* <ENQ> */, /* 0x05 */
  1360. /* 0x06 */ 1 /* <ACK> */, /* 0x06 */
  1361. /* 0x07 */ 1 /* <BEL> */, /* 0x07 */
  1362. /* 0x08 */ 1 /* <BS> */, /* 0x08 */
  1363. /* 0x09 */ 1 /* <HT> */, /* 0x09 */
  1364. /* 0x0a */ 1 /* <LF> */, /* 0x0a */
  1365. /* 0x0b */ 1 /* <VT> */, /* 0x0b */
  1366. /* 0x0c */ 1 /* <FF> */, /* 0x0c */
  1367. /* 0x0d */ 1 /* <CR> */, /* 0x0d */
  1368. /* 0x0e */ 1 /* <SO> */, /* 0x0e */
  1369. /* 0x0f */ 1 /* <SI> */, /* 0x0f */
  1370. /* 0x10 */ 1 /* <DLE> */, /* 0x10 */
  1371. /* 0x11 */ 1 /* <DC1> */, /* 0x11 */
  1372. /* 0x12 */ 1 /* <DC2> */, /* 0x12 */
  1373. /* 0x13 */ 1 /* <DC3> */, /* 0x13 */
  1374. /* 0x14 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x21 */
  1375. /* 0x22 */ 1 /* <"> */, /* 0x22 */
  1376. /* 0x23 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x42 */
  1377. /* 0x43 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x5b */
  1378. /* 0x5c */ 1 /* <\> */, /* 0x5c */
  1379. /* 0x5d */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x7c */
  1380. /* 0x7d */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x9c */
  1381. /* 0x9d */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xbc */
  1382. /* 0xbd */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xdc */
  1383. /* 0xdd */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xfc */
  1384. /* 0xfd */ 0,0, /* 0xfe */
  1385. };
  1386. /**
  1387. * Allowable two-character 'common' escapes:
  1388. */
  1389. static const char Allowed_Escapes[0x100] = {
  1390. /* 0x00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x1f */
  1391. /* 0x20 */ 0,0, /* 0x21 */
  1392. /* 0x22 */ 1 /* <"> */, /* 0x22 */
  1393. /* 0x23 */ 0,0,0,0,0,0,0,0,0,0,0,0, /* 0x2e */
  1394. /* 0x2f */ 1 /* </> */, /* 0x2f */
  1395. /* 0x30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x4f */
  1396. /* 0x50 */ 0,0,0,0,0,0,0,0,0,0,0,0, /* 0x5b */
  1397. /* 0x5c */ 1 /* <\> */, /* 0x5c */
  1398. /* 0x5d */ 0,0,0,0,0, /* 0x61 */
  1399. /* 0x62 */ 1 /* <b> */, /* 0x62 */
  1400. /* 0x63 */ 0,0,0, /* 0x65 */
  1401. /* 0x66 */ 1 /* <f> */, /* 0x66 */
  1402. /* 0x67 */ 0,0,0,0,0,0,0, /* 0x6d */
  1403. /* 0x6e */ 1 /* <n> */, /* 0x6e */
  1404. /* 0x6f */ 0,0,0, /* 0x71 */
  1405. /* 0x72 */ 1 /* <r> */, /* 0x72 */
  1406. /* 0x73 */ 0, /* 0x73 */
  1407. /* 0x74 */ 1 /* <t> */, /* 0x74 */
  1408. /* 0x75 */ 1 /* <u> */, /* 0x75 */
  1409. /* 0x76 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x95 */
  1410. /* 0x96 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xb5 */
  1411. /* 0xb6 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xd5 */
  1412. /* 0xd6 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xf5 */
  1413. /* 0xf6 */ 0,0,0,0,0,0,0,0,0, /* 0xfe */
  1414. };
  1415. static const uint32_t Allowed_Escapes_bits[0x80 / 32] = {
  1416. 0b00000000000000000000000000000000,
  1417. 0b00100000000000010000000000000000,
  1418. 0b00000000000000000000000000001000,
  1419. 0b00100010000000100010110000000000
  1420. };
  1421. /**
  1422. * This table contains the _values_ for a given (single) escaped character.
  1423. */
  1424. static unsigned char Escape_Equivs[0x100] = {
  1425. /* 0x00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x1f */
  1426. /* 0x20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x3f */
  1427. /* 0x40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x5f */
  1428. /* 0x60 */ 0,0, /* 0x61 */
  1429. /* 0x62 */ 8 /* <b> */, /* 0x62 */
  1430. /* 0x63 */ 0,0,0, /* 0x65 */
  1431. /* 0x66 */ 12 /* <f> */, /* 0x66 */
  1432. /* 0x67 */ 0,0,0,0,0,0,0, /* 0x6d */
  1433. /* 0x6e */ 10 /* <n> */, /* 0x6e */
  1434. /* 0x6f */ 0,0,0, /* 0x71 */
  1435. /* 0x72 */ 13 /* <r> */, /* 0x72 */
  1436. /* 0x73 */ 0, /* 0x73 */
  1437. /* 0x74 */ 9 /* <t> */, /* 0x74 */
  1438. /* 0x75 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x94 */
  1439. /* 0x95 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xb4 */
  1440. /* 0xb5 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xd4 */
  1441. /* 0xd5 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0xf4 */
  1442. /* 0xf5 */ 0,0,0,0,0,0,0,0,0,0 /* 0xfe */
  1443. };
  1444. /* Definitions of above-declared static functions */
  1445. static char get_escape_equiv(unsigned c) {
  1446. switch(c) {
  1447. case 'b':
  1448. return '\b';
  1449. case 'n':
  1450. return '\n';
  1451. case 'r':
  1452. return '\r';
  1453. case 't':
  1454. return '\t';
  1455. case 'f':
  1456. return '\f';
  1457. }
  1458. return 0;
  1459. }
  1460. static unsigned extract_special(unsigned c) {
  1461. return (c < 0x80) ? Special_Table[c & 0xff] : 0;
  1462. }
  1463. static int is_special_end(unsigned c) {
  1464. return (c < 0x80) && (Special_Endings_bits[c >> 5] & (1 << (31 - (c & 31))));
  1465. }
  1466. static int is_allowed_whitespace(unsigned c) {
  1467. return c == ' ' || (c < 0x20 && (Allowed_Whitespace_bits & (1 << (31 - c))));
  1468. }
  1469. static int is_allowed_escape(unsigned c) {
  1470. return (c < 0x80) && (Allowed_Escapes_bits[c >> 5] & (1 << (31 - (c & 31))));
  1471. }
  1472. static int is_simple_char(unsigned c) {
  1473. return !(c < 0x14 || c == '"' || c == '\\');
  1474. }
  1475. /* Clean up all our macros! */
  1476. #undef INCR_METRIC
  1477. #undef INCR_GENERIC
  1478. #undef INCR_STRINGY_CATCH
  1479. #undef CASE_DIGITS
  1480. #undef INVOKE_ERROR
  1481. #undef STACK_PUSH
  1482. #undef STACK_POP_NOPOS
  1483. #undef STACK_POP
  1484. #undef CALLBACK_AND_POP_NOPOS
  1485. #undef CALLBACK_AND_POP
  1486. #undef SPECIAL_POP
  1487. #undef CUR_CHAR
  1488. #undef DO_CALLBACK
  1489. #undef ENSURE_HVAL
  1490. #undef VERIFY_SPECIAL
  1491. #undef STATE_SPECIAL_LENGTH
  1492. #undef IS_NORMAL_NUMBER
  1493. #undef STATE_NUM_LAST
  1494. #undef FASTPARSE_EXHAUSTED
  1495. #undef FASTPARSE_BREAK