diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-02-23 14:17:25 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-02-23 14:17:25 -0300 |
| commit | 39b79783297bee79db9853b63d199e120a009a8f (patch) | |
| tree | c738c621c4c28d8822c2f785400786301985273b /lstrlib.c | |
| parent | d164e2294f73d8e69f00d95a66014514b2dd0ec0 (diff) | |
| download | lua-39b79783297bee79db9853b63d199e120a009a8f.tar.gz lua-39b79783297bee79db9853b63d199e120a009a8f.tar.bz2 lua-39b79783297bee79db9853b63d199e120a009a8f.zip | |
first (big) step to support wide chars
Diffstat (limited to 'lstrlib.c')
| -rw-r--r-- | lstrlib.c | 254 |
1 files changed, 127 insertions, 127 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstrlib.c,v 1.63 2001/02/22 17:15:18 roberto Exp roberto $ | 2 | ** $Id: lstrlib.c,v 1.64 2001/02/22 18:59:59 roberto Exp roberto $ |
| 3 | ** Standard library for string operations and pattern-matching | 3 | ** Standard library for string operations and pattern-matching |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -36,14 +36,14 @@ static sint32 posrelat (sint32 pos, size_t len) { | |||
| 36 | 36 | ||
| 37 | static int str_sub (lua_State *L) { | 37 | static int str_sub (lua_State *L) { |
| 38 | size_t l; | 38 | size_t l; |
| 39 | const char *s = luaL_check_lstr(L, 1, &l); | 39 | const l_char *s = luaL_check_lstr(L, 1, &l); |
| 40 | sint32 start = posrelat(luaL_check_long(L, 2), l); | 40 | sint32 start = posrelat(luaL_check_long(L, 2), l); |
| 41 | sint32 end = posrelat(luaL_opt_long(L, 3, -1), l); | 41 | sint32 end = posrelat(luaL_opt_long(L, 3, -1), l); |
| 42 | if (start < 1) start = 1; | 42 | if (start < 1) start = 1; |
| 43 | if (end > (sint32)l) end = l; | 43 | if (end > (sint32)l) end = l; |
| 44 | if (start <= end) | 44 | if (start <= end) |
| 45 | lua_pushlstring(L, s+start-1, end-start+1); | 45 | lua_pushlstring(L, s+start-1, end-start+1); |
| 46 | else lua_pushliteral(L, ""); | 46 | else lua_pushliteral(L, l_s("")); |
| 47 | return 1; | 47 | return 1; |
| 48 | } | 48 | } |
| 49 | 49 | ||
| @@ -52,7 +52,7 @@ static int str_lower (lua_State *L) { | |||
| 52 | size_t l; | 52 | size_t l; |
| 53 | size_t i; | 53 | size_t i; |
| 54 | luaL_Buffer b; | 54 | luaL_Buffer b; |
| 55 | const char *s = luaL_check_lstr(L, 1, &l); | 55 | const l_char *s = luaL_check_lstr(L, 1, &l); |
| 56 | luaL_buffinit(L, &b); | 56 | luaL_buffinit(L, &b); |
| 57 | for (i=0; i<l; i++) | 57 | for (i=0; i<l; i++) |
| 58 | luaL_putchar(&b, tolower(uchar(s[i]))); | 58 | luaL_putchar(&b, tolower(uchar(s[i]))); |
| @@ -65,7 +65,7 @@ static int str_upper (lua_State *L) { | |||
| 65 | size_t l; | 65 | size_t l; |
| 66 | size_t i; | 66 | size_t i; |
| 67 | luaL_Buffer b; | 67 | luaL_Buffer b; |
| 68 | const char *s = luaL_check_lstr(L, 1, &l); | 68 | const l_char *s = luaL_check_lstr(L, 1, &l); |
| 69 | luaL_buffinit(L, &b); | 69 | luaL_buffinit(L, &b); |
| 70 | for (i=0; i<l; i++) | 70 | for (i=0; i<l; i++) |
| 71 | luaL_putchar(&b, toupper(uchar(s[i]))); | 71 | luaL_putchar(&b, toupper(uchar(s[i]))); |
| @@ -76,7 +76,7 @@ static int str_upper (lua_State *L) { | |||
| 76 | static int str_rep (lua_State *L) { | 76 | static int str_rep (lua_State *L) { |
| 77 | size_t l; | 77 | size_t l; |
| 78 | luaL_Buffer b; | 78 | luaL_Buffer b; |
| 79 | const char *s = luaL_check_lstr(L, 1, &l); | 79 | const l_char *s = luaL_check_lstr(L, 1, &l); |
| 80 | int n = luaL_check_int(L, 2); | 80 | int n = luaL_check_int(L, 2); |
| 81 | luaL_buffinit(L, &b); | 81 | luaL_buffinit(L, &b); |
| 82 | while (n-- > 0) | 82 | while (n-- > 0) |
| @@ -88,9 +88,9 @@ static int str_rep (lua_State *L) { | |||
| 88 | 88 | ||
| 89 | static int str_byte (lua_State *L) { | 89 | static int str_byte (lua_State *L) { |
| 90 | size_t l; | 90 | size_t l; |
| 91 | const char *s = luaL_check_lstr(L, 1, &l); | 91 | const l_char *s = luaL_check_lstr(L, 1, &l); |
| 92 | sint32 pos = posrelat(luaL_opt_long(L, 2, 1), l); | 92 | sint32 pos = posrelat(luaL_opt_long(L, 2, 1), l); |
| 93 | luaL_arg_check(L, 0<pos && (size_t)pos<=l, 2, "out of range"); | 93 | luaL_arg_check(L, 0<pos && (size_t)pos<=l, 2, l_s("out of range")); |
| 94 | lua_pushnumber(L, uchar(s[pos-1])); | 94 | lua_pushnumber(L, uchar(s[pos-1])); |
| 95 | return 1; | 95 | return 1; |
| 96 | } | 96 | } |
| @@ -103,7 +103,7 @@ static int str_char (lua_State *L) { | |||
| 103 | luaL_buffinit(L, &b); | 103 | luaL_buffinit(L, &b); |
| 104 | for (i=1; i<=n; i++) { | 104 | for (i=1; i<=n; i++) { |
| 105 | int c = luaL_check_int(L, i); | 105 | int c = luaL_check_int(L, i); |
| 106 | luaL_arg_check(L, uchar(c) == c, i, "invalid value"); | 106 | luaL_arg_check(L, uchar(c) == c, i, l_s("invalid value")); |
| 107 | luaL_putchar(&b, uchar(c)); | 107 | luaL_putchar(&b, uchar(c)); |
| 108 | } | 108 | } |
| 109 | luaL_pushresult(&b); | 109 | luaL_pushresult(&b); |
| @@ -127,25 +127,25 @@ static int str_char (lua_State *L) { | |||
| 127 | #define CAP_POSITION (-2) | 127 | #define CAP_POSITION (-2) |
| 128 | 128 | ||
| 129 | typedef struct MatchState { | 129 | typedef struct MatchState { |
| 130 | const char *src_init; /* init of source string */ | 130 | const l_char *src_init; /* init of source string */ |
| 131 | const char *src_end; /* end (`\0') of source string */ | 131 | const l_char *src_end; /* end (`\0') of source string */ |
| 132 | int level; /* total number of captures (finished or unfinished) */ | 132 | int level; /* total number of captures (finished or unfinished) */ |
| 133 | struct { | 133 | struct { |
| 134 | const char *init; | 134 | const l_char *init; |
| 135 | sint32 len; | 135 | sint32 len; |
| 136 | } capture[MAX_CAPTURES]; | 136 | } capture[MAX_CAPTURES]; |
| 137 | lua_State *L; | 137 | lua_State *L; |
| 138 | } MatchState; | 138 | } MatchState; |
| 139 | 139 | ||
| 140 | 140 | ||
| 141 | #define ESC '%' | 141 | #define ESC l_c('%') |
| 142 | #define SPECIALS "^$*+?.([%-" | 142 | #define SPECIALS l_s("^$*+?.([%-") |
| 143 | 143 | ||
| 144 | 144 | ||
| 145 | static int check_capture (MatchState *ms, int l) { | 145 | static int check_capture (MatchState *ms, int l) { |
| 146 | l -= '1'; | 146 | l -= l_c('1'); |
| 147 | if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED) | 147 | if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED) |
| 148 | lua_error(ms->L, "invalid capture index"); | 148 | lua_error(ms->L, l_s("invalid capture index")); |
| 149 | return l; | 149 | return l; |
| 150 | } | 150 | } |
| 151 | 151 | ||
| @@ -154,22 +154,22 @@ static int capture_to_close (MatchState *ms) { | |||
| 154 | int level = ms->level; | 154 | int level = ms->level; |
| 155 | for (level--; level>=0; level--) | 155 | for (level--; level>=0; level--) |
| 156 | if (ms->capture[level].len == CAP_UNFINISHED) return level; | 156 | if (ms->capture[level].len == CAP_UNFINISHED) return level; |
| 157 | lua_error(ms->L, "invalid pattern capture"); | 157 | lua_error(ms->L, l_s("invalid pattern capture")); |
| 158 | return 0; /* to avoid warnings */ | 158 | return 0; /* to avoid warnings */ |
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | 161 | ||
| 162 | static const char *luaI_classend (MatchState *ms, const char *p) { | 162 | static const l_char *luaI_classend (MatchState *ms, const l_char *p) { |
| 163 | switch (*p++) { | 163 | switch (*p++) { |
| 164 | case ESC: | 164 | case ESC: |
| 165 | if (*p == '\0') lua_error(ms->L, "malformed pattern (ends with `%')"); | 165 | if (*p == l_c('\0')) lua_error(ms->L, l_s("malformed pattern (ends with `%')")); |
| 166 | return p+1; | 166 | return p+1; |
| 167 | case '[': | 167 | case l_c('['): |
| 168 | if (*p == '^') p++; | 168 | if (*p == l_c('^')) p++; |
| 169 | do { /* look for a `]' */ | 169 | do { /* look for a `]' */ |
| 170 | if (*p == '\0') lua_error(ms->L, "malformed pattern (missing `]')"); | 170 | if (*p == l_c('\0')) lua_error(ms->L, l_s("malformed pattern (missing `]')")); |
| 171 | if (*(p++) == ESC && *p != '\0') p++; /* skip escapes (e.g. `%]') */ | 171 | if (*(p++) == ESC && *p != l_c('\0')) p++; /* skip escapes (e.g. `%]') */ |
| 172 | } while (*p != ']'); | 172 | } while (*p != l_c(']')); |
| 173 | return p+1; | 173 | return p+1; |
| 174 | default: | 174 | default: |
| 175 | return p; | 175 | return p; |
| @@ -177,28 +177,28 @@ static const char *luaI_classend (MatchState *ms, const char *p) { | |||
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | 179 | ||
| 180 | static int match_class (char c, char cl) { | 180 | static int match_class (l_char c, l_char cl) { |
| 181 | int res; | 181 | int res; |
| 182 | switch (tolower(uchar(cl))) { | 182 | switch (tolower(uchar(cl))) { |
| 183 | case 'a' : res = isalpha(uchar(c)); break; | 183 | case l_c('a') : res = isalpha(uchar(c)); break; |
| 184 | case 'c' : res = iscntrl(uchar(c)); break; | 184 | case l_c('c') : res = iscntrl(uchar(c)); break; |
| 185 | case 'd' : res = isdigit(uchar(c)); break; | 185 | case l_c('d') : res = isdigit(uchar(c)); break; |
| 186 | case 'l' : res = islower(uchar(c)); break; | 186 | case l_c('l') : res = islower(uchar(c)); break; |
| 187 | case 'p' : res = ispunct(uchar(c)); break; | 187 | case l_c('p') : res = ispunct(uchar(c)); break; |
| 188 | case 's' : res = isspace(uchar(c)); break; | 188 | case l_c('s') : res = isspace(uchar(c)); break; |
| 189 | case 'u' : res = isupper(uchar(c)); break; | 189 | case l_c('u') : res = isupper(uchar(c)); break; |
| 190 | case 'w' : res = isalnum(uchar(c)); break; | 190 | case l_c('w') : res = isalnum(uchar(c)); break; |
| 191 | case 'x' : res = isxdigit(uchar(c)); break; | 191 | case l_c('x') : res = isxdigit(uchar(c)); break; |
| 192 | case 'z' : res = (c == '\0'); break; | 192 | case l_c('z') : res = (c == l_c('\0')); break; |
| 193 | default: return (cl == c); | 193 | default: return (cl == c); |
| 194 | } | 194 | } |
| 195 | return (islower(uchar(cl)) ? res : !res); | 195 | return (islower(uchar(cl)) ? res : !res); |
| 196 | } | 196 | } |
| 197 | 197 | ||
| 198 | 198 | ||
| 199 | static int matchbracketclass (char c, const char *p, const char *endclass) { | 199 | static int matchbracketclass (l_char c, const l_char *p, const l_char *endclass) { |
| 200 | int sig = 1; | 200 | int sig = 1; |
| 201 | if (*(p+1) == '^') { | 201 | if (*(p+1) == l_c('^')) { |
| 202 | sig = 0; | 202 | sig = 0; |
| 203 | p++; /* skip the `^' */ | 203 | p++; /* skip the `^' */ |
| 204 | } | 204 | } |
| @@ -208,7 +208,7 @@ static int matchbracketclass (char c, const char *p, const char *endclass) { | |||
| 208 | if (match_class(c, *p)) | 208 | if (match_class(c, *p)) |
| 209 | return sig; | 209 | return sig; |
| 210 | } | 210 | } |
| 211 | else if ((*(p+1) == '-') && (p+2 < endclass)) { | 211 | else if ((*(p+1) == l_c('-')) && (p+2 < endclass)) { |
| 212 | p+=2; | 212 | p+=2; |
| 213 | if (uchar(*(p-2)) <= uchar(c) && uchar(c) <= uchar(*p)) | 213 | if (uchar(*(p-2)) <= uchar(c) && uchar(c) <= uchar(*p)) |
| 214 | return sig; | 214 | return sig; |
| @@ -219,13 +219,13 @@ static int matchbracketclass (char c, const char *p, const char *endclass) { | |||
| 219 | } | 219 | } |
| 220 | 220 | ||
| 221 | 221 | ||
| 222 | static int luaI_singlematch (char c, const char *p, const char *ep) { | 222 | static int luaI_singlematch (l_char c, const l_char *p, const l_char *ep) { |
| 223 | switch (*p) { | 223 | switch (*p) { |
| 224 | case '.': /* matches any char */ | 224 | case l_c('.'): /* matches any char */ |
| 225 | return 1; | 225 | return 1; |
| 226 | case ESC: | 226 | case ESC: |
| 227 | return match_class(c, *(p+1)); | 227 | return match_class(c, *(p+1)); |
| 228 | case '[': | 228 | case l_c('['): |
| 229 | return matchbracketclass(c, p, ep-1); | 229 | return matchbracketclass(c, p, ep-1); |
| 230 | default: | 230 | default: |
| 231 | return (*p == c); | 231 | return (*p == c); |
| @@ -233,12 +233,12 @@ static int luaI_singlematch (char c, const char *p, const char *ep) { | |||
| 233 | } | 233 | } |
| 234 | 234 | ||
| 235 | 235 | ||
| 236 | static const char *match (MatchState *ms, const char *s, const char *p); | 236 | static const l_char *match (MatchState *ms, const l_char *s, const l_char *p); |
| 237 | 237 | ||
| 238 | 238 | ||
| 239 | static const char *matchbalance (MatchState *ms, const char *s, const char *p) { | 239 | static const l_char *matchbalance (MatchState *ms, const l_char *s, const l_char *p) { |
| 240 | if (*p == 0 || *(p+1) == 0) | 240 | if (*p == 0 || *(p+1) == 0) |
| 241 | lua_error(ms->L, "unbalanced pattern"); | 241 | lua_error(ms->L, l_s("unbalanced pattern")); |
| 242 | if (*s != *p) return NULL; | 242 | if (*s != *p) return NULL; |
| 243 | else { | 243 | else { |
| 244 | int b = *p; | 244 | int b = *p; |
| @@ -255,14 +255,14 @@ static const char *matchbalance (MatchState *ms, const char *s, const char *p) { | |||
| 255 | } | 255 | } |
| 256 | 256 | ||
| 257 | 257 | ||
| 258 | static const char *max_expand (MatchState *ms, const char *s, const char *p, | 258 | static const l_char *max_expand (MatchState *ms, const l_char *s, const l_char *p, |
| 259 | const char *ep) { | 259 | const l_char *ep) { |
| 260 | sint32 i = 0; /* counts maximum expand for item */ | 260 | sint32 i = 0; /* counts maximum expand for item */ |
| 261 | while ((s+i)<ms->src_end && luaI_singlematch(*(s+i), p, ep)) | 261 | while ((s+i)<ms->src_end && luaI_singlematch(*(s+i), p, ep)) |
| 262 | i++; | 262 | i++; |
| 263 | /* keeps trying to match with the maximum repetitions */ | 263 | /* keeps trying to match with the maximum repetitions */ |
| 264 | while (i>=0) { | 264 | while (i>=0) { |
| 265 | const char *res = match(ms, (s+i), ep+1); | 265 | const l_char *res = match(ms, (s+i), ep+1); |
| 266 | if (res) return res; | 266 | if (res) return res; |
| 267 | i--; /* else didn't match; reduce 1 repetition to try again */ | 267 | i--; /* else didn't match; reduce 1 repetition to try again */ |
| 268 | } | 268 | } |
| @@ -270,10 +270,10 @@ static const char *max_expand (MatchState *ms, const char *s, const char *p, | |||
| 270 | } | 270 | } |
| 271 | 271 | ||
| 272 | 272 | ||
| 273 | static const char *min_expand (MatchState *ms, const char *s, const char *p, | 273 | static const l_char *min_expand (MatchState *ms, const l_char *s, const l_char *p, |
| 274 | const char *ep) { | 274 | const l_char *ep) { |
| 275 | for (;;) { | 275 | for (;;) { |
| 276 | const char *res = match(ms, s, ep+1); | 276 | const l_char *res = match(ms, s, ep+1); |
| 277 | if (res != NULL) | 277 | if (res != NULL) |
| 278 | return res; | 278 | return res; |
| 279 | else if (s<ms->src_end && luaI_singlematch(*s, p, ep)) | 279 | else if (s<ms->src_end && luaI_singlematch(*s, p, ep)) |
| @@ -283,11 +283,11 @@ static const char *min_expand (MatchState *ms, const char *s, const char *p, | |||
| 283 | } | 283 | } |
| 284 | 284 | ||
| 285 | 285 | ||
| 286 | static const char *start_capture (MatchState *ms, const char *s, | 286 | static const l_char *start_capture (MatchState *ms, const l_char *s, |
| 287 | const char *p, int what) { | 287 | const l_char *p, int what) { |
| 288 | const char *res; | 288 | const l_char *res; |
| 289 | int level = ms->level; | 289 | int level = ms->level; |
| 290 | if (level >= MAX_CAPTURES) lua_error(ms->L, "too many captures"); | 290 | if (level >= MAX_CAPTURES) lua_error(ms->L, l_s("too many captures")); |
| 291 | ms->capture[level].init = s; | 291 | ms->capture[level].init = s; |
| 292 | ms->capture[level].len = what; | 292 | ms->capture[level].len = what; |
| 293 | ms->level = level+1; | 293 | ms->level = level+1; |
| @@ -297,9 +297,9 @@ static const char *start_capture (MatchState *ms, const char *s, | |||
| 297 | } | 297 | } |
| 298 | 298 | ||
| 299 | 299 | ||
| 300 | static const char *end_capture (MatchState *ms, const char *s, const char *p) { | 300 | static const l_char *end_capture (MatchState *ms, const l_char *s, const l_char *p) { |
| 301 | int l = capture_to_close(ms); | 301 | int l = capture_to_close(ms); |
| 302 | const char *res; | 302 | const l_char *res; |
| 303 | ms->capture[l].len = s - ms->capture[l].init; /* close capture */ | 303 | ms->capture[l].len = s - ms->capture[l].init; /* close capture */ |
| 304 | if ((res = match(ms, s, p)) == NULL) /* match failed? */ | 304 | if ((res = match(ms, s, p)) == NULL) /* match failed? */ |
| 305 | ms->capture[l].len = CAP_UNFINISHED; /* undo capture */ | 305 | ms->capture[l].len = CAP_UNFINISHED; /* undo capture */ |
| @@ -307,7 +307,7 @@ static const char *end_capture (MatchState *ms, const char *s, const char *p) { | |||
| 307 | } | 307 | } |
| 308 | 308 | ||
| 309 | 309 | ||
| 310 | static const char *match_capture (MatchState *ms, const char *s, int level) { | 310 | static const l_char *match_capture (MatchState *ms, const l_char *s, int level) { |
| 311 | int l = check_capture(ms, level); | 311 | int l = check_capture(ms, level); |
| 312 | size_t len = ms->capture[l].len; | 312 | size_t len = ms->capture[l].len; |
| 313 | if ((size_t)(ms->src_end-s) >= len && | 313 | if ((size_t)(ms->src_end-s) >= len && |
| @@ -317,15 +317,15 @@ static const char *match_capture (MatchState *ms, const char *s, int level) { | |||
| 317 | } | 317 | } |
| 318 | 318 | ||
| 319 | 319 | ||
| 320 | static const char *match (MatchState *ms, const char *s, const char *p) { | 320 | static const l_char *match (MatchState *ms, const l_char *s, const l_char *p) { |
| 321 | init: /* using goto's to optimize tail recursion */ | 321 | init: /* using goto's to optimize tail recursion */ |
| 322 | switch (*p) { | 322 | switch (*p) { |
| 323 | case '(': /* start capture */ | 323 | case l_c('('): /* start capture */ |
| 324 | if (*(p+1) == ')') /* position capture? */ | 324 | if (*(p+1) == l_c(')')) /* position capture? */ |
| 325 | return start_capture(ms, s, p+2, CAP_POSITION); | 325 | return start_capture(ms, s, p+2, CAP_POSITION); |
| 326 | else | 326 | else |
| 327 | return start_capture(ms, s, p+1, CAP_UNFINISHED); | 327 | return start_capture(ms, s, p+1, CAP_UNFINISHED); |
| 328 | case ')': /* end capture */ | 328 | case l_c(')'): /* end capture */ |
| 329 | return end_capture(ms, s, p+1); | 329 | return end_capture(ms, s, p+1); |
| 330 | case ESC: /* may be %[0-9] or %b */ | 330 | case ESC: /* may be %[0-9] or %b */ |
| 331 | if (isdigit(uchar(*(p+1)))) { /* capture? */ | 331 | if (isdigit(uchar(*(p+1)))) { /* capture? */ |
| @@ -333,33 +333,33 @@ static const char *match (MatchState *ms, const char *s, const char *p) { | |||
| 333 | if (s == NULL) return NULL; | 333 | if (s == NULL) return NULL; |
| 334 | p+=2; goto init; /* else return match(ms, s, p+2) */ | 334 | p+=2; goto init; /* else return match(ms, s, p+2) */ |
| 335 | } | 335 | } |
| 336 | else if (*(p+1) == 'b') { /* balanced string? */ | 336 | else if (*(p+1) == l_c('b')) { /* balanced string? */ |
| 337 | s = matchbalance(ms, s, p+2); | 337 | s = matchbalance(ms, s, p+2); |
| 338 | if (s == NULL) return NULL; | 338 | if (s == NULL) return NULL; |
| 339 | p+=4; goto init; /* else return match(ms, s, p+4); */ | 339 | p+=4; goto init; /* else return match(ms, s, p+4); */ |
| 340 | } | 340 | } |
| 341 | else goto dflt; /* case default */ | 341 | else goto dflt; /* case default */ |
| 342 | case '\0': /* end of pattern */ | 342 | case l_c('\0'): /* end of pattern */ |
| 343 | return s; /* match succeeded */ | 343 | return s; /* match succeeded */ |
| 344 | case '$': | 344 | case l_c('$'): |
| 345 | if (*(p+1) == '\0') /* is the `$' the last char in pattern? */ | 345 | if (*(p+1) == l_c('\0')) /* is the `$' the last char in pattern? */ |
| 346 | return (s == ms->src_end) ? s : NULL; /* check end of string */ | 346 | return (s == ms->src_end) ? s : NULL; /* check end of string */ |
| 347 | else goto dflt; | 347 | else goto dflt; |
| 348 | default: dflt: { /* it is a pattern item */ | 348 | default: dflt: { /* it is a pattern item */ |
| 349 | const char *ep = luaI_classend(ms, p); /* points to what is next */ | 349 | const l_char *ep = luaI_classend(ms, p); /* points to what is next */ |
| 350 | int m = s<ms->src_end && luaI_singlematch(*s, p, ep); | 350 | int m = s<ms->src_end && luaI_singlematch(*s, p, ep); |
| 351 | switch (*ep) { | 351 | switch (*ep) { |
| 352 | case '?': { /* optional */ | 352 | case l_c('?'): { /* optional */ |
| 353 | const char *res; | 353 | const l_char *res; |
| 354 | if (m && ((res=match(ms, s+1, ep+1)) != NULL)) | 354 | if (m && ((res=match(ms, s+1, ep+1)) != NULL)) |
| 355 | return res; | 355 | return res; |
| 356 | p=ep+1; goto init; /* else return match(ms, s, ep+1); */ | 356 | p=ep+1; goto init; /* else return match(ms, s, ep+1); */ |
| 357 | } | 357 | } |
| 358 | case '*': /* 0 or more repetitions */ | 358 | case l_c('*'): /* 0 or more repetitions */ |
| 359 | return max_expand(ms, s, p, ep); | 359 | return max_expand(ms, s, p, ep); |
| 360 | case '+': /* 1 or more repetitions */ | 360 | case l_c('+'): /* 1 or more repetitions */ |
| 361 | return (m ? max_expand(ms, s+1, p, ep) : NULL); | 361 | return (m ? max_expand(ms, s+1, p, ep) : NULL); |
| 362 | case '-': /* 0 or more repetitions (minimum) */ | 362 | case l_c('-'): /* 0 or more repetitions (minimum) */ |
| 363 | return min_expand(ms, s, p, ep); | 363 | return min_expand(ms, s, p, ep); |
| 364 | default: | 364 | default: |
| 365 | if (!m) return NULL; | 365 | if (!m) return NULL; |
| @@ -371,15 +371,15 @@ static const char *match (MatchState *ms, const char *s, const char *p) { | |||
| 371 | 371 | ||
| 372 | 372 | ||
| 373 | 373 | ||
| 374 | static const char *lmemfind (const char *s1, size_t l1, | 374 | static const l_char *lmemfind (const l_char *s1, size_t l1, |
| 375 | const char *s2, size_t l2) { | 375 | const l_char *s2, size_t l2) { |
| 376 | if (l2 == 0) return s1; /* empty strings are everywhere */ | 376 | if (l2 == 0) return s1; /* empty strings are everywhere */ |
| 377 | else if (l2 > l1) return NULL; /* avoids a negative `l1' */ | 377 | else if (l2 > l1) return NULL; /* avoids a negative `l1' */ |
| 378 | else { | 378 | else { |
| 379 | const char *init; /* to search for a `*s2' inside `s1' */ | 379 | const l_char *init; /* to search for a `*s2' inside `s1' */ |
| 380 | l2--; /* 1st char will be checked by `memchr' */ | 380 | l2--; /* 1st char will be checked by `memchr' */ |
| 381 | l1 = l1-l2; /* `s2' cannot be found after that */ | 381 | l1 = l1-l2; /* `s2' cannot be found after that */ |
| 382 | while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) { | 382 | while (l1 > 0 && (init = (const l_char *)memchr(s1, *s2, l1)) != NULL) { |
| 383 | init++; /* 1st char is already checked */ | 383 | init++; /* 1st char is already checked */ |
| 384 | if (memcmp(init, s2+1, l2) == 0) | 384 | if (memcmp(init, s2+1, l2) == 0) |
| 385 | return init-1; | 385 | return init-1; |
| @@ -395,7 +395,7 @@ static const char *lmemfind (const char *s1, size_t l1, | |||
| 395 | 395 | ||
| 396 | static void push_onecapture (MatchState *ms, int i) { | 396 | static void push_onecapture (MatchState *ms, int i) { |
| 397 | int l = ms->capture[i].len; | 397 | int l = ms->capture[i].len; |
| 398 | if (l == CAP_UNFINISHED) lua_error(ms->L, "unfinished capture"); | 398 | if (l == CAP_UNFINISHED) lua_error(ms->L, l_s("unfinished capture")); |
| 399 | if (l == CAP_POSITION) | 399 | if (l == CAP_POSITION) |
| 400 | lua_pushnumber(ms->L, ms->capture[i].init - ms->src_init + 1); | 400 | lua_pushnumber(ms->L, ms->capture[i].init - ms->src_init + 1); |
| 401 | else | 401 | else |
| @@ -405,7 +405,7 @@ static void push_onecapture (MatchState *ms, int i) { | |||
| 405 | 405 | ||
| 406 | static int push_captures (MatchState *ms) { | 406 | static int push_captures (MatchState *ms) { |
| 407 | int i; | 407 | int i; |
| 408 | luaL_checkstack(ms->L, ms->level, "too many captures"); | 408 | luaL_checkstack(ms->L, ms->level, l_s("too many captures")); |
| 409 | for (i=0; i<ms->level; i++) | 409 | for (i=0; i<ms->level; i++) |
| 410 | push_onecapture(ms, i); | 410 | push_onecapture(ms, i); |
| 411 | return ms->level; /* number of strings pushed */ | 411 | return ms->level; /* number of strings pushed */ |
| @@ -414,13 +414,13 @@ static int push_captures (MatchState *ms) { | |||
| 414 | 414 | ||
| 415 | static int str_find (lua_State *L) { | 415 | static int str_find (lua_State *L) { |
| 416 | size_t l1, l2; | 416 | size_t l1, l2; |
| 417 | const char *s = luaL_check_lstr(L, 1, &l1); | 417 | const l_char *s = luaL_check_lstr(L, 1, &l1); |
| 418 | const char *p = luaL_check_lstr(L, 2, &l2); | 418 | const l_char *p = luaL_check_lstr(L, 2, &l2); |
| 419 | sint32 init = posrelat(luaL_opt_long(L, 3, 1), l1) - 1; | 419 | sint32 init = posrelat(luaL_opt_long(L, 3, 1), l1) - 1; |
| 420 | luaL_arg_check(L, 0 <= init && (size_t)init <= l1, 3, "out of range"); | 420 | luaL_arg_check(L, 0 <= init && (size_t)init <= l1, 3, l_s("out of range")); |
| 421 | if (lua_gettop(L) > 3 || /* extra argument? */ | 421 | if (lua_gettop(L) > 3 || /* extra argument? */ |
| 422 | strpbrk(p, SPECIALS) == NULL) { /* or no special characters? */ | 422 | strpbrk(p, SPECIALS) == NULL) { /* or no special characters? */ |
| 423 | const char *s2 = lmemfind(s+init, l1-init, p, l2); | 423 | const l_char *s2 = lmemfind(s+init, l1-init, p, l2); |
| 424 | if (s2) { | 424 | if (s2) { |
| 425 | lua_pushnumber(L, s2-s+1); | 425 | lua_pushnumber(L, s2-s+1); |
| 426 | lua_pushnumber(L, s2-s+l2); | 426 | lua_pushnumber(L, s2-s+l2); |
| @@ -429,13 +429,13 @@ static int str_find (lua_State *L) { | |||
| 429 | } | 429 | } |
| 430 | else { | 430 | else { |
| 431 | MatchState ms; | 431 | MatchState ms; |
| 432 | int anchor = (*p == '^') ? (p++, 1) : 0; | 432 | int anchor = (*p == l_c('^')) ? (p++, 1) : 0; |
| 433 | const char *s1=s+init; | 433 | const l_char *s1=s+init; |
| 434 | ms.L = L; | 434 | ms.L = L; |
| 435 | ms.src_init = s; | 435 | ms.src_init = s; |
| 436 | ms.src_end = s+l1; | 436 | ms.src_end = s+l1; |
| 437 | do { | 437 | do { |
| 438 | const char *res; | 438 | const l_char *res; |
| 439 | ms.level = 0; | 439 | ms.level = 0; |
| 440 | if ((res=match(&ms, s1, p)) != NULL) { | 440 | if ((res=match(&ms, s1, p)) != NULL) { |
| 441 | lua_pushnumber(L, s1-s+1); /* start */ | 441 | lua_pushnumber(L, s1-s+1); /* start */ |
| @@ -452,7 +452,7 @@ static int str_find (lua_State *L) { | |||
| 452 | static void add_s (MatchState *ms, luaL_Buffer *b) { | 452 | static void add_s (MatchState *ms, luaL_Buffer *b) { |
| 453 | lua_State *L = ms->L; | 453 | lua_State *L = ms->L; |
| 454 | if (lua_isstring(L, 3)) { | 454 | if (lua_isstring(L, 3)) { |
| 455 | const char *news = lua_tostring(L, 3); | 455 | const l_char *news = lua_tostring(L, 3); |
| 456 | size_t l = lua_strlen(L, 3); | 456 | size_t l = lua_strlen(L, 3); |
| 457 | size_t i; | 457 | size_t i; |
| 458 | for (i=0; i<l; i++) { | 458 | for (i=0; i<l; i++) { |
| @@ -485,22 +485,22 @@ static void add_s (MatchState *ms, luaL_Buffer *b) { | |||
| 485 | 485 | ||
| 486 | static int str_gsub (lua_State *L) { | 486 | static int str_gsub (lua_State *L) { |
| 487 | size_t srcl; | 487 | size_t srcl; |
| 488 | const char *src = luaL_check_lstr(L, 1, &srcl); | 488 | const l_char *src = luaL_check_lstr(L, 1, &srcl); |
| 489 | const char *p = luaL_check_string(L, 2); | 489 | const l_char *p = luaL_check_string(L, 2); |
| 490 | int max_s = luaL_opt_int(L, 4, srcl+1); | 490 | int max_s = luaL_opt_int(L, 4, srcl+1); |
| 491 | int anchor = (*p == '^') ? (p++, 1) : 0; | 491 | int anchor = (*p == l_c('^')) ? (p++, 1) : 0; |
| 492 | int n = 0; | 492 | int n = 0; |
| 493 | MatchState ms; | 493 | MatchState ms; |
| 494 | luaL_Buffer b; | 494 | luaL_Buffer b; |
| 495 | luaL_arg_check(L, | 495 | luaL_arg_check(L, |
| 496 | lua_gettop(L) >= 3 && (lua_isstring(L, 3) || lua_isfunction(L, 3)), | 496 | lua_gettop(L) >= 3 && (lua_isstring(L, 3) || lua_isfunction(L, 3)), |
| 497 | 3, "string or function expected"); | 497 | 3, l_s("string or function expected")); |
| 498 | luaL_buffinit(L, &b); | 498 | luaL_buffinit(L, &b); |
| 499 | ms.L = L; | 499 | ms.L = L; |
| 500 | ms.src_init = src; | 500 | ms.src_init = src; |
| 501 | ms.src_end = src+srcl; | 501 | ms.src_end = src+srcl; |
| 502 | while (n < max_s) { | 502 | while (n < max_s) { |
| 503 | const char *e; | 503 | const l_char *e; |
| 504 | ms.level = 0; | 504 | ms.level = 0; |
| 505 | e = match(&ms, src, p); | 505 | e = match(&ms, src, p); |
| 506 | if (e) { | 506 | if (e) { |
| @@ -531,40 +531,40 @@ static int str_gsub (lua_State *L) { | |||
| 531 | 531 | ||
| 532 | static void luaI_addquoted (lua_State *L, luaL_Buffer *b, int arg) { | 532 | static void luaI_addquoted (lua_State *L, luaL_Buffer *b, int arg) { |
| 533 | size_t l; | 533 | size_t l; |
| 534 | const char *s = luaL_check_lstr(L, arg, &l); | 534 | const l_char *s = luaL_check_lstr(L, arg, &l); |
| 535 | luaL_putchar(b, '"'); | 535 | luaL_putchar(b, l_c('"')); |
| 536 | while (l--) { | 536 | while (l--) { |
| 537 | switch (*s) { | 537 | switch (*s) { |
| 538 | case '"': case '\\': case '\n': | 538 | case l_c('"'): case l_c('\\'): case l_c('\n'): |
| 539 | luaL_putchar(b, '\\'); | 539 | luaL_putchar(b, l_c('\\')); |
| 540 | luaL_putchar(b, *s); | 540 | luaL_putchar(b, *s); |
| 541 | break; | 541 | break; |
| 542 | case '\0': luaL_addlstring(b, "\\000", 4); break; | 542 | case l_c('\0'): luaL_addlstring(b, l_s("\\000"), 4); break; |
| 543 | default: luaL_putchar(b, *s); | 543 | default: luaL_putchar(b, *s); |
| 544 | } | 544 | } |
| 545 | s++; | 545 | s++; |
| 546 | } | 546 | } |
| 547 | luaL_putchar(b, '"'); | 547 | luaL_putchar(b, l_c('"')); |
| 548 | } | 548 | } |
| 549 | 549 | ||
| 550 | 550 | ||
| 551 | static const char *scanformat (lua_State *L, const char *strfrmt, char *form, | 551 | static const l_char *scanformat (lua_State *L, const l_char *strfrmt, l_char *form, |
| 552 | int *hasprecision) { | 552 | int *hasprecision) { |
| 553 | const char *p = strfrmt; | 553 | const l_char *p = strfrmt; |
| 554 | while (strchr("-+ #0", *p)) p++; /* skip flags */ | 554 | while (strchr(l_s("-+ #0"), *p)) p++; /* skip flags */ |
| 555 | if (isdigit(uchar(*p))) p++; /* skip width */ | 555 | if (isdigit(uchar(*p))) p++; /* skip width */ |
| 556 | if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ | 556 | if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ |
| 557 | if (*p == '.') { | 557 | if (*p == l_c('.')) { |
| 558 | p++; | 558 | p++; |
| 559 | *hasprecision = 1; | 559 | *hasprecision = 1; |
| 560 | if (isdigit(uchar(*p))) p++; /* skip precision */ | 560 | if (isdigit(uchar(*p))) p++; /* skip precision */ |
| 561 | if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ | 561 | if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ |
| 562 | } | 562 | } |
| 563 | if (isdigit(uchar(*p))) | 563 | if (isdigit(uchar(*p))) |
| 564 | lua_error(L, "invalid format (width or precision too long)"); | 564 | lua_error(L, l_s("invalid format (width or precision too long)")); |
| 565 | if (p-strfrmt+2 > MAX_FORMAT) /* +2 to include `%' and the specifier */ | 565 | if (p-strfrmt+2 > MAX_FORMAT) /* +2 to include `%' and the specifier */ |
| 566 | lua_error(L, "invalid format (too long)"); | 566 | lua_error(L, l_s("invalid format (too long)")); |
| 567 | form[0] = '%'; | 567 | form[0] = l_c('%'); |
| 568 | strncpy(form+1, strfrmt, p-strfrmt+1); | 568 | strncpy(form+1, strfrmt, p-strfrmt+1); |
| 569 | form[p-strfrmt+2] = 0; | 569 | form[p-strfrmt+2] = 0; |
| 570 | return p; | 570 | return p; |
| @@ -573,38 +573,38 @@ static const char *scanformat (lua_State *L, const char *strfrmt, char *form, | |||
| 573 | 573 | ||
| 574 | static int str_format (lua_State *L) { | 574 | static int str_format (lua_State *L) { |
| 575 | int arg = 1; | 575 | int arg = 1; |
| 576 | const char *strfrmt = luaL_check_string(L, arg); | 576 | const l_char *strfrmt = luaL_check_string(L, arg); |
| 577 | luaL_Buffer b; | 577 | luaL_Buffer b; |
| 578 | luaL_buffinit(L, &b); | 578 | luaL_buffinit(L, &b); |
| 579 | while (*strfrmt) { | 579 | while (*strfrmt) { |
| 580 | if (*strfrmt != '%') | 580 | if (*strfrmt != l_c('%')) |
| 581 | luaL_putchar(&b, *strfrmt++); | 581 | luaL_putchar(&b, *strfrmt++); |
| 582 | else if (*++strfrmt == '%') | 582 | else if (*++strfrmt == l_c('%')) |
| 583 | luaL_putchar(&b, *strfrmt++); /* %% */ | 583 | luaL_putchar(&b, *strfrmt++); /* %% */ |
| 584 | else { /* format item */ | 584 | else { /* format item */ |
| 585 | char form[MAX_FORMAT]; /* to store the format (`%...') */ | 585 | l_char form[MAX_FORMAT]; /* to store the format (`%...') */ |
| 586 | char buff[MAX_ITEM]; /* to store the formatted item */ | 586 | l_char buff[MAX_ITEM]; /* to store the formatted item */ |
| 587 | int hasprecision = 0; | 587 | int hasprecision = 0; |
| 588 | if (isdigit(uchar(*strfrmt)) && *(strfrmt+1) == '$') | 588 | if (isdigit(uchar(*strfrmt)) && *(strfrmt+1) == l_c('$')) |
| 589 | lua_error(L, "obsolete `format' option (d$)"); | 589 | lua_error(L, l_s("obsolete `format' option (d$)")); |
| 590 | arg++; | 590 | arg++; |
| 591 | strfrmt = scanformat(L, strfrmt, form, &hasprecision); | 591 | strfrmt = scanformat(L, strfrmt, form, &hasprecision); |
| 592 | switch (*strfrmt++) { | 592 | switch (*strfrmt++) { |
| 593 | case 'c': case 'd': case 'i': | 593 | case l_c('c'): case l_c('d'): case l_c('i'): |
| 594 | sprintf(buff, form, luaL_check_int(L, arg)); | 594 | sprintf(buff, form, luaL_check_int(L, arg)); |
| 595 | break; | 595 | break; |
| 596 | case 'o': case 'u': case 'x': case 'X': | 596 | case l_c('o'): case l_c('u'): case l_c('x'): case l_c('X'): |
| 597 | sprintf(buff, form, (unsigned int)luaL_check_number(L, arg)); | 597 | sprintf(buff, form, (unsigned int)luaL_check_number(L, arg)); |
| 598 | break; | 598 | break; |
| 599 | case 'e': case 'E': case 'f': case 'g': case 'G': | 599 | case l_c('e'): case l_c('E'): case l_c('f'): case l_c('g'): case l_c('G'): |
| 600 | sprintf(buff, form, luaL_check_number(L, arg)); | 600 | sprintf(buff, form, luaL_check_number(L, arg)); |
| 601 | break; | 601 | break; |
| 602 | case 'q': | 602 | case l_c('q'): |
| 603 | luaI_addquoted(L, &b, arg); | 603 | luaI_addquoted(L, &b, arg); |
| 604 | continue; /* skip the `addsize' at the end */ | 604 | continue; /* skip the `addsize' at the end */ |
| 605 | case 's': { | 605 | case l_c('s'): { |
| 606 | size_t l; | 606 | size_t l; |
| 607 | const char *s = luaL_check_lstr(L, arg, &l); | 607 | const l_char *s = luaL_check_lstr(L, arg, &l); |
| 608 | if (!hasprecision && l >= 100) { | 608 | if (!hasprecision && l >= 100) { |
| 609 | /* no precision and string is too long to be formatted; | 609 | /* no precision and string is too long to be formatted; |
| 610 | keep original string */ | 610 | keep original string */ |
| @@ -618,7 +618,7 @@ static int str_format (lua_State *L) { | |||
| 618 | } | 618 | } |
| 619 | } | 619 | } |
| 620 | default: /* also treat cases `pnLlh' */ | 620 | default: /* also treat cases `pnLlh' */ |
| 621 | lua_error(L, "invalid option in `format'"); | 621 | lua_error(L, l_s("invalid option in `format'")); |
| 622 | } | 622 | } |
| 623 | luaL_addlstring(&b, buff, strlen(buff)); | 623 | luaL_addlstring(&b, buff, strlen(buff)); |
| 624 | } | 624 | } |
| @@ -629,16 +629,16 @@ static int str_format (lua_State *L) { | |||
| 629 | 629 | ||
| 630 | 630 | ||
| 631 | static const luaL_reg strlib[] = { | 631 | static const luaL_reg strlib[] = { |
| 632 | {"strlen", str_len}, | 632 | {l_s("strlen"), str_len}, |
| 633 | {"strsub", str_sub}, | 633 | {l_s("strsub"), str_sub}, |
| 634 | {"strlower", str_lower}, | 634 | {l_s("strlower"), str_lower}, |
| 635 | {"strupper", str_upper}, | 635 | {l_s("strupper"), str_upper}, |
| 636 | {"strchar", str_char}, | 636 | {l_s("strchar"), str_char}, |
| 637 | {"strrep", str_rep}, | 637 | {l_s("strrep"), str_rep}, |
| 638 | {"strbyte", str_byte}, | 638 | {l_s("strbyte"), str_byte}, |
| 639 | {"format", str_format}, | 639 | {l_s("format"), str_format}, |
| 640 | {"strfind", str_find}, | 640 | {l_s("strfind"), str_find}, |
| 641 | {"gsub", str_gsub} | 641 | {l_s("gsub"), str_gsub} |
| 642 | }; | 642 | }; |
| 643 | 643 | ||
| 644 | 644 | ||
