ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Convert-UUlib/uulib/fptools.c
Revision: 1.11
Committed: Sun Feb 9 15:06:43 2020 UTC (4 years, 3 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.10: +2 -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.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.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.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 root 1.10 #ifndef FP_stricmp
144 root 1.1 int TOOLEXPORT
145 root 1.11 _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.11 _FP_strnicmp (const char *str1, const char *str2, int count)
163 root 1.1 {
164     if (str1==NULL || str2==NULL)
165     return -1;
166    
167     while (*str1 && count) {
168     if (tolower(*str1) != tolower(*str2))
169     break;
170     str1++;
171     str2++;
172     count--;
173     }
174     return count ? (tolower (*str1) - tolower (*str2)) : 0;
175     }
176 root 1.10 #endif
177 root 1.1
178     char * TOOLEXPORT
179 root 1.5 _FP_strpbrk (char *str, char *accept)
180 root 1.1 {
181     char *ptr;
182    
183     if (str == NULL)
184     return NULL;
185     if (accept == NULL || *accept == '\0')
186     return str;
187    
188     for (; *str; str++)
189     for (ptr=accept; *ptr; ptr++)
190     if (*str == *ptr)
191     return str;
192    
193     return NULL;
194     }
195    
196     /*
197     * autoconf also complains about this one
198     */
199    
200     char * TOOLEXPORT
201 root 1.5 _FP_strtok (char *str1, char *str2)
202 root 1.1 {
203     static char *optr;
204     char *ptr;
205    
206     if (str2 == NULL)
207     return NULL;
208    
209     if (str1) {
210     optr = str1;
211     }
212     else {
213     if (*optr == '\0')
214     return NULL;
215     }
216    
217     while (*optr && strchr (str2, *optr)) /* look for beginning of token */
218     optr++;
219    
220     if (*optr == '\0') /* no token found */
221     return NULL;
222    
223     ptr = optr;
224     while (*optr && strchr (str2, *optr) == NULL) /* look for end of token */
225     optr++;
226    
227     if (*optr) {
228     *optr++ = '\0';
229     }
230     return ptr;
231     }
232    
233     /*
234     * case insensitive strstr.
235     */
236    
237 root 1.10 #ifndef FP_stristr
238 root 1.1 char * TOOLEXPORT
239 root 1.5 _FP_stristr (char *str1, char *str2)
240 root 1.1 {
241     char *ptr1, *ptr2;
242    
243     if (str1==NULL)
244     return NULL;
245     if (str2==NULL)
246     return str1;
247    
248     while (*(ptr1=str1)) {
249     for (ptr2=str2;
250     *ptr1 && *ptr2 && tolower(*ptr1)==tolower(*ptr2);
251     ptr1++, ptr2++)
252     /* empty loop */ ;
253    
254     if (*ptr2 == '\0')
255     return str1;
256     str1++;
257     }
258     return NULL;
259     }
260 root 1.10 #endif
261 root 1.1
262     /*
263     * Nice fake of the real (non-standard) one
264     */
265    
266     char * TOOLEXPORT
267 root 1.5 _FP_strrstr (char *ptr, char *str)
268 root 1.1 {
269     char *found=NULL, *new, *iter=ptr;
270    
271     if (ptr==NULL || str==NULL)
272     return NULL;
273    
274     if (*str == '\0')
275     return ptr;
276    
277 root 1.5 while ((new = _FP_strstr (iter, str)) != NULL) {
278 root 1.1 found = new;
279     iter = new + 1;
280     }
281     return found;
282     }
283    
284     char * TOOLEXPORT
285 root 1.5 _FP_strirstr (char *ptr, char *str)
286 root 1.1 {
287     char *found=NULL, *iter=ptr, *new;
288    
289     if (ptr==NULL || str==NULL)
290     return NULL;
291     if (*str == '\0')
292     return ptr;
293    
294 root 1.5 while ((new = _FP_stristr (iter, str)) != NULL) {
295 root 1.1 found = new;
296     iter = new + 1;
297     }
298     return found;
299     }
300    
301     /*
302     * convert whole string to case
303     */
304    
305     char * TOOLEXPORT
306 root 1.5 _FP_stoupper (char *input)
307 root 1.1 {
308     char *iter = input;
309    
310     if (input == NULL)
311     return NULL;
312    
313     while (*iter) {
314     *iter = toupper (*iter);
315     iter++;
316     }
317     return input;
318     }
319    
320     char * TOOLEXPORT
321 root 1.5 _FP_stolower (char *input)
322 root 1.1 {
323     char *iter = input;
324    
325     if (input == NULL)
326     return NULL;
327    
328     while (*iter) {
329     *iter = tolower (*iter);
330     iter++;
331     }
332     return input;
333     }
334    
335     /*
336     * string matching with wildcards
337     */
338    
339     int TOOLEXPORT
340 root 1.5 _FP_strmatch (char *string, char *pattern)
341 root 1.1 {
342     char *p1 = string, *p2 = pattern;
343    
344     if (pattern==NULL || string==NULL)
345     return 0;
346    
347     while (*p1 && *p2) {
348     if (*p2 == '?') {
349     p1++; p2++;
350     }
351     else if (*p2 == '*') {
352     if (*++p2 == '\0')
353     return 1;
354     while (*p1 && *p1 != *p2)
355     p1++;
356     }
357     else if (*p1 == *p2) {
358     p1++; p2++;
359     }
360     else
361     return 0;
362     }
363     if (*p1 || *p2)
364     return 0;
365    
366     return 1;
367     }
368    
369     char * TOOLEXPORT
370 root 1.5 _FP_strrchr (char *string, int tc)
371 root 1.1 {
372     char *ptr;
373    
374 root 1.7 if (string == NULL || !*string)
375 root 1.1 return NULL;
376    
377     ptr = string + strlen (string) - 1;
378    
379     while (ptr != string && *ptr != tc)
380     ptr--;
381    
382     if (*ptr == tc)
383     return ptr;
384    
385     return NULL;
386     }
387    
388     /*
389     * strip directory information from a filename. Works only on DOS and
390     * Unix systems so far ...
391     */
392    
393     char * TOOLEXPORT
394 root 1.5 _FP_cutdir (char *filename)
395 root 1.1 {
396     char *ptr;
397    
398     if (filename == NULL)
399     return NULL;
400    
401 root 1.5 if ((ptr = _FP_strrchr (filename, '/')) != NULL)
402 root 1.1 ptr++;
403 root 1.5 else if ((ptr = _FP_strrchr (filename, '\\')) != NULL)
404 root 1.1 ptr++;
405     else
406     ptr = filename;
407    
408     return ptr;
409     }
410    
411     /*
412     * My own fgets function. It handles all kinds of line terminators
413 root 1.9 * properly: LF (Unix), CRLF (DOS) and CR (Mac).
414 root 1.1 */
415 root 1.9 /* (schmorp) the buffer is always written to, and no LF is stored at the end */
416 root 1.1 char * TOOLEXPORT
417 root 1.5 _FP_fgets (char *buf, int n, FILE *stream)
418 root 1.1 {
419 root 1.9 static char format[64];
420     static int format_n = 0;
421     int res;
422 root 1.1 int c;
423 root 1.6
424     /* shield against buffer overflows caused by "255 - bytes_left"-kind of bugs when bytes_left > 255 */
425     if (n <= 0)
426     return NULL;
427 root 1.1
428 root 1.9 if (format_n != n)
429     {
430     sprintf (format, "%%%d[^\015\012]", n - 1);
431     format_n = n;
432     }
433    
434     *buf = 0; /* fscanf return s0 on empty lines */
435     res = fscanf (stream, format, buf);
436    
437     if (res == EOF)
438     return 0; /* an error occured */
439    
440 root 1.10 /* skip line endings */
441 root 1.9 for (;;)
442     {
443     c = _FP_fgetc (stream);
444    
445     if (c == '\012') /* LF */
446     return buf;
447     else if (c == '\015') /* CR */
448     {
449     c = _FP_fgetc (stream);
450     if (c != '\012') /* CR LF? */
451     ungetc (c, stream);
452    
453     return buf;
454     }
455     else if (c == EOF)
456     return 0; /* error */
457 root 1.1
458 root 1.9 /* skip remaining line */
459 root 1.1 }
460     }
461    
462     /*
463     * A replacement strerror function that just returns the error code
464     */
465    
466     char * TOOLEXPORT
467 root 1.5 _FP_strerror (int errcode)
468 root 1.1 {
469     static char number[8];
470    
471     sprintf (number, "%03d", errcode);
472    
473     return number;
474     }
475 root 1.3 #ifndef HAVE_MKSTEMP
476 root 1.1 /*
477     * tempnam is not ANSI, but tmpnam is. Ignore the prefix here.
478     */
479    
480     char * TOOLEXPORT
481 root 1.5 _FP_tempnam (char *dir, char *pfx)
482 root 1.1 {
483 root 1.5 return _FP_strdup (tmpnam (NULL));
484 root 1.1 }
485 root 1.3 #endif /* HAVE_MKSTEMP */