aboutsummaryrefslogtreecommitdiff
path: root/lib/sg_pr2serr.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sg_pr2serr.c')
-rw-r--r--lib/sg_pr2serr.c145
1 files changed, 100 insertions, 45 deletions
diff --git a/lib/sg_pr2serr.c b/lib/sg_pr2serr.c
index be07a2e1..310ea78b 100644
--- a/lib/sg_pr2serr.c
+++ b/lib/sg_pr2serr.c
@@ -49,6 +49,8 @@ static const json_serialize_opts def_out_settings = {
4 /* indent size */
};
+static int sgj_name_to_snake(const char * in, char * out, int maxlen_out);
+
/* Users of the sg_pr2serr.h header need this function definition */
int
@@ -116,11 +118,14 @@ sgj_parse_opts(sgj_state * jsp, const char * j_optarg)
case 'h':
jsp->pr_hex = ! prev_negate;
break;
+ case 'k':
+ jsp->pr_packed = ! prev_negate;
+ break;
case 'l':
jsp->pr_leadin = ! prev_negate;
break;
case 'o':
- jsp->pr_output = ! prev_negate;
+ jsp->pr_out_hr = ! prev_negate;
break;
case 'p':
jsp->pr_pretty = ! prev_negate;
@@ -178,6 +183,8 @@ sg_json_usage(int char_if_not_j, char * b, int blen)
n += sg_scnpr(b + n, blen - n,
" h show 'hex' fields\n");
n += sg_scnpr(b + n, blen - n,
+ " k packed, only non-pretty printed output\n");
+ n += sg_scnpr(b + n, blen - n,
" l show lead-in fields (invocation "
"information)\n");
n += sg_scnpr(b + n, blen - n,
@@ -212,11 +219,12 @@ fini:
char *
sg_json_settings(sgj_state * jsp, char * b, int blen)
{
- snprintf(b, blen, "%d%sa%se%sh%sl%so%sp%ss%sv", jsp->pr_indent_size,
+ snprintf(b, blen, "%d%sa%se%sh%sk%sl%so%sp%ss%sv", jsp->pr_indent_size,
jsp->pr_ane ? "" : "-", jsp->pr_exit_status ? "" : "-",
- jsp->pr_hex ? "" : "-", jsp->pr_leadin ? "" : "-",
- jsp->pr_output ? "" : "-", jsp->pr_pretty ? "" : "-",
- jsp->pr_string ? "" : "-", jsp->verbose ? "" : "-");
+ jsp->pr_hex ? "" : "-", jsp->pr_packed ? "" : "-",
+ jsp->pr_leadin ? "" : "-", jsp->pr_out_hr ? "" : "-",
+ jsp->pr_pretty ? "" : "-", jsp->pr_string ? "" : "-",
+ jsp->verbose ? "" : "-");
return b;
}
@@ -228,7 +236,8 @@ sgj_def_opts(sgj_state * jsp)
jsp->pr_exit_status = true;
jsp->pr_hex = false;
jsp->pr_leadin = true;
- jsp->pr_output = false;
+ jsp->pr_out_hr = false;
+ jsp->pr_packed = false; /* 'k' control character, needs '-p' */
jsp->pr_pretty = true;
jsp->pr_string = true;
jsp->pr_format = 0;
@@ -244,7 +253,7 @@ sgj_init_state(sgj_state * jsp, const char * j_optarg)
sgj_def_opts(jsp);
jsp->basep = NULL;
- jsp->outputp = NULL;
+ jsp->out_hrp = NULL;
jsp->userp = NULL;
cp = getenv(sgj_opts_ev);
@@ -286,8 +295,11 @@ sgj_start(const char * util_name, const char * ver_str, int argc,
(json_value *)jap);
if (util_name) {
jap = json_array_new(0);
- for (k = 0; k < argc; ++k)
- json_array_push((json_value *)jap, json_string_new(argv[k]));
+ if (argv) {
+ for (k = 0; k < argc; ++k)
+ json_array_push((json_value *)jap,
+ json_string_new(argv[k]));
+ }
jv2p = json_object_push((json_value *)jvp, "utility_invoked",
json_object_new(0));
json_object_push((json_value *)jv2p, "name",
@@ -313,19 +325,19 @@ sgj_start(const char * util_name, const char * ver_str, int argc,
json_string_new(b));
}
} else {
- if (jsp->pr_output && util_name)
+ if (jsp->pr_out_hr && util_name)
jv2p = json_object_push((json_value *)jvp, "utility_invoked",
json_object_new(0));
}
- if (jsp->pr_output && jv2p) {
- jsp->outputp = json_object_push((json_value *)jv2p, "output",
+ if (jsp->pr_out_hr && jv2p) {
+ jsp->out_hrp = json_object_push((json_value *)jv2p, "output",
json_array_new(0));
if (jsp->pr_leadin && (jsp->verbose > 3)) {
char * bp = (char *)calloc(4096, 1);
if (bp) {
sg_json_usage(0, bp, 4096);
- sgj_pr_str_output(jsp, bp, strlen(bp));
+ sgj_pr_str_out_hr(jsp, bp, strlen(bp));
free(bp);
}
}
@@ -359,7 +371,8 @@ sgj_pr2file(sgj_state * jsp, sgj_opaque_p jop, int exit_status, FILE * fp)
if (jsp->pr_indent_size != def_out_settings.indent_size)
out_settings.indent_size = jsp->pr_indent_size;
if (! jsp->pr_pretty)
- out_settings.mode = json_serialize_mode_single_line;
+ out_settings.mode = jsp->pr_packed ? json_serialize_mode_packed :
+ json_serialize_mode_single_line;
len = json_measure_ex(jvp, out_settings);
if (len < 1)
@@ -372,6 +385,7 @@ sgj_pr2file(sgj_state * jsp, sgj_opaque_p jop, int exit_status, FILE * fp)
pr2serr("%s: unable to get %zu bytes on heap\n", __func__, len);
return;
}
+
json_serialize_ex(b, jvp, out_settings);
if (jsp->verbose > 3)
fprintf(fp, "json serialized:\n");
@@ -384,7 +398,7 @@ sgj_finish(sgj_state * jsp)
if (jsp && jsp->basep) {
json_builder_free((json_value *)jsp->basep);
jsp->basep = NULL;
- jsp->outputp = NULL;
+ jsp->out_hrp = NULL;
jsp->userp = NULL;
}
}
@@ -401,7 +415,7 @@ sgj_pr_hr(sgj_state * jsp, const char * fmt, ...)
{
va_list args;
- if (jsp->pr_as_json && jsp->pr_output) {
+ if (jsp->pr_as_json && jsp->pr_out_hr) {
size_t len;
char b[256];
@@ -420,7 +434,7 @@ sgj_pr_hr(sgj_state * jsp, const char * fmt, ...)
/* remove leading linefeed, if present */
if ((len > 0) && ('\n' == b[0]))
++cp;
- json_array_push((json_value *)jsp->outputp, json_string_new(cp));
+ json_array_push((json_value *)jsp->out_hrp, json_string_new(cp));
}
va_end(args);
} else if (jsp->pr_as_json) {
@@ -445,6 +459,22 @@ sgj_new_named_object(sgj_state * jsp, sgj_opaque_p jop, const char * name)
return resp;
}
+sgj_opaque_p
+sgj_new_snake_named_object(sgj_state * jsp, sgj_opaque_p jop,
+ const char * conv2sname)
+{
+ if (jsp && jsp->pr_as_json && conv2sname) {
+ int olen = strlen(conv2sname);
+ char * sname = malloc(olen + 8);
+ int nlen = sgj_name_to_snake(conv2sname, sname, olen + 8);
+
+ if (nlen > 0)
+ return json_object_push((json_value *)(jop ? jop : jsp->basep),
+ sname, json_object_new(0));
+ }
+ return NULL;
+}
+
/* jop will 'own' returned value (if non-NULL) */
sgj_opaque_p
sgj_new_named_array(sgj_state * jsp, sgj_opaque_p jop, const char * name)
@@ -457,6 +487,22 @@ sgj_new_named_array(sgj_state * jsp, sgj_opaque_p jop, const char * name)
return resp;
}
+sgj_opaque_p
+sgj_new_snake_named_array(sgj_state * jsp, sgj_opaque_p jop,
+ const char * conv2sname)
+{
+ if (jsp && jsp->pr_as_json && conv2sname) {
+ int olen = strlen(conv2sname);
+ char * sname = malloc(olen + 8);
+ int nlen = sgj_name_to_snake(conv2sname, sname, olen + 8);
+
+ if (nlen > 0)
+ return json_object_push((json_value *)(jop ? jop : jsp->basep),
+ sname, json_array_new(0));
+ }
+ return NULL;
+}
+
/* Newly created object is un-attached to jsp->basep tree */
sgj_opaque_p
sgj_new_unattached_object(sgj_state * jsp)
@@ -490,14 +536,19 @@ sgj_opaque_p
sgj_add_nv_s_len(sgj_state * jsp, sgj_opaque_p jop, const char * name,
const char * value, int slen)
{
+ int k;
+
if (jsp && jsp->pr_as_json && value && (slen >= 0)) {
+ for (k = 0; k < slen; ++k) { /* don't want '\0' in value string */
+ if (0 == value[k])
+ break;
+ }
if (name)
return json_object_push((json_value *)(jop ? jop : jsp->basep),
- name, json_string_new_length(slen,
- value));
+ name, json_string_new_length(k, value));
else
return json_array_push((json_value *)(jop ? jop : jsp->basep),
- json_string_new_length(slen, value));
+ json_string_new_length(k, value));
} else
return NULL;
}
@@ -555,8 +606,7 @@ sgj_add_nv_ihex(sgj_state * jsp, sgj_opaque_p jop, const char * name,
if ((NULL == jsp) || (NULL == name) || (! jsp->pr_as_json))
return;
else if (jsp->pr_hex) {
- sgj_opaque_p jo2p =
- sgj_new_named_object(jsp, jop, name);
+ sgj_opaque_p jo2p = sgj_new_named_object(jsp, jop, name);
char b[64];
if (NULL == jo2p)
@@ -577,8 +627,8 @@ sgj_add_nv_istr(sgj_state * jsp, sgj_opaque_p jop, const char * name,
if ((NULL == jsp) || (! jsp->pr_as_json))
return;
else if (jsp->pr_string) {
- sgj_opaque_p jo2p =
- sgj_new_named_object(jsp, jop, name);
+ sgj_opaque_p jo2p = sgj_new_named_object(jsp, jop, name);
+
if (NULL == jo2p)
return;
sgj_add_nv_i(jsp, jo2p, "i", (int64_t)val_i);
@@ -598,8 +648,7 @@ sgj_add_nv_ihexstr(sgj_state * jsp, sgj_opaque_p jop, const char * name,
sgj_add_nv_i(jsp, jop, name, val_i);
else {
char b[64];
- sgj_opaque_p jo2p =
- sgj_new_named_object(jsp, jop, name);
+ sgj_opaque_p jo2p = sgj_new_named_object(jsp, jop, name);
if (NULL == jo2p)
return;
@@ -713,18 +762,18 @@ sgj_add_nv_ihexstr_ane(sgj_state * jsp, sgj_opaque_p jop, const char * name,
}
/* Treat '\n' in sp as line breaks. Consumes characters from sp until either
- * a '\0' is found or slen is exhausted. Add each line to jsp->outputp JSON
+ * a '\0' is found or slen is exhausted. Add each line to jsp->out_hrp JSON
* array (if conditions met). */
void
-sgj_pr_str_output(sgj_state * jsp, const char * sp, int slen)
+sgj_pr_str_out_hr(sgj_state * jsp, const char * sp, int slen)
{
char c;
int k, n;
const char * prev_sp = sp;
const char * cur_sp = sp;
- if ((NULL == jsp) || (NULL == jsp->outputp) || (! jsp->pr_as_json) ||
- (! jsp->pr_output))
+ if ((NULL == jsp) || (NULL == jsp->out_hrp) || (! jsp->pr_as_json) ||
+ (! jsp->pr_out_hr))
return;
for (k = 0; k < slen; ++k, ++cur_sp) {
c = *cur_sp;
@@ -732,20 +781,25 @@ sgj_pr_str_output(sgj_state * jsp, const char * sp, int slen)
break;
else if ('\n' == c) {
n = cur_sp - prev_sp;
- /* when name is NULL, add to array (jsp->outputp) */
- sgj_add_nv_s_len(jsp, jsp->outputp, NULL, prev_sp, n);
+ /* when name is NULL, add to array (jsp->out_hrp) */
+ sgj_add_nv_s_len(jsp, jsp->out_hrp, NULL, prev_sp, n);
prev_sp = cur_sp + 1;
}
}
if (prev_sp < cur_sp) {
n = cur_sp - prev_sp;
- sgj_add_nv_s_len(jsp, jsp->outputp, NULL, prev_sp, n);
+ sgj_add_nv_s_len(jsp, jsp->out_hrp, NULL, prev_sp, n);
}
}
-/* Returns number of characters placed in 'out' excluding trailing NULL */
+/* This function tries to convert the 'in' C string to "snake_case"
+ * convention so the output 'out' only contains lower case ASCII letters,
+ * numerals and "_" as a separator. Any leading or trailing underscores
+ * are removed as are repeated underscores (e.g. "_Snake __ case" becomes
+ * "snake_case"). Returns number of characters placed in 'out' excluding
+ * the trailing NULL */
static int
-sgj_jsonify_name(const char * in, char * out, int maxlen_out)
+sgj_name_to_snake(const char * in, char * out, int maxlen_out)
{
bool prev_underscore = false;
int c, k, j, inlen;
@@ -800,7 +854,7 @@ sgj_pr_hr_js_xx(sgj_state * jsp, sgj_opaque_p jop, int leadin_sp,
b[n] = ' ';
b[n] = '\0';
if (NULL == name) {
- if ((! as_json) || (jsp && jsp->pr_output)) {
+ if ((! as_json) || (jsp && jsp->pr_out_hr)) {
switch (jtype) {
case json_string:
sg_scnpr(b + n, blen - n, "%s", jvp->u.string.ptr);
@@ -819,9 +873,9 @@ sgj_pr_hr_js_xx(sgj_state * jsp, sgj_opaque_p jop, int leadin_sp,
printf("%s\n", b);
}
if (NULL == jop) {
- if (as_json && jsp->pr_output) {
+ if (as_json && jsp->pr_out_hr) {
eaten = true;
- json_array_push((json_value *)jsp->outputp,
+ json_array_push((json_value *)jsp->out_hrp,
jvp ? jvp : json_null_new());
}
} else { /* assume jop points to named array */
@@ -841,14 +895,14 @@ sgj_pr_hr_js_xx(sgj_state * jsp, sgj_opaque_p jop, int leadin_sp,
if (NULL == jop)
jop = jsp->basep;
- k = sgj_jsonify_name(name, jname, sizeof(jname));
+ k = sgj_name_to_snake(name, jname, sizeof(jname));
if (k > 0) {
eaten = true;
json_object_push((json_value *)jop, jname,
jvp ? jvp : json_null_new());
}
}
- if (jvp && ((as_json && jsp->pr_output) || (! as_json))) {
+ if (jvp && ((as_json && jsp->pr_out_hr) || (! as_json))) {
switch (sep) {
case SGJ_SEP_NONE:
break;
@@ -894,8 +948,8 @@ sgj_pr_hr_js_xx(sgj_state * jsp, sgj_opaque_p jop, int leadin_sp,
break;
}
}
- if (as_json && jsp->pr_output)
- json_array_push((json_value *)jsp->outputp, json_string_new(b));
+ if (as_json && jsp->pr_out_hr)
+ json_array_push((json_value *)jsp->out_hrp, json_string_new(b));
else if (! as_json)
printf("%s\n", b);
if (jvp && (! eaten))
@@ -1292,7 +1346,7 @@ sgj_uds_referral_descriptor(sgj_state * jsp, sgj_opaque_p jop,
"Not all referrals");
dp += 4;
jap = sgj_new_named_array(jsp, jop,
- "user_data_segment_referral_descriptor");
+ "user_data_segment_referral_descriptor_list");
for (k = 0, f = 1; (k + 4) < dlen; k += g, dp += g, ++f) {
int ntpgd = dp[3];
@@ -1309,7 +1363,8 @@ sgj_uds_referral_descriptor(sgj_state * jsp, sgj_opaque_p jop,
sgj_add_nv_ihex(jsp, jo2p, "first_user_date_sgment_lba", ull);
ull = sg_get_unaligned_be64(dp + 12);
sgj_add_nv_ihex(jsp, jo2p, "last_user_date_sgment_lba", ull);
- ja2p = sgj_new_named_array(jsp, jo2p, "target_port_group_descriptor");
+ ja2p = sgj_new_named_array(jsp, jo2p,
+ "target_port_group_descriptor_list");
for (j = 0; j < ntpgd; ++j) {
jo3p = sgj_new_unattached_object(jsp);
tp = dp + 20 + (j * 4);
@@ -1358,7 +1413,7 @@ sgj_get_sense_descriptors(sgj_state * jsp, sgj_opaque_p jop,
add_sb_len = sshp->additional_length;
add_sb_len = (add_sb_len < sb_len) ? add_sb_len : sb_len;
sense_key = sshp->sense_key;
- jap = sgj_new_named_array(jsp, jop, "sense_data_descriptor");
+ jap = sgj_new_named_array(jsp, jop, "sense_data_descriptor_list");
for (descp = sbp, k = 0; (k < add_sb_len);
k += desc_len, descp += desc_len) {