porting tio from xpkit

This commit is contained in:
hyung-hwan 2008-10-14 05:32:58 +00:00
parent 5cb4f03cf9
commit dc0203008e
16 changed files with 917 additions and 46 deletions

View File

@ -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 <ase/awk/awk.h>
@ -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;

View File

@ -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}
*/
@ -816,12 +816,11 @@ int ase_awk_parse (
int ase_awk_parsefiles (
ase_awk_t* awk,
const ase_char_t* isf[] /* input source file names */,
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.
*

View File

@ -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

View File

@ -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

271
ase/include/ase/cmn/tio.h Normal file
View File

@ -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 <ase/types.h>
#include <ase/macros.h>
#include <ase/cmn/str.h>
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:
* <ase_tio_t> 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:
* <ase_tio_gets> 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:
* <ase_tio_getsx> 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

View File

@ -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}
*/

View File

@ -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

View File

@ -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,7 +69,7 @@ struct sf_t
{
struct
{
const ase_char_t** files;
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 */
@ -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;
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);
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);

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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 $@ $<; \

View File

@ -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)

222
ase/lib/cmn/tio.c Normal file
View File

@ -0,0 +1,222 @@
/*
* $Id: tio.c,v 1.13 2006/01/01 13:50:24 bacon Exp $
*/
#include <ase/cmn/tio.h>
#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;
}

156
ase/lib/cmn/tio_get.c Normal file
View File

@ -0,0 +1,156 @@
/*
* $Id: tio_get.c,v 1.8 2005/12/26 07:41:48 bacon Exp $
*/
#include <ase/cmn/tio.h>
#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);
}

152
ase/lib/cmn/tio_put.c Normal file
View File

@ -0,0 +1,152 @@
/*
* $Id: tio_put.c,v 1.2 2005/12/26 07:41:48 bacon Exp $
*/
#include <ase/cmn/tio.h>
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