Exemple #1
0
static void
collect_arguments (symbol *sym, struct obstack *argptr,
                   struct obstack *arguments)
{
  token_data td;
  token_data *tdp;
  bool more_args;
  bool groks_macro_args = SYMBOL_MACRO_ARGS (sym);

  TOKEN_DATA_TYPE (&td) = TOKEN_TEXT;
  TOKEN_DATA_TEXT (&td) = SYMBOL_NAME (sym);
  tdp = (token_data *) obstack_copy (arguments, &td, sizeof td);
  obstack_ptr_grow (argptr, tdp);

  if (peek_token () == TOKEN_OPEN)
    {
      next_token (&td, NULL); /* gobble parenthesis */
      do
        {
          more_args = expand_argument (arguments, &td);

          if (!groks_macro_args && TOKEN_DATA_TYPE (&td) == TOKEN_FUNC)
            {
              TOKEN_DATA_TYPE (&td) = TOKEN_TEXT;
              TOKEN_DATA_TEXT (&td) = (char *) "";
            }
          tdp = (token_data *) obstack_copy (arguments, &td, sizeof td);
          obstack_ptr_grow (argptr, tdp);
        }
      while (more_args);
    }
}
Exemple #2
0
const char *
predefined_attribute (const char *key, int *ptr_argc, token_data **argv,
                      boolean lowercase)
{
  var_stack *next;
  char *cp, *sp, *lower;
  int i, j, special_chars;
  boolean found = FALSE;

  i = 1;
  while (i<*ptr_argc)
    {
      special_chars = 0;
      sp = TOKEN_DATA_TEXT (argv[i]);
      while (IS_GROUP (*sp))
        {
          sp++;
          special_chars++;
        }

      cp = strchr (sp, '=');
      if ((cp == NULL && strcasecmp (sp, key) == 0) ||
          (cp != NULL && strncasecmp (sp, key, strlen (key)) == 0
               && *(sp + strlen (key)) == '='))
        {
          found = TRUE;
          next = (var_stack *) xmalloc (sizeof (var_stack));
          next->prev = tag_attr;
          if (cp)
            {
              next->text = (char *) xmalloc (special_chars + strlen (cp+1) + 1);
              if (special_chars)
                strncpy (next->text, TOKEN_DATA_TEXT (argv[i]), special_chars);
              strcpy (next->text+special_chars, cp+1);
            }
          else
            next->text = xstrdup (key);
          tag_attr = next;

          if (lowercase)
            for (lower=tag_attr->text; *lower != '\0'; lower++)
              *lower = tolower (*lower);

          /* remove this attribute from argv[].  */
          for (j=i+1; j<=*ptr_argc; j++)
            argv[j-1] = argv[j];

          (*ptr_argc)--;
        }
      i++;
    }

  return (found ? tag_attr->text : NULL );
}
Exemple #3
0
static void
print_token (const char *s, token_type t, token_data *td)
{
  fprintf (stderr, "%s: ", s);
  switch (t)
    {				/* TOKSW */
    case TOKEN_SIMPLE:
      fprintf (stderr, "char:");
      break;

    case TOKEN_WORD:
      fprintf (stderr, "word:");
      break;

    case TOKEN_STRING:
      fprintf (stderr, "string:");
      break;

    case TOKEN_MACDEF:
      fprintf (stderr, "macro: 0x%x\n", TOKEN_DATA_FUNC (td));
      break;

    case TOKEN_EOF:
      fprintf (stderr, "eof\n");
      break;
    }
  fprintf (stderr, "\t\"%s\"\n", TOKEN_DATA_TEXT (td));
}
Exemple #4
0
const char *
push_string_finish (read_type expansion)
{
  const char *ret = NULL;

  if (next == NULL)
    return NULL;

  if (obstack_object_size (current_input) > 0)
    {
      obstack_1grow (current_input, '\0');
      next->u.u_s.start = (unsigned char *) obstack_finish (current_input);
      if (expansion == READ_ATTR_VERB || expansion == READ_ATTR_ASIS
          || expansion == READ_BODY)
        {
          TOKEN_DATA_TYPE (&token_read) = TOKEN_TEXT;
          TOKEN_DATA_TEXT (&token_read) = xstrdup ((char *) next->u.u_s.start);
          next->u.u_s.current = next->u.u_s.start + strlen ((char *) next->u.u_s.start);
        }
      else
        next->u.u_s.current = next->u.u_s.start;

      next->prev = isp;
      isp = next;
      ret = (char *) isp->u.u_s.start;   /* for immediate use only */
    }
  else
    obstack_free (current_input, next); /* people might leave garbage on it. */
  next = NULL;
  return ret;
}
Exemple #5
0
static void
expand_token (struct obstack *obs, token_type t, token_data *td, int line)
{
  symbol *sym;

  switch (t)
    { /* TOKSW */
    case TOKEN_EOF:
    case TOKEN_MACDEF:
      break;

    case TOKEN_OPEN:
    case TOKEN_COMMA:
    case TOKEN_CLOSE:
    case TOKEN_SIMPLE:
    case TOKEN_STRING:
      shipout_text (obs, TOKEN_DATA_TEXT (td), strlen (TOKEN_DATA_TEXT (td)),
                    line);
      break;

    case TOKEN_WORD:
      sym = lookup_symbol (TOKEN_DATA_TEXT (td), SYMBOL_LOOKUP);
      if (sym == NULL || SYMBOL_TYPE (sym) == TOKEN_VOID
          || (SYMBOL_TYPE (sym) == TOKEN_FUNC
              && SYMBOL_BLIND_NO_ARGS (sym)
              && peek_token () != TOKEN_OPEN))
        {
#ifdef ENABLE_CHANGEWORD
          shipout_text (obs, TOKEN_DATA_ORIG_TEXT (td),
                        strlen (TOKEN_DATA_ORIG_TEXT (td)), line);
#else
          shipout_text (obs, TOKEN_DATA_TEXT (td),
                        strlen (TOKEN_DATA_TEXT (td)), line);
#endif
        }
      else
        expand_macro (sym);
      break;

    default:
      M4ERROR ((warning_status, 0,
                "INTERNAL ERROR: bad token type in expand_token ()"));
      abort ();
    }
}
Exemple #6
0
boolean
bad_argc (token_data *name, int argc, int min, int max)
{
  boolean isbad = FALSE;

  if (min > 0 && argc < min)
    {
      if (!suppress_warnings)
        MP4HERROR ((warning_status, 0,
          _("Warning:%s:%d: Too few arguments to built-in `%s'"),
               CURRENT_FILE_LINE, TOKEN_DATA_TEXT (name)));
      isbad = TRUE;
    }
  else if (max > 0 && argc > max && !suppress_warnings)
    {
      MP4HERROR ((warning_status, 0,
        _("Warning:%s:%d: Excess arguments to built-in `%s' ignored"),
             CURRENT_FILE_LINE, TOKEN_DATA_TEXT (name)));
    }

  return isbad;
}
Exemple #7
0
boolean
numeric_arg (token_data *macro, const char *arg, boolean warn, int *valuep)
{
  char *endp;

  if (*arg == 0 || (*valuep = strtol (skip_space (arg), &endp, 10),
                    *skip_space (endp) != 0))
    {
      if (warn)
        MP4HERROR ((warning_status, 0,
          _("Warning:%s:%d: Argument `%s' non-numeric in the <%s> tag"),
               CURRENT_FILE_LINE, arg, TOKEN_DATA_TEXT (macro)));
      return FALSE;
    }
  return TRUE;
}
Exemple #8
0
void
trace_pre (const char *name, int id, int argc, token_data **argv)
{
  int i;
  const builtin *bp;

  trace_header (id);
  trace_format ("%s", name);

  if (argc > 1 && (debug_level & DEBUG_TRACE_ARGS))
    {
      trace_format ("(");

      for (i = 1; i < argc; i++)
        {
          if (i != 1)
            trace_format (", ");

          switch (TOKEN_DATA_TYPE (argv[i]))
            {
            case TOKEN_TEXT:
              trace_format ("%l%S%r", TOKEN_DATA_TEXT (argv[i]));
              break;

            case TOKEN_FUNC:
              bp = find_builtin_by_addr (TOKEN_DATA_FUNC (argv[i]));
              if (bp == NULL)
                {
                  M4ERROR ((warning_status, 0, "\
INTERNAL ERROR: builtin not found in builtin table! (trace_pre ())"));
                  abort ();
                }
              trace_format ("<%s>", bp->name);
              break;

            case TOKEN_VOID:
            default:
              M4ERROR ((warning_status, 0,
                        "INTERNAL ERROR: bad token data type (trace_pre ())"));
              abort ();
            }

        }
Exemple #9
0
token_type
next_token (token_data *td)
{
  int ch;
  int quote_level;
  token_type type;
#ifdef ENABLE_CHANGEWORD
  int startpos;
  char *orig_text = 0;
#endif

  obstack_free (&token_stack, token_bottom);
  obstack_1grow (&token_stack, '\0');
  token_bottom = obstack_finish (&token_stack);

  ch = peek_input ();
  if (ch == CHAR_EOF)
    {
      return TOKEN_EOF;
#ifdef DEBUG_INPUT
      fprintf (stderr, "next_token -> EOF\n");
#endif
    }
  if (ch == CHAR_MACRO)
    {
      init_macro_token (td);
      (void) next_char ();
      return TOKEN_MACDEF;
    }

  (void) next_char ();
  if (MATCH (ch, bcomm.string))
    {
      obstack_grow (&token_stack, bcomm.string, bcomm.length);
      while ((ch = next_char ()) != CHAR_EOF && !MATCH (ch, ecomm.string))
	obstack_1grow (&token_stack, ch);
      if (ch != CHAR_EOF)
	obstack_grow (&token_stack, ecomm.string, ecomm.length);
      type = TOKEN_STRING;
    }
#ifdef ENABLE_CHANGEWORD
  else if (default_word_regexp && (isalpha (ch) || ch == '_'))
#else
  else if (isalpha (ch) || ch == '_')
#endif
    {
      obstack_1grow (&token_stack, ch);
      while ((ch = peek_input ()) != CHAR_EOF && (isalnum (ch) || ch == '_'))
	{
	  obstack_1grow (&token_stack, ch);
	  (void) next_char ();
	}
      type = TOKEN_WORD;
    }

#ifdef ENABLE_CHANGEWORD

  else if (!default_word_regexp && strchr (word_start, ch))
    {
      obstack_1grow (&token_stack, ch);
      while (1)
        {
	  ch = peek_input ();
	  if (ch == CHAR_EOF)
	    break;
	  obstack_1grow (&token_stack, ch);
	  startpos = re_search (&word_regexp, obstack_base (&token_stack),
				obstack_object_size (&token_stack), 0, 0,
				&regs);
	  if (startpos != 0 ||
	      regs.end [0] != obstack_object_size (&token_stack))
	    {
	      *(((char *) obstack_base (&token_stack)
		 + obstack_object_size (&token_stack)) - 1) = '\0';
	      break;
	    }
	  next_char ();
	}

      obstack_1grow (&token_stack, '\0');
      orig_text = obstack_finish (&token_stack);

      if (regs.start[1] != -1)
	obstack_grow (&token_stack,orig_text + regs.start[1],
		      regs.end[1] - regs.start[1]);
      else
	obstack_grow (&token_stack, orig_text,regs.end[0]);

      type = TOKEN_WORD;
    }

#endif /* ENABLE_CHANGEWORD */

  else if (!MATCH (ch, lquote.string))
    {
      type = TOKEN_SIMPLE;
      obstack_1grow (&token_stack, ch);
    }
  else
    {
      quote_level = 1;
      while (1)
	{
	  ch = next_char ();
	  if (ch == CHAR_EOF)
	    M4ERROR ((EXIT_FAILURE, 0,
		      "ERROR: EOF in string"));

	  if (MATCH (ch, rquote.string))
	    {
	      if (--quote_level == 0)
		break;
	      obstack_grow (&token_stack, rquote.string, rquote.length);
	    }
	  else if (MATCH (ch, lquote.string))
	    {
	      quote_level++;
	      obstack_grow (&token_stack, lquote.string, lquote.length);
	    }
	  else
	    obstack_1grow (&token_stack, ch);
	}
      type = TOKEN_STRING;
    }

  obstack_1grow (&token_stack, '\0');

  TOKEN_DATA_TYPE (td) = TOKEN_TEXT;
  TOKEN_DATA_TEXT (td) = obstack_finish (&token_stack);
#ifdef ENABLE_CHANGEWORD
  if (orig_text == NULL)
    orig_text = TOKEN_DATA_TEXT (td);
  TOKEN_DATA_ORIG_TEXT (td) = orig_text;
#endif
#ifdef DEBUG_INPUT
  fprintf (stderr, "next_token -> %d (%s)\n", type, TOKEN_DATA_TEXT (td));
#endif
  return type;
}
Exemple #10
0
token_type
next_token (token_data *td)
{
  int ch;
  int quote_level;
  token_type type;

  obstack_free (&token_stack, token_bottom);
  obstack_1grow (&token_stack, '\0');
  token_bottom = obstack_finish (&token_stack);

  ch = peek_input ();
  if (ch == CHAR_EOF)
    {
      return TOKEN_EOF;
#ifdef DEBUG_INPUT
      fprintf (stderr, "next_token -> EOF\n");
#endif
    }
  if (ch == CHAR_MACRO)
    {
      init_macro_token (td);
      (void) next_char ();
      return TOKEN_MACDEF;
    }

  (void) next_char ();
  if (MATCH (ch, bcomm))
    {

      obstack_grow (&token_stack, bcomm, len_bcomm);
      while ((ch = next_char ()) != CHAR_EOF && !MATCH (ch, ecomm))
	obstack_1grow (&token_stack, ch);
      if (ch != CHAR_EOF)
	obstack_grow (&token_stack, ecomm, len_ecomm);
      type = TOKEN_STRING;

    }
  else if (isalpha (ch) || ch == '_')
    {

      obstack_1grow (&token_stack, ch);
      while ((ch = peek_input ()) != CHAR_EOF && (isalnum (ch) || ch == '_'))
	{
	  obstack_1grow (&token_stack, ch);
	  (void) next_char ();
	}
      type = TOKEN_WORD;

    }
  else if (!MATCH (ch, lquote))
    {

      type = TOKEN_SIMPLE;
      obstack_1grow (&token_stack, ch);

    }
  else
    {

      quote_level = 1;
      while (1)
	{
	  ch = next_char ();
	  if (ch == CHAR_EOF)
	    fatal ("EOF in string");

	  if (MATCH (ch, rquote))
	    {
	      if (--quote_level == 0)
		break;
	      obstack_grow (&token_stack, rquote, len_rquote);
	    }
	  else if (MATCH (ch, lquote))
	    {
	      quote_level++;
	      obstack_grow (&token_stack, lquote, len_lquote);
	    }
	  else
	    obstack_1grow (&token_stack, ch);
	}
      type = TOKEN_STRING;
    }

  obstack_1grow (&token_stack, '\0');

  TOKEN_DATA_TYPE (td) = TOKEN_TEXT;
  TOKEN_DATA_TEXT (td) = obstack_finish (&token_stack);
#ifdef DEBUG_INPUT
  fprintf (stderr, "next_token -> %d (%s)\n", type, TOKEN_DATA_TEXT (td));
#endif
  return type;
}
Exemple #11
0
token_type
next_token (token_data *td, read_type expansion, boolean in_string)
{
  int ch;
  token_type type = TOKEN_NONE;
  int quote_level;

  if (TOKEN_DATA_TYPE (&token_read) != TOKEN_VOID)
    {
      type = TOKEN_STRING;
      obstack_grow (&token_stack, TOKEN_DATA_TEXT (&token_read),
              strlen (TOKEN_DATA_TEXT (&token_read)));
      xfree ((voidstar) TOKEN_DATA_TEXT (&token_read));
      TOKEN_DATA_TYPE (&token_read) = TOKEN_VOID;
    }

  while (type == TOKEN_NONE)
    {
      obstack_free (&token_stack, token_bottom);
      obstack_1grow (&token_stack, '\0');
      token_bottom = obstack_finish (&token_stack);

      ch = peek_input ();
      if (ch == CHAR_EOF)                 /* EOF */
        {
#ifdef DEBUG_INPUT
          fprintf (stderr, "next_token -> EOF\n");
#endif
          return TOKEN_EOF;
        }

      if (ch == CHAR_MACRO)               /* MACRO TOKEN */
        {
          init_macro_token (td);
          (void) next_char ();
#ifdef DEBUG_INPUT
          print_token("next_token", TOKEN_MACDEF, td);
#endif
          return TOKEN_MACDEF;
        }

      (void) next_char ();
      if (IS_TAG(ch))             /* ESCAPED WORD */
        {
          if (lquote.length > 0 && MATCH (ch, lquote.string))
            {
              if (visible_quotes || expansion == READ_ATTR_VERB
                  || expansion == READ_ATTR_ASIS || expansion == READ_BODY)
                obstack_grow (&token_stack, lquote.string, lquote.length);
              while ((ch = next_char ()) != CHAR_EOF)
                {
                  if (rquote.length > 0 && MATCH (ch, rquote.string))
                    break;
                  obstack_1grow (&token_stack, ch);
                }
              if (visible_quotes || expansion == READ_ATTR_VERB
                  || expansion == READ_ATTR_ASIS || expansion == READ_BODY)
                {
                  obstack_grow (&token_stack, rquote.string, rquote.length);
                  type = TOKEN_STRING;
                }
              else
                type = TOKEN_QUOTED;
            }
          else
            {
              obstack_1grow (&token_stack, ch);
              if ((ch = peek_input ()) != CHAR_EOF)
                {
                  if (ch == '/')
                    {
                      obstack_1grow (&token_stack, '/');
                      (void) next_char ();
                      ch = peek_input ();
                    }
                  if (IS_ALPHA(ch))
                    {
                      ch = next_char ();
                      obstack_1grow (&token_stack, ch);
                      while ((ch = next_char ()) != CHAR_EOF && IS_ALNUM(ch))
                        {
                          obstack_1grow (&token_stack, ch);
                        }
                      if (ch == '*')
                        {
                          obstack_1grow (&token_stack, ch);
                          ch = peek_input ();
                        }
                      else
                        unget_input(ch);

                      if (IS_SPACE(ch) || IS_CLOSE(ch) || IS_SLASH (ch))
                        type = TOKEN_WORD;
                      else
                        type = TOKEN_STRING;
                    }
                  else
                    type = TOKEN_STRING;
                }
              else
                type = TOKEN_SIMPLE;        /* escape before eof */
            }
        }
      else if (IS_CLOSE(ch))
        {
          obstack_1grow (&token_stack, ch);
          type = TOKEN_SIMPLE;
        }
      else if (IS_ENTITY(ch))             /* entity  */
        {
          obstack_1grow (&token_stack, ch);
          if ((ch = peek_input ()) != CHAR_EOF)
            {
              if (IS_ALPHA(ch))
                {
                  ch = next_char ();
                  obstack_1grow (&token_stack, ch);
                  while ((ch = next_char ()) != CHAR_EOF && IS_ALNUM(ch))
                    {
                      obstack_1grow (&token_stack, ch);
                    }

                  if (ch == ';')
                    {
                      obstack_1grow (&token_stack, ch);
                      type = TOKEN_ENTITY;
                    }
                  else
                    {
                      type = TOKEN_STRING;
                      unget_input(ch);
                    }
                }
              else
                type = TOKEN_STRING;
            }
          else
            type = TOKEN_SIMPLE;        /* escape before eof */
        }
      else if (eolcomm.length > 0 && MATCH (ch, eolcomm.string))
        skip_line ();
      else if (expansion == READ_BODY)
        {
          if (ch == '"')
            obstack_1grow (&token_stack, CHAR_QUOTE);
          else
            obstack_1grow (&token_stack, ch);
          while ((ch = next_char ()) != CHAR_EOF
                  && ! IS_TAG(ch) && ! IS_CLOSE (ch))
            {
              if (eolcomm.length > 0 && MATCH (ch, eolcomm.string))
                {
                  skip_line ();
                  ch = CHAR_EOF;
                  break;
                }
              if (ch == '"')
                obstack_1grow (&token_stack, CHAR_QUOTE);
              else
                obstack_1grow (&token_stack, ch);
            }
          unget_input(ch);

          type = TOKEN_STRING;
        }
      /*  Below we know that expansion != READ_BODY  */
      else if (IS_ALPHA(ch))
        {
          obstack_1grow (&token_stack, ch);
          while ((ch = next_char ()) != CHAR_EOF && (IS_ALNUM(ch)))
            {
              obstack_1grow (&token_stack, ch);
            }
          if (ch == '*')
            {
              obstack_1grow (&token_stack, ch);
              ch = peek_input ();
            }
          else
            unget_input(ch);

          type = TOKEN_STRING;
        }
      else if (IS_RQUOTE(ch))
        {
          MP4HERROR ((EXIT_FAILURE, 0,
             "INTERNAL ERROR: CHAR_RQUOTE found."));
        }
      else if (IS_LQUOTE(ch))             /* QUOTED STRING */
        {
          quote_level = 1;
          while (1)
            {
              ch = next_char ();
              if (ch == CHAR_EOF)
                MP4HERROR ((EXIT_FAILURE, 0,
                   "INTERNAL ERROR: EOF in string"));

              if (IS_BGROUP(ch) || IS_EGROUP(ch))
                continue;
              else if (IS_RQUOTE(ch))
                {
                  quote_level--;
                  if (quote_level == 0)
                      break;
                }
              else if (IS_LQUOTE(ch))
                quote_level++;
              else
                obstack_1grow (&token_stack, ch);
            }
          type = TOKEN_QUOTED;
        }
      else if (IS_BGROUP(ch))             /* BEGIN GROUP */
        type = TOKEN_BGROUP;
      else if (IS_EGROUP(ch))             /* END GROUP */
        type = TOKEN_EGROUP;
      else if (ch == '"')                 /* QUOTED STRING */
        {
          switch (expansion)
          {
            case READ_NORMAL:
              obstack_1grow (&token_stack, CHAR_QUOTE);
              type = TOKEN_SIMPLE;
              break;

            case READ_ATTRIBUTE:
            case READ_ATTR_VERB:
              type = TOKEN_QUOTE;
              break;

            case READ_ATTR_ASIS:
            case READ_ATTR_QUOT:
              obstack_1grow (&token_stack, '"');
              type = TOKEN_QUOTE;
              break;

            default:
              MP4HERROR ((warning_status, 0,
                "INTERNAL ERROR: Unknown expansion type"));
              exit (1);
          }
        }
      else if (ch == '\\')
        {
          switch (expansion)
          {
            case READ_NORMAL:
              obstack_1grow (&token_stack, ch);
              type = TOKEN_SIMPLE;
              break;

            case READ_ATTRIBUTE:
            case READ_ATTR_QUOT:
              ch = next_char();
              if (ch == 'n')
                obstack_1grow (&token_stack, '\n');
              else if (ch == 't')
                obstack_1grow (&token_stack, '\t');
              else if (ch == 'r')
                obstack_1grow (&token_stack, '\r');
              else if (ch == '\\')
                obstack_1grow (&token_stack, ch);
              else if (ch == '"' && in_string)
                obstack_1grow (&token_stack, CHAR_QUOTE);
              else
                {
                  if (!(exp_flags & EXP_STD_BSLASH))
                    obstack_1grow (&token_stack, '\\');
                  obstack_1grow (&token_stack, ch);
                }

              type = TOKEN_STRING;
              break;

            case READ_ATTR_VERB:
              ch = next_char();
              if (ch == '"' && in_string)
                obstack_1grow (&token_stack, CHAR_QUOTE);
              else
                {
                  obstack_1grow (&token_stack, '\\');
                  obstack_1grow (&token_stack, ch);
                }

              type = TOKEN_STRING;
              break;

            case READ_ATTR_ASIS:
              obstack_1grow (&token_stack, ch);
              ch = next_char();
              obstack_1grow (&token_stack, ch);
              type = TOKEN_STRING;
              break;

            default:
              MP4HERROR ((warning_status, 0,
                "INTERNAL ERROR: Unknown expansion type"));
              exit (1);
          }
        }
      else /* EVERYTHING ELSE */
        {
          obstack_1grow (&token_stack, ch);

          if (IS_OTHER(ch) || IS_NUM(ch))
            type = TOKEN_STRING;
          else if (IS_SPACE(ch))
            {
              while ((ch = next_char ()) != CHAR_EOF && IS_SPACE(ch))
                obstack_1grow (&token_stack, ch);
              unget_input(ch);
              type = TOKEN_SPACE;
            }
          else
            type = TOKEN_SIMPLE;
        }
    }

  obstack_1grow (&token_stack, '\0');

  TOKEN_DATA_TYPE (td) = TOKEN_TEXT;
  TOKEN_DATA_TEXT (td) = obstack_finish (&token_stack);

#ifdef DEBUG_INPUT
  print_token("next_token", type, td);
#endif

  return type;
}
Exemple #12
0
static int
print_token (const char *s, token_type t, token_data *td)
{
  fprintf (stderr, "%s: ", s);
  switch (t)
    {                           /* TOKSW */
    case TOKEN_SIMPLE:
      fprintf (stderr, "char\t\"%s\"\n", TOKEN_DATA_TEXT (td));
      break;

    case TOKEN_WORD:
      fprintf (stderr, "word\t\"%s\"\n", TOKEN_DATA_TEXT (td));
      break;

    case TOKEN_ENTITY:
      fprintf (stderr, "entity\t\"%s\"\n", TOKEN_DATA_TEXT (td));
      break;

    case TOKEN_STRING:
      fprintf (stderr, "string\t\"%s\"\n", TOKEN_DATA_TEXT (td));
      break;

    case TOKEN_QUOTED:
      fprintf (stderr, "quoted\t\"%s\"\n", TOKEN_DATA_TEXT (td));
      break;

    case TOKEN_BGROUP:
      fprintf (stderr, "bgroup\n");
      break;

    case TOKEN_EGROUP:
      fprintf (stderr, "egroup\n");
      break;

    case TOKEN_QUOTE:
      fprintf (stderr, "quote\n");
      break;

    case TOKEN_SPACE:
      fprintf (stderr, "space\t\"%s\"\n", TOKEN_DATA_TEXT (td));
      break;

    case TOKEN_MACDEF:
      fprintf (stderr, "macro 0x%x\n", (int)TOKEN_DATA_FUNC (td));
      break;

    case TOKEN_EOF:
      fprintf (stderr, "eof\n");
      break;

    case TOKEN_NONE:
      fprintf (stderr, "none\n");
      break;

    default:
      MP4HERROR ((warning_status, 0,
        "INTERNAL ERROR: unknown token in print_token"));
      break;
    }
  return 0;
}
Exemple #13
0
token_type
next_token (token_data *td, int *line)
{
  int ch;
  int quote_level;
  token_type type;
#ifdef ENABLE_CHANGEWORD
  int startpos;
  char *orig_text = NULL;
#endif
  const char *file;
  int dummy;

  obstack_free (&token_stack, token_bottom);
  if (!line)
    line = &dummy;

 /* Can't consume character until after CHAR_MACRO is handled.  */
  ch = peek_input ();
  if (ch == CHAR_EOF)
    {
#ifdef DEBUG_INPUT
      xfprintf (stderr, "next_token -> EOF\n");
#endif
      next_char ();
      return TOKEN_EOF;
    }
  if (ch == CHAR_MACRO)
    {
      init_macro_token (td);
      next_char ();
#ifdef DEBUG_INPUT
      xfprintf (stderr, "next_token -> MACDEF (%s)\n",
                find_builtin_by_addr (TOKEN_DATA_FUNC (td))->name);
#endif
      return TOKEN_MACDEF;
    }

  next_char (); /* Consume character we already peeked at.  */
  file = current_file;
  *line = current_line;
  if (MATCH (ch, bcomm.string, true))
    {
      obstack_grow (&token_stack, bcomm.string, bcomm.length);
      while ((ch = next_char ()) != CHAR_EOF
             && !MATCH (ch, ecomm.string, true))
        obstack_1grow (&token_stack, ch);
      if (ch != CHAR_EOF)
        obstack_grow (&token_stack, ecomm.string, ecomm.length);
      else
        /* current_file changed to "" if we see CHAR_EOF, use the
           previous value we stored earlier.  */
        M4ERROR_AT_LINE ((EXIT_FAILURE, 0, file, *line,
                          "ERROR: end of file in comment"));

      type = TOKEN_STRING;
    }
  else if (default_word_regexp && (isalpha (ch) || ch == '_'))
    {
      obstack_1grow (&token_stack, ch);
      while ((ch = peek_input ()) != CHAR_EOF && (isalnum (ch) || ch == '_'))
        {
          obstack_1grow (&token_stack, ch);
          next_char ();
        }
      type = TOKEN_WORD;
    }

#ifdef ENABLE_CHANGEWORD

  else if (!default_word_regexp && word_regexp.fastmap[ch])
    {
      obstack_1grow (&token_stack, ch);
      while (1)
        {
          ch = peek_input ();
          if (ch == CHAR_EOF)
            break;
          obstack_1grow (&token_stack, ch);
          startpos = re_search (&word_regexp,
                                (char *) obstack_base (&token_stack),
                                obstack_object_size (&token_stack), 0, 0,
                                &regs);
          if (startpos ||
              regs.end [0] != (regoff_t) obstack_object_size (&token_stack))
            {
              *(((char *) obstack_base (&token_stack)
                 + obstack_object_size (&token_stack)) - 1) = '\0';
              break;
            }
          next_char ();
        }

      obstack_1grow (&token_stack, '\0');
      orig_text = (char *) obstack_finish (&token_stack);

      if (regs.start[1] != -1)
        obstack_grow (&token_stack,orig_text + regs.start[1],
                      regs.end[1] - regs.start[1]);
      else
        obstack_grow (&token_stack, orig_text,regs.end[0]);

      type = TOKEN_WORD;
    }

#endif /* ENABLE_CHANGEWORD */

  else if (!MATCH (ch, lquote.string, true))
    {
      switch (ch)
        {
        case '(':
          type = TOKEN_OPEN;
          break;
        case ',':
          type = TOKEN_COMMA;
          break;
        case ')':
          type = TOKEN_CLOSE;
          break;
        default:
          type = TOKEN_SIMPLE;
          break;
        }
      obstack_1grow (&token_stack, ch);
    }
  else
    {
      bool fast = lquote.length == 1 && rquote.length == 1;
      quote_level = 1;
      while (1)
        {
          /* Try scanning a buffer first.  */
          const char *buffer = (isp && isp->type == INPUT_STRING
                                ? isp->u.u_s.string : NULL);
          if (buffer && *buffer)
            {
              size_t len = isp->u.u_s.end - buffer;
              const char *p = buffer;
              do
                {
                  p = (char *) memchr2 (p, *lquote.string, *rquote.string,
                                        buffer + len - p);
                }
              while (p && fast && (*p++ == *rquote.string
                                   ? --quote_level : ++quote_level));
              if (p)
                {
                  if (fast)
                    {
                      assert (!quote_level);
                      obstack_grow (&token_stack, buffer, p - buffer - 1);
                      isp->u.u_s.string += p - buffer;
                      break;
                    }
                  obstack_grow (&token_stack, buffer, p - buffer);
                  ch = to_uchar (*p);
                  isp->u.u_s.string += p - buffer + 1;
                }
              else
                {
                  obstack_grow (&token_stack, buffer, len);
                  isp->u.u_s.string += len;
                  continue;
                }
            }
          /* Fall back to a byte.  */
          else
            ch = next_char ();
          if (ch == CHAR_EOF)
            /* current_file changed to "" if we see CHAR_EOF, use
               the previous value we stored earlier.  */
            M4ERROR_AT_LINE ((EXIT_FAILURE, 0, file, *line,
                              "ERROR: end of file in string"));

          if (MATCH (ch, rquote.string, true))
            {
              if (--quote_level == 0)
                break;
              obstack_grow (&token_stack, rquote.string, rquote.length);
            }
          else if (MATCH (ch, lquote.string, true))
            {
              quote_level++;
              obstack_grow (&token_stack, lquote.string, lquote.length);
            }
          else
            obstack_1grow (&token_stack, ch);
        }
      type = TOKEN_STRING;
    }

  obstack_1grow (&token_stack, '\0');

  TOKEN_DATA_TYPE (td) = TOKEN_TEXT;
  TOKEN_DATA_TEXT (td) = (char *) obstack_finish (&token_stack);
#ifdef ENABLE_CHANGEWORD
  if (orig_text == NULL)
    orig_text = TOKEN_DATA_TEXT (td);
  TOKEN_DATA_ORIG_TEXT (td) = orig_text;
#endif
#ifdef DEBUG_INPUT
  xfprintf (stderr, "next_token -> %s (%s)\n",
            token_type_string (type), TOKEN_DATA_TEXT (td));
#endif
  return type;
}
Exemple #14
0
static bool
expand_argument (struct obstack *obs, token_data *argp)
{
  token_type t;
  token_data td;
  char *text;
  int paren_level;
  const char *file = current_file;
  int line = current_line;

  TOKEN_DATA_TYPE (argp) = TOKEN_VOID;

  /* Skip leading white space.  */
  do
    {
      t = next_token (&td, NULL);
    }
  while (t == TOKEN_SIMPLE && isspace (to_uchar (*TOKEN_DATA_TEXT (&td))));

  paren_level = 0;

  while (1)
    {

      switch (t)
        { /* TOKSW */
        case TOKEN_COMMA:
        case TOKEN_CLOSE:
          if (paren_level == 0)
            {
              /* The argument MUST be finished, whether we want it or not.  */
              obstack_1grow (obs, '\0');
              text = (char *) obstack_finish (obs);

              if (TOKEN_DATA_TYPE (argp) == TOKEN_VOID)
                {
                  TOKEN_DATA_TYPE (argp) = TOKEN_TEXT;
                  TOKEN_DATA_TEXT (argp) = text;
                }
              return t == TOKEN_COMMA;
            }
          /* fallthru */
        case TOKEN_OPEN:
        case TOKEN_SIMPLE:
          text = TOKEN_DATA_TEXT (&td);

          if (*text == '(')
            paren_level++;
          else if (*text == ')')
            paren_level--;
          expand_token (obs, t, &td, line);
          break;

        case TOKEN_EOF:
          /* current_file changed to "" if we see TOKEN_EOF, use the
             previous value we stored earlier.  */
          M4ERROR_AT_LINE ((EXIT_FAILURE, 0, file, line,
                            "ERROR: end of file in argument list"));
          break;

        case TOKEN_WORD:
        case TOKEN_STRING:
          expand_token (obs, t, &td, line);
          break;

        case TOKEN_MACDEF:
          if (obstack_object_size (obs) == 0)
            {
              TOKEN_DATA_TYPE (argp) = TOKEN_FUNC;
              TOKEN_DATA_FUNC (argp) = TOKEN_DATA_FUNC (&td);
            }
          break;

        default:
          M4ERROR ((warning_status, 0,
                    "INTERNAL ERROR: bad token type in expand_argument ()"));
          abort ();
        }

      t = next_token (&td, NULL);
    }
}