diff --git a/jparse/CHANGES.md b/jparse/CHANGES.md index 203f8126..0bdea50f 100644 --- a/jparse/CHANGES.md +++ b/jparse/CHANGES.md @@ -25,6 +25,24 @@ subdirectories and the tools/directories under that (in other words under Fixed comments in some tools. +Fix format/display issue in `jstrdecode -h`. + +Add missing `const char *const jparse_utf8_version` (assigned to +`JPARSE_UTF8_VERSION`) and rename `json_parser_version` to +`jparse_library_version` to match the `#define`d macro name, which was changed a +while back. + +Improve comments in `jparse.l`, at least for those who are forced to read the +generated code, perhaps in a torture chamber or something like that, or for +those who want hallucinations or nightmares :-) or simply those who are really +curious what flex does. + +Add extra sanity checks to `jstrencode(1)` and `jstrdecode(1)` when freeing the +lists. The function `free_jstring_list()` now takes a `struct jstring +**jstring_list` and if not NULL it will set `*jstring_list` to NULL, after +freeing the list, in case the caller does something silly. Even so, the two +tools now set the list to NULL after calling the free function. + ## Release 2.0.0 2024-10-31 diff --git a/jparse/jparse.h b/jparse/jparse.h index 457d8314..e67041ea 100644 --- a/jparse/jparse.h +++ b/jparse/jparse.h @@ -78,8 +78,9 @@ /* * globals */ -extern const char *const json_parser_version; /* library version format: major.minor YYYY-MM-DD */ +extern const char *const jparse_library_version; /* library version format: major.minor YYYY-MM-DD */ extern const char *const jparse_version; /* jparse version format: major.minor YYYY-MM-DD */ +extern const char *const jparse_utf8_version; /* jparse utf8 version format: major.minor YYYY-MM-DD */ /* lexer and parser specific variables */ extern int jparse_debug; diff --git a/jparse/jparse.l b/jparse/jparse.l index 1391c62a..d37e8538 100644 --- a/jparse/jparse.l +++ b/jparse/jparse.l @@ -111,7 +111,13 @@ static YY_BUFFER_STATE bs; * Section 1: Patterns (regular expressions) and actions. */ +/* + * JSON_WS [ \t\r]+ + */ JSON_WS [ \t\r]+ +/* + * JSON_NL \n+ + */ JSON_NL \n+ /* * NOTE: on the subject of JSON_STRING one might ask the question about the @@ -128,20 +134,63 @@ JSON_NL \n+ * interested, the old regexp was: * * \"([^\n"]|\\\")*\" + * + * ...and this is the current one: + * + * JSON_STRING \"([^"\x01-\x1f]|\\\")*\" */ JSON_STRING \"([^"\x01-\x1f]|\\\")*\" +/* + * JSON_INTEGER -?([1-9][0-9]*|0) + */ JSON_INTEGER -?([1-9][0-9]*|0) +/* + * JSON_FRACTION "."[0-9]+ + */ JSON_FRACTION "."[0-9]+ +/* + * JSON_EXPONENT [Ee][-+]?[0-9]+ + */ JSON_EXPONENT [Ee][-+]?[0-9]+ +/* + * JSON_NUMBER ({JSON_INTEGER}|{JSON_INTEGER}{JSON_FRACTION}|{JSON_INTEGER}{JSON_FRACTION}{JSON_EXPONENT}|{JSON_INTEGER}{JSON_EXPONENT}) + */ JSON_NUMBER ({JSON_INTEGER}|{JSON_INTEGER}{JSON_FRACTION}|{JSON_INTEGER}{JSON_FRACTION}{JSON_EXPONENT}|{JSON_INTEGER}{JSON_EXPONENT}) +/* + * JSON_TRUE "true" + */ JSON_TRUE "true" +/* + * JSON_FALSE "false" + */ JSON_FALSE "false" +/* + * JSON_NULL "null" + */ JSON_NULL "null" +/* + * JSON_OPEN_BRACE "{" + */ JSON_OPEN_BRACE "{" +/* + * JSON_CLOSE_BRACE "}" + */ JSON_CLOSE_BRACE "}" +/* + * JSON_OPEN_BRACKET "[" + */ JSON_OPEN_BRACKET "[" +/* + * JSON_CLOSE_BRACKET "]" + */ JSON_CLOSE_BRACKET "]" +/* + * JSON_COLON ":" + */ JSON_COLON ":" +/* + * JSON_COMMA "," + */ JSON_COMMA "," /* Actions. */ @@ -220,7 +269,8 @@ JSON_COMMA "," . { /* invalid token: any other character */ - dbg(DBG_LOW, "at line %d column %d: invalid token: 0x%02x = <%c>", yylloc->first_line, yylloc->first_column, *yytext, *yytext); + dbg(DBG_LOW, "at line %d column %d: invalid token: 0x%02x = <%c>", yylloc->first_line, + yylloc->first_column, *yytext, *yytext); /* * This is a hack for better error messages with diff --git a/jparse/jparse.lex.ref.h b/jparse/jparse.lex.ref.h index e103d859..b451d32b 100644 --- a/jparse/jparse.lex.ref.h +++ b/jparse/jparse.lex.ref.h @@ -777,7 +777,7 @@ extern int yylex \ #undef yyTABLES_NAME #endif -#line 254 "./jparse.l" +#line 304 "./jparse.l" #line 732 "jparse.lex.h" diff --git a/jparse/jparse.ref.c b/jparse/jparse.ref.c index 4ece006a..15d29ae5 100644 --- a/jparse/jparse.ref.c +++ b/jparse/jparse.ref.c @@ -868,6 +868,12 @@ static YY_BUFFER_STATE bs; /* * Section 1: Patterns (regular expressions) and actions. */ +/* + * JSON_WS [ \t\r]+ + */ +/* + * JSON_NL \n+ + */ /* * NOTE: on the subject of JSON_STRING one might ask the question about the * tighter restrictions on JSON strings and why we don't even consider them. @@ -883,9 +889,52 @@ static YY_BUFFER_STATE bs; * interested, the old regexp was: * * \"([^\n"]|\\\")*\" + * + * ...and this is the current one: + * + * JSON_STRING \"([^"\x01-\x1f]|\\\")*\" + */ +/* + * JSON_INTEGER -?([1-9][0-9]*|0) + */ +/* + * JSON_FRACTION "."[0-9]+ + */ +/* + * JSON_EXPONENT [Ee][-+]?[0-9]+ + */ +/* + * JSON_NUMBER ({JSON_INTEGER}|{JSON_INTEGER}{JSON_FRACTION}|{JSON_INTEGER}{JSON_FRACTION}{JSON_EXPONENT}|{JSON_INTEGER}{JSON_EXPONENT}) + */ +/* + * JSON_TRUE "true" + */ +/* + * JSON_FALSE "false" + */ +/* + * JSON_NULL "null" + */ +/* + * JSON_OPEN_BRACE "{" + */ +/* + * JSON_CLOSE_BRACE "}" + */ +/* + * JSON_OPEN_BRACKET "[" + */ +/* + * JSON_CLOSE_BRACKET "]" + */ +/* + * JSON_COLON ":" + */ +/* + * JSON_COMMA "," */ /* Actions. */ -#line 837 "jparse.c" +#line 886 "jparse.c" #define INITIAL 0 @@ -1165,9 +1214,9 @@ YY_DECL } { -#line 148 "./jparse.l" +#line 197 "./jparse.l" -#line 1119 "jparse.c" +#line 1168 "jparse.c" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { @@ -1238,7 +1287,7 @@ YY_DECL case 1: YY_RULE_SETUP -#line 149 "./jparse.l" +#line 198 "./jparse.l" { /* * Whitespace excluding newlines @@ -1258,14 +1307,14 @@ YY_RULE_SETUP case 2: /* rule 2 can match eol */ YY_RULE_SETUP -#line 165 "./jparse.l" +#line 214 "./jparse.l" { yycolumn = 1; /* on newline we need to reset the column for error location tracking */ } YY_BREAK case 3: YY_RULE_SETUP -#line 169 "./jparse.l" +#line 218 "./jparse.l" { /* string */ return JSON_STRING; @@ -1273,7 +1322,7 @@ YY_RULE_SETUP YY_BREAK case 4: YY_RULE_SETUP -#line 174 "./jparse.l" +#line 223 "./jparse.l" { /* number */ return JSON_NUMBER; @@ -1281,7 +1330,7 @@ YY_RULE_SETUP YY_BREAK case 5: YY_RULE_SETUP -#line 179 "./jparse.l" +#line 228 "./jparse.l" { /* null object */ return JSON_NULL; @@ -1289,7 +1338,7 @@ YY_RULE_SETUP YY_BREAK case 6: YY_RULE_SETUP -#line 184 "./jparse.l" +#line 233 "./jparse.l" { /* boolean: true */ return JSON_TRUE; @@ -1297,7 +1346,7 @@ YY_RULE_SETUP YY_BREAK case 7: YY_RULE_SETUP -#line 188 "./jparse.l" +#line 237 "./jparse.l" { /* boolean: false */ return JSON_FALSE; @@ -1305,7 +1354,7 @@ YY_RULE_SETUP YY_BREAK case 8: YY_RULE_SETUP -#line 193 "./jparse.l" +#line 242 "./jparse.l" { /* start of object */ return JSON_OPEN_BRACE; @@ -1313,7 +1362,7 @@ YY_RULE_SETUP YY_BREAK case 9: YY_RULE_SETUP -#line 197 "./jparse.l" +#line 246 "./jparse.l" { /* end of object */ return JSON_CLOSE_BRACE; @@ -1321,7 +1370,7 @@ YY_RULE_SETUP YY_BREAK case 10: YY_RULE_SETUP -#line 202 "./jparse.l" +#line 251 "./jparse.l" { /* start of array */ return JSON_OPEN_BRACKET; @@ -1329,7 +1378,7 @@ YY_RULE_SETUP YY_BREAK case 11: YY_RULE_SETUP -#line 206 "./jparse.l" +#line 255 "./jparse.l" { /* end of array */ return JSON_CLOSE_BRACKET; @@ -1337,7 +1386,7 @@ YY_RULE_SETUP YY_BREAK case 12: YY_RULE_SETUP -#line 211 "./jparse.l" +#line 260 "./jparse.l" { /* colon or 'equals' */ return JSON_COLON; @@ -1345,7 +1394,7 @@ YY_RULE_SETUP YY_BREAK case 13: YY_RULE_SETUP -#line 216 "./jparse.l" +#line 265 "./jparse.l" { /* comma: name/value pair separator */ return JSON_COMMA; @@ -1353,10 +1402,11 @@ YY_RULE_SETUP YY_BREAK case 14: YY_RULE_SETUP -#line 221 "./jparse.l" +#line 270 "./jparse.l" { /* invalid token: any other character */ - dbg(DBG_LOW, "at line %d column %d: invalid token: 0x%02x = <%c>", yylloc->first_line, yylloc->first_column, *yytext, *yytext); + dbg(DBG_LOW, "at line %d column %d: invalid token: 0x%02x = <%c>", yylloc->first_line, + yylloc->first_column, *yytext, *yytext); /* * This is a hack for better error messages with @@ -1389,10 +1439,10 @@ YY_RULE_SETUP YY_BREAK case 15: YY_RULE_SETUP -#line 254 "./jparse.l" +#line 304 "./jparse.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 1344 "jparse.c" +#line 1394 "jparse.c" case YY_STATE_EOF(INITIAL): yyterminate(); @@ -2554,7 +2604,7 @@ void yyfree (void * ptr , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 254 "./jparse.l" +#line 304 "./jparse.l" /* Section 2: Code that's copied to the generated scanner */ diff --git a/jparse/jparse.tab.ref.c b/jparse/jparse.tab.ref.c index 4eece827..59e1fb96 100644 --- a/jparse/jparse.tab.ref.c +++ b/jparse/jparse.tab.ref.c @@ -155,11 +155,12 @@ int jparse_debug = 0; /* 0 ==> verbose bison debug off, 1 ==> verbose bison debu /* * JSON parser library version */ -const char *const json_parser_version = JPARSE_LIBRARY_VERSION; /* library version format: major.minor YYYY-MM-DD */ +const char *const jparse_library_version = JPARSE_LIBRARY_VERSION;/* library version format: major.minor YYYY-MM-DD */ const char *const jparse_version = JPARSE_VERSION; /* jparse version format: major.minor YYYY-MM-DD */ +const char *const jparse_utf8_version = JPARSE_UTF8_VERSION; /* jparse utf8 version format: major.minor YYYY-MM-DD */ -#line 112 "jparse.tab.c" +#line 113 "jparse.tab.c" # ifndef YY_CAST # ifdef __cplusplus @@ -579,9 +580,9 @@ static const yytype_int8 yytranslate[] = /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int16 yyrline[] = { - 0, 226, 226, 284, 315, 346, 377, 408, 438, 468, - 500, 531, 561, 595, 634, 670, 701, 731, 765, 803, - 836, 868 + 0, 227, 227, 285, 316, 347, 378, 409, 439, 469, + 501, 532, 562, 596, 635, 671, 702, 732, 766, 804, + 837, 869 }; #endif @@ -1544,7 +1545,7 @@ YYLTYPE yylloc = yyloc_default; switch (yyn) { case 2: /* json: json_element */ -#line 227 "./jparse.y" +#line 228 "./jparse.y" { /* * $$ = $json @@ -1598,11 +1599,11 @@ YYLTYPE yylloc = yyloc_default; "json: json_element"); } } -#line 1551 "jparse.tab.c" +#line 1552 "jparse.tab.c" break; case 3: /* json_value: json_object */ -#line 285 "./jparse.y" +#line 286 "./jparse.y" { /* * $$ = $json_value @@ -1631,11 +1632,11 @@ YYLTYPE yylloc = yyloc_default; "json_value: json_object"); } } -#line 1584 "jparse.tab.c" +#line 1585 "jparse.tab.c" break; case 4: /* json_value: json_array */ -#line 316 "./jparse.y" +#line 317 "./jparse.y" { /* * $$ = $json_value @@ -1664,11 +1665,11 @@ YYLTYPE yylloc = yyloc_default; "json_value: json_array"); } } -#line 1617 "jparse.tab.c" +#line 1618 "jparse.tab.c" break; case 5: /* json_value: json_string */ -#line 347 "./jparse.y" +#line 348 "./jparse.y" { /* * $$ = $json_value @@ -1697,11 +1698,11 @@ YYLTYPE yylloc = yyloc_default; "json_value: json_string"); } } -#line 1650 "jparse.tab.c" +#line 1651 "jparse.tab.c" break; case 6: /* json_value: json_number */ -#line 378 "./jparse.y" +#line 379 "./jparse.y" { /* * $$ = $json_value @@ -1730,11 +1731,11 @@ YYLTYPE yylloc = yyloc_default; "json_value: json_number"); } } -#line 1683 "jparse.tab.c" +#line 1684 "jparse.tab.c" break; case 7: /* json_value: "true" */ -#line 409 "./jparse.y" +#line 410 "./jparse.y" { /* * $$ = $json_value @@ -1762,11 +1763,11 @@ YYLTYPE yylloc = yyloc_default; "json_value: JSON_TRUE"); } } -#line 1715 "jparse.tab.c" +#line 1716 "jparse.tab.c" break; case 8: /* json_value: "false" */ -#line 439 "./jparse.y" +#line 440 "./jparse.y" { /* * $$ = $json_value @@ -1794,11 +1795,11 @@ YYLTYPE yylloc = yyloc_default; "json_value: JSON_FALSE"); } } -#line 1747 "jparse.tab.c" +#line 1748 "jparse.tab.c" break; case 9: /* json_value: "null" */ -#line 469 "./jparse.y" +#line 470 "./jparse.y" { /* * $$ = $json_value @@ -1826,11 +1827,11 @@ YYLTYPE yylloc = yyloc_default; "json_value: JSON_NULL"); } } -#line 1779 "jparse.tab.c" +#line 1780 "jparse.tab.c" break; case 10: /* json_object: "{" json_members "}" */ -#line 501 "./jparse.y" +#line 502 "./jparse.y" { /* * $$ = $json_object @@ -1859,11 +1860,11 @@ YYLTYPE yylloc = yyloc_default; "json_object: JSON_OPEN_BRACE json_members JSON_CLOSE_BRACE"); } } -#line 1812 "jparse.tab.c" +#line 1813 "jparse.tab.c" break; case 11: /* json_object: "{" "}" */ -#line 532 "./jparse.y" +#line 533 "./jparse.y" { /* * $$ = $json_object @@ -1889,11 +1890,11 @@ YYLTYPE yylloc = yyloc_default; "json_object: JSON_OPEN_BRACE JSON_CLOSE_BRACE"); } } -#line 1842 "jparse.tab.c" +#line 1843 "jparse.tab.c" break; case 12: /* json_members: json_member */ -#line 562 "./jparse.y" +#line 563 "./jparse.y" { /* * $$ = $json_members @@ -1925,11 +1926,11 @@ YYLTYPE yylloc = yyloc_default; "json_members: json_member"); } } -#line 1878 "jparse.tab.c" +#line 1879 "jparse.tab.c" break; case 13: /* json_members: json_members "," json_member */ -#line 596 "./jparse.y" +#line 597 "./jparse.y" { /* * $$ = $json_members @@ -1964,11 +1965,11 @@ YYLTYPE yylloc = yyloc_default; "json_members: json_members JSON_COMMA json_member"); } } -#line 1917 "jparse.tab.c" +#line 1918 "jparse.tab.c" break; case 14: /* json_member: json_string ":" json_element */ -#line 635 "./jparse.y" +#line 636 "./jparse.y" { /* * $$ = $json_member @@ -2000,11 +2001,11 @@ YYLTYPE yylloc = yyloc_default; "json_member: json_string JSON_COLON json_element"); } } -#line 1953 "jparse.tab.c" +#line 1954 "jparse.tab.c" break; case 15: /* json_array: "[" json_elements "]" */ -#line 671 "./jparse.y" +#line 672 "./jparse.y" { /* * $$ = $json_array @@ -2033,11 +2034,11 @@ YYLTYPE yylloc = yyloc_default; "json_array: JSON_OPEN_BRACKET json_elements JSON_CLOSE_BRACKET"); } } -#line 1986 "jparse.tab.c" +#line 1987 "jparse.tab.c" break; case 16: /* json_array: "[" "]" */ -#line 702 "./jparse.y" +#line 703 "./jparse.y" { /* * $$ = $json_array @@ -2063,11 +2064,11 @@ YYLTYPE yylloc = yyloc_default; "json_array: JSON_OPEN_BRACKET JSON_CLOSE_BRACKET"); } } -#line 2016 "jparse.tab.c" +#line 2017 "jparse.tab.c" break; case 17: /* json_elements: json_element */ -#line 732 "./jparse.y" +#line 733 "./jparse.y" { /* * $$ = $json_elements @@ -2099,11 +2100,11 @@ YYLTYPE yylloc = yyloc_default; "json_elements: json_element"); } } -#line 2052 "jparse.tab.c" +#line 2053 "jparse.tab.c" break; case 18: /* json_elements: json_elements "," json_element */ -#line 766 "./jparse.y" +#line 767 "./jparse.y" { /* * $$ = $json_elements @@ -2137,11 +2138,11 @@ YYLTYPE yylloc = yyloc_default; "json_elements: json_elements JSON_COMMA json_element"); } } -#line 2090 "jparse.tab.c" +#line 2091 "jparse.tab.c" break; case 19: /* json_element: json_value */ -#line 804 "./jparse.y" +#line 805 "./jparse.y" { /* * $$ = $json_element @@ -2170,11 +2171,11 @@ YYLTYPE yylloc = yyloc_default; "json_element: json_value"); } } -#line 2123 "jparse.tab.c" +#line 2124 "jparse.tab.c" break; case 20: /* json_string: JSON_STRING */ -#line 837 "./jparse.y" +#line 838 "./jparse.y" { /* * $$ = $json_string @@ -2202,11 +2203,11 @@ YYLTYPE yylloc = yyloc_default; "json_string: JSON_STRING"); } } -#line 2155 "jparse.tab.c" +#line 2156 "jparse.tab.c" break; case 21: /* json_number: JSON_NUMBER */ -#line 869 "./jparse.y" +#line 870 "./jparse.y" { /* * $$ = $json_number @@ -2234,11 +2235,11 @@ YYLTYPE yylloc = yyloc_default; "json_number: JSON_NUMBER"); } } -#line 2187 "jparse.tab.c" +#line 2188 "jparse.tab.c" break; -#line 2191 "jparse.tab.c" +#line 2192 "jparse.tab.c" default: break; } @@ -2445,7 +2446,7 @@ YYLTYPE yylloc = yyloc_default; return yyresult; } -#line 899 "./jparse.y" +#line 900 "./jparse.y" diff --git a/jparse/jparse.tab.ref.h b/jparse/jparse.tab.ref.h index b76d72a5..a43fcb03 100644 --- a/jparse/jparse.tab.ref.h +++ b/jparse/jparse.tab.ref.h @@ -104,7 +104,7 @@ extern int jparse_debug; #endif /* "%code requires" blocks. */ -#line 118 "./jparse.y" +#line 119 "./jparse.y" #if !defined(JPARSE_LTYPE_IS_DECLARED) struct JPARSE_LTYPE @@ -195,7 +195,7 @@ struct JPARSE_LTYPE int jparse_parse (struct json **tree, yyscan_t scanner); /* "%code provides" blocks. */ -#line 110 "./jparse.y" +#line 111 "./jparse.y" #ifndef YY_DECL #define YY_DECL int jparse_lex(JPARSE_STYPE *yylval_param, JPARSE_LTYPE *yylloc_param, yyscan_t yyscanner) diff --git a/jparse/jparse.y b/jparse/jparse.y index bd6f3d18..8f011fca 100644 --- a/jparse/jparse.y +++ b/jparse/jparse.y @@ -20,7 +20,7 @@ /* Section 0: Declarations */ /* - * We enable lookahead correction parser for improved errors: + * We enable lookahead correction parser for improved error messages: * * %define parse.lac full */ @@ -102,8 +102,9 @@ int jparse_debug = 0; /* 0 ==> verbose bison debug off, 1 ==> verbose bison debu /* * JSON parser library version */ -const char *const json_parser_version = JPARSE_LIBRARY_VERSION; /* library version format: major.minor YYYY-MM-DD */ +const char *const jparse_library_version = JPARSE_LIBRARY_VERSION;/* library version format: major.minor YYYY-MM-DD */ const char *const jparse_version = JPARSE_VERSION; /* jparse version format: major.minor YYYY-MM-DD */ +const char *const jparse_utf8_version = JPARSE_UTF8_VERSION; /* jparse utf8 version format: major.minor YYYY-MM-DD */ %} diff --git a/jparse/json_parse.c b/jparse/json_parse.c index 92e90287..b8c0a4a4 100644 --- a/jparse/json_parse.c +++ b/jparse/json_parse.c @@ -503,7 +503,7 @@ jdecencchk(int entertainment) if (entertainment > 0) { /* - * :-) + * :-) :-) */ decstr = "\\uD83C\\uDF0E\\u2604"; /* @@ -558,7 +558,7 @@ jdecencchk(int entertainment) } /* - * :-) + * :-) :-) :-) */ decstr = "\\uD83D\\uDD25\\uD83C\\uDF0E\\uD83E\\uDD96\\uD83E\\uDD95\\u2604"; /* @@ -616,6 +616,10 @@ jdecencchk(int entertainment) * and now we entertain, at least for those with a dark sense of humour :-) */ if (entertainment > 1) { + + /* + * :-) :-) :-) :-) + */ decstr = "\\uD83D\\uDD25\\uD83E\\uDDD9"; /* * test encoding the JSON decoded string @@ -673,6 +677,9 @@ jdecencchk(int entertainment) } if (entertainment > 2) { + /* + * :-) :-) :-) :-) :-) + */ decstr = "\\uD83E\\uDEC3\\uD83D\\uDD25\\uD83D\\uDC09"; /* * test encoding the JSON decoded string @@ -731,6 +738,9 @@ jdecencchk(int entertainment) */ if (entertainment > 2) { dbg(DBG_VVHIGH, "entertainment level %u", entertainment); + /* + * :-) :-) :-) :-) :-) :-) + */ decstr = "\\uD83E\\uDD30\\uD83D\\uDD25\\uD83D\\uDC09"; /* * test encoding the JSON decoded string diff --git a/jparse/jstr_util.c b/jparse/jstr_util.c index 3c9d0c49..23b6042a 100644 --- a/jparse/jstr_util.c +++ b/jparse/jstr_util.c @@ -155,22 +155,25 @@ free_jstring(struct jstring **jstr) * * given: * - * jstring_list pointer to list to free + * jstring_list pointer to pointer to list to free * - * This function takes a struct jstring *, a pointer to a linked list of struct + * This function takes a struct jstring **, a pointer to a linked list of struct * jstring *. * * NOTE: it is ASSUMED that the string in each struct jstring * is allocated on * the stack due to how the encoding/decoding works. If this is not the case * then expect errors. + * + * NOTE: if jstring_list is NULL then nothing is done. */ void -free_jstring_list(struct jstring *jstring_list) +free_jstring_list(struct jstring **jstring_list) { struct jstring *jstr = NULL; /* current in list */ struct jstring *jstr_next = NULL; /* next in list */ - for (jstr = jstring_list; jstr != NULL; jstr = jstr_next) { + + for (jstr = jstring_list != NULL ? *jstring_list : NULL; jstr != NULL; jstr = jstr_next) { jstr_next = jstr->next; /* get next in list before we free the current */ /* free current json string */ @@ -178,5 +181,9 @@ free_jstring_list(struct jstring *jstring_list) jstr = NULL; } + if (jstring_list != NULL) { + *jstring_list = NULL; + } + jstring_list = NULL; } diff --git a/jparse/jstr_util.h b/jparse/jstr_util.h index b0c5c1a9..fbb57a07 100644 --- a/jparse/jstr_util.h +++ b/jparse/jstr_util.h @@ -75,6 +75,6 @@ struct jstring extern struct jstring *alloc_jstr(char *string, size_t bufsiz); extern int parse_entertainment(char const *optarg); extern void free_jstring(struct jstring **jstr); -extern void free_jstring_list(struct jstring *jstring_list); +extern void free_jstring_list(struct jstring **jstring_list); #endif /* INCLUDE_JSTR_UTIL_H */ diff --git a/jparse/jstrdecode.c b/jparse/jstrdecode.c index 80977a48..208540f2 100644 --- a/jparse/jstrdecode.c +++ b/jparse/jstrdecode.c @@ -57,7 +57,7 @@ static const char * const usage_msg = "\t-N\t\tignore all newline characters\n" "\t-Q\t\tdo not decode double quotes that enclose the concatenation of args (def: do decode)\n" "\t-e\t\tdo not output double quotes that enclose each arg (def: do not remove)\n" - "\t-E level\t\tentertainment mode\n" + "\t-E level\tentertainment mode\n" "\n" "\t[string ...]\tdecode the concatenation of string args (def: decode stdin)\n" "\t\t\tNOTE: - means read from stdin\n" @@ -703,7 +703,8 @@ main(int argc, char **argv) /* * free list of decoded strings */ - free_jstring_list(json_decoded_strings); + free_jstring_list(&json_decoded_strings); + json_decoded_strings = NULL; /* * All Done!!! All Done!!! -- Jessica Noll, Age 2 diff --git a/jparse/jstrdecode.h b/jparse/jstrdecode.h index 92db1569..9039ab84 100644 --- a/jparse/jstrdecode.h +++ b/jparse/jstrdecode.h @@ -69,7 +69,7 @@ /* * official jstrdecode version */ -#define JSTRDECODE_VERSION "2.0.0 2024-10-31" /* format: major.minor YYYY-MM-DD */ +#define JSTRDECODE_VERSION "2.0.1 2024-11-01" /* format: major.minor YYYY-MM-DD */ /* diff --git a/jparse/jstrencode.c b/jparse/jstrencode.c index 1d73976e..c6794650 100644 --- a/jparse/jstrencode.c +++ b/jparse/jstrencode.c @@ -604,7 +604,8 @@ main(int argc, char **argv) /* * free list of encoded strings */ - free_jstring_list(json_encoded_strings); + free_jstring_list(&json_encoded_strings); + json_encoded_strings = NULL; /* * All Done!!! All Done!!! -- Jessica Noll, Age 2 diff --git a/jparse/jstrencode.h b/jparse/jstrencode.h index a44650af..02cba84f 100644 --- a/jparse/jstrencode.h +++ b/jparse/jstrencode.h @@ -69,7 +69,7 @@ /* * official jstrencode version */ -#define JSTRENCODE_VERSION "2.0.0 2024-10-31" /* format: major.minor YYYY-MM-DD */ +#define JSTRENCODE_VERSION "2.0.1 2024-11-01" /* format: major.minor YYYY-MM-DD */ /* diff --git a/jparse/man/man3/jparse.3 b/jparse/man/man3/jparse.3 index 41914439..508e7f02 100644 --- a/jparse/man/man3/jparse.3 +++ b/jparse/man/man3/jparse.3 @@ -9,7 +9,7 @@ .\" "Share and Enjoy!" .\" -- Sirius Cybernetics Corporation Complaints Division, JSON spec department. :-) .\" -.TH jparse 3 "31 October 2024" "jparse" +.TH jparse 3 "01 November 2024" "jparse" .SH NAME .BR parse_json() \|, .BR parse_json_stream() \|, @@ -22,10 +22,6 @@ .SH SYNOPSIS \fB#include \fP .sp -\fB#define JPARSE_VERSION "..." /* format: major.minor YYYY-MM-DD */\fP -.br -\fB#define JPARSE_LIBRARY_VERSION "..." /* library format: major.minor YYYY-MM-DD */\fP -.br \fB#define VALID_JSON_NODE(item) ((item) != NULL && (((item)->parsed == true) || ((item)->converted == true)))\fP .br \fB#define PARSED_JSON_NODE(item) ((item) != NULL && ((item)->parsed == true))\fP @@ -34,9 +30,11 @@ .br \fB#define CONVERTED_JSON_NODE(item) ((item) != NULL && (item)->converted == true)\fP .sp -.B "extern const char *const json_parser_version; /* library version format: major.minor YYYY-MM-DD */" +.B "extern const char *const jparse_library_version; /* library version format: major.minor YYYY-MM-DD */" .br .B "extern const char *const jparse_version; /* jparse version format: major.minor YYYY-MM-DD */" +.br +.B "extern const char *const jparse_utf8_version; /* jparse utf8 version format: major.minor YYYY-MM-DD */" .sp .B "extern struct json *parse_json(char const *ptr, size_t len, char const *filename, bool *is_valid);" .br @@ -253,7 +251,7 @@ is the current version of the .B jparse tool. The string -.BR json_parser_version , +.BR jparse_library_version , which points to .BR JPARSE_LIBRARY_VERSION , is the current version of the parser itself. @@ -305,5 +303,3 @@ Although the scanner and parser are re-entrant only one parse at one time in a p If it's not clear this means that having more than one parse active in the same process at the same time is not tested so even though it should be okay there might be some issues that have yet to be discovered. .SH SEE ALSO .BR jparse (1), -.IR README.md \|, -.BR printf (3)