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