eruby delimiters

Christian Luginbuehl <[email protected]> Mon, 16 Feb 2004 09:23:35 +0100
Newsgroups gmane.comp.apache.mod-ruby
Message-ID <[email protected]>
hi,

i've been working with mod_ruby and eruby for quite some time now and i am really impressed by it's ease of use. however i had a problem when parsing XML-files with embedded eruby code. at least libxml for ruby does not like the original delimiters. i found out, that in the file eruby_lib.c there are constants for beginning and ending delimiters to be set. but they would only work when they are 2 characters long. so i hacked the code a bit and made it work for beginning delimiters with variable length.

i'm not quite sure if this is the right place to post a patch, but i still paste it here and wait for some reaction.


=== start patch ===

--- eruby-1.0.5/eruby_lib.c	Tue Jul 29 05:42:56 2003
+++ eruby-1.0.5-h1/eruby_lib.c	Thu Jul  1 02:14:22 2004
@@ -51,8 +51,8 @@
 VALUE eruby_charset;
 VALUE eruby_default_charset;
 
-#define ERUBY_BEGIN_DELIMITER "<%"
-#define ERUBY_END_DELIMITER "%>"
+#define ERUBY_BEGIN_DELIMITER "<?ruby"
+#define ERUBY_END_DELIMITER "?>"
 #define ERUBY_EXPR_CHAR '='
 #define ERUBY_COMMENT_CHAR '#'
 #define ERUBY_LINE_BEG_CHAR '%'
@@ -498,42 +498,46 @@
     }
 
     for (;;) {
-	c = nextc(compiler);
-      again:
-	if (c == ERUBY_BEGIN_DELIMITER[0]) {
-	    c = nextc(compiler);
-	    if (c == ERUBY_BEGIN_DELIMITER[1]) {
 		c = nextc(compiler);
-		if (c == EOF) {
-		    compile_error(compiler, "missing end delimiter");
-		}
-		else if (c == ERUBY_BEGIN_DELIMITER[1]) { /* <%% => <% */
-		    if (prevc < 0) output_literal(compiler, "print \"");
-		    output(compiler, ERUBY_BEGIN_DELIMITER, 2);
-		    prevc = ERUBY_BEGIN_DELIMITER[1];
-		    continue;
-		}
-		else {
-		    if (prevc >= 0)
-			output_literal(compiler, "\"; ");
-		    if (c == ERUBY_COMMENT_CHAR) {
-			parse_embedded_program(compiler, EMBEDDED_COMMENT);
-		    }
-		    else if (c == ERUBY_EXPR_CHAR) {
-			parse_embedded_program(compiler, EMBEDDED_EXPR);
-		    }
-		    else {
-			pushback(compiler, c);
-			parse_embedded_program(compiler, EMBEDDED_STMT);
-		    }
-		    prevc = EOP;
-		}
-	    } else {
-		if (prevc < 0) output_literal(compiler, "print \"");
-		output(compiler, ERUBY_BEGIN_DELIMITER, 1);
-		prevc = ERUBY_BEGIN_DELIMITER[0];
-		goto again;
-	    }
+      again:
+		if (c == ERUBY_BEGIN_DELIMITER[0]) {
+			int is_tag = 1;
+			int i = 1;
+			while (is_tag == 1 && i < sizeof(ERUBY_BEGIN_DELIMITER)-1) {
+				c = nextc(compiler);
+				if (c == EOF) {
+				    compile_error(compiler, "missing end delimiter");
+				}
+				else if (c != ERUBY_BEGIN_DELIMITER[i]) {
+					is_tag = 0;
+				}
+				i++;
+			}
+			if (is_tag == 1) {
+		    	c = nextc(compiler);
+				if (c == EOF) {
+				    compile_error(compiler, "missing end delimiter");
+				}
+		    	if (prevc >= 0)
+					output_literal(compiler, "\"; ");
+			    if (c == ERUBY_COMMENT_CHAR) {
+					parse_embedded_program(compiler, EMBEDDED_COMMENT);
+		    	}
+			    else if (c == ERUBY_EXPR_CHAR) {
+					parse_embedded_program(compiler, EMBEDDED_EXPR);
+			    }
+		    	else {
+					pushback(compiler, c);
+					parse_embedded_program(compiler, EMBEDDED_STMT);
+			    }
+		    	prevc = EOP;
+			}
+			else {
+				if (prevc < 0) output_literal(compiler, "print \"");
+				output(compiler, ERUBY_BEGIN_DELIMITER, i-1);
+				prevc = ERUBY_BEGIN_DELIMITER[i];
+				goto again;
+			}
 	}
 	else if (c == ERUBY_LINE_BEG_CHAR && prevc == EOF) {
 	    c = nextc(compiler);

=== end patch ===

there are some remarks i have to give:
- this patch is not well tested. i just hacked the code yesterday.
- i did not quite understand the part that does transform <%% to <% (and
  simply removed it). why should this be done? is the % at the beginning
  of a line of any use (this oen i didn't touch)?
- there is no code change for the ending delimiter. if you like my patch i
  could also do that later (it just wasn't of any need for me)


bye

dinkel