1 /*
2 * routine.c
3 *
4 * general use routines
5 * Copyright (c) 1988-1993 Miguel Santana
6 * Copyright (c) 1995-1999 Akim Demaille, Miguel Santana
7 * $Id$
8 */
9
10 /*
11 * This file is part of a2ps.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; see the file COPYING. If not, write to
25 * the Free Software Foundation, 59 Temple Place - Suite 330,
26 * Boston, MA 02111-1307, USA.
27 */
28
29 #include "a2ps.h"
30 #include "routines.h"
31 #include "stpncpy.h"
32 #include "message.h"
33 #include "quotearg.h"
34
35
36 /*
37 * Convert a list of string of valid chars to an yes/no array
38 */
39 void
string_to_array(uchar arr[256],const uchar * string)40 string_to_array (uchar arr[256], const uchar * string)
41 {
42 int c;
43
44 for (c = 0 ; c < 256 ; c++)
45 arr [c] = false;
46 for ( /* nothing */ ; *string ; string ++)
47 arr [*string] = true;
48 }
49
50 /*
51 * Concatenation of a char. No malloc is done.
52 */
53 void
ustrccat(uchar * string,uchar c)54 ustrccat (uchar * string, uchar c)
55 {
56 int len = strlen((char *)string);
57 *(string+len) = c;
58 *(string+len+1) = '\0';
59 }
60
61 /*
62 * return true iff there are no upper case chars
63 */
64 int
is_strlower(const uchar * string)65 is_strlower (const uchar * string)
66 {
67 for (/* skip */; *string != '\0'; string++)
68 if (isupper(*string))
69 return false;
70 return true;
71 }
72
73 /* Copy the LEN first characters of SRC into DST in lower case.
74 DST[LEN] is set to \0. */
75
76 static inline uchar *
_strncpylc(uchar * dst,const uchar * src,size_t len)77 _strncpylc (uchar *dst, const uchar *src, size_t len)
78 {
79 size_t i;
80 for (i = 0 ; i < len ; i++)
81 dst[i] = tolower (src[i]);
82 dst[len] = '\0';
83 return dst;
84 }
85
86 uchar *
strnlower(uchar * string,size_t len)87 strnlower (uchar *string, size_t len)
88 {
89 return _strncpylc (string, string, len);
90 }
91
92 uchar *
strlower(uchar * string)93 strlower (uchar *string)
94 {
95 return _strncpylc (string, string, strlen (string));
96 }
97
98 uchar *
strcpylc(uchar * dst,const uchar * src)99 strcpylc (uchar *dst, const uchar *src)
100 {
101 return _strncpylc (dst, src, strlen (src));
102 }
103
104 /*
105 * Count the number of occurrence of C in S
106 */
107 int
strcnt(uchar * s,uchar c)108 strcnt (uchar *s, uchar c)
109 {
110 int res;
111 for (res = 0 ; *s ; s++)
112 if (*s == c)
113 res++;
114 return res;
115 }
116
117 /*
118 * Extract a substring for START, of LENGTH, making sure to
119 * set the trailing '\0' (return pos of \0)
120 */
121 char *
strsub(char * dest,const char * string,int start,int length)122 strsub (char * dest, const char * string, int start, int length)
123 {
124 char * end = stpncpy (dest, string + start, length);
125 *end = '\0';
126 return end;
127 }
128
129 /*
130 * fopen, but exits on failure
131 */
132 static inline FILE *
_xfopen(const char * filename,const char * rights,const char * format)133 _xfopen (const char * filename, const char * rights, const char * format)
134 {
135 FILE * res;
136
137 message (msg_file,
138 (stderr, "%s-fopen (%s)\n", rights, quotearg (filename)));
139 res = fopen (filename, rights);
140 if (!res)
141 error (1, errno, format, quotearg (filename));
142 return res;
143 }
144
145 FILE *
xfopen(const char * filename,const char * rights,const char * format)146 xfopen (const char * filename, const char * rights, const char * format)
147 {
148 return _xfopen (filename, rights, format);
149 }
150
151 FILE *
xrfopen(const char * filename)152 xrfopen (const char * filename)
153 {
154 return _xfopen (filename, "r", _("cannot open file `%s'"));
155 }
156
157 FILE *
xwfopen(const char * filename)158 xwfopen (const char * filename)
159 {
160 return _xfopen (filename, "w", _("cannot create file `%s'"));
161 }
162
163
164
165 /*
166 * Like popen, but exist upon failure
167 */
168 static inline FILE *
_xpopen(const char * filename,const char * rights,const char * format)169 _xpopen (const char * filename, const char * rights, const char * format)
170 {
171 FILE * res;
172
173 message (msg_file,
174 (stderr, "%s-popen (%s)\n", rights, filename));
175 res = popen (filename, rights);
176 if (!res)
177 error (1, errno, format, quotearg (filename));
178 return res;
179 }
180
181 FILE *
xpopen(const char * filename,const char * rights,const char * format)182 xpopen (const char * filename, const char * rights, const char * format)
183 {
184 return _xpopen (filename, rights, format);
185 }
186
187 FILE *
xrpopen(const char * filename)188 xrpopen (const char * filename)
189 {
190 return _xpopen (filename, "r", _("cannot open a pipe on `%s'"));
191 }
192
193 FILE *
xwpopen(const char * filename)194 xwpopen (const char * filename)
195 {
196 return _xpopen (filename, "w", _("cannot open a pipe on `%s'"));
197 }
198
199 /*
200 * Copy the content of IN into OUT
201 */
202 static inline void
_streams_copy(FILE * in,FILE * out)203 _streams_copy (FILE * in, FILE * out)
204 {
205 size_t read_length;
206 char buf [BUFSIZ];
207
208 while ((read_length = fread (buf, sizeof (char), sizeof (buf), in)))
209 fwrite (buf, sizeof (char), read_length, out);
210 }
211
212 void
streams_copy(FILE * in,FILE * out)213 streams_copy (FILE * in, FILE * out)
214 {
215 _streams_copy (in, out);
216 }
217
218 /*
219 * Dump the content of the file FILENAME onto STREAM.
220 * Used when honoring a subcontract.
221 */
222 void
stream_dump(FILE * stream,const char * filename)223 stream_dump (FILE * stream, const char * filename)
224 {
225 FILE * fp;
226
227 message (msg_tool | msg_file, (stderr, "Dumping file `%s'\n", filename));
228
229 fp = xrfopen (filename);
230 _streams_copy (fp, stream);
231 fclose (fp);
232 }
233
234 /*
235 * Unlink the file FILENAME.
236 */
237 void
unlink2(PARAM_UNUSED void * dummy,const char * filename)238 unlink2 (PARAM_UNUSED void * dummy, const char * filename)
239 {
240 message (msg_tool | msg_file, (stderr, "Unlinking file `%s'\n", filename));
241
242 /* Don't complain if you can't unlink. Who cares of a tmp file? */
243 unlink (filename);
244 }
245