enhanced Awk classes
This commit is contained in:
parent
b682392d5f
commit
1d88a17c7c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: Awk.hpp 224 2009-07-07 13:05:10Z hyunghwan.chung $
|
||||
* $Id: Awk.hpp 225 2009-07-08 13:01:45Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
|
||||
@ -87,7 +87,7 @@ public:
|
||||
* and Source::WRITE respectively when called from
|
||||
* Awk::readSource and Awk::writeSource.
|
||||
*
|
||||
* <pre>
|
||||
* @code
|
||||
* int openSource (Source& io)
|
||||
* {
|
||||
* if (io.getMode() == Source::READ)
|
||||
@ -117,7 +117,7 @@ public:
|
||||
* }
|
||||
* return -1;
|
||||
* }
|
||||
* </pre>
|
||||
* @endcode
|
||||
*
|
||||
* @return Awk::Source::READ or Awk::Source::WRITE
|
||||
*/
|
||||
@ -131,7 +131,7 @@ public:
|
||||
* Awk::closeSource to get the value set in Awk::openSource
|
||||
* as shown in the example below.
|
||||
*
|
||||
* <pre>
|
||||
* @code
|
||||
* int closeSource (Source& io)
|
||||
* {
|
||||
* if (io.getMode() == Source::READ)
|
||||
@ -146,10 +146,10 @@ public:
|
||||
* }
|
||||
* return -1;
|
||||
* }
|
||||
* </pre>
|
||||
* @endcode
|
||||
*
|
||||
* @return an arbitrary value of type void* set with
|
||||
* Source::setHandle or QSE_NULL
|
||||
* Source::setHandle() or QSE_NULL
|
||||
*/
|
||||
const void* getHandle () const;
|
||||
|
||||
@ -526,7 +526,6 @@ public:
|
||||
};
|
||||
// end of enum ErrorNumber
|
||||
|
||||
|
||||
// generated by genoptcode.awk
|
||||
/** Defines options */
|
||||
enum Option
|
||||
@ -708,23 +707,12 @@ public:
|
||||
*/
|
||||
int getGlobal (int id, Argument& global) const;
|
||||
|
||||
/**
|
||||
* Sets a value into the data field
|
||||
*/
|
||||
void setData (void* data);
|
||||
|
||||
/**
|
||||
* Gets the value stored in the data field
|
||||
*/
|
||||
void* getData () const;
|
||||
|
||||
void* alloc (size_t size);
|
||||
void free (void* ptr);
|
||||
|
||||
protected:
|
||||
Awk* awk;
|
||||
rtx_t* rtx;
|
||||
void* data;
|
||||
};
|
||||
|
||||
/** Constructor */
|
||||
@ -829,9 +817,9 @@ public:
|
||||
* override Awk::openSource, Awk::closeSource, Awk::readSource,
|
||||
* Awk::writeSource to implement the source code stream.
|
||||
*
|
||||
* @return 0 on success, -1 on failure
|
||||
* @return a Run object on success, QSE_NULL on failure
|
||||
*/
|
||||
virtual int parse ();
|
||||
virtual Awk::Run* parse ();
|
||||
|
||||
/**
|
||||
* Executes the BEGIN block, pattern-action blocks, and the END block.
|
||||
@ -839,6 +827,15 @@ public:
|
||||
*/
|
||||
virtual int loop ();
|
||||
|
||||
/**
|
||||
* Calls a function
|
||||
*/
|
||||
virtual int call (
|
||||
const char_t* name,
|
||||
const Return* args,
|
||||
size_t nargs
|
||||
);
|
||||
|
||||
/**
|
||||
* Makes request to abort execution
|
||||
*/
|
||||
@ -1077,6 +1074,11 @@ protected:
|
||||
xstrs_t runarg;
|
||||
|
||||
private:
|
||||
Run runctx;
|
||||
|
||||
int init_runctx ();
|
||||
void fini_runctx ();
|
||||
|
||||
static const char_t* xerrstr (awk_t* a, errnum_t num) throw ();
|
||||
|
||||
private:
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: Awk.cpp 224 2009-07-07 13:05:10Z hyunghwan.chung $
|
||||
* $Id: Awk.cpp 225 2009-07-08 13:01:45Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
|
||||
@ -226,8 +226,8 @@ void Awk::Argument::clear ()
|
||||
{
|
||||
/* case 1. not initialized.
|
||||
* case 2. initialized with the second init.
|
||||
* none of the cases creates a new string so the sttring
|
||||
* that str.ptr is pointing at doesn't have to be freed */
|
||||
* none of the cases. create a new string so the sttring
|
||||
* that str.ptr is pointing to doesn't have to be freed */
|
||||
this->str.ptr = QSE_NULL;
|
||||
this->str.len = 0;
|
||||
}
|
||||
@ -918,7 +918,7 @@ Awk::Run::Run (Awk* awk): awk (awk), rtx (QSE_NULL)
|
||||
{
|
||||
}
|
||||
|
||||
Awk::Run::Run (Awk* awk, rtx_t* rtx): awk (awk), rtx (rtx), data (QSE_NULL)
|
||||
Awk::Run::Run (Awk* awk, rtx_t* rtx): awk (awk), rtx (rtx)
|
||||
{
|
||||
QSE_ASSERT (this->rtx != QSE_NULL);
|
||||
}
|
||||
@ -1062,23 +1062,14 @@ int Awk::Run::getGlobal (int id, Argument& gbl) const
|
||||
return gbl.init (qse_awk_rtx_getgbl (this->rtx, id));
|
||||
}
|
||||
|
||||
void Awk::Run::setData (void* data)
|
||||
{
|
||||
this->data = data;
|
||||
}
|
||||
|
||||
void* Awk::Run::getData () const
|
||||
{
|
||||
return this->data;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Awk
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
Awk::Awk () throw (): awk (QSE_NULL), functionMap (QSE_NULL),
|
||||
sourceIn (Source::READ), sourceOut (Source::WRITE),
|
||||
errnum (ERR_NOERR), errlin (0), runCallback (false)
|
||||
errnum (ERR_NOERR), errlin (0), runCallback (false),
|
||||
runctx (this)
|
||||
|
||||
{
|
||||
this->errmsg[0] = QSE_T('\0');
|
||||
@ -1238,6 +1229,7 @@ int Awk::open ()
|
||||
|
||||
void Awk::close ()
|
||||
{
|
||||
fini_runctx ();
|
||||
clearArguments ();
|
||||
|
||||
if (functionMap != QSE_NULL)
|
||||
@ -1337,31 +1329,34 @@ int Awk::unsetAllWords ()
|
||||
return qse_awk_setword (awk, QSE_NULL, 0, QSE_NULL, 0);
|
||||
}
|
||||
|
||||
int Awk::parse ()
|
||||
Awk::Run* Awk::parse ()
|
||||
{
|
||||
QSE_ASSERT (awk != QSE_NULL);
|
||||
|
||||
qse_awk_sio_t sio;
|
||||
fini_runctx ();
|
||||
|
||||
qse_awk_sio_t sio;
|
||||
sio.in = sourceReader;
|
||||
sio.out = sourceWriter;
|
||||
|
||||
int n = qse_awk_parse (awk, &sio);
|
||||
if (n == -1) retrieveError ();
|
||||
return n;
|
||||
if (n <= -1)
|
||||
{
|
||||
retrieveError ();
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
int Awk::loop ()
|
||||
if (init_runctx () <= -1) return QSE_NULL;
|
||||
return &runctx;
|
||||
}
|
||||
|
||||
int Awk::init_runctx ()
|
||||
{
|
||||
QSE_ASSERT (awk != QSE_NULL);
|
||||
if (runctx.rtx != QSE_NULL) return 0;
|
||||
|
||||
qse_awk_rio_t rio;
|
||||
qse_awk_rcb_t rcb;
|
||||
|
||||
// note that the run field is set below after qse_awk_rtx_open() is
|
||||
// executed.
|
||||
Run runctx (this);
|
||||
|
||||
rio.pipe = pipeHandler;
|
||||
rio.file = fileHandler;
|
||||
rio.console = consoleHandler;
|
||||
@ -1375,30 +1370,76 @@ int Awk::loop ()
|
||||
rcb.udd = &runctx;
|
||||
}
|
||||
|
||||
int n = 0;
|
||||
rtx_t* rtx = qse_awk_rtx_open (
|
||||
awk, QSE_SIZEOF(rxtn_t), &rio, (qse_cstr_t*)runarg.ptr);
|
||||
if (rtx == QSE_NULL)
|
||||
{
|
||||
retrieveError();
|
||||
n = -1;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
runctx.rtx = rtx;
|
||||
|
||||
rxtn_t* rxtn = (rxtn_t*) QSE_XTN (rtx);
|
||||
rxtn->run = &runctx;
|
||||
|
||||
if (runCallback) qse_awk_rtx_setrcb (rtx, &rcb);
|
||||
n = qse_awk_rtx_loop (rtx);
|
||||
if (n == -1) retrieveError (rtx);
|
||||
qse_awk_rtx_close (rtx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Awk::fini_runctx ()
|
||||
{
|
||||
if (runctx.rtx != QSE_NULL)
|
||||
{
|
||||
qse_awk_rtx_close (runctx.rtx);
|
||||
runctx.rtx = QSE_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int Awk::loop ()
|
||||
{
|
||||
QSE_ASSERT (awk != QSE_NULL);
|
||||
QSE_ASSERT (runctx.rtx != QSE_NULL);
|
||||
|
||||
int n = qse_awk_rtx_loop (runctx.rtx);
|
||||
if (n <= -1) retrieveError (runctx.rtx);
|
||||
return n;
|
||||
}
|
||||
|
||||
int Awk::call (const char_t* name, const Return* args, size_t nargs)
|
||||
{
|
||||
QSE_ASSERT (awk != QSE_NULL);
|
||||
QSE_ASSERT (runctx.rtx != QSE_NULL);
|
||||
|
||||
val_t** ptr = QSE_NULL;
|
||||
|
||||
if (args != QSE_NULL)
|
||||
{
|
||||
ptr = (val_t**) qse_awk_alloc (awk, QSE_SIZEOF(val_t*) * nargs);
|
||||
if (ptr == QSE_NULL)
|
||||
{
|
||||
runctx.setError (ERR_NOMEM);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < nargs; i++) ptr[i] = args[i].val;
|
||||
}
|
||||
|
||||
val_t* ret = qse_awk_rtx_call (runctx.rtx, name, ptr, nargs);
|
||||
|
||||
if (ptr != QSE_NULL) qse_awk_free (awk, ptr);
|
||||
|
||||
if (ret == QSE_NULL)
|
||||
{
|
||||
retrieveError (runctx.rtx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// TODO: how can i store it???
|
||||
qse_awk_rtx_refdownval (runctx.rtx, ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Awk::stop ()
|
||||
{
|
||||
QSE_ASSERT (awk != QSE_NULL);
|
||||
@ -1410,8 +1451,6 @@ int Awk::dispatchFunction (Run* run, const char_t* name, size_t len)
|
||||
pair_t* pair;
|
||||
awk_t* awk = run->awk->awk;
|
||||
|
||||
//awk = qse_awk_rtx_getawk (run);
|
||||
|
||||
pair = qse_map_search (functionMap, name, len);
|
||||
if (pair == QSE_NULL)
|
||||
{
|
||||
@ -1495,9 +1534,11 @@ void Awk::xstrs_t::clear (awk_t* awk)
|
||||
{
|
||||
if (this->ptr != QSE_NULL)
|
||||
{
|
||||
while (this->len > 0)
|
||||
qse_awk_free (awk, this->ptr[--this->len].ptr);
|
||||
|
||||
qse_awk_free (awk, this->ptr);
|
||||
this->ptr = QSE_NULL;
|
||||
this->len = 0;
|
||||
this->capa = 0;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: StdAwk.cpp 224 2009-07-07 13:05:10Z hyunghwan.chung $
|
||||
* $Id: StdAwk.cpp 225 2009-07-08 13:01:45Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
|
||||
@ -480,8 +480,10 @@ int StdAwk::open_console_in (Console& io)
|
||||
map = ((qse_awk_val_map_t*)argv)->map;
|
||||
QSE_ASSERT (map != QSE_NULL);
|
||||
|
||||
// ok to find ARGV[runarg_index] as ARGV[0]
|
||||
// has been skipped.
|
||||
ibuflen = qse_awk_longtostr (
|
||||
rtx->awk, runarg_index + 1,
|
||||
rtx->awk, runarg_index,
|
||||
10, QSE_NULL,
|
||||
ibuf, QSE_COUNTOF(ibuf)
|
||||
);
|
||||
@ -622,6 +624,11 @@ int StdAwk::openConsole (Console& io)
|
||||
{
|
||||
runarg_count = 0;
|
||||
runarg_index = 0;
|
||||
if (runarg.len > 0)
|
||||
{
|
||||
// skip ARGV[0]
|
||||
runarg_index++;
|
||||
}
|
||||
return open_console_in (io);
|
||||
}
|
||||
else
|
||||
|
@ -32,7 +32,7 @@
|
||||
# include <errno.h>
|
||||
#endif
|
||||
|
||||
class TestAwk;
|
||||
class MyAwk;
|
||||
#ifdef _WIN32
|
||||
static BOOL WINAPI stop_run (DWORD ctrl_type);
|
||||
#else
|
||||
@ -42,13 +42,13 @@ static void stop_run (int sig);
|
||||
static void set_intr_run (void);
|
||||
static void unset_intr_run (void);
|
||||
|
||||
TestAwk* app_awk = QSE_NULL;
|
||||
MyAwk* app_awk = QSE_NULL;
|
||||
static bool verbose = false;
|
||||
|
||||
class TestAwk: public QSE::StdAwk
|
||||
class MyAwk: public QSE::StdAwk
|
||||
{
|
||||
public:
|
||||
TestAwk (): srcInName(QSE_NULL), srcOutName(QSE_NULL)
|
||||
MyAwk (): srcInName(QSE_NULL), srcOutName(QSE_NULL)
|
||||
|
||||
{
|
||||
#ifdef _WIN32
|
||||
@ -56,7 +56,7 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
~TestAwk ()
|
||||
~MyAwk ()
|
||||
{
|
||||
close ();
|
||||
}
|
||||
@ -83,13 +83,13 @@ public:
|
||||
if (idLastSleep <= -1) goto failure;
|
||||
|
||||
if (addFunction (QSE_T("sleep"), 1, 1,
|
||||
(FunctionHandler)&TestAwk::sleep) <= -1) goto failure;
|
||||
(FunctionHandler)&MyAwk::sleep) <= -1) goto failure;
|
||||
|
||||
if (addFunction (QSE_T("sumintarray"), 1, 1,
|
||||
(FunctionHandler)&TestAwk::sumintarray) <= -1) goto failure;
|
||||
(FunctionHandler)&MyAwk::sumintarray) <= -1) goto failure;
|
||||
|
||||
if (addFunction (QSE_T("arrayindices"), 1, 1,
|
||||
(FunctionHandler)&TestAwk::arrayindices) <= -1) goto failure;
|
||||
(FunctionHandler)&MyAwk::arrayindices) <= -1) goto failure;
|
||||
return 0;
|
||||
|
||||
failure:
|
||||
@ -190,7 +190,7 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parse (const char_t* in, const char_t* out)
|
||||
Run* parse (const char_t* in, const char_t* out)
|
||||
{
|
||||
srcInName = in;
|
||||
srcOutName = out;
|
||||
@ -199,13 +199,13 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
bool onRunEnter (Run& run)
|
||||
bool onLoopEnter (Run& run)
|
||||
{
|
||||
set_intr_run ();
|
||||
return true;
|
||||
}
|
||||
|
||||
void onRunExit (Run& run, const Argument& ret)
|
||||
void onLoopExit (Run& run, const Argument& ret)
|
||||
{
|
||||
unset_intr_run ();
|
||||
|
||||
@ -414,29 +414,29 @@ static void unset_intr_run (void)
|
||||
|
||||
static void print_error (const qse_char_t* msg)
|
||||
{
|
||||
qse_printf (QSE_T("Error: %s\n"), msg);
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), msg);
|
||||
}
|
||||
|
||||
static struct
|
||||
{
|
||||
const qse_char_t* name;
|
||||
TestAwk::Option opt;
|
||||
MyAwk::Option opt;
|
||||
} otab[] =
|
||||
{
|
||||
{ QSE_T("implicit"), TestAwk::OPT_IMPLICIT },
|
||||
{ QSE_T("explicit"), TestAwk::OPT_EXPLICIT },
|
||||
{ QSE_T("bxor"), TestAwk::OPT_BXOR },
|
||||
{ QSE_T("shift"), TestAwk::OPT_SHIFT },
|
||||
{ QSE_T("idiv"), TestAwk::OPT_IDIV },
|
||||
{ QSE_T("rio"), TestAwk::OPT_RIO },
|
||||
{ QSE_T("rwpipe"), TestAwk::OPT_RWPIPE },
|
||||
{ QSE_T("newline"), TestAwk::OPT_NEWLINE },
|
||||
{ QSE_T("stripspaces"), TestAwk::OPT_STRIPSPACES },
|
||||
{ QSE_T("nextofile"), TestAwk::OPT_NEXTOFILE },
|
||||
{ QSE_T("crlf"), TestAwk::OPT_CRLF },
|
||||
{ QSE_T("reset"), TestAwk::OPT_RESET },
|
||||
{ QSE_T("maptovar"), TestAwk::OPT_MAPTOVAR },
|
||||
{ QSE_T("pablock"), TestAwk::OPT_PABLOCK }
|
||||
{ QSE_T("implicit"), MyAwk::OPT_IMPLICIT },
|
||||
{ QSE_T("explicit"), MyAwk::OPT_EXPLICIT },
|
||||
{ QSE_T("bxor"), MyAwk::OPT_BXOR },
|
||||
{ QSE_T("shift"), MyAwk::OPT_SHIFT },
|
||||
{ QSE_T("idiv"), MyAwk::OPT_IDIV },
|
||||
{ QSE_T("rio"), MyAwk::OPT_RIO },
|
||||
{ QSE_T("rwpipe"), MyAwk::OPT_RWPIPE },
|
||||
{ QSE_T("newline"), MyAwk::OPT_NEWLINE },
|
||||
{ QSE_T("stripspaces"), MyAwk::OPT_STRIPSPACES },
|
||||
{ QSE_T("nextofile"), MyAwk::OPT_NEXTOFILE },
|
||||
{ QSE_T("crlf"), MyAwk::OPT_CRLF },
|
||||
{ QSE_T("reset"), MyAwk::OPT_RESET },
|
||||
{ QSE_T("maptovar"), MyAwk::OPT_MAPTOVAR },
|
||||
{ QSE_T("pablock"), MyAwk::OPT_PABLOCK }
|
||||
};
|
||||
|
||||
static void print_usage (const qse_char_t* argv0)
|
||||
@ -470,7 +470,8 @@ static void print_usage (const qse_char_t* argv0)
|
||||
|
||||
static int awk_main (int argc, qse_char_t* argv[])
|
||||
{
|
||||
TestAwk awk;
|
||||
MyAwk awk;
|
||||
MyAwk::Run* run;
|
||||
|
||||
int mode = 0;
|
||||
const qse_char_t* srcin = QSE_T("");
|
||||
@ -480,7 +481,15 @@ static int awk_main (int argc, qse_char_t* argv[])
|
||||
|
||||
if (awk.open() <= -1)
|
||||
{
|
||||
qse_fprintf (stderr, QSE_T("cannot open awk\n"));
|
||||
print_error (awk.getErrorMessage());
|
||||
return -1;
|
||||
}
|
||||
|
||||
// ARGV[0]
|
||||
if (awk.addArgument (QSE_T("awk05")) <= -1)
|
||||
{
|
||||
print_error (awk.getErrorMessage());
|
||||
awk.close ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -616,7 +625,8 @@ static int awk_main (int argc, qse_char_t* argv[])
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (awk.parse (srcin, srcout) <= -1)
|
||||
run = awk.parse (srcin, srcout);
|
||||
if (run == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (stderr, QSE_T("cannot parse: LINE[%d] %s\n"),
|
||||
awk.getErrorLine(), awk.getErrorMessage());
|
||||
@ -635,6 +645,20 @@ static int awk_main (int argc, qse_char_t* argv[])
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
MyAwk::Return args[2];
|
||||
|
||||
args[0].setRun (run);
|
||||
args[1].setRun (run);
|
||||
|
||||
if (awk.call (QSE_T("add"), args, 2) <= -1)
|
||||
{
|
||||
qse_fprintf (stderr, QSE_T("cannot run: LINE[%d] %s\n"),
|
||||
awk.getErrorLine(), awk.getErrorMessage());
|
||||
awk.close ();
|
||||
}
|
||||
#endif
|
||||
|
||||
app_awk = QSE_NULL;
|
||||
awk.close ();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user