diff options
-rw-r--r-- | lobject.c | 66 |
1 files changed, 38 insertions, 28 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lobject.c,v 2.24 2006/11/22 11:02:03 roberto Exp roberto $ | 2 | ** $Id: lobject.c,v 2.25 2007/04/10 12:18:17 roberto Exp roberto $ |
3 | ** Some generic functions over Lua objects | 3 | ** Some generic functions over Lua objects |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -161,36 +161,46 @@ const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { | |||
161 | } | 161 | } |
162 | 162 | ||
163 | 163 | ||
164 | |||
165 | #define LL(x) (sizeof(x) - 1) | ||
166 | #define RETS "..." | ||
167 | #define PRE "[string \"" | ||
168 | #define POS "\"]" | ||
169 | |||
170 | #define addstr(a,b,l) ( memcpy(a,b,l), a += (l) ) | ||
171 | |||
164 | void luaO_chunkid (char *out, const char *source, size_t bufflen) { | 172 | void luaO_chunkid (char *out, const char *source, size_t bufflen) { |
165 | if (*source == '=') { | 173 | size_t l = strlen(source); |
166 | strncpy(out, source+1, bufflen); /* remove first char */ | 174 | if (*source == '=') { /* 'literal' source */ |
167 | out[bufflen-1] = '\0'; /* ensures null termination */ | 175 | if (l <= bufflen) /* small enough? */ |
176 | memcpy(out, source + 1, l); | ||
177 | else { /* truncate it */ | ||
178 | addstr(out, source + 1, bufflen - 1); | ||
179 | *out = '\0'; | ||
180 | } | ||
168 | } | 181 | } |
169 | else { /* out = "source", or "...source" */ | 182 | else if (*source == '@') { /* file name */ |
170 | if (*source == '@') { | 183 | if (l <= bufflen) /* small enough? */ |
171 | size_t l; | 184 | memcpy(out, source + 1, l); |
172 | source++; /* skip the `@' */ | 185 | else { /* add '...' before rest of name */ |
173 | bufflen -= sizeof(" '...' "); | 186 | addstr(out, RETS, LL(RETS)); |
174 | l = strlen(source); | 187 | bufflen -= LL(RETS); |
175 | strcpy(out, ""); | 188 | memcpy(out, source + 1 + l - bufflen, bufflen); |
176 | if (l > bufflen) { | ||
177 | source += (l-bufflen); /* get last part of file name */ | ||
178 | strcat(out, "..."); | ||
179 | } | ||
180 | strcat(out, source); | ||
181 | } | 189 | } |
182 | else { /* out = [string "string"] */ | 190 | } |
183 | size_t len = strcspn(source, "\n\r"); /* stop at first newline */ | 191 | else { /* string; format as [string "source"] */ |
184 | bufflen -= sizeof(" [string \"...\"] "); | 192 | const char *nl = strchr(source, '\n'); /* find first new line (if any) */ |
185 | if (len > bufflen) len = bufflen; | 193 | addstr(out, PRE, LL(PRE)); /* add prefix */ |
186 | strcpy(out, "[string \""); | 194 | bufflen -= LL(PRE RETS POS); /* save space for prefix+sufix */ |
187 | if (source[len] != '\0') { /* must truncate? */ | 195 | if (l < bufflen && nl == NULL) { /* small one-line source? */ |
188 | strncat(out, source, len); | 196 | addstr(out, source, l); /* keep it */ |
189 | strcat(out, "..."); | 197 | } |
190 | } | 198 | else { |
191 | else | 199 | if (nl != NULL) l = nl - source; /* stop at first newline */ |
192 | strcat(out, source); | 200 | if (l > bufflen) l = bufflen; |
193 | strcat(out, "\"]"); | 201 | addstr(out, source, l); |
202 | addstr(out, RETS, LL(RETS)); | ||
194 | } | 203 | } |
204 | memcpy(out, POS, LL(POS) + 1); | ||
195 | } | 205 | } |
196 | } | 206 | } |