File Coverage

x2p/str.c
Criterion Covered Total %
statement 0 102 0.0
branch n/a
condition n/a
subroutine n/a
total 0 102 0.0


line stmt bran cond sub time code
1           /* str.c
2           *
3           * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1999,
4           * 2001, 2002, 2005 by Larry Wall and others
5           *
6           * You may distribute under the terms of either the GNU General Public
7           * License or the Artistic License, as specified in the README file.
8           */
9            
10           #include "EXTERN.h"
11           #include "a2p.h"
12           #include "util.h"
13            
14           void
15 0         str_numset(STR *str, double num)
16           {
17 0         str->str_nval = num;
18 0         str->str_pok = 0; /* invalidate pointer */
19 0         str->str_nok = 1; /* validate number */
20 0         }
21            
22           char *
23 0         str_2ptr(STR *str)
24           {
25           char *s;
26            
27 0         if (!str)
28           return (char *)""; /* probably safe - won't be written to */
29 0         GROWSTR(&(str->str_ptr), &(str->str_len), 24);
30 0         s = str->str_ptr;
31 0         if (str->str_nok) {
32 0         sprintf(s,"%.20g",str->str_nval);
33 0         while (*s) s++;
34           }
35 0         *s = '\0';
36 0         str->str_cur = s - str->str_ptr;
37 0         str->str_pok = 1;
38           #ifdef DEBUGGING
39           if (debug & 32)
40           fprintf(stderr,"0x%lx ptr(%s)\n",(unsigned long)str,str->str_ptr);
41           #endif
42 0         return str->str_ptr;
43           }
44            
45           void
46 0         str_sset(STR *dstr, STR *sstr)
47           {
48 0         if (!sstr)
49 0         str_nset(dstr,No,0);
50 0         else if (sstr->str_nok)
51 0         str_numset(dstr,sstr->str_nval);
52 0         else if (sstr->str_pok)
53 0         str_nset(dstr,sstr->str_ptr,sstr->str_cur);
54           else
55 0         str_nset(dstr,"",0);
56 0         }
57            
58           void
59 0         str_nset(STR *str, const char *ptr, int len)
60           {
61 0         GROWSTR(&(str->str_ptr), &(str->str_len), len + 1);
62 0         memcpy(str->str_ptr,ptr,len);
63 0         str->str_cur = len;
64 0         *(str->str_ptr+str->str_cur) = '\0';
65 0         str->str_nok = 0; /* invalidate number */
66 0         str->str_pok = 1; /* validate pointer */
67 0         }
68            
69           void
70 0         str_set(STR *str, const char *ptr)
71           {
72           int len;
73            
74 0         if (!ptr)
75           ptr = "";
76 0         len = strlen(ptr);
77 0         GROWSTR(&(str->str_ptr), &(str->str_len), len + 1);
78 0         memcpy(str->str_ptr,ptr,len+1);
79 0         str->str_cur = len;
80 0         str->str_nok = 0; /* invalidate number */
81 0         str->str_pok = 1; /* validate pointer */
82 0         }
83            
84           void
85 0         str_ncat(STR *str, const char *ptr, int len)
86           {
87 0         if (!(str->str_pok))
88 0         str_2ptr(str);
89 0         GROWSTR(&(str->str_ptr), &(str->str_len), str->str_cur + len + 1);
90 0         memcpy(str->str_ptr+str->str_cur, ptr, len);
91 0         str->str_cur += len;
92 0         *(str->str_ptr+str->str_cur) = '\0';
93 0         str->str_nok = 0; /* invalidate number */
94 0         str->str_pok = 1; /* validate pointer */
95 0         }
96            
97           void
98 0         str_scat(STR *dstr, STR *sstr)
99           {
100 0         if (!(sstr->str_pok))
101 0         str_2ptr(sstr);
102 0         if (sstr)
103 0         str_ncat(dstr,sstr->str_ptr,sstr->str_cur);
104 0         }
105            
106           void
107 0         str_cat(STR *str, const char *ptr)
108           {
109           int len;
110            
111 0         if (!ptr)
112 0         return;
113 0         if (!(str->str_pok))
114 0         str_2ptr(str);
115 0         len = strlen(ptr);
116 0         GROWSTR(&(str->str_ptr), &(str->str_len), str->str_cur + len + 1);
117 0         memcpy(str->str_ptr+str->str_cur, ptr, len+1);
118 0         str->str_cur += len;
119 0         str->str_nok = 0; /* invalidate number */
120 0         str->str_pok = 1; /* validate pointer */
121           }
122            
123           STR *
124 0         str_new(int len)
125           {
126           STR *str;
127          
128 0         if (freestrroot) {
129 0         str = freestrroot;
130 0         freestrroot = str->str_link.str_next;
131           }
132           else {
133 0         str = (STR *) safemalloc(sizeof(STR));
134           memset((char*)str,0,sizeof(STR));
135           }
136 0         if (len)
137 0         GROWSTR(&(str->str_ptr), &(str->str_len), len + 1);
138 0         return str;
139           }
140            
141           /* make str point to what nstr did */
142            
143           void
144 0         str_free(STR *str)
145           {
146 0         if (!str)
147 0         return;
148 0         if (str->str_len)
149 0         str->str_ptr[0] = '\0';
150 0         str->str_cur = 0;
151 0         str->str_nok = 0;
152 0         str->str_pok = 0;
153 0         str->str_link.str_next = freestrroot;
154 0         freestrroot = str;
155           }
156            
157           int
158 0         str_len(STR *str)
159           {
160 0         if (!str)
161           return 0;
162 0         if (!(str->str_pok))
163 0         str_2ptr(str);
164 0         if (str->str_len)
165 0         return str->str_cur;
166           else
167           return 0;
168           }
169            
170           char *
171 0         str_gets(STR *str, FILE *fp)
172           {
173           #if defined(USE_STDIO_PTR) && defined(STDIO_PTR_LVALUE) && defined(STDIO_CNT_LVALUE)
174           /* Here is some breathtakingly efficient cheating */
175            
176           char *bp; /* we're going to steal some values */
177           int cnt; /* from the stdio struct and put EVERYTHING */
178           STDCHAR *ptr; /* in the innermost loop into registers */
179           char newline = '\n'; /* (assuming at least 6 registers) */
180           int i;
181           int bpx;
182            
183           #if defined(VMS)
184           /* An ungetc()d char is handled separately from the regular
185           * buffer, so we getc() it back out and stuff it in the buffer.
186           */
187           i = getc(fp);
188           if (i == EOF) return NULL;
189           *(--((*fp)->_ptr)) = (unsigned char) i;
190           (*fp)->_cnt++;
191           #endif
192            
193           cnt = FILE_cnt(fp); /* get count into register */
194           str->str_nok = 0; /* invalidate number */
195           str->str_pok = 1; /* validate pointer */
196           if (str->str_len <= cnt) /* make sure we have the room */
197           GROWSTR(&(str->str_ptr), &(str->str_len), cnt+1);
198           bp = str->str_ptr; /* move these two too to registers */
199           ptr = (STDCHAR*)FILE_ptr(fp);
200           for (;;) {
201           while (--cnt >= 0) {
202           if ((*bp++ = *ptr++) == newline) {
203           if (bp <= str->str_ptr || bp[-2] != '\\')
204           goto thats_all_folks;
205           else {
206           line++;
207           bp -= 2;
208           }
209           }
210           }
211          
212           FILE_cnt(fp) = cnt; /* deregisterize cnt and ptr */
213           FILE_ptr(fp) = ptr;
214           i = getc(fp); /* get more characters */
215           cnt = FILE_cnt(fp);
216           ptr = (STDCHAR*)FILE_ptr(fp); /* reregisterize cnt and ptr */
217            
218           bpx = bp - str->str_ptr; /* prepare for possible relocation */
219           GROWSTR(&(str->str_ptr), &(str->str_len), str->str_cur + cnt + 1);
220           bp = str->str_ptr + bpx; /* reconstitute our pointer */
221            
222           if (i == newline) { /* all done for now? */
223           *bp++ = i;
224           goto thats_all_folks;
225           }
226           else if (i == EOF) /* all done for ever? */
227           goto thats_all_folks;
228           *bp++ = i; /* now go back to screaming loop */
229           }
230            
231           thats_all_folks:
232           FILE_cnt(fp) = cnt; /* put these back or we're in trouble */
233           FILE_ptr(fp) = ptr;
234           *bp = '\0';
235           str->str_cur = bp - str->str_ptr; /* set length */
236            
237           #else /* USE_STDIO_PTR && STDIO_PTR_LVALUE && STDIO_CNT_LVALUE */
238           /* The big, slow, and stupid way */
239            
240           static char buf[4192];
241            
242 0         if (fgets(buf, sizeof buf, fp) != NULL)
243 0         str_set(str, buf);
244           else
245 0         str_set(str, No);
246            
247           #endif /* USE_STDIO_PTR && STDIO_PTR_LVALUE && STDIO_CNT_LVALUE */
248            
249 0         return str->str_cur ? str->str_ptr : NULL;
250           }
251            
252           STR *
253 0         str_make(const char *s)
254           {
255 0         STR *str = str_new(0);
256            
257 0         str_set(str,s);
258 0         return str;
259           }
260