diff --git a/engine/lua.cpp b/engine/lua.cpp index 5cb123a260a..40d64b74be0 100644 --- a/engine/lua.cpp +++ b/engine/lua.cpp @@ -1674,7 +1674,7 @@ static void ShutUpActor() { /* Find the sector (of any type) which contains * the requested coordinate (x,y,z). */ -static void GetPointSector(void) { +static void GetPointSector() { lua_Object xparam, yparam, zparam; Sector *result; float x = 0.0f, y = 0.0f, z = 0.0f; @@ -1705,7 +1705,7 @@ static void GetPointSector(void) { lua_pushnumber(result->type()); } -static void GetActorSector(void) { +static void GetActorSector() { Actor *act; int sectorType; @@ -1724,7 +1724,7 @@ static void GetActorSector(void) { } } -static void IsActorInSector(void) { +static void IsActorInSector() { int i, numSectors; const char *name; Actor *act; @@ -1749,7 +1749,7 @@ static void IsActorInSector(void) { lua_pushnil(); } -static void MakeSectorActive(void) { +static void MakeSectorActive() { lua_Object sectorName; bool visible; int i = 0, numSectors; diff --git a/engine/lua/liolib.cpp b/engine/lua/liolib.cpp index 54b1bdf999a..9a61f005526 100644 --- a/engine/lua/liolib.cpp +++ b/engine/lua/liolib.cpp @@ -145,7 +145,7 @@ static void read_until(FILE *f, int32 lim) { lua_pushlstring(luaL_buffer(), l); } -static void io_read (void) { +static void io_read() { int32 arg = FIRSTARG; FILE *f = getfileparam(FINPUT, &arg); const char *p = luaL_opt_string(arg, NULL); diff --git a/engine/lua/lstate.cpp b/engine/lua/lstate.cpp index 2237f041dbc..eb00cf2039c 100644 --- a/engine/lua/lstate.cpp +++ b/engine/lua/lstate.cpp @@ -22,7 +22,7 @@ lua_State *lua_state = NULL; int32 globalTaskSerialId; -void stderrorim (void); +void stderrorim(); static luaL_reg stdErrorRimFunc[] = { { "stderrorim", stderrorim } diff --git a/engine/lua/lstring.h b/engine/lua/lstring.h index 9186794658c..ba8bccc557a 100644 --- a/engine/lua/lstring.h +++ b/engine/lua/lstring.h @@ -8,21 +8,21 @@ #define lstring_h -#include "lobject.h" +#include "engine/lua/lobject.h" -void luaS_init (void); -TaggedString *luaS_createudata (void *udata, int32 tag); -TaggedString *luaS_collector (void); +void luaS_init(); +TaggedString *luaS_createudata(void *udata, int32 tag); +TaggedString *luaS_collector(); void luaS_free (TaggedString *l); -TaggedString *luaS_newlstr (const char *str, int32 l); -TaggedString *luaS_new (const char *str); +TaggedString *luaS_newlstr(const char *str, int32 l); +TaggedString *luaS_new(const char *str); TaggedString *luaS_newfixedstring (const char *str); -void luaS_rawsetglobal (TaggedString *ts, TObject *newval); -char *luaS_travsymbol (int32 (*fn)(TObject *)); -int32 luaS_globaldefined (const char *name); -TaggedString *luaS_collectudata (void); -void luaS_freeall (void); +void luaS_rawsetglobal(TaggedString *ts, TObject *newval); +char *luaS_travsymbol(int32 (*fn)(TObject *)); +int32 luaS_globaldefined(const char *name); +TaggedString *luaS_collectudata(); +void luaS_freeall(); extern TaggedString EMPTY; #define NUM_HASHS 61 diff --git a/engine/lua/lstrlib.cpp b/engine/lua/lstrlib.cpp index 0a5e6e2e4f2..0d3f0ef251f 100644 --- a/engine/lua/lstrlib.cpp +++ b/engine/lua/lstrlib.cpp @@ -5,508 +5,497 @@ */ -#include "lauxlib.h" -#include "lua.h" -#include "lualib.h" +#include "engine/lua/lauxlib.h" +#include "engine/lua/lua.h" +#include "engine/lua/lualib.h" - - -static void addnchar (const char *s, int32 n) -{ - char *b = luaL_openspace(n); - memcpy(b, s, n); - luaL_addsize(n); +static void addnchar(const char *s, int32 n) { + char *b = luaL_openspace(n); + memcpy(b, s, n); + luaL_addsize(n); } - -static void str_len (void) -{ - int32 l; - luaL_check_lstr(1, &l); - lua_pushnumber(l); +static void str_len() { + int32 l; + luaL_check_lstr(1, &l); + lua_pushnumber(l); } - -static void closeandpush (void) -{ - lua_pushlstring(luaL_buffer(), luaL_getsize()); +static void closeandpush() { + lua_pushlstring(luaL_buffer(), luaL_getsize()); } - -static int32 posrelat (int32 pos, int32 len) -{ - /* relative string position: negative means back from end */ - return (pos>=0) ? pos : len+pos+1; +static int32 posrelat (int32 pos, int32 len) { + /* relative string position: negative means back from end */ + return (pos >= 0) ? pos : len + pos + 1; } - -static void str_sub (void) -{ - int32 l; - const char *s = luaL_check_lstr(1, &l); - int32 start = posrelat((int32)luaL_check_number(2), l); - int32 end = posrelat((int32)luaL_opt_number(3, -1), l); - if (1 <= start && start <= end && end <= l) - lua_pushlstring(s+start-1, end-start+1); - else lua_pushstring(""); +static void str_sub() { + int32 l; + const char *s = luaL_check_lstr(1, &l); + int32 start = posrelat((int32)luaL_check_number(2), l); + int32 end = posrelat((int32)luaL_opt_number(3, -1), l); + if (1 <= start && start <= end && end <= l) + lua_pushlstring(s + start - 1, end - start + 1); + else + lua_pushstring(""); } - -static void str_lower (void) -{ - int32 l; - int32 i; - const char *s = luaL_check_lstr(1, &l); - luaL_resetbuffer(); - for (i=0; i 0) - addnchar(s, l); - closeandpush(); +static void str_rep() { + int32 l; + const char *s = luaL_check_lstr(1, &l); + int32 n = (int32)luaL_check_number(2); + luaL_resetbuffer(); + while (n-- > 0) + addnchar(s, l); + closeandpush(); } - -/* -** ======================================================= -** PATTERN MATCHING -** ======================================================= -*/ - #define MAX_CAPT 9 struct Capture { - int32 level; /* total number of captures (finished or unfinished) */ - const char *src_end; /* end ('\0') of source string */ - struct { - const char *init; - int32 len; /* -1 signals unfinished capture */ - } capture[MAX_CAPT]; + int32 level; // total number of captures (finished or unfinished) + const char *src_end; // end ('\0') of source string + struct { + const char *init; + int32 len; // -1 signals unfinished capture + } capture[MAX_CAPT]; }; - #define ESC '%' #define SPECIALS "^$*?.([%-" +static void push_captures(Capture *cap) { + int32 i; + for (i = 0; i < cap->level; i++) + lua_pushlstring(cap->capture[i].init, cap->capture[i].len); +} -static void push_captures (struct Capture *cap) -{ - int32 i; - for (i=0; ilevel; i++) - lua_pushlstring(cap->capture[i].init, cap->capture[i].len); +static int32 check_cap (int32 l, Capture *cap) { + l -= '1'; + if (!(0 <= l && l < cap->level && cap->capture[l].len != -1)) + lua_error("invalid capture index"); + return l; +} + +static int32 capture_to_close(Capture *cap) { + int32 level = cap->level; + for (level--; level >= 0; level--) + if (cap->capture[level].len == -1) return level; + lua_error("invalid pattern capture"); + return 0; // to avoid warnings } -static int32 check_cap (int32 l, struct Capture *cap) -{ - l -= '1'; - if (!(0 <= l && l < cap->level && cap->capture[l].len != -1)) - lua_error("invalid capture index"); - return l; +static const char *bracket_end(const char *p) { + return (*p == 0) ? NULL : strchr((*p == '^') ? p + 2 : p + 1, ']'); } - -static int32 capture_to_close (struct Capture *cap) -{ - int32 level = cap->level; - for (level--; level>=0; level--) - if (cap->capture[level].len == -1) return level; - lua_error("invalid pattern capture"); - return 0; /* to avoid warnings */ +static int32 matchclass(int32 c, int32 cl) { + int32 res; + switch (tolower((int)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 'z' : + res = (c == '\0'); + break; + default: + return (cl == c); + } + return (islower((byte)cl) ? res : !res); } - -static const char *bracket_end (const char *p) -{ - return (*p == 0) ? NULL : strchr((*p=='^') ? p+2 : p+1, ']'); +int32 luaI_singlematch(int32 c, const char *p, const char **ep) { + switch (*p) { + case '.': // matches any char + *ep = p + 1; + return 1; + case '\0': // end of pattern; matches nothing + *ep = p; + return 0; + case ESC: + if (*(++p) == '\0') + luaL_verror("incorrect pattern (ends with `%c')", ESC); + *ep = p+1; + return matchclass(c, (byte)*p); + case '[': { + const char *end = bracket_end(p + 1); + int32 sig = *(p + 1) == '^' ? (p++, 0) : 1; + if (!end) lua_error("incorrect pattern (missing `]')"); + *ep = end + 1; + while (++p < end) { + if (*p == ESC) { + if (((p + 1) < end) && matchclass(c, (byte)*++p)) + return sig; + } else if ((*(p + 1) == '-') && (p + 2 < end)) { + p += 2; + if ((byte)*(p - 2) <= c && c <= (byte)*p) + return sig; + } else if ((byte)*p == c) + return sig; + } + return !sig; + } + default: + *ep = p+1; + return ((byte)*p == c); + } } - -static int32 matchclass (int32 c, int32 cl) -{ - int32 res; - switch (tolower((int)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 'z' : res = (c == '\0'); break; - default: return (cl == c); - } - return (islower((byte)cl) ? res : !res); +static const char *matchbalance(const char *s, int32 b, int32 e, Capture *cap) { + if (*s != b) + return NULL; + else { + int32 cont = 1; + while (++s < cap->src_end) { + if (*s == e) { + if (--cont == 0) + return s + 1; + } else if (*s == b) + cont++; + } + } + return NULL; // string ends out of balance } - -int32 luaI_singlematch (int32 c, const char *p, const char **ep) -{ - switch (*p) { - case '.': /* matches any char */ - *ep = p+1; - return 1; - case '\0': /* end of pattern; matches nothing */ - *ep = p; - return 0; - case ESC: - if (*(++p) == '\0') - luaL_verror("incorrect pattern (ends with `%c')", ESC); - *ep = p+1; - return matchclass(c, (byte)*p); - case '[': { - const char *end = bracket_end(p+1); - int32 sig = *(p+1) == '^' ? (p++, 0) : 1; - if (end == NULL) lua_error("incorrect pattern (missing `]')"); - *ep = end+1; - while (++p < end) { - if (*p == ESC) { - if (((p+1) < end) && matchclass(c, (byte)*++p)) - return sig; - } - else if ((*(p+1) == '-') && (p+2 < end)) { - p+=2; - if ((byte)*(p-2) <= c && c <= (byte)*p) - return sig; - } - else if ((byte)*p == c) return sig; - } - return !sig; - } - default: - *ep = p+1; - return ((byte)*p == c); - } +static const char *matchitem(const char *s, const char *p, Capture *cap, const char **ep) { + if (*p == ESC) { + p++; + if (isdigit((byte)*p)) { // capture + int32 l = check_cap(*p, cap); + int32 len = cap->capture[l].len; + *ep = p + 1; + if (cap->src_end-s >= len && memcmp(cap->capture[l].init, s, len) == 0) + return s + len; + else + return NULL; + } else if (*p == 'b') { // balanced string + p++; + if (*p == 0 || *(p + 1) == 0) + lua_error("unbalanced pattern"); + *ep = p + 2; + return matchbalance(s, *p, *(p + 1), cap); + } else + p--; // and go through + } + // "luaI_singlematch" sets "ep" (so must be called even when *s == 0) + return (luaI_singlematch((byte)*s, p, ep) && s < cap->src_end) ? s + 1 : NULL; } - -static const char *matchbalance (const char *s, int32 b, int32 e, struct Capture *cap) -{ - if (*s != b) return NULL; - else { - int32 cont = 1; - while (++s < cap->src_end) { - if (*s == e) { - if (--cont == 0) return s+1; - } - else if (*s == b) cont++; - } - } - return NULL; /* string ends out of balance */ +static const char *match(const char *s, const char *p, Capture *cap) { +init: + // using goto's to optimize tail recursion + switch (*p) { + case '(': + { // start capture + const char *res; + if (cap->level >= MAX_CAPT) + lua_error("too many captures"); + cap->capture[cap->level].init = s; + cap->capture[cap->level].len = -1; + cap->level++; + if (!(res = match(s, p + 1, cap))) // match failed? + cap->level--; // undo capture + return res; + } + case ')': + { // end capture + int32 l = capture_to_close(cap); + const char *res; + cap->capture[l].len = s - cap->capture[l].init; // close capture + if (!(res = match(s, p + 1, cap))) // match failed? + cap->capture[l].len = -1; // undo capture + return res; + } + case '\0': + case '$': // (possibly) end of pattern + if (*p == 0 || (*(p + 1) == 0 && s == cap->src_end)) + return s; + // else go through + default: + { // it is a pattern item + const char *ep; // get what is next + const char *s1 = matchitem(s, p, cap, &ep); + switch (*ep) { + case '*': + { // repetition + const char *res; + if (s1 && s1 > s && (res = match(s1, p, cap))) + return res; + p = ep + 1; + goto init; + } + case '?': + { // optional + const char *res; + if (s1 && (res = match(s1, ep + 1, cap))) + return res; + p = ep + 1; + goto init; + } + case '-': + { // repetition + const char *res; + if (res = match(s, ep + 1, cap)) + return res; + else if (s1 && s1 > s) { + s = s1; + goto init; + } else + return NULL; + } + default: + if (s1) { + s = s1; + p = ep; + goto init; + } else + return NULL; + } + } + } } - -static const char *matchitem (const char *s, const char *p, struct Capture *cap, const char **ep) -{ - if (*p == ESC) { - p++; - if (isdigit((byte)*p)) { /* capture */ - int32 l = check_cap(*p, cap); - int32 len = cap->capture[l].len; - *ep = p+1; - if (cap->src_end-s >= len && memcmp(cap->capture[l].init, s, len) == 0) - return s+len; - else return NULL; - } - else if (*p == 'b') { /* balanced string */ - p++; - if (*p == 0 || *(p+1) == 0) - lua_error("unbalanced pattern"); - *ep = p+2; - return matchbalance(s, *p, *(p+1), cap); - } - else p--; /* and go through */ - } - /* "luaI_singlematch" sets "ep" (so must be called even when *s == 0) */ - return (luaI_singlematch((byte)*s, p, ep) && ssrc_end) ? - s+1 : NULL; +static void str_find() { + int32 l; + const char *s = luaL_check_lstr(1, &l); + const char *p = luaL_check_string(2); + int32 init = posrelat((int32)luaL_opt_number(3, 1), l) - 1; + struct Capture cap; + luaL_arg_check(0 <= init && init <= l, 3, "out of range"); + if (lua_getparam(4) != LUA_NOOBJECT || !strpbrk(p, SPECIALS)) { // no special characters? + const char *s2 = strstr(s + init, p); + if (s2) { + lua_pushnumber(s2 - s + 1); + lua_pushnumber(s2 - s + strlen(p)); + return; + } + } else { + int32 anchor = (*p == '^') ? (p++, 1) : 0; + const char *s1 = s + init; + cap.src_end = s + l; + do { + const char *res; + cap.level = 0; + if ((res = match(s1, p, &cap))) { + lua_pushnumber(s1 - s + 1); // start + lua_pushnumber(res - s); // end + push_captures(&cap); + return; + } + } while (s1++ < cap.src_end && !anchor); + } + lua_pushnil(); // if arrives here, it didn't find } - -static const char *match (const char *s, const char *p, struct Capture *cap) -{ - init: /* using goto's to optimize tail recursion */ - switch (*p) { - case '(': { /* start capture */ - const char *res; - if (cap->level >= MAX_CAPT) lua_error("too many captures"); - cap->capture[cap->level].init = s; - cap->capture[cap->level].len = -1; - cap->level++; - if ((res=match(s, p+1, cap)) == NULL) /* match failed? */ - cap->level--; /* undo capture */ - return res; - } - case ')': { /* end capture */ - int32 l = capture_to_close(cap); - const char *res; - cap->capture[l].len = s - cap->capture[l].init; /* close capture */ - if ((res = match(s, p+1, cap)) == NULL) /* match failed? */ - cap->capture[l].len = -1; /* undo capture */ - return res; - } - case '\0': case '$': /* (possibly) end of pattern */ - if (*p == 0 || (*(p+1) == 0 && s == cap->src_end)) - return s; - /* else go through */ - default: { /* it is a pattern item */ - const char *ep; /* get what is next */ - const char *s1 = matchitem(s, p, cap, &ep); - switch (*ep) { - case '*': { /* repetition */ - const char *res; - if (s1 && s1>s && ((res=match(s1, p, cap)) != NULL)) - return res; - p=ep+1; goto init; /* else return match(s, ep+1, cap); */ - } - case '?': { /* optional */ - const char *res; - if (s1 && ((res=match(s1, ep+1, cap)) != NULL)) - return res; - p=ep+1; goto init; /* else return match(s, ep+1, cap); */ - } - case '-': { /* repetition */ - const char *res; - if ((res = match(s, ep+1, cap)) != NULL) - return res; - else if (s1 && s1>s) { - s = s1; - goto init; /* return match(s1, p, cap); */ - } - else - return NULL; - } - default: - if (s1) { s=s1; p=ep; goto init; } /* return match(s1, ep, cap); */ - else return NULL; - } - } - } +static void add_s(lua_Object newp, Capture *cap) { + if (lua_isstring(newp)) { + const char *news = lua_getstring(newp); + int32 l = lua_strlen(newp); + int32 i; + for (i = 0; i < l; i++) { + if (news[i] != ESC) + luaL_addchar(news[i]); + else { + i++; // skip ESC + if (!isdigit((byte)news[i])) + luaL_addchar(news[i]); + else { + int32 level = check_cap(news[i], cap); + addnchar(cap->capture[level].init, cap->capture[level].len); + } + } + } + } else { // is a function + lua_Object res; + int32 status; + int32 oldbuff; + lua_beginblock(); + push_captures(cap); + // function may use buffer, so save it and create a new one + oldbuff = luaL_newbuffer(0); + status = lua_callfunction(newp); + // restore old buffer + luaL_oldbuffer(oldbuff); + if (status) { + lua_endblock(); + lua_error(NULL); + } + res = lua_getresult(1); + if (lua_isstring(res)) + addnchar(lua_getstring(res), lua_strlen(res)); + lua_endblock(); + } } - -static void str_find (void) -{ - int32 l; - const char *s = luaL_check_lstr(1, &l); - const char *p = luaL_check_string(2); - int32 init = posrelat((int32)luaL_opt_number(3, 1), l) - 1; - struct Capture cap; - luaL_arg_check(0 <= init && init <= l, 3, "out of range"); - if (lua_getparam(4) != LUA_NOOBJECT || - strpbrk(p, SPECIALS) == NULL) { /* no special characters? */ - const char *s2 = strstr(s+init, p); - if (s2) { - lua_pushnumber(s2-s+1); - lua_pushnumber(s2-s+strlen(p)); - return; - } - } - else { - int32 anchor = (*p == '^') ? (p++, 1) : 0; - const char *s1=s+init; - cap.src_end = s+l; - do { - const char *res; - cap.level = 0; - if ((res=match(s1, p, &cap)) != NULL) { - lua_pushnumber(s1-s+1); /* start */ - lua_pushnumber(res-s); /* end */ - push_captures(&cap); - return; - } - } while (s1++ src) // non empty match? + src = e; // skip it + else if (src < cap.src_end) + luaL_addchar(*src++); + else + break; + if (anchor) + break; + } + addnchar(src, cap.src_end - src); + closeandpush(); + lua_pushnumber(n); // number of substitutions } - -static void add_s (lua_Object newp, struct Capture *cap) -{ - if (lua_isstring(newp)) { - const char *news = lua_getstring(newp); - int32 l = lua_strlen(newp); - int32 i; - for (i=0; icapture[level].init, cap->capture[level].len); - } - } - } - } - else { /* is a function */ - lua_Object res; - int32 status; - int32 oldbuff; - lua_beginblock(); - push_captures(cap); - /* function may use buffer, so save it and create a new one */ - oldbuff = luaL_newbuffer(0); - status = lua_callfunction(newp); - /* restore old buffer */ - luaL_oldbuffer(oldbuff); - if (status != 0) { - lua_endblock(); - lua_error(NULL); - } - res = lua_getresult(1); - if (lua_isstring(res)) - addnchar(lua_getstring(res), lua_strlen(res)); - lua_endblock(); - } -} - - -static void str_gsub (void) -{ - int32 srcl; - const char *src = luaL_check_lstr(1, &srcl); - const char *p = luaL_check_string(2); - lua_Object newp = lua_getparam(3); - int32 max_s = (int32)luaL_opt_number(4, srcl+1); - int32 anchor = (*p == '^') ? (p++, 1) : 0; - int32 n = 0; - struct Capture cap; - luaL_arg_check(lua_isstring(newp) || lua_isfunction(newp), 3, - "string or function expected"); - luaL_resetbuffer(); - cap.src_end = src+srcl; - while (n < max_s) { - const char *e; - cap.level = 0; - e = match(src, p, &cap); - if (e) { - n++; - add_s(newp, &cap); - } - if (e && e>src) /* non empty match? */ - src = e; /* skip it */ - else if (src < cap.src_end) - luaL_addchar(*src++); - else break; - if (anchor) break; - } - addnchar(src, cap.src_end-src); - closeandpush(); - lua_pushnumber(n); /* number of substitutions */ -} - - -static void luaI_addquoted (const char *s) -{ - luaL_addchar('"'); - for (; *s; s++) { - if (strchr("\"\\\n", *s)) - luaL_addchar('\\'); - luaL_addchar(*s); - } - luaL_addchar('"'); +static void luaI_addquoted(const char *s) { + luaL_addchar('"'); + for (; *s; s++) { + if (strchr("\"\\\n", *s)) + luaL_addchar('\\'); + luaL_addchar(*s); + } + luaL_addchar('"'); } #define MAX_FORMAT 200 -static void str_format (void) -{ - int32 arg = 1; - const char *strfrmt = luaL_check_string(arg); - struct Capture cap; - cap.src_end = strfrmt+strlen(strfrmt)+1; - luaL_resetbuffer(); - while (*strfrmt) { - if (*strfrmt != '%') - luaL_addchar(*strfrmt++); - else if (*++strfrmt == '%') - luaL_addchar(*strfrmt++); /* %% */ - else { /* format item */ - char form[MAX_FORMAT]; /* store the format ('%...') */ - char *buff; - const char *initf = strfrmt; - form[0] = '%'; - cap.level = 0; - if (isdigit((byte)initf[0]) && initf[1] == '$') { - arg = initf[0] - '0'; - initf += 2; /* skip the 'n$' */ - } - arg++; - strfrmt = match(initf, "[-+ #0]*(%d*)%.?(%d*)", &cap); - if (cap.capture[0].len > 2 || cap.capture[1].len > 2) /* < 100? */ - lua_error("invalid format (width or precision too long)"); - strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */ - form[strfrmt-initf+2] = 0; - buff = luaL_openspace(1000); /* to store the formatted value */ - switch (*strfrmt++) { - case 'q': - luaI_addquoted(luaL_check_string(arg)); - continue; - case 's': { - const char *s = luaL_check_string(arg); - buff = luaL_openspace(strlen(s)); - sprintf(buff, form, s); - break; - } - case 'c': case 'd': case 'i': - sprintf(buff, form, (int)luaL_check_number(arg)); - break; - case 'o': case 'u': case 'x': case 'X': - sprintf(buff, form, (unsigned int)luaL_check_number(arg)); - break; - case 'e': case 'E': case 'f': case 'g': case 'G': - sprintf(buff, form, luaL_check_number(arg)); - break; - default: /* also treat cases 'pnLlh' */ - lua_error("invalid option in `format'"); - } - luaL_addsize(strlen(buff)); - } - } - closeandpush(); /* push the result */ +static void str_format() { + int32 arg = 1; + const char *strfrmt = luaL_check_string(arg); + struct Capture cap; + cap.src_end = strfrmt + strlen(strfrmt) + 1; + luaL_resetbuffer(); + while (*strfrmt) { + if (*strfrmt != '%') + luaL_addchar(*strfrmt++); + else if (*++strfrmt == '%') + luaL_addchar(*strfrmt++); // %% + else { // format item + char form[MAX_FORMAT]; // store the format ('%...') + char *buff; + const char *initf = strfrmt; + form[0] = '%'; + cap.level = 0; + if (isdigit((byte)initf[0]) && initf[1] == '$') { + arg = initf[0] - '0'; + initf += 2; // skip the 'n$' + } + arg++; + strfrmt = match(initf, "[-+ #0]*(%d*)%.?(%d*)", &cap); + if (cap.capture[0].len > 2 || cap.capture[1].len > 2) // < 100? + lua_error("invalid format (width or precision too long)"); + strncpy(form + 1, initf, strfrmt - initf + 1); // +1 to include conversion + form[strfrmt-initf + 2] = 0; + buff = luaL_openspace(1000); // to store the formatted value + switch (*strfrmt++) { + case 'q': + luaI_addquoted(luaL_check_string(arg)); + continue; + case 's': + { + const char *s = luaL_check_string(arg); + buff = luaL_openspace(strlen(s)); + sprintf(buff, form, s); + break; + } + case 'c': + case 'd': + case 'i': + sprintf(buff, form, (int)luaL_check_number(arg)); + break; + case 'o': + case 'u': + case 'x': + case 'X': + sprintf(buff, form, (unsigned int)luaL_check_number(arg)); + break; + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + sprintf(buff, form, luaL_check_number(arg)); + break; + default: // also treat cases 'pnLlh' + lua_error("invalid option in `format'"); + } + luaL_addsize(strlen(buff)); + } + } + closeandpush(); // push the result } - static struct luaL_reg strlib[] = { -{"strlen", str_len}, -{"strsub", str_sub}, -{"strlower", str_lower}, -{"strupper", str_upper}, -{"strrep", str_rep}, -{"format", str_format}, -{"strfind", str_find}, -{"gsub", str_gsub} + {"strlen", str_len}, + {"strsub", str_sub}, + {"strlower", str_lower}, + {"strupper", str_upper}, + {"strrep", str_rep}, + {"format", str_format}, + {"strfind", str_find}, + {"gsub", str_gsub} }; - /* ** Open string library */ -void strlib_open (void) -{ - luaL_openlib(strlib, (sizeof(strlib)/sizeof(strlib[0]))); +void strlib_open() { + luaL_openlib(strlib, (sizeof(strlib) / sizeof(strlib[0]))); } diff --git a/engine/tinygl/gl.h b/engine/tinygl/gl.h index bcf2a5d5250..0b482476e22 100644 --- a/engine/tinygl/gl.h +++ b/engine/tinygl/gl.h @@ -738,7 +738,7 @@ void tglFrustum(double left, double right, double bottom, double top, unsigned int tglGenLists(int range); int tglIsList(unsigned int list); void tglNewList(unsigned int list, int mode); -void tglEndList(void); +void tglEndList(); void tglCallList(unsigned int list); // clear @@ -752,7 +752,7 @@ void tglSelectBuffer(int size, unsigned int *buf); void tglInitNames(); void tglPushName(unsigned int name); -void tglPopName(void); +void tglPopName(); void tglLoadName(unsigned int name); // textures diff --git a/engine/tinygl/zgl.h b/engine/tinygl/zgl.h index 4aea74810aa..115ccd48b16 100644 --- a/engine/tinygl/zgl.h +++ b/engine/tinygl/zgl.h @@ -307,7 +307,7 @@ void gl_resizeImage(unsigned char *dest, int xsize_dest, int ysize_dest, void gl_resizeImageNoInterpolate(unsigned char *dest, int xsize_dest, int ysize_dest, unsigned char *src, int xsize_src, int ysize_src); -GLContext *gl_get_context(void); +GLContext *gl_get_context(); void gl_fatal_error(const char *format, ...);