summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Benjamin Barenblat <bbaren@mit.edu>2015-07-30 16:51:31 -0400
committerGravatar Benjamin Barenblat <bbaren@mit.edu>2015-07-30 16:51:31 -0400
commitaa05cf6073cf2a6dfa46108cd5522c0171a7f1c3 (patch)
tree27405b9488362c624788da7278c57afc101a300c
parentd6528405184ed3cc2a4f25b8ba86fabbc892dc59 (diff)
Make library work on both client and server sides
Replace the two-step compile/match process with a single compile-and-match one to avoid issues with server-client representation incompatibility. Use the browser regex engine on the client side.
-rw-r--r--Makefile.am1
-rw-r--r--src/lib.urp6
-rw-r--r--src/regex.ur7
-rw-r--r--src/regex.urs18
-rw-r--r--src/regex__FFI.cc35
-rw-r--r--src/regex__FFI.h9
-rw-r--r--src/regex__FFI.js42
-rw-r--r--src/regex__FFI.urs12
8 files changed, 67 insertions, 63 deletions
diff --git a/Makefile.am b/Makefile.am
index cba5a94..0a9cf20 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -48,6 +48,7 @@ liburweb_regex_la_SOURCES = src/regex__FFI.cc
liburweb_regex_la_DATA = \
src/lib.urp \
src/regex__FFI.h \
+ src/regex__FFI.js \
src/regex__FFI.urs \
src/regex.urs \
src/regex.ur
diff --git a/src/lib.urp b/src/lib.urp
index 9f95450..2dff404 100644
--- a/src/lib.urp
+++ b/src/lib.urp
@@ -1,5 +1,11 @@
ffi regex__FFI
include regex__FFI.h
link -lurweb_regex
+jsFunc Regex__FFI.succeeded=UrWeb.Regex.succeeded
+jsFunc Regex__FFI.n_subexpression_matches=UrWeb.Regex.nSubexpressionMatches
+jsFunc Regex__FFI.subexpression_match=UrWeb.Regex.subexpressionMatch
+jsFunc Regex__FFI.do_match=UrWeb.Regex.doMatch
+file /cgGvSqBi.js regex__FFI.js
+script /cgGvSqBi.js
regex \ No newline at end of file
diff --git a/src/regex.ur b/src/regex.ur
index ddc7793..cc039e2 100644
--- a/src/regex.ur
+++ b/src/regex.ur
@@ -1,4 +1,5 @@
(* Copyright 2015 the Massachusetts Institute of Technology
+Copyright 2015 Benjamin Barenblat
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
@@ -13,12 +14,6 @@ specific language governing permissions and limitations under the License. *)
structure FFI = Regex__FFI
-type t = FFI.regex
-
-val compile = FFI.compile True
-
-val compile_case_insensitive = FFI.compile False
-
fun match regex input =
(* Perform the match. *)
let
diff --git a/src/regex.urs b/src/regex.urs
index 15ce216..2591fe8 100644
--- a/src/regex.urs
+++ b/src/regex.urs
@@ -1,4 +1,5 @@
(* Copyright 2015 the Massachusetts Institute of Technology
+Copyright 2015 Benjamin Barenblat
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
@@ -56,22 +57,11 @@ Here's a brief syntax reminder:
'[[:digit:]]'. *)
-(* Creating *)
-
-(* A compiled regular expression. *)
-type t
-
-(* Compiles a regular expression from a POSIX extended regular expression
-string. *)
-val compile : string -> t
-
-(* Compiles a case-insensitive regular expression from a POSIX extended regular expression string. *)
-val compile_case_insensitive : string -> t
-
-
(* Searching *)
(* Matches a regular expression against any part of a string. Returns 'Some
strs', where 'strs' is a list of subexpression matches, if a match succeeds, and
'None' otherwise. *)
-val match : t -> string -> option (list string)
+val match : string (* needle *)
+ -> string (* haystack *)
+ -> option (list string)
diff --git a/src/regex__FFI.cc b/src/regex__FFI.cc
index 3412e51..b4a2297 100644
--- a/src/regex__FFI.cc
+++ b/src/regex__FFI.cc
@@ -1,4 +1,5 @@
// Copyright (C) 2015 the Massachusetts Institute of Technology
+// Copyright (C) 2015 Benjamin Barenblat
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
@@ -43,10 +44,6 @@ void Assert(uw_context* const context, const bool condition,
Assert(context, condition, FATAL, message);
}
-void DeleteRegex(void* regex, [[gnu::unused]] const int _will_retry) {
- delete reinterpret_cast<std::regex*>(regex);
-}
-
void DeleteMatchResults(void* match_result,
[[gnu::unused]] const int _will_retry) {
delete reinterpret_cast<std::cmatch*>(match_result);
@@ -108,23 +105,12 @@ uw_Basis_string uw_Regex__FFI_subexpression_match(
return result;
}
-uw_Regex__FFI_regex uw_Regex__FFI_compile(uw_context* const context,
- const uw_Basis_bool case_sensitive,
- const uw_Basis_string input) {
- // We'd like to stack-allocate the result--or, at least, to allocate it with
- // uw_malloc. Unfortunately, neither of those will work, because we need to
- // run a finalizer on it, and Ur finalizers can only reference addresses that
- // are not managed by Ur.
- auto* result = new std::regex;
- Assert(context, uw_register_transactional(context, result, nullptr, nullptr,
- DeleteRegex) == 0,
- "regex: could not register DeleteRegex finalizer");
- auto flags = std::regex_constants::extended;
- if (!case_sensitive) {
- flags |= std::regex_constants::icase;
- }
+uw_Regex__FFI_match uw_Regex__FFI_do_match(uw_context* const context,
+ const uw_Basis_string needle_string,
+ const uw_Basis_string haystack) {
+ std::regex needle;
try {
- result->assign(input, flags);
+ needle.assign(needle_string, std::regex_constants::extended);
} catch (const std::regex_error& e) {
switch (e.code()) {
case std::regex_constants::error_space:
@@ -136,12 +122,6 @@ uw_Regex__FFI_regex uw_Regex__FFI_compile(uw_context* const context,
uw_error(context, FATAL, "regex: compilation failed: %s", e.what());
}
}
- return result;
-}
-
-uw_Regex__FFI_match uw_Regex__FFI_do_match(uw_context* const context,
- const uw_Regex__FFI_regex needle,
- const uw_Basis_string haystack) {
uw_Regex__FFI_match result;
// Make a duplicate of the string to match against, so if it goes out of
// scope in the calling Ur code, we still have it.
@@ -158,7 +138,6 @@ uw_Regex__FFI_match uw_Regex__FFI_do_match(uw_context* const context,
"regex: could not register DeleteMatchResults finalizer");
result.result = match_results;
// Execute the regex on the saved haystack, not the original one.
- std::regex_search(result.haystack, *match_results,
- *reinterpret_cast<std::regex*>(needle));
+ std::regex_search(result.haystack, *match_results, needle);
return result;
}
diff --git a/src/regex__FFI.h b/src/regex__FFI.h
index 4cf5435..695033a 100644
--- a/src/regex__FFI.h
+++ b/src/regex__FFI.h
@@ -1,4 +1,5 @@
/* Copyright (C) 2015 the Massachusetts Institute of Technology
+Copyright (C) 2015 Benjamin Barenblat
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
@@ -24,8 +25,6 @@ extern "C" {
#include <urweb/urweb_cpp.h>
-typedef void* uw_Regex__FFI_regex;
-
typedef struct {
char* haystack;
void* result;
@@ -41,12 +40,8 @@ uw_Basis_string uw_Regex__FFI_subexpression_match(struct uw_context*,
const uw_Regex__FFI_match,
const uw_Basis_int);
-uw_Regex__FFI_regex uw_Regex__FFI_compile(struct uw_context*,
- const uw_Basis_bool,
- const uw_Basis_string);
-
uw_Regex__FFI_match uw_Regex__FFI_do_match(struct uw_context*,
- const uw_Regex__FFI_regex,
+ const uw_Basis_string,
const uw_Basis_string);
#ifdef __cplusplus
diff --git a/src/regex__FFI.js b/src/regex__FFI.js
new file mode 100644
index 0000000..fcb8927
--- /dev/null
+++ b/src/regex__FFI.js
@@ -0,0 +1,42 @@
+// Copyright © 2015 Benjamin Barenblat
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+var UrWeb = { Regex: {
+
+succeeded: function(match) {
+ return !!match;
+},
+
+nSubexpressionMatches: function(match) {
+ return match.length - 1;
+},
+
+subexpressionMatch: function(match, n) {
+ if (match.length - 1 <= n) {
+ er("regex: match does not exist");
+ }
+ return match[n + 1];
+},
+
+doMatch: function(needle_string, haystack) {
+ var needle;
+ try {
+ needle = new RegExp(needle_string);
+ } catch (e) {
+ er("regex: compilation failed");
+ }
+ return haystack.match(needle);
+},
+
+}}; // UrWeb.Regex
diff --git a/src/regex__FFI.urs b/src/regex__FFI.urs
index 690ca1d..862d4f3 100644
--- a/src/regex__FFI.urs
+++ b/src/regex__FFI.urs
@@ -1,4 +1,5 @@
(* Copyright 2015 the Massachusetts Institute of Technology
+Copyright 2015 Benjamin Barenblat
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
@@ -15,9 +16,6 @@ specific language governing permissions and limitations under the License. *)
instead. *)
-(* A compiled regular expression. *)
-type regex
-
(* Data about a match. There is no function which returns all subexpression
matches, as we can't build an Ur list in C. *)
type match
@@ -26,9 +24,7 @@ val n_subexpression_matches : match -> int
val subexpression_match : match -> int -> string
-(* Compiles a regular expression from a POSIX extended regular expression
-string. *)
-val compile : bool (* case sensitive? *) -> string -> regex
-
(* Matches a regular expression against any part of a string. *)
-val do_match : regex -> string -> match
+val do_match : string (* needle *)
+ -> string (* haystack *)
+ -> match