changed qse_awk_parsestd_t and related code.

changed to use windows API for WIN32 in slmb.c
This commit is contained in:
hyung-hwan 2012-01-06 14:38:11 +00:00
parent 42431d2642
commit 70090bc117
22 changed files with 665 additions and 521 deletions

View File

@ -30,7 +30,6 @@
#include <qse/cmn/mbwc.h> #include <qse/cmn/mbwc.h>
#include <qse/cmn/xma.h> #include <qse/cmn/xma.h>
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>
#include <stdarg.h> #include <stdarg.h>
@ -69,7 +68,6 @@ struct arg_t
} isp; } isp;
qse_size_t isfl; /* the number of input source files */ qse_size_t isfl; /* the number of input source files */
qse_awk_parsestd_type_t ost; /* output source type */
qse_char_t* osf; /* output source file */ qse_char_t* osf; /* output source file */
qse_char_t** icf; /* input console files */ qse_char_t** icf; /* input console files */
@ -678,7 +676,7 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
} }
/* the source code is the string, not from the file */ /* the source code is the string, not from the file */
arg->ist = QSE_AWK_PARSESTD_CP; arg->ist = QSE_AWK_PARSESTD_STR;
arg->isp.str = argv[opt.ind++]; arg->isp.str = argv[opt.ind++];
free (isf); free (isf);
@ -714,7 +712,6 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
icf[icfl] = QSE_NULL; icf[icfl] = QSE_NULL;
} }
arg->ost = QSE_AWK_PARSESTD_FILE;
arg->osf = osf; arg->osf = osf;
arg->icf = icf; arg->icf = icf;
@ -855,8 +852,8 @@ static int awk_main (int argc, qse_char_t* argv[])
int ret = -1; int ret = -1;
/* TODO: change it to support multiple source files */ /* TODO: change it to support multiple source files */
qse_awk_parsestd_in_t psin; qse_awk_parsestd_t psin;
qse_awk_parsestd_out_t psout; qse_awk_parsestd_t psout;
qse_mmgr_t* mmgr = QSE_MMGR_GETDFL(); qse_mmgr_t* mmgr = QSE_MMGR_GETDFL();
memset (&arg, 0, QSE_SIZEOF(arg)); memset (&arg, 0, QSE_SIZEOF(arg));
@ -869,13 +866,22 @@ static int awk_main (int argc, qse_char_t* argv[])
} }
psin.type = arg.ist; psin.type = arg.ist;
if (arg.ist == QSE_AWK_PARSESTD_CP) psin.u.cp = arg.isp.str; if (arg.ist == QSE_AWK_PARSESTD_STR)
else psin.u.file = arg.isp.files[0]; {
psin.u.str.ptr = arg.isp.str;
psin.u.str.len = qse_strlen(arg.isp.str);
}
else
{
psin.u.file.path = arg.isp.files[0];
psin.u.file.cmgr = QSE_NULL;
}
if (arg.osf != QSE_NULL) if (arg.osf != QSE_NULL)
{ {
psout.type = arg.ost; psout.type = QSE_AWK_PARSESTD_FILE;
psout.u.file = arg.osf; psout.u.file.path = arg.osf;
psout.u.file.cmgr = QSE_NULL;
} }
#if defined(QSE_BUILD_DEBUG) #if defined(QSE_BUILD_DEBUG)

View File

@ -184,17 +184,18 @@ static int add_script (const qse_char_t* str, int mem)
if (mem) if (mem)
{ {
g_script.io[g_script.size].type = QSE_SED_IOSTD_MEM; g_script.io[g_script.size].type = QSE_SED_IOSTD_STR;
/* though its type is not qualified to be const, /* though its type is not qualified to be const,
* u.mem.ptr is actually const when used for input */ * u.mem.ptr is actually const when used for input */
g_script.io[g_script.size].u.mem.ptr = (qse_char_t*)str; g_script.io[g_script.size].u.str.ptr = (qse_char_t*)str;
g_script.io[g_script.size].u.mem.len = qse_strlen(str); g_script.io[g_script.size].u.str.len = qse_strlen(str);
} }
else else
{ {
g_script.io[g_script.size].type = QSE_SED_IOSTD_FILE; g_script.io[g_script.size].type = QSE_SED_IOSTD_FILE;
g_script.io[g_script.size].u.file = g_script.io[g_script.size].u.file.path =
(qse_strcmp (str, QSE_T("-")) == 0)? QSE_NULL: str; (qse_strcmp (str, QSE_T("-")) == 0)? QSE_NULL: str;
g_script.io[g_script.size].u.file.cmgr = QSE_NULL;
} }
g_script.size++; g_script.size++;
return 0; return 0;
@ -589,12 +590,12 @@ int sed_main (int argc, qse_char_t* argv[])
if (g_script.io[script_count].type == QSE_SED_IOSTD_FILE) if (g_script.io[script_count].type == QSE_SED_IOSTD_FILE)
{ {
target = g_script.io[script_count].u.file; target = g_script.io[script_count].u.file.path;
} }
else else
{ {
/* i dont' use QSE_SED_IOSTD_SIO for input */ /* i dont' use QSE_SED_IOSTD_SIO for input */
QSE_ASSERT (g_script.io[script_count].type == QSE_SED_IOSTD_MEM); QSE_ASSERT (g_script.io[script_count].type == QSE_SED_IOSTD_STR);
qse_sprintf (exprbuf, QSE_COUNTOF(exprbuf), qse_sprintf (exprbuf, QSE_COUNTOF(exprbuf),
QSE_T("expression #%lu"), (unsigned long)script_count); QSE_T("expression #%lu"), (unsigned long)script_count);
target = exprbuf; target = exprbuf;
@ -663,15 +664,16 @@ int sed_main (int argc, qse_char_t* argv[])
qse_char_t* tmpl_tmpfile; qse_char_t* tmpl_tmpfile;
in[0].type = QSE_SED_IOSTD_FILE; in[0].type = QSE_SED_IOSTD_FILE;
in[0].u.file = in[0].u.file.path =
(qse_strcmp (argv[g_infile_pos], QSE_T("-")) == 0)? (qse_strcmp (argv[g_infile_pos], QSE_T("-")) == 0)?
QSE_NULL: argv[g_infile_pos]; QSE_NULL: argv[g_infile_pos];
in[0].u.file.cmgr = QSE_NULL;
in[1].type = QSE_SED_IOSTD_NULL; in[1].type = QSE_SED_IOSTD_NULL;
tmpl_tmpfile = QSE_NULL; tmpl_tmpfile = QSE_NULL;
if (g_inplace && in[0].u.file) if (g_inplace && in[0].u.file.path)
{ {
tmpl_tmpfile = qse_strdup2 (in[0].u.file, QSE_T(".XXXX"), qse_sed_getmmgr(sed)); tmpl_tmpfile = qse_strdup2 (in[0].u.file.path, QSE_T(".XXXX"), qse_sed_getmmgr(sed));
if (tmpl_tmpfile == QSE_NULL) if (tmpl_tmpfile == QSE_NULL)
{ {
qse_fprintf (QSE_STDERR, QSE_T("ERROR: out of memory\n")); qse_fprintf (QSE_STDERR, QSE_T("ERROR: out of memory\n"));
@ -721,10 +723,10 @@ TODO:
qse_sio_close (output->u.sio); qse_sio_close (output->u.sio);
output = output_file; output = output_file;
if (qse_fs_move (fs, tmpl_tmpfile, in[0].u.file) <= -1) if (qse_fs_move (fs, tmpl_tmpfile, in[0].u.file.path) <= -1)
{ {
qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot rename %s to %s. not deleting %s - %s\n"), qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot rename %s to %s. not deleting %s - %s\n"),
tmpl_tmpfile, in[0].u.file, tmpl_tmpfile, qse_fs_geterrmsg(fs)); tmpl_tmpfile, in[0].u.file.path, tmpl_tmpfile, qse_fs_geterrmsg(fs));
QSE_MMGR_FREE (qse_sed_getmmgr(sed), tmpl_tmpfile); QSE_MMGR_FREE (qse_sed_getmmgr(sed), tmpl_tmpfile);
goto oops; goto oops;
} }
@ -762,9 +764,10 @@ TODO:
for (i = 0; i < num_ins; i++) for (i = 0; i < num_ins; i++)
{ {
in[i].type = QSE_SED_IOSTD_FILE; in[i].type = QSE_SED_IOSTD_FILE;
in[i].u.file = in[i].u.file.path =
(qse_strcmp (argv[g_infile_pos], QSE_T("-")) == 0)? (qse_strcmp (argv[g_infile_pos], QSE_T("-")) == 0)?
QSE_NULL: argv[g_infile_pos]; QSE_NULL: argv[g_infile_pos];
in[i].u.file.cmgr = QSE_NULL;
g_infile_pos++; g_infile_pos++;
} }
@ -774,9 +777,10 @@ TODO:
if (g_output_file) if (g_output_file)
{ {
out.type = QSE_SED_IOSTD_FILE; out.type = QSE_SED_IOSTD_FILE;
out.u.file = out.u.file.path =
(qse_strcmp (g_output_file, QSE_T("-")) == 0)? (qse_strcmp (g_output_file, QSE_T("-")) == 0)?
QSE_NULL: g_output_file; QSE_NULL: g_output_file;
out.u.file.cmgr = QSE_NULL;
} }
g_sed = sed; g_sed = sed;

View File

@ -4,8 +4,6 @@
A memory manager is an instance of a structure type #qse_mmgr_t. Creating A memory manager is an instance of a structure type #qse_mmgr_t. Creating
and/or initializing an object requires a memory manager to be passed in. and/or initializing an object requires a memory manager to be passed in.
If you pass in #QSE_NULL for a memory manager, the object is created and/or
initialized with the default memory manager.
The default memory manager is merely a wrapper to memory allocation functions The default memory manager is merely a wrapper to memory allocation functions
provided by underlying operating systems: HeapAlloc/HeapReAlloc/HeapFree provided by underlying operating systems: HeapAlloc/HeapReAlloc/HeapFree

View File

@ -22,6 +22,7 @@
#define _QSE_AWK_STD_H_ #define _QSE_AWK_STD_H_
#include <qse/awk/awk.h> #include <qse/awk/awk.h>
#include <qse/cmn/sio.h>
/** @file /** @file
* This file defines functions and data types that help you create * This file defines functions and data types that help you create
@ -38,49 +39,34 @@
* This programs shows how to specify multiple console output files. * This programs shows how to specify multiple console output files.
*/ */
/**
* The qse_awk_parsestd_type_t type defines a source script type
*/
enum qse_awk_parsestd_type_t enum qse_awk_parsestd_type_t
{ {
QSE_AWK_PARSESTD_FILE = 0, /**< file name */ QSE_AWK_PARSESTD_FILE = 1,
QSE_AWK_PARSESTD_CP = 1, /**< character pointer */ QSE_AWK_PARSESTD_STR = 2
QSE_AWK_PARSESTD_CPL = 2, /**< character pointer + length */
QSE_AWK_PARSESTD_STDIO = 3 /**< standard input/output */
}; };
typedef enum qse_awk_parsestd_type_t qse_awk_parsestd_type_t; typedef enum qse_awk_parsestd_type_t qse_awk_parsestd_type_t;
/** /**
* The qse_awk_parsestd_in_t type defines a source input. * The qse_awk_parsestd_t type defines a source I/O.
*/ */
struct qse_awk_parsestd_in_t struct qse_awk_parsestd_t
{ {
qse_awk_parsestd_type_t type; qse_awk_parsestd_type_t type;
union union
{ {
const qse_char_t* file; qse_sio_t* sio;
const qse_char_t* cp; struct
qse_cstr_t cpl; {
const qse_char_t* path;
qse_cmgr_t* cmgr;
} file;
qse_xstr_t str;
} u; } u;
}; };
typedef struct qse_awk_parsestd_in_t qse_awk_parsestd_in_t;
/** typedef struct qse_awk_parsestd_t qse_awk_parsestd_t;
* The qse_awk_parsestd_out_t type defines a source output.
*/
struct qse_awk_parsestd_out_t
{
qse_awk_parsestd_type_t type;
union
{
const qse_char_t* file;
qse_char_t* cp;
qse_xstr_t cpl;
} u;
};
typedef struct qse_awk_parsestd_out_t qse_awk_parsestd_out_t;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -136,9 +122,9 @@ void* qse_awk_getxtnstd (
* @endcode * @endcode
*/ */
int qse_awk_parsestd ( int qse_awk_parsestd (
qse_awk_t* awk, qse_awk_t* awk,
const qse_awk_parsestd_in_t* in, qse_awk_parsestd_t* in,
qse_awk_parsestd_out_t* out qse_awk_parsestd_t* out
); );
/** /**

View File

@ -24,6 +24,12 @@
#include <qse/types.h> #include <qse/types.h>
#include <qse/macros.h> #include <qse/macros.h>
/** @file
* This file provides functions, types, macros for
* multibyte/wide-character conversion based on system locale.
*
*
*/
/** /**
* The qse_mbstate_t type defines a structure large enough to hold * The qse_mbstate_t type defines a structure large enough to hold
@ -114,7 +120,7 @@ qse_size_t qse_slmblen (
* The qse_slmblenmax() function returns the value of MB_CUR_MAX. * The qse_slmblenmax() function returns the value of MB_CUR_MAX.
* Note that QSE_MBLEN_MAX defines MB_LEN_MAX. * Note that QSE_MBLEN_MAX defines MB_LEN_MAX.
*/ */
int qse_slmblenmax ( qse_size_t qse_slmblenmax (
void void
); );

View File

@ -24,6 +24,14 @@
#include <qse/types.h> #include <qse/types.h>
#include <qse/macros.h> #include <qse/macros.h>
/** @file
* This file provides functions, types, macros for utf8 conversion.
*/
/**
* The QSE_UTF8LEN_MAX macro defines the maximum number of bytes
* needed to form a single unicode character.
*/
#if QSE_SIZEOF_WCHAR_T == 2 #if QSE_SIZEOF_WCHAR_T == 2
# define QSE_UTF8LEN_MAX 3 # define QSE_UTF8LEN_MAX 3
#elif QSE_SIZEOF_WCHAR_T == 4 #elif QSE_SIZEOF_WCHAR_T == 4
@ -36,24 +44,19 @@
extern "C" { extern "C" {
#endif #endif
/**
* The qse_uctoutf8len() function returns the number bytes in the utf8 sequence
* that would result from the original unicode character.
* @return
* - 0 is returned if @a uc is invalid.
* - A positive integer is returned in all other cases.
*/
qse_size_t qse_uctoutf8len (
qse_wchar_t uc
);
/** /**
* The qse_uctoutf8() function converts a unicode character to a utf8 sequence. * The qse_uctoutf8() function converts a unicode character to a utf8 sequence.
* @return * @return
* - 0 is returned if @a uc is invalid. * - 0 is returned if @a uc is invalid.
* - An integer greater than @a size is returned if the utf8 sequence buffer is * - An integer greater than @a size is returned if the @a utf8 sequence buffer
* not large enough. * is not #QSE_NULL and not large enough. This integer is actually the number
* of bytes needed.
* - If @a utf8 is #QSE_NULL, the number of bytes that would have been stored
* into @a utf8 if it had not been #QSE_NULL is returned.
* - An integer between 1 and size inclusive is returned in all other cases. * - An integer between 1 and size inclusive is returned in all other cases.
* @note
* This function doesn't check invalid unicode code points and performs
* conversion compuationally.
*/ */
qse_size_t qse_uctoutf8 ( qse_size_t qse_uctoutf8 (
qse_wchar_t uc, qse_wchar_t uc,
@ -61,17 +64,40 @@ qse_size_t qse_uctoutf8 (
qse_size_t size qse_size_t size
); );
/**
* The qse_utf8touc() function converts a utf8 sequence to a unicode character.
* @return
* - 0 is returned if the @a utf8 sequence is invalid.
* - An integer greater than @a size is returned if the @a utf8 sequence is
* not complete.
* - An integer between 1 and size inclusive is returned in all other cases.
*/
qse_size_t qse_utf8touc ( qse_size_t qse_utf8touc (
const qse_mchar_t* utf8, const qse_mchar_t* utf8,
qse_size_t size, qse_size_t size,
qse_wchar_t* uc qse_wchar_t* uc
); );
/**
* The qse_utf8lenmax() function scans at most @a size bytes from the @a utf8
* sequence and returns the number of bytes needed to form a single unicode
* character.
* @return
* - 0 is returned if the @a utf8 sequence is invalid.
* - An integer greater than @a size is returned if the @a utf8 sequence is
* not complete.
* - An integer between 1 and size inclusive is returned in all other cases.
*/
qse_size_t qse_utf8len ( qse_size_t qse_utf8len (
const qse_mchar_t* utf8, const qse_mchar_t* utf8,
qse_size_t len qse_size_t size
); );
/**
* The qse_utf8lenmax() function returns the maximum number of bytes needed
* to form a single unicode character. Use #QSE_UTF8LEN_MAX if you need a
* compile-time constant.
*/
qse_size_t qse_utf8lenmax ( qse_size_t qse_utf8lenmax (
void void
); );

View File

@ -46,16 +46,20 @@ struct qse_sed_iostd_t
enum enum
{ {
QSE_SED_IOSTD_NULL, /** invalid resource */ QSE_SED_IOSTD_NULL, /** invalid resource */
QSE_SED_IOSTD_SIO,
QSE_SED_IOSTD_FILE, QSE_SED_IOSTD_FILE,
QSE_SED_IOSTD_MEM QSE_SED_IOSTD_STR,
QSE_SED_IOSTD_SIO
} type; } type;
union union
{ {
struct
{
const qse_char_t* path;
qse_cmgr_t* cmgr;
} file;
qse_xstr_t str;
qse_sio_t* sio; qse_sio_t* sio;
const qse_char_t* file;
qse_xstr_t mem;
} u; } u;
}; };
@ -113,22 +117,28 @@ int qse_sed_compstd (
/** /**
* The qse_sed_compstdfile() function compiles a sed script from * The qse_sed_compstdfile() function compiles a sed script from
* a single file @a infile. * a single file @a infile. If @a infile is #QSE_NULL, it reads
* the script from the standard input.
* When #QSE_CHAR_IS_WCHAR is defined, it converts the multibyte
* sequences in the file @a infile to wide characters via the
* #qse_cmgr_t interface @a cmgr. If @a cmgr is #QSE_NULL, it uses
* the default interface. It calls cmgr->mbtowc() for conversion.
* @return 0 on success, -1 on failure * @return 0 on success, -1 on failure
*/ */
int qse_sed_compstdfile ( int qse_sed_compstdfile (
qse_sed_t* sed, qse_sed_t* sed,
const qse_char_t* infile const qse_char_t* infile,
qse_cmgr_t* cmgr
); );
/** /**
* The qse_sed_compstdmem() function compiles a sed script stored * The qse_sed_compstd() function compiles a sed script stored
* in a null-terminated string pointed to by @a str. * in a null-terminated string pointed to by @a script.
* @return 0 on success, -1 on failure * @return 0 on success, -1 on failure
*/ */
int qse_sed_compstdmem ( int qse_sed_compstdstr (
qse_sed_t* sed, qse_sed_t* sed,
const qse_char_t* str const qse_char_t* script
); );
/** /**
@ -164,7 +174,8 @@ int qse_sed_execstd (
int qse_sed_execstdfile ( int qse_sed_execstdfile (
qse_sed_t* sed, qse_sed_t* sed,
const qse_char_t* infile, const qse_char_t* infile,
const qse_char_t* outfile const qse_char_t* outfile,
qse_cmgr_t* cmgr
); );
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -697,7 +697,7 @@ typedef void* (*qse_mmgr_realloc_t) (void* ctx, void* ptr, qse_size_t n);
typedef void (*qse_mmgr_free_t) (void* ctx, void* ptr); typedef void (*qse_mmgr_free_t) (void* ctx, void* ptr);
/** /**
* The qse_mmgr_t type defines a set of functions for memory management. * The qse_mmgr_t type defines the memory management interface.
* As the type is merely a structure, it is just used as a single container * As the type is merely a structure, it is just used as a single container
* for memory management functions with a pointer to user-defined data. * for memory management functions with a pointer to user-defined data.
* The user-defined data pointer @a ctx is passed to each memory management * The user-defined data pointer @a ctx is passed to each memory management
@ -730,7 +730,10 @@ typedef qse_size_t (*qse_cmgr_wctomb_t) (
/** /**
* The qse_cmgr_t type defines the character-level interface to * The qse_cmgr_t type defines the character-level interface to
* multibyte/wide-character string conversion. * multibyte/wide-character conversion. This interface doesn't
* provide any facility to store conversion state in a context
* independent manner. This leads to the limitation that it can
* handle a stateless multibyte encoding only.
*/ */
struct qse_cmgr_t struct qse_cmgr_t
{ {

View File

@ -169,7 +169,7 @@ int StdAwk::openPipe (Pipe& io)
{ {
Awk::Pipe::Mode mode = io.getMode(); Awk::Pipe::Mode mode = io.getMode();
qse_pio_t* pio = QSE_NULL; qse_pio_t* pio = QSE_NULL;
int flags = QSE_PIO_TEXT | QSE_PIO_SHELL; int flags = QSE_PIO_TEXT | QSE_PIO_SHELL | QSE_PIO_IGNOREMBWCERR;
switch (mode) switch (mode)
{ {

View File

@ -58,36 +58,40 @@ typedef struct xtn_t
{ {
struct struct
{ {
qse_awk_parsestd_type_t type; qse_awk_parsestd_t* x;
union union
{ {
const qse_char_t* file; struct
const qse_char_t* cp; {
qse_sio_t* sio; /* the handle to an open file */
qse_cstr_t dir;
} file;
struct struct
{ {
const qse_char_t* ptr; const qse_char_t* ptr;
const qse_char_t* end; const qse_char_t* end;
} cpl; } str;
} u; } u;
qse_cstr_t dir;
qse_sio_t* handle; /* the handle to an open file */
} in; } in;
struct struct
{ {
qse_awk_parsestd_type_t type; qse_awk_parsestd_t* x;
union union
{ {
const qse_char_t* file;
qse_char_t* cp;
struct struct
{ {
qse_xstr_t* osp; qse_sio_t* sio;
} file;
struct
{
qse_str_t* buf;
#if 0
qse_char_t* ptr; qse_char_t* ptr;
qse_char_t* end; qse_char_t* end;
} cpl; #endif
} str;
} u; } u;
qse_sio_t* handle;
} out; } out;
} s; } s;
@ -337,11 +341,17 @@ static qse_sio_t* open_sio_rtx (qse_awk_rtx_t* rtx, const qse_char_t* file, int
return sio; return sio;
} }
static const qse_char_t* sio_std_names[] = struct sio_std_name_t
{ {
QSE_T("stdin"), const qse_char_t* ptr;
QSE_T("stdout"), qse_size_t len;
QSE_T("stderr"), };
static struct sio_std_name_t sio_std_names[] =
{
{ QSE_T("stdin"), 5 },
{ QSE_T("stdout"), 6 },
{ QSE_T("stderr"), 6 }
}; };
static qse_sio_t* open_sio_std (qse_awk_t* awk, qse_sio_std_t std, int flags) static qse_sio_t* open_sio_std (qse_awk_t* awk, qse_sio_std_t std, int flags)
@ -351,8 +361,8 @@ static qse_sio_t* open_sio_std (qse_awk_t* awk, qse_sio_std_t std, int flags)
if (sio == QSE_NULL) if (sio == QSE_NULL)
{ {
qse_cstr_t ea; qse_cstr_t ea;
ea.ptr = sio_std_names[std]; ea.ptr = sio_std_names[std].ptr;
ea.len = qse_strlen (sio_std_names[std]); ea.len = sio_std_names[std].len;
qse_awk_seterrnum (awk, QSE_AWK_EOPEN, &ea); qse_awk_seterrnum (awk, QSE_AWK_EOPEN, &ea);
} }
return sio; return sio;
@ -366,8 +376,8 @@ static qse_sio_t* open_sio_std_rtx (qse_awk_rtx_t* rtx, qse_sio_std_t std, int f
if (sio == QSE_NULL) if (sio == QSE_NULL)
{ {
qse_cstr_t ea; qse_cstr_t ea;
ea.ptr = sio_std_names[std]; ea.ptr = sio_std_names[std].ptr;
ea.len = qse_strlen (sio_std_names[std]); ea.len = sio_std_names[std].len;
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EOPEN, &ea); qse_awk_rtx_seterrnum (rtx, QSE_AWK_EOPEN, &ea);
} }
return sio; return sio;
@ -379,47 +389,42 @@ static qse_ssize_t sf_in_open (
{ {
if (arg == QSE_NULL || arg->name == QSE_NULL) if (arg == QSE_NULL || arg->name == QSE_NULL)
{ {
switch (xtn->s.in.type) switch (xtn->s.in.x->type)
{ {
case QSE_AWK_PARSESTD_FILE: case QSE_AWK_PARSESTD_FILE:
if (xtn->s.in.u.file == QSE_NULL) return -1; if (xtn->s.in.x->u.file.path == QSE_NULL ||
(xtn->s.in.x->u.file.path[0] == QSE_T('-') &&
if (xtn->s.in.u.file[0] == QSE_T('-') && xtn->s.in.x->u.file.path[1] == QSE_T('\0')))
xtn->s.in.u.file[1] == QSE_T('\0'))
{ {
/* special file name '-' */ /* special file name '-' */
xtn->s.in.handle = open_sio_std ( xtn->s.in.u.file.sio = open_sio_std (
awk, QSE_SIO_STDIN, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR); awk, QSE_SIO_STDIN, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR);
if (xtn->s.in.handle == QSE_NULL) return -1; if (xtn->s.in.u.file.sio == QSE_NULL) return -1;
} }
else else
{ {
const qse_char_t* base; const qse_char_t* base;
xtn->s.in.handle = open_sio ( xtn->s.in.u.file.sio = open_sio (
awk, xtn->s.in.u.file, awk, xtn->s.in.x->u.file.path,
QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR
); );
if (xtn->s.in.handle == QSE_NULL) return -1; if (xtn->s.in.u.file.sio == QSE_NULL) return -1;
base = qse_basename (xtn->s.in.u.file); base = qse_basename (xtn->s.in.x->u.file.path);
if (base != xtn->s.in.u.file) if (base != xtn->s.in.x->u.file.path)
{ {
xtn->s.in.dir.ptr = xtn->s.in.u.file; xtn->s.in.u.file.dir.ptr = xtn->s.in.x->u.file.path;
xtn->s.in.dir.len = base - xtn->s.in.u.file; xtn->s.in.u.file.dir.len = base - xtn->s.in.x->u.file.path;
} }
} }
if (xtn->s.in.x->u.file.cmgr)
qse_sio_setcmgr (xtn->s.in.u.file.sio, xtn->s.in.x->u.file.cmgr);
return 1; return 1;
case QSE_AWK_PARSESTD_STDIO: case QSE_AWK_PARSESTD_STR:
xtn->s.in.handle = open_sio_std ( xtn->s.in.u.str.ptr = xtn->s.in.x->u.str.ptr;
awk, QSE_SIO_STDIN, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR); xtn->s.in.u.str.end = xtn->s.in.x->u.str.ptr + xtn->s.in.x->u.str.len;
if (xtn->s.in.handle == QSE_NULL) return -1;
return 1;
case QSE_AWK_PARSESTD_CP:
case QSE_AWK_PARSESTD_CPL:
xtn->s.in.handle = QSE_NULL;
return 1; return 1;
} }
@ -433,11 +438,11 @@ static qse_ssize_t sf_in_open (
qse_char_t fbuf[64]; qse_char_t fbuf[64];
qse_char_t* dbuf = QSE_NULL; qse_char_t* dbuf = QSE_NULL;
if (xtn->s.in.dir.len > 0 && arg->name[0] != QSE_T('/')) if (xtn->s.in.u.file.dir.len > 0 && arg->name[0] != QSE_T('/'))
{ {
qse_size_t tmplen, totlen; qse_size_t tmplen, totlen;
totlen = qse_strlen(arg->name) + xtn->s.in.dir.len; totlen = qse_strlen(arg->name) + xtn->s.in.u.file.dir.len;
if (totlen >= QSE_COUNTOF(fbuf)) if (totlen >= QSE_COUNTOF(fbuf))
{ {
dbuf = QSE_MMGR_ALLOC ( dbuf = QSE_MMGR_ALLOC (
@ -456,8 +461,8 @@ static qse_ssize_t sf_in_open (
tmplen = qse_strncpy ( tmplen = qse_strncpy (
(qse_char_t*)file, (qse_char_t*)file,
xtn->s.in.dir.ptr, xtn->s.in.u.file.dir.ptr,
xtn->s.in.dir.len xtn->s.in.u.file.dir.len
); );
qse_strcpy ((qse_char_t*)file + tmplen, arg->name); qse_strcpy ((qse_char_t*)file + tmplen, arg->name);
} }
@ -485,7 +490,16 @@ static qse_ssize_t sf_in_close (
{ {
if (arg == QSE_NULL || arg->name == QSE_NULL) if (arg == QSE_NULL || arg->name == QSE_NULL)
{ {
if (xtn->s.in.handle) qse_sio_close (xtn->s.in.handle); switch (xtn->s.in.x->type)
{
case QSE_AWK_PARSESTD_FILE:
qse_sio_close (xtn->s.in.u.file.sio);
break;
case QSE_AWK_PARSESTD_STR:
/* nothing to close */
break;
}
} }
else else
{ {
@ -502,41 +516,38 @@ static qse_ssize_t sf_in_read (
{ {
if (arg == QSE_NULL || arg->name == QSE_NULL) if (arg == QSE_NULL || arg->name == QSE_NULL)
{ {
switch (xtn->s.in.type) switch (xtn->s.in.x->type)
{ {
case QSE_AWK_PARSESTD_FILE: case QSE_AWK_PARSESTD_FILE:
case QSE_AWK_PARSESTD_STDIO:
{ {
qse_ssize_t n; qse_ssize_t n;
QSE_ASSERT (xtn->s.in.handle != QSE_NULL); QSE_ASSERT (xtn->s.in.u.file.sio != QSE_NULL);
n = qse_sio_getstrn (xtn->s.in.handle, data, size); n = qse_sio_getstrn (xtn->s.in.u.file.sio, data, size);
if (n == -1) if (n <= -1)
{ {
qse_cstr_t ea; qse_cstr_t ea;
ea.ptr = xtn->s.in.u.file; if (xtn->s.in.x->u.file.path)
ea.len = qse_strlen(ea.ptr); {
ea.ptr = xtn->s.in.x->u.file.path;
ea.len = qse_strlen(ea.ptr);
}
else
{
ea.ptr = sio_std_names[QSE_SIO_STDIN].ptr;
ea.len = sio_std_names[QSE_SIO_STDIN].len;
}
qse_awk_seterrnum (awk, QSE_AWK_EREAD, &ea); qse_awk_seterrnum (awk, QSE_AWK_EREAD, &ea);
} }
return n; return n;
} }
case QSE_AWK_PARSESTD_CP: case QSE_AWK_PARSESTD_STR:
{ {
qse_size_t n = 0; qse_size_t n = 0;
while (n < size && *xtn->s.in.u.cp != QSE_T('\0')) while (n < size && xtn->s.in.u.str.ptr < xtn->s.in.u.str.end)
{ {
data[n++] = *xtn->s.in.u.cp++; data[n++] = *xtn->s.in.u.str.ptr++;
}
return n;
}
case QSE_AWK_PARSESTD_CPL:
{
qse_size_t n = 0;
while (n < size && xtn->s.in.u.cpl.ptr < xtn->s.in.u.cpl.end)
{
data[n++] = *xtn->s.in.u.cpl.ptr++;
} }
return n; return n;
} }
@ -551,7 +562,7 @@ static qse_ssize_t sf_in_read (
QSE_ASSERT (arg->handle != QSE_NULL); QSE_ASSERT (arg->handle != QSE_NULL);
n = qse_sio_getstrn (arg->handle, data, size); n = qse_sio_getstrn (arg->handle, data, size);
if (n == -1) if (n <= -1)
{ {
qse_cstr_t ea; qse_cstr_t ea;
ea.ptr = arg->name; ea.ptr = arg->name;
@ -595,43 +606,42 @@ static qse_ssize_t sf_out (
{ {
case QSE_AWK_SIO_OPEN: case QSE_AWK_SIO_OPEN:
{ {
switch (xtn->s.out.type) switch (xtn->s.out.x->type)
{ {
case QSE_AWK_PARSESTD_FILE: case QSE_AWK_PARSESTD_FILE:
if (xtn->s.out.u.file == QSE_NULL) return -1; if (xtn->s.out.x->u.file.path == QSE_NULL ||
(xtn->s.out.x->u.file.path[0] == QSE_T('-') &&
if (xtn->s.out.u.file[0] == QSE_T('-') && xtn->s.out.x->u.file.path[1] == QSE_T('\0')))
xtn->s.out.u.file[1] == QSE_T('\0'))
{ {
/* special file name '-' */ /* special file name '-' */
xtn->s.out.handle = open_sio_std ( xtn->s.out.u.file.sio = open_sio_std (
awk, QSE_SIO_STDOUT, awk, QSE_SIO_STDOUT,
QSE_SIO_WRITE | QSE_SIO_IGNOREMBWCERR QSE_SIO_WRITE | QSE_SIO_IGNOREMBWCERR
); );
if (xtn->s.out.handle == QSE_NULL) return -1; if (xtn->s.out.u.file.sio == QSE_NULL) return -1;
} }
else else
{ {
xtn->s.out.handle = open_sio ( xtn->s.out.u.file.sio = open_sio (
awk, xtn->s.out.u.file, awk, xtn->s.out.x->u.file.path,
QSE_SIO_WRITE | QSE_SIO_CREATE | QSE_SIO_WRITE | QSE_SIO_CREATE |
QSE_SIO_TRUNCATE | QSE_SIO_IGNOREMBWCERR QSE_SIO_TRUNCATE | QSE_SIO_IGNOREMBWCERR
); );
if (xtn->s.out.handle == QSE_NULL) return -1; if (xtn->s.out.u.file.sio == QSE_NULL) return -1;
} }
if (xtn->s.out.x->u.file.cmgr)
qse_sio_setcmgr (xtn->s.out.u.file.sio, xtn->s.out.x->u.file.cmgr);
return 1; return 1;
case QSE_AWK_PARSESTD_STDIO: case QSE_AWK_PARSESTD_STR:
xtn->s.out.handle = open_sio_std ( xtn->s.out.u.str.buf = qse_str_open (awk->mmgr, 0, 512);
awk, QSE_SIO_STDOUT, if (xtn->s.out.u.str.buf == QSE_NULL)
QSE_SIO_WRITE | QSE_SIO_IGNOREMBWCERR {
); qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
if (xtn->s.out.handle == QSE_NULL) return -1; return -1;
return 1; }
case QSE_AWK_PARSESTD_CP:
case QSE_AWK_PARSESTD_CPL:
xtn->s.out.handle = QSE_NULL;
return 1; return 1;
} }
@ -641,23 +651,15 @@ static qse_ssize_t sf_out (
case QSE_AWK_SIO_CLOSE: case QSE_AWK_SIO_CLOSE:
{ {
switch (xtn->s.out.type) switch (xtn->s.out.x->type)
{ {
case QSE_AWK_PARSESTD_FILE: case QSE_AWK_PARSESTD_FILE:
case QSE_AWK_PARSESTD_STDIO: qse_sio_close (xtn->s.out.u.file.sio);
qse_sio_flush (xtn->s.out.handle);
qse_sio_close (xtn->s.out.handle);
return 0; return 0;
case QSE_AWK_PARSESTD_CP: case QSE_AWK_PARSESTD_STR:
*xtn->s.out.u.cp = QSE_T('\0'); /* i don't close xtn->s.out.u.str.buf intentionally here.
return 0; * it will be closed at the end of qse_awk_parsestd() */
case QSE_AWK_PARSESTD_CPL:
xtn->s.out.u.cpl.osp->len =
xtn->s.out.u.cpl.ptr -
xtn->s.out.u.cpl.osp->ptr;
return 0; return 0;
} }
@ -666,43 +668,41 @@ static qse_ssize_t sf_out (
case QSE_AWK_SIO_WRITE: case QSE_AWK_SIO_WRITE:
{ {
switch (xtn->s.out.type) switch (xtn->s.out.x->type)
{ {
case QSE_AWK_PARSESTD_FILE: case QSE_AWK_PARSESTD_FILE:
case QSE_AWK_PARSESTD_STDIO:
{ {
qse_ssize_t n; qse_ssize_t n;
QSE_ASSERT (xtn->s.out.handle != QSE_NULL); QSE_ASSERT (xtn->s.out.u.file.sio != QSE_NULL);
n = qse_sio_putstrn (xtn->s.out.handle, data, size); n = qse_sio_putstrn (xtn->s.out.u.file.sio, data, size);
if (n == -1) if (n <= -1)
{ {
qse_cstr_t ea; qse_cstr_t ea;
ea.ptr = xtn->s.in.u.file; if (xtn->s.out.x->u.file.path)
ea.len = qse_strlen(ea.ptr); {
ea.ptr = xtn->s.out.x->u.file.path;
ea.len = qse_strlen(ea.ptr);
}
else
{
ea.ptr = sio_std_names[QSE_SIO_STDOUT].ptr;
ea.len = sio_std_names[QSE_SIO_STDOUT].len;
}
qse_awk_seterrnum (awk, QSE_AWK_EWRITE, &ea); qse_awk_seterrnum (awk, QSE_AWK_EWRITE, &ea);
} }
return n; return n;
} }
case QSE_AWK_PARSESTD_CP: case QSE_AWK_PARSESTD_STR:
{ {
qse_size_t n = 0; if (size > QSE_TYPE_MAX(qse_ssize_t)) size = QSE_TYPE_MAX(qse_ssize_t);
while (n < size && *xtn->s.out.u.cp != QSE_T('\0')) if (qse_str_ncat (xtn->s.out.u.str.buf, data, size) == (qse_size_t)-1)
{ {
*xtn->s.out.u.cp++ = data[n++]; qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
return -1;
} }
return n; return size;
}
case QSE_AWK_PARSESTD_CPL:
{
qse_size_t n = 0;
while (n < size && xtn->s.out.u.cpl.ptr < xtn->s.out.u.cpl.end)
{
*xtn->s.out.u.cpl.ptr++ = data[n++];
}
return n;
} }
} }
@ -715,12 +715,11 @@ static qse_ssize_t sf_out (
} }
int qse_awk_parsestd ( int qse_awk_parsestd (
qse_awk_t* awk, qse_awk_t* awk, qse_awk_parsestd_t* in, qse_awk_parsestd_t* out)
const qse_awk_parsestd_in_t* in,
qse_awk_parsestd_out_t* out)
{ {
qse_awk_sio_t sio; qse_awk_sio_t sio;
xtn_t* xtn = (xtn_t*) QSE_XTN (awk); xtn_t* xtn = (xtn_t*) QSE_XTN (awk);
int n;
if (in == QSE_NULL) if (in == QSE_NULL)
{ {
@ -729,67 +728,41 @@ int qse_awk_parsestd (
return -1; return -1;
} }
switch (in->type) if (in->type != QSE_AWK_PARSESTD_FILE &&
in->type != QSE_AWK_PARSESTD_STR)
{ {
case QSE_AWK_PARSESTD_FILE: qse_awk_seterrnum (awk, QSE_AWK_EINVAL, QSE_NULL);
xtn->s.in.u.file = in->u.file; return -1;
break;
case QSE_AWK_PARSESTD_CP:
xtn->s.in.u.cp = in->u.cp;
break;
case QSE_AWK_PARSESTD_CPL:
xtn->s.in.u.cpl.ptr = in->u.cpl.ptr;
xtn->s.in.u.cpl.end = in->u.cpl.ptr + in->u.cpl.len;
break;
case QSE_AWK_PARSESTD_STDIO:
/* nothing to do */
break;
default:
qse_awk_seterrnum (awk, QSE_AWK_EINVAL, QSE_NULL);
return -1;
} }
xtn->s.in.type = in->type;
xtn->s.in.handle = QSE_NULL;
sio.in = sf_in; sio.in = sf_in;
xtn->s.in.x = in;
if (out == QSE_NULL) sio.out = QSE_NULL; if (out == QSE_NULL) sio.out = QSE_NULL;
else else
{ {
switch (out->type) if (out->type != QSE_AWK_PARSESTD_FILE &&
out->type != QSE_AWK_PARSESTD_STR)
{ {
case QSE_AWK_PARSESTD_FILE: qse_awk_seterrnum (awk, QSE_AWK_EINVAL, QSE_NULL);
xtn->s.out.u.file = out->u.file; return -1;
break;
case QSE_AWK_PARSESTD_CP:
xtn->s.out.u.cp = out->u.cp;
break;
case QSE_AWK_PARSESTD_CPL:
xtn->s.out.u.cpl.osp = &out->u.cpl;
xtn->s.out.u.cpl.ptr = out->u.cpl.ptr;
xtn->s.out.u.cpl.end = out->u.cpl.ptr + out->u.cpl.len;
break;
case QSE_AWK_PARSESTD_STDIO:
/* nothing to do */
break;
default:
qse_awk_seterrnum (awk, QSE_AWK_EINVAL, QSE_NULL);
return -1;
} }
xtn->s.out.type = out->type;
xtn->s.out.handle = QSE_NULL;
sio.out = sf_out; sio.out = sf_out;
xtn->s.out.x = out;
} }
return qse_awk_parse (awk, &sio); n = qse_awk_parse (awk, &sio);
if (out && out->type == QSE_AWK_PARSESTD_STR)
{
if (n >= 0)
{
QSE_ASSERT (xtn->s.out.u.str.buf != QSE_NULL);
qse_str_yield (xtn->s.out.u.str.buf, &out->u.str, 0);
}
if (xtn->s.out.u.str.buf) qse_str_close (xtn->s.out.u.str.buf);
}
return n;
} }
/*** RTX_OPENSTD ***/ /*** RTX_OPENSTD ***/
@ -827,7 +800,7 @@ static qse_ssize_t awk_rio_pipe (
0, 0,
riod->name, riod->name,
QSE_NULL, QSE_NULL,
flags|QSE_PIO_SHELL|QSE_PIO_TEXT flags|QSE_PIO_SHELL|QSE_PIO_TEXT|QSE_PIO_IGNOREMBWCERR
); );
if (handle == QSE_NULL) return -1; if (handle == QSE_NULL) return -1;
@ -1271,6 +1244,13 @@ static qse_ssize_t awk_rio_console (
return -1; return -1;
} }
/* TODO: provide a way to set cmgr for console files icf and ocf...
* should i accept something similar to qse_awk_parsestd_t?
*
* what is the best way to change cmgr for pipes and files?
* currently there is no way to change cmgr for each pipe and file.
* you can change the global cmgr only with qse_setdflcmgr().
*/
qse_awk_rtx_t* qse_awk_rtx_openstd ( qse_awk_rtx_t* qse_awk_rtx_openstd (
qse_awk_t* awk, qse_awk_t* awk,
qse_size_t xtnsize, qse_size_t xtnsize,
@ -1288,8 +1268,8 @@ qse_awk_rtx_t* qse_awk_rtx_openstd (
qse_cstr_t argv[16]; qse_cstr_t argv[16];
qse_cstr_t* argvp = QSE_NULL, * p2; qse_cstr_t* argvp = QSE_NULL, * p2;
rio.pipe = awk_rio_pipe; rio.pipe = awk_rio_pipe;
rio.file = awk_rio_file; rio.file = awk_rio_file;
rio.console = awk_rio_console; rio.console = awk_rio_console;
if (icf != QSE_NULL) if (icf != QSE_NULL)

View File

@ -37,59 +37,31 @@
#ifdef HAVE_STDLIB_H #ifdef HAVE_STDLIB_H
# include <stdlib.h> # include <stdlib.h>
#endif #endif
#if defined(_WIN32)
qse_size_t qse_slmbrlen ( # include <windows.h>
const qse_mchar_t* mb, qse_size_t mbl, qse_mbstate_t* state)
{
#if defined(HAVE_MBRLEN)
size_t n;
n = mbrlen (mb, mbl, (mbstate_t*)state);
if (n == 0) return 1; /* a null character */
if (n == (size_t)-1) return 0; /* invalid sequence */
if (n == (size_t)-2) return mbl + 1; /* incomplete sequence */
return (qse_size_t)n;
#if 0
n = mblen (mb, mbl);
if (n == (size_t)-1) return 0; /* invalid or incomplete sequence */
if (n == 0) return 1; /* a null character */
return (qse_size_t)n;
#endif
#else
#error #### NOT SUPPORTED ####
#endif #endif
}
qse_size_t qse_slmbrtoslwc (
const qse_mchar_t* mb, qse_size_t mbl,
qse_wchar_t* wc, qse_mbstate_t* state)
{
#if defined(HAVE_MBRTOWC)
size_t n;
n = mbrtowc (wc, mb, mbl, (mbstate_t*)state);
if (n == 0)
{
*wc = QSE_WT('\0');
return 1;
}
if (n == (size_t)-1) return 0; /* invalid sequence */
if (n == (size_t)-2) return mbl + 1; /* incomplete sequence */
return (qse_size_t)n;
#else
#error #### NOT SUPPORTED ####
#endif
}
qse_size_t qse_slwcrtoslmb ( qse_size_t qse_slwcrtoslmb (
qse_wchar_t wc, qse_mchar_t* mb, qse_wchar_t wc, qse_mchar_t* mb,
qse_size_t mbl, qse_mbstate_t* state) qse_size_t mbl, qse_mbstate_t* state)
{ {
#if defined(HAVE_WCRTOMB) #if defined(_WIN32)
int n;
n = WideCharToMultiByte (
CP_THREAD_ACP, 0 /*WC_ERR_INVALID_CHARS*/,
&wc, 1, mb, mbl, NULL, NULL);
if (n == 0)
{
DWORD e = GetLastError();
if (e == ERROR_INSUFFICIENT_BUFFER) return mbl + 1;
/*if (e == ERROR_NO_UNICODE_TRANSLATION) return 0;*/
/* treat all other erros as invalid unicode character */
}
return (qse_size_t)n;
#elif defined(HAVE_WCRTOMB)
size_t n; size_t n;
if (mbl < QSE_MBLEN_MAX) if (mbl < QSE_MBLEN_MAX)
@ -123,6 +95,90 @@ qse_size_t qse_slwcrtoslmb (
#endif #endif
} }
qse_size_t qse_slmbrtoslwc (
const qse_mchar_t* mb, qse_size_t mbl,
qse_wchar_t* wc, qse_mbstate_t* state)
{
#if defined(_WIN32)
qse_size_t dbcslen;
int n;
QSE_ASSERT (mb != QSE_NULL);
QSE_ASSERT (mbl > 0);
dbcslen = IsDBCSLeadByteEx(CP_THREAD_ACP, *mb)? 2: 1;
if (mbl < dbcslen) return mbl + 1; /* incomplete sequence */
n = MultiByteToWideChar (
CP_THREAD_ACP, MB_ERR_INVALID_CHARS, mb, dbcslen, wc, 1);
if (n == 0)
{
/*DWORD e = GetLastError();*/
/*if (e == ERROR_NO_UNICODE_TRANSLATION) return 0;*/
/*if (e == ERROR_INSUFFICIENT_BUFFER) return mbl + 1;*/
return 0;
}
return dbcslen;
#elif defined(HAVE_MBRTOWC)
size_t n;
QSE_ASSERT (mb != QSE_NULL);
QSE_ASSERT (mbl > 0);
n = mbrtowc (wc, mb, mbl, (mbstate_t*)state);
if (n == 0)
{
if (wc) *wc = QSE_WT('\0');
return 1;
}
if (n == (size_t)-1) return 0; /* invalid sequence */
if (n == (size_t)-2) return mbl + 1; /* incomplete sequence */
return (qse_size_t)n;
#else
#error #### NOT SUPPORTED ####
#endif
}
qse_size_t qse_slmbrlen (
const qse_mchar_t* mb, qse_size_t mbl, qse_mbstate_t* state)
{
#if defined(_WIN32)
qse_size_t dbcslen;
QSE_ASSERT (mb != QSE_NULL);
QSE_ASSERT (mbl > 0);
dbcslen = IsDBCSLeadByteEx(CP_THREAD_ACP, *mb)? 2: 1;
if (mbl < dbcslen) return mbl + 1; /* incomplete sequence */
return dbcslen;
#elif defined(HAVE_MBRLEN)
size_t n;
QSE_ASSERT (mb != QSE_NULL);
QSE_ASSERT (mbl > 0);
n = mbrlen (mb, mbl, (mbstate_t*)state);
if (n == 0) return 1; /* a null character */
if (n == (size_t)-1) return 0; /* invalid sequence */
if (n == (size_t)-2) return mbl + 1; /* incomplete sequence */
return (qse_size_t)n;
#if 0
n = mblen (mb, mbl);
if (n == (size_t)-1) return 0; /* invalid or incomplete sequence */
if (n == 0) return 1; /* a null character */
return (qse_size_t)n;
#endif
#else
#error #### NOT SUPPORTED ####
#endif
}
/* man mbsinit /* man mbsinit
* For 8-bit encodings, all states are equivalent to the initial state. * For 8-bit encodings, all states are equivalent to the initial state.
* For multibyte encodings like UTF-8, EUC-*, BIG5 or SJIS, the wide char * For multibyte encodings like UTF-8, EUC-*, BIG5 or SJIS, the wide char
@ -131,11 +187,6 @@ qse_size_t qse_slwcrtoslmb (
* mbrtowc(3) do produce non-initial states when interrupted in the middle * mbrtowc(3) do produce non-initial states when interrupted in the middle
* of a character. * of a character.
*/ */
qse_size_t qse_slmblen (const qse_mchar_t* mb, qse_size_t mbl)
{
qse_mbstate_t state = { { 0, } };
return qse_slmbrlen (mb, mbl, &state);
}
qse_size_t qse_slmbtoslwc (const qse_mchar_t* mb, qse_size_t mbl, qse_wchar_t* wc) qse_size_t qse_slmbtoslwc (const qse_mchar_t* mb, qse_size_t mbl, qse_wchar_t* wc)
{ {
@ -149,7 +200,20 @@ qse_size_t qse_slwctoslmb (qse_wchar_t wc, qse_mchar_t* mb, qse_size_t mbl)
return qse_slwcrtoslmb (wc, mb, mbl, &state); return qse_slwcrtoslmb (wc, mb, mbl, &state);
} }
int qse_slmblenmax (void) qse_size_t qse_slmblen (const qse_mchar_t* mb, qse_size_t mbl)
{ {
return MB_CUR_MAX; qse_mbstate_t state = { { 0, } };
return qse_slmbrlen (mb, mbl, &state);
}
qse_size_t qse_slmblenmax (void)
{
#if defined(_WIN32)
/* Windows doesn't handle utf8 properly even when your code page
* is CP_UTF8(65001). you should use functions in utf8.c for utf8
* handleing on windows. */
return 2;
#else
return MB_CUR_MAX;
#endif
} }

View File

@ -73,53 +73,40 @@ static QSE_INLINE __utf8_t* get_utf8_slot (qse_wchar_t uc)
return QSE_NULL; /* invalid character */ return QSE_NULL; /* invalid character */
} }
qse_size_t qse_uctoutf8len (qse_wchar_t uc)
{
__utf8_t* cur = get_utf8_slot (uc);
return (cur == QSE_NULL)? 0: (qse_size_t)cur->length;
}
/* wctomb for utf8/unicode */
qse_size_t qse_uctoutf8 (qse_wchar_t uc, qse_mchar_t* utf8, qse_size_t size) qse_size_t qse_uctoutf8 (qse_wchar_t uc, qse_mchar_t* utf8, qse_size_t size)
{ {
__utf8_t* cur = get_utf8_slot (uc); __utf8_t* cur = get_utf8_slot (uc);
int index;
if (cur == QSE_NULL) return 0; /* illegal character */ if (cur == QSE_NULL) return 0; /* illegal character */
if (cur->length > size) if (utf8 && cur->length <= size)
{ {
/* buffer not big enough. index indicates the buffer int index = cur->length;
* size needed */ while (index > 1)
return size + 1; {
/*
* 0x3F: 00111111
* 0x80: 10000000
*/
utf8[--index] = (uc & 0x3F) | 0x80;
uc >>= 6;
}
utf8[0] = uc | cur->fbyte;
} }
index = cur->length; /* small buffer is also indicated by this return value
while (index > 1) * greater than 'size'. */
{
/*
* 0x3F: 00111111
* 0x80: 10000000
*/
utf8[--index] = (uc & 0x3F) | 0x80;
uc >>= 6;
}
utf8[0] = uc | cur->fbyte;
return (qse_size_t)cur->length; return (qse_size_t)cur->length;
} }
/* mbtowc for utf8/unicode */
qse_size_t qse_utf8touc ( qse_size_t qse_utf8touc (
const qse_mchar_t* utf8, qse_size_t size, qse_wchar_t* uc) const qse_mchar_t* utf8, qse_size_t size, qse_wchar_t* uc)
{ {
__utf8_t* cur, * end; __utf8_t* cur, * end;
#if 0
qse_mchar_t c, t;
int count = 0;
#endif
QSE_ASSERT (utf8 != QSE_NULL); QSE_ASSERT (utf8 != QSE_NULL);
QSE_ASSERT (size > 0);
QSE_ASSERT (QSE_SIZEOF(qse_mchar_t) == 1); QSE_ASSERT (QSE_SIZEOF(qse_mchar_t) == 1);
QSE_ASSERT (QSE_SIZEOF(qse_wchar_t) >= 2); QSE_ASSERT (QSE_SIZEOF(qse_wchar_t) >= 2);
@ -130,81 +117,37 @@ qse_size_t qse_utf8touc (
{ {
if ((utf8[0] & cur->mask) == cur->fbyte) if ((utf8[0] & cur->mask) == cur->fbyte)
{ {
int i;
qse_wchar_t w;
if (size < cur->length) return size + 1; /* if size is less that cur->length, the incomplete-seqeunce
w = utf8[0] & cur->fmask;
for (i = 1; i < cur->length; i++)
{
if (!(utf8[i] & 0x80)) return 0;
w = (w << 6) | (utf8[i] & 0x3F);
}
*uc = w;
return (qse_size_t)cur->length;
}
cur++;
}
return 0; /* error - invalid sequence */
#if 0
c = *utf8;
w = c;
while (cur < end)
{
count++;
if ((c & cur->mask) == cur->fbyte)
{
w &= cur->upper;
if (w < cur->lower) break; /* wrong value */
*uc = w;
return (qse_size_t)count;
}
if (size <= count) break; /* insufficient input */
utf8++; /* advance to the next character in the sequence */
t = (*utf8 ^ 0x80) & 0xFF;
if (t & 0xC0) break;
w = (w << 6) | t;
cur++;
}
return 0; /* error - invalid sequence */
#endif
}
/* mblen for utf8 */
qse_size_t qse_utf8len (const qse_mchar_t* utf8, qse_size_t len)
{
__utf8_t* cur, * end;
end = utf8_table + QSE_COUNTOF(utf8_table);
cur = utf8_table;
while (cur < end)
{
if ((utf8[0] & cur->mask) == cur->fbyte)
{
int i;
/* if len is less that cur->length, the incomplete-seqeunce
* error is naturally indicated. so validate the string * error is naturally indicated. so validate the string
* only if len is as large as cur->length. */ * only if size is as large as cur->length. */
if (len >= cur->length) if (size >= cur->length)
{ {
for (i = 1; i < cur->length; i++) int i;
if (uc)
{ {
/* in utf8, trailing bytes are all qse_wchar_t w;
* set with 0x80. if not, invalid */
if (!(utf8[i] & 0x80)) return 0; w = utf8[0] & cur->fmask;
for (i = 1; i < cur->length; i++)
{
/* in utf8, trailing bytes are all
* set with 0x80. if not, invalid */
if (!(utf8[i] & 0x80)) return 0;
w = (w << 6) | (utf8[i] & 0x3F);
}
*uc = w;
}
else
{
for (i = 1; i < cur->length; i++)
{
/* in utf8, trailing bytes are all
* set with 0x80. if not, invalid */
if (!(utf8[i] & 0x80)) return 0;
}
} }
} }
@ -221,7 +164,13 @@ qse_size_t qse_utf8len (const qse_mchar_t* utf8, qse_size_t len)
return 0; /* error - invalid sequence */ return 0; /* error - invalid sequence */
} }
qse_size_t qse_utf8len (const qse_mchar_t* utf8, qse_size_t size)
{
return qse_utf8touc (utf8, size, QSE_NULL);
}
qse_size_t qse_utf8lenmax (void) qse_size_t qse_utf8lenmax (void)
{ {
return QSE_UTF8LEN_MAX; return QSE_UTF8LEN_MAX;
} }

View File

@ -64,7 +64,7 @@ int qse_cut_compstd (qse_cut_t* cut, const qse_char_t* sptr)
return qse_cut_comp (cut, sptr, qse_strlen(sptr)); return qse_cut_comp (cut, sptr, qse_strlen(sptr));
} }
static qse_sio_t* open_sio (qse_cut_t* cut, const qse_char_t* file, int flags) static qse_sio_t* open_sio_file (qse_cut_t* cut, const qse_char_t* file, int flags)
{ {
qse_sio_t* sio; qse_sio_t* sio;
@ -79,23 +79,29 @@ static qse_sio_t* open_sio (qse_cut_t* cut, const qse_char_t* file, int flags)
return sio; return sio;
} }
struct sio_std_name_t
{
const qse_char_t* ptr;
qse_size_t len;
};
static struct sio_std_name_t sio_std_names[] =
{
{ QSE_T("stdin"), 5 },
{ QSE_T("stdout"), 6 },
{ QSE_T("stderr"), 6 }
};
static qse_sio_t* open_sio_std (qse_cut_t* cut, qse_sio_std_t std, int flags) static qse_sio_t* open_sio_std (qse_cut_t* cut, qse_sio_std_t std, int flags)
{ {
static const qse_char_t* sio_std_names[] =
{
QSE_T("stdin"),
QSE_T("stdout"),
QSE_T("stderr"),
};
qse_sio_t* sio; qse_sio_t* sio;
sio = qse_sio_openstd (cut->mmgr, 0, std, flags); sio = qse_sio_openstd (cut->mmgr, 0, std, flags);
if (sio == QSE_NULL) if (sio == QSE_NULL)
{ {
qse_cstr_t ea; qse_cstr_t ea;
ea.ptr = sio_std_names[std]; ea.ptr = sio_std_names[std].ptr;
ea.len = qse_strlen (sio_std_names[std]); ea.len = sio_std_names[std].len;
qse_cut_seterrnum (cut, QSE_CUT_EIOFIL, &ea); qse_cut_seterrnum (cut, QSE_CUT_EIOFIL, &ea);
} }
return sio; return sio;
@ -114,7 +120,7 @@ static qse_ssize_t xin (
{ {
/* main data stream */ /* main data stream */
sio = xtn->infile? sio = xtn->infile?
open_sio (cut, xtn->infile, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR): open_sio_file (cut, xtn->infile, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR):
open_sio_std (cut, QSE_SIO_STDIN, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR); open_sio_std (cut, QSE_SIO_STDIN, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR);
if (sio == QSE_NULL) return -1; if (sio == QSE_NULL) return -1;
arg->handle = sio; arg->handle = sio;
@ -132,15 +138,20 @@ static qse_ssize_t xin (
{ {
qse_ssize_t n = qse_sio_getstrn (arg->handle, buf, len); qse_ssize_t n = qse_sio_getstrn (arg->handle, buf, len);
if (n == -1) if (n <= -1)
{ {
qse_cstr_t ea;
if (xtn->infile) if (xtn->infile)
{ {
qse_cstr_t ea;
ea.ptr = xtn->infile; ea.ptr = xtn->infile;
ea.len = qse_strlen (xtn->infile); ea.len = qse_strlen (xtn->infile);
qse_cut_seterrnum (cut, QSE_CUT_EIOFIL, &ea);
} }
else
{
ea.ptr = sio_std_names[QSE_SIO_STDIN].ptr;
ea.len = sio_std_names[QSE_SIO_STDIN].len;
}
qse_cut_seterrnum (cut, QSE_CUT_EIOFIL, &ea);
} }
return n; return n;
@ -163,7 +174,7 @@ static qse_ssize_t xout (
case QSE_CUT_IO_OPEN: case QSE_CUT_IO_OPEN:
{ {
sio = xtn->outfile? sio = xtn->outfile?
open_sio (cut, xtn->outfile, QSE_SIO_WRITE | QSE_SIO_CREATE | QSE_SIO_TRUNCATE | QSE_SIO_IGNOREMBWCERR): open_sio_file (cut, xtn->outfile, QSE_SIO_WRITE | QSE_SIO_CREATE | QSE_SIO_TRUNCATE | QSE_SIO_IGNOREMBWCERR):
open_sio_std (cut, QSE_SIO_STDOUT, QSE_SIO_WRITE | QSE_SIO_IGNOREMBWCERR); open_sio_std (cut, QSE_SIO_STDOUT, QSE_SIO_WRITE | QSE_SIO_IGNOREMBWCERR);
if (sio == QSE_NULL) return -1; if (sio == QSE_NULL) return -1;
arg->handle = sio; arg->handle = sio;
@ -182,15 +193,20 @@ static qse_ssize_t xout (
{ {
qse_ssize_t n = qse_sio_putstrn (arg->handle, dat, len); qse_ssize_t n = qse_sio_putstrn (arg->handle, dat, len);
if (n == -1) if (n <= -1)
{ {
qse_cstr_t ea;
if (xtn->outfile) if (xtn->outfile)
{ {
qse_cstr_t ea;
ea.ptr = xtn->outfile; ea.ptr = xtn->outfile;
ea.len = qse_strlen (xtn->outfile); ea.len = qse_strlen (xtn->outfile);
qse_cut_seterrnum (cut, QSE_CUT_EIOFIL, &ea);
} }
else
{
ea.ptr = sio_std_names[QSE_SIO_STDOUT].ptr;
ea.len = sio_std_names[QSE_SIO_STDOUT].len;
}
qse_cut_seterrnum (cut, QSE_CUT_EIOFIL, &ea);
} }
return n; return n;
@ -202,6 +218,7 @@ static qse_ssize_t xout (
} }
/* TODO: refer to sed/std.c and make similar enhancements */ /* TODO: refer to sed/std.c and make similar enhancements */
/* TODO: accept cmgr */
int qse_cut_execstd (qse_cut_t* cut, const qse_char_t* infile, const qse_char_t* outfile) int qse_cut_execstd (qse_cut_t* cut, const qse_char_t* infile, const qse_char_t* outfile)
{ {
xtn_t* xtn = (xtn_t*) QSE_XTN (cut); xtn_t* xtn = (xtn_t*) QSE_XTN (cut);

View File

@ -1,5 +1,5 @@
/* /*
* $Id: std.c 306 2009-11-22 13:58:53Z baconevi $ * $Id$
* *
Copyright 2006-2011 Chung, Hyung-Hwan. Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE. This file is part of QSE.
@ -136,7 +136,7 @@ static int verify_iostd_in (qse_sed_t* sed, qse_sed_iostd_t in[])
{ {
if (in[i].type != QSE_SED_IOSTD_SIO && if (in[i].type != QSE_SED_IOSTD_SIO &&
in[i].type != QSE_SED_IOSTD_FILE && in[i].type != QSE_SED_IOSTD_FILE &&
in[i].type != QSE_SED_IOSTD_MEM) in[i].type != QSE_SED_IOSTD_STR)
{ {
qse_sed_seterrnum (sed, QSE_SED_EINVAL, QSE_NULL); qse_sed_seterrnum (sed, QSE_SED_EINVAL, QSE_NULL);
return -1; return -1;
@ -146,7 +146,7 @@ static int verify_iostd_in (qse_sed_t* sed, qse_sed_iostd_t in[])
return 0; return 0;
} }
static qse_sio_t* open_sio (qse_sed_t* sed, const qse_char_t* file, int flags) static qse_sio_t* open_sio_file (qse_sed_t* sed, const qse_char_t* file, int flags)
{ {
qse_sio_t* sio; qse_sio_t* sio;
@ -161,11 +161,17 @@ static qse_sio_t* open_sio (qse_sed_t* sed, const qse_char_t* file, int flags)
return sio; return sio;
} }
static const qse_char_t* sio_std_names[] = struct sio_std_name_t
{ {
QSE_T("stdin"), const qse_char_t* ptr;
QSE_T("stdout"), qse_size_t len;
QSE_T("stderr"), };
static struct sio_std_name_t sio_std_names[] =
{
{ QSE_T("stdin"), 5 },
{ QSE_T("stdout"), 6 },
{ QSE_T("stderr"), 6 }
}; };
static qse_sio_t* open_sio_std (qse_sed_t* sed, qse_sio_std_t std, int flags) static qse_sio_t* open_sio_std (qse_sed_t* sed, qse_sio_std_t std, int flags)
@ -176,8 +182,8 @@ static qse_sio_t* open_sio_std (qse_sed_t* sed, qse_sio_std_t std, int flags)
if (sio == QSE_NULL) if (sio == QSE_NULL)
{ {
qse_cstr_t ea; qse_cstr_t ea;
ea.ptr = sio_std_names[std]; ea.ptr = sio_std_names[std].ptr;
ea.len = qse_strlen (sio_std_names[std]); ea.len = sio_std_names[std].len;
qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea); qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea);
} }
return sio; return sio;
@ -186,7 +192,24 @@ static qse_sio_t* open_sio_std (qse_sed_t* sed, qse_sio_std_t std, int flags)
static void close_main_stream ( static void close_main_stream (
qse_sed_t* sed, qse_sed_io_arg_t* arg, qse_sed_iostd_t* io) qse_sed_t* sed, qse_sed_io_arg_t* arg, qse_sed_iostd_t* io)
{ {
if (io->type == QSE_SED_IOSTD_FILE) qse_sio_close (arg->handle); switch (io->type)
{
case QSE_SED_IOSTD_SIO:
/* nothing to do */
break;
case QSE_SED_IOSTD_FILE:
qse_sio_close (arg->handle);
break;
case QSE_SED_IOSTD_STR:
/* nothing to do for input.
* i don't close xtn->e.out.memstr intentionally.
* i close this in qse_awk_execstd()
*/
break;
}
} }
static int open_input_stream ( static int open_input_stream (
@ -204,15 +227,16 @@ static int open_input_stream (
case QSE_SED_IOSTD_FILE: case QSE_SED_IOSTD_FILE:
{ {
qse_sio_t* sio; qse_sio_t* sio;
sio = (io->u.file == QSE_NULL)? sio = (io->u.file.path == QSE_NULL)?
open_sio_std (sed, QSE_SIO_STDIN, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR): open_sio_std (sed, QSE_SIO_STDIN, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR):
open_sio (sed, io->u.file, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR); open_sio_file (sed, io->u.file.path, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR);
if (sio == QSE_NULL) return -1; if (sio == QSE_NULL) return -1;
if (io->u.file.cmgr) qse_sio_setcmgr (sio, io->u.file.cmgr);
arg->handle = sio; arg->handle = sio;
break; break;
} }
case QSE_SED_IOSTD_MEM: case QSE_SED_IOSTD_STR:
/* don't store anything to arg->handle */ /* don't store anything to arg->handle */
base->mempos = 0; base->mempos = 0;
break; break;
@ -220,7 +244,7 @@ static int open_input_stream (
default: default:
QSE_ASSERTX ( QSE_ASSERTX (
!"should never happen", !"should never happen",
"io-type must be one of SIO,FILE,MEM" "io-type must be one of SIO,FILE,STR"
); );
qse_sed_seterrnum (sed, QSE_SED_EINTERN, QSE_NULL); qse_sed_seterrnum (sed, QSE_SED_EINTERN, QSE_NULL);
return -1; return -1;
@ -234,8 +258,8 @@ static int open_input_stream (
{ {
qse_sed_setcompid ( qse_sed_setcompid (
sed, sed,
((io->u.file == QSE_NULL)? ((io->u.file.path == QSE_NULL)?
sio_std_names[QSE_SIO_STDIN]: io->u.file) sio_std_names[QSE_SIO_STDIN].ptr: io->u.file.path)
); );
} }
else else
@ -243,7 +267,7 @@ static int open_input_stream (
qse_char_t buf[64]; qse_char_t buf[64];
/* format an identifier to be something like M#1, S#5 */ /* format an identifier to be something like M#1, S#5 */
buf[0] = (io->type == QSE_SED_IOSTD_MEM)? QSE_T('M'): QSE_T('S'); buf[0] = (io->type == QSE_SED_IOSTD_STR)? QSE_T('M'): QSE_T('S');
buf[1] = QSE_T('#'); buf[1] = QSE_T('#');
int_to_str (io - xtn->s.in.ptr, &buf[2], QSE_COUNTOF(buf) - 2); int_to_str (io - xtn->s.in.ptr, &buf[2], QSE_COUNTOF(buf) - 2);
@ -271,7 +295,7 @@ static int open_output_stream (qse_sed_t* sed, qse_sed_io_arg_t* arg, qse_sed_io
case QSE_SED_IOSTD_FILE: case QSE_SED_IOSTD_FILE:
{ {
qse_sio_t* sio; qse_sio_t* sio;
if (io->u.file == QSE_NULL) if (io->u.file.path == QSE_NULL)
{ {
sio = open_sio_std ( sio = open_sio_std (
sed, QSE_SIO_STDOUT, sed, QSE_SIO_STDOUT,
@ -283,8 +307,8 @@ static int open_output_stream (qse_sed_t* sed, qse_sed_io_arg_t* arg, qse_sed_io
} }
else else
{ {
sio = open_sio ( sio = open_sio_file (
sed, io->u.file, sed, io->u.file.path,
QSE_SIO_WRITE | QSE_SIO_WRITE |
QSE_SIO_CREATE | QSE_SIO_CREATE |
QSE_SIO_TRUNCATE | QSE_SIO_TRUNCATE |
@ -292,11 +316,12 @@ static int open_output_stream (qse_sed_t* sed, qse_sed_io_arg_t* arg, qse_sed_io
); );
} }
if (sio == QSE_NULL) return -1; if (sio == QSE_NULL) return -1;
if (io->u.file.cmgr) qse_sio_setcmgr (sio, io->u.file.cmgr);
arg->handle = sio; arg->handle = sio;
break; break;
} }
case QSE_SED_IOSTD_MEM: case QSE_SED_IOSTD_STR:
/* don't store anything to arg->handle */ /* don't store anything to arg->handle */
xtn->e.out.memstr = qse_str_open (sed->mmgr, 0, 512); xtn->e.out.memstr = qse_str_open (sed->mmgr, 0, 512);
if (xtn->e.out.memstr == QSE_NULL) if (xtn->e.out.memstr == QSE_NULL)
@ -309,7 +334,7 @@ static int open_output_stream (qse_sed_t* sed, qse_sed_io_arg_t* arg, qse_sed_io
default: default:
QSE_ASSERTX ( QSE_ASSERTX (
!"should never happen", !"should never happen",
"io-type must be one of SIO,FILE,MEM" "io-type must be one of SIO,FILE,STR"
); );
qse_sed_seterrnum (sed, QSE_SED_EINTERN, QSE_NULL); qse_sed_seterrnum (sed, QSE_SED_EINTERN, QSE_NULL);
return -1; return -1;
@ -341,13 +366,14 @@ static qse_ssize_t read_input_stream (
QSE_ASSERT (io != QSE_NULL); QSE_ASSERT (io != QSE_NULL);
if (io->type == QSE_SED_IOSTD_MEM) if (io->type == QSE_SED_IOSTD_STR)
{ {
n = 0; n = 0;
while (base->mempos < io->u.mem.len && n < len) while (base->mempos < io->u.str.len && n < len)
buf[n++] = io->u.mem.ptr[base->mempos++]; buf[n++] = io->u.str.ptr[base->mempos++];
} }
else n = qse_sio_getstrn (arg->handle, buf, len); else n = qse_sio_getstrn (arg->handle, buf, len);
if (n != 0) if (n != 0)
{ {
if (n <= -1) if (n <= -1)
@ -355,8 +381,16 @@ static qse_ssize_t read_input_stream (
if (io->type == QSE_SED_IOSTD_FILE) if (io->type == QSE_SED_IOSTD_FILE)
{ {
qse_cstr_t ea; qse_cstr_t ea;
ea.ptr = io->u.file; if (io->u.file.path)
ea.len = qse_strlen (io->u.file); {
ea.ptr = io->u.file.path;
ea.len = qse_strlen (io->u.file.path);
}
else
{
ea.ptr = sio_std_names[QSE_SIO_STDIN].ptr;
ea.len = sio_std_names[QSE_SIO_STDIN].len;
}
qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea); qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea);
} }
} }
@ -398,8 +432,16 @@ static qse_ssize_t read_input_stream (
if (next->type == QSE_SED_IOSTD_FILE) if (next->type == QSE_SED_IOSTD_FILE)
{ {
qse_cstr_t ea; qse_cstr_t ea;
ea.ptr = next->u.file; if (next->u.file.path)
ea.len = qse_strlen (next->u.file); {
ea.ptr = next->u.file.path;
ea.len = qse_strlen (next->u.file.path);
}
else
{
ea.ptr = sio_std_names[QSE_SIO_STDIN].ptr;
ea.len = sio_std_names[QSE_SIO_STDIN].len;
}
qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea); qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea);
} }
@ -489,7 +531,7 @@ static qse_ssize_t x_in (
} }
else else
{ {
sio = open_sio (sed, arg->path, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR); sio = open_sio_file (sed, arg->path, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR);
if (sio == QSE_NULL) return -1; if (sio == QSE_NULL) return -1;
arg->handle = sio; arg->handle = sio;
} }
@ -527,8 +569,8 @@ static qse_ssize_t x_in (
if (n <= -1) if (n <= -1)
{ {
qse_cstr_t ea; qse_cstr_t ea;
ea.ptr = QSE_T("stdin"); ea.ptr = sio_std_names[QSE_SIO_STDIN].ptr;
ea.len = 5; ea.len = sio_std_names[QSE_SIO_STDIN].len;
qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea); qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea);
} }
return n; return n;
@ -574,7 +616,7 @@ static qse_ssize_t x_out (
{ {
if (arg->path == QSE_NULL) if (arg->path == QSE_NULL)
{ {
if (xtn->e.out.ptr== QSE_NULL) if (xtn->e.out.ptr == QSE_NULL)
{ {
sio = open_sio_std ( sio = open_sio_std (
sed, QSE_SIO_STDOUT, sed, QSE_SIO_STDOUT,
@ -593,7 +635,7 @@ static qse_ssize_t x_out (
} }
else else
{ {
sio = open_sio ( sio = open_sio_file (
sed, arg->path, sed, arg->path,
QSE_SIO_WRITE | QSE_SIO_WRITE |
QSE_SIO_CREATE | QSE_SIO_CREATE |
@ -611,7 +653,7 @@ static qse_ssize_t x_out (
{ {
if (arg->path == QSE_NULL) if (arg->path == QSE_NULL)
{ {
if (xtn->e.out.ptr== QSE_NULL) if (xtn->e.out.ptr == QSE_NULL)
qse_sio_close (arg->handle); qse_sio_close (arg->handle);
else else
close_main_stream (sed, arg, xtn->e.out.ptr); close_main_stream (sed, arg, xtn->e.out.ptr);
@ -628,15 +670,15 @@ static qse_ssize_t x_out (
if (arg->path == QSE_NULL) if (arg->path == QSE_NULL)
{ {
/* main data stream */ /* main data stream */
if (xtn->e.out.ptr== QSE_NULL) if (xtn->e.out.ptr == QSE_NULL)
{ {
qse_ssize_t n; qse_ssize_t n;
n = qse_sio_putstrn (arg->handle, dat, len); n = qse_sio_putstrn (arg->handle, dat, len);
if (n <= -1) if (n <= -1)
{ {
qse_cstr_t ea; qse_cstr_t ea;
ea.ptr = QSE_T("stdin"); ea.ptr = sio_std_names[QSE_SIO_STDOUT].ptr;
ea.len = 5; ea.len = sio_std_names[QSE_SIO_STDOUT].len;
qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea); qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea);
} }
return n; return n;
@ -644,7 +686,7 @@ static qse_ssize_t x_out (
else else
{ {
qse_sed_iostd_t* io = xtn->e.out.ptr; qse_sed_iostd_t* io = xtn->e.out.ptr;
if (io->type == QSE_SED_IOSTD_MEM) if (io->type == QSE_SED_IOSTD_STR)
{ {
if (len > QSE_TYPE_MAX(qse_ssize_t)) len = QSE_TYPE_MAX(qse_ssize_t); if (len > QSE_TYPE_MAX(qse_ssize_t)) len = QSE_TYPE_MAX(qse_ssize_t);
@ -663,8 +705,16 @@ static qse_ssize_t x_out (
if (n <= -1) if (n <= -1)
{ {
qse_cstr_t ea; qse_cstr_t ea;
ea.ptr = io->u.file; if (io->u.file.path)
ea.len = qse_strlen(io->u.file); {
ea.ptr = io->u.file.path;
ea.len = qse_strlen(io->u.file.path);
}
else
{
ea.ptr = sio_std_names[QSE_SIO_STDOUT].ptr;
ea.len = sio_std_names[QSE_SIO_STDOUT].len;
}
qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea); qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea);
} }
return n; return n;
@ -732,7 +782,7 @@ int qse_sed_execstd (
{ {
if (out->type != QSE_SED_IOSTD_SIO && if (out->type != QSE_SED_IOSTD_SIO &&
out->type != QSE_SED_IOSTD_FILE && out->type != QSE_SED_IOSTD_FILE &&
out->type != QSE_SED_IOSTD_MEM) out->type != QSE_SED_IOSTD_STR)
{ {
qse_sed_seterrnum (sed, QSE_SED_EINVAL, QSE_NULL); qse_sed_seterrnum (sed, QSE_SED_EINVAL, QSE_NULL);
return -1; return -1;
@ -746,41 +796,47 @@ int qse_sed_execstd (
n = qse_sed_exec (sed, x_in, x_out); n = qse_sed_exec (sed, x_in, x_out);
if (n >= 0 && out && out->type == QSE_SED_IOSTD_MEM) if (out && out->type == QSE_SED_IOSTD_STR)
{ {
QSE_ASSERT (xtn->e.out.memstr != QSE_NULL); if (n >= 0)
qse_str_yield (xtn->e.out.memstr, &out->u.mem, 0); {
QSE_ASSERT (xtn->e.out.memstr != QSE_NULL);
qse_str_yield (xtn->e.out.memstr, &out->u.str, 0);
}
if (xtn->e.out.memstr) qse_str_close (xtn->e.out.memstr);
} }
if (xtn->e.out.memstr) qse_str_close (xtn->e.out.memstr);
return n; return n;
} }
int qse_sed_compstdfile (qse_sed_t* sed, const qse_char_t* file) int qse_sed_compstdfile (
qse_sed_t* sed, const qse_char_t* file, qse_cmgr_t* cmgr)
{ {
qse_sed_iostd_t in[2]; qse_sed_iostd_t in[2];
in[0].type = QSE_SED_IOSTD_FILE; in[0].type = QSE_SED_IOSTD_FILE;
in[0].u.file = file; in[0].u.file.path = file;
in[0].u.file.cmgr = cmgr;
in[1].type = QSE_SED_IOSTD_NULL; in[1].type = QSE_SED_IOSTD_NULL;
return qse_sed_compstd (sed, in, QSE_NULL); return qse_sed_compstd (sed, in, QSE_NULL);
} }
int qse_sed_compstdmem (qse_sed_t* sed, const qse_char_t* script) int qse_sed_compstdstr (qse_sed_t* sed, const qse_char_t* script)
{ {
qse_sed_iostd_t in[2]; qse_sed_iostd_t in[2];
in[0].type = QSE_SED_IOSTD_MEM; in[0].type = QSE_SED_IOSTD_STR;
in[0].u.mem.ptr = script; in[0].u.str.ptr = script;
in[0].u.mem.len = qse_strlen(script); in[0].u.str.len = qse_strlen(script);
in[1].type = QSE_SED_IOSTD_NULL; in[1].type = QSE_SED_IOSTD_NULL;
return qse_sed_compstd (sed, in, QSE_NULL); return qse_sed_compstd (sed, in, QSE_NULL);
} }
int qse_sed_execstdfile ( int qse_sed_execstdfile (
qse_sed_t* sed, const qse_char_t* infile, const qse_char_t* outfile) qse_sed_t* sed, const qse_char_t* infile,
const qse_char_t* outfile, qse_cmgr_t* cmgr)
{ {
qse_sed_iostd_t in[2]; qse_sed_iostd_t in[2];
qse_sed_iostd_t out; qse_sed_iostd_t out;
@ -789,7 +845,8 @@ int qse_sed_execstdfile (
if (infile) if (infile)
{ {
in[0].type = QSE_SED_IOSTD_FILE; in[0].type = QSE_SED_IOSTD_FILE;
in[0].u.file = infile; in[0].u.file.path = infile;
in[0].u.file.cmgr = cmgr;
in[1].type = QSE_SED_IOSTD_NULL; in[1].type = QSE_SED_IOSTD_NULL;
pin = in; pin = in;
} }
@ -797,7 +854,8 @@ int qse_sed_execstdfile (
if (outfile) if (outfile)
{ {
out.type = QSE_SED_IOSTD_FILE; out.type = QSE_SED_IOSTD_FILE;
out.u.file = outfile; out.u.file.path = outfile;
out.u.file.cmgr = cmgr;
pout = &out; pout = &out;
} }

View File

@ -37,7 +37,7 @@ int main ()
qse_awk_t* awk = QSE_NULL; qse_awk_t* awk = QSE_NULL;
qse_awk_rtx_t* rtx = QSE_NULL; qse_awk_rtx_t* rtx = QSE_NULL;
qse_awk_val_t* retv; qse_awk_val_t* retv;
qse_awk_parsestd_in_t psin; qse_awk_parsestd_t psin;
int ret = -1; int ret = -1;
awk = qse_awk_openstd (0); awk = qse_awk_openstd (0);
@ -47,8 +47,9 @@ int main ()
goto oops; goto oops;
} }
psin.type = QSE_AWK_PARSESTD_CP; psin.type = QSE_AWK_PARSESTD_STR;
psin.u.cp = src; psin.u.str.ptr = src;
psin.u.str.len = qse_strlen(src);
if (qse_awk_parsestd (awk, &psin, QSE_NULL) <= -1) if (qse_awk_parsestd (awk, &psin, QSE_NULL) <= -1)
{ {

View File

@ -34,16 +34,14 @@ static const qse_char_t* src = QSE_T(
"}" "}"
); );
static qse_char_t srcout[5000];
int main () int main ()
{ {
qse_awk_t* awk = QSE_NULL; qse_awk_t* awk = QSE_NULL;
qse_awk_rtx_t* rtx = QSE_NULL; qse_awk_rtx_t* rtx = QSE_NULL;
qse_awk_val_t* retv; qse_awk_val_t* retv;
qse_awk_parsestd_in_t psin; qse_awk_parsestd_t psin;
qse_awk_parsestd_out_t psout; qse_awk_parsestd_t psout;
int ret; int ret;
@ -54,13 +52,13 @@ int main ()
ret = -1; goto oops; ret = -1; goto oops;
} }
qse_memset (srcout, QSE_T(' '), QSE_COUNTOF(srcout)-1); psin.type = QSE_AWK_PARSESTD_STR;
srcout[QSE_COUNTOF(srcout)-1] = QSE_T('\0'); psin.u.str.ptr = src;
psin.u.str.len = qse_strlen(src);
psin.type = QSE_AWK_PARSESTD_CP; psout.type = QSE_AWK_PARSESTD_STR;
psin.u.cp = src; /* ps.out.u.str.ptr and ps.out.u.str.len are set when qse_awk_parsestd()
psout.type = QSE_AWK_PARSESTD_CP; * returns success */
psout.u.cp = srcout;
ret = qse_awk_parsestd (awk, &psin, &psout); ret = qse_awk_parsestd (awk, &psin, &psout);
if (ret <= -1) if (ret <= -1)
@ -70,10 +68,12 @@ int main ()
ret = -1; goto oops; ret = -1; goto oops;
} }
qse_printf (QSE_T("DEPARSED SOURCE:\n%s\n"), srcout); qse_printf (QSE_T("DEPARSED SOURCE:\n%s\n"), psout.u.str.ptr);
qse_printf (QSE_T("=================================\n")); qse_printf (QSE_T("=================================\n"));
qse_fflush (QSE_STDOUT); qse_fflush (QSE_STDOUT);
QSE_MMGR_FREE (qse_awk_getmmgr(awk), psout.u.str.ptr);
rtx = qse_awk_rtx_openstd ( rtx = qse_awk_rtx_openstd (
awk, awk,
0, 0,

View File

@ -43,7 +43,7 @@ int main ()
qse_awk_t* awk = QSE_NULL; qse_awk_t* awk = QSE_NULL;
qse_awk_rtx_t* rtx = QSE_NULL; qse_awk_rtx_t* rtx = QSE_NULL;
qse_awk_parsestd_in_t psin; qse_awk_parsestd_t psin;
int ret, i; int ret, i;
@ -58,8 +58,9 @@ int main ()
/* don't allow BEGIN, END, pattern-action blocks */ /* don't allow BEGIN, END, pattern-action blocks */
qse_awk_setoption (awk, qse_awk_getoption(awk) & ~QSE_AWK_PABLOCK); qse_awk_setoption (awk, qse_awk_getoption(awk) & ~QSE_AWK_PABLOCK);
psin.type = QSE_AWK_PARSESTD_CP; psin.type = QSE_AWK_PARSESTD_STR;
psin.u.cp = src; psin.u.str.ptr = src;
psin.u.str.len = qse_strlen(src);
ret = qse_awk_parsestd (awk, &psin, QSE_NULL); ret = qse_awk_parsestd (awk, &psin, QSE_NULL);
if (ret == -1) if (ret == -1)

View File

@ -30,7 +30,7 @@ int main ()
{ {
qse_awk_t* awk = QSE_NULL; qse_awk_t* awk = QSE_NULL;
qse_awk_rtx_t* rtx = QSE_NULL; qse_awk_rtx_t* rtx = QSE_NULL;
qse_awk_parsestd_in_t psin; qse_awk_parsestd_t psin;
qse_char_t* str; qse_char_t* str;
qse_size_t len; qse_size_t len;
qse_awk_val_t* rtv = QSE_NULL; qse_awk_val_t* rtv = QSE_NULL;
@ -58,8 +58,9 @@ int main ()
qse_awk_setoption (awk, opt); qse_awk_setoption (awk, opt);
psin.type = QSE_AWK_PARSESTD_CP; psin.type = QSE_AWK_PARSESTD_STR;
psin.u.cp = src; psin.u.str.ptr = src;
psin.u.str.len = qse_strlen(src);
ret = qse_awk_parsestd (awk, &psin, QSE_NULL); ret = qse_awk_parsestd (awk, &psin, QSE_NULL);
if (ret == -1) if (ret == -1)

View File

@ -40,7 +40,7 @@ int main ()
qse_awk_t* awk = QSE_NULL; qse_awk_t* awk = QSE_NULL;
qse_awk_rtx_t* rtx = QSE_NULL; qse_awk_rtx_t* rtx = QSE_NULL;
qse_awk_val_t* retv; qse_awk_val_t* retv;
qse_awk_parsestd_in_t psin; qse_awk_parsestd_t psin;
int ret = -1; int ret = -1;
const qse_char_t* output_files[] = const qse_char_t* output_files[] =
@ -65,8 +65,9 @@ int main ()
qse_awk_setoption (awk, qse_awk_getoption(awk) | QSE_AWK_NEXTOFILE); qse_awk_setoption (awk, qse_awk_getoption(awk) | QSE_AWK_NEXTOFILE);
psin.type = QSE_AWK_PARSESTD_CP; psin.type = QSE_AWK_PARSESTD_STR;
psin.u.cp = src; psin.u.str.ptr = src;
psin.u.str.len = qse_strlen(src);
if (qse_awk_parsestd (awk, &psin, QSE_NULL) <= -1) if (qse_awk_parsestd (awk, &psin, QSE_NULL) <= -1)
{ {

View File

@ -30,7 +30,7 @@ int main ()
{ {
qse_awk_t* awk = QSE_NULL; qse_awk_t* awk = QSE_NULL;
qse_awk_rtx_t* rtx = QSE_NULL; qse_awk_rtx_t* rtx = QSE_NULL;
qse_awk_parsestd_in_t psin; qse_awk_parsestd_t psin;
qse_awk_val_t* rtv = QSE_NULL; qse_awk_val_t* rtv = QSE_NULL;
qse_awk_val_t* arg = QSE_NULL; qse_awk_val_t* arg = QSE_NULL;
int ret, i, opt; int ret, i, opt;
@ -65,8 +65,9 @@ int main ()
qse_awk_setoption (awk, opt); qse_awk_setoption (awk, opt);
psin.type = QSE_AWK_PARSESTD_CP; psin.type = QSE_AWK_PARSESTD_STR;
psin.u.cp = src; psin.u.str.ptr = src;
psin.u.str.len = qse_strlen(src);
ret = qse_awk_parsestd (awk, &psin, QSE_NULL); ret = qse_awk_parsestd (awk, &psin, QSE_NULL);
if (ret == -1) if (ret == -1)

View File

@ -17,6 +17,12 @@
} while (0) } while (0)
static int test1 (void) static int test1 (void)
{
qse_printf (QSE_T("slmblenmax=%d\n"), (int)qse_slmblenmax());
return 0;
}
static int test2 (void)
{ {
int i; int i;
const qse_mchar_t* x[] = const qse_mchar_t* x[] =
@ -80,9 +86,9 @@ static int test1 (void)
return 0; return 0;
} }
static int test2 (void) static int test3 (void)
{ {
const qse_wchar_t unistr[] = const qse_wchar_t unistr_kr[] =
{ {
/*L"\uB108 \uBB50\uAC00 \uC798\uB0AC\uC5B4!",*/ /*L"\uB108 \uBB50\uAC00 \uC798\uB0AC\uC5B4!",*/
0xB108, 0xB108,
@ -97,16 +103,31 @@ static int test2 (void)
L'\0' L'\0'
}; };
const qse_wchar_t unistr_cn[] =
{
/* 智慧手機帶頭 */
/* \u667A\u6167\u624B\u6A5F\u5E36\u982D */
0x667A,
0x6167,
0x624B,
0x6A5F,
0x5E36,
0x982D,
L'\0'
};
const qse_wchar_t* x[] = const qse_wchar_t* x[] =
{ {
L"\0", L"\0",
L"", L"",
L"",
L"Fly to the universe" L"Fly to the universe"
}; };
char buf[100]; char buf[100];
int i, j; int i, j;
x[1] = unistr; x[1] = unistr_kr;
x[2] = unistr_cn;
for (i = 0; i < QSE_COUNTOF(x); i++) for (i = 0; i < QSE_COUNTOF(x); i++)
{ {
@ -162,6 +183,15 @@ int main ()
setlocale (LC_ALL, locale); setlocale (LC_ALL, locale);
qse_setdflcmgr (qse_slmbcmgr); qse_setdflcmgr (qse_slmbcmgr);
} }
#if 0
{
WORD LangID = MAKELANGID(LANG_CHINESE, SUBLANG_DEFAULT);
SetThreadLocale(MAKELCID(LangID, SORT_DEFAULT));
/* SetThreadUILanguage(), SetThreadPreferredUILanguage(). */
}
#endif
#else #else
setlocale (LC_ALL, ""); setlocale (LC_ALL, "");
qse_setdflcmgr (qse_slmbcmgr); qse_setdflcmgr (qse_slmbcmgr);
@ -169,6 +199,7 @@ int main ()
R (test1); R (test1);
R (test2); R (test2);
R (test3);
return 0; return 0;
} }

View File

@ -48,7 +48,7 @@ int sed_main (int argc, qse_char_t* argv[])
goto oops; goto oops;
} }
if (qse_sed_compstdmem (sed, argv[1]) <= -1) if (qse_sed_compstdstr (sed, argv[1]) <= -1)
{ {
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_sed_geterrmsg(sed)); qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_sed_geterrmsg(sed));
goto oops; goto oops;
@ -57,7 +57,7 @@ int sed_main (int argc, qse_char_t* argv[])
infile = (argc >= 3)? argv[2]: QSE_NULL; infile = (argc >= 3)? argv[2]: QSE_NULL;
outfile = (argc >= 4)? argv[3]: QSE_NULL; outfile = (argc >= 4)? argv[3]: QSE_NULL;
if (qse_sed_execstdfile (sed, infile, outfile) <= -1) if (qse_sed_execstdfile (sed, infile, outfile, QSE_NULL) <= -1)
{ {
qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_sed_geterrmsg(sed)); qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_sed_geterrmsg(sed));
goto oops; goto oops;