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.
@ -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,6 +352,7 @@ 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 */
@ -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 (

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.
@ -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
};
/**

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.
@ -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 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
* remembers the pointers without copying in the contents.
* SYNOPSIS
*/
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_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

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.
@ -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);*/

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.
@ -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)

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.
@ -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

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.
@ -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;
@ -866,24 +848,70 @@ 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[])
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);