/Assets/LUA/KopiLua/lstrlib.cs
C# | 989 lines | 943 code | 46 blank | 0 comment | 224 complexity | 599e40604a3eab8fdf0d0dab3e2817f0 MD5 | raw file
- using System.IO;
- namespace KopiLua
- {
- using lua_Integer = System.Int32;
- using LUA_INTFRM_T = System.Int64;
- using ptrdiff_t = System.Int32;
- using UNSIGNED_LUA_INTFRM_T = System.UInt64;
- public partial class Lua
- {
- public const int CAP_UNFINISHED = (-1);
- public const int CAP_POSITION = (-2);
- public const int MAX_ITEM = 512;
- public const int MAXCCALLS = 200;
- public const string FLAGS = "-+ #0";
- public const string SPECIALS = "^$*+?.([%-";
- public static readonly int MAX_FORMAT = (FLAGS.Length + 1) + (LUA_INTFRMLEN.Length + 1) + 10;
- public const char L_ESC = '%';
-
- private static int StrLen(LuaState _l)
- {
- uint __l;
- LuaLCheckLString(_l, 1, out __l);
- LuaPushInteger(_l, (int)__l);
- return 1;
- }
- private static ptrdiff_t PosRelat(ptrdiff_t _pos, uint _len)
- {
- if (_pos < 0) _pos += (ptrdiff_t)_len + 1;
- return (_pos >= 0) ? _pos : 0;
- }
- private static int StrSub(LuaState _l)
- {
- uint __l;
- CharPtr _s = LuaLCheckLString(_l, 1, out __l);
- ptrdiff_t _start = PosRelat(LuaLCheckInteger(_l, 2), __l);
- ptrdiff_t _end = PosRelat(LuaLOptInteger(_l, 3, -1), __l);
- if (_start < 1) _start = 1;
- if (_end > (ptrdiff_t)__l) _end = (ptrdiff_t)__l;
- if (_start <= _end)
- LuaPushLString(_l, _s + _start - 1, (uint)(_end - _start + 1));
- else LuaPushLiteral(_l, "");
- return 1;
- }
- private static int StrReverse(LuaState _l)
- {
- uint __l;
- LuaLBuffer _b = new LuaLBuffer();
- CharPtr _s = LuaLCheckLString(_l, 1, out __l);
- LuaLBuffInit(_l, _b);
- while ((__l--) != 0) LuaLAddChar(_b, _s[__l]);
- LuaLPushResult(_b);
- return 1;
- }
- private static int StrLower(LuaState _l)
- {
- uint __l;
- uint _i;
- LuaLBuffer _b = new LuaLBuffer();
- CharPtr _s = LuaLCheckLString(_l, 1, out __l);
- LuaLBuffInit(_l, _b);
- for (_i = 0; _i < __l; _i++)
- LuaLAddChar(_b, ToLower(_s[_i]));
- LuaLPushResult(_b);
- return 1;
- }
- private static int StrUpper(LuaState _l)
- {
- uint __l;
- uint _i;
- LuaLBuffer _b = new LuaLBuffer();
- CharPtr _s = LuaLCheckLString(_l, 1, out __l);
- LuaLBuffInit(_l, _b);
- for (_i = 0; _i < __l; _i++)
- LuaLAddChar(_b, ToUpper(_s[_i]));
- LuaLPushResult(_b);
- return 1;
- }
- private static int StrRep(LuaState _l)
- {
- uint __l;
- LuaLBuffer _b = new LuaLBuffer();
- CharPtr _s = LuaLCheckLString(_l, 1, out __l);
- int _n = LuaLCheckInt(_l, 2);
- LuaLBuffInit(_l, _b);
- while (_n-- > 0)
- LuaLAddLString(_b, _s, __l);
- LuaLPushResult(_b);
- return 1;
- }
- private static int StrByte(LuaState _l)
- {
- uint __l;
- CharPtr s = LuaLCheckLString(_l, 1, out __l);
- ptrdiff_t _pos_i = PosRelat(LuaLOptInteger(_l, 2, 1), __l);
- ptrdiff_t _pos_e = PosRelat(LuaLOptInteger(_l, 3, _pos_i), __l);
- int _n, _i;
- if (_pos_i <= 0) _pos_i = 1;
- if ((uint)_pos_e > __l) _pos_e = (int)__l;
- if (_pos_i > _pos_e) return 0;
- _n = _pos_e - _pos_i + 1;
- if (_pos_i + _n <= _pos_e)
- LuaLError(_l, "string slice too long");
- LuaLCheckStack(_l, _n, "string slice too long");
- for (_i = 0; _i < _n; _i++)
- LuaPushInteger(_l, (byte)(s[_pos_i + _i - 1]));
- return _n;
- }
- private static int StrChar(LuaState _l)
- {
- int _n = LuaGetTop(_l);
- int _i;
- LuaLBuffer _b = new LuaLBuffer();
- LuaLBuffInit(_l, _b);
- for (_i = 1; _i <= _n; _i++)
- {
- int _c = LuaLCheckInt(_l, _i);
- LuaLArgCheck(_l, (byte)(_c) == _c, _i, "invalid value");
- LuaLAddChar(_b, (char)(byte)_c);
- }
- LuaLPushResult(_b);
- return 1;
- }
- private static int Writer(LuaState _l, object _b, uint _size, object __b)
- {
- if (_b.GetType() != typeof(CharPtr))
- {
- using (MemoryStream _stream = new MemoryStream())
- {
- }
- }
- LuaLAddLString((LuaLBuffer)__b, (CharPtr)_b, _size);
- return 0;
- }
- private static int StrDump(LuaState _l)
- {
- LuaLBuffer _b = new LuaLBuffer();
- LuaLCheckType(_l, 1, LUA_TFUNCTION);
- LuaSetTop(_l, 1);
- LuaLBuffInit(_l, _b);
- if (LuaDump(_l, Writer, _b) != 0)
- LuaLError(_l, "unable to dump given function");
- LuaLPushResult(_b);
- return 1;
- }
- public class MatchState
- {
- public int matchDepth;
- public CharPtr srcInit;
- public CharPtr srcEnd;
- public LuaState l;
- public int level;
- public MatchState()
- {
- for (int i = 0; i < LUA_MAXCAPTURES; i++)
- Capture[i] = new capture_();
- }
- public class capture_
- {
- public CharPtr init;
- public ptrdiff_t len;
- };
- public capture_[] Capture = new capture_[LUA_MAXCAPTURES];
- };
- private static int CheckCapture(MatchState _ms, int _l)
- {
- _l -= '1';
- if (_l < 0 || _l >= _ms.level || _ms.Capture[_l].len == CAP_UNFINISHED)
- return LuaLError(_ms.l, "invalid capture index %%%d", _l + 1);
- return _l;
- }
- private static int CaptureToClose(MatchState _ms)
- {
- int _level = _ms.level;
- for (_level--; _level >= 0; _level--)
- if (_ms.Capture[_level].len == CAP_UNFINISHED) return _level;
- return LuaLError(_ms.l, "invalid pattern capture");
- }
- 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')
- LuaLError(_ms.l, "malformed pattern (ends with " + LUA_QL("%%") + ")");
- return _p + 1;
- }
- case '[':
- {
- if (_p[0] == '^') _p = _p.next();
- do
- {
- 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();
- } while (_p[0] != ']');
- return _p + 1;
- }
- default:
- {
- return _p;
- }
- }
- }
- private static int MatchClass(int _c, int _cl)
- {
- bool _res;
- switch (ToLower(_cl))
- {
- case 'a': _res = IsAlpha(_c); break;
- case 'c': _res = IsCntrl(_c); break;
- case 'd': _res = IsDigit(_c); break;
- case 'l': _res = IsLower(_c); break;
- case 'p': _res = IsPunct(_c); break;
- case 's': _res = IsSpace(_c); break;
- case 'u': _res = IsUpper(_c); break;
- case 'w': _res = IsAlnum(_c); break;
- case 'x': _res = IsXDigit((char)_c); break;
- case 'z': _res = (_c == 0); break;
- default: return (_cl == _c) ? 1 : 0;
- }
- return (IsLower(_cl) ? (_res ? 1 : 0) : ((!_res) ? 1 : 0));
- }
- private static int MatchBracketClass(int _c, CharPtr _p, CharPtr _ec)
- {
- int _sig = 1;
- if (_p[1] == '^')
- {
- _sig = 0;
- _p = _p.next();
- }
- while ((_p = _p.next()) < _ec)
- {
- if (_p == L_ESC)
- {
- _p = _p.next();
- if (MatchClass(_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;
- }
- private static int SingleMatch(int _c, CharPtr _p, CharPtr _ep)
- {
- switch (_p[0])
- {
- case '.': return 1;
- case L_ESC: return MatchClass(_c, (byte)(_p[1]));
- case '[': return MatchBracketClass(_c, _p, _ep - 1);
- default: return ((byte)(_p[0]) == _c) ? 1 : 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;
- else
- {
- int _b = _p[0];
- int _e = _p[1];
- int _cont = 1;
- while ((_s = _s.next()) < _ms.srcEnd)
- {
- if (_s[0] == _e)
- {
- if (--_cont == 0) return _s + 1;
- }
- else if (_s[0] == _b) _cont++;
- }
- }
- return null;
- }
- private static CharPtr MaxExpand(MatchState _ms, CharPtr _s, CharPtr _p, CharPtr _ep)
- {
- ptrdiff_t _i = 0;
- while ((_s + _i < _ms.srcEnd) && (SingleMatch((byte)(_s[_i]), _p, _ep) != 0))
- _i++;
- while (_i >= 0)
- {
- CharPtr _res = Match(_ms, (_s + _i), _ep + 1);
- if (_res != null) return _res;
- _i--;
- }
- return null;
- }
- private static CharPtr MinExpand(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.srcEnd) && (SingleMatch((byte)(_s[0]), _p, _ep) != 0))
- _s = _s.next();
- else return null;
- }
- }
- private static CharPtr StartCapture(MatchState _ms, CharPtr _s, CharPtr _p, int _what)
- {
- CharPtr _res;
- int _level = _ms.level;
- if (_level >= LUA_MAXCAPTURES) LuaLError(_ms.l, "too many captures");
- _ms.Capture[_level].init = _s;
- _ms.Capture[_level].len = _what;
- _ms.level = _level + 1;
- if ((_res = Match(_ms, _s, _p)) == null)
- _ms.level--;
- return _res;
- }
- private static CharPtr EndCapture(MatchState _ms, CharPtr _s, CharPtr _p)
- {
- int _l = CaptureToClose(_ms);
- CharPtr _res;
- _ms.Capture[_l].len = _s - _ms.Capture[_l].init;
- if ((_res = Match(_ms, _s, _p)) == null)
- _ms.Capture[_l].len = CAP_UNFINISHED;
- return _res;
- }
- private static CharPtr MatchCapture(MatchState _ms, CharPtr _s, int _l)
- {
- uint _len;
- _l = CheckCapture(_ms, _l);
- _len = (uint)_ms.Capture[_l].len;
- if ((uint)(_ms.srcEnd - _s) >= _len &&
- MemCmp(_ms.Capture[_l].init, _s, _len) == 0)
- return _s + _len;
- else return null;
- }
- 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:
- switch (_p[0])
- {
- case '(':
- {
- if (_p[1] == ')')
- return StartCapture(_ms, _s, _p + 2, CAP_POSITION);
- else
- return StartCapture(_ms, _s, _p + 1, CAP_UNFINISHED);
- }
- case ')':
- {
- return EndCapture(_ms, _s, _p + 1);
- }
- case L_ESC:
- {
- switch (_p[1])
- {
- case 'b':
- {
- _s = MatchBalance(_ms, _s, _p + 2);
- if (_s == null) return null;
- _p += 4; goto init;
- }
- case 'f':
- {
- 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);
- previous = (_s == _ms.srcInit) ? '\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;
- }
- default:
- {
- if (IsDigit((byte)(_p[1])))
- {
- _s = MatchCapture(_ms, _s, (byte)(_p[1]));
- if (_s == null) return null;
- _p += 2; goto init;
- }
- {
- CharPtr _ep = ClassEnd(_ms, _p);
- int _m = (_s < _ms.srcEnd) && (SingleMatch((byte)(_s[0]), _p, _ep) != 0) ? 1 : 0;
- switch (_ep[0])
- {
- case '?':
- {
- CharPtr _res;
- if ((_m != 0) && ((_res = Match(_ms, _s + 1, _ep + 1)) != null))
- return _res;
- _p = _ep + 1; goto init;
- }
- case '*':
- {
- return MaxExpand(_ms, _s, _p, _ep);
- }
- case '+':
- {
- return ((_m != 0) ? MaxExpand(_ms, _s + 1, _p, _ep) : null);
- }
- case '-':
- {
- return MinExpand(_ms, _s, _p, _ep);
- }
- default:
- {
- if (_m == 0) return null;
- _s = _s.next(); _p = _ep; goto init;
- }
- }
- }
- }
- }
- }
- case '\0':
- {
- return _s;
- }
- case '$':
- {
- if (_p[1] == '\0')
- return (_s == _ms.srcEnd) ? _s : null;
- else goto dflt;
- }
- default:
- dflt:
- {
- CharPtr _ep = ClassEnd(_ms, _p);
- int _m = (_s < _ms.srcEnd) && (SingleMatch((byte)(_s[0]), _p, _ep) != 0) ? 1 : 0;
- switch (_ep[0])
- {
- case '?':
- {
- CharPtr _res;
- if ((_m != 0) && ((_res = Match(_ms, _s + 1, _ep + 1)) != null))
- return _res;
- _p = _ep + 1; goto init;
- }
- case '*':
- {
- return MaxExpand(_ms, _s, _p, _ep);
- }
- case '+':
- {
- return ((_m != 0) ? MaxExpand(_ms, _s + 1, _p, _ep) : null);
- }
- case '-':
- {
- return MinExpand(_ms, _s, _p, _ep);
- }
- default:
- {
- if (_m == 0) return null;
- _s = _s.next(); _p = _ep; goto init;
- }
- }
- }
- }
- }
- private static CharPtr LMemFind(CharPtr _s_1, uint _l_1, CharPtr _s_2, uint _l_2)
- {
- if (_l_2 == 0) return _s_1;
- else if (_l_2 > _l_1) return null;
- else
- {
- CharPtr _init;
- _l_2--;
- _l_1 = _l_1 - _l_2;
- while (_l_1 > 0 && (_init = MemChr(_s_1, _s_2[0], _l_1)) != null)
- {
- _init = _init.next();
- if (MemCmp(_init, _s_2 + 1, _l_2) == 0)
- return _init - 1;
- else
- {
- _l_1 -= (uint)(_init - _s_1);
- _s_1 = _init;
- }
- }
- return null;
- }
- }
- private static void PushOneCapture(MatchState _ms, int _i, CharPtr _s, CharPtr _e)
- {
- if (_i >= _ms.level)
- {
- if (_i == 0)
- LuaPushLString(_ms.l, _s, (uint)(_e - _s));
- else
- LuaLError(_ms.l, "invalid capture index");
- }
- else
- {
- ptrdiff_t _l = _ms.Capture[_i].len;
- if (_l == CAP_UNFINISHED) LuaLError(_ms.l, "unfinished capture");
- if (_l == CAP_POSITION)
- LuaPushInteger(_ms.l, _ms.Capture[_i].init - _ms.srcInit + 1);
- else
- LuaPushLString(_ms.l, _ms.Capture[_i].init, (uint)_l);
- }
- }
- private static int PushCaptures(MatchState _ms, CharPtr _s, CharPtr _e)
- {
- int _i;
- int _n_levels = ((_ms.level == 0) && (_s != null)) ? 1 : _ms.level;
- LuaLCheckStack(_ms.l, _n_levels, "too many captures");
- for (_i = 0; _i < _n_levels; _i++)
- PushOneCapture(_ms, _i, _s, _e);
- return _n_levels;
- }
- private static int StrFindAux(LuaState _l, int _find)
- {
- uint _l_1, _l_2;
- CharPtr _s = LuaLCheckLString(_l, 1, out _l_1);
- CharPtr _p = LuaLCheckLString(_l, 2, out _l_2);
- ptrdiff_t _init = PosRelat(LuaLOptInteger(_l, 3, 1), _l_1) - 1;
- if (_init < 0) _init = 0;
- else if ((uint)(_init) > _l_1) _init = (ptrdiff_t)_l_1;
- if ((_find != 0) && ((LuaToBoolean(_l, 4) != 0) || StrPbrk(_p, SPECIALS) == null))
- {
- CharPtr _s_2 = LMemFind(_s + _init, (uint)(_l_1 - _init), _p, (uint)(_l_2));
- if (_s_2 != null)
- {
- LuaPushInteger(_l, _s_2 - _s + 1);
- LuaPushInteger(_l, (int)(_s_2 - _s + _l_2));
- return 2;
- }
- }
- else
- {
- MatchState _ms = new MatchState();
- int _anchor = 0;
- if (_p[0] == '^')
- {
- _p = _p.next();
- _anchor = 1;
- }
- CharPtr _s_1 = _s + _init;
- _ms.l = _l;
- _ms.matchDepth = MAXCCALLS;
- _ms.srcInit = _s;
- _ms.srcEnd = _s + _l_1;
- do
- {
- CharPtr _res;
- _ms.level = 0;
- LuaAssert(_ms.matchDepth == MAXCCALLS);
- if ((_res = Match(_ms, _s_1, _p)) != null)
- {
- if (_find != 0)
- {
- LuaPushInteger(_l, _s_1 - _s + 1);
- LuaPushInteger(_l, _res - _s);
- return PushCaptures(_ms, null, null) + 2;
- }
- else
- return PushCaptures(_ms, _s_1, _res);
- }
- } while (((_s_1 = _s_1.next()) <= _ms.srcEnd) && (_anchor == 0));
- }
- LuaPushNil(_l);
- return 1;
- }
- private static int StrFind(LuaState _l)
- {
- return StrFindAux(_l, 1);
- }
- private static int StrMatch(LuaState _l)
- {
- return StrFindAux(_l, 0);
- }
- private static int GMatchAux(LuaState _l)
- {
- MatchState _ms = new MatchState();
- uint _ls;
- CharPtr _s = LuaToLString(_l, LuaUpValueIndex(1), out _ls);
- CharPtr _p = LuaToString(_l, LuaUpValueIndex(2));
- CharPtr _src;
- _ms.l = _l;
- _ms.matchDepth = MAXCCALLS;
- _ms.srcInit = _s;
- _ms.srcEnd = _s + _ls;
- for (_src = _s + (uint)LuaToInteger(_l, LuaUpValueIndex(3));
- _src <= _ms.srcEnd;
- _src = _src.next())
- {
- CharPtr _e;
- _ms.level = 0;
- LuaAssert(_ms.matchDepth == MAXCCALLS);
- if ((_e = Match(_ms, _src, _p)) != null)
- {
- lua_Integer _new_start = _e - _s;
- if (_e == _src) _new_start++;
- LuaPushInteger(_l, _new_start);
- LuaReplace(_l, LuaUpValueIndex(3));
- return PushCaptures(_ms, _src, _e);
- }
- }
- return 0;
- }
- private static int GMatch(LuaState _l)
- {
- LuaLCheckString(_l, 1);
- LuaLCheckString(_l, 2);
- LuaSetTop(_l, 2);
- LuaPushInteger(_l, 0);
- LuaPushCClosure(_l, GMatchAux, 3);
- return 1;
- }
- private static int GFindNodeF(LuaState _l)
- {
- return LuaLError(_l, LUA_QL("string.gfind") + " was renamed to " + LUA_QL("string.gmatch"));
- }
- private static void AddS(MatchState _ms, LuaLBuffer _b, CharPtr _s, CharPtr _e)
- {
- uint _l, _i;
- CharPtr _news = LuaToLString(_ms.l, 3, out _l);
- for (_i = 0; _i < _l; _i++)
- {
- if (_news[_i] != L_ESC)
- LuaLAddChar(_b, _news[_i]);
- else
- {
- _i++;
- if (!IsDigit((byte)(_news[_i])))
- LuaLAddChar(_b, _news[_i]);
- else if (_news[_i] == '0')
- LuaLAddLString(_b, _s, (uint)(_e - _s));
- else
- {
- PushOneCapture(_ms, _news[_i] - '1', _s, _e);
- LuaLAddValue(_b);
- }
- }
- }
- }
- private static void AddValue(MatchState _ms, LuaLBuffer _b, CharPtr _s, CharPtr _e)
- {
- LuaState _l = _ms.l;
- switch (LuaType(_l, 3))
- {
- case LUA_TNUMBER:
- case LUA_TSTRING:
- {
- AddS(_ms, _b, _s, _e);
- return;
- }
- case LUA_TUSERDATA:
- case LUA_TFUNCTION:
- {
- int n;
- LuaPushValue(_l, 3);
- n = PushCaptures(_ms, _s, _e);
- LuaCall(_l, n, 1);
- break;
- }
- case LUA_TTABLE:
- {
- PushOneCapture(_ms, 0, _s, _e);
- LuaGetTable(_l, 3);
- break;
- }
- }
- if (LuaToBoolean(_l, -1) == 0)
- {
- LuaPop(_l, 1);
- LuaPushLString(_l, _s, (uint)(_e - _s));
- }
- else if (LuaIsString(_l, -1) == 0)
- LuaLError(_l, "invalid replacement value (a %s)", LuaLTypeName(_l, -1));
- LuaLAddValue(_b);
- }
- private static int StrGSub(LuaState _l)
- {
- uint _src_l;
- CharPtr _src = LuaLCheckLString(_l, 1, out _src_l);
- CharPtr _p = LuaLCheckString(_l, 2);
- int _tr = LuaType(_l, 3);
- int _max_s = LuaLOptInt(_l, 4, (int)(_src_l + 1));
- int _anchor = 0;
- if (_p[0] == '^')
- {
- _p = _p.next();
- _anchor = 1;
- }
- int _n = 0;
- MatchState _ms = new MatchState();
- LuaLBuffer _b = new LuaLBuffer();
- 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.srcInit = _src;
- _ms.srcEnd = _src + _src_l;
- while (_n < _max_s)
- {
- CharPtr _e;
- _ms.level = 0;
- LuaAssert(_ms.matchDepth == MAXCCALLS);
- _e = Match(_ms, _src, _p);
- if (_e != null)
- {
- _n++;
- AddValue(_ms, _b, _src, _e);
- }
- if ((_e != null) && _e > _src)
- _src = _e;
- else if (_src < _ms.srcEnd)
- {
- char _c = _src[0];
- _src = _src.next();
- LuaLAddChar(_b, _c);
- }
- else break;
- if (_anchor != 0) break;
- }
- LuaLAddLString(_b, _src, (uint)(_ms.srcEnd - _src));
- LuaLPushResult(_b);
- LuaPushInteger(_l, _n);
- return 2;
- }
- 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;
- }
- case '\0':
- {
- LuaLAddLString(_b, "\\000", 4);
- break;
- }
- default:
- {
- LuaLAddChar(_b, _s[0]);
- break;
- }
- }
- _s = _s.next();
- }
- LuaLAddChar(_b, '"');
- }
- private static CharPtr ScanFormat(LuaState _l, CharPtr _str_format, CharPtr _form)
- {
- CharPtr _p = _str_format;
- while (_p[0] != '\0' && StrChr(FLAGS, _p[0]) != null) _p = _p.next();
- if ((uint)(_p - _str_format) >= (FLAGS.Length + 1))
- LuaLError(_l, "invalid format (repeated flags)");
- if (IsDigit((byte)(_p[0]))) _p = _p.next();
- if (IsDigit((byte)(_p[0]))) _p = _p.next();
- if (_p[0] == '.')
- {
- _p = _p.next();
- if (IsDigit((byte)(_p[0]))) _p = _p.next();
- if (IsDigit((byte)(_p[0]))) _p = _p.next();
- }
- if (IsDigit((byte)(_p[0])))
- LuaLError(_l, "invalid format (width or precision too long)");
- _form[0] = '%';
- _form = _form.next();
- StrNCpy(_form, _str_format, _p - _str_format + 1);
- _form += _p - _str_format + 1;
- _form[0] = '\0';
- return _p;
- }
- private static void AddIntLen(CharPtr _form)
- {
- uint _l = (uint)StrLen(_form);
- char _spec = _form[_l - 1];
- StrCpy(_form + _l - 1, LUA_INTFRMLEN);
- _form[_l + (LUA_INTFRMLEN.Length + 1) - 2] = _spec;
- _form[_l + (LUA_INTFRMLEN.Length + 1) - 1] = '\0';
- }
- private static int StrFormat(LuaState _l)
- {
- int _top = LuaGetTop(_l);
- int _arg = 1;
- uint _sfl;
- CharPtr _str_format = LuaLCheckLString(_l, _arg, out _sfl);
- CharPtr _str_format_end = _str_format + _sfl;
- LuaLBuffer _b = new LuaLBuffer();
- LuaLBuffInit(_l, _b);
- while (_str_format < _str_format_end)
- {
- if (_str_format[0] != L_ESC)
- {
- LuaLAddChar(_b, _str_format[0]);
- _str_format = _str_format.next();
- }
- else if (_str_format[1] == L_ESC)
- {
- LuaLAddChar(_b, _str_format[0]);
- _str_format = _str_format + 2;
- }
- else
- {
- _str_format = _str_format.next();
- CharPtr _form = new char[MAX_FORMAT];
- CharPtr _buff = new char[MAX_ITEM];
- if (++_arg > _top)
- LuaLArgError(_l, _arg, "no value");
- _str_format = ScanFormat(_l, _str_format, _form);
- char _ch = _str_format[0];
- _str_format = _str_format.next();
- switch (_ch)
- {
- case 'c':
- {
- SPrintF(_buff, _form, (int)LuaLCheckNumber(_l, _arg));
- break;
- }
- case 'd':
- case 'i':
- {
- AddIntLen(_form);
- SPrintF(_buff, _form, (LUA_INTFRM_T)LuaLCheckNumber(_l, _arg));
- break;
- }
- case 'o':
- case 'u':
- case 'x':
- case 'X':
- {
- AddIntLen(_form);
- SPrintF(_buff, _form, (UNSIGNED_LUA_INTFRM_T)LuaLCheckNumber(_l, _arg));
- break;
- }
- case 'e':
- case 'E':
- case 'f':
- case 'g':
- case 'G':
- {
- SPrintF(_buff, _form, (double)LuaLCheckNumber(_l, _arg));
- break;
- }
- case 'q':
- {
- AddQuoted(_l, _b, _arg);
- continue;
- }
- case 's':
- {
- uint __l;
- CharPtr _s = LuaLCheckLString(_l, _arg, out __l);
- if ((StrChr(_form, '.') == null) && __l >= 100)
- {
- LuaPushValue(_l, _arg);
- LuaLAddValue(_b);
- continue;
- }
- else
- {
- SPrintF(_buff, _form, _s);
- break;
- }
- }
- default:
- {
- return LuaLError(_l, "invalid option " + LUA_QL("%%%c") + " to " + LUA_QL("format"), _str_format[-1]);
- }
- }
- LuaLAddLString(_b, _buff, (uint)StrLen(_buff));
- }
- }
- LuaLPushResult(_b);
- return 1;
- }
- private readonly static LuaLReg[] strlib = {
- new LuaLReg("byte", StrByte),
- new LuaLReg("char", StrChar),
- new LuaLReg("dump", StrDump),
- new LuaLReg("find", StrFind),
- new LuaLReg("format", StrFormat),
- new LuaLReg("gfind", GFindNodeF),
- new LuaLReg("gmatch", GMatch),
- new LuaLReg("gsub", StrGSub),
- new LuaLReg("len", StrLen),
- new LuaLReg("lower", StrLower),
- new LuaLReg("match", StrMatch),
- new LuaLReg("rep", StrRep),
- new LuaLReg("reverse", StrReverse),
- new LuaLReg("sub", StrSub),
- new LuaLReg("upper", StrUpper),
- new LuaLReg(null, null)
- };
- private static void CreateMetaTable(LuaState _l)
- {
- LuaCreateTable(_l, 0, 1);
- LuaPushLiteral(_l, "");
- LuaPushValue(_l, -2);
- LuaSetMetatable(_l, -2);
- LuaPop(_l, 1);
- LuaPushValue(_l, -2);
- LuaSetField(_l, -2, "__index");
- LuaPop(_l, 1);
- }
- public static int LuaOpenString(LuaState _l)
- {
- LuaLRegister(_l, LUA_STRLIBNAME, strlib);
- #if LUA_COMPAT_GFIND
- lua_getfield(_l, -1, "gmatch");
- lua_setfield(_l, -2, "gfind");
- #endif
- CreateMetaTable(_l);
- return 1;
- }
- }
- }