]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - gnu/usr.bin/perl/x2p/str.c
Add the missing rerelease target back.
[FreeBSD/FreeBSD.git] / gnu / usr.bin / perl / x2p / str.c
1 /* $RCSfile: str.c,v $$Revision: 1.1.1.1 $$Date: 1994/09/10 06:27:54 $
2  *
3  *    Copyright (c) 1991, Larry Wall
4  *
5  *    You may distribute under the terms of either the GNU General Public
6  *    License or the Artistic License, as specified in the README file.
7  *
8  * $Log: str.c,v $
9  * Revision 1.1.1.1  1994/09/10  06:27:54  gclarkii
10  * Initial import of Perl 4.046 bmaked
11  *
12  * Revision 1.1.1.1  1993/08/23  21:30:09  nate
13  * PERL!
14  *
15  * Revision 4.0.1.1  91/06/07  12:20:08  lwall
16  * patch4: new copyright notice
17  *
18  * Revision 4.0  91/03/20  01:58:15  lwall
19  * 4.0 baseline.
20  *
21  */
22
23 #include "handy.h"
24 #include "EXTERN.h"
25 #include "util.h"
26 #include "a2p.h"
27
28 str_numset(str,num)
29 register STR *str;
30 double num;
31 {
32     str->str_nval = num;
33     str->str_pok = 0;           /* invalidate pointer */
34     str->str_nok = 1;           /* validate number */
35 }
36
37 char *
38 str_2ptr(str)
39 register STR *str;
40 {
41     register char *s;
42
43     if (!str)
44         return "";
45     GROWSTR(&(str->str_ptr), &(str->str_len), 24);
46     s = str->str_ptr;
47     if (str->str_nok) {
48         sprintf(s,"%.20g",str->str_nval);
49         while (*s) s++;
50     }
51     *s = '\0';
52     str->str_cur = s - str->str_ptr;
53     str->str_pok = 1;
54 #ifdef DEBUGGING
55     if (debug & 32)
56         fprintf(stderr,"0x%lx ptr(%s)\n",str,str->str_ptr);
57 #endif
58     return str->str_ptr;
59 }
60
61 double
62 str_2num(str)
63 register STR *str;
64 {
65     if (!str)
66         return 0.0;
67     if (str->str_len && str->str_pok)
68         str->str_nval = atof(str->str_ptr);
69     else
70         str->str_nval = 0.0;
71     str->str_nok = 1;
72 #ifdef DEBUGGING
73     if (debug & 32)
74         fprintf(stderr,"0x%lx num(%g)\n",str,str->str_nval);
75 #endif
76     return str->str_nval;
77 }
78
79 str_sset(dstr,sstr)
80 STR *dstr;
81 register STR *sstr;
82 {
83     if (!sstr)
84         str_nset(dstr,No,0);
85     else if (sstr->str_nok)
86         str_numset(dstr,sstr->str_nval);
87     else if (sstr->str_pok)
88         str_nset(dstr,sstr->str_ptr,sstr->str_cur);
89     else
90         str_nset(dstr,"",0);
91 }
92
93 str_nset(str,ptr,len)
94 register STR *str;
95 register char *ptr;
96 register int len;
97 {
98     GROWSTR(&(str->str_ptr), &(str->str_len), len + 1);
99     bcopy(ptr,str->str_ptr,len);
100     str->str_cur = len;
101     *(str->str_ptr+str->str_cur) = '\0';
102     str->str_nok = 0;           /* invalidate number */
103     str->str_pok = 1;           /* validate pointer */
104 }
105
106 str_set(str,ptr)
107 register STR *str;
108 register char *ptr;
109 {
110     register int len;
111
112     if (!ptr)
113         ptr = "";
114     len = strlen(ptr);
115     GROWSTR(&(str->str_ptr), &(str->str_len), len + 1);
116     bcopy(ptr,str->str_ptr,len+1);
117     str->str_cur = len;
118     str->str_nok = 0;           /* invalidate number */
119     str->str_pok = 1;           /* validate pointer */
120 }
121
122 str_chop(str,ptr)       /* like set but assuming ptr is in str */
123 register STR *str;
124 register char *ptr;
125 {
126     if (!(str->str_pok))
127         str_2ptr(str);
128     str->str_cur -= (ptr - str->str_ptr);
129     bcopy(ptr,str->str_ptr, str->str_cur + 1);
130     str->str_nok = 0;           /* invalidate number */
131     str->str_pok = 1;           /* validate pointer */
132 }
133
134 str_ncat(str,ptr,len)
135 register STR *str;
136 register char *ptr;
137 register int len;
138 {
139     if (!(str->str_pok))
140         str_2ptr(str);
141     GROWSTR(&(str->str_ptr), &(str->str_len), str->str_cur + len + 1);
142     bcopy(ptr,str->str_ptr+str->str_cur,len);
143     str->str_cur += len;
144     *(str->str_ptr+str->str_cur) = '\0';
145     str->str_nok = 0;           /* invalidate number */
146     str->str_pok = 1;           /* validate pointer */
147 }
148
149 str_scat(dstr,sstr)
150 STR *dstr;
151 register STR *sstr;
152 {
153     if (!(sstr->str_pok))
154         str_2ptr(sstr);
155     if (sstr)
156         str_ncat(dstr,sstr->str_ptr,sstr->str_cur);
157 }
158
159 str_cat(str,ptr)
160 register STR *str;
161 register char *ptr;
162 {
163     register int len;
164
165     if (!ptr)
166         return;
167     if (!(str->str_pok))
168         str_2ptr(str);
169     len = strlen(ptr);
170     GROWSTR(&(str->str_ptr), &(str->str_len), str->str_cur + len + 1);
171     bcopy(ptr,str->str_ptr+str->str_cur,len+1);
172     str->str_cur += len;
173     str->str_nok = 0;           /* invalidate number */
174     str->str_pok = 1;           /* validate pointer */
175 }
176
177 char *
178 str_append_till(str,from,delim,keeplist)
179 register STR *str;
180 register char *from;
181 register int delim;
182 char *keeplist;
183 {
184     register char *to;
185     register int len;
186
187     if (!from)
188         return Nullch;
189     len = strlen(from);
190     GROWSTR(&(str->str_ptr), &(str->str_len), str->str_cur + len + 1);
191     str->str_nok = 0;           /* invalidate number */
192     str->str_pok = 1;           /* validate pointer */
193     to = str->str_ptr+str->str_cur;
194     for (; *from; from++,to++) {
195         if (*from == '\\' && from[1] && delim != '\\') {
196             if (!keeplist) {
197                 if (from[1] == delim || from[1] == '\\')
198                     from++;
199                 else
200                     *to++ = *from++;
201             }
202             else if (index(keeplist,from[1]))
203                 *to++ = *from++;
204             else
205                 from++;
206         }
207         else if (*from == delim)
208             break;
209         *to = *from;
210     }
211     *to = '\0';
212     str->str_cur = to - str->str_ptr;
213     return from;
214 }
215
216 STR *
217 str_new(len)
218 int len;
219 {
220     register STR *str;
221
222     if (freestrroot) {
223         str = freestrroot;
224         freestrroot = str->str_link.str_next;
225     }
226     else {
227         str = (STR *) safemalloc(sizeof(STR));
228         bzero((char*)str,sizeof(STR));
229     }
230     if (len)
231         GROWSTR(&(str->str_ptr), &(str->str_len), len + 1);
232     return str;
233 }
234
235 void
236 str_grow(str,len)
237 register STR *str;
238 int len;
239 {
240     if (len && str)
241         GROWSTR(&(str->str_ptr), &(str->str_len), len + 1);
242 }
243
244 /* make str point to what nstr did */
245
246 void
247 str_replace(str,nstr)
248 register STR *str;
249 register STR *nstr;
250 {
251     safefree(str->str_ptr);
252     str->str_ptr = nstr->str_ptr;
253     str->str_len = nstr->str_len;
254     str->str_cur = nstr->str_cur;
255     str->str_pok = nstr->str_pok;
256     if (str->str_nok = nstr->str_nok)
257         str->str_nval = nstr->str_nval;
258     safefree((char*)nstr);
259 }
260
261 void
262 str_free(str)
263 register STR *str;
264 {
265     if (!str)
266         return;
267     if (str->str_len)
268         str->str_ptr[0] = '\0';
269     str->str_cur = 0;
270     str->str_nok = 0;
271     str->str_pok = 0;
272     str->str_link.str_next = freestrroot;
273     freestrroot = str;
274 }
275
276 str_len(str)
277 register STR *str;
278 {
279     if (!str)
280         return 0;
281     if (!(str->str_pok))
282         str_2ptr(str);
283     if (str->str_len)
284         return str->str_cur;
285     else
286         return 0;
287 }
288
289 char *
290 str_gets(str,fp)
291 register STR *str;
292 register FILE *fp;
293 {
294 #ifdef STDSTDIO         /* Here is some breathtakingly efficient cheating */
295
296     register char *bp;          /* we're going to steal some values */
297     register int cnt;           /*  from the stdio struct and put EVERYTHING */
298     register STDCHAR *ptr;      /*   in the innermost loop into registers */
299     register char newline = '\n';       /* (assuming at least 6 registers) */
300     int i;
301     int bpx;
302
303     cnt = fp->_cnt;                     /* get count into register */
304     str->str_nok = 0;                   /* invalidate number */
305     str->str_pok = 1;                   /* validate pointer */
306     if (str->str_len <= cnt)            /* make sure we have the room */
307         GROWSTR(&(str->str_ptr), &(str->str_len), cnt+1);
308     bp = str->str_ptr;                  /* move these two too to registers */
309     ptr = fp->_ptr;
310     for (;;) {
311         while (--cnt >= 0) {
312             if ((*bp++ = *ptr++) == newline)
313                 if (bp <= str->str_ptr || bp[-2] != '\\')
314                     goto thats_all_folks;
315                 else {
316                     line++;
317                     bp -= 2;
318                 }
319         }
320
321         fp->_cnt = cnt;                 /* deregisterize cnt and ptr */
322         fp->_ptr = ptr;
323         i = _filbuf(fp);                /* get more characters */
324         cnt = fp->_cnt;
325         ptr = fp->_ptr;                 /* reregisterize cnt and ptr */
326
327         bpx = bp - str->str_ptr;        /* prepare for possible relocation */
328         GROWSTR(&(str->str_ptr), &(str->str_len), str->str_cur + cnt + 1);
329         bp = str->str_ptr + bpx;        /* reconstitute our pointer */
330
331         if (i == newline) {             /* all done for now? */
332             *bp++ = i;
333             goto thats_all_folks;
334         }
335         else if (i == EOF)              /* all done for ever? */
336             goto thats_all_folks;
337         *bp++ = i;                      /* now go back to screaming loop */
338     }
339
340 thats_all_folks:
341     fp->_cnt = cnt;                     /* put these back or we're in trouble */
342     fp->_ptr = ptr;
343     *bp = '\0';
344     str->str_cur = bp - str->str_ptr;   /* set length */
345
346 #else /* !STDSTDIO */   /* The big, slow, and stupid way */
347
348     static char buf[4192];
349
350     if (fgets(buf, sizeof buf, fp) != Nullch)
351         str_set(str, buf);
352     else
353         str_set(str, No);
354
355 #endif /* STDSTDIO */
356
357     return str->str_cur ? str->str_ptr : Nullch;
358 }
359
360 void
361 str_inc(str)
362 register STR *str;
363 {
364     register char *d;
365
366     if (!str)
367         return;
368     if (str->str_nok) {
369         str->str_nval += 1.0;
370         str->str_pok = 0;
371         return;
372     }
373     if (!str->str_pok) {
374         str->str_nval = 1.0;
375         str->str_nok = 1;
376         return;
377     }
378     for (d = str->str_ptr; *d && *d != '.'; d++) ;
379     d--;
380     if (!isdigit(*str->str_ptr) || !isdigit(*d) ) {
381         str_numset(str,atof(str->str_ptr) + 1.0);  /* punt */
382         return;
383     }
384     while (d >= str->str_ptr) {
385         if (++*d <= '9')
386             return;
387         *(d--) = '0';
388     }
389     /* oh,oh, the number grew */
390     GROWSTR(&(str->str_ptr), &(str->str_len), str->str_cur + 2);
391     str->str_cur++;
392     for (d = str->str_ptr + str->str_cur; d > str->str_ptr; d--)
393         *d = d[-1];
394     *d = '1';
395 }
396
397 void
398 str_dec(str)
399 register STR *str;
400 {
401     register char *d;
402
403     if (!str)
404         return;
405     if (str->str_nok) {
406         str->str_nval -= 1.0;
407         str->str_pok = 0;
408         return;
409     }
410     if (!str->str_pok) {
411         str->str_nval = -1.0;
412         str->str_nok = 1;
413         return;
414     }
415     for (d = str->str_ptr; *d && *d != '.'; d++) ;
416     d--;
417     if (!isdigit(*str->str_ptr) || !isdigit(*d) || (*d == '0' && d == str->str_ptr)) {
418         str_numset(str,atof(str->str_ptr) - 1.0);  /* punt */
419         return;
420     }
421     while (d >= str->str_ptr) {
422         if (--*d >= '0')
423             return;
424         *(d--) = '9';
425     }
426 }
427
428 /* make a string that will exist for the duration of the expression eval */
429
430 STR *
431 str_mortal(oldstr)
432 STR *oldstr;
433 {
434     register STR *str = str_new(0);
435     static long tmps_size = -1;
436
437     str_sset(str,oldstr);
438     if (++tmps_max > tmps_size) {
439         tmps_size = tmps_max;
440         if (!(tmps_size & 127)) {
441             if (tmps_size)
442                 tmps_list = (STR**)saferealloc((char*)tmps_list,
443                     (tmps_size + 128) * sizeof(STR*) );
444             else
445                 tmps_list = (STR**)safemalloc(128 * sizeof(char*));
446         }
447     }
448     tmps_list[tmps_max] = str;
449     return str;
450 }
451
452 STR *
453 str_make(s)
454 char *s;
455 {
456     register STR *str = str_new(0);
457
458     str_set(str,s);
459     return str;
460 }
461
462 STR *
463 str_nmake(n)
464 double n;
465 {
466     register STR *str = str_new(0);
467
468     str_numset(str,n);
469     return str;
470 }