/* macro.h - header file for macro support for gas
   Copyright (C) 1994-2021 Free Software Foundation, Inc.

   Written by Steve and Judy Chamberlain of Cygnus Support,
      sac@cygnus.com

   This file is part of GAS, the GNU Assembler.

   GAS is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   GAS is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with GAS; see the file COPYING.  If not, write to the Free
   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
   02110-1301, USA.  */

#ifndef MACRO_H

#define MACRO_H

/* Structures used to store macros.

   Each macro knows its name and included text.  It gets built with a
   list of formal arguments, and also keeps a hash table which points
   into the list to speed up formal search.  Each formal knows its
   name and its default value.  Each time the macro is expanded, the
   formals get the actual values attached to them.  */

enum formal_type
  {
    FORMAL_OPTIONAL,
    FORMAL_REQUIRED,
    FORMAL_VARARG
  };

/* Describe the formal arguments to a macro.  */

typedef struct formal_struct {
  struct formal_struct *next;	/* Next formal in list.  */
  sb name;			/* Name of the formal.  */
  sb def;			/* The default value.  */
  sb actual;			/* The actual argument (changed on each expansion).  */
  int index;			/* The index of the formal 0..formal_count - 1.  */
  enum formal_type type;	/* The kind of the formal.  */
} formal_entry;

/* Other values found in the index field of a formal_entry.  */
#define QUAL_INDEX (-1)
#define NARG_INDEX (-2)
#define LOCAL_INDEX (-3)

/* Describe the macro.  */

typedef struct macro_struct
{
  sb sub;				/* Substitution text.  */
  int formal_count;			/* Number of formal args.  */
  formal_entry *formals;		/* Pointer to list of formal_structs.  */
  struct htab *formal_hash;		/* Hash table of formals.  */
  const char *name;			/* Macro name.  */
  const char *file;				/* File the macro was defined in.  */
  unsigned int line;			/* Line number of definition.  */
} macro_entry;

/* Whether any macros have been defined.  */

extern int macro_defined;

/* The macro nesting level.  */

extern int macro_nest;

/* The macro hash table.  */

extern struct htab *macro_hash;

struct macro_hash_entry
{
  const char *name;
  macro_entry *macro;
};

typedef struct macro_hash_entry macro_hash_entry_t;

/* Hash function for a macro_hash_entry.  */

static inline hashval_t
hash_macro_entry (const void *e)
{
  const macro_hash_entry_t *entry = (const macro_hash_entry_t *) e;
  return htab_hash_string (entry->name);
}

/* Equality function for a macro_hash_entry.  */

static inline int
eq_macro_entry (const void *a, const void *b)
{
  const macro_hash_entry_t *ea = (const macro_hash_entry_t *) a;
  const macro_hash_entry_t *eb = (const macro_hash_entry_t *) b;

  return strcmp (ea->name, eb->name) == 0;
}

static inline macro_hash_entry_t *
macro_entry_alloc (const char *name, macro_entry *macro)
{
  macro_hash_entry_t *entry = XNEW (macro_hash_entry_t);
  entry->name = name;
  entry->macro = macro;
  return entry;
}

static inline macro_entry *
macro_entry_find (htab_t table, const char *name)
{
  macro_hash_entry_t needle = { name, NULL };
  macro_hash_entry_t *entry = htab_find (table, &needle);
  return entry != NULL ? entry->macro : NULL;
}

struct formal_hash_entry
{
  const char *name;
  formal_entry *formal;
};

typedef struct formal_hash_entry formal_hash_entry_t;

/* Hash function for a macro_hash_entry.  */

static inline hashval_t
hash_formal_entry (const void *e)
{
  const formal_hash_entry_t *entry = (const formal_hash_entry_t *) e;
  return htab_hash_string (entry->name);
}

/* Equality function for a formal_hash_entry.  */

static inline int
eq_formal_entry (const void *a, const void *b)
{
  const formal_hash_entry_t *ea = (const formal_hash_entry_t *) a;
  const formal_hash_entry_t *eb = (const formal_hash_entry_t *) b;

  return strcmp (ea->name, eb->name) == 0;
}

static inline formal_hash_entry_t *
formal_entry_alloc (const char *name, formal_entry *formal)
{
  formal_hash_entry_t *entry = XNEW (formal_hash_entry_t);
  entry->name = name;
  entry->formal = formal;
  return entry;
}

static inline formal_entry *
formal_entry_find (htab_t table, const char *name)
{
  formal_hash_entry_t needle = { name, NULL };
  formal_hash_entry_t *entry = htab_find (table, &needle);
  return entry != NULL ? entry->formal : NULL;
}

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

#endif
