aboutsummaryrefslogtreecommitdiff
path: root/lstrlib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-11-22 11:12:07 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-11-22 11:12:07 -0200
commit29ede6aa13144ff7b69c57a87be1ee93f57ae896 (patch)
treeadcfb5dcff7db55481cd675349e23dec0e63c939 /lstrlib.c
parent951897c09319ae5474a4b86bb7d615136577caa0 (diff)
downloadlua-29ede6aa13144ff7b69c57a87be1ee93f57ae896.tar.gz
lua-29ede6aa13144ff7b69c57a87be1ee93f57ae896.tar.bz2
lua-29ede6aa13144ff7b69c57a87be1ee93f57ae896.zip
first implementation of multiple states (reentrant code).
Diffstat (limited to 'lstrlib.c')
-rw-r--r--lstrlib.c310
1 files changed, 156 insertions, 154 deletions
diff --git a/lstrlib.c b/lstrlib.c
index 27676543..c973d0e4 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstrlib.c,v 1.35 1999/10/25 13:35:44 roberto Exp roberto $ 2** $Id: lstrlib.c,v 1.36 1999/11/11 16:45:04 roberto Exp roberto $
3** Standard library for strings and pattern-matching 3** Standard library for strings and pattern-matching
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -10,28 +10,30 @@
10#include <stdlib.h> 10#include <stdlib.h>
11#include <string.h> 11#include <string.h>
12 12
13#define LUA_REENTRANT
14
13#include "lauxlib.h" 15#include "lauxlib.h"
14#include "lua.h" 16#include "lua.h"
15#include "lualib.h" 17#include "lualib.h"
16 18
17 19
18 20
19static void addnchar (const char *s, int n) { 21static void addnchar (lua_State *L, const char *s, int n) {
20 char *b = luaL_openspace(n); 22 char *b = luaL_openspace(L, n);
21 memcpy(b, s, n); 23 memcpy(b, s, n);
22 luaL_addsize(n); 24 luaL_addsize(L, n);
23} 25}
24 26
25 27
26static void str_len (void) { 28static void str_len (lua_State *L) {
27 long l; 29 long l;
28 luaL_check_lstr(1, &l); 30 luaL_check_lstr(L, 1, &l);
29 lua_pushnumber(l); 31 lua_pushnumber(L, l);
30} 32}
31 33
32 34
33static void closeandpush (void) { 35static void closeandpush (lua_State *L) {
34 lua_pushlstring(luaL_buffer(), luaL_getsize()); 36 lua_pushlstring(L, luaL_buffer(L), luaL_getsize(L));
35} 37}
36 38
37 39
@@ -41,69 +43,69 @@ static long posrelat (long pos, long len) {
41} 43}
42 44
43 45
44static void str_sub (void) { 46static void str_sub (lua_State *L) {
45 long l; 47 long l;
46 const char *s = luaL_check_lstr(1, &l); 48 const char *s = luaL_check_lstr(L, 1, &l);
47 long start = posrelat(luaL_check_long(2), l); 49 long start = posrelat(luaL_check_long(L, 2), l);
48 long end = posrelat(luaL_opt_long(3, -1), l); 50 long end = posrelat(luaL_opt_long(L, 3, -1), l);
49 if (start < 1) start = 1; 51 if (start < 1) start = 1;
50 if (end > l) end = l; 52 if (end > l) end = l;
51 if (start <= end) 53 if (start <= end)
52 lua_pushlstring(s+start-1, end-start+1); 54 lua_pushlstring(L, s+start-1, end-start+1);
53 else lua_pushstring(""); 55 else lua_pushstring(L, "");
54} 56}
55 57
56 58
57static void str_lower (void) { 59static void str_lower (lua_State *L) {
58 long l; 60 long l;
59 int i; 61 int i;
60 const char *s = luaL_check_lstr(1, &l); 62 const char *s = luaL_check_lstr(L, 1, &l);
61 luaL_resetbuffer(); 63 luaL_resetbuffer(L);
62 for (i=0; i<l; i++) 64 for (i=0; i<l; i++)
63 luaL_addchar(tolower((unsigned char)(s[i]))); 65 luaL_addchar(L, tolower((unsigned char)(s[i])));
64 closeandpush(); 66 closeandpush(L);
65} 67}
66 68
67 69
68static void str_upper (void) { 70static void str_upper (lua_State *L) {
69 long l; 71 long l;
70 int i; 72 int i;
71 const char *s = luaL_check_lstr(1, &l); 73 const char *s = luaL_check_lstr(L, 1, &l);
72 luaL_resetbuffer(); 74 luaL_resetbuffer(L);
73 for (i=0; i<l; i++) 75 for (i=0; i<l; i++)
74 luaL_addchar(toupper((unsigned char)(s[i]))); 76 luaL_addchar(L, toupper((unsigned char)(s[i])));
75 closeandpush(); 77 closeandpush(L);
76} 78}
77 79
78static void str_rep (void) { 80static void str_rep (lua_State *L) {
79 long l; 81 long l;
80 const char *s = luaL_check_lstr(1, &l); 82 const char *s = luaL_check_lstr(L, 1, &l);
81 int n = luaL_check_int(2); 83 int n = luaL_check_int(L, 2);
82 luaL_resetbuffer(); 84 luaL_resetbuffer(L);
83 while (n-- > 0) 85 while (n-- > 0)
84 addnchar(s, l); 86 addnchar(L, s, l);
85 closeandpush(); 87 closeandpush(L);
86} 88}
87 89
88 90
89static void str_byte (void) { 91static void str_byte (lua_State *L) {
90 long l; 92 long l;
91 const char *s = luaL_check_lstr(1, &l); 93 const char *s = luaL_check_lstr(L, 1, &l);
92 long pos = posrelat(luaL_opt_long(2, 1), l); 94 long pos = posrelat(luaL_opt_long(L, 2, 1), l);
93 luaL_arg_check(0<pos && pos<=l, 2, "out of range"); 95 luaL_arg_check(L, 0<pos && pos<=l, 2, "out of range");
94 lua_pushnumber((unsigned char)s[pos-1]); 96 lua_pushnumber(L, (unsigned char)s[pos-1]);
95} 97}
96 98
97 99
98static void str_char (void) { 100static void str_char (lua_State *L) {
99 int i = 0; 101 int i = 0;
100 luaL_resetbuffer(); 102 luaL_resetbuffer(L);
101 while (lua_getparam(++i) != LUA_NOOBJECT) { 103 while (lua_getparam(L, ++i) != LUA_NOOBJECT) {
102 int c = luaL_check_int(i); 104 int c = luaL_check_int(L, i);
103 luaL_arg_check((unsigned char)c == c, i, "invalid value"); 105 luaL_arg_check(L, (unsigned char)c == c, i, "invalid value");
104 luaL_addchar((unsigned char)c); 106 luaL_addchar(L, (unsigned char)c);
105 } 107 }
106 closeandpush(); 108 closeandpush(L);
107} 109}
108 110
109 111
@@ -133,42 +135,42 @@ struct Capture {
133#define SPECIALS "^$*+?.([%-" 135#define SPECIALS "^$*+?.([%-"
134 136
135 137
136static void push_captures (struct Capture *cap) { 138static void push_captures (lua_State *L, struct Capture *cap) {
137 int i; 139 int i;
138 for (i=0; i<cap->level; i++) { 140 for (i=0; i<cap->level; i++) {
139 int l = cap->capture[i].len; 141 int l = cap->capture[i].len;
140 if (l == -1) lua_error("unfinished capture"); 142 if (l == -1) lua_error(L, "unfinished capture");
141 lua_pushlstring(cap->capture[i].init, l); 143 lua_pushlstring(L, cap->capture[i].init, l);
142 } 144 }
143} 145}
144 146
145 147
146static int check_cap (int l, struct Capture *cap) { 148static int check_cap (lua_State *L, int l, struct Capture *cap) {
147 l -= '1'; 149 l -= '1';
148 if (!(0 <= l && l < cap->level && cap->capture[l].len != -1)) 150 if (!(0 <= l && l < cap->level && cap->capture[l].len != -1))
149 lua_error("invalid capture index"); 151 lua_error(L, "invalid capture index");
150 return l; 152 return l;
151} 153}
152 154
153 155
154static int capture_to_close (struct Capture *cap) { 156static int capture_to_close (lua_State *L, struct Capture *cap) {
155 int level = cap->level; 157 int level = cap->level;
156 for (level--; level>=0; level--) 158 for (level--; level>=0; level--)
157 if (cap->capture[level].len == -1) return level; 159 if (cap->capture[level].len == -1) return level;
158 lua_error("invalid pattern capture"); 160 lua_error(L, "invalid pattern capture");
159 return 0; /* to avoid warnings */ 161 return 0; /* to avoid warnings */
160} 162}
161 163
162 164
163const char *luaI_classend (const char *p) { 165const char *luaI_classend (lua_State *L, const char *p) {
164 switch (*p++) { 166 switch (*p++) {
165 case ESC: 167 case ESC:
166 if (*p == '\0') lua_error("incorrect pattern (ends with `%')"); 168 if (*p == '\0') lua_error(L, "incorrect pattern (ends with `%')");
167 return p+1; 169 return p+1;
168 case '[': 170 case '[':
169 if (*p == '^') p++; 171 if (*p == '^') p++;
170 do { /* look for a ']' */ 172 do { /* look for a ']' */
171 if (*p == '\0') lua_error("incorrect pattern (missing `]')"); 173 if (*p == '\0') lua_error(L, "incorrect pattern (missing `]')");
172 if (*(p++) == ESC && *p != '\0') p++; /* skip escapes (e.g. '%]') */ 174 if (*(p++) == ESC && *p != '\0') p++; /* skip escapes (e.g. '%]') */
173 } while (*p != ']'); 175 } while (*p != ']');
174 return p+1; 176 return p+1;
@@ -236,13 +238,13 @@ int luaI_singlematch (int c, const char *p, const char *ep) {
236} 238}
237 239
238 240
239static const char *match (const char *s, const char *p, struct Capture *cap); 241static const char *match (lua_State *L, const char *s, const char *p, struct Capture *cap);
240 242
241 243
242static const char *matchbalance (const char *s, const char *p, 244static const char *matchbalance (lua_State *L, const char *s, const char *p,
243 struct Capture *cap) { 245 struct Capture *cap) {
244 if (*p == 0 || *(p+1) == 0) 246 if (*p == 0 || *(p+1) == 0)
245 lua_error("unbalanced pattern"); 247 lua_error(L, "unbalanced pattern");
246 if (*s != *p) return NULL; 248 if (*s != *p) return NULL;
247 else { 249 else {
248 int b = *p; 250 int b = *p;
@@ -259,14 +261,14 @@ static const char *matchbalance (const char *s, const char *p,
259} 261}
260 262
261 263
262static const char *max_expand (const char *s, const char *p, const char *ep, 264static const char *max_expand (lua_State *L, const char *s, const char *p, const char *ep,
263 struct Capture *cap) { 265 struct Capture *cap) {
264 int i = 0; /* counts maximum expand for item */ 266 int i = 0; /* counts maximum expand for item */
265 while ((s+i)<cap->src_end && luaI_singlematch((unsigned char)*(s+i), p, ep)) 267 while ((s+i)<cap->src_end && luaI_singlematch((unsigned char)*(s+i), p, ep))
266 i++; 268 i++;
267 /* keeps trying to match mith the maximum repetitions */ 269 /* keeps trying to match mith the maximum repetitions */
268 while (i>=0) { 270 while (i>=0) {
269 const char *res = match((s+i), ep+1, cap); 271 const char *res = match(L, (s+i), ep+1, cap);
270 if (res) return res; 272 if (res) return res;
271 i--; /* else didn't match; reduce 1 repetition to try again */ 273 i--; /* else didn't match; reduce 1 repetition to try again */
272 } 274 }
@@ -274,10 +276,10 @@ static const char *max_expand (const char *s, const char *p, const char *ep,
274} 276}
275 277
276 278
277static const char *min_expand (const char *s, const char *p, const char *ep, 279static const char *min_expand (lua_State *L, const char *s, const char *p, const char *ep,
278 struct Capture *cap) { 280 struct Capture *cap) {
279 for (;;) { 281 for (;;) {
280 const char *res = match(s, ep+1, cap); 282 const char *res = match(L, s, ep+1, cap);
281 if (res != NULL) 283 if (res != NULL)
282 return res; 284 return res;
283 else if (s<cap->src_end && luaI_singlematch((unsigned char)*s, p, ep)) 285 else if (s<cap->src_end && luaI_singlematch((unsigned char)*s, p, ep))
@@ -287,34 +289,34 @@ static const char *min_expand (const char *s, const char *p, const char *ep,
287} 289}
288 290
289 291
290static const char *start_capt (const char *s, const char *p, 292static const char *start_capt (lua_State *L, const char *s, const char *p,
291 struct Capture *cap) { 293 struct Capture *cap) {
292 const char *res; 294 const char *res;
293 int level = cap->level; 295 int level = cap->level;
294 if (level >= MAX_CAPT) lua_error("too many captures"); 296 if (level >= MAX_CAPT) lua_error(L, "too many captures");
295 cap->capture[level].init = s; 297 cap->capture[level].init = s;
296 cap->capture[level].len = -1; 298 cap->capture[level].len = -1;
297 cap->level = level+1; 299 cap->level = level+1;
298 if ((res=match(s, p+1, cap)) == NULL) /* match failed? */ 300 if ((res=match(L, s, p+1, cap)) == NULL) /* match failed? */
299 cap->level--; /* undo capture */ 301 cap->level--; /* undo capture */
300 return res; 302 return res;
301} 303}
302 304
303 305
304static const char *end_capt (const char *s, const char *p, 306static const char *end_capt (lua_State *L, const char *s, const char *p,
305 struct Capture *cap) { 307 struct Capture *cap) {
306 int l = capture_to_close(cap); 308 int l = capture_to_close(L, cap);
307 const char *res; 309 const char *res;
308 cap->capture[l].len = s - cap->capture[l].init; /* close capture */ 310 cap->capture[l].len = s - cap->capture[l].init; /* close capture */
309 if ((res = match(s, p+1, cap)) == NULL) /* match failed? */ 311 if ((res = match(L, s, p+1, cap)) == NULL) /* match failed? */
310 cap->capture[l].len = -1; /* undo capture */ 312 cap->capture[l].len = -1; /* undo capture */
311 return res; 313 return res;
312} 314}
313 315
314 316
315static const char *match_capture (const char *s, int level, 317static const char *match_capture (lua_State *L, const char *s, int level,
316 struct Capture *cap) { 318 struct Capture *cap) {
317 int l = check_cap(level, cap); 319 int l = check_cap(L, level, cap);
318 int len = cap->capture[l].len; 320 int len = cap->capture[l].len;
319 if (cap->src_end-s >= len && 321 if (cap->src_end-s >= len &&
320 memcmp(cap->capture[l].init, s, len) == 0) 322 memcmp(cap->capture[l].init, s, len) == 0)
@@ -323,23 +325,23 @@ static const char *match_capture (const char *s, int level,
323} 325}
324 326
325 327
326static const char *match (const char *s, const char *p, struct Capture *cap) { 328static const char *match (lua_State *L, const char *s, const char *p, struct Capture *cap) {
327 init: /* using goto's to optimize tail recursion */ 329 init: /* using goto's to optimize tail recursion */
328 switch (*p) { 330 switch (*p) {
329 case '(': /* start capture */ 331 case '(': /* start capture */
330 return start_capt(s, p, cap); 332 return start_capt(L, s, p, cap);
331 case ')': /* end capture */ 333 case ')': /* end capture */
332 return end_capt(s, p, cap); 334 return end_capt(L, s, p, cap);
333 case ESC: /* may be %[0-9] or %b */ 335 case ESC: /* may be %[0-9] or %b */
334 if (isdigit((unsigned char)(*(p+1)))) { /* capture? */ 336 if (isdigit((unsigned char)(*(p+1)))) { /* capture? */
335 s = match_capture(s, *(p+1), cap); 337 s = match_capture(L, s, *(p+1), cap);
336 if (s == NULL) return NULL; 338 if (s == NULL) return NULL;
337 p+=2; goto init; /* else return match(s, p+2, cap) */ 339 p+=2; goto init; /* else return match(L, s, p+2, cap) */
338 } 340 }
339 else if (*(p+1) == 'b') { /* balanced string? */ 341 else if (*(p+1) == 'b') { /* balanced string? */
340 s = matchbalance(s, p+2, cap); 342 s = matchbalance(L, s, p+2, cap);
341 if (s == NULL) return NULL; 343 if (s == NULL) return NULL;
342 p+=4; goto init; /* else return match(s, p+4, cap); */ 344 p+=4; goto init; /* else return match(L, s, p+4, cap); */
343 } 345 }
344 else goto dflt; /* case default */ 346 else goto dflt; /* case default */
345 case '\0': /* end of pattern */ 347 case '\0': /* end of pattern */
@@ -349,24 +351,24 @@ static const char *match (const char *s, const char *p, struct Capture *cap) {
349 return (s == cap->src_end) ? s : NULL; /* check end of string */ 351 return (s == cap->src_end) ? s : NULL; /* check end of string */
350 else goto dflt; 352 else goto dflt;
351 default: dflt: { /* it is a pattern item */ 353 default: dflt: { /* it is a pattern item */
352 const char *ep = luaI_classend(p); /* points to what is next */ 354 const char *ep = luaI_classend(L, p); /* points to what is next */
353 int m = s<cap->src_end && luaI_singlematch((unsigned char)*s, p, ep); 355 int m = s<cap->src_end && luaI_singlematch((unsigned char)*s, p, ep);
354 switch (*ep) { 356 switch (*ep) {
355 case '?': { /* optional */ 357 case '?': { /* optional */
356 const char *res; 358 const char *res;
357 if (m && ((res=match(s+1, ep+1, cap)) != NULL)) 359 if (m && ((res=match(L, s+1, ep+1, cap)) != NULL))
358 return res; 360 return res;
359 p=ep+1; goto init; /* else return match(s, ep+1, cap); */ 361 p=ep+1; goto init; /* else return match(L, s, ep+1, cap); */
360 } 362 }
361 case '*': /* 0 or more repetitions */ 363 case '*': /* 0 or more repetitions */
362 return max_expand(s, p, ep, cap); 364 return max_expand(L, s, p, ep, cap);
363 case '+': /* 1 or more repetitions */ 365 case '+': /* 1 or more repetitions */
364 return (m ? max_expand(s+1, p, ep, cap) : NULL); 366 return (m ? max_expand(L, s+1, p, ep, cap) : NULL);
365 case '-': /* 0 or more repetitions (minimum) */ 367 case '-': /* 0 or more repetitions (minimum) */
366 return min_expand(s, p, ep, cap); 368 return min_expand(L, s, p, ep, cap);
367 default: 369 default:
368 if (!m) return NULL; 370 if (!m) return NULL;
369 s++; p=ep; goto init; /* else return match(s+1, ep, cap); */ 371 s++; p=ep; goto init; /* else return match(L, s+1, ep, cap); */
370 } 372 }
371 } 373 }
372 } 374 }
@@ -394,19 +396,19 @@ static const char *memfind (const char *s1, long l1, const char *s2, long l2) {
394} 396}
395 397
396 398
397static void str_find (void) { 399static void str_find (lua_State *L) {
398 long l1, l2; 400 long l1, l2;
399 const char *s = luaL_check_lstr(1, &l1); 401 const char *s = luaL_check_lstr(L, 1, &l1);
400 const char *p = luaL_check_lstr(2, &l2); 402 const char *p = luaL_check_lstr(L, 2, &l2);
401 long init = posrelat(luaL_opt_long(3, 1), l1) - 1; 403 long init = posrelat(luaL_opt_long(L, 3, 1), l1) - 1;
402 struct Capture cap; 404 struct Capture cap;
403 luaL_arg_check(0 <= init && init <= l1, 3, "out of range"); 405 luaL_arg_check(L, 0 <= init && init <= l1, 3, "out of range");
404 if (lua_getparam(4) != LUA_NOOBJECT || 406 if (lua_getparam(L, 4) != LUA_NOOBJECT ||
405 strpbrk(p, SPECIALS) == NULL) { /* no special characters? */ 407 strpbrk(p, SPECIALS) == NULL) { /* no special characters? */
406 const char *s2 = memfind(s+init, l1, p, l2); 408 const char *s2 = memfind(s+init, l1, p, l2);
407 if (s2) { 409 if (s2) {
408 lua_pushnumber(s2-s+1); 410 lua_pushnumber(L, s2-s+1);
409 lua_pushnumber(s2-s+l2); 411 lua_pushnumber(L, s2-s+l2);
410 return; 412 return;
411 } 413 }
412 } 414 }
@@ -417,33 +419,33 @@ static void str_find (void) {
417 do { 419 do {
418 const char *res; 420 const char *res;
419 cap.level = 0; 421 cap.level = 0;
420 if ((res=match(s1, p, &cap)) != NULL) { 422 if ((res=match(L, s1, p, &cap)) != NULL) {
421 lua_pushnumber(s1-s+1); /* start */ 423 lua_pushnumber(L, s1-s+1); /* start */
422 lua_pushnumber(res-s); /* end */ 424 lua_pushnumber(L, res-s); /* end */
423 push_captures(&cap); 425 push_captures(L, &cap);
424 return; 426 return;
425 } 427 }
426 } while (s1++<cap.src_end && !anchor); 428 } while (s1++<cap.src_end && !anchor);
427 } 429 }
428 lua_pushnil(); /* not found */ 430 lua_pushnil(L); /* not found */
429} 431}
430 432
431 433
432static void add_s (lua_Object newp, struct Capture *cap) { 434static void add_s (lua_State *L, lua_Object newp, struct Capture *cap) {
433 if (lua_isstring(newp)) { 435 if (lua_isstring(L, newp)) {
434 const char *news = lua_getstring(newp); 436 const char *news = lua_getstring(L, newp);
435 int l = lua_strlen(newp); 437 int l = lua_strlen(L, newp);
436 int i; 438 int i;
437 for (i=0; i<l; i++) { 439 for (i=0; i<l; i++) {
438 if (news[i] != ESC) 440 if (news[i] != ESC)
439 luaL_addchar(news[i]); 441 luaL_addchar(L, news[i]);
440 else { 442 else {
441 i++; /* skip ESC */ 443 i++; /* skip ESC */
442 if (!isdigit((unsigned char)news[i])) 444 if (!isdigit((unsigned char)news[i]))
443 luaL_addchar(news[i]); 445 luaL_addchar(L, news[i]);
444 else { 446 else {
445 int level = check_cap(news[i], cap); 447 int level = check_cap(L, news[i], cap);
446 addnchar(cap->capture[level].init, cap->capture[level].len); 448 addnchar(L, cap->capture[level].init, cap->capture[level].len);
447 } 449 }
448 } 450 }
449 } 451 }
@@ -452,91 +454,91 @@ static void add_s (lua_Object newp, struct Capture *cap) {
452 lua_Object res; 454 lua_Object res;
453 int status; 455 int status;
454 int oldbuff; 456 int oldbuff;
455 lua_beginblock(); 457 lua_beginblock(L);
456 push_captures(cap); 458 push_captures(L, cap);
457 /* function may use buffer, so save it and create a new one */ 459 /* function may use buffer, so save it and create a new one */
458 oldbuff = luaL_newbuffer(0); 460 oldbuff = luaL_newbuffer(L, 0);
459 status = lua_callfunction(newp); 461 status = lua_callfunction(L, newp);
460 /* restore old buffer */ 462 /* restore old buffer */
461 luaL_oldbuffer(oldbuff); 463 luaL_oldbuffer(L, oldbuff);
462 if (status != 0) { 464 if (status != 0) {
463 lua_endblock(); 465 lua_endblock(L);
464 lua_error(NULL); 466 lua_error(L, NULL);
465 } 467 }
466 res = lua_getresult(1); 468 res = lua_getresult(L, 1);
467 if (lua_isstring(res)) 469 if (lua_isstring(L, res))
468 addnchar(lua_getstring(res), lua_strlen(res)); 470 addnchar(L, lua_getstring(L, res), lua_strlen(L, res));
469 lua_endblock(); 471 lua_endblock(L);
470 } 472 }
471} 473}
472 474
473 475
474static void str_gsub (void) { 476static void str_gsub (lua_State *L) {
475 long srcl; 477 long srcl;
476 const char *src = luaL_check_lstr(1, &srcl); 478 const char *src = luaL_check_lstr(L, 1, &srcl);
477 const char *p = luaL_check_string(2); 479 const char *p = luaL_check_string(L, 2);
478 lua_Object newp = lua_getparam(3); 480 lua_Object newp = lua_getparam(L, 3);
479 int max_s = luaL_opt_int(4, srcl+1); 481 int max_s = luaL_opt_int(L, 4, srcl+1);
480 int anchor = (*p == '^') ? (p++, 1) : 0; 482 int anchor = (*p == '^') ? (p++, 1) : 0;
481 int n = 0; 483 int n = 0;
482 struct Capture cap; 484 struct Capture cap;
483 luaL_arg_check(lua_isstring(newp) || lua_isfunction(newp), 3, 485 luaL_arg_check(L, lua_isstring(L, newp) || lua_isfunction(L, newp), 3,
484 "string or function expected"); 486 "string or function expected");
485 luaL_resetbuffer(); 487 luaL_resetbuffer(L);
486 cap.src_end = src+srcl; 488 cap.src_end = src+srcl;
487 while (n < max_s) { 489 while (n < max_s) {
488 const char *e; 490 const char *e;
489 cap.level = 0; 491 cap.level = 0;
490 e = match(src, p, &cap); 492 e = match(L, src, p, &cap);
491 if (e) { 493 if (e) {
492 n++; 494 n++;
493 add_s(newp, &cap); 495 add_s(L, newp, &cap);
494 } 496 }
495 if (e && e>src) /* non empty match? */ 497 if (e && e>src) /* non empty match? */
496 src = e; /* skip it */ 498 src = e; /* skip it */
497 else if (src < cap.src_end) 499 else if (src < cap.src_end)
498 luaL_addchar(*src++); 500 luaL_addchar(L, *src++);
499 else break; 501 else break;
500 if (anchor) break; 502 if (anchor) break;
501 } 503 }
502 addnchar(src, cap.src_end-src); 504 addnchar(L, src, cap.src_end-src);
503 closeandpush(); 505 closeandpush(L);
504 lua_pushnumber(n); /* number of substitutions */ 506 lua_pushnumber(L, n); /* number of substitutions */
505} 507}
506 508
507/* }====================================================== */ 509/* }====================================================== */
508 510
509 511
510static void luaI_addquoted (int arg) { 512static void luaI_addquoted (lua_State *L, int arg) {
511 long l; 513 long l;
512 const char *s = luaL_check_lstr(arg, &l); 514 const char *s = luaL_check_lstr(L, arg, &l);
513 luaL_addchar('"'); 515 luaL_addchar(L, '"');
514 while (l--) { 516 while (l--) {
515 switch (*s) { 517 switch (*s) {
516 case '"': case '\\': case '\n': 518 case '"': case '\\': case '\n':
517 luaL_addchar('\\'); 519 luaL_addchar(L, '\\');
518 luaL_addchar(*s); 520 luaL_addchar(L, *s);
519 break; 521 break;
520 case '\0': addnchar("\\000", 4); break; 522 case '\0': addnchar(L, "\\000", 4); break;
521 default: luaL_addchar(*s); 523 default: luaL_addchar(L, *s);
522 } 524 }
523 s++; 525 s++;
524 } 526 }
525 luaL_addchar('"'); 527 luaL_addchar(L, '"');
526} 528}
527 529
528/* maximum size of each format specification (such as '%-099.99d') */ 530/* maximum size of each format specification (such as '%-099.99d') */
529#define MAX_FORMAT 20 /* arbitrary limit */ 531#define MAX_FORMAT 20 /* arbitrary limit */
530 532
531static void str_format (void) { 533static void str_format (lua_State *L) {
532 int arg = 1; 534 int arg = 1;
533 const char *strfrmt = luaL_check_string(arg); 535 const char *strfrmt = luaL_check_string(L, arg);
534 luaL_resetbuffer(); 536 luaL_resetbuffer(L);
535 while (*strfrmt) { 537 while (*strfrmt) {
536 if (*strfrmt != '%') 538 if (*strfrmt != '%')
537 luaL_addchar(*strfrmt++); 539 luaL_addchar(L, *strfrmt++);
538 else if (*++strfrmt == '%') 540 else if (*++strfrmt == '%')
539 luaL_addchar(*strfrmt++); /* %% */ 541 luaL_addchar(L, *strfrmt++); /* %% */
540 else { /* format item */ 542 else { /* format item */
541 struct Capture cap; 543 struct Capture cap;
542 char form[MAX_FORMAT]; /* to store the format ('%...') */ 544 char form[MAX_FORMAT]; /* to store the format ('%...') */
@@ -550,33 +552,33 @@ static void str_format (void) {
550 arg++; 552 arg++;
551 cap.src_end = strfrmt+strlen(strfrmt)+1; 553 cap.src_end = strfrmt+strlen(strfrmt)+1;
552 cap.level = 0; 554 cap.level = 0;
553 strfrmt = match(initf, "[-+ #0]*(%d*)%.?(%d*)", &cap); 555 strfrmt = match(L, initf, "[-+ #0]*(%d*)%.?(%d*)", &cap);
554 if (cap.capture[0].len > 2 || cap.capture[1].len > 2 || /* < 100? */ 556 if (cap.capture[0].len > 2 || cap.capture[1].len > 2 || /* < 100? */
555 strfrmt-initf > MAX_FORMAT-2) 557 strfrmt-initf > MAX_FORMAT-2)
556 lua_error("invalid format (width or precision too long)"); 558 lua_error(L, "invalid format (width or precision too long)");
557 strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */ 559 strncpy(form+1, initf, strfrmt-initf+1); /* +1 to include conversion */
558 form[strfrmt-initf+2] = 0; 560 form[strfrmt-initf+2] = 0;
559 buff = luaL_openspace(512); /* 512 > soid luaI_addquot99.99f', -1e308) */ 561 buff = luaL_openspace(L, 512); /* 512 > len(format('%99.99f', -1e308)) */
560 switch (*strfrmt++) { 562 switch (*strfrmt++) {
561 case 'c': case 'd': case 'i': 563 case 'c': case 'd': case 'i':
562 sprintf(buff, form, luaL_check_int(arg)); 564 sprintf(buff, form, luaL_check_int(L, arg));
563 break; 565 break;
564 case 'o': case 'u': case 'x': case 'X': 566 case 'o': case 'u': case 'x': case 'X':
565 sprintf(buff, form, (unsigned int)luaL_check_number(arg)); 567 sprintf(buff, form, (unsigned int)luaL_check_number(L, arg));
566 break; 568 break;
567 case 'e': case 'E': case 'f': case 'g': case 'G': 569 case 'e': case 'E': case 'f': case 'g': case 'G':
568 sprintf(buff, form, luaL_check_number(arg)); 570 sprintf(buff, form, luaL_check_number(L, arg));
569 break; 571 break;
570 case 'q': 572 case 'q':
571 luaI_addquoted(arg); 573 luaI_addquoted(L, arg);
572 continue; /* skip the "addsize" at the end */ 574 continue; /* skip the "addsize" at the end */
573 case 's': { 575 case 's': {
574 long l; 576 long l;
575 const char *s = luaL_check_lstr(arg, &l); 577 const char *s = luaL_check_lstr(L, arg, &l);
576 if (cap.capture[1].len == 0 && l >= 100) { 578 if (cap.capture[1].len == 0 && l >= 100) {
577 /* no precision and string is too big to be formatted; 579 /* no precision and string is too big to be formatted;
578 keep original string */ 580 keep original string */
579 addnchar(s, l); 581 addnchar(L, s, l);
580 continue; /* skip the "addsize" at the end */ 582 continue; /* skip the "addsize" at the end */
581 } 583 }
582 else { 584 else {
@@ -585,12 +587,12 @@ static void str_format (void) {
585 } 587 }
586 } 588 }
587 default: /* also treat cases 'pnLlh' */ 589 default: /* also treat cases 'pnLlh' */
588 lua_error("invalid option in `format'"); 590 lua_error(L, "invalid option in `format'");
589 } 591 }
590 luaL_addsize(strlen(buff)); 592 luaL_addsize(L, strlen(buff));
591 } 593 }
592 } 594 }
593 closeandpush(); /* push the result */ 595 closeandpush(L); /* push the result */
594} 596}
595 597
596 598
@@ -612,7 +614,7 @@ static const struct luaL_reg strlib[] = {
612/* 614/*
613** Open string library 615** Open string library
614*/ 616*/
615void strlib_open (void) 617void lua_strlibopen (lua_State *L)
616{ 618{
617 luaL_openlib(strlib, (sizeof(strlib)/sizeof(strlib[0]))); 619 luaL_openlib(L, strlib, (sizeof(strlib)/sizeof(strlib[0])));
618} 620}