diff --git a/Makefile b/Makefile
index 78dfa62..1f914c1 100644
--- a/Makefile
+++ b/Makefile
@@ -19,6 +19,7 @@ all:
${MAKE} -C kc3s all
${MAKE} -C ekc3 all
${MAKE} -C http all
+ ${MAKE} -C httpd all
${MAKE} -C test all
${MAKE} -C libkc3_window all
@@ -30,6 +31,7 @@ asan:
${MAKE} -C kc3s asan
${MAKE} -C ekc3 asan
${MAKE} -C http asan
+ ${MAKE} -C httpd asan
${MAKE} -C test asan
${MAKE} -C libkc3_window asan
@@ -42,6 +44,7 @@ build:
${MAKE} -C kc3s build
${MAKE} -C ekc3 build
${MAKE} -C http build
+ ${MAKE} -C httpd build
${MAKE} -C test build
${MAKE} -C libkc3_window build
@@ -53,6 +56,7 @@ clean:
${MAKE} -C kc3s clean
${MAKE} -C ekc3 clean
${MAKE} -C http clean
+ ${MAKE} -C httpd clean
${MAKE} -C test clean
${MAKE} -C libkc3_window clean
@@ -63,6 +67,7 @@ clean_cov:
${MAKE} -C kc3s clean_cov
${MAKE} -C ekc3 clean_cov
${MAKE} -C http clean_cov
+ ${MAKE} -C httpd clean_cov
${MAKE} -C test clean_cov
${MAKE} -C libkc3_window clean_cov
@@ -74,6 +79,7 @@ cov:
${MAKE} -C kc3s cov
${MAKE} -C ekc3 cov
${MAKE} -C http cov
+ ${MAKE} -C httpd cov
${MAKE} -C test cov
${MAKE} -C libkc3_window cov
@@ -85,6 +91,7 @@ debug:
${MAKE} -C kc3s debug
${MAKE} -C ekc3 debug
${MAKE} -C http debug
+ ${MAKE} -C httpd debug
${MAKE} -C test debug
${MAKE} -C libkc3_window debug
@@ -123,6 +130,16 @@ http:
${MAKE} -C ekc3 build
${MAKE} -C http build
+httpd:
+ ${MAKE} -C libtommath build
+ ${MAKE} -C ucd2c
+ ${MAKE} -C libkc3 build
+ ${MAKE} -C ikc3 build
+ ${MAKE} -C kc3s build
+ ${MAKE} -C ekc3 build
+ ${MAKE} -C http build
+ ${MAKE} -C httpd build
+
kc3-${KC3_VERSION}.tar.gz: kc3.index
rm -rf kc3-${KC3_VERSION}.old
-mv kc3-${KC3_VERSION} kc3-${KC3_VERSION}.old
@@ -141,6 +158,7 @@ distclean:
${MAKE} -C kc3s distclean
${MAKE} -C ekc3 distclean
${MAKE} -C http distclean
+ ${MAKE} -C httpd distclean
${MAKE} -C test distclean
${MAKE} -C libkc3_window distclean
@@ -150,6 +168,7 @@ gcovr:
${MAKE} -C kc3s gcovr
${MAKE} -C ekc3 gcovr
${MAKE} -C http gcovr
+ ${MAKE} -C httpd gcovr
${MAKE} -C test gcovr
${MAKE} -C libkc3_window gcovr
if [ -d "$$HOME/Downloads/kc3_gcovr" ]; then bin/gcovr-to-downloads; fi
@@ -230,6 +249,7 @@ install:
${MAKE} -C kc3s install
${MAKE} -C ekc3 install
${MAKE} -C http install
+ ${MAKE} -C httpd install
${MAKE} -C libkc3_window install
lib_links_linux:
@@ -286,6 +306,7 @@ test:
${MAKE} -C kc3s build
${MAKE} -C ekc3 build
${MAKE} -C http build
+ ${MAKE} -C httpd build
${MAKE} -C test test
if ${HAVE_ASAN}; then ${MAKE} test_asan; fi
@@ -297,6 +318,7 @@ test_asan:
${MAKE} -C kc3s asan
${MAKE} -C ekc3 asan
${MAKE} -C http asan
+ ${MAKE} -C httpd asan
${MAKE} -C test test_asan
test_cov:
@@ -307,6 +329,7 @@ test_cov:
${MAKE} -C kc3s cov clean_cov
${MAKE} -C ekc3 cov clean_cov
${MAKE} -C http cov clean_cov
+ ${MAKE} -C httpd cov clean_cov
${MAKE} -C test test_cov
test_debug:
@@ -317,6 +340,7 @@ test_debug:
${MAKE} -C kc3s debug
${MAKE} -C ekc3 debug
${MAKE} -C http debug
+ ${MAKE} -C httpd debug
${MAKE} -C test test_debug
test_ekc3:
@@ -465,6 +489,7 @@ test_libkc3_debug:
dist \
gcovr \
http \
+ httpd \
ikc3 \
install \
libkc3 \
diff --git a/env b/env
index de90e5d..39926f6 100644
--- a/env
+++ b/env
@@ -1 +1,3 @@
export LD_LIBRARY_PATH="$PWD/libkc3/.libs:$PWD/ekc3/.libs:$PWD/lib/kc3/0.1:$LD_LIBRARY_PATH"
+export KC3_HTTPD_HOST=0.0.0.0
+export KC3_HTTPD_PORT=58000
diff --git a/httpd/Makefile b/httpd/Makefile
new file mode 100644
index 0000000..ff04799
--- /dev/null
+++ b/httpd/Makefile
@@ -0,0 +1,70 @@
+## kc3
+## Copyright 2022-2024 kmx.io <contact@kmx.io>
+##
+## Permission is hereby granted to use this software granted the above
+## copyright notice and this permission paragraph are included in all
+## copies and substantial portions of this software.
+##
+## THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+## PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+## AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+## THIS SOFTWARE.
+
+CLEANFILES = *.a kc3_httpd kc3_httpd_asan kc3_httpd_cov kc3_httpd_debug *.css *.gcno *.html *.o .libs *.lo
+
+CLEANFILES_COV = *.css *.gcda *.html .libs/*.gcda
+CLEANFILES += ${CLEANFILES_COV}
+
+DISTCLEANFILES = ${CLEANFILES} config.mk
+
+build: kc3_httpd
+
+all:
+ ${MAKE} build
+ if ${HAVE_GCOV}; then ${MAKE} cov; fi
+ ${MAKE} debug
+ if ${HAVE_ASAN}; then ${MAKE} asan; fi
+
+asan: kc3_httpd_asan
+
+clean:
+ rm -rf ${CLEANFILES}
+
+clean_cov:
+ rm -rf ${CLEANFILES_COV}
+
+cov: kc3_httpd_cov
+
+debug: kc3_httpd_debug
+
+distclean:
+ rm -rf ${DISTCLEANFILES}
+
+gcovr:
+ gcovr --gcov-executable ${GCOV} --html-details kc3_httpd.html
+
+gdb_httpd: debug
+ if [ -f kc3_httpd_debug.core ]; then gdb .libs/kc3_httpd_debug kc3_httpd_debug.core; else gdb .libs/kc3_httpd_debug; fi
+
+install:
+ mkdir -p ${prefix}/bin
+ install -m 755 kc3_httpd ${prefix}/bin/kc3_httpd
+
+lldb_httpd: debug
+ if [ -f kc3_httpd_debug.core ]; then lldb .libs/kc3_httpd_debug kc3_httpd_debug.core; else lldb .libs/kc3_httpd_debug; fi
+
+.PHONY: \
+ all \
+ asan \
+ clean \
+ clean_cov \
+ cov \
+ debug \
+ distclean \
+ gdb_httpd \
+ install \
+ lldb_httpd \
+ update_sources \
+
+include config.mk
+include sources.mk
diff --git a/httpd/configure b/httpd/configure
index dac1451..91a939c 100755
--- a/httpd/configure
+++ b/httpd/configure
@@ -29,6 +29,7 @@ PROG_DEBUG=kc3_httpd_debug
. ./sources.sh
# Common config for all targets
+CPPFLAGS="-I .."
CFLAGS="$CFLAGS -W -Wall -Werror -std=c11 -pedantic -fPIC"
LDFLAGS="$LDFLAGS -rdynamic"
config_asan
@@ -39,6 +40,7 @@ pkg_config libffi
pkg_config libmd
config_lib libmd -lmd 2>/dev/null
config_lib dl -ldl 2>/dev/null
+config_define PREFIX "\"${PREFIX}\""
LIBS="$LIBS -pthread"
update_config_h
@@ -56,6 +58,7 @@ OBJECTS_DEBUG="$(c2ext .debug.lo "$SOURCES")"
echo "OBJECTS_DEBUG = $OBJECTS_DEBUG" >> ${CONFIG_MK}
# Asan config
+CPPFLAGS_ASAN="$CPPFLAGS"
CFLAGS_ASAN="$CFLAGS -DDEBUG -O1 -g"
CFLAGS_ASAN="$CFLAGS_ASAN -fsanitize=address -fno-omit-frame-pointer"
LDFLAGS_ASAN="$LDFLAGS"
@@ -63,6 +66,7 @@ LOCAL_LIBS_ASAN="../libkc3/libkc3_asan.la ../http/libkc3_http.la"
LIBS_ASAN="$LOCAL_LIBS_ASAN $LIBS"
# Coverage config
+CPPFLAGS_COV="$CPPFLAGS"
CFLAGS_COV="$CFLAGS -fprofile-arcs -ftest-coverage"
LDFLAGS_COV="$LDFLAGS --coverage"
LIBKC3_COV=
@@ -70,6 +74,7 @@ LOCAL_LIBS_COV="../libkc3/libkc3_cov.la ../http/libkc3_http_cov.la"
LIBS_COV="$LOCAL_LIBS_COV $LIBS -lgcov"
# Debug config
+CPPFLAGS_DEBUG="$CPPFLAGS"
CFLAGS_DEBUG="$CFLAGS -DDEBUG -O0 -g"
LDFLAGS_DEBUG="$LDFLAGS"
LOCAL_LIBS_DEBUG="../libkc3/libkc3_debug.la ../http/libkc3_http_debug.la"
@@ -90,14 +95,17 @@ echo "CFLAGS = $CFLAGS" >> ${CONFIG_MK}
echo "LDFLAGS = $LDFLAGS" >> ${CONFIG_MK}
echo "LIBS = $LIBS" >> ${CONFIG_MK}
echo >> ${CONFIG_MK}
+echo "CPPFLAGS_ASAN = $CPPFLAGS_ASAN" >> ${CONFIG_MK}
echo "CFLAGS_ASAN = $CFLAGS_ASAN" >> ${CONFIG_MK}
echo "LDFLAGS_ASAN = $LDFLAGS_ASAN" >> ${CONFIG_MK}
echo "LIBS_ASAN = $LIBS_ASAN" >> ${CONFIG_MK}
echo >> ${CONFIG_MK}
+echo "CPPFLAGS_COV = $CPPFLAGS_COV" >> ${CONFIG_MK}
echo "CFLAGS_COV = $CFLAGS_COV" >> ${CONFIG_MK}
echo "LDFLAGS_COV = $LDFLAGS_COV" >> ${CONFIG_MK}
echo "LIBS_COV = $LIBS_COV" >> ${CONFIG_MK}
echo >> ${CONFIG_MK}
+echo "CPPFLAGS_DEBUG = $CPPFLAGS_DEBUG" >> ${CONFIG_MK}
echo "CFLAGS_DEBUG = $CFLAGS_DEBUG" >> ${CONFIG_MK}
echo "LDFLAGS_DEBUG = $LDFLAGS_DEBUG" >> ${CONFIG_MK}
echo "LIBS_DEBUG = $LIBS_DEBUG" >> ${CONFIG_MK}
diff --git a/httpd/httpd.c b/httpd/httpd.c
new file mode 100644
index 0000000..98dc664
--- /dev/null
+++ b/httpd/httpd.c
@@ -0,0 +1,28 @@
+/* kc3
+ * Copyright 2022,2023,2024 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#include <libkc3/kc3.h>
+#include "config.h"
+
+int main (int argc, char **argv)
+{
+ s_str path;
+ kc3_init(NULL, &argc, &argv);
+ if (! module_path(sym_1("HTTPd"), &g_kc3_env.module_path, KC3_EXT,
+ &path)) {
+ kc3_clean(NULL);
+ return 1;
+ }
+ kc3_load(&path);
+ kc3_clean(NULL);
+ return 0;
+}
diff --git a/httpd/httpd.h b/httpd/httpd.h
new file mode 100644
index 0000000..fed5dbe
--- /dev/null
+++ b/httpd/httpd.h
@@ -0,0 +1,18 @@
+/* kc3
+ * Copyright 2022,2023,2024 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#ifndef KC3_HTTPD_H
+#define KC3_HTTPD_H
+
+#include <libkc3/http/types.h>
+
+#endif /* KC3_HTTPD_H */
diff --git a/httpd/kc3_httpd b/httpd/kc3_httpd
new file mode 100755
index 0000000..3845b5b
--- /dev/null
+++ b/httpd/kc3_httpd
@@ -0,0 +1,210 @@
+#! /bin/sh
+
+# kc3_httpd - temporary wrapper script for .libs/kc3_httpd
+# Generated by libtool (GNU libtool) 2.4.2
+#
+# The kc3_httpd program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=""
+
+# This environment variable determines our operation mode.
+if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then
+ # install mode needs the following variables:
+ generated_by_libtool_version='2.4.2'
+ notinst_deplibs=' ../libkc3/libkc3.la ../http/libkc3_http.la'
+else
+ # When we are sourced in execute mode, $file and $ECHO are already set.
+ if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
+ file="$0"
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+ ECHO="print -r --"
+ fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ which is used only on
+# windows platforms, and (c) all begin with the string --lt-
+# (application programs are unlikely to have options which match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's /usr/local/bin/libtool value, followed by no.
+lt_option_debug=
+func_parse_lt_options ()
+{
+ lt_script_arg0=$0
+ shift
+ for lt_opt
+ do
+ case "$lt_opt" in
+ --lt-debug) lt_option_debug=1 ;;
+ --lt-dump-script)
+ lt_dump_D=`$ECHO "X$lt_script_arg0" | /usr/bin/sed -e 's/^X//' -e 's%/[^/]*$%%'`
+ test "X$lt_dump_D" = "X$lt_script_arg0" && lt_dump_D=.
+ lt_dump_F=`$ECHO "X$lt_script_arg0" | /usr/bin/sed -e 's/^X//' -e 's%^.*/%%'`
+ cat "$lt_dump_D/$lt_dump_F"
+ exit 0
+ ;;
+ --lt-*)
+ $ECHO "Unrecognized --lt- option: '$lt_opt'" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+
+ # Print the debug banner immediately:
+ if test -n "$lt_option_debug"; then
+ echo "kc3_httpd:kc3_httpd:${LINENO}: libtool wrapper (GNU libtool) 2.4.2" 1>&2
+ fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+ lt_dump_args_N=1;
+ for lt_arg
+ do
+ $ECHO "kc3_httpd:kc3_httpd:${LINENO}: newargv[$lt_dump_args_N]: $lt_arg"
+ lt_dump_args_N=`expr $lt_dump_args_N + 1`
+ done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+
+ if test -n "$lt_option_debug"; then
+ $ECHO "kc3_httpd:kc3_httpd:${LINENO}: newargv[0]: $progdir/$program" 1>&2
+ func_lt_dump_args ${1+"$@"} 1>&2
+ fi
+ exec "$progdir/$program" ${1+"$@"}
+
+ $ECHO "$0: cannot exec $program $*" 1>&2
+ exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from $@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+ case " $* " in
+ *\ --lt-*)
+ for lt_wr_arg
+ do
+ case $lt_wr_arg in
+ --lt-*) ;;
+ *) set x "$@" "$lt_wr_arg"; shift;;
+ esac
+ shift
+ done ;;
+ esac
+ func_exec_program_core ${1+"$@"}
+}
+
+ # Parse options
+ func_parse_lt_options "$0" ${1+"$@"}
+
+ # Find the directory that this script lives in.
+ thisdir=`$ECHO "$file" | /usr/bin/sed 's%/[^/]*$%%'`
+ test "x$thisdir" = "x$file" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=`ls -ld "$file" | /usr/bin/sed -n 's/.*-> //p'`
+ while test -n "$file"; do
+ destdir=`$ECHO "$file" | /usr/bin/sed 's%/[^/]*$%%'`
+
+ # If there was a directory component, then change thisdir.
+ if test "x$destdir" != "x$file"; then
+ case "$destdir" in
+ [\\/]* | [A-Za-z]:[\\/]*) thisdir="$destdir" ;;
+ *) thisdir="$thisdir/$destdir" ;;
+ esac
+ fi
+
+ file=`$ECHO "$file" | /usr/bin/sed 's%^.*/%%'`
+ file=`ls -ld "$thisdir/$file" | /usr/bin/sed -n 's/.*-> //p'`
+ done
+
+ # Usually 'no', except on cygwin/mingw when embedded into
+ # the cwrapper.
+ WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=no
+ if test "$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR" = "yes"; then
+ # special case for '.'
+ if test "$thisdir" = "."; then
+ thisdir=`pwd`
+ fi
+ # remove .libs from thisdir
+ case "$thisdir" in
+ *[\\/].libs ) thisdir=`$ECHO "$thisdir" | /usr/bin/sed 's%[\\/][^\\/]*$%%'` ;;
+ .libs ) thisdir=. ;;
+ esac
+ fi
+
+ # Try to get the absolute directory name.
+ absdir=`cd "$thisdir" && pwd`
+ test -n "$absdir" && thisdir="$absdir"
+
+ program='kc3_httpd'
+ progdir="$thisdir/.libs"
+
+
+ if test -f "$progdir/$program"; then
+ # Add our own library path to LD_LIBRARY_PATH
+ LD_LIBRARY_PATH="/home/dx/c/thodg/kc3-lang/kc3/libkc3/.libs:/home/dx/c/thodg/kc3-lang/kc3/http/.libs:/usr/local/lib:$LD_LIBRARY_PATH"
+
+ # Some systems cannot cope with colon-terminated LD_LIBRARY_PATH
+ # The second colon is a workaround for a bug in BeOS R4 sed
+ LD_LIBRARY_PATH=`$ECHO "$LD_LIBRARY_PATH" | /usr/bin/sed 's/::*$//'`
+
+ export LD_LIBRARY_PATH
+
+ if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
+ # Run the actual program with our arguments.
+ func_exec_program ${1+"$@"}
+ fi
+ else
+ # The program doesn't exist.
+ $ECHO "$0: error: \`$progdir/$program' does not exist" 1>&2
+ $ECHO "This script is just a wrapper for $program." 1>&2
+ $ECHO "See the libtool documentation for more information." 1>&2
+ exit 1
+ fi
+fi
diff --git a/httpd/kc3_httpd_debug b/httpd/kc3_httpd_debug
new file mode 100755
index 0000000..9affeae
--- /dev/null
+++ b/httpd/kc3_httpd_debug
@@ -0,0 +1,210 @@
+#! /bin/sh
+
+# kc3_httpd_debug - temporary wrapper script for .libs/kc3_httpd_debug
+# Generated by libtool (GNU libtool) 2.4.2
+#
+# The kc3_httpd_debug program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=""
+
+# This environment variable determines our operation mode.
+if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then
+ # install mode needs the following variables:
+ generated_by_libtool_version='2.4.2'
+ notinst_deplibs=' ../libkc3/libkc3_debug.la ../http/libkc3_http_debug.la'
+else
+ # When we are sourced in execute mode, $file and $ECHO are already set.
+ if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
+ file="$0"
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+ ECHO="print -r --"
+ fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ which is used only on
+# windows platforms, and (c) all begin with the string --lt-
+# (application programs are unlikely to have options which match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's /usr/local/bin/libtool value, followed by no.
+lt_option_debug=
+func_parse_lt_options ()
+{
+ lt_script_arg0=$0
+ shift
+ for lt_opt
+ do
+ case "$lt_opt" in
+ --lt-debug) lt_option_debug=1 ;;
+ --lt-dump-script)
+ lt_dump_D=`$ECHO "X$lt_script_arg0" | /usr/bin/sed -e 's/^X//' -e 's%/[^/]*$%%'`
+ test "X$lt_dump_D" = "X$lt_script_arg0" && lt_dump_D=.
+ lt_dump_F=`$ECHO "X$lt_script_arg0" | /usr/bin/sed -e 's/^X//' -e 's%^.*/%%'`
+ cat "$lt_dump_D/$lt_dump_F"
+ exit 0
+ ;;
+ --lt-*)
+ $ECHO "Unrecognized --lt- option: '$lt_opt'" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+
+ # Print the debug banner immediately:
+ if test -n "$lt_option_debug"; then
+ echo "kc3_httpd_debug:kc3_httpd_debug:${LINENO}: libtool wrapper (GNU libtool) 2.4.2" 1>&2
+ fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+ lt_dump_args_N=1;
+ for lt_arg
+ do
+ $ECHO "kc3_httpd_debug:kc3_httpd_debug:${LINENO}: newargv[$lt_dump_args_N]: $lt_arg"
+ lt_dump_args_N=`expr $lt_dump_args_N + 1`
+ done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+
+ if test -n "$lt_option_debug"; then
+ $ECHO "kc3_httpd_debug:kc3_httpd_debug:${LINENO}: newargv[0]: $progdir/$program" 1>&2
+ func_lt_dump_args ${1+"$@"} 1>&2
+ fi
+ exec "$progdir/$program" ${1+"$@"}
+
+ $ECHO "$0: cannot exec $program $*" 1>&2
+ exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from $@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+ case " $* " in
+ *\ --lt-*)
+ for lt_wr_arg
+ do
+ case $lt_wr_arg in
+ --lt-*) ;;
+ *) set x "$@" "$lt_wr_arg"; shift;;
+ esac
+ shift
+ done ;;
+ esac
+ func_exec_program_core ${1+"$@"}
+}
+
+ # Parse options
+ func_parse_lt_options "$0" ${1+"$@"}
+
+ # Find the directory that this script lives in.
+ thisdir=`$ECHO "$file" | /usr/bin/sed 's%/[^/]*$%%'`
+ test "x$thisdir" = "x$file" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=`ls -ld "$file" | /usr/bin/sed -n 's/.*-> //p'`
+ while test -n "$file"; do
+ destdir=`$ECHO "$file" | /usr/bin/sed 's%/[^/]*$%%'`
+
+ # If there was a directory component, then change thisdir.
+ if test "x$destdir" != "x$file"; then
+ case "$destdir" in
+ [\\/]* | [A-Za-z]:[\\/]*) thisdir="$destdir" ;;
+ *) thisdir="$thisdir/$destdir" ;;
+ esac
+ fi
+
+ file=`$ECHO "$file" | /usr/bin/sed 's%^.*/%%'`
+ file=`ls -ld "$thisdir/$file" | /usr/bin/sed -n 's/.*-> //p'`
+ done
+
+ # Usually 'no', except on cygwin/mingw when embedded into
+ # the cwrapper.
+ WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=no
+ if test "$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR" = "yes"; then
+ # special case for '.'
+ if test "$thisdir" = "."; then
+ thisdir=`pwd`
+ fi
+ # remove .libs from thisdir
+ case "$thisdir" in
+ *[\\/].libs ) thisdir=`$ECHO "$thisdir" | /usr/bin/sed 's%[\\/][^\\/]*$%%'` ;;
+ .libs ) thisdir=. ;;
+ esac
+ fi
+
+ # Try to get the absolute directory name.
+ absdir=`cd "$thisdir" && pwd`
+ test -n "$absdir" && thisdir="$absdir"
+
+ program='kc3_httpd_debug'
+ progdir="$thisdir/.libs"
+
+
+ if test -f "$progdir/$program"; then
+ # Add our own library path to LD_LIBRARY_PATH
+ LD_LIBRARY_PATH="/home/dx/c/thodg/kc3-lang/kc3/libkc3/.libs:/home/dx/c/thodg/kc3-lang/kc3/http/.libs:/usr/local/lib:$LD_LIBRARY_PATH"
+
+ # Some systems cannot cope with colon-terminated LD_LIBRARY_PATH
+ # The second colon is a workaround for a bug in BeOS R4 sed
+ LD_LIBRARY_PATH=`$ECHO "$LD_LIBRARY_PATH" | /usr/bin/sed 's/::*$//'`
+
+ export LD_LIBRARY_PATH
+
+ if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
+ # Run the actual program with our arguments.
+ func_exec_program ${1+"$@"}
+ fi
+ else
+ # The program doesn't exist.
+ $ECHO "$0: error: \`$progdir/$program' does not exist" 1>&2
+ $ECHO "This script is just a wrapper for $program." 1>&2
+ $ECHO "See the libtool documentation for more information." 1>&2
+ exit 1
+ fi
+fi
diff --git a/httpd/sources.mk b/httpd/sources.mk
new file mode 100644
index 0000000..f42227c
--- /dev/null
+++ b/httpd/sources.mk
@@ -0,0 +1,7 @@
+# sources.mk generated by update_sources
+HEADERS = \
+ "httpd.h" \
+
+SOURCES = \
+ "httpd.c" \
+
diff --git a/httpd/sources.sh b/httpd/sources.sh
new file mode 100644
index 0000000..bb735b8
--- /dev/null
+++ b/httpd/sources.sh
@@ -0,0 +1,3 @@
+# sources.sh generated by update_sources
+HEADERS='httpd.h '
+SOURCES='httpd.c '
diff --git a/lib/kc3/0.1/httpd.kc3 b/lib/kc3/0.1/httpd.kc3
new file mode 100644
index 0000000..84d24c6
--- /dev/null
+++ b/lib/kc3/0.1/httpd.kc3
@@ -0,0 +1,37 @@
+defmodule HTTPd do
+
+ def server_loop = fn (client) do
+ while true do
+ req = HTTP.Request.buf_parse(client.buf_rw.r)
+ res = %HTTP.Response{body: """
+<html>
+ <head>
+ <title>KC3 HTTPd</title>
+ </head>
+ <body>
+ <h1>KC3 HTTPd</h1>
+ <p>
+ Hello from #{__FILE__}
+ </p>
+ <h2>Request</h2>
+ <pre><code>#{req}</code></pre>
+ </body>
+</html>
+"""}
+ if HTTP.Response.buf_write(res, client.buf_rw.w) < 0
+ break
+ end
+ end
+
+ def server = fn (host, port) do
+ socket = Socket.listen(host, port)
+ puts("KC3 HTTPd: listening on #{host}:#{port}")
+ while true do
+ client = Socket.Buf.accept(socket)
+ HTTPd.server_loop(client)
+ end
+ end
+
+ HTTPd.server(getenv("KC3_HTTPD_HOST"), getenv("KC3_HTTPD_PORT"))
+
+end
diff --git a/lib/kc3/0.1/kc3.facts b/lib/kc3/0.1/kc3.facts
index 58705b0..f728ab9 100644
--- a/lib/kc3/0.1/kc3.facts
+++ b/lib/kc3/0.1/kc3.facts
@@ -263,3 +263,7 @@ add {KC3, :symbol, KC3.load}
replace {KC3.load, :symbol_value, cfn Bool "kc3_load" (Str)}
add {KC3, :symbol, KC3.must_clean}
replace {KC3.must_clean, :symbol_value, cfn Bool "kc3_must_clean" (Sym, Result)}
+add {KC3, :symbol, KC3.while}
+replace {KC3.while, :arity, 2}
+replace {KC3.while, :is_a, :special_operator}
+replace {KC3.while, :symbol_value, cfn Tag "kc3_while" (Tag, Tag, Result)}
diff --git a/libkc3/env.c b/libkc3/env.c
index bfbc71b..64546e8 100644
--- a/libkc3/env.c
+++ b/libkc3/env.c
@@ -3134,3 +3134,32 @@ s_tag * env_unwind_protect (s_env *env, s_tag *protected, s_block *cleanup,
env_eval_block(env, cleanup, &tmp);
return dest;
}
+
+s_tag * env_while (s_env *env, const s_tag *cond, const s_tag *body,
+ s_tag *dest)
+{
+ s_tag cond_bool = {0};
+ s_call cond_cast = {0};
+ s_tag tmp = {0};
+ call_init_call_cast(&cond_cast, &g_sym_Bool);
+ if (! tag_init_copy(&cond_cast.arguments->tag, cond))
+ goto ko;
+ while (1) {
+ tag_clean(&tmp);
+ if (! env_eval_call(env, &cond_cast, &cond_bool))
+ goto ko;
+ if (cond_bool.type != TAG_BOOL)
+ goto ko;
+ if (! cond_bool.data.bool)
+ break;
+ if (! env_eval_tag(env, body, &tmp))
+ goto ko;
+ }
+ call_clean(&cond_cast);
+ *dest = tmp;
+ return dest;
+ ko:
+ tag_clean(&tmp);
+ call_clean(&cond_cast);
+ return NULL;
+ }
diff --git a/libkc3/env.h b/libkc3/env.h
index 0410921..c8ff46c 100644
--- a/libkc3/env.h
+++ b/libkc3/env.h
@@ -214,6 +214,8 @@ bool * env_struct_type_has_spec (s_env *env, const s_sym *module,
bool *dest);
bool env_tag_ident_is_bound (s_env *env,
const s_tag *tag);
+s_tag * env_while (s_env *env, const s_tag *cond,
+ const s_tag *body, s_tag *dest);
/* Modifiers. */
bool env_call_get (s_env *env, s_call *call);
diff --git a/libkc3/http b/libkc3/http
new file mode 120000
index 0000000..c7e370b
--- /dev/null
+++ b/libkc3/http
@@ -0,0 +1 @@
+../http
\ No newline at end of file
diff --git a/libkc3/kc3.c b/libkc3/kc3.c
index 9eabf09..92605c5 100644
--- a/libkc3/kc3.c
+++ b/libkc3/kc3.c
@@ -259,3 +259,8 @@ s_list ** kc3_search_modules (s_list **dest)
{
return env_search_modules(&g_kc3_env, dest);
}
+
+s_tag * kc3_while (const s_tag *cond, const s_tag *body, s_tag *dest)
+{
+ return env_while(&g_kc3_env, cond, body, dest);
+}
diff --git a/libkc3/kc3_main.h b/libkc3/kc3_main.h
index d770d2a..ccde0fb 100644
--- a/libkc3/kc3_main.h
+++ b/libkc3/kc3_main.h
@@ -58,6 +58,7 @@ bool kc3_require (const s_sym * const *module);
/* Special operators. */
s_tag * kc3_if_then_else (const s_tag *cond, const s_tag *then,
const s_tag *else_, s_tag *dest);
+s_tag * kc3_while (const s_tag *cond, const s_tag *body, s_tag *dest);
/* debug */
void kc3_break (void);