diff --git a/qse/doc/Makefile.in b/qse/doc/Makefile.in index 94c73389..9b129efd 100644 --- a/qse/doc/Makefile.in +++ b/qse/doc/Makefile.in @@ -231,12 +231,13 @@ EXTRA_DIST = \ gendoc.sh \ page/mainpage.md \ page/installation.md \ - page/mem.doc \ - page/cenc.doc \ - page/io.doc \ - page/awk.doc \ - page/awk-lang.md \ - page/sed.doc \ + page/mem.doc \ + page/cenc.doc \ + page/io.doc \ + page/awk.doc \ + page/awk-embed.md \ + page/awk-lang.md \ + page/sed.doc \ image/qse-logo.png all: all-am diff --git a/qse/doc/page/awk-embed.md b/qse/doc/page/awk-embed.md index 52f10a40..6b18565a 100644 --- a/qse/doc/page/awk-embed.md +++ b/qse/doc/page/awk-embed.md @@ -1,15 +1,19 @@ -Embedding Guid {#embedding-guide} +Embedding Guide {#embedding-guide} ================================================================================ Overview --------- -The design of the library is divided into two layers: core and standard. +The QSEAWK library is divided into two layers: core and standard. The core layer is a skeleton implmenetation that requires various callbacks to be useful. The standard layer provides these callbacks in a general respect. For example, qse_awk_open() in the core layer requires a set of primitive functions to be able to create an awk object while qse_awk_openstd() provides -qse_awk_open() with a standard set of primitive functions. +qse_awk_open() with a standard set of primitive functions. + +The core layer is defined in while the standard layer is +defined in . Naming-wise, a standard layer name contains *std* +over its corresponding core layer name. Embedding QSEAWK involves the following steps in the simplest form: @@ -21,8 +25,54 @@ Embedding QSEAWK involves the following steps in the simplest form: - close the runtime context - close the awk object -\includelineno awk01.c +The sample below follows these steps using as many standard layer functions as +possible for convenience sake. It simply prints *hello, world* to the console. + + \includelineno awk01.c + +Separation of the awk object and the runtime context was devised to deal with +such cases as you want to reuse the same script over different data streams. +More complex samples concerning this will be shown later. + +Customizing Console I/O +----------------------- + +The qse_awk_rtx_openstd() function implements I/O related callback functions +for files, pipes, and the console. While you are unlikely to change the +definition of files and pipes, the console is the most frequently customized +I/O object. Most likely, you may want to feed the console with a string or +something and capture the console output into a buffer. Though you can define +your own callback functions for files, pipes, and the console, it is possible +to override the callback functions implemented by qse_awk_rtx_openstd() +partially. This sample redefines the console handler while keeping the file +and pipe handler by qse_awk_rtx_openstd(). + + \includelineno awk02.c + + +Changes +------- + +### qse_awk_parsestd() ### + +In 0.5.6, it accepted a single script. + + qse_awk_parsestd_t psin; + psin.type = QSE_AWK_PARSESTD_STR; + psin.u.str.ptr = src; + psin.u.str.len = qse_strlen(src); + qse_awk_parsestd (awk, &psin, QSE_NULL); + +In 0.6.0 or later, it accepts an array of scripts. + + qse_awk_parsestd_t psin[2]; + 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_STR; + qse_awk_parsestd (awk, psin, QSE_NULL) + +### qse_awk_parsestd_t ### +the cmgr field moved from the union member file to the outer structure. -You can create multiple runtime contexts over a single awk object. It is useful -if you want to execute the same AWK script over different data streams. diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index 93027f05..18f23be6 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -653,7 +653,7 @@ typedef struct qse_awk_rio_arg_t qse_awk_rio_arg_t; typedef qse_ssize_t (*qse_awk_rio_impl_t) ( qse_awk_rtx_t* rtx, qse_awk_rio_cmd_t cmd, - qse_awk_rio_arg_t* riod, + qse_awk_rio_arg_t* arg, qse_char_t* data, qse_size_t count ); diff --git a/qse/lib/awk/std.c b/qse/lib/awk/std.c index d1ecbe07..2d8d6e25 100644 --- a/qse/lib/awk/std.c +++ b/qse/lib/awk/std.c @@ -1073,7 +1073,8 @@ int qse_awk_parsestd ( if (in == QSE_NULL || (in[0].type != QSE_AWK_PARSESTD_FILE && in[0].type != QSE_AWK_PARSESTD_STR)) { - /* the input is a must */ + /* the input is a must. at least 1 file or 1 string + * must be specified */ qse_awk_seterrnum (awk, QSE_AWK_EINVAL, QSE_NULL); return -1; } diff --git a/qse/samples/awk/Makefile.am b/qse/samples/awk/Makefile.am index 5472a553..277f9a56 100644 --- a/qse/samples/awk/Makefile.am +++ b/qse/samples/awk/Makefile.am @@ -5,7 +5,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/include \ -I$(includedir) -bin_PROGRAMS = awk01 awk02 awk03 awk04 awk09 awk10 awk11 +bin_PROGRAMS = awk01 awk02 awk03 awk04 awk09 awk10 awk11 awk15 LDFLAGS = -L../../lib/awk -L../../lib/cmn LDADD = -lqseawk -lqsecmn $(LIBM) @@ -23,6 +23,7 @@ awk04_SOURCES = awk04.c awk09_SOURCES = awk09.c awk10_SOURCES = awk10.c awk11_SOURCES = awk11.c +awk15_SOURCES = awk15.c if ENABLE_CXX diff --git a/qse/samples/awk/Makefile.in b/qse/samples/awk/Makefile.in index 3a90d878..562aa3c4 100644 --- a/qse/samples/awk/Makefile.in +++ b/qse/samples/awk/Makefile.in @@ -36,7 +36,7 @@ build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = awk01$(EXEEXT) awk02$(EXEEXT) awk03$(EXEEXT) \ awk04$(EXEEXT) awk09$(EXEEXT) awk10$(EXEEXT) awk11$(EXEEXT) \ - $(am__EXEEXT_1) + awk15$(EXEEXT) $(am__EXEEXT_1) @WCHAR_TRUE@@WIN32_TRUE@am__append_1 = $(UNICOWS_LIBS) @ENABLE_CXX_TRUE@am__append_2 = awk05 awk06 awk07 awk08 awk12 awk13 awk14 subdir = samples/awk @@ -125,6 +125,10 @@ am__awk14_SOURCES_DIST = awk14.cpp awk14_OBJECTS = $(am_awk14_OBJECTS) @ENABLE_CXX_TRUE@awk14_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @ENABLE_CXX_TRUE@ $(am__DEPENDENCIES_3) +am_awk15_OBJECTS = awk15.$(OBJEXT) +awk15_OBJECTS = $(am_awk15_OBJECTS) +awk15_LDADD = $(LDADD) +awk15_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/ac/depcomp am__depfiles_maybe = depfiles @@ -151,13 +155,14 @@ SOURCES = $(awk01_SOURCES) $(awk02_SOURCES) $(awk03_SOURCES) \ $(awk04_SOURCES) $(awk05_SOURCES) $(awk06_SOURCES) \ $(awk07_SOURCES) $(awk08_SOURCES) $(awk09_SOURCES) \ $(awk10_SOURCES) $(awk11_SOURCES) $(awk12_SOURCES) \ - $(awk13_SOURCES) $(awk14_SOURCES) + $(awk13_SOURCES) $(awk14_SOURCES) $(awk15_SOURCES) DIST_SOURCES = $(awk01_SOURCES) $(awk02_SOURCES) $(awk03_SOURCES) \ $(awk04_SOURCES) $(am__awk05_SOURCES_DIST) \ $(am__awk06_SOURCES_DIST) $(am__awk07_SOURCES_DIST) \ $(am__awk08_SOURCES_DIST) $(awk09_SOURCES) $(awk10_SOURCES) \ $(awk11_SOURCES) $(am__awk12_SOURCES_DIST) \ - $(am__awk13_SOURCES_DIST) $(am__awk14_SOURCES_DIST) + $(am__awk13_SOURCES_DIST) $(am__awk14_SOURCES_DIST) \ + $(awk15_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -346,6 +351,7 @@ awk04_SOURCES = awk04.c awk09_SOURCES = awk09.c awk10_SOURCES = awk10.c awk11_SOURCES = awk11.c +awk15_SOURCES = awk15.c @ENABLE_CXX_TRUE@CXXLIB = -lqseawkxx -lqsecmnxx @ENABLE_CXX_TRUE@awk05_SOURCES = awk05.cpp @ENABLE_CXX_TRUE@awk06_SOURCES = awk06.cpp @@ -480,6 +486,9 @@ awk13$(EXEEXT): $(awk13_OBJECTS) $(awk13_DEPENDENCIES) $(EXTRA_awk13_DEPENDENCIE awk14$(EXEEXT): $(awk14_OBJECTS) $(awk14_DEPENDENCIES) $(EXTRA_awk14_DEPENDENCIES) @rm -f awk14$(EXEEXT) $(CXXLINK) $(awk14_OBJECTS) $(awk14_LDADD) $(LIBS) +awk15$(EXEEXT): $(awk15_OBJECTS) $(awk15_DEPENDENCIES) $(EXTRA_awk15_DEPENDENCIES) + @rm -f awk15$(EXEEXT) + $(LINK) $(awk15_OBJECTS) $(awk15_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -501,6 +510,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk12.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk13.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk14.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk15.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< diff --git a/qse/samples/awk/awk01.c b/qse/samples/awk/awk01.c index 4fda605d..897a83db 100644 --- a/qse/samples/awk/awk01.c +++ b/qse/samples/awk/awk01.c @@ -8,7 +8,7 @@ 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; + qse_awk_parsestd_t psin[2]; int ret = -1; /* create an awk object */ @@ -19,12 +19,13 @@ int main () goto oops; } - psin.type = QSE_AWK_PARSESTD_STR; - psin.u.str.ptr = script; - psin.u.str.len = qse_strlen(script); + 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) + if (qse_awk_parsestd (awk, psin, QSE_NULL) <= -1) { qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk)); diff --git a/qse/samples/awk/awk02.c b/qse/samples/awk/awk02.c index 95f6ddb6..60815396 100644 --- a/qse/samples/awk/awk02.c +++ b/qse/samples/awk/awk02.c @@ -1,108 +1,153 @@ -/* - * $Id: awk02.c 441 2011-04-22 14:28:43Z hyunghwan.chung $ - * - Copyright 2006-2012 Chung, Hyung-Hwan. - This file is part of QSE. - - QSE is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - QSE is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with QSE. If not, see . - */ - -#include #include -#include +#include #include -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 \"---------------------\";" - " }" - "}" -); +/* 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; + +/* i'll store the console output to 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; +} + 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]; + qse_awk_rio_t rio; + int ret = -1; - qse_awk_parsestd_t psin; - qse_awk_parsestd_t psout; - - int ret; - + /* create an awk object */ awk = qse_awk_openstd (0); if (awk == QSE_NULL) { qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open awk\n")); - ret = -1; goto oops; + goto oops; } - psin.type = QSE_AWK_PARSESTD_STR; - psin.u.str.ptr = src; - psin.u.str.len = qse_strlen(src); + /* 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; - psout.type = QSE_AWK_PARSESTD_STR; - /* 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) + /* 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)); - ret = -1; goto oops; + goto oops; } - qse_printf (QSE_T("DEPARSED SOURCE:\n%s\n"), psout.u.str.ptr); - qse_printf (QSE_T("=================================\n")); - qse_fflush (QSE_STDOUT); - - QSE_MMGR_FREE (qse_awk_getmmgr(awk), psout.u.str.ptr); - + /* open a runtime context */ rtx = qse_awk_rtx_openstd ( awk, 0, - QSE_T("awk02"), - QSE_NULL, /* stdin */ - QSE_NULL, /* stdout */ - QSE_NULL /* default cmgr */ + 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)); - ret = -1; goto oops; + 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)); - ret = -1; goto oops; + goto oops; } + /* decrement the reference count of the return value */ 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); - return -1; -} + /* 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; +} diff --git a/qse/samples/awk/awk03.c b/qse/samples/awk/awk03.c index 1e430746..ab259b18 100644 --- a/qse/samples/awk/awk03.c +++ b/qse/samples/awk/awk03.c @@ -43,7 +43,7 @@ int main () qse_awk_t* awk = QSE_NULL; qse_awk_rtx_t* rtx = QSE_NULL; - qse_awk_parsestd_t psin; + qse_awk_parsestd_t psin[2]; int ret, i, opt; @@ -60,11 +60,12 @@ int main () opt &= ~QSE_AWK_PABLOCK; qse_awk_setopt (awk, QSE_AWK_TRAIT, &opt); - psin.type = QSE_AWK_PARSESTD_STR; - psin.u.str.ptr = src; - psin.u.str.len = qse_strlen(src); + 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; - ret = qse_awk_parsestd (awk, &psin, QSE_NULL); + ret = qse_awk_parsestd (awk, psin, QSE_NULL); if (ret == -1) { qse_fprintf (QSE_STDERR, QSE_T("error: %s\n"), diff --git a/qse/samples/awk/awk04.c b/qse/samples/awk/awk04.c index fcbdcaf8..6748836e 100644 --- a/qse/samples/awk/awk04.c +++ b/qse/samples/awk/awk04.c @@ -30,7 +30,7 @@ int main () { qse_awk_t* awk = QSE_NULL; qse_awk_rtx_t* rtx = QSE_NULL; - qse_awk_parsestd_t psin; + qse_awk_parsestd_t psin[2]; qse_char_t* str; qse_size_t len; qse_awk_val_t* rtv = QSE_NULL; @@ -56,11 +56,12 @@ int main () qse_awk_setopt (awk, QSE_AWK_TRAIT, &opt); - psin.type = QSE_AWK_PARSESTD_STR; - psin.u.str.ptr = src; - psin.u.str.len = qse_strlen(src); + 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; - ret = qse_awk_parsestd (awk, &psin, QSE_NULL); + ret = qse_awk_parsestd (awk, psin, QSE_NULL); if (ret == -1) { qse_fprintf (QSE_STDERR, QSE_T("error: %s\n"), diff --git a/qse/samples/awk/awk09.c b/qse/samples/awk/awk09.c index 1d31a75d..f9645ad7 100644 --- a/qse/samples/awk/awk09.c +++ b/qse/samples/awk/awk09.c @@ -40,7 +40,7 @@ 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; + qse_awk_parsestd_t psin[2]; int ret = -1, opt; const qse_char_t* output_files[] = @@ -67,11 +67,12 @@ int main () opt |= QSE_AWK_EXTRAKWS; qse_awk_setopt (awk, QSE_AWK_TRAIT, &opt); - psin.type = QSE_AWK_PARSESTD_STR; - psin.u.str.ptr = src; - psin.u.str.len = qse_strlen(src); + 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) + if (qse_awk_parsestd (awk, psin, QSE_NULL) <= -1) { qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk)); diff --git a/qse/samples/awk/awk10.c b/qse/samples/awk/awk10.c index c418b96e..1c208553 100644 --- a/qse/samples/awk/awk10.c +++ b/qse/samples/awk/awk10.c @@ -18,7 +18,6 @@ License along with QSE. If not, see . */ -#include #include #include @@ -30,7 +29,7 @@ int main () { qse_awk_t* awk = QSE_NULL; qse_awk_rtx_t* rtx = QSE_NULL; - qse_awk_parsestd_t psin; + qse_awk_parsestd_t psin[2]; qse_awk_val_t* rtv = QSE_NULL; qse_awk_val_t* arg = QSE_NULL; int ret, i, opt; @@ -61,11 +60,12 @@ int main () opt |= QSE_AWK_FLEXMAP; qse_awk_setopt (awk, QSE_AWK_TRAIT, &opt); - psin.type = QSE_AWK_PARSESTD_STR; - psin.u.str.ptr = src; - psin.u.str.len = qse_strlen(src); + 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; - ret = qse_awk_parsestd (awk, &psin, QSE_NULL); + ret = qse_awk_parsestd (awk, psin, QSE_NULL); if (ret == -1) { qse_fprintf (QSE_STDERR, QSE_T("error: %s\n"), diff --git a/qse/samples/awk/awk11.c b/qse/samples/awk/awk11.c index 42d467c4..c1508c20 100644 --- a/qse/samples/awk/awk11.c +++ b/qse/samples/awk/awk11.c @@ -69,7 +69,7 @@ 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; + qse_awk_parsestd_t psin[2]; int ret = -1; awk = qse_awk_openstd (0); @@ -79,11 +79,12 @@ int main () goto oops; } - psin.type = QSE_AWK_PARSESTD_STR; - psin.u.str.ptr = src; - psin.u.str.len = qse_strlen(src); + 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) + if (qse_awk_parsestd (awk, psin, QSE_NULL) <= -1) { qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk)); diff --git a/qse/samples/awk/awk15.c b/qse/samples/awk/awk15.c new file mode 100644 index 00000000..88774e13 --- /dev/null +++ b/qse/samples/awk/awk15.c @@ -0,0 +1,109 @@ +/* + * $Id: awk02.c 441 2011-04-22 14:28:43Z hyunghwan.chung $ + * + Copyright 2006-2012 Chung, Hyung-Hwan. + This file is part of QSE. + + QSE is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + QSE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with QSE. If not, see . + */ + +#include +#include +#include +#include + +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 () +{ + 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; + + awk = qse_awk_openstd (0); + 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; + + psout.type = QSE_AWK_PARSESTD_STR; + /* 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%s\n"), psout.u.str.ptr); + qse_printf (QSE_T("=================================\n")); + qse_fflush (QSE_STDOUT); + + QSE_MMGR_FREE (qse_awk_getmmgr(awk), psout.u.str.ptr); + + rtx = qse_awk_rtx_openstd ( + awk, + 0, + QSE_T("awk02"), + 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); + return -1; +} +