This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
>>> 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 now also addresses 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. Built and tested natively on ia64-unknown-linux-gnu and as cross tools for a large number of targets. Unfortunately, it breaks the mmix test 'relax2', and after a bit of investigation I can't see how this could be fixed (mmix considers ':' a normal symbol character, and hence constructs like \x: in a macro now - correctly - try to find "x:" among the parameters, while previously only "x" was used and the colon left alone). Jan gas/ 2005-02-04 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-04 Jan Beulich <jbeulich@novell.com> * gas/macros/dot.[ls]: New. * gas/macros/macros.exp: Run new test. --- /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, ¯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 @@ -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, ¯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) { @@ -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-04 10:42:36.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:30.743421618 +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:
binutils-mainline-macro-identifiers.patch
Description: Text document
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |