From 8e6e7f29a66b303198c588286e315e6ced2f5beb Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Tue, 26 Nov 2013 13:47:58 +0000 Subject: [PATCH] touched up gdl.h --- qse/configure | 221 +++++++++++++++++++------------------- qse/configure.ac | 60 +++++------ qse/include/qse/cmn/dll.h | 115 +------------------- qse/include/qse/cmn/gdl.h | 176 +++++++++++++++++++++++++----- qse/lib/awk/parse.c | 26 ++--- qse/lib/awk/val.c | 2 +- qse/lib/cmn/dll.c | 77 +++++++------ qse/lib/cmn/gdl.c | 21 +++- qse/samples/cmn/dll.c | 65 ++--------- 9 files changed, 370 insertions(+), 393 deletions(-) diff --git a/qse/configure b/qse/configure index 84804385..1340cd81 100755 --- a/qse/configure +++ b/qse/configure @@ -655,6 +655,7 @@ CHAR_MODE PACKAGE_VERSION_PATCH PACKAGE_VERSION_MINOR PACKAGE_VERSION_MAJOR +QUADMATH_LIBS HAVE_LIBUCI_FALSE HAVE_LIBUCI_TRUE UCI_LIBS @@ -667,7 +668,6 @@ SSL_LIBS UNICOWS_LIBS SENDFILE_LIBS SOCKET_LIBS -QUADMATH_LIBS LIBM WIN32_FALSE WIN32_TRUE @@ -17671,114 +17671,6 @@ done LIBS="$OLDLIBS" - for ac_func in quadmath_snprintf -do : - ac_fn_c_check_func "$LINENO" "quadmath_snprintf" "ac_cv_func_quadmath_snprintf" -if test "x$ac_cv_func_quadmath_snprintf" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_QUADMATH_SNPRINTF 1 -_ACEOF - -fi -done - - if test "$ac_cv_func_quadmath_snprintf" = "no" - then - OLDLIBS="$LIBS" - LIBS="$LIBM $LIBS" - for ac_func in quadmath_snprintf -do : - ac_fn_c_check_func "$LINENO" "quadmath_snprintf" "ac_cv_func_quadmath_snprintf" -if test "x$ac_cv_func_quadmath_snprintf" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_QUADMATH_SNPRINTF 1 -_ACEOF - -fi -done - - LIBS="$OLDLIBS" - - if test "$ac_cv_func_quadmath_snprintf" = "no" - then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for quadmath_snprintf in -lquadmath" >&5 -$as_echo_n "checking for quadmath_snprintf in -lquadmath... " >&6; } -if ${ac_cv_lib_quadmath_quadmath_snprintf+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lquadmath $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char quadmath_snprintf (); -int -main () -{ -return quadmath_snprintf (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_quadmath_quadmath_snprintf=yes -else - ac_cv_lib_quadmath_quadmath_snprintf=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_quadmath_quadmath_snprintf" >&5 -$as_echo "$ac_cv_lib_quadmath_quadmath_snprintf" >&6; } -if test "x$ac_cv_lib_quadmath_quadmath_snprintf" = xyes; then : - - QUADMATH_LIBS="-lquadmath" - LIBM="$LIBM -lquadmath" - $as_echo "#define HAVE_QUADMATH_SNPRINTF 1" >>confdefs.h - - -fi - - else - QUADMATH_LIBS="$LIBM" - fi - fi - - OLDLIBS="$LIBS" - LIBS="$LIBM $LIBS" - for ac_func in powq fmodq sinq cosq tanq atanq atan2q logq log10q expq sqrtq ceilq floorq roundq -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - for ac_func in strtoflt128 -do : - ac_fn_c_check_func "$LINENO" "strtoflt128" "ac_cv_func_strtoflt128" -if test "x$ac_cv_func_strtoflt128" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_STRTOFLT128 1 -_ACEOF - -fi -done - - LIBS="$OLDLIBS" - - for ac_func in connect gethostbyname do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` @@ -20114,6 +20006,117 @@ rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi +if test ${ac_cv_sizeof___float128} -gt 0 +then + for ac_func in quadmath_snprintf +do : + ac_fn_c_check_func "$LINENO" "quadmath_snprintf" "ac_cv_func_quadmath_snprintf" +if test "x$ac_cv_func_quadmath_snprintf" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_QUADMATH_SNPRINTF 1 +_ACEOF + +fi +done + + if test "$ac_cv_func_quadmath_snprintf" = "no" + then + OLDLIBS="$LIBS" + LIBS="$LIBM $LIBS" + for ac_func in quadmath_snprintf +do : + ac_fn_c_check_func "$LINENO" "quadmath_snprintf" "ac_cv_func_quadmath_snprintf" +if test "x$ac_cv_func_quadmath_snprintf" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_QUADMATH_SNPRINTF 1 +_ACEOF + +fi +done + + LIBS="$OLDLIBS" + + if test "$ac_cv_func_quadmath_snprintf" = "no" + then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for quadmath_snprintf in -lquadmath" >&5 +$as_echo_n "checking for quadmath_snprintf in -lquadmath... " >&6; } +if ${ac_cv_lib_quadmath_quadmath_snprintf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lquadmath $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char quadmath_snprintf (); +int +main () +{ +return quadmath_snprintf (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_quadmath_quadmath_snprintf=yes +else + ac_cv_lib_quadmath_quadmath_snprintf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_quadmath_quadmath_snprintf" >&5 +$as_echo "$ac_cv_lib_quadmath_quadmath_snprintf" >&6; } +if test "x$ac_cv_lib_quadmath_quadmath_snprintf" = xyes; then : + + QUADMATH_LIBS="-lquadmath" + LIBM="$LIBM -lquadmath" + $as_echo "#define HAVE_QUADMATH_SNPRINTF 1" >>confdefs.h + + +fi + + else + QUADMATH_LIBS="$LIBM" + fi + fi + + OLDLIBS="$LIBS" + LIBS="$LIBM $LIBS" + for ac_func in powq fmodq sinq cosq tanq atanq atan2q logq log10q expq sqrtq ceilq floorq roundq +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + for ac_func in strtoflt128 +do : + ac_fn_c_check_func "$LINENO" "strtoflt128" "ac_cv_func_strtoflt128" +if test "x$ac_cv_func_strtoflt128" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRTOFLT128 1 +_ACEOF + +fi +done + + LIBS="$OLDLIBS" +fi + + cat >>confdefs.h <<_ACEOF #define QSE_SIZEOF_CHAR ${ac_cv_sizeof_char} diff --git a/qse/configure.ac b/qse/configure.ac index ba160443..be6b86c7 100644 --- a/qse/configure.ac +++ b/qse/configure.ac @@ -156,36 +156,6 @@ AC_CHECK_FUNCS([pow fmod sin cos tan atan atan2 log log10 exp sqrt ceil floor ro AC_CHECK_FUNCS([powf fmodf sinf cosf tanf atanf atan2f logf log10f expf sqrtf ceilf floorf roundf]) LIBS="$OLDLIBS" -dnl if test "${platform_win32}" = "no" -dnl then - AC_CHECK_FUNCS([quadmath_snprintf]) - if test "$ac_cv_func_quadmath_snprintf" = "no" - then - OLDLIBS="$LIBS" - LIBS="$LIBM $LIBS" - AC_CHECK_FUNCS([quadmath_snprintf]) - LIBS="$OLDLIBS" - - if test "$ac_cv_func_quadmath_snprintf" = "no" - then - AC_CHECK_LIB([quadmath], [quadmath_snprintf], [ - QUADMATH_LIBS="-lquadmath" - LIBM="$LIBM -lquadmath" - AC_DEFINE(HAVE_QUADMATH_SNPRINTF, 1) - ]) - else - QUADMATH_LIBS="$LIBM" - fi - fi - - OLDLIBS="$LIBS" - LIBS="$LIBM $LIBS" - AC_CHECK_FUNCS([powq fmodq sinq cosq tanq atanq atan2q logq log10q expq sqrtq ceilq floorq roundq]) - AC_CHECK_FUNCS([strtoflt128]) - LIBS="$OLDLIBS" -dnl fi -AC_SUBST(QUADMATH_LIBS) - dnl OLDLIBS="$LIBS" dnl AC_SEARCH_LIBS([connect], [socket]) dnl LIBS="$OLDLIBS" @@ -462,6 +432,36 @@ then ) fi +if test ${ac_cv_sizeof___float128} -gt 0 +then + AC_CHECK_FUNCS([quadmath_snprintf]) + if test "$ac_cv_func_quadmath_snprintf" = "no" + then + OLDLIBS="$LIBS" + LIBS="$LIBM $LIBS" + AC_CHECK_FUNCS([quadmath_snprintf]) + LIBS="$OLDLIBS" + + if test "$ac_cv_func_quadmath_snprintf" = "no" + then + AC_CHECK_LIB([quadmath], [quadmath_snprintf], [ + QUADMATH_LIBS="-lquadmath" + LIBM="$LIBM -lquadmath" + AC_DEFINE(HAVE_QUADMATH_SNPRINTF, 1) + ]) + else + QUADMATH_LIBS="$LIBM" + fi + fi + + OLDLIBS="$LIBS" + LIBS="$LIBM $LIBS" + AC_CHECK_FUNCS([powq fmodq sinq cosq tanq atanq atan2q logq log10q expq sqrtq ceilq floorq roundq]) + AC_CHECK_FUNCS([strtoflt128]) + LIBS="$OLDLIBS" +fi +AC_SUBST(QUADMATH_LIBS) + AC_DEFINE_UNQUOTED(QSE_SIZEOF_CHAR, ${ac_cv_sizeof_char}, [sizeof(char)]) AC_DEFINE_UNQUOTED(QSE_SIZEOF_SHORT, ${ac_cv_sizeof_short}, [sizeof(short)]) AC_DEFINE_UNQUOTED(QSE_SIZEOF_INT, ${ac_cv_sizeof_int}, [sizeof(int)]) diff --git a/qse/include/qse/cmn/dll.h b/qse/include/qse/cmn/dll.h index c0cab7e7..e5fbc67e 100644 --- a/qse/include/qse/cmn/dll.h +++ b/qse/include/qse/cmn/dll.h @@ -29,115 +29,8 @@ #include #include -#define QSE_DLL_DEFINE(list_type,node_type,data_define,manage_define) \ - typedef struct list_type list_type; \ - typedef struct node_type node_type; \ - struct node_type \ - { \ - node_type* prev; \ - node_type* next; \ - data_define \ - }; \ - struct list_type \ - { \ - node_type gdl; \ - qse_size_t size; \ - manage_define \ - } - -#define QSE_DLL_TYPE(data_type) qse_dll_ ## data_type ## _t -#define QSE_DLL_NODE_TYPE(data_type) qse_dll_ ## data_type ## _node_t - -/** - * The QSE_DLL_DEFINE_SIMPLE macro defines a doubly-linked list type for data - * of the @a data_type type. - */ -#define QSE_DLL_DEFINE_SIMPLE(data_type) \ - QSE_DLL_DEFINE ( \ - QSE_DLL_TYPE(data_type), \ - QSE_DLL_NODE_TYPE(data_type), \ - data_type data;, \ - ) - -/** - * The QSE_DLL_DEFINE_MANAGED macro defines a doubly-linked list type for data - * of the @a data_type type. - */ -#define QSE_DLL_DEFINE_MANAGED(data_type,manage_type) \ - QSE_DLL_DEFINE ( \ - QSE_DLL_TYPE(data_type), \ - QSE_DLL_NODE_TYPE(data_type), \ - data_type data;, \ - manage_type data; \ - ) - -#define QSE_DLL_INIT(dll) \ - QSE_BLOCK ( \ - QSE_GDL_INIT(&(dll)->gdl); \ - (dll)->size = 0; \ - ) - -#define QSE_DLL_FINI(dll) QSE_DLL_CLEAR(dll) - -#define QSE_DLL_CHAIN(dll,p,x,n) \ - QSE_BLOCK ( \ - QSE_GDL_CHAIN ((qse_gdl_t*)p, (qse_gdl_t*)x, (qse_gdl_t*)n); \ - (dll)->size++; \ - ) - -#define QSE_DLL_UNCHAIN(dll,x) \ - QSE_BLOCK ( \ - QSE_GDL_UNCHAIN ((qse_gdl_t*)x); \ - (dll)->size--; \ - ) - -#define QSE_DLL_CLEAR(dll) \ - QSE_BLOCK ( \ - while (!QSE_DLL_ISEMPTY(dll)) QSE_DLL_DELHEAD(dll); \ - ) - -/** - * The QSE_DLL_ISEMPTY macro determines if a list @a dll is empty - */ -#define QSE_DLL_ISEMPTY(dll) QSE_GDL_ISEMPTY(&(dll)->gdl) - -/** - * The QSE_DLL_ISMEMBER macro determines if a node @a x is a member - * of a list @a dll. - */ -#define QSE_DLL_ISMEMBER(dll,x) ((x) != &(dll)->gdl) - -#define QSE_DLL_HEAD(dll) QSE_GDL_HEAD(&(dll)->gdl) -#define QSE_DLL_TAIL(dll) QSE_GDL_TAIL(&(dll)->gdl) #define QSE_DLL_SIZE(dll) ((const qse_size_t)(dll)->size) -/** - * The QSE_DLL_ADDHEAD macro add a member node @a x to the head of - * the list @a dll. - */ -#define QSE_DLL_ADDHEAD(dll,x) \ - QSE_DLL_CHAIN(dll,&(dll)->gdl,x,QSE_DLL_HEAD(dll)) - -/** - * The QSE_DLL_ADDHEAD macro add a member node @a x to the tail of - * the list @a dll. - */ -#define QSE_DLL_ADDTAIL(dll,x) \ - QSE_DLL_CHAIN(dll,QSE_DLL_TAIL(dll),x,&(dll)->gdl) - -/** - * The QSE_DLL_DELHEAD macro deletes the head node. - */ -#define QSE_DLL_DELHEAD(dll) \ - QSE_DLL_UNCHAIN(dll,QSE_DLL_HEAD(dll)) - -/** - * The QSE_DLL_DELTAIL macro deletes the tail node. - */ -#define QSE_DLL_DELTAIL(dll) \ - QSE_DLL_UNCHAIN(dll,QSE_DLL_TAIL(dll)) - - /* ----------- more general implementation below ----------------- */ enum qse_dll_walk_t { @@ -193,8 +86,9 @@ typedef qse_dll_walk_t (*qse_dll_walker_t) ( struct qse_dll_node_t { /* the first two fields in sync with qse_gdl_t */ - qse_dll_node_t* prev; - qse_dll_node_t* next; + /*qse_dll_node_t* prev; + qse_dll_node_t* next;*/ + qse_gdl_link_t link; /* data */ qse_xptl_t val; }; @@ -206,7 +100,8 @@ struct qse_dll_t { qse_mmgr_t* mmgr; - qse_dll_node_t gdl; + /*qse_dll_node_t gdl;*/ + qse_gdl_t gdl; qse_size_t size; qse_byte_t scale; diff --git a/qse/include/qse/cmn/gdl.h b/qse/include/qse/cmn/gdl.h index b45bee3b..4ded634d 100644 --- a/qse/include/qse/cmn/gdl.h +++ b/qse/include/qse/cmn/gdl.h @@ -23,68 +23,186 @@ #include #include + /** @file - * This file defins a generic double link and provides basic macros to - * manipulate a chain of links. + * This file defines a generic doubly linked list. + * + * When the list is empty, the primary node points to itself. + * +-------+ + * | gdl | + * | tail --------+ + * | head ----+ | + * +-------+ | | + * ^ ^ | | + * | +------+ | + * +-------------+ + * + * The list contains 1 item. + * +----------------------------+ + * V | + * +-------+ +-------+ | + * | gdl | | first | | + * | tail ------------> | prev ----+ + * | head ------------> | next ----+ + * +-------+ +-------+ | + * ^ | + * +---------------------------+ + * + * The list contains 2 item. + * +----------------------------+ + * V | +--------------------+ + * +-------+ +-------+ | | +--------+ | + * | gdl | | first | <---+ | second | | + * | tail ------+ | prev ----+ | prev ------+ + * | head ------|-----> | next -------------> | next ------+ + * +-------+ | +-------+ +--------+ | + * ^ | ^ | + * | +---------------------------------+ | + * +------------------------------------------------------+ + * + * gdl's tail points to the last item. + * gdl's head points to the first item. + * the last item's next points to gdl. + * the first item's prev points to gdl. + * + * + * \code + * #include + * + * struct q + * { + * int x; + * qse_gdl_link_t rr; + * }; + * + * int main () + * { + * struct q a, b, c, d, e; + * qse_gdl_link_t* x; + * qse_gdl_t rr; + * + * a.x = 1; + * b.x = 2; + * c.x = 3; + * d.x = 4; + * e.x = 5; + * + * QSE_GDL_INIT (&rr); + * + * QSE_GDL_APPEND (&rr, &c.rr); + * QSE_GDL_APPEND (&rr, &b.rr); + * QSE_GDL_PREPEND (&rr, &a.rr); + * QSE_GDL_APPEND (&rr, &d.rr); + * QSE_GDL_REPLACE (&rr, &b.rr, &e.rr); + * QSE_GDL_DELETE (&rr, QSE_GDL_TAIL(&rr)); + * + * for (x = QSE_GDL_HEAD(&rr); QSE_GDL_ISLINK(&rr,x); x = QSE_GDL_NEXT(x)) + * { + * struct q* qq = QSE_GDL_CONTAINER(x,struct q,rr); + * // do something here + * } + * + * return 0; + * } + * \endcode */ /** - * The qse_gdl_t type defines a structure to contain forward and - * backward links. + * The qse_gdl_t type defines a structure to contain the pointers to + * the head and the tail links. It maintains the same layout as the + * #qse_gdl_link_t type despite different member names. */ typedef struct qse_gdl_t qse_gdl_t; + +/** + * The qse_gdl_link_t type defines a structure to contain forward and + * backward links. It maintains the same layout as the #qse_gdl_t type + * despite different member names. + */ +typedef struct qse_gdl_link_t qse_gdl_link_t; + struct qse_gdl_t { - qse_gdl_t* prev; - qse_gdl_t* next; + qse_gdl_link_t* tail; /* this maps to prev of qse_gdl_link_t */ + qse_gdl_link_t* head; /* this maps to next of qse_gdl_link_t */ +}; + +struct qse_gdl_link_t +{ + qse_gdl_link_t* prev; /* this maps to tail of qse_gdl_t */ + qse_gdl_link_t* next; /* this maps to head of qse_gdl_t */ }; /** * The QSE_GDL_INIT macro initializes a link to be used for internal * management. */ -#define QSE_GDL_INIT(link) QSE_BLOCK ( \ - (link)->next = (link); (link)->prev = (link); \ +#define QSE_GDL_INIT(gdl) QSE_BLOCK ( \ + (gdl)->head = (qse_gdl_link_t*)(gdl); \ + (gdl)->tail = (qse_gdl_link_t*)(gdl); \ ) -/** - * The QSE_GDL_CHAIN macro chains a new member node @a x between - * two nodes @a p and @a n. - */ -#define QSE_GDL_CHAIN(p,x,n) qse_gdl_chain(p,x,n) - -/** - * The QSE_GDL_UNCHAIN macro unchains a member node @a x. - */ -#define QSE_GDL_UNCHAIN(x) qse_gdl_unchain(x) - -/** - * The QSE_GDL_ISEMPTY macro checks if the chain is empty. - */ -#define QSE_GDL_ISEMPTY(link) ((link)->next == (link)) +#define QSE_GDL_NEXT(link) ((link)->next) +#define QSE_GDL_PREV(link) ((link)->prev) +#define QSE_GDL_CONTAINER(link,type,name) \ + ((type*)(((qse_uint8_t*)link) - QSE_OFFSETOF(type,name))) /** * The QSE_GDL_HEAD macro get the first node in the chain. */ -#define QSE_GDL_HEAD(link) ((link)->next) +#define QSE_GDL_HEAD(gdl) ((gdl)->head) /** * The QSE_GDL_TAIL macro gets the last node in the chain. */ -#define QSE_GDL_TAIL(link) ((link)->prev) +#define QSE_GDL_TAIL(gdl) ((gdl)->tail) + +/** + * The QSE_GDL_CHAIN macro chains a new member node \a x between + * two nodes \a p and \a n. + */ +#define QSE_GDL_CHAIN(gdl,p,x,n) qse_gdl_chain(gdl,p,x,n) + +/** + * The QSE_GDL_UNCHAIN macro unchains a member node \a x. + */ +#define QSE_GDL_UNCHAIN(gdl,x) qse_gdl_unchain(gdl,x) + +#define QSE_GDL_APPEND(gdl,x) \ + qse_gdl_chain (gdl, QSE_GDL_TAIL(gdl), (x), (qse_gdl_link_t*)(gdl)) + +#define QSE_GDL_PREPEND(gdl,x) \ + qse_gdl_chain (gdl, (qse_gdl_link_t*)(gdl), (x), QSE_GDL_HEAD(gdl)) + +#define QSE_GDL_REPLACE(gdl,x,y) qse_gdl_replace (gdl, x, y) + +#define QSE_GDL_DELETE(gdl,x) QSE_GDL_UNCHAIN(gdl,x) + +#define QSE_GDL_ISEMPTY(gdl) ((gdl)->head == (qse_gdl_link_t*)(gdl)) +#define QSE_GDL_ISLINK(gdl,x) ((gdl) != (qse_gdl_t*)(x)) +#define QSE_GDL_ISHEAD(gdl,x) ((x)->prev == (qse_gdl_link_t*)(gdl)) +#define QSE_GDL_ISTAIL(gdl,x) ((x)->next == (qse_gdl_link_t*)(gdl)) #ifdef __cplusplus extern "C" { #endif QSE_EXPORT void qse_gdl_chain ( - qse_gdl_t* p, - qse_gdl_t* x, - qse_gdl_t* n + qse_gdl_t* gdl, + qse_gdl_link_t* prev, + qse_gdl_link_t* x, + qse_gdl_link_t* next ); QSE_EXPORT void qse_gdl_unchain ( - qse_gdl_t* x + qse_gdl_t* gdl, + qse_gdl_link_t* x +); + +QSE_EXPORT void qse_gdl_replace ( + qse_gdl_t* gdl, + qse_gdl_link_t* old_link, + qse_gdl_link_t* new_link ); #ifdef __cplusplus diff --git a/qse/lib/awk/parse.c b/qse/lib/awk/parse.c index 6ea48864..ad21e1f5 100644 --- a/qse/lib/awk/parse.c +++ b/qse/lib/awk/parse.c @@ -1097,15 +1097,15 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk) /* note that i'm assigning to rederr in the 'if' conditions below. * i'm not checking equality */ /* check if it is a builtin function */ - if ((qse_awk_findfnc (awk, &name) != QSE_NULL && (rederr = QSE_AWK_EFNCRED)) || + if ((qse_awk_findfnc (awk, (const qse_cstr_t*)&name) != QSE_NULL && (rederr = QSE_AWK_EFNCRED)) || /* check if it has already been defined as a function */ (qse_htb_search (awk->tree.funs, name.ptr, name.len) != QSE_NULL && (rederr = QSE_AWK_EFUNRED)) || /* check if it conflicts with a named variable */ (qse_htb_search (awk->parse.named, name.ptr, name.len) != QSE_NULL && (rederr = QSE_AWK_EVARRED)) || /* check if it coincides to be a global variable name */ - (((g = find_global (awk, &name)) != QSE_LDA_NIL) && (rederr = QSE_AWK_EGBLRED))) + (((g = find_global (awk, (const qse_cstr_t*)&name)) != QSE_LDA_NIL) && (rederr = QSE_AWK_EGBLRED))) { - qse_awk_seterror (awk, rederr, &name, &awk->tok.loc); + qse_awk_seterror (awk, rederr, (const qse_cstr_t*)&name, &awk->tok.loc); return QSE_NULL; } @@ -1947,7 +1947,7 @@ static qse_awk_t* collect_locals ( /* check if it conflicts with a builtin function name * function f() { local length; } */ - if (qse_awk_findfnc (awk, &lcl) != QSE_NULL) + if (qse_awk_findfnc (awk, (const qse_cstr_t*)&lcl) != QSE_NULL) { SETERR_ARG_LOC ( awk, QSE_AWK_EFNCRED, @@ -2000,7 +2000,7 @@ static qse_awk_t* collect_locals ( } /* check if it conflicts with global variable names */ - n = find_global (awk, &lcl); + n = find_global (awk, (const qse_cstr_t*)&lcl); if (n != QSE_LDA_NIL) { if (n < awk->tree.ngbls_base) @@ -4211,7 +4211,7 @@ static QSE_INLINE int isfunname (qse_awk_t* awk, const qse_xstr_t* name) static QSE_INLINE int isfnname (qse_awk_t* awk, const qse_xstr_t* name) { - if (qse_awk_findfnc (awk, name) != QSE_NULL) + if (qse_awk_findfnc (awk, (const qse_cstr_t*)name) != QSE_NULL) { /* implicit function */ return FNTYPE_FNC; @@ -4856,7 +4856,7 @@ static qse_awk_nde_t* parse_primary_ident_noseg ( qse_awk_nde_t* nde = QSE_NULL; /* check if name is an intrinsic function name */ - fnc = qse_awk_findfnc (awk, name); + fnc = qse_awk_findfnc (awk, (const qse_cstr_t*)name); if (fnc) { if (MATCH(awk,TOK_LPAREN)) @@ -5668,17 +5668,6 @@ static int get_string ( return 0; } -static int get_charstr (qse_awk_t* awk, qse_awk_tok_t* tok, qse_char_t c) -{ - if (awk->sio.last.c != QSE_T('\"')) - { - /* the starting quote has been consumed before this function - * has been called */ - ADD_TOKEN_CHAR (awk, tok, awk->sio.last.c); - } - return get_string (awk, QSE_T('\"'), QSE_T('\\'), 0, 0, tok); -} - static int get_rexstr (qse_awk_t* awk, qse_awk_tok_t* tok) { if (awk->sio.last.c == QSE_T('/')) @@ -6067,7 +6056,6 @@ retry: { /* double-quoted string */ SET_TOKEN_TYPE (awk, tok, TOK_STR); - /*if (get_charstr(awk, tok, c) <= -1) return -1;*/ if (get_string (awk, c, QSE_T('\\'), 0, 0, tok) <= -1) return -1; } else if (c == QSE_T('\'')) diff --git a/qse/lib/awk/val.c b/qse/lib/awk/val.c index 8da05af9..ee66d8c9 100644 --- a/qse/lib/awk/val.c +++ b/qse/lib/awk/val.c @@ -1564,7 +1564,7 @@ int qse_awk_rtx_valtonum ( case QSE_AWK_VAL_REF: { - return val_ref_to_num (rtx, (qse_awk_val_str_t*)v, l, r); + return val_ref_to_num (rtx, (qse_awk_val_ref_t*)v, l, r); } } diff --git a/qse/lib/cmn/dll.c b/qse/lib/cmn/dll.c index 49ba80ee..d3679e33 100644 --- a/qse/lib/cmn/dll.c +++ b/qse/lib/cmn/dll.c @@ -79,7 +79,7 @@ int qse_dll_init (qse_dll_t* dll, qse_mmgr_t* mmgr) dll->comper = default_comper; dll->copier = QSE_DLL_COPIER_SIMPLE; - QSE_DLL_INIT (dll); + QSE_GDL_INIT (&dll->gdl); return 0; } @@ -154,12 +154,14 @@ qse_size_t qse_dll_getsize (qse_dll_t* dll) qse_dll_node_t* qse_dll_gethead (qse_dll_t* dll) { - return QSE_DLL_HEAD(dll); + if (QSE_GDL_ISEMPTY(&dll->gdl)) return QSE_NULL; + return QSE_GDL_CONTAINER(QSE_GDL_HEAD(&dll->gdl), qse_dll_node_t, link); } qse_dll_node_t* qse_dll_gettail (qse_dll_t* dll) { - return QSE_DLL_TAIL(dll); + if (QSE_GDL_ISEMPTY(&dll->gdl)) return QSE_NULL; + return QSE_GDL_CONTAINER(QSE_GDL_TAIL(&dll->gdl), qse_dll_node_t, link); } static qse_dll_node_t* alloc_node (qse_dll_t* dll, void* dptr, qse_size_t dlen) @@ -212,16 +214,19 @@ static QSE_INLINE void free_node (qse_dll_t* dll, qse_dll_node_t* node) qse_dll_node_t* qse_dll_search ( qse_dll_t* dll, qse_dll_node_t* pos, const void* dptr, qse_size_t dlen) { - if (pos == QSE_NULL) pos = QSE_DLL_HEAD(dll); + if (QSE_GDL_ISEMPTY(&dll->gdl)) return QSE_NULL; - while (QSE_DLL_ISMEMBER(dll,pos)) + if (pos == QSE_NULL) + pos = QSE_GDL_CONTAINER (QSE_GDL_HEAD(&dll->gdl), qse_dll_node_t, link); + + while (QSE_GDL_ISLINK (&dll->gdl, &pos->link)) { if (dll->comper (dll, DPTR(pos), DLEN(pos), dptr, dlen) == 0) { return pos; } - pos = pos->next; + pos = QSE_GDL_CONTAINER (QSE_GDL_NEXT(&pos->link), qse_dll_node_t, link); } return QSE_NULL; @@ -230,16 +235,18 @@ qse_dll_node_t* qse_dll_search ( qse_dll_node_t* qse_dll_rsearch ( qse_dll_t* dll, qse_dll_node_t* pos, const void* dptr, qse_size_t dlen) { - if (pos == QSE_NULL) pos = QSE_DLL_TAIL(dll); + if (QSE_GDL_ISEMPTY(&dll->gdl)) return QSE_NULL; + if (pos == QSE_NULL) + pos = QSE_GDL_CONTAINER (QSE_GDL_TAIL(&dll->gdl), qse_dll_node_t, link); - while (QSE_DLL_ISMEMBER(dll,pos)) + while (QSE_GDL_ISLINK (&dll->gdl, &pos->link)) { if (dll->comper (dll, DPTR(pos), DLEN(pos), dptr, dlen) == 0) { return pos; } - pos = pos->prev; + pos = QSE_GDL_CONTAINER (QSE_GDL_PREV(&pos->link), qse_dll_node_t, link); } return QSE_NULL; @@ -254,12 +261,14 @@ qse_dll_node_t* qse_dll_insert ( if (pos == QSE_NULL) { /* insert at the end */ - QSE_DLL_ADDTAIL (dll, n); + QSE_GDL_APPEND (&dll->gdl, &n->link); + dll->size++; } else { /* insert in front of the positional node */ - QSE_DLL_CHAIN (dll, pos->prev, n, pos); + QSE_GDL_CHAIN (&dll->gdl, QSE_GDL_PREV(&pos->link), &n->link, &pos->link); + dll->size++; } } @@ -268,58 +277,58 @@ qse_dll_node_t* qse_dll_insert ( void qse_dll_delete (qse_dll_t* dll, qse_dll_node_t* pos) { - if (pos == QSE_NULL || !QSE_DLL_ISMEMBER(dll,pos)) return; - QSE_DLL_UNCHAIN (dll, pos); + if (pos == QSE_NULL || !QSE_GDL_ISLINK(&dll->gdl,&pos->link)) return; + + QSE_GDL_UNCHAIN (&dll->gdl, &pos->link); free_node (dll, pos); + dll->size--; } void qse_dll_clear (qse_dll_t* dll) { - while (!QSE_DLL_ISEMPTY(dll)) + while (!QSE_GDL_ISEMPTY(&dll->gdl)) { - qse_dll_delete (dll, QSE_DLL_HEAD(dll)); + qse_dll_delete (dll, QSE_GDL_CONTAINER (QSE_GDL_HEAD(&dll->gdl), qse_dll_node_t, link)); } } void qse_dll_walk (qse_dll_t* dll, qse_dll_walker_t walker, void* ctx) { - qse_dll_node_t* n = QSE_DLL_HEAD(dll); + qse_gdl_link_t* n = QSE_GDL_HEAD (&dll->gdl); qse_dll_walk_t w = QSE_DLL_WALK_FORWARD; - while (QSE_DLL_ISMEMBER(dll,n)) + while (QSE_GDL_ISLINK(&dll->gdl,n)) { - qse_dll_node_t* nxt = n->next; - qse_dll_node_t* prv = n->prev; + qse_gdl_link_t tmp = *n; - w = walker (dll, n, ctx); + w = walker (dll, QSE_GDL_CONTAINER (n, qse_dll_node_t, link), ctx); - if (w == QSE_DLL_WALK_FORWARD) n = nxt; - else if (w == QSE_DLL_WALK_BACKWARD) n = prv; + if (w == QSE_DLL_WALK_FORWARD) n = QSE_GDL_NEXT (&tmp); + else if (w == QSE_DLL_WALK_BACKWARD) n = QSE_GDL_PREV (&tmp); else break; } } void qse_dll_rwalk (qse_dll_t* dll, qse_dll_walker_t walker, void* ctx) { - qse_dll_node_t* n = QSE_DLL_TAIL(dll); + qse_gdl_link_t* n = QSE_GDL_TAIL (&dll->gdl); qse_dll_walk_t w = QSE_DLL_WALK_BACKWARD; - while (QSE_DLL_ISMEMBER(dll,n)) + while (QSE_GDL_ISLINK(&dll->gdl,n)) { - qse_dll_node_t* nxt = n->next; - qse_dll_node_t* prv = n->prev; + qse_gdl_link_t tmp = *n; - w = walker (dll, n, ctx); + w = walker (dll, QSE_GDL_CONTAINER (n, qse_dll_node_t, link), ctx); - if (w == QSE_DLL_WALK_FORWARD) n = nxt; - else if (w == QSE_DLL_WALK_BACKWARD) n = prv; + if (w == QSE_DLL_WALK_FORWARD) n = QSE_GDL_NEXT (&tmp); + else if (w == QSE_DLL_WALK_BACKWARD) n = QSE_GDL_PREV (&tmp); else break; } } qse_dll_node_t* qse_dll_pushhead (qse_dll_t* dll, void* data, qse_size_t size) { - return qse_dll_insert (dll, QSE_DLL_HEAD(dll), data, size); + return qse_dll_insert (dll, QSE_GDL_CONTAINER (QSE_GDL_HEAD (&dll->gdl), qse_dll_node_t, link), data, size); } qse_dll_node_t* qse_dll_pushtail (qse_dll_t* dll, void* data, qse_size_t size) @@ -329,14 +338,14 @@ qse_dll_node_t* qse_dll_pushtail (qse_dll_t* dll, void* data, qse_size_t size) void qse_dll_pophead (qse_dll_t* dll) { - QSE_ASSERT (!QSE_DLL_ISEMPTY(dll)); - QSE_DLL_DELHEAD (dll); + QSE_ASSERT (!QSE_GDL_ISEMPTY(&dll->gdl)); + qse_dll_delete (dll, QSE_GDL_CONTAINER (QSE_GDL_HEAD (&dll->gdl), qse_dll_node_t, link)); } void qse_dll_poptail (qse_dll_t* dll) { - QSE_ASSERT (!QSE_DLL_ISEMPTY(dll)); - QSE_DLL_DELTAIL (dll); + QSE_ASSERT (!QSE_GDL_ISEMPTY(&dll->gdl)); + qse_dll_delete (dll, QSE_GDL_CONTAINER (QSE_GDL_TAIL (&dll->gdl), qse_dll_node_t, link)); } diff --git a/qse/lib/cmn/gdl.c b/qse/lib/cmn/gdl.c index 43de8a6d..8d12f814 100644 --- a/qse/lib/cmn/gdl.c +++ b/qse/lib/cmn/gdl.c @@ -20,14 +20,25 @@ #include -void qse_gdl_chain (qse_gdl_t* p, qse_gdl_t* x, qse_gdl_t* n) +void qse_gdl_chain (qse_gdl_t* gdl, qse_gdl_link_t* prev, qse_gdl_link_t* x, qse_gdl_link_t* next) { - x->prev = p; x->next = n; n->prev = x; p->next = x; + x->prev = prev; + x->next = next; + next->prev = x; + prev->next = x; } -void qse_gdl_unchain (qse_gdl_t* x) +void qse_gdl_unchain (qse_gdl_t* gdl, qse_gdl_link_t* x) { - qse_gdl_t* p = x->prev; - qse_gdl_t* n = x->next; + qse_gdl_link_t* p = x->prev; + qse_gdl_link_t* n = x->next; n->prev = p; p->next = n; } + +void qse_gdl_replace (qse_gdl_t* gdl, qse_gdl_link_t* old_link, qse_gdl_link_t* new_link) +{ + new_link->next = old_link->next; + new_link->next->prev = new_link; + new_link->prev = old_link->prev; + new_link->prev->next = new_link; +} diff --git a/qse/samples/cmn/dll.c b/qse/samples/cmn/dll.c index 315a442d..84e739b2 100644 --- a/qse/samples/cmn/dll.c +++ b/qse/samples/cmn/dll.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #define R(f) \ @@ -48,7 +48,7 @@ static int test1 () { qse_dll_pushtail (s1, x[i], qse_strlen(x[i])); } - qse_printf (QSE_T("s1 holding [%d] nodes\n"), QSE_DLL_SIZE(s1)); + qse_printf (QSE_T("s1 holding [%zu] nodes\n"), QSE_DLL_SIZE(s1)); qse_dll_walk (s1, walk_dll, QSE_NULL); @@ -57,7 +57,7 @@ static int test1 () { qse_dll_delete (s1, p); } - qse_printf (QSE_T("s1 holding [%d] nodes\n"), QSE_DLL_SIZE(s1)); + qse_printf (QSE_T("s1 holding [%zu] nodes\n"), QSE_DLL_SIZE(s1)); qse_dll_walk (s1, walk_dll, QSE_NULL); qse_dll_close (s1); @@ -90,7 +90,7 @@ static int test2 () { qse_dll_pushtail (s1, x[i], qse_strlen(x[i])); } - qse_printf (QSE_T("s1 holding [%d] nodes\n"), QSE_DLL_SIZE(s1)); + qse_printf (QSE_T("s1 holding [%zu] nodes\n"), QSE_DLL_SIZE(s1)); qse_dll_rwalk (s1, rwalk_dll, QSE_NULL); @@ -99,67 +99,20 @@ static int test2 () { qse_dll_delete (s1, p); } - qse_printf (QSE_T("s1 holding [%d] nodes\n"), QSE_DLL_SIZE(s1)); + qse_printf (QSE_T("s1 holding [%zu] nodes\n"), QSE_DLL_SIZE(s1)); qse_dll_rwalk (s1, rwalk_dll, QSE_NULL); qse_dll_close (s1); return 0; } -typedef struct item_t item_t; -struct item_t -{ - int a; - int b; -}; -QSE_DLL_DEFINE_SIMPLE (item_t); - -static int test3 () -{ - qse_size_t n; - QSE_DLL_TYPE(item_t) ii; - QSE_DLL_NODE_TYPE(item_t) x[30]; - QSE_DLL_NODE_TYPE(item_t)* p; - - QSE_DLL_INIT(&ii); - - for (n = 0; n < QSE_COUNTOF(x); n++) - { - x[n].data.a = n; - x[n].data.b = n * 2; - } - - for (n = 0; n < QSE_COUNTOF(x)/2; n++) - { - QSE_DLL_ADDHEAD (&ii, &x[n]); - } - - for (; n < QSE_COUNTOF(x); n++) - { - QSE_DLL_ADDTAIL (&ii, &x[n]); - } - - qse_printf (QSE_T("total %d items\n"), (int)QSE_DLL_SIZE (&ii)); - for (p = QSE_DLL_HEAD(&ii); QSE_DLL_ISMEMBER(&ii,p); p = p->next) - { - qse_printf (QSE_T("%d %d\n"), p->data.a, p->data.b); - } - - QSE_DLL_UNCHAIN (&ii, QSE_DLL_TAIL(&ii)->prev); - QSE_DLL_DELHEAD (&ii); - qse_printf (QSE_T("total %d items. printing in reverse\n"), (int)QSE_DLL_SIZE (&ii)); - for (p = QSE_DLL_TAIL(&ii); QSE_DLL_ISMEMBER(&ii,p); p = p->prev) - { - qse_printf (QSE_T("%d %d\n"), p->data.a, p->data.b); - } - QSE_DLL_FINI (&ii); - return 0; -} - int main () { + qse_openstdsios (); + R (test1); R (test2); - R (test3); + + qse_closestdsios (); return 0; }