]> granicus.if.org Git - re2c/commitdiff
- Added re2c:cond:divider and re2c:con:goto inplace configuration.
authorhelly <helly@642ea486-5414-0410-9d7f-a0204ed87703>
Sun, 20 Jan 2008 21:25:30 +0000 (21:25 +0000)
committerhelly <helly@642ea486-5414-0410-9d7f-a0204ed87703>
Sun, 20 Jan 2008 21:25:30 +0000 (21:25 +0000)
re2c/CHANGELOG
re2c/code.cc
re2c/globals.h
re2c/htdocs/index.html
re2c/htdocs/manual.html
re2c/main.cc
re2c/test/condition_14.cgif.c [new file with mode: 0755]
re2c/test/condition_14.cgif.re [new file with mode: 0755]

index 2a0970197f020775033c0e02d47dea36f49a32b3..1c19c5086f3e7d0e28c4c7da7133d3be6eeaa9fc 100644 (file)
@@ -3,6 +3,7 @@ Version 0.13.2 (2007-??-??)
 - Added support for '=>' style rules.
 - Added support for ':=' style rules.
 - Added support for ':=>' style rules.
+- Added re2c:cond:divider and re2c:con:goto inplace configuration.
 
 Version 0.13.1 (2007-08-24)
 ---------------------------
index 64af1ab033fe04aaea971062150794bb48dd70c0..01306b0ba2c69168780d664524262984d25c8bec 100644 (file)
@@ -688,9 +688,9 @@ void Rule::emit(std::ostream &o, uint ind, bool &) const
        o << indent(ind);
        if (rule->code->autogen)
        {
-               // TODO: When an empty rule is present, we need to go there. So we need
-               // an option to generate a 'continue' rather than the 'goto' line.
-               o << "goto " << condPrefix << rule->code->newcond << ";";
+               std::string condLabel(condPrefix);
+               condLabel += rule->code->newcond->to_string();
+               o << replaceParam(condGoto, condGotoParam, condLabel);
        }
        else
        {
@@ -2138,6 +2138,14 @@ void Scanner::config(const Str& cfg, const Str& val)
        {
                condDividerParam = strVal;
        }
+       else if (cfg.to_string() == "cond:goto")
+       {
+               condGoto = strVal;
+       }
+       else if (cfg.to_string() == "cond:goto@cond")
+       {
+               condGotoParam = strVal;
+       }
        else if (cfg.to_string() == "define:YYFILL@len")
        {
                yyFillLength = strVal;
index b04b0ffe8981a214869de7c12c0e62f90f1b0e13..fd04656ddb09a03b95873280b6038e7a9ce16e30 100644 (file)
@@ -45,6 +45,8 @@ extern std::string condPrefix;
 extern std::string condEnumPrefix;
 extern std::string condDivider;
 extern std::string condDividerParam;
+extern std::string condGoto;
+extern std::string condGotoParam;
 extern std::string yychConversion;
 extern std::string yyFillLength;
 extern std::string yySetConditionParam;
index 977043dacd6837e735fa473cb676a4852d728582..ff9c17626bf775357c9147d452740124c37e93eb 100755 (executable)
@@ -84,6 +84,7 @@ fixes which were incorporated. <a href=
 <li>Added support for '=>' style rules.</li>
 <li>Added support for ':=' style rules.</li>
 <li>Added support for ':=>' style rules.</li>
+<li>Added re2c:cond:divider and re2c:con:goto inplace configuration.</li>
 <ul>
 </ul>
 <h2>2007-08-24: 0.13.1</h2>
index c263e03808d0f5fad462490be472534b422dcb06..4ce80fa532cc37beb8953c87ff67a08a43ebbd0e 100755 (executable)
@@ -421,6 +421,15 @@ using <i>re2c:cond:divider@cond</i>.</dd>
 <dt><i>re2c:cond:divider@cond</i> <b>=</b> @@ <b>;</b></dt>
 <dd>Specify the placeholder that will be replaced with the condition name
 in <i>re2c:cond:divider\fP</i>.</dd>
+<dt><i>re2c:cond:goto</i> <b>=</b> "goto @@;" <b>;</b></dt>
+<dd>Allows to customize the condition goto statements used with ':=>' style rules.
+You can use '@@' to put the name of the condition or ustomize the plaeholder
+using <i>re2c:cond:goto@cond</i>. You can also change this to 'continue;',
+which would allow you to continue with the next loop cycle including any code
+between loop start and re2c block.</dd>
+<dt><i>re2c:cond:goto@cond</i> <b>=</b> @@ <b>;</b></dt>
+<dd>Spcifies the placeholder that will be replaced with the condition label
+in <i>re2c:cond:goto</i>.</dd>
 <dt><i>re2c:indent:top</i> <b>=</b> 0 <b>;</b></dt>
 <dd>Specifies the minimum number of indendation to use. Requires a numeric
 value greater than or equal zero.</dd>
index a7c9df09a3bd7da36c50ca5620550710d578a775..9842d7e930ffd6855c0296edf600f9d69debfa2e 100644 (file)
@@ -61,6 +61,8 @@ std::string condPrefix("yyc_");
 std::string condEnumPrefix("yyc");
 std::string condDivider("/* *********************************** */");
 std::string condDividerParam("@@");
+std::string condGoto("goto @@;");
+std::string condGotoParam("@@");
 std::string yychConversion("");
 std::string yyFillLength("@@");
 std::string yySetConditionParam("@@");
diff --git a/re2c/test/condition_14.cgif.c b/re2c/test/condition_14.cgif.c
new file mode 100755 (executable)
index 0000000..8218f90
--- /dev/null
@@ -0,0 +1,441 @@
+/* Generated by re2c */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define        BSIZE   8192
+
+
+enum ScanContition {
+       EStateNormal,
+       EStateComment,
+       EStateSkiptoeol,
+       EStateString,
+};
+
+
+typedef struct Scanner
+{
+       FILE                        *fp;
+       unsigned char       *cur, *tok, *lim, *eof;
+       unsigned char       buffer[BSIZE];
+       unsigned char       yych;
+       enum ScanContition  cond;
+       int                 state;
+} Scanner;
+
+size_t fill(Scanner *s, size_t len)
+{
+       size_t got = ~0, cnt;
+
+       if (!s->eof && s->lim - s->tok < len)
+       {
+               if (s->tok > s->buffer)
+               {
+                       cnt = s->tok - s->buffer;
+                       memcpy(s->buffer, s->tok, s->lim - s->tok);
+                       s->tok -= cnt;
+                       s->cur -= cnt;
+                       s->lim -= cnt;
+                       cnt = &s->buffer[BSIZE] - s->lim;
+               }
+               else
+               {
+                       cnt = BSIZE;
+               }
+               if ((got = fread(s->lim, 1, cnt, s->fp)) != cnt)
+               {
+                       s->eof = &s->lim[got];
+               }
+               s->lim += got;
+       }
+       if (s->eof && s->cur + len > s->eof)
+       {
+               return ~0; /* not enough input data */
+       }
+       return got;
+}
+
+size_t init(Scanner *s)
+{
+       s->cur = s->tok = s->lim = s->buffer;
+       s->eof = 0;
+       s->cond = EStateNormal;
+       s->state = -1;
+
+       return fill(s, 0);
+}
+
+void fputl(const char *s, size_t len, FILE *stream)
+{
+       while(len-- > 0)
+       {
+               fputc(*s++, stream);
+       }
+}
+
+void scan(Scanner *s)
+{
+       s->tok = s->cur;
+
+       static void *yystable[] = {
+               &&yyFillLabel0,
+               &&yyFillLabel1,
+               &&yyFillLabel2,
+               &&yyFillLabel3,
+       };
+
+       if(s->state < 0) goto yy0;
+       goto *yystable[s->state];
+       for(;;)
+       {
+               s->tok = s->cur;
+
+               {
+
+                       static void *yyctable[4] = {
+                               &&yyc_Normal,
+                               &&yyc_Comment,
+                               &&yyc_Skiptoeol,
+                               &&yyc_String,
+                       };
+yy0:
+                       goto *yyctable[s->cond];
+/* *********************************** */
+yyc_Comment:
+
+                       s->state = 0;
+                       if((s->lim - s->cur) < 2) if(fill(s, 2) == ~0) break;
+yyFillLabel0:
+                       s->yych = *s->cur;
+                       if(s->yych != '*') goto yy4;
+                       ++s->cur;
+                       if((s->yych = *s->cur) == '/') goto yy5;
+yy3:
+                       continue;
+yy4:
+                       s->yych = *++s->cur;
+                       goto yy3;
+yy5:
+                       ++s->cur;
+                       s->cond = EStateNormal;
+                       continue;
+/* *********************************** */
+yyc_Normal:
+                       s->state = 1;
+                       if((s->lim - s->cur) < 4) if(fill(s, 4) == ~0) break;
+yyFillLabel1:
+                       s->yych = *s->cur;
+                       {
+                               static void *yytarget[256] = {
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy13, &&yy15, &&yy15, &&yy15, &&yy15, &&yy12,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy11,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy9,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15,
+                                       &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15
+                               };
+                               goto *yytarget[s->yych];
+                       }
+yy9:
+                       s->yych = *(s->tok = ++s->cur);
+                       if(s->yych == '?') goto yy26;
+yy10:
+                       fputc(s->cur[-1], stdout);
+                       continue;
+yy11:
+                       s->yych = *++s->cur;
+                       if(s->yych == '*') goto yy24;
+                       if(s->yych == '/') goto yy22;
+                       goto yy10;
+yy12:
+                       s->yych = *(s->tok = ++s->cur);
+                       if(s->yych == '"') goto yy16;
+                       if(s->yych == '\\') goto yy18;
+                       goto yy10;
+yy13:
+                       ++s->cur;
+                       s->cond = EStateString;
+                       fputc(s->cur[-1], stdout);
+                       continue;
+yy15:
+                       s->yych = *++s->cur;
+                       goto yy10;
+yy16:
+                       s->yych = *++s->cur;
+                       if(s->yych == '\'') goto yy20;
+yy17:
+                       s->cur = s->tok;
+                       goto yy10;
+yy18:
+                       s->yych = *++s->cur;
+                       if(s->yych != '"') goto yy17;
+                       s->yych = *++s->cur;
+                       if(s->yych != '\'') goto yy17;
+yy20:
+                       ++s->cur;
+                       fputl("'\"'", 3, stdout);
+                       continue;
+yy22:
+                       ++s->cur;
+                       s->cond = EStateSkiptoeol;
+                       continue;
+yy24:
+                       ++s->cur;
+                       s->cond = EStateComment;
+                       continue;
+yy26:
+                       s->yych = *++s->cur;
+                       {
+                               static void *yytarget[256] = {
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy41, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy39,
+                                       &&yy27, &&yy29, &&yy17, &&yy17, &&yy17, &&yy43, &&yy17, &&yy37,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy31, &&yy35, &&yy33, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17,
+                                       &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17
+                               };
+                               goto *yytarget[s->yych];
+                       }
+yy27:
+                       ++s->cur;
+                       fputc('[', stdout);
+                       continue;
+yy29:
+                       ++s->cur;
+                       fputc(']', stdout);
+                       continue;
+yy31:
+                       ++s->cur;
+                       fputc('{', stdout);
+                       continue;
+yy33:
+                       ++s->cur;
+                       fputc('}', stdout);
+                       continue;
+yy35:
+                       ++s->cur;
+                       fputc('#', stdout);
+                       continue;
+yy37:
+                       ++s->cur;
+                       fputc('\\', stdout);
+                       continue;
+yy39:
+                       ++s->cur;
+                       fputc('^', stdout);
+                       continue;
+yy41:
+                       ++s->cur;
+                       fputc('|', stdout);
+                       continue;
+yy43:
+                       ++s->cur;
+                       fputc('~', stdout);
+                       continue;
+/* *********************************** */
+yyc_Skiptoeol:
+                       s->state = 2;
+                       if((s->lim - s->cur) < 5) if(fill(s, 5) == ~0) break;
+yyFillLabel2:
+                       s->yych = *s->cur;
+                       {
+                               static void *yytarget[256] = {
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy51, &&yy53, &&yy53, &&yy50, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy47,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy49, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53,
+                                       &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53
+                               };
+                               goto *yytarget[s->yych];
+                       }
+yy47:
+                       s->yych = *(s->tok = ++s->cur);
+                       if(s->yych == '?') goto yy60;
+yy48:
+                       continue;
+yy49:
+                       s->yych = *(s->tok = ++s->cur);
+                       if(s->yych == 0x0A) goto yy58;
+                       if(s->yych == 0x0D) goto yy56;
+                       goto yy48;
+yy50:
+                       s->yych = *++s->cur;
+                       if(s->yych == 0x0A) goto yy54;
+                       goto yy48;
+yy51:
+                       ++s->cur;
+                       s->cond = EStateNormal;
+                       fputc('\n', stdout);
+                       continue;
+yy53:
+                       s->yych = *++s->cur;
+                       goto yy48;
+yy54:
+                       ++s->cur;
+                       s->cond = EStateNormal;
+                       fputc('\r', stdout);
+                       fputc('\n', stdout);
+                       continue;
+yy56:
+                       s->yych = *++s->cur;
+                       if(s->yych == 0x0A) goto yy58;
+yy57:
+                       s->cur = s->tok;
+                       goto yy48;
+yy58:
+                       ++s->cur;
+                       continue;
+yy60:
+                       s->yych = *++s->cur;
+                       if(s->yych != '/') goto yy57;
+                       s->yych = *++s->cur;
+                       if(s->yych == 0x0A) goto yy63;
+                       if(s->yych != 0x0D) goto yy57;
+                       s->yych = *++s->cur;
+                       if(s->yych != 0x0A) goto yy57;
+yy63:
+                       ++s->cur;
+                       continue;
+/* *********************************** */
+yyc_String:
+                       s->state = 3;
+                       if((s->lim - s->cur) < 2) if(fill(s, 2) == ~0) break;
+yyFillLabel3:
+                       s->yych = *s->cur;
+                       if(s->yych == '"') goto yy69;
+                       if(s->yych != '\\') goto yy71;
+                       ++s->cur;
+                       if((s->yych = *s->cur) != 0x0A) goto yy72;
+yy68:
+                       fputc(s->cur[-1], stdout);
+                       continue;
+yy69:
+                       ++s->cur;
+                       s->cond = EStateNormal;
+                       fputc(s->cur[-1], stdout);
+                       continue;
+yy71:
+                       s->yych = *++s->cur;
+                       goto yy68;
+yy72:
+                       ++s->cur;
+                       fputl((const char*)s->cur-2, 2, stdout);
+                       continue;
+               }
+
+       }
+}
+
+int main(int argc, char **argv)
+{
+       Scanner in;
+
+       if (argc != 2)
+       {
+               fprintf(stderr, "%s <file>\n", argv[0]);
+               return 1;;
+       }
+
+       memset((char*) &in, 0, sizeof(in));
+
+       if (!strcmp(argv[1], "-"))
+       {
+               in.fp = stdin;
+       }
+       else if ((in.fp = fopen(argv[1], "r")) == NULL)
+       {
+               fprintf(stderr, "Cannot open file '%s'\n", argv[1]);
+               return 1;
+       }
+
+       if (init(&in) > 0)
+       {
+               scan(&in);
+       }
+
+       if (in.fp != stdin)
+       {
+               fclose(in.fp);
+       }
+       return 0;
+}
diff --git a/re2c/test/condition_14.cgif.re b/re2c/test/condition_14.cgif.re
new file mode 100755 (executable)
index 0000000..5e9d168
--- /dev/null
@@ -0,0 +1,198 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define        BSIZE   8192
+
+/*!types:re2c */
+
+typedef struct Scanner
+{
+       FILE                        *fp;
+       unsigned char       *cur, *tok, *lim, *eof;
+       unsigned char       buffer[BSIZE];
+       unsigned char       yych;
+       enum ScanContition  cond;
+       int                 state;
+} Scanner;
+
+size_t fill(Scanner *s, size_t len)
+{
+       size_t got = ~0, cnt;
+
+       if (!s->eof && s->lim - s->tok < len)
+       {
+               if (s->tok > s->buffer)
+               {
+                       cnt = s->tok - s->buffer;
+                       memcpy(s->buffer, s->tok, s->lim - s->tok);
+                       s->tok -= cnt;
+                       s->cur -= cnt;
+                       s->lim -= cnt;
+                       cnt = &s->buffer[BSIZE] - s->lim;
+               }
+               else
+               {
+                       cnt = BSIZE;
+               }
+               if ((got = fread(s->lim, 1, cnt, s->fp)) != cnt)
+               {
+                       s->eof = &s->lim[got];
+               }
+               s->lim += got;
+       }
+       if (s->eof && s->cur + len > s->eof)
+       {
+               return ~0; /* not enough input data */
+       }
+       return got;
+}
+
+size_t init(Scanner *s)
+{
+       s->cur = s->tok = s->lim = s->buffer;
+       s->eof = 0;
+       s->cond = EStateNormal;
+       s->state = -1;
+
+       return fill(s, 0);
+}
+
+void fputl(const char *s, size_t len, FILE *stream)
+{
+       while(len-- > 0)
+       {
+               fputc(*s++, stream);
+       }
+}
+
+void scan(Scanner *s)
+{
+       s->tok = s->cur;
+/*!re2c
+re2c:define:YYGETSTATE       = "s->state";
+re2c:define:YYGETSTATE:naked = 1;
+re2c:define:YYCONDTYPE       = ScanContition;
+re2c:indent:top              = 1;
+re2c:cond:goto               = "continue;";
+*/
+/*!getstate:re2c */
+       for(;;)
+       {
+               s->tok = s->cur;
+/*!re2c
+
+re2c:define:YYCTYPE          = "unsigned char";
+re2c:define:YYCURSOR         = s->cur;
+re2c:define:YYLIMIT          = s->lim;
+re2c:define:YYMARKER         = s->tok;
+re2c:define:YYFILL@len       = #;
+re2c:define:YYFILL:naked     = 1;
+re2c:define:YYFILL           = "if(fill(s, #) == ~0) break;";
+re2c:define:YYSETSTATE@state = #;
+re2c:define:YYSETSTATE       = "s->state = #;";
+re2c:define:YYSETCONDITION       = "s->cond = #;";
+re2c:define:YYSETCONDITION@cond  = #;
+re2c:define:YYGETCONDITION       = s->cond;
+re2c:define:YYGETCONDITION:naked = 1;
+re2c:variable:yych           = s->yych;
+re2c:yych:emit               = 0;
+re2c:indent:top              = 2;
+re2c:condenumprefix          = EState;
+
+<Normal>       "??(" :=
+                       fputc('[', stdout);
+                       continue;
+<Normal>       "??)" :=
+                       fputc(']', stdout);
+                       continue;
+<Normal>       "??<" :=
+                       fputc('{', stdout);
+                       continue;
+<Normal>       "??>" :=
+                       fputc('}', stdout);
+                       continue;
+<Normal>       "??=" :=
+                       fputc('#', stdout);
+                       continue;
+<Normal>       "??/" :=
+                       fputc('\\', stdout);
+                       continue;
+<Normal>       "??'" :=
+                       fputc('^', stdout);
+                       continue;
+<Normal>       "??!" :=
+                       fputc('|', stdout);
+                       continue;
+<Normal>       "??-" :=
+                       fputc('~', stdout);
+                       continue;
+<Normal>       "/*" :=> Comment
+<Normal>       "//" :=> Skiptoeol
+<Normal>       "'\\\"'"|"'\"'" :=
+                       fputl("'\"'", 3, stdout);
+                       continue;
+<Normal>       '"' => String :=
+                       fputc(s->cur[-1], stdout);
+                       continue;
+<Normal>       [^] :=
+                       fputc(s->cur[-1], stdout);
+                       continue;
+<Comment>      "*" "/" :=> Normal
+<Comment>      [^] :=> Comment
+<Skiptoeol>    "??/" "\r"? "\n" :=> Skiptoeol
+<Skiptoeol>    "\\" "\r"? "\n" :=> Skiptoeol
+<Skiptoeol>    "\r" "\n" => Normal :=
+                       fputc('\r', stdout);
+                       fputc('\n', stdout);
+                       continue;
+<Skiptoeol>    "\n" => Normal :=
+                       fputc('\n', stdout);
+                       continue;
+<Skiptoeol>    [^] :=> Skiptoeol
+<String>       '\\' . :=
+                       fputl((const char*)s->cur-2, 2, stdout);
+                       continue;
+<String>       '"' => Normal :=
+                       fputc(s->cur[-1], stdout);
+                       continue;
+<String>       [^] :=
+                       fputc(s->cur[-1], stdout);
+                       continue;
+*/
+       }
+}
+
+int main(int argc, char **argv)
+{
+       Scanner in;
+
+       if (argc != 2)
+       {
+               fprintf(stderr, "%s <file>\n", argv[0]);
+               return 1;;
+       }
+
+       memset((char*) &in, 0, sizeof(in));
+
+       if (!strcmp(argv[1], "-"))
+       {
+               in.fp = stdin;
+       }
+       else if ((in.fp = fopen(argv[1], "r")) == NULL)
+       {
+               fprintf(stderr, "Cannot open file '%s'\n", argv[1]);
+               return 1;
+       }
+
+       if (init(&in) > 0)
+       {
+               scan(&in);
+       }
+
+       if (in.fp != stdin)
+       {
+               fclose(in.fp);
+       }
+       return 0;
+}