fixed a bug in the builtin split() function

This commit is contained in:
hyung-hwan 2009-06-10 07:07:42 +00:00
parent 334b52900d
commit a326e5f17f
7 changed files with 98 additions and 57 deletions

View File

@ -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. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -63,6 +63,7 @@ struct argout_t
qse_char_t* osf; /* output source file */ qse_char_t* osf; /* output source file */
qse_char_t** arg;
qse_char_t** icf; /* input console files */ qse_char_t** icf; /* input console files */
qse_size_t icfl; /* the number of input console files */ qse_size_t icfl; /* the number of input console files */
qse_map_t* vm; /* global variable map */ 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 isfc = 16; /* the capacity of isf */
qse_size_t isfl = 0; /* number of input source files */ 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 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** isf = QSE_NULL; /* input source files */
qse_char_t* osf = QSE_NULL; /* output source file */ 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 */ /* the remaining arguments are input console file names */
icfc = (opt.ind >= argc)? 2: (argc - opt.ind + 1); 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) if (icf == QSE_NULL)
{ {
out_of_memory (); out_of_memory ();
@ -644,7 +646,7 @@ static int awk_main (int argc, qse_char_t* argv[])
rcb.data = &ao; rcb.data = &ao;
rtx = qse_awk_rtx_openstd ( 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) if (rtx == QSE_NULL)
{ {
qse_printf ( qse_printf (

View File

@ -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. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -413,7 +413,8 @@ enum qse_awk_option_t
/* option aggregtes */ /* option aggregtes */
QSE_AWK_CLASSIC = QSE_AWK_IMPLICIT | QSE_AWK_RIO | QSE_AWK_CLASSIC = QSE_AWK_IMPLICIT | QSE_AWK_RIO |
QSE_AWK_NEWLINE | QSE_AWK_PABLOCK QSE_AWK_NEWLINE | QSE_AWK_PABLOCK |
QSE_AWK_STRIPSPACES
}; };
/** /**

View File

@ -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. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -21,6 +21,10 @@
#include <qse/awk/awk.h> #include <qse/awk/awk.h>
/** @file
* Standard AWK Interpreter
*/
/****e* AWK/qse_awk_parsestd_type_t /****e* AWK/qse_awk_parsestd_type_t
* NAME * NAME
* qse_awk_parsestd_type_t - define a source type * 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 * DESCRIPTION
* The caller should keep the contents of icf and ocf valid throughout * The qse_awk_rtx_openstd() function creates a standard runtime context.
* the lifetime of the runtime context created. The runtime context * The caller should keep the contents of icf and ocf valid throughout
* remembers the pointers without copying in the contents. * the lifetime of the runtime context created. The runtime context
* SYNOPSIS
*/ */
qse_awk_rtx_t* qse_awk_rtx_openstd ( qse_awk_rtx_t* qse_awk_rtx_openstd (
qse_awk_t* awk, qse_awk_t* awk,
qse_size_t xtnsize, qse_size_t xtn,
const qse_char_t*const icf[], const qse_char_t* id,
const qse_char_t*const ocf[] const qse_char_t*const* icf,
const qse_char_t*const* ocf
); );
/******/
/****f* AWK/qse_awk_rtx_getxtnstd /****f* AWK/qse_awk_rtx_getxtnstd
* NAME * NAME

View File

@ -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. 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_awk_val_t* a0, * a1, * a2, * t1, * t2, ** a1_ref;
qse_char_t* str, * str_free, * p, * tok; qse_char_t* str, * str_free, * p, * tok;
qse_size_t str_len, str_left, tok_len, org_len; 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_char_t key[QSE_SIZEOF(qse_long_t)*8+2];
qse_size_t key_len; qse_size_t key_len;
qse_char_t* fs_ptr, * fs_free; qse_char_t* fs_ptr, * fs_free;
@ -727,7 +727,7 @@ static int fnc_split (
qse_awk_rtx_refupval (run, *a1_ref); qse_awk_rtx_refupval (run, *a1_ref);
p = str; str_left = str_len; org_len = str_len; p = str; str_left = str_len; org_len = str_len;
num = 1; nflds = 0;
while (p != QSE_NULL) 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*/ /* no field at all*/
break; break;
} }
QSE_ASSERT ( QSE_ASSERT ((tok != QSE_NULL && tok_len > 0) || tok_len == 0);
(tok != QSE_NULL && tok_len > 0) || tok_len == 0);
/* create the field string */ /* create the field string */
t2 = qse_awk_rtx_makestrval (run, tok, tok_len); t2 = qse_awk_rtx_makestrval (run, tok, tok_len);
@ -780,7 +779,7 @@ static int fnc_split (
/* put it into the map */ /* put it into the map */
key_len = qse_awk_longtostr ( 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); QSE_ASSERT (key_len != (qse_size_t)-1);
/* don't forget to update the reference count when you /* don't forget to update the reference count when you
@ -810,7 +809,6 @@ static int fnc_split (
return -1; return -1;
} }
num++;
str_len = str_left - (p - str); 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_free != QSE_NULL) QSE_AWK_FREE (run->awk, fs_free);
if (fs_rex_free != QSE_NULL) QSE_AWK_FREEREX (run->awk, fs_rex_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) if (t1 == QSE_NULL)
{ {
/*qse_awk_rtx_seterrnum (run, QSE_AWK_ENOMEM);*/ /*qse_awk_rtx_seterrnum (run, QSE_AWK_ENOMEM);*/

View File

@ -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. 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; 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 (MATCH(awk,TOKEN_ELSE))
{ {
if (get_token(awk) == -1) if (get_token(awk) == -1)

View File

@ -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. Copyright 2006-2009 Chung, Hyung-Hwan.
@ -1002,8 +1002,8 @@ static int build_runarg (
return -1; return -1;
} }
key_len = qse_awk_longtostr (argc+1, key_len = qse_awk_longtostr (
10, QSE_NULL, key, QSE_COUNTOF(key)); argc, 10, QSE_NULL, key, QSE_COUNTOF(key));
QSE_ASSERT (key_len != (qse_size_t)-1); QSE_ASSERT (key_len != (qse_size_t)-1);
/* increment reference count of v_tmp in advance as if /* increment reference count of v_tmp in advance as if

View File

@ -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. 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? */ 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 ( handle = qse_pio_open (
rtx->awk->mmgr, rtx->awk->mmgr,
0, 0,
@ -456,7 +454,6 @@ static qse_ssize_t awk_rio_pipe (
case QSE_AWK_RIO_CLOSE: 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); qse_pio_close ((qse_pio_t*)riod->handle);
riod->handle = QSE_NULL; riod->handle = QSE_NULL;
return 0; return 0;
@ -525,7 +522,6 @@ static qse_ssize_t awk_rio_file (
} }
else return -1; /* TODO: any way to set the error number? */ 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 ( handle = qse_fio_open (
rtx->awk->mmgr, rtx->awk->mmgr,
0, 0,
@ -551,7 +547,6 @@ static qse_ssize_t awk_rio_file (
case QSE_AWK_RIO_CLOSE: 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); qse_fio_close ((qse_fio_t*)riod->handle);
riod->handle = QSE_NULL; riod->handle = QSE_NULL;
return 0; 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); 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 (riod->mode == QSE_AWK_RIO_CONSOLE_READ)
{ {
if (rxtn->c.in.files == QSE_NULL) 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) if (rxtn->c.in.files[rxtn->c.in.index] == QSE_NULL)
{ {
/* no more input file */ /* no more input file */
/*dprint (QSE_T("console - no more file\n"));*/
return 0; return 0;
} }
if (rxtn->c.in.files[rxtn->c.in.index][0] == QSE_T('\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; riod->handle = qse_sio_in;
} }
else else
@ -639,7 +630,6 @@ static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_riod_t* riod)
return -1; return -1;
} }
/*dprint (QSE_T(" console(r) - %s\n"), rxtn->c.in.files[rxtn->c.in.index]);*/
if (qse_awk_rtx_setfilename ( if (qse_awk_rtx_setfilename (
rtx, rxtn->c.in.files[rxtn->c.in.index], rtx, rxtn->c.in.files[rxtn->c.in.index],
qse_strlen(rxtn->c.in.files[rxtn->c.in.index])) == -1) 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) if (rxtn->c.out.files[rxtn->c.out.index] == QSE_NULL)
{ {
/* no more input file */ /* no more input file */
/*dprint (QSE_T("console - no more file\n"));*/
return 0; return 0;
} }
if (rxtn->c.out.files[rxtn->c.out.index][0] == QSE_T('\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; riod->handle = qse_sio_out;
} }
else else
@ -697,7 +685,6 @@ static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_riod_t* riod)
return -1; return -1;
} }
/*dprint (QSE_T(" console(w) - %s\n"), rxtn->c.out.files[rxtn->c.out.index]);*/
if (qse_awk_rtx_setofilename ( if (qse_awk_rtx_setofilename (
rtx, rxtn->c.out.files[rxtn->c.out.index], rtx, rxtn->c.out.files[rxtn->c.out.index],
qse_strlen(rxtn->c.out.files[rxtn->c.out.index])) == -1) 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) else if (cmd == QSE_AWK_RIO_CLOSE)
{ {
/*dprint (QSE_T("closing console of type %x\n"), riod->type);*/
if (riod->handle != QSE_NULL && if (riod->handle != QSE_NULL &&
riod->handle != qse_sio_in && riod->handle != qse_sio_in &&
riod->handle != qse_sio_out && riod->handle != qse_sio_out &&
@ -812,7 +797,6 @@ static qse_ssize_t awk_rio_console (
qse_sio_close ((qse_sio_t*)riod->handle); 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; riod->handle = sio;
} }
@ -838,8 +822,6 @@ static qse_ssize_t awk_rio_console (
int n; int n;
qse_sio_t* sio = (qse_sio_t*)riod->handle; 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); n = open_rio_console (rtx, riod);
if (n == -1) return -1; 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_rtx_t* qse_awk_rtx_openstd (
qse_awk_t* awk, qse_awk_t* awk,
qse_size_t xtnsize, qse_size_t xtnsize,
const qse_char_t*const icf[], const qse_char_t* id,
const qse_char_t*const ocf[]) const qse_char_t*const* icf,
const qse_char_t*const* ocf)
{ {
qse_awk_rtx_t* rtx; qse_awk_rtx_t* rtx;
qse_awk_rio_t rio; qse_awk_rio_t rio;
rxtn_t* rxtn; rxtn_t* rxtn;
qse_ntime_t now; 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.pipe = awk_rio_pipe;
rio.file = awk_rio_file; rio.file = awk_rio_file;
rio.console = awk_rio_console; 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 ( rtx = qse_awk_rtx_open (
awk, awk,
QSE_SIZEOF(rxtn_t) + xtnsize, QSE_SIZEOF(rxtn_t) + xtnsize,
&rio, &rio,
QSE_NULL/*runarg*/ argvp
); );
if (argvp != QSE_NULL && argvp != argv) QSE_AWK_FREE (awk, argvp);
if (rtx == QSE_NULL) return QSE_NULL; if (rtx == QSE_NULL) return QSE_NULL;
rxtn = (rxtn_t*) QSE_XTN (rtx); rxtn = (rxtn_t*) QSE_XTN (rtx);