summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/manual.tex2
-rw-r--r--src/c/urweb.c9
-rw-r--r--src/compiler.sig2
-rw-r--r--src/compiler.sml24
4 files changed, 28 insertions, 9 deletions
diff --git a/doc/manual.tex b/doc/manual.tex
index 25c5d9b6..5c197116 100644
--- a/doc/manual.tex
+++ b/doc/manual.tex
@@ -142,7 +142,7 @@ Here is the complete list of directive forms. ``FFI'' stands for ``foreign func
\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{/}.
diff --git a/src/c/urweb.c b/src/c/urweb.c
index 1f8271d5..4a0306e0 100644
--- a/src/c/urweb.c
+++ b/src/c/urweb.c
@@ -468,7 +468,8 @@ void uw_free(uw_context ctx) {
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_get_global(uw_context ctx, char *name) {
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;
diff --git a/src/compiler.sig b/src/compiler.sig
index e34b771e..fbc3011e 100644
--- a/src/compiler.sig
+++ b/src/compiler.sig
@@ -156,4 +156,6 @@ signature COMPILER = sig
val debug : bool ref
+ val addPath : string * string -> unit
+
end
diff --git a/src/compiler.sml b/src/compiler.sml
index fc764205..b793ab60 100644
--- a/src/compiler.sml
+++ b/src/compiler.sml
@@ -270,9 +270,13 @@ structure M = BinaryMapFn(struct
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 @@ fun parseUrp' accLibs fname =
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 @@ fun parseUrp' accLibs fname =
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)