summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG11
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac2
-rw-r--r--doc/intro.ur7
-rw-r--r--doc/manual.tex2
-rw-r--r--src/c/http.c2
-rw-r--r--src/c/openssl.c40
-rw-r--r--src/c/urweb.c5
-rw-r--r--src/elaborate.sml12
-rw-r--r--src/settings.sml2
-rw-r--r--tests/empty.ur0
-rw-r--r--tests/ffisub.urp3
-rw-r--r--tests/ffisub.urs5
13 files changed, 81 insertions, 12 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 838da410..02e9d754 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,4 +1,15 @@
========
+20150819
+========
+
+- Allow mouse and key events for <body>
+- Add HTML 'align' attribute
+- Add onChange handler to radioOption
+- New literal [_LOC_] that is replaced with textual information on location in source file
+- Add a simple 'make test' target
+- Bug fixes and documentation improvements
+
+========
20150520
========
diff --git a/Makefile.am b/Makefile.am
index 79cd2e7d..ab11999e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -119,7 +119,7 @@ TESTDB = /tmp/urweb.db
TESTPID = /tmp/urweb.pid
test:
- urweb -dbms sqlite -db $(TESTDB) -demo /Demo demo
+ bin/urweb -boot -noEmacs -dbms sqlite -db $(TESTDB) -demo /Demo demo
rm -f $(TESTDB)
sqlite3 $(TESTDB) < demo/demo.sql
demo/demo.exe & echo $$! > $(TESTPID)
diff --git a/configure.ac b/configure.ac
index f471eef7..a6f8ac43 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT([urweb], [20150520])
+AC_INIT([urweb], [20150819])
WORKING_VERSION=1
AC_USE_SYSTEM_EXTENSIONS
diff --git a/doc/intro.ur b/doc/intro.ur
index 770b7b06..b08e2395 100644
--- a/doc/intro.ur
+++ b/doc/intro.ur
@@ -58,12 +58,15 @@ fun fact n = if n = 0 then 1 else n * fact (n - 1)
fact 5
(* end *)
-fun isEven n = n = 0 || isOdd (n - 1)
-and isOdd n = n = 1 || isEven (n - 1)
+fun isEven n = n = 0 || (n > 1 && isOdd (n - 1))
+and isOdd n = n = 1 || (n > 1 && isEven (n - 1))
(* begin eval *)
isEven 32
(* end *)
+(* begin eval *)
+isEven 31
+(* end *)
(* Of course we have anonymous functions, too. *)
diff --git a/doc/manual.tex b/doc/manual.tex
index e140fac1..5c5e5cbb 100644
--- a/doc/manual.tex
+++ b/doc/manual.tex
@@ -2314,7 +2314,7 @@ $$\begin{array}{rrcll}
&&& (E) & \textrm{explicit precedence} \\
\textrm{Nullary operators} & n &::=& \mt{CURRENT\_TIMESTAMP} \\
\textrm{Unary operators} & u &::=& \mt{NOT} \\
- \textrm{Binary operators} & b &::=& \mt{AND} \mid \mt{OR} \mid = \mid \neq \mid < \mid \leq \mid > \mid \geq \\
+ \textrm{Binary operators} & b &::=& \mt{AND} \mid \mt{OR} \mid = \mid \neq \mid < \mid \leq \mid > \mid \geq \mid \mt{LIKE} \\
\textrm{Aggregate functions} & a &::=& \mt{COUNT} \mid \mt{AVG} \mid \mt{SUM} \mid \mt{MIN} \mid \mt{MAX} \\
\textrm{Directions} & o &::=& \mt{ASC} \mid \mt{DESC} \mid \{e\} \\
\textrm{SQL integer} & N &::=& n \mid \{e\} \\
diff --git a/src/c/http.c b/src/c/http.c
index e6c7b1af..9059746f 100644
--- a/src/c/http.c
+++ b/src/c/http.c
@@ -314,7 +314,7 @@ static void *worker(void *data) {
}
static void help(char *cmd) {
- printf("Usage: %s [-p <port>] [-a <IP address>] [-t <thread count>] [-k] [-q] [-T SEC]\nThe '-k' option turns on HTTP keepalive.\nThe '-q' option turns off some chatter on stdout.\nThe -T option sets socket recv timeout (0 disables timeout, default is 5 sec)", cmd);
+ printf("Usage: %s [-p <port>] [-a <IP address>] [-t <thread count>] [-k] [-q] [-T SEC]\nThe '-k' option turns on HTTP keepalive.\nThe '-q' option turns off some chatter on stdout.\nThe '-T' option sets socket recv timeout (0 disables timeout, default is 5 sec).\n", cmd);
}
static void sigint(int signum) {
diff --git a/src/c/openssl.c b/src/c/openssl.c
index 1d820a34..6d018707 100644
--- a/src/c/openssl.c
+++ b/src/c/openssl.c
@@ -1,5 +1,6 @@
#include "config.h"
+#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
@@ -7,12 +8,17 @@
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
+#include <pthread.h>
+#include <openssl/crypto.h>
#include <openssl/sha.h>
#include <openssl/rand.h>
#define PASSSIZE 4
+// OpenSSL locks array. See threads(3SSL).
+static pthread_mutex_t *openssl_locks;
+
int uw_hash_blocksize = 32;
static int password[PASSSIZE];
@@ -27,7 +33,41 @@ static void random_password() {
}
}
+// OpenSSL callbacks
+static void thread_id(CRYPTO_THREADID *const result) {
+ CRYPTO_THREADID_set_numeric(result, pthread_self());
+}
+static void lock_or_unlock(const int mode, const int type, const char *file,
+ const int line) {
+ pthread_mutex_t *const lock = &openssl_locks[type];
+ if (mode & CRYPTO_LOCK) {
+ if (pthread_mutex_lock(lock)) {
+ fprintf(stderr, "Can't take lock at %s:%d\n", file, line);
+ exit(1);
+ }
+ } else {
+ if (pthread_mutex_unlock(lock)) {
+ fprintf(stderr, "Can't release lock at %s:%d\n", file, line);
+ exit(1);
+ }
+ }
+}
+
void uw_init_crypto() {
+ int i;
+ // Set up OpenSSL.
+ assert(openssl_locks == NULL);
+ openssl_locks = malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
+ if (!openssl_locks) {
+ perror("malloc");
+ exit(1);
+ }
+ for (i = 0; i < CRYPTO_num_locks(); ++i) {
+ pthread_mutex_init(&(openssl_locks[i]), NULL);
+ }
+ CRYPTO_THREADID_set_callback(thread_id);
+ CRYPTO_set_locking_callback(lock_or_unlock);
+ // Prepare signatures.
if (uw_sig_file) {
int fd;
diff --git a/src/c/urweb.c b/src/c/urweb.c
index faef4d3a..66fedfa2 100644
--- a/src/c/urweb.c
+++ b/src/c/urweb.c
@@ -169,13 +169,8 @@ void *uw_init_client_data();
void uw_free_client_data(void *);
void uw_copy_client_data(void *dst, void *src);
-static pthread_mutex_t rand_mutex = PTHREAD_MUTEX_INITIALIZER;
-
static uw_Basis_int my_rand() {
- pthread_mutex_lock(&rand_mutex);
int ret, r = RAND_bytes((unsigned char *)&ret, sizeof ret);
- pthread_mutex_unlock(&rand_mutex);
-
if (r)
return abs(ret);
else
diff --git a/src/elaborate.sml b/src/elaborate.sml
index 5b18ae94..ca4e124c 100644
--- a/src/elaborate.sml
+++ b/src/elaborate.sml
@@ -4123,6 +4123,18 @@ and elabDecl (dAll as (d, loc), (env, denv, gs)) =
val dNew = (L'.DFfiStr (x, n, sgn'), loc)
in
+ case #1 sgn' of
+ L'.SgnConst sgis =>
+ (case List.find (fn (L'.SgiConAbs _, _) => false
+ | (L'.SgiCon _, _) => false
+ | (L'.SgiDatatype _, _) => false
+ | (L'.SgiVal _, _) => false
+ | _ => true) sgis of
+ NONE => ()
+ | SOME sgi => (ErrorMsg.errorAt loc "Disallowed signature item for FFI module";
+ epreface ("item", p_sgn_item env sgi)))
+ | _ => raise Fail "FFI signature isn't SgnConst";
+
Option.map (fn tm => ModDb.insert (dNew, tm)) tmo;
([dNew], (env', denv, enD gs' @ gs))
end)
diff --git a/src/settings.sml b/src/settings.sml
index fc55511d..ff99bf13 100644
--- a/src/settings.sml
+++ b/src/settings.sml
@@ -887,7 +887,7 @@ fun addFile {Uri, LoadFromFilename} =
if path' = path then
()
else
- ErrorMsg.error ("Two different files requested for URI " ^ Uri)
+ ErrorMsg.error ("Two different files requested for URI " ^ Uri ^ " ( " ^ path' ^ " vs. " ^ path ^ ")")
| NONE =>
let
val inf = BinIO.openIn path
diff --git a/tests/empty.ur b/tests/empty.ur
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tests/empty.ur
diff --git a/tests/ffisub.urp b/tests/ffisub.urp
new file mode 100644
index 00000000..b695bad1
--- /dev/null
+++ b/tests/ffisub.urp
@@ -0,0 +1,3 @@
+ffi ffisub
+
+empty
diff --git a/tests/ffisub.urs b/tests/ffisub.urs
new file mode 100644
index 00000000..ce245884
--- /dev/null
+++ b/tests/ffisub.urs
@@ -0,0 +1,5 @@
+structure S : sig
+ type t
+end
+
+val x : S.t