From fd94b209743863c3299460f8e78885f3e15f646d Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Wed, 15 Apr 2020 08:35:07 +0000 Subject: [PATCH] adding HAWK_MODLIBDIR --- hawk/lib/hawk-prv.h | 2 +- hawk/lib/hawk.c | 6 +++-- hawk/lib/hawk.h | 2 ++ hawk/lib/parse.c | 48 ++++++++++++++++++++++++++---------- hawk/lib/std.c | 60 ++++++++++++++++++++++++++++++++++++++++----- 5 files changed, 96 insertions(+), 22 deletions(-) diff --git a/hawk/lib/hawk-prv.h b/hawk/lib/hawk-prv.h index fd8d972c..ef4aab5e 100644 --- a/hawk/lib/hawk-prv.h +++ b/hawk/lib/hawk-prv.h @@ -209,7 +209,7 @@ struct hawk_t struct { int trait; - hawk_oocs_t mod[2]; + hawk_oocs_t mod[3]; hawk_oocs_t incldirs; union diff --git a/hawk/lib/hawk.c b/hawk/lib/hawk.c index ec955479..e8202de3 100644 --- a/hawk/lib/hawk.c +++ b/hawk/lib/hawk.c @@ -461,6 +461,7 @@ int hawk_setopt (hawk_t* hawk, hawk_opt_t id, const void* value) hawk->opt.trait = *(const int*)value; return 0; + case HAWK_MODLIBDIR: case HAWK_MODPREFIX: case HAWK_MODPOSTFIX: { @@ -469,7 +470,7 @@ int hawk_setopt (hawk_t* hawk, hawk_opt_t id, const void* value) if (dup_str_opt(hawk, value, &tmp) <= -1) return -1; - idx = id - HAWK_MODPREFIX; + idx = id - HAWK_MODLIBDIR; if (hawk->opt.mod[idx].ptr) hawk_freemem (hawk, hawk->opt.mod[idx].ptr); hawk->opt.mod[idx] = tmp; @@ -524,9 +525,10 @@ int hawk_getopt (hawk_t* hawk, hawk_opt_t id, void* value) *(int*)value = hawk->opt.trait; return 0; + case HAWK_MODLIBDIR: case HAWK_MODPREFIX: case HAWK_MODPOSTFIX: - *(const hawk_ooch_t**)value = hawk->opt.mod[id - HAWK_MODPREFIX].ptr; + *(const hawk_ooch_t**)value = hawk->opt.mod[id - HAWK_MODLIBDIR].ptr; return 0; case HAWK_INCLUDEDIRS: diff --git a/hawk/lib/hawk.h b/hawk/lib/hawk.h index e8ce7059..daabaa4c 100644 --- a/hawk/lib/hawk.h +++ b/hawk/lib/hawk.h @@ -481,6 +481,7 @@ typedef struct hawk_mod_spec_t hawk_mod_spec_t; struct hawk_mod_spec_t { + const hawk_ooch_t* libdir; const hawk_ooch_t* prefix; const hawk_ooch_t* postfix; const hawk_ooch_t* name; @@ -1143,6 +1144,7 @@ enum hawk_opt_t /** trait option. 0 or bitwise-ORed of ::hawk_trait_t values */ HAWK_TRAIT, + HAWK_MODLIBDIR, HAWK_MODPREFIX, HAWK_MODPOSTFIX, diff --git a/hawk/lib/parse.c b/hawk/lib/parse.c index 79c9e189..5af1b3f3 100644 --- a/hawk/lib/parse.c +++ b/hawk/lib/parse.c @@ -26,6 +26,10 @@ #include "hawk-prv.h" +#if !defined(HAWK_DEFAULT_MODLIBDIR) +# define HAWK_DEFAULT_MODLIBDIR "" +#endif + #if !defined(HAWK_DEFAULT_MODPREFIX) # if defined(_WIN32) # define HAWK_DEFAULT_MODPREFIX "hawk-" @@ -7336,33 +7340,51 @@ static hawk_mod_t* query_module (hawk_t* awk, const hawk_oocs_t segs[], int nseg goto done; } #endif + + if (!awk->prm.modopen || !awk->prm.modgetsym || !awk->prm.modclose) + { + hawk_seterrfmt (awk, HAWK_NULL, HAWK_EINVAL, HAWK_T("module callbacks not set properly")); + goto open_fail; + } + hawk_seterrnum (awk, HAWK_NULL, HAWK_ENOERR); /* attempt to find an external module */ HAWK_MEMSET (&spec, 0, HAWK_SIZEOF(spec)); if (awk->opt.mod[0].len > 0) - spec.prefix = awk->opt.mod[0].ptr; - else spec.prefix = HAWK_T(HAWK_DEFAULT_MODPREFIX); + spec.libdir = awk->opt.mod[0].ptr; + else + spec.libdir = HAWK_T(HAWK_DEFAULT_MODLIBDIR); if (awk->opt.mod[1].len > 0) - spec.postfix = awk->opt.mod[1].ptr; + spec.prefix = awk->opt.mod[1].ptr; + else spec.prefix = HAWK_T(HAWK_DEFAULT_MODPREFIX); + + if (awk->opt.mod[2].len > 0) + spec.postfix = awk->opt.mod[2].ptr; else spec.postfix = HAWK_T(HAWK_DEFAULT_MODPOSTFIX); HAWK_MEMSET (&md, 0, HAWK_SIZEOF(md)); spec.name = segs[0].ptr; - md.handle = HAWK_NULL; - if (awk->prm.modopen && awk->prm.modgetsym && awk->prm.modclose) + do { - md.handle = awk->prm.modopen(awk, &spec); - } - else - { - hawk_seterrfmt (awk, HAWK_NULL, HAWK_EINVAL, HAWK_T("module callbacks not set properly")); - } + hawk_ooch_t* colon; - if (md.handle == HAWK_NULL) + colon = hawk_find_oochar_in_oocstr(spec.libdir, ':'); + if (colon) *colon = '\0'; + + md.handle = awk->prm.modopen(awk, &spec); + if (!colon) break; + + *colon = ':'; + } + while (!md.handle); + + if (!md.handle) { - const hawk_ooch_t* bem = hawk_backuperrmsg(awk); + const hawk_ooch_t* bem; + open_fail: + bem = hawk_backuperrmsg(awk); hawk_seterrfmt (awk, HAWK_NULL, HAWK_ENOENT, HAWK_T("'%js%js%js' for module '%js' not found - %js"), (spec.prefix? spec.prefix: HAWK_T("")), spec.name, (spec.postfix? spec.postfix: HAWK_T("")), spec.name, bem); return HAWK_NULL; diff --git a/hawk/lib/std.c b/hawk/lib/std.c index 148f4943..8acca018 100644 --- a/hawk/lib/std.c +++ b/hawk/lib/std.c @@ -307,10 +307,19 @@ void* hawk_stdmodopen (hawk_t* awk, const hawk_mod_spec_t* spec) void* h; lt_dladvise adv; hawk_bch_t* modpath; - const hawk_ooch_t* tmp[4]; + const hawk_ooch_t* tmp[6]; int count; + static hawk_ooch_t ds[] = { '/', '\0' }; count = 0; + if (spec->libdir) + { + hawk_oow_t len; + + tmp[count++] = spec->libdir; + len = hawk_count_oocstr(spec->libdir); + if (len > 0 && spec->libdir[len - 1] != '/') tmp[count++] = ds; + } if (spec->prefix) tmp[count++] = spec->prefix; tmp[count++] = spec->name; if (spec->postfix) tmp[count++] = spec->postfix; @@ -344,10 +353,22 @@ void* hawk_stdmodopen (hawk_t* awk, const hawk_mod_spec_t* spec) HMODULE h; hawk_ooch_t* modpath; - const hawk_ooch_t* tmp[4]; + const hawk_ooch_t* tmp[6]; int count; - + static hawk_ooch_t ds[][2] = { { '\\', '\0' }, { '/', '\0' } } + false 0 treu 1 count = 0; + if (spec->libdir) + { + hawk_oow_t len; + + tmp[count++] = spec->libdir; + len = hawk_count_oocstr(spec->libdir); + if (len > 0 && (spec->libdir[len - 1] != '/' && spec->libdir[len - 1] != '\\')) + { + tmp[count++] = ds[hawk_find_oochar_in_oocstr(spec->libdir, '/') != HAWK_NULL]; + } + } if (spec->prefix) tmp[count++] = spec->prefix; tmp[count++] = spec->name; if (spec->postfix) tmp[count++] = spec->postfix; @@ -368,12 +389,21 @@ void* hawk_stdmodopen (hawk_t* awk, const hawk_mod_spec_t* spec) HMODULE h; hawk_bch_t* modpath; - const hawk_ooch_t* tmp[4]; + const hawk_ooch_t* tmp[6]; int count; char errbuf[CCHMAXPATH]; APIRET rc; + static hawk_ooch_t ds[] = { '\\', '\0' }; count = 0; + if (spec->libdir) + { + hawk_oow_t len; + + tmp[count++] = spec->libdir; + len = hawk_count_oocstr(spec->libdir); + if (len > 0 && spec->libdir[len - 1] != '\\') tmp[count++] = ds; + } if (spec->prefix) tmp[count++] = spec->prefix; tmp[count++] = spec->name; if (spec->postfix) tmp[count++] = spec->postfix; @@ -407,10 +437,19 @@ void* hawk_stdmodopen (hawk_t* awk, const hawk_mod_spec_t* spec) * when building for DOS. */ void* h; hawk_bch_t* modpath; - const hawk_ooch_t* tmp[4]; + const hawk_ooch_t* tmp[6]; int count; + static hawk_ooch_t ds[] = { '\\', '\0' }; count = 0; + if (spec->libdir) + { + hawk_oow_t len; + + tmp[count++] = spec->libdir; + len = hawk_count_oocstr(spec->libdir); + if (len > 0 && spec->libdir[len - 1] != '/') tmp[count++] = ds; + } if (spec->prefix) tmp[count++] = spec->prefix; tmp[count++] = spec->name; if (spec->postfix) tmp[count++] = spec->postfix; @@ -434,10 +473,19 @@ void* hawk_stdmodopen (hawk_t* awk, const hawk_mod_spec_t* spec) #elif defined(USE_DLFCN) void* h; hawk_bch_t* modpath; - const hawk_ooch_t* tmp[4]; + const hawk_ooch_t* tmp[6]; int count; + static hawk_ooch_t ds[] = { '/', '\0' }; count = 0; + if (spec->libdir) + { + hawk_oow_t len; + + tmp[count++] = spec->libdir; + len = hawk_count_oocstr(spec->libdir); + if (len > 0 && spec->libdir[len - 1] != '/') tmp[count++] = ds; + } if (spec->prefix) tmp[count++] = spec->prefix; tmp[count++] = spec->name; if (spec->postfix) tmp[count++] = spec->postfix;