Logo Search packages:      
Sourcecode: yodl version File versions  Download package

gramdefinechartable.c

#include "yodl.h"

static int
escapechar (char const *str)  /* convert escaped char */
{
  switch (*str)
    {
    case 'a':
      return ('\a');
    case 'b':
      return ('\b');
    case 'f':
      return ('\f');
    case 'n':
      return ('\n');
    case 'r':
      return ('\r');
    case 't':
      return ('\t');
    case 'v':
      return ('\v');
    default:
      return ((unsigned char)*str);
    }
}

static int
string_to_char (char const *str)    /* convert 'charspec' */
{
  if (*str != '\'')
    return (0);

  str++;
  if (!*str)
    return (0);

  if (*str != '\\')
    return ((unsigned char)*str);

  str++;
  if (!*str)
    return (0);

  return (escapechar (str));
}

static char *
string_to_string (char const *str)  /* convert escape string */
{
  char
   *ret = 0;

  while (*str)
    {
      if (*str == '\\')       /* escape sequence */
      {
        str++;
        ret = str_addchar (ret, escapechar (str));
      }
      else
      ret = str_addchar (ret, *str);

      if (*str)
      str++;
    }

  return (ret);
}

void
parse_table (char *table, CHARTAB * dest)
{
  char
   *line, **lines = 0, **charp = 0, *newchar, **redefp = 0, *newredef;
  int
    i, chindex, redeflen, nlines = 0, ncharp = 0, nredefp = 0;

  line = strtok (table, "\n");
  while (line)
    {
      lines = strarr_add (lines, &nlines, line);
      line = strtok (0, "\n");
    }

  for (i = 0; i < nlines; i++)
    {
      newchar = strtok (lines[i], "=");
      if (!newchar)
      error_gram (builtin_get (idx_DEFINECHARTABLE),
                "missing character specifier in line %s", lines[i]);
      while (isspace ((int)*newchar))
      newchar++;
      newredef = strtok (0, "=");
      if (!newredef)
      error_gram (builtin_get (idx_DEFINECHARTABLE),
                "missing redefinition specifier in line %s", lines[i]);
      while (isspace ((int)*newredef))
      newredef++;

      charp = strarr_add (charp, &ncharp, newchar);
      redefp = strarr_add (redefp, &nredefp, newredef);
    }

  for (i = 0; i < nlines; i++)
    {
      if ((chindex = string_to_char (charp[i])) == -1)
      error_gram (builtin_get (idx_DEFINECHARTABLE),
                "at %s: expected 'c' character specifier", charp[i]);

      if (*redefp[i] != '"' || !*(redefp[i] + 1))
      error_gram (builtin_get (idx_DEFINECHARTABLE),
                "redefinition %s: must have form \"redef\"", redefp);
      strcpy (redefp[i], redefp[i] + 1);
      redeflen = strlen (redefp[i]) - 1;
      if (redefp[i][redeflen] != '"')
      error_gram (builtin_get (idx_DEFINECHARTABLE),
                "redefinition %s: unterminated string", redefp[i]);
      redefp[i][redeflen] = '\0';

      (*dest)[chindex] = string_to_string (redefp[i]);
    }

  strarr_free (lines, nlines);
  strarr_free (charp, ncharp);
  strarr_free (redefp, nredefp);
}

void
gram_DEFINECHARTABLE ()
{
  char
   *tabname,                  /* table name */
   *table;              /* table itself */
  int
    i;                        /* index in chartab */
  CHARTAB
    * dest;             /* new table to define */
  static char
    buf[2];             /* conversion buf */


  tabname =             /* retrieve table name */
    gram_parlist (builtin_get (idx_DEFINECHARTABLE), 0);
  gram_onename (builtin_get (idx_DEFINECHARTABLE), tabname);

  message (3, "%s %s\n", builtin_get (idx_DEFINECHARTABLE), tabname);

  while (lextok == tok_space ||     /* skip spaces, newlines */
       lextok == tok_newline
    )
    lexer ();

  table =               /* retrieve table itself */
    gram_parlist (builtin_get (idx_DEFINECHARTABLE), 0);
  if (!table || !*table)      /* may not be empty */
    error_gram (builtin_get (idx_DEFINECHARTABLE),
            "empty table definition for table %s", tabname);

  /* table already defined? */
  if (strtab_find (chartabname, nchartab, tabname) != -1)
    error_gram (builtin_get (idx_DEFINECHARTABLE),
            "table %s already defined", tabname);

  i = curchartab - chartab;   /* remember current */

  /* make new table */
  chartabname = strtab_add (chartabname, &nchartab, tabname);
  chartab = (CHARTAB *) xrealloc (chartab, nchartab * sizeof (CHARTAB));

  if (curchartab)       /* restore current */
    curchartab = chartab + i;

  dest = chartab + nchartab - 1;    /* destination of new */

  for (i = 0; i < 256; i++)   /* reset table to defaults */
    {
      buf[0] = (char) i;
      (*dest)[i] = xstrdup (buf);
    }

  parse_table (table, dest);

  free (tabname);
  free (table);
}

Generated by  Doxygen 1.6.0   Back to index