2007-05-02 01:07:00 +00:00
|
|
|
/*
|
2012-08-16 03:47:55 +00:00
|
|
|
* $Id$
|
2007-05-02 01:07:00 +00:00
|
|
|
*
|
2012-07-20 04:13:39 +00:00
|
|
|
Copyright 2006-2012 Chung, Hyung-Hwan.
|
2009-09-16 04:01:02 +00:00
|
|
|
This file is part of QSE.
|
2008-12-27 04:35:14 +00:00
|
|
|
|
2009-09-16 04:01:02 +00:00
|
|
|
QSE is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU Lesser General Public License as
|
|
|
|
published by the Free Software Foundation, either version 3 of
|
|
|
|
the License, or (at your option) any later version.
|
2008-12-27 04:35:14 +00:00
|
|
|
|
2009-09-16 04:01:02 +00:00
|
|
|
QSE is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU Lesser General Public License for more details.
|
2008-12-27 04:35:14 +00:00
|
|
|
|
2009-09-16 04:01:02 +00:00
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
|
|
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
|
2007-05-02 01:07:00 +00:00
|
|
|
*/
|
|
|
|
|
2008-08-21 03:17:25 +00:00
|
|
|
#include "awk.h"
|
2012-10-29 14:41:39 +00:00
|
|
|
#include <qse/cmn/mbwc.h>
|
2007-05-02 01:07:00 +00:00
|
|
|
|
|
|
|
#ifdef DEBUG_VAL
|
2009-06-04 15:50:32 +00:00
|
|
|
#include <qse/cmn/stdio.h>
|
2007-05-02 01:07:00 +00:00
|
|
|
#endif
|
|
|
|
|
2009-02-27 04:56:12 +00:00
|
|
|
#define CHUNKSIZE QSE_AWK_VAL_CHUNK_SIZE
|
2008-03-23 00:47:27 +00:00
|
|
|
|
2012-11-05 05:20:12 +00:00
|
|
|
static qse_awk_val_nil_t awk_nil = { QSE_AWK_VAL_NIL, 0, 1, 0 };
|
|
|
|
static qse_awk_val_str_t awk_zls = { QSE_AWK_VAL_STR, 0, 1, 0, { QSE_T(""), 0 } };
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
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;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
static qse_awk_val_int_t awk_int[] =
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2012-11-05 05:20:12 +00:00
|
|
|
{ QSE_AWK_VAL_INT, 0, 1, 0, -1, QSE_NULL },
|
|
|
|
{ QSE_AWK_VAL_INT, 0, 1, 0, 0, QSE_NULL },
|
|
|
|
{ QSE_AWK_VAL_INT, 0, 1, 0, 1, QSE_NULL },
|
|
|
|
{ QSE_AWK_VAL_INT, 0, 1, 0, 2, QSE_NULL },
|
|
|
|
{ QSE_AWK_VAL_INT, 0, 1, 0, 3, QSE_NULL },
|
|
|
|
{ QSE_AWK_VAL_INT, 0, 1, 0, 4, QSE_NULL },
|
|
|
|
{ QSE_AWK_VAL_INT, 0, 1, 0, 5, QSE_NULL },
|
|
|
|
{ QSE_AWK_VAL_INT, 0, 1, 0, 6, QSE_NULL },
|
|
|
|
{ QSE_AWK_VAL_INT, 0, 1, 0, 7, QSE_NULL },
|
|
|
|
{ QSE_AWK_VAL_INT, 0, 1, 0, 8, QSE_NULL },
|
|
|
|
{ QSE_AWK_VAL_INT, 0, 1, 0, 9, QSE_NULL },
|
|
|
|
{ QSE_AWK_VAL_INT, 0, 1, 0, 10, QSE_NULL },
|
|
|
|
{ QSE_AWK_VAL_INT, 0, 1, 0, 11, QSE_NULL },
|
|
|
|
{ QSE_AWK_VAL_INT, 0, 1, 0, 12, QSE_NULL },
|
|
|
|
{ QSE_AWK_VAL_INT, 0, 1, 0, 13, QSE_NULL },
|
|
|
|
{ QSE_AWK_VAL_INT, 0, 1, 0, 14, QSE_NULL },
|
|
|
|
{ QSE_AWK_VAL_INT, 0, 1, 0, 15, QSE_NULL },
|
|
|
|
{ QSE_AWK_VAL_INT, 0, 1, 0, 16, QSE_NULL },
|
|
|
|
{ QSE_AWK_VAL_INT, 0, 1, 0, 17, QSE_NULL },
|
|
|
|
{ QSE_AWK_VAL_INT, 0, 1, 0, 18, QSE_NULL },
|
|
|
|
{ QSE_AWK_VAL_INT, 0, 1, 0, 19, QSE_NULL },
|
|
|
|
{ QSE_AWK_VAL_INT, 0, 1, 0, 20, QSE_NULL }
|
2007-05-02 01:07:00 +00:00
|
|
|
};
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_awk_val_t* qse_awk_val_negone = (qse_awk_val_t*)&awk_int[0];
|
|
|
|
qse_awk_val_t* qse_awk_val_zero = (qse_awk_val_t*)&awk_int[1];
|
|
|
|
qse_awk_val_t* qse_awk_val_one = (qse_awk_val_t*)&awk_int[2];
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2012-12-01 13:13:13 +00:00
|
|
|
qse_awk_val_t* qse_getawknilval (void)
|
|
|
|
{
|
|
|
|
return (qse_awk_val_t*)&awk_nil;
|
|
|
|
}
|
|
|
|
|
2012-11-29 14:03:59 +00:00
|
|
|
int qse_awk_rtx_isnilval (qse_awk_rtx_t* rtx, qse_awk_val_t* val)
|
|
|
|
{
|
|
|
|
return val->type == QSE_AWK_VAL_NIL;
|
|
|
|
}
|
|
|
|
|
2012-10-23 17:08:56 +00:00
|
|
|
qse_awk_val_t* qse_awk_rtx_makenilval (qse_awk_rtx_t* rtx)
|
|
|
|
{
|
2012-10-29 14:41:39 +00:00
|
|
|
return (qse_awk_val_t*)&awk_nil;
|
2012-10-23 17:08:56 +00:00
|
|
|
}
|
|
|
|
|
2009-08-21 05:28:03 +00:00
|
|
|
qse_awk_val_t* qse_awk_rtx_makeintval (qse_awk_rtx_t* rtx, qse_long_t v)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_awk_val_int_t* val;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
|
|
|
if (v >= awk_int[0].val &&
|
2008-12-21 21:35:07 +00:00
|
|
|
v <= awk_int[QSE_COUNTOF(awk_int)-1].val)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
return (qse_awk_val_t*)&awk_int[v-awk_int[0].val];
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
2009-08-21 05:28:03 +00:00
|
|
|
if (rtx->vmgr.ifree == QSE_NULL)
|
2008-01-16 08:03:41 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_awk_val_ichunk_t* c;
|
2009-01-18 01:48:21 +00:00
|
|
|
/*qse_awk_val_int_t* x;*/
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_size_t i;
|
2008-01-16 08:03:41 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
/* use qse_awk_val_ichunk structure to avoid
|
2008-03-23 00:47:27 +00:00
|
|
|
* any alignment issues on platforms requiring
|
|
|
|
* aligned memory access - using the code commented out
|
|
|
|
* will cause a fault on such a platform */
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
/* c = QSE_AWK_ALLOC (run->awk,
|
|
|
|
QSE_SIZEOF(qse_awk_val_chunk_t)+
|
|
|
|
QSE_SIZEOF(qse_awk_val_int_t)*CHUNKSIZE); */
|
2009-08-21 05:28:03 +00:00
|
|
|
c = QSE_AWK_ALLOC (rtx->awk, QSE_SIZEOF(qse_awk_val_ichunk_t));
|
2008-12-21 21:35:07 +00:00
|
|
|
if (c == QSE_NULL)
|
2008-01-16 08:03:41 +00:00
|
|
|
{
|
2009-08-21 05:28:03 +00:00
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
2008-12-21 21:35:07 +00:00
|
|
|
return QSE_NULL;
|
2008-01-16 08:03:41 +00:00
|
|
|
}
|
|
|
|
|
2009-08-21 05:28:03 +00:00
|
|
|
c->next = rtx->vmgr.ichunk;
|
2008-03-23 00:47:27 +00:00
|
|
|
/*run->vmgr.ichunk = c;*/
|
2009-08-21 05:28:03 +00:00
|
|
|
rtx->vmgr.ichunk = (qse_awk_val_chunk_t*)c;
|
2008-01-16 21:46:08 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
/*x = (qse_awk_val_int_t*)(c + 1);
|
2008-01-16 21:46:08 +00:00
|
|
|
for (i = 0; i < CHUNKSIZE-1; i++)
|
2008-12-21 21:35:07 +00:00
|
|
|
x[i].nde = (qse_awk_nde_int_t*)&x[i+1];
|
|
|
|
x[i].nde = QSE_NULL;
|
2008-01-16 08:03:41 +00:00
|
|
|
|
2008-01-16 21:46:08 +00:00
|
|
|
run->vmgr.ifree = x;
|
2008-03-23 00:47:27 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
for (i = 0; i < CHUNKSIZE-1; i++)
|
2008-12-21 21:35:07 +00:00
|
|
|
c->slot[i].nde = (qse_awk_nde_int_t*)&c->slot[i+1];
|
|
|
|
c->slot[i].nde = QSE_NULL;
|
2008-03-23 00:47:27 +00:00
|
|
|
|
2009-08-21 05:28:03 +00:00
|
|
|
rtx->vmgr.ifree = &c->slot[0];
|
2008-01-16 08:03:41 +00:00
|
|
|
}
|
2008-03-23 00:47:27 +00:00
|
|
|
|
2009-08-21 05:28:03 +00:00
|
|
|
val = rtx->vmgr.ifree;
|
|
|
|
rtx->vmgr.ifree = (qse_awk_val_int_t*)val->nde;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
val->type = QSE_AWK_VAL_INT;
|
2007-05-02 01:07:00 +00:00
|
|
|
val->ref = 0;
|
2012-11-05 05:20:12 +00:00
|
|
|
val->stat = 0;
|
2009-06-15 07:22:00 +00:00
|
|
|
val->nstr = 0;
|
2007-05-02 01:07:00 +00:00
|
|
|
val->val = v;
|
2008-12-21 21:35:07 +00:00
|
|
|
val->nde = QSE_NULL;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
|
|
|
#ifdef DEBUG_VAL
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_dprintf (QSE_T("makeintval => %ld [%p]\n"), (long)v, val);
|
2007-05-02 01:07:00 +00:00
|
|
|
#endif
|
2008-12-21 21:35:07 +00:00
|
|
|
return (qse_awk_val_t*)val;
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
2011-11-22 05:03:31 +00:00
|
|
|
qse_awk_val_t* qse_awk_rtx_makefltval (qse_awk_rtx_t* rtx, qse_flt_t v)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2011-11-22 05:03:31 +00:00
|
|
|
qse_awk_val_flt_t* val;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2009-08-21 05:28:03 +00:00
|
|
|
if (rtx->vmgr.rfree == QSE_NULL)
|
2008-01-16 21:46:08 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_awk_val_rchunk_t* c;
|
2011-11-22 05:03:31 +00:00
|
|
|
/*qse_awk_val_flt_t* x;*/
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_size_t i;
|
|
|
|
|
|
|
|
/* c = QSE_AWK_ALLOC (run->awk,
|
|
|
|
QSE_SIZEOF(qse_awk_val_chunk_t)+
|
2011-11-22 05:03:31 +00:00
|
|
|
QSE_SIZEOF(qse_awk_val_flt_t)*CHUNKSIZE); */
|
2009-08-21 05:28:03 +00:00
|
|
|
c = QSE_AWK_ALLOC (rtx->awk, QSE_SIZEOF(qse_awk_val_rchunk_t));
|
2008-12-21 21:35:07 +00:00
|
|
|
if (c == QSE_NULL)
|
2008-01-16 21:46:08 +00:00
|
|
|
{
|
2009-08-21 05:28:03 +00:00
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
2008-12-21 21:35:07 +00:00
|
|
|
return QSE_NULL;
|
2008-01-16 21:46:08 +00:00
|
|
|
}
|
|
|
|
|
2009-08-21 05:28:03 +00:00
|
|
|
c->next = rtx->vmgr.rchunk;
|
2008-03-23 00:47:27 +00:00
|
|
|
/*run->vmgr.rchunk = c;*/
|
2009-08-21 05:28:03 +00:00
|
|
|
rtx->vmgr.rchunk = (qse_awk_val_chunk_t*)c;
|
2008-01-16 21:46:08 +00:00
|
|
|
|
2008-03-23 00:47:27 +00:00
|
|
|
/*
|
2011-11-22 05:03:31 +00:00
|
|
|
x = (qse_awk_val_flt_t*)(c + 1);
|
2008-01-16 21:46:08 +00:00
|
|
|
for (i = 0; i < CHUNKSIZE-1; i++)
|
2011-11-22 05:03:31 +00:00
|
|
|
x[i].nde = (qse_awk_nde_flt_t*)&x[i+1];
|
2008-12-21 21:35:07 +00:00
|
|
|
x[i].nde = QSE_NULL;
|
2008-01-16 21:46:08 +00:00
|
|
|
|
|
|
|
run->vmgr.rfree = x;
|
2008-03-23 00:47:27 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
for (i = 0; i < CHUNKSIZE-1; i++)
|
2011-11-22 05:03:31 +00:00
|
|
|
c->slot[i].nde = (qse_awk_nde_flt_t*)&c->slot[i+1];
|
2008-12-21 21:35:07 +00:00
|
|
|
c->slot[i].nde = QSE_NULL;
|
2008-03-23 00:47:27 +00:00
|
|
|
|
2009-08-21 05:28:03 +00:00
|
|
|
rtx->vmgr.rfree = &c->slot[0];
|
2008-01-16 21:46:08 +00:00
|
|
|
}
|
2008-03-23 00:47:27 +00:00
|
|
|
|
2009-08-21 05:28:03 +00:00
|
|
|
val = rtx->vmgr.rfree;
|
2011-11-22 05:03:31 +00:00
|
|
|
rtx->vmgr.rfree = (qse_awk_val_flt_t*)val->nde;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2011-11-22 05:03:31 +00:00
|
|
|
val->type = QSE_AWK_VAL_FLT;
|
2007-05-02 01:07:00 +00:00
|
|
|
val->ref = 0;
|
2012-11-05 05:20:12 +00:00
|
|
|
val->stat = 0;
|
2009-06-15 07:22:00 +00:00
|
|
|
val->nstr = 0;
|
2007-05-02 01:07:00 +00:00
|
|
|
val->val = v;
|
2008-12-21 21:35:07 +00:00
|
|
|
val->nde = QSE_NULL;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
|
|
|
#ifdef DEBUG_VAL
|
2011-11-22 05:03:31 +00:00
|
|
|
qse_dprintf (QSE_T("makefltval => %Lf [%p]\n"), (double)v, val);
|
2007-05-02 01:07:00 +00:00
|
|
|
#endif
|
2008-12-21 21:35:07 +00:00
|
|
|
return (qse_awk_val_t*)val;
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
2012-10-29 14:41:39 +00:00
|
|
|
qse_awk_val_t* qse_awk_rtx_makestrvalwithmbs (
|
|
|
|
qse_awk_rtx_t* rtx, const qse_mchar_t* mbs)
|
|
|
|
{
|
|
|
|
#if defined(QSE_CHAR_IS_MCHAR)
|
|
|
|
return qse_awk_rtx_makestrval (rtx, mbs, qse_mbslen(mbs));
|
|
|
|
#else
|
|
|
|
qse_awk_val_t* v;
|
|
|
|
qse_wxstr_t tmp;
|
|
|
|
|
|
|
|
tmp.ptr = qse_mbstowcsdup (mbs, &tmp.len, rtx->awk->mmgr);
|
|
|
|
if (tmp.ptr == QSE_NULL)
|
|
|
|
{
|
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
|
|
|
return QSE_NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
v = qse_awk_rtx_makestrvalwithcstr (rtx, &tmp);
|
|
|
|
QSE_AWK_FREE (rtx->awk, tmp.ptr);
|
|
|
|
return v;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
qse_awk_val_t* qse_awk_rtx_makestrvalwithwcs (
|
|
|
|
qse_awk_rtx_t* rtx, const qse_wchar_t* wcs)
|
|
|
|
{
|
|
|
|
#if defined(QSE_CHAR_IS_MCHAR)
|
|
|
|
qse_awk_val_t* v;
|
|
|
|
qse_mxstr_t tmp;
|
|
|
|
|
|
|
|
tmp.ptr = qse_wcstombsdup (wcs, &tmp.len, rtx->awk->mmgr);
|
|
|
|
if (tmp.ptr == QSE_NULL)
|
|
|
|
{
|
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
|
|
|
return QSE_NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
v = qse_awk_rtx_makestrvalwithcstr (rtx, &tmp);
|
|
|
|
QSE_AWK_FREE (rtx->awk, tmp.ptr);
|
|
|
|
return v;
|
|
|
|
#else
|
|
|
|
return qse_awk_rtx_makestrval (rtx, wcs, qse_wcslen(wcs));
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
qse_awk_val_t* qse_awk_rtx_makestrvalwithstr (
|
2009-08-21 05:28:03 +00:00
|
|
|
qse_awk_rtx_t* rtx, const qse_char_t* str)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2009-08-21 05:28:03 +00:00
|
|
|
return qse_awk_rtx_makestrval (rtx, str, qse_strlen(str));
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
2012-10-29 14:41:39 +00:00
|
|
|
qse_awk_val_t* qse_awk_rtx_makestrvalwithmcstr (
|
|
|
|
qse_awk_rtx_t* rtx, const qse_mcstr_t* mcstr)
|
|
|
|
{
|
|
|
|
#if defined(QSE_CHAR_IS_MCHAR)
|
|
|
|
return qse_awk_rtx_makestrvalwithcstr (rtx, mcstr);
|
|
|
|
#else
|
|
|
|
qse_awk_val_t* v;
|
2012-10-31 08:31:58 +00:00
|
|
|
qse_wxstr_t tmp;
|
2012-10-29 14:41:39 +00:00
|
|
|
qse_size_t mbslen;
|
|
|
|
|
|
|
|
mbslen = mcstr->len;
|
|
|
|
tmp.ptr = qse_mbsntowcsdup (mcstr->ptr, &mbslen, &tmp.len, rtx->awk->mmgr);
|
|
|
|
if (tmp.ptr == QSE_NULL)
|
|
|
|
{
|
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
|
|
|
return QSE_NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
v = qse_awk_rtx_makestrvalwithcstr (rtx, &tmp);
|
|
|
|
QSE_AWK_FREE (rtx->awk, tmp.ptr);
|
|
|
|
return v;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
qse_awk_val_t* qse_awk_rtx_makestrvalwithwcstr (
|
|
|
|
qse_awk_rtx_t* rtx, const qse_wcstr_t* wcstr)
|
|
|
|
{
|
|
|
|
#if defined(QSE_CHAR_IS_MCHAR)
|
|
|
|
qse_awk_val_t* v;
|
2012-10-31 08:31:58 +00:00
|
|
|
qse_mxstr_t tmp;
|
2012-10-29 14:41:39 +00:00
|
|
|
qse_size_t wcslen;
|
|
|
|
|
|
|
|
wcslen = wcstr->len;
|
|
|
|
tmp.ptr = qse_wcsntombsdup (wcstr->ptr, &wcslen, &tmp.len, rtx->awk->mmgr);
|
|
|
|
if (tmp.ptr == QSE_NULL)
|
|
|
|
{
|
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
|
|
|
return QSE_NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
v = qse_awk_rtx_makestrvalwithcstr (rtx, &tmp);
|
|
|
|
QSE_AWK_FREE (rtx->awk, tmp.ptr);
|
|
|
|
return v;
|
|
|
|
#else
|
|
|
|
return qse_awk_rtx_makestrvalwithcstr (rtx, wcstr);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
qse_awk_val_t* qse_awk_rtx_makestrvalwithcstr (
|
|
|
|
qse_awk_rtx_t* rtx, const qse_cstr_t* str)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2009-09-19 22:28:49 +00:00
|
|
|
qse_awk_val_str_t* val = QSE_NULL;
|
2012-10-29 14:41:39 +00:00
|
|
|
qse_size_t rlen = str->len;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2009-09-19 22:28:49 +00:00
|
|
|
#ifdef ENABLE_FEATURE_SCACHE
|
|
|
|
qse_size_t i;
|
|
|
|
|
|
|
|
i = rlen / FEATURE_SCACHE_BLOCK_UNIT;
|
|
|
|
if (i < QSE_COUNTOF(rtx->scache_count))
|
2008-01-16 03:01:47 +00:00
|
|
|
{
|
2009-09-19 22:28:49 +00:00
|
|
|
rlen = (i + 1) * FEATURE_SCACHE_BLOCK_UNIT - 1;
|
|
|
|
if (rtx->scache_count[i] > 0)
|
2008-01-16 03:01:47 +00:00
|
|
|
{
|
2009-09-19 22:28:49 +00:00
|
|
|
val = rtx->scache[i][--rtx->scache_count[i]];
|
2008-01-16 03:01:47 +00:00
|
|
|
goto init;
|
|
|
|
}
|
|
|
|
}
|
2009-09-19 22:28:49 +00:00
|
|
|
#endif
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
val = (qse_awk_val_str_t*) QSE_AWK_ALLOC (
|
2009-08-21 05:28:03 +00:00
|
|
|
rtx->awk,
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_SIZEOF(qse_awk_val_str_t) +
|
2012-10-29 14:41:39 +00:00
|
|
|
(rlen + 1) * QSE_SIZEOF(qse_char_t));
|
2008-12-21 21:35:07 +00:00
|
|
|
if (val == QSE_NULL)
|
2007-11-03 23:35:00 +00:00
|
|
|
{
|
2009-08-21 05:28:03 +00:00
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
2008-12-21 21:35:07 +00:00
|
|
|
return QSE_NULL;
|
2007-11-03 23:35:00 +00:00
|
|
|
}
|
2009-09-19 22:28:49 +00:00
|
|
|
|
|
|
|
#ifdef ENABLE_FEATURE_SCACHE
|
2008-01-16 03:01:47 +00:00
|
|
|
init:
|
2009-09-19 22:28:49 +00:00
|
|
|
#endif
|
2008-12-21 21:35:07 +00:00
|
|
|
val->type = QSE_AWK_VAL_STR;
|
2007-11-03 23:35:00 +00:00
|
|
|
val->ref = 0;
|
2012-11-05 05:20:12 +00:00
|
|
|
val->stat = 0;
|
2009-06-15 07:22:00 +00:00
|
|
|
val->nstr = 0;
|
2012-10-29 14:41:39 +00:00
|
|
|
val->val.len = str->len;
|
2011-05-19 08:36:40 +00:00
|
|
|
val->val.ptr = (qse_char_t*)(val + 1);
|
2012-10-29 14:41:39 +00:00
|
|
|
qse_strncpy (val->val.ptr, str->ptr, str->len);
|
2007-05-02 01:07:00 +00:00
|
|
|
|
|
|
|
#ifdef DEBUG_VAL
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_dprintf (QSE_T("makestrval => %p\n"), val);
|
2007-05-02 01:07:00 +00:00
|
|
|
#endif
|
2008-12-21 21:35:07 +00:00
|
|
|
return (qse_awk_val_t*)val;
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
2012-10-29 14:41:39 +00:00
|
|
|
qse_awk_val_t* qse_awk_rtx_makestrval (
|
|
|
|
qse_awk_rtx_t* rtx, const qse_char_t* str, qse_size_t len)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2012-10-29 14:41:39 +00:00
|
|
|
qse_cstr_t cstr;
|
|
|
|
cstr.ptr = str;
|
|
|
|
cstr.len = len;
|
|
|
|
return qse_awk_rtx_makestrvalwithcstr (rtx, &cstr);
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
2009-02-01 03:59:46 +00:00
|
|
|
qse_awk_val_t* qse_awk_rtx_makestrval2 (
|
2009-08-21 05:28:03 +00:00
|
|
|
qse_awk_rtx_t* rtx,
|
2008-12-21 21:35:07 +00:00
|
|
|
const qse_char_t* str1, qse_size_t len1,
|
|
|
|
const qse_char_t* str2, qse_size_t len2)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_awk_val_str_t* val;
|
|
|
|
qse_size_t rlen = len1 + len2;
|
2008-01-16 03:01:47 +00:00
|
|
|
|
2009-09-19 22:28:49 +00:00
|
|
|
#ifdef ENABLE_FEATURE_SCACHE
|
|
|
|
int i;
|
|
|
|
|
|
|
|
i = rlen / FEATURE_SCACHE_BLOCK_UNIT;
|
|
|
|
if (i < QSE_COUNTOF(rtx->scache_count))
|
2008-01-16 03:01:47 +00:00
|
|
|
{
|
2009-09-19 22:28:49 +00:00
|
|
|
rlen = (i + 1) * FEATURE_SCACHE_BLOCK_UNIT - 1;
|
|
|
|
if (rtx->scache_count[i] > 0)
|
2008-01-16 03:01:47 +00:00
|
|
|
{
|
2009-09-19 22:28:49 +00:00
|
|
|
val = rtx->scache[i][--rtx->scache_count[i]];
|
2008-01-16 03:01:47 +00:00
|
|
|
goto init;
|
|
|
|
}
|
|
|
|
}
|
2009-09-19 22:28:49 +00:00
|
|
|
#endif
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
val = (qse_awk_val_str_t*) QSE_AWK_ALLOC (
|
2009-08-21 05:28:03 +00:00
|
|
|
rtx->awk,
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_SIZEOF(qse_awk_val_str_t) +
|
|
|
|
(rlen+1)*QSE_SIZEOF(qse_char_t));
|
|
|
|
if (val == QSE_NULL)
|
2007-11-03 23:35:00 +00:00
|
|
|
{
|
2009-08-21 05:28:03 +00:00
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
2008-12-21 21:35:07 +00:00
|
|
|
return QSE_NULL;
|
2007-11-03 23:35:00 +00:00
|
|
|
}
|
|
|
|
|
2009-09-19 22:28:49 +00:00
|
|
|
#ifdef ENABLE_FEATURE_SCACHE
|
2008-01-16 03:01:47 +00:00
|
|
|
init:
|
2009-09-19 22:28:49 +00:00
|
|
|
#endif
|
2008-12-21 21:35:07 +00:00
|
|
|
val->type = QSE_AWK_VAL_STR;
|
2007-11-03 23:35:00 +00:00
|
|
|
val->ref = 0;
|
2012-11-05 05:20:12 +00:00
|
|
|
val->stat = 0;
|
2009-06-15 07:22:00 +00:00
|
|
|
val->nstr = 0;
|
2011-05-19 08:36:40 +00:00
|
|
|
val->val.len = len1 + len2;
|
|
|
|
val->val.ptr = (qse_char_t*)(val + 1);
|
|
|
|
qse_strncpy (val->val.ptr, str1, len1);
|
|
|
|
qse_strncpy (&val->val.ptr[len1], str2, len2);
|
2007-05-02 01:07:00 +00:00
|
|
|
|
|
|
|
#ifdef DEBUG_VAL
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_dprintf (QSE_T("makestrval2 => %p\n"), val);
|
2007-05-02 01:07:00 +00:00
|
|
|
#endif
|
2008-12-21 21:35:07 +00:00
|
|
|
return (qse_awk_val_t*)val;
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
2012-10-29 14:41:39 +00:00
|
|
|
qse_awk_val_t* qse_awk_rtx_makenstrvalwithcstr (qse_awk_rtx_t* rtx, const qse_cstr_t* str)
|
2009-06-21 06:47:34 +00:00
|
|
|
{
|
|
|
|
int x;
|
|
|
|
qse_awk_val_t* v;
|
|
|
|
qse_long_t l;
|
2011-11-22 05:03:31 +00:00
|
|
|
qse_flt_t r;
|
2009-06-21 06:47:34 +00:00
|
|
|
|
2012-10-29 14:41:39 +00:00
|
|
|
x = qse_awk_rtx_strtonum (rtx, 1, str->ptr, str->len, &l, &r);
|
|
|
|
v = qse_awk_rtx_makestrvalwithcstr (rtx, str);
|
2009-06-21 06:47:34 +00:00
|
|
|
|
|
|
|
if (v == QSE_NULL) return QSE_NULL;
|
|
|
|
|
|
|
|
if (x >= 0)
|
|
|
|
{
|
|
|
|
/* set the numeric string flag if a string
|
|
|
|
* can be converted to a number */
|
|
|
|
QSE_ASSERT (x == 0 || x == 1);
|
|
|
|
v->nstr = x + 1; /* long -> 1, real -> 2 */
|
|
|
|
}
|
|
|
|
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2009-02-01 03:59:46 +00:00
|
|
|
qse_awk_val_t* qse_awk_rtx_makerexval (
|
2012-11-01 15:03:02 +00:00
|
|
|
qse_awk_rtx_t* rtx, const qse_cstr_t* str, void* code)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_awk_val_rex_t* val;
|
2009-02-17 02:11:31 +00:00
|
|
|
qse_size_t totsz;
|
|
|
|
|
|
|
|
/* the regular expression value holds:
|
2009-08-21 05:28:03 +00:00
|
|
|
* - header
|
|
|
|
* - a raw string plus with added a terminating '\0'
|
2009-02-17 02:11:31 +00:00
|
|
|
* the total size is just large enough for all these.
|
|
|
|
*/
|
2012-11-01 15:03:02 +00:00
|
|
|
totsz = QSE_SIZEOF(*val) + (QSE_SIZEOF(*str->ptr) * (str->len + 1));
|
2009-08-21 05:28:03 +00:00
|
|
|
val = (qse_awk_val_rex_t*) QSE_AWK_ALLOC (rtx->awk, totsz);
|
2009-02-17 02:11:31 +00:00
|
|
|
if (val == QSE_NULL)
|
|
|
|
{
|
2009-08-21 05:28:03 +00:00
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
2009-02-17 02:11:31 +00:00
|
|
|
return QSE_NULL;
|
|
|
|
}
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
val->type = QSE_AWK_VAL_REX;
|
2007-05-02 01:07:00 +00:00
|
|
|
val->ref = 0;
|
2012-11-05 05:20:12 +00:00
|
|
|
val->stat = 0;
|
2009-06-15 07:22:00 +00:00
|
|
|
val->nstr = 0;
|
2012-11-01 15:03:02 +00:00
|
|
|
val->str.len = str->len;
|
2009-02-17 02:11:31 +00:00
|
|
|
|
2012-11-01 15:03:02 +00:00
|
|
|
val->str.ptr = (qse_char_t*)(val + 1);
|
|
|
|
qse_strncpy (val->str.ptr, str->ptr, str->len);
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2009-12-11 07:03:54 +00:00
|
|
|
val->code = code;
|
2008-02-29 00:50:10 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
return (qse_awk_val_t*)val;
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
2010-07-09 00:58:44 +00:00
|
|
|
static void free_mapval (qse_htb_t* map, void* dptr, qse_size_t dlen)
|
2008-09-25 02:00:50 +00:00
|
|
|
{
|
2009-09-19 22:28:49 +00:00
|
|
|
qse_awk_rtx_t* rtx = *(qse_awk_rtx_t**)QSE_XTN(map);
|
2008-09-25 02:00:50 +00:00
|
|
|
|
|
|
|
#ifdef DEBUG_VAL
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_dprintf (QSE_T("refdown in map free..."));
|
2009-09-19 22:28:49 +00:00
|
|
|
qse_awk_dprintval (rtx, dptr);
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_dprintf (QSE_T("\n"));
|
2008-09-25 02:00:50 +00:00
|
|
|
#endif
|
|
|
|
|
2009-09-19 22:28:49 +00:00
|
|
|
qse_awk_rtx_refdownval (rtx, dptr);
|
2008-09-25 02:00:50 +00:00
|
|
|
}
|
|
|
|
|
2010-07-09 00:58:44 +00:00
|
|
|
static void same_mapval (qse_htb_t* map, void* dptr, qse_size_t dlen)
|
2008-09-25 02:00:50 +00:00
|
|
|
{
|
2009-02-17 02:11:31 +00:00
|
|
|
qse_awk_rtx_t* run = *(qse_awk_rtx_t**)QSE_XTN(map);
|
2008-09-25 02:00:50 +00:00
|
|
|
#ifdef DEBUG_VAL
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_dprintf (QSE_T("refdown nofree in map free..."));
|
|
|
|
qse_awk_dprintval (run, dptr);
|
|
|
|
qse_dprintf (QSE_T("\n"));
|
2008-09-25 02:00:50 +00:00
|
|
|
#endif
|
2009-02-01 03:59:46 +00:00
|
|
|
qse_awk_rtx_refdownval_nofree (run, dptr);
|
2008-09-25 02:00:50 +00:00
|
|
|
}
|
2007-12-07 19:57:10 +00:00
|
|
|
|
2009-08-21 05:28:03 +00:00
|
|
|
qse_awk_val_t* qse_awk_rtx_makemapval (qse_awk_rtx_t* rtx)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2010-10-28 06:54:37 +00:00
|
|
|
static qse_htb_mancbs_t mancbs =
|
|
|
|
{
|
|
|
|
/* the key is copied inline into a pair and is freed when the pair
|
|
|
|
* is destroyed. not setting copier for a value means that the pointer
|
|
|
|
* to the data allocated somewhere else is remembered in a pair. but
|
|
|
|
* freeing the actual value is handled by free_mapval and same_mapval */
|
|
|
|
{
|
|
|
|
QSE_HTB_COPIER_INLINE,
|
|
|
|
QSE_HTB_COPIER_DEFAULT
|
|
|
|
},
|
|
|
|
{
|
|
|
|
QSE_HTB_FREEER_DEFAULT,
|
|
|
|
free_mapval
|
|
|
|
},
|
|
|
|
QSE_HTB_COMPER_DEFAULT,
|
|
|
|
same_mapval,
|
2010-10-30 07:54:36 +00:00
|
|
|
QSE_HTB_SIZER_DEFAULT,
|
|
|
|
QSE_HTB_HASHER_DEFAULT
|
2010-10-28 06:54:37 +00:00
|
|
|
};
|
2011-05-13 08:55:53 +00:00
|
|
|
qse_awk_val_map_t* val;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2008-09-25 05:07:24 +00:00
|
|
|
/* CHECK */
|
|
|
|
/*
|
2008-12-21 21:35:07 +00:00
|
|
|
val = (qse_awk_val_map_t*) QSE_AWK_ALLOC (
|
|
|
|
run->awk, QSE_SIZEOF(qse_awk_val_map_t) );
|
|
|
|
if (val == QSE_NULL)
|
2007-10-24 00:18:00 +00:00
|
|
|
{
|
2009-08-17 02:08:58 +00:00
|
|
|
qse_awk_rtx_seterrnum (run, QSE_AWK_ENOMEM, QSE_NULL);
|
2008-12-21 21:35:07 +00:00
|
|
|
return QSE_NULL;
|
2007-10-24 00:18:00 +00:00
|
|
|
}
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
val->type = QSE_AWK_VAL_MAP;
|
2007-05-02 01:07:00 +00:00
|
|
|
val->ref = 0;
|
2012-11-05 05:20:12 +00:00
|
|
|
val->stat = 0;
|
2009-06-15 07:22:00 +00:00
|
|
|
val->nstr = 0;
|
2010-07-09 00:58:44 +00:00
|
|
|
val->map = qse_htb_open (
|
2008-07-20 23:53:29 +00:00
|
|
|
run, 256, 70, free_mapval, same_mapval, run->awk->mmgr);
|
2008-12-21 21:35:07 +00:00
|
|
|
if (val->map == QSE_NULL)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_AWK_FREE (run->awk, val);
|
2009-08-17 02:08:58 +00:00
|
|
|
qse_awk_rtx_seterrnum (run, QSE_AWK_ENOMEM, QSE_NULL);
|
2008-12-21 21:35:07 +00:00
|
|
|
return QSE_NULL;
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
2008-09-25 02:00:50 +00:00
|
|
|
*/
|
2008-09-25 05:07:24 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
val = (qse_awk_val_map_t*) QSE_AWK_ALLOC (
|
2009-08-21 05:28:03 +00:00
|
|
|
rtx->awk,
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_SIZEOF(qse_awk_val_map_t) +
|
2010-07-09 00:58:44 +00:00
|
|
|
QSE_SIZEOF(qse_htb_t) +
|
2009-08-21 05:28:03 +00:00
|
|
|
QSE_SIZEOF(rtx));
|
2008-12-21 21:35:07 +00:00
|
|
|
if (val == QSE_NULL)
|
2008-09-25 05:07:24 +00:00
|
|
|
{
|
2009-08-21 05:28:03 +00:00
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
2008-12-21 21:35:07 +00:00
|
|
|
return QSE_NULL;
|
2008-09-25 05:07:24 +00:00
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
val->type = QSE_AWK_VAL_MAP;
|
2008-09-25 05:07:24 +00:00
|
|
|
val->ref = 0;
|
2012-11-05 05:20:12 +00:00
|
|
|
val->stat = 0;
|
2009-06-15 07:22:00 +00:00
|
|
|
val->nstr = 0;
|
2010-07-09 00:58:44 +00:00
|
|
|
val->map = (qse_htb_t*)(val + 1);
|
2008-09-25 05:07:24 +00:00
|
|
|
|
2011-09-01 09:43:46 +00:00
|
|
|
if (qse_htb_init (
|
|
|
|
val->map, rtx->awk->mmgr,
|
|
|
|
256, 70, QSE_SIZEOF(qse_char_t), 1) <= -1)
|
2008-09-25 02:00:50 +00:00
|
|
|
{
|
2009-08-21 05:28:03 +00:00
|
|
|
QSE_AWK_FREE (rtx->awk, val);
|
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
2008-12-21 21:35:07 +00:00
|
|
|
return QSE_NULL;
|
2008-09-25 02:00:50 +00:00
|
|
|
}
|
2009-08-21 05:28:03 +00:00
|
|
|
*(qse_awk_rtx_t**)QSE_XTN(val->map) = rtx;
|
2010-10-28 06:54:37 +00:00
|
|
|
qse_htb_setmancbs (val->map, &mancbs);
|
2008-09-25 02:00:50 +00:00
|
|
|
/* END CHECK */
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
return (qse_awk_val_t*)val;
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
2012-10-29 14:41:39 +00:00
|
|
|
qse_awk_val_t* qse_awk_rtx_makemapvalwithdata (qse_awk_rtx_t* rtx, qse_awk_val_map_data_t data[])
|
|
|
|
{
|
|
|
|
qse_awk_val_t* map, * tmp;
|
|
|
|
qse_awk_val_map_data_t* p;
|
|
|
|
|
|
|
|
map = qse_awk_rtx_makemapval (rtx);
|
|
|
|
if (map == QSE_NULL) return QSE_NULL;
|
|
|
|
|
|
|
|
for (p = data; p->key.ptr; p++)
|
|
|
|
{
|
|
|
|
switch (p->type)
|
|
|
|
{
|
|
|
|
case QSE_AWK_VAL_MAP_DATA_INT:
|
|
|
|
tmp = qse_awk_rtx_makeintval (rtx, *(qse_long_t*)p->vptr);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QSE_AWK_VAL_MAP_DATA_FLT:
|
|
|
|
tmp = qse_awk_rtx_makefltval (rtx, *(qse_flt_t*)p->vptr);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QSE_AWK_VAL_MAP_DATA_STR:
|
|
|
|
tmp = qse_awk_rtx_makestrvalwithstr (rtx, (qse_char_t*)p->vptr);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QSE_AWK_VAL_MAP_DATA_MBS:
|
|
|
|
tmp = qse_awk_rtx_makestrvalwithmbs (rtx, (qse_mchar_t*)p->vptr);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QSE_AWK_VAL_MAP_DATA_WCS:
|
|
|
|
tmp = qse_awk_rtx_makestrvalwithwcs (rtx, (qse_wchar_t*)p->vptr);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QSE_AWK_VAL_MAP_DATA_XSTR:
|
|
|
|
case QSE_AWK_VAL_MAP_DATA_CSTR:
|
|
|
|
tmp = qse_awk_rtx_makestrvalwithcstr (rtx, (qse_cstr_t*)p->vptr);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QSE_AWK_VAL_MAP_DATA_MXSTR:
|
|
|
|
case QSE_AWK_VAL_MAP_DATA_MCSTR:
|
|
|
|
tmp = qse_awk_rtx_makestrvalwithmcstr (rtx, (qse_mcstr_t*)p->vptr);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QSE_AWK_VAL_MAP_DATA_WXSTR:
|
|
|
|
case QSE_AWK_VAL_MAP_DATA_WCSTR:
|
|
|
|
tmp = qse_awk_rtx_makestrvalwithwcstr (rtx, (qse_wcstr_t*)p->vptr);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
tmp = QSE_NULL;
|
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINVAL, QSE_NULL);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tmp == QSE_NULL || qse_awk_rtx_setmapvalfld (rtx, map, p->key.ptr, p->key.len, tmp) == QSE_NULL)
|
|
|
|
{
|
|
|
|
if (tmp) qse_awk_rtx_freeval (rtx, tmp, 1);
|
|
|
|
qse_awk_rtx_freeval (rtx, map, 1);
|
|
|
|
return QSE_NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return map;
|
|
|
|
}
|
|
|
|
|
2011-05-13 08:55:53 +00:00
|
|
|
qse_awk_val_t* qse_awk_rtx_setmapvalfld (
|
|
|
|
qse_awk_rtx_t* rtx, qse_awk_val_t* map,
|
2011-05-13 10:16:57 +00:00
|
|
|
const qse_char_t* kptr, qse_size_t klen, qse_awk_val_t* v)
|
2011-05-13 08:55:53 +00:00
|
|
|
{
|
|
|
|
QSE_ASSERT (map->type == QSE_AWK_VAL_MAP);
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
if (map->type != QSE_AWK_VAL_MAP)
|
|
|
|
{
|
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOTIDX, QSE_NULL);
|
|
|
|
return QSE_NULL;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (qse_htb_upsert (
|
|
|
|
((qse_awk_val_map_t*)map)->map,
|
2011-05-13 10:16:57 +00:00
|
|
|
(qse_char_t*)kptr, klen, v, 0) == QSE_NULL)
|
2011-05-13 08:55:53 +00:00
|
|
|
{
|
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
|
|
|
return QSE_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
|
|
|
|
* can be destroyed if it was passed with the reference count of 0.
|
|
|
|
* so we increment the reference count when htb_upsert() is complete */
|
|
|
|
qse_awk_rtx_refupval (rtx, v);
|
|
|
|
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
|
|
|
qse_awk_val_t* qse_awk_rtx_getmapvalfld (
|
|
|
|
qse_awk_rtx_t* rtx, qse_awk_val_t* map,
|
2011-05-13 10:16:57 +00:00
|
|
|
const qse_char_t* kptr, qse_size_t klen)
|
2011-05-13 08:55:53 +00:00
|
|
|
{
|
|
|
|
qse_htb_pair_t* pair;
|
|
|
|
|
|
|
|
QSE_ASSERT (map->type == QSE_AWK_VAL_MAP);
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
if (map->type != QSE_AWK_VAL_MAP)
|
|
|
|
{
|
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOTIDX, QSE_NULL);
|
|
|
|
return QSE_NULL;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
pair = qse_htb_search (((qse_awk_val_map_t*)map)->map, kptr, klen);
|
|
|
|
if (pair == QSE_NULL)
|
|
|
|
{
|
|
|
|
/* the given key is not found in the map.
|
|
|
|
* we return NULL here as this function is called by
|
|
|
|
* a user unlike the awk statement accessing the map key.
|
|
|
|
* so you can easily determine if the key is found by
|
|
|
|
* checking the error number.
|
|
|
|
*/
|
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINVAL, QSE_NULL);
|
|
|
|
return QSE_NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return QSE_HTB_VPTR(pair);
|
|
|
|
}
|
|
|
|
|
2011-05-13 22:06:55 +00:00
|
|
|
qse_awk_val_map_itr_t* qse_awk_rtx_getfirstmapvalitr (
|
|
|
|
qse_awk_rtx_t* rtx, qse_awk_val_t* map, qse_awk_val_map_itr_t* itr)
|
|
|
|
{
|
|
|
|
QSE_ASSERT (map->type == QSE_AWK_VAL_MAP);
|
|
|
|
itr->pair = qse_htb_getfirstpair (
|
|
|
|
((qse_awk_val_map_t*)map)->map, &itr->buckno);
|
|
|
|
return itr->pair? itr: QSE_NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
qse_awk_val_map_itr_t* qse_awk_rtx_getnextmapvalitr (
|
|
|
|
qse_awk_rtx_t* rtx, qse_awk_val_t* map, qse_awk_val_map_itr_t* itr)
|
|
|
|
{
|
|
|
|
QSE_ASSERT (map->type == QSE_AWK_VAL_MAP);
|
|
|
|
itr->pair = qse_htb_getnextpair (
|
|
|
|
((qse_awk_val_map_t*)map)->map, itr->pair, &itr->buckno);
|
|
|
|
return itr->pair? itr: QSE_NULL;
|
|
|
|
}
|
|
|
|
|
2009-08-21 05:28:03 +00:00
|
|
|
qse_awk_val_t* qse_awk_rtx_makerefval (
|
|
|
|
qse_awk_rtx_t* rtx, int id, qse_awk_val_t** adr)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_awk_val_ref_t* val;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2012-10-29 14:41:39 +00:00
|
|
|
if (rtx->rcache_count > 0)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2012-10-29 14:41:39 +00:00
|
|
|
val = rtx->rcache[--rtx->rcache_count];
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
val = (qse_awk_val_ref_t*) QSE_AWK_ALLOC (
|
2009-08-21 05:28:03 +00:00
|
|
|
rtx->awk, QSE_SIZEOF(qse_awk_val_ref_t));
|
2008-12-21 21:35:07 +00:00
|
|
|
if (val == QSE_NULL)
|
2007-10-24 00:18:00 +00:00
|
|
|
{
|
2009-08-21 05:28:03 +00:00
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
2008-12-21 21:35:07 +00:00
|
|
|
return QSE_NULL;
|
2007-10-24 00:18:00 +00:00
|
|
|
}
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
val->type = QSE_AWK_VAL_REF;
|
2007-05-02 01:07:00 +00:00
|
|
|
val->ref = 0;
|
2012-11-05 05:20:12 +00:00
|
|
|
val->stat = 0;
|
2009-06-15 07:22:00 +00:00
|
|
|
val->nstr = 0;
|
2007-05-02 01:07:00 +00:00
|
|
|
val->id = id;
|
|
|
|
val->adr = adr;
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
return (qse_awk_val_t*)val;
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
2012-11-05 05:20:12 +00:00
|
|
|
/*
|
|
|
|
* if shared objects link a static library, statically defined objects
|
|
|
|
* in the static library will be instatiated in the multiple shared objects.
|
|
|
|
*
|
|
|
|
* so equality check with a value pointer doesn't work
|
|
|
|
* if the code crosses the library boundaries. instead, i decided to
|
|
|
|
* add a field to indicate if a value is static.
|
|
|
|
*
|
|
|
|
|
2008-01-16 23:08:17 +00:00
|
|
|
#define IS_STATICVAL(val) \
|
2008-12-21 21:35:07 +00:00
|
|
|
((val) == QSE_NULL || \
|
|
|
|
(val) == qse_awk_val_nil || \
|
|
|
|
(val) == qse_awk_val_zls || \
|
|
|
|
(val) == qse_awk_val_zero || \
|
|
|
|
(val) == qse_awk_val_one || \
|
|
|
|
((val) >= (qse_awk_val_t*)&awk_int[0] && \
|
|
|
|
(val) <= (qse_awk_val_t*)&awk_int[QSE_COUNTOF(awk_int)-1]))
|
2012-11-05 05:20:12 +00:00
|
|
|
*/
|
|
|
|
#define IS_STATICVAL(val) ((val)->stat)
|
2008-12-21 21:35:07 +00:00
|
|
|
|
2012-10-22 09:36:15 +00:00
|
|
|
int qse_awk_rtx_isstaticval (qse_awk_rtx_t* rtx, qse_awk_val_t* val)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2008-01-16 23:08:17 +00:00
|
|
|
return IS_STATICVAL(val);
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
2009-09-19 22:28:49 +00:00
|
|
|
void qse_awk_rtx_freeval (
|
2012-10-22 09:36:15 +00:00
|
|
|
qse_awk_rtx_t* rtx, qse_awk_val_t* val, int cache)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2008-01-16 23:08:17 +00:00
|
|
|
if (IS_STATICVAL(val)) return;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
|
|
|
#ifdef DEBUG_VAL
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_dprintf (QSE_T("freeing [cache=%d] ... "), cache);
|
2009-02-01 03:59:46 +00:00
|
|
|
qse_awk_dprintval (rtx, val);
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_dprintf (QSE_T("\n"));
|
2007-05-02 01:07:00 +00:00
|
|
|
#endif
|
|
|
|
|
2011-05-26 08:42:26 +00:00
|
|
|
switch (val->type)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2011-05-26 08:42:26 +00:00
|
|
|
case QSE_AWK_VAL_NIL:
|
|
|
|
{
|
|
|
|
QSE_AWK_FREE (rtx->awk, val);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case QSE_AWK_VAL_INT:
|
2008-01-16 03:01:47 +00:00
|
|
|
{
|
2011-05-26 08:42:26 +00:00
|
|
|
((qse_awk_val_int_t*)val)->nde =
|
|
|
|
(qse_awk_nde_int_t*)rtx->vmgr.ifree;
|
|
|
|
rtx->vmgr.ifree = (qse_awk_val_int_t*)val;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2011-11-22 05:03:31 +00:00
|
|
|
case QSE_AWK_VAL_FLT:
|
2011-05-26 08:42:26 +00:00
|
|
|
{
|
2011-11-22 05:03:31 +00:00
|
|
|
((qse_awk_val_flt_t*)val)->nde =
|
|
|
|
(qse_awk_nde_flt_t*)rtx->vmgr.rfree;
|
|
|
|
rtx->vmgr.rfree = (qse_awk_val_flt_t*)val;
|
2011-05-26 08:42:26 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-09-19 22:28:49 +00:00
|
|
|
|
2011-05-26 08:42:26 +00:00
|
|
|
case QSE_AWK_VAL_STR:
|
|
|
|
{
|
|
|
|
#ifdef ENABLE_FEATURE_SCACHE
|
|
|
|
if (cache)
|
2008-01-16 03:01:47 +00:00
|
|
|
{
|
2011-05-26 08:42:26 +00:00
|
|
|
qse_awk_val_str_t* v = (qse_awk_val_str_t*)val;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
i = v->val.len / FEATURE_SCACHE_BLOCK_UNIT;
|
|
|
|
if (i < QSE_COUNTOF(rtx->scache_count) &&
|
|
|
|
rtx->scache_count[i] < QSE_COUNTOF(rtx->scache[i]))
|
|
|
|
{
|
|
|
|
rtx->scache[i][rtx->scache_count[i]++] = v;
|
|
|
|
v->nstr = 0;
|
|
|
|
}
|
|
|
|
else QSE_AWK_FREE (rtx->awk, val);
|
2008-01-16 03:01:47 +00:00
|
|
|
}
|
2011-05-26 08:42:26 +00:00
|
|
|
else
|
|
|
|
#endif
|
|
|
|
QSE_AWK_FREE (rtx->awk, val);
|
|
|
|
|
|
|
|
break;
|
2008-01-16 03:01:47 +00:00
|
|
|
}
|
2011-05-26 08:42:26 +00:00
|
|
|
|
|
|
|
case QSE_AWK_VAL_REX:
|
|
|
|
{
|
|
|
|
/* don't free ptr as it is inlined to val
|
|
|
|
QSE_AWK_FREE (rtx->awk, ((qse_awk_val_rex_t*)val)->ptr);
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* code is just a pointer to a regular expression stored
|
|
|
|
* in parse tree nodes. so don't free it.
|
|
|
|
QSE_AWK_FREEREX (rtx->awk, ((qse_awk_val_rex_t*)val)->code);
|
|
|
|
*/
|
|
|
|
|
2009-09-19 22:28:49 +00:00
|
|
|
QSE_AWK_FREE (rtx->awk, val);
|
2011-05-26 08:42:26 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-12-11 07:03:54 +00:00
|
|
|
|
2011-05-26 08:42:26 +00:00
|
|
|
case QSE_AWK_VAL_MAP:
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2011-05-26 08:42:26 +00:00
|
|
|
qse_htb_fini (((qse_awk_val_map_t*)val)->map);
|
|
|
|
QSE_AWK_FREE (rtx->awk, val);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case QSE_AWK_VAL_REF:
|
|
|
|
{
|
2012-10-29 14:41:39 +00:00
|
|
|
if (cache && rtx->rcache_count < QSE_COUNTOF(rtx->rcache))
|
2011-05-26 08:42:26 +00:00
|
|
|
{
|
2012-10-29 14:41:39 +00:00
|
|
|
rtx->rcache[rtx->rcache_count++] = (qse_awk_val_ref_t*)val;
|
2011-05-26 08:42:26 +00:00
|
|
|
}
|
|
|
|
else QSE_AWK_FREE (rtx->awk, val);
|
|
|
|
break;
|
|
|
|
}
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-01 03:59:46 +00:00
|
|
|
void qse_awk_rtx_refupval (qse_awk_rtx_t* rtx, qse_awk_val_t* val)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2008-01-16 23:08:17 +00:00
|
|
|
if (IS_STATICVAL(val)) return;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
|
|
|
#ifdef DEBUG_VAL
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_dprintf (QSE_T("ref up [ptr=%p] [count=%d] "), val, (int)val->ref);
|
2009-02-01 03:59:46 +00:00
|
|
|
qse_awk_dprintval (rtx, val);
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_dprintf (QSE_T("\n"));
|
2007-05-02 01:07:00 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
val->ref++;
|
|
|
|
}
|
|
|
|
|
2009-02-01 03:59:46 +00:00
|
|
|
void qse_awk_rtx_refdownval (qse_awk_rtx_t* rtx, qse_awk_val_t* val)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2008-01-16 23:08:17 +00:00
|
|
|
if (IS_STATICVAL(val)) return;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
|
|
|
#ifdef DEBUG_VAL
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_dprintf (QSE_T("ref down [ptr=%p] [count=%d]\n"), val, (int)val->ref);
|
2009-02-01 03:59:46 +00:00
|
|
|
qse_awk_dprintval (rtx, val);
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_dprintf (QSE_T("\n"));
|
2007-05-02 01:07:00 +00:00
|
|
|
#endif
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_ASSERTX (val->ref > 0,
|
2012-12-13 13:07:16 +00:00
|
|
|
"the reference count of a value should be greater than zero for it to be decremented. check the source code for any bugs");
|
2007-05-02 01:07:00 +00:00
|
|
|
|
|
|
|
val->ref--;
|
|
|
|
if (val->ref <= 0)
|
|
|
|
{
|
2012-10-22 09:36:15 +00:00
|
|
|
qse_awk_rtx_freeval(rtx, val, 1);
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-01 03:59:46 +00:00
|
|
|
void qse_awk_rtx_refdownval_nofree (qse_awk_rtx_t* rtx, qse_awk_val_t* val)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2008-01-16 23:08:17 +00:00
|
|
|
if (IS_STATICVAL(val)) return;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_ASSERTX (val->ref > 0,
|
2012-12-13 13:07:16 +00:00
|
|
|
"the reference count of a value should be greater than zero for it to be decremented. check the source code for any bugs");
|
2007-05-02 01:07:00 +00:00
|
|
|
val->ref--;
|
|
|
|
}
|
|
|
|
|
2009-02-01 03:59:46 +00:00
|
|
|
void qse_awk_rtx_freevalchunk (qse_awk_rtx_t* rtx, qse_awk_val_chunk_t* chunk)
|
2008-03-23 00:47:27 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
while (chunk != QSE_NULL)
|
2008-03-23 00:47:27 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_awk_val_chunk_t* next = chunk->next;
|
2009-02-01 03:59:46 +00:00
|
|
|
QSE_AWK_FREE (rtx->awk, chunk);
|
2008-03-23 00:47:27 +00:00
|
|
|
chunk = next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-22 09:36:15 +00:00
|
|
|
int qse_awk_rtx_valtobool (qse_awk_rtx_t* run, const qse_awk_val_t* val)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2012-10-22 09:36:15 +00:00
|
|
|
if (val == QSE_NULL) return 0;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
|
|
|
switch (val->type)
|
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
case QSE_AWK_VAL_NIL:
|
2012-10-22 09:36:15 +00:00
|
|
|
return 0;
|
2008-12-21 21:35:07 +00:00
|
|
|
case QSE_AWK_VAL_INT:
|
|
|
|
return ((qse_awk_val_int_t*)val)->val != 0;
|
2011-11-22 05:03:31 +00:00
|
|
|
case QSE_AWK_VAL_FLT:
|
|
|
|
return ((qse_awk_val_flt_t*)val)->val != 0.0;
|
2008-12-21 21:35:07 +00:00
|
|
|
case QSE_AWK_VAL_STR:
|
2011-05-19 08:36:40 +00:00
|
|
|
return ((qse_awk_val_str_t*)val)->val.len > 0;
|
2008-12-21 21:35:07 +00:00
|
|
|
case QSE_AWK_VAL_REX: /* TODO: is this correct? */
|
2012-11-01 15:03:02 +00:00
|
|
|
return ((qse_awk_val_rex_t*)val)->str.len > 0;
|
2008-12-21 21:35:07 +00:00
|
|
|
case QSE_AWK_VAL_MAP:
|
2012-10-22 09:36:15 +00:00
|
|
|
return 0; /* TODO: is this correct? */
|
2008-12-21 21:35:07 +00:00
|
|
|
case QSE_AWK_VAL_REF:
|
2012-10-22 09:36:15 +00:00
|
|
|
return 0; /* TODO: is this correct? */
|
2011-05-26 08:42:26 +00:00
|
|
|
}
|
2011-05-26 08:50:19 +00:00
|
|
|
|
|
|
|
QSE_ASSERTX (
|
|
|
|
!"should never happen - invalid value type",
|
|
|
|
"the type of a value should be one of QSE_AWK_VAL_XXX's defined in awk.h");
|
2012-10-22 09:36:15 +00:00
|
|
|
return 0;
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
2011-05-26 08:00:19 +00:00
|
|
|
static int str_to_str (
|
2009-02-28 20:18:00 +00:00
|
|
|
qse_awk_rtx_t* rtx, const qse_char_t* str, qse_size_t str_len,
|
2009-03-01 02:44:21 +00:00
|
|
|
qse_awk_rtx_valtostr_out_t* out)
|
2009-02-28 20:18:00 +00:00
|
|
|
{
|
2009-03-01 02:44:21 +00:00
|
|
|
int type = out->type & ~QSE_AWK_RTX_VALTOSTR_PRINT;
|
|
|
|
|
|
|
|
switch (type)
|
2009-02-28 20:18:00 +00:00
|
|
|
{
|
2009-03-01 02:44:21 +00:00
|
|
|
case QSE_AWK_RTX_VALTOSTR_CPL:
|
2009-02-28 20:18:00 +00:00
|
|
|
{
|
2011-05-25 09:14:58 +00:00
|
|
|
out->u.cpl.len = str_len;
|
|
|
|
out->u.cpl.ptr = str;
|
2011-05-26 08:00:19 +00:00
|
|
|
return 0;
|
2011-05-25 09:14:58 +00:00
|
|
|
}
|
|
|
|
|
2011-05-26 08:00:19 +00:00
|
|
|
case QSE_AWK_RTX_VALTOSTR_CPLCPY:
|
2011-05-25 09:14:58 +00:00
|
|
|
{
|
2011-05-26 08:00:19 +00:00
|
|
|
if (str_len >= out->u.cplcpy.len)
|
2009-02-28 20:18:00 +00:00
|
|
|
{
|
2009-08-17 02:08:58 +00:00
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINVAL, QSE_NULL);
|
2011-05-26 08:00:19 +00:00
|
|
|
out->u.cplcpy.len = str_len + 1;
|
|
|
|
return -1;
|
2009-02-28 20:18:00 +00:00
|
|
|
}
|
|
|
|
|
2011-05-26 08:00:19 +00:00
|
|
|
out->u.cplcpy.len =
|
|
|
|
qse_strncpy (out->u.cplcpy.ptr, str, str_len);
|
|
|
|
return 0;
|
2009-02-28 20:18:00 +00:00
|
|
|
}
|
|
|
|
|
2009-03-01 02:44:21 +00:00
|
|
|
case QSE_AWK_RTX_VALTOSTR_CPLDUP:
|
2009-02-28 20:18:00 +00:00
|
|
|
{
|
2009-03-01 02:44:21 +00:00
|
|
|
qse_char_t* tmp;
|
2009-02-28 20:18:00 +00:00
|
|
|
|
2009-03-01 02:44:21 +00:00
|
|
|
tmp = QSE_AWK_STRXDUP (rtx->awk, str, str_len);
|
|
|
|
if (tmp == QSE_NULL)
|
2009-02-28 20:18:00 +00:00
|
|
|
{
|
2009-08-17 02:08:58 +00:00
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
2011-05-26 08:00:19 +00:00
|
|
|
return -1;
|
2009-02-28 20:18:00 +00:00
|
|
|
}
|
|
|
|
|
2009-03-01 02:44:21 +00:00
|
|
|
out->u.cpldup.ptr = tmp;
|
|
|
|
out->u.cpldup.len = str_len;
|
2011-05-26 08:00:19 +00:00
|
|
|
return 0;
|
2009-02-28 20:18:00 +00:00
|
|
|
}
|
2009-03-01 02:44:21 +00:00
|
|
|
|
|
|
|
case QSE_AWK_RTX_VALTOSTR_STRP:
|
2009-02-28 20:18:00 +00:00
|
|
|
{
|
|
|
|
qse_size_t n;
|
|
|
|
|
2009-03-01 02:44:21 +00:00
|
|
|
qse_str_clear (out->u.strp);
|
|
|
|
n = qse_str_ncat (out->u.strp, str, str_len);
|
2009-02-28 20:18:00 +00:00
|
|
|
if (n == (qse_size_t)-1)
|
|
|
|
{
|
2009-08-17 02:08:58 +00:00
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
2011-05-26 08:00:19 +00:00
|
|
|
return -1;
|
2009-02-28 20:18:00 +00:00
|
|
|
}
|
2011-05-26 08:00:19 +00:00
|
|
|
return 0;
|
2009-02-28 20:18:00 +00:00
|
|
|
}
|
|
|
|
|
2009-03-01 02:44:21 +00:00
|
|
|
case QSE_AWK_RTX_VALTOSTR_STRPCAT:
|
2009-02-28 20:18:00 +00:00
|
|
|
{
|
2009-03-01 02:44:21 +00:00
|
|
|
qse_size_t n;
|
|
|
|
|
|
|
|
n = qse_str_ncat (out->u.strpcat, str, str_len);
|
|
|
|
if (n == (qse_size_t)-1)
|
2009-02-28 20:18:00 +00:00
|
|
|
{
|
2009-08-17 02:08:58 +00:00
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
2011-05-26 08:00:19 +00:00
|
|
|
return -1;
|
2009-02-28 20:18:00 +00:00
|
|
|
}
|
2011-05-26 08:00:19 +00:00
|
|
|
return 0;
|
2009-02-28 20:18:00 +00:00
|
|
|
}
|
2011-05-26 08:42:26 +00:00
|
|
|
}
|
2011-05-26 08:50:19 +00:00
|
|
|
|
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINVAL, QSE_NULL);
|
|
|
|
return -1;
|
2009-02-28 20:18:00 +00:00
|
|
|
}
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2011-05-26 08:00:19 +00:00
|
|
|
static int val_int_to_str (
|
2011-05-25 09:14:58 +00:00
|
|
|
qse_awk_rtx_t* rtx, const qse_awk_val_int_t* v,
|
2009-03-01 02:44:21 +00:00
|
|
|
qse_awk_rtx_valtostr_out_t* out)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_char_t* tmp;
|
2012-08-27 15:10:57 +00:00
|
|
|
qse_ulong_t t;
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_size_t rlen = 0;
|
2009-03-01 02:44:21 +00:00
|
|
|
int type = out->type & ~QSE_AWK_RTX_VALTOSTR_PRINT;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2012-08-27 15:10:57 +00:00
|
|
|
if (v->val == 0) rlen++;
|
2011-05-26 08:00:19 +00:00
|
|
|
else
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2011-05-26 08:00:19 +00:00
|
|
|
/* non-zero values */
|
2012-08-27 15:10:57 +00:00
|
|
|
if (v->val < 0)
|
|
|
|
{
|
|
|
|
t = v->val * -1; rlen++;
|
|
|
|
}
|
|
|
|
else t = v->val;
|
2011-05-26 08:00:19 +00:00
|
|
|
while (t > 0) { rlen++; t /= 10; }
|
2009-03-01 02:44:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case QSE_AWK_RTX_VALTOSTR_CPL:
|
2011-05-25 09:14:58 +00:00
|
|
|
/* CPL and CPLCP behave the same for int_t.
|
2011-05-26 08:00:19 +00:00
|
|
|
* i just fall through assuming that cplcpy
|
2011-05-25 09:14:58 +00:00
|
|
|
* and cpl are the same type. the following
|
|
|
|
* assertion at least ensure that they have
|
|
|
|
* the same size. */
|
2011-05-26 08:00:19 +00:00
|
|
|
QSE_ASSERT (QSE_SIZEOF(out->u.cpl) == QSE_SIZEOF(out->u.cplcpy));
|
2011-05-25 09:14:58 +00:00
|
|
|
|
2011-05-26 08:00:19 +00:00
|
|
|
case QSE_AWK_RTX_VALTOSTR_CPLCPY:
|
|
|
|
if (rlen >= out->u.cplcpy.len)
|
2008-01-16 21:46:08 +00:00
|
|
|
{
|
2009-08-17 02:08:58 +00:00
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINVAL, QSE_NULL);
|
2009-03-01 02:44:21 +00:00
|
|
|
/* store the buffer size needed */
|
2011-05-26 08:00:19 +00:00
|
|
|
out->u.cplcpy.len = rlen + 1;
|
|
|
|
return -1;
|
2008-01-16 21:46:08 +00:00
|
|
|
}
|
|
|
|
|
2011-05-26 08:00:19 +00:00
|
|
|
tmp = out->u.cplcpy.ptr;
|
2009-03-01 02:44:21 +00:00
|
|
|
tmp[rlen] = QSE_T('\0');
|
2011-05-26 08:00:19 +00:00
|
|
|
out->u.cplcpy.len = rlen;
|
2009-03-01 02:44:21 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case QSE_AWK_RTX_VALTOSTR_CPLDUP:
|
|
|
|
tmp = QSE_AWK_ALLOC (
|
|
|
|
rtx->awk, (rlen + 1) * QSE_SIZEOF(qse_char_t));
|
|
|
|
if (tmp == QSE_NULL)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2009-08-17 02:08:58 +00:00
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
2011-05-26 08:00:19 +00:00
|
|
|
return -1;
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
2009-03-01 02:44:21 +00:00
|
|
|
tmp[rlen] = QSE_T('\0');
|
|
|
|
out->u.cpldup.ptr = tmp;
|
|
|
|
out->u.cpldup.len = rlen;
|
|
|
|
break;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2009-03-01 02:44:21 +00:00
|
|
|
case QSE_AWK_RTX_VALTOSTR_STRP:
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2009-03-01 02:44:21 +00:00
|
|
|
qse_size_t n;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2009-03-01 02:44:21 +00:00
|
|
|
qse_str_clear (out->u.strp);
|
|
|
|
QSE_ASSERT (QSE_STR_LEN(out->u.strp) == 0);
|
2008-01-16 21:46:08 +00:00
|
|
|
|
2009-03-01 02:44:21 +00:00
|
|
|
/* point to the beginning of the buffer */
|
|
|
|
tmp = QSE_STR_PTR(out->u.strp);
|
|
|
|
|
|
|
|
/* extend the buffer */
|
|
|
|
n = qse_str_nccat (out->u.strp, QSE_T(' '), rlen);
|
|
|
|
if (n == (qse_size_t)-1)
|
|
|
|
{
|
2009-08-17 02:08:58 +00:00
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
2011-05-26 08:00:19 +00:00
|
|
|
return -1;
|
2009-03-01 02:44:21 +00:00
|
|
|
}
|
|
|
|
break;
|
2008-01-16 21:46:08 +00:00
|
|
|
}
|
|
|
|
|
2009-03-01 02:44:21 +00:00
|
|
|
case QSE_AWK_RTX_VALTOSTR_STRPCAT:
|
|
|
|
{
|
|
|
|
qse_size_t n;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2009-03-01 02:44:21 +00:00
|
|
|
/* point to the insertion point */
|
|
|
|
tmp = QSE_STR_PTR(out->u.strpcat) + QSE_STR_LEN(out->u.strpcat);
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2009-03-01 02:44:21 +00:00
|
|
|
/* extend the buffer */
|
|
|
|
n = qse_str_nccat (out->u.strpcat, QSE_T(' '), rlen);
|
|
|
|
if (n == (qse_size_t)-1)
|
|
|
|
{
|
2009-08-17 02:08:58 +00:00
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
2011-05-26 08:00:19 +00:00
|
|
|
return -1;
|
2009-03-01 02:44:21 +00:00
|
|
|
}
|
|
|
|
break;
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
2011-05-26 08:42:26 +00:00
|
|
|
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINVAL, QSE_NULL);
|
|
|
|
return -1;
|
|
|
|
}
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
2012-08-27 15:10:57 +00:00
|
|
|
if (v->val == 0) tmp[0] = QSE_T('0');
|
2011-05-26 08:00:19 +00:00
|
|
|
else
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2012-08-27 15:10:57 +00:00
|
|
|
t = (v->val < 0)? (v->val * -1): v->val;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2011-05-26 08:00:19 +00:00
|
|
|
/* fill in the buffer with digits */
|
|
|
|
while (t > 0)
|
|
|
|
{
|
|
|
|
tmp[--rlen] = (qse_char_t)(t % 10) + QSE_T('0');
|
|
|
|
t /= 10;
|
|
|
|
}
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2011-05-26 08:00:19 +00:00
|
|
|
/* insert the negative sign if necessary */
|
|
|
|
if (v->val < 0) tmp[--rlen] = QSE_T('-');
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
2011-05-26 08:00:19 +00:00
|
|
|
return 0;
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
2011-11-22 05:03:31 +00:00
|
|
|
static int val_flt_to_str (
|
|
|
|
qse_awk_rtx_t* rtx, const qse_awk_val_flt_t* v,
|
2009-03-01 02:44:21 +00:00
|
|
|
qse_awk_rtx_valtostr_out_t* out)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_char_t* tmp;
|
|
|
|
qse_size_t tmp_len;
|
2009-03-01 02:44:21 +00:00
|
|
|
qse_str_t buf, fbu;
|
2011-05-26 08:00:19 +00:00
|
|
|
int buf_inited = 0, fbu_inited = 0;
|
2009-03-01 02:44:21 +00:00
|
|
|
int type = out->type & ~QSE_AWK_RTX_VALTOSTR_PRINT;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2009-03-01 02:44:21 +00:00
|
|
|
if (out->type & QSE_AWK_RTX_VALTOSTR_PRINT)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2009-03-01 02:44:21 +00:00
|
|
|
tmp = rtx->gbl.ofmt.ptr;
|
|
|
|
tmp_len = rtx->gbl.ofmt.len;
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-03-01 02:44:21 +00:00
|
|
|
tmp = rtx->gbl.convfmt.ptr;
|
|
|
|
tmp_len = rtx->gbl.convfmt.len;
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
2011-09-01 09:43:46 +00:00
|
|
|
if (qse_str_init (&buf, rtx->awk->mmgr, 256) <= -1)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2009-08-17 02:08:58 +00:00
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
2011-05-26 08:00:19 +00:00
|
|
|
return -1;
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
2011-05-26 08:00:19 +00:00
|
|
|
buf_inited = 1;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2011-09-01 09:43:46 +00:00
|
|
|
if (qse_str_init (&fbu, rtx->awk->mmgr, 256) <= -1)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2009-03-01 02:44:21 +00:00
|
|
|
qse_str_fini (&buf);
|
2009-08-17 02:08:58 +00:00
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
2011-05-26 08:00:19 +00:00
|
|
|
return -1;
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
2011-05-26 08:00:19 +00:00
|
|
|
fbu_inited = 1;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2009-03-01 02:44:21 +00:00
|
|
|
tmp = qse_awk_rtx_format (rtx, &buf, &fbu, tmp, tmp_len,
|
2008-12-21 21:35:07 +00:00
|
|
|
(qse_size_t)-1, (qse_awk_nde_t*)v, &tmp_len);
|
2011-05-26 08:00:19 +00:00
|
|
|
if (tmp == QSE_NULL) goto oops;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2009-03-01 02:44:21 +00:00
|
|
|
switch (type)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2009-03-01 02:44:21 +00:00
|
|
|
case QSE_AWK_RTX_VALTOSTR_CPL:
|
2011-11-22 05:03:31 +00:00
|
|
|
/* CPL and CPLCP behave the same for flt_t.
|
2011-05-26 08:00:19 +00:00
|
|
|
* i just fall through assuming that cplcpy
|
2011-05-25 09:14:58 +00:00
|
|
|
* and cpl are the same type. the following
|
|
|
|
* assertion at least ensure that they have
|
|
|
|
* the same size. */
|
2011-05-26 08:00:19 +00:00
|
|
|
QSE_ASSERT (QSE_SIZEOF(out->u.cpl) == QSE_SIZEOF(out->u.cplcpy));
|
2011-05-25 09:14:58 +00:00
|
|
|
|
2011-05-26 08:00:19 +00:00
|
|
|
case QSE_AWK_RTX_VALTOSTR_CPLCPY:
|
|
|
|
if (out->u.cplcpy.len <= tmp_len)
|
2009-03-01 02:44:21 +00:00
|
|
|
{
|
2009-08-17 02:08:58 +00:00
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINVAL, QSE_NULL);
|
2009-03-01 02:44:21 +00:00
|
|
|
/* store the buffer size required */
|
2011-05-26 08:00:19 +00:00
|
|
|
out->u.cplcpy.len = tmp_len + 1;
|
|
|
|
goto oops;
|
2009-03-01 02:44:21 +00:00
|
|
|
}
|
2008-09-05 04:58:08 +00:00
|
|
|
|
2011-05-26 08:00:19 +00:00
|
|
|
qse_strncpy (out->u.cplcpy.ptr, tmp, tmp_len);
|
|
|
|
out->u.cplcpy.len = tmp_len;
|
|
|
|
break;
|
2008-01-16 21:46:08 +00:00
|
|
|
|
2009-03-01 02:44:21 +00:00
|
|
|
case QSE_AWK_RTX_VALTOSTR_CPLDUP:
|
2011-05-26 08:00:19 +00:00
|
|
|
{
|
2009-03-01 02:44:21 +00:00
|
|
|
qse_str_yield (&buf, QSE_NULL, 0);
|
|
|
|
out->u.cpldup.ptr = tmp;
|
|
|
|
out->u.cpldup.len = tmp_len;
|
2011-05-26 08:00:19 +00:00
|
|
|
break;
|
|
|
|
}
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2009-03-01 02:44:21 +00:00
|
|
|
case QSE_AWK_RTX_VALTOSTR_STRP:
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2009-03-01 02:44:21 +00:00
|
|
|
qse_size_t n;
|
|
|
|
|
|
|
|
qse_str_clear (out->u.strp);
|
|
|
|
|
|
|
|
n = qse_str_ncat (out->u.strp, tmp, tmp_len);
|
|
|
|
if (n == (qse_size_t)-1)
|
|
|
|
{
|
2009-08-17 02:08:58 +00:00
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
2011-05-26 08:00:19 +00:00
|
|
|
goto oops;
|
2009-03-01 02:44:21 +00:00
|
|
|
}
|
2011-05-26 08:00:19 +00:00
|
|
|
break;
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
2009-03-01 02:44:21 +00:00
|
|
|
case QSE_AWK_RTX_VALTOSTR_STRPCAT:
|
|
|
|
{
|
|
|
|
qse_size_t n;
|
|
|
|
|
|
|
|
n = qse_str_ncat (out->u.strpcat, tmp, tmp_len);
|
|
|
|
if (n == (qse_size_t)-1)
|
|
|
|
{
|
2009-08-17 02:08:58 +00:00
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
2011-05-26 08:00:19 +00:00
|
|
|
goto oops;
|
2009-03-01 02:44:21 +00:00
|
|
|
}
|
2011-05-26 08:00:19 +00:00
|
|
|
break;
|
|
|
|
}
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2011-05-26 08:00:19 +00:00
|
|
|
default:
|
|
|
|
{
|
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EINVAL, QSE_NULL);
|
|
|
|
goto oops;
|
2009-03-01 02:44:21 +00:00
|
|
|
}
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
2009-03-01 02:44:21 +00:00
|
|
|
qse_str_fini (&fbu);
|
|
|
|
qse_str_fini (&buf);
|
2011-05-26 08:00:19 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
oops:
|
|
|
|
if (fbu_inited) qse_str_fini (&fbu);
|
|
|
|
if (buf_inited) qse_str_fini (&buf);
|
|
|
|
return -1;
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
2011-05-26 08:00:19 +00:00
|
|
|
int qse_awk_rtx_valtostr (
|
2011-05-25 09:14:58 +00:00
|
|
|
qse_awk_rtx_t* rtx, const qse_awk_val_t* v,
|
|
|
|
qse_awk_rtx_valtostr_out_t* out)
|
2009-02-28 20:18:00 +00:00
|
|
|
{
|
|
|
|
switch (v->type)
|
|
|
|
{
|
|
|
|
case QSE_AWK_VAL_NIL:
|
2011-05-25 09:14:58 +00:00
|
|
|
{
|
2009-03-01 02:44:21 +00:00
|
|
|
return str_to_str (rtx, QSE_T(""), 0, out);
|
2011-05-25 09:14:58 +00:00
|
|
|
}
|
2009-02-28 20:18:00 +00:00
|
|
|
|
|
|
|
case QSE_AWK_VAL_INT:
|
2011-05-25 09:14:58 +00:00
|
|
|
{
|
2009-02-28 20:18:00 +00:00
|
|
|
return val_int_to_str (
|
2009-03-01 02:44:21 +00:00
|
|
|
rtx, (qse_awk_val_int_t*)v, out);
|
2011-05-25 09:14:58 +00:00
|
|
|
}
|
2009-02-28 20:18:00 +00:00
|
|
|
|
2011-11-22 05:03:31 +00:00
|
|
|
case QSE_AWK_VAL_FLT:
|
2011-05-25 09:14:58 +00:00
|
|
|
{
|
2011-11-22 05:03:31 +00:00
|
|
|
return val_flt_to_str (
|
|
|
|
rtx, (qse_awk_val_flt_t*)v, out);
|
2011-05-25 09:14:58 +00:00
|
|
|
}
|
2009-02-28 20:18:00 +00:00
|
|
|
|
|
|
|
case QSE_AWK_VAL_STR:
|
|
|
|
{
|
|
|
|
qse_awk_val_str_t* vs = (qse_awk_val_str_t*)v;
|
2011-05-19 08:36:40 +00:00
|
|
|
return str_to_str (rtx, vs->val.ptr, vs->val.len, out);
|
2009-02-28 20:18:00 +00:00
|
|
|
}
|
2012-11-28 05:34:19 +00:00
|
|
|
|
|
|
|
case QSE_AWK_VAL_MAP:
|
|
|
|
{
|
|
|
|
if (rtx->awk->opt.trait & QSE_AWK_FLEXMAP)
|
|
|
|
return str_to_str (rtx, QSE_T("#MAP"), 4, out);
|
|
|
|
break;
|
|
|
|
}
|
2011-05-26 08:42:26 +00:00
|
|
|
}
|
2011-05-26 08:50:19 +00:00
|
|
|
|
|
|
|
#ifdef DEBUG_VAL
|
|
|
|
qse_dprintf (
|
|
|
|
QSE_T(">>WRONG VALUE TYPE [%d] in qse_awk_rtx_valtostr\n"),
|
|
|
|
v->type
|
|
|
|
);
|
|
|
|
#endif
|
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EVALTYPE, QSE_NULL);
|
|
|
|
return -1;
|
2009-02-28 20:18:00 +00:00
|
|
|
}
|
|
|
|
|
2012-10-31 08:31:58 +00:00
|
|
|
qse_char_t* qse_awk_rtx_valtostrdup (
|
|
|
|
qse_awk_rtx_t* rtx, const qse_awk_val_t* v, qse_size_t* len)
|
|
|
|
{
|
|
|
|
qse_awk_rtx_valtostr_out_t out;
|
|
|
|
|
|
|
|
out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP;
|
|
|
|
if (qse_awk_rtx_valtostr (rtx, v, &out) <= -1) return QSE_NULL;
|
|
|
|
|
|
|
|
if (len) *len = out.u.cpldup.len;
|
|
|
|
return out.u.cpldup.ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
qse_mchar_t* qse_awk_rtx_valtombsdup (
|
|
|
|
qse_awk_rtx_t* rtx, const qse_awk_val_t* v, qse_size_t* len)
|
|
|
|
{
|
|
|
|
#if defined(QSE_CHAR_IS_MCHAR)
|
|
|
|
qse_awk_rtx_valtostr_out_t out;
|
|
|
|
|
|
|
|
out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP;
|
|
|
|
if (qse_awk_rtx_valtostr (rtx, v, &out) <= -1) return QSE_NULL;
|
|
|
|
|
|
|
|
if (len) *len = out.u.cpldup.len;
|
|
|
|
return out.u.cpldup.ptr;
|
|
|
|
#else
|
|
|
|
qse_awk_rtx_valtostr_out_t out;
|
|
|
|
qse_mchar_t* mbs;
|
|
|
|
|
|
|
|
out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP;
|
|
|
|
if (qse_awk_rtx_valtostr (rtx, v, &out) <= -1) return QSE_NULL;
|
|
|
|
|
|
|
|
mbs = qse_wcsntombsdup (out.u.cpldup.ptr, out.u.cpldup.len, len, rtx->awk->mmgr);
|
|
|
|
QSE_AWK_FREE (rtx->awk, out.u.cpldup.ptr);
|
|
|
|
return mbs;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
qse_wchar_t* qse_awk_rtx_valtowcsdup (
|
2011-05-25 09:14:58 +00:00
|
|
|
qse_awk_rtx_t* rtx, const qse_awk_val_t* v, qse_size_t* len)
|
2009-03-01 09:27:03 +00:00
|
|
|
{
|
2012-10-31 08:31:58 +00:00
|
|
|
#if defined(QSE_CHAR_IS_MCHAR)
|
2009-03-01 09:27:03 +00:00
|
|
|
qse_awk_rtx_valtostr_out_t out;
|
2012-10-31 08:31:58 +00:00
|
|
|
qse_wchar_t* wcs;
|
2009-03-01 09:27:03 +00:00
|
|
|
|
|
|
|
out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP;
|
2011-05-26 08:00:19 +00:00
|
|
|
if (qse_awk_rtx_valtostr (rtx, v, &out) <= -1) return QSE_NULL;
|
2009-03-01 09:27:03 +00:00
|
|
|
|
2012-11-16 17:11:18 +00:00
|
|
|
wcs = qse_mbsntowcsdup (out.u.cpldup.ptr, out.u.cpldup.len, len, rtx->awk->mmgr);
|
2012-10-31 08:31:58 +00:00
|
|
|
QSE_AWK_FREE (rtx->awk, out.u.cpldup.ptr);
|
|
|
|
return wcs;
|
|
|
|
#else
|
|
|
|
qse_awk_rtx_valtostr_out_t out;
|
|
|
|
|
|
|
|
out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP;
|
|
|
|
if (qse_awk_rtx_valtostr (rtx, v, &out) <= -1) return QSE_NULL;
|
|
|
|
|
|
|
|
if (len) *len = out.u.cpldup.len;
|
2009-03-01 09:27:03 +00:00
|
|
|
return out.u.cpldup.ptr;
|
2012-10-31 08:31:58 +00:00
|
|
|
#endif
|
2009-03-01 09:27:03 +00:00
|
|
|
}
|
|
|
|
|
2009-02-01 03:59:46 +00:00
|
|
|
int qse_awk_rtx_valtonum (
|
2011-11-22 05:03:31 +00:00
|
|
|
qse_awk_rtx_t* rtx, const qse_awk_val_t* v, qse_long_t* l, qse_flt_t* r)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2011-05-26 08:42:26 +00:00
|
|
|
switch (v->type)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2011-05-26 08:42:26 +00:00
|
|
|
case QSE_AWK_VAL_NIL:
|
|
|
|
{
|
|
|
|
*l = 0;
|
|
|
|
return 0;
|
|
|
|
}
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2011-05-26 08:42:26 +00:00
|
|
|
case QSE_AWK_VAL_INT:
|
|
|
|
{
|
|
|
|
*l = ((qse_awk_val_int_t*)v)->val;
|
|
|
|
return 0; /* long */
|
|
|
|
}
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2011-11-22 05:03:31 +00:00
|
|
|
case QSE_AWK_VAL_FLT:
|
2011-05-26 08:42:26 +00:00
|
|
|
{
|
2011-11-22 05:03:31 +00:00
|
|
|
*r = ((qse_awk_val_flt_t*)v)->val;
|
2011-05-26 08:42:26 +00:00
|
|
|
return 1; /* real */
|
|
|
|
}
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2011-05-26 08:42:26 +00:00
|
|
|
case QSE_AWK_VAL_STR:
|
|
|
|
{
|
|
|
|
return qse_awk_rtx_strtonum (
|
|
|
|
rtx, 0,
|
|
|
|
((qse_awk_val_str_t*)v)->val.ptr,
|
|
|
|
((qse_awk_val_str_t*)v)->val.len,
|
|
|
|
l, r
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2011-05-26 08:50:19 +00:00
|
|
|
#ifdef DEBUG_VAL
|
|
|
|
qse_dprintf (
|
2012-09-10 09:55:22 +00:00
|
|
|
QSE_T(">>WRONG VALUE TYPE [%d] in qse_awk_rtx_valtonum()\n"),
|
2011-05-26 08:50:19 +00:00
|
|
|
v->type
|
|
|
|
);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EVALTYPE, QSE_NULL);
|
|
|
|
return -1; /* error */
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
2011-07-25 08:24:13 +00:00
|
|
|
int qse_awk_rtx_valtolong (
|
|
|
|
qse_awk_rtx_t* rtx, const qse_awk_val_t* v, qse_long_t* l)
|
|
|
|
{
|
|
|
|
int n;
|
2011-11-22 05:03:31 +00:00
|
|
|
qse_flt_t r;
|
2011-07-25 08:24:13 +00:00
|
|
|
|
|
|
|
n = qse_awk_rtx_valtonum (rtx, v, l, &r);
|
|
|
|
if (n == 1)
|
|
|
|
{
|
|
|
|
*l = (qse_long_t)r;
|
|
|
|
n = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2011-11-22 05:03:31 +00:00
|
|
|
int qse_awk_rtx_valtoflt (
|
|
|
|
qse_awk_rtx_t* rtx, const qse_awk_val_t* v, qse_flt_t* r)
|
2011-07-25 08:24:13 +00:00
|
|
|
{
|
|
|
|
int n;
|
|
|
|
qse_long_t l;
|
|
|
|
|
|
|
|
n = qse_awk_rtx_valtonum (rtx, v, &l, r);
|
2011-11-22 05:03:31 +00:00
|
|
|
if (n == 0) *r = (qse_flt_t)l;
|
2011-07-25 08:24:13 +00:00
|
|
|
else if (n == 1) n = 0;
|
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2009-02-01 03:59:46 +00:00
|
|
|
int qse_awk_rtx_strtonum (
|
2009-06-12 20:59:59 +00:00
|
|
|
qse_awk_rtx_t* rtx, int strict,
|
|
|
|
const qse_char_t* ptr, qse_size_t len,
|
2011-11-22 05:03:31 +00:00
|
|
|
qse_long_t* l, qse_flt_t* r)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
const qse_char_t* endptr;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2009-06-12 20:59:59 +00:00
|
|
|
*l = qse_awk_strxtolong (rtx->awk, ptr, len, 0, &endptr);
|
|
|
|
if (endptr < ptr + len &&
|
|
|
|
(*endptr == QSE_T('.') ||
|
|
|
|
*endptr == QSE_T('E') ||
|
|
|
|
*endptr == QSE_T('e')))
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2011-11-22 05:03:31 +00:00
|
|
|
*r = qse_awk_strxtoflt (rtx->awk, ptr, len, &endptr);
|
2009-06-12 20:59:59 +00:00
|
|
|
if (strict && endptr < ptr + len) return -1;
|
2007-05-02 01:07:00 +00:00
|
|
|
return 1; /* real */
|
|
|
|
}
|
2007-05-11 10:07:00 +00:00
|
|
|
|
2009-06-12 20:59:59 +00:00
|
|
|
if (strict && endptr < ptr + len) return -1;
|
2007-05-02 01:07:00 +00:00
|
|
|
return 0; /* long */
|
|
|
|
}
|
|
|
|
|
2012-09-10 09:55:22 +00:00
|
|
|
static qse_ulong_t hash (qse_uint8_t* ptr, qse_size_t len)
|
|
|
|
{
|
|
|
|
qse_ulong_t h = 5381;
|
|
|
|
while (len > 0) h = ((h << 5) + h) + ptr[--len];
|
|
|
|
return h;
|
|
|
|
}
|
|
|
|
|
|
|
|
qse_long_t qse_awk_rtx_hashval (qse_awk_rtx_t* rtx, qse_awk_val_t* v)
|
|
|
|
{
|
|
|
|
qse_long_t hv;
|
|
|
|
|
|
|
|
switch (v->type)
|
|
|
|
{
|
|
|
|
case QSE_AWK_VAL_NIL:
|
|
|
|
hv = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QSE_AWK_VAL_INT:
|
|
|
|
/*hv = ((qse_awk_val_int_t*)v)->val;*/
|
2012-10-15 09:36:39 +00:00
|
|
|
hv = (qse_long_t)hash (
|
|
|
|
(qse_uint8_t*)&((qse_awk_val_int_t*)v)->val,
|
|
|
|
QSE_SIZEOF(((qse_awk_val_int_t*)v)->val));
|
2012-09-10 09:55:22 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case QSE_AWK_VAL_FLT:
|
2012-10-15 09:36:39 +00:00
|
|
|
hv = (qse_long_t)hash (
|
|
|
|
(qse_uint8_t*)&((qse_awk_val_flt_t*)v)->val,
|
|
|
|
QSE_SIZEOF(((qse_awk_val_flt_t*)v)->val));
|
2012-09-10 09:55:22 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case QSE_AWK_VAL_STR:
|
2012-10-15 09:36:39 +00:00
|
|
|
hv = (qse_long_t)hash (
|
|
|
|
(qse_uint8_t*)((qse_awk_val_str_t*)v)->val.ptr,
|
|
|
|
((qse_awk_val_str_t*)v)->val.len * QSE_SIZEOF(qse_char_t));
|
2012-09-10 09:55:22 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
#ifdef DEBUG_VAL
|
|
|
|
qse_dprintf (
|
|
|
|
QSE_T(">>WRONG VALUE TYPE [%d] in qse_awk_rtx_hashval()\n"),
|
|
|
|
v->type
|
|
|
|
);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EVALTYPE, QSE_NULL);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2012-09-11 16:19:52 +00:00
|
|
|
/* turn off the sign bit */
|
2012-09-10 09:55:22 +00:00
|
|
|
return hv & ~(((qse_ulong_t)1) << ((QSE_SIZEOF(qse_ulong_t) * 8) - 1));
|
|
|
|
}
|
|
|
|
|
2008-12-11 04:19:59 +00:00
|
|
|
#if 0
|
|
|
|
|
2008-07-21 06:42:39 +00:00
|
|
|
#define DPRINTF run->awk->prmfns->dprintf
|
2008-08-19 05:21:48 +00:00
|
|
|
#define DCUSTOM run->awk->prmfns->data
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2010-07-09 00:58:44 +00:00
|
|
|
static qse_htb_walk_t print_pair (
|
|
|
|
qse_htb_t* map, qse_htb_pair_t* pair, void* arg)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2009-01-31 04:31:40 +00:00
|
|
|
qse_awk_rtx_t* run = (qse_awk_rtx_t*)arg;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2009-02-17 02:11:31 +00:00
|
|
|
QSE_ASSERT (run == *(qse_awk_rtx_t**)QSE_XTN(map));
|
2008-09-25 02:00:50 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
DPRINTF (DCUSTOM, QSE_T(" %.*s=>"),
|
2010-07-09 00:58:44 +00:00
|
|
|
(int)QSE_HTB_KLEN(pair), QSE_HTB_KPTR(pair));
|
|
|
|
qse_awk_dprintval ((qse_awk_rtx_t*)arg, QSE_HTB_VPTR(pair));
|
2008-12-21 21:35:07 +00:00
|
|
|
DPRINTF (DCUSTOM, QSE_T(" "));
|
2008-03-23 06:09:35 +00:00
|
|
|
|
2010-07-09 00:58:44 +00:00
|
|
|
return QSE_HTB_WALK_FORWARD;
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
2009-01-31 04:31:40 +00:00
|
|
|
void qse_awk_dprintval (qse_awk_rtx_t* run, qse_awk_val_t* val)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
|
|
|
/* TODO: better value printing ... */
|
|
|
|
|
|
|
|
switch (val->type)
|
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
case QSE_AWK_VAL_NIL:
|
|
|
|
DPRINTF (DCUSTOM, QSE_T("nil"));
|
2007-05-02 01:07:00 +00:00
|
|
|
break;
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
case QSE_AWK_VAL_INT:
|
|
|
|
#if QSE_SIZEOF_LONG_LONG > 0
|
|
|
|
DPRINTF (DCUSTOM, QSE_T("%lld"),
|
|
|
|
(long long)((qse_awk_val_int_t*)val)->val);
|
|
|
|
#elif QSE_SIZEOF___INT64 > 0
|
|
|
|
DPRINTF (DCUSTOM, QSE_T("%I64d"),
|
|
|
|
(__int64)((qse_awk_val_int_t*)val)->val);
|
|
|
|
#elif QSE_SIZEOF_LONG > 0
|
|
|
|
DPRINTF (DCUSTOM, QSE_T("%ld"),
|
|
|
|
(long)((qse_awk_val_int_t*)val)->val);
|
|
|
|
#elif QSE_SIZEOF_INT > 0
|
|
|
|
DPRINTF (DCUSTOM, QSE_T("%d"),
|
|
|
|
(int)((qse_awk_val_int_t*)val)->val);
|
2007-05-02 01:07:00 +00:00
|
|
|
#else
|
|
|
|
#error unsupported size
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
|
2011-11-22 05:03:31 +00:00
|
|
|
case QSE_AWK_VAL_FLT:
|
2008-12-10 03:50:40 +00:00
|
|
|
#if defined(__MINGW32__)
|
2008-12-21 21:35:07 +00:00
|
|
|
DPRINTF (DCUSTOM, QSE_T("%Lf"),
|
2011-11-22 05:03:31 +00:00
|
|
|
(double)((qse_awk_val_flt_t*)val)->val);
|
2008-12-10 03:50:40 +00:00
|
|
|
#else
|
2008-12-21 21:35:07 +00:00
|
|
|
DPRINTF (DCUSTOM, QSE_T("%Lf"),
|
2011-11-22 05:03:31 +00:00
|
|
|
(long double)((qse_awk_val_flt_t*)val)->val);
|
2008-12-10 03:50:40 +00:00
|
|
|
#endif
|
2007-05-02 01:07:00 +00:00
|
|
|
break;
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
case QSE_AWK_VAL_STR:
|
2008-12-30 04:49:25 +00:00
|
|
|
DPRINTF (DCUSTOM, QSE_T("%s"), ((qse_awk_val_str_t*)val)->ptr);
|
2007-05-02 01:07:00 +00:00
|
|
|
break;
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
case QSE_AWK_VAL_REX:
|
2008-12-30 04:49:25 +00:00
|
|
|
DPRINTF (DCUSTOM, QSE_T("REX[%s]"), ((qse_awk_val_rex_t*)val)->ptr);
|
2007-05-02 01:07:00 +00:00
|
|
|
break;
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
case QSE_AWK_VAL_MAP:
|
|
|
|
DPRINTF (DCUSTOM, QSE_T("MAP["));
|
2010-07-09 00:58:44 +00:00
|
|
|
qse_htb_walk (((qse_awk_val_map_t*)val)->map, print_pair, run);
|
2008-12-21 21:35:07 +00:00
|
|
|
DPRINTF (DCUSTOM, QSE_T("]"));
|
2007-05-02 01:07:00 +00:00
|
|
|
break;
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
case QSE_AWK_VAL_REF:
|
|
|
|
DPRINTF (DCUSTOM, QSE_T("REF[id=%d,val="), ((qse_awk_val_ref_t*)val)->id);
|
|
|
|
qse_awk_dprintval (run, *((qse_awk_val_ref_t*)val)->adr);
|
|
|
|
DPRINTF (DCUSTOM, QSE_T("]"));
|
2007-05-02 01:07:00 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2008-12-21 21:35:07 +00:00
|
|
|
DPRINTF (DCUSTOM, QSE_T("**** INTERNAL ERROR - INVALID VALUE TYPE ****\n"));
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
}
|
2008-03-23 00:47:27 +00:00
|
|
|
|
2008-12-11 04:19:59 +00:00
|
|
|
#endif
|