diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-08-15 13:44:36 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-08-15 13:44:36 -0300 |
| commit | a1d8eb27431c02c4529be1efd92143ad65434f3a (patch) | |
| tree | 58db9340ba2b8ea1cb91004b96f15a955f167c58 | |
| parent | f64a1b175a5fa65434a073e6d071b32bb7b0ab69 (diff) | |
| download | lua-a1d8eb27431c02c4529be1efd92143ad65434f3a.tar.gz lua-a1d8eb27431c02c4529be1efd92143ad65434f3a.tar.bz2 lua-a1d8eb27431c02c4529be1efd92143ad65434f3a.zip | |
Added control messages to warnings
Added the concept of control messages to the warning system, plus the
implementation of the controls "@on"/"@off" to turn warnings on/off.
Moreover, the warning system in the test library adds some other
controls to ease the test of warnings.
| -rw-r--r-- | lauxlib.c | 34 | ||||
| -rw-r--r-- | lbaselib.c | 4 | ||||
| -rw-r--r-- | ltests.c | 64 | ||||
| -rw-r--r-- | lua.c | 36 | ||||
| -rw-r--r-- | manual/manual.of | 29 | ||||
| -rw-r--r-- | testes/all.lua | 4 | ||||
| -rw-r--r-- | testes/api.lua | 2 | ||||
| -rw-r--r-- | testes/gc.lua | 8 | ||||
| -rw-r--r-- | testes/main.lua | 29 |
9 files changed, 161 insertions, 49 deletions
| @@ -1002,29 +1002,43 @@ static int panic (lua_State *L) { | |||
| 1002 | 1002 | ||
| 1003 | 1003 | ||
| 1004 | /* | 1004 | /* |
| 1005 | ** Emit a warning. '*previoustocont' signals whether previous message | 1005 | ** Emit a warning. '*warnstate' means: |
| 1006 | ** was to be continued by the current one. | 1006 | ** 0 - warning system is off; |
| 1007 | ** 1 - ready to start a new message; | ||
| 1008 | ** 2 - previous message is to be continued. | ||
| 1007 | */ | 1009 | */ |
| 1008 | static void warnf (void *ud, const char *message, int tocont) { | 1010 | static void warnf (void *ud, const char *message, int tocont) { |
| 1009 | int *previoustocont = (int *)ud; | 1011 | int *warnstate = (int *)ud; |
| 1010 | if (!*previoustocont) /* previous message was the last? */ | 1012 | if (*warnstate != 2 && !tocont && *message == '@') { /* control message? */ |
| 1013 | if (strcmp(message + 1, "off") == 0) | ||
| 1014 | *warnstate = 0; | ||
| 1015 | else if (strcmp(message + 1, "on") == 0) | ||
| 1016 | *warnstate = 1; | ||
| 1017 | return; | ||
| 1018 | } | ||
| 1019 | else if (*warnstate == 0) /* warnings off? */ | ||
| 1020 | return; | ||
| 1021 | if (*warnstate == 1) /* previous message was the last? */ | ||
| 1011 | lua_writestringerror("%s", "Lua warning: "); /* start a new warning */ | 1022 | lua_writestringerror("%s", "Lua warning: "); /* start a new warning */ |
| 1012 | lua_writestringerror("%s", message); /* write message */ | 1023 | lua_writestringerror("%s", message); /* write message */ |
| 1013 | if (!tocont) /* is this the last part? */ | 1024 | if (tocont) /* not the last part? */ |
| 1025 | *warnstate = 2; /* to be continued */ | ||
| 1026 | else { /* last part */ | ||
| 1014 | lua_writestringerror("%s", "\n"); /* finish message with end-of-line */ | 1027 | lua_writestringerror("%s", "\n"); /* finish message with end-of-line */ |
| 1015 | *previoustocont = tocont; | 1028 | *warnstate = 1; /* ready to start a new message */ |
| 1029 | } | ||
| 1016 | } | 1030 | } |
| 1017 | 1031 | ||
| 1018 | 1032 | ||
| 1019 | LUALIB_API lua_State *luaL_newstate (void) { | 1033 | LUALIB_API lua_State *luaL_newstate (void) { |
| 1020 | lua_State *L = lua_newstate(l_alloc, NULL); | 1034 | lua_State *L = lua_newstate(l_alloc, NULL); |
| 1021 | if (L) { | 1035 | if (L) { |
| 1022 | int *previoustocont; /* space for warning state */ | 1036 | int *warnstate; /* space for warning state */ |
| 1023 | lua_atpanic(L, &panic); | 1037 | lua_atpanic(L, &panic); |
| 1024 | previoustocont = (int *)lua_newuserdatauv(L, sizeof(int), 0); | 1038 | warnstate = (int *)lua_newuserdatauv(L, sizeof(int), 0); |
| 1025 | luaL_ref(L, LUA_REGISTRYINDEX); /* make sure it won't be collected */ | 1039 | luaL_ref(L, LUA_REGISTRYINDEX); /* make sure it won't be collected */ |
| 1026 | *previoustocont = 0; /* next message starts a new warning */ | 1040 | *warnstate = 1; /* next message starts a new warning */ |
| 1027 | lua_setwarnf(L, warnf, previoustocont); | 1041 | lua_setwarnf(L, warnf, warnstate); |
| 1028 | } | 1042 | } |
| 1029 | return L; | 1043 | return L; |
| 1030 | } | 1044 | } |
| @@ -48,9 +48,9 @@ static int luaB_warn (lua_State *L) { | |||
| 48 | luaL_checkstring(L, 1); /* at least one argument */ | 48 | luaL_checkstring(L, 1); /* at least one argument */ |
| 49 | for (i = 2; i <= n; i++) | 49 | for (i = 2; i <= n; i++) |
| 50 | luaL_checkstring(L, i); /* make sure all arguments are strings */ | 50 | luaL_checkstring(L, i); /* make sure all arguments are strings */ |
| 51 | for (i = 1; i <= n; i++) /* compose warning */ | 51 | for (i = 1; i < n; i++) /* compose warning */ |
| 52 | lua_warning(L, lua_tostring(L, i), 1); | 52 | lua_warning(L, lua_tostring(L, i), 1); |
| 53 | lua_warning(L, "", 0); /* close warning */ | 53 | lua_warning(L, lua_tostring(L, n), 0); /* close warning */ |
| 54 | return 0; | 54 | return 0; |
| 55 | } | 55 | } |
| 56 | 56 | ||
| @@ -79,32 +79,62 @@ static int tpanic (lua_State *L) { | |||
| 79 | 79 | ||
| 80 | /* | 80 | /* |
| 81 | ** Warning function for tests. Fist, it concatenates all parts of | 81 | ** Warning function for tests. Fist, it concatenates all parts of |
| 82 | ** a warning in buffer 'buff'. Then: | 82 | ** a warning in buffer 'buff'. Then, it has three modes: |
| 83 | ** - messages starting with '#' are shown on standard output (used to | 83 | ** - 0.normal: messages starting with '#' are shown on standard output; |
| 84 | ** test explicit warnings); | ||
| 85 | ** - messages containing '@' are stored in global '_WARN' (used to test | ||
| 86 | ** errors that generate warnings); | ||
| 87 | ** - other messages abort the tests (they represent real warning | 84 | ** - other messages abort the tests (they represent real warning |
| 88 | ** conditions; the standard tests should not generate these conditions | 85 | ** conditions; the standard tests should not generate these conditions |
| 89 | ** unexpectedly). | 86 | ** unexpectedly); |
| 87 | ** - 1.allow: all messages are shown; | ||
| 88 | ** - 2.store: all warnings go to the global '_WARN'; | ||
| 90 | */ | 89 | */ |
| 91 | static void warnf (void *ud, const char *msg, int tocont) { | 90 | static void warnf (void *ud, const char *msg, int tocont) { |
| 92 | static char buff[200] = ""; /* should be enough for tests... */ | 91 | static char buff[200] = ""; /* should be enough for tests... */ |
| 92 | static int onoff = 1; | ||
| 93 | static int mode = 0; /* start in normal mode */ | ||
| 94 | static int lasttocont = 0; | ||
| 95 | if (!lasttocont && !tocont && *msg == '@') { /* control message? */ | ||
| 96 | if (buff[0] != '\0') | ||
| 97 | badexit("Control warning during warning: %s\naborting...\n", msg); | ||
| 98 | if (strcmp(msg + 1, "off") == 0) | ||
| 99 | onoff = 0; | ||
| 100 | else if (strcmp(msg + 1, "on") == 0) | ||
| 101 | onoff = 1; | ||
| 102 | else if (strcmp(msg + 1, "normal") == 0) | ||
| 103 | mode = 0; | ||
| 104 | else if (strcmp(msg + 1, "allow") == 0) | ||
| 105 | mode = 1; | ||
| 106 | else if (strcmp(msg + 1, "store") == 0) | ||
| 107 | mode = 2; | ||
| 108 | else | ||
| 109 | badexit("Invalid control warning in test mode: %s\naborting...\n", msg); | ||
| 110 | return; | ||
| 111 | } | ||
| 112 | lasttocont = tocont; | ||
| 93 | if (strlen(msg) >= sizeof(buff) - strlen(buff)) | 113 | if (strlen(msg) >= sizeof(buff) - strlen(buff)) |
| 94 | badexit("%s", "warnf-buffer overflow"); | 114 | badexit("%s", "warnf-buffer overflow"); |
| 95 | strcat(buff, msg); /* add new message to current warning */ | 115 | strcat(buff, msg); /* add new message to current warning */ |
| 96 | if (!tocont) { /* message finished? */ | 116 | if (!tocont) { /* message finished? */ |
| 97 | if (buff[0] == '#') /* expected warning? */ | 117 | switch (mode) { |
| 98 | printf("Expected Lua warning: %s\n", buff); /* print it */ | 118 | case 0: { /* normal */ |
| 99 | else if (strchr(buff, '@') != NULL) { /* warning for test purposes? */ | 119 | if (buff[0] != '#' && onoff) /* unexpected warning? */ |
| 100 | lua_State *L = cast(lua_State *, ud); | 120 | badexit("Unexpected warning in test mode: %s\naborting...\n", buff); |
| 101 | lua_unlock(L); | 121 | /* else */ /* FALLTHROUGH */ |
| 102 | lua_pushstring(L, buff); | 122 | } |
| 103 | lua_setglobal(L, "_WARN"); /* assign message to global '_WARN' */ | 123 | case 1: { /* allow */ |
| 104 | lua_lock(L); | 124 | if (onoff) |
| 105 | } | 125 | fprintf(stderr, "Lua warning: %s\n", buff); /* print warning */ |
| 106 | else /* a real warning; should not happen during tests */ | 126 | break; |
| 107 | badexit("Unexpected warning in test mode: %s\naborting...\n", buff); | 127 | } |
| 128 | case 2: { /* store */ | ||
| 129 | lua_State *L = cast(lua_State *, ud); | ||
| 130 | lua_unlock(L); | ||
| 131 | lua_pushstring(L, buff); | ||
| 132 | lua_setglobal(L, "_WARN"); /* assign message to global '_WARN' */ | ||
| 133 | lua_lock(L); | ||
| 134 | buff[0] = '\0'; /* prepare buffer for next warning */ | ||
| 135 | break; | ||
| 136 | } | ||
| 137 | } | ||
| 108 | buff[0] = '\0'; /* prepare buffer for next warning */ | 138 | buff[0] = '\0'; /* prepare buffer for next warning */ |
| 109 | } | 139 | } |
| 110 | } | 140 | } |
| @@ -73,6 +73,7 @@ static void print_usage (const char *badoption) { | |||
| 73 | " -l name require library 'name' into global 'name'\n" | 73 | " -l name require library 'name' into global 'name'\n" |
| 74 | " -v show version information\n" | 74 | " -v show version information\n" |
| 75 | " -E ignore environment variables\n" | 75 | " -E ignore environment variables\n" |
| 76 | " -q turn warnings off\n" | ||
| 76 | " -- stop handling options\n" | 77 | " -- stop handling options\n" |
| 77 | " - stop handling options and execute stdin\n" | 78 | " - stop handling options and execute stdin\n" |
| 78 | , | 79 | , |
| @@ -259,14 +260,18 @@ static int collectargs (char **argv, int *first) { | |||
| 259 | case '\0': /* '-' */ | 260 | case '\0': /* '-' */ |
| 260 | return args; /* script "name" is '-' */ | 261 | return args; /* script "name" is '-' */ |
| 261 | case 'E': | 262 | case 'E': |
| 262 | if (argv[i][2] != '\0') /* extra characters after 1st? */ | 263 | if (argv[i][2] != '\0') /* extra characters? */ |
| 263 | return has_error; /* invalid option */ | 264 | return has_error; /* invalid option */ |
| 264 | args |= has_E; | 265 | args |= has_E; |
| 265 | break; | 266 | break; |
| 267 | case 'q': | ||
| 268 | if (argv[i][2] != '\0') /* extra characters? */ | ||
| 269 | return has_error; /* invalid option */ | ||
| 270 | break; | ||
| 266 | case 'i': | 271 | case 'i': |
| 267 | args |= has_i; /* (-i implies -v) *//* FALLTHROUGH */ | 272 | args |= has_i; /* (-i implies -v) *//* FALLTHROUGH */ |
| 268 | case 'v': | 273 | case 'v': |
| 269 | if (argv[i][2] != '\0') /* extra characters after 1st? */ | 274 | if (argv[i][2] != '\0') /* extra characters? */ |
| 270 | return has_error; /* invalid option */ | 275 | return has_error; /* invalid option */ |
| 271 | args |= has_v; | 276 | args |= has_v; |
| 272 | break; | 277 | break; |
| @@ -289,7 +294,8 @@ static int collectargs (char **argv, int *first) { | |||
| 289 | 294 | ||
| 290 | 295 | ||
| 291 | /* | 296 | /* |
| 292 | ** Processes options 'e' and 'l', which involve running Lua code. | 297 | ** Processes options 'e' and 'l', which involve running Lua code, and |
| 298 | ** 'q', which also affects the state. | ||
| 293 | ** Returns 0 if some code raises an error. | 299 | ** Returns 0 if some code raises an error. |
| 294 | */ | 300 | */ |
| 295 | static int runargs (lua_State *L, char **argv, int n) { | 301 | static int runargs (lua_State *L, char **argv, int n) { |
| @@ -297,15 +303,21 @@ static int runargs (lua_State *L, char **argv, int n) { | |||
| 297 | for (i = 1; i < n; i++) { | 303 | for (i = 1; i < n; i++) { |
| 298 | int option = argv[i][1]; | 304 | int option = argv[i][1]; |
| 299 | lua_assert(argv[i][0] == '-'); /* already checked */ | 305 | lua_assert(argv[i][0] == '-'); /* already checked */ |
| 300 | if (option == 'e' || option == 'l') { | 306 | switch (option) { |
| 301 | int status; | 307 | case 'e': case 'l': { |
| 302 | const char *extra = argv[i] + 2; /* both options need an argument */ | 308 | int status; |
| 303 | if (*extra == '\0') extra = argv[++i]; | 309 | const char *extra = argv[i] + 2; /* both options need an argument */ |
| 304 | lua_assert(extra != NULL); | 310 | if (*extra == '\0') extra = argv[++i]; |
| 305 | status = (option == 'e') | 311 | lua_assert(extra != NULL); |
| 306 | ? dostring(L, extra, "=(command line)") | 312 | status = (option == 'e') |
| 307 | : dolibrary(L, extra); | 313 | ? dostring(L, extra, "=(command line)") |
| 308 | if (status != LUA_OK) return 0; | 314 | : dolibrary(L, extra); |
| 315 | if (status != LUA_OK) return 0; | ||
| 316 | break; | ||
| 317 | } | ||
| 318 | case 'q': | ||
| 319 | lua_warning(L, "@off", 0); /* no warnings */ | ||
| 320 | break; | ||
| 309 | } | 321 | } |
| 310 | } | 322 | } |
| 311 | return 1; | 323 | return 1; |
diff --git a/manual/manual.of b/manual/manual.of index ff27a7d4..8c71c613 100644 --- a/manual/manual.of +++ b/manual/manual.of | |||
| @@ -4370,6 +4370,8 @@ The third parameter is a boolean that | |||
| 4370 | indicates whether the message is | 4370 | indicates whether the message is |
| 4371 | to be continued by the message in the next call. | 4371 | to be continued by the message in the next call. |
| 4372 | 4372 | ||
| 4373 | See @Lid{warn} for more details about warnings. | ||
| 4374 | |||
| 4373 | } | 4375 | } |
| 4374 | 4376 | ||
| 4375 | @APIEntry{ | 4377 | @APIEntry{ |
| @@ -4380,6 +4382,8 @@ Emits a warning with the given message. | |||
| 4380 | A message in a call with @id{tocont} true should be | 4382 | A message in a call with @id{tocont} true should be |
| 4381 | continued in another call to this function. | 4383 | continued in another call to this function. |
| 4382 | 4384 | ||
| 4385 | See @Lid{warn} for more details about warnings. | ||
| 4386 | |||
| 4383 | } | 4387 | } |
| 4384 | 4388 | ||
| 4385 | @APIEntry{ | 4389 | @APIEntry{ |
| @@ -6355,6 +6359,16 @@ The current value of this variable is @St{Lua 5.4}. | |||
| 6355 | Emits a warning with a message composed by the concatenation | 6359 | Emits a warning with a message composed by the concatenation |
| 6356 | of all its arguments (which should be strings). | 6360 | of all its arguments (which should be strings). |
| 6357 | 6361 | ||
| 6362 | By convention, | ||
| 6363 | a one-piece message starting with @Char{@At} | ||
| 6364 | is intended to be a @emph{control message}, | ||
| 6365 | which is a message to the warning system itself. | ||
| 6366 | In particular, the standard warning function in Lua | ||
| 6367 | recognizes the control messages @St{@At{}off}, | ||
| 6368 | to stop the emission of warnings, | ||
| 6369 | and @St{@At{}on}, to (re)start the emission; | ||
| 6370 | it ignores unknown control messages. | ||
| 6371 | |||
| 6358 | } | 6372 | } |
| 6359 | 6373 | ||
| 6360 | @LibEntry{xpcall (f, msgh [, arg1, @Cdots])| | 6374 | @LibEntry{xpcall (f, msgh [, arg1, @Cdots])| |
| @@ -7293,7 +7307,7 @@ stored as the first capture, and therefore has @N{number 1}; | |||
| 7293 | the character matching @St{.} is captured with @N{number 2}, | 7307 | the character matching @St{.} is captured with @N{number 2}, |
| 7294 | and the part matching @St{%s*} has @N{number 3}. | 7308 | and the part matching @St{%s*} has @N{number 3}. |
| 7295 | 7309 | ||
| 7296 | As a special case, the empty capture @T{()} captures | 7310 | As a special case, the capture @T{()} captures |
| 7297 | the current string position (a number). | 7311 | the current string position (a number). |
| 7298 | For instance, if we apply the pattern @T{"()aa()"} on the | 7312 | For instance, if we apply the pattern @T{"()aa()"} on the |
| 7299 | string @T{"flaaap"}, there will be two captures: @N{3 and 5}. | 7313 | string @T{"flaaap"}, there will be two captures: @N{3 and 5}. |
| @@ -7858,7 +7872,6 @@ they are compared as @x{unsigned integers}. | |||
| 7858 | 7872 | ||
| 7859 | } | 7873 | } |
| 7860 | 7874 | ||
| 7861 | |||
| 7862 | @sect2{iolib| @title{Input and Output Facilities} | 7875 | @sect2{iolib| @title{Input and Output Facilities} |
| 7863 | 7876 | ||
| 7864 | The I/O library provides two different styles for file manipulation. | 7877 | The I/O library provides two different styles for file manipulation. |
| @@ -8150,7 +8163,6 @@ There are three available modes: | |||
| 8150 | @item{@St{line}| line buffering.} | 8163 | @item{@St{line}| line buffering.} |
| 8151 | } | 8164 | } |
| 8152 | 8165 | ||
| 8153 | } | ||
| 8154 | For the last two cases, | 8166 | For the last two cases, |
| 8155 | @id{size} is a hint for the size of the buffer, in bytes. | 8167 | @id{size} is a hint for the size of the buffer, in bytes. |
| 8156 | The default is an appropriate size. | 8168 | The default is an appropriate size. |
| @@ -8708,6 +8720,7 @@ The options are: | |||
| 8708 | @item{@T{-i}| enters interactive mode after running @rep{script};} | 8720 | @item{@T{-i}| enters interactive mode after running @rep{script};} |
| 8709 | @item{@T{-v}| prints version information;} | 8721 | @item{@T{-v}| prints version information;} |
| 8710 | @item{@T{-E}| ignores environment variables;} | 8722 | @item{@T{-E}| ignores environment variables;} |
| 8723 | @item{@T{-q}| turn warnings off;} | ||
| 8711 | @item{@T{--}| stops handling options;} | 8724 | @item{@T{--}| stops handling options;} |
| 8712 | @item{@T{-}| executes @id{stdin} as a file and stops handling options.} | 8725 | @item{@T{-}| executes @id{stdin} as a file and stops handling options.} |
| 8713 | } | 8726 | } |
| @@ -8733,12 +8746,13 @@ setting the values of | |||
| 8733 | @Lid{package.path} and @Lid{package.cpath} | 8746 | @Lid{package.path} and @Lid{package.cpath} |
| 8734 | with the default paths defined in @id{luaconf.h}. | 8747 | with the default paths defined in @id{luaconf.h}. |
| 8735 | 8748 | ||
| 8736 | All options are handled in order, except @T{-i} and @T{-E}. | 8749 | The options @T{-e}, @T{-l}, and @T{-q} are handled in |
| 8750 | the order they appear. | ||
| 8737 | For instance, an invocation like | 8751 | For instance, an invocation like |
| 8738 | @verbatim{ | 8752 | @verbatim{ |
| 8739 | $ lua -e'a=1' -e 'print(a)' script.lua | 8753 | $ lua -e 'a=1' -llib1 script.lua |
| 8740 | } | 8754 | } |
| 8741 | will first set @id{a} to 1, then print the value of @id{a}, | 8755 | will first set @id{a} to 1, then require the library @id{lib1}, |
| 8742 | and finally run the file @id{script.lua} with no arguments. | 8756 | and finally run the file @id{script.lua} with no arguments. |
| 8743 | (Here @T{$} is the shell prompt. Your prompt may be different.) | 8757 | (Here @T{$} is the shell prompt. Your prompt may be different.) |
| 8744 | 8758 | ||
| @@ -8798,7 +8812,8 @@ has a metamethod @idx{__tostring}, | |||
| 8798 | the interpreter calls this metamethod to produce the final message. | 8812 | the interpreter calls this metamethod to produce the final message. |
| 8799 | Otherwise, the interpreter converts the error object to a string | 8813 | Otherwise, the interpreter converts the error object to a string |
| 8800 | and adds a stack traceback to it. | 8814 | and adds a stack traceback to it. |
| 8801 | Warnings are simply printed in the standard error output. | 8815 | When warnings are on, |
| 8816 | they are simply printed in the standard error output. | ||
| 8802 | 8817 | ||
| 8803 | When finishing normally, | 8818 | When finishing normally, |
| 8804 | the interpreter closes its main Lua state | 8819 | the interpreter closes its main Lua state |
diff --git a/testes/all.lua b/testes/all.lua index bf27f106..5d698d4b 100644 --- a/testes/all.lua +++ b/testes/all.lua | |||
| @@ -209,6 +209,10 @@ if #msgs > 0 then | |||
| 209 | warn("#tests not performed:\n ", m, "\n") | 209 | warn("#tests not performed:\n ", m, "\n") |
| 210 | end | 210 | end |
| 211 | 211 | ||
| 212 | warn("@off") | ||
| 213 | warn("******** THIS WARNING SHOULD NOT APPEAR **********") | ||
| 214 | warn("******** THIS WARNING ALSO SHOULD NOT APPEAR **********") | ||
| 215 | warn("@on") | ||
| 212 | print("(there should be two warnings now)") | 216 | print("(there should be two warnings now)") |
| 213 | warn("#This is ", "an expected", " warning") | 217 | warn("#This is ", "an expected", " warning") |
| 214 | warn("#This is", " another one") | 218 | warn("#This is", " another one") |
diff --git a/testes/api.lua b/testes/api.lua index f6915c3e..4f9d6717 100644 --- a/testes/api.lua +++ b/testes/api.lua | |||
| @@ -977,6 +977,7 @@ assert(t[7] == nil) | |||
| 977 | 977 | ||
| 978 | ------------------------------------------------------------------------- | 978 | ------------------------------------------------------------------------- |
| 979 | do -- testing errors during GC | 979 | do -- testing errors during GC |
| 980 | warn("@off") | ||
| 980 | collectgarbage("stop") | 981 | collectgarbage("stop") |
| 981 | local a = {} | 982 | local a = {} |
| 982 | for i=1,20 do | 983 | for i=1,20 do |
| @@ -994,6 +995,7 @@ do -- testing errors during GC | |||
| 994 | collectgarbage() | 995 | collectgarbage() |
| 995 | assert(A == 10) -- number of normal collections | 996 | assert(A == 10) -- number of normal collections |
| 996 | collectgarbage("restart") | 997 | collectgarbage("restart") |
| 998 | warn("@on") | ||
| 997 | end | 999 | end |
| 998 | ------------------------------------------------------------------------- | 1000 | ------------------------------------------------------------------------- |
| 999 | -- test for userdata vals | 1001 | -- test for userdata vals |
diff --git a/testes/gc.lua b/testes/gc.lua index 9ea054c1..6bdc98ca 100644 --- a/testes/gc.lua +++ b/testes/gc.lua | |||
| @@ -369,6 +369,7 @@ if T then | |||
| 369 | s[n] = i | 369 | s[n] = i |
| 370 | end | 370 | end |
| 371 | 371 | ||
| 372 | warn("@store") | ||
| 372 | collectgarbage() | 373 | collectgarbage() |
| 373 | assert(string.find(_WARN, "error in __gc metamethod")) | 374 | assert(string.find(_WARN, "error in __gc metamethod")) |
| 374 | assert(string.match(_WARN, "@(.-)@") == "expected") | 375 | assert(string.match(_WARN, "@(.-)@") == "expected") |
| @@ -383,6 +384,7 @@ if T then | |||
| 383 | for i = 1, 10 do assert(s[i]) end | 384 | for i = 1, 10 do assert(s[i]) end |
| 384 | 385 | ||
| 385 | getmetatable(u).__gc = nil | 386 | getmetatable(u).__gc = nil |
| 387 | warn("@normal") | ||
| 386 | 388 | ||
| 387 | end | 389 | end |
| 388 | print '+' | 390 | print '+' |
| @@ -475,9 +477,11 @@ end | |||
| 475 | 477 | ||
| 476 | -- errors during collection | 478 | -- errors during collection |
| 477 | if T then | 479 | if T then |
| 480 | warn("@store") | ||
| 478 | u = setmetatable({}, {__gc = function () error "@expected error" end}) | 481 | u = setmetatable({}, {__gc = function () error "@expected error" end}) |
| 479 | u = nil | 482 | u = nil |
| 480 | collectgarbage() | 483 | collectgarbage() |
| 484 | warn("@normal") | ||
| 481 | end | 485 | end |
| 482 | 486 | ||
| 483 | 487 | ||
| @@ -645,7 +649,7 @@ end | |||
| 645 | 649 | ||
| 646 | -- create several objects to raise errors when collected while closing state | 650 | -- create several objects to raise errors when collected while closing state |
| 647 | if T then | 651 | if T then |
| 648 | local error, assert, find = error, assert, string.find | 652 | local error, assert, find, warn = error, assert, string.find, warn |
| 649 | local n = 0 | 653 | local n = 0 |
| 650 | local lastmsg | 654 | local lastmsg |
| 651 | local mt = {__gc = function (o) | 655 | local mt = {__gc = function (o) |
| @@ -659,7 +663,9 @@ if T then | |||
| 659 | else | 663 | else |
| 660 | assert(lastmsg == _WARN) -- subsequent error messages are equal | 664 | assert(lastmsg == _WARN) -- subsequent error messages are equal |
| 661 | end | 665 | end |
| 666 | warn("@store") | ||
| 662 | error"@expected warning" | 667 | error"@expected warning" |
| 668 | warn("@normal") | ||
| 663 | end} | 669 | end} |
| 664 | for i = 10, 1, -1 do | 670 | for i = 10, 1, -1 do |
| 665 | -- create object and preserve it until the end | 671 | -- create object and preserve it until the end |
diff --git a/testes/main.lua b/testes/main.lua index b224b54e..0ef4822d 100644 --- a/testes/main.lua +++ b/testes/main.lua | |||
| @@ -221,6 +221,28 @@ assert(string.find(getoutput(), "error calling 'print'")) | |||
| 221 | RUN('echo "io.stderr:write(1000)\ncont" | lua -e "require\'debug\'.debug()" 2> %s', out) | 221 | RUN('echo "io.stderr:write(1000)\ncont" | lua -e "require\'debug\'.debug()" 2> %s', out) |
| 222 | checkout("lua_debug> 1000lua_debug> ") | 222 | checkout("lua_debug> 1000lua_debug> ") |
| 223 | 223 | ||
| 224 | -- test warnings | ||
| 225 | RUN('echo "io.stderr:write(1); warn[[XXX]]" | lua -q 2> %s', out) | ||
| 226 | checkout("1") | ||
| 227 | |||
| 228 | prepfile[[ | ||
| 229 | warn("@allow") -- unknown control, ignored | ||
| 230 | warn("@off", "XXX", "@off") -- these are not control messages | ||
| 231 | warn("@off") -- this one is | ||
| 232 | warn("@on", "YYY", "@on") -- not control, but warn is off | ||
| 233 | warn("@off") -- keep it off | ||
| 234 | warn("@on") -- restart warnings | ||
| 235 | warn("", "@on") -- again, no control, real warning | ||
| 236 | warn("@on") -- keep it "started" | ||
| 237 | warn("Z", "Z", "Z") -- common warning | ||
| 238 | ]] | ||
| 239 | RUN('lua %s 2> %s', prog, out) | ||
| 240 | checkout[[ | ||
| 241 | Lua warning: @offXXX@off | ||
| 242 | Lua warning: @on | ||
| 243 | Lua warning: ZZZ | ||
| 244 | ]] | ||
| 245 | |||
| 224 | -- test many arguments | 246 | -- test many arguments |
| 225 | prepfile[[print(({...})[30])]] | 247 | prepfile[[print(({...})[30])]] |
| 226 | RUN('lua %s %s > %s', prog, string.rep(" a", 30), out) | 248 | RUN('lua %s %s > %s', prog, string.rep(" a", 30), out) |
| @@ -355,8 +377,15 @@ if T then -- test library? | |||
| 355 | NoRun("not enough memory", "env MEMLIMIT=100 lua") | 377 | NoRun("not enough memory", "env MEMLIMIT=100 lua") |
| 356 | 378 | ||
| 357 | -- testing 'warn' | 379 | -- testing 'warn' |
| 380 | warn("@store") | ||
| 358 | warn("@123", "456", "789") | 381 | warn("@123", "456", "789") |
| 359 | assert(_WARN == "@123456789") | 382 | assert(_WARN == "@123456789") |
| 383 | |||
| 384 | warn("zip", "", " ", "zap") | ||
| 385 | assert(_WARN == "zip zap") | ||
| 386 | warn("ZIP", "", " ", "ZAP") | ||
| 387 | assert(_WARN == "ZIP ZAP") | ||
| 388 | warn("@normal") | ||
| 360 | end | 389 | end |
| 361 | 390 | ||
| 362 | do | 391 | do |
