This is the mail archive of the binutils@sourceware.cygnus.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH] macro hooks (revised)


Here is the macro hooks/line substitution patch previously submitted,
and revised according to previous discussion.


Index: gas/ChangeLog
===================================================================
RCS file: /cvs/src/src/gas/ChangeLog,v
retrieving revision 1.279
diff -d -c -p -r1.279 ChangeLog
*** ChangeLog	2000/03/07 00:06:51	1.279
--- ChangeLog	2000/03/08 19:50:05
***************
*** 1,3 ****
--- 1,30 ----
+ 2000-03-08  Timothy Wall <twall@cygnus.com>
+ 
+ 	* gasp.c (macro_op): Add new argument to check_macro call.
+ 	Macro structure definitions moved to macro.h
+ 	* sb.h:  Add argument to prototype for input_scrib_include_sb.
+ 	* input-scrub.c (input_scrub_include_sb): Allow disabling of sb
+ 	nesting checks with an additional flag.
+ 	(struct input_save): Add flag to indicate whether current sb
+ 	should be checked for proper macro/conditional nesting.
+ 	(input_scrub_push/pop): Save/restore nest check flag.
+ 	(input_scrub_next_buffer): Ditto.  Also call end of macro hook if
+ 	defined. 
+ 	* macro.c (check_macro):  Allow caller to retrieve parsed macro
+ 	information if a pointer is provided.  This information may be
+ 	used by the new macro hooks.
+ 	* macro.h: Update prototype for check_macro.  Macro struct
+ 	definitions moved here from macro.c/gasp.c.
+ 	* read.c (read_a_source_file): Add parameter to check_macro call,
+ 	and pass macro info to the macro hook, if defined.
+ 	(input_scrub_insert_line): New.  Allow insertion of a line of
+ 	characters into the input stream.
+ 	(input_scrub_insert_file): New.  Allow insertion of an arbitrary
+ 	file into the input stream.
+ 	(s_include): Use input_scrub_insert_file.
+ 	* internals.texi: Document new macro hooks.
+ 	* as.h: New prototypes added.
+ 	
  2000-03-06  Nick Clifton  <nickc@cygnus.com>
  
  	* config/tc-m32r.c (struct md_longopts): Add -m32r command line
Index: gas/as.h
===================================================================
RCS file: /cvs/src/src/gas/as.h,v
retrieving revision 1.8
diff -d -c -p -r1.8 as.h
*** as.h	2000/02/24 01:56:31	1.8
--- as.h	2000/03/08 19:50:05
*************** void print_version_id PARAMS ((void));
*** 557,562 ****
--- 557,564 ----
  char *app_push PARAMS ((void));
  char *atof_ieee PARAMS ((char *str, int what_kind, LITTLENUM_TYPE * words));
  char *input_scrub_include_file PARAMS ((char *filename, char *position));
+ extern void input_scrub_insert_line PARAMS((const char *line));
+ extern void input_scrub_insert_file PARAMS((char *path));
  char *input_scrub_new_file PARAMS ((char *filename));
  char *input_scrub_next_buffer PARAMS ((char **bufp));
  int do_scrub_chars PARAMS ((int (*get) (char *, int), char *to, int tolen));
Index: gas/gasp.c
===================================================================
RCS file: /cvs/src/src/gas/gasp.c,v
retrieving revision 1.5
diff -d -c -p -r1.5 gasp.c
*** gasp.c	2000/03/01 18:03:49	1.5
--- gasp.c	2000/03/08 19:50:06
*************** typedef struct
*** 193,229 ****
    } hash_table;
  
  
- /* 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 attatched to them. */
- 
- /* 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 */
-   }
- formal_entry;
- 
- /* 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 */
-     hash_table formal_hash;	/* hash table of formals. */
-   }
- macro_entry;
- 
  /* how we nest files and expand macros etc.
  
     we keep a stack of of include_stack structs.  each include file
--- 193,198 ----
*************** macro_op (idx, in)
*** 2687,2693 ****
      return 0;
  
    sb_terminate (in);
!   if (! check_macro (in->ptr + idx, &out, comment_char, &err))
      return 0;
  
    if (err != NULL)
--- 2656,2662 ----
      return 0;
  
    sb_terminate (in);
!   if (! check_macro (in->ptr + idx, &out, comment_char, &err, NULL))
      return 0;
  
    if (err != NULL)
Index: gas/input-scrub.c
===================================================================
RCS file: /cvs/src/src/gas/input-scrub.c,v
retrieving revision 1.1.1.1
diff -d -c -p -r1.1.1.1 input-scrub.c
*** input-scrub.c	1999/05/03 07:28:41	1.1.1.1
--- input-scrub.c	2000/03/08 19:50:06
*************** static int sb_index = -1;
*** 74,79 ****
--- 74,82 ----
  /* If we are reading from an sb structure, this is it.  */
  static sb from_sb;
  
+ /* Should we do a conditional check on from_sb? */
+ static int check_from_sb = 1;
+ 
  /* The number of nested sb structures we have included.  */
  int macro_nest;
  
*************** struct input_save
*** 111,116 ****
--- 114,120 ----
      int logical_input_line;
      int sb_index;
      sb from_sb;
+     int check_from_sb;          /* Should we do a conditional check? */
      struct input_save *next_saved_file;	/* Chain of input_saves */
      char *input_file_save;	/* Saved state of input routines */
      char *saved_position;	/* Caller's saved position in buf */
*************** input_scrub_push (saved_position)
*** 147,152 ****
--- 151,157 ----
    saved->logical_input_line = logical_input_line;
    saved->sb_index = sb_index;
    saved->from_sb = from_sb;
+   saved->check_from_sb = check_from_sb;
    memcpy (saved->save_source, save_source, sizeof (save_source));
    saved->next_saved_file = next_saved_file;
    saved->input_file_save = input_file_push ();
*************** input_scrub_pop (saved)
*** 181,186 ****
--- 186,192 ----
    logical_input_line = saved->logical_input_line;
    sb_index = saved->sb_index;
    from_sb = saved->from_sb;
+   check_from_sb = saved->check_from_sb;
    partial_where = saved->partial_where;
    partial_size = saved->partial_size;
    next_saved_file = saved->next_saved_file;
*************** input_scrub_include_file (filename, posi
*** 255,271 ****
     expanding a macro.  */
  
  void
! input_scrub_include_sb (from, position)
       sb *from;
       char *position;
  {
!   if (macro_nest > max_macro_nest)
!     as_fatal (_("macros nested too deeply"));
!   ++macro_nest;
  
    next_saved_file = input_scrub_push (position);
  
    sb_new (&from_sb);
    if (from->len >= 1 && from->ptr[0] != '\n')
      {
        /* Add the sentinel required by read.c.  */
--- 261,285 ----
     expanding a macro.  */
  
  void
! input_scrub_include_sb (from, position, do_check)
       sb *from;
       char *position;
+      int do_check;
  {
!   if (do_check)
!     {
!       if (macro_nest > max_macro_nest)
!         as_fatal (_("macros nested too deeply"));
!       ++macro_nest;
! #ifdef md_macro_start
!       md_macro_start ();
! #endif
!     }
  
    next_saved_file = input_scrub_push (position);
  
    sb_new (&from_sb);
+   check_from_sb = do_check;
    if (from->len >= 1 && from->ptr[0] != '\n')
      {
        /* Add the sentinel required by read.c.  */
*************** input_scrub_next_buffer (bufp)
*** 297,304 ****
        if (sb_index >= from_sb.len)
  	{
  	  sb_kill (&from_sb);
! 	  cond_finish_check (macro_nest);
! 	  --macro_nest;
  	  partial_where = NULL;
  	  if (next_saved_file != NULL)
  	    *bufp = input_scrub_pop (next_saved_file);
--- 311,325 ----
        if (sb_index >= from_sb.len)
  	{
  	  sb_kill (&from_sb);
!           if (check_from_sb)
!             {
!               cond_finish_check (macro_nest);
!               /* allow the target to clean up per-macro expansion data */
! #ifdef md_macro_end
!               md_macro_end ();
! #endif
!               --macro_nest;
!             }
  	  partial_where = NULL;
  	  if (next_saved_file != NULL)
  	    *bufp = input_scrub_pop (next_saved_file);
Index: gas/macro.c
===================================================================
RCS file: /cvs/src/src/gas/macro.c,v
retrieving revision 1.5
diff -d -c -p -r1.5 macro.c
*** macro.c	1999/11/12 15:39:46	1.5
--- macro.c	2000/03/08 19:50:06
*************** extern void *alloca ();
*** 70,111 ****
  /* The routines in this file handle macro definition and expansion.
     They are called by both gasp and gas.  */
  
- /* 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 attatched to them. */
- 
- /* 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 */
-   }
- 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 hash_control *formal_hash; /* hash table of formals. */
-   }
- macro_entry;
- 
  /* Internal functions.  */
  
  static int get_token PARAMS ((int, sb *, sb *));
--- 70,75 ----
*************** macro_expand (idx, in, m, out, comment_c
*** 1108,1118 ****
     gasp.  Return 1 if a macro is found, 0 otherwise.  */
  
  int
! check_macro (line, expand, comment_char, error)
       const char *line;
       sb *expand;
       int comment_char;
       const char **error;
  {
    const char *s;
    char *copy, *cs;
--- 1072,1083 ----
     gasp.  Return 1 if a macro is found, 0 otherwise.  */
  
  int
! check_macro (line, expand, comment_char, error, info)
       const char *line;
       sb *expand;
       int comment_char;
       const char **error;
+      macro_entry **info;
  {
    const char *s;
    char *copy, *cs;
*************** check_macro (line, expand, comment_char,
*** 1152,1157 ****
--- 1117,1126 ----
    *error = macro_expand (0, &line_sb, macro, expand, comment_char);
  
    sb_kill (&line_sb);
+ 
+   /* export the macro information if requested */
+   if (info)
+     *info = macro;
  
    return 1;
  }
Index: gas/macro.h
===================================================================
RCS file: /cvs/src/src/gas/macro.h,v
retrieving revision 1.1.1.1
diff -d -c -p -r1.1.1.1 macro.h
*** macro.h	1999/05/03 07:28:41	1.1.1.1
--- macro.h	2000/03/08 19:50:06
***************
*** 28,33 ****
--- 28,69 ----
  #include "ansidecl.h"
  #include "sb.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 attatched to them. */
+ 
+ /* 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 */
+   }
+ 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 hash_control *formal_hash; /* hash table of formals. */
+   }
+ macro_entry;
+ 
  /* Whether any macros have been defined.  */
  
  extern int macro_defined;
*************** extern void macro_mri_mode PARAMS ((int)
*** 45,51 ****
  extern const char *define_macro
    PARAMS ((int idx, sb *in, sb *label, int (*get_line) PARAMS ((sb *)),
  	   const char **namep));
! extern int check_macro PARAMS ((const char *, sb *, int, const char **));
  extern void delete_macro PARAMS ((const char *));
  extern const char *expand_irp
    PARAMS ((int, int, sb *, sb *, int (*) PARAMS ((sb *)), int));
--- 81,88 ----
  extern const char *define_macro
    PARAMS ((int idx, sb *in, sb *label, int (*get_line) PARAMS ((sb *)),
  	   const char **namep));
! extern int check_macro PARAMS ((const char *, sb *, int, const char **, 
!                                 macro_entry **));
  extern void delete_macro PARAMS ((const char *));
  extern const char *expand_irp
    PARAMS ((int, int, sb *, sb *, int (*) PARAMS ((sb *)), int));
Index: gas/read.c
===================================================================
RCS file: /cvs/src/src/gas/read.c,v
retrieving revision 1.16
diff -d -c -p -r1.16 read.c
*** read.c	2000/02/24 01:56:31	1.16
--- read.c	2000/03/08 19:50:07
*************** read_a_source_file (name)
*** 864,880 ****
  			{
  			  sb out;
  			  const char *err;
  
! 			  if (check_macro (s, &out, '\0', &err))
  			    {
  			      if (err != NULL)
  				as_bad ("%s", err);
  			      *input_line_pointer++ = c;
  			      input_scrub_include_sb (&out,
! 						      input_line_pointer);
  			      sb_kill (&out);
  			      buffer_limit =
  				input_scrub_next_buffer (&input_line_pointer);
  			      continue;
  			    }
  			}
--- 864,884 ----
  			{
  			  sb out;
  			  const char *err;
+                           macro_entry *macro;
  
! 			  if (check_macro (s, &out, '\0', &err, &macro))
  			    {
  			      if (err != NULL)
  				as_bad ("%s", err);
  			      *input_line_pointer++ = c;
  			      input_scrub_include_sb (&out,
! 						      input_line_pointer, 1);
  			      sb_kill (&out);
  			      buffer_limit =
  				input_scrub_next_buffer (&input_line_pointer);
+ #ifdef md_macro_info
+                               md_macro_info (macro);
+ #endif
  			      continue;
  			    }
  			}
*************** s_irp (irpc)
*** 1827,1833 ****
  
    sb_kill (&s);
  
!   input_scrub_include_sb (&out, input_line_pointer);
    sb_kill (&out);
    buffer_limit = input_scrub_next_buffer (&input_line_pointer);
  }
--- 1831,1837 ----
  
    sb_kill (&s);
  
!   input_scrub_include_sb (&out, input_line_pointer, 1);
    sb_kill (&out);
    buffer_limit = input_scrub_next_buffer (&input_line_pointer);
  }
*************** do_repeat (count, start, end)
*** 2670,2676 ****
  
    sb_kill (&one);
  
!   input_scrub_include_sb (&many, input_line_pointer);
    sb_kill (&many);
    buffer_limit = input_scrub_next_buffer (&input_line_pointer);
  }
--- 2674,2680 ----
  
    sb_kill (&one);
  
!   input_scrub_include_sb (&many, input_line_pointer, 1);
    sb_kill (&many);
    buffer_limit = input_scrub_next_buffer (&input_line_pointer);
  }
*************** void 
*** 4873,4879 ****
  s_include (arg)
       int arg ATTRIBUTE_UNUSED;
  {
-   char *newbuf;
    char *filename;
    int i;
    FILE *try;
--- 4877,4882 ----
*************** s_include (arg)
*** 4924,4931 ****
  gotit:
    /* malloc Storage leak when file is found on path.  FIXME-SOMEDAY. */
    register_dependency (path);
!   newbuf = input_scrub_include_file (path, input_line_pointer);
!   buffer_limit = input_scrub_next_buffer (&input_line_pointer);
  }				/* s_include() */
  
  void 
--- 4927,4933 ----
  gotit:
    /* malloc Storage leak when file is found on path.  FIXME-SOMEDAY. */
    register_dependency (path);
!   input_scrub_insert_file (path);
  }				/* s_include() */
  
  void 
*************** read_print_statistics (file)
*** 5108,5113 ****
--- 5110,5148 ----
       FILE *file;
  {
    hash_print_statistics (file, "pseudo-op table", po_hash);
+ }
+ 
+ /* Inserts the given line into the input stream.  
+    
+    This call avoids macro/conditionals nesting checking, since the contents of
+    the line are considered a self-contained element, but may actually replace
+    the starting line of a conditional.
+    This function allows easy substition of input lines when called by
+    md_start_line_hook().  The given line is assumed to already be properly
+    scrubbed.  */
+ 
+ void
+ input_scrub_insert_line (line)
+   const char *line;
+ {
+   sb newline;
+   sb_new (&newline);
+   sb_add_string (&newline, line);
+   input_scrub_include_sb (&newline, input_line_pointer, 0);
+   sb_kill (&newline);
+   buffer_limit = input_scrub_next_buffer (&input_line_pointer);
+ }
+ 
+ /* Insert a (usually automatically generated) file into the input stream;
+    the path must resolve to an actual file; no include path searching or
+    dependency registering is performed.  */
+ 
+ void
+ input_scrub_insert_file (path)
+   char *path;
+ {
+   input_scrub_include_file (path, input_line_pointer);
+   buffer_limit = input_scrub_next_buffer (&input_line_pointer);
  }
  
  /* end of read.c */
Index: gas/sb.h
===================================================================
RCS file: /cvs/src/src/gas/sb.h,v
retrieving revision 1.1.1.1
diff -d -c -p -r1.1.1.1 sb.h
*** sb.h	1999/05/03 07:28:41	1.1.1.1
--- sb.h	2000/03/08 19:50:07
*************** extern int sb_skip_white PARAMS ((int, s
*** 94,99 ****
  extern int sb_skip_comma PARAMS ((int, sb *));
  
  /* Actually in input-scrub.c.  */
! extern void input_scrub_include_sb PARAMS ((sb *, char *));
  
  #endif /* SB_H */
--- 94,99 ----
  extern int sb_skip_comma PARAMS ((int, sb *));
  
  /* Actually in input-scrub.c.  */
! extern void input_scrub_include_sb PARAMS ((sb *, char *, int));
  
  #endif /* SB_H */
Index: gas/doc/internals.texi
===================================================================
RCS file: /cvs/src/src/gas/doc/internals.texi,v
retrieving revision 1.7
diff -d -c -p -r1.7 internals.texi
*** internals.texi	2000/02/28 04:08:32	1.7
--- internals.texi	2000/03/08 19:50:07
*************** must take two arguments, a @code{segT} f
*** 1237,1242 ****
--- 1237,1260 ----
  for the size of the section, and return a @code{valueT} for the rounded
  size.
  
+ @item md_macro_start
+ @cindex md_macro_start
+ GAS will call this function when it starts to include a macro expansion.
+ 'macro_nest' indicates the current macro nesting level, which includes the one
+ being expanded. 
+ 
+ @item md_macro_info
+ @cindex md_macro_info
+ GAS will call this function after the macro expansion has been included and
+ after parsing the macro arguments.  The single argument is a pointer to the
+ macro processing's internal representation of the macro, which includes
+ expansion of the formal arguments.
+ 
+ @item md_macro_end
+ @cindex md_macro_end
+ Complement to md_macro_start, called when finished processing an inserted macro
+ expansion, just before decrementing macro_nest.
+ 
  @item DOUBLEBAR_PARALLEL
  @cindex DOUBLEBAR_PARALLEL
  Affects the preprocessor so that lines containing '||' don't have their

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]