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/xma.h>
#include <string.h>
#include <signal.h>
#include <stdarg.h>
@ -69,7 +68,6 @@ struct arg_t
} isp;
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** 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 */
arg->ist = QSE_AWK_PARSESTD_CP;
arg->ist = QSE_AWK_PARSESTD_STR;
arg->isp.str = argv[opt.ind++];
free (isf);
@ -714,7 +712,6 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
icf[icfl] = QSE_NULL;
}
arg->ost = QSE_AWK_PARSESTD_FILE;
arg->osf = osf;
arg->icf = icf;
@ -855,8 +852,8 @@ static int awk_main (int argc, qse_char_t* argv[])
int ret = -1;
/* TODO: change it to support multiple source files */
qse_awk_parsestd_in_t psin;
qse_awk_parsestd_out_t psout;
qse_awk_parsestd_t psin;
qse_awk_parsestd_t psout;
qse_mmgr_t* mmgr = QSE_MMGR_GETDFL();
memset (&arg, 0, QSE_SIZEOF(arg));
@ -869,13 +866,22 @@ static int awk_main (int argc, qse_char_t* argv[])
}
psin.type = arg.ist;
if (arg.ist == QSE_AWK_PARSESTD_CP) psin.u.cp = arg.isp.str;
else psin.u.file = arg.isp.files[0];
if (arg.ist == QSE_AWK_PARSESTD_STR)
{
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)
{
psout.type = arg.ost;
psout.u.file = arg.osf;
psout.type = QSE_AWK_PARSESTD_FILE;
psout.u.file.path = arg.osf;
psout.u.file.cmgr = QSE_NULL;
}
#if defined(QSE_BUILD_DEBUG)

View File

@ -184,17 +184,18 @@ static int add_script (const qse_char_t* str, int 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,
* 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.mem.len = qse_strlen(str);
g_script.io[g_script.size].u.str.ptr = (qse_char_t*)str;
g_script.io[g_script.size].u.str.len = qse_strlen(str);
}
else
{
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;
g_script.io[g_script.size].u.file.cmgr = QSE_NULL;
}
g_script.size++;
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)
{
target = g_script.io[script_count].u.file;
target = g_script.io[script_count].u.file.path;
}
else
{
/* 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_T("expression #%lu"), (unsigned long)script_count);
target = exprbuf;
@ -663,15 +664,16 @@ 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 =
in[0].u.file.path =
(qse_strcmp (argv[g_infile_pos], QSE_T("-")) == 0)?
QSE_NULL: argv[g_infile_pos];
in[0].u.file.cmgr = QSE_NULL;
in[1].type = QSE_SED_IOSTD_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)
{
qse_fprintf (QSE_STDERR, QSE_T("ERROR: out of memory\n"));
@ -721,10 +723,10 @@ TODO:
qse_sio_close (output->u.sio);
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"),
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);
goto oops;
}
@ -762,9 +764,10 @@ TODO:
for (i = 0; i < num_ins; i++)
{
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_NULL: argv[g_infile_pos];
in[i].u.file.cmgr = QSE_NULL;
g_infile_pos++;
}
@ -774,9 +777,10 @@ TODO:
if (g_output_file)
{
out.type = QSE_SED_IOSTD_FILE;
out.u.file =
out.u.file.path =
(qse_strcmp (g_output_file, QSE_T("-")) == 0)?
QSE_NULL: g_output_file;
out.u.file.cmgr = QSE_NULL;
}
g_sed = sed;

View File

@ -4,8 +4,6 @@
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.
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
provided by underlying operating systems: HeapAlloc/HeapReAlloc/HeapFree

View File

@ -22,6 +22,7 @@
#define _QSE_AWK_STD_H_
#include <qse/awk/awk.h>
#include <qse/cmn/sio.h>
/** @file
* 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.
*/
/**
* The qse_awk_parsestd_type_t type defines a source script type
*/
enum qse_awk_parsestd_type_t
{
QSE_AWK_PARSESTD_FILE = 0, /**< file name */
QSE_AWK_PARSESTD_CP = 1, /**< character pointer */
QSE_AWK_PARSESTD_CPL = 2, /**< character pointer + length */
QSE_AWK_PARSESTD_STDIO = 3 /**< standard input/output */
QSE_AWK_PARSESTD_FILE = 1,
QSE_AWK_PARSESTD_STR = 2
};
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;
union
{
const qse_char_t* file;
const qse_char_t* cp;
qse_cstr_t cpl;
qse_sio_t* sio;
struct
{
const qse_char_t* path;
qse_cmgr_t* cmgr;
} file;
qse_xstr_t str;
} u;
};
typedef struct qse_awk_parsestd_in_t qse_awk_parsestd_in_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;
typedef struct qse_awk_parsestd_t qse_awk_parsestd_t;
#ifdef __cplusplus
extern "C" {
@ -137,8 +123,8 @@ void* qse_awk_getxtnstd (
*/
int qse_awk_parsestd (
qse_awk_t* awk,
const qse_awk_parsestd_in_t* in,
qse_awk_parsestd_out_t* out
qse_awk_parsestd_t* in,
qse_awk_parsestd_t* out
);
/**

View File

@ -24,6 +24,12 @@
#include <qse/types.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
@ -114,7 +120,7 @@ qse_size_t qse_slmblen (
* The qse_slmblenmax() function returns the value of MB_CUR_MAX.
* Note that QSE_MBLEN_MAX defines MB_LEN_MAX.
*/
int qse_slmblenmax (
qse_size_t qse_slmblenmax (
void
);

View File

@ -24,6 +24,14 @@
#include <qse/types.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
# define QSE_UTF8LEN_MAX 3
#elif QSE_SIZEOF_WCHAR_T == 4
@ -36,24 +44,19 @@
extern "C" {
#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.
* @return
* - 0 is returned if @a uc is invalid.
* - An integer greater than @a size is returned if the utf8 sequence buffer is
* not large enough.
* - An integer greater than @a size is returned if the @a utf8 sequence buffer
* 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.
* @note
* This function doesn't check invalid unicode code points and performs
* conversion compuationally.
*/
qse_size_t qse_uctoutf8 (
qse_wchar_t uc,
@ -61,17 +64,40 @@ qse_size_t qse_uctoutf8 (
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 (
const qse_mchar_t* utf8,
qse_size_t size,
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 (
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 (
void
);

View File

@ -46,16 +46,20 @@ struct qse_sed_iostd_t
enum
{
QSE_SED_IOSTD_NULL, /** invalid resource */
QSE_SED_IOSTD_SIO,
QSE_SED_IOSTD_FILE,
QSE_SED_IOSTD_MEM
QSE_SED_IOSTD_STR,
QSE_SED_IOSTD_SIO
} type;
union
{
struct
{
const qse_char_t* path;
qse_cmgr_t* cmgr;
} file;
qse_xstr_t str;
qse_sio_t* sio;
const qse_char_t* file;
qse_xstr_t mem;
} u;
};
@ -113,22 +117,28 @@ int qse_sed_compstd (
/**
* 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
*/
int qse_sed_compstdfile (
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
* in a null-terminated string pointed to by @a str.
* The qse_sed_compstd() function compiles a sed script stored
* in a null-terminated string pointed to by @a script.
* @return 0 on success, -1 on failure
*/
int qse_sed_compstdmem (
int qse_sed_compstdstr (
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 (
qse_sed_t* sed,
const qse_char_t* infile,
const qse_char_t* outfile
const qse_char_t* outfile,
qse_cmgr_t* cmgr
);
#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);
/**
* 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
* for memory management functions with a pointer to user-defined data.
* 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
* 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
{

View File

@ -169,7 +169,7 @@ int StdAwk::openPipe (Pipe& io)
{
Awk::Pipe::Mode mode = io.getMode();
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)
{

View File

@ -58,36 +58,40 @@ typedef struct xtn_t
{
struct
{
qse_awk_parsestd_type_t type;
qse_awk_parsestd_t* x;
union
{
const qse_char_t* file;
const qse_char_t* cp;
struct
{
qse_sio_t* sio; /* the handle to an open file */
qse_cstr_t dir;
} file;
struct
{
const qse_char_t* ptr;
const qse_char_t* end;
} cpl;
} str;
} u;
qse_cstr_t dir;
qse_sio_t* handle; /* the handle to an open file */
} in;
struct
{
qse_awk_parsestd_type_t type;
qse_awk_parsestd_t* x;
union
{
const qse_char_t* file;
qse_char_t* cp;
struct
{
qse_xstr_t* osp;
qse_sio_t* sio;
} file;
struct
{
qse_str_t* buf;
#if 0
qse_char_t* ptr;
qse_char_t* end;
} cpl;
#endif
} str;
} u;
qse_sio_t* handle;
} out;
} 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;
}
static const qse_char_t* sio_std_names[] =
struct sio_std_name_t
{
QSE_T("stdin"),
QSE_T("stdout"),
QSE_T("stderr"),
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_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)
{
qse_cstr_t ea;
ea.ptr = sio_std_names[std];
ea.len = qse_strlen (sio_std_names[std]);
ea.ptr = sio_std_names[std].ptr;
ea.len = sio_std_names[std].len;
qse_awk_seterrnum (awk, QSE_AWK_EOPEN, &ea);
}
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)
{
qse_cstr_t ea;
ea.ptr = sio_std_names[std];
ea.len = qse_strlen (sio_std_names[std]);
ea.ptr = sio_std_names[std].ptr;
ea.len = sio_std_names[std].len;
qse_awk_rtx_seterrnum (rtx, QSE_AWK_EOPEN, &ea);
}
return sio;
@ -379,47 +389,42 @@ static qse_ssize_t sf_in_open (
{
if (arg == QSE_NULL || arg->name == QSE_NULL)
{
switch (xtn->s.in.type)
switch (xtn->s.in.x->type)
{
case QSE_AWK_PARSESTD_FILE:
if (xtn->s.in.u.file == QSE_NULL) return -1;
if (xtn->s.in.u.file[0] == QSE_T('-') &&
xtn->s.in.u.file[1] == QSE_T('\0'))
if (xtn->s.in.x->u.file.path == QSE_NULL ||
(xtn->s.in.x->u.file.path[0] == QSE_T('-') &&
xtn->s.in.x->u.file.path[1] == QSE_T('\0')))
{
/* 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);
if (xtn->s.in.handle == QSE_NULL) return -1;
if (xtn->s.in.u.file.sio == QSE_NULL) return -1;
}
else
{
const qse_char_t* base;
xtn->s.in.handle = open_sio (
awk, xtn->s.in.u.file,
xtn->s.in.u.file.sio = open_sio (
awk, xtn->s.in.x->u.file.path,
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);
if (base != xtn->s.in.u.file)
base = qse_basename (xtn->s.in.x->u.file.path);
if (base != xtn->s.in.x->u.file.path)
{
xtn->s.in.dir.ptr = xtn->s.in.u.file;
xtn->s.in.dir.len = base - xtn->s.in.u.file;
xtn->s.in.u.file.dir.ptr = xtn->s.in.x->u.file.path;
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;
case QSE_AWK_PARSESTD_STDIO:
xtn->s.in.handle = open_sio_std (
awk, QSE_SIO_STDIN, QSE_SIO_READ | QSE_SIO_IGNOREMBWCERR);
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;
case QSE_AWK_PARSESTD_STR:
xtn->s.in.u.str.ptr = xtn->s.in.x->u.str.ptr;
xtn->s.in.u.str.end = xtn->s.in.x->u.str.ptr + xtn->s.in.x->u.str.len;
return 1;
}
@ -433,11 +438,11 @@ static qse_ssize_t sf_in_open (
qse_char_t fbuf[64];
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;
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))
{
dbuf = QSE_MMGR_ALLOC (
@ -456,8 +461,8 @@ static qse_ssize_t sf_in_open (
tmplen = qse_strncpy (
(qse_char_t*)file,
xtn->s.in.dir.ptr,
xtn->s.in.dir.len
xtn->s.in.u.file.dir.ptr,
xtn->s.in.u.file.dir.len
);
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 (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
{
@ -502,41 +516,38 @@ static qse_ssize_t sf_in_read (
{
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_STDIO:
{
qse_ssize_t n;
QSE_ASSERT (xtn->s.in.handle != QSE_NULL);
n = qse_sio_getstrn (xtn->s.in.handle, data, size);
if (n == -1)
QSE_ASSERT (xtn->s.in.u.file.sio != QSE_NULL);
n = qse_sio_getstrn (xtn->s.in.u.file.sio, data, size);
if (n <= -1)
{
qse_cstr_t ea;
ea.ptr = xtn->s.in.u.file;
if (xtn->s.in.x->u.file.path)
{
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);
}
return n;
}
case QSE_AWK_PARSESTD_CP:
case QSE_AWK_PARSESTD_STR:
{
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++;
}
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++;
data[n++] = *xtn->s.in.u.str.ptr++;
}
return n;
}
@ -551,7 +562,7 @@ static qse_ssize_t sf_in_read (
QSE_ASSERT (arg->handle != QSE_NULL);
n = qse_sio_getstrn (arg->handle, data, size);
if (n == -1)
if (n <= -1)
{
qse_cstr_t ea;
ea.ptr = arg->name;
@ -595,43 +606,42 @@ static qse_ssize_t sf_out (
{
case QSE_AWK_SIO_OPEN:
{
switch (xtn->s.out.type)
switch (xtn->s.out.x->type)
{
case QSE_AWK_PARSESTD_FILE:
if (xtn->s.out.u.file == QSE_NULL) return -1;
if (xtn->s.out.u.file[0] == QSE_T('-') &&
xtn->s.out.u.file[1] == QSE_T('\0'))
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 '-' */
xtn->s.out.handle = open_sio_std (
xtn->s.out.u.file.sio = open_sio_std (
awk, QSE_SIO_STDOUT,
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
{
xtn->s.out.handle = open_sio (
awk, xtn->s.out.u.file,
xtn->s.out.u.file.sio = open_sio (
awk, xtn->s.out.x->u.file.path,
QSE_SIO_WRITE | QSE_SIO_CREATE |
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;
case QSE_AWK_PARSESTD_STDIO:
xtn->s.out.handle = open_sio_std (
awk, QSE_SIO_STDOUT,
QSE_SIO_WRITE | QSE_SIO_IGNOREMBWCERR
);
if (xtn->s.out.handle == QSE_NULL) return -1;
return 1;
case QSE_AWK_PARSESTD_STR:
xtn->s.out.u.str.buf = qse_str_open (awk->mmgr, 0, 512);
if (xtn->s.out.u.str.buf == QSE_NULL)
{
qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
return -1;
}
case QSE_AWK_PARSESTD_CP:
case QSE_AWK_PARSESTD_CPL:
xtn->s.out.handle = QSE_NULL;
return 1;
}
@ -641,23 +651,15 @@ static qse_ssize_t sf_out (
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_STDIO:
qse_sio_flush (xtn->s.out.handle);
qse_sio_close (xtn->s.out.handle);
qse_sio_close (xtn->s.out.u.file.sio);
return 0;
case QSE_AWK_PARSESTD_CP:
*xtn->s.out.u.cp = QSE_T('\0');
return 0;
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;
case QSE_AWK_PARSESTD_STR:
/* i don't close xtn->s.out.u.str.buf intentionally here.
* it will be closed at the end of qse_awk_parsestd() */
return 0;
}
@ -666,43 +668,41 @@ static qse_ssize_t sf_out (
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_STDIO:
{
qse_ssize_t n;
QSE_ASSERT (xtn->s.out.handle != QSE_NULL);
n = qse_sio_putstrn (xtn->s.out.handle, data, size);
if (n == -1)
QSE_ASSERT (xtn->s.out.u.file.sio != QSE_NULL);
n = qse_sio_putstrn (xtn->s.out.u.file.sio, data, size);
if (n <= -1)
{
qse_cstr_t ea;
ea.ptr = xtn->s.in.u.file;
if (xtn->s.out.x->u.file.path)
{
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);
}
return n;
}
case QSE_AWK_PARSESTD_CP:
case QSE_AWK_PARSESTD_STR:
{
qse_size_t n = 0;
while (n < size && *xtn->s.out.u.cp != QSE_T('\0'))
if (size > QSE_TYPE_MAX(qse_ssize_t)) size = QSE_TYPE_MAX(qse_ssize_t);
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;
}
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;
return size;
}
}
@ -715,12 +715,11 @@ static qse_ssize_t sf_out (
}
int qse_awk_parsestd (
qse_awk_t* awk,
const qse_awk_parsestd_in_t* in,
qse_awk_parsestd_out_t* out)
qse_awk_t* awk, qse_awk_parsestd_t* in, qse_awk_parsestd_t* out)
{
qse_awk_sio_t sio;
xtn_t* xtn = (xtn_t*) QSE_XTN (awk);
int n;
if (in == QSE_NULL)
{
@ -729,67 +728,41 @@ int qse_awk_parsestd (
return -1;
}
switch (in->type)
if (in->type != QSE_AWK_PARSESTD_FILE &&
in->type != QSE_AWK_PARSESTD_STR)
{
case QSE_AWK_PARSESTD_FILE:
xtn->s.in.u.file = in->u.file;
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;
xtn->s.in.x = in;
if (out == QSE_NULL) sio.out = QSE_NULL;
else
{
switch (out->type)
if (out->type != QSE_AWK_PARSESTD_FILE &&
out->type != QSE_AWK_PARSESTD_STR)
{
case QSE_AWK_PARSESTD_FILE:
xtn->s.out.u.file = out->u.file;
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;
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 ***/
@ -827,7 +800,7 @@ static qse_ssize_t awk_rio_pipe (
0,
riod->name,
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;
@ -1271,6 +1244,13 @@ static qse_ssize_t awk_rio_console (
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_t* awk,
qse_size_t xtnsize,

View File

@ -37,59 +37,31 @@
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
qse_size_t qse_slmbrlen (
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;
#if defined(_WIN32)
# include <windows.h>
#endif
#else
#error #### NOT SUPPORTED ####
#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_wchar_t wc, qse_mchar_t* mb,
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;
if (mbl < QSE_MBLEN_MAX)
@ -123,6 +95,90 @@ qse_size_t qse_slwcrtoslmb (
#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
* 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
@ -131,11 +187,6 @@ qse_size_t qse_slwcrtoslmb (
* mbrtowc(3) do produce non-initial states when interrupted in the middle
* 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)
{
@ -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);
}
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,28 +73,15 @@ static QSE_INLINE __utf8_t* get_utf8_slot (qse_wchar_t uc)
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)
{
__utf8_t* cur = get_utf8_slot (uc);
int index;
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
* size needed */
return size + 1;
}
index = cur->length;
int index = cur->length;
while (index > 1)
{
/*
@ -106,20 +93,20 @@ qse_size_t qse_uctoutf8 (qse_wchar_t uc, qse_mchar_t* utf8, qse_size_t size)
}
utf8[0] = uc | cur->fbyte;
}
/* small buffer is also indicated by this return value
* greater than 'size'. */
return (qse_size_t)cur->length;
}
/* mbtowc for utf8/unicode */
qse_size_t qse_utf8touc (
const qse_mchar_t* utf8, qse_size_t size, qse_wchar_t* uc)
{
__utf8_t* cur, * end;
#if 0
qse_mchar_t c, t;
int count = 0;
#endif
QSE_ASSERT (utf8 != QSE_NULL);
QSE_ASSERT (size > 0);
QSE_ASSERT (QSE_SIZEOF(qse_mchar_t) == 1);
QSE_ASSERT (QSE_SIZEOF(qse_wchar_t) >= 2);
@ -130,75 +117,30 @@ qse_size_t qse_utf8touc (
{
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
* error is naturally indicated. so validate the string
* only if size is as large as cur->length. */
if (size >= cur->length)
{
int i;
if (uc)
{
qse_wchar_t w;
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;
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
* only if len is as large as cur->length. */
if (len >= cur->length)
else
{
for (i = 1; i < cur->length; i++)
{
@ -207,6 +149,7 @@ qse_size_t qse_utf8len (const qse_mchar_t* utf8, qse_size_t len)
if (!(utf8[i] & 0x80)) return 0;
}
}
}
/* this return value can indicate both
* the correct length (len >= cur->length)
@ -221,7 +164,13 @@ qse_size_t qse_utf8len (const qse_mchar_t* utf8, qse_size_t len)
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)
{
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));
}
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;
@ -79,23 +79,29 @@ static qse_sio_t* open_sio (qse_cut_t* cut, const qse_char_t* file, int flags)
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 const qse_char_t* sio_std_names[] =
{
QSE_T("stdin"),
QSE_T("stdout"),
QSE_T("stderr"),
};
qse_sio_t* sio;
sio = qse_sio_openstd (cut->mmgr, 0, std, flags);
if (sio == QSE_NULL)
{
qse_cstr_t ea;
ea.ptr = sio_std_names[std];
ea.len = qse_strlen (sio_std_names[std]);
ea.ptr = sio_std_names[std].ptr;
ea.len = sio_std_names[std].len;
qse_cut_seterrnum (cut, QSE_CUT_EIOFIL, &ea);
}
return sio;
@ -114,7 +120,7 @@ static qse_ssize_t xin (
{
/* main data stream */
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);
if (sio == QSE_NULL) return -1;
arg->handle = sio;
@ -132,15 +138,20 @@ static qse_ssize_t xin (
{
qse_ssize_t n = qse_sio_getstrn (arg->handle, buf, len);
if (n == -1)
{
if (xtn->infile)
if (n <= -1)
{
qse_cstr_t ea;
if (xtn->infile)
{
ea.ptr = 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;
@ -163,7 +174,7 @@ static qse_ssize_t xout (
case QSE_CUT_IO_OPEN:
{
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);
if (sio == QSE_NULL) return -1;
arg->handle = sio;
@ -182,15 +193,20 @@ static qse_ssize_t xout (
{
qse_ssize_t n = qse_sio_putstrn (arg->handle, dat, len);
if (n == -1)
{
if (xtn->outfile)
if (n <= -1)
{
qse_cstr_t ea;
if (xtn->outfile)
{
ea.ptr = 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;
@ -202,6 +218,7 @@ static qse_ssize_t xout (
}
/* 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)
{
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.
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 &&
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);
return -1;
@ -146,7 +146,7 @@ static int verify_iostd_in (qse_sed_t* sed, qse_sed_iostd_t in[])
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;
@ -161,11 +161,17 @@ static qse_sio_t* open_sio (qse_sed_t* sed, const qse_char_t* file, int flags)
return sio;
}
static const qse_char_t* sio_std_names[] =
struct sio_std_name_t
{
QSE_T("stdin"),
QSE_T("stdout"),
QSE_T("stderr"),
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_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)
{
qse_cstr_t ea;
ea.ptr = sio_std_names[std];
ea.len = qse_strlen (sio_std_names[std]);
ea.ptr = sio_std_names[std].ptr;
ea.len = sio_std_names[std].len;
qse_sed_seterrnum (sed, QSE_SED_EIOFIL, &ea);
}
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 (
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 (
@ -204,15 +227,16 @@ static int open_input_stream (
case QSE_SED_IOSTD_FILE:
{
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 (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 (io->u.file.cmgr) qse_sio_setcmgr (sio, io->u.file.cmgr);
arg->handle = sio;
break;
}
case QSE_SED_IOSTD_MEM:
case QSE_SED_IOSTD_STR:
/* don't store anything to arg->handle */
base->mempos = 0;
break;
@ -220,7 +244,7 @@ static int open_input_stream (
default:
QSE_ASSERTX (
!"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);
return -1;
@ -234,8 +258,8 @@ static int open_input_stream (
{
qse_sed_setcompid (
sed,
((io->u.file == QSE_NULL)?
sio_std_names[QSE_SIO_STDIN]: io->u.file)
((io->u.file.path == QSE_NULL)?
sio_std_names[QSE_SIO_STDIN].ptr: io->u.file.path)
);
}
else
@ -243,7 +267,7 @@ static int open_input_stream (
qse_char_t buf[64];
/* 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('#');
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:
{
qse_sio_t* sio;
if (io->u.file == QSE_NULL)
if (io->u.file.path == QSE_NULL)
{
sio = open_sio_std (
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
{
sio = open_sio (
sed, io->u.file,
sio = open_sio_file (
sed, io->u.file.path,
QSE_SIO_WRITE |
QSE_SIO_CREATE |
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 (io->u.file.cmgr) qse_sio_setcmgr (sio, io->u.file.cmgr);
arg->handle = sio;
break;
}
case QSE_SED_IOSTD_MEM:
case QSE_SED_IOSTD_STR:
/* don't store anything to arg->handle */
xtn->e.out.memstr = qse_str_open (sed->mmgr, 0, 512);
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:
QSE_ASSERTX (
!"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);
return -1;
@ -341,13 +366,14 @@ static qse_ssize_t read_input_stream (
QSE_ASSERT (io != QSE_NULL);
if (io->type == QSE_SED_IOSTD_MEM)
if (io->type == QSE_SED_IOSTD_STR)
{
n = 0;
while (base->mempos < io->u.mem.len && n < len)
buf[n++] = io->u.mem.ptr[base->mempos++];
while (base->mempos < io->u.str.len && n < len)
buf[n++] = io->u.str.ptr[base->mempos++];
}
else n = qse_sio_getstrn (arg->handle, buf, len);
if (n != 0)
{
if (n <= -1)
@ -355,8 +381,16 @@ static qse_ssize_t read_input_stream (
if (io->type == QSE_SED_IOSTD_FILE)
{
qse_cstr_t ea;
ea.ptr = io->u.file;
ea.len = qse_strlen (io->u.file);
if (io->u.file.path)
{
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);
}
}
@ -398,8 +432,16 @@ static qse_ssize_t read_input_stream (
if (next->type == QSE_SED_IOSTD_FILE)
{
qse_cstr_t ea;
ea.ptr = next->u.file;
ea.len = qse_strlen (next->u.file);
if (next->u.file.path)
{
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);
}
@ -489,7 +531,7 @@ static qse_ssize_t x_in (
}
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;
arg->handle = sio;
}
@ -527,8 +569,8 @@ static qse_ssize_t x_in (
if (n <= -1)
{
qse_cstr_t ea;
ea.ptr = QSE_T("stdin");
ea.len = 5;
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);
}
return n;
@ -593,7 +635,7 @@ static qse_ssize_t x_out (
}
else
{
sio = open_sio (
sio = open_sio_file (
sed, arg->path,
QSE_SIO_WRITE |
QSE_SIO_CREATE |
@ -635,8 +677,8 @@ static qse_ssize_t x_out (
if (n <= -1)
{
qse_cstr_t ea;
ea.ptr = QSE_T("stdin");
ea.len = 5;
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);
}
return n;
@ -644,7 +686,7 @@ static qse_ssize_t x_out (
else
{
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);
@ -663,8 +705,16 @@ static qse_ssize_t x_out (
if (n <= -1)
{
qse_cstr_t ea;
ea.ptr = io->u.file;
ea.len = qse_strlen(io->u.file);
if (io->u.file.path)
{
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);
}
return n;
@ -732,7 +782,7 @@ int qse_sed_execstd (
{
if (out->type != QSE_SED_IOSTD_SIO &&
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);
return -1;
@ -746,41 +796,47 @@ int qse_sed_execstd (
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)
{
if (n >= 0)
{
QSE_ASSERT (xtn->e.out.memstr != QSE_NULL);
qse_str_yield (xtn->e.out.memstr, &out->u.mem, 0);
qse_str_yield (xtn->e.out.memstr, &out->u.str, 0);
}
if (xtn->e.out.memstr) qse_str_close (xtn->e.out.memstr);
}
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];
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;
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];
in[0].type = QSE_SED_IOSTD_MEM;
in[0].u.mem.ptr = script;
in[0].u.mem.len = qse_strlen(script);
in[0].type = QSE_SED_IOSTD_STR;
in[0].u.str.ptr = script;
in[0].u.str.len = qse_strlen(script);
in[1].type = QSE_SED_IOSTD_NULL;
return qse_sed_compstd (sed, in, QSE_NULL);
}
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 out;
@ -789,7 +845,8 @@ int qse_sed_execstdfile (
if (infile)
{
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;
pin = in;
}
@ -797,7 +854,8 @@ int qse_sed_execstdfile (
if (outfile)
{
out.type = QSE_SED_IOSTD_FILE;
out.u.file = outfile;
out.u.file.path = outfile;
out.u.file.cmgr = cmgr;
pout = &out;
}

View File

@ -37,7 +37,7 @@ int main ()
qse_awk_t* awk = QSE_NULL;
qse_awk_rtx_t* rtx = QSE_NULL;
qse_awk_val_t* retv;
qse_awk_parsestd_in_t psin;
qse_awk_parsestd_t psin;
int ret = -1;
awk = qse_awk_openstd (0);
@ -47,8 +47,9 @@ int main ()
goto oops;
}
psin.type = QSE_AWK_PARSESTD_CP;
psin.u.cp = src;
psin.type = QSE_AWK_PARSESTD_STR;
psin.u.str.ptr = src;
psin.u.str.len = qse_strlen(src);
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 ()
{
qse_awk_t* awk = QSE_NULL;
qse_awk_rtx_t* rtx = QSE_NULL;
qse_awk_val_t* retv;
qse_awk_parsestd_in_t psin;
qse_awk_parsestd_out_t psout;
qse_awk_parsestd_t psin;
qse_awk_parsestd_t psout;
int ret;
@ -54,13 +52,13 @@ int main ()
ret = -1; goto oops;
}
qse_memset (srcout, QSE_T(' '), QSE_COUNTOF(srcout)-1);
srcout[QSE_COUNTOF(srcout)-1] = QSE_T('\0');
psin.type = QSE_AWK_PARSESTD_STR;
psin.u.str.ptr = src;
psin.u.str.len = qse_strlen(src);
psin.type = QSE_AWK_PARSESTD_CP;
psin.u.cp = src;
psout.type = QSE_AWK_PARSESTD_CP;
psout.u.cp = srcout;
psout.type = QSE_AWK_PARSESTD_STR;
/* ps.out.u.str.ptr and ps.out.u.str.len are set when qse_awk_parsestd()
* returns success */
ret = qse_awk_parsestd (awk, &psin, &psout);
if (ret <= -1)
@ -70,10 +68,12 @@ int main ()
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_fflush (QSE_STDOUT);
QSE_MMGR_FREE (qse_awk_getmmgr(awk), psout.u.str.ptr);
rtx = qse_awk_rtx_openstd (
awk,
0,

View File

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

View File

@ -30,7 +30,7 @@ int main ()
{
qse_awk_t* awk = 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_size_t len;
qse_awk_val_t* rtv = QSE_NULL;
@ -58,8 +58,9 @@ int main ()
qse_awk_setoption (awk, opt);
psin.type = QSE_AWK_PARSESTD_CP;
psin.u.cp = src;
psin.type = QSE_AWK_PARSESTD_STR;
psin.u.str.ptr = src;
psin.u.str.len = qse_strlen(src);
ret = qse_awk_parsestd (awk, &psin, QSE_NULL);
if (ret == -1)

View File

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

View File

@ -17,6 +17,12 @@
} while (0)
static int test1 (void)
{
qse_printf (QSE_T("slmblenmax=%d\n"), (int)qse_slmblenmax());
return 0;
}
static int test2 (void)
{
int i;
const qse_mchar_t* x[] =
@ -80,9 +86,9 @@ static int test1 (void)
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!",*/
0xB108,
@ -97,16 +103,31 @@ static int test2 (void)
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[] =
{
L"\0",
L"",
L"",
L"Fly to the universe"
};
char buf[100];
int i, j;
x[1] = unistr;
x[1] = unistr_kr;
x[2] = unistr_cn;
for (i = 0; i < QSE_COUNTOF(x); i++)
{
@ -162,6 +183,15 @@ int main ()
setlocale (LC_ALL, locale);
qse_setdflcmgr (qse_slmbcmgr);
}
#if 0
{
WORD LangID = MAKELANGID(LANG_CHINESE, SUBLANG_DEFAULT);
SetThreadLocale(MAKELCID(LangID, SORT_DEFAULT));
/* SetThreadUILanguage(), SetThreadPreferredUILanguage(). */
}
#endif
#else
setlocale (LC_ALL, "");
qse_setdflcmgr (qse_slmbcmgr);
@ -169,6 +199,7 @@ int main ()
R (test1);
R (test2);
R (test3);
return 0;
}

View File

@ -48,7 +48,7 @@ int sed_main (int argc, qse_char_t* argv[])
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));
goto oops;
@ -57,7 +57,7 @@ int sed_main (int argc, qse_char_t* argv[])
infile = (argc >= 3)? argv[2]: 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));
goto oops;