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

# User Rev Content
1 root 1.1 /*
2     * fptools.c, some helper functions for getcgi.c and uu(en|de)view
3     *
4 root 1.2 * Distributed under the terms of the GNU General Public License.
5     * Use and be happy.
6 root 1.1 */
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 root 1.13 * AC_CHECK_FUNC(strrchr,AC_DEFINE(strrchr,FP_strrchr))
26 root 1.1 * 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 root 1.13 * FP_free) or provide extended functionality (FP_gets).
30 root 1.1 * The above is not used in the uuenview/uudeview configuration script,
31     * since both only use the replacement functions in non-performance-cri-
32 root 1.13 * tical sections (except for FP_tempnam and FP_strerror, where some
33 root 1.1 * 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 root 1.7 char * fptools_id = "$Id$";
68 root 1.1
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 root 1.13 FP_free (void *ptr)
77 root 1.1 {
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 root 1.13 FP_strdup (char *string)
87 root 1.1 {
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 root 1.13 FP_strncpy (char *dest, char *src, int length)
108 root 1.1 {
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 root 1.14 FP_memdup (const void *ptr, int len)
126 root 1.1 {
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 root 1.10 #ifndef FP_stricmp
144 root 1.1 int TOOLEXPORT
145 root 1.13 FP_stricmp (const char *str1, const char *str2)
146 root 1.1 {
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 root 1.10 #endif
159 root 1.1
160 root 1.10 #ifndef FP_strnicmp
161 root 1.1 int TOOLEXPORT
162 root 1.13 FP_strnicmp (const char *str1, const char *str2, int count)
163 root 1.1 {
164 root 1.16 int d;
165    
166     if (!str1 || !str2)
167 root 1.1 return -1;
168    
169 root 1.16 while (count--) {
170     if (!*str1)
171     return -1;
172    
173     d = tolower (*str1) - tolower (*str2);
174     if (d)
175     return d;
176    
177 root 1.1 str1++;
178     str2++;
179     }
180 root 1.16
181     return 0;
182 root 1.1 }
183 root 1.10 #endif
184 root 1.1
185 root 1.14 int TOOLEXPORT
186     FP_strnicmp_fast (const char *str1, const char *str2, int count)
187     {
188 root 1.15 if (!str1 || !str2)
189 root 1.14 return -1;
190    
191 root 1.16 while (count--) {
192     if (!*str1)
193     return -1;
194    
195 root 1.14 if ((*str1 ^ *str2) & 0xdf)
196 root 1.16 return (*str1 & 0xdf) - (*str2 & 0xdf);
197 root 1.14
198     str1++;
199     str2++;
200     }
201    
202 root 1.16 return 0;
203 root 1.14 }
204    
205 root 1.1 char * TOOLEXPORT
206 root 1.13 FP_strpbrk (char *str, char *accept)
207 root 1.1 {
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 root 1.13 FP_strtok (char *str1, char *str2)
229 root 1.1 {
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 root 1.10 #ifndef FP_stristr
265 root 1.1 char * TOOLEXPORT
266 root 1.13 FP_stristr (char *str1, char *str2)
267 root 1.1 {
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 root 1.10 #endif
288 root 1.1
289     /*
290     * Nice fake of the real (non-standard) one
291     */
292    
293     char * TOOLEXPORT
294 root 1.15 FP_strrstr (const char *ptr, const char *str)
295 root 1.1 {
296 root 1.15 const char *found=NULL, *new, *iter=ptr;
297 root 1.1
298     if (ptr==NULL || str==NULL)
299     return NULL;
300    
301     if (*str == '\0')
302 root 1.15 return (char *)ptr;
303 root 1.1
304 root 1.13 while ((new = FP_strstr (iter, str)) != NULL) {
305 root 1.1 found = new;
306     iter = new + 1;
307     }
308 root 1.15
309     return (char *)found;
310 root 1.1 }
311    
312     char * TOOLEXPORT
313 root 1.13 FP_strirstr (char *ptr, char *str)
314 root 1.1 {
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 root 1.13 while ((new = FP_stristr (iter, str)) != NULL) {
323 root 1.1 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 root 1.13 FP_stoupper (char *input)
335 root 1.1 {
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 root 1.13 FP_stolower (char *input)
350 root 1.1 {
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 root 1.13 FP_strmatch (char *string, char *pattern)
369 root 1.1 {
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 root 1.14 FP_strrchr (const char *string, int tc)
399 root 1.1 {
400 root 1.14 const char *ptr;
401 root 1.1
402 root 1.7 if (string == NULL || !*string)
403 root 1.1 return NULL;
404    
405     ptr = string + strlen (string) - 1;
406    
407     while (ptr != string && *ptr != tc)
408     ptr--;
409    
410     if (*ptr == tc)
411 root 1.14 return (char *)ptr;
412 root 1.1
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 root 1.13 FP_cutdir (char *filename)
423 root 1.1 {
424     char *ptr;
425    
426     if (filename == NULL)
427     return NULL;
428    
429 root 1.13 if ((ptr = FP_strrchr (filename, '/')) != NULL)
430 root 1.1 ptr++;
431 root 1.13 else if ((ptr = FP_strrchr (filename, '\\')) != NULL)
432 root 1.1 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 root 1.9 * properly: LF (Unix), CRLF (DOS) and CR (Mac).
442 root 1.1 */
443 root 1.9 /* (schmorp) the buffer is always written to, and no LF is stored at the end */
444 root 1.12 /* also, if the buffer is too short, the remaining line is skipped */
445 root 1.1 char * TOOLEXPORT
446 root 1.13 FP_fgets (char *buf, int n, FILE *stream)
447 root 1.1 {
448 root 1.12 char *ptr = buf;
449     char *end = buf + n - 1;
450 root 1.6
451     /* shield against buffer overflows caused by "255 - bytes_left"-kind of bugs when bytes_left > 255 */
452     if (n <= 0)
453 root 1.12 return 0;
454 root 1.1
455 root 1.9 for (;;)
456     {
457 root 1.13 int c = FP_getc (stream);
458 root 1.9
459 root 1.12 if (ecb_expect_false (c <= '\015')) /* EOF is < 0x20, too */
460 root 1.9 {
461 root 1.12 /* ctlchar */
462 root 1.9
463 root 1.12 if (c == '\012')
464     /* LF, nothing following */
465     break;
466     else if (c == '\015')
467     {
468     /* CR, possibly CRLF, skip following LF */
469 root 1.13 c = FP_getc (stream);
470 root 1.12
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 root 1.9 }
482 root 1.1
483 root 1.12 *ptr = c;
484     ptr += ptr < end; /* this is hopefully branch-free, and fast */
485 root 1.1 }
486 root 1.12
487     *ptr = 0;
488     return buf;
489 root 1.1 }
490    
491     /*
492     * A replacement strerror function that just returns the error code
493     */
494    
495     char * TOOLEXPORT
496 root 1.13 FP_strerror (int errcode)
497 root 1.1 {
498     static char number[8];
499    
500     sprintf (number, "%03d", errcode);
501    
502     return number;
503     }
504 root 1.3 #ifndef HAVE_MKSTEMP
505 root 1.1 /*
506     * tempnam is not ANSI, but tmpnam is. Ignore the prefix here.
507     */
508    
509     char * TOOLEXPORT
510 root 1.13 FP_tempnam (char *dir, char *pfx)
511 root 1.1 {
512 root 1.13 return FP_strdup (tmpnam (NULL));
513 root 1.1 }
514 root 1.3 #endif /* HAVE_MKSTEMP */