Skip to content

Commit

Permalink
Merge pull request #1002 from xexyl/encode-decode
Browse files Browse the repository at this point in the history
Add new option -N to jstrencode and jstrdecode
  • Loading branch information
lcn2 authored Oct 10, 2024
2 parents ebea5ec + 5278561 commit 401e76f
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 15 deletions.
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ something else), amongst various other things. Should one wish to further
progress their dementia! :-) they can look at that repo's log or the
jparse/CHANGES.md file.

New option `-N` to `jstrdecode(1)` and `jstrencode(1)` to ignore (in decoding
and encoding internal to the tool itself, not JSON) final newline in input.


## Release 1.5.24 2024-10-09

Expand Down
7 changes: 7 additions & 0 deletions jparse/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ Improve the way `utf8len()` works. It now returns a `size_t` and the `size_t
*bytes` was removed from it. Returns `-1` if an error occurs. This better fits
the name and purpose of the function.

Add new option `-N` to `jstrdecode(1)`. This option ignores a final newline in
the input for easier typing of commands. It does not change the validity
checking of JSON.

Add new option `-N` to `jstrencode(1)`. This option ignores a final newline in
the input. It does not change the validity checking of JSON.


## Release 1.2.0 2024-10-09

Expand Down
25 changes: 19 additions & 6 deletions jparse/jstrdecode.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ static const char * const usage_msg =
"\t-V\t\tprint version string and exit\n"
"\t-t\t\tperform tests of JSON decode/encode functionality\n"
"\t-n\t\tdo not output newline after decode output\n"
"\t-N\t\tignore final newline in input\n"
"\t-Q\t\tenclose output in double quotes (def: do not)\n"
"\t-e\t\tenclose each decoded string with escaped double quotes (def: do not)\n"
"\n"
Expand All @@ -76,7 +77,7 @@ static const char * const usage_msg =
* forward declarations
*/
static void usage(int exitcode, char const *prog, char const *str) __attribute__((noreturn));
static struct jstring *jstrdecode_stream(FILE *in_stream);
static struct jstring *jstrdecode_stream(FILE *in_stream, bool skip_eol_nl);
static struct jstring *add_decoded_string(char *string, size_t bufsiz);
static void free_json_decoded_strings(void);

Expand Down Expand Up @@ -178,6 +179,7 @@ free_json_decoded_strings(void)
*
* given:
* in_stream open file stream to decode
* skip_eol_nl true ==> ignore final newline
*
* returns:
* allocated struct jstring * ==> decoding was successful,
Expand All @@ -187,7 +189,7 @@ free_json_decoded_strings(void)
* decoded JSON strings.
*/
static struct jstring *
jstrdecode_stream(FILE *in_stream)
jstrdecode_stream(FILE *in_stream, bool skip_eol_nl)
{
char *input = NULL; /* argument to process */
size_t inputlen; /* length of input buffer */
Expand Down Expand Up @@ -217,7 +219,11 @@ jstrdecode_stream(FILE *in_stream)
/*
* decode data read from input stream
*/
buf = json_decode(input, inputlen, &bufsiz);
if (skip_eol_nl && inputlen > 0 && input[inputlen-1] == '\n') {
buf = json_decode(input, inputlen-1, &bufsiz);
} else {
buf = json_decode(input, inputlen, &bufsiz);
}
if (buf == NULL) {
/* free input */
if (input != NULL) {
Expand Down Expand Up @@ -264,6 +270,7 @@ main(int argc, char **argv)
size_t outputlen; /* length of write of decode buffer */
bool success = true; /* true ==> encoding OK, false ==> error while encoding */
bool nloutput = true; /* true ==> output newline after JSON decode */
bool skip_eol_nl = false; /* true ==> ignore final newline when encoding */
bool write_quote = false; /* true ==> output enclosing quotes */
bool esc_quotes = false; /* true ==> escape quotes */
int ret; /* libc return code */
Expand All @@ -282,7 +289,7 @@ main(int argc, char **argv)
* parse args
*/
program = argv[0];
while ((i = getopt(argc, argv, ":hv:qVtnQe")) != -1) {
while ((i = getopt(argc, argv, ":hv:qVtnNQe")) != -1) {
switch (i) {
case 'h': /* -h - print help to stderr and exit 2 */
usage(2, program, ""); /*ooo*/
Expand Down Expand Up @@ -321,6 +328,9 @@ main(int argc, char **argv)
case 'n':
nloutput = false;
break;
case 'N':
skip_eol_nl = true;
break;
case 'Q':
write_quote = true;
break;
Expand Down Expand Up @@ -363,7 +373,7 @@ main(int argc, char **argv)
* NOTE: the function jstrdecode_stream() adds the allocated
* struct jstring * to the list of decoded JSON strings
*/
jstr = jstrdecode_stream(stdin);
jstr = jstrdecode_stream(stdin, skip_eol_nl);
if (jstr != NULL) {
dbg(DBG_MED, "decode length: %ju", jstr->bufsiz);
} else {
Expand All @@ -383,6 +393,9 @@ main(int argc, char **argv)
/*
* decode arg
*/
if (skip_eol_nl && inputlen > 0 && input[inputlen-1] == '\n') {
input[inputlen - 1] = '\0';
}
buf = json_decode_str(input, &bufsiz);
if (buf == NULL) {
warn(__func__, "error while decoding processing arg: %d", i-optind);
Expand Down Expand Up @@ -413,7 +426,7 @@ main(int argc, char **argv)
* NOTE: the function jstrdecode_stream() adds the allocated
* struct jstring * to the list of decoded JSON strings
*/
jstr = jstrdecode_stream(stdin);
jstr = jstrdecode_stream(stdin, skip_eol_nl);

if (jstr != NULL) {
dbg(DBG_MED, "decode length: %ju", jstr->bufsiz);
Expand Down
2 changes: 1 addition & 1 deletion jparse/jstrdecode.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
/*
* official jstrdecode version
*/
#define JSTRDECODE_VERSION "1.2.1 2024-10-10" /* format: major.minor YYYY-MM-DD */
#define JSTRDECODE_VERSION "1.2.2 2024-10-10" /* format: major.minor YYYY-MM-DD */


/*
Expand Down
29 changes: 24 additions & 5 deletions jparse/jstrencode.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ static const char * const usage_msg =
"\t-V\t\tprint version string and exit\n"
"\t-t\t\tperform tests of JSON decode/encode functionality\n"
"\t-n\t\tdo not output newline after encode output (def: print final newline)\n"
"\t-N\t\tignore final newline in input\n"
"\t-Q\t\tdo not encode double quotes that enclose the concatenation of args (def: do encode)\n"
"\t-e\t\tdo not output double quotes that enclose each arg (def: do not remove)\n"
"\n"
Expand All @@ -76,7 +77,8 @@ static const char * const usage_msg =
* forward declarations
*/
static void usage(int exitcode, char const *prog, char const *str) __attribute__((noreturn));
static struct jstring *jstrencode_stream(FILE *in_stream, bool skip_enclosing, bool ignore_first, bool remove_last);
static struct jstring *jstrencode_stream(FILE *in_stream, bool skip_enclosing, bool ignore_first, bool remove_last,
bool skip_eol_nl);
static struct jstring *add_encoded_string(char *string, size_t bufsiz);
static void free_json_encoded_strings(void);

Expand Down Expand Up @@ -187,6 +189,7 @@ free_json_encoded_strings(void)
* false ==> do not remove
* remove_last remove any final double quote
* false ==> do not remove
* skip_eol_nl true ==> skip final newline
*
* returns:
* allocated struct jstring * ==> encoding was successful,
Expand All @@ -196,7 +199,7 @@ free_json_encoded_strings(void)
* encoded JSON strings.
*/
static struct jstring *
jstrencode_stream(FILE *in_stream, bool skip_enclosing, bool ignore_first, bool remove_last)
jstrencode_stream(FILE *in_stream, bool skip_enclosing, bool ignore_first, bool remove_last, bool skip_eol_nl)
{
char *orig_input = NULL; /* argument to process */
char *input = NULL; /* possibly updated orig_input */
Expand Down Expand Up @@ -226,6 +229,10 @@ jstrencode_stream(FILE *in_stream, bool skip_enclosing, bool ignore_first, bool
input = orig_input;
dbg(DBG_HIGH, "stream data is: <%s>", input);

if (skip_eol_nl && inputlen > 0 && input[inputlen - 1] == '\n') {
input[inputlen - 1] = '\0';
--inputlen;
}
/*
* case: we need to remove BOTH a leading and a trailing double quote
*/
Expand Down Expand Up @@ -328,6 +335,7 @@ main(int argc, char **argv)
size_t outputlen; /* length of write of encode buffer */
bool success = true; /* true ==> encoding OK, false ==> error while encoding */
bool nloutput = true; /* true ==> output newline after JSON encode */
bool skip_eol_nl = false; /* true ==> ignore final newline when encoding */
bool skip_concat_quotes = false; /* true ==> skip enclosing quotes around the arg concatenation */
bool skip_each = false; /* true ==> skip enclosing quotes around each arg */
int ret; /* libc return code */
Expand All @@ -346,7 +354,7 @@ main(int argc, char **argv)
* parse args
*/
program = argv[0];
while ((i = getopt(argc, argv, ":hv:qVtnQe")) != -1) {
while ((i = getopt(argc, argv, ":hv:qVtnNQe")) != -1) {
switch (i) {
case 'h': /* -h - print help to stderr and exit 2 */
usage(2, program, ""); /*ooo*/
Expand Down Expand Up @@ -385,6 +393,9 @@ main(int argc, char **argv)
case 'n':
nloutput = false;
break;
case 'N':
skip_eol_nl = true;
break;
case 'Q':
skip_concat_quotes = true;
break;
Expand Down Expand Up @@ -433,7 +444,7 @@ main(int argc, char **argv)
*/
jstr = jstrencode_stream(stdin, skip_each,
(skip_concat_quotes && i == optind),
(skip_concat_quotes && i == argc-1));
(skip_concat_quotes && i == argc-1), skip_eol_nl);
if (!jstr) {
warn(__func__, "failed to encode string from stdin");
success = false;
Expand All @@ -451,6 +462,14 @@ main(int argc, char **argv)
dbg(DBG_MED, "arg length: %ju", (uintmax_t)inputlen);
}

/*
* case: we need to remove trailing newline
*/
if (skip_eol_nl && inputlen > 0 && input[inputlen-1] == '\n') {
input[inputlen - 1] = '\0';
--inputlen;
}

/*
* case: we need to remove BOTH a leading and a trailing double quote
*/
Expand Down Expand Up @@ -541,7 +560,7 @@ main(int argc, char **argv)
* NOTE: jstrencode_stream() adds the allocated struct jstring * to the
* encoded JSON strings list
*/
jstr = jstrencode_stream(stdin, skip_concat_quotes, skip_each, skip_each);
jstr = jstrencode_stream(stdin, skip_concat_quotes, skip_each, skip_each, skip_eol_nl);
if (jstr != NULL) {
dbg(DBG_MED, "encode length: %ju", jstr->bufsiz);
} else {
Expand Down
2 changes: 1 addition & 1 deletion jparse/jstrencode.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
/*
* official jstrencode version
*/
#define JSTRENCODE_VERSION "1.2.1 2024-10-10" /* format: major.minor YYYY-MM-DD */
#define JSTRENCODE_VERSION "1.2.2 2024-10-10" /* format: major.minor YYYY-MM-DD */


/*
Expand Down
6 changes: 5 additions & 1 deletion jparse/man/man1/jstrdecode.1
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
.\" "Share and Enjoy!"
.\" -- Sirius Cybernetics Corporation Complaints Division, JSON spec department. :-)
.\"
.TH jstrdecode 1 "14 September 2024" "jstrdecode" "jparse tools"
.TH jstrdecode 1 "10 October 2024" "jstrdecode" "jparse tools"
.SH NAME
.B jstrdecode
\- decode JSON encoded strings
Expand All @@ -22,6 +22,7 @@
.RB [\| \-V \|]
.RB [\| \-t \|]
.RB [\| \-n \|]
.RB [\| \-N \|]
.RB [\| \-Q \|]
.RB [\| \-e \|]
.RI [\| string
Expand Down Expand Up @@ -69,6 +70,9 @@ Run tests on the JSON decode/encode functions
.B \-n
Do not output a newline after the decode function
.TP
.B \-N
Skip final newline in input, for easier typing commands.
.TP
.B \-Q
Enclose output in double quotes
.TP
Expand Down
6 changes: 5 additions & 1 deletion jparse/man/man1/jstrencode.1
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
.\" "Share and Enjoy!"
.\" -- Sirius Cybernetics Corporation Complaints Division, JSON spec department. :-)
.\"
.TH jstrencode 1 "14 September 2024" "jstrencode" "jparse tools"
.TH jstrencode 1 "10 October 2024" "jstrencode" "jparse tools"
.SH NAME
.B jstrencode
\- encode JSON encoded strings
Expand All @@ -22,6 +22,7 @@
.RB [\| \-V \|]
.RB [\| \-t \|]
.RB [\| \-n \|]
.RB [\| \-N \|]
.RB [\| \-Q \|]
.RI [\| string
.IR ... \|]
Expand Down Expand Up @@ -56,6 +57,9 @@ Run tests on the JSON encode/encode functions
.B \-n
Do not output a newline after the encode function
.TP
.B \-N
Ignore trailing newline in input
.TP
.B \-Q
Do not encode double quotes that enclose the concatenation of args (def: do encode)
.TP
Expand Down

0 comments on commit 401e76f

Please sign in to comment.