示例#1
0
static size_t
sub_actual (size_t start, sb *in, sb *t, struct hash_control *formal_hash,
	    int kind, sb *out, int copyifnotthere)
{
  size_t src;
  formal_entry *ptr;

  src = get_apost_token (start, in, t, kind);
  /* See if it's in the macro's hash table, unless this is
     macro_strip_at and kind is '@' and the token did not end in '@'.  */
  if (macro_strip_at
      && kind == '@'
      && (src == start || in->ptr[src - 1] != '@'))
    ptr = NULL;
  else
    ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (t));
  if (ptr)
    {
      if (ptr->actual.len)
	{
	  sb_add_sb (out, &ptr->actual);
	}
      else
	{
	  sb_add_sb (out, &ptr->def);
	}
    }
  else if (kind == '&')
    {
      /* Doing this permits people to use & in macro bodies.  */
      sb_add_char (out, '&');
      sb_add_sb (out, t);
      if (src != start && in->ptr[src - 1] == '&')
	sb_add_char (out, '&');
    }
  else if (copyifnotthere)
    {
      sb_add_sb (out, t);
    }
  else
    {
      sb_add_char (out, '\\');
      sb_add_sb (out, t);
    }
  return src;
}
示例#2
0
文件: macro.c 项目: ajinkya93/OpenBSD
const char *
define_macro (int idx, sb *in, sb *label,
	      int (*get_line) (sb *), const char **namep)
{
  macro_entry *macro;
  sb name;
  const char *namestr;

  macro = (macro_entry *) xmalloc (sizeof (macro_entry));
  sb_new (&macro->sub);
  sb_new (&name);

  macro->formal_count = 0;
  macro->formals = 0;

  idx = sb_skip_white (idx, in);
  if (! buffer_and_nest ("MACRO", "ENDM", &macro->sub, get_line))
    return _("unexpected end of file in macro definition");
  if (label != NULL && label->len != 0)
    {
      sb_add_sb (&name, label);
      if (idx < in->len && in->ptr[idx] == '(')
	{
	  /* It's the label: MACRO (formals,...)  sort  */
	  idx = do_formals (macro, idx + 1, in);
	  if (in->ptr[idx] != ')')
	    return _("missing ) after formals");
	}
      else
	{
	  /* It's the label: MACRO formals,...  sort  */
	  idx = do_formals (macro, idx, in);
	}
    }
  else
    {
      idx = get_token (idx, in, &name);
      idx = sb_skip_comma (idx, in);
      idx = do_formals (macro, idx, in);
    }

  /* And stick it in the macro hash table.  */
  for (idx = 0; idx < name.len; idx++)
    name.ptr[idx] = TOLOWER (name.ptr[idx]);
  namestr = sb_terminate (&name);
  hash_jam (macro_hash, namestr, (PTR) macro);

  macro_defined = 1;

  if (namep != NULL)
    *namep = namestr;

  return NULL;
}
示例#3
0
文件: sb.c 项目: 5432935/crossbridge
static void
sb_check (sb *ptr, int len)
{
  if (ptr->len + len >= 1 << ptr->pot)
    {
      sb tmp;
      int pot = ptr->pot;

      while (ptr->len + len >= 1 << pot)
	pot++;
      sb_build (&tmp, pot);
      sb_add_sb (&tmp, ptr);
      sb_kill (ptr);
      *ptr = tmp;
    }
}
示例#4
0
static const char *
macro_expand_body (sb *in, sb *out, formal_entry *formals,
		   struct hash_control *formal_hash, const macro_entry *macro)
{
  sb t;
  int src = 0, inquote = 0, macro_line = 0;
  formal_entry *loclist = NULL;
  const char *err = NULL;

  sb_new (&t);

  while (src < in->len && !err)
    {
      if (in->ptr[src] == '&')
	{
	  sb_reset (&t);
	  if (macro_mri)
	    {
	      if (src + 1 < in->len && in->ptr[src + 1] == '&')
		src = sub_actual (src + 2, in, &t, formal_hash, '\'', out, 1);
	      else
		sb_add_char (out, in->ptr[src++]);
	    }
	  else
	    {
	      /* FIXME: Why do we do this?  */
	      /* At least in alternate mode this seems correct; without this
	         one can't append a literal to a parameter.  */
	      src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
	    }
	}
      else if (in->ptr[src] == '\\')
	{
	  src++;
	  if (src < in->len && in->ptr[src] == '(')
	    {
	      /* Sub in till the next ')' literally.  */
	      src++;
	      while (src < in->len && in->ptr[src] != ')')
		{
		  sb_add_char (out, in->ptr[src++]);
		}
	      if (src < in->len)
		src++;
	      else if (!macro)
		err = _("missing `)'");
	      else
		as_bad_where (macro->file, macro->line + macro_line, _("missing `)'"));
	    }
	  else if (src < in->len && in->ptr[src] == '@')
	    {
	      /* Sub in the macro invocation number.  */

	      char buffer[10];
	      src++;
	      sprintf (buffer, "%d", macro_number);
	      sb_add_string (out, buffer);
	    }
	  else if (src < in->len && in->ptr[src] == '&')
	    {
	      /* This is a preprocessor variable name, we don't do them
		 here.  */
	      sb_add_char (out, '\\');
	      sb_add_char (out, '&');
	      src++;
	    }
	  else if (macro_mri && src < in->len && ISALNUM (in->ptr[src]))
	    {
	      int ind;
	      formal_entry *f;

	      if (ISDIGIT (in->ptr[src]))
		ind = in->ptr[src] - '0';
	      else if (ISUPPER (in->ptr[src]))
		ind = in->ptr[src] - 'A' + 10;
	      else
		ind = in->ptr[src] - 'a' + 10;
	      ++src;
	      for (f = formals; f != NULL; f = f->next)
		{
		  if (f->index == ind - 1)
		    {
		      if (f->actual.len != 0)
			sb_add_sb (out, &f->actual);
		      else
			sb_add_sb (out, &f->def);
		      break;
		    }
		}
	    }
	  else
	    {
	      sb_reset (&t);
	      src = sub_actual (src, in, &t, formal_hash, '\'', out, 0);
	    }
	}
      else if ((macro_alternate || macro_mri)
	       && is_name_beginner (in->ptr[src])
	       && (! inquote
		   || ! macro_strip_at
		   || (src > 0 && in->ptr[src - 1] == '@')))
	{
	  if (! macro
	      || src + 5 >= in->len
	      || strncasecmp (in->ptr + src, "LOCAL", 5) != 0
	      || ! ISWHITE (in->ptr[src + 5]))
	    {
	      sb_reset (&t);
	      src = sub_actual (src, in, &t, formal_hash,
				(macro_strip_at && inquote) ? '@' : '\'',
				out, 1);
	    }
	  else
	    {
	      src = sb_skip_white (src + 5, in);
	      while (in->ptr[src] != '\n')
		{
		  const char *name;
		  formal_entry *f = new_formal ();

		  src = get_token (src, in, &f->name);
		  name = sb_terminate (&f->name);
		  if (! hash_find (formal_hash, name))
		    {
		      static int loccnt;
		      char buf[20];

		      f->index = LOCAL_INDEX;
		      f->next = loclist;
		      loclist = f;

		      sprintf (buf, IS_ELF ? ".LL%04x" : "LL%04x", ++loccnt);
		      sb_add_string (&f->actual, buf);

		      err = hash_jam (formal_hash, name, f);
		      if (err != NULL)
			break;
		    }
		  else
		    {
		      as_bad_where (macro->file,
				    macro->line + macro_line,
				    _("`%s' was already used as parameter (or another local) name"),
				    name);
		      del_formal (f);
		    }

		  src = sb_skip_comma (src, in);
		}
	    }
	}
      else if (in->ptr[src] == '"'
	       || (macro_mri && in->ptr[src] == '\''))
	{
	  inquote = !inquote;
	  sb_add_char (out, in->ptr[src++]);
	}
      else if (in->ptr[src] == '@' && macro_strip_at)
	{
	  ++src;
	  if (src < in->len
	      && in->ptr[src] == '@')
	    {
	      sb_add_char (out, '@');
	      ++src;
	    }
	}
      else if (macro_mri
	       && in->ptr[src] == '='
	       && src + 1 < in->len
	       && in->ptr[src + 1] == '=')
	{
	  formal_entry *ptr;

	  sb_reset (&t);
	  src = get_token (src + 2, in, &t);
	  ptr = (formal_entry *) hash_find (formal_hash, sb_terminate (&t));
	  if (ptr == NULL)
	    {
	      /* FIXME: We should really return a warning string here,
                 but we can't, because the == might be in the MRI
                 comment field, and, since the nature of the MRI
                 comment field depends upon the exact instruction
                 being used, we don't have enough information here to
                 figure out whether it is or not.  Instead, we leave
                 the == in place, which should cause a syntax error if
                 it is not in a comment.  */
	      sb_add_char (out, '=');
	      sb_add_char (out, '=');
	      sb_add_sb (out, &t);
	    }
	  else
	    {
	      if (ptr->actual.len)
		{
		  sb_add_string (out, "-1");
		}
	      else
		{
		  sb_add_char (out, '0');
		}
	    }
	}
      else
	{
	  if (in->ptr[src] == '\n')
	    ++macro_line;
	  sb_add_char (out, in->ptr[src++]);
	}
    }

  sb_kill (&t);

  while (loclist != NULL)
    {
      formal_entry *f;

      f = loclist->next;
      /* Setting the value to NULL effectively deletes the entry.  We
         avoid calling hash_delete because it doesn't reclaim memory.  */
      hash_jam (formal_hash, sb_terminate (&loclist->name), NULL);
      del_formal (loclist);
      loclist = f;
    }

  return err;
}
示例#5
0
const char *
define_macro (int idx, sb *in, sb *label,
	      int (*get_line) (sb *),
	      char *file, unsigned int line,
	      const char **namep)
{
  macro_entry *macro;
  sb name;
  const char *error = NULL;

  macro = (macro_entry *) xmalloc (sizeof (macro_entry));
  sb_new (&macro->sub);
  sb_new (&name);
  macro->file = file;
  macro->line = line;

  macro->formal_count = 0;
  macro->formals = 0;
  macro->formal_hash = hash_new ();

  idx = sb_skip_white (idx, in);
  if (! buffer_and_nest ("MACRO", "ENDM", &macro->sub, get_line))
    error = _("unexpected end of file in macro `%s' definition");
  if (label != NULL && label->len != 0)
    {
      sb_add_sb (&name, label);
      macro->name = sb_terminate (&name);
      if (idx < in->len && in->ptr[idx] == '(')
	{
	  /* It's the label: MACRO (formals,...)  sort  */
	  idx = do_formals (macro, idx + 1, in);
	  if (idx < in->len && in->ptr[idx] == ')')
	    idx = sb_skip_white (idx + 1, in);
	  else if (!error)
	    error = _("missing `)' after formals in macro definition `%s'");
	}
      else
	{
	  /* It's the label: MACRO formals,...  sort  */
	  idx = do_formals (macro, idx, in);
	}
    }
  else
    {
      int cidx;

      idx = get_token (idx, in, &name);
      macro->name = sb_terminate (&name);
      if (name.len == 0)
	error = _("Missing macro name");
      cidx = sb_skip_white (idx, in);
      idx = sb_skip_comma (cidx, in);
      if (idx == cidx || idx < in->len)
	idx = do_formals (macro, idx, in);
      else
	idx = cidx;
    }
  if (!error && idx < in->len)
    error = _("Bad parameter list for macro `%s'");

  /* And stick it in the macro hash table.  */
  for (idx = 0; idx < name.len; idx++)
    name.ptr[idx] = TOLOWER (name.ptr[idx]);
  if (hash_find (macro_hash, macro->name))
    error = _("Macro `%s' was already defined");
  if (!error)
    error = hash_jam (macro_hash, macro->name, (PTR) macro);

  if (namep != NULL)
    *namep = macro->name;

  if (!error)
    macro_defined = 1;
  else
    free_macro (macro);

  return error;
}