1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI not be used in advertising or publicity pertaining to
13 distribution of the software without specific, written prior permission.
15 STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18 FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21 OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 ******************************************************************/
27 #include "allobjects.h"
28 #include "modsupport.h"
31 /* XXX This file assumes that the <ctype.h> is*() functions
32 XXX are defined for all 8-bit characters! */
38 strop_split(self
, args
)
39 object
*self
; /* Not used */
47 if (!getargs(args
, "s#", &s
, &len
))
49 list
= newlistobject(0);
56 ((c
= s
[i
]), isspace(c
))) {
61 !((c
= s
[i
]), isspace(c
))) {
65 item
= newsizedstringobject(s
+j
, (int)(i
-j
));
70 err
= addlistitem(list
, item
);
84 strop_splitfields(self
, args
)
85 object
*self
; /* Not used */
88 int len
, n
, i
, j
, err
;
92 if (!getargs(args
, "(s#s#)", &s
, &len
, &sub
, &n
))
95 err_setstr(ValueError
, "empty separator");
99 list
= newlistobject(0);
105 if (s
[i
] == sub
[0] && (n
== 1 || strncmp(s
+i
, sub
, n
) == 0)) {
106 item
= newsizedstringobject(s
+j
, (int)(i
-j
));
109 err
= addlistitem(list
, item
);
118 item
= newsizedstringobject(s
+j
, (int)(len
-j
));
121 err
= addlistitem(list
, item
);
135 strop_joinfields(self
, args
)
136 object
*self
; /* Not used */
139 object
*seq
, *item
, *res
;
140 object
* (*getitem
) FPROTO((object
*, int));
142 int seplen
, seqlen
, reslen
, itemlen
, i
;
144 if (!getargs(args
, "(Os#)", &seq
, &sep
, &seplen
))
146 if (is_listobject(seq
)) {
147 getitem
= getlistitem
;
148 seqlen
= getlistsize(seq
);
150 else if (is_tupleobject(seq
)) {
151 getitem
= gettupleitem
;
152 seqlen
= gettuplesize(seq
);
155 err_setstr(TypeError
, "first argument must be list/tuple");
159 for (i
= 0; i
< seqlen
; i
++) {
160 item
= getitem(seq
, i
);
161 if (!is_stringobject(item
)) {
162 err_setstr(TypeError
,
163 "first argument must be list/tuple of strings");
167 reslen
= reslen
+ seplen
;
168 reslen
= reslen
+ getstringsize(item
);
171 /* Optimization if there's only one item */
172 item
= getitem(seq
, 0);
176 res
= newsizedstringobject((char *)NULL
, reslen
);
179 p
= getstringvalue(res
);
180 for (i
= 0; i
< seqlen
; i
++) {
181 item
= getitem(seq
, i
);
183 memcpy(p
, sep
, seplen
);
186 itemlen
= getstringsize(item
);
187 memcpy(p
, getstringvalue(item
), itemlen
);
190 if (p
!= getstringvalue(res
) + reslen
) {
191 err_setstr(SystemError
, "strop.joinfields: assertion failed");
199 strop_find(self
, args
)
200 object
*self
; /* Not used */
206 if (getargs(args
, "(s#s#i)", &s
, &len
, &sub
, &n
, &i
)) {
214 if (!getargs(args
, "(s#s#)", &s
, &len
, &sub
, &n
))
220 return newintobject((long)i
);
223 for (; i
<= len
; ++i
)
224 if (s
[i
] == sub
[0] &&
225 (n
== 1 || strncmp(&s
[i
+1], &sub
[1], n
-1) == 0))
226 return newintobject((long)i
);
228 return newintobject(-1L);
233 strop_rfind(self
, args
)
234 object
*self
; /* Not used */
240 if (getargs(args
, "(s#s#i)", &s
, &len
, &sub
, &n
, &i
)) {
248 if (!getargs(args
, "(s#s#)", &s
, &len
, &sub
, &n
))
254 return newintobject((long)len
);
256 for (j
= len
-n
; j
>= i
; --j
)
257 if (s
[j
] == sub
[0] &&
258 (n
== 1 || strncmp(&s
[j
+1], &sub
[1], n
-1) == 0))
259 return newintobject((long)j
);
261 return newintobject(-1L);
266 strop_strip(self
, args
)
267 object
*self
; /* Not used */
274 if (!getargs(args
, "s#", &s
, &len
))
278 while (i
< len
&& ((c
= s
[i
]), isspace(c
))) {
285 } while (j
>= i
&& ((c
= s
[j
]), isspace(c
)));
288 if (i
== 0 && j
== len
) {
293 return newsizedstringobject(s
+i
, j
-i
);
298 strop_lower(self
, args
)
299 object
*self
; /* Not used */
307 if (!getargs(args
, "s#", &s
, &n
))
309 new = newsizedstringobject(NULL
, n
);
312 s_new
= getstringvalue(new);
314 for (i
= 0; i
< n
; i
++) {
333 strop_upper(self
, args
)
334 object
*self
; /* Not used */
342 if (!getargs(args
, "s#", &s
, &n
))
344 new = newsizedstringobject(NULL
, n
);
347 s_new
= getstringvalue(new);
349 for (i
= 0; i
< n
; i
++) {
368 strop_swapcase(self
, args
)
369 object
*self
; /* Not used */
377 if (!getargs(args
, "s#", &s
, &n
))
379 new = newsizedstringobject(NULL
, n
);
382 s_new
= getstringvalue(new);
384 for (i
= 0; i
< n
; i
++) {
390 else if (isupper(c
)) {
408 strop_atoi(self
, args
)
409 object
*self
; /* Not used */
412 extern long mystrtol
PROTO((const char *, char **, int));
413 extern unsigned long mystrtoul
PROTO((const char *, char **, int));
418 if (args
!= NULL
&& is_tupleobject(args
)) {
419 if (!getargs(args
, "(si)", &s
, &base
))
421 if (base
!= 0 && base
< 2 || base
> 36) {
422 err_setstr(ValueError
, "invalid base for atoi()");
426 else if (!getargs(args
, "s", &s
))
429 if (base
== 0 && s
[0] == '0')
430 x
= (long) mystrtoul(s
, &end
, base
);
432 x
= mystrtol(s
, &end
, base
);
434 err_setstr(ValueError
, "invalid literal for atoi()");
437 else if (errno
!= 0) {
438 err_setstr(OverflowError
, "atoi() literal too large");
441 return newintobject(x
);
446 strop_atol(self
, args
)
447 object
*self
; /* Not used */
454 if (args
!= NULL
&& is_tupleobject(args
)) {
455 if (!getargs(args
, "(si)", &s
, &base
))
457 if (base
!= 0 && base
< 2 || base
> 36) {
458 err_setstr(ValueError
, "invalid base for atol()");
462 else if (!getargs(args
, "s", &s
))
464 x
= long_escan(s
, &end
, base
);
467 if (base
== 0 && (*end
== 'l' || *end
== 'L'))
470 err_setstr(ValueError
, "invalid literal for atol()");
479 strop_atof(self
, args
)
480 object
*self
; /* Not used */
483 extern double strtod
PROTO((const char *, char **));
487 if (!getargs(args
, "s", &s
))
492 err_setstr(ValueError
, "invalid literal for atof()");
495 else if (errno
!= 0) {
496 err_setstr(OverflowError
, "atof() literal too large");
499 return newfloatobject(x
);
503 /* List of functions defined in the module */
505 static struct methodlist strop_methods
[] = {
506 {"atof", strop_atof
},
507 {"atoi", strop_atoi
},
508 {"atol", strop_atol
},
509 {"find", strop_find
},
510 {"joinfields", strop_joinfields
},
511 {"lower", strop_lower
},
512 {"rfind", strop_rfind
},
513 {"split", strop_split
},
514 {"splitfields", strop_splitfields
},
515 {"strip", strop_strip
},
516 {"swapcase", strop_swapcase
},
517 {"upper", strop_upper
},
518 {NULL
, NULL
} /* sentinel */
528 m
= initmodule("strop", strop_methods
);
529 d
= getmoduledict(m
);
531 /* Create 'whitespace' object */
533 for (c
= 1; c
< 256; c
++) {
537 s
= newsizedstringobject(buf
, n
);
539 dictinsert(d
, "whitespace", s
);
542 /* Create 'lowercase' object */
544 for (c
= 1; c
< 256; c
++) {
548 s
= newsizedstringobject(buf
, n
);
550 dictinsert(d
, "lowercase", s
);
554 /* Create 'uppercase' object */
556 for (c
= 1; c
< 256; c
++) {
560 s
= newsizedstringobject(buf
, n
);
562 dictinsert(d
, "uppercase", s
);
567 fatal("can't initialize module strop");