changeset 1089:f1647f16097d

Convenience libifying; allow more NULLs with globals
author Adam Chlipala <adamc@hcoop.net>
date Thu, 24 Dec 2009 15:49:52 -0500
parents 5f72a66402f7
children e77079953308
files doc/manual.tex src/c/urweb.c src/compiler.sig src/compiler.sml
diffstat 4 files changed, 28 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/doc/manual.tex	Thu Dec 24 10:59:35 2009 -0500
+++ b/doc/manual.tex	Thu Dec 24 15:49:52 2009 -0500
@@ -142,7 +142,7 @@
 \item \texttt{ffi FILENAME} reads the file \texttt{FILENAME.urs} to determine the interface to a new FFI module.  The name of the module is calculated from \texttt{FILENAME} in the same way as for normal source files.  See the files \texttt{include/urweb.h} and \texttt{src/c/urweb.c} for examples of C headers and implementations for FFI modules.  In general, every type or value \texttt{Module.ident} becomes \texttt{uw\_Module\_ident} in C.
 \item \texttt{header FILENAME} adds \texttt{FILENAME} to the list of files to be \texttt{\#include}d in C sources.  This is most useful for interfacing with new FFI modules.
 \item \texttt{jsFunc Module.ident=name} gives the JavaScript name of an FFI value.
-\item \texttt{library FILENAME} parses \texttt{FILENAME.urp} and merges its contents with the rest of the current file's contents.
+\item \texttt{library FILENAME} parses \texttt{FILENAME.urp} and merges its contents with the rest of the current file's contents.  If \texttt{FILENAME.urp} doesn't exist, the compiler also tries \texttt{FILENAME/lib.urp}.
 \item \texttt{link FILENAME} adds \texttt{FILENAME} to the list of files to be passed to the GCC linker at the end of compilation.  This is most useful for importing extra libraries needed by new FFI modules.
 \item \texttt{path NAME=VALUE} creates a mapping from \texttt{NAME} to \texttt{VALUE}.  This mapping may be used at the beginnings of filesystem paths given to various other configuration directives.  A path like \texttt{\$NAME/rest} is expanded to \texttt{VALUE/rest}.  There is an initial mapping from the empty name (for paths like \texttt{\$/list}) to the directory where the Ur/Web standard library is installed.  If you accept the default \texttt{configure} options, this directory is \texttt{/usr/local/lib/urweb/ur}.
 \item \texttt{prefix PREFIX} sets the prefix included before every URI within the generated application.  The default is \texttt{/}.
--- a/src/c/urweb.c	Thu Dec 24 10:59:35 2009 -0500
+++ b/src/c/urweb.c	Thu Dec 24 15:49:52 2009 -0500
@@ -468,7 +468,8 @@
     buf_free(&ctx->deltas[i].msgs);
 
   for (i = 0; i < ctx->n_globals; ++i)
-    ctx->globals[i].free(ctx->globals[i].data);
+    if (ctx->globals[i].free)
+      ctx->globals[i].free(ctx->globals[i].data);
 
   free(ctx);
 }
@@ -3177,17 +3178,15 @@
 void uw_set_global(uw_context ctx, char *name, void *data, void (*free)(void*)) {
   int i;
 
-  if (data == NULL) uw_error(ctx, FATAL, "NULL data value for global '%s'", name);
-
   for (i = 0; i < ctx->n_globals; ++i)
     if (!strcmp(name, ctx->globals[i].name)) {
-      if (ctx->globals[i].data)
+      if (ctx->globals[i].free)
         ctx->globals[i].free(ctx->globals[i].data);
       ctx->globals[i].data = data;
       ctx->globals[i].free = free;
       return;
     }
-      
+
   ++ctx->n_globals;
   ctx->globals = realloc(ctx->globals, ctx->n_globals * sizeof(global));
   ctx->globals[ctx->n_globals-1].name = name;
--- a/src/compiler.sig	Thu Dec 24 10:59:35 2009 -0500
+++ b/src/compiler.sig	Thu Dec 24 15:49:52 2009 -0500
@@ -156,4 +156,6 @@
 
     val debug : bool ref
 
+    val addPath : string * string -> unit
+
 end
--- a/src/compiler.sml	Thu Dec 24 10:59:35 2009 -0500
+++ b/src/compiler.sml	Thu Dec 24 15:49:52 2009 -0500
@@ -270,9 +270,13 @@
                           val compare = String.compare
                           end)
 
+val pathmap = ref (M.insert (M.empty, "", Config.libUr))
+
+fun addPath (k, v) = pathmap := M.insert (!pathmap, k, v)
+
 fun parseUrp' accLibs fname =
     let
-        val pathmap = ref (M.insert (M.empty, "", Config.libUr))
+        val pathmap = ref (!pathmap)
         val bigLibs = ref []
 
         fun pu filename =
@@ -304,6 +308,20 @@
                         handle OS.Path.Path => fname
                     end
 
+                fun libify path =
+                    (if Posix.FileSys.access (path ^ ".urp", []) then
+                         path
+                     else
+                         path ^ "/lib")
+                    handle SysErr => path
+
+                fun libify' path =
+                    (if Posix.FileSys.access (relify path ^ ".urp", []) then
+                         path
+                     else
+                         path ^ "/lib")
+                    handle SysErr => path
+
                 val absDir = OS.Path.mkAbsolute {path = dir, relativeTo = OS.FileSys.getDir ()}
 
                 fun relifyA fname =
@@ -559,9 +577,9 @@
                                      end
                                    | _ => ErrorMsg.error "Bad 'deny' syntax")
                               | "library" => if accLibs then
-                                                 libs := pu (relify arg) :: !libs
+                                                 libs := pu (libify (relify arg)) :: !libs
                                              else
-                                                 bigLibs := arg :: !bigLibs
+                                                 bigLibs := libify' arg :: !bigLibs
                               | "path" =>
                                 (case String.fields (fn ch => ch = #"=") arg of
                                      [n, v] => pathmap := M.insert (!pathmap, n, v)