diff --git a/qse/cmd/sed/sed.c b/qse/cmd/sed/sed.c index 187510d3..8e805902 100644 --- a/qse/cmd/sed/sed.c +++ b/qse/cmd/sed/sed.c @@ -212,8 +212,7 @@ static int add_script (const qse_char_t* str, int mem) else { g_script.io[g_script.size].type = QSE_SED_IOSTD_FILE; - g_script.io[g_script.size].u.file.path = - (qse_strcmp (str, QSE_T("-")) == 0)? QSE_NULL: str; + g_script.io[g_script.size].u.file.path = str; g_script.io[g_script.size].u.file.cmgr = g_script_cmgr; } g_script.size++; @@ -797,6 +796,8 @@ static int sed_main (int argc, qse_char_t* argv[]) qse_sed_iostd_t* output = QSE_NULL; int inpos; + /* a dash is treated specially for QSE_SED_IOSTD_FILE in + * qse_sed_execstd(). so make an exception here */ if (g_output_file && qse_strcmp (g_output_file, QSE_T("-")) != 0) { @@ -833,8 +834,7 @@ static int sed_main (int argc, qse_char_t* argv[]) qse_char_t* tmpl_tmpfile; in[0].type = QSE_SED_IOSTD_FILE; - in[0].u.file.path = - (qse_strcmp (xarg.ptr[inpos], QSE_T("-")) == 0)? QSE_NULL: xarg.ptr[inpos]; + in[0].u.file.path = xarg.ptr[inpos]; in[0].u.file.cmgr = g_infile_cmgr; in[1].type = QSE_SED_IOSTD_NULL; @@ -954,8 +954,7 @@ static int sed_main (int argc, qse_char_t* argv[]) { in[i].type = QSE_SED_IOSTD_FILE; tmp = xarg.ptr[i]; - in[i].u.file.path = - (qse_strcmp (tmp, QSE_T("-")) == 0)? QSE_NULL: tmp; + in[i].u.file.path = tmp; in[i].u.file.cmgr = g_infile_cmgr; } @@ -965,9 +964,7 @@ static int sed_main (int argc, qse_char_t* argv[]) if (g_output_file) { out.type = QSE_SED_IOSTD_FILE; - out.u.file.path = - (qse_strcmp (g_output_file, QSE_T("-")) == 0)? - QSE_NULL: g_output_file; + out.u.file.path = g_output_file; out.u.file.cmgr = g_outfile_cmgr; } else diff --git a/qse/doc/Doxyfile.in b/qse/doc/Doxyfile.in index dae97846..6c087b13 100644 --- a/qse/doc/Doxyfile.in +++ b/qse/doc/Doxyfile.in @@ -735,9 +735,7 @@ EXAMPLE_PATH = @top_srcdir@/samples \ # and *.h) to filter out the source-files in the directories. If left # blank all files are included. -EXAMPLE_PATTERNS = *.c \ - *.cpp \ - awk00.h +EXAMPLE_PATTERNS = *.c *.cpp awk00.h sed00.h # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be @@ -1554,6 +1552,7 @@ PREDEFINED = "QSE_BEGIN_NAMESPACE(x)=namespace x {" \ "QSE_SIZEOF_OFF_T=@QSE_SIZEOF_OFF_T@" \ "QSE_SIZEOF_OFF64_T=@QSE_SIZEOF_OFF64_T@" \ "QSE_EXPORT=" \ + "QSE_ENABLE_SEDTRACER=" \ "@CHAR_MODE@" # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then diff --git a/qse/doc/page/awk-embed.md b/qse/doc/page/awk-embed.md index a2421195..a2230296 100644 --- a/qse/doc/page/awk-embed.md +++ b/qse/doc/page/awk-embed.md @@ -221,3 +221,23 @@ the cmgr field moved from the union member file to the outer structure. ### 0 upon Opening ### I/O handlers can return 0 for success upon opening. + + + + + + +\skipline --------------------------------------------------------------------- +\skipline the sample files are listed here for example list generation purpose. +\skipline --------------------------------------------------------------------- +\example awk01.c +\example awk02.c +\example awk03.c +\example awk04.c +\example awk05.c +\example awk06.c +\example awk07.c +\example awk21.cpp +\example awk22.cpp +\example awk23.cpp + diff --git a/qse/doc/page/sed-embed.md b/qse/doc/page/sed-embed.md index bfdd5401..21850edd 100644 --- a/qse/doc/page/sed-embed.md +++ b/qse/doc/page/sed-embed.md @@ -27,14 +27,51 @@ You can call qse_sed_compstdfile() instead of qse_sed_compstdstr() to compile sed commands stored in a file. You can use qse_sed_compstd() or qse_sed_comp() for more flexibility. -Customize Console ------------------ +Locale +------ -Accessing Pattern Space ------------------------ +While QSESED can use a wide character type as the default character type, +the hosting program still has to initialize the locale whenever necessary. +All the samples shown in this page calls a common function +init_sed_sample_locale(), use the qse_main() macro as the main function, +and call qse_runmain() for cross-platform and cross-character-set support. -Accessing Hold Space --------------------- +Here is the function prototype. + + \includelineno sed00.h + +Here goes the actual function. + + \includelineno sed00.c + +Note that these two files do not constitute QSEAWK and are used for samples +here only. + +Customizing Streams +------------------- + +You can use qse_sed_execstd() in customzing the input and output streams. +The sample below uses I/O resources of the #QSE_SED_IOSTD_STR type to use +an argument as input data and let the output to be dynamically allocated. + + \includelineno sed02.c + +You can use the core layer function qse_sed_exec() and implement the +::qse_sed_io_impl_t interface for more flexibility. No samples will +be provided here because the standard layer functions qse_sed_execstd() +and qse_sed_execstdfile() are the good samples. + +Accessing Pattern and Hold Space +-------------------------------- + +The qse_sed_getspace() allows to you get the pointer and the length +of the pattern space and the hold space. It may not be so useful you +access them after execution is completed. The qse_sed_setexectracer() +function lets you set up a hook function during execution time. +The following sample prints the contents of the pattern space and +hold space at each phase of execution. + + \includelineno sed03.c Embedding In C++ ---------------- @@ -42,5 +79,15 @@ Embedding In C++ The QSE::Sed and QSE::StdSed classes are provided for C++. The sample here shows how to embed QSE::StdSed for stream editing. - \includelineno sed02.cpp + \includelineno sed21.cpp + + + +\skipline --------------------------------------------------------------------- +\skipline the sample files are listed here for example list generation purpose. +\skipline --------------------------------------------------------------------- +\example sed01.c +\example sed02.c +\example sed03.c +\example sed21.cpp diff --git a/qse/include/qse/awk/std.h b/qse/include/qse/awk/std.h index 85643b86..c546f719 100644 --- a/qse/include/qse/awk/std.h +++ b/qse/include/qse/awk/std.h @@ -65,14 +65,20 @@ struct qse_awk_parsestd_t } file; /** + * input string or dynamically allocated output string + * * For input, the ptr and the len field of str indicates the - * pointer and the length of a string to read. + * pointer and the length of a string to read. You must set + * these fields before calling qse_awk_parsestd(). * * For output, the ptr and the len field of str indicates the * pointer and the length of a deparsed source string. The output - * string is dynamically allocated. You must free this output - * pointer using #QSE_MMGR_FREE once you're done with it to avoid - * memory leaks. + * string is dynamically allocated. You don't need to set these + * fields before calling qse_awk_parsestd() because they are set + * by qse_awk_parsestd() and valid while the relevant awk object + * is alive. You must free the memory chunk pointed to by the + * ptr field with qse_awk_freemem() once you're done with it to + * avoid memory leaks. */ qse_xstr_t str; } u; diff --git a/qse/include/qse/sed/Sed.hpp b/qse/include/qse/sed/Sed.hpp index 7521e0a9..4888bb1f 100644 --- a/qse/include/qse/sed/Sed.hpp +++ b/qse/include/qse/sed/Sed.hpp @@ -34,9 +34,9 @@ QSE_BEGIN_NAMESPACE(QSE) ///////////////////////////////// -/** - * The Sed class implements a stream editor by wrapping around #qse_sed_t. - */ +/// +/// The Sed class implements a stream editor by wrapping around #qse_sed_t. +/// class QSE_EXPORT Sed: public Mmged { public: @@ -60,7 +60,7 @@ public: #endif /// - /// The Stream class is a base class for I/O operation during + /// The Stream class is a abstract class for I/O operation during /// execution. /// class QSE_EXPORT Stream: public Types diff --git a/qse/include/qse/sed/StdSed.hpp b/qse/include/qse/sed/StdSed.hpp index 2e6d0164..38e8a147 100644 --- a/qse/include/qse/sed/StdSed.hpp +++ b/qse/include/qse/sed/StdSed.hpp @@ -34,16 +34,19 @@ QSE_BEGIN_NAMESPACE(QSE) ///////////////////////////////// -/** - * The StdSed class inherits the Sed class, implements a standard - * I/O stream class, and sets the default memory manager. - * - */ +/// +/// The StdSed class inherits the Sed class, implements a standard +/// I/O stream class, and sets the default memory manager. +/// class QSE_EXPORT StdSed: public Sed { public: StdSed (Mmgr* mmgr = StdMmgr::getDFL()): Sed (mmgr) {} + /// + /// The FileStream class implements a stream over input + /// and output files. + /// class QSE_EXPORT FileStream: public Stream { public: @@ -65,6 +68,9 @@ public: qse_cmgr_t* cmgr; }; + /// + /// The StringStream class implements a stream over a string + /// class QSE_EXPORT StringStream: public Stream { public: @@ -96,19 +102,6 @@ public: }; }; -/** - * @example sed02.cpp - * The example shows how to use the QSE::StdSed class to write a simple stream - * editor that reads from a standard input or a file and writes to a standard - * output or a file. - */ - -/** - * @example sed03.cpp - * The example shows how to extend the QSE::StdSed class to read from and - * write to a string. - */ - ///////////////////////////////// QSE_END_NAMESPACE(QSE) ///////////////////////////////// diff --git a/qse/include/qse/sed/sed.h b/qse/include/qse/sed/sed.h index 88ce7024..409531da 100644 --- a/qse/include/qse/sed/sed.h +++ b/qse/include/qse/sed/sed.h @@ -44,11 +44,6 @@ * */ -/** - * @example sed.c - * This example shows how to write a basic stream editor. - */ - /** @struct qse_sed_t * The qse_sed_t type defines a stream editor. The structural details are * hidden as it is a relatively complex data type and fragile to external @@ -388,6 +383,17 @@ typedef void (*qse_sed_exec_tracer_t) ( ); #endif +/** + * The qse_sed_space_t type defines the types of + * sed bufferspaces. + */ +enum qse_sed_space_t +{ + QSE_SED_SPACE_HOLD, /**< hold space */ + QSE_SED_SPACE_PATTERN /**< pattern space */ +}; +typedef enum qse_sed_space_t qse_sed_space_t; + #ifdef __cplusplus extern "C" { #endif @@ -653,6 +659,44 @@ QSE_EXPORT void qse_sed_setlinenum ( qse_size_t num /**< a line number */ ); + +/** + * The qse_sed_allocmem() function allocates a chunk of memory using + * the memory manager of \a sed. + */ +QSE_EXPORT void* qse_sed_allocmem ( + qse_sed_t* sed, + qse_size_t size +); + +/** + * The qse_sed_allocmem() function allocates a chunk of memory using + * the memory manager of \a sed and clears it to zeros. + */ +QSE_EXPORT void* qse_sed_callocmem ( + qse_sed_t* sed, + qse_size_t size +); + +/** + * The qse_sed_allocmem() function reallocates a chunk of memory using + * the memory manager of \a sed. + */ +QSE_EXPORT void* qse_sed_reallocmem ( + qse_sed_t* sed, + void* ptr, + qse_size_t size +); + +/** + * The qse_sed_allocmem() function frees a chunk of memory using + * the memory manager of \a sed. + */ +QSE_EXPORT void qse_sed_freemem ( + qse_sed_t* sed, + void* ptr +); + #ifdef QSE_ENABLE_SEDTRACER /** * The qse_sed_getexectracer() function returns the execution tracer @@ -663,7 +707,7 @@ QSE_EXPORT qse_sed_exec_tracer_t qse_sed_getexectracer ( ); /** - * The qse_sed_getexectracer() function sets a hook function via which + * The qse_sed_setexectracer() function sets a hook function via which * you can trace commands being executed. */ QSE_EXPORT void qse_sed_setexectracer ( @@ -672,6 +716,16 @@ QSE_EXPORT void qse_sed_setexectracer ( ); #endif +/** + * The qse_sed_getspace() function gets the pointer and the length + * to a buffer space specfied by \a space. + */ +QSE_EXPORT void qse_sed_getspace ( + qse_sed_t* sed, + qse_sed_space_t space, + qse_cstr_t* str +); + #ifdef __cplusplus } #endif diff --git a/qse/include/qse/sed/std.h b/qse/include/qse/sed/std.h index 4ef2b110..61874fd9 100644 --- a/qse/include/qse/sed/std.h +++ b/qse/include/qse/sed/std.h @@ -30,10 +30,6 @@ * you can choose to use the helper functions provided here. It is * a higher-level interface that is easier to use as it implements * default handlers for I/O and memory management. - * - * @example sed01.c - * This example shows how to write a simple stream editor using easy API - * functions. */ /** @@ -54,17 +50,43 @@ typedef enum qse_sed_iostd_type_t qse_sed_iostd_type_t; */ struct qse_sed_iostd_t { - qse_sed_iostd_type_t type; /**< resource type */ + /** resource type */ + qse_sed_iostd_type_t type; + + /** union describing the resource of the specified type */ union { + /** file path with character encoding */ struct { - const qse_char_t* path; /**< file path */ - qse_cmgr_t* cmgr; /**< cmgr for the file */ + /** file path to open. #QSE_NULL or '-' for stdin/stdout. */ + const qse_char_t* path; + /** a stream created with the file path is set with this + * cmgr if it is not #QSE_NULL. */ + qse_cmgr_t* cmgr; } file; + + /** + * input string or dynamically allocated output string + * + * For input, the ptr and the len field of str indicates the + * pointer and the length of a string to read. You must set + * these two fields before calling qse_sed_execstd(). + * + * For output, the ptr and the len field of str indicates the + * pointer and the length of produced output. The output + * string is dynamically allocated. You don't need to set these + * fields before calling qse_sed_execstd() because they are + * set by qse_sed_execstd() and valid while the relevant sed + * object is alive. You must free the memory chunk pointed to by + * the ptr field with qse_sed_freemem() once you're done with it + * to avoid memory leaks. + */ qse_xstr_t str; + + /** pre-opened sio stream */ qse_sio_t* sio; - } u; /**< union containing data for each type */ + } u; }; typedef struct qse_sed_iostd_t qse_sed_iostd_t; diff --git a/qse/lib/awk/StdAwk.cpp b/qse/lib/awk/StdAwk.cpp index f95c4779..81387156 100644 --- a/qse/lib/awk/StdAwk.cpp +++ b/qse/lib/awk/StdAwk.cpp @@ -857,7 +857,7 @@ int StdAwk::open_console_in (Console& io) qse_char_t ibuf[128]; qse_size_t ibuflen; qse_awk_val_t* v; - qse_awk_rtx_valtostr_out_t out; + qse_xstr_t as; nextfile: file = this->runarg.ptr[this->runarg_index].ptr; @@ -928,29 +928,29 @@ int StdAwk::open_console_in (Console& io) v = (qse_awk_val_t*)QSE_HTB_VPTR(pair); QSE_ASSERT (v != QSE_NULL); - out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP; - if (qse_awk_rtx_valtostr (rtx, v, &out) <= -1) return -1; + as.ptr = qse_awk_rtx_valtostrdup (rtx, v, &as.len); + if (as.ptr == QSE_NULL) return -1; - if (out.u.cpldup.len == 0) + if (as.len == 0) { /* the name is empty */ - qse_awk_rtx_freemem (rtx, out.u.cpldup.ptr); + qse_awk_rtx_freemem (rtx, as.ptr); this->runarg_index++; goto nextfile; } - if (qse_strlen(out.u.cpldup.ptr) < out.u.cpldup.len) + if (qse_strlen(as.ptr) < as.len) { /* the name contains one or more '\0' */ cstr_t arg; - arg.ptr = out.u.cpldup.ptr; - arg.len = qse_strlen (arg.ptr); + arg.ptr = as.ptr; + arg.len = qse_strlen (as.ptr); ((Run*)io)->setError (QSE_AWK_EIONMNL, &arg); - qse_awk_rtx_freemem (rtx, out.u.cpldup.ptr); + qse_awk_rtx_freemem (rtx, as.ptr); return -1; } - file = out.u.cpldup.ptr; + file = as.ptr; if (file[0] == QSE_T('-') && file[1] == QSE_T('\0')) sio = open_sio_std (QSE_NULL, io, QSE_SIO_STDIN, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR); @@ -958,19 +958,18 @@ int StdAwk::open_console_in (Console& io) sio = open_sio (QSE_NULL, io, file, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR); if (sio == QSE_NULL) { - qse_awk_rtx_freemem (rtx, out.u.cpldup.ptr); + qse_awk_rtx_freemem (rtx, as.ptr); return -1; } - if (qse_awk_rtx_setfilename ( - rtx, file, qse_strlen(file)) == -1) + if (qse_awk_rtx_setfilename (rtx, file, qse_strlen(file)) <= -1) { qse_sio_close (sio); - qse_awk_rtx_freemem (rtx, out.u.cpldup.ptr); + qse_awk_rtx_freemem (rtx, as.ptr); return -1; } - qse_awk_rtx_freemem (rtx, out.u.cpldup.ptr); + qse_awk_rtx_freemem (rtx, as.ptr); if (this->console_cmgr) qse_sio_setcmgr (sio, this->console_cmgr); diff --git a/qse/lib/awk/std.c b/qse/lib/awk/std.c index 99fa61a7..c7b0b67e 100644 --- a/qse/lib/awk/std.c +++ b/qse/lib/awk/std.c @@ -669,7 +669,7 @@ static int open_parsestd (qse_awk_t* awk, xtn_t* xtn, qse_size_t index) (psin->u.file.path[0] == QSE_T('-') && psin->u.file.path[1] == QSE_T('\0'))) { - /* special file name '-' */ + /* no path name or - -> stdin */ qse_sio_t* tmp; tmp = open_sio_std (awk, QSE_SIO_STDIN, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR); @@ -955,11 +955,12 @@ static qse_ssize_t sf_out ( switch (xtn->s.out.x->type) { case QSE_AWK_PARSESTD_FILE: - if (xtn->s.out.x->u.file.path == QSE_NULL || + if (xtn->s.out.x->u.file.path == QSE_NULL || (xtn->s.out.x->u.file.path[0] == QSE_T('-') && xtn->s.out.x->u.file.path[1] == QSE_T('\0'))) + { - /* special file name '-' */ + /* no path name or - -> stdout */ xtn->s.out.u.file.sio = open_sio_std ( awk, QSE_SIO_STDOUT, QSE_SIO_WRITE | QSE_SIO_IGNOREMBWCERR @@ -1510,7 +1511,7 @@ static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_rio_arg_t* riod) qse_char_t ibuf[128]; qse_size_t ibuflen; qse_awk_val_t* v; - qse_awk_rtx_valtostr_out_t out; + qse_xstr_t as; nextfile: file = rxtn->c.in.files[rxtn->c.in.index]; @@ -1568,35 +1569,34 @@ static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_rio_arg_t* riod) v = QSE_HTB_VPTR(pair); QSE_ASSERT (v != QSE_NULL); - out.type = QSE_AWK_RTX_VALTOSTR_CPLDUP; - if (qse_awk_rtx_valtostr (rtx, v, &out) <= -1) return -1; + as.ptr = qse_awk_rtx_valtostrdup (rtx, v, &as.len); + if (as.ptr == QSE_NULL) return -1; - if (out.u.cpldup.len == 0) + if (as.len == 0) { /* the name is empty */ - qse_awk_rtx_freemem (rtx, out.u.cpldup.ptr); + qse_awk_rtx_freemem (rtx, as.ptr); rxtn->c.in.index++; goto nextfile; } - if (qse_strlen(out.u.cpldup.ptr) < out.u.cpldup.len) + if (qse_strlen(as.ptr) < as.len) { /* the name contains one or more '\0' */ qse_cstr_t errarg; - errarg.ptr = out.u.cpldup.ptr; + errarg.ptr = as.ptr; /* use this length not to contains '\0' * in an error message */ - errarg.len = qse_strlen(out.u.cpldup.ptr); + errarg.len = qse_strlen(as.ptr); - qse_awk_rtx_seterrnum ( - rtx, QSE_AWK_EIONMNL, &errarg); + qse_awk_rtx_seterrnum (rtx, QSE_AWK_EIONMNL, &errarg); - qse_awk_rtx_freemem (rtx, out.u.cpldup.ptr); + qse_awk_rtx_freemem (rtx, as.ptr); return -1; } - file = out.u.cpldup.ptr; + file = as.ptr; sio = (file[0] == QSE_T('-') && file[1] == QSE_T('\0'))? open_sio_std_rtx (rtx, QSE_SIO_STDIN, @@ -1605,7 +1605,7 @@ static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_rio_arg_t* riod) QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR); if (sio == QSE_NULL) { - qse_awk_rtx_freemem (rtx, out.u.cpldup.ptr); + qse_awk_rtx_freemem (rtx, as.ptr); return -1; } @@ -1615,11 +1615,11 @@ static int open_rio_console (qse_awk_rtx_t* rtx, qse_awk_rio_arg_t* riod) rtx, file, qse_strlen(file)) <= -1) { qse_sio_close (sio); - qse_awk_rtx_freemem (rtx, out.u.cpldup.ptr); + qse_awk_rtx_freemem (rtx, as.ptr); return -1; } - qse_awk_rtx_freemem (rtx, out.u.cpldup.ptr); + qse_awk_rtx_freemem (rtx, as.ptr); riod->handle = sio; /* increment the counter of files successfully opened */ diff --git a/qse/lib/sed/StdSed.cpp b/qse/lib/sed/StdSed.cpp index 109ee700..50fb820c 100644 --- a/qse/lib/sed/StdSed.cpp +++ b/qse/lib/sed/StdSed.cpp @@ -78,17 +78,17 @@ int StdSed::FileStream::open (Data& io) if (ioname == QSE_NULL) { // - // a normal console is indicated by a null name + // a normal console is indicated by a null name or a dash // if (io.getMode() == READ) { - sio = (infile == QSE_NULL)? + sio = (infile == QSE_NULL || (infile[0] == QSE_T('-') && infile[1] == QSE_T('\0')))? open_sio_std (io, QSE_SIO_STDIN, oflags): open_sio (io, infile, oflags); } else { - sio = (outfile == QSE_NULL)? + sio = (outfile == QSE_NULL || (outfile[0] == QSE_T('-') && outfile[1] == QSE_T('\0')))? open_sio_std (io, QSE_SIO_STDOUT, oflags): open_sio (io, outfile, oflags); } diff --git a/qse/lib/sed/sed.c b/qse/lib/sed/sed.c index d91aa52e..0bc4a850 100644 --- a/qse/lib/sed/sed.c +++ b/qse/lib/sed/sed.c @@ -504,14 +504,9 @@ static int add_command_block (qse_sed_t* sed) { qse_sed_cmd_blk_t* b; - b = (qse_sed_cmd_blk_t*) QSE_MMGR_ALLOC (sed->mmgr, QSE_SIZEOF(*b)); - if (b == QSE_NULL) - { - SETERR0 (sed, QSE_SED_ENOMEM, QSE_NULL); - return -1; - } + b = (qse_sed_cmd_blk_t*) qse_sed_callocmem (sed, QSE_SIZEOF(*b)); + if (b == QSE_NULL) return -1; - QSE_MEMSET (b, 0, QSE_SIZEOF(*b)); b->next = QSE_NULL; b->len = 0; @@ -1513,14 +1508,9 @@ static int add_cut_selector_block (qse_sed_t* sed, qse_sed_cmd_t* cmd) { qse_sed_cut_sel_t* b; - b = (qse_sed_cut_sel_t*) QSE_MMGR_ALLOC (sed->mmgr, QSE_SIZEOF(*b)); - if (b == QSE_NULL) - { - SETERR0 (sed, QSE_SED_ENOMEM, QSE_NULL); - return -1; - } + b = (qse_sed_cut_sel_t*) qse_sed_callocmem (sed, QSE_SIZEOF(*b)); + if (b == QSE_NULL) return -1; - QSE_MEMSET (b, 0, QSE_SIZEOF(*b)); b->next = QSE_NULL; b->len = 0; @@ -3021,22 +3011,14 @@ static int split_into_fields_for_cut ( if (sed->e.cutf.flds == sed->e.cutf.sflds) { - tmp = QSE_MMGR_ALLOC (sed->mmgr, QSE_SIZEOF(*tmp) * nsz); - if (tmp == QSE_NULL) - { - SETERR0 (sed, QSE_SED_ENOMEM, QSE_NULL); - return -1; - } + tmp = qse_sed_allocmem (sed, QSE_SIZEOF(*tmp) * nsz); + if (tmp == QSE_NULL) return -1; QSE_MEMCPY (tmp, sed->e.cutf.flds, QSE_SIZEOF(*tmp) * sed->e.cutf.cflds); } else { - tmp = QSE_MMGR_REALLOC (sed->mmgr, sed->e.cutf.flds, QSE_SIZEOF(*tmp) * nsz); - if (tmp == QSE_NULL) - { - SETERR0 (sed, QSE_SED_ENOMEM, QSE_NULL); - return -1; - } + tmp = qse_sed_reallocmem (sed, sed->e.cutf.flds, QSE_SIZEOF(*tmp) * nsz); + if (tmp == QSE_NULL) return -1; } sed->e.cutf.flds = tmp; @@ -4131,6 +4113,35 @@ void qse_sed_pushecb (qse_sed_t* sed, qse_sed_ecb_t* ecb) sed->ecb = ecb; } +void* qse_sed_allocmem (qse_sed_t* sed, qse_size_t size) +{ + void* ptr = QSE_MMGR_ALLOC (sed->mmgr, size); + if (ptr == QSE_NULL) + qse_sed_seterrnum (sed, QSE_SED_ENOMEM, QSE_NULL); + return ptr; +} + +void* qse_sed_callocmem (qse_sed_t* sed, qse_size_t size) +{ + void* ptr = QSE_MMGR_ALLOC (sed->mmgr, size); + if (ptr) QSE_MEMSET (ptr, 0, size); + else qse_sed_seterrnum (sed, QSE_SED_ENOMEM, QSE_NULL); + return ptr; +} + +void* qse_sed_reallocmem (qse_sed_t* sed, void* ptr, qse_size_t size) +{ + void* nptr = QSE_MMGR_REALLOC (sed->mmgr, ptr, size); + if (nptr == QSE_NULL) qse_sed_seterrnum (sed, QSE_SED_ENOMEM, QSE_NULL); + return nptr; +} + +void qse_sed_freemem (qse_sed_t* sed, void* ptr) +{ + QSE_MMGR_FREE (sed->mmgr, ptr); +} + + #ifdef QSE_ENABLE_SEDTRACER qse_sed_exec_tracer_t qse_sed_getexectracer (qse_sed_t* sed) { @@ -4143,3 +4154,17 @@ void qse_sed_setexectracer (qse_sed_t* sed, qse_sed_exec_tracer_t tracer) } #endif +void qse_sed_getspace (qse_sed_t* sed, qse_sed_space_t space, qse_cstr_t* str) +{ + switch (space) + { + case QSE_SED_SPACE_HOLD: + str->ptr = QSE_STR_PTR(&sed->e.txt.hold); + str->len = QSE_STR_LEN(&sed->e.txt.hold); + break; + case QSE_SED_SPACE_PATTERN: + str->ptr = QSE_STR_PTR(&sed->e.in.line); + str->len = QSE_STR_LEN(&sed->e.in.line); + break; + } +} diff --git a/qse/lib/sed/sed.h b/qse/lib/sed/sed.h index aaa9ba87..1f0da8db 100644 --- a/qse/lib/sed/sed.h +++ b/qse/lib/sed/sed.h @@ -174,10 +174,10 @@ struct qse_sed_t /** data needed for input streams */ struct { - qse_sed_io_impl_t fun; /**< an input handler */ + qse_sed_io_impl_t fun; /**< input handler */ qse_sed_io_arg_t arg; /**< input handling data */ - qse_char_t xbuf[1]; /**< a read-ahead buffer */ + qse_char_t xbuf[1]; /**< read-ahead buffer */ int xbuf_len; /**< data length in the buffer */ qse_char_t buf[2048]; /**< input buffer */ @@ -199,6 +199,7 @@ struct qse_sed_t qse_sed_app_t* tail; } d; } append; + /** text buffers */ struct { diff --git a/qse/lib/sed/std.c b/qse/lib/sed/std.c index 0d8eae5e..20d478c4 100644 --- a/qse/lib/sed/std.c +++ b/qse/lib/sed/std.c @@ -216,9 +216,22 @@ static int open_input_stream ( case QSE_SED_IOSTD_FILE: { qse_sio_t* sio; - sio = (io->u.file.path == QSE_NULL)? - open_sio_std (sed, QSE_SIO_STDIN, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR): - open_sio_file (sed, io->u.file.path, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR); + + if (io->u.file.path == QSE_NULL || + (io->u.file.path[0] == QSE_T('-') && + io->u.file.path[1] == QSE_T('\0'))) + { + sio = open_sio_std ( + sed, QSE_SIO_STDIN, + QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR + ); + } + else + { + sio = open_sio_file ( + sed, io->u.file.path, + QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR); + } if (sio == QSE_NULL) return -1; if (io->u.file.cmgr) qse_sio_setcmgr (sio, io->u.file.cmgr); arg->handle = sio; @@ -284,7 +297,9 @@ static int open_output_stream (qse_sed_t* sed, qse_sed_io_arg_t* arg, qse_sed_io case QSE_SED_IOSTD_FILE: { qse_sio_t* sio; - if (io->u.file.path == QSE_NULL) + if (io->u.file.path == QSE_NULL || + (io->u.file.path[0] == QSE_T('-') && + io->u.file.path[1] == QSE_T('\0'))) { sio = open_sio_std ( sed, QSE_SIO_STDOUT, @@ -512,6 +527,7 @@ static qse_ssize_t x_in ( /* no file specified. console stream */ if (xtn->e.in.ptr == QSE_NULL) { + /* QSE_NULL passed into qse_sed_exec() for input */ sio = open_sio_std ( sed, QSE_SIO_STDIN, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR); if (sio == QSE_NULL) return -1; @@ -609,8 +625,11 @@ static qse_ssize_t x_out ( { if (arg->path == QSE_NULL) { + /* main data stream */ + if (xtn->e.out.ptr == QSE_NULL) { + /* QSE_NULL passed into qse_sed_execstd() for output */ sio = open_sio_std ( sed, QSE_SIO_STDOUT, QSE_SIO_WRITE | @@ -628,6 +647,7 @@ static qse_ssize_t x_out ( } else { + sio = open_sio_file ( sed, arg->path, QSE_SIO_WRITE | @@ -785,7 +805,7 @@ int qse_sed_execstd ( QSE_MEMSET (&xtn->e, 0, QSE_SIZEOF(xtn->e)); xtn->e.in.ptr = in; xtn->e.in.cur = in; - xtn->e.out.ptr= out; + xtn->e.out.ptr = out; n = qse_sed_exec (sed, x_in, x_out); diff --git a/qse/samples/sed/Makefile.am b/qse/samples/sed/Makefile.am index ede8e625..6a534e89 100644 --- a/qse/samples/sed/Makefile.am +++ b/qse/samples/sed/Makefile.am @@ -15,20 +15,27 @@ LDADD += $(UNICOWS_LIBS) endif endif -bin_PROGRAMS = sed01 +CMNFILES = sed00.c sed00.h +bin_PROGRAMS = sed01 sed02 sed03 -sed01_SOURCES = sed01.c +sed01_SOURCES = sed01.c $(CMNFILES) sed01_LDADD = $(LDADD) +sed02_SOURCES = sed02.c $(CMNFILES) +sed02_LDADD = $(LDADD) + +sed03_SOURCES = sed03.c $(CMNFILES) +sed03_LDADD = $(LDADD) + if ENABLE_CXX CXXLIB = -lqsesedxx -lqsecmnxx bin_PROGRAMS += sed21 sed22 -sed21_SOURCES = sed21.cpp +sed21_SOURCES = sed21.cpp $(CMNFILES) sed21_LDADD = $(CXXLIB) $(LDADD) -sed22_SOURCES = sed22.cpp +sed22_SOURCES = sed22.cpp $(CMNFILES) sed22_LDADD = $(CXXLIB) $(LDADD) endif diff --git a/qse/samples/sed/Makefile.in b/qse/samples/sed/Makefile.in index 7e99d86e..b26f555b 100644 --- a/qse/samples/sed/Makefile.in +++ b/qse/samples/sed/Makefile.in @@ -35,7 +35,8 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @WCHAR_TRUE@@WIN32_TRUE@am__append_1 = $(UNICOWS_LIBS) -bin_PROGRAMS = sed01$(EXEEXT) $(am__EXEEXT_1) +bin_PROGRAMS = sed01$(EXEEXT) sed02$(EXEEXT) sed03$(EXEEXT) \ + $(am__EXEEXT_1) @ENABLE_CXX_TRUE@am__append_2 = sed21 sed22 subdir = samples/sed DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in @@ -55,19 +56,26 @@ CONFIG_CLEAN_VPATH_FILES = @ENABLE_CXX_TRUE@am__EXEEXT_1 = sed21$(EXEEXT) sed22$(EXEEXT) am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) -am_sed01_OBJECTS = sed01.$(OBJEXT) +am__objects_1 = sed00.$(OBJEXT) +am_sed01_OBJECTS = sed01.$(OBJEXT) $(am__objects_1) sed01_OBJECTS = $(am_sed01_OBJECTS) am__DEPENDENCIES_1 = @WCHAR_TRUE@@WIN32_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) am__DEPENDENCIES_3 = $(am__DEPENDENCIES_2) sed01_DEPENDENCIES = $(am__DEPENDENCIES_3) -am__sed21_SOURCES_DIST = sed21.cpp -@ENABLE_CXX_TRUE@am_sed21_OBJECTS = sed21.$(OBJEXT) +am_sed02_OBJECTS = sed02.$(OBJEXT) $(am__objects_1) +sed02_OBJECTS = $(am_sed02_OBJECTS) +sed02_DEPENDENCIES = $(am__DEPENDENCIES_3) +am_sed03_OBJECTS = sed03.$(OBJEXT) $(am__objects_1) +sed03_OBJECTS = $(am_sed03_OBJECTS) +sed03_DEPENDENCIES = $(am__DEPENDENCIES_3) +am__sed21_SOURCES_DIST = sed21.cpp sed00.c sed00.h +@ENABLE_CXX_TRUE@am_sed21_OBJECTS = sed21.$(OBJEXT) $(am__objects_1) sed21_OBJECTS = $(am_sed21_OBJECTS) @ENABLE_CXX_TRUE@sed21_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @ENABLE_CXX_TRUE@ $(am__DEPENDENCIES_3) -am__sed22_SOURCES_DIST = sed22.cpp -@ENABLE_CXX_TRUE@am_sed22_OBJECTS = sed22.$(OBJEXT) +am__sed22_SOURCES_DIST = sed22.cpp sed00.c sed00.h +@ENABLE_CXX_TRUE@am_sed22_OBJECTS = sed22.$(OBJEXT) $(am__objects_1) sed22_OBJECTS = $(am_sed22_OBJECTS) @ENABLE_CXX_TRUE@sed22_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @ENABLE_CXX_TRUE@ $(am__DEPENDENCIES_3) @@ -93,9 +101,10 @@ CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ -SOURCES = $(sed01_SOURCES) $(sed21_SOURCES) $(sed22_SOURCES) -DIST_SOURCES = $(sed01_SOURCES) $(am__sed21_SOURCES_DIST) \ - $(am__sed22_SOURCES_DIST) +SOURCES = $(sed01_SOURCES) $(sed02_SOURCES) $(sed03_SOURCES) \ + $(sed21_SOURCES) $(sed22_SOURCES) +DIST_SOURCES = $(sed01_SOURCES) $(sed02_SOURCES) $(sed03_SOURCES) \ + $(am__sed21_SOURCES_DIST) $(am__sed22_SOURCES_DIST) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -279,12 +288,17 @@ AM_CPPFLAGS = \ -I$(includedir) LDADD = -lqsesed -lqsecmn $(am__append_1) -sed01_SOURCES = sed01.c +CMNFILES = sed00.c sed00.h +sed01_SOURCES = sed01.c $(CMNFILES) sed01_LDADD = $(LDADD) +sed02_SOURCES = sed02.c $(CMNFILES) +sed02_LDADD = $(LDADD) +sed03_SOURCES = sed03.c $(CMNFILES) +sed03_LDADD = $(LDADD) @ENABLE_CXX_TRUE@CXXLIB = -lqsesedxx -lqsecmnxx -@ENABLE_CXX_TRUE@sed21_SOURCES = sed21.cpp +@ENABLE_CXX_TRUE@sed21_SOURCES = sed21.cpp $(CMNFILES) @ENABLE_CXX_TRUE@sed21_LDADD = $(CXXLIB) $(LDADD) -@ENABLE_CXX_TRUE@sed22_SOURCES = sed22.cpp +@ENABLE_CXX_TRUE@sed22_SOURCES = sed22.cpp $(CMNFILES) @ENABLE_CXX_TRUE@sed22_LDADD = $(CXXLIB) $(LDADD) all: all-am @@ -366,6 +380,12 @@ clean-binPROGRAMS: sed01$(EXEEXT): $(sed01_OBJECTS) $(sed01_DEPENDENCIES) $(EXTRA_sed01_DEPENDENCIES) @rm -f sed01$(EXEEXT) $(LINK) $(sed01_OBJECTS) $(sed01_LDADD) $(LIBS) +sed02$(EXEEXT): $(sed02_OBJECTS) $(sed02_DEPENDENCIES) $(EXTRA_sed02_DEPENDENCIES) + @rm -f sed02$(EXEEXT) + $(LINK) $(sed02_OBJECTS) $(sed02_LDADD) $(LIBS) +sed03$(EXEEXT): $(sed03_OBJECTS) $(sed03_DEPENDENCIES) $(EXTRA_sed03_DEPENDENCIES) + @rm -f sed03$(EXEEXT) + $(LINK) $(sed03_OBJECTS) $(sed03_LDADD) $(LIBS) sed21$(EXEEXT): $(sed21_OBJECTS) $(sed21_DEPENDENCIES) $(EXTRA_sed21_DEPENDENCIES) @rm -f sed21$(EXEEXT) $(CXXLINK) $(sed21_OBJECTS) $(sed21_LDADD) $(LIBS) @@ -379,7 +399,10 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sed00.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sed01.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sed02.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sed03.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sed21.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sed22.Po@am__quote@ diff --git a/qse/samples/sed/sed00.c b/qse/samples/sed/sed00.c new file mode 100644 index 00000000..3f62c3d0 --- /dev/null +++ b/qse/samples/sed/sed00.c @@ -0,0 +1,31 @@ +/* sed00.c */ + +#include "sed00.h" +#include + +#include +#if defined(_WIN32) +# include +#endif + +void init_sed_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 + { + 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 +} diff --git a/qse/samples/sed/sed00.h b/qse/samples/sed/sed00.h new file mode 100644 index 00000000..13de9376 --- /dev/null +++ b/qse/samples/sed/sed00.h @@ -0,0 +1,16 @@ +/* sed00.h */ + +#ifndef _SED00_H_ +#define _SED00_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +void init_sed_sample_locale (void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/qse/samples/sed/sed01.c b/qse/samples/sed/sed01.c index 8069acd9..67044403 100644 --- a/qse/samples/sed/sed01.c +++ b/qse/samples/sed/sed01.c @@ -1,14 +1,9 @@ #include #include -#include #include +#include "sed00.h" -#include -#if defined(_WIN32) -# include -#endif - -int sed_main (int argc, qse_char_t* argv[]) +static int sed_main (int argc, qse_char_t* argv[]) { qse_sed_t* sed = QSE_NULL; qse_char_t* infile; @@ -21,6 +16,7 @@ int sed_main (int argc, qse_char_t* argv[]) return -1; } + /* create a sed object */ sed = qse_sed_openstd (0); if (sed == QSE_NULL) { @@ -28,6 +24,7 @@ int sed_main (int argc, qse_char_t* argv[]) goto oops; } + /* compile commands */ if (qse_sed_compstdstr (sed, argv[1]) <= -1) { qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_sed_geterrmsg(sed)); @@ -37,6 +34,7 @@ int sed_main (int argc, qse_char_t* argv[]) infile = (argc >= 3)? argv[2]: QSE_NULL; outfile = (argc >= 4)? argv[3]: QSE_NULL; + /* executes the compiled commands over the intput and output files specified */ if (qse_sed_execstdfile (sed, infile, outfile, QSE_NULL) <= -1) { qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_sed_geterrmsg(sed)); @@ -44,30 +42,14 @@ int sed_main (int argc, qse_char_t* argv[]) } oops: - if (sed != QSE_NULL) qse_sed_close (sed); + /* destroy the sed object */ + if (sed) qse_sed_close (sed); return ret; } int qse_main (int argc, qse_achar_t* argv[]) { -#if defined(_WIN32) - char locale[100]; - UINT codepage = GetConsoleOutputCP(); - if (codepage == CP_UTF8) - { - /*SetConsoleOutputCP (CP_UTF8);*/ - qse_setdflcmgrbyid (QSE_CMGR_UTF8); - } - else - { - sprintf (locale, ".%u", (unsigned int)codepage); - setlocale (LC_ALL, locale); - qse_setdflcmgrbyid (QSE_CMGR_SLMB); - } -#else - setlocale (LC_ALL, ""); - qse_setdflcmgrbyid (QSE_CMGR_SLMB); -#endif + init_sed_sample_locale (); return qse_runmain (argc, argv, sed_main); } diff --git a/qse/samples/sed/sed02.c b/qse/samples/sed/sed02.c new file mode 100644 index 00000000..230f88c4 --- /dev/null +++ b/qse/samples/sed/sed02.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include "sed00.h" + +static int sed_main (int argc, qse_char_t* argv[]) +{ + qse_sed_t* sed = QSE_NULL; + qse_sed_iostd_t in[2]; + qse_sed_iostd_t out; + int ret = -1; + + if (argc != 3) + { + qse_fprintf (QSE_STDERR, QSE_T("USAGE: %s command-string input-string\n"), argv[0]); + return -1; + } + + /* create the sed object */ + sed = qse_sed_openstd (0); + if (sed == QSE_NULL) + { + qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open sed\n")); + goto oops; + } + + /* compile the command string */ + if (qse_sed_compstdstr (sed, argv[1]) <= -1) + { + qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_sed_geterrmsg(sed)); + goto oops; + } + + /* arrange to use the second argument as input data */ + in[0].type = QSE_SED_IOSTD_STR; + in[0].u.str.ptr = argv[2]; + in[0].u.str.len = qse_strlen (argv[2]); + in[1].type = QSE_SED_IOSTD_NULL; + + /* indicate that the output should be placed in a + * dynamically allocated memory chunk */ + out.type = QSE_SED_IOSTD_STR; + + /* execute the compiled command */ + if (qse_sed_execstd (sed, in, &out) <= -1) + { + qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_sed_geterrmsg(sed)); + goto oops; + } + + /* access the output data produced */ + qse_printf (QSE_T("%.*s\n"), (int)out.u.str.len, out.u.str.ptr); + + /* free the output data */ + qse_sed_freemem (sed, out.u.str.ptr); + +oops: + /* destroy the sed object */ + if (sed) qse_sed_close (sed); + return ret; +} + +int qse_main (int argc, qse_achar_t* argv[]) +{ + init_sed_sample_locale (); + return qse_runmain (argc, argv, sed_main); +} + diff --git a/qse/samples/sed/sed03.c b/qse/samples/sed/sed03.c new file mode 100644 index 00000000..5daa0a8d --- /dev/null +++ b/qse/samples/sed/sed03.c @@ -0,0 +1,77 @@ +#include +#include +#include +#include "sed00.h" + +static void trace_exec (qse_sed_t* sed, qse_sed_exec_op_t op, qse_sed_cmd_t* cmd) +{ + qse_cstr_t h, p; + + qse_sed_getspace (sed, QSE_SED_SPACE_HOLD, &h); + qse_sed_getspace (sed, QSE_SED_SPACE_PATTERN, &p); + + /* print the contents of the hold space and the pattern space + * at each phase of execution */ + qse_printf (QSE_T("HOLD: [%.*s] PATTERN: [%.*s]\n"), (int)h.len, h.ptr, (int)p.len, p.ptr); +} + +static int sed_main (int argc, qse_char_t* argv[]) +{ + qse_sed_t* sed = QSE_NULL; + qse_sed_iostd_t in[2]; + qse_sed_iostd_t out; + int ret = -1; + + /* create the sed object */ + sed = qse_sed_openstd (0); + if (sed == QSE_NULL) + { + qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open sed\n")); + goto oops; + } + + /* compile the command string */ + if (qse_sed_compstdstr (sed, QSE_T("s/abc/def/g; s/def/kkk/g")) <= -1) + { + qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_sed_geterrmsg(sed)); + goto oops; + } + + /* arrange to use the second argument as input data */ + in[0].type = QSE_SED_IOSTD_STR; + in[0].u.str.ptr = QSE_T("ABCDEFGHI abcdefghi abcdefghi\nhigh abc dom\n"); + in[0].u.str.len = qse_strlen (in[0].u.str.ptr); + in[1].type = QSE_SED_IOSTD_NULL; + + /* indicate that the output should be placed in a + * dynamically allocated memory chunk */ + out.type = QSE_SED_IOSTD_STR; + + /* squeeze in a tracing hook */ + qse_sed_setexectracer (sed, trace_exec); + + /* execute the compiled command */ + if (qse_sed_execstd (sed, in, &out) <= -1) + { + qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_sed_geterrmsg(sed)); + goto oops; + } + + /* access the output data produced */ + qse_printf (QSE_T("%.*s\n"), (int)out.u.str.len, out.u.str.ptr); + + /* free the output data */ + qse_sed_freemem (sed, out.u.str.ptr); + +oops: + /* destroy the sed object */ + if (sed) qse_sed_close (sed); + return ret; +} + +int qse_main (int argc, qse_achar_t* argv[]) +{ + init_sed_sample_locale (); + return qse_runmain (argc, argv, sed_main); +} + diff --git a/qse/samples/sed/sed21.cpp b/qse/samples/sed/sed21.cpp index 995b0527..e28bb739 100644 --- a/qse/samples/sed/sed21.cpp +++ b/qse/samples/sed/sed21.cpp @@ -1,16 +1,9 @@ #include #include -#include #include +#include "sed00.h" -#include -#if defined(_WIN32) -# include -# include -#endif - - -#ifdef QSE_CHAR_IS_MCHAR +#if defined(QSE_CHAR_IS_MCHAR) # define xcout std::cout #else # define xcout std::wcout @@ -27,7 +20,7 @@ int sed_main (int argc, qse_char_t* argv[]) QSE::StdSed sed; - if (sed.open () == -1) + if (sed.open () <= -1) { xcout << QSE_T("ERR: cannot open") << std::endl; return -1; @@ -35,7 +28,7 @@ int sed_main (int argc, qse_char_t* argv[]) QSE::StdSed::StringStream sstream (argv[1]); - if (sed.compile (sstream) == -1) + if (sed.compile (sstream) <= -1) { xcout << QSE_T("ERR: cannot compile - ") << sed.getErrorMessage() << std::endl; sed.close (); @@ -46,7 +39,7 @@ int sed_main (int argc, qse_char_t* argv[]) qse_char_t* outfile = (argc >= 4)? argv[3]: QSE_NULL; QSE::StdSed::FileStream fstream (infile, outfile); - if (sed.execute (fstream) == -1) + if (sed.execute (fstream) <= -1) { xcout << QSE_T("ERR: cannot execute - ") << sed.getErrorMessage() << std::endl; sed.close (); @@ -59,23 +52,6 @@ int sed_main (int argc, qse_char_t* argv[]) int qse_main (int argc, qse_achar_t* argv[]) { -#if defined(_WIN32) - char locale[100]; - UINT codepage = GetConsoleOutputCP(); - if (codepage == CP_UTF8) - { - /*SetConsoleOUtputCP (CP_UTF8);*/ - qse_setdflcmgrbyid (QSE_CMGR_UTF8); - } - else - { - sprintf (locale, ".%u", (unsigned int)codepage); - setlocale (LC_ALL, locale); - qse_setdflcmgrbyid (QSE_CMGR_SLMB); - } -#else - setlocale (LC_ALL, ""); - qse_setdflcmgrbyid (QSE_CMGR_SLMB); -#endif + init_sed_sample_locale (); return qse_runmain (argc, argv, sed_main); } diff --git a/qse/samples/sed/sed22.cpp b/qse/samples/sed/sed22.cpp index 60d645a4..d831b4b0 100644 --- a/qse/samples/sed/sed22.cpp +++ b/qse/samples/sed/sed22.cpp @@ -1,37 +1,10 @@ -/** - * $Id$ - * - Copyright 2006-2012 Chung, Hyung-Hwan. - This file is part of QSE. - - QSE is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - QSE is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with QSE. If not, see . - */ - #include #include -#include #include #include +#include "sed00.h" -#include -#if defined(_WIN32) -# include -# include -#endif - - -#ifdef QSE_CHAR_IS_MCHAR +#if defined(QSE_CHAR_IS_MCHAR) # define xcout std::cout #else # define xcout std::wcout @@ -94,23 +67,6 @@ int sed_main (int argc, qse_char_t* argv[]) int qse_main (int argc, qse_achar_t* argv[]) { -#if defined(_WIN32) - char locale[100]; - UINT codepage = GetConsoleOutputCP(); - if (codepage == CP_UTF8) - { - /*SetConsoleOUtputCP (CP_UTF8);*/ - qse_setdflcmgrbyid (QSE_CMGR_UTF8); - } - else - { - sprintf (locale, ".%u", (unsigned int)codepage); - setlocale (LC_ALL, locale); - qse_setdflcmgrbyid (QSE_CMGR_SLMB); - } -#else - setlocale (LC_ALL, ""); - qse_setdflcmgrbyid (QSE_CMGR_SLMB); -#endif + init_sed_sample_locale (); return qse_runmain (argc, argv, sed_main); }