From dc0203008e088808c17c0045aa44e567d3634b57 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Tue, 14 Oct 2008 05:32:58 +0000 Subject: [PATCH] porting tio from xpkit --- ase/cmd/awk/awk.c | 13 +- ase/include/ase/awk/awk.h | 11 +- ase/include/ase/cmn/makefile.am | 2 +- ase/include/ase/cmn/makefile.in | 2 +- ase/include/ase/cmn/tio.h | 271 ++++++++++++++++++++++++++++++++ ase/include/ase/utl/stdio.h | 10 +- ase/lib/awk/makefile.in | 4 +- ase/lib/awk/std.c | 83 +++++++--- ase/lib/cmn/chr.c | 13 ++ ase/lib/cmn/lda.c | 8 +- ase/lib/cmn/makefile.am | 1 + ase/lib/cmn/makefile.in | 7 +- ase/lib/cmn/sll.c | 8 +- ase/lib/cmn/tio.c | 222 ++++++++++++++++++++++++++ ase/lib/cmn/tio_get.c | 156 ++++++++++++++++++ ase/lib/cmn/tio_put.c | 152 ++++++++++++++++++ 16 files changed, 917 insertions(+), 46 deletions(-) create mode 100644 ase/include/ase/cmn/tio.h create mode 100644 ase/lib/cmn/tio.c create mode 100644 ase/lib/cmn/tio_get.c create mode 100644 ase/lib/cmn/tio_put.c diff --git a/ase/cmd/awk/awk.c b/ase/cmd/awk/awk.c index a09af8e8..58953d18 100644 --- a/ase/cmd/awk/awk.c +++ b/ase/cmd/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c 417 2008-10-12 15:08:26Z baconevi $ + * $Id: awk.c 419 2008-10-13 11:32:58Z baconevi $ */ #include @@ -903,6 +903,7 @@ static int handle_args (int argc, ase_char_t* argv[], struct argout_t* ao) { ASE_T(":main"), ASE_T('m') }, { ASE_T(":file"), ASE_T('f') }, { ASE_T(":field-separator"), ASE_T('F') }, + { ASE_T(":deparse-file"), ASE_T('d') }, { ASE_T(":assign"), ASE_T('v') }, { ASE_T("help"), ASE_T('h') } @@ -910,7 +911,7 @@ static int handle_args (int argc, ase_char_t* argv[], struct argout_t* ao) static ase_opt_t opt = { - ASE_T("hm:f:F:v:"), + ASE_T("hm:f:F:d:v:"), lng }; @@ -918,6 +919,7 @@ static int handle_args (int argc, ase_char_t* argv[], struct argout_t* ao) ase_size_t isfc = 16; ase_size_t isfl = 0; ase_char_t** isf = ASE_NULL; + ase_char_t* osf = ASE_NULL; ase_map_t* vm = ASE_NULL; isf = (ase_char_t**)malloc (ASE_SIZEOF(*isf) * isfc); @@ -978,6 +980,12 @@ static int handle_args (int argc, ase_char_t* argv[], struct argout_t* ao) break; } + case ASE_T('d'): + { + osf = opt.arg; + break; + } + case ASE_T('v'): { ase_char_t* eq = ase_strchr(opt.arg, ASE_T('=')); @@ -1052,6 +1060,7 @@ static int handle_args (int argc, ase_char_t* argv[], struct argout_t* ao) /* TODO; remaining args are input(console) file names */ + ao->osf = osf; ao->vm = vm; return 0; diff --git a/ase/include/ase/awk/awk.h b/ase/include/ase/awk/awk.h index e5f2e851..efa91968 100644 --- a/ase/include/ase/awk/awk.h +++ b/ase/include/ase/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h 417 2008-10-12 15:08:26Z baconevi $ + * $Id: awk.h 419 2008-10-13 11:32:58Z baconevi $ * * {License} */ @@ -815,13 +815,12 @@ int ase_awk_parse ( int ase_awk_parsefiles ( - ase_awk_t* awk, - const ase_char_t* isf[] /* input source file names */, - ase_size_t isfl /* the number of input source files */, - const ase_char_t* osf /* an output source file name */ + ase_awk_t* awk, + const ase_char_t*const* isf /* input source file names */, + ase_size_t isfl /* the number of input source files */, + const ase_char_t* osf /* an output source file name */ ); - /** * Executes a parsed program. * diff --git a/ase/include/ase/cmn/makefile.am b/ase/include/ase/cmn/makefile.am index 9d55397e..0048f3f9 100644 --- a/ase/include/ase/cmn/makefile.am +++ b/ase/include/ase/cmn/makefile.am @@ -1,5 +1,5 @@ -pkginclude_HEADERS = mem.h chr.h str.h lda.h map.h rex.h sll.h dll.h opt.h +pkginclude_HEADERS = mem.h chr.h str.h lda.h map.h rex.h sll.h dll.h opt.h tio.h pkgincludedir= $(includedir)/ase/cmn diff --git a/ase/include/ase/cmn/makefile.in b/ase/include/ase/cmn/makefile.in index 5a326008..c94d3926 100644 --- a/ase/include/ase/cmn/makefile.in +++ b/ase/include/ase/cmn/makefile.in @@ -176,7 +176,7 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ -pkginclude_HEADERS = mem.h chr.h str.h lda.h map.h rex.h sll.h dll.h opt.h +pkginclude_HEADERS = mem.h chr.h str.h lda.h map.h rex.h sll.h dll.h opt.h tio.h CLEANFILES = *dist all: all-am diff --git a/ase/include/ase/cmn/tio.h b/ase/include/ase/cmn/tio.h new file mode 100644 index 00000000..26b33d4e --- /dev/null +++ b/ase/include/ase/cmn/tio.h @@ -0,0 +1,271 @@ +/* + * $Id: tio.h,v 1.19 2006/01/01 13:50:24 bacon Exp $ + */ + +#ifndef _ASE_CMN_TIO_H_ +#define _ASE_CMN_TIO_H_ + +#include +#include +#include + +enum +{ + ASE_TIO_ENOERR = 0, + ASE_TIO_ENOMEM, /* out of memory */ + ASE_TIO_ENOSPC, /* no more space */ + ASE_TIO_EILSEQ, /* illegal utf-8 sequence */ + ASE_TIO_ENOINF, /* no input function attached */ + ASE_TIO_EINPUT, /* input function returned an error */ + ASE_TIO_EINPOP, /* input function failed to open */ + ASE_TIO_EINPCL, /* input function failed to close */ + ASE_TIO_ENOUTF, /* no output function attached */ + ASE_TIO_EOUTPT, /* output function returned an error */ + ASE_TIO_EOUTOP, /* output function failed to open */ + ASE_TIO_EOUTCL /* output function failed to close */ +}; + +enum +{ + /* the size of input buffer should be at least equal to or greater + * than the maximum sequence length of the ase_mchar_t string. + * (i.e. 6 for utf8) + */ + ASE_TIO_MAX_INBUF_LEN = 4096, + ASE_TIO_MAX_OUTBUF_LEN = 4096 +}; + +enum +{ + ASE_TIO_IO_OPEN, + ASE_TIO_IO_CLOSE, + ASE_TIO_IO_DATA +}; + + +#define ASE_TIO_MMGR(tio) ((tio)->mmgr) +#define ASE_TIO_ERRNUM(tio) ((tio)->errnum) + +/* + * TYPE: ase_tio_t + * Defines the tio type + * + * DESCRIPTION: + * defines a generic type for text-based IO. When ase_char_t is + * ase_mchar_t, it handles any byte streams. When ase_char_t is ase_wchar_t, + * it handles utf-8 byte streams. + */ +typedef struct ase_tio_t ase_tio_t; + +/* + * TYPE: ase_tio_io_t + * Defines a user-defines IO handler + */ +typedef ase_ssize_t (*ase_tio_io_t) ( + int cmd, void* arg, void* data, ase_size_t size); + +struct ase_tio_t +{ + ase_mmgr_t* mmgr; + int errnum; + + /* io functions */ + ase_tio_io_t input_func; + ase_tio_io_t output_func; + void* input_arg; + void* output_arg; + + /* for housekeeping */ + int input_status; + ase_size_t inbuf_curp; + ase_size_t inbuf_len; + ase_size_t outbuf_len; + + ase_mchar_t inbuf[ASE_TIO_MAX_INBUF_LEN]; + ase_mchar_t outbuf[ASE_TIO_MAX_OUTBUF_LEN]; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * FUNCTION: ase_tio_open + */ +ase_tio_t* ase_tio_open ( + ase_mmgr_t* mmgr, + ase_size_t ext +); + +/* + * FUNCTION: ase_tio_close + */ +int ase_tio_close ( + ase_tio_t* tio +); + +ase_tio_t* ase_tio_init ( + ase_tio_t* tip, + ase_mmgr_t* mmgr +); + +int ase_tio_fini ( + ase_tio_t* tio +); + +/* + * FUNCTION: ase_tio_geterrnum + * Returns an error code + * + * PARAMETERS: + * grep - a grep object + * + * RETURNS: + * Error code set by the last tio function called + */ +int ase_tio_geterrnum (ase_tio_t* tio); + +/* + * FUNCTION: ase_tio_geterrstr + * Translates an error code to a string + * + * PARAMETERS: + * tio - a tio object + * + * RETURNS: + * A pointer to a constant string describing the last error occurred + */ +const ase_char_t* ase_tio_geterrstr (ase_tio_t* tio); + +/* + * FUNCTION: ase_tio_attinp + * Attaches an input handler function + * + * PARAMETERS: + * tio - a tio object + * input - input handler function + * arg - user data to be passed to the input handler + * + * RETURNS: + * 0 on success, -1 on failure + */ +int ase_tio_attinp (ase_tio_t* tio, ase_tio_io_t input, void* arg); + +/* + * FUNCTION: ase_tio_detinp + * Detaches an input handler function + * + * PARAMETERS: + * tio - a tio object + * + * RETURNS: + * 0 on success, -1 on failure + */ +int ase_tio_detinp (ase_tio_t* tio); + +/* + * FUNCTION: ase_tio_attoutp + * Attaches an output handler function + * + * PARAMETERS: + * tio - a tio object + * output - output handler function + * arg - user data to be passed to the output handler + * + * RETURNS: + * 0 on success, -1 on failure + */ +int ase_tio_attoutp (ase_tio_t* tio, ase_tio_io_t output, void* arg); + +/* + * FUNCTION: ase_tio_detoutp + * Detaches an output handler function + * + * PARAMETERS: + * tio - a tio object + * + * RETURNS: + * 0 on success, -1 on failure + */ +int ase_tio_detoutp (ase_tio_t* tio); + + +/* + * FUNCTION: ase_tio_flush + * Flushes the output buffer + * + * PARAMETERS: + * tio - a tio object + * + * RETURNS: + * Number of bytes written on success, -1 on failure + */ +ase_ssize_t ase_tio_flush (ase_tio_t* tio); + +/* + * FUNCTION: ase_tio_purge + * Erases all input and output buffered + * + * PARAMETERS: + * tio - a tio object + * + */ +void ase_tio_purge (ase_tio_t* tio); + +/* + * FUNCTION: ase_tio_getc + * Reads a single character + */ +ase_ssize_t ase_tio_getc (ase_tio_t* tio, ase_char_t* c); + +/* + * FUNCTION: ase_tio_gets + * + * DESCRIPTION: + * inserts a terminating null if there is a room + */ +ase_ssize_t ase_tio_gets (ase_tio_t* tio, ase_char_t* buf, ase_size_t size); + +/* + * FUNCTION: ase_tio_getsx + * + * DESCRIPTION: + * doesn't insert a terminating null character + */ +ase_ssize_t ase_tio_getsx (ase_tio_t* tio, ase_char_t* buf, ase_size_t size); + +/* + * FUNCTION: ase_tio_getstr + */ +ase_ssize_t ase_tio_getstr (ase_tio_t* tio, ase_str_t* buf); + +/* + * FUNCTION: ase_tio_putc + */ +ase_ssize_t ase_tio_putc (ase_tio_t* tio, ase_char_t c); + +/* + * FUNCTION: ase_tio_puts + */ +ase_ssize_t ase_tio_puts (ase_tio_t* tio, const ase_char_t* str); + +/* + * FUNCTION: ase_tio_putsx + */ +ase_ssize_t ase_tio_putsx (ase_tio_t* tio, const ase_char_t* str, ase_size_t size); + +/* + * FUNCTION: ase_tio_putsn + */ +ase_ssize_t ase_tio_putsn (ase_tio_t* tio, ...); + +/* + * FUNCTION: ase_tio_putsxn + */ +ase_ssize_t ase_tio_putsxn (ase_tio_t* tio, ...); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ase/include/ase/utl/stdio.h b/ase/include/ase/utl/stdio.h index ebce6ec6..c1a355bd 100644 --- a/ase/include/ase/utl/stdio.h +++ b/ase/include/ase/utl/stdio.h @@ -1,5 +1,5 @@ /* - * $Id: stdio.h 223 2008-06-26 06:44:41Z baconevi $ + * $Id: stdio.h 419 2008-10-13 11:32:58Z baconevi $ * * {License} */ @@ -44,10 +44,10 @@ #define ase_fflush(s) fflush(s) #define ase_fclose(s) fclose(s) -#define ASE_FILE FILE -#define ASE_STDIN stdin -#define ASE_STDOUT stdout -#define ASE_STDERR stderr +#define ASE_FILE FILE +#define ASE_STDIN stdin +#define ASE_STDOUT stdout +#define ASE_STDERR stderr typedef int (*ase_getdelim_t) (const ase_char_t* ptr,ase_size_t len, void* arg); diff --git a/ase/lib/awk/makefile.in b/ase/lib/awk/makefile.in index 5280b332..1b770f17 100644 --- a/ase/lib/awk/makefile.in +++ b/ase/lib/awk/makefile.in @@ -63,8 +63,8 @@ am__libaseawk___la_SOURCES_DIST = Awk.cpp StdAwk.cpp libaseawk___la_OBJECTS = $(am_libaseawk___la_OBJECTS) @ENABLE_CXX_TRUE@am_libaseawk___la_rpath = -rpath $(libdir) libaseawk_la_DEPENDENCIES = -am_libaseawk_la_OBJECTS = awk.lo err.lo tree.lo parse.lo run.lo \ - rec.lo val.lo func.lo misc.lo extio.lo std.lo +am_libaseawk_la_OBJECTS = awk.lo err.lo tree.lo parse.lo run.lo rec.lo \ + val.lo func.lo misc.lo extio.lo std.lo libaseawk_la_OBJECTS = $(am_libaseawk_la_OBJECTS) DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/autoconf/depcomp diff --git a/ase/lib/awk/std.c b/ase/lib/awk/std.c index e3a2a6ae..4a635c2d 100644 --- a/ase/lib/awk/std.c +++ b/ase/lib/awk/std.c @@ -35,7 +35,7 @@ static void custom_awk_dprintf (void* custom, const ase_char_t* fmt, ...) { va_list ap; va_start (ap, fmt); - ase_vfprintf (stderr, fmt, ap); + ase_vfprintf (ASE_STDERR, fmt, ap); va_end (ap); } @@ -69,16 +69,16 @@ struct sf_t { struct { - const ase_char_t** files; - ase_size_t count; /* the number of files */ - ase_size_t index; /* current file index */ - ASE_FILE* handle; /* the handle to an open file */ + const ase_char_t*const* files; + ase_size_t count; /* the number of files */ + ase_size_t index; /* current file index */ + ASE_FILE* handle; /* the handle to an open file */ } in; struct { - const ase_char_t* file; - ASE_FILE* handle; + const ase_char_t* file; + ASE_FILE* handle; } out; }; @@ -90,8 +90,16 @@ static ase_ssize_t sf_in (int cmd, void* arg, ase_char_t* data, ase_size_t size) if (cmd == ASE_AWK_IO_OPEN) { if (sf->in.index >= sf->in.count) return 0; - sf->in.handle = ase_fopen (sf->in.files[sf->in.index], ASE_T("r")); - if (sf->in.handle == ASE_NULL) return -1; + + if (sf->in.files[sf->in.index][0] == ASE_T('\0')) + { + sf->in.handle = ASE_STDIN; + } + else + { + sf->in.handle = ase_fopen (sf->in.files[sf->in.index], ASE_T("r")); + if (sf->in.handle == ASE_NULL) return -1; + } /* ase_awk_setsinname (); @@ -102,8 +110,7 @@ static ase_ssize_t sf_in (int cmd, void* arg, ase_char_t* data, ase_size_t size) else if (cmd == ASE_AWK_IO_CLOSE) { if (sf->in.index >= sf->in.count) return 0; - - fclose (sf->in.handle); + if (sf->in.handle != ASE_STDIN) ase_fclose (sf->in.handle); return 0; } else if (cmd == ASE_AWK_IO_READ) @@ -129,9 +136,16 @@ static ase_ssize_t sf_in (int cmd, void* arg, ase_char_t* data, ase_size_t size) sf->in.index++; if (sf->in.index < sf->in.count) { - ase_fclose (fp); - sf->in.handle = ase_fopen (sf->in.files[sf->in.index], ASE_T("r")); - if (sf->in.handle == ASE_NULL) return -1; + if (fp != ASE_STDIN) ase_fclose (fp); + if (sf->in.files[sf->in.index][0] == ASE_T('\0')) + { + sf->in.handle = ASE_STDIN; + } + else + { + sf->in.handle = ase_fopen (sf->in.files[sf->in.index], ASE_T("r")); + if (sf->in.handle == ASE_NULL) return -1; + } /* TODO: reset internal line counters... ase_awk_setsinname (); */ @@ -144,16 +158,29 @@ static ase_ssize_t sf_in (int cmd, void* arg, ase_char_t* data, ase_size_t size) return -1; } -#if 0 -static ase_ssize_t sf_out ( - int cmd, void* arg, ase_char_t* data, ase_size_t size) +static ase_ssize_t sf_out (int cmd, void* arg, ase_char_t* data, ase_size_t size) { - /*struct srcio_data_t* srcio = (struct srcio_data_t*)arg;*/ + sf_t* sf = (sf_t*)arg; - if (cmd == ASE_AWK_IO_OPEN) return 1; + if (cmd == ASE_AWK_IO_OPEN) + { + if (sf->out.file[0] == ASE_T('\0')) + { + sf->out.handle = ASE_STDOUT; + } + else + { + sf->out.handle = ase_fopen (sf->out.file, ASE_T("r")); + if (sf->out.handle == ASE_NULL) return -1; + } + + return 1; + } else if (cmd == ASE_AWK_IO_CLOSE) { - ase_fflush (stdout); + ase_fflush (sf->out.handle); + if (sf->out.handle != ASE_STDOUT && + sf->out.handle != ASE_STDERR) ase_fclose (sf->out.handle); return 0; } else if (cmd == ASE_AWK_IO_WRITE) @@ -164,13 +191,13 @@ static ase_ssize_t sf_out ( { if (*data == ASE_T('\0')) { - if (ase_fputc (*data, stdout) == ASE_CHAR_EOF) return -1; + if (ase_fputc (*data, sf->out.handle) == ASE_CHAR_EOF) return -1; left -= 1; data += 1; } else { int chunk = (left > ASE_TYPE_MAX(int))? ASE_TYPE_MAX(int): (int)left; - int n = ase_fprintf (stdout, ASE_T("%.*s"), chunk, data); + int n = ase_fprintf (sf->out.handle, ASE_T("%.*s"), chunk, data); if (n < 0) return -1; left -= n; data += n; } @@ -181,13 +208,18 @@ static ase_ssize_t sf_out ( return -1; } -#endif -int ase_awk_parsefiles (ase_awk_t* awk, const ase_char_t** isf, ase_size_t isfl, const ase_char_t* osf) +int ase_awk_parsefiles (ase_awk_t* awk, const ase_char_t*const* isf, ase_size_t isfl, const ase_char_t* osf) { sf_t sf; ase_awk_srcios_t sio; + if (isf == ASE_NULL || isfl == 0) + { + ase_awk_seterrnum (awk, ASE_AWK_EINVAL); + return -1; + } + sf.in.files = isf; sf.in.count = isfl; sf.in.index = 0; @@ -196,8 +228,7 @@ int ase_awk_parsefiles (ase_awk_t* awk, const ase_char_t** isf, ase_size_t isfl, sf.out.file = osf; sio.in = sf_in; - //sio.out = deparse? sf_out: NULL; - sio.out = ASE_NULL; + sio.out = (osf == ASE_NULL)? ASE_NULL: sf_out; sio.data = &sf; return ase_awk_parse (awk, &sio); diff --git a/ase/lib/cmn/chr.c b/ase/lib/cmn/chr.c index a8f3b015..878bf24f 100644 --- a/ase/lib/cmn/chr.c +++ b/ase/lib/cmn/chr.c @@ -142,3 +142,16 @@ static ase_ccls_t ccls = }; ase_ccls_t* ase_ccls = &ccls; + + +#if 0 +int ase_wctomb (ase_wchar_t wc, ase_mchar_t* mb, int mblen) +{ + if (mblen < MB_CUR_MAX) return -1; + return wctomb (mb, wc); +} + +ase_wchar_t ase_mbtowc (ase_mchar_t* mb, int mblen) +{ +} +#endif diff --git a/ase/lib/cmn/lda.c b/ase/lib/cmn/lda.c index 7bce63b3..f52899b5 100644 --- a/ase/lib/cmn/lda.c +++ b/ase/lib/cmn/lda.c @@ -96,7 +96,13 @@ lda_t* ase_lda_open (mmgr_t* mmgr, size_t ext, size_t capa) lda = ASE_MMGR_ALLOC (mmgr, ASE_SIZEOF(lda_t) + ext); if (lda == ASE_NULL) return ASE_NULL; - return ase_lda_init (lda, mmgr, capa); + if (ase_lda_init (lda, mmgr, capa) == ASE_NULL) + { + ASE_MMGR_FREE (mmgr, lda); + return ASE_NULL; + } + + return lda; } void ase_lda_close (lda_t* lda) diff --git a/ase/lib/cmn/makefile.am b/ase/lib/cmn/makefile.am index 6a8e51e3..73e77afd 100644 --- a/ase/lib/cmn/makefile.am +++ b/ase/lib/cmn/makefile.am @@ -6,6 +6,7 @@ lib_LTLIBRARIES = libasecmn.la libasecmn_la_SOURCES = mem.h chr.h \ mem.c chr.c rex.c str_bas.c str_cnv.c str_dyn.c \ lda.c map.c sll.c dll.c opt.c \ + tio.c tio_get.c tio_put.c \ misc.c libasecmn_la_LDFLAGS = -version-info 1:0:0 diff --git a/ase/lib/cmn/makefile.in b/ase/lib/cmn/makefile.in index 8e9b7bcf..8fec34c3 100644 --- a/ase/lib/cmn/makefile.in +++ b/ase/lib/cmn/makefile.in @@ -58,7 +58,8 @@ libLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(lib_LTLIBRARIES) libasecmn_la_LIBADD = am_libasecmn_la_OBJECTS = mem.lo chr.lo rex.lo str_bas.lo str_cnv.lo \ - str_dyn.lo lda.lo map.lo sll.lo dll.lo opt.lo misc.lo + str_dyn.lo lda.lo map.lo sll.lo dll.lo opt.lo tio.lo \ + tio_get.lo tio_put.lo misc.lo libasecmn_la_OBJECTS = $(am_libasecmn_la_OBJECTS) DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/autoconf/depcomp @@ -198,6 +199,7 @@ lib_LTLIBRARIES = libasecmn.la libasecmn_la_SOURCES = mem.h chr.h \ mem.c chr.c rex.c str_bas.c str_cnv.c str_dyn.c \ lda.c map.c sll.c dll.c opt.c \ + tio.c tio_get.c tio_put.c \ misc.c libasecmn_la_LDFLAGS = -version-info 1:0:0 @@ -282,6 +284,9 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_bas.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_cnv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str_dyn.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tio.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tio_get.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tio_put.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ diff --git a/ase/lib/cmn/sll.c b/ase/lib/cmn/sll.c index 1a903151..b82a51a3 100644 --- a/ase/lib/cmn/sll.c +++ b/ase/lib/cmn/sll.c @@ -91,7 +91,13 @@ sll_t* ase_sll_open (mmgr_t* mmgr, size_t ext) sll = ASE_MMGR_ALLOC (mmgr, SIZEOF(sll_t) + ext); if (sll == ASE_NULL) return ASE_NULL; - return ase_sll_init (sll, mmgr); + if (ase_sll_init (sll, mmgr) == ASE_NULL) + { + ASE_MMGR_FREE (mmgr, sll); + return ASE_NULL; + } + + return sll; } void ase_sll_close (sll_t* sll) diff --git a/ase/lib/cmn/tio.c b/ase/lib/cmn/tio.c new file mode 100644 index 00000000..1ac5ae7c --- /dev/null +++ b/ase/lib/cmn/tio.c @@ -0,0 +1,222 @@ +/* + * $Id: tio.c,v 1.13 2006/01/01 13:50:24 bacon Exp $ + */ + +#include +#include "mem.h" + +ase_tio_t* ase_tio_open (ase_mmgr_t* mmgr, ase_size_t ext) +{ + ase_tio_t* tio; + + if (mmgr == ASE_NULL) + { + mmgr = ASE_MMGR_GETDFL(); + + ASE_ASSERTX (mmgr != ASE_NULL, + "Set the memory manager with ASE_MMGR_SETDFL()"); + + if (mmgr == ASE_NULL) return ASE_NULL; + } + + tio = ASE_MMGR_ALLOC (mmgr, ASE_SIZEOF(ase_tio_t) + ext); + if (tio == ASE_NULL) return ASE_NULL; + + if (ase_tio_init (tio, mmgr) == ASE_NULL) + { + ASE_MMGR_FREE (mmgr, tio); + return ASE_NULL; + } + + return tio; +} + +int ase_tio_close (ase_tio_t* tio) +{ + int n = ase_tio_fini (tio); + ASE_MMGR_FREE (tio->mmgr, tio); + return n; +} + +ase_tio_t* ase_tio_init (ase_tio_t* tio, ase_mmgr_t* mmgr) +{ + ASE_MEMSET (tio, 0, ASE_SIZEOF(*tio)); + + tio->mmgr = mmgr; + + /* + tio->input_func = ASE_NULL; + tio->input_arg = ASE_NULL; + tio->output_func = ASE_NULL; + tio->output_arg = ASE_NULL; + + tio->input_status = 0; + tio->inbuf_curp = 0; + tio->inbuf_len = 0; + tio->outbuf_len = 0; + */ + + tio->errnum = ASE_TIO_ENOERR; + + return tio; +} + +int ase_tio_fini (ase_tio_t* tio) +{ + ase_tio_flush (tio); /* don't care about the result */ + if (ase_tio_detin(tio) == -1) return -1; + if (ase_tio_detout(tio) == -1) return -1; + return 0; +} + +int ase_tio_geterrnum (ase_tio_t* tio) +{ + return tio->errnum; +} + +const ase_char_t* ase_tio_geterrstr (ase_tio_t* tio) +{ + static const ase_char_t* __errstr[] = + { + ASE_T("no error"), + ASE_T("out of memory"), + ASE_T("no more space"), + ASE_T("illegal utf-8 sequence"), + ASE_T("no input function attached"), + ASE_T("input function returned an error"), + ASE_T("input function failed to open"), + ASE_T("input function failed to closed"), + ASE_T("no output function attached"), + ASE_T("output function returned an error"), + ASE_T("output function failed to open"), + ASE_T("output function failed to closed"), + ASE_T("unknown error") + }; + + return __errstr[ + (tio->errnum < 0 || tio->errnum >= ase_countof(__errstr))? + ase_countof(__errstr) - 1: tio->errnum]; +} + +int ase_tio_attin (ase_tio_t* tio, ase_tio_io_t input, void* arg) +{ + if (ase_tio_detin(tio) == -1) return -1; + + ASE_ASSERT (tio->input_func == ASE_NULL); + + if (input(ASE_TIO_IO_OPEN, arg, ASE_NULL, 0) == -1) + { + tio->errnum = ASE_TIO_EINPOP; + return -1; + } + + tio->input_func = input; + tio->input_arg = arg; + + tio->input_status = 0; + tio->inbuf_curp = 0; + tio->inbuf_len = 0; + + return 0; +} + +int ase_tio_detin (ase_tio_t* tio) +{ + if (tio->input_func != ASE_NULL) + { + if (tio->input_func ( + ASE_TIO_IO_CLOSE, tio->input_arg, ASE_NULL, 0) == -1) + { + tio->errnum = ASE_TIO_EINPCL; + return -1; + } + + tio->input_func = ASE_NULL; + tio->input_arg = ASE_NULL; + } + + return 0; +} + +int ase_tio_attout (ase_tio_t* tio, ase_tio_io_t output, void* arg) +{ + if (ase_tio_detout(tio) == -1) return -1; + + ASE_ASSERT (tio->output_func == ASE_NULL); + + if (output(ASE_TIO_IO_OPEN, arg, ASE_NULL, 0) == -1) + { + tio->errnum = ASE_TIO_EOUTOP; + return -1; + } + + tio->output_func = output; + tio->output_arg = arg; + tio->outbuf_len = 0; + + return 0; +} + +int ase_tio_detout (ase_tio_t* tio) +{ + if (tio->output_func != ASE_NULL) + { + ase_tio_flush (tio); /* don't care about the result */ + + if (tio->output_func ( + ASE_TIO_IO_CLOSE, tio->output_arg, ASE_NULL, 0) == -1) + { + tio->errnum = ASE_TIO_EOUTCL; + return -1; + } + + tio->output_func = ASE_NULL; + tio->output_arg = ASE_NULL; + } + + return 0; +} + +ase_ssize_t ase_tio_flush (ase_tio_t* tio) +{ + ase_size_t left, count; + + if (tio->output_func == ASE_NULL) + { + tio->errnum = ASE_TIO_ENOUTF; + return (ase_ssize_t)-1; + } + + left = tio->outbuf_len; + while (left > 0) + { + ase_ssize_t n; + + n = tio->output_func ( + ASE_TIO_IO_DATA, tio->output_arg, tio->outbuf, left); + if (n <= -1) + { + tio->outbuf_len = left; + tio->errnum = ASE_TIO_EOUTPT; + return -1; + } + if (n == 0) break; + + left -= n; + ase_memcpy (tio->outbuf, &tio->inbuf[n], left); + } + + count = tio->outbuf_len - left; + tio->outbuf_len = left; + + return (ase_ssize_t)count; +} + +void ase_tio_purge (ase_tio_t* tio) +{ + tio->input_status = 0; + tio->inbuf_curp = 0; + tio->inbuf_len = 0; + tio->outbuf_len = 0; + tio->errnum = ASE_TIO_ENOERR; +} diff --git a/ase/lib/cmn/tio_get.c b/ase/lib/cmn/tio_get.c new file mode 100644 index 00000000..18b8de02 --- /dev/null +++ b/ase/lib/cmn/tio_get.c @@ -0,0 +1,156 @@ +/* + * $Id: tio_get.c,v 1.8 2005/12/26 07:41:48 bacon Exp $ + */ + +#include +#include "mem.h" + +#define STATUS_GETC_EILSEQ (1 << 0) + +ase_ssize_t ase_tio_getc (ase_tio_t* tio, ase_char_t* c) +{ + ase_size_t left = 0; + ase_ssize_t n; + ase_char_t curc; +#ifndef ASE_CHAR_IS_MCHAR + ase_size_t seqlen; +#endif + + /* TODO: more efficient to check this... + * maybe better to use ASE_ASSERT + * ASE_ASSERT (tio->input_func != ASE_NULL); + */ + if (tio->input_func == ASE_NULL) + { + tio->errnum = ASE_TIO_ENOINF; + return -1; + } + + if (tio->input_status & STATUS_GETC_EILSEQ) + { + tio->input_status &= ~STATUS_GETC_EILSEQ; + tio->errnum = ASE_TIO_EILSEQ; + return -1; + } + + if (tio->inbuf_curp >= tio->inbuf_len) + { +getc_conv: + n = tio->input_func ( + ASE_TIO_IO_DATA, tio->input_arg, + &tio->inbuf[left], ASE_COUINTOF(tio->inbuf) - left); + if (n == 0) return 0; + if (n <= -1) + { + tio->errnum = ASE_TIO_EINPUT; + return -1; + } + + tio->inbuf_curp = 0; + tio->inbuf_len = (ase_size_t)n + left; + } + +#ifdef ASE_CHAR_IS_MCHAR + curc = tio->inbuf[tio->inbuf_curp++]; +#else + seqlen = ase_mcseqlen (tio->inbuf[tio->inbuf_curp]); + if (seqlen == 0) { + tio->inbuf_curp++; /* skip one byte */ + tio->errnum = ASE_TIO_EILSEQ; + return -1; + } + + left = tio->inbuf_len - tio->inbuf_curp; + if (left < seqlen) { + ase_memcpy (tio->inbuf, &tio->inbuf[tio->inbuf_curp], left); + tio->inbuf_curp = 0; + tio->inbuf_len = left; + goto getc_conv; + } + + n = ase_mctowc (&tio->inbuf[tio->inbuf_curp], seqlen, &curc); + if (n == 0) { + tio->inbuf_curp++; /* skip one byte */ + tio->errnum = ASE_TIO_EILSEQ; + return -1; + } + + tio->inbuf_curp += n; +#endif + + *c = curc; + return 1; +} + +ase_ssize_t ase_tio_gets (ase_tio_t* tio, ase_char_t* buf, ase_size_t size) +{ + ase_ssize_t n; + + if (size <= 0) return 0; + n = ase_tio_getsx (tio, buf, size - 1); + if (n == -1) return -1; + buf[n] = ASE_CHAR('\0'); + return n; +} + +ase_ssize_t ase_tio_getsx (ase_tio_t* tio, ase_char_t* buf, ase_size_t size) +{ + ase_ssize_t n; + ase_char_t* p, * end, c; + + if (size <= 0) return 0; + + p = buf; end = buf + size; + while (p < end) + { + n = ase_tio_getc (tio, &c); + if (n == -1) + { + if (p > buf && tio->errnum == ASE_TIO_EILSEQ) + { + tio->input_status |= STATUS_GETC_EILSEQ; + break; + } + return -1; + } + if (n == 0) break; + *p++ = c; + + if (c == ASE_CHAR('\n')) break; + } + + return p - buf; +} + +ase_ssize_t ase_tio_getstr (ase_tio_t* tio, ase_str_t* buf) +{ + ase_ssize_t n; + ase_char_t c; + + ase_str_clear (buf); + + for (;;) + { + n = ase_tio_getc (tio, &c); + if (n == -1) + { + if (ASE_STR_LEN(buf) > 0 && tio->errnum == ASE_TIO_EILSEQ) + { + tio->input_status |= STATUS_GETC_EILSEQ; + break; + } + return -1; + } + if (n == 0) break; + + if (ase_str_ccat(buf, c) == (ase_size_t)-1) + { + tio->errnum = ASE_TIO_ENOMEM; + return -1; + } + + if (c == ASE_CHAR('\n')) break; + } + + return ASE_STR_LEN(buf); +} diff --git a/ase/lib/cmn/tio_put.c b/ase/lib/cmn/tio_put.c new file mode 100644 index 00000000..c9025e29 --- /dev/null +++ b/ase/lib/cmn/tio_put.c @@ -0,0 +1,152 @@ +/* + * $Id: tio_put.c,v 1.2 2005/12/26 07:41:48 bacon Exp $ + */ + +#include + +ase_ssize_t ase_tio_putc (ase_tio_t* tio, ase_char_t c) +{ +#ifndef ASE_CHAR_IS_MCHAR + ase_size_t n, i; + ase_mchar_t mc[50]; +#endif + + if (tio->outbuf_len >= ASE_COUNTOF(tio->outbuf)) + { + /* maybe, previous flush operation has failed a few + * times previously. so the buffer is full. + */ + tio->errnum = ASE_TIO_ENOSPC; + return -1; + } + +#ifdef ASE_CHAR_IS_MCHAR + tio->outbuf[tio->outbuf_len++] = c; + if (tio->outbuf_len >= ASE_COUNTOF(tio->outbuf)) + return ase_tio_flush (tio); +#else + + n = ase_wctomc (c, mc, ASE_COUNTOF(mc)); + if (n == 0) + { + tio->errnum = ASE_TIO_EILSEQ; + return -1; + } + + for (i = 0; i < n; i++) + { + tio->outbuf[tio->outbuf_len++] = mc[i]; + if (tio->outbuf_len >= ASE_COUNTOF(tio->outbuf)) + { + if (ase_tio_flush(tio) == -1) return -1; + } + } +#endif + + if (c == ASE_CHAR('\n') && tio->outbuf_len > 0) + { + if (ase_tio_flush(tio) == -1) return -1; + } + + return 1; +} + +ase_ssize_t ase_tio_puts (ase_tio_t* tio, const ase_char_t* str) +{ + ase_ssize_t n; + const ase_char_t* p; + + for (p = str; *p != ASE_CHAR('\0'); p++) + { + n = ase_tio_putc (tio, *p); + if (n == -1) return -1; + if (n == 0) break; + } + + return p - str; +} + +ase_ssize_t ase_tio_putsx (ase_tio_t* tio, const ase_char_t* str, ase_size_t size) +{ + ase_ssize_t n; + const ase_char_t* p, * end; + + if (size == 0) return 0; + + p = str; end = str + size; + while (p < end) + { + n = ase_tio_putc (tio, *p); + if (n == -1) return -1; + if (n == 0) break; + + p++; + } + + return p - str; +} + +#if 0 +ase_ssize_t ase_tio_putsn (ase_tio_t* tio, ...) +{ + ase_ssize_t n; + ase_va_list ap; + + ase_va_start (ap, tio); + n = ase_tio_putsv (tio, ap); + ase_va_end (ap); + + return n; +} + +ase_ssize_t ase_tio_putsxn (ase_tio_t* tio, ...) +{ + ase_ssize_t n; + ase_va_list ap; + + ase_va_start (ap, tio); + n = ase_tio_putsxv (tio, ap); + ase_va_end (ap); + + return n; +} + +ase_ssize_t ase_tio_putsv (ase_tio_t* tio, ase_va_list ap) +{ + const ase_char_t* p; + ase_size_t n, total = 0; + + while ((p = ase_va_arg (ap, const ase_char_t*)) != ASE_NULL) + { + if (p[0] == ASE_CHAR('\0')) continue; + + n = ase_tio_puts (tio, p); + if (n == -1) return -1; + if (n == 0) break; + + total += n; + } + + return total; +} + +ase_ssize_t ase_tio_putsxv (ase_tio_t* tio, ase_va_list ap) +{ + const ase_char_t* p; + ase_size_t len, n, total = 0; + + while ((p = ase_va_arg (ap, const ase_char_t*)) != ASE_NULL) + { + len = ase_va_arg (ap, ase_size_t); + if (len == 0) continue; + + n = ase_tio_putsx (tio, p, len); + if (n == -1) return -1; + if (n == 0) break; + + total += n; + } + + return total; +} +#endif