Reorganized the directory structure

This commit is contained in:
2022-09-25 09:23:29 +09:00
parent 1bac167e2d
commit 84d1c4c55f
864 changed files with 11 additions and 12 deletions

2
include/Makefile.am Normal file
View File

@@ -0,0 +1,2 @@
#AUTOMAKE_OPTIONS = no-dependencies
SUBDIRS = qse

665
include/Makefile.in Normal file
View File

@@ -0,0 +1,665 @@
# Makefile.in generated by automake 1.16.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = include
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_sign.m4 \
$(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/ax_cxx_namespace.m4 \
$(top_srcdir)/m4/ax_lib_mysql.m4 $(top_srcdir)/m4/ax_numval.m4 \
$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/m4/lx_find_mpi.m4 \
$(top_srcdir)/m4/qse_try_cflags.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/include/qse/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
ctags-recursive dvi-recursive html-recursive info-recursive \
install-data-recursive install-dvi-recursive \
install-exec-recursive install-html-recursive \
install-info-recursive install-pdf-recursive \
install-ps-recursive install-recursive installcheck-recursive \
installdirs-recursive pdf-recursive ps-recursive \
tags-recursive uninstall-recursive
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
am__recursive_targets = \
$(RECURSIVE_TARGETS) \
$(RECURSIVE_CLEAN_TARGETS) \
$(am__extra_recursive_targets)
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
distdir distdir-am
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
sed_rest='s,^[^/]*/*,,'; \
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
sed_butlast='s,/*[^/]*$$,,'; \
while test -n "$$dir1"; do \
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
if test "$$first" != "."; then \
if test "$$first" = ".."; then \
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
else \
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
if test "$$first2" = "$$first"; then \
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
else \
dir2="../$$dir2"; \
fi; \
dir0="$$dir0"/"$$first"; \
fi; \
fi; \
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
done; \
reldir="$$dir2"
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BUILD_MODE = @BUILD_MODE@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DL_LIBS = @DL_LIBS@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
HAVE_CXX = @HAVE_CXX@
HAVE_CXX11 = @HAVE_CXX11@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBM = @LIBM@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBTOOL_DEPS = @LIBTOOL_DEPS@
LIPO = @LIPO@
LN_S = @LN_S@
LTDL_LIBS = @LTDL_LIBS@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
MPICC = @MPICC@
MPI_CFLAGS = @MPI_CFLAGS@
MPI_CLDFLAGS = @MPI_CLDFLAGS@
MYSQL_CFLAGS = @MYSQL_CFLAGS@
MYSQL_CONFIG = @MYSQL_CONFIG@
MYSQL_LDFLAGS = @MYSQL_LDFLAGS@
MYSQL_LIBS = @MYSQL_LIBS@
MYSQL_VERSION = @MYSQL_VERSION@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
PACKAGE_VERSION_PATCH = @PACKAGE_VERSION_PATCH@
PATH_SEPARATOR = @PATH_SEPARATOR@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
QSE_PROJECT_AUTHOR = @QSE_PROJECT_AUTHOR@
QSE_PROJECT_URL = @QSE_PROJECT_URL@
QUADMATH_LIBS = @QUADMATH_LIBS@
RANLIB = @RANLIB@
RM = @RM@
RMDIR = @RMDIR@
SED = @SED@
SENDFILE_LIBS = @SENDFILE_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SOCKET_LIBS = @SOCKET_LIBS@
SSL_LIBS = @SSL_LIBS@
STRIP = @STRIP@
TRUE = @TRUE@
UCI_LIBS = @UCI_LIBS@
UNICOWS_LIBS = @UNICOWS_LIBS@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
ax_pthread_config = @ax_pthread_config@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
#AUTOMAKE_OPTIONS = no-dependencies
SUBDIRS = qse
all: all-recursive
.SUFFIXES:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign include/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
# This directory's subdirectories are mostly independent; you can cd
# into them and run 'make' without going through this Makefile.
# To change the values of 'make' variables: instead of editing Makefiles,
# (1) if the variable is set in 'config.status', edit 'config.status'
# (which will cause the Makefiles to be regenerated when you run 'make');
# (2) otherwise, pass the desired values on the 'make' command line.
$(am__recursive_targets):
@fail=; \
if $(am__make_keepgoing); then \
failcom='fail=yes'; \
else \
failcom='exit 1'; \
fi; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-recursive
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-recursive
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-recursive
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
$(am__make_dryrun) \
|| test -d "$(distdir)/$$subdir" \
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|| exit 1; \
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
$(am__relativize); \
new_distdir=$$reldir; \
dir1=$$subdir; dir2="$(top_distdir)"; \
$(am__relativize); \
new_top_distdir=$$reldir; \
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
($(am__cd) $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$new_top_distdir" \
distdir="$$new_distdir" \
am__remove_distdir=: \
am__skip_length_check=: \
am__skip_mode_fix=: \
distdir) \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-recursive
all-am: Makefile
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-recursive
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
html-am:
info: info-recursive
info-am:
install-data-am:
install-dvi: install-dvi-recursive
install-dvi-am:
install-exec-am:
install-html: install-html-recursive
install-html-am:
install-info: install-info-recursive
install-info-am:
install-man:
install-pdf: install-pdf-recursive
install-pdf-am:
install-ps: install-ps-recursive
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am:
.MAKE: $(am__recursive_targets) install-am install-strip
.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
check-am clean clean-generic clean-libtool cscopelist-am ctags \
ctags-am distclean distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
installdirs-am maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
ps ps-am tags tags-am uninstall uninstall-am
.PRECIOUS: Makefile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

192
include/qse/Cstr.hpp Normal file
View File

@@ -0,0 +1,192 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CSTR_HPP_
#define _QSE_CSTR_HPP_
#include <qse/Types.hpp>
#include <qse/Hashable.hpp>
#include <qse/cmn/str.h>
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
/// The Mcstr class encapsulates a multibyte string pointer and length.
class Mcstr: public Types::mcstr_t, public Hashable
{
public:
Mcstr (qse_mchar_t* ptr)
{
this->ptr = ptr;
this->len = qse_mbslen(ptr);
}
Mcstr (const qse_mchar_t* ptr)
{
this->ptr = (qse_mchar_t*)ptr;
this->len = qse_mbslen(ptr);
}
Mcstr (qse_mchar_t* ptr, qse_size_t len)
{
this->ptr = ptr;
this->len = len;
}
Mcstr (const qse_mchar_t* ptr, qse_size_t len)
{
this->ptr = (qse_mchar_t*)ptr;
this->len = len;
}
Mcstr (Types::mcstr_t& str)
{
this->ptr = (qse_mchar_t*)str.ptr;
this->len = str.len;
}
qse_size_t getHashCode () const
{
return Hashable::getHashCode (this->ptr, this->len * QSE_SIZEOF(*this->ptr));
}
bool operator== (const Mcstr& str) const
{
return qse_mbsxncmp (this->ptr, this->len, str.ptr, str.len) == 0;
}
bool operator!= (const Mcstr& str) const
{
return qse_mbsxncmp (this->ptr, this->len, str.ptr, str.len) != 0;
}
};
/// The Mcstr class encapsulates a wide-character string pointer and length.
class Wcstr: public Types::wcstr_t, public Hashable
{
public:
Wcstr (qse_wchar_t* ptr)
{
this->ptr = ptr;
this->len = qse_wcslen(ptr);
}
Wcstr (const qse_wchar_t* ptr)
{
this->ptr = (qse_wchar_t*)ptr;
this->len = qse_wcslen(ptr);
}
Wcstr (qse_wchar_t* ptr, qse_size_t len)
{
this->ptr = ptr;
this->len = len;
}
Wcstr (const qse_wchar_t* ptr, qse_size_t len)
{
this->ptr = (qse_wchar_t*)ptr;
this->len = len;
}
Wcstr (Types::wcstr_t& str)
{
this->ptr = (qse_wchar_t*)str.ptr;
this->len = str.len;
}
qse_size_t getHashCode () const
{
return Hashable::getHashCode (this->ptr, this->len * QSE_SIZEOF(*this->ptr));
}
bool operator== (const Wcstr& str) const
{
return qse_wcsxncmp (this->ptr, this->len, str.ptr, str.len) == 0;
}
bool operator!= (const Wcstr& str) const
{
return qse_wcsxncmp (this->ptr, this->len, str.ptr, str.len) != 0;
}
};
/// The Mcstr class encapsulates a character string pointer and length.
class Cstr: public Types::cstr_t, public Hashable
{
public:
Cstr (qse_char_t* ptr)
{
this->ptr = ptr;
this->len = qse_strlen(ptr);
}
Cstr (const qse_char_t* ptr)
{
this->ptr = (qse_char_t*)ptr;
this->len = qse_strlen(ptr);
}
Cstr (qse_char_t* ptr, qse_size_t len)
{
this->ptr = ptr;
this->len = len;
}
Cstr (const qse_char_t* ptr, qse_size_t len)
{
this->ptr = (qse_char_t*)ptr;
this->len = len;
}
Cstr (Types::cstr_t& str)
{
this->ptr = (qse_char_t*)str.ptr;
this->len = str.len;
}
qse_size_t getHashCode () const
{
return Hashable::getHashCode (this->ptr, this->len * QSE_SIZEOF(*this->ptr));
}
bool operator== (const Cstr& str) const
{
return qse_strxncmp (this->ptr, this->len, str.ptr, str.len) == 0;
}
bool operator!= (const Cstr& str) const
{
return qse_strxncmp (this->ptr, this->len, str.ptr, str.len) != 0;
}
};
/////////////////////////////////
QSE_END_NAMESPACE(QSE)
/////////////////////////////////
#endif

91
include/qse/Exception.hpp Normal file
View File

@@ -0,0 +1,91 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_EXCEPTION_HPP_
#define _QSE_EXCEPTION_HPP_
/// \file
/// Provides the Exception class.
#include <qse/Types.hpp>
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
/// The Exception class implements the exception object.
class QSE_EXPORT Exception
{
public:
Exception (
const qse_char_t* name, const qse_char_t* msg,
const qse_char_t* file, qse_size_t line) QSE_CPP_NOEXCEPT:
name(name), msg(msg)
#if !defined(QSE_NO_LOCATION_IN_EXCEPTION)
, file(file), line(line)
#endif
{
}
const qse_char_t* name;
const qse_char_t* msg;
#if !defined(QSE_NO_LOCATION_IN_EXCEPTION)
const qse_char_t* file;
qse_size_t line;
#endif
};
#define QSE_THROW(ex_name) \
throw ex_name(QSE_Q(ex_name),QSE_Q(ex_name), QSE_T(__FILE__), (qse_size_t)__LINE__)
#define QSE_THROW_WITH_MSG(ex_name,msg) \
throw ex_name(QSE_Q(ex_name),msg, QSE_T(__FILE__), (qse_size_t)__LINE__)
#define QSE_EXCEPTION(ex_name) \
class ex_name: public QSE::Exception \
{ \
public: \
ex_name (const qse_char_t* name, const qse_char_t* msg, \
const qse_char_t* file, qse_size_t line) QSE_CPP_NOEXCEPT: \
QSE::Exception (name, msg, file, line) {} \
}
#define QSE_EXCEPTION_NAME(exception_object) ((exception_object).name)
#define QSE_EXCEPTION_MSG(exception_object) ((exception_object).msg)
#if !defined(QSE_NO_LOCATION_IN_EXCEPTION)
# define QSE_EXCEPTION_FILE(exception_object) ((exception_object).file)
# define QSE_EXCEPTION_LINE(exception_object) ((exception_object).line)
#else
# define QSE_EXCEPTION_FILE(exception_object) (QSE_T(""))
# define QSE_EXCEPTION_LINE(exception_object) (0)
#endif
/////////////////////////////////
QSE_END_NAMESPACE(QSE)
/////////////////////////////////
#endif

107
include/qse/Growable.hpp Normal file
View File

@@ -0,0 +1,107 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_GROWABLE_HPP_
#define _QSE_GROWABLE_HPP_
/// \file
/// Provides classes for handling size growth including buffer growth.
#include <qse/Types.hpp>
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
///
/// The GrowthPolicy class is an abstract class that defines the behavior of
/// growth policy.
///
class QSE_EXPORT GrowthPolicy
{
public:
virtual ~GrowthPolicy () {}
///
/// A subclass must implement this function to return a new size over
/// the existing size \a current.
///
virtual qse_size_t getNewSize (qse_size_t current) const = 0;
};
///
/// The PercentageGrowthPolicy class calculates a new size incremented by
/// the configured percentage over the existing size.
///
class QSE_EXPORT PercentageGrowthPolicy: public GrowthPolicy
{
public:
PercentageGrowthPolicy (int percentage = 0): _percentage(percentage) {}
qse_size_t getNewSize (qse_size_t current) const
{
// TODO: better way to handle overflow?
qse_size_t new_size = current + ((current * this->_percentage) / 100);
if (new_size < current) new_size = QSE_TYPE_MAX(qse_size_t);
return new_size;
}
protected:
int _percentage;
};
///
/// The Growable class implements common functions to get and set growth policy.
/// The class of an object that needs to grow the buffer or something similar
/// can inherit this class and utilize the policy set. The interface is designed
/// to remember the pointer to the policy to minimize memory use. This requires
/// the policy to outlive the life of the target object set with the policy.
///
class QSE_EXPORT Growable
{
public:
Growable (const GrowthPolicy* p = QSE_NULL): _growth_policy(p) {}
const GrowthPolicy* getGrowthPolicy () const
{
return this->_growth_policy;
}
void setGrowthPolicy (const GrowthPolicy* p)
{
this->_growth_policy = p;
}
protected:
const GrowthPolicy* _growth_policy;
};
/////////////////////////////////
QSE_END_NAMESPACE(QSE)
/////////////////////////////////
#endif

95
include/qse/Hashable.hpp Normal file
View File

@@ -0,0 +1,95 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_HASHABLE_HPP_
#define _QSE_HASHABLE_HPP_
/// \file
/// Privides the Hashable interface class.
#include <qse/Types.hpp>
#include <qse/hash.h>
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
/// The Hashable class is an abstract class that provides interface required
/// by a hasable object. In addtion, it provides static hash calculation
/// functions for convenience.
///
class QSE_EXPORT Hashable
{
public:
virtual ~Hashable () {}
/// A class of an hashable object must implement this function.
virtual qse_size_t getHashCode () const = 0;
static qse_size_t getHashCode (qse_size_t init, const qse_mchar_t* str)
{
qse_size_t n = init;
QSE_HASH_MORE_MBS(n, str);
return n;
}
static qse_size_t getHashCode (const qse_mchar_t* str)
{
return Hashable::getHashCode(0, str);
}
static qse_size_t getHashCode (qse_size_t init, const qse_wchar_t* str)
{
qse_size_t n = init;
QSE_HASH_MORE_WCS(n, str);
return n;
}
static qse_size_t getHashCode (const qse_wchar_t* str)
{
return Hashable::getHashCode(0, str);
}
static qse_size_t getHashCode (qse_size_t init, const void* data, qse_size_t size)
{
qse_size_t n = init;
QSE_HASH_BYTES (n, data, size);
return n;
}
/// The getHashCode() function calculates a hash value of a byte stream
/// pointed to by \a data of the length \a size.
static qse_size_t getHashCode (const void* data, qse_size_t size)
{
return Hashable::getHashCode(0, data, size);
}
};
/////////////////////////////////
QSE_END_NAMESPACE(QSE)
/////////////////////////////////
#endif

24
include/qse/Makefile.am Normal file
View File

@@ -0,0 +1,24 @@
SUBDIRS = cmn cry si awk sed xli http rad dhcp sttp
pkgincludedir = $(includedir)/qse
pkginclude_HEADERS = \
conf-msw.h conf-os2.h conf-dos.h conf-vms.h conf-mac.h conf-inf.h \
types.h macros.h hash.h pack1.h unpack.h
if ENABLE_CXX
pkginclude_HEADERS += \
Types.hpp Growable.hpp Hashable.hpp Uncopyable.hpp RefCounted.hpp \
Exception.hpp Cstr.hpp
endif
install-data-hook:
@echo "#ifndef _QSE_CONFIG_H_" > "$(DESTDIR)$(pkgincludedir)/config.h"
@echo "#define _QSE_CONFIG_H_" >> "$(DESTDIR)$(pkgincludedir)/config.h"
@$(EGREP) "#define[ ]+QSE_" "$(top_builddir)/include/qse/config.h" >> "$(DESTDIR)$(pkgincludedir)/config.h"
@echo "#endif" >> "$(DESTDIR)$(pkgincludedir)/config.h"
@$(RM) "$(DESTDIR)$(pkgincludedir)/config.h.in"
@$(SED) 's|/\*#define QSE_HAVE_CONFIG_H\*/|#define QSE_HAVE_CONFIG_H|' "$(srcdir)/types.h" > "$(DESTDIR)$(pkgincludedir)/types.h"
uninstall-hook:
@$(RM) "$(DESTDIR)$(pkgincludedir)/config.h"

762
include/qse/Makefile.in Normal file
View File

@@ -0,0 +1,762 @@
# Makefile.in generated by automake 1.16.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
@ENABLE_CXX_TRUE@am__append_1 = \
@ENABLE_CXX_TRUE@ Types.hpp Growable.hpp Hashable.hpp Uncopyable.hpp RefCounted.hpp \
@ENABLE_CXX_TRUE@ Exception.hpp Cstr.hpp
subdir = include/qse
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_sign.m4 \
$(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/ax_cxx_namespace.m4 \
$(top_srcdir)/m4/ax_lib_mysql.m4 $(top_srcdir)/m4/ax_numval.m4 \
$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/m4/lx_find_mpi.m4 \
$(top_srcdir)/m4/qse_try_cflags.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__pkginclude_HEADERS_DIST) \
$(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
ctags-recursive dvi-recursive html-recursive info-recursive \
install-data-recursive install-dvi-recursive \
install-exec-recursive install-html-recursive \
install-info-recursive install-pdf-recursive \
install-ps-recursive install-recursive installcheck-recursive \
installdirs-recursive pdf-recursive ps-recursive \
tags-recursive uninstall-recursive
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__pkginclude_HEADERS_DIST = conf-msw.h conf-os2.h conf-dos.h \
conf-vms.h conf-mac.h conf-inf.h types.h macros.h hash.h \
pack1.h unpack.h Types.hpp Growable.hpp Hashable.hpp \
Uncopyable.hpp RefCounted.hpp Exception.hpp Cstr.hpp
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(pkgincludedir)"
HEADERS = $(pkginclude_HEADERS)
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
am__recursive_targets = \
$(RECURSIVE_TARGETS) \
$(RECURSIVE_CLEAN_TARGETS) \
$(am__extra_recursive_targets)
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
distdir distdir-am
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \
config.h.in
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
sed_rest='s,^[^/]*/*,,'; \
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
sed_butlast='s,/*[^/]*$$,,'; \
while test -n "$$dir1"; do \
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
if test "$$first" != "."; then \
if test "$$first" = ".."; then \
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
else \
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
if test "$$first2" = "$$first"; then \
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
else \
dir2="../$$dir2"; \
fi; \
dir0="$$dir0"/"$$first"; \
fi; \
fi; \
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
done; \
reldir="$$dir2"
pkgincludedir = $(includedir)/qse
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BUILD_MODE = @BUILD_MODE@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DL_LIBS = @DL_LIBS@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
HAVE_CXX = @HAVE_CXX@
HAVE_CXX11 = @HAVE_CXX11@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBM = @LIBM@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBTOOL_DEPS = @LIBTOOL_DEPS@
LIPO = @LIPO@
LN_S = @LN_S@
LTDL_LIBS = @LTDL_LIBS@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
MPICC = @MPICC@
MPI_CFLAGS = @MPI_CFLAGS@
MPI_CLDFLAGS = @MPI_CLDFLAGS@
MYSQL_CFLAGS = @MYSQL_CFLAGS@
MYSQL_CONFIG = @MYSQL_CONFIG@
MYSQL_LDFLAGS = @MYSQL_LDFLAGS@
MYSQL_LIBS = @MYSQL_LIBS@
MYSQL_VERSION = @MYSQL_VERSION@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
PACKAGE_VERSION_PATCH = @PACKAGE_VERSION_PATCH@
PATH_SEPARATOR = @PATH_SEPARATOR@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
QSE_PROJECT_AUTHOR = @QSE_PROJECT_AUTHOR@
QSE_PROJECT_URL = @QSE_PROJECT_URL@
QUADMATH_LIBS = @QUADMATH_LIBS@
RANLIB = @RANLIB@
RM = @RM@
RMDIR = @RMDIR@
SED = @SED@
SENDFILE_LIBS = @SENDFILE_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SOCKET_LIBS = @SOCKET_LIBS@
SSL_LIBS = @SSL_LIBS@
STRIP = @STRIP@
TRUE = @TRUE@
UCI_LIBS = @UCI_LIBS@
UNICOWS_LIBS = @UNICOWS_LIBS@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
ax_pthread_config = @ax_pthread_config@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
SUBDIRS = cmn cry si awk sed xli http rad dhcp sttp
pkginclude_HEADERS = conf-msw.h conf-os2.h conf-dos.h conf-vms.h \
conf-mac.h conf-inf.h types.h macros.h hash.h pack1.h unpack.h \
$(am__append_1)
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
.SUFFIXES:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/qse/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign include/qse/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
config.h: stamp-h1
@test -f $@ || rm -f stamp-h1
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status include/qse/config.h
$(srcdir)/config.h.in: $(am__configure_deps)
($(am__cd) $(top_srcdir) && $(AUTOHEADER))
rm -f stamp-h1
touch $@
distclean-hdr:
-rm -f config.h stamp-h1
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-pkgincludeHEADERS: $(pkginclude_HEADERS)
@$(NORMAL_INSTALL)
@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \
$(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \
$(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \
done
uninstall-pkgincludeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir)
# This directory's subdirectories are mostly independent; you can cd
# into them and run 'make' without going through this Makefile.
# To change the values of 'make' variables: instead of editing Makefiles,
# (1) if the variable is set in 'config.status', edit 'config.status'
# (which will cause the Makefiles to be regenerated when you run 'make');
# (2) otherwise, pass the desired values on the 'make' command line.
$(am__recursive_targets):
@fail=; \
if $(am__make_keepgoing); then \
failcom='fail=yes'; \
else \
failcom='exit 1'; \
fi; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-recursive
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-recursive
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-recursive
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
$(am__make_dryrun) \
|| test -d "$(distdir)/$$subdir" \
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|| exit 1; \
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
$(am__relativize); \
new_distdir=$$reldir; \
dir1=$$subdir; dir2="$(top_distdir)"; \
$(am__relativize); \
new_top_distdir=$$reldir; \
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
($(am__cd) $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$new_top_distdir" \
distdir="$$new_distdir" \
am__remove_distdir=: \
am__skip_length_check=: \
am__skip_mode_fix=: \
distdir) \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-recursive
all-am: Makefile $(HEADERS) config.h
installdirs: installdirs-recursive
installdirs-am:
for dir in "$(DESTDIR)$(pkgincludedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-recursive
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-hdr distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
html-am:
info: info-recursive
info-am:
install-data-am: install-pkgincludeHEADERS
@$(NORMAL_INSTALL)
$(MAKE) $(AM_MAKEFLAGS) install-data-hook
install-dvi: install-dvi-recursive
install-dvi-am:
install-exec-am:
install-html: install-html-recursive
install-html-am:
install-info: install-info-recursive
install-info-am:
install-man:
install-pdf: install-pdf-recursive
install-pdf-am:
install-ps: install-ps-recursive
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am: uninstall-pkgincludeHEADERS
@$(NORMAL_INSTALL)
$(MAKE) $(AM_MAKEFLAGS) uninstall-hook
.MAKE: $(am__recursive_targets) all install-am install-data-am \
install-strip uninstall-am
.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
check-am clean clean-generic clean-libtool cscopelist-am ctags \
ctags-am distclean distclean-generic distclean-hdr \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-data-hook install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-pdf \
install-pdf-am install-pkgincludeHEADERS install-ps \
install-ps-am install-strip installcheck installcheck-am \
installdirs installdirs-am maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic \
mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
uninstall-am uninstall-hook uninstall-pkgincludeHEADERS
.PRECIOUS: Makefile
install-data-hook:
@echo "#ifndef _QSE_CONFIG_H_" > "$(DESTDIR)$(pkgincludedir)/config.h"
@echo "#define _QSE_CONFIG_H_" >> "$(DESTDIR)$(pkgincludedir)/config.h"
@$(EGREP) "#define[ ]+QSE_" "$(top_builddir)/include/qse/config.h" >> "$(DESTDIR)$(pkgincludedir)/config.h"
@echo "#endif" >> "$(DESTDIR)$(pkgincludedir)/config.h"
@$(RM) "$(DESTDIR)$(pkgincludedir)/config.h.in"
@$(SED) 's|/\*#define QSE_HAVE_CONFIG_H\*/|#define QSE_HAVE_CONFIG_H|' "$(srcdir)/types.h" > "$(DESTDIR)$(pkgincludedir)/types.h"
uninstall-hook:
@$(RM) "$(DESTDIR)$(pkgincludedir)/config.h"
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@@ -0,0 +1,88 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_REFCOUNTED_HPP_
#define _QSE_REFCOUNTED_HPP_
/// \file
/// Defines a class that can be used to implement a class of a reference
/// counted object.
#include <qse/Uncopyable.hpp>
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
/// The RefCounted class provides common functions required to
/// implement a reference counted class.
class QSE_EXPORT RefCounted: public Uncopyable
{
protected:
RefCounted (): _ref_count(0)
{
}
public:
/// The ref() function increments the reference count and returns
/// the incremented count.
qse_size_t ref () const
{
return ++this->_ref_count;
}
/// The deref() function decrements the reference count and returns
/// the decremented count. The caller should kill the callee if it
/// returns 0.
qse_size_t deref () const
{
return --this->_ref_count;
}
/// The getRefCount() function returns the current reference count.
qse_size_t getRefCount () const
{
return this->_ref_count;
}
/// The isShared() function returns true if the object is referenced
/// more than twice and false otherwise.
bool isShared () const
{
return this->_ref_count > 1;
}
protected:
mutable qse_size_t _ref_count;
};
/////////////////////////////////
QSE_END_NAMESPACE(QSE)
/////////////////////////////////
#endif

261
include/qse/Types.hpp Normal file
View File

@@ -0,0 +1,261 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_TYPES_HPP_
#define _QSE_TYPES_HPP_
/// \file
/// Defines aliases to various QSE types in a class and holds various feature
/// configuration options.
#include <qse/types.h>
#include <qse/macros.h>
#if (__cplusplus >= 201103L) || (defined(_MSC_VER) && _MSC_VER >= 1900) // C++11 or later
#define QSE_LANG_CPP11 1
#define QSE_CPP_NOEXCEPT noexcept(true)
#define QSE_CPP_THREXCEPT1(e1) throw(e1)
#define QSE_CPP_THREXCEPT2(e1,e2) throw(e1,e2)
#define QSE_CPP_THREXCEPT3(e1,e2,e3) throw(e1,e2,e3)
#define QSE_CPP_THREXCEPT4(e1,e2,e3,e4) throw(e1,e2,e3,e4)
#define QSE_CPP_THREXCEPT5(e1,e2,e3,e4,e5) throw(e1,e2,e3,e4,e5)
#define QSE_CPP_EXPLICIT explicit
#define QSE_CPP_OVERRIDE override
/// The QSE_CPP_ENABLE_CPP11_MOVE macro enables C++11 move semantics
/// in various classes.
#define QSE_CPP_ENABLE_CPP11_MOVE 1
// The QSE_CPP_CALL_DESTRUCTOR() macro calls a destructor explicitly.
#define QSE_CPP_CALL_DESTRUCTOR(ptr, class_name) ((ptr)->~class_name())
// The QSE_CPP_CALL_PLACEMENT_DELETE1() macro calls the global operator delete
// with 1 extra argument given.
#define QSE_CPP_CALL_PLACEMENT_DELETE1(ptr, arg1) (::operator delete((ptr), (arg1)))
#define QSE_CPP_TEMPLATE_QUALIFIER template
#elif (__cplusplus >= 199711L) // C++98
#undef QSE_LANG_CPP11
#define QSE_CPP_NOEXCEPT throw()
#define QSE_CPP_THREXCEPT1(e1) throw(e1)
#define QSE_CPP_THREXCEPT2(e1,e2) throw(e1,e2)
#define QSE_CPP_THREXCEPT3(e1,e2,e3) throw(e1,e2,e3)
#define QSE_CPP_THREXCEPT4(e1,e2,e3,e4) throw(e1,e2,e3,e4)
#define QSE_CPP_THREXCEPT5(e1,e2,e3,e4,e5) throw(e1,e2,e3,e4,e5)
#define QSE_CPP_EXPLICIT
#define QSE_CPP_OVERRIDE
#define QSE_CPP_CALL_DESTRUCTOR(ptr, class_name) ((ptr)->~class_name())
#define QSE_CPP_CALL_PLACEMENT_DELETE1(ptr, arg1) (::operator delete((ptr), (arg1)))
#define QSE_CPP_TEMPLATE_QUALIFIER template
#else
#define QSE_CPP_NOEXCEPT
#define QSE_CPP_THREXCEPT1(e1)
#define QSE_CPP_THREXCEPT2(e1,e2)
#define QSE_CPP_THREXCEPT3(e1,e2,e3)
#define QSE_CPP_THREXCEPT4(e1,e2,e3,e4)
#define QSE_CPP_THREXCEPT5(e1,e2,e3,e4,e5)
#define QSE_CPP_EXPLICIT
#define QSE_CPP_OVERRIDE
#if defined(__BORLANDC__)
// Explicit destructor call requires a class name depending on the
// C++ standard/compiler.
//
// Node* x;
// x->~Node ();
//
// While x->~Node() is ok with modern compilers, some old compilers
// like BCC55 required the class name in the call as shown below.
//
// x->Node::~Node ();
#define QSE_CPP_CALL_DESTRUCTOR(ptr, class_name) ((ptr)->class_name::~class_name())
#define QSE_CPP_CALL_PLACEMENT_DELETE1(ptr, arg1) (::operator delete((ptr), (arg1)))
#define QSE_CPP_TEMPLATE_QUALIFIER template
#elif defined(__WATCOMC__)
// WATCOM has a problem with this syntax.
// Node* x; x->Node::~Node().
// But it doesn't support operator delete overloading.
#define QSE_CPP_CALL_DESTRUCTOR(ptr, class_name) ((ptr)->~class_name())
#define QSE_CPP_CALL_PLACEMENT_DELETE1(ptr, arg1) (::qse_operator_delete((ptr), (arg1)))
// When the name of a member template specialization appears after . or
// -> in a postfix-expression, or after :: in a qualified-id that explic-
// itly depends on a template-argument (_temp.dep_), the member template
// name must be prefixed by the keyword template. Otherwise the name is
// assumed to name a non-template. [Example:
// class X {
// public:
// template<size_t> X* alloc();
// };
// void f(X* p)
// {
// X* p1 = p->alloc<200>();
// // ill-formed: < means less than
// X* p2 = p->template alloc<200>();
// // fine: < starts explicit qualification
// }
// --end example]
//
// WATCOM doesn't support this qualifier.
#define QSE_CPP_TEMPLATE_QUALIFIER
#define QSE_CPP_NO_OPERATOR_DELETE_OVERLOADING 1
#else
#define QSE_CPP_CALL_DESTRUCTOR(ptr, class_name) ((ptr)->~class_name())
#define QSE_CPP_CALL_PLACEMENT_DELETE1(ptr, arg1) (::operator delete((ptr), (arg1)))
#define QSE_CPP_TEMPLATE_QUALIFIER template
#endif
#endif
#if defined(QSE_CPP_ENABLE_CPP11_MOVE)
template<typename T> struct QSE_CPP_RMREF { typedef T Type; };
template<typename T> struct QSE_CPP_RMREF<T&> { typedef T Type; };
template<typename T> struct QSE_CPP_RMREF<T&&> { typedef T Type; };
template<typename T> inline
typename QSE_CPP_RMREF<T>::Type&& QSE_CPP_RVREF(T&& v)
{
return (typename QSE_CPP_RMREF<T>::Type&&)v;
}
#else
/*
template<typename T> inline
T& QSE_CPP_RVREF(T& v) { return (T&)v; }
template<typename T> inline
const T& QSE_CPP_RVREF(const T& v) { return (const T&)v; }
*/
#define QSE_CPP_RVREF(x) x
#endif
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
/**
* The Types class defines handy aliases for various QSE types.
*/
class QSE_EXPORT Types
{
public:
/** boolean data type */
typedef qse_bool_t bool_t;
/** data type that can hold any character */
typedef qse_char_t char_t;
/** data type that can hold an unsigned char_t value */
typedef qse_chau_t chau_t;
/** data type that can hold any character or an end-of-file value */
typedef qse_cint_t cint_t;
/** redefines an unsigned integer number of the same size as void* */
typedef qse_size_t size_t;
/** signed version of size_t */
typedef qse_ssize_t ssize_t;
/** redefines qse_long_t */
typedef qse_long_t long_t;
/** redefines qse_ulong_t */
typedef qse_ulong_t ulong_t;
/** redefines qse_intptr_t */
typedef qse_intptr_t intptr_t;
/** redefines qse_uintptr_t */
typedef qse_uintptr_t uintptr_t;
/** redefines qse_intmax_t */
typedef qse_intmax_t intmax_t;
/** redefines qse_uintmax_t */
typedef qse_uintmax_t uintmax_t;
/** redefines a floating-point number */
typedef qse_flt_t flt_t;
/** redefines a structure of a character pointer and length */
typedef qse_cstr_t cstr_t;
/** redefines a structure of a character pointer and length */
typedef qse_wcstr_t wcstr_t;
/** redefines a structure of a character pointer and length */
typedef qse_mcstr_t mcstr_t;
/** defines common error codes */
enum ErrorNumber
{
/* [NOTE] if you change items here, you must change the stock error description in TypesErrorNumberToStr::operator() */
E_ENOERR, /**< no error */
E_EOTHER, /**< other error */
E_ENOIMPL, /**< not implemented */
E_ESYSERR, /**< subsystem error */
E_EINTERN, /**< internal error */
E_ENOMEM,
E_ENARGS, /**< wrong number of arguments */
E_EINVAL,
E_EACCES,
E_EPERM,
E_ENOENT,
E_EEXIST,
E_ENOTDIR,
E_EINTR,
E_EPIPE,
E_EINPROG, /* in progress */
E_EAGAIN, /* resource unavailable unavailable */
E_EEXCEPT /**< exception */
};
};
/////////////////////////////////
QSE_END_NAMESPACE(QSE)
/////////////////////////////////
#endif

View File

@@ -0,0 +1,57 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_UNCOPYABLE_HPP_
#define _QSE_UNCOPYABLE_HPP_
/// \file
/// Provides the Uncopyable class.
#include <qse/Types.hpp>
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
/// The Uncopyable class disallows an inheriting class to be assigned or
/// copied.
class QSE_EXPORT Uncopyable
{
public:
Uncopyable () QSE_CPP_NOEXCEPT {}
//virtual ~Uncopyable () {}
private:
Uncopyable (const Uncopyable&);
const Uncopyable& operator= (const Uncopyable&);
};
/////////////////////////////////
QSE_END_NAMESPACE(QSE)
/////////////////////////////////
#endif

1435
include/qse/awk/Awk.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
pkgincludedir = $(includedir)/qse/awk
pkginclude_HEADERS = awk.h stdawk.h
if ENABLE_CXX
pkginclude_HEADERS += Awk.hpp StdAwk.hpp
endif

606
include/qse/awk/Makefile.in Normal file
View File

@@ -0,0 +1,606 @@
# Makefile.in generated by automake 1.16.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
@ENABLE_CXX_TRUE@am__append_1 = Awk.hpp StdAwk.hpp
subdir = include/qse/awk
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_sign.m4 \
$(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/ax_cxx_namespace.m4 \
$(top_srcdir)/m4/ax_lib_mysql.m4 $(top_srcdir)/m4/ax_numval.m4 \
$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/m4/lx_find_mpi.m4 \
$(top_srcdir)/m4/qse_try_cflags.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__pkginclude_HEADERS_DIST) \
$(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/include/qse/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__pkginclude_HEADERS_DIST = awk.h stdawk.h Awk.hpp StdAwk.hpp
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(pkgincludedir)"
HEADERS = $(pkginclude_HEADERS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
pkgincludedir = $(includedir)/qse/awk
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BUILD_MODE = @BUILD_MODE@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DL_LIBS = @DL_LIBS@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
HAVE_CXX = @HAVE_CXX@
HAVE_CXX11 = @HAVE_CXX11@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBM = @LIBM@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBTOOL_DEPS = @LIBTOOL_DEPS@
LIPO = @LIPO@
LN_S = @LN_S@
LTDL_LIBS = @LTDL_LIBS@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
MPICC = @MPICC@
MPI_CFLAGS = @MPI_CFLAGS@
MPI_CLDFLAGS = @MPI_CLDFLAGS@
MYSQL_CFLAGS = @MYSQL_CFLAGS@
MYSQL_CONFIG = @MYSQL_CONFIG@
MYSQL_LDFLAGS = @MYSQL_LDFLAGS@
MYSQL_LIBS = @MYSQL_LIBS@
MYSQL_VERSION = @MYSQL_VERSION@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
PACKAGE_VERSION_PATCH = @PACKAGE_VERSION_PATCH@
PATH_SEPARATOR = @PATH_SEPARATOR@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
QSE_PROJECT_AUTHOR = @QSE_PROJECT_AUTHOR@
QSE_PROJECT_URL = @QSE_PROJECT_URL@
QUADMATH_LIBS = @QUADMATH_LIBS@
RANLIB = @RANLIB@
RM = @RM@
RMDIR = @RMDIR@
SED = @SED@
SENDFILE_LIBS = @SENDFILE_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SOCKET_LIBS = @SOCKET_LIBS@
SSL_LIBS = @SSL_LIBS@
STRIP = @STRIP@
TRUE = @TRUE@
UCI_LIBS = @UCI_LIBS@
UNICOWS_LIBS = @UNICOWS_LIBS@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
ax_pthread_config = @ax_pthread_config@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
pkginclude_HEADERS = awk.h stdawk.h $(am__append_1)
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/qse/awk/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign include/qse/awk/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-pkgincludeHEADERS: $(pkginclude_HEADERS)
@$(NORMAL_INSTALL)
@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \
$(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \
$(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \
done
uninstall-pkgincludeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir)
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(pkgincludedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-pkgincludeHEADERS
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-pkgincludeHEADERS
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libtool cscopelist-am ctags ctags-am distclean \
distclean-generic distclean-libtool distclean-tags distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-pdf \
install-pdf-am install-pkgincludeHEADERS install-ps \
install-ps-am install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
ps ps-am tags tags-am uninstall uninstall-am \
uninstall-pkgincludeHEADERS
.PRECIOUS: Makefile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

228
include/qse/awk/StdAwk.hpp Normal file
View File

@@ -0,0 +1,228 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_AWK_STDAWK_HPP_
#define _QSE_AWK_STDAWK_HPP_
#include <qse/awk/Awk.hpp>
#include <qse/cmn/StdMmgr.hpp>
#include <qse/cmn/time.h>
/// \file
/// Standard AWK Interpreter
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
////////////////////////////////
///
/// The StdAwk class provides an easier-to-use interface by overriding
/// primitive methods, and implementing the file handler, the pipe handler,
/// and common intrinsic functions.
///
class QSE_EXPORT StdAwk: public Awk
{
public:
///
/// The SourceFile class implements script I/O from and to a file.
///
class QSE_EXPORT SourceFile: public Source
{
public:
SourceFile (const char_t* name, qse_cmgr_t* cmgr = QSE_NULL):
name (name), cmgr (cmgr)
{
dir.ptr = QSE_NULL; dir.len = 0;
}
int open (Data& io);
int close (Data& io);
ssize_t read (Data& io, char_t* buf, size_t len);
ssize_t write (Data& io, const char_t* buf, size_t len);
protected:
const char_t* name;
qse_cstr_t dir;
qse_cmgr_t* cmgr;
};
///
/// The SourceString class implements script input from a string.
/// Deparsing is not supported.
///
class QSE_EXPORT SourceString: public Source
{
public:
SourceString (const char_t* str): str (str) {}
int open (Data& io);
int close (Data& io);
ssize_t read (Data& io, char_t* buf, size_t len);
ssize_t write (Data& io, const char_t* buf, size_t len);
protected:
const char_t* str;
const char_t* ptr;
};
StdAwk (Mmgr* mmgr = QSE_NULL): Awk(mmgr), stdmod_up(false), console_cmgr(QSE_NULL)
{
}
int open ();
void close ();
void uponClosing ();
Run* parse (Source& in, Source& out);
/// The setConsoleCmgr() function sets the encoding type of
/// the console streams. They include both the input and the output
/// streams. It provides no way to specify a different encoding
/// type for the input and the output stream.
void setConsoleCmgr (const qse_cmgr_t* cmgr);
/// The getConsoleCmgr() function returns the current encoding
/// type set for the console streams.
const qse_cmgr_t* getConsoleCmgr () const;
/// The addConsoleOutput() function adds a file to form an
/// output console stream.
int addConsoleOutput (const char_t* arg, size_t len);
int addConsoleOutput (const char_t* arg);
void clearConsoleOutputs ();
protected:
int make_additional_globals (Run* run);
int build_argcv (Run* run);
int build_environ (Run* run);
int __build_environ (Run* run, void* envptr);
// intrinsic functions
qse_cmgr_t* getiocmgr (const char_t* ioname);
int setioattr (Run& run, Value& ret, Value* args, size_t nargs, const char_t* name, size_t len);
int getioattr (Run& run, Value& ret, Value* args, size_t nargs, const char_t* name, size_t len);
// pipe io handlers
int openPipe (Pipe& io);
int closePipe (Pipe& io);
ssize_t readPipe (Pipe& io, char_t* buf, size_t len);
ssize_t writePipe (Pipe& io, const char_t* buf, size_t len);
ssize_t writePipeBytes (Pipe& io, const qse_mchar_t* buf, size_t len);
int flushPipe (Pipe& io);
// file io handlers
int openFile (File& io);
int closeFile (File& io);
ssize_t readFile (File& io, char_t* buf, size_t len);
ssize_t writeFile (File& io, const char_t* buf, size_t len);
ssize_t writeFileBytes (File& io, const qse_mchar_t* buf, size_t len);
int flushFile (File& io);
// console io handlers
int openConsole (Console& io);
int closeConsole (Console& io);
ssize_t readConsole (Console& io, char_t* buf, size_t len);
ssize_t writeConsole (Console& io, const char_t* buf, size_t len);
ssize_t writeConsoleBytes (Console& io, const qse_mchar_t* buf, size_t len);
int flushConsole (Console& io);
int nextConsole (Console& io);
// primitive handlers
void* allocMem (size_t n);
void* reallocMem (void* ptr, size_t n);
void freeMem (void* ptr);
flt_t pow (flt_t x, flt_t y);
flt_t mod (flt_t x, flt_t y);
void* modopen (const mod_spec_t* spec);
void modclose (void* handle);
void* modsym (void* handle, const char_t* name);
protected:
qse_htb_t cmgrtab;
bool cmgrtab_inited;
bool stdmod_up;
qse_cmgr_t* console_cmgr;
// global variables
int gbl_argc;
int gbl_argv;
int gbl_environ;
// standard input console - reuse runarg
size_t runarg_index;
size_t runarg_count;
// standard output console
xstrs_t ofile;
size_t ofile_index;
size_t ofile_count;
public:
struct ioattr_t
{
qse_cmgr_t* cmgr;
char_t cmgr_name[64]; // i assume that the cmgr name never exceeds this length.
qse_ntime_t tmout[4];
ioattr_t (): cmgr (QSE_NULL)
{
this->cmgr_name[0] = QSE_T('\0');
for (size_t i = 0; i < QSE_COUNTOF(this->tmout); i++)
{
this->tmout[i].sec = -999;
this->tmout[i].nsec = 0;
}
}
};
static ioattr_t default_ioattr;
protected:
ioattr_t* get_ioattr (const char_t* ptr, size_t len);
ioattr_t* find_or_make_ioattr (const char_t* ptr, size_t len);
private:
int open_console_in (Console& io);
int open_console_out (Console& io);
int open_pio (Pipe& io);
int open_nwio (Pipe& io, int flags, void* nwad);
};
/////////////////////////////////
QSE_END_NAMESPACE(QSE)
/////////////////////////////////
#endif

3364
include/qse/awk/awk.h Normal file

File diff suppressed because it is too large Load Diff

205
include/qse/awk/stdawk.h Normal file
View File

@@ -0,0 +1,205 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_AWK_STDAWK_H_
#define _QSE_AWK_STDAWK_H_
#include <qse/awk/awk.h>
/** \file
* This file defines functions and data types that help you create
* an awk interpreter with less effort. It is designed to be as close
* to conventional awk implementations as possible.
*
* The source script handler does not evaluate a file name of the "var=val"
* form as an assignment expression. Instead, it just treats it as a
* normal file name.
*/
/**
* The qse_awk_parsestd_type_t type defines standard source I/O types.
*/
enum qse_awk_parsestd_type_t
{
QSE_AWK_PARSESTD_NULL = 0, /**< pseudo-value to indicate no script */
QSE_AWK_PARSESTD_FILE = 1, /**< file */
QSE_AWK_PARSESTD_STR = 2, /**< length-bounded string */
QSE_AWK_PARSESTD_MBS = 3,
QSE_AWK_PARSESTD_WCS = 4
};
typedef enum qse_awk_parsestd_type_t qse_awk_parsestd_type_t;
/**
* The qse_awk_parsestd_t type defines a source I/O.
*/
struct qse_awk_parsestd_t
{
qse_awk_parsestd_type_t type;
union
{
struct
{
/** file path to open. #QSE_NULL or '-' for stdin/stdout. */
const qse_char_t* path;
/** a stream created with the file path is set with this
* cmgr if it is not #QSE_NULL. */
qse_cmgr_t* cmgr;
} file;
/**
* input string or dynamically allocated output string
*
* For input, the ptr and the len field of str indicates the
* pointer and the length of a string to read. You must set
* these fields before calling qse_awk_parsestd().
*
* For output, the ptr and the len field of str indicates the
* pointer and the length of a deparsed source string. The output
* string is dynamically allocated. You don't need to set these
* fields before calling qse_awk_parsestd() because they are set
* by qse_awk_parsestd() and valid while the relevant awk object
* is alive. You must free the memory chunk pointed to by the
* ptr field with qse_awk_freemem() once you're done with it to
* avoid memory leaks.
*/
qse_cstr_t str;
qse_mcstr_t mbs;
qse_wcstr_t wcs;
} u;
};
typedef struct qse_awk_parsestd_t qse_awk_parsestd_t;
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The qse_awk_openstd() function creates an awk object using the default
* memory manager and primitive functions. Besides, it adds a set of
* standard intrinsic functions like atan, system, etc. Use this function
* over qse_awk_open() if you don't need finer-grained customization.
*/
QSE_EXPORT qse_awk_t* qse_awk_openstd (
qse_size_t xtnsize, /**< extension size in bytes */
qse_awk_errnum_t* errnum /**< pointer to an error number variable */
);
/**
* The qse_awk_openstdwithmmgr() function creates an awk object with a
* user-defined memory manager. It is equivalent to qse_awk_openstd(),
* except that you can specify your own memory manager.
*/
QSE_EXPORT qse_awk_t* qse_awk_openstdwithmmgr (
qse_mmgr_t* mmgr, /**< memory manager */
qse_size_t xtnsize, /**< extension size in bytes */
qse_awk_errnum_t* errnum /**< pointer to an error number variable */
);
/**
* The qse_awk_parsestd() functions parses source script.
* The code below shows how to parse a literal string 'BEGIN { print 10; }'
* and deparses it out to a buffer 'buf'.
* \code
* int n;
* qse_awk_parsestd_t in[2];
* qse_awk_parsestd_t out;
*
* in[0].type = QSE_AWK_PARSESTD_STR;
* in[0].u.str.ptr = QSE_T("BEGIN { print 10; }");
* in[0].u.str.len = qse_strlen(in.u.str.ptr);
* in[1].type = QSE_AWK_PARSESTD_NULL;
* out.type = QSE_AWK_PARSESTD_STR;
* n = qse_awk_parsestd (awk, in, &out);
* if (n >= 0)
* {
* qse_printf (QSE_T("%s\n"), out.u.str.ptr);
* QSE_MMGR_FREE (out.u.str.ptr);
* }
* \endcode
*/
QSE_EXPORT int qse_awk_parsestd (
qse_awk_t* awk,
qse_awk_parsestd_t in[],
qse_awk_parsestd_t* out
);
/**
* The qse_awk_rtx_openstdwithmbs() function creates a standard runtime context.
* The caller should keep the contents of \a icf and \a ocf valid throughout
* the lifetime of the runtime context created. The \a cmgr is set to the
* streams created with \a icf and \a ocf if it is not #QSE_NULL.
*/
QSE_EXPORT qse_awk_rtx_t* qse_awk_rtx_openstdwithmbs (
qse_awk_t* awk,
qse_size_t xtnsize,
const qse_mchar_t* id,
const qse_mchar_t* icf[],
const qse_mchar_t* ocf[],
qse_cmgr_t* cmgr
);
/**
* The qse_awk_rtx_openstdwithwcs() function creates a standard runtime context.
* The caller should keep the contents of \a icf and \a ocf valid throughout
* the lifetime of the runtime context created. The \a cmgr is set to the
* streams created with \a icf and \a ocf if it is not #QSE_NULL.
*/
QSE_EXPORT qse_awk_rtx_t* qse_awk_rtx_openstdwithwcs (
qse_awk_t* awk,
qse_size_t xtnsize,
const qse_wchar_t* id,
const qse_wchar_t* icf[],
const qse_wchar_t* ocf[],
qse_cmgr_t* cmgr
);
#if defined(QSE_CHAR_IS_MCHAR)
# define qse_awk_rtx_openstd qse_awk_rtx_openstdwithmbs
#else
# define qse_awk_rtx_openstd qse_awk_rtx_openstdwithwcs
#endif
/**
* The qse_awk_rtx_getiocmgrstd() function gets the current character
* manager associated with a particular I/O target indicated by the name
* \a ioname if #QSE_CHAR_IS_WCHAR is defined. It always returns #QSE_NULL
* if #QSE_CHAR_IS_MCHAR is defined.
*/
QSE_EXPORT qse_cmgr_t* qse_awk_rtx_getiocmgrstd (
qse_awk_rtx_t* rtx,
const qse_char_t* ioname
);
#if defined(__cplusplus)
}
#endif
#endif

899
include/qse/cmn/Array.hpp Normal file
View File

@@ -0,0 +1,899 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_ARRAY_HPP_
#define _QSE_CMN_ARRAY_HPP_
/// \file
/// Provide the Array class.
#include <qse/Growable.hpp>
#include <qse/cmn/Mmged.hpp>
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
template <typename T>
struct ArrayPositioner
{
void operator() (T& v, qse_size_t index) const
{
// do nothing
}
};
struct ArrayResizer
{
qse_size_t operator() (qse_size_t current, const GrowthPolicy* gp) const
{
if (current <= 0) current = 1;
if (gp)
{
return gp->getNewSize (current);
}
else
{
return (current < 5000)? (current + current):
(current < 50000)? (current + (current / 2)):
(current < 100000)? (current + (current / 4)):
(current < 150000)? (current + (current / 8)):
(current + (current / 16));
}
}
};
///
/// The Array class provides a dynamically resized array.
///
/// With C++11, the Array class move-contructs values in various context.
/// The move constructor of the value must not raise an exception.
///
template <typename T, typename POSITIONER = ArrayPositioner<T>, typename RESIZER = ArrayResizer>
class Array: public Mmged, public Growable
{
public:
typedef Array<T,POSITIONER,RESIZER> SelfType;
typedef ArrayPositioner<T> DefaultPositioner;
typedef ArrayResizer DefaultResizer;
enum
{
DEFAULT_CAPACITY = 128,
INVALID_INDEX = ~(qse_size_t)0
};
void init_array (int capacity)
{
if (capacity <= 0)
{
this->buffer = QSE_NULL;
this->capacity = 0;
}
else
{
//this->buffer = new T[capacity];
this->buffer = (T*)::operator new (capacity * QSE_SIZEOF(*this->buffer), this->getMmgr());
this->capacity = capacity;
}
this->count = 0;
}
public:
Array (Mmgr* mmgr = QSE_NULL): Mmged(mmgr)
{
this->init_array (DEFAULT_CAPACITY);
}
Array (qse_size_t capacity, Mmgr* mmgr = QSE_NULL): Mmged(mmgr)
{
this->init_array (capacity);
}
Array (const SelfType& array): Mmged(array.getMmgr()), count(0), capacity(0), buffer(QSE_NULL)
{
if (array.buffer)
{
this->buffer = this->clone_buffer (array.buffer, array.capacity, array.count);
this->count = array.count;
this->capacity = array.capacity;
}
}
#if defined(QSE_CPP_ENABLE_CPP11_MOVE)
Array (SelfType&& array): Mmged(array.getMmgr()), count(0), capacity(0), buffer(QSE_NULL)
{
if (array.buffer)
{
this->buffer = array.buffer;
this->count = array.count;
this->capacity = array.capacity;
array.buffer = QSE_NULL;
array.count = 0;
array.capacity = 0;
}
}
#endif
~Array ()
{
this->clear (true);
}
SelfType& operator= (const SelfType& array)
{
if (this != &array)
{
this->clear (true);
if (array.buffer)
{
this->buffer = this->clone_buffer (array, array.capacity, array.count);
this->count = array.count;
this->capacity = array.capacity;
}
}
return *this;
}
#if defined(QSE_CPP_ENABLE_CPP11_MOVE)
SelfType& operator= (SelfType&& array)
{
if (this != &array)
{
// since 'array' is an rvalue, i know it's going to be destroyed.
// it should be safe to destroy all my items here first instead of
// arranging to swap with items of 'array'.
this->clear (true);
if (array.buffer)
{
// TODO: should i swap items if mmgrs are differnt
// between *this and array?
this->setMmgr (array.getMmgr()); // copy over mmgr.
this->buffer = array.buffer;
this->count = array.count;
this->capacity = array.capacity;
// since i cleared all items in the existing array,
// i can simply do the followings.
array.buffer = QSE_NULL;
array.count = 0;
array.capacity = 0;
}
}
return *this;
}
#endif
protected:
T* clone_buffer (const T* srcbuf, qse_size_t capa, qse_size_t cnt)
{
QSE_ASSERT (capa > 0);
QSE_ASSERT (cnt <= capa);
qse_size_t index;
//T* tmp = new T[capa];
//T* tmp = (T*)::operator new (capa * QSE_SIZEOF(*tmp), this->getMmgr());
T* tmp = (T*)this->getMmgr()->allocate(capa * QSE_SIZEOF(*tmp));
try
{
for (index = 0; index < cnt; index++)
{
// copy-construct each element.
new((QSE::Mmgr*)QSE_NULL, &tmp[index]) T(srcbuf[index]);
this->_positioner (tmp[index], index);
}
}
catch (...)
{
// in case copy-constructor raises an exception.
QSE_ASSERT (tmp != QSE_NULL);
while (index > 0)
{
--index;
this->_positioner (tmp[index], INVALID_INDEX);
tmp[index].T::~T ();
}
//::operator delete (tmp, this->getMmgr());
this->getMmgr()->dispose (tmp);
throw;
}
return tmp;
}
#if defined(QSE_CPP_ENABLE_CPP11_MOVE)
T* clone_buffer_by_moving (T* srcbuf, qse_size_t capa, qse_size_t cnt)
{
QSE_ASSERT (capa > 0);
QSE_ASSERT (cnt <= capa);
qse_size_t index;
//T* tmp = new T[capa];
//T* tmp = (T*)::operator new (capa * QSE_SIZEOF(*tmp), this->getMmgr());
T* tmp = (T*)this->getMmgr()->allocate(capa * QSE_SIZEOF(*tmp));
try
{
for (index = 0; index < cnt; index++)
{
// move-construct(or copy-construct) each element.
new((QSE::Mmgr*)QSE_NULL, &tmp[index]) T(QSE_CPP_RVREF(srcbuf[index]));
this->_positioner (tmp[index], index);
}
}
catch (...)
{
// in case move-constructor(or copy-constructor) raises an exception.
QSE_ASSERT (tmp != QSE_NULL);
while (index > 0)
{
--index;
// if move-contruction ended up with an exception,
// the original array can get into an unknown state eventually.
// i don't attempt to restore the moved object as an exception
// may be raised during restoration. i don't implement noexcept
// check yet.
//
// TODO: reconsider if this unwinding is needed
//try { new((QSE::Mmgr*)QSE_NULL, &srcbuf[index]) T((T&&)tmp[index]); }
//catch (...) {}
this->_positioner (tmp[index], INVALID_INDEX);
tmp[index].T::~T ();
}
//::operator delete (tmp, this->getMmgr());
this->getMmgr()->dispose (tmp);
throw;
}
return tmp;
}
#endif
void put_item (qse_size_t index, const T& value)
{
if (index >= this->count)
{
// no value exists in the given position.
// i can copy-construct the value.
new((QSE::Mmgr*)QSE_NULL, &this->buffer[index]) T(value);
this->_positioner (this->buffer[index], index);
}
else
{
// there is an old value in the position. do classic-assignment
this->buffer[index] = value;
this->_positioner (this->buffer[index], index);
}
}
#if defined(QSE_CPP_ENABLE_CPP11_MOVE)
void put_item_by_moving (qse_size_t index, T&& value)
{
if (index >= this->count)
{
// no value exists in the given position.
// i can move-construct the value.
new((QSE::Mmgr*)QSE_NULL, &this->buffer[index]) T(QSE_CPP_RVREF(value));
this->_positioner (this->buffer[index], index);
}
else
{
// there is an old value in the position. do move-assignment.
this->buffer[index] = QSE_CPP_RVREF(value);
this->_positioner (this->buffer[index], index);
}
}
#endif
void clear_all_items ()
{
QSE_ASSERT (this->count <= 0 || (this->count >= 1 && this->buffer));
for (qse_size_t i = this->count; i > 0; )
{
--i;
this->_positioner (this->buffer[i], INVALID_INDEX);
this->buffer[i].T::~T ();
}
this->count = 0;
}
public:
bool isEmpty () const QSE_CPP_NOEXCEPT
{
return this->count == 0;
}
qse_size_t getSize () const QSE_CPP_NOEXCEPT
{
return this->count;
}
qse_size_t getCapacity () const QSE_CPP_NOEXCEPT
{
return this->capacity;
}
operator T* () QSE_CPP_NOEXCEPT
{
return this->buffer;
}
operator const T* () const QSE_CPP_NOEXCEPT
{
return this->buffer;
}
T* getBuffer () QSE_CPP_NOEXCEPT
{
return this->buffer;
}
const T* getBuffer () const QSE_CPP_NOEXCEPT
{
return this->buffer;
}
/// The getIndex() function returns the index of the given value \a v
/// if it belongs to the array. It returns #INVALID_INDEX if not.
/// Note that this is not a search function.
///
/// \code
/// QSE::Array<int> a;
/// a.insert (0, 10);
/// a.insert (0, 20);
/// a.insert (0, 30);
/// const int& t = a[2];
/// printf ("%lu\n", (unsigned long int)a.getIndex(t)); // print 2
/// \endcode
qse_size_t getIndex (const T& v) const QSE_CPP_NOEXCEPT
{
if (&v >= &this->buffer[0] && &v < &this->buffer[this->count])
{
return &v - &this->buffer[0];
}
return INVALID_INDEX;
}
T& operator[] (qse_size_t index) QSE_CPP_NOEXCEPT
{
QSE_ASSERT (index < this->count);
return this->buffer[index];
}
const T& operator[] (qse_size_t index) const QSE_CPP_NOEXCEPT
{
QSE_ASSERT (index < this->count);
return this->buffer[index];
}
T& getValueAt (qse_size_t index) QSE_CPP_NOEXCEPT
{
QSE_ASSERT (index < this->count);
return this->buffer[index];
}
const T& getValueAt (qse_size_t index) const QSE_CPP_NOEXCEPT
{
QSE_ASSERT (index < this->count);
return this->buffer[index];
}
void setValueAt (qse_size_t index, const T& value)
{
this->update (index, value);
}
#if defined(QSE_CPP_ENABLE_CPP11_MOVE)
void setValueAt (qse_size_t index, T&& value)
{
this->update (index, QSE_CPP_RVREF(value));
}
#endif
const T& getFirst () const QSE_CPP_NOEXCEPT
{
return this->getValueAt(0);
}
const T& getLast () const QSE_CPP_NOEXCEPT
{
return this->getValueAt(this->getSize() - 1);
}
protected:
void secure_slot (qse_size_t index)
{
if (index >= this->capacity)
{
// the position to add the element is beyond the
// capacity. resize the buffer.
qse_size_t new_capa = this->_resizer (this->capacity, this->getGrowthPolicy());
if (index < new_capa)
this->setCapacity (new_capa);
else
this->setCapacity (index + 1);
}
else if (this->count >= this->capacity)
{
// the array is already full.
// insertion requires at least one more slot
qse_size_t new_capa = this->_resizer (this->capacity, this->getGrowthPolicy());
this->setCapacity (new_capa);
}
if (index < this->count)
{
// shift the existing elements to the back by one slot.
for (qse_size_t i = this->count; i > index; i--)
{
#if defined(QSE_CPP_ENABLE_CPP11_MOVE)
this->put_item_by_moving (i, QSE_CPP_RVREF(this->buffer[i - 1]));
#else
this->put_item (i, this->buffer[i - 1]);
#endif
}
}
else if (index > this->count)
{
// the insertion position leaves some gaps in between.
// fill the gap with a default value.
for (qse_size_t i = this->count; i < index; i++)
{
new((QSE::Mmgr*)QSE_NULL, &this->buffer[i]) T();
this->_positioner (this->buffer[i], i);
}
}
}
public:
qse_size_t insert (qse_size_t index, const T& value)
{
// Unlike insert() in RedBlackTree and HashList,
// it inserts an item when index exists in the existing array.
// It is because array allows duplicate items.
// RedBlckTree::insert() and HashList::insert() return failure
// if existing item exists.
this->secure_slot (index);
//this->buffer[index] = value;
this->put_item (index, value);
if (index > this->count) this->count = index + 1;
else this->count++;
return index;
}
#if defined(QSE_CPP_ENABLE_CPP11_MOVE)
qse_size_t insert (qse_size_t index, T&& value)
{
// Unlike insert() in RedBlackTree and HashList,
// it inserts an item when index exists in the existing array.
// It is because array allows duplicate items.
// RedBlckTree::insert() and HashList::insert() return failure
// if existing item exists.
this->secure_slot (index);
//this->buffer[index] = value;
this->put_item_by_moving (index, QSE_CPP_RVREF(value));
if (index > this->count) this->count = index + 1;
else this->count++;
return index;
}
#endif
qse_size_t update (qse_size_t index, const T& value)
{
QSE_ASSERT (index < this->count);
this->buffer[index] = value;
this->_positioner (this->buffer[index], index);
return index;
}
#if defined(QSE_CPP_ENABLE_CPP11_MOVE)
qse_size_t update (qse_size_t index, T&& value)
{
QSE_ASSERT (index < this->count);
this->buffer[index] = QSE_CPP_RVREF(value);
this->_positioner (this->buffer[index], index);
return index;
}
#endif
qse_size_t upsert (qse_size_t index, const T& value)
{
if (index < this->count)
return this->update(index, value);
else
return this->insert(index, value);
}
#if defined(QSE_CPP_ENABLE_CPP11_MOVE)
qse_size_t upsert (qse_size_t index, T&& value)
{
if (index < this->count)
return this->update(index, QSE_CPP_RVREF(value));
else
return this->insert(index, QSE_CPP_RVREF(value));
}
#endif
qse_size_t ensert (qse_size_t index, const T& value)
{
if (index < this->count)
return index; // no update
else
return this->insert(index, value);
}
#if defined(QSE_CPP_ENABLE_CPP11_MOVE)
qse_size_t ensert (qse_size_t index, T&& value)
{
if (index < this->count)
return index; // no update
else
return this->insert(index, QSE_CPP_RVREF(value));
}
#endif
qse_size_t insertFirst (const T& value)
{
return this->insert(0, value);
}
#if defined(QSE_CPP_ENABLE_CPP11_MOVE)
qse_size_t insertFirst (T&& value)
{
return this->insert(0, QSE_CPP_RVREF(value));
}
#endif
qse_size_t insertLast (const T& value)
{
return this->insert(this->getSize(), value);
}
#if defined(QSE_CPP_ENABLE_CPP11_MOVE)
qse_size_t insertLast (T&& value)
{
return this->insert(this->getSize(), QSE_CPP_RVREF(value));
}
#endif
void remove (qse_size_t index)
{
this->remove (index, 1);
}
void remove (qse_size_t from_index, qse_size_t size)
{
if (size <= 0 || this->count <= 0 || from_index >= this->count) return;
qse_size_t to_index = from_index + size - 1;
if (to_index >= this->count) to_index = this->count - 1;
qse_size_t j = from_index;
qse_size_t i = to_index + 1;
// replace deleted elements by surviving elements at the back
while (i < this->count)
{
// which is better?
// 1. destruct followed by copy construct
// 2. operator assignment.
// 1. destruct followed by copy construct
//this->_positioner (this->buffer[j], INVALID_INDEX);
//this->buffer[j].T::~T();
//new((QSE::Mmgr*)QSE_NULL, &this->buffer[j]) T(this->buffer[i]);
//this->_positioner (this->buffer[j], j);
// 2. operator assignment
this->buffer[j] = QSE_CPP_RVREF(this->buffer[i]);
this->_positioner (this->buffer[j], j);
j++; i++;
}
// call the destructor of deleted elements.
while (j < this->count)
{
this->_positioner (this->buffer[j], INVALID_INDEX);
this->buffer[j].T::~T ();
j++;
}
// recalculate the number of elements
this->count -= to_index - from_index + 1;
}
void removeFirst ()
{
this->remove(0);
}
void removeLast ()
{
this->remove(this->getSize() - 1);
}
public:
void clear (bool purge_buffer = false)
{
this->clear_all_items ();
if (purge_buffer && this->buffer)
{
QSE_ASSERT (this->count <= 0);
QSE_ASSERT (this->capacity > 0);
//::operator delete (this->buffer, this->getMmgr());
this->getMmgr()->dispose (this->buffer);
this->buffer = QSE_NULL;
this->capacity = 0;
}
}
void setSize (qse_size_t size)
{
if (size < this->count)
{
for (qse_size_t i = size; i < this->count; ++i)
{
// call the destructor of the items
this->_positioner (this->buffer[i], INVALID_INDEX);
this->buffer[i].T::~T ();
}
this->count = size;
}
else if (size > this->count)
{
if (size > this->capacity) this->setCapacity (size);
for (qse_size_t i = this->count; i < size; ++i)
{
// use the default contructor to set the value.
new((QSE::Mmgr*)QSE_NULL, &this->buffer[i]) T();
this->_positioner (this->buffer[i], i);
}
this->count = size;
}
}
void setCapacity (qse_size_t capa)
{
if (capa == this->capacity) return;
if (capa <= 0)
{
this->clear (true);
}
else if (this->buffer)
{
QSE_ASSERT (this->capacity > 0);
qse_size_t cnt = this->count;
if (cnt > capa) cnt = capa;
#if defined(QSE_CPP_ENABLE_CPP11_MOVE)
T* tmp = this->clone_buffer_by_moving (this->buffer, capa, cnt);
#else
T* tmp = this->clone_buffer (this->buffer, capa, cnt);
#endif
this->clear (true);
this->buffer = tmp;
this->capacity = capa;
this->count = cnt;
}
else
{
QSE_ASSERT (this->capacity <= 0);
QSE_ASSERT (this->count <= 0);
//this->buffer = (T*)::operator new (capa * QSE_SIZEOF(*this->buffer), this->getMmgr());
this->buffer = (T*)this->getMmgr()->allocate(capa * QSE_SIZEOF(*this->buffer));
this->capacity = capa;
}
}
/// The compact() function removes the unused space in the buffer.
void compact ()
{
this->setCapacity (this->size);
}
enum RotateDirection
{
ROTATE_LEFT,
ROTATE_RIGHT
};
void rotate (RotateDirection dir, qse_size_t n)
{
qse_size_t first, last, cnt, index, nk;
T c;
if ((n %= this->count) == 0) return;
if (dir == ROTATE_RIGHT) n = this->count - n;
first = 0; nk = this->count - n; cnt = 0;
while (cnt < n)
{
last = first + nk;
index = first;
c = QSE_CPP_RVREF(this->buffer[index]);
while (1)
{
cnt++;
while (index < nk)
{
this->buffer[index] = QSE_CPP_RVREF(this->buffer[index + n]);
this->_positioner (this->buffer[index], index);
index += n;
}
if (index == last) break;
this->buffer[index] = QSE_CPP_RVREF(this->buffer[index - nk]);
this->_positioner (this->buffer[index], index);
index -= nk;
}
this->buffer[last] = QSE_CPP_RVREF(c);
this->_positioner (this->buffer[last], last);
first++;
}
}
protected:
POSITIONER _positioner;
RESIZER _resizer;
qse_size_t count;
qse_size_t capacity;
T* buffer;
};
// euqal-to comparator
template <typename T>
struct SearchableArrayEqtester
{
// this can be used to build a max heap
bool operator() (const T& v1, const T& v2) const
{
return v1 == v2;
}
};
template <typename T, typename EQTESTER = SearchableArrayEqtester<T>, typename POSITIONER = ArrayPositioner<T>, typename RESIZER = ArrayResizer>
class SearchableArray: public Array<T, POSITIONER, RESIZER>
{
public:
typedef SearchableArray<T,EQTESTER,POSITIONER,RESIZER> SelfType;
typedef Array<T,POSITIONER,RESIZER> ParentType;
enum
{
DEFAULT_CAPACITY = ParentType::DEFAULT_CAPACITY,
INVALID_INDEX = ParentType::INVALID_INDEX
};
SearchableArray (Mmgr* mmgr = QSE_NULL): ParentType(mmgr) {}
SearchableArray (qse_size_t capacity, Mmgr* mmgr = QSE_NULL): ParentType(capacity, mmgr) {}
SearchableArray (const SelfType& heap): ParentType(heap) {}
#if defined(QSE_CPP_ENABLE_CPP11_MOVE)
SearchableArray (SelfType&& heap): ParentType(QSE_CPP_RVREF(heap)) {}
#endif
~SearchableArray () { }
/// \return the number of items deleted.
int removeByValue (const T& value)
{
qse_size_t index = this->findFirstIndex (value);
if (index == INVALID_INDEX) return 0;
this->remove (index);
return 1;
}
qse_size_t removeAllByValue (const T& value)
{
qse_size_t cnt = 0;
while (this->removeByValue(value) > 0) cnt++;
return cnt;
}
qse_size_t findFirstIndex (const T& value) const
{
for (qse_size_t i = 0; i < this->count; i++)
{
if (this->_eqtester(this->buffer[i], value)) return i;
}
return INVALID_INDEX;
}
qse_size_t findFirstIndex (const T& value, qse_size_t index) const
{
for (qse_size_t i = index; i < this->count; i++)
{
if (this->_eqtester(this->buffer[i], value)) return i;
}
return INVALID_INDEX;
}
qse_size_t findLastIndex (const T& value) const
{
for (qse_size_t i = this->count; i > 0; )
{
if (this->_eqtester(this->buffer[--i], value)) return i;
}
return INVALID_INDEX;
}
qse_size_t findLastIndex (const T& value, qse_size_t index) const
{
for (qse_size_t i = index + 1; i > 0; )
{
if (this->_eqtester(this->buffer[--i], value)) return i;
}
return INVALID_INDEX;
}
protected:
EQTESTER _eqtester;
};
/////////////////////////////////
QSE_END_NAMESPACE(QSE)
/////////////////////////////////
#endif

View File

@@ -0,0 +1,61 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_ASSOCIATION_HPP_
#define _QSE_CMN_ASSOCIATION_HPP_
#include <qse/Types.hpp>
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
template <typename K, typename V>
class Association
{
public:
K key;
V value;
Association () {}
Association (const K& key): key (key) {}
Association (const K& key, const V& value): key (key), value (value) {}
K& getKey () { return this->key; }
const K& getKey () const { return this->key; }
V& getValue () { return this->value; }
const V& getValue () const { return this->value; }
void setKey (const K& key) { this->key = key; }
void setValue (const V& value) { this->value = value; }
};
/////////////////////////////////
QSE_END_NAMESPACE(QSE)
/////////////////////////////////
#endif

View File

@@ -0,0 +1,346 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_BINARYHEAP_HPP_
#define _QSE_CMN_BINARYHEAP_HPP_
/// \file
/// Provides a binary heap implementation.
///
/// \includelineno bh01.cpp
///
#include <qse/cmn/Array.hpp>
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
// greater-than comparator
template <typename T>
struct BinaryHeapComparator
{
// this can be used to build a max heap
bool operator() (const T& v1, const T& v2) const
{
return v1 > v2;
}
};
template <typename T>
struct BinaryHeapPositioner
{
void operator() (T& v, qse_size_t index) const
{
// do nothing
}
};
typedef ArrayResizer BinaryHeapResizer;
#define QSE_BINARY_HEAP_UP(x) (((x) - 1) / 2)
#define QSE_BINARY_HEAP_LEFT(x) ((x) * 2 + 1)
#define QSE_BINARY_HEAP_RIGHT(x) ((x) * 2 + 2)
///
/// The BinaryHeap class is a template class that implements a binary heap.
///
/// \code
/// #include <qse/cmn/BinaryHeap.hpp>
/// #include <stdio.h>
///
/// struct IntComparator
/// {
/// bool operator() (int v1, int v2) const
/// {
/// //return !(v1 > v2);
/// return v1 > v2;
/// }
/// };
///
/// int main (int argc, char* argv[])
/// {
/// QSE::BinaryHeap<int,IntComparator> heap;
///
/// heap.insert (70);
/// heap.insert (90);
/// heap.insert (10);
/// heap.insert (5);
/// heap.insert (88);
/// heap.insert (87);
/// heap.insert (300);
/// heap.insert (91);
/// heap.insert (100);
/// heap.insert (200);
///
/// while (heap.getSize() > 0)
/// {
/// printf ("%d\n", heap.getValueAt(0));
/// heap.remove (0);
/// }
///
/// return 0;
/// }
/// \endcode
///
template <typename T, typename COMPARATOR = BinaryHeapComparator<T>, typename POSITIONER = BinaryHeapPositioner<T>, typename RESIZER = BinaryHeapResizer >
class BinaryHeap: protected Array<T,POSITIONER,RESIZER>
{
public:
typedef BinaryHeap<T,COMPARATOR,POSITIONER,RESIZER> SelfType;
typedef Array<T,POSITIONER,RESIZER> ParentType;
typedef BinaryHeapComparator<T> DefaultComparator;
typedef BinaryHeapPositioner<T> DefaultPositioner;
typedef BinaryHeapResizer DefaultResizer;
enum
{
DEFAULT_CAPACITY = ParentType::DEFAULT_CAPACITY,
INVALID_INDEX = ParentType::INVALID_INDEX
};
BinaryHeap (Mmgr* mmgr = QSE_NULL): ParentType(DEFAULT_CAPACITY, mmgr) {}
BinaryHeap (qse_size_t capacity, Mmgr* mmgr = QSE_NULL): ParentType(capacity, mmgr) {}
BinaryHeap (const SelfType& heap): ParentType(heap) {}
#if defined(QSE_CPP_ENABLE_CPP11_MOVE)
BinaryHeap (SelfType&& heap): ParentType(QSE_CPP_RVREF(heap)) {}
#endif
~BinaryHeap () {}
SelfType& operator= (const SelfType& heap)
{
if (this != &heap)
{
ParentType::operator= (heap);
}
return *this;
}
#if defined(QSE_CPP_ENABLE_CPP11_MOVE)
SelfType& operator= (SelfType&& heap)
{
if (this != &heap)
{
ParentType::operator= (QSE_CPP_RVREF(heap));
}
return *this;
}
#endif
/// The isEmpty() function returns true if the binary heap contains no
/// item and false otherwise.
bool isEmpty() const QSE_CPP_NOEXCEPT{ return ParentType::isEmpty(); }
/// The getSize() function returns the number of items in the binary heap.
qse_size_t getSize() const QSE_CPP_NOEXCEPT{ return ParentType::getSize(); }
/// The getCapacity() function returns the capacity of the internal buffer
/// of the binary heap.
qse_size_t getCapacity() const QSE_CPP_NOEXCEPT { return ParentType::getCapacity(); }
/// The getIndex() function returns the index of an item reference \a v.
qse_size_t getIndex (const T& v) const { return ParentType::getIndex(v); }
/// The setCapacity() function resizes the capacity of the internal buffer.
/// If the given capacity is smaller than the current size, it skips resizing.
void setCapacity (qse_size_t capa) { if (capa > ParentType::getSize()) ParentType::setCapacity (capa); }
/// The clear() function returns all items.
void clear (bool purge_buffer = false) { ParentType::clear (purge_buffer); }
/// The compact() function restructures the internal buffer to the size
/// that is just large enough to hold the existing items.
void compact() { ParentType::compact (); }
/// The operator[] function returns the constant reference to the item
/// at the specified \a index.
const T& operator[] (qse_size_t index) const QSE_CPP_NOEXCEPT
{
return ParentType::getValueAt (index);
}
/// The getValueAt() function returns the constant reference to the item
/// at the specified \a index.
const T& getValueAt (qse_size_t index) const QSE_CPP_NOEXCEPT
{
return ParentType::getValueAt (index);
}
/// The insert() function adds a new item \a value to the binary heap.
qse_size_t insert (const T& value)
{
qse_size_t index = this->count;
// add the item at the back of the array
ParentType::insert (index, value);
// move the item up to the top if it's greater than the up item
return this->sift_up(index);
}
#if defined(QSE_CPP_ENABLE_CPP11_MOVE)
qse_size_t insert (T&& value)
{
qse_size_t index = this->count;
// add the item at the back of the array
ParentType::insert (index, QSE_CPP_RVREF(value));
// move the item up to the top if it's greater than the up item
return this->sift_up(index);
}
#endif
/// The update() function changes the item at the specified \a index
/// to a new item \a value.
qse_size_t update (qse_size_t index, const T& value)
{
T old = this->buffer[index];
ParentType::update (index, value);
return (this->greater_than(value, old))? this->sift_up(index): this->sift_down(index);
}
#if defined(QSE_CPP_ENABLE_CPP11_MOVE)
qse_size_t update (qse_size_t index, T&& value)
{
T old = QSE_CPP_RVREF(this->buffer[index]);
ParentType::update (index, QSE_CPP_RVREF(value));
return (this->greater_than(value, old))? this->sift_up(index): this->sift_down(index);
}
#endif
/// The remove() function removes an item at the specified \a index.
void remove (qse_size_t index)
{
QSE_ASSERT (index < this->count);
if (this->count == 1)
{
ParentType::remove (this->count - 1);
}
else if (this->count > 1)
{
// store the item to remove temporarily
T old = QSE_CPP_RVREF(this->buffer[index]);
// copy the last item to the position to remove
ParentType::update (index, QSE_CPP_RVREF(this->buffer[this->count - 1]));
// decrement the count as if the last item has been deleted.
this->count = this->count - 1;
// relocate the item
(this->greater_than(this->buffer[index], old))? this->sift_up(index): this->sift_down(index);
// call the positioner on the actual item removed
this->_positioner (old, INVALID_INDEX);
}
}
protected:
qse_size_t sift_up (qse_size_t index)
{
qse_size_t up;
up = QSE_BINARY_HEAP_UP(index);
if (index > 0 && this->greater_than(this->buffer[index], this->buffer[up]))
{
T item = QSE_CPP_RVREF(this->buffer[index]);
do
{
ParentType::setValueAt (index, QSE_CPP_RVREF(this->buffer[up]));
index = up;
up = QSE_BINARY_HEAP_UP(up);
}
while (index > 0 && this->greater_than(item, this->buffer[up]));
ParentType::setValueAt (index, QSE_CPP_RVREF(item));
}
return index;
}
qse_size_t sift_down (qse_size_t index)
{
qse_size_t half_data_count = this->count / 2;
if (index < half_data_count)
{
// if at least 1 child is under the 'index' position
// perform sifting
T item = QSE_CPP_RVREF(this->buffer[index]);
do
{
qse_size_t left, right, greater;
left = QSE_BINARY_HEAP_LEFT(index);
right = QSE_BINARY_HEAP_RIGHT(index);
// choose the larger one between 2 BinaryHeap
if (right < this->count &&
this->greater_than(this->buffer[right], this->buffer[left]))
{
// if the right child exists and
// the right item is greater than the left item
greater = right;
}
else
{
greater = left;
}
if (this->greater_than(item, this->buffer[greater])) break;
ParentType::setValueAt (index, QSE_CPP_RVREF(this->buffer[greater]));
index = greater;
}
while (index < half_data_count);
ParentType::setValueAt (index, QSE_CPP_RVREF(item));
}
return index;
}
protected:
COMPARATOR greater_than;
};
/////////////////////////////////
QSE_END_NAMESPACE(QSE)
/////////////////////////////////
#endif

132
include/qse/cmn/Bitset.hpp Normal file
View File

@@ -0,0 +1,132 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_BITSET_HPP_
#define _QSE_CMN_BITSET_HPP_
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
template <int NB>
class Bitset
{
public:
typedef qse_size_t word_type_t;
static const int NW = (NB - 1) / (QSE_SIZEOF(word_type_t) * 8) + 1;
Bitset() { this->empty (); }
bool operator== (const Bitset<NB>& bs) const
{
// [NOTE]
// if you happen to have different garbage at the unused part
// of the last word, this equality check may return a wrong result.
for (int i = 0; i < NW; i++)
{
if (this->_w[i] != bs._w[i]) return false;
}
return true;
}
bool operator!= (const Bitset<NB>& bs) const
{
return !this->operator==(bs);
}
int get_word_index (int bit) const
{
return bit / (QSE_SIZEOF(word_type_t) * 8);
}
word_type_t get_word_mask (int bit) const
{
return ((word_type_t)1) << (bit % (QSE_SIZEOF(word_type_t) * 8));
}
void set (int bit)
{
this->_w[this->get_word_index(bit)] |= this->get_word_mask(bit);
}
void unset (int bit)
{
this->_w[this->get_word_index(bit)] &= ~this->get_word_mask(bit);
}
void set (const Bitset<NB>& bs)
{
// mask on all bits set in bs.
for (int i = 0; i < NW; i++)
{
this->_w[i] |= bs._w[i];
}
}
void unset (const Bitset<NB>& bs)
{
// mask off all bits set in bs.
for (int i = 0; i < NW; i++)
{
this->_w[i] &= ~bs._w[i];
}
}
bool isSet (int bit) const
{
return (this->_w[this->get_word_index(bit)] & this->get_word_mask(bit));
}
bool isEmpty () const
{
for (int i = 0; i < NW; i++)
{
if (this->_w[i]) return false;
}
return true;
}
void empty ()
{
for (int i = 0; i < NW; i++) this->_w[i] = 0;
}
void fill ()
{
for (int i = 0; i < NW; i++) this->_w[i] = ~(word_type_t)0;
}
protected:
word_type_t _w[NW];
};
/////////////////////////////////
QSE_END_NAMESPACE(QSE)
/////////////////////////////////
#endif

View File

@@ -0,0 +1,105 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_ERRORGRAB_CLASS_
#define _QSE_CMN_ERRORGRAB_CLASS_
#include <stdarg.h>
#include <qse/Types.hpp>
#include <qse/cmn/str.h>
QSE_BEGIN_NAMESPACE(QSE)
template <typename ERRNUM, typename ERRNUMTOSTR, int MSGSZ>
class QSE_EXPORT ErrorGrab
{
public:
ErrorGrab(): _errnum((ERRNUM)0)
{
this->_errmsg[0] = QSE_T('\0');
this->_errmsg_backup[0] = QSE_T('\0');
}
ERRNUM getErrorNumber () const QSE_CPP_NOEXCEPT { return this->_errnum; }
const qse_char_t* getErrorMsg () const QSE_CPP_NOEXCEPT { return this->_errmsg; }
const qse_char_t* backupErrorMsg () QSE_CPP_NOEXCEPT
{
qse_strcpy (this->_errmsg_backup, this->_errmsg);
return this->_errmsg_backup;
}
void setErrorFmtv (ERRNUM errnum, const qse_char_t* fmt, va_list ap) QSE_CPP_NOEXCEPT
{
this->_errnum = errnum;
qse_strxvfmt (this->_errmsg, QSE_COUNTOF(this->_errmsg), fmt, ap);
}
void setErrorFmt (ERRNUM errnum, const qse_char_t* fmt, ...) QSE_CPP_NOEXCEPT
{
va_list ap;
va_start (ap, fmt);
this->setErrorFmtv (errnum, fmt, ap);
va_end (ap);
}
void setErrorNumber (ERRNUM errnum)
{
this->_errnum = errnum;
qse_strxcpy (this->_errmsg, QSE_COUNTOF(this->_errmsg), this->_errtostr(errnum));
}
private:
ERRNUM _errnum;
ERRNUMTOSTR _errtostr;
qse_char_t _errmsg_backup[MSGSZ];
qse_char_t _errmsg[MSGSZ];
};
// the stock functor class to convert the Types::ErrorNumber to a string
struct TypesErrorNumberToWcstr
{
const qse_wchar_t* operator() (Types::ErrorNumber errnum);
};
struct TypesErrorNumberToMbstr
{
const qse_mchar_t* operator() (Types::ErrorNumber errnum);
};
#if defined(QSE_CHAR_IS_MCHAR)
typedef TypesErrorNumberToMbstr TypesErrorNumberToStr;
#else
typedef TypesErrorNumberToWcstr TypesErrorNumberToStr;
#endif
typedef ErrorGrab<Types::ErrorNumber, TypesErrorNumberToStr, 64> ErrorGrab64;
typedef ErrorGrab<Types::ErrorNumber, TypesErrorNumberToStr, 128> ErrorGrab128;
typedef ErrorGrab<Types::ErrorNumber, TypesErrorNumberToStr, 256> ErrorGrab256;
QSE_END_NAMESPACE(QSE)
#endif

View File

@@ -0,0 +1,771 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_HASHLIST_HPP_
#define _QSE_CMN_HASHLIST_HPP_
/// \file
/// Provides a hash list template class.
#include <qse/Hashable.hpp>
#include <qse/Growable.hpp>
#include <qse/cmn/LinkedList.hpp>
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
template<typename T>
struct HashListHasher
{
qse_size_t operator() (const T& v) const
{
return v.getHashCode();
}
};
template<typename T>
struct HashListEqualer
{
bool operator() (const T& v1, const T& v2) const
{
return v1 == v2;
}
};
struct HashListResizer
{
qse_size_t operator() (qse_size_t current, const GrowthPolicy* gp) const
{
if (current <= 0) current = 1;
if (gp)
{
return gp->getNewSize (current);
}
else
{
return (current < 5000)? (current + current):
(current < 50000)? (current + (current / 2)):
(current < 100000)? (current + (current / 4)):
(current < 150000)? (current + (current / 8)):
(current + (current / 16));
}
}
};
/// The HashList class provides a linked list where a data item can be accessed
/// using hashing. The accessor functions are similar to those of the HashTable
/// class whereas the data items are linked with each other in a linked list.
/// Extra hashing buckets maintain pointers to the first and the last node of
/// data items whose hash values are equal. Unlike the HashTable class that
/// maintains pairs of a key and a value, it stores a series of single items
/// whose key is distinuguished via the hashing function.
///
/// For the capacicity of X, it allocates (X * 2) node slots(this->nodes).
/// For a hash value of hc, this->nodes[hc * 2] points to the first node and
/// this->nodes[hc * 2 + 1] ponits to the last node.
template <typename T, typename HASHER = HashListHasher<T>, typename EQUALER = HashListEqualer<T>, typename RESIZER = HashListResizer >
class HashList: public Mmged, public Growable
{
public:
typedef LinkedList<T,EQUALER> DatumList;
typedef typename DatumList::Node Node;
typedef typename DatumList::Iterator Iterator;
typedef typename DatumList::ConstIterator ConstIterator;
typedef HashList<T,HASHER,EQUALER,RESIZER> SelfType;
typedef HashListHasher<T> DefaultHasher;
typedef HashListEqualer<T> DefaultEqualer;
typedef HashListResizer DefaultResizer;
enum
{
DEFAULT_CAPACITY = 10,
DEFAULT_LOAD_FACTOR = 75, // Load factor in percentage
MIN_CAPACITY = 1,
MIN_LOAD_FACTOR = 20
};
private:
void init_list (qse_size_t node_capacity, qse_size_t load_factor, qse_size_t mpb_size)
{
if (node_capacity < MIN_CAPACITY) node_capacity = MIN_CAPACITY;
if (load_factor < MIN_LOAD_FACTOR) load_factor = MIN_LOAD_FACTOR;
this->nodes = QSE_NULL;
this->node_capacity = 0;
this->datum_list = QSE_NULL;
try
{
qse_size_t total_count = node_capacity << 1;
// Node* is a plain type that doesn't have any constructors and destructors.
// it should be safe to call the memory manager bypassing the new operator.
//this->nodes = new Node*[total_count];
this->nodes = (Node**)this->getMmgr()->allocate (QSE_SIZEOF(Node*) * total_count);
this->node_capacity = node_capacity;
for (qse_size_t i = 0; i < total_count; i++)
{
this->nodes[i] = QSE_NULL;
}
this->datum_list = new(this->getMmgr()) DatumList(mpb_size, this->getMmgr());
}
catch (...)
{
if (this->nodes)
{
this->getMmgr()->dispose (this->nodes); //delete[] this->nodes;
this->nodes = QSE_NULL;
this->node_capacity = 0;
}
if (this->datum_list)
{
this->free_datum_list ();
this->datum_list = QSE_NULL;
}
throw;
}
this->load_factor = load_factor;
this->threshold = node_capacity * load_factor / 100;
}
public:
HashList (
Mmgr* mmgr = QSE_NULL): Mmged(mmgr)
{
this->init_list (DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, 0);
}
HashList (qse_size_t node_capacity, qse_size_t load_factor = DEFAULT_LOAD_FACTOR, qse_size_t mpb_size = 0, Mmgr* mmgr = QSE_NULL): Mmged(mmgr)
{
this->init_list (DEFAULT_CAPACITY, load_factor, mpb_size);
}
HashList (const SelfType& list): Mmged(list)
{
this->nodes = QSE_NULL;
this->node_capacity = 0;
this->datum_list = QSE_NULL;
try
{
qse_size_t total_count = list.node_capacity << 1;
//this->nodes = new Node*[total_count];
this->nodes = (Node**)this->getMmgr()->allocate (QSE_SIZEOF(Node*) * total_count);
this->node_capacity = list.node_capacity;
for (qse_size_t i = 0; i < total_count; i++)
{
this->nodes[i] = QSE_NULL;
}
// placement new
this->datum_list = new(list.getMmgr()) DatumList(list.getMpool().getBlockSize(), list.getMmgr());
}
catch (...)
{
if (this->nodes)
{
this->getMmgr()->dispose (this->nodes); //delete[] this->nodes;
this->nodes = QSE_NULL;
this->node_capacity = 0;
}
if (this->datum_list)
{
this->free_datum_list ();
this->datum_list = QSE_NULL;
}
throw;
}
this->load_factor = list.load_factor;
this->threshold = list.threshold;
for (qse_size_t i = 0; i < list.node_capacity; i++)
{
qse_size_t head = i << 1;
qse_size_t tail = head + 1;
Node* np = list.nodes[head];
if (!np) continue;
do
{
this->copy_datum (np, this->node_capacity, this->nodes, this->datum_list);
if (np == list.nodes[tail]) break;
np = np->getNextNode ();
}
while (1);
}
}
~HashList ()
{
this->clear (true);
if (this->nodes) this->getMmgr()->dispose (this->nodes); //delete[] this->nodes;
if (this->datum_list) this->free_datum_list ();
}
SelfType& operator= (const SelfType& list)
{
if (this != &list)
{
this->clear (false);
// note that the memory pool itself is not copied.
for (qse_size_t i = 0; i < list.node_capacity; i++)
{
qse_size_t head = i << 1;
qse_size_t tail = head + 1;
Node* np = list.nodes[head];
if (np == QSE_NULL) continue;
do
{
this->copy_datum (np, this->node_capacity, this->nodes, this->datum_list);
if (np == list.nodes[tail]) break;
np = np->getNextNode ();
}
while (1);
}
}
return *this;
}
Mpool& getMpool ()
{
return this->datum_list->getMpool ();
}
const Mpool& getMpool() const
{
return this->datum_list->getMpool ();
}
qse_size_t getCapacity() const
{
return this->node_capacity;
}
qse_size_t getSize () const
{
return this->datum_list->getSize ();
}
bool isEmpty () const
{
return this->datum_list->isEmpty ();
}
Node* getHeadNode () { return this->datum_list->getHeadNode (); }
const Node* getHeadNode () const { return this->datum_list->getHeadNode (); }
Node* getFirstNode () { return this->datum_list->getHeadNode (); }
const Node* getFirstNode () const { return this->datum_list->getHeadNode (); }
Node* getTailNode () { return this->datum_list->getTailNode (); }
const Node* getTailNode () const { return this->datum_list->getTailNode (); }
Node* getLastNode () { return this->datum_list->getTailNode (); }
const Node* getLastNode () const { return this->datum_list->getTailNode (); }
protected:
Node* find_node (const T& datum) const
{
qse_size_t hc, head, tail;
Node* np;
hc = this->_hasher(datum) % this->node_capacity;
head = hc << 1; tail = head + 1;
np = this->nodes[head];
if (np)
{
do
{
T& t = np->value;
if (this->_equaler (datum, t)) return np;
if (np == this->nodes[tail]) break;
np = np->getNextNode ();
}
while (1);
}
return QSE_NULL;
}
template <typename MT, typename MEQUALER>
Node* heterofind_node (const MT& datum, qse_size_t hc) const
{
MEQUALER mequaler;
qse_size_t head, tail;
Node* np;
head = hc << 1; tail = head + 1;
np = this->nodes[head];
if (np)
{
do
{
T& t = np->value;
if (mequaler (datum, t)) return np;
if (np == this->nodes[tail]) break;
np = np->getNextNode ();
}
while (1);
}
return QSE_NULL;
}
public:
Node* findNode (const T& datum)
{
return this->find_node (datum);
}
const Node* findNode (const T& datum) const
{
return this->find_node (datum);
}
T* findValue (const T& datum)
{
Node* b = this->findNode (datum);
if (!b) return QSE_NULL;
return &b->value;
}
const T* findValue (const T& datum) const
{
const Node* b = this->findNode (datum);
if (!b) return QSE_NULL;
return &b->value;
}
template <typename MT, typename MHASHER, typename MEQUALER>
Node* heterofindNode (const MT& datum)
{
MHASHER hash;
return this->heterofind_node<MT,MEQUALER> (datum, hash(datum) % this->node_capacity);
}
template <typename MT, typename MHASHER, typename MEQUALER>
const Node* heterofindNode (const MT& datum) const
{
MHASHER hash;
return this->heterofind_node<MT,MEQUALER> (datum, hash(datum) % this->node_capacity);
}
template <typename MT, typename MHASHER, typename MEQUALER>
T* heterofindValue(const MT& datum)
{
MHASHER hash;
Node* b = this->heterofind_node<MT,MEQUALER> (datum, hash(datum) % this->node_capacity);
if (!b) return QSE_NULL;
return &b->value;
}
template <typename MT, typename MHASHER, typename MEQUALER>
const T* heterofindValue(const MT& datum) const
{
MHASHER hash;
Node* b = this->heterofind_node<MT,MEQUALER> (datum, hash(datum) % this->node_capacity);
if (!b) return QSE_NULL;
return &b->value;
}
/// The search() function returns the pointer to the existing node
/// containing the equal value to \a datum. If no node is found, it
/// return #QSE_NULL.
Node* search (const T& datum)
{
return this->find_node (datum);
}
/// The search() function returns the pointer to the existing node
/// containing the equal value to \a datum. If no node is found, it
/// return #QSE_NULL.
const Node* search (const T& datum) const
{
return this->find_node (datum);
}
template <typename MT, typename MHASHER, typename MEQUALER>
Node* heterosearch (const MT& datum)
{
MHASHER hash;
return this->heterofind_node<MT,MEQUALER> (datum, hash(datum) % this->node_capacity);
}
template <typename MT, typename MHASHER, typename MEQUALER>
const Node* heterosearch (const MT& datum) const
{
MHASHER hash;
return this->heterofind_node<MT,MEQUALER> (datum, hash(datum) % this->node_capacity);
}
Node* inject (const T& datum, int mode, bool* injected = QSE_NULL)
{
qse_size_t hc, head, tail;
Node* np;
hc = this->_hasher(datum) % this->node_capacity;
head = hc << 1; tail = head + 1;
np = this->nodes[head];
if (np)
{
do
{
T& t = np->value;
if (this->_equaler (datum, t))
{
if (injected) *injected = false;
if (mode <= -1) return QSE_NULL; // failure
if (mode >= 1) t = datum; // overwrite
return np;
}
if (np == this->nodes[tail]) break;
np = np->getNextNode ();
}
while (1);
}
if (datum_list->getSize() >= threshold)
{
this->rehash ();
hc = this->_hasher(datum) % this->node_capacity;
head = hc << 1; tail = head + 1;
}
if (nodes[head] == QSE_NULL)
{
this->nodes[head] = this->datum_list->insert ((Node*)QSE_NULL, datum);
this->nodes[tail] = this->nodes[head];
}
else
{
this->nodes[head] = this->datum_list->insert (this->nodes[head], datum);
}
if (injected) *injected = true;
return this->nodes[head];
}
Node* insert (const T& datum)
{
return this->inject(datum, -1, QSE_NULL);
}
Node* ensert (const T& datum)
{
return this->inject(datum, 0, QSE_NULL);
}
Node* upsert (const T& datum)
{
return this->inject(datum, 1, QSE_NULL);
}
Node* update (const T& datum)
{
Node* node = this->find_node(datum);
if (node) node->value = datum;
return node;
}
int remove (const T& datum)
{
qse_size_t hc, head, tail;
Node* np;
hc = this->_hasher(datum) % this->node_capacity;
head = hc << 1; tail = head + 1;
np = this->nodes[head];
if (np)
{
do
{
T& t = np->value;
if (this->_equaler (datum, t))
{
if (this->nodes[head] == this->nodes[tail])
{
QSE_ASSERT (np == this->nodes[head]);
this->nodes[head] = this->nodes[tail] = QSE_NULL;
}
else if (np == this->nodes[head])
{
this->nodes[head] = np->getNextNode();
}
else if (np == this->nodes[tail])
{
this->nodes[tail] = np->getPrevNode();
}
this->datum_list->remove (np);
return 0;
}
if (np == this->nodes[tail]) break;
np = np->getNextNode ();
}
while (1);
}
return -1;
}
template <typename MT, typename MHASHER, typename MEQUALER>
int heteroremove (const MT& datum)
{
MHASHER hash;
qse_size_t hc = hash(datum) % this->node_capacity;
Node* np = this->heterofind_node<MT,MEQUALER> (datum, hc);
if (np)
{
this->remove_node (np, hc);
return 0;
}
return -1;
}
void removeNode (Node* np)
{
T& datum = np->value;
qse_size_t hc = this->_hasher(datum) % this->node_capacity;
this->remove_node (np, hc);
}
private:
void remove_node (Node* np, qse_size_t hc)
{
qse_size_t head, tail;
head = hc << 1; tail = head + 1;
if (this->nodes[head] == this->nodes[tail])
{
QSE_ASSERT (np == this->nodes[head]);
this->nodes[head] = this->nodes[tail] = QSE_NULL;
}
else if (np == this->nodes[head])
{
this->nodes[head] = np->getNextNode();
}
else if (np == this->nodes[tail])
{
this->nodes[tail] = np->getPrevNode();
}
this->datum_list->remove (np);
}
public:
void clear (bool clear_mpool = false)
{
for (qse_size_t i = 0; i < (this->node_capacity << 1); i++)
{
this->nodes[i] = QSE_NULL;
}
this->datum_list->clear (clear_mpool);
}
///
/// The getIterator() function returns an iterator. You can use
/// the iterator to loop over items in the hash list.
///
/// \code{.cpp}
/// struct IntHasher
/// {
/// qse_size_t operator() (int v) { return v; }
/// };
/// typedef QSE::HashList<int,QSE::Mpool,IntHasher> IntList;
///
/// IntList hl;
/// IntList::Iterator it;
///
/// hl.insert (10);
/// hl.insert (150);
/// hl.insert (200);
/// for (it = hl.getIterator(); it.isLegit(); it++)
/// {
/// printf ("%d\n", *it);
/// }
/// \endcode
///
Iterator getIterator (qse_size_t index = 0)
{
return this->datum_list->getIterator (index);
}
/// The getConstIterator() function returns an iterator that emits the
/// constant reference to an item.
ConstIterator getConstIterator (qse_size_t index = 0) const
{
return this->datum_list->getConstIterator (index);
}
protected:
mutable qse_size_t node_capacity;
mutable Node** nodes;
mutable DatumList* datum_list;
mutable qse_size_t threshold;
qse_size_t load_factor;
HASHER _hasher;
EQUALER _equaler;
RESIZER _resizer;
void rehash ()
{
// Move nodes around instead of values to prevent
// existing values from being copied over and destroyed.
// this incurs less number of memory allocations also.
Mpool& mpool = this->getMpool();
// Using the memory pool block size of 0 is OK because the nodes
// to be inserted are yielded off the original list and inserted
// without new allocation.
//SelfType temp (this->getMmgr(), this->_resizer(this->node_capacity), this->load_factor, mpool.getBlockSize());
SelfType temp (this->_resizer(this->node_capacity, this->getGrowthPolicy()), this->load_factor, 0, this->getMmgr());
Node* p = this->datum_list->getHeadNode();
while (p)
{
Node* next = p->getNextNode();
// p->value must be a unique value in the existing hashed list.
// i can safely skip checking existing values.
// detach the existing node.
Node* pp = this->datum_list->yield (p, true);
// get the hash code using the new capacity
qse_size_t hc, head, tail;
hc = this->_hasher(pp->value) % temp.node_capacity;
head = hc << 1; tail = head + 1;
// insert the detached node to the new temporary list
if (temp.nodes[head])
{
temp.nodes[head] = temp.datum_list->insertNode (temp.nodes[head], pp);
}
else
{
temp.nodes[head] = temp.datum_list->insertNode ((Node*)QSE_NULL, pp);
temp.nodes[tail] = temp.nodes[head];
}
p = next;
}
// all nodes must have been popped out.
QSE_ASSERT (this->datum_list->getSize() <= 0);
// clear the node pointers by force as no nodes exist in the old list.
for (qse_size_t i = 0; i < (this->node_capacity << 1); i++)
{
this->nodes[i] = QSE_NULL;
}
// swapping the memory pool is a critical thing to do
// especially when the memory pooling is enabled. the datum node in
// 'temp' is actual allocated inside 'mpool' not inside temp.getMpool().
// it is because yield() has been used for insertion into 'temp'.
mpool.swap (temp.getMpool());
// swap the actual contents
qse_size_t temp_capa = temp.node_capacity;
Node** temp_nodes = temp.nodes;
DatumList* temp_datum_list = temp.datum_list;
qse_size_t temp_threshold = temp.threshold;
qse_size_t temp_load_factor = temp.load_factor;
temp.node_capacity = this->node_capacity;
temp.nodes = this->nodes;
temp.datum_list = this->datum_list;
temp.threshold = this->threshold;
temp.load_factor = this->load_factor;
this->node_capacity = temp_capa;
this->nodes = temp_nodes;
this->datum_list = temp_datum_list;
this->threshold = temp_threshold;
this->load_factor = temp_load_factor;
}
void copy_datum (
Node* np, qse_size_t new_node_capa,
Node** new_nodes, DatumList* new_datum_list) const
{
T& t = np->value;
qse_size_t hc = this->_hasher(t) % new_node_capa;
qse_size_t head = hc << 1;
qse_size_t tail = head + 1;
if (new_nodes[head] == QSE_NULL)
{
new_nodes[head] = new_datum_list->insert ((Node*)QSE_NULL, t);
new_nodes[tail] = new_nodes[head];
}
else
{
new_nodes[head] = new_datum_list->insert (new_nodes[head], t);
}
}
private:
void free_datum_list ()
{
// destruction in response to 'placement new'
QSE_CPP_CALL_DESTRUCTOR (this->datum_list, DatumList);
QSE_CPP_CALL_PLACEMENT_DELETE1 (this->datum_list, this->getMmgr());
}
};
/////////////////////////////////
QSE_END_NAMESPACE(QSE)
/////////////////////////////////
#endif

View File

@@ -0,0 +1,310 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_HASHTABLE_HPP_
#define _QSE_CMN_HASHTABLE_HPP_
/// \file
/// Provides a hash table template class.
#include <qse/cmn/Association.hpp>
#include <qse/cmn/HashList.hpp>
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
template<typename T>
struct HashTableHasher
{
qse_size_t operator() (const T& v) const
{
return v.getHashCode();
}
};
template<typename T>
struct HashTableEqualer
{
// it must return true if two values are equal
bool operator() (const T& v1, const T& v2) const
{
return v1 == v2;
}
};
typedef HashListResizer HashTableResizer;
template <typename K, typename V, typename HASHER = HashTableHasher<K>, typename EQUALER = HashTableEqualer<K>, typename RESIZER = HashTableResizer>
class HashTable: public Mmged
{
public:
typedef Association<K,V> Pair;
typedef HashTable<K,V,HASHER,EQUALER,RESIZER> SelfType;
typedef HashTableHasher<K> DefaultHasher;
typedef HashTableEqualer<K> DefaultEqualer;
typedef HashTableResizer DefaultResizer;
struct PairHasher
{
qse_size_t operator() (const Pair& p) const
{
HASHER hasher;
return hasher (p.key);
}
};
struct PairEqualer
{
qse_size_t operator() (const Pair& p1, const Pair& p2) const
{
EQUALER equaler;
return equaler (p1.key, p2.key);
}
};
struct PairHeteroEqualer
{
qse_size_t operator() (const K& p1, const Pair& p2) const
{
EQUALER equaler;
return equaler (p1, p2.key);
}
};
template <typename MK, typename MEQUALER>
struct MHeteroEqualer
{
qse_size_t operator() (const MK& p1, const Pair& p2) const
{
MEQUALER mequaler;
return mequaler (p1, p2.key);
}
};
typedef HashList<Pair,PairHasher,PairEqualer,RESIZER> PairList;
typedef typename PairList::Node PairNode;
typedef typename PairList::Iterator Iterator;
typedef typename PairList::ConstIterator ConstIterator;
enum
{
DEFAULT_CAPACITY = PairList::DEFAULT_CAPACITY,
DEFAULT_LOAD_FACTOR = PairList::DEFAULT_LOAD_FACTOR,
MIN_CAPACITY = PairList::MIN_CAPACITY,
MIN_LOAD_FACTOR = PairList::MIN_LOAD_FACTOR
};
HashTable (Mmgr* mmgr = QSE_NULL):
Mmged(mmgr), pair_list(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR, 0, mmgr)
{
}
HashTable (qse_size_t capacity,
qse_size_t load_factor = DEFAULT_LOAD_FACTOR,
qse_size_t mpb_size = 0,
Mmgr* mmgr = QSE_NULL):
Mmged(mmgr), pair_list(capacity, load_factor, mpb_size, mmgr)
{
}
HashTable (const SelfType& table): Mmged(table), pair_list(table.pair_list)
{
}
SelfType& operator= (const SelfType& table)
{
if (this != &table)
{
this->pair_list = table.pair_list;
}
return *this;
}
Mpool& getMpool ()
{
return this->pair_list.getMpool ();
}
const Mpool& getMpool () const
{
return this->pair_list.getMpool ();
}
qse_size_t getCapacity() const
{
return this->pair_list.getCapacity ();
}
qse_size_t getSize() const
{
return this->pair_list.getSize ();
}
bool isEmpty () const
{
return this->pair_list.isEmpty ();
}
PairNode* getHeadNode () { return this->pair_list.getHeadNode (); }
const PairNode* getHeadNode () const { return this->pair_list.getHeadNode (); }
PairNode* getFirstNode () { return this->pair_list.getHeadNode (); }
const PairNode* getFirstNode () const { return this->pair_list.getHeadNode (); }
PairNode* getTailNode () { return this->pair_list.getTailNode (); }
const PairNode* getTailNode () const { return this->pair_list.getTailNode (); }
PairNode* getLastNode () { return this->pair_list.getTailNode (); }
const PairNode* getLastNode () const { return this->pair_list.getTailNode (); }
Pair* inject (const K& key, const V& value, int mode, bool* injected = QSE_NULL)
{
PairNode* node = this->pair_list.inject (Pair(key, value), mode, injected);
if (!node) return QSE_NULL;
return &node->value;
}
Pair* insert (const K& key, const V& value)
{
PairNode* node = this->pair_list.insert (Pair(key, value));
if (!node) return QSE_NULL;
return &node->value;
}
Pair* ensert (const K& key, const V& value)
{
PairNode* node = this->pair_list.ensert (Pair(key, value));
if (!node) return QSE_NULL;
return &node->value;
}
Pair* upsert (const K& key, const V& value)
{
//PairNode* node = this->pair_list.upsert (Pair(key, value));
//if (!node) return QSE_NULL;
//return &node->value;
// Don't call pair_list.upsert() to make sure that the 'key' object
// itself remains identical after potential update operation.
// pair_list.upsert() changes the Pair object as a whole. so this
// trick is required.
bool injected;
PairNode* node = this->pair_list.inject (Pair(key, value), 0, &injected);
QSE_ASSERT (node != QSE_NULL);
Pair& pair = node->value;
if (injected) pair.value = value;
return &pair;
}
Pair* update (const K& key, const V& value)
{
//PairNode* node = this->pair_list.update (Pair(key, value));
//if (!node) return QSE_NULL;
//return &node->value;
PairNode* node = this->pair_list.QSE_CPP_TEMPLATE_QUALIFIER heterofindNode<K,HASHER,PairHeteroEqualer> (key);
if (!node) return QSE_NULL;
Pair& pair = node->value;
pair.value = value;
return &pair;
}
Pair* search (const K& key)
{
//PairNode* node = this->pair_list.search (Pair(key));
PairNode* node = this->pair_list.QSE_CPP_TEMPLATE_QUALIFIER heterofindNode<K,HASHER,PairHeteroEqualer> (key);
if (!node) return QSE_NULL;
return &node->value;
}
int remove (const K& key)
{
//return this->pair_list.remove (Pair(key));
return this->pair_list.QSE_CPP_TEMPLATE_QUALIFIER heteroremove<K,HASHER,PairHeteroEqualer> (key);
}
template <typename MK, typename MHASHER, typename MEQUALER>
Pair* heterosearch (const MK& key)
{
typedef MHeteroEqualer<MK,MEQUALER> MEqualer;
PairNode* node = this->pair_list.QSE_CPP_TEMPLATE_QUALIFIER heterosearch<MK,MHASHER,MEqualer> (key);
if (!node) return QSE_NULL;
return &node->value;
}
template <typename MK, typename MHASHER, typename MEQUALER>
const Pair* heterosearch (const MK& key) const
{
typedef MHeteroEqualer<MK,MEQUALER> MEqualer;
PairNode* node = this->pair_list.QSE_CPP_TEMPLATE_QUALIFIER heterosearch<MK,MHASHER,MEqualer> (key);
if (!node) return QSE_NULL;
return &node->value;
}
template <typename MK, typename MHASHER, typename MEQUALER>
int heteroremove (const MK& key)
{
typedef MHeteroEqualer<MK,MEQUALER> MEqualer;
return this->pair_list.QSE_CPP_TEMPLATE_QUALIFIER heteroremove<MK,MHASHER,MEqualer> (key);
}
void clear (bool clear_mpool = false)
{
return this->pair_list.clear (clear_mpool);
}
void removeNode (PairNode* node)
{
this->pair_list.removeNode (node);
}
PairNode* findNode (const K& key)
{
return this->pair_list.findNode (key);
}
Iterator getIterator (qse_size_t index = 0)
{
return this->pair_list.getIterator (index);
}
ConstIterator getConstIterator (qse_size_t index = 0) const
{
return this->pair_list.getConstIterator (index);
}
protected:
PairList pair_list;
};
/////////////////////////////////
QSE_END_NAMESPACE(QSE)
/////////////////////////////////
#endif

View File

@@ -0,0 +1,77 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_HEAPMMGR_HPP_
#define _QSE_CMN_HEAPMMGR_HPP_
#include <qse/cmn/Mmgr.hpp>
#include <qse/cmn/Mmged.hpp>
#include <qse/cmn/xma.h>
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
/// The HeapMmgr class implements a memory management interface that
/// handles a memory heap of a given size. Notably, it is a memory manager
/// managed by another memory manager.
///
/// \code
/// QSE::HeapMmgr heap_mmgr (30000, QSE::Mmgr::getDFL());
/// QSE::LinkedList<int> int_list (&heap_mmgr);
/// int_list.append (10);
/// int_list.append (20);
/// \endcode
class QSE_EXPORT HeapMmgr: public Mmgr, public Mmged
{
public:
/// The constructor function accepts an memory manager \a mmgr that
/// is used to create a heap of the size \a heap_size.
HeapMmgr (qse_size_t heap_size, Mmgr* mmgr = QSE_NULL) QSE_CPP_NOEXCEPT;
/// The destructor function frees the heap. Memory areas returned by
/// allocate(), reallocate(), allocMem(), reallocMem() are invalidated
/// all at once.
~HeapMmgr () QSE_CPP_NOEXCEPT;
void* allocMem (qse_size_t n) QSE_CPP_NOEXCEPT;
void* reallocMem (void* ptr, qse_size_t n) QSE_CPP_NOEXCEPT;
void freeMem (void* ptr) QSE_CPP_NOEXCEPT;
// the library does not provide a stock instance of this class
//static HeapMmgr* getInstance () QSE_CPP_NOEXCEPT;
protected:
qse_xma_t* xma;
qse_size_t heap_size;
};
/////////////////////////////////
QSE_END_NAMESPACE(QSE)
/////////////////////////////////
#endif

View File

@@ -0,0 +1,700 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_LINKEDLIST_HPP_
#define _QSE_CMN_LINKEDLIST_HPP_
#include <qse/Types.hpp>
#include <qse/cmn/Mpool.hpp>
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
template <typename T, typename EQUALER> class LinkedList;
template <typename T, typename EQUALER>
class LinkedListNode
{
public:
friend class LinkedList<T,EQUALER>;
typedef LinkedListNode<T,EQUALER> SelfType;
T value; // you can use this variable or accessor functions below
protected:
SelfType* prev;
SelfType* next;
public:
T& getValue () { return this->value; }
const T& getValue () const { return this->value; }
void setValue (const T& v) { this->value = v; }
SelfType* getNext () { return this->next; }
const SelfType* getNext () const { return this->next; }
SelfType* getNextNode () { return this->next; }
const SelfType* getNextNode () const { return this->next; }
SelfType* getPrev () { return this->prev; }
const SelfType* getPrev () const { return this->prev; }
SelfType* getPrevNode () { return this->prev; }
const SelfType* getPrevNode () const { return this->prev; }
protected:
LinkedListNode (): prev(QSE_NULL), next(QSE_NULL) {}
LinkedListNode (const T& v): value(v), prev(QSE_NULL), next(QSE_NULL) {}
void setNext (const SelfType* node)
{
this->next = node;
}
void setPrev (const SelfType* node)
{
this->prev = node;
}
};
template <typename T, typename EQUALER, typename NODE, typename GET_T>
class LinkedListIterator
{
public:
friend class LinkedList<T,EQUALER>;
//typedef LinkedListNode<T,EQUALER> Node;
typedef NODE Node;
typedef LinkedListIterator<T,EQUALER,NODE,GET_T> SelfType;
LinkedListIterator (): current(QSE_NULL) {}
LinkedListIterator (Node* node): current(node) {}
LinkedListIterator (const SelfType& it): current (it.current) {}
SelfType& operator= (const SelfType& it)
{
this->current = it.current;
return *this;
}
SelfType& operator++ () // prefix increment
{
QSE_ASSERT (this->current != QSE_NULL);
this->current = this->current->getNext();
return *this;
}
SelfType operator++ (int) // postfix increment
{
QSE_ASSERT (this->current != QSE_NULL);
SelfType saved (*this);
this->current = this->current->getNext(); //++(*this);
return saved;
}
SelfType& operator-- () // prefix decrement
{
QSE_ASSERT (this->current != QSE_NULL);
this->current = this->current->getPrev();
return *this;
}
SelfType operator-- (int) // postfix decrement
{
QSE_ASSERT (this->current != QSE_NULL);
SelfType saved (*this);
this->current = this->current->getPrev(); //--(*this);
return saved;
}
bool operator== (const SelfType& it) const
{
QSE_ASSERT (this->current != QSE_NULL);
return this->current == it.current;
}
bool operator!= (const SelfType& it) const
{
QSE_ASSERT (this->current != QSE_NULL);
return this->current != it.current;
}
bool isLegit () const
{
return this->current != QSE_NULL;
}
GET_T& operator* () // dereference
{
return this->current->getValue();
}
#if 0
T* operator-> ()
{
return &this->current->getValue();
}
#endif
GET_T& getValue ()
{
QSE_ASSERT (this->current != QSE_NULL);
return this->current->getValue();
}
void setValue (const T& v)
{
QSE_ASSERT (this->current != QSE_NULL);
this->current->setValue (v);
}
Node* getNode ()
{
return this->current;
}
protected:
Node* current;
};
template<typename T>
struct LinkedListEqualer
{
// it must return true if two values are equal
bool operator() (const T& v1, const T& v2) const
{
return v1 == v2;
}
};
///
/// The LinkedList<T,EQUALER> class provides a template for a doubly-linked list.
///
template <typename T, typename EQUALER = LinkedListEqualer<T> > class LinkedList: public Mmged
{
public:
typedef LinkedList<T,EQUALER> SelfType;
typedef LinkedListNode<T,EQUALER> Node;
typedef LinkedListIterator<T,EQUALER,Node,T> Iterator;
typedef LinkedListIterator<T,EQUALER,const Node,const T> ConstIterator;
typedef LinkedListEqualer<T> DefaultEqualer;
enum
{
INVALID_INDEX = ~(qse_size_t)0
};
~LinkedList ()
{
this->clear (true);
}
LinkedList (Mmgr* mmgr = QSE_NULL): Mmged(mmgr), mp(QSE_NULL, QSE_SIZEOF(Node), 0)
{
this->node_count = 0;
this->head_node = QSE_NULL;
this->tail_node = QSE_NULL;
}
LinkedList (qse_size_t mpb_size, Mmgr* mmgr = QSE_NULL): Mmged(mmgr), mp(mmgr, QSE_SIZEOF(Node), mpb_size)
{
this->node_count = 0;
this->head_node = QSE_NULL;
this->tail_node = QSE_NULL;
}
LinkedList (const SelfType& ll):
Mmged(ll.getMmgr()), mp (ll.getMmgr(), ll.mp.getDatumSize(), ll.mp.getBlockSize())
{
this->node_count = 0;
this->head_node = QSE_NULL;
this->tail_node = QSE_NULL;
for (Node* p = ll.head_node; p != QSE_NULL; p = p->next)
this->append (p->value);
}
SelfType& operator= (const SelfType& ll)
{
if (this != &ll)
{
this->clear ();
// note that the memory pool itself is not copied.
for (Node* p = ll.head_node; p != QSE_NULL; p = p->next)
this->append (p->value);
}
return *this;
}
#if 0
T& operator[] (qse_size_t index)
{
// same as getValueAt()
QSE_ASSERT (index < this->node_count);
Node* np = this->getNodeAt (index);
return np->value;
}
const T& operator[] (qse_size_t index) const
{
// same as getValueAt()
QSE_ASSERT (index < this->node_count);
Node* np = this->getNodeAt (index);
return np->value;
}
#endif
Mpool& getMpool ()
{
return this->mp;
}
const Mpool& getMpool () const
{
return this->mp;
}
qse_size_t getSize () const
{
return this->node_count;
}
bool isEmpty () const
{
return this->node_count <= 0;
}
/// The insertNode() function inserts an externally created \a node
/// before the node at the given position \a pos. If \a pos is QSE_NULL,
/// the \a node is inserted at the back of the list. You must take extra
/// care when using this function.
Node* insertNode (Node* pos, Node* node)
{
if (pos == QSE_NULL)
{
// add to the back
if (this->node_count == 0)
{
QSE_ASSERT (head_node == QSE_NULL);
QSE_ASSERT (tail_node == QSE_NULL);
this->head_node = this->tail_node = node;
}
else
{
node->prev = this->tail_node;
this->tail_node->next = node;
this->tail_node = node;
}
}
else
{
// insert 'node' before the node at the given position 'pos'.
node->next = pos;
node->prev = pos->prev;
if (pos->prev) pos->prev->next = node;
else this->head_node = node;
pos->prev = node;
}
this->node_count++;
return node;
}
/// The prependNode() function adds an externally created \a node
/// to the front of the list.
Node* prependNode (Node* node) { return this->insertNode (this->head_node, node); }
Node* insertFirstNode (Node* node) { return this->insertNode (this->head_node, node); }
/// The appendNode() function adds an externally created \a node
/// to the back of the list.
Node* appendNode (Node* node) { return this->insertNode (QSE_NULL, node); }
Node* insertLastNode (Node* node) { return this->insertNode (QSE_NULL, node); }
// create a new node to hold the value and insert it.
Node* insert (Node* pos, const T& value)
{
Node* node = new(&this->mp) Node(value);
return this->insertNode (pos, node);
}
Node* prepend (const T& value) { return this->insert (this->head_node, value); }
Node* insertFirst (const T& value) { return this->insert (this->head_node, value); }
Node* append (const T& value) { return this->insert ((Node*)QSE_NULL, value); }
Node* insertLast (const T& value) { return this->insert ((Node*)QSE_NULL, value); }
void prependAll (const SelfType& list)
{
Node* n = list.tail_node;
if (&list == this)
{
Node* head = list.head_node;
while (n)
{
this->prepend (n->value);
if (n == head) break;
n = (Node*)n->prev;
}
}
else
{
while (n)
{
this->prepend (n->value);
n = (Node*)n->prev;
}
}
}
void appendAll (const SelfType& list)
{
Node* n = list.head_node;
if (&list == this)
{
Node* tail = list.tail_node;
while (n)
{
this->append (n->value);
if (n == tail) break;
n = n->next;
}
}
else
{
while (n)
{
this->append (n->value);
n = n->next;
}
}
}
// remove a node from the list without freeing it.
// take extra care when using this method as the node
// can be freed through the memory pool when the list is
// destructed if the memory pool is enabled.
Node* yield (Node* node, bool clear_links = true)
{
QSE_ASSERT (node != QSE_NULL);
QSE_ASSERT (this->node_count > 0);
if (node->next)
node->next->prev = node->prev;
else
this->tail_node = node->prev;
if (node->prev)
node->prev->next = node->next;
else
this->head_node = node->next;
this->node_count--;
if (clear_links)
{
node->next = QSE_NULL;
node->prev = QSE_NULL;
}
return node;
}
// remove a node from the list and free it.
void remove (Node* node)
{
this->yield (node, false);
QSE_CPP_CALL_DESTRUCTOR (node, Node);
QSE_CPP_CALL_PLACEMENT_DELETE1 (node, &this->mp);
}
Node* yieldByValue (const T& value, bool clear_links = true)
{
Node* p = this->findFirstNode (value);
if (!p) return QSE_NULL;
return this->yield (p, clear_links);
}
/// \return the number of items deleted.
qse_size_t removeByValue (const T& value)
{
Node* p = this->findFirstNode (value);
if (!p) return 0;
this->remove (p);
return 1;
}
/// \return the number of items deleted
qse_size_t removeAllByValue (const T& value)
{
Node* p = this->findFirstNode (value);
if (!p) return 0;
qse_size_t cnt = 0;
do
{
Node* tmp = p->next;
this->remove (p);
cnt++;
p = this->findFirstNode (value, tmp);
}
while (p);
return cnt;
}
void removeHead () { this->remove (this->head_node); }
void removeFirst () { this->remove (this->head_node); }
void removeTail () { this->remove (this->tail_node); }
void removeLast () { this->remove (this->tail_node); }
/// The getHeadNode() function returns the first node.
/// \code
/// QSE::LinkedList<int> l;
/// QSE::LinkedList<int>::Node* np;
/// for (np = l.getHeadNode(); np; np = np->getNextNode())
/// {
/// printf ("%d\n", np->value);
/// }
/// \endcode
Node* getHeadNode () { return this->head_node; }
const Node* getHeadNode () const { return this->head_node; }
Node* getFirstNode () { return this->head_node; }
const Node* getFirstNode () const { return this->head_node; }
/// The getTailNode() function returns the last node.
/// \code
/// QSE::LinkedList<int> l;
/// QSE::LinkedList<int>::Node* np;
/// for (np = l.getTailNode(); np; np = np->getPrevNode())
/// {
/// printf ("%d\n", np->value);
/// }
/// \endcode
Node* getTailNode () { return this->tail_node; }
const Node* getTailNode () const { return this->tail_node; }
Node* getLastNode () { return this->tail_node; }
const Node* getLastNode () const { return this->tail_node; }
protected:
Node* get_node_at (qse_size_t index) const
{
QSE_ASSERT (index < this->node_count);
Node* np;
qse_size_t cnt;
if (index < (this->node_count >> 1))
{
for (np = this->head_node, cnt = 0; cnt < index; np = np->next, cnt++)
{
QSE_ASSERT (np != QSE_NULL);
}
}
else
{
for (np = this->tail_node, cnt = this->node_count - 1; cnt > index; np = np->prev, cnt--)
{
QSE_ASSERT (np != QSE_NULL);
}
}
return np;
}
public:
Node* getNodeAt (qse_size_t index)
{
return this->get_node_at (index);
}
const Node* getNodeAt (qse_size_t index) const
{
return this->get_node_at (index);
}
T& getValueAt (qse_size_t index)
{
// same as operator[]
QSE_ASSERT (index < this->node_count);
Node* np = this->getNodeAt (index);
return np->value;
}
const T& getValueAt (qse_size_t index) const
{
// same as operator[]
QSE_ASSERT (index < this->node_count);
Node* np = this->getNodeAt (index);
return np->value;
}
void setValueAt (qse_size_t index, const T& value)
{
QSE_ASSERT (index < this->node_count);
Node* np = this->getNodeAt (index);
np->value = value;
}
Node* findFirstNode (const T& value) const
{
for (Node* p = this->head_node; p; p = p->next)
{
if (this->equaler (value, p->value)) return p;
}
return QSE_NULL;
}
Node* findLastNode (const T& value) const
{
for (Node* p = tail_node; p; p = p->prev)
{
if (this->equaler (value, p->value)) return p;
}
return QSE_NULL;
}
Node* findFirstNode (const T& value, Node* head) const
{
for (Node* p = head; p; p = p->next)
{
if (this->equaler (value, p->value)) return p;
}
return QSE_NULL;
}
Node* findLastNode (const T& value, Node* tail) const
{
for (Node* p = tail; p; p = p->prev)
{
if (this->equaler (value, p->value)) return p;
}
return QSE_NULL;
}
qse_size_t findFirstIndex (const T& value) const
{
qse_size_t index = 0;
for (Node* p = this->head_node; p; p = p->next)
{
if (this->equaler (value, p->value)) return index;
index++;
}
return INVALID_INDEX;
}
qse_size_t findLastIndex (const T& value) const
{
qse_size_t index = this->node_count;
for (Node* p = tail_node; p; p = p->prev)
{
index--;
if (this->equaler (value, p->value)) return index;
}
return INVALID_INDEX;
}
void clear (bool clear_mpool = false)
{
Node* p, * saved;
p = this->head_node;
while (p)
{
saved = p->next;
// placement new/delete handling
QSE_CPP_CALL_DESTRUCTOR (p, Node);
QSE_CPP_CALL_PLACEMENT_DELETE1 (p, &this->mp);
this->node_count--;
p = saved;
}
this->head_node = this->tail_node = QSE_NULL;
QSE_ASSERT (this->node_count == 0);
if (clear_mpool) this->mp.dispose ();
}
Iterator getIterator (qse_size_t index = 0)
{
if (this->node_count <= 0)
{
return Iterator (QSE_NULL);
}
else
{
if (index >= this->node_count) index = this->node_count - 1;
return Iterator (this->getNodeAt(index));
}
}
ConstIterator getConstIterator (qse_size_t index = 0) const
{
if (this->node_count <= 0)
{
return ConstIterator (QSE_NULL);
}
else
{
if (index >= this->node_count) index = this->node_count - 1;
return ConstIterator (this->getNodeAt(index));
}
}
/// The reverse() function reverses the order of nodes.
void reverse ()
{
if (this->node_count > 0)
{
Node* head = this->head_node;
QSE_ASSERT (head != QSE_NULL);
while (head->next)
{
Node* next_node = this->yield (head->next, false);
this->insertNode (this->head_node, next_node);
}
}
}
protected:
Mpool mp;
EQUALER equaler;
Node* head_node;
Node* tail_node;
qse_size_t node_count;
};
/////////////////////////////////
QSE_END_NAMESPACE(QSE)
/////////////////////////////////
#endif

View File

@@ -0,0 +1,66 @@
pkgincludedir = $(includedir)/qse/cmn
pkginclude_HEADERS = \
alg.h \
arr.h \
chr.h \
cp949.h \
cp950.h \
dll.h \
env.h \
fma.h \
fmt.h \
gdl.h \
htb.h \
htl.h \
hton.h \
hwad.h \
ipad.h \
main.h \
map.h \
mb8.h \
mbwc.h \
mem.h \
oht.h \
opt.h \
path.h \
pma.h \
rbt.h \
rex.h \
sll.h \
slmb.h \
str.h \
time.h \
tmr.h \
tre.h \
test.h \
uni.h \
uri.h \
utf8.h \
xma.h
if ENABLE_CXX
pkginclude_HEADERS += \
Array.hpp \
Association.hpp \
BinaryHeap.hpp \
Bitset.hpp \
ErrorGrab.hpp \
HashList.hpp \
HashTable.hpp \
HeapMmgr.hpp \
LinkedList.hpp \
Mmged.hpp \
Mmgr.hpp \
Mpool.hpp \
Named.hpp \
RedBlackTree.hpp \
RedBlackTable.hpp \
ScopedPtr.hpp \
SharedPtr.hpp \
StrBase.hpp \
String.hpp \
StdMmgr.hpp \
Transmittable.hpp
endif

641
include/qse/cmn/Makefile.in Normal file
View File

@@ -0,0 +1,641 @@
# Makefile.in generated by automake 1.16.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
@ENABLE_CXX_TRUE@am__append_1 = \
@ENABLE_CXX_TRUE@ Array.hpp \
@ENABLE_CXX_TRUE@ Association.hpp \
@ENABLE_CXX_TRUE@ BinaryHeap.hpp \
@ENABLE_CXX_TRUE@ Bitset.hpp \
@ENABLE_CXX_TRUE@ ErrorGrab.hpp \
@ENABLE_CXX_TRUE@ HashList.hpp \
@ENABLE_CXX_TRUE@ HashTable.hpp \
@ENABLE_CXX_TRUE@ HeapMmgr.hpp \
@ENABLE_CXX_TRUE@ LinkedList.hpp \
@ENABLE_CXX_TRUE@ Mmged.hpp \
@ENABLE_CXX_TRUE@ Mmgr.hpp \
@ENABLE_CXX_TRUE@ Mpool.hpp \
@ENABLE_CXX_TRUE@ Named.hpp \
@ENABLE_CXX_TRUE@ RedBlackTree.hpp \
@ENABLE_CXX_TRUE@ RedBlackTable.hpp \
@ENABLE_CXX_TRUE@ ScopedPtr.hpp \
@ENABLE_CXX_TRUE@ SharedPtr.hpp \
@ENABLE_CXX_TRUE@ StrBase.hpp \
@ENABLE_CXX_TRUE@ String.hpp \
@ENABLE_CXX_TRUE@ StdMmgr.hpp \
@ENABLE_CXX_TRUE@ Transmittable.hpp
subdir = include/qse/cmn
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_sign.m4 \
$(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/ax_cxx_namespace.m4 \
$(top_srcdir)/m4/ax_lib_mysql.m4 $(top_srcdir)/m4/ax_numval.m4 \
$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/m4/lx_find_mpi.m4 \
$(top_srcdir)/m4/qse_try_cflags.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__pkginclude_HEADERS_DIST) \
$(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/include/qse/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__pkginclude_HEADERS_DIST = alg.h arr.h chr.h cp949.h cp950.h dll.h \
env.h fma.h fmt.h gdl.h htb.h htl.h hton.h hwad.h ipad.h \
main.h map.h mb8.h mbwc.h mem.h oht.h opt.h path.h pma.h rbt.h \
rex.h sll.h slmb.h str.h time.h tmr.h tre.h test.h uni.h uri.h \
utf8.h xma.h Array.hpp Association.hpp BinaryHeap.hpp \
Bitset.hpp ErrorGrab.hpp HashList.hpp HashTable.hpp \
HeapMmgr.hpp LinkedList.hpp Mmged.hpp Mmgr.hpp Mpool.hpp \
Named.hpp RedBlackTree.hpp RedBlackTable.hpp ScopedPtr.hpp \
SharedPtr.hpp StrBase.hpp String.hpp StdMmgr.hpp \
Transmittable.hpp
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(pkgincludedir)"
HEADERS = $(pkginclude_HEADERS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
pkgincludedir = $(includedir)/qse/cmn
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BUILD_MODE = @BUILD_MODE@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DL_LIBS = @DL_LIBS@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
HAVE_CXX = @HAVE_CXX@
HAVE_CXX11 = @HAVE_CXX11@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBM = @LIBM@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBTOOL_DEPS = @LIBTOOL_DEPS@
LIPO = @LIPO@
LN_S = @LN_S@
LTDL_LIBS = @LTDL_LIBS@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
MPICC = @MPICC@
MPI_CFLAGS = @MPI_CFLAGS@
MPI_CLDFLAGS = @MPI_CLDFLAGS@
MYSQL_CFLAGS = @MYSQL_CFLAGS@
MYSQL_CONFIG = @MYSQL_CONFIG@
MYSQL_LDFLAGS = @MYSQL_LDFLAGS@
MYSQL_LIBS = @MYSQL_LIBS@
MYSQL_VERSION = @MYSQL_VERSION@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
PACKAGE_VERSION_PATCH = @PACKAGE_VERSION_PATCH@
PATH_SEPARATOR = @PATH_SEPARATOR@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
QSE_PROJECT_AUTHOR = @QSE_PROJECT_AUTHOR@
QSE_PROJECT_URL = @QSE_PROJECT_URL@
QUADMATH_LIBS = @QUADMATH_LIBS@
RANLIB = @RANLIB@
RM = @RM@
RMDIR = @RMDIR@
SED = @SED@
SENDFILE_LIBS = @SENDFILE_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SOCKET_LIBS = @SOCKET_LIBS@
SSL_LIBS = @SSL_LIBS@
STRIP = @STRIP@
TRUE = @TRUE@
UCI_LIBS = @UCI_LIBS@
UNICOWS_LIBS = @UNICOWS_LIBS@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
ax_pthread_config = @ax_pthread_config@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
pkginclude_HEADERS = alg.h arr.h chr.h cp949.h cp950.h dll.h env.h \
fma.h fmt.h gdl.h htb.h htl.h hton.h hwad.h ipad.h main.h \
map.h mb8.h mbwc.h mem.h oht.h opt.h path.h pma.h rbt.h rex.h \
sll.h slmb.h str.h time.h tmr.h tre.h test.h uni.h uri.h \
utf8.h xma.h $(am__append_1)
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/qse/cmn/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign include/qse/cmn/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-pkgincludeHEADERS: $(pkginclude_HEADERS)
@$(NORMAL_INSTALL)
@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \
$(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \
$(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \
done
uninstall-pkgincludeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir)
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(pkgincludedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-pkgincludeHEADERS
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-pkgincludeHEADERS
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libtool cscopelist-am ctags ctags-am distclean \
distclean-generic distclean-libtool distclean-tags distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-pdf \
install-pdf-am install-pkgincludeHEADERS install-ps \
install-ps-am install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
ps ps-am tags tags-am uninstall uninstall-am \
uninstall-pkgincludeHEADERS
.PRECIOUS: Makefile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

68
include/qse/cmn/Mmged.hpp Normal file
View File

@@ -0,0 +1,68 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_MMGED_HPP_
#define _QSE_CMN_MMGED_HPP_
#include <qse/cmn/Mmgr.hpp>
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
///
/// The Mmged class defines a memory manager interface to be inherited by
/// a subclass that uses a memory manager.
///
class QSE_EXPORT Mmged
{
public:
Mmged (Mmgr* mmgr = QSE_NULL);
///
/// The getMmgr() function returns the memory manager associated.
///
Mmgr* getMmgr () const { return this->_mmgr; }
protected:
///
/// The setMmgr() function changes the memory manager.
/// Changing memory manager requires extra care to be taken
/// especially when you have some data allocated with the previous
/// manager. for this reason, i put this as a protected function.
///
void setMmgr(Mmgr* mmgr);
private:
Mmgr* _mmgr;
};
/////////////////////////////////
QSE_END_NAMESPACE(QSE)
/////////////////////////////////
#endif

202
include/qse/cmn/Mmgr.hpp Normal file
View File

@@ -0,0 +1,202 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_MMGR_HPP_
#define _QSE_CMN_MMGR_HPP_
#include <qse/Exception.hpp>
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
///
/// The Mmgr class defines a memory manager interface that can be inherited
/// by a class in need of a memory manager as defined in the primitive
/// #qse_mmgr_t type. Using the class over the primitive type enables you to
/// write code in more object-oriented fashion. An inheriting class should
/// implement three pure virtual functions.
///
/// You are free to call allocMem(), reallocMem(), and freeMem() in C++ context
/// where no exception raising is desired. If you want an exception to be
/// raised upon memory allocation errors, you can call allocate(), reallocate(),
/// dispose() instead.
///
///
class QSE_EXPORT Mmgr: public qse_mmgr_t
{
public:
/// defines an alias type to #qse_mmgr_t
typedef qse_mmgr_t mmgr_t;
QSE_EXCEPTION (MemoryError);
public:
///
/// The Mmgr() function builds a memory manager composed of bridge
/// functions connecting itself with it.
///
Mmgr () QSE_CPP_NOEXCEPT
{
// NOTE:
// the #qse_mmgr_t interface is not affected by raise_exception
// because direct calls to the virtual functions that don't raise
// exceptions are made via bridge functions below.
this->alloc = alloc_mem;
this->realloc = realloc_mem;
this->free = free_mem;
this->ctx = this;
}
///
/// The ~Mmgr() function finalizes a memory manager.
///
virtual ~Mmgr () QSE_CPP_NOEXCEPT {}
///
/// The allocate() function calls allocMem() for memory
/// allocation. if it fails, it raise an exception if it's
/// configured to do so.
///
void* allocate (qse_size_t n, bool raise_exception = true) /*QSE_CPP_THREXCEPT1(MemoryError)*/
{
void* xptr = this->allocMem(n);
if (!xptr && raise_exception) QSE_THROW (MemoryError);
return xptr;
}
///
/// The callocate() function allocates memory like allocate() and
/// clears the memory before returning.
///
void* callocate (qse_size_t n, bool raise_exception = true) /*QSE_CPP_THREXCEPT1(MemoryError)*/;
///
/// The reallocate() function calls reallocMem() for memory
/// reallocation. if it fails, it raise an exception if it's
/// configured to do so.
///
void* reallocate (void* ptr, qse_size_t n, bool raise_exception = true) /*QSE_CPP_THREXCEPT1(MemoryError)*/
{
void* xptr = this->reallocMem(ptr, n);
if (!xptr && raise_exception) QSE_THROW (MemoryError);
return xptr;
}
///
/// The dispose() function calls freeMem() for memory disposal.
///
void dispose (void* ptr) QSE_CPP_NOEXCEPT
{
this->freeMem (ptr);
}
//protected:
///
/// The allocMem() function allocates a chunk of memory of the
/// size \a n and return the pointer to the beginning of the chunk.
/// If it fails to allocate memory, it should return #QSE_NULL.
///
virtual void* allocMem (
qse_size_t n ///< size of memory chunk to allocate in bytes
) QSE_CPP_NOEXCEPT = 0;
///
/// The reallocMem() function resizes a chunk of memory previously
/// allocated with the allocMem() function. When resized, the contents
/// of the surviving part of a memory chunk is preserved. If it fails to
/// resize memory, it should return QSE_NULL.
///
virtual void* reallocMem (
void* ptr, ///< pointer to memory chunk to resize
qse_size_t n ///< new size in bytes
) QSE_CPP_NOEXCEPT = 0;
///
/// The freeMem() function frees a chunk of memory allocated with
/// the allocMem() function or resized with the reallocMem() function.
///
virtual void freeMem (
void* ptr ///< pointer to memory chunk to free
) QSE_CPP_NOEXCEPT = 0;
protected:
///
/// bridge function from the #qse_mmgr_t type the allocMem() function.
///
static void* alloc_mem (mmgr_t* mmgr, qse_size_t n) QSE_CPP_NOEXCEPT;
///
/// bridge function from the #qse_mmgr_t type the reallocMem() function.
///
static void* realloc_mem (mmgr_t* mmgr, void* ptr, qse_size_t n) QSE_CPP_NOEXCEPT;
///
/// bridge function from the #qse_mmgr_t type the freeMem() function.
///
static void free_mem (mmgr_t* mmgr, void* ptr) QSE_CPP_NOEXCEPT;
public:
static Mmgr* getDFL () QSE_CPP_NOEXCEPT;
static void setDFL (Mmgr* mmgr) QSE_CPP_NOEXCEPT;
protected:
static Mmgr* dfl_mmgr;
};
/////////////////////////////////
QSE_END_NAMESPACE(QSE)
/////////////////////////////////
QSE_EXPORT void* operator new (qse_size_t size, QSE::Mmgr* mmgr) /*QSE_CPP_THREXCEPT1(QSE::Mmgr::MemoryError)*/;
#if defined(QSE_CPP_NO_OPERATOR_DELETE_OVERLOADING)
QSE_EXPORT void qse_operator_delete (void* ptr, QSE::Mmgr* mmgr);
#else
QSE_EXPORT void operator delete (void* ptr, QSE::Mmgr* mmgr);
#endif
QSE_EXPORT void* operator new (qse_size_t size, QSE::Mmgr* mmgr, void* existing_ptr) /*QSE_CPP_THREXCEPT1(QSE::Mmgr::MemoryError)*/;
#if 0
// i found no way to delete an array allocated with
// the placement new operator. if the array element is an instance
// of a class, the pointer returned by the new operator call
// may not be the actual pointer allocated. some compilers
// seem to put some information about the array at the
// beginning of the allocated memory and return the pointer
// off a few bytes from the beginning.
void* operator new[] (qse_size_t size, QSE::Mmgr* mmgr);
void operator delete[] (void* ptr, QSE::Mmgr* mmgr);
#endif
#define QSE_CPP_DELETE_WITH_MMGR(ptr, class_name, mmgr) \
do { \
QSE_CPP_CALL_DESTRUCTOR (ptr, class_name); \
QSE_CPP_CALL_PLACEMENT_DELETE1(ptr, mmgr); \
} while(0);
#endif

137
include/qse/cmn/Mpool.hpp Normal file
View File

@@ -0,0 +1,137 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_MPOOL_HPP_
#define _QSE_CMN_MPOOL_HPP_
/// \file
/// Provides the Mpool class.
#include <qse/Uncopyable.hpp>
#include <qse/cmn/Mmged.hpp>
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
///
/// The Mpool class implements an memory allocator for fixed-sized data.
/// It is similar to #qse_fma_t in functionality.
///
class QSE_EXPORT Mpool: public Uncopyable, public Mmged
{
public:
enum
{
DEFAULT_BLOCK_SIZE = 128
};
Mpool (
Mmgr* mmgr,
qse_size_t datum_size,
qse_size_t block_size = DEFAULT_BLOCK_SIZE);
~Mpool ();
/// The allocate() function returns the pointer to the memory chunk of the
/// configured datum size. It returns #QSE_NULL upon failure.
void* allocate ();
/// The dispose() function frees the memory chunk pointed to by \a ptr.
void dispose (void* ptr);
/// The dispose() function frees all memory chunks allocated in the pool.
void dispose ();
bool isEnabled () const
{
return this->datum_size > 0 && this->block_size > 0;
}
bool isDisabled () const
{
return this->datum_size <= 0 || this->block_size <= 0;
}
qse_size_t getDatumSize () const
{
return this->datum_size;
}
qse_size_t getBlockSize () const
{
return this->block_size;
}
void setBlockSize (qse_size_t blockSize)
{
this->block_size = blockSize;
}
int swap (Mpool& mpool);
#if defined(QSE_DEBUG_MPOOL)
qse_size_t nalloc;
qse_size_t navail;
#endif
protected:
struct Block
{
Block* next;
//qse_uint8_t data[0];
};
struct Chain
{
Chain* next;
};
// NOTE: whenever you add new member variables, make sure to
// update the swap() function accordingly
Block* mp_blocks;
Chain* free_list;
qse_size_t datum_size;
qse_size_t block_size;
Block* add_block ();
};
/////////////////////////////////
QSE_END_NAMESPACE(QSE)
////////////////////////////////
QSE_EXPORT void* operator new (qse_size_t size, QSE::Mpool* mp);
#if defined(QSE_CPP_NO_OPERATOR_DELETE_OVERLOADING)
QSE_EXPORT void qse_operator_delete (void* ptr, QSE::Mpool* mp);
#else
QSE_EXPORT void operator delete (void* ptr, QSE::Mpool* mp);
#endif
QSE_EXPORT void* operator new (qse_size_t size, QSE::Mpool* mp, void* existing_ptr);
#endif

85
include/qse/cmn/Named.hpp Normal file
View File

@@ -0,0 +1,85 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 EQSERESS 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 _QSE_CMN_NAMED_CLASS_
#define _QSE_CMN_NAMED_CLASS_
#include <qse/Types.hpp>
#include <qse/cmn/str.h>
QSE_BEGIN_NAMESPACE(QSE)
template <int N>
class Named
{
public:
Named (const qse_char_t* name = QSE_T("")) QSE_CPP_NOEXCEPT
{
QSE_ASSERT (name != QSE_NULL);
// WARNING: a long name can be truncated
qse_strxcpy (this->_name_buf, QSE_COUNTOF(this->_name_buf), name);
}
~Named () QSE_CPP_NOEXCEPT {}
qse_char_t* getName () QSE_CPP_NOEXCEPT
{
return this->_name_buf;
}
const qse_char_t* getName () const QSE_CPP_NOEXCEPT
{
return this->_name_buf;
}
void setName (const qse_char_t* name) QSE_CPP_NOEXCEPT
{
QSE_ASSERT (name != QSE_NULL);
// WARNING: a long name can be truncated
qse_strxcpy (this->_name_buf, QSE_COUNTOF(this->_name_buf), name);
}
bool isNamed () const QSE_CPP_NOEXCEPT
{
return this->_name_buf[0] != QSE_T('\0');
}
bool isNamed (const qse_char_t* n) const QSE_CPP_NOEXCEPT
{
return qse_strcmp(this->_name_buf, n) == 0;
}
enum
{
MAX_NAME_LEN = N
};
protected:
qse_char_t _name_buf[MAX_NAME_LEN + 1];
};
QSE_END_NAMESPACE(QSE)
#endif

View File

@@ -0,0 +1,276 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_REDBLACKTABLE_HPP_
#define _QSE_CMN_REDBLACKTABLE_HPP_
/// \file
/// Provides the RedBlackTable class.
#include <qse/cmn/Association.hpp>
#include <qse/cmn/RedBlackTree.hpp>
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
template<typename T>
struct RedBlackTableComparator
{
// it must return true if two values are equal
int operator() (const T& v1, const T& v2) const
{
if (v1 > v2) return 1;
if (v1 < v2) return -1;
QSE_ASSERT (v1 == v2);
return 0;
}
};
///
/// The RedBlackTable class extends the RedBlackTree class to maintain the
/// pair of a key and a value.
///
template <typename K, typename V, typename COMPARATOR = RedBlackTableComparator<K> >
class RedBlackTable: public Mmged
{
public:
typedef Association<K,V> Pair;
typedef RedBlackTable<K,V,COMPARATOR> SelfType;
typedef RedBlackTableComparator<K> DefaultComparator;
struct PairComparator
{
qse_size_t operator() (const Pair& p1, const Pair& p2) const
{
COMPARATOR comparator;
return comparator (p1.key, p2.key);
}
};
struct PairHeteroComparator
{
qse_size_t operator() (const K& p1, const Pair& p2) const
{
COMPARATOR comparator;
return comparator (p1, p2.key);
}
};
template <typename MK, typename MCOMPARATOR>
struct MHeteroComparator
{
qse_size_t operator() (const MK& p1, const Pair& p2) const
{
MCOMPARATOR mcomparator;
return mcomparator (p1, p2.key);
}
};
typedef RedBlackTree<Pair,PairComparator> PairTree;
typedef typename PairTree::Node PairNode;
typedef typename PairTree::Iterator Iterator;
typedef typename PairTree::ConstIterator ConstIterator;
RedBlackTable (Mmgr* mmgr = QSE_NULL): Mmged(mmgr), pair_tree(mmgr, 0)
{
}
RedBlackTable (qse_size_t mpb_size, Mmgr* mmgr = QSE_NULL): Mmged(mmgr), pair_tree(mpb_size, mmgr)
{
}
RedBlackTable (const SelfType& table): Mmged(table), pair_tree(table.pair_tree)
{
}
SelfType& operator= (const SelfType& table)
{
if (this != &table)
{
this->pair_tree = table.pair_tree;
}
return *this;
}
Mpool& getMpool ()
{
return this->pair_tree.getMpool ();
}
const Mpool& getMpool () const
{
return this->pair_tree.getMpool ();
}
qse_size_t getSize() const
{
return this->pair_tree.getSize ();
}
bool isEmpty () const
{
return this->pair_tree.isEmpty ();
}
PairNode* getHeadNode ()
{
return this->pair_tree.getHeadNode ();
}
const PairNode* getHeadNode () const
{
return this->pair_tree.getHeadNode ();
}
PairNode* getTailNode ()
{
return this->pair_tree.getTailNode ();
}
const PairNode* getTailNode () const
{
return this->pair_tree.getTailNode ();
}
Pair* inject (const K& key, const V& value, int mode, bool* injected = QSE_NULL)
{
PairNode* node = this->pair_tree.inject (Pair(key, value), mode, injected);
if (!node) return QSE_NULL;
return &node->value;
}
Pair* insert (const K& key, const V& value)
{
PairNode* node = this->pair_tree.insert (Pair(key, value));
if (!node) return QSE_NULL;
return &node->value;
}
Pair* ensert (const K& key, const V& value)
{
PairNode* node = this->pair_tree.ensert (Pair(key, value));
if (!node) return QSE_NULL;
return &node->value;
}
Pair* upsert (const K& key, const V& value)
{
//PairNode* node = this->pair_tree.upsert (Pair(key, value));
//if (!node) return QSE_NULL;
//return &node->value;
// Don't call pair_tree.upsert() to make sure that the 'key' object
// itself remains identical after potential update operation.
// pair_tree.upsert() changes the Pair object as a whole. so this
// trick is required.
bool injected;
PairNode* node = this->pair_tree.inject (Pair(key, value), 0, &injected);
QSE_ASSERT (node != QSE_NULL);
Pair& pair = node->value;
if (injected) pair.value = value;
return &pair;
}
Pair* update (const K& key, const V& value)
{
//PairNode* node = this->pair_tree.update (Pair(key, value));
//if (!node) return QSE_NULL;
//return &node->value;
PairNode* node = this->pair_tree.QSE_CPP_TEMPLATE_QUALIFIER heterofindNode<K,PairHeteroComparator> (key);
if (!node) return QSE_NULL;
Pair& pair = node->value;
pair.value = value;
return &pair;
}
Pair* search (const K& key)
{
//PairNode* node = this->pair_tree.update (Pair(key));
PairNode* node = this->pair_tree.QSE_CPP_TEMPLATE_QUALIFIER heterofindNode<K,PairHeteroComparator> (key);
if (!node) return QSE_NULL;
return &node->value;
}
int remove (const K& key)
{
//return this->pair_tree.remove (Pair(key));
return this->pair_tree.QSE_CPP_TEMPLATE_QUALIFIER heteroremove<K,PairHeteroComparator> (key);
}
template <typename MK, typename MCOMPARATOR>
Pair* heterosearch (const MK& key)
{
typedef MHeteroComparator<MK,MCOMPARATOR> MComparator;
PairNode* node = this->pair_tree.QSE_CPP_TEMPLATE_QUALIFIER heterosearch<MK,MComparator> (key);
if (!node) return QSE_NULL;
return &node->value;
}
template <typename MK, typename MCOMPARATOR>
const Pair* heterosearch (const MK& key) const
{
typedef MHeteroComparator<MK,MCOMPARATOR> MComparator;
PairNode* node = this->pair_tree.QSE_CPP_TEMPLATE_QUALIFIER heterosearch<MK,MComparator> (key);
if (!node) return QSE_NULL;
return &node->value;
}
template <typename MK, typename MCOMPARATOR>
int heteroremove (const MK& key)
{
typedef MHeteroComparator<MK,MCOMPARATOR> MComparator;
return this->pair_tree.QSE_CPP_TEMPLATE_QUALIFIER heteroremove<MK,MComparator> (key);
}
void clear (bool clear_mpool = false)
{
return this->pair_tree.clear (clear_mpool);
}
Iterator getIterator (typename Iterator::Mode mode = Iterator::ASCENDING) const
{
return this->pair_tree.getIterator (mode);
}
ConstIterator getConstIterator (typename ConstIterator::Mode mode = ConstIterator::ASCENDING) const
{
return this->pair_tree.getConstIterator (mode);
}
protected:
PairTree pair_tree;
};
/////////////////////////////////
QSE_END_NAMESPACE(QSE)
/////////////////////////////////
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,196 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_SCOPEDPTR_HPP_
#define _QSE_CMN_SCOPEDPTR_HPP_
/// \file
/// Provides the ScopedPtr template class.
#include <qse/Uncopyable.hpp>
#include <qse/cmn/Mmgr.hpp>
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
template <typename T>
struct ScopedPtrDeleter
{
void operator() (T* ptr, void* arg)
{
delete ptr;
}
};
template <typename T>
struct ScopedPtrArrayDeleter
{
void operator() (T* ptr, void* arg)
{
delete[] ptr;
}
};
template <typename T>
struct ScopedPtrMmgrDeleter
{
void operator() (T* ptr, void* arg)
{
QSE_CPP_CALL_DESTRUCTOR (ptr, T);
QSE_CPP_CALL_PLACEMENT_DELETE1 (ptr, (QSE::Mmgr*)arg);
}
};
/// The ScopedPtr class is a template class that destroys the object the
/// pointer points to when its destructor is called. You can use this class
/// to free a certain resource associated to the pointer when it goes out
/// of the current scope.
///
/// \code
/// #include <stdio.h>
/// #include <qse/cmn/ScopedPtr.hpp>
/// #include <qse/cmn/HeapMmgr.hpp>
///
///
/// class X
/// {
/// public:
/// X() { printf ("X constructured\n"); }
/// ~X() { printf ("X destructed\n"); }
/// };
///
///
/// int main ()
/// {
/// QSE::HeapMmgr heap_mmgr (QSE::Mmgr::getDFL(), 30000);
///
/// {
/// QSE::ScopedPtr<X> x1 (new X);
/// QSE::ScopedPtr<X,QSE::ScopedPtrArrayDeleter<X> > x3 (new X[10]);
/// QSE::ScopedPtr<X,QSE::ScopedPtrMmgrDeleter<X> > x2 (new(&heap_mmgr) X, &heap_mmgr);
/// }
///
/// return 0;
/// }
/// \endcode
///
template<typename T, typename DELETER = ScopedPtrDeleter<T> >
class QSE_EXPORT ScopedPtr: public Uncopyable
{
public:
typedef ScopedPtr<T,DELETER> SelfType;
typedef ScopedPtrDeleter<T> DefaultDeleter;
ScopedPtr (T* ptr = (T*)QSE_NULL, void* darg = (void*)QSE_NULL): _ptr (ptr), _darg (darg)
{
}
~ScopedPtr ()
{
if (this->_ptr)
{
this->_deleter (this->_ptr, this->_darg);
}
}
T& operator* ()
{
QSE_ASSERT (this->_ptr != (T*)QSE_NULL);
return *this->_ptr;
}
const T& operator* () const
{
QSE_ASSERT (this->_ptr != (T*)QSE_NULL);
return *this->_ptr;
}
T* operator-> ()
{
QSE_ASSERT (this->_ptr != (T*)QSE_NULL);
return this->_ptr;
}
const T* operator-> () const
{
QSE_ASSERT (this->_ptr != (T*)QSE_NULL);
return this->_ptr;
}
bool operator! () const
{
return this->_ptr == (T*)QSE_NULL;
}
T& operator[] (qse_size_t idx)
{
QSE_ASSERT (this->_ptr != (T*)QSE_NULL);
return this->_ptr[idx];
}
T* get ()
{
return this->_ptr;
}
const T* get () const
{
return this->_ptr;
}
T* release ()
{
T* t = this->_ptr;
this->_ptr = (T*)QSE_NULL;
this->_darg = QSE_NULL;
return t;
}
void reset (T* ptr = (T*)QSE_NULL, void* darg = (T*)QSE_NULL)
{
if (this->_ptr)
{
this->_deleter (this->_ptr, this->_darg);
}
this->_ptr = ptr;
this->_darg = darg;
}
private:
T* _ptr;
void* _darg;
DELETER _deleter;
};
/////////////////////////////////
QSE_END_NAMESPACE(QSE)
/////////////////////////////////
#endif

View File

@@ -0,0 +1,198 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_SHAREDPTR_HPP_
#define _QSE_CMN_SHAREDPTR_HPP_
/// \file
/// Provides the SharedPtr template class.
#include <qse/cmn/Mmged.hpp>
#include <qse/RefCounted.hpp>
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
template <typename T>
struct SharedPtrDeleter
{
void operator() (T* ptr, void* arg)
{
delete ptr;
}
};
template <typename T>
struct SharedPtrArrayDeleter
{
void operator() (T* ptr, void* arg)
{
delete[] ptr;
}
};
template <typename T>
struct SharedPtrMmgrDeleter
{
void operator() (T* ptr, void* arg)
{
QSE_CPP_CALL_DESTRUCTOR (ptr, T);
QSE_CPP_CALL_PLACEMENT_DELETE1 (ptr, (QSE::Mmgr*)arg);
}
};
///
/// The SharedPtr class provides a smart pointer that can be shared
/// using reference counting.
///
template<typename T, typename DELETER = SharedPtrDeleter<T> >
class QSE_EXPORT SharedPtr: public Mmged
{
public:
typedef SharedPtr<T,DELETER> SelfType;
typedef SharedPtrDeleter<T> DefaultDeleter;
SharedPtr (T* ptr = (T*)QSE_NULL, void* darg = (void*)QSE_NULL): Mmged(QSE_NULL)
{
this->_item = new(this->getMmgr()) item_t;
this->_item->ptr = ptr;
this->_item->darg = darg;
this->_item->ref ();
}
SharedPtr (Mmgr* mmgr, T* ptr = (T*)QSE_NULL, void* darg = (void*)QSE_NULL): Mmged(mmgr)
{
this->_item = new(this->getMmgr()) item_t;
this->_item->ptr = ptr;
this->_item->darg = darg;
this->_item->ref ();
}
SharedPtr (const SelfType& sp): Mmged(sp), _item(sp._item)
{
this->_item->ref ();
}
~SharedPtr ()
{
if (this->_item->deref() <= 0)
{
// reference count reached 0.
if (this->_item->ptr) this->_item->deleter (this->_item->ptr, this->_item->darg);
QSE_CPP_CALL_DESTRUCTOR (this->_item, item_t);
QSE_CPP_CALL_PLACEMENT_DELETE1 (this->_item, this->getMmgr());
}
}
SelfType& operator= (const SelfType& sp)
{
if (this != &sp)
{
if (this->_item->deref() <= 0)
{
if (this->_item->ptr) this->_item->deleter (this->_item->ptr, this->_item->darg);
QSE_CPP_CALL_DESTRUCTOR (this->_item, item_t);
QSE_CPP_CALL_PLACEMENT_DELETE1 (this->_item, this->getMmgr());
}
// must copy the memory manager pointer as the item
// to be copied is allocated using the memory manager of sp.
this->setMmgr (sp.getMmgr()); // copy over mmgr
this->_item = sp._item;
this->_item->ref ();
}
return *this;
}
T& operator* ()
{
QSE_ASSERT (this->_item->ptr != (T*)QSE_NULL);
return *this->_item->ptr;
}
const T& operator* () const
{
QSE_ASSERT (this->_item->ptr != (T*)QSE_NULL);
return *this->_item->ptr;
}
T* operator-> ()
{
QSE_ASSERT (this->_item->ptr != (T*)QSE_NULL);
return this->_item->ptr;
}
const T* operator-> () const
{
QSE_ASSERT (this->_item->ptr != (T*)QSE_NULL);
return this->_item->ptr;
}
bool operator! () const
{
return this->_item->ptr == (T*)QSE_NULL;
}
T& operator[] (qse_size_t idx)
{
QSE_ASSERT (this->_item->ptr != (T*)QSE_NULL);
return this->_item->ptr[idx];
}
T* getPtr ()
{
return this->_item->ptr;
}
const T* getPtr () const
{
return this->_item->ptr;
}
private:
struct item_t: public RefCounted
{
T* ptr;
void* darg;
DELETER deleter;
};
item_t* _item;
};
/////////////////////////////////
QSE_END_NAMESPACE(QSE)
/////////////////////////////////
#endif

View File

@@ -0,0 +1,60 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_STDMMGR_HPP_
#define _QSE_CMN_STDMMGR_HPP_
#include <qse/cmn/Mmgr.hpp>
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
/// The StdMmgr class implements the memory manager interface.
/// It doesn't raise an exception upon failure. If you want an exception
/// to be raised, use the ExcMmgr class instead.
class QSE_EXPORT StdMmgr: public Mmgr
{
public:
StdMmgr () QSE_CPP_NOEXCEPT: Mmgr () {}
void* allocMem (qse_size_t n) QSE_CPP_NOEXCEPT;
void* reallocMem (void* ptr, qse_size_t n) QSE_CPP_NOEXCEPT;
void freeMem (void* ptr) QSE_CPP_NOEXCEPT;
#if 0
/// The getInstance() function returns the stock instance of the StdMmgr
/// class.
static StdMmgr* getInstance () QSE_CPP_NOEXCEPT;
#endif
};
/////////////////////////////////
QSE_END_NAMESPACE(QSE)
/////////////////////////////////
#endif

1141
include/qse/cmn/StrBase.hpp Normal file

File diff suppressed because it is too large Load Diff

284
include/qse/cmn/String.hpp Normal file
View File

@@ -0,0 +1,284 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_STRING_HPP_
#define _QSE_CMN_STRING_HPP_
/// \file
/// Provides the String, WcString, McString classes.
///
/// \includelineno str02.cpp
///
#include <qse/cmn/StrBase.hpp>
#include <qse/cmn/str.h>
#include <qse/cmn/mem.h>
#include <stdarg.h>
/////////////////////////////////
QSE_BEGIN_NAMESPACE(QSE)
/////////////////////////////////
struct WcStringOpset
{
qse_size_t copy (qse_wchar_t* dst, const qse_wchar_t* src, qse_size_t ssz) const
{
return qse_wcsncpy(dst, src, ssz);
}
qse_size_t move (qse_wchar_t* dst, const qse_wchar_t* src, qse_size_t ssz) const
{
// this one doesn't insert terminating null
qse_memmove (dst, src, ssz * QSE_SIZEOF(*dst));
return ssz;
}
// compare two strings of the same length
int compare (const qse_wchar_t* str1, const qse_wchar_t* str2, qse_size_t len) const
{
return qse_wcsxncmp(str1, len, str2, len);
}
// compare a length-bound string with a null-terminated string.
int compare (const qse_wchar_t* str1, qse_size_t len, const qse_wchar_t* str2) const
{
return qse_wcsxcmp(str1, len, str2);
}
qse_size_t getLength (const qse_wchar_t* str) const
{
return qse_wcslen(str);
}
bool beginsWith (const qse_wchar_t* str, qse_size_t len, const qse_wchar_t* sub) const
{
return qse_wcsxbeg (str, len, sub) != QSE_NULL;
}
bool beginsWith (const qse_wchar_t* str, qse_size_t len, const qse_wchar_t* sub, qse_size_t sublen) const
{
return qse_wcsxnbeg (str, len, sub, sublen) != QSE_NULL;
}
bool endsWith (const qse_wchar_t* str, qse_size_t len, const qse_wchar_t* sub) const
{
return qse_wcsxend (str, len, sub) != QSE_NULL;
}
bool endsWith (const qse_wchar_t* str, qse_size_t len, const qse_wchar_t* sub, qse_size_t sublen) const
{
return qse_wcsxnend (str, len, sub, sublen) != QSE_NULL;
}
qse_size_t trim (qse_wchar_t* str, qse_size_t len, bool left, bool right) const
{
qse_wchar_t* ptr;
qse_size_t xlen = len;
int flags = 0;
if (left) flags |= QSE_WCSTRMX_LEFT;
if (right) flags |= QSE_WCSTRMX_RIGHT;
ptr = qse_wcsxtrmx (str, &xlen, flags);
this->move (str, ptr, xlen);
str[xlen] = QSE_WT('\0');
return xlen;
}
};
struct MbStringOpset
{
qse_size_t copy (qse_mchar_t* dst, const qse_mchar_t* src, qse_size_t ssz) const
{
return qse_mbsncpy(dst, src, ssz);
}
qse_size_t move (qse_mchar_t* dst, const qse_mchar_t* src, qse_size_t ssz) const
{
// this one doesn't insert terminating null
qse_memmove (dst, src, ssz * QSE_SIZEOF(*dst));
return ssz;
}
// compare two strings of the same length
int compare (const qse_mchar_t* str1, const qse_mchar_t* str2, qse_size_t len) const
{
return qse_mbsxncmp(str1, len, str2, len);
}
// compare a length-bound string with a null-terminated string.
int compare (const qse_mchar_t* str1, qse_size_t len, const qse_mchar_t* str2) const
{
return qse_mbsxcmp(str1, len, str2);
}
qse_size_t getLength (const qse_mchar_t* str) const
{
return qse_mbslen(str);
}
bool beginsWith (const qse_mchar_t* str, qse_size_t len, const qse_mchar_t* sub) const
{
return qse_mbsxbeg (str, len, sub) != QSE_NULL;
}
bool beginsWith (const qse_mchar_t* str, qse_size_t len, const qse_mchar_t* sub, qse_size_t sublen) const
{
return qse_mbsxnbeg (str, len, sub, sublen) != QSE_NULL;
}
bool endsWith (const qse_mchar_t* str, qse_size_t len, const qse_mchar_t* sub) const
{
return qse_mbsxend (str, len, sub) != QSE_NULL;
}
bool endsWith (const qse_mchar_t* str, qse_size_t len, const qse_mchar_t* sub, qse_size_t sublen) const
{
return qse_mbsxnend (str, len, sub, sublen) != QSE_NULL;
}
qse_size_t trim (qse_mchar_t* str, qse_size_t len, bool left, bool right) const
{
qse_mchar_t* ptr;
qse_size_t xlen = len;
int flags = 0;
if (left) flags |= QSE_MBSTRMX_LEFT;
if (right) flags |= QSE_MBSTRMX_RIGHT;
ptr = qse_mbsxtrmx (str, &xlen, flags);
this->move (str, ptr, xlen);
str[xlen] = QSE_MT('\0');
return xlen;
}
};
// It's a pain to inherit StrBase<> as it has many constructors.
// i do this to hide various va_xxx calls from the header file of StrBase.
class WcString: public StrBase<qse_wchar_t, QSE_WT('\0'), WcStringOpset>
{
private:
typedef StrBase<qse_wchar_t, QSE_WT('\0'), WcStringOpset> ParentType;
public:
WcString (Mmgr* mmgr = QSE_NULL): ParentType(mmgr) {}
WcString (int capacity, Mmgr* mmgr = QSE_NULL): ParentType(capacity, mmgr) {}
WcString (qse_size_t capacity, Mmgr* mmgr = QSE_NULL): ParentType(capacity, mmgr) {}
WcString (const qse_wchar_t* str, Mmgr* mmgr = QSE_NULL): ParentType(str, mmgr) {}
WcString (const qse_wchar_t* str, qse_size_t size, Mmgr* mmgr = QSE_NULL): ParentType(str, size, mmgr) {}
WcString (qse_wchar_t c, qse_size_t size, Mmgr* mmgr = QSE_NULL): ParentType(c, size, mmgr) {}
WcString (const WcString& str): ParentType(str) {}
#if defined(QSE_CPP_ENABLE_CPP11_MOVE)
WcString (WcString&& str): ParentType(QSE_CPP_RVREF(str)) {}
WcString (ParentType&& str): ParentType(QSE_CPP_RVREF(str)) {} // added for ParentType returned in some methods defined in ParentType. e.g. getSubstring()
#endif
WcString& operator= (const WcString& str) { ParentType::operator=(str); return *this; }
#if defined(QSE_CPP_ENABLE_CPP11_MOVE)
WcString& operator= (WcString&& str) { ParentType::operator=(QSE_CPP_RVREF(str)); return *this; }
WcString& operator= (ParentType&& str) { ParentType::operator=(QSE_CPP_RVREF(str)); return *this; } // added for ParentType returned in some methods defined in ParentType. e.g. getSubstring()
#endif
WcString& operator= (const qse_wchar_t* str) { ParentType::operator=(str); return *this; }
WcString& operator= (const qse_wchar_t c) { ParentType::operator=(c); return *this; }
//using ParentType::operator=;
int format (const qse_wchar_t* fmt, ...);
int formatv (const qse_wchar_t* fmt, va_list ap);
};
class MbString: public StrBase<qse_mchar_t, QSE_MT('\0'), MbStringOpset>
{
private:
typedef StrBase<qse_mchar_t, QSE_MT('\0'), MbStringOpset> ParentType;
public:
MbString (Mmgr* mmgr = QSE_NULL): ParentType(mmgr) {}
MbString (int capacity, Mmgr* mmgr = QSE_NULL): ParentType(capacity, mmgr) {}
MbString (qse_size_t capacity, Mmgr* mmgr = QSE_NULL): ParentType(capacity, mmgr) {}
MbString (const qse_mchar_t* str, Mmgr* mmgr = QSE_NULL): ParentType(str, mmgr) {}
MbString (const qse_mchar_t* str, qse_size_t size, Mmgr* mmgr = QSE_NULL): ParentType(str, size, mmgr) {}
MbString (qse_mchar_t c, qse_size_t size, Mmgr* mmgr = QSE_NULL): ParentType(c, size, mmgr) {}
MbString (const MbString& str): ParentType(str) {}
MbString (const ParentType& str): ParentType(str) {}
#if defined(QSE_CPP_ENABLE_CPP11_MOVE)
MbString (MbString&& str): ParentType(QSE_CPP_RVREF(str)) {}
MbString (ParentType&& str): ParentType(QSE_CPP_RVREF(str)) {} // added for ParentType returned in some methods defined in ParentType. e.g. getSubstring()
#endif
MbString& operator= (const MbString& str) { ParentType::operator=(str); return *this; }
MbString& operator= (const ParentType& str) { ParentType::operator=(str); return *this; }
#if defined(QSE_CPP_ENABLE_CPP11_MOVE)
MbString& operator= (MbString&& str) { ParentType::operator=(QSE_CPP_RVREF(str)); return *this; }
MbString& operator= (ParentType&& str) { ParentType::operator=(QSE_CPP_RVREF(str)); return *this; } // added for ParentType returned in some methods defined in ParentType. e.g. getSubstring()
#endif
MbString& operator= (const qse_mchar_t* str) { ParentType::operator=(str); return *this; }
MbString& operator= (const qse_mchar_t c) { ParentType::operator=(c); return *this; }
//using ParentType::operator=;
int format (const qse_mchar_t* fmt, ...);
int formatv (const qse_mchar_t* fmt, va_list ap);
};
class WcPtrString: public PtrStrBase<qse_wchar_t, QSE_MT('\0'), WcStringOpset>
{
private:
typedef PtrStrBase<qse_wchar_t, QSE_MT('\0'), WcStringOpset> ParentType;
public:
WcPtrString () {}
WcPtrString (const qse_wchar_t* ptr): ParentType(ptr) {}
WcPtrString (const qse_wchar_t* ptr, qse_size_t len): ParentType(ptr, len) {}
};
class MbPtrString: public PtrStrBase<qse_mchar_t, QSE_MT('\0'), MbStringOpset>
{
private:
typedef PtrStrBase<qse_mchar_t, QSE_MT('\0'), MbStringOpset> ParentType;
public:
MbPtrString () {}
MbPtrString (const qse_mchar_t* ptr): ParentType(ptr) {}
MbPtrString (const qse_mchar_t* ptr, qse_size_t len): ParentType(ptr, len) {}
};
#if defined(QSE_CHAR_IS_MCHAR)
typedef MbString String;
typedef MbPtrString PtrString;
#else
typedef WcString String;
typedef WcPtrString PtrString;
#endif
/////////////////////////////////
QSE_END_NAMESPACE(QSE)
/////////////////////////////////
#endif

View File

@@ -0,0 +1,46 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_TRANSMITTABLE_CLASS_
#define _QSE_CMN_TRANSMITTABLE_CLASS_
#include <qse/cmn/time.h>
QSE_BEGIN_NAMESPACE(QSE)
class Transmittable
{
public:
virtual ~Transmittable() QSE_CPP_NOEXCEPT {}
virtual qse_ssize_t send (const void* buf, qse_size_t len) QSE_CPP_NOEXCEPT = 0;
virtual qse_ssize_t receive (void* buf, qse_size_t len) QSE_CPP_NOEXCEPT = 0;
};
QSE_END_NAMESPACE(QSE)
#endif

248
include/qse/cmn/alg.h Normal file
View File

@@ -0,0 +1,248 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_ALG_H_
#define _QSE_ALG_H_
/** \file
* This file provides functions for commonly used algorithms.
*/
#if defined(macintosh)
# include <:qse:types.h>
# include <:qse:macros.h>
#else
# include <qse/types.h>
# include <qse/macros.h>
#endif
/**
* The qse_search_comper_t type defines a search callback function.
* The callback function is called by search functions for each comparison
* performed. It should return 0 if \a ptr1 and \a ptr2 are
* euqal, a positive integer if \a ptr1 is greater than \a ptr2, a negative
* if \a ptr2 is greater than \a ptr1. Both \a ptr1 and \a ptr2 are
* pointers to any two items in the array. \a ctx which is a pointer to
* user-defined data passed to a search function is passed to the callback
* with no modification.
*/
typedef int (*qse_search_comper_t) (
const void* ptr1,
const void* ptr2,
void* ctx
);
/**
* The qse_search_comperx_t type defines a search callback function.
* It should return 0 on success and -1 on failure. the comparsion
* result must be put back into the variable pointed to by \a cv.
*/
typedef int (*qse_search_comperx_t) (
const void* ptr1,
const void* ptr2,
void* ctx,
int * cv
);
/**
* The qse_sort_comper_t type defines a sort callback function.
*/
typedef qse_search_comper_t qse_sort_comper_t;
typedef qse_search_comperx_t qse_sort_comperx_t;
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The qse_bsearch() function performs binary search over a sorted array.
* It looks for an item matching \a key in an array \a base containing
* \a nmemb items each of which is as large as \a size. The comparison
* function \a comper is invoked with \a key as the first parameter and
* an item being tested as the second parameter. The \a ctx parameter is
* passed to \a comper as the third parameter.
*
* See the example below:
* \code
* static int compstr (const void* s1, const void* s2, void* ctx)
* {
* return qse_strcmp ((const qse_char_t*)s1, *(const qse_char_t**)s2);
* }
* int find (const qse_char_t* name)
* {
* static const qse_char_t* tgtnames[] =
* {
* QSE_T("awk"),
* QSE_T("cut"),
* QSE_T("ls"),
* QSE_T("rm"),
* QSE_T("sed"),
* QSE_T("tr"),
* QSE_T("watch")
* };
*
* const qse_char_t** ptr;
* ptr = (const qse_char_t**) qse_bsearch (
* name, tgtnames, QSE_COUNTOF(tgtnames),
* QSE_SIZEOF(qse_char_t*), QSE_NULL, compstr
* );
* return ptr? (ptr - tgtnames): -1;
* }
* \endcode
*/
QSE_EXPORT void* qse_bsearch (
const void* key,
const void* base,
qse_size_t nmemb,
qse_size_t size,
qse_search_comper_t comper,
void* ctx
);
/**
* The qse_lsearch() function performs linear search over an array.
*/
QSE_EXPORT void* qse_lsearch (
const void* key,
const void* base,
qse_size_t nmemb,
qse_size_t size,
qse_search_comper_t comper,
void* ctx
);
/**
* The qse_qsort() function performs quick-sorting over an array.
*/
QSE_EXPORT void qse_qsort (
void* base,
qse_size_t nmemb,
qse_size_t size,
qse_sort_comper_t comper,
void* ctx
);
QSE_EXPORT int qse_qsortx (
void* base,
qse_size_t nmemb,
qse_size_t size,
qse_sort_comperx_t comper,
void* ctx
);
/**
* The qse_rand31() function implements Park-Miller's minimal standard
* 32 bit pseudo-random number generator.
*/
QSE_EXPORT qse_uint32_t qse_rand31 (
qse_uint32_t seed
);
#if (QSE_SIZEOF_UINT32_T > 0)
/**
* The qse_randxs32() function implements the xorshift random number generator
* by George Marsaglia.
*/
QSE_EXPORT qse_uint32_t qse_randxs32 (
qse_uint32_t seed
);
#endif
#if (QSE_SIZEOF_UINT64_T > 0)
/**
* The qse_randxs64() function implements the xorshift random number generator
* by George Marsaglia.
*/
QSE_EXPORT qse_uint64_t qse_randxs64 (
qse_uint64_t seed
);
#endif
#if (QSE_SIZEOF_UINT128_T > 0)
/**
* The qse_randxs128() function implements the xorshift random number generator
* by George Marsaglia.
*/
QSE_EXPORT qse_uint128_t qse_randxs128 (
qse_uint128_t seed
);
#endif
#if (QSE_SIZEOF_ULONG_T == QSE_SIZEOF_UINT128_T)
# define qse_randxsulong(seed) qse_randxs128(seed)
#elif (QSE_SIZEOF_ULONG_T == QSE_SIZEOF_UINT64_T)
# define qse_randxsulong(seed) qse_randxs64(seed)
#elif (QSE_SIZEOF_ULONG_T == QSE_SIZEOF_UINT32_T)
# define qse_randxsulong(seed) qse_randxs32(seed)
#else
# error Unsupported
#endif
#if (QSE_SIZEOF_UINT_T == QSE_SIZEOF_UINT128_T)
# define qse_randxsuint(seed) qse_randxs128(seed)
#elif (QSE_SIZEOF_UINT_T == QSE_SIZEOF_UINT64_T)
# define qse_randxsuint(seed) qse_randxs64(seed)
#elif (QSE_SIZEOF_UINT_T == QSE_SIZEOF_UINT32_T)
# define qse_randxsuint(seed) qse_randxs32(seed)
#else
# error Unsupported
#endif
#if (QSE_SIZEOF_UINTMAX_T == QSE_SIZEOF_UINT128_T)
# define qse_randxsuintmax(seed) qse_randxs128(seed)
#elif (QSE_SIZEOF_UINTMAX_T == QSE_SIZEOF_UINT64_T)
# define qse_randxsuintmax(seed) qse_randxs64(seed)
#elif (QSE_SIZEOF_UINTMAX_T == QSE_SIZEOF_UINT32_T)
# define qse_randxsuintmax(seed) qse_randxs32(seed)
#else
# error Unsupported
#endif
QSE_EXPORT qse_size_t qse_enbase64 (
const void* in,
qse_size_t isz,
qse_mchar_t* out,
qse_size_t osz,
qse_size_t* xsz
);
QSE_EXPORT qse_size_t qse_debase64 (
const qse_mchar_t* in,
qse_size_t isz,
void* out,
qse_size_t osz,
qse_size_t* xsz
);
#if defined(__cplusplus)
}
#endif
#endif

485
include/qse/cmn/arr.h Normal file
View File

@@ -0,0 +1,485 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_ARR_H_
#define _QSE_CMN_ARR_H_
#include <qse/types.h>
#include <qse/macros.h>
/** @file
* This file provides a linear dynamic array. It grows dynamically as items
* are added.
*/
enum qse_arr_walk_t
{
QSE_ARR_WALK_STOP = 0,
QSE_ARR_WALK_FORWARD = 1,
QSE_ARR_WALK_BACKWARD = 2
};
typedef struct qse_arr_t qse_arr_t;
typedef struct qse_arr_slot_t qse_arr_slot_t;
typedef enum qse_arr_walk_t qse_arr_walk_t;
#define QSE_ARR_COPIER_SIMPLE ((qse_arr_copier_t)1)
#define QSE_ARR_COPIER_INLINE ((qse_arr_copier_t)2)
#define QSE_ARR_NIL ((qse_size_t)-1)
#define QSE_ARR_SIZE(arr) (*(const qse_size_t*)&(arr)->size)
#define QSE_ARR_CAPA(arr) (*(const qse_size_t*)&(arr)->capa)
#define QSE_ARR_SLOT(arr,index) ((arr)->slot[index])
#define QSE_ARR_DPTL(arr,index) ((const qse_xptl_t*)&(arr)->slot[index]->val)
#define QSE_ARR_DPTR(arr,index) ((arr)->slot[index]->val.ptr)
#define QSE_ARR_DLEN(arr,index) ((arr)->slot[index]->val.len)
/**
* The qse_arr_copier_t type defines a callback function for slot construction.
* A slot is contructed when a user adds data to an array. The user can
* define how the data to add can be maintained in the array. A dynamic
* array not specified with any copiers stores the data pointer and
* the data length into a slot. A special copier QSE_ARR_COPIER_INLINE copies
* the contents of the data a user provided into the slot. You can use the
* qse_arr_setcopier() function to change the copier.
*
* A copier should return the pointer to the copied data. If it fails to copy
* data, it may return QSE_NULL. You need to set a proper freeer to free up
* memory allocated for copy.
*/
typedef void* (*qse_arr_copier_t) (
qse_arr_t* arr /**< array */,
void* dptr /**< pointer to data to copy */,
qse_size_t dlen /**< length of data to copy */
);
/**
* The qse_arr_freeer_t type defines a slot destruction callback.
*/
typedef void (*qse_arr_freeer_t) (
qse_arr_t* arr /**< array */,
void* dptr /**< pointer to data to free */,
qse_size_t dlen /**< length of data to free */
);
/**
* The qse_arr_comper_t type defines a key comparator that is called when
* the arry needs to compare data. A linear dynamic array is created with a
* default comparator that performs bitwise comparison.
*
* The default comparator compares data in a memcmp-like fashion.
* It is not suitable when you want to implement a heap of numbers
* greater than a byte size. You must implement a comparator that
* takes the whole element and performs comparison in such a case.
*
* The comparator should return 0 if the data are the same, a negative
* integer if the first data is less than the second data, a positive
* integer otherwise.
*
*/
typedef int (*qse_arr_comper_t) (
qse_arr_t* arr /* array */,
const void* dptr1 /* data pointer */,
qse_size_t dlen1 /* data length */,
const void* dptr2 /* data pointer */,
qse_size_t dlen2 /* data length */
);
/**
* The qse_arr_keeper_t type defines a value keeper that is called when
* a value is retained in the context that it should be destroyed because
* it is identical to a new value. Two values are identical if their beginning
* pointers and their lengths are equal.
*/
typedef void (*qse_arr_keeper_t) (
qse_arr_t* arr /**< array */,
void* vptr /**< pointer to a value */,
qse_size_t vlen /**< length of a value */
);
/**
* The qse_arr_sizer_t type defines an array size claculator that is called
* when the array needs to be resized.
*/
typedef qse_size_t (*qse_arr_sizer_t) (
qse_arr_t* arr, /**< array */
qse_size_t hint /**< sizing hint */
);
typedef qse_arr_walk_t (*qse_arr_walker_t) (
qse_arr_t* arr /* array */,
qse_size_t index /* index to the visited slot */,
void* ctx /* user-defined context */
);
/**
* The qse_arr_t type defines a linear dynamic array.
*/
struct qse_arr_t
{
qse_mmgr_t* mmgr;
qse_arr_copier_t copier; /* data copier */
qse_arr_freeer_t freeer; /* data freeer */
qse_arr_comper_t comper; /* data comparator */
qse_arr_keeper_t keeper; /* data keeper */
qse_arr_sizer_t sizer; /* size calculator */
qse_byte_t scale; /* scale factor */
qse_size_t heap_pos_offset; /* offset in the data element where position
* is stored when heap operation is performed. */
qse_size_t size; /* number of items */
qse_size_t capa; /* capacity */
qse_arr_slot_t** slot;
};
/**
* The qse_arr_slot_t type defines a linear dynamic array slot
*/
struct qse_arr_slot_t
{
qse_xptl_t val;
};
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The qse_arr_open() function creates a linear dynamic array.
*/
QSE_EXPORT qse_arr_t* qse_arr_open (
qse_mmgr_t* mmgr, /**< memory manager */
qse_size_t ext, /**< extension size in bytes */
qse_size_t capa /**< initial array capacity */
);
/**
* The qse_arr_close() function destroys a linear dynamic array.
*/
QSE_EXPORT void qse_arr_close (
qse_arr_t* arr /**< array */
);
/**
* The qse_arr_init() function initializes a linear dynamic array.
*/
QSE_EXPORT int qse_arr_init (
qse_arr_t* arr,
qse_mmgr_t* mmgr,
qse_size_t capa
);
/**
* The qse_arr_fini() function finalizes a linear dynamic array.
*/
QSE_EXPORT void qse_arr_fini (
qse_arr_t* arr /**< array */
);
QSE_EXPORT qse_mmgr_t* qse_arr_getmmgr (
qse_arr_t* arr
);
QSE_EXPORT void* qse_arr_getxtn (
qse_arr_t* arr
);
/**
* The qse_arr_getscale() function returns the scale factor
*/
QSE_EXPORT int qse_arr_getscale (
qse_arr_t* arr /**< array */
);
/**
* The qse_arr_setscale() function sets the scale factor of the length
* of a key and a value. A scale factor determines the actual length of
* a key and a value in bytes. A arr is created with a scale factor of 1.
* The scale factor should be larger than 0 and less than 256.
* It is a bad idea to change the scale factor when @a arr is not empty.
*/
QSE_EXPORT void qse_arr_setscale (
qse_arr_t* arr /**< array */,
int scale /**< scale factor - 1 to 255 */
);
QSE_EXPORT qse_arr_copier_t qse_arr_getcopier (
qse_arr_t* arr /* array */
);
/**
* The qse_arr_setcopier() specifies how to clone an element. The special
* copier #QSE_ARR_COPIER_INLINE copies the data inline to the internal slot.
* No freeer is invoked when the slot is freeed. You may set the copier to
* #QSE_ARR_COPIER_SIMPLE to perform no special operation when the data
* pointer is stored.
*/
QSE_EXPORT void qse_arr_setcopier (
qse_arr_t* arr /** arr */,
qse_arr_copier_t copier /** element copier */
);
/**
* The qse_arr_getfreeer() function returns a custom element destroyer.
*/
QSE_EXPORT qse_arr_freeer_t qse_arr_getfreeer (
qse_arr_t* arr /**< arr */
);
/**
* The qse_arr_setfreeer() function specifies how to destroy an element.
* The @a freeer is called when a slot containing the element is destroyed.
*/
QSE_EXPORT void qse_arr_setfreeer (
qse_arr_t* arr /**< arr */,
qse_arr_freeer_t freeer /**< element freeer */
);
QSE_EXPORT qse_arr_comper_t qse_arr_getcomper (
qse_arr_t* arr /**< arr */
);
/**
* The qse_arr_setcomper() function specifies how to compare two elements
* for equality test. The comparator @a comper must return 0 if two elements
* compared are equal, 1 if the first element is greater than the
* second, -1 if the second element is greater than the first.
*/
QSE_EXPORT void qse_arr_setcomper (
qse_arr_t* arr /**< arr */,
qse_arr_comper_t comper /**< comparator */
);
QSE_EXPORT qse_arr_keeper_t qse_arr_getkeeper (
qse_arr_t* arr
);
QSE_EXPORT void qse_arr_setkeeper (
qse_arr_t* arr,
qse_arr_keeper_t keeper
);
QSE_EXPORT qse_arr_sizer_t qse_arr_getsizer (
qse_arr_t* arr
);
QSE_EXPORT void qse_arr_setsizer (
qse_arr_t* arr,
qse_arr_sizer_t sizer
);
QSE_EXPORT qse_size_t qse_arr_getsize (
qse_arr_t* arr
);
QSE_EXPORT qse_size_t qse_arr_getcapa (
qse_arr_t* arr
);
QSE_EXPORT qse_arr_t* qse_arr_setcapa (
qse_arr_t* arr,
qse_size_t capa
);
QSE_EXPORT qse_size_t qse_arr_search (
qse_arr_t* arr,
qse_size_t pos,
const void* dptr,
qse_size_t dlen
);
QSE_EXPORT qse_size_t qse_arr_rsearch (
qse_arr_t* arr,
qse_size_t pos,
const void* dptr,
qse_size_t dlen
);
QSE_EXPORT qse_size_t qse_arr_upsert (
qse_arr_t* arr,
qse_size_t index,
void* dptr,
qse_size_t dlen
);
QSE_EXPORT qse_size_t qse_arr_insert (
qse_arr_t* arr,
qse_size_t index,
void* dptr,
qse_size_t dlen
);
QSE_EXPORT qse_size_t qse_arr_update (
qse_arr_t* arr,
qse_size_t pos,
void* dptr,
qse_size_t dlen
);
/**
* The qse_arr_delete() function deletes the as many data as the count
* from the index. It returns the number of data deleted.
*/
QSE_EXPORT qse_size_t qse_arr_delete (
qse_arr_t* arr,
qse_size_t index,
qse_size_t count
);
/**
* The qse_arr_uplete() function deletes data slot without compaction.
* It returns the number of data affected.
*/
QSE_EXPORT qse_size_t qse_arr_uplete (
qse_arr_t* arr,
qse_size_t index,
qse_size_t count
);
QSE_EXPORT void qse_arr_clear (
qse_arr_t* arr
);
/**
* The qse_arr_walk() function calls the @a walker function for each
* element in the array beginning from the first. The @a walker function
* should return one of #QSE_ARR_WALK_FORWARD, #QSE_ARR_WALK_BACKWARD,
* #QSE_ARR_WALK_STOP.
* @return number of calls to the @a walker fucntion made
*/
QSE_EXPORT qse_size_t qse_arr_walk (
qse_arr_t* arr,
qse_arr_walker_t walker,
void* ctx
);
/**
* The qse_arr_rwalk() function calls the @a walker function for each
* element in the array beginning from the last. The @a walker function
* should return one of #QSE_ARR_WALK_FORWARD, #QSE_ARR_WALK_BACKWARD,
* #QSE_ARR_WALK_STOP.
* @return number of calls to the @a walker fucntion made
*/
QSE_EXPORT qse_size_t qse_arr_rwalk (
qse_arr_t* arr,
qse_arr_walker_t walker,
void* ctx
);
/**
* The qse_arr_pushstack() function appends data to the array. It is a utility
* function to allow stack-like operations over an array. To do so, you should
* not play with other non-stack related functions.
*/
QSE_EXPORT qse_size_t qse_arr_pushstack (
qse_arr_t* arr,
void* dptr,
qse_size_t dlen
);
/**
* The qse_arr_popstack() function deletes the last array data. It is a utility
* function to allow stack-like operations over an array. To do so, you should
* not play with other non-stack related functions.
* @note You must not call this function if @a arr is empty.
*/
QSE_EXPORT void qse_arr_popstack (
qse_arr_t* arr
);
/**
* The qse_arr_pushheap() function inserts data to an array while keeping the
* largest data at position 0. It is a utiltiy funtion to implement a binary
* max-heap over an array. Inverse the comparator to implement a min-heap.
* @return number of array elements
* @note You must not mess up the array with other non-heap related functions
* to keep the heap property.
*/
QSE_EXPORT qse_size_t qse_arr_pushheap (
qse_arr_t* arr,
void* dptr,
qse_size_t dlen
);
/**
* The qse_arr_popheap() function deletes data at position 0 while keeping
* the largest data at positon 0. It is a utiltiy funtion to implement a binary
* max-heap over an array.
* @note You must not mess up the array with other non-heap related functions
* to keep the heap property.
*/
QSE_EXPORT void qse_arr_popheap (
qse_arr_t* arr
);
QSE_EXPORT void qse_arr_deleteheap (
qse_arr_t* arr,
qse_size_t index
);
QSE_EXPORT qse_size_t qse_arr_updateheap (
qse_arr_t* arr,
qse_size_t index,
void* dptr,
qse_size_t dlen
);
QSE_EXPORT qse_size_t qse_arr_getheapposoffset (
qse_arr_t* arr
);
/**
* The qse_arr_setheapposoffset() function sets the offset to a position holding
* field within a data element. It assumes that the field is of the qse_size_t type.
*
* \code
* struct data_t
* {
* int v;
* qse_size_t pos;
* };
* struct data_t d;
* qse_arr_setheapposoffset (arr, QSE_OFFSETOF(struct data_t, pos));
* d.v = 20;
* qse_arr_pushheap (arr, &d, 1);
* \endcode
*
* In the code above, the 'pos' field of the first element in the array must be 0.
*
* If it's set to QSE_ARR_NIL, position is not updated when heapification is
* performed.
*/
QSE_EXPORT void qse_arr_setheapposoffset (
qse_arr_t* arr,
qse_size_t offset
);
#if defined(__cplusplus)
}
#endif
#endif

233
include/qse/cmn/chr.h Normal file
View File

@@ -0,0 +1,233 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_CHR_H_
#define _QSE_CMN_CHR_H_
/** @file
* This file provides functions, types, macros for character handling.
*/
#include <qse/types.h>
#include <qse/macros.h>
/**
* The qse_ctype_t type defines character class types.
*/
enum qse_ctype_t
{
QSE_CTYPE_ALNUM = 1,
QSE_CTYPE_ALPHA,
QSE_CTYPE_BLANK,
QSE_CTYPE_CNTRL,
QSE_CTYPE_DIGIT,
QSE_CTYPE_GRAPH,
QSE_CTYPE_LOWER,
QSE_CTYPE_PRINT,
QSE_CTYPE_PUNCT,
QSE_CTYPE_SPACE,
QSE_CTYPE_UPPER,
QSE_CTYPE_XDIGIT
};
typedef enum qse_ctype_t qse_ctype_t;
typedef qse_ctype_t qse_mctype_t;
typedef qse_ctype_t qse_wctype_t;
#define QSE_MCTYPE_UPPER QSE_CTYPE_UPPER
#define QSE_MCTYPE_LOWER QSE_CTYPE_LOWER
#define QSE_MCTYPE_ALPHA QSE_CTYPE_ALPHA
#define QSE_MCTYPE_DIGIT QSE_CTYPE_DIGIT
#define QSE_MCTYPE_XDIGIT QSE_CTYPE_XDIGIT
#define QSE_MCTYPE_ALNUM QSE_CTYPE_ALNUM
#define QSE_MCTYPE_SPACE QSE_CTYPE_SPACE
#define QSE_MCTYPE_PRINT QSE_CTYPE_PRINT
#define QSE_MCTYPE_GRAPH QSE_CTYPE_GRAPH
#define QSE_MCTYPE_CNTRL QSE_CTYPE_CNTRL
#define QSE_MCTYPE_PUNCT QSE_CTYPE_PUNCT
#define QSE_MCTYPE_BLANK QSE_CTYPE_BLANK
#define QSE_WCTYPE_UPPER QSE_CTYPE_UPPER
#define QSE_WCTYPE_LOWER QSE_CTYPE_LOWER
#define QSE_WCTYPE_ALPHA QSE_CTYPE_ALPHA
#define QSE_WCTYPE_DIGIT QSE_CTYPE_DIGIT
#define QSE_WCTYPE_XDIGIT QSE_CTYPE_XDIGIT
#define QSE_WCTYPE_ALNUM QSE_CTYPE_ALNUM
#define QSE_WCTYPE_SPACE QSE_CTYPE_SPACE
#define QSE_WCTYPE_PRINT QSE_CTYPE_PRINT
#define QSE_WCTYPE_GRAPH QSE_CTYPE_GRAPH
#define QSE_WCTYPE_CNTRL QSE_CTYPE_CNTRL
#define QSE_WCTYPE_PUNCT QSE_CTYPE_PUNCT
#define QSE_WCTYPE_BLANK QSE_CTYPE_BLANK
#define QSE_MCTYPE(name) (qse_getmctype(name))
#define QSE_ISMCTYPE(c,t) (qse_ismctype(c,t))
#define QSE_ISMALNUM(c) (qse_ismctype(c,QSE_CTYPE_ALNUM))
#define QSE_ISMALPHA(c) (qse_ismctype(c,QSE_CTYPE_ALPHA))
#define QSE_ISMBLANK(c) (qse_ismctype(c,QSE_CTYPE_BLANK))
#define QSE_ISMCNTRL(c) (qse_ismctype(c,QSE_CTYPE_CNTRL))
#define QSE_ISMDIGIT(c) (qse_ismctype(c,QSE_CTYPE_DIGIT))
#define QSE_ISMGRAPH(c) (qse_ismctype(c,QSE_CTYPE_GRAPH))
#define QSE_ISMLOWER(c) (qse_ismctype(c,QSE_CTYPE_LOWER))
#define QSE_ISMPRINT(c) (qse_ismctype(c,QSE_CTYPE_PRINT))
#define QSE_ISMPUNCT(c) (qse_ismctype(c,QSE_CTYPE_PUNCT))
#define QSE_ISMSPACE(c) (qse_ismctype(c,QSE_CTYPE_SPACE))
#define QSE_ISMUPPER(c) (qse_ismctype(c,QSE_CTYPE_UPPER))
#define QSE_ISMXDIGIT(c) (qse_ismctype(c,QSE_CTYPE_XDIGIT))
#define QSE_TOMUPPER(c) (qse_tomctype(c,QSE_CTYPE_UPPER))
#define QSE_TOMLOWER(c) (qse_tomctype(c,QSE_CTYPE_LOWER))
#define QSE_WCTYPE(name) (qse_getwctype(name))
#define QSE_ISWCTYPE(c,t) (qse_iswctype(c,t))
#define QSE_ISWALNUM(c) (qse_iswctype(c,QSE_CTYPE_ALNUM))
#define QSE_ISWALPHA(c) (qse_iswctype(c,QSE_CTYPE_ALPHA))
#define QSE_ISWBLANK(c) (qse_iswctype(c,QSE_CTYPE_BLANK))
#define QSE_ISWCNTRL(c) (qse_iswctype(c,QSE_CTYPE_CNTRL))
#define QSE_ISWDIGIT(c) (qse_iswctype(c,QSE_CTYPE_DIGIT))
#define QSE_ISWGRAPH(c) (qse_iswctype(c,QSE_CTYPE_GRAPH))
#define QSE_ISWLOWER(c) (qse_iswctype(c,QSE_CTYPE_LOWER))
#define QSE_ISWPRINT(c) (qse_iswctype(c,QSE_CTYPE_PRINT))
#define QSE_ISWPUNCT(c) (qse_iswctype(c,QSE_CTYPE_PUNCT))
#define QSE_ISWSPACE(c) (qse_iswctype(c,QSE_CTYPE_SPACE))
#define QSE_ISWUPPER(c) (qse_iswctype(c,QSE_CTYPE_UPPER))
#define QSE_ISWXDIGIT(c) (qse_iswctype(c,QSE_CTYPE_XDIGIT))
#define QSE_TOWUPPER(c) (qse_towctype(c,QSE_CTYPE_UPPER))
#define QSE_TOWLOWER(c) (qse_towctype(c,QSE_CTYPE_LOWER))
#ifdef QSE_CHAR_IS_MCHAR
# define QSE_CTYPE(name) QSE_MCTYPE(name)
# define QSE_ISCTYPE(c,t) QSE_ISMCTYPE(c,t)
# define QSE_ISUPPER(c) QSE_ISMUPPER(c)
# define QSE_ISLOWER(c) QSE_ISMLOWER(c)
# define QSE_ISALPHA(c) QSE_ISMALPHA(c)
# define QSE_ISDIGIT(c) QSE_ISMDIGIT(c)
# define QSE_ISXDIGIT(c) QSE_ISMXDIGIT(c)
# define QSE_ISALNUM(c) QSE_ISMALNUM(c)
# define QSE_ISSPACE(c) QSE_ISMSPACE(c)
# define QSE_ISPRINT(c) QSE_ISMPRINT(c)
# define QSE_ISGRAPH(c) QSE_ISMGRAPH(c)
# define QSE_ISCNTRL(c) QSE_ISMCNTRL(c)
# define QSE_ISPUNCT(c) QSE_ISMPUNCT(c)
# define QSE_ISBLANK(c) QSE_ISMBLANK(c)
# define QSE_TOUPPER(c) QSE_TOMUPPER(c)
# define QSE_TOLOWER(c) QSE_TOMLOWER(c)
#else
# define QSE_CTYPE(name) QSE_WCTYPE(name)
# define QSE_ISCTYPE(c,t) QSE_ISWCTYPE(c,t)
# define QSE_ISUPPER(c) QSE_ISWUPPER(c)
# define QSE_ISLOWER(c) QSE_ISWLOWER(c)
# define QSE_ISALPHA(c) QSE_ISWALPHA(c)
# define QSE_ISDIGIT(c) QSE_ISWDIGIT(c)
# define QSE_ISXDIGIT(c) QSE_ISWXDIGIT(c)
# define QSE_ISALNUM(c) QSE_ISWALNUM(c)
# define QSE_ISSPACE(c) QSE_ISWSPACE(c)
# define QSE_ISPRINT(c) QSE_ISWPRINT(c)
# define QSE_ISGRAPH(c) QSE_ISWGRAPH(c)
# define QSE_ISCNTRL(c) QSE_ISWCNTRL(c)
# define QSE_ISPUNCT(c) QSE_ISWPUNCT(c)
# define QSE_ISBLANK(c) QSE_ISWBLANK(c)
# define QSE_TOUPPER(c) QSE_TOWUPPER(c)
# define QSE_TOLOWER(c) QSE_TOWLOWER(c)
#endif
#define QSE_XDIGITTONUM(c) \
(((c) >= QSE_T('0') && (c) <= QSE_T('9'))? ((c) - QSE_T('0')): \
((c) >= QSE_T('A') && (c) <= QSE_T('F'))? ((c) - QSE_T('A') + 10): \
((c) >= QSE_T('a') && (c) <= QSE_T('f'))? ((c) - QSE_T('a') + 10): -1)
#define QSE_MXDIGITTONUM(c) \
(((c) >= QSE_MT('0') && (c) <= QSE_MT('9'))? ((c) - QSE_MT('0')): \
((c) >= QSE_MT('A') && (c) <= QSE_MT('F'))? ((c) - QSE_MT('A') + 10): \
((c) >= QSE_MT('a') && (c) <= QSE_MT('f'))? ((c) - QSE_MT('a') + 10): -1)
#define QSE_WXDIGITTONUM(c) \
(((c) >= QSE_WT('0') && (c) <= QSE_WT('9'))? ((c) - QSE_WT('0')): \
((c) >= QSE_WT('A') && (c) <= QSE_WT('F'))? ((c) - QSE_WT('A') + 10): \
((c) >= QSE_WT('a') && (c) <= QSE_WT('f'))? ((c) - QSE_WT('a') + 10): -1)
#if defined(__cplusplus)
extern "C" {
#endif
QSE_EXPORT int qse_ismctype (
qse_mcint_t c,
qse_mctype_t type
);
QSE_EXPORT int qse_iswctype (
qse_wcint_t c,
qse_wctype_t type
);
QSE_EXPORT qse_mcint_t qse_tomctype (
qse_mcint_t c,
qse_mctype_t type
);
QSE_EXPORT qse_wcint_t qse_towctype (
qse_wcint_t c,
qse_wctype_t type
);
QSE_EXPORT int qse_mbstoctype (
const qse_mchar_t* name,
qse_mctype_t* id
);
QSE_EXPORT int qse_mbsntoctype (
const qse_mchar_t* name,
qse_size_t len,
qse_mctype_t* id
);
QSE_EXPORT int qse_wcstoctype (
const qse_wchar_t* name,
qse_wctype_t* id
);
QSE_EXPORT int qse_wcsntoctype (
const qse_wchar_t* name,
qse_size_t len,
qse_wctype_t* id
);
#if defined(QSE_CHAR_IS_MCHAR)
# define qse_isctype(c,type) qse_ismctype(c,type)
# define qse_toctype(c,type) qse_ismctype(c,type)
# define qse_strtoctype(name,id) qse_mbstoctype(name,id)
# define qse_strntoctype(name,len,id) qse_mbsntoctype(name,len,id)
#else
# define qse_isctype(c,type) qse_iswctype(c,type)
# define qse_toctype(c,type) qse_towctype(c,type)
# define qse_strtoctype(name,id) qse_wcstoctype(name,id)
# define qse_strntoctype(name,len,id) qse_wcsntoctype(name,len,id)
#endif
#if defined(__cplusplus)
}
#endif
#endif

109
include/qse/cmn/cp949.h Normal file
View File

@@ -0,0 +1,109 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_CP949_H_
#define _QSE_CMN_CP949_H_
#include <qse/types.h>
#include <qse/macros.h>
/** @file
* This file provides functions, types, macros for cp949 conversion.
*/
/**
* The QSE_CP949LEN_MAX macro defines the maximum number of bytes
* needed to form a single unicode character.
*/
#define QSE_CP949LEN_MAX 2
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The qse_uctocp949() function converts a unicode character to a cp949 sequence.
* @return
* - 0 is returned if @a uc is invalid.
* - An integer greater than @a size is returned if the @a cp949 sequence buffer
* is not #QSE_NULL and not large enough. This integer is actually the number
* of bytes needed.
* - If @a cp949 is #QSE_NULL, the number of bytes that would have been stored
* into @a cp949 if it had not been #QSE_NULL is returned.
* - An integer between 1 and size inclusive is returned in all other cases.
* @note
* This function doesn't check invalid unicode code points and performs
* conversion compuationally.
*/
QSE_EXPORT qse_size_t qse_uctocp949 (
qse_wchar_t uc,
qse_mchar_t* cp949,
qse_size_t size
);
/**
* The qse_cp949touc() function converts a cp949 sequence to a unicode character.
* @return
* - 0 is returned if the @a cp949 sequence is invalid.
* - An integer greater than @a size is returned if the @a cp949 sequence is
* not complete.
* - An integer between 1 and size inclusive is returned in all other cases.
*/
QSE_EXPORT qse_size_t qse_cp949touc (
const qse_mchar_t* cp949,
qse_size_t size,
qse_wchar_t* uc
);
/**
* The qse_cp949lenmax() function scans at most @a size bytes from the @a cp949
* sequence and returns the number of bytes needed to form a single unicode
* character.
* @return
* - 0 is returned if the @a cp949 sequence is invalid.
* - An integer greater than @a size is returned if the @a cp949 sequence is
* not complete.
* - An integer between 1 and size inclusive is returned in all other cases.
*/
QSE_EXPORT qse_size_t qse_cp949len (
const qse_mchar_t* cp949,
qse_size_t size
);
/**
* The qse_cp949lenmax() function returns the maximum number of bytes needed
* to form a single unicode character. Use #QSE_CP949LEN_MAX if you need a
* compile-time constant.
*/
QSE_EXPORT qse_size_t qse_cp949lenmax (
void
);
#if defined(__cplusplus)
}
#endif
#endif

109
include/qse/cmn/cp950.h Normal file
View File

@@ -0,0 +1,109 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_CP950_H_
#define _QSE_CMN_CP950_H_
#include <qse/types.h>
#include <qse/macros.h>
/** @file
* This file provides functions, types, macros for cp950 conversion.
*/
/**
* The QSE_CP950LEN_MAX macro defines the maximum number of bytes
* needed to form a single unicode character.
*/
#define QSE_CP950LEN_MAX 2
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The qse_uctocp950() function converts a unicode character to a cp950 sequence.
* @return
* - 0 is returned if @a uc is invalid.
* - An integer greater than @a size is returned if the @a cp950 sequence buffer
* is not #QSE_NULL and not large enough. This integer is actually the number
* of bytes needed.
* - If @a cp950 is #QSE_NULL, the number of bytes that would have been stored
* into @a cp950 if it had not been #QSE_NULL is returned.
* - An integer between 1 and size inclusive is returned in all other cases.
* @note
* This function doesn't check invalid unicode code points and performs
* conversion compuationally.
*/
QSE_EXPORT qse_size_t qse_uctocp950 (
qse_wchar_t uc,
qse_mchar_t* cp950,
qse_size_t size
);
/**
* The qse_cp950touc() function converts a cp950 sequence to a unicode character.
* @return
* - 0 is returned if the @a cp950 sequence is invalid.
* - An integer greater than @a size is returned if the @a cp950 sequence is
* not complete.
* - An integer between 1 and size inclusive is returned in all other cases.
*/
QSE_EXPORT qse_size_t qse_cp950touc (
const qse_mchar_t* cp950,
qse_size_t size,
qse_wchar_t* uc
);
/**
* The qse_cp950lenmax() function scans at most @a size bytes from the @a cp950
* sequence and returns the number of bytes needed to form a single unicode
* character.
* @return
* - 0 is returned if the @a cp950 sequence is invalid.
* - An integer greater than @a size is returned if the @a cp950 sequence is
* not complete.
* - An integer between 1 and size inclusive is returned in all other cases.
*/
QSE_EXPORT qse_size_t qse_cp950len (
const qse_mchar_t* cp950,
qse_size_t size
);
/**
* The qse_cp950lenmax() function returns the maximum number of bytes needed
* to form a single unicode character. Use #QSE_CP950LEN_MAX if you need a
* compile-time constant.
*/
QSE_EXPORT qse_size_t qse_cp950lenmax (
void
);
#if defined(__cplusplus)
}
#endif
#endif

344
include/qse/cmn/dll.h Normal file
View File

@@ -0,0 +1,344 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_DLL_H_
#define _QSE_CMN_DLL_H_
/** @file
* This file defines a doubly linked list interface.
*/
#include <qse/types.h>
#include <qse/macros.h>
#include <qse/cmn/gdl.h>
#define QSE_DLL_SIZE(dll) ((const qse_size_t)(dll)->size)
/* ----------- more general implementation below ----------------- */
enum qse_dll_walk_t
{
QSE_DLL_WALK_STOP = 0,
QSE_DLL_WALK_FORWARD = 1,
QSE_DLL_WALK_BACKWARD = 2
};
typedef enum qse_dll_walk_t qse_dll_walk_t;
typedef struct qse_dll_t qse_dll_t;
typedef struct qse_dll_node_t qse_dll_node_t;
/* data copier */
typedef void* (*qse_dll_copier_t) (
qse_dll_t* dll,
void* dptr,
qse_size_t dlen
);
/* data freeer */
typedef void (*qse_dll_freeer_t) (
qse_dll_t* dll,
void* dptr,
qse_size_t dlen
);
/**
* The qse_dll_comper_t type defines a key comparator that is called when
* the list needs to compare data. A doubly linked list is created with a
* default comparator that performs bitwise comparison.
*
* The comparator must return 0 if the data are the same and a non-zero
* integer otherwise.
*/
typedef int (*qse_dll_comper_t) (
qse_dll_t* dll, /**< doubly linked list */
const void* dptr1, /**< data pointer */
qse_size_t dlen1, /**< data length */
const void* dptr2, /**< data pointer */
qse_size_t dlen2 /**< data length */
);
/* node visitor */
typedef qse_dll_walk_t (*qse_dll_walker_t) (
qse_dll_t* dll,
qse_dll_node_t* node,
void* ctx
);
/**
* The qse_dll_node_t type defines a doubly linked list node.
*/
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_gdl_link_t link;
/* data */
qse_xptl_t val;
};
/**
* The qse_dll_t type defines a doubly linked list.
*/
struct qse_dll_t
{
qse_mmgr_t* mmgr;
/*qse_dll_node_t gdl;*/
qse_gdl_t gdl;
qse_size_t size;
qse_byte_t scale;
qse_dll_copier_t copier;
qse_dll_freeer_t freeer;
qse_dll_comper_t comper;
};
#define QSE_DLL_COPIER_SIMPLE ((qse_dll_copier_t)1)
#define QSE_DLL_COPIER_INLINE ((qse_dll_copier_t)2)
#define QSE_DLL_SCALE(dll) ((const int)(dll)->scale)
#define QSE_DLL_DPTR(node) ((node)->val.ptr)
#define QSE_DLL_DLEN(node) ((node)->val.len)
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The qse_dll_open() function creates an empty doubly linked list.
* If the memory manager mmgr is QSE_NULL, the function gets the default
* memory manager with QSE_MMGR_GETMMGR() and uses it if it is not QSE_NULL.
* The extension area is allocated when the positive extension size extension
* is specified. It calls the extension initialization function initializer
* after initializing the main area. The extension initializer is passed
* the pointer to the doubly linked list created.
*
* @return
* the pointer to a newly created doubly linked list on success.
* QSE_NULL on failure.
*/
QSE_EXPORT qse_dll_t* qse_dll_open (
qse_mmgr_t* mmgr, /**< memory manager */
qse_size_t xtnsize /**< size of extension area in bytes */
);
/**
* The qse_dll_close() function destroys a doubly linked list.
*/
QSE_EXPORT void qse_dll_close (
qse_dll_t* dll /** doubly linked list */
);
/**
* The qse_dll_init() function initializes a statically declared list.
*/
QSE_EXPORT int qse_dll_init (
qse_dll_t* dll, /**< doubly linked list */
qse_mmgr_t* mmgr /**< memory manager */
);
/**
* The qse_dll_fini() function finalizes a statically initialized list.
*/
QSE_EXPORT void qse_dll_fini (
qse_dll_t* dll /**< doubly linked list */
);
QSE_EXPORT qse_mmgr_t* qse_dll_getmmgr (
qse_dll_t* dll
);
QSE_EXPORT void* qse_dll_getxtn (
qse_dll_t* dll
);
/**
* The qse_dll_getscale() function gets the scale factor
*/
QSE_EXPORT int qse_dll_getscale (
qse_dll_t* dll /**< doubly linked list */
);
/**
* The qse_dll_setscale() function sets the scale factor of the data length.
* A scale factor determines the actual length of data in bytes. A doubly
* linked list created with a scale factor of 1. The scale factor should be
* larger than 0 and less than 256.
*/
QSE_EXPORT void qse_dll_setscale (
qse_dll_t* dll, /**< doubly linked list */
int scale /**< scale factor */
);
/**
* The qse_dll_setcopier() function changes the element copier.
* A special copier QSE_DLL_COPIER_INLINE is provided. This copier enables
* you to copy the data inline to the internal node. No freeer is invoked
* when the node is freeed. You may set the copier to QSE_NULL to perform
* no special operation when the data pointer is rememebered.
*/
QSE_EXPORT void qse_dll_setcopier (
qse_dll_t* dll, /**< doubly linked list */
qse_dll_copier_t copier /**< element copier */
);
/**
* The qse_dll_getcopier() function returns the element copier.
*/
QSE_EXPORT qse_dll_copier_t qse_dll_getcopier (
qse_dll_t* dll /**< doubly linked list */
);
/**
* The qse_dll_setfreeer() function changes the element freeer.
* The freeer is called when a node containing the element is destroyed.
*/
QSE_EXPORT void qse_dll_setfreeer (
qse_dll_t* dll, /**< doubly linked list */
qse_dll_freeer_t freeer /**< element freeer */
);
/**
* The qse_dll_getfreeer() function returns the element freeer.
*/
QSE_EXPORT qse_dll_freeer_t qse_dll_getfreeer (
qse_dll_t* dll /**< doubly linked list */
);
/**
* The qse_dll_getcomper() function returns the data comparator.
*/
QSE_EXPORT qse_dll_comper_t qse_dll_getcomper (
qse_dll_t* dll /**< doubly linked list */
);
/**
* The qse_dll_setcomper() function changes the data comparator
*/
QSE_EXPORT void qse_dll_setcomper (
qse_dll_t* dll, /**< doubly linked list */
qse_dll_comper_t comper /**< comparator */
);
/**
* The qse_dll_getsize() function returns the number of the data nodes held
* in a doubly linked list.
*/
QSE_EXPORT qse_size_t qse_dll_getsize (
qse_dll_t* dll /**< doubly linked list */
);
/**
* The qse_dll_gethead() function gets the head node. You may use the
* #QSE_DLL_HEAD macro instead.
*/
QSE_EXPORT qse_dll_node_t* qse_dll_gethead (
qse_dll_t* dll /**< doubly linked list */
);
/**
* The qse_dll_gettail() function gets the head node. You may use the
* #QSE_DLL_TAIL macro instead.
*/
QSE_EXPORT qse_dll_node_t* qse_dll_gettail (
qse_dll_t* dll /**< doubly linked list */
);
QSE_EXPORT qse_dll_node_t* qse_dll_search (
qse_dll_t* dll, /**< doubly linked list */
qse_dll_node_t* pos, /**< positional node */
const void* dptr, /**< data pointer */
qse_size_t dlen /**< data length */
);
QSE_EXPORT qse_dll_node_t* qse_dll_rsearch (
qse_dll_t* dll, /**< doubly linked list */
qse_dll_node_t* pos, /**< positional node */
const void* dptr, /**< data pointer */
qse_size_t dlen /**< data length */
);
/**
* The qse_dll_insert() function insert an element into a list
*/
QSE_EXPORT qse_dll_node_t* qse_dll_insert (
qse_dll_t* dll, /**< doubly linked list */
qse_dll_node_t* pos, /**< node before which a new node is inserted */
void* dptr, /**< data pointer */
qse_size_t dlen /**< data length */
);
QSE_EXPORT void qse_dll_delete (
qse_dll_t* dll,
qse_dll_node_t* pos
);
/**
* The qse_dll_clear() functions deletes all elements of a list
*/
QSE_EXPORT void qse_dll_clear (
qse_dll_t* dll /**< doubly linked list */
);
QSE_EXPORT void qse_dll_walk (
qse_dll_t* dll, /**< doubly linked list */
qse_dll_walker_t walker, /**< user-defined walker function */
void* ctx /**< pointer to user-defined data */
);
QSE_EXPORT void qse_dll_rwalk (
qse_dll_t* dll, /**< doubly linked list */
qse_dll_walker_t walker, /**< user-defined walker function */
void* ctx /**< pointer to user-defined data */
);
QSE_EXPORT qse_dll_node_t* qse_dll_pushhead (
qse_dll_t* dll, /* doubly linked list */
void* dptr,
qse_size_t dlen
);
QSE_EXPORT qse_dll_node_t* qse_dll_pushtail (
qse_dll_t* dll, /* doubly linked list */
void* dptr,
qse_size_t dlen
);
QSE_EXPORT void qse_dll_pophead (
qse_dll_t* dll
);
QSE_EXPORT void qse_dll_poptail (
qse_dll_t* dll
);
#if defined(__cplusplus)
}
#endif
#endif

194
include/qse/cmn/env.h Normal file
View File

@@ -0,0 +1,194 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_ENV_H_
#define _QSE_CMN_ENV_H_
#include <qse/types.h>
#include <qse/macros.h>
/** \file
* This file defines data types and functions that you can use to build
* an environment block.
*/
/*
* Note:
* The wprintf function provided by Watcom C doesn't seem to be able to
* print multibyte-characters properly at least on OS2. You may have
* difficulty if you try to print the environment strings with Watcom C.
*/
#if defined(_WIN32) && defined(QSE_CHAR_IS_WCHAR)
typedef qse_wchar_t qse_env_char_t;
# define QSE_ENV_CHAR_IS_WCHAR
# define QSE_SIZEOF_ENV_CHAR_T QSE_SIZEOF_WCHAR_T
#else
typedef qse_mchar_t qse_env_char_t;
# define QSE_ENV_CHAR_IS_MCHAR
# define QSE_SIZEOF_ENV_CHAR_T QSE_SIZEOF_MCHAR_T
#endif
/**
* The qse_env_t type defines a cross-platform environment block.
*/
typedef struct qse_env_t qse_env_t;
struct qse_env_t
{
qse_mmgr_t* mmgr;
struct
{
qse_size_t capa;
qse_size_t len;
qse_env_char_t* ptr;
} str;
struct
{
qse_size_t capa;
qse_size_t len;
qse_env_char_t** ptr;
} arr;
};
#if defined(__cplusplus)
extern "C" {
#endif
QSE_EXPORT qse_env_t* qse_env_open (
qse_mmgr_t* mmgr,
qse_size_t xtnsize,
int fromcurenv
);
QSE_EXPORT void qse_env_close (
qse_env_t* env
);
QSE_EXPORT int qse_env_init (
qse_env_t* env,
qse_mmgr_t* mmgr,
int fromcurenv
);
QSE_EXPORT void qse_env_fini (
qse_env_t* env
);
QSE_EXPORT qse_mmgr_t* qse_env_getmmgr (
qse_env_t* env
);
QSE_EXPORT void* qse_env_getxtn (
qse_env_t* env
);
QSE_EXPORT void qse_env_clear (
qse_env_t* env
);
QSE_EXPORT const qse_env_char_t* qse_env_getstr (
qse_env_t* env
);
QSE_EXPORT qse_env_char_t** qse_env_getarr (
qse_env_t* env
);
/**
* The qse_env_insertwcs() function adds a new environment variable
* \a name with the \a value. If the \a value is #QSE_NULL, it takes
* the actual value from the system environment
*
* \return 0 on success, -1 on failure
*/
QSE_EXPORT int qse_env_insertwcs (
qse_env_t* env,
const qse_wchar_t* name,
const qse_wchar_t* value
);
QSE_EXPORT int qse_env_insertwcsa (
qse_env_t* env,
const qse_wchar_t* name,
const qse_wchar_t* value[]
);
QSE_EXPORT int qse_env_insertmbs (
qse_env_t* env,
const qse_mchar_t* name,
const qse_mchar_t* value
);
QSE_EXPORT int qse_env_insertmbsa (
qse_env_t* env,
const qse_mchar_t* name,
const qse_mchar_t* value[]
);
/**
* The qse_env_appendwcs() function appends an extra value to the last item
* in the environment list.
*/
QSE_EXPORT int qse_env_appendwcs (
qse_env_t* env,
const qse_wchar_t* value
);
QSE_EXPORT int qse_env_appendmbs (
qse_env_t* env,
const qse_mchar_t* value
);
QSE_EXPORT int qse_env_deletewcs (
qse_env_t* env,
const qse_wchar_t* name
);
QSE_EXPORT int qse_env_deletembs (
qse_env_t* env,
const qse_mchar_t* name
);
#if defined(QSE_CHAR_IS_MCHAR)
# define qse_env_insert(env,name,value) qse_env_insertmbs(env,name,value)
# define qse_env_inserta(env,name,value) qse_env_insertmbsa(env,name,value)
# define qse_env_append(env,value) qse_env_appendmbs(env,value)
# define qse_env_delete(env,name) qse_env_deletembs(env,name)
#else
# define qse_env_insert(env,name,value) qse_env_insertwcs(env,name,value)
# define qse_env_inserta(env,name,value) qse_env_insertwcsa(env,name,value)
# define qse_env_append(env,value) qse_env_appendwcs(env,value)
# define qse_env_delete(env,name) qse_env_deletewcs(env,name)
#endif
#if defined(__cplusplus)
}
#endif
#endif

313
include/qse/cmn/fma.h Normal file
View File

@@ -0,0 +1,313 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_FMA_H_
#define _QSE_CMN_FMA_H_
/** @file
* This file defines a fixed-size block memory allocator.
* As the block size is known in advance, it achieves block allocation
* with little overhead.
*
* <pre>
* chunk head(cnkhead)
* |
* | +---------------------------------------------+
* +--> | | f1 | f2 | | | chunk #2
* +--|---------^------|----^--------------------+
* | | | |
* | +------+ +---+ +--------------+
* | | | |
* | +-----------------|----V--------------|-------+
* +---> | | | f3 | | f4 | chunk #1
* +---------------------------------------^-----+
* |
* free block head (freeblk)
* </pre>
*
* The diagram above assumes that f1, f2, f3, and f4 are free blocks.
* The chaining order depends on the allocation and deallocation order.
*
* See an example below. Note that it omits error handling.
*
* @code
* #include <qse/cmn/fma.h>
* int main ()
* {
* qse_fma_t* fma;
* int* ptr1, * ptr2;
*
* // create a memory allocator for integer blocks up to 50.
* fma = qse_fma_open (QSE_NULL, 0, sizeof(int), 10, 5);
*
* // allocate two integer blocks
* ptr1 = (int*) qse_fma_alloc (fma, sizeof(int));
* ptr2 = (int*) qse_fma_alloc (fma, sizeof(int));
*
* *ptr1 = 20; *ptr2 = 99;
*
* // free the two blocks.
* qse_fma_free (fma, ptr1);
* qse_fma_free (fma, ptr2);
*
* // destroy the memory allocator
* qse_fma_close (fma);
* }
* @endcode
*
* The following example shows how to use the fixed-size block
* allocator for a dynamic data structure allocating fixed-size nodes.
*
* @code
* #include <qse/cmn/fma.h>
* #include <qse/cmn/rbt.h>
* #include <qse/cmn/mem.h>
* #include <qse/cmn/stdio.h>
*
* static qse_rbt_walk_t walk (qse_rbt_t* rbt, qse_rbt_pair_t* pair, void* ctx)
* {
* qse_printf (QSE_T("key = %lld, value = %lld\n"),
* *(long*)QSE_RBT_KPTR(pair), *(long*)QSE_RBT_VPTR(pair));
* return QSE_RBT_WALK_FORWARD;
* }
*
* int main ()
* {
* qse_fma_t* fma;
* qse_rbt_t rbt;
* qse_size_t blksize;
* long x;
*
* // prepare the fixed-size block allocator into the qse_mmgr_t interface
* qse_mmgr_t mmgr =
* {
* (qse_mmgr_alloc_t) qse_fma_alloc,
* (qse_mmgr_realloc_t) qse_fma_realloc,
* (qse_mmgr_free_t) qse_fma_free,
* QSE_NULL
* };
*
* // the block size of a red-black tree is fixed to be:
* // key size + value size + internal node size.
* blksize = sizeof(long) + sizeof(long) + sizeof(qse_rbt_pair_t);
*
* // create a fixed-size block allocator which is created
* // with the default memory allocator.
* fma = qse_fma_open (QSE_MMGR_GETDFL(), 0, blksize, 10, 0);
* if (fma == QSE_NULL)
* {
* qse_printf (QSE_T("cannot open a memory allocator\n"));
* return -1;
* }
*
* // complete the qse_mmgr_t interface by providing the allocator.
* mmgr.ctx = fma;
*
* // initializes the statically declared red-black tree.
* // can not call qse_rbt_open() which allocates the qse_rbt_t object.
* // as its size differs from the block size calculated above.
* if (qse_rbt_init (&rbt, &mmgr) == QSE_NULL)
* {
* qse_printf (QSE_T("cannot initialize a tree\n"));
* qse_fma_close (fma);
* return -1;
* }
*
* // perform more initializations for keys and values.
* qse_rbt_setcopier (&rbt, QSE_RBT_KEY, QSE_RBT_COPIER_INLINE);
* qse_rbt_setcopier (&rbt, QSE_RBT_VAL, QSE_RBT_COPIER_INLINE);
* qse_rbt_setscale (&rbt, QSE_RBT_KEY, QSE_SIZEOF(long));
* qse_rbt_setscale (&rbt, QSE_RBT_VAL, QSE_SIZEOF(long));
*
* // insert numbers into the red-black tree
* for (x = 10; x < 100; x++)
* {
* long y = x * x;
* if (qse_rbt_insert (&rbt, &x, 1, &y, 1) == QSE_NULL)
* {
* qse_printf (QSE_T("failed to insert. out of memory\n"));
* break;
* }
* }
*
* // print the tree contents
* qse_rbt_walk (&rbt, walk, QSE_NULL);
*
* // finalize the tree.
* qse_rbt_fini (&rbt);
*
* // destroy the memory allocator.
* qse_fma_close (fma);
*
* return 0;
* }
* @endcode
*
* Use #qse_xma_t for variable-size block allocation.
*/
#include <qse/types.h>
#include <qse/macros.h>
/** @struct qse_fma_cnk_t
* The qse_fma_cnk_t type defines a memory chunk header to hold memory blocks.
* The chunks added are maintained in a singly-linked list
*/
typedef struct qse_fma_cnk_t qse_fma_cnk_t;
struct qse_fma_cnk_t
{
qse_fma_cnk_t* next; /**< point to the next chunk */
};
/** @struct qse_fma_blk_t
* The qse_fma_blk_t type defines a memory block header to weave free blocks
* into a singly-linked list.
*/
typedef struct qse_fma_blk_t qse_fma_blk_t;
struct qse_fma_blk_t
{
qse_fma_blk_t* next; /**< point to the next block */
};
/** @struct qse_fma_t
* The qse_fma_t type defines a fixed-size block memory allocator.
*/
typedef struct qse_fma_t qse_fma_t;
struct qse_fma_t
{
qse_mmgr_t* mmgr; /**< memory manager */
qse_size_t blksize; /**< block size */
qse_size_t maxblks; /**< maximum blocks in a chunk */
qse_size_t maxcnks; /**< maximum chunks */
qse_size_t numcnks; /**< current numbers of chunks */
qse_fma_cnk_t* cnkhead; /**< point to the first chunk added */
qse_fma_blk_t* freeblk; /**< point to the first free block */
};
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The qse_fma_open() function creates a memory allocator with an outer
* memory manager.
*/
QSE_EXPORT qse_fma_t* qse_fma_open (
qse_mmgr_t* mmgr, /**< outer memory manager */
qse_size_t xtnsize, /**< extension size in bytes */
qse_size_t blksize, /**< fixed block size in bytes */
qse_size_t maxblks, /**< maximum numbers of blocks in a chunk */
qse_size_t maxcnks /**< maximum numbers of chunks. 0 for no limit */
);
/**
* The qse_fma_close() function destroys an memory allocator.
*/
QSE_EXPORT void qse_fma_close (
qse_fma_t* fma /**< memory allocator */
);
/**
* The qse_fma_init() function initializes an memory allocator statically
* declared.
*/
QSE_EXPORT int qse_fma_init (
qse_fma_t* fma, /**< memory allocator */
qse_mmgr_t* mmgr, /**< outer memory manager */
qse_size_t blksize, /**< fixed block size in bytes */
qse_size_t maxblks, /**< maximum numbers of blocks in a chunk */
qse_size_t maxcnks /**< maximum numbers of chunks. 0 for no limit */
);
/**
* The qse_fma_fini() function finalizes an memory allocator.
*/
QSE_EXPORT void qse_fma_fini (
qse_fma_t* fma /**< memory allocator */
);
QSE_EXPORT qse_mmgr_t* qse_fma_getmmgr (
qse_fma_t* fma
);
QSE_EXPORT void* qse_fma_getxtn (
qse_fma_t* fma
);
/**
* The qse_fma_alloc() function allocates a block of the fixed block size
* specified during initialization regardless of the block size @a size
* requested so long as it is not greater than the fixed size. The function
* fails if it is greater.
*
* @return block pointer on success, #QSE_NULL on failure
*/
QSE_EXPORT void* qse_fma_alloc (
qse_fma_t* fma, /**< memory allocator */
qse_size_t size /**< block size in bytes*/
);
QSE_EXPORT void* qse_fma_calloc (
qse_fma_t* fma,
qse_size_t size
);
/**
* The qse_fma_realloc() function is provided for consistency with other
* generic memory allocator which provides a reallocation function.
* Block resizing is meaningless for #qse_fma_t as it deals with fixed-size
* blocks.
*
* If the @a size requested is greater than the fixed block size of the memory
* allocator @a fma, the function fails; If the block @a blk is #QSE_NULL and
* the @a size requested is not greater than the fixed block size of the memory
* allocator @a fma, it allocates a block of the fixed size; If the block
* @a blk is not #QSE_NULL and the @a size requested is not greater than the
* fixed block size of the memory allocator @a fma, it returns the block @a blk.
*
* @return block pointer on success, #QSE_NULL on failure
*/
QSE_EXPORT void* qse_fma_realloc (
qse_fma_t* fma, /**< memory allocator */
void* blk, /**< memory block */
qse_size_t size /**< block size in bytes*/
);
/**
* The qse_fma_free() function deallocates a block.
*/
QSE_EXPORT void qse_fma_free (
qse_fma_t* fma, /**< memory allocator */
void* blk /**< memory block to free */
);
#if defined(__cplusplus)
}
#endif
#endif

312
include/qse/cmn/fmt.h Normal file
View File

@@ -0,0 +1,312 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_FMT_H_
#define _QSE_CMN_FMT_H_
#include <qse/types.h>
#include <qse/macros.h>
/** \file
* This file defines various formatting functions.
*/
/**
* The qse_fmtintmax_flag_t type defines enumerators to change the
* behavior of qse_fmtintmax() and qse_fmtuintmax().
*/
enum qse_fmtintmax_flag_t
{
/* Use lower 6 bits to represent base between 2 and 36 inclusive.
* Upper bits are used for these flag options */
/** Don't truncate if the buffer is not large enough */
QSE_FMTINTMAX_NOTRUNC = (0x40 << 0),
/** Don't append a terminating null */
QSE_FMTINTMAX_NONULL = (0x40 << 1),
/** Produce no digit for a value of zero */
QSE_FMTINTMAX_NOZERO = (0x40 << 2),
/** Produce a leading zero for a non-zero value */
QSE_FMTINTMAX_ZEROLEAD = (0x40 << 3),
/** Use uppercase letters for alphabetic digits */
QSE_FMTINTMAX_UPPERCASE = (0x40 << 4),
/** Insert a plus sign for a positive integer including 0 */
QSE_FMTINTMAX_PLUSSIGN = (0x40 << 5),
/** Insert a space for a positive integer including 0 */
QSE_FMTINTMAX_EMPTYSIGN = (0x40 << 6),
/** Fill the right part of the string */
QSE_FMTINTMAX_FILLRIGHT = (0x40 << 7),
/** Fill between the sign chacter and the digit part */
QSE_FMTINTMAX_FILLCENTER = (0x40 << 8)
};
#define QSE_FMTINTMAX_NOTRUNC QSE_FMTINTMAX_NOTRUNC
#define QSE_FMTINTMAX_NONULL QSE_FMTINTMAX_NONULL
#define QSE_FMTINTMAX_NOZERO QSE_FMTINTMAX_NOZERO
#define QSE_FMTINTMAX_ZEROLEAD QSE_FMTINTMAX_ZEROLEAD
#define QSE_FMTINTMAX_UPPERCASE QSE_FMTINTMAX_UPPERCASE
#define QSE_FMTINTMAX_PLUSSIGN QSE_FMTINTMAX_PLUSSIGN
#define QSE_FMTINTMAX_EMPTYSIGN QSE_FMTINTMAX_EMPTYSIGN
#define QSE_FMTINTMAX_FILLRIGHT QSE_FMTINTMAX_FILLRIGHT
#define QSE_FMTINTMAX_FILLCENTER QSE_FMTINTMAX_FILLCENTER
#define QSE_FMTUINTMAX_NOTRUNC QSE_FMTINTMAX_NOTRUNC
#define QSE_FMTUINTMAX_NONULL QSE_FMTINTMAX_NONULL
#define QSE_FMTUINTMAX_NOZERO QSE_FMTINTMAX_NOZERO
#define QSE_FMTUINTMAX_ZEROLEAD QSE_FMTINTMAX_ZEROLEAD
#define QSE_FMTUINTMAX_UPPERCASE QSE_FMTINTMAX_UPPERCASE
#define QSE_FMTUINTMAX_PLUSSIGN QSE_FMTINTMAX_PLUSSIGN
#define QSE_FMTUINTMAX_EMPTYSIGN QSE_FMTINTMAX_EMPTYSIGN
#define QSE_FMTUINTMAX_FILLRIGHT QSE_FMTINTMAX_FILLRIGHT
#define QSE_FMTUINTMAX_FILLCENTER QSE_FMTINTMAX_FILLCENTER
#define QSE_FMTINTMAXTOMBS_NOTRUNC QSE_FMTINTMAX_NOTRUNC
#define QSE_FMTINTMAXTOMBS_NONULL QSE_FMTINTMAX_NONULL
#define QSE_FMTINTMAXTOMBS_NOZERO QSE_FMTINTMAX_NOZERO
#define QSE_FMTINTMAXTOMBS_ZEROLEAD QSE_FMTINTMAX_ZEROLEAD
#define QSE_FMTINTMAXTOMBS_UPPERCASE QSE_FMTINTMAX_UPPERCASE
#define QSE_FMTINTMAXTOMBS_PLUSSIGN QSE_FMTINTMAX_PLUSSIGN
#define QSE_FMTINTMAXTOMBS_EMPTYSIGN QSE_FMTINTMAX_EMPTYSIGN
#define QSE_FMTINTMAXTOMBS_FILLRIGHT QSE_FMTINTMAX_FILLRIGHT
#define QSE_FMTINTMAXTOMBS_FILLCENTER QSE_FMTINTMAX_FILLCENTER
#define QSE_FMTUINTMAXTOMBS_NOTRUNC QSE_FMTINTMAX_NOTRUNC
#define QSE_FMTUINTMAXTOMBS_NONULL QSE_FMTINTMAX_NONULL
#define QSE_FMTUINTMAXTOMBS_NOZERO QSE_FMTINTMAX_NOZERO
#define QSE_FMTUINTMAXTOMBS_ZEROLEAD QSE_FMTINTMAX_ZEROLEAD
#define QSE_FMTUINTMAXTOMBS_UPPERCASE QSE_FMTINTMAX_UPPERCASE
#define QSE_FMTUINTMAXTOMBS_PLUSSIGN QSE_FMTINTMAX_PLUSSIGN
#define QSE_FMTUINTMAXTOMBS_EMPTYSIGN QSE_FMTINTMAX_EMPTYSIGN
#define QSE_FMTUINTMAXTOMBS_FILLRIGHT QSE_FMTINTMAX_FILLRIGHT
#define QSE_FMTUINTMAXTOMBS_FILLCENTER QSE_FMTINTMAX_FILLCENTER
#define QSE_FMTINTMAXTOWCS_NOTRUNC QSE_FMTINTMAX_NOTRUNC
#define QSE_FMTINTMAXTOWCS_NONULL QSE_FMTINTMAX_NONULL
#define QSE_FMTINTMAXTOWCS_NOZERO QSE_FMTINTMAX_NOZERO
#define QSE_FMTINTMAXTOWCS_ZEROLEAD QSE_FMTINTMAX_ZEROLEAD
#define QSE_FMTINTMAXTOWCS_UPPERCASE QSE_FMTINTMAX_UPPERCASE
#define QSE_FMTINTMAXTOWCS_PLUSSIGN QSE_FMTINTMAX_PLUSSIGN
#define QSE_FMTINTMAXTOWCS_EMPTYSIGN QSE_FMTINTMAX_EMPTYSIGN
#define QSE_FMTINTMAXTOWCS_FILLRIGHT QSE_FMTINTMAX_FILLRIGHT
#define QSE_FMTINTMAXTOWCS_FILLCENTER QSE_FMTINTMAX_FILLCENTER
#define QSE_FMTUINTMAXTOWCS_NOTRUNC QSE_FMTINTMAX_NOTRUNC
#define QSE_FMTUINTMAXTOWCS_NONULL QSE_FMTINTMAX_NONULL
#define QSE_FMTUINTMAXTOWCS_NOZERO QSE_FMTINTMAX_NOZERO
#define QSE_FMTUINTMAXTOWCS_ZEROLEAD QSE_FMTINTMAX_ZEROLEAD
#define QSE_FMTUINTMAXTOWCS_UPPERCASE QSE_FMTINTMAX_UPPERCASE
#define QSE_FMTUINTMAXTOWCS_PLUSSIGN QSE_FMTINTMAX_PLUSSIGN
#define QSE_FMTUINTMAXTOWCS_EMPTYSIGN QSE_FMTINTMAX_EMPTYSIGN
#define QSE_FMTUINTMAXTOWCS_FILLRIGHT QSE_FMTINTMAX_FILLRIGHT
#define QSE_FMTUINTMAXTOWCS_FILLCENTER QSE_FMTINTMAX_FILLCENTER
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The qse_fmtintmaxtombs() function formats an integer \a value to a
* multibyte string according to the given base and writes it to a buffer
* pointed to by \a buf. It writes to the buffer at most \a size characters
* including the terminating null. The base must be between 2 and 36 inclusive
* and can be ORed with zero or more #qse_fmtintmaxtombs_flag_t enumerators.
* This ORed value is passed to the function via the \a base_and_flags
* parameter. If the formatted string is shorter than \a bufsize, the redundant
* slots are filled with the fill character \a fillchar if it is not a null
* character. The filling behavior is determined by the flags shown below:
*
* - If #QSE_FMTINTMAXTOMBS_FILLRIGHT is set in \a base_and_flags, slots
* after the formatting string are filled.
* - If #QSE_FMTINTMAXTOMBS_FILLCENTER is set in \a base_and_flags, slots
* before the formatting string are filled. However, if it contains the
* sign character, the slots between the sign character and the digit part
* are filled.
* - If neither #QSE_FMTINTMAXTOMBS_FILLRIGHT nor #QSE_FMTINTMAXTOMBS_FILLCENTER
* , slots before the formatting string are filled.
*
* The \a precision parameter specified the minimum number of digits to
* produce from the \a value. If \a value produces fewer digits than
* \a precision, the actual digits are padded with '0' to meet the precision
* requirement. You can pass a negative number if you don't wish to specify
* precision.
*
* The terminating null is not added if #QSE_FMTINTMAXTOMBS_NONULL is set;
* The #QSE_FMTINTMAXTOMBS_UPPERCASE flag indicates that the function should
* use the uppercase letter for a alphabetic digit;
* You can set #QSE_FMTINTMAXTOMBS_NOTRUNC if you require lossless formatting.
* The #QSE_FMTINTMAXTOMBS_PLUSSIGN flag and #QSE_FMTINTMAXTOMBS_EMPTYSIGN
* ensures that the plus sign and a space is added for a positive integer
* including 0 respectively.
* The #QSE_FMTINTMAXTOMBS_ZEROLEAD flag ensures that the numeric string
* begins with '0' before applying the prefix.
* You can set the #QSE_FMTINTMAXTOMBS_NOZERO flag if you want the value of
* 0 to produce nothing. If both #QSE_FMTINTMAXTOMBS_NOZERO and
* #QSE_FMTINTMAXTOMBS_ZEROLEAD are specified, '0' is still produced.
*
* If \a prefix is not #QSE_NULL, it is inserted before the digits.
*
* \return
* - -1 if the base is not between 2 and 36 inclusive.
* - negated number of characters required for lossless formatting
* - if \a bufsize is 0.
* - if #QSE_FMTINTMAXTOMBS_NOTRUNC is set and \a bufsize is less than
* the minimum required for lossless formatting.
* - number of characters written to the buffer excluding a terminating
* null in all other cases.
*/
QSE_EXPORT int qse_fmtintmaxtombs (
qse_mchar_t* buf, /**< buffer pointer */
int bufsize, /**< buffer size */
qse_intmax_t value, /**< integer to format */
int base_and_flags, /**< base ORed with flags */
int precision, /**< precision */
qse_mchar_t fillchar, /**< fill character */
const qse_mchar_t* prefix /**< prefix */
);
/**
* The qse_fmtintmaxtowcs() function formats an integer \a value to a
* wide-character string according to the given base and writes it to a buffer
* pointed to by \a buf. It writes to the buffer at most \a size characters
* including the terminating null. The base must be between 2 and 36 inclusive
* and can be ORed with zero or more #qse_fmtintmaxtowcs_flag_t enumerators.
* This ORed value is passed to the function via the \a base_and_flags
* parameter. If the formatted string is shorter than \a bufsize, the redundant
* slots are filled with the fill character \a fillchar if it is not a null
* character. The filling behavior is determined by the flags shown below:
*
* - If #QSE_FMTINTMAXTOWCS_FILLRIGHT is set in \a base_and_flags, slots
* after the formatting string are filled.
* - If #QSE_FMTINTMAXTOWCS_FILLCENTER is set in \a base_and_flags, slots
* before the formatting string are filled. However, if it contains the
* sign character, the slots between the sign character and the digit part
* are filled.
* - If neither #QSE_FMTINTMAXTOWCS_FILLRIGHT nor #QSE_FMTINTMAXTOWCS_FILLCENTER
* , slots before the formatting string are filled.
*
* The \a precision parameter specified the minimum number of digits to
* produce from the \ value. If \a value produces fewer digits than
* \a precision, the actual digits are padded with '0' to meet the precision
* requirement. You can pass a negative number if don't wish to specify
* precision.
*
* The terminating null is not added if #QSE_FMTINTMAXTOWCS_NONULL is set;
* The #QSE_FMTINTMAXTOWCS_UPPERCASE flag indicates that the function should
* use the uppercase letter for a alphabetic digit;
* You can set #QSE_FMTINTMAXTOWCS_NOTRUNC if you require lossless formatting.
* The #QSE_FMTINTMAXTOWCS_PLUSSIGN flag and #QSE_FMTINTMAXTOWCS_EMPTYSIGN
* ensures that the plus sign and a space is added for a positive integer
* including 0 respectively.
* The #QSE_FMTINTMAXTOWCS_ZEROLEAD flag ensures that the numeric string
* begins with 0 before applying the prefix.
* You can set the #QSE_FMTINTMAXTOWCS_NOZERO flag if you want the value of
* 0 to produce nothing. If both #QSE_FMTINTMAXTOWCS_NOZERO and
* #QSE_FMTINTMAXTOWCS_ZEROLEAD are specified, '0' is still produced.
*
* If \a prefix is not #QSE_NULL, it is inserted before the digits.
*
* \return
* - -1 if the base is not between 2 and 36 inclusive.
* - negated number of characters required for lossless formatting
* - if \a bufsize is 0.
* - if #QSE_FMTINTMAXTOWCS_NOTRUNC is set and \a bufsize is less than
* the minimum required for lossless formatting.
* - number of characters written to the buffer excluding a terminating
* null in all other cases.
*/
QSE_EXPORT int qse_fmtintmaxtowcs (
qse_wchar_t* buf, /**< buffer pointer */
int bufsize, /**< buffer size */
qse_intmax_t value, /**< integer to format */
int base_and_flags, /**< base ORed with flags */
int precision, /**< precision */
qse_wchar_t fillchar, /**< fill character */
const qse_wchar_t* prefix /**< prefix */
);
/** \def qse_fmtintmax
* The qse_fmtintmax() macro maps to qse_fmtintmaxtombs() if
* #QSE_CHAR_IS_MCHAR, and qse_fmtintmaxtowcs() if #QSE_CHAR_IS_WCHAR.
*/
#ifdef QSE_CHAR_IS_MCHAR
# define qse_fmtintmax(b,sz,v,bf,pr,fc,pf) qse_fmtintmaxtombs(b,sz,v,bf,pr,fc,pf)
#else
# define qse_fmtintmax(b,sz,v,bf,pr,fc,pf) qse_fmtintmaxtowcs(b,sz,v,bf,pr,fc,pf)
#endif
/**
* The qse_fmtuintmaxtombs() function formats an unsigned integer \a value
* to a multibyte string buffer. It behaves the same as qse_fmtuintmaxtombs()
* except that it handles an unsigned integer.
*/
QSE_EXPORT int qse_fmtuintmaxtombs (
qse_mchar_t* buf, /**< buffer pointer */
int bufsize, /**< buffer size */
qse_uintmax_t value, /**< integer to format */
int base_and_flags, /**< base ORed with flags */
int precision, /**< precision */
qse_mchar_t fillchar, /**< fill character */
const qse_mchar_t* prefix /**< prefix */
);
/**
* The qse_fmtuintmaxtowcs() function formats an unsigned integer \a value
* to a wide-character string buffer. It behaves the same as
* qse_fmtuintmaxtowcs() except that it handles an unsigned integer.
*/
QSE_EXPORT int qse_fmtuintmaxtowcs (
qse_wchar_t* buf, /**< buffer pointer */
int bufsize, /**< buffer size */
qse_uintmax_t value, /**< integer to format */
int base_and_flags, /**< base ORed with flags */
int precision, /**< precision */
qse_wchar_t fillchar, /**< fill character */
const qse_wchar_t* prefix /**< prefix */
);
/** \def qse_fmtuintmax
* The qse_fmtuintmax() macro maps to qse_fmtuintmaxtombs() if
* #QSE_CHAR_IS_MCHAR, and qse_fmtuintmaxtowcs() if #QSE_CHAR_IS_WCHAR.
*/
#ifdef QSE_CHAR_IS_MCHAR
# define qse_fmtuintmax(b,sz,v,bf,pr,fc,pf) qse_fmtuintmaxtombs(b,sz,v,bf,pr,fc,pf)
#else
# define qse_fmtuintmax(b,sz,v,bf,pr,fc,pf) qse_fmtuintmaxtowcs(b,sz,v,bf,pr,fc,pf)
#endif
QSE_EXPORT int qse_fmtfltmaxtombs (
qse_mchar_t* buf,
qse_size_t bufsize,
qse_fltmax_t f,
qse_mchar_t point,
int digits
);
#if defined(__cplusplus)
}
#endif
#endif

218
include/qse/cmn/gdl.h Normal file
View File

@@ -0,0 +1,218 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_GDL_H_
#define _QSE_CMN_GDL_H_
#include <qse/types.h>
#include <qse/macros.h>
/** @file
* 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 <qse/cmn/gdl.h>
*
* 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 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_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(gdl) QSE_BLOCK ( \
(gdl)->head = (qse_gdl_link_t*)(gdl); \
(gdl)->tail = (qse_gdl_link_t*)(gdl); \
)
#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(gdl) ((gdl)->head)
/**
* The QSE_GDL_TAIL macro gets the last node in the chain.
*/
#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))
#if defined(__cplusplus)
extern "C" {
#endif
QSE_EXPORT void qse_gdl_chain (
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* 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
);
#if defined(__cplusplus)
}
#endif
#endif

678
include/qse/cmn/htb.h Normal file
View File

@@ -0,0 +1,678 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_HTB_H_
#define _QSE_CMN_HTB_H_
#include <qse/types.h>
#include <qse/macros.h>
/**@file
* This file provides a hash table encapsulated in the #qse_htb_t type that
* maintains buckets for key/value pairs with the same key hash chained under
* the same bucket. Its interface is very close to #qse_rbt_t.
*
* This sample code adds a series of keys and values and print them
* in the randome order.
* @code
* #include <qse/cmn/htb.h>
* #include <qse/cmn/mem.h>
* #include <qse/si/sio.h>
*
* static qse_htb_walk_t walk (qse_htb_t* htb, qse_htb_pair_t* pair, void* ctx)
* {
* qse_printf (QSE_T("key = %d, value = %d\n"),
* *(int*)QSE_HTB_KPTR(pair), *(int*)QSE_HTB_VPTR(pair));
* return QSE_HTB_WALK_FORWARD;
* }
*
* int main ()
* {
* qse_htb_t* s1;
* int i;
*
* qse_open_stdsios ();
* s1 = qse_htb_open (QSE_MMGR_GETDFL(), 0, 30, 75, 1, 1); // error handling skipped
* qse_htb_setstyle (s1, qse_gethtbstyle(QSE_HTB_STYLE_INLINE_COPIERS));
*
* for (i = 0; i < 20; i++)
* {
* int x = i * 20;
* qse_htb_insert (s1, &i, QSE_SIZEOF(i), &x, QSE_SIZEOF(x)); // eror handling skipped
* }
*
* qse_htb_walk (s1, walk, QSE_NULL);
*
* qse_htb_close (s1);
* qse_close_stdsios ();
* return 0;
* }
* @endcode
*/
typedef struct qse_htb_t qse_htb_t;
typedef struct qse_htb_pair_t qse_htb_pair_t;
/**
* The qse_htb_walk_t type defines values that the callback function can
* return to control qse_htb_walk().
*/
enum qse_htb_walk_t
{
QSE_HTB_WALK_STOP = 0,
QSE_HTB_WALK_FORWARD = 1
};
typedef enum qse_htb_walk_t qse_htb_walk_t;
/**
* The qse_htb_id_t type defines IDs to indicate a key or a value in various
* functions.
*/
enum qse_htb_id_t
{
QSE_HTB_KEY = 0,
QSE_HTB_VAL = 1
};
typedef enum qse_htb_id_t qse_htb_id_t;
/**
* The qse_htb_copier_t type defines a pair contruction callback.
* A special copier #QSE_HTB_COPIER_INLINE is provided. This copier enables
* you to copy the data inline to the internal node. No freeer is invoked
* when the node is freeed.
*/
typedef void* (*qse_htb_copier_t) (
qse_htb_t* htb /* hash table */,
void* dptr /* pointer to a key or a value */,
qse_size_t dlen /* length of a key or a value */
);
/**
* The qse_htb_freeer_t defines a key/value destruction callback
* The freeer is called when a node containing the element is destroyed.
*/
typedef void (*qse_htb_freeer_t) (
qse_htb_t* htb, /**< hash table */
void* dptr, /**< pointer to a key or a value */
qse_size_t dlen /**< length of a key or a value */
);
/**
* The qse_htb_comper_t type defines a key comparator that is called when
* the htb needs to compare keys. A hash table is created with a default
* comparator which performs bitwise comparison of two keys.
* The comparator should return 0 if the keys are the same and a non-zero
* integer otherwise.
*/
typedef int (*qse_htb_comper_t) (
const qse_htb_t* htb, /**< hash table */
const void* kptr1, /**< key pointer */
qse_size_t klen1, /**< key length */
const void* kptr2, /**< key pointer */
qse_size_t klen2 /**< key length */
);
/**
* The qse_htb_keeper_t type defines a value keeper that is called when
* a value is retained in the context that it should be destroyed because
* it is identical to a new value. Two values are identical if their
* pointers and lengths are equal.
*/
typedef void (*qse_htb_keeper_t) (
qse_htb_t* htb, /**< hash table */
void* vptr, /**< value pointer */
qse_size_t vlen /**< value length */
);
/**
* The qse_htb_sizer_t type defines a bucket size claculator that is called
* when hash table should resize the bucket. The current bucket size + 1 is
* passed as the hint.
*/
typedef qse_size_t (*qse_htb_sizer_t) (
qse_htb_t* htb, /**< htb */
qse_size_t hint /**< sizing hint */
);
/**
* The qse_htb_hasher_t type defines a key hash function
*/
typedef qse_size_t (*qse_htb_hasher_t) (
const qse_htb_t* htb, /**< hash table */
const void* kptr, /**< key pointer */
qse_size_t klen /**< key length in bytes */
);
/**
* The qse_htb_walker_t defines a pair visitor.
*/
typedef qse_htb_walk_t (*qse_htb_walker_t) (
qse_htb_t* htb, /**< htb */
qse_htb_pair_t* pair, /**< pointer to a key/value pair */
void* ctx /**< pointer to user-defined data */
);
/**
* The qse_htb_cbserter_t type defines a callback function for qse_htb_cbsert().
* The qse_htb_cbserter() function calls it to allocate a new pair for the
* key pointed to by @a kptr of the length @a klen and the callback context
* @a ctx. The second parameter @a pair is passed the pointer to the existing
* pair for the key or #QSE_NULL in case of no existing key. The callback
* must return a pointer to a new or a reallocated pair. When reallocating the
* existing pair, this callback must destroy the existing pair and return the
* newly reallocated pair. It must return #QSE_NULL for failure.
*/
typedef qse_htb_pair_t* (*qse_htb_cbserter_t) (
qse_htb_t* htb, /**< hash table */
qse_htb_pair_t* pair, /**< pair pointer */
void* kptr, /**< key pointer */
qse_size_t klen, /**< key length */
void* ctx /**< callback context */
);
/**
* The qse_htb_pair_t type defines hash table pair. A pair is composed of a key
* and a value. It maintains pointers to the beginning of a key and a value
* plus their length. The length is scaled down with the scale factor
* specified in an owning hash table.
*/
struct qse_htb_pair_t
{
qse_xptl_t key;
qse_xptl_t val;
/* management information below */
qse_htb_pair_t* next;
};
typedef struct qse_htb_style_t qse_htb_style_t;
struct qse_htb_style_t
{
qse_htb_copier_t copier[2];
qse_htb_freeer_t freeer[2];
qse_htb_comper_t comper; /**< key comparator */
qse_htb_keeper_t keeper; /**< value keeper */
qse_htb_sizer_t sizer; /**< bucket capacity recalculator */
qse_htb_hasher_t hasher; /**< key hasher */
};
/**
* The qse_htb_style_kind_t type defines the type of predefined
* callback set for pair manipulation.
*/
enum qse_htb_style_kind_t
{
/** store the key and the value pointer */
QSE_HTB_STYLE_DEFAULT,
/** copy both key and value into the pair */
QSE_HTB_STYLE_INLINE_COPIERS,
/** copy the key into the pair but store the value pointer */
QSE_HTB_STYLE_INLINE_KEY_COPIER,
/** copy the value into the pair but store the key pointer */
QSE_HTB_STYLE_INLINE_VALUE_COPIER
};
typedef enum qse_htb_style_kind_t qse_htb_style_kind_t;
/**
* The qse_htb_t type defines a hash table.
*/
struct qse_htb_t
{
qse_mmgr_t* mmgr;
const qse_htb_style_t* style;
qse_byte_t scale[2]; /**< length scale */
qse_byte_t factor; /**< load factor in percentage */
qse_size_t size;
qse_size_t capa;
qse_size_t threshold;
qse_htb_pair_t** bucket;
};
/**
* The QSE_HTB_COPIER_SIMPLE macros defines a copier that remembers the
* pointer and length of data in a pair.
**/
#define QSE_HTB_COPIER_SIMPLE ((qse_htb_copier_t)1)
/**
* The QSE_HTB_COPIER_INLINE macros defines a copier that copies data into
* a pair.
**/
#define QSE_HTB_COPIER_INLINE ((qse_htb_copier_t)2)
#define QSE_HTB_COPIER_DEFAULT (QSE_HTB_COPIER_SIMPLE)
#define QSE_HTB_FREEER_DEFAULT (QSE_NULL)
#define QSE_HTB_COMPER_DEFAULT (qse_htb_dflcomp)
#define QSE_HTB_KEEPER_DEFAULT (QSE_NULL)
#define QSE_HTB_SIZER_DEFAULT (QSE_NULL)
#define QSE_HTB_HASHER_DEFAULT (qse_htb_dflhash)
/**
* The QSE_HTB_SIZE() macro returns the number of pairs in a hash table.
*/
#define QSE_HTB_SIZE(m) (*(const qse_size_t*)&(m)->size)
/**
* The QSE_HTB_CAPA() macro returns the maximum number of pairs that can be
* stored in a hash table without further reorganization.
*/
#define QSE_HTB_CAPA(m) (*(const qse_size_t*)&(m)->capa)
#define QSE_HTB_FACTOR(m) (*(const int*)&(m)->factor)
#define QSE_HTB_KSCALE(m) (*(const int*)&(m)->scale[QSE_HTB_KEY])
#define QSE_HTB_VSCALE(m) (*(const int*)&(m)->scale[QSE_HTB_VAL])
#define QSE_HTB_KPTL(p) (&(p)->key)
#define QSE_HTB_VPTL(p) (&(p)->val)
#define QSE_HTB_KPTR(p) ((p)->key.ptr)
#define QSE_HTB_KLEN(p) ((p)->key.len)
#define QSE_HTB_VPTR(p) ((p)->val.ptr)
#define QSE_HTB_VLEN(p) ((p)->val.len)
#define QSE_HTB_NEXT(p) ((p)->next)
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The qse_gethtbstyle() functions returns a predefined callback set for
* pair manipulation.
*/
QSE_EXPORT const qse_htb_style_t* qse_gethtbstyle (
qse_htb_style_kind_t kind
);
/**
* The qse_htb_open() function creates a hash table with a dynamic array
* bucket and a list of values chained. The initial capacity should be larger
* than 0. The load factor should be between 0 and 100 inclusive and the load
* factor of 0 disables bucket resizing. If you need extra space associated
* with hash table, you may pass a non-zero value for @a xtnsize.
* The QSE_HTB_XTN() macro and the qse_htb_getxtn() function return the
* pointer to the beginning of the extension.
* The @a kscale and @a vscale parameters specify the unit of the key and
* value size.
* @return #qse_htb_t pointer on success, #QSE_NULL on failure.
*/
QSE_EXPORT qse_htb_t* qse_htb_open (
qse_mmgr_t* mmgr, /**< memory manager */
qse_size_t xtnsize, /**< extension size in bytes */
qse_size_t capa, /**< initial capacity */
int factor, /**< load factor */
int kscale, /**< key scale - 1 to 255 */
int vscale /**< value scale - 1 to 255 */
);
/**
* The qse_htb_close() function destroys a hash table.
*/
QSE_EXPORT void qse_htb_close (
qse_htb_t* htb /**< hash table */
);
/**
* The qse_htb_init() function initializes a hash table
*/
QSE_EXPORT int qse_htb_init (
qse_htb_t* htb, /**< hash table */
qse_mmgr_t* mmgr, /**< memory manager */
qse_size_t capa, /**< initial capacity */
int factor, /**< load factor */
int kscale, /**< key scale */
int vscale /**< value scale */
);
/**
* The qse_htb_fini() funtion finalizes a hash table
*/
QSE_EXPORT void qse_htb_fini (
qse_htb_t* htb
);
QSE_EXPORT qse_mmgr_t* qse_htb_getmmgr (
qse_htb_t* htb
);
QSE_EXPORT void* qse_htb_getxtn (
qse_htb_t* htb
);
/**
* The qse_htb_getstyle() function gets manipulation callback function set.
*/
QSE_EXPORT const qse_htb_style_t* qse_htb_getstyle (
const qse_htb_t* htb /**< hash table */
);
/**
* The qse_htb_setstyle() function sets internal manipulation callback
* functions for data construction, destruction, resizing, hashing, etc.
* The callback structure pointed to by \a style must outlive the hash
* table pointed to by \a htb as the hash table doesn't copy the contents
* of the structure.
*/
QSE_EXPORT void qse_htb_setstyle (
qse_htb_t* htb, /**< hash table */
const qse_htb_style_t* style /**< callback function set */
);
/**
* The qse_htb_getsize() function gets the number of pairs in hash table.
*/
QSE_EXPORT qse_size_t qse_htb_getsize (
const qse_htb_t* htb
);
/**
* The qse_htb_getcapa() function gets the number of slots allocated
* in a hash bucket.
*/
QSE_EXPORT qse_size_t qse_htb_getcapa (
const qse_htb_t* htb /**< hash table */
);
/**
* The qse_htb_search() function searches a hash table to find a pair with a
* matching key. It returns the pointer to the pair found. If it fails
* to find one, it returns QSE_NULL.
* @return pointer to the pair with a maching key,
* or #QSE_NULL if no match is found.
*/
QSE_EXPORT qse_htb_pair_t* qse_htb_search (
const qse_htb_t* htb, /**< hash table */
const void* kptr, /**< key pointer */
qse_size_t klen /**< key length */
);
/**
* The qse_htb_upsert() function searches a hash table for the pair with a
* matching key. If one is found, it updates the pair. Otherwise, it inserts
* a new pair with the key and value given. It returns the pointer to the
* pair updated or inserted.
* @return pointer to the updated or inserted pair on success,
* #QSE_NULL on failure.
*/
QSE_EXPORT qse_htb_pair_t* qse_htb_upsert (
qse_htb_t* htb, /**< hash table */
void* kptr, /**< key pointer */
qse_size_t klen, /**< key length */
void* vptr, /**< value pointer */
qse_size_t vlen /**< value length */
);
/**
* The qse_htb_ensert() function inserts a new pair with the key and the value
* given. If there exists a pair with the key given, the function returns
* the pair containing the key.
* @return pointer to a pair on success, #QSE_NULL on failure.
*/
QSE_EXPORT qse_htb_pair_t* qse_htb_ensert (
qse_htb_t* htb, /**< hash table */
void* kptr, /**< key pointer */
qse_size_t klen, /**< key length */
void* vptr, /**< value pointer */
qse_size_t vlen /**< value length */
);
/**
* The qse_htb_insert() function inserts a new pair with the key and the value
* given. If there exists a pair with the key given, the function returns
* #QSE_NULL without channging the value.
* @return pointer to the pair created on success, #QSE_NULL on failure.
*/
QSE_EXPORT qse_htb_pair_t* qse_htb_insert (
qse_htb_t* htb, /**< hash table */
void* kptr, /**< key pointer */
qse_size_t klen, /**< key length */
void* vptr, /**< value pointer */
qse_size_t vlen /**< value length */
);
/**
* The qse_htb_update() function updates the value of an existing pair
* with a matching key.
* @return pointer to the pair on success, #QSE_NULL on no matching pair
*/
QSE_EXPORT qse_htb_pair_t* qse_htb_update (
qse_htb_t* htb, /**< hash table */
void* kptr, /**< key pointer */
qse_size_t klen, /**< key length */
void* vptr, /**< value pointer */
qse_size_t vlen /**< value length */
);
/**
* The qse_htb_cbsert() function inserts a key/value pair by delegating pair
* allocation to a callback function. Depending on the callback function,
* it may behave like qse_htb_insert(), qse_htb_upsert(), qse_htb_update(),
* qse_htb_ensert(), or totally differently. The sample code below inserts
* a new pair if the key is not found and appends the new value to the
* existing value delimited by a comma if the key is found.
*
* @code
* #include <qse/cmn/htb.h>
* #include <qse/cmn/mem.h>
* #include <qse/si/sio.h>
*
* qse_htb_walk_t print_map_pair (qse_htb_t* map, qse_htb_pair_t* pair, void* ctx)
* {
* qse_printf (QSE_T("%.*s[%d] => %.*s[%d]\n"),
* (int)QSE_HTB_KLEN(pair), QSE_HTB_KPTR(pair), (int)QSE_HTB_KLEN(pair),
* (int)QSE_HTB_VLEN(pair), QSE_HTB_VPTR(pair), (int)QSE_HTB_VLEN(pair));
* return QSE_HTB_WALK_FORWARD;
* }
*
* qse_htb_pair_t* cbserter (
* qse_htb_t* htb, qse_htb_pair_t* pair,
* void* kptr, qse_size_t klen, void* ctx)
* {
* qse_cstr_t* v = (qse_cstr_t*)ctx;
* if (pair == QSE_NULL)
* {
* // no existing key for the key
* return qse_htb_allocpair (htb, kptr, klen, v->ptr, v->len);
* }
* else
* {
* // a pair with the key exists.
* // in this sample, i will append the new value to the old value
* // separated by a comma
* qse_htb_pair_t* new_pair;
* qse_char_t comma = QSE_T(',');
* qse_byte_t* vptr;
*
* // allocate a new pair, but without filling the actual value.
* // note vptr is given QSE_NULL for that purpose
* new_pair = qse_htb_allocpair (
* htb, kptr, klen, QSE_NULL, QSE_HTB_VLEN(pair) + 1 + v->len);
* if (new_pair == QSE_NULL) return QSE_NULL;
*
* // fill in the value space
* vptr = QSE_HTB_VPTR(new_pair);
* qse_memcpy (vptr, QSE_HTB_VPTR(pair), QSE_HTB_VLEN(pair)*QSE_SIZEOF(qse_char_t));
* vptr += QSE_HTB_VLEN(pair)*QSE_SIZEOF(qse_char_t);
* qse_memcpy (vptr, &comma, QSE_SIZEOF(qse_char_t));
* vptr += QSE_SIZEOF(qse_char_t);
* qse_memcpy (vptr, v->ptr, v->len*QSE_SIZEOF(qse_char_t));
*
* // this callback requires the old pair to be destroyed
* qse_htb_freepair (htb, pair);
*
* // return the new pair
* return new_pair;
* }
* }
*
* int main ()
* {
* qse_htb_t* s1;
* int i;
* qse_char_t* keys[] = { QSE_T("one"), QSE_T("two"), QSE_T("three") };
* qse_char_t* vals[] = { QSE_T("1"), QSE_T("2"), QSE_T("3"), QSE_T("4"), QSE_T("5") };
*
* qse_open_stdsios ();
* s1 = qse_htb_open (
* QSE_MMGR_GETDFL(), 0, 10, 70,
* QSE_SIZEOF(qse_char_t), QSE_SIZEOF(qse_char_t)
* ); // note error check is skipped
* qse_htb_setstyle (s1, qse_gethtbstyle(QSE_HTB_STYLE_INLINE_COPIERS));
*
* for (i = 0; i < QSE_COUNTOF(vals); i++)
* {
* qse_cstr_t ctx;
* ctx.ptr = vals[i]; ctx.len = qse_strlen(vals[i]);
* qse_htb_cbsert (s1,
* keys[i%QSE_COUNTOF(keys)], qse_strlen(keys[i%QSE_COUNTOF(keys)]),
* cbserter, &ctx
* ); // note error check is skipped
* }
* qse_htb_walk (s1, print_map_pair, QSE_NULL);
*
* qse_htb_close (s1);
* qse_close_stdsios ();
* return 0;
* }
* @endcode
*/
QSE_EXPORT qse_htb_pair_t* qse_htb_cbsert (
qse_htb_t* htb, /**< hash table */
void* kptr, /**< key pointer */
qse_size_t klen, /**< key length */
qse_htb_cbserter_t cbserter, /**< callback function */
void* ctx /**< callback context */
);
/**
* The qse_htb_delete() function deletes a pair with a matching key
* @return 0 on success, -1 on failure
*/
QSE_EXPORT int qse_htb_delete (
qse_htb_t* htb, /**< hash table */
const void* kptr, /**< key pointer */
qse_size_t klen /**< key length */
);
/**
* The qse_htb_clear() function empties a hash table
*/
QSE_EXPORT void qse_htb_clear (
qse_htb_t* htb /**< hash table */
);
/**
* The qse_htb_walk() function traverses a hash table.
*/
QSE_EXPORT void qse_htb_walk (
qse_htb_t* htb, /**< hash table */
qse_htb_walker_t walker, /**< callback function for each pair */
void* ctx /**< pointer to user-specific data */
);
/**
* The qse_htb_getfirstpair() function returns the pointer to the first pair
* in a hash table.
*/
QSE_EXPORT qse_htb_pair_t* qse_htb_getfirstpair (
qse_htb_t* htb, /**< hash table */
qse_size_t* buckno /**< bucket number */
);
/**
* The qse_htb_getnextpair() function returns the pointer to the next pair
* to the current pair @a pair in a hash table.
*/
QSE_EXPORT qse_htb_pair_t* qse_htb_getnextpair (
qse_htb_t* htb, /**< hash table */
qse_htb_pair_t* pair, /**< current pair */
qse_size_t* buckno /**< bucket number */
);
/**
* The qse_htb_allocpair() function allocates a pair for a key and a value
* given. But it does not chain the pair allocated into the hash table @a htb.
* Use this function at your own risk.
*
* Take note of he following special behavior when the copier is
* #QSE_HTB_COPIER_INLINE.
* - If @a kptr is #QSE_NULL, the key space of the size @a klen is reserved but
* not propagated with any data.
* - If @a vptr is #QSE_NULL, the value space of the size @a vlen is reserved
* but not propagated with any data.
*/
QSE_EXPORT qse_htb_pair_t* qse_htb_allocpair (
qse_htb_t* htb,
void* kptr,
qse_size_t klen,
void* vptr,
qse_size_t vlen
);
/**
* The qse_htb_freepair() function destroys a pair. But it does not detach
* the pair destroyed from the hash table @a htb. Use this function at your
* own risk.
*/
QSE_EXPORT void qse_htb_freepair (
qse_htb_t* htb,
qse_htb_pair_t* pair
);
/**
* The qse_htb_dflhash() function is a default hash function.
*/
QSE_EXPORT qse_size_t qse_htb_dflhash (
const qse_htb_t* htb,
const void* kptr,
qse_size_t klen
);
/**
* The qse_htb_dflcomp() function is default comparator.
*/
QSE_EXPORT int qse_htb_dflcomp (
const qse_htb_t* htb,
const void* kptr1,
qse_size_t klen1,
const void* kptr2,
qse_size_t klen2
);
#if defined(__cplusplus)
}
#endif
#endif

326
include/qse/cmn/htl.h Normal file
View File

@@ -0,0 +1,326 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_HTL_T_
#define _QSE_HTL_T_
/** \file
* This file provides the hash table for fixed-size data.
*/
#include <qse/types.h>
#include <qse/macros.h>
/**
* The #qse_htl_walk_t type defines walking directions.
*/
enum qse_htl_walk_t
{
QSE_HTL_WALK_STOP = 0,
QSE_HTL_WALK_FORWARD = 1,
};
typedef enum qse_htl_walk_t qse_htl_walk_t;
typedef struct qse_htl_t qse_htl_t;
typedef struct qse_htl_node_t qse_htl_node_t;
/**
* The #qse_htl_hasher_t type defines a data hasher function.
*/
typedef qse_uint32_t (*qse_htl_hasher_t) (
qse_htl_t* htl,
const void* data
);
/**
* The #qse_htl_comper_t type defines a key comparator that is called when
* the list needs to compare data. The comparator must return 0 if the data
* are the same and a non-zero integer otherwise.
*/
typedef int (*qse_htl_comper_t) (
qse_htl_t* htl, /**< hash table */
const void* data1, /**< data pointer */
const void* data2 /**< data pointer */
);
/**
* The #qse_htl_feeeer_t type defines a data deallocation function.
*/
typedef void (*qse_htl_freeer_t) (
qse_htl_t* htl,
void* data
);
/**
* The #qse_htl_copier_t type defines a data copier function.
*/
typedef void* (*qse_htl_copier_t) (
qse_htl_t* htl,
void* data
);
/**
* The #qse_htl_walker_t function defines a callback function
* for qse_htl_walk().
*/
typedef qse_htl_walk_t (*qse_htl_walker_t) (
qse_htl_t* htl,
void* data,
void* ctx
);
struct qse_htl_node_t
{
struct qse_htl_node_t* next;
qse_uint32_t reversed;
qse_uint32_t key;
void* data;
};
struct qse_htl_t
{
qse_mmgr_t* mmgr;
int keysize; /* default key size */
int num_elements;
int num_buckets; /* power of 2 */
int next_grow;
int mask;
qse_htl_hasher_t hasher;
qse_htl_comper_t comper;
qse_htl_freeer_t freeer;
qse_htl_copier_t copier;
qse_htl_node_t null;
qse_htl_node_t** buckets;
};
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The qse_htl_open() function creates an hash table.
*/
QSE_EXPORT qse_htl_t* qse_htl_open (
qse_mmgr_t* mmgr,
qse_size_t xtnsize,
int scale
);
/**
* The qse_htl_close() function destroys an hash table.
*/
QSE_EXPORT void qse_htl_close (
qse_htl_t* htl /**< hash table */
);
/**
* The qse_htl_open() function initializes an hash table.
*/
QSE_EXPORT int qse_htl_init (
qse_htl_t* htl,
qse_mmgr_t* mmgr,
int scale
);
/**
* The qse_htl_close() function finalizes an hash table.
*/
QSE_EXPORT void qse_htl_fini (
qse_htl_t* htl /**< hash table */
);
#if defined(QSE_HAVE_INLINE)
static QSE_INLINE qse_mmgr_t* qse_htl_getmmgr (qse_htl_t* htl) { return (htl)->mmgr; }
#else
#define qse_htl_getmmgr(htl) ((htl)->mmgr))
#endif
#if defined(QSE_HAVE_INLINE)
static QSE_INLINE void* qse_htl_getxtn (qse_htl_t* htl) { return QSE_XTN(htl); }
#else
#define qse_htl_getxtn(htl) (QSE_XTN(htl))
#endif
#if defined(QSE_HAVE_INLINE)
static QSE_INLINE int qse_htl_getsize (qse_htl_t* htl) { return htl->num_elements; }
#else
#define qse_htl_getsize(htl) ((htl)->num_elements)
#endif
#if defined(QSE_HAVE_INLINE)
static QSE_INLINE qse_htl_hasher_t qse_htl_gethasher (qse_htl_t* htl) { return htl->hasher; }
static QSE_INLINE qse_htl_comper_t qse_htl_getcomper (qse_htl_t* htl) { return htl->comper; }
static QSE_INLINE qse_htl_freeer_t qse_htl_getfreeer (qse_htl_t* htl) { return htl->freeer; }
static QSE_INLINE void qse_htl_sethasher (qse_htl_t* htl, qse_htl_hasher_t _hasher) { htl->hasher = _hasher; }
static QSE_INLINE void qse_htl_setcomper (qse_htl_t* htl, qse_htl_comper_t _comper) { htl->comper = _comper; }
static QSE_INLINE void qse_htl_setfreeer (qse_htl_t* htl, qse_htl_freeer_t _freeer) { htl->freeer = _freeer; }
static QSE_INLINE void qse_htl_setcopier (qse_htl_t* htl, qse_htl_copier_t _copier) { htl->copier = _copier; }
#else
#define qse_htl_gethasher(htl) ((htl)->hasher)
#define qse_htl_getcomper(htl) ((htl)->comper)
#define qse_htl_getfreeer(htl) ((htl)->freeer)
#define qse_htl_sethasher(htl,_hasher) ((htl)->hasher = (_hasher))
#define qse_htl_setcomper(htl,_comper) ((htl)->comper = (_comper))
#define qse_htl_setfreeer(htl,_freeer) ((htl)->freeer = (_freeer))
#define qse_htl_setcopier(htl,_copier) ((htl)->copier = (_copier))
#endif
/**
* The qse_htl_search() function searches a hash table to find a
* matching item. It returns the index to the slot of an internal array
* where the matching item is found.
* \return slot index if a match if found,
* #QSE_NULL if no match is found.
*/
QSE_EXPORT qse_htl_node_t* qse_htl_search (
qse_htl_t* htl, /**< hash table */
const void* data /**< data pointer */
);
QSE_EXPORT qse_htl_node_t* qse_htl_heterosearch (
qse_htl_t* htl, /**< hash table */
const void* data, /**< data pointer */
qse_htl_hasher_t hasher,
qse_htl_comper_t comper
);
/**
* The qse_htl_insert() function inserts a new item. It fails if it finds
* an existing item.
* \return a node pointer on success, #QSE_NULL on failure.
*/
QSE_EXPORT qse_htl_node_t* qse_htl_insert (
qse_htl_t* htl, /**< hash table */
void* data /**< data pointer */
);
/**
* The qse_htl_upsert() function inserts a new item if it finds no matching
* item or updates an exsting item if finds a matching item.
* \return node pointer on success, #QSE_NULL on failure.
*/
QSE_EXPORT qse_htl_node_t* qse_htl_upsert (
qse_htl_t* htl, /**< hash table */
void* data /**< data pointer */
);
/**
* The qse_htl_update() function updates an existing item. It fails if it finds
* no existing item.
* \return a node pointer on success, #QSE_NULL on failure.
*/
QSE_EXPORT qse_htl_node_t* qse_htl_update (
qse_htl_t* htl, /**< hash table */
void* data /**< data pointer */
);
/**
* The qse_htl_upyank() function updates an existing dataum without disposing
* the old data.
*/
QSE_EXPORT qse_htl_node_t* qse_htl_upyank (
qse_htl_t* htl, /**< hash table */
void* data, /**< data pointer */
void** oldata /**< old data pointer */
);
/**
* The qse_htl_ensert() function inserts a new item if one is not found.
* It returns an existing item otherwise.
*/
QSE_EXPORT qse_htl_node_t* qse_htl_ensert (
qse_htl_t* htl, /**< hash table */
void* data /**< data pointer */
);
/**
* The qse_htl_delete() function deletes an existing item. It fails if it finds
* no existing item.
* \return 0 on success, -1 on failure
*/
QSE_EXPORT int qse_htl_delete (
qse_htl_t* htl, /**< hash table */
void* data /**< data pointer */
);
QSE_EXPORT void* qse_htl_yank (
qse_htl_t* ht,
void* data
);
QSE_EXPORT qse_htl_node_t* qse_htl_yanknode (
qse_htl_t* ht,
void* data
);
/**
* The qse_htl_clear() functions deletes all data items.
*/
QSE_EXPORT void qse_htl_clear (
qse_htl_t* htl /**< hash table */
);
/**
* The qse_htl_walk() function executes the callback function @a walker for
* each valid data item.
*/
QSE_EXPORT void qse_htl_walk (
qse_htl_t* htl, /**< hash table */
qse_htl_walker_t walker, /**< callback function */
void* ctx /**< context */
);
/* ------------------------------------------------------------------------- */
QSE_EXPORT qse_uint32_t qse_genhash32_update (const void* data, qse_size_t size, qse_uint32_t hash);
QSE_EXPORT qse_uint32_t qse_genhash32 (const void *data, qse_size_t size);
/*qse_uint32_t qse_foldhash32 (qse_uint32_t hash, int bits);*/
QSE_EXPORT qse_uint32_t qse_mbshash32 (const qse_mchar_t* p);
QSE_EXPORT qse_uint32_t qse_wcshash32 (const qse_wchar_t* p);
QSE_EXPORT qse_uint32_t qse_mbscasehash32 (const qse_mchar_t* p);
QSE_EXPORT qse_uint32_t qse_wcscasehash32 (const qse_wchar_t* p);
#if defined(QSE_CHAR_IS_WCHAR)
# define qse_strhash32(x) qse_wcshash32(x)
# define qse_strcasehash32(x) qse_wcscasehash32(x)
#else
# define qse_strhash32(x) qse_mbshash32(x)
# define qse_strcasehash32(x) qse_mbscasehash32(x)
#endif
#if defined(__cplusplus)
}
#endif
#endif

370
include/qse/cmn/hton.h Normal file
View File

@@ -0,0 +1,370 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_HTON_H_
#define _QSE_CMN_HTON_H_
#include <qse/types.h>
#include <qse/macros.h>
#define QSE_CONST_BSWAP16(x) \
((qse_uint16_t)((((qse_uint16_t)(x) & ((qse_uint16_t)0xff << 0)) << 8) | \
(((qse_uint16_t)(x) & ((qse_uint16_t)0xff << 8)) >> 8)))
#define QSE_CONST_BSWAP32(x) \
((qse_uint32_t)((((qse_uint32_t)(x) & ((qse_uint32_t)0xff << 0)) << 24) | \
(((qse_uint32_t)(x) & ((qse_uint32_t)0xff << 8)) << 8) | \
(((qse_uint32_t)(x) & ((qse_uint32_t)0xff << 16)) >> 8) | \
(((qse_uint32_t)(x) & ((qse_uint32_t)0xff << 24)) >> 24)))
#if defined(QSE_HAVE_UINT64_T)
#define QSE_CONST_BSWAP64(x) \
((qse_uint64_t)((((qse_uint64_t)(x) & ((qse_uint64_t)0xff << 0)) << 56) | \
(((qse_uint64_t)(x) & ((qse_uint64_t)0xff << 8)) << 40) | \
(((qse_uint64_t)(x) & ((qse_uint64_t)0xff << 16)) << 24) | \
(((qse_uint64_t)(x) & ((qse_uint64_t)0xff << 24)) << 8) | \
(((qse_uint64_t)(x) & ((qse_uint64_t)0xff << 32)) >> 8) | \
(((qse_uint64_t)(x) & ((qse_uint64_t)0xff << 40)) >> 24) | \
(((qse_uint64_t)(x) & ((qse_uint64_t)0xff << 48)) >> 40) | \
(((qse_uint64_t)(x) & ((qse_uint64_t)0xff << 56)) >> 56)))
#endif
#if defined(QSE_HAVE_UINT128_T)
#define QSE_CONST_BSWAP128(x) \
((qse_uint128_t)((((qse_uint128_t)(x) & ((qse_uint128_t)0xff << 0)) << 120) | \
(((qse_uint128_t)(x) & ((qse_uint128_t)0xff << 8)) << 104) | \
(((qse_uint128_t)(x) & ((qse_uint128_t)0xff << 16)) << 88) | \
(((qse_uint128_t)(x) & ((qse_uint128_t)0xff << 24)) << 72) | \
(((qse_uint128_t)(x) & ((qse_uint128_t)0xff << 32)) << 56) | \
(((qse_uint128_t)(x) & ((qse_uint128_t)0xff << 40)) << 40) | \
(((qse_uint128_t)(x) & ((qse_uint128_t)0xff << 48)) << 24) | \
(((qse_uint128_t)(x) & ((qse_uint128_t)0xff << 56)) << 8) | \
(((qse_uint128_t)(x) & ((qse_uint128_t)0xff << 64)) >> 8) | \
(((qse_uint128_t)(x) & ((qse_uint128_t)0xff << 72)) >> 24) | \
(((qse_uint128_t)(x) & ((qse_uint128_t)0xff << 80)) >> 40) | \
(((qse_uint128_t)(x) & ((qse_uint128_t)0xff << 88)) >> 56) | \
(((qse_uint128_t)(x) & ((qse_uint128_t)0xff << 96)) >> 72) | \
(((qse_uint128_t)(x) & ((qse_uint128_t)0xff << 104)) >> 88) | \
(((qse_uint128_t)(x) & ((qse_uint128_t)0xff << 112)) >> 104) | \
(((qse_uint128_t)(x) & ((qse_uint128_t)0xff << 120)) >> 120)))
#endif
#if defined(QSE_ENDIAN_LITTLE)
# if defined(QSE_HAVE_UINT16_T)
# define QSE_CONST_NTOH16(x) QSE_CONST_BSWAP16(x)
# define QSE_CONST_HTON16(x) QSE_CONST_BSWAP16(x)
# define QSE_CONST_HTOBE16(x) QSE_CONST_BSWAP16(x)
# define QSE_CONST_HTOLE16(x) (x)
# define QSE_CONST_BE16TOH(x) QSE_CONST_BSWAP16(x)
# define QSE_CONST_LE16TOH(x) (x)
# endif
# if defined(QSE_HAVE_UINT32_T)
# define QSE_CONST_NTOH32(x) QSE_CONST_BSWAP32(x)
# define QSE_CONST_HTON32(x) QSE_CONST_BSWAP32(x)
# define QSE_CONST_HTOBE32(x) QSE_CONST_BSWAP32(x)
# define QSE_CONST_HTOLE32(x) (x)
# define QSE_CONST_BE32TOH(x) QSE_CONST_BSWAP32(x)
# define QSE_CONST_LE32TOH(x) (x)
# endif
# if defined(QSE_HAVE_UINT64_T)
# define QSE_CONST_NTOH64(x) QSE_CONST_BSWAP64(x)
# define QSE_CONST_HTON64(x) QSE_CONST_BSWAP64(x)
# define QSE_CONST_HTOBE64(x) QSE_CONST_BSWAP64(x)
# define QSE_CONST_HTOLE64(x) (x)
# define QSE_CONST_BE64TOH(x) QSE_CONST_BSWAP64(x)
# define QSE_CONST_LE64TOH(x) (x)
# endif
# if defined(QSE_HAVE_UINT128_T)
# define QSE_CONST_NTOH128(x) QSE_CONST_BSWAP128(x)
# define QSE_CONST_HTON128(x) QSE_CONST_BSWAP128(x)
# define QSE_CONST_HTOBE128(x) QSE_CONST_BSWAP128(x)
# define QSE_CONST_HTOLE128(x) (x)
# define QSE_CONST_BE128TOH(x) QSE_CONST_BSWAP128(x)
# define QSE_CONST_LE128TOH(x) (x)
#endif
#elif defined(QSE_ENDIAN_BIG)
# if defined(QSE_HAVE_UINT16_T)
# define QSE_CONST_NTOH16(x) (x)
# define QSE_CONST_HTON16(x) (x)
# define QSE_CONST_HTOBE16(x) (x)
# define QSE_CONST_HTOLE16(x) QSE_CONST_BSWAP16(x)
# define QSE_CONST_BE16TOH(x) (x)
# define QSE_CONST_LE16TOH(x) QSE_CONST_BSWAP16(x)
# endif
# if defined(QSE_HAVE_UINT32_T)
# define QSE_CONST_NTOH32(x) (x)
# define QSE_CONST_HTON32(x) (x)
# define QSE_CONST_HTOBE32(x) (x)
# define QSE_CONST_HTOLE32(x) QSE_CONST_BSWAP32(x)
# define QSE_CONST_BE32TOH(x) (x)
# define QSE_CONST_LE32TOH(x) QSE_CONST_BSWAP32(x)
# endif
# if defined(QSE_HAVE_UINT64_T)
# define QSE_CONST_NTOH64(x) (x)
# define QSE_CONST_HTON64(x) (x)
# define QSE_CONST_HTOBE64(x) (x)
# define QSE_CONST_HTOLE64(x) QSE_CONST_BSWAP64(x)
# define QSE_CONST_BE64TOH(x) (x)
# define QSE_CONST_LE64TOH(x) QSE_CONST_BSWAP64(x)
# endif
# if defined(QSE_HAVE_UINT128_T)
# define QSE_CONST_NTOH128(x) (x)
# define QSE_CONST_HTON128(x) (x)
# define QSE_CONST_HTOBE128(x) (x)
# define QSE_CONST_HTOLE128(x) QSE_CONST_BSWAP128(x)
# define QSE_CONST_BE128TOH(x) (x)
# define QSE_CONST_LE128TOH(x) QSE_CONST_BSWAP128(x)
# endif
#else
# error UNKNOWN ENDIAN
#endif
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(QSE_HAVE_INLINE)
#if defined(QSE_HAVE_UINT16_T)
static QSE_INLINE qse_uint16_t qse_bswap16 (qse_uint16_t x)
{
#if defined(QSE_HAVE_BUILTIN_BSWAP16)
return __builtin_bswap16(x);
#elif defined(__GNUC__) && (defined(__x86_64) || defined(__amd64) || defined(__i386) || defined(i386))
__asm__ volatile ("xchgb %b0, %h0" : "=Q"(x): "0"(x));
return x;
#else
return (x << 8) | (x >> 8);
#endif
}
#endif
#if defined(QSE_HAVE_UINT32_T)
static QSE_INLINE qse_uint32_t qse_bswap32 (qse_uint32_t x)
{
#if defined(QSE_HAVE_BUILTIN_BSWAP32)
return __builtin_bswap32(x);
#elif defined(__GNUC__) && (defined(__x86_64) || defined(__amd64) || defined(__i386) || defined(i386))
__asm__ volatile ("bswapl %0" : "=r"(x) : "0"(x));
return x;
#else
return ((x >> 24)) |
((x >> 8) & ((qse_uint32_t)0xff << 8)) |
((x << 8) & ((qse_uint32_t)0xff << 16)) |
((x << 24));
#endif
}
#endif
#if defined(QSE_HAVE_UINT64_T)
static QSE_INLINE qse_uint64_t qse_bswap64 (qse_uint64_t x)
{
#if defined(QSE_HAVE_BUILTIN_BSWAP64)
return __builtin_bswap64(x);
#elif defined(__GNUC__) && (defined(__x86_64) || defined(__amd64))
__asm__ volatile ("bswapq %0" : "=r"(x) : "0"(x));
return x;
#else
return ((x >> 56)) |
((x >> 40) & ((qse_uint64_t)0xff << 8)) |
((x >> 24) & ((qse_uint64_t)0xff << 16)) |
((x >> 8) & ((qse_uint64_t)0xff << 24)) |
((x << 8) & ((qse_uint64_t)0xff << 32)) |
((x << 24) & ((qse_uint64_t)0xff << 40)) |
((x << 40) & ((qse_uint64_t)0xff << 48)) |
((x << 56));
#endif
}
#endif
#if defined(QSE_HAVE_UINT128_T)
static QSE_INLINE qse_uint128_t qse_bswap128 (qse_uint128_t x)
{
#if defined(QSE_HAVE_BUILTIN_BSWAP128)
return __builtin_bswap128(x);
#else
return ((x >> 120)) |
((x >> 104) & ((qse_uint128_t)0xff << 8)) |
((x >> 88) & ((qse_uint128_t)0xff << 16)) |
((x >> 72) & ((qse_uint128_t)0xff << 24)) |
((x >> 56) & ((qse_uint128_t)0xff << 32)) |
((x >> 40) & ((qse_uint128_t)0xff << 40)) |
((x >> 24) & ((qse_uint128_t)0xff << 48)) |
((x >> 8) & ((qse_uint128_t)0xff << 56)) |
((x << 8) & ((qse_uint128_t)0xff << 64)) |
((x << 24) & ((qse_uint128_t)0xff << 72)) |
((x << 40) & ((qse_uint128_t)0xff << 80)) |
((x << 56) & ((qse_uint128_t)0xff << 88)) |
((x << 72) & ((qse_uint128_t)0xff << 96)) |
((x << 88) & ((qse_uint128_t)0xff << 104)) |
((x << 104) & ((qse_uint128_t)0xff << 112)) |
((x << 120));
#endif
}
#endif
#else
#if defined(QSE_HAVE_UINT16_T)
# define qse_bswap16(x) ((qse_uint16_t)(((qse_uint16_t)(x)) << 8) | (((qse_uint16_t)(x)) >> 8))
#endif
#if defined(QSE_HAVE_UINT32_T)
# define qse_bswap32(x) ((qse_uint32_t)(((((qse_uint32_t)(x)) >> 24)) | \
((((qse_uint32_t)(x)) >> 8) & ((qse_uint32_t)0xff << 8)) | \
((((qse_uint32_t)(x)) << 8) & ((qse_uint32_t)0xff << 16)) | \
((((qse_uint32_t)(x)) << 24))))
#endif
#if defined(QSE_HAVE_UINT64_T)
# define qse_bswap64(x) ((qse_uint64_t)(((((qse_uint64_t)(x)) >> 56)) | \
((((qse_uint64_t)(x)) >> 40) & ((qse_uint64_t)0xff << 8)) | \
((((qse_uint64_t)(x)) >> 24) & ((qse_uint64_t)0xff << 16)) | \
((((qse_uint64_t)(x)) >> 8) & ((qse_uint64_t)0xff << 24)) | \
((((qse_uint64_t)(x)) << 8) & ((qse_uint64_t)0xff << 32)) | \
((((qse_uint64_t)(x)) << 24) & ((qse_uint64_t)0xff << 40)) | \
((((qse_uint64_t)(x)) << 40) & ((qse_uint64_t)0xff << 48)) | \
((((qse_uint64_t)(x)) << 56))))
#endif
#if defined(QSE_HAVE_UINT128_T)
# define qse_bswap128(x) ((qse_uint128_t)(((((qse_uint128_t)(x)) >> 120)) | \
((((qse_uint128_t)(x)) >> 104) & ((qse_uint128_t)0xff << 8)) | \
((((qse_uint128_t)(x)) >> 88) & ((qse_uint128_t)0xff << 16)) | \
((((qse_uint128_t)(x)) >> 72) & ((qse_uint128_t)0xff << 24)) | \
((((qse_uint128_t)(x)) >> 56) & ((qse_uint128_t)0xff << 32)) | \
((((qse_uint128_t)(x)) >> 40) & ((qse_uint128_t)0xff << 40)) | \
((((qse_uint128_t)(x)) >> 24) & ((qse_uint128_t)0xff << 48)) | \
((((qse_uint128_t)(x)) >> 8) & ((qse_uint128_t)0xff << 56)) | \
((((qse_uint128_t)(x)) << 8) & ((qse_uint128_t)0xff << 64)) | \
((((qse_uint128_t)(x)) << 24) & ((qse_uint128_t)0xff << 72)) | \
((((qse_uint128_t)(x)) << 40) & ((qse_uint128_t)0xff << 80)) | \
((((qse_uint128_t)(x)) << 56) & ((qse_uint128_t)0xff << 88)) | \
((((qse_uint128_t)(x)) << 72) & ((qse_uint128_t)0xff << 96)) | \
((((qse_uint128_t)(x)) << 88) & ((qse_uint128_t)0xff << 104)) | \
((((qse_uint128_t)(x)) << 104) & ((qse_uint128_t)0xff << 112)) | \
((((qse_uint128_t)(x)) << 120))))
#endif
#endif /* QSE_HAVE_INLINE */
#if defined(QSE_ENDIAN_LITTLE)
# if defined(QSE_HAVE_UINT16_T)
# define qse_hton16(x) qse_bswap16(x)
# define qse_ntoh16(x) qse_bswap16(x)
# define qse_htobe16(x) qse_bswap16(x)
# define qse_be16toh(x) qse_bswap16(x)
# define qse_htole16(x) ((qse_uint16_t)(x))
# define qse_le16toh(x) ((qse_uint16_t)(x))
# endif
# if defined(QSE_HAVE_UINT32_T)
# define qse_hton32(x) qse_bswap32(x)
# define qse_ntoh32(x) qse_bswap32(x)
# define qse_htobe32(x) qse_bswap32(x)
# define qse_be32toh(x) qse_bswap32(x)
# define qse_htole32(x) ((qse_uint32_t)(x))
# define qse_le32toh(x) ((qse_uint32_t)(x))
# endif
# if defined(QSE_HAVE_UINT64_T)
# define qse_hton64(x) qse_bswap64(x)
# define qse_ntoh64(x) qse_bswap64(x)
# define qse_htobe64(x) qse_bswap64(x)
# define qse_be64toh(x) qse_bswap64(x)
# define qse_htole64(x) ((qse_uint64_t)(x))
# define qse_le64toh(x) ((qse_uint64_t)(x))
# endif
# if defined(QSE_HAVE_UINT128_T)
# define qse_hton128(x) qse_bswap128(x)
# define qse_ntoh128(x) qse_bswap128(x)
# define qse_htobe128(x) qse_bswap128(x)
# define qse_be128toh(x) qse_bswap128(x)
# define qse_htole128(x) ((qse_uint128_t)(x))
# define qse_le128toh(x) ((qse_uint128_t)(x))
# endif
#elif defined(QSE_ENDIAN_BIG)
# if defined(QSE_HAVE_UINT16_T)
# define qse_hton16(x) ((qse_uint16_t)(x))
# define qse_ntoh16(x) ((qse_uint16_t)(x))
# define qse_htobe16(x) ((qse_uint16_t)(x))
# define qse_be16toh(x) ((qse_uint16_t)(x))
# define qse_htole16(x) qse_bswap16(x)
# define qse_le16toh(x) qse_bswap16(x)
# endif
# if defined(QSE_HAVE_UINT32_T)
# define qse_hton32(x) ((qse_uint32_t)(x))
# define qse_ntoh32(x) ((qse_uint32_t)(x))
# define qse_htobe32(x) ((qse_uint32_t)(x))
# define qse_be32toh(x) ((qse_uint32_t)(x))
# define qse_htole32(x) qse_bswap32(x)
# define qse_le32toh(x) qse_bswap32(x)
# endif
# if defined(QSE_HAVE_UINT64_T)
# define qse_hton64(x) ((qse_uint64_t)(x))
# define qse_ntoh64(x) ((qse_uint64_t)(x))
# define qse_htobe64(x) ((qse_uint64_t)(x))
# define qse_be64toh(x) ((qse_uint64_t)(x))
# define qse_htole64(x) qse_bswap64(x)
# define qse_le64toh(x) qse_bswap64(x)
# endif
# if defined(QSE_HAVE_UINT128_T)
# define qse_hton128(x) ((qse_uint128_t)(x))
# define qse_ntoh128(x) ((qse_uint128_t)(x))
# define qse_htobe128(x) ((qse_uint128_t)(x))
# define qse_be128toh(x) ((qse_uint128_t)(x))
# define qse_htole128(x) qse_bswap128(x)
# define qse_le128toh(x) qse_bswap128(x)
# endif
#else
# error UNKNOWN ENDIAN
#endif
#if defined(__cplusplus)
}
#endif
#endif

96
include/qse/cmn/hwad.h Normal file
View File

@@ -0,0 +1,96 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_HWAD_H_
#define _QSE_CMN_HWAD_H_
#include <qse/types.h>
#include <qse/macros.h>
#define QSE_ETHWAD_LEN 6
#include <qse/pack1.h>
struct qse_ethwad_t
{
qse_uint8_t value[QSE_ETHWAD_LEN];
};
#include <qse/unpack.h>
typedef struct qse_ethwad_t qse_ethwad_t;
#if defined(__cplusplus)
extern "C" {
#endif
QSE_EXPORT int qse_mbstoethwad (
const qse_mchar_t* mbs,
qse_ethwad_t* hwad
);
QSE_EXPORT int qse_mbsntoethwad (
const qse_mchar_t* mbs,
qse_size_t len,
qse_ethwad_t* hwad
);
QSE_EXPORT qse_size_t qse_ethwadtombs (
const qse_ethwad_t* hwaddr,
qse_mchar_t* buf,
qse_size_t size
);
QSE_EXPORT int qse_wcstoethwad (
const qse_wchar_t* mbs,
qse_ethwad_t* hwad
);
QSE_EXPORT int qse_wcsntoethwad (
const qse_wchar_t* mbs,
qse_size_t len,
qse_ethwad_t* hwad
);
QSE_EXPORT qse_size_t qse_ethwadtowcs (
const qse_ethwad_t* hwaddr,
qse_wchar_t* buf,
qse_size_t size
);
#if defined(QSE_CHAR_IS_MCHAR)
# define qse_strtoethwad(ptr,hwad) qse_mbstoethwad(ptr,hwad)
# define qse_strntoethwad(ptr,len,hwad) qse_mbsntoethwad(ptr,len,hwad)
# define qse_ethwadtostr(hwad,ptr,len) qse_ethwadtombs(hwad,ptr,len)
#else
# define qse_strtoethwad(ptr,hwad) qse_wcstoethwad(ptr,hwad)
# define qse_strntoethwad(ptr,len,hwad) qse_wcsntoethwad(ptr,len,hwad)
# define qse_ethwadtostr(hwad,ptr,len) qse_ethwadtowcs(hwad,ptr,len)
#endif
#if defined(__cplusplus)
}
#endif
#endif

405
include/qse/cmn/ipad.h Normal file
View File

@@ -0,0 +1,405 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_IPAD_H_
#define _QSE_CMN_IPAD_H_
#include <qse/types.h>
#include <qse/macros.h>
#include <qse/cmn/hton.h>
typedef struct qse_ip4ad_t qse_ip4ad_t;
typedef struct qse_ip6ad_t qse_ip6ad_t;
#include <qse/pack1.h>
struct qse_ip4ad_t
{
qse_uint32_t value;
};
struct qse_ip6ad_t
{
qse_uint8_t value[16];
};
/* 127.0.0.0/8 */
#define QSE_IP4AD_IS_LOOPBACK(addr) ((((addr)->value) & QSE_CONST_HTON32(0xFF000000u)) == QSE_CONST_HTON32(0x7F000000u))
/* 169.254.0.0/16 */
#define QSE_IP4AD_IS_LINK_LOCAL(addr) ((((addr)->value) & QSE_CONST_HTON32(0xFFFF0000u)) == QSE_CONST_HTON32(0xA9FE0000u))
/* 224.0.0.0/4 */
#define QSE_IP4AD_IS_MULTICAST(addr) ((((addr)->value) & QSE_CONST_HTON32(0xF0000000u)) == QSE_CONST_HTON32(0xE0000000u))
/* ::1 */
#define QSE_IP6AD_IS_LOOPBACK(addr) \
((addr)->value[0] == 0 && (addr)->value[1] == 0 && \
(addr)->value[2] == 0 && (addr)->value[3] == 0 && \
(addr)->value[4] == 0 && (addr)->value[5] == 0 && \
(addr)->value[6] == 0 && (addr)->value[7] == 0 && \
(addr)->value[8] == 0 && (addr)->value[9] == 0 && \
(addr)->value[10] == 0 && (addr)->value[11] == 0 && \
(addr)->value[12] == 0 && (addr)->value[13] == 0 && \
(addr)->value[14] == 0 && (addr)->value[15] == 1)
/* FE80::/10 */
#define QSE_IP6AD_IS_LINK_LOCAL(addr) (this->value[0] == 0xFE && (this->value[1] & 0xC0) == 0x80)
/* FEC0::/10 */
#define QSE_IP6AD_IS_SITE_LOCAL(addr) (this->value[0] == 0xFE && (this->value[1] & 0xC0) == 0xC0)
/* FF00::/8 */
#define QSE_IP6AD_IS_MULTICAST(addr) ((addr)->value[0] == 0xFF)
#define QSE_IP6AD_IS_MULTICAST_LINK_LOCAL(addr) ((addr)->value[0] == 0xFF && ((addr)->value[1] & 0x0F) == 0x02)
#define QSE_IP6AD_IS_MULTICAST_SITE_LOCAL(addr) ((addr)->value[0] == 0xFF && ((addr)->value[1] & 0x0F) == 0x05)
#define QSE_IP6AD_IS_MULTICAST_ORGANIZATION(addr) ((addr)->value[0] == 0xFF && ((addr)->value[1] & 0x0F) == 0x08)
#define QSE_IP6AD_IS_MULTICAST_GLOBAL(addr) ((addr)->value[0] == 0xFF && ((addr)->value[1] & 0x0F) == 0x0E)
#define QSE_IP6AD_IS_MULTICAST_INTERFACE_LOCAL(addr) ((addr)->value[0] == 0xFF && ((addr)->value[1] & 0x0F) == 0x01)
#if defined(__cplusplus)
struct qse_ip4adxx_t: public qse_ip4ad_t
{
qse_ip4adxx_t (qse_uint32_t v = 0)
{
this->value = v;
}
bool operator== (const qse_ip4adxx_t& peer) const { return this->value == peer.value; }
bool operator!= (const qse_ip4adxx_t& peer) const { return this->value != peer.value; }
bool operator< (const qse_ip4adxx_t& peer) const { return qse_ntoh32(this->value) < qse_ntoh32(peer.value); }
bool operator<= (const qse_ip4adxx_t& peer) const { return qse_ntoh32(this->value) <= qse_ntoh32(peer.value); }
bool operator> (const qse_ip4adxx_t& peer) const { return qse_ntoh32(this->value) > qse_ntoh32(peer.value); }
bool operator>= (const qse_ip4adxx_t& peer) const { return qse_ntoh32(this->value) >= qse_ntoh32(peer.value); }
qse_ip4adxx_t& operator= (const qse_ip4adxx_t& v)
{
this->value = v.value;
return *this;
}
qse_ip4adxx_t& operator+= (const qse_ip4adxx_t& v)
{
this->value = qse_hton32(qse_ntoh32(this->value) + qse_ntoh32(v.value));
return *this;
}
qse_ip4adxx_t& operator-= (const qse_ip4adxx_t& v)
{
this->value = qse_hton32(qse_ntoh32(this->value) - qse_ntoh32(v.value));
return *this;
}
qse_ip4adxx_t operator+ (const qse_ip4adxx_t& v) const
{
qse_ip4adxx_t x;
x.value = qse_hton32(qse_ntoh32(this->value) + qse_ntoh32(v.value));
return x;
}
qse_ip4adxx_t operator- (const qse_ip4adxx_t& v) const
{
qse_ip4adxx_t x;
x.value = qse_hton32(qse_ntoh32(this->value) - qse_ntoh32(v.value));
return x;
}
qse_ip4adxx_t& operator= (qse_uint32_t v)
{
this->value = qse_hton32(v);
return *this;
}
qse_ip4adxx_t& operator+= (qse_uint32_t v)
{
this->value = qse_hton32(qse_ntoh32(this->value) + v);
return *this;
}
qse_ip4adxx_t& operator-= (qse_uint32_t v)
{
this->value = qse_hton32(qse_ntoh32(this->value) - v);
return *this;
}
qse_ip4adxx_t operator+ (qse_uint32_t v) const
{
qse_ip4adxx_t x;
x.value = qse_hton32(qse_ntoh32(this->value) + v);
return x;
}
qse_ip4adxx_t operator- (qse_uint32_t v) const
{
qse_ip4adxx_t x;
x.value = qse_hton32(qse_ntoh32(this->value) - v);
return x;
}
};
struct qse_ip6adxx_t: public qse_ip6ad_t
{
struct ad64_t
{
qse_uint64_t w[2];
};
qse_ip6adxx_t ()
{
ad64_t* x = (ad64_t*)this->value;
x->w[0] = 0;
x->w[1] = 0;
}
qse_ip6adxx_t (qse_uint8_t (*value)[16])
{
ad64_t* x = (ad64_t*)this->value;
x->w[0] = ((ad64_t*)value)->w[0];
x->w[1] = ((ad64_t*)value)->w[1];
}
qse_ip6adxx_t (qse_uint8_t (&value)[16])
{
ad64_t* x = (ad64_t*)this->value;
x->w[0] = ((ad64_t*)&value)->w[0];
x->w[1] = ((ad64_t*)&value)->w[1];
}
bool operator== (const qse_ip4adxx_t& peer) const
{
ad64_t* x = (ad64_t*)this->value;
ad64_t* y = (ad64_t*)&peer.value;
return x->w[0] == y->w[0] && x->w[1] == y->w[1];
}
bool operator!= (const qse_ip4adxx_t& peer) const
{
ad64_t* x = (ad64_t*)this->value;
ad64_t* y = (ad64_t*)&peer.value;
return x->w[0] != y->w[0] || x->w[1] != y->w[1];
}
qse_ip6adxx_t& operator= (const qse_ip6adxx_t& v)
{
ad64_t* x = (ad64_t*)this->value;
x->w[0] = ((ad64_t*)&v)->w[0];
x->w[1] = ((ad64_t*)&v)->w[1];
return *this;
}
bool isZero() const
{
ad64_t* x = (ad64_t*)this->value;
return x->w[0] == 0 && x->w[1] == 0;
}
bool isLoopback() const
{
return QSE_IP6AD_IS_LOOPBACK(this);
}
bool isLinkLocal() const
{
// FE80::/10
return QSE_IP6AD_IS_LINK_LOCAL(this);
}
bool isSiteLocal() const
{
// FEC0::/10
return QSE_IP6AD_IS_SITE_LOCAL(this);
}
// multicast addresses
// ff02:: Link Local: spans the same topological region as the corresponding unicast scope, i.e. all nodes on the same LAN.
// ff05:: Site local: is intended to span a single site
// ff08:: Organization scope: Intended to span multiple sizes within the same organization
// ff0e:: Global scope, assigned by IANA.
// ff01:: Interface local: Spans only a single interface on a node and is useful only for loopback transmission of multicast.
bool isMulticast() const
{
return QSE_IP6AD_IS_MULTICAST(this);
}
bool isMulticastLinkLocal() const
{
return QSE_IP6AD_IS_MULTICAST_LINK_LOCAL(this);
}
bool isMulticastSiteLocal() const
{
return QSE_IP6AD_IS_MULTICAST_SITE_LOCAL(this);
}
bool isMulticastOrganization() const
{
return QSE_IP6AD_IS_MULTICAST_ORGANIZATION(this);
}
bool isMulticastGlobal() const
{
return QSE_IP6AD_IS_MULTICAST_GLOBAL(this);
}
bool isMulticastInterfaceLocal() const
{
return QSE_IP6AD_IS_MULTICAST_INTERFACE_LOCAL(this);
}
bool isV4Mapped () const
{
return this->value[0] == 0x00 && this->value[1] == 0x00 &&
this->value[2] == 0x00 && this->value[3] == 0x00 &&
this->value[4] == 0x00 && this->value[5] == 0x00 &&
this->value[6] == 0x00 && this->value[7] == 0x00 &&
this->value[8] == 0x00 && this->value[9] == 0x00 &&
this->value[10] == 0xFF && this->value[11] == 0xFF;
}
};
#endif
#include <qse/unpack.h>
#if defined(__cplusplus)
extern "C" {
#endif
QSE_EXPORT int qse_mbstoip4ad (
const qse_mchar_t* mbs,
qse_ip4ad_t* ipad
);
QSE_EXPORT int qse_mbsntoip4ad (
const qse_mchar_t* mbs,
qse_size_t len,
qse_ip4ad_t* ipad
);
QSE_EXPORT int qse_wcstoip4ad (
const qse_wchar_t* wcs,
qse_ip4ad_t* ipad
);
QSE_EXPORT int qse_wcsntoip4ad (
const qse_wchar_t* wcs,
qse_size_t len,
qse_ip4ad_t* ipad
);
QSE_EXPORT qse_size_t qse_ip4adtombs (
const qse_ip4ad_t* ipad,
qse_mchar_t* mbs,
qse_size_t len
);
QSE_EXPORT qse_size_t qse_ip4adtowcs (
const qse_ip4ad_t* ipad,
qse_wchar_t* wcs,
qse_size_t len
);
#if defined(QSE_CHAR_IS_MCHAR)
# define qse_strtoip4ad(ptr,ipad) qse_mbstoip4ad(ptr,ipad)
# define qse_strntoip4ad(ptr,len,ipad) qse_mbsntoip4ad(ptr,len,ipad)
# define qse_ip4adtostr(ipad,ptr,len) qse_ip4adtombs(ipad,ptr,len)
#else
# define qse_strtoip4ad(ptr,ipad) qse_wcstoip4ad(ptr,ipad)
# define qse_strntoip4ad(ptr,len,ipad) qse_wcsntoip4ad(ptr,len,ipad)
# define qse_ip4adtostr(ipad,ptr,len) qse_ip4adtowcs(ipad,ptr,len)
#endif
QSE_EXPORT int qse_mbstoip6ad (
const qse_mchar_t* mbs,
qse_ip6ad_t* ipad
);
QSE_EXPORT int qse_mbsntoip6ad (
const qse_mchar_t* mbs,
qse_size_t len,
qse_ip6ad_t* ipad
);
QSE_EXPORT int qse_wcstoip6ad (
const qse_wchar_t* wcs,
qse_ip6ad_t* ipad
);
QSE_EXPORT int qse_wcsntoip6ad (
const qse_wchar_t* wcs,
qse_size_t len,
qse_ip6ad_t* ipad
);
QSE_EXPORT qse_size_t qse_ip6adtombs (
const qse_ip6ad_t* ipad,
qse_mchar_t* mbs,
qse_size_t len
);
QSE_EXPORT qse_size_t qse_ip6adtowcs (
const qse_ip6ad_t* ipad,
qse_wchar_t* wcs,
qse_size_t len
);
#if defined(QSE_CHAR_IS_MCHAR)
# define qse_strtoip6ad(ptr,ipad) qse_mbstoip6ad(ptr,ipad)
# define qse_strntoip6ad(ptr,len,ipad) qse_mbsntoip6ad(ptr,len,ipad)
# define qse_ip6adtostr(ipad,ptr,len) qse_ip6adtombs(ipad,ptr,len)
#else
# define qse_strtoip6ad(ptr,ipad) qse_wcstoip6ad(ptr,ipad)
# define qse_strntoip6ad(ptr,len,ipad) qse_wcsntoip6ad(ptr,len,ipad)
# define qse_ip6adtostr(ipad,ptr,len) qse_ip6adtowcs(ipad,ptr,len)
#endif
/*
* The qse_prefixtoip4ad() function converts the prefix length
* to an IPv4 address mask. The prefix length @a prefix must be
* between 0 and 32 inclusive.
* @return 0 on success, -1 on failure
*/
QSE_EXPORT int qse_prefixtoip4ad (
int prefix,
qse_ip4ad_t* ipad
);
/*
* The qse_prefixtoip4ad() function converts the prefix length
* to an IPv6 address mask. The prefix length @a prefix must be
* between 0 and 128 inclusive.
* @return 0 on success, -1 on failure
*/
QSE_EXPORT int qse_prefixtoip6ad (
int prefix,
qse_ip6ad_t* ipad
);
/*
* The qse_ip4adtoprefix() function returns the prefix length
* of the given IPv4 address mask.
*/
QSE_EXPORT int qse_ip4adtoprefix (
const qse_ip4ad_t* ipad
);
#if defined(__cplusplus)
}
#endif
#endif

120
include/qse/cmn/main.h Normal file
View File

@@ -0,0 +1,120 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_MAIN_H_
#define _QSE_CMN_MAIN_H_
#include <qse/types.h>
#include <qse/macros.h>
/** @file
* This file includes a macro and a function to help users to write a
* cross-platform main function.
*/
/**
* @def qse_main
* The qse_main macro defines a main function wrapper for an underlying
* platform. It is defined to @b main or @b wmain depending on the choice of
* the default character type #qse_char_t. Combined with the qse_run_main()
* function, it provides a consistant view to the main function.
*
* @typedef qse_achar_t
* The qse_achar_t type defines a character type for the second parameter to
* #qse_main. It is defined to #qse_mchar_t or #qse_wchar_t depending on the
* choice of the default character type #qse_char_t.
*/
#if defined(_WIN32) && defined(_MSC_VER)
# if defined(QSE_CHAR_IS_MCHAR)
# define qse_main main
# define QSE_ACHAR_IS_MCHAR
typedef qse_mchar_t qse_achar_t;
# else
# define qse_main wmain
# define QSE_ACHAR_IS_WCHAR
typedef qse_wchar_t qse_achar_t;
# endif
#elif defined(__OS2__)
# define qse_main main
# define QSE_ACHAR_IS_MCHAR
typedef qse_mchar_t qse_achar_t;
#else
# define qse_main main
# define QSE_ACHAR_IS_MCHAR
typedef qse_mchar_t qse_achar_t;
#endif
/**
* The qse_run_main_handler_t type defines the actual function to be
* executed by qse_run_main(). Unlike the standard main(), it is passed
* arguments in the #qse_char_t type.
*/
typedef int (*qse_run_main_handler_t) (
int argc,
qse_char_t* argv[]
);
typedef int (*qse_run_main_with_env_handler_t) (
int argc,
qse_char_t* argv[],
qse_char_t* envp[]
);
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The qse_run_main() function helps to invoke a main function independent of
* the character mode configured for the library.
*/
QSE_EXPORT int qse_run_main (
int argc,
qse_achar_t* argv[],
qse_run_main_handler_t handler
);
/**
* The qse_run_main_with_env() function helps to invoke a main function
* independent of the character mode configured for the library providing
* the enviroment list.
*/
QSE_EXPORT int qse_run_main_with_env (
int argc,
qse_achar_t* argv[],
qse_achar_t* envp[],
qse_run_main_with_env_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 */
#if defined(__cplusplus)
}
#endif
#endif

156
include/qse/cmn/map.h Normal file
View File

@@ -0,0 +1,156 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_MAP_H_
#define _QSE_CMN_MAP_H_
/*
* it is a convenience header file to switch easily between a red-black tree
* and a hash table. You must define either QSE_MAP_AS_HTB or QSE_MAP_AS_RBT
* before including this file.
*/
#if defined(QSE_MAP_AS_HTB)
# include <qse/cmn/htb.h>
# define QSE_MAP_STYLE_DEFAULT QSE_HTB_STYLE_DEFAULT
# define QSE_MAP_STYLE_INLINE_COPIERS QSE_HTB_STYLE_INLINE_COPIERS
# define QSE_MAP_STYLE_INLINE_KEY_COPIER QSE_HTB_STYLE_INLINE_KEY_COPIER
# define QSE_MAP_STYLE_INLINE_VALUE_COPIER QSE_HTB_STYLE_INLINE_VALUE_COPIER
# define qse_getmapstyle(kind) qse_gethtbstyle(kind)
# define qse_map_open(mmgr,ext,capa,factor,ks,vs) qse_htb_open(mmgr,ext,capa,factor,ks,vs)
# define qse_map_close(map) qse_htb_close(map)
# define qse_map_init(map,mmgr,capa,factor,ks,vs) qse_htb_init(map,mmgr,capa,factor,ks,vs)
# define qse_map_fini(map) qse_htb_fini(map)
# define qse_map_getsize(map) qse_htb_getsize(map)
# define qse_map_getcapa(map) qse_htb_getcapa(map)
# define qse_map_getstyle(map) qse_htb_getstyle(map)
# define qse_map_setstyle(map,cbs) qse_htb_setstyle(map,cbs)
# define qse_map_search(map,kptr,klen) qse_htb_search(map,kptr,klen)
# define qse_map_upsert(map,kptr,klen,vptr,vlen) qse_htb_upsert(map,kptr,klen,vptr,vlen)
# define qse_map_ensert(map,kptr,klen,vptr,vlen) qse_htb_ensert(map,kptr,klen,vptr,vlen)
# define qse_map_insert(map,kptr,klen,vptr,vlen) qse_htb_insert(map,kptr,klen,vptr,vlen)
# define qse_map_update(map,kptr,klen,vptr,vlen) qse_htb_update(map,kptr,klen,vptr,vlen)
# define qse_map_cbsert(map,kptr,klen,cb,ctx) qse_htb_cbsert(map,kptr,klen,cb,ctx)
# define qse_map_delete(map,kptr,klen) qse_htb_delete(map,kptr,klen)
# define qse_map_clear(map) qse_htb_clear(map)
# define qse_map_walk(map,walker,ctx) qse_htb_walk(map,walker,ctx)
# define QSE_MAP_WALK_STOP QSE_HTB_WALK_STOP
# define QSE_MAP_WALK_FORWARD QSE_HTB_WALK_FORWARD
# define qse_map_walk_t qse_htb_walk_t
# define QSE_MAP_KEY QSE_HTB_KEY
# define QSE_MAP_VAL QSE_HTB_VAL
# define qse_map_id_t qse_htb_id_t
# define qse_map_t qse_htb_t
# define qse_map_pair_t qse_htb_pair_t
# define qse_map_style_t qse_htb_style_t
# define qse_map_cbserter_t qse_htb_cbserter_t
# define qse_map_walker_t qse_htb_walker_t
# define QSE_MAP_COPIER_SIMPLE QSE_HTB_COPIER_SIMPLE
# define QSE_MAP_COPIER_INLINE QSE_HTB_COPIER_INLINE
# define QSE_MAP_COPIER_DEFAULT QSE_HTB_COPIER_DEFAULT
# define QSE_MAP_FREEER_DEFAULT QSE_HTB_FREEER_DEFAULT
# define QSE_MAP_COMPER_DEFAULT QSE_HTB_COMPER_DEFAULT
# define QSE_MAP_KEEPER_DEFAULT QSE_HTB_KEEPER_DEFAULT
# define QSE_MAP_SIZER_DEFAULT QSE_HTB_SIZER_DEFAULT
# define QSE_MAP_HASHER_DEFAULT QSE_HTB_HASHER_DEFAULT
# define QSE_MAP_SIZE(map) QSE_HTB_SIZE(map)
# define QSE_MAP_KCOPIER(map) QSE_HTB_KCOPIER(map)
# define QSE_MAP_VCOPIER(map) QSE_HTB_VCOPIER(map)
# define QSE_MAP_KFREEER(map) QSE_HTB_KFREEER(map)
# define QSE_MAP_VFREEER(map) QSE_HTB_VFREEER(map)
# define QSE_MAP_COMPER(map) QSE_HTB_COMPER(map)
# define QSE_MAP_KEEPER(map) QSE_HTB_KEEPER(map)
# define QSE_MAP_KSCALE(map) QSE_HTB_KSCALE(map)
# define QSE_MAP_VSCALE(map) QSE_HTB_VSCALE(map)
# define QSE_MAP_KPTL(p) QSE_HTB_KPTL(p)
# define QSE_MAP_VPTL(p) QSE_HTB_VPTL(p)
# define QSE_MAP_KPTR(p) QSE_HTB_KPTR(p)
# define QSE_MAP_KLEN(p) QSE_HTB_KLEN(p)
# define QSE_MAP_VPTR(p) QSE_HTB_VPTR(p)
# define QSE_MAP_VLEN(p) QSE_HTB_VLEN(p)
#elif defined(QSE_MAP_AS_RBT)
# include <qse/cmn/rbt.h>
# define QSE_MAP_STYLE_DEFAULT QSE_RBT_STYLE_DEFAULT
# define QSE_MAP_STYLE_INLINE_COPIERS QSE_RBT_STYLE_INLINE_COPIERS
# define QSE_MAP_STYLE_INLINE_KEY_COPIER QSE_RBT_STYLE_INLINE_KEY_COPIER
# define QSE_MAP_STYLE_INLINE_VALUE_COPIER QSE_RBT_STYLE_INLINE_VALUE_COPIER
# define qse_getmapstyle(kind) qse_getrbtstyle(kind)
# define qse_map_open(mmgr,ext,capa,factor,ks,vs) qse_rbt_open(mmgr,ext,ks,vs)
# define qse_map_close(map) qse_rbt_close(map)
# define qse_map_init(map,mmgr,capa,factor,ks,vs) qse_rbt_init(map,mmgr,ks,vs)
# define qse_map_fini(map) qse_rbt_fini(map)
# define qse_map_getsize(map) qse_rbt_getsize(map)
# define qse_map_getcapa(map) qse_rbt_getsize(map)
# define qse_map_getstyle(map) qse_rbt_getstyle(map)
# define qse_map_setstyle(map,cbs) qse_rbt_setstyle(map,cbs)
# define qse_map_search(map,kptr,klen) qse_rbt_search(map,kptr,klen)
# define qse_map_upsert(map,kptr,klen,vptr,vlen) qse_rbt_upsert(map,kptr,klen,vptr,vlen)
# define qse_map_ensert(map,kptr,klen,vptr,vlen) qse_rbt_ensert(map,kptr,klen,vptr,vlen)
# define qse_map_insert(map,kptr,klen,vptr,vlen) qse_rbt_insert(map,kptr,klen,vptr,vlen)
# define qse_map_update(map,kptr,klen,vptr,vlen) qse_rbt_update(map,kptr,klen,vptr,vlen)
# define qse_map_cbsert(map,kptr,klen,cb,ctx) qse_rbt_cbsert(map,kptr,klen,cb,ctx)
# define qse_map_delete(map,kptr,klen) qse_rbt_delete(map,kptr,klen)
# define qse_map_clear(map) qse_rbt_clear(map)
# define qse_map_walk(map,walker,ctx) qse_rbt_walk(map,walker,ctx)
# define QSE_MAP_WALK_STOP QSE_RBT_WALK_STOP
# define QSE_MAP_WALK_FORWARD QSE_RBT_WALK_FORWARD
# define qse_map_walk_t qse_rbt_walk_t
# define QSE_MAP_KEY QSE_RBT_KEY
# define QSE_MAP_VAL QSE_RBT_VAL
# define qse_map_id_t qse_rbt_id_t
# define qse_map_t qse_rbt_t
# define qse_map_pair_t qse_rbt_pair_t
# define qse_map_style_t qse_rbt_style_t
# define qse_map_cbserter_t qse_rbt_cbserter_t
# define qse_map_walker_t qse_rbt_walker_t
# define QSE_MAP_COPIER_SIMPLE QSE_RBT_COPIER_SIMPLE
# define QSE_MAP_COPIER_INLINE QSE_RBT_COPIER_INLINE
# define QSE_MAP_COPIER_DEFAULT QSE_RBT_COPIER_DEFAULT
# define QSE_MAP_FREEER_DEFAULT QSE_RBT_FREEER_DEFAULT
# define QSE_MAP_COMPER_DEFAULT QSE_RBT_COMPER_DEFAULT
# define QSE_MAP_KEEPER_DEFAULT QSE_RBT_KEEPER_DEFAULT
# define QSE_MAP_SIZER_DEFAULT (QSE_NULL)
# define QSE_MAP_HASHER_DEFAULT (QSE_NULL)
# define QSE_MAP_SIZE(map) QSE_RBT_SIZE(map)
# define QSE_MAP_KCOPIER(map) QSE_RBT_KCOPIER(map)
# define QSE_MAP_VCOPIER(map) QSE_RBT_VCOPIER(map)
# define QSE_MAP_KFREEER(map) QSE_RBT_KFREEER(map)
# define QSE_MAP_VFREEER(map) QSE_RBT_VFREEER(map)
# define QSE_MAP_COMPER(map) QSE_RBT_COMPER(map)
# define QSE_MAP_KEEPER(map) QSE_RBT_KEEPER(map)
# define QSE_MAP_KSCALE(map) QSE_RBT_KSCALE(map)
# define QSE_MAP_VSCALE(map) QSE_RBT_VSCALE(map)
# define QSE_MAP_KPTL(p) QSE_RBT_KPTL(p)
# define QSE_MAP_VPTL(p) QSE_RBT_VPTL(p)
# define QSE_MAP_KPTR(p) QSE_RBT_KPTR(p)
# define QSE_MAP_KLEN(p) QSE_RBT_KLEN(p)
# define QSE_MAP_VPTR(p) QSE_RBT_VPTR(p)
# define QSE_MAP_VLEN(p) QSE_RBT_VLEN(p)
#else
# error define QSE_MAP_AS_HTB or QSE_MAP_AS_RBT before including this file
#endif
#endif

76
include/qse/cmn/mb8.h Normal file
View File

@@ -0,0 +1,76 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_MB8_H_
#define _QSE_CMN_MB8_H_
#include <qse/types.h>
#include <qse/macros.h>
/** \file
* This file provides functions, types, macros for mb8 conversion.
*/
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The qse_wctomb8() function converts a wide character to a mb8 sequence.
* \return
* - 0 is returned if \a wc is invalid.
* - An integer greater than \a size is returned if the \a mb8 sequence buffer
* is not #QSE_NULL and not large enough. This integer is actually the number
* of bytes needed.
* - If \a mb8 is #QSE_NULL, the number of bytes that would have been stored
* into \a mb8 if it had not been #QSE_NULL is returned.
* - An integer between 1 and size inclusive is returned in all other cases.
*/
qse_size_t qse_wctomb8 (
qse_wchar_t wc,
qse_mchar_t* mb8,
qse_size_t size
);
/**
* The qse_mb8towc() function converts a mb8 sequence to a wide character.
* \return
* - 0 is returned if the \a mb8 sequence is invalid.
* - An integer greater than \a size is returned if the \a mb8 sequence is
* not complete.
* - An integer between 1 and size inclusive is returned in all other cases.
*/
qse_size_t qse_mb8towc (
const qse_mchar_t* mb8,
qse_size_t size,
qse_wchar_t* wc
);
#if defined(__cplusplus)
}
#endif
#endif

492
include/qse/cmn/mbwc.h Normal file
View File

@@ -0,0 +1,492 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_MBWC_H_
#define _QSE_CMN_MBWC_H_
/** \file
* This file provides functions and definitions needed for
* multibyte/wide-characer conversion.
*/
#include <qse/types.h>
#include <qse/macros.h>
#include <qse/cmn/str.h>
typedef qse_cmgr_t* (*qse_cmgr_finder_t) (const qse_char_t* name);
/**
* The qse_cmgr_id_t type defines the builtin-in cmgr IDs.
*/
enum qse_cmgr_id_t
{
/** The slmb cmgr relies on the locale routnines in the underlying
* platforms. You should initialize locale properly before using this.
*/
QSE_CMGR_SLMB,
/**
* The utf cmgr converts between utf8 and unicode characters.
*/
QSE_CMGR_UTF8,
/**
* The mb8 cmgr is used to convert raw bytes to wide characters and
* vice versa.
*/
QSE_CMGR_MB8
#if defined(QSE_ENABLE_XCMGRS)
,
QSE_CMGR_CP949, /**< cp949 */
QSE_CMGR_CP950 /**< cp950 */
#endif
};
typedef enum qse_cmgr_id_t qse_cmgr_id_t;
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The qse_findcmgrbyid() function returns a built-in cmgr for a given \a id.
*/
QSE_EXPORT qse_cmgr_t* qse_findcmgrbyid (
qse_cmgr_id_t id
);
/**
* The qse_getfindcmgr() function find a built-in cmgr matching a given
* \a name and returns it. It returns #QSE_NULL if no match is found.
* The \a name can be one of "slmb", "utf8", "mb8", "cp949", "cp950", and an
* empty string. Calling this function with an empty string is the same
* as calling qse_getdflcmgr().
*/
QSE_EXPORT qse_cmgr_t* qse_findcmgr (
const qse_char_t* name
);
QSE_EXPORT void qse_setcmgrfinder (
qse_cmgr_finder_t finder
);
QSE_EXPORT qse_cmgr_finder_t qse_getcmgrfinder (
void
);
/* --------------------------------------------------- */
/* DEFAULT GLOBAL CMGR */
/* --------------------------------------------------- */
QSE_EXPORT qse_cmgr_t* qse_getdflcmgr (
void
);
QSE_EXPORT qse_cmgr_t* qse_setdflcmgr (
qse_cmgr_t* cmgr
);
/**
* The qse_setdflcmgrbyid() function finds a built-in cmgr for the \a id and
* sets it as a default cmgr. It returns the pointer to the cmgr object set.
*/
QSE_EXPORT qse_cmgr_t* qse_setdflcmgrbyid (
qse_cmgr_id_t id
);
/* --------------------------------------------------- */
/* STRING CONVERSION USING CMGR */
/* --------------------------------------------------- */
QSE_EXPORT int qse_mbstowcswithcmgr (
const qse_mchar_t* mbs,
qse_size_t* mbslen,
qse_wchar_t* wcs,
qse_size_t* wcslen,
qse_cmgr_t* cmgr
);
QSE_EXPORT int qse_mbstowcsallwithcmgr (
const qse_mchar_t* mbs,
qse_size_t* mbslen,
qse_wchar_t* wcs,
qse_size_t* wcslen,
qse_cmgr_t* cmgr
);
QSE_EXPORT int qse_mbsntowcsnwithcmgr (
const qse_mchar_t* mbs,
qse_size_t* mbslen,
qse_wchar_t* wcs,
qse_size_t* wcslen,
qse_cmgr_t* cmgr
);
QSE_EXPORT int qse_mbsntowcsnallwithcmgr (
const qse_mchar_t* mbs,
qse_size_t* mbslen,
qse_wchar_t* wcs,
qse_size_t* wcslen,
qse_cmgr_t* cmgr
);
QSE_EXPORT int qse_mbsntowcsnuptowithcmgr (
const qse_mchar_t* mbs,
qse_size_t* mbslen,
qse_wchar_t* wcs,
qse_size_t* wcslen,
qse_wchar_t stopper,
qse_cmgr_t* cmgr
);
QSE_EXPORT qse_wchar_t* qse_mbsntowcsdupwithcmgr (
const qse_mchar_t* mbs,
qse_size_t* mbslen,
qse_size_t* wcslen,
qse_mmgr_t* mmgr,
qse_cmgr_t* cmgr
);
QSE_EXPORT qse_wchar_t* qse_mbsntowcsalldupwithcmgr (
const qse_mchar_t* mbs,
qse_size_t* mbslen,
qse_size_t* wcslen,
qse_mmgr_t* mmgr,
qse_cmgr_t* cmgr
);
QSE_EXPORT qse_wchar_t* qse_mbstowcsdupwithcmgr (
const qse_mchar_t* mbs,
qse_size_t* wcslen,
qse_mmgr_t* mmgr,
qse_cmgr_t* cmgr
);
QSE_EXPORT qse_wchar_t* qse_mbstowcsalldupwithcmgr (
const qse_mchar_t* mbs,
qse_size_t* wcslen,
qse_mmgr_t* mmgr,
qse_cmgr_t* cmgr
);
QSE_EXPORT qse_wchar_t* qse_mbsatowcsdupwithcmgr (
const qse_mchar_t* mbs[],
qse_size_t* wcslen,
qse_mmgr_t* mmgr,
qse_cmgr_t* cmgr
);
QSE_EXPORT qse_wchar_t* qse_mbsatowcsalldupwithcmgr (
const qse_mchar_t* mbs[],
qse_size_t* wcslen,
qse_mmgr_t* mmgr,
qse_cmgr_t* cmgr
);
QSE_EXPORT int qse_wcstombswithcmgr (
const qse_wchar_t* wcs, /**< [in] wide-character string to convert*/
qse_size_t* wcslen, /**< [out] number of wide-characters handled */
qse_mchar_t* mbs, /**< [out] #QSE_NULL or buffer pointer */
qse_size_t* mbslen, /**< [in,out] buffer size for in,
actual length for out*/
qse_cmgr_t* cmgr
);
QSE_EXPORT int qse_wcsntombsnwithcmgr (
const qse_wchar_t* wcs, /**< [in] wide string */
qse_size_t* wcslen, /**< [in,out] wide string length for in,
number of wide characters handled for out */
qse_mchar_t* mbs, /**< [out] #QSE_NULL or buffer pointer */
qse_size_t* mbslen, /**< [in,out] buffer size for in,
actual size for out */
qse_cmgr_t* cmgr
);
QSE_EXPORT qse_mchar_t* qse_wcstombsdupwithcmgr (
const qse_wchar_t* wcs,
qse_size_t* mbslen,
qse_mmgr_t* mmgr,
qse_cmgr_t* cmgr
);
QSE_EXPORT qse_mchar_t* qse_wcsntombsdupwithcmgr (
const qse_wchar_t* wcs,
qse_size_t wcslen,
qse_size_t* mbslen,
qse_mmgr_t* mmgr,
qse_cmgr_t* cmgr
);
QSE_EXPORT qse_mchar_t* qse_wcsatombsdupwithcmgr (
const qse_wchar_t* wcs[],
qse_size_t* mbslen,
qse_mmgr_t* mmgr,
qse_cmgr_t* cmgr
);
QSE_EXPORT qse_mchar_t* qse_wcsnatombsdupwithcmgr (
const qse_wcstr_t wcs[],
qse_size_t* mbslen,
qse_mmgr_t* mmgr,
qse_cmgr_t* cmgr
);
/* --------------------------------------------------- */
/* STRING CONVERSION WITH DEFAULT GLOBAL CMGR */
/* --------------------------------------------------- */
/**
* The qse_mbstowcs() function converts a null-terminated multibyte string to
* a wide character string.
*
* It never returns -2 if \a wcs is #QSE_NULL.
*
* \code
* const qse_mchar_t* mbs = QSE_MT("a multibyte string");
* qse_wchar_t wcs[100];
* qse_size_t wcslen = QSE_COUNTOF(buf), n;
* qse_size_t mbslen;
* int n;
* n = qse_mbstowcs (mbs, &mbslen, wcs, &wcslen);
* if (n <= -1) { invalid/incomplenete sequence or buffer to small }
* \endcode
*
* \return 0 on success.
* -1 if \a mbs contains an illegal character.
* -2 if the wide-character string buffer is too small.
* -3 if \a mbs is not a complete sequence.
*/
QSE_EXPORT int qse_mbstowcs (
const qse_mchar_t* mbs, /**< [in] multibyte string to convert */
qse_size_t* mbslen, /**< [out] number of multibyte characters
handled */
qse_wchar_t* wcs, /**< [out] wide-character string buffer */
qse_size_t* wcslen /**< [in,out] buffer size for in,
number of characters in the buffer for out */
);
/**
* The qse_mbstowcsall() functions behaves like qse_mbstowcs() except
* it converts an invalid sequence or an incomplete sequence to a question
* mark. it never returns -1 or -3.
*/
QSE_EXPORT int qse_mbstowcsall (
const qse_mchar_t* mbs, /**< [in] multibyte string to convert */
qse_size_t* mbslen, /**< [out] number of multibyte characters
handled */
qse_wchar_t* wcs, /**< [out] wide-character string buffer */
qse_size_t* wcslen /**< [in,out] buffer size for in,
number of characters in the buffer for out */
);
/**
* The qse_mbsntowcsn() function converts a multibyte string to a
* wide character string.
*
* It never returns -2 if \a wcs is #QSE_NULL.
*
* \return 0 on success.
* -1 if \a mbs contains an illegal character.
* -2 if the wide-character string buffer is too small.
* -3 if \a mbs is not a complete sequence.
*/
QSE_EXPORT int qse_mbsntowcsn (
const qse_mchar_t* mbs,
qse_size_t* mbslen,
qse_wchar_t* wcs,
qse_size_t* wcslen
);
QSE_EXPORT int qse_mbsntowcsnall (
const qse_mchar_t* mbs,
qse_size_t* mbslen,
qse_wchar_t* wcs,
qse_size_t* wcslen
);
/**
* The qse_mbsntowcsnupto() function is the same as qse_mbsntowcsn()
* except that it stops once it has processed the \a stopper character.
*/
QSE_EXPORT int qse_mbsntowcsnupto (
const qse_mchar_t* mbs,
qse_size_t* mbslen,
qse_wchar_t* wcs,
qse_size_t* wcslen,
qse_wchar_t stopper
);
QSE_EXPORT qse_wchar_t* qse_mbsntowcsdup (
const qse_mchar_t* mbs,
qse_size_t* mbslen,
qse_size_t* wcslen,
qse_mmgr_t* mmgr
);
QSE_EXPORT qse_wchar_t* qse_mbsntowcsalldup (
const qse_mchar_t* mbs,
qse_size_t* mbslen,
qse_size_t* wcslen,
qse_mmgr_t* mmgr
);
QSE_EXPORT qse_wchar_t* qse_mbstowcsdup (
const qse_mchar_t* mbs,
qse_size_t* wcslen,
qse_mmgr_t* mmgr
);
QSE_EXPORT qse_wchar_t* qse_mbstowcsalldup (
const qse_mchar_t* mbs,
qse_size_t* wcslen,
qse_mmgr_t* mmgr
);
QSE_EXPORT qse_wchar_t* qse_mbsatowcsdup (
const qse_mchar_t* mbs[],
qse_size_t* wcslen,
qse_mmgr_t* mmgr
);
QSE_EXPORT qse_wchar_t* qse_mbsatowcsalldup (
const qse_mchar_t* mbs[],
qse_size_t* wcslen,
qse_mmgr_t* mmgr
);
/**
* The qse_wcstombs() function converts a null-terminated wide character
* string \a wcs to a multibyte string and writes it into the buffer pointed to
* by \a mbs, but not more than \a mbslen bytes including the terminating null.
*
* Upon return, \a mbslen is modified to the actual bytes written to \a mbs
* excluding the terminating null; \a wcslen is modified to the number of
* wide characters converted.
*
* You may pass #QSE_NULL for \a mbs 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 qse_wchar_t* wcs = QSE_T("hello");
* qse_mchar_t mbs[10];
* qse_size_t wcslen;
* qse_size_t mbslen = QSE_COUNTOF(mbs);
* n = qse_wcstombs (wcs, &wcslen, mbs, &mbslen);
* if (n <= -1)
* {
* // conversion error
* }
* \endcode
*/
QSE_EXPORT int qse_wcstombs (
const qse_wchar_t* wcs, /**< [in] wide-character string to convert*/
qse_size_t* wcslen, /**< [out] number of wide-characters handled */
qse_mchar_t* mbs, /**< [out] #QSE_NULL or buffer pointer */
qse_size_t* mbslen /**< [in,out] buffer size for in,
actual length for out*/
);
/**
* The qse_wcsntombsn() function converts the first \a wcslen characters from
* a wide character string \a wcs to a multibyte string and writes it to a
* buffer \a mbs not more than \a mbslen bytes.
*
* Upon return, it modifies \a mbslen to the actual bytes written to \a mbs
* and \a wcslen to the number of wide characters converted.
*
* You may pass #QSE_NULL for \a mbs to dry-run conversion or to get the
* required buffer size for conversion.
*
* 0 is returned on full conversion. The number of wide characters handled
* is stored into \a wcslen and the number of produced multibyte characters
* is stored into \a mbslen. -1 is returned if an illegal character is
* encounterd during conversion and -2 is returned if the buffer is not
* large enough to perform full conversion. however, the number of wide
* characters handled so far stored into \a wcslen and the number of produced
* multibyte characters so far stored into \a mbslen are still valid.
* If \a mbs is #QSE_NULL, -2 is never returned.
*
* \return 0 on success,
* -1 if \a wcs contains an illegal character,
* -2 if the multibyte string buffer is too small.
*/
QSE_EXPORT int qse_wcsntombsn (
const qse_wchar_t* wcs, /**< [in] wide string */
qse_size_t* wcslen,/**< [in,out] wide string length for in,
number of wide characters handled for out */
qse_mchar_t* mbs, /**< [out] #QSE_NULL or buffer pointer */
qse_size_t* mbslen /**< [in,out] buffer size for in,
actual size for out */
);
QSE_EXPORT qse_mchar_t* qse_wcstombsdup (
const qse_wchar_t* wcs,
qse_size_t* mbslen,
qse_mmgr_t* mmgr
);
QSE_EXPORT qse_mchar_t* qse_wcsntombsdup (
const qse_wchar_t* wcs,
qse_size_t wcslen,
qse_size_t* mbslen,
qse_mmgr_t* mmgr
);
QSE_EXPORT qse_mchar_t* qse_wcsatombsdup (
const qse_wchar_t* wcs[],
qse_size_t* mbslen,
qse_mmgr_t* mmgr
);
QSE_EXPORT qse_mchar_t* qse_wcsnatombsdup (
const qse_wcstr_t wcs[],
qse_size_t* mbslen,
qse_mmgr_t* mmgr
);
#if defined(QSE_CHAR_IS_MCHAR)
# define qse_strtombsdup(sa,mmgr) qse_strdup(sa,mmgr)
# define qse_strtowcsdup(sa,mmgr) qse_mbstowcsdup(sa,QSE_NULL,mmgr)
# define qse_strtombsdupwithcmgr(sa,mmgr,cmgr) qse_strdup(sa,mmgr)
# define qse_strtowcsdupwithcmgr(sa,mmgr,cmgr) qse_mbstowcsdupwithcmgr(sa,QSE_NULL,mmgr,cmgr)
#else
# define qse_strtombsdup(sa,mmgr) qse_wcstombsdup(sa,QSE_NULL,mmgr)
# define qse_strtowcsdup(sa,mmgr) qse_wcsdup(sa,mmgr)
# define qse_strtombsdupwithcmgr(sa,mmgr,cmgr) qse_wcstombsdupwithcmgr(sa,QSE_NULL,mmgr,cmgr)
# define qse_strtowcsdupwithcmgr(sa,mmgr,cmgr) qse_wcsdup(sa,mmgr)
#endif
#if defined(__cplusplus)
}
#endif
#endif

206
include/qse/cmn/mem.h Normal file
View File

@@ -0,0 +1,206 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_MEM_H_
#define _QSE_CMN_MEM_H_
/** @file
* This file defines functions and macros for memory manipulation.
*/
#include <qse/types.h>
#include <qse/macros.h>
/**
* The QSE_MMGR_GETDFL() macro returns the default memory manager.
*/
#define QSE_MMGR_GETDFL() qse_getdflmmgr()
/**
* The QSE_MMGR_SETDFL() macro changes the default memory manager.
*/
#define QSE_MMGR_SETDFL(m) qse_setdflmmgr(m)
/**
* The QSE_MMGR_ALLOC() macro allocates a memory block of the @a size bytes
* using the @a mmgr memory manager.
*/
#define QSE_MMGR_ALLOC(mmgr,size) ((mmgr)->alloc(mmgr,size))
/**
* The QSE_MMGR_REALLOC() macro resizes a memory block pointed to by @a ptr
* to the @a size bytes using the @a mmgr memory manager.
*/
#define QSE_MMGR_REALLOC(mmgr,ptr,size) ((mmgr)->realloc(mmgr,ptr,size))
/**
* The QSE_MMGR_FREE() macro deallocates the memory block pointed to by @a ptr.
*/
#define QSE_MMGR_FREE(mmgr,ptr) ((mmgr)->free(mmgr,ptr))
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The qse_memcpy() functions copies @a n bytes from the source memory block
* @a src to the destinaion memory block @a dst. The memory blocks must not
* overlap. Use qse_memmove() if they overlap.
*
* @return destination memory block @a dst.
*/
QSE_EXPORT void* qse_memcpy (
void* dst, /**< destination memory block */
const void* src, /**< source memory block */
qse_size_t n /**< number of bytes to copy */
);
/**
* The qse_memmove() functions copies @a n bytes from the source memory block
* @a src to the destinaion memory block @a dst without corrupting overlapping
* zone.
*
* @return destination memory block @a dst.
*/
QSE_EXPORT void* qse_memmove (
void* dst, /**< destination memory block */
const void* src, /**< source memory block */
qse_size_t n /**< number of bytes to copy */
);
/**
* The qse_memset() function fills leading @a n bytes of the destination
* memory block @a dst with the byte @a val.
*
* @return destination memory block @a dst.
*/
QSE_EXPORT void* qse_memset (
void* dst, /**< destination memory block */
int val, /**< value fill the memory block with */
qse_size_t n /**< number of bytes to fill */
);
/**
* The qse_memcmp() function compares leading *a n bytes of two memory blocks
* @a s1 and @a s2.
*
* @return
* 0 if two memory ares have the same leadning @a n bytes.
* positive number if the first different byte of s1 is greater than that of s2.
* negative number if the first different byte of s1 is less than that of s2.
*/
QSE_EXPORT int qse_memcmp (
const void* s1, /**< first memory block to compare */
const void* s2, /**< second memory block to compare */
qse_size_t n /**< the number of bytes to compare */
);
/**
* The qse_membyte() function scans the memory block @a s from the first byte
* up to the nth byte in search of the byte @a val. If it finds a match,
* it aborts scanning the memory block and returns the pointer to the matching
* location.
*
* @return
* #QSE_NULL if the byte @a val is not found.
* pointer to the location in the memory block @a s matching the byte @a val
* if a match is found.
*/
QSE_EXPORT void* qse_membyte (
const void* s, /**< memory block to scan */
int val, /**< byte to find */
qse_size_t n /**< number of bytes to scan */
);
/**
* The qse_memrbyte() function scans the memory block @a s from the nth byte
* backward to the first byte in search of the byte @a val. If it finds a match,
* it aborts scanning the memory block and returns the pointer to the matching
* location.
*
* @return
* #QSE_NULL if the byte val is not found.
* pointer to the location in the memory block s matching the byte val
* if a match is found.
*/
QSE_EXPORT void* qse_memrbyte (
const void* s, /**< memory block to scan */
int val, /**< byte to find */
qse_size_t n /**< number of bytes to scan */
);
/**
* The qse_memmem() functions scans the first @a hl bytes of the memory
* block @a hs in search of the byte block @a nd of the length @a nl bytes.
*
* @return
* #QSE_NULL if no match is found.
* pointer to the start of the matching location if a match is found.
*/
QSE_EXPORT void* qse_memmem (
const void* hs, /**< memory block to scan */
qse_size_t hl, /**< number of bytes to scan */
const void* nd, /**< byte block to find */
qse_size_t nl /**< number of bytes in the block */
);
/**
* The qse_memrmem() functions scans the first @a hl bytes of the memory
* block @a hs backward in search of the byte block @a nd of the length
* @a nl bytes.
*
* @return
* #QSE_NULL if no match is found.
* pointer to the start of the matching location if a match is found.
*/
QSE_EXPORT void* qse_memrmem (
const void* hs, /**< memory block to scan */
qse_size_t hl, /**< number of bytes to scan */
const void* nd, /**< byte block to find */
qse_size_t nl /**< number of bytes in the block */
);
/**
* The qse_getdflmmgr() function returns the default memory manager.
*/
QSE_EXPORT qse_mmgr_t* qse_getdflmmgr (
void
);
/**
* The qse_setdflmmgr() function changes the default memory manager.
* If mmgr is #QSE_NULL, the memory manager is set to the builtin
* default.
*/
QSE_EXPORT void qse_setdflmmgr (
qse_mmgr_t* mmgr
);
#if defined(__cplusplus)
}
#endif
#endif

318
include/qse/cmn/oht.h Normal file
View File

@@ -0,0 +1,318 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_OHT_T_
#define _QSE_OHT_T_
/** @file
* This file provides the open-addressed hash table for fixed-size data.
*/
#include <qse/types.h>
#include <qse/macros.h>
/**
* The #QSE_OHT_NIL macro represents an invalid index.
*/
#define QSE_OHT_NIL ((qse_size_t)-1)
/**
* The #QSE_OHT_SIZE macro returns the number of items.
*/
#define QSE_OHT_SIZE(oht) ((const qse_size_t)(oht)->size)
/**
* The #QSE_OHT_CAPA macro returns the capacity of a table.
*/
#define QSE_OHT_CAPA(oht) ((const qse_size_t)(oht)->capa.hard)
/**
* The #QSE_OHT_LIMIT macro returns the maximum number of items.
* It is equal to or less than the capacity.
*/
#define QSE_OHT_LIMIT(oht) ((const qse_size_t)(oht)->capa.soft)
/**
* The #QSE_OHT_SCALE macro returns the size of an item in bytes.
*/
#define QSE_OHT_SCALE(oht) ((const int)(oht)->scale)
/**
* The #qse_oht_mark_t type defines enumerations values to indicate
* the slot status.
*/
enum qse_oht_mark_t
{
QSE_OHT_EMPTY = 0,
QSE_OHT_OCCUPIED = 1 /*,
QSE_OHT_DELETED = 2 */
};
typedef enum qse_oht_mark_t qse_oht_mark_t;
/**
* The #qse_oht_walk_t type defines walking directions.
*/
enum qse_oht_walk_t
{
QSE_OHT_WALK_STOP = 0,
QSE_OHT_WALK_FORWARD = 1,
};
typedef enum qse_oht_walk_t qse_oht_walk_t;
typedef struct qse_oht_t qse_oht_t;
/**
* The #qse_oht_hasher_t type defines a data hasher function.
*/
typedef qse_size_t (*qse_oht_hasher_t) (
qse_oht_t* oht,
const void* data
);
/**
* The #qse_oht_comper_t type defines a key comparator that is called when
* the list needs to compare data. The comparator must return 0 if the data
* are the same and a non-zero integer otherwise.
*/
typedef int (*qse_oht_comper_t) (
qse_oht_t* oht, /**< open-addressed hash table */
const void* data1, /**< data pointer */
const void* data2 /**< data pointer */
);
/**
* The #qse_oht_copier_t type defines a data copier function.
*/
typedef void (*qse_oht_copier_t) (
qse_oht_t* oht,
void* dst,
const void* src
);
/**
* The #qse_oht_t type defines an open-address hash table for fixed-size data.
* Unlike #qse_rbt_t or #qse_htb_t, it does not separate a key from a value.
*/
struct qse_oht_t
{
qse_mmgr_t* mmgr;
int scale;
struct
{
qse_size_t hard;
qse_size_t soft;
} capa;
qse_size_t size;
qse_oht_hasher_t hasher;
qse_oht_comper_t comper;
qse_oht_copier_t copier;
qse_oht_mark_t* mark;
void* data;
};
/**
* The #qse_oht_walker_t function defines a callback function
* for qse_oht_walk().
*/
typedef qse_oht_walk_t (*qse_oht_walker_t) (
qse_oht_t* oht,
void* data,
void* ctx
);
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The qse_oht_open() function creates an open-addressed hash table.
*/
QSE_EXPORT qse_oht_t* qse_oht_open (
qse_mmgr_t* mmgr,
qse_size_t xtnsize,
int scale,
qse_size_t capa,
qse_size_t limit
);
/**
* The qse_oht_close() function destroys an open-addressed hash table.
*/
QSE_EXPORT void qse_oht_close (
qse_oht_t* oht /**< open-addressed hash table */
);
/**
* The qse_oht_open() function initializes an open-addressed hash table.
*/
QSE_EXPORT int qse_oht_init (
qse_oht_t* oht,
qse_mmgr_t* mmgr,
int scale,
qse_size_t capa,
qse_size_t limit
);
/**
* The qse_oht_close() function finalizes an open-addressed hash table.
*/
QSE_EXPORT void qse_oht_fini (
qse_oht_t* oht /**< open-addressed hash table */
);
QSE_EXPORT qse_mmgr_t* qse_oht_getmmgr (
qse_oht_t* oht
);
QSE_EXPORT void* qse_oht_getxtn (
qse_oht_t* oht
);
/**
* The qse_oht_getcomper() function returns the data hasher.
*/
QSE_EXPORT qse_oht_hasher_t qse_oht_gethasher (
qse_oht_t* oht /**< open-addressed hash table */
);
/**
* The qse_oht_setcomper() function changes the data hasher
*/
QSE_EXPORT void qse_oht_sethasher (
qse_oht_t* oht, /**< open-addressed hash table */
qse_oht_hasher_t hasher /**< hasher */
);
/**
* The qse_oht_getcomper() function returns the data comparator.
*/
QSE_EXPORT qse_oht_comper_t qse_oht_getcomper (
qse_oht_t* oht /**< open-addressed hash table */
);
/**
* The qse_oht_setcomper() function changes the data comparator
*/
QSE_EXPORT void qse_oht_setcomper (
qse_oht_t* oht, /**< open-addressed hash table */
qse_oht_comper_t comper /**< comparator */
);
/**
* The qse_oht_getcomper() function returns the data copier.
*/
QSE_EXPORT qse_oht_copier_t qse_oht_getcopier (
qse_oht_t* oht /**< open-addressed hash table */
);
/**
* The qse_oht_setcomper() function changes the data copier.
*/
QSE_EXPORT void qse_oht_setcopier (
qse_oht_t* oht, /**< open-addressed hash table */
qse_oht_copier_t copier /**< copier */
);
/**
* The qse_oht_search() function searches a hash table to find a
* matching datum. It returns the index to the slot of an internal array
* where the matching datum is found.
* @return slot index if a match if found,
* #QSE_OHT_NIL if no match is found.
*/
QSE_EXPORT qse_size_t qse_oht_search (
qse_oht_t* oht, /**< open-addressed hash table */
void* data /**< data pointer */
);
/**
* The qse_oht_insert() function inserts a new datum. It fails if it finds
* an existing datum.
* @return slot index where the new datum is inserted on success,
* #QSE_OHT_NIL on failure.
*/
QSE_EXPORT qse_size_t qse_oht_insert (
qse_oht_t* oht, /**< open-addressed hash table */
const void* data /**< data pointer */
);
/**
* The qse_oht_upsert() function inserts a new datum if it finds no matching
* datum or updates an exsting datum if finds a matching datum.
* @return slot index where the datum is inserted or updated.
*/
QSE_EXPORT qse_size_t qse_oht_upsert (
qse_oht_t* oht, /**< open-addressed hash table */
const void* data /**< data pointer */
);
/**
* The qse_oht_update() function updates an existing datum. It fails if it finds
* no existing datum.
* @return slot index where an existing datum is updated on success,
* #QSE_OHT_NIL on failure.
*/
QSE_EXPORT qse_size_t qse_oht_update (
qse_oht_t* oht, /**< open-addressed hash table */
const void* data /**< data pointer */
);
/**
* The qse_oht_delete() function deletes an existing datum. It fails if it finds
* no existing datum.
* @return slot index where an existing datum is deleted on success,
* #QSE_OHT_NIL on failure.
*/
QSE_EXPORT qse_size_t qse_oht_delete (
qse_oht_t* oht, /**< open-addressed hash table */
const void* data /**< data pointer */
);
/**
* The qse_oht_clear() functions deletes all data items.
*/
QSE_EXPORT void qse_oht_clear (
qse_oht_t* oht /**< open-addressed hash table */
);
/**
* The qse_oht_walk() function executes the callback function @a walker for
* each valid data item.
*/
QSE_EXPORT void qse_oht_walk (
qse_oht_t* oht, /**< open-addressed hash table */
qse_oht_walker_t walker, /**< callback function */
void* ctx /**< context */
);
#if defined(__cplusplus)
}
#endif
#endif

195
include/qse/cmn/opt.h Normal file
View File

@@ -0,0 +1,195 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_OPT_H_
#define _QSE_CMN_OPT_H_
#include <qse/types.h>
#include <qse/macros.h>
/** \file
* This file defines functions and data structures to process
* command-line arguments.
*/
typedef struct qse_opt_t qse_opt_t;
typedef struct qse_opt_lng_t qse_opt_lng_t;
struct qse_opt_lng_t
{
const qse_char_t* str;
qse_cint_t val;
};
struct qse_opt_t
{
/* input */
const qse_char_t* str; /* option string */
qse_opt_lng_t* lng; /* long options */
/* output */
qse_cint_t opt; /* character checked for validity */
qse_char_t* arg; /* argument associated with an option */
/* output */
const qse_char_t* lngopt;
/* input + output */
int ind; /* index into parent argv vector */
/* input + output - internal*/
qse_char_t* cur;
};
/* --------------------------------------------------------------------- */
enum qse_cli_optflag_t
{
QSE_CLI_REQUIRE_OPTNAME = (1 << 0), /* if set, the option itself is required */
QSE_CLI_REQUIRE_OPTVAL = (1 << 1), /* if set, the option's value is mandatory */
QSE_CLI_DISCRETIONARY_OPTVAL = (1 << 2) /* if set, the option's value is optional. */
};
typedef enum qse_cli_optflag_t qse_cli_optflag_t;
enum qse_cli_error_code_t
{
QSE_CLI_ERROR_INVALID_OPTNAME = 1,
QSE_CLI_ERROR_MISSING_OPTNAME = 2,
QSE_CLI_ERROR_REDUNDANT_OPTVAL = 3,
QSE_CLI_ERROR_MISSING_OPTVAL = 4,
QSE_CLI_ERROR_MEMORY = 5
};
typedef enum qse_cli_error_code_t qse_cli_error_code_t;
typedef struct qse_cli_opt_t qse_cli_opt_t;
typedef struct qse_cli_t qse_cli_t;
struct qse_cli_opt_t
{
/* input */
const qse_char_t* name;
int optflags; /* 0 or bitwise-ORed of qse_cli_optflags_t enumerartors */
/* output - you don't have to initialize this field */
qse_char_t* value;
};
typedef int (*qse_cli_errcb_t) (
qse_cli_t* cli,
qse_cli_error_code_t code,
const qse_char_t* qname,
const qse_char_t* qval
);
struct qse_cli_data_t
{
/* input */
qse_cli_errcb_t errcb;
const qse_char_t** optsta;
const qse_char_t* optasn;
qse_cli_opt_t* opts;
void* ctx;
};
typedef struct qse_cli_data_t qse_cli_data_t;
struct qse_cli_t
{
qse_mmgr_t* mmgr;
qse_cli_data_t data;
/* output - you don't have to initialize these fields */
qse_char_t* verb;
int nparams;
qse_char_t** params;
};
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The qse_getopt() function processes the \a argc command-line arguments
* pointed to by \a argv as configured in \a opt. It can process two
* different option styles: a single character starting with '-', and a
* long name starting with '--'.
*
* A character in \a opt.str is treated as a single character option. Should
* it require a parameter, specify ':' after it.
*
* Two special returning option characters indicate special error conditions.
* - \b ? indicates a bad option stored in the \a opt->opt field.
* - \b : indicates a bad parameter for an option stored in the
* \a opt->opt field.
*
* \return an option character on success, QSE_CHAR_EOF on no more options.
*/
QSE_EXPORT qse_cint_t qse_getopt (
int argc, /* argument count */
qse_char_t* const* argv, /* argument array */
qse_opt_t* opt /* option configuration */
);
/* --------------------------------------------------------------------- */
QSE_EXPORT int qse_parsecli (
qse_cli_t* cli,
qse_mmgr_t* mmgr,
int argc,
qse_char_t* const argv[],
qse_cli_data_t* data
);
QSE_EXPORT void qse_clearcli (
qse_cli_t* cli
);
QSE_EXPORT qse_char_t* qse_getcliverb (
qse_cli_t* cli
);
QSE_EXPORT qse_char_t* qse_getclioptval (
qse_cli_t* cli,
const qse_char_t* opt
);
QSE_EXPORT qse_char_t* qse_getcliparams (
qse_cli_t* cli,
int index
);
#if defined(QSE_HAVE_INLINE)
static QSE_INLINE int qse_getncliparams (qse_cli_t* cli) { return cli->nparams; }
#else
# define qse_getncliparams(cli) ((cli)->nparams)
#endif
#if defined(__cplusplus)
}
#endif
#endif

337
include/qse/cmn/path.h Normal file
View File

@@ -0,0 +1,337 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_PATH_H_
#define _QSE_CMN_PATH_H_
/** \file
* This file provides functions for path name manipulation.
*/
#include <qse/types.h>
#include <qse/macros.h>
#if !defined(QSE_PATH_MAX)
# define QSE_PATH_MAX 1024
#endif
enum qse_canonpath_flag_t
{
/** if the final output is . logically, return an empty path */
QSE_CANONPATH_EMPTYSINGLEDOT = (1 << 0),
/** keep the .. segment in the path name */
QSE_CANONPATH_KEEPDOUBLEDOTS = (1 << 1),
/** drop a trailing separator even if the source contains one */
QSE_CANONPATH_DROPTRAILINGSEP = (1 << 2)
};
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
# define QSE_ISPATHMBSEP(c) ((c) == QSE_MT('/') || (c) == QSE_MT('\\'))
# define QSE_ISPATHWCSEP(c) ((c) == QSE_WT('/') || (c) == QSE_WT('\\'))
#else
# define QSE_ISPATHMBSEP(c) ((c) == QSE_MT('/'))
# define QSE_ISPATHWCSEP(c) ((c) == QSE_WT('/'))
#endif
#define QSE_ISPATHMBDRIVE(s) \
(((s[0] >= QSE_MT('A') && s[0] <= QSE_MT('Z')) || \
(s[0] >= QSE_MT('a') && s[0] <= QSE_MT('z'))) && \
s[1] == QSE_MT(':'))
#define QSE_ISPATHWCDRIVE(s) \
(((s[0] >= QSE_WT('A') && s[0] <= QSE_WT('Z')) || \
(s[0] >= QSE_WT('a') && s[0] <= QSE_WT('z'))) && \
s[1] == QSE_WT(':'))
#define QSE_ISPATHMBSEPORNIL(c) (QSE_ISPATHMBSEP(c) || (c) == QSE_MT('\0'))
#define QSE_ISPATHWCSEPORNIL(c) (QSE_ISPATHWCSEP(c) || (c) == QSE_WT('\0'))
#if defined(QSE_CHAR_IS_MCHAR)
# define QSE_ISPATHSEP(c) QSE_ISPATHMBSEP(c)
# define QSE_ISPATHSEPORNIL(c) QSE_ISPATHMBSEPORNIL(c)
# if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
# define QSE_ISPATHDRIVE(s) QSE_ISPATHMBDRIVE(s)
# endif
#else
# define QSE_ISPATHSEP(c) QSE_ISPATHWCSEP(c)
# define QSE_ISPATHSEPORNIL(c) QSE_ISPATHWCSEPORNIL(c)
# if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
# define QSE_ISPATHDRIVE(s) QSE_ISPATHWCDRIVE(s)
# endif
#endif
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The qse_ismbsabspath() function determines if a path name is absolute.
* A path name beginning with a segment separator is absolute.
* On Win32/OS2/DOS, it also returns 1 if a path name begins with a drive
* letter followed by a colon.
* \return 1 if absolute, 0 if not.
*/
QSE_EXPORT int qse_ismbsabspath (
const qse_mchar_t* path
);
/**
* The qse_ismbsdrivepath() function determines if a path name begins with
* a drive letter followed by a colon like A:.
*/
QSE_EXPORT int qse_ismbsdrivepath (
const qse_mchar_t* path
);
/**
* The qse_ismbsdriveabspath() function determines if a path name is in the form
* of a drive letter followed by a colon like A: and a path separator.
*/
QSE_EXPORT int qse_ismbsdriveabspath (
const qse_mchar_t* path
);
/**
* The qse_ismbsdrivecurpath() function determines if a path name is in the form
* of a drive letter followed by a colon like A:, without any trailing path.
*/
QSE_EXPORT int qse_ismbsdrivecurpath (
const qse_mchar_t* path
);
/**
* The qse_mbsbasename() function returns the pointer to the file name
* segment in a multibyte path name.
*/
QSE_EXPORT const qse_mchar_t* qse_mbsbasename (
const qse_mchar_t* path
);
/**
* The qse_substmbsbasenamedup() function creates a new string composed of
* the base directory part of the given \a path and \a file combined.
*/
QSE_EXPORT qse_mchar_t* qse_substmbsbasenamedup (
const qse_mchar_t* path,
const qse_mchar_t* file,
qse_mmgr_t* mmgr
);
/**
* The qse_mbspathcore() function returns the core part of \a path
* excluding a special prefix.
*/
QSE_EXPORT qse_mchar_t* qse_mbspathcore (
const qse_mchar_t* path
);
/**
* The qse_canonmbspath() function canonicalizes a path name \a path by deleting
* unnecessary path segments from it and stores the result to a memory buffer
* pointed to by \a canon. Canonicalization is purely performed on the path
* name without refering to actual file systems. It null-terminates the
* canonical path in \a canon and returns the number of characters excluding
* the terminating null.
*
* \code
* qse_mchar_t buf[64];
* qse_canonmbspath (QSE_MT("/usr/local/../bin/sh"), buf);
* qse_printf (QSE_T("%hs\n")); // prints /usr/bin/sh
* \endcode
*
* If #QSE_CANONPATH_EMPTYSINGLEDOT is clear in the \a flags, a single dot
* is produced if the input \a path resolves to the current directory logically.
* For example, dir/.. is canonicalized to a single period; If it is set,
* an empty string is produced. Even a single period as an input produces
* an empty string if it is set.
*
* The output is empty returning 0 regardless of \a flags if the input
* \a path is empty.
*
* The caller must ensure that it is large enough to hold the resulting
* canonical path before calling because this function does not check the
* size of the memory buffer. Since the canonical path cannot be larger
* than the original path, you can simply ensure this by providing a memory
* buffer as long as the number of characters and a terminating null in
* the original path.
*
* \return number of characters in the resulting canonical path excluding
* the terminating null.
*/
QSE_EXPORT qse_size_t qse_canonmbspath (
const qse_mchar_t* path,
qse_mchar_t* canon,
int flags
);
QSE_EXPORT qse_mchar_t* qse_mergembspathdup (
const qse_mchar_t* dir,
const qse_mchar_t* file,
qse_mmgr_t* mmgr
);
/* ------------------------------------------------------------------------- */
/**
* The qse_iswcsabspath() function determines if a path name is absolute.
* A path name beginning with a segment separator is absolute.
* On Win32/OS2/DOS, it also returns 1 if a path name begins with a drive
* letter followed by a colon.
* \return 1 if absolute, 0 if not.
*/
QSE_EXPORT int qse_iswcsabspath (
const qse_wchar_t* path
);
/**
* The qse_iswcsdrivepath() function determines if a path name begins with
* a drive letter followed by a colon like A:.
*/
QSE_EXPORT int qse_iswcsdrivepath (
const qse_wchar_t* path
);
/**
* The qse_iswcsdriveabspath() function determines if a path name is in the form
* of a drive letter followed by a colon like A: and a path separtor.
*/
QSE_EXPORT int qse_iswcsdriveabspath (
const qse_wchar_t* path
);
/**
* The qse_iswcsdrivecurpath() function determines if a path name is in the form
* of a drive letter followed by a colon like A:, without any trailing path.
*/
QSE_EXPORT int qse_iswcsdrivecurpath (
const qse_wchar_t* path
);
/**
* The qse_wcsbasename() function returns the pointer to the file name
* segment in a wide-character path name.
*/
QSE_EXPORT const qse_wchar_t* qse_wcsbasename (
const qse_wchar_t* path
);
QSE_EXPORT qse_wchar_t* qse_substwcsbasenamedup (
const qse_wchar_t* path,
const qse_wchar_t* file,
qse_mmgr_t* mmgr
);
/**
* The qse_wcspathcore() function returns the core part of \a path
* excluding a special prefix.
*/
QSE_EXPORT qse_wchar_t* qse_wcspathcore (
const qse_wchar_t* path
);
/**
* The qse_canonwcspath() function canonicalizes a path name \a path by deleting
* unnecessary path segments from it and stores the result to a memory buffer
* pointed to by \a canon. Canonicalization is purely performed on the path
* name without refering to actual file systems. It null-terminates the
* canonical path in \a canon and returns the number of characters excluding
* the terminating null.
*
* \code
* qse_wchar_t buf[64];
* qse_canonwcspath (QSE_WT("/usr/local/../bin/sh"), buf);
* qse_printf (QSE_T("%ls\n")); // prints /usr/bin/sh
* \endcode
*
* If #QSE_CANONPATH_EMPTYSINGLEDOT is clear in the \a flags, a single dot
* is produced if the input \a path resolves to the current directory logically.
* For example, dir/.. is canonicalized to a single period; If it is set,
* an empty string is produced. Even a single period as an input produces
* an empty string if it is set.
*
* The output is empty returning 0 regardless of \a flags if the input
* \a path is empty.
*
* The caller must ensure that it is large enough to hold the resulting
* canonical path before calling because this function does not check the
* size of the memory buffer. Since the canonical path cannot be larger
* than the original path, you can simply ensure this by providing a memory
* buffer as long as the number of characters and a terminating null in
* the original path.
*
* \return number of characters in the resulting canonical path excluding
* the terminating null.
*/
QSE_EXPORT qse_size_t qse_canonwcspath (
const qse_wchar_t* path,
qse_wchar_t* canon,
int flags
);
/**
* The qse_substwcsbasenamedup() function creates a new string composed of
* the base directory part of the given \a path and \a file combined.
*/
QSE_EXPORT qse_wchar_t* qse_mergewcspathdup (
const qse_wchar_t* dir,
const qse_wchar_t* file,
qse_mmgr_t* mmgr
);
#if defined(QSE_CHAR_IS_MCHAR)
# define qse_isabspath(p) qse_ismbsabspath(p)
# define qse_isdrivepath(p) qse_ismbsdrivepath(p)
# define qse_isdriveabspath(p) qse_ismbsdriveabspath(p)
# define qse_isdrivecurpath(p) qse_ismbsdrivecurpath(p)
# define qse_basename(path) qse_mbsbasename(path)
# define qse_pathcore(p) qse_mbspathcore(p)
# define qse_canonpath(p,c,f) qse_canonmbspath(p,c,f)
# define qse_mergepathdup(d,f,m) qse_mergembspathdup(d,f,m)
# define qse_substbasenamedup(d,f,m) qse_substmbsbasenamedup(d,f,m)
#else
# define qse_isabspath(p) qse_iswcsabspath(p)
# define qse_isdrivepath(p) qse_iswcsdrivepath(p)
# define qse_isdriveabspath(p) qse_iswcsdriveabspath(p)
# define qse_isdrivecurpath(p) qse_iswcsdrivecurpath(p)
# define qse_basename(path) qse_wcsbasename(path)
# define qse_pathcore(p) qse_wcspathcore(p)
# define qse_canonpath(p,c,f) qse_canonwcspath(p,c,f)
# define qse_mergepathdup(d,f,m) qse_mergewcspathdup(d,f,m)
# define qse_substbasenamedup(d,f,m) qse_substwcsbasenamedup(d,f,m)
#endif
#if defined(__cplusplus)
}
#endif
#endif

157
include/qse/cmn/pma.h Normal file
View File

@@ -0,0 +1,157 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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.
*/
/*
tre-mem.h - TRE memory allocator interface
This software is released under a BSD-style license.
See the file LICENSE for details and copyright.
*/
#ifndef _QSE_CMN_PMA_H_
#define _QSE_CMN_PMA_H_
/** @file
* This file defines a pool-based block allocator.
*/
#include <qse/types.h>
#include <qse/macros.h>
#define QSE_PMA_BLOCK_SIZE 1024
typedef struct qse_pma_blk_t qse_pma_blk_t;
struct qse_pma_blk_t
{
void *data;
qse_pma_blk_t* next;
};
/**
* The qse_pma_t type defines a pool-based block allocator. You can allocate
* blocks of memories but you can't resize or free individual blocks allocated.
* Instead, you can destroy the whole pool once you're done with all the
* blocks allocated.
*/
typedef struct qse_pma_t qse_pma_t;
struct qse_pma_t
{
qse_mmgr_t* mmgr;
qse_pma_blk_t* blocks;
qse_pma_blk_t* current;
char *ptr;
qse_size_t n;
int failed;
};
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The qse_pma_open() function creates a pool-based memory allocator.
*/
QSE_EXPORT qse_pma_t* qse_pma_open (
qse_mmgr_t* mmgr, /**< memory manager */
qse_size_t xtnsize /**< extension size in bytes */
);
/**
* The qse_pma_close() function destroys a pool-based memory allocator.
*/
QSE_EXPORT void qse_pma_close (
qse_pma_t* pma /**< memory allocator */
);
QSE_EXPORT int qse_pma_init (
qse_pma_t* pma, /**< memory allocator */
qse_mmgr_t* mmgr /**< memory manager */
);
QSE_EXPORT void qse_pma_fini (
qse_pma_t* pma /**< memory allocator */
);
QSE_EXPORT qse_mmgr_t* qse_pma_getmmgr (
qse_pma_t* pma
);
QSE_EXPORT void* qse_pma_getxtn (
qse_pma_t* pma
);
/**
* The qse_pma_clear() function frees all the allocated memory blocks
* by freeing the entire memory pool.
*/
QSE_EXPORT void qse_pma_clear (
qse_pma_t* pma /**< memory allocator */
);
/**
* The qse_pma_alloc() function allocates a memory block of the @a size bytes.
* @return pointer to a allocated block on success, #QSE_NULL on failure.
*/
QSE_EXPORT void* qse_pma_alloc (
qse_pma_t* pma, /**< memory allocator */
qse_size_t size /**< block size */
);
/**
* The qse_pma_alloc() function allocates a memory block of the @a size bytes
* and initializes the whole block with 0.
* @return pointer to a allocated block on success, #QSE_NULL on failure.
*/
QSE_EXPORT void* qse_pma_calloc (
qse_pma_t* pma, /**< memory allocator */
qse_size_t size /**< block size */
);
/**
* The qse_pma_free() function is provided for completeness, and doesn't
* resize an individual block @a blk.
*/
QSE_EXPORT void* qse_pma_realloc (
qse_pma_t* pma, /**< memory allocator */
void* blk, /**< memory block */
qse_size_t size /**< new size in bytes */
);
/**
* The qse_pma_free() function is provided for completeness, and doesn't
* free an individual block @a blk.
*/
QSE_EXPORT void qse_pma_free (
qse_pma_t* pma, /**< memory allocator */
void* blk /**< memory block */
);
#endif

603
include/qse/cmn/rbt.h Normal file
View File

@@ -0,0 +1,603 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_RBT_H_
#define _QSE_CMN_RBT_H_
#include <qse/types.h>
#include <qse/macros.h>
/**@file
* This file provides a red-black tree encapsulated in the #qse_rbt_t type that
* implements a self-balancing binary search tree.Its interface is very close
* to #qse_htb_t.
*
* This sample code adds a series of keys and values and print them
* in descending key order.
* @code
* #include <qse/cmn/rbt.h>
* #include <qse/cmn/mem.h>
* #include <qse/cmn/sio.h>
*
* static qse_rbt_walk_t walk (qse_rbt_t* rbt, qse_rbt_pair_t* pair, void* ctx)
* {
* qse_printf (QSE_T("key = %d, value = %d\n"),
* *(int*)QSE_RBT_KPTR(pair), *(int*)QSE_RBT_VPTR(pair));
* return QSE_RBT_WALK_FORWARD;
* }
*
* int main ()
* {
* qse_rbt_t* s1;
* int i;
*
* s1 = qse_rbt_open (QSE_MMGR_GETDFL(), 0, 1, 1); // error handling skipped
* qse_rbt_setstyle (s1, qse_getrbtstyle(QSE_RBT_STYLE_INLINE_COPIERS));
*
* for (i = 0; i < 20; i++)
* {
* int x = i * 20;
* qse_rbt_insert (s1, &i, QSE_SIZEOF(i), &x, QSE_SIZEOF(x)); // eror handling skipped
* }
*
* qse_rbt_rwalk (s1, walk, QSE_NULL);
*
* qse_rbt_close (s1);
* return 0;
* }
* @endcode
*/
typedef struct qse_rbt_t qse_rbt_t;
typedef struct qse_rbt_pair_t qse_rbt_pair_t;
/**
* The qse_rbt_walk_t type defines values that the callback function can
* return to control qse_rbt_walk() and qse_rbt_rwalk().
*/
enum qse_rbt_walk_t
{
QSE_RBT_WALK_STOP = 0,
QSE_RBT_WALK_FORWARD = 1
};
typedef enum qse_rbt_walk_t qse_rbt_walk_t;
/**
* The qse_rbt_id_t type defines IDs to indicate a key or a value in various
* functions
*/
enum qse_rbt_id_t
{
QSE_RBT_KEY = 0, /**< indicate a key */
QSE_RBT_VAL = 1 /**< indicate a value */
};
typedef enum qse_rbt_id_t qse_rbt_id_t;
/**
* The qse_rbt_copier_t type defines a pair contruction callback.
*/
typedef void* (*qse_rbt_copier_t) (
qse_rbt_t* rbt /* red-black tree */,
void* dptr /* pointer to a key or a value */,
qse_size_t dlen /* length of a key or a value */
);
/**
* The qse_rbt_freeer_t defines a key/value destruction callback.
*/
typedef void (*qse_rbt_freeer_t) (
qse_rbt_t* rbt, /**< red-black tree */
void* dptr, /**< pointer to a key or a value */
qse_size_t dlen /**< length of a key or a value */
);
/**
* The qse_rbt_comper_t type defines a key comparator that is called when
* the rbt needs to compare keys. A red-black tree is created with a default
* comparator which performs bitwise comparison of two keys.
* The comparator should return 0 if the keys are the same, 1 if the first
* key is greater than the second key, -1 otherwise.
*/
typedef int (*qse_rbt_comper_t) (
const qse_rbt_t* rbt, /**< red-black tree */
const void* kptr1, /**< key pointer */
qse_size_t klen1, /**< key length */
const void* kptr2, /**< key pointer */
qse_size_t klen2 /**< key length */
);
/**
* The qse_rbt_keeper_t type defines a value keeper that is called when
* a value is retained in the context that it should be destroyed because
* it is identical to a new value. Two values are identical if their
* pointers and lengths are equal.
*/
typedef void (*qse_rbt_keeper_t) (
qse_rbt_t* rbt, /**< red-black tree */
void* vptr, /**< value pointer */
qse_size_t vlen /**< value length */
);
/**
* The qse_rbt_walker_t defines a pair visitor.
*/
typedef qse_rbt_walk_t (*qse_rbt_walker_t) (
qse_rbt_t* rbt, /**< red-black tree */
qse_rbt_pair_t* pair, /**< pointer to a key/value pair */
void* ctx /**< pointer to user-defined data */
);
/**
* The qse_rbt_cbserter_t type defines a callback function for qse_rbt_cbsert().
* The qse_rbt_cbserter() function calls it to allocate a new pair for the
* key pointed to by @a kptr of the length @a klen and the callback context
* @a ctx. The second parameter @a pair is passed the pointer to the existing
* pair for the key or #QSE_NULL in case of no existing key. The callback
* must return a pointer to a new or a reallocated pair. When reallocating the
* existing pair, this callback must destroy the existing pair and return the
* newly reallocated pair. It must return #QSE_NULL for failure.
*/
typedef qse_rbt_pair_t* (*qse_rbt_cbserter_t) (
qse_rbt_t* rbt, /**< red-black tree */
qse_rbt_pair_t* pair, /**< pair pointer */
void* kptr, /**< key pointer */
qse_size_t klen, /**< key length */
void* ctx /**< callback context */
);
/**
* The qse_rbt_pair_t type defines red-black tree pair. A pair is composed
* of a key and a value. It maintains pointers to the beginning of a key and
* a value plus their length. The length is scaled down with the scale factor
* specified in an owning tree. Use macros defined in the
*/
struct qse_rbt_pair_t
{
qse_xptl_t key;
qse_xptl_t val;
/* management information below */
enum
{
QSE_RBT_RED,
QSE_RBT_BLACK
} color;
qse_rbt_pair_t* parent;
qse_rbt_pair_t* child[2]; /* left and right */
};
typedef struct qse_rbt_style_t qse_rbt_style_t;
/**
* The qse_rbt_style_t type defines callback function sets for key/value
* pair manipulation.
*/
struct qse_rbt_style_t
{
qse_rbt_copier_t copier[2]; /**< key and value copier */
qse_rbt_freeer_t freeer[2]; /**< key and value freeer */
qse_rbt_comper_t comper; /**< key comparator */
qse_rbt_keeper_t keeper; /**< value keeper */
};
/**
* The qse_rbt_style_kind_t type defines the type of predefined
* callback set for pair manipulation.
*/
enum qse_rbt_style_kind_t
{
/** store the key and the value pointer */
QSE_RBT_STYLE_DEFAULT,
/** copy both key and value into the pair */
QSE_RBT_STYLE_INLINE_COPIERS,
/** copy the key into the pair but store the value pointer */
QSE_RBT_STYLE_INLINE_KEY_COPIER,
/** copy the value into the pair but store the key pointer */
QSE_RBT_STYLE_INLINE_VALUE_COPIER
};
typedef enum qse_rbt_style_kind_t qse_rbt_style_kind_t;
/**
* The qse_rbt_t type defines a red-black tree.
*/
struct qse_rbt_t
{
qse_mmgr_t* mmgr;
const qse_rbt_style_t* style;
qse_byte_t scale[2]; /**< length scale */
qse_rbt_pair_t xnil; /**< internal nil node */
qse_size_t size; /**< number of pairs */
qse_rbt_pair_t* root; /**< root pair */
};
/**
* The QSE_RBT_COPIER_SIMPLE macros defines a copier that remembers the
* pointer and length of data in a pair.
*/
#define QSE_RBT_COPIER_SIMPLE ((qse_rbt_copier_t)1)
/**
* The QSE_RBT_COPIER_INLINE macros defines a copier that copies data into
* a pair.
*/
#define QSE_RBT_COPIER_INLINE ((qse_rbt_copier_t)2)
#define QSE_RBT_COPIER_DEFAULT (QSE_RBT_COPIER_SIMPLE)
#define QSE_RBT_FREEER_DEFAULT (QSE_NULL)
#define QSE_RBT_COMPER_DEFAULT (qse_rbt_dflcomp)
#define QSE_RBT_KEEPER_DEFAULT (QSE_NULL)
/**
* The QSE_RBT_SIZE() macro returns the number of pairs in red-black tree.
*/
#define QSE_RBT_SIZE(m) ((const qse_size_t)(m)->size)
#define QSE_RBT_KSCALE(m) ((const int)(m)->scale[QSE_RBT_KEY])
#define QSE_RBT_VSCALE(m) ((const int)(m)->scale[QSE_RBT_VAL])
#define QSE_RBT_KPTL(p) (&(p)->key)
#define QSE_RBT_VPTL(p) (&(p)->val)
#define QSE_RBT_KPTR(p) ((p)->key.ptr)
#define QSE_RBT_KLEN(p) ((p)->key.len)
#define QSE_RBT_VPTR(p) ((p)->val.ptr)
#define QSE_RBT_VLEN(p) ((p)->val.len)
#define QSE_RBT_NEXT(p) ((p)->next)
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The qse_getrbtstyle() functions returns a predefined callback set for
* pair manipulation.
*/
QSE_EXPORT const qse_rbt_style_t* qse_getrbtstyle (
qse_rbt_style_kind_t kind
);
/**
* The qse_rbt_open() function creates a red-black tree.
* @return qse_rbt_t pointer on success, QSE_NULL on failure.
*/
QSE_EXPORT qse_rbt_t* qse_rbt_open (
qse_mmgr_t* mmgr, /**< memory manager */
qse_size_t xtnsize, /**< extension size in bytes */
int kscale, /**< key scale */
int vscale /**< value scale */
);
/**
* The qse_rbt_close() function destroys a red-black tree.
*/
QSE_EXPORT void qse_rbt_close (
qse_rbt_t* rbt /**< red-black tree */
);
/**
* The qse_rbt_init() function initializes a red-black tree
*/
QSE_EXPORT int qse_rbt_init (
qse_rbt_t* rbt, /**< red-black tree */
qse_mmgr_t* mmgr, /**< memory manager */
int kscale, /**< key scale */
int vscale /**< value scale */
);
/**
* The qse_rbt_fini() funtion finalizes a red-black tree
*/
QSE_EXPORT void qse_rbt_fini (
qse_rbt_t* rbt /**< red-black tree */
);
QSE_EXPORT qse_mmgr_t* qse_rbt_getmmgr (
qse_rbt_t* rbt
);
QSE_EXPORT void* qse_rbt_getxtn (
qse_rbt_t* rbt
);
/**
* The qse_rbt_getstyle() function gets manipulation callback function set.
*/
QSE_EXPORT const qse_rbt_style_t* qse_rbt_getstyle (
const qse_rbt_t* rbt /**< red-black tree */
);
/**
* The qse_rbt_setstyle() function sets internal manipulation callback
* functions for data construction, destruction, comparison, etc.
* The callback structure pointed to by \a style must outlive the tree
* pointed to by \a htb as the tree doesn't copy the contents of the
* structure.
*/
QSE_EXPORT void qse_rbt_setstyle (
qse_rbt_t* rbt, /**< red-black tree */
const qse_rbt_style_t* style /**< callback function set */
);
/**
* The qse_rbt_getsize() function gets the number of pairs in red-black tree.
*/
QSE_EXPORT qse_size_t qse_rbt_getsize (
const qse_rbt_t* rbt /**< red-black tree */
);
/**
* The qse_rbt_search() function searches red-black tree to find a pair with a
* matching key. It returns the pointer to the pair found. If it fails
* to find one, it returns QSE_NULL.
* @return pointer to the pair with a maching key,
* or QSE_NULL if no match is found.
*/
QSE_EXPORT qse_rbt_pair_t* qse_rbt_search (
const qse_rbt_t* rbt, /**< red-black tree */
const void* kptr, /**< key pointer */
qse_size_t klen /**< the size of the key */
);
/**
* The qse_rbt_upsert() function searches red-black tree for the pair with a
* matching key. If one is found, it updates the pair. Otherwise, it inserts
* a new pair with the key and the value given. It returns the pointer to the
* pair updated or inserted.
* @return a pointer to the updated or inserted pair on success,
* QSE_NULL on failure.
*/
QSE_EXPORT qse_rbt_pair_t* qse_rbt_upsert (
qse_rbt_t* rbt, /**< red-black tree */
void* kptr, /**< key pointer */
qse_size_t klen, /**< key length */
void* vptr, /**< value pointer */
qse_size_t vlen /**< value length */
);
/**
* The qse_rbt_ensert() function inserts a new pair with the key and the value
* given. If there exists a pair with the key given, the function returns
* the pair containing the key.
* @return pointer to a pair on success, QSE_NULL on failure.
*/
QSE_EXPORT qse_rbt_pair_t* qse_rbt_ensert (
qse_rbt_t* rbt, /**< red-black tree */
void* kptr, /**< key pointer */
qse_size_t klen, /**< key length */
void* vptr, /**< value pointer */
qse_size_t vlen /**< value length */
);
/**
* The qse_rbt_insert() function inserts a new pair with the key and the value
* given. If there exists a pair with the key given, the function returns
* QSE_NULL without channging the value.
* @return pointer to the pair created on success, QSE_NULL on failure.
*/
QSE_EXPORT qse_rbt_pair_t* qse_rbt_insert (
qse_rbt_t* rbt, /**< red-black tree */
void* kptr, /**< key pointer */
qse_size_t klen, /**< key length */
void* vptr, /**< value pointer */
qse_size_t vlen /**< value length */
);
/**
* The qse_rbt_update() function updates the value of an existing pair
* with a matching key.
* @return pointer to the pair on success, QSE_NULL on no matching pair
*/
QSE_EXPORT qse_rbt_pair_t* qse_rbt_update (
qse_rbt_t* rbt, /**< red-black tree */
void* kptr, /**< key pointer */
qse_size_t klen, /**< key length */
void* vptr, /**< value pointer */
qse_size_t vlen /**< value length */
);
/**
* The qse_rbt_cbsert() function inserts a key/value pair by delegating pair
* allocation to a callback function. Depending on the callback function,
* it may behave like qse_rbt_insert(), qse_rbt_upsert(), qse_rbt_update(),
* qse_rbt_ensert(), or totally differently. The sample code below inserts
* a new pair if the key is not found and appends the new value to the
* existing value delimited by a comma if the key is found.
*
* @code
* qse_rbt_walk_t print_map_pair (qse_rbt_t* map, qse_rbt_pair_t* pair, void* ctx)
* {
* qse_printf (QSE_T("%.*s[%d] => %.*s[%d]\n"),
* (int)QSE_RBT_KLEN(pair), QSE_RBT_KPTR(pair), (int)QSE_RBT_KLEN(pair),
* (int)QSE_RBT_VLEN(pair), QSE_RBT_VPTR(pair), (int)QSE_RBT_VLEN(pair));
* return QSE_RBT_WALK_FORWARD;
* }
*
* qse_rbt_pair_t* cbserter (
* qse_rbt_t* rbt, qse_rbt_pair_t* pair,
* void* kptr, qse_size_t klen, void* ctx)
* {
* qse_cstr_t* v = (qse_cstr_t*)ctx;
* if (pair == QSE_NULL)
* {
* // no existing key for the key
* return qse_rbt_allocpair (rbt, kptr, klen, v->ptr, v->len);
* }
* else
* {
* // a pair with the key exists.
* // in this sample, i will append the new value to the old value
* // separated by a comma
* qse_rbt_pair_t* new_pair;
* qse_char_t comma = QSE_T(',');
* qse_byte_t* vptr;
*
* // allocate a new pair, but without filling the actual value.
* // note vptr is given QSE_NULL for that purpose
* new_pair = qse_rbt_allocpair (
* rbt, kptr, klen, QSE_NULL, pair->vlen + 1 + v->len);
* if (new_pair == QSE_NULL) return QSE_NULL;
*
* // fill in the value space
* vptr = new_pair->vptr;
* qse_memcpy (vptr, pair->vptr, pair->vlen*QSE_SIZEOF(qse_char_t));
* vptr += pair->vlen*QSE_SIZEOF(qse_char_t);
* qse_memcpy (vptr, &comma, QSE_SIZEOF(qse_char_t));
* vptr += QSE_SIZEOF(qse_char_t);
* qse_memcpy (vptr, v->ptr, v->len*QSE_SIZEOF(qse_char_t));
*
* // this callback requires the old pair to be destroyed
* qse_rbt_freepair (rbt, pair);
*
* // return the new pair
* return new_pair;
* }
* }
*
* int main ()
* {
* qse_rbt_t* s1;
* int i;
* qse_char_t* keys[] = { QSE_T("one"), QSE_T("two"), QSE_T("three") };
* qse_char_t* vals[] = { QSE_T("1"), QSE_T("2"), QSE_T("3"), QSE_T("4"), QSE_T("5") };
*
* s1 = qse_rbt_open (
* QSE_MMGR_GETDFL(), 0,
* QSE_SIZEOF(qse_char_t), QSE_SIZEOF(qse_char_t)
* ); // note error check is skipped
* qse_rbt_setstyle (s1, &style1);
*
* for (i = 0; i < QSE_COUNTOF(vals); i++)
* {
* qse_cstr_t ctx;
* ctx.ptr = vals[i]; ctx.len = qse_strlen(vals[i]);
* qse_rbt_cbsert (s1,
* keys[i%QSE_COUNTOF(keys)], qse_strlen(keys[i%QSE_COUNTOF(keys)]),
* cbserter, &ctx
* ); // note error check is skipped
* }
* qse_rbt_walk (s1, print_map_pair, QSE_NULL);
*
* qse_rbt_close (s1);
* return 0;
* }
* @endcode
*/
QSE_EXPORT qse_rbt_pair_t* qse_rbt_cbsert (
qse_rbt_t* rbt, /**< red-black tree */
void* kptr, /**< key pointer */
qse_size_t klen, /**< key length */
qse_rbt_cbserter_t cbserter, /**< callback function */
void* ctx /**< callback context */
);
/**
* The qse_rbt_delete() function deletes a pair with a matching key
* @return 0 on success, -1 on failure
*/
QSE_EXPORT int qse_rbt_delete (
qse_rbt_t* rbt, /**< red-black tree */
const void* kptr, /**< key pointer */
qse_size_t klen /**< key size */
);
/**
* The qse_rbt_clear() function empties a red-black tree.
*/
QSE_EXPORT void qse_rbt_clear (
qse_rbt_t* rbt /**< red-black tree */
);
/**
* The qse_rbt_walk() function traverses a red-black tree in preorder
* from the leftmost child.
*/
QSE_EXPORT void qse_rbt_walk (
qse_rbt_t* rbt, /**< red-black tree */
qse_rbt_walker_t walker, /**< callback function for each pair */
void* ctx /**< pointer to user-specific data */
);
/**
* The qse_rbt_walk() function traverses a red-black tree in preorder
* from the rightmost child.
*/
QSE_EXPORT void qse_rbt_rwalk (
qse_rbt_t* rbt, /**< red-black tree */
qse_rbt_walker_t walker, /**< callback function for each pair */
void* ctx /**< pointer to user-specific data */
);
/**
* The qse_rbt_allocpair() function allocates a pair for a key and a value
* given. But it does not chain the pair allocated into the red-black tree @a rbt.
* Use this function at your own risk.
*
* Take note of he following special behavior when the copier is
* #QSE_RBT_COPIER_INLINE.
* - If @a kptr is #QSE_NULL, the key space of the size @a klen is reserved but
* not propagated with any data.
* - If @a vptr is #QSE_NULL, the value space of the size @a vlen is reserved
* but not propagated with any data.
*/
QSE_EXPORT qse_rbt_pair_t* qse_rbt_allocpair (
qse_rbt_t* rbt,
void* kptr,
qse_size_t klen,
void* vptr,
qse_size_t vlen
);
/**
* The qse_rbt_freepair() function destroys a pair. But it does not detach
* the pair destroyed from the red-black tree @a rbt. Use this function at your
* own risk.
*/
QSE_EXPORT void qse_rbt_freepair (
qse_rbt_t* rbt,
qse_rbt_pair_t* pair
);
/**
* The qse_rbt_dflcomp() function defines the default key comparator.
*/
QSE_EXPORT int qse_rbt_dflcomp (
const qse_rbt_t* rbt,
const void* kptr1,
qse_size_t klen1,
const void* kptr2,
qse_size_t klen2
);
#if defined(__cplusplus)
}
#endif
#endif

320
include/qse/cmn/rex.h Normal file
View File

@@ -0,0 +1,320 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_REX_H_
#define _QSE_CMN_REX_H_
#include <qse/types.h>
#include <qse/macros.h>
#include <qse/cmn/str.h>
/** @file
*
* Regular Expression Syntax
*
* regular expression := branch_set
* branch_set := branch [ '|' branch ]*
* atom := char | '.' | '^' | '$' | subgroup
* subgroup = '(' branch_set ')'
* bound := '?' | '*' | '+' | {n,m}
* bounded_atom := atom bound*
* branch := bounded_atom bounded_atom*
*
* Special escaping sequence includes:
* \uXXXX, \XX, \000, \t, \n, \r, \v, ...
*
* A special character preceded by a backslash loses its special role and
* matches the character itself literally.
*
* Some examples of compiled regular expressions are shown below.
*
* @code
* ab
* START --@ NOP --@ CHAR(a) --@ CHAR(b) --@ END
*
* a(bc)d
* START --@ NOP --@ CHAR(A) --@ GROUP --@ CHAR(d) --@ END
* u.g.head => | @
* | | <= u.g.end
* | +---------------------------+
* | | <= u.ge.group
* @ @
* NOP -@ CHAR(b) -@ CHAR(c) -@ GROUPEND
*
* ab|cd
* START --@ NOP --@ BRANCH --+--@ CHAR(a) --@ CHAR(b) --+--@ END
* | |
* | <= u.b.alter |
* +--@ CHAR(c) --@ CHAR(d) --+
* @endcode
*
* @todo
* - support \\n to refer to the nth matching substring
*/
enum qse_rex_option_t
{
/**< do not allow a special character at normal character position. */
QSE_REX_STRICT = (1 << 0),
/**< do not support the {n,m} style occurrence specifier. */
QSE_REX_NOBOUND = (1 << 1),
/**< perform case-insensitive match */
QSE_REX_IGNORECASE = (1 << 2)
};
enum qse_rex_errnum_t
{
QSE_REX_ENOERR = 0,
QSE_REX_EOTHER,
QSE_REX_ENOIMPL,
QSE_REX_ESYSERR,
QSE_REX_EINTERN,
QSE_REX_ENOMEM, /**< no sufficient memory available */
QSE_REX_ENOCOMP, /**< no expression compiled */
QSE_REX_ERECUR, /**< recursion too deep */
QSE_REX_ERPAREN, /**< right parenthesis expected */
QSE_REX_ERBRACK, /**< right bracket expected */
QSE_REX_ERBRACE, /**< right brace expected */
QSE_REX_ECOLON, /**< colon expected */
QSE_REX_ECRANGE, /**< invalid character range */
QSE_REX_ECCLASS, /**< invalid character class */
QSE_REX_EBOUND, /**< invalid occurrence bound */
QSE_REX_ESPCAWP, /**< special character at wrong position */
QSE_REX_EPREEND /**< premature expression end */
};
typedef enum qse_rex_errnum_t qse_rex_errnum_t;
enum qse_rex_node_id_t
{
QSE_REX_NODE_START,
QSE_REX_NODE_END,
QSE_REX_NODE_NOP,
QSE_REX_NODE_BOL, /* beginning of line */
QSE_REX_NODE_EOL, /* end of line */
QSE_REX_NODE_ANY, /* dot */
QSE_REX_NODE_CHAR, /* single character */
QSE_REX_NODE_CSET, /* character set */
QSE_REX_NODE_BRANCH,
QSE_REX_NODE_GROUP,
QSE_REX_NODE_GROUPEND,
QSE_REX_NODE_BACKREF /* back reference */
};
typedef enum qse_rex_node_id_t qse_rex_node_id_t;
typedef struct qse_rex_node_t qse_rex_node_t;
struct qse_rex_node_t
{
/* for internal management. not used for startnode */
qse_rex_node_t* link;
/* connect to the next node in the graph.
* it is always NULL for a branch node. */
qse_rex_node_t* next;
qse_rex_node_id_t id;
union
{
struct
{
qse_mmgr_t* mmgr;
qse_rex_node_t* link;
} s;
qse_char_t c;
struct
{
int negated;
qse_str_t* member;
} cset;
struct
{
qse_rex_node_t* alter;
} b;
struct
{
qse_rex_node_t* head;
qse_rex_node_t* end;
int pseudo;
} g;
struct
{
qse_rex_node_t* group;
int pseudo;
} ge;
struct
{
int index;
} bref;
} u;
struct
{
qse_size_t min;
qse_size_t max;
} occ;
};
enum qse_rex_cset_code_t
{
QSE_REX_CSET_CHAR,
QSE_REX_CSET_RANGE,
QSE_REX_CSET_CLASS
};
/** @struct qse_rex_t
* The qse_rex_t type defines a regular expression processor.
* You can compile a regular expression and match it againt a string.
*/
typedef struct qse_rex_t qse_rex_t;
struct qse_rex_t
{
qse_mmgr_t* mmgr;
qse_rex_errnum_t errnum;
int option;
qse_rex_node_t* code;
};
#if defined(__cplusplus)
extern "C" {
#endif
QSE_EXPORT qse_rex_t* qse_rex_open (
qse_mmgr_t* mmgr, /**< memory manager */
qse_size_t xtn, /**< extension size */
qse_rex_node_t* code /**< compiled regular expression code */
);
QSE_EXPORT void qse_rex_close (
qse_rex_t* rex
);
QSE_EXPORT int qse_rex_init (
qse_rex_t* rex,
qse_mmgr_t* mmgr,
qse_rex_node_t* code
);
/**
* The qse_rex_fini() function finalizes a statically initialized
* regular expression object @a rex.
*/
QSE_EXPORT void qse_rex_fini (
qse_rex_t* rex
);
QSE_EXPORT qse_mmgr_t* qse_rex_getmmgr (
qse_rex_t* rex
);
QSE_EXPORT void* qse_rex_getxtn (
qse_rex_t* rex
);
/**
* The qse_rex_yield() function gives up the ownership of a compiled regular
* expression. Once yielded, the compiled regular expression is not destroyed
* when @a rex is closed or finalized.
* @return start node of a compiled regular expression
*/
QSE_EXPORT qse_rex_node_t* qse_rex_yield (
qse_rex_t* rex /**< regular expression processor */
);
/**
* The qse_rex_getopt() function returns the current options.
*/
QSE_EXPORT int qse_rex_getopt (
const qse_rex_t* rex /**< regular expression processor */
);
/**
* The qse_rex_setopt() function overrides the current options with options.
*/
QSE_EXPORT void qse_rex_setopt (
qse_rex_t* rex, /**< regular expression processor */
int opts /**< 0 or number XORed of ::qse_rex_option_t enumerators */
);
QSE_EXPORT qse_rex_errnum_t qse_rex_geterrnum (
const qse_rex_t* rex
);
QSE_EXPORT const qse_char_t* qse_rex_geterrmsg (
const qse_rex_t* rex
);
QSE_EXPORT qse_rex_node_t* qse_rex_comp (
qse_rex_t* rex,
const qse_char_t* ptn,
qse_size_t len
);
QSE_EXPORT int qse_rex_exec (
qse_rex_t* rex,
const qse_cstr_t* str,
const qse_cstr_t* substr,
qse_cstr_t* matstr
);
QSE_EXPORT void* qse_buildrex (
qse_mmgr_t* mmgr,
qse_size_t depth,
int option,
const qse_char_t* ptn,
qse_size_t len,
qse_rex_errnum_t* errnum
);
QSE_EXPORT int qse_matchrex (
qse_mmgr_t* mmgr,
qse_size_t depth,
void* code,
int option,
const qse_cstr_t* str,
const qse_cstr_t* substr,
qse_cstr_t* match,
qse_rex_errnum_t* errnum
);
QSE_EXPORT void qse_freerex (
qse_mmgr_t* mmgr,
void* code
);
#if defined(__cplusplus)
}
#endif
#endif

405
include/qse/cmn/sll.h Normal file
View File

@@ -0,0 +1,405 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_SLL_H_
#define _QSE_CMN_SLL_H_
#include <qse/types.h>
#include <qse/macros.h>
/** @file
* This file provides a singly linked list interface.
*/
/**
* The qse_sll_walk_t type defines a value that qse_sll_walker_t can return.
*/
enum qse_sll_walk_t
{
QSE_SLL_WALK_STOP = 0, /**< stop traversal */
QSE_SLL_WALK_FORWARD = 1 /**< traverse to the next node */
};
typedef enum qse_sll_walk_t qse_sll_walk_t;
typedef struct qse_sll_t qse_sll_t;
typedef struct qse_sll_node_t qse_sll_node_t;
/**
* The qse_sll_copier_t type defines a callback function for node construction.
* A node is contructed when a user adds data to a list. The user can
* define how the data to add can be maintained in the list. A singly
* linked list not specified with any copiers stores the data pointer and
* the data length into a node. A special copier QSE_SLL_COPIER_INLINE copies
* the contents of the data a user provided into the node. You can use the
* qse_sll_setcopier() function to change the copier.
*
* A copier should return the pointer to the copied data. If it fails to copy
* data, it may return QSE_NULL. You need to set a proper freeer to free up
* memory allocated for copy.
*/
typedef void* (*qse_sll_copier_t) (
qse_sll_t* sll, /**< singly linked list */
void* dptr, /**< pointer to data to copy */
qse_size_t dlen /**< length of data to copy */
);
/**
* The qse_sll_freeer_t type defines a node destruction callback.
*/
typedef void (*qse_sll_freeer_t) (
qse_sll_t* sll, /**< singly linked list */
void* dptr, /**< pointer to data to free */
qse_size_t dlen /**< length of data to free */
);
/**
* The qse_sll_comper_t type defines a key comparator that is called when
* the list needs to compare data. A singly linked list is created with a
* default comparator that performs bitwise comparison.
*
* The comparator must return 0 if the data are the same and a non-zero
* integer otherwise.
*/
typedef int (*qse_sll_comper_t) (
qse_sll_t* sll, /**< singly linked list */
const void* dptr1, /**< data pointer */
qse_size_t dlen1, /**< data length */
const void* dptr2, /**< data pointer */
qse_size_t dlen2 /**< data length */
);
/**
* The qse_sll_walker_t type defines a list traversal callback for each node.
* The qse_sll_walk() calls a callback function of the type qse_sll_walker_t
* for each node until it returns QSE_SLL_WALK_STOP. The walker should return
* QSE_SLL_WALK_FORWARD to let qse_sll_walk() continue visiting the next node.
* The third parameter to qse_sll_walk() is passed to the walker as the third
* parameter.
*/
typedef qse_sll_walk_t (*qse_sll_walker_t) (
qse_sll_t* sll, /**< singly linked list */
qse_sll_node_t* node, /**< visited node */
void* ctx /**< user-defined data */
);
/**
* The qse_sll_t type defines a singly lnked list.
*/
struct qse_sll_t
{
qse_mmgr_t* mmgr;
qse_sll_copier_t copier; /**< data copier */
qse_sll_freeer_t freeer; /**< data freeer */
qse_sll_comper_t comper; /**< data comparator */
qse_byte_t scale; /**< scale factor */
qse_size_t size; /**< number of nodes */
qse_sll_node_t* head; /**< head node */
qse_sll_node_t* tail; /**< tail node */
};
/**
* The qse_sll_node_t type defines a list node containing a data pointer and
* and data length.
*/
struct qse_sll_node_t
{
qse_sll_node_t* next; /* point to the next node */
qse_xptl_t val;
};
#define QSE_SLL_COPIER_SIMPLE ((qse_sll_copier_t)1)
#define QSE_SLL_COPIER_INLINE ((qse_sll_copier_t)2)
#define QSE_SLL_HEAD(sll) ((sll)->head)
#define QSE_SLL_TAIL(sll) ((sll)->tail)
#define QSE_SLL_SIZE(sll) ((sll)->size)
#define QSE_SLL_SCALE(sll) ((sll)->scale)
/**
* The QSE_SLL_DPTR macro gets the data pointer in a node.
*/
#define QSE_SLL_DPTR(node) ((node)->val.ptr)
/**
* The QSE_SLL_DLEN macro gets the length of data in a node.
*/
#define QSE_SLL_DLEN(node) ((node)->val.len)
/**
* The QSE_SLL_NEXT macro gets the next node.
*/
#define QSE_SLL_NEXT(node) ((node)->next)
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The qse_sll_open() function creates an empty singly linked list.
* If the memory manager mmgr is QSE_NULL, the function gets the default
* memory manager with QSE_MMGR_GETDFL() and uses it if it is not QSE_NULL.
* The extension area is allocated when the positive extension size extension
* is specified. It calls the extension initialization function initializer
* after initializing the main area. The extension initializer is passed
* the pointer to the singly linked list created.
*
* @return pointer to a new singly linked list on success,
* QSE_NULL on failure
*
* @note
* In the debug build, it fails an assertion if QSE_MMGR_GETDFL() returns
* QSE_NULL and @a mmgr is QSE_NULL. In the release build, it returns QSE_NULL
* in such case.
*/
QSE_EXPORT qse_sll_t* qse_sll_open (
qse_mmgr_t* mmgr, /* memory manager */
qse_size_t ext /* size of extension area in bytes */
);
/**
* The qse_sll_close() function destroys a singly linked list freeing up
* the memory.
*/
QSE_EXPORT void qse_sll_close (
qse_sll_t* sll /**< singly linked list */
);
/**
* The qse_sll_init() function initializes a statically declared singly
* linked list. The memory should be allocated by a caller and be passed
* to it. The caller may declare a static variable of the qse_sll_t type
* and pass its address. A memory manager still needs to be passed for
* node manipulation later.
* @return 0 on success, -1 on failure
* The qse_sll_init() function returns the first parameter on success and
* QSE_NULL on failure.
*/
QSE_EXPORT int qse_sll_init (
qse_sll_t* sll, /* singly linked list */
qse_mmgr_t* mmgr /* memory manager */
);
/**
* The qse_sll_fini() function finalizes a statically initialized list.
*/
QSE_EXPORT void qse_sll_fini (
qse_sll_t* sll /**< singly linked list */
);
QSE_EXPORT qse_mmgr_t* qse_sll_getmmgr (
qse_sll_t* sll
);
QSE_EXPORT void* qse_sll_getxtn (
qse_sll_t* sll
);
/**
* The qse_sll_getscale() function gets the scale factor
*/
QSE_EXPORT int qse_sll_getscale (
qse_sll_t* sll /**< singly linked list */
);
/**
* The qse_sll_setscale() function sets the scale factor of the data length.
* A scale factor determines the actual length of data in bytes. A singly
* linked list created with a scale factor of 1. The scale factor should be
* larger than 0 and less than 256.
*/
QSE_EXPORT void qse_sll_setscale (
qse_sll_t* sll, /**< singly linked list */
int scale /**< scale factor */
);
/**
* The qse_sll_getfreeer() function gets the data copier.
*/
QSE_EXPORT qse_sll_copier_t qse_sll_getcopier (
qse_sll_t* sll /* singly linked list */
);
/**
* The qse_sll_setcopier() function changes the element copier.
* A special copier QSE_SLL_COPIER_INLINE is provided. This copier enables
* you to copy the data inline to the internal node. No freeer is invoked
* when the node is freeed. You may set the copier to QSE_NULL to perform
* no special operation when the data pointer is rememebered.
*/
QSE_EXPORT void qse_sll_setcopier (
qse_sll_t* sll, /**< singly linked list */
qse_sll_copier_t copier /**< data copier */
);
/**
* The qse_sll_getfreeer() function returns the element freeer.
*/
QSE_EXPORT qse_sll_freeer_t qse_sll_getfreeer (
qse_sll_t* sll /**< singly linked list */
);
/**
* The qse_sll_setfreeer() function changes the element freeer.
* The freeer is called when a node containing the element is destroyed.
*/
QSE_EXPORT void qse_sll_setfreeer (
qse_sll_t* sll, /**< singly linked list */
qse_sll_freeer_t freeer /**< data freeer */
);
/**
* The qse_sll_getcomper() function returns the data comparator.
*/
QSE_EXPORT qse_sll_comper_t qse_sll_getcomper (
qse_sll_t* sll /**< singly linked list */
);
/**
* The qse_sll_setcomper() function changes the data comparator
*/
QSE_EXPORT void qse_sll_setcomper (
qse_sll_t* sll, /**< singly linked list */
qse_sll_comper_t comper /**< comparator */
);
/**
* The qse_sll_getsize() function returns the number of the data nodes held
* in a singly linked list.
*/
QSE_EXPORT qse_size_t qse_sll_getsize (
qse_sll_t* sll /** singly linked list */
);
/**
* The qse_sll_gethead() function gets the head node. You may use the
* #QSE_SLL_HEAD macro instead.
*/
QSE_EXPORT qse_sll_node_t* qse_sll_gethead (
qse_sll_t* sll /**< a singly linked list */
);
/**
* The qse_sll_gettail() function gets the head node. You may use the
* #QSE_SLL_TAIL macro instead.
*/
QSE_EXPORT qse_sll_node_t* qse_sll_gettail (
qse_sll_t* sll /**< singly linked list */
);
/**
* The qse_sll_search() function traverses a list to find a node containing
* the same value as the the data pointer and length. The traversal begins
* from the next node of the positional node. If the positional node is
* QSE_NULL, the traversal begins from the head node.
*
* Note that no reverse search is provided because a reverse traversal can not
* be achieved efficiently.
*
* @return pointer to the node found. QSE_NULL if no match is found
*/
QSE_EXPORT qse_sll_node_t* qse_sll_search (
qse_sll_t* sll, /**< singly linked list */
qse_sll_node_t* pos, /**< positional node */
const void* dptr, /**< data pointer */
qse_size_t dlen /**< data length */
);
/**
* The qse_sll_insert() function inserts data to the list @a sll.
* There is performance penalty unless the positional node is neither
* the head node nor QSE_NULL. You should consider a different data
* structure such as a doubly linked list if you need to insert data
* into a random position.
* @return pointer to a new node on success, QSE_NULL on failure
*/
QSE_EXPORT qse_sll_node_t* qse_sll_insert (
qse_sll_t* sll, /**< singly linked list */
qse_sll_node_t* pos, /**< node before which a new node is inserted */
void* dptr, /**< the pointer to the data */
qse_size_t dlen /**< the length of the data */
);
/**
* The qse_sll_delete() function deletes a node.
*/
QSE_EXPORT void qse_sll_delete (
qse_sll_t* sll, /**< singly linked list */
qse_sll_node_t* pos /**< node to delete */
);
/**
* The qse_sll_clear() function empties a singly linked list by deletinng
* all the nodes.
*/
QSE_EXPORT void qse_sll_clear (
qse_sll_t* sll /**< singly linked list */
);
/**
* The qse_sll_walk() function traverses a singly linkked list from its
* head node down to its tail node as long as the walker function returns
* QSE_SLL_WALK_FORWARD . A walker can return QSE_SLL_WALK_STOP to cause
* immediate stop of traversal.
*
* For each node, the walker function is called and it is passed three
* parameters: the singly linked list, the visiting node, and the
* user-defined data passed as the third parameter in a call to the
* qse_sll_walk() function.
*/
QSE_EXPORT void qse_sll_walk (
qse_sll_t* sll, /**< singly linked list */
qse_sll_walker_t walker, /**< user-defined walker function */
void* ctx /**< the pointer to user-defined data */
);
QSE_EXPORT qse_sll_node_t* qse_sll_pushhead (
qse_sll_t* sll /**< singly linked list */,
void* dptr,
qse_size_t dlen
);
QSE_EXPORT qse_sll_node_t* qse_sll_pushtail (
qse_sll_t* sll /**< singly linked list */,
void* dptr,
qse_size_t dlen
);
QSE_EXPORT void qse_sll_pophead (
qse_sll_t* sll
);
QSE_EXPORT void qse_sll_poptail (
qse_sll_t* sll
);
#if defined(__cplusplus)
}
#endif
#endif

136
include/qse/cmn/slmb.h Normal file
View File

@@ -0,0 +1,136 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_SLMB_H_
#define _QSE_CMN_SLMB_H_
#include <qse/types.h>
#include <qse/macros.h>
/** \file
* This file provides functions, types, macros for
* multibyte/wide-character conversion based on system locale.
*/
/**
* The qse_mbstate_t type defines a structure large enough to hold
* the standard mbstate_t.
*/
typedef struct qse_mbstate_t qse_mbstate_t;
struct qse_mbstate_t
{
#if defined(QSE_SIZEOF_MBSTATE_T) && (QSE_SIZEOF_MBSTATE_T > 0)
qse_uint8_t dummy[QSE_SIZEOF_MBSTATE_T];
#else
qse_uint8_t dummy[1];
#endif
};
/* --------------------------------------------------- */
/* SYSTEM LOCALE BASED CHARACTER CONVERSION */
/* --------------------------------------------------- */
#if defined(__cplusplus)
extern "C" {
#endif
QSE_EXPORT qse_size_t qse_slmbrlen (
const qse_mchar_t* mb,
qse_size_t mblen,
qse_mbstate_t* state
);
QSE_EXPORT qse_size_t qse_slmbrtoslwc (
const qse_mchar_t* mb,
qse_size_t mblen,
qse_wchar_t* wc,
qse_mbstate_t* state
);
QSE_EXPORT qse_size_t qse_slwcrtoslmb (
qse_wchar_t wc,
qse_mchar_t* mb,
qse_size_t mblen,
qse_mbstate_t* state
);
/**
* The qse_slmbtoslwc() function converts a multibyte sequence to a wide character.
* It returns 0 if an invalid multibyte sequence is detected, mblen + 1 if the
* sequence is incomplete. It returns the number of bytes processed to form a
* wide character.
* \note This function can not handle conversion producing non-initial
* states. For each call, it assumes initial state.
*/
QSE_EXPORT qse_size_t qse_slmbtoslwc (
const qse_mchar_t* mb,
qse_size_t mblen,
qse_wchar_t* wc
);
/**
* The qse_slwctoslmb() function converts a wide character to a multibyte sequence.
* It returns 0 if the wide character is illegal, mblen + 1 if mblen is not
* large enough to hold the multibyte sequence. On successful conversion, it
* returns the number of bytes in the sequence.
* \note This function can not handle conversion producing non-initial
* states. For each call, it assumes initial state.
*/
QSE_EXPORT qse_size_t qse_slwctoslmb (
qse_wchar_t wc,
qse_mchar_t* mb,
qse_size_t mblen
);
/**
* The qse_slmblen() function scans a multibyte sequence to get the number of
* bytes needed to form a wide character. It does not scan more than \a mblen
* bytes.
* \return number of bytes processed on success,
* 0 for invalid sequences,
* mblen + 1 for incomplete sequences
* \note This function can not handle conversion producing non-initial
* states. For each call, it assumes initial state.
*/
QSE_EXPORT qse_size_t qse_slmblen (
const qse_mchar_t* mb,
qse_size_t mblen
);
/**
* The qse_slmblenmax() function returns the value of MB_CUR_MAX.
* Note that QSE_MBLEN_MAX defines MB_LEN_MAX.
*/
QSE_EXPORT qse_size_t qse_slmblenmax (
void
);
#if defined(__cplusplus)
}
#endif
#endif

3699
include/qse/cmn/str.h Normal file

File diff suppressed because it is too large Load Diff

38
include/qse/cmn/test.h Normal file
View File

@@ -0,0 +1,38 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_TEST_H_
#define _QSE_CMN_TEST_H_
#include <qse/si/sio.h>
#define QSE_TESASSERT_FAIL1(msg1) qse_printf(QSE_T("FAILURE in %hs[%d] - %s\n"), __func__, (int)__LINE__, msg1)
#define QSE_TESASSERT_FAIL2(msg1,msg2) qse_printf(QSE_T("FAILURE in %hs[%d] - %s - %s\n"), __func__, (int)__LINE__, msg1, msg2)
#define QSE_TESASSERT1(test,msg1) do { if (!(test)) { QSE_TESASSERT_FAIL1(msg1); goto oops; } } while(0)
#define QSE_TESASSERT2(test,msg1,msg2) do { if (!(test)) { QSE_TESASSERT_FAIL2(msg1,msg2); goto oops; } } while(0)
#endif

267
include/qse/cmn/time.h Normal file
View File

@@ -0,0 +1,267 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_TIME_H_
#define _QSE_CMN_TIME_H_
/** \file
* This file provides time manipulation functions.
*/
#include <qse/types.h>
#include <qse/macros.h>
#define QSE_EPOCH_YEAR (1970)
#define QSE_EPOCH_MON (1)
#define QSE_EPOCH_DAY (1)
#define QSE_EPOCH_WDAY (4)
/* windows specific epoch time */
#define QSE_EPOCH_YEAR_WIN (1601)
#define QSE_EPOCH_MON_WIN (1)
#define QSE_EPOCH_DAY_WIN (1)
#define QSE_BTIME_YEAR_BASE (1900)
#define QSE_DAYS_PER_NORMYEAR (365)
#define QSE_DAYS_PER_LEAPYEAR (366)
#define QSE_DAYS_PER_WEEK (7)
#define QSE_MONS_PER_YEAR (12)
#define QSE_HOURS_PER_DAY (24)
#define QSE_MINS_PER_HOUR (60)
#define QSE_MINS_PER_DAY (QSE_MINS_PER_HOUR*QSE_HOURS_PER_DAY)
#define QSE_SECS_PER_MIN (60)
#define QSE_SECS_PER_HOUR (QSE_SECS_PER_MIN*QSE_MINS_PER_HOUR)
#define QSE_SECS_PER_DAY (QSE_SECS_PER_MIN*QSE_MINS_PER_DAY)
#define QSE_MSECS_PER_SEC (1000)
#define QSE_MSECS_PER_MIN (QSE_MSECS_PER_SEC*QSE_SECS_PER_MIN)
#define QSE_MSECS_PER_HOUR (QSE_MSECS_PER_SEC*QSE_SECS_PER_HOUR)
#define QSE_MSECS_PER_DAY (QSE_MSECS_PER_SEC*QSE_SECS_PER_DAY)
#define QSE_USECS_PER_MSEC (1000)
#define QSE_NSECS_PER_USEC (1000)
#define QSE_NSECS_PER_MSEC (QSE_NSECS_PER_USEC*QSE_USECS_PER_MSEC)
#define QSE_USECS_PER_SEC (QSE_USECS_PER_MSEC*QSE_MSECS_PER_SEC)
#define QSE_NSECS_PER_SEC (QSE_NSECS_PER_USEC*QSE_USECS_PER_MSEC*QSE_MSECS_PER_SEC)
#define QSE_IS_LEAPYEAR(year) ((!((year)%4) && ((year)%100)) || !((year)%400))
#define QSE_DAYS_PER_YEAR(year) \
(QSE_IS_LEAPYEAR(year)? QSE_DAYS_PER_LEAPYEAR: QSE_DAYS_PER_NORMYEAR)
#define QSE_SECNSEC_TO_MSEC(sec,nsec) \
(((qse_ntime_sec_t)(sec) * QSE_MSECS_PER_SEC) + ((qse_ntime_sec_t)(nsec) / QSE_NSECS_PER_MSEC))
#define QSE_SECNSEC_TO_USEC(sec,nsec) \
(((qse_ntime_sec_t)(sec) * QSE_USECS_PER_SEC) + ((qse_ntime_sec_t)(nsec) / QSE_NSECS_PER_USEC))
#define QSE_SEC_TO_MSEC(sec) ((sec) * QSE_MSECS_PER_SEC)
#define QSE_MSEC_TO_SEC(sec) ((sec) / QSE_MSECS_PER_SEC)
#define QSE_USEC_TO_NSEC(usec) ((usec) * QSE_NSECS_PER_USEC)
#define QSE_NSEC_TO_USEC(nsec) ((nsec) / QSE_NSECS_PER_USEC)
#define QSE_MSEC_TO_NSEC(msec) ((msec) * QSE_NSECS_PER_MSEC)
#define QSE_NSEC_TO_MSEC(nsec) ((nsec) / QSE_NSECS_PER_MSEC)
#define QSE_SEC_TO_NSEC(sec) ((sec) * QSE_NSECS_PER_SEC)
#define QSE_NSEC_TO_SEC(nsec) ((nsec) / QSE_NSECS_PER_SEC)
#define QSE_SEC_TO_USEC(sec) ((sec) * QSE_USECS_PER_SEC)
#define QSE_USEC_TO_SEC(usec) ((usec) / QSE_USECS_PER_SEC)
#if defined(QSE_SIZEOF_INT64_T) && (QSE_SIZEOF_INT64_T > 0)
typedef qse_int64_t qse_ntime_sec_t;
#else
typedef qse_int32_t qse_ntime_sec_t;
#endif
typedef qse_int32_t qse_ntime_nsec_t;
/**
* The qse_ntime_t type defines a numeric time type expressed in the
* number of milliseconds since the Epoch (00:00:00 UTC, Jan 1, 1970).
*/
typedef struct qse_ntime_t qse_ntime_t;
struct qse_ntime_t
{
qse_ntime_sec_t sec;
qse_ntime_nsec_t nsec; /* nanoseconds */
};
typedef struct qse_btime_t qse_btime_t;
struct qse_btime_t
{
int sec; /* 0-61 */
int min; /* 0-59 */
int hour; /* 0-23 */
int mday; /* 1-31 */
int mon; /* 0(jan)-11(dec) */
int year; /* the number of years since QSE_BTIME_YEAR_BASE */
int wday; /* 0(sun)-6(sat) */
int yday; /* 0(jan 1) to 365 */
int isdst; /* -1(unknown), 0(not in effect), 1 (in effect) */
int gmtoff;
};
/* number of milliseconds since the Epoch (00:00:00 UTC, Jan 1, 1970) */
typedef qse_long_t qse_mtime_t;
#if defined(QSE_HAVE_INLINE)
static QSE_INLINE void qse_init_ntime(qse_ntime_t* x, qse_ntime_sec_t s, qse_ntime_nsec_t nsec)
{
x->sec = s;
x->nsec = nsec;
}
static QSE_INLINE void qse_clear_ntime(qse_ntime_t* x) { qse_init_ntime (x, 0, 0); }
/*static QSE_INLINE int qse_cmp_ntime(const qse_ntime_t* x, const qse_ntime_t* y)
{
// TODO: fix the type and value range issue and replace the macro below.
return (x->sec == y->sec)? (x->nsec - y->nsec): (x->sec - y->sec);
}*/
# define qse_cmp_ntime(x,y) (((x)->sec == (y)->sec)? ((x)->nsec - (y)->nsec): ((x)->sec - (y)->sec))
static QSE_INLINE int qse_is_neg_ntime(qse_ntime_t* x) { return x->sec < 0; }
static QSE_INLINE int qse_is_pos_ntime(qse_ntime_t* x) { return x->sec > 0 || (x->sec == 0 && x->nsec > 0); }
static QSE_INLINE int qse_is_zero_ntime(qse_ntime_t* x) { return x->sec == 0 && x->nsec == 0; }
#else
# define qse_init_ntime(x,s,ns) (((x)->sec = (s)), ((x)->nsec = (ns)))
# define qse_clear_ntime(x) qse_init_ntime(x,0,0)
# define qse_cmp_ntime(x,y) (((x)->sec == (y)->sec)? ((x)->nsec - (y)->nsec): ((x)->sec - (y)->sec))
/* if time has been normalized properly, nsec must be equal to or
* greater than 0. */
# define qse_is_neg_ntime(x) ((x)->sec < 0)
# define qse_is_pos_ntime(x) ((x)->sec > 0 || ((x)->sec == 0 && (x)->nsec > 0))
# define qse_is_zero_ntime(x) ((x)->sec == 0 && (x)->nsec == 0)
#endif
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The qse_gettime() function gets the current time.
*/
QSE_EXPORT int qse_gettime (
qse_ntime_t* nt
);
/**
* The qse_getmtime() function gets the current time in milliseconds.
*/
QSE_EXPORT int qse_getmtime (
qse_mtime_t* mt
);
/**
* The qse_settime() function sets the current time.
*/
QSE_EXPORT int qse_settime (
const qse_ntime_t* nt
);
/**
* The qse_gmtime() function converts numeric time to broken-down time.
*/
QSE_EXPORT int qse_gmtime (
const qse_ntime_t* nt,
qse_btime_t* bt
);
/**
* The qse_localtime() function converts numeric time to broken-down time
*/
QSE_EXPORT int qse_localtime (
const qse_ntime_t* nt,
qse_btime_t* bt
);
/**
* The qse_timegm() function converts broken-down time to numeric time. It is
* the inverse of qse_gmtime(). It is useful if the broken-down time is in UTC
* and the local environment is not.
*/
QSE_EXPORT int qse_timegm (
const qse_btime_t* bt,
qse_ntime_t* nt
);
/**
* The qse_timelocal() converts broken-down time to numeric time. It is the
* inverse of qse_localtime();
*/
QSE_EXPORT int qse_timelocal (
const qse_btime_t* bt,
qse_ntime_t* nt
);
/**
* The qse_add_time() function adds x and y and stores the result in z
*/
QSE_EXPORT void qse_add_ntime (
qse_ntime_t* z,
const qse_ntime_t* x,
const qse_ntime_t* y
);
/**
* The qse_sub_time() function subtract y from x and stores the result in z.
*/
QSE_EXPORT void qse_sub_ntime (
qse_ntime_t* z,
const qse_ntime_t* x,
const qse_ntime_t* y
);
/**
* The qse_mbs_to_ntime() function converts a numeric text to the numeric time.
* seconds.nanoseconds
* 10.231
*/
QSE_EXPORT int qse_mbs_to_ntime (
const qse_mchar_t* text,
qse_ntime_t* ntime
);
QSE_EXPORT int qse_wcs_to_ntime (
const qse_wchar_t* text,
qse_ntime_t* ntime
);
#if defined(QSE_CHAR_IS_MCHAR)
# define qse_str_to_ntime(text,ntime) qse_mbs_to_ntime(text,ntime)
#else
# define qse_str_to_ntime(text,ntime) qse_wcs_to_ntime(text,ntime)
#endif
#if defined(__cplusplus)
}
#endif
#endif

156
include/qse/cmn/tmr.h Normal file
View File

@@ -0,0 +1,156 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_TMR_H_
#define _QSE_CMN_TMR_H_
#include <qse/cmn/time.h>
typedef struct qse_tmr_t qse_tmr_t;
typedef struct qse_tmr_event_t qse_tmr_event_t;
typedef qse_size_t qse_tmr_index_t;
typedef void (*qse_tmr_handler_t) (
qse_tmr_t* tmr,
const qse_ntime_t* now,
qse_tmr_event_t* evt
);
typedef void (*qse_tmr_updater_t) (
qse_tmr_t* tmr,
qse_tmr_index_t old_index,
qse_tmr_index_t new_index,
qse_tmr_event_t* evt
);
struct qse_tmr_t
{
qse_mmgr_t* mmgr;
qse_size_t capa;
qse_size_t size;
qse_tmr_event_t* event;
};
struct qse_tmr_event_t
{
void* ctx; /* primary context pointer */
void* ctx2; /* secondary context pointer */
void* ctx3; /* tertiary context pointer */
qse_ntime_t when;
qse_tmr_handler_t handler;
qse_tmr_updater_t updater;
};
#define QSE_TMR_INVALID_INDEX ((qse_tmr_index_t)-1)
#define QSE_TMR_SIZE(tmr) ((tmr)->size)
#define QSE_TMR_CAPA(tmr) ((tmr)->capa);
#if defined(__cplusplus)
extern "C" {
#endif
QSE_EXPORT qse_tmr_t* qse_tmr_open (
qse_mmgr_t* mmgr,
qse_size_t xtnsize,
qse_size_t capa
);
QSE_EXPORT void qse_tmr_close (
qse_tmr_t* tmr
);
QSE_EXPORT int qse_tmr_init (
qse_tmr_t* tmr,
qse_mmgr_t* mmgr,
qse_size_t capa
);
QSE_EXPORT void qse_tmr_fini (
qse_tmr_t* tmr
);
QSE_EXPORT qse_mmgr_t* qse_tmr_getmmgr (
qse_tmr_t* tmr
);
QSE_EXPORT void* qse_tmr_getxtn (
qse_tmr_t* tmr
);
QSE_EXPORT void qse_tmr_clear (
qse_tmr_t* tmr
);
/**
* The qse_tmr_insert() function schedules a new event.
*
* \return #QSE_TMR_INVALID_INDEX on failure, valid index on success.
*/
QSE_EXPORT qse_tmr_index_t qse_tmr_insert (
qse_tmr_t* tmr,
const qse_tmr_event_t* event
);
QSE_EXPORT qse_tmr_index_t qse_tmr_update (
qse_tmr_t* tmr,
qse_tmr_index_t index,
const qse_tmr_event_t* event
);
QSE_EXPORT void qse_tmr_delete (
qse_tmr_t* tmr,
qse_tmr_index_t index
);
QSE_EXPORT int qse_tmr_fire (
qse_tmr_t* tmr,
const qse_ntime_t* tm,
qse_size_t* firecnt
);
QSE_EXPORT int qse_tmr_gettmout (
qse_tmr_t* tmr,
const qse_ntime_t* tm,
qse_ntime_t* tmout
);
/**
* The qse_tmr_getevent() function returns the
* pointer to the registered event at the given index.
*/
QSE_EXPORT qse_tmr_event_t* qse_tmr_getevent (
qse_tmr_t* tmr,
qse_tmr_index_t index
);
#if defined(__cplusplus)
}
#endif
#endif

182
include/qse/cmn/tre.h Normal file
View File

@@ -0,0 +1,182 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_TRE_TRE_H_
#define _QSE_TRE_TRE_H_
#include <qse/types.h>
#include <qse/macros.h>
enum qse_tre_errnum_t
{
QSE_TRE_ENOERR,
QSE_TRE_EOTHER,
QSE_TRE_ENOIMPL,
QSE_TRE_ESYSERR,
QSE_TRE_EINTERN,
QSE_TRE_ENOMEM, /* Out of memory */
QSE_TRE_ENOMATCH, /* No match */
QSE_TRE_EBADPAT, /* Invalid regular expression */
QSE_TRE_ECOLLATE, /* Unknown collating element */
QSE_TRE_ECTYPE, /* Unknown character class name */
QSE_TRE_EESCAPE, /* Traling backslash */
QSE_TRE_ESUBREG, /* Invalid backreference */
QSE_TRE_EBRACK, /* "[]" imbalance */
QSE_TRE_EPAREN, /* "\(\)" or "()" imbalance */
QSE_TRE_EBRACE, /* "\{\}" or "{}" imbalance */
QSE_TRE_EBADBR, /* Invalid content of {} */
QSE_TRE_ERANGE, /* Invalid use of range operator */
QSE_TRE_EBADRPT /* Invalid use of repetition operators */
};
typedef enum qse_tre_errnum_t qse_tre_errnum_t;
typedef struct qse_tre_t qse_tre_t;
struct qse_tre_t
{
qse_mmgr_t* mmgr;
qse_tre_errnum_t errnum;
qse_size_t re_nsub; /* Number of parenthesized subexpressions. */
void* value; /* For internal use only. */
};
#define QSE_TRE_ERRNUM(tre) ((const qse_tre_errnum_t)((tre)->errnum))
typedef int qse_tre_off_t;
typedef struct qse_tre_match_t qse_tre_match_t;
struct qse_tre_match_t
{
qse_tre_off_t rm_so;
qse_tre_off_t rm_eo;
};
enum qse_tre_cflag_t
{
QSE_TRE_EXTENDED = (1 << 0),
QSE_TRE_IGNORECASE = (1 << 1),
QSE_TRE_NEWLINE = (1 << 2),
QSE_TRE_NOSUBREG = (1 << 3),
QSE_TRE_LITERAL = (1 << 4),
QSE_TRE_RIGHTASSOC = (1 << 5),
QSE_TRE_UNGREEDY = (1 << 6),
/* Disable {n,m} occrrence specifier
* in the QSE_TRE_EXTENDED mode.
* it doesn't affect the BRE's \{\}. */
QSE_TRE_NOBOUND = (1 << 7),
/* Enable non-standard extensions:
* - Enable (?:text) for no submatch backreference.
* - Enable perl-like (?...) extensions like (?i)
* if QSE_TRE_EXTENDED is also set.
*/
QSE_TRE_NONSTDEXT = (1 << 8)
};
enum qse_tre_eflag_t
{
QSE_TRE_BACKTRACKING = (1 << 0),
QSE_TRE_NOTBOL = (1 << 1),
QSE_TRE_NOTEOL = (1 << 2)
};
#if defined(__cplusplus)
extern "C" {
#endif
QSE_EXPORT qse_tre_t* qse_tre_open (
qse_mmgr_t* mmgr,
qse_size_t xtnsize
);
QSE_EXPORT void qse_tre_close (
qse_tre_t* tre
);
QSE_EXPORT int qse_tre_init (
qse_tre_t* tre,
qse_mmgr_t* mmgr
);
QSE_EXPORT void qse_tre_fini (
qse_tre_t* tre
);
QSE_EXPORT qse_mmgr_t* qse_tre_getmmgr (
qse_tre_t* tre
);
QSE_EXPORT void* qse_tre_getxtn (
qse_tre_t* tre
);
QSE_EXPORT qse_tre_errnum_t qse_tre_geterrnum (
qse_tre_t* tre
);
QSE_EXPORT const qse_char_t* qse_tre_geterrmsg (
qse_tre_t* tre
);
QSE_EXPORT int qse_tre_compx (
qse_tre_t* tre,
const qse_char_t* regex,
qse_size_t n,
unsigned int* nsubmat,
int cflags
);
QSE_EXPORT int qse_tre_comp (
qse_tre_t* tre,
const qse_char_t* regex,
unsigned int* nsubmat,
int cflags
);
QSE_EXPORT int qse_tre_execx (
qse_tre_t* tre,
const qse_char_t* str,
qse_size_t len,
qse_tre_match_t* pmatch,
qse_size_t nmatch,
int eflags
);
QSE_EXPORT int qse_tre_exec (
qse_tre_t* tre,
const qse_char_t* str,
qse_tre_match_t* pmatch,
qse_size_t nmatch,
int eflags
);
#if defined(__cplusplus)
}
#endif
#endif

63
include/qse/cmn/uni.h Normal file
View File

@@ -0,0 +1,63 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_UNI_H_
#define _QSE_CMN_UNI_H_
/** @file
* This file provides functions, types, macros for unicode handling.
*/
#include <qse/types.h>
#include <qse/macros.h>
#if defined(__cplusplus)
extern "C" {
#endif
QSE_EXPORT int qse_isunitype (qse_wcint_t c, int type);
QSE_EXPORT int qse_isuniupper (qse_wcint_t c);
QSE_EXPORT int qse_isunilower (qse_wcint_t c);
QSE_EXPORT int qse_isunialpha (qse_wcint_t c);
QSE_EXPORT int qse_isunidigit (qse_wcint_t c);
QSE_EXPORT int qse_isunixdigit (qse_wcint_t c);
QSE_EXPORT int qse_isunialnum (qse_wcint_t c);
QSE_EXPORT int qse_isunispace (qse_wcint_t c);
QSE_EXPORT int qse_isuniprint (qse_wcint_t c);
QSE_EXPORT int qse_isunigraph (qse_wcint_t c);
QSE_EXPORT int qse_isunicntrl (qse_wcint_t c);
QSE_EXPORT int qse_isunipunct (qse_wcint_t c);
QSE_EXPORT int qse_isuniblank (qse_wcint_t c);
QSE_EXPORT qse_wcint_t qse_touniupper (qse_wcint_t c);
QSE_EXPORT qse_wcint_t qse_tounilower (qse_wcint_t c);
#if defined(__cplusplus)
}
#endif
#endif

119
include/qse/cmn/uri.h Normal file
View File

@@ -0,0 +1,119 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_URI_H_
#define _QSE_CMN_URI_H_
#include <qse/types.h>
#include <qse/macros.h>
typedef struct qse_muri_t qse_muri_t;
typedef struct qse_wuri_t qse_wuri_t;
struct qse_muri_t
{
qse_mcstr_t scheme;
struct
{
qse_mcstr_t user;
qse_mcstr_t pass;
} auth;
qse_mcstr_t host;
qse_mcstr_t port;
qse_mcstr_t path;
qse_mcstr_t query;
qse_mcstr_t frag;
};
struct qse_wuri_t
{
qse_wcstr_t scheme;
struct
{
qse_wcstr_t user;
qse_wcstr_t pass;
} auth;
qse_wcstr_t host;
qse_wcstr_t port;
qse_wcstr_t path;
qse_wcstr_t query;
qse_wcstr_t frag;
};
enum qse_mbstouri_flag_t
{
QSE_MBSTOURI_NOAUTH = (1 << 0),
QSE_MBSTOURI_NOQUERY = (1 << 1),
QSE_MBSTOURI_NOFRAG = (1 << 2)
};
enum qse_wcstouri_flag_t
{
QSE_WCSTOURI_NOAUTH = (1 << 0),
QSE_WCSTOURI_NOQUERY = (1 << 1),
QSE_WCSTOURI_NOFRAG = (1 << 2)
};
#if defined(QSE_CHAR_IS_MCHAR)
# define QSE_STRTOURI_NOAUTH QSE_MBSTOURI_NOAUTH
# define QSE_STRTOURI_NOQUERY QSE_MBSTOURI_NOQUERY
# define QSE_STRTOURI_NOFRAG QSE_MBSTOURI_NOFRAG
typedef qse_muri_t qse_uri_t;
#else
# define QSE_STRTOURI_NOAUTH QSE_WCSTOURI_NOAUTH
# define QSE_STRTOURI_NOQUERY QSE_WCSTOURI_NOQUERY
# define QSE_STRTOURI_NOFRAG QSE_WCSTOURI_NOFRAG
typedef qse_wuri_t qse_uri_t;
#endif
#if defined(__cplusplus)
extern "C" {
#endif
QSE_EXPORT int qse_mbstouri (
const qse_mchar_t* str,
qse_muri_t* uri,
int flags
);
QSE_EXPORT int qse_wcstouri (
const qse_wchar_t* str,
qse_wuri_t* uri,
int flags
);
#if defined(QSE_CHAR_IS_MCHAR)
#define qse_strtouri(str,uri,flags) qse_mbstouri(str,uri,flags)
#else
#define qse_strtouri(str,uri,flags) qse_wcstouri(str,uri,flags)
#endif
#if defined(__cplusplus)
}
#endif
#endif

118
include/qse/cmn/utf8.h Normal file
View File

@@ -0,0 +1,118 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_UTF8_H_
#define _QSE_CMN_UTF8_H_
#include <qse/types.h>
#include <qse/macros.h>
/** @file
* This file provides functions, types, macros for utf8 conversion.
*/
/**
* The QSE_UTF8LEN_MAX macro defines the maximum number of bytes
* needed to form a single unicode character.
*/
#if (QSE_SIZEOF_WCHAR_T == QSE_SIZEOF_MCHAR_T)
/* cannot handle utf8 conversion properly */
# define QSE_UTF8LEN_MAX 1
#elif (QSE_SIZEOF_WCHAR_T == 2)
# define QSE_UTF8LEN_MAX 3
#elif (QSE_SIZEOF_WCHAR_T == 4)
# define QSE_UTF8LEN_MAX 6
#else
# error Unsupported wide-character size
#endif
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The qse_uctoutf8() function converts a unicode character to a utf8 sequence.
* @return
* - 0 is returned if @a uc is invalid.
* - An integer greater than @a size is returned if the @a utf8 sequence buffer
* is not #QSE_NULL and not large enough. This integer is actually the number
* of bytes needed.
* - If @a utf8 is #QSE_NULL, the number of bytes that would have been stored
* into @a utf8 if it had not been #QSE_NULL is returned.
* - An integer between 1 and size inclusive is returned in all other cases.
* @note
* This function doesn't check invalid unicode code points and performs
* conversion compuationally.
*/
qse_size_t qse_uctoutf8 (
qse_wchar_t uc,
qse_mchar_t* utf8,
qse_size_t size
);
/**
* The qse_utf8touc() function converts a utf8 sequence to a unicode character.
* @return
* - 0 is returned if the @a utf8 sequence is invalid.
* - An integer greater than @a size is returned if the @a utf8 sequence is
* not complete.
* - An integer between 1 and size inclusive is returned in all other cases.
*/
qse_size_t qse_utf8touc (
const qse_mchar_t* utf8,
qse_size_t size,
qse_wchar_t* uc
);
/**
* The qse_utf8len() function scans at most @a size bytes from the @a utf8
* sequence and returns the number of bytes needed to form a single unicode
* character.
* @return
* - 0 is returned if the @a utf8 sequence is invalid.
* - An integer greater than @a size is returned if the @a utf8 sequence is
* not complete.
* - An integer between 1 and size inclusive is returned in all other cases.
*/
qse_size_t qse_utf8len (
const qse_mchar_t* utf8,
qse_size_t size
);
/**
* The qse_utf8lenmax() function returns the maximum number of bytes needed
* to form a single unicode character. Use #QSE_UTF8LEN_MAX if you need a
* compile-time constant.
*/
qse_size_t qse_utf8lenmax (
void
);
#if defined(__cplusplus)
}
#endif
#endif

236
include/qse/cmn/xma.h Normal file
View File

@@ -0,0 +1,236 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CMN_XMA_H_
#define _QSE_CMN_XMA_H_
/** @file
* This file defines an extravagant memory allocator. Why? It may be so.
* The memory allocator allows you to maintain memory blocks from a
* larger memory chunk allocated with an outer memory allocator.
* Typically, an outer memory allocator is a standard memory allocator
* like malloc(). You can isolate memory blocks into a particular chunk.
*
* See the example below. Note it omits error handling.
*
* @code
* #include <qse/cmn/xma.h>
* #include <qse/cmn/stdio.h>
* int main ()
* {
* qse_xma_t* xma;
* void* ptr1, * ptr2;
*
* // create a new memory allocator obtaining a 100K byte zone
* // with the default memory allocator
* xma = qse_xma_open(QSE_NULL, 0, 100000L);
*
* ptr1 = qse_xma_alloc(xma, 5000); // allocate a 5K block from the zone
* ptr2 = qse_xma_alloc(xma, 1000); // allocate a 1K block from the zone
* ptr1 = qse_xma_realloc(xma, ptr1, 6000); // resize the 5K block to 6K.
*
* qse_xma_dump (xma, qse_fprintf, QSE_STDOUT); // dump memory blocks
*
* // the following two lines are not actually needed as the allocator
* // is closed after them.
* qse_xma_free (xma, ptr2); // dispose of the 1K block
* qse_xma_free (xma, ptr1); // dispose of the 6K block
*
* qse_xma_close (xma); // destroy the memory allocator
* return 0;
* }
* @endcode
*/
#include <qse/types.h>
#include <qse/macros.h>
#if defined(QSE_BUILD_DEBUG)
# define QSE_XMA_ENABLE_STAT
#endif
/** @struct qse_xma_t
* The qse_xma_t type defines a simple memory allocator over a memory zone.
* It can obtain a relatively large zone of memory and manage it.
*/
typedef struct qse_xma_t qse_xma_t;
/**
* The qse_xma_fblk_t type defines a memory block allocated.
*/
typedef struct qse_xma_fblk_t qse_xma_fblk_t;
typedef struct qse_xma_mblk_t qse_xma_mblk_t;
#define QSE_XMA_FIXED 32
#define QSE_XMA_SIZE_BITS ((QSE_SIZEOF_SIZE_T*8)-1)
struct qse_xma_t
{
qse_mmgr_t* _mmgr;
qse_uint8_t* start; /* zone beginning */
qse_uint8_t* end; /* zone end */
int internal;
/** pointer array to free memory blocks */
qse_xma_fblk_t* xfree[QSE_XMA_FIXED + QSE_XMA_SIZE_BITS + 1];
/** pre-computed value for fast xfree index calculation */
qse_size_t bdec;
#if defined(QSE_XMA_ENABLE_STAT)
struct
{
qse_size_t total;
qse_size_t alloc;
qse_size_t avail;
qse_size_t nused;
qse_size_t nfree;
} stat;
#endif
};
/**
* The qse_xma_dumper_t type defines a printf-like output function
* for qse_xma_dump().
*/
typedef int (*qse_xma_dumper_t) (
void* ctx,
const qse_char_t* fmt,
...
);
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The qse_xma_open() function creates a memory allocator. It obtains a memory
* zone of the @a zonesize bytes with the memory manager @a mmgr. It also makes
* available the extension area of the @a xtnsize bytes that you can get the
* pointer to with qse_xma_getxtn().
*
* @return pointer to a memory allocator on success, #QSE_NULL on failure
*/
QSE_EXPORT qse_xma_t* qse_xma_open (
qse_mmgr_t* mmgr, /**< memory manager */
qse_size_t xtnsize, /**< extension size in bytes */
void* zoneptr,
qse_size_t zonesize /**< zone size in bytes */
);
/**
* The qse_xma_close() function destroys a memory allocator. It also frees
* the memory zone obtained, which invalidates the memory blocks within
* the zone. Call this function to destroy a memory allocator created with
* qse_xma_open().
*/
QSE_EXPORT void qse_xma_close (
qse_xma_t* xma /**< memory allocator */
);
#if defined(QSE_HAVE_INLINE)
static QSE_INLINE qse_mmgr_t* qse_xma_getmmgr (qse_xma_t* xma) { return xma->_mmgr; }
#else
# define qse_xma_getmmgr(xma) (((qse_xma_t*)(xma))->_mmgr)
#endif
#if defined(QSE_HAVE_INLINE)
static QSE_INLINE void* qse_xma_getxtn (qse_xma_t* xma) { return (void*)(xma + 1); }
#else
#define qse_xma_getxtn(xma) ((void*)((qse_xma_t*)(xma) + 1))
#endif
/**
* The qse_xma_init() initializes a memory allocator. If you have the qse_xma_t
* structure statically declared or already allocated, you may pass the pointer
* to this function instead of calling qse_xma_open(). It obtains a memory zone
* of @a zonesize bytes with the memory manager @a mmgr. Unlike qse_xma_open(),
* it does not accept the extension size, thus not creating an extention area.
* @return 0 on success, -1 on failure
*/
QSE_EXPORT int qse_xma_init (
qse_xma_t* xma, /**< memory allocator */
qse_mmgr_t* mmgr, /**< memory manager */
void* zoneptr, /**< pointer to memory zone. if #QSE_NULL, a zone is auto-created */
qse_size_t zonesize /**< zone size in bytes */
);
/**
* The qse_xma_fini() function finalizes a memory allocator. Call this
* function to finalize a memory allocator initialized with qse_xma_init().
*/
QSE_EXPORT void qse_xma_fini (
qse_xma_t* xma /**< memory allocator */
);
/**
* The qse_xma_alloc() function allocates @a size bytes.
* @return pointer to a memory block on success, #QSE_NULL on failure
*/
QSE_EXPORT void* qse_xma_alloc (
qse_xma_t* xma, /**< memory allocator */
qse_size_t size /**< size in bytes */
);
QSE_EXPORT void* qse_xma_calloc (
qse_xma_t* xma,
qse_size_t size
);
/**
* The qse_xma_alloc() function resizes the memory block @a b to @a size bytes.
* @return pointer to a resized memory block on success, #QSE_NULL on failure
*/
QSE_EXPORT void* qse_xma_realloc (
qse_xma_t* xma, /**< memory allocator */
void* b, /**< memory block */
qse_size_t size /**< new size in bytes */
);
/**
* The qse_xma_alloc() function frees the memory block @a b.
*/
QSE_EXPORT void qse_xma_free (
qse_xma_t* xma, /**< memory allocator */
void* b /**< memory block */
);
/**
* The qse_xma_dump() function dumps the contents of the memory zone
* with the output function @a dumper provided. The debug build shows
* more statistical counters.
*/
QSE_EXPORT void qse_xma_dump (
qse_xma_t* xma, /**< memory allocator */
qse_xma_dumper_t dumper, /**< output function */
void* ctx /**< first parameter to output function */
);
#if defined(__cplusplus)
}
#endif
#endif

126
include/qse/conf-dos.h Normal file
View File

@@ -0,0 +1,126 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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.
*/
/* DOS for other platforms than x86?
* If so, the endian should be defined selectively
*/
#define QSE_ENDIAN_LITTLE
/*
* You must define which character type to use as a default character here.
*
* #define QSE_CHAR_IS_WCHAR
* #define QSE_CHAR_IS_MCHAR
*/
#if defined(__WATCOMC__) && defined(__386__)
# define QSE_SIZEOF_CHAR 1
# define QSE_SIZEOF_SHORT 2
# define QSE_SIZEOF_INT 4
# define QSE_SIZEOF_LONG 4
# if (__WATCOMC__ < 1200)
# define QSE_SIZEOF_LONG_LONG 0
# else
# define QSE_SIZEOF_LONG_LONG 8
# endif
# define QSE_SIZEOF_VOID_P 4
# define QSE_SIZEOF_FLOAT 4
# define QSE_SIZEOF_DOUBLE 8
# define QSE_SIZEOF_LONG_DOUBLE 8
# define QSE_SIZEOF_WCHAR_T 2
# define QSE_SIZEOF___INT8 1
# define QSE_SIZEOF___INT16 2
# define QSE_SIZEOF___INT32 4
# define QSE_SIZEOF___INT64 8
# define QSE_SIZEOF___INT128 0
# define QSE_SIZEOF_OFF64_T 0
# define QSE_SIZEOF_OFF_T 4
# define QSE_SIZEOF_MBSTATE_T QSE_SIZEOF_LONG
# define QSE_MBLEN_MAX 8
/* these two have only to be large enough */
# define QSE_SIZEOF_STRUCT_SOCKADDR_IN 32
# define QSE_SIZEOF_STRUCT_SOCKADDR_IN6 64
# define QSE_SIZEOF_SOCKLEN_T 4
# if !defined(QSE_CHAR_IS_WCHAR) && !defined(QSE_CHAR_IS_MCHAR)
# define QSE_CHAR_IS_WCHAR 1
# endif
/* old watcom c/c++ compiler requires this */
# if (__WATCOMC__ < 1200)
# undef QSE_ENABLE_BUNDLED_UNICODE
# define QSE_ENABLE_BUNDLED_UNICODE 1
# endif
#elif defined(__WATCOMC__) && !defined(__386__)
# define QSE_SIZEOF_CHAR 1
# define QSE_SIZEOF_SHORT 2
# define QSE_SIZEOF_INT 2
# define QSE_SIZEOF_LONG 4
# define QSE_SIZEOF_LONG_LONG 8
# define QSE_SIZEOF_VOID_P 4
# define QSE_SIZEOF_FLOAT 4
# define QSE_SIZEOF_DOUBLE 8
# define QSE_SIZEOF_LONG_DOUBLE 8
# define QSE_SIZEOF_WCHAR_T 2
# define QSE_SIZEOF___INT8 1
# define QSE_SIZEOF___INT16 2
# define QSE_SIZEOF___INT32 4
# define QSE_SIZEOF___INT64 8
# define QSE_SIZEOF___INT128 0
# define QSE_SIZEOF_OFF64_T 0
# define QSE_SIZEOF_OFF_T 4
# define QSE_SIZEOF_MBSTATE_T QSE_SIZEOF_LONG
# define QSE_MBLEN_MAX 8
/* these two have only to be large enough */
# define QSE_SIZEOF_STRUCT_SOCKADDR_IN 32
# define QSE_SIZEOF_STRUCT_SOCKADDR_IN6 64
# define QSE_SIZEOF_SOCKLEN_T 4
# if !defined(QSE_CHAR_IS_WCHAR) && !defined(QSE_CHAR_IS_MCHAR)
# define QSE_CHAR_IS_WCHAR 1
# endif
/* old watcom c/c++ compiler requires this */
# if (__WATCOMC__ < 1200)
# undef QSE_ENABLE_BUNDLED_UNICODE
# define QSE_ENABLE_BUNDLED_UNICODE 1
# endif
#else
# error Define the size of various data types.
#endif
#include <qse/conf-inf.h>

12
include/qse/conf-inf.h Normal file
View File

@@ -0,0 +1,12 @@
#ifndef _QSE_CONF_INF_H_
#define _QSE_CONF_INF_H_
/* This file is used for non-autoconf based build systems.
* Change this information whenever you update package version in configure.ac */
#define QSE_PACKAGE_VERSION "0.9.0"
#define QSE_PACKAGE_VERSION_MAJOR 0
#define QSE_PACKAGE_VERSION_MINOR 9
#define QSE_PACKAGE_VERSION_PATCH 0
#endif

79
include/qse/conf-mac.h Normal file
View File

@@ -0,0 +1,79 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 is for class Mac OS */
/* Mac OS on PPC and m68k uses the big endian mode */
#define QSE_ENDIAN_BIG
/*
* You must define which character type to use as a default character here.
*
* #define QSE_CHAR_IS_WCHAR
* #define QSE_CHAR_IS_MCHAR
*/
#if defined(__MWERKS__)
# define QSE_SIZEOF_CHAR 1
# define QSE_SIZEOF_SHORT 2
# define QSE_SIZEOF_INT 4
# define QSE_SIZEOF_LONG 4
# define QSE_SIZEOF_LONG_LONG 8
# define QSE_SIZEOF_VOID_P 4
# define QSE_SIZEOF_FLOAT 4
# define QSE_SIZEOF_DOUBLE 8
# define QSE_SIZEOF_LONG_DOUBLE 8
# define QSE_SIZEOF_WCHAR_T 2
# define QSE_SIZEOF___INT8 1
# define QSE_SIZEOF___INT16 2
# define QSE_SIZEOF___INT32 4
# define QSE_SIZEOF___INT64 8
# define QSE_SIZEOF___INT128 0
# define QSE_SIZEOF_OFF64_T 0
# define QSE_SIZEOF_OFF_T 8
# define QSE_SIZEOF_MBSTATE_T QSE_SIZEOF_LONG
# define QSE_MBLEN_MAX 16
/* these two have only to be large enough */
# define QSE_SIZEOF_STRUCT_SOCKADDR_IN 32
# define QSE_SIZEOF_STRUCT_SOCKADDR_IN6 64
# define QSE_SIZEOF_SOCKLEN_T 4
# if !defined(QSE_CHAR_IS_WCHAR) && !defined(QSE_CHAR_IS_MCHAR)
# define QSE_CHAR_IS_WCHAR 1
# endif
# undef QSE_ENABLE_BUNDLED_UNICODE
# define QSE_ENABLE_BUNDLED_UNICODE 1
#else
# error Define the size of various data types.
#endif
#include <:qse:conf-inf.h>

223
include/qse/conf-msw.h Normal file
View File

@@ -0,0 +1,223 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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.
*/
/*
Macro Meaning
_WIN64 A 64-bit platform.
_WIN32 A 32-bit platform. This value is also defined by the 64-bit
compiler for backward compatibility.
_WIN16 A 16-bit platform
The following macros are specific to the architecture.
Macro Meaning
_M_IA64 Intel Itanium Processor Family
_M_IX86 x86 platform
_M_X64 x64 platform
*/
/* windows for most of non-x86 platforms dropped.
* make it selective to support old non-x86 windows platforms. */
#define QSE_ENDIAN_LITTLE
/*
* You must define which character type to use as a default character here.
*
* #define QSE_CHAR_IS_WCHAR
* #define QSE_CHAR_IS_MCHAR
*/
#if defined(__WATCOMC__)
# define QSE_SIZEOF_CHAR 1
# define QSE_SIZEOF_SHORT 2
# define QSE_SIZEOF_INT 4
# define QSE_SIZEOF_LONG 4
# if (__WATCOMC__ < 1200)
# define QSE_SIZEOF_LONG_LONG 0
# else
# define QSE_SIZEOF_LONG_LONG 8
# endif
# if defined(_WIN64)
# define QSE_SIZEOF_VOID_P 8
# else
# define QSE_SIZEOF_VOID_P 4
# endif
# define QSE_SIZEOF_FLOAT 4
# define QSE_SIZEOF_DOUBLE 8
# define QSE_SIZEOF_LONG_DOUBLE 8
# define QSE_SIZEOF_WCHAR_T 2
# define QSE_SIZEOF___INT8 1
# define QSE_SIZEOF___INT16 2
# define QSE_SIZEOF___INT32 4
# define QSE_SIZEOF___INT64 8
# define QSE_SIZEOF___INT128 0
# define QSE_SIZEOF_OFF64_T 0
# define QSE_SIZEOF_OFF_T 8
# define QSE_SIZEOF_MBSTATE_T QSE_SIZEOF_LONG
# define QSE_MBLEN_MAX 16
/* these two have only to be large enough */
# define QSE_SIZEOF_STRUCT_SOCKADDR_IN 32
# define QSE_SIZEOF_STRUCT_SOCKADDR_IN6 64
# define QSE_SIZEOF_SOCKLEN_T 4
# if !defined(QSE_CHAR_IS_WCHAR) && !defined(QSE_CHAR_IS_MCHAR)
# define QSE_CHAR_IS_WCHAR 1
# endif
/* old watcom c/c++ compiler requires this */
# if (__WATCOMC__ < 1200)
# undef QSE_ENABLE_BUNDLED_UNICODE
# define QSE_ENABLE_BUNDLED_UNICODE 1
# endif
#elif defined(__GNUC__) || defined(__DMC__) || defined(__POCC__)
# define QSE_SIZEOF_CHAR 1
# define QSE_SIZEOF_SHORT 2
# define QSE_SIZEOF_INT 4
# define QSE_SIZEOF_LONG 4
# define QSE_SIZEOF_LONG_LONG 8
# if defined(_WIN64)
# define QSE_SIZEOF_VOID_P 8
# else
# define QSE_SIZEOF_VOID_P 4
# endif
# define QSE_SIZEOF_FLOAT 4
# define QSE_SIZEOF_DOUBLE 8
# define QSE_SIZEOF_LONG_DOUBLE 16
# define QSE_SIZEOF_WCHAR_T 2
# define QSE_SIZEOF___INT8 0
# define QSE_SIZEOF___INT16 0
# define QSE_SIZEOF___INT32 0
# define QSE_SIZEOF___INT64 0
# define QSE_SIZEOF___INT128 0
# define QSE_SIZEOF_OFF64_T 0
# define QSE_SIZEOF_OFF_T 8
# define QSE_SIZEOF_MBSTATE_T QSE_SIZEOF_LONG
# define QSE_MBLEN_MAX 16
/* these two have only to be large enough */
# define QSE_SIZEOF_STRUCT_SOCKADDR_IN 32
# define QSE_SIZEOF_STRUCT_SOCKADDR_IN6 64
# if !defined(QSE_CHAR_IS_WCHAR) && !defined(QSE_CHAR_IS_MCHAR)
# define QSE_CHAR_IS_WCHAR 1
# endif
#elif defined(_MSC_VER)
# define QSE_SIZEOF_CHAR 1
# define QSE_SIZEOF_SHORT 2
# define QSE_SIZEOF_INT 4
# define QSE_SIZEOF_LONG 4
# if (_MSC_VER>=1310)
# define QSE_SIZEOF_LONG_LONG 8
# else
# define QSE_SIZEOF_LONG_LONG 0
# endif
# if defined(_WIN64)
# define QSE_SIZEOF_VOID_P 8
# else
# define QSE_SIZEOF_VOID_P 4
# endif
# define QSE_SIZEOF_FLOAT 4
# define QSE_SIZEOF_DOUBLE 8
# define QSE_SIZEOF_LONG_DOUBLE 8
# define QSE_SIZEOF_WCHAR_T 2
# define QSE_SIZEOF___INT8 1
# define QSE_SIZEOF___INT16 2
# define QSE_SIZEOF___INT32 4
# define QSE_SIZEOF___INT64 8
# define QSE_SIZEOF___INT128 0
# define QSE_SIZEOF_OFF64_T 0
# define QSE_SIZEOF_OFF_T 8
# define QSE_SIZEOF_MBSTATE_T QSE_SIZEOF_LONG
# define QSE_MBLEN_MAX 8
/* these two have only to be large enough */
# define QSE_SIZEOF_STRUCT_SOCKADDR_IN 32
# define QSE_SIZEOF_STRUCT_SOCKADDR_IN6 64
# define QSE_SIZEOF_SOCKLEN_T 4
# if !defined(QSE_CHAR_IS_WCHAR) && !defined(QSE_CHAR_IS_MCHAR)
# define QSE_CHAR_IS_WCHAR 1
# endif
#elif defined(__BORLANDC__)
# define QSE_SIZEOF_CHAR 1
# define QSE_SIZEOF_SHORT 2
# define QSE_SIZEOF_INT 4
# define QSE_SIZEOF_LONG 4
# define QSE_SIZEOF_LONG_LONG 0
# if defined(_WIN64)
# define QSE_SIZEOF_VOID_P 8
# else
# define QSE_SIZEOF_VOID_P 4
# endif
# define QSE_SIZEOF_FLOAT 4
# define QSE_SIZEOF_DOUBLE 8
# define QSE_SIZEOF_LONG_DOUBLE 8
# define QSE_SIZEOF_WCHAR_T 2
# define QSE_SIZEOF___INT8 1
# define QSE_SIZEOF___INT16 2
# define QSE_SIZEOF___INT32 4
# define QSE_SIZEOF___INT64 8
# define QSE_SIZEOF___INT128 0
# define QSE_SIZEOF_OFF64_T 0
# define QSE_SIZEOF_OFF_T 8
# define QSE_SIZEOF_MBSTATE_T QSE_SIZEOF_LONG
# define QSE_MBLEN_MAX 8
/* these two have only to be large enough */
# define QSE_SIZEOF_STRUCT_SOCKADDR_IN 32
# define QSE_SIZEOF_STRUCT_SOCKADDR_IN6 64
# define QSE_SIZEOF_SOCKLEN_T 4
# if !defined(QSE_CHAR_IS_WCHAR) && !defined(QSE_CHAR_IS_MCHAR)
# define QSE_CHAR_IS_WCHAR 1
# endif
#else
# error Define the size of various data types.
#endif
#include <qse/conf-inf.h>

122
include/qse/conf-os2.h Normal file
View File

@@ -0,0 +1,122 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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.
*/
/* OS/2 for other platforms than x86?
* If so, the endian should be defined selectively
*/
#define QSE_ENDIAN_LITTLE
/*
* You must define which character type to use as a default character here.
*
* #define QSE_CHAR_IS_WCHAR
* #define QSE_CHAR_IS_MCHAR
*/
#if defined(__WATCOMC__)
# define QSE_SIZEOF_CHAR 1
# define QSE_SIZEOF_SHORT 2
# define QSE_SIZEOF_INT 4
# define QSE_SIZEOF_LONG 4
# if (__WATCOMC__ < 1200)
# define QSE_SIZEOF_LONG_LONG 0
# else
# define QSE_SIZEOF_LONG_LONG 8
# endif
# define QSE_SIZEOF_VOID_P 4
# define QSE_SIZEOF_FLOAT 4
# define QSE_SIZEOF_DOUBLE 8
# define QSE_SIZEOF_LONG_DOUBLE 8
# define QSE_SIZEOF_WCHAR_T 2
# define QSE_SIZEOF___INT8 1
# define QSE_SIZEOF___INT16 2
# define QSE_SIZEOF___INT32 4
# define QSE_SIZEOF___INT64 8
# define QSE_SIZEOF___INT128 0
# define QSE_SIZEOF_OFF64_T 0
# define QSE_SIZEOF_OFF_T 8
/* I don't know the exact mbstate size.
* but this should be large enough */
# define QSE_SIZEOF_MBSTATE_T QSE_SIZEOF_LONG
/* TODO: check the exact value */
# define QSE_MBLEN_MAX 8
/* these two have only to be large enough */
# define QSE_SIZEOF_STRUCT_SOCKADDR_IN 32
# define QSE_SIZEOF_STRUCT_SOCKADDR_IN6 64
# define QSE_SIZEOF_SOCKLEN_T 4
# if !defined(QSE_CHAR_IS_WCHAR) && !defined(QSE_CHAR_IS_MCHAR)
# define QSE_CHAR_IS_WCHAR 1
# endif
/* old watcom c/c++ compiler requires this */
# if (__WATCOMC__ < 1200)
# undef QSE_ENABLE_BUNDLED_UNICODE
# define QSE_ENABLE_BUNDLED_UNICODE 1
# endif
#elif defined(__BORLANDC__)
# define QSE_SIZEOF_CHAR 1
# define QSE_SIZEOF_SHORT 2
# define QSE_SIZEOF_INT 4
# define QSE_SIZEOF_LONG 4
# define QSE_SIZEOF_LONG_LONG 0
# define QSE_SIZEOF_VOID_P 4
# define QSE_SIZEOF_FLOAT 4
# define QSE_SIZEOF_DOUBLE 8
# define QSE_SIZEOF_LONG_DOUBLE 8
# define QSE_SIZEOF_WCHAR_T 2
# define QSE_SIZEOF___INT8 0
# define QSE_SIZEOF___INT16 0
# define QSE_SIZEOF___INT32 0
# define QSE_SIZEOF___INT64 0
# define QSE_SIZEOF___INT128 0
# define QSE_SIZEOF_OFF64_T 0
# define QSE_SIZEOF_OFF_T 4
# define QSE_SIZEOF_MBSTATE_T QSE_SIZEOF_LONG
# define QSE_MBLEN_MAX 8
# define QSE_SIZEOF_STRUCT_SOCKADDR_IN 32
# define QSE_SIZEOF_STRUCT_SOCKADDR_IN6 64
# define QSE_SIZEOF_SOCKLEN_T 4
# if !defined(QSE_CHAR_IS_WCHAR) && !defined(QSE_CHAR_IS_MCHAR)
# define QSE_CHAR_IS_WCHAR 1
# endif
# define QSE_ENABLE_BUNDLED_UNICODE 1
#else
# error Define the size of various data types.
#endif
#include <qse/conf-inf.h>

136
include/qse/conf-vms.h Normal file
View File

@@ -0,0 +1,136 @@
/*
* $Id: conf_vms.h 441 2011-04-22 14:28:43Z hyunghwan.chung $
*
Copyright (c) 2006-2019 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.
*/
/* all of vax, alpha, ia64 are in the little endian. */
#define QSE_ENDIAN_LITTLE
/*
* Refer to the chapter 3 of the following URL for the data sizes.
* http://h71000.www7.hp.com/commercial/c/docs/6180profile.html
*/
#define QSE_SIZEOF_CHAR 1
#define QSE_SIZEOF_SHORT 2
#define QSE_SIZEOF_INT 4
#define QSE_SIZEOF_LONG 4
#if defined(vax) || defined(__vax)
#define QSE_SIZEOF_LONG_LONG 0
#elif defined(alpha) || defined(__alpha)
#define QSE_SIZEOF_LONG_LONG 8
#elif defined(ia64) || defined(__ia64)
#define QSE_SIZEOF_LONG_LONG 8
#else
#define QSE_SIZEOF_LONG_LONG 0
#endif
#define QSE_SIZEOF___INT8 1
#define QSE_SIZEOF___INT16 2
#define QSE_SIZEOF___INT32 4
#if defined(vax) || defined(__vax)
#define QSE_SIZEOF___INT64 0
#elif defined(alpha) || defined(__alpha)
#define QSE_SIZEOF___INT64 8
#elif defined(ia64) || defined(__ia64)
#define QSE_SIZEOF___INT64 8
#else
#define QSE_SIZEOF___INT64 0
#endif
#define QSE_SIZEOF___INT128 0
#if defined(vax) || defined(__vax)
#define QSE_SIZEOF_VOID_P 4
#elif defined(alpha) || defined(__alpha)
#if __INITIAL_POINTER_SIZE==64
#pragma pointer_size 64
#define QSE_SIZEOF_VOID_P 8
#elif __INITIAL_POINTER_SIZE==32
#pragma pointer_size 32
#define QSE_SIZEOF_VOID_P 4
#elif __INITIAL_POINTER_SIZE==0
#define QSE_SIZEOF_VOID_P 4
#else
#error "unsupported initial pointer size"
#endif
#elif defined(ia64) || defined(__ia64)
#if __INITIAL_POINTER_SIZE==64
#pragma pointer_size 64
#define QSE_SIZEOF_VOID_P 8
#elif __INITIAL_POINTER_SIZE==32
#pragma pointer_size 32
#define QSE_SIZEOF_VOID_P 4
#elif __INITIAL_POINTER_SIZE==0
#define QSE_SIZEOF_VOID_P 4
#else
#error "unsupported initial pointer size"
#endif
#else
#error "unsupported architecture"
#endif
#define QSE_SIZEOF_FLOAT 4
#define QSE_SIZEOF_DOUBLE 8
#if defined(vax) || defined(__vax)
#define QSE_SIZEOF_LONG_DOUBLE 8
#elif defined(alpha) || defined(__alpha)
#define QSE_SIZEOF_LONG_DOUBLE 16
#elif defined(ia64) || defined(__ia64)
#define QSE_SIZEOF_LONG_DOUBLE 16
#else
#define QSE_SIZEOF_LONG_DOUBLE 0
#endif
#define QSE_SIZEOF_WCHAR_T 4
#define QSE_CHAR_IS_WCHAR
#if defined(vax) || defined(__vax)
# define QSE_SIZEOF_OFF_T 4
#elif defined(_LARGEFILE)
# define QSE_SIZEOF_OFF_T 8
#else
# define QSE_SIZEOF_OFF_T 4
#endif
#define QSE_SIZEOF_OFF64_T 0
#define QSE_SIZEOF_MBSTATE_T 24
#define QSE_MBLEN_MAX 8
/* these two have only to be large enough */
#define QSE_SIZEOF_STRUCT_SOCKADDR_IN 32
#define QSE_SIZEOF_STRUCT_SOCKADDR_IN6 64
#define QSE_SIZEOF_SOCKLEN_T 4
#if !defined(QSE_CHAR_IS_WCHAR) && !defined(QSE_CHAR_IS_MCHAR)
# define QSE_CHAR_IS_WCHAR 1
#endif
#undef QSE_ENABLE_BUNDLED_UNICODE
#define QSE_ENABLE_BUNDLED_UNICODE 1
#include <qse/conf-inf.h>

1225
include/qse/config.h.in Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,10 @@
pkgincludedir = $(includedir)/qse/cry
pkginclude_HEADERS = \
blowfish.h \
hmac.h \
kseed.h \
md5.h \
sha1.h \
sha2.h

611
include/qse/cry/Makefile.in Normal file
View File

@@ -0,0 +1,611 @@
# Makefile.in generated by automake 1.16.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = include/qse/cry
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_sign.m4 \
$(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/ax_cxx_namespace.m4 \
$(top_srcdir)/m4/ax_lib_mysql.m4 $(top_srcdir)/m4/ax_numval.m4 \
$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/m4/lx_find_mpi.m4 \
$(top_srcdir)/m4/qse_try_cflags.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(pkginclude_HEADERS) \
$(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/include/qse/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(pkgincludedir)"
HEADERS = $(pkginclude_HEADERS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
pkgincludedir = $(includedir)/qse/cry
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BUILD_MODE = @BUILD_MODE@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DL_LIBS = @DL_LIBS@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
HAVE_CXX = @HAVE_CXX@
HAVE_CXX11 = @HAVE_CXX11@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBM = @LIBM@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBTOOL_DEPS = @LIBTOOL_DEPS@
LIPO = @LIPO@
LN_S = @LN_S@
LTDL_LIBS = @LTDL_LIBS@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
MPICC = @MPICC@
MPI_CFLAGS = @MPI_CFLAGS@
MPI_CLDFLAGS = @MPI_CLDFLAGS@
MYSQL_CFLAGS = @MYSQL_CFLAGS@
MYSQL_CONFIG = @MYSQL_CONFIG@
MYSQL_LDFLAGS = @MYSQL_LDFLAGS@
MYSQL_LIBS = @MYSQL_LIBS@
MYSQL_VERSION = @MYSQL_VERSION@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
PACKAGE_VERSION_PATCH = @PACKAGE_VERSION_PATCH@
PATH_SEPARATOR = @PATH_SEPARATOR@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
QSE_PROJECT_AUTHOR = @QSE_PROJECT_AUTHOR@
QSE_PROJECT_URL = @QSE_PROJECT_URL@
QUADMATH_LIBS = @QUADMATH_LIBS@
RANLIB = @RANLIB@
RM = @RM@
RMDIR = @RMDIR@
SED = @SED@
SENDFILE_LIBS = @SENDFILE_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SOCKET_LIBS = @SOCKET_LIBS@
SSL_LIBS = @SSL_LIBS@
STRIP = @STRIP@
TRUE = @TRUE@
UCI_LIBS = @UCI_LIBS@
UNICOWS_LIBS = @UNICOWS_LIBS@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
ax_pthread_config = @ax_pthread_config@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
pkginclude_HEADERS = \
blowfish.h \
hmac.h \
kseed.h \
md5.h \
sha1.h \
sha2.h
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/qse/cry/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign include/qse/cry/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-pkgincludeHEADERS: $(pkginclude_HEADERS)
@$(NORMAL_INSTALL)
@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \
$(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \
$(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \
done
uninstall-pkgincludeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir)
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(pkgincludedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-pkgincludeHEADERS
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-pkgincludeHEADERS
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libtool cscopelist-am ctags ctags-am distclean \
distclean-generic distclean-libtool distclean-tags distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-pdf \
install-pdf-am install-pkgincludeHEADERS install-ps \
install-ps-am install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
ps ps-am tags tags-am uninstall uninstall-am \
uninstall-pkgincludeHEADERS
.PRECIOUS: Makefile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@@ -0,0 +1,90 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CRY_BLOWFISH_H_
#define _QSE_CRY_BLOWFISH_H_
#include <qse/types.h>
#include <qse/macros.h>
#define QSE_BLOWFISH_NUM_SUBKEYS 18
#define QSE_BLOWFISH_NUM_S_BOXES 4
#define QSE_BLOWFISH_NUM_ENTRIES 256
#define QSE_BLOWFISH_MIN_KEY_LEN 4 /* bytes - 32 bits */
#define QSE_BLOWFISH_MAX_KEY_LEN 56 /* bytes - 448 bits */
#define QSE_BLOWFISH_BLOCK_SIZE 8 /* bytes */
struct qse_blowfish_t
{
qse_uint32_t PA[QSE_BLOWFISH_NUM_SUBKEYS];
qse_uint32_t SB[QSE_BLOWFISH_NUM_S_BOXES][QSE_BLOWFISH_NUM_ENTRIES];
};
typedef struct qse_blowfish_t qse_blowfish_t;
typedef qse_uint8_t (qse_blowfish_block_t)[QSE_BLOWFISH_BLOCK_SIZE];
#ifdef __cplusplus
extern "C" {
#endif
QSE_EXPORT void qse_blowfish_initialize (
qse_blowfish_t* bf,
const void* keyptr,
qse_size_t keylen
);
QSE_EXPORT void qse_blowfish_encrypt_block (
qse_blowfish_t* bf,
qse_blowfish_block_t* blk
);
QSE_EXPORT void qse_blowfish_decrypt_block (
qse_blowfish_t* bf,
qse_blowfish_block_t* blk
);
/*
QSE_EXPORT void qse_blowfish_encrypt (
qse_blowfish_t* bf,
void* data,
qse_size_t len
);
QSE_EXPORT void qse_blowfish_decrypt (
qse_blowfish_t* bf,
void* data,
qse_size_t len
);
*/
#ifdef __cplusplus
}
#endif
#endif

158
include/qse/cry/hmac.h Normal file
View File

@@ -0,0 +1,158 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CRY_HMAC_H_
#define _QSE_CRY_HMAC_H_
#include <qse/cry/md5.h>
#include <qse/cry/sha1.h>
#include <qse/cry/sha2.h>
#define QSE_HMAC_MAX_DIGEST_LEN QSE_SHA512_DIGEST_LEN
#define QSE_HMAC_MAX_BLOCK_LEN QSE_SHA512_BLOCK_LEN
enum qse_hmac_sha_type_t
{
QSE_HMAC_MD5,
QSE_HMAC_SHA1,
QSE_HMAC_SHA256,
QSE_HMAC_SHA384,
QSE_HMAC_SHA512
};
typedef enum qse_hmac_sha_type_t qse_hmac_sha_type_t;
union qse_hmac_sha_t
{
qse_md5_t md5;
qse_sha1_t sha1;
qse_sha256_t sha256;
qse_sha384_t sha384;
qse_sha512_t sha512;
};
typedef union qse_hmac_sha_t qse_hmac_sha_t;
struct qse_hmac_t
{
qse_hmac_sha_type_t sha_type;
qse_size_t digest_size;
qse_size_t block_size;
qse_hmac_sha_t sha;
qse_uint8_t k_opad[QSE_HMAC_MAX_BLOCK_LEN];
};
typedef struct qse_hmac_t qse_hmac_t;
#if defined(__cplusplus)
extern "C" {
#endif
void qse_hmac_initialize (
qse_hmac_t* ctx,
qse_hmac_sha_type_t sha_type,
const qse_uint8_t* key,
qse_size_t key_len
);
void qse_hmac_update (
qse_hmac_t* ctx,
const qse_uint8_t* data,
qse_size_t len
);
#define qse_hmac_upatex qse_hmac_upate
qse_size_t qse_hmac_digest (
qse_hmac_t* ctx,
qse_uint8_t* digest,
qse_size_t size
);
qse_size_t qse_get_hmac_digest_size (
qse_hmac_sha_type_t sha_type
);
qse_size_t qse_get_hmac_block_size (
qse_hmac_sha_type_t sha_type
);
/* given an array of pointer and length pairs, it creates a string
* prefixed with hmac followed by the pair values encoded in hexdecimal
* digits seperated by a dash
*/
qse_mchar_t* qse_encode_hmacmbs (
qse_hmac_sha_type_t sha_type,
const qse_uint8_t* keyptr,
qse_size_t keylen,
qse_xptl_t* data,
qse_size_t count,
qse_mmgr_t* mmgr
);
qse_xptl_t* qse_decode_hmacmbs (
qse_hmac_sha_type_t sha_type,
const qse_uint8_t* keyptr,
qse_size_t keylen,
const qse_mchar_t* hmacmbs,
qse_size_t* count,
qse_mmgr_t* mmgr
);
qse_wchar_t* qse_encode_hmacwcs (
qse_hmac_sha_type_t sha_type,
const qse_uint8_t* keyptr,
qse_size_t keylen,
qse_xptl_t* data,
qse_size_t count,
qse_mmgr_t* mmgr
);
qse_xptl_t* qse_decode_hmacwcs (
qse_hmac_sha_type_t sha_type,
const qse_uint8_t* keyptr,
qse_size_t keylen,
const qse_wchar_t* hmacwcs,
qse_size_t* count,
qse_mmgr_t* mmgr
);
#if defined(QSE_CHAR_IS_MCHAR)
# define qse_encode_hmacstr qse_encode_hmacmbs
# define qse_decode_hmacstr qse_decode_hmacmbs
#else
# define qse_encode_hmacstr qse_encode_hmacwcs
# define qse_decode_hmacstr qse_decode_hmacwcs
#endif
#if defined(__cplusplus)
}
#endif
#endif

87
include/qse/cry/kseed.h Normal file
View File

@@ -0,0 +1,87 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CRY_KSEED_H_
#define _QSE_CRY_KSEED_H_
#include <qse/types.h>
#include <qse/macros.h>
#define QSE_KSEED_NUM_S_BOXES 4
#define QSE_KSEED_NUM_ENTRIES 256
#define QSE_KSEED_MIN_KEY_LEN 16 /* bytes - 128 bits */
#define QSE_KSEED_MAX_KEY_LEN 16 /* bytes - 128 bits */
#define QSE_KSEED_BLOCK_SIZE 16 /* bytes */
struct qse_kseed_t
{
qse_uint32_t KD[32];
};
typedef struct qse_kseed_t qse_kseed_t;
typedef qse_uint8_t (qse_kseed_block_t)[QSE_KSEED_BLOCK_SIZE];
#ifdef __cplusplus
extern "C" {
#endif
QSE_EXPORT void qse_kseed_initialize (
qse_kseed_t* ks,
const void* key,
qse_size_t len
);
QSE_EXPORT void qse_kseed_encrypt_block (
qse_kseed_t* ks,
qse_kseed_block_t* blk
);
QSE_EXPORT void qse_kseed_decrypt_block (
qse_kseed_t* ks,
qse_kseed_block_t* blk
);
/*
QSE_EXPORT void qse_kseed_encrypt (
qse_kseed_t* ks,
void* data,
qse_size_t len
);
QSE_EXPORT void qse_kseed_decrypt (
qse_kseed_t* ks,
void* data,
qse_size_t len
);
*/
#ifdef __cplusplus
}
#endif
#endif

74
include/qse/cry/md5.h Normal file
View File

@@ -0,0 +1,74 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CRY_MD5_H_
#define _QSE_CRY_MD5_H_
#include <qse/types.h>
#include <qse/macros.h>
#define QSE_MD5_DIGEST_LEN (16)
#define QSE_MD5_BLOCK_LEN (64)
struct qse_md5_t
{
qse_uint32_t count[2];
qse_uint32_t state[4];
qse_uint8_t buffer[QSE_MD5_BLOCK_LEN];
};
typedef struct qse_md5_t qse_md5_t;
#ifdef __cplusplus
extern "C" {
#endif
QSE_EXPORT void qse_md5_initialize (
qse_md5_t* md5
);
QSE_EXPORT void qse_md5_update (
qse_md5_t* md5,
const void* data,
qse_uint32_t len
);
QSE_EXPORT void qse_md5_updatex (
qse_md5_t* md5,
const void* data,
qse_size_t len
);
QSE_EXPORT qse_size_t qse_md5_digest (
qse_md5_t* md5,
void* digest,
qse_size_t size
);
#ifdef __cplusplus
}
#endif
#endif

75
include/qse/cry/sha1.h Normal file
View File

@@ -0,0 +1,75 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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 _QSE_CRY_SHA1_H_
#define _QSE_CRY_SHA1_H_
#include <qse/types.h>
#include <qse/macros.h>
#define QSE_SHA1_DIGEST_LEN (20)
#define QSE_SHA1_BLOCK_LEN (64)
struct qse_sha1_t
{
qse_uint32_t state[5];
qse_uint32_t count[2];
qse_uint8_t buffer[QSE_SHA1_BLOCK_LEN];
};
typedef struct qse_sha1_t qse_sha1_t;
#ifdef __cplusplus
extern "C" {
#endif
QSE_EXPORT void qse_sha1_initialize (
qse_sha1_t* ctx
);
QSE_EXPORT void qse_sha1_update (
qse_sha1_t* sha1,
const void* data,
qse_uint32_t len
);
QSE_EXPORT void qse_sha1_updatex (
qse_sha1_t* sha1,
const void* data,
qse_size_t len
);
QSE_EXPORT qse_size_t qse_sha1_digest (
qse_sha1_t* sha1,
void* digest,
qse_size_t size
);
#ifdef __cplusplus
}
#endif
#endif /* SHA1_H */

158
include/qse/cry/sha2.h Normal file
View File

@@ -0,0 +1,158 @@
/*
* $Id$
*
Copyright (c) 2006-2019 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.
*/
/*
* FILE: sha2.h
* AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/
*
* Copyright (c) 2000-2001, Aaron D. Gifford
* 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.
* 3. Neither the name of the copyright holder nor the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``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 OR CONTRIBUTOR(S) 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.
*
* $Id: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $
*/
#ifndef _QSE_CRY_SHA2_H_
#define _QSE_CRY_SHA2_H_
#include <qse/types.h>
#include <qse/macros.h>
#define QSE_SHA256_BLOCK_LEN (64)
#define QSE_SHA256_DIGEST_LEN (32)
#define QSE_SHA384_BLOCK_LEN (128)
#define QSE_SHA384_DIGEST_LEN (48)
#define QSE_SHA512_BLOCK_LEN (128)
#define QSE_SHA512_DIGEST_LEN (64)
struct qse_sha256_t
{
qse_uint32_t state[8];
qse_uint64_t bitcount;
qse_uint8_t buffer[QSE_SHA256_BLOCK_LEN];
};
typedef struct qse_sha256_t qse_sha256_t;
struct qse_sha512_t
{
qse_uint64_t state[8];
qse_uint64_t bitcount[2];
qse_uint8_t buffer[QSE_SHA512_BLOCK_LEN];
};
typedef struct qse_sha512_t qse_sha512_t;
typedef qse_sha512_t qse_sha384_t;
#if defined(__cplusplus)
extern "C" {
#endif
QSE_EXPORT void qse_sha256_initialize (
qse_sha256_t* ctx
);
QSE_EXPORT void qse_sha256_update (
qse_sha256_t* ctx,
const qse_uint8_t* data,
qse_size_t len
);
#define qse_sha256_updatex qse_sha256_update
QSE_EXPORT qse_size_t qse_sha256_digest (
qse_sha256_t* ctx,
qse_uint8_t* digest,
qse_size_t size
);
QSE_EXPORT void qse_sha384_initialize (
qse_sha384_t* ctx
);
QSE_EXPORT void qse_sha384_update (
qse_sha384_t* ctx,
const qse_uint8_t* data,
qse_size_t len
);
#define qse_sha384_updatex qse_sha384_update
QSE_EXPORT qse_size_t qse_sha384_digest (
qse_sha384_t* ctx,
qse_uint8_t* digest,
qse_size_t size
);
QSE_EXPORT void qse_sha512_initialize (
qse_sha512_t* ctx
);
QSE_EXPORT void qse_sha512_update (
qse_sha512_t* ctx,
const qse_uint8_t* data,
qse_size_t len
);
#define qse_sha512_updatex qse_sha512_update
QSE_EXPORT qse_size_t qse_sha512_digest (
qse_sha512_t* ctx,
qse_uint8_t* digest,
qse_size_t size
);
#if defined(__cplusplus)
}
#endif
#endif

View File

@@ -0,0 +1,7 @@
pkgincludedir = $(includedir)/qse/dhcp
pkginclude_HEADERS = \
dhcpmsg.h \
dhcp4msg.h \
dhcp6msg.h

View File

@@ -0,0 +1,608 @@
# Makefile.in generated by automake 1.16.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = include/qse/dhcp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_sign.m4 \
$(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/ax_cxx_namespace.m4 \
$(top_srcdir)/m4/ax_lib_mysql.m4 $(top_srcdir)/m4/ax_numval.m4 \
$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/m4/lx_find_mpi.m4 \
$(top_srcdir)/m4/qse_try_cflags.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(pkginclude_HEADERS) \
$(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/include/qse/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(pkgincludedir)"
HEADERS = $(pkginclude_HEADERS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
pkgincludedir = $(includedir)/qse/dhcp
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BUILD_MODE = @BUILD_MODE@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DL_LIBS = @DL_LIBS@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
HAVE_CXX = @HAVE_CXX@
HAVE_CXX11 = @HAVE_CXX11@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBM = @LIBM@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBTOOL_DEPS = @LIBTOOL_DEPS@
LIPO = @LIPO@
LN_S = @LN_S@
LTDL_LIBS = @LTDL_LIBS@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
MPICC = @MPICC@
MPI_CFLAGS = @MPI_CFLAGS@
MPI_CLDFLAGS = @MPI_CLDFLAGS@
MYSQL_CFLAGS = @MYSQL_CFLAGS@
MYSQL_CONFIG = @MYSQL_CONFIG@
MYSQL_LDFLAGS = @MYSQL_LDFLAGS@
MYSQL_LIBS = @MYSQL_LIBS@
MYSQL_VERSION = @MYSQL_VERSION@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
PACKAGE_VERSION_PATCH = @PACKAGE_VERSION_PATCH@
PATH_SEPARATOR = @PATH_SEPARATOR@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
QSE_PROJECT_AUTHOR = @QSE_PROJECT_AUTHOR@
QSE_PROJECT_URL = @QSE_PROJECT_URL@
QUADMATH_LIBS = @QUADMATH_LIBS@
RANLIB = @RANLIB@
RM = @RM@
RMDIR = @RMDIR@
SED = @SED@
SENDFILE_LIBS = @SENDFILE_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SOCKET_LIBS = @SOCKET_LIBS@
SSL_LIBS = @SSL_LIBS@
STRIP = @STRIP@
TRUE = @TRUE@
UCI_LIBS = @UCI_LIBS@
UNICOWS_LIBS = @UNICOWS_LIBS@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
ax_pthread_config = @ax_pthread_config@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
pkginclude_HEADERS = \
dhcpmsg.h \
dhcp4msg.h \
dhcp6msg.h
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/qse/dhcp/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign include/qse/dhcp/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-pkgincludeHEADERS: $(pkginclude_HEADERS)
@$(NORMAL_INSTALL)
@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \
$(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \
$(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \
done
uninstall-pkgincludeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir)
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(pkgincludedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-pkgincludeHEADERS
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-pkgincludeHEADERS
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libtool cscopelist-am ctags ctags-am distclean \
distclean-generic distclean-libtool distclean-tags distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-pdf \
install-pdf-am install-pkgincludeHEADERS install-ps \
install-ps-am install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
ps ps-am tags tags-am uninstall uninstall-am \
uninstall-pkgincludeHEADERS
.PRECIOUS: Makefile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

217
include/qse/dhcp/dhcp4msg.h Normal file
View File

@@ -0,0 +1,217 @@
#ifndef _QSE_DHCP_DHCP4MSG_H_
#define _QSE_DHCP_DHCP4MSG_H_
#include <qse/types.h>
#include <qse/macros.h>
#define QSE_DHCP4_SERVER_PORT 67
#define QSE_DHCP4_CLIENT_PORT 68
#define QSE_DHCP4_MAGIC_COOKIE 0x63825363
/* operation code */
enum qse_dhcp4_op_t
{
QSE_DHCP4_OP_BOOTREQUEST = 1,
QSE_DHCP4_OP_BOOTREPLY = 2
};
enum qse_dhcp4_htype_t
{
QSE_DHCP4_HTYPE_ETHERNET = 1,
QSE_DHCP4_HTYPE_IEEE802 = 6,
QSE_DHCP4_HTYPE_ARCNET = 7,
QSE_DHCP4_HTYPE_APPLETALK = 8,
QSE_DHCP4_HTYPE_HDLC = 17,
QSE_DHCP4_HTYPE_ATM = 19,
QSE_DHCP4_HTYPE_INFINIBAND = 32
};
/* option codes (partial) */
enum qse_dhcp4_opt_t
{
QSE_DHCP4_OPT_PADDING = 0x00,
QSE_DHCP4_OPT_SUBNET = 0x01,
QSE_DHCP4_OPT_TIME_OFFSET = 0x02,
QSE_DHCP4_OPT_ROUTER = 0x03,
QSE_DHCP4_OPT_TIME_SERVER = 0x04,
QSE_DHCP4_OPT_NAME_SERVER = 0x05,
QSE_DHCP4_OPT_DNS_SERVER = 0x06,
QSE_DHCP4_OPT_LOG_SERVER = 0x07,
QSE_DHCP4_OPT_COOKIE_SERVER = 0x08,
QSE_DHCP4_OPT_LPR_SERVER = 0x09,
QSE_DHCP4_OPT_HOST_NAME = 0x0c,
QSE_DHCP4_OPT_BOOT_SIZE = 0x0d,
QSE_DHCP4_OPT_DOMAIN_NAME = 0x0f,
QSE_DHCP4_OPT_SWAP_SERVER = 0x10,
QSE_DHCP4_OPT_ROOT_PATH = 0x11,
QSE_DHCP4_OPT_IP_TTL = 0x17,
QSE_DHCP4_OPT_MTU = 0x1a,
QSE_DHCP4_OPT_BROADCAST = 0x1c,
QSE_DHCP4_OPT_NTP_SERVER = 0x2a,
QSE_DHCP4_OPT_WINS_SERVER = 0x2c,
QSE_DHCP4_OPT_REQUESTED_IPADDR = 0x32,
QSE_DHCP4_OPT_LEASE_TIME = 0x33,
QSE_DHCP4_OPT_OVERLOAD = 0x34, /* overload sname or file */
QSE_DHCP4_OPT_MESSAGE_TYPE = 0x35,
QSE_DHCP4_OPT_SERVER_ID = 0x36,
QSE_DHCP4_OPT_PARAM_REQ = 0x37,
QSE_DHCP4_OPT_MESSAGE = 0x38,
QSE_DHCP4_OPT_MAX_SIZE = 0x39,
QSE_DHCP4_OPT_T1 = 0x3a,
QSE_DHCP4_OPT_T2 = 0x3b,
QSE_DHCP4_OPT_VENDOR = 0x3c,
QSE_DHCP4_OPT_CLIENT_ID = 0x3d,
QSE_DHCP4_OPT_RELAY = 0x52,
QSE_DHCP4_OPT_SUBNET_SELECTION = 0x76,
QSE_DHCP4_OPT_END = 0xFF
};
/* flags for QSE_DHCP4_OPT_OVERLOAD */
enum qse_dhcp4_opt_overload_t
{
QSE_DHCP4_OPT_OVERLOAD_FILE = (1 << 0),
QSE_DHCP4_OPT_OVERLOAD_SNAME = (1 << 1)
};
/* flags for QSE_DHCP4_OPT_OVERLOAD */
enum qse_dhcp4_opt_relay_t
{
QSE_DHCP4_OPT_RELAY_CIRCUIT_ID = 1,
QSE_DHCP4_OPT_RELAY_REMOTE_ID = 2
};
/* message type */
enum qse_dhcp4_msg_t
{
QSE_DHCP4_MSG_DISCOVER = 1,
QSE_DHCP4_MSG_OFFER = 2,
QSE_DHCP4_MSG_REQUEST = 3,
QSE_DHCP4_MSG_DECLINE = 4,
QSE_DHCP4_MSG_ACK = 5,
QSE_DHCP4_MSG_NAK = 6,
QSE_DHCP4_MSG_RELEASE = 7,
QSE_DHCP4_MSG_INFORM = 8,
/*QSE_DHCP4_MSG_RENEW = 9,*/
QSE_DHCP4_MSG_LEASE_QUERY = 10,
QSE_DHCP4_MSG_LEASE_UNASSIGNED = 11,
QSE_DHCP4_MSG_LEASE_UNKNOWN = 12,
QSE_DHCP4_MSG_LEASE_ACTIVE = 13,
QSE_DHCP4_MSG_BULK_LEASE_QUERY = 14,
QSE_DHCP4_MSG_LEASE_QUERY_DONE = 15
};
/* --------------------------------------------------- */
#include <qse/pack1.h>
/* --------------------------------------------------- */
struct qse_dhcp4_pkt_hdr_t
{
qse_uint8_t op;
qse_uint8_t htype;
qse_uint8_t hlen;
qse_uint8_t hops;
qse_uint32_t xid; /* transaction id */
qse_uint16_t secs; /* seconds elapsed */
qse_uint16_t flags; /* bootp flags */
qse_uint32_t ciaddr; /* client ip */
qse_uint32_t yiaddr; /* your ip */
qse_uint32_t siaddr; /* next server ip */
qse_uint32_t giaddr; /* relay agent ip */
qse_uint8_t chaddr[16]; /* client mac */
char sname[64]; /* server host name */
char file[128]; /* boot file name */
/* options are placed after the header.
* the first four bytes of the options compose a magic cookie
* 0x63 0x82 0x53 0x63 */
};
typedef struct qse_dhcp4_pkt_hdr_t qse_dhcp4_pkt_hdr_t;
struct qse_dhcp4_opt_hdr_t
{
qse_uint8_t code;
qse_uint8_t len;
};
typedef struct qse_dhcp4_opt_hdr_t qse_dhcp4_opt_hdr_t;
/* --------------------------------------------------- */
#include <qse/unpack.h>
/* --------------------------------------------------- */
typedef int (*qse_dhcp4_opt_walker_t) (qse_dhcp4_opt_hdr_t* opt);
struct qse_dhcp4_pktinf_t
{
qse_dhcp4_pkt_hdr_t* hdr;
qse_size_t len;
};
typedef struct qse_dhcp4_pktinf_t qse_dhcp4_pktinf_t;
struct qse_dhcp4_pktbuf_t
{
qse_dhcp4_pkt_hdr_t* hdr;
qse_size_t len;
qse_size_t capa;
};
typedef struct qse_dhcp4_pktbuf_t qse_dhcp4_pktbuf_t;
#ifdef __cplusplus
extern "C" {
#endif
QSE_EXPORT int qse_dhcp4_initialize_pktbuf (
qse_dhcp4_pktbuf_t* pkt,
void* buf,
qse_size_t capa
);
QSE_EXPORT int qse_dhcp4_add_option (
qse_dhcp4_pktbuf_t* pkt,
int code,
void* optr, /**< option data pointer */
qse_uint8_t olen /**< option data length */
);
QSE_EXPORT void qse_dhcp4_compact_options (
qse_dhcp4_pktbuf_t* pkt
);
#if 0
QSE_EXPORT int qse_dhcp4_add_options (
qse_dhcp4_pkt_hdr_t* pkt,
qse_size_t len,
qse_size_t max,
int code,
qse_uint8_t* optr, /* option data */
qse_uint8_t olen /* option length */
);
#endif
QSE_EXPORT int qse_dhcp4_walk_options (
const qse_dhcp4_pktinf_t* pkt,
qse_dhcp4_opt_walker_t walker
);
QSE_EXPORT qse_dhcp4_opt_hdr_t* qse_dhcp4_find_option (
const qse_dhcp4_pktinf_t* pkt,
int code
);
QSE_EXPORT qse_uint8_t* qse_dhcp4_get_relay_suboption (
const qse_uint8_t* ptr,
qse_uint8_t len,
int code,
qse_uint8_t* olen
);
#ifdef __cplusplus
}
#endif
#endif

100
include/qse/dhcp/dhcp6msg.h Normal file
View File

@@ -0,0 +1,100 @@
#ifndef _QSE_DHCP_DHCP6MSG_H_
#define _QSE_DHCP_DHCP6MSG_H_
#include <qse/types.h>
#include <qse/macros.h>
#define QSE_DHCP6_SERVER_PORT 547
#define QSE_DHCP6_CLIENT_PORT 546
#define QSE_DHCP6_HOP_COUNT_LIMIT 32
enum qse_dhcp6_msg_t
{
QSE_DHCP6_MSG_SOLICIT = 1,
QSE_DHCP6_MSG_ADVERTISE = 2,
QSE_DHCP6_MSG_REQUEST = 3,
QSE_DHCP6_MSG_CONFIRM = 4,
QSE_DHCP6_MSG_RENEW = 5,
QSE_DHCP6_MSG_REBIND = 6,
QSE_DHCP6_MSG_REPLY = 7,
QSE_DHCP6_MSG_RELEASE = 8,
QSE_DHCP6_MSG_DECLINE = 9,
QSE_DHCP6_MSG_RECONFIGURE = 10,
QSE_DHCP6_MSG_INFOREQ = 11,
QSE_DHCP6_MSG_RELAYFORW = 12,
QSE_DHCP6_MSG_RELAYREPL = 13,
};
typedef enum qse_dhcp6_msg_t qse_dhcp6_msg_t;
enum qse_dhcp6_opt_t
{
QSE_DHCP6_OPT_CLIENTID = 1,
QSE_DHCP6_OPT_SERVERID = 2,
QSE_DHCP6_OPT_IA_NA = 3,
QSE_DHCP6_OPT_IA_TA = 4,
QSE_DHCP6_OPT_IAADDR = 5,
QSE_DHCP6_OPT_PREFERENCE = 7,
QSE_DHCP6_OPT_ELAPSED_TIME = 8,
QSE_DHCP6_OPT_RELAY_MESSAGE = 9,
QSE_DHCP6_OPT_RAPID_COMMIT = 14,
QSE_DHCP6_OPT_USER_CLASS = 15,
QSE_DHCP6_OPT_VENDOR_CLASS = 16,
QSE_DHCP6_OPT_INTERFACE_ID = 18,
QSE_DHCP6_OPT_IA_PD = 25,
QSE_DHCP6_OPT_IAPREFIX = 26
};
typedef enum qse_dhcp6_opt_t qse_dhcp6_opt_t;
/* --------------------------------------------------- */
#include <qse/pack1.h>
/* --------------------------------------------------- */
struct qse_dhcp6_pkt_hdr_t
{
qse_uint8_t msgtype;
qse_uint8_t transid[3];
};
typedef struct qse_dhcp6_pkt_hdr_t qse_dhcp6_pkt_hdr_t;
struct qse_dhcp6_relay_hdr_t
{
qse_uint8_t msgtype; /* RELAY-FORW, RELAY-REPL */
qse_uint8_t hopcount;
qse_uint8_t linkaddr[16];
qse_uint8_t peeraddr[16];
};
typedef struct qse_dhcp6_relay_hdr_t qse_dhcp6_relay_hdr_t;
struct qse_dhcp6_opt_hdr_t
{
qse_uint16_t code;
qse_uint16_t len; /* length of option data, excludes the option header */
};
typedef struct qse_dhcp6_opt_hdr_t qse_dhcp6_opt_hdr_t;
/* --------------------------------------------------- */
#include <qse/unpack.h>
/* --------------------------------------------------- */
struct qse_dhcp6_pktinf_t
{
qse_dhcp6_pkt_hdr_t* hdr;
qse_size_t len;
};
typedef struct qse_dhcp6_pktinf_t qse_dhcp6_pktinf_t;
#ifdef __cplusplus
extern "C" {
#endif
QSE_EXPORT qse_dhcp6_opt_hdr_t* qse_dhcp6_find_option (
const qse_dhcp6_pktinf_t* pkt,
int code
);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,7 @@
#ifndef _QSE_DHCP_DHCPMSG_H_
#define _QSE_DHCP_DHCPMSG_H_
#include <qse/dhcp/dhcp4msg.h>
#include <qse/dhcp/dhcp6msg.h>
#endif

102
include/qse/hash.h Normal file
View File

@@ -0,0 +1,102 @@
/*
* $Id: types.h 560 2011-09-06 14:18:36Z hyunghwan.chung $
*
Copyright (c) 2006-2019 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 _QSE_HASH_H_
#define _QSE_HASH_H_
#include <qse/types.h>
#include <qse/macros.h>
#if (QSE_SIZEOF_SIZE_T == 4)
# define QSE_HASH_FNV_MAGIC_INIT (0x811c9dc5)
# define QSE_HASH_FNV_MAGIC_PRIME (0x01000193)
#elif (QSE_SIZEOF_SIZE_T == 8)
# define QSE_HASH_FNV_MAGIC_INIT (0xCBF29CE484222325)
# define QSE_HASH_FNV_MAGIC_PRIME (0x100000001B3l)
#elif (QSE_SIZEOF_SIZE_T == 16)
# define QSE_HASH_FNV_MAGIC_INIT (0x6C62272E07BB014262B821756295C58D)
# define QSE_HASH_FNV_MAGIC_PRIME (0x1000000000000000000013B)
#endif
#if defined(QSE_HASH_FNV_MAGIC_INIT)
/* FNV-1 hash */
# define QSE_HASH_INIT QSE_HASH_FNV_MAGIC_INIT
# define QSE_HASH_VALUE(hv,v) (((hv) ^ (v)) * QSE_HASH_FNV_MAGIC_PRIME)
#else
/* SDBM hash */
# define QSE_HASH_INIT 0
# define QSE_HASH_VALUE(hv,v) (((hv) << 6) + ((hv) << 16) - (hv) + (v))
#endif
#define QSE_HASH_VPTL(hv, ptr, len, type) do { \
hv = QSE_HASH_INIT; \
QSE_HASH_MORE_VPTL (hv, ptr, len, type); \
} while(0)
#define QSE_HASH_MORE_VPTL(hv, ptr, len, type) do { \
type* __qse_hash_more_vptl_p = (type*)(ptr); \
type* __qse_hash_more_vptl_q = (type*)__qse_hash_more_vptl_p + (len); \
while (__qse_hash_more_vptl_p < __qse_hash_more_vptl_q) \
{ \
hv = QSE_HASH_VALUE(hv, *__qse_hash_more_vptl_p); \
__qse_hash_more_vptl_p++; \
} \
} while(0)
#define QSE_HASH_VPTR(hv, ptr, type) do { \
hv = QSE_HASH_INIT; \
QSE_HASH_MORE_VPTR (hv, ptr, type); \
} while(0)
#define QSE_HASH_MORE_VPTR(hv, ptr, type) do { \
type* __qse_hash_more_vptr_p = (type*)(ptr); \
while (*__qse_hash_more_vptr_p) \
{ \
hv = QSE_HASH_VALUE(hv, *__qse_hash_more_vptr_p); \
__qse_hash_more_vptr_p++; \
} \
} while(0)
#define QSE_HASH_BYTES(hv, ptr, len) QSE_HASH_VPTL(hv, ptr, len, const qse_uint8_t)
#define QSE_HASH_MORE_BYTES(hv, ptr, len) QSE_HASH_MORE_VPTL(hv, ptr, len, const qse_uint8_t)
#define QSE_HASH_MCHARS(hv, ptr, len) QSE_HASH_VPTL(hv, ptr, len, const qse_mchar_t)
#define QSE_HASH_MORE_MCHARS(hv, ptr, len) QSE_HASH_MORE_VPTL(hv, ptr, len, const qse_mchar_t)
#define QSE_HASH_WCHARS(hv, ptr, len) QSE_HASH_VPTL(hv, ptr, len, const qse_wchar_t)
#define QSE_HASH_MORE_WCHARS(hv, ptr, len) QSE_HASH_MORE_VPTL(hv, ptr, len, const qse_wchar_t)
#define QSE_HASH_MBS(hv, ptr) QSE_HASH_VPTR(hv, ptr, const qse_mchar_t)
#define QSE_HASH_MORE_MBS(hv, ptr) QSE_HASH_MORE_VPTR(hv, ptr, const qse_mchar_t)
#define QSE_HASH_WCS(hv, ptr) QSE_HASH_VPTR(hv, ptr, const qse_wchar_t)
#define QSE_HASH_MORE_WCS(hv, ptr) QSE_HASH_MORE_VPTR(hv, ptr, const qse_wchar_t)
#endif

View File

@@ -0,0 +1,4 @@
pkgincludedir= $(includedir)/qse/http
pkginclude_HEADERS = http.h htre.h htrd.h httpd.h stdhttpd.h upxd.h

View File

@@ -0,0 +1,604 @@
# Makefile.in generated by automake 1.16.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = include/qse/http
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_sign.m4 \
$(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/ax_cxx_namespace.m4 \
$(top_srcdir)/m4/ax_lib_mysql.m4 $(top_srcdir)/m4/ax_numval.m4 \
$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/m4/lx_find_mpi.m4 \
$(top_srcdir)/m4/qse_try_cflags.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(pkginclude_HEADERS) \
$(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/include/qse/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(pkgincludedir)"
HEADERS = $(pkginclude_HEADERS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
pkgincludedir = $(includedir)/qse/http
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BUILD_MODE = @BUILD_MODE@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DL_LIBS = @DL_LIBS@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
HAVE_CXX = @HAVE_CXX@
HAVE_CXX11 = @HAVE_CXX11@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBM = @LIBM@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBTOOL_DEPS = @LIBTOOL_DEPS@
LIPO = @LIPO@
LN_S = @LN_S@
LTDL_LIBS = @LTDL_LIBS@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
MPICC = @MPICC@
MPI_CFLAGS = @MPI_CFLAGS@
MPI_CLDFLAGS = @MPI_CLDFLAGS@
MYSQL_CFLAGS = @MYSQL_CFLAGS@
MYSQL_CONFIG = @MYSQL_CONFIG@
MYSQL_LDFLAGS = @MYSQL_LDFLAGS@
MYSQL_LIBS = @MYSQL_LIBS@
MYSQL_VERSION = @MYSQL_VERSION@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
PACKAGE_VERSION_PATCH = @PACKAGE_VERSION_PATCH@
PATH_SEPARATOR = @PATH_SEPARATOR@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
QSE_PROJECT_AUTHOR = @QSE_PROJECT_AUTHOR@
QSE_PROJECT_URL = @QSE_PROJECT_URL@
QUADMATH_LIBS = @QUADMATH_LIBS@
RANLIB = @RANLIB@
RM = @RM@
RMDIR = @RMDIR@
SED = @SED@
SENDFILE_LIBS = @SENDFILE_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SOCKET_LIBS = @SOCKET_LIBS@
SSL_LIBS = @SSL_LIBS@
STRIP = @STRIP@
TRUE = @TRUE@
UCI_LIBS = @UCI_LIBS@
UNICOWS_LIBS = @UNICOWS_LIBS@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
ax_pthread_config = @ax_pthread_config@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
pkginclude_HEADERS = http.h htre.h htrd.h httpd.h stdhttpd.h upxd.h
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/qse/http/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign include/qse/http/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-pkgincludeHEADERS: $(pkginclude_HEADERS)
@$(NORMAL_INSTALL)
@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \
$(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \
$(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \
done
uninstall-pkgincludeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir)
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(pkgincludedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-pkgincludeHEADERS
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-pkgincludeHEADERS
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libtool cscopelist-am ctags ctags-am distclean \
distclean-generic distclean-libtool distclean-tags distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-pdf \
install-pdf-am install-pkgincludeHEADERS install-ps \
install-ps-am install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
ps ps-am tags tags-am uninstall uninstall-am \
uninstall-pkgincludeHEADERS
.PRECIOUS: Makefile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

Some files were not shown because too many files have changed in this diff Show More