# HG changeset patch # User Richard M. Stallman # Date 789676282 0 # Node ID 4b1c8dc724e64a95919c6b368c221eaa645ce125 # Parent 1b6d44607114914fb3be5b5b81491c1ad17c1333 (concat, xmalloc, xrealloc, readline, xnew): Four new functions and a macro that allow the program to work on input lines of whatever length. Copied from etags.c. (fatal): Print a fatal error message and exit. (main): Use the new functions. Fixed a bug that made a \037 char appear at the end of the output. diff -r 1b6d44607114 -r 4b1c8dc724e6 lib-src/b2m.c --- a/lib-src/b2m.c Mon Jan 09 18:27:32 1995 +0000 +++ b/lib-src/b2m.c Mon Jan 09 18:31:22 1995 +0000 @@ -15,6 +15,9 @@ * Mon Nov 7 15:54:06 PDT 1988 */ +/* Made conformant to the GNU coding standards January, 1995 + by Francesco Potorti` . */ + #include #include #include @@ -22,101 +25,233 @@ #include #endif -#include <../src/config.h> - -/* BSD's strings.h does not declare the type of strtok. */ -extern char *strtok (); +#ifdef HAVE_CONFIG_H +#include +/* On some systems, Emacs defines static as nothing for the sake + of unexec. We don't want that here since we don't use unexec. */ +#undef static +#endif -#ifndef TRUE -#define TRUE (1) -#endif -#ifndef FALSE -#define FALSE (0) +#undef TRUE +#define TRUE 1 +#undef FALSE +#define FALSE 0 + +/* Exit codes for success and failure. */ +#ifdef VMS +#define GOOD 1 +#define BAD 0 +#else +#define GOOD 0 +#define BAD 1 #endif -#define MAX_DATA_LEN 256 /* size for from[], labels[], and data[] arrays */ +#define streq(s,t) (strcmp (s, t) == 0) +#define strneq(s,t,n) (strncmp (s, t, n) == 0) + +typedef int logical; + +/* + * A `struct linebuffer' is a structure which holds a line of text. + * `readline' reads a line from a stream into a linebuffer and works + * regardless of the length of the line. + */ +struct linebuffer +{ + long size; + char *buffer; +}; -int header = FALSE, printing; -time_t ltoday; -char from[MAX_DATA_LEN], labels[MAX_DATA_LEN], data[MAX_DATA_LEN], *p, *today; +extern char *strtok(); + +char *xmalloc (), *xrealloc (); +char *concat (); +long readline (); +void fatal (); -int +/* + * xnew -- allocate storage. SYNOPSIS: Type *xnew (int n, Type); + */ +#define xnew(n, Type) ((Type *) xmalloc ((n) * sizeof (Type))) + + + +char *progname; + main (argc, argv) int argc; char **argv; { + logical labels_saved, printing, header; + time_t ltoday; + char *labels, *p, *today; + struct linebuffer data; + #ifdef MSDOS _fmode = O_BINARY; /* all of files are treated as binary files */ (stdout)->_flag &= ~_IOTEXT; (stdin)->_flag &= ~_IOTEXT; #endif - if (argc >= 2 && strcmp (argv[1], "--help") == 0) + if (argc != 1) { - fprintf (stderr, "Usage: %s unixmailbox\n", argv[0]); - exit (0); + fprintf (stderr, "Usage: %s unixmailbox\n", progname); + exit (GOOD); } + labels_saved = printing = header = FALSE; + progname = argv[0]; ltoday = time (0); today = ctime (<oday); + data.size = 200; + data.buffer = xnew (200, char); - if (fgets (data, MAX_DATA_LEN, stdin)) + if (readline (&data, stdin) == 0 + || !strneq (data.buffer, "BABYL OPTIONS:", 14)) + fatal ("standard input is not a Babyl mailfile."); + + while (readline (&data, stdin) > 0) { - if (strncmp (data, "BABYL OPTIONS:", 14)) - { - fprintf (stderr, "%s: not a Babyl mailfile!\n", argv[0]); - exit (-1); - } - else - printing = FALSE; - } - else - exit (-1); - if (printing) - puts (data); - - while (fgets (data, MAX_DATA_LEN, stdin)) - { - -#if 0 - /* What was this for? Does somebody have something against blank - lines? */ - if (!strcmp (data, "")) - exit (0); -#endif - - if (!strcmp (data, "*** EOOH ***") && !printing) + if (streq (data.buffer, "*** EOOH ***") && !printing) { printing = header = TRUE; - printf ("From %s %s", argv[0], today); + printf ("From Babyl to mail by %s %s", progname, today); continue; } - if (!strcmp (data, "\037\f")) + if (data.buffer[0] == '\037') { - /* save labels */ - fgets (data, MAX_DATA_LEN, stdin); - p = strtok (data, " ,\r\n\t"); - strcpy (labels, "X-Babyl-Labels: "); + if (data.buffer[1] == '\0') + continue; + else if (data.buffer[1] == '\f') + { + /* Save labels. */ + readline (&data, stdin); + p = strtok (data.buffer, " ,\r\n\t"); + labels = "X-Babyl-Labels: "; - while (p = strtok (NULL, " ,\r\n\t")) - { - strcat (labels, p); - strcat (labels, ", "); + while (p = strtok (NULL, " ,\r\n\t")) + labels = concat (labels, p, ", "); + + labels[strlen (labels) - 2] = '\0'; + printing = header = FALSE; + labels_saved = TRUE; + continue; } + } - labels[strlen (labels) - 2] = '\0'; - printing = header = FALSE; - continue; + if ((data.buffer[0] == '\0') && header) + { + header = FALSE; + if (labels_saved) + puts (labels); } - if (!strlen (data) && header) + if (printing) + puts (data.buffer); + } +} + + + +/* + * Return a newly-allocated string whose contents + * concatenate those of s1, s2, s3. + */ +char * +concat (s1, s2, s3) + char *s1, *s2, *s3; +{ + int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3); + char *result = xnew (len1 + len2 + len3 + 1, char); + + strcpy (result, s1); + strcpy (result + len1, s2); + strcpy (result + len1 + len2, s3); + result[len1 + len2 + len3] = '\0'; + + return result; +} + +/* + * Read a line of text from `stream' into `linebuffer'. + * Return the number of characters read from `stream', + * which is the length of the line including the newline, if any. + */ +long +readline (linebuffer, stream) + struct linebuffer *linebuffer; + register FILE *stream; +{ + char *buffer = linebuffer->buffer; + register char *p = linebuffer->buffer; + register char *pend; + int chars_deleted; + + pend = p + linebuffer->size; /* Separate to avoid 386/IX compiler bug. */ + + while (1) + { + register int c = getc (stream); + if (p == pend) { - header = FALSE; - if (strcmp (labels, "X-Babyl-Labels")) - puts (labels); + linebuffer->size *= 2; + buffer = (char *) xrealloc (buffer, linebuffer->size); + p += buffer - linebuffer->buffer; + pend = buffer + linebuffer->size; + linebuffer->buffer = buffer; } - - if (printing) - puts (data); + if (c == EOF) + { + chars_deleted = 0; + break; + } + if (c == '\n') + { + if (p[-1] == '\r' && p > buffer) + { + *--p = '\0'; + chars_deleted = 2; + } + else + { + *p = '\0'; + chars_deleted = 1; + } + break; + } + *p++ = c; } - return 0; + + return (p - buffer + chars_deleted); +} + +/* + * Like malloc but get fatal error if memory is exhausted. + */ +char * +xmalloc (size) + unsigned int size; +{ + char *result = (char *) malloc (size); + if (result == NULL) + fatal ("virtual memory exhausted"); + return result; } + +char * +xrealloc (ptr, size) + char *ptr; + unsigned int size; +{ + char *result = (char *) realloc (ptr, size); + if (result == NULL) + fatal ("virtual memory exhausted"); + return result; +} + +void +fatal (message) +{ + fprintf (stderr, "%s: %s\n", progname, message); + exit (BAD); +} +