ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Convert-UUlib/uulib/fptools.c
Revision: 1.1
Committed: Mon Jun 11 19:48:57 2001 UTC (22 years, 11 months ago) by root
Content type: text/plain
Branch: MAIN
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 by the GNU General Public License. Use and be happy.
5 * Read http://www.uni-frankfurt.de/~fp/Tools/Getcgi.html for more
6 * information. fp@informatik.uni-frankfurt.de
7 */
8
9 #ifdef HAVE_CONFIG_H
10 #include "config.h"
11 #endif
12
13 #ifdef SYSTEM_WINDLL
14 #include <windows.h>
15 #endif
16 #ifdef SYSTEM_OS2
17 #include <os2.h>
18 #endif
19
20 /*
21 * This file provides replacements for some handy functions that aren't
22 * available on all systems, like most of the <string.h> functions. They
23 * should behave exactly as their counterparts. There are also extensions
24 * that aren't portable at all (like strirstr etc.).
25 * The proper behaviour in a configure script is as follows:
26 * AC_CHECK_FUNC(strrchr,AC_DEFINE(strrchr,FP_strrchr))
27 * This way, the (probably less efficient) replacements will only be used
28 * where it is not provided by the default libraries. Be aware that this
29 * does not work with replacements that just shadow wrong behaviour (like
30 * FP_free) or provide extended functionality (FP_gets).
31 * The above is not used in the uuenview/uudeview configuration script,
32 * since both only use the replacement functions in non-performance-cri-
33 * tical sections (except for FP_tempnam and FP_strerror, where some
34 * functionality of the original would be lost).
35 */
36
37 #include <stdio.h>
38 #include <ctype.h>
39
40 #ifdef STDC_HEADERS
41 #include <stdlib.h>
42 #include <string.h>
43 #endif
44 #ifdef HAVE_MALLOC_H
45 #include <malloc.h>
46 #endif
47 #ifdef HAVE_UNISTD_H
48 #include <unistd.h>
49 #endif
50 #ifdef HAVE_MEMORY_H
51 #include <memory.h>
52 #endif
53
54 #include <fptools.h>
55
56 #if 0
57 #ifdef SYSTEM_WINDLL
58 BOOL _export WINAPI
59 DllEntryPoint (HINSTANCE hInstance, DWORD seginfo,
60 LPVOID lpCmdLine)
61 {
62 /* Don't do anything, so just return true */
63 return TRUE;
64 }
65 #endif
66 #endif
67
68 char * fptools_id = "$Id: fptools.c,v 1.4 1996/09/10 18:45:07 fp Exp $";
69
70 /*
71 * some versions of free can't handle a NULL pointer properly
72 * (ANSI says, free ignores a NULL pointer, but some machines
73 * prefer to SIGSEGV on it)
74 */
75
76 void TOOLEXPORT
77 FP_free (void *ptr)
78 {
79 if (ptr) free (ptr);
80 }
81
82 /*
83 * This is non-standard, so I'm defining my own
84 */
85
86 char * TOOLEXPORT
87 FP_strdup (char *string)
88 {
89 char *result;
90
91 if (string == NULL)
92 return NULL;
93
94 if ((result = (char *) malloc (strlen (string) + 1)) == NULL)
95 return NULL;
96
97 strcpy (result, string);
98 return result;
99 }
100
101 /*
102 * limited-length string copy. this function behaves differently from
103 * the original in that the dest string is always terminated with a
104 * NULL character.
105 */
106
107 char * TOOLEXPORT
108 FP_strncpy (char *dest, char *src, int length)
109 {
110 char *odest=dest;
111 if (src == NULL || dest == NULL || length-- <= 0)
112 return dest;
113
114 while (length-- && *src)
115 *dest++ = *src++;
116
117 *dest++ = '\0';
118 return odest;
119 }
120
121 /*
122 * duplicate a memory area
123 */
124
125 void * TOOLEXPORT
126 FP_memdup (void *ptr, int len)
127 {
128 void *result;
129
130 if (ptr == NULL)
131 return NULL;
132
133 if ((result = malloc (len)) == NULL)
134 return NULL;
135
136 memcpy (result, ptr, len);
137 return result;
138 }
139
140 /*
141 * case-insensitive compare
142 */
143
144 int TOOLEXPORT
145 FP_stricmp (char *str1, char *str2)
146 {
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
159 int TOOLEXPORT
160 FP_strnicmp (char *str1, char *str2, int count)
161 {
162 if (str1==NULL || str2==NULL)
163 return -1;
164
165 while (*str1 && count) {
166 if (tolower(*str1) != tolower(*str2))
167 break;
168 str1++;
169 str2++;
170 count--;
171 }
172 return count ? (tolower (*str1) - tolower (*str2)) : 0;
173 }
174
175 /*
176 * autoconf says this function might be a compatibility problem
177 */
178
179 char * TOOLEXPORT
180 FP_strstr (char *str1, char *str2)
181 {
182 char *ptr1, *ptr2;
183
184 if (str1==NULL)
185 return NULL;
186 if (str2==NULL)
187 return str1;
188
189 while (*(ptr1=str1)) {
190 for (ptr2=str2;
191 *ptr1 && *ptr2 && *ptr1==*ptr2;
192 ptr1++, ptr2++)
193 /* empty loop */ ;
194
195 if (*ptr2 == '\0')
196 return str1;
197 str1++;
198 }
199 return NULL;
200 }
201
202 char * TOOLEXPORT
203 FP_strpbrk (char *str, char *accept)
204 {
205 char *ptr;
206
207 if (str == NULL)
208 return NULL;
209 if (accept == NULL || *accept == '\0')
210 return str;
211
212 for (; *str; str++)
213 for (ptr=accept; *ptr; ptr++)
214 if (*str == *ptr)
215 return str;
216
217 return NULL;
218 }
219
220 /*
221 * autoconf also complains about this one
222 */
223
224 char * TOOLEXPORT
225 FP_strtok (char *str1, char *str2)
226 {
227 static char *optr;
228 char *ptr;
229
230 if (str2 == NULL)
231 return NULL;
232
233 if (str1) {
234 optr = str1;
235 }
236 else {
237 if (*optr == '\0')
238 return NULL;
239 }
240
241 while (*optr && strchr (str2, *optr)) /* look for beginning of token */
242 optr++;
243
244 if (*optr == '\0') /* no token found */
245 return NULL;
246
247 ptr = optr;
248 while (*optr && strchr (str2, *optr) == NULL) /* look for end of token */
249 optr++;
250
251 if (*optr) {
252 *optr++ = '\0';
253 }
254 return ptr;
255 }
256
257 /*
258 * case insensitive strstr.
259 */
260
261 char * TOOLEXPORT
262 FP_stristr (char *str1, char *str2)
263 {
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
284 /*
285 * Nice fake of the real (non-standard) one
286 */
287
288 char * TOOLEXPORT
289 FP_strrstr (char *ptr, char *str)
290 {
291 char *found=NULL, *new, *iter=ptr;
292
293 if (ptr==NULL || str==NULL)
294 return NULL;
295
296 if (*str == '\0')
297 return ptr;
298
299 while ((new = FP_strstr (iter, str)) != NULL) {
300 found = new;
301 iter = new + 1;
302 }
303 return found;
304 }
305
306 char * TOOLEXPORT
307 FP_strirstr (char *ptr, char *str)
308 {
309 char *found=NULL, *iter=ptr, *new;
310
311 if (ptr==NULL || str==NULL)
312 return NULL;
313 if (*str == '\0')
314 return ptr;
315
316 while ((new = FP_stristr (iter, str)) != NULL) {
317 found = new;
318 iter = new + 1;
319 }
320 return found;
321 }
322
323 /*
324 * convert whole string to case
325 */
326
327 char * TOOLEXPORT
328 FP_stoupper (char *input)
329 {
330 char *iter = input;
331
332 if (input == NULL)
333 return NULL;
334
335 while (*iter) {
336 *iter = toupper (*iter);
337 iter++;
338 }
339 return input;
340 }
341
342 char * TOOLEXPORT
343 FP_stolower (char *input)
344 {
345 char *iter = input;
346
347 if (input == NULL)
348 return NULL;
349
350 while (*iter) {
351 *iter = tolower (*iter);
352 iter++;
353 }
354 return input;
355 }
356
357 /*
358 * string matching with wildcards
359 */
360
361 int TOOLEXPORT
362 FP_strmatch (char *string, char *pattern)
363 {
364 char *p1 = string, *p2 = pattern;
365
366 if (pattern==NULL || string==NULL)
367 return 0;
368
369 while (*p1 && *p2) {
370 if (*p2 == '?') {
371 p1++; p2++;
372 }
373 else if (*p2 == '*') {
374 if (*++p2 == '\0')
375 return 1;
376 while (*p1 && *p1 != *p2)
377 p1++;
378 }
379 else if (*p1 == *p2) {
380 p1++; p2++;
381 }
382 else
383 return 0;
384 }
385 if (*p1 || *p2)
386 return 0;
387
388 return 1;
389 }
390
391 char * TOOLEXPORT
392 FP_strrchr (char *string, int tc)
393 {
394 char *ptr;
395
396 if (string == NULL)
397 return NULL;
398
399 ptr = string + strlen (string) - 1;
400
401 while (ptr != string && *ptr != tc)
402 ptr--;
403
404 if (*ptr == tc)
405 return ptr;
406
407 return NULL;
408 }
409
410 /*
411 * strip directory information from a filename. Works only on DOS and
412 * Unix systems so far ...
413 */
414
415 char * TOOLEXPORT
416 FP_cutdir (char *filename)
417 {
418 char *ptr;
419
420 if (filename == NULL)
421 return NULL;
422
423 if ((ptr = FP_strrchr (filename, '/')) != NULL)
424 ptr++;
425 else if ((ptr = FP_strrchr (filename, '\\')) != NULL)
426 ptr++;
427 else
428 ptr = filename;
429
430 return ptr;
431 }
432
433 /*
434 * My own fgets function. It handles all kinds of line terminators
435 * properly: LF (Unix), CRLF (DOS) and CR (Mac). In all cases, the
436 * terminator is replaced by a single LF
437 */
438
439 char * TOOLEXPORT
440 FP_fgets (char *buf, int n, FILE *stream)
441 {
442 char *obp = buf;
443 int c;
444
445 if (feof (stream))
446 return NULL;
447
448 while (--n) {
449 if ((c = fgetc (stream)) == EOF) {
450 if (ferror (stream))
451 return NULL;
452 else {
453 if (obp == buf)
454 return NULL;
455 *buf = '\0';
456 return obp;
457 }
458 }
459 if (c == '\015') { /* CR */
460 /*
461 * Peek next character. If it's no LF, push it back.
462 * ungetc(EOF, stream) is handled correctly according
463 * to the manual page
464 */
465 if ((c = fgetc (stream)) != '\012')
466 if (!feof (stream))
467 ungetc (c, stream);
468 *buf++ = '\012';
469 *buf = '\0';
470 return obp;
471 }
472 else if (c == '\012') { /* LF */
473 *buf++ = '\012';
474 *buf = '\0';
475 return obp;
476 }
477 /*
478 * just another standard character
479 */
480 *buf++ = c;
481 }
482 /*
483 * n-1 characters already transferred
484 */
485 *buf = '\0';
486
487 return obp;
488 }
489
490 /*
491 * A replacement strerror function that just returns the error code
492 */
493
494 char * TOOLEXPORT
495 FP_strerror (int errcode)
496 {
497 static char number[8];
498
499 sprintf (number, "%03d", errcode);
500
501 return number;
502 }
503
504 /*
505 * tempnam is not ANSI, but tmpnam is. Ignore the prefix here.
506 */
507
508 char * TOOLEXPORT
509 FP_tempnam (char *dir, char *pfx)
510 {
511 return FP_strdup (tmpnam (NULL));
512 }