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


This patch adds hooks to allow the target to do things when a macro is
encountered, parsed, and terminated.  It also adds convenience functions
to aid in substituting the contents of a line and inserting an
automatically generated file into the input stream.


Index: gas/ChangeLog
===================================================================
RCS file: /cvs/src/src/gas/ChangeLog,v
retrieving revision 1.260
diff -d -c -p -r1.260 ChangeLog
*** ChangeLog	2000/02/23 13:52:20	1.260
--- ChangeLog	2000/02/23 16:13:28
***************
*** 1,3 ****
--- 1,25 ----
+ 2000-02-23  Timothy Wall <twall@cygnus.com>
+ 
+ 	* gasp.c (macro_op): Add new argument to check_macro call.
+ 	* input-scrub.c (input_scrub_inlcude_sb): Allow disabling of sb
+ 	nesting checks when appropriate.
+ 	(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.
+ 	* read.c (read_a_source_file): Add parameter to check_macro call,
+ 	and pass macro info to the macro hook, if defined.
+ 	(insert_line): New.  Allow insertion of a line of characters into
+ 	the input stream.
+ 	(insert_file): New.  Allow insertion of an arbitrary file into the
+ 	input stream.
+ 	* read.h: New prototypes added.
+ 	* sb.c: Initialize no_macro_check field.
+ 	* sb.h: Add no_macro_check field for line substitution support.
+ 	* internals.texi: Document new macro hooks.
+ 	
  2000-02-23  Linas Vepstas <linas@linas.org>
  
  	* config/tc-i370.c, config/tc-i370.h: New files.
Index: gas/gasp.c
===================================================================
RCS file: /cvs/src/src/gas/gasp.c,v
retrieving revision 1.4
diff -d -c -p -r1.4 gasp.c
*** gasp.c	2000/01/26 22:48:31	1.4
--- gasp.c	2000/02/23 16:13:28
*************** macro_op (idx, in)
*** 2692,2698 ****
      return 0;
  
    sb_terminate (in);
!   if (! check_macro (in->ptr + idx, &out, comment_char, &err))
      return 0;
  
    if (err != NULL)
--- 2692,2698 ----
      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/02/23 16:13:28
*************** input_scrub_include_sb (from, position)
*** 259,267 ****
       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);
  
--- 259,279 ----
       sb *from;
       char *position;
  {
!   /* I put this flag so that it's possible to do a wholesale
!      replace of a single line w/o disrupting the input stream; if the checking
!      is enabled, substitutions on lines like " .if SUBS" will fail, thinking
!      they have to see ".endif" before the end of the single-line sb
!      twall@cygnus.com 
!   */
!   if (!from->no_macro_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);
  
*************** input_scrub_include_sb (from, position)
*** 272,277 ****
--- 284,290 ----
        sb_add_char (&from_sb, '\n');
      }
    sb_add_sb (&from_sb, from);
+   from_sb.no_macro_check = from->no_macro_check;
    sb_index = 1;
  
    /* These variables are reset by input_scrub_push.  Restore them
*************** input_scrub_next_buffer (bufp)
*** 296,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);
--- 309,325 ----
      {
        if (sb_index >= from_sb.len)
  	{
+           int macro_check = !from_sb.no_macro_check;
  	  sb_kill (&from_sb);
!           if (macro_check)
!             {
!               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/02/23 16:13:29
*************** 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;
--- 1108,1119 ----
     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;
+      void **info;
  {
    const char *s;
    char *copy, *cs;
*************** check_macro (line, expand, comment_char,
*** 1152,1157 ****
--- 1153,1162 ----
    *error = macro_expand (0, &line_sb, macro, expand, comment_char);
  
    sb_kill (&line_sb);
+ 
+   /* export the macro information if requested */
+   if (info)
+     *info = (void *)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/02/23 16:13:29
*************** 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));
--- 45,52 ----
  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 **, 
!                                 void **));
  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.15
diff -d -c -p -r1.15 read.c
*** read.c	2000/02/10 21:03:12	1.15
--- read.c	2000/02/23 16:13:29
*************** read_a_source_file (name)
*** 872,879 ****
  			{
  			  sb out;
  			  const char *err;
  
! 			  if (check_macro (s, &out, '\0', &err))
  			    {
  			      if (err != NULL)
  				as_bad ("%s", err);
--- 872,880 ----
  			{
  			  sb out;
  			  const char *err;
+                           void *macro;
  
! 			  if (check_macro (s, &out, '\0', &err, &macro))
  			    {
  			      if (err != NULL)
  				as_bad ("%s", err);
*************** read_a_source_file (name)
*** 883,888 ****
--- 884,892 ----
  			      sb_kill (&out);
  			      buffer_limit =
  				input_scrub_next_buffer (&input_line_pointer);
+ #ifdef md_macro_info
+                               md_macro_info (macro);
+ #endif
  			      continue;
  			    }
  			}
*************** read_print_statistics (file)
*** 5112,5117 ****
--- 5116,5157 ----
       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.  
+    This function allows easy substition of input lines when called by
+    md_start_line_hook().  The line is assumed to already be properly
+    scrubbed. 
+  */
+ 
+ void
+ insert_line (line)
+   const char *line;
+ {
+   sb newline;
+   sb_new (&newline);
+   while (*line != 0)
+     sb_add_char (&newline, *line++);
+   newline.no_macro_check = 1;
+   input_scrub_include_sb (&newline, input_line_pointer);
+   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
+ insert_file (path)
+   const 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/read.h
===================================================================
RCS file: /cvs/src/src/gas/read.h,v
retrieving revision 1.4
diff -d -c -p -r1.4 read.h
*** read.h	2000/02/08 19:06:00	1.4
--- read.h	2000/02/23 16:13:29
*************** extern void stabs_generate_asm_func PARA
*** 118,123 ****
--- 118,125 ----
  extern void stabs_generate_asm_endfunc PARAMS ((const char *, const char *));
  extern void do_repeat PARAMS((int,const char *,const char *));
  extern void end_repeat PARAMS((int));
+ extern void insert_line PARAMS((const char *line));
+ extern void insert_file PARAMS((const char *filename));
  
  extern void generate_lineno_debug PARAMS ((void));
  
Index: gas/sb.c
===================================================================
RCS file: /cvs/src/src/gas/sb.c,v
retrieving revision 1.1.1.1
diff -d -c -p -r1.1.1.1 sb.c
*** sb.c	1999/05/03 07:28:41	1.1.1.1
--- sb.c	2000/02/23 16:13:29
*************** sb_build (ptr, size)
*** 92,97 ****
--- 92,98 ----
    ptr->pot = size;
    ptr->len = 0;
    ptr->item = e;
+   ptr->no_macro_check = 0;
  }
  
  
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/02/23 16:13:29
*************** typedef struct sb
*** 58,63 ****
--- 58,64 ----
      int len;			/* how much is used. */
      int pot;			/* the maximum length is 1<<pot */
      struct le *item;
+     int no_macro_check;         /* skip macro/conditional nest checking */
    }
  sb;
  
Index: gas/doc/internals.texi
===================================================================
RCS file: /cvs/src/src/gas/doc/internals.texi,v
retrieving revision 1.6
diff -d -c -p -r1.6 internals.texi
*** internals.texi	2000/02/10 21:00:10	1.6
--- internals.texi	2000/02/23 16:13:30
*************** If you define this macro, GAS will call 
*** 1229,1234 ****
--- 1229,1252 ----
  GAS will call this function for each section at the end of the assembly, to
  permit the CPU backend to adjust the alignment of a section.
  
+ @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]