From bc3173d74a3b83b8526ced17fc43e9ea6912be0c Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Fri, 26 Apr 2019 16:55:57 +0000 Subject: [PATCH] added the typename() builtin awk function and qse_awk_rtx_getvaltypename() --- qse/include/qse/awk/awk.h | 9 +++++++-- qse/lib/awk/fnc.c | 40 ++++++++++++++++++++++++++++++------- qse/lib/awk/misc.c | 5 ++--- qse/lib/awk/mod-str.c | 2 +- qse/lib/awk/run.c | 13 ++++++------ qse/lib/awk/val.c | 24 +++++++++++++++++++--- qse/lib/cmn/tre.c | 17 +++++----------- qse/samples/awk/Makefile.am | 8 -------- qse/samples/awk/Makefile.in | 19 ++++++++---------- 9 files changed, 84 insertions(+), 53 deletions(-) diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index 000357cf..4417187b 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -1400,12 +1400,12 @@ enum qse_awk_val_type_t { /* the values between QSE_AWK_VAL_NIL and QSE_AWK_VAL_MAP inclusive * must be synchronized with an internal table of the __cmp_val - * function in run.c */ + * function in run.c and the __val_type_name in val.c */ QSE_AWK_VAL_NIL = 0, /**< nil */ QSE_AWK_VAL_INT = 1, /**< integer */ QSE_AWK_VAL_FLT = 2, /**< floating-pointer number */ QSE_AWK_VAL_STR = 3, /**< string */ - QSE_AWK_VAL_MBS = 4, /**< byte array */ + QSE_AWK_VAL_MBS = 4, /**< byte array */ QSE_AWK_VAL_MAP = 5, /**< map */ QSE_AWK_VAL_REX = 6, /**< regular expression */ @@ -2607,6 +2607,11 @@ QSE_EXPORT int qse_awk_rtx_getvaltype ( qse_awk_val_t* val ); +QSE_EXPORT const qse_char_t* qse_awk_rtx_getvaltypename ( + qse_awk_rtx_t* rtx, + qse_awk_val_t* val +); + QSE_EXPORT int qse_awk_rtx_getintfromval ( qse_awk_rtx_t* rtx, qse_awk_val_t* val diff --git a/qse/lib/awk/fnc.c b/qse/lib/awk/fnc.c index 20e57b18..5c402ecc 100644 --- a/qse/lib/awk/fnc.c +++ b/qse/lib/awk/fnc.c @@ -26,10 +26,11 @@ #include "awk-prv.h" -static int fnc_close (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi); -static int fnc_fflush (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi); -static int fnc_int (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi); -static int fnc_asort (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi); +static int fnc_close (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi); +static int fnc_fflush (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi); +static int fnc_int (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi); +static int fnc_typename (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi); +static int fnc_asort (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi); #define A_MAX QSE_TYPE_MAX(int) @@ -55,8 +56,9 @@ static qse_awk_fnc_t sysfnctab[] = { {QSE_T("close"), 5}, 0, { {1, 2, QSE_NULL}, fnc_close, QSE_AWK_RIO }, QSE_NULL}, { {QSE_T("fflush"), 6}, 0, { {0, 1, QSE_NULL}, fnc_fflush, QSE_AWK_RIO }, QSE_NULL}, - /* integer conversion */ + /* type info/conversion */ { {QSE_T("int"), 3}, 0, { {1, 1, QSE_NULL}, fnc_int, 0 }, QSE_NULL}, + { {QSE_T("typename"), 8}, 0, { {1, 1, QSE_NULL}, fnc_typename, 0 }, QSE_NULL}, /* array sort */ { {QSE_T("asort"), 5}, 0, { {1, 3, QSE_NULL}, fnc_asort, 0 }, QSE_NULL}, @@ -109,7 +111,7 @@ qse_awk_fnc_t* qse_awk_addfnc (qse_awk_t* awk, const qse_char_t* name, const qse * such a function registered won't take effect because * the word is treated as a keyword */ - if (qse_awk_findfnc (awk, &ncs) != QSE_NULL) + if (qse_awk_findfnc(awk, &ncs) != QSE_NULL) { qse_awk_seterrnum (awk, QSE_AWK_EEXIST, &ncs); return QSE_NULL; @@ -1245,6 +1247,14 @@ int qse_awk_fnc_match (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) if (nargs >= 4) a3 = qse_awk_rtx_getarg(rtx, 3); } +#if 0 + if (QSE_AWK_RTX_GETVALTYPE(rtx, a0) == QSE_AWK_VAL_MBS) + { + str0 = ((qse_awk_val_mbs_t*)a0)->val.ptr; + len0 = ((qse_awk_val_mbs_t*)a0)->val.len; + } +#endif + str0 = qse_awk_rtx_getvalstr(rtx, a0, &len0); if (str0 == QSE_NULL) return -1; @@ -1268,7 +1278,7 @@ int qse_awk_fnc_match (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) qse_awk_rtx_freevalstr (rtx, a0, str0); /* RSTART: 0 on no match */ - idx = (n == 0)? 0: ((qse_awk_int_t)(mat.ptr-str0) + 1); + idx = (n == 0)? 0: ((qse_awk_int_t)(mat.ptr - str0) + 1); x0 = qse_awk_rtx_makeintval(rtx, idx); if (!x0) goto oops; @@ -1471,6 +1481,22 @@ static int fnc_int (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) return 0; } +static int fnc_typename (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) +{ + qse_awk_val_t* a0; + qse_awk_val_t* r; + const qse_char_t* name; + + a0 = qse_awk_rtx_getarg(rtx, 0); + name = qse_awk_rtx_getvaltypename(rtx, a0); + + r = qse_awk_rtx_makestrval(rtx, name, qse_strlen(name)); + if (r == QSE_NULL) return -1; + + qse_awk_rtx_setretval (rtx, r); + return 0; +} + static int fnc_asort (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) { qse_size_t nargs; diff --git a/qse/lib/awk/misc.c b/qse/lib/awk/misc.c index 3002100e..139e8655 100644 --- a/qse/lib/awk/misc.c +++ b/qse/lib/awk/misc.c @@ -740,7 +740,6 @@ int qse_awk_buildrex ( } #if !defined(USE_REX) - static int matchtre ( qse_awk_t* awk, qse_tre_t* tre, int opt, const qse_cstr_t* str, qse_cstr_t* mat, @@ -751,7 +750,7 @@ static int matchtre ( qse_tre_match_t match[10]; QSE_MEMSET (match, 0, QSE_SIZEOF(match)); - n = qse_tre_execx (tre, str->ptr, str->len, match, QSE_COUNTOF(match), opt); + n = qse_tre_execx(tre, str->ptr, str->len, match, QSE_COUNTOF(match), opt); if (n <= -1) { if (QSE_TRE_ERRNUM(tre) == QSE_TRE_ENOMATCH) return 0; @@ -763,7 +762,7 @@ static int matchtre ( #endif *errnum = (QSE_TRE_ERRNUM(tre) == QSE_TRE_ENOMEM)? QSE_AWK_ENOMEM: QSE_AWK_EREXMA; - return -1; + return -1; } QSE_ASSERT (match[0].rm_so != -1); diff --git a/qse/lib/awk/mod-str.c b/qse/lib/awk/mod-str.c index 3105c6c9..03a4e210 100644 --- a/qse/lib/awk/mod-str.c +++ b/qse/lib/awk/mod-str.c @@ -425,7 +425,7 @@ static int query (qse_awk_mod_t* mod, qse_awk_t* awk, const qse_char_t* name, qs { mid = left + (right - left) / 2; - n = qse_strcmp (fnctab[mid].name, name); + n = qse_strcmp(fnctab[mid].name, name); if (n > 0) right = mid - 1; else if (n < 0) left = mid + 1; else diff --git a/qse/lib/awk/run.c b/qse/lib/awk/run.c index 25e8a5dc..55bcdf1c 100644 --- a/qse/lib/awk/run.c +++ b/qse/lib/awk/run.c @@ -6549,7 +6549,7 @@ static qse_awk_val_t* eval_getline (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde) read_console_again: qse_str_clear (&rtx->inrec.lineg); - n = qse_awk_rtx_readio (rtx, p->in_type, dst, buf); + n = qse_awk_rtx_readio(rtx, p->in_type, dst, buf); if (p->in) { @@ -6570,10 +6570,11 @@ read_console_again: QSE_ASSERT (p->in == QSE_NULL); if (rtx->nrflt.limit > 0) { + /* record filter based on record number(NR) */ if (((rtx->gbl.nr / rtx->nrflt.limit) % rtx->nrflt.size) != rtx->nrflt.rank) { - if (update_fnr (rtx, rtx->gbl.fnr + 1, rtx->gbl.nr + 1) <= -1) return QSE_NULL; - /* this jump is a bit dirty. the 'if' block below qse_awk_rtx_readion() + if (update_fnr(rtx, rtx->gbl.fnr + 1, rtx->gbl.nr + 1) <= -1) return QSE_NULL; + /* this jump is a bit dirty. the 'if' block below qse_awk_rtx_readio() * will never be true. but this makes code confusing */ goto read_console_again; } @@ -6583,14 +6584,14 @@ read_console_again: if (p->var == QSE_NULL) { /* set $0 with the input value */ - x = qse_awk_rtx_setrec (rtx, 0, QSE_STR_XSTR(buf)); + x = qse_awk_rtx_setrec(rtx, 0, QSE_STR_XSTR(buf)); if (x <= -1) return QSE_NULL; } else { qse_awk_val_t* v; - v = qse_awk_rtx_makestrvalwithxstr (rtx, QSE_STR_XSTR(buf)); + v = qse_awk_rtx_makestrvalwithxstr(rtx, QSE_STR_XSTR(buf)); if (v == QSE_NULL) { ADJERR_LOC (rtx, &nde->loc); @@ -6605,7 +6606,7 @@ read_console_again: /* update FNR & NR if reading from console */ if (p->in_type == QSE_AWK_IN_CONSOLE && - update_fnr (rtx, rtx->gbl.fnr + 1, rtx->gbl.nr + 1) <= -1) + update_fnr(rtx, rtx->gbl.fnr + 1, rtx->gbl.nr + 1) <= -1) { return QSE_NULL; } diff --git a/qse/lib/awk/val.c b/qse/lib/awk/val.c index 2742c37d..3dbe6350 100644 --- a/qse/lib/awk/val.c +++ b/qse/lib/awk/val.c @@ -40,7 +40,6 @@ static qse_awk_val_str_t awk_zls = { QSE_AWK_VAL_STR, 0, 1, 0, { QSE_T(""), 0 } qse_awk_val_t* qse_awk_val_nil = (qse_awk_val_t*)&awk_nil; qse_awk_val_t* qse_awk_val_zls = (qse_awk_val_t*)&awk_zls; - qse_awk_val_t* qse_getawknilval (void) { return (qse_awk_val_t*)&awk_nil; @@ -747,13 +746,32 @@ int QSE_INLINE qse_awk_rtx_isstaticval (qse_awk_rtx_t* rtx, qse_awk_val_t* val) int qse_awk_rtx_getvaltype (qse_awk_rtx_t* rtx, qse_awk_val_t* val) { - return QSE_AWK_RTX_GETVALTYPE (rtx, val); + return QSE_AWK_RTX_GETVALTYPE(rtx, val); +} + +const qse_char_t* qse_awk_rtx_getvaltypename(qse_awk_rtx_t* rtx, qse_awk_val_t* val) +{ + static const qse_char_t* __val_type_name[] = + { + /* synchronize this table with enum qse_awk_val_type_t in awk.h */ + QSE_T("nil"), + QSE_T("int"), + QSE_T("flt"), + QSE_T("str"), + QSE_T("mbs"), + QSE_T("map"), + QSE_T("rex"), + QSE_T("ref"), + QSE_T("fun") + }; + + return __val_type_name[QSE_AWK_RTX_GETVALTYPE(rtx, val)]; } int qse_awk_rtx_getintfromval (qse_awk_rtx_t* rtx, qse_awk_val_t* val) { - return QSE_AWK_RTX_GETINTFROMVAL (rtx, val); + return QSE_AWK_RTX_GETINTFROMVAL(rtx, val); } void qse_awk_rtx_freeval (qse_awk_rtx_t* rtx, qse_awk_val_t* val, int cache) diff --git a/qse/lib/cmn/tre.c b/qse/lib/cmn/tre.c index ee08d552..879a299c 100644 --- a/qse/lib/cmn/tre.c +++ b/qse/lib/cmn/tre.c @@ -78,9 +78,7 @@ void* qse_tre_getxtn (qse_tre_t* tre) return QSE_XTN (tre); } -int qse_tre_compx ( - qse_tre_t* tre, const qse_char_t* regex, qse_size_t n, - unsigned int* nsubmat, int cflags) +int qse_tre_compx (qse_tre_t* tre, const qse_char_t* regex, qse_size_t n, unsigned int* nsubmat, int cflags) { int ret; @@ -90,12 +88,12 @@ int qse_tre_compx ( tre->TRE_REGEX_T_FIELD = QSE_NULL; } - ret = tre_compile (tre, regex, n, cflags); + ret = tre_compile(tre, regex, n, cflags); if (ret > 0) { tre->TRE_REGEX_T_FIELD = QSE_NULL; /* just to make sure */ tre->errnum = ret; - return -1; + return -1; } if (nsubmat) @@ -105,14 +103,9 @@ int qse_tre_compx ( return 0; } -int qse_tre_comp ( - qse_tre_t* tre, const qse_char_t* regex, - unsigned int* nsubmat, int cflags) +int qse_tre_comp (qse_tre_t* tre, const qse_char_t* regex, unsigned int* nsubmat, int cflags) { - return qse_tre_compx ( - tre, regex, (regex? qse_strlen(regex):0), - nsubmat, cflags - ); + return qse_tre_compx(tre, regex, (regex? qse_strlen(regex):0), nsubmat, cflags); } /* Fills the POSIX.2 regmatch_t array according to the TNFA tag and match diff --git a/qse/samples/awk/Makefile.am b/qse/samples/awk/Makefile.am index 69923c32..1685f50b 100644 --- a/qse/samples/awk/Makefile.am +++ b/qse/samples/awk/Makefile.am @@ -10,14 +10,6 @@ bin_PROGRAMS = awk01 awk02 awk03 awk04 awk05 awk06 awk07 awk08 awk09 awk10 awk11 AM_LDFLAGS = -L../../lib/awk -L../../lib/cmn LDADD = -lqseawk -lqsecmn $(LIBM) -if WIN32 -# you must adjust the value of DEFAULT_MODPOSTFIX according to -# -version-info in ../../lib/awk/Makefile.am -AM_CPPFLAGS += -DDEFAULT_MODPREFIX=\"libqseawk-\" -DDEFAULT_MODPOSTFIX=\"-1\" -else -AM_CPPFLAGS += -DDEFAULT_MODPREFIX=\"$(libdir)/libqseawk-\" -DDEFAULT_MODPOSTFIX=\"\" -endif - if WIN32 if WCHAR LDADD += $(UNICOWS_LIBS) diff --git a/qse/samples/awk/Makefile.in b/qse/samples/awk/Makefile.in index 0f3b084f..da3faace 100644 --- a/qse/samples/awk/Makefile.in +++ b/qse/samples/awk/Makefile.in @@ -92,13 +92,8 @@ bin_PROGRAMS = awk01$(EXEEXT) awk02$(EXEEXT) awk03$(EXEEXT) \ awk04$(EXEEXT) awk05$(EXEEXT) awk06$(EXEEXT) awk07$(EXEEXT) \ awk08$(EXEEXT) awk09$(EXEEXT) awk10$(EXEEXT) awk11$(EXEEXT) \ awk12$(EXEEXT) awk15$(EXEEXT) $(am__EXEEXT_1) - -# you must adjust the value of DEFAULT_MODPOSTFIX according to -# -version-info in ../../lib/awk/Makefile.am -@WIN32_TRUE@am__append_1 = -DDEFAULT_MODPREFIX=\"libqseawk-\" -DDEFAULT_MODPOSTFIX=\"-1\" -@WIN32_FALSE@am__append_2 = -DDEFAULT_MODPREFIX=\"$(libdir)/libqseawk-\" -DDEFAULT_MODPOSTFIX=\"\" -@WCHAR_TRUE@@WIN32_TRUE@am__append_3 = $(UNICOWS_LIBS) -@ENABLE_CXX_TRUE@am__append_4 = awk21 awk22 awk23 awk24 awk25 awk26 awk27 awk28 +@WCHAR_TRUE@@WIN32_TRUE@am__append_1 = $(UNICOWS_LIBS) +@ENABLE_CXX_TRUE@am__append_2 = awk21 awk22 awk23 awk24 awk25 awk26 awk27 awk28 subdir = samples/awk ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_sign.m4 \ @@ -471,7 +466,6 @@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ -runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ @@ -481,10 +475,13 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = nostdinc -AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include \ - -I$(includedir) $(am__append_1) $(am__append_2) +AM_CPPFLAGS = \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/include \ + -I$(includedir) + AM_LDFLAGS = -L../../lib/awk -L../../lib/cmn -LDADD = -lqseawk -lqsecmn $(LIBM) $(am__append_3) +LDADD = -lqseawk -lqsecmn $(LIBM) $(am__append_1) CMNFILES = awk00.c awk00.h awk01_SOURCES = awk01.c awk02_SOURCES = awk02.c $(CMNFILES)