Reorganized the directory structure
This commit is contained in:
46
samples/awk/Makefile.am
Normal file
46
samples/awk/Makefile.am
Normal file
@ -0,0 +1,46 @@
|
||||
AUTOMAKE_OPTIONS = nostdinc
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-I$(top_builddir)/include \
|
||||
-I$(top_srcdir)/include \
|
||||
-I$(includedir)
|
||||
|
||||
bin_PROGRAMS = awk01 awk02 awk03 awk04 awk05 awk06 awk07 awk08 awk09 awk10 awk11 awk12 awk15
|
||||
|
||||
AM_LDFLAGS = -L../../lib/awk -L../../lib/cmn
|
||||
LDADD = -lqseawk -lqsecmn $(LIBM)
|
||||
|
||||
if WIN32
|
||||
LDADD += $(UNICOWS_LIBS)
|
||||
endif
|
||||
|
||||
CMNFILES = awk00.c awk00.h
|
||||
awk01_SOURCES = awk01.c
|
||||
awk02_SOURCES = awk02.c $(CMNFILES)
|
||||
awk03_SOURCES = awk03.c $(CMNFILES)
|
||||
awk04_SOURCES = awk04.c $(CMNFILES)
|
||||
awk05_SOURCES = awk05.c $(CMNFILES)
|
||||
awk06_SOURCES = awk06.c $(CMNFILES)
|
||||
awk07_SOURCES = awk07.c $(CMNFILES)
|
||||
awk08_SOURCES = awk08.c $(CMNFILES)
|
||||
awk09_SOURCES = awk09.c $(CMNFILES)
|
||||
awk10_SOURCES = awk10.c $(CMNFILES)
|
||||
awk11_SOURCES = awk11.c $(CMNFILES)
|
||||
awk12_SOURCES = awk12.c $(CMNFILES)
|
||||
awk15_SOURCES = awk15.c $(CMNFILES)
|
||||
|
||||
if ENABLE_CXX
|
||||
|
||||
CXXLIB = -lqseawkxx -lqsecmnxx
|
||||
|
||||
bin_PROGRAMS += awk21 awk22 awk23 awk24 awk25 awk26 awk27 awk28
|
||||
|
||||
awk21_SOURCES = awk21.cpp
|
||||
awk22_SOURCES = awk22.cpp
|
||||
awk23_SOURCES = awk23.cpp
|
||||
awk24_SOURCES = awk24.cpp
|
||||
awk25_SOURCES = awk25.cpp
|
||||
awk26_SOURCES = awk26.cpp
|
||||
awk27_SOURCES = awk27.cpp
|
||||
awk28_SOURCES = awk28.cpp
|
||||
endif
|
1012
samples/awk/Makefile.in
Normal file
1012
samples/awk/Makefile.in
Normal file
File diff suppressed because it is too large
Load Diff
33
samples/awk/awk00.c
Normal file
33
samples/awk/awk00.c
Normal file
@ -0,0 +1,33 @@
|
||||
/* awk00.c */
|
||||
|
||||
#include "awk00.h"
|
||||
#include <qse/cmn/mbwc.h>
|
||||
#include <qse/cmn/fmt.h>
|
||||
|
||||
#include <locale.h>
|
||||
#if defined(_WIN32)
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
void init_awk_sample_locale (void)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
char locale[100];
|
||||
UINT codepage = GetConsoleOutputCP();
|
||||
if (codepage == CP_UTF8)
|
||||
{
|
||||
/*SetConsoleOutputCP (CP_UTF8);*/
|
||||
qse_setdflcmgrbyid (QSE_CMGR_UTF8);
|
||||
}
|
||||
else
|
||||
{
|
||||
qse_fmtuintmaxtombs (locale, QSE_COUNTOF(locale),
|
||||
codepage, 10, -1, QSE_MT('\0'), QSE_MT("."));
|
||||
setlocale (LC_ALL, locale);
|
||||
/*qse_setdflcmgrbyid (QSE_CMGR_SLMB);*/
|
||||
}
|
||||
#else
|
||||
setlocale (LC_ALL, "");
|
||||
/*qse_setdflcmgrbyid (QSE_CMGR_SLMB);*/
|
||||
#endif
|
||||
}
|
16
samples/awk/awk00.h
Normal file
16
samples/awk/awk00.h
Normal file
@ -0,0 +1,16 @@
|
||||
/* awk00.h */
|
||||
|
||||
#ifndef _AWK00_H_
|
||||
#define _AWK00_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void init_awk_sample_locale (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
76
samples/awk/awk01.c
Normal file
76
samples/awk/awk01.c
Normal file
@ -0,0 +1,76 @@
|
||||
#include <qse/awk/stdawk.h>
|
||||
#include <qse/si/sio.h>
|
||||
|
||||
static const qse_char_t* script = QSE_T("BEGIN { print \"hello, world\"; }");
|
||||
|
||||
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[2];
|
||||
int ret = -1;
|
||||
|
||||
qse_open_stdsios ();
|
||||
|
||||
/* create an awk object */
|
||||
awk = qse_awk_openstd (0, QSE_NULL);
|
||||
if (awk == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open awk\n"));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* prepare a script to parse */
|
||||
psin[0].type = QSE_AWK_PARSESTD_STR;
|
||||
psin[0].u.str.ptr = script;
|
||||
psin[0].u.str.len = qse_strlen(script);
|
||||
psin[1].type = QSE_AWK_PARSESTD_NULL;
|
||||
|
||||
/* parse a script in a string */
|
||||
if (qse_awk_parsestd (awk, psin, QSE_NULL) <= -1)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"),
|
||||
qse_awk_geterrmsg(awk));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* open a runtime context */
|
||||
rtx = qse_awk_rtx_openstd (
|
||||
awk,
|
||||
0,
|
||||
QSE_T("awk01"),
|
||||
QSE_NULL, /* stdin */
|
||||
QSE_NULL, /* stdout */
|
||||
QSE_NULL /* default cmgr */
|
||||
);
|
||||
if (rtx == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"),
|
||||
qse_awk_geterrmsg(awk));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* execute pattern-action blocks */
|
||||
retv = qse_awk_rtx_loop (rtx);
|
||||
if (retv == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"),
|
||||
qse_awk_rtx_geterrmsg(rtx));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* decrement the reference count of the return value */
|
||||
qse_awk_rtx_refdownval (rtx, retv);
|
||||
ret = 0;
|
||||
|
||||
oops:
|
||||
/* destroy the runtime context */
|
||||
if (rtx) qse_awk_rtx_close (rtx);
|
||||
|
||||
/* destroy the awk object */
|
||||
if (awk) qse_awk_close (awk);
|
||||
|
||||
qse_close_stdsios ();
|
||||
return ret;
|
||||
}
|
164
samples/awk/awk02.c
Normal file
164
samples/awk/awk02.c
Normal file
@ -0,0 +1,164 @@
|
||||
#include <qse/awk/stdawk.h>
|
||||
#include <qse/cmn/str.h>
|
||||
#include <qse/si/sio.h>
|
||||
#include <qse/cmn/main.h>
|
||||
#include "awk00.h"
|
||||
|
||||
/* i'll print records with the second field grater than 4.
|
||||
* at the end, we'll print the number of records seen so far */
|
||||
static const qse_char_t* script =
|
||||
QSE_T("$2 > 4 { print $0; } END { print NR; }");
|
||||
|
||||
/* the console input string */
|
||||
static const qse_char_t* conin =
|
||||
QSE_T("Beth 4.00 0\nDan 3.74 0\nKathy 4.00 10\nMark 5.00 20\nMary 5.50 22\nSusie 4.25 18\n");
|
||||
static qse_size_t coninpos = 0;
|
||||
|
||||
/* the console output is stored into this buffer */
|
||||
static qse_char_t conout[10000];
|
||||
static qse_size_t conoutpos = 0;
|
||||
|
||||
/* this is the console I/O handler */
|
||||
static qse_ssize_t handle_console (
|
||||
qse_awk_rtx_t* rtx,
|
||||
qse_awk_rio_cmd_t cmd,
|
||||
qse_awk_rio_arg_t* arg,
|
||||
qse_char_t* data,
|
||||
qse_size_t count)
|
||||
{
|
||||
/* this function is called separately for the console input and console
|
||||
* output. however, since i don't maintain underlying resources like
|
||||
* file handles, i don't really check if it's input or output.
|
||||
* you can check the value of #qse_awk_rio_mode_t in the arg->mode
|
||||
* field if you want to tell.
|
||||
*/
|
||||
switch (cmd)
|
||||
{
|
||||
case QSE_AWK_RIO_OPEN:
|
||||
/* 0 for success, -1 for failure. */
|
||||
return 0;
|
||||
|
||||
case QSE_AWK_RIO_CLOSE:
|
||||
/* 0 for success, -1 for failure. */
|
||||
return 0;
|
||||
|
||||
case QSE_AWK_RIO_READ:
|
||||
{
|
||||
qse_ssize_t len = 0;
|
||||
|
||||
while (conin[coninpos] && len < count)
|
||||
data[len++] = conin[coninpos++];
|
||||
|
||||
/* 0 for EOF, -1 for failure.
|
||||
positive numbers for the number of characters read */
|
||||
return len;
|
||||
}
|
||||
|
||||
case QSE_AWK_RIO_WRITE:
|
||||
conoutpos += qse_strxncpy (
|
||||
&conout[conoutpos], QSE_COUNTOF(conout) - conoutpos,
|
||||
data, count);
|
||||
/* 0 for EOF, -1 for failure.
|
||||
positive numbers for the number of characters written */
|
||||
return count;
|
||||
|
||||
case QSE_AWK_RIO_FLUSH:
|
||||
/* 0 for success, -1 for failure. */
|
||||
return 0;
|
||||
|
||||
case QSE_AWK_RIO_NEXT:
|
||||
/* 0 for success, -1 for failure. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* this part will never be reached */
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int awk_main (int argc, qse_char_t* argv[])
|
||||
{
|
||||
qse_awk_t* awk = QSE_NULL;
|
||||
qse_awk_rtx_t* rtx = QSE_NULL;
|
||||
qse_awk_val_t* retv;
|
||||
qse_awk_parsestd_t psin[2];
|
||||
qse_awk_rio_t rio;
|
||||
int ret = -1;
|
||||
|
||||
/* create an awk object */
|
||||
awk = qse_awk_openstd (0, QSE_NULL);
|
||||
if (awk == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open awk\n"));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* prepare a script to parse */
|
||||
psin[0].type = QSE_AWK_PARSESTD_STR;
|
||||
psin[0].u.str.ptr = script;
|
||||
psin[0].u.str.len = qse_strlen(script);
|
||||
psin[1].type = QSE_AWK_PARSESTD_NULL;
|
||||
|
||||
/* parse a script in a string */
|
||||
if (qse_awk_parsestd (awk, psin, QSE_NULL) <= -1)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* open a runtime context */
|
||||
rtx = qse_awk_rtx_openstd (
|
||||
awk,
|
||||
0,
|
||||
QSE_T("awk01"),
|
||||
QSE_NULL, /* stdin */
|
||||
QSE_NULL, /* stdout */
|
||||
QSE_NULL /* default cmgr */
|
||||
);
|
||||
if (rtx == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"),
|
||||
qse_awk_geterrmsg(awk));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* retrieve the I/O handlers created by qse_awk_rtx_openstd() */
|
||||
qse_awk_rtx_getrio (rtx, &rio);
|
||||
/* override the console handler */
|
||||
rio.console = handle_console;
|
||||
/* update the I/O handlers */
|
||||
qse_awk_rtx_setrio (rtx, &rio);
|
||||
|
||||
/* execute pattern-action blocks */
|
||||
retv = qse_awk_rtx_loop (rtx);
|
||||
if (retv == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"),
|
||||
qse_awk_rtx_geterrmsg(rtx));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* decrement the reference count of the return value */
|
||||
qse_awk_rtx_refdownval (rtx, retv);
|
||||
ret = 0;
|
||||
|
||||
oops:
|
||||
/* destroy the runtime context */
|
||||
if (rtx) qse_awk_rtx_close (rtx);
|
||||
|
||||
/* destroy the awk object */
|
||||
if (awk) qse_awk_close (awk);
|
||||
|
||||
qse_printf (QSE_T("Console Output:\n================\n%.*s\n"), (int)conoutpos, conout);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qse_main (int argc, qse_achar_t* argv[])
|
||||
{
|
||||
int x;
|
||||
|
||||
qse_open_stdsios ();
|
||||
init_awk_sample_locale ();
|
||||
x = qse_run_main (argc, argv, awk_main);
|
||||
qse_close_stdsios ();
|
||||
return x;
|
||||
}
|
179
samples/awk/awk03.c
Normal file
179
samples/awk/awk03.c
Normal file
@ -0,0 +1,179 @@
|
||||
#include <qse/awk/stdawk.h>
|
||||
#include <qse/cmn/str.h>
|
||||
#include <qse/si/sio.h>
|
||||
#include <qse/cmn/main.h>
|
||||
#include "awk00.h"
|
||||
|
||||
/* i'll print records with the second field grater than 4.
|
||||
* at the end, we'll print the number of records seen so far */
|
||||
static const qse_char_t* script =
|
||||
QSE_T("$2 > 4 { print $0; } END { print NR; }");
|
||||
|
||||
struct console_t
|
||||
{
|
||||
/* console input */
|
||||
const qse_char_t* conin;
|
||||
qse_size_t coninpos;
|
||||
|
||||
/* console output */
|
||||
qse_char_t conout[10000]; /* fixed-size console buffer for demo only */
|
||||
qse_size_t conoutpos;
|
||||
};
|
||||
|
||||
typedef struct console_t console_t;
|
||||
|
||||
/* this is the console I/O handler */
|
||||
static qse_ssize_t handle_console (
|
||||
qse_awk_rtx_t* rtx,
|
||||
qse_awk_rio_cmd_t cmd,
|
||||
qse_awk_rio_arg_t* arg,
|
||||
qse_char_t* data,
|
||||
qse_size_t count)
|
||||
{
|
||||
console_t* con = qse_awk_rtx_getxtn(rtx);
|
||||
|
||||
/* this function is called separately for the console input and console
|
||||
* output. however, since i don't maintain underlying resources like
|
||||
* file handles, i don't really check if it's input or output.
|
||||
* you can check the value of #qse_awk_rio_mode_t in the arg->mode
|
||||
* field if you want to tell.
|
||||
*/
|
||||
switch (cmd)
|
||||
{
|
||||
case QSE_AWK_RIO_OPEN:
|
||||
/* 0 for success, -1 for failure. */
|
||||
return 0;
|
||||
|
||||
case QSE_AWK_RIO_CLOSE:
|
||||
/* 0 for success, -1 for failure. */
|
||||
return 0;
|
||||
|
||||
case QSE_AWK_RIO_READ:
|
||||
{
|
||||
qse_ssize_t len = 0;
|
||||
|
||||
while (con->conin[con->coninpos] && len < count)
|
||||
data[len++] = con->conin[con->coninpos++];
|
||||
|
||||
/* 0 for EOF, -1 for failure.
|
||||
positive numbers for the number of characters read */
|
||||
return len;
|
||||
}
|
||||
|
||||
case QSE_AWK_RIO_WRITE:
|
||||
con->conoutpos += qse_strxncpy (
|
||||
&con->conout[con->conoutpos], QSE_COUNTOF(con->conout) - con->conoutpos,
|
||||
data, count);
|
||||
/* 0 for EOF, -1 for failure.
|
||||
positive numbers for the number of characters written */
|
||||
return count;
|
||||
|
||||
case QSE_AWK_RIO_FLUSH:
|
||||
/* 0 for success, -1 for failure. */
|
||||
return 0;
|
||||
|
||||
case QSE_AWK_RIO_NEXT:
|
||||
/* 0 for success, -1 for failure. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* this part will never be reached */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int awk_main (int argc, qse_char_t* argv[])
|
||||
{
|
||||
qse_awk_t* awk = QSE_NULL;
|
||||
qse_awk_rtx_t* rtx = QSE_NULL;
|
||||
qse_awk_val_t* retv;
|
||||
qse_awk_parsestd_t psin[2];
|
||||
qse_awk_rio_t rio;
|
||||
int ret = -1;
|
||||
console_t* con;
|
||||
|
||||
/* create an awk object */
|
||||
awk = qse_awk_openstd (0, QSE_NULL);
|
||||
if (awk == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open awk\n"));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* prepare a script to parse */
|
||||
psin[0].type = QSE_AWK_PARSESTD_STR;
|
||||
psin[0].u.str.ptr = script;
|
||||
psin[0].u.str.len = qse_strlen(script);
|
||||
psin[1].type = QSE_AWK_PARSESTD_NULL;
|
||||
|
||||
/* parse a script in a string */
|
||||
if (qse_awk_parsestd (awk, psin, QSE_NULL) <= -1)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* open a runtime context */
|
||||
rtx = qse_awk_rtx_openstd (
|
||||
awk,
|
||||
QSE_SIZEOF(console_t), /* the size of extenstion area */
|
||||
QSE_T("awk01"),
|
||||
QSE_NULL, /* stdin */
|
||||
QSE_NULL, /* stdout */
|
||||
QSE_NULL /* default cmgr */
|
||||
);
|
||||
if (rtx == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* get the pointer to the extension area. */
|
||||
con = (console_t*)qse_awk_rtx_getxtn(rtx);
|
||||
/* initialize fields that require non-zero values.
|
||||
* the entire extension area was initialized to zeros
|
||||
* when it was created. */
|
||||
con->conin = QSE_T("Beth 4.00 0\nDan 3.74 0\nKathy 4.00 10\nMark 5.00 20\nMary 5.50 22\nSusie 4.25 18\n");
|
||||
|
||||
/* retrieve the I/O handlers created by qse_awk_rtx_openstd() */
|
||||
qse_awk_rtx_getrio (rtx, &rio);
|
||||
/* override the console handler */
|
||||
rio.console = handle_console;
|
||||
/* update the I/O handlers */
|
||||
qse_awk_rtx_setrio (rtx, &rio);
|
||||
|
||||
/* execute pattern-action blocks */
|
||||
retv = qse_awk_rtx_loop (rtx);
|
||||
if (retv == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_rtx_geterrmsg(rtx));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* decrement the reference count of the return value */
|
||||
qse_awk_rtx_refdownval (rtx, retv);
|
||||
|
||||
/* the buffer is available during the runtime context is alive */
|
||||
qse_printf (QSE_T("Console Output:\n================\n%.*s\n"), (int)con->conoutpos, con->conout);
|
||||
|
||||
ret = 0;
|
||||
|
||||
oops:
|
||||
/* destroy the runtime context */
|
||||
if (rtx) qse_awk_rtx_close (rtx);
|
||||
|
||||
/* destroy the awk object */
|
||||
if (awk) qse_awk_close (awk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qse_main (int argc, qse_achar_t* argv[])
|
||||
{
|
||||
int x;
|
||||
qse_open_stdsios ();
|
||||
init_awk_sample_locale ();
|
||||
x = qse_run_main (argc, argv, awk_main);
|
||||
qse_close_stdsios ();
|
||||
return x;
|
||||
}
|
128
samples/awk/awk04.c
Normal file
128
samples/awk/awk04.c
Normal file
@ -0,0 +1,128 @@
|
||||
#include <qse/awk/stdawk.h>
|
||||
#include <qse/si/sio.h>
|
||||
#include <qse/cmn/main.h>
|
||||
#include "awk00.h"
|
||||
|
||||
static const qse_char_t* src = QSE_T(
|
||||
"function init() { a = 20; return a; }"
|
||||
"function main() { return ++a; }"
|
||||
"function fini() { print \"a in fini() =>\", ++a; return a; }"
|
||||
);
|
||||
|
||||
static const qse_char_t* fnc[] =
|
||||
{
|
||||
QSE_T("init"),
|
||||
QSE_T("main"),
|
||||
QSE_T("main"),
|
||||
QSE_T("main"),
|
||||
QSE_T("main"),
|
||||
QSE_T("fini"),
|
||||
};
|
||||
|
||||
static int awk_main (int argc, qse_char_t* argv[])
|
||||
{
|
||||
qse_awk_t* awk = QSE_NULL;
|
||||
qse_awk_rtx_t* rtx = QSE_NULL;
|
||||
qse_awk_parsestd_t psin[2];
|
||||
int ret = -1, i, opt;
|
||||
|
||||
/* create an awk object */
|
||||
awk = qse_awk_openstd (0, QSE_NULL);
|
||||
if (awk == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open awk\n"));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* get the awk's trait */
|
||||
qse_awk_getopt (awk, QSE_AWK_TRAIT, &opt);
|
||||
/* change the trait value to disallow BEGIN, END, pattern-action blocks */
|
||||
opt &= ~QSE_AWK_PABLOCK;
|
||||
/* update the trait */
|
||||
qse_awk_setopt (awk, QSE_AWK_TRAIT, &opt);
|
||||
|
||||
/* prepare a script to parse */
|
||||
psin[0].type = QSE_AWK_PARSESTD_STR;
|
||||
psin[0].u.str.ptr = src;
|
||||
psin[0].u.str.len = qse_strlen(src);
|
||||
psin[1].type = QSE_AWK_PARSESTD_NULL;
|
||||
|
||||
/* parse a script */
|
||||
if (qse_awk_parsestd (awk, psin, QSE_NULL) <= -1)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"),
|
||||
qse_awk_geterrmsg(awk));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* create a runtime context */
|
||||
rtx = qse_awk_rtx_openstd (
|
||||
awk,
|
||||
0,
|
||||
QSE_T("awk03"),
|
||||
QSE_NULL, /* stdin */
|
||||
QSE_NULL, /* stdout */
|
||||
QSE_NULL /* default cmgr */
|
||||
);
|
||||
if (rtx == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* call init() initially, followed by 4 calls to main(),
|
||||
* and a final call to fini() */
|
||||
for (i = 0; i < QSE_COUNTOF(fnc); i++)
|
||||
{
|
||||
qse_awk_val_t* v;
|
||||
qse_char_t* str;
|
||||
qse_size_t len;
|
||||
|
||||
/* call the function */
|
||||
v = qse_awk_rtx_call (rtx, fnc[i], QSE_NULL, 0);
|
||||
if (v == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_rtx_geterrmsg(rtx));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* convert the return value to a string with duplication */
|
||||
str = qse_awk_rtx_valtostrdup (rtx, v, &len);
|
||||
|
||||
/* clear the return value */
|
||||
qse_awk_rtx_refdownval (rtx, v);
|
||||
|
||||
if (str == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_rtx_geterrmsg(rtx));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* print the return value */
|
||||
qse_printf (QSE_T("return: [%.*s]\n"), (int)len, str);
|
||||
|
||||
/* destroy the duplicated string */
|
||||
qse_awk_rtx_freemem (rtx, str);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
oops:
|
||||
/* destroy a runtime context */
|
||||
if (rtx) qse_awk_rtx_close (rtx);
|
||||
|
||||
/* destroy the awk object */
|
||||
if (awk) qse_awk_close (awk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qse_main (int argc, qse_achar_t* argv[])
|
||||
{
|
||||
int x;
|
||||
init_awk_sample_locale ();
|
||||
qse_open_stdsios ();
|
||||
x = qse_run_main (argc, argv, awk_main);
|
||||
qse_close_stdsios ();
|
||||
return x;
|
||||
}
|
134
samples/awk/awk05.c
Normal file
134
samples/awk/awk05.c
Normal file
@ -0,0 +1,134 @@
|
||||
#include <qse/awk/stdawk.h>
|
||||
#include <qse/si/sio.h>
|
||||
#include <qse/cmn/main.h>
|
||||
#include "awk00.h"
|
||||
|
||||
static const qse_char_t* src = QSE_T(
|
||||
"function pow(x,y) { return x ** y; }"
|
||||
);
|
||||
|
||||
static int awk_main (int argc, qse_char_t* argv[])
|
||||
{
|
||||
qse_awk_t* awk = QSE_NULL;
|
||||
qse_awk_rtx_t* rtx = QSE_NULL;
|
||||
qse_awk_parsestd_t psin[2];
|
||||
qse_char_t* str;
|
||||
qse_size_t len;
|
||||
qse_awk_val_t* rtv;
|
||||
qse_awk_val_t* arg[2] = { QSE_NULL, QSE_NULL };
|
||||
int ret = -1, i, opt;
|
||||
|
||||
/* create an awk object */
|
||||
awk = qse_awk_openstd (0, QSE_NULL);
|
||||
if (awk == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open awk\n"));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* get the awk's trait */
|
||||
qse_awk_getopt (awk, QSE_AWK_TRAIT, &opt);
|
||||
/* change the trait value to disallow BEGIN, END, pattern-action blocks */
|
||||
opt &= ~QSE_AWK_PABLOCK;
|
||||
/* update the trait */
|
||||
qse_awk_setopt (awk, QSE_AWK_TRAIT, &opt);
|
||||
|
||||
/* prepare an awk script to parse */
|
||||
psin[0].type = QSE_AWK_PARSESTD_STR;
|
||||
psin[0].u.str.ptr = src;
|
||||
psin[0].u.str.len = qse_strlen(src);
|
||||
psin[1].type = QSE_AWK_PARSESTD_NULL;
|
||||
|
||||
/* parse the script */
|
||||
if (qse_awk_parsestd (awk, psin, QSE_NULL) <= -1)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* create a runtime context */
|
||||
rtx = qse_awk_rtx_openstd (
|
||||
awk,
|
||||
0,
|
||||
QSE_T("awk04"),
|
||||
QSE_NULL, /* stdin */
|
||||
QSE_NULL, /* stdout */
|
||||
QSE_NULL /* default cmgr */
|
||||
);
|
||||
if (rtx == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* create the first argument to the pow function to call */
|
||||
arg[0] = qse_awk_rtx_makeintval (rtx, 50);
|
||||
if (arg[0] == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_rtx_geterrmsg(rtx));
|
||||
goto oops;
|
||||
}
|
||||
qse_awk_rtx_refupval (rtx, arg[0]);
|
||||
|
||||
/* create the second argument to the pow function to call */
|
||||
arg[1] = qse_awk_rtx_makeintval (rtx, 3);
|
||||
if (arg[1] == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_rtx_geterrmsg(rtx));
|
||||
goto oops;
|
||||
}
|
||||
qse_awk_rtx_refupval (rtx, arg[1]);
|
||||
|
||||
/* call the pow function */
|
||||
rtv = qse_awk_rtx_call (rtx, QSE_T("pow"), arg, 2);
|
||||
if (rtv == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_rtx_geterrmsg(rtx));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* duplicate the return value to a string */
|
||||
str = qse_awk_rtx_valtostrdup (rtx, rtv, &len);
|
||||
|
||||
/* clear the return value */
|
||||
qse_awk_rtx_refdownval (rtx, rtv);
|
||||
|
||||
if (str == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_rtx_geterrmsg(rtx));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
qse_printf (QSE_T("[%.*s]\n"), (int)len, str);
|
||||
|
||||
/* destroy the duplicated string */
|
||||
qse_awk_rtx_freemem (rtx, str);
|
||||
|
||||
ret = 0;
|
||||
|
||||
oops:
|
||||
/* dereference all arguments */
|
||||
for (i = 0; i < QSE_COUNTOF(arg); i++)
|
||||
{
|
||||
if (arg[i]) qse_awk_rtx_refdownval (rtx, arg[i]);
|
||||
}
|
||||
|
||||
/* destroy a runtime context */
|
||||
if (rtx) qse_awk_rtx_close (rtx);
|
||||
|
||||
/* destroy the processor */
|
||||
if (awk) qse_awk_close (awk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qse_main (int argc, qse_achar_t* argv[])
|
||||
{
|
||||
int x;
|
||||
qse_open_stdsios ();
|
||||
init_awk_sample_locale ();
|
||||
x = qse_run_main (argc, argv, awk_main);
|
||||
qse_close_stdsios ();
|
||||
return x;
|
||||
}
|
||||
|
143
samples/awk/awk06.c
Normal file
143
samples/awk/awk06.c
Normal file
@ -0,0 +1,143 @@
|
||||
#include <qse/awk/stdawk.h>
|
||||
#include <qse/si/sio.h>
|
||||
#include <qse/cmn/main.h>
|
||||
#include "awk00.h"
|
||||
|
||||
static const qse_char_t* src = QSE_T(
|
||||
"function pow(x,y) { return x ** y; }"
|
||||
);
|
||||
|
||||
static int awk_main (int argc, qse_char_t* argv[])
|
||||
{
|
||||
qse_awk_t* awk = QSE_NULL;
|
||||
qse_awk_rtx_t* rtx = QSE_NULL;
|
||||
qse_awk_parsestd_t psin[2];
|
||||
qse_char_t* str;
|
||||
qse_size_t len;
|
||||
qse_awk_val_t* rtv;
|
||||
qse_awk_val_t* arg[2] = { QSE_NULL, QSE_NULL };
|
||||
int ret = -1, i, opt;
|
||||
qse_awk_fun_t* fun;
|
||||
|
||||
/* create an awk object */
|
||||
awk = qse_awk_openstd (0, QSE_NULL);
|
||||
if (awk == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open awk\n"));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* get the awk's trait */
|
||||
qse_awk_getopt (awk, QSE_AWK_TRAIT, &opt);
|
||||
/* change the trait value to disallow BEGIN, END, pattern-action blocks */
|
||||
opt &= ~QSE_AWK_PABLOCK;
|
||||
/* update the trait */
|
||||
qse_awk_setopt (awk, QSE_AWK_TRAIT, &opt);
|
||||
|
||||
/* prepare an awk script to parse */
|
||||
psin[0].type = QSE_AWK_PARSESTD_STR;
|
||||
psin[0].u.str.ptr = src;
|
||||
psin[0].u.str.len = qse_strlen(src);
|
||||
psin[1].type = QSE_AWK_PARSESTD_NULL;
|
||||
|
||||
/* parse the script */
|
||||
if (qse_awk_parsestd (awk, psin, QSE_NULL) <= -1)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* create a runtime context */
|
||||
rtx = qse_awk_rtx_openstd (
|
||||
awk,
|
||||
0,
|
||||
QSE_T("awk05"),
|
||||
QSE_NULL, /* stdin */
|
||||
QSE_NULL, /* stdout */
|
||||
QSE_NULL /* default cmgr */
|
||||
);
|
||||
if (rtx == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* create the first argument to the pow function to call */
|
||||
arg[0] = qse_awk_rtx_makeintval (rtx, 50);
|
||||
if (arg[0] == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_rtx_geterrmsg(rtx));
|
||||
goto oops;
|
||||
}
|
||||
qse_awk_rtx_refupval (rtx, arg[0]);
|
||||
|
||||
/* create the second argument to the pow function to call */
|
||||
arg[1] = qse_awk_rtx_makeintval (rtx, 3);
|
||||
if (arg[1] == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_rtx_geterrmsg(rtx));
|
||||
goto oops;
|
||||
}
|
||||
qse_awk_rtx_refupval (rtx, arg[1]);
|
||||
|
||||
/* find the pow function */
|
||||
fun = qse_awk_rtx_findfun (rtx, QSE_T("pow"));
|
||||
if (fun == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_rtx_geterrmsg(rtx));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* call the function found */
|
||||
rtv = qse_awk_rtx_callfun (rtx, fun, arg, 2);
|
||||
if (rtv == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_rtx_geterrmsg(rtx));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* duplicate the return value to a string */
|
||||
str = qse_awk_rtx_valtostrdup (rtx, rtv, &len);
|
||||
|
||||
/* clear the return value */
|
||||
qse_awk_rtx_refdownval (rtx, rtv);
|
||||
|
||||
if (str == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_rtx_geterrmsg(rtx));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
qse_printf (QSE_T("[%.*s]\n"), (int)len, str);
|
||||
|
||||
/* destroy the duplicated string */
|
||||
qse_awk_rtx_freemem (rtx, str);
|
||||
|
||||
ret = 0;
|
||||
|
||||
oops:
|
||||
/* dereference all arguments */
|
||||
for (i = 0; i < QSE_COUNTOF(arg); i++)
|
||||
{
|
||||
if (arg[i]) qse_awk_rtx_refdownval (rtx, arg[i]);
|
||||
}
|
||||
|
||||
/* destroy a runtime context */
|
||||
if (rtx) qse_awk_rtx_close (rtx);
|
||||
|
||||
/* destroy the processor */
|
||||
if (awk) qse_awk_close (awk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qse_main (int argc, qse_achar_t* argv[])
|
||||
{
|
||||
int x;
|
||||
qse_open_stdsios ();
|
||||
init_awk_sample_locale ();
|
||||
x = qse_run_main (argc, argv, awk_main);
|
||||
qse_close_stdsios ();
|
||||
return x;
|
||||
}
|
||||
|
168
samples/awk/awk07.c
Normal file
168
samples/awk/awk07.c
Normal file
@ -0,0 +1,168 @@
|
||||
#include <qse/awk/stdawk.h>
|
||||
#include <qse/si/sio.h>
|
||||
#include <qse/cmn/main.h>
|
||||
#include "awk00.h"
|
||||
|
||||
static const qse_char_t* src = QSE_T(
|
||||
"function dump(x) { OFS=\"=\"; for (k in x) print k, x[k]; x[\"f99\"]=\"os2\"; return x; }"
|
||||
);
|
||||
|
||||
static int awk_main (int argc, qse_char_t* argv[])
|
||||
{
|
||||
qse_awk_t* awk = QSE_NULL;
|
||||
qse_awk_rtx_t* rtx = QSE_NULL;
|
||||
qse_awk_parsestd_t psin[2];
|
||||
qse_awk_val_t* rtv = QSE_NULL;
|
||||
qse_awk_val_t* arg = QSE_NULL;
|
||||
int ret = -1, opt;
|
||||
|
||||
/* this structure is passed to qse_awk_rtx_makemapvalwithdata() */
|
||||
qse_awk_val_map_data_t md[] =
|
||||
{
|
||||
{ { QSE_T("f0"), 2 }, QSE_AWK_VAL_MAP_DATA_STR, QSE_T("linux") },
|
||||
{ { QSE_T("f1"), 2 }, QSE_AWK_VAL_MAP_DATA_STR, QSE_T("openvms") },
|
||||
{ { QSE_T("f2"), 2 }, QSE_AWK_VAL_MAP_DATA_STR, QSE_T("hpux") },
|
||||
{ { QSE_NULL, 0 }, 0, QSE_NULL } /* last item */
|
||||
};
|
||||
|
||||
/* create a standard awk object */
|
||||
awk = qse_awk_openstd (0, QSE_NULL);
|
||||
if (awk == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open awk\n"));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* get the awk's trait */
|
||||
qse_awk_getopt (awk, QSE_AWK_TRAIT, &opt);
|
||||
/* change the trait value to disallow BEGIN, END, pattern-action blocks */
|
||||
opt &= ~QSE_AWK_PABLOCK;
|
||||
/* update the trait */
|
||||
qse_awk_setopt (awk, QSE_AWK_TRAIT, &opt);
|
||||
|
||||
/* prepare a script to parse */
|
||||
psin[0].type = QSE_AWK_PARSESTD_STR;
|
||||
psin[0].u.str.ptr = src;
|
||||
psin[0].u.str.len = qse_strlen(src);
|
||||
psin[1].type = QSE_AWK_PARSESTD_NULL;
|
||||
|
||||
/* parse the script */
|
||||
if (qse_awk_parsestd (awk, psin, QSE_NULL) <= -1)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* create a standard runtime context */
|
||||
rtx = qse_awk_rtx_openstd (
|
||||
awk,
|
||||
0,
|
||||
QSE_T("awk06"),
|
||||
QSE_NULL, /* stdin */
|
||||
QSE_NULL, /* stdout */
|
||||
QSE_NULL /* default cmgr */
|
||||
|
||||
);
|
||||
if (rtx == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* create a map value to pass as an argument */
|
||||
arg = qse_awk_rtx_makemapvalwithdata (rtx, md);
|
||||
if (arg == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_rtx_geterrmsg(rtx));
|
||||
goto oops;
|
||||
}
|
||||
qse_awk_rtx_refupval (rtx, arg);
|
||||
|
||||
/* execute the dump function in the awk script */
|
||||
rtv = qse_awk_rtx_call (rtx, QSE_T("dump"), &arg, 1);
|
||||
if (rtv == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_rtx_geterrmsg(rtx));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
if (qse_awk_rtx_getvaltype (rtx, rtv) == QSE_AWK_VAL_MAP)
|
||||
{
|
||||
/* if a returned value is a map,
|
||||
* traverse the map and print the key/value pairs. */
|
||||
|
||||
qse_awk_val_map_itr_t itr;
|
||||
qse_awk_val_map_itr_t* iptr;
|
||||
|
||||
/* get the iterator to the first key/value pair */
|
||||
iptr = qse_awk_rtx_getfirstmapvalitr (rtx, rtv, &itr);
|
||||
while (iptr)
|
||||
{
|
||||
qse_cstr_t str;
|
||||
|
||||
/* #QSE_AWK_VAL_MAP_ITR_VAL returns the value part */
|
||||
str.ptr = qse_awk_rtx_valtostrdup (
|
||||
rtx, QSE_AWK_VAL_MAP_ITR_VAL(iptr), &str.len);
|
||||
if (str.ptr == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_rtx_geterrmsg(rtx));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* #QSE_AWK_VAL_MAP_ITR_KEY returns the key part */
|
||||
qse_printf (QSE_T("ret [%.*s]=[%.*s]\n"),
|
||||
(int)QSE_AWK_VAL_MAP_ITR_KEY(iptr)->len,
|
||||
QSE_AWK_VAL_MAP_ITR_KEY(iptr)->ptr,
|
||||
(int)str.len, 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);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if it is a plain value, convert it to a string
|
||||
* and print it */
|
||||
qse_cstr_t str;
|
||||
|
||||
str.ptr = qse_awk_rtx_valtostrdup (rtx, rtv, &str.len);
|
||||
if (str.ptr == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_rtx_geterrmsg(rtx));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
qse_printf (QSE_T("ret [%.*s]\n"), (int)str.len, str.ptr);
|
||||
qse_awk_rtx_freemem (rtx, str.ptr);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
oops:
|
||||
/* clear the return value */
|
||||
if (rtv) qse_awk_rtx_refdownval (rtx, rtv);
|
||||
|
||||
/* dereference the argument */
|
||||
if (arg) qse_awk_rtx_refdownval (rtx, arg);
|
||||
|
||||
/* destroy a runtime context */
|
||||
if (rtx) qse_awk_rtx_close (rtx);
|
||||
|
||||
/* destroy the processor */
|
||||
if (awk) qse_awk_close (awk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qse_main (int argc, qse_achar_t* argv[])
|
||||
{
|
||||
int x;
|
||||
qse_open_stdsios ();
|
||||
init_awk_sample_locale ();
|
||||
x = qse_run_main (argc, argv, awk_main);
|
||||
qse_close_stdsios ();
|
||||
return x;
|
||||
}
|
||||
|
145
samples/awk/awk08.c
Normal file
145
samples/awk/awk08.c
Normal file
@ -0,0 +1,145 @@
|
||||
#include <qse/awk/stdawk.h>
|
||||
#include <qse/si/sio.h>
|
||||
#include <qse/cmn/main.h>
|
||||
#include "awk00.h"
|
||||
|
||||
static const qse_char_t* src = QSE_T(
|
||||
"BEGIN { G0 = 10; G1 = \"hello, world\"; G2 = sin(90); G3=33; G4=44; G5=55; G6=66; G7=77; G8=88; G9=99; match (\"abcdefg\", /[c-f]+/); }"
|
||||
);
|
||||
|
||||
struct ginfo_t
|
||||
{
|
||||
int g[10];
|
||||
};
|
||||
|
||||
typedef struct ginfo_t ginfo_t;
|
||||
|
||||
static int awk_main (int argc, qse_char_t* argv[])
|
||||
{
|
||||
qse_awk_t* awk = QSE_NULL;
|
||||
qse_awk_rtx_t* rtx = QSE_NULL;
|
||||
qse_awk_parsestd_t psin[2];
|
||||
qse_char_t* str;
|
||||
qse_size_t len;
|
||||
qse_awk_val_t* rtv;
|
||||
int ret = -1, i;
|
||||
ginfo_t* ginfo;
|
||||
|
||||
/* create an awk object */
|
||||
awk = qse_awk_openstd(QSE_SIZEOF(*ginfo), QSE_NULL);
|
||||
if (awk == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open awk\n"));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* add global variables G1, G2, and G3. store the IDs to the extension
|
||||
* area. the extension area is used for demonstration. there is no special
|
||||
* need to use it when adding global variables. */
|
||||
ginfo = qse_awk_getxtn(awk);
|
||||
for (i = 0; i < QSE_COUNTOF(ginfo->g); i++)
|
||||
{
|
||||
qse_char_t name[] = QSE_T("GX");
|
||||
qse_wchar_t wname[] = QSE_WT("GX");
|
||||
qse_mchar_t mname[] = QSE_MT("GX");
|
||||
name[1] = QSE_T('0') + i;
|
||||
wname[1] = QSE_WT('0') + i;
|
||||
mname[1] = QSE_MT('0') + i;
|
||||
if (i < 3)
|
||||
ginfo->g[i] = qse_awk_addgblwithmbs(awk, mname);
|
||||
else if (i < 6)
|
||||
ginfo->g[i] = qse_awk_addgblwithwcs(awk, wname);
|
||||
else
|
||||
ginfo->g[i] = qse_awk_addgbl(awk, name);
|
||||
if (ginfo->g[i] <= -1)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk));
|
||||
goto oops;
|
||||
}
|
||||
}
|
||||
|
||||
/* prepare an awk script to parse */
|
||||
psin[0].type = QSE_AWK_PARSESTD_STR;
|
||||
psin[0].u.str.ptr = src;
|
||||
psin[0].u.str.len = qse_strlen(src);
|
||||
psin[1].type = QSE_AWK_PARSESTD_NULL;
|
||||
|
||||
/* parse the script */
|
||||
if (qse_awk_parsestd (awk, psin, QSE_NULL) <= -1)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* create a runtime context */
|
||||
rtx = qse_awk_rtx_openstd (
|
||||
awk,
|
||||
0,
|
||||
QSE_T("awk08"),
|
||||
QSE_NULL, /* stdin */
|
||||
QSE_NULL, /* stdout */
|
||||
QSE_NULL /* default cmgr */
|
||||
);
|
||||
if (rtx == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* execute the script over the standard data streams */
|
||||
rtv = qse_awk_rtx_loop (rtx);
|
||||
if (rtv == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_rtx_geterrmsg(rtx));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* clear the return value */
|
||||
qse_awk_rtx_refdownval (rtx, rtv);
|
||||
|
||||
/* get the values of built-in global variables
|
||||
* and print them */
|
||||
for (i = 0; i < QSE_COUNTOF(ginfo->g); i++)
|
||||
{
|
||||
str = qse_awk_rtx_valtostrdup (rtx, qse_awk_rtx_getgbl (rtx, ginfo->g[i]), &len);
|
||||
if (str == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_rtx_geterrmsg(rtx));
|
||||
goto oops;
|
||||
}
|
||||
qse_printf (QSE_T("G%d => %.*s\n"), i, (int)len, str);
|
||||
qse_awk_rtx_freemem (rtx, str);
|
||||
}
|
||||
|
||||
/* get the value of RLENGTH and print it */
|
||||
str = qse_awk_rtx_valtostrdup (rtx, qse_awk_rtx_getgbl (rtx, QSE_AWK_GBL_RLENGTH), &len);
|
||||
if (str == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_rtx_geterrmsg(rtx));
|
||||
goto oops;
|
||||
}
|
||||
qse_printf (QSE_T("RLENGTH => %.*s\n"), (int)len, str);
|
||||
qse_awk_rtx_freemem (rtx, str);
|
||||
|
||||
ret = 0;
|
||||
|
||||
oops:
|
||||
/* destroy a runtime context */
|
||||
if (rtx) qse_awk_rtx_close (rtx);
|
||||
|
||||
/* destroy the processor */
|
||||
if (awk) qse_awk_close (awk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qse_main (int argc, qse_achar_t* argv[])
|
||||
{
|
||||
int x;
|
||||
qse_open_stdsios ();
|
||||
init_awk_sample_locale ();
|
||||
x = qse_run_main (argc, argv, awk_main);
|
||||
qse_close_stdsios ();
|
||||
return x;
|
||||
}
|
||||
|
143
samples/awk/awk09.c
Normal file
143
samples/awk/awk09.c
Normal file
@ -0,0 +1,143 @@
|
||||
#include <qse/awk/stdawk.h>
|
||||
#include <qse/si/sio.h>
|
||||
#include <qse/cmn/main.h>
|
||||
#include <qse/cmn/mem.h>
|
||||
#include <qse/cmn/path.h>
|
||||
#include "awk00.h"
|
||||
|
||||
static const qse_char_t* src = QSE_T(
|
||||
"BEGIN { print basename(\"/etc/passwd\"); }"
|
||||
);
|
||||
|
||||
static int fnc_basename (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
||||
{
|
||||
qse_awk_val_t* a0, * rv;
|
||||
qse_char_t* ptr;
|
||||
qse_size_t len;
|
||||
|
||||
/* note that this implementation doesn't care if the parameter
|
||||
* contains a null character like "/etc/p\0asswd" */
|
||||
|
||||
/* get the value of the first parameter */
|
||||
a0 = qse_awk_rtx_getarg (rtx, 0);
|
||||
if (qse_awk_rtx_getvaltype (rtx, a0) == QSE_AWK_VAL_STR)
|
||||
{
|
||||
/* if it is a string value, don't duplicate the value */
|
||||
ptr = ((qse_awk_val_str_t*)a0)->val.ptr;
|
||||
len = ((qse_awk_val_str_t*)a0)->val.len;
|
||||
|
||||
/* make a string value with the base name */
|
||||
rv = qse_awk_rtx_makestrvalwithstr (rtx, qse_basename (ptr));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if it is a string value, convert the value to a string
|
||||
* with duplication */
|
||||
ptr = qse_awk_rtx_valtostrdup (rtx, a0, &len);
|
||||
if (ptr == QSE_NULL) return -1;
|
||||
|
||||
/* make a string value with the base name */
|
||||
rv = qse_awk_rtx_makestrvalwithstr (rtx, qse_basename (ptr));
|
||||
|
||||
/* free the duplicated string */
|
||||
qse_awk_rtx_freemem (rtx, ptr);
|
||||
}
|
||||
|
||||
if (rv == QSE_NULL) return -1;
|
||||
|
||||
/* set the return value that basename() will return */
|
||||
qse_awk_rtx_setretval (rtx, rv);
|
||||
|
||||
/* implemenation success */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int awk_main (int argc, qse_char_t* argv[])
|
||||
{
|
||||
qse_awk_t* awk = QSE_NULL;
|
||||
qse_awk_rtx_t* rtx = QSE_NULL;
|
||||
qse_awk_parsestd_t psin[2];
|
||||
qse_awk_val_t* rtv;
|
||||
int ret = -1;
|
||||
qse_awk_fnc_spec_t spec;
|
||||
|
||||
/* create an awk object */
|
||||
awk = qse_awk_openstd (0, QSE_NULL);
|
||||
if (awk == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open awk\n"));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* add a built-in function basename() */
|
||||
qse_memset (&spec, 0, QSE_SIZEOF(spec));
|
||||
spec.arg.min = 1; /* limit the number of arguments to 1 */
|
||||
spec.arg.max = 1;
|
||||
spec.impl = fnc_basename; /* specify the actual implementation */
|
||||
if (qse_awk_addfnc (awk, QSE_T("basename"), &spec) == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* prepare an awk script to parse */
|
||||
psin[0].type = QSE_AWK_PARSESTD_STR;
|
||||
psin[0].u.str.ptr = src;
|
||||
psin[0].u.str.len = qse_strlen(src);
|
||||
psin[1].type = QSE_AWK_PARSESTD_NULL;
|
||||
|
||||
/* parse the script */
|
||||
if (qse_awk_parsestd (awk, psin, QSE_NULL) <= -1)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* create a runtime context */
|
||||
rtx = qse_awk_rtx_openstd (
|
||||
awk,
|
||||
0,
|
||||
QSE_T("awk09"),
|
||||
QSE_NULL, /* stdin */
|
||||
QSE_NULL, /* stdout */
|
||||
QSE_NULL /* default cmgr */
|
||||
);
|
||||
if (rtx == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* execute the script over the standard data streams */
|
||||
rtv = qse_awk_rtx_loop (rtx);
|
||||
if (rtv == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_rtx_geterrmsg(rtx));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* clear the return value */
|
||||
qse_awk_rtx_refdownval (rtx, rtv);
|
||||
|
||||
ret = 0;
|
||||
|
||||
oops:
|
||||
/* destroy a runtime context */
|
||||
if (rtx) qse_awk_rtx_close (rtx);
|
||||
|
||||
/* destroy the processor */
|
||||
if (awk) qse_awk_close (awk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qse_main (int argc, qse_achar_t* argv[])
|
||||
{
|
||||
int x;
|
||||
qse_open_stdsios ();
|
||||
init_awk_sample_locale ();
|
||||
x = qse_run_main (argc, argv, awk_main);
|
||||
qse_close_stdsios ();
|
||||
return x;
|
||||
}
|
||||
|
155
samples/awk/awk10.c
Normal file
155
samples/awk/awk10.c
Normal file
@ -0,0 +1,155 @@
|
||||
#include <qse/awk/stdawk.h>
|
||||
#include <qse/si/sio.h>
|
||||
#include <qse/cmn/main.h>
|
||||
#include <qse/cmn/mem.h>
|
||||
#include <qse/cmn/path.h>
|
||||
#include "awk00.h"
|
||||
|
||||
static const qse_char_t* src = QSE_T(
|
||||
"BEGIN { if (basename(\"/etc/passwd\", base) <= -1) print \"ERROR\"; else print base; }"
|
||||
);
|
||||
|
||||
static int fnc_basename (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
||||
{
|
||||
qse_awk_val_t* a0, * rv = QSE_NULL;
|
||||
qse_char_t* ptr;
|
||||
qse_size_t len;
|
||||
|
||||
/* note that this implementation doesn't care if the parameter
|
||||
* contains a null character like "/etc/p\0asswd" */
|
||||
|
||||
/* get the value of the first parameter */
|
||||
a0 = qse_awk_rtx_getarg (rtx, 0);
|
||||
if (qse_awk_rtx_getvaltype (rtx, a0) == QSE_AWK_VAL_STR)
|
||||
{
|
||||
/* if it is a string value, don't duplicate the value */
|
||||
ptr = ((qse_awk_val_str_t*)a0)->val.ptr;
|
||||
len = ((qse_awk_val_str_t*)a0)->val.len;
|
||||
|
||||
/* make a string value with the base name */
|
||||
rv = qse_awk_rtx_makestrvalwithstr (rtx, qse_basename (ptr));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if it is a string value, convert the value to a string
|
||||
* with duplication */
|
||||
ptr = qse_awk_rtx_valtostrdup (rtx, a0, &len);
|
||||
if (ptr)
|
||||
{
|
||||
/* make a string value with the base name */
|
||||
rv = qse_awk_rtx_makestrvalwithstr (rtx, qse_basename (ptr));
|
||||
|
||||
/* free the duplicated string */
|
||||
qse_awk_rtx_freemem (rtx, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
if (rv)
|
||||
{
|
||||
/* change the value of the second parameter passed by reference */
|
||||
qse_awk_rtx_setrefval (rtx, qse_awk_rtx_getarg (rtx, 1), rv);
|
||||
|
||||
/* set the return value without error checks because
|
||||
* qse_awk_rtx_makeintval() for 0 never fails */
|
||||
qse_awk_rtx_setretval (rtx, qse_awk_rtx_makeintval (rtx, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* set the return value without error checks because
|
||||
* qse_awk_rtx_makeintval() for -1 never fails */
|
||||
qse_awk_rtx_setretval (rtx, qse_awk_rtx_makeintval (rtx, -1));
|
||||
}
|
||||
|
||||
/* implementation success */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int awk_main (int argc, qse_char_t* argv[])
|
||||
{
|
||||
qse_awk_t* awk = QSE_NULL;
|
||||
qse_awk_rtx_t* rtx = QSE_NULL;
|
||||
qse_awk_parsestd_t psin[2];
|
||||
qse_awk_val_t* rtv;
|
||||
int ret = -1;
|
||||
qse_awk_fnc_spec_t spec;
|
||||
|
||||
/* create an awk object */
|
||||
awk = qse_awk_openstd (0, QSE_NULL);
|
||||
if (awk == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open awk\n"));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* add a built-in function basename() */
|
||||
qse_memset (&spec, 0, QSE_SIZEOF(spec));
|
||||
spec.arg.min = 2; /* limit the number of arguments to 1 */
|
||||
spec.arg.max = 2;
|
||||
spec.arg.spec = QSE_T("vr"); /* pass the second argument by reference */
|
||||
spec.impl = fnc_basename; /* specify the actual implementation */
|
||||
if (qse_awk_addfnc (awk, QSE_T("basename"), &spec) == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* prepare an awk script to parse */
|
||||
psin[0].type = QSE_AWK_PARSESTD_STR;
|
||||
psin[0].u.str.ptr = src;
|
||||
psin[0].u.str.len = qse_strlen(src);
|
||||
psin[1].type = QSE_AWK_PARSESTD_NULL;
|
||||
|
||||
/* parse the script */
|
||||
if (qse_awk_parsestd (awk, psin, QSE_NULL) <= -1)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* create a runtime context */
|
||||
rtx = qse_awk_rtx_openstd (
|
||||
awk,
|
||||
0,
|
||||
QSE_T("awk10"),
|
||||
QSE_NULL, /* stdin */
|
||||
QSE_NULL, /* stdout */
|
||||
QSE_NULL /* default cmgr */
|
||||
);
|
||||
if (rtx == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* execute the script over the standard data streams */
|
||||
rtv = qse_awk_rtx_loop (rtx);
|
||||
if (rtv == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_rtx_geterrmsg(rtx));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/* clear the return value */
|
||||
qse_awk_rtx_refdownval (rtx, rtv);
|
||||
|
||||
ret = 0;
|
||||
|
||||
oops:
|
||||
/* destroy a runtime context */
|
||||
if (rtx) qse_awk_rtx_close (rtx);
|
||||
|
||||
/* destroy the processor */
|
||||
if (awk) qse_awk_close (awk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qse_main (int argc, qse_achar_t* argv[])
|
||||
{
|
||||
int x;
|
||||
qse_open_stdsios ();
|
||||
init_awk_sample_locale ();
|
||||
x = qse_run_main (argc, argv, awk_main);
|
||||
qse_close_stdsios ();
|
||||
return x;
|
||||
}
|
138
samples/awk/awk11.c
Normal file
138
samples/awk/awk11.c
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright (c) 2006-2019 Chung, Hyung-Hwan. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <qse/awk/stdawk.h>
|
||||
#include <qse/si/sio.h>
|
||||
|
||||
const qse_char_t* src = QSE_T("BEGIN { print \"hello, world\" | \"dir\"; }");
|
||||
|
||||
struct rtx_xtn_t
|
||||
{
|
||||
qse_awk_rio_impl_t old_pipe_handler;
|
||||
};
|
||||
|
||||
static qse_ssize_t new_pipe_handler (
|
||||
qse_awk_rtx_t* rtx, qse_awk_rio_cmd_t cmd, qse_awk_rio_arg_t* riod,
|
||||
qse_char_t* data, qse_size_t size)
|
||||
{
|
||||
struct rtx_xtn_t* xtn;
|
||||
|
||||
xtn = qse_awk_rtx_getxtn(rtx);
|
||||
|
||||
if (cmd == QSE_AWK_RIO_OPEN)
|
||||
qse_fprintf (QSE_STDERR, QSE_T("LOG: Executing [%s] for piping\n"), riod->name);
|
||||
|
||||
return xtn->old_pipe_handler (rtx, cmd, riod, data, size);
|
||||
}
|
||||
|
||||
static void extend_pipe_handler (qse_awk_rtx_t* rtx)
|
||||
{
|
||||
/* this function simply demonstrates how to extend
|
||||
* runtime I/O handlers provided by qse_awk_rtx_openstd() */
|
||||
|
||||
struct rtx_xtn_t* xtn;
|
||||
qse_awk_rio_t rio;
|
||||
|
||||
xtn = qse_awk_rtx_getxtn(rtx);
|
||||
|
||||
/* get the previous handler functions */
|
||||
qse_awk_rtx_getrio (rtx, &rio);
|
||||
|
||||
/* remember the old pipe handler function */
|
||||
xtn->old_pipe_handler = rio.pipe;
|
||||
|
||||
/* change the pipe handler to a new one */
|
||||
rio.pipe = new_pipe_handler;
|
||||
|
||||
/* changes the handlers with a new set */
|
||||
qse_awk_rtx_setrio (rtx, &rio);
|
||||
}
|
||||
|
||||
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[2];
|
||||
int ret = -1;
|
||||
|
||||
qse_open_stdsios ();
|
||||
|
||||
awk = qse_awk_openstd (0, QSE_NULL);
|
||||
if (awk == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open awk\n"));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
psin[0].type = QSE_AWK_PARSESTD_STR;
|
||||
psin[0].u.str.ptr = src;
|
||||
psin[0].u.str.len = qse_strlen(src);
|
||||
psin[1].type = QSE_AWK_PARSESTD_NULL;
|
||||
|
||||
if (qse_awk_parsestd (awk, psin, QSE_NULL) <= -1)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"),
|
||||
qse_awk_geterrmsg(awk));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
rtx = qse_awk_rtx_openstd (
|
||||
awk,
|
||||
QSE_SIZEOF(struct rtx_xtn_t),
|
||||
QSE_T("awk11"),
|
||||
QSE_NULL, /* stdin */
|
||||
QSE_NULL, /* stdout */
|
||||
QSE_NULL /* default cmgr */
|
||||
);
|
||||
if (rtx == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"),
|
||||
qse_awk_geterrmsg(awk));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
extend_pipe_handler (rtx);
|
||||
|
||||
retv = qse_awk_rtx_loop (rtx);
|
||||
if (retv == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"),
|
||||
qse_awk_rtx_geterrmsg(rtx));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
qse_awk_rtx_refdownval (rtx, retv);
|
||||
ret = 0;
|
||||
|
||||
oops:
|
||||
if (rtx != QSE_NULL) qse_awk_rtx_close (rtx);
|
||||
if (awk != QSE_NULL) qse_awk_close (awk);
|
||||
|
||||
qse_close_stdsios ();
|
||||
return ret;
|
||||
}
|
||||
|
97
samples/awk/awk12.c
Normal file
97
samples/awk/awk12.c
Normal file
@ -0,0 +1,97 @@
|
||||
#include <qse/awk/stdawk.h>
|
||||
#include <qse/si/sio.h>
|
||||
|
||||
/* this sample produces 8 text files containing multiplication chart. */
|
||||
|
||||
const qse_char_t* src = QSE_T(
|
||||
"BEGIN {"
|
||||
" for (i=2;i<=9;i++)"
|
||||
" {"
|
||||
" print \"OFILENAME:\" OFILENAME;"
|
||||
" for (j=1;j<=9;j++)"
|
||||
" print i \"*\" j \"=\" i * j;"
|
||||
" nextofile;"
|
||||
" }"
|
||||
"}"
|
||||
);
|
||||
|
||||
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[2];
|
||||
int ret = -1, opt;
|
||||
|
||||
const qse_char_t* output_files[] =
|
||||
{
|
||||
QSE_T("awk12.out.2"),
|
||||
QSE_T("awk12.out.3"),
|
||||
QSE_T("awk12.out.4"),
|
||||
QSE_T("awk12.out.5"),
|
||||
QSE_T("awk12.out.6"),
|
||||
QSE_T("awk12.out.7"),
|
||||
QSE_T("awk12.out.8"),
|
||||
QSE_T("awk12.out.9"),
|
||||
QSE_NULL
|
||||
};
|
||||
|
||||
qse_open_stdsios ();
|
||||
|
||||
awk = qse_awk_openstd (0, QSE_NULL);
|
||||
if (awk == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open awk\n"));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
qse_awk_getopt (awk, QSE_AWK_TRAIT, &opt);
|
||||
opt |= QSE_AWK_NEXTOFILE;
|
||||
qse_awk_setopt (awk, QSE_AWK_TRAIT, &opt);
|
||||
|
||||
psin[0].type = QSE_AWK_PARSESTD_STR;
|
||||
psin[0].u.str.ptr = src;
|
||||
psin[0].u.str.len = qse_strlen(src);
|
||||
psin[1].type = QSE_AWK_PARSESTD_NULL;
|
||||
|
||||
if (qse_awk_parsestd (awk, psin, QSE_NULL) <= -1)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"),
|
||||
qse_awk_geterrmsg(awk));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
rtx = qse_awk_rtx_openstd (
|
||||
awk,
|
||||
0,
|
||||
QSE_T("awk12"),
|
||||
QSE_NULL, /* stdin */
|
||||
output_files,
|
||||
QSE_NULL /* default cmgr */
|
||||
);
|
||||
if (rtx == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"),
|
||||
qse_awk_geterrmsg(awk));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
retv = qse_awk_rtx_loop (rtx);
|
||||
if (retv == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"),
|
||||
qse_awk_rtx_geterrmsg(rtx));
|
||||
goto oops;
|
||||
}
|
||||
|
||||
qse_awk_rtx_refdownval (rtx, retv);
|
||||
ret = 0;
|
||||
|
||||
oops:
|
||||
if (rtx != QSE_NULL) qse_awk_rtx_close (rtx);
|
||||
if (awk != QSE_NULL) qse_awk_close (awk);
|
||||
|
||||
qse_close_stdsios ();
|
||||
return ret;
|
||||
}
|
||||
|
157
samples/awk/awk15.c
Normal file
157
samples/awk/awk15.c
Normal file
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright (c) 2006-2019 Chung, Hyung-Hwan. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <qse/awk/awk.h>
|
||||
#include <qse/awk/stdawk.h>
|
||||
#include <qse/cmn/mem.h>
|
||||
#include <qse/cmn/path.h>
|
||||
#include <qse/cmn/str.h>
|
||||
#include <qse/si/sio.h>
|
||||
|
||||
static const qse_char_t* src = QSE_T(
|
||||
"BEGIN {"
|
||||
" for (i=2;i<=9;i++)"
|
||||
" {"
|
||||
" for (j=1;j<=9;j++)"
|
||||
" print i \"*\" j \"=\" i * j;"
|
||||
" print \"---------------------\";"
|
||||
" }"
|
||||
"}"
|
||||
);
|
||||
|
||||
int main (int argc, char* argv[])
|
||||
{
|
||||
qse_awk_t* awk = QSE_NULL;
|
||||
qse_awk_rtx_t* rtx = QSE_NULL;
|
||||
qse_awk_val_t* retv;
|
||||
|
||||
qse_awk_parsestd_t psin[2];
|
||||
qse_awk_parsestd_t psout;
|
||||
|
||||
int ret, omode = 0;
|
||||
|
||||
qse_open_stdsios ();
|
||||
|
||||
if (argc >= 2)
|
||||
{
|
||||
if (argc == 2 && qse_mbscmp(argv[1], "-m") == 0) omode = 1;
|
||||
else if (argc == 2 && qse_mbscmp(argv[1], "-w") == 0) omode = 2;
|
||||
else
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("USAGE: %hs [-m | -w]\n"), qse_mbsbasename(argv[0]));
|
||||
ret = -1; goto oops;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
awk = qse_awk_openstd(0, QSE_NULL);
|
||||
if (awk == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open awk\n"));
|
||||
ret = -1; goto oops;
|
||||
}
|
||||
|
||||
psin[0].type = QSE_AWK_PARSESTD_STR;
|
||||
psin[0].u.str.ptr = src;
|
||||
psin[0].u.str.len = qse_strlen(src);
|
||||
psin[1].type = QSE_AWK_PARSESTD_NULL;
|
||||
|
||||
switch (omode)
|
||||
{
|
||||
case 1:
|
||||
psout.type = QSE_AWK_PARSESTD_MBS;
|
||||
break;
|
||||
case 2:
|
||||
psout.type = QSE_AWK_PARSESTD_WCS;
|
||||
break;
|
||||
|
||||
default:
|
||||
psout.type = QSE_AWK_PARSESTD_STR;
|
||||
break;
|
||||
/* ps.out.u.str.ptr and ps.out.u.str.len are set when qse_awk_parsestd()
|
||||
* returns success */
|
||||
}
|
||||
|
||||
ret = qse_awk_parsestd(awk, psin, &psout);
|
||||
if (ret <= -1)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk));
|
||||
ret = -1; goto oops;
|
||||
}
|
||||
|
||||
qse_printf (QSE_T("DEPARSED SOURCE:\n"));
|
||||
switch (omode)
|
||||
{
|
||||
case 1:
|
||||
qse_printf (QSE_T("%hs\n"), psout.u.mbs.ptr);
|
||||
qse_awk_freemem (awk, psout.u.mbs.ptr);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
qse_printf (QSE_T("%ls\n"), psout.u.wcs.ptr);
|
||||
qse_awk_freemem (awk, psout.u.wcs.ptr);
|
||||
break;
|
||||
|
||||
default:
|
||||
qse_printf (QSE_T("%js\n"), psout.u.str.ptr);
|
||||
qse_awk_freemem (awk, psout.u.str.ptr);
|
||||
break;
|
||||
}
|
||||
qse_printf (QSE_T("=================================\n"));
|
||||
qse_fflush (QSE_STDOUT);
|
||||
|
||||
rtx = qse_awk_rtx_openstd (
|
||||
awk,
|
||||
0,
|
||||
QSE_T("awk15"),
|
||||
QSE_NULL, /* stdin */
|
||||
QSE_NULL, /* stdout */
|
||||
QSE_NULL /* default cmgr */
|
||||
);
|
||||
if (rtx == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk));
|
||||
ret = -1; goto oops;
|
||||
}
|
||||
|
||||
retv = qse_awk_rtx_loop(rtx);
|
||||
if (retv == QSE_NULL)
|
||||
{
|
||||
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_rtx_geterrmsg(rtx));
|
||||
ret = -1; goto oops;
|
||||
}
|
||||
|
||||
qse_awk_rtx_refdownval (rtx, retv);
|
||||
ret = 0;
|
||||
|
||||
oops:
|
||||
if (rtx != QSE_NULL) qse_awk_rtx_close (rtx);
|
||||
if (awk != QSE_NULL) qse_awk_close (awk);
|
||||
|
||||
qse_close_stdsios ();
|
||||
return -1;
|
||||
}
|
||||
|
32
samples/awk/awk21.cpp
Normal file
32
samples/awk/awk21.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
#include <qse/awk/StdAwk.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#if defined(QSE_CHAR_IS_MCHAR)
|
||||
# define xcout std::cout
|
||||
#else
|
||||
# define xcout std::wcout
|
||||
#endif
|
||||
|
||||
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; \
|
||||
}
|
136
samples/awk/awk22.cpp
Normal file
136
samples/awk/awk22.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
#include <qse/awk/StdAwk.hpp>
|
||||
#include <qse/si/sio.h>
|
||||
#include <string>
|
||||
|
||||
#if defined(QSE_CHAR_IS_WCHAR) && defined(QSE_USE_PREFIX_SMALL_U)
|
||||
typedef std::basic_string<char16_t> String;
|
||||
#elif 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 MyAwk: public StdAwk
|
||||
{
|
||||
public:
|
||||
//
|
||||
// this class overrides console methods to use
|
||||
// string buffers for console input and output.
|
||||
//
|
||||
MyAwk () { }
|
||||
~MyAwk () { close (); }
|
||||
|
||||
void setInput (const char_t* instr)
|
||||
{
|
||||
this->input = instr;
|
||||
this->inptr = this->input.c_str();
|
||||
this->inend = inptr + this->input.length();
|
||||
}
|
||||
|
||||
void clearOutput () { this->output.clear (); }
|
||||
const char_t* getOutput () { return this->output.c_str(); }
|
||||
|
||||
protected:
|
||||
String input; // console input buffer
|
||||
const char_t* inptr;
|
||||
const char_t* inend;
|
||||
|
||||
String output; // console output buffer
|
||||
|
||||
int openConsole (Console& io) { return 0; }
|
||||
int closeConsole (Console& io) { return 0; }
|
||||
int flushConsole (Console& io) { return 0; }
|
||||
int nextConsole (Console& io) { return 0; }
|
||||
|
||||
ssize_t readConsole (Console& io, char_t* data, size_t size)
|
||||
{
|
||||
if (this->inptr >= this->inend) return 0; // EOF
|
||||
size_t x = qse_strxncpy (data, size, inptr, inend - inptr);
|
||||
this->inptr += x;
|
||||
return x;
|
||||
}
|
||||
|
||||
ssize_t writeConsole (Console& io, const char_t* data, size_t size)
|
||||
{
|
||||
try { this->output.append (data, size); }
|
||||
catch (...)
|
||||
{
|
||||
((Run*)io)->setError (QSE_AWK_ENOMEM);
|
||||
return -1;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
};
|
||||
|
||||
static void print_error (
|
||||
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 int run_awk (MyAwk& awk)
|
||||
{
|
||||
// sample input string
|
||||
const qse_char_t* instr = QSE_T(
|
||||
"aardvark 555-5553 1200/300 B\n"
|
||||
"alpo-net 555-3412 2400/1200/300 A\n"
|
||||
"barfly 555-7685 1200/300 A\n"
|
||||
"bites 555-1675 2400/1200/300 A\n"
|
||||
"camelot 555-0542 300 C\n"
|
||||
"core 555-2912 1200/300 C\n"
|
||||
"fooey 555-1234 2400/1200/300 B\n"
|
||||
"foot 555-6699 1200/300 B\n"
|
||||
"macfoo 555-6480 1200/300 A\n"
|
||||
"sdace 555-3430 2400/1200/300 A\n"
|
||||
"sabafoo 555-2127 1200/300 C\n");
|
||||
|
||||
// ARGV[0]
|
||||
if (awk.addArgument (QSE_T("awk22")) <= -1) return -1;
|
||||
|
||||
// prepare a script to print the second and the first column
|
||||
MyAwk::SourceString in (QSE_T("{ print $2, $1; }"));
|
||||
|
||||
// parse the script.
|
||||
if (awk.parse (in, MyAwk::Source::NONE) == QSE_NULL) return -1;
|
||||
MyAwk::Value r;
|
||||
|
||||
awk.setInput (instr); // locate the input string
|
||||
awk.clearOutput (); // clear the output string
|
||||
int x = awk.loop (&r); // execute the BEGIN, pattern-action, END blocks.
|
||||
|
||||
if (x >= 0)
|
||||
{
|
||||
qse_printf (QSE_T("%s"), awk.getOutput()); // print the console output
|
||||
qse_printf (QSE_T("-----------------------------\n"));
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
int main (int argc, char* argv[])
|
||||
{
|
||||
MyAwk awk;
|
||||
|
||||
qse_open_stdsios ();
|
||||
int ret = awk.open ();
|
||||
if (ret >= 0) ret = run_awk (awk);
|
||||
|
||||
if (ret <= -1)
|
||||
{
|
||||
MyAwk::loc_t loc = awk.getErrorLocation();
|
||||
print_error (loc, awk.getErrorMessage());
|
||||
}
|
||||
|
||||
awk.close ();
|
||||
qse_close_stdsios ();
|
||||
return ret;
|
||||
}
|
||||
|
189
samples/awk/awk23.cpp
Normal file
189
samples/awk/awk23.cpp
Normal file
@ -0,0 +1,189 @@
|
||||
#include <qse/awk/StdAwk.hpp>
|
||||
#include <qse/si/sio.h>
|
||||
#include <string>
|
||||
|
||||
#if defined(QSE_CHAR_IS_WCHAR) && defined(QSE_USE_PREFIX_SMALL_U)
|
||||
typedef std::basic_string<char16_t> String;
|
||||
#elif 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 MyAwk: public StdAwk
|
||||
{
|
||||
public:
|
||||
//
|
||||
// this class overrides console methods to use
|
||||
// string buffers for console input and output.
|
||||
//
|
||||
MyAwk () { }
|
||||
~MyAwk () { close (); }
|
||||
|
||||
void setInput (const char_t* instr)
|
||||
{
|
||||
this->input = instr;
|
||||
this->inptr = this->input.c_str();
|
||||
this->inend = inptr + this->input.length();
|
||||
}
|
||||
|
||||
const char_t* getOutput () { return this->output.c_str(); }
|
||||
|
||||
protected:
|
||||
String input; // console input buffer
|
||||
const char_t* inptr;
|
||||
const char_t* inend;
|
||||
|
||||
String output; // console output buffer
|
||||
|
||||
int openConsole (Console& io)
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
int nextConsole (Console& io)
|
||||
{
|
||||
// this stripped-down awk doesn't honor the nextfile statement
|
||||
// or the nextofile statement. just return failure.
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssize_t readConsole (Console& io, char_t* data, size_t size)
|
||||
{
|
||||
if (this->inptr >= this->inend) return 0; // EOF
|
||||
size_t x = qse_strxncpy (data, size, inptr, inend - inptr);
|
||||
this->inptr += x;
|
||||
return x;
|
||||
}
|
||||
|
||||
ssize_t writeConsole (Console& io, const char_t* data, size_t size)
|
||||
{
|
||||
try { this->output.append (data, size); }
|
||||
catch (...)
|
||||
{
|
||||
((Run*)io)->setError (QSE_AWK_ENOMEM);
|
||||
return -1;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
};
|
||||
|
||||
static void print_error (
|
||||
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 int run_awk (MyAwk& awk)
|
||||
{
|
||||
// sample input string
|
||||
const qse_char_t* instr = QSE_T(
|
||||
"aardvark 555-5553 1200/300 B\n"
|
||||
"alpo-net 555-3412 2400/1200/300 A\n"
|
||||
"barfly 555-7685 1200/300 A\n"
|
||||
"bites 555-1675 2400/1200/300 A\n"
|
||||
"camelot 555-0542 300 C\n"
|
||||
"core 555-2912 1200/300 C\n"
|
||||
"fooey 555-1234 2400/1200/300 B\n"
|
||||
"foot 555-6699 1200/300 B\n"
|
||||
"macfoo 555-6480 1200/300 A\n"
|
||||
"sdace 555-3430 2400/1200/300 A\n"
|
||||
"sabafoo 555-2127 1200/300 C\n");
|
||||
|
||||
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("awk23")) <= -1) return -1;
|
||||
|
||||
// prepare a string to print lines with A in the fourth column
|
||||
MyAwk::SourceString in (QSE_T("$4 == \"A\" { print $2, $1, $3; }"));
|
||||
|
||||
// parse the script.
|
||||
if (awk.parse (in, MyAwk::Source::NONE) == QSE_NULL) return -1;
|
||||
MyAwk::Value r;
|
||||
|
||||
awk.setInput (instr); // locate the input string
|
||||
int x = awk.loop (&r); // execute the BEGIN, pattern-action, END blocks.
|
||||
|
||||
if (x >= 0)
|
||||
{
|
||||
qse_printf (QSE_T("%s"), awk.getOutput()); // print the console output
|
||||
qse_printf (QSE_T("-----------------------------\n"));
|
||||
|
||||
awk.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"), awk.getOutput());
|
||||
qse_printf (QSE_T("-----------------------------\n"));
|
||||
}
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
int main (int argc, char* argv[])
|
||||
{
|
||||
MyAwk awk;
|
||||
|
||||
qse_open_stdsios ();
|
||||
int ret = awk.open ();
|
||||
if (ret >= 0) ret = run_awk (awk);
|
||||
|
||||
if (ret <= -1)
|
||||
{
|
||||
MyAwk::loc_t loc = awk.getErrorLocation();
|
||||
print_error (loc, awk.getErrorMessage());
|
||||
}
|
||||
|
||||
awk.close ();
|
||||
qse_close_stdsios ();
|
||||
return ret;
|
||||
}
|
||||
|
190
samples/awk/awk24.cpp
Normal file
190
samples/awk/awk24.cpp
Normal file
@ -0,0 +1,190 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright (c) 2006-2019 Chung, Hyung-Hwan. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <qse/awk/StdAwk.hpp>
|
||||
#include <qse/si/sio.h>
|
||||
#include <qse/cmn/main.h>
|
||||
#include <qse/cmn/mbwc.h>
|
||||
|
||||
#include <locale.h>
|
||||
#if defined(_WIN32)
|
||||
# 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)
|
||||
{
|
||||
QSE::StdAwk::Run* run;
|
||||
|
||||
QSE::StdAwk::SourceString in (QSE_T(
|
||||
"function pa (x) {\n"
|
||||
" @reset ret;\n"
|
||||
" for (i in x) { print i, \"=>\", x[i]; ret += x[i]; }\n"
|
||||
" return ret + FOO++;\n"
|
||||
"}\n"
|
||||
"function pb (x) {\n"
|
||||
" @reset ret;\n"
|
||||
" for (i in x) { ret[-i] = -x[i]; }\n"
|
||||
" return ret;\n"
|
||||
"}"
|
||||
));
|
||||
|
||||
// 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) [%js]\n"), r.toStr(QSE_NULL));
|
||||
qse_printf (QSE_T(" (mbs) [%hs]\n"), r.toMbs(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) [%js]\n"), foov.toStr(QSE_NULL));
|
||||
qse_printf (QSE_T(" (mbs) [%hs]\n"), foov.toMbs(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);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int awk_main (int argc, qse_char_t* argv[])
|
||||
{
|
||||
QSE::StdAwk awk;
|
||||
|
||||
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)
|
||||
{
|
||||
QSE::StdAwk::loc_t loc = awk.getErrorLocation();
|
||||
print_error (loc, awk.getErrorMessage());
|
||||
}
|
||||
|
||||
awk.close ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int qse_main (int argc, qse_achar_t* argv[])
|
||||
{
|
||||
int x;
|
||||
|
||||
qse_open_stdsios ();
|
||||
|
||||
{
|
||||
#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
|
||||
}
|
||||
|
||||
x = qse_run_main (argc,argv,awk_main);
|
||||
qse_close_stdsios ();
|
||||
return x;
|
||||
}
|
497
samples/awk/awk25.cpp
Normal file
497
samples/awk/awk25.cpp
Normal file
@ -0,0 +1,497 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright (c) 2006-2019 Chung, Hyung-Hwan. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <qse/awk/StdAwk.hpp>
|
||||
#include <qse/cmn/HeapMmgr.hpp>
|
||||
#include <qse/cmn/opt.h>
|
||||
#include <qse/cmn/main.h>
|
||||
#include <qse/cmn/mbwc.h>
|
||||
#include <qse/si/sio.h>
|
||||
#include <cstring>
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
# include <windows.h>
|
||||
#elif defined(__OS2__)
|
||||
# define INCL_DOSPROCESS
|
||||
# include <os2.h>
|
||||
#else
|
||||
# include <unistd.h>
|
||||
# include <signal.h>
|
||||
# include <errno.h>
|
||||
#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
|
||||
{
|
||||
public:
|
||||
MyAwk (QSE::Mmgr* mmgr = QSE_NULL): StdAwk (mmgr) { }
|
||||
~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;
|
||||
}
|
||||
|
||||
Awk::int_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
|
||||
{
|
||||
print_error (QSE_T("line %u - %s\n"), (unsigned)loc.line, awk.getErrorMessage());
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static BOOL WINAPI stop_run (DWORD ctrl_type)
|
||||
{
|
||||
if (ctrl_type == CTRL_C_EVENT ||
|
||||
ctrl_type == CTRL_CLOSE_EVENT)
|
||||
{
|
||||
if (app_awk) app_awk->stop ();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
#else
|
||||
|
||||
static int setsignal (int sig, void(*handler)(int), int restart)
|
||||
{
|
||||
struct sigaction sa_int;
|
||||
|
||||
sa_int.sa_handler = handler;
|
||||
sigemptyset (&sa_int.sa_mask);
|
||||
|
||||
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->halt ();
|
||||
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_sio_t* 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_FLEXMAP | QSE_AWK_RWPIPE | QSE_AWK_NEXTOFILE);
|
||||
|
||||
// ARGV[0]
|
||||
if (awk.addArgument (QSE_T("awk25")) <= -1)
|
||||
{
|
||||
print_error (awk);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((n = handle_cmdline (awk, argc, argv, &cmdline)) <= 0) return n;
|
||||
|
||||
MyAwk::Source* in, * out;
|
||||
MyAwk::SourceString in_str (cmdline.ins);
|
||||
MyAwk::SourceFile in_file (cmdline.inf);
|
||||
MyAwk::SourceFile out_file (cmdline.outf);
|
||||
|
||||
in = (cmdline.ins)? (MyAwk::Source*)&in_str: (MyAwk::Source*)&in_file;
|
||||
out = (cmdline.outf)? (MyAwk::Source*)&out_file: &MyAwk::Source::NONE;
|
||||
run = awk.parse (*in, *out);
|
||||
if (run == QSE_NULL)
|
||||
{
|
||||
print_error (awk);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cmdline.fs)
|
||||
{
|
||||
MyAwk::Value fs (run);
|
||||
if (fs.setStr (cmdline.fs) <= -1)
|
||||
{
|
||||
print_error (awk);
|
||||
return -1;
|
||||
}
|
||||
if (awk.setGlobal (QSE_AWK_GBL_FS, fs) <= -1)
|
||||
{
|
||||
print_error (awk);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (cmdline.outc)
|
||||
{
|
||||
if (awk.addConsoleOutput (cmdline.outc) <= -1)
|
||||
{
|
||||
print_error (awk);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
MyAwk::Value ret;
|
||||
if (awk.loop (&ret) <= -1)
|
||||
{
|
||||
print_error (awk);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int awk_main (int argc, qse_char_t* argv[])
|
||||
{
|
||||
//QSE::HeapMmgr hm (1000000);
|
||||
//MyAwk awk (&hm);
|
||||
MyAwk awk;
|
||||
|
||||
if (awk.open() <= -1)
|
||||
{
|
||||
print_error (awk);
|
||||
return -1;
|
||||
}
|
||||
app_awk = &awk;
|
||||
|
||||
set_signal ();
|
||||
int n = awk_main_2 (awk, argc, argv);
|
||||
unset_signal ();
|
||||
|
||||
app_awk = QSE_NULL;
|
||||
awk.close ();
|
||||
return n;
|
||||
}
|
||||
|
||||
int qse_main (int argc, qse_achar_t* argv[])
|
||||
{
|
||||
int ret;
|
||||
|
||||
qse_open_stdsios ();
|
||||
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
char locale[100];
|
||||
UINT codepage;
|
||||
WSADATA wsadata;
|
||||
|
||||
codepage = GetConsoleOutputCP();
|
||||
if (codepage == CP_UTF8)
|
||||
{
|
||||
/*SetConsoleOUtputCP (CP_UTF8);*/
|
||||
qse_setdflcmgrbyid (QSE_CMGR_UTF8);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf (locale, ".%u", (unsigned int)codepage);
|
||||
setlocale (LC_ALL, locale);
|
||||
/*qse_setdflcmgrbyid (QSE_CMGR_SLMB);*/
|
||||
}
|
||||
|
||||
if (WSAStartup (MAKEWORD(2,0), &wsadata) != 0)
|
||||
{
|
||||
print_error (QSE_T("Failed to start up winsock\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
#else
|
||||
setlocale (LC_ALL, "");
|
||||
/*qse_setdflcmgrbyid (QSE_CMGR_SLMB);*/
|
||||
#endif
|
||||
}
|
||||
|
||||
ret = qse_run_main (argc, argv, awk_main);
|
||||
|
||||
#if defined(_WIN32)
|
||||
WSACleanup ();
|
||||
#endif
|
||||
|
||||
qse_close_stdsios ();
|
||||
return ret;
|
||||
}
|
118
samples/awk/awk26.cpp
Normal file
118
samples/awk/awk26.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright (c) 2006-2019 Chung, Hyung-Hwan. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <qse/awk/StdAwk.hpp>
|
||||
#include <qse/si/sio.h>
|
||||
#include <qse/cmn/main.h>
|
||||
#include <qse/cmn/mbwc.h>
|
||||
|
||||
#include <locale.h>
|
||||
#if defined(_WIN32)
|
||||
# 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[])
|
||||
{
|
||||
int x;
|
||||
|
||||
qse_open_stdsios ();
|
||||
{
|
||||
#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
|
||||
}
|
||||
|
||||
x = qse_run_main (argc,argv,awk_main);
|
||||
qse_close_stdsios ();
|
||||
return x;
|
||||
}
|
148
samples/awk/awk27.cpp
Normal file
148
samples/awk/awk27.cpp
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright (c) 2006-2019 Chung, Hyung-Hwan. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <qse/awk/StdAwk.hpp>
|
||||
#include <qse/si/sio.h>
|
||||
#include <qse/cmn/main.h>
|
||||
#include <qse/cmn/mbwc.h>
|
||||
|
||||
#include <locale.h>
|
||||
#if defined(_WIN32)
|
||||
# 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)
|
||||
{
|
||||
QSE::StdAwk::Run* run;
|
||||
|
||||
const qse_char_t* script = QSE_T(
|
||||
"function add (a, b) { return a + b }\n"
|
||||
"function mul (a, b) { return a * b }\n"
|
||||
"function div (a, b) { return a / b }\n"
|
||||
"function sine (a) { return sin(a) }\n"
|
||||
);
|
||||
|
||||
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) [%js]\n"), ret.toStr(QSE_NULL));
|
||||
qse_printf (QSE_T(" (mbs) [%hs]\n"), ret.toMbs(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) [%js]\n"), ret.toStr(QSE_NULL));
|
||||
qse_printf (QSE_T(" (mbs) [%hs]\n"), ret.toMbs(QSE_NULL));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 -1;
|
||||
}
|
||||
|
||||
int qse_main (int argc, qse_achar_t* argv[])
|
||||
{
|
||||
int x;
|
||||
|
||||
qse_open_stdsios ();
|
||||
|
||||
{
|
||||
#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
|
||||
}
|
||||
|
||||
x = qse_run_main (argc,argv,awk_main);
|
||||
qse_close_stdsios ();
|
||||
return x;
|
||||
}
|
270
samples/awk/awk28.cpp
Normal file
270
samples/awk/awk28.cpp
Normal file
@ -0,0 +1,270 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright (c) 2006-2019 Chung, Hyung-Hwan. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <qse/awk/StdAwk.hpp>
|
||||
#include <qse/si/sio.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) && defined(QSE_USE_PREFIX_SMALL_U)
|
||||
typedef std::basic_string<char16_t> String;
|
||||
#elif 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;
|
||||
}
|
||||
|
||||
StdAwk::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;
|
||||
}
|
||||
|
||||
StdAwk::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;
|
||||
}
|
||||
|
||||
StdAwk::ssize_t writeBytes (StdAwk::Console& io, const qse_mchar_t* data, size_t size)
|
||||
{
|
||||
/*
|
||||
try { this->output.append (data, size); }
|
||||
catch (...)
|
||||
{
|
||||
((StdAwk::Run*)io)->setError (QSE_AWK_ENOMEM);
|
||||
return -1;
|
||||
}
|
||||
return size;
|
||||
*/
|
||||
((StdAwk::Run*)io)->setError (QSE_AWK_ENOIMPL);
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
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[])
|
||||
{
|
||||
int x;
|
||||
qse_open_stdsios ();
|
||||
|
||||
{
|
||||
#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
|
||||
}
|
||||
|
||||
x = qse_run_main (argc,argv,awk_main);
|
||||
qse_close_stdsios ();
|
||||
return x;
|
||||
}
|
Reference in New Issue
Block a user