public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* Re: [PATCH] Re: .macro behavior
@ 2005-02-09 14:32 Jan Beulich
  2005-02-09 15:03 ` Hans-Peter Nilsson
  0 siblings, 1 reply; 27+ messages in thread
From: Jan Beulich @ 2005-02-09 14:32 UTC (permalink / raw)
  To: hp; +Cc: binutils

>I don't see what's wrong with that.  I'd say it actually
>simplifies macro definitions and usage.  The macro parameter
>name is used only in a macro definition, as a placeholder. It's
>no big limitation to make it alphanumeric_ only.  Otherwise, the
>macro writer that wants to cater to multiple GAS ports (say, in
>a package similar to glibc) would have to avoid making the
>parameter name followed by any non-space character at all, in
>case some port has that character as part of an identifier.

The change doesn't prevent anyone from continuing to only use
alphanumeric characters for macro parameter names. And such a name can
validly only be followed by a comma or equal sign (perhaps whitespace,
but no other punctuation), so allowing more characters for use in
parameter names can't break anything (at least no properly written
code), unless a port allows '=' in symbol names (those, the existence of
which I question, would have to separate parameter name and = by
whitespace).

Jan

^ permalink raw reply	[flat|nested] 27+ messages in thread
* Re: [PATCH] Re: .macro behavior
@ 2005-04-11 12:48 Jan Beulich
  0 siblings, 0 replies; 27+ messages in thread
From: Jan Beulich @ 2005-04-11 12:48 UTC (permalink / raw)
  To: nickc; +Cc: binutils

>>> Nick Clifton <nickc@redhat.com> 01.04.05 16:27:14 >>>
>Hi Jan,
>
>> gas/
>> 2005-03-29  Jan Beulich  <jbeulich@novell.com>
>> 
>> 	* NEWS: Mention these changes and their effects.
>> 	* macro.c (get_token): Use is_name_beginner/is_part_of_name/
>> 	is_name_ender.
>> 	(check_macro): Likewise.
>> 	(buffer_and_nest): Likewise. Permit multiple labels. Don't discard
>> 	labels together with the closing pseudo-op.
>> 	(macro_expand_body): Adjust comment. Range-check input before use.
>> 	Adjust mis-spelled diagnostic. Use is_name_beginner.
>> 	* read.c (try_macro): New.
>> 	(read_a_source_file): New static variable last_eol. Don't list
>> 	macro expansion lines more than once. Call try_macro.
>> 	(s_macro): Set section of line_label to absolute instead of undefined.
>> 
>> gas/testsuite/
>> 2005-03-29  Jan Beulich  <jbeulich@novell.com>
>> 
>> 	* gas/macros/dot.[ls]: New.
>> 	* gas/macros/macros.exp: Run new test.
>
>Approved - please apply.
>
>One request though.  Would it be possible to add entry to the assembler 
>documentation about this new feature, and in particular a lengthier 
>description of:
>
>"...this is known to cause problems in certain sources when the
>  respective target uses characters inconsistently, and thus macro
>  parameter references are no longer recognized as such."
>
>With an example and a suggested workaround.

Done.

^ permalink raw reply	[flat|nested] 27+ messages in thread
* Re: [PATCH] Re: .macro behavior
@ 2005-03-29 16:26 Jan Beulich
  2005-04-01 14:30 ` Nick Clifton
  0 siblings, 1 reply; 27+ messages in thread
From: Jan Beulich @ 2005-03-29 16:26 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 14137 bytes --]

This is a resubmission of the patch at
http://sourceware.org/ml/binutils/2005-02/msg00120.html to address the
inconsistent acceptance of identifiers between the macro handling code and
the rest of the assembler, including the unability to use a macro the name
of which starts with a dot.
Over the previously submitted revisions, this has a small bug fixed and the
new test case slightly changed.

Originally built and tested natively on ia64-unknown-linux-gnu and as cross
tools for a large number of targets. Re-built and re-tested on
x86_64-unknown-linux-gnu.

Jan

gas/
2005-03-29  Jan Beulich  <jbeulich@novell.com>

	* NEWS: Mention these changes and their effects.
	* macro.c (get_token): Use is_name_beginner/is_part_of_name/
	is_name_ender.
	(check_macro): Likewise.
	(buffer_and_nest): Likewise. Permit multiple labels. Don't discard
	labels together with the closing pseudo-op.
	(macro_expand_body): Adjust comment. Range-check input before use.
	Adjust mis-spelled diagnostic. Use is_name_beginner.
	* read.c (try_macro): New.
	(read_a_source_file): New static variable last_eol. Don't list
	macro expansion lines more than once. Call try_macro.
	(s_macro): Set section of line_label to absolute instead of undefined.

gas/testsuite/
2005-03-29  Jan Beulich  <jbeulich@novell.com>

	* gas/macros/dot.[ls]: New.
	* gas/macros/macros.exp: Run new test.

--- /home/jbeulich/src/binutils/mainline/2005-03-29/gas/NEWS	2005-03-29 15:26:51.000000000 +0200
+++ 2005-03-29/gas/NEWS	2005-03-29 16:00:15.131442440 +0200
@@ -1,11 +1,17 @@
 -*- text -*-
 
+* Redefinition of macros now results in an error.
+
+* Macro names and macro parameter names can now be any identifier that would
+  also be legal as a symbol elsewhere. For macro parameter names, this is
+  known to cause problems in certain sources when the respective target uses
+  characters inconsistently, and thus macro parameter references are no longer
+  recognized as such.
+
 * New command line option -mtune=[itanium1|itanium2] for IA64 targets.
 
 Changes in 2.16:
 
-* Redefinition of macros now results in an error.
-
 * New command line option -mhint.b=[ok|warning|error] for IA64 targets.
 
 * New command line option -munwind-check=[warning|error] for IA64
--- /home/jbeulich/src/binutils/mainline/2005-03-29/gas/macro.c	2005-03-04 15:51:40.000000000 +0100
+++ 2005-03-29/gas/macro.c	2005-03-29 15:57:46.380056088 +0200
@@ -187,21 +187,37 @@ buffer_and_nest (const char *from, const
 	     the first column, since we can't tell what's a label and
 	     whats a pseudoop.  */
 
-	  /* Skip leading whitespace.  */
-	  while (i < ptr->len && ISWHITE (ptr->ptr[i]))
-	    i++;
-
-	  /* Skip over a label.  */
-	  while (i < ptr->len
-		 && (ISALNUM (ptr->ptr[i])
-		     || ptr->ptr[i] == '_'
-		     || ptr->ptr[i] == '$'))
-	    i++;
-
-	  /* And a colon.  */
-	  if (i < ptr->len
-	      && ptr->ptr[i] == ':')
-	    i++;
+	  if (! LABELS_WITHOUT_COLONS)
+	    {
+	      /* Skip leading whitespace.  */
+	      while (i < ptr->len && ISWHITE (ptr->ptr[i]))
+		i++;
+	    }
+
+	  for (;;)
+	    {
+	      /* Skip over a label, if any.  */
+	      if (i >= ptr->len || ! is_name_beginner (ptr->ptr[i]))
+		break;
+	      i++;
+	      while (i < ptr->len && is_part_of_name (ptr->ptr[i]))
+		i++;
+	      if (i < ptr->len && is_name_ender (ptr->ptr[i]))
+		i++;
+	      if (LABELS_WITHOUT_COLONS)
+		break;
+	      /* Skip whitespace.  */
+	      while (i < ptr->len && ISWHITE (ptr->ptr[i]))
+		i++;
+	      /* Check for the colon.  */
+	      if (i >= ptr->len || ptr->ptr[i] != ':')
+		{
+		  i = line_start;
+		  break;
+		}
+	      i++;
+	      line_start = i;
+	    }
 
 	}
       /* Skip trailing whitespace.  */
@@ -226,11 +242,13 @@ buffer_and_nest (const char *from, const
 	       ? strncasecmp (ptr->ptr + i, from, from_len) == 0
 	       : from_len > 0)
 	      && (ptr->len == (i + from_len)
-		  || ! ISALNUM (ptr->ptr[i + from_len])))
+		  || ! (is_part_of_name (ptr->ptr[i + from_len])
+			|| is_name_ender (ptr->ptr[i + from_len]))))
 	    depth++;
 	  if (strncasecmp (ptr->ptr + i, to, to_len) == 0
 	      && (ptr->len == (i + to_len)
-		  || ! ISALNUM (ptr->ptr[i + to_len])))
+		  || ! (is_part_of_name (ptr->ptr[i + to_len])
+			|| is_name_ender (ptr->ptr[i + to_len]))))
 	    {
 	      depth--;
 	      if (depth == 0)
@@ -258,15 +276,16 @@ static int
 get_token (int idx, sb *in, sb *name)
 {
   if (idx < in->len
-      && (ISALPHA (in->ptr[idx])
-	  || in->ptr[idx] == '_'
-	  || in->ptr[idx] == '$'))
+      && is_name_beginner (in->ptr[idx]))
     {
       sb_add_char (name, in->ptr[idx++]);
       while (idx < in->len
-	     && (ISALNUM (in->ptr[idx])
-		 || in->ptr[idx] == '_'
-		 || in->ptr[idx] == '$'))
+	     && is_part_of_name (in->ptr[idx]))
+	{
+	  sb_add_char (name, in->ptr[idx++]);
+	}
+      if (idx < in->len
+	     && is_name_ender (in->ptr[idx]))
 	{
 	  sb_add_char (name, in->ptr[idx++]);
 	}
@@ -692,13 +711,14 @@ macro_expand_body (sb *in, sb *out, form
 	  else
 	    {
 	      /* FIXME: Why do we do this?  */
+	      /* At least in alternate mode this seems correct.  */
 	      src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
 	    }
 	}
       else if (in->ptr[src] == '\\')
 	{
 	  src++;
-	  if (in->ptr[src] == '(')
+	  if (src < in->len && in->ptr[src] == '(')
 	    {
 	      /* Sub in till the next ')' literally.  */
 	      src++;
@@ -709,9 +729,9 @@ macro_expand_body (sb *in, sb *out, form
 	      if (in->ptr[src] == ')')
 		src++;
 	      else
-		return _("missplaced )");
+		return _("misplaced `)'");
 	    }
-	  else if (in->ptr[src] == '@')
+	  else if (src < in->len && in->ptr[src] == '@')
 	    {
 	      /* Sub in the macro invocation number.  */
 
@@ -720,7 +740,7 @@ macro_expand_body (sb *in, sb *out, form
 	      sprintf (buffer, "%d", macro_number);
 	      sb_add_string (out, buffer);
 	    }
-	  else if (in->ptr[src] == '&')
+	  else if (src < in->len && in->ptr[src] == '&')
 	    {
 	      /* This is a preprocessor variable name, we don't do them
 		 here.  */
@@ -728,7 +748,7 @@ macro_expand_body (sb *in, sb *out, form
 	      sb_add_char (out, '&');
 	      src++;
 	    }
-	  else if (macro_mri && ISALNUM (in->ptr[src]))
+	  else if (macro_mri && src < in->len && ISALNUM (in->ptr[src]))
 	    {
 	      int ind;
 	      formal_entry *f;
@@ -759,9 +779,7 @@ macro_expand_body (sb *in, sb *out, form
 	    }
 	}
       else if ((macro_alternate || macro_mri)
-	       && (ISALPHA (in->ptr[src])
-		   || in->ptr[src] == '_'
-		   || in->ptr[src] == '$')
+	       && is_name_beginner (in->ptr[src])
 	       && (! inquote
 		   || ! macro_strip_at
 		   || (src > 0 && in->ptr[src - 1] == '@')))
@@ -1086,16 +1104,14 @@ check_macro (const char *line, sb *expan
   macro_entry *macro;
   sb line_sb;
 
-  if (! ISALPHA (*line)
-      && *line != '_'
-      && *line != '$'
+  if (! is_name_beginner (*line)
       && (! macro_mri || *line != '.'))
     return 0;
 
   s = line + 1;
-  while (ISALNUM (*s)
-	 || *s == '_'
-	 || *s == '$')
+  while (is_part_of_name (*s))
+    ++s;
+  if (is_name_ender (*s))
     ++s;
 
   copy = (char *) alloca (s - line + 1);
--- /home/jbeulich/src/binutils/mainline/2005-03-29/gas/read.c	2005-03-02 08:46:24.000000000 +0100
+++ 2005-03-29/gas/read.c	2005-03-29 16:22:02.120749864 +0200
@@ -520,6 +520,32 @@ scrub_from_string (char *buf, int buflen
   return copy;
 }
 
+/* Helper function of read_a_source_file, which tries to expand a macro.  */
+static int
+try_macro (char term, const char *line)
+{
+  sb out;
+  const char *err;
+  macro_entry *macro;
+
+  if (check_macro (line, &out, &err, &macro))
+    {
+      if (err != NULL)
+	as_bad ("%s", err);
+      *input_line_pointer++ = term;
+      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
+      return 1;
+    }
+  return 0;
+}
+
 /* We read the file, putting things into a web that represents what we
    have been reading.  */
 void
@@ -547,6 +573,13 @@ read_a_source_file (char *name)
 
   while ((buffer_limit = input_scrub_next_buffer (&input_line_pointer)) != 0)
     {				/* We have another line to parse.  */
+#ifndef NO_LISTING
+      /* In order to avoid listing macro expansion lines with labels
+	 multiple times, keep track of which line was last issued.  */
+      static char *last_eol;
+
+      last_eol = NULL;
+#endif
       know (buffer_limit[-1] == '\n');	/* Must have a sentinel.  */
 
       while (input_line_pointer < buffer_limit)
@@ -666,17 +699,21 @@ read_a_source_file (char *name)
 		    if (is_end_of_line[(unsigned char) *s])
 		      break;
 
-		  /* Copy it for safe keeping.  Also give an indication of
-		     how much macro nesting is involved at this point.  */
-		  len = s - (input_line_pointer - 1);
-		  copy = (char *) xmalloc (len + macro_nest + 2);
-		  memset (copy, '>', macro_nest);
-		  copy[macro_nest] = ' ';
-		  memcpy (copy + macro_nest + 1, input_line_pointer - 1, len);
-		  copy[macro_nest + 1 + len] = '\0';
+		  if (s != last_eol)
+		    {
+		      last_eol = s;
+		      /* Copy it for safe keeping.  Also give an indication of
+			 how much macro nesting is involved at this point.  */
+		      len = s - (input_line_pointer - 1);
+		      copy = (char *) xmalloc (len + macro_nest + 2);
+		      memset (copy, '>', macro_nest);
+		      copy[macro_nest] = ' ';
+		      memcpy (copy + macro_nest + 1, input_line_pointer - 1, len);
+		      copy[macro_nest + 1 + len] = '\0';
 
-		  /* Install the line with the listing facility.  */
-		  listing_newline (copy);
+		      /* Install the line with the listing facility.  */
+		      listing_newline (copy);
+		    }
 		}
 	      else
 		listing_newline (NULL);
@@ -816,9 +853,18 @@ read_a_source_file (char *name)
 		      /* Print the error msg now, while we still can.  */
 		      if (pop == NULL)
 			{
-			  as_bad (_("unknown pseudo-op: `%s'"), s);
+			  char *end = input_line_pointer;
+
 			  *input_line_pointer = c;
 			  s_ignore (0);
+			  c = *--input_line_pointer;
+			  *input_line_pointer = '\0';
+			  if (! macro_defined || ! try_macro (c, s))
+			    {
+			      *end = '\0';
+			      as_bad (_("unknown pseudo-op: `%s'"), s);
+			      *input_line_pointer++ = c;
+			    }
 			  continue;
 			}
 
@@ -874,28 +920,8 @@ read_a_source_file (char *name)
 
 		      generate_lineno_debug ();
 
-		      if (macro_defined)
-			{
-			  sb out;
-			  const char *err;
-			  macro_entry *macro;
-
-			  if (check_macro (s, &out, &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;
-			    }
-			}
+		      if (macro_defined && try_macro (c, s))
+			continue;
 
 		      if (mri_pending_align)
 			{
@@ -2319,7 +2345,7 @@ s_macro (int ignore ATTRIBUTE_UNUSED)
     {
       if (line_label != NULL)
 	{
-	  S_SET_SEGMENT (line_label, undefined_section);
+	  S_SET_SEGMENT (line_label, absolute_section);
 	  S_SET_VALUE (line_label, 0);
 	  symbol_set_frag (line_label, &zero_address_frag);
 	}
--- /home/jbeulich/src/binutils/mainline/2005-03-29/gas/testsuite/gas/macros/dot.l	1970-01-01 01:00:00.000000000 +0100
+++ 2005-03-29/gas/testsuite/gas/macros/dot.l	2005-03-29 16:26:54.000000000 +0200
@@ -0,0 +1,22 @@
+.*: Assembler messages:
+.*:[1-9][0-9]*: Warning: attempt to redefine pseudo-op .\.macro. ignored
+.*:27: Error: unknown pseudo-op: .\.xyz.
+.*:28: Error: .*
+(.* )?GAS .*
+#...
+[ 	]*[1-9][0-9]*[ 	]+m 4, 2
+[ 	]*[1-9][0-9]*[ 	]+> \.data
+[ 	]*[1-9][0-9]*[ 	]+> labelA:labelB:labelC:labelD:x\.y\.z 4\+2
+[ 	]*[1-9][0-9]*[ 	]+>> \.align 4
+[ 	]*[1-9][0-9]*[ 	]+\?+[ 	]+0606[ 	]+>> \.byte 4\+2,4\+2
+[ 	]*[1-9][0-9]*[ 	]+\?+[ 	]+0000[ 	]+> \.skip 2
+[ 	]*[1-9][0-9]*[ 	]+> labelZ:labelY:labelX:labelW:\.xyz 4-2
+[ 	]*[1-9][0-9]*[ 	]+>> \.align 8
+[ 	]*[1-9][0-9]*[ 	]+\?+[ 	]+0202[ 	]+>> \.byte 4-2,4-2
+[ 	]*[1-9][0-9]*[ 	]+\?+[ 	]+0000 ?0000[ 	]+> \.skip 4\*2
+[ 	]*[1-9][0-9]*[ 	]+0000 ?0000[ 	]*
+[ 	]*[1-9][0-9]*[ 	]+> label9:label8:label7:label6:
+[ 	]*[1-9][0-9]*[ 	]+
+[ 	]*[1-9][0-9]*[ 	]+\.purgem \.xyz, x\.y\.z
+[ 	]*[1-9][0-9]*[ 	]+\.xyz 0
+[ 	]*[1-9][0-9]*[ 	]+x\.y\.z 0
--- /home/jbeulich/src/binutils/mainline/2005-03-29/gas/testsuite/gas/macros/dot.s	1970-01-01 01:00:00.000000000 +0100
+++ 2005-03-29/gas/testsuite/gas/macros/dot.s	2005-02-08 09:57:12.000000000 +0100
@@ -0,0 +1,28 @@
+.altmacro
+
+.macro x.y.z val
+ .align 4
+ .byte val, val
+.endm
+
+.macro .xyz val
+ .align 8
+ .byte val, val
+.endm
+
+.macro .macro
+.endm
+
+label1:label2 : label3 :label4: m: .macro arg.1, arg.2
+ .data
+labelA:labelB : labelC :labelD: x.y.z arg.1+arg.2
+ .skip arg.2
+labelZ:labelY : labelX :labelW: .xyz arg.1-arg.2
+ .skip arg.1*arg.2
+label9:label8 : label7 :label6: .endm
+
+m 4, 2
+
+.purgem .xyz, x.y.z
+.xyz 0
+x.y.z 0
--- /home/jbeulich/src/binutils/mainline/2005-03-29/gas/testsuite/gas/macros/macros.exp	2005-03-04 15:51:53.000000000 +0100
+++ 2005-03-29/gas/testsuite/gas/macros/macros.exp	2005-03-29 15:57:46.389054720 +0200
@@ -68,5 +68,14 @@ run_dump_test app3
 run_dump_test app4
 
 run_list_test badarg ""
+case $target_triplet in {
+    { *c54x*-*-* } { }
+    { *c4x*-*-* } { }
+    { h8500-*-* } { }
+    { m68*-*-* } { }
+    { m88*-*-* } { }
+    { mmix-* } { }
+    default { run_list_test dot "-alm" }
+}
 run_list_test end ""
 run_list_test redef ""


[-- Attachment #2: binutils-mainline-macro-identifiers.patch --]
[-- Type: text/plain, Size: 13691 bytes --]

This is a resubmission of the patch at
http://sourceware.org/ml/binutils/2005-02/msg00120.html to address the
inconsistent acceptance of identifiers between the macro handling code and
the rest of the assembler, including the unability to use a macro the name
of which starts with a dot.
Over the previously submitted revisions, this has a small bug fixed and the
new test case slightly changed.

Originally built and tested natively on ia64-unknown-linux-gnu and as cross
tools for a large number of targets. Re-built and re-tested on
x86_64-unknown-linux-gnu.

Jan

gas/
2005-03-29  Jan Beulich  <jbeulich@novell.com>

	* NEWS: Mention these changes and their effects.
	* macro.c (get_token): Use is_name_beginner/is_part_of_name/
	is_name_ender.
	(check_macro): Likewise.
	(buffer_and_nest): Likewise. Permit multiple labels. Don't discard
	labels together with the closing pseudo-op.
	(macro_expand_body): Adjust comment. Range-check input before use.
	Adjust mis-spelled diagnostic. Use is_name_beginner.
	* read.c (try_macro): New.
	(read_a_source_file): New static variable last_eol. Don't list
	macro expansion lines more than once. Call try_macro.
	(s_macro): Set section of line_label to absolute instead of undefined.

gas/testsuite/
2005-03-29  Jan Beulich  <jbeulich@novell.com>

	* gas/macros/dot.[ls]: New.
	* gas/macros/macros.exp: Run new test.

--- /home/jbeulich/src/binutils/mainline/2005-03-29/gas/NEWS	2005-03-29 15:26:51.000000000 +0200
+++ 2005-03-29/gas/NEWS	2005-03-29 16:00:15.131442440 +0200
@@ -1,11 +1,17 @@
 -*- text -*-
 
+* Redefinition of macros now results in an error.
+
+* Macro names and macro parameter names can now be any identifier that would
+  also be legal as a symbol elsewhere. For macro parameter names, this is
+  known to cause problems in certain sources when the respective target uses
+  characters inconsistently, and thus macro parameter references are no longer
+  recognized as such.
+
 * New command line option -mtune=[itanium1|itanium2] for IA64 targets.
 
 Changes in 2.16:
 
-* Redefinition of macros now results in an error.
-
 * New command line option -mhint.b=[ok|warning|error] for IA64 targets.
 
 * New command line option -munwind-check=[warning|error] for IA64
--- /home/jbeulich/src/binutils/mainline/2005-03-29/gas/macro.c	2005-03-04 15:51:40.000000000 +0100
+++ 2005-03-29/gas/macro.c	2005-03-29 15:57:46.380056088 +0200
@@ -187,21 +187,37 @@ buffer_and_nest (const char *from, const
 	     the first column, since we can't tell what's a label and
 	     whats a pseudoop.  */
 
-	  /* Skip leading whitespace.  */
-	  while (i < ptr->len && ISWHITE (ptr->ptr[i]))
-	    i++;
-
-	  /* Skip over a label.  */
-	  while (i < ptr->len
-		 && (ISALNUM (ptr->ptr[i])
-		     || ptr->ptr[i] == '_'
-		     || ptr->ptr[i] == '$'))
-	    i++;
-
-	  /* And a colon.  */
-	  if (i < ptr->len
-	      && ptr->ptr[i] == ':')
-	    i++;
+	  if (! LABELS_WITHOUT_COLONS)
+	    {
+	      /* Skip leading whitespace.  */
+	      while (i < ptr->len && ISWHITE (ptr->ptr[i]))
+		i++;
+	    }
+
+	  for (;;)
+	    {
+	      /* Skip over a label, if any.  */
+	      if (i >= ptr->len || ! is_name_beginner (ptr->ptr[i]))
+		break;
+	      i++;
+	      while (i < ptr->len && is_part_of_name (ptr->ptr[i]))
+		i++;
+	      if (i < ptr->len && is_name_ender (ptr->ptr[i]))
+		i++;
+	      if (LABELS_WITHOUT_COLONS)
+		break;
+	      /* Skip whitespace.  */
+	      while (i < ptr->len && ISWHITE (ptr->ptr[i]))
+		i++;
+	      /* Check for the colon.  */
+	      if (i >= ptr->len || ptr->ptr[i] != ':')
+		{
+		  i = line_start;
+		  break;
+		}
+	      i++;
+	      line_start = i;
+	    }
 
 	}
       /* Skip trailing whitespace.  */
@@ -226,11 +242,13 @@ buffer_and_nest (const char *from, const
 	       ? strncasecmp (ptr->ptr + i, from, from_len) == 0
 	       : from_len > 0)
 	      && (ptr->len == (i + from_len)
-		  || ! ISALNUM (ptr->ptr[i + from_len])))
+		  || ! (is_part_of_name (ptr->ptr[i + from_len])
+			|| is_name_ender (ptr->ptr[i + from_len]))))
 	    depth++;
 	  if (strncasecmp (ptr->ptr + i, to, to_len) == 0
 	      && (ptr->len == (i + to_len)
-		  || ! ISALNUM (ptr->ptr[i + to_len])))
+		  || ! (is_part_of_name (ptr->ptr[i + to_len])
+			|| is_name_ender (ptr->ptr[i + to_len]))))
 	    {
 	      depth--;
 	      if (depth == 0)
@@ -258,15 +276,16 @@ static int
 get_token (int idx, sb *in, sb *name)
 {
   if (idx < in->len
-      && (ISALPHA (in->ptr[idx])
-	  || in->ptr[idx] == '_'
-	  || in->ptr[idx] == '$'))
+      && is_name_beginner (in->ptr[idx]))
     {
       sb_add_char (name, in->ptr[idx++]);
       while (idx < in->len
-	     && (ISALNUM (in->ptr[idx])
-		 || in->ptr[idx] == '_'
-		 || in->ptr[idx] == '$'))
+	     && is_part_of_name (in->ptr[idx]))
+	{
+	  sb_add_char (name, in->ptr[idx++]);
+	}
+      if (idx < in->len
+	     && is_name_ender (in->ptr[idx]))
 	{
 	  sb_add_char (name, in->ptr[idx++]);
 	}
@@ -692,13 +711,14 @@ macro_expand_body (sb *in, sb *out, form
 	  else
 	    {
 	      /* FIXME: Why do we do this?  */
+	      /* At least in alternate mode this seems correct.  */
 	      src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
 	    }
 	}
       else if (in->ptr[src] == '\\')
 	{
 	  src++;
-	  if (in->ptr[src] == '(')
+	  if (src < in->len && in->ptr[src] == '(')
 	    {
 	      /* Sub in till the next ')' literally.  */
 	      src++;
@@ -709,9 +729,9 @@ macro_expand_body (sb *in, sb *out, form
 	      if (in->ptr[src] == ')')
 		src++;
 	      else
-		return _("missplaced )");
+		return _("misplaced `)'");
 	    }
-	  else if (in->ptr[src] == '@')
+	  else if (src < in->len && in->ptr[src] == '@')
 	    {
 	      /* Sub in the macro invocation number.  */
 
@@ -720,7 +740,7 @@ macro_expand_body (sb *in, sb *out, form
 	      sprintf (buffer, "%d", macro_number);
 	      sb_add_string (out, buffer);
 	    }
-	  else if (in->ptr[src] == '&')
+	  else if (src < in->len && in->ptr[src] == '&')
 	    {
 	      /* This is a preprocessor variable name, we don't do them
 		 here.  */
@@ -728,7 +748,7 @@ macro_expand_body (sb *in, sb *out, form
 	      sb_add_char (out, '&');
 	      src++;
 	    }
-	  else if (macro_mri && ISALNUM (in->ptr[src]))
+	  else if (macro_mri && src < in->len && ISALNUM (in->ptr[src]))
 	    {
 	      int ind;
 	      formal_entry *f;
@@ -759,9 +779,7 @@ macro_expand_body (sb *in, sb *out, form
 	    }
 	}
       else if ((macro_alternate || macro_mri)
-	       && (ISALPHA (in->ptr[src])
-		   || in->ptr[src] == '_'
-		   || in->ptr[src] == '$')
+	       && is_name_beginner (in->ptr[src])
 	       && (! inquote
 		   || ! macro_strip_at
 		   || (src > 0 && in->ptr[src - 1] == '@')))
@@ -1086,16 +1104,14 @@ check_macro (const char *line, sb *expan
   macro_entry *macro;
   sb line_sb;
 
-  if (! ISALPHA (*line)
-      && *line != '_'
-      && *line != '$'
+  if (! is_name_beginner (*line)
       && (! macro_mri || *line != '.'))
     return 0;
 
   s = line + 1;
-  while (ISALNUM (*s)
-	 || *s == '_'
-	 || *s == '$')
+  while (is_part_of_name (*s))
+    ++s;
+  if (is_name_ender (*s))
     ++s;
 
   copy = (char *) alloca (s - line + 1);
--- /home/jbeulich/src/binutils/mainline/2005-03-29/gas/read.c	2005-03-02 08:46:24.000000000 +0100
+++ 2005-03-29/gas/read.c	2005-03-29 16:22:02.120749864 +0200
@@ -520,6 +520,32 @@ scrub_from_string (char *buf, int buflen
   return copy;
 }
 
+/* Helper function of read_a_source_file, which tries to expand a macro.  */
+static int
+try_macro (char term, const char *line)
+{
+  sb out;
+  const char *err;
+  macro_entry *macro;
+
+  if (check_macro (line, &out, &err, &macro))
+    {
+      if (err != NULL)
+	as_bad ("%s", err);
+      *input_line_pointer++ = term;
+      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
+      return 1;
+    }
+  return 0;
+}
+
 /* We read the file, putting things into a web that represents what we
    have been reading.  */
 void
@@ -547,6 +573,13 @@ read_a_source_file (char *name)
 
   while ((buffer_limit = input_scrub_next_buffer (&input_line_pointer)) != 0)
     {				/* We have another line to parse.  */
+#ifndef NO_LISTING
+      /* In order to avoid listing macro expansion lines with labels
+	 multiple times, keep track of which line was last issued.  */
+      static char *last_eol;
+
+      last_eol = NULL;
+#endif
       know (buffer_limit[-1] == '\n');	/* Must have a sentinel.  */
 
       while (input_line_pointer < buffer_limit)
@@ -666,17 +699,21 @@ read_a_source_file (char *name)
 		    if (is_end_of_line[(unsigned char) *s])
 		      break;
 
-		  /* Copy it for safe keeping.  Also give an indication of
-		     how much macro nesting is involved at this point.  */
-		  len = s - (input_line_pointer - 1);
-		  copy = (char *) xmalloc (len + macro_nest + 2);
-		  memset (copy, '>', macro_nest);
-		  copy[macro_nest] = ' ';
-		  memcpy (copy + macro_nest + 1, input_line_pointer - 1, len);
-		  copy[macro_nest + 1 + len] = '\0';
+		  if (s != last_eol)
+		    {
+		      last_eol = s;
+		      /* Copy it for safe keeping.  Also give an indication of
+			 how much macro nesting is involved at this point.  */
+		      len = s - (input_line_pointer - 1);
+		      copy = (char *) xmalloc (len + macro_nest + 2);
+		      memset (copy, '>', macro_nest);
+		      copy[macro_nest] = ' ';
+		      memcpy (copy + macro_nest + 1, input_line_pointer - 1, len);
+		      copy[macro_nest + 1 + len] = '\0';
 
-		  /* Install the line with the listing facility.  */
-		  listing_newline (copy);
+		      /* Install the line with the listing facility.  */
+		      listing_newline (copy);
+		    }
 		}
 	      else
 		listing_newline (NULL);
@@ -816,9 +853,18 @@ read_a_source_file (char *name)
 		      /* Print the error msg now, while we still can.  */
 		      if (pop == NULL)
 			{
-			  as_bad (_("unknown pseudo-op: `%s'"), s);
+			  char *end = input_line_pointer;
+
 			  *input_line_pointer = c;
 			  s_ignore (0);
+			  c = *--input_line_pointer;
+			  *input_line_pointer = '\0';
+			  if (! macro_defined || ! try_macro (c, s))
+			    {
+			      *end = '\0';
+			      as_bad (_("unknown pseudo-op: `%s'"), s);
+			      *input_line_pointer++ = c;
+			    }
 			  continue;
 			}
 
@@ -874,28 +920,8 @@ read_a_source_file (char *name)
 
 		      generate_lineno_debug ();
 
-		      if (macro_defined)
-			{
-			  sb out;
-			  const char *err;
-			  macro_entry *macro;
-
-			  if (check_macro (s, &out, &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;
-			    }
-			}
+		      if (macro_defined && try_macro (c, s))
+			continue;
 
 		      if (mri_pending_align)
 			{
@@ -2319,7 +2345,7 @@ s_macro (int ignore ATTRIBUTE_UNUSED)
     {
       if (line_label != NULL)
 	{
-	  S_SET_SEGMENT (line_label, undefined_section);
+	  S_SET_SEGMENT (line_label, absolute_section);
 	  S_SET_VALUE (line_label, 0);
 	  symbol_set_frag (line_label, &zero_address_frag);
 	}
--- /home/jbeulich/src/binutils/mainline/2005-03-29/gas/testsuite/gas/macros/dot.l	1970-01-01 01:00:00.000000000 +0100
+++ 2005-03-29/gas/testsuite/gas/macros/dot.l	2005-03-29 16:26:54.000000000 +0200
@@ -0,0 +1,22 @@
+.*: Assembler messages:
+.*:[1-9][0-9]*: Warning: attempt to redefine pseudo-op .\.macro. ignored
+.*:27: Error: unknown pseudo-op: .\.xyz.
+.*:28: Error: .*
+(.* )?GAS .*
+#...
+[ 	]*[1-9][0-9]*[ 	]+m 4, 2
+[ 	]*[1-9][0-9]*[ 	]+> \.data
+[ 	]*[1-9][0-9]*[ 	]+> labelA:labelB:labelC:labelD:x\.y\.z 4\+2
+[ 	]*[1-9][0-9]*[ 	]+>> \.align 4
+[ 	]*[1-9][0-9]*[ 	]+\?+[ 	]+0606[ 	]+>> \.byte 4\+2,4\+2
+[ 	]*[1-9][0-9]*[ 	]+\?+[ 	]+0000[ 	]+> \.skip 2
+[ 	]*[1-9][0-9]*[ 	]+> labelZ:labelY:labelX:labelW:\.xyz 4-2
+[ 	]*[1-9][0-9]*[ 	]+>> \.align 8
+[ 	]*[1-9][0-9]*[ 	]+\?+[ 	]+0202[ 	]+>> \.byte 4-2,4-2
+[ 	]*[1-9][0-9]*[ 	]+\?+[ 	]+0000 ?0000[ 	]+> \.skip 4\*2
+[ 	]*[1-9][0-9]*[ 	]+0000 ?0000[ 	]*
+[ 	]*[1-9][0-9]*[ 	]+> label9:label8:label7:label6:
+[ 	]*[1-9][0-9]*[ 	]+
+[ 	]*[1-9][0-9]*[ 	]+\.purgem \.xyz, x\.y\.z
+[ 	]*[1-9][0-9]*[ 	]+\.xyz 0
+[ 	]*[1-9][0-9]*[ 	]+x\.y\.z 0
--- /home/jbeulich/src/binutils/mainline/2005-03-29/gas/testsuite/gas/macros/dot.s	1970-01-01 01:00:00.000000000 +0100
+++ 2005-03-29/gas/testsuite/gas/macros/dot.s	2005-02-08 09:57:12.000000000 +0100
@@ -0,0 +1,28 @@
+.altmacro
+
+.macro x.y.z val
+ .align 4
+ .byte val, val
+.endm
+
+.macro .xyz val
+ .align 8
+ .byte val, val
+.endm
+
+.macro .macro
+.endm
+
+label1:label2 : label3 :label4: m: .macro arg.1, arg.2
+ .data
+labelA:labelB : labelC :labelD: x.y.z arg.1+arg.2
+ .skip arg.2
+labelZ:labelY : labelX :labelW: .xyz arg.1-arg.2
+ .skip arg.1*arg.2
+label9:label8 : label7 :label6: .endm
+
+m 4, 2
+
+.purgem .xyz, x.y.z
+.xyz 0
+x.y.z 0
--- /home/jbeulich/src/binutils/mainline/2005-03-29/gas/testsuite/gas/macros/macros.exp	2005-03-04 15:51:53.000000000 +0100
+++ 2005-03-29/gas/testsuite/gas/macros/macros.exp	2005-03-29 15:57:46.389054720 +0200
@@ -68,5 +68,14 @@ run_dump_test app3
 run_dump_test app4
 
 run_list_test badarg ""
+case $target_triplet in {
+    { *c54x*-*-* } { }
+    { *c4x*-*-* } { }
+    { h8500-*-* } { }
+    { m68*-*-* } { }
+    { m88*-*-* } { }
+    { mmix-* } { }
+    default { run_list_test dot "-alm" }
+}
 run_list_test end ""
 run_list_test redef ""

^ permalink raw reply	[flat|nested] 27+ messages in thread
[parent not found: <s225d5fa.098@emea1-mh.id2.novell.com>]
* Re: [PATCH] Re: .macro behavior
@ 2005-03-02 15:04 Jan Beulich
  0 siblings, 0 replies; 27+ messages in thread
From: Jan Beulich @ 2005-03-02 15:04 UTC (permalink / raw)
  To: ian; +Cc: binutils

>I'm reading this, but I don't have any particular comment.  The
>current behaviour was an accident of implementation.  I think Steve
>and Judy wrote gasp over a weekend once, and I didn't change the
>behaviour when I reworked it into gas.  But I don't really have an
>opinion on what the right behaviour should be.

So if neither you nor anyone else of the general maintainers has an
opion here (presumably because macros are rarely used, and even if
they're used then only to do simple tings), how should I proceed? I
wouldn't want to maintain this change outside of the tree...

Jan

^ permalink raw reply	[flat|nested] 27+ messages in thread
* Re: [PATCH] Re: .macro behavior
@ 2005-03-02  8:28 Jan Beulich
  2005-03-02 14:42 ` Ian Lance Taylor
  0 siblings, 1 reply; 27+ messages in thread
From: Jan Beulich @ 2005-03-02  8:28 UTC (permalink / raw)
  To: binutils

>And I still think there's greater benefit from keeping the
>syntax of macro *parameter names* the same as today, something
>like "[A-Za-z_][A-Za-z0-9_]+" and not dependent on the target
>symbol character set.  (Heh, saying :alpha: and :alnum: would
>imply it's locale-dependent.  I don't think we want *that*! ;-)

One additional note here: The current behavior is to allow
"[A-Za-z_$][A-Za-z0-9_$]+", which already is in conflict with some
targets' use of '$' (see those defining LEX_DOLLAR).
I would consider it acceptable to shrink the set down to
"[A-Za-z_][A-Za-z0-9_]+" as you suggest (in order to be largest commonly
acceptable set in general. However, since macros can be used to define
macros, having a way to avoid 'common' symbol names may be quite
valuable, and having available as option here only underscores (to add a
prefix and/or suffix) may make things rather difficult. I'd therefore
like to not restrict targets that allow a reasonable set of additional
symbol characters from actually using them here.

Still, I'm hoping to get comments on this from others, namely Ian, who
originally agreed that the current behavior doesn't seem to be
intended.

Jan

^ permalink raw reply	[flat|nested] 27+ messages in thread
* Re: [PATCH] Re: .macro behavior
@ 2005-02-28 19:22 Jan Beulich
  2005-02-28 23:47 ` Hans-Peter Nilsson
  0 siblings, 1 reply; 27+ messages in thread
From: Jan Beulich @ 2005-02-28 19:22 UTC (permalink / raw)
  To: hp; +Cc: binutils

>No, thanks, I don't like MMIX being accused of being
>"inconsistent" like that.  It *is* consistent - all trailing
>":"s are chopped off.  I think I now remember why; it's not
>really related to ":" as separating namespaces, but the main
>reason is so I could run the binutils test-suite!  Most tests
>"unportably"  assumes that ":" is a label delimiter and not part
>of the label.  Maybe I should insiste that tests be rewritten
>and labels there be defined as "label .set ." :-)

I didn't mean to offend you. Do you have an alternative suggestion for
the wording then?

Jan

^ permalink raw reply	[flat|nested] 27+ messages in thread
* Re: [PATCH] Re: .macro behavior
@ 2005-02-28 13:37 Jan Beulich
  2005-02-28 17:14 ` Hans-Peter Nilsson
  0 siblings, 1 reply; 27+ messages in thread
From: Jan Beulich @ 2005-02-28 13:37 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 13748 bytes --]

This is a resubmission of the patch at
http://sourceware.org/ml/binutils/2005-02/msg00120.html to address the
inconsistent acceptance of identifiers between the macro handling code
and
the rest of the assembler, including the unability to use a macro the
name
of which starts with a dot.
Over the previously submitted revisions, this has just cosmetic
changes
(NEWS entry, change to MMIX testcase removed again based on that
target's
maintainer's request) and thus I did not re-build or re-run the tests.
I'm
not sure why there wasn't any comment of non-cosmetic nature so far; I
had
hoped to at least get pointers to and reasons for what needs to change
to
make this acceptable.

Originally built and tested natively on ia64-unknown-linux-gnu and as
cross
tools for a large number of targets.

Jan

gas/
2005-02-28  Jan Beulich  <jbeulich@novell.com>

	* NEWS: Mention these changes and their effects.
	* macro.c (get_token): Use is_name_beginner/is_part_of_name/
	is_name_ender.
	(check_macro): Likewise.
	(buffer_and_nest): Likewise. Permit multiple labels. Don't
discard
	labels together with the closing pseudo-op.
	(macro_expand_body): Adjust comment. Range-check input before
use.
	Adjust mis-spelled diagnostic. Use is_name_beginner.
	* read.c (try_macro): New.
	(read_a_source_file): New static variable last_eol. Don't list
	macro expansion lines more than once. Call try_macro.
	(s_macro): Set section of line_label to absolute instead of
undefined.

gas/testsuite/
2005-02-28  Jan Beulich  <jbeulich@novell.com>

	* gas/macros/dot.[ls]: New.
	* gas/macros/macros.exp: Run new test.

---
/home/jbeulich/src/binutils/mainline/2005-02-28/gas/NEWS	2005-02-28
08:27:12.000000000 +0100
+++ 2005-02-28/gas/NEWS	2005-02-28 09:52:47.000000000 +0100
@@ -1,5 +1,11 @@
 -*- text -*-
 
+* Macro names and macro parameter names can now be any identifier that
would
+  also be legal as a symbol elsewhere. For macro parameter names, this
is
+  known to cause problems in certain sources when the respective
target uses
+  characters inconsistently (like MMIX's use of ':'), and thus macro
+  parameter references are no longer recognized as such.
+
 * New command line option -mhint.b=[ok|warning|error] for IA64
targets.
 
 * New command line option -munwind-check=[warning|error] for IA64
---
/home/jbeulich/src/binutils/mainline/2005-02-28/gas/macro.c	2005-01-31
15:27:07.000000000 +0100
+++ 2005-02-28/gas/macro.c	2005-02-03 15:12:04.000000000 +0100
@@ -187,21 +187,37 @@ buffer_and_nest (const char *from, const
 	     the first column, since we can't tell what's a label and
 	     whats a pseudoop.  */
 
-	  /* Skip leading whitespace.  */
-	  while (i < ptr->len && ISWHITE (ptr->ptr[i]))
-	    i++;
-
-	  /* Skip over a label.  */
-	  while (i < ptr->len
-		 && (ISALNUM (ptr->ptr[i])
-		     || ptr->ptr[i] == '_'
-		     || ptr->ptr[i] == '$'))
-	    i++;
-
-	  /* And a colon.  */
-	  if (i < ptr->len
-	      && ptr->ptr[i] == ':')
-	    i++;
+	  if (! LABELS_WITHOUT_COLONS)
+	    {
+	      /* Skip leading whitespace.  */
+	      while (i < ptr->len && ISWHITE (ptr->ptr[i]))
+		i++;
+	    }
+
+	  for (;;)
+	    {
+	      /* Skip over a label, if any.  */
+	      if (i >= ptr->len || ! is_name_beginner (ptr->ptr[i]))
+		break;
+	      i++;
+	      while (i < ptr->len && is_part_of_name (ptr->ptr[i]))
+		i++;
+	      if (i < ptr->len && is_name_ender (ptr->ptr[i]))
+		i++;
+	      if (LABELS_WITHOUT_COLONS)
+		break;
+	      /* Skip whitespace.  */
+	      while (i < ptr->len && ISWHITE (ptr->ptr[i]))
+		i++;
+	      /* Check for the colon.  */
+	      if (i >= ptr->len || ptr->ptr[i] != ':')
+		{
+		  i = line_start;
+		  break;
+		}
+	      i++;
+	      line_start = i;
+	    }
 
 	}
       /* Skip trailing whitespace.  */
@@ -226,11 +242,13 @@ buffer_and_nest (const char *from, const
 	       ? strncasecmp (ptr->ptr + i, from, from_len) == 0
 	       : from_len > 0)
 	      && (ptr->len == (i + from_len)
-		  || ! ISALNUM (ptr->ptr[i + from_len])))
+		  || ! (is_part_of_name (ptr->ptr[i + from_len])
+			|| is_name_ender (ptr->ptr[i + from_len]))))
 	    depth++;
 	  if (strncasecmp (ptr->ptr + i, to, to_len) == 0
 	      && (ptr->len == (i + to_len)
-		  || ! ISALNUM (ptr->ptr[i + to_len])))
+		  || ! (is_part_of_name (ptr->ptr[i + to_len])
+			|| is_name_ender (ptr->ptr[i + to_len]))))
 	    {
 	      depth--;
 	      if (depth == 0)
@@ -258,15 +276,16 @@ static int
 get_token (int idx, sb *in, sb *name)
 {
   if (idx < in->len
-      && (ISALPHA (in->ptr[idx])
-	  || in->ptr[idx] == '_'
-	  || in->ptr[idx] == '$'))
+      && is_name_beginner (in->ptr[idx]))
     {
       sb_add_char (name, in->ptr[idx++]);
       while (idx < in->len
-	     && (ISALNUM (in->ptr[idx])
-		 || in->ptr[idx] == '_'
-		 || in->ptr[idx] == '$'))
+	     && is_part_of_name (in->ptr[idx]))
+	{
+	  sb_add_char (name, in->ptr[idx++]);
+	}
+      if (idx < in->len
+	     && is_name_ender (in->ptr[idx]))
 	{
 	  sb_add_char (name, in->ptr[idx++]);
 	}
@@ -692,13 +711,14 @@ macro_expand_body (sb *in, sb *out, form
 	  else
 	    {
 	      /* FIXME: Why do we do this?  */
+	      /* At least in alternate mode this seems correct.  */
 	      src = sub_actual (src + 1, in, &t, formal_hash, '&', out,
0);
 	    }
 	}
       else if (in->ptr[src] == '\\')
 	{
 	  src++;
-	  if (in->ptr[src] == '(')
+	  if (src < in->len && in->ptr[src] == '(')
 	    {
 	      /* Sub in till the next ')' literally.  */
 	      src++;
@@ -709,9 +729,9 @@ macro_expand_body (sb *in, sb *out, form
 	      if (in->ptr[src] == ')')
 		src++;
 	      else
-		return _("missplaced )");
+		return _("misplaced `)'");
 	    }
-	  else if (in->ptr[src] == '@')
+	  else if (src < in->len && in->ptr[src] == '@')
 	    {
 	      /* Sub in the macro invocation number.  */
 
@@ -720,7 +740,7 @@ macro_expand_body (sb *in, sb *out, form
 	      sprintf (buffer, "%d", macro_number);
 	      sb_add_string (out, buffer);
 	    }
-	  else if (in->ptr[src] == '&')
+	  else if (src < in->len && in->ptr[src] == '&')
 	    {
 	      /* This is a preprocessor variable name, we don't do them
 		 here.  */
@@ -728,7 +748,7 @@ macro_expand_body (sb *in, sb *out, form
 	      sb_add_char (out, '&');
 	      src++;
 	    }
-	  else if (macro_mri && ISALNUM (in->ptr[src]))
+	  else if (macro_mri && src < in->len && ISALNUM
(in->ptr[src]))
 	    {
 	      int ind;
 	      formal_entry *f;
@@ -759,9 +779,7 @@ macro_expand_body (sb *in, sb *out, form
 	    }
 	}
       else if ((macro_alternate || macro_mri)
-	       && (ISALPHA (in->ptr[src])
-		   || in->ptr[src] == '_'
-		   || in->ptr[src] == '$')
+	       && is_name_beginner (in->ptr[src])
 	       && (! inquote
 		   || ! macro_strip_at
 		   || (src > 0 && in->ptr[src - 1] == '@')))
@@ -1086,16 +1104,14 @@ check_macro (const char *line, sb *expan
   macro_entry *macro;
   sb line_sb;
 
-  if (! ISALPHA (*line)
-      && *line != '_'
-      && *line != '$'
+  if (! is_name_beginner (*line)
       && (! macro_mri || *line != '.'))
     return 0;
 
   s = line + 1;
-  while (ISALNUM (*s)
-	 || *s == '_'
-	 || *s == '$')
+  while (is_part_of_name (*s))
+    ++s;
+  if (is_name_ender (*s))
     ++s;
 
   copy = (char *) alloca (s - line + 1);
---
/home/jbeulich/src/binutils/mainline/2005-02-28/gas/read.c	2005-02-28
08:27:13.000000000 +0100
+++ 2005-02-28/gas/read.c	2005-02-28 09:39:16.502014184 +0100
@@ -520,6 +520,32 @@ scrub_from_string (char *buf, int buflen
   return copy;
 }
 
+/* Helper function of read_a_source_file, which tries to expand a
macro.  */
+static int
+try_macro (char term, const char *line)
+{
+  sb out;
+  const char *err;
+  macro_entry *macro;
+
+  if (check_macro (line, &out, &err, &macro))
+    {
+      if (err != NULL)
+	as_bad ("%s", err);
+      *input_line_pointer++ = term;
+      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
+      return 1;
+    }
+  return 0;
+}
+
 /* We read the file, putting things into a web that represents what
we
    have been reading.  */
 void
@@ -547,6 +573,13 @@ read_a_source_file (char *name)
 
   while ((buffer_limit = input_scrub_next_buffer
(&input_line_pointer)) != 0)
     {				/* We have another line to parse.  */
+#ifndef NO_LISTING
+      /* In order to avoid listing macro expansion lines with labels
+	 multiple times, keep track of which line was last issued.  */
+      static char *last_eol;
+
+      last_eol = NULL;
+#endif
       know (buffer_limit[-1] == '\n');	/* Must have a sentinel.
 */
 
       while (input_line_pointer < buffer_limit)
@@ -666,17 +699,21 @@ read_a_source_file (char *name)
 		    if (is_end_of_line[(unsigned char) *s])
 		      break;
 
-		  /* Copy it for safe keeping.  Also give an indication
of
-		     how much macro nesting is involved at this point. 
*/
-		  len = s - (input_line_pointer - 1);
-		  copy = (char *) xmalloc (len + macro_nest + 2);
-		  memset (copy, '>', macro_nest);
-		  copy[macro_nest] = ' ';
-		  memcpy (copy + macro_nest + 1, input_line_pointer - 1,
len);
-		  copy[macro_nest + 1 + len] = '\0';
+		  if (s != last_eol)
+		    {
+		      last_eol = s;
+		      /* Copy it for safe keeping.  Also give an
indication of
+			 how much macro nesting is involved at this
point.  */
+		      len = s - (input_line_pointer - 1);
+		      copy = (char *) xmalloc (len + macro_nest + 2);
+		      memset (copy, '>', macro_nest);
+		      copy[macro_nest] = ' ';
+		      memcpy (copy + macro_nest + 1, input_line_pointer
- 1, len);
+		      copy[macro_nest + 1 + len] = '\0';
 
-		  /* Install the line with the listing facility.  */
-		  listing_newline (copy);
+		      /* Install the line with the listing facility. 
*/
+		      listing_newline (copy);
+		    }
 		}
 	      else
 		listing_newline (NULL);
@@ -816,9 +853,17 @@ read_a_source_file (char *name)
 		      /* Print the error msg now, while we still can. 
*/
 		      if (pop == NULL)
 			{
-			  as_bad (_("unknown pseudo-op: `%s'"), s);
+			  char *end = input_line_pointer;
+
 			  *input_line_pointer = c;
 			  s_ignore (0);
+			  c = *input_line_pointer;
+			  *input_line_pointer = '\0';
+			  if (! macro_defined || ! try_macro (c, s))
+			    {
+			      *end = '\0';
+			      as_bad (_("unknown pseudo-op: `%s'"), s);
+			    }
 			  continue;
 			}
 
@@ -874,28 +919,8 @@ read_a_source_file (char *name)
 
 		      generate_lineno_debug ();
 
-		      if (macro_defined)
-			{
-			  sb out;
-			  const char *err;
-			  macro_entry *macro;
-
-			  if (check_macro (s, &out, &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;
-			    }
-			}
+		      if (macro_defined && try_macro (c, s))
+			continue;
 
 		      if (mri_pending_align)
 			{
@@ -2320,7 +2345,7 @@ s_macro (int ignore ATTRIBUTE_UNUSED)
     {
       if (line_label != NULL)
 	{
-	  S_SET_SEGMENT (line_label, undefined_section);
+	  S_SET_SEGMENT (line_label, absolute_section);
 	  S_SET_VALUE (line_label, 0);
 	  symbol_set_frag (line_label, &zero_address_frag);
 	}
---
/home/jbeulich/src/binutils/mainline/2005-02-28/gas/testsuite/gas/macros/dot.l	1970-01-01
01:00:00.000000000 +0100
+++ 2005-02-28/gas/testsuite/gas/macros/dot.l	2005-02-04
10:54:39.000000000 +0100
@@ -0,0 +1,22 @@
+.*: Assembler messages:
+.*:[1-9][0-9]*: Warning: attempt to redefine pseudo-op `.macro'
ignored
+.*:[1-9][0-9]*: Error: unknown pseudo-op: `.xyz'
+.*:[1-9][0-9]*: Error: unknown pseudo-op: `.y.z'
+(.* )?GAS .*
+#...
+[ 	]*[1-9][0-9]*[ 	]+m 4, 2
+[ 	]*[1-9][0-9]*[ 	]+> \.data
+[ 	]*[1-9][0-9]*[ 	]+> labelA:labelB:labelC:labelD:x\.y\.z 4\+2
+[ 	]*[1-9][0-9]*[ 	]+>> \.align 4
+[ 	]*[1-9][0-9]*[ 	]+\?+[ 	]+0606[ 	]+>> \.byte 4\+2,4\+2
+[ 	]*[1-9][0-9]*[ 	]+\?+[ 	]+0000[ 	]+> \.skip 2
+[ 	]*[1-9][0-9]*[ 	]+> labelZ:labelY:labelX:labelW:\.xyz 4-2
+[ 	]*[1-9][0-9]*[ 	]+>> \.align 8
+[ 	]*[1-9][0-9]*[ 	]+\?+[ 	]+0202[ 	]+>> \.byte 4-2,4-2
+[ 	]*[1-9][0-9]*[ 	]+\?+[ 	]+0000 ?0000[ 	]+> \.skip 4\*2
+[ 	]*[1-9][0-9]*[ 	]+0000 ?0000[ 	]*
+[ 	]*[1-9][0-9]*[ 	]+> label9:label8:label7:label6:
+[ 	]*[1-9][0-9]*[ 	]+
+[ 	]*[1-9][0-9]*[ 	]+\.purgem \.xyz, x\.y\.z
+[ 	]*[1-9][0-9]*[ 	]+\.xyz 0
+[ 	]*[1-9][0-9]*[ 	]+x\.y\.z 0
---
/home/jbeulich/src/binutils/mainline/2005-02-28/gas/testsuite/gas/macros/dot.s	1970-01-01
01:00:00.000000000 +0100
+++ 2005-02-28/gas/testsuite/gas/macros/dot.s	2005-02-08
09:57:12.000000000 +0100
@@ -0,0 +1,28 @@
+.altmacro
+
+.macro x.y.z val
+ .align 4
+ .byte val, val
+.endm
+
+.macro .xyz val
+ .align 8
+ .byte val, val
+.endm
+
+.macro .macro
+.endm
+
+label1:label2 : label3 :label4: m: .macro arg.1, arg.2
+ .data
+labelA:labelB : labelC :labelD: x.y.z arg.1+arg.2
+ .skip arg.2
+labelZ:labelY : labelX :labelW: .xyz arg.1-arg.2
+ .skip arg.1*arg.2
+label9:label8 : label7 :label6: .endm
+
+m 4, 2
+
+.purgem .xyz, x.y.z
+.xyz 0
+x.y.z 0
---
/home/jbeulich/src/binutils/mainline/2005-02-28/gas/testsuite/gas/macros/macros.exp	2005-01-31
15:27:07.000000000 +0100
+++ 2005-02-28/gas/testsuite/gas/macros/macros.exp	2005-02-04
16:44:31.000000000 +0100
@@ -63,5 +63,14 @@ run_dump_test app3
 run_dump_test app4
 
 run_list_test badarg ""
+case $target_triplet in {
+    { *c54x*-*-* } { }
+    { *c4x*-*-* } { }
+    { h8500-*-* } { }
+    { m68*-*-* } { }
+    { m88*-*-* } { }
+    { mmix-* } { }
+    default { run_list_test dot "-alm" }
+}
 run_list_test end ""
 run_list_test redef ""


[-- Attachment #2: binutils-mainline-macro-identifiers.patch --]
[-- Type: text/plain, Size: 13747 bytes --]

This is a resubmission of the patch at
http://sourceware.org/ml/binutils/2005-02/msg00120.html to address the
inconsistent acceptance of identifiers between the macro handling code and
the rest of the assembler, including the unability to use a macro the name
of which starts with a dot.
Over the previously submitted revisions, this has just cosmetic changes
(NEWS entry, change to MMIX testcase removed again based on that target's
maintainer's request) and thus I did not re-build or re-run the tests. I'm
not sure why there wasn't any comment of non-cosmetic nature so far; I had
hoped to at least get pointers to and reasons for what needs to change to
make this acceptable.

Originally built and tested natively on ia64-unknown-linux-gnu and as cross
tools for a large number of targets.

Jan

gas/
2005-02-28  Jan Beulich  <jbeulich@novell.com>

	* NEWS: Mention these changes and their effects.
	* macro.c (get_token): Use is_name_beginner/is_part_of_name/
	is_name_ender.
	(check_macro): Likewise.
	(buffer_and_nest): Likewise. Permit multiple labels. Don't discard
	labels together with the closing pseudo-op.
	(macro_expand_body): Adjust comment. Range-check input before use.
	Adjust mis-spelled diagnostic. Use is_name_beginner.
	* read.c (try_macro): New.
	(read_a_source_file): New static variable last_eol. Don't list
	macro expansion lines more than once. Call try_macro.
	(s_macro): Set section of line_label to absolute instead of undefined.

gas/testsuite/
2005-02-28  Jan Beulich  <jbeulich@novell.com>

	* gas/macros/dot.[ls]: New.
	* gas/macros/macros.exp: Run new test.

--- /home/jbeulich/src/binutils/mainline/2005-02-28/gas/NEWS	2005-02-28 08:27:12.000000000 +0100
+++ 2005-02-28/gas/NEWS	2005-02-28 09:52:47.000000000 +0100
@@ -1,5 +1,11 @@
 -*- text -*-
 
+* Macro names and macro parameter names can now be any identifier that would
+  also be legal as a symbol elsewhere. For macro parameter names, this is
+  known to cause problems in certain sources when the respective target uses
+  characters inconsistently (like MMIX's use of ':'), and thus macro
+  parameter references are no longer recognized as such.
+
 * New command line option -mhint.b=[ok|warning|error] for IA64 targets.
 
 * New command line option -munwind-check=[warning|error] for IA64
--- /home/jbeulich/src/binutils/mainline/2005-02-28/gas/macro.c	2005-01-31 15:27:07.000000000 +0100
+++ 2005-02-28/gas/macro.c	2005-02-03 15:12:04.000000000 +0100
@@ -187,21 +187,37 @@ buffer_and_nest (const char *from, const
 	     the first column, since we can't tell what's a label and
 	     whats a pseudoop.  */
 
-	  /* Skip leading whitespace.  */
-	  while (i < ptr->len && ISWHITE (ptr->ptr[i]))
-	    i++;
-
-	  /* Skip over a label.  */
-	  while (i < ptr->len
-		 && (ISALNUM (ptr->ptr[i])
-		     || ptr->ptr[i] == '_'
-		     || ptr->ptr[i] == '$'))
-	    i++;
-
-	  /* And a colon.  */
-	  if (i < ptr->len
-	      && ptr->ptr[i] == ':')
-	    i++;
+	  if (! LABELS_WITHOUT_COLONS)
+	    {
+	      /* Skip leading whitespace.  */
+	      while (i < ptr->len && ISWHITE (ptr->ptr[i]))
+		i++;
+	    }
+
+	  for (;;)
+	    {
+	      /* Skip over a label, if any.  */
+	      if (i >= ptr->len || ! is_name_beginner (ptr->ptr[i]))
+		break;
+	      i++;
+	      while (i < ptr->len && is_part_of_name (ptr->ptr[i]))
+		i++;
+	      if (i < ptr->len && is_name_ender (ptr->ptr[i]))
+		i++;
+	      if (LABELS_WITHOUT_COLONS)
+		break;
+	      /* Skip whitespace.  */
+	      while (i < ptr->len && ISWHITE (ptr->ptr[i]))
+		i++;
+	      /* Check for the colon.  */
+	      if (i >= ptr->len || ptr->ptr[i] != ':')
+		{
+		  i = line_start;
+		  break;
+		}
+	      i++;
+	      line_start = i;
+	    }
 
 	}
       /* Skip trailing whitespace.  */
@@ -226,11 +242,13 @@ buffer_and_nest (const char *from, const
 	       ? strncasecmp (ptr->ptr + i, from, from_len) == 0
 	       : from_len > 0)
 	      && (ptr->len == (i + from_len)
-		  || ! ISALNUM (ptr->ptr[i + from_len])))
+		  || ! (is_part_of_name (ptr->ptr[i + from_len])
+			|| is_name_ender (ptr->ptr[i + from_len]))))
 	    depth++;
 	  if (strncasecmp (ptr->ptr + i, to, to_len) == 0
 	      && (ptr->len == (i + to_len)
-		  || ! ISALNUM (ptr->ptr[i + to_len])))
+		  || ! (is_part_of_name (ptr->ptr[i + to_len])
+			|| is_name_ender (ptr->ptr[i + to_len]))))
 	    {
 	      depth--;
 	      if (depth == 0)
@@ -258,15 +276,16 @@ static int
 get_token (int idx, sb *in, sb *name)
 {
   if (idx < in->len
-      && (ISALPHA (in->ptr[idx])
-	  || in->ptr[idx] == '_'
-	  || in->ptr[idx] == '$'))
+      && is_name_beginner (in->ptr[idx]))
     {
       sb_add_char (name, in->ptr[idx++]);
       while (idx < in->len
-	     && (ISALNUM (in->ptr[idx])
-		 || in->ptr[idx] == '_'
-		 || in->ptr[idx] == '$'))
+	     && is_part_of_name (in->ptr[idx]))
+	{
+	  sb_add_char (name, in->ptr[idx++]);
+	}
+      if (idx < in->len
+	     && is_name_ender (in->ptr[idx]))
 	{
 	  sb_add_char (name, in->ptr[idx++]);
 	}
@@ -692,13 +711,14 @@ macro_expand_body (sb *in, sb *out, form
 	  else
 	    {
 	      /* FIXME: Why do we do this?  */
+	      /* At least in alternate mode this seems correct.  */
 	      src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
 	    }
 	}
       else if (in->ptr[src] == '\\')
 	{
 	  src++;
-	  if (in->ptr[src] == '(')
+	  if (src < in->len && in->ptr[src] == '(')
 	    {
 	      /* Sub in till the next ')' literally.  */
 	      src++;
@@ -709,9 +729,9 @@ macro_expand_body (sb *in, sb *out, form
 	      if (in->ptr[src] == ')')
 		src++;
 	      else
-		return _("missplaced )");
+		return _("misplaced `)'");
 	    }
-	  else if (in->ptr[src] == '@')
+	  else if (src < in->len && in->ptr[src] == '@')
 	    {
 	      /* Sub in the macro invocation number.  */
 
@@ -720,7 +740,7 @@ macro_expand_body (sb *in, sb *out, form
 	      sprintf (buffer, "%d", macro_number);
 	      sb_add_string (out, buffer);
 	    }
-	  else if (in->ptr[src] == '&')
+	  else if (src < in->len && in->ptr[src] == '&')
 	    {
 	      /* This is a preprocessor variable name, we don't do them
 		 here.  */
@@ -728,7 +748,7 @@ macro_expand_body (sb *in, sb *out, form
 	      sb_add_char (out, '&');
 	      src++;
 	    }
-	  else if (macro_mri && ISALNUM (in->ptr[src]))
+	  else if (macro_mri && src < in->len && ISALNUM (in->ptr[src]))
 	    {
 	      int ind;
 	      formal_entry *f;
@@ -759,9 +779,7 @@ macro_expand_body (sb *in, sb *out, form
 	    }
 	}
       else if ((macro_alternate || macro_mri)
-	       && (ISALPHA (in->ptr[src])
-		   || in->ptr[src] == '_'
-		   || in->ptr[src] == '$')
+	       && is_name_beginner (in->ptr[src])
 	       && (! inquote
 		   || ! macro_strip_at
 		   || (src > 0 && in->ptr[src - 1] == '@')))
@@ -1086,16 +1104,14 @@ check_macro (const char *line, sb *expan
   macro_entry *macro;
   sb line_sb;
 
-  if (! ISALPHA (*line)
-      && *line != '_'
-      && *line != '$'
+  if (! is_name_beginner (*line)
       && (! macro_mri || *line != '.'))
     return 0;
 
   s = line + 1;
-  while (ISALNUM (*s)
-	 || *s == '_'
-	 || *s == '$')
+  while (is_part_of_name (*s))
+    ++s;
+  if (is_name_ender (*s))
     ++s;
 
   copy = (char *) alloca (s - line + 1);
--- /home/jbeulich/src/binutils/mainline/2005-02-28/gas/read.c	2005-02-28 08:27:13.000000000 +0100
+++ 2005-02-28/gas/read.c	2005-02-28 09:39:16.502014184 +0100
@@ -520,6 +520,32 @@ scrub_from_string (char *buf, int buflen
   return copy;
 }
 
+/* Helper function of read_a_source_file, which tries to expand a macro.  */
+static int
+try_macro (char term, const char *line)
+{
+  sb out;
+  const char *err;
+  macro_entry *macro;
+
+  if (check_macro (line, &out, &err, &macro))
+    {
+      if (err != NULL)
+	as_bad ("%s", err);
+      *input_line_pointer++ = term;
+      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
+      return 1;
+    }
+  return 0;
+}
+
 /* We read the file, putting things into a web that represents what we
    have been reading.  */
 void
@@ -547,6 +573,13 @@ read_a_source_file (char *name)
 
   while ((buffer_limit = input_scrub_next_buffer (&input_line_pointer)) != 0)
     {				/* We have another line to parse.  */
+#ifndef NO_LISTING
+      /* In order to avoid listing macro expansion lines with labels
+	 multiple times, keep track of which line was last issued.  */
+      static char *last_eol;
+
+      last_eol = NULL;
+#endif
       know (buffer_limit[-1] == '\n');	/* Must have a sentinel.  */
 
       while (input_line_pointer < buffer_limit)
@@ -666,17 +699,21 @@ read_a_source_file (char *name)
 		    if (is_end_of_line[(unsigned char) *s])
 		      break;
 
-		  /* Copy it for safe keeping.  Also give an indication of
-		     how much macro nesting is involved at this point.  */
-		  len = s - (input_line_pointer - 1);
-		  copy = (char *) xmalloc (len + macro_nest + 2);
-		  memset (copy, '>', macro_nest);
-		  copy[macro_nest] = ' ';
-		  memcpy (copy + macro_nest + 1, input_line_pointer - 1, len);
-		  copy[macro_nest + 1 + len] = '\0';
+		  if (s != last_eol)
+		    {
+		      last_eol = s;
+		      /* Copy it for safe keeping.  Also give an indication of
+			 how much macro nesting is involved at this point.  */
+		      len = s - (input_line_pointer - 1);
+		      copy = (char *) xmalloc (len + macro_nest + 2);
+		      memset (copy, '>', macro_nest);
+		      copy[macro_nest] = ' ';
+		      memcpy (copy + macro_nest + 1, input_line_pointer - 1, len);
+		      copy[macro_nest + 1 + len] = '\0';
 
-		  /* Install the line with the listing facility.  */
-		  listing_newline (copy);
+		      /* Install the line with the listing facility.  */
+		      listing_newline (copy);
+		    }
 		}
 	      else
 		listing_newline (NULL);
@@ -816,9 +853,17 @@ read_a_source_file (char *name)
 		      /* Print the error msg now, while we still can.  */
 		      if (pop == NULL)
 			{
-			  as_bad (_("unknown pseudo-op: `%s'"), s);
+			  char *end = input_line_pointer;
+
 			  *input_line_pointer = c;
 			  s_ignore (0);
+			  c = *input_line_pointer;
+			  *input_line_pointer = '\0';
+			  if (! macro_defined || ! try_macro (c, s))
+			    {
+			      *end = '\0';
+			      as_bad (_("unknown pseudo-op: `%s'"), s);
+			    }
 			  continue;
 			}
 
@@ -874,28 +919,8 @@ read_a_source_file (char *name)
 
 		      generate_lineno_debug ();
 
-		      if (macro_defined)
-			{
-			  sb out;
-			  const char *err;
-			  macro_entry *macro;
-
-			  if (check_macro (s, &out, &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;
-			    }
-			}
+		      if (macro_defined && try_macro (c, s))
+			continue;
 
 		      if (mri_pending_align)
 			{
@@ -2320,7 +2345,7 @@ s_macro (int ignore ATTRIBUTE_UNUSED)
     {
       if (line_label != NULL)
 	{
-	  S_SET_SEGMENT (line_label, undefined_section);
+	  S_SET_SEGMENT (line_label, absolute_section);
 	  S_SET_VALUE (line_label, 0);
 	  symbol_set_frag (line_label, &zero_address_frag);
 	}
--- /home/jbeulich/src/binutils/mainline/2005-02-28/gas/testsuite/gas/macros/dot.l	1970-01-01 01:00:00.000000000 +0100
+++ 2005-02-28/gas/testsuite/gas/macros/dot.l	2005-02-04 10:54:39.000000000 +0100
@@ -0,0 +1,22 @@
+.*: Assembler messages:
+.*:[1-9][0-9]*: Warning: attempt to redefine pseudo-op `.macro' ignored
+.*:[1-9][0-9]*: Error: unknown pseudo-op: `.xyz'
+.*:[1-9][0-9]*: Error: unknown pseudo-op: `.y.z'
+(.* )?GAS .*
+#...
+[ 	]*[1-9][0-9]*[ 	]+m 4, 2
+[ 	]*[1-9][0-9]*[ 	]+> \.data
+[ 	]*[1-9][0-9]*[ 	]+> labelA:labelB:labelC:labelD:x\.y\.z 4\+2
+[ 	]*[1-9][0-9]*[ 	]+>> \.align 4
+[ 	]*[1-9][0-9]*[ 	]+\?+[ 	]+0606[ 	]+>> \.byte 4\+2,4\+2
+[ 	]*[1-9][0-9]*[ 	]+\?+[ 	]+0000[ 	]+> \.skip 2
+[ 	]*[1-9][0-9]*[ 	]+> labelZ:labelY:labelX:labelW:\.xyz 4-2
+[ 	]*[1-9][0-9]*[ 	]+>> \.align 8
+[ 	]*[1-9][0-9]*[ 	]+\?+[ 	]+0202[ 	]+>> \.byte 4-2,4-2
+[ 	]*[1-9][0-9]*[ 	]+\?+[ 	]+0000 ?0000[ 	]+> \.skip 4\*2
+[ 	]*[1-9][0-9]*[ 	]+0000 ?0000[ 	]*
+[ 	]*[1-9][0-9]*[ 	]+> label9:label8:label7:label6:
+[ 	]*[1-9][0-9]*[ 	]+
+[ 	]*[1-9][0-9]*[ 	]+\.purgem \.xyz, x\.y\.z
+[ 	]*[1-9][0-9]*[ 	]+\.xyz 0
+[ 	]*[1-9][0-9]*[ 	]+x\.y\.z 0
--- /home/jbeulich/src/binutils/mainline/2005-02-28/gas/testsuite/gas/macros/dot.s	1970-01-01 01:00:00.000000000 +0100
+++ 2005-02-28/gas/testsuite/gas/macros/dot.s	2005-02-08 09:57:12.000000000 +0100
@@ -0,0 +1,28 @@
+.altmacro
+
+.macro x.y.z val
+ .align 4
+ .byte val, val
+.endm
+
+.macro .xyz val
+ .align 8
+ .byte val, val
+.endm
+
+.macro .macro
+.endm
+
+label1:label2 : label3 :label4: m: .macro arg.1, arg.2
+ .data
+labelA:labelB : labelC :labelD: x.y.z arg.1+arg.2
+ .skip arg.2
+labelZ:labelY : labelX :labelW: .xyz arg.1-arg.2
+ .skip arg.1*arg.2
+label9:label8 : label7 :label6: .endm
+
+m 4, 2
+
+.purgem .xyz, x.y.z
+.xyz 0
+x.y.z 0
--- /home/jbeulich/src/binutils/mainline/2005-02-28/gas/testsuite/gas/macros/macros.exp	2005-01-31 15:27:07.000000000 +0100
+++ 2005-02-28/gas/testsuite/gas/macros/macros.exp	2005-02-04 16:44:31.000000000 +0100
@@ -63,5 +63,14 @@ run_dump_test app3
 run_dump_test app4
 
 run_list_test badarg ""
+case $target_triplet in {
+    { *c54x*-*-* } { }
+    { *c4x*-*-* } { }
+    { h8500-*-* } { }
+    { m68*-*-* } { }
+    { m88*-*-* } { }
+    { mmix-* } { }
+    default { run_list_test dot "-alm" }
+}
 run_list_test end ""
 run_list_test redef ""

^ permalink raw reply	[flat|nested] 27+ messages in thread
[parent not found: <s209d602.092@emea1-mh.id2.novell.com>]
[parent not found: <s209c6d8.000@emea1-mh.id2.novell.com>]
* Re: [PATCH] Re: .macro behavior
@ 2005-02-09 14:06 Jan Beulich
  0 siblings, 0 replies; 27+ messages in thread
From: Jan Beulich @ 2005-02-09 14:06 UTC (permalink / raw)
  To: hp; +Cc: binutils

>But apparently there's bug, exposed by the change I asked for.
>I suggest you just hold off on your gas/mmix/relax2.s patch and
>let me handle it, once your patch is in.

So am I getting you right, you want the patch to introduce a new
failure for mmix? That's fine with me (and hopefully with whoever
eventually approves the rest of the patch).

Jan

^ permalink raw reply	[flat|nested] 27+ messages in thread
[parent not found: <s209c8b9.060@emea1-mh.id2.novell.com>]
* Re: [PATCH] Re: .macro behavior
@ 2005-02-09 11:32 Jan Beulich
  0 siblings, 0 replies; 27+ messages in thread
From: Jan Beulich @ 2005-02-09 11:32 UTC (permalink / raw)
  To: hp; +Cc: binutils

>>> Hans-Peter Nilsson <hp@bitrange.com> 08.02.05 19:04:20 >>>
>On Tue, 8 Feb 2005, Jan Beulich wrote:
>> >> 	* gas/mmix/relax2.s: Use .altmacro and & to separate macro
>> >> parameter
>> >> 	references.
>> >
>> >Ew.  Please just get rid of the ":"s instead (my mistake, as
>> >it's a symbol character, not the usual label-ending thingy).
>>
>> I can't: The test just fails (with an error message that says
nothing
>> to me) if I do so.
>
>Please quote those error messages here.

"internal: unhandled label aa0"

This results from the dubious code in mmix_handle_mmixal following the
comment

  /* Remove trailing ":" off labels, as they'd otherwise be considered
     part of the name.  But don't do it for local labels.  */

storing labels without trailing colons in pending_label (I consider
this dubious because colons are valid parts of a symbol name, and hence
I can't see how one could at the same time consider them separators when
last in a label).

Jan

^ permalink raw reply	[flat|nested] 27+ messages in thread
* Re: [PATCH] Re: .macro behavior
@ 2005-02-09 10:28 Jan Beulich
  0 siblings, 0 replies; 27+ messages in thread
From: Jan Beulich @ 2005-02-09 10:28 UTC (permalink / raw)
  To: hp; +Cc: binutils

>>> Hans-Peter Nilsson <hp@bitrange.com> 08.02.05 18:31:37 >>>
>On Tue, 8 Feb 2005, Jan Beulich wrote:
>
>> >> >> only allows [[:alpha:]_$][[:alnum:]_$]*
>> >
>> >I think this restriction is actually good.  Calls for the least
>> >amount of surprises when applying the same macro to different
>> >GAS ports.
>>
>> Not so. If, on IA-64 as an example, I want to define an
>> instruction-like macro, I need to have '.' as an acceptable
character
>> for the macro name.
>
>I thought you were talking about macro *parameter names*, as
>that's the change that exposed the mistake in the MMIX
>test-case.  I agree the macro names themselves should be
>freely chosen (anything but whitespace or whatever).

I'm actualy talking about both, and since both are symbol names, both
should get the same treatment as ordinary symbols (despite agreeing that
for macro parameters the previous restriction is less hurting).
Otherwise it's just inconsistent.

Jan

^ permalink raw reply	[flat|nested] 27+ messages in thread
* Re: [PATCH] Re: .macro behavior
@ 2005-02-08 20:55 Jan Beulich
  2005-02-08 23:05 ` Hans-Peter Nilsson
  2005-02-08 23:58 ` Hans-Peter Nilsson
  0 siblings, 2 replies; 27+ messages in thread
From: Jan Beulich @ 2005-02-08 20:55 UTC (permalink / raw)
  To: hp; +Cc: binutils

>> >> only allows [[:alpha:]_$][[:alnum:]_$]*
>
>I think this restriction is actually good.  Calls for the least
>amount of surprises when applying the same macro to different
>GAS ports.

Not so. If, on IA-64 as an example, I want to define an
instruction-like macro, I need to have '.' as an acceptable character
for the macro name.

>> 	* gas/mmix/relax2.s: Use .altmacro and & to separate macro
>> parameter
>> 	references.
>
>Ew.  Please just get rid of the ":"s instead (my mistake, as
>it's a symbol character, not the usual label-ending thingy).

I can't: The test just fails (with an error message that says nothing
to me) if I do so.

>And a nitpick:
>
>>
/home/jbeulich/src/binutils/mainline/2005-02-01/gas/testsuite/gas/mmix/relax2.s	2003-10-18
>> 18:00:21.000000000 +0200
>> +++ 2005-02-01/gas/testsuite/gas/mmix/relax2.s	2005-02-08
>> 09:38:12.000000000 +0100
>> @@ -1,35 +1,37 @@
>>  # PUSHJ stub border-cases: two with either or both stubs
unreachable,
>>  # local symbols, ditto non-local labels, similar with three
PUSHJs.
>>
>> +.altmacro
>> +
>
>Pseudos shouldn't be first on a line. Accepting it in gas is ok,
>but we shouldn't get sloppy in the test-suite.  For consistency,
>it should also be aligned with the other pseudos in that file.
>(I guess you don't need the ".altmacro" pseudo if you just
>remove the ":"s so this is mostly for the record.)

Will do.

Thanks, Jan

^ permalink raw reply	[flat|nested] 27+ messages in thread
* [PATCH] Re: .macro behavior
@ 2005-02-08 17:52 Jan Beulich
  2005-02-08 20:22 ` Hans-Peter Nilsson
  0 siblings, 1 reply; 27+ messages in thread
From: Jan Beulich @ 2005-02-08 17:52 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 14943 bytes --]

>>> Ian Lance Taylor <ian@airs.com> 14.01.05 17:50:05 >>>
>"Jan Beulich" <JBeulich@novell.com> writes:
>
>> Is it intentional that .macro
>> 
>> - ignores the (configurable) set of symbol name characters and
instead
>> only allows [[:alpha:]_$][[:alnum:]_$]*
>> - silently inserts a zero-length named macro if the name starts
with
>> any non-token character
>> - silently ignores the rest of the line if a formal argument starts
>> with any non-token character
>> 
>> If not, I'd like to fix this. One major concern here is that with
these
>> restrictions one can't build trivial things like a .bss
>> pseudo-directive...
>
>None of these behaviours are intentional.
>
>But you're still not going to be able to define a macro which starts
>with '.'.  Those are handled specially in read_a_source_file().
>Although I suppose that could also be changed.

This is a resubmission of the patch to address the inconsistent
acceptance
of identifiers between the macro handling code and the rest of the
assembler,
including the unability to use a macro the name of which starts with a
dot.

It now also includes a fix for the previously failing mmix testcase.

Built and tested natively on ia64-unknown-linux-gnu and as cross tools
for a large number of targets.

Jan

gas/
2005-02-08  Jan Beulich  <jbeulich@novell.com>

	* macro.c (get_token): Use is_name_beginner/is_part_of_name/
	is_name_ender.
	(check_macro): Likewise.
	(buffer_and_nest): Likewise. Permit multiple labels. Don't
discard
	labels together with the closing pseudo-op.
	(macro_expand_body): Adjust comment. Range-check input before
use.
	Adjust mis-spelled diagnostic. Use is_name_beginner.
	* read.c (try_macro): New.
	(read_a_source_file): New static variable last_eol. Don't list
	macro expansion lines more than once. Call try_macro.
	(s_macro): Set section of line_label to absolute instead of
undefined.

gas/testsuite/
2005-02-08  Jan Beulich  <jbeulich@novell.com>

	* gas/macros/dot.[ls]: New.
	* gas/macros/macros.exp: Run new test.
	* gas/mmix/relax2.s: Use .altmacro and & to separate macro
parameter
	references.

---
/home/jbeulich/src/binutils/mainline/2005-02-01/gas/macro.c	2005-01-31
15:27:07.000000000 +0100
+++ 2005-02-01/gas/macro.c	2005-02-03 15:12:04.000000000 +0100
@@ -187,21 +187,37 @@ buffer_and_nest (const char *from, const
 	     the first column, since we can't tell what's a label and
 	     whats a pseudoop.  */
 
-	  /* Skip leading whitespace.  */
-	  while (i < ptr->len && ISWHITE (ptr->ptr[i]))
-	    i++;
-
-	  /* Skip over a label.  */
-	  while (i < ptr->len
-		 && (ISALNUM (ptr->ptr[i])
-		     || ptr->ptr[i] == '_'
-		     || ptr->ptr[i] == '$'))
-	    i++;
-
-	  /* And a colon.  */
-	  if (i < ptr->len
-	      && ptr->ptr[i] == ':')
-	    i++;
+	  if (! LABELS_WITHOUT_COLONS)
+	    {
+	      /* Skip leading whitespace.  */
+	      while (i < ptr->len && ISWHITE (ptr->ptr[i]))
+		i++;
+	    }
+
+	  for (;;)
+	    {
+	      /* Skip over a label, if any.  */
+	      if (i >= ptr->len || ! is_name_beginner (ptr->ptr[i]))
+		break;
+	      i++;
+	      while (i < ptr->len && is_part_of_name (ptr->ptr[i]))
+		i++;
+	      if (i < ptr->len && is_name_ender (ptr->ptr[i]))
+		i++;
+	      if (LABELS_WITHOUT_COLONS)
+		break;
+	      /* Skip whitespace.  */
+	      while (i < ptr->len && ISWHITE (ptr->ptr[i]))
+		i++;
+	      /* Check for the colon.  */
+	      if (i >= ptr->len || ptr->ptr[i] != ':')
+		{
+		  i = line_start;
+		  break;
+		}
+	      i++;
+	      line_start = i;
+	    }
 
 	}
       /* Skip trailing whitespace.  */
@@ -226,11 +242,13 @@ buffer_and_nest (const char *from, const
 	       ? strncasecmp (ptr->ptr + i, from, from_len) == 0
 	       : from_len > 0)
 	      && (ptr->len == (i + from_len)
-		  || ! ISALNUM (ptr->ptr[i + from_len])))
+		  || ! (is_part_of_name (ptr->ptr[i + from_len])
+			|| is_name_ender (ptr->ptr[i + from_len]))))
 	    depth++;
 	  if (strncasecmp (ptr->ptr + i, to, to_len) == 0
 	      && (ptr->len == (i + to_len)
-		  || ! ISALNUM (ptr->ptr[i + to_len])))
+		  || ! (is_part_of_name (ptr->ptr[i + to_len])
+			|| is_name_ender (ptr->ptr[i + to_len]))))
 	    {
 	      depth--;
 	      if (depth == 0)
@@ -258,15 +276,16 @@ static int
 get_token (int idx, sb *in, sb *name)
 {
   if (idx < in->len
-      && (ISALPHA (in->ptr[idx])
-	  || in->ptr[idx] == '_'
-	  || in->ptr[idx] == '$'))
+      && is_name_beginner (in->ptr[idx]))
     {
       sb_add_char (name, in->ptr[idx++]);
       while (idx < in->len
-	     && (ISALNUM (in->ptr[idx])
-		 || in->ptr[idx] == '_'
-		 || in->ptr[idx] == '$'))
+	     && is_part_of_name (in->ptr[idx]))
+	{
+	  sb_add_char (name, in->ptr[idx++]);
+	}
+      if (idx < in->len
+	     && is_name_ender (in->ptr[idx]))
 	{
 	  sb_add_char (name, in->ptr[idx++]);
 	}
@@ -692,13 +711,14 @@ macro_expand_body (sb *in, sb *out, form
 	  else
 	    {
 	      /* FIXME: Why do we do this?  */
+	      /* At least in alternate mode this seems correct.  */
 	      src = sub_actual (src + 1, in, &t, formal_hash, '&', out,
0);
 	    }
 	}
       else if (in->ptr[src] == '\\')
 	{
 	  src++;
-	  if (in->ptr[src] == '(')
+	  if (src < in->len && in->ptr[src] == '(')
 	    {
 	      /* Sub in till the next ')' literally.  */
 	      src++;
@@ -709,9 +729,9 @@ macro_expand_body (sb *in, sb *out, form
 	      if (in->ptr[src] == ')')
 		src++;
 	      else
-		return _("missplaced )");
+		return _("misplaced `)'");
 	    }
-	  else if (in->ptr[src] == '@')
+	  else if (src < in->len && in->ptr[src] == '@')
 	    {
 	      /* Sub in the macro invocation number.  */
 
@@ -720,7 +740,7 @@ macro_expand_body (sb *in, sb *out, form
 	      sprintf (buffer, "%d", macro_number);
 	      sb_add_string (out, buffer);
 	    }
-	  else if (in->ptr[src] == '&')
+	  else if (src < in->len && in->ptr[src] == '&')
 	    {
 	      /* This is a preprocessor variable name, we don't do them
 		 here.  */
@@ -728,7 +748,7 @@ macro_expand_body (sb *in, sb *out, form
 	      sb_add_char (out, '&');
 	      src++;
 	    }
-	  else if (macro_mri && ISALNUM (in->ptr[src]))
+	  else if (macro_mri && src < in->len && ISALNUM
(in->ptr[src]))
 	    {
 	      int ind;
 	      formal_entry *f;
@@ -759,9 +779,7 @@ macro_expand_body (sb *in, sb *out, form
 	    }
 	}
       else if ((macro_alternate || macro_mri)
-	       && (ISALPHA (in->ptr[src])
-		   || in->ptr[src] == '_'
-		   || in->ptr[src] == '$')
+	       && is_name_beginner (in->ptr[src])
 	       && (! inquote
 		   || ! macro_strip_at
 		   || (src > 0 && in->ptr[src - 1] == '@')))
@@ -1086,16 +1104,14 @@ check_macro (const char *line, sb *expan
   macro_entry *macro;
   sb line_sb;
 
-  if (! ISALPHA (*line)
-      && *line != '_'
-      && *line != '$'
+  if (! is_name_beginner (*line)
       && (! macro_mri || *line != '.'))
     return 0;
 
   s = line + 1;
-  while (ISALNUM (*s)
-	 || *s == '_'
-	 || *s == '$')
+  while (is_part_of_name (*s))
+    ++s;
+  if (is_name_ender (*s))
     ++s;
 
   copy = (char *) alloca (s - line + 1);
---
/home/jbeulich/src/binutils/mainline/2005-02-01/gas/read.c	2005-01-26
08:33:13.000000000 +0100
+++ 2005-02-01/gas/read.c	2005-02-03 15:12:04.000000000 +0100
@@ -499,6 +499,32 @@ scrub_from_string (char *buf, int buflen
   return copy;
 }
 
+/* Helper function of read_a_source_file, which tries to expand a
macro.  */
+static int
+try_macro (char term, const char *line)
+{
+  sb out;
+  const char *err;
+  macro_entry *macro;
+
+  if (check_macro (line, &out, &err, &macro))
+    {
+      if (err != NULL)
+	as_bad ("%s", err);
+      *input_line_pointer++ = term;
+      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
+      return 1;
+    }
+  return 0;
+}
+
 /* We read the file, putting things into a web that represents what
we
    have been reading.  */
 void
@@ -526,6 +552,13 @@ read_a_source_file (char *name)
 
   while ((buffer_limit = input_scrub_next_buffer
(&input_line_pointer)) != 0)
     {				/* We have another line to parse.  */
+#ifndef NO_LISTING
+      /* In order to avoid listing macro expansion lines with labels
+	 multiple times, keep track of which line was last issued.  */
+      static char *last_eol;
+
+      last_eol = NULL;
+#endif
       know (buffer_limit[-1] == '\n');	/* Must have a sentinel.
 */
 
       while (input_line_pointer < buffer_limit)
@@ -645,17 +678,21 @@ read_a_source_file (char *name)
 		    if (is_end_of_line[(unsigned char) *s])
 		      break;
 
-		  /* Copy it for safe keeping.  Also give an indication
of
-		     how much macro nesting is involved at this point. 
*/
-		  len = s - (input_line_pointer - 1);
-		  copy = (char *) xmalloc (len + macro_nest + 2);
-		  memset (copy, '>', macro_nest);
-		  copy[macro_nest] = ' ';
-		  memcpy (copy + macro_nest + 1, input_line_pointer - 1,
len);
-		  copy[macro_nest + 1 + len] = '\0';
+		  if (s != last_eol)
+		    {
+		      last_eol = s;
+		      /* Copy it for safe keeping.  Also give an
indication of
+			 how much macro nesting is involved at this
point.  */
+		      len = s - (input_line_pointer - 1);
+		      copy = (char *) xmalloc (len + macro_nest + 2);
+		      memset (copy, '>', macro_nest);
+		      copy[macro_nest] = ' ';
+		      memcpy (copy + macro_nest + 1, input_line_pointer
- 1, len);
+		      copy[macro_nest + 1 + len] = '\0';
 
-		  /* Install the line with the listing facility.  */
-		  listing_newline (copy);
+		      /* Install the line with the listing facility. 
*/
+		      listing_newline (copy);
+		    }
 		}
 	      else
 		listing_newline (NULL);
@@ -795,9 +832,17 @@ read_a_source_file (char *name)
 		      /* Print the error msg now, while we still can. 
*/
 		      if (pop == NULL)
 			{
-			  as_bad (_("unknown pseudo-op: `%s'"), s);
+			  char *end = input_line_pointer;
+
 			  *input_line_pointer = c;
 			  s_ignore (0);
+			  c = *input_line_pointer;
+			  *input_line_pointer = '\0';
+			  if (! macro_defined || ! try_macro (c, s))
+			    {
+			      *end = '\0';
+			      as_bad (_("unknown pseudo-op: `%s'"), s);
+			    }
 			  continue;
 			}
 
@@ -853,28 +898,8 @@ read_a_source_file (char *name)
 
 		      generate_lineno_debug ();
 
-		      if (macro_defined)
-			{
-			  sb out;
-			  const char *err;
-			  macro_entry *macro;
-
-			  if (check_macro (s, &out, &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;
-			    }
-			}
+		      if (macro_defined && try_macro (c, s))
+			continue;
 
 		      if (mri_pending_align)
 			{
@@ -2299,7 +2324,7 @@ s_macro (int ignore ATTRIBUTE_UNUSED)
     {
       if (line_label != NULL)
 	{
-	  S_SET_SEGMENT (line_label, undefined_section);
+	  S_SET_SEGMENT (line_label, absolute_section);
 	  S_SET_VALUE (line_label, 0);
 	  symbol_set_frag (line_label, &zero_address_frag);
 	}
---
/home/jbeulich/src/binutils/mainline/2005-02-01/gas/testsuite/gas/macros/dot.l	1970-01-01
01:00:00.000000000 +0100
+++ 2005-02-01/gas/testsuite/gas/macros/dot.l	2005-02-04
10:54:39.000000000 +0100
@@ -0,0 +1,22 @@
+.*: Assembler messages:
+.*:[1-9][0-9]*: Warning: attempt to redefine pseudo-op `.macro'
ignored
+.*:[1-9][0-9]*: Error: unknown pseudo-op: `.xyz'
+.*:[1-9][0-9]*: Error: unknown pseudo-op: `.y.z'
+(.* )?GAS .*
+#...
+[ 	]*[1-9][0-9]*[ 	]+m 4, 2
+[ 	]*[1-9][0-9]*[ 	]+> \.data
+[ 	]*[1-9][0-9]*[ 	]+> labelA:labelB:labelC:labelD:x\.y\.z 4\+2
+[ 	]*[1-9][0-9]*[ 	]+>> \.align 4
+[ 	]*[1-9][0-9]*[ 	]+\?+[ 	]+0606[ 	]+>> \.byte 4\+2,4\+2
+[ 	]*[1-9][0-9]*[ 	]+\?+[ 	]+0000[ 	]+> \.skip 2
+[ 	]*[1-9][0-9]*[ 	]+> labelZ:labelY:labelX:labelW:\.xyz 4-2
+[ 	]*[1-9][0-9]*[ 	]+>> \.align 8
+[ 	]*[1-9][0-9]*[ 	]+\?+[ 	]+0202[ 	]+>> \.byte 4-2,4-2
+[ 	]*[1-9][0-9]*[ 	]+\?+[ 	]+0000 ?0000[ 	]+> \.skip 4\*2
+[ 	]*[1-9][0-9]*[ 	]+0000 ?0000[ 	]*
+[ 	]*[1-9][0-9]*[ 	]+> label9:label8:label7:label6:
+[ 	]*[1-9][0-9]*[ 	]+
+[ 	]*[1-9][0-9]*[ 	]+\.purgem \.xyz, x\.y\.z
+[ 	]*[1-9][0-9]*[ 	]+\.xyz 0
+[ 	]*[1-9][0-9]*[ 	]+x\.y\.z 0
---
/home/jbeulich/src/binutils/mainline/2005-02-01/gas/testsuite/gas/macros/dot.s	1970-01-01
01:00:00.000000000 +0100
+++ 2005-02-01/gas/testsuite/gas/macros/dot.s	2005-02-08
09:57:12.000000000 +0100
@@ -0,0 +1,28 @@
+.altmacro
+
+.macro x.y.z val
+ .align 4
+ .byte val, val
+.endm
+
+.macro .xyz val
+ .align 8
+ .byte val, val
+.endm
+
+.macro .macro
+.endm
+
+label1:label2 : label3 :label4: m: .macro arg.1, arg.2
+ .data
+labelA:labelB : labelC :labelD: x.y.z arg.1+arg.2
+ .skip arg.2
+labelZ:labelY : labelX :labelW: .xyz arg.1-arg.2
+ .skip arg.1*arg.2
+label9:label8 : label7 :label6: .endm
+
+m 4, 2
+
+.purgem .xyz, x.y.z
+.xyz 0
+x.y.z 0
---
/home/jbeulich/src/binutils/mainline/2005-02-01/gas/testsuite/gas/macros/macros.exp	2005-01-31
15:27:07.000000000 +0100
+++ 2005-02-01/gas/testsuite/gas/macros/macros.exp	2005-02-04
16:44:31.000000000 +0100
@@ -63,5 +63,14 @@ run_dump_test app3
 run_dump_test app4
 
 run_list_test badarg ""
+case $target_triplet in {
+    { *c54x*-*-* } { }
+    { *c4x*-*-* } { }
+    { h8500-*-* } { }
+    { m68*-*-* } { }
+    { m88*-*-* } { }
+    { mmix-* } { }
+    default { run_list_test dot "-alm" }
+}
 run_list_test end ""
 run_list_test redef ""
---
/home/jbeulich/src/binutils/mainline/2005-02-01/gas/testsuite/gas/mmix/relax2.s	2003-10-18
18:00:21.000000000 +0200
+++ 2005-02-01/gas/testsuite/gas/mmix/relax2.s	2005-02-08
09:38:12.000000000 +0100
@@ -1,35 +1,37 @@
 # PUSHJ stub border-cases: two with either or both stubs unreachable,
 # local symbols, ditto non-local labels, similar with three PUSHJs.
 
+.altmacro
+
 Main	SWYM
 
 	.irp x,0,1,2,3,4,5,6,7,8,9,10,11,12
 
-	.section .text.a\x,"ax"
-aa\x:	.space 4,0
-a\x:	.space 65536*4,0
-	PUSHJ $33,aa\x
-	PUSHJ $22,a\x
-	.space 65535*4-4*\x
-
-	.section .text.b\x,"ax"
-bbb\x:	.space 4,0
-bb\x:	.space 4,0
-b\x:	.space 65535*4
-	PUSHJ $12,bbb\x
-	PUSHJ $13,bb\x
-	PUSHJ $14,b\x
-	.space 65535*4-4*\x
-
-	.section .text.c\x,"ax"
-c\x:	PUSHJ $100,ca\x
-	PUSHJ $101,cb\x
-	.space 65535*4-4*\x
-
-	.section .text.d\x,"ax"
-d\x:	PUSHJ $99,da\x
-	PUSHJ $98,db\x
-	PUSHJ $97,dc\x
-	.space 65535*4-4*\x
+	.section .text.a&x,"ax"
+aa&x&:	.space 4,0
+a&x&:	.space 65536*4,0
+	PUSHJ $33,aa&x
+	PUSHJ $22,a&x
+	.space 65535*4-4*x
+
+	.section .text.b&x,"ax"
+bbb&x&:	.space 4,0
+bb&x&:	.space 4,0
+b&x&:	.space 65535*4
+	PUSHJ $12,bbb&x
+	PUSHJ $13,bb&x
+	PUSHJ $14,b&x
+	.space 65535*4-4*x
+
+	.section .text.c&x,"ax"
+c&x&:	PUSHJ $100,ca&x
+	PUSHJ $101,cb&x
+	.space 65535*4-4*x
+
+	.section .text.d&x,"ax"
+d&x&:	PUSHJ $99,da&x
+	PUSHJ $98,db&x
+	PUSHJ $97,dc&x
+	.space 65535*4-4*x
 
 	.endr


[-- Attachment #2: binutils-mainline-macro-identifiers.patch --]
[-- Type: text/plain, Size: 14088 bytes --]

This is a resubmission of the patch to address the inconsistent acceptance
of identifiers between the macro handling code and the rest of the assembler,
including the unability to use a macro the name of which starts with a dot.
It now also includes a fix for the previously failing mmix testcase.

Built and tested natively on ia64-unknown-linux-gnu and as cross tools
for a large number of targets.

Jan

gas/
2005-02-08  Jan Beulich  <jbeulich@novell.com>

	* macro.c (get_token): Use is_name_beginner/is_part_of_name/
	is_name_ender.
	(check_macro): Likewise.
	(buffer_and_nest): Likewise. Permit multiple labels. Don't discard
	labels together with the closing pseudo-op.
	(macro_expand_body): Adjust comment. Range-check input before use.
	Adjust mis-spelled diagnostic. Use is_name_beginner.
	* read.c (try_macro): New.
	(read_a_source_file): New static variable last_eol. Don't list
	macro expansion lines more than once. Call try_macro.
	(s_macro): Set section of line_label to absolute instead of undefined.

gas/testsuite/
2005-02-08  Jan Beulich  <jbeulich@novell.com>

	* gas/macros/dot.[ls]: New.
	* gas/macros/macros.exp: Run new test.
	* gas/mmix/relax2.s: Use .altmacro and & to separate macro parameter
	references.

--- /home/jbeulich/src/binutils/mainline/2005-02-01/gas/macro.c	2005-01-31 15:27:07.000000000 +0100
+++ 2005-02-01/gas/macro.c	2005-02-03 15:12:04.000000000 +0100
@@ -187,21 +187,37 @@ buffer_and_nest (const char *from, const
 	     the first column, since we can't tell what's a label and
 	     whats a pseudoop.  */
 
-	  /* Skip leading whitespace.  */
-	  while (i < ptr->len && ISWHITE (ptr->ptr[i]))
-	    i++;
-
-	  /* Skip over a label.  */
-	  while (i < ptr->len
-		 && (ISALNUM (ptr->ptr[i])
-		     || ptr->ptr[i] == '_'
-		     || ptr->ptr[i] == '$'))
-	    i++;
-
-	  /* And a colon.  */
-	  if (i < ptr->len
-	      && ptr->ptr[i] == ':')
-	    i++;
+	  if (! LABELS_WITHOUT_COLONS)
+	    {
+	      /* Skip leading whitespace.  */
+	      while (i < ptr->len && ISWHITE (ptr->ptr[i]))
+		i++;
+	    }
+
+	  for (;;)
+	    {
+	      /* Skip over a label, if any.  */
+	      if (i >= ptr->len || ! is_name_beginner (ptr->ptr[i]))
+		break;
+	      i++;
+	      while (i < ptr->len && is_part_of_name (ptr->ptr[i]))
+		i++;
+	      if (i < ptr->len && is_name_ender (ptr->ptr[i]))
+		i++;
+	      if (LABELS_WITHOUT_COLONS)
+		break;
+	      /* Skip whitespace.  */
+	      while (i < ptr->len && ISWHITE (ptr->ptr[i]))
+		i++;
+	      /* Check for the colon.  */
+	      if (i >= ptr->len || ptr->ptr[i] != ':')
+		{
+		  i = line_start;
+		  break;
+		}
+	      i++;
+	      line_start = i;
+	    }
 
 	}
       /* Skip trailing whitespace.  */
@@ -226,11 +242,13 @@ buffer_and_nest (const char *from, const
 	       ? strncasecmp (ptr->ptr + i, from, from_len) == 0
 	       : from_len > 0)
 	      && (ptr->len == (i + from_len)
-		  || ! ISALNUM (ptr->ptr[i + from_len])))
+		  || ! (is_part_of_name (ptr->ptr[i + from_len])
+			|| is_name_ender (ptr->ptr[i + from_len]))))
 	    depth++;
 	  if (strncasecmp (ptr->ptr + i, to, to_len) == 0
 	      && (ptr->len == (i + to_len)
-		  || ! ISALNUM (ptr->ptr[i + to_len])))
+		  || ! (is_part_of_name (ptr->ptr[i + to_len])
+			|| is_name_ender (ptr->ptr[i + to_len]))))
 	    {
 	      depth--;
 	      if (depth == 0)
@@ -258,15 +276,16 @@ static int
 get_token (int idx, sb *in, sb *name)
 {
   if (idx < in->len
-      && (ISALPHA (in->ptr[idx])
-	  || in->ptr[idx] == '_'
-	  || in->ptr[idx] == '$'))
+      && is_name_beginner (in->ptr[idx]))
     {
       sb_add_char (name, in->ptr[idx++]);
       while (idx < in->len
-	     && (ISALNUM (in->ptr[idx])
-		 || in->ptr[idx] == '_'
-		 || in->ptr[idx] == '$'))
+	     && is_part_of_name (in->ptr[idx]))
+	{
+	  sb_add_char (name, in->ptr[idx++]);
+	}
+      if (idx < in->len
+	     && is_name_ender (in->ptr[idx]))
 	{
 	  sb_add_char (name, in->ptr[idx++]);
 	}
@@ -692,13 +711,14 @@ macro_expand_body (sb *in, sb *out, form
 	  else
 	    {
 	      /* FIXME: Why do we do this?  */
+	      /* At least in alternate mode this seems correct.  */
 	      src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
 	    }
 	}
       else if (in->ptr[src] == '\\')
 	{
 	  src++;
-	  if (in->ptr[src] == '(')
+	  if (src < in->len && in->ptr[src] == '(')
 	    {
 	      /* Sub in till the next ')' literally.  */
 	      src++;
@@ -709,9 +729,9 @@ macro_expand_body (sb *in, sb *out, form
 	      if (in->ptr[src] == ')')
 		src++;
 	      else
-		return _("missplaced )");
+		return _("misplaced `)'");
 	    }
-	  else if (in->ptr[src] == '@')
+	  else if (src < in->len && in->ptr[src] == '@')
 	    {
 	      /* Sub in the macro invocation number.  */
 
@@ -720,7 +740,7 @@ macro_expand_body (sb *in, sb *out, form
 	      sprintf (buffer, "%d", macro_number);
 	      sb_add_string (out, buffer);
 	    }
-	  else if (in->ptr[src] == '&')
+	  else if (src < in->len && in->ptr[src] == '&')
 	    {
 	      /* This is a preprocessor variable name, we don't do them
 		 here.  */
@@ -728,7 +748,7 @@ macro_expand_body (sb *in, sb *out, form
 	      sb_add_char (out, '&');
 	      src++;
 	    }
-	  else if (macro_mri && ISALNUM (in->ptr[src]))
+	  else if (macro_mri && src < in->len && ISALNUM (in->ptr[src]))
 	    {
 	      int ind;
 	      formal_entry *f;
@@ -759,9 +779,7 @@ macro_expand_body (sb *in, sb *out, form
 	    }
 	}
       else if ((macro_alternate || macro_mri)
-	       && (ISALPHA (in->ptr[src])
-		   || in->ptr[src] == '_'
-		   || in->ptr[src] == '$')
+	       && is_name_beginner (in->ptr[src])
 	       && (! inquote
 		   || ! macro_strip_at
 		   || (src > 0 && in->ptr[src - 1] == '@')))
@@ -1086,16 +1104,14 @@ check_macro (const char *line, sb *expan
   macro_entry *macro;
   sb line_sb;
 
-  if (! ISALPHA (*line)
-      && *line != '_'
-      && *line != '$'
+  if (! is_name_beginner (*line)
       && (! macro_mri || *line != '.'))
     return 0;
 
   s = line + 1;
-  while (ISALNUM (*s)
-	 || *s == '_'
-	 || *s == '$')
+  while (is_part_of_name (*s))
+    ++s;
+  if (is_name_ender (*s))
     ++s;
 
   copy = (char *) alloca (s - line + 1);
--- /home/jbeulich/src/binutils/mainline/2005-02-01/gas/read.c	2005-01-26 08:33:13.000000000 +0100
+++ 2005-02-01/gas/read.c	2005-02-03 15:12:04.000000000 +0100
@@ -499,6 +499,32 @@ scrub_from_string (char *buf, int buflen
   return copy;
 }
 
+/* Helper function of read_a_source_file, which tries to expand a macro.  */
+static int
+try_macro (char term, const char *line)
+{
+  sb out;
+  const char *err;
+  macro_entry *macro;
+
+  if (check_macro (line, &out, &err, &macro))
+    {
+      if (err != NULL)
+	as_bad ("%s", err);
+      *input_line_pointer++ = term;
+      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
+      return 1;
+    }
+  return 0;
+}
+
 /* We read the file, putting things into a web that represents what we
    have been reading.  */
 void
@@ -526,6 +552,13 @@ read_a_source_file (char *name)
 
   while ((buffer_limit = input_scrub_next_buffer (&input_line_pointer)) != 0)
     {				/* We have another line to parse.  */
+#ifndef NO_LISTING
+      /* In order to avoid listing macro expansion lines with labels
+	 multiple times, keep track of which line was last issued.  */
+      static char *last_eol;
+
+      last_eol = NULL;
+#endif
       know (buffer_limit[-1] == '\n');	/* Must have a sentinel.  */
 
       while (input_line_pointer < buffer_limit)
@@ -645,17 +678,21 @@ read_a_source_file (char *name)
 		    if (is_end_of_line[(unsigned char) *s])
 		      break;
 
-		  /* Copy it for safe keeping.  Also give an indication of
-		     how much macro nesting is involved at this point.  */
-		  len = s - (input_line_pointer - 1);
-		  copy = (char *) xmalloc (len + macro_nest + 2);
-		  memset (copy, '>', macro_nest);
-		  copy[macro_nest] = ' ';
-		  memcpy (copy + macro_nest + 1, input_line_pointer - 1, len);
-		  copy[macro_nest + 1 + len] = '\0';
+		  if (s != last_eol)
+		    {
+		      last_eol = s;
+		      /* Copy it for safe keeping.  Also give an indication of
+			 how much macro nesting is involved at this point.  */
+		      len = s - (input_line_pointer - 1);
+		      copy = (char *) xmalloc (len + macro_nest + 2);
+		      memset (copy, '>', macro_nest);
+		      copy[macro_nest] = ' ';
+		      memcpy (copy + macro_nest + 1, input_line_pointer - 1, len);
+		      copy[macro_nest + 1 + len] = '\0';
 
-		  /* Install the line with the listing facility.  */
-		  listing_newline (copy);
+		      /* Install the line with the listing facility.  */
+		      listing_newline (copy);
+		    }
 		}
 	      else
 		listing_newline (NULL);
@@ -795,9 +832,17 @@ read_a_source_file (char *name)
 		      /* Print the error msg now, while we still can.  */
 		      if (pop == NULL)
 			{
-			  as_bad (_("unknown pseudo-op: `%s'"), s);
+			  char *end = input_line_pointer;
+
 			  *input_line_pointer = c;
 			  s_ignore (0);
+			  c = *input_line_pointer;
+			  *input_line_pointer = '\0';
+			  if (! macro_defined || ! try_macro (c, s))
+			    {
+			      *end = '\0';
+			      as_bad (_("unknown pseudo-op: `%s'"), s);
+			    }
 			  continue;
 			}
 
@@ -853,28 +898,8 @@ read_a_source_file (char *name)
 
 		      generate_lineno_debug ();
 
-		      if (macro_defined)
-			{
-			  sb out;
-			  const char *err;
-			  macro_entry *macro;
-
-			  if (check_macro (s, &out, &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;
-			    }
-			}
+		      if (macro_defined && try_macro (c, s))
+			continue;
 
 		      if (mri_pending_align)
 			{
@@ -2299,7 +2324,7 @@ s_macro (int ignore ATTRIBUTE_UNUSED)
     {
       if (line_label != NULL)
 	{
-	  S_SET_SEGMENT (line_label, undefined_section);
+	  S_SET_SEGMENT (line_label, absolute_section);
 	  S_SET_VALUE (line_label, 0);
 	  symbol_set_frag (line_label, &zero_address_frag);
 	}
--- /home/jbeulich/src/binutils/mainline/2005-02-01/gas/testsuite/gas/macros/dot.l	1970-01-01 01:00:00.000000000 +0100
+++ 2005-02-01/gas/testsuite/gas/macros/dot.l	2005-02-04 10:54:39.000000000 +0100
@@ -0,0 +1,22 @@
+.*: Assembler messages:
+.*:[1-9][0-9]*: Warning: attempt to redefine pseudo-op `.macro' ignored
+.*:[1-9][0-9]*: Error: unknown pseudo-op: `.xyz'
+.*:[1-9][0-9]*: Error: unknown pseudo-op: `.y.z'
+(.* )?GAS .*
+#...
+[ 	]*[1-9][0-9]*[ 	]+m 4, 2
+[ 	]*[1-9][0-9]*[ 	]+> \.data
+[ 	]*[1-9][0-9]*[ 	]+> labelA:labelB:labelC:labelD:x\.y\.z 4\+2
+[ 	]*[1-9][0-9]*[ 	]+>> \.align 4
+[ 	]*[1-9][0-9]*[ 	]+\?+[ 	]+0606[ 	]+>> \.byte 4\+2,4\+2
+[ 	]*[1-9][0-9]*[ 	]+\?+[ 	]+0000[ 	]+> \.skip 2
+[ 	]*[1-9][0-9]*[ 	]+> labelZ:labelY:labelX:labelW:\.xyz 4-2
+[ 	]*[1-9][0-9]*[ 	]+>> \.align 8
+[ 	]*[1-9][0-9]*[ 	]+\?+[ 	]+0202[ 	]+>> \.byte 4-2,4-2
+[ 	]*[1-9][0-9]*[ 	]+\?+[ 	]+0000 ?0000[ 	]+> \.skip 4\*2
+[ 	]*[1-9][0-9]*[ 	]+0000 ?0000[ 	]*
+[ 	]*[1-9][0-9]*[ 	]+> label9:label8:label7:label6:
+[ 	]*[1-9][0-9]*[ 	]+
+[ 	]*[1-9][0-9]*[ 	]+\.purgem \.xyz, x\.y\.z
+[ 	]*[1-9][0-9]*[ 	]+\.xyz 0
+[ 	]*[1-9][0-9]*[ 	]+x\.y\.z 0
--- /home/jbeulich/src/binutils/mainline/2005-02-01/gas/testsuite/gas/macros/dot.s	1970-01-01 01:00:00.000000000 +0100
+++ 2005-02-01/gas/testsuite/gas/macros/dot.s	2005-02-08 09:57:12.000000000 +0100
@@ -0,0 +1,28 @@
+.altmacro
+
+.macro x.y.z val
+ .align 4
+ .byte val, val
+.endm
+
+.macro .xyz val
+ .align 8
+ .byte val, val
+.endm
+
+.macro .macro
+.endm
+
+label1:label2 : label3 :label4: m: .macro arg.1, arg.2
+ .data
+labelA:labelB : labelC :labelD: x.y.z arg.1+arg.2
+ .skip arg.2
+labelZ:labelY : labelX :labelW: .xyz arg.1-arg.2
+ .skip arg.1*arg.2
+label9:label8 : label7 :label6: .endm
+
+m 4, 2
+
+.purgem .xyz, x.y.z
+.xyz 0
+x.y.z 0
--- /home/jbeulich/src/binutils/mainline/2005-02-01/gas/testsuite/gas/macros/macros.exp	2005-01-31 15:27:07.000000000 +0100
+++ 2005-02-01/gas/testsuite/gas/macros/macros.exp	2005-02-04 16:44:31.000000000 +0100
@@ -63,5 +63,14 @@ run_dump_test app3
 run_dump_test app4
 
 run_list_test badarg ""
+case $target_triplet in {
+    { *c54x*-*-* } { }
+    { *c4x*-*-* } { }
+    { h8500-*-* } { }
+    { m68*-*-* } { }
+    { m88*-*-* } { }
+    { mmix-* } { }
+    default { run_list_test dot "-alm" }
+}
 run_list_test end ""
 run_list_test redef ""
--- /home/jbeulich/src/binutils/mainline/2005-02-01/gas/testsuite/gas/mmix/relax2.s	2003-10-18 18:00:21.000000000 +0200
+++ 2005-02-01/gas/testsuite/gas/mmix/relax2.s	2005-02-08 09:38:12.000000000 +0100
@@ -1,35 +1,37 @@
 # PUSHJ stub border-cases: two with either or both stubs unreachable,
 # local symbols, ditto non-local labels, similar with three PUSHJs.
 
+.altmacro
+
 Main	SWYM
 
 	.irp x,0,1,2,3,4,5,6,7,8,9,10,11,12
 
-	.section .text.a\x,"ax"
-aa\x:	.space 4,0
-a\x:	.space 65536*4,0
-	PUSHJ $33,aa\x
-	PUSHJ $22,a\x
-	.space 65535*4-4*\x
-
-	.section .text.b\x,"ax"
-bbb\x:	.space 4,0
-bb\x:	.space 4,0
-b\x:	.space 65535*4
-	PUSHJ $12,bbb\x
-	PUSHJ $13,bb\x
-	PUSHJ $14,b\x
-	.space 65535*4-4*\x
-
-	.section .text.c\x,"ax"
-c\x:	PUSHJ $100,ca\x
-	PUSHJ $101,cb\x
-	.space 65535*4-4*\x
-
-	.section .text.d\x,"ax"
-d\x:	PUSHJ $99,da\x
-	PUSHJ $98,db\x
-	PUSHJ $97,dc\x
-	.space 65535*4-4*\x
+	.section .text.a&x,"ax"
+aa&x&:	.space 4,0
+a&x&:	.space 65536*4,0
+	PUSHJ $33,aa&x
+	PUSHJ $22,a&x
+	.space 65535*4-4*x
+
+	.section .text.b&x,"ax"
+bbb&x&:	.space 4,0
+bb&x&:	.space 4,0
+b&x&:	.space 65535*4
+	PUSHJ $12,bbb&x
+	PUSHJ $13,bb&x
+	PUSHJ $14,b&x
+	.space 65535*4-4*x
+
+	.section .text.c&x,"ax"
+c&x&:	PUSHJ $100,ca&x
+	PUSHJ $101,cb&x
+	.space 65535*4-4*x
+
+	.section .text.d&x,"ax"
+d&x&:	PUSHJ $99,da&x
+	PUSHJ $98,db&x
+	PUSHJ $97,dc&x
+	.space 65535*4-4*x
 
 	.endr

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2005-04-11 12:48 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-02-09 14:32 [PATCH] Re: .macro behavior Jan Beulich
2005-02-09 15:03 ` Hans-Peter Nilsson
  -- strict thread matches above, loose matches on Subject: below --
2005-04-11 12:48 Jan Beulich
2005-03-29 16:26 Jan Beulich
2005-04-01 14:30 ` Nick Clifton
     [not found] <s225d5fa.098@emea1-mh.id2.novell.com>
2005-03-02 15:20 ` Ian Lance Taylor
2005-03-02 15:04 Jan Beulich
2005-03-02  8:28 Jan Beulich
2005-03-02 14:42 ` Ian Lance Taylor
2005-02-28 19:22 Jan Beulich
2005-02-28 23:47 ` Hans-Peter Nilsson
2005-02-28 13:37 Jan Beulich
2005-02-28 17:14 ` Hans-Peter Nilsson
     [not found]   ` <20050228222944.GF5299@bubble.modra.org>
2005-03-01  6:27     ` Hans-Peter Nilsson
2005-03-01  6:45       ` Hans-Peter Nilsson
2005-03-01  7:07       ` Alan Modra
     [not found] <s209d602.092@emea1-mh.id2.novell.com>
2005-02-09 14:14 ` Hans-Peter Nilsson
     [not found] <s209c6d8.000@emea1-mh.id2.novell.com>
2005-02-09 14:11 ` Hans-Peter Nilsson
2005-02-09 14:06 Jan Beulich
     [not found] <s209c8b9.060@emea1-mh.id2.novell.com>
2005-02-09 11:42 ` Hans-Peter Nilsson
2005-02-09 11:32 Jan Beulich
2005-02-09 10:28 Jan Beulich
2005-02-08 20:55 Jan Beulich
2005-02-08 23:05 ` Hans-Peter Nilsson
2005-02-08 23:58 ` Hans-Peter Nilsson
2005-02-08 17:52 Jan Beulich
2005-02-08 20:22 ` Hans-Peter Nilsson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).