diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index 4f955fd0..7c18b549 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -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. */ diff --git a/qse/lib/awk/Awk.cpp b/qse/lib/awk/Awk.cpp index 54661b3f..85714dd8 100644 --- a/qse/lib/awk/Awk.cpp +++ b/qse/lib/awk/Awk.cpp @@ -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); diff --git a/qse/lib/awk/misc.c b/qse/lib/awk/misc.c index 3caebf2f..88e88834 100644 --- a/qse/lib/awk/misc.c +++ b/qse/lib/awk/misc.c @@ -34,6 +34,8 @@ # include #endif +#include + 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 diff --git a/qse/lib/awk/parse.c b/qse/lib/awk/parse.c index f02a899d..eae990db 100644 --- a/qse/lib/awk/parse.c +++ b/qse/lib/awk/parse.c @@ -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)) diff --git a/qse/lib/cmn/mbwc-str.c b/qse/lib/cmn/mbwc-str.c index a148a476..b710d997 100644 --- a/qse/lib/cmn/mbwc-str.c +++ b/qse/lib/cmn/mbwc-str.c @@ -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); } diff --git a/qse/samples/awk/awk08.c b/qse/samples/awk/awk08.c index d3efedb8..b67b75fc 100644 --- a/qse/samples/awk/awk08.c +++ b/qse/samples/awk/awk08.c @@ -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));