1268
|
1 /* fn.c: arbitrarily long filenames (or just strings). |
|
2 |
|
3 Copyright (C) 1993 Karl Berry. |
|
4 |
|
5 This program is free software; you can redistribute it and/or modify |
|
6 it under the terms of the GNU General Public License as published by |
|
7 the Free Software Foundation; either version 2, or (at your option) |
|
8 any later version. |
|
9 |
|
10 This program is distributed in the hope that it will be useful, |
|
11 but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
13 GNU General Public License for more details. |
|
14 |
|
15 You should have received a copy of the GNU General Public License |
|
16 along with this program; if not, write to the Free Software |
1315
|
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
1268
|
18 |
|
19 #include <kpathsea/config.h> |
|
20 |
|
21 #include <kpathsea/fn.h> |
|
22 |
|
23 |
|
24 /* /usr/local/lib/texmf/fonts/public/cm/pk/ljfour/cmr10.300pk is 58 |
|
25 chars, so ASCII `K' seems a good choice. */ |
|
26 #define CHUNK_SIZE 75 |
|
27 |
|
28 |
|
29 fn_type |
|
30 fn_init P1H(void) |
|
31 { |
|
32 fn_type ret; |
|
33 |
|
34 FN_ALLOCATED (ret) = FN_LENGTH (ret) = 0; |
|
35 FN_STRING (ret) = NULL; |
|
36 |
|
37 return ret; |
|
38 } |
|
39 |
|
40 |
|
41 fn_type |
|
42 fn_copy0 P2C(const_string, s, unsigned, len) |
|
43 { |
|
44 fn_type ret; |
|
45 |
|
46 FN_ALLOCATED (ret) = CHUNK_SIZE > len ? CHUNK_SIZE : len + 1; |
|
47 FN_STRING (ret) = xmalloc (FN_ALLOCATED (ret)); |
|
48 |
|
49 strncpy (FN_STRING (ret), s, len); |
|
50 FN_STRING (ret)[len] = 0; |
|
51 FN_LENGTH (ret) = len + 1; |
|
52 |
|
53 return ret; |
|
54 } |
|
55 |
|
56 /* Don't think we ever try to free something that might usefully be |
|
57 empty, so give fatal error if nothing allocated. */ |
|
58 |
|
59 void |
|
60 fn_free P1C(fn_type *, f) |
|
61 { |
|
62 assert (FN_STRING (*f) != NULL); |
|
63 free (FN_STRING (*f)); |
|
64 FN_STRING (*f) = NULL; |
|
65 FN_ALLOCATED (*f) = 0; |
|
66 FN_LENGTH (*f) = 0; |
|
67 } |
|
68 |
|
69 /* An arithmetic increase seems more reasonable than geometric. We |
|
70 don't increase the length member since it may be more convenient for |
|
71 the caller to add than subtract when appending the stuff that will |
|
72 presumably follow. */ |
|
73 |
|
74 static void |
|
75 grow P2C(fn_type *, f, unsigned, len) |
|
76 { |
|
77 while (FN_LENGTH (*f) + len > FN_ALLOCATED (*f)) |
|
78 { |
|
79 FN_ALLOCATED (*f) += CHUNK_SIZE; |
|
80 XRETALLOC (FN_STRING (*f), FN_ALLOCATED (*f), char); |
|
81 } |
|
82 } |
|
83 |
|
84 |
|
85 void |
|
86 fn_1grow P2C(fn_type *, f, char, c) |
|
87 { |
|
88 grow (f, 1); |
|
89 FN_STRING (*f)[FN_LENGTH (*f)] = c; |
|
90 FN_LENGTH (*f)++; |
|
91 } |
|
92 |
|
93 |
|
94 void |
|
95 fn_grow P3C(fn_type *, f, address, source, unsigned, len) |
|
96 { |
|
97 grow (f, len); |
|
98 strncpy (FN_STRING (*f) + FN_LENGTH (*f), source, len); |
|
99 FN_LENGTH (*f) += len; |
|
100 } |
|
101 |
|
102 |
|
103 void |
|
104 fn_str_grow P2C(fn_type *, f, const_string, s) |
|
105 { |
|
106 unsigned more_len = strlen (s); |
|
107 grow (f, more_len); |
|
108 strcat (FN_STRING (*f), s); |
|
109 FN_LENGTH (*f) += more_len; |
|
110 } |
|
111 |
|
112 |
|
113 void |
|
114 fn_shrink_to P2C(fn_type *, f, unsigned, loc) |
|
115 { |
|
116 assert (FN_LENGTH (*f) > loc); |
|
117 FN_STRING (*f)[loc] = 0; |
|
118 FN_LENGTH (*f) = loc + 1; |
|
119 } |