… | |
… | |
62 | return TRUE; |
62 | return TRUE; |
63 | } |
63 | } |
64 | #endif |
64 | #endif |
65 | #endif |
65 | #endif |
66 | |
66 | |
67 | char * fptools_id = "$Id: fptools.c,v 1.8 2004/04/18 20:08:11 root Exp $"; |
67 | char * fptools_id = "$Id: fptools.c,v 1.9 2009/08/24 04:38:23 root Exp $"; |
68 | |
68 | |
69 | /* |
69 | /* |
70 | * some versions of free can't handle a NULL pointer properly |
70 | * some versions of free can't handle a NULL pointer properly |
71 | * (ANSI says, free ignores a NULL pointer, but some machines |
71 | * (ANSI says, free ignores a NULL pointer, but some machines |
72 | * prefer to SIGSEGV on it) |
72 | * prefer to SIGSEGV on it) |
… | |
… | |
427 | ptr = filename; |
427 | ptr = filename; |
428 | |
428 | |
429 | return ptr; |
429 | return ptr; |
430 | } |
430 | } |
431 | |
431 | |
|
|
432 | #if HAVE_FGETC_UNLOCKED |
|
|
433 | # define _FP_fgetc(s) fgetc_unlocked (s) |
|
|
434 | #else |
|
|
435 | # define _FP_fgetc(s) fgetc (s) |
|
|
436 | #endif |
|
|
437 | |
432 | /* |
438 | /* |
433 | * My own fgets function. It handles all kinds of line terminators |
439 | * My own fgets function. It handles all kinds of line terminators |
434 | * properly: LF (Unix), CRLF (DOS) and CR (Mac). In all cases, the |
440 | * properly: LF (Unix), CRLF (DOS) and CR (Mac). |
435 | * terminator is replaced by a single LF |
|
|
436 | */ |
441 | */ |
437 | |
442 | /* (schmorp) the buffer is always written to, and no LF is stored at the end */ |
438 | char * TOOLEXPORT |
443 | char * TOOLEXPORT |
439 | _FP_fgets (char *buf, int n, FILE *stream) |
444 | _FP_fgets (char *buf, int n, FILE *stream) |
440 | { |
445 | { |
|
|
446 | static char format[64]; |
|
|
447 | static int format_n = 0; |
441 | char *obp = buf; |
448 | char *cp = buf; |
|
|
449 | int res; |
442 | int c; |
450 | int c; |
443 | |
451 | |
444 | /* shield against buffer overflows caused by "255 - bytes_left"-kind of bugs when bytes_left > 255 */ |
452 | /* shield against buffer overflows caused by "255 - bytes_left"-kind of bugs when bytes_left > 255 */ |
445 | if (n <= 0) |
453 | if (n <= 0) |
446 | return NULL; |
454 | return NULL; |
447 | |
455 | |
448 | if (feof (stream)) |
456 | if (format_n != n) |
449 | return NULL; |
457 | { |
450 | |
458 | sprintf (format, "%%%d[^\015\012]", n - 1); |
451 | while (--n && !feof (stream)) { |
459 | format_n = n; |
452 | if ((c = fgetc (stream)) == EOF) { |
|
|
453 | if (ferror (stream)) |
|
|
454 | return NULL; |
|
|
455 | else { |
|
|
456 | if (obp == buf) |
|
|
457 | return NULL; |
|
|
458 | *buf = '\0'; |
|
|
459 | return obp; |
|
|
460 | } |
|
|
461 | } |
460 | } |
|
|
461 | |
|
|
462 | *buf = 0; /* fscanf return s0 on empty lines */ |
|
|
463 | res = fscanf (stream, format, buf); |
|
|
464 | |
|
|
465 | if (res == EOF) |
|
|
466 | return 0; /* an error occured */ |
|
|
467 | |
|
|
468 | for (;;) |
|
|
469 | { |
|
|
470 | c = _FP_fgetc (stream); |
|
|
471 | |
|
|
472 | if (c == '\012') /* LF */ |
|
|
473 | return buf; |
462 | if (c == '\015') { /* CR */ |
474 | else if (c == '\015') /* CR */ |
463 | /* |
|
|
464 | * Peek next character. If it's no LF, push it back. |
|
|
465 | * ungetc(EOF, stream) is handled correctly according |
|
|
466 | * to the manual page |
|
|
467 | */ |
475 | { |
468 | if ((c = fgetc (stream)) != '\012') |
476 | c = _FP_fgetc (stream); |
469 | if (!feof (stream)) |
477 | if (c != '\012') /* CR LF? */ |
470 | ungetc (c, stream); |
478 | ungetc (c, stream); |
471 | *buf++ = '\012'; |
479 | |
472 | *buf = '\0'; |
|
|
473 | return obp; |
480 | return buf; |
|
|
481 | } |
|
|
482 | else if (c == EOF) |
|
|
483 | return 0; /* error */ |
|
|
484 | |
|
|
485 | /* skip remaining line */ |
474 | } |
486 | } |
475 | else if (c == '\012') { /* LF */ |
|
|
476 | *buf++ = '\012'; |
|
|
477 | *buf = '\0'; |
|
|
478 | return obp; |
|
|
479 | } |
|
|
480 | /* |
|
|
481 | * just another standard character |
|
|
482 | */ |
|
|
483 | *buf++ = c; |
|
|
484 | } |
|
|
485 | |
|
|
486 | /* |
|
|
487 | * n-1 characters already transferred |
|
|
488 | */ |
|
|
489 | |
|
|
490 | *buf = '\0'; |
|
|
491 | |
|
|
492 | /* |
|
|
493 | * If a line break is coming up, read it |
|
|
494 | */ |
|
|
495 | |
|
|
496 | if (!feof (stream)) { |
|
|
497 | if ((c = fgetc (stream)) == '\015' && !feof (stream)) { |
|
|
498 | if ((c = fgetc (stream)) != '\012' && !feof (stream)) { |
|
|
499 | ungetc (c, stream); |
|
|
500 | } |
|
|
501 | } |
|
|
502 | else if (c != '\012' && !feof (stream)) { |
|
|
503 | ungetc (c, stream); |
|
|
504 | } |
|
|
505 | } |
|
|
506 | |
|
|
507 | return obp; |
|
|
508 | } |
487 | } |
509 | |
488 | |
510 | /* |
489 | /* |
511 | * A replacement strerror function that just returns the error code |
490 | * A replacement strerror function that just returns the error code |
512 | */ |
491 | */ |