updated documentation
This commit is contained in:
parent
19b4e697af
commit
6e94d324ef
@ -9,7 +9,6 @@ EXTRA_DIST = \
|
|||||||
page/mem.doc \
|
page/mem.doc \
|
||||||
page/cenc.doc \
|
page/cenc.doc \
|
||||||
page/io.doc \
|
page/io.doc \
|
||||||
page/awk.doc \
|
|
||||||
page/awk-embed.md \
|
page/awk-embed.md \
|
||||||
page/awk-lang.md \
|
page/awk-lang.md \
|
||||||
page/sed.doc \
|
page/sed.doc \
|
||||||
|
@ -234,7 +234,6 @@ EXTRA_DIST = \
|
|||||||
page/mem.doc \
|
page/mem.doc \
|
||||||
page/cenc.doc \
|
page/cenc.doc \
|
||||||
page/io.doc \
|
page/io.doc \
|
||||||
page/awk.doc \
|
|
||||||
page/awk-embed.md \
|
page/awk-embed.md \
|
||||||
page/awk-lang.md \
|
page/awk-lang.md \
|
||||||
page/sed.doc \
|
page/sed.doc \
|
||||||
@ -432,6 +431,9 @@ uninstall-am:
|
|||||||
mostlyclean-libtool pdf pdf-am ps ps-am uninstall 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.
|
# 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.
|
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||||
.NOEXPORT:
|
.NOEXPORT:
|
||||||
|
@ -62,23 +62,31 @@ functions like *gsub* or *index*.
|
|||||||
|
|
||||||
\includelineno awk03.c
|
\includelineno awk03.c
|
||||||
|
|
||||||
If you want to pass arguments to the function you call with qse_awk_rtx_call(),
|
If you want to pass arguments to the function, you must create values with
|
||||||
you must create values with value creation functions, updates their reference
|
value creation functions, updates their reference count, and pass them to
|
||||||
count, and pass them to qse_awk_rtx_call(). The sample below creates 2 integer
|
qse_awk_rtx_call(). The sample below creates 2 integer values with
|
||||||
values with qse_awk_rtx_makeintval() and pass them to the *pow* function.
|
qse_awk_rtx_makeintval() and pass them to the *pow* function.
|
||||||
|
|
||||||
\includelineno awk04.c
|
\includelineno awk04.c
|
||||||
|
|
||||||
While qse_awk_rtx_call() looks up a function in the function table by name,
|
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
|
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
|
calling it. qse_awk_rtx_findfun() and qse_awk_rtx_callfun() come to play a role
|
||||||
to play a role in this situation. qse_awk_rtx_call() in the sample above
|
in this situation. qse_awk_rtx_call() in the sample above can be translated
|
||||||
can be translated into 2 separate calls to qse_awk_rtx_findfun() and
|
into 2 separate calls to qse_awk_rtx_findfun() and qse_awk_rtx_callfun().
|
||||||
qse_awk_rtx_callfun(). You can reduce look-up overhead via these 2
|
You can reduce look-up overhead via these 2 functions if you are to execute
|
||||||
functions if you have to execute the same function multiple times.
|
the same function multiple times.
|
||||||
|
|
||||||
\includelineno awk05.c
|
\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
|
Global Variables
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
@ -91,6 +99,29 @@ Built-in Functions
|
|||||||
You can add built-in functions with qse_awk_addfnc().
|
You can add built-in functions with qse_awk_addfnc().
|
||||||
On the other hand, modular built-in functions reside in a shared object.
|
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 <qse/awk/Awk.hpp>
|
||||||
|
and <qse/awk/StdAwk.hpp> 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
|
Changes in 0.6.0
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
@ -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
|
|
||||||
<b>BEGIN { print "hello, world" }</b>.
|
|
||||||
|
|
||||||
@code
|
|
||||||
/* cc -o hello hello.c -lqseawk -lqsecmn -lm */
|
|
||||||
#include <qse/awk/std.h>
|
|
||||||
#include <qse/cmn/stdio.h>
|
|
||||||
|
|
||||||
#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 <qse/awk/StdAwk.hpp>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#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
|
|
||||||
<project-root>/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
|
|
||||||
|
|
||||||
*/
|
|
@ -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:
|
The library is licensed under the GNU Lesser General Public License version 3:
|
||||||
http://www.gnu.org/licenses/
|
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:
|
For further information, contact:
|
||||||
Chung, Hyung-Hwan <hyunghwan.chung@gmail.com>
|
Chung, Hyung-Hwan <hyunghwan.chung@gmail.com>
|
||||||
@ -21,11 +21,10 @@ Chung, Hyung-Hwan <hyunghwan.chung@gmail.com>
|
|||||||
See the subpages for more information.
|
See the subpages for more information.
|
||||||
|
|
||||||
- @ref installation
|
- @ref installation
|
||||||
|
- @ref awk-lang
|
||||||
|
- @ref awk-embed
|
||||||
- @subpage mem "Memory Management"
|
- @subpage mem "Memory Management"
|
||||||
- @subpage cenc "Character Encoding"
|
- @subpage cenc "Character Encoding"
|
||||||
- @subpage io "I/O Handling"
|
- @subpage io "I/O Handling"
|
||||||
- @subpage awk "AWK Interpreter"
|
|
||||||
- @subpage sed "SED Stream Editor"
|
- @subpage sed "SED Stream Editor"
|
||||||
- @subpage awk-lang
|
|
||||||
- @subpage awk-embed
|
|
||||||
|
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
|
|
||||||
/// @file
|
/// @file
|
||||||
/// AWK Interpreter
|
/// AWK Interpreter
|
||||||
///
|
|
||||||
|
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
QSE_BEGIN_NAMESPACE(QSE)
|
QSE_BEGIN_NAMESPACE(QSE)
|
||||||
|
@ -27,33 +27,6 @@
|
|||||||
|
|
||||||
/// @file
|
/// @file
|
||||||
/// Standard AWK Interpreter
|
/// 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)
|
QSE_BEGIN_NAMESPACE(QSE)
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -24,7 +24,7 @@
|
|||||||
#include <qse/awk/awk.h>
|
#include <qse/awk/awk.h>
|
||||||
#include <qse/cmn/sio.h>
|
#include <qse/cmn/sio.h>
|
||||||
|
|
||||||
/** @file
|
/** \file
|
||||||
* This file defines functions and data types that help you create
|
* This file defines functions and data types that help you create
|
||||||
* an awk interpreter with less effort. It is designed to be as close
|
* an awk interpreter with less effort. It is designed to be as close
|
||||||
* to conventional awk implementations as possible.
|
* to conventional awk implementations as possible.
|
||||||
@ -34,16 +34,6 @@
|
|||||||
* normal file name.
|
* 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.
|
* 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 qse_awk_parsestd() functions parses source script.
|
||||||
* The code below shows how to parse a literal string 'BEGIN { print 10; }'
|
* The code below shows how to parse a literal string 'BEGIN { print 10; }'
|
||||||
* and deparses it out to a buffer 'buf'.
|
* and deparses it out to a buffer 'buf'.
|
||||||
* @code
|
* \code
|
||||||
* int n;
|
* int n;
|
||||||
* qse_awk_parsestd_t in[2];
|
* qse_awk_parsestd_t in[2];
|
||||||
* qse_awk_parsestd_t out;
|
* 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_printf (QSE_T("%s\n"), out.u.str.ptr);
|
||||||
* QSE_MMGR_FREE (out.u.str.ptr);
|
* QSE_MMGR_FREE (out.u.str.ptr);
|
||||||
* }
|
* }
|
||||||
* @endcode
|
* \endcode
|
||||||
*/
|
*/
|
||||||
QSE_EXPORT int qse_awk_parsestd (
|
QSE_EXPORT int qse_awk_parsestd (
|
||||||
qse_awk_t* awk,
|
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 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 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
|
* 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.
|
* 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_EXPORT qse_awk_rtx_t* qse_awk_rtx_openstd (
|
||||||
qse_awk_t* awk,
|
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
|
* The qse_awk_rtx_getcmgrstd() function gets the current character
|
||||||
* manager associated with a particular I/O target indicated by the name
|
* 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.
|
* if #QSE_CHAR_IS_MCHAR is defined.
|
||||||
*/
|
*/
|
||||||
QSE_EXPORT qse_cmgr_t* qse_awk_rtx_getcmgrstd (
|
QSE_EXPORT qse_cmgr_t* qse_awk_rtx_getcmgrstd (
|
||||||
|
@ -5,7 +5,7 @@ AM_CPPFLAGS = \
|
|||||||
-I$(top_srcdir)/include \
|
-I$(top_srcdir)/include \
|
||||||
-I$(includedir)
|
-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
|
LDFLAGS = -L../../lib/awk -L../../lib/cmn
|
||||||
LDADD = -lqseawk -lqsecmn $(LIBM)
|
LDADD = -lqseawk -lqsecmn $(LIBM)
|
||||||
@ -21,8 +21,8 @@ awk02_SOURCES = awk02.c
|
|||||||
awk03_SOURCES = awk03.c
|
awk03_SOURCES = awk03.c
|
||||||
awk04_SOURCES = awk04.c
|
awk04_SOURCES = awk04.c
|
||||||
awk05_SOURCES = awk05.c
|
awk05_SOURCES = awk05.c
|
||||||
|
awk06_SOURCES = awk06.c
|
||||||
awk09_SOURCES = awk09.c
|
awk09_SOURCES = awk09.c
|
||||||
awk10_SOURCES = awk10.c
|
|
||||||
awk11_SOURCES = awk11.c
|
awk11_SOURCES = awk11.c
|
||||||
awk15_SOURCES = awk15.c
|
awk15_SOURCES = awk15.c
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ if ENABLE_CXX
|
|||||||
|
|
||||||
CXXLIB = -lqseawkxx -lqsecmnxx
|
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
|
awk21_SOURCES = awk21.cpp
|
||||||
awk22_SOURCES = awk22.cpp
|
awk22_SOURCES = awk22.cpp
|
||||||
@ -39,6 +39,7 @@ awk24_SOURCES = awk24.cpp
|
|||||||
awk25_SOURCES = awk25.cpp
|
awk25_SOURCES = awk25.cpp
|
||||||
awk26_SOURCES = awk26.cpp
|
awk26_SOURCES = awk26.cpp
|
||||||
awk27_SOURCES = awk27.cpp
|
awk27_SOURCES = awk27.cpp
|
||||||
|
awk28_SOURCES = awk27.cpp
|
||||||
|
|
||||||
awk21_LDADD = $(CXXLIB) $(LDADD)
|
awk21_LDADD = $(CXXLIB) $(LDADD)
|
||||||
awk22_LDADD = $(CXXLIB) $(LDADD)
|
awk22_LDADD = $(CXXLIB) $(LDADD)
|
||||||
@ -47,4 +48,5 @@ awk24_LDADD = $(CXXLIB) $(LDADD)
|
|||||||
awk25_LDADD = $(CXXLIB) $(LDADD)
|
awk25_LDADD = $(CXXLIB) $(LDADD)
|
||||||
awk26_LDADD = $(CXXLIB) $(LDADD)
|
awk26_LDADD = $(CXXLIB) $(LDADD)
|
||||||
awk27_LDADD = $(CXXLIB) $(LDADD)
|
awk27_LDADD = $(CXXLIB) $(LDADD)
|
||||||
|
awk28_LDADD = $(CXXLIB) $(LDADD)
|
||||||
endif
|
endif
|
||||||
|
@ -35,10 +35,10 @@ POST_UNINSTALL = :
|
|||||||
build_triplet = @build@
|
build_triplet = @build@
|
||||||
host_triplet = @host@
|
host_triplet = @host@
|
||||||
bin_PROGRAMS = awk01$(EXEEXT) awk02$(EXEEXT) awk03$(EXEEXT) \
|
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)
|
awk11$(EXEEXT) awk15$(EXEEXT) $(am__EXEEXT_1)
|
||||||
@WCHAR_TRUE@@WIN32_TRUE@am__append_1 = $(UNICOWS_LIBS)
|
@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
|
subdir = samples/awk
|
||||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||||
@ -56,7 +56,7 @@ CONFIG_CLEAN_FILES =
|
|||||||
CONFIG_CLEAN_VPATH_FILES =
|
CONFIG_CLEAN_VPATH_FILES =
|
||||||
@ENABLE_CXX_TRUE@am__EXEEXT_1 = awk21$(EXEEXT) awk22$(EXEEXT) \
|
@ENABLE_CXX_TRUE@am__EXEEXT_1 = awk21$(EXEEXT) awk22$(EXEEXT) \
|
||||||
@ENABLE_CXX_TRUE@ awk23$(EXEEXT) awk24$(EXEEXT) awk25$(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)"
|
am__installdirs = "$(DESTDIR)$(bindir)"
|
||||||
PROGRAMS = $(bin_PROGRAMS)
|
PROGRAMS = $(bin_PROGRAMS)
|
||||||
am_awk01_OBJECTS = awk01.$(OBJEXT)
|
am_awk01_OBJECTS = awk01.$(OBJEXT)
|
||||||
@ -81,14 +81,14 @@ am_awk05_OBJECTS = awk05.$(OBJEXT)
|
|||||||
awk05_OBJECTS = $(am_awk05_OBJECTS)
|
awk05_OBJECTS = $(am_awk05_OBJECTS)
|
||||||
awk05_LDADD = $(LDADD)
|
awk05_LDADD = $(LDADD)
|
||||||
awk05_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
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)
|
am_awk09_OBJECTS = awk09.$(OBJEXT)
|
||||||
awk09_OBJECTS = $(am_awk09_OBJECTS)
|
awk09_OBJECTS = $(am_awk09_OBJECTS)
|
||||||
awk09_LDADD = $(LDADD)
|
awk09_LDADD = $(LDADD)
|
||||||
awk09_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
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)
|
am_awk11_OBJECTS = awk11.$(OBJEXT)
|
||||||
awk11_OBJECTS = $(am_awk11_OBJECTS)
|
awk11_OBJECTS = $(am_awk11_OBJECTS)
|
||||||
awk11_LDADD = $(LDADD)
|
awk11_LDADD = $(LDADD)
|
||||||
@ -133,6 +133,11 @@ am__awk27_SOURCES_DIST = awk27.cpp
|
|||||||
awk27_OBJECTS = $(am_awk27_OBJECTS)
|
awk27_OBJECTS = $(am_awk27_OBJECTS)
|
||||||
@ENABLE_CXX_TRUE@awk27_DEPENDENCIES = $(am__DEPENDENCIES_1) \
|
@ENABLE_CXX_TRUE@awk27_DEPENDENCIES = $(am__DEPENDENCIES_1) \
|
||||||
@ENABLE_CXX_TRUE@ $(am__DEPENDENCIES_3)
|
@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 =
|
DEFAULT_INCLUDES =
|
||||||
depcomp = $(SHELL) $(top_srcdir)/ac/depcomp
|
depcomp = $(SHELL) $(top_srcdir)/ac/depcomp
|
||||||
am__depfiles_maybe = depfiles
|
am__depfiles_maybe = depfiles
|
||||||
@ -156,18 +161,18 @@ CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
|||||||
--mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
|
--mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
|
||||||
$(LDFLAGS) -o $@
|
$(LDFLAGS) -o $@
|
||||||
SOURCES = $(awk01_SOURCES) $(awk02_SOURCES) $(awk03_SOURCES) \
|
SOURCES = $(awk01_SOURCES) $(awk02_SOURCES) $(awk03_SOURCES) \
|
||||||
$(awk04_SOURCES) $(awk05_SOURCES) $(awk09_SOURCES) \
|
$(awk04_SOURCES) $(awk05_SOURCES) $(awk06_SOURCES) \
|
||||||
$(awk10_SOURCES) $(awk11_SOURCES) $(awk15_SOURCES) \
|
$(awk09_SOURCES) $(awk11_SOURCES) $(awk15_SOURCES) \
|
||||||
$(awk21_SOURCES) $(awk22_SOURCES) $(awk23_SOURCES) \
|
$(awk21_SOURCES) $(awk22_SOURCES) $(awk23_SOURCES) \
|
||||||
$(awk24_SOURCES) $(awk25_SOURCES) $(awk26_SOURCES) \
|
$(awk24_SOURCES) $(awk25_SOURCES) $(awk26_SOURCES) \
|
||||||
$(awk27_SOURCES)
|
$(awk27_SOURCES) $(awk28_SOURCES)
|
||||||
DIST_SOURCES = $(awk01_SOURCES) $(awk02_SOURCES) $(awk03_SOURCES) \
|
DIST_SOURCES = $(awk01_SOURCES) $(awk02_SOURCES) $(awk03_SOURCES) \
|
||||||
$(awk04_SOURCES) $(awk05_SOURCES) $(awk09_SOURCES) \
|
$(awk04_SOURCES) $(awk05_SOURCES) $(awk06_SOURCES) \
|
||||||
$(awk10_SOURCES) $(awk11_SOURCES) $(awk15_SOURCES) \
|
$(awk09_SOURCES) $(awk11_SOURCES) $(awk15_SOURCES) \
|
||||||
$(am__awk21_SOURCES_DIST) $(am__awk22_SOURCES_DIST) \
|
$(am__awk21_SOURCES_DIST) $(am__awk22_SOURCES_DIST) \
|
||||||
$(am__awk23_SOURCES_DIST) $(am__awk24_SOURCES_DIST) \
|
$(am__awk23_SOURCES_DIST) $(am__awk24_SOURCES_DIST) \
|
||||||
$(am__awk25_SOURCES_DIST) $(am__awk26_SOURCES_DIST) \
|
$(am__awk25_SOURCES_DIST) $(am__awk26_SOURCES_DIST) \
|
||||||
$(am__awk27_SOURCES_DIST)
|
$(am__awk27_SOURCES_DIST) $(am__awk28_SOURCES_DIST)
|
||||||
ETAGS = etags
|
ETAGS = etags
|
||||||
CTAGS = ctags
|
CTAGS = ctags
|
||||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||||
@ -354,8 +359,8 @@ awk02_SOURCES = awk02.c
|
|||||||
awk03_SOURCES = awk03.c
|
awk03_SOURCES = awk03.c
|
||||||
awk04_SOURCES = awk04.c
|
awk04_SOURCES = awk04.c
|
||||||
awk05_SOURCES = awk05.c
|
awk05_SOURCES = awk05.c
|
||||||
|
awk06_SOURCES = awk06.c
|
||||||
awk09_SOURCES = awk09.c
|
awk09_SOURCES = awk09.c
|
||||||
awk10_SOURCES = awk10.c
|
|
||||||
awk11_SOURCES = awk11.c
|
awk11_SOURCES = awk11.c
|
||||||
awk15_SOURCES = awk15.c
|
awk15_SOURCES = awk15.c
|
||||||
@ENABLE_CXX_TRUE@CXXLIB = -lqseawkxx -lqsecmnxx
|
@ENABLE_CXX_TRUE@CXXLIB = -lqseawkxx -lqsecmnxx
|
||||||
@ -366,6 +371,7 @@ awk15_SOURCES = awk15.c
|
|||||||
@ENABLE_CXX_TRUE@awk25_SOURCES = awk25.cpp
|
@ENABLE_CXX_TRUE@awk25_SOURCES = awk25.cpp
|
||||||
@ENABLE_CXX_TRUE@awk26_SOURCES = awk26.cpp
|
@ENABLE_CXX_TRUE@awk26_SOURCES = awk26.cpp
|
||||||
@ENABLE_CXX_TRUE@awk27_SOURCES = awk27.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@awk21_LDADD = $(CXXLIB) $(LDADD)
|
||||||
@ENABLE_CXX_TRUE@awk22_LDADD = $(CXXLIB) $(LDADD)
|
@ENABLE_CXX_TRUE@awk22_LDADD = $(CXXLIB) $(LDADD)
|
||||||
@ENABLE_CXX_TRUE@awk23_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@awk25_LDADD = $(CXXLIB) $(LDADD)
|
||||||
@ENABLE_CXX_TRUE@awk26_LDADD = $(CXXLIB) $(LDADD)
|
@ENABLE_CXX_TRUE@awk26_LDADD = $(CXXLIB) $(LDADD)
|
||||||
@ENABLE_CXX_TRUE@awk27_LDADD = $(CXXLIB) $(LDADD)
|
@ENABLE_CXX_TRUE@awk27_LDADD = $(CXXLIB) $(LDADD)
|
||||||
|
@ENABLE_CXX_TRUE@awk28_LDADD = $(CXXLIB) $(LDADD)
|
||||||
all: all-am
|
all: all-am
|
||||||
|
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
@ -465,12 +472,12 @@ awk04$(EXEEXT): $(awk04_OBJECTS) $(awk04_DEPENDENCIES) $(EXTRA_awk04_DEPENDENCIE
|
|||||||
awk05$(EXEEXT): $(awk05_OBJECTS) $(awk05_DEPENDENCIES) $(EXTRA_awk05_DEPENDENCIES)
|
awk05$(EXEEXT): $(awk05_OBJECTS) $(awk05_DEPENDENCIES) $(EXTRA_awk05_DEPENDENCIES)
|
||||||
@rm -f awk05$(EXEEXT)
|
@rm -f awk05$(EXEEXT)
|
||||||
$(LINK) $(awk05_OBJECTS) $(awk05_LDADD) $(LIBS)
|
$(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)
|
awk09$(EXEEXT): $(awk09_OBJECTS) $(awk09_DEPENDENCIES) $(EXTRA_awk09_DEPENDENCIES)
|
||||||
@rm -f awk09$(EXEEXT)
|
@rm -f awk09$(EXEEXT)
|
||||||
$(LINK) $(awk09_OBJECTS) $(awk09_LDADD) $(LIBS)
|
$(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)
|
awk11$(EXEEXT): $(awk11_OBJECTS) $(awk11_DEPENDENCIES) $(EXTRA_awk11_DEPENDENCIES)
|
||||||
@rm -f awk11$(EXEEXT)
|
@rm -f awk11$(EXEEXT)
|
||||||
$(LINK) $(awk11_OBJECTS) $(awk11_LDADD) $(LIBS)
|
$(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)
|
awk27$(EXEEXT): $(awk27_OBJECTS) $(awk27_DEPENDENCIES) $(EXTRA_awk27_DEPENDENCIES)
|
||||||
@rm -f awk27$(EXEEXT)
|
@rm -f awk27$(EXEEXT)
|
||||||
$(CXXLINK) $(awk27_OBJECTS) $(awk27_LDADD) $(LIBS)
|
$(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:
|
mostlyclean-compile:
|
||||||
-rm -f *.$(OBJEXT)
|
-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)/awk03.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk04.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)/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)/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)/awk11.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk15.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@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk21.Po@am__quote@
|
||||||
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <qse/awk/std.h>
|
#include <qse/awk/std.h>
|
||||||
#include <qse/cmn/stdio.h>
|
#include <qse/cmn/stdio.h>
|
||||||
|
|
||||||
@ -32,20 +12,18 @@ int main ()
|
|||||||
qse_awk_parsestd_t psin[2];
|
qse_awk_parsestd_t psin[2];
|
||||||
qse_awk_val_t* rtv = QSE_NULL;
|
qse_awk_val_t* rtv = QSE_NULL;
|
||||||
qse_awk_val_t* arg = QSE_NULL;
|
qse_awk_val_t* arg = QSE_NULL;
|
||||||
int ret, i, opt;
|
int ret, opt;
|
||||||
struct
|
|
||||||
|
/* this structure is passed to qse_awk_rtx_makemapvalwithdata() */
|
||||||
|
qse_awk_val_map_data_t md[] =
|
||||||
{
|
{
|
||||||
const qse_char_t* kptr;
|
{ { QSE_T("f0"), 2 }, QSE_AWK_VAL_MAP_DATA_STR, QSE_T("linux") },
|
||||||
qse_size_t klen;
|
{ { QSE_T("f1"), 2 }, QSE_AWK_VAL_MAP_DATA_STR, QSE_T("openvms") },
|
||||||
const qse_char_t* vptr;
|
{ { QSE_T("f2"), 2 }, QSE_AWK_VAL_MAP_DATA_STR, QSE_T("hpux") },
|
||||||
} xxx[] =
|
{ { QSE_NULL, 0 }, 0, QSE_NULL } /* last item */
|
||||||
{
|
|
||||||
{ QSE_T("f0"), 2, QSE_T("linux") },
|
|
||||||
{ QSE_T("f1"), 2, QSE_T("openvms") },
|
|
||||||
{ QSE_T("f2"), 2, QSE_T("hpux") }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* create a main processor */
|
/* create a standard awk object */
|
||||||
awk = qse_awk_openstd (0);
|
awk = qse_awk_openstd (0);
|
||||||
if (awk == QSE_NULL)
|
if (awk == QSE_NULL)
|
||||||
{
|
{
|
||||||
@ -53,18 +31,20 @@ int main ()
|
|||||||
ret = -1; goto oops;
|
ret = -1; goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* get the awk's trait */
|
||||||
qse_awk_getopt (awk, QSE_AWK_TRAIT, &opt);
|
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;
|
opt &= ~QSE_AWK_PABLOCK;
|
||||||
/* can assign a map to a variable */
|
/* update the trait */
|
||||||
opt |= QSE_AWK_FLEXMAP;
|
|
||||||
qse_awk_setopt (awk, QSE_AWK_TRAIT, &opt);
|
qse_awk_setopt (awk, QSE_AWK_TRAIT, &opt);
|
||||||
|
|
||||||
|
/* prepare a script to parse */
|
||||||
psin[0].type = QSE_AWK_PARSESTD_STR;
|
psin[0].type = QSE_AWK_PARSESTD_STR;
|
||||||
psin[0].u.str.ptr = src;
|
psin[0].u.str.ptr = src;
|
||||||
psin[0].u.str.len = qse_strlen(src);
|
psin[0].u.str.len = qse_strlen(src);
|
||||||
psin[1].type = QSE_AWK_PARSESTD_NULL;
|
psin[1].type = QSE_AWK_PARSESTD_NULL;
|
||||||
|
|
||||||
|
/* parse the script */
|
||||||
ret = qse_awk_parsestd (awk, psin, QSE_NULL);
|
ret = qse_awk_parsestd (awk, psin, QSE_NULL);
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
{
|
{
|
||||||
@ -73,11 +53,11 @@ int main ()
|
|||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create a runtime context */
|
/* create a standard runtime context */
|
||||||
rtx = qse_awk_rtx_openstd (
|
rtx = qse_awk_rtx_openstd (
|
||||||
awk,
|
awk,
|
||||||
0,
|
0,
|
||||||
QSE_T("awk10"),
|
QSE_T("awk06"),
|
||||||
QSE_NULL, /* stdin */
|
QSE_NULL, /* stdin */
|
||||||
QSE_NULL, /* stdout */
|
QSE_NULL, /* stdout */
|
||||||
QSE_NULL /* default cmgr */
|
QSE_NULL /* default cmgr */
|
||||||
@ -90,8 +70,8 @@ int main ()
|
|||||||
ret = -1; goto oops;
|
ret = -1; goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* prepare a argument to be a map */
|
/* create a map value to pass as an argument */
|
||||||
arg = qse_awk_rtx_makemapval (rtx);
|
arg = qse_awk_rtx_makemapvalwithdata (rtx, md);
|
||||||
if (arg == QSE_NULL)
|
if (arg == QSE_NULL)
|
||||||
{
|
{
|
||||||
qse_fprintf (QSE_STDERR, QSE_T("error: %s\n"),
|
qse_fprintf (QSE_STDERR, QSE_T("error: %s\n"),
|
||||||
@ -100,30 +80,7 @@ int main ()
|
|||||||
}
|
}
|
||||||
qse_awk_rtx_refupval (rtx, arg);
|
qse_awk_rtx_refupval (rtx, arg);
|
||||||
|
|
||||||
/* insert some key/value pairs into the map */
|
/* execute the dump function in the awk script */
|
||||||
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 */
|
|
||||||
rtv = qse_awk_rtx_call (rtx, QSE_T("dump"), &arg, 1);
|
rtv = qse_awk_rtx_call (rtx, QSE_T("dump"), &arg, 1);
|
||||||
if (rtv == QSE_NULL)
|
if (rtv == QSE_NULL)
|
||||||
{
|
{
|
||||||
@ -132,17 +89,21 @@ int main ()
|
|||||||
ret = -1; goto oops;
|
ret = -1; goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* print the return value */
|
|
||||||
if (rtv->type == QSE_AWK_VAL_MAP)
|
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 itr;
|
||||||
qse_awk_val_map_itr_t* iptr;
|
qse_awk_val_map_itr_t* iptr;
|
||||||
|
|
||||||
|
/* get the iterator to the first key/value pair */
|
||||||
iptr = qse_awk_rtx_getfirstmapvalitr (rtx, rtv, &itr);
|
iptr = qse_awk_rtx_getfirstmapvalitr (rtx, rtv, &itr);
|
||||||
while (iptr)
|
while (iptr)
|
||||||
{
|
{
|
||||||
qse_xstr_t str;
|
qse_xstr_t str;
|
||||||
|
|
||||||
|
/* #QSE_AWK_VAL_MAP_ITR_VAL returns the value part */
|
||||||
str.ptr = qse_awk_rtx_valtostrdup (
|
str.ptr = qse_awk_rtx_valtostrdup (
|
||||||
rtx, QSE_AWK_VAL_MAP_ITR_VAL(iptr), &str.len);
|
rtx, QSE_AWK_VAL_MAP_ITR_VAL(iptr), &str.len);
|
||||||
if (str.ptr == QSE_NULL)
|
if (str.ptr == QSE_NULL)
|
||||||
@ -152,6 +113,7 @@ int main ()
|
|||||||
ret = -1; goto oops;
|
ret = -1; goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* #QSE_AWK_VAL_MAP_ITR_KEY returns the key part */
|
||||||
qse_printf (QSE_T("ret [%.*s]=[%.*s]\n"),
|
qse_printf (QSE_T("ret [%.*s]=[%.*s]\n"),
|
||||||
(int)QSE_AWK_VAL_MAP_ITR_KEY(iptr)->len,
|
(int)QSE_AWK_VAL_MAP_ITR_KEY(iptr)->len,
|
||||||
QSE_AWK_VAL_MAP_ITR_KEY(iptr)->ptr,
|
QSE_AWK_VAL_MAP_ITR_KEY(iptr)->ptr,
|
||||||
@ -159,11 +121,14 @@ int main ()
|
|||||||
);
|
);
|
||||||
qse_awk_rtx_freemem (rtx, str.ptr);
|
qse_awk_rtx_freemem (rtx, str.ptr);
|
||||||
|
|
||||||
|
/* get the iterator to the next key/value pair */
|
||||||
iptr = qse_awk_rtx_getnextmapvalitr (rtx, rtv, &itr);
|
iptr = qse_awk_rtx_getnextmapvalitr (rtx, rtv, &itr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* if it is a plain value, convert it to a string
|
||||||
|
* and print it */
|
||||||
qse_xstr_t str;
|
qse_xstr_t str;
|
||||||
|
|
||||||
str.ptr = qse_awk_rtx_valtostrdup (rtx, rtv, &str.len);
|
str.ptr = qse_awk_rtx_valtostrdup (rtx, rtv, &str.len);
|
||||||
@ -187,7 +152,9 @@ oops:
|
|||||||
|
|
||||||
/* destroy a runtime context */
|
/* destroy a runtime context */
|
||||||
if (rtx) qse_awk_rtx_close (rtx);
|
if (rtx) qse_awk_rtx_close (rtx);
|
||||||
|
|
||||||
/* destroy the processor */
|
/* destroy the processor */
|
||||||
if (awk) qse_awk_close (awk);
|
if (awk) qse_awk_close (awk);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <qse/awk/StdAwk.hpp>
|
#include <qse/awk/StdAwk.hpp>
|
||||||
#include <qse/cmn/stdio.h>
|
#include <iostream>
|
||||||
#include <qse/cmn/main.h>
|
|
||||||
#include <qse/cmn/mbwc.h>
|
|
||||||
|
|
||||||
#include <locale.h>
|
#if defined(QSE_CHAR_IS_MCHAR)
|
||||||
#if defined(_WIN32)
|
# define xcout std::cout
|
||||||
# include <windows.h>
|
|
||||||
#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);
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
setlocale (LC_ALL, "");
|
# define xcout std::wcout
|
||||||
qse_setdflcmgrbyid (QSE_CMGR_SLMB);
|
|
||||||
#endif
|
#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; \
|
||||||
}
|
}
|
||||||
|
@ -40,54 +40,27 @@ static void print_error (
|
|||||||
|
|
||||||
static int run_awk (QSE::StdAwk& awk)
|
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(
|
const qse_char_t* script = QSE_T(
|
||||||
"function add (a, b) { return a + b }\n"
|
"BEGIN { print \">> PRINT ALL LINES WHOSE LENGTH IS GREATER THAN 0\"; }\n"
|
||||||
"function mul (a, b) { return a * b }\n"
|
"length($0) > 0 { print $0; count++; }\n"
|
||||||
"function div (a, b) { return a / b }\n"
|
"END { print \">> TOTAL\", count, \"LINES\"; }\n"
|
||||||
"function sine (a) { return sin(a) }\n"
|
|
||||||
);
|
);
|
||||||
|
|
||||||
QSE::StdAwk::SourceString in (script);
|
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
|
// parse the script string and deparse it to awk05.out.
|
||||||
run = awk.parse (in, out);
|
if (awk.parse (in, out) == QSE_NULL) return -1;
|
||||||
if (run == QSE_NULL) return -1;
|
|
||||||
|
|
||||||
QSE::StdAwk::Value arg[2];
|
QSE::StdAwk::Value r;
|
||||||
if (arg[0].setInt (run, -20) <= -1) return -1;
|
// execute the BEGIN, pattern-action, END blocks.
|
||||||
if (arg[1].setStr (run, QSE_T("51")) <= -1) return -1;
|
return awk.loop (&r);
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int awk_main (int argc, qse_char_t* argv[])
|
static int awk_main (int argc, qse_char_t* argv[])
|
||||||
@ -95,8 +68,8 @@ static int awk_main (int argc, qse_char_t* argv[])
|
|||||||
QSE::StdAwk awk;
|
QSE::StdAwk awk;
|
||||||
|
|
||||||
int ret = awk.open ();
|
int ret = awk.open ();
|
||||||
|
|
||||||
if (ret >= 0) ret = run_awk (awk);
|
if (ret >= 0) ret = run_awk (awk);
|
||||||
|
|
||||||
if (ret <= -1)
|
if (ret <= -1)
|
||||||
{
|
{
|
||||||
QSE::StdAwk::loc_t loc = awk.getErrorLocation();
|
QSE::StdAwk::loc_t loc = awk.getErrorLocation();
|
||||||
@ -104,7 +77,7 @@ static int awk_main (int argc, qse_char_t* argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
awk.close ();
|
awk.close ();
|
||||||
return -1;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int qse_main (int argc, qse_achar_t* argv[])
|
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, "");
|
setlocale (LC_ALL, "");
|
||||||
qse_setdflcmgrbyid (QSE_CMGR_SLMB);
|
qse_setdflcmgrbyid (QSE_CMGR_SLMB);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return qse_runmain (argc,argv,awk_main);
|
return qse_runmain (argc,argv,awk_main);
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void print_error (
|
static void print_error (
|
||||||
const QSE::StdAwk::loc_t& loc, const QSE::StdAwk::char_t* msg)
|
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::Run* run;
|
||||||
|
|
||||||
QSE::StdAwk::SourceString in (QSE_T(
|
const qse_char_t* script = QSE_T(
|
||||||
"function pa (x) {\n"
|
"function add (a, b) { return a + b }\n"
|
||||||
" @reset ret;\n"
|
"function mul (a, b) { return a * b }\n"
|
||||||
" for (i in x) { print i, \"=>\", x[i]; ret += x[i]; }\n"
|
"function div (a, b) { return a / b }\n"
|
||||||
" return ret + FOO++;\n"
|
"function sine (a) { return sin(a) }\n"
|
||||||
"}\n"
|
|
||||||
"function pb (x) {\n"
|
|
||||||
" @reset ret;\n"
|
|
||||||
" for (i in x) { ret[-i] = -x[i]; }\n"
|
|
||||||
" return ret;\n"
|
|
||||||
"}"
|
|
||||||
));
|
|
||||||
|
|
||||||
// add a global variable 'FOO'
|
|
||||||
int foo = awk.addGlobal (QSE_T("FOO"));
|
|
||||||
if (foo <= -1) return -1;
|
|
||||||
|
|
||||||
// parse the script and perform no deparsing
|
|
||||||
run = awk.parse (in, QSE::StdAwk::Source::NONE);
|
|
||||||
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;
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
// 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 (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);
|
QSE::StdAwk::SourceString in (script);
|
||||||
}
|
QSE::StdAwk::SourceFile out (QSE_T("awk06.out"));
|
||||||
|
|
||||||
|
// parse the script and deparse it to awk06.out
|
||||||
|
run = awk.parse (in, out);
|
||||||
|
if (run == 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;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -135,9 +96,6 @@ static int awk_main (int argc, qse_char_t* argv[])
|
|||||||
|
|
||||||
int ret = awk.open();
|
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 >= 0) ret = run_awk (awk);
|
||||||
if (ret <= -1)
|
if (ret <= -1)
|
||||||
{
|
{
|
||||||
|
@ -19,402 +19,111 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <qse/awk/StdAwk.hpp>
|
#include <qse/awk/StdAwk.hpp>
|
||||||
#include <qse/cmn/opt.h>
|
#include <qse/cmn/stdio.h>
|
||||||
#include <qse/cmn/main.h>
|
#include <qse/cmn/main.h>
|
||||||
#include <qse/cmn/mbwc.h>
|
#include <qse/cmn/mbwc.h>
|
||||||
#include <qse/cmn/stdio.h>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
#elif defined(__OS2__)
|
|
||||||
# define INCL_DOSPROCESS
|
|
||||||
# include <os2.h>
|
|
||||||
#else
|
|
||||||
# include <unistd.h>
|
|
||||||
# include <signal.h>
|
|
||||||
# include <errno.h>
|
|
||||||
#endif
|
#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:
|
if (loc.line > 0 || loc.colm > 0)
|
||||||
MyAwk () { }
|
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s at LINE %lu COLUMN %lu\n"), msg, loc.line, loc.colm);
|
||||||
~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());
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), msg);
|
||||||
print_error (QSE_T("line %u - %s\n"), (unsigned)loc.line, awk.getErrorMessage());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
static int run_awk (QSE::StdAwk& awk)
|
||||||
static BOOL WINAPI stop_run (DWORD ctrl_type)
|
|
||||||
{
|
{
|
||||||
if (ctrl_type == CTRL_C_EVENT ||
|
QSE::StdAwk::Run* run;
|
||||||
ctrl_type == CTRL_CLOSE_EVENT)
|
|
||||||
|
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"
|
||||||
|
"}"
|
||||||
|
));
|
||||||
|
|
||||||
|
// add a global variable 'FOO'
|
||||||
|
int foo = awk.addGlobal (QSE_T("FOO"));
|
||||||
|
if (foo <= -1) return -1;
|
||||||
|
|
||||||
|
// parse the script and perform no deparsing
|
||||||
|
run = awk.parse (in, QSE::StdAwk::Source::NONE);
|
||||||
|
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;
|
||||||
|
|
||||||
|
// prepare an indexed parameter
|
||||||
|
QSE::StdAwk::Value arg[1];
|
||||||
|
for (int i = 1; i <= 5; i++)
|
||||||
{
|
{
|
||||||
if (app_awk) app_awk->stop ();
|
if (arg[0].setIndexedInt (run,
|
||||||
return TRUE;
|
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;
|
||||||
|
|
||||||
return FALSE;
|
QSE::StdAwk::Value dummy;
|
||||||
}
|
if (dummy.setStr (run, QSE_T("4567")) <= -1) return -1;
|
||||||
#else
|
if (arg[0].setIndexedVal (run,
|
||||||
|
QSE::StdAwk::Value::IntIndex(999), dummy) <= -1) return -1;
|
||||||
|
|
||||||
static int setsignal (int sig, void(*handler)(int), int restart)
|
// 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)
|
||||||
{
|
{
|
||||||
struct sigaction sa_int;
|
if (r.getIndexed (idx, &v) <= -1) return -1;
|
||||||
|
|
||||||
sa_int.sa_handler = handler;
|
qse_printf (QSE_T("\t[%.*s]=>[%lld]\n"),
|
||||||
sigemptyset (&sa_int.sa_mask);
|
(int)idx.length(), idx.pointer(),
|
||||||
|
(long long)v.toInt()
|
||||||
|
);
|
||||||
|
|
||||||
sa_int.sa_flags = 0;
|
iter = r.getNextIndex (&idx, iter);
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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 (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;
|
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[])
|
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);
|
QSE::StdAwk::loc_t loc = awk.getErrorLocation();
|
||||||
return -1;
|
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 ();
|
awk.close ();
|
||||||
return n;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int qse_main (int argc, qse_achar_t* argv[])
|
int qse_main (int argc, qse_achar_t* argv[])
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
char locale[100];
|
char locale[100];
|
||||||
UINT codepage;
|
UINT codepage = GetConsoleOutputCP();
|
||||||
WSADATA wsadata;
|
|
||||||
|
|
||||||
codepage = GetConsoleOutputCP();
|
|
||||||
if (codepage == CP_UTF8)
|
if (codepage == CP_UTF8)
|
||||||
{
|
{
|
||||||
/*SetConsoleOUtputCP (CP_UTF8);*/
|
/*SetConsoleOUtputCP (CP_UTF8);*/
|
||||||
@ -461,23 +165,9 @@ int qse_main (int argc, qse_achar_t* argv[])
|
|||||||
setlocale (LC_ALL, locale);
|
setlocale (LC_ALL, locale);
|
||||||
qse_setdflcmgrbyid (QSE_CMGR_SLMB);
|
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
|
#else
|
||||||
setlocale (LC_ALL, "");
|
setlocale (LC_ALL, "");
|
||||||
qse_setdflcmgrbyid (QSE_CMGR_SLMB);
|
qse_setdflcmgrbyid (QSE_CMGR_SLMB);
|
||||||
#endif
|
#endif
|
||||||
|
return qse_runmain (argc,argv,awk_main);
|
||||||
ret = qse_runmain (argc, argv, awk_main);
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
WSACleanup ();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
@ -19,23 +19,26 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <qse/awk/StdAwk.hpp>
|
#include <qse/awk/StdAwk.hpp>
|
||||||
#include <qse/cmn/stdio.h>
|
#include <qse/cmn/opt.h>
|
||||||
#include <qse/cmn/main.h>
|
#include <qse/cmn/main.h>
|
||||||
#include <qse/cmn/mbwc.h>
|
#include <qse/cmn/mbwc.h>
|
||||||
#include <qse/cmn/str.h>
|
#include <qse/cmn/stdio.h>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
#endif
|
#elif defined(__OS2__)
|
||||||
|
# define INCL_DOSPROCESS
|
||||||
#include <string>
|
# include <os2.h>
|
||||||
#if defined(QSE_CHAR_IS_WCHAR)
|
|
||||||
typedef std::wstring String;
|
|
||||||
#else
|
#else
|
||||||
typedef std::string String;
|
# include <unistd.h>
|
||||||
|
# include <signal.h>
|
||||||
|
# include <errno.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* these three definitions for doxygen cross-reference */
|
||||||
typedef QSE::StdAwk StdAwk;
|
typedef QSE::StdAwk StdAwk;
|
||||||
typedef QSE::StdAwk::Run Run;
|
typedef QSE::StdAwk::Run Run;
|
||||||
typedef QSE::StdAwk::Value Value;
|
typedef QSE::StdAwk::Value Value;
|
||||||
@ -43,159 +46,410 @@ typedef QSE::StdAwk::Value Value;
|
|||||||
class MyAwk: public StdAwk
|
class MyAwk: public StdAwk
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//
|
|
||||||
// this class overrides console methods to use
|
|
||||||
// string buffers for console input and output.
|
|
||||||
//
|
|
||||||
MyAwk () { }
|
MyAwk () { }
|
||||||
~MyAwk () { close (); }
|
~MyAwk () { close (); }
|
||||||
|
|
||||||
void setInput (const char_t* instr)
|
int open ()
|
||||||
{
|
{
|
||||||
this->input = instr;
|
if (StdAwk::open () <= -1) return -1;
|
||||||
this->inptr = this->input.c_str();
|
|
||||||
this->inend = inptr + this->input.length();
|
|
||||||
}
|
|
||||||
|
|
||||||
void clearOutput () { this->output.clear (); }
|
idLastSleep = addGlobal (QSE_T("LAST_SLEEP"));
|
||||||
const char_t* getOutput () { return this->output.c_str(); }
|
if (idLastSleep <= -1) goto oops;
|
||||||
|
|
||||||
protected:
|
/* this is for demonstration only.
|
||||||
String input; // console input buffer
|
* you can use sys::sleep() instead */
|
||||||
const char_t* inptr;
|
if (addFunction (QSE_T("sleep"), 1, 1, QSE_NULL,
|
||||||
const char_t* inend;
|
(FunctionHandler)&MyAwk::sleep) <= -1) goto oops;
|
||||||
|
|
||||||
String output; // console output buffer
|
if (addFunction (QSE_T("sumintarray"), 1, 1, QSE_NULL,
|
||||||
|
(FunctionHandler)&MyAwk::sumintarray) <= -1) goto oops;
|
||||||
|
|
||||||
int openConsole (Console& io)
|
if (addFunction (QSE_T("arrayindices"), 1, 1, QSE_NULL,
|
||||||
{
|
(FunctionHandler)&MyAwk::arrayindices) <= -1) goto oops;
|
||||||
return 1; // return open-success
|
|
||||||
}
|
|
||||||
|
|
||||||
int closeConsole (Console& io)
|
|
||||||
{
|
|
||||||
return 0; // return success
|
|
||||||
}
|
|
||||||
|
|
||||||
int flushConsole (Console& io)
|
|
||||||
{
|
|
||||||
// there is nothing to flush since a string buffer
|
|
||||||
// is used for a console output. just return success.
|
|
||||||
return 0;
|
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)
|
oops:
|
||||||
{
|
StdAwk::close ();
|
||||||
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;
|
return -1;
|
||||||
}
|
}
|
||||||
return size;
|
|
||||||
|
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 void print_error (
|
static MyAwk* app_awk = QSE_NULL;
|
||||||
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);
|
|
||||||
else
|
|
||||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), msg);
|
|
||||||
|
|
||||||
|
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 int run_awk (MyAwk& awk)
|
static void print_error (MyAwk& awk)
|
||||||
{
|
{
|
||||||
// sample input string
|
MyAwk::loc_t loc = awk.getErrorLocation();
|
||||||
const qse_char_t* instr = QSE_T(
|
|
||||||
"aardvark 555-5553 1200/300 B\n"
|
if (loc.file)
|
||||||
"alpo-net 555-3412 2400/1200/300 A\n"
|
{
|
||||||
"barfly 555-7685 1200/300 A\n"
|
print_error (QSE_T("line %u at %s - %s\n"), (unsigned)loc.line, loc.file, awk.getErrorMessage());
|
||||||
"bites 555-1675 2400/1200/300 A\n"
|
}
|
||||||
"camelot 555-0542 300 C\n"
|
else
|
||||||
"core 555-2912 1200/300 C\n"
|
{
|
||||||
"fooey 555-1234 2400/1200/300 B\n"
|
print_error (QSE_T("line %u - %s\n"), (unsigned)loc.line, awk.getErrorMessage());
|
||||||
"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");
|
#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);
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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 (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]
|
// ARGV[0]
|
||||||
if (awk.addArgument (QSE_T("awk12")) <= -1) return -1;
|
if (awk.addArgument (QSE_T("awk08")) <= -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)
|
|
||||||
{
|
{
|
||||||
qse_printf (QSE_T("%s"), awk.getOutput()); // print the console output
|
print_error (awk);
|
||||||
qse_printf (QSE_T("-----------------------------\n"));
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
// prepare a string to print lines with A in the fourth column
|
if ((n = handle_cmdline (awk, argc, argv, &cmdline)) <= 0) return n;
|
||||||
MyAwk::SourceString in2 (QSE_T("$4 == \"A\" { print $1; }"));
|
|
||||||
if (awk.parse (in2, MyAwk::Source::NONE) == QSE_NULL) return -1;
|
|
||||||
|
|
||||||
awk.setInput (instr);
|
MyAwk::Source* in, * out;
|
||||||
awk.clearOutput ();
|
MyAwk::SourceString in_str (cmdline.ins);
|
||||||
|
MyAwk::SourceFile in_file (cmdline.inf);
|
||||||
|
MyAwk::SourceFile out_file (cmdline.outf);
|
||||||
|
|
||||||
int x = awk.loop (&r);
|
in = (cmdline.ins)? (MyAwk::Source*)&in_str: (MyAwk::Source*)&in_file;
|
||||||
|
out = (cmdline.outf)? (MyAwk::Source*)&out_file: &MyAwk::Source::NONE;
|
||||||
if (x >= 0)
|
run = awk.parse (*in, *out);
|
||||||
|
if (run == QSE_NULL)
|
||||||
{
|
{
|
||||||
qse_printf (QSE_T("%s"), awk.getOutput());
|
print_error (awk);
|
||||||
qse_printf (QSE_T("-----------------------------\n"));
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return x;
|
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[])
|
static int awk_main (int argc, qse_char_t* argv[])
|
||||||
{
|
{
|
||||||
MyAwk awk;
|
MyAwk awk;
|
||||||
|
|
||||||
int ret = awk.open ();
|
if (awk.open() <= -1)
|
||||||
if (ret >= 0) ret = run_awk (awk);
|
|
||||||
|
|
||||||
if (ret <= -1)
|
|
||||||
{
|
{
|
||||||
MyAwk::loc_t loc = awk.getErrorLocation();
|
print_error (awk);
|
||||||
print_error (loc, awk.getErrorMessage());
|
return -1;
|
||||||
}
|
}
|
||||||
|
app_awk = &awk;
|
||||||
|
|
||||||
|
set_signal ();
|
||||||
|
int n = awk_main_2 (awk, argc, argv);
|
||||||
|
unset_signal ();
|
||||||
|
|
||||||
|
app_awk = QSE_NULL;
|
||||||
awk.close ();
|
awk.close ();
|
||||||
return ret;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
int qse_main (int argc, qse_achar_t* argv[])
|
int qse_main (int argc, qse_achar_t* argv[])
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
char locale[100];
|
char locale[100];
|
||||||
UINT codepage = GetConsoleOutputCP();
|
UINT codepage;
|
||||||
|
WSADATA wsadata;
|
||||||
|
|
||||||
|
codepage = GetConsoleOutputCP();
|
||||||
if (codepage == CP_UTF8)
|
if (codepage == CP_UTF8)
|
||||||
{
|
{
|
||||||
/*SetConsoleOUtputCP (CP_UTF8);*/
|
/*SetConsoleOUtputCP (CP_UTF8);*/
|
||||||
@ -207,10 +461,23 @@ int qse_main (int argc, qse_achar_t* argv[])
|
|||||||
setlocale (LC_ALL, locale);
|
setlocale (LC_ALL, locale);
|
||||||
qse_setdflcmgrbyid (QSE_CMGR_SLMB);
|
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
|
#else
|
||||||
setlocale (LC_ALL, "");
|
setlocale (LC_ALL, "");
|
||||||
qse_setdflcmgrbyid (QSE_CMGR_SLMB);
|
qse_setdflcmgrbyid (QSE_CMGR_SLMB);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return qse_runmain (argc,argv,awk_main);
|
ret = qse_runmain (argc, argv, awk_main);
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
WSACleanup ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,7 @@ public:
|
|||||||
this->inend = inptr + this->input.length();
|
this->inend = inptr + this->input.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clearOutput () { this->output.clear (); }
|
||||||
const char_t* getOutput () { return this->output.c_str(); }
|
const char_t* getOutput () { return this->output.c_str(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -68,16 +69,6 @@ protected:
|
|||||||
|
|
||||||
int openConsole (Console& io)
|
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
|
return 1; // return open-success
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,8 +86,8 @@ protected:
|
|||||||
int nextConsole (Console& io)
|
int nextConsole (Console& io)
|
||||||
{
|
{
|
||||||
// this stripped-down awk doesn't honor the nextfile statement
|
// this stripped-down awk doesn't honor the nextfile statement
|
||||||
// or the nextofile statement. just return failure.
|
// or the nextofile statement. just return success.
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t readConsole (Console& io, char_t* data, size_t size)
|
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"
|
"sdace 555-3430 2400/1200/300 A\n"
|
||||||
"sabafoo 555-2127 1200/300 C\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]
|
// 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
|
// prepare a script to print the second and the first column
|
||||||
MyAwk::SourceString in (QSE_T("$4 == \"A\" { print $2, $1, $3; }"));
|
MyAwk::SourceString in (QSE_T("{ print $2, $1; }"));
|
||||||
|
|
||||||
// parse the script.
|
// parse the script.
|
||||||
if (awk.parse (in, MyAwk::Source::NONE) == QSE_NULL) return -1;
|
if (awk.parse (in, MyAwk::Source::NONE) == QSE_NULL) return -1;
|
||||||
MyAwk::Value r;
|
MyAwk::Value r;
|
||||||
|
|
||||||
awk.setInput (instr); // locate the input string
|
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.
|
int x = awk.loop (&r); // execute the BEGIN, pattern-action, END blocks.
|
||||||
|
|
||||||
if (x >= 0)
|
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("%s"), awk.getOutput()); // print the console output
|
||||||
qse_printf (QSE_T("-----------------------------\n"));
|
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
|
awk.setInput (instr);
|
||||||
// is performed over a new console stream.
|
awk.clearOutput ();
|
||||||
if (awk.resetRunContext() == QSE_NULL) return -1;
|
|
||||||
|
|
||||||
int x = awk.loop (&r);
|
int x = awk.loop (&r);
|
||||||
|
|
||||||
|
@ -40,31 +40,35 @@ typedef QSE::StdAwk StdAwk;
|
|||||||
typedef QSE::StdAwk::Run Run;
|
typedef QSE::StdAwk::Run Run;
|
||||||
typedef QSE::StdAwk::Value Value;
|
typedef QSE::StdAwk::Value Value;
|
||||||
|
|
||||||
class MyConsoleHandler: public StdAwk::Console::Handler
|
class MyAwk: public StdAwk
|
||||||
{
|
{
|
||||||
public:
|
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->input = instr;
|
||||||
this->inptr = this->input.c_str();
|
this->inptr = this->input.c_str();
|
||||||
this->inend = inptr + this->input.length();
|
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:
|
protected:
|
||||||
String input; // console input buffer
|
String input; // console input buffer
|
||||||
const StdAwk::char_t* inptr;
|
const char_t* inptr;
|
||||||
const StdAwk::char_t* inend;
|
const char_t* inend;
|
||||||
|
|
||||||
String output; // console output buffer
|
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->inptr = this->input.c_str();
|
||||||
this->inend = inptr + this->input.length();
|
this->inend = inptr + this->input.length();
|
||||||
@ -77,25 +81,25 @@ protected:
|
|||||||
return 1; // return open-success
|
return 1; // return open-success
|
||||||
}
|
}
|
||||||
|
|
||||||
int close (StdAwk::Console& io)
|
int closeConsole (Console& io)
|
||||||
{
|
{
|
||||||
return 0; // return success
|
return 0; // return success
|
||||||
}
|
}
|
||||||
|
|
||||||
int flush (StdAwk::Console& io)
|
int flushConsole (Console& io)
|
||||||
{
|
{
|
||||||
// there is nothing to flush since a string buffer
|
// there is nothing to flush since a string buffer
|
||||||
// is used for a console output. just return success.
|
// is used for a console output. just return success.
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int next (StdAwk::Console& io)
|
int nextConsole (Console& io)
|
||||||
{
|
{
|
||||||
// this stripped-down awk doesn't honor the nextfile statement
|
// this stripped-down awk doesn't honor the nextfile statement
|
||||||
// or the nextofile statement. just return failure.
|
// or the nextofile statement. just return failure.
|
||||||
return -1;
|
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
|
if (this->inptr >= this->inend) return 0; // EOF
|
||||||
size_t x = qse_strxncpy (data, size, inptr, inend - inptr);
|
size_t x = qse_strxncpy (data, size, inptr, inend - inptr);
|
||||||
@ -103,12 +107,12 @@ protected:
|
|||||||
return x;
|
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); }
|
try { this->output.append (data, size); }
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
((StdAwk::Run*)io)->setError (QSE_AWK_ENOMEM);
|
((Run*)io)->setError (QSE_AWK_ENOMEM);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
@ -116,7 +120,7 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void print_error (
|
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)
|
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);
|
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
|
// sample input string
|
||||||
const qse_char_t* instr = QSE_T(
|
const qse_char_t* instr = QSE_T(
|
||||||
@ -155,26 +159,24 @@ static int run_awk (StdAwk& awk)
|
|||||||
"sabafoo 555-2127 1200/300 A\n");
|
"sabafoo 555-2127 1200/300 A\n");
|
||||||
|
|
||||||
// ARGV[0]
|
// 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
|
// 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.
|
// parse the script.
|
||||||
if (awk.parse (in, StdAwk::Source::NONE) == QSE_NULL) return -1;
|
if (awk.parse (in, MyAwk::Source::NONE) == QSE_NULL) return -1;
|
||||||
StdAwk::Value r;
|
MyAwk::Value r;
|
||||||
|
|
||||||
MyConsoleHandler* mch = (MyConsoleHandler*)awk.getConsoleHandler();
|
awk.setInput (instr); // locate the input string
|
||||||
|
|
||||||
mch->setInput (instr); // locate the input string
|
|
||||||
int x = awk.loop (&r); // execute the BEGIN, pattern-action, END blocks.
|
int x = awk.loop (&r); // execute the BEGIN, pattern-action, END blocks.
|
||||||
|
|
||||||
if (x >= 0)
|
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"));
|
qse_printf (QSE_T("-----------------------------\n"));
|
||||||
|
|
||||||
mch->setInput (instr2);
|
awk.setInput (instr2);
|
||||||
|
|
||||||
// reset the runtime context so that the next loop() method
|
// reset the runtime context so that the next loop() method
|
||||||
// is performed over a new console stream.
|
// is performed over a new console stream.
|
||||||
@ -184,7 +186,7 @@ static int run_awk (StdAwk& awk)
|
|||||||
|
|
||||||
if (x >= 0)
|
if (x >= 0)
|
||||||
{
|
{
|
||||||
qse_printf (QSE_T("%s"), mch->getOutput());
|
qse_printf (QSE_T("%s"), awk.getOutput());
|
||||||
qse_printf (QSE_T("-----------------------------\n"));
|
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[])
|
static int awk_main (int argc, qse_char_t* argv[])
|
||||||
{
|
{
|
||||||
|
MyAwk awk;
|
||||||
MyConsoleHandler mch;
|
|
||||||
StdAwk awk;
|
|
||||||
|
|
||||||
int ret = awk.open ();
|
int ret = awk.open ();
|
||||||
if (ret >= 0)
|
if (ret >= 0) ret = run_awk (awk);
|
||||||
{
|
|
||||||
awk.setConsoleHandler (&mch);
|
|
||||||
ret = run_awk (awk);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret <= -1)
|
if (ret <= -1)
|
||||||
{
|
{
|
||||||
StdAwk::loc_t loc = awk.getErrorLocation();
|
MyAwk::loc_t loc = awk.getErrorLocation();
|
||||||
print_error (loc, awk.getErrorMessage());
|
print_error (loc, awk.getErrorMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
240
qse/samples/awk/awk28.cpp
Normal file
240
qse/samples/awk/awk28.cpp
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <qse/awk/StdAwk.hpp>
|
||||||
|
#include <qse/cmn/stdio.h>
|
||||||
|
#include <qse/cmn/main.h>
|
||||||
|
#include <qse/cmn/mbwc.h>
|
||||||
|
#include <qse/cmn/str.h>
|
||||||
|
|
||||||
|
#include <locale.h>
|
||||||
|
#if defined(_WIN32)
|
||||||
|
# include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#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);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user