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_, "\"]"); } } }
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); }
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); } } }
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); }
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, '"'); }
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); }
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); }
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); }
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); }