diff --git a/hawk/bin/hawk.c b/hawk/bin/hawk.c index ff7a73b4..b8a9db72 100644 --- a/hawk/bin/hawk.c +++ b/hawk/bin/hawk.c @@ -544,8 +544,8 @@ static void print_usage (FILE* out, const hawk_bch_t* argv0) fprintf (out, " --console-encoding string specify console encoding name\n"); #endif - fprintf (out, " --includedirs specify directories to look for includes files in\n"); - fprintf (out, " --modlibdirs specify directories to look for module files in\n"); + fprintf (out, " -I/--includedirs string specify directories to look for includes files in\n"); + fprintf (out, " --modlibdirs string specify directories to look for module files in\n"); fprintf (out, " --modern run in the modern mode(default)\n"); fprintf (out, " --classic run in the classic mode\n"); @@ -667,7 +667,7 @@ static int process_argv (int argc, hawk_bch_t* argv[], struct arg_t* arg) { ":script-encoding", '\0' }, { ":console-encoding", '\0' }, - { ":includedirs", '\0' }, + { ":includedirs", 'I' }, { ":modlibdirs", '\0' }, { "modern", '\0' }, @@ -681,9 +681,9 @@ static int process_argv (int argc, hawk_bch_t* argv[], struct arg_t* arg) static hawk_bcli_t opt = { #if defined(HAWK_BUILD_DEBUG) - "hDc:f:d:t:F:v:m:wX:", + "hDc:f:d:t:F:v:m:I:wX:", #else - "hDc:f:d:t:F:v:m:w", + "hDc:f:d:t:F:v:m:I:w", #endif lng }; @@ -826,6 +826,14 @@ static int process_argv (int argc, hawk_bch_t* argv[], struct arg_t* arg) break; } + + case 'I': + { + arg->includedirs = opt.arg; + break; + } + + #if defined(HAWK_BUILD_DEBUG) case 'X': { @@ -873,10 +881,6 @@ static int process_argv (int argc, hawk_bch_t* argv[], struct arg_t* arg) { arg->classic = 1; } - else if (hawk_comp_bcstr(opt.lngopt, "includedirs", 0) == 0) - { - arg->includedirs = opt.arg; - } else if (hawk_comp_bcstr(opt.lngopt, "modlibdirs", 0) == 0) { arg->modlibdirs = opt.arg; diff --git a/hawk/lib/Hawk.cpp b/hawk/lib/Hawk.cpp index 1bb99c4e..8e2a5e38 100644 --- a/hawk/lib/Hawk.cpp +++ b/hawk/lib/Hawk.cpp @@ -1904,6 +1904,36 @@ void Hawk::setMaxDepth (depth_t id, hawk_oow_t depth) hawk_setopt (this->hawk, (hawk_opt_t)id, &depth); } +int Hawk::setIncludeDirs (const hawk_uch_t* dirs) +{ +#if defined(HAWK_OOCH_IS_UCH) + return hawk_setopt(this->hawk, HAWK_OPT_INCLUDEDIRS, dirs); +#else + hawk_ooch_t* tmp; + tmp = hawk_duputobcstr(hawk, dirs, HAWK_NULL); + if (HAWK_UNLIKELY(!tmp)) return -1; + + int n = hawk_setopt(hawk, HAWK_OPT_INCLUDEDIRS, tmp); + hawk_freemem (hawk, tmp); + return n; +#endif +} + +int Hawk::setIncludeDirs (const hawk_bch_t* dirs) +{ +#if defined(HAWK_OOCH_IS_UCH) + hawk_ooch_t* tmp; + tmp = hawk_dupbtoucstr(hawk, dirs, HAWK_NULL, 1); + if (HAWK_UNLIKELY(!tmp)) return -1; + + int n = hawk_setopt(hawk, HAWK_OPT_INCLUDEDIRS, tmp); + hawk_freemem (hawk, tmp); + return n; +#else + return hawk_setopt(this->hawk, HAWK_OPT_INCLUDEDIRS, dirs); +#endif +} + int Hawk::dispatch_function (Run* run, const hawk_fnc_info_t* fi) { bool has_ref_arg = false; diff --git a/hawk/lib/Hawk.hpp b/hawk/lib/Hawk.hpp index c527af8a..4b67219d 100644 --- a/hawk/lib/Hawk.hpp +++ b/hawk/lib/Hawk.hpp @@ -1443,6 +1443,9 @@ public: depth_t id ///< depth identifier ) const; + int setIncludeDirs (const hawk_uch_t* dirs); + int setIncludeDirs (const hawk_bch_t* dirs); + /// /// The addArgument() function adds an ARGV string as long as \a len /// characters pointed to diff --git a/hawk/lib/Std.cpp b/hawk/lib/Std.cpp index 45007f21..4fa994d8 100644 --- a/hawk/lib/Std.cpp +++ b/hawk/lib/Std.cpp @@ -30,6 +30,7 @@ #include // for hawk_stdmodXXX() functions #include "hawk-prv.h" #include +#include // TODO: remove the following definitions and find a way to share the similar definitions in std.c #if defined(HAWK_ENABLE_LIBLTDL) @@ -1321,12 +1322,30 @@ int HawkStd::SourceFile::open (Data& io) hawk_copy_oocstr_unlimited ((hawk_ooch_t*)path + tmplen, ioname); } } + + if (!hawk_stdplainfileexists((hawk_t*)io, path) && ((hawk_t*)io)->opt.includedirs.len > 0 && ioname[0] != '/') + { + const hawk_ooch_t* tmp; + tmp = hawk_stdgetfileindirs((hawk_t*)io, &((hawk_t*)io)->opt.includedirs, ioname); + if (tmp) path = tmp; + } + xpath = hawk_addsionamewithoochars((hawk_t*)io, path, hawk_count_oocstr(path)); if (dbuf) hawk_freemem ((hawk_t*)io, dbuf); } else { - xpath = hawk_addsionamewithoochars((hawk_t*)io, ioname, hawk_count_oocstr(ioname)); + const hawk_ooch_t* path; + + path = ioname; + if (!hawk_stdplainfileexists((hawk_t*)io, path) && ((hawk_t*)io)->opt.includedirs.len > 0 && ioname[0] != '/') + { + const hawk_ooch_t* tmp; + tmp = hawk_stdgetfileindirs((hawk_t*)io, &((hawk_t*)io)->opt.includedirs, ioname); + if (tmp) path = tmp; + } + + xpath = hawk_addsionamewithoochars((hawk_t*)io, path, hawk_count_oocstr(path)); } if (!xpath) return -1; diff --git a/hawk/lib/hawk-cmn.h b/hawk/lib/hawk-cmn.h index 12e49f00..e0f67c3e 100644 --- a/hawk/lib/hawk-cmn.h +++ b/hawk/lib/hawk-cmn.h @@ -844,14 +844,14 @@ typedef struct hawk_cmgr_t hawk_cmgr_t; typedef hawk_oow_t (*hawk_cmgr_bctouc_t) ( const hawk_bch_t* mb, - hawk_oow_t size, + hawk_oow_t size, hawk_uch_t* wc ); typedef hawk_oow_t (*hawk_cmgr_uctobc_t) ( hawk_uch_t wc, hawk_bch_t* mb, - hawk_oow_t size + hawk_oow_t size ); /** diff --git a/hawk/lib/hawk-prv.h b/hawk/lib/hawk-prv.h index cdbb7c2d..fdd1f5c6 100644 --- a/hawk/lib/hawk-prv.h +++ b/hawk/lib/hawk-prv.h @@ -203,6 +203,14 @@ struct hawk_tok_t hawk_loc_t loc; }; +struct hawk_sbuf_t +{ + hawk_ooch_t* ptr; + hawk_oow_t len; + hawk_oow_t capa; +}; +typedef struct hawk_sbuf_t hawk_sbuf_t; + struct hawk_t { /* exposed fields via hawk_alt_t */ @@ -238,6 +246,9 @@ struct hawk_t hawk_oow_t log_maxcapa; } opt; + /* some temporary workspace */ + hawk_sbuf_t sbuf[HAWK_SBUF_COUNT]; + /* parse tree */ hawk_tree_t tree; diff --git a/hawk/lib/hawk-std.h b/hawk/lib/hawk-std.h index 72bba2ce..3b7b1559 100644 --- a/hawk/lib/hawk-std.h +++ b/hawk/lib/hawk-std.h @@ -260,6 +260,18 @@ HAWK_EXPORT void* hawk_stdmodgetsym ( const hawk_ooch_t* name ); + +HAWK_EXPORT int hawk_stdplainfileexists ( + hawk_t* hawk, + const hawk_ooch_t* file +); + +HAWK_EXPORT const hawk_ooch_t* hawk_stdgetfileindirs ( + hawk_t* hawk, + const hawk_oocs_t* dirs, + const hawk_ooch_t* file +); + /* ------------------------------------------------------------------------- */ HAWK_EXPORT hawk_mmgr_t* hawk_get_sys_mmgr ( diff --git a/hawk/lib/hawk.c b/hawk/lib/hawk.c index b310888d..a207bbef 100644 --- a/hawk/lib/hawk.c +++ b/hawk/lib/hawk.c @@ -322,6 +322,18 @@ void hawk_fini (hawk_t* hawk) if (hawk->opt.includedirs.ptr) hawk_freemem (hawk, hawk->opt.includedirs.ptr); + + for (i = 0; i < HAWK_COUNTOF(hawk->sbuf); i++) + { + if (hawk->sbuf[i].ptr) + { + hawk_freemem (hawk, hawk->sbuf[i].ptr); + hawk->sbuf[i].ptr = HAWK_NULL; + hawk->sbuf[i].len = 0; + hawk->sbuf[i].capa = 0; + } + } + if (hawk->log.len > 0) { /* flush pending log message that could be generated by the fini @@ -735,3 +747,69 @@ int hawk_findmodsymflt (hawk_t* hawk, hawk_mod_flt_tab_t* flttab, hawk_oow_t cou if (n <= -1) hawk_seterrfmt (hawk, HAWK_NULL, HAWK_ENOENT, HAWK_T("'%js' not found"), name); return n; } + + +/* ------------------------------------------------------------------------ */ + +static HAWK_INLINE int secure_space_in_sbuf (hawk_t* hawk, hawk_oow_t req, hawk_sbuf_t* p) +{ + if (req > p->capa - p->len) + { + hawk_oow_t newcapa; + hawk_ooch_t* tmp; + + newcapa = p->len + req + 1; + newcapa = HAWK_ALIGN_POW2(newcapa, 512); /* TODO: adjust this capacity */ + + tmp = (hawk_ooch_t*)hawk_reallocmem(hawk, p->ptr, newcapa * HAWK_SIZEOF(*tmp)); + if (!tmp) return -1; + + p->ptr = tmp; + p->capa = newcapa - 1; + } + + return 0; +} + +int hawk_concatoocstrtosbuf (hawk_t* hawk, const hawk_ooch_t* str, hawk_sbuf_id_t id) +{ + return hawk_concatoocharstosbuf(hawk, str, hawk_count_oocstr(str), id); +} + +int hawk_concatoocharstosbuf (hawk_t* hawk, const hawk_ooch_t* ptr, hawk_oow_t len, hawk_sbuf_id_t id) +{ + hawk_sbuf_t* p; + + p = &hawk->sbuf[id]; + if (secure_space_in_sbuf(hawk, len, p) <= -1) return -1; + hawk_copy_oochars (&p->ptr[p->len], ptr, len); + p->len += len; + p->ptr[p->len] = '\0'; + + return 0; +} + +int hawk_concatoochartosbuf (hawk_t* hawk, hawk_ooch_t ch, hawk_oow_t count, hawk_sbuf_id_t id) +{ + hawk_sbuf_t* p; + + p = &hawk->sbuf[id]; + if (secure_space_in_sbuf(hawk, count, p) <= -1) return -1; + hawk_fill_oochars (&p->ptr[p->len], ch, count); + p->len += count; + p->ptr[p->len] = '\0'; + + return 0; +} + +int hawk_copyoocstrtosbuf (hawk_t* hawk, const hawk_ooch_t* str, hawk_sbuf_id_t id) +{ + hawk->sbuf[id].len = 0; + return hawk_concatoocstrtosbuf(hawk, str, id); +} + +int hawk_copyoocharstosbuf (hawk_t* hawk, const hawk_ooch_t* ptr, hawk_oow_t len, hawk_sbuf_id_t id) +{ + hawk->sbuf[id].len = 0; + return hawk_concatoocharstosbuf(hawk, ptr, len, id); +} diff --git a/hawk/lib/hawk.h b/hawk/lib/hawk.h index 36e8f01f..d6c7c7df 100644 --- a/hawk/lib/hawk.h +++ b/hawk/lib/hawk.h @@ -1480,6 +1480,17 @@ struct hawk_nrflt_t }; typedef struct hawk_nrflt_t hawk_nrflt_t; +/* sbuf ids */ +enum hawk_sbuf_id_t +{ + HAWK_SBUF_ID_TMP_1 = 0, + HAWK_SBUF_ID_TMP_2 = 1, + HAWK_SBUF_ID_TMP_3 = 2, + /* more? */ + HAWK_SBUF_COUNT +}; +typedef enum hawk_sbuf_id_t hawk_sbuf_id_t; + #if defined(__cplusplus) extern "C" { #endif @@ -2141,6 +2152,43 @@ HAWK_EXPORT hawk_ooi_t hawk_logbfmt ( # define hawk_logfmt hawk_logbfmt #endif + +/* ----------------------------------------------------------------------- */ + +HAWK_EXPORT int hawk_copyoocstrtosbuf ( + hawk_t* hawk, + const hawk_ooch_t* str, + hawk_sbuf_id_t id +); + +HAWK_EXPORT int hawk_concatoocstrtosbuf ( + hawk_t* hawk, + const hawk_ooch_t* str, + hawk_sbuf_id_t id +); + + +HAWK_EXPORT int hawk_copyoocharstosbuf ( + hawk_t* hawk, + const hawk_ooch_t* ptr, + hawk_oow_t len, + hawk_sbuf_id_t id +); + +HAWK_EXPORT int hawk_concatoocharstosbuf ( + hawk_t* hawk, + const hawk_ooch_t* ptr, + hawk_oow_t len, + hawk_sbuf_id_t id +); + +HAWK_EXPORT int hawk_concatoochartosbuf ( + hawk_t* hawk, + hawk_ooch_t ch, + hawk_oow_t count, + hawk_sbuf_id_t id +); + /* ----------------------------------------------------------------------- */ diff --git a/hawk/lib/std.c b/hawk/lib/std.c index 7777279d..4e119459 100644 --- a/hawk/lib/std.c +++ b/hawk/lib/std.c @@ -112,8 +112,6 @@ typedef struct xtn_t const hawk_uch_t* end; } ucs; } u; - - hawk_ooecs_t tbuf; } in; struct @@ -944,8 +942,6 @@ static void fini_xtn (hawk_t* hawk, void* ctx) xtn->stdmod_up = 0; } - hawk_ooecs_fini (&xtn->s.in.tbuf); - if ((xtn->log.fd_flag & LOGFD_OPENED_HERE) && xtn->log.fd >= 0) close (xtn->log.fd); reset_log_to_default (xtn); } @@ -993,7 +989,6 @@ hawk_t* hawk_openstdwithmmgr (hawk_mmgr_t* mmgr, hawk_oow_t xtnsize, hawk_cmgr_t /* initialize extension */ xtn = GET_XTN(hawk); - hawk_ooecs_init (&xtn->s.in.tbuf, hawk_getgem(hawk), 0); reset_log_to_default (xtn); /* add intrinsic global variables and functions */ @@ -1227,7 +1222,7 @@ static int fill_sio_arg_unique_id (hawk_t* hawk, hawk_sio_arg_t* arg, const hawk #endif } -static int plain_file_exists (hawk_t* hawk, const hawk_ooch_t* file) +int hawk_stdplainfileexists (hawk_t* hawk, const hawk_ooch_t* file) { #if defined(_WIN32) DWORD attr; @@ -1255,7 +1250,7 @@ static int plain_file_exists (hawk_t* hawk, const hawk_ooch_t* file) #endif } -static const hawk_ooch_t* get_file_in_dirs_noseterr (hawk_t* hawk, const hawk_oocs_t* dirs, const hawk_ooch_t* file) +const hawk_ooch_t* hawk_stdgetfileindirs (hawk_t* hawk, const hawk_oocs_t* dirs, const hawk_ooch_t* file) { xtn_t* xtn = GET_XTN(hawk); const hawk_ooch_t* ptr = dirs->ptr; @@ -1267,14 +1262,13 @@ static const hawk_ooch_t* get_file_in_dirs_noseterr (hawk_t* hawk, const hawk_oo colon = hawk_find_oochar_in_oocstr(ptr, ':'); endptr = colon? colon: dirend; - hawk_ooecs_clear (&xtn->s.in.tbuf); - if (hawk_ooecs_ncat(&xtn->s.in.tbuf, ptr, endptr - ptr) == (hawk_oow_t)-1 || - hawk_ooecs_ccat(&xtn->s.in.tbuf, '/') == (hawk_oow_t)-1 || - hawk_ooecs_cat(&xtn->s.in.tbuf, file) == (hawk_oow_t)-1) break; /* the failure in hawk_ooecs_XXX functions still sets the error code */ + if (hawk_copyoocharstosbuf(hawk, ptr, endptr - ptr, HAWK_SBUF_ID_TMP_3) <= -1 || + hawk_concatoochartosbuf(hawk, '/', 1, HAWK_SBUF_ID_TMP_3) <= -1 || + hawk_concatoocstrtosbuf(hawk, file, HAWK_SBUF_ID_TMP_3) <= -1) break; - if (plain_file_exists(hawk, HAWK_OOECS_PTR(&xtn->s.in.tbuf))) + if (hawk_stdplainfileexists(hawk, hawk->sbuf[HAWK_SBUF_ID_TMP_3].ptr)) { - return HAWK_OOECS_PTR(&xtn->s.in.tbuf); + return hawk->sbuf[HAWK_SBUF_ID_TMP_3].ptr; } if (!colon) break; @@ -1339,10 +1333,10 @@ static hawk_ooi_t sf_in_open (hawk_t* hawk, hawk_sio_arg_t* arg, xtn_t* xtn) } } - if (!plain_file_exists(hawk, path) && hawk->opt.includedirs.len > 0 && arg->name[0] != '/') + if (!hawk_stdplainfileexists(hawk, path) && hawk->opt.includedirs.len > 0 && arg->name[0] != '/') { const hawk_ooch_t* tmp; - tmp = get_file_in_dirs_noseterr(hawk, &hawk->opt.includedirs, arg->name); + tmp = hawk_stdgetfileindirs(hawk, &hawk->opt.includedirs, arg->name); if (tmp) path = tmp; } @@ -1354,10 +1348,10 @@ static hawk_ooi_t sf_in_open (hawk_t* hawk, hawk_sio_arg_t* arg, xtn_t* xtn) const hawk_ooch_t* path; path = arg->name; - if (!plain_file_exists(hawk, path) && hawk->opt.includedirs.len > 0 && arg->name[0] != '/') + if (!hawk_stdplainfileexists(hawk, path) && hawk->opt.includedirs.len > 0 && arg->name[0] != '/') { const hawk_ooch_t* tmp; - tmp = get_file_in_dirs_noseterr(hawk, &hawk->opt.includedirs, arg->name); + tmp = hawk_stdgetfileindirs(hawk, &hawk->opt.includedirs, arg->name); if (tmp) path = tmp; } diff --git a/hawk/samples/hawk51.cpp b/hawk/samples/hawk51.cpp index a655f0d1..a057845d 100644 --- a/hawk/samples/hawk51.cpp +++ b/hawk/samples/hawk51.cpp @@ -277,6 +277,8 @@ static void print_usage (FILE* out, const hawk_bch_t* argv0) fprintf (out, " -d deparsedfile set the deparsing output file\n"); fprintf (out, " -o outputfile set the console output file\n"); fprintf (out, " -F string set a field separator(FS)\n"); + fprintf (out, " -I string set include directories\n"); + } struct cmdline_t @@ -286,6 +288,7 @@ struct cmdline_t hawk_bch_t* outf; hawk_bch_t* outc; hawk_bch_t* fs; + hawk_bch_t* incdirs; HAWK::Hawk::Value* argv; int argc; @@ -295,7 +298,7 @@ static int handle_cmdline (MyHawk& awk, int argc, hawk_bch_t* argv[], cmdline_t* { static hawk_bcli_t opt = { - "hF:f:d:o:", + "hF:f:d:o:I:", HAWK_NULL }; hawk_bci_t c; @@ -325,6 +328,10 @@ static int handle_cmdline (MyHawk& awk, int argc, hawk_bch_t* argv[], cmdline_t* cmdline->outc = opt.arg; break; + case 'I': + cmdline->incdirs = opt.arg; + break; + case '?': print_error ("illegal option - '%c'\n", opt.opt); return -1; @@ -417,6 +424,7 @@ static int hawk_main (MyHawk& hawk, int argc, hawk_bch_t* argv[]) if ((n = handle_cmdline(hawk, argc, argv, &cmdline)) <= 0) return n; + if (cmdline.incdirs) hawk.setIncludeDirs (cmdline.incdirs); MyHawk::Source* in, * out; MyHawk::SourceString in_str(cmdline.ins); MyHawk::SourceFile in_file(cmdline.inf);