dvitomp fix from Akira
[mplib] / src / texk / kpathsea / fn.c
1 /* fn.c: arbitrarily long filenames or strings.
2
3    Copyright 1993, 2008 Karl Berry.
4    Copyright 2001, 2005 Olaf Weber.
5
6    This library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    This library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public License
17    along with this library; if not, see <http://www.gnu.org/licenses/>.  */
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) = (string)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 \f
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 \f
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,  const_string, 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 }