Annotation of OpenXM/src/kan96xx/plugin/oxcgi.c, Revision 1.11
1.11 ! takayama 1: /* $OpenXM: OpenXM/src/kan96xx/plugin/oxcgi.c,v 1.10 2005/07/03 11:08:54 ohara Exp $ */
1.2 takayama 2: #include <stdio.h>
1.10 ohara 3: #include <stdlib.h>
4: #include <string.h>
1.2 takayama 5: #include "datatype.h"
6: #include "stackm.h"
7: #include "extern.h"
8: #include "file2.h"
9: #include "oxcgi.h"
10:
11: static int ppp(char *s,int kstart,int kend, int vstart, int vend);
12: static int cgiHex(int p);
13:
1.11 ! takayama 14: static void test1();
! 15: static void test2();
! 16: static void test3();
! 17: static void test4();
1.2 takayama 18:
19: /* main() {KSstart();test4();} */
20:
21: /*
22: [["URL","http://www.openxm.org"],
23: ["foo","value1"], <--- the first key value.
24: ["hoge","value2"]
25: ]
26: */
27: struct object cgiUrlEncodingToKeyValuePair(char *s) {
28: int i,n,start;
29: int kstart,kend; /* start of key, end of key */
30: int vstart,vend; /* start of value, end of value */
31: int state;
32: int nOfPairs;
1.9 takayama 33: struct object rob = OINIT;
34: struct object ob = OINIT;
1.2 takayama 35: int k;
36: n = strlen(s); start = -1;
37: for (i=0; i<n; i++) {
38: if (s[i] == '?') { start=i+1; break;}
39: }
1.5 takayama 40: if (start == -1) {
41: start = 0;
42: for (i=0; i<n; i++) {
43: if (s[i] > ' ') { start = i; break; }
44: }
45: }
1.2 takayama 46: for (k=0; k<2; k++) {
47: /* k==0 path one. Count nOfPairs. */
48: /* k==1 path two. generate array. */
49: nOfPairs = 0;
50: i = start;
51: /* state 0, 1 : key
52: =
53: state 2, 3 : value
54: &
55: state 5 : after getting &
56: state 4 : after getting eof
57: state 6
58: */
59: state = 0;
60: while (1) {
61: switch(state) {
62: case 0:
63: kstart = kend = vstart = vend = -1;
64: if (s[i] <= ' ') {
65: state=6; break;
66: } else {
67: kstart = kend = i;
68: nOfPairs++;
69: i++;
70: state=1;
71: break;
72: }
73: case 1:
74: if (s[i] <= ' ') {
75: state=4; break;
76: }else if (s[i] == '=') {
77: state=2; i++; break;
78: }else {
79: kend = i; i++; break;
80: }
81: case 2:
82: vstart = vend = -1;
83: if (s[i] <= ' ') {
84: state=4; break;
85: }else if (s[i] == '&') {
86: state=5; break;
87: }else {
88: state=3; vstart=vend=i; i++; break;
89: }
90: case 3:
91: if (s[i] <= ' ') {
92: state=4; break;
93: }else if (s[i] == '&') {
94: state=5; break;
95: }else{
96: vend=i; i++; break;
97: }
98: case 4:
99: if (k == 1) {
100: ob = newObjectArray(2);
101: putoa(ob,0,urlEncodedStringToObj(s,kstart,kend,0));
102: putoa(ob,1,urlEncodedStringToObj(s,vstart,vend,0));
103: putoa(rob,nOfPairs,ob);
104: }
105: state = -1; break;
106: case 5:
107: if (k == 1) {
108: ob = newObjectArray(2);
109: putoa(ob,0,urlEncodedStringToObj(s,kstart,kend,0));
110: putoa(ob,1,urlEncodedStringToObj(s,vstart,vend,0));
111: putoa(rob,nOfPairs,ob);
112: }
113: i++; state = 0; break;
114: case 6: state = -1; break;
115: default: break;
116: }
117: if (state < 0) break;
118: /*
119: if ((state == 4) || (state == 5)) {
120: ppp(s,kstart,kend,vstart,vend);
121: }
122: */
123: }
124: if (k == 0) {
125: char *stmp; int ii;
126: rob = newObjectArray(nOfPairs+1);
127: ob = newObjectArray(2);
128: putoa(ob,0,KpoString("URL"));
129: stmp = sGC_malloc(start+2);
130: if (stmp == NULL) errorKan1("%s\n","No more memory.");
131: stmp[0] = 0;
132: for (ii=0; ii<start-1; ii++) {
133: stmp[ii] = s[ii]; stmp[ii+1] = 0;
134: }
135: putoa(ob,1,KpoString(stmp));
136: putoa(rob,0,ob);
137: }
138: }
139: return rob;
140: }
141:
142: /* . - _ A-Z a-z 0-9
143: space --> +
144: */
145: static int isUrlEncoding3(char s) {
146: if ((s == '.') || (s == '-') || (s == '_')) return(0);
147: if ((s >= 'A') && (s <= 'Z')) return(0);
148: if ((s >= 'a') && (s <= 'z')) return(0);
149: if ((s >= '0') && (s <= '9')) return(0);
150: if (s == ' ') return(0);
151: return(1);
152: }
153:
154: char *byteArrayToUrlEncoding(unsigned char *s,int size) {
155: int n,i,j;
156: char *r;
157: n = 0;
158: /* get Size */
159: for (i=0; i<size; i++) {
160: if (isUrlEncoding3((char)s[i])) n += 3;
161: n++;
162: }
163: r = sGC_malloc(n+1);
164: if (r == NULL) errorKan1("%s\n","No more memory.");
165: r[0] = 0; r[n] = 0;
166: i = 0; j = 0;
167: while ((j < n) && (i<size)) {
168: if (isUrlEncoding3((char)s[i])) {
169: sprintf(&(r[j]),"%%%02X",s[i]); j += 3;
170: }else{
171: if ((char)s[i] == ' ') r[j]='+';
172: else r[j] = s[i];
173: j++; r[j] = 0;
174: }
175: i++;
176: }
177: return(r);
178: }
179: struct object urlEncodedStringToObj(char *s,int vstart,int vend,int mode)
180: /*
181: mode == 0. Authmatically choose Sdollar or SbyteArray.
182: [ not implemented yet. ]
183: */
184: {
1.9 takayama 185: struct object rob = OINIT;
1.2 takayama 186: char *ts;
187: char *ts2;
188: int i,j;
189: int p;
190: if ((s == NULL) || (vstart < 0)) return(NullObject);
191: if (vend+1-vstart <= 0) return(NullObject);
192: ts = (char *) malloc(vend-vstart+1);
193: if (ts == NULL) errorKan1("%s\n","Out of memory.");
194: j = 0; ts[j] = 0;
195: for (i=vstart; i<=vend; i++,j++) {
196: ts[j] = 0;
197: if (s[i] == '+') {
198: ts[j] = ' '; ts[j+1] = 0;
199: }else if (s[i] == '%') {
200: p = cgiHex(s[i+1])*16+cgiHex(s[i+2]);
201: i = i+2;
202: ts[j] = p; ts[j+1] = 0;
203: }else {
204: ts[j] = s[i]; ts[j+1] = 0;
205: }
206: }
207: ts2 = (char *)sGC_malloc(j);
208: if (ts2 == NULL) errorKan1("%s\n","Out of memory.");
209: for (i=0; i<j; i++) {
210: ts2[i] = ts[i];
211: }
212: return KpoString(ts2);
213: }
214:
215: static int cgiHex(int p) {
216: if (p >= '0' && p <= '9') return (p-'0');
217: if (p >= 'A' && p <= 'F') return (p-'A'+10);
218: if (p >= 'a' && p <= 'f') return (p-'a'+10);
219: errorKan1("%s\n","Invalid argument to cgiHex.");
220: }
221:
222: /* for debug */
223: static int ppp(char *s,int kstart,int kend, int vstart, int vend) {
224: int i;
225: printf("%d %d %d %d\n",kstart,kend,vstart,vend);
226: if (kstart >= 0) {
227: printf("key=");
228: for (i=kstart; i<=kend; i++) putchar(s[i]);
229: printf("\n");
230: }
231: if (vstart >= 0) {
232: printf("value=");
233: for (i=vstart; i<=vend; i++) putchar(s[i]);
234: printf("\n");
235: }
236: }
1.11 ! takayama 237: static void test1() {
1.2 takayama 238: char s[1000];
239: cgiUrlEncodingToKeyValuePair("http://hoge.hoge?name=1231232&hoge=asdfsdf&foo=asdfasdf");
240: cgiUrlEncodingToKeyValuePair("http://hoge.hoge?name=1231232&hoge=&foo=asdfasdf&");
241: scanf("%s",s);
242: cgiUrlEncodingToKeyValuePair(s);
243: }
1.11 ! takayama 244: static void test2() {
1.2 takayama 245: char s[1000];
1.9 takayama 246: struct object ob = OINIT;
1.2 takayama 247: ob=cgiUrlEncodingToKeyValuePair("http://hoge.hoge?name=1231232&hoge=asdfsdf&foo=asdfasdf");
248: printObject(ob,1,stdout);
249: ob=cgiUrlEncodingToKeyValuePair("http://hoge.hoge?name=1231232&hoge=&foo=asdfasdf&hoge=A%41+%42%62y%21");
250: printObject(ob,1,stdout);
251: scanf("%s",s);
252: ob=cgiUrlEncodingToKeyValuePair(s);
253: printObject(ob,1,stdout);
254: }
255:
1.11 ! takayama 256: static void test4() {
1.2 takayama 257: char s[1000];
1.9 takayama 258: struct object ob = OINIT;
1.2 takayama 259: char *ts;
260: int size;
261: ob=cgiUrlEncodingToKeyValuePair("http://hoge.hoge?name=1231232&hoge=&foo=asdfasdf&hoge=A%41+%42%62y%21");
262: printObject(ob,1,stdout);
263: ts = cgiKeyValuePairToUrlEncoding(ob);
264: printf("result=%s",ts);
265:
266:
267: ts = "Pragma: no-cache\nContent-Length: 2915\nContent-Type: text/html\nConnection: close\n\n <DIV class=Section1> \n <P class=MsoNormal \n style=\"mso-list: none; mso-list-ins: \" 19991102T2025\"> \n </P> ";
268:
269: ob=cgiHttpToKeyValuePair(ts,strlen(ts));
270: printObject(ob,1,stdout);
271: ts = cgiKeyValuePairToHttp(ob,&size);
272: printf("result:\n%s",ts);
273:
274: }
275: /* end for debug */
276:
277:
278: char *cgiKeyValuePairToUrlEncoding(struct object ob) {
279: FILE2 *fp;
280: int size;
281: fp = fp2open(-1);
282: if (fp == NULL) errorKan1("%s\n","cgiKeyValuePairToUrlEncoding: open error.");
283: cgiKeyValuePairToUrlEncodingFile2(ob,fp);
284: return fp2fcloseInString(fp,&size);
285: }
286: int checkKeyValuePairFormat(struct object ob,char *msg) {
287: int i,n;
1.9 takayama 288: struct object eob = OINIT;
289: struct object eob0 = OINIT;
290: struct object eob1 = OINIT;
1.2 takayama 291: static char *fmt = NULL;
292: int size;
293: char *ss;
294: size = 1024;
295: if (fmt == NULL) fmt = sGC_malloc(size);
296: if (fmt == NULL) errorKan1("%s\n","No more memory.");
297: for (i=0; i<size; i++) fmt[i]=0;
298: ss = "%s\n In ";
299: strcpy(fmt,ss);
300: strncpy(&(fmt[strlen(ss)]),msg,size-strlen(ss)-2);
301:
302: if (ob.tag != Sarray) errorKan1(fmt,"checkKeyValuePairFormat: argument must be an array.");
303: n = getoaSize(ob);
304: for (i=0; i<n ; i++) {
305: eob = getoa(ob,i);
306: if (eob.tag != Sarray) errorKan1(fmt,"checkKeyValuePairFormat: argument must be an array of arrays.");
307: if (getoaSize(eob) != 2) errorKan1(fmt,"checkKeyValuePairFormat: argument must be an array of arrays of size 2.");
308: eob0 = getoa(eob,0); eob1 = getoa(eob,1);
309: if (eob0.tag != Sdollar) errorKan1(fmt,"checkKeyValuePairFormat: the key word must be a string.\n");
310: }
311: return 0;
312: }
313:
314: int cgiKeyValuePairToUrlEncodingFile2(struct object ob,FILE2 *fp) {
315: int n,i;
1.9 takayama 316: struct object eob = OINIT;
317: struct object eob0 = OINIT;
318: struct object eob1 = OINIT;
1.2 takayama 319: char *key, *s;
320: checkKeyValuePairFormat(ob,"cgiKeyValuePairToUrlEncodingFile2");
321: n = getoaSize(ob);
322: for (i=0; i<n; i++) {
323: eob = getoa(ob,i);
324: eob0 = getoa(eob,0); eob1 = getoa(eob,1);
325: key = KopString(eob0);
1.7 takayama 326: if ((i == 0) && (strcmp(key,"URL")==0)) {
1.2 takayama 327: if (eob1.tag != Sdollar) errorKan1("%s\n","URL value must be a string.");
328: fp2fputs(KopString(eob1),fp);
329: if ( n > 1 ) fp2fputc('?',fp);
330: }else{
331: fp2fputs(key,fp); fp2fputc('=',fp);
332: if (eob1.tag == Snull) ;
333: else if (eob1.tag == Sdollar) {
334: s = KopString(eob1);
335: fp2fputs(byteArrayToUrlEncoding((unsigned char *)s, strlen(s)),fp);
336: }else if (eob1.tag == SbyteArray) {
337: fp2fputs(byteArrayToUrlEncoding(KopByteArray(eob1),getByteArraySize(eob1)),fp);
338: }else{
339: errorKan1("%s\n","Value is not string nor byte array.");
340: }
341: if (i < n-1) fp2fputc('&',fp);
342: }
343: }
344: return(fp2fflush(fp));
345: }
346:
347: static struct object rStringToObj(char *s,int vstart,int vend,int mode) {
348: /* mode has not yet been used. */
1.9 takayama 349: struct object rob = OINIT;
1.2 takayama 350: char *sss; int i;
351: int bytearray;
352: bytearray=0;
353: if (vend < vstart) return NullObject;
354: for (i=vstart; i<= vend; i++) {
355: if (s[i] == 0) bytearray=1;
356: }
357: if (bytearray) {
358: rob = newByteArrayFromStr(&(s[vstart]),vend-vstart+1);
359: return(rob);
360: }
361: sss = (char *)sGC_malloc(vend-vstart+1);
362: if (sss == NULL) errorKan1("%s\n","No more memory.");
363: for (i=vstart; i<=vend; i++) {
364: sss[i-vstart] = s[i]; sss[i-vstart+1] = 0;
365: }
366: rob = KpoString(sss);
367: return(rob);
368: }
369:
370: /*
371: [["Content-Body$,"Body"],
372: ["key1","value1"],
373: ["key2","value2"],
374: ...
375: ]
376: */
377: struct object cgiHttpToKeyValuePair(char *s,int size) {
378: int ssize,i,j,k;
379: int nOfPairs, startbody,state, kstart,kend,vstart, vend,startline,endline;
380: int nextstart,path;
1.9 takayama 381: struct object rob = OINIT;
382: struct object ob = OINIT;
1.2 takayama 383: ssize = strlen(s);
384: nOfPairs = 0; startbody = -1;
385: /* state==0 : readline and set startline and endline; state = 1;
386: state==1 : if the line is empty, then state=10;
387: Determine kstart,kend (key) and vstart,vend (value); state=0;
388: state==10 : Read the body.
389: */
390: for (path=0; path<2; path++) {
391: if (path == 1) {
392: rob = newObjectArray(nOfPairs+1); nOfPairs = 0;
393: }
394: i = 0; state=0;
395: while (i<size) {
396: if (state == 0) {
397: /* Read the line */
398: startline=i; endline= size-1; nextstart = size;
399: for (j = startline; j<size; j++) {
400: if (s[j] == 0xd) {
401: endline = j-1;
402: if (s[j+1] == 0xa) nextstart = j+2;
403: else nextstart = j+1;
404: break;
405: }else if (s[j] == 0xa) {
406: endline = j-1; nextstart = j+1; break;
407: }
408: }
409: state = 1; i = nextstart;
410: }else if (state == 1) {
411: if (endline <= startline) { state=10; }
412: else {
413: kstart=startline; kend = endline;
414: vstart=endline+1; vend = endline;
415: for (j=startline; j<=endline; j++) {
416: if (s[j] > ' ') {kstart = j; break;}
417: }
418: for (j=kstart; j<=endline; j++) {
419: if (s[j] == ':') { kend=j-1; break; }
420: }
421: for (j=kend+2; j<=endline; j++) {
422: if (s[j] > ' ') {vstart = j; break; }
423: }
424: for (j=vend; j >= vstart; j--) {
425: if (s[j] > ' ') { vend=j; break;}
426: else vend = j-1;
427: }
428: /* ppp(s,kstart,kend,vstart,vend); */
429: nOfPairs++;
430: if (path == 1) {
431: ob = newObjectArray(2);
432: putoa(ob,0,rStringToObj(s,kstart,kend,0));
433: putoa(ob,1,rStringToObj(s,vstart,vend,0));
434: putoa(rob,nOfPairs,ob);
435: }
436: state = 0;
437: }
438: }else {
439: startbody = i;
440: if (path == 1) {
441: ob = newObjectArray(2);
442: putoa(ob,0,KpoString("Content-Body"));
443: putoa(ob,1,rStringToObj(s,startbody,size-1,0));
444: putoa(rob,0,ob);
445: }
446: break;
447: }
448: }
449: }
450: return rob;
451: }
452:
453: char *cgiKeyValuePairToHttp(struct object ob,int *sizep) {
454: char *s;
455: FILE2 *fp;
456: int size;
457: fp=fp2open(-1);
458: cgiKeyValuePairToHttpFile2(ob,fp);
459: s = fp2fcloseInString(fp,sizep);
460: return(s);
461: }
462:
463: int cgiKeyValuePairToHttpFile2(struct object ob,FILE2 *fp) {
464: int n,i;
1.9 takayama 465: struct object eob = OINIT;
466: struct object eob0 = OINIT;
467: struct object eob1 = OINIT;
1.2 takayama 468: char *key, *s;
469: checkKeyValuePairFormat(ob,"cgiKeyValuePairToHttpFile2");
470: n = getoaSize(ob);
471: if (n == 0) return(0);
472: for (i=1; i<n; i++) {
473: eob = getoa(ob,i);
474: eob0 = getoa(eob,0); eob1 = getoa(eob,1);
475: key = KopString(eob0);
476: fp2fputs(key,fp); fp2fputs(": ",fp);
477: if (eob1.tag == Snull) ;
478: else if (eob1.tag == Sdollar) {
479: s = KopString(eob1);
480: fp2fputs(s,fp);
481: }else{
482: errorKan1("%s\n","Value is not a string.");
483: }
484: if (i < n-1) fp2fputc('\n',fp);
485: else fp2fputs("\n\n",fp);
486: }
487: eob = getoa(ob,0);
488: eob0 = getoa(eob,0); eob1 = getoa(eob,1);
489: key = KopString(eob0);
490: if (strcmp(key,"Content-Body") != 0) warningKan("Key word should be Content-Body.\n");
491: if (eob1.tag == Sdollar) {
492: fp2fputs(KopString(eob1),fp);
493: }else if (eob1.tag == SbyteArray) {
494: fp2write(fp,KopByteArray(eob1),getByteArraySize(eob1));
495: }else errorKan1("%s\n","BODY must be a string or a byte array.");
496:
497: return(fp2fflush(fp));
498: }
499:
500:
1.11 ! takayama 501: static void test3() {
1.2 takayama 502: char *s;
1.9 takayama 503: struct object ob = OINIT;
1.2 takayama 504: s = "Pragma: no-cache\nContent-Length: 2915\nContent-Type: text/html\nConnection: close\n\n <DIV class=Section1> \n <P class=MsoNormal \n style=\"mso-list: none; mso-list-ins: \" 19991102T2025\"> \n </P> ";
505:
506: ob=cgiHttpToKeyValuePair(s,strlen(s));
507: printObject(ob,1,stdout);
508:
509: s = "Pragma:\nContent-Length: 2915\r\nContent-Type: text/html\nConnection: close\n\n <DIV class=Section1> \n <P class=MsoNormal \n style=\"mso-list: none; mso-list-ins: \" 19991102T2025\"> \n </P> ";
510: ob=cgiHttpToKeyValuePair(s,strlen(s));
511: printObject(ob,1,stdout);
512:
513: s = "Pragma\nContent-Length 2915\r\nContent-Type text/html\nConnection: close\n\n <DIV class=Section1> \n <P class=MsoNormal \n style=\"mso-list: none; mso-list-ins: \" 19991102T2025\"> \n </P> ";
514: ob=cgiHttpToKeyValuePair(s,strlen(s));
515: printObject(ob,1,stdout);
516:
517: {
518: char *s;
519: s = "This is a pen.com? !@#0989\n";
520: printf("\n%s\n",byteArrayToUrlEncoding((unsigned char *)s,strlen(s)));
521: }
522: }
523:
524: struct object cgiKeyValuePairToUrlEncodingString(struct object ob) {
525: char *s;
526: s = cgiKeyValuePairToUrlEncoding(ob);
527: if (s == NULL) return NullObject;
528: return KpoString(s);
529: }
530: struct object cgiKeyValuePairToHttpString(struct object ob) {
531: int size;
532: char *s;
533: s = cgiKeyValuePairToHttp(ob,&size);
534: if (s == NULL) return NullObject;
535: return KpoString(s);
536: }
537:
1.3 takayama 538: struct object KooStringToUrlEncoding(struct object sob) {
539: unsigned char *s;
540: char *rs;
541: int n;
542: if (sob.tag == Sdollar) {
543: s = (unsigned char *) KopString(sob);
544: n = strlen((char *)s);
545: }else if (sob.tag == SbyteArray) {
546: s = KopByteArray(sob);
547: n = getByteArraySize(sob);
548: }else errorKan1("%s\n","KooStringToUrlEncoding: argument must be a string or a bytearray.");
549: rs = byteArrayToUrlEncoding(s,n);
550: return KpoString(rs);
551: }
552:
553: struct object KooUrlEncodedStringToObj(struct object sob) {
554: char *s;
555: int n;
556: if (sob.tag == Sdollar) {
557: s = KopString(sob);
558: n = strlen((char *)s);
559: }else if (sob.tag == SbyteArray) {
560: s = KopByteArray(sob);
561: n = getByteArraySize(sob);
562: }else errorKan1("%s\n","KooUrlEncodedStringToObj: argument must be a string.");
563: return urlEncodedStringToObj(s,0,n-1,0);
1.8 takayama 564: }
565:
566: static struct object toTokens(char *s,int *sep,int nsep) {
567: /* s is the input, and sep are the separators. */
568: /* -1 means <=' ' are separators */
569: int nOfTokens,n,i,done,k,start,sav;
1.9 takayama 570: struct object rob = OINIT;
1.8 takayama 571: char *t;
572:
573: rob = NullObject;
574: if (nsep < 1) return rob;
575: if (sep[0] != -1) {
576: fprintf(stderr,"cgiToTokens: Not implemeted for this separator.\n");
577: return rob;
578: }
579:
580: /* Count the number of tokens */
581: n = strlen(s); i = 0; nOfTokens=0;
582: while (i < n) {
583: done = 0;
584: while (s[i] <= ' ') {
585: i++; if (i >= n) { done=1; break;}
586: }
587: if (done==1) break;
588: nOfTokens++;
589: while (s[i] > ' ') {
590: i++; if (i >= n) { done=1; break; }
591: }
592: if (done == 1) break;
593: }
594:
595: rob = newObjectArray(nOfTokens);
596: n = strlen(s); i = 0; k = 0;
597: while (i < n) {
598: done = 0;
599: while (s[i] <= ' ') {
600: i++; if (i >= n) { done=1; break;}
601: }
602: if (done==1) break;
603: start = i;
604: while (s[i] > ' ') {
605: i++; if (i >= n) { done=1; break; }
606: }
607: t = (char *) GC_malloc(i-start+1);
608: if (t == NULL) { fprintf(stderr,"No more memory.\n"); exit(10); }
609: t[i-start] = 0;
610: strncpy(t,&(s[start]),i-start);
611: putoa(rob,k,KpoString(t));
612: k++;
613: if (done == 1) break;
614: }
615:
616: return rob;
617: }
618:
619: struct object KooToTokens(struct object ob,struct object sep) {
620: char *s;
621: int n;
622: int tmp[1];
623: tmp[0] = -1;
624: if (ob.tag == Sdollar) {
625: s = KopString(ob);
626: n = strlen((char *)s);
627: }else errorKan1("%s\n","KooToTokens: the first argument must be a string.");
628: if (sep.tag == Sarray) {
629: if (getoaSize(sep) != 0) {
630: errorKan1("%s\n","This separators have not been implemented.");
631: }
632: }else errorKan1("%s\n","KooToTokens: the second argument(separators) must be an array.");
633: return toTokens(s,tmp,1);
1.3 takayama 634: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>