diff --git a/qse/doc/Makefile.am b/qse/doc/Makefile.am index 128db276..9b91902c 100644 --- a/qse/doc/Makefile.am +++ b/qse/doc/Makefile.am @@ -9,7 +9,6 @@ EXTRA_DIST = \ page/mem.doc \ page/cenc.doc \ page/io.doc \ - page/awk.doc \ page/awk-embed.md \ page/awk-lang.md \ page/sed.doc \ diff --git a/qse/doc/Makefile.in b/qse/doc/Makefile.in index 9b129efd..2ed26db1 100644 --- a/qse/doc/Makefile.in +++ b/qse/doc/Makefile.in @@ -234,7 +234,6 @@ EXTRA_DIST = \ page/mem.doc \ page/cenc.doc \ page/io.doc \ - page/awk.doc \ page/awk-embed.md \ page/awk-lang.md \ page/sed.doc \ @@ -432,6 +431,9 @@ uninstall-am: mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am +all: + doxygen + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/qse/doc/page/awk-embed.md b/qse/doc/page/awk-embed.md index 141bbe2a..978c582c 100644 --- a/qse/doc/page/awk-embed.md +++ b/qse/doc/page/awk-embed.md @@ -62,23 +62,31 @@ functions like *gsub* or *index*. \includelineno awk03.c -If you want to pass arguments to the function you call with qse_awk_rtx_call(), -you must create values with value creation functions, updates their reference -count, and pass them to qse_awk_rtx_call(). The sample below creates 2 integer -values with qse_awk_rtx_makeintval() and pass them to the *pow* function. +If you want to pass arguments to the function, you must create values with +value creation functions, updates their reference count, and pass them to +qse_awk_rtx_call(). The sample below creates 2 integer values with +qse_awk_rtx_makeintval() and pass them to the *pow* function. \includelineno awk04.c While qse_awk_rtx_call() looks up a function in the function table by name, you can find the function in advance and use the information found when -calling a function. qse_awk_rtx_findfun() and qse_awk_rtx_callfun() come -to play a role in this situation. qse_awk_rtx_call() in the sample above -can be translated into 2 separate calls to qse_awk_rtx_findfun() and -qse_awk_rtx_callfun(). You can reduce look-up overhead via these 2 -functions if you have to execute the same function multiple times. +calling it. qse_awk_rtx_findfun() and qse_awk_rtx_callfun() come to play a role +in this situation. qse_awk_rtx_call() in the sample above can be translated +into 2 separate calls to qse_awk_rtx_findfun() and qse_awk_rtx_callfun(). +You can reduce look-up overhead via these 2 functions if you are to execute +the same function multiple times. \includelineno awk05.c +Similarly, you can pass a more complex value than a number. You can compose +a map value with qse_awk_rtx_makemapval() or qse_awk_rtx_makemapvalwithdata(). +The sample below demonstrates how to use qse_awk_rtx_makemapvalwithdata(), +pass a created map value to qse_awk_rtx_call(), and traverse a map value +returned with qse_awk_rtx_getfirstmapvalitr() and qse_awk_rtx_getnextmapvalitr(). + + \includelineno awk06.c + Global Variables ---------------- @@ -91,6 +99,29 @@ Built-in Functions You can add built-in functions with qse_awk_addfnc(). On the other hand, modular built-in functions reside in a shared object. +Single Script over Multiple Data Streams +---------------------------------------- + +Customizing Language Features +----------------------------- + +Creating multiple awk objects +----------------------------- + +Memory Pool +----------- + +Embedding in C++ +----------------- + +The QSE::Awk class and QSE::StdAwk classe wrap the underlying C library routines +for better object-orientation. These two classes are defined in +and respectively. The embedding task can be simplified despite +slight performance overhead. The hello-world sample in C can be rewritten with +less numbers of lines in C++. + + \includelineno awk21.cpp + Changes in 0.6.0 ---------------- diff --git a/qse/doc/page/awk.doc b/qse/doc/page/awk.doc deleted file mode 100644 index ba817fec..00000000 --- a/qse/doc/page/awk.doc +++ /dev/null @@ -1,180 +0,0 @@ -/** @page awk AWK - -@section awk-content CONTENTS -- @ref awk-intro "INTRODUCTION" - -@section awk-intro INTRODUCTION - -QSEAWK is an AWK interpreter and is a part of the @ref qse_intro "QSE" library. -Its design focuses on building a flexible and robust embedding API with minimal -platform dependency. An embedding application is capable of: -- adding new global variables and functions. -- getting and set the value of a global variable. -- calling a function with or without parameters and getting its return value. -- customizing I/O handlers for file, pipe, console I/O. -- creating multiple interpreters independent of each other. -- running a single script with different I/O streams independently. -- changing language features by setting options. -- and more - -The library implements AWK in multiple levels: - -- base interpreter -- standard interpreter -- parallel interpreter - -The base interpreter provides most core language features while minimizing -platform dependence. When working with the base interpreter, you're required -to write primtive operation handlers like I/O and pass them in to make it -useful. The standard interpreter is usable immediately since it implements -all the primitive operations required by the base interpreter and adds -standard AWK functions. The parallel interpreter enables parallel processing -by adding various MPI variables and functions to the standard interpreter. - -Embedding a standard interpreter typically involves the following steps. - -- open a new interpreter -- parse in a source script -- open a new runtime context -- execute pattern-action blocks or call a function -- close the runtime context -- close the interpter - -The code example below demonstrates the steps in C. It executes the one liner -BEGIN { print "hello, world" }. - -@code -/* cc -o hello hello.c -lqseawk -lqsecmn -lm */ -#include -#include - -#define FAIL(msg) do { qse_printf(QSE_T("ERR: %s\n"),msg); goto oops; } while(0) - -int main () -{ - qse_awk_t* awk = QSE_NULL; - qse_awk_rtx_t* rtx = QSE_NULL; - qse_awk_val_t* retv; - qse_awk_parsestd_t psin; - int ret = -1; - - awk = qse_awk_openstd (0); /* open a new interpreter */ - if (!awk) FAIL ("cannot open awk"); - - /* parse the hello world script from a string */ - psin.type = QSE_AWK_PARSESTD_STR; - psin.u.str.ptr = QSE_T("BEGIN { print \"hello, world\" }"); - psin.u.str.len = qse_strlen(psin.u.str.ptr); - if (qse_awk_parsestd (awk, &psin, QSE_NULL) <= -1) - FAIL (qse_awk_geterrmsg(awk)); - - rtx = qse_awk_rtx_openstd ( /* open a runtime context */ - awk, 0, /* no extension */ - QSE_T("hello"), /* ARGV[0] */ - QSE_NULL, /* stdin */ - QSE_NULL, /* stdout */ - QSE_NULL /* default cmgr */ - ); - if (!rtx) FAIL (qse_awk_geterrmsg(awk)); - - /* exeucte pattern-action blocks */ - retv = qse_awk_rtx_loop (rtx); - if (!retv) FAIL (qse_awk_rtx_geterrmsg(rtx)); - - qse_awk_rtx_refdownval (rtx, retv); /* destroy the return value */ - ret = 0; - -oops: - if (rtx) qse_awk_rtx_close (rtx); /* close the runtime context */ - if (awk) qse_awk_close (awk); /* close the interpreter */ - return ret; -} -@endcode - -Things can get simpler when you use C++ API. Note that the C++ API supports -1 single runtime context for each interpreter. - -@code -/* c++ -o hello hello.cpp -lqseawkxx -lqseawk -lqsecmnxx -lqsecmn -lm */ -#include -#include - -#ifdef QSE_CHAR_IS_MCHAR -# define xcout std::cout -#else -# define xcout std::wcout -#endif - -struct MyAwk: public QSE::StdAwk { ~MyAwk () { QSE::StdAwk::close (); } }; - -#define FAIL(awk) do { \ - xcout << QSE_T("ERR: ") << awk.getErrorMessage() << std::endl; \ - return -1; \ -} while (0) - -int main (int argc, char* argv[]) -{ - MyAwk awk; - - // open a new interpreter - if (awk.open () <= -1) FAIL (awk); - - // set ARGV[0] - if (awk.addArgument (QSE_T("hello")) <= -1) FAIL (awk); - - // parse the source script string - MyAwk::SourceString in(QSE_T("BEGIN { print \"hello, world\" }")); - if (awk.parse (in, MyAwk::Source::NONE) == QSE_NULL) FAIL (awk); - - // execute pattern-action blocks. - MyAwk::Value r; - if (awk.loop (&r) <= -1) FAIL (awk); - - return 0; -} -@endcode - -This library also provides a stand-alone AWK interpreter that you can use -in a console environment. The source code is located under the -/cmd/awk subdirectory. See the usage below. - -@code -$ qseawk -USAGE: qseawk [options] -f sourcefile [ -- ] [datafile]* - qseawk [options] [ -- ] sourcestring [datafile]* -Where options are: - -h/--help print this message - --version print version - -D show extra information - -c/--call name call a function instead of entering - the pattern-action loop - -f/--file sourcefile set the source script file - -d/--deparsed-file deparsedfile set the deparsing output file - -F/--field-separator string set a field separator(FS) - -v/--assign var=value add a global variable with a value - -m/--memory-limit number limit the memory usage (bytes) - -X number fail the number'th memory allocation - --script-encoding string specify script file encoding name - --console-encoding string specify console encoding name - --implicit on/off allow undeclared variables - --explicit on/off allow declared variables(local,global) - --extraops on/off enable extra operators(<<,>>,^^,\) - --rio on/off enable builtin I/O including getline & print - --rwpipe on/off allow a dual-directional pipe - --newline on/off enable a newline to terminate a statement - --striprecspc on/off strip spaces in splitting a record - --stripstrspc on/off strip spaces in converting a string to a number - --nextofile on/off enable 'nextofile' - --reset on/off enable 'reset' - --crlf on/off use CRLF for a newline - --maptovar on/off allow a map to be assigned or returned - --pablock on/off enable pattern-action loop - --rexbound on/off enable {n,m} in a regular expression - --ncmponstr on/off perform numeric comparsion on numeric strings - --strictnaming on/off enable the strict naming rule - --include on/off enable '@include' - --tolerant on/off make more I/O fault-tolerant - --abort on/off enable 'abort' -@endcode - -*/ diff --git a/qse/doc/page/mainpage.md b/qse/doc/page/mainpage.md index 71434792..4df12d12 100644 --- a/qse/doc/page/mainpage.md +++ b/qse/doc/page/mainpage.md @@ -13,7 +13,7 @@ aspects of embedding application and an embedded object from each other. The library is licensed under the GNU Lesser General Public License version 3: http://www.gnu.org/licenses/ -The project webpage: http://code.abiyo.net/@qse +The project webpage: http://code.abiyo.net/@qse or http://qse.googlecode.com For further information, contact: Chung, Hyung-Hwan @@ -21,11 +21,10 @@ Chung, Hyung-Hwan See the subpages for more information. - @ref installation +- @ref awk-lang +- @ref awk-embed - @subpage mem "Memory Management" - @subpage cenc "Character Encoding" - @subpage io "I/O Handling" -- @subpage awk "AWK Interpreter" - @subpage sed "SED Stream Editor" -- @subpage awk-lang -- @subpage awk-embed diff --git a/qse/include/qse/awk/Awk.hpp b/qse/include/qse/awk/Awk.hpp index a253fe92..daba6b8a 100644 --- a/qse/include/qse/awk/Awk.hpp +++ b/qse/include/qse/awk/Awk.hpp @@ -29,7 +29,6 @@ /// @file /// AWK Interpreter -/// ///////////////////////////////// QSE_BEGIN_NAMESPACE(QSE) diff --git a/qse/include/qse/awk/StdAwk.hpp b/qse/include/qse/awk/StdAwk.hpp index f5332e0f..eb4625dd 100644 --- a/qse/include/qse/awk/StdAwk.hpp +++ b/qse/include/qse/awk/StdAwk.hpp @@ -27,33 +27,6 @@ /// @file /// Standard AWK Interpreter -/// -/// @example awk05.cpp -/// This program demonstrates how to use QSE::StdAwk::loop(). -/// -/// @example awk06.cpp -/// This program demonstrates how to use QSE::StdAwk::call(). -/// -/// @example awk07.cpp -/// This program demonstrates how to handle an indexed value. -/// -/// @example awk08.cpp -/// This program shows how to add intrinsic functions. -/// -/// @example awk12.cpp -/// This program shows how to override console methods to use -/// string buffers for console input and output. -/// -/// @example awk13.cpp -/// This program shows how to use resetRunContext(). It is similar -/// to awk12.cpp in principle. -/// -/// @example awk14.cpp -/// This program shows how to define a console handler to use -/// string buffers for console input and output. It is identical -/// to awk13.cpp except that it relies an external console handler -/// rather than overriding console methods. -/// ///////////////////////////////// QSE_BEGIN_NAMESPACE(QSE) diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index 56364475..197fc4f3 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -26,47 +26,23 @@ #include #include -/** @file +/** \file * An embeddable AWK interpreter is defined in this header file. * - * @todo + * \todo * - make enhancement to treat a function as a value * - improve performance of qse_awk_rtx_readio() if RS is logner than 2 chars. * - consider something like ${1:3,5} => $1, $2, $3, and $5 concatenated */ -/** - * @example awk.c - * This program demonstrates how to build a complete awk interpreter. - * - * @example awk01.c - * This program demonstrates how to use qse_awk_rtx_loop(). - * - * @example awk02.c - * The program deparses the source code and prints it before executing it. - * - * @example awk03.c - * This program demonstrates how to use qse_awk_rtx_call(). - * It parses the program stored in the string src and calls the functions - * stated in the array fnc. If no errors occur, it should print 24. - * - * @example awk04.c - * This programs shows how to qse_awk_rtx_call(). - * - * @example awk10.c - * This programs shows how to manipuate a map using qse_awk_rtx_makemapval() - * and qse_awk_rtx_setmapvalfld(). - * - */ - -/** @struct qse_awk_t +/** \struct qse_awk_t * The #qse_awk_t type defines an AWK interpreter. It provides an interface * to parse an AWK script and run it to manipulate input and output data. * * In brief, you need to call APIs with user-defined handlers to run a typical * AWK script as shown below: * - * @code + * \code * qse_awk_t* awk; * qse_awk_rtx_t* rtx; * qse_awk_sio_t sio; // need to initialize it with callback functions @@ -80,18 +56,18 @@ * qse_awk_rtx_refdownval (rtx, retv); // free return value * qse_awk_rtx_close (rtx); // destroy the runtime context * qse_awk_close (awk); // destroy the interpreter - * @endcode + * \endcode * * It provides an interface to change the conventional behavior of the * interpreter; most notably, you can call a particular function with * qse_awk_rtx_call() instead of entering the BEGIN, pattern-action blocks, END * loop. By doing this, you may utilize a script in an event-driven way. * - * @sa qse_awk_rtx_t qse_awk_open qse_awk_close + * \sa qse_awk_rtx_t qse_awk_open qse_awk_close */ typedef struct qse_awk_t qse_awk_t; -/** @struct qse_awk_rtx_t +/** \struct qse_awk_rtx_t * The #qse_awk_rtx_t type defines a runtime context. A runtime context * maintains runtime state for a running script. You can create multiple * runtime contexts out of a single AWK interpreter; in other words, you @@ -114,7 +90,7 @@ typedef struct qse_awk_t qse_awk_t; * read from a console. (/susie/ { ... }) * - print and printf write to a console. (print "hello, world") * - * @sa qse_awk_t qse_awk_rtx_open qse_awk_rio_t + * \sa qse_awk_t qse_awk_rtx_open qse_awk_rio_t */ typedef struct qse_awk_rtx_t qse_awk_rtx_t; @@ -130,7 +106,7 @@ struct qse_awk_loc_t typedef struct qse_awk_loc_t qse_awk_loc_t; /** - * The QSE_AWK_VAL_HDR defines the common header for a value. + * The #QSE_AWK_VAL_HDR defines the common header for a value. * Three common fields are: * - type - type of a value from #qse_awk_val_type_t * - ref - reference count @@ -275,12 +251,25 @@ struct qse_awk_val_map_itr_t }; typedef struct qse_awk_val_map_itr_t qse_awk_val_map_itr_t; +/** + * The #QSE_AWK_VAL_MAP_ITR_KEY macro get the pointer to the key part + * of a map value. + */ #define QSE_AWK_VAL_MAP_ITR_KEY(itr) \ ((const qse_cstr_t*)QSE_HTB_KPTL((itr)->pair)) + +/** + * The #QSE_AWK_VAL_MAP_ITR_VAL macro get the pointer to the value part + * of a map value. + */ #define QSE_AWK_VAL_MAP_ITR_VAL(itr) \ ((const qse_awk_val_t*)QSE_HTB_VPTR((itr)->pair)) +/** + * The qse_awk_val_map_data_type_t type defines the type of + * map value data for the #qse_awk_val_map_data_t structure. + */ enum qse_awk_val_map_data_type_t { QSE_AWK_VAL_MAP_DATA_INT = 0, @@ -297,12 +286,18 @@ enum qse_awk_val_map_data_type_t }; typedef enum qse_awk_val_map_data_type_t qse_awk_val_map_data_type_t; +/** + * The qse_awk_val_map_data_t type defines a structure that + * describes a key/value pair for a map value to be created + * with qse_awk_makemapvalwithdata(). + */ struct qse_awk_val_map_data_t { qse_cstr_t key; qse_awk_val_map_data_type_t type; void* vptr; }; + typedef struct qse_awk_val_map_data_t qse_awk_val_map_data_t; /* ------------------------------------------------------------------------ */ @@ -373,7 +368,7 @@ typedef enum qse_awk_nde_type_t qse_awk_nde_type_t; qse_awk_loc_t loc; \ qse_awk_nde_t* next -/** @struct qse_awk_nde_t +/** \struct qse_awk_nde_t * The qse_awk_nde_t type defines a common part of a node. */ typedef struct qse_awk_nde_t qse_awk_nde_t; @@ -608,10 +603,10 @@ typedef enum qse_awk_rio_rwcmode_t qse_awk_rio_rwcmode_t; /** * The qse_awk_rio_arg_t defines the data structure passed to a runtime - * I/O handler. An I/O handler should inspect the @a mode field and the - * @a name field and store an open handle to the @a handle field when + * I/O handler. An I/O handler should inspect the \a mode field and the + * \a name field and store an open handle to the \a handle field when * #QSE_AWK_RIO_OPEN is requested. For other request type, it can refer - * to the @a handle field set previously. + * to the \a handle field set previously. */ struct qse_awk_rio_arg_t { @@ -706,7 +701,7 @@ typedef struct qse_awk_prm_t qse_awk_prm_t; * a script and optionally deparse it. Typical input and output handlers * are shown below: * - * @code + * \code * qse_ssize_t in ( * qse_awk_t* awk, qse_awk_sio_cmd_t cmd, * qse_char_t* buf, qse_size_t size) @@ -724,7 +719,7 @@ typedef struct qse_awk_prm_t qse_awk_prm_t; * else if (cmd == QSE_AWK_SIO_CLOSE) close_output_stream; * else write data of size characters to output stream; * } - * @endcode + * \endcode * * For #QSE_AWK_SIO_OPEN, a handler must return: * - -1 if it failed to open a stream. @@ -751,7 +746,7 @@ typedef struct qse_awk_sio_t qse_awk_sio_t; /** * The qse_awk_rio_t type defines a runtime I/O handler set. - * @sa qse_awk_rtx_t + * \sa qse_awk_rtx_t */ struct qse_awk_rio_t { @@ -1013,7 +1008,7 @@ enum qse_awk_trait_t */ QSE_AWK_EXTRAKWS = (1 << 2), - /** supports @b getline and @b print */ + /** supports \b getline and \b print */ QSE_AWK_RIO = (1 << 3), /** enables the two-way pipe if #QSE_AWK_RIO is on */ @@ -1026,22 +1021,22 @@ enum qse_awk_trait_t * removes empty fields when splitting a record if FS is a regular * expression and the match is all spaces. * - * @code + * \code * BEGIN { FS="[[:space:]]+"; } * { * print "NF=" NF; * for (i = 0; i < NF; i++) print i " [" $(i+1) "]"; * } - * @endcode + * \endcode * " a b c " is split to [a], [b], [c] if #QSE_AWK_STRIPRECSPC is on. * Otherwise, it is split to [], [a], [b], [c], []. * - * @code + * \code * BEGIN { * n=split(" oh my noodle ", x, /[ o]+/); * for (i=1;i<=n;i++) print "[" x[i] "]"; * } - * @endcode + * \endcode * This example splits the string to [], [h], [my], [n], [dle] * if #QSE_AWK_STRIPRECSPC is on. Otherwise, it results in * [], [h], [my], [n], [dle], []. Note that the first empty field is not @@ -1065,7 +1060,7 @@ enum qse_awk_trait_t */ QSE_AWK_FLEXMAP = (1 << 11), - /** allows @b BEGIN, @b END, pattern-action blocks */ + /** allows \b BEGIN, \b END, pattern-action blocks */ QSE_AWK_PABLOCK = (1 << 12), /** allows {n,m} in a regular expression. */ @@ -1326,8 +1321,8 @@ typedef enum qse_awk_gbl_id_t qse_awk_gbl_id_t; /** * The qse_awk_val_type_t type defines types of AWK values. Each value - * allocated is tagged with a value type in the @a type field. - * @sa qse_awk_val_t QSE_AWK_VAL_HDR + * allocated is tagged with a value type in the \a type field. + * \sa qse_awk_val_t QSE_AWK_VAL_HDR */ enum qse_awk_val_type_t { @@ -1415,7 +1410,7 @@ extern "C" { * function structures. Therefore, you should keep the memory manager valid * during the whole life cycle of an qse_awk_t object. * - * @code + * \code * qse_awk_t* dummy() * { * qse_mmgr_t mmgr; @@ -1427,9 +1422,9 @@ extern "C" { * &prm // OK * ); * } - * @endcode + * \endcode * - * @return a pointer to a qse_awk_t object on success, #QSE_NULL on failure. + * \return a pointer to a qse_awk_t object on success, #QSE_NULL on failure. */ QSE_EXPORT qse_awk_t* qse_awk_open ( qse_mmgr_t* mmgr, /**< memory manager */ @@ -1439,7 +1434,7 @@ QSE_EXPORT qse_awk_t* qse_awk_open ( /** * The qse_awk_close() function destroys a qse_awk_t object. - * @return 0 on success, -1 on failure + * \return 0 on success, -1 on failure */ QSE_EXPORT int qse_awk_close ( qse_awk_t* awk /**< awk */ @@ -1456,7 +1451,7 @@ QSE_EXPORT void* qse_awk_getxtn ( /** * The qse_awk_getprm() function retrieves primitive functions * associated. Actual function pointers are copied into a - * structure specified by @a prm. + * structure specified by \a prm. */ QSE_EXPORT void qse_awk_getprm ( qse_awk_t* awk, @@ -1473,12 +1468,12 @@ QSE_EXPORT void qse_awk_setprm ( ); /** - * The qse_awk_clear() clears the internal state of @a awk. If you want to + * The qse_awk_clear() clears the internal state of \a awk. If you want to * reuse a qse_awk_t instance that finished being used, you may call * qse_awk_clear() instead of destroying and creating a new * #qse_awk_t instance using qse_awk_close() and qse_awk_open(). * - * @return 0 on success, -1 on failure + * \return 0 on success, -1 on failure */ QSE_EXPORT int qse_awk_clear ( qse_awk_t* awk @@ -1497,7 +1492,7 @@ QSE_EXPORT qse_awk_errstr_t qse_awk_geterrstr ( * * Here is an example of changing the formatting string for the #QSE_SED_ECMDNR * error. - * @code + * \code * qse_awk_errstr_t orgerrstr; * * const qse_char_t* myerrstr (qse_awk_t* awk, qse_awk_errnum_t num) @@ -1513,7 +1508,7 @@ QSE_EXPORT qse_awk_errstr_t qse_awk_geterrstr ( * qse_awk_seterrstr (awk, myerrstr); * ... * } - * @endcode + * \endcode */ QSE_EXPORT void qse_awk_seterrstr ( qse_awk_t* awk, /**< awk */ @@ -1523,7 +1518,7 @@ QSE_EXPORT void qse_awk_seterrstr ( /** * The qse_awk_geterrnum() function returns the number of the last error * occurred. - * @return error number + * \return error number */ QSE_EXPORT qse_awk_errnum_t qse_awk_geterrnum ( const qse_awk_t* awk /**< awk */ @@ -1539,9 +1534,9 @@ QSE_EXPORT const qse_awk_loc_t* qse_awk_geterrloc ( /** * The qse_awk_geterrmsg() function returns the error message describing - * the last error occurred. The @b fil field of the location returned is - * #QSE_NULL if the error occurred in the main script. - * @return error message + * the last error occurred. + * + * \return error message */ QSE_EXPORT const qse_char_t* qse_awk_geterrmsg ( const qse_awk_t* awk /**< awk */ @@ -1549,7 +1544,7 @@ QSE_EXPORT const qse_char_t* qse_awk_geterrmsg ( /** * The qse_awk_geterrinf() function copies error information into memory - * pointed to by @a errinf from @a awk. + * pointed to by \a errinf from \a awk. */ QSE_EXPORT void qse_awk_geterrinf ( const qse_awk_t* awk, /**< awk */ @@ -1558,8 +1553,8 @@ QSE_EXPORT void qse_awk_geterrinf ( /** * The qse_awk_seterrnum() function sets the error information omitting - * error location. You must pass a non-NULL for @a errarg if the specified - * error number @a errnum requires one or more arguments to format an + * error location. You must pass a non-NULL for \a errarg if the specified + * error number \a errnum requires one or more arguments to format an * error message. */ QSE_EXPORT void qse_awk_seterrnum ( @@ -1631,7 +1626,7 @@ QSE_EXPORT void qse_awk_pushecb ( /** * The qse_awk_addgbl() function adds an intrinsic global variable. - * @return the ID of the global variable added on success, -1 on failure. + * \return the ID of the global variable added on success, -1 on failure. */ QSE_EXPORT int qse_awk_addgbl ( qse_awk_t* awk, /**< awk */ @@ -1640,7 +1635,7 @@ QSE_EXPORT int qse_awk_addgbl ( /** * The qse_awk_delgbl() function deletes an intrinsic global variable by name. - * @return 0 on success, -1 on failure + * \return 0 on success, -1 on failure */ QSE_EXPORT int qse_awk_delgbl ( qse_awk_t* awk, /**< awk */ @@ -1650,7 +1645,7 @@ QSE_EXPORT int qse_awk_delgbl ( /** * The qse_awk_findgbl() function returns the numeric ID of an intrinsic global * variable. - * @return number >= 0 on success, -1 on failure + * \return number >= 0 on success, -1 on failure */ QSE_EXPORT int qse_awk_findgbl ( qse_awk_t* awk, /**< awk */ @@ -1668,7 +1663,7 @@ QSE_EXPORT qse_awk_fnc_t* qse_awk_addfnc ( /** * The qse_awk_delfnc() function deletes an intrinsic function by name. - * @return 0 on success, -1 on failure + * \return 0 on success, -1 on failure */ QSE_EXPORT int qse_awk_delfnc ( qse_awk_t* awk, /**< awk */ @@ -1686,10 +1681,10 @@ QSE_EXPORT void qse_awk_clrfnc ( * The qse_awk_parse() function parses a source script, and optionally * deparses it back. * - * It reads a source script by calling @a sio->in as shown in the pseudo code + * It reads a source script by calling \a sio->in as shown in the pseudo code * below: * - * @code + * \code * n = sio->in (awk, QSE_AWK_SIO_OPEN); * if (n >= 0) * { @@ -1697,17 +1692,17 @@ QSE_EXPORT void qse_awk_clrfnc ( * n = sio->in (awk, QSE_AWK_SIO_READ, buf, buf_size); * sio->in (awk, QSE_AWK_SIO_CLOSE); * } - * @endcode + * \endcode * * A negative number returned causes qse_awk_parse() to return failure; * 0 returned indicates the end of a stream; A positive number returned * indicates successful opening of a stream or the length of the text read. * - * If @a sio->out is not #QSE_NULL, it deparses the internal parse tree + * If \a sio->out is not #QSE_NULL, it deparses the internal parse tree * composed of a source script and writes back the deparsing result by - * calling @a sio->out as shown below: + * calling \a sio->out as shown below: * - * @code + * \code * n = sio->out (awk, QSE_AWK_SIO_OPEN); * if (n >= 0) * { @@ -1715,13 +1710,13 @@ QSE_EXPORT void qse_awk_clrfnc ( * n = sio->out (awk, QSE_AWK_SIO_WRITE, text, text_size); * sio->out (awk, QSE_AWK_SIO_CLOSE); * } - * @endcode + * \endcode * - * Unlike @a sf->in, the return value of 0 from @a sf->out is treated as + * Unlike \a sf->in, the return value of 0 from \a sf->out is treated as * premature end of a stream; therefore, it causes qse_awk_parse() to return * failure. * - * @return 0 on success, -1 on failure. + * \return 0 on success, -1 on failure. */ QSE_EXPORT int qse_awk_parse ( qse_awk_t* awk, /**< awk */ @@ -1730,7 +1725,7 @@ QSE_EXPORT int qse_awk_parse ( /** * The qse_awk_allocmem() function allocates dynamic memory. - * @return a pointer to a memory block on success, #QSE_NULL on failure + * \return a pointer to a memory block on success, #QSE_NULL on failure */ QSE_EXPORT void* qse_awk_allocmem ( qse_awk_t* awk, /**< awk */ @@ -1739,7 +1734,7 @@ QSE_EXPORT void* qse_awk_allocmem ( /** * The qse_awk_reallocmem() function resizes a dynamic memory block. - * @return a pointer to a memory block on success, #QSE_NULL on failure + * \return a pointer to a memory block on success, #QSE_NULL on failure */ QSE_EXPORT void* qse_awk_reallocmem ( qse_awk_t* awk, /**< awk */ @@ -1749,8 +1744,8 @@ QSE_EXPORT void* qse_awk_reallocmem ( /** * The qse_awk_callocmem() function allocates a memory block of - * the size of @a size bytes and initializes it with 0. - * @return a pointer to a memory block on success, #QSE_NULL on failure + * the size of \a size bytes and initializes it with 0. + * \return a pointer to a memory block on success, #QSE_NULL on failure */ QSE_EXPORT void* qse_awk_callocmem ( qse_awk_t* awk, /**< awk */ @@ -1771,7 +1766,7 @@ QSE_EXPORT void qse_awk_freemem ( * The new string must be freed using the qse_awk_freemem() function when * it's not needed any more. * - * @return a pointer to a new string duplicated of @a s on success, + * \return a pointer to a new string duplicated of \a s on success, * #QSE_NULL on failure. */ QSE_EXPORT qse_char_t* qse_awk_strdup ( @@ -1785,7 +1780,7 @@ QSE_EXPORT qse_char_t* qse_awk_strdup ( * qse_awk_t instance. The new string must be freed using the qse_awk_freemem() * function it's not needed any more. * - * @return a pointer to a new string duplicated of @a s on success, + * \return a pointer to a new string duplicated of \a s on success, * #QSE_NULL on failure. */ QSE_EXPORT qse_char_t* qse_awk_strxdup ( @@ -1795,11 +1790,11 @@ QSE_EXPORT qse_char_t* qse_awk_strxdup ( ); /** - * The qse_awk_cstrdup() funcation duplicates @a str->len characters from a + * The qse_awk_cstrdup() funcation duplicates \a str->len characters from a * string pointed to by @str->ptr. The duplicated string must be freed with * the qse_awk_freemem() function when it's not needed any more. * - * @return pointer to a duplicated string on success, + * \return pointer to a duplicated string on success, * #QSE_NULL on failure. */ QSE_EXPORT qse_char_t* qse_awk_cstrdup ( @@ -1842,13 +1837,13 @@ QSE_EXPORT qse_size_t qse_awk_longtostr ( ); /** - * 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. + * 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. * - * @return new runtime context on success, #QSE_NULL on failure + * \return new runtime context on success, #QSE_NULL on failure */ QSE_EXPORT qse_awk_rtx_t* qse_awk_rtx_open ( qse_awk_t* awk, /**< awk */ @@ -1871,17 +1866,17 @@ QSE_EXPORT void qse_awk_rtx_close ( * is not desirable. * * The example shows typical usage of the function. - * @code - * rtx = qse_awk_rtx_open (awk, 0, rio, QSE_NULL); - * if (rtx != QSE_NULL) + * \code + * rtx = qse_awk_rtx_open (awk, 0, rio); + * if (rtx) * { * retv = qse_awk_rtx_loop (rtx); - * if (retv != QSE_NULL) qse_awk_rtx_refdownval (rtx, retv); + * if (retv) qse_awk_rtx_refdownval (rtx, retv); * qse_awk_rtx_close (rtx); * } - * @endcode + * \endcode * - * @return return value on success, #QSE_NULL on failure. + * \return return value on success, #QSE_NULL on failure. */ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_loop ( qse_awk_rtx_t* rtx /**< runtime context */ @@ -1890,7 +1885,7 @@ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_loop ( /** * The qse_awk_rtx_findfun() function finds the function structure by name * and returns the pointer to it if one is found. It returns #QSE_NULL if - * it fails to find a function by the @a name. + * it fails to find a function by the \a name. */ QSE_EXPORT qse_awk_fun_t* qse_awk_rtx_findfun ( qse_awk_rtx_t* rtx, /**< runtime context */ @@ -1899,8 +1894,8 @@ QSE_EXPORT qse_awk_fun_t* qse_awk_rtx_findfun ( /** * The qse_awk_rtx_callfun() function invokes an AWK function described by - * the structure pointed to by @a fun. - * @sa qse_awk_rtx_call + * the structure pointed to by \a fun. + * \sa qse_awk_rtx_call */ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_callfun ( qse_awk_rtx_t* rtx, /**< runtime context */ @@ -1910,14 +1905,14 @@ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_callfun ( ); /** - * The qse_awk_rtx_call() function invokes an AWK function named @a name. + * The qse_awk_rtx_call() function invokes an AWK function named \a name. * However, it is not able to invoke an intrinsic function such as split(). * The #QSE_AWK_PABLOCK option can be turned off to make illegal the BEGIN * blocks, the pattern-action blocks, and the END blocks. * * The example shows typical usage of the function. - * @code - * rtx = qse_awk_rtx_open (awk, 0, rio, QSE_NULL); + * \code + * rtx = qse_awk_rtx_open (awk, 0, rio); * if (rtx) * { * v = qse_awk_rtx_call (rtx, QSE_T("init"), QSE_NULL, 0); @@ -1926,9 +1921,9 @@ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_callfun ( * if (v) qse_awk_rtx_refdownval (rtx, v); * qse_awk_rtx_close (rtx); * } - * @endcode + * \endcode * - * @return 0 on success, -1 on failure + * \return 0 on success, -1 on failure */ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_call ( qse_awk_rtx_t* rtx, /**< runtime context */ @@ -1952,7 +1947,7 @@ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_callwithstrs ( /** * The qse_awk_stopall() function aborts all active runtime contexts - * associated with @a awk. + * associated with \a awk. */ QSE_EXPORT void qse_awk_stopall ( qse_awk_t* awk /**< awk */ @@ -1967,7 +1962,7 @@ QSE_EXPORT int qse_awk_rtx_isstop ( ); /** - * The qse_awk_rtx_stop() function causes an active runtime context @a rtx to + * The qse_awk_rtx_stop() function causes an active runtime context \a rtx to * be aborted. */ QSE_EXPORT void qse_awk_rtx_stop ( @@ -1976,7 +1971,7 @@ QSE_EXPORT void qse_awk_rtx_stop ( /** * The qse_awk_rtx_getrio() function copies runtime I/O handlers - * to the memory buffer pointed to by @a rio. + * to the memory buffer pointed to by \a rio. */ QSE_EXPORT void qse_awk_rtx_getrio ( qse_awk_rtx_t* rtx, @@ -1985,7 +1980,7 @@ QSE_EXPORT void qse_awk_rtx_getrio ( /** * The qse_awk_rtx_getrio() function sets runtime I/O handlers - * with the functions pointed to by @a rio. + * with the functions pointed to by \a rio. */ QSE_EXPORT void qse_awk_rtx_setrio ( qse_awk_rtx_t* rtx, @@ -2037,12 +2032,12 @@ QSE_EXPORT const qse_xstr_t* qse_awk_rtx_getsubsep ( /** * The qse_awk_rtx_getgbl() gets the value of a global variable. - * The global variable ID @a id is one of the predefined global + * The global variable ID \a id is one of the predefined global * variable IDs or a value returned by qse_awk_addgbl(). * This function never fails so long as the ID is valid. Otherwise, * you may get into trouble. * - * @return value pointer + * \return value pointer */ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_getgbl ( qse_awk_rtx_t* rtx, /**< runtime context */ @@ -2090,8 +2085,8 @@ QSE_EXPORT int qse_awk_rtx_setofilename ( ); /** - * The qse_awk_rtx_getawk() function gets the owner of a runtime context @a rtx. - * @return owner of a runtime context @a rtx. + * The qse_awk_rtx_getawk() function gets the owner of a runtime context \a rtx. + * \return owner of a runtime context \a rtx. */ QSE_EXPORT qse_awk_t* qse_awk_rtx_getawk ( qse_awk_rtx_t* rtx /**< runtime context */ @@ -2122,7 +2117,7 @@ QSE_EXPORT qse_htb_t* qse_awk_rtx_getnvmap ( /** * The qse_awk_rtx_geterrnum() function gets the number of the last error * occurred during runtime. - * @return error number + * \return error number */ QSE_EXPORT qse_awk_errnum_t qse_awk_rtx_geterrnum ( const qse_awk_rtx_t* rtx /**< runtime context */ @@ -2131,7 +2126,7 @@ QSE_EXPORT qse_awk_errnum_t qse_awk_rtx_geterrnum ( /** * The qse_awk_rtx_geterrloc() function gets the location of the last error * occurred during runtime. The - * @return error location + * \return error location */ QSE_EXPORT const qse_awk_loc_t* qse_awk_rtx_geterrloc ( const qse_awk_rtx_t* rtx /**< runtime context */ @@ -2140,7 +2135,7 @@ QSE_EXPORT const qse_awk_loc_t* qse_awk_rtx_geterrloc ( /** * The qse_awk_rtx_geterrmsg() function gets the string describing the last * error occurred during runtime. - * @return error message + * \return error message */ QSE_EXPORT const qse_char_t* qse_awk_rtx_geterrmsg ( const qse_awk_rtx_t* rtx /**< runtime context */ @@ -2148,7 +2143,7 @@ QSE_EXPORT const qse_char_t* qse_awk_rtx_geterrmsg ( /** * The qse_awk_rtx_geterrinf() function copies error information into memory - * pointed to by @a errinf from a runtime context @a rtx. + * pointed to by \a errinf from a runtime context \a rtx. */ QSE_EXPORT void qse_awk_rtx_geterrinf ( const qse_awk_rtx_t* rtx, /**< runtime context */ @@ -2157,9 +2152,9 @@ QSE_EXPORT void qse_awk_rtx_geterrinf ( /** * The qse_awk_rtx_geterror() function retrieves error information from a - * runtime context @a rtx. The error number is stored into memory pointed - * to by @a errnum; the error message pointer into memory pointed to by - * @a errmsg; the error line into memory pointed to by @a errlin. + * runtime context \a rtx. The error number is stored into memory pointed + * to by \a errnum; the error message pointer into memory pointed to by + * \a errmsg; the error line into memory pointed to by \a errlin. */ QSE_EXPORT void qse_awk_rtx_geterror ( const qse_awk_rtx_t* rtx, /**< runtime context */ @@ -2236,7 +2231,7 @@ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makenilval ( /** * The qse_awk_rtx_makeintval() function creates an integer value. - * @return value on success, QSE_NULL on failure + * \return value on success, #QSE_NULL on failure */ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makeintval ( qse_awk_rtx_t* rtx, @@ -2245,7 +2240,7 @@ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makeintval ( /** * The qse_awk_rtx_makefltval() function creates a floating-point value. - * @return value on success, QSE_NULL on failure + * \return value on success, #QSE_NULL on failure */ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makefltval ( qse_awk_rtx_t* rtx, @@ -2254,7 +2249,7 @@ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makefltval ( /** * The qse_awk_rtx_makestrvalwithstr() function creates a string value. - * @return value on success, QSE_NULL on failure + * \return value on success, #QSE_NULL on failure */ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makestrvalwithstr ( qse_awk_rtx_t* rtx, @@ -2264,7 +2259,7 @@ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makestrvalwithstr ( /** * The qse_awk_rtx_makestrvalwithmbs() function creates a string value * from a null-terminated multibyte string. - * @return value on success, QSE_NULL on failure + * \return value on success, #QSE_NULL on failure */ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makestrvalwithmbs ( qse_awk_rtx_t* rtx, @@ -2274,7 +2269,7 @@ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makestrvalwithmbs ( /** * The qse_awk_rtx_makestrvalwithwcs() function creates a string value * from a null-terminated wide-character string. - * @return value on success, QSE_NULL on failure + * \return value on success, #QSE_NULL on failure */ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makestrvalwithwcs ( qse_awk_rtx_t* rtx, @@ -2283,7 +2278,7 @@ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makestrvalwithwcs ( /** * The qse_awk_rtx_makestrvalwithcstr() function creates a string value. - * @return value on success, QSE_NULL on failure + * \return value on success, #QSE_NULL on failure */ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makestrvalwithcstr ( qse_awk_rtx_t* rtx, @@ -2302,7 +2297,7 @@ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makestrvalwithwcstr ( /** * The qse_awk_rtx_makestrval() function creates a string value. - * @return value on success, QSE_NULL on failure + * \return value on success, #QSE_NULL on failure */ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makestrval ( qse_awk_rtx_t* rtx, @@ -2313,7 +2308,7 @@ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makestrval ( /** * The qse_awk_rtx_makestrval2() function creates a string value combining * two strings. - * @return value on success, QSE_NULL on failure + * \return value on success, #QSE_NULL on failure */ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makestrval2 ( qse_awk_rtx_t* rtx, @@ -2324,10 +2319,10 @@ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makestrval2 ( ); /** - * The qse_awk_rtx_makenstrval() function creates a numeric string value. - * A numeric string is a string value whose one of the header fields @b nstr - * is 1. - * @return value on success, QSE_NULL on failure + * The qse_awk_rtx_makenstrvalwithcstr() function creates a numeric string + * value. A numeric string is a string value whose one of the header fields + * \b nstr is 1. + * \return value on success, #QSE_NULL on failure */ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makenstrvalwithcstr ( qse_awk_rtx_t* rtx, @@ -2336,7 +2331,7 @@ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makenstrvalwithcstr ( /** * The qse_awk_rtx_makerexval() function creates a regular expression value. - * @return value on success, QSE_NULL on failure + * \return value on success, #QSE_NULL on failure */ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makerexval ( qse_awk_rtx_t* rtx, @@ -2346,12 +2341,19 @@ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makerexval ( /** * The qse_awk_rtx_makemapval() function creates an empty map value. - * @return value on success, QSE_NULL on failure + * \return value on success, #QSE_NULL on failure */ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makemapval ( qse_awk_rtx_t* rtx ); +/** + * The qse_awk_rtx_makemapvalwithdata() function creates a map value + * containing key/value pairs described in the structure array \a data. + * It combines qse_awk_rtx_makemapval() an qse_awk_rtx_setmapvalfld() + * for convenience sake. + * \return value on success, #QSE_NULL on failure + */ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makemapvalwithdata ( qse_awk_rtx_t* rtx, qse_awk_val_map_data_t data[] @@ -2359,8 +2361,8 @@ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makemapvalwithdata ( /** * The qse_awk_rtx_setmapvalfld() function sets a field value in a map. - * You must make sure that the type of @a map is #QSE_AWK_VAL_MAP. - * @return value @a v on success, #QSE_NULL on failure. + * You must make sure that the type of \a map is #QSE_AWK_VAL_MAP. + * \return value \a v on success, #QSE_NULL on failure. */ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_setmapvalfld ( qse_awk_rtx_t* rtx, @@ -2372,10 +2374,10 @@ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_setmapvalfld ( /** * The qse_awk_rtx_setmapvalfld() function gets the field value in a map. - * You must make sure that the type of @a map is #QSE_AWK_VAL_MAP. + * You must make sure that the type of \a map is #QSE_AWK_VAL_MAP. * If the field is not found, the function fails and sets the error number * to #QSE_AWK_EINVAL. The function does not fail for other reasons. - * @return field value on success, #QSE_NULL on failure. + * \return field value on success, #QSE_NULL on failure. */ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_getmapvalfld ( qse_awk_rtx_t* rtx, @@ -2387,8 +2389,8 @@ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_getmapvalfld ( /** * The qse_awk_rtx_getfirstmapvalitr() returns the iterator to the * first pair in the map. It returns #QSE_NULL and sets the pair field of - * @a itr to #QSE_NULL if the map contains no pair. Otherwise, it returns - * @a itr pointing to the first pair. + * \a itr to #QSE_NULL if the map contains no pair. Otherwise, it returns + * \a itr pointing to the first pair. */ QSE_EXPORT qse_awk_val_map_itr_t* qse_awk_rtx_getfirstmapvalitr ( qse_awk_rtx_t* rtx, @@ -2398,9 +2400,9 @@ QSE_EXPORT qse_awk_val_map_itr_t* qse_awk_rtx_getfirstmapvalitr ( /** * The qse_awk_rtx_getnextmapvalitr() returns the iterator to the - * next pair to @a itr in the map. It returns #QSE_NULL and sets the pair - * field of @a itr to #QSE_NULL if @a itr points to the last pair. - * Otherwise, it returns @a itr pointing to the next pair. + * next pair to \a itr in the map. It returns #QSE_NULL and sets the pair + * field of \a itr to #QSE_NULL if \a itr points to the last pair. + * Otherwise, it returns \a itr pointing to the next pair. */ QSE_EXPORT qse_awk_val_map_itr_t* qse_awk_rtx_getnextmapvalitr ( qse_awk_rtx_t* rtx, @@ -2411,7 +2413,7 @@ QSE_EXPORT qse_awk_val_map_itr_t* qse_awk_rtx_getnextmapvalitr ( /** * The qse_awk_rtx_makerefval() function creates a reference value. - * @return value on success, QSE_NULL on failure + * \return value on success, #QSE_NULL on failure */ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makerefval ( qse_awk_rtx_t* rtx, @@ -2423,7 +2425,7 @@ QSE_EXPORT qse_awk_val_t* qse_awk_rtx_makerefval ( * The qse_awk_rtx_isstaticval() function determines if a value is static. * A static value is allocated once and reused until a runtime context @ rtx * is closed. - * @return QSE_TRUE if @a val is static, QSE_FALSE if @a val is false + * \return QSE_TRUE if \a val is static, QSE_FALSE if \a val is false */ QSE_EXPORT int qse_awk_rtx_isstaticval ( qse_awk_rtx_t* rtx, /**< runtime context */ @@ -2432,7 +2434,7 @@ QSE_EXPORT int qse_awk_rtx_isstaticval ( /** * The qse_awk_rtx_refupval() function increments a reference count of a - * value @a val. + * value \a val. */ QSE_EXPORT void qse_awk_rtx_refupval ( qse_awk_rtx_t* rtx, /**< runtime context */ @@ -2441,7 +2443,7 @@ QSE_EXPORT void qse_awk_rtx_refupval ( /** * The qse_awk_rtx_refdownval() function decrements a reference count of - * a value @a val. It destroys the value if it has reached the count of 0. + * a value \a val. It destroys the value if it has reached the count of 0. */ QSE_EXPORT void qse_awk_rtx_refdownval ( qse_awk_rtx_t* rtx, /**< runtime context */ @@ -2450,7 +2452,7 @@ QSE_EXPORT void qse_awk_rtx_refdownval ( /** * The qse_awk_rtx_refdownval() function decrements a reference count of - * a value @a val. It does not destroy the value if it has reached the + * a value \a val. It does not destroy the value if it has reached the * count of 0. */ QSE_EXPORT void qse_awk_rtx_refdownval_nofree ( @@ -2459,7 +2461,7 @@ QSE_EXPORT void qse_awk_rtx_refdownval_nofree ( ); /** - * The qse_awk_rtx_valtobool() function converts a value @a val to a boolean + * The qse_awk_rtx_valtobool() function converts a value \a val to a boolean * value. */ QSE_EXPORT int qse_awk_rtx_valtobool ( @@ -2468,7 +2470,7 @@ QSE_EXPORT int qse_awk_rtx_valtobool ( ); /** - * The qse_awk_rtx_valtostr() function converts a value @a val to a string as + * 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. * @@ -2482,14 +2484,14 @@ QSE_EXPORT int qse_awk_rtx_valtobool ( * * 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 @b 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_CPLCPY. * the resulting string is copied to the buffer. - * @code + * \code * qse_awk_rtx_valtostr_out_t out; * qse_char_t buf[100]; * out.type = QSE_AWK_RTX_VALTOSTR_CPLCPY; @@ -2497,13 +2499,13 @@ QSE_EXPORT int qse_awk_rtx_valtobool ( * out.u.cplcpy.len = QSE_COUNTOF(buf); * if (qse_awk_rtx_valtostr (rtx, v, &out) <= -1) goto oops; * qse_printf (QSE_T("%.*s\n"), (int)out.u.cplcpy.len, out.u.cplcpy.ptr); - * @endcode + * \endcode * * #QSE_AWK_RTX_VALTOSTR_CPL is different from #QSE_AWK_RTX_VALTOSTR_CPLCPY * in that it doesn't copy the string to the buffer if the type of the value * is #QSE_AWK_VAL_STR. It copies the resulting string to the buffer if * the value type is not #QSE_AWK_VAL_STR. - * @code + * \code * qse_awk_rtx_valtostr_out_t out; * qse_char_t buf[100]; * out.type = QSE_AWK_RTX_VALTOSTR_CPL; @@ -2511,22 +2513,22 @@ QSE_EXPORT int qse_awk_rtx_valtobool ( * out.u.cpl.len = QSE_COUNTOF(buf); * if (qse_awk_rtx_valtostr (rtx, v, &out) <= -1) goto oops; * qse_printf (QSE_T("%.*s\n"), (int)out.u.cpl.len, out.u.cpl.ptr); - * @endcode + * \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 * pointed to by the u.cpldup.ptr field after use. - * @code + * \code * qse_awk_rtx_valtostr_out_t out; * out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP; * if (qse_awk_rtx_valtostr (rtx, v, &out) <= -1) goto oops; * qse_printf (QSE_T("%.*s\n"), (int)out.u.cpldup.len, out.u.cpldup.ptr); * qse_awk_rtx_free (rtx, out.u.cpldup.ptr); - * @endcode + * \endcode * * You may like to store the result in a dynamically resizable string. * Consider #QSE_AWK_RTX_VALTOSTR_STRP. - * @code + * \code * qse_awk_rtx_valtostr_out_t out; * qse_str_t str; * qse_str_init (&str, qse_awk_rtx_getmmgr(rtx), 100); @@ -2536,18 +2538,18 @@ QSE_EXPORT int qse_awk_rtx_valtobool ( * qse_printf (QSE_T("%.*s\n"), * (int)QSE_STR_LEN(out.u.strp), QSE_STR_PTR(out.u.strp)); * qse_str_fini (&str); - * @endcode + * \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 * u.strpcat field instead of the u.strp field. * - * In the context where @a val is determined to be of the type + * 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 0 on success, -1 on failure + * \return 0 on success, -1 on failure */ QSE_EXPORT int qse_awk_rtx_valtostr ( qse_awk_rtx_t* rtx, /**< runtime context */ @@ -2558,18 +2560,18 @@ QSE_EXPORT int qse_awk_rtx_valtostr ( /** * The qse_awk_rtx_valtostrdup() function provides a shortcut to the * 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 + * 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. * - * @code + * \code * ptr = qse_awk_rtx_valtostrdup (rtx, v, &len); * if (str == QSE_NULL) handle_error(); * qse_printf (QSE_T("%.*s\n"), (int)len, ptr); * qse_awk_rtx_free (rtx, ptr); - * @endcode + * \endcode * - * @return character pointer to a string converted on success, + * \return character pointer to a string converted on success, * #QSE_NULL on failure */ QSE_EXPORT qse_char_t* qse_awk_rtx_valtostrdup ( @@ -2595,12 +2597,12 @@ QSE_EXPORT qse_wchar_t* qse_awk_rtx_valtowcsdup ( * If the value is converted to a long number, it is stored in the memory * pointed to by l and 0 is returned. If the value is converted to a real * number, it is stored in the memory pointed to by r and 1 is returned. - * The function never fails as long as @a val points to a valid value. + * The function never fails as long as \a val points to a valid value. * * The code below shows how to convert a value to a number and determine * if it is an integer or a floating-point number. * - * @code + * \code * qse_long_t l; * qse_flt_t r; * int n; @@ -2608,9 +2610,9 @@ QSE_EXPORT qse_wchar_t* qse_awk_rtx_valtowcsdup ( * if (n <= -1) error (); * else if (n == 0) print_long (l); * else if (n >= 1) print_real (r); - * @endcode + * \endcode * - * @return -1 on failure, 0 if converted to a long number, 1 if converted to + * \return -1 on failure, 0 if converted to a long number, 1 if converted to * a floating-point number. */ QSE_EXPORT int qse_awk_rtx_valtonum ( @@ -2636,13 +2638,13 @@ QSE_EXPORT int qse_awk_rtx_valtoflt ( * The qse_awk_rtx_strtonum() function converts a string to a number. * A numeric string in the valid decimal, hexadecimal(0x), binary(0b), * octal(0) notation is converted to an integer and it is stored into - * memory pointed to by @a l; A string containng '.', 'E', or 'e' is + * memory pointed to by \a l; A string containng '.', 'E', or 'e' is * converted to a floating-pointer number and it is stored into memory - * pointed to by @a r. If @a strict is 0, the function takes up to the last - * valid character and never fails. If @a strict is non-zero, an invalid + * pointed to by \a r. If \a strict is 0, the function takes up to the last + * valid character and never fails. If \a strict is non-zero, an invalid * character causes the function to return an error. * - * @return 0 if converted to an integer, + * \return 0 if converted to an integer, * 1 if converted to a floating-point number * -1 on error. */ @@ -2666,8 +2668,8 @@ QSE_EXPORT qse_long_t qse_awk_rtx_hashval ( /** * The qse_awk_rtx_setrefval() function changes the value - * of a variable referenced in @a ref. - * @return 0 on success, -1 on failure. + * of a variable referenced in \a ref. + * \return 0 on success, -1 on failure. */ QSE_EXPORT int qse_awk_rtx_setrefval ( qse_awk_rtx_t* rtx, @@ -2686,9 +2688,9 @@ QSE_EXPORT void qse_awk_rtx_getnrflt ( ); /** - * The qse_awk_rtx_allocmem() function allocats a memory block of @a size bytes - * using the memory manager associated with a runtime context @a rtx. - * @return the pointer to a memory block on success, #QSE_NULL on failure. + * The qse_awk_rtx_allocmem() function allocats a memory block of \a size bytes + * using the memory manager associated with a runtime context \a rtx. + * \return the pointer to a memory block on success, #QSE_NULL on failure. */ QSE_EXPORT void* qse_awk_rtx_allocmem ( qse_awk_rtx_t* rtx, /**< runtime context */ @@ -2697,9 +2699,9 @@ QSE_EXPORT void* qse_awk_rtx_allocmem ( /** * The qse_awk_rtx_reallocmem() function resizes a memory block pointed to - * by @a ptr to @a size bytes using the memory manager associated with - * a runtime context @a rtx. - * @return the pointer to a memory block on success, #QSE_NULL on failure. + * by \a ptr to \a size bytes using the memory manager associated with + * a runtime context \a rtx. + * \return the pointer to a memory block on success, #QSE_NULL on failure. */ QSE_EXPORT void* qse_awk_rtx_reallocmem ( qse_awk_rtx_t* rtx, /**< runtime context */ @@ -2709,8 +2711,8 @@ QSE_EXPORT void* qse_awk_rtx_reallocmem ( /** * The qse_awk_rtx_callocmem() function allocates a memory block of - * the size of @a size bytes and initializes it with 0. - * @return a pointer to a memory block on success, #QSE_NULL on failure + * the size of \a size bytes and initializes it with 0. + * \return a pointer to a memory block on success, #QSE_NULL on failure */ QSE_EXPORT void* qse_awk_rtx_callocmem ( qse_awk_rtx_t* rtx, /**< runtime context */ @@ -2718,8 +2720,8 @@ QSE_EXPORT void* qse_awk_rtx_callocmem ( ); /** - * The qse_awk_rtx_freemem() function frees a memory block pointed to by @a ptr - * using the memory manager of a runtime ocntext @a rtx. + * The qse_awk_rtx_freemem() function frees a memory block pointed to by \a ptr + * using the memory manager of a runtime ocntext \a rtx. */ QSE_EXPORT void qse_awk_rtx_freemem ( qse_awk_rtx_t* rtx, /**< runtime context */ diff --git a/qse/include/qse/awk/std.h b/qse/include/qse/awk/std.h index baf3c75c..3625b0a3 100644 --- a/qse/include/qse/awk/std.h +++ b/qse/include/qse/awk/std.h @@ -24,7 +24,7 @@ #include #include -/** @file +/** \file * This file defines functions and data types that help you create * an awk interpreter with less effort. It is designed to be as close * to conventional awk implementations as possible. @@ -34,16 +34,6 @@ * normal file name. */ -/** - * @example awk09.c - * This programs shows how to specify multiple console output files. - * - * @example awk11.c - * This programs shows how to extend an I/O handler implemented by - * qse_awk_rtx_openstd(). - * - */ - /** * The qse_awk_parsestd_type_t type defines the types of source I/O. */ @@ -128,7 +118,7 @@ QSE_EXPORT void* qse_awk_getxtnstd ( * The qse_awk_parsestd() functions parses source script. * The code below shows how to parse a literal string 'BEGIN { print 10; }' * and deparses it out to a buffer 'buf'. - * @code + * \code * int n; * qse_awk_parsestd_t in[2]; * qse_awk_parsestd_t out; @@ -144,7 +134,7 @@ QSE_EXPORT void* qse_awk_getxtnstd ( * qse_printf (QSE_T("%s\n"), out.u.str.ptr); * QSE_MMGR_FREE (out.u.str.ptr); * } - * @endcode + * \endcode */ QSE_EXPORT int qse_awk_parsestd ( qse_awk_t* awk, @@ -154,9 +144,9 @@ QSE_EXPORT int qse_awk_parsestd ( /** * The qse_awk_rtx_openstd() function creates a standard runtime context. - * The caller should keep the contents of @a icf and @a ocf valid throughout - * the lifetime of the runtime context created. The @a cmgr is set to the - * streams created with @a icf and @a ocf if it is not #QSE_NULL. + * The caller should keep the contents of \a icf and \a ocf valid throughout + * the lifetime of the runtime context created. The \a cmgr is set to the + * streams created with \a icf and \a ocf if it is not #QSE_NULL. */ QSE_EXPORT qse_awk_rtx_t* qse_awk_rtx_openstd ( qse_awk_t* awk, @@ -178,7 +168,7 @@ QSE_EXPORT void* qse_awk_rtx_getxtnstd ( /** * The qse_awk_rtx_getcmgrstd() function gets the current character * manager associated with a particular I/O target indicated by the name - * @a ioname if #QSE_CHAR_IS_WCHAR is defined. It always returns #QSE_NULL + * \a ioname if #QSE_CHAR_IS_WCHAR is defined. It always returns #QSE_NULL * if #QSE_CHAR_IS_MCHAR is defined. */ QSE_EXPORT qse_cmgr_t* qse_awk_rtx_getcmgrstd ( diff --git a/qse/samples/awk/Makefile.am b/qse/samples/awk/Makefile.am index c9121361..d8a55755 100644 --- a/qse/samples/awk/Makefile.am +++ b/qse/samples/awk/Makefile.am @@ -5,7 +5,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/include \ -I$(includedir) -bin_PROGRAMS = awk01 awk02 awk03 awk04 awk05 awk09 awk10 awk11 awk15 +bin_PROGRAMS = awk01 awk02 awk03 awk04 awk05 awk06 awk09 awk11 awk15 LDFLAGS = -L../../lib/awk -L../../lib/cmn LDADD = -lqseawk -lqsecmn $(LIBM) @@ -21,8 +21,8 @@ awk02_SOURCES = awk02.c awk03_SOURCES = awk03.c awk04_SOURCES = awk04.c awk05_SOURCES = awk05.c +awk06_SOURCES = awk06.c awk09_SOURCES = awk09.c -awk10_SOURCES = awk10.c awk11_SOURCES = awk11.c awk15_SOURCES = awk15.c @@ -30,7 +30,7 @@ if ENABLE_CXX CXXLIB = -lqseawkxx -lqsecmnxx -bin_PROGRAMS += awk21 awk22 awk23 awk24 awk25 awk26 awk27 +bin_PROGRAMS += awk21 awk22 awk23 awk24 awk25 awk26 awk27 awk28 awk21_SOURCES = awk21.cpp awk22_SOURCES = awk22.cpp @@ -39,6 +39,7 @@ awk24_SOURCES = awk24.cpp awk25_SOURCES = awk25.cpp awk26_SOURCES = awk26.cpp awk27_SOURCES = awk27.cpp +awk28_SOURCES = awk27.cpp awk21_LDADD = $(CXXLIB) $(LDADD) awk22_LDADD = $(CXXLIB) $(LDADD) @@ -47,4 +48,5 @@ awk24_LDADD = $(CXXLIB) $(LDADD) awk25_LDADD = $(CXXLIB) $(LDADD) awk26_LDADD = $(CXXLIB) $(LDADD) awk27_LDADD = $(CXXLIB) $(LDADD) +awk28_LDADD = $(CXXLIB) $(LDADD) endif diff --git a/qse/samples/awk/Makefile.in b/qse/samples/awk/Makefile.in index 78285d15..34d8e904 100644 --- a/qse/samples/awk/Makefile.in +++ b/qse/samples/awk/Makefile.in @@ -35,10 +35,10 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = awk01$(EXEEXT) awk02$(EXEEXT) awk03$(EXEEXT) \ - awk04$(EXEEXT) awk05$(EXEEXT) awk09$(EXEEXT) awk10$(EXEEXT) \ + awk04$(EXEEXT) awk05$(EXEEXT) awk06$(EXEEXT) awk09$(EXEEXT) \ awk11$(EXEEXT) awk15$(EXEEXT) $(am__EXEEXT_1) @WCHAR_TRUE@@WIN32_TRUE@am__append_1 = $(UNICOWS_LIBS) -@ENABLE_CXX_TRUE@am__append_2 = awk21 awk22 awk23 awk24 awk25 awk26 awk27 +@ENABLE_CXX_TRUE@am__append_2 = awk21 awk22 awk23 awk24 awk25 awk26 awk27 awk28 subdir = samples/awk DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -56,7 +56,7 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = @ENABLE_CXX_TRUE@am__EXEEXT_1 = awk21$(EXEEXT) awk22$(EXEEXT) \ @ENABLE_CXX_TRUE@ awk23$(EXEEXT) awk24$(EXEEXT) awk25$(EXEEXT) \ -@ENABLE_CXX_TRUE@ awk26$(EXEEXT) awk27$(EXEEXT) +@ENABLE_CXX_TRUE@ awk26$(EXEEXT) awk27$(EXEEXT) awk28$(EXEEXT) am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_awk01_OBJECTS = awk01.$(OBJEXT) @@ -81,14 +81,14 @@ am_awk05_OBJECTS = awk05.$(OBJEXT) awk05_OBJECTS = $(am_awk05_OBJECTS) awk05_LDADD = $(LDADD) awk05_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) +am_awk06_OBJECTS = awk06.$(OBJEXT) +awk06_OBJECTS = $(am_awk06_OBJECTS) +awk06_LDADD = $(LDADD) +awk06_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) am_awk09_OBJECTS = awk09.$(OBJEXT) awk09_OBJECTS = $(am_awk09_OBJECTS) awk09_LDADD = $(LDADD) awk09_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) -am_awk10_OBJECTS = awk10.$(OBJEXT) -awk10_OBJECTS = $(am_awk10_OBJECTS) -awk10_LDADD = $(LDADD) -awk10_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) am_awk11_OBJECTS = awk11.$(OBJEXT) awk11_OBJECTS = $(am_awk11_OBJECTS) awk11_LDADD = $(LDADD) @@ -133,6 +133,11 @@ am__awk27_SOURCES_DIST = awk27.cpp awk27_OBJECTS = $(am_awk27_OBJECTS) @ENABLE_CXX_TRUE@awk27_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @ENABLE_CXX_TRUE@ $(am__DEPENDENCIES_3) +am__awk28_SOURCES_DIST = awk27.cpp +@ENABLE_CXX_TRUE@am_awk28_OBJECTS = awk27.$(OBJEXT) +awk28_OBJECTS = $(am_awk28_OBJECTS) +@ENABLE_CXX_TRUE@awk28_DEPENDENCIES = $(am__DEPENDENCIES_1) \ +@ENABLE_CXX_TRUE@ $(am__DEPENDENCIES_3) DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/ac/depcomp am__depfiles_maybe = depfiles @@ -156,18 +161,18 @@ CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(awk01_SOURCES) $(awk02_SOURCES) $(awk03_SOURCES) \ - $(awk04_SOURCES) $(awk05_SOURCES) $(awk09_SOURCES) \ - $(awk10_SOURCES) $(awk11_SOURCES) $(awk15_SOURCES) \ + $(awk04_SOURCES) $(awk05_SOURCES) $(awk06_SOURCES) \ + $(awk09_SOURCES) $(awk11_SOURCES) $(awk15_SOURCES) \ $(awk21_SOURCES) $(awk22_SOURCES) $(awk23_SOURCES) \ $(awk24_SOURCES) $(awk25_SOURCES) $(awk26_SOURCES) \ - $(awk27_SOURCES) + $(awk27_SOURCES) $(awk28_SOURCES) DIST_SOURCES = $(awk01_SOURCES) $(awk02_SOURCES) $(awk03_SOURCES) \ - $(awk04_SOURCES) $(awk05_SOURCES) $(awk09_SOURCES) \ - $(awk10_SOURCES) $(awk11_SOURCES) $(awk15_SOURCES) \ + $(awk04_SOURCES) $(awk05_SOURCES) $(awk06_SOURCES) \ + $(awk09_SOURCES) $(awk11_SOURCES) $(awk15_SOURCES) \ $(am__awk21_SOURCES_DIST) $(am__awk22_SOURCES_DIST) \ $(am__awk23_SOURCES_DIST) $(am__awk24_SOURCES_DIST) \ $(am__awk25_SOURCES_DIST) $(am__awk26_SOURCES_DIST) \ - $(am__awk27_SOURCES_DIST) + $(am__awk27_SOURCES_DIST) $(am__awk28_SOURCES_DIST) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -354,8 +359,8 @@ awk02_SOURCES = awk02.c awk03_SOURCES = awk03.c awk04_SOURCES = awk04.c awk05_SOURCES = awk05.c +awk06_SOURCES = awk06.c awk09_SOURCES = awk09.c -awk10_SOURCES = awk10.c awk11_SOURCES = awk11.c awk15_SOURCES = awk15.c @ENABLE_CXX_TRUE@CXXLIB = -lqseawkxx -lqsecmnxx @@ -366,6 +371,7 @@ awk15_SOURCES = awk15.c @ENABLE_CXX_TRUE@awk25_SOURCES = awk25.cpp @ENABLE_CXX_TRUE@awk26_SOURCES = awk26.cpp @ENABLE_CXX_TRUE@awk27_SOURCES = awk27.cpp +@ENABLE_CXX_TRUE@awk28_SOURCES = awk27.cpp @ENABLE_CXX_TRUE@awk21_LDADD = $(CXXLIB) $(LDADD) @ENABLE_CXX_TRUE@awk22_LDADD = $(CXXLIB) $(LDADD) @ENABLE_CXX_TRUE@awk23_LDADD = $(CXXLIB) $(LDADD) @@ -373,6 +379,7 @@ awk15_SOURCES = awk15.c @ENABLE_CXX_TRUE@awk25_LDADD = $(CXXLIB) $(LDADD) @ENABLE_CXX_TRUE@awk26_LDADD = $(CXXLIB) $(LDADD) @ENABLE_CXX_TRUE@awk27_LDADD = $(CXXLIB) $(LDADD) +@ENABLE_CXX_TRUE@awk28_LDADD = $(CXXLIB) $(LDADD) all: all-am .SUFFIXES: @@ -465,12 +472,12 @@ awk04$(EXEEXT): $(awk04_OBJECTS) $(awk04_DEPENDENCIES) $(EXTRA_awk04_DEPENDENCIE awk05$(EXEEXT): $(awk05_OBJECTS) $(awk05_DEPENDENCIES) $(EXTRA_awk05_DEPENDENCIES) @rm -f awk05$(EXEEXT) $(LINK) $(awk05_OBJECTS) $(awk05_LDADD) $(LIBS) +awk06$(EXEEXT): $(awk06_OBJECTS) $(awk06_DEPENDENCIES) $(EXTRA_awk06_DEPENDENCIES) + @rm -f awk06$(EXEEXT) + $(LINK) $(awk06_OBJECTS) $(awk06_LDADD) $(LIBS) awk09$(EXEEXT): $(awk09_OBJECTS) $(awk09_DEPENDENCIES) $(EXTRA_awk09_DEPENDENCIES) @rm -f awk09$(EXEEXT) $(LINK) $(awk09_OBJECTS) $(awk09_LDADD) $(LIBS) -awk10$(EXEEXT): $(awk10_OBJECTS) $(awk10_DEPENDENCIES) $(EXTRA_awk10_DEPENDENCIES) - @rm -f awk10$(EXEEXT) - $(LINK) $(awk10_OBJECTS) $(awk10_LDADD) $(LIBS) awk11$(EXEEXT): $(awk11_OBJECTS) $(awk11_DEPENDENCIES) $(EXTRA_awk11_DEPENDENCIES) @rm -f awk11$(EXEEXT) $(LINK) $(awk11_OBJECTS) $(awk11_LDADD) $(LIBS) @@ -498,6 +505,9 @@ awk26$(EXEEXT): $(awk26_OBJECTS) $(awk26_DEPENDENCIES) $(EXTRA_awk26_DEPENDENCIE awk27$(EXEEXT): $(awk27_OBJECTS) $(awk27_DEPENDENCIES) $(EXTRA_awk27_DEPENDENCIES) @rm -f awk27$(EXEEXT) $(CXXLINK) $(awk27_OBJECTS) $(awk27_LDADD) $(LIBS) +awk28$(EXEEXT): $(awk28_OBJECTS) $(awk28_DEPENDENCIES) $(EXTRA_awk28_DEPENDENCIES) + @rm -f awk28$(EXEEXT) + $(CXXLINK) $(awk28_OBJECTS) $(awk28_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -510,8 +520,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk03.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk04.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk05.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk06.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk09.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk10.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk11.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk15.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk21.Po@am__quote@ diff --git a/qse/samples/awk/awk10.c b/qse/samples/awk/awk06.c similarity index 59% rename from qse/samples/awk/awk10.c rename to qse/samples/awk/awk06.c index 1c208553..b42f8fd0 100644 --- a/qse/samples/awk/awk10.c +++ b/qse/samples/awk/awk06.c @@ -1,23 +1,3 @@ -/* - * $Id: awk04.c 441 2011-04-22 14:28:43Z hyunghwan.chung $ - * - Copyright 2006-2012 Chung, Hyung-Hwan. - This file is part of QSE. - - QSE is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - QSE is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with QSE. If not, see . - */ - #include #include @@ -32,20 +12,18 @@ int main () qse_awk_parsestd_t psin[2]; qse_awk_val_t* rtv = QSE_NULL; qse_awk_val_t* arg = QSE_NULL; - int ret, i, opt; - struct + int ret, opt; + + /* this structure is passed to qse_awk_rtx_makemapvalwithdata() */ + qse_awk_val_map_data_t md[] = { - const qse_char_t* kptr; - qse_size_t klen; - const qse_char_t* vptr; - } xxx[] = - { - { QSE_T("f0"), 2, QSE_T("linux") }, - { QSE_T("f1"), 2, QSE_T("openvms") }, - { QSE_T("f2"), 2, QSE_T("hpux") } + { { QSE_T("f0"), 2 }, QSE_AWK_VAL_MAP_DATA_STR, QSE_T("linux") }, + { { QSE_T("f1"), 2 }, QSE_AWK_VAL_MAP_DATA_STR, QSE_T("openvms") }, + { { QSE_T("f2"), 2 }, QSE_AWK_VAL_MAP_DATA_STR, QSE_T("hpux") }, + { { QSE_NULL, 0 }, 0, QSE_NULL } /* last item */ }; - /* create a main processor */ + /* create a standard awk object */ awk = qse_awk_openstd (0); if (awk == QSE_NULL) { @@ -53,18 +31,20 @@ int main () ret = -1; goto oops; } + /* get the awk's trait */ qse_awk_getopt (awk, QSE_AWK_TRAIT, &opt); - /* don't allow BEGIN, END, pattern-action blocks */ + /* change the trait value to disallow BEGIN, END, pattern-action blocks */ opt &= ~QSE_AWK_PABLOCK; - /* can assign a map to a variable */ - opt |= QSE_AWK_FLEXMAP; + /* update the trait */ qse_awk_setopt (awk, QSE_AWK_TRAIT, &opt); + /* prepare a script to parse */ psin[0].type = QSE_AWK_PARSESTD_STR; psin[0].u.str.ptr = src; psin[0].u.str.len = qse_strlen(src); psin[1].type = QSE_AWK_PARSESTD_NULL; + /* parse the script */ ret = qse_awk_parsestd (awk, psin, QSE_NULL); if (ret == -1) { @@ -73,11 +53,11 @@ int main () goto oops; } - /* create a runtime context */ + /* create a standard runtime context */ rtx = qse_awk_rtx_openstd ( awk, 0, - QSE_T("awk10"), + QSE_T("awk06"), QSE_NULL, /* stdin */ QSE_NULL, /* stdout */ QSE_NULL /* default cmgr */ @@ -90,8 +70,8 @@ int main () ret = -1; goto oops; } - /* prepare a argument to be a map */ - arg = qse_awk_rtx_makemapval (rtx); + /* create a map value to pass as an argument */ + arg = qse_awk_rtx_makemapvalwithdata (rtx, md); if (arg == QSE_NULL) { qse_fprintf (QSE_STDERR, QSE_T("error: %s\n"), @@ -99,31 +79,8 @@ int main () ret = -1; goto oops; } qse_awk_rtx_refupval (rtx, arg); - - /* insert some key/value pairs into the map */ - for (i = 0; i < QSE_COUNTOF(xxx); i++) - { - qse_awk_val_t* v, * fv; - - fv = qse_awk_rtx_makestrvalwithstr (rtx, xxx[i].vptr); - if (fv == QSE_NULL) - { - qse_fprintf (QSE_STDERR, QSE_T("error: %s\n"), - qse_awk_rtx_geterrmsg(rtx)); - ret = -1; goto oops; - } - qse_awk_rtx_refupval (rtx, fv); - v = qse_awk_rtx_setmapvalfld (rtx, arg, xxx[i].kptr, xxx[i].klen, fv); - qse_awk_rtx_refdownval (rtx, fv); - if (v == QSE_NULL) - { - qse_fprintf (QSE_STDERR, QSE_T("error: %s\n"), - qse_awk_rtx_geterrmsg(rtx)); - ret = -1; goto oops; - } - } - /* invoke the dump function */ + /* execute the dump function in the awk script */ rtv = qse_awk_rtx_call (rtx, QSE_T("dump"), &arg, 1); if (rtv == QSE_NULL) { @@ -132,17 +89,21 @@ int main () ret = -1; goto oops; } - /* print the return value */ if (rtv->type == QSE_AWK_VAL_MAP) { + /* if a returned value is a map, + * traverse the map and print the key/value pairs. */ + qse_awk_val_map_itr_t itr; qse_awk_val_map_itr_t* iptr; + /* get the iterator to the first key/value pair */ iptr = qse_awk_rtx_getfirstmapvalitr (rtx, rtv, &itr); while (iptr) { qse_xstr_t str; + /* #QSE_AWK_VAL_MAP_ITR_VAL returns the value part */ str.ptr = qse_awk_rtx_valtostrdup ( rtx, QSE_AWK_VAL_MAP_ITR_VAL(iptr), &str.len); if (str.ptr == QSE_NULL) @@ -152,6 +113,7 @@ int main () ret = -1; goto oops; } + /* #QSE_AWK_VAL_MAP_ITR_KEY returns the key part */ qse_printf (QSE_T("ret [%.*s]=[%.*s]\n"), (int)QSE_AWK_VAL_MAP_ITR_KEY(iptr)->len, QSE_AWK_VAL_MAP_ITR_KEY(iptr)->ptr, @@ -159,11 +121,14 @@ int main () ); qse_awk_rtx_freemem (rtx, str.ptr); + /* get the iterator to the next key/value pair */ iptr = qse_awk_rtx_getnextmapvalitr (rtx, rtv, &itr); } } else { + /* if it is a plain value, convert it to a string + * and print it */ qse_xstr_t str; str.ptr = qse_awk_rtx_valtostrdup (rtx, rtv, &str.len); @@ -187,7 +152,9 @@ oops: /* destroy a runtime context */ if (rtx) qse_awk_rtx_close (rtx); + /* destroy the processor */ if (awk) qse_awk_close (awk); + return ret; } diff --git a/qse/samples/awk/awk21.cpp b/qse/samples/awk/awk21.cpp index bbe53a87..5c6f5f3b 100644 --- a/qse/samples/awk/awk21.cpp +++ b/qse/samples/awk/awk21.cpp @@ -1,105 +1,32 @@ -/* - * $Id$ - * - Copyright 2006-2012 Chung, Hyung-Hwan. - This file is part of QSE. - - QSE is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - QSE is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with QSE. If not, see . - */ - #include -#include -#include -#include +#include -#include -#if defined(_WIN32) -# include -#endif - -static void print_error ( - const QSE::StdAwk::loc_t& loc, const QSE::StdAwk::char_t* msg) -{ - if (loc.line > 0 || loc.colm > 0) - qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s at LINE %lu COLUMN %lu\n"), msg, loc.line, loc.colm); - else - qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), msg); - -} - -static int run_awk (QSE::StdAwk& awk) -{ - // ARGV[0] - if (awk.addArgument (QSE_T("awk05")) <= -1) return -1; - - // ARGV[1] and/or the first console input file - if (awk.addArgument (QSE_T("Makefile")) <= -1) return -1; - - const qse_char_t* script = QSE_T( - "BEGIN { print \">> PRINT ALL LINES WHOSE LENGTH IS GREATER THAN 0\"; }\n" - "length($0) > 0 { print $0; count++; }\n" - "END { print \">> TOTAL\", count, \"LINES\"; }\n" - ); - - QSE::StdAwk::SourceString in (script); - QSE::StdAwk::SourceFile out (QSE_T("awk05.out")); - - // parse the script string and deparse it to awk05.out. - if (awk.parse (in, out) == QSE_NULL) return -1; - - QSE::StdAwk::Value r; - // execute the BEGIN, pattern-action, END blocks. - return awk.loop (&r); -} - -static int awk_main (int argc, qse_char_t* argv[]) -{ - QSE::StdAwk awk; - - int ret = awk.open (); - if (ret >= 0) ret = run_awk (awk); - - if (ret <= -1) - { - QSE::StdAwk::loc_t loc = awk.getErrorLocation(); - print_error (loc, awk.getErrorMessage()); - } - - awk.close (); - return ret; -} - -int qse_main (int argc, qse_achar_t* argv[]) -{ -#if defined(_WIN32) - char locale[100]; - UINT codepage = GetConsoleOutputCP(); - if (codepage == CP_UTF8) - { - /*SetConsoleOUtputCP (CP_UTF8);*/ - qse_setdflcmgrbyid (QSE_CMGR_UTF8); - } - else - { - sprintf (locale, ".%u", (unsigned int)codepage); - setlocale (LC_ALL, locale); - qse_setdflcmgrbyid (QSE_CMGR_SLMB); - } +#if defined(QSE_CHAR_IS_MCHAR) +# define xcout std::cout #else - setlocale (LC_ALL, ""); - qse_setdflcmgrbyid (QSE_CMGR_SLMB); +# define xcout std::wcout #endif - return qse_runmain (argc,argv,awk_main); +struct MyAwk: public QSE::StdAwk +{ + ~MyAwk () { QSE::StdAwk::close (); } +}; + +int main (int argc, char* argv[]) +{ + MyAwk awk; + MyAwk::Value r; + MyAwk::SourceString in (QSE_T("BEGIN { print \"hello, world\" }")); + + if (awk.open () <= -1 || // initialize an awk object + awk.addArgument (QSE_T("awk21")) <= -1 || // set ARGV[0] + awk.parse (in, MyAwk::Source::NONE) == QSE_NULL || // parse the script + awk.loop (&r) <= -1) goto oops; + + // no need to close anything since the destructor performs it + return 0; + +oops: + xcout << QSE_T("ERR: ") << awk.getErrorMessage() << std::endl; \ + return -1; \ } diff --git a/qse/samples/awk/awk22.cpp b/qse/samples/awk/awk22.cpp index 2aa364e9..bbe53a87 100644 --- a/qse/samples/awk/awk22.cpp +++ b/qse/samples/awk/awk22.cpp @@ -40,63 +40,36 @@ static void print_error ( static int run_awk (QSE::StdAwk& awk) { - QSE::StdAwk::Run* run; + // ARGV[0] + if (awk.addArgument (QSE_T("awk05")) <= -1) return -1; + + // ARGV[1] and/or the first console input file + if (awk.addArgument (QSE_T("Makefile")) <= -1) return -1; const qse_char_t* script = QSE_T( - "function add (a, b) { return a + b }\n" - "function mul (a, b) { return a * b }\n" - "function div (a, b) { return a / b }\n" - "function sine (a) { return sin(a) }\n" + "BEGIN { print \">> PRINT ALL LINES WHOSE LENGTH IS GREATER THAN 0\"; }\n" + "length($0) > 0 { print $0; count++; }\n" + "END { print \">> TOTAL\", count, \"LINES\"; }\n" ); QSE::StdAwk::SourceString in (script); - QSE::StdAwk::SourceFile out (QSE_T("awk06.out")); + QSE::StdAwk::SourceFile out (QSE_T("awk05.out")); - // parse the script and deparse it to awk06.out - run = awk.parse (in, out); - if (run == QSE_NULL) return -1; + // parse the script string and deparse it to awk05.out. + if (awk.parse (in, out) == QSE_NULL) return -1; - QSE::StdAwk::Value arg[2]; - if (arg[0].setInt (run, -20) <= -1) return -1; - if (arg[1].setStr (run, QSE_T("51")) <= -1) return -1; - - // ret = add (-20, 51) - QSE::StdAwk::Value ret; - if (awk.call (QSE_T("add"), &ret, arg, 2) <= -1) return -1; - - // ret = mul (ret, 51); - arg[0] = ret; - if (awk.call (QSE_T("mul"), &ret, arg, 2) <= -1) return -1; - - // ret = div (ret, 2); - arg[0] = ret; - if (arg[1].setFlt (run, 2) <= -1) return -1; - if (awk.call (QSE_T("div"), &ret, arg, 2) <= -1) return -1; - - // output the result in various types - qse_printf (QSE_T("RESULT: (int) [%lld]\n"), (long long)ret.toInt()); - qse_printf (QSE_T(" (flt) [%Lf]\n"), (long double)ret.toFlt()); - qse_printf (QSE_T(" (str) [%s]\n"), ret.toStr(QSE_NULL)); - - // ret = sine (ret); - arg[0] = ret; - if (awk.call (QSE_T("sine"), &ret, arg, 1) <= -1) return -1; - - // output the result in various types - qse_printf (QSE_T("RESULT: (int) [%lld]\n"), (long long)ret.toInt()); - qse_printf (QSE_T(" (flt) [%Lf]\n"), (long double)ret.toFlt()); - qse_printf (QSE_T(" (str) [%s]\n"), ret.toStr(QSE_NULL)); - - return 0; + QSE::StdAwk::Value r; + // execute the BEGIN, pattern-action, END blocks. + return awk.loop (&r); } static int awk_main (int argc, qse_char_t* argv[]) { QSE::StdAwk awk; - int ret = awk.open(); - + int ret = awk.open (); if (ret >= 0) ret = run_awk (awk); + if (ret <= -1) { QSE::StdAwk::loc_t loc = awk.getErrorLocation(); @@ -104,7 +77,7 @@ static int awk_main (int argc, qse_char_t* argv[]) } awk.close (); - return -1; + return ret; } int qse_main (int argc, qse_achar_t* argv[]) @@ -127,5 +100,6 @@ int qse_main (int argc, qse_achar_t* argv[]) setlocale (LC_ALL, ""); qse_setdflcmgrbyid (QSE_CMGR_SLMB); #endif + return qse_runmain (argc,argv,awk_main); } diff --git a/qse/samples/awk/awk23.cpp b/qse/samples/awk/awk23.cpp index db7093c6..2aa364e9 100644 --- a/qse/samples/awk/awk23.cpp +++ b/qse/samples/awk/awk23.cpp @@ -28,7 +28,6 @@ # include #endif - static void print_error ( const QSE::StdAwk::loc_t& loc, const QSE::StdAwk::char_t* msg) { @@ -43,88 +42,50 @@ static int run_awk (QSE::StdAwk& awk) { QSE::StdAwk::Run* run; - QSE::StdAwk::SourceString in (QSE_T( - "function pa (x) {\n" - " @reset ret;\n" - " for (i in x) { print i, \"=>\", x[i]; ret += x[i]; }\n" - " return ret + FOO++;\n" - "}\n" - "function pb (x) {\n" - " @reset ret;\n" - " for (i in x) { ret[-i] = -x[i]; }\n" - " return ret;\n" - "}" - )); + const qse_char_t* script = QSE_T( + "function add (a, b) { return a + b }\n" + "function mul (a, b) { return a * b }\n" + "function div (a, b) { return a / b }\n" + "function sine (a) { return sin(a) }\n" + ); - // add a global variable 'FOO' - int foo = awk.addGlobal (QSE_T("FOO")); - if (foo <= -1) return -1; + QSE::StdAwk::SourceString in (script); + QSE::StdAwk::SourceFile out (QSE_T("awk06.out")); - // parse the script and perform no deparsing - run = awk.parse (in, QSE::StdAwk::Source::NONE); + // parse the script and deparse it to awk06.out + run = awk.parse (in, out); if (run == QSE_NULL) return -1; - // set 'FOO' to 100000 - QSE::StdAwk::Value foov (run); - if (foov.setInt (100000) <= -1) return -1; - if (awk.setGlobal (foo, foov) <= -1) return -1; + QSE::StdAwk::Value arg[2]; + if (arg[0].setInt (run, -20) <= -1) return -1; + if (arg[1].setStr (run, QSE_T("51")) <= -1) return -1; - // prepare an indexed parameter - QSE::StdAwk::Value arg[1]; - for (int i = 1; i <= 5; i++) - { - if (arg[0].setIndexedInt (run, - QSE::StdAwk::Value::IntIndex(i), i*20) <= -1) return -1; - } - if (arg[0].setIndexedStr (run, - QSE::StdAwk::Value::IntIndex(99), QSE_T("-2345")) <= -1) return -1; + // ret = add (-20, 51) + QSE::StdAwk::Value ret; + if (awk.call (QSE_T("add"), &ret, arg, 2) <= -1) return -1; - QSE::StdAwk::Value dummy; - if (dummy.setStr (run, QSE_T("4567")) <= -1) return -1; - if (arg[0].setIndexedVal (run, - QSE::StdAwk::Value::IntIndex(999), dummy) <= -1) return -1; + // ret = mul (ret, 51); + arg[0] = ret; + if (awk.call (QSE_T("mul"), &ret, arg, 2) <= -1) return -1; - // prepare a variable to hold the return value - QSE::StdAwk::Value r; - - // call the 'pa' function - if (awk.call (QSE_T("pa"), &r, arg, 1) <= -1) return -1; + // ret = div (ret, 2); + arg[0] = ret; + if (arg[1].setFlt (run, 2) <= -1) return -1; + if (awk.call (QSE_T("div"), &ret, arg, 2) <= -1) return -1; // output the result in various types - qse_printf (QSE_T("RESULT: (int) [%lld]\n"), (long long)r.toInt()); - qse_printf (QSE_T(" (flt)[%Lf]\n"), (long double)r.toFlt()); - qse_printf (QSE_T(" (str) [%s]\n"), r.toStr(QSE_NULL)); + qse_printf (QSE_T("RESULT: (int) [%lld]\n"), (long long)ret.toInt()); + qse_printf (QSE_T(" (flt) [%Lf]\n"), (long double)ret.toFlt()); + qse_printf (QSE_T(" (str) [%s]\n"), ret.toStr(QSE_NULL)); - // get the value of 'FOO' - if (awk.getGlobal (foo, foov) <= -1) return -1; - qse_printf (QSE_T("FOO: (int) [%lld]\n"), (long long)foov.toInt()); - qse_printf (QSE_T(" (flt)[%Lf]\n"), (long double)foov.toFlt()); - qse_printf (QSE_T(" (str) [%s]\n"), foov.toStr(QSE_NULL)); + // ret = sine (ret); + arg[0] = ret; + if (awk.call (QSE_T("sine"), &ret, arg, 1) <= -1) return -1; - // call the 'pb' function - if (awk.call (QSE_T("pb"), &r, arg, QSE_COUNTOF(arg)) <= -1) return -1; - - // output the returned map. - QSE_ASSERT (r.isIndexed()); - - QSE::StdAwk::Value::IndexIterator iter; - QSE::StdAwk::Value::Index idx; - QSE::StdAwk::Value v; - - qse_printf (QSE_T("RESULT:\n")); - - iter = r.getFirstIndex (&idx); - while (iter != QSE::StdAwk::Value::IndexIterator::END) - { - if (r.getIndexed (idx, &v) <= -1) return -1; - - qse_printf (QSE_T("\t[%.*s]=>[%lld]\n"), - (int)idx.length(), idx.pointer(), - (long long)v.toInt() - ); - - iter = r.getNextIndex (&idx, iter); - } + // output the result in various types + qse_printf (QSE_T("RESULT: (int) [%lld]\n"), (long long)ret.toInt()); + qse_printf (QSE_T(" (flt) [%Lf]\n"), (long double)ret.toFlt()); + qse_printf (QSE_T(" (str) [%s]\n"), ret.toStr(QSE_NULL)); return 0; } @@ -135,9 +96,6 @@ static int awk_main (int argc, qse_char_t* argv[]) int ret = awk.open(); - // allow returning a map from a function - awk.setTrait (awk.getTrait() | QSE_AWK_FLEXMAP); - if (ret >= 0) ret = run_awk (awk); if (ret <= -1) { diff --git a/qse/samples/awk/awk24.cpp b/qse/samples/awk/awk24.cpp index 51a0b432..db7093c6 100644 --- a/qse/samples/awk/awk24.cpp +++ b/qse/samples/awk/awk24.cpp @@ -19,402 +19,111 @@ */ #include -#include +#include #include #include -#include -#include #include - #if defined(_WIN32) # include -#elif defined(__OS2__) -# define INCL_DOSPROCESS -# include -#else -# include -# include -# include #endif -/* these three definitions for doxygen cross-reference */ -typedef QSE::StdAwk StdAwk; -typedef QSE::StdAwk::Run Run; -typedef QSE::StdAwk::Value Value; -class MyAwk: public StdAwk +static void print_error ( + const QSE::StdAwk::loc_t& loc, const QSE::StdAwk::char_t* msg) { -public: - MyAwk () { } - ~MyAwk () { close (); } - - int open () - { - if (StdAwk::open () <= -1) return -1; - - idLastSleep = addGlobal (QSE_T("LAST_SLEEP")); - if (idLastSleep <= -1) goto oops; - - /* this is for demonstration only. - * you can use sys::sleep() instead */ - if (addFunction (QSE_T("sleep"), 1, 1, QSE_NULL, - (FunctionHandler)&MyAwk::sleep) <= -1) goto oops; - - if (addFunction (QSE_T("sumintarray"), 1, 1, QSE_NULL, - (FunctionHandler)&MyAwk::sumintarray) <= -1) goto oops; - - if (addFunction (QSE_T("arrayindices"), 1, 1, QSE_NULL, - (FunctionHandler)&MyAwk::arrayindices) <= -1) goto oops; - - return 0; - - oops: - StdAwk::close (); - return -1; - } - - int sleep ( - Run& run, Value& ret, Value* args, size_t nargs, - const char_t* name, size_t len) - { - if (args[0].isIndexed()) - { - run.setError (QSE_AWK_EINVAL); - return -1; - } - - long_t x = args[0].toInt(); - - /*Value arg; - if (run.getGlobal(idLastSleep, arg) == 0) - qse_printf (QSE_T("GOOD: [%d]\n"), (int)arg.toInt()); - else { qse_printf (QSE_T("BAD:\n")); } - */ - - if (run.setGlobal (idLastSleep, x) <= -1) return -1; - - #if defined(_WIN32) - ::Sleep ((DWORD)(x * 1000)); - return ret.setInt (0); - #elif defined(__OS2__) - ::DosSleep ((ULONG)(x * 1000)); - return ret.setInt (0); - #else - return ret.setInt (::sleep (x)); - #endif - } - - int sumintarray ( - Run& run, Value& ret, Value* args, size_t nargs, - const char_t* name, size_t len) - { - // BEGIN { - // for(i=0;i<=10;i++) x[i]=i; - // print sumintarray(x); - // } - long_t x = 0; - - if (args[0].isIndexed()) - { - Value val(run); - Value::Index idx; - Value::IndexIterator ii; - - ii = args[0].getFirstIndex (&idx); - while (ii != ii.END) - { - if (args[0].getIndexed(idx, &val) <= -1) return -1; - x += val.toInt (); - - ii = args[0].getNextIndex (&idx, ii); - } - } - else x += args[0].toInt(); - - return ret.setInt (x); - } - - int arrayindices ( - Run& run, - Value& ret, - Value* args, - size_t nargs, - const char_t* name, - size_t len) - { - // create another array composed of array indices - // BEGIN { - // for(i=0;i<=10;i++) x[i]=i; - // y=arrayindices(x); - // for (i in y) print y[i]; - // } - if (!args[0].isIndexed()) return 0; - - Value::Index idx; - Value::IndexIterator ii; - long_t i; - - ii = args[0].getFirstIndex (&idx); - for (i = 0; ii != ii.END ; i++) - { - Value::IntIndex iidx (i); - if (ret.setIndexedStr ( - iidx, idx.pointer(), idx.length()) <= -1) return -1; - ii = args[0].getNextIndex (&idx, ii); - } - - return 0; - } - -private: - int idLastSleep; -}; - -static MyAwk* app_awk = QSE_NULL; - -static void print_error (const qse_char_t* fmt, ...) -{ - va_list va; - - qse_fprintf (QSE_STDERR, QSE_T("ERROR: ")); - - va_start (va, fmt); - qse_vfprintf (QSE_STDERR, fmt, va); - va_end (va); -} - -static void print_error (MyAwk& awk) -{ - MyAwk::loc_t loc = awk.getErrorLocation(); - - if (loc.file) - { - print_error (QSE_T("line %u at %s - %s\n"), (unsigned)loc.line, loc.file, awk.getErrorMessage()); - } + if (loc.line > 0 || loc.colm > 0) + qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s at LINE %lu COLUMN %lu\n"), msg, loc.line, loc.colm); else - { - print_error (QSE_T("line %u - %s\n"), (unsigned)loc.line, awk.getErrorMessage()); - } -} - -#ifdef _WIN32 -static BOOL WINAPI stop_run (DWORD ctrl_type) -{ - if (ctrl_type == CTRL_C_EVENT || - ctrl_type == CTRL_CLOSE_EVENT) - { - if (app_awk) app_awk->stop (); - return TRUE; - } - - return FALSE; -} -#else - -static int setsignal (int sig, void(*handler)(int), int restart) -{ - struct sigaction sa_int; - - sa_int.sa_handler = handler; - sigemptyset (&sa_int.sa_mask); + qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), msg); - sa_int.sa_flags = 0; - - if (restart) - { - #ifdef SA_RESTART - sa_int.sa_flags |= SA_RESTART; - #endif - } - else - { - #ifdef SA_INTERRUPT - sa_int.sa_flags |= SA_INTERRUPT; - #endif - } - return sigaction (sig, &sa_int, NULL); } -static void stop_run (int sig) +static int run_awk (QSE::StdAwk& awk) { - int e = errno; - if (app_awk) app_awk->stop (); - errno = e; -} -#endif + QSE::StdAwk::Run* run; -static void set_signal (void) -{ -#ifdef _WIN32 - SetConsoleCtrlHandler (stop_run, TRUE); -#else - /*setsignal (SIGINT, stop_run, 1); TO BE MORE COMPATIBLE WITH WIN32*/ - setsignal (SIGINT, stop_run, 0); -#endif -} + QSE::StdAwk::SourceString in (QSE_T( + "function pa (x) {\n" + " @reset ret;\n" + " for (i in x) { print i, \"=>\", x[i]; ret += x[i]; }\n" + " return ret + FOO++;\n" + "}\n" + "function pb (x) {\n" + " @reset ret;\n" + " for (i in x) { ret[-i] = -x[i]; }\n" + " return ret;\n" + "}" + )); -static void unset_signal (void) -{ -#ifdef _WIN32 - SetConsoleCtrlHandler (stop_run, FALSE); -#else - setsignal (SIGINT, SIG_DFL, 1); -#endif -} + // add a global variable 'FOO' + int foo = awk.addGlobal (QSE_T("FOO")); + if (foo <= -1) return -1; -static void print_usage (QSE_FILE* out, const qse_char_t* argv0) -{ - qse_fprintf (out, QSE_T("USAGE: %s [options] -f sourcefile [ -- ] [datafile]*\n"), argv0); - qse_fprintf (out, QSE_T(" %s [options] [ -- ] sourcestring [datafile]*\n"), argv0); - qse_fprintf (out, QSE_T("Where options are:\n")); - qse_fprintf (out, QSE_T(" -h print this message\n")); - qse_fprintf (out, QSE_T(" -f sourcefile set the source script file\n")); - qse_fprintf (out, QSE_T(" -d deparsedfile set the deparsing output file\n")); - qse_fprintf (out, QSE_T(" -o outputfile set the console output file\n")); - qse_fprintf (out, QSE_T(" -F string set a field separator(FS)\n")); -} + // parse the script and perform no deparsing + run = awk.parse (in, QSE::StdAwk::Source::NONE); + if (run == QSE_NULL) return -1; -struct cmdline_t -{ - qse_char_t* ins; - qse_char_t* inf; - qse_char_t* outf; - qse_char_t* outc; - qse_char_t* fs; -}; + // set 'FOO' to 100000 + QSE::StdAwk::Value foov (run); + if (foov.setInt (100000) <= -1) return -1; + if (awk.setGlobal (foo, foov) <= -1) return -1; -static int handle_cmdline ( - MyAwk& awk, int argc, qse_char_t* argv[], cmdline_t* cmdline) -{ - static qse_opt_t opt = + // prepare an indexed parameter + QSE::StdAwk::Value arg[1]; + for (int i = 1; i <= 5; i++) { - QSE_T("hF:f:d:o:"), - QSE_NULL - }; - qse_cint_t c; - - std::memset (cmdline, 0, QSE_SIZEOF(*cmdline)); - while ((c = qse_getopt (argc, argv, &opt)) != QSE_CHAR_EOF) - { - switch (c) - { - case QSE_T('h'): - print_usage (QSE_STDOUT, argv[0]); - return 0; - - case QSE_T('F'): - cmdline->fs = opt.arg; - break; - - case QSE_T('f'): - cmdline->inf = opt.arg; - break; - - case QSE_T('d'): - cmdline->outf = opt.arg; - break; - - case QSE_T('o'): - cmdline->outc = opt.arg; - break; - - case QSE_T('?'): - print_error (QSE_T("illegal option - '%c'\n"), opt.opt); - return -1; - - case QSE_T(':'): - print_error (QSE_T("bad argument for '%c'\n"), opt.opt); - return -1; - - default: - print_usage (QSE_STDERR, argv[0]); - return -1; - } + if (arg[0].setIndexedInt (run, + QSE::StdAwk::Value::IntIndex(i), i*20) <= -1) return -1; } + if (arg[0].setIndexedStr (run, + QSE::StdAwk::Value::IntIndex(99), QSE_T("-2345")) <= -1) return -1; - if (opt.ind < argc && !cmdline->inf) - cmdline->ins = argv[opt.ind++]; + QSE::StdAwk::Value dummy; + if (dummy.setStr (run, QSE_T("4567")) <= -1) return -1; + if (arg[0].setIndexedVal (run, + QSE::StdAwk::Value::IntIndex(999), dummy) <= -1) return -1; - while (opt.ind < argc) + // prepare a variable to hold the return value + QSE::StdAwk::Value r; + + // call the 'pa' function + if (awk.call (QSE_T("pa"), &r, arg, 1) <= -1) return -1; + + // output the result in various types + qse_printf (QSE_T("RESULT: (int) [%lld]\n"), (long long)r.toInt()); + qse_printf (QSE_T(" (flt)[%Lf]\n"), (long double)r.toFlt()); + qse_printf (QSE_T(" (str) [%s]\n"), r.toStr(QSE_NULL)); + + // get the value of 'FOO' + if (awk.getGlobal (foo, foov) <= -1) return -1; + qse_printf (QSE_T("FOO: (int) [%lld]\n"), (long long)foov.toInt()); + qse_printf (QSE_T(" (flt)[%Lf]\n"), (long double)foov.toFlt()); + qse_printf (QSE_T(" (str) [%s]\n"), foov.toStr(QSE_NULL)); + + // call the 'pb' function + if (awk.call (QSE_T("pb"), &r, arg, QSE_COUNTOF(arg)) <= -1) return -1; + + // output the returned map. + QSE_ASSERT (r.isIndexed()); + + QSE::StdAwk::Value::IndexIterator iter; + QSE::StdAwk::Value::Index idx; + QSE::StdAwk::Value v; + + qse_printf (QSE_T("RESULT:\n")); + + iter = r.getFirstIndex (&idx); + while (iter != QSE::StdAwk::Value::IndexIterator::END) { - if (awk.addArgument (argv[opt.ind++]) <= -1) - { - print_error (awk); - return -1; - } - } - - if (!cmdline->ins && !cmdline->inf) - { - print_usage (QSE_STDERR, argv[0]); - return -1; - } - - return 1; -} - - -static int awk_main_2 (MyAwk& awk, int argc, qse_char_t* argv[]) -{ - MyAwk::Run* run; - cmdline_t cmdline; - int n; - - awk.setTrait (awk.getTrait() | QSE_AWK_EXTRAKWS | QSE_AWK_FLEXMAP | QSE_AWK_RWPIPE); - - // ARGV[0] - if (awk.addArgument (QSE_T("awk08")) <= -1) - { - print_error (awk); - return -1; - } - - if ((n = handle_cmdline (awk, argc, argv, &cmdline)) <= 0) return n; - - MyAwk::Source* in, * out; - MyAwk::SourceString in_str (cmdline.ins); - MyAwk::SourceFile in_file (cmdline.inf); - MyAwk::SourceFile out_file (cmdline.outf); - - in = (cmdline.ins)? (MyAwk::Source*)&in_str: (MyAwk::Source*)&in_file; - out = (cmdline.outf)? (MyAwk::Source*)&out_file: &MyAwk::Source::NONE; - run = awk.parse (*in, *out); - if (run == QSE_NULL) - { - print_error (awk); - return -1; - } - - if (cmdline.fs) - { - MyAwk::Value fs (run); - if (fs.setStr (cmdline.fs) <= -1) - { - print_error (awk); - return -1; - } - if (awk.setGlobal (QSE_AWK_GBL_FS, fs) <= -1) - { - print_error (awk); - return -1; - } - } - - if (cmdline.outc) - { - if (awk.addConsoleOutput (cmdline.outc) <= -1) - { - print_error (awk); - return -1; - } - } - - MyAwk::Value ret; - if (awk.loop (&ret) <= -1) - { - print_error (awk); - return -1; + if (r.getIndexed (idx, &v) <= -1) return -1; + + qse_printf (QSE_T("\t[%.*s]=>[%lld]\n"), + (int)idx.length(), idx.pointer(), + (long long)v.toInt() + ); + + iter = r.getNextIndex (&idx, iter); } return 0; @@ -422,34 +131,29 @@ static int awk_main_2 (MyAwk& awk, int argc, qse_char_t* argv[]) static int awk_main (int argc, qse_char_t* argv[]) { - MyAwk awk; + QSE::StdAwk awk; - if (awk.open() <= -1) + int ret = awk.open(); + + // allow returning a map from a function + awk.setTrait (awk.getTrait() | QSE_AWK_FLEXMAP); + + if (ret >= 0) ret = run_awk (awk); + if (ret <= -1) { - print_error (awk); - return -1; + QSE::StdAwk::loc_t loc = awk.getErrorLocation(); + print_error (loc, awk.getErrorMessage()); } - app_awk = &awk; - set_signal (); - int n = awk_main_2 (awk, argc, argv); - unset_signal (); - - app_awk = QSE_NULL; awk.close (); - return n; + return -1; } int qse_main (int argc, qse_achar_t* argv[]) { - int ret; - #if defined(_WIN32) char locale[100]; - UINT codepage; - WSADATA wsadata; - - codepage = GetConsoleOutputCP(); + UINT codepage = GetConsoleOutputCP(); if (codepage == CP_UTF8) { /*SetConsoleOUtputCP (CP_UTF8);*/ @@ -461,23 +165,9 @@ int qse_main (int argc, qse_achar_t* argv[]) setlocale (LC_ALL, locale); qse_setdflcmgrbyid (QSE_CMGR_SLMB); } - - if (WSAStartup (MAKEWORD(2,0), &wsadata) != 0) - { - print_error (QSE_T("Failed to start up winsock\n")); - return -1; - } - #else setlocale (LC_ALL, ""); qse_setdflcmgrbyid (QSE_CMGR_SLMB); #endif - - ret = qse_runmain (argc, argv, awk_main); - -#if defined(_WIN32) - WSACleanup (); -#endif - - return ret; + return qse_runmain (argc,argv,awk_main); } diff --git a/qse/samples/awk/awk25.cpp b/qse/samples/awk/awk25.cpp index d0222ebc..51a0b432 100644 --- a/qse/samples/awk/awk25.cpp +++ b/qse/samples/awk/awk25.cpp @@ -19,23 +19,26 @@ */ #include -#include +#include #include #include -#include +#include +#include #include + #if defined(_WIN32) # include -#endif - -#include -#if defined(QSE_CHAR_IS_WCHAR) -typedef std::wstring String; +#elif defined(__OS2__) +# define INCL_DOSPROCESS +# include #else -typedef std::string String; +# include +# include +# include #endif +/* these three definitions for doxygen cross-reference */ typedef QSE::StdAwk StdAwk; typedef QSE::StdAwk::Run Run; typedef QSE::StdAwk::Value Value; @@ -43,159 +46,410 @@ typedef QSE::StdAwk::Value Value; class MyAwk: public StdAwk { public: - // - // this class overrides console methods to use - // string buffers for console input and output. - // MyAwk () { } ~MyAwk () { close (); } - void setInput (const char_t* instr) + int open () { - this->input = instr; - this->inptr = this->input.c_str(); - this->inend = inptr + this->input.length(); + if (StdAwk::open () <= -1) return -1; + + idLastSleep = addGlobal (QSE_T("LAST_SLEEP")); + if (idLastSleep <= -1) goto oops; + + /* this is for demonstration only. + * you can use sys::sleep() instead */ + if (addFunction (QSE_T("sleep"), 1, 1, QSE_NULL, + (FunctionHandler)&MyAwk::sleep) <= -1) goto oops; + + if (addFunction (QSE_T("sumintarray"), 1, 1, QSE_NULL, + (FunctionHandler)&MyAwk::sumintarray) <= -1) goto oops; + + if (addFunction (QSE_T("arrayindices"), 1, 1, QSE_NULL, + (FunctionHandler)&MyAwk::arrayindices) <= -1) goto oops; + + return 0; + + oops: + StdAwk::close (); + return -1; } - void clearOutput () { this->output.clear (); } - const char_t* getOutput () { return this->output.c_str(); } - -protected: - String input; // console input buffer - const char_t* inptr; - const char_t* inend; - - String output; // console output buffer - - int openConsole (Console& io) - { - return 1; // return open-success - } - - int closeConsole (Console& io) - { - return 0; // return success - } - - int flushConsole (Console& io) + int sleep ( + Run& run, Value& ret, Value* args, size_t nargs, + const char_t* name, size_t len) { - // there is nothing to flush since a string buffer - // is used for a console output. just return success. - return 0; - } - int nextConsole (Console& io) - { - // this stripped-down awk doesn't honor the nextfile statement - // or the nextofile statement. just return success. - return 0; - } - - ssize_t readConsole (Console& io, char_t* data, size_t size) - { - if (this->inptr >= this->inend) return 0; // EOF - size_t x = qse_strxncpy (data, size, inptr, inend - inptr); - this->inptr += x; - return x; - } - - ssize_t writeConsole (Console& io, const char_t* data, size_t size) - { - try { this->output.append (data, size); } - catch (...) - { - ((Run*)io)->setError (QSE_AWK_ENOMEM); - return -1; + if (args[0].isIndexed()) + { + run.setError (QSE_AWK_EINVAL); + return -1; } - return size; + + long_t x = args[0].toInt(); + + /*Value arg; + if (run.getGlobal(idLastSleep, arg) == 0) + qse_printf (QSE_T("GOOD: [%d]\n"), (int)arg.toInt()); + else { qse_printf (QSE_T("BAD:\n")); } + */ + + if (run.setGlobal (idLastSleep, x) <= -1) return -1; + + #if defined(_WIN32) + ::Sleep ((DWORD)(x * 1000)); + return ret.setInt (0); + #elif defined(__OS2__) + ::DosSleep ((ULONG)(x * 1000)); + return ret.setInt (0); + #else + return ret.setInt (::sleep (x)); + #endif } + + int sumintarray ( + Run& run, Value& ret, Value* args, size_t nargs, + const char_t* name, size_t len) + { + // BEGIN { + // for(i=0;i<=10;i++) x[i]=i; + // print sumintarray(x); + // } + long_t x = 0; + + if (args[0].isIndexed()) + { + Value val(run); + Value::Index idx; + Value::IndexIterator ii; + + ii = args[0].getFirstIndex (&idx); + while (ii != ii.END) + { + if (args[0].getIndexed(idx, &val) <= -1) return -1; + x += val.toInt (); + + ii = args[0].getNextIndex (&idx, ii); + } + } + else x += args[0].toInt(); + + return ret.setInt (x); + } + + int arrayindices ( + Run& run, + Value& ret, + Value* args, + size_t nargs, + const char_t* name, + size_t len) + { + // create another array composed of array indices + // BEGIN { + // for(i=0;i<=10;i++) x[i]=i; + // y=arrayindices(x); + // for (i in y) print y[i]; + // } + if (!args[0].isIndexed()) return 0; + + Value::Index idx; + Value::IndexIterator ii; + long_t i; + + ii = args[0].getFirstIndex (&idx); + for (i = 0; ii != ii.END ; i++) + { + Value::IntIndex iidx (i); + if (ret.setIndexedStr ( + iidx, idx.pointer(), idx.length()) <= -1) return -1; + ii = args[0].getNextIndex (&idx, ii); + } + + return 0; + } + +private: + int idLastSleep; }; -static void print_error ( - const MyAwk::loc_t& loc, const MyAwk::char_t* msg) +static MyAwk* app_awk = QSE_NULL; + +static void print_error (const qse_char_t* fmt, ...) { - if (loc.line > 0 || loc.colm > 0) - qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s at LINE %lu COLUMN %lu\n"), msg, loc.line, loc.colm); - else - qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), msg); - + va_list va; + + qse_fprintf (QSE_STDERR, QSE_T("ERROR: ")); + + va_start (va, fmt); + qse_vfprintf (QSE_STDERR, fmt, va); + va_end (va); } -static int run_awk (MyAwk& awk) +static void print_error (MyAwk& awk) { - // sample input string - const qse_char_t* instr = QSE_T( - "aardvark 555-5553 1200/300 B\n" - "alpo-net 555-3412 2400/1200/300 A\n" - "barfly 555-7685 1200/300 A\n" - "bites 555-1675 2400/1200/300 A\n" - "camelot 555-0542 300 C\n" - "core 555-2912 1200/300 C\n" - "fooey 555-1234 2400/1200/300 B\n" - "foot 555-6699 1200/300 B\n" - "macfoo 555-6480 1200/300 A\n" - "sdace 555-3430 2400/1200/300 A\n" - "sabafoo 555-2127 1200/300 C\n"); + MyAwk::loc_t loc = awk.getErrorLocation(); - // ARGV[0] - if (awk.addArgument (QSE_T("awk12")) <= -1) return -1; - - // prepare a script to print the second and the first column - MyAwk::SourceString in (QSE_T("{ print $2, $1; }")); - - // parse the script. - if (awk.parse (in, MyAwk::Source::NONE) == QSE_NULL) return -1; - MyAwk::Value r; - - awk.setInput (instr); // locate the input string - awk.clearOutput (); // clear the output string - int x = awk.loop (&r); // execute the BEGIN, pattern-action, END blocks. - - if (x >= 0) + if (loc.file) { - qse_printf (QSE_T("%s"), awk.getOutput()); // print the console output - qse_printf (QSE_T("-----------------------------\n")); + print_error (QSE_T("line %u at %s - %s\n"), (unsigned)loc.line, loc.file, awk.getErrorMessage()); + } + else + { + print_error (QSE_T("line %u - %s\n"), (unsigned)loc.line, awk.getErrorMessage()); + } +} - // prepare a string to print lines with A in the fourth column - MyAwk::SourceString in2 (QSE_T("$4 == \"A\" { print $1; }")); - if (awk.parse (in2, MyAwk::Source::NONE) == QSE_NULL) return -1; +#ifdef _WIN32 +static BOOL WINAPI stop_run (DWORD ctrl_type) +{ + if (ctrl_type == CTRL_C_EVENT || + ctrl_type == CTRL_CLOSE_EVENT) + { + if (app_awk) app_awk->stop (); + return TRUE; + } - awk.setInput (instr); - awk.clearOutput (); + return FALSE; +} +#else - int x = awk.loop (&r); +static int setsignal (int sig, void(*handler)(int), int restart) +{ + struct sigaction sa_int; - if (x >= 0) + sa_int.sa_handler = handler; + sigemptyset (&sa_int.sa_mask); + + sa_int.sa_flags = 0; + + if (restart) + { + #ifdef SA_RESTART + sa_int.sa_flags |= SA_RESTART; + #endif + } + else + { + #ifdef SA_INTERRUPT + sa_int.sa_flags |= SA_INTERRUPT; + #endif + } + return sigaction (sig, &sa_int, NULL); +} + +static void stop_run (int sig) +{ + int e = errno; + if (app_awk) app_awk->stop (); + errno = e; +} +#endif + +static void set_signal (void) +{ +#ifdef _WIN32 + SetConsoleCtrlHandler (stop_run, TRUE); +#else + /*setsignal (SIGINT, stop_run, 1); TO BE MORE COMPATIBLE WITH WIN32*/ + setsignal (SIGINT, stop_run, 0); +#endif +} + +static void unset_signal (void) +{ +#ifdef _WIN32 + SetConsoleCtrlHandler (stop_run, FALSE); +#else + setsignal (SIGINT, SIG_DFL, 1); +#endif +} + +static void print_usage (QSE_FILE* out, const qse_char_t* argv0) +{ + qse_fprintf (out, QSE_T("USAGE: %s [options] -f sourcefile [ -- ] [datafile]*\n"), argv0); + qse_fprintf (out, QSE_T(" %s [options] [ -- ] sourcestring [datafile]*\n"), argv0); + qse_fprintf (out, QSE_T("Where options are:\n")); + qse_fprintf (out, QSE_T(" -h print this message\n")); + qse_fprintf (out, QSE_T(" -f sourcefile set the source script file\n")); + qse_fprintf (out, QSE_T(" -d deparsedfile set the deparsing output file\n")); + qse_fprintf (out, QSE_T(" -o outputfile set the console output file\n")); + qse_fprintf (out, QSE_T(" -F string set a field separator(FS)\n")); +} + +struct cmdline_t +{ + qse_char_t* ins; + qse_char_t* inf; + qse_char_t* outf; + qse_char_t* outc; + qse_char_t* fs; +}; + +static int handle_cmdline ( + MyAwk& awk, int argc, qse_char_t* argv[], cmdline_t* cmdline) +{ + static qse_opt_t opt = + { + QSE_T("hF:f:d:o:"), + QSE_NULL + }; + qse_cint_t c; + + std::memset (cmdline, 0, QSE_SIZEOF(*cmdline)); + while ((c = qse_getopt (argc, argv, &opt)) != QSE_CHAR_EOF) + { + switch (c) { - qse_printf (QSE_T("%s"), awk.getOutput()); - qse_printf (QSE_T("-----------------------------\n")); + case QSE_T('h'): + print_usage (QSE_STDOUT, argv[0]); + return 0; + + case QSE_T('F'): + cmdline->fs = opt.arg; + break; + + case QSE_T('f'): + cmdline->inf = opt.arg; + break; + + case QSE_T('d'): + cmdline->outf = opt.arg; + break; + + case QSE_T('o'): + cmdline->outc = opt.arg; + break; + + case QSE_T('?'): + print_error (QSE_T("illegal option - '%c'\n"), opt.opt); + return -1; + + case QSE_T(':'): + print_error (QSE_T("bad argument for '%c'\n"), opt.opt); + return -1; + + default: + print_usage (QSE_STDERR, argv[0]); + return -1; } } - return x; + if (opt.ind < argc && !cmdline->inf) + cmdline->ins = argv[opt.ind++]; + + while (opt.ind < argc) + { + if (awk.addArgument (argv[opt.ind++]) <= -1) + { + print_error (awk); + return -1; + } + } + + if (!cmdline->ins && !cmdline->inf) + { + print_usage (QSE_STDERR, argv[0]); + return -1; + } + + return 1; +} + + +static int awk_main_2 (MyAwk& awk, int argc, qse_char_t* argv[]) +{ + MyAwk::Run* run; + cmdline_t cmdline; + int n; + + awk.setTrait (awk.getTrait() | QSE_AWK_EXTRAKWS | QSE_AWK_FLEXMAP | QSE_AWK_RWPIPE); + + // ARGV[0] + if (awk.addArgument (QSE_T("awk08")) <= -1) + { + print_error (awk); + return -1; + } + + if ((n = handle_cmdline (awk, argc, argv, &cmdline)) <= 0) return n; + + MyAwk::Source* in, * out; + MyAwk::SourceString in_str (cmdline.ins); + MyAwk::SourceFile in_file (cmdline.inf); + MyAwk::SourceFile out_file (cmdline.outf); + + in = (cmdline.ins)? (MyAwk::Source*)&in_str: (MyAwk::Source*)&in_file; + out = (cmdline.outf)? (MyAwk::Source*)&out_file: &MyAwk::Source::NONE; + run = awk.parse (*in, *out); + if (run == QSE_NULL) + { + print_error (awk); + return -1; + } + + if (cmdline.fs) + { + MyAwk::Value fs (run); + if (fs.setStr (cmdline.fs) <= -1) + { + print_error (awk); + return -1; + } + if (awk.setGlobal (QSE_AWK_GBL_FS, fs) <= -1) + { + print_error (awk); + return -1; + } + } + + if (cmdline.outc) + { + if (awk.addConsoleOutput (cmdline.outc) <= -1) + { + print_error (awk); + return -1; + } + } + + MyAwk::Value ret; + if (awk.loop (&ret) <= -1) + { + print_error (awk); + return -1; + } + + return 0; } static int awk_main (int argc, qse_char_t* argv[]) { MyAwk awk; - int ret = awk.open (); - if (ret >= 0) ret = run_awk (awk); - - if (ret <= -1) + if (awk.open() <= -1) { - MyAwk::loc_t loc = awk.getErrorLocation(); - print_error (loc, awk.getErrorMessage()); + print_error (awk); + return -1; } + app_awk = &awk; + set_signal (); + int n = awk_main_2 (awk, argc, argv); + unset_signal (); + + app_awk = QSE_NULL; awk.close (); - return ret; + return n; } int qse_main (int argc, qse_achar_t* argv[]) { + int ret; + #if defined(_WIN32) char locale[100]; - UINT codepage = GetConsoleOutputCP(); + UINT codepage; + WSADATA wsadata; + + codepage = GetConsoleOutputCP(); if (codepage == CP_UTF8) { /*SetConsoleOUtputCP (CP_UTF8);*/ @@ -207,10 +461,23 @@ int qse_main (int argc, qse_achar_t* argv[]) setlocale (LC_ALL, locale); qse_setdflcmgrbyid (QSE_CMGR_SLMB); } + + if (WSAStartup (MAKEWORD(2,0), &wsadata) != 0) + { + print_error (QSE_T("Failed to start up winsock\n")); + return -1; + } + #else setlocale (LC_ALL, ""); qse_setdflcmgrbyid (QSE_CMGR_SLMB); #endif - return qse_runmain (argc,argv,awk_main); + ret = qse_runmain (argc, argv, awk_main); + +#if defined(_WIN32) + WSACleanup (); +#endif + + return ret; } diff --git a/qse/samples/awk/awk26.cpp b/qse/samples/awk/awk26.cpp index 3688f419..d0222ebc 100644 --- a/qse/samples/awk/awk26.cpp +++ b/qse/samples/awk/awk26.cpp @@ -57,6 +57,7 @@ public: this->inend = inptr + this->input.length(); } + void clearOutput () { this->output.clear (); } const char_t* getOutput () { return this->output.c_str(); } protected: @@ -68,16 +69,6 @@ protected: int openConsole (Console& io) { - if (io.getMode() == Console::READ) - { - this->inptr = this->input.c_str(); - this->inend = inptr + this->input.length(); - } - else - { - this->output.clear (); - } - return 1; // return open-success } @@ -95,8 +86,8 @@ protected: int nextConsole (Console& io) { // this stripped-down awk doesn't honor the nextfile statement - // or the nextofile statement. just return failure. - return -1; + // or the nextofile statement. just return success. + return 0; } ssize_t readConsole (Console& io, char_t* data, size_t size) @@ -145,30 +136,18 @@ static int run_awk (MyAwk& awk) "sdace 555-3430 2400/1200/300 A\n" "sabafoo 555-2127 1200/300 C\n"); - const qse_char_t* instr2 = QSE_T( - "aardvark 555-5553 1200/300 A\n" - "alpo-net 555-3412 2400/1200/300 B\n" - "barfly 555-7685 1200/300 C\n" - "bites 555-1675 2400/1200/300 A\n" - "camelot 555-0542 300 C\n" - "core 555-2912 1200/300 B\n" - "fooey 555-1234 2400/1200/300 A\n" - "foot 555-6699 1200/300 A\n" - "macfoo 555-6480 1200/300 B\n" - "sdace 555-3430 2400/1200/300 B\n" - "sabafoo 555-2127 1200/300 A\n"); - // ARGV[0] - if (awk.addArgument (QSE_T("awk13")) <= -1) return -1; + if (awk.addArgument (QSE_T("awk12")) <= -1) return -1; - // prepare a string to print lines with A in the fourth column - MyAwk::SourceString in (QSE_T("$4 == \"A\" { print $2, $1, $3; }")); + // prepare a script to print the second and the first column + MyAwk::SourceString in (QSE_T("{ print $2, $1; }")); // parse the script. if (awk.parse (in, MyAwk::Source::NONE) == QSE_NULL) return -1; MyAwk::Value r; awk.setInput (instr); // locate the input string + awk.clearOutput (); // clear the output string int x = awk.loop (&r); // execute the BEGIN, pattern-action, END blocks. if (x >= 0) @@ -176,11 +155,12 @@ static int run_awk (MyAwk& awk) qse_printf (QSE_T("%s"), awk.getOutput()); // print the console output qse_printf (QSE_T("-----------------------------\n")); - awk.setInput (instr2); + // prepare a string to print lines with A in the fourth column + MyAwk::SourceString in2 (QSE_T("$4 == \"A\" { print $1; }")); + if (awk.parse (in2, MyAwk::Source::NONE) == QSE_NULL) return -1; - // reset the runtime context so that the next loop() method - // is performed over a new console stream. - if (awk.resetRunContext() == QSE_NULL) return -1; + awk.setInput (instr); + awk.clearOutput (); int x = awk.loop (&r); diff --git a/qse/samples/awk/awk27.cpp b/qse/samples/awk/awk27.cpp index e50489c2..3688f419 100644 --- a/qse/samples/awk/awk27.cpp +++ b/qse/samples/awk/awk27.cpp @@ -40,31 +40,35 @@ typedef QSE::StdAwk StdAwk; typedef QSE::StdAwk::Run Run; typedef QSE::StdAwk::Value Value; -class MyConsoleHandler: public StdAwk::Console::Handler +class MyAwk: public StdAwk { public: - // this class defines a console handler that can be - // registered into an awk object. + // + // this class overrides console methods to use + // string buffers for console input and output. + // + MyAwk () { } + ~MyAwk () { close (); } - void setInput (const StdAwk::char_t* instr) + void setInput (const char_t* instr) { this->input = instr; this->inptr = this->input.c_str(); this->inend = inptr + this->input.length(); } - const StdAwk::char_t* getOutput () { return this->output.c_str(); } + const char_t* getOutput () { return this->output.c_str(); } protected: String input; // console input buffer - const StdAwk::char_t* inptr; - const StdAwk::char_t* inend; + const char_t* inptr; + const char_t* inend; String output; // console output buffer - int open (StdAwk::Console& io) + int openConsole (Console& io) { - if (io.getMode() == StdAwk::Console::READ) + if (io.getMode() == Console::READ) { this->inptr = this->input.c_str(); this->inend = inptr + this->input.length(); @@ -77,25 +81,25 @@ protected: return 1; // return open-success } - int close (StdAwk::Console& io) + int closeConsole (Console& io) { return 0; // return success } - int flush (StdAwk::Console& io) + int flushConsole (Console& io) { // there is nothing to flush since a string buffer // is used for a console output. just return success. return 0; } - int next (StdAwk::Console& io) + int nextConsole (Console& io) { // this stripped-down awk doesn't honor the nextfile statement // or the nextofile statement. just return failure. return -1; } - ssize_t read (StdAwk::Console& io, StdAwk::char_t* data, size_t size) + ssize_t readConsole (Console& io, char_t* data, size_t size) { if (this->inptr >= this->inend) return 0; // EOF size_t x = qse_strxncpy (data, size, inptr, inend - inptr); @@ -103,12 +107,12 @@ protected: return x; } - ssize_t write (StdAwk::Console& io, const StdAwk::char_t* data, size_t size) + ssize_t writeConsole (Console& io, const char_t* data, size_t size) { try { this->output.append (data, size); } catch (...) { - ((StdAwk::Run*)io)->setError (QSE_AWK_ENOMEM); + ((Run*)io)->setError (QSE_AWK_ENOMEM); return -1; } return size; @@ -116,7 +120,7 @@ protected: }; static void print_error ( - const StdAwk::loc_t& loc, const StdAwk::char_t* msg) + const MyAwk::loc_t& loc, const MyAwk::char_t* msg) { if (loc.line > 0 || loc.colm > 0) qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s at LINE %lu COLUMN %lu\n"), msg, loc.line, loc.colm); @@ -125,7 +129,7 @@ static void print_error ( } -static int run_awk (StdAwk& awk) +static int run_awk (MyAwk& awk) { // sample input string const qse_char_t* instr = QSE_T( @@ -155,26 +159,24 @@ static int run_awk (StdAwk& awk) "sabafoo 555-2127 1200/300 A\n"); // ARGV[0] - if (awk.addArgument (QSE_T("awk14")) <= -1) return -1; + if (awk.addArgument (QSE_T("awk13")) <= -1) return -1; // prepare a string to print lines with A in the fourth column - StdAwk::SourceString in (QSE_T("$4 == \"A\" { print $2, $1, $3; }")); + MyAwk::SourceString in (QSE_T("$4 == \"A\" { print $2, $1, $3; }")); // parse the script. - if (awk.parse (in, StdAwk::Source::NONE) == QSE_NULL) return -1; - StdAwk::Value r; + if (awk.parse (in, MyAwk::Source::NONE) == QSE_NULL) return -1; + MyAwk::Value r; - MyConsoleHandler* mch = (MyConsoleHandler*)awk.getConsoleHandler(); - - mch->setInput (instr); // locate the input string + awk.setInput (instr); // locate the input string int x = awk.loop (&r); // execute the BEGIN, pattern-action, END blocks. if (x >= 0) { - qse_printf (QSE_T("%s"), mch->getOutput()); // print the console output + qse_printf (QSE_T("%s"), awk.getOutput()); // print the console output qse_printf (QSE_T("-----------------------------\n")); - mch->setInput (instr2); + awk.setInput (instr2); // reset the runtime context so that the next loop() method // is performed over a new console stream. @@ -184,7 +186,7 @@ static int run_awk (StdAwk& awk) if (x >= 0) { - qse_printf (QSE_T("%s"), mch->getOutput()); + qse_printf (QSE_T("%s"), awk.getOutput()); qse_printf (QSE_T("-----------------------------\n")); } } @@ -194,20 +196,14 @@ static int run_awk (StdAwk& awk) static int awk_main (int argc, qse_char_t* argv[]) { - - MyConsoleHandler mch; - StdAwk awk; + MyAwk awk; int ret = awk.open (); - if (ret >= 0) - { - awk.setConsoleHandler (&mch); - ret = run_awk (awk); - } + if (ret >= 0) ret = run_awk (awk); if (ret <= -1) { - StdAwk::loc_t loc = awk.getErrorLocation(); + MyAwk::loc_t loc = awk.getErrorLocation(); print_error (loc, awk.getErrorMessage()); } diff --git a/qse/samples/awk/awk28.cpp b/qse/samples/awk/awk28.cpp new file mode 100644 index 00000000..e50489c2 --- /dev/null +++ b/qse/samples/awk/awk28.cpp @@ -0,0 +1,240 @@ +/* + * $Id$ + * + Copyright 2006-2012 Chung, Hyung-Hwan. + This file is part of QSE. + + QSE is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + QSE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with QSE. If not, see . + */ + +#include +#include +#include +#include +#include + +#include +#if defined(_WIN32) +# include +#endif + +#include +#if defined(QSE_CHAR_IS_WCHAR) +typedef std::wstring String; +#else +typedef std::string String; +#endif + +typedef QSE::StdAwk StdAwk; +typedef QSE::StdAwk::Run Run; +typedef QSE::StdAwk::Value Value; + +class MyConsoleHandler: public StdAwk::Console::Handler +{ +public: + // this class defines a console handler that can be + // registered into an awk object. + + void setInput (const StdAwk::char_t* instr) + { + this->input = instr; + this->inptr = this->input.c_str(); + this->inend = inptr + this->input.length(); + } + + const StdAwk::char_t* getOutput () { return this->output.c_str(); } + +protected: + String input; // console input buffer + const StdAwk::char_t* inptr; + const StdAwk::char_t* inend; + + String output; // console output buffer + + int open (StdAwk::Console& io) + { + if (io.getMode() == StdAwk::Console::READ) + { + this->inptr = this->input.c_str(); + this->inend = inptr + this->input.length(); + } + else + { + this->output.clear (); + } + + return 1; // return open-success + } + + int close (StdAwk::Console& io) + { + return 0; // return success + } + + int flush (StdAwk::Console& io) + { + // there is nothing to flush since a string buffer + // is used for a console output. just return success. + return 0; + } + int next (StdAwk::Console& io) + { + // this stripped-down awk doesn't honor the nextfile statement + // or the nextofile statement. just return failure. + return -1; + } + + ssize_t read (StdAwk::Console& io, StdAwk::char_t* data, size_t size) + { + if (this->inptr >= this->inend) return 0; // EOF + size_t x = qse_strxncpy (data, size, inptr, inend - inptr); + this->inptr += x; + return x; + } + + ssize_t write (StdAwk::Console& io, const StdAwk::char_t* data, size_t size) + { + try { this->output.append (data, size); } + catch (...) + { + ((StdAwk::Run*)io)->setError (QSE_AWK_ENOMEM); + return -1; + } + return size; + } +}; + +static void print_error ( + const StdAwk::loc_t& loc, const StdAwk::char_t* msg) +{ + if (loc.line > 0 || loc.colm > 0) + qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s at LINE %lu COLUMN %lu\n"), msg, loc.line, loc.colm); + else + qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), msg); + +} + +static int run_awk (StdAwk& awk) +{ + // sample input string + const qse_char_t* instr = QSE_T( + "aardvark 555-5553 1200/300 B\n" + "alpo-net 555-3412 2400/1200/300 A\n" + "barfly 555-7685 1200/300 A\n" + "bites 555-1675 2400/1200/300 A\n" + "camelot 555-0542 300 C\n" + "core 555-2912 1200/300 C\n" + "fooey 555-1234 2400/1200/300 B\n" + "foot 555-6699 1200/300 B\n" + "macfoo 555-6480 1200/300 A\n" + "sdace 555-3430 2400/1200/300 A\n" + "sabafoo 555-2127 1200/300 C\n"); + + const qse_char_t* instr2 = QSE_T( + "aardvark 555-5553 1200/300 A\n" + "alpo-net 555-3412 2400/1200/300 B\n" + "barfly 555-7685 1200/300 C\n" + "bites 555-1675 2400/1200/300 A\n" + "camelot 555-0542 300 C\n" + "core 555-2912 1200/300 B\n" + "fooey 555-1234 2400/1200/300 A\n" + "foot 555-6699 1200/300 A\n" + "macfoo 555-6480 1200/300 B\n" + "sdace 555-3430 2400/1200/300 B\n" + "sabafoo 555-2127 1200/300 A\n"); + + // ARGV[0] + if (awk.addArgument (QSE_T("awk14")) <= -1) return -1; + + // prepare a string to print lines with A in the fourth column + StdAwk::SourceString in (QSE_T("$4 == \"A\" { print $2, $1, $3; }")); + + // parse the script. + if (awk.parse (in, StdAwk::Source::NONE) == QSE_NULL) return -1; + StdAwk::Value r; + + MyConsoleHandler* mch = (MyConsoleHandler*)awk.getConsoleHandler(); + + mch->setInput (instr); // locate the input string + int x = awk.loop (&r); // execute the BEGIN, pattern-action, END blocks. + + if (x >= 0) + { + qse_printf (QSE_T("%s"), mch->getOutput()); // print the console output + qse_printf (QSE_T("-----------------------------\n")); + + mch->setInput (instr2); + + // reset the runtime context so that the next loop() method + // is performed over a new console stream. + if (awk.resetRunContext() == QSE_NULL) return -1; + + int x = awk.loop (&r); + + if (x >= 0) + { + qse_printf (QSE_T("%s"), mch->getOutput()); + qse_printf (QSE_T("-----------------------------\n")); + } + } + + return x; +} + +static int awk_main (int argc, qse_char_t* argv[]) +{ + + MyConsoleHandler mch; + StdAwk awk; + + int ret = awk.open (); + if (ret >= 0) + { + awk.setConsoleHandler (&mch); + ret = run_awk (awk); + } + + if (ret <= -1) + { + StdAwk::loc_t loc = awk.getErrorLocation(); + print_error (loc, awk.getErrorMessage()); + } + + awk.close (); + return ret; +} + +int qse_main (int argc, qse_achar_t* argv[]) +{ +#if defined(_WIN32) + char locale[100]; + UINT codepage = GetConsoleOutputCP(); + if (codepage == CP_UTF8) + { + /*SetConsoleOUtputCP (CP_UTF8);*/ + qse_setdflcmgrbyid (QSE_CMGR_UTF8); + } + else + { + sprintf (locale, ".%u", (unsigned int)codepage); + setlocale (LC_ALL, locale); + qse_setdflcmgrbyid (QSE_CMGR_SLMB); + } +#else + setlocale (LC_ALL, ""); + qse_setdflcmgrbyid (QSE_CMGR_SLMB); +#endif + + return qse_runmain (argc,argv,awk_main); +}