changeset 1739:c414850f206f

Add support for -boot flag, which allows in-tree execution of Ur/Web The boot flag rewrites most hardcoded paths to point to the build directory, and also forces static compilation. This is convenient for developing Ur/Web, or if you cannot 'sudo make install' Ur/Web. The following changes were made: * Header files were moved to include/urweb instead of include; this lets FFI users point their C_INCLUDE_PATH at this directory at write <urweb/urweb.h>. For internal Ur/Web executables, we simply pass -I$PATH/include/urweb as normal. * Differentiate between LIB and SRCLIB; SRCLIB is Ur and JavaScript source files, while LIB is compiled products from libtool. For in-tree compilation these live in different places. * No longer reference Config for paths; instead use Settings; these settings can be changed dynamically by Compiler.enableBoot () (TODO: add a disableBoot function.) * config.h is now generated directly in include/urweb/config.h, for consistency's sake (especially since it gets installed along with the rest of the headers!) * All of the autotools build products got updated. * The linkStatic field in protocols now only contains the name of the build product, and not the absolute path. Future users have to be careful not to reference the Settings files to early, lest they get an old version (this was the source of two bugs during development of this patch.)
author Edward Z. Yang <ezyang@mit.edu>
date Wed, 02 May 2012 17:17:57 -0400
parents 1a35e75b6967
children d2ec62c5ad81
files Makefile.am Makefile.in config.h.in configure.ac doc/manual.tex include/queue.h include/request.h include/types.h include/urweb.h include/urweb/config.h.in include/urweb/queue.h include/urweb/request.h include/urweb/types.h include/urweb/urweb.h src/c/Makefile.am src/c/Makefile.in src/cgi.sml src/cjr_print.sml src/compiler.sig src/compiler.sml src/config.sig src/config.sml.in src/demo.sml src/fastcgi.sml src/http.sml src/jscomp.sml src/main.mlton.sml src/settings.sig src/settings.sml src/static.sml src/tutorial.sml
diffstat 31 files changed, 759 insertions(+), 746 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile.am	Thu May 03 09:56:41 2012 -0400
+++ b/Makefile.am	Wed May 02 17:17:57 2012 -0400
@@ -82,8 +82,7 @@
 	mkdir -p $(DESTDIR)$(LIB_JS)
 	cp lib/js/*.js $(DESTDIR)$(LIB_JS)/
 	mkdir -p $(DESTDIR)$(INCLUDE)
-	cp config.h $(DESTDIR)$(INCLUDE)/
-	cp include/*.h $(DESTDIR)$(INCLUDE)/
+	cp include/urweb/*.h $(DESTDIR)$(INCLUDE)/
 
 install-exec-local: install-exec-local-main install-exec-emacs
 	-ldconfig
--- a/Makefile.in	Thu May 03 09:56:41 2012 -0400
+++ b/Makefile.in	Wed May 02 17:17:57 2012 -0400
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
-# Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  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.
@@ -35,9 +35,10 @@
 host_triplet = @host@
 subdir = .
 DIST_COMMON = $(am__configure_deps) $(srcdir)/Makefile.am \
-	$(srcdir)/Makefile.in $(srcdir)/config.h.in \
-	$(top_srcdir)/configure $(top_srcdir)/src/config.sml.in \
-	config.guess config.sub depcomp install-sh ltmain.sh missing
+	$(srcdir)/Makefile.in $(top_srcdir)/configure \
+	$(top_srcdir)/include/urweb/config.h.in \
+	$(top_srcdir)/src/config.sml.in config.guess config.sub \
+	depcomp install-sh ltmain.sh missing
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_openssl.m4 \
 	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
@@ -49,7 +50,7 @@
 am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
  configure.lineno config.status.lineno
 mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = config.h
+CONFIG_HEADER = $(top_builddir)/include/urweb/config.h
 CONFIG_CLEAN_FILES = src/config.sml
 CONFIG_CLEAN_VPATH_FILES =
 SOURCES =
@@ -73,11 +74,9 @@
 distdir = $(PACKAGE)-$(VERSION)
 top_distdir = $(distdir)
 am__remove_distdir = \
-  if test -d "$(distdir)"; then \
-    find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
-      && rm -rf "$(distdir)" \
-      || { sleep 5 && rm -rf "$(distdir)"; }; \
-  else :; fi
+  { test ! -d "$(distdir)" \
+    || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+         && rm -fr "$(distdir)"; }; }
 am__relativize = \
   dir0=`pwd`; \
   sed_first='s,^\([^/]*\)/.*$$,\1,'; \
@@ -106,8 +105,6 @@
 DIST_ARCHIVES = $(distdir).tar.gz
 GZIP_ENV = --best
 distuninstallcheck_listfiles = find . -type f -print
-am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
-  | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
 distcleancheck_listfiles = find . -type f -print
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -186,6 +183,7 @@
 SHELL = @SHELL@
 SITELISP := @SITELISP@
 SQHEADER = @SQHEADER@
+SRCLIB = @SRCLIB@
 STRIP = @STRIP@
 VERSION := @VERSION@
 abs_builddir = @abs_builddir@
@@ -246,11 +244,10 @@
 LIB_C := $(LIB)/c
 LIB_JS := $(LIB)/js
 SUBDIRS = src/c
-all: config.h
-	$(MAKE) $(AM_MAKEFLAGS) all-recursive
+all: all-recursive
 
 .SUFFIXES:
-am--refresh: Makefile
+am--refresh:
 	@:
 $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	@for dep in $?; do \
@@ -285,20 +282,22 @@
 	$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
 $(am__aclocal_m4_deps):
 
-config.h: stamp-h1
-	@if test ! -f $@; then rm -f stamp-h1; else :; fi
-	@if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi
+include/urweb/config.h: include/urweb/stamp-h1
+	@if test ! -f $@; then \
+	  rm -f include/urweb/stamp-h1; \
+	  $(MAKE) $(AM_MAKEFLAGS) include/urweb/stamp-h1; \
+	else :; fi
 
-stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
-	@rm -f stamp-h1
-	cd $(top_builddir) && $(SHELL) ./config.status config.h
-$(srcdir)/config.h.in:  $(am__configure_deps) 
+include/urweb/stamp-h1: $(top_srcdir)/include/urweb/config.h.in $(top_builddir)/config.status
+	@rm -f include/urweb/stamp-h1
+	cd $(top_builddir) && $(SHELL) ./config.status include/urweb/config.h
+$(top_srcdir)/include/urweb/config.h.in:  $(am__configure_deps) 
 	($(am__cd) $(top_srcdir) && $(AUTOHEADER))
-	rm -f stamp-h1
+	rm -f include/urweb/stamp-h1
 	touch $@
 
 distclean-hdr:
-	-rm -f config.h stamp-h1
+	-rm -f include/urweb/config.h include/urweb/stamp-h1
 src/config.sml: $(top_builddir)/config.status $(top_srcdir)/src/config.sml.in
 	cd $(top_builddir) && $(SHELL) ./config.status $@
 
@@ -391,7 +390,7 @@
 	mkid -fID $$unique
 tags: TAGS
 
-TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
 		$(TAGS_FILES) $(LISP)
 	set x; \
 	here=`pwd`; \
@@ -408,7 +407,7 @@
 	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
 	  fi; \
 	done; \
-	list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
@@ -426,9 +425,9 @@
 	  fi; \
 	fi
 ctags: CTAGS
-CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
 		$(TAGS_FILES) $(LISP)
-	list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
@@ -518,11 +517,7 @@
 	$(am__remove_distdir)
 
 dist-bzip2: distdir
-	tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
-	$(am__remove_distdir)
-
-dist-lzip: distdir
-	tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
+	tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
 	$(am__remove_distdir)
 
 dist-lzma: distdir
@@ -530,7 +525,7 @@
 	$(am__remove_distdir)
 
 dist-xz: distdir
-	tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+	tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
 	$(am__remove_distdir)
 
 dist-tarZ: distdir
@@ -561,8 +556,6 @@
 	  bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
 	*.tar.lzma*) \
 	  lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
-	*.tar.lz*) \
-	  lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
 	*.tar.xz*) \
 	  xz -dc $(distdir).tar.xz | $(am__untar) ;;\
 	*.tar.Z*) \
@@ -582,7 +575,6 @@
 	  && am__cwd=`pwd` \
 	  && $(am__cd) $(distdir)/_build \
 	  && ../configure --srcdir=.. --prefix="$$dc_install_base" \
-	    $(AM_DISTCHECK_CONFIGURE_FLAGS) \
 	    $(DISTCHECK_CONFIGURE_FLAGS) \
 	  && $(MAKE) $(AM_MAKEFLAGS) \
 	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
@@ -611,16 +603,8 @@
 	  list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
 	  sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
 distuninstallcheck:
-	@test -n '$(distuninstallcheck_dir)' || { \
-	  echo 'ERROR: trying to run $@ with an empty' \
-	       '$$(distuninstallcheck_dir)' >&2; \
-	  exit 1; \
-	}; \
-	$(am__cd) '$(distuninstallcheck_dir)' || { \
-	  echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
-	  exit 1; \
-	}; \
-	test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
+	@$(am__cd) '$(distuninstallcheck_dir)' \
+	&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
 	   || { echo "ERROR: files left after uninstall:" ; \
 	        if test -n "$(DESTDIR)"; then \
 	          echo "  (check DESTDIR support)"; \
@@ -638,7 +622,7 @@
 	       exit 1; } >&2
 check-am: all-am
 check: check-recursive
-all-am: Makefile config.h all-local
+all-am: Makefile all-local
 installdirs: installdirs-recursive
 installdirs-am:
 install: install-recursive
@@ -651,15 +635,10 @@
 
 installcheck: installcheck-recursive
 install-strip:
-	if test -z '$(STRIP)'; then \
-	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	      install; \
-	else \
-	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
-	fi
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
 mostlyclean-generic:
 
 clean-generic:
@@ -741,14 +720,14 @@
 
 uninstall-am: uninstall-local
 
-.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \
-	ctags-recursive install-am install-strip tags-recursive
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
+	install-am install-strip tags-recursive
 
 .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
 	all all-am all-local am--refresh check check-am clean \
 	clean-generic clean-libtool clean-local ctags ctags-recursive \
-	dist dist-all dist-bzip2 dist-gzip dist-lzip dist-lzma \
-	dist-shar dist-tarZ dist-xz dist-zip distcheck distclean \
+	dist dist-all dist-bzip2 dist-gzip dist-lzma dist-shar \
+	dist-tarZ dist-xz dist-zip distcheck distclean \
 	distclean-generic distclean-hdr distclean-libtool \
 	distclean-tags distcleancheck distdir distuninstallcheck dvi \
 	dvi-am html html-am info info-am install install-am \
@@ -829,8 +808,7 @@
 	mkdir -p $(DESTDIR)$(LIB_JS)
 	cp lib/js/*.js $(DESTDIR)$(LIB_JS)/
 	mkdir -p $(DESTDIR)$(INCLUDE)
-	cp config.h $(DESTDIR)$(INCLUDE)/
-	cp include/*.h $(DESTDIR)$(INCLUDE)/
+	cp include/urweb/*.h $(DESTDIR)$(INCLUDE)/
 
 install-exec-local: install-exec-local-main install-exec-emacs
 	-ldconfig
--- a/config.h.in	Thu May 03 09:56:41 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-/* config.h.in.  Generated from configure.ac by autoheader.  */
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#undef HAVE_DLFCN_H
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
-
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
-
-/* Define to 1 if you have the <mysql/mysql.h> header file. */
-#undef HAVE_MYSQL_MYSQL_H
-
-/* Define to 1 if you have the <postgresql/libpq-fe.h> header file. */
-#undef HAVE_POSTGRESQL_LIBPQ_FE_H
-
-/* Define if you have POSIX threads libraries and header files. */
-#undef HAVE_PTHREAD
-
-/* Have PTHREAD_PRIO_INHERIT. */
-#undef HAVE_PTHREAD_PRIO_INHERIT
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#undef HAVE_STDLIB_H
-
-/* Define to 1 if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
-
-/* Define to 1 if you have the <string.h> header file. */
-#undef HAVE_STRING_H
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#undef HAVE_SYS_STAT_H
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#undef HAVE_SYS_TYPES_H
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#undef HAVE_UNISTD_H
-
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
-   */
-#undef LT_OBJDIR
-
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the home page for this package. */
-#undef PACKAGE_URL
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
-
-/* Define to necessary symbol if this constant uses a non-standard name on
-   your system. */
-#undef PTHREAD_CREATE_JOINABLE
-
-/* Define to 1 if you have the ANSI C header files. */
-#undef STDC_HEADERS
-
-/* Enable extensions on AIX 3, Interix.  */
-#ifndef _ALL_SOURCE
-# undef _ALL_SOURCE
-#endif
-/* Enable GNU extensions on systems that have them.  */
-#ifndef _GNU_SOURCE
-# undef _GNU_SOURCE
-#endif
-/* Enable threading extensions on Solaris.  */
-#ifndef _POSIX_PTHREAD_SEMANTICS
-# undef _POSIX_PTHREAD_SEMANTICS
-#endif
-/* Enable extensions on HP NonStop.  */
-#ifndef _TANDEM_SOURCE
-# undef _TANDEM_SOURCE
-#endif
-/* Enable general extensions on Solaris.  */
-#ifndef __EXTENSIONS__
-# undef __EXTENSIONS__
-#endif
-
-
-/* Define to 1 if on MINIX. */
-#undef _MINIX
-
-/* Define to 2 if the system does not provide POSIX.1 features except with
-   this defined. */
-#undef _POSIX_1_SOURCE
-
-/* Define to 1 if you need to in order for `stat' and other things to work. */
-#undef _POSIX_SOURCE
--- a/configure.ac	Thu May 03 09:56:41 2012 -0400
+++ b/configure.ac	Wed May 02 17:17:57 2012 -0400
@@ -5,7 +5,7 @@
 AC_PROG_CC()
 AC_PROG_LIBTOOL()
 AC_CONFIG_MACRO_DIR([m4])
-AC_CONFIG_HEADERS([config.h])
+AC_CONFIG_HEADERS([include/urweb/config.h])
 
 AX_PTHREAD([echo >/dev/null], [echo "Your C compiler does not support POSIX threads."; exit 1])
 
@@ -41,7 +41,11 @@
 fi
 
 if test [-z $LIB]; then
-    LIB=$prefix/lib/urweb
+    LIB=$prefix/lib
+fi
+
+if test [-z $SRCLIB]; then
+    SRCLIB=$prefix/lib/urweb
 fi
 
 if test [-z $INCLUDE]; then
@@ -89,6 +93,7 @@
 AC_SUBST(CC)
 AC_SUBST(BIN)
 AC_SUBST(LIB)
+AC_SUBST(SRCLIB)
 AC_SUBST(INCLUDE)
 AC_SUBST(SITELISP)
 AC_SUBST(CCARGS)
@@ -112,6 +117,7 @@
 Ur/Web configuration:
   bin directory:       BIN            $BIN
   lib directory:       LIB            $LIB
+  src lib directory:   SRCLIB         $SRCLIB
   include directory:   INCLUDE        $INCLUDE
   site-lisp directory: SITELISP       $SITELISP
   C compiler:          CC             $CC
--- a/doc/manual.tex	Thu May 03 09:56:41 2012 -0400
+++ b/doc/manual.tex	Wed May 02 17:17:57 2012 -0400
@@ -225,6 +225,8 @@
 
 Some other command-line parameters are accepted:
 \begin{itemize}
+\item \texttt{-boot}: Run Ur/Web from a build tree (and not from a system install).  This is useful if you're testing the compiler and don't want to install it.  It forces generation of statically linked executables.
+
 \item \texttt{-db <DBSTRING>}: Set database connection information, using the format expected by Postgres's \texttt{PQconnectdb()}, which is \texttt{name1=value1 ... nameN=valueN}.  The same format is also parsed and used to discover connection parameters for MySQL and SQLite.  The only significant settings for MySQL are \texttt{host}, \texttt{hostaddr}, \texttt{port}, \texttt{dbname}, \texttt{user}, and \texttt{password}.  The only significant setting for SQLite is \texttt{dbname}, which is interpreted as the filesystem path to the database.  Additionally, when using SQLite, a database string may be just a file path.
 
 \item \texttt{-dbms [postgres|mysql|sqlite]}: Sets the database backend to use.
--- a/include/queue.h	Thu May 03 09:56:41 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-#ifndef QUEUE_H
-#define QUEUE_H
-
-int uw_dequeue();
-void uw_enqueue(int);
-
-#endif
--- a/include/request.h	Thu May 03 09:56:41 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-#ifndef REQUEST_H
-#define REQUEST_H
-
-#include <sys/types.h>
-
-#include "types.h"
-
-typedef struct uw_rc *uw_request_context;
-
-void uw_request_init(uw_app *app, void *logger_data, uw_logger log_error, uw_logger log_debug);
-void uw_sign(const char *in, char *out);
-
-uw_request_context uw_new_request_context(void);
-void uw_free_request_context(uw_request_context);
-
-request_result uw_request(uw_request_context, uw_context,
-                          char *method, char *path, char *query_string,
-                          char *body, size_t body_len,
-                          void (*on_success)(uw_context), void (*on_failure)(uw_context),
-                          void *logger_data, uw_logger log_error, uw_logger log_debug,
-                          int sock,
-                          int (*send)(int sockfd, const void *buf, ssize_t len),
-                          int (*close)(int fd));
-
-uw_context uw_request_new_context(int id, uw_app*, void *logger_data, uw_logger log_error, uw_logger log_debug);
-
-typedef struct {
-  uw_app *app;
-  void *logger_data;
-  uw_logger log_error, log_debug;
-} loggers;
-
-void *client_pruner(void *data);
-
-int pthread_create_big(pthread_t *outThread, void *foo, void *threadFunc, void *arg);
-
-#endif
--- a/include/types.h	Thu May 03 09:56:41 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-#ifndef URWEB_TYPES_H
-#define URWEB_TYPES_H
-
-#include <time.h>
-#include <unistd.h>
-#include <stdint.h>
-
-typedef long long uw_Basis_int;
-typedef double uw_Basis_float;
-typedef char* uw_Basis_string;
-typedef char uw_Basis_char;
-typedef struct {
-  time_t seconds;
-  unsigned microseconds;
-} uw_Basis_time;
-typedef struct {
-  size_t size;
-  char *data;
-} uw_Basis_blob;
-
-typedef int uw_unit;
-typedef uw_unit uw_Basis_unit;
-
-typedef enum uw_Basis_bool { uw_Basis_False, uw_Basis_True } uw_Basis_bool;
-
-typedef struct uw_context *uw_context;
-
-typedef uw_Basis_string uw_Basis_xhtml;
-typedef uw_Basis_string uw_Basis_page;
-typedef uw_Basis_string uw_Basis_xbody;
-typedef uw_Basis_string uw_Basis_css_class;
-
-typedef unsigned uw_Basis_client;
-typedef struct {
-  unsigned cli, chn;
-} uw_Basis_channel;
-
-typedef struct {
-  int context;
-  unsigned long long source;
-} uw_Basis_source;
-
-typedef struct uw_Basis_file {
-  uw_Basis_string name, type;
-  uw_Basis_blob data;
-} uw_Basis_file;
-
-typedef struct uw_Basis_postBody {
-  uw_Basis_string type, data;
-} uw_Basis_postBody;
-
-typedef uw_Basis_string uw_Basis_queryString;
-
-typedef enum { SUCCESS, FATAL, BOUNDED_RETRY, UNLIMITED_RETRY, RETURN_INDIRECTLY } failure_kind;
-
-typedef enum { SERVED, KEEP_OPEN, FAILED } request_result;
-
-typedef struct input *uw_input;
-
-#define INTS_MAX 50
-#define FLOATS_MAX 100
-#define TIMES_MAX 100
-
-typedef void (*uw_callback)(void *);
-typedef void (*uw_callback_with_retry)(void *, int will_retry);
-typedef void (*uw_logger)(void*, const char *fmt, ...);
-
-typedef struct {
-  void (*callback)(uw_context);
-  unsigned int period;
-} uw_periodic;
-
-typedef struct {
-  int inputs_len, timeout;
-  char *url_prefix;
-
-  void (*client_init)();
-  void (*initializer)(uw_context);
-  void (*expunger)(uw_context, uw_Basis_client);
-
-  void (*db_init)(uw_context);
-  int (*db_begin)(uw_context);
-  int (*db_commit)(uw_context);
-  int (*db_rollback)(uw_context);
-  void (*db_close)(uw_context);
-
-  void (*handle)(uw_context, char *);
-
-  int (*input_num)(const char*);
-  uw_Basis_string (*cookie_sig)(uw_context);
-  int (*check_url)(const char *);
-  int (*check_mime)(const char *);
-  int (*check_requestHeader)(const char *);
-  int (*check_responseHeader)(const char *);
-
-  void (*on_error)(uw_context, char *);
-
-  uw_periodic *periodics; // 0-terminated array
-
-  uw_Basis_string time_format;
-} uw_app;
-
-#define ERROR_BUF_LEN 1024
-
-typedef struct {
-  size_t max;
-  char *start, *front, *back;
-} uw_buffer;
-
-#endif
--- a/include/urweb.h	Thu May 03 09:56:41 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,359 +0,0 @@
-#ifndef URWEB_H
-#define URWEB_H
-
-#include <sys/types.h>
-
-#include "types.h"
-
-int uw_really_send(int sock, const void *buf, ssize_t len);
-int uw_really_write(int fd, const void *buf, size_t len);
-
-extern uw_unit uw_unit_v;
-
-void uw_global_init(void);
-void uw_app_init(uw_app*);
-
-void uw_client_connect(unsigned id, int pass, int sock,
-                       int (*send)(int sockfd, const void *buf, size_t len),
-                       int (*close)(int fd),
-                       void *logger_data, uw_logger log_error);
-void uw_prune_clients(uw_context);
-failure_kind uw_initialize(uw_context);
-
-uw_context uw_init(int id, void *logger_data, uw_logger log_debug);
-void uw_close(uw_context);
-int uw_set_app(uw_context, uw_app*);
-uw_app *uw_get_app(uw_context);
-void uw_set_db(uw_context, void*);
-void *uw_get_db(uw_context);
-void uw_free(uw_context);
-void uw_reset(uw_context);
-void uw_reset_keep_request(uw_context);
-void uw_reset_keep_error_message(uw_context);
-char *uw_get_url_prefix(uw_context);
-
-failure_kind uw_begin_init(uw_context);
-void uw_set_on_success(char *);
-void uw_set_headers(uw_context, char *(*get_header)(void *, const char *), void *get_header_data);
-failure_kind uw_begin(uw_context, char *path);
-failure_kind uw_begin_onError(uw_context, char *msg);
-void uw_login(uw_context);
-void uw_commit(uw_context);
-int uw_rollback(uw_context, int will_retry);
-
-__attribute__((noreturn)) void uw_error(uw_context, failure_kind, const char *fmt, ...);
-char *uw_error_message(uw_context);
-void uw_set_error_message(uw_context, const char *fmt, ...);
-uw_Basis_string uw_dup_and_clear_error_message(uw_context);
-int uw_has_error(uw_context);
-void uw_push_cleanup(uw_context, void (*func)(void *), void *arg);
-void uw_pop_cleanup(uw_context);
-
-void *uw_malloc(uw_context, size_t);
-void uw_begin_region(uw_context);
-void uw_end_region(uw_context);
-void uw_memstats(uw_context);
-
-int uw_send(uw_context, int sock);
-int uw_print(uw_context, int fd);
-int uw_output(uw_context ctx, int (*output)(void *data, const char *buf, size_t len), void *data);
-
-int uw_set_input(uw_context, const char *name, char *value);
-int uw_set_file_input(uw_context, char *name, uw_Basis_file);
-
-char *uw_get_input(uw_context, int name);
-char *uw_get_optional_input(uw_context, int name);
-uw_Basis_file uw_get_file_input(uw_context, int name);
-void uw_enter_subform(uw_context, int name);
-void uw_leave_subform(uw_context);
-int uw_enter_subforms(uw_context, int name);
-int uw_next_entry(uw_context);
-
-void uw_write(uw_context, const char*);
-
-uw_Basis_source uw_Basis_new_client_source(uw_context, uw_Basis_string);
-uw_unit uw_Basis_set_client_source(uw_context, uw_Basis_source, uw_Basis_string);
-
-void uw_set_script_header(uw_context, const char*);
-char *uw_Basis_get_settings(uw_context, uw_unit);
-char *uw_get_real_script(uw_context);
-
-uw_Basis_string uw_Basis_maybe_onload(uw_context, uw_Basis_string);
-uw_Basis_string uw_Basis_maybe_onunload(uw_context, uw_Basis_string);
-
-void uw_set_needs_push(uw_context, int);
-void uw_set_needs_sig(uw_context, int);
-
-char *uw_Basis_htmlifyInt(uw_context, uw_Basis_int);
-char *uw_Basis_htmlifyFloat(uw_context, uw_Basis_float);
-char *uw_Basis_htmlifyString(uw_context, uw_Basis_string);
-char *uw_Basis_htmlifyBool(uw_context, uw_Basis_bool);
-char *uw_Basis_htmlifyTime(uw_context, uw_Basis_time);
-char *uw_Basis_htmlifySpecialChar(uw_context, unsigned char);
-char *uw_Basis_htmlifySource(uw_context, uw_Basis_source);
-
-uw_unit uw_Basis_htmlifyInt_w(uw_context, uw_Basis_int);
-uw_unit uw_Basis_htmlifyFloat_w(uw_context, uw_Basis_float);
-uw_unit uw_Basis_htmlifyString_w(uw_context, uw_Basis_string);
-uw_unit uw_Basis_htmlifyBool_w(uw_context, uw_Basis_bool);
-uw_unit uw_Basis_htmlifyTime_w(uw_context, uw_Basis_time);
-uw_unit uw_Basis_htmlifySpecialChar_w(uw_context, unsigned char);
-uw_unit uw_Basis_htmlifySource_w(uw_context, uw_Basis_source);
-
-char *uw_Basis_attrifyInt(uw_context, uw_Basis_int);
-char *uw_Basis_attrifyFloat(uw_context, uw_Basis_float);
-char *uw_Basis_attrifyString(uw_context, uw_Basis_string);
-char *uw_Basis_attrifyChar(uw_context, uw_Basis_char);
-char *uw_Basis_attrifyTime(uw_context, uw_Basis_time);
-char *uw_Basis_attrifyChannel(uw_context, uw_Basis_channel);
-char *uw_Basis_attrifyClient(uw_context, uw_Basis_client);
-char *uw_Basis_attrifyCss_class(uw_context, uw_Basis_css_class);
-
-uw_unit uw_Basis_attrifyInt_w(uw_context, uw_Basis_int);
-uw_unit uw_Basis_attrifyFloat_w(uw_context, uw_Basis_float);
-uw_unit uw_Basis_attrifyString_w(uw_context, uw_Basis_string);
-uw_unit uw_Basis_attrifyChar_w(uw_context, uw_Basis_char);
-
-char *uw_Basis_urlifyInt(uw_context, uw_Basis_int);
-char *uw_Basis_urlifyFloat(uw_context, uw_Basis_float);
-char *uw_Basis_urlifyString(uw_context, uw_Basis_string);
-char *uw_Basis_urlifyBool(uw_context, uw_Basis_bool);
-char *uw_Basis_urlifyTime(uw_context, uw_Basis_time);
-char *uw_Basis_urlifyChannel(uw_context, uw_Basis_channel);
-char *uw_Basis_urlifySource(uw_context, uw_Basis_source);
-
-uw_unit uw_Basis_urlifyInt_w(uw_context, uw_Basis_int);
-uw_unit uw_Basis_urlifyFloat_w(uw_context, uw_Basis_float);
-uw_unit uw_Basis_urlifyString_w(uw_context, uw_Basis_string);
-uw_unit uw_Basis_urlifyBool_w(uw_context, uw_Basis_bool);
-uw_unit uw_Basis_urlifyTime_w(uw_context, uw_Basis_time);
-uw_unit uw_Basis_urlifyChannel_w(uw_context, uw_Basis_channel);
-uw_unit uw_Basis_urlifySource_w(uw_context, uw_Basis_source);
-
-uw_Basis_unit uw_Basis_unurlifyUnit(uw_context ctx, char **s);
-uw_Basis_int uw_Basis_unurlifyInt(uw_context, char **);
-uw_Basis_float uw_Basis_unurlifyFloat(uw_context, char **);
-uw_Basis_string uw_Basis_unurlifyString(uw_context, char **);
-uw_Basis_string uw_Basis_unurlifyString_fromClient(uw_context, char **);
-uw_Basis_bool uw_Basis_unurlifyBool(uw_context, char **);
-uw_Basis_time uw_Basis_unurlifyTime(uw_context, char **);
-
-uw_Basis_int uw_Basis_strlen(uw_context, const char *);
-uw_Basis_bool uw_Basis_strlenGe(uw_context, uw_Basis_string, uw_Basis_int);
-uw_Basis_char uw_Basis_strsub(uw_context, const char *, uw_Basis_int);
-uw_Basis_string uw_Basis_strsuffix(uw_context, const char *, uw_Basis_int);
-uw_Basis_string uw_Basis_strcat(uw_context, const char *, const char *);
-uw_Basis_string uw_Basis_mstrcat(uw_context ctx, ...);
-uw_Basis_int *uw_Basis_strindex(uw_context, const char *, uw_Basis_char);
-uw_Basis_int *uw_Basis_strsindex(uw_context, const char *, const char *needle);
-uw_Basis_string uw_Basis_strchr(uw_context, const char *, uw_Basis_char);
-uw_Basis_int uw_Basis_strcspn(uw_context, const char *, const char *);
-uw_Basis_string uw_Basis_substring(uw_context, const char *, uw_Basis_int, uw_Basis_int);
-uw_Basis_string uw_Basis_str1(uw_context, uw_Basis_char);
-
-uw_Basis_string uw_strdup(uw_context, const char *);
-uw_Basis_string uw_maybe_strdup(uw_context, const char *);
-char *uw_memdup(uw_context, const char *, size_t);
-
-uw_Basis_string uw_Basis_sqlifyInt(uw_context, uw_Basis_int);
-uw_Basis_string uw_Basis_sqlifyFloat(uw_context, uw_Basis_float);
-uw_Basis_string uw_Basis_sqlifyString(uw_context, uw_Basis_string);
-uw_Basis_string uw_Basis_sqlifyChar(uw_context, uw_Basis_char);
-uw_Basis_string uw_Basis_sqlifyBool(uw_context, uw_Basis_bool);
-uw_Basis_string uw_Basis_sqlifyTime(uw_context, uw_Basis_time);
-uw_Basis_string uw_Basis_sqlifyBlob(uw_context, uw_Basis_blob);
-uw_Basis_string uw_Basis_sqlifyChannel(uw_context, uw_Basis_channel);
-uw_Basis_string uw_Basis_sqlifyClient(uw_context, uw_Basis_client);
-
-uw_Basis_string uw_Basis_sqlifyIntN(uw_context, uw_Basis_int*);
-uw_Basis_string uw_Basis_sqlifyFloatN(uw_context, uw_Basis_float*);
-uw_Basis_string uw_Basis_sqlifyStringN(uw_context, uw_Basis_string);
-uw_Basis_string uw_Basis_sqlifyBoolN(uw_context, uw_Basis_bool*);
-uw_Basis_string uw_Basis_sqlifyTimeN(uw_context, uw_Basis_time*);
-
-char *uw_Basis_ensqlBool(uw_Basis_bool);
-char *uw_Basis_ensqlTime(uw_context ctx, uw_Basis_time);
-
-char *uw_Basis_jsifyString(uw_context, uw_Basis_string);
-char *uw_Basis_jsifyChar(uw_context, uw_Basis_char);
-char *uw_Basis_jsifyChannel(uw_context, uw_Basis_channel);
-char *uw_Basis_jsifyTime(uw_context, uw_Basis_time);
-
-uw_Basis_string uw_Basis_intToString(uw_context, uw_Basis_int);
-uw_Basis_string uw_Basis_floatToString(uw_context, uw_Basis_float);
-uw_Basis_string uw_Basis_charToString(uw_context, uw_Basis_char);
-uw_Basis_string uw_Basis_boolToString(uw_context, uw_Basis_bool);
-uw_Basis_string uw_Basis_timeToString(uw_context, uw_Basis_time);
-
-uw_Basis_int *uw_Basis_stringToInt(uw_context, uw_Basis_string);
-uw_Basis_float *uw_Basis_stringToFloat(uw_context, uw_Basis_string);
-uw_Basis_char *uw_Basis_stringToChar(uw_context, uw_Basis_string);
-uw_Basis_bool *uw_Basis_stringToBool(uw_context, uw_Basis_string);
-uw_Basis_time *uw_Basis_stringToTime(uw_context, const char *);
-
-uw_Basis_int uw_Basis_stringToInt_error(uw_context, uw_Basis_string);
-uw_Basis_float uw_Basis_stringToFloat_error(uw_context, uw_Basis_string);
-uw_Basis_char uw_Basis_stringToChar_error(uw_context, uw_Basis_string);
-uw_Basis_bool uw_Basis_stringToBool_error(uw_context, uw_Basis_string);
-uw_Basis_time uw_Basis_stringToTime_error(uw_context, const char *);
-uw_Basis_blob uw_Basis_stringToBlob_error(uw_context, uw_Basis_string, size_t);
-uw_Basis_channel uw_Basis_stringToChannel_error(uw_context, uw_Basis_string);
-uw_Basis_client uw_Basis_stringToClient_error(uw_context, uw_Basis_string);
-
-uw_Basis_time uw_Basis_unsqlTime(uw_context, uw_Basis_string);
-
-uw_Basis_string uw_Basis_requestHeader(uw_context, uw_Basis_string);
-
-void uw_write_header(uw_context, uw_Basis_string);
-void uw_clear_headers(uw_context);
-
-uw_Basis_string uw_Basis_get_cookie(uw_context, uw_Basis_string c);
-uw_unit uw_Basis_set_cookie(uw_context, uw_Basis_string prefix, uw_Basis_string c, uw_Basis_string v, uw_Basis_time *expires, uw_Basis_bool secure);
-uw_unit uw_Basis_clear_cookie(uw_context, uw_Basis_string prefix, uw_Basis_string c);
-
-uw_Basis_channel uw_Basis_new_channel(uw_context, uw_unit);
-uw_unit uw_Basis_send(uw_context, uw_Basis_channel, uw_Basis_string);
-
-uw_Basis_client uw_Basis_self(uw_context);
-
-uw_Basis_string uw_Basis_bless(uw_context, uw_Basis_string);
-uw_Basis_string uw_Basis_blessMime(uw_context, uw_Basis_string);
-uw_Basis_string uw_Basis_blessRequestHeader(uw_context, uw_Basis_string);
-uw_Basis_string uw_Basis_blessResponseHeader(uw_context, uw_Basis_string);
-
-uw_Basis_string uw_Basis_checkUrl(uw_context, uw_Basis_string);
-uw_Basis_string uw_Basis_checkMime(uw_context, uw_Basis_string);
-uw_Basis_string uw_Basis_checkRequestHeader(uw_context, uw_Basis_string);
-uw_Basis_string uw_Basis_checkResponseHeader(uw_context, uw_Basis_string);
-
-uw_Basis_string uw_Basis_getHeader(uw_context, uw_Basis_string name);
-uw_unit uw_Basis_setHeader(uw_context, uw_Basis_string name, uw_Basis_string value);
-
-uw_Basis_string uw_unnull(uw_Basis_string);
-uw_Basis_string uw_Basis_makeSigString(uw_context, uw_Basis_string);
-int uw_streq(uw_Basis_string, uw_Basis_string);
-uw_Basis_string uw_Basis_sigString(uw_context, uw_unit);
-
-uw_Basis_string uw_Basis_fileName(uw_context, uw_Basis_file);
-uw_Basis_string uw_Basis_fileMimeType(uw_context, uw_Basis_file);
-uw_Basis_blob uw_Basis_fileData(uw_context, uw_Basis_file);
-uw_Basis_int uw_Basis_blobSize(uw_context, uw_Basis_blob);
-uw_Basis_blob uw_Basis_textBlob(uw_context, uw_Basis_string);
-
-uw_Basis_string uw_Basis_postType(uw_context, uw_Basis_postBody);
-uw_Basis_string uw_Basis_postData(uw_context, uw_Basis_postBody);
-void uw_noPostBody(uw_context);
-void uw_postBody(uw_context, uw_Basis_postBody);
-int uw_hasPostBody(uw_context);
-uw_Basis_postBody uw_getPostBody(uw_context);
-
-void uw_mayReturnIndirectly(uw_context);
-__attribute__((noreturn)) void uw_return_blob(uw_context, uw_Basis_blob, uw_Basis_string mimeType);
-__attribute__((noreturn)) void uw_redirect(uw_context, uw_Basis_string url);
-
-uw_Basis_time uw_Basis_now(uw_context);
-uw_Basis_time uw_Basis_addSeconds(uw_context, uw_Basis_time, uw_Basis_int);
-uw_Basis_int uw_Basis_diffInSeconds(uw_context, uw_Basis_time, uw_Basis_time);
-uw_Basis_int uw_Basis_toSeconds(uw_context, uw_Basis_time);
-uw_Basis_int uw_Basis_diffInMilliseconds(uw_context, uw_Basis_time, uw_Basis_time);
-uw_Basis_int uw_Basis_toMilliseconds(uw_context, uw_Basis_time);
-extern const uw_Basis_time uw_Basis_minTime;
-
-void uw_register_transactional(uw_context, void *data, uw_callback commit, uw_callback rollback, uw_callback_with_retry free);
-
-void uw_check_heap(uw_context, size_t extra);
-char *uw_heap_front(uw_context);
-void uw_set_heap_front(uw_context, char*);
-
-uw_Basis_string uw_Basis_unAs(uw_context, uw_Basis_string);
-
-extern char *uw_sqlfmtInt;
-extern char *uw_sqlfmtFloat;
-extern int uw_Estrings;
-extern char *uw_sqlsuffixString;
-extern char *uw_sqlsuffixChar;
-extern char *uw_sqlsuffixBlob;
-extern char *uw_sqlfmtUint4;
-
-void *uw_get_global(uw_context, char *name);
-void uw_set_global(uw_context, char *name, void *data, uw_callback free);
-
-uw_Basis_bool uw_Basis_isalnum(uw_context, uw_Basis_char);
-uw_Basis_bool uw_Basis_isalpha(uw_context, uw_Basis_char);
-uw_Basis_bool uw_Basis_isblank(uw_context, uw_Basis_char);
-uw_Basis_bool uw_Basis_iscntrl(uw_context, uw_Basis_char);
-uw_Basis_bool uw_Basis_isdigit(uw_context, uw_Basis_char);
-uw_Basis_bool uw_Basis_isgraph(uw_context, uw_Basis_char);
-uw_Basis_bool uw_Basis_islower(uw_context, uw_Basis_char);
-uw_Basis_bool uw_Basis_isprint(uw_context, uw_Basis_char);
-uw_Basis_bool uw_Basis_ispunct(uw_context, uw_Basis_char);
-uw_Basis_bool uw_Basis_isspace(uw_context, uw_Basis_char);
-uw_Basis_bool uw_Basis_isupper(uw_context, uw_Basis_char);
-uw_Basis_bool uw_Basis_isxdigit(uw_context, uw_Basis_char);
-uw_Basis_char uw_Basis_tolower(uw_context, uw_Basis_char);
-uw_Basis_char uw_Basis_toupper(uw_context, uw_Basis_char);
-
-uw_Basis_int uw_Basis_ord(uw_context, uw_Basis_char);
-uw_Basis_char uw_Basis_chr(uw_context, uw_Basis_int);
-
-uw_Basis_string uw_Basis_currentUrl(uw_context);
-void uw_set_currentUrl(uw_context, char *);
-
-extern size_t uw_messages_max, uw_clients_max, uw_headers_max, uw_page_max, uw_heap_max, uw_script_max;
-extern size_t uw_inputs_max, uw_cleanup_max, uw_subinputs_max, uw_deltas_max, uw_transactionals_max, uw_globals_max;
-
-extern size_t uw_database_max;
-
-extern int uw_time;
-
-void uw_set_deadline(uw_context, int);
-void uw_check_deadline(uw_context);
-
-uw_Basis_unit uw_Basis_debug(uw_context, uw_Basis_string);
-uw_Basis_int uw_Basis_naughtyDebug(uw_context, uw_Basis_string);
-
-void uw_set_client_data(uw_context, void *);
-
-uw_Basis_int uw_Basis_rand(uw_context);
-
-extern int uw_time_max, uw_supports_direct_status, uw_min_heap;
-
-failure_kind uw_runCallback(uw_context, void (*callback)(uw_context));
-
-uw_Basis_string uw_Basis_timef(uw_context, const char *fmt, uw_Basis_time);
-uw_Basis_time uw_Basis_stringToTimef(uw_context, const char *fmt, uw_Basis_string);
-uw_Basis_time uw_Basis_stringToTimef_error(uw_context, const char *fmt, uw_Basis_string);
-
-uw_Basis_string uw_Basis_crypt(uw_context, uw_Basis_string key, uw_Basis_string salt);
-
-uw_Basis_bool uw_Basis_eq_time(uw_context, uw_Basis_time, uw_Basis_time);
-uw_Basis_bool uw_Basis_lt_time(uw_context, uw_Basis_time, uw_Basis_time);
-uw_Basis_bool uw_Basis_le_time(uw_context, uw_Basis_time, uw_Basis_time);
-
-void uw_buffer_init(size_t max, uw_buffer *, size_t initial);
-void uw_buffer_free(uw_buffer *);
-void uw_buffer_reset(uw_buffer *);
-int uw_buffer_check(uw_buffer *, size_t extra);
-size_t uw_buffer_used(uw_buffer *);
-size_t uw_buffer_avail(uw_buffer *);
-int uw_buffer_append(uw_buffer *, const char *, size_t);
-
-void uw_setQueryString(uw_context, uw_Basis_string);
-uw_Basis_string uw_queryString(uw_context);
-
-uw_Basis_time *uw_Basis_readUtc(uw_context, uw_Basis_string);
-
-void uw_isPost(uw_context);
-uw_Basis_bool uw_Basis_currentUrlHasPost(uw_context);
-uw_Basis_bool uw_Basis_currentUrlHasQueryString(uw_context);
-
-void uw_cutErrorLocation(char *);
-
-uw_Basis_string uw_Basis_fresh(uw_context);
-
-uw_Basis_float uw_Basis_floatFromInt(uw_context, uw_Basis_int);
-uw_Basis_int uw_Basis_ceil(uw_context, uw_Basis_float);
-uw_Basis_int uw_Basis_trunc(uw_context, uw_Basis_float);
-uw_Basis_int uw_Basis_round(uw_context, uw_Basis_float);
-
-#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/urweb/config.h.in	Wed May 02 17:17:57 2012 -0400
@@ -0,0 +1,104 @@
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <mysql/mysql.h> header file. */
+#undef HAVE_MYSQL_MYSQL_H
+
+/* Define to 1 if you have the <postgresql/libpq-fe.h> header file. */
+#undef HAVE_POSTGRESQL_LIBPQ_FE_H
+
+/* Define if you have POSIX threads libraries and header files. */
+#undef HAVE_PTHREAD
+
+/* Have PTHREAD_PRIO_INHERIT. */
+#undef HAVE_PTHREAD_PRIO_INHERIT
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#undef LT_OBJDIR
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to necessary symbol if this constant uses a non-standard name on
+   your system. */
+#undef PTHREAD_CREATE_JOINABLE
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Enable extensions on AIX 3, Interix.  */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+/* Enable GNU extensions on systems that have them.  */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+/* Enable threading extensions on Solaris.  */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+/* Enable extensions on HP NonStop.  */
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif
+/* Enable general extensions on Solaris.  */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+
+
+/* Define to 1 if on MINIX. */
+#undef _MINIX
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+   this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+#undef _POSIX_SOURCE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/urweb/queue.h	Wed May 02 17:17:57 2012 -0400
@@ -0,0 +1,7 @@
+#ifndef QUEUE_H
+#define QUEUE_H
+
+int uw_dequeue();
+void uw_enqueue(int);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/urweb/request.h	Wed May 02 17:17:57 2012 -0400
@@ -0,0 +1,37 @@
+#ifndef REQUEST_H
+#define REQUEST_H
+
+#include <sys/types.h>
+
+#include "types.h"
+
+typedef struct uw_rc *uw_request_context;
+
+void uw_request_init(uw_app *app, void *logger_data, uw_logger log_error, uw_logger log_debug);
+void uw_sign(const char *in, char *out);
+
+uw_request_context uw_new_request_context(void);
+void uw_free_request_context(uw_request_context);
+
+request_result uw_request(uw_request_context, uw_context,
+                          char *method, char *path, char *query_string,
+                          char *body, size_t body_len,
+                          void (*on_success)(uw_context), void (*on_failure)(uw_context),
+                          void *logger_data, uw_logger log_error, uw_logger log_debug,
+                          int sock,
+                          int (*send)(int sockfd, const void *buf, ssize_t len),
+                          int (*close)(int fd));
+
+uw_context uw_request_new_context(int id, uw_app*, void *logger_data, uw_logger log_error, uw_logger log_debug);
+
+typedef struct {
+  uw_app *app;
+  void *logger_data;
+  uw_logger log_error, log_debug;
+} loggers;
+
+void *client_pruner(void *data);
+
+int pthread_create_big(pthread_t *outThread, void *foo, void *threadFunc, void *arg);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/urweb/types.h	Wed May 02 17:17:57 2012 -0400
@@ -0,0 +1,110 @@
+#ifndef URWEB_TYPES_H
+#define URWEB_TYPES_H
+
+#include <time.h>
+#include <unistd.h>
+#include <stdint.h>
+
+typedef long long uw_Basis_int;
+typedef double uw_Basis_float;
+typedef char* uw_Basis_string;
+typedef char uw_Basis_char;
+typedef struct {
+  time_t seconds;
+  unsigned microseconds;
+} uw_Basis_time;
+typedef struct {
+  size_t size;
+  char *data;
+} uw_Basis_blob;
+
+typedef int uw_unit;
+typedef uw_unit uw_Basis_unit;
+
+typedef enum uw_Basis_bool { uw_Basis_False, uw_Basis_True } uw_Basis_bool;
+
+typedef struct uw_context *uw_context;
+
+typedef uw_Basis_string uw_Basis_xhtml;
+typedef uw_Basis_string uw_Basis_page;
+typedef uw_Basis_string uw_Basis_xbody;
+typedef uw_Basis_string uw_Basis_css_class;
+
+typedef unsigned uw_Basis_client;
+typedef struct {
+  unsigned cli, chn;
+} uw_Basis_channel;
+
+typedef struct {
+  int context;
+  unsigned long long source;
+} uw_Basis_source;
+
+typedef struct uw_Basis_file {
+  uw_Basis_string name, type;
+  uw_Basis_blob data;
+} uw_Basis_file;
+
+typedef struct uw_Basis_postBody {
+  uw_Basis_string type, data;
+} uw_Basis_postBody;
+
+typedef uw_Basis_string uw_Basis_queryString;
+
+typedef enum { SUCCESS, FATAL, BOUNDED_RETRY, UNLIMITED_RETRY, RETURN_INDIRECTLY } failure_kind;
+
+typedef enum { SERVED, KEEP_OPEN, FAILED } request_result;
+
+typedef struct input *uw_input;
+
+#define INTS_MAX 50
+#define FLOATS_MAX 100
+#define TIMES_MAX 100
+
+typedef void (*uw_callback)(void *);
+typedef void (*uw_callback_with_retry)(void *, int will_retry);
+typedef void (*uw_logger)(void*, const char *fmt, ...);
+
+typedef struct {
+  void (*callback)(uw_context);
+  unsigned int period;
+} uw_periodic;
+
+typedef struct {
+  int inputs_len, timeout;
+  char *url_prefix;
+
+  void (*client_init)();
+  void (*initializer)(uw_context);
+  void (*expunger)(uw_context, uw_Basis_client);
+
+  void (*db_init)(uw_context);
+  int (*db_begin)(uw_context);
+  int (*db_commit)(uw_context);
+  int (*db_rollback)(uw_context);
+  void (*db_close)(uw_context);
+
+  void (*handle)(uw_context, char *);
+
+  int (*input_num)(const char*);
+  uw_Basis_string (*cookie_sig)(uw_context);
+  int (*check_url)(const char *);
+  int (*check_mime)(const char *);
+  int (*check_requestHeader)(const char *);
+  int (*check_responseHeader)(const char *);
+
+  void (*on_error)(uw_context, char *);
+
+  uw_periodic *periodics; // 0-terminated array
+
+  uw_Basis_string time_format;
+} uw_app;
+
+#define ERROR_BUF_LEN 1024
+
+typedef struct {
+  size_t max;
+  char *start, *front, *back;
+} uw_buffer;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/urweb/urweb.h	Wed May 02 17:17:57 2012 -0400
@@ -0,0 +1,359 @@
+#ifndef URWEB_H
+#define URWEB_H
+
+#include <sys/types.h>
+
+#include "types.h"
+
+int uw_really_send(int sock, const void *buf, ssize_t len);
+int uw_really_write(int fd, const void *buf, size_t len);
+
+extern uw_unit uw_unit_v;
+
+void uw_global_init(void);
+void uw_app_init(uw_app*);
+
+void uw_client_connect(unsigned id, int pass, int sock,
+                       int (*send)(int sockfd, const void *buf, size_t len),
+                       int (*close)(int fd),
+                       void *logger_data, uw_logger log_error);
+void uw_prune_clients(uw_context);
+failure_kind uw_initialize(uw_context);
+
+uw_context uw_init(int id, void *logger_data, uw_logger log_debug);
+void uw_close(uw_context);
+int uw_set_app(uw_context, uw_app*);
+uw_app *uw_get_app(uw_context);
+void uw_set_db(uw_context, void*);
+void *uw_get_db(uw_context);
+void uw_free(uw_context);
+void uw_reset(uw_context);
+void uw_reset_keep_request(uw_context);
+void uw_reset_keep_error_message(uw_context);
+char *uw_get_url_prefix(uw_context);
+
+failure_kind uw_begin_init(uw_context);
+void uw_set_on_success(char *);
+void uw_set_headers(uw_context, char *(*get_header)(void *, const char *), void *get_header_data);
+failure_kind uw_begin(uw_context, char *path);
+failure_kind uw_begin_onError(uw_context, char *msg);
+void uw_login(uw_context);
+void uw_commit(uw_context);
+int uw_rollback(uw_context, int will_retry);
+
+__attribute__((noreturn)) void uw_error(uw_context, failure_kind, const char *fmt, ...);
+char *uw_error_message(uw_context);
+void uw_set_error_message(uw_context, const char *fmt, ...);
+uw_Basis_string uw_dup_and_clear_error_message(uw_context);
+int uw_has_error(uw_context);
+void uw_push_cleanup(uw_context, void (*func)(void *), void *arg);
+void uw_pop_cleanup(uw_context);
+
+void *uw_malloc(uw_context, size_t);
+void uw_begin_region(uw_context);
+void uw_end_region(uw_context);
+void uw_memstats(uw_context);
+
+int uw_send(uw_context, int sock);
+int uw_print(uw_context, int fd);
+int uw_output(uw_context ctx, int (*output)(void *data, const char *buf, size_t len), void *data);
+
+int uw_set_input(uw_context, const char *name, char *value);
+int uw_set_file_input(uw_context, char *name, uw_Basis_file);
+
+char *uw_get_input(uw_context, int name);
+char *uw_get_optional_input(uw_context, int name);
+uw_Basis_file uw_get_file_input(uw_context, int name);
+void uw_enter_subform(uw_context, int name);
+void uw_leave_subform(uw_context);
+int uw_enter_subforms(uw_context, int name);
+int uw_next_entry(uw_context);
+
+void uw_write(uw_context, const char*);
+
+uw_Basis_source uw_Basis_new_client_source(uw_context, uw_Basis_string);
+uw_unit uw_Basis_set_client_source(uw_context, uw_Basis_source, uw_Basis_string);
+
+void uw_set_script_header(uw_context, const char*);
+char *uw_Basis_get_settings(uw_context, uw_unit);
+char *uw_get_real_script(uw_context);
+
+uw_Basis_string uw_Basis_maybe_onload(uw_context, uw_Basis_string);
+uw_Basis_string uw_Basis_maybe_onunload(uw_context, uw_Basis_string);
+
+void uw_set_needs_push(uw_context, int);
+void uw_set_needs_sig(uw_context, int);
+
+char *uw_Basis_htmlifyInt(uw_context, uw_Basis_int);
+char *uw_Basis_htmlifyFloat(uw_context, uw_Basis_float);
+char *uw_Basis_htmlifyString(uw_context, uw_Basis_string);
+char *uw_Basis_htmlifyBool(uw_context, uw_Basis_bool);
+char *uw_Basis_htmlifyTime(uw_context, uw_Basis_time);
+char *uw_Basis_htmlifySpecialChar(uw_context, unsigned char);
+char *uw_Basis_htmlifySource(uw_context, uw_Basis_source);
+
+uw_unit uw_Basis_htmlifyInt_w(uw_context, uw_Basis_int);
+uw_unit uw_Basis_htmlifyFloat_w(uw_context, uw_Basis_float);
+uw_unit uw_Basis_htmlifyString_w(uw_context, uw_Basis_string);
+uw_unit uw_Basis_htmlifyBool_w(uw_context, uw_Basis_bool);
+uw_unit uw_Basis_htmlifyTime_w(uw_context, uw_Basis_time);
+uw_unit uw_Basis_htmlifySpecialChar_w(uw_context, unsigned char);
+uw_unit uw_Basis_htmlifySource_w(uw_context, uw_Basis_source);
+
+char *uw_Basis_attrifyInt(uw_context, uw_Basis_int);
+char *uw_Basis_attrifyFloat(uw_context, uw_Basis_float);
+char *uw_Basis_attrifyString(uw_context, uw_Basis_string);
+char *uw_Basis_attrifyChar(uw_context, uw_Basis_char);
+char *uw_Basis_attrifyTime(uw_context, uw_Basis_time);
+char *uw_Basis_attrifyChannel(uw_context, uw_Basis_channel);
+char *uw_Basis_attrifyClient(uw_context, uw_Basis_client);
+char *uw_Basis_attrifyCss_class(uw_context, uw_Basis_css_class);
+
+uw_unit uw_Basis_attrifyInt_w(uw_context, uw_Basis_int);
+uw_unit uw_Basis_attrifyFloat_w(uw_context, uw_Basis_float);
+uw_unit uw_Basis_attrifyString_w(uw_context, uw_Basis_string);
+uw_unit uw_Basis_attrifyChar_w(uw_context, uw_Basis_char);
+
+char *uw_Basis_urlifyInt(uw_context, uw_Basis_int);
+char *uw_Basis_urlifyFloat(uw_context, uw_Basis_float);
+char *uw_Basis_urlifyString(uw_context, uw_Basis_string);
+char *uw_Basis_urlifyBool(uw_context, uw_Basis_bool);
+char *uw_Basis_urlifyTime(uw_context, uw_Basis_time);
+char *uw_Basis_urlifyChannel(uw_context, uw_Basis_channel);
+char *uw_Basis_urlifySource(uw_context, uw_Basis_source);
+
+uw_unit uw_Basis_urlifyInt_w(uw_context, uw_Basis_int);
+uw_unit uw_Basis_urlifyFloat_w(uw_context, uw_Basis_float);
+uw_unit uw_Basis_urlifyString_w(uw_context, uw_Basis_string);
+uw_unit uw_Basis_urlifyBool_w(uw_context, uw_Basis_bool);
+uw_unit uw_Basis_urlifyTime_w(uw_context, uw_Basis_time);
+uw_unit uw_Basis_urlifyChannel_w(uw_context, uw_Basis_channel);
+uw_unit uw_Basis_urlifySource_w(uw_context, uw_Basis_source);
+
+uw_Basis_unit uw_Basis_unurlifyUnit(uw_context ctx, char **s);
+uw_Basis_int uw_Basis_unurlifyInt(uw_context, char **);
+uw_Basis_float uw_Basis_unurlifyFloat(uw_context, char **);
+uw_Basis_string uw_Basis_unurlifyString(uw_context, char **);
+uw_Basis_string uw_Basis_unurlifyString_fromClient(uw_context, char **);
+uw_Basis_bool uw_Basis_unurlifyBool(uw_context, char **);
+uw_Basis_time uw_Basis_unurlifyTime(uw_context, char **);
+
+uw_Basis_int uw_Basis_strlen(uw_context, const char *);
+uw_Basis_bool uw_Basis_strlenGe(uw_context, uw_Basis_string, uw_Basis_int);
+uw_Basis_char uw_Basis_strsub(uw_context, const char *, uw_Basis_int);
+uw_Basis_string uw_Basis_strsuffix(uw_context, const char *, uw_Basis_int);
+uw_Basis_string uw_Basis_strcat(uw_context, const char *, const char *);
+uw_Basis_string uw_Basis_mstrcat(uw_context ctx, ...);
+uw_Basis_int *uw_Basis_strindex(uw_context, const char *, uw_Basis_char);
+uw_Basis_int *uw_Basis_strsindex(uw_context, const char *, const char *needle);
+uw_Basis_string uw_Basis_strchr(uw_context, const char *, uw_Basis_char);
+uw_Basis_int uw_Basis_strcspn(uw_context, const char *, const char *);
+uw_Basis_string uw_Basis_substring(uw_context, const char *, uw_Basis_int, uw_Basis_int);
+uw_Basis_string uw_Basis_str1(uw_context, uw_Basis_char);
+
+uw_Basis_string uw_strdup(uw_context, const char *);
+uw_Basis_string uw_maybe_strdup(uw_context, const char *);
+char *uw_memdup(uw_context, const char *, size_t);
+
+uw_Basis_string uw_Basis_sqlifyInt(uw_context, uw_Basis_int);
+uw_Basis_string uw_Basis_sqlifyFloat(uw_context, uw_Basis_float);
+uw_Basis_string uw_Basis_sqlifyString(uw_context, uw_Basis_string);
+uw_Basis_string uw_Basis_sqlifyChar(uw_context, uw_Basis_char);
+uw_Basis_string uw_Basis_sqlifyBool(uw_context, uw_Basis_bool);
+uw_Basis_string uw_Basis_sqlifyTime(uw_context, uw_Basis_time);
+uw_Basis_string uw_Basis_sqlifyBlob(uw_context, uw_Basis_blob);
+uw_Basis_string uw_Basis_sqlifyChannel(uw_context, uw_Basis_channel);
+uw_Basis_string uw_Basis_sqlifyClient(uw_context, uw_Basis_client);
+
+uw_Basis_string uw_Basis_sqlifyIntN(uw_context, uw_Basis_int*);
+uw_Basis_string uw_Basis_sqlifyFloatN(uw_context, uw_Basis_float*);
+uw_Basis_string uw_Basis_sqlifyStringN(uw_context, uw_Basis_string);
+uw_Basis_string uw_Basis_sqlifyBoolN(uw_context, uw_Basis_bool*);
+uw_Basis_string uw_Basis_sqlifyTimeN(uw_context, uw_Basis_time*);
+
+char *uw_Basis_ensqlBool(uw_Basis_bool);
+char *uw_Basis_ensqlTime(uw_context ctx, uw_Basis_time);
+
+char *uw_Basis_jsifyString(uw_context, uw_Basis_string);
+char *uw_Basis_jsifyChar(uw_context, uw_Basis_char);
+char *uw_Basis_jsifyChannel(uw_context, uw_Basis_channel);
+char *uw_Basis_jsifyTime(uw_context, uw_Basis_time);
+
+uw_Basis_string uw_Basis_intToString(uw_context, uw_Basis_int);
+uw_Basis_string uw_Basis_floatToString(uw_context, uw_Basis_float);
+uw_Basis_string uw_Basis_charToString(uw_context, uw_Basis_char);
+uw_Basis_string uw_Basis_boolToString(uw_context, uw_Basis_bool);
+uw_Basis_string uw_Basis_timeToString(uw_context, uw_Basis_time);
+
+uw_Basis_int *uw_Basis_stringToInt(uw_context, uw_Basis_string);
+uw_Basis_float *uw_Basis_stringToFloat(uw_context, uw_Basis_string);
+uw_Basis_char *uw_Basis_stringToChar(uw_context, uw_Basis_string);
+uw_Basis_bool *uw_Basis_stringToBool(uw_context, uw_Basis_string);
+uw_Basis_time *uw_Basis_stringToTime(uw_context, const char *);
+
+uw_Basis_int uw_Basis_stringToInt_error(uw_context, uw_Basis_string);
+uw_Basis_float uw_Basis_stringToFloat_error(uw_context, uw_Basis_string);
+uw_Basis_char uw_Basis_stringToChar_error(uw_context, uw_Basis_string);
+uw_Basis_bool uw_Basis_stringToBool_error(uw_context, uw_Basis_string);
+uw_Basis_time uw_Basis_stringToTime_error(uw_context, const char *);
+uw_Basis_blob uw_Basis_stringToBlob_error(uw_context, uw_Basis_string, size_t);
+uw_Basis_channel uw_Basis_stringToChannel_error(uw_context, uw_Basis_string);
+uw_Basis_client uw_Basis_stringToClient_error(uw_context, uw_Basis_string);
+
+uw_Basis_time uw_Basis_unsqlTime(uw_context, uw_Basis_string);
+
+uw_Basis_string uw_Basis_requestHeader(uw_context, uw_Basis_string);
+
+void uw_write_header(uw_context, uw_Basis_string);
+void uw_clear_headers(uw_context);
+
+uw_Basis_string uw_Basis_get_cookie(uw_context, uw_Basis_string c);
+uw_unit uw_Basis_set_cookie(uw_context, uw_Basis_string prefix, uw_Basis_string c, uw_Basis_string v, uw_Basis_time *expires, uw_Basis_bool secure);
+uw_unit uw_Basis_clear_cookie(uw_context, uw_Basis_string prefix, uw_Basis_string c);
+
+uw_Basis_channel uw_Basis_new_channel(uw_context, uw_unit);
+uw_unit uw_Basis_send(uw_context, uw_Basis_channel, uw_Basis_string);
+
+uw_Basis_client uw_Basis_self(uw_context);
+
+uw_Basis_string uw_Basis_bless(uw_context, uw_Basis_string);
+uw_Basis_string uw_Basis_blessMime(uw_context, uw_Basis_string);
+uw_Basis_string uw_Basis_blessRequestHeader(uw_context, uw_Basis_string);
+uw_Basis_string uw_Basis_blessResponseHeader(uw_context, uw_Basis_string);
+
+uw_Basis_string uw_Basis_checkUrl(uw_context, uw_Basis_string);
+uw_Basis_string uw_Basis_checkMime(uw_context, uw_Basis_string);
+uw_Basis_string uw_Basis_checkRequestHeader(uw_context, uw_Basis_string);
+uw_Basis_string uw_Basis_checkResponseHeader(uw_context, uw_Basis_string);
+
+uw_Basis_string uw_Basis_getHeader(uw_context, uw_Basis_string name);
+uw_unit uw_Basis_setHeader(uw_context, uw_Basis_string name, uw_Basis_string value);
+
+uw_Basis_string uw_unnull(uw_Basis_string);
+uw_Basis_string uw_Basis_makeSigString(uw_context, uw_Basis_string);
+int uw_streq(uw_Basis_string, uw_Basis_string);
+uw_Basis_string uw_Basis_sigString(uw_context, uw_unit);
+
+uw_Basis_string uw_Basis_fileName(uw_context, uw_Basis_file);
+uw_Basis_string uw_Basis_fileMimeType(uw_context, uw_Basis_file);
+uw_Basis_blob uw_Basis_fileData(uw_context, uw_Basis_file);
+uw_Basis_int uw_Basis_blobSize(uw_context, uw_Basis_blob);
+uw_Basis_blob uw_Basis_textBlob(uw_context, uw_Basis_string);
+
+uw_Basis_string uw_Basis_postType(uw_context, uw_Basis_postBody);
+uw_Basis_string uw_Basis_postData(uw_context, uw_Basis_postBody);
+void uw_noPostBody(uw_context);
+void uw_postBody(uw_context, uw_Basis_postBody);
+int uw_hasPostBody(uw_context);
+uw_Basis_postBody uw_getPostBody(uw_context);
+
+void uw_mayReturnIndirectly(uw_context);
+__attribute__((noreturn)) void uw_return_blob(uw_context, uw_Basis_blob, uw_Basis_string mimeType);
+__attribute__((noreturn)) void uw_redirect(uw_context, uw_Basis_string url);
+
+uw_Basis_time uw_Basis_now(uw_context);
+uw_Basis_time uw_Basis_addSeconds(uw_context, uw_Basis_time, uw_Basis_int);
+uw_Basis_int uw_Basis_diffInSeconds(uw_context, uw_Basis_time, uw_Basis_time);
+uw_Basis_int uw_Basis_toSeconds(uw_context, uw_Basis_time);
+uw_Basis_int uw_Basis_diffInMilliseconds(uw_context, uw_Basis_time, uw_Basis_time);
+uw_Basis_int uw_Basis_toMilliseconds(uw_context, uw_Basis_time);
+extern const uw_Basis_time uw_Basis_minTime;
+
+void uw_register_transactional(uw_context, void *data, uw_callback commit, uw_callback rollback, uw_callback_with_retry free);
+
+void uw_check_heap(uw_context, size_t extra);
+char *uw_heap_front(uw_context);
+void uw_set_heap_front(uw_context, char*);
+
+uw_Basis_string uw_Basis_unAs(uw_context, uw_Basis_string);
+
+extern char *uw_sqlfmtInt;
+extern char *uw_sqlfmtFloat;
+extern int uw_Estrings;
+extern char *uw_sqlsuffixString;
+extern char *uw_sqlsuffixChar;
+extern char *uw_sqlsuffixBlob;
+extern char *uw_sqlfmtUint4;
+
+void *uw_get_global(uw_context, char *name);
+void uw_set_global(uw_context, char *name, void *data, uw_callback free);
+
+uw_Basis_bool uw_Basis_isalnum(uw_context, uw_Basis_char);
+uw_Basis_bool uw_Basis_isalpha(uw_context, uw_Basis_char);
+uw_Basis_bool uw_Basis_isblank(uw_context, uw_Basis_char);
+uw_Basis_bool uw_Basis_iscntrl(uw_context, uw_Basis_char);
+uw_Basis_bool uw_Basis_isdigit(uw_context, uw_Basis_char);
+uw_Basis_bool uw_Basis_isgraph(uw_context, uw_Basis_char);
+uw_Basis_bool uw_Basis_islower(uw_context, uw_Basis_char);
+uw_Basis_bool uw_Basis_isprint(uw_context, uw_Basis_char);
+uw_Basis_bool uw_Basis_ispunct(uw_context, uw_Basis_char);
+uw_Basis_bool uw_Basis_isspace(uw_context, uw_Basis_char);
+uw_Basis_bool uw_Basis_isupper(uw_context, uw_Basis_char);
+uw_Basis_bool uw_Basis_isxdigit(uw_context, uw_Basis_char);
+uw_Basis_char uw_Basis_tolower(uw_context, uw_Basis_char);
+uw_Basis_char uw_Basis_toupper(uw_context, uw_Basis_char);
+
+uw_Basis_int uw_Basis_ord(uw_context, uw_Basis_char);
+uw_Basis_char uw_Basis_chr(uw_context, uw_Basis_int);
+
+uw_Basis_string uw_Basis_currentUrl(uw_context);
+void uw_set_currentUrl(uw_context, char *);
+
+extern size_t uw_messages_max, uw_clients_max, uw_headers_max, uw_page_max, uw_heap_max, uw_script_max;
+extern size_t uw_inputs_max, uw_cleanup_max, uw_subinputs_max, uw_deltas_max, uw_transactionals_max, uw_globals_max;
+
+extern size_t uw_database_max;
+
+extern int uw_time;
+
+void uw_set_deadline(uw_context, int);
+void uw_check_deadline(uw_context);
+
+uw_Basis_unit uw_Basis_debug(uw_context, uw_Basis_string);
+uw_Basis_int uw_Basis_naughtyDebug(uw_context, uw_Basis_string);
+
+void uw_set_client_data(uw_context, void *);
+
+uw_Basis_int uw_Basis_rand(uw_context);
+
+extern int uw_time_max, uw_supports_direct_status, uw_min_heap;
+
+failure_kind uw_runCallback(uw_context, void (*callback)(uw_context));
+
+uw_Basis_string uw_Basis_timef(uw_context, const char *fmt, uw_Basis_time);
+uw_Basis_time uw_Basis_stringToTimef(uw_context, const char *fmt, uw_Basis_string);
+uw_Basis_time uw_Basis_stringToTimef_error(uw_context, const char *fmt, uw_Basis_string);
+
+uw_Basis_string uw_Basis_crypt(uw_context, uw_Basis_string key, uw_Basis_string salt);
+
+uw_Basis_bool uw_Basis_eq_time(uw_context, uw_Basis_time, uw_Basis_time);
+uw_Basis_bool uw_Basis_lt_time(uw_context, uw_Basis_time, uw_Basis_time);
+uw_Basis_bool uw_Basis_le_time(uw_context, uw_Basis_time, uw_Basis_time);
+
+void uw_buffer_init(size_t max, uw_buffer *, size_t initial);
+void uw_buffer_free(uw_buffer *);
+void uw_buffer_reset(uw_buffer *);
+int uw_buffer_check(uw_buffer *, size_t extra);
+size_t uw_buffer_used(uw_buffer *);
+size_t uw_buffer_avail(uw_buffer *);
+int uw_buffer_append(uw_buffer *, const char *, size_t);
+
+void uw_setQueryString(uw_context, uw_Basis_string);
+uw_Basis_string uw_queryString(uw_context);
+
+uw_Basis_time *uw_Basis_readUtc(uw_context, uw_Basis_string);
+
+void uw_isPost(uw_context);
+uw_Basis_bool uw_Basis_currentUrlHasPost(uw_context);
+uw_Basis_bool uw_Basis_currentUrlHasQueryString(uw_context);
+
+void uw_cutErrorLocation(char *);
+
+uw_Basis_string uw_Basis_fresh(uw_context);
+
+uw_Basis_float uw_Basis_floatFromInt(uw_context, uw_Basis_int);
+uw_Basis_int uw_Basis_ceil(uw_context, uw_Basis_float);
+uw_Basis_int uw_Basis_trunc(uw_context, uw_Basis_float);
+uw_Basis_int uw_Basis_round(uw_context, uw_Basis_float);
+
+#endif
--- a/src/c/Makefile.am	Thu May 03 09:56:41 2012 -0400
+++ b/src/c/Makefile.am	Wed May 02 17:17:57 2012 -0400
@@ -6,5 +6,5 @@
 liburweb_fastcgi_la_SOURCES = fastcgi.c
 liburweb_static_la_SOURCES = static.c
 
-AM_CPPFLAGS = -I../../include @OPENSSL_INCLUDES@
+AM_CPPFLAGS = -I../../include/urweb @OPENSSL_INCLUDES@
 AM_CFLAGS = -Wimplicit -Wall -Werror -Wno-format-security -Wno-deprecated-declarations
--- a/src/c/Makefile.in	Thu May 03 09:56:41 2012 -0400
+++ b/src/c/Makefile.in	Wed May 02 17:17:57 2012 -0400
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
-# Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  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.
@@ -45,7 +45,7 @@
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_HEADER = $(top_builddir)/include/urweb/config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
@@ -69,12 +69,6 @@
 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)$(libdir)"
 LTLIBRARIES = $(lib_LTLIBRARIES)
 liburweb_la_LIBADD =
@@ -93,7 +87,7 @@
 liburweb_static_la_LIBADD =
 am_liburweb_static_la_OBJECTS = static.lo
 liburweb_static_la_OBJECTS = $(am_liburweb_static_la_OBJECTS)
-DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/urweb
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
 am__mv = mv -f
@@ -192,6 +186,7 @@
 SHELL = @SHELL@
 SITELISP = @SITELISP@
 SQHEADER = @SQHEADER@
+SRCLIB = @SRCLIB@
 STRIP = @STRIP@
 VERSION = @VERSION@
 abs_builddir = @abs_builddir@
@@ -253,7 +248,7 @@
 liburweb_cgi_la_SOURCES = cgi.c
 liburweb_fastcgi_la_SOURCES = fastcgi.c
 liburweb_static_la_SOURCES = static.c
-AM_CPPFLAGS = -I../../include @OPENSSL_INCLUDES@
+AM_CPPFLAGS = -I../../include/urweb @OPENSSL_INCLUDES@
 AM_CFLAGS = -Wimplicit -Wall -Werror -Wno-format-security -Wno-deprecated-declarations
 all: all-am
 
@@ -320,15 +315,15 @@
 	  echo "rm -f \"$${dir}/so_locations\""; \
 	  rm -f "$${dir}/so_locations"; \
 	done
-liburweb.la: $(liburweb_la_OBJECTS) $(liburweb_la_DEPENDENCIES) $(EXTRA_liburweb_la_DEPENDENCIES) 
+liburweb.la: $(liburweb_la_OBJECTS) $(liburweb_la_DEPENDENCIES) 
 	$(LINK) -rpath $(libdir) $(liburweb_la_OBJECTS) $(liburweb_la_LIBADD) $(LIBS)
-liburweb_cgi.la: $(liburweb_cgi_la_OBJECTS) $(liburweb_cgi_la_DEPENDENCIES) $(EXTRA_liburweb_cgi_la_DEPENDENCIES) 
+liburweb_cgi.la: $(liburweb_cgi_la_OBJECTS) $(liburweb_cgi_la_DEPENDENCIES) 
 	$(LINK) -rpath $(libdir) $(liburweb_cgi_la_OBJECTS) $(liburweb_cgi_la_LIBADD) $(LIBS)
-liburweb_fastcgi.la: $(liburweb_fastcgi_la_OBJECTS) $(liburweb_fastcgi_la_DEPENDENCIES) $(EXTRA_liburweb_fastcgi_la_DEPENDENCIES) 
+liburweb_fastcgi.la: $(liburweb_fastcgi_la_OBJECTS) $(liburweb_fastcgi_la_DEPENDENCIES) 
 	$(LINK) -rpath $(libdir) $(liburweb_fastcgi_la_OBJECTS) $(liburweb_fastcgi_la_LIBADD) $(LIBS)
-liburweb_http.la: $(liburweb_http_la_OBJECTS) $(liburweb_http_la_DEPENDENCIES) $(EXTRA_liburweb_http_la_DEPENDENCIES) 
+liburweb_http.la: $(liburweb_http_la_OBJECTS) $(liburweb_http_la_DEPENDENCIES) 
 	$(LINK) -rpath $(libdir) $(liburweb_http_la_OBJECTS) $(liburweb_http_la_LIBADD) $(LIBS)
-liburweb_static.la: $(liburweb_static_la_OBJECTS) $(liburweb_static_la_DEPENDENCIES) $(EXTRA_liburweb_static_la_DEPENDENCIES) 
+liburweb_static.la: $(liburweb_static_la_OBJECTS) $(liburweb_static_la_DEPENDENCIES) 
 	$(LINK) -rpath $(libdir) $(liburweb_static_la_OBJECTS) $(liburweb_static_la_LIBADD) $(LIBS)
 
 mostlyclean-compile:
@@ -473,15 +468,10 @@
 
 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
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
 mostlyclean-generic:
 
 clean-generic:
--- a/src/cgi.sml	Thu May 03 09:56:41 2012 -0400
+++ b/src/cgi.sml	Wed May 02 17:17:57 2012 -0400
@@ -32,7 +32,7 @@
 
 val () = addProtocol {name = "cgi",
                       compile = "",
-                      linkStatic = Config.lib ^ "/../liburweb_cgi.a",
+                      linkStatic = "liburweb_cgi.a",
                       linkDynamic = "-lurweb_cgi",
                       persistent = false,
                       code = fn () => box [string "void uw_global_custom() {",
--- a/src/cjr_print.sml	Thu May 03 09:56:41 2012 -0400
+++ b/src/cjr_print.sml	Wed May 02 17:17:57 2012 -0400
@@ -3238,7 +3238,7 @@
         val rfcFmt = "%a, %d %b %Y %H:%M:%S"
     in
         box [string "#include \"",
-             string (OS.Path.joinDirFile {dir = Config.includ,
+             string (OS.Path.joinDirFile {dir = !Settings.configInclude,
                                           file = "config.h"}),
              string "\"",
              newline,
@@ -3262,7 +3262,7 @@
                                                string "\"",
                                                newline]) (Settings.getHeaders ()),
              string "#include \"",
-             string (OS.Path.joinDirFile {dir = Config.includ,
+             string (OS.Path.joinDirFile {dir = !Settings.configInclude,
                                           file = "urweb.h"}),
              string "\"",
              newline,
--- a/src/compiler.sig	Thu May 03 09:56:41 2012 -0400
+++ b/src/compiler.sig	Wed May 02 17:17:57 2012 -0400
@@ -187,6 +187,7 @@
 
     val debug : bool ref
     val dumpSource : bool ref
+    val enableBoot : unit -> unit
 
     val doIflow : bool ref
 
--- a/src/compiler.sml	Thu May 03 09:56:41 2012 -0400
+++ b/src/compiler.sml	Wed May 02 17:17:57 2012 -0400
@@ -326,10 +326,25 @@
                           val compare = String.compare
                           end)
 
-val pathmap = ref (M.insert (M.empty, "", Config.libUr))
+(* XXX ezyang: pathmap gets initialized /really early/, before
+ * we do any options parsing.  So libUr will always point to the
+ * default. We override it explicitly in enableBoot *)
+val pathmap = ref (M.insert (M.empty, "", Settings.libUr ()))
 
 fun addPath (k, v) = pathmap := M.insert (!pathmap, k, v)
 
+(* XXX ezyang: this is not right; it probably doesn't work in
+ * the case of separate build and src trees *)
+fun enableBoot () =
+ (Settings.configBin := OS.Path.joinDirFile {dir = Config.builddir, file = "bin"};
+  Settings.configSrcLib := OS.Path.joinDirFile {dir = Config.builddir, file = "lib"};
+  (* joinDirFile is annoying... (ArcError; it doesn't like
+   * slashes in file) *)
+  Settings.configLib := Config.builddir ^ "/src/c/.libs";
+  Settings.configInclude := OS.Path.joinDirFile {dir = Config.builddir ^ "/include", file = "urweb"};
+  Settings.configSitelisp := Config.builddir ^ "/src/elisp";
+  addPath ("", Settings.libUr ()))
+
 fun capitalize "" = ""
   | capitalize s = str (Char.toUpper (String.sub (s, 0))) ^ String.extract (s, 1, NONE)
 
@@ -1098,16 +1113,11 @@
 
 val toParse = transform parse "parse" o toParseJob
 
-fun libFile s = OS.Path.joinDirFile {dir = Config.libUr,
-                                     file = s}
-fun clibFile s = OS.Path.joinDirFile {dir = Config.libC,
-                                      file = s}
-
 val elaborate = {
     func = fn file => let
-                  val basisF = libFile "basis.urs"
-                  val topF = libFile "top.urs"
-                  val topF' = libFile "top.ur"
+                  val basisF = Settings.libFile "basis.urs"
+                  val topF = Settings.libFile "top.urs"
+                  val topF' = Settings.libFile "top.ur"
 
                   val basis = #func parseUrs basisF
                   val topSgn = #func parseUrs topF
@@ -1389,9 +1399,9 @@
         val proto = Settings.currentProtocol ()
 
         val lib = if Settings.getStaticLinking () then
-                      #linkStatic proto ^ " " ^ Config.lib ^ "/../liburweb.a"
+                      " " ^ !Settings.configLib ^ "/" ^ #linkStatic proto ^ " " ^ !Settings.configLib ^ "/liburweb.a"
                   else
-                      "-L" ^ Config.lib ^ "/.. " ^ #linkDynamic proto ^ " -lurweb"
+                      "-L" ^ !Settings.configLib ^ " " ^ #linkDynamic proto ^ " -lurweb"
 
         val opt = if debug then
                       ""
@@ -1399,7 +1409,7 @@
                       " -O3"
 
         val compile = Config.ccompiler ^ " " ^ Config.ccArgs ^ " " ^ Config.pthreadCflags ^ " -Wimplicit -Werror -Wno-unused-value"
-                      ^ opt ^ " -I " ^ Config.includ
+                      ^ opt ^ " -I " ^ !Settings.configInclude
                       ^ " " ^ #compile proto
                       ^ " -c " ^ escapeFilename cname ^ " -o " ^ escapeFilename oname
 
--- a/src/config.sig	Thu May 03 09:56:41 2012 -0400
+++ b/src/config.sig	Wed May 02 17:17:57 2012 -0400
@@ -1,13 +1,12 @@
 signature CONFIG = sig
+    val builddir : string
+
     val bin : string
+    val srclib : string
     val lib : string
     val includ : string
     val sitelisp : string
 
-    val libUr : string
-    val libC : string
-    val libJs : string
-
     val ccompiler : string
     val ccArgs : string
     val openssl : string
--- a/src/config.sml.in	Thu May 03 09:56:41 2012 -0400
+++ b/src/config.sml.in	Wed May 02 17:17:57 2012 -0400
@@ -1,17 +1,13 @@
 structure Config :> CONFIG = struct
 
+val builddir = "@abs_top_builddir@"
+
 val bin = "@BIN@"
+val srclib = "@SRCLIB@"
 val lib = "@LIB@"
 val includ = "@INCLUDE@"
 val sitelisp = "@SITELISP@"
 
-val libUr = OS.Path.joinDirFile {dir = lib,
-                                 file = "ur"}
-val libC = OS.Path.joinDirFile {dir = lib,
-                                file = "c"}
-val libJs = OS.Path.joinDirFile {dir = lib,
-                                 file = "js"}
-
 val ccompiler = "@CC@"
 val ccArgs = "@CCARGS@"
 
--- a/src/demo.sml	Thu May 03 09:56:41 2012 -0400
+++ b/src/demo.sml	Wed May 02 17:17:57 2012 -0400
@@ -320,7 +320,7 @@
                                              val cmd = "emacs --eval \"(progn "
                                                        ^ "(global-font-lock-mode t) "
                                                        ^ "(add-to-list 'load-path \\\""
-                                                       ^ Config.sitelisp
+                                                       ^ !Settings.configSitelisp
                                                        ^ "/\\\") "
                                                        ^ "(load \\\"urweb-mode-startup\\\") "
                                                        ^ "(urweb-mode) "
--- a/src/fastcgi.sml	Thu May 03 09:56:41 2012 -0400
+++ b/src/fastcgi.sml	Wed May 02 17:17:57 2012 -0400
@@ -32,7 +32,7 @@
 
 val () = addProtocol {name = "fastcgi",
                       compile = "",
-                      linkStatic = Config.lib ^ "/../liburweb_fastcgi.a",
+                      linkStatic = "liburweb_fastcgi.a",
                       linkDynamic = "-lurweb_fastcgi",
                       persistent = true,
                       code = fn () => box [string "void uw_global_custom() {",
--- a/src/http.sml	Thu May 03 09:56:41 2012 -0400
+++ b/src/http.sml	Wed May 02 17:17:57 2012 -0400
@@ -32,7 +32,7 @@
 
 val () = addProtocol {name = "http",
                       compile = "",
-                      linkStatic = Config.lib ^ "/../liburweb_http.a",
+                      linkStatic = "liburweb_http.a",
                       linkDynamic = "-lurweb_http",
                       persistent = true,
                       code = fn () => box [string "void uw_global_custom() {",
--- a/src/jscomp.sml	Thu May 03 09:56:41 2012 -0400
+++ b/src/jscomp.sml	Wed May 02 17:17:57 2012 -0400
@@ -1306,7 +1306,7 @@
                         maxName = U.File.maxName file + 1}
                        file
 
-        val inf = TextIO.openIn (OS.Path.joinDirFile {dir = Config.libJs, file = "urweb.js"})
+        val inf = TextIO.openIn (OS.Path.joinDirFile {dir = Settings.libJs (), file = "urweb.js"})
         fun lines acc =
             case TextIO.inputLine inf of
                 NONE => String.concat (rev acc)
--- a/src/main.mlton.sml	Thu May 03 09:56:41 2012 -0400
+++ b/src/main.mlton.sml	Wed May 02 17:17:57 2012 -0400
@@ -122,6 +122,10 @@
               | "-root" :: name :: root :: rest =>
                 (Compiler.addModuleRoot (root, name);
                  doArgs rest)
+              | "-boot" :: rest =>
+                (Compiler.enableBoot ();
+                 Settings.setStaticLinking true;
+                 doArgs rest)
               | "-sigfile" :: name :: rest =>
                 (Settings.setSigFile (SOME name);
                  doArgs rest)
--- a/src/settings.sig	Thu May 03 09:56:41 2012 -0400
+++ b/src/settings.sig	Wed May 02 17:17:57 2012 -0400
@@ -27,9 +27,21 @@
 
 signature SETTINGS = sig
 
+    (* XXX these should be unit -> string too *)
+    val configBin : string ref
+    val configLib : string ref
+    val configSrcLib : string ref
+    val configInclude : string ref
+    val configSitelisp : string ref
+
+    val libUr : unit -> string
+    val libC : unit -> string
+    val libJs : unit -> string
+
     val setDebug : bool -> unit
     val getDebug : unit -> bool
 
+    val libFile : string -> string
     val clibFile : string -> string
 
     (* How do all application URLs begin? *)
--- a/src/settings.sml	Thu May 03 09:56:41 2012 -0400
+++ b/src/settings.sml	Wed May 02 17:17:57 2012 -0400
@@ -27,6 +27,22 @@
 
 structure Settings :> SETTINGS = struct
 
+val configBin = ref Config.bin
+val configLib = ref Config.lib
+val configSrcLib = ref Config.srclib
+val configInclude = ref Config.includ
+val configSitelisp = ref Config.sitelisp
+
+fun libUr () = OS.Path.joinDirFile {dir = !configSrcLib,
+                                    file = "ur"}
+fun libC () = OS.Path.joinDirFile {dir = !configSrcLib,
+                                   file = "c"}
+fun libJs () = OS.Path.joinDirFile {dir = !configSrcLib,
+                                    file = "js"}
+
+fun libFile s = OS.Path.joinDirFile {dir = libUr (),
+                                     file = s}
+
 val urlPrefixFull = ref "/"
 val urlPrefix = ref "/"
 val urlPrePrefix = ref ""
@@ -408,7 +424,7 @@
 fun addProtocol p = protocols := p :: !protocols
 fun getProtocol s = List.find (fn p => #name p = s) (!protocols)
 
-fun clibFile s = OS.Path.joinDirFile {dir = Config.libC,
+fun clibFile s = OS.Path.joinDirFile {dir = libC (),
                                       file = s}
 
 val curProto = ref {name = "",
--- a/src/static.sml	Thu May 03 09:56:41 2012 -0400
+++ b/src/static.sml	Wed May 02 17:17:57 2012 -0400
@@ -32,7 +32,7 @@
 
 val () = addProtocol {name = "static",
                       compile = "",
-                      linkStatic = Config.lib ^ "/../liburweb_static.a",
+                      linkStatic = "liburweb_static.a",
                       linkDynamic = "-lurweb_static",
                       persistent = false,
                       code = fn () => box [string "void uw_global_custom() { }",
--- a/src/tutorial.sml	Thu May 03 09:56:41 2012 -0400
+++ b/src/tutorial.sml	Wed May 02 17:17:57 2012 -0400
@@ -280,7 +280,7 @@
                                 val cmd = "emacs --eval \"(progn "
                                           ^ "(global-font-lock-mode t) "
                                           ^ "(add-to-list 'load-path \\\""
-                                          ^ Config.sitelisp
+                                          ^ !Settings.configSitelisp
                                           ^ "/\\\") "
                                           ^ "(load \\\"urweb-mode-startup\\\") "
                                           ^ "(urweb-mode) "