diff options
-rw-r--r-- | lapi.c | 4 | ||||
-rw-r--r-- | lauxlib.c | 34 | ||||
-rw-r--r-- | lbaselib.c | 2 | ||||
-rw-r--r-- | lgc.c | 8 | ||||
-rw-r--r-- | lstate.c | 4 | ||||
-rw-r--r-- | lstate.h | 2 | ||||
-rw-r--r-- | ltests.c | 60 | ||||
-rw-r--r-- | lua.h | 4 | ||||
-rw-r--r-- | manual/manual.of | 26 | ||||
-rw-r--r-- | testes/all.lua | 10 | ||||
-rw-r--r-- | testes/api.lua | 12 | ||||
-rw-r--r-- | testes/gc.lua | 11 |
12 files changed, 79 insertions, 98 deletions
@@ -1286,9 +1286,9 @@ void lua_setwarnf (lua_State *L, lua_WarnFunction f, void *ud) { | |||
1286 | } | 1286 | } |
1287 | 1287 | ||
1288 | 1288 | ||
1289 | void lua_warning (lua_State *L, const char *msg) { | 1289 | void lua_warning (lua_State *L, const char *msg, int tocont) { |
1290 | lua_lock(L); | 1290 | lua_lock(L); |
1291 | luaE_warning(L, msg); | 1291 | luaE_warning(L, msg, tocont); |
1292 | lua_unlock(L); | 1292 | lua_unlock(L); |
1293 | } | 1293 | } |
1294 | 1294 | ||
@@ -987,33 +987,29 @@ static int panic (lua_State *L) { | |||
987 | 987 | ||
988 | 988 | ||
989 | /* | 989 | /* |
990 | ** checks whether 'message' ends with end-of-line | 990 | ** Emit a warning. '*previoustocont' signals whether previous message |
991 | ** (and therefore is the last part of a warning) | 991 | ** was to be continued by the current one. |
992 | */ | 992 | */ |
993 | static int islast (const char *message) { | 993 | static void warnf (void *ud, const char *message, int tocont) { |
994 | size_t len = strlen(message); | 994 | int *previoustocont = (int *)ud; |
995 | return (len > 0 && message[len - 1] == '\n'); | 995 | if (!*previoustocont) /* previous message was the last? */ |
996 | } | 996 | lua_writestringerror("%s", "Lua warning: "); /* start a new warning */ |
997 | 997 | lua_writestringerror("%s", message); /* write message */ | |
998 | 998 | if (!tocont) /* is this the last part? */ | |
999 | /* | 999 | lua_writestringerror("%s", "\n"); /* finish message with end-of-line */ |
1000 | ** Emit a warning. If '*pud' is NULL, previous message was to be | 1000 | *previoustocont = tocont; |
1001 | ** continued by the current one. | ||
1002 | */ | ||
1003 | static void warnf (void **pud, const char *message) { | ||
1004 | if (*pud == NULL) /* previous message was not the last? */ | ||
1005 | lua_writestringerror("%s", message); | ||
1006 | else /* start a new warning */ | ||
1007 | lua_writestringerror("Lua warning: %s", message); | ||
1008 | *pud = (islast(message)) ? pud : NULL; | ||
1009 | } | 1001 | } |
1010 | 1002 | ||
1011 | 1003 | ||
1012 | LUALIB_API lua_State *luaL_newstate (void) { | 1004 | LUALIB_API lua_State *luaL_newstate (void) { |
1013 | lua_State *L = lua_newstate(l_alloc, NULL); | 1005 | lua_State *L = lua_newstate(l_alloc, NULL); |
1014 | if (L) { | 1006 | if (L) { |
1007 | int *previoustocont; /* space for warning state */ | ||
1015 | lua_atpanic(L, &panic); | 1008 | lua_atpanic(L, &panic); |
1016 | lua_setwarnf(L, warnf, L); | 1009 | previoustocont = (int *)lua_newuserdatauv(L, sizeof(int), 0); |
1010 | luaL_ref(L, LUA_REGISTRYINDEX); /* make sure it won't be collected */ | ||
1011 | *previoustocont = 0; /* next message starts a new warning */ | ||
1012 | lua_setwarnf(L, warnf, previoustocont); | ||
1017 | } | 1013 | } |
1018 | return L; | 1014 | return L; |
1019 | } | 1015 | } |
@@ -45,7 +45,7 @@ static int luaB_print (lua_State *L) { | |||
45 | 45 | ||
46 | static int luaB_warn (lua_State *L) { | 46 | static int luaB_warn (lua_State *L) { |
47 | const char *msg = luaL_checkstring(L, 1); | 47 | const char *msg = luaL_checkstring(L, 1); |
48 | lua_warning(L, msg); | 48 | lua_warning(L, msg, lua_toboolean(L, 2)); |
49 | return 0; | 49 | return 0; |
50 | } | 50 | } |
51 | 51 | ||
@@ -832,7 +832,7 @@ static void GCTM (lua_State *L) { | |||
832 | lua_assert(!g->gcemergency); | 832 | lua_assert(!g->gcemergency); |
833 | setgcovalue(L, &v, udata2finalize(g)); | 833 | setgcovalue(L, &v, udata2finalize(g)); |
834 | tm = luaT_gettmbyobj(L, &v, TM_GC); | 834 | tm = luaT_gettmbyobj(L, &v, TM_GC); |
835 | if (tm != NULL && ttisfunction(tm)) { /* is there a finalizer? */ | 835 | if (ttisfunction(tm)) { /* is the finalizer a function? */ |
836 | int status; | 836 | int status; |
837 | lu_byte oldah = L->allowhook; | 837 | lu_byte oldah = L->allowhook; |
838 | int running = g->gcrunning; | 838 | int running = g->gcrunning; |
@@ -850,9 +850,9 @@ static void GCTM (lua_State *L) { | |||
850 | const char *msg = (ttisstring(s2v(L->top - 1))) | 850 | const char *msg = (ttisstring(s2v(L->top - 1))) |
851 | ? svalue(s2v(L->top - 1)) | 851 | ? svalue(s2v(L->top - 1)) |
852 | : "error object is not a string"; | 852 | : "error object is not a string"; |
853 | luaE_warning(L, "error in __gc metamethod ("); | 853 | luaE_warning(L, "error in __gc metamethod (", 1); |
854 | luaE_warning(L, msg); | 854 | luaE_warning(L, msg, 1); |
855 | luaE_warning(L, ")\n"); | 855 | luaE_warning(L, ")", 0); |
856 | } | 856 | } |
857 | } | 857 | } |
858 | } | 858 | } |
@@ -411,10 +411,10 @@ LUA_API void lua_close (lua_State *L) { | |||
411 | } | 411 | } |
412 | 412 | ||
413 | 413 | ||
414 | void luaE_warning (lua_State *L, const char *msg) { | 414 | void luaE_warning (lua_State *L, const char *msg, int tocont) { |
415 | lua_WarnFunction wf = G(L)->warnf; | 415 | lua_WarnFunction wf = G(L)->warnf; |
416 | if (wf != NULL) | 416 | if (wf != NULL) |
417 | wf(&G(L)->ud_warn, msg); | 417 | wf(G(L)->ud_warn, msg, tocont); |
418 | } | 418 | } |
419 | 419 | ||
420 | 420 | ||
@@ -317,7 +317,7 @@ LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); | |||
317 | LUAI_FUNC void luaE_freeCI (lua_State *L); | 317 | LUAI_FUNC void luaE_freeCI (lua_State *L); |
318 | LUAI_FUNC void luaE_shrinkCI (lua_State *L); | 318 | LUAI_FUNC void luaE_shrinkCI (lua_State *L); |
319 | LUAI_FUNC void luaE_enterCcall (lua_State *L); | 319 | LUAI_FUNC void luaE_enterCcall (lua_State *L); |
320 | LUAI_FUNC void luaE_warning (lua_State *L, const char *msg); | 320 | LUAI_FUNC void luaE_warning (lua_State *L, const char *msg, int tocont); |
321 | 321 | ||
322 | 322 | ||
323 | #define luaE_exitCcall(L) ((L)->nCcalls--) | 323 | #define luaE_exitCcall(L) ((L)->nCcalls--) |
@@ -63,11 +63,8 @@ static void pushobject (lua_State *L, const TValue *o) { | |||
63 | } | 63 | } |
64 | 64 | ||
65 | 65 | ||
66 | static void badexit (const char *fmt, ...) { | 66 | static void badexit (const char *fmt, const char *s) { |
67 | va_list argp; | 67 | fprintf(stderr, fmt, s); |
68 | va_start(argp, fmt); | ||
69 | vfprintf(stderr, fmt, argp); | ||
70 | va_end(argp); | ||
71 | /* avoid assertion failures when exiting */ | 68 | /* avoid assertion failures when exiting */ |
72 | l_memcontrol.numblocks = l_memcontrol.total = 0; | 69 | l_memcontrol.numblocks = l_memcontrol.total = 0; |
73 | exit(EXIT_FAILURE); | 70 | exit(EXIT_FAILURE); |
@@ -81,52 +78,35 @@ static int tpanic (lua_State *L) { | |||
81 | } | 78 | } |
82 | 79 | ||
83 | 80 | ||
84 | static int islast (const char *message) { | ||
85 | size_t len = strlen(message); | ||
86 | return (len > 0 && message[len - 1] == '\n'); | ||
87 | } | ||
88 | |||
89 | |||
90 | /* | 81 | /* |
91 | ** Warning function for tests. Fist, it concatenates all parts of | 82 | ** Warning function for tests. Fist, it concatenates all parts of |
92 | ** a warning in buffer 'buff'. Then: | 83 | ** a warning in buffer 'buff'. Then: |
93 | ** messages starting with '#' are shown on standard output (used to | 84 | ** - messages starting with '#' are shown on standard output (used to |
94 | ** test explicit warnings); | 85 | ** test explicit warnings); |
95 | ** messages containing '@' are stored in global '_WARN' (used to test | 86 | ** - messages containing '@' are stored in global '_WARN' (used to test |
96 | ** errors that generate warnings); | 87 | ** errors that generate warnings); |
97 | ** other messages abort the tests (they represent real warning conditions; | 88 | ** - other messages abort the tests (they represent real warning |
98 | ** the standard tests should not generate these conditions unexpectedly). | 89 | ** conditions; the standard tests should not generate these conditions |
90 | ** unexpectedly). | ||
99 | */ | 91 | */ |
100 | static void warnf (void **pud, const char *msg) { | 92 | static void warnf (void *ud, const char *msg, int tocont) { |
101 | static char buff[200]; /* should be enough for tests... */ | 93 | static char buff[200] = ""; /* should be enough for tests... */ |
102 | static int cont = 0; /* message to be continued */ | 94 | if (strlen(msg) >= sizeof(buff) - strlen(buff)) |
103 | if (cont) { /* continuation? */ | 95 | badexit("%s", "warnf-buffer overflow"); |
104 | if (strlen(msg) >= sizeof(buff) - strlen(buff)) | 96 | strcat(buff, msg); /* add new message to current warning */ |
105 | badexit("warnf-buffer overflow"); | 97 | if (!tocont) { /* message finished? */ |
106 | strcat(buff, msg); /* add new message to current warning */ | ||
107 | } | ||
108 | else { /* new warning */ | ||
109 | if (strlen(msg) >= sizeof(buff)) | ||
110 | badexit("warnf-buffer overflow"); | ||
111 | strcpy(buff, msg); /* start a new warning */ | ||
112 | } | ||
113 | if (!islast(msg)) /* message not finished yet? */ | ||
114 | cont = 1; /* wait for more */ | ||
115 | else { /* handle message */ | ||
116 | cont = 0; /* prepare for next message */ | ||
117 | if (buff[0] == '#') /* expected warning? */ | 98 | if (buff[0] == '#') /* expected warning? */ |
118 | printf("Expected Lua warning: %s", buff); /* print it */ | 99 | printf("Expected Lua warning: %s\n", buff); /* print it */ |
119 | else if (strchr(buff, '@') != NULL) { /* warning for test purposes? */ | 100 | else if (strchr(buff, '@') != NULL) { /* warning for test purposes? */ |
120 | lua_State *L = cast(lua_State *, *pud); | 101 | lua_State *L = cast(lua_State *, ud); |
121 | lua_unlock(L); | 102 | lua_unlock(L); |
122 | lua_pushstring(L, buff); | 103 | lua_pushstring(L, buff); |
123 | lua_setglobal(L, "_WARN"); /* assign message to global '_WARN' */ | 104 | lua_setglobal(L, "_WARN"); /* assign message to global '_WARN' */ |
124 | lua_lock(L); | 105 | lua_lock(L); |
125 | return; | ||
126 | } | 106 | } |
127 | else { /* a real warning; should not happen during tests */ | 107 | else /* a real warning; should not happen during tests */ |
128 | badexit("Unexpected warning in test mode: %s\naborting...\n", buff); | 108 | badexit("Unexpected warning in test mode: %s\naborting...\n", buff); |
129 | } | 109 | buff[0] = '\0'; /* prepare buffer for next warning */ |
130 | } | 110 | } |
131 | } | 111 | } |
132 | 112 | ||
@@ -1466,9 +1446,13 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) { | |||
1466 | const char *msg = getstring; | 1446 | const char *msg = getstring; |
1467 | printf("%s\n", msg); | 1447 | printf("%s\n", msg); |
1468 | } | 1448 | } |
1449 | else if EQ("warningC") { | ||
1450 | const char *msg = getstring; | ||
1451 | lua_warning(L1, msg, 1); | ||
1452 | } | ||
1469 | else if EQ("warning") { | 1453 | else if EQ("warning") { |
1470 | const char *msg = getstring; | 1454 | const char *msg = getstring; |
1471 | lua_warning(L1, msg); | 1455 | lua_warning(L1, msg, 0); |
1472 | } | 1456 | } |
1473 | else if EQ("pushbool") { | 1457 | else if EQ("pushbool") { |
1474 | lua_pushboolean(L1, getnum); | 1458 | lua_pushboolean(L1, getnum); |
@@ -128,7 +128,7 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); | |||
128 | /* | 128 | /* |
129 | ** Type for warning functions | 129 | ** Type for warning functions |
130 | */ | 130 | */ |
131 | typedef void (*lua_WarnFunction) (void **pud, const char *msg); | 131 | typedef void (*lua_WarnFunction) (void *ud, const char *msg, int tocont); |
132 | 132 | ||
133 | 133 | ||
134 | 134 | ||
@@ -309,7 +309,7 @@ LUA_API int (lua_isyieldable) (lua_State *L); | |||
309 | ** Warning-related functions | 309 | ** Warning-related functions |
310 | */ | 310 | */ |
311 | LUA_API void (lua_setwarnf) (lua_State *L, lua_WarnFunction f, void *ud); | 311 | LUA_API void (lua_setwarnf) (lua_State *L, lua_WarnFunction f, void *ud); |
312 | LUA_API void (lua_warning) (lua_State *L, const char *msg); | 312 | LUA_API void (lua_warning) (lua_State *L, const char *msg, int tocont); |
313 | 313 | ||
314 | 314 | ||
315 | /* | 315 | /* |
diff --git a/manual/manual.of b/manual/manual.of index b47fd865..63e78f95 100644 --- a/manual/manual.of +++ b/manual/manual.of | |||
@@ -4061,7 +4061,7 @@ If @id{index} @N{is 0}, then all stack elements are removed. | |||
4061 | 4061 | ||
4062 | Sets the @x{warning function} to be used by Lua to emit warnings | 4062 | Sets the @x{warning function} to be used by Lua to emit warnings |
4063 | @see{lua_WarnFunction}. | 4063 | @see{lua_WarnFunction}. |
4064 | The @id{ud} parameter initializes the slot @id{pud} passed to | 4064 | The @id{ud} parameter sets the value @id{ud} passed to |
4065 | the warning function. | 4065 | the warning function. |
4066 | 4066 | ||
4067 | } | 4067 | } |
@@ -4325,25 +4325,24 @@ Returns the version number of this core. | |||
4325 | } | 4325 | } |
4326 | 4326 | ||
4327 | @APIEntry{ | 4327 | @APIEntry{ |
4328 | typedef void (*lua_WarnFunction) (void **pud, const char *msg);| | 4328 | typedef void (*lua_WarnFunction) (void *ud, const char *msg, int tocont);| |
4329 | 4329 | ||
4330 | The type of @x{warning function}s, called by Lua to emit warnings. | 4330 | The type of @x{warning function}s, called by Lua to emit warnings. |
4331 | The first parameter is the address of a writable slot, | 4331 | The first parameter is an opaque pointer |
4332 | constant for a given Lua state and | 4332 | set by @Lid{lua_setwarnf}. |
4333 | initialized by @Lid{lua_setwarnf}. | ||
4334 | The second parameter is the warning message. | 4333 | The second parameter is the warning message. |
4335 | This function should assume that | 4334 | The third parameter is a boolean that |
4336 | a message not ending with an end-of-line will be | 4335 | indicates whether the message is |
4337 | continued by the message in the next call. | 4336 | to be continued by the message in the next call. |
4338 | 4337 | ||
4339 | } | 4338 | } |
4340 | 4339 | ||
4341 | @APIEntry{ | 4340 | @APIEntry{ |
4342 | void lua_warning (lua_State *L, const char *msg);| | 4341 | void lua_warning (lua_State *L, const char *msg, int tocont);| |
4343 | @apii{0,0,-} | 4342 | @apii{0,0,-} |
4344 | 4343 | ||
4345 | Emits a warning with the given message. | 4344 | Emits a warning with the given message. |
4346 | A message not ending with an end-of-line should be | 4345 | A message in a call with @id{tocont} true should be |
4347 | continued in another call to this function. | 4346 | continued in another call to this function. |
4348 | 4347 | ||
4349 | } | 4348 | } |
@@ -6275,11 +6274,12 @@ The current value of this variable is @St{Lua 5.4}. | |||
6275 | 6274 | ||
6276 | } | 6275 | } |
6277 | 6276 | ||
6278 | @LibEntry{warn (message)| | 6277 | @LibEntry{warn (message [, tocont])| |
6279 | 6278 | ||
6280 | Emits a warning with the given message. | 6279 | Emits a warning with the given message. |
6281 | Note that messages not ending with an end-of-line | 6280 | A message in a call with @id{tocont} true should be |
6282 | are assumed to be continued by the message in the next call. | 6281 | continued in another call to this function. |
6282 | The default for @id{tocont} is false. | ||
6283 | 6283 | ||
6284 | } | 6284 | } |
6285 | 6285 | ||
diff --git a/testes/all.lua b/testes/all.lua index 506afad2..8d727b6b 100644 --- a/testes/all.lua +++ b/testes/all.lua | |||
@@ -6,7 +6,7 @@ | |||
6 | local version = "Lua 5.4" | 6 | local version = "Lua 5.4" |
7 | if _VERSION ~= version then | 7 | if _VERSION ~= version then |
8 | warn(string.format( | 8 | warn(string.format( |
9 | "This test suite is for %s, not for %s\nExiting tests\n", version, _VERSION)) | 9 | "This test suite is for %s, not for %s\nExiting tests", version, _VERSION)) |
10 | return | 10 | return |
11 | end | 11 | end |
12 | 12 | ||
@@ -190,16 +190,16 @@ assert(dofile('verybig.lua', true) == 10); collectgarbage() | |||
190 | dofile('files.lua') | 190 | dofile('files.lua') |
191 | 191 | ||
192 | if #msgs > 0 then | 192 | if #msgs > 0 then |
193 | warn("#tests not performed:\n ") | 193 | warn("#tests not performed:", true) |
194 | for i=1,#msgs do | 194 | for i=1,#msgs do |
195 | warn(msgs[i]); warn("\n ") | 195 | warn("\n ", true); warn(msgs[i], true) |
196 | end | 196 | end |
197 | warn("\n") | 197 | warn("\n") |
198 | end | 198 | end |
199 | 199 | ||
200 | print("(there should be two warnings now)") | 200 | print("(there should be two warnings now)") |
201 | warn("#This is "); warn("an expected"); warn(" warning\n") | 201 | warn("#This is ", true); warn("an expected", true); warn(" warning") |
202 | warn("#This is"); warn(" another one\n") | 202 | warn("#This is", true); warn(" another one") |
203 | 203 | ||
204 | -- no test module should define 'debug' | 204 | -- no test module should define 'debug' |
205 | assert(debug == nil) | 205 | assert(debug == nil) |
diff --git a/testes/api.lua b/testes/api.lua index d034ea80..08672e8a 100644 --- a/testes/api.lua +++ b/testes/api.lua | |||
@@ -114,13 +114,11 @@ end | |||
114 | 114 | ||
115 | -- testing warnings | 115 | -- testing warnings |
116 | T.testC([[ | 116 | T.testC([[ |
117 | warning "#This shold be a" | 117 | warningC "#This shold be a" |
118 | warning " single " | 118 | warningC " single " |
119 | warning "warning | 119 | warning "warning" |
120 | " | 120 | warningC "#This should be " |
121 | warning "#This should be " | 121 | warning "another one" |
122 | warning "another one | ||
123 | " | ||
124 | ]]) | 122 | ]]) |
125 | 123 | ||
126 | 124 | ||
diff --git a/testes/gc.lua b/testes/gc.lua index 05bf564e..91e78a48 100644 --- a/testes/gc.lua +++ b/testes/gc.lua | |||
@@ -18,6 +18,8 @@ assert(collectgarbage("incremental") == "generational") | |||
18 | assert(collectgarbage("incremental") == "incremental") | 18 | assert(collectgarbage("incremental") == "incremental") |
19 | 19 | ||
20 | 20 | ||
21 | local function nop () end | ||
22 | |||
21 | local function gcinfo () | 23 | local function gcinfo () |
22 | return collectgarbage"count" * 1024 | 24 | return collectgarbage"count" * 1024 |
23 | end | 25 | end |
@@ -388,7 +390,7 @@ if T then | |||
388 | collectgarbage() | 390 | collectgarbage() |
389 | for i = 1, 10 do assert(s[i]) end | 391 | for i = 1, 10 do assert(s[i]) end |
390 | 392 | ||
391 | getmetatable(u).__gc = false | 393 | getmetatable(u).__gc = nil |
392 | 394 | ||
393 | end | 395 | end |
394 | print '+' | 396 | print '+' |
@@ -604,8 +606,8 @@ if T then | |||
604 | collectgarbage("stop") | 606 | collectgarbage("stop") |
605 | local x = T.newuserdata(0) | 607 | local x = T.newuserdata(0) |
606 | local y = T.newuserdata(0) | 608 | local y = T.newuserdata(0) |
607 | debug.setmetatable(y, {__gc = true}) -- bless the new udata before... | 609 | debug.setmetatable(y, {__gc = nop}) -- bless the new udata before... |
608 | debug.setmetatable(x, {__gc = true}) -- ...the old one | 610 | debug.setmetatable(x, {__gc = nop}) -- ...the old one |
609 | assert(T.gccolor(y) == "white") | 611 | assert(T.gccolor(y) == "white") |
610 | T.checkmemory() | 612 | T.checkmemory() |
611 | collectgarbage("restart") | 613 | collectgarbage("restart") |
@@ -631,6 +633,7 @@ if T then | |||
631 | assert(T.totalmem("thread") == t + 1) | 633 | assert(T.totalmem("thread") == t + 1) |
632 | end | 634 | end |
633 | 635 | ||
636 | |||
634 | -- create an object to be collected when state is closed | 637 | -- create an object to be collected when state is closed |
635 | do | 638 | do |
636 | local setmetatable,assert,type,print,getmetatable = | 639 | local setmetatable,assert,type,print,getmetatable = |
@@ -650,7 +653,7 @@ end | |||
650 | 653 | ||
651 | -- create several objects to raise errors when collected while closing state | 654 | -- create several objects to raise errors when collected while closing state |
652 | if T then | 655 | if T then |
653 | local error, assert, warn, find = error, assert, warn, string.find | 656 | local error, assert, find = error, assert, string.find |
654 | local n = 0 | 657 | local n = 0 |
655 | local lastmsg | 658 | local lastmsg |
656 | local mt = {__gc = function (o) | 659 | local mt = {__gc = function (o) |