Line | Count | Source |
1 | | /* $Id: Str.c,v 1.8 2002/12/24 17:20:46 ukai Exp $ */ |
2 | | /* |
3 | | * String manipulation library for Boehm GC |
4 | | * |
5 | | * (C) Copyright 1998-1999 by Akinori Ito |
6 | | * |
7 | | * This software may be redistributed freely for this purpose, in full |
8 | | * or in part, provided that this entire copyright notice is included |
9 | | * on any copies of this software and applications and derivations thereof. |
10 | | * |
11 | | * This software is provided on an "as is" basis, without warranty of any |
12 | | * kind, either expressed or implied, as to any matter including, but not |
13 | | * limited to warranty of fitness of purpose, or merchantability, or |
14 | | * results obtained from use of this software. |
15 | | */ |
16 | | #include <stdio.h> |
17 | | #include <stdlib.h> |
18 | | #include <gc.h> |
19 | | #include <stdarg.h> |
20 | | #include <string.h> |
21 | | #ifdef __EMX__ /* or include "fm.h" for HAVE_BCOPY? */ |
22 | | #include <strings.h> |
23 | | #endif |
24 | | #include "Str.h" |
25 | | #include "myctype.h" |
26 | | |
27 | 62.0k | #define INITIAL_STR_SIZE 32 |
28 | | |
29 | | #ifdef STR_DEBUG |
30 | | /* This is obsolete, because "Str" can handle a '\0' character now. */ |
31 | | #define STR_LENGTH_CHECK(x) if (((x)->ptr==0&&(x)->length!=0)||(strlen((x)->ptr)!=(x)->length))abort(); |
32 | | #else /* not STR_DEBUG */ |
33 | | #define STR_LENGTH_CHECK(x) |
34 | | #endif /* not STR_DEBUG */ |
35 | | |
36 | | Str |
37 | | Strnew() |
38 | 0 | { |
39 | 0 | Str x = GC_MALLOC(sizeof(struct _Str)); |
40 | 0 | if (x == NULL) |
41 | 0 | exit(1); |
42 | 0 | x->ptr = GC_MALLOC_ATOMIC(INITIAL_STR_SIZE); |
43 | 0 | if (x->ptr == NULL) |
44 | 0 | exit(1); |
45 | 0 | x->ptr[0] = '\0'; |
46 | 0 | x->area_size = INITIAL_STR_SIZE; |
47 | 0 | x->length = 0; |
48 | 0 | return x; |
49 | 0 | } |
50 | | |
51 | | Str |
52 | | Strnew_size(int n) |
53 | 23.5k | { |
54 | 23.5k | Str x = GC_MALLOC(sizeof(struct _Str)); |
55 | 23.5k | if (x == NULL) |
56 | 0 | exit(1); |
57 | 23.5k | if (n < 0 || n >= STR_SIZE_MAX) |
58 | 0 | n = STR_SIZE_MAX - 1; |
59 | 23.5k | else if (n + 1 < INITIAL_STR_SIZE) |
60 | 15.2k | n = INITIAL_STR_SIZE - 1; |
61 | 23.5k | x->ptr = GC_MALLOC_ATOMIC(n + 1); |
62 | 23.5k | if (x->ptr == NULL) |
63 | 0 | exit(1); |
64 | 23.5k | x->ptr[0] = '\0'; |
65 | 23.5k | x->area_size = n + 1; |
66 | 23.5k | x->length = 0; |
67 | 23.5k | return x; |
68 | 23.5k | } |
69 | | |
70 | | Str |
71 | | Strnew_charp(const char *p) |
72 | 0 | { |
73 | 0 | Str x; |
74 | 0 | int n, len; |
75 | |
|
76 | 0 | if (p == NULL) |
77 | 0 | return Strnew(); |
78 | 0 | x = GC_MALLOC(sizeof(struct _Str)); |
79 | 0 | if (x == NULL) |
80 | 0 | exit(1); |
81 | 0 | n = strlen(p) + 1; |
82 | 0 | if (n <= 0 || n > STR_SIZE_MAX) |
83 | 0 | n = STR_SIZE_MAX; |
84 | 0 | len = n - 1; |
85 | 0 | if (n < INITIAL_STR_SIZE) |
86 | 0 | n = INITIAL_STR_SIZE; |
87 | 0 | x->ptr = GC_MALLOC_ATOMIC(n); |
88 | 0 | if (x->ptr == NULL) |
89 | 0 | exit(1); |
90 | 0 | x->area_size = n; |
91 | 0 | x->length = len; |
92 | 0 | bcopy((void *)p, (void *)x->ptr, len); |
93 | 0 | x->ptr[x->length] = '\0'; |
94 | 0 | return x; |
95 | 0 | } |
96 | | |
97 | | Str |
98 | | Strnew_m_charp(const char *p, ...) |
99 | 0 | { |
100 | 0 | va_list ap; |
101 | 0 | Str r = Strnew(); |
102 | |
|
103 | 0 | va_start(ap, p); |
104 | 0 | while (p != NULL) { |
105 | 0 | Strcat_charp(r, p); |
106 | 0 | p = va_arg(ap, char *); |
107 | 0 | } |
108 | 0 | va_end(ap); |
109 | 0 | return r; |
110 | 0 | } |
111 | | |
112 | | Str |
113 | | Strnew_charp_n(const char *p, int n) |
114 | 12.0k | { |
115 | 12.0k | Str x; |
116 | 12.0k | int len; |
117 | | |
118 | 12.0k | if (p == NULL) |
119 | 0 | return Strnew_size(n); |
120 | 12.0k | x = GC_MALLOC(sizeof(struct _Str)); |
121 | 12.0k | if (x == NULL) |
122 | 0 | exit(1); |
123 | 12.0k | if (n < 0 || n >= STR_SIZE_MAX) |
124 | 0 | n = STR_SIZE_MAX - 1; |
125 | 12.0k | len = n; |
126 | 12.0k | if (n + 1 < INITIAL_STR_SIZE) |
127 | 8.09k | n = INITIAL_STR_SIZE - 1; |
128 | 12.0k | x->ptr = GC_MALLOC_ATOMIC(n + 1); |
129 | 12.0k | if (x->ptr == NULL) |
130 | 0 | exit(1); |
131 | 12.0k | x->area_size = n + 1; |
132 | 12.0k | x->length = len; |
133 | 12.0k | bcopy((void *)p, (void *)x->ptr, len); |
134 | 12.0k | x->ptr[x->length] = '\0'; |
135 | 12.0k | return x; |
136 | 12.0k | } |
137 | | |
138 | | Str |
139 | | Strdup(Str s) |
140 | 0 | { |
141 | 0 | Str n = Strnew_size(s->length); |
142 | 0 | STR_LENGTH_CHECK(s); |
143 | 0 | Strcopy(n, s); |
144 | 0 | return n; |
145 | 0 | } |
146 | | |
147 | | void |
148 | | Strclear(Str s) |
149 | 260 | { |
150 | 260 | s->length = 0; |
151 | 260 | s->ptr[0] = '\0'; |
152 | 260 | } |
153 | | |
154 | | void |
155 | | Strfree(Str x) |
156 | 12.4k | { |
157 | 12.4k | GC_free(x->ptr); |
158 | 12.4k | GC_free(x); |
159 | 12.4k | } |
160 | | |
161 | | void |
162 | | Strcopy(Str x, Str y) |
163 | 0 | { |
164 | 0 | STR_LENGTH_CHECK(x); |
165 | 0 | STR_LENGTH_CHECK(y); |
166 | 0 | if (x->area_size < y->length + 1) { |
167 | 0 | x->ptr = GC_REALLOC(x->ptr, y->length + 1); |
168 | 0 | if (x->ptr == NULL) |
169 | 0 | exit(1); |
170 | 0 | x->area_size = y->length + 1; |
171 | 0 | } |
172 | 0 | bcopy((void *)y->ptr, (void *)x->ptr, y->length + 1); |
173 | 0 | x->length = y->length; |
174 | 0 | } |
175 | | |
176 | | void |
177 | | Strcopy_charp(Str x, const char *y) |
178 | 0 | { |
179 | 0 | int len; |
180 | |
|
181 | 0 | STR_LENGTH_CHECK(x); |
182 | 0 | if (y == NULL) { |
183 | 0 | x->length = 0; |
184 | 0 | x->ptr[0] = '\0'; |
185 | 0 | return; |
186 | 0 | } |
187 | 0 | len = strlen(y); |
188 | 0 | if (len < 0 || len >= STR_SIZE_MAX) |
189 | 0 | len = STR_SIZE_MAX - 1; |
190 | 0 | if (x->area_size < len + 1) { |
191 | 0 | x->ptr = GC_REALLOC(x->ptr, len + 1); |
192 | 0 | if (x->ptr == NULL) |
193 | 0 | exit(1); |
194 | 0 | x->area_size = len + 1; |
195 | 0 | } |
196 | 0 | bcopy((void *)y, (void *)x->ptr, len); |
197 | 0 | x->ptr[len] = '\0'; |
198 | 0 | x->length = len; |
199 | 0 | } |
200 | | |
201 | | void |
202 | | Strcopy_charp_n(Str x, const char *y, int n) |
203 | 0 | { |
204 | 0 | int len = n; |
205 | |
|
206 | 0 | STR_LENGTH_CHECK(x); |
207 | 0 | if (y == NULL) { |
208 | 0 | x->length = 0; |
209 | 0 | x->ptr[0] = '\0'; |
210 | 0 | return; |
211 | 0 | } |
212 | 0 | if (len < 0 || len >= STR_SIZE_MAX) |
213 | 0 | len = STR_SIZE_MAX - 1; |
214 | 0 | if (x->area_size < len + 1) { |
215 | 0 | x->ptr = GC_REALLOC(x->ptr, len + 1); |
216 | 0 | if (x->ptr == NULL) |
217 | 0 | exit(1); |
218 | 0 | x->area_size = len + 1; |
219 | 0 | } |
220 | 0 | bcopy((void *)y, (void *)x->ptr, len); |
221 | 0 | x->ptr[len] = '\0'; |
222 | 0 | x->length = len; |
223 | 0 | } |
224 | | |
225 | | void |
226 | | Strcat_charp_n(Str x, const char *y, int n) |
227 | 237M | { |
228 | 237M | int newlen; |
229 | | |
230 | 237M | STR_LENGTH_CHECK(x); |
231 | 237M | if (y == NULL || n == 0) |
232 | 706 | return; |
233 | 237M | if (n < 0) |
234 | 0 | n = STR_SIZE_MAX - 1; |
235 | 237M | newlen = x->length + n + 1; |
236 | 237M | if (newlen <= 0 || newlen > STR_SIZE_MAX) { |
237 | 0 | newlen = STR_SIZE_MAX; |
238 | 0 | n = newlen - x->length - 1; |
239 | 0 | if (n <= 0) |
240 | 0 | return; |
241 | 0 | } |
242 | 237M | if (x->area_size < newlen) { |
243 | 10.5k | newlen += newlen / 2; |
244 | 10.5k | if (newlen <= 0 || newlen > STR_SIZE_MAX) |
245 | 0 | newlen = STR_SIZE_MAX; |
246 | 10.5k | x->ptr = GC_REALLOC(x->ptr, newlen); |
247 | 10.5k | if (x->ptr == NULL) |
248 | 0 | exit(1); |
249 | 10.5k | x->area_size = newlen; |
250 | 10.5k | } |
251 | 237M | bcopy((void *)y, (void *)&x->ptr[x->length], n); |
252 | 237M | x->length += n; |
253 | 237M | x->ptr[x->length] = '\0'; |
254 | 237M | } |
255 | | |
256 | | void |
257 | | Strcat(Str x, Str y) |
258 | 0 | { |
259 | 0 | STR_LENGTH_CHECK(y); |
260 | 0 | Strcat_charp_n(x, y->ptr, y->length); |
261 | 0 | } |
262 | | |
263 | | void |
264 | | Strcat_charp(Str x, const char *y) |
265 | 82.2M | { |
266 | 82.2M | if (y == NULL) |
267 | 0 | return; |
268 | 82.2M | Strcat_charp_n(x, y, strlen(y)); |
269 | 82.2M | } |
270 | | |
271 | | void |
272 | | Strcat_m_charp(Str x, ...) |
273 | 0 | { |
274 | 0 | va_list ap; |
275 | 0 | char *p; |
276 | |
|
277 | 0 | va_start(ap, x); |
278 | 0 | while ((p = va_arg(ap, char *)) != NULL) |
279 | 0 | Strcat_charp_n(x, p, strlen(p)); |
280 | 0 | va_end(ap); |
281 | 0 | } |
282 | | |
283 | | void |
284 | | Strgrow(Str x) |
285 | 3.16k | { |
286 | 3.16k | int newlen, addlen; |
287 | | |
288 | 3.16k | if (x->area_size < 8192) |
289 | 1.55k | addlen = x->area_size; |
290 | 1.60k | else |
291 | 1.60k | addlen = x->area_size / 2; |
292 | 3.16k | if (addlen < INITIAL_STR_SIZE) |
293 | 0 | addlen = INITIAL_STR_SIZE; |
294 | 3.16k | newlen = x->area_size + addlen; |
295 | 3.16k | if (newlen <= 0 || newlen > STR_SIZE_MAX) { |
296 | 21 | newlen = STR_SIZE_MAX; |
297 | 21 | if (x->length + 1 >= newlen) |
298 | 0 | x->length = newlen - 2; |
299 | 21 | } |
300 | 3.16k | if (x->area_size < newlen) { |
301 | 3.16k | x->ptr = GC_REALLOC(x->ptr, newlen); |
302 | 3.16k | if (x->ptr == NULL) |
303 | 0 | exit(1); |
304 | 3.16k | x->area_size = newlen; |
305 | 3.16k | } |
306 | 3.16k | x->ptr[x->length] = '\0'; |
307 | 3.16k | } |
308 | | |
309 | | Str |
310 | | Strsubstr(Str s, int beg, int len) |
311 | 0 | { |
312 | 0 | Str new_s; |
313 | 0 | int i; |
314 | |
|
315 | 0 | STR_LENGTH_CHECK(s); |
316 | 0 | new_s = Strnew(); |
317 | 0 | if (beg >= s->length) |
318 | 0 | return new_s; |
319 | 0 | for (i = 0; i < len && beg + i < s->length; i++) |
320 | 0 | Strcat_char(new_s, s->ptr[beg + i]); |
321 | 0 | return new_s; |
322 | 0 | } |
323 | | |
324 | | void |
325 | | Strlower(Str s) |
326 | 0 | { |
327 | 0 | int i; |
328 | 0 | STR_LENGTH_CHECK(s); |
329 | 0 | for (i = 0; i < s->length; i++) |
330 | 0 | s->ptr[i] = TOLOWER(s->ptr[i]); |
331 | 0 | } |
332 | | |
333 | | void |
334 | | Strupper(Str s) |
335 | 0 | { |
336 | 0 | int i; |
337 | 0 | STR_LENGTH_CHECK(s); |
338 | 0 | for (i = 0; i < s->length; i++) |
339 | 0 | s->ptr[i] = TOUPPER(s->ptr[i]); |
340 | 0 | } |
341 | | |
342 | | void |
343 | | Strchop(Str s) |
344 | 0 | { |
345 | 0 | STR_LENGTH_CHECK(s); |
346 | 0 | while (s->length > 0 && |
347 | 0 | (s->ptr[s->length - 1] == '\n' || s->ptr[s->length - 1] == '\r')) { |
348 | 0 | s->length--; |
349 | 0 | } |
350 | 0 | s->ptr[s->length] = '\0'; |
351 | 0 | } |
352 | | |
353 | | void |
354 | | Strinsert_char(Str s, int pos, char c) |
355 | 0 | { |
356 | 0 | int i; |
357 | 0 | STR_LENGTH_CHECK(s); |
358 | 0 | if (pos < 0 || s->length < pos) |
359 | 0 | return; |
360 | 0 | if (s->length + 2 > s->area_size) |
361 | 0 | Strgrow(s); |
362 | 0 | if (s->length < pos) |
363 | 0 | return; |
364 | 0 | for (i = s->length; i > pos; i--) |
365 | 0 | s->ptr[i] = s->ptr[i - 1]; |
366 | 0 | s->ptr[++s->length] = '\0'; |
367 | 0 | s->ptr[pos] = c; |
368 | 0 | } |
369 | | |
370 | | void |
371 | | Strinsert_charp(Str s, int pos, const char *p) |
372 | 0 | { |
373 | 0 | STR_LENGTH_CHECK(s); |
374 | 0 | while (*p) |
375 | 0 | Strinsert_char(s, pos++, *(p++)); |
376 | 0 | } |
377 | | |
378 | | void |
379 | | Strdelete(Str s, int pos, int n) |
380 | 0 | { |
381 | 0 | int i; |
382 | 0 | STR_LENGTH_CHECK(s); |
383 | 0 | if (pos < 0 || s->length < pos) |
384 | 0 | return; |
385 | 0 | if (n < 0) |
386 | 0 | n = STR_SIZE_MAX - pos - 1; |
387 | 0 | if (s->length <= pos + n) { |
388 | 0 | s->ptr[pos] = '\0'; |
389 | 0 | s->length = pos; |
390 | 0 | return; |
391 | 0 | } |
392 | 0 | for (i = pos; i < s->length - n; i++) |
393 | 0 | s->ptr[i] = s->ptr[i + n]; |
394 | 0 | s->ptr[i] = '\0'; |
395 | 0 | s->length = i; |
396 | 0 | } |
397 | | |
398 | | void |
399 | | Strtruncate(Str s, int pos) |
400 | 0 | { |
401 | 0 | STR_LENGTH_CHECK(s); |
402 | 0 | if (pos < 0 || s->length < pos) |
403 | 0 | return; |
404 | 0 | s->ptr[pos] = '\0'; |
405 | 0 | s->length = pos; |
406 | 0 | } |
407 | | |
408 | | void |
409 | | Strshrink(Str s, int n) |
410 | 0 | { |
411 | 0 | STR_LENGTH_CHECK(s); |
412 | 0 | if (n >= s->length) { |
413 | 0 | s->length = 0; |
414 | 0 | s->ptr[0] = '\0'; |
415 | 0 | } |
416 | 0 | else if (n > 0) { |
417 | 0 | s->length -= n; |
418 | 0 | s->ptr[s->length] = '\0'; |
419 | 0 | } |
420 | 0 | } |
421 | | |
422 | | void |
423 | | Strremovefirstspaces(Str s) |
424 | 0 | { |
425 | 0 | int i; |
426 | |
|
427 | 0 | STR_LENGTH_CHECK(s); |
428 | 0 | for (i = 0; i < s->length && IS_SPACE(s->ptr[i]); i++) ; |
429 | 0 | if (i == 0) |
430 | 0 | return; |
431 | 0 | Strdelete(s, 0, i); |
432 | 0 | } |
433 | | |
434 | | void |
435 | | Strremovetrailingspaces(Str s) |
436 | 0 | { |
437 | 0 | int i; |
438 | |
|
439 | 0 | STR_LENGTH_CHECK(s); |
440 | 0 | for (i = s->length - 1; i >= 0 && IS_SPACE(s->ptr[i]); i--) ; |
441 | 0 | s->length = i + 1; |
442 | 0 | s->ptr[i + 1] = '\0'; |
443 | 0 | } |
444 | | |
445 | | Str |
446 | | Stralign_left(Str s, int width) |
447 | 0 | { |
448 | 0 | Str n; |
449 | 0 | int i; |
450 | |
|
451 | 0 | STR_LENGTH_CHECK(s); |
452 | 0 | if (s->length >= width) |
453 | 0 | return Strdup(s); |
454 | 0 | n = Strnew_size(width); |
455 | 0 | Strcopy(n, s); |
456 | 0 | for (i = s->length; i < width; i++) |
457 | 0 | Strcat_char(n, ' '); |
458 | 0 | return n; |
459 | 0 | } |
460 | | |
461 | | Str |
462 | | Stralign_right(Str s, int width) |
463 | 0 | { |
464 | 0 | Str n; |
465 | 0 | int i; |
466 | |
|
467 | 0 | STR_LENGTH_CHECK(s); |
468 | 0 | if (s->length >= width) |
469 | 0 | return Strdup(s); |
470 | 0 | n = Strnew_size(width); |
471 | 0 | for (i = s->length; i < width; i++) |
472 | 0 | Strcat_char(n, ' '); |
473 | 0 | Strcat(n, s); |
474 | 0 | return n; |
475 | 0 | } |
476 | | |
477 | | Str |
478 | | Stralign_center(Str s, int width) |
479 | 0 | { |
480 | 0 | Str n; |
481 | 0 | int i, w; |
482 | |
|
483 | 0 | STR_LENGTH_CHECK(s); |
484 | 0 | if (s->length >= width) |
485 | 0 | return Strdup(s); |
486 | 0 | n = Strnew_size(width); |
487 | 0 | w = (width - s->length) / 2; |
488 | 0 | for (i = 0; i < w; i++) |
489 | 0 | Strcat_char(n, ' '); |
490 | 0 | Strcat(n, s); |
491 | 0 | for (i = w + s->length; i < width; i++) |
492 | 0 | Strcat_char(n, ' '); |
493 | 0 | return n; |
494 | 0 | } |
495 | | |
496 | 0 | #define SP_NORMAL 0 |
497 | 0 | #define SP_PREC 1 |
498 | 0 | #define SP_PREC2 2 |
499 | | |
500 | | Str |
501 | | Sprintf(char *fmt, ...) |
502 | 0 | { |
503 | 0 | int len = 0; |
504 | 0 | int status = SP_NORMAL; |
505 | 0 | int p = 0; |
506 | 0 | char *f; |
507 | 0 | Str s; |
508 | 0 | va_list ap; |
509 | |
|
510 | 0 | va_start(ap, fmt); |
511 | 0 | for (f = fmt; *f; f++) { |
512 | 0 | redo: |
513 | 0 | switch (status) { |
514 | 0 | case SP_NORMAL: |
515 | 0 | if (*f == '%') { |
516 | 0 | status = SP_PREC; |
517 | 0 | p = 0; |
518 | 0 | } |
519 | 0 | else |
520 | 0 | len++; |
521 | 0 | break; |
522 | 0 | case SP_PREC: |
523 | 0 | if (IS_ALPHA(*f)) { |
524 | | /* conversion char. */ |
525 | 0 | int vi; |
526 | 0 | char *vs; |
527 | |
|
528 | 0 | switch (*f) { |
529 | 0 | case 'l': |
530 | 0 | case 'h': |
531 | 0 | case 'L': |
532 | 0 | case 'w': |
533 | 0 | continue; |
534 | 0 | case 'd': |
535 | 0 | case 'i': |
536 | 0 | case 'o': |
537 | 0 | case 'x': |
538 | 0 | case 'X': |
539 | 0 | case 'u': |
540 | 0 | vi = va_arg(ap, int); |
541 | 0 | len += (p > 0) ? p : 10; |
542 | 0 | break; |
543 | 0 | case 'f': |
544 | 0 | case 'g': |
545 | 0 | case 'e': |
546 | 0 | case 'G': |
547 | 0 | case 'E': |
548 | 0 | va_arg(ap, double); |
549 | 0 | len += (p > 0) ? p : 15; |
550 | 0 | break; |
551 | 0 | case 'c': |
552 | 0 | len += 1; |
553 | 0 | vi = va_arg(ap, int); |
554 | 0 | break; |
555 | 0 | case 's': |
556 | 0 | vs = va_arg(ap, char *); |
557 | 0 | vi = strlen(vs); |
558 | 0 | len += (p > vi) ? p : vi; |
559 | 0 | break; |
560 | 0 | case 'p': |
561 | 0 | va_arg(ap, void *); |
562 | 0 | len += 10; |
563 | 0 | break; |
564 | 0 | case 'n': |
565 | 0 | va_arg(ap, void *); |
566 | 0 | break; |
567 | 0 | } |
568 | 0 | status = SP_NORMAL; |
569 | 0 | } |
570 | 0 | else if (IS_DIGIT(*f)) |
571 | 0 | p = p * 10 + *f - '0'; |
572 | 0 | else if (*f == '.') |
573 | 0 | status = SP_PREC2; |
574 | 0 | else if (*f == '%') { |
575 | 0 | status = SP_NORMAL; |
576 | 0 | len++; |
577 | 0 | } |
578 | 0 | break; |
579 | 0 | case SP_PREC2: |
580 | 0 | if (IS_ALPHA(*f)) { |
581 | 0 | status = SP_PREC; |
582 | 0 | goto redo; |
583 | 0 | } |
584 | 0 | break; |
585 | 0 | } |
586 | 0 | } |
587 | 0 | va_end(ap); |
588 | 0 | s = Strnew_size(len * 2); |
589 | 0 | va_start(ap, fmt); |
590 | 0 | vsprintf(s->ptr, fmt, ap); |
591 | 0 | va_end(ap); |
592 | 0 | s->length = strlen(s->ptr); |
593 | 0 | if (s->length > len * 2) { |
594 | 0 | fprintf(stderr, "Sprintf: string too long\n"); |
595 | 0 | exit(1); |
596 | 0 | } |
597 | 0 | return s; |
598 | 0 | } |
599 | | |
600 | | Str |
601 | | Strfgets(FILE * f) |
602 | 0 | { |
603 | 0 | Str s = Strnew(); |
604 | 0 | int c; |
605 | 0 | while ((c = fgetc(f)) != EOF) { |
606 | 0 | Strcat_char(s, c); |
607 | 0 | if (c == '\n') |
608 | 0 | break; |
609 | 0 | } |
610 | 0 | return s; |
611 | 0 | } |
612 | | |
613 | | Str |
614 | | Strfgetall(FILE * f) |
615 | 0 | { |
616 | 0 | Str s = Strnew(); |
617 | 0 | int c; |
618 | 0 | while ((c = fgetc(f)) != EOF) { |
619 | | Strcat_char(s, c); |
620 | 0 | } |
621 | 0 | return s; |
622 | 0 | } |