added many new files to form fundamental base. wip

This commit is contained in:
hyung-hwan 2019-01-24 09:53:10 +00:00
parent 9b391741d6
commit a6d1122e33
19 changed files with 4867 additions and 1025 deletions

2
mio/configure vendored
View File

@ -17716,7 +17716,7 @@ fi
done
for ac_header in ifaddrs.h tiuser.h linux/netfilter_ipv4.h netinet/sctp.h
for ac_header in ifaddrs.h tiuser.h linux/netfilter_ipv4.h netinet/in.h netinet/sctp.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"

View File

@ -131,7 +131,7 @@ AC_CHECK_HEADERS([time.h sys/time.h utime.h spawn.h execinfo.h ucontext.h])
AC_CHECK_HEADERS([sys/resource.h sys/wait.h sys/syscall.h sys/ioctl.h])
AC_CHECK_HEADERS([sys/sendfile.h sys/epoll.h sys/event.h sys/poll.h])
AC_CHECK_HEADERS([sys/sysctl.h sys/socket.h sys/sockio.h sys/un.h])
AC_CHECK_HEADERS([ifaddrs.h tiuser.h linux/netfilter_ipv4.h netinet/sctp.h])
AC_CHECK_HEADERS([ifaddrs.h tiuser.h linux/netfilter_ipv4.h netinet/in.h netinet/sctp.h])
AC_CHECK_HEADERS([net/if.h net/if_dl.h netpacket/packet.h], [], [], [
#include <sys/types.h>
#include <sys/socket.h>])

View File

@ -24,18 +24,24 @@ include_HEADERS = \
mio-cmn.h \
mio-pro.h \
mio-sck.h \
mio-utl.h \
mio.h
lib_LTLIBRARIES = libmio.la
libmio_la_SOURCES = \
err.c \
logfmt.c \
logfmtv.h \
mio-prv.h \
mio.c \
mio-pro.c \
mio-sck.c \
mio-tim.c \
mio-tmr.c \
mio-utl.c \
utf8.c
sck-addr.c \
sck-addr.h \
utf8.c \
utl.c
libmio_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
libmio_la_LDFLAGS = $(LDFLAGS_LIB_COMMON)
libmio_la_LIBADD = $(LIBADD_LIB_COMMON) $(SSL_LIBS)

View File

@ -140,9 +140,10 @@ LTLIBRARIES = $(lib_LTLIBRARIES)
am__DEPENDENCIES_1 =
am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
libmio_la_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
am_libmio_la_OBJECTS = libmio_la-mio.lo libmio_la-mio-pro.lo \
libmio_la-mio-sck.lo libmio_la-mio-tim.lo libmio_la-mio-tmr.lo \
libmio_la-mio-utl.lo libmio_la-utf8.lo
am_libmio_la_OBJECTS = libmio_la-err.lo libmio_la-logfmt.lo \
libmio_la-mio.lo libmio_la-mio-pro.lo libmio_la-mio-sck.lo \
libmio_la-mio-tim.lo libmio_la-mio-tmr.lo \
libmio_la-sck-addr.lo libmio_la-utf8.lo libmio_la-utl.lo
libmio_la_OBJECTS = $(am_libmio_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@ -392,18 +393,24 @@ include_HEADERS = \
mio-cmn.h \
mio-pro.h \
mio-sck.h \
mio-utl.h \
mio.h
lib_LTLIBRARIES = libmio.la
libmio_la_SOURCES = \
err.c \
logfmt.c \
logfmtv.h \
mio-prv.h \
mio.c \
mio-pro.c \
mio-sck.c \
mio-tim.c \
mio-tmr.c \
mio-utl.c \
utf8.c
sck-addr.c \
sck-addr.h \
utf8.c \
utl.c
libmio_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
libmio_la_LDFLAGS = $(LDFLAGS_LIB_COMMON)
@ -559,13 +566,16 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-err.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-logfmt.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-mio-pro.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-mio-sck.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-mio-tim.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-mio-tmr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-mio-utl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-mio.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-sck-addr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-utf8.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-utl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mio-main.Po@am__quote@
.c.o:
@ -592,6 +602,20 @@ distclean-compile:
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
libmio_la-err.lo: err.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-err.lo -MD -MP -MF $(DEPDIR)/libmio_la-err.Tpo -c -o libmio_la-err.lo `test -f 'err.c' || echo '$(srcdir)/'`err.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-err.Tpo $(DEPDIR)/libmio_la-err.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='err.c' object='libmio_la-err.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-err.lo `test -f 'err.c' || echo '$(srcdir)/'`err.c
libmio_la-logfmt.lo: logfmt.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-logfmt.lo -MD -MP -MF $(DEPDIR)/libmio_la-logfmt.Tpo -c -o libmio_la-logfmt.lo `test -f 'logfmt.c' || echo '$(srcdir)/'`logfmt.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-logfmt.Tpo $(DEPDIR)/libmio_la-logfmt.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='logfmt.c' object='libmio_la-logfmt.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-logfmt.lo `test -f 'logfmt.c' || echo '$(srcdir)/'`logfmt.c
libmio_la-mio.lo: mio.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-mio.lo -MD -MP -MF $(DEPDIR)/libmio_la-mio.Tpo -c -o libmio_la-mio.lo `test -f 'mio.c' || echo '$(srcdir)/'`mio.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-mio.Tpo $(DEPDIR)/libmio_la-mio.Plo
@ -627,12 +651,12 @@ libmio_la-mio-tmr.lo: mio-tmr.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-mio-tmr.lo `test -f 'mio-tmr.c' || echo '$(srcdir)/'`mio-tmr.c
libmio_la-mio-utl.lo: mio-utl.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-mio-utl.lo -MD -MP -MF $(DEPDIR)/libmio_la-mio-utl.Tpo -c -o libmio_la-mio-utl.lo `test -f 'mio-utl.c' || echo '$(srcdir)/'`mio-utl.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-mio-utl.Tpo $(DEPDIR)/libmio_la-mio-utl.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mio-utl.c' object='libmio_la-mio-utl.lo' libtool=yes @AMDEPBACKSLASH@
libmio_la-sck-addr.lo: sck-addr.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-sck-addr.lo -MD -MP -MF $(DEPDIR)/libmio_la-sck-addr.Tpo -c -o libmio_la-sck-addr.lo `test -f 'sck-addr.c' || echo '$(srcdir)/'`sck-addr.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-sck-addr.Tpo $(DEPDIR)/libmio_la-sck-addr.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sck-addr.c' object='libmio_la-sck-addr.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-mio-utl.lo `test -f 'mio-utl.c' || echo '$(srcdir)/'`mio-utl.c
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-sck-addr.lo `test -f 'sck-addr.c' || echo '$(srcdir)/'`sck-addr.c
libmio_la-utf8.lo: utf8.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-utf8.lo -MD -MP -MF $(DEPDIR)/libmio_la-utf8.Tpo -c -o libmio_la-utf8.lo `test -f 'utf8.c' || echo '$(srcdir)/'`utf8.c
@ -641,6 +665,13 @@ libmio_la-utf8.lo: utf8.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-utf8.lo `test -f 'utf8.c' || echo '$(srcdir)/'`utf8.c
libmio_la-utl.lo: utl.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-utl.lo -MD -MP -MF $(DEPDIR)/libmio_la-utl.Tpo -c -o libmio_la-utl.lo `test -f 'utl.c' || echo '$(srcdir)/'`utl.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-utl.Tpo $(DEPDIR)/libmio_la-utl.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utl.c' object='libmio_la-utl.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-utl.lo `test -f 'utl.c' || echo '$(srcdir)/'`utl.c
mio-main.o: main.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mio_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mio-main.o -MD -MP -MF $(DEPDIR)/mio-main.Tpo -c -o mio-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mio-main.Tpo $(DEPDIR)/mio-main.Po

449
mio/lib/err.c Normal file
View File

@ -0,0 +1,449 @@
/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "mio-prv.h"
static mio_ooch_t errstr_0[] = {'n','o',' ','e','r','r','o','r','\0'};
static mio_ooch_t errstr_1[] = {'g','e','n','e','r','i','c',' ','e','r','r','o','r','\0'};
static mio_ooch_t errstr_2[] = {'n','o','t',' ','i','m','p','l','e','m','e','n','t','e','d','\0'};
static mio_ooch_t errstr_3[] = {'s','u','b','s','y','s','t','e','m',' ','e','r','r','o','r','\0'};
static mio_ooch_t errstr_4[] = {'i','n','t','e','r','n','a','l',' ','e','r','r','o','r',' ','t','h','a','t',' ','s','h','o','u','l','d',' ','n','e','v','e','r',' ','h','a','v','e',' ','h','a','p','p','e','n','e','d','\0'};
static mio_ooch_t errstr_5[] = {'i','n','s','u','f','f','i','c','i','e','n','t',' ','s','y','s','t','e','m',' ','m','e','m','o','r','y','\0'};
static mio_ooch_t errstr_6[] = {'i','n','s','u','f','f','i','c','i','e','n','t',' ','o','b','j','e','c','t',' ','m','e','m','o','r','y','\0'};
static mio_ooch_t errstr_7[] = {'i','n','v','a','l','i','d',' ','c','l','a','s','s','/','t','y','p','e','\0'};
static mio_ooch_t errstr_8[] = {'i','n','v','a','l','i','d',' ','p','a','r','a','m','e','t','e','r',' ','o','r',' ','a','r','g','u','m','e','n','t','\0'};
static mio_ooch_t errstr_9[] = {'d','a','t','a',' ','n','o','t',' ','f','o','u','n','d','\0'};
static mio_ooch_t errstr_10[] = {'e','x','i','s','t','i','n','g','/','d','u','p','l','i','c','a','t','e',' ','d','a','t','a','\0'};
static mio_ooch_t errstr_11[] = {'b','u','s','y','\0'};
static mio_ooch_t errstr_12[] = {'a','c','c','e','s','s',' ','d','e','n','i','e','d','\0'};
static mio_ooch_t errstr_13[] = {'o','p','e','r','a','t','i','o','n',' ','n','o','t',' ','p','e','r','m','i','t','t','e','d','\0'};
static mio_ooch_t errstr_14[] = {'n','o','t',' ','a',' ','d','i','r','e','c','t','o','r','y','\0'};
static mio_ooch_t errstr_15[] = {'i','n','t','e','r','r','u','p','t','e','d','\0'};
static mio_ooch_t errstr_16[] = {'p','i','p','e',' ','e','r','r','o','r','\0'};
static mio_ooch_t errstr_17[] = {'r','e','s','o','u','r','c','e',' ','t','e','m','p','o','r','a','r','i','l','y',' ','u','n','a','v','a','i','l','a','b','l','e','\0'};
static mio_ooch_t errstr_18[] = {'b','a','d',' ','s','y','s','t','e','m',' ','h','a','n','d','l','e','\0'};
static mio_ooch_t errstr_19[] = {'*','*','*',' ','u','n','d','e','f','i','n','e','d',' ','e','r','r','o','r',' ','*','*','*','\0'};
static mio_ooch_t errstr_20[] = {'m','e','s','s','a','g','e',' ','r','e','c','e','i','v','e','r',' ','e','r','r','o','r','\0'};
static mio_ooch_t errstr_21[] = {'m','e','s','s','a','g','e',' ','s','e','n','d','i','n','g',' ','e','r','r','o','r','\0'};
static mio_ooch_t errstr_22[] = {'w','r','o','n','g',' ','n','u','m','b','e','r',' ','o','f',' ','a','r','g','u','m','e','n','t','s','\0'};
static mio_ooch_t errstr_23[] = {'r','a','n','g','e',' ','e','r','r','o','r','\0'};
static mio_ooch_t errstr_24[] = {'b','y','t','e','-','c','o','d','e',' ','f','u','l','l','\0'};
static mio_ooch_t errstr_25[] = {'d','i','c','t','i','o','n','a','r','y',' ','f','u','l','l','\0'};
static mio_ooch_t errstr_26[] = {'p','r','o','c','e','s','s','o','r',' ','f','u','l','l','\0'};
static mio_ooch_t errstr_27[] = {'t','o','o',' ','m','a','n','y',' ','s','e','m','a','p','h','o','r','e','s','\0'};
static mio_ooch_t errstr_28[] = {'*','*','*',' ','u','n','d','e','f','i','n','e','d',' ','e','r','r','o','r',' ','*','*','*','\0'};
static mio_ooch_t errstr_29[] = {'d','i','v','i','d','e',' ','b','y',' ','z','e','r','o','\0'};
static mio_ooch_t errstr_30[] = {'I','/','O',' ','e','r','r','o','r','\0'};
static mio_ooch_t errstr_31[] = {'e','n','c','o','d','i','n','g',' ','c','o','n','v','e','r','s','i','o','n',' ','e','r','r','o','r','\0'};
static mio_ooch_t errstr_32[] = {'i','n','s','u','f','f','i','c','i','e','n','t',' ','d','a','t','a',' ','f','o','r',' ','e','n','c','o','d','i','n','g',' ','c','o','n','v','e','r','s','i','o','n','\0'};
static mio_ooch_t errstr_33[] = {'b','u','f','f','e','r',' ','f','u','l','l','\0'};
static mio_ooch_t* errstr[] =
{
errstr_0, errstr_1, errstr_2, errstr_3, errstr_4, errstr_5, errstr_6, errstr_7,
errstr_8, errstr_9, errstr_10, errstr_11, errstr_12, errstr_13, errstr_14, errstr_15,
errstr_16, errstr_17, errstr_18, errstr_19, errstr_20, errstr_21, errstr_22, errstr_23,
errstr_24, errstr_25, errstr_26, errstr_27, errstr_28, errstr_29, errstr_30, errstr_31,
errstr_32, errstr_33
};
/* --------------------------------------------------------------------------
* ERROR NUMBER TO STRING CONVERSION
* -------------------------------------------------------------------------- */
const mio_ooch_t* mio_errnum_to_errstr (mio_errnum_t errnum)
{
static mio_ooch_t e_unknown[] = {'u','n','k','n','o','w','n',' ','e','r','r','o','r','\0'};
return (errnum >= 0 && errnum < MIO_COUNTOF(errstr))? errstr[errnum]: e_unknown;
}
/* --------------------------------------------------------------------------
* ERROR MESSAGE CONVERSION
* -------------------------------------------------------------------------- */
#include <errno.h>
static mio_errnum_t errno_to_errnum (int errcode)
{
switch (errcode)
{
case ENOMEM: return MIO_ESYSMEM;
case EINVAL: return MIO_EINVAL;
#if defined(EBUSY)
case EBUSY: return MIO_EBUSY;
#endif
case EACCES: return MIO_EACCES;
#if defined(EPERM)
case EPERM: return MIO_EPERM;
#endif
#if defined(ENOTDIR)
case ENOTDIR: return MIO_ENOTDIR;
#endif
case ENOENT: return MIO_ENOENT;
#if defined(EEXIST)
case EEXIST: return MIO_EEXIST;
#endif
#if defined(EINTR)
case EINTR: return MIO_EINTR;
#endif
#if defined(EPIPE)
case EPIPE: return MIO_EPIPE;
#endif
#if defined(EAGAIN) && defined(EWOULDBLOCK) && (EAGAIN != EWOULDBLOCK)
case EAGAIN:
case EWOULDBLOCK: return MIO_EAGAIN;
#elif defined(EAGAIN)
case EAGAIN: return MIO_EAGAIN;
#elif defined(EWOULDBLOCK)
case EWOULDBLOCK: return MIO_EAGAIN;
#endif
#if defined(EBADF)
case EBADF: return MIO_EBADHND;
#endif
#if defined(EIO)
case EIO: return MIO_EIOERR;
#endif
default: return MIO_ESYSERR;
}
}
#if defined(_WIN32)
static mio_errnum_t winerr_to_errnum (DWORD errcode)
{
switch (errcode)
{
case ERROR_NOT_ENOUGH_MEMORY:
case ERROR_OUTOFMEMORY:
return MIO_ESYSMEM;
case ERROR_INVALID_PARAMETER:
case ERROR_INVALID_NAME:
return MIO_EINVAL;
case ERROR_INVALID_HANDLE:
return MIO_EBADHND;
case ERROR_ACCESS_DENIED:
case ERROR_SHARING_VIOLATION:
return MIO_EACCES;
#if defined(ERROR_IO_PRIVILEGE_FAILED)
case ERROR_IO_PRIVILEGE_FAILED:
#endif
case ERROR_PRIVILEGE_NOT_HELD:
return MIO_EPERM;
case ERROR_FILE_NOT_FOUND:
case ERROR_PATH_NOT_FOUND:
return MIO_ENOENT;
case ERROR_ALREADY_EXISTS:
case ERROR_FILE_EXISTS:
return MIO_EEXIST;
case ERROR_BROKEN_PIPE:
return MIO_EPIPE;
default:
return MIO_ESYSERR;
}
}
#endif
#if defined(__OS2__)
static mio_errnum_t os2err_to_errnum (APIRET errcode)
{
/* APIRET e */
switch (errcode)
{
case ERROR_NOT_ENOUGH_MEMORY:
return MIO_ESYSMEM;
case ERROR_INVALID_PARAMETER:
case ERROR_INVALID_NAME:
return MIO_EINVAL;
case ERROR_INVALID_HANDLE:
return MIO_EBADHND;
case ERROR_ACCESS_DENIED:
case ERROR_SHARING_VIOLATION:
return MIO_EACCES;
case ERROR_FILE_NOT_FOUND:
case ERROR_PATH_NOT_FOUND:
return MIO_ENOENT;
case ERROR_ALREADY_EXISTS:
return MIO_EEXIST;
/*TODO: add more mappings */
default:
return MIO_ESYSERR;
}
}
#endif
#if defined(macintosh)
static mio_errnum_t macerr_to_errnum (int errcode)
{
switch (e)
{
case notEnoughMemoryErr:
return MIO_ESYSMEM;
case paramErr:
return MIO_EINVAL;
case qErr: /* queue element not found during deletion */
case fnfErr: /* file not found */
case dirNFErr: /* direcotry not found */
case resNotFound: /* resource not found */
case resFNotFound: /* resource file not found */
case nbpNotFound: /* name not found on remove */
return MIO_ENOENT;
/*TODO: add more mappings */
default:
return MIO_ESYSERR;
}
}
#endif
static mio_errnum_t syserrstrb (mio_t* mio, int syserr_type, int syserr_code, mio_bch_t* buf, mio_oow_t len)
{
switch (syserr_type)
{
case 1:
#if defined(_WIN32)
if (buf)
{
DWORD rc;
rc = FormatMessageA (
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, syserr_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
buf, len, MIO_NULL
);
while (rc > 0 && buf[rc - 1] == '\r' || buf[rc - 1] == '\n') buf[--rc] = '\0';
}
return winerr_to_errnum(syserr_code);
#elif defined(__OS2__)
/* TODO: convert code to string */
if (buf) mio_copy_bcstr (buf, len, "system error");
return os2err_to_errnum(syserr_code);
#elif defined(macintosh)
/* TODO: convert code to string */
if (buf) mio_copy_bcstr (buf, len, "system error");
return os2err_to_errnum(syserr_code);
#else
/* in other systems, errno is still the native system error code.
* fall thru */
#endif
case 0:
#if defined(HAVE_STRERROR_R)
if (buf) strerror_r (syserr_code, buf, len);
#else
/* this is not thread safe */
if (buf) mio_copy_bcstr (buf, len, strerror(syserr_code));
#endif
return errno_to_errnum(syserr_code);
}
if (buf) mio_copy_bcstr (buf, len, "system error");
return MIO_ESYSERR;
}
/* --------------------------------------------------------------------------
* ERROR NUMBER/MESSAGE HANDLING
* -------------------------------------------------------------------------- */
const mio_ooch_t* mio_geterrstr (mio_t* mio)
{
return mio_errnum_to_errstr(mio->errnum);
}
const mio_ooch_t* mio_geterrmsg (mio_t* mio)
{
if (mio->errmsg.len <= 0) return mio_errnum_to_errstr(mio->errnum);
return mio->errmsg.buf;
}
void mio_geterrinf (mio_t* mio, mio_errinf_t* info)
{
info->num = mio_geterrnum(mio);
mio_copy_oocstr (info->msg, MIO_COUNTOF(info->msg), mio_geterrmsg(mio));
}
const mio_ooch_t* mio_backuperrmsg (mio_t* mio)
{
mio_copy_oocstr (mio->errmsg.tmpbuf.ooch, MIO_COUNTOF(mio->errmsg.tmpbuf.ooch), mio_geterrmsg(mio));
return mio->errmsg.tmpbuf.ooch;
}
void mio_seterrnum (mio_t* mio, mio_errnum_t errnum)
{
if (mio->shuterr) return;
mio->errnum = errnum;
mio->errmsg.len = 0;
}
void mio_seterrwithsyserr (mio_t* mio, int syserr_type, int syserr_code)
{
mio_errnum_t errnum;
if (mio->shuterr) return;
/*if (mio->vmprim.syserrstrb)
{*/
errnum = /*mio->vmprim.*/syserrstrb(mio, syserr_type, syserr_code, mio->errmsg.tmpbuf.bch, MIO_COUNTOF(mio->errmsg.tmpbuf.bch));
mio_seterrbfmt (mio, errnum, "%hs", mio->errmsg.tmpbuf.bch);
/*
}
else
{
MIO_ASSERT (mio, mio->vmprim.syserrstru != MIO_NULL);
errnum = mio->vmprim.syserrstru(mio, syserr_type, syserr_code, mio->errmsg.tmpbuf.uch, MIO_COUNTOF(mio->errmsg.tmpbuf.uch));
mio_seterrbfmt (mio, errnum, "%ls", mio->errmsg.tmpbuf.uch);
}*/
}
void mio_seterrbfmtwithsyserr (mio_t* mio, int syserr_type, int syserr_code, const mio_bch_t* fmt, ...)
{
mio_errnum_t errnum;
mio_oow_t ucslen, bcslen;
va_list ap;
if (mio->shuterr) return;
/*
if (mio->vmprim.syserrstrb)
{*/
errnum = /*mio->vmprim.*/syserrstrb(mio, syserr_type, syserr_code, mio->errmsg.tmpbuf.bch, MIO_COUNTOF(mio->errmsg.tmpbuf.bch));
va_start (ap, fmt);
mio_seterrbfmtv (mio, errnum, fmt, ap);
va_end (ap);
if (MIO_COUNTOF(mio->errmsg.buf) - mio->errmsg.len >= 5)
{
mio->errmsg.buf[mio->errmsg.len++] = ' ';
mio->errmsg.buf[mio->errmsg.len++] = '-';
mio->errmsg.buf[mio->errmsg.len++] = ' ';
#if defined(MIO_OOCH_IS_BCH)
mio->errmsg.len += mio_copy_bcstr(&mio->errmsg.buf[mio->errmsg.len], MIO_COUNTOF(mio->errmsg.buf) - mio->errmsg.len, mio->errmsg.tmpbuf.bch);
#else
ucslen = MIO_COUNTOF(mio->errmsg.buf) - mio->errmsg.len;
mio_convbtoucstr (mio, mio->errmsg.tmpbuf.bch, &bcslen, &mio->errmsg.buf[mio->errmsg.len], &ucslen);
mio->errmsg.len += ucslen;
#endif
}
/*}
else
{
MIO_ASSERT (mio, mio->vmprim.syserrstru != MIO_NULL);
errnum = mio->vmprim.syserrstru(mio, syserr_type, syserr_code, mio->errmsg.tmpbuf.uch, MIO_COUNTOF(mio->errmsg.tmpbuf.uch));
va_start (ap, fmt);
mio_seterrbfmtv (mio, errnum, fmt, ap);
va_end (ap);
if (MIO_COUNTOF(mio->errmsg.buf) - mio->errmsg.len >= 5)
{
mio->errmsg.buf[mio->errmsg.len++] = ' ';
mio->errmsg.buf[mio->errmsg.len++] = '-';
mio->errmsg.buf[mio->errmsg.len++] = ' ';
#if defined(MIO_OOCH_IS_BCH)
bcslen = MIO_COUNTOF(mio->errmsg.buf) - mio->errmsg.len;
mio_convutobcstr (mio, mio->errmsg.tmpbuf.uch, &ucslen, &mio->errmsg.buf[mio->errmsg.len], &bcslen);
mio->errmsg.len += bcslen;
#else
mio->errmsg.len += mio_copy_ucstr(&mio->errmsg.buf[mio->errmsg.len], MIO_COUNTOF(mio->errmsg.buf) - mio->errmsg.len, mio->errmsg.tmpbuf.uch);
#endif
}
}*/
}
void mio_seterrufmtwithsyserr (mio_t* mio, int syserr_type, int syserr_code, const mio_uch_t* fmt, ...)
{
mio_errnum_t errnum;
mio_oow_t ucslen, bcslen;
va_list ap;
if (mio->shuterr) return;
/*if (mio->vmprim.syserrstrb)
{*/
errnum = /*mio->vmprim.*/syserrstrb(mio, syserr_type, syserr_code, mio->errmsg.tmpbuf.bch, MIO_COUNTOF(mio->errmsg.tmpbuf.bch));
va_start (ap, fmt);
mio_seterrufmtv (mio, errnum, fmt, ap);
va_end (ap);
if (MIO_COUNTOF(mio->errmsg.buf) - mio->errmsg.len >= 5)
{
mio->errmsg.buf[mio->errmsg.len++] = ' ';
mio->errmsg.buf[mio->errmsg.len++] = '-';
mio->errmsg.buf[mio->errmsg.len++] = ' ';
#if defined(MIO_OOCH_IS_BCH)
mio->errmsg.len += mio_copy_bcstr(&mio->errmsg.buf[mio->errmsg.len], MIO_COUNTOF(mio->errmsg.buf) - mio->errmsg.len, mio->errmsg.tmpbuf.bch);
#else
ucslen = MIO_COUNTOF(mio->errmsg.buf) - mio->errmsg.len;
mio_convbtoucstr (mio, mio->errmsg.tmpbuf.bch, &bcslen, &mio->errmsg.buf[mio->errmsg.len], &ucslen);
mio->errmsg.len += ucslen;
#endif
}
/*}
else
{
MIO_ASSERT (mio, mio->vmprim.syserrstru != MIO_NULL);
errnum = mio->vmprim.syserrstru(mio, syserr_type, syserr_code, mio->errmsg.tmpbuf.uch, MIO_COUNTOF(mio->errmsg.tmpbuf.uch));
va_start (ap, fmt);
mio_seterrufmtv (mio, errnum, fmt, ap);
va_end (ap);
if (MIO_COUNTOF(mio->errmsg.buf) - mio->errmsg.len >= 5)
{
mio->errmsg.buf[mio->errmsg.len++] = ' ';
mio->errmsg.buf[mio->errmsg.len++] = '-';
mio->errmsg.buf[mio->errmsg.len++] = ' ';
#if defined(MIO_OOCH_IS_BCH)
bcslen = MIO_COUNTOF(mio->errmsg.buf) - mio->errmsg.len;
mio_convutobcstr (mio, mio->errmsg.tmpbuf.uch, &ucslen, &mio->errmsg.buf[mio->errmsg.len], &bcslen);
mio->errmsg.len += bcslen;
#else
mio->errmsg.len += mio_copy_ucstr(&mio->errmsg.buf[mio->errmsg.len], MIO_COUNTOF(mio->errmsg.buf) - mio->errmsg.len, mio->errmsg.tmpbuf.uch);
#endif
}
}*/
}

733
mio/lib/logfmt.c Normal file
View File

@ -0,0 +1,733 @@
/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "mio-prv.h"
/*#include <stdio.h>*/ /* for snprintf(). used for floating-point number formatting */
#if defined(_MSC_VER) || defined(__BORLANDC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1200))
# define snprintf _snprintf
# if !defined(HAVE_SNPRINTF)
# define HAVE_SNPRINTF
# endif
#endif
#if defined(HAVE_QUADMATH_H)
# include <quadmath.h> /* for quadmath_snprintf() */
#endif
/* TODO: remove stdio.h and quadmath.h once snprintf gets replaced by own
floting-point conversion implementation*/
/* Max number conversion buffer length:
* mio_intmax_t in base 2, plus NUL byte. */
#define MAXNBUF (MIO_SIZEOF(mio_intmax_t) * 8 + 1)
enum
{
/* integer */
LF_C = (1 << 0),
LF_H = (1 << 1),
LF_J = (1 << 2),
LF_L = (1 << 3),
LF_Q = (1 << 4),
LF_T = (1 << 5),
LF_Z = (1 << 6),
/* long double */
LF_LD = (1 << 7),
/* __float128 */
LF_QD = (1 << 8)
};
static struct
{
mio_uint8_t flag; /* for single occurrence */
mio_uint8_t dflag; /* for double occurrence */
} lm_tab[26] =
{
{ 0, 0 }, /* a */
{ 0, 0 }, /* b */
{ 0, 0 }, /* c */
{ 0, 0 }, /* d */
{ 0, 0 }, /* e */
{ 0, 0 }, /* f */
{ 0, 0 }, /* g */
{ LF_H, LF_C }, /* h */
{ 0, 0 }, /* i */
{ LF_J, 0 }, /* j */
{ 0, 0 }, /* k */
{ LF_L, LF_Q }, /* l */
{ 0, 0 }, /* m */
{ 0, 0 }, /* n */
{ 0, 0 }, /* o */
{ 0, 0 }, /* p */
{ LF_Q, 0 }, /* q */
{ 0, 0 }, /* r */
{ 0, 0 }, /* s */
{ LF_T, 0 }, /* t */
{ 0, 0 }, /* u */
{ 0, 0 }, /* v */
{ 0, 0 }, /* w */
{ 0, 0 }, /* z */
{ 0, 0 }, /* y */
{ LF_Z, 0 }, /* z */
};
enum
{
FLAGC_DOT = (1 << 0),
FLAGC_SPACE = (1 << 1),
FLAGC_SHARP = (1 << 2),
FLAGC_SIGN = (1 << 3),
FLAGC_LEFTADJ = (1 << 4),
FLAGC_ZEROPAD = (1 << 5),
FLAGC_WIDTH = (1 << 6),
FLAGC_PRECISION = (1 << 7),
FLAGC_STAR1 = (1 << 8),
FLAGC_STAR2 = (1 << 9),
FLAGC_LENMOD = (1 << 10) /* length modifier */
};
static const mio_bch_t hex2ascii_lower[] =
{
'0','1','2','3','4','5','6','7','8','9',
'a','b','c','d','e','f','g','h','i','j','k','l','m',
'n','o','p','q','r','s','t','u','v','w','x','y','z'
};
static const mio_bch_t hex2ascii_upper[] =
{
'0','1','2','3','4','5','6','7','8','9',
'A','B','C','D','E','F','G','H','I','J','K','L','M',
'N','O','P','Q','R','S','T','U','V','W','X','H','Z'
};
static mio_uch_t uch_nullstr[] = { '(','n','u','l','l', ')','\0' };
static mio_bch_t bch_nullstr[] = { '(','n','u','l','l', ')','\0' };
typedef int (*mio_fmtout_putch_t) (
mio_t* mio,
mio_bitmask_t mask,
mio_ooch_t c,
mio_oow_t len
);
typedef int (*mio_fmtout_putcs_t) (
mio_t* mio,
mio_bitmask_t mask,
const mio_ooch_t* ptr,
mio_oow_t len
);
typedef struct mio_fmtout_t mio_fmtout_t;
struct mio_fmtout_t
{
mio_oow_t count; /* out */
mio_bitmask_t mask; /* in */
mio_fmtout_putch_t putch; /* in */
mio_fmtout_putcs_t putcs; /* in */
};
/* ------------------------------------------------------------------------- */
/*
* Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
* order; return an optional length and a pointer to the last character
* written in the buffer (i.e., the first character of the string).
* The buffer pointed to by `nbuf' must have length >= MAXNBUF.
*/
static mio_bch_t* sprintn_lower (mio_bch_t* nbuf, mio_uintmax_t num, int base, mio_ooi_t* lenp)
{
mio_bch_t* p;
p = nbuf;
*p = '\0';
do { *++p = hex2ascii_lower[num % base]; } while (num /= base);
if (lenp) *lenp = p - nbuf;
return p; /* returns the end */
}
static mio_bch_t* sprintn_upper (mio_bch_t* nbuf, mio_uintmax_t num, int base, mio_ooi_t* lenp)
{
mio_bch_t* p;
p = nbuf;
*p = '\0';
do { *++p = hex2ascii_upper[num % base]; } while (num /= base);
if (lenp) *lenp = p - nbuf;
return p; /* returns the end */
}
/* ------------------------------------------------------------------------- */
static int put_ooch (mio_t* mio, mio_bitmask_t mask, mio_ooch_t ch, mio_oow_t len)
{
/* this is not equivalent to put_oocs(mio,mask,&ch, 1);
* this function is to emit a single character multiple times */
mio_oow_t rem;
if (len <= 0) return 1;
if (mio->log.len > 0 && mio->log.last_mask != mask)
{
/* the mask has changed. commit the buffered text */
/* TODO: HANDLE LINE ENDING CONVENTION BETTER... */
if (mio->log.ptr[mio->log.len - 1] != '\n')
{
/* no line ending - append a line terminator */
mio->log.ptr[mio->log.len++] = '\n';
}
vmprim_log_write (mio, mio->log.last_mask, mio->log.ptr, mio->log.len);
mio->log.len = 0;
}
redo:
rem = 0;
if (len > mio->log.capa - mio->log.len)
{
mio_oow_t newcapa, max;
mio_ooch_t* tmp;
max = MIO_TYPE_MAX(mio_oow_t) - mio->log.len;
if (len > max)
{
/* data too big. */
rem += len - max;
len = max;
}
newcapa = MIO_ALIGN_POW2(mio->log.len + len, MIO_LOG_CAPA_ALIGN); /* TODO: adjust this capacity */
if (newcapa > mio->option.log_maxcapa)
{
/* [NOTE]
* it doesn't adjust newcapa to mio->option.log_maxcapa.
* nor does it cut the input to fit it into the adjusted capacity.
* if maxcapa set is not aligned to MIO_LOG_CAPA_ALIGN,
* the largest buffer capacity may be suboptimal */
goto make_do;
}
/* +1 to handle line ending injection more easily */
tmp = mio_reallocmem(mio, mio->log.ptr, (newcapa + 1) * MIO_SIZEOF(*tmp));
if (!tmp)
{
make_do:
if (mio->log.len > 0)
{
/* can't expand the buffer. just flush the existing contents */
/* TODO: HANDLE LINE ENDING CONVENTION BETTER... */
if (mio->log.ptr[mio->log.len - 1] != '\n')
{
/* no line ending - append a line terminator */
mio->log.ptr[mio->log.len++] = '\n';
}
vmprim_log_write (mio, mio->log.last_mask, mio->log.ptr, mio->log.len);
mio->log.len = 0;
}
if (len > mio->log.capa)
{
rem += len - mio->log.capa;
len = mio->log.capa;
}
}
else
{
mio->log.ptr = tmp;
mio->log.capa = newcapa;
}
}
while (len > 0)
{
mio->log.ptr[mio->log.len++] = ch;
len--;
}
mio->log.last_mask = mask;
if (rem > 0)
{
len = rem;
goto redo;
}
return 1; /* success */
}
static int put_oocs (mio_t* mio, mio_bitmask_t mask, const mio_ooch_t* ptr, mio_oow_t len)
{
mio_oow_t rem;
if (len <= 0) return 1;
if (mio->log.len > 0 && mio->log.last_mask != mask)
{
/* the mask has changed. commit the buffered text */
/* TODO: HANDLE LINE ENDING CONVENTION BETTER... */
if (mio->log.ptr[mio->log.len - 1] != '\n')
{
/* no line ending - append a line terminator */
mio->log.ptr[mio->log.len++] = '\n';
}
vmprim_log_write (mio, mio->log.last_mask, mio->log.ptr, mio->log.len);
mio->log.len = 0;
}
redo:
rem = 0;
if (len > mio->log.capa - mio->log.len)
{
mio_oow_t newcapa, max;
mio_ooch_t* tmp;
max = MIO_TYPE_MAX(mio_oow_t) - mio->log.len;
if (len > max)
{
/* data too big. */
rem += len - max;
len = max;
}
newcapa = MIO_ALIGN_POW2(mio->log.len + len, 512); /* TODO: adjust this capacity */
if (newcapa > mio->option.log_maxcapa)
{
/* [NOTE]
* it doesn't adjust newcapa to mio->option.log_maxcapa.
* nor does it cut the input to fit it into the adjusted capacity.
* if maxcapa set is not aligned to MIO_LOG_CAPA_ALIGN,
* the largest buffer capacity may be suboptimal */
goto make_do;
}
/* +1 to handle line ending injection more easily */
tmp = mio_reallocmem(mio, mio->log.ptr, (newcapa + 1) * MIO_SIZEOF(*tmp));
if (!tmp)
{
make_do:
if (mio->log.len > 0)
{
/* can't expand the buffer. just flush the existing contents */
/* TODO: HANDLE LINE ENDING CONVENTION BETTER... */
if (mio->log.ptr[mio->log.len - 1] != '\n')
{
/* no line ending - append a line terminator */
mio->log.ptr[mio->log.len++] = '\n';
}
vmprim_log_write (mio, mio->log.last_mask, mio->log.ptr, mio->log.len);
mio->log.len = 0;
}
if (len > mio->log.capa)
{
rem += len - mio->log.capa;
len = mio->log.capa;
}
}
else
{
mio->log.ptr = tmp;
mio->log.capa = newcapa;
}
}
MIO_MEMCPY (&mio->log.ptr[mio->log.len], ptr, len * MIO_SIZEOF(*ptr));
mio->log.len += len;
mio->log.last_mask = mask;
if (rem > 0)
{
ptr += len;
len = rem;
goto redo;
}
return 1; /* success */
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
#undef FMTCHAR_IS_BCH
#undef FMTCHAR_IS_UCH
#undef FMTCHAR_IS_OOCH
#undef fmtchar_t
#undef logfmtv
#define fmtchar_t mio_bch_t
#define logfmtv __logbfmtv
#define FMTCHAR_IS_BCH
#if defined(MIO_OOCH_IS_BCH)
# define FMTCHAR_IS_OOCH
#endif
#include "logfmtv.h"
#undef FMTCHAR_IS_BCH
#undef FMTCHAR_IS_UCH
#undef FMTCHAR_IS_OOCH
#undef fmtchar_t
#undef logfmtv
#define fmtchar_t mio_uch_t
#define logfmtv __logufmtv
#define FMTCHAR_IS_UCH
#if defined(MIO_OOCH_IS_UCH)
# define FMTCHAR_IS_OOCH
#endif
#include "logfmtv.h"
static int _logbfmtv (mio_t* mio, const mio_bch_t* fmt, mio_fmtout_t* data, va_list ap)
{
return __logbfmtv (mio, fmt, data, ap, mio_logbfmt);
}
static int _logufmtv (mio_t* mio, const mio_uch_t* fmt, mio_fmtout_t* data, va_list ap)
{
return __logufmtv (mio, fmt, data, ap, mio_logbfmt);
}
mio_ooi_t mio_logbfmt (mio_t* mio, mio_bitmask_t mask, const mio_bch_t* fmt, ...)
{
int x;
va_list ap;
mio_fmtout_t fo;
if (mio->log.default_type_mask & MIO_LOG_ALL_TYPES)
{
/* if a type is given, it's not untyped any more.
* mask off the UNTYPED bit */
mask &= ~MIO_LOG_UNTYPED;
/* if the default_type_mask has the UNTYPED bit on,
* it'll get turned back on */
mask |= (mio->log.default_type_mask & MIO_LOG_ALL_TYPES);
}
fo.mask = mask;
fo.putch = put_ooch;
fo.putcs = put_oocs;
va_start (ap, fmt);
x = _logbfmtv(mio, fmt, &fo, ap);
va_end (ap);
if (mio->log.len > 0 && mio->log.ptr[mio->log.len - 1] == '\n')
{
vmprim_log_write (mio, mio->log.last_mask, mio->log.ptr, mio->log.len);
mio->log.len = 0;
}
return (x <= -1)? -1: fo.count;
}
mio_ooi_t mio_logufmt (mio_t* mio, mio_bitmask_t mask, const mio_uch_t* fmt, ...)
{
int x;
va_list ap;
mio_fmtout_t fo;
if (mio->log.default_type_mask & MIO_LOG_ALL_TYPES)
{
mask &= ~MIO_LOG_UNTYPED;
mask |= (mio->log.default_type_mask & MIO_LOG_ALL_TYPES);
}
fo.mask = mask;
fo.putch = put_ooch;
fo.putcs = put_oocs;
va_start (ap, fmt);
x = _logufmtv(mio, fmt, &fo, ap);
va_end (ap);
if (mio->log.len > 0 && mio->log.ptr[mio->log.len - 1] == '\n')
{
vmprim_log_write (mio, mio->log.last_mask, mio->log.ptr, mio->log.len);
mio->log.len = 0;
}
return (x <= -1)? -1: fo.count;
}
/* --------------------------------------------------------------------------
* ERROR MESSAGE FORMATTING
* -------------------------------------------------------------------------- */
static int put_errch (mio_t* mio, mio_bitmask_t mask, mio_ooch_t ch, mio_oow_t len)
{
mio_oow_t max;
max = MIO_COUNTOF(mio->errmsg.buf) - mio->errmsg.len - 1;
if (len > max) len = max;
if (len <= 0) return 1;
while (len > 0)
{
mio->errmsg.buf[mio->errmsg.len++] = ch;
len--;
}
mio->errmsg.buf[mio->errmsg.len] = '\0';
return 1; /* success */
}
static int put_errcs (mio_t* mio, mio_bitmask_t mask, const mio_ooch_t* ptr, mio_oow_t len)
{
mio_oow_t max;
max = MIO_COUNTOF(mio->errmsg.buf) - mio->errmsg.len - 1;
if (len > max) len = max;
if (len <= 0) return 1;
MIO_MEMCPY (&mio->errmsg.buf[mio->errmsg.len], ptr, len * MIO_SIZEOF(*ptr));
mio->errmsg.len += len;
mio->errmsg.buf[mio->errmsg.len] = '\0';
return 1; /* success */
}
static mio_ooi_t __errbfmtv (mio_t* mio, mio_bitmask_t mask, const mio_bch_t* fmt, ...);
static int _errbfmtv (mio_t* mio, const mio_bch_t* fmt, mio_fmtout_t* data, va_list ap)
{
return __logbfmtv (mio, fmt, data, ap, __errbfmtv);
}
static int _errufmtv (mio_t* mio, const mio_uch_t* fmt, mio_fmtout_t* data, va_list ap)
{
return __logufmtv (mio, fmt, data, ap, __errbfmtv);
}
static mio_ooi_t __errbfmtv (mio_t* mio, mio_bitmask_t mask, const mio_bch_t* fmt, ...)
{
va_list ap;
mio_fmtout_t fo;
fo.mask = 0; /* not used */
fo.putch = put_errch;
fo.putcs = put_errcs;
va_start (ap, fmt);
_errbfmtv (mio, fmt, &fo, ap);
va_end (ap);
return fo.count;
}
void mio_seterrbfmt (mio_t* mio, mio_errnum_t errnum, const mio_bch_t* fmt, ...)
{
va_list ap;
mio_fmtout_t fo;
if (mio->shuterr) return;
mio->errmsg.len = 0;
fo.mask = 0; /* not used */
fo.putch = put_errch;
fo.putcs = put_errcs;
va_start (ap, fmt);
_errbfmtv (mio, fmt, &fo, ap);
va_end (ap);
mio->errnum = errnum;
}
void mio_seterrufmt (mio_t* mio, mio_errnum_t errnum, const mio_uch_t* fmt, ...)
{
va_list ap;
mio_fmtout_t fo;
if (mio->shuterr) return;
mio->errmsg.len = 0;
fo.mask = 0; /* not used */
fo.putch = put_errch;
fo.putcs = put_errcs;
va_start (ap, fmt);
_errufmtv (mio, fmt, &fo, ap);
va_end (ap);
mio->errnum = errnum;
}
void mio_seterrbfmtv (mio_t* mio, mio_errnum_t errnum, const mio_bch_t* fmt, va_list ap)
{
mio_fmtout_t fo;
if (mio->shuterr) return;
mio->errmsg.len = 0;
fo.mask = 0; /* not used */
fo.putch = put_errch;
fo.putcs = put_errcs;
_errbfmtv (mio, fmt, &fo, ap);
mio->errnum = errnum;
}
void mio_seterrufmtv (mio_t* mio, mio_errnum_t errnum, const mio_uch_t* fmt, va_list ap)
{
mio_fmtout_t fo;
if (mio->shuterr) return;
mio->errmsg.len = 0;
fo.mask = 0; /* not used */
fo.putch = put_errch;
fo.putcs = put_errcs;
_errufmtv (mio, fmt, &fo, ap);
mio->errnum = errnum;
}
/* --------------------------------------------------------------------------
* SUPPORT FOR THE BUILTIN SPRINTF PRIMITIVE FUNCTION
* -------------------------------------------------------------------------- */
static int put_sprcs (mio_t* mio, mio_bitmask_t mask, const mio_ooch_t* ptr, mio_oow_t len)
{
if (len > mio->sprintf.xbuf.capa - mio->sprintf.xbuf.len)
{
mio_ooch_t* tmp;
mio_oow_t newcapa;
newcapa = mio->sprintf.xbuf.len + len + 1;
newcapa = MIO_ALIGN_POW2(newcapa, 256);
tmp = (mio_ooch_t*)mio_reallocmem(mio, mio->sprintf.xbuf.ptr, newcapa * MIO_SIZEOF(*tmp));
if (!tmp) return -1;
mio->sprintf.xbuf.ptr = tmp;
mio->sprintf.xbuf.capa = newcapa;
}
MIO_MEMCPY (&mio->sprintf.xbuf.ptr[mio->sprintf.xbuf.len], ptr, len * MIO_SIZEOF(*ptr));
mio->sprintf.xbuf.len += len;
return 1; /* success */
}
static int put_sprch (mio_t* mio, mio_bitmask_t mask, mio_ooch_t ch, mio_oow_t len)
{
if (len > mio->sprintf.xbuf.capa - mio->sprintf.xbuf.len)
{
mio_ooch_t* tmp;
mio_oow_t newcapa;
newcapa = mio->sprintf.xbuf.len + len + 1;
newcapa = MIO_ALIGN_POW2(newcapa, 256);
tmp = (mio_ooch_t*)mio_reallocmem(mio, mio->sprintf.xbuf.ptr, newcapa * MIO_SIZEOF(*tmp));
if (!tmp) return -1;
mio->sprintf.xbuf.ptr = tmp;
mio->sprintf.xbuf.capa = newcapa;
}
while (len > 0)
{
--len;
mio->sprintf.xbuf.ptr[mio->sprintf.xbuf.len++] = ch;
}
return 1; /* success */
}
static mio_ooi_t __sprbfmtv (mio_t* mio, mio_bitmask_t mask, const mio_bch_t* fmt, ...);
static int _sprbfmtv (mio_t* mio, const mio_bch_t* fmt, mio_fmtout_t* data, va_list ap)
{
return __logbfmtv (mio, fmt, data, ap, __sprbfmtv);
}
/*
static int _sprufmtv (mio_t* mio, const mio_uch_t* fmt, mio_fmtout_t* data, va_list ap)
{
return __logufmtv (mio, fmt, data, ap, __sprbfmtv);
}*/
static mio_ooi_t __sprbfmtv (mio_t* mio, mio_bitmask_t mask, const mio_bch_t* fmt, ...)
{
va_list ap;
mio_fmtout_t fo;
fo.mask = mask; /* not used */
fo.putch = put_sprch;
fo.putcs = put_sprcs;
va_start (ap, fmt);
_sprbfmtv (mio, fmt, &fo, ap);
va_end (ap);
return fo.count;
}
mio_ooi_t mio_sproutbfmt (mio_t* mio, mio_bitmask_t mask, const mio_bch_t* fmt, ...)
{
int x;
va_list ap;
mio_fmtout_t fo;
fo.mask = mask;
fo.putch = put_sprch;
fo.putcs = put_sprcs;
va_start (ap, fmt);
x = _sprbfmtv(mio, fmt, &fo, ap);
va_end (ap);
return (x <= -1)? -1: fo.count;
}
/*
mio_ooi_t mio_sproutufmt (mio_t* mio, mio_bitmask_t mask, const mio_uch_t* fmt, ...)
{
int x;
va_list ap;
mio_fmtout_t fo;
fo.mask = mask;
fo.putch = put_sprch;
fo.putcs = put_sprcs;
va_start (ap, fmt);
x = _sprufmtv (mio, fmt, &fo, ap);
va_end (ap);
return (x <= -1)? -1: fo.count;
}*/

996
mio/lib/logfmtv.h Normal file
View File

@ -0,0 +1,996 @@
/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This file contains a formatted output routine derived from kvprintf()
* of FreeBSD. It has been heavily modified and bug-fixed.
*/
/*
* Copyright (c) 1986, 1988, 1991, 1993
* The Regents of the University of California. All rights reserved.
* (c) UNIX System Laboratories, Inc.
* All or some portions of this file are derived from material licensed
* to the University of California by American Telephone and Telegraph
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
* the permission of UNIX System Laboratories, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
/* NOTE: data output is aborted if the data limit is reached or
* I/O error occurs */
#undef PUT_OOCH
#undef PUT_OOCS
#define PUT_OOCH(c,n) do { \
if (n > 0) { \
int xx; \
if ((xx = data->putch (mio, data->mask, c, n)) <= -1) goto oops; \
if (xx == 0) goto done; \
data->count += n; \
} \
} while (0)
#define PUT_OOCS(ptr,len) do { \
if (len > 0) { \
int xx; \
if ((xx = data->putcs (mio, data->mask, ptr, len)) <= -1) goto oops; \
if (xx == 0) goto done; \
data->count += len; \
} \
} while (0)
static int logfmtv (mio_t* mio, const fmtchar_t* fmt, mio_fmtout_t* data, va_list ap, outbfmt_t outbfmt)
{
const fmtchar_t* percent;
const fmtchar_t* checkpoint;
mio_bch_t nbuf[MAXNBUF], bch;
const mio_bch_t* nbufp;
int n, base, neg, sign;
mio_ooi_t tmp, width, precision;
mio_ooch_t ch, padc;
#if !defined(FMTCHAR_IS_OOCH)
fmtchar_t fch;
#endif
int lm_flag, lm_dflag, flagc, numlen;
mio_uintmax_t num = 0;
int stop = 0;
#if 0
mio_bchbuf_t* fltfmt;
mio_oochbuf_t* fltout;
#endif
mio_bch_t* (*sprintn) (mio_bch_t* nbuf, mio_uintmax_t num, int base, mio_ooi_t* lenp);
data->count = 0;
#if 0
fltfmt = &mio->d->fltfmt;
fltout = &mio->d->fltout;
fltfmt->ptr = fltfmt->buf;
fltfmt->capa = MIO_COUNTOF(fltfmt->buf) - 1;
fltout->ptr = fltout->buf;
fltout->capa = MIO_COUNTOF(fltout->buf) - 1;
#endif
while (1)
{
#if defined(FMTCHAR_IS_OOCH)
checkpoint = fmt;
while ((ch = *fmt++) != '%' || stop)
{
if (ch == '\0')
{
PUT_OOCS (checkpoint, fmt - checkpoint - 1);
goto done;
}
}
PUT_OOCS (checkpoint, fmt - checkpoint - 1);
#else
#if defined(MIO_OOCH_IS_UCH)
/* fmtchar is bch. ooch is uch. convert bch to uch */
checkpoint = fmt;
while ((fch = *fmt++) != '%' || stop)
{
if (fch == '\0') break;
}
while (checkpoint < fmt - 1)
{
mio_oow_t cvlen, bclen;
bclen = fmt - checkpoint - 1;
cvlen = mio->cmgr->bctouc(checkpoint, bclen, &ch);
if (cvlen == 0 || cvlen > bclen) goto oops;
checkpoint += cvlen;
PUT_OOCH (ch, 1);
}
if (fch == '\0') goto done;
#else
while ((fch = *fmt++) != '%' || stop)
{
mio_bch_t bcsbuf[MIO_MBLEN_MAX + 1];
mio_oow_t ucslen, bcslen;
if (fch == '\0') goto done;
/* fmtchar is uch. ooch is bch. convert uch to bch */
ucslen = 1;
bcslen = MIO_COUNTOF(bcsbuf);
if (mio_conv_uchars_to_bchars_with_cmgr(&fch, &ucslen, bcsbuf, &bcslen, mio->cmgr) <= -1) goto oops;
PUT_OOCS (bcsbuf, bcslen);
}
#endif
#endif
percent = fmt - 1;
padc = ' ';
width = 0; precision = 0;
neg = 0; sign = 0;
lm_flag = 0; lm_dflag = 0; flagc = 0;
sprintn = sprintn_lower;
reswitch:
switch (ch = *fmt++)
{
case '%': /* %% */
bch = ch;
goto print_lowercase_c;
/* flag characters */
case '.':
if (flagc & FLAGC_DOT) goto invalid_format;
flagc |= FLAGC_DOT;
goto reswitch;
case '#':
if (flagc & (FLAGC_WIDTH | FLAGC_DOT | FLAGC_LENMOD)) goto invalid_format;
flagc |= FLAGC_SHARP;
goto reswitch;
case ' ':
if (flagc & (FLAGC_WIDTH | FLAGC_DOT | FLAGC_LENMOD)) goto invalid_format;
flagc |= FLAGC_SPACE;
goto reswitch;
case '+': /* place sign for signed conversion */
if (flagc & (FLAGC_WIDTH | FLAGC_DOT | FLAGC_LENMOD)) goto invalid_format;
flagc |= FLAGC_SIGN;
goto reswitch;
case '-': /* left adjusted */
if (flagc & (FLAGC_WIDTH | FLAGC_DOT | FLAGC_LENMOD)) goto invalid_format;
if (flagc & FLAGC_DOT)
{
goto invalid_format;
}
else
{
flagc |= FLAGC_LEFTADJ;
if (flagc & FLAGC_ZEROPAD)
{
padc = ' ';
flagc &= ~FLAGC_ZEROPAD;
}
}
goto reswitch;
case '*': /* take the length from the parameter */
if (flagc & FLAGC_DOT)
{
if (flagc & (FLAGC_STAR2 | FLAGC_PRECISION)) goto invalid_format;
flagc |= FLAGC_STAR2;
precision = va_arg(ap, mio_ooi_t); /* this deviates from the standard printf that accepts 'int' */
if (precision < 0)
{
/* if precision is less than 0,
* treat it as if no .precision is specified */
flagc &= ~FLAGC_DOT;
precision = 0;
}
}
else
{
if (flagc & (FLAGC_STAR1 | FLAGC_WIDTH)) goto invalid_format;
flagc |= FLAGC_STAR1;
width = va_arg(ap, mio_ooi_t); /* it deviates from the standard printf that accepts 'int' */
if (width < 0)
{
/*
if (flagc & FLAGC_LEFTADJ)
flagc &= ~FLAGC_LEFTADJ;
else
*/
flagc |= FLAGC_LEFTADJ;
width = -width;
}
}
goto reswitch;
case '0': /* zero pad */
if (flagc & FLAGC_LENMOD) goto invalid_format;
if (!(flagc & (FLAGC_DOT | FLAGC_LEFTADJ)))
{
padc = '0';
flagc |= FLAGC_ZEROPAD;
goto reswitch;
}
/* end of flags characters */
case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
if (flagc & FLAGC_LENMOD) goto invalid_format;
for (n = 0;; ++fmt)
{
n = n * 10 + ch - '0';
ch = *fmt;
if (ch < '0' || ch > '9') break;
}
if (flagc & FLAGC_DOT)
{
if (flagc & FLAGC_STAR2) goto invalid_format;
precision = n;
flagc |= FLAGC_PRECISION;
}
else
{
if (flagc & FLAGC_STAR1) goto invalid_format;
width = n;
flagc |= FLAGC_WIDTH;
}
goto reswitch;
/* length modifiers */
case 'h': /* short int */
case 'l': /* long int */
case 'q': /* long long int */
case 'j': /* mio_intmax_t/mio_uintmax_t */
case 'z': /* mio_ooi_t/mio_oow_t */
case 't': /* ptrdiff_t */
if (lm_flag & (LF_LD | LF_QD)) goto invalid_format;
flagc |= FLAGC_LENMOD;
if (lm_dflag)
{
/* error */
goto invalid_format;
}
else if (lm_flag)
{
if (lm_tab[ch - 'a'].dflag && lm_flag == lm_tab[ch - 'a'].flag)
{
lm_flag &= ~lm_tab[ch - 'a'].flag;
lm_flag |= lm_tab[ch - 'a'].dflag;
lm_dflag |= lm_flag;
goto reswitch;
}
else
{
/* error */
goto invalid_format;
}
}
else
{
lm_flag |= lm_tab[ch - 'a'].flag;
goto reswitch;
}
break;
case 'L': /* long double */
if (flagc & FLAGC_LENMOD)
{
/* conflict with other length modifier */
goto invalid_format;
}
flagc |= FLAGC_LENMOD;
lm_flag |= LF_LD;
goto reswitch;
case 'Q': /* __float128 */
if (flagc & FLAGC_LENMOD)
{
/* conflict with other length modifier */
goto invalid_format;
}
flagc |= FLAGC_LENMOD;
lm_flag |= LF_QD;
goto reswitch;
/* end of length modifiers */
case 'n': /* number of characters printed so far */
if (lm_flag & LF_J) /* j */
*(va_arg(ap, mio_intmax_t*)) = data->count;
else if (lm_flag & LF_Z) /* z */
*(va_arg(ap, mio_ooi_t*)) = data->count;
#if (MIO_SIZEOF_LONG_LONG > 0)
else if (lm_flag & LF_Q) /* ll */
*(va_arg(ap, long long int*)) = data->count;
#endif
else if (lm_flag & LF_L) /* l */
*(va_arg(ap, long int*)) = data->count;
else if (lm_flag & LF_H) /* h */
*(va_arg(ap, short int*)) = data->count;
else if (lm_flag & LF_C) /* hh */
*(va_arg(ap, char*)) = data->count;
else if (flagc & FLAGC_LENMOD)
goto invalid_format;
else
*(va_arg(ap, int*)) = data->count;
break;
/* signed integer conversions */
case 'd':
case 'i': /* signed conversion */
base = 10;
sign = 1;
goto handle_sign;
/* end of signed integer conversions */
/* unsigned integer conversions */
case 'o':
base = 8;
goto handle_nosign;
case 'u':
base = 10;
goto handle_nosign;
case 'X':
sprintn = sprintn_upper;
case 'x':
base = 16;
goto handle_nosign;
case 'b':
base = 2;
goto handle_nosign;
/* end of unsigned integer conversions */
case 'p': /* pointer */
base = 16;
if (width == 0) flagc |= FLAGC_SHARP;
else flagc &= ~FLAGC_SHARP;
num = (mio_uintptr_t)va_arg(ap, void*);
goto number;
case 'c':
{
/* zeropad must not take effect for 'c' */
if (flagc & FLAGC_ZEROPAD) padc = ' ';
if (lm_flag & LF_L) goto uppercase_c;
#if defined(MIO_OOCH_IS_UCH)
if (lm_flag & LF_J) goto uppercase_c;
#endif
lowercase_c:
bch = MIO_SIZEOF(mio_bch_t) < MIO_SIZEOF(int)? va_arg(ap, int): va_arg(ap, mio_bch_t);
print_lowercase_c:
/* precision 0 doesn't kill the letter */
width--;
if (!(flagc & FLAGC_LEFTADJ) && width > 0) PUT_OOCH (padc, width);
PUT_OOCH (bch, 1);
if ((flagc & FLAGC_LEFTADJ) && width > 0) PUT_OOCH (padc, width);
break;
}
case 'C':
{
mio_uch_t ooch;
/* zeropad must not take effect for 'C' */
if (flagc & FLAGC_ZEROPAD) padc = ' ';
if (lm_flag & LF_H) goto lowercase_c;
#if defined(MIO_OOCH_IS_BCH)
if (lm_flag & LF_J) goto lowercase_c;
#endif
uppercase_c:
ooch = MIO_SIZEOF(mio_uch_t) < MIO_SIZEOF(int)? va_arg(ap, int): va_arg(ap, mio_uch_t);
/* precision 0 doesn't kill the letter */
width--;
if (!(flagc & FLAGC_LEFTADJ) && width > 0) PUT_OOCH (padc, width);
PUT_OOCH (ooch, 1);
if ((flagc & FLAGC_LEFTADJ) && width > 0) PUT_OOCH (padc, width);
break;
}
case 's':
{
const mio_bch_t* bsp;
mio_oow_t bslen, slen;
/* zeropad must not take effect for 'S' */
if (flagc & FLAGC_ZEROPAD) padc = ' ';
if (lm_flag & LF_L) goto uppercase_s;
#if defined(MIO_OOCH_IS_UCH)
if (lm_flag & LF_J) goto uppercase_s;
#endif
lowercase_s:
bsp = va_arg (ap, mio_bch_t*);
if (bsp == MIO_NULL) bsp = bch_nullstr;
#if defined(MIO_OOCH_IS_UCH)
/* get the length */
for (bslen = 0; bsp[bslen]; bslen++);
if (mio_conv_bchars_to_uchars_with_cmgr(bsp, &bslen, MIO_NULL, &slen, mio->cmgr, 0) <= -1) goto oops;
/* slen holds the length after conversion */
n = slen;
if ((flagc & FLAGC_DOT) && precision < slen) n = precision;
width -= n;
if (!(flagc & FLAGC_LEFTADJ) && width > 0) PUT_OOCH (padc, width);
{
mio_ooch_t conv_buf[32];
mio_oow_t conv_len, src_len, tot_len = 0;
while (n > 0)
{
MIO_ASSERT (mio, bslen > tot_len);
src_len = bslen - tot_len;
conv_len = MIO_COUNTOF(conv_buf);
/* this must not fail since the dry-run above was successful */
mio_conv_bchars_to_uchars_with_cmgr(&bsp[tot_len], &src_len, conv_buf, &conv_len, mio->cmgr, 0);
tot_len += src_len;
if (conv_len > n) conv_len = n;
PUT_OOCS (conv_buf, conv_len);
n -= conv_len;
}
}
if ((flagc & FLAGC_LEFTADJ) && width > 0) PUT_OOCH (padc, width);
#else
if (flagc & FLAGC_DOT)
{
for (n = 0; n < precision && bsp[n]; n++);
}
else
{
for (n = 0; bsp[n]; n++);
}
width -= n;
if (!(flagc & FLAGC_LEFTADJ) && width > 0) PUT_OOCH (padc, width);
PUT_OOCS (bsp, n);
if ((flagc & FLAGC_LEFTADJ) && width > 0) PUT_OOCH (padc, width);
#endif
break;
}
case 'S':
{
const mio_uch_t* usp;
mio_oow_t uslen, slen;
/* zeropad must not take effect for 's' */
if (flagc & FLAGC_ZEROPAD) padc = ' ';
if (lm_flag & LF_H) goto lowercase_s;
#if defined(MIO_OOCH_IS_UCH)
if (lm_flag & LF_J) goto lowercase_s;
#endif
uppercase_s:
usp = va_arg (ap, mio_uch_t*);
if (usp == MIO_NULL) usp = uch_nullstr;
#if defined(MIO_OOCH_IS_BCH)
/* get the length */
for (uslen = 0; usp[uslen]; uslen++);
if (mio_conv_uchars_to_bchars_with_cmgr(usp, &uslen, MIO_NULL, &slen, mio->cmgr) <= -1) goto oops;
/* slen holds the length after conversion */
n = slen;
if ((flagc & FLAGC_DOT) && precision < slen) n = precision;
width -= n;
if (!(flagc & FLAGC_LEFTADJ) && width > 0) PUT_OOCH (padc, width);
{
mio_ooch_t conv_buf[32];
mio_oow_t conv_len, src_len, tot_len = 0;
while (n > 0)
{
MIO_ASSERT (mio, uslen > tot_len);
src_len = uslen - tot_len;
conv_len = MIO_COUNTOF(conv_buf);
/* this must not fail since the dry-run above was successful */
mio_conv_uchars_to_bchars_with_cmgr (&usp[tot_len], &src_len, conv_buf, &conv_len, mio->cmgr);
tot_len += src_len;
if (conv_len > n) conv_len = n;
PUT_OOCS (conv_buf, conv_len);
n -= conv_len;
}
}
if ((flagc & FLAGC_LEFTADJ) && width > 0) PUT_OOCH (padc, width);
#else
if (flagc & FLAGC_DOT)
{
for (n = 0; n < precision && usp[n]; n++);
}
else
{
for (n = 0; usp[n]; n++);
}
width -= n;
if (!(flagc & FLAGC_LEFTADJ) && width > 0) PUT_OOCH (padc, width);
PUT_OOCS (usp, n);
if ((flagc & FLAGC_LEFTADJ) && width > 0) PUT_OOCH (padc, width);
#endif
break;
}
case 'O': /* object - ignore precision, width, adjustment */
if (print_object(mio, data->mask, va_arg(ap, mio_oop_t), outbfmt) <= -1) goto oops;
break;
#if 0
case 'e':
case 'E':
case 'f':
case 'F':
case 'g':
case 'G':
/*
case 'a':
case 'A':
*/
{
/* let me rely on snprintf until i implement float-point to string conversion */
int q;
mio_oow_t fmtlen;
#if (MIO_SIZEOF___FLOAT128 > 0) && defined(HAVE_QUADMATH_SNPRINTF)
__float128 v_qd;
#endif
long double v_ld;
double v_d;
int dtype = 0;
mio_oow_t newcapa;
if (lm_flag & LF_J)
{
#if (MIO_SIZEOF___FLOAT128 > 0) && defined(HAVE_QUADMATH_SNPRINTF) && (MIO_SIZEOF_FLTMAX_T == MIO_SIZEOF___FLOAT128)
v_qd = va_arg (ap, mio_fltmax_t);
dtype = LF_QD;
#elif MIO_SIZEOF_FLTMAX_T == MIO_SIZEOF_DOUBLE
v_d = va_arg (ap, mio_fltmax_t);
#elif MIO_SIZEOF_FLTMAX_T == MIO_SIZEOF_LONG_DOUBLE
v_ld = va_arg (ap, mio_fltmax_t);
dtype = LF_LD;
#else
#error Unsupported mio_flt_t
#endif
}
else if (lm_flag & LF_Z)
{
/* mio_flt_t is limited to double or long double */
/* precedence goes to double if sizeof(double) == sizeof(long double)
* for example, %Lf didn't work on some old platforms.
* so i prefer the format specifier with no modifier.
*/
#if MIO_SIZEOF_FLT_T == MIO_SIZEOF_DOUBLE
v_d = va_arg (ap, mio_flt_t);
#elif MIO_SIZEOF_FLT_T == MIO_SIZEOF_LONG_DOUBLE
v_ld = va_arg (ap, mio_flt_t);
dtype = LF_LD;
#else
#error Unsupported mio_flt_t
#endif
}
else if (lm_flag & (LF_LD | LF_L))
{
v_ld = va_arg (ap, long double);
dtype = LF_LD;
}
#if (MIO_SIZEOF___FLOAT128 > 0) && defined(HAVE_QUADMATH_SNPRINTF)
else if (lm_flag & (LF_QD | LF_Q))
{
v_qd = va_arg (ap, __float128);
dtype = LF_QD;
}
#endif
else if (flagc & FLAGC_LENMOD)
{
goto invalid_format;
}
else
{
v_d = va_arg (ap, double);
}
fmtlen = fmt - percent;
if (fmtlen > fltfmt->capa)
{
if (fltfmt->ptr == fltfmt->buf)
{
fltfmt->ptr = MIO_MMGR_ALLOC (MIO_MMGR_GETDFL(), MIO_SIZEOF(*fltfmt->ptr) * (fmtlen + 1));
if (fltfmt->ptr == MIO_NULL) goto oops;
}
else
{
mio_mchar_t* tmpptr;
tmpptr = MIO_MMGR_REALLOC (MIO_MMGR_GETDFL(), fltfmt->ptr, MIO_SIZEOF(*fltfmt->ptr) * (fmtlen + 1));
if (tmpptr == MIO_NULL) goto oops;
fltfmt->ptr = tmpptr;
}
fltfmt->capa = fmtlen;
}
/* compose back the format specifier */
fmtlen = 0;
fltfmt->ptr[fmtlen++] = '%';
if (flagc & FLAGC_SPACE) fltfmt->ptr[fmtlen++] = ' ';
if (flagc & FLAGC_SHARP) fltfmt->ptr[fmtlen++] = '#';
if (flagc & FLAGC_SIGN) fltfmt->ptr[fmtlen++] = '+';
if (flagc & FLAGC_LEFTADJ) fltfmt->ptr[fmtlen++] = '-';
if (flagc & FLAGC_ZEROPAD) fltfmt->ptr[fmtlen++] = '0';
if (flagc & FLAGC_STAR1) fltfmt->ptr[fmtlen++] = '*';
else if (flagc & FLAGC_WIDTH)
{
fmtlen += mio_fmtuintmaxtombs (
&fltfmt->ptr[fmtlen], fltfmt->capa - fmtlen,
width, 10, -1, '\0', MIO_NULL);
}
if (flagc & FLAGC_DOT) fltfmt->ptr[fmtlen++] = '.';
if (flagc & FLAGC_STAR2) fltfmt->ptr[fmtlen++] = '*';
else if (flagc & FLAGC_PRECISION)
{
fmtlen += mio_fmtuintmaxtombs (
&fltfmt->ptr[fmtlen], fltfmt->capa - fmtlen,
precision, 10, -1, '\0', MIO_NULL);
}
if (dtype == LF_LD)
fltfmt->ptr[fmtlen++] = 'L';
#if (MIO_SIZEOF___FLOAT128 > 0)
else if (dtype == LF_QD)
fltfmt->ptr[fmtlen++] = 'Q';
#endif
fltfmt->ptr[fmtlen++] = ch;
fltfmt->ptr[fmtlen] = '\0';
#if defined(HAVE_SNPRINTF)
/* nothing special here */
#else
/* best effort to avoid buffer overflow when no snprintf is available.
* i really can't do much if it happens. */
newcapa = precision + width + 32;
if (fltout->capa < newcapa)
{
MIO_ASSERT (mio, fltout->ptr == fltout->buf);
fltout->ptr = MIO_MMGR_ALLOC (MIO_MMGR_GETDFL(), MIO_SIZEOF(char_t) * (newcapa + 1));
if (fltout->ptr == MIO_NULL) goto oops;
fltout->capa = newcapa;
}
#endif
while (1)
{
if (dtype == LF_LD)
{
#if defined(HAVE_SNPRINTF)
q = snprintf ((mio_mchar_t*)fltout->ptr, fltout->capa + 1, fltfmt->ptr, v_ld);
#else
q = sprintf ((mio_mchar_t*)fltout->ptr, fltfmt->ptr, v_ld);
#endif
}
#if (MIO_SIZEOF___FLOAT128 > 0) && defined(HAVE_QUADMATH_SNPRINTF)
else if (dtype == LF_QD)
{
q = quadmath_snprintf ((mio_mchar_t*)fltout->ptr, fltout->capa + 1, fltfmt->ptr, v_qd);
}
#endif
else
{
#if defined(HAVE_SNPRINTF)
q = snprintf ((mio_mchar_t*)fltout->ptr, fltout->capa + 1, fltfmt->ptr, v_d);
#else
q = sprintf ((mio_mchar_t*)fltout->ptr, fltfmt->ptr, v_d);
#endif
}
if (q <= -1) goto oops;
if (q <= fltout->capa) break;
newcapa = fltout->capa * 2;
if (newcapa < q) newcapa = q;
if (fltout->ptr == fltout->sbuf)
{
fltout->ptr = MIO_MMGR_ALLOC (MIO_MMGR_GETDFL(), MIO_SIZEOF(char_t) * (newcapa + 1));
if (fltout->ptr == MIO_NULL) goto oops;
}
else
{
char_t* tmpptr;
tmpptr = MIO_MMGR_REALLOC (MIO_MMGR_GETDFL(), fltout->ptr, MIO_SIZEOF(char_t) * (newcapa + 1));
if (tmpptr == MIO_NULL) goto oops;
fltout->ptr = tmpptr;
}
fltout->capa = newcapa;
}
if (MIO_SIZEOF(char_t) != MIO_SIZEOF(mio_mchar_t))
{
fltout->ptr[q] = '\0';
while (q > 0)
{
q--;
fltout->ptr[q] = ((mio_mchar_t*)fltout->ptr)[q];
}
}
sp = fltout->ptr;
flagc &= ~FLAGC_DOT;
width = 0;
precision = 0;
goto print_lowercase_s;
}
#endif
handle_nosign:
sign = 0;
if (lm_flag & LF_J)
{
#if defined(__GNUC__) && \
(MIO_SIZEOF_UINTMAX_T > MIO_SIZEOF_OOW_T) && \
(MIO_SIZEOF_UINTMAX_T != MIO_SIZEOF_LONG_LONG) && \
(MIO_SIZEOF_UINTMAX_T != MIO_SIZEOF_LONG)
/* GCC-compiled binaries crashed when getting mio_uintmax_t with va_arg.
* This is just a work-around for it */
int i;
for (i = 0, num = 0; i < MIO_SIZEOF(mio_uintmax_t) / MIO_SIZEOF(mio_oow_t); i++)
{
#if defined(MIO_ENDIAN_BIG)
num = num << (8 * MIO_SIZEOF(mio_oow_t)) | (va_arg (ap, mio_oow_t));
#else
register int shift = i * MIO_SIZEOF(mio_oow_t);
mio_oow_t x = va_arg (ap, mio_oow_t);
num |= (mio_uintmax_t)x << (shift * 8);
#endif
}
#else
num = va_arg (ap, mio_uintmax_t);
#endif
}
#if 0
else if (lm_flag & LF_T)
num = va_arg (ap, mio_ptrdiff_t);
#endif
else if (lm_flag & LF_Z)
num = va_arg (ap, mio_oow_t);
#if (MIO_SIZEOF_LONG_LONG > 0)
else if (lm_flag & LF_Q)
num = va_arg (ap, unsigned long long int);
#endif
else if (lm_flag & (LF_L | LF_LD))
num = va_arg (ap, unsigned long int);
else if (lm_flag & LF_H)
num = (unsigned short int)va_arg (ap, int);
else if (lm_flag & LF_C)
num = (unsigned char)va_arg (ap, int);
else
num = va_arg (ap, unsigned int);
goto number;
handle_sign:
if (lm_flag & LF_J)
{
#if defined(__GNUC__) && \
(MIO_SIZEOF_INTMAX_T > MIO_SIZEOF_OOI_T) && \
(MIO_SIZEOF_UINTMAX_T != MIO_SIZEOF_LONG_LONG) && \
(MIO_SIZEOF_UINTMAX_T != MIO_SIZEOF_LONG)
/* GCC-compiled binraries crashed when getting mio_uintmax_t with va_arg.
* This is just a work-around for it */
int i;
for (i = 0, num = 0; i < MIO_SIZEOF(mio_intmax_t) / MIO_SIZEOF(mio_oow_t); i++)
{
#if defined(MIO_ENDIAN_BIG)
num = num << (8 * MIO_SIZEOF(mio_oow_t)) | (va_arg (ap, mio_oow_t));
#else
register int shift = i * MIO_SIZEOF(mio_oow_t);
mio_oow_t x = va_arg (ap, mio_oow_t);
num |= (mio_uintmax_t)x << (shift * 8);
#endif
}
#else
num = va_arg (ap, mio_intmax_t);
#endif
}
#if 0
else if (lm_flag & LF_T)
num = va_arg(ap, mio_ptrdiff_t);
#endif
else if (lm_flag & LF_Z)
num = va_arg (ap, mio_ooi_t);
#if (MIO_SIZEOF_LONG_LONG > 0)
else if (lm_flag & LF_Q)
num = va_arg (ap, long long int);
#endif
else if (lm_flag & (LF_L | LF_LD))
num = va_arg (ap, long int);
else if (lm_flag & LF_H)
num = (short int)va_arg (ap, int);
else if (lm_flag & LF_C)
num = (char)va_arg (ap, int);
else
num = va_arg (ap, int);
number:
if (sign && (mio_intmax_t)num < 0)
{
neg = 1;
num = -(mio_intmax_t)num;
}
nbufp = sprintn (nbuf, num, base, &tmp);
if ((flagc & FLAGC_SHARP) && num != 0)
{
if (base == 2 || base == 8) tmp += 2;
else if (base == 16) tmp += 3;
}
if (neg) tmp++;
else if (flagc & FLAGC_SIGN) tmp++;
else if (flagc & FLAGC_SPACE) tmp++;
numlen = (int)((const mio_bch_t*)nbufp - (const mio_bch_t*)nbuf);
if ((flagc & FLAGC_DOT) && precision > numlen)
{
/* extra zeros for precision specified */
tmp += (precision - numlen);
}
if (!(flagc & FLAGC_LEFTADJ) && !(flagc & FLAGC_ZEROPAD) && width > 0 && (width -= tmp) > 0)
{
PUT_OOCH (padc, width);
width = 0;
}
if (neg) PUT_OOCH ('-', 1);
else if (flagc & FLAGC_SIGN) PUT_OOCH ('+', 1);
else if (flagc & FLAGC_SPACE) PUT_OOCH (' ', 1);
if ((flagc & FLAGC_SHARP) && num != 0)
{
if (base == 2)
{
PUT_OOCH ('2', 1);
PUT_OOCH ('r', 1);
}
if (base == 8)
{
PUT_OOCH ('8', 1);
PUT_OOCH ('r', 1);
}
else if (base == 16)
{
PUT_OOCH ('1', 1);
PUT_OOCH ('6', 1);
PUT_OOCH ('r', 1);
}
}
if ((flagc & FLAGC_DOT) && precision > numlen)
{
/* extra zeros for precision specified */
PUT_OOCH ('0', precision - numlen);
}
if (!(flagc & FLAGC_LEFTADJ) && width > 0 && (width -= tmp) > 0)
{
PUT_OOCH (padc, width);
}
while (*nbufp) PUT_OOCH (*nbufp--, 1); /* output actual digits */
if ((flagc & FLAGC_LEFTADJ) && width > 0 && (width -= tmp) > 0)
{
PUT_OOCH (padc, width);
}
break;
invalid_format:
#if defined(FMTCHAR_IS_OOCH)
PUT_OOCS (percent, fmt - percent);
#else
while (percent < fmt) PUT_OOCH (*percent++, 1);
#endif
break;
default:
#if defined(FMTCHAR_IS_OOCH)
PUT_OOCS (percent, fmt - percent);
#else
while (percent < fmt) PUT_OOCH (*percent++, 1);
#endif
/*
* Since we ignore an formatting argument it is no
* longer safe to obey the remaining formatting
* arguments as the arguments will no longer match
* the format specs.
*/
stop = 1;
break;
}
}
done:
return 0;
oops:
return -1;
}
#undef PUT_OOCH

View File

@ -26,6 +26,7 @@
#include <mio.h>
#include <mio-utl.h>
#include <mio-sck.h>
#include <mio-pro.h>

View File

@ -340,6 +340,9 @@
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
#undef HAVE_NDIR_H
/* Define to 1 if you have the <netinet/in.h> header file. */
#undef HAVE_NETINET_IN_H
/* Define to 1 if you have the <netinet/sctp.h> header file. */
#undef HAVE_NETINET_SCTP_H

View File

@ -107,7 +107,7 @@ static int make_param (mio_t* mio, const mio_bch_t* cmd, int flags, param_t* par
param->argv = MIO_MMGR_ALLOC (mio->mmgr, (fcnt + 1) * MIO_SIZEOF(argv[0]));
if (param->argv == MIO_NULL)
{
mio->errnum = MIO_ENOMEM;
mio->errnum = MIO_ESYSMEM;
goto oops;
}
}

View File

@ -28,6 +28,9 @@
#define _MIO_PRV_H_
#include "mio.h"
#include "mio-utl.h"
#include <stdarg.h>
/*TODO: redefine and remove these */
#include <assert.h>
@ -40,58 +43,6 @@
#define MIO_MEMCMP(dst,src,count) memcmp(dst,src,count)
#define MIO_ASSERT assert
#define MIO_CWQFL_SIZE 16
#define MIO_CWQFL_ALIGN 16
typedef struct mio_mux_t mio_mux_t;
struct mio_t
{
mio_mmgr_t* mmgr;
mio_errnum_t errnum;
mio_stopreq_t stopreq; /* stop request to abort mio_loop() */
struct
{
mio_dev_t* head;
mio_dev_t* tail;
} actdev; /* active devices */
struct
{
mio_dev_t* head;
mio_dev_t* tail;
} hltdev; /* halted devices */
struct
{
mio_dev_t* head;
mio_dev_t* tail;
} zmbdev; /* zombie devices */
mio_uint8_t bigbuf[65535]; /* TODO: make this dynamic depending on devices added. device may indicate a buffer size required??? */
unsigned int renew_watch: 1;
unsigned int in_exec: 1;
struct
{
mio_oow_t capa;
mio_oow_t size;
mio_tmrjob_t* jobs;
} tmr;
mio_cwq_t cwq;
mio_cwq_t* cwqfl[MIO_CWQFL_SIZE]; /* list of free cwq objects */
/* platform specific fields below */
#if defined(_WIN32)
HANDLE iocp;
#else
mio_mux_t* mux;
#endif
};
#define MIO_EPOCH_YEAR (1970)
#define MIO_EPOCH_MON (1)

View File

@ -142,7 +142,7 @@ mio_tmridx_t mio_instmrjob (mio_t* mio, const mio_tmrjob_t* job)
tmp = (mio_tmrjob_t*)MIO_MMGR_REALLOC (mio->mmgr, mio->tmr.jobs, new_capa * MIO_SIZEOF(*tmp));
if (tmp == MIO_NULL)
{
mio->errnum = MIO_ENOMEM;
mio->errnum = MIO_ESYSMEM;
return MIO_TMRIDX_INVALID;
}

View File

@ -1,526 +0,0 @@
/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "mio-prv.h"
/* ========================================================================= */
#if defined(MIO_HAVE_UINT16_T)
mio_uint16_t mio_ntoh16 (mio_uint16_t x)
{
#if defined(MIO_ENDIAN_BIG)
return x;
#elif defined(MIO_ENDIAN_LITTLE)
mio_uint8_t* c = (mio_uint8_t*)&x;
return (mio_uint16_t)(
((mio_uint16_t)c[0] << 8) |
((mio_uint16_t)c[1] << 0));
#else
# error Unknown endian
#endif
}
mio_uint16_t mio_hton16 (mio_uint16_t x)
{
#if defined(MIO_ENDIAN_BIG)
return x;
#elif defined(MIO_ENDIAN_LITTLE)
mio_uint8_t* c = (mio_uint8_t*)&x;
return (mio_uint16_t)(
((mio_uint16_t)c[0] << 8) |
((mio_uint16_t)c[1] << 0));
#else
# error Unknown endian
#endif
}
#endif
/* ========================================================================= */
#if defined(MIO_HAVE_UINT32_T)
mio_uint32_t mio_ntoh32 (mio_uint32_t x)
{
#if defined(MIO_ENDIAN_BIG)
return x;
#elif defined(MIO_ENDIAN_LITTLE)
mio_uint8_t* c = (mio_uint8_t*)&x;
return (mio_uint32_t)(
((mio_uint32_t)c[0] << 24) |
((mio_uint32_t)c[1] << 16) |
((mio_uint32_t)c[2] << 8) |
((mio_uint32_t)c[3] << 0));
#else
# error Unknown endian
#endif
}
mio_uint32_t mio_hton32 (mio_uint32_t x)
{
#if defined(MIO_ENDIAN_BIG)
return x;
#elif defined(MIO_ENDIAN_LITTLE)
mio_uint8_t* c = (mio_uint8_t*)&x;
return (mio_uint32_t)(
((mio_uint32_t)c[0] << 24) |
((mio_uint32_t)c[1] << 16) |
((mio_uint32_t)c[2] << 8) |
((mio_uint32_t)c[3] << 0));
#else
# error Unknown endian
#endif
}
#endif
/* ========================================================================= */
#if defined(MIO_HAVE_UINT64_T)
mio_uint64_t mio_ntoh64 (mio_uint64_t x)
{
#if defined(MIO_ENDIAN_BIG)
return x;
#elif defined(MIO_ENDIAN_LITTLE)
mio_uint8_t* c = (mio_uint8_t*)&x;
return (mio_uint64_t)(
((mio_uint64_t)c[0] << 56) |
((mio_uint64_t)c[1] << 48) |
((mio_uint64_t)c[2] << 40) |
((mio_uint64_t)c[3] << 32) |
((mio_uint64_t)c[4] << 24) |
((mio_uint64_t)c[5] << 16) |
((mio_uint64_t)c[6] << 8) |
((mio_uint64_t)c[7] << 0));
#else
# error Unknown endian
#endif
}
mio_uint64_t mio_hton64 (mio_uint64_t x)
{
#if defined(MIO_ENDIAN_BIG)
return x;
#elif defined(MIO_ENDIAN_LITTLE)
mio_uint8_t* c = (mio_uint8_t*)&x;
return (mio_uint64_t)(
((mio_uint64_t)c[0] << 56) |
((mio_uint64_t)c[1] << 48) |
((mio_uint64_t)c[2] << 40) |
((mio_uint64_t)c[3] << 32) |
((mio_uint64_t)c[4] << 24) |
((mio_uint64_t)c[5] << 16) |
((mio_uint64_t)c[6] << 8) |
((mio_uint64_t)c[7] << 0));
#else
# error Unknown endian
#endif
}
#endif
/* ========================================================================= */
#if defined(MIO_HAVE_UINT128_T)
mio_uint128_t mio_ntoh128 (mio_uint128_t x)
{
#if defined(MIO_ENDIAN_BIG)
return x;
#elif defined(MIO_ENDIAN_LITTLE)
mio_uint8_t* c = (mio_uint8_t*)&x;
return (mio_uint128_t)(
((mio_uint128_t)c[0] << 120) |
((mio_uint128_t)c[1] << 112) |
((mio_uint128_t)c[2] << 104) |
((mio_uint128_t)c[3] << 96) |
((mio_uint128_t)c[4] << 88) |
((mio_uint128_t)c[5] << 80) |
((mio_uint128_t)c[6] << 72) |
((mio_uint128_t)c[7] << 64) |
((mio_uint128_t)c[8] << 56) |
((mio_uint128_t)c[9] << 48) |
((mio_uint128_t)c[10] << 40) |
((mio_uint128_t)c[11] << 32) |
((mio_uint128_t)c[12] << 24) |
((mio_uint128_t)c[13] << 16) |
((mio_uint128_t)c[14] << 8) |
((mio_uint128_t)c[15] << 0));
#else
# error Unknown endian
#endif
}
mio_uint128_t mio_hton128 (mio_uint128_t x)
{
#if defined(MIO_ENDIAN_BIG)
return x;
#elif defined(MIO_ENDIAN_LITTLE)
mio_uint8_t* c = (mio_uint8_t*)&x;
return (mio_uint128_t)(
((mio_uint128_t)c[0] << 120) |
((mio_uint128_t)c[1] << 112) |
((mio_uint128_t)c[2] << 104) |
((mio_uint128_t)c[3] << 96) |
((mio_uint128_t)c[4] << 88) |
((mio_uint128_t)c[5] << 80) |
((mio_uint128_t)c[6] << 72) |
((mio_uint128_t)c[7] << 64) |
((mio_uint128_t)c[8] << 56) |
((mio_uint128_t)c[9] << 48) |
((mio_uint128_t)c[10] << 40) |
((mio_uint128_t)c[11] << 32) |
((mio_uint128_t)c[12] << 24) |
((mio_uint128_t)c[13] << 16) |
((mio_uint128_t)c[14] << 8) |
((mio_uint128_t)c[15] << 0));
#else
# error Unknown endian
#endif
}
#endif
/* ========================================================================= */
#define MIO_MT(x) (x)
#define IS_MSPACE(x) ((x) == MIO_MT(' ') || (x) == MIO_MT('\t') || (x) == MIO_MT('\n') || (x) == MIO_MT('\r'))
mio_bch_t* mio_mbsdup (mio_t* mio, const mio_bch_t* src)
{
mio_bch_t* dst;
mio_oow_t len;
dst = (mio_bch_t*)src;
while (*dst != MIO_MT('\0')) dst++;
len = dst - src;
dst = MIO_MMGR_ALLOC (mio->mmgr, (len + 1) * MIO_SIZEOF(*src));
if (!dst)
{
mio->errnum = MIO_ENOMEM;
return MIO_NULL;
}
MIO_MEMCPY (dst, src, (len + 1) * MIO_SIZEOF(*src));
return dst;
}
mio_oow_t mio_mbscpy (mio_bch_t* buf, const mio_bch_t* str)
{
mio_bch_t* org = buf;
while ((*buf++ = *str++) != MIO_MT('\0'));
return buf - org - 1;
}
int mio_mbsspltrn (
mio_bch_t* s, const mio_bch_t* delim,
mio_bch_t lquote, mio_bch_t rquote,
mio_bch_t escape, const mio_bch_t* trset)
{
mio_bch_t* p = s, *d;
mio_bch_t* sp = MIO_NULL, * ep = MIO_NULL;
int delim_mode;
int cnt = 0;
if (delim == MIO_NULL) delim_mode = 0;
else
{
delim_mode = 1;
for (d = (mio_bch_t*)delim; *d != MIO_MT('\0'); d++)
if (!IS_MSPACE(*d)) delim_mode = 2;
}
if (delim_mode == 0)
{
/* skip preceding space characters */
while (IS_MSPACE(*p)) p++;
/* when 0 is given as "delim", it has an effect of cutting
preceding and trailing space characters off "s". */
if (lquote != MIO_MT('\0') && *p == lquote)
{
mio_mbscpy (p, p + 1);
for (;;)
{
if (*p == MIO_MT('\0')) return -1;
if (escape != MIO_MT('\0') && *p == escape)
{
if (trset != MIO_NULL && p[1] != MIO_MT('\0'))
{
const mio_bch_t* ep = trset;
while (*ep != MIO_MT('\0'))
{
if (p[1] == *ep++)
{
p[1] = *ep;
break;
}
}
}
mio_mbscpy (p, p + 1);
}
else
{
if (*p == rquote)
{
p++;
break;
}
}
if (sp == 0) sp = p;
ep = p;
p++;
}
while (IS_MSPACE(*p)) p++;
if (*p != MIO_MT('\0')) return -1;
if (sp == 0 && ep == 0) s[0] = MIO_MT('\0');
else
{
ep[1] = MIO_MT('\0');
if (s != (mio_bch_t*)sp) mio_mbscpy (s, sp);
cnt++;
}
}
else
{
while (*p)
{
if (!IS_MSPACE(*p))
{
if (sp == 0) sp = p;
ep = p;
}
p++;
}
if (sp == 0 && ep == 0) s[0] = MIO_MT('\0');
else
{
ep[1] = MIO_MT('\0');
if (s != (mio_bch_t*)sp) mio_mbscpy (s, sp);
cnt++;
}
}
}
else if (delim_mode == 1)
{
mio_bch_t* o;
while (*p)
{
o = p;
while (IS_MSPACE(*p)) p++;
if (o != p) { mio_mbscpy (o, p); p = o; }
if (lquote != MIO_MT('\0') && *p == lquote)
{
mio_mbscpy (p, p + 1);
for (;;)
{
if (*p == MIO_MT('\0')) return -1;
if (escape != MIO_MT('\0') && *p == escape)
{
if (trset != MIO_NULL && p[1] != MIO_MT('\0'))
{
const mio_bch_t* ep = trset;
while (*ep != MIO_MT('\0'))
{
if (p[1] == *ep++)
{
p[1] = *ep;
break;
}
}
}
mio_mbscpy (p, p + 1);
}
else
{
if (*p == rquote)
{
*p++ = MIO_MT('\0');
cnt++;
break;
}
}
p++;
}
}
else
{
o = p;
for (;;)
{
if (*p == MIO_MT('\0'))
{
if (o != p) cnt++;
break;
}
if (IS_MSPACE (*p))
{
*p++ = MIO_MT('\0');
cnt++;
break;
}
p++;
}
}
}
}
else /* if (delim_mode == 2) */
{
mio_bch_t* o;
int ok;
while (*p != MIO_MT('\0'))
{
o = p;
while (IS_MSPACE(*p)) p++;
if (o != p) { mio_mbscpy (o, p); p = o; }
if (lquote != MIO_MT('\0') && *p == lquote)
{
mio_mbscpy (p, p + 1);
for (;;)
{
if (*p == MIO_MT('\0')) return -1;
if (escape != MIO_MT('\0') && *p == escape)
{
if (trset != MIO_NULL && p[1] != MIO_MT('\0'))
{
const mio_bch_t* ep = trset;
while (*ep != MIO_MT('\0'))
{
if (p[1] == *ep++)
{
p[1] = *ep;
break;
}
}
}
mio_mbscpy (p, p + 1);
}
else
{
if (*p == rquote)
{
*p++ = MIO_MT('\0');
cnt++;
break;
}
}
p++;
}
ok = 0;
while (IS_MSPACE(*p)) p++;
if (*p == MIO_MT('\0')) ok = 1;
for (d = (mio_bch_t*)delim; *d != MIO_MT('\0'); d++)
{
if (*p == *d)
{
ok = 1;
mio_mbscpy (p, p + 1);
break;
}
}
if (ok == 0) return -1;
}
else
{
o = p; sp = ep = 0;
for (;;)
{
if (*p == MIO_MT('\0'))
{
if (ep)
{
ep[1] = MIO_MT('\0');
p = &ep[1];
}
cnt++;
break;
}
for (d = (mio_bch_t*)delim; *d != MIO_MT('\0'); d++)
{
if (*p == *d)
{
if (sp == MIO_NULL)
{
mio_mbscpy (o, p); p = o;
*p++ = MIO_MT('\0');
}
else
{
mio_mbscpy (&ep[1], p);
mio_mbscpy (o, sp);
o[ep - sp + 1] = MIO_MT('\0');
p = &o[ep - sp + 2];
}
cnt++;
/* last empty field after delim */
if (*p == MIO_MT('\0')) cnt++;
goto exit_point;
}
}
if (!IS_MSPACE (*p))
{
if (sp == MIO_NULL) sp = p;
ep = p;
}
p++;
}
exit_point:
;
}
}
}
return cnt;
}
int mio_mbsspl (
mio_bch_t* s, const mio_bch_t* delim,
mio_bch_t lquote, mio_bch_t rquote, mio_bch_t escape)
{
return mio_mbsspltrn (s, delim, lquote, rquote, escape, MIO_NULL);
}

412
mio/lib/mio-utl.h Normal file
View File

@ -0,0 +1,412 @@
/*
* $Id$
*
Copyright (c) 2014-2018 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MIO_UTL_H_
#define _MIO_UTL_H_
#include "mio-cmn.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* The mio_equal_uchars() function determines equality of two strings
* of the same length \a len.
*/
MIO_EXPORT int mio_equal_uchars (
const mio_uch_t* str1,
const mio_uch_t* str2,
mio_oow_t len
);
MIO_EXPORT int mio_equal_bchars (
const mio_bch_t* str1,
const mio_bch_t* str2,
mio_oow_t len
);
MIO_EXPORT int mio_comp_uchars (
const mio_uch_t* str1,
mio_oow_t len1,
const mio_uch_t* str2,
mio_oow_t len2
);
MIO_EXPORT int mio_comp_bchars (
const mio_bch_t* str1,
mio_oow_t len1,
const mio_bch_t* str2,
mio_oow_t len2
);
MIO_EXPORT int mio_comp_ucstr (
const mio_uch_t* str1,
const mio_uch_t* str2
);
MIO_EXPORT int mio_comp_bcstr (
const mio_bch_t* str1,
const mio_bch_t* str2
);
MIO_EXPORT int mio_comp_ucstr_bcstr (
const mio_uch_t* str1,
const mio_bch_t* str2
);
MIO_EXPORT int mio_comp_uchars_ucstr (
const mio_uch_t* str1,
mio_oow_t len,
const mio_uch_t* str2
);
MIO_EXPORT int mio_comp_uchars_bcstr (
const mio_uch_t* str1,
mio_oow_t len,
const mio_bch_t* str2
);
MIO_EXPORT int mio_comp_bchars_bcstr (
const mio_bch_t* str1,
mio_oow_t len,
const mio_bch_t* str2
);
MIO_EXPORT int mio_comp_bchars_ucstr (
const mio_bch_t* str1,
mio_oow_t len,
const mio_uch_t* str2
);
MIO_EXPORT void mio_copy_uchars (
mio_uch_t* dst,
const mio_uch_t* src,
mio_oow_t len
);
MIO_EXPORT void mio_copy_bchars (
mio_bch_t* dst,
const mio_bch_t* src,
mio_oow_t len
);
MIO_EXPORT void mio_copy_bchars_to_uchars (
mio_uch_t* dst,
const mio_bch_t* src,
mio_oow_t len
);
MIO_EXPORT mio_oow_t mio_copy_ucstr (
mio_uch_t* dst,
mio_oow_t len,
const mio_uch_t* src
);
MIO_EXPORT mio_oow_t mio_copy_bcstr (
mio_bch_t* dst,
mio_oow_t len,
const mio_bch_t* src
);
MIO_EXPORT mio_uch_t* mio_find_uchar (
const mio_uch_t* ptr,
mio_oow_t len,
mio_uch_t c
);
MIO_EXPORT mio_bch_t* mio_find_bchar (
const mio_bch_t* ptr,
mio_oow_t len,
mio_bch_t c
);
MIO_EXPORT mio_uch_t* mio_rfind_uchar (
const mio_uch_t* ptr,
mio_oow_t len,
mio_uch_t c
);
MIO_EXPORT mio_bch_t* mio_rfind_bchar (
const mio_bch_t* ptr,
mio_oow_t len,
mio_bch_t c
);
MIO_EXPORT mio_uch_t* mio_find_uchar_in_ucstr (
const mio_uch_t* ptr,
mio_uch_t c
);
MIO_EXPORT mio_bch_t* mio_find_bchar_in_bcstr (
const mio_bch_t* ptr,
mio_bch_t c
);
MIO_EXPORT mio_oow_t mio_count_ucstr (
const mio_uch_t* str
);
MIO_EXPORT mio_oow_t mio_count_bcstr (
const mio_bch_t* str
);
#if defined(MIO_OOCH_IS_UCH)
# define mio_equal_oochars(str1,str2,len) mio_equal_uchars(str1,str2,len)
# define mio_comp_oochars(str1,len1,str2,len2) mio_comp_uchars(str1,len1,str2,len2)
# define mio_comp_oocstr_bcstr(str1,str2) mio_comp_ucstr_bcstr(str1,str2)
# define mio_comp_oochars_bcstr(str1,len1,str2) mio_comp_uchars_bcstr(str1,len1,str2)
# define mio_comp_oochars_ucstr(str1,len1,str2) mio_comp_uchars_ucstr(str1,len1,str2)
# define mio_comp_oochars_oocstr(str1,len1,str2) mio_comp_uchars_ucstr(str1,len1,str2)
# define mio_comp_oocstr(str1,str2) mio_comp_ucstr(str1,str2)
# define mio_copy_oochars(dst,src,len) mio_copy_uchars(dst,src,len)
# define mio_copy_bchars_to_oochars(dst,src,len) mio_copy_bchars_to_uchars(dst,src,len)
# define mio_copy_oocstr(dst,len,src) mio_copy_ucstr(dst,len,src)
# define mio_find_oochar(ptr,len,c) mio_find_uchar(ptr,len,c)
# define mio_rfind_oochar(ptr,len,c) mio_rfind_uchar(ptr,len,c)
# define mio_find_oochar_in_oocstr(ptr,c) mio_find_uchar_in_ucstr(ptr,c)
# define mio_count_oocstr(str) mio_count_ucstr(str)
#else
# define mio_equal_oochars(str1,str2,len) mio_equal_bchars(str1,str2,len)
# define mio_comp_oochars(str1,len1,str2,len2) mio_comp_bchars(str1,len1,str2,len2)
# define mio_comp_oocstr_bcstr(str1,str2) mio_comp_bcstr(str1,str2)
# define mio_comp_oochars_bcstr(str1,len1,str2) mio_comp_bchars_bcstr(str1,len1,str2)
# define mio_comp_oochars_ucstr(str1,len1,str2) mio_comp_bchars_ucstr(str1,len1,str2)
# define mio_comp_oochars_oocstr(str1,len1,str2) mio_comp_bchars_bcstr(str1,len1,str2)
# define mio_comp_oocstr(str1,str2) mio_comp_bcstr(str1,str2)
# define mio_copy_oochars(dst,src,len) mio_copy_bchars(dst,src,len)
# define mio_copy_bchars_to_oochars(dst,src,len) mio_copy_bchars(dst,src,len)
# define mio_copy_oocstr(dst,len,src) mio_copy_bcstr(dst,len,src)
# define mio_find_oochar(ptr,len,c) mio_find_bchar(ptr,len,c)
# define mio_rfind_oochar(ptr,len,c) mio_rfind_bchar(ptr,len,c)
# define mio_find_oochar_in_oocstr(ptr,c) mio_find_bchar_in_bcstr(ptr,c)
# define mio_count_oocstr(str) mio_count_bcstr(str)
#endif
/* ------------------------------------------------------------------------- */
MIO_EXPORT int mio_ucwidth (
mio_uch_t uc
);
/* ------------------------------------------------------------------------- */
#if defined(MIO_OOCH_IS_UCH)
# define mio_conv_oocs_to_bcs_with_cmgr(oocs,oocslen,bcs,bcslen,cmgr) mio_conv_ucs_to_bcs_with_cmgr(oocs,oocslen,bcs,bcslen,cmgr)
# define mio_conv_oochars_to_bchars_with_cmgr(oocs,oocslen,bcs,bcslen,cmgr) mio_conv_uchars_to_bchars_with_cmgr(oocs,oocslen,bcs,bcslen,cmgr)
#else
# define mio_conv_oocs_to_ucs_with_cmgr(oocs,oocslen,ucs,ucslen,cmgr) mio_conv_bcs_to_ucs_with_cmgr(oocs,oocslen,ucs,ucslen,cmgr,0)
# define mio_conv_oochars_to_uchars_with_cmgr(oocs,oocslen,ucs,ucslen,cmgr) mio_conv_bchars_to_uchars_with_cmgr(oocs,oocslen,ucs,ucslen,cmgr,0)
#endif
MIO_EXPORT int mio_conv_bcs_to_ucs_with_cmgr (
const mio_bch_t* bcs,
mio_oow_t* bcslen,
mio_uch_t* ucs,
mio_oow_t* ucslen,
mio_cmgr_t* cmgr,
int all
);
MIO_EXPORT int mio_conv_bchars_to_uchars_with_cmgr (
const mio_bch_t* bcs,
mio_oow_t* bcslen,
mio_uch_t* ucs,
mio_oow_t* ucslen,
mio_cmgr_t* cmgr,
int all
);
MIO_EXPORT int mio_conv_ucs_to_bcs_with_cmgr (
const mio_uch_t* ucs,
mio_oow_t* ucslen,
mio_bch_t* bcs,
mio_oow_t* bcslen,
mio_cmgr_t* cmgr
);
MIO_EXPORT int mio_conv_uchars_to_bchars_with_cmgr (
const mio_uch_t* ucs,
mio_oow_t* ucslen,
mio_bch_t* bcs,
mio_oow_t* bcslen,
mio_cmgr_t* cmgr
);
/* ------------------------------------------------------------------------- */
MIO_EXPORT mio_cmgr_t* mio_get_utf8_cmgr (
void
);
/**
* The mio_conv_uchars_to_utf8() function converts a unicode character string \a ucs
* to a UTF8 string and writes it into the buffer pointed to by \a bcs, but
* not more than \a bcslen bytes including the terminating null.
*
* Upon return, \a bcslen is modified to the actual number of bytes written to
* \a bcs excluding the terminating null; \a ucslen is modified to the number of
* wide characters converted.
*
* You may pass #MIO_NULL for \a bcs to dry-run conversion or to get the
* required buffer size for conversion. -2 is never returned in this case.
*
* \return
* - 0 on full conversion,
* - -1 on no or partial conversion for an illegal character encountered,
* - -2 on no or partial conversion for a small buffer.
*
* \code
* const mio_uch_t ucs[] = { 'H', 'e', 'l', 'l', 'o' };
* mio_bch_t bcs[10];
* mio_oow_t ucslen = 5;
* mio_oow_t bcslen = MIO_COUNTOF(bcs);
* n = mio_conv_uchars_to_utf8 (ucs, &ucslen, bcs, &bcslen);
* if (n <= -1)
* {
* // conversion error
* }
* \endcode
*/
MIO_EXPORT int mio_conv_uchars_to_utf8 (
const mio_uch_t* ucs,
mio_oow_t* ucslen,
mio_bch_t* bcs,
mio_oow_t* bcslen
);
/**
* The mio_conv_utf8_to_uchars() function converts a UTF8 string to a uncide string.
*
* It never returns -2 if \a ucs is #MIO_NULL.
*
* \code
* const mio_bch_t* bcs = "test string";
* mio_uch_t ucs[100];
* mio_oow_t ucslen = MIO_COUNTOF(buf), n;
* mio_oow_t bcslen = 11;
* int n;
* n = mio_conv_utf8_to_uchars (bcs, &bcslen, ucs, &ucslen);
* if (n <= -1) { invalid/incomplenete sequence or buffer to small }
* \endcode
*
* The resulting \a ucslen can still be greater than 0 even if the return
* value is negative. The value indiates the number of characters converted
* before the error has occurred.
*
* \return 0 on success.
* -1 if \a bcs contains an illegal character.
* -2 if the wide-character string buffer is too small.
* -3 if \a bcs is not a complete sequence.
*/
MIO_EXPORT int mio_conv_utf8_to_uchars (
const mio_bch_t* bcs,
mio_oow_t* bcslen,
mio_uch_t* ucs,
mio_oow_t* ucslen
);
MIO_EXPORT int mio_conv_ucstr_to_utf8 (
const mio_uch_t* ucs,
mio_oow_t* ucslen,
mio_bch_t* bcs,
mio_oow_t* bcslen
);
MIO_EXPORT int mio_conv_utf8_to_ucstr (
const mio_bch_t* bcs,
mio_oow_t* bcslen,
mio_uch_t* ucs,
mio_oow_t* ucslen
);
MIO_EXPORT mio_oow_t mio_uc_to_utf8 (
mio_uch_t uc,
mio_bch_t* utf8,
mio_oow_t size
);
MIO_EXPORT mio_oow_t mio_utf8_to_uc (
const mio_bch_t* utf8,
mio_oow_t size,
mio_uch_t* uc
);
/* ------------------------------------------------------------------------- */
#if defined(MIO_HAVE_UINT16_T)
MIO_EXPORT mio_uint16_t mio_ntoh16 (
mio_uint16_t x
);
MIO_EXPORT mio_uint16_t mio_hton16 (
mio_uint16_t x
);
#endif
#if defined(MIO_HAVE_UINT32_T)
MIO_EXPORT mio_uint32_t mio_ntoh32 (
mio_uint32_t x
);
MIO_EXPORT mio_uint32_t mio_hton32 (
mio_uint32_t x
);
#endif
#if defined(MIO_HAVE_UINT64_T)
MIO_EXPORT mio_uint64_t mio_ntoh64 (
mio_uint64_t x
);
MIO_EXPORT mio_uint64_t mio_hton64 (
mio_uint64_t x
);
#endif
#if defined(MIO_HAVE_UINT128_T)
MIO_EXPORT mio_uint128_t mio_ntoh128 (
mio_uint128_t x
);
MIO_EXPORT mio_uint128_t mio_hton128 (
mio_uint128_t x
);
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -99,7 +99,7 @@ static int mux_open (mio_t* mio)
mux = MIO_MMGR_ALLOC (mio->mmgr, MIO_SIZEOF(*mux));
if (!mux)
{
mio->errnum = MIO_ENOMEM;
mio->errnum = MIO_ESYSMEM;
return -1;
}
@ -143,7 +143,7 @@ static int mux_control (mio_dev_t* dev, int cmd, mio_syshnd_t hnd, int dev_capa)
tmp = MIO_MMGR_REALLOC(mio->mmgr, mux->map.ptr, new_capa * MIO_SIZEOF(*tmp));
if (!tmp)
{
mio->errnum = MIO_ENOMEM;
mio->errnum = MIO_ESYSMEM;
return -1;
}
@ -187,7 +187,7 @@ static int mux_control (mio_dev_t* dev, int cmd, mio_syshnd_t hnd, int dev_capa)
tmp1 = MIO_MMGR_REALLOC(mio->mmgr, mux->pd.pfd, new_capa * MIO_SIZEOF(*tmp1));
if (!tmp1)
{
mio->errnum = MIO_ENOMEM;
mio->errnum = MIO_ESYSMEM;
return -1;
}
@ -195,7 +195,7 @@ static int mux_control (mio_dev_t* dev, int cmd, mio_syshnd_t hnd, int dev_capa)
if (!tmp2)
{
MIO_MMGR_FREE (mio->mmgr, tmp1);
mio->errnum = MIO_ENOMEM;
mio->errnum = MIO_ESYSMEM;
return -1;
}
@ -276,7 +276,7 @@ static int mux_open (mio_t* mio)
mux = MIO_MMGR_ALLOC (mio->mmgr, MIO_SIZEOF(*mux));
if (!mux)
{
mio->errnum = MIO_ENOMEM;
mio->errnum = MIO_ESYSMEM;
return -1;
}
@ -352,7 +352,7 @@ mio_t* mio_open (mio_mmgr_t* mmgr, mio_oow_t xtnsize, mio_oow_t tmrcapa, mio_err
}
else
{
if (errnum) *errnum = MIO_ENOMEM;
if (errnum) *errnum = MIO_ESYSMEM;
}
return mio;
@ -378,7 +378,7 @@ int mio_init (mio_t* mio, mio_mmgr_t* mmgr, mio_oow_t tmrcapa)
mio->tmr.jobs = MIO_MMGR_ALLOC (mio->mmgr, tmrcapa * MIO_SIZEOF(mio_tmrjob_t));
if (!mio->tmr.jobs)
{
mio->errnum = MIO_ENOMEM;
mio->errnum = MIO_ESYSMEM;
mux_close (mio);
return -1;
}
@ -938,7 +938,7 @@ mio_dev_t* mio_makedev (mio_t* mio, mio_oow_t dev_size, mio_dev_mth_t* dev_mth,
dev = MIO_MMGR_ALLOC(mio->mmgr, dev_size);
if (!dev)
{
mio->errnum = MIO_ENOMEM;
mio->errnum = MIO_ESYSMEM;
return MIO_NULL;
}
@ -1202,7 +1202,7 @@ void mio_dev_halt (mio_dev_t* dev)
int mio_dev_ioctl (mio_dev_t* dev, int cmd, void* arg)
{
if (dev->dev_mth->ioctl) return dev->dev_mth->ioctl (dev, cmd, arg);
dev->mio->errnum = MIO_ENOSUP; /* TODO: different error code ? */
dev->mio->errnum = MIO_ENOIMPL; /* TODO: different error code ? */
return -1;
}
@ -1502,7 +1502,7 @@ enqueue_data:
q = (mio_wq_t*)MIO_MMGR_ALLOC(dev->mio->mmgr, MIO_SIZEOF(*q) + (dstaddr? dstaddr->len: 0) + urem);
if (!q)
{
dev->mio->errnum = MIO_ENOMEM;
dev->mio->errnum = MIO_ESYSMEM;
return -1;
}
@ -1580,7 +1580,7 @@ enqueue_completed_write:
cwq = (mio_cwq_t*)MIO_MMGR_ALLOC(dev->mio->mmgr, MIO_SIZEOF(*cwq) + cwq_extra_aligned);
if (!cwq)
{
dev->mio->errnum = MIO_ENOMEM;
dev->mio->errnum = MIO_ESYSMEM;
return -1;
}
}
@ -1640,7 +1640,7 @@ mio_errnum_t mio_syserrtoerrnum (int no)
switch (no)
{
case ENOMEM:
return MIO_ENOMEM;
return MIO_ESYSMEM;
case EINVAL:
return MIO_EINVAL;
@ -1690,3 +1690,37 @@ mio_errnum_t mio_syserrtoerrnum (int no)
return MIO_ESYSERR;
}
}
/* -------------------------------------------------------------------------- */
void* mio_allocmem (mio_t* mio, mio_oow_t size)
{
void* ptr;
ptr = MIO_MMGR_ALLOC (mio->mmgr, size);
if (!ptr) mio_seterrnum (mio, MIO_ESYSMEM);
return ptr;
}
void* mio_callocmem (mio_t* mio, mio_oow_t size)
{
void* ptr;
ptr = MIO_MMGR_ALLOC (mio->mmgr, size);
if (!ptr) mio_seterrnum (mio, MIO_ESYSMEM);
else MIO_MEMSET (ptr, 0, size);
return ptr;
}
void* mio_reallocmem (mio_t* mio, void* ptr, mio_oow_t size)
{
ptr = MIO_MMGR_REALLOC (mio->mmgr, ptr, size);
if (!ptr) mio_seterrnum (mio, MIO_ESYSMEM);
return ptr;
}
void mio_freemem (mio_t* mio, void* ptr)
{
MIO_MMGR_FREE (mio->mmgr, ptr);
}

View File

@ -80,34 +80,60 @@ typedef struct mio_wq_t mio_wq_t;
typedef struct mio_cwq_t mio_cwq_t;
typedef mio_intptr_t mio_iolen_t; /* NOTE: this is a signed type */
typedef unsigned int mio_bitmask_t;
enum mio_errnum_t
{
MIO_ENOERR,
MIO_ENOIMPL,
MIO_ESYSERR,
MIO_EINTERN,
MIO_ENOERR, /**< no error */
MIO_EGENERIC, /**< generic error */
MIO_ENOIMPL, /**< not implemented */
MIO_ESYSERR, /**< system error */
MIO_EINTERN, /**< internal error */
MIO_ESYSMEM, /**< insufficient system memory */
MIO_EOOMEM, /**< insufficient object memory */
MIO_ETYPE, /**< invalid class/type */
MIO_EINVAL, /**< invalid parameter or data */
MIO_ENOENT, /**< data not found */
MIO_EEXIST, /**< existing/duplicate data */
MIO_EBUSY,
MIO_EACCES,
MIO_EPERM, /**< operation not permitted */
MIO_ENOTDIR,
MIO_EINTR,
MIO_EPIPE,
MIO_EAGAIN,
MIO_EBADHND,
MIO_ENOMEM,
MIO_EINVAL,
MIO_EEXIST,
MIO_ENOENT,
MIO_ENOSUP, /* not supported */
MIO_EMFILE, /* too many open files */
MIO_ENFILE,
MIO_EAGAIN,
MIO_EIOERR, /**< I/O error */
MIO_EECERR, /**< encoding conversion error */
MIO_EECMORE, /**< insufficient data for encoding conversion */
MIO_EBUFFULL, /**< buffer full */
MIO_ECONRF, /* connection refused */
MIO_ECONRS, /* connection reset */
MIO_ENOCAPA, /* no capability */
MIO_ETMOUT, /* timed out */
MIO_EPERM, /* operation not permitted */
MIO_EDEVMAKE,
MIO_EDEVERR,
MIO_EDEVHUP
};
typedef enum mio_errnum_t mio_errnum_t;
#define MIO_ERRMSG_CAPA (2048)
struct mio_errinf_t
{
mio_errnum_t num;
mio_ooch_t msg[MIO_ERRMSG_CAPA];
};
typedef struct mio_errinf_t mio_errinf_t;
enum mio_stopreq_t
{
MIO_STOPREQ_NONE = 0,
@ -364,6 +390,71 @@ enum mio_dev_event_t
typedef enum mio_dev_event_t mio_dev_event_t;
#define MIO_CWQFL_SIZE 16
#define MIO_CWQFL_ALIGN 16
typedef struct mio_mux_t mio_mux_t;
struct mio_t
{
mio_mmgr_t* mmgr;
mio_cmgr_t* cmgr;
mio_errnum_t errnum;
struct
{
union
{
mio_ooch_t ooch[MIO_ERRMSG_CAPA];
mio_bch_t bch[MIO_ERRMSG_CAPA];
mio_uch_t uch[MIO_ERRMSG_CAPA];
} tmpbuf;
mio_ooch_t buf[MIO_ERRMSG_CAPA];
mio_oow_t len;
} errmsg;
int shuterr;
mio_stopreq_t stopreq; /* stop request to abort mio_loop() */
struct
{
mio_dev_t* head;
mio_dev_t* tail;
} actdev; /* active devices */
struct
{
mio_dev_t* head;
mio_dev_t* tail;
} hltdev; /* halted devices */
struct
{
mio_dev_t* head;
mio_dev_t* tail;
} zmbdev; /* zombie devices */
mio_uint8_t bigbuf[65535]; /* TODO: make this dynamic depending on devices added. device may indicate a buffer size required??? */
unsigned int renew_watch: 1;
unsigned int in_exec: 1;
struct
{
mio_oow_t capa;
mio_oow_t size;
mio_tmrjob_t* jobs;
} tmr;
mio_cwq_t cwq;
mio_cwq_t* cwqfl[MIO_CWQFL_SIZE]; /* list of free cwq objects */
/* platform specific fields below */
mio_mux_t* mux;
};
/* ========================================================================= */
#ifdef __cplusplus
@ -391,6 +482,84 @@ MIO_EXPORT void mio_fini (
mio_t* mio
);
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE mio_mmgr_t* mio_getmmgr (mio_t* mio) { return mio->mmgr; }
static MIO_INLINE void* mio_getxtn (mio_t* mio) { return (void*)(mio + 1); }
static MIO_INLINE mio_cmgr_t* mio_getcmgr (mio_t* mio) { return mio->cmgr; }
static MIO_INLINE void mio_setcmgr (mio_t* mio, mio_cmgr_t* cmgr) { mio->cmgr = cmgr; }
static MIO_INLINE mio_errnum_t mio_geterrnum (mio_t* mio) { return mio->errnum; }
#else
# define mio_getmmgr(mio) ((mio)->mmgr)
# define mio_getxtn(mio) ((void*)((mio) + 1))
# define mio_getcmgr(mio) ((mio)->cmgr)
# define mio_setcmgr(mio,mgr) ((mio)->cmgr = (mgr))
# define mio_geterrnum(mio) ((mio)->errnum)
#endif
MIO_EXPORT void mio_seterrnum (
mio_t* mio,
mio_errnum_t errnum
);
MIO_EXPORT void mio_seterrwithsyserr (
mio_t* mio,
int syserr_type,
int syserr_code
);
MIO_EXPORT void mio_seterrbfmt (
mio_t* mio,
mio_errnum_t errnum,
const mio_bch_t* fmt,
...
);
MIO_EXPORT void mio_seterrufmt (
mio_t* mio,
mio_errnum_t errnum,
const mio_uch_t* fmt,
...
);
MIO_EXPORT void mio_seterrbfmtwithsyserr (
mio_t* mio,
int syserr_type,
int syserr_code,
const mio_bch_t* fmt,
...
);
MIO_EXPORT void mio_seterrufmtwithsyserr (
mio_t* mio,
int syserr_type,
int syserr_code,
const mio_uch_t* fmt,
...
);
MIO_EXPORT const mio_ooch_t* mio_geterrstr (
mio_t* mio
);
MIO_EXPORT const mio_ooch_t* mio_geterrmsg (
mio_t* mio
);
MIO_EXPORT void mio_geterrinf (
mio_t* mio,
mio_errinf_t* info
);
MIO_EXPORT const mio_ooch_t* mio_backuperrmsg (
mio_t* mio
);
MIO_EXPORT int mio_exec (
mio_t* mio
);
@ -549,50 +718,186 @@ MIO_EXPORT int mio_gettmrjobdeadline (
mio_ntime_t* deadline
);
/* ========================================================================= */
#if defined(MIO_HAVE_UINT16_T)
MIO_EXPORT mio_uint16_t mio_ntoh16 (
mio_uint16_t x
/* =========================================================================
* SYSTEM MEMORY MANAGEMENT FUCNTIONS VIA MMGR
* ========================================================================= */
MIO_EXPORT void* mio_allocmem (
mio_t* mio,
mio_oow_t size
);
MIO_EXPORT mio_uint16_t mio_hton16 (
mio_uint16_t x
MIO_EXPORT void* mio_callocmem (
mio_t* mio,
mio_oow_t size
);
MIO_EXPORT void* mio_reallocmem (
mio_t* mio,
void* ptr,
mio_oow_t size
);
MIO_EXPORT void mio_freemem (
mio_t* mio,
void* ptr
);
/* =========================================================================
* STRING ENCODING CONVERSION
* ========================================================================= */
#if defined(MIO_OOCH_IS_UCH)
# define mio_convootobchars(mio,oocs,oocslen,bcs,bcslen) mio_convutobchars(mio,oocs,oocslen,bcs,bcslen)
# define mio_convbtooochars(mio,bcs,bcslen,oocs,oocslen) mio_convbtouchars(mio,bcs,bcslen,oocs,oocslen)
# define mio_convootobcstr(mio,oocs,oocslen,bcs,bcslen) mio_convutobcstr(mio,oocs,oocslen,bcs,bcslen)
# define mio_convbtooocstr(mio,bcs,bcslen,oocs,oocslen) mio_convbtoucstr(mio,bcs,bcslen,oocs,oocslen)
#else
# define mio_convootouchars(mio,oocs,oocslen,bcs,bcslen) mio_convbtouchars(mio,oocs,oocslen,bcs,bcslen)
# define mio_convutooochars(mio,bcs,bcslen,oocs,oocslen) mio_convutobchars(mio,bcs,bcslen,oocs,oocslen)
# define mio_convootoucstr(mio,oocs,oocslen,bcs,bcslen) mio_convbtoucstr(mio,oocs,oocslen,bcs,bcslen)
# define mio_convutooocstr(mio,bcs,bcslen,oocs,oocslen) mio_convutobcstr(mio,bcs,bcslen,oocs,oocslen)
#endif
#if defined(MIO_HAVE_UINT32_T)
MIO_EXPORT mio_uint32_t mio_ntoh32 (
mio_uint32_t x
MIO_EXPORT int mio_convbtouchars (
mio_t* mio,
const mio_bch_t* bcs,
mio_oow_t* bcslen,
mio_uch_t* ucs,
mio_oow_t* ucslen
);
MIO_EXPORT mio_uint32_t mio_hton32 (
mio_uint32_t x
MIO_EXPORT int mio_convutobchars (
mio_t* mio,
const mio_uch_t* ucs,
mio_oow_t* ucslen,
mio_bch_t* bcs,
mio_oow_t* bcslen
);
/**
* The mio_convbtoucstr() function converts a null-terminated byte string
* to a wide string.
*/
MIO_EXPORT int mio_convbtoucstr (
mio_t* mio,
const mio_bch_t* bcs,
mio_oow_t* bcslen,
mio_uch_t* ucs,
mio_oow_t* ucslen
);
/**
* The mio_convutobcstr() function converts a null-terminated wide string
* to a byte string.
*/
MIO_EXPORT int mio_convutobcstr (
mio_t* mio,
const mio_uch_t* ucs,
mio_oow_t* ucslen,
mio_bch_t* bcs,
mio_oow_t* bcslen
);
#if defined(MIO_OOCH_IS_UCH)
# define mio_dupootobcharswithheadroom(mio,hrb,oocs,oocslen,bcslen) mio_duputobcharswithheadroom(mio,hrb,oocs,oocslen,bcslen)
# define mio_dupbtooocharswithheadroom(mio,hrb,bcs,bcslen,oocslen) mio_dupbtoucharswithheadroom(mio,hrb,bcs,bcslen,oocslen)
# define mio_dupootobchars(mio,oocs,oocslen,bcslen) mio_duputobchars(mio,oocs,oocslen,bcslen)
# define mio_dupbtooochars(mio,bcs,bcslen,oocslen) mio_dupbtouchars(mio,bcs,bcslen,oocslen)
# define mio_dupootobcstrwithheadroom(mio,hrb,oocs,bcslen) mio_duputobcstrwithheadroom(mio,hrb,oocs,bcslen)
# define mio_dupbtooocstrwithheadroom(mio,hrb,bcs,oocslen) mio_dupbtoucstrwithheadroom(mio,hrb,bcs,oocslen)
# define mio_dupootobcstr(mio,oocs,bcslen) mio_duputobcstr(mio,oocs,bcslen)
# define mio_dupbtooocstr(mio,bcs,oocslen) mio_dupbtoucstr(mio,bcs,oocslen)
#else
# define mio_dupootoucharswithheadroom(mio,hrb,oocs,oocslen,ucslen) mio_dupbtoucharswithheadroom(mio,hrb,oocs,oocslen,ucslen)
# define mio_duputooocharswithheadroom(mio,hrb,ucs,ucslen,oocslen) mio_duputobcharswithheadroom(mio,hrb,ucs,ucslen,oocslen)
# define mio_dupootouchars(mio,oocs,oocslen,ucslen) mio_dupbtouchars(mio,oocs,oocslen,ucslen)
# define mio_duputooochars(mio,ucs,ucslen,oocslen) mio_duputobchars(mio,ucs,ucslen,oocslen)
# define mio_dupootoucstrwithheadroom(mio,hrb,oocs,ucslen) mio_dupbtoucstrwithheadroom(mio,hrb,oocs,ucslen)
# define mio_duputooocstrwithheadroom(mio,hrb,ucs,oocslen) mio_duputobcstrwithheadroom(mio,hrb,ucs,oocslen)
# define mio_dupootoucstr(mio,oocs,ucslen) mio_dupbtoucstr(mio,oocs,ucslen)
# define mio_duputooocstr(mio,ucs,oocslen) mio_duputobcstr(mio,ucs,oocslen)
#endif
#if defined(MIO_HAVE_UINT64_T)
MIO_EXPORT mio_uint64_t mio_ntoh64 (
mio_uint64_t x
MIO_EXPORT mio_uch_t* mio_dupbtoucharswithheadroom (
mio_t* mio,
mio_oow_t headroom_bytes,
const mio_bch_t* bcs,
mio_oow_t bcslen,
mio_oow_t* ucslen
);
MIO_EXPORT mio_uint64_t mio_hton64 (
mio_uint64_t x
MIO_EXPORT mio_bch_t* mio_duputobcharswithheadroom (
mio_t* mio,
mio_oow_t headroom_bytes,
const mio_uch_t* ucs,
mio_oow_t ucslen,
mio_oow_t* bcslen
);
MIO_EXPORT mio_uch_t* mio_dupbtouchars (
mio_t* mio,
const mio_bch_t* bcs,
mio_oow_t bcslen,
mio_oow_t* ucslen
);
MIO_EXPORT mio_bch_t* mio_duputobchars (
mio_t* mio,
const mio_uch_t* ucs,
mio_oow_t ucslen,
mio_oow_t* bcslen
);
MIO_EXPORT mio_uch_t* mio_dupbtoucstrwithheadroom (
mio_t* mio,
mio_oow_t headroom_bytes,
const mio_bch_t* bcs,
mio_oow_t* ucslen
);
MIO_EXPORT mio_bch_t* mio_duputobcstrwithheadroom (
mio_t* mio,
mio_oow_t headroom_bytes,
const mio_uch_t* ucs,
mio_oow_t* bcslen
);
MIO_EXPORT mio_uch_t* mio_dupbtoucstr (
mio_t* mio,
const mio_bch_t* bcs,
mio_oow_t* ucslen /* optional: length of returned string */
);
MIO_EXPORT mio_bch_t* mio_duputobcstr (
mio_t* mio,
const mio_uch_t* ucs,
mio_oow_t* bcslen /* optional: length of returned string */
);
#if defined(MIO_OOCH_IS_UCH)
# define mio_dupoochars(mio,oocs,oocslen) mio_dupuchars(mio,oocs,oocslen)
#else
# define mio_dupoochars(mio,oocs,oocslen) mio_dupbchars(mio,oocs,oocslen)
#endif
#if defined(MIO_HAVE_UINT128_T)
MIO_EXPORT mio_uint128_t mio_ntoh128 (
mio_uint128_t x
MIO_EXPORT mio_uch_t* mio_dupuchars (
mio_t* mio,
const mio_uch_t* ucs,
mio_oow_t ucslen
);
MIO_EXPORT mio_uint128_t mio_hton128 (
mio_uint128_t x
MIO_EXPORT mio_bch_t* mio_dupbchars (
mio_t* mio,
const mio_bch_t* bcs,
mio_oow_t bcslen
);
#endif
/* ========================================================================= */
#ifdef __cplusplus

View File

@ -1,3 +1,53 @@
/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "mio-prv.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#if defined(HAVE_NETINET_IN_H)
# include <netinet/in.h>
#endif
#if defined(HAVE_SYS_UN_H)
# include <sys/un.h>
#endif
#if defined(HAVE_NETPACKET_PACKET_H)
# include <netpacket/packet.h>
#endif
#if defined(HAVE_NET_IF_DL_H)
# include <net/if_dl.h>
#endif
#include <arpa/inet.h>
union sockaddr_t
{
struct sockaddr sa;
@ -16,385 +66,31 @@ union sockaddr_t
};
typedef union sockaddr_t sockaddr_t;
static int str_to_ipv4 (const mio_ooch_t* str, mio_oow_t len, struct in_addr* inaddr)
{
const mio_ooch_t* end;
int dots = 0, digits = 0;
mio_uint32_t acc = 0, addr = 0;
mio_ooch_t c;
end = str + len;
do
{
if (str >= end)
{
if (dots < 3 || digits == 0) return -1;
addr = (addr << 8) | acc;
break;
}
c = *str++;
if (c >= '0' && c <= '9')
{
if (digits > 0 && acc == 0) return -1;
acc = acc * 10 + (c - '0');
if (acc > 255) return -1;
digits++;
}
else if (c == '.')
{
if (dots >= 3 || digits == 0) return -1;
addr = (addr << 8) | acc;
dots++; acc = 0; digits = 0;
}
else return -1;
}
while (1);
inaddr->s_addr = mio_hton32(addr);
return 0;
}
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
static int str_to_ipv6 (const mio_ooch_t* src, mio_oow_t len, struct in6_addr* inaddr)
{
mio_uint8_t* tp, * endp, * colonp;
const mio_ooch_t* curtok;
mio_ooch_t ch;
int saw_xdigit;
unsigned int val;
const mio_ooch_t* src_end;
src_end = src + len;
MIO_MEMSET (inaddr, 0, MIO_SIZEOF(*inaddr));
tp = &inaddr->s6_addr[0];
endp = &inaddr->s6_addr[MIO_COUNTOF(inaddr->s6_addr)];
colonp = MIO_NULL;
/* Leading :: requires some special handling. */
if (src < src_end && *src == ':')
{
src++;
if (src >= src_end || *src != ':') return -1;
}
curtok = src;
saw_xdigit = 0;
val = 0;
while (src < src_end)
{
int v1;
ch = *src++;
if (ch >= '0' && ch <= '9')
v1 = ch - '0';
else if (ch >= 'A' && ch <= 'F')
v1 = ch - 'A' + 10;
else if (ch >= 'a' && ch <= 'f')
v1 = ch - 'a' + 10;
else v1 = -1;
if (v1 >= 0)
{
val <<= 4;
val |= v1;
if (val > 0xffff) return -1;
saw_xdigit = 1;
continue;
}
if (ch == ':')
{
curtok = src;
if (!saw_xdigit)
{
if (colonp) return -1;
colonp = tp;
continue;
}
else if (src >= src_end)
{
/* a colon can't be the last character */
return -1;
}
*tp++ = (mio_uint8_t)(val >> 8) & 0xff;
*tp++ = (mio_uint8_t)val & 0xff;
saw_xdigit = 0;
val = 0;
continue;
}
if (ch == '.' && ((tp + MIO_SIZEOF(struct in_addr)) <= endp) &&
str_to_ipv4(curtok, src_end - curtok, (struct in_addr*)tp) == 0)
{
tp += MIO_SIZEOF(struct in_addr*);
saw_xdigit = 0;
break;
}
return -1;
}
if (saw_xdigit)
{
if (tp + MIO_SIZEOF(mio_uint16_t) > endp) return -1;
*tp++ = (mio_uint8_t)(val >> 8) & 0xff;
*tp++ = (mio_uint8_t)val & 0xff;
}
if (colonp != MIO_NULL)
{
/*
* Since some memmove()'s erroneously fail to handle
* overlapping regions, we'll do the shift by hand.
*/
mio_oow_t n = tp - colonp;
mio_oow_t i;
for (i = 1; i <= n; i++)
{
endp[-i] = colonp[n - i];
colonp[n - i] = 0;
}
tp = endp;
}
if (tp != endp) return -1;
return 0;
}
#endif
#undef char_t
#undef cstr_t
#undef str_to_sockaddr
#undef str_to_ipv4
#undef str_to_ipv6
#define CHAR_T_IS_BCH
#undef CHAR_T_IS_UCH
#define char_t mio_bch_t
#define cstr_t mio_bcs_t
#define str_to_sockaddr bcstr_to_sockaddr
#define str_to_ipv4 bcstr_to_ipv4
#define str_to_ipv6 bcstr_to_ipv6
#include "sck-addr.h"
static int str_to_sockaddr (mio_t* mio, const mio_ooch_t* str, mio_oow_t len, sockaddr_t* nwad)
{
const mio_ooch_t* p;
const mio_ooch_t* end;
mio_oocs_t tmp;
p = str;
end = str + len;
if (p >= end)
{
mio_seterrbfmt (mio, MIO_EINVAL, "blank address");
return -1;
}
MIO_MEMSET (nwad, 0, MIO_SIZEOF(*nwad));
#if defined(AF_UNIX)
if (*p == '/' && len >= 2)
{
#if defined(MIO_OOCH_IS_BCH)
mio_copybcstr (nwad->un.sun_path, MIO_COUNTOF(nwad->un.sun_path), str);
#else
mio_oow_t dstlen;
dstlen = MIO_COUNTOF(nwad->un.sun_path) - 1;
if (mio_convutobchars (mio, p, &len, nwad->un.sun_path, &dstlen) <= -1)
{
mio_seterrbfmt (mio, MIO_EINVAL, "unable to convert encoding");
return -1;
}
nwad->un.sun_path[dstlen] = '\0';
#endif
nwad->un.sun_family = AF_UNIX;
return 0;
}
#endif
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
if (*p == '[')
{
/* IPv6 address */
tmp.ptr = (mio_ooch_t*)++p; /* skip [ and remember the position */
while (p < end && *p != '%' && *p != ']') p++;
if (p >= end) goto no_rbrack;
tmp.len = p - tmp.ptr;
if (*p == '%')
{
/* handle scope id */
mio_uint32_t x;
p++; /* skip % */
if (p >= end)
{
/* premature end */
mio_seterrbfmt (mio, MIO_EINVAL, "scope id blank");
return -1;
}
if (*p >= '0' && *p <= '9')
{
/* numeric scope id */
nwad->in6.sin6_scope_id = 0;
do
{
x = nwad->in6.sin6_scope_id * 10 + (*p - '0');
if (x < nwad->in6.sin6_scope_id)
{
mio_seterrbfmt (mio, MIO_EINVAL, "scope id too large");
return -1; /* overflow */
}
nwad->in6.sin6_scope_id = x;
p++;
}
while (p < end && *p >= '0' && *p <= '9');
}
else
{
#if 0
TODO:
/* interface name as a scope id? */
const mio_ooch_t* stmp = p;
unsigned int index;
do p++; while (p < end && *p != ']');
if (mio_nwifwcsntoindex (stmp, p - stmp, &index) <= -1) return -1;
tmpad.u.in6.scope = index;
#endif
}
if (p >= end || *p != ']') goto no_rbrack;
}
p++; /* skip ] */
if (str_to_ipv6(tmp.ptr, tmp.len, &nwad->in6.sin6_addr) <= -1) goto unrecog;
nwad->in6.sin6_family = AF_INET6;
}
else
{
#endif
/* IPv4 address */
tmp.ptr = (mio_ooch_t*)p;
while (p < end && *p != ':') p++;
tmp.len = p - tmp.ptr;
if (str_to_ipv4(tmp.ptr, tmp.len, &nwad->in4.sin_addr) <= -1)
{
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
/* check if it is an IPv6 address not enclosed in [].
* the port number can't be specified in this format. */
if (p >= end || *p != ':')
{
/* without :, it can't be an ipv6 address */
goto unrecog;
}
while (p < end && *p != '%') p++;
tmp.len = p - tmp.ptr;
if (str_to_ipv6(tmp.ptr, tmp.len, &nwad->in6.sin6_addr) <= -1) goto unrecog;
if (p < end && *p == '%')
{
/* handle scope id */
mio_uint32_t x;
p++; /* skip % */
if (p >= end)
{
/* premature end */
mio_seterrbfmt (mio, MIO_EINVAL, "scope id blank");
return -1;
}
if (*p >= '0' && *p <= '9')
{
/* numeric scope id */
nwad->in6.sin6_scope_id = 0;
do
{
x = nwad->in6.sin6_scope_id * 10 + (*p - '0');
if (x < nwad->in6.sin6_scope_id)
{
mio_seterrbfmt (mio, MIO_EINVAL, "scope id too large");
return -1; /* overflow */
}
nwad->in6.sin6_scope_id = x;
p++;
}
while (p < end && *p >= '0' && *p <= '9');
}
else
{
#if 0
TODO
/* interface name as a scope id? */
const mio_ooch_t* stmp = p;
unsigned int index;
do p++; while (p < end);
if (mio_nwifwcsntoindex (stmp, p - stmp, &index) <= -1) return -1;
nwad->in6.sin6_scope_id = index;
#endif
}
}
if (p < end) goto unrecog; /* some gargage after the end? */
nwad->in6.sin6_family = AF_INET6;
return 0;
#else
goto unrecog;
#endif
}
nwad->in4.sin_family = AF_INET;
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
}
#endif
if (p < end && *p == ':')
{
/* port number */
mio_uint32_t port = 0;
p++; /* skip : */
tmp.ptr = (mio_ooch_t*)p;
while (p < end && *p >= '0' && *p <= '9')
{
port = port * 10 + (*p - '0');
p++;
}
tmp.len = p - tmp.ptr;
if (tmp.len <= 0 || tmp.len >= 6 ||
port > MIO_TYPE_MAX(mio_uint16_t))
{
mio_seterrbfmt (mio, MIO_EINVAL, "port number blank or too large");
return -1;
}
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
if (nwad->in4.sin_family == AF_INET)
nwad->in4.sin_port = mio_hton16(port);
else
nwad->in6.sin6_port = mio_hton16(port);
#else
nwad->in4.sin_port = mio_hton16(port);
#endif
}
return 0;
unrecog:
mio_seterrbfmt (mio, MIO_EINVAL, "unrecognized address");
return -1;
no_rbrack:
mio_seterrbfmt (mio, MIO_EINVAL, "missing right bracket");
return -1;
}
#undef char_t
#undef cstr_t
#undef str_to_sockaddr
#undef str_to_ipv4
#undef str_to_ipv6
#undef CHAR_T_IS_BCH
#define CHAR_T_IS_UCH
#define char_t mio_uch_t
#define cstr_t mio_ucs_t
#define str_to_sockaddr ucstr_to_sockaddr
#define str_to_ipv4 ucstr_to_ipv4
#define str_to_ipv6 ucstr_to_ipv6
#include "sck-addr.h"

383
mio/lib/sck-addr.h Normal file
View File

@ -0,0 +1,383 @@
/* this file is included by sck-addr.c */
static int str_to_ipv4 (const char_t* str, mio_oow_t len, struct in_addr* inaddr)
{
const char_t* end;
int dots = 0, digits = 0;
mio_uint32_t acc = 0, addr = 0;
char_t c;
end = str + len;
do
{
if (str >= end)
{
if (dots < 3 || digits == 0) return -1;
addr = (addr << 8) | acc;
break;
}
c = *str++;
if (c >= '0' && c <= '9')
{
if (digits > 0 && acc == 0) return -1;
acc = acc * 10 + (c - '0');
if (acc > 255) return -1;
digits++;
}
else if (c == '.')
{
if (dots >= 3 || digits == 0) return -1;
addr = (addr << 8) | acc;
dots++; acc = 0; digits = 0;
}
else return -1;
}
while (1);
inaddr->s_addr = mio_hton32(addr);
return 0;
}
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
static int str_to_ipv6 (const char_t* src, mio_oow_t len, struct in6_addr* inaddr)
{
mio_uint8_t* tp, * endp, * colonp;
const char_t* curtok;
char_t ch;
int saw_xdigit;
unsigned int val;
const char_t* src_end;
src_end = src + len;
MIO_MEMSET (inaddr, 0, MIO_SIZEOF(*inaddr));
tp = &inaddr->s6_addr[0];
endp = &inaddr->s6_addr[MIO_COUNTOF(inaddr->s6_addr)];
colonp = MIO_NULL;
/* Leading :: requires some special handling. */
if (src < src_end && *src == ':')
{
src++;
if (src >= src_end || *src != ':') return -1;
}
curtok = src;
saw_xdigit = 0;
val = 0;
while (src < src_end)
{
int v1;
ch = *src++;
if (ch >= '0' && ch <= '9')
v1 = ch - '0';
else if (ch >= 'A' && ch <= 'F')
v1 = ch - 'A' + 10;
else if (ch >= 'a' && ch <= 'f')
v1 = ch - 'a' + 10;
else v1 = -1;
if (v1 >= 0)
{
val <<= 4;
val |= v1;
if (val > 0xffff) return -1;
saw_xdigit = 1;
continue;
}
if (ch == ':')
{
curtok = src;
if (!saw_xdigit)
{
if (colonp) return -1;
colonp = tp;
continue;
}
else if (src >= src_end)
{
/* a colon can't be the last character */
return -1;
}
*tp++ = (mio_uint8_t)(val >> 8) & 0xff;
*tp++ = (mio_uint8_t)val & 0xff;
saw_xdigit = 0;
val = 0;
continue;
}
if (ch == '.' && ((tp + MIO_SIZEOF(struct in_addr)) <= endp) &&
str_to_ipv4(curtok, src_end - curtok, (struct in_addr*)tp) == 0)
{
tp += MIO_SIZEOF(struct in_addr*);
saw_xdigit = 0;
break;
}
return -1;
}
if (saw_xdigit)
{
if (tp + MIO_SIZEOF(mio_uint16_t) > endp) return -1;
*tp++ = (mio_uint8_t)(val >> 8) & 0xff;
*tp++ = (mio_uint8_t)val & 0xff;
}
if (colonp != MIO_NULL)
{
/*
* Since some memmove()'s erroneously fail to handle
* overlapping regions, we'll do the shift by hand.
*/
mio_oow_t n = tp - colonp;
mio_oow_t i;
for (i = 1; i <= n; i++)
{
endp[-i] = colonp[n - i];
colonp[n - i] = 0;
}
tp = endp;
}
if (tp != endp) return -1;
return 0;
}
#endif
static int str_to_sockaddr (mio_t* mio, const char_t* str, mio_oow_t len, sockaddr_t* nwad)
{
const char_t* p;
const char_t* end;
cstr_t tmp;
p = str;
end = str + len;
if (p >= end)
{
mio_seterrbfmt (mio, MIO_EINVAL, "blank address");
return -1;
}
MIO_MEMSET (nwad, 0, MIO_SIZEOF(*nwad));
#if defined(AF_UNIX)
if (*p == '/' && len >= 2)
{
#if defined(CHAR_T_IS_BCH)
mio_copy_bcstr (nwad->un.sun_path, MIO_COUNTOF(nwad->un.sun_path), str);
#else
mio_oow_t dstlen;
dstlen = MIO_COUNTOF(nwad->un.sun_path) - 1;
if (mio_convutobchars(mio, p, &len, nwad->un.sun_path, &dstlen) <= -1)
{
mio_seterrbfmt (mio, MIO_EINVAL, "unable to convert encoding");
return -1;
}
nwad->un.sun_path[dstlen] = '\0';
#endif
nwad->un.sun_family = AF_UNIX;
return 0;
}
#endif
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
if (*p == '[')
{
/* IPv6 address */
tmp.ptr = (char_t*)++p; /* skip [ and remember the position */
while (p < end && *p != '%' && *p != ']') p++;
if (p >= end) goto no_rbrack;
tmp.len = p - tmp.ptr;
if (*p == '%')
{
/* handle scope id */
mio_uint32_t x;
p++; /* skip % */
if (p >= end)
{
/* premature end */
mio_seterrbfmt (mio, MIO_EINVAL, "scope id blank");
return -1;
}
if (*p >= '0' && *p <= '9')
{
/* numeric scope id */
nwad->in6.sin6_scope_id = 0;
do
{
x = nwad->in6.sin6_scope_id * 10 + (*p - '0');
if (x < nwad->in6.sin6_scope_id)
{
mio_seterrbfmt (mio, MIO_EINVAL, "scope id too large");
return -1; /* overflow */
}
nwad->in6.sin6_scope_id = x;
p++;
}
while (p < end && *p >= '0' && *p <= '9');
}
else
{
#if 0
TODO:
/* interface name as a scope id? */
const char_t* stmp = p;
unsigned int index;
do p++; while (p < end && *p != ']');
if (mio_nwifwcsntoindex (stmp, p - stmp, &index) <= -1) return -1;
tmpad.u.in6.scope = index;
#endif
}
if (p >= end || *p != ']') goto no_rbrack;
}
p++; /* skip ] */
if (str_to_ipv6(tmp.ptr, tmp.len, &nwad->in6.sin6_addr) <= -1) goto unrecog;
nwad->in6.sin6_family = AF_INET6;
}
else
{
#endif
/* IPv4 address */
tmp.ptr = (char_t*)p;
while (p < end && *p != ':') p++;
tmp.len = p - tmp.ptr;
if (str_to_ipv4(tmp.ptr, tmp.len, &nwad->in4.sin_addr) <= -1)
{
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
/* check if it is an IPv6 address not enclosed in [].
* the port number can't be specified in this format. */
if (p >= end || *p != ':')
{
/* without :, it can't be an ipv6 address */
goto unrecog;
}
while (p < end && *p != '%') p++;
tmp.len = p - tmp.ptr;
if (str_to_ipv6(tmp.ptr, tmp.len, &nwad->in6.sin6_addr) <= -1) goto unrecog;
if (p < end && *p == '%')
{
/* handle scope id */
mio_uint32_t x;
p++; /* skip % */
if (p >= end)
{
/* premature end */
mio_seterrbfmt (mio, MIO_EINVAL, "scope id blank");
return -1;
}
if (*p >= '0' && *p <= '9')
{
/* numeric scope id */
nwad->in6.sin6_scope_id = 0;
do
{
x = nwad->in6.sin6_scope_id * 10 + (*p - '0');
if (x < nwad->in6.sin6_scope_id)
{
mio_seterrbfmt (mio, MIO_EINVAL, "scope id too large");
return -1; /* overflow */
}
nwad->in6.sin6_scope_id = x;
p++;
}
while (p < end && *p >= '0' && *p <= '9');
}
else
{
#if 0
TODO
/* interface name as a scope id? */
const char_t* stmp = p;
unsigned int index;
do p++; while (p < end);
if (mio_nwifwcsntoindex (stmp, p - stmp, &index) <= -1) return -1;
nwad->in6.sin6_scope_id = index;
#endif
}
}
if (p < end) goto unrecog; /* some gargage after the end? */
nwad->in6.sin6_family = AF_INET6;
return 0;
#else
goto unrecog;
#endif
}
nwad->in4.sin_family = AF_INET;
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
}
#endif
if (p < end && *p == ':')
{
/* port number */
mio_uint32_t port = 0;
p++; /* skip : */
tmp.ptr = (char_t*)p;
while (p < end && *p >= '0' && *p <= '9')
{
port = port * 10 + (*p - '0');
p++;
}
tmp.len = p - tmp.ptr;
if (tmp.len <= 0 || tmp.len >= 6 ||
port > MIO_TYPE_MAX(mio_uint16_t))
{
mio_seterrbfmt (mio, MIO_EINVAL, "port number blank or too large");
return -1;
}
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
if (nwad->in4.sin_family == AF_INET)
nwad->in4.sin_port = mio_hton16(port);
else
nwad->in6.sin6_port = mio_hton16(port);
#else
nwad->in4.sin_port = mio_hton16(port);
#endif
}
return 0;
unrecog:
mio_seterrbfmt (mio, MIO_EINVAL, "unrecognized address");
return -1;
no_rbrack:
mio_seterrbfmt (mio, MIO_EINVAL, "missing right bracket");
return -1;
}

1368
mio/lib/utl.c Normal file

File diff suppressed because it is too large Load Diff