Пример #1
0
 private static CharPtr scanformat(LuaState L, CharPtr strfrmt, CharPtr form)
 {
     var p = strfrmt;
     while (p[0] != '\0' && strchr(FLAGS, p[0]) != null) p = p.next(); /* skip flags */
     if ((uint) (p - strfrmt) >= (FLAGS.Length + 1))
         LuaLError(L, "invalid format (repeated flags)");
     if (isdigit((byte) (p[0]))) p = p.next(); /* skip width */
     if (isdigit((byte) (p[0]))) p = p.next(); /* (2 digits at most) */
     if (p[0] == '.')
     {
         p = p.next();
         if (isdigit((byte) (p[0]))) p = p.next(); /* skip precision */
         if (isdigit((byte) (p[0]))) p = p.next(); /* (2 digits at most) */
     }
     if (isdigit((byte) (p[0])))
         LuaLError(L, "invalid format (width or precision too long)");
     form[0] = '%';
     form = form.next();
     strncpy(form, strfrmt, p - strfrmt + 1);
     form += p - strfrmt + 1;
     form[0] = '\0';
     return p;
 }
Пример #2
0
 private static CharPtr match(MatchState ms, CharPtr s, CharPtr p)
 {
     s = new CharPtr(s);
     p = new CharPtr(p);
     if (ms.matchdepth-- == 0)
         LuaLError(ms.L, "pattern too complex");
     init: /* using goto's to optimize tail recursion */
     switch (p[0])
     {
         case '(':
         {
             /* start capture */
             if (p[1] == ')') /* position capture? */
                 return start_capture(ms, s, p + 2, CAP_POSITION);
             return start_capture(ms, s, p + 1, CAP_UNFINISHED);
         }
         case ')':
         {
             /* end capture */
             return end_capture(ms, s, p + 1);
         }
         case L_ESC:
         {
             switch (p[1])
             {
                 case 'b':
                 {
                     /* balanced string? */
                     s = matchbalance(ms, s, p + 2);
                     if (s == null) return null;
                     p += 4;
                     goto init; /* else return match(ms, s, p+4); */
                 }
                 case 'f':
                 {
                     /* frontier? */
                     CharPtr ep;
                     char previous;
                     p += 2;
                     if (p[0] != '[')
                         LuaLError(ms.L, "missing " + LUA_QL("[") + " after " +
                                         LUA_QL("%f") + " in pattern");
                     ep = classend(ms, p); /* points to what is next */
                     previous = (s == ms.src_init) ? '\0' : s[-1];
                     if ((matchbracketclass((byte) (previous), p, ep - 1) != 0) ||
                         (matchbracketclass((byte) (s[0]), p, ep - 1) == 0)) return null;
                     p = ep;
                     goto init; /* else return match(ms, s, ep); */
                 }
                 default:
                 {
                     if (isdigit(p[1]))
                     {
                         /* capture results (%0-%9)? */
                         s = match_capture(ms, s, (byte) (p[1]));
                         if (s == null) return null;
                         p += 2;
                         goto init; /* else return match(ms, s, p+2) */
                     }
                     //ismeretlen hiba miatt lett ide átmásolva
                     {
                         /* it is a pattern item */
                         var ep = classend(ms, p); /* points to what is next */
                         var m = (s < ms.src_end) && (singlematch((byte) (s[0]), p, ep) != 0) ? 1 : 0;
                         switch (ep[0])
                         {
                             case '?':
                             {
                                 /* optional */
                                 CharPtr res;
                                 if ((m != 0) && ((res = match(ms, s + 1, ep + 1)) != null))
                                     return res;
                                 p = ep + 1;
                                 goto init; /* else return match(ms, s, ep+1); */
                             }
                             case '*':
                             {
                                 /* 0 or more repetitions */
                                 return max_expand(ms, s, p, ep);
                             }
                             case '+':
                             {
                                 /* 1 or more repetitions */
                                 return ((m != 0) ? max_expand(ms, s + 1, p, ep) : null);
                             }
                             case '-':
                             {
                                 /* 0 or more repetitions (minimum) */
                                 return min_expand(ms, s, p, ep);
                             }
                             default:
                             {
                                 if (m == 0) return null;
                                 s = s.next();
                                 p = ep;
                                 goto init; /* else return match(ms, s+1, ep); */
                             }
                         }
                     }
                     //goto dflt;  /* case default */
                 }
             }
         }
         case '\0':
         {
             /* end of pattern */
             return s; /* match succeeded */
         }
         case '$':
         {
             if (p[1] == '\0') /* is the `$' the last char in pattern? */
                 return (s == ms.src_end) ? s : null; /* check end of string */
             goto dflt;
         }
         default:
             dflt:
         {
             /* it is a pattern item */
             var ep = classend(ms, p); /* points to what is next */
             var m = (s < ms.src_end) && (singlematch((byte) (s[0]), p, ep) != 0) ? 1 : 0;
             switch (ep[0])
             {
                 case '?':
                 {
                     /* optional */
                     CharPtr res;
                     if ((m != 0) && ((res = match(ms, s + 1, ep + 1)) != null))
                         return res;
                     p = ep + 1;
                     goto init; /* else return match(ms, s, ep+1); */
                 }
                 case '*':
                 {
                     /* 0 or more repetitions */
                     return max_expand(ms, s, p, ep);
                 }
                 case '+':
                 {
                     /* 1 or more repetitions */
                     return ((m != 0) ? max_expand(ms, s + 1, p, ep) : null);
                 }
                 case '-':
                 {
                     /* 0 or more repetitions (minimum) */
                     return min_expand(ms, s, p, ep);
                 }
                 default:
                 {
                     if (m == 0) return null;
                     s = s.next();
                     p = ep;
                     goto init; /* else return match(ms, s+1, ep); */
                 }
             }
         }
     }
 }
Пример #3
0
 private static CharPtr min_expand(MatchState ms, CharPtr s,
     CharPtr p, CharPtr ep)
 {
     for (;;)
     {
         var res = match(ms, s, ep + 1);
         if (res != null)
             return res;
         if ((s < ms.src_end) && (singlematch((byte) (s[0]), p, ep) != 0))
             s = s.next(); /* try with one more repetition */
         else return null;
     }
 }
Пример #4
0
 private static CharPtr matchbalance(MatchState ms, CharPtr s,
     CharPtr p)
 {
     if ((p[0] == 0) || (p[1] == 0))
         LuaLError(ms.L, "unbalanced pattern");
     if (s[0] != p[0]) return null;
     int b = p[0];
     int e = p[1];
     var cont = 1;
     while ((s = s.next()) < ms.src_end)
     {
         if (s[0] == e)
         {
             if (--cont == 0) return s + 1;
         }
         else if (s[0] == b) cont++;
     }
     return null; /* string ends out of balance */
 }
Пример #5
0
 private static int matchbracketclass(int c, CharPtr p, CharPtr ec)
 {
     var sig = 1;
     if (p[1] == '^')
     {
         sig = 0;
         p = p.next(); /* skip the `^' */
     }
     while ((p = p.next()) < ec)
     {
         if (p == L_ESC)
         {
             p = p.next();
             if (match_class((char) c, p[0]) != 0)
                 return sig;
         }
         else if ((p[1] == '-') && (p + 2 < ec))
         {
             p += 2;
             if ((byte) ((p[-2])) <= c && (c <= (byte) p[0]))
                 return sig;
         }
         else if ((byte) (p[0]) == c) return sig;
     }
     return (sig == 0) ? 1 : 0;
 }
Пример #6
0
 private static CharPtr classend(MatchState ms, CharPtr p)
 {
     p = new CharPtr(p);
     var c = p[0];
     p = p.next();
     switch (c)
     {
         case L_ESC:
         {
             if (p[0] == '\0')
                 LuaLError(ms.L, "malformed pattern (ends with " + LUA_QL("%") + ")");
             return p + 1;
         }
         case '[':
         {
             if (p[0] == '^') p = p.next();
             do
             {
                 /* look for a `]' */
                 if (p[0] == '\0')
                     LuaLError(ms.L, "malformed pattern (missing " + LUA_QL("]") + ")");
                 c = p[0];
                 p = p.next();
                 if (c == L_ESC && p[0] != '\0')
                     p = p.next(); /* skip escapes (e.g. `%]') */
             } while (p[0] != ']');
             return p + 1;
         }
         default:
         {
             return p;
         }
     }
 }