diff --git a/qse/configure.ac b/qse/configure.ac index 0db36788..8546f705 100644 --- a/qse/configure.ac +++ b/qse/configure.ac @@ -1,7 +1,7 @@ -dnl AC_PREREQ(2.59) +dnl AC_PREREQ([2.67]) -AC_INIT([qse],[0.5.5],[Chung, Hyung-Hwan (hyunghwan.chung@gmail.com)],,[http://code.abiyo.net/@qse]) +AC_INIT([qse],[0.5.5],[Chung, Hyung-Hwan (hyunghwan.chung@gmail.com)],[],[http://code.abiyo.net/@qse]) AC_CONFIG_HEADER([include/qse/config.h]) AC_CONFIG_AUX_DIR([ac]) AC_CONFIG_MACRO_DIR([m4]) @@ -36,7 +36,7 @@ dnl avoid "'/bin/rm: cannot remove `libtoolT': No such file or directory" RM="$RM -f" dnl initialize libtool -AC_PROG_LIBTOOL +LT_INIT AC_SUBST(LIBTOOL_DEPS) dnl overrides the default CFLAGS setting @@ -73,7 +73,7 @@ esac AM_CONDITIONAL(WIN32, test "${platform_win32}" = "yes" ) dnl check the math library (check if -lm is needed) -AC_CHECK_LIBM +LT_LIB_M AC_SUBST(LIBM, $LIBM) dnl check header files. @@ -166,8 +166,7 @@ AC_C_BIGENDIAN( [AC_DEFINE([QSE_ENDIAN_UNKNOWN],[],[Unknown Endian])]) dnl define extra options -AC_ARG_ENABLE([wchar], [AC_HELP_STRING([--enable-wchar], - [use wchar_t a default charater type when enabled (default. yes)])], +AC_ARG_ENABLE([wchar], [AS_HELP_STRING([--enable-wchar],[use wchar_t a default charater type when enabled (default. yes)])], enable_wchar_is=$enableval,enable_wchar_is=yes) test "${ac_cv_sizeof_wchar_t}" = "0" && enable_wchar_is=no if test "${enable_wchar_is}" = "yes" @@ -179,16 +178,14 @@ else AC_SUBST(CHAR_MODE, "QSE_CHAR_IS_MCHAR") fi -AC_ARG_ENABLE([syscall], [AC_HELP_STRING([--enable-syscall], - [use the syscall() function to call system calls (default. no)])], +AC_ARG_ENABLE([syscall], [AS_HELP_STRING([--enable-syscall],[use the syscall() function to call system calls (default. no)])], enable_syscall_is=$enableval,enable_syscall_is=no) if test "${enable_syscall_is}" = "yes" then AC_DEFINE([QSE_USE_SYSCALL],[],[use the syscall() function to invoke a system call]) fi -AC_ARG_ENABLE([debug], [AC_HELP_STRING([--enable-debug], - [build the library in the debug mode (default. no)])], +AC_ARG_ENABLE([debug], [AS_HELP_STRING([--enable-debug],[build the library in the debug mode (default. no)])], enable_debug_is=$enableval,enable_debug_is=no) if test "$enable_debug_is" = "yes" then @@ -201,15 +198,13 @@ else AC_SUBST(BUILD_MODE, "release") fi -AC_ARG_ENABLE([cxx], [AC_HELP_STRING([--enable-cxx], - [build the library for C++ if a C++ compiler is available (default. yes)])], +AC_ARG_ENABLE([cxx], [AS_HELP_STRING([--enable-cxx],[build the library for C++ if a C++ compiler is available (default. yes)])], enable_cxx_is=$enableval,enable_cxx_is=yes) [test "${HAVE_CXX}" = "yes" || enable_cxx_is="no"] AM_CONDITIONAL(ENABLE_CXX, test "${enable_cxx_is}" = "yes" ) # configure makefiles -AC_ARG_ENABLE([reentrant], [AC_HELP_STRING([--enable-reentrant], - [define _REENTRANT (default. yes)])], +AC_ARG_ENABLE([reentrant], [AS_HELP_STRING([--enable-reentrant],[define _REENTRANT (default. yes)])], enable_reentrant_is=$enableval,enable_reentrant_is=yes) if test "$enable_reentrant_is" = "yes" then diff --git a/qse/include/qse/cmn/main.h b/qse/include/qse/cmn/main.h index 3a43b835..6d56941c 100644 --- a/qse/include/qse/cmn/main.h +++ b/qse/include/qse/cmn/main.h @@ -55,6 +55,22 @@ typedef qse_mchar_t qse_achar_t; #endif +/** + * The qse_runmain_handler_t type defines the actual function to be + * executed by qse_runmain(). Unlike the standard main(), it is passed + * arguments in the #qse_char_t type. + */ +typedef int (*qse_runmain_handler_t) ( + int argc, + qse_char_t* argv[] +); + +typedef int (*qse_runmainwithenv_handler_t) ( + int argc, + qse_char_t* argv[], + qse_char_t* envp[] +); + #ifdef __cplusplus extern "C" { #endif @@ -64,12 +80,25 @@ extern "C" { * the character mode configured for the library. */ int qse_runmain ( - int argc, - qse_achar_t* argv[], - int (*mf)(int,qse_char_t*[]) + int argc, + qse_achar_t* argv[], + qse_runmain_handler_t handler ); -/* TODO - qse_runmain with env, namely, qse_runmaine */ +/** + * The qse_runmainwithenv() function helps to invoke a main function + * independent of the character mode configured for the library providing + * the enviroment list. + */ +int qse_runmainwithenv ( + int argc, + qse_achar_t* argv[], + qse_achar_t* envp[], + qse_runmainwithenv_handler_t handler +); + +/* TODO: support more weird main functions. for example, + * int main(int argc, char **argv, char **envp, char **apple) in Mac OS X */ #ifdef __cplusplus } diff --git a/qse/lib/cmn/main.c b/qse/lib/cmn/main.c index 9ab61f09..b2fff962 100644 --- a/qse/lib/cmn/main.c +++ b/qse/lib/cmn/main.c @@ -23,84 +23,138 @@ #include #include "mem.h" -#if defined(_WIN32) && !defined(__MINGW32__) - -int qse_runmain (int argc, qse_achar_t* argv[], int(*mf) (int,qse_char_t*[])) +int qse_runmain ( + int argc, qse_achar_t* argv[], qse_runmain_handler_t handler) { - return mf (argc, argv); -} + setlocale (LC_ALL, ""); /* TODO: remove dependency on setlocale */ -#elif defined(QSE_CHAR_IS_WCHAR) - -int qse_runmain (int argc, qse_achar_t* argv[], int(*mf) (int,qse_char_t*[])) -{ - int i, ret; - qse_char_t** v; - qse_mmgr_t* mmgr = QSE_MMGR_GETDFL (); - - setlocale (LC_ALL, ""); - - v = (qse_char_t**) QSE_MMGR_ALLOC ( - mmgr, argc * QSE_SIZEOF(qse_char_t*)); - if (v == QSE_NULL) return -1; - - for (i = 0; i < argc; i++) v[i] = QSE_NULL; - - for (i = 0; i < argc; i++) + if (QSE_SIZEOF(qse_achar_t) == QSE_SIZEOF(qse_char_t)) { - qse_size_t n, len, nlen; - qse_size_t mbslen; - - mbslen = qse_mbslen (argv[i]); - - n = qse_mbstowcslen (argv[i], &len); - if (n < mbslen) - { - ret = -1; goto oops; - } - - len++; /* include the terminating null */ - - v[i] = (qse_char_t*) QSE_MMGR_ALLOC ( - mmgr, len*QSE_SIZEOF(qse_char_t)); - if (v[i] == QSE_NULL) - { - ret = -1; goto oops; - } - - nlen = len; - n = qse_mbstowcs (argv[i], v[i], &nlen); - if (nlen >= len) - { - /* no null-termination */ - ret = -1; goto oops; - } - if (argv[i][n] != '\0') - { - /* partial processing */ - ret = -1; goto oops; - } + return handler (argc, (qse_char_t**)argv); } - - /* TODO: envp... */ - //ret = mf (argc, v, QSE_NULL); - ret = mf (argc, v); - -oops: - for (i = 0; i < argc; i++) + else { - if (v[i] != QSE_NULL) QSE_MMGR_FREE (mmgr, v[i]); + int i, ret; + qse_char_t** v; + qse_mmgr_t* mmgr = QSE_MMGR_GETDFL (); + + v = (qse_char_t**) QSE_MMGR_ALLOC ( + mmgr, (argc + 1) * QSE_SIZEOF(qse_char_t*)); + if (v == QSE_NULL) return -1; + + for (i = 0; i < argc + 1; i++) v[i] = QSE_NULL; + + for (i = 0; i < argc; i++) + { + qse_size_t n, len, nlen; + qse_size_t mbslen; + + mbslen = qse_mbslen (argv[i]); + + n = qse_mbstowcslen (argv[i], &len); + if (n < mbslen) { ret = -1; goto oops; } + + len++; /* include the terminating null */ + + v[i] = (qse_char_t*) QSE_MMGR_ALLOC ( + mmgr, len*QSE_SIZEOF(qse_char_t)); + if (v[i] == QSE_NULL) { ret = -1; goto oops; } + + nlen = len; + n = qse_mbstowcs (argv[i], v[i], &nlen); + if (nlen >= len) + { + /* no null-termination */ + ret = -1; goto oops; + } + if (argv[i][n] != '\0') + { + /* partial processing */ + ret = -1; goto oops; + } + } + + ret = handler (argc, v); + + oops: + for (i = 0; i < argc + 1; i++) + { + if (v[i] != QSE_NULL) QSE_MMGR_FREE (mmgr, v[i]); + } + QSE_MMGR_FREE (mmgr, v); + + return ret; } - QSE_MMGR_FREE (mmgr, v); - - return ret; } -#else - -int qse_runmain (int argc, qse_achar_t* argv[], int(*mf) (int,qse_char_t*[])) +int qse_runmainwithenv ( + int argc, qse_achar_t* argv[], + qse_achar_t* envp[], qse_runmainwithenv_handler_t handler) { - return mf (argc, argv); -} + setlocale (LC_ALL, ""); /* TODO: remove dependency on setlocale */ -#endif + if (QSE_SIZEOF(qse_achar_t) == QSE_SIZEOF(qse_char_t)) + { + return handler (argc, (qse_char_t**)argv, (qse_char_t**)envp); + } + else + { + int i, ret, envc; + qse_char_t** v; + qse_mmgr_t* mmgr = QSE_MMGR_GETDFL (); + + for (envc = 0; envp[envc]; envc++) ; /* count the number of env items */ + + v = (qse_char_t**) QSE_MMGR_ALLOC ( + mmgr, (argc + 1 + envc + 1) * QSE_SIZEOF(qse_char_t*)); + if (v == QSE_NULL) return -1; + + for (i = 0; i < argc + 1 + envc + 1; i++) v[i] = QSE_NULL; + + for (i = 0; i < argc + 1 + envc; i++) + { + qse_size_t n, len, nlen; + qse_size_t mbslen; + qse_achar_t* x; + + if (i < argc) x = argv[i]; + else if (i == argc) continue; + else x = envp[i - argc - 1]; + + mbslen = qse_mbslen (x); + + n = qse_mbstowcslen (x, &len); + if (n < mbslen) { ret = -1; goto oops; } + + len++; /* include the terminating null */ + + v[i] = (qse_char_t*) QSE_MMGR_ALLOC ( + mmgr, len*QSE_SIZEOF(qse_char_t)); + if (v[i] == QSE_NULL) { ret = -1; goto oops; } + + nlen = len; + n = qse_mbstowcs (x, v[i], &nlen); + if (nlen >= len) + { + /* no null-termination */ + ret = -1; goto oops; + } + if (x[n] != '\0') + { + /* partial processing */ + ret = -1; goto oops; + } + } + + ret = handler (argc, v, &v[argc + 1]); + + oops: + for (i = 0; i < argc + 1 + envc + 1; i++) + { + if (v[i] != QSE_NULL) QSE_MMGR_FREE (mmgr, v[i]); + } + QSE_MMGR_FREE (mmgr, v); + + return ret; + } +} diff --git a/qse/samples/cmn/Makefile.am b/qse/samples/cmn/Makefile.am index ffaacf32..fa2f34e7 100644 --- a/qse/samples/cmn/Makefile.am +++ b/qse/samples/cmn/Makefile.am @@ -6,7 +6,7 @@ AM_CPPFLAGS = \ -I$(includedir) -bin_PROGRAMS = xma fma chr str sll dll lda oht htb rbt fio pio sio time main rex01 +bin_PROGRAMS = xma fma chr str sll dll lda oht htb rbt fio pio sio time main main2 rex01 LDFLAGS = -L../../lib/cmn LDADD = -lqsecmn @@ -26,6 +26,7 @@ pio_SOURCES = pio.c sio_SOURCES = sio.c time_SOURCES = time.c main_SOURCES = main.c +main2_SOURCES = main2.c rex01_SOURCES = rex01.c if ENABLE_CXX diff --git a/qse/samples/cmn/Makefile.in b/qse/samples/cmn/Makefile.in index b479ad87..c41df617 100644 --- a/qse/samples/cmn/Makefile.in +++ b/qse/samples/cmn/Makefile.in @@ -37,7 +37,8 @@ host_triplet = @host@ bin_PROGRAMS = xma$(EXEEXT) fma$(EXEEXT) chr$(EXEEXT) str$(EXEEXT) \ sll$(EXEEXT) dll$(EXEEXT) lda$(EXEEXT) oht$(EXEEXT) \ htb$(EXEEXT) rbt$(EXEEXT) fio$(EXEEXT) pio$(EXEEXT) \ - sio$(EXEEXT) time$(EXEEXT) main$(EXEEXT) rex01$(EXEEXT) + sio$(EXEEXT) time$(EXEEXT) main$(EXEEXT) main2$(EXEEXT) \ + rex01$(EXEEXT) subdir = samples/cmn DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -81,6 +82,10 @@ am_main_OBJECTS = main.$(OBJEXT) main_OBJECTS = $(am_main_OBJECTS) main_LDADD = $(LDADD) main_DEPENDENCIES = +am_main2_OBJECTS = main2.$(OBJEXT) +main2_OBJECTS = $(am_main2_OBJECTS) +main2_LDADD = $(LDADD) +main2_DEPENDENCIES = am_oht_OBJECTS = oht.$(OBJEXT) oht_OBJECTS = $(am_oht_OBJECTS) oht_LDADD = $(LDADD) @@ -131,14 +136,15 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(chr_SOURCES) $(dll_SOURCES) $(fio_SOURCES) $(fma_SOURCES) \ - $(htb_SOURCES) $(lda_SOURCES) $(main_SOURCES) $(oht_SOURCES) \ - $(pio_SOURCES) $(rbt_SOURCES) $(rex01_SOURCES) $(sio_SOURCES) \ - $(sll_SOURCES) $(str_SOURCES) $(time_SOURCES) $(xma_SOURCES) -DIST_SOURCES = $(chr_SOURCES) $(dll_SOURCES) $(fio_SOURCES) \ - $(fma_SOURCES) $(htb_SOURCES) $(lda_SOURCES) $(main_SOURCES) \ + $(htb_SOURCES) $(lda_SOURCES) $(main_SOURCES) $(main2_SOURCES) \ $(oht_SOURCES) $(pio_SOURCES) $(rbt_SOURCES) $(rex01_SOURCES) \ $(sio_SOURCES) $(sll_SOURCES) $(str_SOURCES) $(time_SOURCES) \ $(xma_SOURCES) +DIST_SOURCES = $(chr_SOURCES) $(dll_SOURCES) $(fio_SOURCES) \ + $(fma_SOURCES) $(htb_SOURCES) $(lda_SOURCES) $(main_SOURCES) \ + $(main2_SOURCES) $(oht_SOURCES) $(pio_SOURCES) $(rbt_SOURCES) \ + $(rex01_SOURCES) $(sio_SOURCES) $(sll_SOURCES) $(str_SOURCES) \ + $(time_SOURCES) $(xma_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -301,6 +307,7 @@ pio_SOURCES = pio.c sio_SOURCES = sio.c time_SOURCES = time.c main_SOURCES = main.c +main2_SOURCES = main2.c rex01_SOURCES = rex01.c all: all-am @@ -400,6 +407,9 @@ lda$(EXEEXT): $(lda_OBJECTS) $(lda_DEPENDENCIES) main$(EXEEXT): $(main_OBJECTS) $(main_DEPENDENCIES) @rm -f main$(EXEEXT) $(LINK) $(main_OBJECTS) $(main_LDADD) $(LIBS) +main2$(EXEEXT): $(main2_OBJECTS) $(main2_DEPENDENCIES) + @rm -f main2$(EXEEXT) + $(LINK) $(main2_OBJECTS) $(main2_LDADD) $(LIBS) oht$(EXEEXT): $(oht_OBJECTS) $(oht_DEPENDENCIES) @rm -f oht$(EXEEXT) $(LINK) $(oht_OBJECTS) $(oht_LDADD) $(LIBS) @@ -441,6 +451,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lda.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oht.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pio.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rbt.Po@am__quote@ diff --git a/qse/samples/cmn/main2.c b/qse/samples/cmn/main2.c new file mode 100644 index 00000000..397fe02e --- /dev/null +++ b/qse/samples/cmn/main2.c @@ -0,0 +1,25 @@ +#include +#include + +static int test_main (int argc, qse_char_t* argv[], qse_char_t* envp[]) +{ + int i; + + for (i = 0; i < argc; i++) + { + qse_printf (QSE_T("%d => [%s]\n"), i, argv[i]); + } + + for (i = 0; envp[i]; i++) + { + qse_printf (QSE_T("%d => [%s]\n"), i, envp[i]); + } + + return 0; +} + +int qse_main (int argc, qse_achar_t* argv[], qse_achar_t* envp[]) +{ + return qse_runmainwithenv (argc, argv, envp, test_main); +} +