Added test-suite files in tests/
Moved two-mode-mode.el to contrib/
Changed behaviour of Apache dtcl 'script' commands.
PR:
diff --git a/Makefile b/Makefile
index 1f34f81..97aed4a 100644
--- a/Makefile
+++ b/Makefile
@@ -12,7 +12,6 @@
CFLAGS_SHLIB=-fpic -DSHARED_MODULE
LDFLAGS_SHLIB=-Bshareable
CFLAGS1= -Wall -DLINUX=2 -DSTATUS -DNO_DBM_REWRITEMAP -DUSE_HSREGEX -fpic -DSHARED_CORE
-MFLAGS_STATIC=--no-print-directory
CFLAGS=$(OPTIM) $(CFLAGS1) $(EXTRA_CFLAGS)
# You must change the following line unless you have the Debian apache-dev package
@@ -24,60 +23,21 @@
all: lib shlib
-other: all txt testdtcl
-
-extra: other code2html
-
lib: $(LIB)
shlib: $(SHLIBS)
-
-.SUFFIXES: .o .so
-
-.c.o:
- $(CC) -g -c $(INCLUDES) $(CFLAGS) $(SPACER) $<
+.SUFFIXES: .so
.c.so:
- $(CC) -g -c $(INCLUDES) $(CFLAGS) $(CFLAGS_SHLIB) $(SPACER) $< && mv $*.o $*-so.o
+ $(CC) -g -c $(INCLUDES) $(CFLAGS) $(CFLAGS_SHLIB) $(SPACER) -DDTCL_VERSION=\"`cat VERSION`\" $< && mv $*.o $*-so.o
$(LD) $(LDFLAGS_SHLIB) -o $@ $*-so.o -ltcl$(TCL_VERSION)
-clean: txtclean
+clean:
rm -f $(SHLIBS) $(SHLIBS_OBJ) $(LIB) $(SHLIB)
- -rm testdtcl
-testdtcl: testdtcl.c
- $(CC) -g -o testdtcl -O3 testdtcl.c -ltcl$(TCL_VERSION) -DDEBUG_SCRIPT_DIR=\"$(DEBUG_SCRIPT_DIR)\"
+version:
+ ./cvsversion.tcl
-txtclean:
- -rm readme.txt INSTALL.txt dtcl-tcl.txt use.txt
-
-txt: readme.txt INSTALL.txt dtcl-tcl.txt use.txt TODO.txt readme.hpux.txt
-
-readme.hpux.html: readme.hpux.txt
- lynx -dump readme.hpux.html > readme.hpux.txt
-
-readme.txt: readme.html
- lynx -dump readme.html > readme.txt
-
-INSTALL.txt: INSTALL.html
- lynx -dump INSTALL.html > INSTALL.txt
-
-dtcl-tcl.txt: dtcl-tcl.html
- lynx -dump dtcl-tcl.html > dtcl-tcl.txt
-
-use.txt: use.html
- lynx -dump use.html > use.txt
-
-TODO.txt: TODO.html
- lynx -dump TODO.html > TODO.txt
-
-readme.hpux.txt: readme.hpux.html
- lynx -dump readme.hpux.html > readme.hpux.txt
-
-# Need to be running under X for this to work!
-code2html: font-lock-stuff.el
- if [ -n "$$DISPLAY" ] ; then emacs -r -l font-lock-stuff.el -f flscreate --kill ; fi
-
-code2htmlclean:
- emacs -r -l font-lock-stuff.el -f flsclean -kill
\ No newline at end of file
+dist: clean version all
+ (cd .. ; tar -czvf mod_dtcl-`cat mod_dtcl/VERSION`.tar.gz mod_dtcl/ ; )
diff --git a/docs/two-mode-mode.el b/contrib/two-mode-mode.el
similarity index 92%
rename from docs/two-mode-mode.el
rename to contrib/two-mode-mode.el
index 4e09c6e..67c1972 100644
--- a/docs/two-mode-mode.el
+++ b/contrib/two-mode-mode.el
@@ -1,6 +1,8 @@
-;; two-mode-mode.el -- switches between tcl and sgml(html) modes $Id:
-;; two-mode-mode.el,v 1.2.2.1 2000/06/21 23:55:05 davidw Exp $
+;; two-mode-mode.el -- switches between tcl and sgml(html) modes
+;; $Id$
+
;; two-mode-mode.el is Copyright David Welton <davidw@efn.org> 1999, 2000
+
;; two-mode-mode.el may be distributed under the terms of the Apache
;; Software License, Version 1.1
@@ -19,8 +21,8 @@
(defvar two-mode-lmatch "<+")
(defvar two-mode-rmatch "+>")
-(defvar default-mode (list 'sgml-mode "SGML"))
-(defvar second-mode (list 'tcl-mode "TCL"))
+(defvar default-mode (list 'sgml-mode "SGML")) ;; outside the above tokens
+(defvar second-mode (list 'tcl-mode "TCL")) ;; inside
;; ----------------
(defun two-mode-mode-setup ()
diff --git a/cvsversion.tcl b/cvsversion.tcl
new file mode 100755
index 0000000..acfc2e5
--- /dev/null
+++ b/cvsversion.tcl
@@ -0,0 +1,108 @@
+#!/usr/bin/tclsh
+# By David N. Welton <davidw@linuxcare.com>
+# $Id$
+
+# This is a script to aid in keeping a coherent version number
+# attached to the program.
+
+set newversionvar 0
+
+proc newversion { } {
+ global newversionvar
+ puts stderr "New version"
+ set newversionvar 1
+}
+
+proc diffentries { {dir .} } {
+ global newversionvar
+
+ puts stderr "Diffentries for $dir"
+ set currentdir [ pwd ]
+ cd $dir
+ if { ! [ file exists ./CVS/Entries ] } {
+ puts stderr "You must be in a directory with a path to ./CVS/Entries."
+ }
+
+ if { ! [ file exists ./.OLDEntries ] } {
+ puts stderr "No OLDEntries file. It will be created."
+ set fl [ open ./.OLDEntries w ]
+ close $fl
+ }
+
+ set entries [ open ./CVS/Entries ]
+ set blob ""
+ while { [ gets $entries ln ] != -1 } {
+ lappend blob $ln
+ }
+ close $entries
+
+ set oldentries [ open ./.OLDEntries ]
+ set blob2 ""
+ while { [ gets $oldentries ln ] != -1 } {
+ lappend blob2 $ln
+ }
+ close $oldentries
+
+ if { $blob != $blob2 } {
+ newversion
+ }
+ foreach ln $blob {
+ # the regexp below scans for directories in CVS Entries files
+ if { [ regexp {^D/(.*)////$} "$ln" match dir ] } {
+ diffentries $dir
+ }
+ }
+
+ file copy -force ./CVS/Entries ./.OLDEntries
+ cd $currentdir
+}
+
+diffentries
+
+if { $newversionvar == 0 } {
+ puts stderr "No changes, exiting."
+} else {
+ if { [ file exists ./VERSION ] } {
+ set versionfile [ open ./VERSION "r" ]
+ gets $versionfile versionstring
+ close $versionfile
+ } else {
+ set versionstring "0.0.0"
+ }
+
+ if { ! [ regexp {([0-9]+)\.([0-9]+)\.([0-9]+)} $versionstring match major minor point ] } {
+ puts stderr "Problem with versionstring '$versionstring', exiting"
+ exit 1
+ }
+
+ set versionfile [ open ./VERSION "w" ]
+ while { 1 } {
+ puts -nonewline stderr "Current version: $major.$minor.$point. "
+ puts -nonewline stderr {Increment [M]ajor, m[I]nor, [P]oint release, or [A]bort? >>> }
+ gets stdin answer
+ switch [ string tolower $answer ] {
+ m {
+ incr major
+ set minor 0
+ set point 0
+ break
+ }
+ i {
+ incr minor
+ set point 0
+ break
+ }
+ p {
+ incr point
+ break
+ }
+ a {
+ puts stderr "Aborted"
+ break
+ }
+ }
+ }
+ puts $versionfile "$major.$minor.$point"
+ close $versionfile
+ puts stderr "Done, version is $major.$minor.$point"
+}
\ No newline at end of file
diff --git a/debian/rules b/debian/rules
index 6c2d1a1..0e5f09e 100755
--- a/debian/rules
+++ b/debian/rules
@@ -36,7 +36,7 @@
cp testdtcl debian/tmp/usr/bin/
# Must have debmake installed for this to work. Otherwise please copy
# /usr/bin/debstd into the debian directory and change debstd to debian/debstd
- dh_installdocs *.html *.ttml INSTALL.txt use.txt readme.txt dtcl-tcl.txt dtcl.tcl two-mode-mode.el dtcl.gif
+ dh_installdocs docs/ contrib/
dh_installchangelogs
dh_installmanpages
dh_movefiles
diff --git a/mod_dtcl.c b/mod_dtcl.c
index 196b7c5..fc8c77b 100644
--- a/mod_dtcl.c
+++ b/mod_dtcl.c
@@ -128,7 +128,7 @@
#define DEFAULT_ERROR_MSG "[an error occurred while processing this directive]"
#define DEFAULT_TIME_FORMAT "%A, %d-%b-%Y %H:%M:%S %Z"
#define DEFAULT_HEADER_TYPE "text/html"
-#define DTCL_VERSION "0.8.5"
+/* #define DTCL_VERSION "0.8.5" */
/* *** Global variables *** */
static Tcl_Interp *interp; /* Tcl interpreter */
@@ -1315,9 +1315,11 @@
}
typedef struct {
- char *dtcl_global_script;
- char *dtcl_init_script;
- char *dtcl_exit_script;
+ Tcl_Obj *dtcl_global_init_script;
+ Tcl_Obj *dtcl_child_init_script;
+ Tcl_Obj *dtcl_child_exit_script;
+ Tcl_Obj *dtcl_before_script;
+ Tcl_Obj *dtcl_after_script;
int dtcl_cache_size;
} dtcl_server_conf;
@@ -1375,13 +1377,13 @@
Tcl_IncrRefCount(namespacePrologue);
#if DBG
- ap_log_error(APLOG_MARK, APLOG_ERR, s, "Config string = \"%s\"", dsc->dtcl_global_script); /* XXX */
+ ap_log_error(APLOG_MARK, APLOG_ERR, s, "Config string = \"%s\"", Tcl_GetStringFromObj(dsc->dtcl_global_init_script, NULL)); /* XXX */
ap_log_error(APLOG_MARK, APLOG_ERR, s, "Cache size = \"%d\"", dsc->dtcl_cache_size); /* XXX */
#endif
- if (dsc->dtcl_global_script != NULL)
+ if (dsc->dtcl_global_init_script != NULL)
{
- rslt = Tcl_EvalFile(interp, dsc->dtcl_global_script);
+ rslt = Tcl_EvalObjEx(interp, dsc->dtcl_global_init_script, 0);
if (rslt != TCL_OK)
{
ap_log_error(APLOG_MARK, APLOG_ERR, s, "%s",
@@ -1396,7 +1398,7 @@
if (ap_max_requests_per_child != 0)
cacheSize = ap_max_requests_per_child / 2;
else
- cacheSize = 50; /* Arbitrary number */
+ cacheSize = 10; /* Arbitrary number FIXME */
cacheFreeSize = cacheSize;
}
/* Initializing cache structures */
@@ -1412,27 +1414,32 @@
ap_add_version_component("Mod_dtcl " DTCL_VERSION);
}
-static const char *set_globalscript(cmd_parms *cmd, void *dummy, char *arg)
+static const char *set_script(cmd_parms *cmd, void *dummy, char *arg, char *arg2)
{
+ Tcl_Obj *objarg;
server_rec *s = cmd->server;
dtcl_server_conf *conf = (dtcl_server_conf *)ap_get_module_config(s->module_config, &dtcl_module);
- conf->dtcl_global_script = arg;
- return NULL;
-}
-static const char *set_initscript(cmd_parms *cmd, void *dummy, char *arg)
-{
- server_rec *s = cmd->server;
- dtcl_server_conf *conf = (dtcl_server_conf *)ap_get_module_config(s->module_config, &dtcl_module);
- conf->dtcl_init_script = arg;
- return NULL;
-}
-
-static const char *set_exitscript(cmd_parms *cmd, void *dummy, char *arg)
-{
- server_rec *s = cmd->server;
- dtcl_server_conf *conf = (dtcl_server_conf *)ap_get_module_config(s->module_config, &dtcl_module);
- conf->dtcl_exit_script = arg;
+ if (arg == NULL || arg2 == NULL)
+ {
+ ap_log_error(APLOG_MARK, APLOG_ERR, global_rr->server, "Mod_Dtcl Error: Dtcl_Script requires two arguments");
+ return NULL;
+ }
+
+ objarg = Tcl_NewStringObj(arg2, -1);
+ if (strcmp(arg, "GlobalInitScript") == 0) {
+ conf->dtcl_global_init_script = objarg;
+ } else if (strcmp(arg, "ChildInitScript") == 0) {
+ conf->dtcl_child_init_script = objarg;
+ } else if (strcmp(arg, "ChildExitScript") == 0) {
+ conf->dtcl_child_exit_script = objarg;
+ } else if (strcmp(arg, "BeforeScript") == 0) {
+ conf->dtcl_before_script = objarg;
+ } else if (strcmp(arg, "AfterScript") == 0) {
+ conf->dtcl_after_script = objarg;
+ } else {
+ ap_log_error(APLOG_MARK, APLOG_ERR, global_rr->server, "Mod_Dtcl Error: Dtcl_Script must have a second argument, which is one of: GlobalInitScript, ChildInitScript, ChildExitScript, BeforeScript, AfterScript");
+ }
return NULL;
}
@@ -1447,19 +1454,20 @@
static void *create_dtcl_config(pool *p, server_rec *s)
{
dtcl_server_conf *dts = (dtcl_server_conf *) ap_pcalloc(p, sizeof(dtcl_server_conf));
- dts->dtcl_global_script = NULL;
- dts->dtcl_init_script = NULL;
- dts->dtcl_exit_script = NULL;
+ dts->dtcl_global_init_script = NULL;
+ dts->dtcl_child_init_script = NULL;
+ dts->dtcl_child_exit_script = NULL;
+ dts->dtcl_before_script = NULL;
+ dts->dtcl_after_script = NULL;
return dts;
}
static void *merge_dtcl_config(pool *p, void *basev, void *overridesv)
{
dtcl_server_conf *base = (dtcl_server_conf *) basev, *overrides = (dtcl_server_conf *) overridesv;
- return overrides->dtcl_global_script ? overrides : base;
+ return overrides->dtcl_global_init_script ? overrides : base;
}
-
static void dtcl_child_init(server_rec *s, pool *p)
{
dtcl_server_conf *dsc = (dtcl_server_conf *) ap_get_module_config(s->module_config, &dtcl_module);
@@ -1468,20 +1476,20 @@
tcl_init_stuff(s, p);
#endif
- if (dsc->dtcl_init_script != NULL)
- if (Tcl_EvalFile(interp, dsc->dtcl_init_script) != TCL_OK)
+ if (dsc->dtcl_child_init_script != NULL)
+ if (Tcl_EvalObjEx(interp, dsc->dtcl_child_init_script, 0) != TCL_OK)
ap_log_error(APLOG_MARK, APLOG_ERR, s,
- "Problem running child init script: %s", dsc->dtcl_init_script);
+ "Problem running child init script: %s", Tcl_GetStringFromObj(dsc->dtcl_child_init_script, NULL));
}
static void dtcl_child_exit(server_rec *s, pool *p)
{
dtcl_server_conf *dsc = (dtcl_server_conf *) ap_get_module_config(s->module_config, &dtcl_module);
- if (dsc->dtcl_exit_script != NULL)
- if (Tcl_EvalFile(interp, dsc->dtcl_exit_script) != TCL_OK)
+ if (dsc->dtcl_child_exit_script != NULL)
+ if (Tcl_EvalObjEx(interp, dsc->dtcl_child_exit_script, 0) != TCL_OK)
ap_log_error(APLOG_MARK, APLOG_ERR, s,
- "Problem running child exit script: %s", dsc->dtcl_exit_script);
+ "Problem running child exit script: %s", Tcl_GetStringFromObj(dsc->dtcl_child_exit_script, NULL));
}
static const handler_rec dtcl_handlers[] =
@@ -1493,9 +1501,7 @@
static const command_rec dtcl_cmds[] =
{
- {"Dtcl_GlobalScript", set_globalscript, NULL, RSRC_CONF, TAKE1, "the name of the global configuration script"},
- {"Dtcl_ChildInitScript", set_initscript, NULL, RSRC_CONF, TAKE1, "the name of the per child init configuration script"},
- {"Dtcl_ChildExitScript", set_exitscript, NULL, RSRC_CONF, TAKE1, "the name of the per child exit configuration script"},
+ {"Dtcl_Script", set_script, NULL, RSRC_CONF, TAKE2, "general script command"},
{"Dtcl_CacheSize", set_cachesize, NULL, RSRC_CONF, TAKE1, "number of ttml scripts cached"},
{NULL}
};
diff --git a/tests/dtcl-test.ttml b/tests/dtcl-test.ttml
new file mode 100644
index 0000000..b458e93
--- /dev/null
+++ b/tests/dtcl-test.ttml
@@ -0,0 +1,32 @@
+<+
+
+hgetvars
+
+# hello-1.1
+hputs "Hello, World\n"
+
+# i18n-1.1
+hputs "¡ À È Ì Ò Ù - El Burro Sabe Más Que Tú!\n"
+
+if { [ array exists VARS ] } {
+ # get/post variables 1.1
+ if { [ info exists VARS(foobar) ] } {
+ hputs "VARS(foobar) = $VARS(foobar)\n"
+ }
+ # get/post variables 1.{2,3}
+ if { [ info exists VARS(Más) ] } {
+ hputs "VARS(Más) = $VARS(Más)\n"
+ }
+}
+
+# env
+hputs "ENVS(DOCUMENT_NAME) = $ENVS(DOCUMENT_NAME)\n"
+
+# cookies
+if { [ array exists COOKIES ] } {
+ foreach { ck } [ array names COOKIES ] {
+ hputs "COOKIES($ck) = $COOKIES($ck)\n"
+ }
+}
+
++>
\ No newline at end of file
diff --git a/tests/dtcl.test b/tests/dtcl.test
new file mode 100755
index 0000000..9f5840d
--- /dev/null
+++ b/tests/dtcl.test
@@ -0,0 +1,73 @@
+#!/usr/bin/tclsh
+
+# mod_dtcl test suite, by David N. Welton <davidw@linuxcare.com>
+
+# $Id$
+
+package require tcltest
+package require http 2.1
+
+set urlbase "http://eugene.i.prosa.it/~davidw/tests/"
+set testfilename "dtcl-test.ttml"
+
+::tcltest::test hello-1.1 {hello world test} {
+ set page [ ::http::geturl "${urlbase}$testfilename" ]
+ regexp -line {^Hello, World$} [ ::http::data $page ]
+} 1
+
+::tcltest::test i18n-1.1 {I18N test} {
+ set page [ ::http::geturl "${urlbase}$testfilename" ]
+ regexp -line {^¡ À È Ì Ò Ù - El Burro Sabe Más Que Tú!$} [ ::http::data $page ]
+} 1
+
+::tcltest::test getvariables-1.1 {GET variables} {
+ set page [ ::http::geturl "${urlbase}$testfilename?foobar=goober" ]
+ regexp -line {^VARS\(foobar\) = goober$} [ ::http::data $page ]
+} 1
+
+::tcltest::test getvariables-1.2 {GET variables + I18N} {
+ set page [ ::http::geturl "${urlbase}$testfilename?Más=Tú" ]
+ regexp -line {^VARS\(Más\) = Tú$} [ ::http::data $page ]
+} 1
+
+::tcltest::test getvariables-1.3 {GET variables + I18N + encoding} {
+ set page [ ::http::geturl [ format "${urlbase}$testfilename?%s" [ ::http::formatQuery Más Tú ] ] ]
+ regexp -line {^VARS\(Más\) = Tú$} [ ::http::data $page ]
+} 1
+
+::tcltest::test postvariables-1.1 {POST variables} {
+ set page [ ::http::geturl "${urlbase}$testfilename" -query foobar=goober ]
+ regexp -line {^VARS\(foobar\) = goober$} [ ::http::data $page ]
+} 1
+
+::tcltest::test postvariables-1.2 {POST variables + I18N} {
+ set page [ ::http::geturl "${urlbase}$testfilename" -query Más=Tú ]
+ regexp -line {^VARS\(Más\) = Tú$} [ ::http::data $page ]
+} 1
+
+::tcltest::test postvariables-1.3 {POST variables + I18N + encoding} {
+ set page [ ::http::geturl "${urlbase}$testfilename" -query [ ::http::formatQuery Más Tú ] ]
+ regexp -line {^VARS\(Más\) = Tú$} [ ::http::data $page ]
+} 1
+
+::tcltest::test env-1.1 {Environment variable} {
+ set page [ ::http::geturl "${urlbase}$testfilename" ]
+ regexp -line "^ENVS\\(DOCUMENT_NAME\\) = $testfilename\$" [ ::http::data $page ]
+} 1
+
+::tcltest::test cookies-1.1 {Cookies} {
+ set page [ ::http::geturl "${urlbase}$testfilename" -headers {Cookie "foo=bar"} ]
+ regexp -line {^COOKIES\(foo\) = bar$} [ ::http::data $page ]
+} 1
+
+::tcltest::test cookies-1.2 {Cookies + I18N} {
+ set page [ ::http::geturl "${urlbase}$testfilename" -headers {Cookie "Más=Tú"} ]
+ regexp -line {^COOKIES\(Más\) = Tú$} [ ::http::data $page ]
+} 1
+
+::tcltest::test cookies-1.3 {Cookies + I18N + encoding} {
+ set page [ ::http::geturl "${urlbase}$testfilename" -headers [ list Cookie [ ::http::formatQuery Más Tú ] ] ]
+ regexp -line {^COOKIES\(Más\) = Tú$} [ ::http::data $page ]
+} 1
+
+puts "Done"
\ No newline at end of file