ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Convert-UUlib/uulib/fptools.c
Revision: 1.21
Committed: Sat Sep 24 06:22:47 2022 UTC (19 months, 3 weeks ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.20: +0 -6 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 /*
2 * fptools.c, some helper functions for getcgi.c and uu(en|de)view
3 *
4 * Distributed under the terms of the GNU General Public License.
5 * Use and be happy.
6 */
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11
12 #ifdef SYSTEM_WINDLL
13 #include <windows.h>
14 #endif
15 #ifdef SYSTEM_OS2
16 #include <os2.h>
17 #endif
18
19 /*
20 * This file provides replacements for some handy functions that aren't
21 * available on all systems, like most of the <string.h> functions. They
22 * should behave exactly as their counterparts. There are also extensions
23 * that aren't portable at all (like strirstr etc.).
24 * The proper behaviour in a configure script is as follows:
25 * AC_CHECK_FUNC(strrchr,AC_DEFINE(strrchr,FP_strrchr))
26 * This way, the (probably less efficient) replacements will only be used
27 * where it is not provided by the default libraries. Be aware that this
28 * does not work with replacements that just shadow wrong behaviour (like
29 * FP_free) or provide extended functionality (FP_gets).
30 * The above is not used in the uuenview/uudeview configuration script,
31 * since both only use the replacement functions in non-performance-cri-
32 * tical sections (except for FP_tempnam and FP_strerror, where some
33 * functionality of the original would be lost).
34 */
35
36 #include <stdio.h>
37 #include <ctype.h>
38 #include <stdlib.h>
39 #include <string.h>
40
41 #ifdef HAVE_UNISTD_H
42 #include <unistd.h>
43 #endif
44
45 #include <fptools.h>
46
47 #if 0
48 #ifdef SYSTEM_WINDLL
49 BOOL _export WINAPI
50 DllEntryPoint (HINSTANCE hInstance, DWORD seginfo,
51 LPVOID lpCmdLine)
52 {
53 /* Don't do anything, so just return true */
54 return TRUE;
55 }
56 #endif
57 #endif
58
59 /*
60 * some versions of free can't handle a NULL pointer properly
61 * (ANSI says, free ignores a NULL pointer, but some machines
62 * prefer to SIGSEGV on it)
63 */
64
65 void TOOLEXPORT
66 FP_free (void *ptr)
67 {
68 if (ptr) free (ptr);
69 }
70
71 /*
72 * This is non-standard, so I'm defining my own
73 */
74
75 char * TOOLEXPORT
76 FP_strdup (char *string)
77 {
78 char *result;
79
80 if (string == NULL)
81 return NULL;
82
83 if ((result = (char *) malloc (strlen (string) + 1)) == NULL)
84 return NULL;
85
86 strcpy (result, string);
87 return result;
88 }
89
90 /*
91 * limited-length string copy. this function behaves differently from
92 * the original in that the dest string is always terminated with a
93 * NULL character.
94 */
95
96 char * TOOLEXPORT
97 FP_strncpy (char *dest, char *src, int length)
98 {
99 char *odest=dest;
100 if (src == NULL || dest == NULL || length-- <= 0)
101 return dest;
102
103 while (length-- && *src)
104 *dest++ = *src++;
105
106 *dest++ = '\0';
107 return odest;
108 }
109
110 /*
111 * duplicate a memory area
112 */
113
114 void * TOOLEXPORT
115 FP_memdup (const void *ptr, int len)
116 {
117 void *result;
118
119 if (ptr == NULL)
120 return NULL;
121
122 if ((result = malloc (len)) == NULL)
123 return NULL;
124
125 memcpy (result, ptr, len);
126 return result;
127 }
128
129 /*
130 * case-insensitive compare
131 */
132
133 #ifndef FP_stricmp
134 int TOOLEXPORT
135 FP_stricmp (const char *str1, const char *str2)
136 {
137 if (str1==NULL || str2==NULL)
138 return -1;
139
140 while (*str1) {
141 if (tolower(*str1) != tolower(*str2))
142 break;
143 str1++;
144 str2++;
145 }
146 return (tolower (*str1) - tolower (*str2));
147 }
148 #endif
149
150 #ifndef FP_strnicmp
151 int TOOLEXPORT
152 FP_strnicmp (const char *str1, const char *str2, int count)
153 {
154 int d;
155
156 if (!str1 || !str2)
157 return -1;
158
159 while (count--) {
160 if (!*str1)
161 return -1;
162
163 d = tolower (*str1) - tolower (*str2);
164 if (d)
165 return d;
166
167 str1++;
168 str2++;
169 }
170
171 return 0;
172 }
173 #endif
174
175 int TOOLEXPORT
176 FP_strnicmp_fast (const char *str1, const char *str2, int count)
177 {
178 if (!str1 || !str2)
179 return -1;
180
181 while (count--) {
182 if (!*str1)
183 return -1;
184
185 if ((*str1 ^ *str2) & 0xdf)
186 return (*str1 & 0xdf) - (*str2 & 0xdf);
187
188 str1++;
189 str2++;
190 }
191
192 return 0;
193 }
194
195 char * TOOLEXPORT
196 FP_strpbrk (char *str, char *accept)
197 {
198 char *ptr;
199
200 if (str == NULL)
201 return NULL;
202 if (accept == NULL || *accept == '\0')
203 return str;
204
205 for (; *str; str++)
206 for (ptr=accept; *ptr; ptr++)
207 if (*str == *ptr)
208 return str;
209
210 return NULL;
211 }
212
213 /*
214 * autoconf also complains about this one
215 */
216
217 char * TOOLEXPORT
218 FP_strtok (char *str1, char *str2)
219 {
220 static char *optr;
221 char *ptr;
222
223 if (str2 == NULL)
224 return NULL;
225
226 if (str1) {
227 optr = str1;
228 }
229 else {
230 if (*optr == '\0')
231 return NULL;
232 }
233
234 while (*optr && strchr (str2, *optr)) /* look for beginning of token */
235 optr++;
236
237 if (*optr == '\0') /* no token found */
238 return NULL;
239
240 ptr = optr;
241 while (*optr && strchr (str2, *optr) == NULL) /* look for end of token */
242 optr++;
243
244 if (*optr) {
245 *optr++ = '\0';
246 }
247 return ptr;
248 }
249
250 /*
251 * case insensitive strstr.
252 */
253
254 #ifndef FP_stristr
255 char * TOOLEXPORT
256 FP_stristr (char *str1, char *str2)
257 {
258 char *ptr1, *ptr2;
259
260 if (str1==NULL)
261 return NULL;
262 if (str2==NULL)
263 return str1;
264
265 while (*(ptr1=str1)) {
266 for (ptr2=str2;
267 *ptr1 && *ptr2 && tolower(*ptr1)==tolower(*ptr2);
268 ptr1++, ptr2++)
269 /* empty loop */ ;
270
271 if (*ptr2 == '\0')
272 return str1;
273 str1++;
274 }
275 return NULL;
276 }
277 #endif
278
279 /*
280 * Nice fake of the real (non-standard) one
281 */
282
283 char * TOOLEXPORT
284 FP_strrstr (const char *ptr, const char *str)
285 {
286 const char *found=NULL, *new, *iter=ptr;
287
288 if (ptr==NULL || str==NULL)
289 return NULL;
290
291 if (*str == '\0')
292 return (char *)ptr;
293
294 while ((new = FP_strstr (iter, str)) != NULL) {
295 found = new;
296 iter = new + 1;
297 }
298
299 return (char *)found;
300 }
301
302 char * TOOLEXPORT
303 FP_strirstr (char *ptr, char *str)
304 {
305 char *found=NULL, *iter=ptr, *new;
306
307 if (ptr==NULL || str==NULL)
308 return NULL;
309 if (*str == '\0')
310 return ptr;
311
312 while ((new = FP_stristr (iter, str)) != NULL) {
313 found = new;
314 iter = new + 1;
315 }
316 return found;
317 }
318
319 /*
320 * convert whole string to case
321 */
322
323 char * TOOLEXPORT
324 FP_stoupper (char *input)
325 {
326 char *iter = input;
327
328 if (input == NULL)
329 return NULL;
330
331 while (*iter) {
332 *iter = toupper (*iter);
333 iter++;
334 }
335 return input;
336 }
337
338 char * TOOLEXPORT
339 FP_stolower (char *input)
340 {
341 char *iter = input;
342
343 if (input == NULL)
344 return NULL;
345
346 while (*iter) {
347 *iter = tolower (*iter);
348 iter++;
349 }
350 return input;
351 }
352
353 /*
354 * string matching with wildcards
355 */
356
357 int TOOLEXPORT
358 FP_strmatch (char *string, char *pattern)
359 {
360 char *p1 = string, *p2 = pattern;
361
362 if (pattern==NULL || string==NULL)
363 return 0;
364
365 while (*p1 && *p2) {
366 if (*p2 == '?') {
367 p1++; p2++;
368 }
369 else if (*p2 == '*') {
370 if (*++p2 == '\0')
371 return 1;
372 while (*p1 && *p1 != *p2)
373 p1++;
374 }
375 else if (*p1 == *p2) {
376 p1++; p2++;
377 }
378 else
379 return 0;
380 }
381 if (*p1 || *p2)
382 return 0;
383
384 return 1;
385 }
386
387 char * TOOLEXPORT
388 FP_strrchr (const char *string, int tc)
389 {
390 const char *ptr;
391
392 if (string == NULL || !*string)
393 return NULL;
394
395 ptr = string + strlen (string) - 1;
396
397 while (ptr != string && *ptr != tc)
398 ptr--;
399
400 if (*ptr == tc)
401 return (char *)ptr;
402
403 return NULL;
404 }
405
406 /*
407 * strip directory information from a filename. Works only on DOS and
408 * Unix systems so far ...
409 */
410
411 char * TOOLEXPORT
412 FP_cutdir (char *filename)
413 {
414 char *ptr;
415
416 if (filename == NULL)
417 return NULL;
418
419 if ((ptr = FP_strrchr (filename, '/')) != NULL)
420 ptr++;
421 else if ((ptr = FP_strrchr (filename, '\\')) != NULL)
422 ptr++;
423 else
424 ptr = filename;
425
426 return ptr;
427 }
428
429 /*
430 * My own fgets function. It handles all kinds of line terminators
431 * properly: LF (Unix), CRLF (DOS) and CR (Mac).
432 */
433 /* (schmorp) the buffer is always written to, and no LF is stored at the end */
434 /* also, if the buffer is too short, the remaining line is skipped */
435 ecb_hot char * TOOLEXPORT
436 FP_fgets (char *buf, int n, FILE *stream)
437 {
438 char *ptr = buf;
439 char *end = buf + n - 1;
440
441 /* shield against buffer overflows caused by "255 - bytes_left"-kind of bugs when bytes_left > 255 */
442 if (n <= 0)
443 return 0;
444
445 for (;;)
446 {
447 int c = FP_getc (stream);
448
449 if (ecb_expect_false (c <= '\015')) /* EOF is < 0x20, too */
450 {
451 /* ctlchar */
452
453 if (c == '\012')
454 /* LF, nothing following */
455 break;
456 else if (c == '\015')
457 {
458 /* CR, possibly CRLF, skip following LF */
459 c = FP_getc (stream);
460
461 if (c != '\012') /* CR LF? */
462 ungetc (c, stream);
463
464 break;
465 }
466 else if (c == EOF)
467 {
468 *ptr = 0;
469 return 0;
470 }
471 }
472
473 *ptr = c;
474 ptr += ptr < end; /* this is hopefully branch-free, and fast */
475 }
476
477 *ptr = 0;
478 return buf;
479 }
480