diff --git a/lib/Makefile.am b/lib/Makefile.am index 71076ce3..b3b5272a 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -62,6 +62,7 @@ pkginclude_HEADERS = \ hawk-gem.h \ hawk-glob.h \ hawk-htb.h \ + hawk-json.h \ hawk-map.h \ hawk-mtx.h \ hawk-rbt.h \ @@ -99,14 +100,15 @@ libhawk_la_SOURCES = \ fmt.c \ fnc-prv.h \ fnc.c \ - htb.c \ gem.c \ gem-glob.c \ gem-nwif.c \ gem-nwif2.c \ hawk-prv.h \ hawk.c \ + htb.c \ idmap-imp.h \ + json.c \ mb8.c \ misc-imp.h \ misc-prv.h \ @@ -166,6 +168,7 @@ libhawk_la_SOURCES += \ syscall.h \ tio.c \ std.c \ + std-json.c \ std-sed.c libhawk_la_CPPFLAGS = $(CPPFLAGS_ALL_COMMON) $(CPPFLAGS_PFMOD) diff --git a/lib/Makefile.in b/lib/Makefile.in index 6994e023..f311fc6d 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -232,25 +232,25 @@ libhawk_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__append_15) am__libhawk_la_SOURCES_DIST = hawk.h hawk-arr.h hawk-chr.h hawk-cli.h \ hawk-cmn.h hawk-dir.h hawk-ecs.h hawk-fio.h hawk-fmt.h \ - hawk-gem.h hawk-glob.h hawk-htb.h hawk-map.h hawk-mtx.h \ - hawk-rbt.h hawk-pac1.h hawk-pio.h hawk-skad.h hawk-utl.h \ - hawk-sed.h hawk-sio.h hawk-std.h hawk-str.h hawk-tio.h \ - hawk-tre.h hawk-upac.h hawk-xma.h Hawk.hpp Hawk-Sed.hpp arr.c \ - chr.c dir.c ecs-imp.h ecs.c err-prv.h err.c err-sys.c \ - fmt-imp.h fmt.c fnc-prv.h fnc.c htb.c gem.c gem-glob.c \ - gem-nwif.c gem-nwif2.c hawk-prv.h hawk.c idmap-imp.h mb8.c \ - misc-imp.h misc-prv.h misc.c parse-prv.h parse.c rbt.c rec.c \ - rio-prv.h rio.c run-prv.h run.c sed-prv.h sed.c skad-prv.h \ - skad.c tre-prv.h tre-ast.c tre-ast.h tre-compile.c \ + hawk-gem.h hawk-glob.h hawk-htb.h hawk-json.h hawk-map.h \ + hawk-mtx.h hawk-rbt.h hawk-pac1.h hawk-pio.h hawk-skad.h \ + hawk-utl.h hawk-sed.h hawk-sio.h hawk-std.h hawk-str.h \ + hawk-tio.h hawk-tre.h hawk-upac.h hawk-xma.h Hawk.hpp \ + Hawk-Sed.hpp arr.c chr.c dir.c ecs-imp.h ecs.c err-prv.h err.c \ + err-sys.c fmt-imp.h fmt.c fnc-prv.h fnc.c gem.c gem-glob.c \ + gem-nwif.c gem-nwif2.c hawk-prv.h hawk.c htb.c idmap-imp.h \ + json.c mb8.c misc-imp.h misc-prv.h misc.c parse-prv.h parse.c \ + rbt.c rec.c rio-prv.h rio.c run-prv.h run.c sed-prv.h sed.c \ + skad-prv.h skad.c tre-prv.h tre-ast.c tre-ast.h tre-compile.c \ tre-compile.h tre-match-bt.c tre-match-pa.c tre-match-ut.h \ tre-mem.c tre-mem.h tre-parse.c tre-parse.h tre-stack.h \ tre-stack.c tre.c tree-prv.h tree.c uch-prop.h uch-case.h \ utf16.c utf8.c utl-ass.c utl-cmgr.c utl-rnd.c utl-sort.c \ utl-str.c utl-sys.c utl-xstr.c utl.c val-prv.h val.c xma.c \ cli-imp.h cli.c fio.c mtx.c pio.c sio.c syscall.h tio.c std.c \ - std-sed.c Hawk.cpp Std.cpp Sed.cpp Std-Sed.cpp mod-hawk.c \ - mod-hawk.h mod-math.c mod-math.h mod-str.c mod-str.h mod-sys.c \ - mod-sys.h + std-json.c std-sed.c Hawk.cpp Std.cpp Sed.cpp Std-Sed.cpp \ + mod-hawk.c mod-hawk.h mod-math.c mod-math.h mod-str.c \ + mod-str.h mod-sys.c mod-sys.h am__objects_1 = am__objects_2 = $(am__objects_1) @ENABLE_CXX_TRUE@am__objects_3 = libhawk_la-Hawk.lo libhawk_la-Std.lo \ @@ -262,24 +262,25 @@ am__objects_2 = $(am__objects_1) am_libhawk_la_OBJECTS = $(am__objects_2) libhawk_la-arr.lo \ libhawk_la-chr.lo libhawk_la-dir.lo libhawk_la-ecs.lo \ libhawk_la-err.lo libhawk_la-err-sys.lo libhawk_la-fmt.lo \ - libhawk_la-fnc.lo libhawk_la-htb.lo libhawk_la-gem.lo \ - libhawk_la-gem-glob.lo libhawk_la-gem-nwif.lo \ - libhawk_la-gem-nwif2.lo libhawk_la-hawk.lo libhawk_la-mb8.lo \ - libhawk_la-misc.lo libhawk_la-parse.lo libhawk_la-rbt.lo \ - libhawk_la-rec.lo libhawk_la-rio.lo libhawk_la-run.lo \ - libhawk_la-sed.lo libhawk_la-skad.lo libhawk_la-tre-ast.lo \ - libhawk_la-tre-compile.lo libhawk_la-tre-match-bt.lo \ - libhawk_la-tre-match-pa.lo libhawk_la-tre-mem.lo \ - libhawk_la-tre-parse.lo libhawk_la-tre-stack.lo \ - libhawk_la-tre.lo libhawk_la-tree.lo libhawk_la-utf16.lo \ - libhawk_la-utf8.lo libhawk_la-utl-ass.lo \ + libhawk_la-fnc.lo libhawk_la-gem.lo libhawk_la-gem-glob.lo \ + libhawk_la-gem-nwif.lo libhawk_la-gem-nwif2.lo \ + libhawk_la-hawk.lo libhawk_la-htb.lo libhawk_la-json.lo \ + libhawk_la-mb8.lo libhawk_la-misc.lo libhawk_la-parse.lo \ + libhawk_la-rbt.lo libhawk_la-rec.lo libhawk_la-rio.lo \ + libhawk_la-run.lo libhawk_la-sed.lo libhawk_la-skad.lo \ + libhawk_la-tre-ast.lo libhawk_la-tre-compile.lo \ + libhawk_la-tre-match-bt.lo libhawk_la-tre-match-pa.lo \ + libhawk_la-tre-mem.lo libhawk_la-tre-parse.lo \ + libhawk_la-tre-stack.lo libhawk_la-tre.lo libhawk_la-tree.lo \ + libhawk_la-utf16.lo libhawk_la-utf8.lo libhawk_la-utl-ass.lo \ libhawk_la-utl-cmgr.lo libhawk_la-utl-rnd.lo \ libhawk_la-utl-sort.lo libhawk_la-utl-str.lo \ libhawk_la-utl-sys.lo libhawk_la-utl-xstr.lo libhawk_la-utl.lo \ libhawk_la-val.lo libhawk_la-xma.lo libhawk_la-cli.lo \ libhawk_la-fio.lo libhawk_la-mtx.lo libhawk_la-pio.lo \ libhawk_la-sio.lo libhawk_la-tio.lo libhawk_la-std.lo \ - libhawk_la-std-sed.lo $(am__objects_3) $(am__objects_4) + libhawk_la-std-json.lo libhawk_la-std-sed.lo $(am__objects_3) \ + $(am__objects_4) libhawk_la_OBJECTS = $(am_libhawk_la_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) @@ -309,8 +310,8 @@ am__depfiles_remade = ./$(DEPDIR)/libhawk_hawk_la-mod-hawk.Plo \ ./$(DEPDIR)/libhawk_la-gem-nwif.Plo \ ./$(DEPDIR)/libhawk_la-gem-nwif2.Plo \ ./$(DEPDIR)/libhawk_la-gem.Plo ./$(DEPDIR)/libhawk_la-hawk.Plo \ - ./$(DEPDIR)/libhawk_la-htb.Plo ./$(DEPDIR)/libhawk_la-mb8.Plo \ - ./$(DEPDIR)/libhawk_la-misc.Plo \ + ./$(DEPDIR)/libhawk_la-htb.Plo ./$(DEPDIR)/libhawk_la-json.Plo \ + ./$(DEPDIR)/libhawk_la-mb8.Plo ./$(DEPDIR)/libhawk_la-misc.Plo \ ./$(DEPDIR)/libhawk_la-mod-hawk.Plo \ ./$(DEPDIR)/libhawk_la-mod-math.Plo \ ./$(DEPDIR)/libhawk_la-mod-str.Plo \ @@ -321,6 +322,7 @@ am__depfiles_remade = ./$(DEPDIR)/libhawk_hawk_la-mod-hawk.Plo \ ./$(DEPDIR)/libhawk_la-rec.Plo ./$(DEPDIR)/libhawk_la-rio.Plo \ ./$(DEPDIR)/libhawk_la-run.Plo ./$(DEPDIR)/libhawk_la-sed.Plo \ ./$(DEPDIR)/libhawk_la-sio.Plo ./$(DEPDIR)/libhawk_la-skad.Plo \ + ./$(DEPDIR)/libhawk_la-std-json.Plo \ ./$(DEPDIR)/libhawk_la-std-sed.Plo \ ./$(DEPDIR)/libhawk_la-std.Plo ./$(DEPDIR)/libhawk_la-tio.Plo \ ./$(DEPDIR)/libhawk_la-tre-ast.Plo \ @@ -397,10 +399,11 @@ am__can_run_installinfo = \ esac am__pkginclude_HEADERS_DIST = hawk.h hawk-arr.h hawk-chr.h hawk-cli.h \ hawk-cmn.h hawk-dir.h hawk-ecs.h hawk-fio.h hawk-fmt.h \ - hawk-gem.h hawk-glob.h hawk-htb.h hawk-map.h hawk-mtx.h \ - hawk-rbt.h hawk-pac1.h hawk-pio.h hawk-skad.h hawk-utl.h \ - hawk-sed.h hawk-sio.h hawk-std.h hawk-str.h hawk-tio.h \ - hawk-tre.h hawk-upac.h hawk-xma.h Hawk.hpp Hawk-Sed.hpp + hawk-gem.h hawk-glob.h hawk-htb.h hawk-json.h hawk-map.h \ + hawk-mtx.h hawk-rbt.h hawk-pac1.h hawk-pio.h hawk-skad.h \ + hawk-utl.h hawk-sed.h hawk-sio.h hawk-std.h hawk-str.h \ + hawk-tio.h hawk-tre.h hawk-upac.h hawk-xma.h Hawk.hpp \ + Hawk-Sed.hpp HEADERS = $(pkginclude_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ hawk-cfg.h.in @@ -625,24 +628,24 @@ BUILT_SOURCES = \ pkginclude_HEADERS = hawk.h hawk-arr.h hawk-chr.h hawk-cli.h \ hawk-cmn.h hawk-dir.h hawk-ecs.h hawk-fio.h hawk-fmt.h \ - hawk-gem.h hawk-glob.h hawk-htb.h hawk-map.h hawk-mtx.h \ - hawk-rbt.h hawk-pac1.h hawk-pio.h hawk-skad.h hawk-utl.h \ - hawk-sed.h hawk-sio.h hawk-std.h hawk-str.h hawk-tio.h \ - hawk-tre.h hawk-upac.h hawk-xma.h $(am__append_7) + hawk-gem.h hawk-glob.h hawk-htb.h hawk-json.h hawk-map.h \ + hawk-mtx.h hawk-rbt.h hawk-pac1.h hawk-pio.h hawk-skad.h \ + hawk-utl.h hawk-sed.h hawk-sio.h hawk-std.h hawk-str.h \ + hawk-tio.h hawk-tre.h hawk-upac.h hawk-xma.h $(am__append_7) pkglib_LTLIBRARIES = libhawk.la $(am__append_16) libhawk_la_SOURCES = $(pkginclude_HEADERS) arr.c chr.c dir.c ecs-imp.h \ ecs.c err-prv.h err.c err-sys.c fmt-imp.h fmt.c fnc-prv.h \ - fnc.c htb.c gem.c gem-glob.c gem-nwif.c gem-nwif2.c hawk-prv.h \ - hawk.c idmap-imp.h mb8.c misc-imp.h misc-prv.h misc.c \ - parse-prv.h parse.c rbt.c rec.c rio-prv.h rio.c run-prv.h \ - run.c sed-prv.h sed.c skad-prv.h skad.c tre-prv.h tre-ast.c \ - tre-ast.h tre-compile.c tre-compile.h tre-match-bt.c \ + fnc.c gem.c gem-glob.c gem-nwif.c gem-nwif2.c hawk-prv.h \ + hawk.c htb.c idmap-imp.h json.c mb8.c misc-imp.h misc-prv.h \ + misc.c parse-prv.h parse.c rbt.c rec.c rio-prv.h rio.c \ + run-prv.h run.c sed-prv.h sed.c skad-prv.h skad.c tre-prv.h \ + tre-ast.c tre-ast.h tre-compile.c tre-compile.h tre-match-bt.c \ tre-match-pa.c tre-match-ut.h tre-mem.c tre-mem.h tre-parse.c \ tre-parse.h tre-stack.h tre-stack.c tre.c tree-prv.h tree.c \ uch-prop.h uch-case.h utf16.c utf8.c utl-ass.c utl-cmgr.c \ utl-rnd.c utl-sort.c utl-str.c utl-sys.c utl-xstr.c utl.c \ val-prv.h val.c xma.c cli-imp.h cli.c fio.c mtx.c pio.c sio.c \ - syscall.h tio.c std.c std-sed.c $(am__append_8) \ + syscall.h tio.c std.c std-json.c std-sed.c $(am__append_8) \ $(am__append_9) libhawk_la_CPPFLAGS = $(CPPFLAGS_ALL_COMMON) $(CPPFLAGS_PFMOD) \ $(am__append_3) @@ -823,6 +826,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_la-gem.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_la-hawk.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_la-htb.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_la-json.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_la-mb8.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_la-misc.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_la-mod-hawk.Plo@am__quote@ # am--include-marker @@ -839,6 +843,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_la-sed.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_la-sio.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_la-skad.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_la-std-json.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_la-std-sed.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_la-std.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_la-tio.Plo@am__quote@ # am--include-marker @@ -981,13 +986,6 @@ libhawk_la-fnc.lo: fnc.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhawk_la_CPPFLAGS) $(CPPFLAGS) $(libhawk_la_CFLAGS) $(CFLAGS) -c -o libhawk_la-fnc.lo `test -f 'fnc.c' || echo '$(srcdir)/'`fnc.c -libhawk_la-htb.lo: htb.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhawk_la_CPPFLAGS) $(CPPFLAGS) $(libhawk_la_CFLAGS) $(CFLAGS) -MT libhawk_la-htb.lo -MD -MP -MF $(DEPDIR)/libhawk_la-htb.Tpo -c -o libhawk_la-htb.lo `test -f 'htb.c' || echo '$(srcdir)/'`htb.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhawk_la-htb.Tpo $(DEPDIR)/libhawk_la-htb.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='htb.c' object='libhawk_la-htb.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhawk_la_CPPFLAGS) $(CPPFLAGS) $(libhawk_la_CFLAGS) $(CFLAGS) -c -o libhawk_la-htb.lo `test -f 'htb.c' || echo '$(srcdir)/'`htb.c - libhawk_la-gem.lo: gem.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhawk_la_CPPFLAGS) $(CPPFLAGS) $(libhawk_la_CFLAGS) $(CFLAGS) -MT libhawk_la-gem.lo -MD -MP -MF $(DEPDIR)/libhawk_la-gem.Tpo -c -o libhawk_la-gem.lo `test -f 'gem.c' || echo '$(srcdir)/'`gem.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhawk_la-gem.Tpo $(DEPDIR)/libhawk_la-gem.Plo @@ -1023,6 +1021,20 @@ libhawk_la-hawk.lo: hawk.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhawk_la_CPPFLAGS) $(CPPFLAGS) $(libhawk_la_CFLAGS) $(CFLAGS) -c -o libhawk_la-hawk.lo `test -f 'hawk.c' || echo '$(srcdir)/'`hawk.c +libhawk_la-htb.lo: htb.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhawk_la_CPPFLAGS) $(CPPFLAGS) $(libhawk_la_CFLAGS) $(CFLAGS) -MT libhawk_la-htb.lo -MD -MP -MF $(DEPDIR)/libhawk_la-htb.Tpo -c -o libhawk_la-htb.lo `test -f 'htb.c' || echo '$(srcdir)/'`htb.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhawk_la-htb.Tpo $(DEPDIR)/libhawk_la-htb.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='htb.c' object='libhawk_la-htb.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhawk_la_CPPFLAGS) $(CPPFLAGS) $(libhawk_la_CFLAGS) $(CFLAGS) -c -o libhawk_la-htb.lo `test -f 'htb.c' || echo '$(srcdir)/'`htb.c + +libhawk_la-json.lo: json.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhawk_la_CPPFLAGS) $(CPPFLAGS) $(libhawk_la_CFLAGS) $(CFLAGS) -MT libhawk_la-json.lo -MD -MP -MF $(DEPDIR)/libhawk_la-json.Tpo -c -o libhawk_la-json.lo `test -f 'json.c' || echo '$(srcdir)/'`json.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhawk_la-json.Tpo $(DEPDIR)/libhawk_la-json.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='json.c' object='libhawk_la-json.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhawk_la_CPPFLAGS) $(CPPFLAGS) $(libhawk_la_CFLAGS) $(CFLAGS) -c -o libhawk_la-json.lo `test -f 'json.c' || echo '$(srcdir)/'`json.c + libhawk_la-mb8.lo: mb8.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhawk_la_CPPFLAGS) $(CPPFLAGS) $(libhawk_la_CFLAGS) $(CFLAGS) -MT libhawk_la-mb8.lo -MD -MP -MF $(DEPDIR)/libhawk_la-mb8.Tpo -c -o libhawk_la-mb8.lo `test -f 'mb8.c' || echo '$(srcdir)/'`mb8.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhawk_la-mb8.Tpo $(DEPDIR)/libhawk_la-mb8.Plo @@ -1282,6 +1294,13 @@ libhawk_la-std.lo: std.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhawk_la_CPPFLAGS) $(CPPFLAGS) $(libhawk_la_CFLAGS) $(CFLAGS) -c -o libhawk_la-std.lo `test -f 'std.c' || echo '$(srcdir)/'`std.c +libhawk_la-std-json.lo: std-json.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhawk_la_CPPFLAGS) $(CPPFLAGS) $(libhawk_la_CFLAGS) $(CFLAGS) -MT libhawk_la-std-json.lo -MD -MP -MF $(DEPDIR)/libhawk_la-std-json.Tpo -c -o libhawk_la-std-json.lo `test -f 'std-json.c' || echo '$(srcdir)/'`std-json.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhawk_la-std-json.Tpo $(DEPDIR)/libhawk_la-std-json.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='std-json.c' object='libhawk_la-std-json.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhawk_la_CPPFLAGS) $(CPPFLAGS) $(libhawk_la_CFLAGS) $(CFLAGS) -c -o libhawk_la-std-json.lo `test -f 'std-json.c' || echo '$(srcdir)/'`std-json.c + libhawk_la-std-sed.lo: std-sed.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhawk_la_CPPFLAGS) $(CPPFLAGS) $(libhawk_la_CFLAGS) $(CFLAGS) -MT libhawk_la-std-sed.lo -MD -MP -MF $(DEPDIR)/libhawk_la-std-sed.Tpo -c -o libhawk_la-std-sed.lo `test -f 'std-sed.c' || echo '$(srcdir)/'`std-sed.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhawk_la-std-sed.Tpo $(DEPDIR)/libhawk_la-std-sed.Plo @@ -1548,6 +1567,7 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/libhawk_la-gem.Plo -rm -f ./$(DEPDIR)/libhawk_la-hawk.Plo -rm -f ./$(DEPDIR)/libhawk_la-htb.Plo + -rm -f ./$(DEPDIR)/libhawk_la-json.Plo -rm -f ./$(DEPDIR)/libhawk_la-mb8.Plo -rm -f ./$(DEPDIR)/libhawk_la-misc.Plo -rm -f ./$(DEPDIR)/libhawk_la-mod-hawk.Plo @@ -1564,6 +1584,7 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/libhawk_la-sed.Plo -rm -f ./$(DEPDIR)/libhawk_la-sio.Plo -rm -f ./$(DEPDIR)/libhawk_la-skad.Plo + -rm -f ./$(DEPDIR)/libhawk_la-std-json.Plo -rm -f ./$(DEPDIR)/libhawk_la-std-sed.Plo -rm -f ./$(DEPDIR)/libhawk_la-std.Plo -rm -f ./$(DEPDIR)/libhawk_la-tio.Plo @@ -1658,6 +1679,7 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libhawk_la-gem.Plo -rm -f ./$(DEPDIR)/libhawk_la-hawk.Plo -rm -f ./$(DEPDIR)/libhawk_la-htb.Plo + -rm -f ./$(DEPDIR)/libhawk_la-json.Plo -rm -f ./$(DEPDIR)/libhawk_la-mb8.Plo -rm -f ./$(DEPDIR)/libhawk_la-misc.Plo -rm -f ./$(DEPDIR)/libhawk_la-mod-hawk.Plo @@ -1674,6 +1696,7 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libhawk_la-sed.Plo -rm -f ./$(DEPDIR)/libhawk_la-sio.Plo -rm -f ./$(DEPDIR)/libhawk_la-skad.Plo + -rm -f ./$(DEPDIR)/libhawk_la-std-json.Plo -rm -f ./$(DEPDIR)/libhawk_la-std-sed.Plo -rm -f ./$(DEPDIR)/libhawk_la-std.Plo -rm -f ./$(DEPDIR)/libhawk_la-tio.Plo diff --git a/lib/hawk-json.h b/lib/hawk-json.h new file mode 100644 index 00000000..ed1443a0 --- /dev/null +++ b/lib/hawk-json.h @@ -0,0 +1,325 @@ +/* + Copyright (c) 2006-2020 Chung, Hyung-Hwan. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _HAWK_JSON_H_ +#define _HAWK_JSON_H_ + +#include +#include + +/** + * The hawk_json_t type defines a simple json parser. + */ +typedef struct hawk_json_t hawk_json_t; + +#define HAWK_JSON_HDR \ + hawk_oow_t _instsize; \ + hawk_gem_t _gem + +typedef struct hawk_json_alt_t hawk_json_alt_t; +struct hawk_json_alt_t +{ + /* ensure that hawk_json_t matches the beginning part of hawk_json_t */ + HAWK_JSON_HDR; +}; + +enum hawk_json_option_t +{ + HAWK_JSON_TRAIT +}; +typedef enum hawk_json_option_t hawk_json_option_t; + +enum hawk_json_trait_t +{ + /* no trait defined at this moment. XXXX is just a placeholder */ + HAWK_JSON_XXXX = (1 << 0) +}; +typedef enum hawk_json_trait_t hawk_json_trait_t; + +/* ========================================================================= */ + +enum hawk_json_state_t +{ + HAWK_JSON_STATE_START, + HAWK_JSON_STATE_IN_ARRAY, + HAWK_JSON_STATE_IN_DIC, + + HAWK_JSON_STATE_IN_WORD_VALUE, + HAWK_JSON_STATE_IN_NUMERIC_VALUE, + HAWK_JSON_STATE_IN_STRING_VALUE, + HAWK_JSON_STATE_IN_CHARACTER_VALUE +}; +typedef enum hawk_json_state_t hawk_json_state_t; + + +/* ========================================================================= */ +enum hawk_json_inst_t +{ + HAWK_JSON_INST_START_ARRAY, + HAWK_JSON_INST_END_ARRAY, + HAWK_JSON_INST_START_DIC, + HAWK_JSON_INST_END_DIC, + + HAWK_JSON_INST_KEY, + + HAWK_JSON_INST_CHARACTER, /* there is no such element as character in real JSON */ + HAWK_JSON_INST_STRING, + HAWK_JSON_INST_NUMBER, + HAWK_JSON_INST_NIL, + HAWK_JSON_INST_TRUE, + HAWK_JSON_INST_FALSE, +}; +typedef enum hawk_json_inst_t hawk_json_inst_t; + +typedef int (*hawk_json_instcb_t) ( + hawk_json_t* json, + hawk_json_inst_t inst, + const hawk_oocs_t* str +); + +struct hawk_json_prim_t +{ + hawk_json_instcb_t instcb; +}; +typedef struct hawk_json_prim_t hawk_json_prim_t; + +/* ========================================================================= */ + +#if defined(__cplusplus) +extern "C" { +#endif + +HAWK_EXPORT hawk_json_t* hawk_json_open ( + hawk_mmgr_t* mmgr, + hawk_oow_t xtnsize, + hawk_cmgr_t* cmgr, + hawk_json_prim_t* prim, + hawk_errnum_t* errnum +); + +HAWK_EXPORT void hawk_json_close ( + hawk_json_t* json +); + +HAWK_EXPORT void hawk_json_reset ( + hawk_json_t* json +); + +HAWK_EXPORT int hawk_json_feed ( + hawk_json_t* json, + const void* ptr, + hawk_oow_t len, + hawk_oow_t* xlen +); + +HAWK_EXPORT hawk_json_state_t hawk_json_getstate ( + hawk_json_t* json +); + +HAWK_EXPORT int hawk_json_setoption ( + hawk_json_t* json, + hawk_json_option_t id, + const void* value +); + +HAWK_EXPORT int hawk_json_getoption ( + hawk_json_t* json, + hawk_json_option_t id, + void* value +); + +/* ------------------------------------------------------------------------- */ + +#if defined(HAWK_HAVE_INLINE) +/** + * The hawk_json_getxtn() function returns the pointer to the extension area + * placed behind the actual json object. + */ +static HAWK_INLINE void* hawk_json_getxtn (hawk_json_t* json) { return (void*)((hawk_uint8_t*)json + ((hawk_json_alt_t*)json)->_instsize); } + +/** + * The hawk_json_getgem() function gets the pointer to the gem structure of the + * json object. + */ +static HAWK_INLINE hawk_gem_t* hawk_json_getgem (hawk_json_t* json) { return &((hawk_json_alt_t*)json)->_gem; } + +/** + * The hawk_json_getmmgr() function gets the memory manager ujson in + * hawk_json_open(). + */ +static HAWK_INLINE hawk_mmgr_t* hawk_json_getmmgr (hawk_json_t* json) { return ((hawk_json_alt_t*)json)->_gem.mmgr; } +static HAWK_INLINE hawk_cmgr_t* hawk_json_getcmgr (hawk_json_t* json) { return ((hawk_json_alt_t*)json)->_gem.cmgr; } +static HAWK_INLINE void hawk_json_setcmgr (hawk_json_t* json, hawk_cmgr_t* cmgr) { ((hawk_json_alt_t*)json)->_gem.cmgr = cmgr; } +#else +#define hawk_json_getxtn(json) ((void*)((hawk_uint8_t*)json + ((hawk_json_alt_t*)json)->_instsize)) +#define hawk_json_getgem(json) (&((hawk_json_alt_t*)(json))->_gem) +#define hawk_json_getmmgr(json) (((hawk_json_alt_t*)(json))->_gem.mmgr) +#define hawk_json_getcmgr(json) (((hawk_json_alt_t*)(json))->_gem.cmgr) +#define hawk_json_setcmgr(json,_cmgr) (((hawk_json_alt_t*)(json))->_gem.cmgr = (_cmgr)) +#endif /* HAWK_HAVE_INLINE */ + +/** + * The hawk_json_geterrnum() function returns the number of the last error + * occurred. + * \return error number + */ + +/** + * The hawk_json_geterror() function gets an error number, an error location, + * and an error message. The information is set to the memory area pointed + * to by each parameter. + */ +#if defined(HAWK_HAVE_INLINE) +static HAWK_INLINE hawk_errnum_t hawk_json_geterrnum (hawk_json_t* json) { return hawk_gem_geterrnum(hawk_json_getgem(json)); } +static HAWK_INLINE const hawk_loc_t* hawk_json_geterrloc (hawk_json_t* json) { return hawk_gem_geterrloc(hawk_json_getgem(json)); } +static HAWK_INLINE const hawk_bch_t* hawk_json_geterrbmsg (hawk_json_t* json) { return hawk_gem_geterrbmsg(hawk_json_getgem(json)); } +static HAWK_INLINE const hawk_uch_t* hawk_json_geterrumsg (hawk_json_t* json) { return hawk_gem_geterrumsg(hawk_json_getgem(json)); } +static HAWK_INLINE void hawk_json_geterrbinf (hawk_json_t* json, hawk_errbinf_t* errinf) { return hawk_gem_geterrbinf(hawk_json_getgem(json), errinf); } +static HAWK_INLINE void hawk_json_geterruinf (hawk_json_t* json, hawk_erruinf_t* errinf) { return hawk_gem_geterruinf(hawk_json_getgem(json), errinf); } +static HAWK_INLINE void hawk_json_geterror (hawk_json_t* json, hawk_errnum_t* errnum, const hawk_ooch_t** errmsg, hawk_loc_t* errloc) { return hawk_gem_geterror(hawk_json_getgem(json), errnum, errmsg, errloc); } +#else +#define hawk_json_geterrnum(json) hawk_gem_geterrnum(hawk_json_getgem(json)) +#define hawk_json_geterrloc(json) hawk_gem_geterrloc(hawk_json_getgem(json)) +#define hawk_json_geterrbmsg(json) hawk_gem_geterrbmsg(hawk_json_getgem(json)) +#define hawk_json_geterrumsg(json) hawk_gem_geterrumsg(hawk_json_getgem(json)) +#define hawk_json_geterrbinf(json, errinf) (hawk_gem_geterrbinf(hawk_json_getgem(json), errinf)) +#define hawk_json_geterruinf(json, errinf) (hawk_gem_geterruinf(hawk_json_getgem(json), errinf)) +#define hawk_json_geterror(json, errnum, errmsg, errloc) (hawk_gem_geterror(hawk_json_getgem(json), errnum, errmsg, errloc)) +#endif + +#if defined(HAWK_OOCH_IS_BCH) +# define hawk_json_geterrmsg hawk_json_geterrbmsg +# define hawk_json_geterrinf hawk_json_geterrbinf +#else +# define hawk_json_geterrmsg hawk_json_geterrumsg +# define hawk_json_geterrinf hawk_json_geterruinf +#endif + + +/** + * The hawk_json_seterrnum() function sets the error information omitting + * error location. You must pass a non-NULL for \a errarg if the specified + * error number \a errnum requires one or more arguments to format an + * error message. + */ +#if defined(HAWK_HAVE_INLINE) +static HAWK_INLINE void hawk_json_seterrnum (hawk_json_t* json, const hawk_loc_t* errloc, hawk_errnum_t errnum) { hawk_gem_seterrnum (hawk_json_getgem(json), errloc, errnum); } +static HAWK_INLINE void hawk_json_seterrinf (hawk_json_t* json, const hawk_errinf_t* errinf) { hawk_gem_seterrinf (hawk_json_getgem(json), errinf); } +static HAWK_INLINE void hawk_json_seterror (hawk_json_t* json, const hawk_loc_t* errloc, hawk_errnum_t errnum, const hawk_oocs_t* errarg) { hawk_gem_seterror(hawk_json_getgem(json), errloc, errnum, errarg); } +static HAWK_INLINE const hawk_ooch_t* hawk_json_backuperrmsg (hawk_json_t* json) { return hawk_gem_backuperrmsg(hawk_json_getgem(json)); } +#else +#define hawk_json_seterrnum(json, errloc, errnum) hawk_gem_seterrnum(hawk_json_getgem(json), errloc, errnum) +#define hawk_json_seterrinf(json, errinf) hawk_gem_seterrinf(hawk_json_getgem(json), errinf) +#define hawk_json_seterror(json, errloc, errnum, errarg) hawk_gem_seterror(hawk_json_getgem(json), errloc, errnum, errarg) +#define hawk_json_backuperrmsg(json) hawk_gem_backuperrmsg(hawk_json_getgem(json)) +#endif + +HAWK_EXPORT void hawk_json_seterrbfmt ( + hawk_json_t* json, + const hawk_loc_t* errloc, + hawk_errnum_t errnum, + const hawk_bch_t* fmt, + ... +); + +HAWK_EXPORT void hawk_json_seterrufmt ( + hawk_json_t* json, + const hawk_loc_t* errloc, + hawk_errnum_t errnum, + const hawk_uch_t* fmt, + ... +); + + +HAWK_EXPORT void hawk_json_seterrbvfmt ( + hawk_json_t* json, + const hawk_loc_t* errloc, + hawk_errnum_t errnum, + const hawk_bch_t* errfmt, + va_list ap +); + +HAWK_EXPORT void hawk_json_seterruvfmt ( + hawk_json_t* json, + const hawk_loc_t* errloc, + hawk_errnum_t errnum, + const hawk_uch_t* errfmt, + va_list ap +); + +/* ------------------------------------------------------------------------- */ + +HAWK_EXPORT void* hawk_json_allocmem ( + hawk_json_t* json, + hawk_oow_t size +); + +HAWK_EXPORT void* hawk_json_callocmem ( + hawk_json_t* json, + hawk_oow_t size +); + +HAWK_EXPORT void* hawk_json_reallocmem ( + hawk_json_t* json, + void* ptr, + hawk_oow_t size +); + +HAWK_EXPORT void hawk_json_freemem ( + hawk_json_t* json, + void* ptr +); + +/* ------------------------------------------------------------------------- */ + +/** + * The hawk_json_openstd() function creates a stream editor with the default + * memory manager and initializes it. + * \return pointer to a stream editor on success, #HAWK_NULL on failure. + */ +HAWK_EXPORT hawk_json_t* hawk_json_openstd ( + hawk_oow_t xtnsize, /**< extension size in bytes */ + hawk_json_prim_t* prim, + hawk_errnum_t* errnum +); + +/** + * The hawk_json_openstdwithmmgr() function creates a stream editor with a + * user-defined memory manager. It is equivalent to hawk_json_openstd(), + * except that you can specify your own memory manager. + * \return pointer to a stream editor on success, #HAWK_NULL on failure. + */ +HAWK_EXPORT hawk_json_t* hawk_json_openstdwithmmgr ( + hawk_mmgr_t* mmgr, /**< memory manager */ + hawk_oow_t xtnsize, /**< extension size in bytes */ + hawk_cmgr_t* cmgr, + hawk_json_prim_t* prim, + hawk_errnum_t* errnum +); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/lib/hawk-sed.h b/lib/hawk-sed.h index d3b0207d..e96ac6bc 100644 --- a/lib/hawk-sed.h +++ b/lib/hawk-sed.h @@ -472,8 +472,6 @@ HAWK_EXPORT void hawk_sed_close ( hawk_sed_t* sed /**< stream editor */ ); - - #if defined(HAWK_HAVE_INLINE) /** * The hawk_sed_getxtn() function returns the pointer to the extension area diff --git a/lib/json-prv.h b/lib/json-prv.h new file mode 100644 index 00000000..2b690e29 --- /dev/null +++ b/lib/json-prv.h @@ -0,0 +1,97 @@ +/* + Copyright (c) 2006-2020 Chung, Hyung-Hwan. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _HAWK_JSON_PRV_H_ +#define _HAWK_JSON_PRV_H_ + +#include + +typedef struct hawk_json_state_node_t hawk_json_state_node_t; +struct hawk_json_state_node_t +{ + hawk_json_state_t state; + union + { + struct + { + int got_value; + } ia; /* in array */ + + struct + { + /* 0: ready to get key (at the beginning or got comma), + * 1: got key, 2: got colon, 3: got value */ + int state; + } id; /* in dictionary */ + struct + { + int escaped; + int digit_count; + /* acc is always of unicode type to handle \u and \U. + * in the bch mode, it will get converted to a utf8 stream. */ + hawk_uch_t acc; + } sv; + struct + { + int escaped; + int digit_count; + /* for a character, no way to support the unicode character + * in the bch mode */ + hawk_ooch_t acc; + } cv; + struct + { + int dotted; + } nv; + } u; + hawk_json_state_node_t* next; +}; + +struct hawk_json_t +{ + HAWK_JSON_HDR; + + hawk_errnum_t errnum; + struct + { + hawk_ooch_t backup[256]; + hawk_ooch_t buf[256]; + /*hawk_oow_t len;*/ + } errmsg; + + hawk_json_prim_t prim; + + struct + { + int trait; + } cfg; + + hawk_json_state_node_t state_top; + hawk_json_state_node_t* state_stack; + + hawk_oocs_t tok; + hawk_oow_t tok_capa; +}; + +#endif diff --git a/lib/json.c b/lib/json.c new file mode 100644 index 00000000..977aea73 --- /dev/null +++ b/lib/json.c @@ -0,0 +1,918 @@ +/* + Copyright (c) 2006-2020 Chung, Hyung-Hwan. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include "hawk-prv.h" +#include "json-prv.h" + +#define HAWK_JSON_TOKEN_NAME_ALIGN (64) + +/* ========================================================================= */ + +static void clear_token (hawk_json_t* json) +{ + json->tok.len = 0; + if (json->tok_capa > 0) json->tok.ptr[json->tok.len] = HAWK_T('\0'); +} + +static int add_char_to_token (hawk_json_t* json, hawk_ooch_t ch) +{ + if (json->tok.len >= json->tok_capa) + { + hawk_ooch_t* tmp; + hawk_oow_t newcapa; + + newcapa = HAWK_ALIGN_POW2(json->tok.len + 2, HAWK_JSON_TOKEN_NAME_ALIGN); /* +2 here because of -1 when setting newcapa */ + tmp = (hawk_ooch_t*)hawk_json_reallocmem(json, json->tok.ptr, newcapa * HAWK_SIZEOF(*tmp)); + if (!tmp) return -1; + + json->tok_capa = newcapa - 1; /* -1 to secure space for terminating null */ + json->tok.ptr = tmp; + } + + json->tok.ptr[json->tok.len++] = ch; + json->tok.ptr[json->tok.len] = HAWK_T('\0'); + return 0; +} + +static int add_chars_to_token (hawk_json_t* json, const hawk_ooch_t* ptr, hawk_oow_t len) +{ + hawk_oow_t i; + + if (json->tok_capa - json->tok.len > len) + { + hawk_ooch_t* tmp; + hawk_oow_t newcapa; + + newcapa = HAWK_ALIGN_POW2(json->tok.len + len + 1, HAWK_JSON_TOKEN_NAME_ALIGN); + tmp = (hawk_ooch_t*)hawk_json_reallocmem(json, json->tok.ptr, newcapa * HAWK_SIZEOF(*tmp)); + if (!tmp) return -1; + + json->tok_capa = newcapa - 1; + json->tok.ptr = tmp; + } + + for (i = 0; i < len; i++) + json->tok.ptr[json->tok.len++] = ptr[i]; + json->tok.ptr[json->tok.len] = HAWK_T('\0'); + return 0; +} + +static HAWK_INLINE hawk_ooch_t unescape (hawk_ooch_t c) +{ + switch (c) + { + case HAWK_T('a'): return HAWK_T('\a'); + case HAWK_T('b'): return HAWK_T('\b'); + case HAWK_T('f'): return HAWK_T('\f'); + case HAWK_T('n'): return HAWK_T('\n'); + case HAWK_T('r'): return HAWK_T('\r'); + case HAWK_T('t'): return HAWK_T('\t'); + case HAWK_T('v'): return HAWK_T('\v'); + default: return c; + } +} + +/* ========================================================================= */ + +static int push_state (hawk_json_t* json, hawk_json_state_t state) +{ + hawk_json_state_node_t* ss; + + ss = (hawk_json_state_node_t*)hawk_json_callocmem(json, HAWK_SIZEOF(*ss)); + if (!ss) return -1; + + ss->state = state; + ss->next = json->state_stack; + + json->state_stack = ss; + return 0; +} + +static void pop_state (hawk_json_t* json) +{ + hawk_json_state_node_t* ss; + + ss = json->state_stack; + HAWK_ASSERT (ss != HAWK_NULL && ss != &json->state_top); + json->state_stack = ss->next; + + if (json->state_stack->state == HAWK_JSON_STATE_IN_ARRAY) + { + json->state_stack->u.ia.got_value = 1; + } + else if (json->state_stack->state == HAWK_JSON_STATE_IN_DIC) + { + json->state_stack->u.id.state++; + } + +/* TODO: don't free this. move it to the free list? */ + hawk_json_freemem (json, ss); +} + +static void pop_all_states (hawk_json_t* json) +{ + while (json->state_stack != &json->state_top) pop_state (json); +} + +/* ========================================================================= */ + +static int invoke_data_inst (hawk_json_t* json, hawk_json_inst_t inst) +{ + if (json->state_stack->state == HAWK_JSON_STATE_IN_DIC && json->state_stack->u.id.state == 1) + { + if (inst != HAWK_JSON_INST_STRING) + { + hawk_json_seterrbfmt (json, HAWK_NULL, HAWK_EINVAL, "dictionary key not a string - %.*js", json->tok.len, json->tok.ptr); + return -1; + } + + inst = HAWK_JSON_INST_KEY; + } + + if (json->prim.instcb(json, inst, &json->tok) <= -1) return -1; + return 0; +} + +static int handle_string_value_char (hawk_json_t* json, hawk_ooci_t c) +{ + int ret = 1; + + if (json->state_stack->u.sv.escaped == 3) + { + if (c >= '0' && c <= '7') + { + json->state_stack->u.sv.acc = json->state_stack->u.sv.acc * 8 + c - '0'; + json->state_stack->u.sv.digit_count++; + if (json->state_stack->u.sv.digit_count >= json->state_stack->u.sv.escaped) goto add_sv_acc; + } + else + { + ret = 0; + goto add_sv_acc; + } + } + else if (json->state_stack->u.sv.escaped >= 2) + { + if (c >= '0' && c <= '9') + { + json->state_stack->u.sv.acc = json->state_stack->u.sv.acc * 16 + c - '0'; + json->state_stack->u.sv.digit_count++; + if (json->state_stack->u.sv.digit_count >= json->state_stack->u.sv.escaped) goto add_sv_acc; + } + else if (c >= 'a' && c <= 'f') + { + json->state_stack->u.sv.acc = json->state_stack->u.sv.acc * 16 + c - 'a' + 10; + json->state_stack->u.sv.digit_count++; + if (json->state_stack->u.sv.digit_count >= json->state_stack->u.sv.escaped) goto add_sv_acc; + } + else if (c >= 'A' && c <= 'F') + { + json->state_stack->u.sv.acc = json->state_stack->u.sv.acc * 16 + c - 'A' + 10; + json->state_stack->u.sv.digit_count++; + if (json->state_stack->u.sv.digit_count >= json->state_stack->u.sv.escaped) goto add_sv_acc; + } + else + { + ret = 0; + add_sv_acc: + #if defined(HAWK_OOCH_IS_UCH) + if (add_char_to_token(json, json->state_stack->u.sv.acc) <= -1) return -1; + #else + /* convert the character to utf8 */ + { + hawk_bch_t bcsbuf[HAWK_MBLEN_MAX]; + hawk_oow_t n; + + n = json->_cmgr->wctomb(json->state_stack->u.sv.acc, bcsbuf, HAWK_COUNTOF(bcsbuf)); + if (n == 0 || n > HAWK_COUNTOF(bcsbuf)) + { + /* illegal character or buffer to small */ + hawk_json_seterrbfmt (json, HAWK_NULL, HAWK_EECERR, "unable to convert %jc", json->state_stack->u.sv.acc); + return -1; + } + + if (add_chars_to_token(json, bcsbuf, n) <= -1) return -1; + } + #endif + json->state_stack->u.sv.escaped = 0; + } + } + else if (json->state_stack->u.sv.escaped == 1) + { + if (c >= '0' && c <= '8') + { + json->state_stack->u.sv.escaped = 3; + json->state_stack->u.sv.digit_count = 0; + json->state_stack->u.sv.acc = c - '0'; + } + else if (c == 'x') + { + json->state_stack->u.sv.escaped = 2; + json->state_stack->u.sv.digit_count = 0; + json->state_stack->u.sv.acc = 0; + } + else if (c == 'u') + { + json->state_stack->u.sv.escaped = 4; + json->state_stack->u.sv.digit_count = 0; + json->state_stack->u.sv.acc = 0; + } + else if (c == 'U') + { + json->state_stack->u.sv.escaped = 8; + json->state_stack->u.sv.digit_count = 0; + json->state_stack->u.sv.acc = 0; + } + else + { + json->state_stack->u.sv.escaped = 0; + if (add_char_to_token(json, unescape(c)) <= -1) return -1; + } + } + else if (c == '\\') + { + json->state_stack->u.sv.escaped = 1; + } + else if (c == '\"') + { + pop_state (json); + if (invoke_data_inst(json, HAWK_JSON_INST_STRING) <= -1) return -1; + } + else + { + if (add_char_to_token(json, c) <= -1) return -1; + } + + return ret; +} + +static int handle_character_value_char (hawk_json_t* json, hawk_ooci_t c) +{ + /* The real JSON dones't support character literal. this is HCL's own extension. */ + int ret = 1; + + if (json->state_stack->u.cv.escaped == 3) + { + if (c >= '0' && c <= '7') + { + json->state_stack->u.cv.acc = json->state_stack->u.cv.acc * 8 + c - '0'; + json->state_stack->u.cv.digit_count++; + if (json->state_stack->u.cv.digit_count >= json->state_stack->u.cv.escaped) goto add_cv_acc; + } + else + { + ret = 0; + goto add_cv_acc; + } + } + if (json->state_stack->u.cv.escaped >= 2) + { + if (c >= '0' && c <= '9') + { + json->state_stack->u.cv.acc = json->state_stack->u.cv.acc * 16 + c - '0'; + json->state_stack->u.cv.digit_count++; + if (json->state_stack->u.cv.digit_count >= json->state_stack->u.cv.escaped) goto add_cv_acc; + } + else if (c >= 'a' && c <= 'f') + { + json->state_stack->u.cv.acc = json->state_stack->u.cv.acc * 16 + c - 'a' + 10; + json->state_stack->u.cv.digit_count++; + if (json->state_stack->u.cv.digit_count >= json->state_stack->u.cv.escaped) goto add_cv_acc; + } + else if (c >= 'A' && c <= 'F') + { + json->state_stack->u.cv.acc = json->state_stack->u.cv.acc * 16 + c - 'A' + 10; + json->state_stack->u.cv.digit_count++; + if (json->state_stack->u.cv.digit_count >= json->state_stack->u.cv.escaped) goto add_cv_acc; + } + else + { + ret = 0; + add_cv_acc: + if (add_char_to_token(json, json->state_stack->u.cv.acc) <= -1) return -1; + json->state_stack->u.cv.escaped = 0; + } + } + else if (json->state_stack->u.cv.escaped == 1) + { + if (c >= '0' && c <= '8') + { + json->state_stack->u.cv.escaped = 3; + json->state_stack->u.cv.digit_count = 0; + json->state_stack->u.cv.acc = c - '0'; + } + else if (c == 'x') + { + json->state_stack->u.cv.escaped = 2; + json->state_stack->u.cv.digit_count = 0; + json->state_stack->u.cv.acc = 0; + } + else if (c == 'u') + { + json->state_stack->u.cv.escaped = 4; + json->state_stack->u.cv.digit_count = 0; + json->state_stack->u.cv.acc = 0; + } + else if (c == 'U') + { + json->state_stack->u.cv.escaped = 8; + json->state_stack->u.cv.digit_count = 0; + json->state_stack->u.cv.acc = 0; + } + else + { + json->state_stack->u.cv.escaped = 0; + if (add_char_to_token(json, unescape(c)) <= -1) return -1; + } + } + else if (c == '\\') + { + json->state_stack->u.cv.escaped = 1; + } + else if (c == '\'') + { + pop_state (json); + + if (json->tok.len < 1) + { + hawk_json_seterrbfmt (json, HAWK_NULL, HAWK_EINVAL, "no character in a character literal"); + return -1; + } + if (invoke_data_inst(json, HAWK_JSON_INST_CHARACTER) <= -1) return -1; + } + else + { + if (add_char_to_token(json, c) <= -1) return -1; + } + + if (json->tok.len > 1) + { + hawk_json_seterrbfmt (json, HAWK_NULL, HAWK_EINVAL, "too many characters in a character literal - %.*js", (int)json->tok.len, json->tok.ptr); + return -1; + } + + return ret; +} + +static int handle_numeric_value_char (hawk_json_t* json, hawk_ooci_t c) +{ + if (hawk_is_ooch_digit(c) || (json->tok.len == 0 && (c == '+' || c == '-'))) + { + if (add_char_to_token(json, c) <= -1) return -1; + return 1; + } + else if (!json->state_stack->u.nv.dotted && c == '.' && + json->tok.len > 0 && hawk_is_ooch_digit(json->tok.ptr[json->tok.len - 1])) + { + if (add_char_to_token(json, c) <= -1) return -1; + json->state_stack->u.nv.dotted = 1; + return 1; + } + + pop_state (json); + + HAWK_ASSERT (json->tok.len > 0); + if (!hawk_is_ooch_digit(json->tok.ptr[json->tok.len - 1])) + { + hawk_json_seterrbfmt (json, HAWK_NULL, HAWK_EINVAL, "invalid numeric value - %.*js", (int)json->tok.len, json->tok.ptr); + return -1; + } + if (invoke_data_inst(json, HAWK_JSON_INST_NUMBER) <= -1) return -1; + return 0; /* start over */ +} + +static int handle_word_value_char (hawk_json_t* json, hawk_ooci_t c) +{ + hawk_json_inst_t inst; + + if (hawk_is_ooch_alpha(c)) + { + if (add_char_to_token(json, c) <= -1) return -1; + return 1; + } + + pop_state (json); + + if (hawk_comp_oochars_bcstr(json->tok.ptr, json->tok.len, "null", 0) == 0) inst = HAWK_JSON_INST_NIL; + else if (hawk_comp_oochars_bcstr(json->tok.ptr, json->tok.len, "true", 0) == 0) inst = HAWK_JSON_INST_TRUE; + else if (hawk_comp_oochars_bcstr(json->tok.ptr, json->tok.len, "false", 0) == 0) inst = HAWK_JSON_INST_FALSE; + else + { + hawk_json_seterrbfmt (json, HAWK_NULL, HAWK_EINVAL, "invalid word value - %.*js", json->tok.len, json->tok.ptr); + return -1; + } + + if (invoke_data_inst(json, inst) <= -1) return -1; + return 0; /* start over */ +} + +/* ========================================================================= */ + +static int handle_start_char (hawk_json_t* json, hawk_ooci_t c) +{ + if (c == '[') + { + if (push_state(json, HAWK_JSON_STATE_IN_ARRAY) <= -1) return -1; + json->state_stack->u.ia.got_value = 0; + if (json->prim.instcb(json, HAWK_JSON_INST_START_ARRAY, HAWK_NULL) <= -1) return -1; + return 1; + } + else if (c == '{') + { + if (push_state(json, HAWK_JSON_STATE_IN_DIC) <= -1) return -1; + json->state_stack->u.id.state = 0; + if (json->prim.instcb(json, HAWK_JSON_INST_START_DIC, HAWK_NULL) <= -1) return -1; + return 1; + } + else if (hawk_is_ooch_space(c)) + { + /* do nothing */ + return 1; + } + else + { + hawk_json_seterrbfmt (json, HAWK_NULL, HAWK_EINVAL, "not starting with [ or { - %jc", (hawk_ooch_t)c); + return -1; + } +} + +static int handle_char_in_array (hawk_json_t* json, hawk_ooci_t c) +{ + if (c == ']') + { + if (json->prim.instcb(json, HAWK_JSON_INST_END_ARRAY, HAWK_NULL) <= -1) return -1; + pop_state (json); + return 1; + } + else if (c == ',') + { + if (!json->state_stack->u.ia.got_value) + { + hawk_json_seterrbfmt (json, HAWK_NULL, HAWK_EINVAL, "redundant comma in array - %jc", (hawk_ooch_t)c); + return -1; + } + json->state_stack->u.ia.got_value = 0; + return 1; + } + else if (hawk_is_ooch_space(c)) + { + /* do nothing */ + return 1; + } + else + { + if (json->state_stack->u.ia.got_value) + { + hawk_json_seterrbfmt (json, HAWK_NULL, HAWK_EINVAL, "comma required in array - %jc", (hawk_ooch_t)c); + return -1; + } + + if (c == '\"') + { + if (push_state(json, HAWK_JSON_STATE_IN_STRING_VALUE) <= -1) return -1; + clear_token (json); + return 1; + } + else if (c == '\'') + { + if (push_state(json, HAWK_JSON_STATE_IN_CHARACTER_VALUE) <= -1) return -1; + clear_token (json); + return 1; + } + /* TOOD: else if (c == '#') HCL radixed number + */ + else if (hawk_is_ooch_digit(c) || c == '+' || c == '-') + { + if (push_state(json, HAWK_JSON_STATE_IN_NUMERIC_VALUE) <= -1) return -1; + clear_token (json); + json->state_stack->u.nv.dotted = 0; + return 0; /* start over */ + } + else if (hawk_is_ooch_alpha(c)) + { + if (push_state(json, HAWK_JSON_STATE_IN_WORD_VALUE) <= -1) return -1; + clear_token (json); + return 0; /* start over */ + } + else if (c == '[') + { + if (push_state(json, HAWK_JSON_STATE_IN_ARRAY) <= -1) return -1; + json->state_stack->u.ia.got_value = 0; + if (json->prim.instcb(json, HAWK_JSON_INST_START_ARRAY, HAWK_NULL) <= -1) return -1; + return 1; + } + else if (c == '{') + { + if (push_state(json, HAWK_JSON_STATE_IN_DIC) <= -1) return -1; + json->state_stack->u.id.state = 0; + if (json->prim.instcb(json, HAWK_JSON_INST_START_DIC, HAWK_NULL) <= -1) return -1; + return 1; + } + else + { + hawk_json_seterrbfmt (json, HAWK_NULL, HAWK_EINVAL, "wrong character inside array - %jc[%d]", (hawk_ooch_t)c, (int)c); + return -1; + } + } +} + +static int handle_char_in_dic (hawk_json_t* json, hawk_ooci_t c) +{ + if (c == '}') + { + if (json->prim.instcb(json, HAWK_JSON_INST_END_DIC, HAWK_NULL) <= -1) return -1; + pop_state (json); + return 1; + } + else if (c == ':') + { + if (json->state_stack->u.id.state != 1) + { + hawk_json_seterrbfmt (json, HAWK_NULL, HAWK_EINVAL, "redundant colon in dictionary - %jc", (hawk_ooch_t)c); + return -1; + } + json->state_stack->u.id.state++; + return 1; + } + else if (c == ',') + { + if (json->state_stack->u.id.state != 3) + { + hawk_json_seterrbfmt (json, HAWK_NULL, HAWK_EINVAL, "redundant comma in dicitonary - %jc", (hawk_ooch_t)c); + return -1; + } + json->state_stack->u.id.state = 0; + return 1; + } + else if (hawk_is_ooch_space(c)) + { + /* do nothing */ + return 1; + } + else + { + if (json->state_stack->u.id.state == 1) + { + hawk_json_seterrbfmt (json, HAWK_NULL, HAWK_EINVAL, "colon required in dicitonary - %jc", (hawk_ooch_t)c); + return -1; + } + else if (json->state_stack->u.id.state == 3) + { + hawk_json_seterrbfmt (json, HAWK_NULL, HAWK_EINVAL, "comma required in dicitonary - %jc", (hawk_ooch_t)c); + return -1; + } + + if (c == '\"') + { + if (push_state(json, HAWK_JSON_STATE_IN_STRING_VALUE) <= -1) return -1; + clear_token (json); + return 1; + } + else if (c == '\'') + { + if (push_state(json, HAWK_JSON_STATE_IN_CHARACTER_VALUE) <= -1) return -1; + clear_token (json); + return 1; + } + /* TOOD: else if (c == '#') HCL radixed number + */ + else if (hawk_is_ooch_digit(c) || c == '+' || c == '-') + { + if (push_state(json, HAWK_JSON_STATE_IN_NUMERIC_VALUE) <= -1) return -1; + clear_token (json); + json->state_stack->u.nv.dotted = 0; + return 0; /* start over */ + } + else if (hawk_is_ooch_alpha(c)) + { + if (push_state(json, HAWK_JSON_STATE_IN_WORD_VALUE) <= -1) return -1; + clear_token (json); + return 0; /* start over */ + } + else if (c == '[') + { + if (push_state(json, HAWK_JSON_STATE_IN_ARRAY) <= -1) return -1; + json->state_stack->u.ia.got_value = 0; + if (json->prim.instcb(json, HAWK_JSON_INST_START_ARRAY, HAWK_NULL) <= -1) return -1; + return 1; + } + else if (c == '{') + { + if (push_state(json, HAWK_JSON_STATE_IN_DIC) <= -1) return -1; + json->state_stack->u.id.state = 0; + if (json->prim.instcb(json, HAWK_JSON_INST_START_DIC, HAWK_NULL) <= -1) return -1; + return 1; + } + else + { + hawk_json_seterrbfmt (json, HAWK_NULL, HAWK_EINVAL, "wrong character inside dictionary - %jc[%d]", (hawk_ooch_t)c, (int)c); + return -1; + } + } +} + +/* ========================================================================= */ + +static int handle_char (hawk_json_t* json, hawk_ooci_t c) +{ + int x; + +start_over: + if (c == HAWK_OOCI_EOF) + { + if (json->state_stack->state == HAWK_JSON_STATE_START) + { + /* no input data */ + return 0; + } + else + { + hawk_json_seterrnum (json, HAWK_NULL, HAWK_EEOF); + return -1; + } + } + + switch (json->state_stack->state) + { + case HAWK_JSON_STATE_START: + x = handle_start_char(json, c); + break; + + case HAWK_JSON_STATE_IN_ARRAY: + x = handle_char_in_array(json, c); + break; + + case HAWK_JSON_STATE_IN_DIC: + x = handle_char_in_dic(json, c); + break; + + case HAWK_JSON_STATE_IN_WORD_VALUE: + x = handle_word_value_char(json, c); + break; + + case HAWK_JSON_STATE_IN_STRING_VALUE: + x = handle_string_value_char(json, c); + break; + + case HAWK_JSON_STATE_IN_CHARACTER_VALUE: + x = handle_character_value_char(json, c); + break; + + case HAWK_JSON_STATE_IN_NUMERIC_VALUE: + x = handle_numeric_value_char(json, c); + break; + + default: + hawk_json_seterrbfmt (json, HAWK_NULL, HAWK_EINTERN, "internal error - must not be called for state %d", (int)json->state_stack->state); + return -1; + } + + if (x <= -1) return -1; + if (x == 0) goto start_over; + + return 0; +} + +/* ========================================================================= */ + +static int feed_json_data (hawk_json_t* json, const hawk_bch_t* data, hawk_oow_t len, hawk_oow_t* xlen) +{ + const hawk_bch_t* ptr; + const hawk_bch_t* end; + + ptr = data; + end = ptr + len; + + while (ptr < end) + { + hawk_ooci_t c; + + #if defined(HAWK_OOCH_IS_UCH) + hawk_ooch_t uc; + hawk_oow_t bcslen; + hawk_oow_t n; + + bcslen = end - ptr; + n = json->_gem.cmgr->bctouc(ptr, bcslen, &uc); + if (n == 0) + { + /* invalid sequence */ + uc = *ptr; + n = 1; + } + else if (n > bcslen) + { + /* incomplete sequence */ + *xlen = ptr - data; /* didn't manage to process in full */ + return 0; /* feed more for incomplete sequence */ + } + + ptr += n; + c = uc; + #else + c = *ptr++; + #endif + + /* handle a single character */ + if (handle_char(json, c) <= -1) goto oops; + } + + *xlen = ptr - data; + return 1; + +oops: + /* TODO: compute the number of processed bytes so far and return it via a parameter??? */ +/*printf ("feed oops....\n");*/ + return -1; +} + + +/* ========================================================================= */ + +hawk_json_t* hawk_json_open (hawk_mmgr_t* mmgr, hawk_oow_t xtnsize, hawk_cmgr_t* cmgr, hawk_json_prim_t* prim, hawk_errnum_t* errnum) +{ + hawk_json_t* json; + + json = (hawk_json_t*)HAWK_MMGR_ALLOC(mmgr, HAWK_SIZEOF(hawk_json_t) + xtnsize); + if (!json) + { + if (errnum) *errnum = HAWK_ENOMEM; + return HAWK_NULL; + } + + HAWK_MEMSET (json, 0, HAWK_SIZEOF(*json) + xtnsize); + json->_instsize = HAWK_SIZEOF(*json); + json->_gem.mmgr = mmgr; + json->_gem.cmgr = cmgr; + + /* initialize error handling fields */ + json->_gem.errnum = HAWK_ENOERR; + json->_gem.errmsg[0] = '\0'; + json->_gem.errloc.line = 0; + json->_gem.errloc.colm = 0; + json->_gem.errloc.file = HAWK_NULL; + json->_gem.errstr = hawk_dfl_errstr; + + json->prim = *prim; + json->state_top.state = HAWK_JSON_STATE_START; + json->state_top.next = HAWK_NULL; + json->state_stack = &json->state_top; + + return json; +} + +void hawk_json_close (hawk_json_t* json) +{ + pop_all_states (json); + if (json->tok.ptr) hawk_json_freemem (json, json->tok.ptr); + HAWK_MMGR_FREE (hawk_json_getmmgr(json), json); +} + +int hawk_json_setoption (hawk_json_t* json, hawk_json_option_t id, const void* value) +{ + switch (id) + { + case HAWK_JSON_TRAIT: + json->cfg.trait = *(const int*)value; + return 0; + } + + hawk_json_seterrnum (json, HAWK_NULL, HAWK_EINVAL); + return -1; +} + +int hawk_json_getoption (hawk_json_t* json, hawk_json_option_t id, void* value) +{ + switch (id) + { + case HAWK_JSON_TRAIT: + *(int*)value = json->cfg.trait; + return 0; + }; + + hawk_json_seterrnum (json, HAWK_NULL, HAWK_EINVAL); + return -1; +} + +/* ========================================================================= */ + +hawk_errstr_t hawk_json_geterrstr (hawk_json_t* json) +{ + return json->_gem.errstr; +} + +void hawk_json_seterrbfmt (hawk_json_t* json, const hawk_loc_t* errloc, hawk_errnum_t errnum, const hawk_bch_t* fmt, ...) +{ + va_list ap; + va_start (ap, fmt); + hawk_gem_seterrbvfmt (hawk_json_getgem(json), errloc, errnum, fmt, ap); + va_end (ap); +} + +void hawk_json_seterrufmt (hawk_json_t* json, const hawk_loc_t* errloc, hawk_errnum_t errnum, const hawk_uch_t* fmt, ...) +{ + va_list ap; + va_start (ap, fmt); + hawk_gem_seterruvfmt (hawk_json_getgem(json), errloc, errnum, fmt, ap); + va_end (ap); +} + + +void hawk_json_seterrbvfmt (hawk_json_t* json, const hawk_loc_t* errloc, hawk_errnum_t errnum, const hawk_bch_t* errfmt, va_list ap) +{ + hawk_gem_seterrbvfmt (hawk_json_getgem(json), errloc, errnum, errfmt, ap); +} + +void hawk_json_seterruvfmt (hawk_json_t* json, const hawk_loc_t* errloc, hawk_errnum_t errnum, const hawk_uch_t* errfmt, va_list ap) +{ + hawk_gem_seterruvfmt (hawk_json_getgem(json), errloc, errnum, errfmt, ap); +} + +/* ========================================================================= */ +void* hawk_json_allocmem (hawk_json_t* json, hawk_oow_t size) +{ + void* ptr; + + ptr = HAWK_MMGR_ALLOC(hawk_json_getmmgr(json), size); + if (!ptr) hawk_json_seterrnum (json, HAWK_NULL, HAWK_ENOMEM); + return ptr; +} + +void* hawk_json_callocmem (hawk_json_t* json, hawk_oow_t size) +{ + void* ptr; + + ptr = HAWK_MMGR_ALLOC(hawk_json_getmmgr(json), size); + if (!ptr) hawk_json_seterrnum (json, HAWK_NULL, HAWK_ENOMEM); + else HAWK_MEMSET (ptr, 0, size); + return ptr; +} + +void* hawk_json_reallocmem (hawk_json_t* json, void* ptr, hawk_oow_t size) +{ + ptr = HAWK_MMGR_REALLOC(hawk_json_getmmgr(json), ptr, size); + if (!ptr) hawk_json_seterrnum (json, HAWK_NULL, HAWK_ENOMEM); + return ptr; +} + +void hawk_json_freemem (hawk_json_t* json, void* ptr) +{ + HAWK_MMGR_FREE (hawk_json_getmmgr(json), ptr); +} + +/* ========================================================================= */ + +hawk_json_state_t hawk_json_getstate (hawk_json_t* json) +{ + return json->state_stack->state; +} + +void hawk_json_reset (hawk_json_t* json) +{ + /* TODO: reset XXXXXXXXXXXXXXXXXXXXXXXXXXXxxxxx */ + pop_all_states (json); + HAWK_ASSERT (json->state_stack == &json->state_top); + json->state_stack->state = HAWK_JSON_STATE_START; +} + +int hawk_json_feed (hawk_json_t* json, const void* ptr, hawk_oow_t len, hawk_oow_t* xlen) +{ + int x; + hawk_oow_t total, ylen; + const hawk_bch_t* buf; + + buf = (const hawk_bch_t*)ptr; + total = 0; + while (total < len) + { + x = feed_json_data(json, &buf[total], len - total, &ylen); + if (x <= -1) return -1; + + total += ylen; + if (x == 0) break; /* incomplete sequence encountered */ + } + + *xlen = total; + return 0; +} diff --git a/lib/mod-sys.c b/lib/mod-sys.c index 47a716cd..d0401335 100644 --- a/lib/mod-sys.c +++ b/lib/mod-sys.c @@ -4919,20 +4919,20 @@ Byte-Order > big-endian ! network (= big-endian) -b qse_int8_t -B qse_uint8_t -h qse_int16_t -H qse_uint16_t -i qse_int32_t -I qse_uint32_t -l qse_int64_t -L qse_uint64_t -q qse_intmax_t -Q qse_uintmax_t -n qse_intptr_t -N qse_uintptr_t -f qse_flt_t (32 bits) -d qse_flt_t (64 bits) +b hawk_int8_t +B hawk_uint8_t +h hawk_int16_t +H hawk_uint16_t +i hawk_int32_t +I hawk_uint32_t +l hawk_int64_t +L hawk_uint64_t +q hawk_intmax_t +Q hawk_uintmax_t +n hawk_intptr_t +N hawk_uintptr_t +f hawk_flt_t (32 bits) +d hawk_flt_t (64 bits) s char[] p char[] x pad bytes diff --git a/lib/std-json.c b/lib/std-json.c new file mode 100644 index 00000000..fe06efe7 --- /dev/null +++ b/lib/std-json.c @@ -0,0 +1,58 @@ +/* + Copyright (c) 2006-2020 Chung, Hyung-Hwan. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "json-prv.h" +#include + +typedef struct xtn_t xtn_t; +struct xtn_t +{ + /* empty. nothing at the moment */ +}; + +#if defined(HAWK_HAVE_INLINE) +static HAWK_INLINE xtn_t* GET_XTN(hawk_json_t* json) { return (xtn_t*)((hawk_uint8_t*)hawk_json_getxtn(json) - HAWK_SIZEOF(xtn_t)); } +#else +#define GET_XTN(json) ((xtn_t*)((hawk_uint8_t*)hawk_json_getxtn(json) - HAWK_SIZEOF(xtn_t))) +#endif + +hawk_json_t* hawk_json_openstd (hawk_oow_t xtnsize, hawk_json_prim_t* prim, hawk_errnum_t* errnum) +{ + return hawk_json_openstdwithmmgr (hawk_get_sys_mmgr(), xtnsize, hawk_get_cmgr_by_id(HAWK_CMGR_UTF8), prim, errnum); +} + +hawk_json_t* hawk_json_openstdwithmmgr (hawk_mmgr_t* mmgr, hawk_oow_t xtnsize, hawk_cmgr_t* cmgr, hawk_json_prim_t* prim, hawk_errnum_t* errnum) +{ + hawk_json_t* json; + + if (!mmgr) mmgr = hawk_get_sys_mmgr(); + if (!cmgr) cmgr = hawk_get_cmgr_by_id(HAWK_CMGR_UTF8); + + json = hawk_json_open(mmgr, HAWK_SIZEOF(xtn_t) + xtnsize, cmgr, prim, errnum); + if (!json) return HAWK_NULL; + + json->_instsize += HAWK_SIZEOF(xtn_t); + + return json; +} diff --git a/t/Makefile.am b/t/Makefile.am index 9e86db1a..54657119 100644 --- a/t/Makefile.am +++ b/t/Makefile.am @@ -22,7 +22,7 @@ EXTRA_DIST = $(check_SCRIPTS) $(check_ERRORS) tap.inc err.sh \ journal-toc.hawk journal-toc.in journal-toc.out journal-toc-html.out \ bibtex-to-html.hawk bibtex-to-html.out -check_PROGRAMS = t-001 t-002 t-003 t-004 t-005 t-006 +check_PROGRAMS = t-001 t-002 t-003 t-004 t-005 t-006 t-007 t_001_SOURCES = t-001.c tap.h t_001_CPPFLAGS = $(CPPFLAGS_COMMON) @@ -57,6 +57,13 @@ t_006_CFLAGS = $(CFLAGS_COMMON) t_006_LDFLAGS = $(LDFLAGS_COMMON) t_006_LDADD = $(LIBADD_COMMON) +t_007_SOURCES = t-007.c tap.h +t_007_CPPFLAGS = $(CPPFLAGS_COMMON) +t_007_CFLAGS = $(CFLAGS_COMMON) +t_007_LDFLAGS = $(LDFLAGS_COMMON) +t_007_LDADD = $(LIBADD_COMMON) + + LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/ac/tap-driver.sh TESTS = $(check_PROGRAMS) $(check_SCRIPTS) $(check_ERRORS) diff --git a/t/Makefile.in b/t/Makefile.in index 1cc0623c..7cc749c2 100644 --- a/t/Makefile.in +++ b/t/Makefile.in @@ -88,7 +88,7 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ check_PROGRAMS = t-001$(EXEEXT) t-002$(EXEEXT) t-003$(EXEEXT) \ - t-004$(EXEEXT) t-005$(EXEEXT) t-006$(EXEEXT) + t-004$(EXEEXT) t-005$(EXEEXT) t-006$(EXEEXT) t-007$(EXEEXT) subdir = t ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_sign.m4 \ @@ -146,6 +146,12 @@ t_006_DEPENDENCIES = $(am__DEPENDENCIES_2) t_006_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(t_006_CFLAGS) $(CFLAGS) \ $(t_006_LDFLAGS) $(LDFLAGS) -o $@ +am_t_007_OBJECTS = t_007-t-007.$(OBJEXT) +t_007_OBJECTS = $(am_t_007_OBJECTS) +t_007_DEPENDENCIES = $(am__DEPENDENCIES_2) +t_007_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(t_007_CFLAGS) $(CFLAGS) \ + $(t_007_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -164,7 +170,7 @@ am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/t_001-t-001.Po \ ./$(DEPDIR)/t_002-t-002.Po ./$(DEPDIR)/t_003-t-003.Po \ ./$(DEPDIR)/t_004-t-004.Po ./$(DEPDIR)/t_005-t-005.Po \ - ./$(DEPDIR)/t_006-t-006.Po + ./$(DEPDIR)/t_006-t-006.Po ./$(DEPDIR)/t_007-t-007.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -185,9 +191,11 @@ am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(t_001_SOURCES) $(t_002_SOURCES) $(t_003_SOURCES) \ - $(t_004_SOURCES) $(t_005_SOURCES) $(t_006_SOURCES) + $(t_004_SOURCES) $(t_005_SOURCES) $(t_006_SOURCES) \ + $(t_007_SOURCES) DIST_SOURCES = $(t_001_SOURCES) $(t_002_SOURCES) $(t_003_SOURCES) \ - $(t_004_SOURCES) $(t_005_SOURCES) $(t_006_SOURCES) + $(t_004_SOURCES) $(t_005_SOURCES) $(t_006_SOURCES) \ + $(t_007_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -615,6 +623,11 @@ t_006_CPPFLAGS = $(CPPFLAGS_COMMON) t_006_CFLAGS = $(CFLAGS_COMMON) t_006_LDFLAGS = $(LDFLAGS_COMMON) t_006_LDADD = $(LIBADD_COMMON) +t_007_SOURCES = t-007.c tap.h +t_007_CPPFLAGS = $(CPPFLAGS_COMMON) +t_007_CFLAGS = $(CFLAGS_COMMON) +t_007_LDFLAGS = $(LDFLAGS_COMMON) +t_007_LDADD = $(LIBADD_COMMON) LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/ac/tap-driver.sh TESTS = $(check_PROGRAMS) $(check_SCRIPTS) $(check_ERRORS) TEST_EXTENSIONS = .hawk .err @@ -691,6 +704,10 @@ t-006$(EXEEXT): $(t_006_OBJECTS) $(t_006_DEPENDENCIES) $(EXTRA_t_006_DEPENDENCIE @rm -f t-006$(EXEEXT) $(AM_V_CCLD)$(t_006_LINK) $(t_006_OBJECTS) $(t_006_LDADD) $(LIBS) +t-007$(EXEEXT): $(t_007_OBJECTS) $(t_007_DEPENDENCIES) $(EXTRA_t_007_DEPENDENCIES) + @rm -f t-007$(EXEEXT) + $(AM_V_CCLD)$(t_007_LINK) $(t_007_OBJECTS) $(t_007_LDADD) $(LIBS) + mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -703,6 +720,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_004-t-004.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_005-t-005.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_006-t-006.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t_007-t-007.Po@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @@ -818,6 +836,20 @@ t_006-t-006.obj: t-006.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(t_006_CPPFLAGS) $(CPPFLAGS) $(t_006_CFLAGS) $(CFLAGS) -c -o t_006-t-006.obj `if test -f 't-006.c'; then $(CYGPATH_W) 't-006.c'; else $(CYGPATH_W) '$(srcdir)/t-006.c'; fi` +t_007-t-007.o: t-007.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(t_007_CPPFLAGS) $(CPPFLAGS) $(t_007_CFLAGS) $(CFLAGS) -MT t_007-t-007.o -MD -MP -MF $(DEPDIR)/t_007-t-007.Tpo -c -o t_007-t-007.o `test -f 't-007.c' || echo '$(srcdir)/'`t-007.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/t_007-t-007.Tpo $(DEPDIR)/t_007-t-007.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='t-007.c' object='t_007-t-007.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(t_007_CPPFLAGS) $(CPPFLAGS) $(t_007_CFLAGS) $(CFLAGS) -c -o t_007-t-007.o `test -f 't-007.c' || echo '$(srcdir)/'`t-007.c + +t_007-t-007.obj: t-007.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(t_007_CPPFLAGS) $(CPPFLAGS) $(t_007_CFLAGS) $(CFLAGS) -MT t_007-t-007.obj -MD -MP -MF $(DEPDIR)/t_007-t-007.Tpo -c -o t_007-t-007.obj `if test -f 't-007.c'; then $(CYGPATH_W) 't-007.c'; else $(CYGPATH_W) '$(srcdir)/t-007.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/t_007-t-007.Tpo $(DEPDIR)/t_007-t-007.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='t-007.c' object='t_007-t-007.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(t_007_CPPFLAGS) $(CPPFLAGS) $(t_007_CFLAGS) $(CFLAGS) -c -o t_007-t-007.obj `if test -f 't-007.c'; then $(CYGPATH_W) 't-007.c'; else $(CYGPATH_W) '$(srcdir)/t-007.c'; fi` + mostlyclean-libtool: -rm -f *.lo @@ -1059,6 +1091,13 @@ t-006.log: t-006$(EXEEXT) --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +t-007.log: t-007$(EXEEXT) + @p='t-007$(EXEEXT)'; \ + b='t-007'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) .hawk.log: @p='$<'; \ $(am__set_b); \ @@ -1171,6 +1210,7 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/t_004-t-004.Po -rm -f ./$(DEPDIR)/t_005-t-005.Po -rm -f ./$(DEPDIR)/t_006-t-006.Po + -rm -f ./$(DEPDIR)/t_007-t-007.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -1222,6 +1262,7 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/t_004-t-004.Po -rm -f ./$(DEPDIR)/t_005-t-005.Po -rm -f ./$(DEPDIR)/t_006-t-006.Po + -rm -f ./$(DEPDIR)/t_007-t-007.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic