perl 2.0 (no announcement message available)
[p5sagit/p5-mst-13.2.git] / str.c
CommitLineData
378cc40b 1/* $Header: str.c,v 2.0 88/06/05 00:11:07 root Exp $
8d063cd8 2 *
3 * $Log: str.c,v $
378cc40b 4 * Revision 2.0 88/06/05 00:11:07 root
5 * Baseline version 2.0.
8d063cd8 6 *
7 */
8
8d063cd8 9#include "EXTERN.h"
8d063cd8 10#include "perl.h"
11
12str_reset(s)
13register char *s;
14{
15 register STAB *stab;
16 register STR *str;
17 register int i;
18 register int max;
19 register SPAT *spat;
20
21 if (!*s) { /* reset ?? searches */
22 for (spat = spat_root; spat != Nullspat; spat = spat->spat_next) {
23 spat->spat_flags &= ~SPAT_USED;
24 }
25 return;
26 }
27
28 /* reset variables */
29
30 while (*s) {
31 i = *s;
32 if (s[1] == '-') {
33 s += 2;
34 }
35 max = *s++;
36 for ( ; i <= max; i++) {
37 for (stab = stab_index[i]; stab; stab = stab->stab_next) {
38 str = stab->stab_val;
39 str->str_cur = 0;
378cc40b 40 str->str_nok = 0;
8d063cd8 41 if (str->str_ptr != Nullch)
42 str->str_ptr[0] = '\0';
378cc40b 43 if (stab->stab_array) {
44 aclear(stab->stab_array);
45 }
46 if (stab->stab_hash) {
47 hclear(stab->stab_hash);
48 }
8d063cd8 49 }
50 }
51 }
52}
53
54str_numset(str,num)
55register STR *str;
56double num;
57{
58 str->str_nval = num;
59 str->str_pok = 0; /* invalidate pointer */
60 str->str_nok = 1; /* validate number */
61}
62
378cc40b 63extern int errno;
64
8d063cd8 65char *
66str_2ptr(str)
67register STR *str;
68{
69 register char *s;
378cc40b 70 int olderrno;
8d063cd8 71
72 if (!str)
73 return "";
74 GROWSTR(&(str->str_ptr), &(str->str_len), 24);
75 s = str->str_ptr;
76 if (str->str_nok) {
378cc40b 77 olderrno = errno; /* some Xenix systems wipe out errno here */
78#if defined(scs) && defined(ns32000)
79 gcvt(str->str_nval,20,s);
80#else
81#ifdef apollo
82 if (str->str_nval == 0.0)
83 strcpy(s,"0");
84 else
85#endif /*apollo*/
8d063cd8 86 sprintf(s,"%.20g",str->str_nval);
378cc40b 87#endif /*scs*/
88 errno = olderrno;
8d063cd8 89 while (*s) s++;
90 }
378cc40b 91 else if (dowarn)
92 warn("Use of uninitialized variable");
8d063cd8 93 *s = '\0';
94 str->str_cur = s - str->str_ptr;
95 str->str_pok = 1;
96#ifdef DEBUGGING
97 if (debug & 32)
98 fprintf(stderr,"0x%lx ptr(%s)\n",str,str->str_ptr);
99#endif
100 return str->str_ptr;
101}
102
103double
104str_2num(str)
105register STR *str;
106{
107 if (!str)
108 return 0.0;
109 if (str->str_len && str->str_pok)
110 str->str_nval = atof(str->str_ptr);
378cc40b 111 else {
112 if (dowarn)
113 fprintf(stderr,"Use of uninitialized variable in %s line %ld.\n",
114 filename,(long)line);
8d063cd8 115 str->str_nval = 0.0;
378cc40b 116 }
8d063cd8 117 str->str_nok = 1;
118#ifdef DEBUGGING
119 if (debug & 32)
120 fprintf(stderr,"0x%lx num(%g)\n",str,str->str_nval);
121#endif
122 return str->str_nval;
123}
124
125str_sset(dstr,sstr)
126STR *dstr;
127register STR *sstr;
128{
129 if (!sstr)
130 str_nset(dstr,No,0);
131 else if (sstr->str_nok)
132 str_numset(dstr,sstr->str_nval);
133 else if (sstr->str_pok)
134 str_nset(dstr,sstr->str_ptr,sstr->str_cur);
135 else
136 str_nset(dstr,"",0);
137}
138
139str_nset(str,ptr,len)
140register STR *str;
141register char *ptr;
142register int len;
143{
144 GROWSTR(&(str->str_ptr), &(str->str_len), len + 1);
145 bcopy(ptr,str->str_ptr,len);
146 str->str_cur = len;
147 *(str->str_ptr+str->str_cur) = '\0';
148 str->str_nok = 0; /* invalidate number */
149 str->str_pok = 1; /* validate pointer */
150}
151
152str_set(str,ptr)
153register STR *str;
154register char *ptr;
155{
156 register int len;
157
158 if (!ptr)
159 ptr = "";
160 len = strlen(ptr);
161 GROWSTR(&(str->str_ptr), &(str->str_len), len + 1);
162 bcopy(ptr,str->str_ptr,len+1);
163 str->str_cur = len;
164 str->str_nok = 0; /* invalidate number */
165 str->str_pok = 1; /* validate pointer */
166}
167
168str_chop(str,ptr) /* like set but assuming ptr is in str */
169register STR *str;
170register char *ptr;
171{
172 if (!(str->str_pok))
173 str_2ptr(str);
174 str->str_cur -= (ptr - str->str_ptr);
175 bcopy(ptr,str->str_ptr, str->str_cur + 1);
176 str->str_nok = 0; /* invalidate number */
177 str->str_pok = 1; /* validate pointer */
178}
179
180str_ncat(str,ptr,len)
181register STR *str;
182register char *ptr;
183register int len;
184{
185 if (!(str->str_pok))
186 str_2ptr(str);
187 GROWSTR(&(str->str_ptr), &(str->str_len), str->str_cur + len + 1);
188 bcopy(ptr,str->str_ptr+str->str_cur,len);
189 str->str_cur += len;
190 *(str->str_ptr+str->str_cur) = '\0';
191 str->str_nok = 0; /* invalidate number */
192 str->str_pok = 1; /* validate pointer */
193}
194
195str_scat(dstr,sstr)
196STR *dstr;
197register STR *sstr;
198{
378cc40b 199 if (!sstr)
200 return;
8d063cd8 201 if (!(sstr->str_pok))
202 str_2ptr(sstr);
203 if (sstr)
204 str_ncat(dstr,sstr->str_ptr,sstr->str_cur);
205}
206
207str_cat(str,ptr)
208register STR *str;
209register char *ptr;
210{
211 register int len;
212
213 if (!ptr)
214 return;
215 if (!(str->str_pok))
216 str_2ptr(str);
217 len = strlen(ptr);
218 GROWSTR(&(str->str_ptr), &(str->str_len), str->str_cur + len + 1);
219 bcopy(ptr,str->str_ptr+str->str_cur,len+1);
220 str->str_cur += len;
221 str->str_nok = 0; /* invalidate number */
222 str->str_pok = 1; /* validate pointer */
223}
224
225char *
226str_append_till(str,from,delim,keeplist)
227register STR *str;
228register char *from;
229register int delim;
230char *keeplist;
231{
232 register char *to;
233 register int len;
234
235 if (!from)
236 return Nullch;
237 len = strlen(from);
238 GROWSTR(&(str->str_ptr), &(str->str_len), str->str_cur + len + 1);
239 str->str_nok = 0; /* invalidate number */
240 str->str_pok = 1; /* validate pointer */
241 to = str->str_ptr+str->str_cur;
242 for (; *from; from++,to++) {
243 if (*from == '\\' && from[1] && delim != '\\') {
244 if (!keeplist) {
245 if (from[1] == delim || from[1] == '\\')
246 from++;
247 else
248 *to++ = *from++;
249 }
250 else if (index(keeplist,from[1]))
251 *to++ = *from++;
252 else
253 from++;
254 }
255 else if (*from == delim)
256 break;
257 *to = *from;
258 }
259 *to = '\0';
260 str->str_cur = to - str->str_ptr;
261 return from;
262}
263
264STR *
265str_new(len)
266int len;
267{
268 register STR *str;
269
270 if (freestrroot) {
271 str = freestrroot;
272 freestrroot = str->str_link.str_next;
273 str->str_link.str_magic = Nullstab;
274 }
275 else {
276 str = (STR *) safemalloc(sizeof(STR));
277 bzero((char*)str,sizeof(STR));
278 }
279 if (len)
280 GROWSTR(&(str->str_ptr), &(str->str_len), len + 1);
281 return str;
282}
283
284void
285str_grow(str,len)
286register STR *str;
287int len;
288{
289 if (len && str)
290 GROWSTR(&(str->str_ptr), &(str->str_len), len + 1);
291}
292
293/* make str point to what nstr did */
294
295void
296str_replace(str,nstr)
297register STR *str;
298register STR *nstr;
299{
300 safefree(str->str_ptr);
301 str->str_ptr = nstr->str_ptr;
302 str->str_len = nstr->str_len;
303 str->str_cur = nstr->str_cur;
304 str->str_pok = nstr->str_pok;
305 if (str->str_nok = nstr->str_nok)
306 str->str_nval = nstr->str_nval;
307 safefree((char*)nstr);
308}
309
310void
311str_free(str)
312register STR *str;
313{
314 if (!str)
315 return;
316 if (str->str_len)
317 str->str_ptr[0] = '\0';
318 str->str_cur = 0;
319 str->str_nok = 0;
320 str->str_pok = 0;
321 str->str_link.str_next = freestrroot;
322 freestrroot = str;
323}
324
325str_len(str)
326register STR *str;
327{
328 if (!str)
329 return 0;
330 if (!(str->str_pok))
331 str_2ptr(str);
332 if (str->str_len)
333 return str->str_cur;
334 else
335 return 0;
336}
337
338char *
339str_gets(str,fp)
340register STR *str;
341register FILE *fp;
342{
343#ifdef STDSTDIO /* Here is some breathtakingly efficient cheating */
344
345 register char *bp; /* we're going to steal some values */
346 register int cnt; /* from the stdio struct and put EVERYTHING */
36ce8bec 347 register STDCHAR *ptr; /* in the innermost loop into registers */
348 register char newline = record_separator;/* (assuming >= 6 registers) */
8d063cd8 349 int i;
350 int bpx;
351 int obpx;
352 register int get_paragraph;
353 register char *oldbp;
354
355 if (get_paragraph = !newline) { /* yes, that's an assignment */
356 newline = '\n';
357 oldbp = Nullch; /* remember last \n position (none) */
358 }
359 cnt = fp->_cnt; /* get count into register */
360 str->str_nok = 0; /* invalidate number */
361 str->str_pok = 1; /* validate pointer */
362 if (str->str_len <= cnt) /* make sure we have the room */
363 GROWSTR(&(str->str_ptr), &(str->str_len), cnt+1);
364 bp = str->str_ptr; /* move these two too to registers */
365 ptr = fp->_ptr;
366 for (;;) {
367 screamer:
368 while (--cnt >= 0) { /* this */ /* eat */
369 if ((*bp++ = *ptr++) == newline) /* really */ /* dust */
370 goto thats_all_folks; /* screams */ /* sed :-) */
371 }
372
373 fp->_cnt = cnt; /* deregisterize cnt and ptr */
374 fp->_ptr = ptr;
375 i = _filbuf(fp); /* get more characters */
376 cnt = fp->_cnt;
377 ptr = fp->_ptr; /* reregisterize cnt and ptr */
378
379 bpx = bp - str->str_ptr; /* prepare for possible relocation */
380 if (get_paragraph && oldbp)
381 obpx = oldbp - str->str_ptr;
378cc40b 382 GROWSTR(&(str->str_ptr), &(str->str_len), bpx + cnt + 2);
8d063cd8 383 bp = str->str_ptr + bpx; /* reconstitute our pointer */
384 if (get_paragraph && oldbp)
385 oldbp = str->str_ptr + obpx;
386
387 if (i == newline) { /* all done for now? */
388 *bp++ = i;
389 goto thats_all_folks;
390 }
391 else if (i == EOF) /* all done for ever? */
392 goto thats_really_all_folks;
393 *bp++ = i; /* now go back to screaming loop */
394 }
395
396thats_all_folks:
397 if (get_paragraph && bp - 1 != oldbp) {
398 oldbp = bp; /* remember where this newline was */
399 goto screamer; /* and go back to the fray */
400 }
401thats_really_all_folks:
402 fp->_cnt = cnt; /* put these back or we're in trouble */
403 fp->_ptr = ptr;
404 *bp = '\0';
405 str->str_cur = bp - str->str_ptr; /* set length */
406
407#else /* !STDSTDIO */ /* The big, slow, and stupid way */
408
409 static char buf[4192];
410
411 if (fgets(buf, sizeof buf, fp) != Nullch)
412 str_set(str, buf);
413 else
414 str_set(str, No);
415
416#endif /* STDSTDIO */
417
418 return str->str_cur ? str->str_ptr : Nullch;
419}
420
421
422STR *
423interp(str,s)
424register STR *str;
425register char *s;
426{
427 register char *t = s;
428 char *envsave = envname;
429 envname = Nullch;
430
431 str_set(str,"");
432 while (*s) {
378cc40b 433 if (*s == '\\' && s[1] == '\\') {
434 str_ncat(str, t, s++ - t);
435 t = s++;
436 }
437 else if (*s == '\\' && s[1] == '$') {
8d063cd8 438 str_ncat(str, t, s++ - t);
439 t = s++;
440 }
441 else if (*s == '$' && s[1] && s[1] != '|') {
442 str_ncat(str,t,s-t);
443 s = scanreg(s,tokenbuf);
444 str_cat(str,reg_get(tokenbuf));
445 t = s;
446 }
447 else
448 s++;
449 }
450 envname = envsave;
451 str_ncat(str,t,s-t);
452 return str;
453}
454
455void
456str_inc(str)
457register STR *str;
458{
459 register char *d;
460
461 if (!str)
462 return;
463 if (str->str_nok) {
464 str->str_nval += 1.0;
465 str->str_pok = 0;
466 return;
467 }
378cc40b 468 if (!str->str_pok || !*str->str_ptr) {
8d063cd8 469 str->str_nval = 1.0;
470 str->str_nok = 1;
471 return;
472 }
378cc40b 473 d = str->str_ptr;
474 while (isalpha(*d)) d++;
475 while (isdigit(*d)) d++;
476 if (*d) {
8d063cd8 477 str_numset(str,atof(str->str_ptr) + 1.0); /* punt */
478 return;
479 }
378cc40b 480 d--;
8d063cd8 481 while (d >= str->str_ptr) {
378cc40b 482 if (isdigit(*d)) {
483 if (++*d <= '9')
484 return;
485 *(d--) = '0';
486 }
487 else {
488 ++*d;
489 if (isalpha(*d))
490 return;
491 *(d--) -= 'z' - 'a' + 1;
492 }
8d063cd8 493 }
494 /* oh,oh, the number grew */
495 GROWSTR(&(str->str_ptr), &(str->str_len), str->str_cur + 2);
496 str->str_cur++;
497 for (d = str->str_ptr + str->str_cur; d > str->str_ptr; d--)
498 *d = d[-1];
378cc40b 499 if (isdigit(d[1]))
500 *d = '1';
501 else
502 *d = d[1];
8d063cd8 503}
504
505void
506str_dec(str)
507register STR *str;
508{
8d063cd8 509 if (!str)
510 return;
511 if (str->str_nok) {
512 str->str_nval -= 1.0;
513 str->str_pok = 0;
514 return;
515 }
516 if (!str->str_pok) {
517 str->str_nval = -1.0;
518 str->str_nok = 1;
519 return;
520 }
378cc40b 521 str_numset(str,atof(str->str_ptr) - 1.0);
8d063cd8 522}
523
524/* make a string that will exist for the duration of the expression eval */
525
526STR *
527str_static(oldstr)
528STR *oldstr;
529{
530 register STR *str = str_new(0);
531 static long tmps_size = -1;
532
533 str_sset(str,oldstr);
534 if (++tmps_max > tmps_size) {
535 tmps_size = tmps_max;
536 if (!(tmps_size & 127)) {
537 if (tmps_size)
538 tmps_list = (STR**)saferealloc((char*)tmps_list,
378cc40b 539 (MEM_SIZE)((tmps_size + 128) * sizeof(STR*)) );
8d063cd8 540 else
541 tmps_list = (STR**)safemalloc(128 * sizeof(char*));
542 }
543 }
544 tmps_list[tmps_max] = str;
545 return str;
546}
547
548STR *
549str_make(s)
550char *s;
551{
552 register STR *str = str_new(0);
553
554 str_set(str,s);
555 return str;
556}
557
558STR *
559str_nmake(n)
560double n;
561{
562 register STR *str = str_new(0);
563
564 str_numset(str,n);
565 return str;
566}