From a326e5f17fe92238ab533a1c99261d96c5010590 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Wed, 10 Jun 2009 07:07:42 +0000 Subject: [PATCH] fixed a bug in the builtin split() function --- qse/cmd/awk/awk.c | 10 +++--- qse/include/qse/awk/awk.h | 5 +-- qse/include/qse/awk/std.h | 27 +++++++------- qse/lib/awk/fnc.c | 18 +++++----- qse/lib/awk/parse.c | 13 ++++++- qse/lib/awk/run.c | 6 ++-- qse/lib/awk/std.c | 76 ++++++++++++++++++++++++++------------- 7 files changed, 98 insertions(+), 57 deletions(-) diff --git a/qse/cmd/awk/awk.c b/qse/cmd/awk/awk.c index 53a5c191..38ffd9c8 100644 --- a/qse/cmd/awk/awk.c +++ b/qse/cmd/awk/awk.c @@ -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 ( diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index 1bfe0b4e..687ef687 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -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 }; /** diff --git a/qse/include/qse/awk/std.h b/qse/include/qse/awk/std.h index 89a81f43..05e2edd0 100644 --- a/qse/include/qse/awk/std.h +++ b/qse/include/qse/awk/std.h @@ -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 +/** @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 diff --git a/qse/lib/awk/fnc.c b/qse/lib/awk/fnc.c index 1b084cbd..07712c78 100644 --- a/qse/lib/awk/fnc.c +++ b/qse/lib/awk/fnc.c @@ -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);*/ diff --git a/qse/lib/awk/parse.c b/qse/lib/awk/parse.c index eb3945d0..ced91a16 100644 --- a/qse/lib/awk/parse.c +++ b/qse/lib/awk/parse.c @@ -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) diff --git a/qse/lib/awk/run.c b/qse/lib/awk/run.c index 23080b13..788de613 100644 --- a/qse/lib/awk/run.c +++ b/qse/lib/awk/run.c @@ -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 diff --git a/qse/lib/awk/std.c b/qse/lib/awk/std.c index f74566b3..ea54e56b 100644 --- a/qse/lib/awk/std.c +++ b/qse/lib/awk/std.c @@ -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) - \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) - \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);