diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-01-01 12:14:56 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-01-01 12:14:56 -0200 |
| commit | c6f7181e910b6b2ff1346b5486a31be87b1da5af (patch) | |
| tree | 92cc716487c83ecd9860444f23fd55ef65358cbb /ltests.c | |
| parent | 437a5b07d415e1a74160ddfd804017171d6cc5cb (diff) | |
| download | lua-c6f7181e910b6b2ff1346b5486a31be87b1da5af.tar.gz lua-c6f7181e910b6b2ff1346b5486a31be87b1da5af.tar.bz2 lua-c6f7181e910b6b2ff1346b5486a31be87b1da5af.zip | |
No more LUA_ERRGCMM errors
Errors in finalizers (__gc metamethods) are never propagated.
Instead, they generate a warning.
Diffstat (limited to 'ltests.c')
| -rw-r--r-- | ltests.c | 61 |
1 files changed, 48 insertions, 13 deletions
| @@ -63,7 +63,11 @@ static void pushobject (lua_State *L, const TValue *o) { | |||
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | 65 | ||
| 66 | static void badexit (void) { | 66 | static void badexit (const char *fmt, ...) { |
| 67 | va_list argp; | ||
| 68 | va_start(argp, fmt); | ||
| 69 | vfprintf(stderr, fmt, argp); | ||
| 70 | va_end(argp); | ||
| 67 | /* avoid assertion failures when exiting */ | 71 | /* avoid assertion failures when exiting */ |
| 68 | l_memcontrol.numblocks = l_memcontrol.total = 0; | 72 | l_memcontrol.numblocks = l_memcontrol.total = 0; |
| 69 | exit(EXIT_FAILURE); | 73 | exit(EXIT_FAILURE); |
| @@ -71,9 +75,9 @@ static void badexit (void) { | |||
| 71 | 75 | ||
| 72 | 76 | ||
| 73 | static int tpanic (lua_State *L) { | 77 | static int tpanic (lua_State *L) { |
| 74 | fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n", | 78 | return (badexit("PANIC: unprotected error in call to Lua API (%s)\n", |
| 75 | lua_tostring(L, -1)); | 79 | lua_tostring(L, -1)), |
| 76 | return (badexit(), 0); /* do not return to Lua */ | 80 | 0); /* do not return to Lua */ |
| 77 | } | 81 | } |
| 78 | 82 | ||
| 79 | 83 | ||
| @@ -83,16 +87,47 @@ static int islast (const char *message) { | |||
| 83 | } | 87 | } |
| 84 | 88 | ||
| 85 | 89 | ||
| 90 | /* | ||
| 91 | ** Warning function for tests. Fist, it concatenates all parts of | ||
| 92 | ** a warning in buffer 'buff'. Then: | ||
| 93 | ** messages starting with '#' are shown on standard output (used to | ||
| 94 | ** test explicit warnings); | ||
| 95 | ** messages containing '@' are stored in global '_WARN' (used to test | ||
| 96 | ** errors that generate warnings); | ||
| 97 | ** other messages abort the tests (they represent real warning conditions; | ||
| 98 | ** the standard tests should not generate these conditions unexpectedly). | ||
| 99 | */ | ||
| 86 | static void warnf (void **pud, const char *msg) { | 100 | static void warnf (void **pud, const char *msg) { |
| 87 | if (*pud == NULL) /* continuation line? */ | 101 | static char buff[200]; /* should be enough for tests... */ |
| 88 | printf("%s", msg); /* print it */ | 102 | static int cont = 0; /* message to be continued */ |
| 89 | else if (msg[0] == '*') /* expected warning? */ | 103 | if (cont) { /* continuation? */ |
| 90 | printf("Expected Lua warning: %s", msg + 1); /* print without the star */ | 104 | if (strlen(msg) >= sizeof(buff) - strlen(buff)) |
| 91 | else { /* a real warning; should not happen during tests */ | 105 | badexit("warnf-buffer overflow"); |
| 92 | fprintf(stderr, "Warning in test mode (%s), aborting...\n", msg); | 106 | strcat(buff, msg); /* add new message to current warning */ |
| 93 | badexit(); | 107 | } |
| 94 | } | 108 | else { /* new warning */ |
| 95 | *pud = islast(msg) ? pud : NULL; | 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? */ | ||
| 118 | printf("Expected Lua warning: %s", buff); /* print it */ | ||
| 119 | else if (strchr(buff, '@') != NULL) { /* warning for test purposes? */ | ||
| 120 | lua_State *L = cast(lua_State *, *pud); | ||
| 121 | lua_unlock(L); | ||
| 122 | lua_pushstring(L, buff); | ||
| 123 | lua_setglobal(L, "_WARN"); /* assign message to global '_WARN' */ | ||
| 124 | lua_lock(L); | ||
| 125 | return; | ||
| 126 | } | ||
| 127 | else { /* a real warning; should not happen during tests */ | ||
| 128 | badexit("Unexpected warning in test mode: %s\naborting...\n", buff); | ||
| 129 | } | ||
| 130 | } | ||
| 96 | } | 131 | } |
| 97 | 132 | ||
| 98 | 133 | ||
