added log writer

This commit is contained in:
hyung-hwan 2019-12-14 16:05:10 +00:00
parent 0d558ca900
commit ef1bb5f689
14 changed files with 546 additions and 194 deletions

View File

@ -407,7 +407,7 @@ static void dprint_return (hawk_rtx_t* rtx, hawk_val_t* ret)
}
else
{
dprint (HAWK_T("[RETURN] - [%.*s]\n"), (int)len, str);
dprint (HAWK_T("[RETURN] - [%.*js]\n"), len, str);
hawk_freemem (hawk_rtx_gethawk(rtx), str);
}
}
@ -923,18 +923,16 @@ static void print_hawk_error (hawk_t* awk)
{
const hawk_loc_t* loc = hawk_geterrloc(awk);
/* TODO: proper logging mask */
printf ("print_hawk_error... TODO: \n");
/* hawk_logfmt (awk, 0,
HAWK_T("ERROR: CODE %d LINE %zu COLUMN %zu %s%s%s- %s\n"),
hawk_geterrnum(awk),
hawk_logfmt (awk, HAWK_LOG_STDERR,
HAWK_T("ERROR: CODE %d LINE %zu COLUMN %zu %js%js%js- %js\n"),
(int)hawk_geterrnum(awk),
(hawk_oow_t)loc->line,
(hawk_oow_t)loc->colm,
((loc->file == HAWK_NULL)? HAWK_T(""): HAWK_T("FILE ")),
((loc->file == HAWK_NULL)? HAWK_T(""): loc->file),
((loc->file == HAWK_NULL)? HAWK_T(""): HAWK_T(" ")),
hawk_geterrmsg(awk)
);*/
);
}
static void print_hawk_rtx_error (hawk_rtx_t* rtx)
@ -1282,6 +1280,8 @@ oops:
}
/* ---------------------------------------------------------------------- */
#if defined(FAKE_SOCKET)
socket () {}
listen () {}

View File

@ -1355,7 +1355,7 @@ int Hawk::open ()
#if defined(HAWK_USE_HTB_FOR_FUNCTION_MAP)
this->functionMap = hawk_htb_open(
hawk_getmmgr(this->awk), HAWK_SIZEOF(this), 512, 70,
hawk_getgem(this->awk), HAWK_SIZEOF(this), 512, 70,
HAWK_SIZEOF(hawk_ooch_t), 1
);
if (this->functionMap == HAWK_NULL)

View File

@ -304,7 +304,7 @@ static int err_uchars (hawk_fmtout_t* fmtout, const hawk_uch_t* ptr, hawk_oow_t
}
void hawk_seterrbfmt (hawk_t* hawk, hawk_errnum_t errnum, hawk_loc_t* errloc, const hawk_bch_t* errfmt, ...)
void hawk_seterrbfmt (hawk_t* hawk, const hawk_loc_t* errloc, hawk_errnum_t errnum, const hawk_bch_t* errfmt, ...)
{
va_list ap;
hawk_fmtout_t fo;
@ -327,7 +327,7 @@ void hawk_seterrbfmt (hawk_t* hawk, hawk_errnum_t errnum, hawk_loc_t* errloc, co
hawk->_gem.errloc = (errloc? *errloc: _nullloc);
}
void hawk_seterrufmt (hawk_t* hawk, hawk_errnum_t errnum, hawk_loc_t* errloc, const hawk_uch_t* errfmt, ...)
void hawk_seterrufmt (hawk_t* hawk, const hawk_loc_t* errloc, hawk_errnum_t errnum, const hawk_uch_t* errfmt, ...)
{
va_list ap;
hawk_fmtout_t fo;
@ -485,7 +485,7 @@ static int rtx_err_uchars (hawk_fmtout_t* fmtout, const hawk_uch_t* ptr, hawk_oo
return 1; /* success */
}
void hawk_rtx_seterrbfmt (hawk_rtx_t* rtx, hawk_errnum_t errnum, const hawk_loc_t* errloc, const hawk_bch_t* errfmt, ...)
void hawk_rtx_seterrbfmt (hawk_rtx_t* rtx, const hawk_loc_t* errloc, hawk_errnum_t errnum, const hawk_bch_t* errfmt, ...)
{
va_list ap;
hawk_fmtout_t fo;
@ -508,7 +508,7 @@ void hawk_rtx_seterrbfmt (hawk_rtx_t* rtx, hawk_errnum_t errnum, const hawk_loc_
rtx->_gem.errloc = (errloc? *errloc: _nullloc);
}
void hawk_rtx_seterrufmt (hawk_rtx_t* rtx, hawk_errnum_t errnum, const hawk_loc_t* errloc, const hawk_uch_t* errfmt, ...)
void hawk_rtx_seterrufmt (hawk_rtx_t* rtx, const hawk_loc_t* errloc, hawk_errnum_t errnum, const hawk_uch_t* errfmt, ...)
{
va_list ap;
hawk_fmtout_t fo;

View File

@ -1509,7 +1509,15 @@ int hawk_ufmt_out (hawk_fmtout_t* fmtout, const hawk_uch_t* fmt, ...)
* FORMATTED LOG OUTPUT
* -------------------------------------------------------------------------- */
#if 0
/* i don't want an error raised inside the callback to override
* the existing error number and message. */
#define log_write(hawk,mask,ptr,len) do { \
int shuterr = (hawk)->shuterr; \
(hawk)->shuterr = 1; \
(hawk)->prm.logwrite (hawk, mask, ptr, len); \
(hawk)->shuterr = shuterr; \
} while(0)
static int log_oocs (hawk_fmtout_t* fmtout, const hawk_ooch_t* ptr, hawk_oow_t len)
{
hawk_t* hawk = (hawk_t*)fmtout->ctx;
@ -1527,7 +1535,7 @@ static int log_oocs (hawk_fmtout_t* fmtout, const hawk_ooch_t* ptr, hawk_oow_t l
hawk->log.ptr[hawk->log.len++] = '\n';
}
vmprim_log_write (hawk, hawk->log.last_mask, hawk->log.ptr, hawk->log.len);
log_write (hawk, hawk->log.last_mask, hawk->log.ptr, hawk->log.len);
hawk->log.len = 0;
}
@ -1546,8 +1554,8 @@ redo:
len = max;
}
newcapa = HAWK_ALIGN_POW2(hawk->log.len + len, 512); /* TODO: adjust this capacity */
if (newcapa > hawk->option.log_maxcapa)
newcapa = HAWK_ALIGN_POW2(hawk->log.len + len, HAWK_LOG_CAPA_ALIGN);
if (newcapa > hawk->opt.log_maxcapa)
{
/* [NOTE]
* it doesn't adjust newcapa to hawk->option.log_maxcapa.
@ -1571,7 +1579,7 @@ redo:
/* no line ending - append a line terminator */
hawk->log.ptr[hawk->log.len++] = '\n';
}
vmprim_log_write (hawk, hawk->log.last_mask, hawk->log.ptr, hawk->log.len);
log_write (hawk, hawk->log.last_mask, hawk->log.ptr, hawk->log.len);
hawk->log.len = 0;
}
@ -1684,7 +1692,7 @@ hawk_ooi_t hawk_logbfmtv (hawk_t* hawk, hawk_bitmask_t mask, const hawk_bch_t* f
if (hawk->log.len > 0 && hawk->log.ptr[hawk->log.len - 1] == '\n')
{
vmprim_log_write (hawk, hawk->log.last_mask, hawk->log.ptr, hawk->log.len);
log_write (hawk, hawk->log.last_mask, hawk->log.ptr, hawk->log.len);
hawk->log.len = 0;
}
@ -1737,7 +1745,7 @@ hawk_ooi_t hawk_logufmtv (hawk_t* hawk, hawk_bitmask_t mask, const hawk_uch_t* f
if (hawk->log.len > 0 && hawk->log.ptr[hawk->log.len - 1] == '\n')
{
vmprim_log_write (hawk, hawk->log.last_mask, hawk->log.ptr, hawk->log.len);
log_write (hawk, hawk->log.last_mask, hawk->log.ptr, hawk->log.len);
hawk->log.len = 0;
}
return (x <= -1)? -1: fo.count;
@ -1754,7 +1762,6 @@ hawk_ooi_t hawk_logufmt (hawk_t* hawk, hawk_bitmask_t mask, const hawk_uch_t* fm
return x;
}
#endif
/* --------------------------------------------------------------------------
* STRING FORMATTING

View File

@ -94,7 +94,7 @@ static hawk_fnc_t sysfnctab[] =
{ {HAWK_T("systime"), 7}, 0, { {A_MAX, 0, HAWK_T("sys") }, HAWK_NULL, 0 }, HAWK_NULL}
};
static hawk_fnc_t* add_fnc (hawk_t* awk, const hawk_ooch_t* name, const hawk_fnc_spec_t* spec)
static hawk_fnc_t* add_fnc (hawk_t* hawk, const hawk_ooch_t* name, const hawk_fnc_spec_t* spec)
{
hawk_fnc_t* fnc;
hawk_oow_t fnc_size;
@ -105,7 +105,7 @@ static hawk_fnc_t* add_fnc (hawk_t* awk, const hawk_ooch_t* name, const hawk_fnc
ncs.len = hawk_count_oocstr(name);
if (ncs.len <= 0)
{
hawk_seterrnum (awk, HAWK_EINVAL, HAWK_NULL);
hawk_seterrnum (hawk, HAWK_EINVAL, HAWK_NULL);
return HAWK_NULL;
}
@ -113,16 +113,16 @@ static hawk_fnc_t* add_fnc (hawk_t* awk, const hawk_ooch_t* name, const hawk_fnc
* such a function registered won't take effect because
* the word is treated as a keyword */
if (hawk_findfncwithoocs(awk, &ncs) != HAWK_NULL)
if (hawk_findfncwithoocs(hawk, &ncs) != HAWK_NULL)
{
hawk_seterrnum (awk, HAWK_EEXIST, &ncs);
hawk_seterrbfmt (hawk, HAWK_NULL, HAWK_EEXIST, "unable to add existing function - %js", name);
return HAWK_NULL;
}
speclen = spec->arg.spec? hawk_count_oocstr(spec->arg.spec): 0;
fnc_size = HAWK_SIZEOF(*fnc) + (ncs.len + 1 + speclen + 1) * HAWK_SIZEOF(hawk_ooch_t);
fnc = (hawk_fnc_t*)hawk_callocmem(awk, fnc_size);
fnc = (hawk_fnc_t*)hawk_callocmem(hawk, fnc_size);
if (fnc)
{
hawk_ooch_t* tmp;
@ -139,10 +139,11 @@ static hawk_fnc_t* add_fnc (hawk_t* awk, const hawk_ooch_t* name, const hawk_fnc
fnc->spec.arg.spec = tmp;
}
if (hawk_htb_insert(awk->fnc.user, (hawk_ooch_t*)ncs.ptr, ncs.len, fnc, 0) == HAWK_NULL)
if (hawk_htb_insert(hawk->fnc.user, (hawk_ooch_t*)ncs.ptr, ncs.len, fnc, 0) == HAWK_NULL)
{
hawk_seterrnum (awk, HAWK_ENOMEM, HAWK_NULL);
hawk_freemem (awk, fnc);
const hawk_ooch_t* bem = hawk_backuperrmsg(hawk);
hawk_seterrbfmt (hawk, HAWK_NULL, hawk_geterrnum(hawk), "unable to add function - %js - %js", name, bem);
hawk_freemem (hawk, fnc);
fnc = HAWK_NULL;
}
}
@ -216,7 +217,7 @@ hawk_fnc_t* hawk_addfncwithucstr (hawk_t* awk, const hawk_uch_t* name, const haw
#endif
}
int hawk_delfncwithbcstr (hawk_t* awk, const hawk_bch_t* name)
int hawk_delfncwithbcstr (hawk_t* hawk, const hawk_bch_t* name)
{
hawk_bcs_t ncs;
hawk_ucs_t wcs;
@ -225,27 +226,27 @@ int hawk_delfncwithbcstr (hawk_t* awk, const hawk_bch_t* name)
ncs.len = hawk_count_bcstr(name);
#if defined(HAWK_OOCH_IS_BCH)
if (hawk_htb_delete(awk->fnc.user, ncs.ptr, ncs.len) <= -1)
if (hawk_htb_delete(hawk->fnc.user, ncs.ptr, ncs.len) <= -1)
{
hawk_seterrnum (awk, HAWK_ENOENT, &ncs);
hawk_seterrbfmt (hawk, HAWK_NULL, HAWK_ENOENT, "no such function - %hs", name);
return -1;
}
#else
wcs.ptr = hawk_dupbtoucstr(awk, ncs.ptr, &wcs.len, 0);
wcs.ptr = hawk_dupbtoucstr(hawk, ncs.ptr, &wcs.len, 0);
if (!wcs.ptr) return -1;
if (hawk_htb_delete(awk->fnc.user, wcs.ptr, wcs.len) <= -1)
if (hawk_htb_delete(hawk->fnc.user, wcs.ptr, wcs.len) <= -1)
{
hawk_seterrnum (awk, HAWK_ENOENT, &wcs);
hawk_freemem (awk, wcs.ptr);
hawk_seterrbfmt (hawk, HAWK_NULL, HAWK_ENOENT, "no such function - %hs", name);
hawk_freemem (hawk, wcs.ptr);
return -1;
}
hawk_freemem (awk, wcs.ptr);
hawk_freemem (hawk, wcs.ptr);
#endif
return 0;
}
int hawk_delfncwithucstr (hawk_t* awk, const hawk_uch_t* name)
int hawk_delfncwithucstr (hawk_t* hawk, const hawk_uch_t* name)
{
hawk_ucs_t ncs;
hawk_bcs_t mbs;
@ -254,19 +255,19 @@ int hawk_delfncwithucstr (hawk_t* awk, const hawk_uch_t* name)
ncs.len = hawk_count_ucstr(name);
#if defined(HAWK_OOCH_IS_BCH)
mbs.ptr = hawk_duputobcstr(awk, ncs.ptr, &mbs.len);
mbs.ptr = hawk_duputobcstr(hawk, ncs.ptr, &mbs.len);
if (!mbs.ptr) return -1;
if (hawk_htb_delete(awk->fnc.user, mbs.ptr, mbs.len) <= -1)
if (hawk_htb_delete(hawk->fnc.user, mbs.ptr, mbs.len) <= -1)
{
hawk_seterrnum (awk, HAWK_ENOENT, &mbs);
hawk_freemem (awk, mbs.ptr);
hawk_seterrbfmt (hawk, HAWK_NULL, HAWK_ENOENT, "no such function - %ls", name);
hawk_freemem (hawk, mbs.ptr);
return -1;
}
hawk_freemem (awk, mbs.ptr);
hawk_freemem (hawk, mbs.ptr);
#else
if (hawk_htb_delete(awk->fnc.user, ncs.ptr, ncs.len) <= -1)
if (hawk_htb_delete(hawk->fnc.user, ncs.ptr, ncs.len) <= -1)
{
hawk_seterrnum (awk, HAWK_ENOENT, &ncs);
hawk_seterrbfmt (hawk, HAWK_NULL, HAWK_ENOENT, "no such function - %ls", name);
return -1;
}
#endif
@ -303,7 +304,7 @@ static hawk_fnc_t* find_fnc (hawk_t* awk, const hawk_oocs_t* name)
if ((awk->opt.trait & fnc->spec.trait) == fnc->spec.trait) return fnc;
}
hawk_seterrnum (awk, HAWK_ENOENT, name);
hawk_seterrbfmt (awk, HAWK_NULL, HAWK_ENOENT, "no such function - %js", name);
return HAWK_NULL;
}
@ -1656,7 +1657,7 @@ static HAWK_INLINE int __fnc_asort (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi,
goto done;
}
hawk_rtx_seterrfmt (rtx, HAWK_ENOTMAP, HAWK_NULL, HAWK_T("source not a map"));
hawk_rtx_seterrfmt (rtx, HAWK_NULL, HAWK_ENOTMAP, HAWK_T("source not a map"));
return -1;
}
@ -1672,7 +1673,7 @@ static HAWK_INLINE int __fnc_asort (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi,
a2 = hawk_rtx_getarg(rtx, 2);
if (HAWK_RTX_GETVALTYPE(rtx, a2) != HAWK_VAL_FUN)
{
hawk_rtx_seterrfmt (rtx, HAWK_EINVAL, HAWK_NULL, HAWK_T("comparator not a function"));
hawk_rtx_seterrfmt (rtx, HAWK_NULL, HAWK_EINVAL, HAWK_T("comparator not a function"));
return -1;
}
@ -1680,7 +1681,7 @@ static HAWK_INLINE int __fnc_asort (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi,
if (fun->nargs < 2)
{
/* the comparison accepts less than 2 arguments */
hawk_rtx_seterrfmt (rtx, HAWK_EINVAL, HAWK_NULL, HAWK_T("%.*s not accepting 2 arguments"), (int)fun->name.len, fun->name.ptr);
hawk_rtx_seterrfmt (rtx, HAWK_NULL, HAWK_EINVAL, HAWK_T("%.*js not accepting 2 arguments"), fun->name.len, fun->name.ptr);
return -1;
}
}

View File

@ -928,6 +928,27 @@ struct hawk_gem_t
hawk_loc_t errloc;
};
enum hawk_log_mask_t
{
HAWK_LOG_DEBUG = (1u << 0),
HAWK_LOG_INFO = (1u << 1),
HAWK_LOG_WARN = (1u << 2),
HAWK_LOG_ERROR = (1u << 3),
HAWK_LOG_FATAL = (1u << 4),
HAWK_LOG_UNTYPED = (1u << 6), /* only to be used by HAWK_DEBUGx() and HAWK_INFOx() */
HAWK_LOG_PARSER = (1u << 7),
HAWK_LOG_RTX = (1u << 8),
HAWK_LOG_APP = (1u << 9),
HAWK_LOG_ALL_LEVELS = (HAWK_LOG_DEBUG | HAWK_LOG_INFO | HAWK_LOG_WARN | HAWK_LOG_ERROR | HAWK_LOG_FATAL),
HAWK_LOG_ALL_TYPES = (HAWK_LOG_UNTYPED | HAWK_LOG_PARSER | HAWK_LOG_RTX | HAWK_LOG_APP),
HAWK_LOG_STDOUT = (1u << 14), /* write log messages to stdout without timestamp. HAWK_LOG_STDOUT wins over HAWK_LOG_STDERR. */
HAWK_LOG_STDERR = (1u << 15) /* write log messages to stderr without timestamp. */
};
typedef enum hawk_log_mask_t hawk_log_mask_t;
/* =========================================================================
* MACROS THAT CHANGES THE BEHAVIORS OF THE C COMPILER/LINKER
* =========================================================================*/

View File

@ -209,6 +209,8 @@ struct hawk_t
} depth;
hawk_oow_t rtx_stack_limit;
hawk_oow_t log_mask;
hawk_oow_t log_maxcapa;
} opt;
/* parse tree */
@ -317,6 +319,16 @@ struct hawk_t
hawk_bch_t berrmsg[HAWK_ERRMSG_CAPA * 2];
#endif
struct
{
hawk_ooch_t* ptr;
hawk_oow_t len;
hawk_oow_t capa;
hawk_bitmask_t last_mask;
hawk_bitmask_t default_type_mask;
} log;
int shuterr;
int haltall;
hawk_ecb_t* ecb;

View File

@ -183,6 +183,8 @@ int hawk_init (hawk_t* awk, hawk_mmgr_t* mmgr, hawk_cmgr_t* cmgr, const hawk_prm
awk->opt.trait |= HAWK_CRLF;
#endif
awk->opt.rtx_stack_limit = HAWK_DFL_RTX_STACK_LIMIT;
awk->opt.log_mask = HAWK_LOG_ALL_LEVELS | HAWK_LOG_ALL_TYPES;
awk->opt.log_maxcapa = HAWK_DFL_LOG_MAXCAPA;
awk->tree.ngbls = 0;
awk->tree.ngbls_base = 0;
@ -423,12 +425,12 @@ static int dup_str_opt (hawk_t* awk, const void* value, hawk_oocs_t* tmp)
return 0;
}
int hawk_setopt (hawk_t* awk, hawk_opt_t id, const void* value)
int hawk_setopt (hawk_t* hawk, hawk_opt_t id, const void* value)
{
switch (id)
{
case HAWK_TRAIT:
awk->opt.trait = *(const int*)value;
hawk->opt.trait = *(const int*)value;
return 0;
case HAWK_MODPREFIX:
@ -437,21 +439,21 @@ int hawk_setopt (hawk_t* awk, hawk_opt_t id, const void* value)
hawk_oocs_t tmp;
int idx;
if (dup_str_opt (awk, value, &tmp) <= -1) return -1;
if (dup_str_opt(hawk, value, &tmp) <= -1) return -1;
idx = id - HAWK_MODPREFIX;
if (awk->opt.mod[idx].ptr) hawk_freemem (awk, awk->opt.mod[idx].ptr);
if (hawk->opt.mod[idx].ptr) hawk_freemem (hawk, hawk->opt.mod[idx].ptr);
awk->opt.mod[idx] = tmp;
hawk->opt.mod[idx] = tmp;
return 0;
}
case HAWK_INCLUDEDIRS:
{
hawk_oocs_t tmp;
if (dup_str_opt (awk, value, &tmp) <= -1) return -1;
if (awk->opt.incldirs.ptr) hawk_freemem (awk, awk->opt.incldirs.ptr);
awk->opt.incldirs = tmp;
if (dup_str_opt(hawk, value, &tmp) <= -1) return -1;
if (hawk->opt.incldirs.ptr) hawk_freemem (hawk, hawk->opt.incldirs.ptr);
hawk->opt.incldirs = tmp;
return 0;
}
@ -462,35 +464,45 @@ int hawk_setopt (hawk_t* awk, hawk_opt_t id, const void* value)
case HAWK_DEPTH_EXPR_RUN:
case HAWK_DEPTH_REX_BUILD:
case HAWK_DEPTH_REX_MATCH:
awk->opt.depth.a[id - HAWK_DEPTH_INCLUDE] = *(const hawk_oow_t*)value;
hawk->opt.depth.a[id - HAWK_DEPTH_INCLUDE] = *(const hawk_oow_t*)value;
return 0;
case HAWK_RTX_STACK_LIMIT:
awk->opt.rtx_stack_limit = *(const hawk_oow_t*)value;
if (awk->opt.rtx_stack_limit < HAWK_MIN_RTX_STACK_LIMIT) awk->opt.rtx_stack_limit = HAWK_MIN_RTX_STACK_LIMIT;
else if (awk->opt.rtx_stack_limit > HAWK_MAX_RTX_STACK_LIMIT) awk->opt.rtx_stack_limit = HAWK_MAX_RTX_STACK_LIMIT;
hawk->opt.rtx_stack_limit = *(const hawk_oow_t*)value;
if (hawk->opt.rtx_stack_limit < HAWK_MIN_RTX_STACK_LIMIT) hawk->opt.rtx_stack_limit = HAWK_MIN_RTX_STACK_LIMIT;
else if (hawk->opt.rtx_stack_limit > HAWK_MAX_RTX_STACK_LIMIT) hawk->opt.rtx_stack_limit = HAWK_MAX_RTX_STACK_LIMIT;
return 0;
case HAWK_LOG_MASK:
hawk->opt.log_mask = *(hawk_bitmask_t*)value;
return 0;
case HAWK_LOG_MAXCAPA:
hawk->opt.log_maxcapa = *(hawk_oow_t*)value;
return 0;
}
hawk_seterrnum (awk, HAWK_EINVAL, HAWK_NULL);
hawk_seterrnum (hawk, HAWK_EINVAL, HAWK_NULL);
return -1;
}
int hawk_getopt (hawk_t* awk, hawk_opt_t id, void* value)
int hawk_getopt (hawk_t* hawk, hawk_opt_t id, void* value)
{
switch (id)
{
case HAWK_TRAIT:
*(int*)value = awk->opt.trait;
*(int*)value = hawk->opt.trait;
return 0;
case HAWK_MODPREFIX:
case HAWK_MODPOSTFIX:
*(const hawk_ooch_t**)value = awk->opt.mod[id - HAWK_MODPREFIX].ptr;
*(const hawk_ooch_t**)value = hawk->opt.mod[id - HAWK_MODPREFIX].ptr;
return 0;
case HAWK_INCLUDEDIRS:
*(const hawk_ooch_t**)value = awk->opt.incldirs.ptr;
*(const hawk_ooch_t**)value = hawk->opt.incldirs.ptr;
return 0;
case HAWK_DEPTH_INCLUDE:
@ -500,15 +512,24 @@ int hawk_getopt (hawk_t* awk, hawk_opt_t id, void* value)
case HAWK_DEPTH_EXPR_RUN:
case HAWK_DEPTH_REX_BUILD:
case HAWK_DEPTH_REX_MATCH:
*(hawk_oow_t*)value = awk->opt.depth.a[id - HAWK_DEPTH_INCLUDE];
*(hawk_oow_t*)value = hawk->opt.depth.a[id - HAWK_DEPTH_INCLUDE];
return 0;
case HAWK_RTX_STACK_LIMIT:
*(hawk_oow_t*)value = awk->opt.rtx_stack_limit;
*(hawk_oow_t*)value = hawk->opt.rtx_stack_limit;
return 0;
case HAWK_LOG_MASK:
*(hawk_bitmask_t*)value = hawk->opt.log_mask;
return 0;
case HAWK_LOG_MAXCAPA:
*(hawk_oow_t*)value = hawk->opt.log_maxcapa;
return 0;
};
hawk_seterrnum (awk, HAWK_EINVAL, HAWK_NULL);
hawk_seterrnum (hawk, HAWK_EINVAL, HAWK_NULL);
return -1;
}

View File

@ -481,6 +481,15 @@ typedef void (*hawk_mod_close_t) (
/* ------------------------------------------------------------------------ */
typedef void (*hawk_log_write_t) (
hawk_t* hawk,
hawk_bitmask_t mask,
const hawk_ooch_t* msg,
hawk_oow_t len
);
/* ------------------------------------------------------------------------ */
#if 0
typedef void* (*hawk_buildrex_t) (
hawk_t* awk,
@ -711,6 +720,7 @@ struct hawk_prm_t
hawk_mod_close_t modclose;
hawk_mod_getsym_t modgetsym;
hawk_log_write_t logwrite;
#if 0
struct
{
@ -1112,10 +1122,15 @@ enum hawk_opt_t
HAWK_DEPTH_REX_BUILD,
HAWK_DEPTH_REX_MATCH,
HAWK_RTX_STACK_LIMIT
HAWK_RTX_STACK_LIMIT,
HAWK_LOG_MASK,
HAWK_LOG_MAXCAPA
};
typedef enum hawk_opt_t hawk_opt_t;
#define HAWK_LOG_CAPA_ALIGN (512)
#define HAWK_DFL_LOG_MAXCAPA (HAWK_LOG_CAPA_ALIGN * 16)
/* ------------------------------------------------------------------------ */
/**
@ -1585,16 +1600,16 @@ HAWK_EXPORT void hawk_seterrnum (
HAWK_EXPORT void hawk_seterrbfmt (
hawk_t* awk,
const hawk_loc_t* errloc,
hawk_errnum_t errnum,
hawk_loc_t* errloc,
const hawk_bch_t* errfmt,
...
);
HAWK_EXPORT void hawk_seterrufmt (
hawk_t* awk,
const hawk_loc_t* errloc,
hawk_errnum_t errnum,
hawk_loc_t* errloc,
const hawk_uch_t* errfmt,
...
);
@ -2424,16 +2439,16 @@ HAWK_EXPORT void hawk_rtx_seterrinf (
HAWK_EXPORT void hawk_rtx_seterrbfmt (
hawk_rtx_t* rtx,
hawk_errnum_t errnum,
const hawk_loc_t* errloc,
hawk_errnum_t errnum,
const hawk_bch_t* errfmt,
...
);
HAWK_EXPORT void hawk_rtx_seterrufmt (
hawk_rtx_t* rtx,
hawk_errnum_t errnum,
const hawk_loc_t* errloc,
hawk_errnum_t errnum,
const hawk_uch_t* errfmt,
...
);

View File

@ -126,8 +126,7 @@ HAWK_INLINE void hawk_htb_freepair (hawk_htb_t* htb, pair_t* pair)
hawk_gem_freemem (htb->gem, pair);
}
static HAWK_INLINE pair_t* change_pair_val (
hawk_htb_t* htb, pair_t* pair, void* vptr, hawk_oow_t vlen)
static HAWK_INLINE pair_t* change_pair_val (hawk_htb_t* htb, pair_t* pair, void* vptr, hawk_oow_t vlen)
{
if (VPTR(pair) == vptr && VLEN(pair) == vlen)
{
@ -160,9 +159,7 @@ static HAWK_INLINE pair_t* change_pair_val (
else
{
/* need to reconstruct the pair */
pair_t* p = hawk_htb_allocpair (htb,
KPTR(pair), KLEN(pair),
vptr, vlen);
pair_t* p = hawk_htb_allocpair(htb, KPTR(pair), KLEN(pair), vptr, vlen);
if (p == HAWK_NULL) return HAWK_NULL;
hawk_htb_freepair (htb, pair);
return p;
@ -183,7 +180,6 @@ static HAWK_INLINE pair_t* change_pair_val (
}
}
return pair;
}
@ -367,6 +363,7 @@ pair_t* hawk_htb_search (const hawk_htb_t* htb, const void* kptr, hawk_oow_t kle
pair = NEXT(pair);
}
hawk_gem_seterrnum (htb->gem, HAWK_NULL, HAWK_ENOENT);
return HAWK_NULL;
}
@ -466,8 +463,7 @@ static HAWK_INLINE pair_t* insert (hawk_htb_t* htb, void* kptr, hawk_oow_t klen,
/* old pair destroyed. new pair reallocated.
* relink to include the new pair but to drop
* the old pair. */
if (prev == HAWK_NULL)
htb->bucket[hc] = p;
if (prev == HAWK_NULL) htb->bucket[hc] = p;
else NEXT(prev) = p;
NEXT(p) = next;
}
@ -479,6 +475,7 @@ static HAWK_INLINE pair_t* insert (hawk_htb_t* htb, void* kptr, hawk_oow_t klen,
case INSERT:
/* return failure */
hawk_gem_seterrnum (htb->gem, HAWK_NULL, HAWK_EEXIST);
return HAWK_NULL;
}
}
@ -487,7 +484,11 @@ static HAWK_INLINE pair_t* insert (hawk_htb_t* htb, void* kptr, hawk_oow_t klen,
pair = next;
}
if (opt == UPDATE) return HAWK_NULL;
if (opt == UPDATE)
{
hawk_gem_seterrnum (htb->gem, HAWK_NULL, HAWK_ENOENT);
return HAWK_NULL;
}
if (htb->threshold > 0 && htb->size >= htb->threshold)
{
@ -559,8 +560,7 @@ pair_t* hawk_htb_cbsert (hawk_htb_t* htb, void* kptr, hawk_oow_t klen, cbserter_
/* old pair destroyed. new pair reallocated.
* relink to include the new pair but to drop
* the old pair. */
if (prev == HAWK_NULL)
htb->bucket[hc] = p;
if (prev == HAWK_NULL) htb->bucket[hc] = p;
else NEXT(prev) = p;
NEXT(p) = next;
}
@ -620,6 +620,7 @@ int hawk_htb_delete (hawk_htb_t* htb, const void* kptr, hawk_oow_t klen)
pair = NEXT(pair);
}
hawk_gem_seterrnum (htb->gem, HAWK_NULL, HAWK_ENOENT);
return -1;
}

View File

@ -435,7 +435,7 @@ static global_t gtab[] =
#define SETERR_ARG(awk,code,ep,el) SETERR_ARG_LOC(awk,code,ep,el,HAWK_NULL)
#define ADJERR_LOC(rtx,l) do { (awk)->_gem.errloc = *(l); } while (0)
#define ADJERR_LOC(hawk,l) do { (hawk)->_gem.errloc = *(l); } while (0)
static HAWK_INLINE int is_plain_var (hawk_nde_t* nde)
{
@ -942,7 +942,7 @@ static int parse_progunit (hawk_t* awk)
if (get_token(awk) <= -1) return -1;
if (!MATCH(awk, TOK_IDENT))
{
hawk_seterrfmt (awk, HAWK_EIDENT, &awk->ptok.loc, HAWK_T("identifier expected for '@pragma'"));
hawk_seterrfmt (awk, &awk->ptok.loc, HAWK_EIDENT, HAWK_T("identifier expected for '@pragma'"));
return -1;
}
@ -957,7 +957,7 @@ static int parse_progunit (hawk_t* awk)
if (!MATCH(awk, TOK_IDENT))
{
error_ident_on_off_expected_for_implicit:
hawk_seterrfmt (awk, HAWK_EIDENT, &awk->ptok.loc, HAWK_T("identifier 'on' or 'off' expected for 'implicit'"));
hawk_seterrfmt (awk, &awk->ptok.loc, HAWK_EIDENT, HAWK_T("identifier 'on' or 'off' expected for 'implicit'"));
return -1;
}
@ -997,7 +997,7 @@ static int parse_progunit (hawk_t* awk)
}
else
{
hawk_seterrfmt (awk, HAWK_EIDENT, &awk->ptok.loc, HAWK_T("unknown @pragma identifier - %.*s"), (int)name.len, name.ptr);
hawk_seterrfmt (awk, &awk->ptok.loc, HAWK_EIDENT, HAWK_T("unknown @pragma identifier - %.*js"), name.len, name.ptr);
return -1;
}
@ -1188,8 +1188,7 @@ static int parse_progunit (hawk_t* awk)
}
/* skip a semicolon after an action block if any */
if (MATCH(awk,TOK_SEMICOLON) &&
get_token (awk) <= -1) return -1;
if (MATCH(awk,TOK_SEMICOLON) && get_token(awk) <= -1) return -1;
}
}
@ -1409,7 +1408,7 @@ static hawk_nde_t* parse_function (hawk_t* awk)
/* if hawk_htb_insert() fails for other reasons than memory
* shortage, there should be implementaion errors as duplicate
* functions are detected earlier in this function */
SETERR_LOC (awk, HAWK_ENOMEM, &awk->tok.loc);
ADJERR_LOC (awk, &awk->tok.loc);
goto oops;
}
@ -1878,11 +1877,9 @@ static int add_global (hawk_t* awk, const hawk_oocs_t* name, hawk_loc_t* xloc, i
return -1;
}
if (hawk_arr_insert (awk->parse.gbls,
HAWK_ARR_SIZE(awk->parse.gbls),
(hawk_ooch_t*)name->ptr, name->len) == HAWK_ARR_NIL)
if (hawk_arr_insert(awk->parse.gbls, HAWK_ARR_SIZE(awk->parse.gbls), (hawk_ooch_t*)name->ptr, name->len) == HAWK_ARR_NIL)
{
SETERR_LOC (awk, HAWK_ENOMEM, xloc);
ADJERR_LOC (awk, xloc);
return -1;
}
@ -5350,7 +5347,7 @@ static hawk_nde_t* parse_primary_ident_noseg (hawk_t* awk, const hawk_loc_t* xlo
* for reference */
if (hawk_htb_upsert(awk->parse.named, name->ptr, name->len, HAWK_NULL, 0) == HAWK_NULL)
{
SETERR_LOC (awk, HAWK_ENOMEM, xloc);
ADJERR_LOC (awk, xloc);
hawk_freemem (awk, tmp);
}
else
@ -5762,7 +5759,7 @@ make_node:
/* store a non-builtin function call into the awk->parse.funs table */
if (!hawk_htb_upsert(awk->parse.funs, name->ptr, name->len, call, 0))
{
SETERR_LOC (awk, HAWK_ENOMEM, xloc);
ADJERR_LOC (awk, xloc);
goto oops;
}
}
@ -7159,12 +7156,12 @@ static hawk_mod_t* query_module (hawk_t* awk, const hawk_oocs_t segs[], int nseg
{
if (hawk_geterrnum(awk) == HAWK_ENOERR)
{
hawk_seterrfmt (awk, HAWK_ENOENT, HAWK_NULL, HAWK_T("module '%.*js' not found"), (int)segs[0].len, segs[0].ptr);
hawk_seterrfmt (awk, HAWK_NULL, HAWK_ENOENT, HAWK_T("module '%.*js' not found"), segs[0].len, segs[0].ptr);
}
else
{
const hawk_ooch_t* olderrmsg = hawk_backuperrmsg(awk);
hawk_seterrfmt (awk, HAWK_ENOENT, HAWK_NULL, HAWK_T("module '%.*js' not found - %js"), (int)segs[0].len, segs[0].ptr, olderrmsg);
hawk_seterrfmt (awk, HAWK_NULL, HAWK_ENOENT, HAWK_T("module '%.*js' not found - %js"), segs[0].len, segs[0].ptr, olderrmsg);
}
return HAWK_NULL;
}
@ -7188,12 +7185,12 @@ static hawk_mod_t* query_module (hawk_t* awk, const hawk_oocs_t segs[], int nseg
{
if (hawk_geterrnum(awk) == HAWK_ENOERR)
{
hawk_seterrfmt (awk, HAWK_ENOENT, HAWK_NULL, HAWK_T("module '%.*js' not found"), (int)(12 + buflen));
hawk_seterrfmt (awk, HAWK_NULL, HAWK_ENOENT, HAWK_T("module '%.*js' not found"), (12 + buflen), &buf[1]);
}
else
{
const hawk_ooch_t* olderrmsg = hawk_backuperrmsg(awk);
hawk_seterrfmt (awk, HAWK_ENOENT, HAWK_NULL, HAWK_T("module '%.*js' not found - %js"), (int)(12 + buflen), &buf[1], olderrmsg);
const hawk_ooch_t* bem = hawk_backuperrmsg(awk);
hawk_seterrfmt (awk, HAWK_NULL, HAWK_ENOENT, HAWK_T("module '%.*js' not found - %js"), (12 + buflen), &buf[1], bem);
}
awk->prm.modclose (awk, md.handle);
return HAWK_NULL;
@ -7227,12 +7224,12 @@ done:
{
if (hawk_geterrnum(awk) == HAWK_ENOERR)
{
hawk_seterrfmt (awk, HAWK_ENOENT, HAWK_NULL, HAWK_T("unable to find '%.*js' in module '%.*js'"), (int)segs[1].len, segs[1].ptr, (int)segs[0].len, segs[0].ptr);
hawk_seterrfmt (awk, HAWK_NULL, HAWK_ENOENT, HAWK_T("unable to find '%.*js' in module '%.*js'"), segs[1].len, segs[1].ptr, segs[0].len, segs[0].ptr);
}
else
{
const hawk_ooch_t* olderrmsg = hawk_backuperrmsg(awk);
hawk_seterrfmt (awk, HAWK_ENOENT, HAWK_NULL, HAWK_T("unable to find '%.*js' in module '%.*js' - %js"), (int)segs[1].len, segs[1].ptr, (int)segs[0].len, segs[0].ptr, olderrmsg);
hawk_seterrfmt (awk, HAWK_NULL, HAWK_ENOENT, HAWK_T("unable to find '%.*js' in module '%.*js' - %js"), segs[1].len, segs[1].ptr, segs[0].len, segs[0].ptr, olderrmsg);
}
return HAWK_NULL;
}

View File

@ -939,7 +939,7 @@ static int init_rtx (hawk_rtx_t* rtx, hawk_t* awk, hawk_rio_cbs_t* rio)
if (hawk_becs_init(&rtx->formatmbs.out, hawk_rtx_getgem(rtx), 256) <= -1) goto oops_6;
if (hawk_becs_init(&rtx->formatmbs.fmt, hawk_rtx_getgem(rtx), 256) <= -1) goto oops_7;
rtx->named = hawk_htb_open(hawk_rtx_gethawk(rtx), HAWK_SIZEOF(rtx), 1024, 70, HAWK_SIZEOF(hawk_ooch_t), 1);
rtx->named = hawk_htb_open(hawk_rtx_getgem(rtx), HAWK_SIZEOF(rtx), 1024, 70, HAWK_SIZEOF(hawk_ooch_t), 1);
if (!rtx->named) goto oops_8;
*(hawk_rtx_t**)hawk_htb_getxtn(rtx->named) = rtx;
hawk_htb_setstyle (rtx->named, &style_for_named);
@ -2542,12 +2542,7 @@ static int delete_indexed (
if (HAWK_RTX_GETVALTYPE(rtx, idx) == HAWK_VAL_STR)
{
/* delete x["abc"] */
hawk_htb_delete (
map,
((hawk_val_str_t*)idx)->val.ptr,
((hawk_val_str_t*)idx)->val.len
);
hawk_htb_delete (map, ((hawk_val_str_t*)idx)->val.ptr, ((hawk_val_str_t*)idx)->val.len);
hawk_rtx_refdownval (rtx, idx);
}
else
@ -2621,7 +2616,7 @@ static int run_delete_named (hawk_rtx_t* rtx, hawk_nde_var_t* var)
{
hawk_rtx_refupval (rtx, tmp);
hawk_rtx_refdownval (rtx, tmp);
SETERR_LOC (rtx, HAWK_ENOMEM, &var->loc);
ADJERR_LOC (rtx, &var->loc);
return -1;
}
@ -3533,7 +3528,7 @@ static hawk_val_t* do_assignment_nonidx (hawk_rtx_t* run, hawk_nde_var_t* var, h
if (hawk_htb_upsert (run->named, var->id.name.ptr, var->id.name.len, val, 0) == HAWK_NULL)
{
SETERR_LOC (run, HAWK_ENOMEM, &var->loc);
ADJERR_LOC (run, &var->loc);
return HAWK_NULL;
}
@ -3636,9 +3631,7 @@ retry:
{
hawk_htb_pair_t* pair;
pair = hawk_htb_search(rtx->named, var->id.name.ptr, var->id.name.len);
map = (pair == HAWK_NULL)?
(hawk_val_map_t*)hawk_val_nil:
(hawk_val_map_t*)HAWK_HTB_VPTR(pair);
map = (pair == HAWK_NULL)? (hawk_val_map_t*)hawk_val_nil: (hawk_val_map_t*)HAWK_HTB_VPTR(pair);
break;
}
@ -3679,7 +3672,7 @@ retry:
if (hawk_htb_upsert(rtx->named, var->id.name.ptr, var->id.name.len, tmp, 0) == HAWK_NULL)
{
hawk_rtx_refdownval (rtx, tmp);
SETERR_LOC (rtx, HAWK_ENOMEM, &var->loc);
ADJERR_LOC (rtx, &var->loc);
return HAWK_NULL;
}
@ -3755,7 +3748,7 @@ retry:
if (hawk_htb_upsert(map->map, str, len, val, 0) == HAWK_NULL)
{
if (str != idxbuf) hawk_rtx_freemem (rtx, str);
SETERR_LOC (rtx, HAWK_ENOMEM, &var->loc);
ADJERR_LOC (rtx, &var->loc);
return HAWK_NULL;
}
@ -4077,8 +4070,7 @@ static hawk_val_t* eval_binop_in (hawk_rtx_t* rtx, hawk_nde_t* left, hawk_nde_t*
hawk_htb_t* map;
map = ((hawk_val_map_t*)rv)->map;
res = (hawk_htb_search (map, str, len) == HAWK_NULL)?
HAWK_VAL_ZERO: HAWK_VAL_ONE;
res = (hawk_htb_search(map, str, len) == HAWK_NULL)? HAWK_VAL_ZERO: HAWK_VAL_ONE;
if (str != idxbuf) hawk_rtx_freemem (rtx, str);
hawk_rtx_refdownval (rtx, rv);
@ -6285,7 +6277,7 @@ static int get_reference (hawk_rtx_t* rtx, hawk_nde_t* nde, hawk_val_t*** ref)
pair = hawk_htb_upsert(rtx->named, tgt->id.name.ptr, tgt->id.name.len, hawk_val_nil, 0);
if (!pair)
{
SETERR_LOC (rtx, HAWK_ENOMEM, &nde->loc);
ADJERR_LOC (rtx, &nde->loc);
return -1;
}
}
@ -6317,7 +6309,7 @@ static int get_reference (hawk_rtx_t* rtx, hawk_nde_t* nde, hawk_val_t*** ref)
pair = hawk_htb_upsert(rtx->named, tgt->id.name.ptr, tgt->id.name.len, hawk_val_nil, 0);
if (pair == HAWK_NULL)
{
SETERR_LOC (rtx, HAWK_ENOMEM, &nde->loc);
ADJERR_LOC (rtx, &nde->loc);
return -1;
}
}
@ -6428,7 +6420,7 @@ static hawk_val_t** get_reference_indexed (hawk_rtx_t* rtx, hawk_nde_var_t* nde,
if (pair == HAWK_NULL)
{
if (str != idxbuf) hawk_rtx_freemem (rtx, str);
SETERR_LOC (rtx, HAWK_ENOMEM, &nde->loc);
ADJERR_LOC (rtx, &nde->loc);
return HAWK_NULL;
}
@ -6586,7 +6578,7 @@ static hawk_val_t* eval_namedidx (hawk_rtx_t* rtx, hawk_nde_t* nde)
pair = hawk_htb_upsert(rtx->named, tgt->id.name.ptr, tgt->id.name.len, hawk_val_nil, 0);
if (pair == HAWK_NULL)
{
SETERR_LOC (rtx, HAWK_ENOMEM, &nde->loc);
ADJERR_LOC (rtx, &nde->loc);
return HAWK_NULL;
}
@ -6807,7 +6799,7 @@ static int __raw_push (hawk_rtx_t* rtx, void* val)
rtx->stack = tmp;
rtx->stack_limit = n;
*/
hawk_rtx_seterrfmt (rtx, HAWK_ESTACK, HAWK_NULL, HAWK_T("runtime stack full"));
hawk_rtx_seterrfmt (rtx, HAWK_NULL, HAWK_ESTACK, HAWK_T("runtime stack full"));
return -1;
}
@ -6832,7 +6824,7 @@ read_again:
}
#if defined(DEBUG_RUN)
hawk_logfmt (hawk_rtx_gethawk(rtx), HAWK_T("record len = %d str=[%.*s]\n"), (int)HAWK_OOECS_LEN(buf), (int)HAWK_OOECS_LEN(buf), HAWK_OOECS_PTR(buf));
hawk_logfmt (hawk_rtx_gethawk(rtx), HAWK_T("record len = %d str=[%.*js]\n"), (int)HAWK_OOECS_LEN(buf), HAWK_OOECS_LEN(buf), HAWK_OOECS_PTR(buf));
#endif
if (n == 0)
{

View File

@ -71,6 +71,12 @@
# endif
#endif
enum logfd_flag_t
{
LOGFD_TTY = (1 << 0),
LOGFD_OPENED_HERE = (1 << 1)
};
typedef struct xtn_t
{
struct
@ -133,6 +139,18 @@ typedef struct xtn_t
hawk_ecb_t ecb;
int stdmod_up;
struct
{
int fd;
int fd_flag; /* bitwise OR'ed fo logfd_flag_t bits */
struct
{
hawk_bch_t buf[4096];
hawk_oow_t len;
} out;
} log;
} xtn_t;
typedef struct rxtn_t
@ -202,9 +220,8 @@ static hawk_mmgr_t sys_mmgr =
HAWK_NULL
};
/* ========================================================================= */
/* ----------------------------------------------------------------------- */
static ioattr_t* get_ioattr (hawk_htb_t* tab, const hawk_ooch_t* ptr, hawk_oow_t len);
hawk_flt_t hawk_stdmathpow (hawk_t* awk, hawk_flt_t x, hawk_flt_t y)
{
@ -428,16 +445,12 @@ void* hawk_stdmodopen (hawk_t* awk, const hawk_mod_spec_t* spec)
#else
modpath = hawk_dupucstrarrtobcstr(awk, tmp, HAWK_NULL);
#endif
if (!modpath)
{
hawk_seterrnum (awk, HAWK_ENOMEM, HAWK_NULL);
return HAWK_NULL;
}
if (!modpath) return HAWK_NULL;
h = dlopen(modpath, RTLD_NOW);
if (!h)
{
hawk_seterrfmt (awk, HAWK_ESYSERR, HAWK_NULL, HAWK_T("%hs"), dlerror());
hawk_seterrfmt (awk, HAWK_NULL, HAWK_ESYSERR, HAWK_T("%hs"), dlerror());
}
hawk_freemem (awk, modpath);
@ -507,6 +520,292 @@ void* hawk_stdmodgetsym (hawk_t* awk, void* handle, const hawk_ooch_t* name)
return s;
}
/* ----------------------------------------------------------------------- */
static HAWK_INLINE void reset_log_to_default (xtn_t* xtn)
{
#if defined(ENABLE_LOG_INITIALLY)
xtn->log.fd = 2;
xtn->log.fd_flag = 0;
#if defined(HAVE_ISATTY)
if (isatty(xtn->log.fd)) xtn->log.fd_flag |= LOGFD_TTY;
#endif
#else
xtn->log.fd = -1;
xtn->log.fd_flag = 0;
#endif
}
#if defined(EMSCRIPTEN)
EM_JS(int, write_all, (int, const hawk_bch_t* ptr, hawk_oow_t len), {
// UTF8ToString() doesn't handle a null byte in the middle of an array.
// Use the heap memory and pass the right portion to UTF8Decoder.
//console.log ("%s", UTF8ToString(ptr, len));
console.log ("%s", UTF8Decoder.decode(HEAPU8.subarray(ptr, ptr + len)));
return 0;
});
#else
static int write_all (int fd, const hawk_bch_t* ptr, hawk_oow_t len)
{
#if defined(EMSCRIPTEN)
EM_ASM_ ({
// UTF8ToString() doesn't handle a null byte in the middle of an array.
// Use the heap memory and pass the right portion to UTF8Decoder.
//console.log ("%s", UTF8ToString($0, $1));
console.log ("%s", UTF8Decoder.decode(HEAPU8.subarray($0, $0 + $1)));
}, ptr, len);
#else
while (len > 0)
{
hawk_ooi_t wr;
wr = write(fd, ptr, len);
if (wr <= -1)
{
#if defined(EAGAIN) && defined(EWOULDBLOCK) && (EAGAIN == EWOULDBLOCK)
if (errno == EAGAIN) continue;
#else
#if defined(EAGAIN)
if (errno == EAGAIN) continue;
#elif defined(EWOULDBLOCK)
if (errno == EWOULDBLOCK) continue;
#endif
#endif
#if defined(EINTR)
/* TODO: would this interfere with non-blocking nature of this VM? */
if (errno == EINTR) continue;
#endif
return -1;
}
ptr += wr;
len -= wr;
}
#endif
return 0;
}
#endif
static int write_log (hawk_t* hawk, int fd, const hawk_bch_t* ptr, hawk_oow_t len)
{
xtn_t* xtn = GET_XTN(hawk);
while (len > 0)
{
if (xtn->log.out.len > 0)
{
hawk_oow_t rcapa, cplen;
rcapa = HAWK_COUNTOF(xtn->log.out.buf) - xtn->log.out.len;
cplen = (len >= rcapa)? rcapa: len;
HAWK_MEMCPY (&xtn->log.out.buf[xtn->log.out.len], ptr, cplen);
xtn->log.out.len += cplen;
ptr += cplen;
len -= cplen;
if (xtn->log.out.len >= HAWK_COUNTOF(xtn->log.out.buf))
{
int n;
n = write_all(fd, xtn->log.out.buf, xtn->log.out.len);
xtn->log.out.len = 0;
if (n <= -1) return -1;
}
}
else
{
hawk_oow_t rcapa;
rcapa = HAWK_COUNTOF(xtn->log.out.buf);
if (len >= rcapa)
{
if (write_all(fd, ptr, rcapa) <= -1) return -1;
ptr += rcapa;
len -= rcapa;
}
else
{
HAWK_MEMCPY (xtn->log.out.buf, ptr, len);
xtn->log.out.len += len;
ptr += len;
len -= len;
}
}
}
return 0;
}
static void flush_log (hawk_t* hawk, int fd)
{
xtn_t* xtn = GET_XTN(hawk);
if (xtn->log.out.len > 0)
{
write_all (fd, xtn->log.out.buf, xtn->log.out.len);
xtn->log.out.len = 0;
}
}
static void log_write (hawk_t* hawk, hawk_bitmask_t mask, const hawk_ooch_t* msg, hawk_oow_t len)
{
xtn_t* xtn = GET_XTN(hawk);
hawk_bch_t buf[256];
hawk_oow_t ucslen, bcslen, msgidx;
int n, logfd;
if (mask & HAWK_LOG_STDERR) logfd = 2;
else if (mask & HAWK_LOG_STDOUT) logfd = 1;
else
{
logfd = xtn->log.fd;
#if !defined(EMSCRIPTEN)
if (logfd <= -1) return;
#endif
}
/* TODO: beautify the log message.
* do classification based on mask. */
if (!(mask & (HAWK_LOG_STDOUT | HAWK_LOG_STDERR)))
{
#if defined(_WIN32)
TIME_ZONE_INFORMATION tzi;
SYSTEMTIME now;
#else
time_t now;
struct tm tm, *tmp;
#endif
#if defined(HAWK_OOCH_IS_UCH)
char ts[32 * HAWK_BCSIZE_MAX];
#else
char ts[32];
#endif
hawk_oow_t tslen;
#if defined(_WIN32)
/* %z for strftime() in win32 seems to produce a long non-numeric timezone name.
* i don't use strftime() for time formatting. */
GetLocalTime (&now);
if (GetTimeZoneInformation(&tzi) != TIME_ZONE_ID_INVALID)
{
tzi.Bias = -tzi.Bias;
tslen = sprintf(ts, "%04d-%02d-%02d %02d:%02d:%02d %+02.2d%02.2d ",
(int)now.wYear, (int)now.wMonth, (int)now.wDay,
(int)now.wHour, (int)now.wMinute, (int)now.wSecond,
(int)(tzi.Bias / 60), (int)(tzi.Bias % 60));
}
else
{
tslen = sprintf(ts, "%04d-%02d-%02d %02d:%02d:%02d ",
(int)now.wYear, (int)now.wMonth, (int)now.wDay,
(int)now.wHour, (int)now.wMinute, (int)now.wSecond);
}
#elif defined(__OS2__)
now = time(HAWK_NULL);
#if defined(__WATCOMC__)
tmp = _localtime(&now, &tm);
#else
tmp = localtime(&now);
#endif
#if defined(__BORLANDC__)
/* the borland compiler doesn't handle %z properly - it showed 00 all the time */
tslen = strftime(ts, sizeof(ts), "%Y-%m-%d %H:%M:%S %Z ", tmp);
#else
tslen = strftime(ts, sizeof(ts), "%Y-%m-%d %H:%M:%S %z ", tmp);
#endif
if (tslen == 0)
{
tslen = sprintf(ts, "%04d-%02d-%02d %02d:%02d:%02d ", tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
}
#elif defined(__DOS__)
now = time(HAWK_NULL);
tmp = localtime(&now);
/* since i know that %z/%Z is not available in strftime, i switch to sprintf immediately */
tslen = sprintf(ts, "%04d-%02d-%02d %02d:%02d:%02d ", tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
#else
now = time(HAWK_NULL);
#if defined(HAVE_LOCALTIME_R)
tmp = localtime_r(&now, &tm);
#else
tmp = localtime(&now);
#endif
#if defined(HAVE_STRFTIME_SMALL_Z)
tslen = strftime(ts, sizeof(ts), "%Y-%m-%d %H:%M:%S %z ", tmp);
#else
tslen = strftime(ts, sizeof(ts), "%Y-%m-%d %H:%M:%S %Z ", tmp);
#endif
if (tslen == 0)
{
tslen = sprintf(ts, "%04d-%02d-%02d %02d:%02d:%02d ", tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
}
#endif
write_log (hawk, logfd, ts, tslen);
}
if (logfd == xtn->log.fd && (xtn->log.fd_flag & LOGFD_TTY))
{
if (mask & HAWK_LOG_FATAL) write_log (hawk, logfd, "\x1B[1;31m", 7);
else if (mask & HAWK_LOG_ERROR) write_log (hawk, logfd, "\x1B[1;32m", 7);
else if (mask & HAWK_LOG_WARN) write_log (hawk, logfd, "\x1B[1;33m", 7);
}
#if defined(HAWK_OOCH_IS_UCH)
msgidx = 0;
while (len > 0)
{
ucslen = len;
bcslen = HAWK_COUNTOF(buf);
/*n = hawk_convootobchars(hawk, &msg[msgidx], &ucslen, buf, &bcslen);*/
n = hawk_conv_uchars_to_bchars_with_cmgr(&msg[msgidx], &ucslen, buf, &bcslen, hawk_getcmgr(hawk));
if (n == 0 || n == -2)
{
/* n = 0:
* converted all successfully
* n == -2:
* buffer not sufficient. not all got converted yet.
* write what have been converted this round. */
HAWK_ASSERT (hawk, ucslen > 0); /* if this fails, the buffer size must be increased */
/* attempt to write all converted characters */
if (write_log(hawk, logfd, buf, bcslen) <= -1) break;
if (n == 0) break;
else
{
msgidx += ucslen;
len -= ucslen;
}
}
else if (n <= -1)
{
/* conversion error but i just stop here but don't treat it as a hard error. */
break;
}
}
#else
write_log (hawk, logfd, msg, len);
#endif
if (logfd == xtn->log.fd && (xtn->log.fd_flag & LOGFD_TTY))
{
if (mask & (HAWK_LOG_FATAL | HAWK_LOG_ERROR | HAWK_LOG_WARN)) write_log (hawk, logfd, "\x1B[0m", 4);
}
flush_log (hawk, logfd);
}
/* ----------------------------------------------------------------------- */
static int add_globals (hawk_t* awk);
static int add_functions (hawk_t* awk);
@ -523,6 +822,9 @@ static void fini_xtn (hawk_t* awk)
hawk_stdmodshutdown (awk);
xtn->stdmod_up = 0;
}
if ((xtn->log.fd_flag & LOGFD_OPENED_HERE) && xtn->log.fd >= 0) close (xtn->log.fd);
reset_log_to_default (xtn);
}
static void clear_xtn (hawk_t* awk)
@ -543,6 +845,8 @@ hawk_t* hawk_openstdwithmmgr (hawk_mmgr_t* mmgr, hawk_oow_t xtnsize, hawk_cmgr_t
prm.modclose = hawk_stdmodclose;
prm.modgetsym = hawk_stdmodgetsym;
prm.logwrite = log_write;
/* create an object */
awk = hawk_open(mmgr, HAWK_SIZEOF(xtn_t) + xtnsize, cmgr, &prm, errnum);
if (!awk) return HAWK_NULL;
@ -550,6 +854,7 @@ hawk_t* hawk_openstdwithmmgr (hawk_mmgr_t* mmgr, hawk_oow_t xtnsize, hawk_cmgr_t
/* adjust the object size by the sizeof xtn_t so that hawk_getxtn() returns the right pointer. */
awk->_instsize += HAWK_SIZEOF(xtn_t);
#if defined(USE_DLFCN)
if (hawk_setopt(awk, HAWK_MODPOSTFIX, HAWK_T(".so")) <= -1)
{
@ -560,8 +865,8 @@ hawk_t* hawk_openstdwithmmgr (hawk_mmgr_t* mmgr, hawk_oow_t xtnsize, hawk_cmgr_t
/* initialize extension */
xtn = GET_XTN(awk);
/* the extension area has been cleared in hawk_open().
* HAWK_MEMSET (xtn, 0, HAWK_SIZEOF(*xtn));*/
reset_log_to_default (xtn);
/* add intrinsic global variables and functions */
if (add_globals(awk) <= -1 || add_functions(awk) <= -1)
@ -1364,6 +1669,8 @@ int hawk_parsestd (hawk_t* awk, hawk_parsestd_t in[], hawk_parsestd_t* out)
/*** RTX_OPENSTD ***/
static ioattr_t* get_ioattr (hawk_htb_t* tab, const hawk_ooch_t* ptr, hawk_oow_t len);
#if defined(ENABLE_NWIO)
static hawk_ooi_t nwio_handler_open (hawk_rtx_t* rtx, hawk_rio_arg_t* riod, int flags, hawk_nwad_t* nwad, hawk_nwio_tmout_t* tmout)
{
@ -2010,9 +2317,7 @@ static int build_argcv (
hawk_rtx_refupval (rtx, v_tmp);
key_len = hawk_copy_oocstr(key, HAWK_COUNTOF(key), HAWK_T("0"));
if (hawk_htb_upsert (
((hawk_val_map_t*)v_argv)->map,
key, key_len, v_tmp, 0) == HAWK_NULL)
if (hawk_htb_upsert (((hawk_val_map_t*)v_argv)->map, key, key_len, v_tmp, 0) == HAWK_NULL)
{
/* if the assignment operation fails, decrements
* the reference of v_tmp to free it */
@ -2022,7 +2327,6 @@ static int build_argcv (
* map will be freeed when v_argv is freed */
hawk_rtx_refdownval (rtx, v_argv);
hawk_rtx_seterrnum (rtx, HAWK_ENOMEM, HAWK_NULL);
return -1;
}
@ -2045,13 +2349,10 @@ static int build_argcv (
hawk_rtx_refupval (rtx, v_tmp);
if (hawk_htb_upsert (
((hawk_val_map_t*)v_argv)->map,
key, key_len, v_tmp, 0) == HAWK_NULL)
if (hawk_htb_upsert (((hawk_val_map_t*)v_argv)->map, key, key_len, v_tmp, 0) == HAWK_NULL)
{
hawk_rtx_refdownval (rtx, v_tmp);
hawk_rtx_refdownval (rtx, v_argv);
hawk_rtx_seterrnum (rtx, HAWK_ENOMEM, HAWK_NULL);
return -1;
}
}
@ -2201,7 +2502,6 @@ static int build_environ (hawk_rtx_t* rtx, int gbl_id, env_char_t* envarr[])
* map will be freeed when v_env is freed */
hawk_rtx_refdownval (rtx, v_env);
hawk_rtx_seterrnum (rtx, HAWK_ENOMEM, HAWK_NULL);
return -1;
}
@ -2467,8 +2767,7 @@ static HAWK_INLINE void init_ioattr (ioattr_t* ioattr)
}
}
static ioattr_t* get_ioattr (
hawk_htb_t* tab, const hawk_ooch_t* ptr, hawk_oow_t len)
static ioattr_t* get_ioattr (hawk_htb_t* tab, const hawk_ooch_t* ptr, hawk_oow_t len)
{
hawk_htb_pair_t* pair;
@ -2478,8 +2777,7 @@ static ioattr_t* get_ioattr (
return HAWK_NULL;
}
static ioattr_t* find_or_make_ioattr (
hawk_rtx_t* rtx, hawk_htb_t* tab, const hawk_ooch_t* ptr, hawk_oow_t len)
static ioattr_t* find_or_make_ioattr (hawk_rtx_t* rtx, hawk_htb_t* tab, const hawk_ooch_t* ptr, hawk_oow_t len)
{
hawk_htb_pair_t* pair;
@ -2491,10 +2789,7 @@ static ioattr_t* find_or_make_ioattr (
init_ioattr (&ioattr);
pair = hawk_htb_insert(tab, (void*)ptr, len, (void*)&ioattr, HAWK_SIZEOF(ioattr));
if (pair == HAWK_NULL)
{
hawk_rtx_seterrnum (rtx, HAWK_ENOMEM, HAWK_NULL);
}
if (pair == HAWK_NULL) return HAWK_NULL;
}
return (ioattr_t*)HAWK_HTB_VPTR(pair);

View File

@ -483,7 +483,7 @@ hawk_val_t* hawk_rtx_makemapval (hawk_rtx_t* rtx)
val->stat = 0;
val->nstr = 0;
val->fcb = 0;
val->map = hawk_htb_open(run, 256, 70, free_mapval, same_mapval, hawk_rtx_getmmgr(run));
val->map = hawk_htb_open(hawk_rtx_getgem(rtx), 256, 70, free_mapval, same_mapval);
if (val->map == HAWK_NULL)
{
hawk_rtx_freemem (rtx, val);
@ -502,10 +502,9 @@ hawk_val_t* hawk_rtx_makemapval (hawk_rtx_t* rtx)
val->fcb = 0;
val->map = (hawk_htb_t*)(val + 1);
if (hawk_htb_init(val->map, hawk_rtx_gethawk(rtx), 256, 70, HAWK_SIZEOF(hawk_ooch_t), 1) <= -1)
if (hawk_htb_init(val->map, hawk_rtx_getgem(rtx), 256, 70, HAWK_SIZEOF(hawk_ooch_t), 1) <= -1)
{
hawk_rtx_freemem (rtx, val);
hawk_rtx_seterrnum (rtx, HAWK_ENOMEM, HAWK_NULL);
return HAWK_NULL;
}
*(hawk_rtx_t**)hawk_htb_getxtn(val->map) = rtx;
@ -585,13 +584,7 @@ hawk_val_t* hawk_rtx_setmapvalfld (
{
HAWK_ASSERT (hawk_rtx_gethawk(rtx), HAWK_RTX_GETVALTYPE (rtx, map) == HAWK_VAL_MAP);
if (hawk_htb_upsert (
((hawk_val_map_t*)map)->map,
(hawk_ooch_t*)kptr, klen, v, 0) == HAWK_NULL)
{
hawk_rtx_seterrnum (rtx, HAWK_ENOMEM, HAWK_NULL);
return HAWK_NULL;
}
if (hawk_htb_upsert (((hawk_val_map_t*)map)->map, (hawk_ooch_t*)kptr, klen, v, 0) == HAWK_NULL) return HAWK_NULL;
/* the value is passed in by an external party. we can't refup()
* and refdown() the value if htb_upsert() fails. that way, the value
@ -602,9 +595,7 @@ hawk_val_t* hawk_rtx_setmapvalfld (
return v;
}
hawk_val_t* hawk_rtx_getmapvalfld (
hawk_rtx_t* rtx, hawk_val_t* map,
const hawk_ooch_t* kptr, hawk_oow_t klen)
hawk_val_t* hawk_rtx_getmapvalfld (hawk_rtx_t* rtx, hawk_val_t* map, const hawk_ooch_t* kptr, hawk_oow_t klen)
{
hawk_htb_pair_t* pair;
@ -619,7 +610,6 @@ hawk_val_t* hawk_rtx_getmapvalfld (
* so you can easily determine if the key is found by
* checking the error number.
*/
hawk_rtx_seterrnum (rtx, HAWK_EINVAL, HAWK_NULL);
return HAWK_NULL;
}