added initial hcl files

This commit is contained in:
2016-09-28 14:40:37 +00:00
commit 94e690004d
53 changed files with 66342 additions and 0 deletions

69
lib/Makefile.am Normal file
View File

@ -0,0 +1,69 @@
AUTOMAKE_OPTIONS = nostdinc
CPPFLAGS_ALL_COMMON = \
-I$(abs_builddir) \
-I$(abs_srcdir) \
-I$(includedir)
LDFLAGS_ALL_COMMON = -L$(abs_builddir) -L$(libdir)
##################################################
# MAIN LIBRARY
##################################################
CPPFLAGS_LIB_COMMON = $(CPPFLAGS_ALL_COMMON)
LDFLAGS_LIB_COMMON = $(LDFLAGS_ALL_COMMON) -version-info 1:0:0 -no-undefined
LIBADD_LIB_COMMON = $(LIBM)
pkgincludedir = $(includedir)
pkglibdir = $(libdir)
pkginclude_HEADERS = \
hcl-cfg.h \
hcl-cmn.h \
hcl-rbt.h \
hcl-utl.h \
hcl.h
pkglib_LTLIBRARIES = libhcl.la
libhcl_la_SOURCES = \
hcl-prv.h \
logfmtv.h \
bigint.c \
comp.c \
debug.c \
decode.c \
dic.c \
exec.c \
gc.c \
hcl.c \
heap.c \
logfmt.c \
obj.c \
print.c \
rbt.c \
read.c \
sym.c \
utf8.c \
utl.c
libhcl_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
libhcl_la_LDFLAGS = $(LDFLAGS_LIB_COMMON)
libhcl_la_LIBADD = $(LIBADD_LIB_COMMON)
bin_PROGRAMS = hcl
hcl_SOURCES = main.c
hcl_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
hcl_LDFLAGS = $(LDFLAGS_LIB_COMMON)
hcl_LDADD = $(LIBADD_LIB_COMMON) -lhcl #-ldyncall_s
install-data-hook:
@echo "#ifndef _HCL_CFG_H_" > "$(DESTDIR)$(pkgincludedir)/hcl-cfg.h"
@echo "#define _HCL_CFG_H_" >> "$(DESTDIR)$(pkgincludedir)/hcl-cfg.h"
@$(EGREP) "#define[ ]+HCL_" "$(abs_builddir)/hcl-cfg.h" >> "$(DESTDIR)$(pkgincludedir)/hcl-cfg.h"
@echo "#endif" >> "$(DESTDIR)$(pkgincludedir)/hcl-cfg.h"
@rm -f "$(DESTDIR)$(pkgincludedir)/hcl-cfg.h.in"
@$(SED) 's|/\*#define HCL_HAVE_CFG_H\*/|#define HCL_HAVE_CFG_H|' "$(srcdir)/hcl-cmn.h" > "$(DESTDIR)$(pkgincludedir)/hcl-cmn.h"
uninstall-hook:
@rm -f "$(DESTDIR)$(pkgincludedir)/hcl-cfg.h"

987
lib/Makefile.in Normal file
View File

@ -0,0 +1,987 @@
# Makefile.in generated by automake 1.14.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 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 = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
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@
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@
bin_PROGRAMS = hcl$(EXEEXT)
subdir = lib
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(srcdir)/hcl-cfg.h.in $(top_srcdir)/ac/depcomp \
$(pkginclude_HEADERS)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_namespace.m4 \
$(top_srcdir)/m4/ax_numval.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)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = hcl-cfg.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
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)$(pkglibdir)" "$(DESTDIR)$(bindir)" \
"$(DESTDIR)$(pkgincludedir)"
LTLIBRARIES = $(pkglib_LTLIBRARIES)
am__DEPENDENCIES_1 =
am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
libhcl_la_DEPENDENCIES = $(am__DEPENDENCIES_2)
am_libhcl_la_OBJECTS = libhcl_la-bigint.lo libhcl_la-comp.lo \
libhcl_la-debug.lo libhcl_la-decode.lo libhcl_la-dic.lo \
libhcl_la-exec.lo libhcl_la-gc.lo libhcl_la-hcl.lo \
libhcl_la-heap.lo libhcl_la-logfmt.lo libhcl_la-obj.lo \
libhcl_la-print.lo libhcl_la-rbt.lo libhcl_la-read.lo \
libhcl_la-sym.lo libhcl_la-utf8.lo libhcl_la-utl.lo
libhcl_la_OBJECTS = $(am_libhcl_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
libhcl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(libhcl_la_LDFLAGS) $(LDFLAGS) -o $@
PROGRAMS = $(bin_PROGRAMS)
am_hcl_OBJECTS = hcl-main.$(OBJEXT)
hcl_OBJECTS = $(am_hcl_OBJECTS)
hcl_DEPENDENCIES = $(am__DEPENDENCIES_2)
hcl_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(hcl_LDFLAGS) $(LDFLAGS) -o $@
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 =
DEFAULT_INCLUDES =
depcomp = $(SHELL) $(top_srcdir)/ac/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(libhcl_la_SOURCES) $(hcl_SOURCES)
DIST_SOURCES = $(libhcl_la_SOURCES) $(hcl_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
HEADERS = $(pkginclude_HEADERS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
$(LISP)hcl-cfg.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
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
pkgincludedir = $(includedir)
pkglibdir = $(libdir)
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@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
HAVE_CXX = @HAVE_CXX@
HCL_PROJECT_AUTHOR = @HCL_PROJECT_AUTHOR@
HCL_PROJECT_URL = @HCL_PROJECT_URL@
HCL_SIZEOF_CHAR = @HCL_SIZEOF_CHAR@
HCL_SIZEOF_DOUBLE = @HCL_SIZEOF_DOUBLE@
HCL_SIZEOF_FLOAT = @HCL_SIZEOF_FLOAT@
HCL_SIZEOF_INT = @HCL_SIZEOF_INT@
HCL_SIZEOF_LONG = @HCL_SIZEOF_LONG@
HCL_SIZEOF_LONG_DOUBLE = @HCL_SIZEOF_LONG_DOUBLE@
HCL_SIZEOF_LONG_LONG = @HCL_SIZEOF_LONG_LONG@
HCL_SIZEOF_OFF64_T = @HCL_SIZEOF_OFF64_T@
HCL_SIZEOF_OFF_T = @HCL_SIZEOF_OFF_T@
HCL_SIZEOF_SHORT = @HCL_SIZEOF_SHORT@
HCL_SIZEOF_VOID_P = @HCL_SIZEOF_VOID_P@
HCL_SIZEOF_WCHAR_T = @HCL_SIZEOF_WCHAR_T@
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@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
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@
QUADMATH_LIBS = @QUADMATH_LIBS@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
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@
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@
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 = nostdinc
CPPFLAGS_ALL_COMMON = \
-I$(abs_builddir) \
-I$(abs_srcdir) \
-I$(includedir)
LDFLAGS_ALL_COMMON = -L$(abs_builddir) -L$(libdir)
##################################################
# MAIN LIBRARY
##################################################
CPPFLAGS_LIB_COMMON = $(CPPFLAGS_ALL_COMMON)
LDFLAGS_LIB_COMMON = $(LDFLAGS_ALL_COMMON) -version-info 1:0:0 -no-undefined
LIBADD_LIB_COMMON = $(LIBM)
pkginclude_HEADERS = \
hcl-cfg.h \
hcl-cmn.h \
hcl-rbt.h \
hcl-utl.h \
hcl.h
pkglib_LTLIBRARIES = libhcl.la
libhcl_la_SOURCES = \
hcl-prv.h \
logfmtv.h \
bigint.c \
comp.c \
debug.c \
decode.c \
dic.c \
exec.c \
gc.c \
hcl.c \
heap.c \
logfmt.c \
obj.c \
print.c \
rbt.c \
read.c \
sym.c \
utf8.c \
utl.c
libhcl_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
libhcl_la_LDFLAGS = $(LDFLAGS_LIB_COMMON)
libhcl_la_LIBADD = $(LIBADD_LIB_COMMON)
hcl_SOURCES = main.c
hcl_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
hcl_LDFLAGS = $(LDFLAGS_LIB_COMMON)
hcl_LDADD = $(LIBADD_LIB_COMMON) -lhcl #-ldyncall_s
all: hcl-cfg.h
$(MAKE) $(AM_MAKEFLAGS) all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(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 lib/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign lib/Makefile
.PRECIOUS: 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__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
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):
hcl-cfg.h: stamp-h1
@test -f $@ || rm -f stamp-h1
@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
stamp-h1: $(srcdir)/hcl-cfg.h.in $(top_builddir)/config.status
@rm -f stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status lib/hcl-cfg.h
$(srcdir)/hcl-cfg.h.in: $(am__configure_deps)
($(am__cd) $(top_srcdir) && $(AUTOHEADER))
rm -f stamp-h1
touch $@
distclean-hdr:
-rm -f hcl-cfg.h stamp-h1
install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES)
@$(NORMAL_INSTALL)
@list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
list2="$$list2 $$p"; \
else :; fi; \
done; \
test -z "$$list2" || { \
echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \
}
uninstall-pkglibLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \
done
clean-pkglibLTLIBRARIES:
-test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES)
@list='$(pkglib_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
libhcl.la: $(libhcl_la_OBJECTS) $(libhcl_la_DEPENDENCIES) $(EXTRA_libhcl_la_DEPENDENCIES)
$(AM_V_CCLD)$(libhcl_la_LINK) -rpath $(pkglibdir) $(libhcl_la_OBJECTS) $(libhcl_la_LIBADD) $(LIBS)
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
$(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
fi; \
for p in $$list; do echo "$$p $$p"; done | \
sed 's/$(EXEEXT)$$//' | \
while read p p1; do if test -f $$p \
|| test -f $$p1 \
; then echo "$$p"; echo "$$p"; else :; fi; \
done | \
sed -e 'p;s,.*/,,;n;h' \
-e 's|.*|.|' \
-e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
sed 'N;N;N;s,\n, ,g' | \
$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
{ d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
if ($$2 == $$4) files[d] = files[d] " " $$1; \
else { print "f", $$3 "/" $$4, $$1; } } \
END { for (d in files) print "f", d, files[d] }' | \
while read type dir files; do \
if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
test -z "$$files" || { \
echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
$(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
} \
; done
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
files=`for p in $$list; do echo "$$p"; done | \
sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
-e 's/$$/$(EXEEXT)/' \
`; \
test -n "$$list" || exit 0; \
echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(bindir)" && rm -f $$files
clean-binPROGRAMS:
@list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
echo " rm -f" $$list; \
rm -f $$list || exit $$?; \
test -n "$(EXEEXT)" || exit 0; \
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
hcl$(EXEEXT): $(hcl_OBJECTS) $(hcl_DEPENDENCIES) $(EXTRA_hcl_DEPENDENCIES)
@rm -f hcl$(EXEEXT)
$(AM_V_CCLD)$(hcl_LINK) $(hcl_OBJECTS) $(hcl_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hcl-main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-bigint.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-comp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-debug.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-decode.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-dic.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-exec.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-gc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-hcl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-heap.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-logfmt.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-obj.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-print.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-rbt.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-read.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-sym.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-utf8.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhcl_la-utl.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
libhcl_la-bigint.lo: bigint.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhcl_la-bigint.lo -MD -MP -MF $(DEPDIR)/libhcl_la-bigint.Tpo -c -o libhcl_la-bigint.lo `test -f 'bigint.c' || echo '$(srcdir)/'`bigint.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhcl_la-bigint.Tpo $(DEPDIR)/libhcl_la-bigint.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bigint.c' object='libhcl_la-bigint.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhcl_la-bigint.lo `test -f 'bigint.c' || echo '$(srcdir)/'`bigint.c
libhcl_la-comp.lo: comp.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhcl_la-comp.lo -MD -MP -MF $(DEPDIR)/libhcl_la-comp.Tpo -c -o libhcl_la-comp.lo `test -f 'comp.c' || echo '$(srcdir)/'`comp.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhcl_la-comp.Tpo $(DEPDIR)/libhcl_la-comp.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='comp.c' object='libhcl_la-comp.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhcl_la-comp.lo `test -f 'comp.c' || echo '$(srcdir)/'`comp.c
libhcl_la-debug.lo: debug.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhcl_la-debug.lo -MD -MP -MF $(DEPDIR)/libhcl_la-debug.Tpo -c -o libhcl_la-debug.lo `test -f 'debug.c' || echo '$(srcdir)/'`debug.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhcl_la-debug.Tpo $(DEPDIR)/libhcl_la-debug.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='debug.c' object='libhcl_la-debug.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhcl_la-debug.lo `test -f 'debug.c' || echo '$(srcdir)/'`debug.c
libhcl_la-decode.lo: decode.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhcl_la-decode.lo -MD -MP -MF $(DEPDIR)/libhcl_la-decode.Tpo -c -o libhcl_la-decode.lo `test -f 'decode.c' || echo '$(srcdir)/'`decode.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhcl_la-decode.Tpo $(DEPDIR)/libhcl_la-decode.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='decode.c' object='libhcl_la-decode.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhcl_la-decode.lo `test -f 'decode.c' || echo '$(srcdir)/'`decode.c
libhcl_la-dic.lo: dic.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhcl_la-dic.lo -MD -MP -MF $(DEPDIR)/libhcl_la-dic.Tpo -c -o libhcl_la-dic.lo `test -f 'dic.c' || echo '$(srcdir)/'`dic.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhcl_la-dic.Tpo $(DEPDIR)/libhcl_la-dic.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dic.c' object='libhcl_la-dic.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhcl_la-dic.lo `test -f 'dic.c' || echo '$(srcdir)/'`dic.c
libhcl_la-exec.lo: exec.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhcl_la-exec.lo -MD -MP -MF $(DEPDIR)/libhcl_la-exec.Tpo -c -o libhcl_la-exec.lo `test -f 'exec.c' || echo '$(srcdir)/'`exec.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhcl_la-exec.Tpo $(DEPDIR)/libhcl_la-exec.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='exec.c' object='libhcl_la-exec.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhcl_la-exec.lo `test -f 'exec.c' || echo '$(srcdir)/'`exec.c
libhcl_la-gc.lo: gc.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhcl_la-gc.lo -MD -MP -MF $(DEPDIR)/libhcl_la-gc.Tpo -c -o libhcl_la-gc.lo `test -f 'gc.c' || echo '$(srcdir)/'`gc.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhcl_la-gc.Tpo $(DEPDIR)/libhcl_la-gc.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gc.c' object='libhcl_la-gc.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhcl_la-gc.lo `test -f 'gc.c' || echo '$(srcdir)/'`gc.c
libhcl_la-hcl.lo: hcl.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhcl_la-hcl.lo -MD -MP -MF $(DEPDIR)/libhcl_la-hcl.Tpo -c -o libhcl_la-hcl.lo `test -f 'hcl.c' || echo '$(srcdir)/'`hcl.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhcl_la-hcl.Tpo $(DEPDIR)/libhcl_la-hcl.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hcl.c' object='libhcl_la-hcl.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhcl_la-hcl.lo `test -f 'hcl.c' || echo '$(srcdir)/'`hcl.c
libhcl_la-heap.lo: heap.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhcl_la-heap.lo -MD -MP -MF $(DEPDIR)/libhcl_la-heap.Tpo -c -o libhcl_la-heap.lo `test -f 'heap.c' || echo '$(srcdir)/'`heap.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhcl_la-heap.Tpo $(DEPDIR)/libhcl_la-heap.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='heap.c' object='libhcl_la-heap.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhcl_la-heap.lo `test -f 'heap.c' || echo '$(srcdir)/'`heap.c
libhcl_la-logfmt.lo: logfmt.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhcl_la-logfmt.lo -MD -MP -MF $(DEPDIR)/libhcl_la-logfmt.Tpo -c -o libhcl_la-logfmt.lo `test -f 'logfmt.c' || echo '$(srcdir)/'`logfmt.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhcl_la-logfmt.Tpo $(DEPDIR)/libhcl_la-logfmt.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='logfmt.c' object='libhcl_la-logfmt.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhcl_la-logfmt.lo `test -f 'logfmt.c' || echo '$(srcdir)/'`logfmt.c
libhcl_la-obj.lo: obj.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhcl_la-obj.lo -MD -MP -MF $(DEPDIR)/libhcl_la-obj.Tpo -c -o libhcl_la-obj.lo `test -f 'obj.c' || echo '$(srcdir)/'`obj.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhcl_la-obj.Tpo $(DEPDIR)/libhcl_la-obj.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='obj.c' object='libhcl_la-obj.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhcl_la-obj.lo `test -f 'obj.c' || echo '$(srcdir)/'`obj.c
libhcl_la-print.lo: print.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhcl_la-print.lo -MD -MP -MF $(DEPDIR)/libhcl_la-print.Tpo -c -o libhcl_la-print.lo `test -f 'print.c' || echo '$(srcdir)/'`print.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhcl_la-print.Tpo $(DEPDIR)/libhcl_la-print.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='print.c' object='libhcl_la-print.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhcl_la-print.lo `test -f 'print.c' || echo '$(srcdir)/'`print.c
libhcl_la-rbt.lo: rbt.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhcl_la-rbt.lo -MD -MP -MF $(DEPDIR)/libhcl_la-rbt.Tpo -c -o libhcl_la-rbt.lo `test -f 'rbt.c' || echo '$(srcdir)/'`rbt.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhcl_la-rbt.Tpo $(DEPDIR)/libhcl_la-rbt.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rbt.c' object='libhcl_la-rbt.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhcl_la-rbt.lo `test -f 'rbt.c' || echo '$(srcdir)/'`rbt.c
libhcl_la-read.lo: read.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhcl_la-read.lo -MD -MP -MF $(DEPDIR)/libhcl_la-read.Tpo -c -o libhcl_la-read.lo `test -f 'read.c' || echo '$(srcdir)/'`read.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhcl_la-read.Tpo $(DEPDIR)/libhcl_la-read.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='read.c' object='libhcl_la-read.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhcl_la-read.lo `test -f 'read.c' || echo '$(srcdir)/'`read.c
libhcl_la-sym.lo: sym.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhcl_la-sym.lo -MD -MP -MF $(DEPDIR)/libhcl_la-sym.Tpo -c -o libhcl_la-sym.lo `test -f 'sym.c' || echo '$(srcdir)/'`sym.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhcl_la-sym.Tpo $(DEPDIR)/libhcl_la-sym.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sym.c' object='libhcl_la-sym.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhcl_la-sym.lo `test -f 'sym.c' || echo '$(srcdir)/'`sym.c
libhcl_la-utf8.lo: utf8.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhcl_la-utf8.lo -MD -MP -MF $(DEPDIR)/libhcl_la-utf8.Tpo -c -o libhcl_la-utf8.lo `test -f 'utf8.c' || echo '$(srcdir)/'`utf8.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhcl_la-utf8.Tpo $(DEPDIR)/libhcl_la-utf8.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utf8.c' object='libhcl_la-utf8.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhcl_la-utf8.lo `test -f 'utf8.c' || echo '$(srcdir)/'`utf8.c
libhcl_la-utl.lo: utl.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhcl_la-utl.lo -MD -MP -MF $(DEPDIR)/libhcl_la-utl.Tpo -c -o libhcl_la-utl.lo `test -f 'utl.c' || echo '$(srcdir)/'`utl.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libhcl_la-utl.Tpo $(DEPDIR)/libhcl_la-utl.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utl.c' object='libhcl_la-utl.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhcl_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhcl_la-utl.lo `test -f 'utl.c' || echo '$(srcdir)/'`utl.c
hcl-main.o: main.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hcl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hcl-main.o -MD -MP -MF $(DEPDIR)/hcl-main.Tpo -c -o hcl-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/hcl-main.Tpo $(DEPDIR)/hcl-main.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='main.c' object='hcl-main.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hcl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hcl-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c
hcl-main.obj: main.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hcl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hcl-main.obj -MD -MP -MF $(DEPDIR)/hcl-main.Tpo -c -o hcl-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/hcl-main.Tpo $(DEPDIR)/hcl-main.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='main.c' object='hcl-main.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(hcl_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o hcl-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`
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: $(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 $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) hcl-cfg.h
installdirs:
for dir in "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(bindir)" "$(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-binPROGRAMS clean-generic clean-libtool \
clean-pkglibLTLIBRARIES mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-hdr distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-pkgincludeHEADERS
@$(NORMAL_INSTALL)
$(MAKE) $(AM_MAKEFLAGS) install-data-hook
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-binPROGRAMS install-pkglibLTLIBRARIES
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 -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-binPROGRAMS uninstall-pkgincludeHEADERS \
uninstall-pkglibLTLIBRARIES
@$(NORMAL_INSTALL)
$(MAKE) $(AM_MAKEFLAGS) uninstall-hook
.MAKE: all install-am install-data-am install-strip uninstall-am
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
clean-binPROGRAMS clean-generic clean-libtool \
clean-pkglibLTLIBRARIES cscopelist-am ctags ctags-am distclean \
distclean-compile distclean-generic distclean-hdr \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-binPROGRAMS \
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-pkglibLTLIBRARIES install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \
uninstall-binPROGRAMS uninstall-hook \
uninstall-pkgincludeHEADERS uninstall-pkglibLTLIBRARIES
install-data-hook:
@echo "#ifndef _HCL_CFG_H_" > "$(DESTDIR)$(pkgincludedir)/hcl-cfg.h"
@echo "#define _HCL_CFG_H_" >> "$(DESTDIR)$(pkgincludedir)/hcl-cfg.h"
@$(EGREP) "#define[ ]+HCL_" "$(abs_builddir)/hcl-cfg.h" >> "$(DESTDIR)$(pkgincludedir)/hcl-cfg.h"
@echo "#endif" >> "$(DESTDIR)$(pkgincludedir)/hcl-cfg.h"
@rm -f "$(DESTDIR)$(pkgincludedir)/hcl-cfg.h.in"
@$(SED) 's|/\*#define HCL_HAVE_CFG_H\*/|#define HCL_HAVE_CFG_H|' "$(srcdir)/hcl-cmn.h" > "$(DESTDIR)$(pkgincludedir)/hcl-cmn.h"
uninstall-hook:
@rm -f "$(DESTDIR)$(pkgincludedir)/hcl-cfg.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:

3699
lib/bigint.c Normal file

File diff suppressed because it is too large Load Diff

1003
lib/comp.c Normal file

File diff suppressed because it is too large Load Diff

71
lib/debug.c Normal file
View File

@ -0,0 +1,71 @@
/*
* $Id$
*
Copyright (c) 2014-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "hcl-prv.h"
void hcl_dumpsymtab (hcl_t* hcl)
{
hcl_oow_t i;
hcl_oop_char_t symbol;
HCL_DEBUG0 (hcl, "--------------------------------------------\n");
HCL_DEBUG1 (hcl, "Stix Symbol Table %zu\n", HCL_OBJ_GET_SIZE(hcl->symtab->bucket));
HCL_DEBUG0 (hcl, "--------------------------------------------\n");
for (i = 0; i < HCL_OBJ_GET_SIZE(hcl->symtab->bucket); i++)
{
symbol = (hcl_oop_char_t)hcl->symtab->bucket->slot[i];
if ((hcl_oop_t)symbol != hcl->_nil)
{
HCL_DEBUG2 (hcl, " %07zu %O\n", i, symbol);
}
}
HCL_DEBUG0 (hcl, "--------------------------------------------\n");
}
void hcl_dumpdic (hcl_t* hcl, hcl_oop_set_t dic, const hcl_bch_t* title)
{
hcl_oow_t i;
hcl_oop_cons_t ass;
HCL_DEBUG0 (hcl, "--------------------------------------------\n");
HCL_DEBUG2 (hcl, "%s %zu\n", title, HCL_OBJ_GET_SIZE(dic->bucket));
HCL_DEBUG0 (hcl, "--------------------------------------------\n");
for (i = 0; i < HCL_OBJ_GET_SIZE(dic->bucket); i++)
{
ass = (hcl_oop_cons_t)dic->bucket->slot[i];
if ((hcl_oop_t)ass != hcl->_nil)
{
HCL_DEBUG2 (hcl, " %07zu %O\n", i, ass->car);
}
}
HCL_DEBUG0 (hcl, "--------------------------------------------\n");
}

536
lib/decode.c Normal file
View File

@ -0,0 +1,536 @@
/*
/*
* $Id$
*
Copyright (c) 2014-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "hcl-prv.h"
#define DECODE_LOG_MASK (HCL_LOG_MNEMONIC)
#define LOG_INST_0(hcl,fmt) HCL_LOG0(hcl, DECODE_LOG_MASK, "\t" fmt "\n")
#define LOG_INST_1(hcl,fmt,a1) HCL_LOG1(hcl, DECODE_LOG_MASK, "\t" fmt "\n",a1)
#define LOG_INST_2(hcl,fmt,a1,a2) HCL_LOG2(hcl, DECODE_LOG_MASK, "\t" fmt "\n", a1, a2)
#define LOG_INST_3(hcl,fmt,a1,a2,a3) HCL_LOG3(hcl, DECODE_LOG_MASK, "\t" fmt "\n", a1, a2, a3)
#define FETCH_BYTE_CODE(hcl) (cdptr[ip++])
#define FETCH_BYTE_CODE_TO(hcl,v_ooi) (v_ooi = FETCH_BYTE_CODE(hcl))
#if (HCL_BCODE_LONG_PARAM_SIZE == 2)
# define FETCH_PARAM_CODE_TO(hcl,v_ooi) \
do { \
v_ooi = FETCH_BYTE_CODE(hcl); \
v_ooi = (v_ooi << 8) | FETCH_BYTE_CODE(hcl); \
} while (0)
#else
# define FETCH_PARAM_CODE_TO(hcl,v_ooi) (v_ooi = FETCH_BYTE_CODE(hcl))
#endif
/* TODO: check if ip shoots beyond the maximum length in fetching code and parameters */
int hcl_decode (hcl_t* hcl, hcl_oow_t start, hcl_oow_t end)
{
hcl_oob_t bcode, * cdptr;
hcl_oow_t ip = start;
hcl_ooi_t b1, b2;
/* the instruction at the offset 'end' is not decoded.
* decoding offset range is from start to end - 1. */
HCL_ASSERT (end <= hcl->code.bc.len);
ip = start;
cdptr = ((hcl_oop_byte_t)hcl->code.bc.arr)->slot;
/* TODO: check if ip increases beyond bcode when fetching parameters too */
while (ip < end)
{
FETCH_BYTE_CODE_TO(hcl, bcode);
switch (bcode)
{
case BCODE_PUSH_INSTVAR_X:
FETCH_PARAM_CODE_TO (hcl, b1);
goto push_instvar;
case BCODE_PUSH_INSTVAR_0:
case BCODE_PUSH_INSTVAR_1:
case BCODE_PUSH_INSTVAR_2:
case BCODE_PUSH_INSTVAR_3:
case BCODE_PUSH_INSTVAR_4:
case BCODE_PUSH_INSTVAR_5:
case BCODE_PUSH_INSTVAR_6:
case BCODE_PUSH_INSTVAR_7:
b1 = bcode & 0x7; /* low 3 bits */
push_instvar:
LOG_INST_1 (hcl, "push_instvar %zd", b1);
break;
/* ------------------------------------------------- */
case BCODE_STORE_INTO_INSTVAR_X:
FETCH_PARAM_CODE_TO (hcl, b1);
goto store_instvar;
case BCODE_STORE_INTO_INSTVAR_0:
case BCODE_STORE_INTO_INSTVAR_1:
case BCODE_STORE_INTO_INSTVAR_2:
case BCODE_STORE_INTO_INSTVAR_3:
case BCODE_STORE_INTO_INSTVAR_4:
case BCODE_STORE_INTO_INSTVAR_5:
case BCODE_STORE_INTO_INSTVAR_6:
case BCODE_STORE_INTO_INSTVAR_7:
b1 = bcode & 0x7; /* low 3 bits */
store_instvar:
LOG_INST_1 (hcl, "store_into_instvar %zd", b1);
break;
case BCODE_POP_INTO_INSTVAR_X:
FETCH_PARAM_CODE_TO (hcl, b1);
goto pop_into_instvar;
case BCODE_POP_INTO_INSTVAR_0:
case BCODE_POP_INTO_INSTVAR_1:
case BCODE_POP_INTO_INSTVAR_2:
case BCODE_POP_INTO_INSTVAR_3:
case BCODE_POP_INTO_INSTVAR_4:
case BCODE_POP_INTO_INSTVAR_5:
case BCODE_POP_INTO_INSTVAR_6:
case BCODE_POP_INTO_INSTVAR_7:
b1 = bcode & 0x7; /* low 3 bits */
pop_into_instvar:
LOG_INST_1 (hcl, "pop_into_instvar %zd", b1);
break;
/* ------------------------------------------------- */
case HCL_CODE_PUSH_TEMPVAR_X:
case BCODE_STORE_INTO_TEMPVAR_X:
case BCODE_POP_INTO_TEMPVAR_X:
FETCH_PARAM_CODE_TO (hcl, b1);
goto handle_tempvar;
case HCL_CODE_PUSH_TEMPVAR_0:
case HCL_CODE_PUSH_TEMPVAR_1:
case HCL_CODE_PUSH_TEMPVAR_2:
case HCL_CODE_PUSH_TEMPVAR_3:
case HCL_CODE_PUSH_TEMPVAR_4:
case HCL_CODE_PUSH_TEMPVAR_5:
case HCL_CODE_PUSH_TEMPVAR_6:
case HCL_CODE_PUSH_TEMPVAR_7:
case BCODE_STORE_INTO_TEMPVAR_0:
case BCODE_STORE_INTO_TEMPVAR_1:
case BCODE_STORE_INTO_TEMPVAR_2:
case BCODE_STORE_INTO_TEMPVAR_3:
case BCODE_STORE_INTO_TEMPVAR_4:
case BCODE_STORE_INTO_TEMPVAR_5:
case BCODE_STORE_INTO_TEMPVAR_6:
case BCODE_STORE_INTO_TEMPVAR_7:
case BCODE_POP_INTO_TEMPVAR_0:
case BCODE_POP_INTO_TEMPVAR_1:
case BCODE_POP_INTO_TEMPVAR_2:
case BCODE_POP_INTO_TEMPVAR_3:
case BCODE_POP_INTO_TEMPVAR_4:
case BCODE_POP_INTO_TEMPVAR_5:
case BCODE_POP_INTO_TEMPVAR_6:
case BCODE_POP_INTO_TEMPVAR_7:
b1 = bcode & 0x7; /* low 3 bits */
handle_tempvar:
if ((bcode >> 4) & 1)
{
/* push - bit 4 on */
LOG_INST_1 (hcl, "push_tempvar %zd", b1);
}
else
{
/* store or pop - bit 5 off */
if ((bcode >> 3) & 1)
{
/* pop - bit 3 on */
LOG_INST_1 (hcl, "pop_into_tempvar %zd", b1);
}
else
{
LOG_INST_1 (hcl, "store_into_tempvar %zd", b1);
}
}
break;
/* ------------------------------------------------- */
case HCL_CODE_PUSH_LITERAL_X2:
FETCH_PARAM_CODE_TO (hcl, b1);
FETCH_PARAM_CODE_TO (hcl, b2);
#if (HCL_BCODE_LONG_PARAM_SIZE == 2)
b1 = (b1 << 16) | b2;
#else
b1 = (b1 << 8) | b2;
#endif
goto push_literal;
case HCL_CODE_PUSH_LITERAL_X:
FETCH_PARAM_CODE_TO (hcl, b1);
goto push_literal;
case HCL_CODE_PUSH_LITERAL_0:
case HCL_CODE_PUSH_LITERAL_1:
case HCL_CODE_PUSH_LITERAL_2:
case HCL_CODE_PUSH_LITERAL_3:
case HCL_CODE_PUSH_LITERAL_4:
case HCL_CODE_PUSH_LITERAL_5:
case HCL_CODE_PUSH_LITERAL_6:
case HCL_CODE_PUSH_LITERAL_7:
b1 = bcode & 0x7; /* low 3 bits */
push_literal:
LOG_INST_1 (hcl, "push_literal @%zd", b1);
break;
/* ------------------------------------------------- */
case HCL_CODE_PUSH_OBJECT_X:
case HCL_CODE_STORE_INTO_OBJECT_X:
case HCL_CODE_POP_INTO_OBJECT_X:
FETCH_PARAM_CODE_TO (hcl, b1);
goto handle_object;
case HCL_CODE_PUSH_OBJECT_0:
case HCL_CODE_PUSH_OBJECT_1:
case HCL_CODE_PUSH_OBJECT_2:
case HCL_CODE_PUSH_OBJECT_3:
case HCL_CODE_STORE_INTO_OBJECT_0:
case HCL_CODE_STORE_INTO_OBJECT_1:
case HCL_CODE_STORE_INTO_OBJECT_2:
case HCL_CODE_STORE_INTO_OBJECT_3:
case HCL_CODE_POP_INTO_OBJECT_0:
case HCL_CODE_POP_INTO_OBJECT_1:
case HCL_CODE_POP_INTO_OBJECT_2:
case HCL_CODE_POP_INTO_OBJECT_3:
b1 = bcode & 0x3; /* low 2 bits */
handle_object:
if ((bcode >> 3) & 1)
{
if ((bcode >> 2) & 1)
{
LOG_INST_1 (hcl, "pop_into_object @%zd", b1);
}
else
{
LOG_INST_1 (hcl, "store_into_object @%zd", b1);
}
}
else
{
LOG_INST_1 (hcl, "push_object @%zd", b1);
}
break;
/* -------------------------------------------------------- */
case HCL_CODE_JUMP_FORWARD_X:
FETCH_PARAM_CODE_TO (hcl, b1);
LOG_INST_1 (hcl, "jump_forward %zd", b1);
break;
case HCL_CODE_JUMP_FORWARD_0:
case HCL_CODE_JUMP_FORWARD_1:
case HCL_CODE_JUMP_FORWARD_2:
case HCL_CODE_JUMP_FORWARD_3:
LOG_INST_1 (hcl, "jump_forward %zd", (bcode & 0x3)); /* low 2 bits */
break;
case HCL_CODE_JUMP_BACKWARD_X:
FETCH_PARAM_CODE_TO (hcl, b1);
LOG_INST_1 (hcl, "jump_backward %zd", b1);
hcl->ip += b1;
break;
case HCL_CODE_JUMP_BACKWARD_0:
case HCL_CODE_JUMP_BACKWARD_1:
case HCL_CODE_JUMP_BACKWARD_2:
case HCL_CODE_JUMP_BACKWARD_3:
LOG_INST_1 (hcl, "jump_backward %zd", (bcode & 0x3)); /* low 2 bits */
break;
case BCODE_JUMP_IF_TRUE_X:
case BCODE_JUMP_IF_FALSE_X:
case BCODE_JUMP_IF_TRUE_0:
case BCODE_JUMP_IF_TRUE_1:
case BCODE_JUMP_IF_TRUE_2:
case BCODE_JUMP_IF_TRUE_3:
case BCODE_JUMP_IF_FALSE_0:
case BCODE_JUMP_IF_FALSE_1:
case BCODE_JUMP_IF_FALSE_2:
case BCODE_JUMP_IF_FALSE_3:
LOG_INST_0 (hcl, "<<<<<<<<<<<<<< JUMP NOT IMPLEMENTED YET >>>>>>>>>>>>");
hcl->errnum = HCL_ENOIMPL;
return -1;
case HCL_CODE_JUMP2_FORWARD:
FETCH_PARAM_CODE_TO (hcl, b1);
LOG_INST_1 (hcl, "jump2_forward %zd", b1);
break;
case HCL_CODE_JUMP2_BACKWARD:
FETCH_PARAM_CODE_TO (hcl, b1);
LOG_INST_1 (hcl, "jump2_backward %zd", b1);
break;
/* -------------------------------------------------------- */
case HCL_CODE_CALL_X:
FETCH_PARAM_CODE_TO (hcl, b1);
goto handle_call;
case HCL_CODE_CALL_0:
case HCL_CODE_CALL_1:
case HCL_CODE_CALL_2:
case HCL_CODE_CALL_3:
b1 = bcode & 0x3; /* low 2 bits */
handle_call:
LOG_INST_1 (hcl, "call %zd", b1);
break;
/* -------------------------------------------------------- */
case BCODE_PUSH_CTXTEMPVAR_X:
case BCODE_STORE_INTO_CTXTEMPVAR_X:
case BCODE_POP_INTO_CTXTEMPVAR_X:
FETCH_PARAM_CODE_TO (hcl, b1);
FETCH_PARAM_CODE_TO (hcl, b2);
goto handle_ctxtempvar;
case BCODE_PUSH_CTXTEMPVAR_0:
case BCODE_PUSH_CTXTEMPVAR_1:
case BCODE_PUSH_CTXTEMPVAR_2:
case BCODE_PUSH_CTXTEMPVAR_3:
case BCODE_STORE_INTO_CTXTEMPVAR_0:
case BCODE_STORE_INTO_CTXTEMPVAR_1:
case BCODE_STORE_INTO_CTXTEMPVAR_2:
case BCODE_STORE_INTO_CTXTEMPVAR_3:
case BCODE_POP_INTO_CTXTEMPVAR_0:
case BCODE_POP_INTO_CTXTEMPVAR_1:
case BCODE_POP_INTO_CTXTEMPVAR_2:
case BCODE_POP_INTO_CTXTEMPVAR_3:
b1 = bcode & 0x3; /* low 2 bits */
FETCH_BYTE_CODE_TO (hcl, b2);
handle_ctxtempvar:
if ((bcode >> 3) & 1)
{
/* store or pop */
if ((bcode >> 2) & 1)
{
LOG_INST_2 (hcl, "pop_into_ctxtempvar %zd %zd", b1, b2);
}
else
{
LOG_INST_2 (hcl, "store_into_ctxtempvar %zd %zd", b1, b2);
}
}
else
{
/* push */
LOG_INST_2 (hcl, "push_ctxtempvar %zd %zd", b1, b2);
}
break;
/* -------------------------------------------------------- */
case BCODE_PUSH_OBJVAR_X:
case BCODE_STORE_INTO_OBJVAR_X:
case BCODE_POP_INTO_OBJVAR_X:
FETCH_PARAM_CODE_TO (hcl, b1);
FETCH_PARAM_CODE_TO (hcl, b2);
goto handle_objvar;
case BCODE_PUSH_OBJVAR_0:
case BCODE_PUSH_OBJVAR_1:
case BCODE_PUSH_OBJVAR_2:
case BCODE_PUSH_OBJVAR_3:
case BCODE_STORE_INTO_OBJVAR_0:
case BCODE_STORE_INTO_OBJVAR_1:
case BCODE_STORE_INTO_OBJVAR_2:
case BCODE_STORE_INTO_OBJVAR_3:
case BCODE_POP_INTO_OBJVAR_0:
case BCODE_POP_INTO_OBJVAR_1:
case BCODE_POP_INTO_OBJVAR_2:
case BCODE_POP_INTO_OBJVAR_3:
/* b1 -> variable index to the object indicated by b2.
* b2 -> object index stored in the literal frame. */
b1 = bcode & 0x3; /* low 2 bits */
FETCH_BYTE_CODE_TO (hcl, b2);
handle_objvar:
if ((bcode >> 3) & 1)
{
/* store or pop */
if ((bcode >> 2) & 1)
{
LOG_INST_2 (hcl, "pop_into_objvar %zd %zd", b1, b2);
}
else
{
LOG_INST_2 (hcl, "store_into_objvar %zd %zd", b1, b2);
}
}
else
{
LOG_INST_2 (hcl, "push_objvar %zd %zd", b1, b2);
}
break;
/* -------------------------------------------------------- */
case BCODE_SEND_MESSAGE_X:
case BCODE_SEND_MESSAGE_TO_SUPER_X:
/* b1 -> number of arguments
* b2 -> selector index stored in the literal frame */
FETCH_PARAM_CODE_TO (hcl, b1);
FETCH_PARAM_CODE_TO (hcl, b2);
goto handle_send_message;
case BCODE_SEND_MESSAGE_0:
case BCODE_SEND_MESSAGE_1:
case BCODE_SEND_MESSAGE_2:
case BCODE_SEND_MESSAGE_3:
case BCODE_SEND_MESSAGE_TO_SUPER_0:
case BCODE_SEND_MESSAGE_TO_SUPER_1:
case BCODE_SEND_MESSAGE_TO_SUPER_2:
case BCODE_SEND_MESSAGE_TO_SUPER_3:
b1 = bcode & 0x3; /* low 2 bits */
FETCH_BYTE_CODE_TO (hcl, b2);
handle_send_message:
LOG_INST_3 (hcl, "send_message%hs %zd @%zd", (((bcode >> 2) & 1)? "_to_super": ""), b1, b2);
break;
/* -------------------------------------------------------- */
case BCODE_PUSH_RECEIVER:
LOG_INST_0 (hcl, "push_receiver");
break;
case HCL_CODE_PUSH_NIL:
LOG_INST_0 (hcl, "push_nil");
break;
case HCL_CODE_PUSH_TRUE:
LOG_INST_0 (hcl, "push_true");
break;
case HCL_CODE_PUSH_FALSE:
LOG_INST_0 (hcl, "push_false");
break;
case BCODE_PUSH_CONTEXT:
LOG_INST_0 (hcl, "push_context");
break;
case BCODE_PUSH_PROCESS:
LOG_INST_0 (hcl, "push_process");
break;
case HCL_CODE_PUSH_NEGONE:
LOG_INST_0 (hcl, "push_negone");
break;
case HCL_CODE_PUSH_ZERO:
LOG_INST_0 (hcl, "push_zero");
break;
case HCL_CODE_PUSH_ONE:
LOG_INST_0 (hcl, "push_one");
break;
case HCL_CODE_PUSH_TWO:
LOG_INST_0 (hcl, "push_two");
break;
case HCL_CODE_PUSH_INTLIT:
FETCH_PARAM_CODE_TO (hcl, b1);
LOG_INST_1 (hcl, "push_intlit %zd", b1);
break;
case HCL_CODE_PUSH_NEGINTLIT:
FETCH_PARAM_CODE_TO (hcl, b1);
LOG_INST_1 (hcl, "push_negintlit %zd", -b1);
break;
case HCL_CODE_PUSH_CHARLIT:
FETCH_PARAM_CODE_TO (hcl, b1);
LOG_INST_1 (hcl, "push_charlit %zd", b1);
break;
/* -------------------------------------------------------- */
case BCODE_DUP_STACKTOP:
LOG_INST_0 (hcl, "dup_stacktop");
break;
case HCL_CODE_POP_STACKTOP:
LOG_INST_0 (hcl, "pop_stacktop");
break;
case BCODE_RETURN_STACKTOP:
LOG_INST_0 (hcl, "return_stacktop");
break;
case BCODE_RETURN_RECEIVER:
LOG_INST_0 (hcl, "return_receiver");
break;
case HCL_CODE_RETURN_FROM_BLOCK:
LOG_INST_0 (hcl, "return_from_block");
break;
case HCL_CODE_MAKE_BLOCK:
/* b1 - number of block arguments
* b2 - number of block temporaries */
FETCH_PARAM_CODE_TO (hcl, b1);
FETCH_PARAM_CODE_TO (hcl, b2);
LOG_INST_2 (hcl, "make_block %zd %zd", b1, b2);
HCL_ASSERT (b1 >= 0);
HCL_ASSERT (b2 >= b1);
break;
case BCODE_SEND_BLOCK_COPY:
LOG_INST_0 (hcl, "send_block_copy");
break;
case HCL_CODE_NOOP:
/* do nothing */
LOG_INST_0 (hcl, "noop");
break;
default:
LOG_INST_1 (hcl, "UNKNOWN BYTE CODE ENCOUNTERED %x", (int)bcode);
hcl->errnum = HCL_EINTERN;
break;
}
}
/* print literal frame contents */
for (ip = 0; ip < hcl->code.lit.len; ip++)
{
LOG_INST_2 (hcl, " @%-3lu %O", (unsigned long int)ip, ((hcl_oop_oop_t)hcl->code.lit.arr)->slot[ip]);
}
return 0;
}

263
lib/dic.c Normal file
View File

@ -0,0 +1,263 @@
/*
* $Id$
*
Copyright (c) 2014-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "hcl-prv.h"
static hcl_oop_oop_t expand_bucket (hcl_t* hcl, hcl_oop_oop_t oldbuc)
{
hcl_oop_oop_t newbuc;
hcl_oow_t oldsz, newsz, index;
hcl_oop_cons_t ass;
hcl_oop_char_t key;
oldsz = HCL_OBJ_GET_SIZE(oldbuc);
/* TODO: better growth policy? */
if (oldsz < 5000) newsz = oldsz + oldsz;
else if (oldsz < 50000) newsz = oldsz + (oldsz / 2);
else if (oldsz < 100000) newsz = oldsz + (oldsz / 4);
else if (oldsz < 200000) newsz = oldsz + (oldsz / 8);
else if (oldsz < 400000) newsz = oldsz + (oldsz / 16);
else if (oldsz < 800000) newsz = oldsz + (oldsz / 32);
else if (oldsz < 1600000) newsz = oldsz + (oldsz / 64);
else
{
hcl_oow_t inc, inc_max;
inc = oldsz / 128;
inc_max = HCL_OBJ_SIZE_MAX - oldsz;
if (inc > inc_max)
{
if (inc_max > 0) inc = inc_max;
else
{
hcl->errnum = HCL_EOOMEM;
return HCL_NULL;
}
}
newsz = oldsz + inc;
}
hcl_pushtmp (hcl, (hcl_oop_t*)&oldbuc);
newbuc = (hcl_oop_oop_t)hcl_makearray (hcl, newsz);
hcl_poptmp (hcl);
if (!newbuc) return HCL_NULL;
while (oldsz > 0)
{
ass = (hcl_oop_cons_t)oldbuc->slot[--oldsz];
if ((hcl_oop_t)ass != hcl->_nil)
{
HCL_ASSERT (HCL_BRANDOF(hcl,ass) == HCL_BRAND_CONS);
key = (hcl_oop_char_t)ass->car;
HCL_ASSERT (HCL_BRANDOF(hcl,key) == HCL_BRAND_SYMBOL);
index = hcl_hashchars(key->slot, HCL_OBJ_GET_SIZE(key)) % newsz;
while (newbuc->slot[index] != hcl->_nil) index = (index + 1) % newsz;
newbuc->slot[index] = (hcl_oop_t)ass;
}
}
return newbuc;
}
static hcl_oop_cons_t find_or_upsert (hcl_t* hcl, hcl_oop_set_t dic, hcl_oop_char_t key, hcl_oop_t value)
{
hcl_ooi_t tally;
hcl_oow_t index;
hcl_oop_cons_t ass;
hcl_oow_t tmp_count = 0;
/* the system dictionary is not a generic dictionary.
* it accepts only a symbol as a key. */
HCL_ASSERT (HCL_BRANDOF(hcl,key) == HCL_BRAND_SYMBOL);
HCL_ASSERT (HCL_OOP_IS_SMOOI(dic->tally));
HCL_ASSERT (HCL_BRANDOF(hcl,dic->bucket) == HCL_BRAND_INTEGER);
index = hcl_hashchars(key->slot, HCL_OBJ_GET_SIZE(key)) % HCL_OBJ_GET_SIZE(dic->bucket);
/* find */
while (dic->bucket->slot[index] != hcl->_nil)
{
ass = (hcl_oop_cons_t)dic->bucket->slot[index];
HCL_ASSERT (HCL_BRANDOF(hcl,ass) == HCL_BRAND_CONS);
HCL_ASSERT (HCL_BRANDOF(hcl,ass->car) == HCL_BRAND_SYMBOL);
if (HCL_OBJ_GET_SIZE(key) == HCL_OBJ_GET_SIZE(ass->car) &&
hcl_equalchars (key->slot, ((hcl_oop_char_t)ass->car)->slot, HCL_OBJ_GET_SIZE(key)))
{
/* the value of HCL_NULL indicates no insertion or update. */
if (value) ass->cdr = value; /* update */
return ass;
}
index = (index + 1) % HCL_OBJ_GET_SIZE(dic->bucket);
}
if (!value)
{
/* when value is HCL_NULL, perform no insertion.
* the value of HCL_NULL indicates no insertion or update. */
hcl->errnum = HCL_ENOENT;
return HCL_NULL;
}
/* the key is not found. insert it. */
HCL_ASSERT (HCL_OOP_IS_SMOOI(dic->tally));
tally = HCL_OOP_TO_SMOOI(dic->tally);
if (tally >= HCL_SMOOI_MAX)
{
/* this built-in dictionary is not allowed to hold more than
* HCL_SMOOI_MAX items for efficiency sake */
hcl->errnum = HCL_EDFULL;
return HCL_NULL;
}
hcl_pushtmp (hcl, (hcl_oop_t*)&dic); tmp_count++;
hcl_pushtmp (hcl, (hcl_oop_t*)&key); tmp_count++;
hcl_pushtmp (hcl, &value); tmp_count++;
/* no conversion to hcl_oow_t is necessary for tally + 1.
* the maximum value of tally is checked to be HCL_SMOOI_MAX - 1.
* tally + 1 can produce at most HCL_SMOOI_MAX. above all,
* HCL_SMOOI_MAX is way smaller than HCL_TYPE_MAX(hcl_ooi_t). */
if (tally + 1 >= HCL_OBJ_GET_SIZE(dic->bucket))
{
hcl_oop_oop_t bucket;
/* TODO: make the growth policy configurable instead of growing
it just before it gets full. The polcy can be grow it
if it's 70% full */
/* enlarge the bucket before it gets full to
* make sure that it has at least one free slot left
* after having added a new symbol. this is to help
* traversal end at a _nil slot if no entry is found. */
bucket = expand_bucket (hcl, dic->bucket);
if (!bucket) goto oops;
dic->bucket = bucket;
/* recalculate the index for the expanded bucket */
index = hcl_hashchars(key->slot, HCL_OBJ_GET_SIZE(key)) % HCL_OBJ_GET_SIZE(dic->bucket);
while (dic->bucket->slot[index] != hcl->_nil)
index = (index + 1) % HCL_OBJ_GET_SIZE(dic->bucket);
}
/* create a new assocation of a key and a value since
* the key isn't found in the root dictionary */
ass = (hcl_oop_cons_t)hcl_makecons (hcl, (hcl_oop_t)key, (hcl_oop_t)value);
if (!ass) goto oops;
/* the current tally must be less than the maximum value. otherwise,
* it overflows after increment below */
HCL_ASSERT (tally < HCL_SMOOI_MAX);
dic->tally = HCL_SMOOI_TO_OOP(tally + 1);
dic->bucket->slot[index] = (hcl_oop_t)ass;
hcl_poptmps (hcl, tmp_count);
return ass;
oops:
hcl_poptmps (hcl, tmp_count);
return HCL_NULL;
}
static hcl_oop_cons_t lookup (hcl_t* hcl, hcl_oop_set_t dic, const hcl_oocs_t* name)
{
/* this is special version of hcl_getatsysdic() that performs
* lookup using a plain string specified */
hcl_oow_t index;
hcl_oop_cons_t ass;
HCL_ASSERT (HCL_OOP_IS_SMOOI(dic->tally));
HCL_ASSERT (HCL_BRANDOF(hcl,dic->bucket) == HCL_BRAND_ARRAY);
index = hcl_hashchars(name->ptr, name->len) % HCL_OBJ_GET_SIZE(dic->bucket);
while (dic->bucket->slot[index] != hcl->_nil)
{
ass = (hcl_oop_cons_t)dic->bucket->slot[index];
HCL_ASSERT (HCL_BRANDOF(hcl,ass) == HCL_BRAND_CONS);
HCL_ASSERT (HCL_BRANDOF(hcl,ass->car) == HCL_BRAND_SYMBOL);
if (name->len == HCL_OBJ_GET_SIZE(ass->car) &&
hcl_equalchars(name->ptr, ((hcl_oop_char_t)ass->car)->slot, name->len))
{
return ass;
}
index = (index + 1) % HCL_OBJ_GET_SIZE(dic->bucket);
}
/* when value is HCL_NULL, perform no insertion */
hcl->errnum = HCL_ENOENT;
return HCL_NULL;
}
hcl_oop_cons_t hcl_putatsysdic (hcl_t* hcl, hcl_oop_t key, hcl_oop_t value)
{
HCL_ASSERT (HCL_BRANDOF(hcl,key) == HCL_BRAND_SYMBOL);
return find_or_upsert (hcl, hcl->sysdic, (hcl_oop_char_t)key, value);
}
hcl_oop_cons_t hcl_getatsysdic (hcl_t* hcl, hcl_oop_t key)
{
HCL_ASSERT (HCL_BRANDOF(hcl,key) == HCL_BRAND_SYMBOL);
return find_or_upsert (hcl, hcl->sysdic, (hcl_oop_char_t)key, HCL_NULL);
}
hcl_oop_cons_t hcl_lookupsysdic (hcl_t* hcl, const hcl_oocs_t* name)
{
return lookup (hcl, hcl->sysdic, name);
}
hcl_oop_cons_t hcl_putatdic (hcl_t* hcl, hcl_oop_set_t dic, hcl_oop_t key, hcl_oop_t value)
{
HCL_ASSERT (HCL_BRANDOF(hcl,key) == HCL_BRAND_SYMBOL);
return find_or_upsert (hcl, dic, (hcl_oop_char_t)key, value);
}
hcl_oop_cons_t hcl_getatdic (hcl_t* hcl, hcl_oop_set_t dic, hcl_oop_t key)
{
HCL_ASSERT (HCL_BRANDOF(hcl,key) == HCL_BRAND_SYMBOL);
return find_or_upsert (hcl, dic, (hcl_oop_char_t)key, HCL_NULL);
}
hcl_oop_cons_t hcl_lookupdic (hcl_t* hcl, hcl_oop_set_t dic, const hcl_oocs_t* name)
{
return lookup (hcl, dic, name);
}
hcl_oop_set_t hcl_makedic (hcl_t* hcl, hcl_oow_t size)
{
return (hcl_oop_set_t)hcl_makeset (hcl, size);
}

30
lib/exec.c Normal file
View File

@ -0,0 +1,30 @@
/*
* $Id$
*
Copyright (c) 2014-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "hcl-prv.h"

513
lib/gc.c Normal file
View File

@ -0,0 +1,513 @@
/*
* $Id$
*
Copyright (c) 2014-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "hcl-prv.h"
static struct
{
hcl_oow_t len;
hcl_ooch_t ptr[10];
int syncode;
hcl_oow_t offset;
} syminfo[] =
{
{ 6, { 'b', 'e', 'g', 'i', 'n' }, HCL_SYNCODE_BEGIN, HCL_OFFSETOF(hcl_t,_begin) },
{ 5, { 'd', 'e', 'f', 'u', 'n' }, HCL_SYNCODE_DEFUN, HCL_OFFSETOF(hcl_t,_defun) },
{ 2, { 'i', 'f' }, HCL_SYNCODE_IF, HCL_OFFSETOF(hcl_t,_if) },
{ 6, { 'l', 'a', 'm', 'b', 'd', 'a' }, HCL_SYNCODE_LAMBDA, HCL_OFFSETOF(hcl_t,_lambda) },
{ 5, { 'q', 'u', 'o', 't', 'e' }, HCL_SYNCODE_QUOTE, HCL_OFFSETOF(hcl_t,_quote) },
{ 3, { 's', 'e', 't' }, HCL_SYNCODE_SET, HCL_OFFSETOF(hcl_t,_set) }
};
/* ========================================================================= */
static void compact_symbol_table (hcl_t* hcl, hcl_oop_t _nil)
{
hcl_oop_char_t symbol;
hcl_oow_t i, x, y, z;
hcl_oow_t bucket_size, index;
hcl_ooi_t tally;
#if defined(HCL_SUPPORT_GC_DURING_IGNITION)
if (!hcl->symtab) return; /* symbol table has not been created */
#endif
/* the symbol table doesn't allow more data items than HCL_SMOOI_MAX.
* so hcl->symtab->tally must always be a small integer */
HCL_ASSERT (HCL_OOP_IS_SMOOI(hcl->symtab->tally));
tally = HCL_OOP_TO_SMOOI(hcl->symtab->tally);
HCL_ASSERT (tally >= 0); /* it must not be less than 0 */
if (tally <= 0) return;
/* NOTE: in theory, the bucket size can be greater than HCL_SMOOI_MAX
* as it is an internal header field and is of an unsigned type */
bucket_size = HCL_OBJ_GET_SIZE(hcl->symtab->bucket);
for (index = 0; index < bucket_size; )
{
if (HCL_OBJ_GET_FLAGS_MOVED(hcl->symtab->bucket->slot[index]))
{
index++;
continue;
}
HCL_ASSERT (hcl->symtab->bucket->slot[index] != _nil);
for (i = 0, x = index, y = index; i < bucket_size; i++)
{
y = (y + 1) % bucket_size;
/* done if the slot at the current hash index is _nil */
if (hcl->symtab->bucket->slot[y] == _nil) break;
/* get the natural hash index for the data in the slot
* at the current hash index */
symbol = (hcl_oop_char_t)hcl->symtab->bucket->slot[y];
HCL_ASSERT (HCL_BRANDOF(hcl,symbol) == HCL_BRAND_SYMBOL);
z = hcl_hashchars(symbol->slot, HCL_OBJ_GET_SIZE(symbol)) % bucket_size;
/* move an element if necessary */
if ((y > x && (z <= x || z > y)) ||
(y < x && (z <= x && z > y)))
{
hcl->symtab->bucket->slot[x] = hcl->symtab->bucket->slot[y];
x = y;
}
}
hcl->symtab->bucket->slot[x] = _nil;
tally--;
}
HCL_ASSERT (tally >= 0);
HCL_ASSERT (tally <= HCL_SMOOI_MAX);
hcl->symtab->tally = HCL_SMOOI_TO_OOP(tally);
}
static HCL_INLINE hcl_oow_t get_payload_bytes (hcl_t* hcl, hcl_oop_t oop)
{
hcl_oow_t nbytes_aligned;
#if defined(HCL_USE_OBJECT_TRAILER)
if (HCL_OBJ_GET_FLAGS_TRAILER(oop))
{
hcl_oow_t nbytes;
/* only an OOP object can have the trailer.
*
* | _flags |
* | _size | <-- if it's 3
* | _class |
* | X |
* | X |
* | X |
* | Y | <-- it may exist if EXTRA is set in _flags.
* | Z | <-- if TRAILER is set, it is the number of bytes in the trailer
* | | | | |
*/
HCL_ASSERT (HCL_OBJ_GET_FLAGS_TYPE(oop) == HCL_OBJ_TYPE_OOP);
HCL_ASSERT (HCL_OBJ_GET_FLAGS_UNIT(oop) == HCL_SIZEOF(hcl_oow_t));
HCL_ASSERT (HCL_OBJ_GET_FLAGS_EXTRA(oop) == 0); /* no 'extra' for an OOP object */
nbytes = HCL_OBJ_BYTESOF(oop) + HCL_SIZEOF(hcl_oow_t) + \
(hcl_oow_t)((hcl_oop_oop_t)oop)->slot[HCL_OBJ_GET_SIZE(oop)];
nbytes_aligned = HCL_ALIGN (nbytes, HCL_SIZEOF(hcl_oop_t));
}
else
{
#endif
/* calculate the payload size in bytes */
nbytes_aligned = HCL_ALIGN (HCL_OBJ_BYTESOF(oop), HCL_SIZEOF(hcl_oop_t));
#if defined(HCL_USE_OBJECT_TRAILER)
}
#endif
return nbytes_aligned;
}
hcl_oop_t hcl_moveoop (hcl_t* hcl, hcl_oop_t oop)
{
#if defined(HCL_SUPPORT_GC_DURING_IGNITION)
if (!oop) return oop;
#endif
if (!HCL_OOP_IS_POINTER(oop)) return oop;
if (HCL_OBJ_GET_FLAGS_NGC(oop)) return oop; /* non-GC object */
if (HCL_OBJ_GET_FLAGS_MOVED(oop))
{
/* this object has migrated to the new heap.
* the class field has been updated to the new object
* in the 'else' block below. i can simply return it
* without further migration. */
return HCL_OBJ_GET_CLASS(oop);
}
else
{
hcl_oow_t nbytes_aligned;
hcl_oop_t tmp;
nbytes_aligned = get_payload_bytes (hcl, oop);
/* allocate space in the new heap */
tmp = hcl_allocheapmem (hcl, hcl->newheap, HCL_SIZEOF(hcl_obj_t) + nbytes_aligned);
/* allocation here must not fail because
* i'm allocating the new space in a new heap for
* moving an existing object in the current heap.
*
* assuming the new heap is as large as the old heap,
* and garbage collection doesn't allocate more objects
* than in the old heap, it must not fail. */
HCL_ASSERT (tmp != HCL_NULL);
/* copy the payload to the new object */
HCL_MEMCPY (tmp, oop, HCL_SIZEOF(hcl_obj_t) + nbytes_aligned);
/* mark the old object that it has migrated to the new heap */
HCL_OBJ_SET_FLAGS_MOVED(oop, 1);
/* let the class field of the old object point to the new
* object allocated in the new heap. it is returned in
* the 'if' block at the top of this function. */
HCL_OBJ_SET_CLASS (oop, tmp);
/* return the new object */
return tmp;
}
}
static hcl_uint8_t* scan_new_heap (hcl_t* hcl, hcl_uint8_t* ptr)
{
while (ptr < hcl->newheap->ptr)
{
hcl_oow_t i;
hcl_oow_t nbytes_aligned;
hcl_oop_t oop;
oop = (hcl_oop_t)ptr;
#if defined(HCL_USE_OBJECT_TRAILER)
if (HCL_OBJ_GET_FLAGS_TRAILER(oop))
{
hcl_oow_t nbytes;
HCL_ASSERT (HCL_OBJ_GET_FLAGS_TYPE(oop) == HCL_OBJ_TYPE_OOP);
HCL_ASSERT (HCL_OBJ_GET_FLAGS_UNIT(oop) == HCL_SIZEOF(hcl_oow_t));
HCL_ASSERT (HCL_OBJ_GET_FLAGS_EXTRA(oop) == 0); /* no 'extra' for an OOP object */
nbytes = HCL_OBJ_BYTESOF(oop) + HCL_SIZEOF(hcl_oow_t) + \
(hcl_oow_t)((hcl_oop_oop_t)oop)->slot[HCL_OBJ_GET_SIZE(oop)];
nbytes_aligned = HCL_ALIGN (nbytes, HCL_SIZEOF(hcl_oop_t));
}
else
{
#endif
nbytes_aligned = HCL_ALIGN (HCL_OBJ_BYTESOF(oop), HCL_SIZEOF(hcl_oop_t));
#if defined(HCL_USE_OBJECT_TRAILER)
}
#endif
HCL_OBJ_SET_CLASS (oop, hcl_moveoop(hcl, HCL_OBJ_GET_CLASS(oop)));
if (HCL_OBJ_GET_FLAGS_TYPE(oop) == HCL_OBJ_TYPE_OOP)
{
hcl_oop_oop_t xtmp;
hcl_oow_t size;
if (HCL_OBJ_GET_FLAGS_BRAND(oop) == HCL_BRAND_PROCESS)
{
/* the stack in a process object doesn't need to be
* scanned in full. the slots above the stack pointer
* are garbages. */
size = HCL_PROCESS_NAMED_INSTVARS +
HCL_OOP_TO_SMOOI(((hcl_oop_process_t)oop)->sp) + 1;
HCL_ASSERT (size <= HCL_OBJ_GET_SIZE(oop));
}
else
{
size = HCL_OBJ_GET_SIZE(oop);
}
xtmp = (hcl_oop_oop_t)oop;
for (i = 0; i < size; i++)
{
if (HCL_OOP_IS_POINTER(xtmp->slot[i]))
xtmp->slot[i] = hcl_moveoop (hcl, xtmp->slot[i]);
}
}
ptr = ptr + HCL_SIZEOF(hcl_obj_t) + nbytes_aligned;
}
/* return the pointer to the beginning of the free space in the heap */
return ptr;
}
void hcl_gc (hcl_t* hcl)
{
/*
* move a referenced object to the new heap.
* inspect the fields of the moved object in the new heap.
* move objects pointed to by the fields to the new heap.
* finally perform some tricky symbol table clean-up.
*/
hcl_uint8_t* ptr;
hcl_heap_t* tmp;
hcl_oop_t old_nil;
hcl_oow_t i;
hcl_cb_t* cb;
if (hcl->active_context)
{
/*HCL_ASSERT ((hcl_oop_t)hcl->processor != hcl->_nil);
if ((hcl_oop_t)hcl->processor->active != hcl->_nil)*/
hcl->processor->active->sp = HCL_SMOOI_TO_OOP(hcl->sp);
/* store the instruction pointer to the active context */
hcl->active_context->ip = HCL_SMOOI_TO_OOP(hcl->ip);
}
HCL_LOG4 (hcl, HCL_LOG_GC | HCL_LOG_INFO,
"Starting GC curheap base %p ptr %p newheap base %p ptr %p\n",
hcl->curheap->base, hcl->curheap->ptr, hcl->newheap->base, hcl->newheap->ptr);
/* TODO: allocate common objects like _nil and the root dictionary
* in the permanant heap. minimize moving around */
old_nil = hcl->_nil;
/* move _nil and the root object table */
hcl->_nil = hcl_moveoop (hcl, hcl->_nil);
hcl->_true = hcl_moveoop (hcl, hcl->_true);
hcl->_false = hcl_moveoop (hcl, hcl->_false);
for (i = 0; i < HCL_COUNTOF(syminfo); i++)
{
hcl_oop_t tmp;
tmp = *(hcl_oop_t*)((hcl_uint8_t*)hcl + syminfo[i].offset);
tmp = hcl_moveoop (hcl, tmp);
*(hcl_oop_t*)((hcl_uint8_t*)hcl + syminfo[i].offset) = tmp;
}
hcl->_class = hcl_moveoop (hcl, hcl->_class);
hcl->_character = hcl_moveoop (hcl, hcl->_character);
hcl->_small_integer = hcl_moveoop (hcl, hcl->_small_integer);
hcl->_large_positive_integer = hcl_moveoop (hcl, hcl->_large_positive_integer);
hcl->_large_negative_integer = hcl_moveoop (hcl, hcl->_large_negative_integer);
hcl->sysdic = (hcl_oop_set_t) hcl_moveoop (hcl, (hcl_oop_t)hcl->sysdic);
hcl->processor = (hcl_oop_process_scheduler_t) hcl_moveoop (hcl, (hcl_oop_t)hcl->processor);
hcl->nil_process = (hcl_oop_process_t) hcl_moveoop (hcl, (hcl_oop_t)hcl->nil_process);
for (i = 0; i < hcl->code.lit.len; i++)
{
((hcl_oop_oop_t)hcl->code.lit.arr)->slot[i] =
hcl_moveoop (hcl, ((hcl_oop_oop_t)hcl->code.lit.arr)->slot[i]);
}
hcl->p.e = hcl_moveoop (hcl, hcl->p.e);
for (i = 0; i < hcl->sem_list_count; i++)
{
hcl->sem_list[i] = (hcl_oop_semaphore_t)hcl_moveoop (hcl, (hcl_oop_t)hcl->sem_list[i]);
}
for (i = 0; i < hcl->sem_heap_count; i++)
{
hcl->sem_heap[i] = (hcl_oop_semaphore_t)hcl_moveoop (hcl, (hcl_oop_t)hcl->sem_heap[i]);
}
for (i = 0; i < hcl->tmp_count; i++)
{
*hcl->tmp_stack[i] = hcl_moveoop (hcl, *hcl->tmp_stack[i]);
}
if (hcl->active_context)
hcl->active_context = (hcl_oop_context_t)hcl_moveoop (hcl, (hcl_oop_t)hcl->active_context);
if (hcl->active_method)
hcl->active_method = (hcl_oop_method_t)hcl_moveoop (hcl, (hcl_oop_t)hcl->active_method);
for (cb = hcl->cblist; cb; cb = cb->next)
{
if (cb->gc) cb->gc (hcl);
}
/* scan the new heap to move referenced objects */
ptr = (hcl_uint8_t*) HCL_ALIGN ((hcl_uintptr_t)hcl->newheap->base, HCL_SIZEOF(hcl_oop_t));
ptr = scan_new_heap (hcl, ptr);
/* traverse the symbol table for unreferenced symbols.
* if the symbol has not moved to the new heap, the symbol
* is not referenced by any other objects than the symbol
* table itself */
compact_symbol_table (hcl, old_nil);
/* move the symbol table itself */
hcl->symtab = (hcl_oop_set_t)hcl_moveoop (hcl, (hcl_oop_t)hcl->symtab);
/* scan the new heap again from the end position of
* the previous scan to move referenced objects by
* the symbol table. */
ptr = scan_new_heap (hcl, ptr);
/* the contents of the current heap is not needed any more.
* reset the upper bound to the base. don't forget to align the heap
* pointer to the OOP size. See hcl_makeheap() also */
hcl->curheap->ptr = (hcl_uint8_t*)HCL_ALIGN(((hcl_uintptr_t)hcl->curheap->base), HCL_SIZEOF(hcl_oop_t));
/* swap the current heap and old heap */
tmp = hcl->curheap;
hcl->curheap = hcl->newheap;
hcl->newheap = tmp;
/*
{
hcl_oow_t index;
hcl_oop_oop_t buc;
printf ("=== SURVIVING SYMBOLS ===\n");
buc = (hcl_oop_oop_t) hcl->symtab->slot[HCL_SYMTAB_BUCKET];
for (index = 0; index < buc->size; index++)
{
if ((hcl_oop_t)buc->slot[index] != hcl->_nil)
{
const hcl_oop_char_t* p = ((hcl_oop_char_t)buc->slot[index])->slot;
printf ("SYM [");
while (*p) printf ("%c", *p++);
printf ("]\n");
}
}
printf ("===========================\n");
}
*/
if (hcl->active_method) SET_ACTIVE_METHOD_CODE (hcl); /* update hcl->active_code */
}
void hcl_pushtmp (hcl_t* hcl, hcl_oop_t* oop_ptr)
{
/* if you have too many temporaries pushed, something must be wrong.
* change your code not to exceede the stack limit */
HCL_ASSERT (hcl->tmp_count < HCL_COUNTOF(hcl->tmp_stack));
hcl->tmp_stack[hcl->tmp_count++] = oop_ptr;
}
void hcl_poptmp (hcl_t* hcl)
{
HCL_ASSERT (hcl->tmp_count > 0);
hcl->tmp_count--;
}
void hcl_poptmps (hcl_t* hcl, hcl_oow_t count)
{
HCL_ASSERT (hcl->tmp_count >= count);
hcl->tmp_count -= count;
}
hcl_oop_t hcl_shallowcopy (hcl_t* hcl, hcl_oop_t oop)
{
if (HCL_OOP_IS_POINTER(oop) && HCL_OBJ_GET_FLAGS_BRAND(oop) != HCL_BRAND_SYMBOL)
{
hcl_oop_t z;
hcl_oow_t total_bytes;
total_bytes = HCL_SIZEOF(hcl_obj_t) + get_payload_bytes(hcl, oop);
hcl_pushtmp (hcl, &oop);
z = hcl_allocbytes (hcl, total_bytes);
hcl_poptmp(hcl);
HCL_MEMCPY (z, oop, total_bytes);
return z;
}
return oop;
}
/* ========================================================================= */
int hcl_ignite (hcl_t* hcl)
{
hcl_oow_t i;
if (!hcl->_nil)
{
hcl->_nil = hcl_makenil (hcl);
if (!hcl->_nil) return -1;
}
if (!hcl->_true)
{
hcl->_true = hcl_maketrue (hcl);
if (!hcl->_true) return -1;
}
if (!hcl->_false)
{
hcl->_false = hcl_makefalse (hcl);
if (!hcl->_false) return -1;
}
if (!hcl->symtab)
{
hcl->symtab = (hcl_oop_set_t)hcl_makeset (hcl, hcl->option.dfl_symtab_size);
if (!hcl->symtab) return -1;
}
if (!hcl->sysdic)
{
hcl->sysdic = (hcl_oop_set_t)hcl_makeset (hcl, hcl->option.dfl_sysdic_size);
if (!hcl->sysdic) return -1;
}
/* symbol table available now. symbols can be created */
for (i = 0; i < HCL_COUNTOF(syminfo); i++)
{
hcl_oop_t tmp;
tmp = hcl_makesymbol (hcl, syminfo[i].ptr, syminfo[i].len);
if (!tmp) return -1;
HCL_OBJ_SET_FLAGS_SYNCODE (tmp, syminfo[i].syncode);
*(hcl_oop_t*)((hcl_uint8_t*)hcl + syminfo[i].offset) = tmp;
}
if (!hcl->code.bc.arr)
{
hcl->code.bc.arr = hcl_makengcbytearray (hcl, HCL_NULL, 20000); /* TODO: set a proper intial size */
if (!hcl->code.bc.arr) return -1;
}
if (!hcl->code.lit.arr)
{
hcl->code.lit.arr = hcl_makengcarray (hcl, 20000); /* TOOD: set a proper initial size */
if (!hcl->code.lit.arr) return -1;
}
hcl->p.e = hcl->_nil;
return 0;
}

711
lib/hcl-cmn.h Normal file
View File

@ -0,0 +1,711 @@
/*
* $Id$
*
Copyright (c) 2014-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _HCL_CMN_H_
#define _HCL_CMN_H_
/* WARNING: NEVER CHANGE/DELETE THE FOLLOWING HCL_HAVE_CFG_H DEFINITION.
* IT IS USED FOR DEPLOYMENT BY MAKEFILE.AM */
/*#define HCL_HAVE_CFG_H*/
#if defined(HCL_HAVE_CFG_H)
# include "hcl-cfg.h"
#elif defined(_WIN32)
# include "hcl-msw.h"
#elif defined(__OS2__)
# include "hcl-os2.h"
#elif defined(__MSDOS__)
# include "hcl-dos.h"
#elif defined(macintosh)
# include "hcl-mac.h" /* class mac os */
#else
# error UNSUPPORTED SYSTEM
#endif
#if defined(EMSCRIPTEN)
# if defined(HCL_SIZEOF___INT128)
# undef HCL_SIZEOF___INT128
# define HCL_SIZEOF___INT128 0
# endif
# if defined(HCL_SIZEOF_LONG) && defined(HCL_SIZEOF_INT) && (HCL_SIZEOF_LONG > HCL_SIZEOF_INT)
/* autoconf doesn't seem to match actual emscripten */
# undef HCL_SIZEOF_LONG
# define HCL_SIZEOF_LONG HCL_SIZEOF_INT
# endif
#endif
/* =========================================================================
* PRIMITIVE TYPE DEFINTIONS
* ========================================================================= */
/* hcl_int8_t */
#if defined(HCL_SIZEOF_CHAR) && (HCL_SIZEOF_CHAR == 1)
# define HCL_HAVE_UINT8_T
# define HCL_HAVE_INT8_T
typedef unsigned char hcl_uint8_t;
typedef signed char hcl_int8_t;
#elif defined(HCL_SIZEOF___INT8) && (HCL_SIZEOF___INT8 == 1)
# define HCL_HAVE_UINT8_T
# define HCL_HAVE_INT8_T
typedef unsigned __int8 hcl_uint8_t;
typedef signed __int8 hcl_int8_t;
#elif defined(HCL_SIZEOF___INT8_T) && (HCL_SIZEOF___INT8_T == 1)
# define HCL_HAVE_UINT8_T
# define HCL_HAVE_INT8_T
typedef unsigned __int8_t hcl_uint8_t;
typedef signed __int8_t hcl_int8_t;
#else
# define HCL_HAVE_UINT8_T
# define HCL_HAVE_INT8_T
typedef unsigned char hcl_uint8_t;
typedef signed char hcl_int8_t;
#endif
/* hcl_int16_t */
#if defined(HCL_SIZEOF_SHORT) && (HCL_SIZEOF_SHORT == 2)
# define HCL_HAVE_UINT16_T
# define HCL_HAVE_INT16_T
typedef unsigned short int hcl_uint16_t;
typedef signed short int hcl_int16_t;
#elif defined(HCL_SIZEOF___INT16) && (HCL_SIZEOF___INT16 == 2)
# define HCL_HAVE_UINT16_T
# define HCL_HAVE_INT16_T
typedef unsigned __int16 hcl_uint16_t;
typedef signed __int16 hcl_int16_t;
#elif defined(HCL_SIZEOF___INT16_T) && (HCL_SIZEOF___INT16_T == 2)
# define HCL_HAVE_UINT16_T
# define HCL_HAVE_INT16_T
typedef unsigned __int16_t hcl_uint16_t;
typedef signed __int16_t hcl_int16_t;
#else
# define HCL_HAVE_UINT16_T
# define HCL_HAVE_INT16_T
typedef unsigned short int hcl_uint16_t;
typedef signed short int hcl_int16_t;
#endif
/* hcl_int32_t */
#if defined(HCL_SIZEOF_INT) && (HCL_SIZEOF_INT == 4)
# define HCL_HAVE_UINT32_T
# define HCL_HAVE_INT32_T
typedef unsigned int hcl_uint32_t;
typedef signed int hcl_int32_t;
#elif defined(HCL_SIZEOF_LONG) && (HCL_SIZEOF_LONG == 4)
# define HCL_HAVE_UINT32_T
# define HCL_HAVE_INT32_T
typedef unsigned long hcl_uint32_t;
typedef signed long hcl_int32_t;
#elif defined(HCL_SIZEOF___INT32) && (HCL_SIZEOF___INT32 == 4)
# define HCL_HAVE_UINT32_T
# define HCL_HAVE_INT32_T
typedef unsigned __int32 hcl_uint32_t;
typedef signed __int32 hcl_int32_t;
#elif defined(HCL_SIZEOF___INT32_T) && (HCL_SIZEOF___INT32_T == 4)
# define HCL_HAVE_UINT32_T
# define HCL_HAVE_INT32_T
typedef unsigned __int32_t hcl_uint32_t;
typedef signed __int32_t hcl_int32_t;
#elif defined(__MSDOS__)
# define HCL_HAVE_UINT32_T
# define HCL_HAVE_INT32_T
typedef unsigned long int hcl_uint32_t;
typedef signed long int hcl_int32_t;
#else
# define HCL_HAVE_UINT32_T
# define HCL_HAVE_INT32_T
typedef unsigned int hcl_uint32_t;
typedef signed int hcl_int32_t;
#endif
/* hcl_int64_t */
#if defined(HCL_SIZEOF_INT) && (HCL_SIZEOF_INT == 8)
# define HCL_HAVE_UINT64_T
# define HCL_HAVE_INT64_T
typedef unsigned int hcl_uint64_t;
typedef signed int hcl_int64_t;
#elif defined(HCL_SIZEOF_LONG) && (HCL_SIZEOF_LONG == 8)
# define HCL_HAVE_UINT64_T
# define HCL_HAVE_INT64_T
typedef unsigned long hcl_uint64_t;
typedef signed long hcl_int64_t;
#elif defined(HCL_SIZEOF_LONG_LONG) && (HCL_SIZEOF_LONG_LONG == 8)
# define HCL_HAVE_UINT64_T
# define HCL_HAVE_INT64_T
typedef unsigned long long hcl_uint64_t;
typedef signed long long hcl_int64_t;
#elif defined(HCL_SIZEOF___INT64) && (HCL_SIZEOF___INT64 == 8)
# define HCL_HAVE_UINT64_T
# define HCL_HAVE_INT64_T
typedef unsigned __int64 hcl_uint64_t;
typedef signed __int64 hcl_int64_t;
#elif defined(HCL_SIZEOF___INT64_T) && (HCL_SIZEOF___INT64_T == 8)
# define HCL_HAVE_UINT64_T
# define HCL_HAVE_INT64_T
typedef unsigned __int64_t hcl_uint64_t;
typedef signed __int64_t hcl_int64_t;
#else
/* no 64-bit integer */
#endif
/* hcl_int128_t */
#if defined(HCL_SIZEOF_INT) && (HCL_SIZEOF_INT == 16)
# define HCL_HAVE_UINT128_T
# define HCL_HAVE_INT128_T
typedef unsigned int hcl_uint128_t;
typedef signed int hcl_int128_t;
#elif defined(HCL_SIZEOF_LONG) && (HCL_SIZEOF_LONG == 16)
# define HCL_HAVE_UINT128_T
# define HCL_HAVE_INT128_T
typedef unsigned long hcl_uint128_t;
typedef signed long hcl_int128_t;
#elif defined(HCL_SIZEOF_LONG_LONG) && (HCL_SIZEOF_LONG_LONG == 16)
# define HCL_HAVE_UINT128_T
# define HCL_HAVE_INT128_T
typedef unsigned long long hcl_uint128_t;
typedef signed long long hcl_int128_t;
#elif defined(HCL_SIZEOF___INT128) && (HCL_SIZEOF___INT128 == 16)
# define HCL_HAVE_UINT128_T
# define HCL_HAVE_INT128_T
typedef unsigned __int128 hcl_uint128_t;
typedef signed __int128 hcl_int128_t;
#elif defined(HCL_SIZEOF___INT128_T) && (HCL_SIZEOF___INT128_T == 16)
# define HCL_HAVE_UINT128_T
# define HCL_HAVE_INT128_T
#if defined(__clang__)
typedef __uint128_t hcl_uint128_t;
typedef __int128_t hcl_int128_t;
#else
typedef unsigned __int128_t hcl_uint128_t;
typedef signed __int128_t hcl_int128_t;
#endif
#else
/* no 128-bit integer */
#endif
#if defined(HCL_HAVE_UINT8_T) && (HCL_SIZEOF_VOID_P == 1)
# error UNSUPPORTED POINTER SIZE
#elif defined(HCL_HAVE_UINT16_T) && (HCL_SIZEOF_VOID_P == 2)
typedef hcl_uint16_t hcl_uintptr_t;
typedef hcl_int16_t hcl_intptr_t;
typedef hcl_uint8_t hcl_ushortptr_t;
typedef hcl_int8_t hcl_shortptr_t;
#elif defined(HCL_HAVE_UINT32_T) && (HCL_SIZEOF_VOID_P == 4)
typedef hcl_uint32_t hcl_uintptr_t;
typedef hcl_int32_t hcl_intptr_t;
typedef hcl_uint16_t hcl_ushortptr_t;
typedef hcl_int16_t hcl_shortptr_t;
#elif defined(HCL_HAVE_UINT64_T) && (HCL_SIZEOF_VOID_P == 8)
typedef hcl_uint64_t hcl_uintptr_t;
typedef hcl_int64_t hcl_intptr_t;
typedef hcl_uint32_t hcl_ushortptr_t;
typedef hcl_int32_t hcl_shortptr_t;
#elif defined(HCL_HAVE_UINT128_T) && (HCL_SIZEOF_VOID_P == 16)
typedef hcl_uint128_t hcl_uintptr_t;
typedef hcl_int128_t hcl_intptr_t;
typedef hcl_uint64_t hcl_ushortptr_t;
typedef hcl_int64_t hcl_shortptr_t;
#else
# error UNKNOWN POINTER SIZE
#endif
#define HCL_SIZEOF_INTPTR_T HCL_SIZEOF_VOID_P
#define HCL_SIZEOF_UINTPTR_T HCL_SIZEOF_VOID_P
#define HCL_SIZEOF_SHORTPTR_T (HCL_SIZEOF_VOID_P / 2)
#define HCL_SIZEOF_USHORTPTR_T (HCL_SIZEOF_VOID_P / 2)
#if defined(HCL_HAVE_INT128_T)
# define HCL_SIZEOF_INTMAX_T 16
# define HCL_SIZEOF_UINTMAX_T 16
typedef hcl_int128_t hcl_intmax_t;
typedef hcl_uint128_t hcl_uintmax_t;
#elif defined(HCL_HAVE_INT64_T)
# define HCL_SIZEOF_INTMAX_T 8
# define HCL_SIZEOF_UINTMAX_T 8
typedef hcl_int64_t hcl_intmax_t;
typedef hcl_uint64_t hcl_uintmax_t;
#elif defined(HCL_HAVE_INT32_T)
# define HCL_SIZEOF_INTMAX_T 4
# define HCL_SIZEOF_UINTMAX_T 4
typedef hcl_int32_t hcl_intmax_t;
typedef hcl_uint32_t hcl_uintmax_t;
#elif defined(HCL_HAVE_INT16_T)
# define HCL_SIZEOF_INTMAX_T 2
# define HCL_SIZEOF_UINTMAX_T 2
typedef hcl_int16_t hcl_intmax_t;
typedef hcl_uint16_t hcl_uintmax_t;
#elif defined(HCL_HAVE_INT8_T)
# define HCL_SIZEOF_INTMAX_T 1
# define HCL_SIZEOF_UINTMAX_T 1
typedef hcl_int8_t hcl_intmax_t;
typedef hcl_uint8_t hcl_uintmax_t;
#else
# error UNKNOWN INTMAX SIZE
#endif
/* =========================================================================
* BASIC HCL TYPES
* =========================================================================*/
typedef char hcl_bch_t;
typedef int hcl_bci_t;
typedef hcl_uint16_t hcl_uch_t; /* TODO ... wchar_t??? */
typedef hcl_int32_t hcl_uci_t;
typedef hcl_uint8_t hcl_oob_t;
/* NOTE: sizeof(hcl_oop_t) must be equal to sizeof(hcl_oow_t) */
typedef hcl_uintptr_t hcl_oow_t;
typedef hcl_intptr_t hcl_ooi_t;
#define HCL_SIZEOF_OOW_T HCL_SIZEOF_UINTPTR_T
#define HCL_SIZEOF_OOI_T HCL_SIZEOF_INTPTR_T
typedef hcl_ushortptr_t hcl_oohw_t; /* half word - half word */
typedef hcl_shortptr_t hcl_oohi_t; /* signed half word */
#define HCL_SIZEOF_OOHW_T HCL_SIZEOF_USHORTPTR_T
#define HCL_SIZEOF_OOHI_T HCL_SIZEOF_SHORTPTR_T
struct hcl_ucs_t
{
hcl_uch_t* ptr;
hcl_oow_t len;
};
typedef struct hcl_ucs_t hcl_ucs_t;
struct hcl_bcs_t
{
hcl_bch_t* ptr;
hcl_oow_t len;
};
typedef struct hcl_bcs_t hcl_bcs_t;
typedef hcl_uch_t hcl_ooch_t;
typedef hcl_uci_t hcl_ooci_t;
typedef hcl_ucs_t hcl_oocs_t;
#define HCL_OOCH_IS_UCH
/* =========================================================================
* TIME-RELATED TYPES
* =========================================================================*/
#define HCL_MSECS_PER_SEC (1000)
#define HCL_MSECS_PER_MIN (HCL_MSECS_PER_SEC * HCL_SECS_PER_MIN)
#define HCL_MSECS_PER_HOUR (HCL_MSECS_PER_SEC * HCL_SECS_PER_HOUR)
#define HCL_MSECS_PER_DAY (HCL_MSECS_PER_SEC * HCL_SECS_PER_DAY)
#define HCL_USECS_PER_MSEC (1000)
#define HCL_NSECS_PER_USEC (1000)
#define HCL_NSECS_PER_MSEC (HCL_NSECS_PER_USEC * HCL_USECS_PER_MSEC)
#define HCL_USECS_PER_SEC (HCL_USECS_PER_MSEC * HCL_MSECS_PER_SEC)
#define HCL_NSECS_PER_SEC (HCL_NSECS_PER_USEC * HCL_USECS_PER_MSEC * HCL_MSECS_PER_SEC)
#define HCL_SECNSEC_TO_MSEC(sec,nsec) \
(((hcl_intptr_t)(sec) * HCL_MSECS_PER_SEC) + ((hcl_intptr_t)(nsec) / HCL_NSECS_PER_MSEC))
#define HCL_SECNSEC_TO_USEC(sec,nsec) \
(((hcl_intptr_t)(sec) * HCL_USECS_PER_SEC) + ((hcl_intptr_t)(nsec) / HCL_NSECS_PER_USEC))
#define HCL_SECNSEC_TO_NSEC(sec,nsec) \
(((hcl_intptr_t)(sec) * HCL_NSECS_PER_SEC) + (hcl_intptr_t)(nsec))
#define HCL_SEC_TO_MSEC(sec) ((sec) * HCL_MSECS_PER_SEC)
#define HCL_MSEC_TO_SEC(sec) ((sec) / HCL_MSECS_PER_SEC)
#define HCL_USEC_TO_NSEC(usec) ((usec) * HCL_NSECS_PER_USEC)
#define HCL_NSEC_TO_USEC(nsec) ((nsec) / HCL_NSECS_PER_USEC)
#define HCL_MSEC_TO_NSEC(msec) ((msec) * HCL_NSECS_PER_MSEC)
#define HCL_NSEC_TO_MSEC(nsec) ((nsec) / HCL_NSECS_PER_MSEC)
#define HCL_SEC_TO_NSEC(sec) ((sec) * HCL_NSECS_PER_SEC)
#define HCL_NSEC_TO_SEC(nsec) ((nsec) / HCL_NSECS_PER_SEC)
#define HCL_SEC_TO_USEC(sec) ((sec) * HCL_USECS_PER_SEC)
#define HCL_USEC_TO_SEC(usec) ((usec) / HCL_USECS_PER_SEC)
typedef struct hcl_ntime_t hcl_ntime_t;
struct hcl_ntime_t
{
hcl_intptr_t sec;
hcl_int32_t nsec; /* nanoseconds */
};
#define HCL_INITNTIME(c,s,ns) (((c)->sec = (s)), ((c)->nsec = (ns)))
#define HCL_CLEARNTIME(c) HCL_INITNTIME(c, 0, 0)
#define HCL_ADDNTIME(c,a,b) \
do { \
(c)->sec = (a)->sec + (b)->sec; \
(c)->nsec = (a)->nsec + (b)->nsec; \
while ((c)->nsec >= HCL_NSECS_PER_SEC) { (c)->sec++; (c)->nsec -= HCL_NSECS_PER_SEC; } \
} while(0)
#define HCL_ADDNTIMESNS(c,a,s,ns) \
do { \
(c)->sec = (a)->sec + (s); \
(c)->nsec = (a)->nsec + (ns); \
while ((c)->nsec >= HCL_NSECS_PER_SEC) { (c)->sec++; (c)->nsec -= HCL_NSECS_PER_SEC; } \
} while(0)
#define HCL_SUBNTIME(c,a,b) \
do { \
(c)->sec = (a)->sec - (b)->sec; \
(c)->nsec = (a)->nsec - (b)->nsec; \
while ((c)->nsec < 0) { (c)->sec--; (c)->nsec += HCL_NSECS_PER_SEC; } \
} while(0)
#define HCL_SUBNTIMESNS(c,a,s,ns) \
do { \
(c)->sec = (a)->sec - s; \
(c)->nsec = (a)->nsec - ns; \
while ((c)->nsec < 0) { (c)->sec--; (c)->nsec += HCL_NSECS_PER_SEC; } \
} while(0)
#define HCL_CMPNTIME(a,b) (((a)->sec == (b)->sec)? ((a)->nsec - (b)->nsec): ((a)->sec - (b)->sec))
/* =========================================================================
* PRIMITIVE MACROS
* ========================================================================= */
#define HCL_UCI_EOF ((hcl_ooci_t)-1)
#define HCL_UCI_NL ((hcl_ooci_t)'\n')
#define HCL_SIZEOF(x) (sizeof(x))
#define HCL_COUNTOF(x) (sizeof(x) / sizeof(x[0]))
/**
* The HCL_OFFSETOF() macro returns the offset of a field from the beginning
* of a structure.
*/
#define HCL_OFFSETOF(type,member) ((hcl_uintptr_t)&((type*)0)->member)
/**
* The HCL_ALIGNOF() macro returns the alignment size of a structure.
* Note that this macro may not work reliably depending on the type given.
*/
#define HCL_ALIGNOF(type) HCL_OFFSETOF(struct { hcl_uint8_t d1; type d2; }, d2)
/*(sizeof(struct { hcl_uint8_t d1; type d2; }) - sizeof(type))*/
#if defined(__cplusplus)
# if (__cplusplus >= 201103L) /* C++11 */
# define HCL_NULL nullptr
# else
# define HCL_NULL (0)
# endif
#else
# define HCL_NULL ((void*)0)
#endif
/* make a bit mask that can mask off low n bits */
#define HCL_LBMASK(type,n) (~(~((type)0) << (n)))
#define HCL_LBMASK_SAFE(type,n) (((n) < HCL_SIZEOF(type) * 8)? HCL_LBMASK(type,n): ~(type)0)
/* make a bit mask that can mask off hig n bits */
#define HCL_HBMASK(type,n) (~(~((type)0) >> (n)))
#define HCL_HBMASK_SAFE(type,n) (((n) < HCL_SIZEOF(type) * 8)? HCL_HBMASK(type,n): ~(type)0)
/* get 'length' bits starting from the bit at the 'offset' */
#define HCL_GETBITS(type,value,offset,length) \
((((type)(value)) >> (offset)) & HCL_LBMASK(type,length))
#define HCL_SETBITS(type,value,offset,length,bits) \
(value = (((type)(value)) | (((bits) & HCL_LBMASK(type,length)) << (offset))))
/**
* The HCL_BITS_MAX() macros calculates the maximum value that the 'nbits'
* bits of an unsigned integer of the given 'type' can hold.
* \code
* printf ("%u", HCL_BITS_MAX(unsigned int, 5));
* \endcode
*/
/*#define HCL_BITS_MAX(type,nbits) ((((type)1) << (nbits)) - 1)*/
#define HCL_BITS_MAX(type,nbits) ((~(type)0) >> (HCL_SIZEOF(type) * 8 - (nbits)))
/* =========================================================================
* MMGR
* ========================================================================= */
typedef struct hcl_mmgr_t hcl_mmgr_t;
/**
* allocate a memory chunk of the size \a n.
* \return pointer to a memory chunk on success, #HCL_NULL on failure.
*/
typedef void* (*hcl_mmgr_alloc_t) (hcl_mmgr_t* mmgr, hcl_oow_t n);
/**
* resize a memory chunk pointed to by \a ptr to the size \a n.
* \return pointer to a memory chunk on success, #HCL_NULL on failure.
*/
typedef void* (*hcl_mmgr_realloc_t) (hcl_mmgr_t* mmgr, void* ptr, hcl_oow_t n);
/**
* free a memory chunk pointed to by \a ptr.
*/
typedef void (*hcl_mmgr_free_t) (hcl_mmgr_t* mmgr, void* ptr);
/**
* The hcl_mmgr_t type defines the memory management interface.
* As the type is merely a structure, it is just used as a single container
* for memory management functions with a pointer to user-defined data.
* The user-defined data pointer \a ctx is passed to each memory management
* function whenever it is called. You can allocate, reallocate, and free
* a memory chunk.
*
* For example, a hcl_xxx_open() function accepts a pointer of the hcl_mmgr_t
* type and the xxx object uses it to manage dynamic data within the object.
*/
struct hcl_mmgr_t
{
hcl_mmgr_alloc_t alloc; /**< allocation function */
hcl_mmgr_realloc_t realloc; /**< resizing function */
hcl_mmgr_free_t free; /**< disposal function */
void* ctx; /**< user-defined data pointer */
};
/**
* The HCL_MMGR_ALLOC() macro allocates a memory block of the \a size bytes
* using the \a mmgr memory manager.
*/
#define HCL_MMGR_ALLOC(mmgr,size) ((mmgr)->alloc(mmgr,size))
/**
* The HCL_MMGR_REALLOC() macro resizes a memory block pointed to by \a ptr
* to the \a size bytes using the \a mmgr memory manager.
*/
#define HCL_MMGR_REALLOC(mmgr,ptr,size) ((mmgr)->realloc(mmgr,ptr,size))
/**
* The HCL_MMGR_FREE() macro deallocates the memory block pointed to by \a ptr.
*/
#define HCL_MMGR_FREE(mmgr,ptr) ((mmgr)->free(mmgr,ptr))
/* =========================================================================
* CMGR
* =========================================================================*/
typedef struct hcl_cmgr_t hcl_cmgr_t;
typedef hcl_oow_t (*hcl_cmgr_bctouc_t) (
const hcl_bch_t* mb,
hcl_oow_t size,
hcl_uch_t* wc
);
typedef hcl_oow_t (*hcl_cmgr_uctobc_t) (
hcl_uch_t wc,
hcl_bch_t* mb,
hcl_oow_t size
);
/**
* The hcl_cmgr_t type defines the character-level interface to
* multibyte/wide-character conversion. This interface doesn't
* provide any facility to store conversion state in a context
* independent manner. This leads to the limitation that it can
* handle a stateless multibyte encoding only.
*/
struct hcl_cmgr_t
{
hcl_cmgr_bctouc_t bctouc;
hcl_cmgr_uctobc_t uctobc;
};
/* =========================================================================
* MACROS THAT CHANGES THE BEHAVIORS OF THE C COMPILER/LINKER
* =========================================================================*/
#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
# define HCL_IMPORT
# define HCL_EXPORT
# define HCL_PRIVATE
#elif defined(_WIN32) || (defined(__WATCOMC__) && !defined(__WINDOWS_386__))
# define HCL_IMPORT __declspec(dllimport)
# define HCL_EXPORT __declspec(dllexport)
# define HCL_PRIVATE
#elif defined(__GNUC__) && (__GNUC__>=4)
# define HCL_IMPORT __attribute__((visibility("default")))
# define HCL_EXPORT __attribute__((visibility("default")))
# define HCL_PRIVATE __attribute__((visibility("hidden")))
/*# define HCL_PRIVATE __attribute__((visibility("internal")))*/
#else
# define HCL_IMPORT
# define HCL_EXPORT
# define HCL_PRIVATE
#endif
#if defined(__STDC_VERSION__) && (__STDC_VERSION__>=199901L)
/* C99 has inline */
# define HCL_INLINE inline
# define HCL_HAVE_INLINE
#elif defined(__GNUC__) && defined(__GNUC_GNU_INLINE__)
/* gcc disables inline when -std=c89 or -ansi is used.
* so use __inline__ supported by gcc regardless of the options */
# define HCL_INLINE /*extern*/ __inline__
# define HCL_HAVE_INLINE
#else
# define HCL_INLINE
# undef HCL_HAVE_INLINE
#endif
/**
* The HCL_TYPE_IS_SIGNED() macro determines if a type is signed.
* \code
* printf ("%d\n", (int)HCL_TYPE_IS_SIGNED(int));
* printf ("%d\n", (int)HCL_TYPE_IS_SIGNED(unsigned int));
* \endcode
*/
#define HCL_TYPE_IS_SIGNED(type) (((type)0) > ((type)-1))
/**
* The HCL_TYPE_IS_SIGNED() macro determines if a type is unsigned.
* \code
* printf ("%d\n", HCL_TYPE_IS_UNSIGNED(int));
* printf ("%d\n", HCL_TYPE_IS_UNSIGNED(unsigned int));
* \endcode
*/
#define HCL_TYPE_IS_UNSIGNED(type) (((type)0) < ((type)-1))
#define HCL_TYPE_SIGNED_MAX(type) \
((type)~((type)1 << ((type)HCL_SIZEOF(type) * 8 - 1)))
#define HCL_TYPE_UNSIGNED_MAX(type) ((type)(~(type)0))
#define HCL_TYPE_SIGNED_MIN(type) \
((type)((type)1 << ((type)HCL_SIZEOF(type) * 8 - 1)))
#define HCL_TYPE_UNSIGNED_MIN(type) ((type)0)
#define HCL_TYPE_MAX(type) \
((HCL_TYPE_IS_SIGNED(type)? HCL_TYPE_SIGNED_MAX(type): HCL_TYPE_UNSIGNED_MAX(type)))
#define HCL_TYPE_MIN(type) \
((HCL_TYPE_IS_SIGNED(type)? HCL_TYPE_SIGNED_MIN(type): HCL_TYPE_UNSIGNED_MIN(type)))
/* =========================================================================
* COMPILER FEATURE TEST MACROS
* =========================================================================*/
#if !defined(__has_builtin) && defined(_INTELC32_)
/* intel c code builder 1.0 ended up with an error without this override */
#define __has_builtin(x) 0
#endif
/*
#if !defined(__is_identifier)
#define __is_identifier(x) 0
#endif
#if !defined(__has_attribute)
#define __has_attribute(x) 0
#endif
*/
#if defined(__has_builtin)
#if __has_builtin(__builtin_ctz)
#define HCL_HAVE_BUILTIN_CTZ
#endif
#if __has_builtin(__builtin_uadd_overflow)
#define HCL_HAVE_BUILTIN_UADD_OVERFLOW
#endif
#if __has_builtin(__builtin_uaddl_overflow)
#define HCL_HAVE_BUILTIN_UADDL_OVERFLOW
#endif
#if __has_builtin(__builtin_uaddll_overflow)
#define HCL_HAVE_BUILTIN_UADDLL_OVERFLOW
#endif
#if __has_builtin(__builtin_umul_overflow)
#define HCL_HAVE_BUILTIN_UMUL_OVERFLOW
#endif
#if __has_builtin(__builtin_umull_overflow)
#define HCL_HAVE_BUILTIN_UMULL_OVERFLOW
#endif
#if __has_builtin(__builtin_umulll_overflow)
#define HCL_HAVE_BUILTIN_UMULLL_OVERFLOW
#endif
#if __has_builtin(__builtin_sadd_overflow)
#define HCL_HAVE_BUILTIN_SADD_OVERFLOW
#endif
#if __has_builtin(__builtin_saddl_overflow)
#define HCL_HAVE_BUILTIN_SADDL_OVERFLOW
#endif
#if __has_builtin(__builtin_saddll_overflow)
#define HCL_HAVE_BUILTIN_SADDLL_OVERFLOW
#endif
#if __has_builtin(__builtin_smul_overflow)
#define HCL_HAVE_BUILTIN_SMUL_OVERFLOW
#endif
#if __has_builtin(__builtin_smull_overflow)
#define HCL_HAVE_BUILTIN_SMULL_OVERFLOW
#endif
#if __has_builtin(__builtin_smulll_overflow)
#define HCL_HAVE_BUILTIN_SMULLL_OVERFLOW
#endif
#if __has_builtin(__builtin_expect)
#define HCL_HAVE_BUILTIN_EXPECT
#endif
#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
#define HCL_HAVE_BUILTIN_CTZ
#define HCL_HAVE_BUILTIN_EXPECT
#endif
#if (__GNUC__ >= 5)
#define HCL_HAVE_BUILTIN_UADD_OVERFLOW
#define HCL_HAVE_BUILTIN_UADDL_OVERFLOW
#define HCL_HAVE_BUILTIN_UADDLL_OVERFLOW
#define HCL_HAVE_BUILTIN_UMUL_OVERFLOW
#define HCL_HAVE_BUILTIN_UMULL_OVERFLOW
#define HCL_HAVE_BUILTIN_UMULLL_OVERFLOW
#define HCL_HAVE_BUILTIN_SADD_OVERFLOW
#define HCL_HAVE_BUILTIN_SADDL_OVERFLOW
#define HCL_HAVE_BUILTIN_SADDLL_OVERFLOW
#define HCL_HAVE_BUILTIN_SMUL_OVERFLOW
#define HCL_HAVE_BUILTIN_SMULL_OVERFLOW
#define HCL_HAVE_BUILTIN_SMULLL_OVERFLOW
#endif
#endif
#if defined(HCL_HAVE_BUILTIN_EXPECT)
# define HCL_LIKELY(x) (__builtin_expect(!!x,1))
# define HCL_UNLIKELY(x) (__builtin_expect(!!x,0))
#else
# define HCL_LIKELY(x) (x)
# define HCL_UNLIKELY(x) (x)
#endif
#endif

167
lib/hcl-dos.h Normal file
View File

@ -0,0 +1,167 @@
/*
* $Id$
*
Copyright (c) 2014-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* DOS for other platforms than x86?
* If so, the endian should be defined selectively
*/
#define HCL_ENDIAN_LITTLE
#if defined(__WATCOMC__) && defined(__386__)
# define HCL_SIZEOF_CHAR 1
# define HCL_SIZEOF_SHORT 2
# define HCL_SIZEOF_INT 4
# define HCL_SIZEOF_LONG 4
# if (__WATCOMC__ < 1200)
# define HCL_SIZEOF_LONG_LONG 0
# else
# define HCL_SIZEOF_LONG_LONG 8
# endif
# define HCL_SIZEOF_VOID_P 4
# define HCL_SIZEOF_FLOAT 4
# define HCL_SIZEOF_DOUBLE 8
# define HCL_SIZEOF_LONG_DOUBLE 8
# define HCL_SIZEOF_WCHAR_T 2
# define HCL_SIZEOF___INT8 1
# define HCL_SIZEOF___INT16 2
# define HCL_SIZEOF___INT32 4
# define HCL_SIZEOF___INT64 8
# define HCL_SIZEOF___INT128 0
# define HCL_SIZEOF_OFF64_T 0
# define HCL_SIZEOF_OFF_T 4
# define HCL_SIZEOF_MBSTATE_T HCL_SIZEOF_LONG
# define HCL_MBLEN_MAX 8
#elif defined(__WATCOMC__) && !defined(__386__)
# define HCL_SIZEOF_CHAR 1
# define HCL_SIZEOF_SHORT 2
# define HCL_SIZEOF_INT 2
# define HCL_SIZEOF_LONG 4
# define HCL_SIZEOF_LONG_LONG 8
# define HCL_SIZEOF_VOID_P 4
# define HCL_SIZEOF_FLOAT 4
# define HCL_SIZEOF_DOUBLE 8
# define HCL_SIZEOF_LONG_DOUBLE 8
# define HCL_SIZEOF_WCHAR_T 2
# define HCL_SIZEOF___INT8 1
# define HCL_SIZEOF___INT16 2
# define HCL_SIZEOF___INT32 4
# define HCL_SIZEOF___INT64 8
# define HCL_SIZEOF___INT128 0
# define HCL_SIZEOF_OFF64_T 0
# define HCL_SIZEOF_OFF_T 4
# define HCL_SIZEOF_MBSTATE_T HCL_SIZEOF_LONG
# define HCL_MBLEN_MAX 8
#elif defined(__TURBOC__)
/* TODO: be more version specific wchar_t may be available in newer BCC */
# define HCL_SIZEOF_CHAR 1
# define HCL_SIZEOF_SHORT 2
# define HCL_SIZEOF_INT 2
# define HCL_SIZEOF_LONG 4
# define HCL_SIZEOF_LONG_LONG 0
# define HCL_SIZEOF_VOID_P 4
# define HCL_SIZEOF_FLOAT 4
# define HCL_SIZEOF_DOUBLE 8
# define HCL_SIZEOF_LONG_DOUBLE 10
# define HCL_SIZEOF_WCHAR_T 0
# define HCL_SIZEOF___INT8 0
# define HCL_SIZEOF___INT16 0
# define HCL_SIZEOF___INT32 0
# define HCL_SIZEOF___INT64 0
# define HCL_SIZEOF___INT128 0
# define HCL_SIZEOF_OFF64_T 0
# define HCL_SIZEOF_OFF_T 4
# define HCL_SIZEOF_MBSTATE_T HCL_SIZEOF_LONG
# define HCL_MBLEN_MAX 8
#elif defined(__ZTC__) && defined(DOS386)
/* Zortech in DOSX 386 mode (ztc -mx) */
# define HCL_SIZEOF_CHAR 1
# define HCL_SIZEOF_SHORT 2
# define HCL_SIZEOF_INT 4
# define HCL_SIZEOF_LONG 4
# define HCL_SIZEOF_LONG_LONG 0
# define HCL_SIZEOF_VOID_P 4
# define HCL_SIZEOF_FLOAT 4
# define HCL_SIZEOF_DOUBLE 8
# define HCL_SIZEOF_LONG_DOUBLE 8
# define HCL_SIZEOF_WCHAR_T 1
# define HCL_SIZEOF___INT8 0
# define HCL_SIZEOF___INT16 0
# define HCL_SIZEOF___INT32 0
# define HCL_SIZEOF___INT64 0
# define HCL_SIZEOF___INT128 0
# define HCL_SIZEOF_OFF64_T 0
# define HCL_SIZEOF_OFF_T 4
# define HCL_SIZEOF_MBSTATE_T HCL_SIZEOF_LONG
# define HCL_MBLEN_MAX 8
#elif defined(_INTELC32_)
/* Intel C Code Builder 1.0 */
# define HCL_SIZEOF_CHAR 1
# define HCL_SIZEOF_SHORT 2
# define HCL_SIZEOF_INT 4
# define HCL_SIZEOF_LONG 4
# define HCL_SIZEOF_LONG_LONG 0
# define HCL_SIZEOF_VOID_P 4
# define HCL_SIZEOF_FLOAT 4
# define HCL_SIZEOF_DOUBLE 8
# define HCL_SIZEOF_LONG_DOUBLE 8
# define HCL_SIZEOF_WCHAR_T 1
# define HCL_SIZEOF___INT8 0
# define HCL_SIZEOF___INT16 0
# define HCL_SIZEOF___INT32 0
# define HCL_SIZEOF___INT64 0
# define HCL_SIZEOF___INT128 0
# define HCL_SIZEOF_OFF64_T 0
# define HCL_SIZEOF_OFF_T 4
# define HCL_SIZEOF_MBSTATE_T HCL_SIZEOF_LONG
# define HCL_MBLEN_MAX 8
#else
# error Define the size of various data types.
#endif

63
lib/hcl-mac.h Normal file
View File

@ -0,0 +1,63 @@
/*
* $Id$
*
Copyright (c) 2014-2015 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 HCL_ENDIAN_BIG
#if defined(__MWERKS__)
# define HCL_SIZEOF_CHAR 1
# define HCL_SIZEOF_SHORT 2
# define HCL_SIZEOF_INT 4
# define HCL_SIZEOF_LONG 4
# define HCL_SIZEOF_LONG_LONG 8
# define HCL_SIZEOF_VOID_P 4
# define HCL_SIZEOF_FLOAT 4
# define HCL_SIZEOF_DOUBLE 8
# define HCL_SIZEOF_LONG_DOUBLE 8
# define HCL_SIZEOF_WCHAR_T 2
# define HCL_SIZEOF___INT8 1
# define HCL_SIZEOF___INT16 2
# define HCL_SIZEOF___INT32 4
# define HCL_SIZEOF___INT64 8
# define HCL_SIZEOF___INT128 0
# define HCL_SIZEOF_OFF64_T 0
# define HCL_SIZEOF_OFF_T 8
# define HCL_SIZEOF_MBSTATE_T HCL_SIZEOF_LONG
# define HCL_MBLEN_MAX 16
/* these two have only to be large enough */
# define HCL_SIZEOF_STRUCT_SOCKADDR_IN 32
# define HCL_SIZEOF_STRUCT_SOCKADDR_IN6 64
# define HCL_SIZEOF_SOCKLEN_T 4
#else
# error Define the size of various data types.
#endif

197
lib/hcl-msw.h Normal file
View File

@ -0,0 +1,197 @@
/*
* $Id$
*
Copyright (c) 2014-2015 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 HCL_ENDIAN_LITTLE
#if defined(__WATCOMC__)
# define HCL_SIZEOF_CHAR 1
# define HCL_SIZEOF_SHORT 2
# define HCL_SIZEOF_INT 4
# define HCL_SIZEOF_LONG 4
# if (__WATCOMC__ < 1200)
# define HCL_SIZEOF_LONG_LONG 0
# else
# define HCL_SIZEOF_LONG_LONG 8
# endif
# if defined(_WIN64)
# define HCL_SIZEOF_VOID_P 8
# else
# define HCL_SIZEOF_VOID_P 4
# endif
# define HCL_SIZEOF_FLOAT 4
# define HCL_SIZEOF_DOUBLE 8
# define HCL_SIZEOF_LONG_DOUBLE 8
# define HCL_SIZEOF_WCHAR_T 2
# define HCL_SIZEOF___INT8 1
# define HCL_SIZEOF___INT16 2
# define HCL_SIZEOF___INT32 4
# define HCL_SIZEOF___INT64 8
# define HCL_SIZEOF___INT128 0
# define HCL_SIZEOF_OFF64_T 0
# define HCL_SIZEOF_OFF_T 8
# define HCL_SIZEOF_MBSTATE_T HCL_SIZEOF_LONG
# define HCL_MBLEN_MAX 16
/* these two have only to be large enough */
# define HCL_SIZEOF_STRUCT_SOCKADDR_IN 32
# define HCL_SIZEOF_STRUCT_SOCKADDR_IN6 64
# define HCL_SIZEOF_SOCKLEN_T 4
#elif defined(__GNUC__) || defined(__DMC__) || defined(__POCC__)
# define HCL_SIZEOF_CHAR 1
# define HCL_SIZEOF_SHORT 2
# define HCL_SIZEOF_INT 4
# define HCL_SIZEOF_LONG 4
# define HCL_SIZEOF_LONG_LONG 8
# if defined(_WIN64)
# define HCL_SIZEOF_VOID_P 8
# else
# define HCL_SIZEOF_VOID_P 4
# endif
# define HCL_SIZEOF_FLOAT 4
# define HCL_SIZEOF_DOUBLE 8
# define HCL_SIZEOF_LONG_DOUBLE 16
# define HCL_SIZEOF_WCHAR_T 2
# define HCL_SIZEOF___INT8 0
# define HCL_SIZEOF___INT16 0
# define HCL_SIZEOF___INT32 0
# define HCL_SIZEOF___INT64 0
# define HCL_SIZEOF___INT128 0
# define HCL_SIZEOF_OFF64_T 0
# define HCL_SIZEOF_OFF_T 8
# define HCL_SIZEOF_MBSTATE_T HCL_SIZEOF_LONG
# define HCL_MBLEN_MAX 16
/* these two have only to be large enough */
# define HCL_SIZEOF_STRUCT_SOCKADDR_IN 32
# define HCL_SIZEOF_STRUCT_SOCKADDR_IN6 64
#elif defined(_MSC_VER)
# define HCL_SIZEOF_CHAR 1
# define HCL_SIZEOF_SHORT 2
# define HCL_SIZEOF_INT 4
# define HCL_SIZEOF_LONG 4
# if (_MSC_VER>=1310)
# define HCL_SIZEOF_LONG_LONG 8
# else
# define HCL_SIZEOF_LONG_LONG 0
# endif
# if defined(_WIN64)
# define HCL_SIZEOF_VOID_P 8
# else
# define HCL_SIZEOF_VOID_P 4
# endif
# define HCL_SIZEOF_FLOAT 4
# define HCL_SIZEOF_DOUBLE 8
# define HCL_SIZEOF_LONG_DOUBLE 8
# define HCL_SIZEOF_WCHAR_T 2
# define HCL_SIZEOF___INT8 1
# define HCL_SIZEOF___INT16 2
# define HCL_SIZEOF___INT32 4
# define HCL_SIZEOF___INT64 8
# define HCL_SIZEOF___INT128 0
# define HCL_SIZEOF_OFF64_T 0
# define HCL_SIZEOF_OFF_T 8
# define HCL_SIZEOF_MBSTATE_T HCL_SIZEOF_LONG
# define HCL_MBLEN_MAX 8
/* these two have only to be large enough */
# define HCL_SIZEOF_STRUCT_SOCKADDR_IN 32
# define HCL_SIZEOF_STRUCT_SOCKADDR_IN6 64
# define HCL_SIZEOF_SOCKLEN_T 4
#elif defined(__BORLANDC__)
# define HCL_SIZEOF_CHAR 1
# define HCL_SIZEOF_SHORT 2
# define HCL_SIZEOF_INT 4
# define HCL_SIZEOF_LONG 4
# define HCL_SIZEOF_LONG_LONG 0
# if defined(_WIN64)
# define HCL_SIZEOF_VOID_P 8
# else
# define HCL_SIZEOF_VOID_P 4
# endif
# define HCL_SIZEOF_FLOAT 4
# define HCL_SIZEOF_DOUBLE 8
# define HCL_SIZEOF_LONG_DOUBLE 8
# define HCL_SIZEOF_WCHAR_T 2
# define HCL_SIZEOF___INT8 1
# define HCL_SIZEOF___INT16 2
# define HCL_SIZEOF___INT32 4
# if (__BORLANDC__ >= 0x500)
# define HCL_SIZEOF___INT64 0
# else
# define HCL_SIZEOF___INT64 0
# endif
# define HCL_SIZEOF___INT128 0
# define HCL_SIZEOF_OFF64_T 0
# define HCL_SIZEOF_OFF_T 8
# define HCL_SIZEOF_MBSTATE_T HCL_SIZEOF_LONG
# define HCL_MBLEN_MAX 8
/* these two have only to be large enough */
# define HCL_SIZEOF_STRUCT_SOCKADDR_IN 32
# define HCL_SIZEOF_STRUCT_SOCKADDR_IN6 64
# define HCL_SIZEOF_SOCKLEN_T 4
#else
# error Define the size of various data types.
#endif

97
lib/hcl-os2.h Normal file
View File

@ -0,0 +1,97 @@
/*
* $Id$
*
Copyright (c) 2014-2015 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 HCL_ENDIAN_LITTLE
#if defined(__WATCOMC__)
# define HCL_SIZEOF_CHAR 1
# define HCL_SIZEOF_SHORT 2
# define HCL_SIZEOF_INT 4
# define HCL_SIZEOF_LONG 4
# if (__WATCOMC__ < 1200)
# define HCL_SIZEOF_LONG_LONG 0
# else
# define HCL_SIZEOF_LONG_LONG 8
# endif
# define HCL_SIZEOF_VOID_P 4
# define HCL_SIZEOF_FLOAT 4
# define HCL_SIZEOF_DOUBLE 8
# define HCL_SIZEOF_LONG_DOUBLE 8
# define HCL_SIZEOF_WCHAR_T 2
# define HCL_SIZEOF___INT8 1
# define HCL_SIZEOF___INT16 2
# define HCL_SIZEOF___INT32 4
# define HCL_SIZEOF___INT64 8
# define HCL_SIZEOF___INT128 0
# define HCL_SIZEOF_OFF64_T 0
# define HCL_SIZEOF_OFF_T 8
/* I don't know the exact mbstate size.
* but this should be large enough */
# define HCL_SIZEOF_MBSTATE_T HCL_SIZEOF_LONG
/* TODO: check the exact value */
# define HCL_MBLEN_MAX 8
/* these two have only to be large enough */
# define HCL_SIZEOF_STRUCT_SOCKADDR_IN 32
# define HCL_SIZEOF_STRUCT_SOCKADDR_IN6 64
# define HCL_SIZEOF_SOCKLEN_T 4
#elif defined(__BORLANDC__)
# define HCL_SIZEOF_CHAR 1
# define HCL_SIZEOF_SHORT 2
# define HCL_SIZEOF_INT 4
# define HCL_SIZEOF_LONG 4
# define HCL_SIZEOF_LONG_LONG 0
# define HCL_SIZEOF_VOID_P 4
# define HCL_SIZEOF_FLOAT 4
# define HCL_SIZEOF_DOUBLE 8
# define HCL_SIZEOF_LONG_DOUBLE 8
# define HCL_SIZEOF_WCHAR_T 2
# define HCL_SIZEOF___INT8 0
# define HCL_SIZEOF___INT16 0
# define HCL_SIZEOF___INT32 0
# define HCL_SIZEOF___INT64 0
# define HCL_SIZEOF___INT128 0
# define HCL_SIZEOF_OFF64_T 0
# define HCL_SIZEOF_OFF_T 4
# define HCL_SIZEOF_MBSTATE_T HCL_SIZEOF_LONG
# define HCL_MBLEN_MAX 8
# define HCL_SIZEOF_STRUCT_SOCKADDR_IN 32
# define HCL_SIZEOF_STRUCT_SOCKADDR_IN6 64
# define HCL_SIZEOF_SOCKLEN_T 4
#else
# error Define the size of various data types.
#endif

1077
lib/hcl-prv.h Normal file

File diff suppressed because it is too large Load Diff

607
lib/hcl-rbt.h Normal file
View File

@ -0,0 +1,607 @@
/*
* $Id$
*
Copyright (c) 2014-2015 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 _HCL_RBT_H_
#define _HCL_RBT_H_
#include "hcl-cmn.h"
/**@file
* This file provides a red-black tree encapsulated in the #hcl_rbt_t type that
* implements a self-balancing binary search tree.Its interface is very close
* to #hcl_htb_t.
*
* This sample code adds a series of keys and values and print them
* in descending key order.
* @code
* #include <hcl/cmn/rbt.h>
* #include <hcl/cmn/mem.h>
* #include <hcl/cmn/sio.h>
*
* static hcl_rbt_walk_t walk (hcl_rbt_t* rbt, hcl_rbt_pair_t* pair, void* ctx)
* {
* hcl_printf (HCL_T("key = %d, value = %d\n"),
* *(int*)HCL_RBT_KPTR(pair), *(int*)HCL_RBT_VPTR(pair));
* return HCL_RBT_WALK_FORWARD;
* }
*
* int main ()
* {
* hcl_rbt_t* s1;
* int i;
*
* s1 = hcl_rbt_open (HCL_MMGR_GETDFL(), 0, 1, 1); // error handling skipped
* hcl_rbt_setstyle (s1, hcl_getrbtstyle(HCL_RBT_STYLE_INLINE_COPIERS));
*
* for (i = 0; i < 20; i++)
* {
* int x = i * 20;
* hcl_rbt_insert (s1, &i, HCL_SIZEOF(i), &x, HCL_SIZEOF(x)); // eror handling skipped
* }
*
* hcl_rbt_rwalk (s1, walk, HCL_NULL);
*
* hcl_rbt_close (s1);
* return 0;
* }
* @endcode
*/
typedef struct hcl_rbt_t hcl_rbt_t;
typedef struct hcl_rbt_pair_t hcl_rbt_pair_t;
/**
* The hcl_rbt_walk_t type defines values that the callback function can
* return to control hcl_rbt_walk() and hcl_rbt_rwalk().
*/
enum hcl_rbt_walk_t
{
HCL_RBT_WALK_STOP = 0,
HCL_RBT_WALK_FORWARD = 1
};
typedef enum hcl_rbt_walk_t hcl_rbt_walk_t;
/**
* The hcl_rbt_id_t type defines IDs to indicate a key or a value in various
* functions
*/
enum hcl_rbt_id_t
{
HCL_RBT_KEY = 0, /**< indicate a key */
HCL_RBT_VAL = 1 /**< indicate a value */
};
typedef enum hcl_rbt_id_t hcl_rbt_id_t;
/**
* The hcl_rbt_copier_t type defines a pair contruction callback.
*/
typedef void* (*hcl_rbt_copier_t) (
hcl_rbt_t* rbt /* red-black tree */,
void* dptr /* pointer to a key or a value */,
hcl_oow_t dlen /* length of a key or a value */
);
/**
* The hcl_rbt_freeer_t defines a key/value destruction callback.
*/
typedef void (*hcl_rbt_freeer_t) (
hcl_rbt_t* rbt, /**< red-black tree */
void* dptr, /**< pointer to a key or a value */
hcl_oow_t dlen /**< length of a key or a value */
);
/**
* The hcl_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 (*hcl_rbt_comper_t) (
const hcl_rbt_t* rbt, /**< red-black tree */
const void* kptr1, /**< key pointer */
hcl_oow_t klen1, /**< key length */
const void* kptr2, /**< key pointer */
hcl_oow_t klen2 /**< key length */
);
/**
* The hcl_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 (*hcl_rbt_keeper_t) (
hcl_rbt_t* rbt, /**< red-black tree */
void* vptr, /**< value pointer */
hcl_oow_t vlen /**< value length */
);
/**
* The hcl_rbt_walker_t defines a pair visitor.
*/
typedef hcl_rbt_walk_t (*hcl_rbt_walker_t) (
hcl_rbt_t* rbt, /**< red-black tree */
hcl_rbt_pair_t* pair, /**< pointer to a key/value pair */
void* ctx /**< pointer to user-defined data */
);
/**
* The hcl_rbt_cbserter_t type defines a callback function for hcl_rbt_cbsert().
* The hcl_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 #HCL_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 #HCL_NULL for failure.
*/
typedef hcl_rbt_pair_t* (*hcl_rbt_cbserter_t) (
hcl_rbt_t* rbt, /**< red-black tree */
hcl_rbt_pair_t* pair, /**< pair pointer */
void* kptr, /**< key pointer */
hcl_oow_t klen, /**< key length */
void* ctx /**< callback context */
);
/**
* The hcl_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 hcl_rbt_pair_t
{
struct
{
void* ptr;
hcl_oow_t len;
} key;
struct
{
void* ptr;
hcl_oow_t len;
} val;
/* management information below */
enum
{
HCL_RBT_RED,
HCL_RBT_BLACK
} color;
hcl_rbt_pair_t* parent;
hcl_rbt_pair_t* child[2]; /* left and right */
};
typedef struct hcl_rbt_style_t hcl_rbt_style_t;
/**
* The hcl_rbt_style_t type defines callback function sets for key/value
* pair manipulation.
*/
struct hcl_rbt_style_t
{
hcl_rbt_copier_t copier[2]; /**< key and value copier */
hcl_rbt_freeer_t freeer[2]; /**< key and value freeer */
hcl_rbt_comper_t comper; /**< key comparator */
hcl_rbt_keeper_t keeper; /**< value keeper */
};
/**
* The hcl_rbt_style_kind_t type defines the type of predefined
* callback set for pair manipulation.
*/
enum hcl_rbt_style_kind_t
{
/** store the key and the value pointer */
HCL_RBT_STYLE_DEFAULT,
/** copy both key and value into the pair */
HCL_RBT_STYLE_INLINE_COPIERS,
/** copy the key into the pair but store the value pointer */
HCL_RBT_STYLE_INLINE_KEY_COPIER,
/** copy the value into the pair but store the key pointer */
HCL_RBT_STYLE_INLINE_VALUE_COPIER
};
typedef enum hcl_rbt_style_kind_t hcl_rbt_style_kind_t;
/**
* The hcl_rbt_t type defines a red-black tree.
*/
struct hcl_rbt_t
{
hcl_mmgr_t* mmgr;
const hcl_rbt_style_t* style;
hcl_oob_t scale[2]; /**< length scale */
hcl_rbt_pair_t xnil; /**< internal nil node */
hcl_oow_t size; /**< number of pairs */
hcl_rbt_pair_t* root; /**< root pair */
};
/**
* The HCL_RBT_COPIER_SIMPLE macros defines a copier that remembers the
* pointer and length of data in a pair.
*/
#define HCL_RBT_COPIER_SIMPLE ((hcl_rbt_copier_t)1)
/**
* The HCL_RBT_COPIER_INLINE macros defines a copier that copies data into
* a pair.
*/
#define HCL_RBT_COPIER_INLINE ((hcl_rbt_copier_t)2)
#define HCL_RBT_COPIER_DEFAULT (HCL_RBT_COPIER_SIMPLE)
#define HCL_RBT_FREEER_DEFAULT (HCL_NULL)
#define HCL_RBT_COMPER_DEFAULT (hcl_rbt_dflcomp)
#define HCL_RBT_KEEPER_DEFAULT (HCL_NULL)
/**
* The HCL_RBT_SIZE() macro returns the number of pairs in red-black tree.
*/
#define HCL_RBT_SIZE(m) ((const hcl_oow_t)(m)->size)
#define HCL_RBT_KSCALE(m) ((const int)(m)->scale[HCL_RBT_KEY])
#define HCL_RBT_VSCALE(m) ((const int)(m)->scale[HCL_RBT_VAL])
#define HCL_RBT_KPTL(p) (&(p)->key)
#define HCL_RBT_VPTL(p) (&(p)->val)
#define HCL_RBT_KPTR(p) ((p)->key.ptr)
#define HCL_RBT_KLEN(p) ((p)->key.len)
#define HCL_RBT_VPTR(p) ((p)->val.ptr)
#define HCL_RBT_VLEN(p) ((p)->val.len)
#define HCL_RBT_NEXT(p) ((p)->next)
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The hcl_getrbtstyle() functions returns a predefined callback set for
* pair manipulation.
*/
HCL_EXPORT const hcl_rbt_style_t* hcl_getrbtstyle (
hcl_rbt_style_kind_t kind
);
/**
* The hcl_rbt_open() function creates a red-black tree.
* @return hcl_rbt_t pointer on success, HCL_NULL on failure.
*/
HCL_EXPORT hcl_rbt_t* hcl_rbt_open (
hcl_mmgr_t* mmgr, /**< memory manager */
hcl_oow_t xtnsize, /**< extension size in bytes */
int kscale, /**< key scale */
int vscale /**< value scale */
);
/**
* The hcl_rbt_close() function destroys a red-black tree.
*/
HCL_EXPORT void hcl_rbt_close (
hcl_rbt_t* rbt /**< red-black tree */
);
/**
* The hcl_rbt_init() function initializes a red-black tree
*/
HCL_EXPORT int hcl_rbt_init (
hcl_rbt_t* rbt, /**< red-black tree */
hcl_mmgr_t* mmgr, /**< memory manager */
int kscale, /**< key scale */
int vscale /**< value scale */
);
/**
* The hcl_rbt_fini() funtion finalizes a red-black tree
*/
HCL_EXPORT void hcl_rbt_fini (
hcl_rbt_t* rbt /**< red-black tree */
);
HCL_EXPORT hcl_mmgr_t* hcl_rbt_getmmgr (
hcl_rbt_t* rbt
);
HCL_EXPORT void* hcl_rbt_getxtn (
hcl_rbt_t* rbt
);
/**
* The hcl_rbt_getstyle() function gets manipulation callback function set.
*/
HCL_EXPORT const hcl_rbt_style_t* hcl_rbt_getstyle (
const hcl_rbt_t* rbt /**< red-black tree */
);
/**
* The hcl_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.
*/
HCL_EXPORT void hcl_rbt_setstyle (
hcl_rbt_t* rbt, /**< red-black tree */
const hcl_rbt_style_t* style /**< callback function set */
);
/**
* The hcl_rbt_getsize() function gets the number of pairs in red-black tree.
*/
HCL_EXPORT hcl_oow_t hcl_rbt_getsize (
const hcl_rbt_t* rbt /**< red-black tree */
);
/**
* The hcl_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 HCL_NULL.
* @return pointer to the pair with a maching key,
* or HCL_NULL if no match is found.
*/
HCL_EXPORT hcl_rbt_pair_t* hcl_rbt_search (
const hcl_rbt_t* rbt, /**< red-black tree */
const void* kptr, /**< key pointer */
hcl_oow_t klen /**< the size of the key */
);
/**
* The hcl_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,
* HCL_NULL on failure.
*/
HCL_EXPORT hcl_rbt_pair_t* hcl_rbt_upsert (
hcl_rbt_t* rbt, /**< red-black tree */
void* kptr, /**< key pointer */
hcl_oow_t klen, /**< key length */
void* vptr, /**< value pointer */
hcl_oow_t vlen /**< value length */
);
/**
* The hcl_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, HCL_NULL on failure.
*/
HCL_EXPORT hcl_rbt_pair_t* hcl_rbt_ensert (
hcl_rbt_t* rbt, /**< red-black tree */
void* kptr, /**< key pointer */
hcl_oow_t klen, /**< key length */
void* vptr, /**< value pointer */
hcl_oow_t vlen /**< value length */
);
/**
* The hcl_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
* HCL_NULL without channging the value.
* @return pointer to the pair created on success, HCL_NULL on failure.
*/
HCL_EXPORT hcl_rbt_pair_t* hcl_rbt_insert (
hcl_rbt_t* rbt, /**< red-black tree */
void* kptr, /**< key pointer */
hcl_oow_t klen, /**< key length */
void* vptr, /**< value pointer */
hcl_oow_t vlen /**< value length */
);
/**
* The hcl_rbt_update() function updates the value of an existing pair
* with a matching key.
* @return pointer to the pair on success, HCL_NULL on no matching pair
*/
HCL_EXPORT hcl_rbt_pair_t* hcl_rbt_update (
hcl_rbt_t* rbt, /**< red-black tree */
void* kptr, /**< key pointer */
hcl_oow_t klen, /**< key length */
void* vptr, /**< value pointer */
hcl_oow_t vlen /**< value length */
);
/**
* The hcl_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 hcl_rbt_insert(), hcl_rbt_upsert(), hcl_rbt_update(),
* hcl_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
* hcl_rbt_walk_t print_map_pair (hcl_rbt_t* map, hcl_rbt_pair_t* pair, void* ctx)
* {
* hcl_printf (HCL_T("%.*s[%d] => %.*s[%d]\n"),
* (int)HCL_RBT_KLEN(pair), HCL_RBT_KPTR(pair), (int)HCL_RBT_KLEN(pair),
* (int)HCL_RBT_VLEN(pair), HCL_RBT_VPTR(pair), (int)HCL_RBT_VLEN(pair));
* return HCL_RBT_WALK_FORWARD;
* }
*
* hcl_rbt_pair_t* cbserter (
* hcl_rbt_t* rbt, hcl_rbt_pair_t* pair,
* void* kptr, hcl_oow_t klen, void* ctx)
* {
* hcl_cstr_t* v = (hcl_cstr_t*)ctx;
* if (pair == HCL_NULL)
* {
* // no existing key for the key
* return hcl_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
* hcl_rbt_pair_t* new_pair;
* hcl_char_t comma = HCL_T(',');
* hcl_oob_t* vptr;
*
* // allocate a new pair, but without filling the actual value.
* // note vptr is given HCL_NULL for that purpose
* new_pair = hcl_rbt_allocpair (
* rbt, kptr, klen, HCL_NULL, pair->vlen + 1 + v->len);
* if (new_pair == HCL_NULL) return HCL_NULL;
*
* // fill in the value space
* vptr = new_pair->vptr;
* hcl_memcpy (vptr, pair->vptr, pair->vlen*HCL_SIZEOF(hcl_char_t));
* vptr += pair->vlen*HCL_SIZEOF(hcl_char_t);
* hcl_memcpy (vptr, &comma, HCL_SIZEOF(hcl_char_t));
* vptr += HCL_SIZEOF(hcl_char_t);
* hcl_memcpy (vptr, v->ptr, v->len*HCL_SIZEOF(hcl_char_t));
*
* // this callback requires the old pair to be destroyed
* hcl_rbt_freepair (rbt, pair);
*
* // return the new pair
* return new_pair;
* }
* }
*
* int main ()
* {
* hcl_rbt_t* s1;
* int i;
* hcl_char_t* keys[] = { HCL_T("one"), HCL_T("two"), HCL_T("three") };
* hcl_char_t* vals[] = { HCL_T("1"), HCL_T("2"), HCL_T("3"), HCL_T("4"), HCL_T("5") };
*
* s1 = hcl_rbt_open (
* HCL_MMGR_GETDFL(), 0,
* HCL_SIZEOF(hcl_char_t), HCL_SIZEOF(hcl_char_t)
* ); // note error check is skipped
* hcl_rbt_setstyle (s1, &style1);
*
* for (i = 0; i < HCL_COUNTOF(vals); i++)
* {
* hcl_cstr_t ctx;
* ctx.ptr = vals[i]; ctx.len = hcl_strlen(vals[i]);
* hcl_rbt_cbsert (s1,
* keys[i%HCL_COUNTOF(keys)], hcl_strlen(keys[i%HCL_COUNTOF(keys)]),
* cbserter, &ctx
* ); // note error check is skipped
* }
* hcl_rbt_walk (s1, print_map_pair, HCL_NULL);
*
* hcl_rbt_close (s1);
* return 0;
* }
* @endcode
*/
HCL_EXPORT hcl_rbt_pair_t* hcl_rbt_cbsert (
hcl_rbt_t* rbt, /**< red-black tree */
void* kptr, /**< key pointer */
hcl_oow_t klen, /**< key length */
hcl_rbt_cbserter_t cbserter, /**< callback function */
void* ctx /**< callback context */
);
/**
* The hcl_rbt_delete() function deletes a pair with a matching key
* @return 0 on success, -1 on failure
*/
HCL_EXPORT int hcl_rbt_delete (
hcl_rbt_t* rbt, /**< red-black tree */
const void* kptr, /**< key pointer */
hcl_oow_t klen /**< key size */
);
/**
* The hcl_rbt_clear() function empties a red-black tree.
*/
HCL_EXPORT void hcl_rbt_clear (
hcl_rbt_t* rbt /**< red-black tree */
);
/**
* The hcl_rbt_walk() function traverses a red-black tree in preorder
* from the leftmost child.
*/
HCL_EXPORT void hcl_rbt_walk (
hcl_rbt_t* rbt, /**< red-black tree */
hcl_rbt_walker_t walker, /**< callback function for each pair */
void* ctx /**< pointer to user-specific data */
);
/**
* The hcl_rbt_walk() function traverses a red-black tree in preorder
* from the rightmost child.
*/
HCL_EXPORT void hcl_rbt_rwalk (
hcl_rbt_t* rbt, /**< red-black tree */
hcl_rbt_walker_t walker, /**< callback function for each pair */
void* ctx /**< pointer to user-specific data */
);
/**
* The hcl_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
* #HCL_RBT_COPIER_INLINE.
* - If @a kptr is #HCL_NULL, the key space of the size @a klen is reserved but
* not propagated with any data.
* - If @a vptr is #HCL_NULL, the value space of the size @a vlen is reserved
* but not propagated with any data.
*/
HCL_EXPORT hcl_rbt_pair_t* hcl_rbt_allocpair (
hcl_rbt_t* rbt,
void* kptr,
hcl_oow_t klen,
void* vptr,
hcl_oow_t vlen
);
/**
* The hcl_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.
*/
HCL_EXPORT void hcl_rbt_freepair (
hcl_rbt_t* rbt,
hcl_rbt_pair_t* pair
);
/**
* The hcl_rbt_dflcomp() function defines the default key comparator.
*/
HCL_EXPORT int hcl_rbt_dflcomp (
const hcl_rbt_t* rbt,
const void* kptr1,
hcl_oow_t klen1,
const void* kptr2,
hcl_oow_t klen2
);
#if defined(__cplusplus)
}
#endif
#endif

155
lib/hcl-utl.h Normal file
View File

@ -0,0 +1,155 @@
/*
* $Id$
*
Copyright (c) 2014-2015 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 _HCL_UTL_H_
#define _HCL_UTL_H_
#include "hcl-cmn.h"
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(HCL_OOCH_IS_UCH)
# define hcl_hashchars(ptr,len) hcl_hashuchars(ptr,len)
# define hcl_compoocbcstr(str1,str2) hcl_compucbcstr(str1,str2)
# define hcl_compoocstr(str1,str2) hcl_compucstr(str1,str2)
# define hcl_copyoochars(dst,src,len) hcl_copyuchars(dst,src,len)
# define hcl_copybchtooochars(dst,src,len) hcl_copybchtouchars(dst,src,len)
# define hcl_copyoocstr(dst,len,src) hcl_copyucstr(dst,len,src)
# define hcl_findoochar(ptr,len,c) hcl_finduchar(ptr,len,c)
# define hcl_countoocstr(str) hcl_countucstr(str)
#else
# define hcl_hashchars(ptr,len) hcl_hashbchars(ptr,len)
# define hcl_compoocbcstr(str1,str2) hcl_compbcstr(str1,str2)
# define hcl_compoocstr(str1,str2) hcl_compbcstr(str1,str2)
# define hcl_copyoochars(dst,src,len) hcl_copybchars(dst,src,len)
# define hcl_copybchtooochars(dst,src,len) hcl_copybchars(dst,src,len)
# define hcl_copyoocstr(dst,len,src) hcl_copybcstr(dst,len,src)
# define hcl_findoochar(ptr,len,c) hcl_findbchar(ptr,len,c)
# define hcl_countoocstr(str) hcl_countbcstr(str)
#endif
/* ========================================================================= */
/* hcl-utl.c */
/* ========================================================================= */
hcl_oow_t hcl_hashbytes (
const hcl_oob_t* ptr,
hcl_oow_t len
);
hcl_oow_t hcl_hashuchars (
const hcl_uch_t* ptr,
hcl_oow_t len
);
#define hcl_hashbchars(ptr,len) hcl_hashbytes(ptr,len)
int hcl_equalchars (
const hcl_uch_t* str1,
const hcl_uch_t* str2,
hcl_oow_t len
);
int hcl_compucstr (
const hcl_uch_t* str1,
const hcl_uch_t* str2
);
int hcl_compbcstr (
const hcl_bch_t* str1,
const hcl_bch_t* str2
);
int hcl_compucbcstr (
const hcl_uch_t* str1,
const hcl_bch_t* str2
);
int hcl_compucxbcstr (
const hcl_uch_t* str1,
hcl_oow_t len,
const hcl_bch_t* str2
);
void hcl_copyuchars (
hcl_uch_t* dst,
const hcl_uch_t* src,
hcl_oow_t len
);
void hcl_copybchars (
hcl_bch_t* dst,
const hcl_bch_t* src,
hcl_oow_t len
);
void hcl_copybchtouchars (
hcl_uch_t* dst,
const hcl_bch_t* src,
hcl_oow_t len
);
hcl_oow_t hcl_copyucstr (
hcl_uch_t* dst,
hcl_oow_t len,
const hcl_uch_t* src
);
hcl_oow_t hcl_copybcstr (
hcl_bch_t* dst,
hcl_oow_t len,
const hcl_bch_t* src
);
hcl_uch_t* hcl_finduchar (
const hcl_uch_t* ptr,
hcl_oow_t len,
hcl_uch_t c
);
hcl_bch_t* hcl_findbchar (
const hcl_bch_t* ptr,
hcl_oow_t len,
hcl_bch_t c
);
hcl_oow_t hcl_countucstr (
const hcl_uch_t* str
);
hcl_oow_t hcl_countbcstr (
const hcl_bch_t* str
);
#if defined(__cplusplus)
}
#endif
#endif

387
lib/hcl.c Normal file
View File

@ -0,0 +1,387 @@
/*
* $Id$
*
Copyright (c) 2014-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "hcl-prv.h"
hcl_t* hcl_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_oow_t heapsize, const hcl_vmprim_t* vmprim, hcl_errnum_t* errnum)
{
hcl_t* hcl;
/* if this assertion fails, correct the type definition in hcl.h */
HCL_ASSERT (HCL_SIZEOF(hcl_oow_t) == HCL_SIZEOF(hcl_oop_t));
hcl = HCL_MMGR_ALLOC (mmgr, HCL_SIZEOF(*hcl) + xtnsize);
if (hcl)
{
if (hcl_init(hcl, mmgr, heapsize, vmprim) <= -1)
{
if (errnum) *errnum = hcl->errnum;
HCL_MMGR_FREE (mmgr, hcl);
hcl = HCL_NULL;
}
else HCL_MEMSET (hcl + 1, 0, xtnsize);
}
else if (errnum) *errnum = HCL_ESYSMEM;
return hcl;
}
void hcl_close (hcl_t* hcl)
{
hcl_fini (hcl);
HCL_MMGR_FREE (hcl->mmgr, hcl);
}
static void fill_bigint_tables (hcl_t* hcl)
{
int radix, safe_ndigits;
hcl_oow_t ub, w;
hcl_oow_t multiplier;
for (radix = 2; radix <= 36; radix++)
{
w = 0;
ub = (hcl_oow_t)HCL_TYPE_MAX(hcl_liw_t) / radix - (radix - 1);
multiplier = 1;
safe_ndigits = 0;
while (w <= ub)
{
w = w * radix + (radix - 1);
multiplier *= radix;
safe_ndigits++;
}
/* safe_ndigits contains the number of digits that never
* cause overflow when computed normally with a native type. */
hcl->bigint[radix].safe_ndigits = safe_ndigits;
hcl->bigint[radix].multiplier = multiplier;
}
}
int hcl_init (hcl_t* hcl, hcl_mmgr_t* mmgr, hcl_oow_t heapsz, const hcl_vmprim_t* vmprim)
{
HCL_MEMSET (hcl, 0, HCL_SIZEOF(*hcl));
hcl->mmgr = mmgr;
hcl->vmprim = *vmprim;
hcl->option.log_mask = ~0u;
hcl->option.dfl_symtab_size = HCL_DFL_SYMTAB_SIZE;
hcl->option.dfl_sysdic_size = HCL_DFL_SYSDIC_SIZE;
hcl->option.dfl_procstk_size = HCL_DFL_PROCSTK_SIZE;
/*hcl->permheap = hcl_makeheap (hcl, what is the best size???);
if (!hcl->curheap) goto oops; */
hcl->curheap = hcl_makeheap (hcl, heapsz);
if (!hcl->curheap) goto oops;
hcl->newheap = hcl_makeheap (hcl, heapsz);
if (!hcl->newheap) goto oops;
if (hcl_rbt_init (&hcl->pmtable, mmgr, HCL_SIZEOF(hcl_ooch_t), 1) <= -1) goto oops;
hcl_rbt_setstyle (&hcl->pmtable, hcl_getrbtstyle(HCL_RBT_STYLE_INLINE_COPIERS));
fill_bigint_tables (hcl);
return 0;
oops:
if (hcl->newheap) hcl_killheap (hcl, hcl->newheap);
if (hcl->curheap) hcl_killheap (hcl, hcl->curheap);
if (hcl->permheap) hcl_killheap (hcl, hcl->permheap);
return -1;
}
static hcl_rbt_walk_t unload_primitive_module (hcl_rbt_t* rbt, hcl_rbt_pair_t* pair, void* ctx)
{
hcl_t* hcl = (hcl_t*)ctx;
hcl_prim_mod_data_t* md;
md = HCL_RBT_VPTR(pair);
if (md->mod.unload) md->mod.unload (hcl, &md->mod);
if (md->handle) hcl->vmprim.mod_close (hcl, md->handle);
return HCL_RBT_WALK_FORWARD;
}
void hcl_fini (hcl_t* hcl)
{
hcl_cb_t* cb;
if (hcl->sem_list)
{
hcl_freemem (hcl, hcl->sem_list);
hcl->sem_list_capa = 0;
hcl->sem_list_count = 0;
}
if (hcl->sem_heap)
{
hcl_freemem (hcl, hcl->sem_heap);
hcl->sem_heap_capa = 0;
hcl->sem_heap_count = 0;
}
for (cb = hcl->cblist; cb; cb = cb->next)
{
if (cb->fini) cb->fini (hcl);
}
hcl_rbt_walk (&hcl->pmtable, unload_primitive_module, hcl);
hcl_rbt_fini (&hcl->pmtable);
if (hcl->code.bc.arr)
{
hcl_freengcobj (hcl, hcl->code.bc.arr);
hcl->code.bc.arr = HCL_NULL;
hcl->code.bc.len = 0;
}
if (hcl->code.lit.arr)
{
hcl_freengcobj (hcl, hcl->code.lit.arr);
hcl->code.lit.arr = HCL_NULL;
hcl->code.lit.len = 0;
}
if (hcl->p.s.ptr)
{
hcl_freemem (hcl, hcl->p.s.ptr);
hcl->p.s.ptr= HCL_NULL;
hcl->p.s.capa = 0;
hcl->p.s.size = 0;
}
hcl_killheap (hcl, hcl->newheap);
hcl_killheap (hcl, hcl->curheap);
hcl_killheap (hcl, hcl->permheap);
/* deregister all callbacks */
while (hcl->cblist) hcl_deregcb (hcl, hcl->cblist);
if (hcl->log.ptr)
{
/* make sure to flush your log message */
/* TODO: flush unwritten message */
hcl_freemem (hcl, hcl->log.ptr);
hcl->log.capa = 0;
hcl->log.len = 0;
}
}
hcl_mmgr_t* hcl_getmmgr (hcl_t* hcl)
{
return hcl->mmgr;
}
void* hcl_getxtn (hcl_t* hcl)
{
return (void*)(hcl + 1);
}
hcl_errnum_t hcl_geterrnum (hcl_t* hcl)
{
return hcl->errnum;
}
void hcl_seterrnum (hcl_t* hcl, hcl_errnum_t errnum)
{
hcl->errnum = errnum;
}
int hcl_setoption (hcl_t* hcl, hcl_option_t id, const void* value)
{
switch (id)
{
case HCL_TRAIT:
hcl->option.trait = *(const int*)value;
return 0;
case HCL_LOG_MASK:
hcl->option.log_mask = *(const unsigned int*)value;
return 0;
case HCL_SYMTAB_SIZE:
{
hcl_oow_t w;
w = *(hcl_oow_t*)value;
if (w <= 0 || w > HCL_SMOOI_MAX) goto einval;
hcl->option.dfl_symtab_size = *(hcl_oow_t*)value;
return 0;
}
case HCL_SYSDIC_SIZE:
{
hcl_oow_t w;
w = *(hcl_oow_t*)value;
if (w <= 0 || w > HCL_SMOOI_MAX) goto einval;
hcl->option.dfl_sysdic_size = *(hcl_oow_t*)value;
return 0;
}
case HCL_PROCSTK_SIZE:
{
hcl_oow_t w;
w = *(hcl_oow_t*)value;
if (w <= 0 || w > HCL_SMOOI_MAX) goto einval;
hcl->option.dfl_procstk_size = *(hcl_oow_t*)value;
return 0;
}
}
einval:
hcl->errnum = HCL_EINVAL;
return -1;
}
int hcl_getoption (hcl_t* hcl, hcl_option_t id, void* value)
{
switch (id)
{
case HCL_TRAIT:
*(int*)value = hcl->option.trait;
return 0;
case HCL_LOG_MASK:
*(unsigned int*)value = hcl->option.log_mask;
return 0;
case HCL_SYMTAB_SIZE:
*(hcl_oow_t*)value = hcl->option.dfl_symtab_size;
return 0;
case HCL_SYSDIC_SIZE:
*(hcl_oow_t*)value = hcl->option.dfl_sysdic_size;
return 0;
case HCL_PROCSTK_SIZE:
*(hcl_oow_t*)value = hcl->option.dfl_procstk_size;
return 0;
};
hcl->errnum = HCL_EINVAL;
return -1;
}
hcl_cb_t* hcl_regcb (hcl_t* hcl, hcl_cb_t* tmpl)
{
hcl_cb_t* actual;
actual = hcl_allocmem (hcl, HCL_SIZEOF(*actual));
if (!actual) return HCL_NULL;
*actual = *tmpl;
actual->next = hcl->cblist;
actual->prev = HCL_NULL;
hcl->cblist = actual;
return actual;
}
void hcl_deregcb (hcl_t* hcl, hcl_cb_t* cb)
{
if (cb == hcl->cblist)
{
hcl->cblist = hcl->cblist->next;
if (hcl->cblist) hcl->cblist->prev = HCL_NULL;
}
else
{
if (cb->next) cb->next->prev = cb->prev;
if (cb->prev) cb->prev->next = cb->next;
}
hcl_freemem (hcl, cb);
}
void* hcl_allocmem (hcl_t* hcl, hcl_oow_t size)
{
void* ptr;
ptr = HCL_MMGR_ALLOC (hcl->mmgr, size);
if (!ptr) hcl->errnum = HCL_ESYSMEM;
return ptr;
}
void* hcl_callocmem (hcl_t* hcl, hcl_oow_t size)
{
void* ptr;
ptr = HCL_MMGR_ALLOC (hcl->mmgr, size);
if (!ptr) hcl->errnum = HCL_ESYSMEM;
else HCL_MEMSET (ptr, 0, size);
return ptr;
}
void* hcl_reallocmem (hcl_t* hcl, void* ptr, hcl_oow_t size)
{
ptr = HCL_MMGR_REALLOC (hcl->mmgr, ptr, size);
if (!ptr) hcl->errnum = HCL_ESYSMEM;
return ptr;
}
void hcl_freemem (hcl_t* hcl, void* ptr)
{
HCL_MMGR_FREE (hcl->mmgr, ptr);
}
void hcl_getsynerr (hcl_t* hcl, hcl_synerr_t* synerr)
{
HCL_ASSERT (hcl->c != HCL_NULL);
if (synerr) *synerr = hcl->c->synerr;
}
void hcl_setsynerr (hcl_t* hcl, hcl_synerrnum_t num, const hcl_ioloc_t* loc, const hcl_oocs_t* tgt)
{
hcl->errnum = HCL_ESYNERR;
hcl->c->synerr.num = num;
/* The SCO compiler complains of this ternary operation saying:
* error: operands have incompatible types: op ":"
* it seems to complain of type mismatch between *loc and
* hcl->c->tok.loc due to 'const' prefixed to loc. */
/*hcl->c->synerr.loc = loc? *loc: hcl->c->tok.loc;*/
if (loc)
hcl->c->synerr.loc = *loc;
else
hcl->c->synerr.loc = hcl->c->tok.loc;
if (tgt) hcl->c->synerr.tgt = *tgt;
else
{
hcl->c->synerr.tgt.ptr = HCL_NULL;
hcl->c->synerr.tgt.len = 0;
}
}

1410
lib/hcl.h Normal file

File diff suppressed because it is too large Load Diff

80
lib/heap.c Normal file
View File

@ -0,0 +1,80 @@
/*
* $Id$
*
Copyright (c) 2014-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "hcl-prv.h"
hcl_heap_t* hcl_makeheap (hcl_t* hcl, hcl_oow_t size)
{
hcl_heap_t* heap;
heap = (hcl_heap_t*)HCL_MMGR_ALLOC(hcl->mmgr, HCL_SIZEOF(*heap) + size);
if (!heap)
{
hcl->errnum = HCL_ESYSMEM;
return HCL_NULL;
}
HCL_MEMSET (heap, 0, HCL_SIZEOF(*heap) + size);
heap->base = (hcl_uint8_t*)(heap + 1);
/* adjust the initial allocation pointer to a multiple of the oop size */
heap->ptr = (hcl_uint8_t*)HCL_ALIGN(((hcl_uintptr_t)heap->base), HCL_SIZEOF(hcl_oop_t));
heap->limit = heap->base + size;
HCL_ASSERT (heap->ptr >= heap->base);
HCL_ASSERT (heap->limit >= heap->base );
HCL_ASSERT (heap->limit - heap->base == size);
/* if size is too small, heap->ptr may go past heap->limit even at
* this moment depending on the alignment of heap->base. subsequent
* calls to subhcl_allocheapmem() are bound to fail. Make sure to
* pass a heap size large enough */
return heap;
}
void hcl_killheap (hcl_t* hcl, hcl_heap_t* heap)
{
HCL_MMGR_FREE (hcl->mmgr, heap);
}
void* hcl_allocheapmem (hcl_t* hcl, hcl_heap_t* heap, hcl_oow_t size)
{
hcl_uint8_t* ptr;
/* check the heap size limit */
if (heap->ptr >= heap->limit || heap->limit - heap->ptr < size)
{
hcl->errnum = HCL_EOOMEM;
return HCL_NULL;
}
/* allocation is as simple as moving the heap pointer */
ptr = heap->ptr;
heap->ptr += size;
return ptr;
}

28
lib/ignite.c Normal file
View File

@ -0,0 +1,28 @@
/*
* $Id$
*
Copyright (c) 2014-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "hcl-prv.h"

353
lib/logfmt.c Normal file
View File

@ -0,0 +1,353 @@
/*
* $Id$
*
Copyright (c) 2014-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "hcl-prv.h"
/*#include <stdio.h>*/ /* for snrintf(). used for floating-point number formatting */
#include <stdarg.h>
#if defined(_MSC_VER) || defined(__BORLANDC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1200))
# define snprintf _snprintf
# if !defined(HAVE_SNPRINTF)
# define HAVE_SNPRINTF
# endif
#endif
#if defined(HAVE_QUADMATH_H)
# include <quadmath.h> /* for quadmath_snprintf() */
#endif
/* TODO: remove stdio.h and quadmath.h once snprintf gets replaced by own
floting-point conversion implementation*/
/* Max number conversion buffer length:
* hcl_intmax_t in base 2, plus NUL byte. */
#define MAXNBUF (HCL_SIZEOF(hcl_intmax_t) * 8 + 1)
enum
{
/* integer */
LF_C = (1 << 0),
LF_H = (1 << 1),
LF_J = (1 << 2),
LF_L = (1 << 3),
LF_Q = (1 << 4),
LF_T = (1 << 5),
LF_Z = (1 << 6),
/* long double */
LF_LD = (1 << 7),
/* __float128 */
LF_QD = (1 << 8)
};
static struct
{
hcl_uint8_t flag; /* for single occurrence */
hcl_uint8_t dflag; /* for double occurrence */
} lm_tab[26] =
{
{ 0, 0 }, /* a */
{ 0, 0 }, /* b */
{ 0, 0 }, /* c */
{ 0, 0 }, /* d */
{ 0, 0 }, /* e */
{ 0, 0 }, /* f */
{ 0, 0 }, /* g */
{ LF_H, LF_C }, /* h */
{ 0, 0 }, /* i */
{ LF_J, 0 }, /* j */
{ 0, 0 }, /* k */
{ LF_L, LF_Q }, /* l */
{ 0, 0 }, /* m */
{ 0, 0 }, /* n */
{ 0, 0 }, /* o */
{ 0, 0 }, /* p */
{ LF_Q, 0 }, /* q */
{ 0, 0 }, /* r */
{ 0, 0 }, /* s */
{ LF_T, 0 }, /* t */
{ 0, 0 }, /* u */
{ 0, 0 }, /* v */
{ 0, 0 }, /* w */
{ 0, 0 }, /* z */
{ 0, 0 }, /* y */
{ LF_Z, 0 }, /* z */
};
enum
{
FLAGC_DOT = (1 << 0),
FLAGC_SPACE = (1 << 1),
FLAGC_SHARP = (1 << 2),
FLAGC_SIGN = (1 << 3),
FLAGC_LEFTADJ = (1 << 4),
FLAGC_ZEROPAD = (1 << 5),
FLAGC_WIDTH = (1 << 6),
FLAGC_PRECISION = (1 << 7),
FLAGC_STAR1 = (1 << 8),
FLAGC_STAR2 = (1 << 9),
FLAGC_LENMOD = (1 << 10) /* length modifier */
};
static const hcl_bch_t hex2ascii_lower[] =
{
'0','1','2','3','4','5','6','7','8','9',
'a','b','c','d','e','f','g','h','i','j','k','l','m',
'n','o','p','q','r','s','t','u','v','w','x','y','z'
};
static const hcl_bch_t hex2ascii_upper[] =
{
'0','1','2','3','4','5','6','7','8','9',
'A','B','C','D','E','F','G','H','I','J','K','L','M',
'N','O','P','Q','R','S','T','U','V','W','X','H','Z'
};
static hcl_ooch_t ooch_nullstr[] = { '(','n','u','l','l', ')','\0' };
static hcl_bch_t bch_nullstr[] = { '(','n','u','l','l', ')','\0' };
typedef int (*hcl_fmtout_putch_t) (
hcl_t* hcl,
hcl_oow_t mask,
hcl_ooch_t c,
hcl_oow_t len
);
typedef int (*hcl_fmtout_putcs_t) (
hcl_t* hcl,
hcl_oow_t mask,
const hcl_ooch_t* ptr,
hcl_oow_t len
);
typedef struct hcl_fmtout_t hcl_fmtout_t;
struct hcl_fmtout_t
{
hcl_oow_t count; /* out */
hcl_oow_t mask; /* in */
hcl_fmtout_putch_t putch; /* in */
hcl_fmtout_putcs_t putcs; /* in */
};
/* ------------------------------------------------------------------------- */
/*
* Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
* order; return an optional length and a pointer to the last character
* written in the buffer (i.e., the first character of the string).
* The buffer pointed to by `nbuf' must have length >= MAXNBUF.
*/
static hcl_bch_t* sprintn_lower (hcl_bch_t* nbuf, hcl_uintmax_t num, int base, hcl_ooi_t *lenp)
{
hcl_bch_t* p;
p = nbuf;
*p = '\0';
do { *++p = hex2ascii_lower[num % base]; } while (num /= base);
if (lenp) *lenp = p - nbuf;
return p; /* returns the end */
}
static hcl_bch_t* sprintn_upper (hcl_bch_t* nbuf, hcl_uintmax_t num, int base, hcl_ooi_t *lenp)
{
hcl_bch_t* p;
p = nbuf;
*p = '\0';
do { *++p = hex2ascii_upper[num % base]; } while (num /= base);
if (lenp) *lenp = p - nbuf;
return p; /* returns the end */
}
/* ------------------------------------------------------------------------- */
static int put_ooch (hcl_t* hcl, hcl_oow_t mask, hcl_ooch_t ch, hcl_oow_t len)
{
if (len <= 0) return 1;
if (hcl->log.len > 0 && hcl->log.last_mask != mask)
{
/* the mask has changed. commit the buffered text */
hcl->vmprim.log_write (hcl, hcl->log.last_mask, hcl->log.ptr, hcl->log.len);
hcl->log.len = 0;
}
redo:
if (len > hcl->log.capa - hcl->log.len)
{
hcl_oow_t newcapa;
hcl_ooch_t* tmp;
if (len > HCL_TYPE_MAX(hcl_oow_t) - hcl->log.len)
{
/* data too big */
hcl->errnum = HCL_ETOOBIG;
return -1;
}
newcapa = HCL_ALIGN(hcl->log.len + len, 512); /* TODO: adjust this capacity */
tmp = hcl_reallocmem (hcl, hcl->log.ptr, newcapa * HCL_SIZEOF(*tmp));
if (!tmp)
{
if (hcl->log.len > 0)
{
/* can't expand the buffer. just flush the existing contents */
hcl->vmprim.log_write (hcl, hcl->log.last_mask, hcl->log.ptr, hcl->log.len);
hcl->log.len = 0;
goto redo;
}
return -1;
}
hcl->log.ptr = tmp;
hcl->log.capa = newcapa;
}
while (len > 0)
{
hcl->log.ptr[hcl->log.len++] = ch;
len--;
}
hcl->log.last_mask = mask;
return 1; /* success */
}
static int put_oocs (hcl_t* hcl, hcl_oow_t mask, const hcl_ooch_t* ptr, hcl_oow_t len)
{
if (len <= 0) return 1;
if (hcl->log.len > 0 && hcl->log.last_mask != mask)
{
/* the mask has changed. commit the buffered text */
hcl->vmprim.log_write (hcl, hcl->log.last_mask, hcl->log.ptr, hcl->log.len);
hcl->log.len = 0;
}
if (len > hcl->log.capa - hcl->log.len)
{
hcl_oow_t newcapa;
hcl_ooch_t* tmp;
if (len > HCL_TYPE_MAX(hcl_oow_t) - hcl->log.len)
{
/* data too big */
hcl->errnum = HCL_ETOOBIG;
return -1;
}
newcapa = HCL_ALIGN(hcl->log.len + len, 512); /* TODO: adjust this capacity */
tmp = hcl_reallocmem (hcl, hcl->log.ptr, newcapa * HCL_SIZEOF(*tmp));
if (!tmp) return -1;
hcl->log.ptr = tmp;
hcl->log.capa = newcapa;
}
HCL_MEMCPY (&hcl->log.ptr[hcl->log.len], ptr, len * HCL_SIZEOF(*ptr));
hcl->log.len += len;
hcl->log.last_mask = mask;
return 1; /* success */
}
/* ------------------------------------------------------------------------- */
static hcl_ooi_t log_object (hcl_t* hcl, hcl_iocmd_t cmd, void* arg)
{
hcl_iooutarg_t* outarg = (hcl_iooutarg_t*)arg;
put_oocs (hcl, (hcl_oow_t)outarg->handle, outarg->ptr, outarg->len);
return outarg->len; /* don't really care about failure as it's for logging */
}
static int print_object (hcl_t* hcl, hcl_oow_t mask, hcl_oop_t obj)
{
hcl_iooutarg_t outarg;
outarg.handle = (void*)mask;
return hcl_printobj (hcl, obj, log_object, &outarg);
}
/* ------------------------------------------------------------------------- */
#undef fmtchar_t
#undef logfmtv
#define fmtchar_t hcl_bch_t
#define FMTCHAR_IS_BCH
#define logfmtv hcl_logbfmtv
#include "logfmtv.h"
#undef fmtchar_t
#undef logfmtv
#define fmtchar_t hcl_ooch_t
#define logfmtv hcl_logoofmtv
#define FMTCHAR_IS_OOCH
#include "logfmtv.h"
hcl_ooi_t hcl_logbfmt (hcl_t* hcl, hcl_oow_t mask, const hcl_bch_t* fmt, ...)
{
int x;
va_list ap;
hcl_fmtout_t fo;
fo.mask = mask;
fo.putch = put_ooch;
fo.putcs = put_oocs;
va_start (ap, fmt);
x = hcl_logbfmtv (hcl, fmt, &fo, ap);
va_end (ap);
if (hcl->log.len > 0 && hcl->log.ptr[hcl->log.len - 1] == '\n')
{
hcl->vmprim.log_write (hcl, hcl->log.last_mask, hcl->log.ptr, hcl->log.len);
hcl->log.len = 0;
}
return (x <= -1)? -1: fo.count;
}
hcl_ooi_t hcl_logoofmt (hcl_t* hcl, hcl_oow_t mask, const hcl_ooch_t* fmt, ...)
{
int x;
va_list ap;
hcl_fmtout_t fo;
fo.mask = mask;
fo.putch = put_ooch;
fo.putcs = put_oocs;
va_start (ap, fmt);
x = hcl_logoofmtv (hcl, fmt, &fo, ap);
va_end (ap);
if (hcl->log.len > 0 && hcl->log.ptr[hcl->log.len - 1] == '\n')
{
hcl->vmprim.log_write (hcl, hcl->log.last_mask, hcl->log.ptr, hcl->log.len);
hcl->log.len = 0;
}
return (x <= -1)? -1: fo.count;
}

883
lib/logfmtv.h Normal file
View File

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

621
lib/main.c Normal file
View File

@ -0,0 +1,621 @@
/*
* $Id$
*
Copyright (c) 2014-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "hcl-prv.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#if defined(_WIN32)
# include <windows.h>
# include <tchar.h>
#elif defined(__OS2__)
# define INCL_DOSMODULEMGR
# define INCL_DOSPROCESS
# define INCL_DOSERRORS
# include <os2.h>
#elif defined(__MSDOS__)
/* nothing to include */
# include <time.h>
#elif defined(macintosh)
/* nothing to include */
#else
# include <unistd.h>
# include <time.h>
#endif
typedef struct bb_t bb_t;
struct bb_t
{
char buf[1024];
hcl_oow_t pos;
hcl_oow_t len;
FILE* fp;
};
typedef struct xtn_t xtn_t;
struct xtn_t
{
const char* read_path; /* main source file */
const char* print_path;
};
/* ========================================================================= */
static void* sys_alloc (hcl_mmgr_t* mmgr, hcl_oow_t size)
{
return malloc (size);
}
static void* sys_realloc (hcl_mmgr_t* mmgr, void* ptr, hcl_oow_t size)
{
return realloc (ptr, size);
}
static void sys_free (hcl_mmgr_t* mmgr, void* ptr)
{
free (ptr);
}
static hcl_mmgr_t sys_mmgr =
{
sys_alloc,
sys_realloc,
sys_free,
HCL_NULL
};
/* ========================================================================= */
static HCL_INLINE hcl_ooi_t open_input (hcl_t* hcl, hcl_ioinarg_t* arg)
{
xtn_t* xtn = hcl_getxtn(hcl);
bb_t* bb;
FILE* infp = HCL_NULL, * outfp = HCL_NULL;
if (arg->includer)
{
/* includee */
hcl_bch_t bcs[1024]; /* TODO: right buffer size */
hcl_oow_t bcslen = HCL_COUNTOF(bcs);
hcl_oow_t ucslen = ~(hcl_oow_t)0;
if (hcl_ucstoutf8 (arg->name, &ucslen, bcs, &bcslen) <= -1)
{
hcl_seterrnum (hcl, HCL_EECERR);
return -1;
}
/* TODO: make bcs relative to the includer */
#if defined(__MSDOS__) || defined(_WIN32) || defined(__OS2__)
infp = fopen (bcs, "rb");
#else
infp = fopen (bcs, "r");
#endif
if (!infp)
{
hcl_seterrnum (hcl, HCL_EIOERR);
return -1;
}
}
else
{
/* main stream */
#if defined(__MSDOS__) || defined(_WIN32) || defined(__OS2__)
infp = fopen (xtn->read_path, "rb");
if (xtn->print_path) outfp = fopen (xtn->print_path, "wb");
else outfp = stdout;
#else
infp = fopen (xtn->read_path, "r");
if (xtn->print_path) outfp = fopen (xtn->print_path, "w");
else outfp = stdout;
#endif
if (!infp || !outfp)
{
if (infp) fclose (infp);
if (outfp && outfp != stdout) fclose (outfp);
hcl_seterrnum (hcl, HCL_EIOERR);
return -1;
}
}
bb = hcl_callocmem (hcl, HCL_SIZEOF(*bb));
if (!bb)
{
if (infp) fclose (infp);
if (outfp && outfp != stdout) fclose (outfp);
return -1;
}
bb->fp = infp;
arg->handle = bb;
return 0;
}
static HCL_INLINE hcl_ooi_t close_input (hcl_t* hcl, hcl_ioinarg_t* arg)
{
xtn_t* xtn = hcl_getxtn(hcl);
bb_t* bb;
bb = (bb_t*)arg->handle;
HCL_ASSERT (bb != HCL_NULL && bb->fp != HCL_NULL);
if (bb->fp) fclose (bb->fp);
hcl_freemem (hcl, bb);
arg->handle = HCL_NULL;
return 0;
}
static HCL_INLINE hcl_ooi_t read_input (hcl_t* hcl, hcl_ioinarg_t* arg)
{
/*xtn_t* xtn = hcl_getxtn(hcl);*/
bb_t* bb;
hcl_oow_t bcslen, ucslen, remlen;
int x;
bb = (bb_t*)arg->handle;
HCL_ASSERT (bb != HCL_NULL && bb->fp != HCL_NULL);
do
{
x = fgetc (bb->fp);
if (x == EOF)
{
if (ferror((FILE*)bb->fp))
{
hcl_seterrnum (hcl, HCL_EIOERR);
return -1;
}
break;
}
bb->buf[bb->len++] = x;
}
while (bb->len < HCL_COUNTOF(bb->buf) && x != '\r' && x != '\n');
bcslen = bb->len;
ucslen = HCL_COUNTOF(arg->buf);
x = hcl_utf8toucs (bb->buf, &bcslen, arg->buf, &ucslen);
if (x <= -1 && ucslen <= 0)
{
hcl_seterrnum (hcl, HCL_EECERR);
return -1;
}
remlen = bb->len - bcslen;
if (remlen > 0) memmove (bb->buf, &bb->buf[bcslen], remlen);
bb->len = remlen;
return ucslen;
}
static hcl_ooi_t read_handler (hcl_t* hcl, hcl_iocmd_t cmd, void* arg)
{
switch (cmd)
{
case HCL_IO_OPEN:
return open_input (hcl, (hcl_ioinarg_t*)arg);
case HCL_IO_CLOSE:
return close_input (hcl, (hcl_ioinarg_t*)arg);
case HCL_IO_READ:
return read_input (hcl, (hcl_ioinarg_t*)arg);
default:
hcl->errnum = HCL_EINTERN;
return -1;
}
}
static HCL_INLINE hcl_ooi_t open_output(hcl_t* hcl, hcl_iooutarg_t* arg)
{
xtn_t* xtn = hcl_getxtn(hcl);
FILE* fp;
#if defined(__MSDOS__) || defined(_WIN32) || defined(__OS2__)
if (xtn->print_path) fp = fopen (xtn->print_path, "wb");
else fp = stdout;
#else
if (xtn->print_path) fp = fopen (xtn->print_path, "w");
else fp = stdout;
#endif
if (!fp)
{
hcl_seterrnum (hcl, HCL_EIOERR);
return -1;
}
arg->handle = fp;
return 0;
}
static HCL_INLINE hcl_ooi_t close_output (hcl_t* hcl, hcl_iooutarg_t* arg)
{
/*xtn_t* xtn = hcl_getxtn(hcl);*/
FILE* fp;
fp = (FILE*)arg->handle;
HCL_ASSERT (fp != HCL_NULL);
fclose (fp);
arg->handle = HCL_NULL;
return 0;
}
static HCL_INLINE hcl_ooi_t write_output (hcl_t* hcl, hcl_iooutarg_t* arg)
{
/*xtn_t* xtn = hcl_getxtn(hcl);*/
hcl_bch_t bcsbuf[1024];
hcl_oow_t bcslen, ucslen, donelen;
int x;
donelen = 0;
do
{
bcslen = HCL_COUNTOF(bcsbuf);
ucslen = arg->len - donelen;
x = hcl_ucstoutf8 (&arg->ptr[donelen], &ucslen, bcsbuf, &bcslen);
if (x <= -1 && ucslen <= 0)
{
hcl_seterrnum (hcl, HCL_EECERR);
return -1;
}
if (fwrite (bcsbuf, HCL_SIZEOF(bcsbuf[0]), bcslen, (FILE*)arg->handle) < bcslen)
{
hcl_seterrnum (hcl, HCL_EIOERR);
return -1;
}
donelen += ucslen;
}
while (donelen < arg->len);
return arg->len;
}
static hcl_ooi_t print_handler (hcl_t* hcl, hcl_iocmd_t cmd, void* arg)
{
switch (cmd)
{
case HCL_IO_OPEN:
return open_output (hcl, (hcl_iooutarg_t*)arg);
case HCL_IO_CLOSE:
return close_output (hcl, (hcl_iooutarg_t*)arg);
case HCL_IO_WRITE:
return write_output (hcl, (hcl_iooutarg_t*)arg);
default:
hcl->errnum = HCL_EINTERN;
return -1;
}
}
/* ========================================================================= */
static int write_all (int fd, const char* ptr, hcl_oow_t len)
{
while (len > 0)
{
hcl_ooi_t wr;
wr = write (1, ptr, len);
if (wr <= -1)
{
/*if (errno == EAGAIN || errno == EWOULDBLOCK)
{
push it to internal buffers? before writing data just converted, need to write buffered data first.
}*/
return -1;
}
ptr += wr;
len -= wr;
}
return 0;
}
static void log_write (hcl_t* hcl, hcl_oow_t mask, const hcl_ooch_t* msg, hcl_oow_t len)
{
#if defined(_WIN32)
# error NOT IMPLEMENTED
#else
hcl_bch_t buf[256];
hcl_oow_t ucslen, bcslen, msgidx;
int n;
if (mask & HCL_LOG_GC) return; /* don't show gc logs */
/* TODO: beautify the log message.
* do classification based on mask. */
{
char ts[32];
struct tm tm, *tmp;
time_t now;
now = time(NULL);
#if defined(__MSDOS__)
tmp = localtime (&now);
#else
tmp = localtime_r (&now, &tm);
#endif
strftime (ts, sizeof(ts), "%Y-%m-%d %H:%M:%S %z ", tmp);
write_all (1, ts, strlen(ts));
}
msgidx = 0;
while (len > 0)
{
ucslen = len;
bcslen = HCL_COUNTOF(buf);
n = hcl_ucstoutf8 (&msg[msgidx], &ucslen, buf, &bcslen);
if (n == 0 || n == -2)
{
/* n = 0:
* converted all successfully
* n == -2:
* buffer not sufficient. not all got converted yet.
* write what have been converted this round. */
HCL_ASSERT (ucslen > 0); /* if this fails, the buffer size must be increased */
/* attempt to write all converted characters */
if (write_all (1, buf, bcslen) <= -1) break;
if (n == 0) break;
else
{
msgidx += ucslen;
len -= ucslen;
}
}
else if (n <= -1)
{
/* conversion error */
break;
}
}
#endif
}
/* ========================================================================= */
static char* syntax_error_msg[] =
{
"no error",
"illegal character",
"comment not closed",
"string not closed",
"invalid hashed literal",
"wrong character literal",
"invalid numeric literal",
"out of integer range",
"sudden end of input",
"( expected",
") expected",
"] expected",
"string expected",
"byte too small or too large",
"nesting level too deep",
". disallowed",
"#include error",
"argument name list expected",
"argument name expected",
"lambda block too big",
"variable name expected",
"wrong number of arguments"
};
static void print_synerr (hcl_t* hcl)
{
hcl_synerr_t synerr;
hcl_bch_t bcs[1024]; /* TODO: right buffer size */
hcl_oow_t bcslen, ucslen;
xtn_t* xtn;
xtn = hcl_getxtn (hcl);
hcl_getsynerr (hcl, &synerr);
printf ("ERROR: ");
if (synerr.loc.file)
{
bcslen = HCL_COUNTOF(bcs);
ucslen = ~(hcl_oow_t)0;
if (hcl_ucstoutf8 (synerr.loc.file, &ucslen, bcs, &bcslen) >= 0)
{
printf ("%.*s ", (int)bcslen, bcs);
}
}
else
{
printf ("%s ", xtn->read_path);
}
printf ("syntax error at line %lu column %lu - %s",
(unsigned long int)synerr.loc.line, (unsigned long int)synerr.loc.colm,
syntax_error_msg[synerr.num]);
if (synerr.tgt.len > 0)
{
bcslen = HCL_COUNTOF(bcs);
ucslen = synerr.tgt.len;
if (hcl_ucstoutf8 (synerr.tgt.ptr, &ucslen, bcs, &bcslen) >= 0)
{
printf (" [%.*s]", (int)bcslen, bcs);
}
}
printf ("\n");
}
hcl_ooch_t str_hcl[] = { 'S', 't', 'i', 'x' };
hcl_ooch_t str_my_object[] = { 'M', 'y', 'O', 'b','j','e','c','t' };
hcl_ooch_t str_main[] = { 'm', 'a', 'i', 'n' };
int main (int argc, char* argv[])
{
hcl_t* hcl;
xtn_t* xtn;
hcl_vmprim_t vmprim;
#if !defined(macintosh)
if (argc < 2)
{
fprintf (stderr, "Usage: %s filename ...\n", argv[0]);
return -1;
}
#endif
memset (&vmprim, 0, HCL_SIZEOF(vmprim));
vmprim.log_write = log_write;
hcl = hcl_open (&sys_mmgr, HCL_SIZEOF(xtn_t), 2048000lu, &vmprim, HCL_NULL);
if (!hcl)
{
printf ("cannot open hcl\n");
return -1;
}
{
hcl_oow_t tab_size;
tab_size = 5000;
hcl_setoption (hcl, HCL_SYMTAB_SIZE, &tab_size);
tab_size = 5000;
hcl_setoption (hcl, HCL_SYSDIC_SIZE, &tab_size);
tab_size = 600;
hcl_setoption (hcl, HCL_PROCSTK_SIZE, &tab_size);
}
{
int trait = 0;
/*trait |= HCL_NOGC;*/
trait |= HCL_AWAIT_PROCS;
hcl_setoption (hcl, HCL_TRAIT, &trait);
}
if (hcl_ignite(hcl) <= -1)
{
printf ("cannot ignite hcl - %d\n", hcl_geterrnum(hcl));
hcl_close (hcl);
return -1;
}
xtn = hcl_getxtn (hcl);
#if defined(macintosh)
i = 20;
xtn->read_path = "test.st";
#endif
xtn->read_path = argv[1];
if (argc >= 2) xtn->print_path = argv[2];
if (hcl_attachio (hcl, read_handler, print_handler) <= -1)
{
printf ("ERROR: cannot attache input stream - %d\n", hcl_geterrnum(hcl));
hcl_close (hcl);
return -1;
}
while (1)
{
hcl_oop_t obj;
obj = hcl_read (hcl);
if (!obj)
{
if (hcl->errnum == HCL_EFINIS)
{
/* end of input */
break;
}
else if (hcl->errnum == HCL_ESYNERR)
{
print_synerr (hcl);
}
else
{
printf ("ERROR: cannot read object - %d\n", hcl_geterrnum(hcl));
}
break;
}
if (hcl_print (hcl, obj) <= -1)
{
printf ("ERROR: cannot print object - %d\n", hcl_geterrnum(hcl));
}
else
{
hcl_print (hcl, HCL_CHAR_TO_OOP('\n'));
hcl_compile (hcl, obj); /* TODO: error handling */
}
}
{
HCL_LOG0 (hcl, HCL_LOG_MNEMONIC, "------------------------------------------\n");
HCL_LOG2 (hcl, HCL_LOG_MNEMONIC, "BYTECODES hcl->code.bc.len = > %lu hcl->code.lit.len => %lu\n",
(unsigned long int)hcl->code.bc.len, (unsigned long int)hcl->code.lit.len);
hcl_decode (hcl, 0, hcl->code.bc.len);
hcl_dumpsymtab (hcl);
}
hcl_close (hcl);
#if defined(_WIN32) && defined(_DEBUG)
getchar();
#endif
return 0;
}

612
lib/obj.c Normal file
View File

@ -0,0 +1,612 @@
/*
* $Id$
*
Copyright (c) 2014-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "hcl-prv.h"
void* hcl_allocbytes (hcl_t* hcl, hcl_oow_t size)
{
hcl_uint8_t* ptr;
#if defined(HCL_DEBUG_GC)
if (!(hcl->option.trait & HCL_NOGC)) hcl_gc (hcl);
#endif
ptr = hcl_allocheapmem (hcl, hcl->curheap, size);
if (!ptr && !(hcl->option.trait & HCL_NOGC))
{
hcl_gc (hcl);
ptr = hcl_allocheapmem (hcl, hcl->curheap, size);
/* TODO: grow heap if ptr is still null. */
}
return ptr;
}
hcl_oop_t hcl_allocoopobj (hcl_t* hcl, hcl_oow_t size)
{
hcl_oop_oop_t hdr;
hcl_oow_t nbytes, nbytes_aligned;
nbytes = size * HCL_SIZEOF(hcl_oop_t);
/* this isn't really necessary since nbytes must be
* aligned already. */
nbytes_aligned = HCL_ALIGN(nbytes, HCL_SIZEOF(hcl_oop_t));
/* making the number of bytes to allocate a multiple of
* HCL_SIZEOF(hcl_oop_t) will guarantee the starting address
* of the allocated space to be an even number.
* see HCL_OOP_IS_NUMERIC() and HCL_OOP_IS_POINTER() */
hdr = hcl_allocbytes (hcl, HCL_SIZEOF(hcl_obj_t) + nbytes_aligned);
if (!hdr) return HCL_NULL;
hdr->_flags = HCL_OBJ_MAKE_FLAGS(HCL_OBJ_TYPE_OOP, HCL_SIZEOF(hcl_oop_t), 0, 0, 0, 0, 0, 0);
HCL_OBJ_SET_SIZE (hdr, size);
HCL_OBJ_SET_CLASS (hdr, hcl->_nil);
while (size > 0) hdr->slot[--size] = hcl->_nil;
return (hcl_oop_t)hdr;
}
#if defined(HCL_USE_OBJECT_TRAILER)
hcl_oop_t hcl_allocoopobjwithtrailer (hcl_t* hcl, hcl_oow_t size, const hcl_oob_t* bptr, hcl_oow_t blen)
{
hcl_oop_oop_t hdr;
hcl_oow_t nbytes, nbytes_aligned;
hcl_oow_t i;
/* +1 for the trailer size of the hcl_oow_t type */
nbytes = (size + 1) * HCL_SIZEOF(hcl_oop_t) + blen;
nbytes_aligned = HCL_ALIGN(nbytes, HCL_SIZEOF(hcl_oop_t));
hdr = hcl_allocbytes (hcl, HCL_SIZEOF(hcl_obj_t) + nbytes_aligned);
if (!hdr) return HCL_NULL;
hdr->_flags = HCL_OBJ_MAKE_FLAGS(HCL_OBJ_TYPE_OOP, HCL_SIZEOF(hcl_oop_t), 0, 0, 0, 0, 1, 0);
HCL_OBJ_SET_SIZE (hdr, size);
HCL_OBJ_SET_CLASS (hdr, hcl->_nil);
for (i = 0; i < size; i++) hdr->slot[i] = hcl->_nil;
/* [NOTE] this is not converted to a SMOOI object */
hdr->slot[size] = (hcl_oop_t)blen;
if (bptr)
{
HCL_MEMCPY (&hdr->slot[size + 1], bptr, blen);
}
else
{
HCL_MEMSET (&hdr->slot[size + 1], 0, blen);
}
return (hcl_oop_t)hdr;
}
#endif
static HCL_INLINE hcl_oop_t alloc_numeric_array (hcl_t* hcl, const void* ptr, hcl_oow_t len, hcl_obj_type_t type, hcl_oow_t unit, int extra, int ngc)
{
/* allocate a variable object */
hcl_oop_t hdr;
hcl_oow_t xbytes, nbytes, nbytes_aligned;
xbytes = len * unit;
/* 'extra' indicates an extra unit to append at the end.
* it's useful to store a string with a terminating null */
nbytes = extra? xbytes + len: xbytes;
nbytes_aligned = HCL_ALIGN(nbytes, HCL_SIZEOF(hcl_oop_t));
/* TODO: check overflow in size calculation*/
/* making the number of bytes to allocate a multiple of
* HCL_SIZEOF(hcl_oop_t) will guarantee the starting address
* of the allocated space to be an even number.
* see HCL_OOP_IS_NUMERIC() and HCL_OOP_IS_POINTER() */
if (HCL_UNLIKELY(ngc))
hdr = hcl_callocmem (hcl, HCL_SIZEOF(hcl_obj_t) + nbytes_aligned);
else
hdr = hcl_allocbytes (hcl, HCL_SIZEOF(hcl_obj_t) + nbytes_aligned);
if (!hdr) return HCL_NULL;
hdr->_flags = HCL_OBJ_MAKE_FLAGS(type, unit, extra, 0, 0, ngc, 0, 0);
hdr->_size = len;
HCL_OBJ_SET_SIZE (hdr, len);
HCL_OBJ_SET_CLASS (hdr, hcl->_nil);
if (ptr)
{
/* copy data */
HCL_MEMCPY (hdr + 1, ptr, xbytes);
HCL_MEMSET ((hcl_uint8_t*)(hdr + 1) + xbytes, 0, nbytes_aligned - xbytes);
}
else
{
/* initialize with zeros when the string pointer is not given */
HCL_MEMSET ((hdr + 1), 0, nbytes_aligned);
}
return hdr;
}
hcl_oop_t hcl_alloccharobj (hcl_t* hcl, const hcl_ooch_t* ptr, hcl_oow_t len)
{
return alloc_numeric_array (hcl, ptr, len, HCL_OBJ_TYPE_CHAR, HCL_SIZEOF(hcl_ooch_t), 1, 0);
}
hcl_oop_t hcl_allocbyteobj (hcl_t* hcl, const hcl_oob_t* ptr, hcl_oow_t len)
{
return alloc_numeric_array (hcl, ptr, len, HCL_OBJ_TYPE_BYTE, HCL_SIZEOF(hcl_oob_t), 0, 0);
}
hcl_oop_t hcl_allochalfwordobj (hcl_t* hcl, const hcl_oohw_t* ptr, hcl_oow_t len)
{
return alloc_numeric_array (hcl, ptr, len, HCL_OBJ_TYPE_HALFWORD, HCL_SIZEOF(hcl_oohw_t), 0, 0);
}
hcl_oop_t hcl_allocwordobj (hcl_t* hcl, const hcl_oow_t* ptr, hcl_oow_t len)
{
return alloc_numeric_array (hcl, ptr, len, HCL_OBJ_TYPE_WORD, HCL_SIZEOF(hcl_oow_t), 0, 0);
}
static HCL_INLINE int decode_spec (hcl_t* hcl, hcl_oop_t _class, hcl_oow_t vlen, hcl_obj_type_t* type, hcl_oow_t* outlen)
{
hcl_oow_t spec;
hcl_oow_t named_instvar;
hcl_obj_type_t indexed_type;
HCL_ASSERT (HCL_OOP_IS_POINTER(_class));
HCL_ASSERT (HCL_CLASSOF(hcl, _class) == hcl->_class);
HCL_ASSERT (HCL_OOP_IS_SMOOI(((hcl_oop_class_t)_class)->spec));
spec = HCL_OOP_TO_SMOOI(((hcl_oop_class_t)_class)->spec);
named_instvar = HCL_CLASS_SPEC_NAMED_INSTVAR(spec); /* size of the named_instvar part */
if (HCL_CLASS_SPEC_IS_INDEXED(spec))
{
indexed_type = HCL_CLASS_SPEC_INDEXED_TYPE(spec);
if (indexed_type == HCL_OBJ_TYPE_OOP)
{
if (named_instvar > HCL_MAX_NAMED_INSTVARS ||
vlen > HCL_MAX_INDEXED_INSTVARS(named_instvar))
{
return -1;
}
HCL_ASSERT (named_instvar + vlen <= HCL_OBJ_SIZE_MAX);
}
else
{
/* a non-pointer indexed class can't have named instance variables */
if (named_instvar > 0) return -1;
if (vlen > HCL_OBJ_SIZE_MAX) return -1;
}
}
else
{
/* named instance variables only. treat it as if it is an
* indexable class with no variable data */
indexed_type = HCL_OBJ_TYPE_OOP;
vlen = 0; /* vlen is not used */
if (named_instvar > HCL_MAX_NAMED_INSTVARS) return -1;
HCL_ASSERT (named_instvar <= HCL_OBJ_SIZE_MAX);
}
*type = indexed_type;
*outlen = named_instvar + vlen;
return 0;
}
hcl_oop_t hcl_instantiate (hcl_t* hcl, hcl_oop_t _class, const void* vptr, hcl_oow_t vlen)
{
hcl_oop_t oop;
hcl_obj_type_t type;
hcl_oow_t alloclen;
hcl_oow_t tmp_count = 0;
HCL_ASSERT (hcl->_nil != HCL_NULL);
if (decode_spec (hcl, _class, vlen, &type, &alloclen) <= -1)
{
hcl->errnum = HCL_EINVAL;
return HCL_NULL;
}
hcl_pushtmp (hcl, &_class); tmp_count++;
switch (type)
{
case HCL_OBJ_TYPE_OOP:
/* both the fixed part(named instance variables) and
* the variable part(indexed instance variables) are allowed. */
oop = hcl_allocoopobj (hcl, alloclen);
HCL_ASSERT (vptr == HCL_NULL);
/*
This function is not GC-safe. so i don't want to initialize
the payload of a pointer object. The caller can call this
function and initialize payloads then.
if (oop && vptr && vlen > 0)
{
hcl_oop_oop_t hdr = (hcl_oop_oop_t)oop;
HCL_MEMCPY (&hdr->slot[named_instvar], vptr, vlen * HCL_SIZEOF(hcl_oop_t));
}
For the above code to work, it should protect the elements of
the vptr array with hcl_pushtmp(). So it might be better
to disallow a non-NULL vptr when indexed_type is OOP. See
the assertion above this comment block.
*/
break;
case HCL_OBJ_TYPE_CHAR:
oop = hcl_alloccharobj (hcl, vptr, alloclen);
break;
case HCL_OBJ_TYPE_BYTE:
oop = hcl_allocbyteobj (hcl, vptr, alloclen);
break;
case HCL_OBJ_TYPE_HALFWORD:
oop = hcl_allochalfwordobj (hcl, vptr, alloclen);
break;
case HCL_OBJ_TYPE_WORD:
oop = hcl_allocwordobj (hcl, vptr, alloclen);
break;
default:
hcl->errnum = HCL_EINTERN;
oop = HCL_NULL;
break;
}
if (oop) HCL_OBJ_SET_CLASS (oop, _class);
hcl_poptmps (hcl, tmp_count);
return oop;
}
#if defined(HCL_USE_OBJECT_TRAILER)
hcl_oop_t hcl_instantiatewithtrailer (hcl_t* hcl, hcl_oop_t _class, hcl_oow_t vlen, const hcl_oob_t* tptr, hcl_oow_t tlen)
{
hcl_oop_t oop;
hcl_obj_type_t type;
hcl_oow_t alloclen;
hcl_oow_t tmp_count = 0;
HCL_ASSERT (hcl->_nil != HCL_NULL);
if (decode_spec (hcl, _class, vlen, &type, &alloclen) <= -1)
{
hcl->errnum = HCL_EINVAL;
return HCL_NULL;
}
hcl_pushtmp (hcl, &_class); tmp_count++;
switch (type)
{
case HCL_OBJ_TYPE_OOP:
/* NOTE: vptr is not used for GC unsafety */
oop = hcl_allocoopobjwithtrailer(hcl, alloclen, tptr, tlen);
break;
default:
hcl->errnum = HCL_EINTERN;
oop = HCL_NULL;
break;
}
if (oop) HCL_OBJ_SET_CLASS (oop, _class);
hcl_poptmps (hcl, tmp_count);
return oop;
}
#endif
/* ------------------------------------------------------------------------ *
* COMMON OBJECTS
* ------------------------------------------------------------------------ */
hcl_oop_t hcl_makenil (hcl_t* hcl)
{
hcl_oop_t obj;
obj = hcl_allocoopobj (hcl, 0);
if (obj)
{
HCL_OBJ_SET_FLAGS_BRAND (obj, HCL_BRAND_NIL);
}
return obj;
}
hcl_oop_t hcl_maketrue (hcl_t* hcl)
{
hcl_oop_t obj;
obj = hcl_allocoopobj (hcl, 0);
if (obj)
{
HCL_OBJ_SET_FLAGS_BRAND (obj, HCL_BRAND_TRUE);
}
return obj;
}
hcl_oop_t hcl_makefalse (hcl_t* hcl)
{
hcl_oop_t obj;
obj = hcl_allocoopobj (hcl, 0);
if (obj)
{
HCL_OBJ_SET_FLAGS_BRAND (obj, HCL_BRAND_FALSE);
}
return obj;
}
hcl_oop_t hcl_makeinteger (hcl_t* hcl, hcl_ooi_t v)
{
hcl_oop_t obj;
if (HCL_IN_SMOOI_RANGE(v)) return HCL_SMOOI_TO_OOP(v);
obj = hcl_allocwordobj (hcl, (hcl_oow_t*)&v, 1);
if (obj)
{
HCL_OBJ_SET_FLAGS_BRAND (obj, HCL_BRAND_INTEGER);
}
return obj;
}
hcl_oop_t hcl_makecons (hcl_t* hcl, hcl_oop_t car, hcl_oop_t cdr)
{
hcl_oop_cons_t cons;
hcl_pushtmp (hcl, &car);
hcl_pushtmp (hcl, &cdr);
cons = (hcl_oop_cons_t)hcl_allocoopobj (hcl, 2);
if (cons)
{
cons->car = car;
cons->cdr = cdr;
HCL_OBJ_SET_FLAGS_BRAND (cons, HCL_BRAND_CONS);
}
hcl_poptmps (hcl, 2);
return (hcl_oop_t)cons;
}
hcl_oop_t hcl_makearray (hcl_t* hcl, hcl_oow_t size)
{
hcl_oop_t obj;
obj = hcl_allocoopobj (hcl, size);
if (obj)
{
HCL_OBJ_SET_FLAGS_BRAND (obj, HCL_BRAND_ARRAY);
}
return obj;
}
hcl_oop_t hcl_makebytearray (hcl_t* hcl, const hcl_oob_t* ptr, hcl_oow_t size)
{
hcl_oop_t obj;
obj = hcl_allocbyteobj (hcl, ptr, size);
if (obj)
{
HCL_OBJ_SET_FLAGS_BRAND (obj, HCL_BRAND_BYTE_ARRAY);
}
return obj;
}
hcl_oop_t hcl_makestring (hcl_t* hcl, const hcl_ooch_t* ptr, hcl_oow_t len)
{
hcl_oop_t obj;
obj = hcl_alloccharobj (hcl, ptr, len);
if (obj)
{
HCL_OBJ_SET_FLAGS_BRAND (obj, HCL_BRAND_STRING);
}
return obj;
}
hcl_oop_t hcl_makeset (hcl_t* hcl, hcl_oow_t inisize)
{
hcl_oop_set_t obj;
obj = (hcl_oop_set_t)hcl_allocoopobj (hcl, 2);
if (obj)
{
hcl_oop_oop_t bucket;
HCL_OBJ_SET_FLAGS_BRAND (obj, HCL_BRAND_SET);
obj->tally = HCL_SMOOI_TO_OOP(0);
hcl_pushtmp (hcl, (hcl_oop_t*)&obj);
bucket = (hcl_oop_oop_t)hcl_makearray (hcl, inisize);
hcl_poptmp (hcl);
if (!bucket) obj = HCL_NULL;
else obj->bucket = bucket;
}
return (hcl_oop_t)obj;
}
void hcl_freengcobj (hcl_t* hcl, hcl_oop_t obj)
{
if (HCL_OOP_IS_POINTER(obj) && HCL_OBJ_GET_FLAGS_NGC(obj)) hcl_freemem (hcl, obj);
}
hcl_oop_t hcl_makengcbytearray (hcl_t* hcl, const hcl_oob_t* ptr, hcl_oow_t len)
{
hcl_oop_t obj;
obj = alloc_numeric_array (hcl, ptr, len, HCL_OBJ_TYPE_BYTE, HCL_SIZEOF(hcl_oob_t), 0, 1);
if (obj)
{
HCL_OBJ_SET_FLAGS_BRAND (obj, HCL_BRAND_BYTE_ARRAY);
}
return obj;
}
hcl_oop_t hcl_remakengcbytearray (hcl_t* hcl, hcl_oop_t obj, hcl_oow_t newsize)
{
hcl_oop_t tmp;
HCL_ASSERT (!obj || (HCL_OOP_IS_POINTER(obj) && HCL_OBJ_GET_FLAGS_NGC(obj)));
/* no hcl_pushtmp() is needed because 'obj' is a non-GC object. */
/* TODO: improve this by using realloc */
tmp = hcl_makengcbytearray (hcl, HCL_NULL, newsize);
if (tmp)
{
if (obj)
{
hcl_oow_t cpsize;
cpsize = (newsize > HCL_OBJ_GET_SIZE(obj))? HCL_OBJ_GET_SIZE(obj): newsize;
HCL_MEMCPY (((hcl_oop_byte_t)tmp)->slot, ((hcl_oop_byte_t)obj)->slot, cpsize * HCL_SIZEOF(hcl_oob_t));
}
hcl_freengcobj (hcl, obj);
}
return tmp;
}
hcl_oop_t hcl_makengcarray (hcl_t* hcl, hcl_oow_t len)
{
hcl_oop_t obj;
obj = alloc_numeric_array (hcl, HCL_NULL, len, HCL_OBJ_TYPE_OOP, HCL_SIZEOF(hcl_oop_t), 0, 1);
if (obj)
{
HCL_OBJ_SET_FLAGS_BRAND (obj, HCL_BRAND_ARRAY);
}
return obj;
}
hcl_oop_t hcl_remakengcarray (hcl_t* hcl, hcl_oop_t obj, hcl_oow_t newsize)
{
hcl_oop_t tmp;
HCL_ASSERT (!obj || (HCL_OOP_IS_POINTER(obj) && HCL_OBJ_GET_FLAGS_NGC(obj)));
/* no hcl_pushtmp() is needed because 'obj' is a non-GC object. */
/* TODO: improve this by using realloc */
tmp = hcl_makengcarray (hcl, newsize);
if (tmp)
{
if (obj)
{
hcl_oow_t cpsize;
cpsize = (newsize > HCL_OBJ_GET_SIZE(obj))? HCL_OBJ_GET_SIZE(obj): newsize;
HCL_MEMCPY (((hcl_oop_oop_t)tmp)->slot, ((hcl_oop_oop_t)obj)->slot, cpsize * HCL_SIZEOF(hcl_oop_t));
}
hcl_freengcobj (hcl, obj);
}
return tmp;
}
/* ------------------------------------------------------------------------ *
* CONS
* ------------------------------------------------------------------------ */
hcl_oow_t hcl_countcons (hcl_t* hcl, hcl_oop_t cons)
{
/* this function ignores the last cdr */
hcl_oow_t count = 1;
HCL_ASSERT (HCL_BRANDOF(hcl, cons));
do
{
cons = HCL_CONS_CDR(cons);
if (HCL_BRANDOF(hcl, cons) != HCL_BRAND_CONS) break;
count++;
}
while (1);
return count;
}
hcl_oop_t hcl_getlastconscdr (hcl_t* hcl, hcl_oop_t cons)
{
HCL_ASSERT (HCL_BRANDOF(hcl, cons));
do
{
cons = HCL_CONS_CDR(cons);
if (HCL_BRANDOF(hcl, cons) != HCL_BRAND_CONS) break;
}
while (1);
return cons;
}
hcl_oop_t hcl_reversecons (hcl_t* hcl, hcl_oop_t cons)
{
hcl_oop_t ptr, prev, next;
/* Note: The non-nil cdr in the last cons cell gets lost.
* e.g.) Reversing (1 2 3 . 4) results in (3 2 1) */
HCL_ASSERT (HCL_BRANDOF(hcl, cons));
prev = hcl->_nil;
ptr = cons;
do
{
next = HCL_CONS_CDR(ptr);
HCL_CONS_CDR(ptr) = prev;
prev = ptr;
if (HCL_BRANDOF(hcl,next) != HCL_BRAND_CONS) break;
ptr = next;
}
while (1);
return ptr;
}

467
lib/print.c Normal file
View File

@ -0,0 +1,467 @@
/*
* $Id$
*
Copyright (c) 2014-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "hcl-prv.h"
#define PRINT_STACK_ALIGN 128
struct printer_t
{
hcl_t* hcl;
hcl_ioimpl_t printer;
hcl_iooutarg_t* outarg;
};
typedef struct printer_t printer_t;
#define OUTPUT_STRX(pr,p,l) \
do { \
(pr)->outarg->ptr = p; \
(pr)->outarg->len = l; \
if ((pr)->printer((pr)->hcl, HCL_IO_WRITE, (pr)->outarg) <= -1) \
{ \
(pr)->hcl->errnum = HCL_EIOERR; \
return -1; \
} \
} while(0)
#define OUTPUT_STR(pr,p) OUTPUT_STRX(pr,p,hcl_countoocstr(p))
#define OUTPUT_CHAR(pr,ch) do { \
hcl_ooch_t tmp = ch; \
OUTPUT_STRX (pr, &tmp, 1); \
} while(0);
#define PRINT_STACK_ARRAY_END 0
#define PRINT_STACK_CONS 1
#define PRINT_STACK_ARRAY 2
typedef struct print_stack_t print_stack_t;
struct print_stack_t
{
int type;
hcl_oop_t obj;
hcl_oow_t idx;
};
static HCL_INLINE int push (hcl_t* hcl, print_stack_t* info)
{
if (hcl->p.s.size >= hcl->p.s.capa)
{
print_stack_t* tmp;
hcl_oow_t new_capa;
new_capa = HCL_ALIGN (hcl->p.s.capa + 1, PRINT_STACK_ALIGN);
tmp = hcl_reallocmem (hcl, hcl->p.s.ptr, new_capa * HCL_SIZEOF(*info));
if (!tmp) return -1;
hcl->p.s.ptr = tmp;
hcl->p.s.capa = new_capa;
}
((print_stack_t*)hcl->p.s.ptr)[hcl->p.s.size] = *info;
hcl->p.s.size++;
return 0;
}
static HCL_INLINE void pop (hcl_t* hcl, print_stack_t* info)
{
HCL_ASSERT (hcl->p.s.size > 0);
hcl->p.s.size--;
*info = ((print_stack_t*)hcl->p.s.ptr)[hcl->p.s.size];
}
static hcl_oow_t long_to_str (
hcl_ooi_t value, int radix,
const hcl_ooch_t* prefix, hcl_ooch_t* buf, hcl_oow_t size)
{
hcl_ooi_t t, rem;
hcl_oow_t len, ret, i;
hcl_oow_t prefix_len;
prefix_len = (prefix != HCL_NULL)? hcl_countoocstr(prefix): 0;
t = value;
if (t == 0)
{
/* zero */
if (buf == HCL_NULL)
{
/* if buf is not given,
* return the number of bytes required */
return prefix_len + 1;
}
if (size < prefix_len + 1)
{
/* buffer too small */
return (hcl_oow_t)-1;
}
for (i = 0; i < prefix_len; i++) buf[i] = prefix[i];
buf[prefix_len] = '0';
if (size > prefix_len+1) buf[prefix_len+1] = '\0';
return prefix_len+1;
}
/* non-zero values */
len = prefix_len;
if (t < 0) { t = -t; len++; }
while (t > 0) { len++; t /= radix; }
if (buf == HCL_NULL)
{
/* if buf is not given, return the number of bytes required */
return len;
}
if (size < len) return (hcl_oow_t)-1; /* buffer too small */
if (size > len) buf[len] = '\0';
ret = len;
t = value;
if (t < 0) t = -t;
while (t > 0)
{
rem = t % radix;
if (rem >= 10)
buf[--len] = (hcl_ooch_t)rem + 'a' - 10;
else
buf[--len] = (hcl_ooch_t)rem + '0';
t /= radix;
}
if (value < 0)
{
for (i = 1; i <= prefix_len; i++)
{
buf[i] = prefix[i-1];
len--;
}
buf[--len] = '-';
}
else
{
for (i = 0; i < prefix_len; i++) buf[i] = prefix[i];
}
return ret;
}
static HCL_INLINE int print_ooi (printer_t* pr, hcl_ooi_t nval)
{
hcl_ooch_t tmp[HCL_SIZEOF(hcl_ooi_t)*8+2];
hcl_oow_t len;
len = long_to_str (nval, 10, HCL_NULL, tmp, HCL_COUNTOF(tmp));
OUTPUT_STRX (pr, tmp, len);
return 0;
}
static HCL_INLINE int print_char (printer_t* pr, hcl_ooch_t ch)
{
OUTPUT_CHAR (pr, ch);
return 0;
}
static int print_object (printer_t* pr, hcl_oop_t obj)
{
hcl_t* hcl;
hcl_oop_t cur;
print_stack_t ps;
static struct
{
hcl_oow_t len;
hcl_ooch_t ptr[10];
} word[] =
{
{ 4, { '#','n', 'i', 'l' } },
{ 5, { '#','t', 'r', 'u', 'e' } },
{ 6, { '#','f', 'a', 'l', 's', 'e' } }
};
hcl = pr->hcl;
next:
if (HCL_OOP_IS_SMOOI(obj))
{
if (print_ooi (pr, HCL_OOP_TO_SMOOI(obj)) <= -1) return -1;
goto done;
}
else if (HCL_OOP_IS_CHAR(obj))
{
if (print_char (pr, HCL_OOP_TO_CHAR(obj)) <= -1) return -1;
goto done;
}
switch (HCL_OBJ_GET_FLAGS_BRAND(obj))
{
case HCL_BRAND_NIL:
OUTPUT_STRX (pr, word[0].ptr, word[0].len);
break;
case HCL_BRAND_TRUE:
OUTPUT_STRX (pr, word[1].ptr, word[1].len);
break;
case HCL_BRAND_FALSE:
OUTPUT_STRX (pr, word[2].ptr, word[2].len);
break;
case HCL_BRAND_INTEGER:
HCL_ASSERT (HCL_OBJ_GET_SIZE(obj) == 1);
if (print_ooi (pr, ((hcl_oop_word_t)obj)->slot[0]) <= -1) return -1;
break;
#if 0
case HCL_BRAND_REAL:
{
qse_char_t buf[256];
hcl->prm.sprintf (
hcl->prm.ctx,
buf, HCL_COUNTOF(buf),
HCL_T("%Lf"),
#ifdef __MINGW32__
(double)HCL_RVAL(obj)
#else
(long double)HCL_RVAL(obj)
#endif
);
OUTPUT_STR (hcl, buf);
break;
}
#endif
case HCL_BRAND_SYMBOL:
/* Any needs for special action if SYNT(obj) is true?
* I simply treat the syntax symbol as a normal symbol
* for printing currently. */
OUTPUT_STRX (pr, ((hcl_oop_char_t)obj)->slot, HCL_OBJ_GET_SIZE(obj));
break;
case HCL_BRAND_STRING:
OUTPUT_CHAR (pr, '\"');
/* TODO: deescaping */
OUTPUT_STRX (pr, ((hcl_oop_char_t)obj)->slot, HCL_OBJ_GET_SIZE(obj));
OUTPUT_CHAR (pr, '\"');
break;
case HCL_BRAND_CONS:
{
OUTPUT_CHAR (pr, '(');
cur = obj;
do
{
int x;
/* Push what to print next on to the stack
* the variable p is */
ps.type = PRINT_STACK_CONS;
ps.obj = HCL_CONS_CDR(cur);
x = push (hcl, &ps);
if (x <= -1) return -1;
obj = HCL_CONS_CAR(cur);
/* Jump to the 'next' label so that the object
* pointed to by 'obj' is printed. Once it
* ends, a jump back to the 'resume' label
* is made at the at of this function. */
goto next;
resume_cons:
HCL_ASSERT (ps.type == PRINT_STACK_CONS);
cur = ps.obj; /* Get back the CDR pushed */
if (HCL_IS_NIL(hcl,cur))
{
/* The CDR part points to a NIL object, which
* indicates the end of a list. break the loop */
break;
}
if (!HCL_OOP_IS_POINTER(cur) || HCL_OBJ_GET_FLAGS_BRAND(cur) != HCL_BRAND_CONS)
{
/* The CDR part does not point to a pair. */
OUTPUT_CHAR (pr, ' ');
OUTPUT_CHAR (pr, '.');
OUTPUT_CHAR (pr, ' ');
/* Push NIL so that the HCL_IS_NIL(hcl,p) test in
* the 'if' statement above breaks the loop
* after the jump is maded back to the 'resume'
* label. */
ps.type = PRINT_STACK_CONS;
ps.obj = hcl->_nil;
x = push (hcl, &ps);
if (x <= -1) return -1;
/* Make a jump to 'next' to print the CDR part */
obj = cur;
goto next;
}
/* The CDR part points to a pair. proceed to it */
OUTPUT_CHAR (pr, ' ');
}
while (1);
OUTPUT_CHAR (pr, ')');
break;
}
case HCL_BRAND_ARRAY:
{
hcl_oow_t arridx;
OUTPUT_CHAR (pr, '#');
OUTPUT_CHAR (pr, '(');
if (HCL_OBJ_GET_SIZE(obj) <= 0) goto done_array;
arridx = 0;
do
{
int x;
/* Push what to print next on to the stack
* the variable p is */
ps.idx = arridx + 1;
if (ps.idx >= HCL_OBJ_GET_SIZE(obj))
{
ps.type = PRINT_STACK_ARRAY_END;
}
else
{
ps.type = PRINT_STACK_ARRAY;
ps.obj = obj;
}
x = push (hcl, &ps);
if (x <= -1) return -1;
obj = ((hcl_oop_oop_t)obj)->slot[arridx];
if (arridx > 0) OUTPUT_CHAR (pr, ' ');
/* Jump to the 'next' label so that the object
* pointed to by 'obj' is printed. Once it
* ends, a jump back to the 'resume' label
* is made at the at of this function. */
goto next;
resume_array:
HCL_ASSERT (ps.type == PRINT_STACK_ARRAY);
arridx = ps.idx;
obj = ps.obj;
}
while (1);
done_array:
OUTPUT_CHAR (pr, ')');
break;
}
case HCL_BRAND_BYTE_ARRAY:
{
hcl_oow_t i;
OUTPUT_CHAR (pr, '#');
OUTPUT_CHAR (pr, '[');
for (i = 0; i < HCL_OBJ_GET_SIZE(obj); i++)
{
if (i > 0) OUTPUT_CHAR (pr, ' ');
if (print_ooi (pr, ((hcl_oop_byte_t)obj)->slot[i]) <= -1) return -1;
}
OUTPUT_CHAR (pr, ']');
break;
}
#if 0
case HCL_BRAND_PROCEDURE:
OUTPUT_STR (pr, "#<PROCEDURE>");
break;
case HCL_BRAND_CLOSURE:
OUTPUT_STR (pr, "#<CLOSURE>");
break;
#endif
default:
HCL_ASSERT ("Unknown object type" == HCL_NULL);
HCL_DEBUG2 (hcl, "Internal error - unknown object type at %s:%d\n", __FILE__, __LINE__);
hcl->errnum = HCL_EINTERN;
return -1;
}
done:
/* if the printing stack is not empty, we still got more to print */
while (hcl->p.s.size > 0)
{
pop (hcl, &ps);
if (ps.type == PRINT_STACK_CONS) goto resume_cons;
else if (ps.type == PRINT_STACK_ARRAY) goto resume_array;
else
{
HCL_ASSERT (ps.type == PRINT_STACK_ARRAY_END);
OUTPUT_CHAR (pr, ')');
}
}
return 0;
}
/* hcl_printobj() is for internal use only. it's called by hcl_print() and a logger. */
HCL_INLINE int hcl_printobj (hcl_t* hcl, hcl_oop_t obj, hcl_ioimpl_t printer, hcl_iooutarg_t* outarg)
{
int n;
printer_t pr;
HCL_ASSERT (hcl->c->printer != HCL_NULL);
/* the printer stack must be empty. buggy if not. */
HCL_ASSERT (hcl->p.s.size == 0);
hcl->p.e = obj; /* remember the head of the object to print */
pr.hcl = hcl;
pr.printer = printer;
pr.outarg = outarg;
n = print_object (&pr, obj); /* call the actual printing routine */
hcl->p.e = hcl->_nil; /* reset what's remembered */
/* clear the printing stack if an error has occurred for GC not to keep
* the objects in the stack */
if (n <= -1) hcl->p.s.size = 0;
/* the printer stack must get empty when done. buggy if not */
HCL_ASSERT (hcl->p.s.size == 0);
return n;
}
int hcl_print (hcl_t* hcl, hcl_oop_t obj)
{
return hcl_printobj (hcl, obj, hcl->c->printer, &hcl->c->outarg);
}

54
lib/proc.c Normal file
View File

@ -0,0 +1,54 @@
/*
* $Id$
*
Copyright (c) 2014-2015 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "hcl-prv.h"
hcl_oop_process_t hcl_addnewproc (hcl_t* hcl)
{
hcl_oop_process_t proc;
proc = (hcl_oop_process_t)hcl_instantiate (hcl, hcl->_process, HCL_NULL, hcl->option.dfl_procstk_size);
if (!proc) return HCL_NULL;
proc->state = HCL_SMOOI_TO_OOP(0);
HCL_ASSERT (HCL_OBJ_GET_SIZE(proc) == HCL_PROCESS_NAMED_INSTVARS + hcl->option.dfl_procstk_size);
return proc;
}
void hcl_schedproc (hcl_t* hcl, hcl_oop_process_t proc)
{
/* TODO: if scheduled, don't add */
/*proc->next = hcl->_active_process;
proc->_active_process = proc;*/
}
void hcl_unschedproc (hcl_t* hcl, hcl_oop_process_t proc)
{
}

1002
lib/rbt.c Normal file

File diff suppressed because it is too large Load Diff

1846
lib/read.c Normal file

File diff suppressed because it is too large Load Diff

184
lib/sym.c Normal file
View File

@ -0,0 +1,184 @@
/*
* $Id$
*
Copyright (c) 2014-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "hcl-prv.h"
static hcl_oop_oop_t expand_bucket (hcl_t* hcl, hcl_oop_oop_t oldbuc)
{
hcl_oop_oop_t newbuc;
hcl_oow_t oldsz, newsz, index;
hcl_oop_char_t symbol;
oldsz = HCL_OBJ_GET_SIZE(oldbuc);
/* TODO: better growth policy? */
if (oldsz < 5000) newsz = oldsz + oldsz;
else if (oldsz < 50000) newsz = oldsz + (oldsz / 2);
else if (oldsz < 100000) newsz = oldsz + (oldsz / 4);
else if (oldsz < 200000) newsz = oldsz + (oldsz / 8);
else if (oldsz < 400000) newsz = oldsz + (oldsz / 16);
else if (oldsz < 800000) newsz = oldsz + (oldsz / 32);
else if (oldsz < 1600000) newsz = oldsz + (oldsz / 64);
else
{
hcl_oow_t inc, inc_max;
inc = oldsz / 128;
inc_max = HCL_OBJ_SIZE_MAX - oldsz;
if (inc > inc_max)
{
if (inc_max > 0) inc = inc_max;
else
{
hcl->errnum = HCL_EOOMEM;
return HCL_NULL;
}
}
newsz = oldsz + inc;
}
hcl_pushtmp (hcl, (hcl_oop_t*)&oldbuc);
newbuc = (hcl_oop_oop_t)hcl_makearray (hcl, newsz);
hcl_poptmp (hcl);
if (!newbuc) return HCL_NULL;
while (oldsz > 0)
{
symbol = (hcl_oop_char_t)oldbuc->slot[--oldsz];
if ((hcl_oop_t)symbol != hcl->_nil)
{
HCL_ASSERT (HCL_BRANDOF(hcl,symbol) == HCL_BRAND_SYMBOL);
/*HCL_ASSERT (sym->size > 0);*/
index = hcl_hashchars(symbol->slot, HCL_OBJ_GET_SIZE(symbol)) % newsz;
while (newbuc->slot[index] != hcl->_nil) index = (index + 1) % newsz;
newbuc->slot[index] = (hcl_oop_t)symbol;
}
}
return newbuc;
}
static hcl_oop_t find_or_make_symbol (hcl_t* hcl, const hcl_ooch_t* ptr, hcl_oow_t len, int create)
{
hcl_ooi_t tally;
hcl_oow_t index;
hcl_oop_char_t symbol;
HCL_ASSERT (len > 0);
if (len <= 0)
{
/* i don't allow an empty symbol name */
hcl->errnum = HCL_EINVAL;
return HCL_NULL;
}
HCL_ASSERT (HCL_BRANDOF(hcl,hcl->symtab->bucket) == HCL_BRAND_ARRAY);
index = hcl_hashchars(ptr, len) % HCL_OBJ_GET_SIZE(hcl->symtab->bucket);
/* find a matching symbol in the open-addressed symbol table */
while (hcl->symtab->bucket->slot[index] != hcl->_nil)
{
symbol = (hcl_oop_char_t)hcl->symtab->bucket->slot[index];
HCL_ASSERT (HCL_BRANDOF(hcl,symbol) == HCL_BRAND_SYMBOL);
if (len == HCL_OBJ_GET_SIZE(symbol) &&
hcl_equalchars (ptr, symbol->slot, len))
{
return (hcl_oop_t)symbol;
}
index = (index + 1) % HCL_OBJ_GET_SIZE(hcl->symtab->bucket);
}
if (!create)
{
hcl->errnum = HCL_ENOENT;
return HCL_NULL;
}
/* make a new symbol and insert it */
HCL_ASSERT (HCL_OOP_IS_SMOOI(hcl->symtab->tally));
tally = HCL_OOP_TO_SMOOI(hcl->symtab->tally);
if (tally >= HCL_SMOOI_MAX)
{
/* this built-in table is not allowed to hold more than
* HCL_SMOOI_MAX items for efficiency sake */
hcl->errnum = HCL_EDFULL;
return HCL_NULL;
}
/* no conversion to hcl_oow_t is necessary for tally + 1.
* the maximum value of tally is checked to be HCL_SMOOI_MAX - 1.
* tally + 1 can produce at most HCL_SMOOI_MAX. above all,
* HCL_SMOOI_MAX is way smaller than HCL_TYPE_MAX(hcl_ooi_t). */
if (tally + 1 >= HCL_OBJ_GET_SIZE(hcl->symtab->bucket))
{
hcl_oop_oop_t bucket;
/* TODO: make the growth policy configurable instead of growing
it just before it gets full. The polcy can be grow it
if it's 70% full */
/* enlarge the symbol table before it gets full to
* make sure that it has at least one free slot left
* after having added a new symbol. this is to help
* traversal end at a _nil slot if no entry is found. */
bucket = expand_bucket(hcl, hcl->symtab->bucket);
if (!bucket) return HCL_NULL;
hcl->symtab->bucket = bucket;
/* recalculate the index for the expanded bucket */
index = hcl_hashchars(ptr, len) % HCL_OBJ_GET_SIZE(hcl->symtab->bucket);
while (hcl->symtab->bucket->slot[index] != hcl->_nil)
index = (index + 1) % HCL_OBJ_GET_SIZE(hcl->symtab->bucket);
}
/* create a new symbol since it isn't found in the symbol table */
symbol = (hcl_oop_char_t)hcl_alloccharobj (hcl, ptr, len);
if (symbol)
{
HCL_OBJ_SET_FLAGS_BRAND (symbol, HCL_BRAND_SYMBOL);
HCL_ASSERT (tally < HCL_SMOOI_MAX);
hcl->symtab->tally = HCL_SMOOI_TO_OOP(tally + 1);
hcl->symtab->bucket->slot[index] = (hcl_oop_t)symbol;
}
return (hcl_oop_t)symbol;
}
hcl_oop_t hcl_makesymbol (hcl_t* hcl, const hcl_ooch_t* ptr, hcl_oow_t len)
{
return find_or_make_symbol (hcl, ptr, len, 1);
}
hcl_oop_t hcl_findsymbol (hcl_t* hcl, const hcl_ooch_t* ptr, hcl_oow_t len)
{
return find_or_make_symbol (hcl, ptr, len, 0);
}

520
lib/utf8.c Normal file
View File

@ -0,0 +1,520 @@
/*
* $Id$
*
Copyright (c) 2014-2015 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "hcl-prv.h"
#define HCL_BCLEN_MAX 6
/*
* from RFC 2279 UTF-8, a transformation format of ISO 10646
*
* UCS-4 range (hex.) UTF-8 octet sequence (binary)
* 1:2 00000000-0000007F 0xxxxxxx
* 2:2 00000080-000007FF 110xxxxx 10xxxxxx
* 3:2 00000800-0000FFFF 1110xxxx 10xxxxxx 10xxxxxx
* 4:4 00010000-001FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
* inv 00200000-03FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
* inv 04000000-7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
*/
struct __utf8_t
{
hcl_uint32_t lower;
hcl_uint32_t upper;
hcl_uint8_t fbyte; /* mask to the first utf8 byte */
hcl_uint8_t mask;
hcl_uint8_t fmask;
int length; /* number of bytes */
};
typedef struct __utf8_t __utf8_t;
static __utf8_t utf8_table[] =
{
{0x00000000ul, 0x0000007Ful, 0x00, 0x80, 0x7F, 1},
{0x00000080ul, 0x000007FFul, 0xC0, 0xE0, 0x1F, 2},
{0x00000800ul, 0x0000FFFFul, 0xE0, 0xF0, 0x0F, 3},
{0x00010000ul, 0x001FFFFFul, 0xF0, 0xF8, 0x07, 4},
{0x00200000ul, 0x03FFFFFFul, 0xF8, 0xFC, 0x03, 5},
{0x04000000ul, 0x7FFFFFFFul, 0xFC, 0xFE, 0x01, 6}
};
static HCL_INLINE __utf8_t* get_utf8_slot (hcl_uch_t uc)
{
__utf8_t* cur, * end;
HCL_ASSERT (HCL_SIZEOF(hcl_bch_t) == 1);
HCL_ASSERT (HCL_SIZEOF(hcl_uch_t) >= 2);
end = utf8_table + HCL_COUNTOF(utf8_table);
cur = utf8_table;
while (cur < end)
{
if (uc >= cur->lower && uc <= cur->upper) return cur;
cur++;
}
return HCL_NULL; /* invalid character */
}
hcl_oow_t hcl_uctoutf8 (hcl_uch_t uc, hcl_bch_t* utf8, hcl_oow_t size)
{
__utf8_t* cur = get_utf8_slot (uc);
if (cur == HCL_NULL) return 0; /* illegal character */
if (utf8 && cur->length <= size)
{
int index = cur->length;
while (index > 1)
{
/*
* 0x3F: 00111111
* 0x80: 10000000
*/
utf8[--index] = (uc & 0x3F) | 0x80;
uc >>= 6;
}
utf8[0] = uc | cur->fbyte;
}
/* small buffer is also indicated by this return value
* greater than 'size'. */
return (hcl_oow_t)cur->length;
}
hcl_oow_t hcl_utf8touc (const hcl_bch_t* utf8, hcl_oow_t size, hcl_uch_t* uc)
{
__utf8_t* cur, * end;
HCL_ASSERT (utf8 != HCL_NULL);
HCL_ASSERT (size > 0);
HCL_ASSERT (HCL_SIZEOF(hcl_bch_t) == 1);
HCL_ASSERT (HCL_SIZEOF(hcl_uch_t) >= 2);
end = utf8_table + HCL_COUNTOF(utf8_table);
cur = utf8_table;
while (cur < end)
{
if ((utf8[0] & cur->mask) == cur->fbyte)
{
/* if size is less that cur->length, the incomplete-seqeunce
* error is naturally indicated. so validate the string
* only if size is as large as cur->length. */
if (size >= cur->length)
{
int i;
if (uc)
{
hcl_uch_t w;
w = utf8[0] & cur->fmask;
for (i = 1; i < cur->length; i++)
{
/* in utf8, trailing bytes are all
* set with 0x80.
*
* 10XXXXXX & 11000000 => 10000000
*
* if not, invalid. */
if ((utf8[i] & 0xC0) != 0x80) return 0;
w = (w << 6) | (utf8[i] & 0x3F);
}
*uc = w;
}
else
{
for (i = 1; i < cur->length; i++)
{
/* in utf8, trailing bytes are all
* set with 0x80.
*
* 10XXXXXX & 11000000 => 10000000
*
* if not, invalid. */
if ((utf8[i] & 0xC0) != 0x80) return 0;
}
}
}
/* this return value can indicate both
* the correct length (size >= cur->length)
* and
* the incomplete seqeunce error (size < cur->length).
*/
return (hcl_oow_t)cur->length;
}
cur++;
}
return 0; /* error - invalid sequence */
}
/* ----------------------------------------------------------------------- */
static HCL_INLINE int bcsn_to_ucsn_with_cmgr (
const hcl_bch_t* bcs, hcl_oow_t* bcslen,
hcl_uch_t* ucs, hcl_oow_t* ucslen, hcl_cmgr_t* cmgr, int all)
{
const hcl_bch_t* p;
int ret = 0;
hcl_oow_t mlen;
if (ucs)
{
/* destination buffer is specified.
* copy the conversion result to the buffer */
hcl_uch_t* q, * qend;
p = bcs;
q = ucs;
qend = ucs + *ucslen;
mlen = *bcslen;
while (mlen > 0)
{
hcl_oow_t n;
if (q >= qend)
{
/* buffer too small */
ret = -2;
break;
}
n = cmgr->bctouc (p, mlen, q);
if (n == 0)
{
/* invalid sequence */
if (all)
{
n = 1;
*q = '?';
}
else
{
ret = -1;
break;
}
}
if (n > mlen)
{
/* incomplete sequence */
if (all)
{
n = 1;
*q = '?';
}
else
{
ret = -3;
break;
}
}
q++;
p += n;
mlen -= n;
}
*ucslen = q - ucs;
*bcslen = p - bcs;
}
else
{
/* no destination buffer is specified. perform conversion
* but don't copy the result. the caller can call this function
* without a buffer to find the required buffer size, allocate
* a buffer with the size and call this function again with
* the buffer. */
hcl_uch_t w;
hcl_oow_t wlen = 0;
p = bcs;
mlen = *bcslen;
while (mlen > 0)
{
hcl_oow_t n;
n = cmgr->bctouc (p, mlen, &w);
if (n == 0)
{
/* invalid sequence */
if (all) n = 1;
else
{
ret = -1;
break;
}
}
if (n > mlen)
{
/* incomplete sequence */
if (all) n = 1;
else
{
ret = -3;
break;
}
}
p += n;
mlen -= n;
wlen += 1;
}
*ucslen = wlen;
*bcslen = p - bcs;
}
return ret;
}
static HCL_INLINE int bcs_to_ucs_with_cmgr (
const hcl_bch_t* bcs, hcl_oow_t* bcslen,
hcl_uch_t* ucs, hcl_oow_t* ucslen, hcl_cmgr_t* cmgr, int all)
{
const hcl_bch_t* bp;
hcl_oow_t mlen, wlen;
int n;
for (bp = bcs; *bp != '\0'; bp++) /* nothing */ ;
mlen = bp - bcs; wlen = *ucslen;
n = bcsn_to_ucsn_with_cmgr (bcs, &mlen, ucs, &wlen, cmgr, all);
if (ucs)
{
/* null-terminate the target buffer if it has room for it. */
if (wlen < *ucslen) ucs[wlen] = '\0';
else n = -2; /* buffer too small */
}
*bcslen = mlen; *ucslen = wlen;
return n;
}
static HCL_INLINE int ucsn_to_bcsn_with_cmgr (
const hcl_uch_t* ucs, hcl_oow_t* ucslen,
hcl_bch_t* bcs, hcl_oow_t* bcslen, hcl_cmgr_t* cmgr)
{
const hcl_uch_t* p = ucs;
const hcl_uch_t* end = ucs + *ucslen;
int ret = 0;
if (bcs)
{
hcl_oow_t rem = *bcslen;
while (p < end)
{
hcl_oow_t n;
if (rem <= 0)
{
ret = -2; /* buffer too small */
break;
}
n = cmgr->uctobc (*p, bcs, rem);
if (n == 0)
{
ret = -1;
break; /* illegal character */
}
if (n > rem)
{
ret = -2; /* buffer too small */
break;
}
bcs += n; rem -= n; p++;
}
*bcslen -= rem;
}
else
{
hcl_bch_t bcsbuf[HCL_BCLEN_MAX];
hcl_oow_t mlen = 0;
while (p < end)
{
hcl_oow_t n;
n = cmgr->uctobc (*p, bcsbuf, HCL_COUNTOF(bcsbuf));
if (n == 0)
{
ret = -1;
break; /* illegal character */
}
/* it assumes that bcsbuf is large enough to hold a character */
HCL_ASSERT (n <= HCL_COUNTOF(bcsbuf));
p++; mlen += n;
}
/* this length excludes the terminating null character.
* this function doesn't even null-terminate the result. */
*bcslen = mlen;
}
*ucslen = p - ucs;
return ret;
}
static int ucs_to_bcs_with_cmgr (
const hcl_uch_t* ucs, hcl_oow_t* ucslen,
hcl_bch_t* bcs, hcl_oow_t* bcslen, hcl_cmgr_t* cmgr)
{
const hcl_uch_t* p = ucs;
int ret = 0;
if (bcs)
{
hcl_oow_t rem = *bcslen;
while (*p != '\0')
{
hcl_oow_t n;
if (rem <= 0)
{
ret = -2;
break;
}
n = cmgr->uctobc (*p, bcs, rem);
if (n == 0)
{
ret = -1;
break; /* illegal character */
}
if (n > rem)
{
ret = -2;
break; /* buffer too small */
}
bcs += n; rem -= n; p++;
}
/* update bcslen to the length of the bcs string converted excluding
* terminating null */
*bcslen -= rem;
/* null-terminate the multibyte sequence if it has sufficient space */
if (rem > 0) *bcs = '\0';
else
{
/* if ret is -2 and cs[cslen] == '\0',
* this means that the bcs buffer was lacking one
* slot for the terminating null */
ret = -2; /* buffer too small */
}
}
else
{
hcl_bch_t bcsbuf[HCL_BCLEN_MAX];
hcl_oow_t mlen = 0;
while (*p != '\0')
{
hcl_oow_t n;
n = cmgr->uctobc (*p, bcsbuf, HCL_COUNTOF(bcsbuf));
if (n == 0)
{
ret = -1;
break; /* illegal character */
}
/* it assumes that bcs is large enough to hold a character */
HCL_ASSERT (n <= HCL_COUNTOF(bcs));
p++; mlen += n;
}
/* this length holds the number of resulting multi-byte characters
* excluding the terminating null character */
*bcslen = mlen;
}
*ucslen = p - ucs; /* the number of wide characters handled. */
return ret;
}
static hcl_cmgr_t utf8_cmgr =
{
hcl_utf8touc,
hcl_uctoutf8
};
int hcl_utf8toucs (const hcl_bch_t* bcs, hcl_oow_t* bcslen, hcl_uch_t* ucs, hcl_oow_t* ucslen)
{
if (*bcslen == ~(hcl_oow_t)0)
{
/* the source is null-terminated. */
return bcs_to_ucs_with_cmgr (bcs, bcslen, ucs, ucslen, &utf8_cmgr, 0);
}
else
{
/* the source is length bound */
return bcsn_to_ucsn_with_cmgr (bcs, bcslen, ucs, ucslen, &utf8_cmgr, 0);
}
}
int hcl_ucstoutf8 (const hcl_uch_t* ucs, hcl_oow_t *ucslen, hcl_bch_t* bcs, hcl_oow_t* bcslen)
{
if (*ucslen == ~(hcl_oow_t)0)
{
/* null-terminated */
return ucs_to_bcs_with_cmgr (ucs, ucslen, bcs, bcslen, &utf8_cmgr);
}
else
{
/* length bound */
return ucsn_to_bcsn_with_cmgr (ucs, ucslen, bcs, bcslen, &utf8_cmgr);
}
}
/*
hcl_oow_t hcl_ucslen (const hcl_uch_t* ucs)
{
const hcl_uch_t* ptr = ucs;
while (*ptr) ptr = HCL_INCPTR(const hcl_uch_t, ptr, 1);
return HCL_SUBPTR(const hcl_uch_t, ptr, ucs);
}
*/

191
lib/utl.c Normal file
View File

@ -0,0 +1,191 @@
/*
* $Id$
*
Copyright (c) 2014-2015 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "hcl-utl.h"
hcl_oow_t hcl_hashbytes (const hcl_oob_t* ptr, hcl_oow_t len)
{
hcl_oow_t h = 0;
const hcl_uint8_t* bp, * be;
bp = ptr; be = bp + len;
while (bp < be) h = h * 31 + *bp++;
return h;
}
hcl_oow_t hcl_hashuchars (const hcl_uch_t* ptr, hcl_oow_t len)
{
return hcl_hashbytes ((const hcl_oob_t *)ptr, len * HCL_SIZEOF(*ptr));
}
int hcl_equalchars (const hcl_uch_t* str1, const hcl_uch_t* str2, hcl_oow_t len)
{
hcl_oow_t i;
for (i = 0; i < len; i++)
{
if (str1[i] != str2[i]) return 0;
}
return 1;
}
int hcl_compucstr (const hcl_uch_t* str1, const hcl_uch_t* str2)
{
while (*str1 == *str2)
{
if (*str1 == '\0') return 0;
str1++, str2++;
}
return (*str1 > *str2)? 1: -1;
}
int hcl_compbcstr (const hcl_bch_t* str1, const hcl_bch_t* str2)
{
while (*str1 == *str2)
{
if (*str1 == '\0') return 0;
str1++, str2++;
}
return (*str1 > *str2)? 1: -1;
}
int hcl_compucbcstr (const hcl_uch_t* str1, const hcl_bch_t* str2)
{
while (*str1 == *str2)
{
if (*str1 == '\0') return 0;
str1++, str2++;
}
return (*str1 > *str2)? 1: -1;
}
int hcl_compucxbcstr (const hcl_uch_t* str1, hcl_oow_t len, const hcl_bch_t* str2)
{
const hcl_uch_t* end = str1 + len;
while (str1 < end && *str2 != '\0' && *str1 == *str2) str1++, str2++;
if (str1 == end && *str2 == '\0') return 0;
if (*str1 == *str2) return (str1 < end)? 1: -1;
return (*str1 > *str2)? 1: -1;
}
void hcl_copyuchars (hcl_uch_t* dst, const hcl_uch_t* src, hcl_oow_t len)
{
hcl_oow_t i;
for (i = 0; i < len; i++) dst[i] = src[i];
}
void hcl_copybchars (hcl_bch_t* dst, const hcl_bch_t* src, hcl_oow_t len)
{
hcl_oow_t i;
for (i = 0; i < len; i++) dst[i] = src[i];
}
void hcl_copybchtouchars (hcl_uch_t* dst, const hcl_bch_t* src, hcl_oow_t len)
{
hcl_oow_t i;
for (i = 0; i < len; i++) dst[i] = src[i];
}
hcl_oow_t hcl_copyucstr (hcl_uch_t* dst, hcl_oow_t len, const hcl_uch_t* src)
{
hcl_uch_t* p, * p2;
p = dst; p2 = dst + len - 1;
while (p < p2)
{
if (*src == '\0') break;
*p++ = *src++;
}
if (len > 0) *p = '\0';
return p - dst;
}
hcl_oow_t hcl_copybcstr (hcl_bch_t* dst, hcl_oow_t len, const hcl_bch_t* src)
{
hcl_bch_t* p, * p2;
p = dst; p2 = dst + len - 1;
while (p < p2)
{
if (*src == '\0') break;
*p++ = *src++;
}
if (len > 0) *p = '\0';
return p - dst;
}
hcl_oow_t hcl_countucstr (const hcl_uch_t* str)
{
const hcl_uch_t* ptr = str;
while (*ptr != '\0') ptr++;
return ptr - str;
}
hcl_oow_t hcl_countbcstr (const hcl_bch_t* str)
{
const hcl_bch_t* ptr = str;
while (*ptr != '\0') ptr++;
return ptr - str;
}
hcl_uch_t* hcl_finduchar (const hcl_uch_t* ptr, hcl_oow_t len, hcl_uch_t c)
{
const hcl_uch_t* end;
end = ptr + len;
while (ptr < end)
{
if (*ptr == c) return (hcl_uch_t*)ptr;
ptr++;
}
return HCL_NULL;
}
hcl_bch_t* hcl_findbchar (const hcl_bch_t* ptr, hcl_oow_t len, hcl_bch_t c)
{
const hcl_bch_t* end;
end = ptr + len;
while (ptr < end)
{
if (*ptr == c) return (hcl_bch_t*)ptr;
ptr++;
}
return HCL_NULL;
}