added qse_awk_addgblwithmbs()/qse_awk_addgblwithwcs()

added qse_awk_delgblwithmbs()/qse_awk_delgblwithwcs()
added qse_awk_findgblwithmbs()/qse_awk_findgblwithwcs()
This commit is contained in:
hyung-hwan 2019-08-27 14:52:19 +00:00
parent 6cdaf0bda6
commit a6484a5605
6 changed files with 277 additions and 107 deletions

View File

@ -1780,33 +1780,71 @@ QSE_EXPORT void qse_awk_pushecb (
);
/**
* The qse_awk_addgbl() function adds an intrinsic global variable.
* The qse_awk_addgblwithmbs() function adds an intrinsic global variable.
* \return the ID of the global variable added on success, -1 on failure.
*/
QSE_EXPORT int qse_awk_addgbl (
qse_awk_t* awk, /**< awk */
const qse_char_t* name /**< variable name */
QSE_EXPORT int qse_awk_addgblwithmbs (
qse_awk_t* awk, /**< awk */
const qse_mchar_t* name /**< variable name */
);
/**
* The qse_awk_delgbl() function deletes an intrinsic global variable by name.
* The qse_awk_addgblwithwcs() function adds an intrinsic global variable.
* \return the ID of the global variable added on success, -1 on failure.
*/
QSE_EXPORT int qse_awk_addgblwithwcs (
qse_awk_t* awk, /**< awk */
const qse_wchar_t* name /**< variable name */
);
/**
* The qse_awk_delgblwithmbs() function deletes an intrinsic global variable by name.
* \return 0 on success, -1 on failure
*/
QSE_EXPORT int qse_awk_delgbl (
qse_awk_t* awk, /**< awk */
const qse_char_t* name /**< variable name */
QSE_EXPORT int qse_awk_delgblwithmbs (
qse_awk_t* awk, /**< awk */
const qse_mchar_t* name /**< variable name */
);
/**
* The qse_awk_findgbl() function returns the numeric ID of an intrinsic global
* The qse_awk_delgblwithwcs() function deletes an intrinsic global variable by name.
* \return 0 on success, -1 on failure
*/
QSE_EXPORT int qse_awk_delgblwithwcs (
qse_awk_t* awk, /**< awk */
const qse_wchar_t* name /**< variable name */
);
/**
* The qse_awk_findgblwithmbs() function returns the numeric ID of an intrinsic global
* variable.
* \return number >= 0 on success, -1 on failure
*/
QSE_EXPORT int qse_awk_findgbl (
qse_awk_t* awk, /**< awk */
const qse_char_t* name /**< variable name */
QSE_EXPORT int qse_awk_findgblwithmbs (
qse_awk_t* awk, /**< awk */
const qse_mchar_t* name /**< variable name */
);
/**
* The qse_awk_findgblwithwcs() function returns the numeric ID of an intrinsic global
* variable.
* \return number >= 0 on success, -1 on failure
*/
QSE_EXPORT int qse_awk_findgblwithwcs (
qse_awk_t* awk, /**< awk */
const qse_wchar_t* name /**< variable name */
);
#if defined(QSE_CHAR_IS_MCHAR)
# define qse_awk_addgbl qse_awk_addgblwithmbs
# define qse_awk_delgbl qse_awk_delgblwithmbs
# define qse_awk_findgbl qse_awk_findgblwithmbs
#else
# define qse_awk_addgbl qse_awk_addgblwithwcs
# define qse_awk_delgbl qse_awk_delgblwithwcs
# define qse_awk_findgbl qse_awk_findgblwithwcs
#endif
/**
* The qse_awk_addfnc() function adds an intrinsic function.
*/
@ -1962,6 +2000,19 @@ QSE_EXPORT qse_char_t* qse_awk_cstrdup (
const qse_cstr_t* str /**< string */
);
QSE_EXPORT qse_wchar_t* qse_awk_mbstowcsdup (
qse_awk_t* awk,
const qse_mchar_t* mbs,
qse_size_t* wcslen
);
QSE_EXPORT qse_mchar_t* qse_awk_wcstombsdup (
qse_awk_t* awk,
const qse_wchar_t* wcs,
qse_size_t* mbslen
);
/**
* The qse_awk_mbsxtoint() function converts a multi-byte string to an integer.
*/

View File

@ -1324,8 +1324,7 @@ int Awk::call (const char_t* name, Value* ret, const Value* args, size_t nargs)
if (nargs <= QSE_COUNTOF(buf)) ptr = buf;
else
{
ptr = (val_t**) qse_awk_allocmem (
awk, QSE_SIZEOF(val_t*) * nargs);
ptr = (val_t**)qse_awk_allocmem(awk, QSE_SIZEOF(val_t*) * nargs);
if (ptr == QSE_NULL)
{
this->runctx.setError (QSE_AWK_ENOMEM);

View File

@ -34,6 +34,8 @@
# include <qse/cmn/tre.h>
#endif
#include <qse/cmn/mbwc.h>
void* qse_awk_allocmem (qse_awk_t* awk, qse_size_t size)
{
void* ptr = QSE_AWK_ALLOC(awk, size);
@ -77,6 +79,50 @@ qse_char_t* qse_awk_cstrdup (qse_awk_t* awk, const qse_cstr_t* s)
return ptr;
}
qse_wchar_t* qse_awk_mbstowcsdup (qse_awk_t* awk, const qse_mchar_t* mbs, qse_size_t* _wcslen)
{
qse_size_t mbslen, wcslen;
qse_wchar_t* wcs;
/* if i use qse_mbstowcsdupwithcmgr(), i cannot pinpoint the exact failure cause.
* let's do it differently. */
if (qse_mbstowcswithcmgr(mbs, &mbslen, QSE_NULL, &wcslen, awk->_cmgr) <= -1)
{
qse_awk_seterrnum (awk, QSE_AWK_EINVAL, QSE_NULL);
return QSE_NULL;
}
wcs = qse_awk_allocmem(awk, QSE_SIZEOF(*wcs) * (wcslen + 1));
if (!wcs) return QSE_NULL;
wcslen = wcslen + 1;
qse_mbstowcswithcmgr (mbs, &mbslen, wcs, &wcslen, awk->_cmgr);
if (_wcslen) *_wcslen = wcslen;
return wcs;
}
qse_mchar_t* qse_awk_wcstombsdup (qse_awk_t* awk, const qse_wchar_t* wcs, qse_size_t* _mbslen)
{
qse_size_t mbslen, wcslen;
qse_mchar_t* mbs;
if (qse_wcstombswithcmgr(wcs, &wcslen, QSE_NULL, &mbslen, awk->_cmgr) <= -1)
{
qse_awk_seterrnum (awk, QSE_AWK_EINVAL, QSE_NULL);
return QSE_NULL;
}
mbs = qse_awk_allocmem(awk, QSE_SIZEOF(*mbs) * (mbslen + 1));
if (!mbs) return QSE_NULL;
mbslen = mbslen + 1;
qse_wcstombswithcmgr (wcs, &wcslen, mbs, &mbslen, awk->_cmgr);
if (_mbslen) *_mbslen = mbslen;
return mbs;
}
/* ========================================================================= */
#undef awk_strxtoint
#undef awk_strtoflt

View File

@ -1864,7 +1864,7 @@ static int add_global (qse_awk_t* awk, const qse_cstr_t* name, qse_awk_loc_t* xl
return -1;
}
#if 0
#if 0
/* TODO: need to check if it conflicts with a named variable to
* disallow such a program shown below (IMPLICIT & EXPLICIT on)
* BEGIN {X=20; x(); x(); x(); print X}
@ -1906,18 +1906,10 @@ static int add_global (qse_awk_t* awk, const qse_cstr_t* name, qse_awk_loc_t* xl
return (int)ngbls;
}
int qse_awk_addgbl (qse_awk_t* awk, const qse_char_t* name)
int qse_awk_addgblwithmbs (qse_awk_t* awk, const qse_mchar_t* name)
{
int n;
qse_cstr_t ncs;
ncs.ptr = (qse_char_t*)name;
ncs.len = qse_strlen(name);;
if (ncs.len <= 0)
{
SETERR_COD (awk, QSE_AWK_EINVAL);
return -1;
}
qse_mcstr_t ncs;
if (awk->tree.ngbls > awk->tree.ngbls_base)
{
@ -1926,7 +1918,25 @@ int qse_awk_addgbl (qse_awk_t* awk, const qse_char_t* name)
return -1;
}
ncs.ptr = (qse_mchar_t*)name;
ncs.len = qse_mbslen(name);;
if (ncs.len <= 0)
{
SETERR_COD (awk, QSE_AWK_EINVAL);
return -1;
}
#if defined(QSE_CHAR_IS_MCHAR)
n = add_global(awk, &ncs, QSE_NULL, 0);
#else
{
qse_wcstr_t wcs;
wcs.ptr = qse_awk_mbstowcsdup(awk, ncs.ptr, &wcs.len);
if (!wcs.ptr) return -1;
n = add_global(awk, &wcs, QSE_NULL, 0);
qse_awk_freemem (awk, wcs.ptr);
}
#endif
/* update the count of the static globals.
* the total global count has been updated inside add_global. */
@ -1958,16 +1968,9 @@ int qse_awk_addgblwithwcs (qse_awk_t* awk, const qse_wchar_t* name)
#if defined(QSE_CHAR_IS_MCHAR)
{
qse_mcstr_t mbs;
mbs.ptr = qse_wcstombsdupwithcmgr(name, &mbs.len, awk->_mmgr, awk->_cmgr);
if (!mbs.ptr)
{
SETERR_COD (awk, QSE_AWK_ENOMEM); /* TODO: it could be encoidng error too?? how to tell? */
return -1;
}
mbs.ptr = qse_awk_wcstombsdup(awk, ncs.ptr, &mbs.len);
if (!mbs.ptr) return -1;
n = add_global(awk, &mbs, QSE_NULL, 0);
qse_awk_freemem (awk, mbs.ptr);
}
#else
@ -1981,62 +1984,17 @@ int qse_awk_addgblwithwcs (qse_awk_t* awk, const qse_wchar_t* name)
return n;
}
int qse_awk_addgblwithmbs (qse_awk_t* awk, const qse_mchar_t* name)
{
int n;
qse_mcstr_t ncs;
if (awk->tree.ngbls > awk->tree.ngbls_base)
{
/* this function is not allowed after qse_awk_parse is called */
SETERR_COD (awk, QSE_AWK_EPERM);
return -1;
}
ncs.ptr = (qse_mchar_t*)name;
ncs.len = qse_mbslen(name);;
if (ncs.len <= 0)
{
SETERR_COD (awk, QSE_AWK_EINVAL);
return -1;
}
#if defined(QSE_CHAR_IS_MCHAR)
n = add_global(awk, &ncs, QSE_NULL, 0);
#else
{
qse_wcstr_t wcs;
wcs.ptr = qse_mbstowcsdupwithcmgr(name, &wcs.len, awk->_mmgr, awk->_cmgr);
if (!wcs.ptr)
{
SETERR_COD (awk, QSE_AWK_ENOMEM); /* TODO: it could be encoidng error too?? how to tell? */
return -1;
}
n = add_global(awk, &wcs, QSE_NULL, 0);
qse_awk_freemem (awk, wcs.ptr);
}
#endif
/* update the count of the static globals.
* the total global count has been updated inside add_global. */
if (n >= 0) awk->tree.ngbls_base++;
return n;
}
#define QSE_AWK_NUM_STATIC_GBLS \
(QSE_AWK_MAX_GBL_ID-QSE_AWK_MIN_GBL_ID+1)
int qse_awk_delgbl (qse_awk_t* awk, const qse_char_t* name)
int qse_awk_delgblwithmbs (qse_awk_t* awk, const qse_mchar_t* name)
{
qse_size_t n;
qse_cstr_t ncs;
qse_mcstr_t ncs;
qse_wcstr_t wcs;
ncs.ptr = (qse_char_t*)name;
ncs.len = qse_strlen (name);
ncs.ptr = (qse_mchar_t*)name;
ncs.len = qse_mbslen(name);
if (awk->tree.ngbls > awk->tree.ngbls_base)
{
@ -2045,12 +2003,25 @@ int qse_awk_delgbl (qse_awk_t* awk, const qse_char_t* name)
return -1;
}
#if defined(QSE_CHAR_IS_MCHAR)
n = qse_arr_search(awk->parse.gbls, QSE_AWK_NUM_STATIC_GBLS, ncs.ptr, ncs.len);
if (n == QSE_ARR_NIL)
{
qse_awk_seterrnum (awk, QSE_AWK_ENOENT, &ncs);
return -1;
}
#else
wcs.ptr = qse_awk_mbstowcsdup(awk, ncs.ptr, &wcs.len);
if (!wcs.ptr) return -1;
n = qse_arr_search(awk->parse.gbls, QSE_AWK_NUM_STATIC_GBLS, wcs.ptr, wcs.len);
if (n == QSE_ARR_NIL)
{
qse_awk_seterrnum (awk, QSE_AWK_ENOENT, &wcs);
qse_awk_freemem (awk, wcs.ptr);
return -1;
}
qse_awk_freemem (awk, wcs.ptr);
#endif
/* invalidate the name if deletion is requested.
* this approach does not delete the entry.
@ -2067,24 +2038,124 @@ int qse_awk_delgbl (qse_awk_t* awk, const qse_char_t* name)
return 0;
}
int qse_awk_findgbl (qse_awk_t* awk, const qse_char_t* name)
int qse_awk_delgblwithwcs (qse_awk_t* awk, const qse_wchar_t* name)
{
qse_size_t n;
qse_cstr_t ncs;
qse_wcstr_t ncs;
qse_mcstr_t mbs;
ncs.ptr = (qse_char_t*)name;
ncs.len = qse_strlen (name);
ncs.ptr = (qse_wchar_t*)name;
ncs.len = qse_wcslen(name);
if (awk->tree.ngbls > awk->tree.ngbls_base)
{
/* this function is not allow after qse_awk_parse is called */
qse_awk_seterrnum (awk, QSE_AWK_EPERM, QSE_NULL);
return -1;
}
#if defined(QSE_CHAR_IS_MCHAR)
mbs.ptr = qse_awk_wcstombsdup(awk, ncs.ptr, &mbs.len);
if (!mbs.ptr) return -1;
n = qse_arr_search(awk->parse.gbls, QSE_AWK_NUM_STATIC_GBLS, mbs.ptr, mbs.len);
if (n == QSE_ARR_NIL)
{
qse_awk_seterrnum (awk, QSE_AWK_ENOENT, &mbs);
qse_awk_freemem (awk, mbs.ptr);
return -1;
}
qse_awk_freemem (awk, mbs.ptr);
#else
n = qse_arr_search(awk->parse.gbls, QSE_AWK_NUM_STATIC_GBLS, ncs.ptr, ncs.len);
if (n == QSE_ARR_NIL)
{
qse_awk_seterrnum (awk, QSE_AWK_ENOENT, &ncs);
return -1;
}
#endif
/* invalidate the name if deletion is requested.
* this approach does not delete the entry.
* if qse_delgbl() is called with the same name
* again, the entry will be appended again.
* never call this funciton unless it is really required. */
/*
awk->parse.gbls.buf[n].name.ptr[0] = QSE_T('\0');
awk->parse.gbls.buf[n].name.len = 0;
*/
n = qse_arr_uplete (awk->parse.gbls, n, 1);
QSE_ASSERT (n == 1);
return 0;
}
int qse_awk_findgblwithmbs (qse_awk_t* awk, const qse_mchar_t* name)
{
qse_size_t n;
qse_mcstr_t ncs;
qse_wcstr_t wcs;
ncs.ptr = (qse_mchar_t*)name;
ncs.len = qse_mbslen(name);
#if defined(QSE_CHAR_IS_MCHAR)
n = qse_arr_search(awk->parse.gbls, QSE_AWK_NUM_STATIC_GBLS, ncs.ptr, ncs.len);
if (n == QSE_ARR_NIL)
{
qse_awk_seterrnum (awk, QSE_AWK_ENOENT, &ncs);
return -1;
}
#else
wcs.ptr = qse_awk_mbstowcsdup(awk, ncs.ptr, &wcs.len);
if (!wcs.ptr) return -1;
n = qse_arr_search(awk->parse.gbls, QSE_AWK_NUM_STATIC_GBLS, wcs.ptr, wcs.len);
if (n == QSE_ARR_NIL)
{
qse_awk_seterrnum (awk, QSE_AWK_ENOENT, &wcs);
qse_awk_freemem (awk, wcs.ptr);
return -1;
}
qse_awk_freemem (awk, wcs.ptr);
#endif
return (int)n;
}
int qse_awk_findgblwithwcs (qse_awk_t* awk, const qse_wchar_t* name)
{
qse_size_t n;
qse_wcstr_t ncs;
qse_mcstr_t mbs;
ncs.ptr = (qse_wchar_t*)name;
ncs.len = qse_wcslen(name);
#if defined(QSE_CHAR_IS_MCHAR)
mbs.ptr = qse_awk_wcstombsdup(awk, ncs.ptr, &mbs.len);
if (!mbs.ptr) return -1;
n = qse_arr_search(awk->parse.gbls, QSE_AWK_NUM_STATIC_GBLS, mbs.ptr, mbs.len);
if (n == QSE_ARR_NIL)
{
qse_awk_seterrnum (awk, QSE_AWK_ENOENT, &mbs);
qse_awk_freemem (awk, mbs.ptr);
return -1;
}
qse_awk_freemem (awk, mbs.ptr);
#else
n = qse_arr_search(awk->parse.gbls, QSE_AWK_NUM_STATIC_GBLS, ncs.ptr, ncs.len);
if (n == QSE_ARR_NIL)
{
qse_awk_seterrnum (awk, QSE_AWK_ENOENT, &ncs);
return -1;
}
#endif
return (int)n;
}
static qse_awk_t* collect_globals (qse_awk_t* awk)
{
if (MATCH(awk,TOK_NEWLINE))

View File

@ -262,8 +262,8 @@ static qse_wchar_t* mbsn_to_wcs_dup_with_cmgr (
if (mbsn_to_wcsn_with_cmgr(mbs, &ml, QSE_NULL, &wl, cmgr, all) <= -1) return QSE_NULL;
wl++; /* for terminating null */
wcs = QSE_MMGR_ALLOC (mmgr, wl * QSE_SIZEOF(*wcs));
if (wcs == QSE_NULL) return QSE_NULL;
wcs = (qse_wchar_t*)QSE_MMGR_ALLOC(mmgr, wl * QSE_SIZEOF(*wcs));
if (!wcs) return QSE_NULL;
mbsn_to_wcsn_with_cmgr (mbs, mbslen, wcs, &wl, cmgr, all);
wcs[wl] = QSE_WT('\0');
@ -287,12 +287,11 @@ static qse_wchar_t* mbs_to_wcs_dup_with_cmgr (const qse_mchar_t* mbs, qse_size_t
qse_size_t ml, wl;
qse_wchar_t* wcs;
if (mbs_to_wcs_with_cmgr (
mbs, &ml, QSE_NULL, &wl, cmgr, all) <= -1) return QSE_NULL;
if (mbs_to_wcs_with_cmgr(mbs, &ml, QSE_NULL, &wl, cmgr, all) <= -1) return QSE_NULL;
wl++; /* for terminating null */
wcs = QSE_MMGR_ALLOC (mmgr, wl * QSE_SIZEOF(*wcs));
if (wcs == QSE_NULL) return QSE_NULL;
wcs = (qse_wchar_t*)QSE_MMGR_ALLOC(mmgr, wl * QSE_SIZEOF(*wcs));
if (!wcs) return QSE_NULL;
mbs_to_wcs_with_cmgr (mbs, &ml, wcs, &wl, cmgr, all);
@ -300,20 +299,17 @@ static qse_wchar_t* mbs_to_wcs_dup_with_cmgr (const qse_mchar_t* mbs, qse_size_t
return wcs;
}
qse_wchar_t* qse_mbstowcsdupwithcmgr (
const qse_mchar_t* mbs, qse_size_t* wcslen, qse_mmgr_t* mmgr, qse_cmgr_t* cmgr)
qse_wchar_t* qse_mbstowcsdupwithcmgr (const qse_mchar_t* mbs, qse_size_t* wcslen, qse_mmgr_t* mmgr, qse_cmgr_t* cmgr)
{
return mbs_to_wcs_dup_with_cmgr (mbs, wcslen, mmgr, cmgr, 0);
}
qse_wchar_t* qse_mbstowcsalldupwithcmgr (
const qse_mchar_t* mbs, qse_size_t* wcslen, qse_mmgr_t* mmgr, qse_cmgr_t* cmgr)
qse_wchar_t* qse_mbstowcsalldupwithcmgr (const qse_mchar_t* mbs, qse_size_t* wcslen, qse_mmgr_t* mmgr, qse_cmgr_t* cmgr)
{
return mbs_to_wcs_dup_with_cmgr (mbs, wcslen, mmgr, cmgr, 1);
}
static qse_wchar_t* mbsa_to_wcs_dup_with_cmgr (
const qse_mchar_t* mbs[], qse_size_t* wcslen, qse_mmgr_t* mmgr, qse_cmgr_t* cmgr, int all)
static qse_wchar_t* mbsa_to_wcs_dup_with_cmgr (const qse_mchar_t* mbs[], qse_size_t* wcslen, qse_mmgr_t* mmgr, qse_cmgr_t* cmgr, int all)
{
qse_wchar_t* buf;
qse_size_t i;
@ -346,14 +342,12 @@ static qse_wchar_t* mbsa_to_wcs_dup_with_cmgr (
return buf;
}
qse_wchar_t* qse_mbsatowcsdupwithcmgr (
const qse_mchar_t* mbs[], qse_size_t* wcslen, qse_mmgr_t* mmgr, qse_cmgr_t* cmgr)
qse_wchar_t* qse_mbsatowcsdupwithcmgr (const qse_mchar_t* mbs[], qse_size_t* wcslen, qse_mmgr_t* mmgr, qse_cmgr_t* cmgr)
{
return mbsa_to_wcs_dup_with_cmgr (mbs, wcslen, mmgr, cmgr, 0);
}
qse_wchar_t* qse_mbsatowcsalldupwithcmgr (
const qse_mchar_t* mbs[], qse_size_t* wcslen, qse_mmgr_t* mmgr, qse_cmgr_t* cmgr)
qse_wchar_t* qse_mbsatowcsalldupwithcmgr (const qse_mchar_t* mbs[], qse_size_t* wcslen, qse_mmgr_t* mmgr, qse_cmgr_t* cmgr)
{
return mbsa_to_wcs_dup_with_cmgr (mbs, wcslen, mmgr, cmgr, 1);
}

View File

@ -4,12 +4,12 @@
#include "awk00.h"
static const qse_char_t* src = QSE_T(
"BEGIN { G0 = 10; G1 = \"hello, world\"; G2 = sin(90); match (\"abcdefg\", /[c-f]+/); }"
"BEGIN { G0 = 10; G1 = \"hello, world\"; G2 = sin(90); G3=33; G4=44; G5=55; G6=66; G7=77; G8=88; G9=99; match (\"abcdefg\", /[c-f]+/); }"
);
struct ginfo_t
{
int g[3];
int g[10];
};
typedef struct ginfo_t ginfo_t;
@ -40,8 +40,17 @@ static int awk_main (int argc, qse_char_t* argv[])
for (i = 0; i < QSE_COUNTOF(ginfo->g); i++)
{
qse_char_t name[] = QSE_T("GX");
qse_wchar_t wname[] = QSE_WT("GX");
qse_mchar_t mname[] = QSE_MT("GX");
name[1] = QSE_T('0') + i;
ginfo->g[i] = qse_awk_addgbl (awk, name);
wname[1] = QSE_WT('0') + i;
mname[1] = QSE_MT('0') + i;
if (i < 3)
ginfo->g[i] = qse_awk_addgblwithmbs(awk, mname);
else if (i < 6)
ginfo->g[i] = qse_awk_addgblwithwcs(awk, wname);
else
ginfo->g[i] = qse_awk_addgbl(awk, name);
if (ginfo->g[i] <= -1)
{
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk));