diff --git a/hawk/Makefile.in b/hawk/Makefile.in index 6b25e600..002e65f8 100644 --- a/hawk/Makefile.in +++ b/hawk/Makefile.in @@ -170,7 +170,7 @@ am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/ac/ar-lib \ $(top_srcdir)/ac/config.sub $(top_srcdir)/ac/install-sh \ $(top_srcdir)/ac/ltmain.sh $(top_srcdir)/ac/missing \ $(top_srcdir)/ac/tap-driver.sh $(top_srcdir)/pkgs/hawk.spec.in \ - ac/ar-lib ac/compile ac/config.guess ac/config.sub ac/depcomp \ + ac/ar-lib ac/compile ac/config.guess ac/config.sub \ ac/install-sh ac/ltmain.sh ac/missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) diff --git a/hawk/bin/hawk.c b/hawk/bin/hawk.c index b8a9db72..4b189561 100644 --- a/hawk/bin/hawk.c +++ b/hawk/bin/hawk.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -37,8 +38,6 @@ #include #include -#define HAWK_MEMSET memset - // #define ENABLE_CALLBACK TODO: enable this back #define ABORT(label) goto label @@ -196,7 +195,7 @@ static int set_signal_handler (int sig, sig_handler_t handler, int extra_flags) if (sigaction(sig, HAWK_NULL, &oldsa) == -1) return -1; - HAWK_MEMSET (&sa, 0, HAWK_SIZEOF(sa)); + memset (&sa, 0, HAWK_SIZEOF(sa)); if (oldsa.sa_flags & SA_SIGINFO) { sa.sa_sigaction = dispatch_siginfo; @@ -240,7 +239,7 @@ static int unset_signal_handler (int sig) if (!g_sig_state[sig].handler) return -1; /* not set */ #if defined(HAVE_SIGACTION) - HAWK_MEMSET (&sa, 0, HAWK_SIZEOF(sa)); + memset (&sa, 0, HAWK_SIZEOF(sa)); sa.sa_mask = g_sig_state[sig].old_sa_mask; sa.sa_flags = g_sig_state[sig].old_sa_flags; @@ -593,7 +592,7 @@ static void purge_xarg (xarg_t* xarg) } } -static int expand_wildcard (int argc, hawk_bch_t* argv[], int glob, xarg_t* xarg) +static int expand_wildcard (int argc, hawk_bch_t* argv[], int do_glob, xarg_t* xarg) { int i; hawk_bcs_t tmp; @@ -602,23 +601,22 @@ static int expand_wildcard (int argc, hawk_bch_t* argv[], int glob, xarg_t* xarg { int x; -#if 0 -// TOOD: revive this part - if (glob) + if (do_glob) { + int glob_flags; + hawk_gem_t fake_gem; /* guly to use this fake gem here */ + + glob_flags = HAWK_GLOB_TOLERANT | HAWK_GLOB_PERIOD; #if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) - int glob_flags = HAWK_GLOB_TOLERANT | HAWK_GLOB_PERIOD | HAWK_GLOB_NOESCAPE | HAWK_GLOB_IGNORECASE; - #else - int glob_flags = HAWK_GLOB_TOLERANT | HAWK_GLOB_PERIOD; + glob_flags |= HAWK_GLOB_NOESCAPE | HAWK_GLOB_IGNORECASE; #endif - x = hawk_glob(argv[i], collect_into_xarg, xarg, glob_flags, xarg->mmgr, hawk_getdflcmgr()); + fake_gem.mmgr = hawk_get_sys_mmgr(); + fake_gem.cmgr = hawk_get_cmgr_by_id(HAWK_CMGR_UTF8); /* TODO: system default? */ + x = hawk_gem_bglob(&fake_gem, argv[i], collect_into_xarg, xarg, glob_flags); if (x <= -1) return -1; } else x = 0; -#else - x = 0; -#endif if (x == 0) { @@ -698,7 +696,7 @@ static int process_argv (int argc, hawk_bch_t* argv[], struct arg_t* arg) int oops_ret = -1; int do_glob = 0; - HAWK_MEMSET (arg, 0, HAWK_SIZEOF(*arg)); + memset (arg, 0, HAWK_SIZEOF(*arg)); isf = (hawk_parsestd_t*)malloc(HAWK_SIZEOF(*isf) * isfc); if (!isf) @@ -962,7 +960,7 @@ static int process_argv (int argc, hawk_bch_t* argv[], struct arg_t* arg) if (opt.ind < argc) { /* the remaining arguments are input console file names */ - if (expand_wildcard(argc - opt.ind, &argv[opt.ind], do_glob, &arg->icf) <= -1) + if (expand_wildcard(argc - opt.ind, &argv[opt.ind], do_glob, &arg->icf) <= -1) { print_error ("failed to expand wildcard\n"); goto oops; diff --git a/hawk/lib/Makefile.am b/hawk/lib/Makefile.am index 5f552df0..7960b4db 100644 --- a/hawk/lib/Makefile.am +++ b/hawk/lib/Makefile.am @@ -32,11 +32,14 @@ endif endif EXTRA_DIST = \ + gem-glob.c.m4 \ + gem-glob.m4 \ hawk-str.h.m4 \ utl-str.c.m4 \ utl-str.m4 BUILT_SOURCES = \ + gem-glob.c \ hawk-str.h \ utl-str.c @@ -55,6 +58,7 @@ pkginclude_HEADERS = \ hawk-ecs.h \ hawk-fmt.h \ hawk-gem.h \ + hawk-glob.h \ hawk-htb.h \ hawk-map.h \ hawk-rbt.h \ @@ -90,6 +94,7 @@ libhawk_la_SOURCES = \ fnc.c \ htb.c \ gem.c \ + gem-glob.c \ gem-nwif.c \ gem-nwif2.c \ hawk-prv.h \ @@ -293,6 +298,8 @@ install-data-hook: uninstall-hook: @rm -f "$(DESTDIR)$(pkgincludedir)/hawk-cfg.h" +gem-glob.c: gem-glob.m4 gem-glob.c.m4 + m4 -I$(srcdir) $(srcdir)/gem-glob.c.m4 > $(srcdir)/gem-glob.c hawk-str.h: utl-str.m4 hawk-str.h.m4 m4 -I$(srcdir) $(srcdir)/hawk-str.h.m4 > $(srcdir)/hawk-str.h diff --git a/hawk/lib/Makefile.in b/hawk/lib/Makefile.in index 22736aff..989f9b5f 100644 --- a/hawk/lib/Makefile.in +++ b/hawk/lib/Makefile.in @@ -229,25 +229,25 @@ libhawk_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_4) $(am__DEPENDENCIES_5) $(am__append_11) \ $(am__append_12) $(am__append_13) $(am__append_14) am__libhawk_la_SOURCES_DIST = hawk.h hawk-arr.h hawk-chr.h hawk-cmn.h \ - hawk-dir.h hawk-ecs.h hawk-fmt.h hawk-gem.h hawk-htb.h \ - hawk-map.h hawk-rbt.h hawk-pac1.h hawk-skad.h hawk-utl.h \ - hawk-sed.h hawk-std.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-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 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 hawk-cli.h hawk-fio.h hawk-mtx.h hawk-pio.h \ - hawk-sio.h hawk-tio.h 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 + hawk-dir.h hawk-ecs.h hawk-fmt.h hawk-gem.h hawk-glob.h \ + hawk-htb.h hawk-map.h hawk-rbt.h hawk-pac1.h hawk-skad.h \ + hawk-utl.h hawk-sed.h hawk-std.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 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 hawk-cli.h hawk-fio.h hawk-mtx.h \ + hawk-pio.h hawk-sio.h hawk-tio.h 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 am__objects_1 = am__objects_2 = $(am__objects_1) @ENABLE_CXX_TRUE@am__objects_3 = libhawk_la-Hawk.lo libhawk_la-Std.lo \ @@ -260,11 +260,11 @@ 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-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-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 \ @@ -302,6 +302,7 @@ am__depfiles_remade = ./$(DEPDIR)/libhawk_hawk_la-mod-hawk.Plo \ ./$(DEPDIR)/libhawk_la-err-sys.Plo \ ./$(DEPDIR)/libhawk_la-err.Plo ./$(DEPDIR)/libhawk_la-fio.Plo \ ./$(DEPDIR)/libhawk_la-fmt.Plo ./$(DEPDIR)/libhawk_la-fnc.Plo \ + ./$(DEPDIR)/libhawk_la-gem-glob.Plo \ ./$(DEPDIR)/libhawk_la-gem-nwif.Plo \ ./$(DEPDIR)/libhawk_la-gem-nwif2.Plo \ ./$(DEPDIR)/libhawk_la-gem.Plo ./$(DEPDIR)/libhawk_la-hawk.Plo \ @@ -392,10 +393,10 @@ am__can_run_installinfo = \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__pkginclude_HEADERS_DIST = hawk.h hawk-arr.h hawk-chr.h hawk-cmn.h \ - hawk-dir.h hawk-ecs.h hawk-fmt.h hawk-gem.h hawk-htb.h \ - hawk-map.h hawk-rbt.h hawk-pac1.h hawk-skad.h hawk-utl.h \ - hawk-sed.h hawk-std.h hawk-tre.h hawk-upac.h hawk-xma.h \ - Hawk.hpp Hawk-Sed.hpp + hawk-dir.h hawk-ecs.h hawk-fmt.h hawk-gem.h hawk-glob.h \ + hawk-htb.h hawk-map.h hawk-rbt.h hawk-pac1.h hawk-skad.h \ + hawk-utl.h hawk-sed.h hawk-std.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 @@ -603,34 +604,37 @@ CXXFLAGS_ALL_COMMON = @WIN32_TRUE@ -DHAWK_DEFAULT_MODPOSTFIX=\"-1.dll\" \ @WIN32_TRUE@ $(am__append_1) $(am__append_2) EXTRA_DIST = \ + gem-glob.c.m4 \ + gem-glob.m4 \ hawk-str.h.m4 \ utl-str.c.m4 \ utl-str.m4 BUILT_SOURCES = \ + gem-glob.c \ hawk-str.h \ utl-str.c pkginclude_HEADERS = hawk.h hawk-arr.h hawk-chr.h hawk-cmn.h \ - hawk-dir.h hawk-ecs.h hawk-fmt.h hawk-gem.h hawk-htb.h \ - hawk-map.h hawk-rbt.h hawk-pac1.h hawk-skad.h hawk-utl.h \ - hawk-sed.h hawk-std.h hawk-tre.h hawk-upac.h hawk-xma.h \ - $(am__append_7) + hawk-dir.h hawk-ecs.h hawk-fmt.h hawk-gem.h hawk-glob.h \ + hawk-htb.h hawk-map.h hawk-rbt.h hawk-pac1.h hawk-skad.h \ + hawk-utl.h hawk-sed.h hawk-std.h hawk-tre.h hawk-upac.h \ + hawk-xma.h $(am__append_7) pkglib_LTLIBRARIES = libhawk.la $(am__append_15) 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-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 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 hawk-cli.h hawk-fio.h hawk-mtx.h hawk-pio.h \ - hawk-sio.h hawk-tio.h 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) \ + 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 \ + 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 hawk-cli.h hawk-fio.h hawk-mtx.h \ + hawk-pio.h hawk-sio.h hawk-tio.h 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) \ $(am__append_9) libhawk_la_CPPFLAGS = $(CPPFLAGS_ALL_COMMON) $(CPPFLAGS_PFMOD) \ $(am__append_3) @@ -805,6 +809,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_la-fio.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_la-fmt.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_la-fnc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_la-gem-glob.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_la-gem-nwif.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_la-gem-nwif2.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhawk_la-gem.Plo@am__quote@ # am--include-marker @@ -982,6 +987,13 @@ libhawk_la-gem.lo: gem.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-gem.lo `test -f 'gem.c' || echo '$(srcdir)/'`gem.c +libhawk_la-gem-glob.lo: gem-glob.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-glob.lo -MD -MP -MF $(DEPDIR)/libhawk_la-gem-glob.Tpo -c -o libhawk_la-gem-glob.lo `test -f 'gem-glob.c' || echo '$(srcdir)/'`gem-glob.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhawk_la-gem-glob.Tpo $(DEPDIR)/libhawk_la-gem-glob.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gem-glob.c' object='libhawk_la-gem-glob.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-gem-glob.lo `test -f 'gem-glob.c' || echo '$(srcdir)/'`gem-glob.c + libhawk_la-gem-nwif.lo: gem-nwif.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-nwif.lo -MD -MP -MF $(DEPDIR)/libhawk_la-gem-nwif.Tpo -c -o libhawk_la-gem-nwif.lo `test -f 'gem-nwif.c' || echo '$(srcdir)/'`gem-nwif.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhawk_la-gem-nwif.Tpo $(DEPDIR)/libhawk_la-gem-nwif.Plo @@ -1522,6 +1534,7 @@ distclean: distclean-am -rm -f ./$(DEPDIR)/libhawk_la-fio.Plo -rm -f ./$(DEPDIR)/libhawk_la-fmt.Plo -rm -f ./$(DEPDIR)/libhawk_la-fnc.Plo + -rm -f ./$(DEPDIR)/libhawk_la-gem-glob.Plo -rm -f ./$(DEPDIR)/libhawk_la-gem-nwif.Plo -rm -f ./$(DEPDIR)/libhawk_la-gem-nwif2.Plo -rm -f ./$(DEPDIR)/libhawk_la-gem.Plo @@ -1631,6 +1644,7 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libhawk_la-fio.Plo -rm -f ./$(DEPDIR)/libhawk_la-fmt.Plo -rm -f ./$(DEPDIR)/libhawk_la-fnc.Plo + -rm -f ./$(DEPDIR)/libhawk_la-gem-glob.Plo -rm -f ./$(DEPDIR)/libhawk_la-gem-nwif.Plo -rm -f ./$(DEPDIR)/libhawk_la-gem-nwif2.Plo -rm -f ./$(DEPDIR)/libhawk_la-gem.Plo @@ -1735,6 +1749,9 @@ install-data-hook: uninstall-hook: @rm -f "$(DESTDIR)$(pkgincludedir)/hawk-cfg.h" +gem-glob.c: gem-glob.m4 gem-glob.c.m4 + m4 -I$(srcdir) $(srcdir)/gem-glob.c.m4 > $(srcdir)/gem-glob.c + hawk-str.h: utl-str.m4 hawk-str.h.m4 m4 -I$(srcdir) $(srcdir)/hawk-str.h.m4 > $(srcdir)/hawk-str.h diff --git a/hawk/lib/dir.c b/hawk/lib/dir.c index f8d7309b..a44e3572 100644 --- a/hawk/lib/dir.c +++ b/hawk/lib/dir.c @@ -135,16 +135,16 @@ int hawk_dir_init (hawk_dir_t* dir, hawk_gem_t* gem, const hawk_ooch_t* path, in int n; int path_flags; - path_flags = flags & (HAWK_DIR_MBSPATH | HAWK_DIR_WCSPATH); - if (path_flags == (HAWK_DIR_MBSPATH | HAWK_DIR_WCSPATH) || path_flags == 0) + path_flags = flags & (HAWK_DIR_BPATH | HAWK_DIR_UPATH); + if (path_flags == (HAWK_DIR_BPATH | HAWK_DIR_UPATH) || path_flags == 0) { /* if both are set or none are set, force it to the default */ #if defined(HAWK_OOCH_IS_BCH) - flags |= HAWK_DIR_MBSPATH; - flags &= ~HAWK_DIR_WCSPATH; + flags |= HAWK_DIR_BPATH; + flags &= ~HAWK_DIR_UPATH; #else - flags |= HAWK_DIR_WCSPATH; - flags &= ~HAWK_DIR_MBSPATH; + flags |= HAWK_DIR_UPATH; + flags &= ~HAWK_DIR_BPATH; #endif } @@ -294,62 +294,6 @@ static hawk_uch_t* make_wcsdos_path (hawk_dir_t* dir, const hawk_uch_t* wpath) } #endif -/* -static hawk_ooch_t* make_dos_path (hawk_dir_t* dir, const hawk_ooch_t* path) -{ - if (path[0] == HAWK_T('\0')) - { - if (hawk_str_cpy (&dir->tbuf, HAWK_T("*.*")) == (hawk_oow_t)-1) - { - dir->errnum = HAWK_DIR_ENOMEM; - return HAWK_NULL; - } - } - else - { - hawk_oow_t len; - if ((len = hawk_str_cpy (&dir->tbuf, path)) == (hawk_oow_t)-1 || - (!HAWK_ISPATHSEP(path[len - 1]) && - !hawk_isdrivecurpath(path) && - hawk_str_ccat (&dir->tbuf, HAWK_T('\\')) == (hawk_oow_t)-1) || - hawk_str_cat (&dir->tbuf, HAWK_T("*.*")) == (hawk_oow_t)-1) - { - dir->errnum = HAWK_DIR_ENOMEM; - return HAWK_NULL; - } - } - - return HAWK_STR_PTR(&dir->tbuf); -} - -static hawk_bch_t* mkdospath (hawk_dir_t* dir, const hawk_ooch_t* path) -{ - -#if defined(HAWK_OOCH_IS_BCH) - return make_dos_path (dir, path); -#else - if (dir->flags & HAWK_DIR_MBSPATH) - { - return make_mbsdos_path (dir, (const hawk_bch_t*) path); - } - else - { - hawk_ooch_t* tptr; - hawk_bch_t* mptr; - - tptr = make_dos_path (dir, path); - if (tptr == HAWK_NULL) return HAWK_NULL; - - mptr = wcs_to_mbuf (dir, HAWK_STR_PTR(&dir->tbuf), &dir->mbuf); - if (mptr == HAWK_NULL) return HAWK_NULL; - - return mptr; - } -#endif - -} -*/ - static int reset_to_path (hawk_dir_t* dir, const hawk_ooch_t* path) { #if defined(_WIN32) @@ -361,7 +305,7 @@ static int reset_to_path (hawk_dir_t* dir, const hawk_ooch_t* path) dir->status &= ~STATUS_DONE; dir->status &= ~STATUS_DONE_ERR; - if (dir->flags & HAWK_DIR_MBSPATH) + if (dir->flags & HAWK_DIR_BPATH) { hawk_bch_t* mptr; @@ -377,7 +321,7 @@ static int reset_to_path (hawk_dir_t* dir, const hawk_ooch_t* path) else { hawk_uch_t* wptr; - HAWK_ASSERT (dir->flags & HAWK_DIR_WCSPATH); + HAWK_ASSERT (dir->flags & HAWK_DIR_UPATH); wptr = make_wcsdos_path(dir, (const hawk_uch_t*)path); if (wptr == HAWK_NULL) return -1; @@ -417,14 +361,14 @@ static int reset_to_path (hawk_dir_t* dir, const hawk_ooch_t* path) #endif ULONG count = 1; - if (dir->flags & HAWK_DIR_MBSPATH) + if (dir->flags & HAWK_DIR_BPATH) { mptr = make_mbsdos_path (dir, (const hawk_bch_t*)path); } else { hawk_uch_t* wptr; - HAWK_ASSERT (dir->flags & HAWK_DIR_WCSPATH); + HAWK_ASSERT (dir->flags & HAWK_DIR_UPATH); wptr = make_wcsdos_path(dir, (const hawk_uch_t*)path); if (wptr == HAWK_NULL) return -1; @@ -471,7 +415,7 @@ static int reset_to_path (hawk_dir_t* dir, const hawk_ooch_t* path) dir->status &= ~STATUS_DONE; dir->status &= ~STATUS_DONE_ERR; - if (dir->flags & HAWK_DIR_MBSPATH) + if (dir->flags & HAWK_DIR_BPATH) { mptr = make_mbsdos_path(dir, (const hawk_bch_t*)path); } @@ -479,7 +423,7 @@ static int reset_to_path (hawk_dir_t* dir, const hawk_ooch_t* path) { hawk_uch_t* wptr; - HAWK_ASSERT (dir->flags & HAWK_DIR_WCSPATH); + HAWK_ASSERT (dir->flags & HAWK_DIR_UPATH); wptr = make_wcsdos_path(dir, (const hawk_uch_t*)path); if (wptr == HAWK_NULL) return -1; @@ -504,7 +448,7 @@ static int reset_to_path (hawk_dir_t* dir, const hawk_ooch_t* path) #else DIR* dp; - if (dir->flags & HAWK_DIR_MBSPATH) + if (dir->flags & HAWK_DIR_BPATH) { const hawk_bch_t* mpath = (const hawk_bch_t*)path; dp = HAWK_OPENDIR(mpath[0] == '\0'? ".": mpath); @@ -512,7 +456,7 @@ static int reset_to_path (hawk_dir_t* dir, const hawk_ooch_t* path) else { const hawk_uch_t* wpath; - /*HAWK_ASSERT (dir->flags & HAWK_DIR_WCSPATH);*/ + /*HAWK_ASSERT (dir->flags & HAWK_DIR_UPATH);*/ wpath = (const hawk_uch_t*)path; if (wpath[0] == '\0') @@ -595,7 +539,7 @@ static int read_dir_to_buf (hawk_dir_t* dir, void** name) } } - if (dir->flags & HAWK_DIR_MBSPATH) + if (dir->flags & HAWK_DIR_BPATH) { #if defined(HAWK_OOCH_IS_BCH) if (mbs_to_mbuf(dir, dir->wfd.cFileName, &dir->mbuf) == HAWK_NULL) return -1; @@ -606,7 +550,7 @@ static int read_dir_to_buf (hawk_dir_t* dir, void** name) } else { - HAWK_ASSERT (dir->flags & HAWK_DIR_WCSPATH); + HAWK_ASSERT (dir->flags & HAWK_DIR_UPATH); #if defined(HAWK_OOCH_IS_BCH) if (mbs_to_wbuf(dir, dir->wfd.cFileName, &dir->wbuf) == HAWK_NULL) return -1; #else @@ -656,14 +600,14 @@ static int read_dir_to_buf (hawk_dir_t* dir, void** name) } } - if (dir->flags & HAWK_DIR_MBSPATH) + if (dir->flags & HAWK_DIR_BPATH) { if (mbs_to_mbuf (dir, dir->ffb.achName, &dir->mbuf) == HAWK_NULL) return -1; *name = HAWK_BECS_PTR(&dir->mbuf); } else { - HAWK_ASSERT (dir->flags & HAWK_DIR_WCSPATH); + HAWK_ASSERT (dir->flags & HAWK_DIR_UPATH); if (mbs_to_wbuf (dir, dir->ffb.achName, &dir->wbuf) == HAWK_NULL) return -1; *name = HAWK_UECS_PTR(&dir->wbuf); } @@ -709,14 +653,14 @@ static int read_dir_to_buf (hawk_dir_t* dir, void** name) } } - if (dir->flags & HAWK_DIR_MBSPATH) + if (dir->flags & HAWK_DIR_BPATH) { if (mbs_to_mbuf (dir, dir->f.name, &dir->mbuf) == HAWK_NULL) return -1; *name = HAWK_BECS_PTR(&dir->mbuf); } else { - HAWK_ASSERT (dir->flags & HAWK_DIR_WCSPATH); + HAWK_ASSERT (dir->flags & HAWK_DIR_UPATH); if (mbs_to_wbuf (dir, dir->f.name, &dir->wbuf) == HAWK_NULL) return -1; *name = HAWK_UECS_PTR(&dir->wbuf); @@ -754,18 +698,17 @@ read: if (dir->flags & HAWK_DIR_SKIPSPCDIR) { /* skip . and .. */ - if (IS_CURDIR(de->d_name) || - IS_PREVDIR(de->d_name)) goto read; + if (IS_CURDIR(de->d_name) || IS_PREVDIR(de->d_name)) goto read; } - if (dir->flags & HAWK_DIR_MBSPATH) + if (dir->flags & HAWK_DIR_BPATH) { if (mbs_to_mbuf(dir, de->d_name, &dir->mbuf) == HAWK_NULL) return -1; *name = HAWK_BECS_PTR(&dir->mbuf); } else { - /*HAWK_ASSERT (dir->flags & HAWK_DIR_WCSPATH);*/ + /*HAWK_ASSERT (dir->flags & HAWK_DIR_UPATH);*/ if (mbs_to_wbuf(dir, de->d_name, &dir->wbuf) == HAWK_NULL) return -1; *name = HAWK_UECS_PTR(&dir->wbuf); } @@ -788,7 +731,7 @@ static int read_ahead_and_sort (hawk_dir_t* dir, const hawk_ooch_t* path) { hawk_oow_t size; - if (dir->flags & HAWK_DIR_MBSPATH) + if (dir->flags & HAWK_DIR_BPATH) size = (hawk_count_bcstr(name) + 1) * HAWK_SIZEOF(hawk_bch_t); else size = (hawk_count_ucstr(name) + 1) * HAWK_SIZEOF(hawk_uch_t); diff --git a/hawk/lib/gem-glob.c.m4 b/hawk/lib/gem-glob.c.m4 new file mode 100644 index 00000000..56b8c1b1 --- /dev/null +++ b/hawk/lib/gem-glob.c.m4 @@ -0,0 +1,170 @@ +/* + 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. + */ + +/* + * Do NOT edit glob.c. Edit glob.c.m4 instead. + * + * Generate gem-glob.c with m4 + * $ m4 gem-glob.c.m4 > gem-glob.c + */ + +#include "hawk-prv.h" +#include +#include +#include +#include + +#include "syscall.h" + +#define NO_RECURSION 1 + +enum segment_type_t +{ + NONE, + ROOT, + NORMAL +}; +typedef enum segment_type_t segment_type_t; + + +#define IS_ESC(c) HAWK_FNMAT_IS_ESC(c) +#define IS_SEP(c) HAWK_FNMAT_IS_SEP(c) +#define IS_NIL(c) ((c) == '\0') +#define IS_SEP_OR_NIL(c) (IS_SEP(c) || IS_NIL(c)) + +/* this macro only checks for top-level wild-cards among these. + * *, ?, [], !, - + * see str-fnmat.c for more wild-card letters + */ +#define IS_WILD(c) ((c) == '*' || (c) == '?' || (c) == '[') + + +static hawk_bch_t* wcs_to_mbuf (hawk_gem_t* g, const hawk_uch_t* wcs, hawk_becs_t* mbuf) +{ + hawk_oow_t ml, wl; + + if (hawk_gem_convutobcstr(g, wcs, &wl, HAWK_NULL, &ml) <= -1 || + hawk_becs_setlen(mbuf, ml) == (hawk_oow_t)-1) return HAWK_NULL; + + hawk_gem_convutobcstr (g, wcs, &wl, HAWK_BECS_PTR(mbuf), &ml); + return HAWK_BECS_PTR(mbuf); +} + +#if defined(_WIN32) && !defined(INVALID_FILE_ATTRIBUTES) +#define INVALID_FILE_ATTRIBUTES ((DWORD)-1) +#endif + +static int upath_exists (hawk_gem_t* g, const hawk_uch_t* name, hawk_becs_t* mbuf) +{ +#if defined(_WIN32) + return (GetFileAttributesW(name) != INVALID_FILE_ATTRIBUTES)? 1: 0; + +#elif defined(__OS2__) + FILESTATUS3 fs; + APIRET rc; + const hawk_bch_t* mptr; + + mptr = wcs_to_mbuf(g, name, mbuf); + if (HAWK_UNLIKELY(!mptr)) return -1; + + rc = DosQueryPathInfo(mptr, FIL_STANDARD, &fs, HAWK_SIZEOF(fs)); + return (rc == NO_ERROR)? 1: ((rc == ERROR_PATH_NOT_FOUND)? 0: -1); + +#elif defined(__DOS__) + unsigned int x, attr; + const hawk_bch_t* mptr; + + mptr = wcs_to_mbuf(g, name, mbuf); + if (HAWK_UNLIKELY(!mptr)) return -1; + + x = _dos_getfileattr (mptr, &attr); + return (x == 0)? 1: ((errno == ENOENT)? 0: -1); + +#elif defined(macintosh) + HFileInfo fpb; + const hawk_bch_t* mptr; + + mptr = wcs_to_mbuf(g, name, mbuf); + if (HAWK_UNLIKELY(!mptr)) return -1; + + HAWK_MEMSET (&fpb, 0, HAWK_SIZEOF(fpb)); + fpb.ioNamePtr = (unsigned char*)mptr; + + return (PBGetCatInfoSync ((CInfoPBRec*)&fpb) == noErr)? 1: 0; +#else + struct stat st; + const hawk_bch_t* mptr; + int t; + + mptr = wcs_to_mbuf(g, name, mbuf); + if (HAWK_UNLIKELY(!mptr)) return -1; + + #if defined(HAVE_LSTAT) + t = HAWK_LSTAT(mptr, &st); + #else + t = HAWK_STAT(mptr, &st);/* use stat() if no lstat() is available. */ + #endif + return (t == 0); +#endif +} + +static int bpath_exists (hawk_gem_t* g, const hawk_bch_t* name, hawk_becs_t* mbuf) +{ +#if defined(_WIN32) + return (GetFileAttributesA(name) != INVALID_FILE_ATTRIBUTES)? 1: 0; +#elif defined(__OS2__) + + FILESTATUS3 fs; + APIRET rc; + rc = DosQueryPathInfo(name, FIL_STANDARD, &fs, HAWK_SIZEOF(fs)); + return (rc == NO_ERROR)? 1: ((rc == ERROR_PATH_NOT_FOUND)? 0: -1); + +#elif defined(__DOS__) + unsigned int x, attr; + x = _dos_getfileattr(name, &attr); + return (x == 0)? 1: ((errno == ENOENT)? 0: -1); + +#elif defined(macintosh) + HFileInfo fpb; + HAWK_MEMSET (&fpb, 0, HAWK_SIZEOF(fpb)); + fpb.ioNamePtr = (unsigned char*)name; + return (PBGetCatInfoSync((CInfoPBRec*)&fpb) == noErr)? 1: 0; +#else + struct stat st; + int t; + #if defined(HAVE_LSTAT) + t = HAWK_LSTAT(name, &st); + #else + t = HAWK_STAT(name, &st); /* use stat() if no lstat() is available. */ + #endif + return (t == 0); +#endif +} + +dnl +dnl --------------------------------------------------------------------------- +include(`gem-glob.m4')dnl +dnl --------------------------------------------------------------------------- +fn_glob(hawk_gem_uglob, hawk_uch_t, hawk_ucs_t, hawk_uecs, HAWK_UECS, hawk_gem_uglob_cb_t, upath_exists, hawk_fnmat_ucstr_uchars, __u) +fn_glob(hawk_gem_bglob, hawk_bch_t, hawk_bcs_t, hawk_becs, HAWK_BECS, hawk_gem_bglob_cb_t, bpath_exists, hawk_fnmat_bcstr_bchars, __b) diff --git a/hawk/lib/gem-glob.m4 b/hawk/lib/gem-glob.m4 new file mode 100644 index 00000000..0d1c8276 --- /dev/null +++ b/hawk/lib/gem-glob.m4 @@ -0,0 +1,472 @@ +dnl --------------------------------------------------------------------------- +changequote(`[[', `]]')dnl +dnl --------------------------------------------------------------------------- + +define([[fn_glob]], [[ +pushdef([[_fn_name_]], $1)dnl +pushdef([[_char_type_]], $2)dnl +pushdef([[_cs_type_]], $3)dnl +pushdef([[_ecs_prefix_]], $4)dnl +pushdef([[_ECS_PREFIX_]], $5)dnl +pushdef([[_cb_type_]], $6)dnl +pushdef([[_path_exists_]], $7)dnl +pushdef([[_fnmat_]], $8)dnl +pushdef([[_g_prefix_]], $9)dnl + +#if defined(NO_RECURSION) +typedef struct _g_prefix_()_stack_node_t _g_prefix_()_stack_node_t; +#endif + +struct _g_prefix_()_glob_t +{ + _cb_type_ cbimpl; + void* cbctx; + + hawk_gem_t* gem; + int flags; + + _ecs_prefix_()_t path; + _ecs_prefix_()_t tbuf; /* temporary buffer */ + + hawk_becs_t mbuf; /* not used if the base character type is hawk_bch_t */ + + int expanded; + int fnmat_flags; + +#if defined(NO_RECURSION) + _g_prefix_()_stack_node_t* stack; + _g_prefix_()_stack_node_t* free; +#endif +}; + +typedef struct _g_prefix_()_glob_t _g_prefix_()_glob_t; + +struct _g_prefix_()_segment_t +{ + segment_type_t type; + + const _char_type_* ptr; + hawk_oow_t len; + + _char_type_ sep; /* preceeding separator */ + unsigned int wild: 1; /* indicate that it contains wildcards */ + unsigned int esc: 1; /* indicate that it contains escaped letters */ + unsigned int next: 1; /* indicate that it has the following segment */ +}; +typedef struct _g_prefix_()_segment_t _g_prefix_()_segment_t; + +#if defined(NO_RECURSION) +struct _g_prefix_()_stack_node_t +{ + hawk_oow_t tmp; + hawk_oow_t tmp2; + hawk_dir_t* dp; + _g_prefix_()_segment_t seg; + _g_prefix_()_stack_node_t* next; +}; +#endif + +static int _g_prefix_()_get_next_segment (_g_prefix_()_glob_t* g, _g_prefix_()_segment_t* seg) +{ + if (seg->type == NONE) + { + /* seg->ptr must point to the beginning of the pattern + * and seg->len must be zero when seg->type is NONE. */ + if (IS_NIL(seg->ptr[0])) + { + /* nothing to do */ + } + else if (IS_SEP(seg->ptr[0])) + { + seg->type = ROOT; + seg->len = 1; + seg->next = IS_NIL(seg->ptr[1])? 0: 1; + seg->sep = '\0'; + seg->wild = 0; + seg->esc = 0; + } + #if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) + else if (IS_DRIVE(seg->ptr)) + { + seg->type = ROOT; + seg->len = 2; + if (IS_SEP(seg->ptr[2])) seg->len++; + seg->next = IS_NIL(seg->ptr[seg->len])? 0: 1; + seg->sep = '\0'; + seg->wild = 0; + seg->esc = 0; + } + #endif + else + { + int escaped = 0; + seg->type = NORMAL; + seg->sep = '\0'; + seg->wild = 0; + seg->esc = 0; + do + { + if (escaped) escaped = 0; + else + { + if (IS_ESC(seg->ptr[seg->len])) + { + escaped = 1; + seg->esc = 1; + } + else if (IS_WILD(seg->ptr[seg->len])) seg->wild = 1; + } + + seg->len++; + } + while (!IS_SEP_OR_NIL(seg->ptr[seg->len])); + seg->next = IS_NIL(seg->ptr[seg->len])? 0: 1; + } + } + else if (seg->type == ROOT) + { + int escaped = 0; + seg->type = NORMAL; + seg->ptr = &seg->ptr[seg->len]; + seg->len = 0; + seg->sep = '\0'; + seg->wild = 0; + seg->esc = 0; + + while (!IS_SEP_OR_NIL(seg->ptr[seg->len])) + { + if (escaped) escaped = 0; + else + { + if (IS_ESC(seg->ptr[seg->len])) + { + escaped = 1; + seg->esc = 1; + } + else if (IS_WILD(seg->ptr[seg->len])) seg->wild = 1; + } + seg->len++; + } + seg->next = IS_NIL(seg->ptr[seg->len])? 0: 1; + } + else + { + HAWK_ASSERT (seg->type == NORMAL); + + seg->ptr = &seg->ptr[seg->len + 1]; + seg->len = 0; + seg->wild = 0; + seg->esc = 0; + if (IS_NIL(seg->ptr[-1])) + { + seg->type = NONE; + seg->next = 0; + seg->sep = '\0'; + } + else + { + int escaped = 0; + seg->sep = seg->ptr[-1]; + while (!IS_SEP_OR_NIL(seg->ptr[seg->len])) + { + if (escaped) escaped = 0; + else + { + if (IS_ESC(seg->ptr[seg->len])) + { + escaped = 1; + seg->esc = 1; + } + else if (IS_WILD(seg->ptr[seg->len])) seg->wild = 1; + } + seg->len++; + } + seg->next = IS_NIL(seg->ptr[seg->len])? 0: 1; + } + } + + return seg->type; +} + +static int _g_prefix_()_handle_non_wild_segments (_g_prefix_()_glob_t* g, _g_prefix_()_segment_t* seg) +{ + while (_g_prefix_()_get_next_segment(g, seg) != NONE && !seg->wild) + { + HAWK_ASSERT (seg->type != NONE && !seg->wild); + + if (seg->sep && _ecs_prefix_()_ccat (&g->path, seg->sep) == (hawk_oow_t)-1) return -1; + if (seg->esc) + { + /* if the segment contains escape sequences, + * strip the escape letters off the segment */ + + + _cs_type_ tmp; + hawk_oow_t i; + int escaped = 0; + + if (_ECS_PREFIX_()_CAPA(&g->tbuf) < seg->len && + _ecs_prefix_()_setcapa (&g->tbuf, seg->len) == (hawk_oow_t)-1) return -1; + + tmp.ptr = _ECS_PREFIX_()_PTR(&g->tbuf); + tmp.len = 0; + + /* the following loop drops the last character + * if it is the escape character */ + for (i = 0; i < seg->len; i++) + { + if (escaped) + { + escaped = 0; + tmp.ptr[tmp.len++] = seg->ptr[i]; + } + else + { + if (IS_ESC(seg->ptr[i])) + escaped = 1; + else + tmp.ptr[tmp.len++] = seg->ptr[i]; + } + } + + if (_ecs_prefix_()_ncat (&g->path, tmp.ptr, tmp.len) == (hawk_oow_t)-1) return -1; + } + else + { + /* if the segment doesn't contain escape sequences, + * append the segment to the path without special handling */ + if (_ecs_prefix_()_ncat (&g->path, seg->ptr, seg->len) == (hawk_oow_t)-1) return -1; + } + + if (!seg->next && _path_exists_()(g->gem, _ECS_PREFIX_()_PTR(&g->path), &g->mbuf) > 0) + { + /* reached the last segment. match if the path exists */ + if (g->cbimpl(_ECS_PREFIX_()_CS(&g->path), g->cbctx) <= -1) return -1; + g->expanded = 1; + } + } + + return 0; +} + +static int _g_prefix_()_search (_g_prefix_()_glob_t* g, _g_prefix_()_segment_t* seg) +{ + hawk_dir_t* dp; + hawk_oow_t tmp, tmp2; + hawk_dir_ent_t ent; + int x; + +#if defined(NO_RECURSION) + _g_prefix_()_stack_node_t* r; + +entry: +#endif + + dp = HAWK_NULL; + + if (_g_prefix_()_handle_non_wild_segments(g, seg) <= -1) goto oops; + + if (seg->wild) + { + int dir_flags = 0; + if (g->flags & HAWK_GLOB_SKIPSPCDIR) dir_flags |= HAWK_DIR_SKIPSPCDIR; + if (HAWK_SIZEOF(_char_type_) == HAWK_SIZEOF(hawk_bch_t)) dir_flags |= HAWK_DIR_BPATH; + + dp = hawk_dir_open(g->gem, 0, (const _char_type_*)_ECS_PREFIX_()_PTR(&g->path), dir_flags); + if (dp) + { + tmp = _ECS_PREFIX_()_LEN(&g->path); + + if (seg->sep && _ecs_prefix_()_ccat(&g->path, seg->sep) == (hawk_oow_t)-1) goto oops; + tmp2 = _ECS_PREFIX_()_LEN(&g->path); + + while (1) + { + _ecs_prefix_()_setlen (&g->path, tmp2); + + x = hawk_dir_read(dp, &ent); + if (x <= -1) + { + if (g->flags & HAWK_GLOB_TOLERANT) break; + else goto oops; + } + if (x == 0) break; + + if (_ecs_prefix_()_cat(&g->path, (const _char_type_*)ent.name) == (hawk_oow_t)-1) goto oops; + + if (_fnmat_()(_ECS_PREFIX_()_CPTR(&g->path,tmp2), seg->ptr, seg->len, g->fnmat_flags) > 0) + { + if (seg->next) + { + #if defined(NO_RECURSION) + if (g->free) + { + r = g->free; + g->free = r->next; + } + else + { + r = hawk_gem_allocmem(g->gem, HAWK_SIZEOF(*r)); + if (r == HAWK_NULL) goto oops; + } + + /* push key variables that must be restored + * into the stack. */ + r->tmp = tmp; + r->tmp2 = tmp2; + r->dp = dp; + r->seg = *seg; + + r->next = g->stack; + g->stack = r; + + /* move to the function entry point as if + * a recursive call has been made */ + goto entry; + + resume: + ; + + #else + _g_prefix_()_segment_t save; + int x; + + save = *seg; + x = _g_prefix_()_search(g, seg); + *seg = save; + if (x <= -1) goto oops; + #endif + } + else + { + if (g->cbimpl(_ECS_PREFIX_()_CS(&g->path), g->cbctx) <= -1) goto oops; + g->expanded = 1; + } + } + } + + _ecs_prefix_()_setlen (&g->path, tmp); + hawk_dir_close (dp); dp = HAWK_NULL; + } + } + + HAWK_ASSERT (dp == HAWK_NULL); + +#if defined(NO_RECURSION) + if (g->stack) + { + /* the stack is not empty. the emulated recusive call + * must have been made. restore the variables pushed + * and jump to the resumption point */ + r = g->stack; + g->stack = r->next; + + tmp = r->tmp; + tmp2 = r->tmp2; + dp = r->dp; + *seg = r->seg; + + /* link the stack node to the free list + * instead of freeing it here */ + r->next = g->free; + g->free = r; + + goto resume; + } + + while (g->free) + { + /* destory the free list */ + r = g->free; + g->free = r->next; + hawk_gem_freemem (g->gem, r); + } +#endif + + return 0; + +oops: + if (dp) hawk_dir_close (dp); + +#if defined(NO_RECURSION) + while (g->stack) + { + r = g->stack; + g->stack = r->next; + hawk_dir_close (r->dp); + hawk_gem_freemem (g->gem, r); + } + + while (g->free) + { + r = g->stack; + g->free = r->next; + hawk_gem_freemem (g->gem, r); + } +#endif + return -1; +} + +int _fn_name_ (hawk_gem_t* gem, const _char_type_* pattern, _cb_type_ cbimpl, void* cbctx, int flags) +{ + _g_prefix_()_segment_t seg; + _g_prefix_()_glob_t g; + int x; + + HAWK_MEMSET (&g, 0, HAWK_SIZEOF(g)); + g.gem = gem; + g.cbimpl = cbimpl; + g.cbctx = cbctx; + g.flags = flags; + +#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) + g.fnmat_flags |= HAWK_FNMAT_IGNORECASE; + g.fnmat_flags |= HAWK_FNMAT_NOESCAPE; +#else + if (flags & HAWK_GLOB_IGNORECASE) g.fnmat_flags |= HAWK_FNMAT_IGNORECASE; + if (flags & HAWK_GLOB_NOESCAPE) g.fnmat_flags |= HAWK_FNMAT_NOESCAPE; +#endif + if (flags & HAWK_GLOB_PERIOD) g.fnmat_flags |= HAWK_FNMAT_PERIOD; + + if (_ecs_prefix_()_init(&g.path, g.gem, 512) <= -1) return -1; + if (_ecs_prefix_()_init(&g.tbuf, g.gem, 256) <= -1) + { + _ecs_prefix_()_fini (&g.path); + return -1; + } + + if (HAWK_SIZEOF(_char_type_) != HAWK_SIZEOF(hawk_bch_t)) + { + if (hawk_becs_init(&g.mbuf, g.gem, 512) <= -1) + { + _ecs_prefix_()_fini (&g.path); + _ecs_prefix_()_fini (&g.path); + return -1; + } + } + + HAWK_MEMSET (&seg, 0, HAWK_SIZEOF(seg)); + seg.type = NONE; + seg.ptr = pattern; + seg.len = 0; + + x = _g_prefix_()_search(&g, &seg); + + if (HAWK_SIZEOF(_char_type_) != HAWK_SIZEOF(hawk_uch_t)) hawk_becs_fini (&g.mbuf); + _ecs_prefix_()_fini (&g.tbuf); + _ecs_prefix_()_fini (&g.path); + + if (x <= -1) return -1; + return g.expanded; +} + +popdef([[_g_prefix_]])dnl +popdef([[_fnmat_]])dnl +popdef([[_path_exists_]])dnl +popdef([[_cb_type_]])dnl +popdef([[_ECS_PREFIX_]])dnl +popdef([[_ecs_prefix_]])dnl +popdef([[_cs_type_]])dnl +popdef([[_char_type_]])dnl +popdef([[_fn_name_]])dnl +]])dnl diff --git a/hawk/lib/hawk-dir.h b/hawk/lib/hawk-dir.h index 36050540..9f103ea7 100644 --- a/hawk/lib/hawk-dir.h +++ b/hawk/lib/hawk-dir.h @@ -32,8 +32,8 @@ typedef struct hawk_dir_ent_t hawk_dir_ent_t; enum hawk_dir_flag_t { - HAWK_DIR_MBSPATH = (1 << 0), - HAWK_DIR_WCSPATH = (1 << 1), + HAWK_DIR_BPATH = (1 << 0), + HAWK_DIR_UPATH = (1 << 1), HAWK_DIR_SORT = (1 << 2), HAWK_DIR_SKIPSPCDIR = (1 << 3) /**< limited to normal entries excluding . and .. */ }; diff --git a/hawk/lib/hawk-ecs.h b/hawk/lib/hawk-ecs.h index 06b4953e..a0ab9d74 100644 --- a/hawk/lib/hawk-ecs.h +++ b/hawk/lib/hawk-ecs.h @@ -30,6 +30,7 @@ /** string pointer and length as a aggregate */ #define HAWK_BECS_BCS(s) (&((s)->val)) +#define HAWK_BECS_CS(s) (&((s)->val)) /** string length */ #define HAWK_BECS_LEN(s) ((s)->val.len) /** string pointer */ @@ -45,6 +46,7 @@ /** string pointer and length as a aggregate */ #define HAWK_UECS_UCS(s) (&((s)->val)) +#define HAWK_UECS_CS(s) (&((s)->val)) /** string length */ #define HAWK_UECS_LEN(s) ((s)->val.len) /** string pointer */ diff --git a/hawk/lib/hawk-str.h b/hawk/lib/hawk-str.h index b8219ce3..b433f5f0 100644 --- a/hawk/lib/hawk-str.h +++ b/hawk/lib/hawk-str.h @@ -38,22 +38,46 @@ + /* ========================================================================= * STRING * ========================================================================= */ -enum hawk_trim_oochars_flag_t +enum hawk_trim_flag_t { - HAWK_TRIM_OOCHARS_LEFT = (1 << 0), /**< trim leading spaces */ -#define HAWK_TRIM_OOCHARS_LEFT HAWK_TRIM_OOCHARS_LEFT -#define HAWK_TRIM_UCHARS_LEFT HAWK_TRIM_OOCHARS_LEFT -#define HAWK_TRIM_BCHARS_LEFT HAWK_TRIM_OOCHARS_LEFT - HAWK_TRIM_OOCHARS_RIGHT = (1 << 1) /**< trim trailing spaces */ -#define HAWK_TRIM_OOCHARS_RIGHT HAWK_TRIM_OOCHARS_RIGHT -#define HAWK_TRIM_UCHARS_RIGHT HAWK_TRIM_OOCHARS_RIGHT -#define HAWK_TRIM_BCHARS_RIGHT HAWK_TRIM_OOCHARS_RIGHT + HAWK_TRIM_LEFT = (1 << 0), /**< trim leading spaces */ +#define HAWK_TRIM_LEFT HAWK_TRIM_LEFT +#define HAWK_TRIM_OOCHARS_LEFT HAWK_TRIM_LEFT +#define HAWK_TRIM_UCHARS_LEFT HAWK_TRIM_LEFT +#define HAWK_TRIM_BCHARS_LEFT HAWK_TRIM_LEFT + HAWK_TRIM_RIGHT = (1 << 1) /**< trim trailing spaces */ +#define HAWK_TRIM_RIGHT HAWK_TRIM_RIGHT +#define HAWK_TRIM_OOCHARS_RIGHT HAWK_TRIM_RIGHT +#define HAWK_TRIM_UCHARS_RIGHT HAWK_TRIM_RIGHT +#define HAWK_TRIM_BCHARS_RIGHT HAWK_TRIM_RIGHT }; +enum hawk_fnmat_flag_t +{ + HAWK_FNMAT_PATHNAME = (1 << 0), +#define HAWK_FNMAT_PATHNAME HAWK_FNMAT_PATHNAME + HAWK_FNMAT_NOESCAPE = (1 << 1), +#define HAWK_FNMAT_NOESCAPE HAWK_FNMAT_NOESCAPE + HAWK_FNMAT_PERIOD = (1 << 2), +#define HAWK_FNMAT_PERIOD HAWK_FNMAT_PERIOD + HAWK_FNMAT_IGNORECASE = (1 << 3) +#define HAWK_FNMAT_IGNORECASE HAWK_FNMAT_IGNORECASE +}; + +#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) + /* i don't support escaping in these systems */ +# define HAWK_FNMAT_IS_ESC(c) (0) +# define HAWK_FNMAT_IS_SEP(c) ((c) == '/' || (c) == '\\') +#else +# define HAWK_FNMAT_IS_ESC(c) ((c) == '\\') +# define HAWK_FNMAT_IS_SEP(c) ((c) == '/') +#endif + #if defined(__cplusplus) extern "C" { #endif @@ -477,6 +501,34 @@ HAWK_EXPORT int hawk_split_bcstr ( ); +HAWK_EXPORT int hawk_fnmat_uchars_i ( + const hawk_uch_t* str, + hawk_oow_t slen, + const hawk_uch_t* ptn, + hawk_oow_t plen, + int flags, + int no_first_period +); + +HAWK_EXPORT int hawk_fnmat_bchars_i ( + const hawk_bch_t* str, + hawk_oow_t slen, + const hawk_bch_t* ptn, + hawk_oow_t plen, + int flags, + int no_first_period +); + +#define hawk_fnmat_uchars(str, slen, ptn, plen, flags) hawk_fnmat_uchars_i(str, slen, ptn, plen, flags, 0) +#define hawk_fnmat_ucstr(str, ptn, flags) hawk_fnmat_uchars_i(str, hawk_count_ucstr(str), ptn, hawk_count_ucstr(ptn), flags, 0) +#define hawk_fnmat_uchars_ucstr(str, slen, ptn, flags) hawk_fnmat_uchars_i(str, slen, ptn, hawk_count_ucstr(ptn), flags, 0) +#define hawk_fnmat_ucstr_uchars(str, ptn, plen, flags) hawk_fnmat_uchars_i(str, hawk_count_ucstr(str), ptn, plen, flags, 0) + +#define hawk_fnmat_bchars(str, slen, ptn, plen, flags) hawk_fnmat_bchars_i(str, slen, ptn, plen, flags, 0) +#define hawk_fnmat_bcstr(str, ptn, flags) hawk_fnmat_bchars_i(str, hawk_count_bcstr(str), ptn, hawk_count_bcstr(ptn), flags, 0) +#define hawk_fnmat_bchars_bcstr(str, slen, ptn, flags) hawk_fnmat_bchars_i(str, slen, ptn, hawk_count_bcstr(ptn), flags, 0) +#define hawk_fnmat_bcstr_bchars(str, ptn, plen, flags) hawk_fnmat_bchars_i(str, hawk_count_bcstr(str), ptn, plen, flags, 0) + #if defined(HAWK_OOCH_IS_UCH) # define hawk_count_oocstr hawk_count_ucstr # define hawk_count_oocstr_limited hawk_count_ucstr_limited @@ -519,6 +571,12 @@ HAWK_EXPORT int hawk_split_bcstr ( # define hawk_tokenize_oochars hawk_tokenize_uchars # define hawk_trim_oochars hawk_trim_uchars # define hawk_split_oocstr hawk_split_ucstr + +# define hawk_fnmat_oochars_i hawk_fnmat_uchars_i +# define hawk_fnmat_oochars hawk_fnmat_uchars +# define hawk_fnmat_oocstr hawk_fnmat_ucstr +# define hawk_fnmat_oochars_oocstr hawk_fnmat_uchars_ucstr +# define hawk_fnmat_oocstr_oochars hawk_fnmat_ucstr_uchars #else # define hawk_count_oocstr hawk_count_bcstr # define hawk_count_oocstr_limited hawk_count_bcstr_limited @@ -561,6 +619,12 @@ HAWK_EXPORT int hawk_split_bcstr ( # define hawk_tokenize_oochars hawk_tokenize_bchars # define hawk_trim_oochars hawk_trim_bchars # define hawk_split_oocstr hawk_split_bcstr + +# define hawk_fnmat_oochars_i hawk_fnmat_bchars_i +# define hawk_fnmat_oochars hawk_fnmat_bchars +# define hawk_fnmat_oocstr hawk_fnmat_bcstr +# define hawk_fnmat_oochars_oocstr hawk_fnmat_bchars_bcstr +# define hawk_fnmat_oocstr_oochars hawk_fnmat_bcstr_bchars #endif /* ------------------------------------------------------------------------- */ diff --git a/hawk/lib/hawk-str.h.m4 b/hawk/lib/hawk-str.h.m4 index 363a79de..557ed14c 100644 --- a/hawk/lib/hawk-str.h.m4 +++ b/hawk/lib/hawk-str.h.m4 @@ -43,18 +43,41 @@ dnl --------------------------------------------------------------------------- * STRING * ========================================================================= */ -enum hawk_trim_oochars_flag_t +enum hawk_trim_flag_t { - HAWK_TRIM_OOCHARS_LEFT = (1 << 0), /**< trim leading spaces */ -#define HAWK_TRIM_OOCHARS_LEFT HAWK_TRIM_OOCHARS_LEFT -#define HAWK_TRIM_UCHARS_LEFT HAWK_TRIM_OOCHARS_LEFT -#define HAWK_TRIM_BCHARS_LEFT HAWK_TRIM_OOCHARS_LEFT - HAWK_TRIM_OOCHARS_RIGHT = (1 << 1) /**< trim trailing spaces */ -#define HAWK_TRIM_OOCHARS_RIGHT HAWK_TRIM_OOCHARS_RIGHT -#define HAWK_TRIM_UCHARS_RIGHT HAWK_TRIM_OOCHARS_RIGHT -#define HAWK_TRIM_BCHARS_RIGHT HAWK_TRIM_OOCHARS_RIGHT + HAWK_TRIM_LEFT = (1 << 0), /**< trim leading spaces */ +#define HAWK_TRIM_LEFT HAWK_TRIM_LEFT +#define HAWK_TRIM_OOCHARS_LEFT HAWK_TRIM_LEFT +#define HAWK_TRIM_UCHARS_LEFT HAWK_TRIM_LEFT +#define HAWK_TRIM_BCHARS_LEFT HAWK_TRIM_LEFT + HAWK_TRIM_RIGHT = (1 << 1) /**< trim trailing spaces */ +#define HAWK_TRIM_RIGHT HAWK_TRIM_RIGHT +#define HAWK_TRIM_OOCHARS_RIGHT HAWK_TRIM_RIGHT +#define HAWK_TRIM_UCHARS_RIGHT HAWK_TRIM_RIGHT +#define HAWK_TRIM_BCHARS_RIGHT HAWK_TRIM_RIGHT }; +enum hawk_fnmat_flag_t +{ + HAWK_FNMAT_PATHNAME = (1 << 0), +#define HAWK_FNMAT_PATHNAME HAWK_FNMAT_PATHNAME + HAWK_FNMAT_NOESCAPE = (1 << 1), +#define HAWK_FNMAT_NOESCAPE HAWK_FNMAT_NOESCAPE + HAWK_FNMAT_PERIOD = (1 << 2), +#define HAWK_FNMAT_PERIOD HAWK_FNMAT_PERIOD + HAWK_FNMAT_IGNORECASE = (1 << 3) +#define HAWK_FNMAT_IGNORECASE HAWK_FNMAT_IGNORECASE +}; + +#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__) + /* i don't support escaping in these systems */ +# define HAWK_FNMAT_IS_ESC(c) (0) +# define HAWK_FNMAT_IS_SEP(c) ((c) == '/' || (c) == '\\') +#else +# define HAWK_FNMAT_IS_ESC(c) ((c) == '\\') +# define HAWK_FNMAT_IS_SEP(c) ((c) == '/') +#endif + #if defined(__cplusplus) extern "C" { #endif @@ -478,6 +501,34 @@ HAWK_EXPORT int hawk_split_bcstr ( ); +HAWK_EXPORT int hawk_fnmat_uchars_i ( + const hawk_uch_t* str, + hawk_oow_t slen, + const hawk_uch_t* ptn, + hawk_oow_t plen, + int flags, + int no_first_period +); + +HAWK_EXPORT int hawk_fnmat_bchars_i ( + const hawk_bch_t* str, + hawk_oow_t slen, + const hawk_bch_t* ptn, + hawk_oow_t plen, + int flags, + int no_first_period +); + +#define hawk_fnmat_uchars(str, slen, ptn, plen, flags) hawk_fnmat_uchars_i(str, slen, ptn, plen, flags, 0) +#define hawk_fnmat_ucstr(str, ptn, flags) hawk_fnmat_uchars_i(str, hawk_count_ucstr(str), ptn, hawk_count_ucstr(ptn), flags, 0) +#define hawk_fnmat_uchars_ucstr(str, slen, ptn, flags) hawk_fnmat_uchars_i(str, slen, ptn, hawk_count_ucstr(ptn), flags, 0) +#define hawk_fnmat_ucstr_uchars(str, ptn, plen, flags) hawk_fnmat_uchars_i(str, hawk_count_ucstr(str), ptn, plen, flags, 0) + +#define hawk_fnmat_bchars(str, slen, ptn, plen, flags) hawk_fnmat_bchars_i(str, slen, ptn, plen, flags, 0) +#define hawk_fnmat_bcstr(str, ptn, flags) hawk_fnmat_bchars_i(str, hawk_count_bcstr(str), ptn, hawk_count_bcstr(ptn), flags, 0) +#define hawk_fnmat_bchars_bcstr(str, slen, ptn, flags) hawk_fnmat_bchars_i(str, slen, ptn, hawk_count_bcstr(ptn), flags, 0) +#define hawk_fnmat_bcstr_bchars(str, ptn, plen, flags) hawk_fnmat_bchars_i(str, hawk_count_bcstr(str), ptn, plen, flags, 0) + #if defined(HAWK_OOCH_IS_UCH) # define hawk_count_oocstr hawk_count_ucstr # define hawk_count_oocstr_limited hawk_count_ucstr_limited @@ -520,6 +571,12 @@ HAWK_EXPORT int hawk_split_bcstr ( # define hawk_tokenize_oochars hawk_tokenize_uchars # define hawk_trim_oochars hawk_trim_uchars # define hawk_split_oocstr hawk_split_ucstr + +# define hawk_fnmat_oochars_i hawk_fnmat_uchars_i +# define hawk_fnmat_oochars hawk_fnmat_uchars +# define hawk_fnmat_oocstr hawk_fnmat_ucstr +# define hawk_fnmat_oochars_oocstr hawk_fnmat_uchars_ucstr +# define hawk_fnmat_oocstr_oochars hawk_fnmat_ucstr_uchars #else # define hawk_count_oocstr hawk_count_bcstr # define hawk_count_oocstr_limited hawk_count_bcstr_limited @@ -562,6 +619,12 @@ HAWK_EXPORT int hawk_split_bcstr ( # define hawk_tokenize_oochars hawk_tokenize_bchars # define hawk_trim_oochars hawk_trim_bchars # define hawk_split_oocstr hawk_split_bcstr + +# define hawk_fnmat_oochars_i hawk_fnmat_bchars_i +# define hawk_fnmat_oochars hawk_fnmat_bchars +# define hawk_fnmat_oocstr hawk_fnmat_bcstr +# define hawk_fnmat_oochars_oocstr hawk_fnmat_bchars_bcstr +# define hawk_fnmat_oocstr_oochars hawk_fnmat_bcstr_bchars #endif /* ------------------------------------------------------------------------- */ diff --git a/hawk/lib/hawk-utl.h b/hawk/lib/hawk-utl.h index 6db943fe..222b50d7 100644 --- a/hawk/lib/hawk-utl.h +++ b/hawk/lib/hawk-utl.h @@ -380,6 +380,13 @@ HAWK_EXPORT int hawk_comp_ucstr_bcstr ( int ignorecase ); +HAWK_EXPORT int hawk_comp_ucstr_bcstr_limited ( + const hawk_uch_t* str1, + const hawk_bch_t* str2, + hawk_oow_t maxlen, + int ignorecase +); + HAWK_EXPORT int hawk_comp_uchars_bcstr ( const hawk_uch_t* str1, hawk_oow_t len, diff --git a/hawk/lib/mod-hawk.c b/hawk/lib/mod-hawk.c index 0a7ea43e..33408159 100644 --- a/hawk/lib/mod-hawk.c +++ b/hawk/lib/mod-hawk.c @@ -537,4 +537,3 @@ int hawk_mod_hawk (hawk_mod_t* mod, hawk_t* hawk) return 0; } - diff --git a/hawk/lib/std.c b/hawk/lib/std.c index 81655bb0..e43b8642 100644 --- a/hawk/lib/std.c +++ b/hawk/lib/std.c @@ -2203,10 +2203,28 @@ static hawk_ooi_t hawk_rio_file (hawk_rtx_t* rtx, hawk_rio_cmd_t cmd, hawk_rio_a return 0; case HAWK_RIO_CMD_READ: - return hawk_sio_getoochars((hawk_sio_t*)riod->handle, data, size); + { + hawk_ooi_t t; + t = hawk_sio_getoochars((hawk_sio_t*)riod->handle, data, size); + if (t <= -1) + { + const hawk_ooch_t* bem = hawk_rtx_backuperrmsg(rtx); + hawk_rtx_seterrfmt (rtx, HAWK_NULL, HAWK_EOPEN, HAWK_T("unable to read %js - %js"), riod->name, bem); + } + return t; + } case HAWK_RIO_CMD_READ_BYTES: - return hawk_sio_getbchars((hawk_sio_t*)riod->handle, data, size); + { + hawk_ooi_t t; + t = hawk_sio_getbchars((hawk_sio_t*)riod->handle, data, size); + if (t <= -1) + { + const hawk_ooch_t* bem = hawk_rtx_backuperrmsg(rtx); + hawk_rtx_seterrfmt (rtx, HAWK_NULL, HAWK_EOPEN, HAWK_T("unable to read %js - %js"), riod->name, bem); + } + return t; + } case HAWK_RIO_CMD_WRITE: return hawk_sio_putoochars((hawk_sio_t*)riod->handle, data, size); @@ -2292,7 +2310,7 @@ static int open_rio_console (hawk_rtx_t* rtx, hawk_rio_arg_t* riod) { console_open_stdin: /* open stdin */ - sio = open_sio_std_rtx (rtx, HAWK_SIO_STDIN, HAWK_SIO_READ | HAWK_SIO_IGNOREECERR); + sio = open_sio_std_rtx(rtx, HAWK_SIO_STDIN, HAWK_SIO_READ | HAWK_SIO_IGNOREECERR); if (HAWK_UNLIKELY(!sio)) return -1; if (rxtn->c.cmgr) hawk_sio_setcmgr (sio, rxtn->c.cmgr); @@ -2361,7 +2379,7 @@ static int open_rio_console (hawk_rtx_t* rtx, hawk_rio_arg_t* riod) * any fields of riod when the open operation fails */ sio = (file[0] == HAWK_T('-') && file[1] == HAWK_T('\0'))? open_sio_std_rtx(rtx, HAWK_SIO_STDIN, HAWK_SIO_READ | HAWK_SIO_IGNOREECERR): - open_sio_rtx(rtx, file, HAWK_SIO_READ | HAWK_SIO_IGNOREECERR); + open_sio_rtx(rtx, file, HAWK_SIO_READ | HAWK_SIO_IGNOREECERR | HAWK_SIO_KEEPPATH); if (HAWK_UNLIKELY(!sio)) { hawk_rtx_freevaloocstr (rtx, v_pair, as.ptr); @@ -2548,6 +2566,15 @@ static hawk_ooi_t hawk_rio_console (hawk_rtx_t* rtx, hawk_rio_cmd_t cmd, hawk_ri /* reset FNR to 0 here since the caller doesn't know that the file has changed. */ hawk_rtx_setgbl(rtx, HAWK_GBL_FNR, hawk_rtx_makeintval(rtx, 0)); } + + if (nn <= -1) + { + const hawk_ooch_t* bem = hawk_rtx_backuperrmsg(rtx); + const hawk_ooch_t* path = hawk_sio_getpath((hawk_sio_t*)riod->handle); + hawk_rtx_seterrfmt (rtx, HAWK_NULL, HAWK_EOPEN, HAWK_T("unable to read%js%js - %js"), + (path? HAWK_T(" "): HAWK_T("")), (path? path: HAWK_T("")), bem); + } + return nn; } @@ -2572,15 +2599,45 @@ static hawk_ooi_t hawk_rio_console (hawk_rtx_t* rtx, hawk_rio_cmd_t cmd, hawk_ri if (sio) hawk_sio_close (sio); hawk_rtx_setgbl(rtx, HAWK_GBL_FNR, hawk_rtx_makeintval(rtx, 0)); } + + if (nn <= -1) + { + const hawk_ooch_t* bem = hawk_rtx_backuperrmsg(rtx); + const hawk_ooch_t* path = hawk_sio_getpath((hawk_sio_t*)riod->handle); + hawk_rtx_seterrfmt (rtx, HAWK_NULL, HAWK_EOPEN, HAWK_T("unable to read%js%js - %js"), + (path? HAWK_T(" "): HAWK_T("")), (path? path: HAWK_T("")), bem); + } return nn; } case HAWK_RIO_CMD_WRITE: - return hawk_sio_putoochars((hawk_sio_t*)riod->handle, data, size); + { + hawk_ooi_t nn; + nn = hawk_sio_putoochars((hawk_sio_t*)riod->handle, data, size); + if (nn <= -1) + { + const hawk_ooch_t* bem = hawk_rtx_backuperrmsg(rtx); + const hawk_ooch_t* path = hawk_sio_getpath((hawk_sio_t*)riod->handle); + hawk_rtx_seterrfmt (rtx, HAWK_NULL, HAWK_EOPEN, HAWK_T("unable to write%js%js - %js"), + (path? HAWK_T(" "): HAWK_T("")), (path? path: HAWK_T("")), bem); + } + return nn; + } case HAWK_RIO_CMD_WRITE_BYTES: - return hawk_sio_putbchars((hawk_sio_t*)riod->handle, data, size); + { + hawk_ooi_t nn; + nn = hawk_sio_putbchars((hawk_sio_t*)riod->handle, data, size); + if (nn <= -1) + { + const hawk_ooch_t* bem = hawk_rtx_backuperrmsg(rtx); + const hawk_ooch_t* path = hawk_sio_getpath((hawk_sio_t*)riod->handle); + hawk_rtx_seterrfmt (rtx, HAWK_NULL, HAWK_EOPEN, HAWK_T("unable to write%js%js - %js"), + (path? HAWK_T(" "): HAWK_T("")), (path? path: HAWK_T("")), bem); + } + return nn; + } case HAWK_RIO_CMD_FLUSH: { diff --git a/hawk/lib/utl-str.c b/hawk/lib/utl-str.c index 6aaa69f7..c543d76d 100644 --- a/hawk/lib/utl-str.c +++ b/hawk/lib/utl-str.c @@ -32,6 +32,130 @@ #include "hawk-prv.h" #include +static int match_uch_class (const hawk_uch_t* pp, hawk_uch_t sc, int* matched) +{ + if (hawk_comp_ucstr_bcstr_limited(pp, "[:upper:]", 9, 0) == 0) + { + *matched = hawk_is_uch_upper(sc); + return 9; + } + else if (hawk_comp_ucstr_bcstr_limited(pp, "[:lower:]", 9, 0) == 0) + { + *matched = hawk_is_uch_lower(sc); + return 9; + } + else if (hawk_comp_ucstr_bcstr_limited(pp, "[:alpha:]", 9, 0) == 0) + { + *matched = hawk_is_uch_alpha(sc); + return 9; + } + else if (hawk_comp_ucstr_bcstr_limited(pp, "[:digit:]", 9, 0) == 0) + { + *matched = hawk_is_uch_digit(sc); + return 9; + } + else if (hawk_comp_ucstr_bcstr_limited(pp, "[:xdigit:]", 10, 0) == 0) + { + *matched = hawk_is_uch_xdigit(sc); + return 10; + } + else if (hawk_comp_ucstr_bcstr_limited(pp, "[:alnum:]", 9, 0) == 0) + { + *matched = hawk_is_uch_alnum(sc); + return 9; + } + else if (hawk_comp_ucstr_bcstr_limited(pp, "[:space:]", 9, 0) == 0) + { + *matched = hawk_is_uch_space(sc); + return 9; + } + else if (hawk_comp_ucstr_bcstr_limited(pp, "[:print:]", 9, 0) == 0) + { + *matched = hawk_is_uch_print(sc); + return 9; + } + else if (hawk_comp_ucstr_bcstr_limited(pp, "[:graph:]", 9, 0) == 0) + { + *matched = hawk_is_uch_graph(sc); + return 9; + } + else if (hawk_comp_ucstr_bcstr_limited(pp, "[:cntrl:]", 9, 0) == 0) + { + *matched = hawk_is_uch_cntrl(sc); + return 9; + } + else if (hawk_comp_ucstr_bcstr_limited(pp, "[:punct:]", 9, 0) == 0) + { + *matched = hawk_is_uch_punct(sc); + return 9; + } + + return 0; +} + +static int match_bch_class (const hawk_bch_t* pp, hawk_bch_t sc, int* matched) +{ + if (hawk_comp_bcstr_limited(pp, "[:upper:]", 9, 0) == 0) + { + *matched = hawk_is_bch_upper(sc); + return 9; + } + else if (hawk_comp_bcstr_limited(pp, "[:lower:]", 9, 0) == 0) + { + *matched = hawk_is_bch_lower(sc); + return 9; + } + else if (hawk_comp_bcstr_limited(pp, "[:alpha:]", 9, 0) == 0) + { + *matched = hawk_is_bch_alpha(sc); + return 9; + } + else if (hawk_comp_bcstr_limited(pp, "[:digit:]", 9, 0) == 0) + { + *matched = hawk_is_bch_digit(sc); + return 9; + } + else if (hawk_comp_bcstr_limited(pp, "[:xdigit:]", 10, 0) == 0) + { + *matched = hawk_is_bch_xdigit(sc); + return 10; + } + else if (hawk_comp_bcstr_limited(pp, "[:alnum:]", 9, 0) == 0) + { + *matched = hawk_is_bch_alnum(sc); + return 9; + } + else if (hawk_comp_bcstr_limited(pp, "[:space:]", 9, 0) == 0) + { + *matched = hawk_is_bch_space(sc); + return 9; + } + else if (hawk_comp_bcstr_limited(pp, "[:print:]", 9, 0) == 0) + { + *matched = hawk_is_bch_print(sc); + return 9; + } + else if (hawk_comp_bcstr_limited(pp, "[:graph:]", 9, 0) == 0) + { + *matched = hawk_is_bch_graph(sc); + return 9; + } + else if (hawk_comp_bcstr_limited(pp, "[:cntrl:]", 9, 0) == 0) + { + *matched = hawk_is_bch_cntrl(sc); + return 9; + } + else if (hawk_comp_bcstr_limited(pp, "[:punct:]", 9, 0) == 0) + { + *matched = hawk_is_bch_punct(sc); + return 9; + } + + return 0; +} + + + int hawk_comp_uchars (const hawk_uch_t* str1, hawk_oow_t len1, const hawk_uch_t* str2, hawk_oow_t len2, int ignorecase) { @@ -3001,3 +3125,465 @@ hawk_uint_t hawk_bchars_to_uint (const hawk_bch_t* str, hawk_oow_t len, int opti return n; } +int hawk_fnmat_uchars_i (const hawk_uch_t* str, hawk_oow_t slen, const hawk_uch_t* ptn, hawk_oow_t plen, int flags, int no_first_period) +{ + const hawk_uch_t* sp = str; + const hawk_uch_t* pp = ptn; + const hawk_uch_t* se = str + slen; + const hawk_uch_t* pe = ptn + plen; + hawk_uch_t sc, pc, pc2; + + while (1) + { + if (pp < pe && HAWK_FNMAT_IS_ESC(*pp) && !(flags & HAWK_FNMAT_NOESCAPE)) + { + /* pattern is escaped and escaping is allowed. */ + + if ((++pp) >= pe) + { + /* + * the last character of the pattern is an WCS_ESC. + * matching is performed as if the end of the pattern is + * reached just without an WCS_ESC. + */ + if (sp < se) return 0; + return 1; + } + + if (sp >= se) return 0; /* premature string termination */ + + sc = *sp; pc = *pp; /* pc is just a normal character */ + if ((flags & HAWK_FNMAT_IGNORECASE) != 0) + { + /* make characters to lower-case */ + sc = hawk_to_uch_lower(sc); + pc = hawk_to_uch_lower(pc); + } + + if (sc != pc) return 0; + sp++; pp++; + continue; + } + if (pp >= pe) + { + /* + * the end of the pattern has been reached. + * the string must terminate too. + */ + return sp >= se; + } + + if (sp >= se) + { + /* the string terminats prematurely */ + while (pp < pe && *pp == '*') pp++; + return pp >= pe; + } + + sc = *sp; pc = *pp; + + if (sc == '.' && (flags & HAWK_FNMAT_PERIOD)) + { + /* + * a leading period in the staring must match + * a period in the pattern explicitly + */ + if ((!no_first_period && sp == str) || + (HAWK_FNMAT_IS_SEP(sp[-1]) && (flags & HAWK_FNMAT_PATHNAME))) + { + if (pc != '.') return 0; + sp++; pp++; + continue; + } + } + else if (HAWK_FNMAT_IS_SEP(sc) && (flags & HAWK_FNMAT_PATHNAME)) + { + while (pc == '*') + { + if ((++pp) >= pe) return 0; + pc = *pp; + } + + /* a path separator must be matched explicitly */ + if (!HAWK_FNMAT_IS_SEP(pc)) return 0; + sp++; pp++; + continue; + } + + /* the handling of special pattern characters begins here */ + if (pc == '?') + { + /* match any single character */ + sp++; pp++; + } + else if (pc == '*') + { + /* match zero or more characters */ + + /* compact asterisks */ + do { pp++; } while (pp < pe && *pp == '*'); + + if (pp >= pe) + { + /* + * if the last character in the pattern is an asterisk, + * the string should not have any directory separators + * when HAWK_FNMAT_PATHNAME is set. + */ + if (flags & HAWK_FNMAT_PATHNAME) + { + const hawk_uch_t* s = sp; + for (s = sp; s < se; s++) + { + if (HAWK_FNMAT_IS_SEP(*s)) return 0; + } + } + return 1; + } + else + { + do + { + if (hawk_fnmat_uchars_i(sp, se - sp, pp, pe - pp, flags, 1)) return 1; + if (HAWK_FNMAT_IS_SEP(*sp) && (flags & HAWK_FNMAT_PATHNAME)) break; + sp++; + } + while (sp < se); + + return 0; + } + } + else if (pc == '[') + { + /* match range */ + int negate = 0; + int matched = 0; + + if ((++pp) >= pe) return 0; + if (*pp == '!') { negate = 1; pp++; } + + while (pp < pe && *pp != ']') + { + if (*pp == '[') + { + hawk_oow_t pl = pe - pp; + + if (pl >= 9) /* assumption that [:class:] is at least 9 in match_uch_class */ + { + int x = match_uch_class(pp, sc, &matched); + if (x > 0) + { + pp += x; + continue; + } + } + + /* + * characters in an invalid class name are + * just treated as normal characters + */ + } + + if (HAWK_FNMAT_IS_ESC(*pp) && !(flags & HAWK_FNMAT_NOESCAPE)) pp++; + else if (*pp == ']') break; + + if (pp >= pe) break; + + pc = *pp; + if ((flags & HAWK_FNMAT_IGNORECASE) != 0) + { + sc = hawk_to_uch_lower(sc); + pc = hawk_to_uch_lower(pc); + } + + if (pp + 1 < pe && pp[1] == '-') + { + pp += 2; /* move the a character next to a dash */ + + if (pp >= pe) + { + if (sc >= pc) matched = 1; + break; + } + + if (HAWK_FNMAT_IS_ESC(*pp) && !(flags & HAWK_FNMAT_NOESCAPE)) + { + if ((++pp) >= pe) + { + if (sc >= pc) matched = 1; + break; + } + } + else if (*pp == ']') + { + if (sc >= pc) matched = 1; + break; + } + + pc2 = *pp; + if ((flags & HAWK_FNMAT_IGNORECASE) != 0) + pc2 = hawk_to_uch_lower(pc2); + + if (sc >= pc && sc <= pc2) matched = 1; + pp++; + } + else + { + if (sc == pc) matched = 1; + pp++; + } + } + + if (negate) matched = !matched; + if (!matched) return 0; + sp++; if (pp < pe) pp++; + } + else + { + /* a normal character */ + if ((flags & HAWK_FNMAT_IGNORECASE) != 0) + { + sc = hawk_to_uch_lower(sc); + pc = hawk_to_uch_lower(pc); + } + + if (sc != pc) return 0; + sp++; pp++; + } + } + + /* will never reach here. but make some immature compilers happy... */ + return 0; +} + +int hawk_fnmat_bchars_i (const hawk_bch_t* str, hawk_oow_t slen, const hawk_bch_t* ptn, hawk_oow_t plen, int flags, int no_first_period) +{ + const hawk_bch_t* sp = str; + const hawk_bch_t* pp = ptn; + const hawk_bch_t* se = str + slen; + const hawk_bch_t* pe = ptn + plen; + hawk_bch_t sc, pc, pc2; + + while (1) + { + if (pp < pe && HAWK_FNMAT_IS_ESC(*pp) && !(flags & HAWK_FNMAT_NOESCAPE)) + { + /* pattern is escaped and escaping is allowed. */ + + if ((++pp) >= pe) + { + /* + * the last character of the pattern is an WCS_ESC. + * matching is performed as if the end of the pattern is + * reached just without an WCS_ESC. + */ + if (sp < se) return 0; + return 1; + } + + if (sp >= se) return 0; /* premature string termination */ + + sc = *sp; pc = *pp; /* pc is just a normal character */ + if ((flags & HAWK_FNMAT_IGNORECASE) != 0) + { + /* make characters to lower-case */ + sc = hawk_to_bch_lower(sc); + pc = hawk_to_bch_lower(pc); + } + + if (sc != pc) return 0; + sp++; pp++; + continue; + } + if (pp >= pe) + { + /* + * the end of the pattern has been reached. + * the string must terminate too. + */ + return sp >= se; + } + + if (sp >= se) + { + /* the string terminats prematurely */ + while (pp < pe && *pp == '*') pp++; + return pp >= pe; + } + + sc = *sp; pc = *pp; + + if (sc == '.' && (flags & HAWK_FNMAT_PERIOD)) + { + /* + * a leading period in the staring must match + * a period in the pattern explicitly + */ + if ((!no_first_period && sp == str) || + (HAWK_FNMAT_IS_SEP(sp[-1]) && (flags & HAWK_FNMAT_PATHNAME))) + { + if (pc != '.') return 0; + sp++; pp++; + continue; + } + } + else if (HAWK_FNMAT_IS_SEP(sc) && (flags & HAWK_FNMAT_PATHNAME)) + { + while (pc == '*') + { + if ((++pp) >= pe) return 0; + pc = *pp; + } + + /* a path separator must be matched explicitly */ + if (!HAWK_FNMAT_IS_SEP(pc)) return 0; + sp++; pp++; + continue; + } + + /* the handling of special pattern characters begins here */ + if (pc == '?') + { + /* match any single character */ + sp++; pp++; + } + else if (pc == '*') + { + /* match zero or more characters */ + + /* compact asterisks */ + do { pp++; } while (pp < pe && *pp == '*'); + + if (pp >= pe) + { + /* + * if the last character in the pattern is an asterisk, + * the string should not have any directory separators + * when HAWK_FNMAT_PATHNAME is set. + */ + if (flags & HAWK_FNMAT_PATHNAME) + { + const hawk_bch_t* s = sp; + for (s = sp; s < se; s++) + { + if (HAWK_FNMAT_IS_SEP(*s)) return 0; + } + } + return 1; + } + else + { + do + { + if (hawk_fnmat_bchars_i(sp, se - sp, pp, pe - pp, flags, 1)) return 1; + if (HAWK_FNMAT_IS_SEP(*sp) && (flags & HAWK_FNMAT_PATHNAME)) break; + sp++; + } + while (sp < se); + + return 0; + } + } + else if (pc == '[') + { + /* match range */ + int negate = 0; + int matched = 0; + + if ((++pp) >= pe) return 0; + if (*pp == '!') { negate = 1; pp++; } + + while (pp < pe && *pp != ']') + { + if (*pp == '[') + { + hawk_oow_t pl = pe - pp; + + if (pl >= 9) /* assumption that [:class:] is at least 9 in match_bch_class */ + { + int x = match_bch_class(pp, sc, &matched); + if (x > 0) + { + pp += x; + continue; + } + } + + /* + * characters in an invalid class name are + * just treated as normal characters + */ + } + + if (HAWK_FNMAT_IS_ESC(*pp) && !(flags & HAWK_FNMAT_NOESCAPE)) pp++; + else if (*pp == ']') break; + + if (pp >= pe) break; + + pc = *pp; + if ((flags & HAWK_FNMAT_IGNORECASE) != 0) + { + sc = hawk_to_bch_lower(sc); + pc = hawk_to_bch_lower(pc); + } + + if (pp + 1 < pe && pp[1] == '-') + { + pp += 2; /* move the a character next to a dash */ + + if (pp >= pe) + { + if (sc >= pc) matched = 1; + break; + } + + if (HAWK_FNMAT_IS_ESC(*pp) && !(flags & HAWK_FNMAT_NOESCAPE)) + { + if ((++pp) >= pe) + { + if (sc >= pc) matched = 1; + break; + } + } + else if (*pp == ']') + { + if (sc >= pc) matched = 1; + break; + } + + pc2 = *pp; + if ((flags & HAWK_FNMAT_IGNORECASE) != 0) + pc2 = hawk_to_bch_lower(pc2); + + if (sc >= pc && sc <= pc2) matched = 1; + pp++; + } + else + { + if (sc == pc) matched = 1; + pp++; + } + } + + if (negate) matched = !matched; + if (!matched) return 0; + sp++; if (pp < pe) pp++; + } + else + { + /* a normal character */ + if ((flags & HAWK_FNMAT_IGNORECASE) != 0) + { + sc = hawk_to_bch_lower(sc); + pc = hawk_to_bch_lower(pc); + } + + if (sc != pc) return 0; + sp++; pp++; + } + } + + /* will never reach here. but make some immature compilers happy... */ + return 0; +} + diff --git a/hawk/lib/utl-str.c.m4 b/hawk/lib/utl-str.c.m4 index 9b88be64..0c3a7c06 100644 --- a/hawk/lib/utl-str.c.m4 +++ b/hawk/lib/utl-str.c.m4 @@ -31,6 +31,129 @@ #include "hawk-prv.h" #include + +static int match_uch_class (const hawk_uch_t* pp, hawk_uch_t sc, int* matched) +{ + if (hawk_comp_ucstr_bcstr_limited(pp, "[:upper:]", 9, 0) == 0) + { + *matched = hawk_is_uch_upper(sc); + return 9; + } + else if (hawk_comp_ucstr_bcstr_limited(pp, "[:lower:]", 9, 0) == 0) + { + *matched = hawk_is_uch_lower(sc); + return 9; + } + else if (hawk_comp_ucstr_bcstr_limited(pp, "[:alpha:]", 9, 0) == 0) + { + *matched = hawk_is_uch_alpha(sc); + return 9; + } + else if (hawk_comp_ucstr_bcstr_limited(pp, "[:digit:]", 9, 0) == 0) + { + *matched = hawk_is_uch_digit(sc); + return 9; + } + else if (hawk_comp_ucstr_bcstr_limited(pp, "[:xdigit:]", 10, 0) == 0) + { + *matched = hawk_is_uch_xdigit(sc); + return 10; + } + else if (hawk_comp_ucstr_bcstr_limited(pp, "[:alnum:]", 9, 0) == 0) + { + *matched = hawk_is_uch_alnum(sc); + return 9; + } + else if (hawk_comp_ucstr_bcstr_limited(pp, "[:space:]", 9, 0) == 0) + { + *matched = hawk_is_uch_space(sc); + return 9; + } + else if (hawk_comp_ucstr_bcstr_limited(pp, "[:print:]", 9, 0) == 0) + { + *matched = hawk_is_uch_print(sc); + return 9; + } + else if (hawk_comp_ucstr_bcstr_limited(pp, "[:graph:]", 9, 0) == 0) + { + *matched = hawk_is_uch_graph(sc); + return 9; + } + else if (hawk_comp_ucstr_bcstr_limited(pp, "[:cntrl:]", 9, 0) == 0) + { + *matched = hawk_is_uch_cntrl(sc); + return 9; + } + else if (hawk_comp_ucstr_bcstr_limited(pp, "[:punct:]", 9, 0) == 0) + { + *matched = hawk_is_uch_punct(sc); + return 9; + } + + return 0; +} + +static int match_bch_class (const hawk_bch_t* pp, hawk_bch_t sc, int* matched) +{ + if (hawk_comp_bcstr_limited(pp, "[:upper:]", 9, 0) == 0) + { + *matched = hawk_is_bch_upper(sc); + return 9; + } + else if (hawk_comp_bcstr_limited(pp, "[:lower:]", 9, 0) == 0) + { + *matched = hawk_is_bch_lower(sc); + return 9; + } + else if (hawk_comp_bcstr_limited(pp, "[:alpha:]", 9, 0) == 0) + { + *matched = hawk_is_bch_alpha(sc); + return 9; + } + else if (hawk_comp_bcstr_limited(pp, "[:digit:]", 9, 0) == 0) + { + *matched = hawk_is_bch_digit(sc); + return 9; + } + else if (hawk_comp_bcstr_limited(pp, "[:xdigit:]", 10, 0) == 0) + { + *matched = hawk_is_bch_xdigit(sc); + return 10; + } + else if (hawk_comp_bcstr_limited(pp, "[:alnum:]", 9, 0) == 0) + { + *matched = hawk_is_bch_alnum(sc); + return 9; + } + else if (hawk_comp_bcstr_limited(pp, "[:space:]", 9, 0) == 0) + { + *matched = hawk_is_bch_space(sc); + return 9; + } + else if (hawk_comp_bcstr_limited(pp, "[:print:]", 9, 0) == 0) + { + *matched = hawk_is_bch_print(sc); + return 9; + } + else if (hawk_comp_bcstr_limited(pp, "[:graph:]", 9, 0) == 0) + { + *matched = hawk_is_bch_graph(sc); + return 9; + } + else if (hawk_comp_bcstr_limited(pp, "[:cntrl:]", 9, 0) == 0) + { + *matched = hawk_is_bch_cntrl(sc); + return 9; + } + else if (hawk_comp_bcstr_limited(pp, "[:punct:]", 9, 0) == 0) + { + *matched = hawk_is_bch_punct(sc); + return 9; + } + + return 0; +} + dnl dnl --------------------------------------------------------------------------- include(`utl-str.m4')dnl @@ -136,3 +259,6 @@ fn_chars_to_int(hawk_bchars_to_int, hawk_bch_t, hawk_int_t, hawk_is_bch_space, H dnl -- fn_chars_to_uint(hawk_uchars_to_uint, hawk_uch_t, hawk_uint_t, hawk_is_uch_space, HAWK_UCHARS_TO_UINTMAX) fn_chars_to_uint(hawk_bchars_to_uint, hawk_bch_t, hawk_uint_t, hawk_is_bch_space, HAWK_BCHARS_TO_UINTMAX) +dnl -- +fn_fnmat(hawk_fnmat_uchars_i, hawk_uch_t, hawk_to_uch_lower, match_uch_class) +fn_fnmat(hawk_fnmat_bchars_i, hawk_bch_t, hawk_to_bch_lower, match_bch_class) diff --git a/hawk/lib/utl-str.m4 b/hawk/lib/utl-str.m4 index 2ce69363..5b267309 100644 --- a/hawk/lib/utl-str.m4 +++ b/hawk/lib/utl-str.m4 @@ -1507,3 +1507,237 @@ _int_type_ _fn_name_ (const _char_type_* str, hawk_oow_t len, int option, const } popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_int_type_]])popdef([[_is_space_]])popdef([[_prefix_]])dnl ]]) +dnl --------------------------------------------------------------------------- +define([[fn_fnmat]], [[pushdef([[_fn_name_]], $1)pushdef([[_char_type_]], $2)pushdef([[_to_lower_]], $3)pushdef([[_match_ch_class_]], $4)dnl +int _fn_name_ (const _char_type_* str, hawk_oow_t slen, const _char_type_* ptn, hawk_oow_t plen, int flags, int no_first_period) +{ + const _char_type_* sp = str; + const _char_type_* pp = ptn; + const _char_type_* se = str + slen; + const _char_type_* pe = ptn + plen; + _char_type_ sc, pc, pc2; + + while (1) + { + if (pp < pe && HAWK_FNMAT_IS_ESC(*pp) && !(flags & HAWK_FNMAT_NOESCAPE)) + { + /* pattern is escaped and escaping is allowed. */ + + if ((++pp) >= pe) + { + /* + * the last character of the pattern is an WCS_ESC. + * matching is performed as if the end of the pattern is + * reached just without an WCS_ESC. + */ + if (sp < se) return 0; + return 1; + } + + if (sp >= se) return 0; /* premature string termination */ + + sc = *sp; pc = *pp; /* pc is just a normal character */ + if ((flags & HAWK_FNMAT_IGNORECASE) != 0) + { + /* make characters to lower-case */ + sc = _to_lower_()(sc); + pc = _to_lower_()(pc); + } + + if (sc != pc) return 0; + sp++; pp++; + continue; + } + if (pp >= pe) + { + /* + * the end of the pattern has been reached. + * the string must terminate too. + */ + return sp >= se; + } + + if (sp >= se) + { + /* the string terminats prematurely */ + while (pp < pe && *pp == '*') pp++; + return pp >= pe; + } + + sc = *sp; pc = *pp; + + if (sc == '.' && (flags & HAWK_FNMAT_PERIOD)) + { + /* + * a leading period in the staring must match + * a period in the pattern explicitly + */ + if ((!no_first_period && sp == str) || + (HAWK_FNMAT_IS_SEP(sp[-1]) && (flags & HAWK_FNMAT_PATHNAME))) + { + if (pc != '.') return 0; + sp++; pp++; + continue; + } + } + else if (HAWK_FNMAT_IS_SEP(sc) && (flags & HAWK_FNMAT_PATHNAME)) + { + while (pc == '*') + { + if ((++pp) >= pe) return 0; + pc = *pp; + } + + /* a path separator must be matched explicitly */ + if (!HAWK_FNMAT_IS_SEP(pc)) return 0; + sp++; pp++; + continue; + } + + /* the handling of special pattern characters begins here */ + if (pc == '?') + { + /* match any single character */ + sp++; pp++; + } + else if (pc == '*') + { + /* match zero or more characters */ + + /* compact asterisks */ + do { pp++; } while (pp < pe && *pp == '*'); + + if (pp >= pe) + { + /* + * if the last character in the pattern is an asterisk, + * the string should not have any directory separators + * when HAWK_FNMAT_PATHNAME is set. + */ + if (flags & HAWK_FNMAT_PATHNAME) + { + const _char_type_* s = sp; + for (s = sp; s < se; s++) + { + if (HAWK_FNMAT_IS_SEP(*s)) return 0; + } + } + return 1; + } + else + { + do + { + if (_fn_name_()(sp, se - sp, pp, pe - pp, flags, 1)) return 1; + if (HAWK_FNMAT_IS_SEP(*sp) && (flags & HAWK_FNMAT_PATHNAME)) break; + sp++; + } + while (sp < se); + + return 0; + } + } + else if (pc == '[') + { + /* match range */ + int negate = 0; + int matched = 0; + + if ((++pp) >= pe) return 0; + if (*pp == '!') { negate = 1; pp++; } + + while (pp < pe && *pp != ']') + { + if (*pp == '[') + { + hawk_oow_t pl = pe - pp; + + if (pl >= 9) /* assumption that [:class:] is at least 9 in _match_ch_class_ */ + { + int x = _match_ch_class_()(pp, sc, &matched); + if (x > 0) + { + pp += x; + continue; + } + } + + /* + * characters in an invalid class name are + * just treated as normal characters + */ + } + + if (HAWK_FNMAT_IS_ESC(*pp) && !(flags & HAWK_FNMAT_NOESCAPE)) pp++; + else if (*pp == ']') break; + + if (pp >= pe) break; + + pc = *pp; + if ((flags & HAWK_FNMAT_IGNORECASE) != 0) + { + sc = _to_lower_()(sc); + pc = _to_lower_()(pc); + } + + if (pp + 1 < pe && pp[1] == '-') + { + pp += 2; /* move the a character next to a dash */ + + if (pp >= pe) + { + if (sc >= pc) matched = 1; + break; + } + + if (HAWK_FNMAT_IS_ESC(*pp) && !(flags & HAWK_FNMAT_NOESCAPE)) + { + if ((++pp) >= pe) + { + if (sc >= pc) matched = 1; + break; + } + } + else if (*pp == ']') + { + if (sc >= pc) matched = 1; + break; + } + + pc2 = *pp; + if ((flags & HAWK_FNMAT_IGNORECASE) != 0) + pc2 = _to_lower_()(pc2); + + if (sc >= pc && sc <= pc2) matched = 1; + pp++; + } + else + { + if (sc == pc) matched = 1; + pp++; + } + } + + if (negate) matched = !matched; + if (!matched) return 0; + sp++; if (pp < pe) pp++; + } + else + { + /* a normal character */ + if ((flags & HAWK_FNMAT_IGNORECASE) != 0) + { + sc = _to_lower_()(sc); + pc = _to_lower_()(pc); + } + + if (sc != pc) return 0; + sp++; pp++; + } + } + + /* will never reach here. but make some immature compilers happy... */ + return 0; +} +popdef([[_fn_name_]])popdef([[_char_type_]])popdef([[_int_type_]])popdef([[_match_ch_class_]])dnl +]]) diff --git a/hawk/lib/utl.c b/hawk/lib/utl.c index f9570719..1a9c50d9 100644 --- a/hawk/lib/utl.c +++ b/hawk/lib/utl.c @@ -50,6 +50,33 @@ int hawk_comp_ucstr_bcstr (const hawk_uch_t* str1, const hawk_bch_t* str2, int i } } +int hawk_comp_ucstr_bcstr_limited (const hawk_uch_t* str1, const hawk_bch_t* str2, hawk_oow_t maxlen, int ignorecase) +{ + if (maxlen == 0) return 0; + + if (ignorecase) + { + while (hawk_to_uch_lower(*str1) == hawk_to_bch_lower(*str2)) + { + if (*str1 == '\0' || maxlen == 1) return 0; + + str1++; str2++; maxlen--; + } + + return ((hawk_uchu_t)hawk_to_uch_lower(*str1) > (hawk_bchu_t)hawk_to_bch_lower(*str2))? 1: -1; + } + else + { + while (*str1 == *str2) + { + if (*str1 == '\0' || maxlen == 1) return 0; + str1++; str2++; maxlen--; + } + + return ((hawk_uchu_t)*str1 > (hawk_bchu_t)*str2)? 1: -1; + } +} + int hawk_comp_uchars_bcstr (const hawk_uch_t* str1, hawk_oow_t len, const hawk_bch_t* str2, int ignorecase) { /* for "abc\0" of length 4 vs "abc", the fourth character