added the typename() builtin awk function and qse_awk_rtx_getvaltypename()

This commit is contained in:
hyung-hwan 2019-04-26 16:55:57 +00:00
parent 1f980cbfb8
commit bc3173d74a
9 changed files with 84 additions and 53 deletions

View File

@ -1400,12 +1400,12 @@ enum qse_awk_val_type_t
{ {
/* the values between QSE_AWK_VAL_NIL and QSE_AWK_VAL_MAP inclusive /* the values between QSE_AWK_VAL_NIL and QSE_AWK_VAL_MAP inclusive
* must be synchronized with an internal table of the __cmp_val * 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_NIL = 0, /**< nil */
QSE_AWK_VAL_INT = 1, /**< integer */ QSE_AWK_VAL_INT = 1, /**< integer */
QSE_AWK_VAL_FLT = 2, /**< floating-pointer number */ QSE_AWK_VAL_FLT = 2, /**< floating-pointer number */
QSE_AWK_VAL_STR = 3, /**< string */ 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_MAP = 5, /**< map */
QSE_AWK_VAL_REX = 6, /**< regular expression */ QSE_AWK_VAL_REX = 6, /**< regular expression */
@ -2607,6 +2607,11 @@ QSE_EXPORT int qse_awk_rtx_getvaltype (
qse_awk_val_t* val 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_EXPORT int qse_awk_rtx_getintfromval (
qse_awk_rtx_t* rtx, qse_awk_rtx_t* rtx,
qse_awk_val_t* val qse_awk_val_t* val

View File

@ -26,10 +26,11 @@
#include "awk-prv.h" #include "awk-prv.h"
static int fnc_close (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_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_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_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) #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("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}, { {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("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 */ /* array sort */
{ {QSE_T("asort"), 5}, 0, { {1, 3, QSE_NULL}, fnc_asort, 0 }, QSE_NULL}, { {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 * such a function registered won't take effect because
* the word is treated as a keyword */ * 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); qse_awk_seterrnum (awk, QSE_AWK_EEXIST, &ncs);
return QSE_NULL; 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 (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); str0 = qse_awk_rtx_getvalstr(rtx, a0, &len0);
if (str0 == QSE_NULL) return -1; 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); qse_awk_rtx_freevalstr (rtx, a0, str0);
/* RSTART: 0 on no match */ /* 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); x0 = qse_awk_rtx_makeintval(rtx, idx);
if (!x0) goto oops; 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; 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) static int fnc_asort (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{ {
qse_size_t nargs; qse_size_t nargs;

View File

@ -740,7 +740,6 @@ int qse_awk_buildrex (
} }
#if !defined(USE_REX) #if !defined(USE_REX)
static int matchtre ( static int matchtre (
qse_awk_t* awk, qse_tre_t* tre, int opt, qse_awk_t* awk, qse_tre_t* tre, int opt,
const qse_cstr_t* str, qse_cstr_t* mat, const qse_cstr_t* str, qse_cstr_t* mat,
@ -751,7 +750,7 @@ static int matchtre (
qse_tre_match_t match[10]; qse_tre_match_t match[10];
QSE_MEMSET (match, 0, QSE_SIZEOF(match)); 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 (n <= -1)
{ {
if (QSE_TRE_ERRNUM(tre) == QSE_TRE_ENOMATCH) return 0; if (QSE_TRE_ERRNUM(tre) == QSE_TRE_ENOMATCH) return 0;
@ -763,7 +762,7 @@ static int matchtre (
#endif #endif
*errnum = (QSE_TRE_ERRNUM(tre) == QSE_TRE_ENOMEM)? *errnum = (QSE_TRE_ERRNUM(tre) == QSE_TRE_ENOMEM)?
QSE_AWK_ENOMEM: QSE_AWK_EREXMA; QSE_AWK_ENOMEM: QSE_AWK_EREXMA;
return -1; return -1;
} }
QSE_ASSERT (match[0].rm_so != -1); QSE_ASSERT (match[0].rm_so != -1);

View File

@ -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; 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; if (n > 0) right = mid - 1;
else if (n < 0) left = mid + 1; else if (n < 0) left = mid + 1;
else else

View File

@ -6549,7 +6549,7 @@ static qse_awk_val_t* eval_getline (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde)
read_console_again: read_console_again:
qse_str_clear (&rtx->inrec.lineg); 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) if (p->in)
{ {
@ -6570,10 +6570,11 @@ read_console_again:
QSE_ASSERT (p->in == QSE_NULL); QSE_ASSERT (p->in == QSE_NULL);
if (rtx->nrflt.limit > 0) 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 (((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; 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() /* this jump is a bit dirty. the 'if' block below qse_awk_rtx_readio()
* will never be true. but this makes code confusing */ * will never be true. but this makes code confusing */
goto read_console_again; goto read_console_again;
} }
@ -6583,14 +6584,14 @@ read_console_again:
if (p->var == QSE_NULL) if (p->var == QSE_NULL)
{ {
/* set $0 with the input value */ /* 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; if (x <= -1) return QSE_NULL;
} }
else else
{ {
qse_awk_val_t* v; 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) if (v == QSE_NULL)
{ {
ADJERR_LOC (rtx, &nde->loc); ADJERR_LOC (rtx, &nde->loc);
@ -6605,7 +6606,7 @@ read_console_again:
/* update FNR & NR if reading from console */ /* update FNR & NR if reading from console */
if (p->in_type == QSE_AWK_IN_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; return QSE_NULL;
} }

View File

@ -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_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_awk_val_zls = (qse_awk_val_t*)&awk_zls;
qse_awk_val_t* qse_getawknilval (void) qse_awk_val_t* qse_getawknilval (void)
{ {
return (qse_awk_val_t*)&awk_nil; 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) 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) 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) void qse_awk_rtx_freeval (qse_awk_rtx_t* rtx, qse_awk_val_t* val, int cache)

View File

@ -78,9 +78,7 @@ void* qse_tre_getxtn (qse_tre_t* tre)
return QSE_XTN (tre); return QSE_XTN (tre);
} }
int qse_tre_compx ( int qse_tre_compx (qse_tre_t* tre, const qse_char_t* regex, qse_size_t n, unsigned int* nsubmat, int cflags)
qse_tre_t* tre, const qse_char_t* regex, qse_size_t n,
unsigned int* nsubmat, int cflags)
{ {
int ret; int ret;
@ -90,12 +88,12 @@ int qse_tre_compx (
tre->TRE_REGEX_T_FIELD = QSE_NULL; tre->TRE_REGEX_T_FIELD = QSE_NULL;
} }
ret = tre_compile (tre, regex, n, cflags); ret = tre_compile(tre, regex, n, cflags);
if (ret > 0) if (ret > 0)
{ {
tre->TRE_REGEX_T_FIELD = QSE_NULL; /* just to make sure */ tre->TRE_REGEX_T_FIELD = QSE_NULL; /* just to make sure */
tre->errnum = ret; tre->errnum = ret;
return -1; return -1;
} }
if (nsubmat) if (nsubmat)
@ -105,14 +103,9 @@ int qse_tre_compx (
return 0; return 0;
} }
int qse_tre_comp ( int qse_tre_comp (qse_tre_t* tre, const qse_char_t* regex, unsigned int* nsubmat, int cflags)
qse_tre_t* tre, const qse_char_t* regex,
unsigned int* nsubmat, int cflags)
{ {
return qse_tre_compx ( return qse_tre_compx(tre, regex, (regex? qse_strlen(regex):0), nsubmat, cflags);
tre, regex, (regex? qse_strlen(regex):0),
nsubmat, cflags
);
} }
/* Fills the POSIX.2 regmatch_t array according to the TNFA tag and match /* Fills the POSIX.2 regmatch_t array according to the TNFA tag and match

View File

@ -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 AM_LDFLAGS = -L../../lib/awk -L../../lib/cmn
LDADD = -lqseawk -lqsecmn $(LIBM) 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 WIN32
if WCHAR if WCHAR
LDADD += $(UNICOWS_LIBS) LDADD += $(UNICOWS_LIBS)

View File

@ -92,13 +92,8 @@ bin_PROGRAMS = awk01$(EXEEXT) awk02$(EXEEXT) awk03$(EXEEXT) \
awk04$(EXEEXT) awk05$(EXEEXT) awk06$(EXEEXT) awk07$(EXEEXT) \ awk04$(EXEEXT) awk05$(EXEEXT) awk06$(EXEEXT) awk07$(EXEEXT) \
awk08$(EXEEXT) awk09$(EXEEXT) awk10$(EXEEXT) awk11$(EXEEXT) \ awk08$(EXEEXT) awk09$(EXEEXT) awk10$(EXEEXT) awk11$(EXEEXT) \
awk12$(EXEEXT) awk15$(EXEEXT) $(am__EXEEXT_1) awk12$(EXEEXT) awk15$(EXEEXT) $(am__EXEEXT_1)
@WCHAR_TRUE@@WIN32_TRUE@am__append_1 = $(UNICOWS_LIBS)
# you must adjust the value of DEFAULT_MODPOSTFIX according to @ENABLE_CXX_TRUE@am__append_2 = awk21 awk22 awk23 awk24 awk25 awk26 awk27 awk28
# -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
subdir = samples/awk subdir = samples/awk
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_sign.m4 \ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_sign.m4 \
@ -471,7 +466,6 @@ pdfdir = @pdfdir@
prefix = @prefix@ prefix = @prefix@
program_transform_name = @program_transform_name@ program_transform_name = @program_transform_name@
psdir = @psdir@ psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@ sbindir = @sbindir@
sharedstatedir = @sharedstatedir@ sharedstatedir = @sharedstatedir@
srcdir = @srcdir@ srcdir = @srcdir@
@ -481,10 +475,13 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@ top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = nostdinc AUTOMAKE_OPTIONS = nostdinc
AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include \ AM_CPPFLAGS = \
-I$(includedir) $(am__append_1) $(am__append_2) -I$(top_builddir)/include \
-I$(top_srcdir)/include \
-I$(includedir)
AM_LDFLAGS = -L../../lib/awk -L../../lib/cmn 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 CMNFILES = awk00.c awk00.h
awk01_SOURCES = awk01.c awk01_SOURCES = awk01.c
awk02_SOURCES = awk02.c $(CMNFILES) awk02_SOURCES = awk02.c $(CMNFILES)