From a0faf15316355217c29fcafaf0a9b0a4d043e5d5 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Tue, 5 Jun 2012 07:45:52 +0000 Subject: [PATCH] added awk12.cpp that shows how to redefine a console handler to use string buffers for console I/O --- qse/include/qse/awk/StdAwk.hpp | 3 + qse/samples/awk/Makefile.am | 4 +- qse/samples/awk/Makefile.in | 19 ++- qse/samples/awk/awk05.cpp | 2 +- qse/samples/awk/awk12.cpp | 216 +++++++++++++++++++++++++++++++++ 5 files changed, 238 insertions(+), 6 deletions(-) create mode 100644 qse/samples/awk/awk12.cpp diff --git a/qse/include/qse/awk/StdAwk.hpp b/qse/include/qse/awk/StdAwk.hpp index ab14f604..020cf868 100644 --- a/qse/include/qse/awk/StdAwk.hpp +++ b/qse/include/qse/awk/StdAwk.hpp @@ -39,6 +39,9 @@ /// @example awk08.cpp /// This program shows how to add intrinsic functions. /// +/// @example awk12.cpp +/// This program shows how to override console methods to use a +/// string buffers for console input and output. ///////////////////////////////// QSE_BEGIN_NAMESPACE(QSE) diff --git a/qse/samples/awk/Makefile.am b/qse/samples/awk/Makefile.am index 82992d4b..8ea6dbf4 100644 --- a/qse/samples/awk/Makefile.am +++ b/qse/samples/awk/Makefile.am @@ -26,15 +26,17 @@ if ENABLE_CXX CXXLIB = -lqseawkxx -lqsecmnxx -bin_PROGRAMS += awk05 awk06 awk07 awk08 +bin_PROGRAMS += awk05 awk06 awk07 awk08 awk12 awk05_SOURCES = awk05.cpp awk06_SOURCES = awk06.cpp awk07_SOURCES = awk07.cpp awk08_SOURCES = awk08.cpp +awk12_SOURCES = awk12.cpp awk05_LDADD = $(CXXLIB) $(LDADD) awk06_LDADD = $(CXXLIB) $(LDADD) awk07_LDADD = $(CXXLIB) $(LDADD) awk08_LDADD = $(CXXLIB) $(LDADD) +awk12_LDADD = $(CXXLIB) $(LDADD) endif diff --git a/qse/samples/awk/Makefile.in b/qse/samples/awk/Makefile.in index a387a8a1..4e01dc1e 100644 --- a/qse/samples/awk/Makefile.in +++ b/qse/samples/awk/Makefile.in @@ -38,7 +38,7 @@ bin_PROGRAMS = awk01$(EXEEXT) awk02$(EXEEXT) awk03$(EXEEXT) \ awk04$(EXEEXT) awk09$(EXEEXT) awk10$(EXEEXT) awk11$(EXEEXT) \ $(am__EXEEXT_1) @WIN32_TRUE@am__append_1 = $(UNICOWS_LIBS) -@ENABLE_CXX_TRUE@am__append_2 = awk05 awk06 awk07 awk08 +@ENABLE_CXX_TRUE@am__append_2 = awk05 awk06 awk07 awk08 awk12 subdir = samples/awk DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -54,7 +54,7 @@ CONFIG_HEADER = $(top_builddir)/include/qse/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = @ENABLE_CXX_TRUE@am__EXEEXT_1 = awk05$(EXEEXT) awk06$(EXEEXT) \ -@ENABLE_CXX_TRUE@ awk07$(EXEEXT) awk08$(EXEEXT) +@ENABLE_CXX_TRUE@ awk07$(EXEEXT) awk08$(EXEEXT) awk12$(EXEEXT) am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_awk01_OBJECTS = awk01.$(OBJEXT) @@ -108,6 +108,11 @@ am_awk11_OBJECTS = awk11.$(OBJEXT) awk11_OBJECTS = $(am_awk11_OBJECTS) awk11_LDADD = $(LDADD) awk11_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) +am__awk12_SOURCES_DIST = awk12.cpp +@ENABLE_CXX_TRUE@am_awk12_OBJECTS = awk12.$(OBJEXT) +awk12_OBJECTS = $(am_awk12_OBJECTS) +@ENABLE_CXX_TRUE@awk12_DEPENDENCIES = $(am__DEPENDENCIES_1) \ +@ENABLE_CXX_TRUE@ $(am__DEPENDENCIES_3) DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/ac/depcomp am__depfiles_maybe = depfiles @@ -133,12 +138,12 @@ CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ SOURCES = $(awk01_SOURCES) $(awk02_SOURCES) $(awk03_SOURCES) \ $(awk04_SOURCES) $(awk05_SOURCES) $(awk06_SOURCES) \ $(awk07_SOURCES) $(awk08_SOURCES) $(awk09_SOURCES) \ - $(awk10_SOURCES) $(awk11_SOURCES) + $(awk10_SOURCES) $(awk11_SOURCES) $(awk12_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) + $(awk11_SOURCES) $(am__awk12_SOURCES_DIST) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -307,10 +312,12 @@ awk11_SOURCES = awk11.c @ENABLE_CXX_TRUE@awk06_SOURCES = awk06.cpp @ENABLE_CXX_TRUE@awk07_SOURCES = awk07.cpp @ENABLE_CXX_TRUE@awk08_SOURCES = awk08.cpp +@ENABLE_CXX_TRUE@awk12_SOURCES = awk12.cpp @ENABLE_CXX_TRUE@awk05_LDADD = $(CXXLIB) $(LDADD) @ENABLE_CXX_TRUE@awk06_LDADD = $(CXXLIB) $(LDADD) @ENABLE_CXX_TRUE@awk07_LDADD = $(CXXLIB) $(LDADD) @ENABLE_CXX_TRUE@awk08_LDADD = $(CXXLIB) $(LDADD) +@ENABLE_CXX_TRUE@awk12_LDADD = $(CXXLIB) $(LDADD) all: all-am .SUFFIXES: @@ -421,6 +428,9 @@ awk10$(EXEEXT): $(awk10_OBJECTS) $(awk10_DEPENDENCIES) awk11$(EXEEXT): $(awk11_OBJECTS) $(awk11_DEPENDENCIES) @rm -f awk11$(EXEEXT) $(LINK) $(awk11_OBJECTS) $(awk11_LDADD) $(LIBS) +awk12$(EXEEXT): $(awk12_OBJECTS) $(awk12_DEPENDENCIES) + @rm -f awk12$(EXEEXT) + $(CXXLINK) $(awk12_OBJECTS) $(awk12_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -439,6 +449,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk09.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk10.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk11.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/awk12.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< diff --git a/qse/samples/awk/awk05.cpp b/qse/samples/awk/awk05.cpp index d50d5100..9b680365 100644 --- a/qse/samples/awk/awk05.cpp +++ b/qse/samples/awk/awk05.cpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.cpp 341 2008-08-20 10:58:19Z baconevi $ + * $Id$ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. diff --git a/qse/samples/awk/awk12.cpp b/qse/samples/awk/awk12.cpp new file mode 100644 index 00000000..20c07014 --- /dev/null +++ b/qse/samples/awk/awk12.cpp @@ -0,0 +1,216 @@ +/* + * $Id$ + * + Copyright 2006-2011 Chung, Hyung-Hwan. + This file is part of QSE. + + QSE is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + QSE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with QSE. If not, see . + */ + +#include +#include +#include +#include +#include + +#include +#if defined(_WIN32) +# include +#endif + +#include +#if defined(QSE_CHAR_IS_WCHAR) +typedef std::wstring String; +#else +typedef std::string String; +#endif + +typedef QSE::StdAwk StdAwk; +typedef QSE::StdAwk::Run Run; +typedef QSE::StdAwk::Value Value; + +class 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 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 success. + return 0; + } + + ssize_t readConsole (Console& io, char_t* data, size_t size) + { + if (this->inptr >= this->inend) return 0; // EOF + size_t x = qse_strxncpy (data, size, inptr, inend - inptr); + this->inptr += x; + return x; + } + + ssize_t writeConsole (Console& io, const char_t* data, size_t size) + { + try { this->output.append (data, size); } + catch (...) + { + ((Run*)io)->setError (QSE_AWK_ENOMEM); + return -1; + } + 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("awk12")) <= -1) return -1; + + // prepare a script to print the second and the first column + MyAwk::SourceString in (QSE_T("{ print $2, $1; }")); + + // parse the script. + if (awk.parse (in, MyAwk::Source::NONE) == QSE_NULL) return -1; + MyAwk::Value r; + + awk.setInput (instr); // locate the input string + awk.clearOutput (); // clear the output string + int x = awk.loop (&r); // execute the BEGIN, pattern-action, END blocks. + + if (x >= 0) + { + qse_printf (QSE_T("%s"), awk.getOutput()); // print the console output + qse_printf (QSE_T("-----------------------------\n"), awk.getOutput()); + + // prepare a string to print lines with A in the fourth column + MyAwk::SourceString in2 (QSE_T("$4 == \"A\" { print $1; }")); + if (awk.parse (in2, MyAwk::Source::NONE) == QSE_NULL) return -1; + + awk.setInput (instr); + awk.clearOutput (); + + int x = awk.loop (&r); + + if (x >= 0) + { + qse_printf (QSE_T("%s"), awk.getOutput()); + qse_printf (QSE_T("-----------------------------\n"), awk.getOutput()); + } + } + + return x; +} + +static int awk_main (int argc, qse_char_t* argv[]) +{ + MyAwk awk; + + int ret = awk.open (); + if (ret >= 0) ret = run_awk (awk); + + if (ret <= -1) + { + MyAwk::loc_t loc = awk.getErrorLocation(); + print_error (loc, awk.getErrorMessage()); + } + + awk.close (); + return ret; +} + +int qse_main (int argc, qse_achar_t* argv[]) +{ +#if defined(_WIN32) + char locale[100]; + UINT codepage = GetConsoleOutputCP(); + if (codepage == CP_UTF8) + { + /*SetConsoleOUtputCP (CP_UTF8);*/ + qse_setdflcmgr (qse_utf8cmgr); + } + else + { + sprintf (locale, ".%u", (unsigned int)codepage); + setlocale (LC_ALL, locale); + qse_setdflcmgr (qse_slmbcmgr); + } +#else + setlocale (LC_ALL, ""); + qse_setdflcmgr (qse_slmbcmgr); +#endif + + return qse_runmain (argc,argv,awk_main); +}