# HG changeset patch # User Adam Chlipala # Date 1260287210 18000 # Node ID e8a35d710ab9958db175c128c85d3e2c31ac77b8 # Parent 6f4f8b9c50231c0306be7c8dd91715371995c820 Context globals; ctype functions diff -r 6f4f8b9c5023 -r e8a35d710ab9 include/urweb.h --- 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 diff -r 6f4f8b9c5023 -r e8a35d710ab9 lib/js/urweb.js --- 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) { diff -r 6f4f8b9c5023 -r e8a35d710ab9 lib/ur/basis.urs --- 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 diff -r 6f4f8b9c5023 -r e8a35d710ab9 lib/ur/char.ur --- /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 diff -r 6f4f8b9c5023 -r e8a35d710ab9 lib/ur/char.urs --- /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 diff -r 6f4f8b9c5023 -r e8a35d710ab9 src/c/urweb.c --- 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); +} diff -r 6f4f8b9c5023 -r e8a35d710ab9 src/compiler.sml --- 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 diff -r 6f4f8b9c5023 -r e8a35d710ab9 src/settings.sml --- 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)