private static int ReadLine(LinyeeState L, Stream f) { LinyeeLBuffer b = new LinyeeLBuffer(); LinyeeLBuffInit(L, b); for (;;) { uint l; CharPtr p = LinyeeLPrepBuffer(b); if (fgets(p, f) == null) /* eof? */ { LinyeeLPushResult(b); /* close buffer */ return((LinyeeObjectLen(L, -1) > 0) ? 1 : 0); /* check whether read something */ } l = (uint)strlen(p); if (l == 0 || p[l - 1] != '\n') { LinyeeLAddSize(b, (int)l); } else { LinyeeLAddSize(b, (int)(l - 1)); /* do not include `eol' */ LinyeeLPushResult(b); /* close buffer */ return(1); /* read at least an `eol' */ } } }
public static void LinyeeLAddValue(LinyeeLBuffer B) { LinyeeState L = B.L; uint vl; CharPtr s = LinyeeToLString(L, -1, out vl); if (vl <= BufferFree(B)) /* fit into buffer? */ { CharPtr dst = new CharPtr(B.buffer.chars, B.buffer.index + B.p); CharPtr src = new CharPtr(s.chars, s.index); for (uint i = 0; i < vl; i++) { dst[i] = src[i]; } B.p += (int)vl; LinyeePop(L, 1); /* remove from stack */ } else { if (EmptyBuffer(B) != 0) { LinyeeInsert(L, -2); /* put buffer before new value */ } B.lvl++; /* add new value into B stack */ AdjustStack(B); } }
private static void add_s(MatchState ms, LinyeeLBuffer b, CharPtr s, CharPtr e) { uint l, i; CharPtr news = LinyeeToLString(ms.L, 3, out l); for (i = 0; i < l; i++) { if (news[i] != L_ESC) { LinyeeLAddChar(b, news[i]); } else { i++; /* skip ESC */ if (!isdigit((byte)(news[i]))) { LinyeeLAddChar(b, news[i]); } else if (news[i] == '0') { LinyeeLAddLString(b, s, (uint)(e - s)); } else { push_onecapture(ms, news[i] - '1', s, e); LinyeeLAddValue(b); /* add capture to accumulated result */ } } } }
public static CharPtr LinyeeLPrepBuffer(LinyeeLBuffer B) { if (EmptyBuffer(B) != 0) { AdjustStack(B); } return(new CharPtr(B.buffer, B.p)); }
public static void LinyeeLAddChar(LinyeeLBuffer B, char c) { if (B.p >= LUAL_BUFFERSIZE) { LinyeeLPrepBuffer(B); } B.buffer[B.p++] = c; }
public static void LinyeeLAddLString(LinyeeLBuffer B, CharPtr s, uint l) { while (l-- != 0) { char c = s[0]; s = s.next(); LinyeeLAddChar(B, c); } }
private static void addfield(LinyeeState L, LinyeeLBuffer b, int i) { LinyeeRawGetI(L, 1, i); if (LinyeeIsString(L, -1) == 0) { LinyeeLError(L, "invalid value (%s) at index %d in table for " + LINYEE_QL("concat"), LinyeeLTypeName(L, -1), i); } LinyeeLAddValue(b); }
private static int str_reverse(LinyeeState L) { uint l; LinyeeLBuffer b = new LinyeeLBuffer(); CharPtr s = LinyeeLCheckLString(L, 1, out l); LinyeeLBuffInit(L, b); while ((l--) != 0) { LinyeeLAddChar(b, s[l]); } LinyeeLPushResult(b); return(1); }
private static int str_dump(LinyeeState L) { LinyeeLBuffer b = new LinyeeLBuffer(); LinyeeLCheckType(L, 1, LINYEE_TFUNCTION); LinyeeSetTop(L, 1); LinyeeLBuffInit(L, b); if (LinyeeDump(L, writer, b) != 0) { LinyeeLError(L, "unable to dump given function"); } LinyeeLPushResult(b); return(1); }
private static int str_upper(LinyeeState L) { uint l; uint i; LinyeeLBuffer b = new LinyeeLBuffer(); CharPtr s = LinyeeLCheckLString(L, 1, out l); LinyeeLBuffInit(L, b); for (i = 0; i < l; i++) { LinyeeLAddChar(b, toupper(s[i])); } LinyeeLPushResult(b); return(1); }
private static int str_rep(LinyeeState L) { uint l; LinyeeLBuffer b = new LinyeeLBuffer(); CharPtr s = LinyeeLCheckLString(L, 1, out l); int n = LinyeeLCheckInt(L, 2); LinyeeLBuffInit(L, b); while (n-- > 0) { LinyeeLAddLString(b, s, l); } LinyeeLPushResult(b); return(1); }
private static int EmptyBuffer(LinyeeLBuffer B) { uint l = (uint)BufferLen(B); if (l == 0) { return(0); /* put nothing on stack */ } else { LinyeePushLString(B.L, B.buffer, l); B.p = 0; B.lvl++; return(1); } }
private static int str_char(LinyeeState L) { int n = LinyeeGetTop(L); /* number of arguments */ int i; LinyeeLBuffer b = new LinyeeLBuffer(); LinyeeLBuffInit(L, b); for (i = 1; i <= n; i++) { int c = LinyeeLCheckInt(L, i); LinyeeLArgCheck(L, (byte)(c) == c, i, "invalid value"); LinyeeLAddChar(b, (char)(byte)c); } LinyeeLPushResult(b); return(1); }
/* }====================================================== */ public static CharPtr LinyeeLGSub(LinyeeState L, CharPtr s, CharPtr p, CharPtr r) { CharPtr wild; uint l = (uint)strlen(p); LinyeeLBuffer b = new LinyeeLBuffer(); LinyeeLBuffInit(L, b); while ((wild = strstr(s, p)) != null) { LinyeeLAddLString(b, s, (uint)(wild - s)); /* push prefix */ LinyeeLAddString(b, r); /* push replacement in place of pattern */ s = wild + l; /* continue after `p' */ } LinyeeLAddString(b, s); /* push last suffix */ LinyeeLPushResult(b); return(LinyeeToString(L, -1)); }
private static void add_value(MatchState ms, LinyeeLBuffer b, CharPtr s, CharPtr e) { LinyeeState L = ms.L; switch (LinyeeType(L, 3)) { case LINYEE_TNUMBER: case LINYEE_TSTRING: { add_s(ms, b, s, e); return; } case LINYEE_TUSERDATA: case LINYEE_TFUNCTION: { int n; LinyeePushValue(L, 3); n = push_captures(ms, s, e); LinyeeCall(L, n, 1); break; } case LINYEE_TTABLE: { push_onecapture(ms, 0, s, e); LinyeeGetTable(L, 3); break; } } if (LinyeeToBoolean(L, -1) == 0) /* nil or false? */ { LinyeePop(L, 1); LinyeePushLString(L, s, (uint)(e - s)); /* keep original text */ } else if (LinyeeIsString(L, -1) == 0) { LinyeeLError(L, "invalid replacement value (a %s)", LinyeeLTypeName(L, -1)); } LinyeeLAddValue(b); /* add result to accumulator */ }
private static int ReadChars(LinyeeState L, Stream f, uint n) { uint rlen; /* how much to read */ uint nr; /* number of chars actually read */ LinyeeLBuffer b = new LinyeeLBuffer(); LinyeeLBuffInit(L, b); rlen = LUAL_BUFFERSIZE; /* try to read that much each time */ do { CharPtr p = LinyeeLPrepBuffer(b); if (rlen > n) { rlen = n; /* cannot read more than asked */ } nr = (uint)fread(p, GetUnmanagedSize(typeof(char)), (int)rlen, f); LinyeeLAddSize(b, (int)nr); n -= nr; /* still have to read `n' chars */ } while (n > 0 && nr == rlen); /* until end of count or eof */ LinyeeLPushResult(b); /* close buffer */ return((n == 0 || LinyeeObjectLen(L, -1) > 0) ? 1 : 0); }
private static int tconcat(LinyeeState L) { LinyeeLBuffer b = new LinyeeLBuffer(); uint lsep; int i, last; CharPtr sep = LinyeeLOptLString(L, 2, "", out lsep); LinyeeLCheckType(L, 1, LINYEE_TTABLE); i = LinyeeLOptInt(L, 3, 1); last = LinyeeLOptInteger(L, LinyeeLCheckInt, 4, LinyeeLGetN(L, 1)); LinyeeLBuffInit(L, b); for (; i < last; i++) { addfield(L, b, i); LinyeeLAddLString(b, sep, lsep); } if (i == last) /* add last value (if interval was not empty) */ { addfield(L, b, i); } LinyeeLPushResult(b); return(1); }
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 void AdjustStack(LinyeeLBuffer B) { if (B.lvl > 1) { LinyeeState L = B.L; int toget = 1; /* number of levels to concat */ uint toplen = LinyeeStrLen(L, -1); do { uint l = LinyeeStrLen(L, -(toget + 1)); if (B.lvl - toget + 1 >= LIMIT || toplen > l) { toplen += l; toget++; } else { break; } } while (toget < B.lvl); LinyeeConcat(L, toget); B.lvl = B.lvl - toget + 1; } }
public static void LinyeeLBuffInit(LinyeeState L, LinyeeLBuffer B) { B.L = L; B.p = /*B.buffer*/ 0; B.lvl = 0; }
public static void LinyeeLPushResult(LinyeeLBuffer B) { EmptyBuffer(B); LinyeeConcat(B.L, B.lvl); B.lvl = 1; }
public static void LinyeeLAddString(LinyeeLBuffer B, CharPtr s) { LinyeeLAddLString(B, s, (uint)strlen(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); }
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 OSDate(LinyeeState L) { CharPtr s = new CharPtr(LinyeeLOptString(L, 1, "%c")); DateTime stm; // Parses the second argument if there's one. If not, uses Now as time. if (LinyeeIsNoneOrNil(L, 2)) { stm = DateTime.Now; } else { LinyeeLCheckType(L, 2, LINYEE_TNUMBER); double seconds = LinyeeToNumber(L, 2); stm = new DateTime((long)seconds * TimeSpan.TicksPerSecond); } if (s[0] == '!') /* UTC? */ { stm = stm.ToUniversalTime(); s.inc(); /* skip `!' */ } if (strcmp(s, "*t") == 0) { LinyeeCreateTable(L, 0, 9); /* 9 = number of fields */ SetField(L, "sec", stm.Second); SetField(L, "min", stm.Minute); SetField(L, "hour", stm.Hour); SetField(L, "day", stm.Day); SetField(L, "month", stm.Month); SetField(L, "year", stm.Year); SetField(L, "wday", (int)stm.DayOfWeek + 1); SetField(L, "yday", stm.DayOfYear); SetBoolField(L, "isdst", stm.IsDaylightSavingTime() ? 1 : 0); } else { CharPtr cc = new char[3]; LinyeeLBuffer b = new LinyeeLBuffer(); cc[0] = '%'; cc[2] = '\0'; LinyeeLBuffInit(L, b); for (; s[0] != 0; s.inc()) { if (s[0] != '%' || s[1] == '\0') /* no conversion specifier? */ { LinyeeLAddChar(b, s[0]); } else { uint reslen; CharPtr buff = new char[200]; /* should be big enough for any conversion result */ s.inc(); cc[1] = s[0]; reslen = strftime(buff, (uint)buff.chars.Length, cc, stm); buff.index = 0; LinyeeLAddLString(b, buff, reslen); } } LinyeeLPushResult(b); } return(1); }
private static int BufferFree(LinyeeLBuffer B) { return(LUAL_BUFFERSIZE - BufferLen(B)); }
/* ** {====================================================== ** Generic Buffer manipulation ** ======================================================= */ private static int BufferLen(LinyeeLBuffer B) { return(B.p); }
public static void LinyeeLAddSize(LinyeeLBuffer B, int n) { B.p += n; }
///* compatibility only */ public static void LinyeeLPutChar(LinyeeLBuffer B, char c) { LinyeeLAddChar(B, c); }