Browse Source

new function `lua_vpushstr' to replace uses of `sprintf'

Roberto Ierusalimschy 23 years ago
parent
commit
dea6b6da94
15 changed files with 194 additions and 156 deletions
  1. 9 2
      lapi.c
  2. 3 31
      lauxlib.c
  3. 3 8
      lcode.c
  4. 1 2
      lcode.h
  5. 4 5
      ldblib.c
  6. 5 5
      ldebug.c
  7. 4 6
      ldo.c
  8. 50 41
      llex.c
  9. 3 3
      llex.h
  10. 76 18
      lobject.c
  11. 3 1
      lobject.h
  12. 16 21
      lparser.c
  13. 2 2
      lstate.c
  14. 5 1
      lua.h
  15. 10 10
      lundump.c

+ 9 - 2
lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 1.188 2002/05/06 15:51:41 roberto Exp roberto $
+** $Id: lapi.c,v 1.189 2002/05/06 19:05:10 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -354,6 +354,13 @@ LUA_API void lua_pushstring (lua_State *L, const char *s) {
 }
 
 
+LUA_API void  lua_vpushstr (lua_State *L, const char *fmt, va_list argp) {
+  lua_lock(L);
+  luaO_vpushstr(L, fmt, argp);
+  lua_unlock(L);
+}
+
+
 LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
   Closure *cl;
   lua_lock(L);
@@ -514,7 +521,7 @@ LUA_API void lua_setmetatable (lua_State *L, int objindex) {
       uvalue(obj)->uv.metatable = hvalue(mt);
       break;
     default:
-      luaO_verror(L, "cannot change the meta table of a %.20s",
+      luaO_verror(L, "cannot change the meta table of a %s",
                   luaT_typenames[ttype(obj)]);
   }
   lua_unlock(L);

+ 3 - 31
lauxlib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lauxlib.c,v 1.67 2002/05/01 20:40:42 roberto Exp roberto $
+** $Id: lauxlib.c,v 1.68 2002/05/06 19:05:10 roberto Exp roberto $
 ** Auxiliary functions for building Lua libraries
 ** See Copyright Notice in lua.h
 */
@@ -142,38 +142,10 @@ LUALIB_API void luaL_opennamedlib (lua_State *L, const char *libname,
 }
 
 
-static void vstr (lua_State *L, const char *fmt, va_list argp) {
-  luaL_Buffer b;
-  luaL_buffinit(L, &b);
-  for (;;) {
-    const char *e = strchr(fmt, '%');
-    if (e == NULL) break;
-    luaL_addlstring(&b, fmt, e-fmt);
-    switch (*(e+1)) {
-      case 's':
-        luaL_addstring(&b, va_arg(argp, char *));
-        break;
-      case 'd':
-        lua_pushnumber(L, va_arg(argp, int));
-        luaL_addvalue (&b);
-        break;
-      case '%':
-        luaL_putchar(&b, '%');
-        break;
-      default:
-        lua_error(L, "invalid format option");
-    }
-    fmt = e+2;
-  }
-  luaL_addstring(&b, fmt);
-  luaL_pushresult(&b);
-}
-
-
 LUALIB_API void luaL_vstr (lua_State *L, const char *fmt, ...) {
   va_list argp;
   va_start(argp, fmt);
-  vstr(L, fmt, argp);
+  lua_vpushstr(L, fmt, argp);
   va_end(argp);
 }
 
@@ -181,7 +153,7 @@ LUALIB_API void luaL_vstr (lua_State *L, const char *fmt, ...) {
 LUALIB_API int luaL_verror (lua_State *L, const char *fmt, ...) {
   va_list argp;
   va_start(argp, fmt);
-  vstr(L, fmt, argp);
+  lua_vpushstr(L, fmt, argp);
   va_end(argp);
   return lua_errorobj(L);
 }

+ 3 - 8
lcode.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lcode.c,v 1.97 2002/04/24 20:07:46 roberto Exp roberto $
+** $Id: lcode.c,v 1.98 2002/05/06 15:51:41 roberto Exp roberto $
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -23,11 +23,6 @@
 #define hasjumps(e)	((e)->t != (e)->f)
 
 
-void luaK_error (LexState *ls, const char *msg) {
-  luaX_error(ls, msg, ls->t.token);
-}
-
-
 void luaK_nil (FuncState *fs, int from, int n) {
   Instruction *previous;
   if (fs->pc > fs->lasttarget &&  /* no jumps to current position? */
@@ -67,7 +62,7 @@ static void luaK_fixjump (FuncState *fs, int pc, int dest) {
   else {  /* jump is relative to position following jump instruction */
     int offset = dest-(pc+1);
     if (abs(offset) > MAXARG_sBx)
-      luaK_error(fs->ls, "control structure too long");
+      luaX_syntaxerror(fs->ls, "control structure too long");
     SETARG_sBx(*jmp, offset);
   }
 }
@@ -182,7 +177,7 @@ static void luaK_checkstack (FuncState *fs, int n) {
   int newstack = fs->freereg + n;
   if (newstack > fs->f->maxstacksize) {
     if (newstack >= MAXSTACK)
-      luaK_error(fs->ls, "function or expression too complex");
+      luaX_syntaxerror(fs->ls, "function or expression too complex");
     fs->f->maxstacksize = cast(lu_byte, newstack);
   }
 }

+ 1 - 2
lcode.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lcode.h,v 1.31 2002/04/09 18:49:30 roberto Exp roberto $
+** $Id: lcode.h,v 1.32 2002/04/24 20:07:46 roberto Exp roberto $
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -41,7 +41,6 @@ typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_NOUNOPR } UnOpr;
 
 #define luaK_codeAsBx(fs,o,A,sBx)	luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
 
-void luaK_error (LexState *ls, const char *msg);
 int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
 int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
 void luaK_nil (FuncState *fs, int from, int n);

+ 4 - 5
ldblib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldblib.c,v 1.49 2002/05/01 20:40:42 roberto Exp roberto $
+** $Id: ldblib.c,v 1.50 2002/05/06 19:05:10 roberto Exp roberto $
 ** Interface from Lua to its debug API
 ** See Copyright Notice in lua.h
 */
@@ -34,7 +34,6 @@ static void settabsi (lua_State *L, const char *i, int v) {
 static int getinfo (lua_State *L) {
   lua_Debug ar;
   const char *options = luaL_opt_string(L, 2, "flnSu");
-  char buff[20];
   if (lua_isnumber(L, 1)) {
     if (!lua_getstack(L, (int)(lua_tonumber(L, 1)), &ar)) {
       lua_pushnil(L);  /* level out of range */
@@ -42,9 +41,9 @@ static int getinfo (lua_State *L) {
     }
   }
   else if (lua_isfunction(L, 1)) {
+    luaL_vstr(L, ">%s", options);
+    options = lua_tostring(L, -1);
     lua_pushvalue(L, 1);
-    sprintf(buff, ">%.10s", options);
-    options = buff;
   }
   else
     return luaL_argerror(L, 1, "function or level expected");
@@ -170,7 +169,7 @@ static int setlinehook (lua_State *L) {
 static int debug (lua_State *L) {
   for (;;) {
     char buffer[250];
-    fprintf(stderr, "lua_debug> ");
+    fputs("lua_debug> ", stderr);
     if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
         strcmp(buffer, "cont\n") == 0)
       return 0;

+ 5 - 5
ldebug.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.c,v 1.110 2002/04/24 20:07:46 roberto Exp roberto $
+** $Id: ldebug.c,v 1.111 2002/05/02 13:06:20 roberto Exp roberto $
 ** Debug Interface
 ** See Copyright Notice in lua.h
 */
@@ -487,10 +487,10 @@ void luaG_typeerror (lua_State *L, const TObject *o, const char *op) {
   if (isinstack(L->ci, o))
     kind = getobjname(L, L->ci, o - L->ci->base, &name);
   if (kind)
-    luaO_verror(L, "attempt to %.30s %.20s `%.40s' (a %.10s value)",
+    luaO_verror(L, "attempt to %s %s `%s' (a %s value)",
                 op, kind, name, t);
   else
-    luaO_verror(L, "attempt to %.30s a %.10s value", op, t);
+    luaO_verror(L, "attempt to %s a %s value", op, t);
 }
 
 
@@ -513,8 +513,8 @@ void luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2) {
   const char *t1 = luaT_typenames[ttype(p1)];
   const char *t2 = luaT_typenames[ttype(p2)];
   if (t1[2] == t2[2])
-    luaO_verror(L, "attempt to compare two %.10s values", t1);
+    luaO_verror(L, "attempt to compare two %s values", t1);
   else
-    luaO_verror(L, "attempt to compare %.10s with %.10s", t1, t2);
+    luaO_verror(L, "attempt to compare %s with %s", t1, t2);
 }
 

+ 4 - 6
ldo.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.c,v 1.172 2002/04/22 14:40:50 roberto Exp roberto $
+** $Id: ldo.c,v 1.173 2002/05/01 20:40:42 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -436,8 +436,7 @@ int luaD_protectedparser (lua_State *L, ZIO *z, int bin) {
   }
   else {
     setobj(L->top++, &p.err);
-    if (status == LUA_ERRRUN)  /* an error occurred: correct error code */
-      status = LUA_ERRSYNTAX;
+    lua_assert(status != LUA_ERRRUN);
   }
   lua_unlock(L);
   return status;
@@ -459,9 +458,8 @@ static void message (lua_State *L, const TObject *msg, int nofunc) {
   }
   else {  /* call error function */
     setobj(L->top, m);
-    incr_top(L);
-    setobj(L->top, msg);
-    incr_top(L);
+    setobj(L->top + 1, msg);
+    L->top += 2;
     luaD_call(L, L->top - 2, 1);
     setobj(m, L->top - 1);
   }

+ 50 - 41
llex.c

@@ -1,5 +1,5 @@
 /*
-** $Id: llex.c,v 1.98 2002/03/08 19:07:01 roberto Exp roberto $
+** $Id: llex.c,v 1.99 2002/03/08 19:25:24 roberto Exp roberto $
 ** Lexical Analyzer
 ** See Copyright Notice in lua.h
 */
@@ -11,6 +11,7 @@
 
 #include "lua.h"
 
+#include "ldo.h"
 #include "llex.h"
 #include "lobject.h"
 #include "lparser.h"
@@ -29,9 +30,9 @@ static const char *const token2string [] = {
     "and", "break", "do", "else", "elseif",
     "end", "false", "for", "function", "global", "if",
     "in", "local", "nil", "not", "or", "repeat",
-    "return", "then", "true", "until", "while", "",
+    "return", "then", "true", "until", "while", "*name",
     "..", "...", "==", ">=", "<=", "~=",
-    "", "", "<eof>"
+    "*number", "*string", "<eof>"
 };
 
 
@@ -50,53 +51,57 @@ void luaX_init (lua_State *L) {
 
 void luaX_checklimit (LexState *ls, int val, int limit, const char *msg) {
   if (val > limit) {
-    char buff[90];
-    sprintf(buff, "too many %.40s (limit=%d)", msg, limit);
-    luaX_error(ls, buff, ls->t.token);
+    msg = luaO_pushstr(ls->L, "too many %s (limit=%d)", msg, limit);
+    luaX_syntaxerror(ls, msg);
   }
 }
 
 
-static void luaX_syntaxerror (LexState *ls, const char *s,
-                              const char *token) {
+static void luaX_error (LexState *ls, const char *s, const char *token) {
+  lua_State *L = ls->L;
   char buff[MAXSRC];
   luaO_chunkid(buff, getstr(ls->source), MAXSRC);
-  luaO_verror(ls->L,
-              "%.99s;\n  last token read: `%.30s' at line %d in %.80s",
-              s, token, ls->linenumber, buff);
+  luaO_pushstr(L, "%s;\n  last token read: `%s' at line %d in %s",
+                        s, token, ls->linenumber, buff);
+  luaD_errorobj(L, L->top - 1, LUA_ERRSYNTAX);
 }
 
 
-void luaX_token2str (int token, char *s) {
-  if (token < FIRST_RESERVED) {
-    lua_assert(token == (char)token);
-    s[0] = (char)token;
-    s[1] = '\0';
+void luaX_syntaxerror (LexState *ls, const char *msg) {
+  const char *lasttoken;
+  switch (ls->t.token) {
+    case TK_NAME:
+      lasttoken = luaO_pushstr(ls->L, "%s", getstr(ls->t.seminfo.ts));
+      break;
+    case TK_STRING:
+      lasttoken = luaO_pushstr(ls->L, "\"%s\"", getstr(ls->t.seminfo.ts));
+      break;
+    case TK_NUMBER:
+      lasttoken = luaO_pushstr(ls->L, "%f", ls->t.seminfo.r);
+      break;
+    default:
+      lasttoken = luaX_token2str(ls, ls->t.token);
+      break;
   }
-  else
-    strcpy(s, token2string[token-FIRST_RESERVED]);
+  luaX_error(ls, msg, lasttoken);
 }
 
 
-static char *token2str_all (LexState *ls, int token, char *s) {
-  luaX_token2str(token, s);
-  if (s[0] == '\0')
-    return cast(char *, G(ls->L)->Mbuffer);
+const char *luaX_token2str (LexState *ls, int token) {
+  if (token < FIRST_RESERVED) {
+    lua_assert(token == (char)token);
+    return luaO_pushstr(ls->L, "%c", token);
+  }
   else
-    return s;
-}
-
-
-void luaX_error (LexState *ls, const char *s, int token) {
-  char buff[TOKEN_LEN];
-  luaX_syntaxerror(ls, s, token2str_all(ls, token, buff));
+    return token2string[token-FIRST_RESERVED];
 }
 
 
-static void luaX_invalidchar (LexState *ls, int c) {
-  char buff[8];
-  sprintf(buff, "0x%02X", (unsigned char)c);
-  luaX_syntaxerror(ls, "invalid control char", buff);
+static void luaX_lexerror (LexState *ls, const char *s, int token) {
+  if (token == TK_EOS)
+    luaX_error(ls, s, luaX_token2str(ls, token));
+  else
+    luaX_error(ls, s, cast(char *, G(ls->L)->Mbuffer));
 }
 
 
@@ -171,7 +176,7 @@ static void read_number (LexState *LS, int comma, SemInfo *seminfo) {
     if (LS->current == '.') {
       save_and_next(L, LS, l);
       save(L, '\0', l);
-      luaX_error(LS,
+      luaX_lexerror(LS,
                  "ambiguous syntax (decimal point x string concatenation)",
                  TK_NUMBER);
     }
@@ -191,7 +196,7 @@ static void read_number (LexState *LS, int comma, SemInfo *seminfo) {
   }
   save(L, '\0', l);
   if (!luaO_str2d(cast(char *, G(L)->Mbuffer), &seminfo->r))
-    luaX_error(LS, "malformed number", TK_NUMBER);
+    luaX_lexerror(LS, "malformed number", TK_NUMBER);
 }
 
 
@@ -209,7 +214,7 @@ static void read_long_string (LexState *LS, SemInfo *seminfo) {
     switch (LS->current) {
       case EOZ:
         save(L, '\0', l);
-        luaX_error(LS, (seminfo) ? "unfinished long string" :
+        luaX_lexerror(LS, (seminfo) ? "unfinished long string" :
                                    "unfinished long comment", TK_EOS);
         break;  /* to avoid warnings */
       case '[':
@@ -251,10 +256,13 @@ static void read_string (LexState *LS, int del, SemInfo *seminfo) {
   while (LS->current != del) {
     checkbuffer(L, l);
     switch (LS->current) {
-      case EOZ:  case '\n':
+      case EOZ:
+        save(L, '\0', l);
+        luaX_lexerror(LS, "unfinished string", TK_EOS);
+        break;  /* to avoid warnings */
+      case '\n':
         save(L, '\0', l);
-        luaX_error(LS, "unfinished string",
-                       (LS->current == EOZ) ? TK_EOS : TK_STRING);
+        luaX_lexerror(LS, "unfinished string", TK_STRING);
         break;  /* to avoid warnings */
       case '\\':
         next(LS);  /* do not save the `\' */
@@ -279,7 +287,7 @@ static void read_string (LexState *LS, int del, SemInfo *seminfo) {
               } while (++i<3 && isdigit(LS->current));
               if (c > UCHAR_MAX) {
                 save(L, '\0', l);
-                luaX_error(LS, "escape sequence too large", TK_STRING);
+                luaX_lexerror(LS, "escape sequence too large", TK_STRING);
               }
               save(L, c, l);
             }
@@ -389,7 +397,8 @@ int luaX_lex (LexState *LS, SemInfo *seminfo) {
         else {
           int c = LS->current;
           if (iscntrl(c))
-            luaX_invalidchar(LS, c);
+            luaX_error(LS, "invalid control char",
+                           luaO_pushstr(LS->L, "char(%d)", c));
           next(LS);
           return c;  /* single-char tokens (+ - / ...) */
         }

+ 3 - 3
llex.h

@@ -1,5 +1,5 @@
 /*
-** $Id: llex.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
+** $Id: llex.h,v 1.42 2002/02/08 22:42:41 roberto Exp roberto $
 ** Lexical Analyzer
 ** See Copyright Notice in lua.h
 */
@@ -65,8 +65,8 @@ void luaX_init (lua_State *L);
 void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source);
 int luaX_lex (LexState *LS, SemInfo *seminfo);
 void luaX_checklimit (LexState *ls, int val, int limit, const char *msg);
-void luaX_error (LexState *ls, const char *s, int token);
-void luaX_token2str (int token, char *s);
+void luaX_syntaxerror (LexState *ls, const char *s);
+const char *luaX_token2str (LexState *ls, int token);
 
 
 #endif

+ 76 - 18
lobject.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lobject.c,v 1.77 2002/04/22 14:40:23 roberto Exp roberto $
+** $Id: lobject.c,v 1.78 2002/05/06 15:51:41 roberto Exp roberto $
 ** Some generic functions over Lua objects
 ** See Copyright Notice in lua.h
 */
@@ -16,6 +16,8 @@
 #include "lmem.h"
 #include "lobject.h"
 #include "lstate.h"
+#include "lstring.h"
+#include "lvm.h"
 
 
 
@@ -89,17 +91,72 @@ int luaO_str2d (const char *s, lua_Number *result) {
 }
 
 
-/* maximum length of a string format for `luaO_verror' */
-#define MAX_VERROR	280
 
-/* this function needs to handle only '%d' and '%.XXs' formats */
+static void pushstr (lua_State *L, const char *str) {
+  setsvalue(L->top, luaS_new(L, str));
+  incr_top(L);
+}
+
+
+/* this function handles only `%d', `%c', %f, and `%s' formats */
+const char *luaO_vpushstr (lua_State *L, const char *fmt, va_list argp) {
+  int n = 0;
+  for (;;) {
+    const char *e = strchr(fmt, '%');
+    if (e == NULL) break;
+    setsvalue(L->top, luaS_newlstr(L, fmt, e-fmt));
+    incr_top(L);
+    switch (*(e+1)) {
+      case 's':
+        pushstr(L, va_arg(argp, char *));
+        break;
+      case 'c': {
+        char buff[2];
+        buff[0] = va_arg(argp, int);
+        buff[1] = '\0';
+        pushstr(L, buff);
+        break;
+      }
+      case 'd':
+        setnvalue(L->top, va_arg(argp, int));
+        incr_top(L);
+        break;
+      case 'f':
+        setnvalue(L->top, va_arg(argp, lua_Number));
+        incr_top(L);
+        break;
+      case '%':
+        pushstr(L, "%");
+        break;
+      default: lua_assert(0);
+    }
+    n += 2;
+    fmt = e+2;
+  }
+  pushstr(L, fmt);
+  luaV_strconc(L, n+1, L->top - L->ci->base - 1);
+  L->top -= n;
+  return svalue(L->top - 1);
+}
+
+
+const char *luaO_pushstr (lua_State *L, const char *fmt, ...) {
+  const char *msg;
+  va_list argp;
+  va_start(argp, fmt);
+  msg = luaO_vpushstr(L, fmt, argp);
+  va_end(argp);
+  return msg;
+}
+
+
 void luaO_verror (lua_State *L, const char *fmt, ...) {
+  const char *msg;
   va_list argp;
-  char buff[MAX_VERROR];  /* to hold formatted message */
   va_start(argp, fmt);
-  vsprintf(buff, fmt, argp);
+  msg = luaO_vpushstr(L, fmt, argp);
   va_end(argp);
-  luaD_runerror(L, buff);
+  luaD_runerror(L, msg);
 }
 
 
@@ -108,31 +165,32 @@ void luaO_chunkid (char *out, const char *source, int bufflen) {
     strncpy(out, source+1, bufflen);  /* remove first char */
     out[bufflen-1] = '\0';  /* ensures null termination */
   }
-  else {
+  else {  /* out = "file `source'", or "file `...source'" */
     if (*source == '@') {
       int l;
       source++;  /* skip the `@' */
-      bufflen -= sizeof("file `...%s'");
+      bufflen -= sizeof(" file `...' ");
       l = strlen(source);
+      strcpy(out, "file `");
       if (l>bufflen) {
         source += (l-bufflen);  /* get last part of file name */
-        sprintf(out, "file `...%.99s'", source);
+        strcat(out, "...");
       }
-      else
-        sprintf(out, "file `%.99s'", source);
+      strcat(out, source);
+      strcat(out, "'");
     }
     else {
       int len = strcspn(source, "\n");  /* stop at first newline */
-      bufflen -= sizeof("string \"%.*s...\"");
+      bufflen -= sizeof(" string \"...\" ");
       if (len > bufflen) len = bufflen;
+      strcpy(out, "string \"");
       if (source[len] != '\0') {  /* must truncate? */
-        strcpy(out, "string \"");
-        out += strlen(out);
-        strncpy(out, source, len);
-        strcpy(out+len, "...\"");
+        strncat(out, source, len);
+        strcat(out, "...");
       }
       else
-        sprintf(out, "string \"%.99s\"", source);
+        strcat(out, source);
+      strcat(out, "\"");
     }
   }
 }

+ 3 - 1
lobject.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lobject.h,v 1.129 2002/04/05 18:54:31 roberto Exp roberto $
+** $Id: lobject.h,v 1.130 2002/05/06 15:51:41 roberto Exp roberto $
 ** Type definitions for Lua objects
 ** See Copyright Notice in lua.h
 */
@@ -250,6 +250,8 @@ void *luaO_openspaceaux (lua_State *L, size_t n);
 int luaO_equalObj (const TObject *t1, const TObject *t2);
 int luaO_str2d (const char *s, lua_Number *result);
 
+const char *luaO_vpushstr (lua_State *L, const char *fmt, va_list argp);
+const char *luaO_pushstr (lua_State *L, const char *fmt, ...);
 void luaO_verror (lua_State *L, const char *fmt, ...);
 void luaO_chunkid (char *out, const char *source, int len);
 

+ 16 - 21
lparser.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.c,v 1.177 2002/04/22 14:38:52 roberto Exp roberto $
+** $Id: lparser.c,v 1.178 2002/04/24 20:07:46 roberto Exp roberto $
 ** Lua Parser
 ** See Copyright Notice in lua.h
 */
@@ -66,10 +66,8 @@ static void lookahead (LexState *ls) {
 
 
 static void error_expected (LexState *ls, int token) {
-  char buff[30], t[TOKEN_LEN];
-  luaX_token2str(token, t);
-  sprintf(buff, "`%.10s' expected", t);
-  luaK_error(ls, buff);
+  luaX_syntaxerror(ls,
+         luaO_pushstr(ls->L, "`%s' expected", luaX_token2str(ls, token)));
 }
 
 
@@ -80,7 +78,7 @@ static void check (LexState *ls, int c) {
 }
 
 
-#define check_condition(ls,c,msg)	{ if (!(c)) luaK_error(ls, msg); }
+#define check_condition(ls,c,msg)	{ if (!(c)) luaX_syntaxerror(ls, msg); }
 
 
 static int optional (LexState *ls, int c) {
@@ -97,13 +95,9 @@ static void check_match (LexState *ls, int what, int who, int where) {
     if (where == ls->linenumber)
       error_expected(ls, what);
     else {
-      char buff[70];
-      char t_what[TOKEN_LEN], t_who[TOKEN_LEN];
-      luaX_token2str(what, t_what);
-      luaX_token2str(who, t_who);
-      sprintf(buff, "`%.10s' expected (to close `%.10s' at line %d)",
-              t_what, t_who, where);
-      luaK_error(ls, buff);
+      luaX_syntaxerror(ls, luaO_pushstr(ls->L,
+             "`%s' expected (to close `%s' at line %d)",
+              luaX_token2str(ls, what), luaX_token2str(ls, who), where));
     }
   }
   next(ls);
@@ -256,7 +250,7 @@ static int singlevar_aux (FuncState *fs, TString *n, expdesc *var, int nd) {
       if (var->k == VGLOBAL) {
         if (k == VNIL && nd && fs->defaultglob != NO_REG) {
           if (fs->defaultglob == NO_REG1)
-            luaK_error(fs->ls, "undeclared global");
+            luaX_syntaxerror(fs->ls, "undeclared global");
           init_exp(var, VLOCAL, fs->defaultglob);
           k = VGLOBAL;  /* now there is a declaration */
         }
@@ -479,7 +473,7 @@ static void funcargs (LexState *ls, expdesc *f) {
   switch (ls->t.token) {
     case '(': {  /* funcargs -> `(' [ explist1 ] `)' */
       if (line != ls->lastline)
-        luaK_error(ls, "ambiguous syntax (function call x new statement)");
+        luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)");
       next(ls);
       if (ls->t.token == ')')  /* arg list is empty? */
         args.k = VVOID;
@@ -500,7 +494,7 @@ static void funcargs (LexState *ls, expdesc *f) {
       break;
     }
     default: {
-      luaK_error(ls, "function arguments expected");
+      luaX_syntaxerror(ls, "function arguments expected");
       return;
     }
   }
@@ -657,9 +651,10 @@ static void prefixexp (LexState *ls, expdesc *v) {
   /* prefixexp -> NAME | '(' expr ')' */
   switch (ls->t.token) {
     case '(': {
+      int line = ls->linenumber;
       next(ls);
       expr(ls, v);
-      check(ls, ')');
+      check_match(ls, ')', '(', line);
       luaK_dischargevars(ls->fs, v);
       return;
     }
@@ -676,7 +671,7 @@ static void prefixexp (LexState *ls, expdesc *v) {
       return;
     }
     default: {
-      luaK_error(ls, "unexpected symbol");
+      luaX_syntaxerror(ls, "unexpected symbol");
       return;
     }
   }
@@ -1070,7 +1065,7 @@ static void forstat (LexState *ls, int line) {
   switch (ls->t.token) {
     case '=': fornum(ls, varname, line); break;
     case ',': case TK_IN: forlist(ls, varname); break;
-    default: luaK_error(ls, "`=' or `in' expected");
+    default: luaX_syntaxerror(ls, "`=' or `in' expected");
   }
   check_match(ls, TK_END, TK_FOR, line);
   leaveblock(fs);
@@ -1245,7 +1240,7 @@ static void breakstat (LexState *ls) {
     bl = bl->previous;
   }
   if (!bl)
-    luaK_error(ls, "no loop to break");
+    luaX_syntaxerror(ls, "no loop to break");
   if (upval)
     luaK_codeABC(fs, OP_CLOSE, bl->nactloc, 0, 0);
   luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
@@ -1314,7 +1309,7 @@ static void parlist (LexState *ls) {
       switch (ls->t.token) {
         case TK_DOTS: dots = 1; break;
         case TK_NAME: new_localvar(ls, str_checkname(ls), nparams++); break;
-        default: luaK_error(ls, "<name> or `...' expected");
+        default: luaX_syntaxerror(ls, "<name> or `...' expected");
       }
       next(ls);
     } while (!dots && optional(ls, ','));

+ 2 - 2
lstate.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.c,v 1.91 2002/04/23 15:04:39 roberto Exp roberto $
+** $Id: lstate.c,v 1.92 2002/05/01 20:40:42 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -30,7 +30,7 @@ static void close_state (lua_State *L);
 ** call `lua_setpanicf'
 */
 static int default_panic (lua_State *L) {
-  fprintf(stderr, "unable to recover; exiting\n");
+  fputs("unable to recover; exiting\n", stderr);
   return 0;
 }
 

+ 5 - 1
lua.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lua.h,v 1.130 2002/05/01 20:48:12 roberto Exp roberto $
+** $Id: lua.h,v 1.131 2002/05/06 19:05:10 roberto Exp roberto $
 ** Lua - An Extensible Extension Language
 ** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
 ** e-mail: [email protected]
@@ -12,6 +12,9 @@
 #define lua_h
 
 
+/* definition of `va_list' */
+#include <stdarg.h>
+
 /* definition of `size_t' */
 #include <stddef.h>
 
@@ -141,6 +144,7 @@ LUA_API void  lua_pushnil (lua_State *L);
 LUA_API void  lua_pushnumber (lua_State *L, lua_Number n);
 LUA_API void  lua_pushlstring (lua_State *L, const char *s, size_t len);
 LUA_API void  lua_pushstring (lua_State *L, const char *s);
+LUA_API void  lua_vpushstr (lua_State *L, const char *fmt, va_list argp);
 LUA_API void  lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
 LUA_API void  lua_pushboolean (lua_State *L, int b);
 LUA_API void  lua_pushudataval (lua_State *L, void *p);

+ 10 - 10
lundump.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lundump.c,v 1.44 2001/11/28 20:13:13 roberto Exp roberto $
+** $Id: lundump.c,v 1.45 2002/03/25 17:47:14 roberto Exp roberto $
 ** load pre-compiled Lua chunks
 ** See Copyright Notice in lua.h
 */
@@ -27,7 +27,7 @@ static const char* ZNAME (ZIO* Z)
 
 static void unexpectedEOZ (lua_State* L, ZIO* Z)
 {
- luaO_verror(L,"unexpected end of file in `%.99s'",ZNAME(Z));
+ luaO_verror(L,"unexpected end of file in `%s'",ZNAME(Z));
 }
 
 static int ezgetc (lua_State* L, ZIO* Z)
@@ -157,7 +157,7 @@ static void LoadConstants (lua_State* L, Proto* f, ZIO* Z, int swap)
 	tsvalue(o)=LoadString(L,Z,swap);
 	break;
    default:
-	luaO_verror(L,"bad constant type (%d) in `%.99s'",ttype(o),ZNAME(Z));
+	luaO_verror(L,"bad constant type (%d) in `%s'",ttype(o),ZNAME(Z));
 	break;
   }
  }
@@ -181,7 +181,7 @@ static Proto* LoadFunction (lua_State* L, TString* p, ZIO* Z, int swap)
  LoadConstants(L,f,Z,swap);
  LoadCode(L,f,Z,swap);
 #ifndef TRUST_BINARIES
- if (!luaG_checkcode(f)) luaO_verror(L,"bad code in `%.99s'",ZNAME(Z));
+ if (!luaG_checkcode(f)) luaO_verror(L,"bad code in `%s'",ZNAME(Z));
 #endif
  return f;
 }
@@ -191,14 +191,14 @@ static void LoadSignature (lua_State* L, ZIO* Z)
  const char* s=LUA_SIGNATURE;
  while (*s!=0 && ezgetc(L,Z)==*s)
   ++s;
- if (*s!=0) luaO_verror(L,"bad signature in `%.99s'",ZNAME(Z));
+ if (*s!=0) luaO_verror(L,"bad signature in `%s'",ZNAME(Z));
 }
 
 static void TestSize (lua_State* L, int s, const char* what, ZIO* Z)
 {
  int r=LoadByte(L,Z);
  if (r!=s)
-  luaO_verror(L,"virtual machine mismatch in `%.99s':\n"
+  luaO_verror(L,"virtual machine mismatch in `%s':\n"
 	"  size of %.20s is %d but read %d",ZNAME(Z),what,s,r);
 }
 
@@ -212,11 +212,11 @@ static int LoadHeader (lua_State* L, ZIO* Z)
  LoadSignature(L,Z);
  version=LoadByte(L,Z);
  if (version>VERSION)
-  luaO_verror(L,"`%.99s' too new:\n"
+  luaO_verror(L,"`%s' too new:\n"
 	"  read version %d.%d; expected at most %d.%d",
 	ZNAME(Z),V(version),V(VERSION));
  if (version<VERSION0)			/* check last major change */
-  luaO_verror(L,"`%.99s' too old:\n"
+  luaO_verror(L,"`%s' too old:\n"
 	"  read version %d.%d; expected at least %d.%d",
 	ZNAME(Z),V(version),V(VERSION));
  swap=(luaU_endianness()!=LoadByte(L,Z));	/* need to swap bytes? */
@@ -230,7 +230,7 @@ static int LoadHeader (lua_State* L, ZIO* Z)
  TESTSIZE(sizeof(lua_Number), "number");
  x=LoadNumber(L,Z,swap);
  if ((long)x!=(long)tx)		/* disregard errors in last bits of fraction */
-  luaO_verror(L,"unknown number format in `%.99s':\n"
+  luaO_verror(L,"unknown number format in `%s':\n"
       "  read " LUA_NUMBER_FMT "; expected " LUA_NUMBER_FMT,
       ZNAME(Z),x,tx);
  return swap;
@@ -248,7 +248,7 @@ Proto* luaU_undump (lua_State* L, ZIO* Z)
 {
  Proto* f=LoadChunk(L,Z);
  if (zgetc(Z)!=EOZ)
-  luaO_verror(L,"`%.99s' apparently contains more than one chunk",ZNAME(Z));
+  luaO_verror(L,"`%s' apparently contains more than one chunk",ZNAME(Z));
  return f;
 }