From 10c75d357d3abf9dc0786961dde0803a3c730e79 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Thu, 3 Sep 2009 06:55:55 +0000 Subject: [PATCH] fixed a bug in emitting a string --- qse/cmd/sed/sed.c | 2 +- qse/doc/Doxyfile.in | 2 +- qse/doc/page/awk.doc | 34 +-- qse/doc/page/sed.doc | 18 +- qse/include/qse/awk/Awk.hpp | 34 +-- qse/include/qse/awk/awk.h | 101 ++++---- qse/include/qse/awk/std.h | 3 +- qse/include/qse/cmn/pio.h | 4 +- qse/include/qse/cmn/sll.h | 225 +++++++----------- qse/include/qse/cmn/str.h | 4 +- qse/include/qse/sed/sed.h | 34 ++- qse/lib/awk/fnc.c | 25 +- qse/lib/awk/rio.c | 10 +- qse/lib/awk/run.c | 11 +- qse/lib/awk/tree.c | 6 +- qse/lib/sed/sed.c | 39 +++- qse/lib/sed/sed.h | 4 +- qse/regress/awk/lang-035.awk | 72 ++++++ qse/regress/awk/lang-035.dat1 | 13 ++ qse/regress/awk/lang-035.dat2 | 159 +++++++++++++ qse/regress/awk/regress.out | 384 +++++++++++++++++++++++++------ qse/regress/awk/regress.sh | 52 +++-- qse/regress/awk/stripcomment.awk | 4 +- 23 files changed, 887 insertions(+), 353 deletions(-) create mode 100644 qse/regress/awk/lang-035.awk create mode 100644 qse/regress/awk/lang-035.dat1 create mode 100644 qse/regress/awk/lang-035.dat2 diff --git a/qse/cmd/sed/sed.c b/qse/cmd/sed/sed.c index 4813d31e..988665dd 100644 --- a/qse/cmd/sed/sed.c +++ b/qse/cmd/sed/sed.c @@ -121,7 +121,7 @@ static void print_usage (QSE_FILE* out, int argc, qse_char_t* argv[]) qse_fprintf (out, QSE_T(" -a perform strict address check\n")); qse_fprintf (out, QSE_T(" -r allows {n,m} in a regular expression\n")); qse_fprintf (out, QSE_T(" -s allows text on the same line as c, a, i\n")); - qse_fprintf (out, QSE_T(" -l ensures a newline at the text end")); + qse_fprintf (out, QSE_T(" -l ensures a newline at text end")); } static int handle_args (int argc, qse_char_t* argv[]) diff --git a/qse/doc/Doxyfile.in b/qse/doc/Doxyfile.in index 369bc9e3..fbfea7a3 100644 --- a/qse/doc/Doxyfile.in +++ b/qse/doc/Doxyfile.in @@ -343,7 +343,7 @@ HIDE_UNDOC_MEMBERS = YES # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. -HIDE_UNDOC_CLASSES = NO +HIDE_UNDOC_CLASSES = YES # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. diff --git a/qse/doc/page/awk.doc b/qse/doc/page/awk.doc index 32cdce27..fb7a3e22 100644 --- a/qse/doc/page/awk.doc +++ b/qse/doc/page/awk.doc @@ -2,13 +2,17 @@ AWK Interpreter -VARIABLE DECLARATION +@section awk_ext EXTENSION +Some language extensions are implemented and they can be enabled by setting the +corresponding options. -QSE_AWK_EXPLICIT enables variable declaration. Variables declared are accessed +@subsection awk_ext_vardecl VARIABLE DECLARATION + +#QSE_AWK_EXPLICIT enables variable declaration. Variables declared are accessed directly bypassing the global named map that stores undeclared variables. -The keyword global introduces a global variable and the keyword local introduces -a local variable. Local variable declaraion in a block should be located before -an expression or a statement appears. +The keyword @b global introduces a global variable and the keyword @b local +introduces local variable. Local variable declaraion in a block must be +located before an expression or a statement appears. @code global g1, g2; #declares two global variables g1 and g2 @@ -19,8 +23,8 @@ BEGIN { g1 = 300; a1 = 200; { - local a1; # this a1 hides the a1 at the outer scope - local g1; # this g1 hides the global g1 + local a1; # a1 here hides the a1 at the outer scope + local g1; # g1 here hides the global g1 a1 = 10; g1 = 5; print a1, g1; # it prints 10 and 5 } @@ -30,26 +34,26 @@ BEGIN { @endcode -However, turning on QSE_AWK_EXPLICIT does not disable named variables. -To disable named variables, you must turn off QSE_AWK_IMPLICIT. +However, turning on #QSE_AWK_EXPLICIT does not disable named variables. +To disable named variables, you must turn off #QSE_AWK_IMPLICIT. -INCLUDE +@subsection awk_ext_include INCLUDE The \@include directive inserts the contents of the object specified in the following string, typically a file name, as if they appeared in the source stream being processed. The directive can only be used at the outmost scope -where global variable declarations, BEGIN, END, and/or pattern-action blocks -appear. To use \@include, you must turn on QSE_AWK_INCLUDE. +where global variable declarations, @b BEGIN, @b END, and/or pattern-action +blocks appear. To use \@include, you must turn on #QSE_AWK_INCLUDE. @code @include "abc.awk" BEGIN { func_in_abc (); } @endcode -TWO-WAY PIPE +@subsection awk_ext_rwpipe TWO-WAY PIPE -The two-way pipe indicated by '||' is supproted, in addition to the one-way -pipe indicated by '|'. Turn on QSE_AWK_RWPIPE to enable the two-way pipe. +The two-way pipe indicated by @b || is supproted, in addition to the one-way +pipe indicated by @b |. Turn on #QSE_AWK_RWPIPE to enable the two-way pipe. @code BEGIN { diff --git a/qse/doc/page/sed.doc b/qse/doc/page/sed.doc index 4a189d5e..90eb29a8 100644 --- a/qse/doc/page/sed.doc +++ b/qse/doc/page/sed.doc @@ -94,14 +94,14 @@ Terminates the exection of commands quietly. - a \\ \n text Stores @b text into the append buffer which is printed after the pattern space for each input line. If #QSE_SED_STRICT is on, an address range is not -allowed for a line selector. If #QSE_SED_NEWLINE is specified, the backslash -and the text can be located on the same line without a line break. +allowed for a line selector. If #QSE_SED_SAMELINE is on, the backslash and the +text can be located on the same line without a line break. - i \\ \n text Inserts @b text into an insert buffer which is printed before the pattern space for each input line. If #QSE_SED_STRICT is on, an address range is not -allowed for a line selector. If #QSE_SED_NEWLINE is specified, the backslash -and the text can be located on the same line without a line break. +allowed for a line selector. If #QSE_SED_SAMELINE is on, the backslash and the +text can be located on the same line without a line break. - c \\ \n text If a single line is selected for the command (i.e. no line selector, a single @@ -109,7 +109,7 @@ address line selector, or a start~step line selector is specified), it changes the pattern space to @b text and branches to the end of commands for the line. If an address range is specified, it deletes the pattern space and branches to the end of commands for all input lines but the last, and changes pattern -space to @b text and branches to the end of commands. If #QSE_SED_NEWLINE is +space to @b text and branches to the end of commands. If #QSE_SED_SAMELINE is on, the backlash and the text can be located on the same line without a line break. @@ -122,8 +122,8 @@ it branches to the end of script. Otherwise, the commands from the first are reapplied to the current pattern space. - = -Prints the current line number. If #QSE_SED_STRICT is speccified, an address -range is not allowed in the line selector. +Prints the current line number. If #QSE_SED_STRICT is on, an address range is +not allowed as a line selector. - p Prints the pattern space. @@ -178,8 +178,8 @@ error. - R file Reads a line of text from @b file and prints it after printing pattern space -but before printing the append buffer. Failure to read @b file does not cause an -error. +but before printing the append buffer. Failure to read @b file does not cause +an error. - w file Writes the pattern space to @b file diff --git a/qse/include/qse/awk/Awk.hpp b/qse/include/qse/awk/Awk.hpp index 32331d70..502ae070 100644 --- a/qse/include/qse/awk/Awk.hpp +++ b/qse/include/qse/awk/Awk.hpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.hpp 275 2009-08-30 13:19:02Z hyunghwan.chung $ + * $Id: Awk.hpp 277 2009-09-02 12:55:55Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -25,7 +25,6 @@ #include #include - /** @file * AWK Interpreter */ @@ -271,24 +270,27 @@ protected: class NoSource; public: - /** - * The Source class is an abstract class to encapsulate - * source script I/O. The Awk::parse function requires a concrete - * object instantiated from its child class. - */ + /// + /// The Source class is an abstract class to encapsulate + /// source script I/O. The Awk::parse function requires a concrete + /// object instantiated from its child class. + /// class Source { public: + /// + /// The Mode type defines opening mode. + /// enum Mode { - READ, /**< source code read. */ - WRITE /**< source code write. */ + READ, ///< open for read + WRITE ///< open for write }; - /** - * The Awk::Source::Data class is used to deliver information - * needed for source script I/O. - */ + /// + /// The Data class encapsulates information passed in and out + /// for source script I/O. + /// class Data: protected sio_arg_t { public: @@ -345,9 +347,9 @@ public: virtual ssize_t read (Data& io, char_t* buf, size_t len) = 0; virtual ssize_t write (Data& io, char_t* buf, size_t len) = 0; - /** - * special value to indicate no source - */ + /// + /// The NONE object indicates no source. + /// static NoSource NONE; private: diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index d20ed852..4956a059 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h 275 2009-08-30 13:19:02Z hyunghwan.chung $ + * $Id: awk.h 277 2009-09-02 12:55:55Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -338,8 +338,8 @@ enum qse_awk_rio_cmd_t QSE_AWK_RIO_OPEN = 0, /**< open a stream */ QSE_AWK_RIO_CLOSE = 1, /**< close a stream */ QSE_AWK_RIO_READ = 2, /**< read a stream */ - QSE_AWK_RIO_WRITE = 3, /**< write a stream */ - QSE_AWK_RIO_FLUSH = 4, /**< write buffered data to a stream */ + QSE_AWK_RIO_WRITE = 3, /**< write to a stream */ + QSE_AWK_RIO_FLUSH = 4, /**< flush buffered data to a stream */ QSE_AWK_RIO_NEXT = 5 /**< close the current stream and open the next stream (only for console) */ }; @@ -582,7 +582,7 @@ enum qse_awk_option_t /** supports @b getline and @b print */ QSE_AWK_RIO = (1 << 3), - /** supports dual direction pipe if #QSE_AWK_RIO is on */ + /** enables the two-way pipe if #QSE_AWK_RIO is on */ QSE_AWK_RWPIPE = (1 << 4), /** a new line can terminate a statement */ @@ -891,23 +891,28 @@ enum qse_awk_val_type_t /** * The values defined are used to set the type field of the - * qse_awk_rtx_valtostr_out_t structure. The field should be one of the + * #qse_awk_rtx_valtostr_out_t structure. The field should be one of the * following values: * - * - QSE_AWK_RTX_VALTOSTR_CPL - * - QSE_AWK_RTX_VALTOSTR_CPLDUP - * - QSE_AWK_RTX_VALTOSTR_STRP - * - QSE_AWK_RTX_VALTOSTR_STRPCAT + * - #QSE_AWK_RTX_VALTOSTR_CPL + * - #QSE_AWK_RTX_VALTOSTR_CPLDUP + * - #QSE_AWK_RTX_VALTOSTR_STRP + * - #QSE_AWK_RTX_VALTOSTR_STRPCAT * - * and it can optionally be ORed with QSE_AWK_RTX_VALTOSTR_PRINT. + * and it can optionally be ORed with #QSE_AWK_RTX_VALTOSTR_PRINT. */ enum qse_awk_rtx_valtostr_type_t -{ - QSE_AWK_RTX_VALTOSTR_CPL = 0x00, +{ + /** use u.cpl of #qse_awk_rtx_valtostr_out_t */ + QSE_AWK_RTX_VALTOSTR_CPL = 0x00, + /** use u.cpldup of #qse_awk_rtx_valtostr_out_t */ QSE_AWK_RTX_VALTOSTR_CPLDUP = 0x01, + /** use u.strp of #qse_awk_rtx_valtostr_out_t */ QSE_AWK_RTX_VALTOSTR_STRP = 0x02, + /** use u.strpcat of #qse_awk_rtx_valtostr_out_t */ QSE_AWK_RTX_VALTOSTR_STRPCAT = 0x03, - QSE_AWK_RTX_VALTOSTR_PRINT = 0x10 + /** convert for print */ + QSE_AWK_RTX_VALTOSTR_PRINT = 0x10 }; /** @@ -916,7 +921,7 @@ enum qse_awk_rtx_valtostr_type_t */ struct qse_awk_rtx_valtostr_out_t { - int type; + int type; /**< enum #qse_awk_rtx_valtostr_type_t */ union { @@ -1086,7 +1091,8 @@ void qse_awk_geterrinf ( void qse_awk_seterrnum ( qse_awk_t* awk, /**< awk object */ qse_awk_errnum_t errnum, /**< error number */ - const qse_cstr_t* errarg /**< arguments to format error message */ + const qse_cstr_t* errarg /**< argument array for formatting + * an error message */ ); void qse_awk_seterrinf ( @@ -1107,7 +1113,7 @@ void qse_awk_geterror ( void qse_awk_seterror ( qse_awk_t* awk, /**< awk object */ qse_awk_errnum_t errnum, /**< error number */ - const qse_cstr_t* errarg, /**< array of arguments for formatting + const qse_cstr_t* errarg, /**< argument array for formatting * an error message */ const qse_awk_loc_t* errloc /**< error location */ ); @@ -1171,7 +1177,7 @@ int qse_awk_setword ( */ int qse_awk_addgbl ( qse_awk_t* awk, /**< awk object */ - const qse_char_t* name, /**< a variable name */ + const qse_char_t* name, /**< variable name */ qse_size_t len /**< name length */ ); @@ -1181,7 +1187,7 @@ int qse_awk_addgbl ( */ int qse_awk_delgbl ( qse_awk_t* awk, /**< awk object */ - const qse_char_t* name, /**< a variable name */ + const qse_char_t* name, /**< variable name */ qse_size_t len /**< name length */ ); @@ -1300,7 +1306,7 @@ void qse_awk_free ( */ qse_char_t* qse_awk_strdup ( qse_awk_t* awk, /**< awk object */ - const qse_char_t* str /**< a string pointer */ + const qse_char_t* str /**< string pointer */ ); /** @@ -1314,8 +1320,8 @@ qse_char_t* qse_awk_strdup ( */ qse_char_t* qse_awk_strxdup ( qse_awk_t* awk, /**< awk object */ - const qse_char_t* str, /**< a string pointer */ - qse_size_t len /**< the number of character in a string */ + const qse_char_t* str, /**< string pointer */ + qse_size_t len /**< string length */ ); qse_long_t qse_awk_strxtolong ( @@ -1343,14 +1349,21 @@ qse_size_t qse_awk_longtostr ( ); /** - * The qse_awk_rtx_open() creates a runtime context. - * @return a runtime context on success, #QSE_NULL on failure + * The qse_awk_rtx_open() creates a runtime context associated with @a awk. + * It also allocates an extra memory block as large as the @a xtn bytes. + * You can get the pointer to the beginning of the block with + * qse_awk_rtx_getxtn(). The block is destroyed when the runtime context is + * destroyed. The argument array @a arg, if not #QSE_NULL, is used to set + * @b ARGV. The @b ptr field and the @b len field of the last member of the + * array must be set to #QSE_NULL and 0 respectively. + * + * @return new runtime context on success, #QSE_NULL on failure */ qse_awk_rtx_t* qse_awk_rtx_open ( qse_awk_t* awk, /**< awk object */ qse_size_t xtn, /**< size of extension in bytes */ qse_awk_rio_t* rio, /**< runtime IO handlers */ - const qse_cstr_t* arg /**< arguments to set ARGV */ + const qse_cstr_t* arg /**< argument array to set ARGV */ ); /** @@ -1378,7 +1391,7 @@ void qse_awk_rtx_close ( * } * @endcode * - * @return return value on success, QSE_NULL on failure. + * @return return value on success, #QSE_NULL on failure. */ qse_awk_val_t* qse_awk_rtx_loop ( qse_awk_rtx_t* rtx /**< runtime context */ @@ -1439,7 +1452,6 @@ void qse_awk_rtx_stop ( * The qse_awk_rtx_setrcb() function gets runtime callbacks. * @return #QSE_NULL if no callback is set. Otherwise, the pointer to a * callback set. - * @sa qse_awk_rtx_setrcb */ qse_awk_rcb_t* qse_awk_rtx_getrcb ( qse_awk_rtx_t* rtx /**< runtime context */ @@ -1447,7 +1459,6 @@ qse_awk_rcb_t* qse_awk_rtx_getrcb ( /** * The qse_awk_rtx_setrcb() function sets runtime callbacks. - * @sa qse_awk_rtx_getrcb */ void qse_awk_rtx_setrcb ( qse_awk_rtx_t* rtx, /**< runtime context */ @@ -1540,7 +1551,7 @@ qse_mmgr_t* qse_awk_rtx_getmmgr ( ); /** - * The qse_awk_rtx_getxtn() function gets the pointer to extension space. + * The qse_awk_rtx_getxtn() function gets the pointer to the extension block. */ void* qse_awk_rtx_getxtn ( qse_awk_rtx_t* rtx /**< runtime context */ @@ -1606,7 +1617,7 @@ void qse_awk_rtx_seterrinf ( void qse_awk_rtx_seterror ( qse_awk_rtx_t* rtx, /**< runtime context */ qse_awk_errnum_t errnum, /**< error number */ - const qse_cstr_t* errarg, /**< array of arguments for formatting + const qse_cstr_t* errarg, /**< argument array for formatting * an error message */ const qse_awk_loc_t* errloc /**< error line */ ); @@ -1730,23 +1741,23 @@ qse_bool_t qse_awk_rtx_valtobool ( /** * The qse_awk_rtx_valtostr() function converts a value @a val to a string as * instructed in the parameter out. Before the call to the function, you - * should initialize a variable of the qse_awk_rtx_valtostr_out_t type. + * should initialize a variable of the #qse_awk_rtx_valtostr_out_t type. * * The type field is one of the following qse_awk_rtx_valtostr_type_t values: * - * - QSE_AWK_RTX_VALTOSTR_CPL - * - QSE_AWK_RTX_VALTOSTR_CPLDUP - * - QSE_AWK_RTX_VALTOSTR_STRP - * - QSE_AWK_RTX_VALTOSTR_STRPCAT + * - #QSE_AWK_RTX_VALTOSTR_CPL + * - #QSE_AWK_RTX_VALTOSTR_CPLDUP + * - #QSE_AWK_RTX_VALTOSTR_STRP + * - #QSE_AWK_RTX_VALTOSTR_STRPCAT * - * It can optionally be ORed with QSE_AWK_RTX_VALTOSTR_PRINT. The option + * It can optionally be ORed with #QSE_AWK_RTX_VALTOSTR_PRINT. The option * causes the function to use OFMT for real number conversion. Otherwise, - * it uses CONVFMT. + * it uses @b CONVFMT. * * You should initialize or free other fields before and after the call * depending on the type field as shown below: * - * If you have a static buffer, use QSE_AWK_RTX_VALTOSTR_CPL. + * If you have a static buffer, use #QSE_AWK_RTX_VALTOSTR_CPL. * @code * qse_awk_rtx_valtostr_out_t out; * qse_char_t buf[100]; @@ -1758,7 +1769,7 @@ qse_bool_t qse_awk_rtx_valtobool ( * @endcode * * When unsure of the size of the string after conversion, you can use - * QSE_AWK_RTX_VALTOSTR_CPLDUP. However, you should free the memory block + * #QSE_AWK_RTX_VALTOSTR_CPLDUP. However, you should free the memory block * pointed to by the u.cpldup.ptr field after use. * @code * qse_awk_rtx_valtostr_out_t out; @@ -1769,7 +1780,7 @@ qse_bool_t qse_awk_rtx_valtobool ( * @endcode * * You may like to store the result in a dynamically resizable string. - * Consider QSE_AWK_RTX_VALTOSTR_STRP. + * Consider #QSE_AWK_RTX_VALTOSTR_STRP. * @code * qse_awk_rtx_valtostr_out_t out; * qse_str_t str; @@ -1783,15 +1794,16 @@ qse_bool_t qse_awk_rtx_valtobool ( * @endcode * * If you want to append the converted string to an existing dynamically - * resizable string, QSE_AWK_RTX_VALTOSTR_STRPCAT is the answer. The usage is - * the same as QSE_AWK_RTX_VALTOSTR_STRP except that you have to use the + * resizable string, #QSE_AWK_RTX_VALTOSTR_STRPCAT is the answer. The usage is + * the same as #QSE_AWK_RTX_VALTOSTR_STRP except that you have to use the * u.strpcat field instead of the u.strp field. * * In the context where @a val is determined to be of the type * #QSE_AWK_VAL_STR, you may access its string pointer and length directly * instead of calling this function. * - * @return the pointer to a string converted on success, #QSE_NULL on failure + * @return character pointer to a string converted on success, + * #QSE_NULL on failure */ qse_char_t* qse_awk_rtx_valtostr ( qse_awk_rtx_t* rtx, /**< runtime context */ @@ -1801,7 +1813,7 @@ qse_char_t* qse_awk_rtx_valtostr ( /** * The qse_awk_rtx_valtocpldup() function provides a shortcut to the - * qse_awk_rtx_valtostr() function with the QSE_AWK_RTX_VALTOSTR_CPLDUP type. + * qse_awk_rtx_valtostr() function with the #QSE_AWK_RTX_VALTOSTR_CPLDUP type. * It returns the pointer to a string converted from @a val and stores its * length to memory pointed to by @a len. You should free the returned * memory block after use. See the code snippet below for a simple usage. @@ -1813,7 +1825,8 @@ qse_char_t* qse_awk_rtx_valtostr ( * qse_awk_rtx_free (rtx, ptr); * @endcode * - * @return the pointer to a string converted on success, #QSE_NULL on failure + * @return character pointer to a string converted on success, + * #QSE_NULL on failure */ qse_char_t* qse_awk_rtx_valtocpldup ( qse_awk_rtx_t* rtx, /**< runtime context */ diff --git a/qse/include/qse/awk/std.h b/qse/include/qse/awk/std.h index ae8d7f4e..08a24f10 100644 --- a/qse/include/qse/awk/std.h +++ b/qse/include/qse/awk/std.h @@ -1,5 +1,5 @@ /* - * $Id: std.h 273 2009-08-28 11:58:05Z hyunghwan.chung $ + * $Id: std.h 277 2009-09-02 12:55:55Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -34,7 +34,6 @@ * - add code to treat a function as a value * - add RQ and LQ for more powerful record splitting * - improve performance in qse_awk_rtx_readio() if RS is logner than 2 chars. - * - implement 'include' */ /** diff --git a/qse/include/qse/cmn/pio.h b/qse/include/qse/cmn/pio.h index db5448f9..12b4fa3e 100644 --- a/qse/include/qse/cmn/pio.h +++ b/qse/include/qse/cmn/pio.h @@ -1,5 +1,5 @@ /* - * $Id: pio.h 275 2009-08-30 13:19:02Z hyunghwan.chung $ + * $Id: pio.h 277 2009-09-02 12:55:55Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -27,8 +27,6 @@ * This file defines a piped interface to a child process. You can execute * a child process, read and write to its stdin, stdout, stderr, and terminate * it. It provides more advanced interface than popen() and pclose(). - * - * @example pio.c */ /** diff --git a/qse/include/qse/cmn/sll.h b/qse/include/qse/cmn/sll.h index c187add7..f3172ba5 100644 --- a/qse/include/qse/cmn/sll.h +++ b/qse/include/qse/cmn/sll.h @@ -1,5 +1,5 @@ /* - * $Id: sll.h 90 2009-03-01 09:58:19Z hyunghwan.chung $ + * $Id: sll.h 277 2009-09-02 12:55:55Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -22,149 +22,102 @@ #include #include -/****o* Common/Singly Linked List - * DESCRIPTION - * provides a singly linked list. - * - * #include - ****** +/** @file + * Singly linked list */ -/****t* Common/qse_sll_walk_t - * NAME - * qse_sll_walk_t - define return values for qse_sll_walker_t - * SEE ALSO - * qse_sll_walker_t - * SYNOPSIS +/** + * The qse_sll_walk_t type defines a value that qse_sll_walker_t can return. */ enum qse_sll_walk_t { - QSE_SLL_WALK_STOP = 0, - QSE_SLL_WALK_FORWARD = 1 + QSE_SLL_WALK_STOP = 0, /**< stop traversal */ + QSE_SLL_WALK_FORWARD = 1 /**< traverse to the next node */ }; -/******/ typedef struct qse_sll_t qse_sll_t; typedef struct qse_sll_node_t qse_sll_node_t; typedef enum qse_sll_walk_t qse_sll_walk_t; -/****t* Common/qse_sll_copier_t - * NAME - * qse_sll_copier_t - define a node contruction callback - * DESCRIPTION - * The qse_sll_copier_t defines a callback function for node construction. - * A node is contructed when a user adds data to a list. The user can - * define how the data to add can be maintained in the list. A singly - * linked list not specified with any copiers stores the data pointer and - * the data length into a node. A special copier QSE_SLL_COPIER_INLINE copies - * the contents of the data a user provided into the node. You can use the - * qse_sll_setcopier() function to change the copier. +/** + * The qse_sll_copier_t type defines a callback function for node construction. + * A node is contructed when a user adds data to a list. The user can + * define how the data to add can be maintained in the list. A singly + * linked list not specified with any copiers stores the data pointer and + * the data length into a node. A special copier QSE_SLL_COPIER_INLINE copies + * the contents of the data a user provided into the node. You can use the + * qse_sll_setcopier() function to change the copier. * - * A copier should return the pointer to the copied data. If it fails to copy - * data, it may return QSE_NULL. You need to set a proper freeer to free up - * memory allocated for copy. - * SEE ALSO - * qse_sll_setcopier, qse_sll_getcopier, QSE_SLL_COPIER - * SYNOPSIS + * A copier should return the pointer to the copied data. If it fails to copy + * data, it may return QSE_NULL. You need to set a proper freeer to free up + * memory allocated for copy. */ typedef void* (*qse_sll_copier_t) ( - qse_sll_t* sll /* a map */, - void* dptr /* the pointer to data to copy */, - qse_size_t dlen /* the length of data to copy */ + qse_sll_t* sll, /**< singly linked list */ + void* dptr, /**< pointer to data to copy */ + qse_size_t dlen /**< length of data to copy */ ); -/******/ -/****t* Common/qse_sll_freeer_t - * NAME - * qse_sll_freeer_t - define a node destruction callback - * SYNOPSIS +/** + * The qse_sll_freeer_t type defines a node destruction callback. */ typedef void (*qse_sll_freeer_t) ( - qse_sll_t* sll /* a map */, - void* dptr /* the pointer to data to free */, - qse_size_t dlen /* the length of data to free */ + qse_sll_t* sll, /**< singly linked list */ + void* dptr, /**< pointer to data to free */ + qse_size_t dlen /**< length of data to free */ ); -/******/ -/****t* Common/qse_sll_comper_t - * NAME - * qse_sll_comper_t - define a data comparator +/** + * The qse_sll_comper_t type defines a key comparator that is called when + * the list needs to compare data. A singly linked list is created with a + * default comparator that performs bitwise comparison. * - * DESCRIPTION - * The qse_sll_comper_t type defines a key comparator that is called when - * the list needs to compare data. A singly linked list is created with a - * default comparator that performs bitwise comparison. - * - * The comparator should return 0 if the data are the same and a non-zero - * integer otherwise. - * - * SYNOPSIS + * The comparator must return 0 if the data are the same and a non-zero + * integer otherwise. */ typedef int (*qse_sll_comper_t) ( - qse_sll_t* sll /* a singly linked list */, - const void* dptr1 /* a data pointer */, - qse_size_t dlen1 /* a data length */, - const void* dptr2 /* a data pointer */, - qse_size_t dlen2 /* a data length */ + qse_sll_t* sll, /**< singly linked list */ + const void* dptr1, /**< data pointer */ + qse_size_t dlen1, /**< data length */ + const void* dptr2, /**< data pointer */ + qse_size_t dlen2 /**< data length */ ); -/******/ -/****t* Common/qse_sll_walker_t - * NAME - * qse_sll_walker_t - define a list traversal callback for each node - * - * DESCRIPTION - * The qse_sll_walk() calls a callback function of the type qse_sll_walker_t - * for each node until it returns QSE_SLL_WALK_STOP. The walker should return - * QSE_SLL_WALK_FORWARD to let qse_sll_walk() continue visiting the next node. - * The third parameter to qse_sll_walk() is passed to the walker as the third - * parameter. - * - * SEE ALSO - * qse_sll_walk, qse_sll_walk_t - * - * SYNOPSIS +/** + * The qse_sll_walker_t type defines a list traversal callback for each node. + * The qse_sll_walk() calls a callback function of the type qse_sll_walker_t + * for each node until it returns QSE_SLL_WALK_STOP. The walker should return + * QSE_SLL_WALK_FORWARD to let qse_sll_walk() continue visiting the next node. + * The third parameter to qse_sll_walk() is passed to the walker as the third + * parameter. */ typedef qse_sll_walk_t (*qse_sll_walker_t) ( - qse_sll_t* sll /* a map */, - qse_sll_node_t* node /* a visited node */, - void* arg /* user-defined data */ + qse_sll_t* sll, /* singly linked list */ + qse_sll_node_t* node, /* visited node */ + void* arg /* user-defined data */ ); /******/ -/****s* Common/qse_sll_t - * NAME - * qse_sll_t - define a singly linked list - * - * DESCRPTION - * The qse_sll_t type defines a singly lnked list. - * - * SYNOPSIS +/** + * The qse_sll_t type defines a singly lnked list. */ struct qse_sll_t { QSE_DEFINE_COMMON_FIELDS (sll) - qse_sll_copier_t copier; /* data copier */ - qse_sll_freeer_t freeer; /* data freeer */ - qse_sll_comper_t comper; /* data comparator */ - qse_byte_t scale; /* scale factor */ + qse_sll_copier_t copier; /**< data copier */ + qse_sll_freeer_t freeer; /**< data freeer */ + qse_sll_comper_t comper; /**< data comparator */ + qse_byte_t scale; /**< scale factor */ - qse_size_t size; /* the number of nodes */ - qse_sll_node_t* head; /* the head node */ - qse_sll_node_t* tail; /* the tail node */ + qse_size_t size; /**< number of nodes */ + qse_sll_node_t* head; /**< head node */ + qse_sll_node_t* tail; /**< tail node */ }; -/******/ -/****s* Common/qse_sll_node_t - * NAME - * qse_sll_node_t - define a list node - * DESCRIPTION - * The qse_sll_node_t type defines a list node containing a data pointer and - * and data length. - * SEE ALSO - * QSE_SLL_DPTR, QSE_SLL_DLEN, QSE_SLL_NEXT - * SYNOPSIS +/** + * The qse_sll_node_t type defines a list node containing a data pointer and + * and data length. */ struct qse_sll_node_t { @@ -172,7 +125,6 @@ struct qse_sll_node_t qse_size_t dlen; /* the length of data */ qse_sll_node_t* next; /* the pointer to the next node */ }; -/******/ #define QSE_SLL_COPIER_SIMPLE ((qse_sll_copier_t)1) #define QSE_SLL_COPIER_INLINE ((qse_sll_copier_t)2) @@ -186,29 +138,20 @@ struct qse_sll_node_t #define QSE_SLL_SIZE(sll) ((sll)->size) #define QSE_SLL_SCALE(sll) ((sll)->scale) -/****m* Common/QSE_SLL_DPTR - * NAME - * QSE_SLL_DPTR - get the data pointer in a node - * SYNOPSIS +/** + * The QSE_SLL_DPTR macro gets the data pointer in a node. */ #define QSE_SLL_DPTR(node) ((node)->dptr) -/******/ -/****m* Common/QSE_SLL_DLEN - * NAME - * QSE_SLL_DLEN - get the length of data in a node - * SYNOPSIS +/** + * The QSE_SLL_DLEN macro gets the length of data in a node. */ #define QSE_SLL_DLEN(node) ((node)->dlen) -/******/ -/****m* Common/QSE_SLL_NEXT - * NAME - * QSE_SLL_NEXT - get the next node - * SYNOPSIS +/** + * The QSE_SLL_NEXT macro gets the next node. */ #define QSE_SLL_NEXT(node) ((node)->next) -/******/ #ifdef __cplusplus extern "C" { @@ -216,35 +159,27 @@ extern "C" { QSE_DEFINE_COMMON_FUNCTIONS (sll) -/****f* Common/qse_sll_open - * NAME - * qse_sll_open - create a singly linked list with extension area +/** + * The qse_sll_open() function creates an empty singly linked list. + * If the memory manager mmgr is QSE_NULL, the function gets the default + * memory manager with QSE_MMGR_GETDFL() and uses it if it is not QSE_NULL. + * The extension area is allocated when the positive extension size extension + * is specified. It calls the extension initialization function initializer + * after initializing the main area. The extension initializer is passed + * the pointer to the singly linked list created. * - * DESCRIPTION - * The qse_sll_open() function creates an empty singly linked list. - * If the memory manager mmgr is QSE_NULL, the function gets the default - * memory manager with QSE_MMGR_GETMMGR() and uses it if it is not QSE_NULL. - * The extension area is allocated when the positive extension size extension - * is specified. It calls the extension initialization function initializer - * after initializing the main area. The extension initializer is passed - * the pointer to the singly linked list created. + * @return pointer to a new singly linked list on success, + * QSE_NULL on failure * - * RETURN - * The qse_sll_open() function returns the pointer to a new singly linked - * list on success and QSE_NULL on failure. - * - * NOTES - * In the debug build, it fails an assertion if QSE_MMGR_GETMMGR() returns - * QSE_NULL when QSE_NULL is passed as the first parameter. In the release - * build, it returns QSE_NULL if such a thing happens. - * - * SYNOPSIS + * @note + * In the debug build, it fails an assertion if QSE_MMGR_GETDFL() returns + * QSE_NULL and @a mmgr is QSE_NULL. In the release build, it returns QSE_NULL + * in such case. */ qse_sll_t* qse_sll_open ( - qse_mmgr_t* mmgr /* memory manager */ , + qse_mmgr_t* mmgr, /* memory manager */ qse_size_t ext /* size of extension area in bytes */ ); -/******/ /****f* Common/qse_sll_close * NAME diff --git a/qse/include/qse/cmn/str.h b/qse/include/qse/cmn/str.h index 5f8cb48c..131fe490 100644 --- a/qse/include/qse/cmn/str.h +++ b/qse/include/qse/cmn/str.h @@ -1,5 +1,5 @@ /* - * $Id: str.h 140 2009-05-18 12:55:01Z hyunghwan.chung $ + * $Id: str.h 277 2009-09-02 12:55:55Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -28,8 +28,6 @@ * * The qse_cstr_t type and the qse_xstr_t defined in helps you * dealing with a string pointer and length. - * - * @example str.c */ #define QSE_STR_LEN(s) ((s)->len) diff --git a/qse/include/qse/sed/sed.h b/qse/include/qse/sed/sed.h index 75fb8054..0e74719d 100644 --- a/qse/include/qse/sed/sed.h +++ b/qse/include/qse/sed/sed.h @@ -1,5 +1,5 @@ /* - * $Id: sed.h 276 2009-08-31 13:24:06Z hyunghwan.chung $ + * $Id: sed.h 277 2009-09-02 12:55:55Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -41,8 +41,8 @@ */ /** - * @example sed01.c - * This example shows how to embed a basic stream editor. + * @example sed.c + * This example shows how to write a basic stream editor. */ /** @struct qse_sed_t @@ -200,6 +200,16 @@ typedef qse_ssize_t (*qse_sed_io_fun_t) ( qse_sed_io_arg_t* arg ); +/** + * The qse_sed_lformatter_t type defines a text formatter for the 'l' command. + */ +typedef int (*qse_sed_lformatter_t) ( + qse_sed_t* sed, + const qse_char_t* str, + qse_size_t len, + int (*cwriter) (qse_sed_t*, qse_char_t) +); + #ifdef __cplusplus extern "C" { #endif @@ -390,6 +400,24 @@ int qse_sed_exec ( qse_sed_io_fun_t outf /**< stream writer */ ); +/** + * The qse_sed_getlformatter() function gets the text formatter for the 'l' + * command. + */ +qse_sed_lformatter_t qse_sed_getlformatter ( + qse_sed_t* sed /**< stream editor */ +); + +/** + * The qse_sed_setlformatter() function sets the text formatter for the 'l' + * command. The text formatter must output the text with a character writer + * provided and return -1 on failure and 0 on success. + */ +void qse_sed_setlformatter ( + qse_sed_t* sed, /**< stream editor */ + qse_sed_lformatter_t lformatter /**< text formatter */ +); + /** * The qse_sed_getlinnum() function gets the current input line number. * @return current input line number diff --git a/qse/lib/awk/fnc.c b/qse/lib/awk/fnc.c index bfbc485f..258a19ac 100644 --- a/qse/lib/awk/fnc.c +++ b/qse/lib/awk/fnc.c @@ -1,5 +1,5 @@ /* - * $Id: fnc.c 274 2009-08-28 12:47:09Z hyunghwan.chung $ + * $Id: fnc.c 277 2009-09-02 12:55:55Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -1080,18 +1080,22 @@ static int __substitute (qse_awk_rtx_t* run, qse_long_t max_count) * end of string($) needs to be tested */ while (cur_ptr <= a2_end) { + qse_awk_errnum_t errnum; + if (max_count == 0 || sub_count < max_count) { n = QSE_AWK_MATCHREX ( run->awk, rex, opt, a2_ptr, a2_len, cur_ptr, cur_len, - &mat, &run->errinf.num); + &mat, &errnum + ); } else n = 0; - if (n == -1) + if (n <= -1) { + qse_awk_rtx_seterrnum (run, errnum, QSE_NULL); FREE_A0_REX (run->awk, rex); qse_str_fini (&new); FREE_A_PTRS (run->awk); @@ -1262,8 +1266,9 @@ static int fnc_match (qse_awk_rtx_t* run, const qse_cstr_t* fnm) qse_size_t len0, len1; qse_long_t idx; void* rex; - int opt, n; + int n; qse_cstr_t mat; + qse_awk_errnum_t errnum; nargs = qse_awk_rtx_getnargs (run); QSE_ASSERT (nargs == 2); @@ -1315,17 +1320,21 @@ static int fnc_match (qse_awk_rtx_t* run, const qse_cstr_t* fnm) if (a1->type != QSE_AWK_VAL_STR) QSE_AWK_FREE (run->awk, str1); } - opt = (run->gbl.ignorecase)? QSE_REX_MATCH_IGNORECASE: 0; n = QSE_AWK_MATCHREX ( - run->awk, rex, opt, + run->awk, rex, + (run->gbl.ignorecase? QSE_REX_MATCH_IGNORECASE: 0), str0, len0, str0, len0, - &mat, &run->errinf.num + &mat, &errnum ); if (a0->type != QSE_AWK_VAL_STR) QSE_AWK_FREE (run->awk, str0); if (a1->type != QSE_AWK_VAL_REX) QSE_AWK_FREEREX (run->awk, rex); - if (n == -1) return -1; + if (n <= -1) + { + qse_awk_rtx_seterrnum (run, errnum, QSE_NULL); + return -1; + } idx = (n == 0)? 0: ((qse_long_t)(mat.ptr-str0) + 1); diff --git a/qse/lib/awk/rio.c b/qse/lib/awk/rio.c index def9d0ad..9e499ffb 100644 --- a/qse/lib/awk/rio.c +++ b/qse/lib/awk/rio.c @@ -1,5 +1,5 @@ /* - * $Id: rio.c 272 2009-08-28 09:48:02Z hyunghwan.chung $ + * $Id: rio.c 277 2009-09-02 12:55:55Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -272,6 +272,7 @@ int qse_awk_rtx_readio ( * after the previous matchrex has failed */ qse_cstr_t match; + qse_awk_errnum_t errnum; QSE_ASSERT (run->gbl.rs != QSE_NULL); @@ -280,9 +281,10 @@ int qse_awk_rtx_readio ( ((run->gbl.ignorecase)? QSE_REX_MATCH_IGNORECASE: 0), QSE_STR_PTR(buf), QSE_STR_LEN(buf), QSE_STR_PTR(buf), QSE_STR_LEN(buf), - &match, &run->errinf.num); + &match, &errnum); if (n <= -1) { + qse_awk_rtx_seterrnum (run, errnum, QSE_NULL); ret = -1; break; } @@ -360,6 +362,7 @@ int qse_awk_rtx_readio ( else { qse_cstr_t match; + qse_awk_errnum_t errnum; /* TODO: minimize the number of regular expressoin match here... * currently matchrex is called for each character added to buf. @@ -372,9 +375,10 @@ int qse_awk_rtx_readio ( ((run->gbl.ignorecase)? QSE_REX_MATCH_IGNORECASE: 0), QSE_STR_PTR(buf), QSE_STR_LEN(buf), QSE_STR_PTR(buf), QSE_STR_LEN(buf), - &match, &run->errinf.num); + &match, &errnum); if (n <= -1) { + qse_awk_rtx_seterrnum (run, errnum, QSE_NULL); ret = -1; p->in.pos--; /* unread the character in c */ break; diff --git a/qse/lib/awk/run.c b/qse/lib/awk/run.c index c4dbc6b6..580cb5a4 100644 --- a/qse/lib/awk/run.c +++ b/qse/lib/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c 267 2009-08-25 09:50:07Z hyunghwan.chung $ + * $Id: run.c 277 2009-09-02 12:55:55Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -403,11 +403,13 @@ static int set_global ( if (fs_len > 1) { void* rex; + qse_awk_errnum_t errnum; rex = QSE_AWK_BUILDREX ( - rtx->awk, fs_ptr, fs_len, &rtx->errinf.num); + rtx->awk, fs_ptr, fs_len, &errnum); if (rex == QSE_NULL) { + SETERR_COD (rtx, errnum); if (val->type != QSE_AWK_VAL_STR) QSE_AWK_FREE (rtx->awk, fs_ptr); return -1; @@ -564,11 +566,14 @@ static int set_global ( if (rs_len > 1) { void* rex; + qse_awk_errnum_t errnum; + /* compile the regular expression */ rex = QSE_AWK_BUILDREX ( - rtx->awk, rs_ptr, rs_len, &rtx->errinf.num); + rtx->awk, rs_ptr, rs_len, &errnum); if (rex == QSE_NULL) { + SETERR_COD (rtx, errnum); if (val->type != QSE_AWK_VAL_STR) QSE_AWK_FREE (rtx->awk, rs_ptr); return -1; diff --git a/qse/lib/awk/tree.c b/qse/lib/awk/tree.c index dc815ae3..8bfd6e50 100644 --- a/qse/lib/awk/tree.c +++ b/qse/lib/awk/tree.c @@ -1,5 +1,5 @@ /* - * $Id: tree.c 265 2009-08-24 01:50:38Z hyunghwan.chung $ + * $Id: tree.c 277 2009-09-02 12:55:55Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -295,6 +295,10 @@ static int print_expr (qse_awk_t* awk, qse_awk_nde_t* nde) PUT_SRCSTR (awk, QSE_T("\\a")); else if (ptr[i] == QSE_T('\0')) PUT_SRCSTR (awk, QSE_T("\\0")); + else if (ptr[i] == QSE_T('\"')) + PUT_SRCSTR (awk, QSE_T("\\\"")); + else if (ptr[i] == QSE_T('\\')) + PUT_SRCSTR (awk, QSE_T("\\\\")); else PUT_SRCSTRX (awk, &ptr[i], 1); } diff --git a/qse/lib/sed/sed.c b/qse/lib/sed/sed.c index 7ceeb892..00776dcc 100644 --- a/qse/lib/sed/sed.c +++ b/qse/lib/sed/sed.c @@ -1,5 +1,5 @@ /* - * $Id: sed.c 276 2009-08-31 13:24:06Z hyunghwan.chung $ + * $Id: sed.c 277 2009-09-02 12:55:55Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -1704,10 +1704,10 @@ static int write_str_clearly ( if (QSE_ISPRINT(c)) WRITE_CHAR (sed, c); else { -# ifdef QSE_CHAR_IS_MCHAR + #ifdef QSE_CHAR_IS_MCHAR WRITE_CHAR (sed, QSE_T('\\')); WRITE_NUM (sed, c, 8, QSE_SIZEOF(qse_char_t)*3); -# else + #else if (QSE_SIZEOF(qse_char_t) <= 2) { WRITE_STR (sed, QSE_T("\\u"), 2); @@ -1717,7 +1717,7 @@ static int write_str_clearly ( WRITE_STR (sed, QSE_T("\\U"), 2); } WRITE_NUM (sed, c, 16, QSE_SIZEOF(qse_char_t)*2); -# endif + #endif } } } @@ -2296,11 +2296,22 @@ static qse_sed_cmd_t* exec_cmd (qse_sed_t* sed, qse_sed_cmd_t* cmd) break; case QSE_SED_CMD_PRINT_CLEARLY: - n = write_str_clearly ( - sed, - QSE_STR_PTR(&sed->e.in.line), - QSE_STR_LEN(&sed->e.in.line) - ); + if (sed->lformatter) + { + n = sed->lformatter ( + sed, + QSE_STR_PTR(&sed->e.in.line), + QSE_STR_LEN(&sed->e.in.line), + write_char + ); + } + else { + n = write_str_clearly ( + sed, + QSE_STR_PTR(&sed->e.in.line), + QSE_STR_LEN(&sed->e.in.line) + ); + } if (n <= -1) return QSE_NULL; break; @@ -2761,6 +2772,16 @@ done3: return ret; } +qse_sed_lformatter_t qse_sed_getlformatter (qse_sed_t* sed) +{ + return sed->lformatter; +} + +void qse_sed_setlformatter (qse_sed_t* sed, qse_sed_lformatter_t lf) +{ + sed->lformatter = lf; +} + qse_size_t qse_sed_getlinnum (qse_sed_t* sed) { return sed->e.in.num; diff --git a/qse/lib/sed/sed.h b/qse/lib/sed/sed.h index 0dbc55a6..fe6c581a 100644 --- a/qse/lib/sed/sed.h +++ b/qse/lib/sed/sed.h @@ -1,5 +1,5 @@ /* - * $Id: sed.h 269 2009-08-26 03:03:51Z hyunghwan.chung $ + * $Id: sed.h 277 2009-09-02 12:55:55Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -147,6 +147,8 @@ struct qse_sed_t int option; /**< stores options */ + qse_sed_lformatter_t lformatter; + struct { struct diff --git a/qse/regress/awk/lang-035.awk b/qse/regress/awk/lang-035.awk new file mode 100644 index 00000000..3690d2c1 --- /dev/null +++ b/qse/regress/awk/lang-035.awk @@ -0,0 +1,72 @@ +BEGIN { + # the maximum numbers of different voice + # numbers for a single circuit ID + max_cid_vars = 100; + + first = 1; + while ((getline x < datafile) > 0) + { + # check if it is the first line. + if (first) + { + # skip it if so + first = 0; + continue; + } + + # split a line into fields + n = split (x, f, ","); + if (n < 3) continue; + + # filter out data with an empty number. + if (f[3] == "") continue; + + # store unique voice numbers to a table + for (suffix = 0; suffix < max_cid_vars; suffix++) + { + oldval = tab[f[2],suffix]; + if (oldval == "") + { + # store a cid/val pair into a table + tab[f[2],suffix] = f[3]; + break; + } + } + } +} + +/^lease[[:space:]]+.+[[:space:]]*{[[:space:]]*$/ { + # reset the counter for each "lease x.x.x.x {" line + voice_no=0; +} + +{ + if ($1 == "option" && $2 == "agent.circuit-id") + { + # extract the circuit ID + pos = index ($0, "agent.circuit-id ") + len = length($0); + + last = substr ($0, len, 1); + adj = 0; if (last != ";") adj++; + cid = substr ($0, pos + 17, length($0) - (pos + 17 + adj)); + + # insert all instances of voice numbers for a circuit ID + for (suffix = 0; suffix < max_cid_vars; suffix++) + { + val = tab[cid,suffix]; + if (val == "") break; + + print " info awk.voice-no-" voice_no " " val ";"; + voice_no++; + } + } + + print $0; + + if ($1 == "hardware" && $2 == "ethernet") + { + # append group information + print " info awk.groupname \"" groupname "\";"; + } +} diff --git a/qse/regress/awk/lang-035.dat1 b/qse/regress/awk/lang-035.dat1 new file mode 100644 index 00000000..383863d5 --- /dev/null +++ b/qse/regress/awk/lang-035.dat1 @@ -0,0 +1,13 @@ +"ID","CIRCUIT_LINE_ID","MIO_NO","SS_IND","CRD","R" +"1","AL_AM3_LAB atm 1/1/01/01:2.100","68599017","OC2","16-JUL-09","1" +"2","AR_Remote atm 1/1/03/02:2.100","68599018","OC2","16-JUL-09","2" +"3","AR_Remote atm 1/1/03/03:2.100","68599015","OC2","16-JUL-09","3" +"4","AR_Remote atm 1/1/03/11:2.100","68599016","OC2","16-JUL-09","4" +"5","AR_Remote atm 1/1/03/12:2.100","68599019","OC2","16-JUL-09","5" +"6","AR_Remote atm 1/1/03/15:2.100","68599010","OC2","16-JUL-09","6" +"7","BLM1500_AR3_ILAB ONT/9/1/2 /0.0","68599011","OC2","16-JUL-09","7" +"8","BLM1500_AR3_ILAB ONT/9/2/1 /0.0","68599012","OC2","16-JUL-09","8" +"9","AL_AM3_LAB atm 1/1/01/01:2.100","68599013","OC2","16-JUL-09","9" +"10","AR_Remote atm 1/1/03/12:2.100","68599014","OC2","16-JUL-09","10" +"11","BLM1500_AR3_ILAB ONT/9/1/1 /0.0","68599021","OC2","16-JUL-09","11" +"12","BLM1500_AR3_ILAB ONT/9/2/2 /0.0","68599022","OC2","16-JUL-09","12" diff --git a/qse/regress/awk/lang-035.dat2 b/qse/regress/awk/lang-035.dat2 new file mode 100644 index 00000000..d5c1eb88 --- /dev/null +++ b/qse/regress/awk/lang-035.dat2 @@ -0,0 +1,159 @@ +# The format of this file is documented in the dhcpd.leases(5) manual page. +# This lease file was written by isc-dhcp-V3.1.1 + +lease 20.1.20.52 { + starts 5 2009/08/07 08:33:03; + ends 5 2009/08/07 08:38:14; + tstp 5 2009/08/07 08:38:14; + cltt 5 2009/08/07 08:33:03; + binding state free; + hardware ethernet 00:13:5e:4f:d2:d3; +} +lease 20.1.20.57 { + starts 1 2009/08/10 09:04:12; + ends 2 2009/08/11 09:04:12; + cltt 1 2009/08/10 09:04:12; + binding state active; + next binding state free; + hardware ethernet 00:13:5e:50:23:6b; + option agent.circuit-id "BLM1500_AR3_ILAB ONT/9/1/1 /0.0"; + option agent.unknown-9 0:0:0:c1:8:45:52:49:43:53:53:4f:4e; +} +lease 20.1.20.54 { + starts 1 2009/08/10 09:04:16; + ends 2 2009/08/11 09:04:16; + cltt 1 2009/08/10 09:04:16; + binding state active; + next binding state free; + hardware ethernet 00:13:5e:50:25:aa; + option agent.circuit-id "BLM1500_AR3_ILAB ONT/9/1/2 /0.0"; + option agent.unknown-9 0:0:0:c1:8:45:52:49:43:53:53:4f:4e; +} +lease 20.1.20.55 { + starts 1 2009/08/10 13:53:08; + ends 2 2009/08/11 13:53:08; + cltt 1 2009/08/10 13:53:08; + binding state active; + next binding state free; + hardware ethernet 00:13:5e:50:20:af; + option agent.circuit-id "BLM1500_AR3_ILAB ONT/9/2/1 /0.0"; + option agent.unknown-9 0:0:0:c1:8:45:52:49:43:53:53:4f:4e; +} +lease 20.1.20.56 { + starts 1 2009/08/10 13:53:42; + ends 2 2009/08/11 13:53:42; + cltt 1 2009/08/10 13:53:42; + binding state active; + next binding state free; + hardware ethernet 00:13:5e:50:20:29; + option agent.circuit-id "BLM1500_AR3_ILAB ONT/9/2/2 /0.0"; + option agent.unknown-9 0:0:0:c1:8:45:52:49:43:53:53:4f:4e; +} +lease 10.218.255.53 { + starts 5 2009/08/07 08:18:04; + ends 5 2009/08/07 08:28:04; + tstp 5 2009/08/07 08:28:04; + cltt 5 2009/08/07 08:18:04; + binding state free; + hardware ethernet 00:1b:5b:9c:4f:7d; + uid "\001\000\033[\234O}"; +} +lease 10.218.255.54 { + starts 5 2009/08/07 08:32:37; + ends 5 2009/08/07 08:42:37; + tstp 5 2009/08/07 08:42:37; + cltt 5 2009/08/07 08:32:37; + binding state free; + hardware ethernet 00:1b:5b:9c:1b:35; + uid "\001\000\033[\234\0335"; +} +lease 10.218.255.59 { + starts 5 2009/08/07 10:39:01; + ends 6 2009/08/08 10:29:45; + tstp 6 2009/08/08 10:29:45; + cltt 5 2009/08/07 10:39:01; + binding state free; + hardware ethernet 00:1f:b3:79:7e:30; + uid "\001\000\037\263y~0"; +} +lease 10.218.255.58 { + starts 0 2009/08/09 14:21:00; + ends 1 2009/08/10 09:13:42; + tstp 1 2009/08/10 09:13:42; + cltt 0 2009/08/09 14:21:00; + binding state free; + hardware ethernet 00:19:e4:43:0e:c8; + uid "\001\000\031\344C\016\310"; +} +lease 10.218.255.55 { + starts 1 2009/08/10 09:02:31; + ends 2 2009/08/11 09:02:31; + cltt 1 2009/08/10 09:02:31; + binding state active; + next binding state free; + hardware ethernet 00:1b:5b:9c:90:00; + uid "\001\000\033[\234\220\000"; + option agent.circuit-id "AR_Remote atm 1/1/03/12:2.100"; + option agent.remote-id "22M-fast"; +} +lease 10.218.255.52 { + starts 1 2009/08/10 09:04:04; + ends 2 2009/08/11 09:04:04; + cltt 1 2009/08/10 09:04:04; + binding state active; + next binding state free; + hardware ethernet 00:1b:5b:9c:81:35; + uid "\001\000\033[\234\2015"; +} +lease 10.218.255.56 { + starts 1 2009/08/10 09:06:09; + ends 2 2009/08/11 09:06:09; + cltt 1 2009/08/10 09:06:09; + binding state active; + next binding state free; + hardware ethernet 00:1e:c7:fb:29:7d; + uid "\001\000\036\307\373)}"; +} +lease 10.218.255.57 { + starts 1 2009/08/10 09:14:33; + ends 2 2009/08/11 09:14:33; + cltt 1 2009/08/10 09:14:33; + binding state active; + next binding state free; + hardware ethernet 00:1e:c7:fb:29:4d; + uid "\001\000\036\307\373)M"; +} +lease 10.218.255.66 { + starts 1 2009/08/10 13:57:24; + ends 2 2009/08/11 13:57:24; + cltt 1 2009/08/10 13:57:24; + binding state active; + next binding state free; + hardware ethernet 00:1a:04:f9:e2:90; + uid "\001\000\032\004\371\342\220"; + option agent.circuit-id "AR_Remote atm 1/1/03/02:2.100"; + option agent.remote-id "3play"; +} +lease 10.218.255.60 { + starts 1 2009/08/10 17:25:17; + ends 2 2009/08/11 17:25:17; + cltt 1 2009/08/10 17:25:17; + binding state active; + next binding state free; + hardware ethernet 00:1e:c7:fb:29:1d; + uid "\001\000\036\307\373)\035"; + option agent.circuit-id "AL_AM3_LAB atm 1/1/01/01:2.100"; + option agent.remote-id "Testing DHCP"; +} +# The format of this file is documented in the dhcpd.leases(5) manual page. +# This lease file was written by isc-dhcp-V3.1.1 + +lease 10.218.255.151 { + starts 5 2009/08/07 08:09:38; + ends 5 2009/08/07 08:13:59; + tstp 5 2009/08/07 08:13:59; + cltt 5 2009/08/07 08:09:38; + binding state free; + hardware ethernet 00:1b:5b:9c:90:00; + uid "\001\000\033[\234\220\000"; +} diff --git a/qse/regress/awk/regress.out b/qse/regress/awk/regress.out index 9e784954..12283de8 100644 --- a/qse/regress/awk/regress.out +++ b/qse/regress/awk/regress.out @@ -1154,88 +1154,88 @@ BEGIN { print "1.1==1 :",(1.1 == 1); print "1.0!=1 :",(1.0 != 1); print "1.1!=1 :",(1.1 != 1); - print ""abc" == "abc"",("abc" == "abc"); - print ""abc" != "abc"",("abc" != "abc"); + print "\"abc\" == \"abc\"",("abc" == "abc"); + print "\"abc\" != \"abc\"",("abc" != "abc"); print "--------------------------"; - print "a == "" :",(a == ""); - print "a >= "" :",(a >= ""); - print "a <= "" :",(a <= ""); - print "a > "" :",(a > ""); - print "a < "" :",(a < ""); + print "a == \"\" :",(a == ""); + print "a >= \"\" :",(a >= ""); + print "a <= \"\" :",(a <= ""); + print "a > \"\" :",(a > ""); + print "a < \"\" :",(a < ""); print "--------------------------"; - print "a == " " :",(a == " "); - print "a >= " " :",(a >= " "); - print "a <= " " :",(a <= " "); - print "a > " " :",(a > " "); - print "a < " " :",(a < " "); + print "a == \" \" :",(a == " "); + print "a >= \" \" :",(a >= " "); + print "a <= \" \" :",(a <= " "); + print "a > \" \" :",(a > " "); + print "a < \" \" :",(a < " "); print "--------------------------"; - print """ == a :",("" == a); - print """ >= a:",("" >= a); - print """ <= a:",("" <= a); - print """ > a:",("" > a); - print """ < a:",("" < a); + print "\"\" == a :",("" == a); + print "\"\" >= a:",("" >= a); + print "\"\" <= a:",("" <= a); + print "\"\" > a:",("" > a); + print "\"\" < a:",("" < a); print "--------------------------"; - print "" " == a :",(" " == a); - print "" " >= a:",(" " >= a); - print "" " <= a:",(" " <= a); - print "" " > a:",(" " > a); - print "" " < a:",(" " < a); + print "\" \" == a :",(" " == a); + print "\" \" >= a:",(" " >= a); + print "\" \" <= a:",(" " <= a); + print "\" \" > a:",(" " > a); + print "\" \" < a:",(" " < a); print "--------------------------"; - print "10 == "10"",(10 == "10"); - print "10 != "10"",(10 != "10"); - print "10 >= "10"",(10 >= "10"); - print "10 <= "10"",(10 <= "10"); - print "10 > "10"",(10 > "10"); - print "10 < "10"",(10 < "10"); + print "10 == \"10\"",(10 == "10"); + print "10 != \"10\"",(10 != "10"); + print "10 >= \"10\"",(10 >= "10"); + print "10 <= \"10\"",(10 <= "10"); + print "10 > \"10\"",(10 > "10"); + print "10 < \"10\"",(10 < "10"); print "--------------------------"; - print "10 == "11"",(10 == "11"); - print "10 != "11"",(10 != "11"); - print "10 >= "11"",(10 >= "11"); - print "10 <= "11"",(10 <= "11"); - print "10 > "11"",(10 > "11"); - print "10 < "11"",(10 < "11"); + print "10 == \"11\"",(10 == "11"); + print "10 != \"11\"",(10 != "11"); + print "10 >= \"11\"",(10 >= "11"); + print "10 <= \"11\"",(10 <= "11"); + print "10 > \"11\"",(10 > "11"); + print "10 < \"11\"",(10 < "11"); print "--------------------------"; - print "11 == "10"",(11 == "10"); - print "11 != "10"",(11 != "10"); - print "11 >= "10"",(11 >= "10"); - print "11 <= "10"",(11 <= "10"); - print "11 > "10"",(11 > "10"); - print "11 < "10"",(11 < "10"); + print "11 == \"10\"",(11 == "10"); + print "11 != \"10\"",(11 != "10"); + print "11 >= \"10\"",(11 >= "10"); + print "11 <= \"10\"",(11 <= "10"); + print "11 > \"10\"",(11 > "10"); + print "11 < \"10\"",(11 < "10"); print "--------------------------"; - print "010 == "8"",(010 == "8"); - print "010 != "8"",(010 != "8"); - print "010 >= "8"",(010 >= "8"); - print "010 <= "8"",(010 <= "8"); - print "010 > "8"",(010 > "8"); - print "010 < "8"",(010 < "8"); + print "010 == \"8\"",(010 == "8"); + print "010 != \"8\"",(010 != "8"); + print "010 >= \"8\"",(010 >= "8"); + print "010 <= \"8\"",(010 <= "8"); + print "010 > \"8\"",(010 > "8"); + print "010 < \"8\"",(010 < "8"); print "--------------------------"; - print "10 == "10.0"",(10 == "10.0"); - print "10 != "10.0"",(10 != "10.0"); - print "10 >= "10.0"",(10 >= "10.0"); - print "10 <= "10.0"",(10 <= "10.0"); - print "10 > "10.0"",(10 > "10.0"); - print "10 < "10.0"",(10 < "10.0"); + print "10 == \"10.0\"",(10 == "10.0"); + print "10 != \"10.0\"",(10 != "10.0"); + print "10 >= \"10.0\"",(10 >= "10.0"); + print "10 <= \"10.0\"",(10 <= "10.0"); + print "10 > \"10.0\"",(10 > "10.0"); + print "10 < \"10.0\"",(10 < "10.0"); print "--------------------------"; - print "10.0 == "10"",(10.0 == "10"); - print "10.0 != "10"",(10.0 != "10"); - print "10.0 >= "10"",(10.0 >= "10"); - print "10.0 <= "10"",(10.0 <= "10"); - print "10.0 > "10"",(10.0 > "10"); - print "10.0 < "10"",(10.0 < "10"); + print "10.0 == \"10\"",(10.0 == "10"); + print "10.0 != \"10\"",(10.0 != "10"); + print "10.0 >= \"10\"",(10.0 >= "10"); + print "10.0 <= \"10\"",(10.0 <= "10"); + print "10.0 > \"10\"",(10.0 > "10"); + print "10.0 < \"10\"",(10.0 < "10"); print "--------------------------"; - print ""10" == 10.0",("10" == 10.0); - print ""10" != 10.0",("10" != 10.0); - print ""10" >= 10.0",("10" >= 10.0); - print ""10" <= 10.0",("10" <= 10.0); - print ""10" > 10.0",("10" > 10.0); - print ""10" < 10.0",("10" < 10.0); + print "\"10\" == 10.0",("10" == 10.0); + print "\"10\" != 10.0",("10" != 10.0); + print "\"10\" >= 10.0",("10" >= 10.0); + print "\"10\" <= 10.0",("10" <= 10.0); + print "\"10\" > 10.0",("10" > 10.0); + print "\"10\" < 10.0",("10" < 10.0); print "--------------------------"; - print ""10" == 10.1",("10" == 10.1); - print ""10" != 10.1",("10" != 10.1); - print ""10" >= 10.1",("10" >= 10.1); - print ""10" <= 10.1",("10" <= 10.1); - print ""10" > 10.1",("10" > 10.1); - print ""10" < 10.1",("10" < 10.1); + print "\"10\" == 10.1",("10" == 10.1); + print "\"10\" != 10.1",("10" != 10.1); + print "\"10\" >= 10.1",("10" >= 10.1); + print "\"10\" <= 10.1",("10" <= 10.1); + print "\"10\" > 10.1",("10" > 10.1); + print "\"10\" < 10.1",("10" < 10.1); print (0.234 + 1.01123); print 12345678901234567890E20; print .123; @@ -1687,6 +1687,250 @@ xx: 13 xx: 14 xx: 15 -------------------------------------------------------------------------------- +../../cmd/awk/qseawk --newline=on -o- -vdatafile=lang-035.dat1 -vgroupname=lang-035 -f lang-035.awk lang-035.dat2 &1 +-------------------------------------------------------------------------------- +BEGIN { + max_cid_vars = 100; + first = 1; + while (((getline x < datafile) > 0)) + { + if (first) + { + first = 0; + continue; + } + n = split (x,f,","); + if ((n < 3)) + continue; + if ((f[3] == "")) + continue; + for (suffix = 0; (suffix < max_cid_vars); (suffix)++) + { + oldval = tab[f[2],suffix]; + if ((oldval == "")) + { + tab[f[2],suffix] = f[3]; + break; + } + } + } +} + +/^lease[[:space:]]+.+[[:space:]]*{[[:space:]]*$/ { + voice_no = 0; +} + +{ + if ((($1 == "option") && ($2 == "agent.circuit-id"))) + { + pos = index ($0,"agent.circuit-id "); + len = length ($0); + last = substr ($0,len,1); + adj = 0; + if ((last != ";")) + (adj)++; + cid = substr ($0,(pos + 17),(length ($0) - ((pos + 17) + adj))); + for (suffix = 0; (suffix < max_cid_vars); (suffix)++) + { + val = tab[cid,suffix]; + if ((val == "")) + break; + print ((((" info awk.voice-no-" voice_no) " ") val) ";"); + (voice_no)++; + } + } + print $0; + if ((($1 == "hardware") && ($2 == "ethernet"))) + { + print ((" info awk.groupname \"" groupname) "\";"); + } +} + +# The format of this file is documented in the dhcpd.leases(5) manual page. +# This lease file was written by isc-dhcp-V3.1.1 + +lease 20.1.20.52 { + starts 5 2009/08/07 08:33:03; + ends 5 2009/08/07 08:38:14; + tstp 5 2009/08/07 08:38:14; + cltt 5 2009/08/07 08:33:03; + binding state free; + hardware ethernet 00:13:5e:4f:d2:d3; + info awk.groupname "lang-035"; +} +lease 20.1.20.57 { + starts 1 2009/08/10 09:04:12; + ends 2 2009/08/11 09:04:12; + cltt 1 2009/08/10 09:04:12; + binding state active; + next binding state free; + hardware ethernet 00:13:5e:50:23:6b; + info awk.groupname "lang-035"; + info awk.voice-no-0 "68599021"; + option agent.circuit-id "BLM1500_AR3_ILAB ONT/9/1/1 /0.0"; + option agent.unknown-9 0:0:0:c1:8:45:52:49:43:53:53:4f:4e; +} +lease 20.1.20.54 { + starts 1 2009/08/10 09:04:16; + ends 2 2009/08/11 09:04:16; + cltt 1 2009/08/10 09:04:16; + binding state active; + next binding state free; + hardware ethernet 00:13:5e:50:25:aa; + info awk.groupname "lang-035"; + info awk.voice-no-0 "68599011"; + option agent.circuit-id "BLM1500_AR3_ILAB ONT/9/1/2 /0.0"; + option agent.unknown-9 0:0:0:c1:8:45:52:49:43:53:53:4f:4e; +} +lease 20.1.20.55 { + starts 1 2009/08/10 13:53:08; + ends 2 2009/08/11 13:53:08; + cltt 1 2009/08/10 13:53:08; + binding state active; + next binding state free; + hardware ethernet 00:13:5e:50:20:af; + info awk.groupname "lang-035"; + info awk.voice-no-0 "68599012"; + option agent.circuit-id "BLM1500_AR3_ILAB ONT/9/2/1 /0.0"; + option agent.unknown-9 0:0:0:c1:8:45:52:49:43:53:53:4f:4e; +} +lease 20.1.20.56 { + starts 1 2009/08/10 13:53:42; + ends 2 2009/08/11 13:53:42; + cltt 1 2009/08/10 13:53:42; + binding state active; + next binding state free; + hardware ethernet 00:13:5e:50:20:29; + info awk.groupname "lang-035"; + info awk.voice-no-0 "68599022"; + option agent.circuit-id "BLM1500_AR3_ILAB ONT/9/2/2 /0.0"; + option agent.unknown-9 0:0:0:c1:8:45:52:49:43:53:53:4f:4e; +} +lease 10.218.255.53 { + starts 5 2009/08/07 08:18:04; + ends 5 2009/08/07 08:28:04; + tstp 5 2009/08/07 08:28:04; + cltt 5 2009/08/07 08:18:04; + binding state free; + hardware ethernet 00:1b:5b:9c:4f:7d; + info awk.groupname "lang-035"; + uid "\001\000\033[\234O}"; +} +lease 10.218.255.54 { + starts 5 2009/08/07 08:32:37; + ends 5 2009/08/07 08:42:37; + tstp 5 2009/08/07 08:42:37; + cltt 5 2009/08/07 08:32:37; + binding state free; + hardware ethernet 00:1b:5b:9c:1b:35; + info awk.groupname "lang-035"; + uid "\001\000\033[\234\0335"; +} +lease 10.218.255.59 { + starts 5 2009/08/07 10:39:01; + ends 6 2009/08/08 10:29:45; + tstp 6 2009/08/08 10:29:45; + cltt 5 2009/08/07 10:39:01; + binding state free; + hardware ethernet 00:1f:b3:79:7e:30; + info awk.groupname "lang-035"; + uid "\001\000\037\263y~0"; +} +lease 10.218.255.58 { + starts 0 2009/08/09 14:21:00; + ends 1 2009/08/10 09:13:42; + tstp 1 2009/08/10 09:13:42; + cltt 0 2009/08/09 14:21:00; + binding state free; + hardware ethernet 00:19:e4:43:0e:c8; + info awk.groupname "lang-035"; + uid "\001\000\031\344C\016\310"; +} +lease 10.218.255.55 { + starts 1 2009/08/10 09:02:31; + ends 2 2009/08/11 09:02:31; + cltt 1 2009/08/10 09:02:31; + binding state active; + next binding state free; + hardware ethernet 00:1b:5b:9c:90:00; + info awk.groupname "lang-035"; + uid "\001\000\033[\234\220\000"; + info awk.voice-no-0 "68599019"; + info awk.voice-no-1 "68599014"; + option agent.circuit-id "AR_Remote atm 1/1/03/12:2.100"; + option agent.remote-id "22M-fast"; +} +lease 10.218.255.52 { + starts 1 2009/08/10 09:04:04; + ends 2 2009/08/11 09:04:04; + cltt 1 2009/08/10 09:04:04; + binding state active; + next binding state free; + hardware ethernet 00:1b:5b:9c:81:35; + info awk.groupname "lang-035"; + uid "\001\000\033[\234\2015"; +} +lease 10.218.255.56 { + starts 1 2009/08/10 09:06:09; + ends 2 2009/08/11 09:06:09; + cltt 1 2009/08/10 09:06:09; + binding state active; + next binding state free; + hardware ethernet 00:1e:c7:fb:29:7d; + info awk.groupname "lang-035"; + uid "\001\000\036\307\373)}"; +} +lease 10.218.255.57 { + starts 1 2009/08/10 09:14:33; + ends 2 2009/08/11 09:14:33; + cltt 1 2009/08/10 09:14:33; + binding state active; + next binding state free; + hardware ethernet 00:1e:c7:fb:29:4d; + info awk.groupname "lang-035"; + uid "\001\000\036\307\373)M"; +} +lease 10.218.255.66 { + starts 1 2009/08/10 13:57:24; + ends 2 2009/08/11 13:57:24; + cltt 1 2009/08/10 13:57:24; + binding state active; + next binding state free; + hardware ethernet 00:1a:04:f9:e2:90; + info awk.groupname "lang-035"; + uid "\001\000\032\004\371\342\220"; + info awk.voice-no-0 "68599018"; + option agent.circuit-id "AR_Remote atm 1/1/03/02:2.100"; + option agent.remote-id "3play"; +} +lease 10.218.255.60 { + starts 1 2009/08/10 17:25:17; + ends 2 2009/08/11 17:25:17; + cltt 1 2009/08/10 17:25:17; + binding state active; + next binding state free; + hardware ethernet 00:1e:c7:fb:29:1d; + info awk.groupname "lang-035"; + uid "\001\000\036\307\373)\035"; + info awk.voice-no-0 "68599017"; + info awk.voice-no-1 "68599013"; + option agent.circuit-id "AL_AM3_LAB atm 1/1/01/01:2.100"; + option agent.remote-id "Testing DHCP"; +} +# The format of this file is documented in the dhcpd.leases(5) manual page. +# This lease file was written by isc-dhcp-V3.1.1 + +lease 10.218.255.151 { + starts 5 2009/08/07 08:09:38; + ends 5 2009/08/07 08:13:59; + tstp 5 2009/08/07 08:13:59; + cltt 5 2009/08/07 08:09:38; + binding state free; + hardware ethernet 00:1b:5b:9c:90:00; + info awk.groupname "lang-035"; + uid "\001\000\033[\234\220\000"; +} +-------------------------------------------------------------------------------- ../../cmd/awk/qseawk -f quicksort.awk quicksort.dat &1 -------------------------------------------------------------------------------- 0.0000000000 diff --git a/qse/regress/awk/regress.sh b/qse/regress/awk/regress.sh index c54fd34b..c027cb0a 100755 --- a/qse/regress/awk/regress.sh +++ b/qse/regress/awk/regress.sh @@ -137,6 +137,7 @@ PROGS=" lang-032.awk///--newline=on -o- lang-033.awk///--newline=on -o- lang-034.awk///--newline=on --rwpipe=on -o- + lang-035.awk/lang-035.dat2//--newline=on -o- -vdatafile=lang-035.dat1 -vgroupname=lang-035 quicksort.awk/quicksort.dat// quicksort2.awk/quicksort2.dat// @@ -161,12 +162,15 @@ run_scripts() do [ -z "${prog}" ] && continue - script="`echo ${prog} | cut -d/ -f1`" - datafile="`echo ${prog} | cut -d/ -f2`" - redinfile="`echo ${prog} | cut -d/ -f3`" - awkopts="`echo ${prog} | cut -d/ -f4`" + local script="`echo ${prog} | cut -d/ -f1`" + local datafile="`echo ${prog} | cut -d/ -f2`" + local redinfile="`echo ${prog} | cut -d/ -f3`" + local awkopts="`echo ${prog} | cut -d/ -f4`" + local orgscript="${script}" [ -z "${script}" ] && continue + + [ -f "${script}".dp ] && script="${script}.dp" [ -f "${script}" ] || { echo_so "${script} not found" @@ -174,9 +178,9 @@ run_scripts() } [ -z "${redinfile}" ] && redinfile="/dev/stdin" - - echo_title "${QSEAWK} ${awkopts} -f ${script} ${datafile} <${redinfile} 2>&1" - ${QSEAWK} ${awkopts} -f ${script} ${datafile} <${redinfile} 2>&1 + + echo_title "${QSEAWK} ${awkopts} -f ${orgscript} ${datafile} <${redinfile} 2>&1" + ${QSEAWK} -o "${script}.dp" ${awkopts} -f ${script} ${datafile} <${redinfile} 2>&1 done < "${TMPFILE}" @@ -185,19 +189,39 @@ run_scripts() case $1 in init) + rm -f *.dp run_scripts > "${OUTFILE}" + rm -f *.dp echo_so "INIT OK" ;; test) - run_scripts > "${OUTFILE}.temp" - # diff -q is not supported on old platforms. - # redirect output to /dev/null instead. - diff "${OUTFILE}" "${OUTFILE}.temp" > /dev/null || { - echo_so "ERROR: ${OUTFILE} differs from ${OUTFILE}.temp." - echo_so " Check the scripts and output files for any errors." + rm -f *.dp + echo_so "FIRST RUN WITH ORIGINAL SOURCE" + run_scripts > "${OUTFILE}.test" + echo_so "SECOND RUN WITH DEPARSED SOURCE" + run_scripts > "${OUTFILE}.test2" + rm -f *.dp + + diff "${OUTFILE}.test" "${OUTFILE}.test2" > /dev/null || { + echo_so "ERROR: Difference is found between the first run and the second run." + echo_so " The output of the first run is stored in '${OUTFILE}.test'." + echo_so " The output of the seconds run is stored in '${OUTFILE}.test2'." + echo_so " You may execute 'diff ${OUTFILE}.test ${OUTFILE}.test2' for more info." exit 1 } - rm -f "${OUTFILE}.temp" + + rm -f "${OUTFILE}.test2" + + # diff -q is not supported on old platforms. + # redirect output to /dev/null instead. + diff "${OUTFILE}" "${OUTFILE}.test" > /dev/null || { + echo_so "ERROR: Difference is found between expected output and actual output." + echo_so " The expected output is stored in '${OUTFILE}'." + echo_so " The actual output is stored in '${OUTFILE}.test'." + echo_so " You may execute 'diff ${OUTFILE} ${OUTFILE}.test' for more info." + exit 1 + } + rm -f "${OUTFILE}.test" echo_so "TEST OK" ;; *) diff --git a/qse/regress/awk/stripcomment.awk b/qse/regress/awk/stripcomment.awk index a4b72f8a..e438bbd0 100644 --- a/qse/regress/awk/stripcomment.awk +++ b/qse/regress/awk/stripcomment.awk @@ -2,10 +2,10 @@ BEGIN { RS = "/\\*([^*]|\\*+[^/*])*\\*+/" # comment is record separator ORS = " " - getline hold + getline hold } { print hold ; hold = $0 } -END { printf "%s" , hold } +END { print hold }