[PATCH] fix handling of parentheses in macro arguments

Jan Beulich JBeulich@novell.com
Thu Feb 23 08:01:00 GMT 2006


The fix originally introduced for PR/1070 resulted in a number of regressions
(now tested for in gas/macros/paren.s), didn't address all intended cases, and
didn't deal with square brackets at all. This patch reverts all the non-white-
space changes of the original two patches and introduces an alternative
mechanism, which hopefully has no regressions anymore (except for the obvious
case where odd games are played with unmatched parentheses or square brackets
as macro arguments). As a side effect, this also fixes a bug with nested angle
brackets resulting from a typo in the aforementioned patches.

Built and tested on i686-pc-linux-gnu, x86_64-unknown-linux-gnu, and for a
large number of cross targets.

Jan

gas/
2006-02-21  Jan Beulich  <jbeulich@novell.com>

	PR/1070
	* macro.c (getstring): Don't treat parentheses special anymore.
	(get_any_string): Don't consider '(' and ')' as quoting anymore.
	Special-case '(', ')', '[', and ']' when dealing with non-quoting
	characters.

gas/testsuite/
2006-02-21  Jan Beulich  <jbeulich@novell.com>

	* gas/macros/paren[sd]: New.
	* gas/macros/macros.exp: Run new test.

--- /home/jbeulich/src/binutils/mainline/2006-02-21/gas/macro.c	2005-11-07 08:48:26.000000000 +0100
+++ 2006-02-21/gas/macro.c	2006-02-21 14:33:52.000000000 +0100
@@ -303,18 +303,14 @@ getstring (int idx, sb *in, sb *acc)
 {
   while (idx < in->len
 	 && (in->ptr[idx] == '"'
-	     || in->ptr[idx] == '('
 	     || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
 	     || (in->ptr[idx] == '\'' && macro_alternate)))
     {
       if (in->ptr[idx] == '<')
 	{
 	  int nest = 0;
-	  char start_char = '>';
-	  char end_char = '>';
-
 	  idx++;
-	  while ((in->ptr[idx] != end_char || nest)
+	  while ((in->ptr[idx] != '>' || nest)
 		 && idx < in->len)
 	    {
 	      if (in->ptr[idx] == '!')
@@ -324,37 +320,15 @@ getstring (int idx, sb *in, sb *acc)
 		}
 	      else
 		{
-		  if (in->ptr[idx] == end_char)
+		  if (in->ptr[idx] == '>')
 		    nest--;
-		  if (in->ptr[idx] == start_char)
+		  if (in->ptr[idx] == '<')
 		    nest++;
 		  sb_add_char (acc, in->ptr[idx++]);
 		}
 	    }
 	  idx++;
 	}
-      else if (in->ptr[idx] == '(')
-	{
-	  int nest = 0;
-	  char c;
-
-	  do
-	    {
-	      c = in->ptr[idx];
-
-	      if (c == '!')
-		c = in->ptr[++idx];
-	      else if (c == ')')
-		nest--;
-	      else if (c == '(')
-		nest++;
-
-	      sb_add_char (acc, c);
-	      idx++;
-	    }
-	  while ((c != ')' || nest)
-		 && idx < in->len);
-	}
       else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
 	{
 	  char tchar = in->ptr[idx];
@@ -438,7 +412,6 @@ get_any_string (int idx, sb *in, sb *out
 	  sb_add_string (out, buf);
 	}
       else if (in->ptr[idx] == '"'
-	       || in->ptr[idx] == '('
 	       || (in->ptr[idx] == '<' && (macro_alternate || macro_mri))
 	       || (macro_alternate && in->ptr[idx] == '\''))
 	{
@@ -457,27 +430,57 @@ get_any_string (int idx, sb *in, sb *out
 	}
       else
 	{
+	  char *br_buf = xmalloc(1);
+	  char *in_br = br_buf;
+
+	  *in_br = '\0';
 	  while (idx < in->len
-		 && in->ptr[idx] != ' '
-		 && in->ptr[idx] != '\t'
+		 && (*in_br
+		     || (in->ptr[idx] != ' '
+			 && in->ptr[idx] != '\t'))
 		 && in->ptr[idx] != ','
 		 && (in->ptr[idx] != '<'
 		     || (! macro_alternate && ! macro_mri)))
 	    {
-	      if (in->ptr[idx] == '"'
-		  || in->ptr[idx] == '\'')
-		{
-		  char tchar = in->ptr[idx];
+	      char tchar = in->ptr[idx];
 
+	      switch (tchar)
+		{
+		case '"':
+		case '\'':
 		  sb_add_char (out, in->ptr[idx++]);
 		  while (idx < in->len
 			 && in->ptr[idx] != tchar)
 		    sb_add_char (out, in->ptr[idx++]);
 		  if (idx == in->len)
 		    return idx;
+		  break;
+		case '(':
+		case '[':
+		  if (in_br > br_buf)
+		    --in_br;
+		  else
+		    {
+		      br_buf = xmalloc(strlen(in_br) + 2);
+		      strcpy(br_buf + 1, in_br);
+		      free(in_br);
+		      in_br = br_buf;
+		    }
+		  *in_br = tchar;
+		  break;
+		case ')':
+		  if (*in_br == '(')
+		    ++in_br;
+		  break;
+		case ']':
+		  if (*in_br == '[')
+		    ++in_br;
+		  break;
 		}
-	      sb_add_char (out, in->ptr[idx++]);
+	      sb_add_char (out, tchar);
+	      ++idx;
 	    }
+	  free(br_buf);
 	}
     }
 
--- /home/jbeulich/src/binutils/mainline/2006-02-21/gas/testsuite/gas/macros/macros.exp	2005-10-26
14:26:29.000000000 +0200
+++ 2006-02-21/gas/testsuite/gas/macros/macros.exp	2006-02-21 13:51:27.000000000 +0100
@@ -82,3 +82,9 @@ case $target_triplet in {
 run_list_test end ""
 run_list_test purge "--hash-size=8000"
 run_list_test redef ""
+
+# This test is valid only when '!' is not a comment character
+# (it is allowed to be a line comment character).
+if [string match "" [lindex [gas_run ../all/excl.s "-o /dev/null" ""] 0]] {
+    run_dump_test paren
+}
--- /home/jbeulich/src/binutils/mainline/2006-02-21/gas/testsuite/gas/macros/paren.d	1970-01-01 01:00:00.000000000
+0100
+++ 2006-02-21/gas/testsuite/gas/macros/paren.d	2006-02-21 14:30:13.000000000 +0100
@@ -0,0 +1,9 @@
+#as: -f
+#objdump: -s -j .data
+#name parenthesized macro arguments
+
+.*: .*
+
+Contents of section .data:
+ 0000 01000202 020402.. ........ ........  ................
+#pass
--- /home/jbeulich/src/binutils/mainline/2006-02-21/gas/testsuite/gas/macros/paren.s	1970-01-01 01:00:00.000000000
+0100
+++ 2006-02-21/gas/testsuite/gas/macros/paren.s	2006-02-21 14:30:07.000000000 +0100
@@ -0,0 +1,12 @@
+ .data
+ .macro m x
+ .byte (\x)
+ .endm
+
+	m	(1)
+	m	(!1)
+	m	(1)+(1)
+	m	1+(1)
+	m	(1 + 1)
+	m	(1 + 1)*(1 + 1)
+	m	(! 0)+(! 0)

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: binutils-mainline-macro-paren.patch
URL: <https://sourceware.org/pipermail/binutils/attachments/20060223/8618c03d/attachment.ksh>


More information about the Binutils mailing list