view lib-src/b2m.c @ 5015:d95c102a96d3

cleanups for specifier font stages, from ben-unicode-internal (preparation for eliminating shadowed warnings) -------------------- ChangeLog entries follow: -------------------- src/ChangeLog addition: 2010-02-08 Ben Wing <ben@xemacs.org> * faces.c: * faces.c (face_property_matching_instance): * faces.c (ensure_face_cachel_contains_charset): * faces.h (FACE_FONT): * lisp.h: * lisp.h (enum font_specifier_matchspec_stages): * objects-msw.c: * objects-msw.c (mswindows_font_spec_matches_charset): * objects-msw.c (mswindows_find_charset_font): * objects-tty.c: * objects-tty.c (tty_font_spec_matches_charset): * objects-tty.c (tty_find_charset_font): * objects-xlike-inc.c: * objects-xlike-inc.c (XFUN): * objects-xlike-inc.c (xft_find_charset_font): * objects.c: * objects.c (font_instantiate): * objects.c (FROB): * specifier.c: * specifier.c (charset_matches_specifier_tag_set_p): * specifier.c (call_charset_predicate): * specifier.c (define_specifier_tag): * specifier.c (Fdefine_specifier_tag): * specifier.c (setup_charset_initial_specifier_tags): * specifier.c (specifier_instance_from_inst_list): * specifier.c (FROB): * specifier.c (vars_of_specifier): * specifier.h: Rename the specifier-font-matching stages in preparation for eliminating shadowed warnings, some other related fixes from ben-unicode-internal. 1. Rename raw enums: initial -> STAGE_INITIAL final -> STAGE_FINAL impossible -> NUM_MATCHSPEC_STAGES 2. Move `enum font_specifier_matchspec_stages' from specifier.h to lisp.h. 3. Whitespace changes to match coding standards. 4. Eliminate unused second argument STAGE in charset predicates that don't use it -- the code that calls the charset predicates is now smart enough to supply the right number of arguments automatically. 5. Add some long(ish) comments and authorial notices, esp. in objects.c. 6. In specifier.c, change Vcharset_tag_lists from a vector over leading bytes to a hash table over charsets. This change is unnecessary currently but doesn't hurt and will be required when we merge in Unicode-internal. 7. In specifier.c, extract out the code that calls charset predicates into a function call_charset_predicate().
author Ben Wing <ben@xemacs.org>
date Mon, 08 Feb 2010 16:51:25 -0600
parents abe6d1db359e
children 061f4f90f874
line wrap: on
line source

/*
 * b2m - a filter for Babyl -> Unix mail files
 *
 * usage:	b2m < babyl > mailbox
 *
 * I find this useful whenever I have to use a
 * system which - shock horror! - doesn't run
 * Gnu emacs. At least now I can read all my
 * Gnumacs Babyl format mail files!
 *
 * it's not much but it's free!
 *
 *   Ed Wilkinson
 *   E.Wilkinson@massey.ac.nz
 *   Mon Nov 7 15:54:06 PDT 1988
 */

/* Made conformant to the GNU coding standards January, 1995
   by Francesco Potorti` <pot@cnuce.cnr.it>. */

#ifdef HAVE_CONFIG_H
#include <config.h>
/* 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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#ifdef WIN32_NATIVE
#include <fcntl.h>
#endif

#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 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;
};


static long *xmalloc (unsigned int);
static long *xrealloc (void *, unsigned int);
static char *concat (char *s1, char *s2, char *s3);
static long readline (struct linebuffer *, FILE *);
static void fatal (char *);

/*
 * xnew -- allocate storage.  SYNOPSIS: Type *xnew (int n, Type);
 */
#define xnew(n, Type)	((Type *) xmalloc ((n) * sizeof (Type)))



char *progname;

int
main (int argc, char *argv[])
{
  logical labels_saved, printing, header;
  time_t ltoday;
  char *labels = NULL, *p, *today;
  struct linebuffer data;

#ifdef WIN32_NATIVE
  _fmode = O_BINARY;		/* all of files are treated as binary files */
  if (!isatty (fileno (stdout)))
    setmode (fileno (stdout), O_BINARY);
  if (!isatty (fileno (stdin)))
    setmode (fileno (stdin), O_BINARY);
#endif
  progname = argv[0];

  if (argc != 1)
    {
      fprintf (stderr, "Usage: %s <babylmailbox >unixmailbox\n", progname);
      exit (GOOD);
    }
  labels_saved = printing = header = FALSE;
  ltoday = time (0);
  today = ctime (&ltoday);
  data.size = 200;
  data.buffer = xnew (200, char);

  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 (streq (data.buffer, "*** EOOH ***") && !printing)
	{
	  printing = header = TRUE;
	  printf ("From \"Babyl to mail by %s\" %s", progname, today);
	  continue;
	}

      if (data.buffer[0] == '\037')
	{
	  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")))
		labels = concat (labels, p, ", ");

	      p = &labels[strlen (labels) - 2];
	      if (*p == ',')
		*p = '\0';
	      printing = header = FALSE;
	      labels_saved = TRUE;
	      continue;
	    }
	}

      if ((data.buffer[0] == '\0') && header)
	{
	  header = FALSE;
	  if (labels_saved)
	    puts (labels);
	}

      if (printing)
	puts (data.buffer);
    }
  return 0;
}



/*
 * Return a newly-allocated string whose contents
 * concatenate those of s1, s2, s3.
 */
static char *
concat (char *s1, char *s2, char *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.
 */
static long
readline (struct linebuffer *linebuffer, 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)
	{
	  linebuffer->size *= 2;
	  buffer = (char *) xrealloc (buffer, linebuffer->size);
	  p += buffer - linebuffer->buffer;
	  pend = buffer + linebuffer->size;
	  linebuffer->buffer = buffer;
	}
      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 (p - buffer + chars_deleted);
}

/*
 * Like malloc but get fatal error if memory is exhausted.
 */
static long *
xmalloc (unsigned int size)
{
  long *result = (long *) malloc (size);
  if (result == NULL)
    fatal ("virtual memory exhausted");
  return result;
}

static long *
xrealloc (void *ptr, unsigned int size)
{
  long *result = (long *) realloc (ptr, size);
  if (result == NULL)
    fatal ("virtual memory exhausted");
  return result;
}

static void
fatal (char *message)
{
  fprintf (stderr, "%s: %s\n", progname, message);
  exit (BAD);
}