0001
0002 #include <pscript.h>
0003 #include <psstdstring.h>
0004 #include <string.h>
0005 #include <stdlib.h>
0006 #include <stdio.h>
0007 #include <ctype.h>
0008 #include <assert.h>
0009 #include <nstdutil.h>
0010 #include <ndebug.h>
0011
0012 #define MAX_FORMAT_LEN 20
0013 #define MAX_WFORMAT_LEN 3
0014 #define ADDITIONAL_FORMAT_SPACE (100*sizeof(PSChar))
0015
0016 static PSBool isfmtchr(PSChar ch)
0017 {
0018 switch(ch) {
0019 case '-': case '+': case ' ': case '#': case '0': return PSTrue;
0020 }
0021 return PSFalse;
0022 }
0023
0024 static PSInteger validate_format(HPSCRIPTVM v, PSChar *fmt, const PSChar *src, PSInteger n,PSInteger &width)
0025 {
0026 PSChar *dummy;
0027 PSChar swidth[MAX_WFORMAT_LEN];
0028 PSInteger wc = 0;
0029 PSInteger start = n;
0030 fmt[0] = '%';
0031 while (isfmtchr(src[n])) n++;
0032 while (scisdigit(src[n])) {
0033 swidth[wc] = src[n];
0034 n++;
0035 wc++;
0036 if(wc>=MAX_WFORMAT_LEN)
0037 return ps_throwerror(v,_SC("width format too long"));
0038 }
0039 swidth[wc] = '\0';
0040 if(wc > 0) {
0041 width = scstrtol(swidth,&dummy,10);
0042 }
0043 else
0044 width = 0;
0045 if (src[n] == '.') {
0046 n++;
0047
0048 wc = 0;
0049 while (scisdigit(src[n])) {
0050 swidth[wc] = src[n];
0051 n++;
0052 wc++;
0053 if(wc>=MAX_WFORMAT_LEN)
0054 return ps_throwerror(v,_SC("precision format too long"));
0055 }
0056 swidth[wc] = '\0';
0057 if(wc > 0) {
0058 width += scstrtol(swidth,&dummy,10);
0059
0060 }
0061 }
0062 if (n-start > MAX_FORMAT_LEN )
0063 return ps_throwerror(v,_SC("format too long"));
0064 memcpy(&fmt[1],&src[start],((n-start)+1)*sizeof(PSChar));
0065 fmt[(n-start)+2] = '\0';
0066 return n;
0067 }
0068
0069 PSRESULT psstd_format(HPSCRIPTVM v,PSInteger nformatstringidx,PSInteger *outlen,PSChar **output)
0070 {
0071 const PSChar *format;
0072 PSChar *dest;
0073 PSChar fmt[MAX_FORMAT_LEN];
0074 ps_getstring(v,nformatstringidx,&format);
0075 PSInteger format_size = ps_getsize(v,nformatstringidx);
0076 PSInteger allocated = (format_size+2)*sizeof(PSChar);
0077 dest = ps_getscratchpad(v,allocated);
0078 PSInteger n = 0,i = 0, nparam = nformatstringidx+1, w = 0;
0079
0080 while(n < format_size)
0081 {
0082 if(format[n] != '%') {
0083 assert(i < allocated);
0084 dest[i++] = format[n];
0085 n++;
0086 }
0087 else if(format[n+1] == '%') {
0088 dest[i++] = '%';
0089 n += 2;
0090 }
0091 else {
0092 n++;
0093 if( nparam > ps_gettop(v) )
0094 return ps_throwerror(v,_SC("not enough paramters for the given format string"));
0095 n = validate_format(v,fmt,format,n,w);
0096 if(n < 0) return -1;
0097 PSInteger addlen = 0;
0098 PSInteger valtype = 0;
0099 const PSChar *ts = NULL;
0100 PSInteger ti = 0;
0101 PSFloat tf = 0;
0102 switch(format[n]) {
0103 case 's':
0104 if(PS_FAILED(ps_getstring(v,nparam,&ts)))
0105 return ps_throwerror(v,_SC("string expected for the specified format"));
0106 addlen = (ps_getsize(v,nparam)*sizeof(PSChar))+((w+1)*sizeof(PSChar));
0107 valtype = 's';
0108 break;
0109 case 'i': case 'd': case 'o': case 'u': case 'x': case 'X':
0110 #ifdef _PS64
0111 {
0112 size_t flen = scstrlen(fmt);
0113 PSInteger fpos = flen - 1;
0114 PSChar f = fmt[fpos];
0115 const PSChar *prec = (const PSChar *)_PRINT_INT_PREC;
0116 while(*prec != _SC('\0')) {
0117 fmt[fpos++] = *prec++;
0118 }
0119 fmt[fpos++] = f;
0120 fmt[fpos++] = _SC('\0');
0121 }
0122 #endif
0123 case 'c':
0124 if(PS_FAILED(ps_getinteger(v,nparam,&ti)))
0125 return ps_throwerror(v,_SC("integer expected for the specified format"));
0126 addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(PSChar));
0127 valtype = 'i';
0128 break;
0129 case 'f': case 'g': case 'G': case 'e': case 'E':
0130 if(PS_FAILED(ps_getfloat(v,nparam,&tf)))
0131 return ps_throwerror(v,_SC("float expected for the specified format"));
0132 addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(PSChar));
0133 valtype = 'f';
0134 break;
0135 default:
0136 return ps_throwerror(v,_SC("invalid format"));
0137 }
0138 n++;
0139 allocated += addlen + sizeof(PSChar);
0140 dest = ps_getscratchpad(v,allocated);
0141 switch(valtype) {
0142 case 's': i += scsprintf(&dest[i],allocated,fmt,ts); break;
0143 case 'i': i += scsprintf(&dest[i],allocated,fmt,ti); break;
0144 case 'f': i += scsprintf(&dest[i],allocated,fmt,tf); break;
0145 };
0146 nparam ++;
0147 }
0148 }
0149 *outlen = i;
0150 dest[i] = '\0';
0151 *output = dest;
0152 return PS_OK;
0153 }
0154
0155 static PSInteger _string_format(HPSCRIPTVM v)
0156 {
0157 PSChar *dest = NULL;
0158 PSInteger length = 0;
0159 if(PS_FAILED(psstd_format(v,2,&length,&dest)))
0160 return -1;
0161 ps_pushstring(v,dest,length);
0162 return 1;
0163 }
0164
0165 static void __strip_l(const PSChar *str,const PSChar **start)
0166 {
0167 const PSChar *t = str;
0168 while(((*t) != '\0') && scisspace(*t)){ t++; }
0169 *start = t;
0170 }
0171
0172 static void __strip_r(const PSChar *str,PSInteger len,const PSChar **end)
0173 {
0174 if(len == 0) {
0175 *end = str;
0176 return;
0177 }
0178 const PSChar *t = &str[len-1];
0179 while(t >= str && scisspace(*t)) { t--; }
0180 *end = t + 1;
0181 }
0182
0183 static PSInteger _string_strip(HPSCRIPTVM v)
0184 {
0185 const PSChar *str,*start,*end;
0186 ps_getstring(v,2,&str);
0187 PSInteger len = ps_getsize(v,2);
0188 __strip_l(str,&start);
0189 __strip_r(str,len,&end);
0190 ps_pushstring(v,start,end - start);
0191 return 1;
0192 }
0193
0194 static PSInteger _string_lstrip(HPSCRIPTVM v)
0195 {
0196 const PSChar *str,*start;
0197 ps_getstring(v,2,&str);
0198 __strip_l(str,&start);
0199 ps_pushstring(v,start,-1);
0200 return 1;
0201 }
0202
0203 static PSInteger _string_rstrip(HPSCRIPTVM v)
0204 {
0205 const PSChar *str,*end;
0206 ps_getstring(v,2,&str);
0207 PSInteger len = ps_getsize(v,2);
0208 __strip_r(str,len,&end);
0209 ps_pushstring(v,str,end - str);
0210 return 1;
0211 }
0212
0213 static PSInteger _string_split(HPSCRIPTVM v)
0214 {
0215 const PSChar *str,*seps;
0216 PSChar *stemp;
0217 ps_getstring(v,2,&str);
0218 ps_getstring(v,3,&seps);
0219 PSInteger sepsize = ps_getsize(v,3);
0220 if(sepsize == 0) return ps_throwerror(v,_SC("empty separators string"));
0221 PSInteger memsize = (ps_getsize(v,2)+1)*sizeof(PSChar);
0222 stemp = ps_getscratchpad(v,memsize);
0223 memcpy(stemp,str,memsize);
0224 PSChar *start = stemp;
0225 PSChar *end = stemp;
0226 ps_newarray(v,0);
0227 while(*end != '\0')
0228 {
0229 PSChar cur = *end;
0230 for(PSInteger i = 0; i < sepsize; i++)
0231 {
0232 if(cur == seps[i])
0233 {
0234 *end = 0;
0235 ps_pushstring(v,start,-1);
0236 ps_arrayappend(v,-2);
0237 start = end + 1;
0238 break;
0239 }
0240 }
0241 end++;
0242 }
0243 if(end != start)
0244 {
0245 ps_pushstring(v,start,-1);
0246 ps_arrayappend(v,-2);
0247 }
0248 return 1;
0249 }
0250
0251
0252
0253
0254
0255
0256 static PSInteger _string_strcommon(HPSCRIPTVM v)
0257 {
0258 const PSChar *str,*str2;
0259 PSChar *stemp;
0260 int i, len;
0261 ps_getstring(v,2,&str);
0262 ps_getstring(v,3,&str2);
0263 PSInteger memsize = (ps_getsize(v,2)+1)*sizeof(PSChar);
0264 stemp = ps_getscratchpad(v,memsize);
0265 memcpy(stemp,str,memsize);
0266 len = strlen(stemp);
0267
0268 for (i=0; i<len; i++)
0269 {
0270 if (stemp[i]!=str2[i])
0271 {
0272 stemp[i] = EXEOS;
0273 break;
0274 }
0275 }
0276
0277 ps_pushstring(v,stemp,-1);
0278
0279 return 1;
0280 }
0281
0282
0283
0284
0285
0286
0287 static PSInteger _string_strdiff(HPSCRIPTVM v)
0288 {
0289 const PSChar *str,*str2;
0290 PSChar *stemp;
0291 int i, len;
0292 static char empty[]="";
0293 char *ret=empty;
0294 ps_getstring(v,2,&str);
0295 ps_getstring(v,3,&str2);
0296 PSInteger memsize = (ps_getsize(v,2)+1)*sizeof(PSChar);
0297 stemp = ps_getscratchpad(v,memsize);
0298 memcpy(stemp,str,memsize);
0299 len = strlen(stemp);
0300
0301 for (i=0; i<len; i++)
0302 {
0303 if (stemp[i]!=str2[i])
0304 {
0305 ret = &stemp[i];
0306 break;
0307 }
0308 }
0309
0310 ps_pushstring(v,ret,-1);
0311
0312 return 1;
0313 }
0314
0315
0316
0317
0318
0319
0320 static PSInteger _string_rstrips(HPSCRIPTVM v)
0321 {
0322 const PSChar *str,*str2;
0323 PSChar *stemp;
0324 char *ret;
0325 ps_getstring(v,2,&str);
0326 ps_getstring(v,3,&str2);
0327 PSInteger memsize = (ps_getsize(v,2)+1)*sizeof(PSChar);
0328 stemp = ps_getscratchpad(v,memsize);
0329 memcpy(stemp,str,memsize);
0330 ndrx_str_rstrip(stemp, (char *)str2);
0331 ret = stemp;
0332 ps_pushstring(v,ret,-1);
0333 return 1;
0334 }
0335
0336
0337
0338
0339
0340
0341 static PSInteger _string_lstrips(HPSCRIPTVM v)
0342 {
0343 const PSChar *str,*str2;
0344 PSChar *stemp;
0345 char *ret;
0346 ps_getstring(v,2,&str);
0347 ps_getstring(v,3,&str2);
0348 ret = ndrx_str_lstrip_ptr((char *)str, (char *)str2);
0349 ps_pushstring(v,ret,-1);
0350 return 1;
0351 }
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361 static PSInteger _string_substr(HPSCRIPTVM v)
0362 {
0363 PSInteger offset, length;
0364 const PSChar *str;
0365 PSChar *stemp;
0366 char *ret;
0367 PSInteger memsize;
0368 int i, len, len_tmp;
0369
0370 ps_getstring(v,2,&str);
0371 ps_getinteger(v,3,&offset);
0372
0373 len_tmp = len = strlen(str);
0374
0375 if (offset<0)
0376 {
0377
0378 offset+=len_tmp;
0379 }
0380
0381 if(ps_gettop(v) > 3)
0382 {
0383 ps_getinteger(v,4,&length);
0384
0385 if (length < 0)
0386 {
0387
0388 len+=length;
0389 length = len_tmp;
0390 }
0391 }
0392 else
0393 {
0394 length = len_tmp;
0395 }
0396
0397 memsize = (ps_getsize(v,2)+1)*sizeof(PSChar);
0398 stemp = ps_getscratchpad(v,memsize);
0399
0400 if (offset>=len)
0401 {
0402 NDRX_STRCPY_SAFE(stemp, "");
0403 }
0404 else
0405 {
0406 for (i=offset; i < len && ( (i-offset) < length); i++)
0407 {
0408 stemp[i-offset]=str[i];
0409 }
0410 stemp[i-offset]=EXEOS;
0411 }
0412
0413 ret = stemp;
0414 ps_pushstring(v,ret,-1);
0415 return 1;
0416 }
0417
0418
0419
0420
0421
0422
0423 static PSInteger _string_strips(HPSCRIPTVM v)
0424 {
0425 const PSChar *str,*str2;
0426 PSChar *stemp;
0427 char *ret;
0428 ps_getstring(v,2,&str);
0429 ps_getstring(v,3,&str2);
0430 PSInteger memsize = (ps_getsize(v,2)+1)*sizeof(PSChar);
0431 stemp = ps_getscratchpad(v,memsize);
0432 memcpy(stemp,str,memsize);
0433 ret = ndrx_str_strip((char *)stemp, (char *)str2);
0434 ps_pushstring(v,ret,-1);
0435 return 1;
0436 }
0437
0438
0439
0440
0441
0442
0443
0444
0445 static PSInteger _string_strtokblk(HPSCRIPTVM v)
0446 {
0447 const PSChar *str,*seps, *quote;
0448 PSChar *stemp, *p;
0449 ps_getstring(v,2,&str);
0450 ps_getstring(v,3,&seps);
0451 ps_getstring(v,4,"e);
0452 PSInteger sepsize = ps_getsize(v,3);
0453 if(sepsize == 0) return ps_throwerror(v,_SC("empty separators string"));
0454
0455 PSInteger quotesize = ps_getsize(v,4);
0456 if(quotesize == 0) return ps_throwerror(v,_SC("empty quotes string"));
0457
0458 PSInteger memsize = (ps_getsize(v,2)+1)*sizeof(PSChar);
0459 stemp = ps_getscratchpad(v,memsize);
0460 memcpy(stemp,str,memsize);
0461
0462 ps_newarray(v,0);
0463
0464 for (p = ndrx_strtokblk ( (char *)stemp, (char *)seps, (char *)quote);
0465 NULL!=p;
0466 p = ndrx_strtokblk (NULL, (char *)seps, (char *)quote))
0467 {
0468 ps_pushstring(v,p,-1);
0469 ps_arrayappend(v,-2);
0470 }
0471
0472 return 1;
0473 }
0474
0475 static PSInteger _string_escape(HPSCRIPTVM v)
0476 {
0477 const PSChar *str;
0478 PSChar *dest,*resstr;
0479 PSInteger size;
0480 ps_getstring(v,2,&str);
0481 size = ps_getsize(v,2);
0482 if(size == 0) {
0483 ps_push(v,2);
0484 return 1;
0485 }
0486 #ifdef PSUNICODE
0487 #if WCHAR_SIZE == 2
0488 const PSChar *escpat = _SC("\\x%04x");
0489 const PSInteger maxescsize = 6;
0490 #else
0491 const PSChar *escpat = _SC("\\x%08x");
0492 const PSInteger maxescsize = 10;
0493 #endif
0494 #else
0495 const PSChar *escpat = _SC("\\x%02x");
0496 const PSInteger maxescsize = 4;
0497 #endif
0498 PSInteger destcharsize = (size * maxescsize);
0499 resstr = dest = (PSChar *)ps_getscratchpad(v,destcharsize * sizeof(PSChar));
0500 PSChar c;
0501 PSChar escch;
0502 PSInteger escaped = 0;
0503 for(int n = 0; n < size; n++){
0504 c = *str++;
0505 escch = 0;
0506 if(scisprint(c) || c == 0) {
0507 switch(c) {
0508 case '\a': escch = 'a'; break;
0509 case '\b': escch = 'b'; break;
0510 case '\t': escch = 't'; break;
0511 case '\n': escch = 'n'; break;
0512 case '\v': escch = 'v'; break;
0513 case '\f': escch = 'f'; break;
0514 case '\r': escch = 'r'; break;
0515 case '\\': escch = '\\'; break;
0516 case '\"': escch = '\"'; break;
0517 case '\'': escch = '\''; break;
0518 case 0: escch = '0'; break;
0519 }
0520 if(escch) {
0521 *dest++ = '\\';
0522 *dest++ = escch;
0523 escaped++;
0524 }
0525 else {
0526 *dest++ = c;
0527 }
0528 }
0529 else {
0530
0531 dest += scsprintf(dest, destcharsize, escpat, c);
0532 escaped++;
0533 }
0534 }
0535
0536 if(escaped) {
0537 ps_pushstring(v,resstr,dest - resstr);
0538 }
0539 else {
0540 ps_push(v,2);
0541 }
0542 return 1;
0543 }
0544
0545 static PSInteger _string_startswith(HPSCRIPTVM v)
0546 {
0547 const PSChar *str,*cmp;
0548 ps_getstring(v,2,&str);
0549 ps_getstring(v,3,&cmp);
0550 PSInteger len = ps_getsize(v,2);
0551 PSInteger cmplen = ps_getsize(v,3);
0552 PSBool ret = PSFalse;
0553 if(cmplen <= len) {
0554 ret = memcmp(str,cmp,ps_rsl(cmplen)) == 0 ? PSTrue : PSFalse;
0555 }
0556 ps_pushbool(v,ret);
0557 return 1;
0558 }
0559
0560 static PSInteger _string_endswith(HPSCRIPTVM v)
0561 {
0562 const PSChar *str,*cmp;
0563 ps_getstring(v,2,&str);
0564 ps_getstring(v,3,&cmp);
0565 PSInteger len = ps_getsize(v,2);
0566 PSInteger cmplen = ps_getsize(v,3);
0567 PSBool ret = PSFalse;
0568 if(cmplen <= len) {
0569 ret = memcmp(&str[len - cmplen],cmp,ps_rsl(cmplen)) == 0 ? PSTrue : PSFalse;
0570 }
0571 ps_pushbool(v,ret);
0572 return 1;
0573 }
0574
0575 #define SETUP_REX(v) \
0576 PSRex *self = NULL; \
0577 ps_getinstanceup(v,1,(PSUserPointer *)&self,0);
0578
0579 static PSInteger _rexobj_releasehook(PSUserPointer p, PSInteger PS_UNUSED_ARG(size))
0580 {
0581 PSRex *self = ((PSRex *)p);
0582 psstd_rex_free(self);
0583 return 1;
0584 }
0585
0586 static PSInteger _regexp_match(HPSCRIPTVM v)
0587 {
0588 SETUP_REX(v);
0589 const PSChar *str;
0590 ps_getstring(v,2,&str);
0591 if(psstd_rex_match(self,str) == PSTrue)
0592 {
0593 ps_pushbool(v,PSTrue);
0594 return 1;
0595 }
0596 ps_pushbool(v,PSFalse);
0597 return 1;
0598 }
0599
0600 static void _addrexmatch(HPSCRIPTVM v,const PSChar *str,const PSChar *begin,const PSChar *end)
0601 {
0602 ps_newtable(v);
0603 ps_pushstring(v,_SC("begin"),-1);
0604 ps_pushinteger(v,begin - str);
0605 ps_rawset(v,-3);
0606 ps_pushstring(v,_SC("end"),-1);
0607 ps_pushinteger(v,end - str);
0608 ps_rawset(v,-3);
0609 }
0610
0611 static PSInteger _regexp_search(HPSCRIPTVM v)
0612 {
0613 SETUP_REX(v);
0614 const PSChar *str,*begin,*end;
0615 PSInteger start = 0;
0616 ps_getstring(v,2,&str);
0617 if(ps_gettop(v) > 2) ps_getinteger(v,3,&start);
0618 if(psstd_rex_search(self,str+start,&begin,&end) == PSTrue) {
0619 _addrexmatch(v,str,begin,end);
0620 return 1;
0621 }
0622 return 0;
0623 }
0624
0625 static PSInteger _regexp_capture(HPSCRIPTVM v)
0626 {
0627 SETUP_REX(v);
0628 const PSChar *str,*begin,*end;
0629 PSInteger start = 0;
0630 ps_getstring(v,2,&str);
0631 if(ps_gettop(v) > 2) ps_getinteger(v,3,&start);
0632 if(psstd_rex_search(self,str+start,&begin,&end) == PSTrue) {
0633 PSInteger n = psstd_rex_getsubexpcount(self);
0634 PSRexMatch match;
0635 ps_newarray(v,0);
0636 for(PSInteger i = 0;i < n; i++) {
0637 psstd_rex_getsubexp(self,i,&match);
0638 if(match.len > 0)
0639 _addrexmatch(v,str,match.begin,match.begin+match.len);
0640 else
0641 _addrexmatch(v,str,str,str);
0642 ps_arrayappend(v,-2);
0643 }
0644 return 1;
0645 }
0646 return 0;
0647 }
0648
0649 static PSInteger _regexp_subexpcount(HPSCRIPTVM v)
0650 {
0651 SETUP_REX(v);
0652 ps_pushinteger(v,psstd_rex_getsubexpcount(self));
0653 return 1;
0654 }
0655
0656 static PSInteger _regexp_constructor(HPSCRIPTVM v)
0657 {
0658 const PSChar *error,*pattern;
0659 ps_getstring(v,2,&pattern);
0660 PSRex *rex = psstd_rex_compile(pattern,&error);
0661 if(!rex) return ps_throwerror(v,error);
0662 ps_setinstanceup(v,1,rex);
0663 ps_setreleasehook(v,1,_rexobj_releasehook);
0664 return 0;
0665 }
0666
0667 static PSInteger _regexp__typeof(HPSCRIPTVM v)
0668 {
0669 ps_pushstring(v,_SC("regexp"),-1);
0670 return 1;
0671 }
0672
0673 #define _DECL_REX_FUNC(name,nparams,pmask) {_SC(#name),_regexp_##name,nparams,pmask}
0674 static const PSRegFunction rexobj_funcs[]={
0675 _DECL_REX_FUNC(constructor,2,_SC(".s")),
0676 _DECL_REX_FUNC(search,-2,_SC("xsn")),
0677 _DECL_REX_FUNC(match,2,_SC("xs")),
0678 _DECL_REX_FUNC(capture,-2,_SC("xsn")),
0679 _DECL_REX_FUNC(subexpcount,1,_SC("x")),
0680 _DECL_REX_FUNC(_typeof,1,_SC("x")),
0681 {NULL,(PSFUNCTION)0,0,NULL}
0682 };
0683 #undef _DECL_REX_FUNC
0684
0685 #define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_string_##name,nparams,pmask}
0686 static const PSRegFunction stringlib_funcs[]={
0687 _DECL_FUNC(format,-2,_SC(".s")),
0688 _DECL_FUNC(strip,2,_SC(".s")),
0689 _DECL_FUNC(lstrip,2,_SC(".s")),
0690 _DECL_FUNC(rstrip,2,_SC(".s")),
0691 _DECL_FUNC(split,3,_SC(".ss")),
0692 _DECL_FUNC(strcommon,3,_SC(".ss")),
0693 _DECL_FUNC(strdiff,3,_SC(".ss")),
0694 _DECL_FUNC(rstrips,3,_SC(".ss")),
0695 _DECL_FUNC(lstrips,3,_SC(".ss")),
0696 _DECL_FUNC(strips,3,_SC(".ss")),
0697 _DECL_FUNC(strtokblk,4,_SC(".sss")),
0698 _DECL_FUNC(substr,-3,_SC(".snn")),
0699 _DECL_FUNC(escape,2,_SC(".s")),
0700 _DECL_FUNC(startswith,3,_SC(".ss")),
0701 _DECL_FUNC(endswith,3,_SC(".ss")),
0702 {NULL,(PSFUNCTION)0,0,NULL}
0703 };
0704 #undef _DECL_FUNC
0705
0706
0707 PSInteger psstd_register_stringlib(HPSCRIPTVM v)
0708 {
0709 ps_pushstring(v,_SC("regexp"),-1);
0710 ps_newclass(v,PSFalse);
0711 PSInteger i = 0;
0712 while(rexobj_funcs[i].name != 0) {
0713 const PSRegFunction &f = rexobj_funcs[i];
0714 ps_pushstring(v,f.name,-1);
0715 ps_newclosure(v,f.f,0);
0716 ps_setparamscheck(v,f.nparamscheck,f.typemask);
0717 ps_setnativeclosurename(v,-1,f.name);
0718 ps_newslot(v,-3,PSFalse);
0719 i++;
0720 }
0721 ps_newslot(v,-3,PSFalse);
0722
0723 i = 0;
0724 while(stringlib_funcs[i].name!=0)
0725 {
0726 ps_pushstring(v,stringlib_funcs[i].name,-1);
0727 ps_newclosure(v,stringlib_funcs[i].f,0);
0728 ps_setparamscheck(v,stringlib_funcs[i].nparamscheck,stringlib_funcs[i].typemask);
0729 ps_setnativeclosurename(v,-1,stringlib_funcs[i].name);
0730 ps_newslot(v,-3,PSFalse);
0731 i++;
0732 }
0733 return 1;
0734 }