fixed a bug in the builtin split() function
This commit is contained in:
parent
334b52900d
commit
a326e5f17f
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: awk.c 182 2009-06-03 21:50:32Z hyunghwan.chung $
|
||||
* $Id: awk.c 194 2009-06-09 13:07:42Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
|
||||
@ -63,6 +63,7 @@ struct argout_t
|
||||
qse_char_t* osf; /* output source file */
|
||||
|
||||
|
||||
qse_char_t** arg;
|
||||
qse_char_t** icf; /* input console files */
|
||||
qse_size_t icfl; /* the number of input console files */
|
||||
qse_map_t* vm; /* global variable map */
|
||||
@ -351,8 +352,9 @@ static int handle_args (int argc, qse_char_t* argv[], struct argout_t* ao)
|
||||
qse_size_t isfc = 16; /* the capacity of isf */
|
||||
qse_size_t isfl = 0; /* number of input source files */
|
||||
|
||||
qse_size_t argl = 0;
|
||||
qse_size_t icfc = 0; /* the capacity of icf */
|
||||
qse_size_t icfl = 0; /* the number of input console files */
|
||||
qse_size_t icfl = 0; /* the number of input console files */
|
||||
|
||||
qse_char_t** isf = QSE_NULL; /* input source files */
|
||||
qse_char_t* osf = QSE_NULL; /* output source file */
|
||||
@ -509,7 +511,7 @@ static int handle_args (int argc, qse_char_t* argv[], struct argout_t* ao)
|
||||
|
||||
/* the remaining arguments are input console file names */
|
||||
icfc = (opt.ind >= argc)? 2: (argc - opt.ind + 1);
|
||||
icf = (qse_char_t**) malloc (QSE_SIZEOF(*icf)*icfc);
|
||||
icf = (qse_char_t**) malloc (QSE_SIZEOF(qse_char_t*)*icfc);
|
||||
if (icf == QSE_NULL)
|
||||
{
|
||||
out_of_memory ();
|
||||
@ -644,7 +646,7 @@ static int awk_main (int argc, qse_char_t* argv[])
|
||||
rcb.data = &ao;
|
||||
|
||||
rtx = qse_awk_rtx_openstd (
|
||||
awk, 0, ao.icf, QSE_AWK_RTX_OPENSTD_STDIO);
|
||||
awk, 0, QSE_T("qseawk"), ao.icf, QSE_AWK_RTX_OPENSTD_STDIO);
|
||||
if (rtx == QSE_NULL)
|
||||
{
|
||||
qse_printf (
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: awk.h 171 2009-06-01 09:34:34Z hyunghwan.chung $
|
||||
* $Id: awk.h 194 2009-06-09 13:07:42Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
|
||||
@ -413,7 +413,8 @@ enum qse_awk_option_t
|
||||
|
||||
/* option aggregtes */
|
||||
QSE_AWK_CLASSIC = QSE_AWK_IMPLICIT | QSE_AWK_RIO |
|
||||
QSE_AWK_NEWLINE | QSE_AWK_PABLOCK
|
||||
QSE_AWK_NEWLINE | QSE_AWK_PABLOCK |
|
||||
QSE_AWK_STRIPSPACES
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: std.h 86 2009-02-26 12:55:05Z hyunghwan.chung $
|
||||
* $Id: std.h 194 2009-06-09 13:07:42Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
|
||||
@ -21,6 +21,10 @@
|
||||
|
||||
#include <qse/awk/awk.h>
|
||||
|
||||
/** @file
|
||||
* Standard AWK Interpreter
|
||||
*/
|
||||
|
||||
/****e* AWK/qse_awk_parsestd_type_t
|
||||
* NAME
|
||||
* qse_awk_parsestd_type_t - define a source type
|
||||
@ -131,22 +135,19 @@ int qse_awk_parsestd (
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* AWK/qse_awk_rtx_openstd
|
||||
* NAME
|
||||
* qse_awk_rtx_openstd - create a runtime context
|
||||
/**
|
||||
* DESCRIPTION
|
||||
* The caller should keep the contents of icf and ocf valid throughout
|
||||
* the lifetime of the runtime context created. The runtime context
|
||||
* remembers the pointers without copying in the contents.
|
||||
* SYNOPSIS
|
||||
* The qse_awk_rtx_openstd() function creates a standard runtime context.
|
||||
* The caller should keep the contents of icf and ocf valid throughout
|
||||
* the lifetime of the runtime context created. The runtime context
|
||||
*/
|
||||
qse_awk_rtx_t* qse_awk_rtx_openstd (
|
||||
qse_awk_t* awk,
|
||||
qse_size_t xtnsize,
|
||||
const qse_char_t*const icf[],
|
||||
const qse_char_t*const ocf[]
|
||||
qse_awk_t* awk,
|
||||
qse_size_t xtn,
|
||||
const qse_char_t* id,
|
||||
const qse_char_t*const* icf,
|
||||
const qse_char_t*const* ocf
|
||||
);
|
||||
/******/
|
||||
|
||||
/****f* AWK/qse_awk_rtx_getxtnstd
|
||||
* NAME
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: fnc.c 171 2009-06-01 09:34:34Z hyunghwan.chung $
|
||||
* $Id: fnc.c 194 2009-06-09 13:07:42Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
|
||||
@ -584,7 +584,7 @@ static int fnc_split (
|
||||
qse_awk_val_t* a0, * a1, * a2, * t1, * t2, ** a1_ref;
|
||||
qse_char_t* str, * str_free, * p, * tok;
|
||||
qse_size_t str_len, str_left, tok_len, org_len;
|
||||
qse_long_t num;
|
||||
qse_long_t nflds;
|
||||
qse_char_t key[QSE_SIZEOF(qse_long_t)*8+2];
|
||||
qse_size_t key_len;
|
||||
qse_char_t* fs_ptr, * fs_free;
|
||||
@ -727,7 +727,7 @@ static int fnc_split (
|
||||
qse_awk_rtx_refupval (run, *a1_ref);
|
||||
|
||||
p = str; str_left = str_len; org_len = str_len;
|
||||
num = 1;
|
||||
nflds = 0;
|
||||
|
||||
while (p != QSE_NULL)
|
||||
{
|
||||
@ -755,14 +755,13 @@ static int fnc_split (
|
||||
}
|
||||
}
|
||||
|
||||
if (num == 0 && p == QSE_NULL && tok_len == 0)
|
||||
if (nflds == 0 && p == QSE_NULL && tok_len == 0)
|
||||
{
|
||||
/* no field at all*/
|
||||
break;
|
||||
}
|
||||
|
||||
QSE_ASSERT (
|
||||
(tok != QSE_NULL && tok_len > 0) || tok_len == 0);
|
||||
QSE_ASSERT ((tok != QSE_NULL && tok_len > 0) || tok_len == 0);
|
||||
|
||||
/* create the field string */
|
||||
t2 = qse_awk_rtx_makestrval (run, tok, tok_len);
|
||||
@ -780,7 +779,7 @@ static int fnc_split (
|
||||
|
||||
/* put it into the map */
|
||||
key_len = qse_awk_longtostr (
|
||||
num, 10, QSE_NULL, key, QSE_COUNTOF(key));
|
||||
++nflds, 10, QSE_NULL, key, QSE_COUNTOF(key));
|
||||
QSE_ASSERT (key_len != (qse_size_t)-1);
|
||||
|
||||
/* don't forget to update the reference count when you
|
||||
@ -810,7 +809,6 @@ static int fnc_split (
|
||||
return -1;
|
||||
}
|
||||
|
||||
num++;
|
||||
str_len = str_left - (p - str);
|
||||
}
|
||||
|
||||
@ -818,9 +816,9 @@ static int fnc_split (
|
||||
if (fs_free != QSE_NULL) QSE_AWK_FREE (run->awk, fs_free);
|
||||
if (fs_rex_free != QSE_NULL) QSE_AWK_FREEREX (run->awk, fs_rex_free);
|
||||
|
||||
num--;
|
||||
/*nflds--;*/
|
||||
|
||||
t1 = qse_awk_rtx_makeintval (run, num);
|
||||
t1 = qse_awk_rtx_makeintval (run, nflds);
|
||||
if (t1 == QSE_NULL)
|
||||
{
|
||||
/*qse_awk_rtx_seterrnum (run, QSE_AWK_ENOMEM);*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: parse.c 171 2009-06-01 09:34:34Z hyunghwan.chung $
|
||||
* $Id: parse.c 194 2009-06-09 13:07:42Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
|
||||
@ -3760,6 +3760,17 @@ static qse_awk_nde_t* parse_if (qse_awk_t* awk, qse_size_t line)
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
/* skip any new lines before the else block */
|
||||
while (MATCH(awk,TOKEN_NEWLINE))
|
||||
{
|
||||
if (get_token(awk) == -1)
|
||||
{
|
||||
qse_awk_clrpt (awk, then_part);
|
||||
qse_awk_clrpt (awk, test);
|
||||
return QSE_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (MATCH(awk,TOKEN_ELSE))
|
||||
{
|
||||
if (get_token(awk) == -1)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: run.c 182 2009-06-03 21:50:32Z hyunghwan.chung $
|
||||
* $Id: run.c 194 2009-06-09 13:07:42Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
|
||||
@ -1002,8 +1002,8 @@ static int build_runarg (
|
||||
return -1;
|
||||
}
|
||||
|
||||
key_len = qse_awk_longtostr (argc+1,
|
||||
10, QSE_NULL, key, QSE_COUNTOF(key));
|
||||
key_len = qse_awk_longtostr (
|
||||
argc, 10, QSE_NULL, key, QSE_COUNTOF(key));
|
||||
QSE_ASSERT (key_len != (qse_size_t)-1);
|
||||
|
||||
/* increment reference count of v_tmp in advance as if
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: std.c 182 2009-06-03 21:50:32Z hyunghwan.chung $
|
||||
* $Id: std.c 194 2009-06-09 13:07:42Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
|
||||
@ -440,8 +440,6 @@ static qse_ssize_t awk_rio_pipe (
|
||||
}
|
||||
else return -1; /* TODO: any way to set the error number? */
|
||||
|
||||
/*dprint (QSE_T("opening %s of type %d (pipe)\n"), riod->name, riod->type);*/
|
||||
|
||||
handle = qse_pio_open (
|
||||
rtx->awk->mmgr,
|
||||
0,
|
||||
@ -456,7 +454,6 @@ static qse_ssize_t awk_rio_pipe (
|
||||
|
||||
case QSE_AWK_RIO_CLOSE:
|
||||
{
|
||||
/*dprint (QSE_T("closing %s of type (pipe) %d\n"), riod->name, riod->type);*/
|
||||
qse_pio_close ((qse_pio_t*)riod->handle);
|
||||
riod->handle = QSE_NULL;
|
||||
return 0;
|
||||
@ -525,7 +522,6 @@ static qse_ssize_t awk_rio_file (
|
||||
}
|
||||
else return -1; /* TODO: any way to set the error number? */
|
||||
|
||||
/*dprint (QSE_T("opening %s of type %d (file)\n"), riod->name, riod->type);*/
|
||||
handle = qse_fio_open (
|
||||
rtx->awk->mmgr,
|
||||
0,
|
||||
@ -551,7 +547,6 @@ static qse_ssize_t awk_rio_file (
|
||||
|
||||
case QSE_AWK_RIO_CLOSE:
|
||||
{
|
||||
/*dprint (QSE_T("closing %s of type %d (file)\n"), riod->name, riod->type);*/
|
||||
qse_fio_close ((qse_fio_t*)riod->handle);
|
||||
riod->handle = QSE_NULL;
|
||||
return 0;
|
||||
@ -594,8 +589,6 @@ static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_riod_t* riod)
|
||||
{
|
||||
rxtn_t* rxtn = (rxtn_t*) QSE_XTN (rtx);
|
||||
|
||||
/*dprint (QSE_T("opening console[%s] of type %x\n"), riod->name, riod->type);*/
|
||||
|
||||
if (riod->mode == QSE_AWK_RIO_CONSOLE_READ)
|
||||
{
|
||||
if (rxtn->c.in.files == QSE_NULL)
|
||||
@ -607,13 +600,11 @@ static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_riod_t* riod)
|
||||
if (rxtn->c.in.files[rxtn->c.in.index] == QSE_NULL)
|
||||
{
|
||||
/* no more input file */
|
||||
/*dprint (QSE_T("console - no more file\n"));*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rxtn->c.in.files[rxtn->c.in.index][0] == QSE_T('\0'))
|
||||
{
|
||||
/*dprint (QSE_T(" console(r) - <standard input>\n"));*/
|
||||
riod->handle = qse_sio_in;
|
||||
}
|
||||
else
|
||||
@ -639,7 +630,6 @@ static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_riod_t* riod)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*dprint (QSE_T(" console(r) - %s\n"), rxtn->c.in.files[rxtn->c.in.index]);*/
|
||||
if (qse_awk_rtx_setfilename (
|
||||
rtx, rxtn->c.in.files[rxtn->c.in.index],
|
||||
qse_strlen(rxtn->c.in.files[rxtn->c.in.index])) == -1)
|
||||
@ -665,13 +655,11 @@ static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_riod_t* riod)
|
||||
if (rxtn->c.out.files[rxtn->c.out.index] == QSE_NULL)
|
||||
{
|
||||
/* no more input file */
|
||||
/*dprint (QSE_T("console - no more file\n"));*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rxtn->c.out.files[rxtn->c.out.index][0] == QSE_T('\0'))
|
||||
{
|
||||
/*dprint (QSE_T(" console(w) - <standard output>\n"));*/
|
||||
riod->handle = qse_sio_out;
|
||||
}
|
||||
else
|
||||
@ -697,7 +685,6 @@ static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_riod_t* riod)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*dprint (QSE_T(" console(w) - %s\n"), rxtn->c.out.files[rxtn->c.out.index]);*/
|
||||
if (qse_awk_rtx_setofilename (
|
||||
rtx, rxtn->c.out.files[rxtn->c.out.index],
|
||||
qse_strlen(rxtn->c.out.files[rxtn->c.out.index])) == -1)
|
||||
@ -728,8 +715,6 @@ static qse_ssize_t awk_rio_console (
|
||||
}
|
||||
else if (cmd == QSE_AWK_RIO_CLOSE)
|
||||
{
|
||||
/*dprint (QSE_T("closing console of type %x\n"), riod->type);*/
|
||||
|
||||
if (riod->handle != QSE_NULL &&
|
||||
riod->handle != qse_sio_in &&
|
||||
riod->handle != qse_sio_out &&
|
||||
@ -812,7 +797,6 @@ static qse_ssize_t awk_rio_console (
|
||||
qse_sio_close ((qse_sio_t*)riod->handle);
|
||||
}
|
||||
|
||||
/*dprint (QSE_T("open the next console [%s]\n"), rxtn->c.in.files[rxtn->c.in.index]);*/
|
||||
riod->handle = sio;
|
||||
}
|
||||
|
||||
@ -838,8 +822,6 @@ static qse_ssize_t awk_rio_console (
|
||||
int n;
|
||||
qse_sio_t* sio = (qse_sio_t*)riod->handle;
|
||||
|
||||
/*dprint (QSE_T("switching console[%s] of type %x\n"), riod->name, riod->type);*/
|
||||
|
||||
n = open_rio_console (rtx, riod);
|
||||
if (n == -1) return -1;
|
||||
|
||||
@ -864,26 +846,72 @@ static qse_ssize_t awk_rio_console (
|
||||
}
|
||||
|
||||
qse_awk_rtx_t* qse_awk_rtx_openstd (
|
||||
qse_awk_t* awk,
|
||||
qse_size_t xtnsize,
|
||||
const qse_char_t*const icf[],
|
||||
const qse_char_t*const ocf[])
|
||||
qse_awk_t* awk,
|
||||
qse_size_t xtnsize,
|
||||
const qse_char_t* id,
|
||||
const qse_char_t*const* icf,
|
||||
const qse_char_t*const* ocf)
|
||||
{
|
||||
qse_awk_rtx_t* rtx;
|
||||
qse_awk_rio_t rio;
|
||||
rxtn_t* rxtn;
|
||||
qse_ntime_t now;
|
||||
|
||||
const qse_char_t*const* p;
|
||||
qse_size_t argc = 0;
|
||||
qse_cstr_t argv[16];
|
||||
qse_cstr_t* argvp = QSE_NULL, * p2;
|
||||
|
||||
rio.pipe = awk_rio_pipe;
|
||||
rio.file = awk_rio_file;
|
||||
rio.console = awk_rio_console;
|
||||
|
||||
if (icf != QSE_NULL)
|
||||
{
|
||||
for (p = icf; *p != QSE_NULL; p++);
|
||||
argc = p - icf;
|
||||
}
|
||||
|
||||
argc++; /* for id */
|
||||
|
||||
if (argc < QSE_COUNTOF(argv)) argvp = argv;
|
||||
else
|
||||
{
|
||||
argvp = QSE_AWK_ALLOC (
|
||||
awk, QSE_SIZEOF(*argvp) * (argc + 1));
|
||||
if (argvp == QSE_NULL)
|
||||
{
|
||||
qse_awk_seterrnum (awk, QSE_AWK_ENOMEM);
|
||||
return QSE_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
p2 = argvp;
|
||||
|
||||
p2->ptr = id;
|
||||
p2->len = qse_strlen(id);
|
||||
p2++;
|
||||
|
||||
if (icf != QSE_NULL)
|
||||
{
|
||||
for (p = icf; *p != QSE_NULL; p++, p2++)
|
||||
{
|
||||
p2->ptr = *p;
|
||||
p2->len = qse_strlen(*p);
|
||||
}
|
||||
}
|
||||
|
||||
p2->ptr = QSE_NULL;
|
||||
p2->len = 0;
|
||||
|
||||
rtx = qse_awk_rtx_open (
|
||||
awk,
|
||||
QSE_SIZEOF(rxtn_t) + xtnsize,
|
||||
&rio,
|
||||
QSE_NULL/*runarg*/
|
||||
argvp
|
||||
);
|
||||
|
||||
if (argvp != QSE_NULL && argvp != argv) QSE_AWK_FREE (awk, argvp);
|
||||
if (rtx == QSE_NULL) return QSE_NULL;
|
||||
|
||||
rxtn = (rxtn_t*) QSE_XTN (rtx);
|
||||
|
Loading…
Reference in New Issue
Block a user