diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2022-04-21 02:37:15 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2022-04-21 02:37:15 +0000 |
commit | 8cd2200ba1758cd127a1b95ab1808cde4f56713c (patch) | |
tree | 81f7e8e9c995548351865b77c13092ebf40d7174 /lib | |
parent | f26bb872bf4f043a1b817c808a6947fcb03ecda4 (diff) | |
download | sg3_utils-8cd2200ba1758cd127a1b95ab1808cde4f56713c.tar.gz |
sg_opcodes: add --inhex=FN to process earlier -HHH, add experimental --json[=JO] option; sg_turs: change nanosleep() to Sleep() in MinGW
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@945 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile.am | 1 | ||||
-rw-r--r-- | lib/Makefile.in | 46 | ||||
-rw-r--r-- | lib/sg_json_builder.c | 4 | ||||
-rw-r--r-- | lib/sg_json_builder.h | 17 | ||||
-rw-r--r-- | lib/sg_lib.c | 14 | ||||
-rw-r--r-- | lib/sg_pr2serr.c | 242 |
6 files changed, 285 insertions, 39 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am index b481816d..77e56408 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -1,5 +1,6 @@ libsgutils2_la_SOURCES = \ sg_lib.c \ + sg_pr2serr.c \ sg_lib_data.c \ sg_lib_names.c \ sg_cmds_basic.c \ diff --git a/lib/Makefile.in b/lib/Makefile.in index 1a6dbeee..64cf1d08 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -144,7 +144,7 @@ am__uninstall_files_from_dir = { \ } am__installdirs = "$(DESTDIR)$(libdir)" LTLIBRARIES = $(lib_LTLIBRARIES) -am__libsgutils2_la_SOURCES_DIST = sg_lib.c sg_lib_data.c \ +am__libsgutils2_la_SOURCES_DIST = sg_lib.c sg_pr2serr.c sg_lib_data.c \ sg_lib_names.c sg_cmds_basic.c sg_cmds_basic2.c \ sg_cmds_extra.c sg_cmds_mmc.c sg_pt_common.c sg_json_builder.c \ sg_pt_dummy.c sg_pt_linux.c sg_io_linux.c sg_pt_linux_nvme.c \ @@ -165,14 +165,14 @@ am__libsgutils2_la_SOURCES_DIST = sg_lib.c sg_lib_data.c \ @OS_NETBSD_TRUE@am__objects_11 = sg_pt_dummy.lo @OS_OPENBSD_TRUE@am__objects_12 = sg_pt_dummy.lo @OS_OTHER_TRUE@am__objects_13 = sg_pt_dummy.lo -am_libsgutils2_la_OBJECTS = sg_lib.lo sg_lib_data.lo sg_lib_names.lo \ - sg_cmds_basic.lo sg_cmds_basic2.lo sg_cmds_extra.lo \ - sg_cmds_mmc.lo sg_pt_common.lo sg_json_builder.lo \ - $(am__objects_1) $(am__objects_2) $(am__objects_3) \ - $(am__objects_4) $(am__objects_5) $(am__objects_6) \ - $(am__objects_7) $(am__objects_8) $(am__objects_9) \ - $(am__objects_10) $(am__objects_11) $(am__objects_12) \ - $(am__objects_13) +am_libsgutils2_la_OBJECTS = sg_lib.lo sg_pr2serr.lo sg_lib_data.lo \ + sg_lib_names.lo sg_cmds_basic.lo sg_cmds_basic2.lo \ + sg_cmds_extra.lo sg_cmds_mmc.lo sg_pt_common.lo \ + sg_json_builder.lo $(am__objects_1) $(am__objects_2) \ + $(am__objects_3) $(am__objects_4) $(am__objects_5) \ + $(am__objects_6) $(am__objects_7) $(am__objects_8) \ + $(am__objects_9) $(am__objects_10) $(am__objects_11) \ + $(am__objects_12) $(am__objects_13) libsgutils2_la_OBJECTS = $(am_libsgutils2_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -202,11 +202,11 @@ am__depfiles_remade = ./$(DEPDIR)/sg_cmds_basic.Plo \ ./$(DEPDIR)/sg_cmds_mmc.Plo ./$(DEPDIR)/sg_io_linux.Plo \ ./$(DEPDIR)/sg_json_builder.Plo ./$(DEPDIR)/sg_lib.Plo \ ./$(DEPDIR)/sg_lib_data.Plo ./$(DEPDIR)/sg_lib_names.Plo \ - ./$(DEPDIR)/sg_pt_common.Plo ./$(DEPDIR)/sg_pt_dummy.Plo \ - ./$(DEPDIR)/sg_pt_freebsd.Plo ./$(DEPDIR)/sg_pt_haiku.Plo \ - ./$(DEPDIR)/sg_pt_linux.Plo ./$(DEPDIR)/sg_pt_linux_nvme.Plo \ - ./$(DEPDIR)/sg_pt_osf1.Plo ./$(DEPDIR)/sg_pt_solaris.Plo \ - ./$(DEPDIR)/sg_pt_win32.Plo + ./$(DEPDIR)/sg_pr2serr.Plo ./$(DEPDIR)/sg_pt_common.Plo \ + ./$(DEPDIR)/sg_pt_dummy.Plo ./$(DEPDIR)/sg_pt_freebsd.Plo \ + ./$(DEPDIR)/sg_pt_haiku.Plo ./$(DEPDIR)/sg_pt_linux.Plo \ + ./$(DEPDIR)/sg_pt_linux_nvme.Plo ./$(DEPDIR)/sg_pt_osf1.Plo \ + ./$(DEPDIR)/sg_pt_solaris.Plo ./$(DEPDIR)/sg_pt_win32.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -377,13 +377,14 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -libsgutils2_la_SOURCES = sg_lib.c sg_lib_data.c sg_lib_names.c \ - sg_cmds_basic.c sg_cmds_basic2.c sg_cmds_extra.c sg_cmds_mmc.c \ - sg_pt_common.c sg_json_builder.c $(am__append_1) \ - $(am__append_2) $(am__append_3) $(am__append_4) \ - $(am__append_5) $(am__append_6) $(am__append_7) \ - $(am__append_8) $(am__append_9) $(am__append_10) \ - $(am__append_11) $(am__append_12) $(am__append_13) +libsgutils2_la_SOURCES = sg_lib.c sg_pr2serr.c sg_lib_data.c \ + sg_lib_names.c sg_cmds_basic.c sg_cmds_basic2.c \ + sg_cmds_extra.c sg_cmds_mmc.c sg_pt_common.c sg_json_builder.c \ + $(am__append_1) $(am__append_2) $(am__append_3) \ + $(am__append_4) $(am__append_5) $(am__append_6) \ + $(am__append_7) $(am__append_8) $(am__append_9) \ + $(am__append_10) $(am__append_11) $(am__append_12) \ + $(am__append_13) @DEBUG_FALSE@DBG_CFLAGS = # This is active if --enable-debug given to ./configure @@ -496,6 +497,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_lib.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_lib_data.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_lib_names.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pr2serr.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_common.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_dummy.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_freebsd.Plo@am__quote@ # am--include-marker @@ -675,6 +677,7 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/sg_lib.Plo -rm -f ./$(DEPDIR)/sg_lib_data.Plo -rm -f ./$(DEPDIR)/sg_lib_names.Plo + -rm -f ./$(DEPDIR)/sg_pr2serr.Plo -rm -f ./$(DEPDIR)/sg_pt_common.Plo -rm -f ./$(DEPDIR)/sg_pt_dummy.Plo -rm -f ./$(DEPDIR)/sg_pt_freebsd.Plo @@ -738,6 +741,7 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/sg_lib.Plo -rm -f ./$(DEPDIR)/sg_lib_data.Plo -rm -f ./$(DEPDIR)/sg_lib_names.Plo + -rm -f ./$(DEPDIR)/sg_pr2serr.Plo -rm -f ./$(DEPDIR)/sg_pt_common.Plo -rm -f ./$(DEPDIR)/sg_pt_dummy.Plo -rm -f ./$(DEPDIR)/sg_pt_freebsd.Plo diff --git a/lib/sg_json_builder.c b/lib/sg_json_builder.c index 4d616989..ed2d1397 100644 --- a/lib/sg_json_builder.c +++ b/lib/sg_json_builder.c @@ -35,6 +35,10 @@ #include <stdlib.h> #include <stdio.h> +/* This code was fetched from https://github.com/json-parser/json-builder + * and comes with the 2 clause BSD license (shown above) which is the same + * license that most of the rest of this package uses. */ + #ifdef _MSC_VER #define snprintf _snprintf #endif diff --git a/lib/sg_json_builder.h b/lib/sg_json_builder.h index 9d83b026..9027ed5b 100644 --- a/lib/sg_json_builder.h +++ b/lib/sg_json_builder.h @@ -28,11 +28,20 @@ * SUCH DAMAGE. */ -#ifndef _JSON_BUILDER_H -#define _JSON_BUILDER_H +#ifndef SG_JSON_BUILDER_H +#define SG_JSON_BUILDER_H + +/* This code was fetched from https://github.com/json-parser/json-builder + * and comes with the 2 clause BSD license (shown above) which is the same + * license that most of the rest of this package uses. + * + * This header file is in this 'lib' directory so its interface is _not_ + * published with sg3_utils other header files found in the 'include' + * directory. Currently only this header's implementation (i.e. + * sg_json_builder.c) and sg_pr2serr.c are the only users of this header. */ /* - * Used to require json.h from json-parser but what was need as been + * Used to require json.h from json-parser but what was needed as been * included in this header. * https://github.com/udp/json-parser */ @@ -318,7 +327,7 @@ void json_builder_free (json_value *); } #endif -#endif +#endif /* SG_JSON_BUILDER_H */ diff --git a/lib/sg_lib.c b/lib/sg_lib.c index 36af6e6f..86fd37dc 100644 --- a/lib/sg_lib.c +++ b/lib/sg_lib.c @@ -75,20 +75,6 @@ pr2ws(const char * fmt, ...) return n; } -/* Users of the sg_pr2serr.h header need this function definition */ -int -pr2serr(const char * fmt, ...) -{ - va_list args; - int n; - - va_start(args, fmt); - n = vfprintf(stderr, fmt, args); - va_end(args); - return n; -} - - /* Want safe, 'n += snprintf(b + n, blen - n, ...)' style sequence of * functions. Returns number of chars placed in cp excluding the * trailing null char. So for cp_max_len > 0 the return value is always diff --git a/lib/sg_pr2serr.c b/lib/sg_pr2serr.c new file mode 100644 index 00000000..5bb87acf --- /dev/null +++ b/lib/sg_pr2serr.c @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2022 Douglas Gilbert. + * All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the BSD_LICENSE file. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <stdbool.h> +#include <string.h> + +#include "sg_pr2serr.h" +#include "sg_json_builder.h" + +/* + * #define json_serialize_mode_multiline 0 + * #define json_serialize_mode_single_line 1 + * #define json_serialize_mode_packed 2 + * + * #define json_serialize_opt_CRLF (1 << 1) + * #define json_serialize_opt_pack_brackets (1 << 2) + * #define json_serialize_opt_no_space_after_comma (1 << 3) + * #define json_serialize_opt_no_space_after_colon (1 << 4) + * #define json_serialize_opt_use_tabs (1 << 5) + */ + + +static const json_serialize_opts def_out_settings = { + json_serialize_mode_multiline, /* one of serialize_mode_* */ + 0, /* serialize_opt_* OR-ed together */ + 4 /* indent size */ +}; + +/* Users of the sg_pr2serr.h header need this function definition */ +int +pr2serr(const char * fmt, ...) +{ + va_list args; + int n; + + va_start(args, fmt); + n = vfprintf(stderr, fmt, args); + va_end(args); + return n; +} + +void +sg_json_init_state(sg_json_state * jstp) +{ + jstp->pr_as_json = true; + jstp->pr_pretty = true; + jstp->pr_sorted = false; + jstp->pr_output = false; + jstp->pr_implemented = false; + jstp->pr_unimplemented = false; + jstp->pr_format = 0; + jstp->verbose = 0; + jstp->pr_indent_size = 4; + jstp->basep = NULL; + jstp->outputp = NULL; + jstp->userp = NULL; +} + +sg_json_opaque_p +sg_json_start(const char * util_name, const char * ver_str, int argc, + char *argv[], sg_json_state * jstp) +{ + int k; + json_value * jvp = json_object_new(0); + json_value * jv2p; + json_value * jap = json_array_new(0); + + if ((NULL == jvp) || (NULL == jap)) { + if (jvp) + json_builder_free(jvp); + if (jap) + json_builder_free(jap); + return NULL; + } + jstp->basep = jvp; + json_array_push(jap, json_integer_new(1)); + json_array_push(jap, json_integer_new(0)); + json_object_push(jvp, "json_format_version", jap); + jap = json_array_new(0); + for (k = 0; k < argc; ++k) + json_array_push(jap, json_string_new(argv[k])); + jv2p = json_object_push(jvp, util_name, json_object_new(0)); + if (ver_str) + json_object_push(jv2p, "version_date", json_string_new(ver_str)); + else + json_object_push(jv2p, "version_date", json_string_new("0.0")); + json_object_push(jv2p, "argv", jap); + if (jstp->pr_output) + jstp->outputp = json_object_push(jv2p, "output", json_array_new(0)); + return jvp; +} + +void +sgj_pr2file(sg_json_opaque_p jop, sg_json_state * jstp, FILE * fp) +{ + size_t len; + char * b; + json_value * jvp = (json_value *)jop; + json_serialize_opts out_settings; + + memcpy(&out_settings, &def_out_settings, sizeof(out_settings)); + if (jstp->pr_indent_size != def_out_settings.indent_size) + out_settings.indent_size = jstp->pr_indent_size; + if (! jstp->pr_pretty) + out_settings.mode = json_serialize_mode_single_line; + + len = json_measure_ex(jvp, out_settings); + if (len < 1) + return; + if (jstp->verbose > 3) + fprintf(fp, "%s: serialization length: %zu bytes\n", __func__, len); + b = calloc(len, 1); + if (NULL == b) { + if (jstp->verbose > 3) + pr2serr("%s: unable to get %zu bytes on heap\n", __func__, len); + return; + } + json_serialize_ex(b, jvp, out_settings); + if (jstp->verbose > 3) + fprintf(fp, "json serialized:\n"); + fprintf(fp, "%s\n", b); +} + +void +sg_json_free(sg_json_opaque_p jop) +{ + json_value * jvp = (json_value *)jop; + + json_builder_free(jvp); +} + +void +sgj_pr_hr(sg_json_state * jsp, const char * fmt, ...) +{ + va_list args; + + if (jsp->pr_as_json && jsp->pr_output) { + size_t len; + char b[256]; + + va_start(args, fmt); + len = vsnprintf(b, sizeof(b), fmt, args); + if ((len > 0) && (len < sizeof(b))) { + const char * cp = b; + + if (b[len - 1] == '\n') { + b[len - 1] = '\0'; + --len; + } + if ((len > 0) && ('\n' == b[0])) + ++cp; + json_array_push(jsp->outputp, json_string_new(cp)); + } + va_end(args); + } else if (jsp->pr_as_json) { + va_start(args, fmt); + va_end(args); + } else { + va_start(args, fmt); + vfprintf(stdout, fmt, args); + va_end(args); + } +} + +sg_json_opaque_p +sgj_new_named_object(sg_json_state * jsp, sg_json_opaque_p jop, + const char * name) +{ + sg_json_opaque_p resp = NULL; + + if (jsp->pr_as_json) + resp = json_object_push(jop, name, json_object_new(0)); + return resp; +} + +sg_json_opaque_p +sgj_new_named_array(sg_json_state * jsp, sg_json_opaque_p jop, + const char * name) +{ + sg_json_opaque_p resp = NULL; + + if (jsp->pr_as_json) + resp = json_object_push(jop, name, json_array_new(0)); + return resp; +} + +sg_json_opaque_p +sgj_add_array_element(sg_json_state * jsp, sg_json_opaque_p jap, + sg_json_opaque_p ejop) +{ + if (jsp->pr_as_json) + return json_array_push(jap, ejop); + else + return NULL; +} + +/* Newly created object is un-attached */ +sg_json_opaque_p +sgj_new_object(sg_json_state * jsp) +{ + return jsp->pr_as_json ? json_object_new(0) : NULL; +} + +sg_json_opaque_p +sgj_add_name_vs(sg_json_state * jsp, sg_json_opaque_p jop, const char * name, + const char * value) +{ + if (jsp->pr_as_json) + return json_object_push(jop, name, json_string_new(value)); + else + return NULL; +} + +sg_json_opaque_p +sgj_add_name_vi(sg_json_state * jsp, sg_json_opaque_p jop, const char * name, + int64_t value) +{ + if (jsp->pr_as_json) + return json_object_push(jop, name, json_integer_new(value)); + else + return NULL; +} + +sg_json_opaque_p +sgj_add_name_vb(sg_json_state * jsp, sg_json_opaque_p jop, const char * name, + bool value) +{ + if (jsp->pr_as_json) + return json_object_push(jop, name, json_boolean_new(value)); + else + return NULL; +} |