This is the mail archive of the binutils@sourceware.org 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]
Other format: [Raw text]

[PATCH] fix handling of parentheses in macro arguments


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)

Attachment: binutils-mainline-macro-paren.patch
Description: Text document


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