From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29089 invoked by alias); 29 Mar 2005 15:34:51 -0000 Mailing-List: contact binutils-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sources.redhat.com Received: (qmail 28638 invoked from network); 29 Mar 2005 15:33:57 -0000 Received: from unknown (HELO emea1-mh.id2.novell.com) (195.33.99.129) by sourceware.org with SMTP; 29 Mar 2005 15:33:57 -0000 Received: from EMEA1-MTA by emea1-mh.id2.novell.com with Novell_GroupWise; Tue, 29 Mar 2005 16:33:56 +0200 Message-Id: Date: Tue, 29 Mar 2005 16:26:00 -0000 From: "Jan Beulich" To: Subject: Re: [PATCH] Re: .macro behavior Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=__Part8EAD8898.0__=" X-SW-Source: 2005-03/txt/msg00863.txt.bz2 This is a MIME message. If you are reading this text, you may want to consider changing to a mail reader or gateway that understands how to properly handle MIME multipart messages. --=__Part8EAD8898.0__= Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Content-length: 13948 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 * 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 * 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 -*- =20 +* Redefinition of macros now results in an error. + +* Macro names and macro parameter names can now be any identifier that wou= ld + also be legal as a symbol elsewhere. For macro parameter names, this is + known to cause problems in certain sources when the respective target us= es + characters inconsistently, and thus macro parameter references are no lo= nger + recognized as such. + * New command line option -mtune=3D[itanium1|itanium2] for IA64 targets. =20 Changes in 2.16: =20 -* Redefinition of macros now results in an error. - * New command line option -mhint.b=3D[ok|warning|error] for IA64 targets. =20 * New command line option -munwind-check=3D[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. */ =20 - /* 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] =3D=3D '_' - || ptr->ptr[i] =3D=3D '$')) - i++; - - /* And a colon. */ - if (i < ptr->len - && ptr->ptr[i] =3D=3D ':') - 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 >=3D 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 >=3D ptr->len || ptr->ptr[i] !=3D ':') + { + i =3D line_start; + break; + } + i++; + line_start =3D i; + } =20 } /* Skip trailing whitespace. */ @@ -226,11 +242,13 @@ buffer_and_nest (const char *from, const ? strncasecmp (ptr->ptr + i, from, from_len) =3D=3D 0 : from_len > 0) && (ptr->len =3D=3D (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) =3D=3D 0 && (ptr->len =3D=3D (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 =3D=3D 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] =3D=3D '_' - || in->ptr[idx] =3D=3D '$')) + && is_name_beginner (in->ptr[idx])) { sb_add_char (name, in->ptr[idx++]); while (idx < in->len - && (ISALNUM (in->ptr[idx]) - || in->ptr[idx] =3D=3D '_' - || in->ptr[idx] =3D=3D '$')) + && 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 =3D sub_actual (src + 1, in, &t, formal_hash, '&', out, 0); } } else if (in->ptr[src] =3D=3D '\\') { src++; - if (in->ptr[src] =3D=3D '(') + if (src < in->len && in->ptr[src] =3D=3D '(') { /* Sub in till the next ')' literally. */ src++; @@ -709,9 +729,9 @@ macro_expand_body (sb *in, sb *out, form if (in->ptr[src] =3D=3D ')') src++; else - return _("missplaced )"); + return _("misplaced `)'"); } - else if (in->ptr[src] =3D=3D '@') + else if (src < in->len && in->ptr[src] =3D=3D '@') { /* Sub in the macro invocation number. */ =20 @@ -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] =3D=3D '&') + else if (src < in->len && in->ptr[src] =3D=3D '&') { /* 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] =3D=3D '_' - || in->ptr[src] =3D=3D '$') + && is_name_beginner (in->ptr[src]) && (! inquote || ! macro_strip_at || (src > 0 && in->ptr[src - 1] =3D=3D '@'))) @@ -1086,16 +1104,14 @@ check_macro (const char *line, sb *expan macro_entry *macro; sb line_sb; =20 - if (! ISALPHA (*line) - && *line !=3D '_' - && *line !=3D '$' + if (! is_name_beginner (*line) && (! macro_mri || *line !=3D '.')) return 0; =20 s =3D line + 1; - while (ISALNUM (*s) - || *s =3D=3D '_' - || *s =3D=3D '$') + while (is_part_of_name (*s)) + ++s; + if (is_name_ender (*s)) ++s; =20 copy =3D (char *) alloca (s - line + 1); --- /home/jbeulich/src/binutils/mainline/2005-03-29/gas/read.c 2005-03-02 0= 8: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; } =20 +/* 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, ¯o)) + { + if (err !=3D NULL) + as_bad ("%s", err); + *input_line_pointer++ =3D term; + input_scrub_include_sb (&out, + input_line_pointer, 1); + sb_kill (&out); + buffer_limit =3D + 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) =20 while ((buffer_limit =3D input_scrub_next_buffer (&input_line_pointer)) = !=3D 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 =3D NULL; +#endif know (buffer_limit[-1] =3D=3D '\n'); /* Must have a sentinel. */ =20 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; =20 - /* Copy it for safe keeping. Also give an indication of - how much macro nesting is involved at this point. */ - len =3D s - (input_line_pointer - 1); - copy =3D (char *) xmalloc (len + macro_nest + 2); - memset (copy, '>', macro_nest); - copy[macro_nest] =3D ' '; - memcpy (copy + macro_nest + 1, input_line_pointer - 1, len); - copy[macro_nest + 1 + len] =3D '\0'; + if (s !=3D last_eol) + { + last_eol =3D s; + /* Copy it for safe keeping. Also give an indication of + how much macro nesting is involved at this point. */ + len =3D s - (input_line_pointer - 1); + copy =3D (char *) xmalloc (len + macro_nest + 2); + memset (copy, '>', macro_nest); + copy[macro_nest] =3D ' '; + memcpy (copy + macro_nest + 1, input_line_pointer - 1, len); + copy[macro_nest + 1 + len] =3D '\0'; =20 - /* 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 =3D=3D NULL) { - as_bad (_("unknown pseudo-op: `%s'"), s); + char *end =3D input_line_pointer; + *input_line_pointer =3D c; s_ignore (0); + c =3D *--input_line_pointer; + *input_line_pointer =3D '\0'; + if (! macro_defined || ! try_macro (c, s)) + { + *end =3D '\0'; + as_bad (_("unknown pseudo-op: `%s'"), s); + *input_line_pointer++ =3D c; + } continue; } =20 @@ -874,28 +920,8 @@ read_a_source_file (char *name) =20 generate_lineno_debug (); =20 - if (macro_defined) - { - sb out; - const char *err; - macro_entry *macro; - - if (check_macro (s, &out, &err, ¯o)) - { - if (err !=3D NULL) - as_bad ("%s", err); - *input_line_pointer++ =3D c; - input_scrub_include_sb (&out, - input_line_pointer, 1); - sb_kill (&out); - buffer_limit =3D - 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; =20 if (mri_pending_align) { @@ -2319,7 +2345,7 @@ s_macro (int ignore ATTRIBUTE_UNUSED) { if (line_label !=3D 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/macro= s/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/macro= s/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/macro= s/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.3890= 54720 +0200 @@ -68,5 +68,14 @@ run_dump_test app3 run_dump_test app4 =20 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 "" --=__Part8EAD8898.0__= Content-Type: text/plain; name="binutils-mainline-macro-identifiers.patch" Content-Transfer-Encoding: 8bit Content-Disposition: attachment; filename="binutils-mainline-macro-identifiers.patch" Content-length: 13691 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 * 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 * 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, ¯o)) + { + 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, ¯o)) - { - 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 "" --=__Part8EAD8898.0__=--