ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Convert-UUlib/uulib/fptools.c
Revision: 1.16
Committed: Sat Dec 12 00:44:18 2020 UTC (3 years, 5 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.15: +19 -10 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
39 #ifdef STDC_HEADERS
40 #include <stdlib.h>
41 #include <string.h>
42 #endif
43 #ifdef HAVE_MALLOC_H
44 #include <malloc.h>
45 #endif
46 #ifdef HAVE_UNISTD_H
47 #include <unistd.h>
48 #endif
49 #ifdef HAVE_MEMORY_H
50 #include <memory.h>
51 #endif
52
53 #include <fptools.h>
54
55 #if 0
56 #ifdef SYSTEM_WINDLL
57 BOOL _export WINAPI
58 DllEntryPoint (HINSTANCE hInstance, DWORD seginfo,
59 LPVOID lpCmdLine)
60 {
61 /* Don't do anything, so just return true */
62 return TRUE;
63 }
64 #endif
65 #endif
66
67 char * fptools_id = "$Id$";
68
69 /*
70 * some versions of free can't handle a NULL pointer properly
71 * (ANSI says, free ignores a NULL pointer, but some machines
72 * prefer to SIGSEGV on it)
73 */
74
75 void TOOLEXPORT
76 FP_free (void *ptr)
77 {
78 if (ptr) free (ptr);
79 }
80
81 /*
82 * This is non-standard, so I'm defining my own
83 */
84
85 char * TOOLEXPORT
86 FP_strdup (char *string)
87 {
88 char *result;
89
90 if (string == NULL)
91 return NULL;
92
93 if ((result = (char *) malloc (strlen (string) + 1)) == NULL)
94 return NULL;
95
96 strcpy (result, string);
97 return result;
98 }
99
100 /*
101 * limited-length string copy. this function behaves differently from
102 * the original in that the dest string is always terminated with a
103 * NULL character.
104 */
105
106 char * TOOLEXPORT
107 FP_strncpy (char *dest, char *src, int length)
108 {
109 char *odest=dest;
110 if (src == NULL || dest == NULL || length-- <= 0)
111 return dest;
112
113 while (length-- && *src)
114 *dest++ = *src++;
115
116 *dest++ = '\0';
117 return odest;
118 }
119
120 /*
121 * duplicate a memory area
122 */
123
124 void * TOOLEXPORT
125 FP_memdup (const void *ptr, int len)
126 {
127 void *result;
128
129 if (ptr == NULL)
130 return NULL;
131
132 if ((result = malloc (len)) == NULL)
133 return NULL;
134
135 memcpy (result, ptr, len);
136 return result;
137 }
138
139 /*
140 * case-insensitive compare
141 */
142
143 #ifndef FP_stricmp
144 int TOOLEXPORT
145 FP_stricmp (const char *str1, const char *str2)
146 {
147 if (str1==NULL || str2==NULL)
148 return -1;
149
150 while (*str1) {
151 if (tolower(*str1) != tolower(*str2))
152 break;
153 str1++;
154 str2++;
155 }
156 return (tolower (*str1) - tolower (*str2));
157 }
158 #endif
159
160 #ifndef FP_strnicmp
161 int TOOLEXPORT
162 FP_strnicmp (const char *str1, const char *str2, int count)
163 {
164 int d;
165
166 if (!str1 || !str2)
167 return -1;
168
169 while (count--) {
170 if (!*str1)
171 return -1;
172
173 d = tolower (*str1) - tolower (*str2);
174 if (d)
175 return d;
176
177 str1++;
178 str2++;
179 }
180
181 return 0;
182 }
183 #endif
184
185 int TOOLEXPORT
186 FP_strnicmp_fast (const char *str1, const char *str2, int count)
187 {
188 if (!str1 || !str2)
189 return -1;
190
191 while (count--) {
192 if (!*str1)
193 return -1;
194
195 if ((*str1 ^ *str2) & 0xdf)
196 return (*str1 & 0xdf) - (*str2 & 0xdf);
197
198 str1++;
199 str2++;
200 }
201
202 return 0;
203 }
204
205 char * TOOLEXPORT
206 FP_strpbrk (char *str, char *accept)
207 {
208 char *ptr;
209
210 if (str == NULL)
211 return NULL;
212 if (accept == NULL || *accept == '\0')
213 return str;
214
215 for (; *str; str++)
216 for (ptr=accept; *ptr; ptr++)
217 if (*str == *ptr)
218 return str;
219
220 return NULL;
221 }
222
223 /*
224 * autoconf also complains about this one
225 */
226
227 char * TOOLEXPORT
228 FP_strtok (char *str1, char *str2)
229 {
230 static char *optr;
231 char *ptr;
232
233 if (str2 == NULL)
234 return NULL;
235
236 if (str1) {
237 optr = str1;
238 }
239 else {
240 if (*optr == '\0')
241 return NULL;
242 }
243
244 while (*optr && strchr (str2, *optr)) /* look for beginning of token */
245 optr++;
246
247 if (*optr == '\0') /* no token found */
248 return NULL;
249
250 ptr = optr;
251 while (*optr && strchr (str2, *optr) == NULL) /* look for end of token */
252 optr++;
253
254 if (*optr) {
255 *optr++ = '\0';
256 }
257 return ptr;
258 }
259
260 /*
261 * case insensitive strstr.
262 */
263
264 #ifndef FP_stristr
265 char * TOOLEXPORT
266 FP_stristr (char *str1, char *str2)
267 {
268 char *ptr1, *ptr2;
269
270 if (str1==NULL)
271 return NULL;
272 if (str2==NULL)
273 return str1;
274
275 while (*(ptr1=str1)) {
276 for (ptr2=str2;
277 *ptr1 && *ptr2 && tolower(*ptr1)==tolower(*ptr2);
278 ptr1++, ptr2++)
279 /* empty loop */ ;
280
281 if (*ptr2 == '\0')
282 return str1;
283 str1++;
284 }
285 return NULL;
286 }
287 #endif
288
289 /*
290 * Nice fake of the real (non-standard) one
291 */
292
293 char * TOOLEXPORT
294 FP_strrstr (const char *ptr, const char *str)
295 {
296 const char *found=NULL, *new, *iter=ptr;
297
298 if (ptr==NULL || str==NULL)
299 return NULL;
300
301 if (*str == '\0')
302 return (char *)ptr;
303
304 while ((new = FP_strstr (iter, str)) != NULL) {
305 found = new;
306 iter = new + 1;
307 }
308
309 return (char *)found;
310 }
311
312 char * TOOLEXPORT
313 FP_strirstr (char *ptr, char *str)
314 {
315 char *found=NULL, *iter=ptr, *new;
316
317 if (ptr==NULL || str==NULL)
318 return NULL;
319 if (*str == '\0')
320 return ptr;
321
322 while ((new = FP_stristr (iter, str)) != NULL) {
323 found = new;
324 iter = new + 1;
325 }
326 return found;
327 }
328
329 /*
330 * convert whole string to case
331 */
332
333 char * TOOLEXPORT
334 FP_stoupper (char *input)
335 {
336 char *iter = input;
337
338 if (input == NULL)
339 return NULL;
340
341 while (*iter) {
342 *iter = toupper (*iter);
343 iter++;
344 }
345 return input;
346 }
347
348 char * TOOLEXPORT
349 FP_stolower (char *input)
350 {
351 char *iter = input;
352
353 if (input == NULL)
354 return NULL;
355
356 while (*iter) {
357 *iter = tolower (*iter);
358 iter++;
359 }
360 return input;
361 }
362
363 /*
364 * string matching with wildcards
365 */
366
367 int TOOLEXPORT
368 FP_strmatch (char *string, char *pattern)
369 {
370 char *p1 = string, *p2 = pattern;
371
372 if (pattern==NULL || string==NULL)
373 return 0;
374
375 while (*p1 && *p2) {
376 if (*p2 == '?') {
377 p1++; p2++;
378 }
379 else if (*p2 == '*') {
380 if (*++p2 == '\0')
381 return 1;
382 while (*p1 && *p1 != *p2)
383 p1++;
384 }
385 else if (*p1 == *p2) {
386 p1++; p2++;
387 }
388 else
389 return 0;
390 }
391 if (*p1 || *p2)
392 return 0;
393
394 return 1;
395 }
396
397 char * TOOLEXPORT
398 FP_strrchr (const char *string, int tc)
399 {
400 const char *ptr;
401
402 if (string == NULL || !*string)
403 return NULL;
404
405 ptr = string + strlen (string) - 1;
406
407 while (ptr != string && *ptr != tc)
408 ptr--;
409
410 if (*ptr == tc)
411 return (char *)ptr;
412
413 return NULL;
414 }
415
416 /*
417 * strip directory information from a filename. Works only on DOS and
418 * Unix systems so far ...
419 */
420
421 char * TOOLEXPORT
422 FP_cutdir (char *filename)
423 {
424 char *ptr;
425
426 if (filename == NULL)
427 return NULL;
428
429 if ((ptr = FP_strrchr (filename, '/')) != NULL)
430 ptr++;
431 else if ((ptr = FP_strrchr (filename, '\\')) != NULL)
432 ptr++;
433 else
434 ptr = filename;
435
436 return ptr;
437 }
438
439 /*
440 * My own fgets function. It handles all kinds of line terminators
441 * properly: LF (Unix), CRLF (DOS) and CR (Mac).
442 */
443 /* (schmorp) the buffer is always written to, and no LF is stored at the end */
444 /* also, if the buffer is too short, the remaining line is skipped */
445 char * TOOLEXPORT
446 FP_fgets (char *buf, int n, FILE *stream)
447 {
448 char *ptr = buf;
449 char *end = buf + n - 1;
450
451 /* shield against buffer overflows caused by "255 - bytes_left"-kind of bugs when bytes_left > 255 */
452 if (n <= 0)
453 return 0;
454
455 for (;;)
456 {
457 int c = FP_getc (stream);
458
459 if (ecb_expect_false (c <= '\015')) /* EOF is < 0x20, too */
460 {
461 /* ctlchar */
462
463 if (c == '\012')
464 /* LF, nothing following */
465 break;
466 else if (c == '\015')
467 {
468 /* CR, possibly CRLF, skip following LF */
469 c = FP_getc (stream);
470
471 if (c != '\012') /* CR LF? */
472 ungetc (c, stream);
473
474 break;
475 }
476 else if (c == EOF)
477 {
478 *ptr = 0;
479 return 0;
480 }
481 }
482
483 *ptr = c;
484 ptr += ptr < end; /* this is hopefully branch-free, and fast */
485 }
486
487 *ptr = 0;
488 return buf;
489 }
490
491 /*
492 * A replacement strerror function that just returns the error code
493 */
494
495 char * TOOLEXPORT
496 FP_strerror (int errcode)
497 {
498 static char number[8];
499
500 sprintf (number, "%03d", errcode);
501
502 return number;
503 }
504 #ifndef HAVE_MKSTEMP
505 /*
506 * tempnam is not ANSI, but tmpnam is. Ignore the prefix here.
507 */
508
509 char * TOOLEXPORT
510 FP_tempnam (char *dir, char *pfx)
511 {
512 return FP_strdup (tmpnam (NULL));
513 }
514 #endif /* HAVE_MKSTEMP */