ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Convert-UUlib/uulib/fptools.c
Revision: 1.3.2.4
Committed: Thu Nov 6 13:08:23 2003 UTC (20 years, 6 months ago) by root
Content type: text/plain
Branch: UUDEVIEW
CVS Tags: UUDEVIEW-0-5-19
Changes since 1.3.2.3: +2 -2 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 /*
2 * fptools.c, some helper functions for getcgi.c and uu(en|de)view
3 *
4 * Distributed under the terms of the GNU General Public License.
5 * Use and be happy.
6 */
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 * AC_CHECK_FUNC(strrchr,AC_DEFINE(strrchr,_FP_strrchr))
26 * 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 * _FP_free) or provide extended functionality (_FP_gets).
30 * The above is not used in the uuenview/uudeview configuration script,
31 * since both only use the replacement functions in non-performance-cri-
32 * tical sections (except for _FP_tempnam and _FP_strerror, where some
33 * 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 char * fptools_id = "$Id: fptools.c,v 1.7 2003/04/13 15:41:55 fp Exp $";
68
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 _FP_free (void *ptr)
77 {
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 _FP_strdup (char *string)
87 {
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 _FP_strncpy (char *dest, char *src, int length)
108 {
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 _FP_memdup (void *ptr, int len)
126 {
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 _FP_stricmp (char *str1, char *str2)
145 {
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 _FP_strnicmp (char *str1, char *str2, int count)
160 {
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 _FP_strstr (char *str1, char *str2)
180 {
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 _FP_strpbrk (char *str, char *accept)
203 {
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 _FP_strtok (char *str1, char *str2)
225 {
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 _FP_stristr (char *str1, char *str2)
262 {
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 _FP_strrstr (char *ptr, char *str)
289 {
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 while ((new = _FP_strstr (iter, str)) != NULL) {
299 found = new;
300 iter = new + 1;
301 }
302 return found;
303 }
304
305 char * TOOLEXPORT
306 _FP_strirstr (char *ptr, char *str)
307 {
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 while ((new = _FP_stristr (iter, str)) != NULL) {
316 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 _FP_stoupper (char *input)
328 {
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 _FP_stolower (char *input)
343 {
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 _FP_strmatch (char *string, char *pattern)
362 {
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 _FP_strrchr (char *string, int tc)
392 {
393 char *ptr;
394
395 if (string == NULL || !*string)
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 _FP_cutdir (char *filename)
416 {
417 char *ptr;
418
419 if (filename == NULL)
420 return NULL;
421
422 if ((ptr = _FP_strrchr (filename, '/')) != NULL)
423 ptr++;
424 else if ((ptr = _FP_strrchr (filename, '\\')) != NULL)
425 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 _FP_fgets (char *buf, int n, FILE *stream)
440 {
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 _FP_strerror (int errcode)
495 {
496 static char number[8];
497
498 sprintf (number, "%03d", errcode);
499
500 return number;
501 }
502
503 /*
504 * tempnam is not ANSI, but tmpnam is. Ignore the prefix here.
505 */
506
507 char * TOOLEXPORT
508 _FP_tempnam (char *dir, char *pfx)
509 {
510 return _FP_strdup (tmpnam (NULL));
511 }