shithub: libmujs

Download patch

ref: a476ffcc12421c576ed0658f0050a511adfc208f
parent: 33c60e4d7b9d598543fe19347bc3f6ef23ccb288
author: Tor Andersson <tor.andersson@artifex.com>
date: Sat Jan 11 07:47:08 EST 2014

Preserve regexp flags. Escape more characters when dumping strings.

--- a/js.h
+++ b/js.h
@@ -13,6 +13,10 @@
 typedef struct js_StringNode js_StringNode;
 typedef struct js_Ast js_Ast;
 
+#define JS_REGEXP_G 1
+#define JS_REGEXP_I 2
+#define JS_REGEXP_M 4
+
 typedef int (*js_CFunction)(js_State *J);
 
 js_State *js_newstate(void);
--- a/jsdump.c
+++ b/jsdump.c
@@ -92,17 +92,29 @@
 
 static void pstr(const char *s)
 {
+	int c;
 	pc('"');
-	while (*s) {
-		if (*s == '"')
-			ps("\\\"");
-		else
-			pc(*s);
-		++s;
+	while ((c = *s++)) {
+		switch (c) {
+		case '"': ps("\\\""); break;
+		case '\\': ps("\\\\"); break;
+		case '\n': ps("\\n"); break;
+		default: pc(c); break;
+		}
 	}
 	pc('"');
 }
 
+static void pregexp(const char *prog, int flags)
+{
+	pc('/');
+	ps(prog);
+	pc('/');
+	if (flags & JS_REGEXP_G) pc('g');
+	if (flags & JS_REGEXP_I) pc('i');
+	if (flags & JS_REGEXP_M) pc('m');
+}
+
 static void pbin(int d, int i, js_Ast *exp, const char *op)
 {
 	if (i) pc('(');
@@ -127,7 +139,7 @@
 	case AST_IDENTIFIER: ps(exp->string); break;
 	case AST_NUMBER: printf("%.9g", exp->number); break;
 	case AST_STRING: pstr(exp->string); break;
-	case AST_REGEXP: pc('/'); ps(exp->string); pc('/'); break;
+	case AST_REGEXP: pregexp(exp->string, exp->number); break;
 
 	case EXP_NULL: ps("null"); break;
 	case EXP_TRUE: ps("true"); break;
@@ -516,7 +528,7 @@
 	switch (node->type) {
 	case AST_IDENTIFIER: pc(' '); ps(node->string); break;
 	case AST_STRING: pc(' '); pstr(node->string); break;
-	case AST_REGEXP: printf(" /%s/", node->string); break;
+	case AST_REGEXP: pc(' '); pregexp(node->string, node->number); break;
 	case AST_NUMBER: printf(" %.9g", node->number); break;
 	case STM_BLOCK: afun = sblock; break;
 	case STM_FUNC: case EXP_FUNC: cfun = sblock; break;
--- a/jslex.c
+++ b/jslex.c
@@ -361,6 +361,7 @@
 static int lexregexp(js_State *J, const char **sp)
 {
 	const char *s;
+	int g, m, i;
 	int c;
 
 	textinit(J);
@@ -386,21 +387,25 @@
 	s = textend(J);
 
 	/* regexp flags */
-	J->flags.g = J->flags.i = J->flags.m = 0;
+	g = i = m = 0;
 
 	c = PEEK();
 	while (isidentifierpart(c)) {
-		if (c == 'g') J->flags.g ++;
-		else if (c == 'i') J->flags.i ++;
-		else if (c == 'm') J->flags.m ++;
+		if (c == 'g') ++g;
+		else if (c == 'i') ++i;
+		else if (c == 'm') ++m;
 		else return jsP_error(J, "illegal flag in regular expression: %c", c);
 		c = NEXTPEEK();
 	}
 
-	if (J->flags.g > 1 || J->flags.i > 1 || J->flags.m > 1)
+	if (g > 1 || i > 1 || m > 1)
 		return jsP_error(J, "duplicated flag in regular expression");
 
 	J->text = js_intern(J, s);
+	J->number = 0;
+	if (g) J->number += JS_REGEXP_G;
+	if (i) J->number += JS_REGEXP_I;
+	if (m) J->number += JS_REGEXP_M;
 	return TK_REGEXP;
 }
 
--- a/jsparse.c
+++ b/jsparse.c
@@ -227,7 +227,7 @@
 	}
 	if (J->lookahead == TK_REGEXP) {
 		a = jsP_newstrnode(J, AST_REGEXP, J->text);
-		// TODO: flags
+		a->number = J->number;
 		next(J);
 		return a;
 	}
--- a/jsstate.h
+++ b/jsstate.h
@@ -21,7 +21,6 @@
 	int lookahead;
 	const char *text;
 	double number;
-	struct { char g, i, m; } flags;
 	js_Ast *ast; /* list of allocated nodes to free after parsing */
 
 	int strict;