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 elseif function for GAS


This patch adds the ".elseif" directive to GAS.  This allows selection
from a set of conditions without having to deeply nest further
conditionals within ".else" clauses.

* gas/read.c: Add elseif to directives table.
* gas/read.h: Add prototype for s_elseif.
* gas/doc/as.texinfo: Add documentation for .elseif usage.
* gas/cond.c (s_elseif): New function.


Index: gas/read.c
===================================================================
RCS file: /cvs/src/src/gas/read.c,v
retrieving revision 1.12
diff -d -c -p -r1.12 read.c
*** read.c	2000/02/03 18:20:23	1.12
--- read.c	2000/02/07 17:27:34
*************** static const pseudo_typeS potable[] =
*** 306,311 ****
--- 306,312 ----
    {"eject", listing_eject, 0},	/* Formfeed listing */
    {"else", s_else, 0},
    {"elsec", s_else, 0},
+   {"elseif", s_elseif, (int) O_ne},
    {"end", s_end, 0},
    {"endc", s_endif, 0},
    {"endfunc", s_func, 1},
Index: gas/read.h
===================================================================
RCS file: /cvs/src/src/gas/read.h,v
retrieving revision 1.2
diff -d -c -p -r1.2 read.h
*** read.h	1999/06/05 18:19:08	1.2
--- read.h	2000/02/07 17:27:34
*************** extern void s_comm PARAMS ((int));
*** 128,133 ****
--- 128,134 ----
  extern void s_data PARAMS ((int));
  extern void s_desc PARAMS ((int));
  extern void s_else PARAMS ((int arg));
+ extern void s_elseif PARAMS ((int arg));
  extern void s_end PARAMS ((int arg));
  extern void s_endif PARAMS ((int arg));
  extern void s_err PARAMS ((int));
Index: gas/cond.c
===================================================================
RCS file: /cvs/src/src/gas/cond.c,v
retrieving revision 1.3
diff -d -c -p -r1.3 cond.c
*** cond.c	1999/07/11 20:19:54	1.3
--- cond.c	2000/02/07 17:27:34
*************** s_ifc (arg)
*** 247,252 ****
--- 247,332 ----
  }
  
  void 
+ s_elseif (arg)
+      int arg;
+ {
+   expressionS operand;
+   int t;
+ 
+   if (current_cframe == NULL)
+     {
+       as_bad (_("\".elseif\" without matching \".if\" - ignored"));
+ 
+     }
+   else if (current_cframe->else_seen)
+     {
+       as_bad (_("\".elseif\" after \".else\" - ignored"));
+       as_bad_where (current_cframe->else_file_line.file,
+ 		    current_cframe->else_file_line.line,
+ 		    _("here is the previous \"else\""));
+       as_bad_where (current_cframe->if_file_line.file,
+ 		    current_cframe->if_file_line.line,
+ 		    _("here is the previous \"if\""));
+     }
+   else
+     {
+       as_where (&current_cframe->else_file_line.file,
+ 		&current_cframe->else_file_line.line);
+ 
+       if (!current_cframe->dead_tree)
+ 	{
+ 	  current_cframe->ignoring = !current_cframe->ignoring;
+ 	  if (LISTING_SKIP_COND ())
+ 	    {
+ 	      if (! current_cframe->ignoring)
+ 		listing_list (1);
+ 	      else
+ 		listing_list (2);
+ 	    }
+ 	}			/* if not a dead tree */
+     }				/* if error else do it */
+ 
+ 
+   SKIP_WHITESPACE ();		/* Leading whitespace is part of operand. */
+ 
+   if (current_cframe != NULL && current_cframe->ignoring)
+     {
+       operand.X_add_number = 0;
+       while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ 	++input_line_pointer;
+     }
+   else
+     {
+       expression (&operand);
+       if (operand.X_op != O_constant)
+ 	as_bad (_("non-constant expression in \".elseif\" statement"));
+     }
+   
+   switch ((operatorT) arg)
+     {
+     case O_eq: t = operand.X_add_number == 0; break;
+     case O_ne: t = operand.X_add_number != 0; break;
+     case O_lt: t = operand.X_add_number < 0; break;
+     case O_le: t = operand.X_add_number <= 0; break;
+     case O_ge: t = operand.X_add_number >= 0; break;
+     case O_gt: t = operand.X_add_number > 0; break;
+     default:
+       abort ();
+       return;
+     }
+ 
+   current_cframe->ignoring = current_cframe->dead_tree || ! t;
+ 
+   if (LISTING_SKIP_COND ()
+       && current_cframe->ignoring
+       && (current_cframe->previous_cframe == NULL
+ 	  || ! current_cframe->previous_cframe->ignoring))
+     listing_list (2);
+ 
+   demand_empty_rest_of_line ();
+ }
+ 
+ void 
  s_endif (arg)
       int arg ATTRIBUTE_UNUSED;
  {
Index: gas/doc/as.texinfo
===================================================================
RCS file: /cvs/src/src/gas/doc/as.texinfo,v
retrieving revision 1.7
diff -d -c -p -r1.7 as.texinfo
*** as.texinfo	2000/01/10 22:22:56	1.7
--- as.texinfo	2000/02/07 17:27:37
*************** Some machine configurations provide addi
*** 3109,3114 ****
--- 3109,3115 ----
  * Double::                      @code{.double @var{flonums}}
  * Eject::                       @code{.eject}
  * Else::                        @code{.else}
+ * Elseif::                      @code{.elseif}
  * End::				@code{.end}
  @ifset COFF
  * Endef::                       @code{.endef}
*************** assembly; @pxref{If,,@code{.if}}.  It ma
*** 3466,3471 ****
--- 3467,3480 ----
  of code to be assembled if the condition for the preceding @code{.if}
  was false.
  
+ @node Elseif
+ @section @code{.elseif}
+ 
+ @cindex @code{elseif} directive
+ @code{.elseif} is part of the @code{@value{AS}} support for conditional
+ assembly; @pxref{If,,@code{.if}}.  It is shorthand for beginning a new
+ @code{.if} block that would otherwise fill the entire @code{.else} section.
+ 
  @node End
  @section @code{.end}
  
*************** considered part of the source program be
*** 3694,3699 ****
--- 3703,3710 ----
  the conditional section of code must be marked by @code{.endif}
  (@pxref{Endif,,@code{.endif}}); optionally, you may include code for the
  alternative condition, flagged by @code{.else} (@pxref{Else,,@code{.else}}).
+ If you have several conditions to check, @code{.elseif} may be used to avoid
+ nesting blocks if/else within each subsequent @code{.else} block.
  
  The following variants of @code{.if} are also supported:
  @table @code

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