Пример #1
0
 public static void LinyeeOChunkID(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_, "\"]");
         }
     }
 }
Пример #2
0
        private static CharPtr scanformat(LinyeeState 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))
            {
                LinyeeLError(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])))
            {
                LinyeeLError(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);
        }
Пример #3
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);
         }
     }
 }
Пример #4
0
        public static int LinyeeGetInfo(LinyeeState L, CharPtr what, ref LinyeeDebug ar)
        {
            int      status;
            Closure  f  = null;
            CallInfo ci = null;

            LinyeeLock(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];
                LinyeeAssert(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);
                }
                IncrTop(L);
            }
            if (strchr(what, 'L') != null)
            {
                CollectValidLines(L, f);
            }
            LinyeeUnlock(L);
            return(status);
        }
Пример #5
0
        private static void addquoted(LinyeeState L, LinyeeLBuffer b, int arg)
        {
            uint    l;
            CharPtr s = LinyeeLCheckLString(L, arg, out l);

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

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

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

                default: {
                    LinyeeLAddChar(b, s[0]);
                    break;
                }
                }
                s = s.next();
            }
            LinyeeLAddChar(b, '"');
        }
Пример #6
0
        private static int str_gsub(LinyeeState L)
        {
            uint    srcl;
            CharPtr src    = LinyeeLCheckLString(L, 1, out srcl);
            CharPtr p      = LinyeeLCheckString(L, 2);
            int     tr     = LinyeeType(L, 3);
            int     max_s  = LinyeeLOptInt(L, 4, (int)(srcl + 1));
            int     anchor = 0;

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

            LinyeeLArgCheck(L, tr == LINYEE_TNUMBER || tr == LINYEE_TSTRING ||
                            tr == LINYEE_TFUNCTION || tr == LINYEE_TTABLE ||
                            tr == LINYEE_TUSERDATA, 3,
                            "string/function/table expected");
            LinyeeLBuffInit(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;
                LinyeeAssert(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();
                    LinyeeLAddChar(b, c);
                }
                else
                {
                    break;
                }
                if (anchor != 0)
                {
                    break;
                }
            }
            LinyeeLAddLString(b, src, (uint)(ms.src_end - src));
            LinyeeLPushResult(b);
            LinyeePushInteger(L, n);        /* number of substitutions */
            return(2);
        }
Пример #7
0
        private static int str_find_aux(LinyeeState L, int find)
        {
            uint      l1, l2;
            CharPtr   s    = LinyeeLCheckLString(L, 1, out l1);
            CharPtr   p    = LinyeeLCheckLString(L, 2, out l2);
            ptrdiff_t init = posrelat(LinyeeLOptInteger(L, 3, 1), l1) - 1;

            if (init < 0)
            {
                init = 0;
            }
            else if ((uint)(init) > l1)
            {
                init = (ptrdiff_t)l1;
            }
            if ((find != 0) && ((LinyeeToBoolean(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)
                {
                    LinyeePushInteger(L, s2 - s + 1);
                    LinyeePushInteger(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.matchdepth = MAXCCALLS;
                ms.src_init   = s;
                ms.src_end    = s + l1;
                do
                {
                    CharPtr res;
                    ms.level = 0;
                    LinyeeAssert(ms.matchdepth == MAXCCALLS);
                    if ((res = match(ms, s1, p)) != null)
                    {
                        if (find != 0)
                        {
                            LinyeePushInteger(L, s1 - s + 1);    /* start */
                            LinyeePushInteger(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));
            }
            LinyeePushNil(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);
            bool runDflt = false;
            bool runInit = true;

            if (ms.matchdepth-- == 0)
            {
                LinyeeLError(ms.L, "pattern too complex");
            }
            //init:
            while (runInit)         // Replaces "init:" in order to be compatible with Mono.
            {
                runInit = false;    // No "goto init" until further notice.
                if (p != '\0')      /* end of pattern? */
                {
                    switch (p[0])
                    {
                    case '(': {                /* start capture */
                        if (p[1] == ')')       /* position capture? */
                        {
                            s = start_capture(ms, s, p + 2, CAP_POSITION);
                        }
                        else
                        {
                            s = start_capture(ms, s, p + 1, CAP_UNFINISHED);
                        }
                        break;
                    }

                    case ')': {                /* end capture */
                        s = end_capture(ms, s, p + 1);
                        break;
                    }

                    case '$': {
                        if (p[1] != '\0')                      /* is the `$' the last char in pattern? */
                        {
                            runDflt = true;                    //goto dflt; /* no; go to default */
                        }
                        s = (s == ms.src_end) ? s : null;      /* check end of string */
                        break;
                    }

                    case L_ESC: {               /* escaped sequences not in the format class[*+?-]? */
                        switch (p[1])
                        {
                        case 'b': {                          /* balanced string? */
                            s = matchbalance(ms, s, p + 2);
                            if (s != null)
                            {
                                p      += 4;
                                runInit = true;                           //goto init;  /* return match(ms, s, p+4); */
                            }
                            /* else fail (s == NULL) */
                            break;
                        }

                        case 'f': {                          /* frontier? */
                            CharPtr ep; char previous;
                            p += 2;
                            if (p[0] != '[')
                            {
                                LinyeeLError(ms.L, "missing " + LINYEE_QL("[") + " after " +
                                             LINYEE_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))
                            {
                                p       = ep;
                                runInit = true;                    //goto init; /* else return match(ms, s, ep); */
                            }
                            s = null;                              /* match failed */
                            break;
                        }

                        default: {
                            if (isdigit((byte)(p[1])))                                /* capture results (%0-%9)? */
                            {
                                s = match_capture(ms, s, (byte)(p[1]));
                                if (s != null)
                                {
                                    p      += 2;
                                    runInit = true;                             //goto init;  /* else return match(ms, s, p+2) */
                                }
                                break;
                            }
                            runDflt = true;                             //goto dflt;
                            break;
                        }
                        }
                        break;
                    }

                    default: {
                        runDflt = true;                   // goto dflt
                        break;
                    }
                    }
                }

                //dflt:
                if (runDflt)                      // Replaces "dflt:" in order to be compatible with Mono.
                {                                 /* pattern class plus optional suffix */
                    runDflt = false;              // no more "goto dflt" until further notice.
                    CharPtr ep = classend(ms, p); /* points to optional suffix */
                    /* does not match at least once? */
                    if ((s >= ms.src_end) || (singlematch((byte)(s[0]), p, ep) == 0))
                    {
                        if (ep == '*' || ep == '?' || ep == '-')                   /* accept empty? */
                        {
                            p       = ep + 1;
                            runInit = true;   //goto init; /* return match(ms, s, ep + 1); */
                        }
                        else                  /* '+' or no suffix */
                        {
                            s = null;         /* fail */
                        }
                    }
                    else                 /* matched once */
                    {
                        switch (ep[0])
                        {
                        case '?': {                    /* optional */
                            CharPtr res;
                            if ((res = match(ms, s + 1, ep + 1)) != null)
                            {
                                s = res;
                            }
                            else
                            {
                                p       = ep + 1;
                                runInit = true;                         //goto init;  /* else return match(ms, s, ep+1); */
                            }
                            break;
                        }

                        case '+': {                       /* 1 or more repetitions */
                            s = s.next();                 /* 1 match already done */
                            s = max_expand(ms, s, p, ep); // cannot fall through, repeating '*' instruction instead.
                            break;
                        }

                        case '*': {                    /* 0 or more repetitions */
                            s = max_expand(ms, s, p, ep);
                            break;
                        }

                        case '-': {                    /* 0 or more repetitions (minimum) */
                            s = min_expand(ms, s, p, ep);
                            break;
                        }

                        default: {                   /* no suffix */
                            s       = s.next();
                            p       = ep;
                            runInit = true;                       //goto init;  /* return match(ms, s+1, ep); */
                            break;
                        }
                        }
                    }
                }
            }

            ms.matchdepth++;
            return(s);
        }
Пример #9
0
        private static int str_format(LinyeeState L)
        {
            int           top = LinyeeGetTop(L);
            int           arg = 1;
            uint          sfl;
            CharPtr       strfrmt     = LinyeeLCheckLString(L, arg, out sfl);
            CharPtr       strfrmt_end = strfrmt + sfl;
            LinyeeLBuffer b           = new LinyeeLBuffer();

            LinyeeLBuffInit(L, b);
            while (strfrmt < strfrmt_end)
            {
                if (strfrmt[0] != L_ESC)
                {
                    LinyeeLAddChar(b, strfrmt[0]);
                    strfrmt = strfrmt.next();
                }
                else if (strfrmt[1] == L_ESC)
                {
                    LinyeeLAddChar(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)
                    {
                        LinyeeLArgError(L, arg, "no value");
                    }
                    strfrmt = scanformat(L, strfrmt, form);
                    char ch = strfrmt[0];
                    strfrmt = strfrmt.next();
                    switch (ch)
                    {
                    case 'c':
                    {
                        sprintf(buff, form, (int)LinyeeLCheckNumber(L, arg));
                        break;
                    }

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

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

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

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

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

                    default:
                    {                                /* also treat cases `pnLlh' */
                        return(LinyeeLError(L, "invalid option " + LINYEE_QL("%%%c") + " to " +
                                            LINYEE_QL("format"), strfrmt[-1]));
                    }
                    }
                    LinyeeLAddLString(b, buff, (uint)strlen(buff));
                }
            }
            LinyeeLPushResult(b);
            return(1);
        }