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