ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Convert-UUlib/uulib/fptools.c
Revision: 1.12
Committed: Fri Feb 14 08:02:26 2020 UTC (4 years, 3 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-1_71, rel-1_7, rel-1_62
Changes since 1.11: +30 -29 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$";
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 #ifndef FP_stricmp
144 int TOOLEXPORT
145 _FP_stricmp (const char *str1, const 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 #endif
159
160 #ifndef FP_strnicmp
161 int TOOLEXPORT
162 _FP_strnicmp (const char *str1, const char *str2, int count)
163 {
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 #endif
177
178 char * TOOLEXPORT
179 _FP_strpbrk (char *str, char *accept)
180 {
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 _FP_strtok (char *str1, char *str2)
202 {
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 #ifndef FP_stristr
238 char * TOOLEXPORT
239 _FP_stristr (char *str1, char *str2)
240 {
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 #endif
261
262 /*
263 * Nice fake of the real (non-standard) one
264 */
265
266 char * TOOLEXPORT
267 _FP_strrstr (char *ptr, char *str)
268 {
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 while ((new = _FP_strstr (iter, str)) != NULL) {
278 found = new;
279 iter = new + 1;
280 }
281 return found;
282 }
283
284 char * TOOLEXPORT
285 _FP_strirstr (char *ptr, char *str)
286 {
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 while ((new = _FP_stristr (iter, str)) != NULL) {
295 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 _FP_stoupper (char *input)
307 {
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 _FP_stolower (char *input)
322 {
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 _FP_strmatch (char *string, char *pattern)
341 {
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 _FP_strrchr (char *string, int tc)
371 {
372 char *ptr;
373
374 if (string == NULL || !*string)
375 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 _FP_cutdir (char *filename)
395 {
396 char *ptr;
397
398 if (filename == NULL)
399 return NULL;
400
401 if ((ptr = _FP_strrchr (filename, '/')) != NULL)
402 ptr++;
403 else if ((ptr = _FP_strrchr (filename, '\\')) != NULL)
404 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 * properly: LF (Unix), CRLF (DOS) and CR (Mac).
414 */
415 /* (schmorp) the buffer is always written to, and no LF is stored at the end */
416 /* also, if the buffer is too short, the remaining line is skipped */
417 char * TOOLEXPORT
418 _FP_fgets (char *buf, int n, FILE *stream)
419 {
420 char *ptr = buf;
421 char *end = buf + n - 1;
422
423 /* shield against buffer overflows caused by "255 - bytes_left"-kind of bugs when bytes_left > 255 */
424 if (n <= 0)
425 return 0;
426
427 for (;;)
428 {
429 int c = FP_fgetc (stream);
430
431 if (ecb_expect_false (c <= '\015')) /* EOF is < 0x20, too */
432 {
433 /* ctlchar */
434
435 if (c == '\012')
436 /* LF, nothing following */
437 break;
438 else if (c == '\015')
439 {
440 /* CR, possibly CRLF, skip following LF */
441 c = FP_fgetc (stream);
442
443 if (c != '\012') /* CR LF? */
444 ungetc (c, stream);
445
446 break;
447 }
448 else if (c == EOF)
449 {
450 *ptr = 0;
451 return 0;
452 }
453 }
454
455 *ptr = c;
456 ptr += ptr < end; /* this is hopefully branch-free, and fast */
457 }
458
459 *ptr = 0;
460 return buf;
461 }
462
463 /*
464 * A replacement strerror function that just returns the error code
465 */
466
467 char * TOOLEXPORT
468 _FP_strerror (int errcode)
469 {
470 static char number[8];
471
472 sprintf (number, "%03d", errcode);
473
474 return number;
475 }
476 #ifndef HAVE_MKSTEMP
477 /*
478 * tempnam is not ANSI, but tmpnam is. Ignore the prefix here.
479 */
480
481 char * TOOLEXPORT
482 _FP_tempnam (char *dir, char *pfx)
483 {
484 return _FP_strdup (tmpnam (NULL));
485 }
486 #endif /* HAVE_MKSTEMP */