Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
# Significant changes in the JSON parser repo


## Release 2.6.0 2026-09-25
## Release 2.6.1 2026-09-27

Sequenced exit codes.
Fixed a few comment typos, and string typos.

Updated `JPARSE_UTF8_VERSION` to `"2.1.5 2026-09-27"` for recent changes.
Improve a few NULL tests.

Improved `jparse(3)` man page to discuss when `filename`
is `NULL`, and `stream` is `!= NULL`.

Added test for when JSON stream is `NULL`, and `filename` uses stream.

This update should have nil effect on use of this library
and the API remains identical to "2.6.0 2026-09-25".

Changed `JPARSE_REPO_VERSION` to "2.6.1 2026-09-27"
Changed `JPARSE_TOOL_VERSION` to "2.1.1 2026-09-27"
Changed `JPARSE_LIBRARY_VERSION` to "2.5.1 2026-09-27"
Changed `JPARSE_UTILS_VERSION` to "2.2.1 2026-06-27"


## Release 2.6.0 2026-09-25
Expand Down Expand Up @@ -64,6 +77,10 @@ Updated `JPARSE_TOOL_VERSION` to `"2.1.0 2026-09-25"`.
Updated `JPARSE_LIBRARY_VERSION` to `"2.5.0 2026-09-25"`.
Updated `JPARSE_UTILS_VERSION` to `"2.2.0 2026-06-25"`.

Sequenced exit codes.

Updated `JPARSE_UTF8_VERSION` to `"2.1.5 2026-09-27"` for recent changes.


## Release 2.5.11 2026-08-03

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ _README.md last updated: 24 June 2025_

`jparse` is a JSON parser (as a stand-alone tool and a library) written in C
with the help of `flex(1)` and `bison(1)`. This library, and all the tools, some
of which use the library and others which do not, were were co-developed in
of which use the library and others which do not, were co-developed in
2022-2024 by:

*@xexyl* (**Cody Boone Ferguson**, [https://xexyl.net](https://xexyl.net),
Expand Down Expand Up @@ -139,7 +139,7 @@ make all

**IMPORTANT NOTE**: the Makefiles allow one to override certain things by having
a file `Makefile.local` in the same directory. This can cause compilation errors
so if you do have such a file you should use so with caution.
so if you do have such a file you should do so with caution.



Expand Down
37 changes: 22 additions & 15 deletions jparse.l
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,7 @@ parse_json(char const *ptr, size_t len, char const *filename, bool *is_valid)
not_reached();
} else {
/*
* assume the JSON block is is valid; set *is_valid to true so that the
* assume the JSON block is valid; set *is_valid to true so that the
* caller does not need to worry about it (well they should in case this
* is removed but we do it explicitly for them anyway).
*/
Expand Down Expand Up @@ -843,7 +843,7 @@ parse_json_str(char const *ptr, size_t len, bool *is_valid)
not_reached();
} else {
/*
* assume the JSON block is is valid; set *is_valid to true so that the
* assume the JSON block is valid; set *is_valid to true so that the
* caller does not need to worry about it (well they should in case this
* is removed but we do it explicitly for them anyway).
*/
Expand Down Expand Up @@ -884,8 +884,8 @@ parse_json_str(char const *ptr, size_t len, bool *is_valid)
*
* given:
* stream - open file stream containing JSON data
* filename - name of file or NULL for stdin
* is_valid - non-NULL printer to boolean to set depending on json validity
* filename - name of file, "-" for stdin, or NULL if no filename should be reported
* is_valid - non-NULL pointer to boolean to set depending on json validity
*
* return:
* pointer to a JSON parse tree
Expand All @@ -897,8 +897,11 @@ parse_json_str(char const *ptr, size_t len, bool *is_valid)
* YY_BUFFER_STATE is part of the scanner and not the parser and that's required
* for the parse_json() function.
*
* NOTE: if filename is "-" and stream is NULL, then the stream is set to stdin,
* as if the filename was NULL.
* NOTE: if filename is NULL, it is reported as "-" only when stream is also
* NULL. Otherwise, the supplied stream is used and the filename is just
* omitted from diagnostics.
*
* NOTE: if filename is "-" and stream is NULL, then the stream is set to stdin.
*
* NOTE: this function only warns on error, except for NULL is_valid, in which
* case it is an error; warning on errors is so that an entire report of
Expand All @@ -923,17 +926,21 @@ parse_json_stream(FILE *stream, char const *filename, bool *is_valid)
not_reached();
} else {
/*
* assume the JSON stream is is valid JSON; set *is_valid to true so
* assume the JSON stream is valid JSON; set *is_valid to true so
* that the caller does not need to worry about it (well they should in
* case this is removed but we do it explicitly for them anyway).
*/
*is_valid = true;
}

if (filename == NULL) {
json_dbg(JSON_DBG_HIGH, __func__, "filename is NULL, forcing it to be \"-\" for stdin");
filename = "-";
stream = stdin;
if (stream == NULL) {
json_dbg(JSON_DBG_HIGH, __func__, "filename and stream are NULL, forcing stdin");
filename = "-";
stream = stdin;
} else {
json_dbg(JSON_DBG_HIGH, __func__, "filename is NULL, using supplied stream without a filename");
}
} else if (!strcmp(filename, "-") && stream == NULL) {
stream = stdin;
}
Expand Down Expand Up @@ -988,7 +995,7 @@ parse_json_stream(FILE *stream, char const *filename, bool *is_valid)
/*
* warn about read error
*/
werr(48, __func__, "could not read read stream");
werr(48, __func__, "could not read stream");
/*
* we need to clearerr() or fclose(), depending on the stream.
*/
Expand Down Expand Up @@ -1071,7 +1078,7 @@ parse_json_stream(FILE *stream, char const *filename, bool *is_valid)
stream = NULL;

/*
* return the JSON parse tree tree
* return the JSON parse tree
*/
return tree;
}
Expand Down Expand Up @@ -1227,7 +1234,7 @@ is_read(char const *path)
*
* given:
* filename - filename of file to parse
* is_valid - non-NULL printer to boolean to set depending on json validity
* is_valid - non-NULL pointer to boolean to set depending on json validity
*
* return:
* pointer to a JSON parse tree
Expand Down Expand Up @@ -1258,7 +1265,7 @@ parse_json_file(char const *filename, bool *is_valid)
not_reached();
} else {
/*
* assume the JSON file is is valid JSON; set *is_valid to true so
* assume the JSON file is valid JSON; set *is_valid to true so
* that the caller does not need to worry about it (well they should in
* case this is removed but we do it explicitly for them anyway).
*/
Expand Down Expand Up @@ -1395,7 +1402,7 @@ parse_json_file(char const *filename, bool *is_valid)
tree = parse_json_stream(stream, filename, is_valid);

/*
* return the JSON parse tree tree
* return the JSON parse tree
*/
return tree;
}
37 changes: 22 additions & 15 deletions jparse.ref.c
Original file line number Diff line number Diff line change
Expand Up @@ -2931,7 +2931,7 @@ parse_json(char const *ptr, size_t len, char const *filename, bool *is_valid)
not_reached();
} else {
/*
* assume the JSON block is is valid; set *is_valid to true so that the
* assume the JSON block is valid; set *is_valid to true so that the
* caller does not need to worry about it (well they should in case this
* is removed but we do it explicitly for them anyway).
*/
Expand Down Expand Up @@ -3143,7 +3143,7 @@ parse_json_str(char const *ptr, size_t len, bool *is_valid)
not_reached();
} else {
/*
* assume the JSON block is is valid; set *is_valid to true so that the
* assume the JSON block is valid; set *is_valid to true so that the
* caller does not need to worry about it (well they should in case this
* is removed but we do it explicitly for them anyway).
*/
Expand Down Expand Up @@ -3184,8 +3184,8 @@ parse_json_str(char const *ptr, size_t len, bool *is_valid)
*
* given:
* stream - open file stream containing JSON data
* filename - name of file or NULL for stdin
* is_valid - non-NULL printer to boolean to set depending on json validity
* filename - name of file, "-" for stdin, or NULL if no filename should be reported
* is_valid - non-NULL pointer to boolean to set depending on json validity
*
* return:
* pointer to a JSON parse tree
Expand All @@ -3197,8 +3197,11 @@ parse_json_str(char const *ptr, size_t len, bool *is_valid)
* YY_BUFFER_STATE is part of the scanner and not the parser and that's required
* for the parse_json() function.
*
* NOTE: if filename is "-" and stream is NULL, then the stream is set to stdin,
* as if the filename was NULL.
* NOTE: if filename is NULL, it is reported as "-" only when stream is also
* NULL. Otherwise, the supplied stream is used and the filename is just
* omitted from diagnostics.
*
* NOTE: if filename is "-" and stream is NULL, then the stream is set to stdin.
*
* NOTE: this function only warns on error, except for NULL is_valid, in which
* case it is an error; warning on errors is so that an entire report of
Expand All @@ -3223,17 +3226,21 @@ parse_json_stream(FILE *stream, char const *filename, bool *is_valid)
not_reached();
} else {
/*
* assume the JSON stream is is valid JSON; set *is_valid to true so
* assume the JSON stream is valid JSON; set *is_valid to true so
* that the caller does not need to worry about it (well they should in
* case this is removed but we do it explicitly for them anyway).
*/
*is_valid = true;
}

if (filename == NULL) {
json_dbg(JSON_DBG_HIGH, __func__, "filename is NULL, forcing it to be \"-\" for stdin");
filename = "-";
stream = stdin;
if (stream == NULL) {
json_dbg(JSON_DBG_HIGH, __func__, "filename and stream are NULL, forcing stdin");
filename = "-";
stream = stdin;
} else {
json_dbg(JSON_DBG_HIGH, __func__, "filename is NULL, using supplied stream without a filename");
}
} else if (!strcmp(filename, "-") && stream == NULL) {
stream = stdin;
}
Expand Down Expand Up @@ -3288,7 +3295,7 @@ parse_json_stream(FILE *stream, char const *filename, bool *is_valid)
/*
* warn about read error
*/
werr(48, __func__, "could not read read stream");
werr(48, __func__, "could not read stream");
/*
* we need to clearerr() or fclose(), depending on the stream.
*/
Expand Down Expand Up @@ -3371,7 +3378,7 @@ parse_json_stream(FILE *stream, char const *filename, bool *is_valid)
stream = NULL;

/*
* return the JSON parse tree tree
* return the JSON parse tree
*/
return tree;
}
Expand Down Expand Up @@ -3527,7 +3534,7 @@ is_read(char const *path)
*
* given:
* filename - filename of file to parse
* is_valid - non-NULL printer to boolean to set depending on json validity
* is_valid - non-NULL pointer to boolean to set depending on json validity
*
* return:
* pointer to a JSON parse tree
Expand Down Expand Up @@ -3558,7 +3565,7 @@ parse_json_file(char const *filename, bool *is_valid)
not_reached();
} else {
/*
* assume the JSON file is is valid JSON; set *is_valid to true so
* assume the JSON file is valid JSON; set *is_valid to true so
* that the caller does not need to worry about it (well they should in
* case this is removed but we do it explicitly for them anyway).
*/
Expand Down Expand Up @@ -3695,7 +3702,7 @@ parse_json_file(char const *filename, bool *is_valid)
tree = parse_json_stream(stream, filename, is_valid);

/*
* return the JSON parse tree tree
* return the JSON parse tree
*/
return tree;
}
Expand Down
14 changes: 8 additions & 6 deletions jsemtblgen.c
Original file line number Diff line number Diff line change
Expand Up @@ -410,8 +410,8 @@ main(int argc, char **argv)
not_reached();
}
for (c=0; c < len; ++c) {
if (islower(tbl_name[c])) {
cap_tbl_name[c] = (char)toupper(tbl_name[c]);
if (islower((unsigned char)tbl_name[c])) {
cap_tbl_name[c] = (char)toupper((unsigned char)tbl_name[c]);
}
}
dbg(DBG_MED, "output_mode: %s", h_mode ? ".h include file" : ".c src file");
Expand Down Expand Up @@ -893,7 +893,8 @@ alloc_c_funct_name(char const *prefix, char const *str)
* case: prefix begins with a digit
* case: prefix begins with an underscore
*/
if (prefix_is_reserved == true || prefix[0] == '\0' || isdigit(prefix[0]) || prefix[0] == '_') {
if (prefix_is_reserved == true || prefix[0] == '\0' ||
isdigit((unsigned char)prefix[0]) || prefix[0] == '_') {
/* add x due to the cases mentioned above */
*p++ = 'x';
}
Expand All @@ -902,7 +903,7 @@ alloc_c_funct_name(char const *prefix, char const *str)
* process prefix
*/
while (prefix[0] != '\0') {
if (!isalnum(prefix[0])) {
if (!isalnum((unsigned char)prefix[0])) {
/* convert non-C name character to underscore */
*p++ = '_';
} else {
Expand All @@ -923,7 +924,8 @@ alloc_c_funct_name(char const *prefix, char const *str)
* case: str begins with a digit
* case: str begins with an underscore
*/
if (str_is_reserved == true || str[0] == '\0' || isdigit(str[0]) || str[0] == '_') {
if (str_is_reserved == true || str[0] == '\0' ||
isdigit((unsigned char)str[0]) || str[0] == '_') {
/* add x due to the cases mentioned above */
*p++ = 'x';
}
Expand All @@ -932,7 +934,7 @@ alloc_c_funct_name(char const *prefix, char const *str)
* process each str character in C, converting non-alphanumeric characters to underscore.
*/
while (str[0] != '\0') {
if (!isalnum(str[0])) {
if (!isalnum((unsigned char)str[0])) {
/* convert non-C name character to underscore */
*p++ = '_';
} else {
Expand Down
14 changes: 12 additions & 2 deletions man/man3/jparse.3
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ described later.
.PP
If
.I filename
is not NULL and is an empty string, then it will set the filename to
is
.BR \*(lq-\*(rq ,
indicating that the input comes from stdin.
it indicates that the input comes from stdin.
If it is a NULL pointer, the filename in the parser extra data will be set to NULL, and messages will not show a filename.
.PP
The variable
Expand Down Expand Up @@ -150,6 +150,16 @@ and does not accept a number of bytes to scan.
The
.I filename
is for messages and is not used to determine what file to open as the stream should already be open.
If
.I filename
is NULL and
.I stream
is non-NULL, the supplied stream is still parsed; only the diagnostic filename is omitted.
If both
.I filename
and
.I stream
are NULL, stdin is used.
If you wish to do that you should use the
.BR parse_json_file ()
function instead, which takes a filename and the
Expand Down
Loading
Loading