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 (20 months, 1 week ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.18: +0 -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 /*
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 FP_free (void *ptr)
75 {
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 FP_strdup (char *string)
85 {
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 FP_strncpy (char *dest, char *src, int length)
106 {
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 FP_memdup (const void *ptr, int len)
124 {
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 #ifndef FP_stricmp
142 int TOOLEXPORT
143 FP_stricmp (const char *str1, const char *str2)
144 {
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 #endif
157
158 #ifndef FP_strnicmp
159 int TOOLEXPORT
160 FP_strnicmp (const char *str1, const char *str2, int count)
161 {
162 int d;
163
164 if (!str1 || !str2)
165 return -1;
166
167 while (count--) {
168 if (!*str1)
169 return -1;
170
171 d = tolower (*str1) - tolower (*str2);
172 if (d)
173 return d;
174
175 str1++;
176 str2++;
177 }
178
179 return 0;
180 }
181 #endif
182
183 int TOOLEXPORT
184 FP_strnicmp_fast (const char *str1, const char *str2, int count)
185 {
186 if (!str1 || !str2)
187 return -1;
188
189 while (count--) {
190 if (!*str1)
191 return -1;
192
193 if ((*str1 ^ *str2) & 0xdf)
194 return (*str1 & 0xdf) - (*str2 & 0xdf);
195
196 str1++;
197 str2++;
198 }
199
200 return 0;
201 }
202
203 char * TOOLEXPORT
204 FP_strpbrk (char *str, char *accept)
205 {
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 FP_strtok (char *str1, char *str2)
227 {
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 #ifndef FP_stristr
263 char * TOOLEXPORT
264 FP_stristr (char *str1, char *str2)
265 {
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 #endif
286
287 /*
288 * Nice fake of the real (non-standard) one
289 */
290
291 char * TOOLEXPORT
292 FP_strrstr (const char *ptr, const char *str)
293 {
294 const char *found=NULL, *new, *iter=ptr;
295
296 if (ptr==NULL || str==NULL)
297 return NULL;
298
299 if (*str == '\0')
300 return (char *)ptr;
301
302 while ((new = FP_strstr (iter, str)) != NULL) {
303 found = new;
304 iter = new + 1;
305 }
306
307 return (char *)found;
308 }
309
310 char * TOOLEXPORT
311 FP_strirstr (char *ptr, char *str)
312 {
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 while ((new = FP_stristr (iter, str)) != NULL) {
321 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 FP_stoupper (char *input)
333 {
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 FP_stolower (char *input)
348 {
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 FP_strmatch (char *string, char *pattern)
367 {
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 FP_strrchr (const char *string, int tc)
397 {
398 const char *ptr;
399
400 if (string == NULL || !*string)
401 return NULL;
402
403 ptr = string + strlen (string) - 1;
404
405 while (ptr != string && *ptr != tc)
406 ptr--;
407
408 if (*ptr == tc)
409 return (char *)ptr;
410
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 FP_cutdir (char *filename)
421 {
422 char *ptr;
423
424 if (filename == NULL)
425 return NULL;
426
427 if ((ptr = FP_strrchr (filename, '/')) != NULL)
428 ptr++;
429 else if ((ptr = FP_strrchr (filename, '\\')) != NULL)
430 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 * properly: LF (Unix), CRLF (DOS) and CR (Mac).
440 */
441 /* (schmorp) the buffer is always written to, and no LF is stored at the end */
442 /* also, if the buffer is too short, the remaining line is skipped */
443 ecb_hot char * TOOLEXPORT
444 FP_fgets (char *buf, int n, FILE *stream)
445 {
446 char *ptr = buf;
447 char *end = buf + n - 1;
448
449 /* shield against buffer overflows caused by "255 - bytes_left"-kind of bugs when bytes_left > 255 */
450 if (n <= 0)
451 return 0;
452
453 for (;;)
454 {
455 int c = FP_getc (stream);
456
457 if (ecb_expect_false (c <= '\015')) /* EOF is < 0x20, too */
458 {
459 /* ctlchar */
460
461 if (c == '\012')
462 /* LF, nothing following */
463 break;
464 else if (c == '\015')
465 {
466 /* CR, possibly CRLF, skip following LF */
467 c = FP_getc (stream);
468
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 }
480
481 *ptr = c;
482 ptr += ptr < end; /* this is hopefully branch-free, and fast */
483 }
484
485 *ptr = 0;
486 return buf;
487 }
488