added hawk_isvalidident() & hawk_setgblbyname().

fixed the standard console input handler to process special arguments of the var=val format
This commit is contained in:
hyung-hwan 2020-03-05 06:33:58 +00:00
parent 30887f7f2c
commit b7d29ffc86
8 changed files with 168 additions and 62 deletions

View File

@ -2182,18 +2182,18 @@ int Hawk::deleteGlobal (const hawk_uch_t* name)
}
int Hawk::findGlobal (const hawk_bch_t* name)
int Hawk::findGlobal (const hawk_bch_t* name, bool inc_builtins)
{
HAWK_ASSERT (awk != HAWK_NULL);
int n = hawk_findgblwithbcstr(this->hawk, name);
int n = hawk_findgblwithbcstr(this->hawk, name, inc_builtins);
if (n <= -1) this->retrieveError ();
return n;
}
int Hawk::findGlobal (const hawk_uch_t* name)
int Hawk::findGlobal (const hawk_uch_t* name, bool inc_builtins)
{
HAWK_ASSERT (awk != HAWK_NULL);
int n = hawk_findgblwithucstr(this->hawk, name);
int n = hawk_findgblwithucstr(this->hawk, name, inc_builtins);
if (n <= -1) this->retrieveError ();
return n;
}

View File

@ -1520,10 +1520,12 @@ public:
/// \return integer >= 0 on success, -1 on failure.
///
int findGlobal (
const hawk_bch_t* name ///> variable name
const hawk_bch_t* name, ///> variable name
bool inc_builtins = false
);
int findGlobal (
const hawk_uch_t* name ///> variable name
const hawk_uch_t* name, ///> variable name
bool inc_builtins = false
);
///

View File

@ -912,7 +912,14 @@ int HawkStd::open_console_in (Console& io)
*/
argv = hawk_rtx_getgbl (rtx, this->gbl_argv);
HAWK_ASSERT (argv != HAWK_NULL);
HAWK_ASSERT (HAWK_RTX_GETVALTYPE (rtx, argv) == HAWK_VAL_MAP);
if (HAWK_RTX_GETVALTYPE(rtx, argv) != HAWK_VAL_MAP)
{
/* with flexmap on, you can change ARGV to a scalar.
* BEGIN { ARGV="xxx"; }
* you must not do this. */
hawk_rtx_seterrfmt (rtx, HAWK_NULL, HAWK_EINVAL, HAWK_T("phony value in ARGV"));
return -1;
}
map = ((hawk_val_map_t*)argv)->map;
HAWK_ASSERT (map != HAWK_NULL);

View File

@ -1685,7 +1685,7 @@ HAWK_EXPORT void hawk_pushecb (
* \return the ID of the global variable added on success, -1 on failure.
*/
HAWK_EXPORT int hawk_addgblwithbcstr (
hawk_t* awk, /**< awk */
hawk_t* hawk, /**< hawk */
const hawk_bch_t* name /**< variable name */
);
@ -1694,7 +1694,7 @@ HAWK_EXPORT int hawk_addgblwithbcstr (
* \return the ID of the global variable added on success, -1 on failure.
*/
HAWK_EXPORT int hawk_addgblwithucstr (
hawk_t* awk, /**< awk */
hawk_t* hawk, /**< hawk */
const hawk_uch_t* name /**< variable name */
);
@ -1703,7 +1703,7 @@ HAWK_EXPORT int hawk_addgblwithucstr (
* \return 0 on success, -1 on failure
*/
HAWK_EXPORT int hawk_delgblwithbcstr (
hawk_t* awk, /**< awk */
hawk_t* hawk, /**< hawk */
const hawk_bch_t* name /**< variable name */
);
@ -1712,28 +1712,28 @@ HAWK_EXPORT int hawk_delgblwithbcstr (
* \return 0 on success, -1 on failure
*/
HAWK_EXPORT int hawk_delgblwithucstr (
hawk_t* awk, /**< awk */
hawk_t* hawk, /**< hawk */
const hawk_uch_t* name /**< variable name */
);
/**
* The hawk_findgblwithbcstr() function returns the numeric ID of an intrinsic global
* variable.
* The hawk_findgblwithbcstr() function returns the numeric ID of a global variable.
* \return number >= 0 on success, -1 on failure
*/
HAWK_EXPORT int hawk_findgblwithbcstr (
hawk_t* awk, /**< awk */
const hawk_bch_t* name /**< variable name */
hawk_t* hawk, /**< hawk */
const hawk_bch_t* name, /**< variable name */
int inc_builtins /**< include builtin global variables like FS */
);
/**
* The hawk_findgblwithucstr() function returns the numeric ID of an intrinsic global
* variable.
* The hawk_findgblwithucstr() function returns the numeric ID of a global variable.
* \return number >= 0 on success, -1 on failure
*/
HAWK_EXPORT int hawk_findgblwithucstr (
hawk_t* awk, /**< awk */
const hawk_uch_t* name /**< variable name */
hawk_t* hawk, /**< hawk */
const hawk_uch_t* name, /**< variable name */
int inc_builtins /**< include builtin globals variables like FS */
);
#if defined(HAWK_OOCH_IS_BCH)
@ -1843,6 +1843,12 @@ HAWK_EXPORT int hawk_parse (
hawk_sio_cbs_t* sio /**< source script I/O handler */
);
HAWK_EXPORT int hawk_isvalidident (
hawk_t* hawk,
const hawk_ooch_t* str
);
#if defined(HAWK_HAVE_INLINE)
static HAWK_INLINE void* hawk_allocmem (hawk_t* hawk, hawk_oow_t size) { return hawk_gem_allocmem(hawk_getgem(hawk), size); }
static HAWK_INLINE void* hawk_reallocmem (hawk_t* hawk, void* ptr, hawk_oow_t size) { return hawk_gem_reallocmem(hawk_getgem(hawk), ptr, size); }
@ -2350,6 +2356,12 @@ HAWK_EXPORT int hawk_rtx_setgbl (
hawk_val_t* val
);
HAWK_EXPORT int hawk_rtx_setgblbyname (
hawk_rtx_t* rtx,
const hawk_ooch_t* name,
const hawk_ooch_t* val
);
/**
* The hawk_rtx_setretval() sets the return value of a function
* when called from within a function handler. The caller doesn't
@ -3037,15 +3049,15 @@ HAWK_EXPORT int hawk_rtx_valtostr (
HAWK_EXPORT hawk_bch_t* hawk_rtx_valtobcstrdupwithcmgr (
hawk_rtx_t* rtx, /**< runtime context */
const hawk_val_t* val, /**< value to convert */
hawk_oow_t* len, /**< result length */
hawk_cmgr_t* cmgr
hawk_oow_t* len, /**< result length */
hawk_cmgr_t* cmgr
);
HAWK_EXPORT hawk_uch_t* hawk_rtx_valtoucstrdupwithcmgr (
hawk_rtx_t* rtx, /**< runtime context */
const hawk_val_t* val, /**< value to convert */
hawk_oow_t* len, /**< result length */
hawk_cmgr_t* cmgr
hawk_oow_t* len, /**< result length */
hawk_cmgr_t* cmgr
);

View File

@ -2177,7 +2177,7 @@ int hawk_delgblwithucstr (hawk_t* hawk, const hawk_uch_t* name)
return 0;
}
int hawk_findgblwithbcstr (hawk_t* hawk, const hawk_bch_t* name)
int hawk_findgblwithbcstr (hawk_t* hawk, const hawk_bch_t* name, int inc_builtins)
{
hawk_oow_t n;
hawk_bcs_t ncs;
@ -2187,7 +2187,7 @@ int hawk_findgblwithbcstr (hawk_t* hawk, const hawk_bch_t* name)
ncs.len = hawk_count_bcstr(name);
#if defined(HAWK_OOCH_IS_BCH)
n = hawk_arr_search(hawk->parse.gbls, HAWK_NUM_STATIC_GBLS, ncs.ptr, ncs.len);
n = hawk_arr_search(hawk->parse.gbls, (inc_builtins? 0: HAWK_NUM_STATIC_GBLS), ncs.ptr, ncs.len);
if (n == HAWK_ARR_NIL)
{
hawk_seterrfmt (hawk, HAWK_NULL, HAWK_ENOENT, FMT_ENOENT_GBL_HS, ncs.len, ncs.ptr);
@ -2196,7 +2196,7 @@ int hawk_findgblwithbcstr (hawk_t* hawk, const hawk_bch_t* name)
#else
wcs.ptr = hawk_dupbtoucstr(hawk, ncs.ptr, &wcs.len, 0);
if (!wcs.ptr) return -1;
n = hawk_arr_search(hawk->parse.gbls, HAWK_NUM_STATIC_GBLS, wcs.ptr, wcs.len);
n = hawk_arr_search(hawk->parse.gbls, (inc_builtins? 0: HAWK_NUM_STATIC_GBLS), wcs.ptr, wcs.len);
if (n == HAWK_ARR_NIL)
{
hawk_seterrfmt (hawk, HAWK_NULL, HAWK_ENOENT, FMT_ENOENT_GBL_LS, wcs.len, wcs.ptr);
@ -2209,7 +2209,7 @@ int hawk_findgblwithbcstr (hawk_t* hawk, const hawk_bch_t* name)
return (int)n;
}
int hawk_findgblwithucstr (hawk_t* hawk, const hawk_uch_t* name)
int hawk_findgblwithucstr (hawk_t* hawk, const hawk_uch_t* name, int inc_builtins)
{
hawk_oow_t n;
hawk_ucs_t ncs;
@ -2221,7 +2221,7 @@ int hawk_findgblwithucstr (hawk_t* hawk, const hawk_uch_t* name)
#if defined(HAWK_OOCH_IS_BCH)
mbs.ptr = hawk_duputobcstr(hawk, ncs.ptr, &mbs.len);
if (!mbs.ptr) return -1;
n = hawk_arr_search(hawk->parse.gbls, HAWK_NUM_STATIC_GBLS, mbs.ptr, mbs.len);
n = hawk_arr_search(hawk->parse.gbls, (inc_builtins? 0: HAWK_NUM_STATIC_GBLS), mbs.ptr, mbs.len);
if (n == HAWK_ARR_NIL)
{
hawk_seterrfmt (hawk, HAWK_NULL, HAWK_ENOENT, FMT_ENOENT_GBL_HS, mbs.len, mbs.ptr);
@ -2230,7 +2230,7 @@ int hawk_findgblwithucstr (hawk_t* hawk, const hawk_uch_t* name)
}
hawk_freemem (hawk, mbs.ptr);
#else
n = hawk_arr_search(hawk->parse.gbls, HAWK_NUM_STATIC_GBLS, ncs.ptr, ncs.len);
n = hawk_arr_search(hawk->parse.gbls, (inc_builtins? 0: HAWK_NUM_STATIC_GBLS), ncs.ptr, ncs.len);
if (n == HAWK_ARR_NIL)
{
hawk_seterrfmt (hawk, HAWK_NULL, HAWK_ENOENT, FMT_ENOENT_GBL_LS, ncs.len, ncs.ptr);
@ -6772,6 +6772,29 @@ static int classify_ident (hawk_t* awk, const hawk_oocs_t* name)
return TOK_IDENT;
}
int hawk_isvalidident (hawk_t* hawk, const hawk_ooch_t* name)
{
hawk_ooch_t c;
hawk_oocs_t cs;
cs.ptr = (hawk_ooch_t*)name;
if ((c = *name) == '_' || hawk_is_ooch_alpha(c))
{
do
{
c = *++name;
}
while (c == '_' || hawk_is_ooch_alpha(c) || hawk_is_ooch_digit(c));
if (c != '\0') return 0;
cs.len = name - cs.ptr;
return classify_ident(hawk, &cs) == TOK_IDENT;
}
return 0;
}
struct deparse_func_t
{
hawk_t* awk;

View File

@ -634,6 +634,42 @@ HAWK_INLINE int hawk_rtx_setgbl (hawk_rtx_t* rtx, int id, hawk_val_t* val)
return set_global(rtx, id, HAWK_NULL, val, 0);
}
int hawk_rtx_setgblbyname (hawk_rtx_t* rtx, const hawk_ooch_t* name, const hawk_ooch_t* val)
{
int id, n;
hawk_val_t* v;
HAWK_ASSERT (hawk_isvalidident(hawk_rtx_gethawk(rtx), name));
id = hawk_findgblwithoocstr(hawk_rtx_gethawk(rtx), name, 1);
v = hawk_rtx_makestrvalwithoocstr(rtx, val);
if (!v) return -1;
hawk_rtx_refupval (rtx, v);
if (id <= -1)
{
/* not found. it's not a builtin/declared global variable */
hawk_nde_var_t var;
/* make a fake variable node for assignment and use it */
HAWK_MEMSET (&var, 0, HAWK_SIZEOF(var));
var.type = HAWK_NDE_NAMED;
var.id.name.ptr = (hawk_ooch_t*)name;
var.id.name.len = hawk_count_oocstr(name);
var.id.idxa = (hawk_oow_t)-1;
var.idx = HAWK_NULL;
n = do_assignment_nonidx(rtx, &var, v)? 0: -1;
}
else
{
n = set_global(rtx, id, HAWK_NULL, v, 1);
}
hawk_rtx_refdownval (rtx, v);
return n;
}
int hawk_rtx_setscriptnamewithuchars (hawk_rtx_t* rtx, const hawk_uch_t* name, hawk_oow_t len)
{
hawk_val_t* tmp;
@ -643,7 +679,7 @@ int hawk_rtx_setscriptnamewithuchars (hawk_rtx_t* rtx, const hawk_uch_t* name, h
if (tmp == HAWK_NULL) return -1;
hawk_rtx_refupval (rtx, tmp);
n = hawk_rtx_setgbl (rtx, HAWK_GBL_SCRIPTNAME, tmp);
n = hawk_rtx_setgbl(rtx, HAWK_GBL_SCRIPTNAME, tmp);
hawk_rtx_refdownval (rtx, tmp);
return n;
@ -658,7 +694,7 @@ int hawk_rtx_setscriptnamewithbchars (hawk_rtx_t* rtx, const hawk_bch_t* name, h
if (tmp == HAWK_NULL) return -1;
hawk_rtx_refupval (rtx, tmp);
n = hawk_rtx_setgbl (rtx, HAWK_GBL_SCRIPTNAME, tmp);
n = hawk_rtx_setgbl(rtx, HAWK_GBL_SCRIPTNAME, tmp);
hawk_rtx_refdownval (rtx, tmp);
return n;
@ -673,7 +709,7 @@ int hawk_rtx_setfilenamewithuchars (hawk_rtx_t* rtx, const hawk_uch_t* name, haw
if (HAWK_UNLIKELY(!tmp)) return -1;
hawk_rtx_refupval (rtx, tmp);
n = hawk_rtx_setgbl (rtx, HAWK_GBL_FILENAME, tmp);
n = hawk_rtx_setgbl(rtx, HAWK_GBL_FILENAME, tmp);
hawk_rtx_refdownval (rtx, tmp);
return n;
@ -688,7 +724,7 @@ int hawk_rtx_setfilenamewithbchars (hawk_rtx_t* rtx, const hawk_bch_t* name, haw
if (HAWK_UNLIKELY(!tmp)) return -1;
hawk_rtx_refupval (rtx, tmp);
n = hawk_rtx_setgbl (rtx, HAWK_GBL_FILENAME, tmp);
n = hawk_rtx_setgbl(rtx, HAWK_GBL_FILENAME, tmp);
hawk_rtx_refdownval (rtx, tmp);
return n;
@ -706,7 +742,7 @@ int hawk_rtx_setofilenamewithuchars (hawk_rtx_t* rtx, const hawk_uch_t* name, ha
if (HAWK_UNLIKELY(!tmp)) return -1;
hawk_rtx_refupval (rtx, tmp);
n = hawk_rtx_setgbl (rtx, HAWK_GBL_OFILENAME, tmp);
n = hawk_rtx_setgbl(rtx, HAWK_GBL_OFILENAME, tmp);
hawk_rtx_refdownval (rtx, tmp);
}
else n = 0;
@ -725,7 +761,7 @@ int hawk_rtx_setofilenamewithbchars (hawk_rtx_t* rtx, const hawk_bch_t* name, ha
if (HAWK_UNLIKELY(!tmp)) return -1;
hawk_rtx_refupval (rtx, tmp);
n = hawk_rtx_setgbl (rtx, HAWK_GBL_OFILENAME, tmp);
n = hawk_rtx_setgbl(rtx, HAWK_GBL_OFILENAME, tmp);
hawk_rtx_refdownval (rtx, tmp);
}
else n = 0;
@ -1183,6 +1219,7 @@ static void fini_rtx (hawk_rtx_t* rtx, int fini_globals)
static int update_fnr (hawk_rtx_t* rtx, hawk_int_t fnr, hawk_int_t nr)
{
hawk_val_t* tmp1, * tmp2;
int n;
tmp1 = hawk_rtx_makeintval(rtx, fnr);
if (!tmp1) return -1;
@ -1193,32 +1230,18 @@ static int update_fnr (hawk_rtx_t* rtx, hawk_int_t fnr, hawk_int_t nr)
else
{
tmp2 = hawk_rtx_makeintval(rtx, nr);
if (!tmp2)
{
hawk_rtx_refdownval (rtx, tmp1);
return -1;
}
if (!tmp2) { n = -1; goto oops; }
hawk_rtx_refupval (rtx, tmp2);
}
if (hawk_rtx_setgbl (rtx, HAWK_GBL_FNR, tmp1) == -1)
{
if (nr != fnr) hawk_rtx_refdownval (rtx, tmp2);
hawk_rtx_refdownval (rtx, tmp1);
return -1;
}
n = (hawk_rtx_setgbl(rtx, HAWK_GBL_FNR, tmp1) <= -1 ||
hawk_rtx_setgbl(rtx, HAWK_GBL_NR, tmp2) <= -1)? -1: 0;
if (hawk_rtx_setgbl (rtx, HAWK_GBL_NR, tmp2) == -1)
{
if (nr != fnr) hawk_rtx_refdownval (rtx, tmp2);
hawk_rtx_refdownval (rtx, tmp1);
return -1;
}
if (tmp2 != tmp1) hawk_rtx_refdownval (rtx, tmp2);
if (nr != fnr) hawk_rtx_refdownval (rtx, tmp2);
oops:
hawk_rtx_refdownval (rtx, tmp1);
return 0;
return n;
}
/*
@ -1271,7 +1294,7 @@ static int defaultify_globals (hawk_rtx_t* rtx)
int idx;
const hawk_ooch_t* str[2];
};
static struct gtab_t gtab[8] =
static struct gtab_t gtab[9] =
{
{ HAWK_GBL_CONVFMT, { DEFAULT_CONVFMT, DEFAULT_CONVFMT } },
{ HAWK_GBL_FILENAME, { HAWK_NULL, HAWK_NULL } },
@ -6806,7 +6829,7 @@ static hawk_val_t* __eval_getbline (hawk_rtx_t* rtx, hawk_nde_t* nde)
hawk_val_t* v = HAWK_NULL, * tmp;
hawk_oocs_t dst;
hawk_becs_t* buf;
int n, x;
int n;
p = (hawk_nde_getline_t*)nde;

View File

@ -1671,6 +1671,23 @@ int hawk_parsestd (hawk_t* awk, hawk_parsestd_t in[], hawk_parsestd_t* out)
return n;
}
static int check_var_assign (hawk_rtx_t* rtx, hawk_ooch_t* str)
{
hawk_ooch_t* eq, * var;
int n;
eq = hawk_find_oochar_in_oocstr(str, '=');
if (!eq || eq <= str) return 0; /* not assignment */
var = hawk_rtx_dupoochars(rtx, str, eq - str);
if (HAWK_UNLIKELY(!var)) return -1;
n = hawk_isvalidident(hawk_rtx_gethawk(rtx), var)?
((hawk_rtx_setgblbyname(rtx, var, eq + 1) <= -1)? -1: 1): 0;
hawk_rtx_freemem (rtx, var);
return n;
}
/*** RTX_OPENSTD ***/
static ioattr_t* get_ioattr (hawk_htb_t* tab, const hawk_ooch_t* ptr, hawk_oow_t len);
@ -2032,6 +2049,7 @@ static int open_rio_console (hawk_rtx_t* rtx, hawk_rio_arg_t* riod)
hawk_oow_t ibuflen;
hawk_val_t* v;
hawk_oocs_t as;
int x;
nextfile:
file = rxtn->c.in.files[rxtn->c.in.index];
@ -2071,7 +2089,14 @@ static int open_rio_console (hawk_rtx_t* rtx, hawk_rio_arg_t* riod)
*/
argv = hawk_rtx_getgbl(rtx, xtn->gbl_argv);
HAWK_ASSERT (argv != HAWK_NULL);
HAWK_ASSERT (HAWK_RTX_GETVALTYPE (rtx, argv) == HAWK_VAL_MAP);
if (HAWK_RTX_GETVALTYPE(rtx, argv) != HAWK_VAL_MAP)
{
/* with flexmap on, you can change ARGV to a scalar.
* BEGIN { ARGV="xxx"; }
* you must not do this. */
hawk_rtx_seterrfmt (rtx, HAWK_NULL, HAWK_EINVAL, HAWK_T("phony value in ARGV"));
return -1;
}
map = ((hawk_val_map_t*)argv)->map;
HAWK_ASSERT (map != HAWK_NULL);
@ -2105,9 +2130,23 @@ static int open_rio_console (hawk_rtx_t* rtx, hawk_rio_arg_t* riod)
file = as.ptr;
/* TODO: special awk quarkyness - check if the file name is var=val format.
* if so, do variable assignment */
/*
* this is different from the -v option.
* if an argument has a special form of var=val, it is treated specially
*
* on the command-line
* hawk -f a.awk a=20 /etc/passwd
* or via ARGV
* hawk 'BEGIN { ARGV[1] = "a=20"; }
* { print a $1; }' dummy /etc/hosts
*/
if ((x = check_var_assign(rtx, file)) != 0)
{
hawk_rtx_freevaloocstr (rtx, v, as.ptr);
if (HAWK_UNLIKELY(x <= -1)) return -1;
rxtn->c.in.index++;
goto nextfile;
}
sio = (file[0] == HAWK_T('-') && file[1] == HAWK_T('\0'))?
open_sio_std_rtx(rtx, HAWK_SIO_STDIN, HAWK_SIO_READ | HAWK_SIO_IGNOREECERR):

View File

@ -129,7 +129,7 @@ struct hawk_nde_cnd_t
struct hawk_nde_pos_t
{
HAWK_NDE_HDR;
hawk_nde_t* val;
hawk_nde_t* val;
};
/* HAWK_NDE_INT */