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
|
|
|
*
|
2019-06-06 05:28:23 +00:00
|
|
|
Copyright (c) 2006-2019 Chung, Hyung-Hwan. All rights reserved.
|
2008-12-27 04:35:14 +00:00
|
|
|
|
2014-11-19 14:42:24 +00:00
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
|
|
modification, are permitted provided that the following conditions
|
|
|
|
are met:
|
|
|
|
1. Redistributions of source code must retain the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer in the
|
|
|
|
documentation and/or other materials provided with the distribution.
|
2008-12-27 04:35:14 +00:00
|
|
|
|
2014-11-19 14:42:24 +00:00
|
|
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
|
|
|
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
|
|
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
|
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
|
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
2007-05-02 01:07:00 +00:00
|
|
|
*/
|
|
|
|
|
2016-04-29 03:55:42 +00:00
|
|
|
#include "awk-prv.h"
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2009-01-31 04:31:40 +00:00
|
|
|
static int split_record (qse_awk_rtx_t* run);
|
2008-02-13 01:39:56 +00:00
|
|
|
static int recomp_record_fields (
|
2014-07-08 14:30:42 +00:00
|
|
|
qse_awk_rtx_t* run, qse_size_t lv, const qse_cstr_t* str);
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2009-02-01 03:59:46 +00:00
|
|
|
int qse_awk_rtx_setrec (
|
2014-07-08 14:30:42 +00:00
|
|
|
qse_awk_rtx_t* run, qse_size_t idx, const qse_cstr_t* str)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_awk_val_t* v;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
|
|
|
if (idx == 0)
|
|
|
|
{
|
2012-10-29 14:41:39 +00:00
|
|
|
if (str->ptr == QSE_STR_PTR(&run->inrec.line) &&
|
|
|
|
str->len == QSE_STR_LEN(&run->inrec.line))
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2012-10-22 09:36:15 +00:00
|
|
|
if (qse_awk_rtx_clrrec (run, 1) == -1) return -1;
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-10-22 09:36:15 +00:00
|
|
|
if (qse_awk_rtx_clrrec (run, 0) == -1) return -1;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2012-10-29 14:41:39 +00:00
|
|
|
if (qse_str_ncpy (&run->inrec.line, str->ptr, str->len) == (qse_size_t)-1)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2012-10-22 09:36:15 +00:00
|
|
|
qse_awk_rtx_clrrec (run, 0);
|
2009-08-17 02:08:58 +00:00
|
|
|
qse_awk_rtx_seterrnum (run, QSE_AWK_ENOMEM, QSE_NULL);
|
2007-05-02 01:07:00 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-28 14:01:28 +00:00
|
|
|
v = qse_awk_rtx_makenstrvalwithcstr (run, str);
|
2009-06-15 07:22:00 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
if (v == QSE_NULL)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2012-10-22 09:36:15 +00:00
|
|
|
qse_awk_rtx_clrrec (run, 0);
|
2007-05-02 01:07:00 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2014-10-23 09:30:22 +00:00
|
|
|
QSE_ASSERT (QSE_AWK_RTX_GETVALTYPE (run, run->inrec.d0) == QSE_AWK_VAL_NIL);
|
2007-05-02 01:07:00 +00:00
|
|
|
/* d0 should be cleared before the next line is reached
|
2009-02-01 03:59:46 +00:00
|
|
|
* as it doesn't call qse_awk_rtx_refdownval on run->inrec.d0 */
|
2007-05-02 01:07:00 +00:00
|
|
|
run->inrec.d0 = v;
|
2009-02-01 03:59:46 +00:00
|
|
|
qse_awk_rtx_refupval (run, v);
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2008-02-13 01:39:56 +00:00
|
|
|
if (split_record (run) == -1)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2012-10-22 09:36:15 +00:00
|
|
|
qse_awk_rtx_clrrec (run, 0);
|
2007-05-02 01:07:00 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-10-29 14:41:39 +00:00
|
|
|
if (recomp_record_fields (run, idx, str) <= -1)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2012-10-22 09:36:15 +00:00
|
|
|
qse_awk_rtx_clrrec (run, 0);
|
2007-05-02 01:07:00 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* recompose $0 */
|
2019-08-28 14:01:28 +00:00
|
|
|
v = qse_awk_rtx_makestrvalwithcstr (run, QSE_STR_XSTR(&run->inrec.line));
|
2008-12-21 21:35:07 +00:00
|
|
|
if (v == QSE_NULL)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2012-10-22 09:36:15 +00:00
|
|
|
qse_awk_rtx_clrrec (run, 0);
|
2007-05-02 01:07:00 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2009-02-01 03:59:46 +00:00
|
|
|
qse_awk_rtx_refdownval (run, run->inrec.d0);
|
2007-05-02 01:07:00 +00:00
|
|
|
run->inrec.d0 = v;
|
2009-02-01 03:59:46 +00:00
|
|
|
qse_awk_rtx_refupval (run, v);
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-09-22 07:28:18 +00:00
|
|
|
static int split_record (qse_awk_rtx_t* rtx)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2014-07-08 14:30:42 +00:00
|
|
|
qse_cstr_t tok;
|
2011-05-19 08:36:40 +00:00
|
|
|
qse_char_t* p, * px;
|
|
|
|
qse_size_t len, nflds;
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_awk_val_t* v, * fs;
|
2014-10-22 17:05:45 +00:00
|
|
|
qse_awk_val_type_t fsvtype;
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_char_t* fs_ptr, * fs_free;
|
|
|
|
qse_size_t fs_len;
|
2009-06-02 03:34:34 +00:00
|
|
|
qse_awk_errnum_t errnum;
|
2009-09-22 07:28:18 +00:00
|
|
|
int how;
|
2014-10-22 17:05:45 +00:00
|
|
|
|
|
|
|
|
2008-02-13 01:39:56 +00:00
|
|
|
/* inrec should be cleared before split_record is called */
|
2009-09-22 07:28:18 +00:00
|
|
|
QSE_ASSERT (rtx->inrec.nflds == 0);
|
2007-05-02 01:07:00 +00:00
|
|
|
|
|
|
|
/* get FS */
|
2009-09-22 07:28:18 +00:00
|
|
|
fs = qse_awk_rtx_getgbl (rtx, QSE_AWK_GBL_FS);
|
2014-10-23 09:30:22 +00:00
|
|
|
fsvtype = QSE_AWK_RTX_GETVALTYPE (rtx, fs);
|
2014-10-22 17:05:45 +00:00
|
|
|
if (fsvtype == QSE_AWK_VAL_NIL)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
fs_ptr = QSE_T(" ");
|
2007-05-02 01:07:00 +00:00
|
|
|
fs_len = 1;
|
2008-12-21 21:35:07 +00:00
|
|
|
fs_free = QSE_NULL;
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
2014-10-22 17:05:45 +00:00
|
|
|
else if (fsvtype == QSE_AWK_VAL_STR)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2011-05-19 08:36:40 +00:00
|
|
|
fs_ptr = ((qse_awk_val_str_t*)fs)->val.ptr;
|
|
|
|
fs_len = ((qse_awk_val_str_t*)fs)->val.len;
|
2008-12-21 21:35:07 +00:00
|
|
|
fs_free = QSE_NULL;
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-04-21 05:44:53 +00:00
|
|
|
fs_ptr = qse_awk_rtx_valtostrdup(rtx, fs, &fs_len);
|
2013-08-23 15:19:29 +00:00
|
|
|
if (fs_ptr == QSE_NULL) return -1;
|
2007-05-02 01:07:00 +00:00
|
|
|
fs_free = fs_ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* scan the input record to count the fields */
|
2009-09-22 07:28:18 +00:00
|
|
|
if (fs_len == 5 && fs_ptr[0] == QSE_T('?'))
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2009-09-22 07:28:18 +00:00
|
|
|
if (qse_str_ncpy (
|
|
|
|
&rtx->inrec.linew,
|
|
|
|
QSE_STR_PTR(&rtx->inrec.line),
|
|
|
|
QSE_STR_LEN(&rtx->inrec.line)) == (qse_size_t)-1)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2009-09-22 07:28:18 +00:00
|
|
|
if (fs_free != QSE_NULL)
|
2019-06-07 05:20:20 +00:00
|
|
|
qse_awk_rtx_freemem (rtx, fs_free);
|
2009-09-22 07:28:18 +00:00
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
|
|
|
return -1;
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
2009-09-22 07:28:18 +00:00
|
|
|
|
2009-09-24 04:19:30 +00:00
|
|
|
px = QSE_STR_PTR(&rtx->inrec.linew);
|
2009-09-22 07:28:18 +00:00
|
|
|
how = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-09-24 04:19:30 +00:00
|
|
|
px = QSE_STR_PTR(&rtx->inrec.line);
|
2009-09-22 07:28:18 +00:00
|
|
|
how = (fs_len <= 1)? 0: 2;
|
|
|
|
}
|
|
|
|
|
2009-09-24 04:19:30 +00:00
|
|
|
p = px;
|
|
|
|
len = QSE_STR_LEN(&rtx->inrec.line);
|
|
|
|
|
2009-09-22 07:28:18 +00:00
|
|
|
#if 0
|
|
|
|
nflds = 0;
|
|
|
|
while (p != QSE_NULL)
|
|
|
|
{
|
|
|
|
switch (how)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2009-09-22 07:28:18 +00:00
|
|
|
case 0:
|
|
|
|
p = qse_awk_rtx_strxntok (rtx,
|
2011-05-19 08:36:40 +00:00
|
|
|
p, len, fs_ptr, fs_len, &tok);
|
2009-09-22 07:28:18 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
p = qse_awk_rtx_strxntokbyrex (
|
|
|
|
rtx,
|
|
|
|
QSE_STR_PTR(&rtx->inrec.line),
|
|
|
|
QSE_STR_LEN(&rtx->inrec.line),
|
|
|
|
p, len,
|
2013-08-23 15:19:29 +00:00
|
|
|
rtx->gbl.fs[rtx->gbl.ignorecase], &tok, &errnum
|
2009-09-22 07:28:18 +00:00
|
|
|
);
|
|
|
|
if (p == QSE_NULL && errnum != QSE_AWK_ENOERR)
|
|
|
|
{
|
|
|
|
if (fs_free != QSE_NULL)
|
2019-06-07 05:20:20 +00:00
|
|
|
qse_awk_rtx_freemem (rtx, fs_free);
|
2009-09-22 07:28:18 +00:00
|
|
|
qse_awk_rtx_seterrnum (rtx, errnum, QSE_NULL);
|
|
|
|
return -1;
|
|
|
|
}
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
2011-05-19 08:36:40 +00:00
|
|
|
if (nflds == 0 && p == QSE_NULL && tok.len == 0)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
|
|
|
/* there are no fields. it can just return here
|
2009-02-01 03:59:46 +00:00
|
|
|
* as qse_awk_rtx_clrrec has been called before this */
|
2019-06-07 05:20:20 +00:00
|
|
|
if (fs_free) qse_awk_rtx_freemem (rtx, fs_free);
|
2007-05-02 01:07:00 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-05-19 08:36:40 +00:00
|
|
|
QSE_ASSERT ((tok.ptr != QSE_NULL && tok.len > 0) || tok.len == 0);
|
2007-05-02 01:07:00 +00:00
|
|
|
|
|
|
|
nflds++;
|
2019-06-07 05:20:20 +00:00
|
|
|
len = QSE_STR_LEN(&rtx->inrec.line) - (p - QSE_STR_PTR(&rtx->inrec.line));
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* allocate space */
|
2009-09-22 07:28:18 +00:00
|
|
|
if (nflds > rtx->inrec.maxflds)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2019-06-07 05:20:20 +00:00
|
|
|
void* tmp = qse_awk_rtx_allocmem(rtx, QSE_SIZEOF(*rtx->inrec.flds) * nflds);
|
|
|
|
if (!tmp)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2019-06-07 05:20:20 +00:00
|
|
|
if (fs_free) qse_awk_rtx_freemem (rtx, fs_free);
|
2007-05-02 01:07:00 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-06-07 05:20:20 +00:00
|
|
|
if (rtx->inrec.flds) qse_awk_rtx_freemem (rtx, rtx->inrec.flds);
|
2009-09-22 07:28:18 +00:00
|
|
|
rtx->inrec.flds = tmp;
|
|
|
|
rtx->inrec.maxflds = nflds;
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* scan again and split it */
|
2009-09-22 07:28:18 +00:00
|
|
|
if (how == 1)
|
|
|
|
{
|
|
|
|
if (qse_str_ncpy (
|
|
|
|
&rtx->inrec.linew,
|
|
|
|
QSE_STR_PTR(&rtx->inrec.line),
|
|
|
|
QSE_STR_LEN(&rtx->inrec.line)) == (qse_size_t)-1)
|
|
|
|
{
|
2019-06-07 05:20:20 +00:00
|
|
|
if (fs_free) qse_awk_rtx_freemem (rtx, fs_free);
|
2009-09-22 07:28:18 +00:00
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
|
|
|
return -1;
|
|
|
|
}
|
2009-09-24 04:19:30 +00:00
|
|
|
px = QSE_STR_PTR(&rtx->inrec.linew):
|
2009-09-22 07:28:18 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-09-24 04:19:30 +00:00
|
|
|
px = QSE_STR_PTR(&rtx->inrec.line);
|
2009-09-22 07:28:18 +00:00
|
|
|
}
|
2009-09-24 04:19:30 +00:00
|
|
|
|
|
|
|
p = px;
|
2009-09-22 07:28:18 +00:00
|
|
|
len = QSE_STR_LEN(&rtx->inrec.line);
|
|
|
|
#endif
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
while (p != QSE_NULL)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2009-09-22 07:28:18 +00:00
|
|
|
switch (how)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2009-09-22 07:28:18 +00:00
|
|
|
case 0:
|
2019-02-04 12:20:16 +00:00
|
|
|
/* 1 character FS */
|
2009-09-22 07:28:18 +00:00
|
|
|
p = qse_awk_rtx_strxntok (
|
2011-05-19 08:36:40 +00:00
|
|
|
rtx, p, len, fs_ptr, fs_len, &tok);
|
2009-09-22 07:28:18 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 1:
|
2019-02-04 12:20:16 +00:00
|
|
|
/* 5 character FS beginning with ? */
|
2009-09-22 07:28:18 +00:00
|
|
|
p = qse_awk_rtx_strxnfld (
|
|
|
|
rtx, p, len,
|
|
|
|
fs_ptr[1], fs_ptr[2],
|
2011-05-19 08:36:40 +00:00
|
|
|
fs_ptr[3], fs_ptr[4], &tok);
|
2009-09-22 07:28:18 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2019-02-04 12:20:16 +00:00
|
|
|
/* all other cases */
|
2009-09-22 07:28:18 +00:00
|
|
|
p = qse_awk_rtx_strxntokbyrex (
|
|
|
|
rtx,
|
|
|
|
QSE_STR_PTR(&rtx->inrec.line),
|
|
|
|
QSE_STR_LEN(&rtx->inrec.line),
|
|
|
|
p, len,
|
2013-08-23 15:19:29 +00:00
|
|
|
rtx->gbl.fs[rtx->gbl.ignorecase], &tok, &errnum
|
2009-09-22 07:28:18 +00:00
|
|
|
);
|
|
|
|
if (p == QSE_NULL && errnum != QSE_AWK_ENOERR)
|
|
|
|
{
|
|
|
|
if (fs_free != QSE_NULL)
|
2019-06-07 05:20:20 +00:00
|
|
|
qse_awk_rtx_freemem (rtx, fs_free);
|
2009-09-22 07:28:18 +00:00
|
|
|
qse_awk_rtx_seterrnum (rtx, errnum, QSE_NULL);
|
|
|
|
return -1;
|
|
|
|
}
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
2009-09-22 07:28:18 +00:00
|
|
|
|
|
|
|
#if 1
|
2011-05-19 08:36:40 +00:00
|
|
|
if (rtx->inrec.nflds == 0 && p == QSE_NULL && tok.len == 0)
|
2009-09-22 07:28:18 +00:00
|
|
|
{
|
|
|
|
/* there are no fields. it can just return here
|
|
|
|
* as qse_awk_rtx_clrrec has been called before this */
|
2019-06-07 05:20:20 +00:00
|
|
|
if (fs_free) qse_awk_rtx_freemem (rtx, fs_free);
|
2009-09-22 07:28:18 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2011-05-19 08:36:40 +00:00
|
|
|
QSE_ASSERT ((tok.ptr != QSE_NULL && tok.len > 0) || tok.len == 0);
|
2009-09-22 07:28:18 +00:00
|
|
|
|
|
|
|
#if 1
|
|
|
|
if (rtx->inrec.nflds >= rtx->inrec.maxflds)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2010-11-04 08:24:29 +00:00
|
|
|
void* tmp;
|
|
|
|
|
2009-09-22 07:28:18 +00:00
|
|
|
if (rtx->inrec.nflds < 16) nflds = 32;
|
|
|
|
else nflds = rtx->inrec.nflds * 2;
|
|
|
|
|
2019-06-07 05:20:20 +00:00
|
|
|
tmp = qse_awk_rtx_allocmem(rtx, QSE_SIZEOF(*rtx->inrec.flds) * nflds);
|
2009-09-22 07:28:18 +00:00
|
|
|
if (tmp == QSE_NULL)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2019-06-07 05:20:20 +00:00
|
|
|
if (fs_free) qse_awk_rtx_freemem (rtx, fs_free);
|
2007-05-02 01:07:00 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2009-09-22 07:28:18 +00:00
|
|
|
if (rtx->inrec.flds != QSE_NULL)
|
|
|
|
{
|
2019-06-07 05:20:20 +00:00
|
|
|
QSE_MEMCPY (tmp, rtx->inrec.flds, QSE_SIZEOF(*rtx->inrec.flds) * rtx->inrec.nflds);
|
|
|
|
qse_awk_rtx_freemem (rtx, rtx->inrec.flds);
|
2009-09-22 07:28:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
rtx->inrec.flds = tmp;
|
|
|
|
rtx->inrec.maxflds = nflds;
|
|
|
|
}
|
|
|
|
#endif
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2011-05-19 08:36:40 +00:00
|
|
|
rtx->inrec.flds[rtx->inrec.nflds].ptr = tok.ptr;
|
|
|
|
rtx->inrec.flds[rtx->inrec.nflds].len = tok.len;
|
2019-08-28 14:01:28 +00:00
|
|
|
rtx->inrec.flds[rtx->inrec.nflds].val = qse_awk_rtx_makenstrvalwithcstr (rtx, &tok);
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2009-09-22 07:28:18 +00:00
|
|
|
if (rtx->inrec.flds[rtx->inrec.nflds].val == QSE_NULL)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2019-06-07 05:20:20 +00:00
|
|
|
if (fs_free) qse_awk_rtx_freemem (rtx, fs_free);
|
2007-05-02 01:07:00 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-06-07 05:20:20 +00:00
|
|
|
qse_awk_rtx_refupval (rtx, rtx->inrec.flds[rtx->inrec.nflds].val);
|
2009-09-22 07:28:18 +00:00
|
|
|
rtx->inrec.nflds++;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2009-09-24 04:19:30 +00:00
|
|
|
len = QSE_STR_LEN(&rtx->inrec.line) - (p - px);
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
2019-06-07 05:20:20 +00:00
|
|
|
if (fs_free) qse_awk_rtx_freemem (rtx, fs_free);
|
2007-05-02 01:07:00 +00:00
|
|
|
|
|
|
|
/* set the number of fields */
|
2019-06-07 05:20:20 +00:00
|
|
|
v = qse_awk_rtx_makeintval(rtx, (qse_awk_int_t)rtx->inrec.nflds);
|
2008-12-21 21:35:07 +00:00
|
|
|
if (v == QSE_NULL) return -1;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2009-09-22 07:28:18 +00:00
|
|
|
qse_awk_rtx_refupval (rtx, v);
|
2019-06-07 05:20:20 +00:00
|
|
|
if (qse_awk_rtx_setgbl(rtx, QSE_AWK_GBL_NF, v) == -1)
|
2007-10-30 00:20:00 +00:00
|
|
|
{
|
2009-09-22 07:28:18 +00:00
|
|
|
qse_awk_rtx_refdownval (rtx, v);
|
2007-10-30 00:20:00 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2009-09-22 07:28:18 +00:00
|
|
|
qse_awk_rtx_refdownval (rtx, v);
|
2007-05-02 01:07:00 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-10-22 09:36:15 +00:00
|
|
|
int qse_awk_rtx_clrrec (qse_awk_rtx_t* run, int skip_inrec_line)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_size_t i;
|
2007-05-02 01:07:00 +00:00
|
|
|
int n = 0;
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
if (run->inrec.d0 != qse_awk_val_nil)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2009-02-01 03:59:46 +00:00
|
|
|
qse_awk_rtx_refdownval (run, run->inrec.d0);
|
2008-12-21 21:35:07 +00:00
|
|
|
run->inrec.d0 = qse_awk_val_nil;
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (run->inrec.nflds > 0)
|
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_ASSERT (run->inrec.flds != QSE_NULL);
|
2007-05-02 01:07:00 +00:00
|
|
|
|
|
|
|
for (i = 0; i < run->inrec.nflds; i++)
|
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_ASSERT (run->inrec.flds[i].val != QSE_NULL);
|
2009-02-01 03:59:46 +00:00
|
|
|
qse_awk_rtx_refdownval (run, run->inrec.flds[i].val);
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
run->inrec.nflds = 0;
|
|
|
|
|
2009-02-02 08:28:04 +00:00
|
|
|
if (qse_awk_rtx_setgbl (
|
2018-11-15 06:27:42 +00:00
|
|
|
run, QSE_AWK_GBL_NF, QSE_AWK_VAL_ZERO) == -1)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
|
|
|
/* first of all, this should never happen.
|
|
|
|
* if it happened, it would return an error
|
|
|
|
* after all the clearance tasks */
|
|
|
|
n = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_ASSERT (run->inrec.nflds == 0);
|
|
|
|
if (!skip_inrec_line) qse_str_clear (&run->inrec.line);
|
2007-05-02 01:07:00 +00:00
|
|
|
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
2019-06-07 05:20:20 +00:00
|
|
|
static int recomp_record_fields (qse_awk_rtx_t* run, qse_size_t lv, const qse_cstr_t* str)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_awk_val_t* v;
|
|
|
|
qse_size_t max, i, nflds;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
|
|
|
/* recomposes the record and the fields when $N has been assigned
|
|
|
|
* a new value and recomputes NF accordingly */
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_ASSERT (lv > 0);
|
2007-05-02 01:07:00 +00:00
|
|
|
max = (lv > run->inrec.nflds)? lv: run->inrec.nflds;
|
|
|
|
|
|
|
|
nflds = run->inrec.nflds;
|
|
|
|
if (max > run->inrec.maxflds)
|
|
|
|
{
|
|
|
|
void* tmp;
|
|
|
|
|
|
|
|
/* if the given field number is greater than the maximum
|
|
|
|
* number of fields that the current record can hold,
|
|
|
|
* the field spaces are resized */
|
|
|
|
|
2019-06-07 05:20:20 +00:00
|
|
|
tmp = qse_awk_rtx_reallocmem(run, run->inrec.flds, QSE_SIZEOF(*run->inrec.flds) * max);
|
2019-06-09 05:55:36 +00:00
|
|
|
if (!tmp) return -1;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
|
|
|
run->inrec.flds = tmp;
|
|
|
|
run->inrec.maxflds = max;
|
|
|
|
}
|
|
|
|
|
|
|
|
lv = lv - 1; /* adjust the value to 0-based index */
|
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_str_clear (&run->inrec.line);
|
2007-05-02 01:07:00 +00:00
|
|
|
|
|
|
|
for (i = 0; i < max; i++)
|
|
|
|
{
|
|
|
|
if (i > 0)
|
|
|
|
{
|
2012-10-29 14:41:39 +00:00
|
|
|
if (qse_str_ncat (&run->inrec.line, run->gbl.ofs.ptr, run->gbl.ofs.len) == (qse_size_t)-1)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2009-08-17 02:08:58 +00:00
|
|
|
qse_awk_rtx_seterrnum (run, QSE_AWK_ENOMEM, QSE_NULL);
|
2007-05-02 01:07:00 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i == lv)
|
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_awk_val_t* tmp;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
|
|
|
run->inrec.flds[i].ptr =
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_STR_PTR(&run->inrec.line) +
|
|
|
|
QSE_STR_LEN(&run->inrec.line);
|
2012-10-29 14:41:39 +00:00
|
|
|
run->inrec.flds[i].len = str->len;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2012-10-29 14:41:39 +00:00
|
|
|
if (qse_str_ncat (&run->inrec.line, str->ptr, str->len) == (qse_size_t)-1)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2009-08-17 02:08:58 +00:00
|
|
|
qse_awk_rtx_seterrnum (run, QSE_AWK_ENOMEM, QSE_NULL);
|
2007-05-02 01:07:00 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-08-28 14:01:28 +00:00
|
|
|
tmp = qse_awk_rtx_makestrvalwithcstr (run, str);
|
2008-12-21 21:35:07 +00:00
|
|
|
if (tmp == QSE_NULL) return -1;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
|
|
|
if (i < nflds)
|
2009-02-01 03:59:46 +00:00
|
|
|
qse_awk_rtx_refdownval (run, run->inrec.flds[i].val);
|
2007-05-02 01:07:00 +00:00
|
|
|
else run->inrec.nflds++;
|
|
|
|
|
|
|
|
run->inrec.flds[i].val = tmp;
|
2009-02-01 03:59:46 +00:00
|
|
|
qse_awk_rtx_refupval (run, tmp);
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
else if (i >= nflds)
|
|
|
|
{
|
|
|
|
run->inrec.flds[i].ptr =
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_STR_PTR(&run->inrec.line) +
|
|
|
|
QSE_STR_LEN(&run->inrec.line);
|
2007-05-02 01:07:00 +00:00
|
|
|
run->inrec.flds[i].len = 0;
|
|
|
|
|
2012-10-29 14:41:39 +00:00
|
|
|
if (qse_str_cat (&run->inrec.line, QSE_T("")) == (qse_size_t)-1)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2009-08-17 02:08:58 +00:00
|
|
|
qse_awk_rtx_seterrnum (run, QSE_AWK_ENOMEM, QSE_NULL);
|
2007-05-02 01:07:00 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2009-02-01 03:59:46 +00:00
|
|
|
/* qse_awk_rtx_refdownval should not be called over
|
2007-05-02 01:07:00 +00:00
|
|
|
* run->inrec.flds[i].val as it is not initialized
|
|
|
|
* to any valid values */
|
2009-02-01 03:59:46 +00:00
|
|
|
/*qse_awk_rtx_refdownval (run, run->inrec.flds[i].val);*/
|
2008-12-21 21:35:07 +00:00
|
|
|
run->inrec.flds[i].val = qse_awk_val_zls;
|
2009-02-01 03:59:46 +00:00
|
|
|
qse_awk_rtx_refupval (run, qse_awk_val_zls);
|
2007-05-02 01:07:00 +00:00
|
|
|
run->inrec.nflds++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-12-21 21:35:07 +00:00
|
|
|
qse_awk_val_str_t* tmp;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2008-12-21 21:35:07 +00:00
|
|
|
tmp = (qse_awk_val_str_t*)run->inrec.flds[i].val;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
|
|
|
run->inrec.flds[i].ptr =
|
2008-12-21 21:35:07 +00:00
|
|
|
QSE_STR_PTR(&run->inrec.line) +
|
|
|
|
QSE_STR_LEN(&run->inrec.line);
|
2011-05-19 08:36:40 +00:00
|
|
|
run->inrec.flds[i].len = tmp->val.len;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2011-05-19 08:36:40 +00:00
|
|
|
if (qse_str_ncat (
|
|
|
|
&run->inrec.line,
|
|
|
|
tmp->val.ptr, tmp->val.len) == (qse_size_t)-1)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2009-08-17 02:08:58 +00:00
|
|
|
qse_awk_rtx_seterrnum (run, QSE_AWK_ENOMEM, QSE_NULL);
|
2007-05-02 01:07:00 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-02 08:28:04 +00:00
|
|
|
v = qse_awk_rtx_getgbl (run, QSE_AWK_GBL_NF);
|
2014-10-23 09:30:22 +00:00
|
|
|
QSE_ASSERT (QSE_AWK_RTX_GETVALTYPE (rtx, v) == QSE_AWK_VAL_INT);
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2014-10-23 09:30:22 +00:00
|
|
|
if (QSE_AWK_RTX_GETINTFROMVAL (rtx, v)!= max)
|
2007-05-02 01:07:00 +00:00
|
|
|
{
|
2013-11-05 14:16:45 +00:00
|
|
|
v = qse_awk_rtx_makeintval (run, (qse_awk_int_t)max);
|
2008-12-21 21:35:07 +00:00
|
|
|
if (v == QSE_NULL) return -1;
|
2007-05-02 01:07:00 +00:00
|
|
|
|
2009-02-01 03:59:46 +00:00
|
|
|
qse_awk_rtx_refupval (run, v);
|
2009-02-02 08:28:04 +00:00
|
|
|
if (qse_awk_rtx_setgbl (run, QSE_AWK_GBL_NF, v) == -1)
|
2007-10-30 00:20:00 +00:00
|
|
|
{
|
2009-02-01 03:59:46 +00:00
|
|
|
qse_awk_rtx_refdownval (run, v);
|
2007-10-30 00:20:00 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2009-02-01 03:59:46 +00:00
|
|
|
qse_awk_rtx_refdownval (run, v);
|
2007-05-02 01:07:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-03-07 16:24:02 +00:00
|
|
|
int qse_awk_rtx_truncrec (qse_awk_rtx_t* rtx, qse_size_t nflds)
|
|
|
|
{
|
|
|
|
qse_awk_val_t* v;
|
|
|
|
qse_char_t* ofs_free = QSE_NULL, * ofs_ptr;
|
|
|
|
qse_size_t ofs_len, i;
|
|
|
|
qse_str_t tmp;
|
|
|
|
qse_awk_val_type_t vtype;
|
|
|
|
|
|
|
|
QSE_ASSERT (nflds <= rtx->inrec.nflds);
|
|
|
|
|
|
|
|
if (nflds > 1)
|
|
|
|
{
|
|
|
|
v = RTX_STACK_GBL(rtx, QSE_AWK_GBL_OFS);
|
|
|
|
qse_awk_rtx_refupval (rtx, v);
|
|
|
|
vtype = QSE_AWK_RTX_GETVALTYPE(rtx, v);
|
|
|
|
|
|
|
|
if (vtype == QSE_AWK_VAL_NIL)
|
|
|
|
{
|
|
|
|
/* OFS not set */
|
|
|
|
ofs_ptr = QSE_T(" ");
|
|
|
|
ofs_len = 1;
|
|
|
|
}
|
|
|
|
else if (vtype == QSE_AWK_VAL_STR)
|
|
|
|
{
|
|
|
|
ofs_ptr = ((qse_awk_val_str_t*)v)->val.ptr;
|
|
|
|
ofs_len = ((qse_awk_val_str_t*)v)->val.len;
|
|
|
|
}
|
|
|
|
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 -1;
|
|
|
|
|
|
|
|
ofs_ptr = out.u.cpldup.ptr;
|
|
|
|
ofs_len = out.u.cpldup.len;
|
|
|
|
ofs_free = ofs_ptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (qse_str_init(&tmp, qse_awk_rtx_getmmgr(rtx), QSE_STR_LEN(&rtx->inrec.line)) <= -1)
|
|
|
|
{
|
|
|
|
if (ofs_free) qse_awk_rtx_freemem (rtx, ofs_free);
|
|
|
|
if (nflds > 1) qse_awk_rtx_refdownval (rtx, v);
|
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < nflds; i++)
|
|
|
|
{
|
|
|
|
if (i > 0 && qse_str_ncat(&tmp,ofs_ptr,ofs_len) == (qse_size_t)-1)
|
|
|
|
{
|
|
|
|
qse_str_fini (&tmp);
|
|
|
|
if (ofs_free) qse_awk_rtx_freemem (rtx, ofs_free);
|
|
|
|
if (nflds > 1) qse_awk_rtx_refdownval (rtx, v);
|
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (qse_str_ncat (&tmp, rtx->inrec.flds[i].ptr, rtx->inrec.flds[i].len) == (qse_size_t)-1)
|
|
|
|
{
|
|
|
|
qse_str_fini (&tmp);
|
|
|
|
if (ofs_free) qse_awk_rtx_freemem (rtx, ofs_free);
|
|
|
|
if (nflds > 1) qse_awk_rtx_refdownval (rtx, v);
|
|
|
|
qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ofs_free) qse_awk_rtx_freemem (rtx, ofs_free);
|
|
|
|
if (nflds > 1) qse_awk_rtx_refdownval (rtx, v);
|
|
|
|
|
|
|
|
v = (qse_awk_val_t*)qse_awk_rtx_makestrvalwithcstr(rtx, QSE_STR_XSTR(&tmp));
|
|
|
|
if (!v)
|
|
|
|
{
|
|
|
|
qse_str_fini (&tmp);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
qse_awk_rtx_refdownval (rtx, rtx->inrec.d0);
|
|
|
|
rtx->inrec.d0 = v;
|
|
|
|
qse_awk_rtx_refupval (rtx, rtx->inrec.d0);
|
|
|
|
|
|
|
|
qse_str_swap (&tmp, &rtx->inrec.line);
|
|
|
|
qse_str_fini (&tmp);
|
|
|
|
|
|
|
|
for (i = nflds; i < rtx->inrec.nflds; i++)
|
|
|
|
{
|
|
|
|
qse_awk_rtx_refdownval (rtx, rtx->inrec.flds[i].val);
|
|
|
|
}
|
|
|
|
|
|
|
|
rtx->inrec.nflds = nflds;
|
|
|
|
return 0;
|
|
|
|
}
|