ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Convert-UUlib/uulib/fptools.c
Revision: 1.5
Committed: Sun Mar 31 20:08:42 2002 UTC (22 years, 2 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.4: +29 -29 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.5 * 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.5 * _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.5 * 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.5 char * fptools_id = "$Id: fptools.c,v 1.4 2002/03/31 20:04:29 root Exp $";
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.5 _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.5 _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.5 _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.5 _FP_memdup (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     int TOOLEXPORT
144 root 1.5 _FP_stricmp (char *str1, char *str2)
145 root 1.1 {
146     if (str1==NULL || str2==NULL)
147     return -1;
148    
149     while (*str1) {
150     if (tolower(*str1) != tolower(*str2))
151     break;
152     str1++;
153     str2++;
154     }
155     return (tolower (*str1) - tolower (*str2));
156     }
157    
158     int TOOLEXPORT
159 root 1.5 _FP_strnicmp (char *str1, char *str2, int count)
160 root 1.1 {
161     if (str1==NULL || str2==NULL)
162     return -1;
163    
164     while (*str1 && count) {
165     if (tolower(*str1) != tolower(*str2))
166     break;
167     str1++;
168     str2++;
169     count--;
170     }
171     return count ? (tolower (*str1) - tolower (*str2)) : 0;
172     }
173    
174     /*
175     * autoconf says this function might be a compatibility problem
176     */
177    
178     char * TOOLEXPORT
179 root 1.5 _FP_strstr (char *str1, char *str2)
180 root 1.1 {
181     char *ptr1, *ptr2;
182    
183     if (str1==NULL)
184     return NULL;
185     if (str2==NULL)
186     return str1;
187    
188     while (*(ptr1=str1)) {
189     for (ptr2=str2;
190     *ptr1 && *ptr2 && *ptr1==*ptr2;
191     ptr1++, ptr2++)
192     /* empty loop */ ;
193    
194     if (*ptr2 == '\0')
195     return str1;
196     str1++;
197     }
198     return NULL;
199     }
200    
201     char * TOOLEXPORT
202 root 1.5 _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.5 _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     char * TOOLEXPORT
261 root 1.5 _FP_stristr (char *str1, char *str2)
262 root 1.1 {
263     char *ptr1, *ptr2;
264    
265     if (str1==NULL)
266     return NULL;
267     if (str2==NULL)
268     return str1;
269    
270     while (*(ptr1=str1)) {
271     for (ptr2=str2;
272     *ptr1 && *ptr2 && tolower(*ptr1)==tolower(*ptr2);
273     ptr1++, ptr2++)
274     /* empty loop */ ;
275    
276     if (*ptr2 == '\0')
277     return str1;
278     str1++;
279     }
280     return NULL;
281     }
282    
283     /*
284     * Nice fake of the real (non-standard) one
285     */
286    
287     char * TOOLEXPORT
288 root 1.5 _FP_strrstr (char *ptr, char *str)
289 root 1.1 {
290     char *found=NULL, *new, *iter=ptr;
291    
292     if (ptr==NULL || str==NULL)
293     return NULL;
294    
295     if (*str == '\0')
296     return ptr;
297    
298 root 1.5 while ((new = _FP_strstr (iter, str)) != NULL) {
299 root 1.1 found = new;
300     iter = new + 1;
301     }
302     return found;
303     }
304    
305     char * TOOLEXPORT
306 root 1.5 _FP_strirstr (char *ptr, char *str)
307 root 1.1 {
308     char *found=NULL, *iter=ptr, *new;
309    
310     if (ptr==NULL || str==NULL)
311     return NULL;
312     if (*str == '\0')
313     return ptr;
314    
315 root 1.5 while ((new = _FP_stristr (iter, str)) != NULL) {
316 root 1.1 found = new;
317     iter = new + 1;
318     }
319     return found;
320     }
321    
322     /*
323     * convert whole string to case
324     */
325    
326     char * TOOLEXPORT
327 root 1.5 _FP_stoupper (char *input)
328 root 1.1 {
329     char *iter = input;
330    
331     if (input == NULL)
332     return NULL;
333    
334     while (*iter) {
335     *iter = toupper (*iter);
336     iter++;
337     }
338     return input;
339     }
340    
341     char * TOOLEXPORT
342 root 1.5 _FP_stolower (char *input)
343 root 1.1 {
344     char *iter = input;
345    
346     if (input == NULL)
347     return NULL;
348    
349     while (*iter) {
350     *iter = tolower (*iter);
351     iter++;
352     }
353     return input;
354     }
355    
356     /*
357     * string matching with wildcards
358     */
359    
360     int TOOLEXPORT
361 root 1.5 _FP_strmatch (char *string, char *pattern)
362 root 1.1 {
363     char *p1 = string, *p2 = pattern;
364    
365     if (pattern==NULL || string==NULL)
366     return 0;
367    
368     while (*p1 && *p2) {
369     if (*p2 == '?') {
370     p1++; p2++;
371     }
372     else if (*p2 == '*') {
373     if (*++p2 == '\0')
374     return 1;
375     while (*p1 && *p1 != *p2)
376     p1++;
377     }
378     else if (*p1 == *p2) {
379     p1++; p2++;
380     }
381     else
382     return 0;
383     }
384     if (*p1 || *p2)
385     return 0;
386    
387     return 1;
388     }
389    
390     char * TOOLEXPORT
391 root 1.5 _FP_strrchr (char *string, int tc)
392 root 1.1 {
393     char *ptr;
394    
395     if (string == NULL)
396     return NULL;
397    
398     ptr = string + strlen (string) - 1;
399    
400     while (ptr != string && *ptr != tc)
401     ptr--;
402    
403     if (*ptr == tc)
404     return ptr;
405    
406     return NULL;
407     }
408    
409     /*
410     * strip directory information from a filename. Works only on DOS and
411     * Unix systems so far ...
412     */
413    
414     char * TOOLEXPORT
415 root 1.5 _FP_cutdir (char *filename)
416 root 1.1 {
417     char *ptr;
418    
419     if (filename == NULL)
420     return NULL;
421    
422 root 1.5 if ((ptr = _FP_strrchr (filename, '/')) != NULL)
423 root 1.1 ptr++;
424 root 1.5 else if ((ptr = _FP_strrchr (filename, '\\')) != NULL)
425 root 1.1 ptr++;
426     else
427     ptr = filename;
428    
429     return ptr;
430     }
431    
432     /*
433     * My own fgets function. It handles all kinds of line terminators
434     * properly: LF (Unix), CRLF (DOS) and CR (Mac). In all cases, the
435     * terminator is replaced by a single LF
436     */
437    
438     char * TOOLEXPORT
439 root 1.5 _FP_fgets (char *buf, int n, FILE *stream)
440 root 1.1 {
441     char *obp = buf;
442     int c;
443    
444     if (feof (stream))
445     return NULL;
446    
447     while (--n) {
448     if ((c = fgetc (stream)) == EOF) {
449     if (ferror (stream))
450     return NULL;
451     else {
452     if (obp == buf)
453     return NULL;
454     *buf = '\0';
455     return obp;
456     }
457     }
458     if (c == '\015') { /* CR */
459     /*
460     * Peek next character. If it's no LF, push it back.
461     * ungetc(EOF, stream) is handled correctly according
462     * to the manual page
463     */
464     if ((c = fgetc (stream)) != '\012')
465     if (!feof (stream))
466     ungetc (c, stream);
467     *buf++ = '\012';
468     *buf = '\0';
469     return obp;
470     }
471     else if (c == '\012') { /* LF */
472     *buf++ = '\012';
473     *buf = '\0';
474     return obp;
475     }
476     /*
477     * just another standard character
478     */
479     *buf++ = c;
480     }
481     /*
482     * n-1 characters already transferred
483     */
484     *buf = '\0';
485    
486     return obp;
487     }
488    
489     /*
490     * A replacement strerror function that just returns the error code
491     */
492    
493     char * TOOLEXPORT
494 root 1.5 _FP_strerror (int errcode)
495 root 1.1 {
496     static char number[8];
497    
498     sprintf (number, "%03d", errcode);
499    
500     return number;
501     }
502 root 1.3 #ifndef HAVE_MKSTEMP
503 root 1.1 /*
504     * tempnam is not ANSI, but tmpnam is. Ignore the prefix here.
505     */
506    
507     char * TOOLEXPORT
508 root 1.5 _FP_tempnam (char *dir, char *pfx)
509 root 1.1 {
510 root 1.5 return _FP_strdup (tmpnam (NULL));
511 root 1.1 }
512 root 1.3 #endif /* HAVE_MKSTEMP */