Back to index

cell-binutils  2.17cvs20070401
Classes | Defines | Typedefs | Functions | Variables
macro.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  formal_struct
struct  macro_struct

Defines

#define QUAL_INDEX   (-1)
#define NARG_INDEX   (-2)
#define LOCAL_INDEX   (-3)

Typedefs

typedef struct formal_struct formal_entry
typedef struct macro_struct macro_entry

Functions

int buffer_and_nest (const char *, const char *, sb *, int(*)(sb *))
void macro_init (int, int, int, int(*)(const char *, int, sb *, int *))
void macro_set_alternate (int)
void macro_mri_mode (int)
const char * define_macro (int, sb *, sb *, int(*)(sb *), char *, unsigned int, const char **)
int check_macro (const char *, sb *, const char **, macro_entry **)
void delete_macro (const char *)
const char * expand_irp (int, int, sb *, sb *, int(*)(sb *))

Variables

int macro_defined
int macro_nest
struct hash_controlmacro_hash

Class Documentation

struct macro_struct

Definition at line 60 of file macro.h.

Collaboration diagram for macro_struct:
Class Members
char * file
int formal_count
struct hash_control * formal_hash
formal_entry * formals
unsigned int line
const char * name
sb sub

Define Documentation

#define LOCAL_INDEX   (-3)

Definition at line 56 of file macro.h.

#define NARG_INDEX   (-2)

Definition at line 55 of file macro.h.

#define QUAL_INDEX   (-1)

Definition at line 54 of file macro.h.


Typedef Documentation


Function Documentation

int buffer_and_nest ( const char *  ,
const char *  ,
sb ,
int(*)(sb *)   
)

Definition at line 127 of file macro.c.

{
  int from_len;
  int to_len = strlen (to);
  int depth = 1;
  int line_start = ptr->len;

  int more = get_line (ptr);

  if (to_len == 4 && strcasecmp(to, "ENDR") == 0)
    {
      from = NULL;
      from_len = 0;
    }
  else
    from_len = strlen (from);

  while (more)
    {
      /* Try to find the first pseudo op on the line.  */
      int i = line_start;

      /* With normal syntax we can suck what we want till we get
        to the dot.  With the alternate, labels have to start in
        the first column, since we can't tell what's a label and
        what's a pseudoop.  */

      if (! LABELS_WITHOUT_COLONS)
       {
         /* Skip leading whitespace.  */
         while (i < ptr->len && ISWHITE (ptr->ptr[i]))
           i++;
       }

      for (;;)
       {
         /* Skip over a label, if any.  */
         if (i >= ptr->len || ! is_name_beginner (ptr->ptr[i]))
           break;
         i++;
         while (i < ptr->len && is_part_of_name (ptr->ptr[i]))
           i++;
         if (i < ptr->len && is_name_ender (ptr->ptr[i]))
           i++;
         if (LABELS_WITHOUT_COLONS)
           break;
         /* Skip whitespace.  */
         while (i < ptr->len && ISWHITE (ptr->ptr[i]))
           i++;
         /* Check for the colon.  */
         if (i >= ptr->len || ptr->ptr[i] != ':')
           {
             i = line_start;
             break;
           }
         i++;
         line_start = i;
       }

      /* Skip trailing whitespace.  */
      while (i < ptr->len && ISWHITE (ptr->ptr[i]))
       i++;

      if (i < ptr->len && (ptr->ptr[i] == '.'
                        || NO_PSEUDO_DOT
                        || macro_mri))
       {
         if (! flag_m68k_mri && ptr->ptr[i] == '.')
           i++;
         if (from == NULL
            && strncasecmp (ptr->ptr + i, "IRPC", from_len = 4) != 0
            && strncasecmp (ptr->ptr + i, "IRP", from_len = 3) != 0
            && strncasecmp (ptr->ptr + i, "IREPC", from_len = 5) != 0
            && strncasecmp (ptr->ptr + i, "IREP", from_len = 4) != 0
            && strncasecmp (ptr->ptr + i, "REPT", from_len = 4) != 0
            && strncasecmp (ptr->ptr + i, "REP", from_len = 3) != 0)
           from_len = 0;
         if ((from != NULL
              ? strncasecmp (ptr->ptr + i, from, from_len) == 0
              : from_len > 0)
             && (ptr->len == (i + from_len)
                || ! (is_part_of_name (ptr->ptr[i + from_len])
                     || is_name_ender (ptr->ptr[i + from_len]))))
           depth++;
         if (strncasecmp (ptr->ptr + i, to, to_len) == 0
             && (ptr->len == (i + to_len)
                || ! (is_part_of_name (ptr->ptr[i + to_len])
                     || is_name_ender (ptr->ptr[i + to_len]))))
           {
             depth--;
             if (depth == 0)
              {
                /* Reset the string to not include the ending rune.  */
                ptr->len = line_start;
                break;
              }
           }
       }

      /* Add the original end-of-line char to the end and keep running.  */
      sb_add_char (ptr, more);
      line_start = ptr->len;
      more = get_line (ptr);
    }

  /* Return 1 on success, 0 on unexpected EOF.  */
  return depth == 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int check_macro ( const char *  ,
sb ,
const char **  ,
macro_entry **   
)

Definition at line 1192 of file macro.c.

{
  const char *s;
  char *copy, *cs;
  macro_entry *macro;
  sb line_sb;

  if (! is_name_beginner (*line)
      && (! macro_mri || *line != '.'))
    return 0;

  s = line + 1;
  while (is_part_of_name (*s))
    ++s;
  if (is_name_ender (*s))
    ++s;

  copy = (char *) alloca (s - line + 1);
  memcpy (copy, line, s - line);
  copy[s - line] = '\0';
  for (cs = copy; *cs != '\0'; cs++)
    *cs = TOLOWER (*cs);

  macro = (macro_entry *) hash_find (macro_hash, copy);

  if (macro == NULL)
    return 0;

  /* Wrap the line up in an sb.  */
  sb_new (&line_sb);
  while (*s != '\0' && *s != '\n' && *s != '\r')
    sb_add_char (&line_sb, *s++);

  sb_new (expand);
  *error = macro_expand (0, &line_sb, macro, expand);

  sb_kill (&line_sb);

  /* Export the macro information if requested.  */
  if (info)
    *info = macro;

  return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char* define_macro ( int  ,
sb ,
sb ,
int(*)(sb *)  ,
char *  ,
unsigned  int,
const char **   
)

Definition at line 614 of file macro.c.

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

Here is the call graph for this function:

Here is the caller graph for this function:

void delete_macro ( const char *  )

Definition at line 1261 of file macro.c.

{
  char *copy;
  size_t i, len;
  macro_entry *macro;

  len = strlen (name);
  copy = (char *) alloca (len + 1);
  for (i = 0; i < len; ++i)
    copy[i] = TOLOWER (name[i]);
  copy[i] = '\0';

  /* Since hash_delete doesn't free memory, just clear out the entry.  */
  if ((macro = hash_find (macro_hash, copy)) != NULL)
    {
      hash_jam (macro_hash, copy, NULL);
      free_macro (macro);
    }
  else
    as_warn (_("Attempt to purge non-existant macro `%s'"), copy);
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char* expand_irp ( int  ,
int  ,
sb ,
sb ,
int(*)(sb *)   
)

Definition at line 1288 of file macro.c.

{
  sb sub;
  formal_entry f;
  struct hash_control *h;
  const char *err;

  idx = sb_skip_white (idx, in);

  sb_new (&sub);
  if (! buffer_and_nest (NULL, "ENDR", &sub, get_line))
    return _("unexpected end of file in irp or irpc");

  sb_new (&f.name);
  sb_new (&f.def);
  sb_new (&f.actual);

  idx = get_token (idx, in, &f.name);
  if (f.name.len == 0)
    return _("missing model parameter");

  h = hash_new ();
  err = hash_jam (h, sb_terminate (&f.name), &f);
  if (err != NULL)
    return err;

  f.index = 1;
  f.next = NULL;
  f.type = FORMAL_OPTIONAL;

  sb_reset (out);

  idx = sb_skip_comma (idx, in);
  if (idx >= in->len)
    {
      /* Expand once with a null string.  */
      err = macro_expand_body (&sub, out, &f, h, 0);
    }
  else
    {
      bfd_boolean in_quotes = FALSE;

      if (irpc && in->ptr[idx] == '"')
       {
         in_quotes = TRUE;
         ++idx;
       }

      while (idx < in->len)
       {
         if (!irpc)
           idx = get_any_string (idx, in, &f.actual);
         else
           {
             if (in->ptr[idx] == '"')
              {
                int nxt;

                if (irpc)
                  in_quotes = ! in_quotes;
         
                nxt = sb_skip_white (idx + 1, in);
                if (nxt >= in->len)
                  {
                    idx = nxt;
                    break;
                  }
              }
             sb_reset (&f.actual);
             sb_add_char (&f.actual, in->ptr[idx]);
             ++idx;
           }

         err = macro_expand_body (&sub, out, &f, h, 0);
         if (err != NULL)
           break;
         if (!irpc)
           idx = sb_skip_comma (idx, in);
         else if (! in_quotes)
           idx = sb_skip_white (idx, in);
       }
    }

  hash_die (h);
  sb_kill (&f.actual);
  sb_kill (&f.def);
  sb_kill (&f.name);
  sb_kill (&sub);

  return err;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void macro_init ( int  ,
int  ,
int  ,
int(*)(const char *, int, sb *, int *)   
)

Definition at line 92 of file macro.c.

{
  macro_hash = hash_new ();
  macro_defined = 0;
  macro_alternate = alternate;
  macro_mri = mri;
  macro_strip_at = strip_at;
  macro_expr = expr;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void macro_mri_mode ( int  )

Definition at line 114 of file macro.c.

{
  macro_mri = mri;
}

Here is the caller graph for this function:

Definition at line 106 of file macro.c.

{
  macro_alternate = alternate;
}

Here is the caller graph for this function:


Variable Documentation

Definition at line 67 of file macro.c.

Definition at line 63 of file macro.c.

Definition at line 86 of file input-scrub.c.