xref: /aosp_15_r20/external/sg3_utils/include/sg_pr2serr.h (revision 44704f698541f6367e81f991ef8bb54ccbf3fc18)
1*44704f69SBart Van Assche #ifndef SG_PR2SERR_H
2*44704f69SBart Van Assche #define SG_PR2SERR_H
3*44704f69SBart Van Assche 
4*44704f69SBart Van Assche /*
5*44704f69SBart Van Assche  * Copyright (c) 2004-2022 Douglas Gilbert.
6*44704f69SBart Van Assche  * All rights reserved.
7*44704f69SBart Van Assche  * Use of this source code is governed by a BSD-style
8*44704f69SBart Van Assche  * license that can be found in the BSD_LICENSE file.
9*44704f69SBart Van Assche  *
10*44704f69SBart Van Assche  * SPDX-License-Identifier: BSD-2-Clause
11*44704f69SBart Van Assche  */
12*44704f69SBart Van Assche 
13*44704f69SBart Van Assche #include <inttypes.h>
14*44704f69SBart Van Assche #include <stdio.h>
15*44704f69SBart Van Assche #include <stdbool.h>
16*44704f69SBart Van Assche 
17*44704f69SBart Van Assche #ifdef __cplusplus
18*44704f69SBart Van Assche extern "C" {
19*44704f69SBart Van Assche #endif
20*44704f69SBart Van Assche 
21*44704f69SBart Van Assche /* pr2serr and pr2ws are convenience functions that replace the somewhat
22*44704f69SBart Van Assche  * long-winded fprintf(stderr, ....). The second form (i.e. pr2ws() ) is for
23*44704f69SBart Van Assche  * internal library use and may place its output somewhere other than stderr;
24*44704f69SBart Van Assche  * it depends on the external variable sg_warnings_strm which can be set
25*44704f69SBart Van Assche  * with sg_set_warnings_strm(). By default it uses stderr. */
26*44704f69SBart Van Assche 
27*44704f69SBart Van Assche #if __USE_MINGW_ANSI_STDIO -0 == 1
28*44704f69SBart Van Assche #define __printf(a, b) __attribute__((__format__(gnu_printf, a, b)))
29*44704f69SBart Van Assche #elif defined(__GNUC__) || defined(__clang__)
30*44704f69SBart Van Assche #define __printf(a, b) __attribute__((__format__(printf, a, b)))
31*44704f69SBart Van Assche #else
32*44704f69SBart Van Assche #define __printf(a, b)
33*44704f69SBart Van Assche #endif
34*44704f69SBart Van Assche 
35*44704f69SBart Van Assche int pr2serr(const char * fmt, ...) __printf(1, 2);
36*44704f69SBart Van Assche 
37*44704f69SBart Van Assche int pr2ws(const char * fmt, ...) __printf(1, 2);
38*44704f69SBart Van Assche 
39*44704f69SBart Van Assche /* Want safe, 'n += snprintf(b + n, blen - n, ...)' style sequence of
40*44704f69SBart Van Assche  * functions that can be called multiple times. Returns number of chars
41*44704f69SBart Van Assche  * placed in cp excluding the trailing null char. So for cp_max_len > 0 the
42*44704f69SBart Van Assche  * return value is always < cp_max_len; for cp_max_len <= 1 the return value
43*44704f69SBart Van Assche  * is 0 and no chars are written to cp. Note this means that when
44*44704f69SBart Van Assche  * cp_max_len = 1, this function assumes that cp[0] is the null character
45*44704f69SBart Van Assche  * and does nothing (and returns 0). Linux kernel has a similar function
46*44704f69SBart Van Assche  * called  scnprintf().  */
47*44704f69SBart Van Assche int sg_scnpr(char * cp, int cp_max_len, const char * fmt, ...) __printf(3, 4);
48*44704f69SBart Van Assche 
49*44704f69SBart Van Assche /* JSON support functions and structures follow. The prefix "sgj_" is used
50*44704f69SBart Van Assche  * for sg3_utils JSON functions, types and values. */
51*44704f69SBart Van Assche 
52*44704f69SBart Van Assche enum sgj_separator_t {
53*44704f69SBart Van Assche     SGJ_SEP_NONE = 0,
54*44704f69SBart Van Assche     SGJ_SEP_SPACE_1,
55*44704f69SBart Van Assche     SGJ_SEP_SPACE_2,
56*44704f69SBart Van Assche     SGJ_SEP_SPACE_3,
57*44704f69SBart Van Assche     SGJ_SEP_SPACE_4,
58*44704f69SBart Van Assche     SGJ_SEP_EQUAL_NO_SPACE,
59*44704f69SBart Van Assche     SGJ_SEP_EQUAL_1_SPACE,
60*44704f69SBart Van Assche     SGJ_SEP_COLON_NO_SPACE,
61*44704f69SBart Van Assche     SGJ_SEP_COLON_1_SPACE,
62*44704f69SBart Van Assche };
63*44704f69SBart Van Assche 
64*44704f69SBart Van Assche typedef void * sgj_opaque_p;
65*44704f69SBart Van Assche 
66*44704f69SBart Van Assche /* Apart from the state information at the end of this structure, the earlier
67*44704f69SBart Van Assche  * fields are initialized from the command line argument given to the
68*44704f69SBart Van Assche  * --json= option. If there is no argument then they initialized as shown. */
69*44704f69SBart Van Assche typedef struct sgj_state_t {
70*44704f69SBart Van Assche     /* the following set by default, the SG3_UTILS_JSON_OPTS environment
71*44704f69SBart Van Assche      * variable or command line argument to --json option, in that order. */
72*44704f69SBart Van Assche     bool pr_as_json;            /* = false (def: is human readable output) */
73*44704f69SBart Van Assche     bool pr_exit_status;        /* 'e' (def: true) */
74*44704f69SBart Van Assche     bool pr_hex;                /* 'h' (def: false) */
75*44704f69SBart Van Assche     bool pr_leadin;             /* 'l' (def: true) */
76*44704f69SBart Van Assche     bool pr_name_ex;        /* 'n' name_extra (information) (def: false) */
77*44704f69SBart Van Assche     bool pr_out_hr;             /* 'o' (def: false) */
78*44704f69SBart Van Assche     bool pr_packed;             /* 'k' (def: false) only when !pr_pretty */
79*44704f69SBart Van Assche     bool pr_pretty;             /* 'p' (def: true) */
80*44704f69SBart Van Assche     bool pr_string;             /* 's' (def: true) */
81*44704f69SBart Van Assche     char pr_format;             /*  (def: '\0') */
82*44704f69SBart Van Assche     int pr_indent_size;         /* digit (def: 4) */
83*44704f69SBart Van Assche     int verbose;                /* 'v' (def: 0) incremented each appearance */
84*44704f69SBart Van Assche 
85*44704f69SBart Van Assche     /* the following hold state information */
86*44704f69SBart Van Assche     int first_bad_char;         /* = '\0' */
87*44704f69SBart Van Assche     sgj_opaque_p basep;         /* base JSON object pointer */
88*44704f69SBart Van Assche     sgj_opaque_p out_hrp;       /* JSON array pointer when pr_out_hr set */
89*44704f69SBart Van Assche     sgj_opaque_p userp;         /* for temporary usage */
90*44704f69SBart Van Assche } sgj_state;
91*44704f69SBart Van Assche 
92*44704f69SBart Van Assche /* This function tries to convert the in_name C string to the "snake_case"
93*44704f69SBart Van Assche  * convention so the output sname only contains lower case ASCII letters,
94*44704f69SBart Van Assche  * numerals and "_" as a separator. Any leading or trailing underscores
95*44704f69SBart Van Assche  * are removed as are repeated underscores (e.g. "_Snake __ case" becomes
96*44704f69SBart Van Assche  * "snake_case"). Parentheses and the characters between them are removed.
97*44704f69SBart Van Assche  * Returns sname (i.e. the pointer to the output buffer).
98*44704f69SBart Van Assche  * Note: strlen(in_name) should be <= max_sname_len . */
99*44704f69SBart Van Assche char * sgj_convert_to_snake_name(const char * in_name, char * sname,
100*44704f69SBart Van Assche                                  int max_sname_len);
101*44704f69SBart Van Assche bool sgj_is_snake_name(const char * in_name);
102*44704f69SBart Van Assche 
103*44704f69SBart Van Assche /* There are many variants of JSON supporting functions below and some
104*44704f69SBart Van Assche  * abbreviations are used to shorten their function names:
105*44704f69SBart Van Assche  *    sgj_  - prefix of all the functions related to (non-)JSON output
106*44704f69SBart Van Assche  *    hr    - human readable form (as it was before JSON)
107*44704f69SBart Van Assche  *    js    - JSON only output
108*44704f69SBart Van Assche  *    haj   - human readable and JSON output, hr goes in 'output' array
109*44704f69SBart Van Assche  *    pr    - has printf() like variadic arguments
110*44704f69SBart Van Assche  *    _r    - suffix indicating the return value should/must be used
111*44704f69SBart Van Assche  *    nv    - adds a name-value JSON field (or several)
112*44704f69SBart Van Assche  *    o     - value is the provided JSON object (or array)
113*44704f69SBart Van Assche  *    i     - value is a JSON integer object (int64_t or uint64_t)
114*44704f69SBart Van Assche  *    b     - value is a JSON boolean object
115*44704f69SBart Van Assche  *    s     - value is a JSON string object
116*44704f69SBart Van Assche  *    str   - same as s
117*44704f69SBart Van Assche  *    hex   - value is hexadecimal in a JSON string object
118*44704f69SBart Van Assche  *    _nex  - extra 'name_extra' JSON string object about name
119*44704f69SBart Van Assche  *    new   - object that needs sgj_free_unattached() if not attached
120*44704f69SBart Van Assche  *
121*44704f69SBart Van Assche  *    */
122*44704f69SBart Van Assche 
123*44704f69SBart Van Assche /* If jsp in non-NULL and jsp->pr_as_json is true then this call is ignored
124*44704f69SBart Van Assche  * unless jsp->pr_out_hrp is true. Otherwise this function prints to stdout
125*44704f69SBart Van Assche  * like printf(fmt, ...); note that no LF is added. In the jsp->pr_out_hrp is
126*44704f69SBart Van Assche  * true case, nothing is printed to stdout but instead is placed into a JSON
127*44704f69SBart Van Assche  * array (jsp->out_hrp) after some preprocessing. That preprocessing involves
128*44704f69SBart Van Assche  * removing a leading LF from 'fmt' (if present) and up to two trailing LF
129*44704f69SBart Van Assche  * characters. */
130*44704f69SBart Van Assche void sgj_pr_hr(sgj_state * jsp, const char * fmt, ...) __printf(2, 3);
131*44704f69SBart Van Assche 
132*44704f69SBart Van Assche /* Initializes the state object pointed to by jsp based on the argument
133*44704f69SBart Van Assche  * given to the right of --json= pointed to by j_optarg. If it is NULL
134*44704f69SBart Van Assche  * then state object gets its default values. Returns true if argument
135*44704f69SBart Van Assche  * to --json= is decoded properly, else returns false and places the
136*44704f69SBart Van Assche  * first "bad" character in jsp->first_bad_char . Note that no JSON
137*44704f69SBart Van Assche  * in-core tree needs to exist when this function is called. */
138*44704f69SBart Van Assche bool sgj_init_state(sgj_state * jsp, const char * j_optarg);
139*44704f69SBart Van Assche 
140*44704f69SBart Van Assche /* sgj_start() creates a JSON in-core tree and returns a pointer to it (or
141*44704f69SBart Van Assche  * NULL if the associated heap allocation fails). It should be paired with
142*44704f69SBart Van Assche  * sgj_finish() to clean up (i.e. remove all heap allocations) all the
143*44704f69SBart Van Assche  * elements (i.e. JSON objects and arrays) that have been placed in that
144*44704f69SBart Van Assche  * in-core tree. If jsp is NULL nothing further happens. Otherwise the pointer
145*44704f69SBart Van Assche  * to be returned is placed in jsp->basep. If jsp->pr_leadin is true and
146*44704f69SBart Van Assche  * util_name is non-NULL then a "utility_invoked" JSON object is made with
147*44704f69SBart Van Assche  * "name", and "version_date" object fields. If the jsp->pr_out_hr field is
148*44704f69SBart Van Assche  * true a named array called "output" is added to the "utility_invoked" object
149*44704f69SBart Van Assche  * (creating it in the case when jsp->pr_leadin is false) and a pointer to
150*44704f69SBart Van Assche  * that array object is placed in jsp->objectp . The returned pointer is not
151*44704f69SBart Van Assche  * usually needed but if it is NULL then a heap allocation has failed. */
152*44704f69SBart Van Assche sgj_opaque_p sgj_start_r(const char * util_name, const char * ver_str,
153*44704f69SBart Van Assche                          int argc, char *argv[], sgj_state * jsp);
154*44704f69SBart Van Assche 
155*44704f69SBart Van Assche /* These are low level functions returning a pointer to a newly created JSON
156*44704f69SBart Van Assche  * object or array. If jsp is NULL or jsp->pr_as_json is false nothing happens
157*44704f69SBart Van Assche  * and NULL is returned. Note that this JSON object is _not_ placed in the
158*44704f69SBart Van Assche  * in-core tree controlled by jsp (jsp->basep); it may be added later as the
159*44704f69SBart Van Assche  * fourth argument to sgj_js_nv_o(), for example. */
160*44704f69SBart Van Assche sgj_opaque_p sgj_new_unattached_object_r(sgj_state * jsp);
161*44704f69SBart Van Assche sgj_opaque_p sgj_new_unattached_array_r(sgj_state * jsp);
162*44704f69SBart Van Assche 
163*44704f69SBart Van Assche /* If jsp is NULL or jsp->pr_as_json is false nothing happens and NULL is
164*44704f69SBart Van Assche  * returned. Otherwise it creates a new named object (whose name is what
165*44704f69SBart Van Assche  * 'name' points to) at 'jop' with an empty object as its value; a pointer
166*44704f69SBart Van Assche  * to that empty object is returned. If 'jop' is NULL then jsp->basep is
167*44704f69SBart Van Assche  * used instead. The returned value should always be checked (for NULL)
168*44704f69SBart Van Assche  * and if not, used. */
169*44704f69SBart Van Assche sgj_opaque_p sgj_named_subobject_r(sgj_state * jsp, sgj_opaque_p jop,
170*44704f69SBart Van Assche                                    const char * name);
171*44704f69SBart Van Assche sgj_opaque_p sgj_snake_named_subobject_r(sgj_state * jsp, sgj_opaque_p jop,
172*44704f69SBart Van Assche                                          const char * conv2sname);
173*44704f69SBart Van Assche 
174*44704f69SBart Van Assche /* If jsp is NULL or jsp->pr_as_json is false nothing happens and NULL is
175*44704f69SBart Van Assche  * returned. Otherwise it creates a new named object (whose name is what
176*44704f69SBart Van Assche  * 'name' points to) at 'jop' with an empty array as its value; a pointer
177*44704f69SBart Van Assche  * to that empty array is returned.  If 'jop' is NULL then jsp->basep is
178*44704f69SBart Van Assche  * used instead. The returned value should always * be checked (for NULL)
179*44704f69SBart Van Assche  * and if not, used. */
180*44704f69SBart Van Assche sgj_opaque_p sgj_named_subarray_r(sgj_state * jsp, sgj_opaque_p jop,
181*44704f69SBart Van Assche                                   const char * name);
182*44704f69SBart Van Assche sgj_opaque_p sgj_snake_named_subarray_r(sgj_state * jsp, sgj_opaque_p jop,
183*44704f69SBart Van Assche                                         const char * conv2sname);
184*44704f69SBart Van Assche 
185*44704f69SBart Van Assche /* If either jsp or value is NULL or jsp->pr_as_json is false then nothing
186*44704f69SBart Van Assche  * happens and NULL is returned. The insertion point is at jop but if it is
187*44704f69SBart Van Assche  * NULL jsp->basep is used. If 'name' is non-NULL a new named JSON object is
188*44704f69SBart Van Assche  * added using 'name' and the associated value is a JSON string formed from
189*44704f69SBart Van Assche  * 'value'. If 'name' is NULL then 'jop' is assumed to be a JSON array and
190*44704f69SBart Van Assche  * a JSON string formed from 'value' is added. Note that the jsp->pr_string
191*44704f69SBart Van Assche  * setting is ignored by this function. If successful returns a * a pointer
192*44704f69SBart Van Assche  * newly formed JSON string. */
193*44704f69SBart Van Assche sgj_opaque_p sgj_js_nv_s(sgj_state * jsp, sgj_opaque_p jop,
194*44704f69SBart Van Assche                          const char * name, const char * value);
195*44704f69SBart Van Assche sgj_opaque_p sgj_js_nv_s_len(sgj_state * jsp, sgj_opaque_p jop,
196*44704f69SBart Van Assche                              const char * name,
197*44704f69SBart Van Assche                              const char * value, int slen);
198*44704f69SBart Van Assche 
199*44704f69SBart Van Assche /* If either jsp is NULL or jsp->pr_as_json is false then nothing happens and
200*44704f69SBart Van Assche  * NULL is returned. The insertion point is at jop but if it is NULL
201*44704f69SBart Van Assche  * jsp->basep is used. If 'name' is non-NULL a new named JSON object is
202*44704f69SBart Van Assche  * added using 'name' and the associated value is a JSON integer formed from
203*44704f69SBart Van Assche  * 'value'. If 'name' is NULL then 'jop' is assumed to be a JSON array and
204*44704f69SBart Van Assche  * a JSON integer formed from 'value' is added. If successful returns a
205*44704f69SBart Van Assche  * a pointer newly formed JSON integer. */
206*44704f69SBart Van Assche sgj_opaque_p sgj_js_nv_i(sgj_state * jsp, sgj_opaque_p jop,
207*44704f69SBart Van Assche                          const char * name, int64_t value);
208*44704f69SBart Van Assche 
209*44704f69SBart Van Assche /* If either jsp is NULL or jsp->pr_as_json is false then nothing happens and
210*44704f69SBart Van Assche  * NULL is returned. The insertion point is at jop but if it is NULL
211*44704f69SBart Van Assche  * jsp->basep is used. If 'name' is non-NULL a new named JSON object is
212*44704f69SBart Van Assche  * added using 'name' and the associated value is a JSON boolean formed from
213*44704f69SBart Van Assche  * 'value'. If 'name' is NULL then 'jop' is assumed to be a JSON array and
214*44704f69SBart Van Assche  * a JSON boolean formed from 'value' is added. If successful returns a
215*44704f69SBart Van Assche  * a pointer newly formed JSON boolean. */
216*44704f69SBart Van Assche sgj_opaque_p sgj_js_nv_b(sgj_state * jsp, sgj_opaque_p jop,
217*44704f69SBart Van Assche                          const char * name, bool value);
218*44704f69SBart Van Assche 
219*44704f69SBart Van Assche /* If jsp is NULL, jsp->pr_as_json is false or ua_jop is NULL nothing then
220*44704f69SBart Van Assche  * happens and NULL is returned. 'jop' is the insertion point but if it is
221*44704f69SBart Van Assche  * NULL jsp->basep is used instead. If 'name' is non-NULL a new named JSON
222*44704f69SBart Van Assche  * object is added using 'name' and the associated value is ua_jop. If 'name'
223*44704f69SBart Van Assche  * is NULL then 'jop' is assumed to be a JSON array and ua_jop is added to
224*44704f69SBart Van Assche  * it. If successful returns ua_jop . The "ua_" prefix stands for unattached.
225*44704f69SBart Van Assche  * That should be the case before invocation and it will be attached to jop
226*44704f69SBart Van Assche  * after a successful invocation. This means that ua_jop must have been
227*44704f69SBart Van Assche  * created by sgj_new_unattached_object_r() or similar. */
228*44704f69SBart Van Assche sgj_opaque_p sgj_js_nv_o(sgj_state * jsp, sgj_opaque_p jop,
229*44704f69SBart Van Assche                          const char * name, sgj_opaque_p ua_jop);
230*44704f69SBart Van Assche 
231*44704f69SBart Van Assche /* This function only produces JSON output if jsp is non-NULL and
232*44704f69SBart Van Assche  * jsp->pr_as_json is true. It adds a named object at 'jop' (or jop->basep
233*44704f69SBart Van Assche  * if jop is NULL) along with a value. If jsp->pr_hex is true then that
234*44704f69SBart Van Assche  * value is two sub-objects, one named 'i' with a 'value' as a JSON integer,
235*44704f69SBart Van Assche  * the other one named 'hex' with 'value' rendered as hex in a JSON string.
236*44704f69SBart Van Assche  * If jsp->pr_hex is false then there are no sub-objects and the 'value' is
237*44704f69SBart Van Assche  * rendered as JSON integer. */
238*44704f69SBart Van Assche void sgj_js_nv_ihex(sgj_state * jsp, sgj_opaque_p jop,
239*44704f69SBart Van Assche                     const char * name, uint64_t value);
240*44704f69SBart Van Assche 
241*44704f69SBart Van Assche /* This function only produces JSON output if jsp is non-NULL and
242*44704f69SBart Van Assche  * jsp->pr_as_json is true. It adds a named object at 'jop' (or jop->basep
243*44704f69SBart Van Assche  * if jop is NULL) along with a value. If jsp->pr_string is true then that
244*44704f69SBart Van Assche  * value is two sub-objects, one named 'i' with a 'val_i' as a JSON integer,
245*44704f69SBart Van Assche  * the other one named str_name with val_s rendered as a JSON string. If
246*44704f69SBart Van Assche  * str_name is NULL then "meaning" will be used. If jsp->pr_string is false
247*44704f69SBart Van Assche  * then there are no sub-objects and the 'val_i' is rendered as a JSON
248*44704f69SBart Van Assche  * integer. */
249*44704f69SBart Van Assche void sgj_js_nv_istr(sgj_state * jsp, sgj_opaque_p jop,
250*44704f69SBart Van Assche                     const char * name, int64_t val_i,
251*44704f69SBart Van Assche                     const char * str_name, const char * val_s);
252*44704f69SBart Van Assche 
253*44704f69SBart Van Assche /* Similar to sgj_js_nv_istr(). The hex output is conditional jsp->pr_hex . */
254*44704f69SBart Van Assche void sgj_js_nv_ihexstr(sgj_state * jsp, sgj_opaque_p jop,
255*44704f69SBart Van Assche                        const char * name, int64_t val_i,
256*44704f69SBart Van Assche                        const char * str_name, const char * val_s);
257*44704f69SBart Van Assche 
258*44704f69SBart Van Assche /* This function only produces JSON output if jsp is non-NULL and
259*44704f69SBart Van Assche  * jsp->pr_as_json is true. It adds a named object at 'jop' (or jop->basep
260*44704f69SBart Van Assche  * if jop is NULL) along with a value. If jsp->pr_name_ex is true then that
261*44704f69SBart Van Assche  * value is two sub-objects, one named 'i' with a 'val_i' as a JSON integer,
262*44704f69SBart Van Assche  * the other one named "abbreviated_name_expansion" with value nex_s rendered
263*44704f69SBart Van Assche  * as a JSON string. If jsp->pr_hex and 'hex_as_well' are true, then a
264*44704f69SBart Van Assche  * sub-object named 'hex' with a value rendered as a hex string equal to
265*44704f69SBart Van Assche  * val_i. If jsp->pr_name_ex is false and either jsp->pr_hex or hex_as_well are
266*44704f69SBart Van Assche  * false then there are no sub-objects and the 'val_i' is rendered as a JSON
267*44704f69SBart Van Assche  * integer. */
268*44704f69SBart Van Assche void sgj_js_nv_ihex_nex(sgj_state * jsp, sgj_opaque_p jop, const char * name,
269*44704f69SBart Van Assche                         int64_t val_i, bool hex_as_well, const char * nex_s);
270*44704f69SBart Van Assche 
271*44704f69SBart Van Assche void sgj_js_nv_ihexstr_nex(sgj_state * jsp, sgj_opaque_p jop,
272*44704f69SBart Van Assche                            const char * name, int64_t val_i, bool hex_as_well,
273*44704f69SBart Van Assche                            const char * str_name, const char * val_s,
274*44704f69SBart Van Assche                            const char * nex_s);
275*44704f69SBart Van Assche 
276*44704f69SBart Van Assche /* Add named field whose value is a (large) JSON string made up of num_bytes
277*44704f69SBart Van Assche  * ASCII hexadecimal bytes (each two hex digits separated by a space) starting
278*44704f69SBart Van Assche  * at byte_arr. The heap is used for intermediate storage so num_bytes can
279*44704f69SBart Van Assche  * be arbitrarily large. */
280*44704f69SBart Van Assche void sgj_js_nv_hex_bytes(sgj_state * jsp, sgj_opaque_p jop, const char * name,
281*44704f69SBart Van Assche                          const uint8_t * byte_arr, int num_bytes);
282*44704f69SBart Van Assche 
283*44704f69SBart Van Assche /* The '_haj_' refers to generating output both for human readable and/or
284*44704f69SBart Van Assche  * JSON with a single invocation. If jsp is non-NULL and jsp->pr_out_hr is
285*44704f69SBart Van Assche  * true then both JSON and human readable output is formed (and the latter is
286*44704f69SBart Van Assche  * placed in the jsp->out_hrp JSON array). The human readable form will have
287*44704f69SBart Van Assche  * leadin_sp spaces followed by 'name' then a separator, then 'value' with a
288*44704f69SBart Van Assche  * trailing LF. If 'name' is NULL then it and the separator are ignored. If
289*44704f69SBart Van Assche  * there is JSON output, then leadin_sp and sep are ignored. If 'jop' is NULL
290*44704f69SBart Van Assche  * then basep->basep is used. If 'name' is NULL then a JSON string object,
291*44704f69SBart Van Assche  * made from 'value' is added to the JSON array pointed to by 'jop'.
292*44704f69SBart Van Assche  * Otherwise a 'name'-d JSON object whose value is a JSON string object made
293*44704f69SBart Van Assche  * from 'value' is added at 'jop'. */
294*44704f69SBart Van Assche void sgj_haj_vs(sgj_state * jsp, sgj_opaque_p jop, int leadin_sp,
295*44704f69SBart Van Assche                 const char * name, enum sgj_separator_t sep,
296*44704f69SBart Van Assche                 const char * value);
297*44704f69SBart Van Assche 
298*44704f69SBart Van Assche /* Similar to sgj_haj_vs()'s description with 'JSON string object'
299*44704f69SBart Van Assche  * replaced by 'JSON integer object'. */
300*44704f69SBart Van Assche void sgj_haj_vi(sgj_state * jsp, sgj_opaque_p jop, int leadin_sp,
301*44704f69SBart Van Assche                 const char * name, enum sgj_separator_t sep,
302*44704f69SBart Van Assche                 int64_t value, bool hex_as_well);
303*44704f69SBart Van Assche void sgj_haj_vistr(sgj_state * jsp, sgj_opaque_p jop, int leadin_sp,
304*44704f69SBart Van Assche                    const char * name, enum sgj_separator_t sep,
305*44704f69SBart Van Assche                    int64_t value, bool hex_as_well, const char * val_s);
306*44704f69SBart Van Assche 
307*44704f69SBart Van Assche /* The '_nex' refers to a "name_extra" (information) sub-object (a JSON
308*44704f69SBart Van Assche  * string) which explains a bit more about the 'name' entry. This is useful
309*44704f69SBart Van Assche  * when T10 specifies the name as an abbreviation (e.g. SYSV). Whether this
310*44704f69SBart Van Assche  * sub-object is shown in the JSON output is controlled by the 'n' control
311*44704f69SBart Van Assche  * character. */
312*44704f69SBart Van Assche void sgj_haj_vi_nex(sgj_state * jsp, sgj_opaque_p jop, int leadin_sp,
313*44704f69SBart Van Assche                     const char * name, enum sgj_separator_t sep,
314*44704f69SBart Van Assche                     int64_t value, bool hex_as_well, const char * nex_s);
315*44704f69SBart Van Assche void sgj_haj_vistr_nex(sgj_state * jsp, sgj_opaque_p jop, int leadin_sp,
316*44704f69SBart Van Assche                        const char * name, enum sgj_separator_t sep,
317*44704f69SBart Van Assche                        int64_t value, bool hex_as_well,
318*44704f69SBart Van Assche                        const char * val_s, const char * nex_s);
319*44704f69SBart Van Assche 
320*44704f69SBart Van Assche /* Similar to above '_haj_' calls but a named sub-object is always formed
321*44704f69SBart Van Assche  * containing a JSON integer object named "i" whose value is 'value'. The
322*44704f69SBart Van Assche  * returned pointer is to that sub-object. */
323*44704f69SBart Van Assche sgj_opaque_p sgj_haj_subo_r(sgj_state * jsp, sgj_opaque_p jop, int leadin_sp,
324*44704f69SBart Van Assche                             const char * name, enum sgj_separator_t sep,
325*44704f69SBart Van Assche                             int64_t value, bool hex_as_well);
326*44704f69SBart Van Assche 
327*44704f69SBart Van Assche /* Similar to sgj_haj_vs()'s description with 'JSON string object' replaced
328*44704f69SBart Van Assche  * by 'JSON boolean object'. */
329*44704f69SBart Van Assche void sgj_haj_vb(sgj_state * jsp, sgj_opaque_p jop, int leadin_sp,
330*44704f69SBart Van Assche                 const char * name, enum sgj_separator_t sep, bool value);
331*44704f69SBart Van Assche 
332*44704f69SBart Van Assche /* Breaks up the string pointed to by 'sp' into lines and adds them to the
333*44704f69SBart Van Assche  * jsp->out_hrp array. Treat '\n' in sp as line breaks. Consumes characters
334*44704f69SBart Van Assche  * from sp until either a '\0' is found or slen is exhausted. Add each line
335*44704f69SBart Van Assche  * to jsp->out_hrp JSON array (if conditions met). */
336*44704f69SBart Van Assche void sgj_js_str_out(sgj_state * jsp, const char * sp, int slen);
337*44704f69SBart Van Assche 
338*44704f69SBart Van Assche /* This function only produces JSON output if jsp is non-NULL and
339*44704f69SBart Van Assche  * jsp->pr_as_json is true. 'sbp' is assumed to point to sense data as
340*44704f69SBart Van Assche  * defined by T10 with a length of 'sb_len' bytes. Returns false if an
341*44704f69SBart Van Assche  * issue is detected, else it returns true. */
342*44704f69SBart Van Assche bool sgj_js_sense(sgj_state * jsp, sgj_opaque_p jop, const uint8_t * sbp,
343*44704f69SBart Van Assche                   int sb_len);
344*44704f69SBart Van Assche 
345*44704f69SBart Van Assche bool sgj_js_designation_descriptor(sgj_state * jsp, sgj_opaque_p jop,
346*44704f69SBart Van Assche                                    const uint8_t * ddp, int dd_len);
347*44704f69SBart Van Assche 
348*44704f69SBart Van Assche /* Nothing in the in-core JSON tree is actually printed to 'fp' (typically
349*44704f69SBart Van Assche  * stdout) until this call is made. If jsp is NULL, jsp->pr_as_json is false
350*44704f69SBart Van Assche  * or jsp->basep is NULL then this function does nothing. If jsp->exit_status
351*44704f69SBart Van Assche  * is true then a new JSON object named "exit_status" and the 'exit_status'
352*44704f69SBart Van Assche  * value rendered as a JSON integer is appended to jsp->basep. The in-core
353*44704f69SBart Van Assche  * JSON tree with jsp->basep as its root is streamed to 'fp'. */
354*44704f69SBart Van Assche void sgj_js2file(sgj_state * jsp, sgj_opaque_p jop, int exit_status,
355*44704f69SBart Van Assche                  FILE * fp);
356*44704f69SBart Van Assche 
357*44704f69SBart Van Assche /* This function is only needed if the pointer returned from either
358*44704f69SBart Van Assche  * sgj_new_unattached_object_r() or sgj_new_unattached_array_r() has not
359*44704f69SBart Van Assche  * been attached into the in-core JSON tree whose root is jsp->basep . */
360*44704f69SBart Van Assche void sgj_free_unattached(sgj_opaque_p jop);
361*44704f69SBart Van Assche 
362*44704f69SBart Van Assche /* If jsp is NULL or jsp->basep is NULL then this function does nothing.
363*44704f69SBart Van Assche  * This function does bottom up, heap freeing of all the in-core JSON
364*44704f69SBart Van Assche  * objects and arrays attached to the root JSON object assumed to be
365*44704f69SBart Van Assche  * found at jsp->basep . After this call jsp->basep, jsp->out_hrp and
366*44704f69SBart Van Assche  * jsp->userp will all be set to NULL.  */
367*44704f69SBart Van Assche void sgj_finish(sgj_state * jsp);
368*44704f69SBart Van Assche 
369*44704f69SBart Van Assche char * sg_json_usage(int char_if_not_j, char * b, int blen);
370*44704f69SBart Van Assche 
371*44704f69SBart Van Assche 
372*44704f69SBart Van Assche #ifdef __cplusplus
373*44704f69SBart Van Assche }
374*44704f69SBart Van Assche #endif
375*44704f69SBart Van Assche 
376*44704f69SBart Van Assche #endif
377