示例#1
0
        private static int auxgetinfo(lua_State L, CharPtr what, lua_Debug ar,
                                      Closure f, CallInfo ci)
        {
            int status = 1;

            if (f == null)
            {
                info_tailcall(ar);
                return(status);
            }
            for (; what[0] != 0; what = what.next())
            {
                switch (what[0])
                {
                case 'S': {
                    funcinfo(ar, f);
                    break;
                }

                case 'l': {
                    ar.currentline = (ci != null) ? currentline(L, ci) : -1;
                    break;
                }

                case 'u': {
                    ar.nups = f.c.nupvalues;
                    break;
                }

                case 'n': {
                    ar.namewhat = (ci != null) ? getfuncname(L, ci, ref ar.name) : null;
                    if (ar.namewhat == null)
                    {
                        ar.namewhat = "";            /* not found */
                        ar.name     = null;
                    }
                    break;
                }

                case 'L':
                case 'f':            /* handled by lua_getinfo */
                    break;

                default: status = 0;  break;          /* invalid option */
                }
            }
            return(status);
        }
示例#2
0
 public static void luaO_chunkid(CharPtr out_, CharPtr source, uint bufflen)
 {
     //out_ = "";
     if (source[0] == '=')
     {
         strncpy(out_, source + 1, (int)bufflen); /* remove first char */
         out_[bufflen - 1] = '\0';                /* ensures null termination */
     }
     else
     {  /* out = "source", or "...source" */
         if (source[0] == '@')
         {
             uint l;
             source   = source.next(); /* skip the `@' */
             bufflen -= (uint)(" '...' ".Length + 1);
             l        = (uint)strlen(source);
             strcpy(out_, "");
             if (l > bufflen)
             {
                 source += (l - bufflen);  /* get last part of file name */
                 strcat(out_, "...");
             }
             strcat(out_, source);
         }
         else
         {                                       /* out = [string "string"] */
             uint len = strcspn(source, "\n\r"); /* stop at first newline */
             bufflen -= (uint)(" [string \"...\"] ".Length + 1);
             if (len > bufflen)
             {
                 len = bufflen;
             }
             strcpy(out_, "[string \"");
             if (source[len] != '\0')
             {  /* must truncate? */
                 strncat(out_, source, (int)len);
                 strcat(out_, "...");
             }
             else
             {
                 strcat(out_, source);
             }
             strcat(out_, "\"]");
         }
     }
 }
示例#3
0
        private static CharPtr scanformat(LuaState L, CharPtr strfrmt, CharPtr form)
        {
            CharPtr p = strfrmt;

            while (p[0] != '\0' && strchr(FLAGS, p[0]) != null)
            {
                p = p.next();                                                  /* skip flags */
            }
            if ((uint)(p - strfrmt) >= (FLAGS.Length + 1))
            {
                luaL_error(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])))
            {
                luaL_error(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);
        }
示例#4
0
 private static CharPtr min_expand(MatchState ms, CharPtr s,
                                   CharPtr p, CharPtr ep)
 {
     for (;;)
     {
         CharPtr res = match(ms, s, ep + 1);
         if (res != null)
         {
             return(res);
         }
         else if ((s < ms.src_end) && (singlematch((byte)(s[0]), p, ep) != 0))
         {
             s = s.next();  /* try with one more repetition */
         }
         else
         {
             return(null);
         }
     }
 }
示例#5
0
        public static int lua_getinfo(lua_State L, CharPtr what, lua_Debug ar)
        {
            int      status;
            Closure  f  = null;
            CallInfo ci = null;

            lua_lock(L);
            if (what == '>')
            {
                StkId func = L.top - 1;
                luai_apicheck(L, ttisfunction(func));
                what = what.next();         /* skip the '>' */
                f    = clvalue(func);
                StkId.dec(ref L.top);       /* pop function */
            }
            else if (ar.i_ci != 0)          /* no tail call? */
            {
                ci = L.base_ci[ar.i_ci];
                lua_assert(ttisfunction(ci.func));
                f = clvalue(ci.func);
            }
            status = auxgetinfo(L, what, ar, f, ci);
            if (strchr(what, 'f') != null)
            {
                if (f == null)
                {
                    setnilvalue(L.top);
                }
                else
                {
                    setclvalue(L, L.top, f);
                }
                incr_top(L);
            }
            if (strchr(what, 'L') != null)
            {
                collectvalidlines(L, f);
            }
            lua_unlock(L);
            return(status);
        }
示例#6
0
        private static void addquoted(LuaState L, luaL_Buffer b, int arg)
        {
            uint    l;
            CharPtr s = luaL_checklstring(L, arg, out l);

            luaL_addchar(b, '"');
            while ((l--) != 0)
            {
                switch (s[0])
                {
                case '"':
                case '\\':
                case '\n': {
                    luaL_addchar(b, '\\');
                    luaL_addchar(b, s[0]);
                    break;
                }

                case '\r': {
                    luaL_addlstring(b, "\\r", 2);
                    break;
                }

                case '\0': {
                    luaL_addlstring(b, "\\000", 4);
                    break;
                }

                default: {
                    luaL_addchar(b, s[0]);
                    break;
                }
                }
                s = s.next();
            }
            luaL_addchar(b, '"');
        }
示例#7
0
        private static int str_find_aux(LuaState L, int find)
        {
            uint      l1, l2;
            CharPtr   s    = luaL_checklstring(L, 1, out l1);
            CharPtr   p    = luaL_checklstring(L, 2, out l2);
            ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1;

            if (init < 0)
            {
                init = 0;
            }
            else if ((uint)(init) > l1)
            {
                init = (ptrdiff_t)l1;
            }
            if ((find != 0) && ((lua_toboolean(L, 4) != 0) ||  /* explicit request? */
                                strpbrk(p, SPECIALS) == null)) /* or no special characters? */
            /* do a plain search */
            {
                CharPtr s2 = lmemfind(s + init, (uint)(l1 - init), p, (uint)(l2));
                if (s2 != null)
                {
                    lua_pushinteger(L, s2 - s + 1);
                    lua_pushinteger(L, (int)(s2 - s + l2));
                    return(2);
                }
            }
            else
            {
                MatchState ms     = new MatchState();
                int        anchor = 0;
                if (p[0] == '^')
                {
                    p      = p.next();
                    anchor = 1;
                }
                CharPtr s1 = s + init;
                ms.L        = L;
                ms.src_init = s;
                ms.src_end  = s + l1;
                do
                {
                    CharPtr res;
                    ms.level = 0;
                    if ((res = match(ms, s1, p)) != null)
                    {
                        if (find != 0)
                        {
                            lua_pushinteger(L, s1 - s + 1); /* start */
                            lua_pushinteger(L, res - s);    /* end */
                            return(push_captures(ms, null, null) + 2);
                        }
                        else
                        {
                            return(push_captures(ms, s1, res));
                        }
                    }
                } while (((s1 = s1.next()) <= ms.src_end) && (anchor == 0));
            }
            lua_pushnil(L);  /* not found */
            return(1);
        }
示例#8
0
        private static CharPtr match(MatchState ms, CharPtr s, CharPtr p)
        {
            s = new CharPtr(s);
            p = new CharPtr(p);
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));
                }
                else
                {
                    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] != '[')
                    {
                        luaL_error(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((byte)(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) */
                    }
                    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 */
                }
                else
                {
                    goto dflt;
                }
            }

            default: dflt : {                     /* it is a pattern item */
                    CharPtr ep = classend(ms, p); /* points to what is next */
                    int     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); */
                    }
                    }
            }
            }
        }
示例#9
0
        private static int str_find_aux(LuaState L, int find)
        {
            uint    l1, l2;
            CharPtr s = LuaLCheckLString(L, 1, out l1);
            CharPtr p = PatchPattern(LuaLCheckLString(L, 2, out l2));

            int init = posrelat(LuaLOptInteger(L, 3, 1), l1) - 1;

            if (init < 0)
            {
                init = 0;
            }
            else if ((uint)(init) > l1)
            {
                init = (int)l1;
            }

            if ((find != 0) && ((LuaToBoolean(L, 4) != 0) || /* explicit request? */
                                strpbrk(p, SPECIALS) == null))
            {
                /* or no special characters? */
                /* do a plain search */
                var s2 = lmemfind(s + init, (uint)(l1 - init), p, l2);
                if (s2 != null)
                {
                    LuaPushInteger(L, s2 - s + 1);
                    LuaPushInteger(L, (int)(s2 - s + l2));
                    return(2);
                }
            }
            else
            {
                var ms     = new MatchState();
                int anchor = 0;
                if (p[0] == '^')
                {
                    p      = p.next();
                    anchor = 1;
                }

                var s1 = s + init;
                ms.L          = L;
                ms.matchdepth = MAXCCALLS;
                ms.src_init   = s;
                ms.src_end    = s + l1;
                do
                {
                    CharPtr res;
                    ms.level = 0;
                    // LuaAssert(ms.matchdepth == MAXCCALLS);
                    ms.matchdepth = MAXCCALLS;
                    if ((res = match(ms, s1, p)) != null)
                    {
                        if (find != 0)
                        {
                            LuaPushInteger(L, s1 - s + 1); /* start */
                            LuaPushInteger(L, res - s);    /* end */
                            return(push_captures(ms, null, null) + 2);
                        }

                        return(push_captures(ms, s1, res));
                    }
                } while (((s1 = s1.next()) <= ms.src_end) && (anchor == 0));
            }

            LuaPushNil(L); /* not found */
            return(1);
        }
示例#10
0
        private static int str_format(LuaState L)
        {
            int         top = lua_gettop(L);
            int         arg = 1;
            uint        sfl;
            CharPtr     strfrmt     = luaL_checklstring(L, arg, out sfl);
            CharPtr     strfrmt_end = strfrmt + sfl;
            luaL_Buffer b           = new luaL_Buffer();

            luaL_buffinit(L, b);
            while (strfrmt < strfrmt_end)
            {
                if (strfrmt[0] != L_ESC)
                {
                    luaL_addchar(b, strfrmt[0]);
                    strfrmt = strfrmt.next();
                }
                else if (strfrmt[1] == L_ESC)
                {
                    luaL_addchar(b, strfrmt[0]);  /* %% */
                    strfrmt = strfrmt + 2;
                }
                else
                {                                        /* format item */
                    strfrmt = strfrmt.next();
                    CharPtr form = new char[MAX_FORMAT]; /* to store the format (`%...') */
                    CharPtr buff = new char[MAX_ITEM];   /* to store the formatted item */
                    if (++arg > top)
                    {
                        luaL_argerror(L, arg, "no value");
                    }

                    strfrmt = scanformat(L, strfrmt, form);
                    char ch = strfrmt[0];
                    strfrmt = strfrmt.next();
                    switch (ch)
                    {
                    case 'c':
                    {
                        sprintf(buff, form, (int)luaL_checknumber(L, arg));
                        break;
                    }

                    case 'd':
                    case 'i':
                    {
                        addintlen(form);
                        sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg));
                        break;
                    }

                    case 'o':
                    case 'u':
                    case 'x':
                    case 'X':
                    {
                        addintlen(form);
                        sprintf(buff, form, (UNSIGNED_LUA_INTFRM_T)luaL_checknumber(L, arg));
                        break;
                    }

                    case 'e':
                    case 'E':
                    case 'f':
                    case 'g':
                    case 'G':
                    {
                        sprintf(buff, form, (double)luaL_checknumber(L, arg));
                        break;
                    }

                    case 'q':
                    {
                        addquoted(L, b, arg);
                        continue;          /* skip the 'addsize' at the end */
                    }

                    case 's':
                    {
                        uint    l;
                        CharPtr s = luaL_checklstring(L, arg, out l);
                        if ((strchr(form, '.') == null) && l >= 100)
                        {
                            /* no precision and string is too long to be formatted;
                             *                                   keep original string */
                            lua_pushvalue(L, arg);
                            luaL_addvalue(b);
                            continue;          /* skip the `addsize' at the end */
                        }
                        else
                        {
                            sprintf(buff, form, s);
                            break;
                        }
                    }

                    default:
                    {          /* also treat cases `pnLlh' */
                        return(luaL_error(L, "invalid option " + LUA_QL("%%%c") + " to " +
                                          LUA_QL("format"), strfrmt[-1]));
                    }
                    }
                    luaL_addlstring(b, buff, (uint)strlen(buff));
                }
            }
            luaL_pushresult(b);
            return(1);
        }
示例#11
0
 public static void luaO_chunkid(CharPtr out_, CharPtr source, uint bufflen)
 {
     //out_ = "";
     if (source[0] == '=')
     {
         strncpy(out_, source + 1, (int)bufflen);  /* remove first char */
         out_[bufflen - 1] = '\0';  /* ensures null termination */
     }
     else
     {  /* out = "source", or "...source" */
         if (source[0] == '@')
         {
             uint l;
             source = source.next();  /* skip the `@' */
             bufflen -= (uint)(" '...' ".Length + 1);
             l = (uint)strlen(source);
             strcpy(out_, "");
             if (l > bufflen)
             {
                 source += (l - bufflen);  /* get last part of file name */
                 strcat(out_, "...");
             }
             strcat(out_, source);
         }
         else
         {  /* out = [string "string"] */
             uint len = strcspn(source, "\n\r");  /* stop at first newline */
             bufflen -= (uint)(" [string \"...\"] ".Length + 1);
             if (len > bufflen) len = bufflen;
             strcpy(out_, "[string \"");
             if (source[len] != '\0')
             {  /* must truncate? */
                 strncat(out_, source, (int)len);
                 strcat(out_, "...");
             }
             else
                 strcat(out_, source);
             strcat(out_, "\"]");
         }
     }
 }
示例#12
0
 public static void luaL_addlstring(luaL_Buffer B, CharPtr s, uint l)
 {
     while (l-- != 0)
     {
         char c = s[0];
         s = s.next();
         luaL_addchar(B, c);
     }
 }
示例#13
0
 private static CharPtr matchbalance (MatchState ms, CharPtr s,
                                      CharPtr p) {
     if ((p[0] == 0) || (p[1] == 0))
         luaL_error(ms.L, "unbalanced pattern");
     if (s[0] != p[0]) return null;
     else {
         int b = p[0];
         int e = p[1];
         int 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 */
 }
示例#14
0
 private static int auxgetinfo(LuaState L, CharPtr what, lua_Debug ar,
                     Closure f, CallInfo ci)
 {
     int status = 1;
     if (f == null)
     {
         info_tailcall(ar);
         return status;
     }
     for (; what[0] != 0; what = what.next())
     {
         switch (what[0])
         {
             case 'S':
                 {
                     funcinfo(ar, f);
                     break;
                 }
             case 'l':
                 {
                     ar.currentline = (ci != null) ? currentline(L, ci) : -1;
                     break;
                 }
             case 'u':
                 {
                     ar.nups = f.c.nupvalues;
                     break;
                 }
             case 'n':
                 {
                     ar.namewhat = (ci != null) ? getfuncname(L, ci, ref ar.name) : null;
                     if (ar.namewhat == null)
                     {
                         ar.namewhat = "";  /* not found */
                         ar.name = null;
                     }
                     break;
                 }
             case 'L':
             case 'f':  /* handled by lua_getinfo */
                 break;
             default: status = 0; break;/* invalid option */
         }
     }
     return status;
 }
示例#15
0
 public static int lua_getinfo(LuaState L, CharPtr what, lua_Debug ar)
 {
     int status;
     Closure f = null;
     CallInfo ci = null;
     lua_lock(L);
     if (what == '>')
     {
         StkId func = L.top - 1;
         luai_apicheck(L, ttisfunction(func));
         what = what.next();  /* skip the '>' */
         f = clvalue(func);
         StkId.dec(ref L.top);  /* pop function */
     }
     else if (ar.i_ci != 0)
     {  /* no tail call? */
         ci = L.base_ci[ar.i_ci];
         lua_assert(ttisfunction(ci.func));
         f = clvalue(ci.func);
     }
     status = auxgetinfo(L, what, ar, f, ci);
     if (strchr(what, 'f') != null)
     {
         if (f == null) setnilvalue(L.top);
         else setclvalue(L, L.top, f);
         incr_top(L);
     }
     if (strchr(what, 'L') != null)
         collectvalidlines(L, f);
     lua_unlock(L);
     return status;
 }
示例#16
0
        public static int str_format(LuaState L)
        {
            int     top = LuaGetTop(L);
            int     arg = 1;
            uint    sfl;
            CharPtr strfrmt     = LuaLCheckLString(L, arg, out sfl);
            var     strfrmt_end = strfrmt + sfl;
            var     b           = new LuaLBuffer(L);

            LuaLBuffInit(L, b);
            while (strfrmt < strfrmt_end)
            {
                if (strfrmt[0] != L_ESC)
                {
                    LuaLAddChar(b, strfrmt[0]);
                    strfrmt = strfrmt.next();
                }
                else if (strfrmt[1] == L_ESC)
                {
                    LuaLAddChar(b, strfrmt[0]); /* %% */
                    strfrmt = strfrmt + 2;
                }
                else
                {
                    /* format item */
                    strfrmt = strfrmt.next();
                    CharPtr form = new char[MAX_FORMAT]; /* to store the format (`%...') */
                    CharPtr buff = new char[MAX_ITEM];   /* to store the formatted item */
                    if (++arg > top)
                    {
                        LuaLArgError(L, arg, "no value");
                    }

                    strfrmt = scanformat(L, strfrmt, form);
                    char ch = strfrmt[0];
                    strfrmt = strfrmt.next();
                    switch (ch)
                    {
                    case 'c':
                    {
                        sprintf(buff, form, (int)LuaLCheckNumber(L, arg));
                        break;
                    }

                    case 'd':
                    case 'i':
                    {
                        addintlen(form);
                        sprintf(buff, form, (long)LuaLCheckNumber(L, arg));
                        break;
                    }

                    case 'o':
                    case 'u':
                    case 'x':
                    case 'X':
                    {
                        addintlen(form);
                        sprintf(buff, form, (ulong)LuaLCheckNumber(L, arg));
                        break;
                    }

                    case 'e':
                    case 'E':
                    case 'f':
                    case 'g':
                    case 'G':
                    {
                        sprintf(buff, form, LuaLCheckNumber(L, arg));
                        break;
                    }

                    case 'q':
                    {
                        addquoted(L, b, arg);
                        continue;     /* skip the 'addsize' at the end */
                    }

                    case 's':
                    {
                        uint    l;
                        CharPtr s = LuaLCheckLString(L, arg, out l);
                        if ((strchr(form, '.') == null) && l >= 100)
                        {
                            /* no precision and string is too long to be formatted;
                             * keep original string */
                            LuaPushValue(L, arg);
                            LuaLAddValue(b);
                            continue;     /* skip the `addsize' at the end */
                        }

                        sprintf(buff, form, s);
                        break;
                    }

                    default:
                    {
                        /* also treat cases `pnLlh' */
                        return(LuaLError(L, "invalid option " + LUA_QL("%" + ch) + " to " +
                                         LUA_QL("format"), strfrmt[-1]));
                    }
                    }

                    LuaLAddLString(b, buff, (uint)strlen(buff));
                }
            }

            LuaLPushResult(b);
            return(1);
        }
示例#17
0
 private static CharPtr classend (MatchState ms, CharPtr p) {
     p = new CharPtr(p);
     char c = p[0];
     p = p.next();
     switch (c) {
             case L_ESC: {
                 if (p[0] == '\0')
                     luaL_error(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')
                         luaL_error(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;
             }
     }
 }
示例#18
0
 private static CharPtr scanformat (LuaState L, CharPtr strfrmt, CharPtr form) {
     CharPtr p = strfrmt;
     while (p[0] != '\0' && strchr(FLAGS, p[0]) != null) p = p.next();  /* skip flags */
     if ((uint)(p - strfrmt) >= (FLAGS.Length+1))
         luaL_error(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])))
         luaL_error(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;
 }
示例#19
0
 private static CharPtr match (MatchState ms, CharPtr s, CharPtr p) {
     s = new CharPtr(s);
     p = new CharPtr(p);
     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);
                 else
                     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] != '[')
                                 luaL_error(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((byte)(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) */
                             }
                             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 */
                 else goto dflt;
             }
             default: dflt: {  /* it is a pattern item */
                 CharPtr ep = classend(ms, p);  /* points to what is next */
                 int 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); */
                         }
                 }
             }
     }
 }
示例#20
0
 private static CharPtr min_expand (MatchState ms, CharPtr s,
                                    CharPtr p, CharPtr ep) {
     for (;;) {
         CharPtr res = match(ms, s, ep+1);
         if (res != null)
             return res;
         else if ( (s < ms.src_end) && (singlematch((byte)(s[0]), p, ep) != 0) )
             s = s.next();  /* try with one more repetition */
         else return null;
     }
 }
示例#21
0
        public static int str_gsub(LuaState L)
        {
            uint    srcl;
            CharPtr src    = LuaLCheckLString(L, 1, out srcl);
            CharPtr p      = PatchPattern(LuaLCheckStringStr(L, 2));
            int     tr     = LuaType(L, 3);
            int     max_s  = LuaLOptInt(L, 4, (int)(srcl + 1));
            int     anchor = 0;

            if (p[0] == '^')
            {
                p      = p.next();
                anchor = 1;
            }
            int        n  = 0;
            MatchState ms = new MatchState();
            LuaLBuffer b  = new LuaLBuffer(L);

            LuaLArgCheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
                         tr == LUA_TFUNCTION || tr == LUA_TTABLE ||
                         tr == LUA_TUSERDATA, 3,
                         "string/function/table expected");
            LuaLBuffInit(L, b);
            ms.L          = L;
            ms.matchdepth = MAXCCALLS;
            ms.src_init   = src;
            ms.src_end    = src + srcl;
            while (n < max_s)
            {
                CharPtr e;
                ms.level = 0;
                //LuaAssert(ms.matchdepth == MAXCCALLS);
                ms.matchdepth = MAXCCALLS;
                e             = match(ms, src, p);
                if (e != null)
                {
                    n++;
                    add_value(ms, b, src, e);
                }
                if ((e != null) && e > src)       /* non empty match? */
                {
                    src = e;                      /* skip it */
                }
                else if (src < ms.src_end)
                {
                    char c = src[0];
                    src = src.next();
                    LuaLAddChar(b, c);
                }
                else
                {
                    break;
                }
                if (anchor != 0)
                {
                    break;
                }
            }
            LuaLAddLString(b, src, (uint)(ms.src_end - src));
            LuaLPushResult(b);
            LuaPushInteger(L, n);              /* number of substitutions */
            return(2);
        }
示例#22
0
        private static void addquoted(LuaState L, LuaLBuffer b, int arg)
        {
            uint    l;
            CharPtr s = LuaLCheckLString(L, arg, out l);

            LuaLAddChar(b, '"');
            while ((l--) != 0)
            {
                switch (s[0])
                {
                case '"':
                case '\\':
                case '\n':
                {
                    LuaLAddChar(b, '\\');
                    LuaLAddChar(b, s[0]);
                    break;
                }

                case '\r':
                {
                    LuaLAddLString(b, "\\r", 2);
                    break;
                }

                default:
                {
                    if (s[0] < (char)16)
                    {
                        bool isfollowedbynum = false;

                        if (l >= 1)
                        {
                            if (char.IsNumber(s[1]))
                            {
                                isfollowedbynum = true;
                            }
                        }

                        if (isfollowedbynum)
                        {
                            LuaLAddString(b, $"\\{(int) s[0]:000}");
                        }
                        else
                        {
                            LuaLAddString(b, $"\\{(int) s[0]}");
                        }
                    }
                    else
                    {
                        LuaLAddChar(b, s[0]);
                    }

                    break;
                }
                }

                s = s.next();
            }

            LuaLAddChar(b, '"');
        }
示例#23
0
 private static int matchbracketclass (int c, CharPtr p, CharPtr ec) {
     int 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(c, (byte)(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;
 }