changeset 1061:e8a35d710ab9

Context globals; ctype functions
author Adam Chlipala <adamc@hcoop.net>
date Tue, 08 Dec 2009 10:46:50 -0500
parents 6f4f8b9c5023
children 3bc726a822fb
files include/urweb.h lib/js/urweb.js lib/ur/basis.urs lib/ur/char.ur lib/ur/char.urs src/c/urweb.c src/compiler.sml src/settings.sml
diffstat 8 files changed, 203 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/include/urweb.h	Tue Dec 08 09:33:08 2009 -0500
+++ b/include/urweb.h	Tue Dec 08 10:46:50 2009 -0500
@@ -229,4 +229,22 @@
 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, void (*free)(void*));
+
+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);
+
 #endif
--- a/lib/js/urweb.js	Tue Dec 08 09:33:08 2009 -0500
+++ b/lib/js/urweb.js	Tue Dec 08 10:46:50 2009 -0500
@@ -23,6 +23,20 @@
 function lt(x, y) { return x < y; }
 function le(x, y) { return x <= y; }
 
+// Characters
+
+function isLower(c) { return c >= 'a' && c <= 'z'; }
+function isUpper(c) { return c >= 'A' && c <= 'Z'; }
+function isAlpha(c) { return isLower(c) || isUpper(c); }
+function isDigit(c) { return c >= '0' && c <= '9'; }
+function isAlnum(c) { return isAlpha(c) || isDigit(c); }
+function isBlank(c) { return c == ' ' || c == '\t'; }
+function isSpace(c) { return isBlank(c) || c == '\r' || c == '\n'; }
+function isXdigit(c) { return isDigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); }
+function toLower(c) { return c.toLowercase(); }
+function toUpper(c) { return c.toUppercase(); }
+
+
 // Lists
 
 function cons(v, ls) {
--- a/lib/ur/basis.urs	Tue Dec 08 09:33:08 2009 -0500
+++ b/lib/ur/basis.urs	Tue Dec 08 10:46:50 2009 -0500
@@ -52,6 +52,24 @@
 val mkOrd : t ::: Type -> {Lt : t -> t -> bool, Le : t -> t -> bool} -> ord t
 
 
+(** Character operations *)
+
+val isalnum : char -> bool
+val isalpha : char -> bool
+val isblank : char -> bool
+val iscntrl : char -> bool
+val isdigit : char -> bool
+val isgraph : char -> bool
+val islower : char -> bool
+val isprint : char -> bool
+val ispunct : char -> bool
+val isspace : char -> bool
+val isupper : char -> bool
+val isxdigit : char -> bool
+val tolower : char -> char
+val toupper : char -> char
+
+
 (** String operations *)
 
 val strlen : string -> int
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/ur/char.ur	Tue Dec 08 10:46:50 2009 -0500
@@ -0,0 +1,16 @@
+type t = char
+
+val isAlnum = Basis.isalnum
+val isAlpha = Basis.isalpha
+val isBlank = Basis.isblank
+val isCntrl = Basis.iscntrl
+val isDigit = Basis.isdigit
+val isGraph = Basis.isgraph
+val isLower = Basis.islower
+val isPrint = Basis.isprint
+val isPunct = Basis.ispunct
+val isSpace = Basis.isspace
+val isUpper = Basis.isupper
+val isXdigit = Basis.isxdigit
+val toLower = Basis.tolower
+val toUpper = Basis.toupper
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/ur/char.urs	Tue Dec 08 10:46:50 2009 -0500
@@ -0,0 +1,16 @@
+type t = char
+
+val isAlnum : t -> bool
+val isAlpha : t -> bool
+val isBlank : t -> bool
+val isCntrl : t -> bool
+val isDigit : t -> bool
+val isGraph : t -> bool
+val isLower : t -> bool
+val isPrint : t -> bool
+val isPunct : t -> bool
+val isSpace : t -> bool
+val isUpper : t -> bool
+val isXdigit : t -> bool
+val toLower : t -> t
+val toUpper : t -> t
--- a/src/c/urweb.c	Tue Dec 08 09:33:08 2009 -0500
+++ b/src/c/urweb.c	Tue Dec 08 10:46:50 2009 -0500
@@ -341,6 +341,12 @@
   uw_callback commit, rollback, free;
 } transactional;
 
+typedef struct {
+  char *name;
+  void *data;
+  void (*free)(void*);
+} global;
+
 struct uw_context {
   char *(*get_header)(void *, const char *);
   void *get_header_data;
@@ -374,6 +380,9 @@
   transactional *transactionals;
   size_t n_transactionals, used_transactionals;
 
+  global *globals;
+  size_t n_globals;
+
   char error_message[ERROR_BUF_LEN];
 };
 
@@ -424,6 +433,9 @@
   ctx->transactionals = malloc(0);
   ctx->n_transactionals = ctx->used_transactionals = 0;
 
+  ctx->globals = malloc(0);
+  ctx->n_globals = 0;
+
   return ctx;
 }
 
@@ -450,6 +462,9 @@
   for (i = 0; i < ctx->n_deltas; ++i)
     buf_free(&ctx->deltas[i].msgs);
 
+  for (i = 0; i < ctx->n_globals; ++i)
+    ctx->globals[i].free(ctx->globals[i].data);
+
   free(ctx);
 }
 
@@ -3092,3 +3107,89 @@
 uw_Basis_time uw_Basis_now(uw_context ctx) {
   return time(NULL);
 }
+
+void *uw_get_global(uw_context ctx, char *name) {
+  int i;
+
+  for (i = 0; i < ctx->n_globals; ++i)
+    if (!strcmp(name, ctx->globals[i].name))
+      return ctx->globals[i].data;
+
+  return NULL;
+}
+
+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)
+        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;
+  ctx->globals[ctx->n_globals-1].data = data;
+  ctx->globals[ctx->n_globals-1].free = free;
+}
+
+uw_Basis_bool uw_Basis_isalnum(uw_context ctx, uw_Basis_char c) {
+  return isalnum(c);
+}
+
+uw_Basis_bool uw_Basis_isalpha(uw_context ctx, uw_Basis_char c) {
+  return isalpha(c);
+}
+
+uw_Basis_bool uw_Basis_isblank(uw_context ctx, uw_Basis_char c) {
+  return isblank(c);
+}
+
+uw_Basis_bool uw_Basis_iscntrl(uw_context ctx, uw_Basis_char c) {
+  return iscntrl(c);
+}
+
+uw_Basis_bool uw_Basis_isdigit(uw_context ctx, uw_Basis_char c) {
+  return isdigit(c);
+}
+
+uw_Basis_bool uw_Basis_isgraph(uw_context ctx, uw_Basis_char c) {
+  return isgraph(c);
+}
+
+uw_Basis_bool uw_Basis_islower(uw_context ctx, uw_Basis_char c) {
+  return islower(c);
+}
+
+uw_Basis_bool uw_Basis_isprint(uw_context ctx, uw_Basis_char c) {
+  return isprint(c);
+}
+
+uw_Basis_bool uw_Basis_ispunct(uw_context ctx, uw_Basis_char c) {
+  return ispunct(c);
+}
+
+uw_Basis_bool uw_Basis_isspace(uw_context ctx, uw_Basis_char c) {
+  return isspace(c);
+}
+uw_Basis_bool uw_Basis_isupper(uw_context ctx, uw_Basis_char c) {
+  return isupper(c);
+}
+
+uw_Basis_bool uw_Basis_isxdigit(uw_context ctx, uw_Basis_char c) {
+  return isxdigit(c);
+}
+
+uw_Basis_char uw_Basis_tolower(uw_context ctx, uw_Basis_char c) {
+  return tolower(c);
+}
+
+uw_Basis_char uw_Basis_toupper(uw_context ctx, uw_Basis_char c) {
+  return toupper(c);
+}
--- a/src/compiler.sml	Tue Dec 08 09:33:08 2009 -0500
+++ b/src/compiler.sml	Tue Dec 08 10:46:50 2009 -0500
@@ -508,7 +508,14 @@
                                    | SOME _ => ErrorMsg.error "Duplicate 'timeout' directive";
                                  timeout := SOME (valOf (Int.fromString arg)))
                               | "ffi" => ffi := relify arg :: !ffi
-                              | "link" => link := relifyA arg :: !link
+                              | "link" => let
+                                    val arg = if size arg >= 2 andalso String.substring (arg, 0, 2) = "-l" then
+                                                  arg
+                                              else
+                                                  relifyA arg
+                                in
+                                    link := arg :: !link
+                                end
                               | "include" => headers := relifyA arg :: !headers
                               | "script" => scripts := arg :: !scripts
                               | "clientToServer" => clientToServer := ffiS () :: !clientToServer
--- a/src/settings.sml	Tue Dec 08 09:33:08 2009 -0500
+++ b/src/settings.sml	Tue Dec 08 10:46:50 2009 -0500
@@ -168,7 +168,18 @@
                           ("strchr", "schr"),
                           ("substring", "ssub"),
                           ("strcspn", "sspn"),
-                          ("kc", "kc")]
+                          ("kc", "kc"),
+
+                          ("islower", "isLower"),
+                          ("isupper", "isUpper"),
+                          ("isalpha", "isAlpha"),
+                          ("isdigit", "isDigit"),
+                          ("isalnum", "isAlnum"),
+                          ("isblank", "isBlank"),
+                          ("isspace", "isSpace"),
+                          ("isxdigit", "isXdigit"),
+                          ("tolower", "toLower"),
+                          ("toupper", "toUpper")]
 val jsFuncs = ref jsFuncsBase
 fun setJsFuncs ls = jsFuncs := foldl (fn ((k, v), m) => M.insert (m, k, v)) jsFuncsBase ls
 fun jsFunc x = M.find (!jsFuncs, x)