From 404cd7cc68c42c49076623e3ec13bb1f42f74ec7 Mon Sep 17 00:00:00 2001 From: Douglas Gilbert Date: Thu, 12 May 2022 18:37:08 +0000 Subject: sg_lib: document internal json interface in include/sg_pr2serr.h; codespell fixes git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@952 6180dd3e-e324-4e3e-922d-17de1ae2f315 --- include/sg_pr2serr.h | 147 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 104 insertions(+), 43 deletions(-) (limited to 'include') diff --git a/include/sg_pr2serr.h b/include/sg_pr2serr.h index b29c7e34..d5a4809c 100644 --- a/include/sg_pr2serr.h +++ b/include/sg_pr2serr.h @@ -67,24 +67,28 @@ typedef void * sgj_opaque_p; * they initialized as shown. */ typedef struct sgj_state_t { bool pr_as_json; /* = false */ - bool pr_pretty; /* = true */ - bool pr_header; /* = true */ - bool pr_sorted; /* = false (ignored) */ - bool pr_output; /* = false */ - bool pr_implemented; - bool pr_unimplemented; - char pr_format; /* = '\0' */ - int pr_indent_size; /* = 4 */ - int first_bad_char; /* = '\0' */ - int verbose; /* = 0 */ + bool pr_hex; /* 'h' (def: true) */ + bool pr_leadin; /* 'l' (def: true) */ + bool pr_output; /* 'o' (def: false) */ + bool pr_pretty; /* 'p' (def: true) */ + bool pr_trailer; /* 't' (def: true) */ + char pr_format; /* (def: '\0') */ + int pr_indent_size; /* digit (def: 4) */ + int verbose; /* 'v' (def: 0) incremented each appearance */ /* the following hold state information */ + int first_bad_char; /* = '\0' */ sgj_opaque_p basep; /* base JSON object pointer */ sgj_opaque_p outputp; /* 'output' named JSON array pointer */ sgj_opaque_p userp; /* for temporary usage */ } sgj_state; -/* Prints to stdout like printf(fmt, ...). Further if --json=o option is - * given that output line is also placed in the JSON 'output' array. */ +/* If jsp in non-NULL and jsp->pr_as_json is true then this call is ignored + * unless jsp->pr_output is true. Otherwise this function prints to stdout + * like printf(fmt, ...); note that no LF is added. In the jsp->pr_output + * is true case, nothing is printed to stdout but instead is placed into the + * JSON 'output" array (jsp->outputp) after some preprocessing. That + * preprocessing involves removing a leading LF from 'fmt' (if present) and + * up to two trailing LF characters. */ void sgj_pr_hr(sgj_state * jsp, const char * fmt, ...) __printf(2, 3); /* Initializes the state object pointed to by jsp based on the argument @@ -100,11 +104,11 @@ bool sgj_init_state(sgj_state * jsp, const char * j_optarg); * sgj_finish() to clean up (i.e. remove all heap allocations) all the * elements (i.e. JSON objects and arrays) that have been placed in that * in-core tree. If jsp is NULL nothing further happens. Otherwise the pointer - * to be returned is placed in jsp->basep. If jsp->pr_header is true and + * to be returned is placed in jsp->basep. If jsp->pr_leadin is true and * util_name is non-NULL then a "utility_invoked" JSON object is made with * "name", and "version_date" object fields. If the jsp->pr_output field is * true a named array called "output" is added to the "utility_invoked" object - * (creating it in the case when jsp->pr_header is false) and a pointer to + * (creating it in the case when jsp->pr_leadin is false) and a pointer to * that array object is placed in jsp->objectp . The returned pointer is not * usually needed but if it is NULL then a heap allocation has failed. */ sgj_opaque_p sgj_start(const char * util_name, const char * ver_str, @@ -136,56 +140,113 @@ sgj_opaque_p sgj_new_named_object(sgj_state * jsp, sgj_opaque_p jop, sgj_opaque_p sgj_new_named_array(sgj_state * jsp, sgj_opaque_p jop, const char * name); -/* If jsp is NULL or jsp->pr_as_json is false or ua_jop is NULL nothing - * happens and NULL is returned. Otherwise it adds a new array element - * (ua_jop) to the array ('jap') that was returned by sgj_new_named_array(). - * ua_jop is assumed to not been part of the main JSON in-core tree before - * this call, and it is after this call. This means that ua_jop must have - * been created by sgj_new_unattached_object() or similar. */ -sgj_opaque_p sgj_add_array_element(sgj_state * jsp, sgj_opaque_p jap, - sgj_opaque_p ua_jop); - -sgj_opaque_p sgj_add_name_vs(sgj_state * jsp, sgj_opaque_p jop, - const char * name, const char * value); - -sgj_opaque_p sgj_add_name_vi(sgj_state * jsp, sgj_opaque_p jop, - const char * name, int64_t value); - -sgj_opaque_p sgj_add_name_vb(sgj_state * jsp, sgj_opaque_p jop, - const char * name, bool value); - -sgj_opaque_p sgj_add_name_obj(sgj_state * jsp, sgj_opaque_p jop, - const char * name, sgj_opaque_p ua_jop); - +/* If either jsp or value is NULL or jsp->pr_as_json is false then nothing + * happens and NULL is returned. The insertion point is at jop but if it is + * NULL jsp->basep is used. If 'name' is non-NULL a new named JSON object is + * added using 'name' and the associated value is a JSON string formed from + * 'value'. If 'name' is NULL then 'jop' is assumed to be a JSON array and + * a JSON string formed from 'value' is added. If successful returns a + * a pointer newly formed JSON string. */ +sgj_opaque_p sgj_add_val_s(sgj_state * jsp, sgj_opaque_p jop, + const char * name, const char * value); + +/* If either jsp is NULL or jsp->pr_as_json is false then nothing happens and + * NULL is returned. The insertion point is at jop but if it is NULL + * jsp->basep is used. If 'name' is non-NULL a new named JSON object is + * added using 'name' and the associated value is a JSON integer formed from + * 'value'. If 'name' is NULL then 'jop' is assumed to be a JSON array and + * a JSON integer formed from 'value' is added. If successful returns a + * a pointer newly formed JSON integer. */ +sgj_opaque_p sgj_add_val_i(sgj_state * jsp, sgj_opaque_p jop, + const char * name, int64_t value); + +/* If either jsp is NULL or jsp->pr_as_json is false then nothing happens and + * NULL is returned. The insertion point is at jop but if it is NULL + * jsp->basep is used. If 'name' is non-NULL a new named JSON object is + * added using 'name' and the associated value is a JSON boolean formed from + * 'value'. If 'name' is NULL then 'jop' is assumed to be a JSON array and + * a JSON boolean formed from 'value' is added. If successful returns a + * a pointer newly formed JSON boolean. */ +sgj_opaque_p sgj_add_val_b(sgj_state * jsp, sgj_opaque_p jop, + const char * name, bool value); + +/* If jsp is NULL, jsp->pr_as_json is false or ua_jop is NULL nothing then + * happens and NULL is returned. 'jop' is the insertion point but if it is + * NULL jsp->basep is used instead. If 'name' is non-NULL a new named JSON + * object is added using 'name' and the associated value is ua_jop. If 'name' + * is NULL then 'jop' is assumed to be a JSON array and ua_jop is added to + * it. If successful returns ua_jop . The "ua_" prefix stands for unattached. + * Tha should be the case before invocation and it will be attached to jop + * after a successful invocation. This means that ua_jop must have been + * created by sgj_new_unattached_object() or similar. */ +sgj_opaque_p sgj_add_val_o(sgj_state * jsp, sgj_opaque_p jop, + const char * name, sgj_opaque_p ua_jop); + +/* The '_twin_' refers to generating output both for human readable and/or + * JSON with a single invocation. If jsp is non_NULL and jsp->pr_output is + * true then both JSON and human readable output is formed (and the latter is + * placed in the jsp->outputp JSON array). The human readable form will have + * leadin_sp spaces followed by 'name' then a separator, then 'value' with a + * trailing LF. If 'name' is NULL then it and the separator are ignored. If + * there is JSON output, then leadin_sp and sep are ignored. If 'jop' is NULL + * then basep->basep is used. If 'name' is NULL then a JSON string object, + * made from 'value' is added to the JSON array pointed to by 'jop'. + * Otherwise a 'name'-d JSON object whose value is a JSON string object made + * from 'value' is added at 'jop'. */ void sgj_pr_twin_vs(sgj_state * jsp, sgj_opaque_p jop, int leadin_sp, const char * name, enum sgj_separator_t sep, const char * value); +/* Similar to sgj_pr_twin_vs()'s description with 'JSON string object' + * replaced by 'JSON integer object'. */ void sgj_pr_twin_vi(sgj_state * jsp, sgj_opaque_p jop, int leadin_sp, const char * name, enum sgj_separator_t sep, int64_t value); +/* Similar to sgj_pr_twin_vs()'s description with 'JSON string object' + * replaced by 'JSON boolean object'. */ void sgj_pr_twin_vb(sgj_state * jsp, sgj_opaque_p jop, int leadin_sp, const char * name, enum sgj_separator_t sep, bool value); +/* This function only produces JSON output if jsp is non-NULL and + * jsp->pr_as_json is true. It adds a named object at 'jop' (or jop->basep + * if jop is NULL) along with a value. If jsp->pr_hex is true then that + * value is two sub-objects, one named 'i' with a 'value' as a JSON integer, + * the other one named 'hex' with 'value' rendered as hex in a JSON string. + * If jsp->pr_hex is false the there are no sub-objects and the 'value' is + * rendered as JSON integer. */ void sgj_add_name_pair_ihex(sgj_state * jsp, sgj_opaque_p jop, const char * name, uint64_t value); +/* This function only produces JSON output if jsp is non-NULL and + * jsp->pr_as_json is true. It adds a named object at 'jop' (or jop->basep + * if jop is NULL) along with a value that has two sub-objects. One is + * named "i" with 'val_i' rendered as a JSON integer. The other is named + * 'str_name' (or "string" if that is NULL) with 'val_s' randered as a + * JSON string. */ void sgj_add_name_pair_istr(sgj_state * jsp, sgj_opaque_p jop, const char * name, int64_t val_i, - const char * val_s); - -#if 0 -void sgj_pr_hr_line_vs(sgj_state * jsp, sgj_opaque_p jop, - const char * hr_line, const char * name, - const char * value); -#endif - + const char * str_name, const char * val_s); + +/* Nothing in the in-core JSON tree is actually printed to 'fp' (typically + * stdout) until this call is made. If jsp is NULL, jsp->pr_as_json is false + * or jsp->basep is NULL then this function does nothing. If jsp->trailer is + * true then a new JSON object named "exit_status" and the 'exit_status' + * value rendered as a JSON integer is appended to jsp->basep. The in-core + * JSON tree with jsp->basep as its root is streamed to 'fp'. */ void sgj_pr2file(sgj_state * jsp, sgj_opaque_p jop, int exit_status, FILE * fp); +/* This function is only needed if the pointer returned from either + * sgj_new_unattached_object() or sgj_new_unattached_array() has not been + * attached into the in-core JSON tree whose root is jsp->basep . */ void sgj_free_unattached(sgj_opaque_p jop); +/* If jsp is NULL or jsp->basep is NULL then this function does nothing. + * This function does bottom up, heap freeing of all the in-core JSON + * objects and arrays attached to the root JSON object assumed to be + * found at jsp->basep . After this call jsp->basep, jsp->outputp and + * jsp->userp will all be set to NULL. */ void sgj_finish(sgj_state * jsp); -- cgit v1.2.3