* Re: .macro behavior
@ 2005-01-26 16:31 Jan Beulich
2005-01-31 11:26 ` Nick Clifton
0 siblings, 1 reply; 5+ messages in thread
From: Jan Beulich @ 2005-01-26 16:31 UTC (permalink / raw)
To: binutils
[-- Attachment #1: Type: text/plain, Size: 8979 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.
Various broken macro definitions were accepted until now.
Built and tested natively on i686-pc-linux-gnu and as cross tools for
a
large number of targets.
Jan
gas/
2005-01-26 Jan Beulich <jbeulich@novell.com>
* macro.c (do_formals): Adjust to no longer accept empty
parameter
names.
(define_macro): Adjust to no longer accept empty macro name,
garbage
following the parameters, or macros that were previously
defined.
* read.c (s_bad_end): Declare.
(potable): Add endm. Handler for endr and endm is s_bad_end.
(s_bad_end): Rename from s_bad_endr. Adjust to handle both
.endm
and .endr.
* read.h (s_bad_endr): Remove.
gas/testsuite/
2005-01-26 Jan Beulich <jbeulich@novell.com>
* gas/macros/badarg.[ls]: New.
* gas/macros/end.[ls]: New.
* gas/macros/redef.[ls]: New.
* gas/macros/macros.exp (run_list_test): Copy from elsewhere.
Run new tests.
---
/home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/macro.c 2004-10-08
08:52:54.000000000 +0200
+++ 2005-01-25.13.54/gas/macro.c 2005-01-26 08:32:36.982880800
+0100
@@ -435,9 +435,11 @@ do_formals (macro_entry *macro, int idx,
macro->formal_count = 0;
macro->formal_hash = hash_new ();
+ idx = sb_skip_white (idx, in);
while (idx < in->len)
{
formal_entry *formal;
+ int cidx;
formal = (formal_entry *) xmalloc (sizeof (formal_entry));
@@ -445,27 +447,33 @@ do_formals (macro_entry *macro, int idx,
sb_new (&formal->def);
sb_new (&formal->actual);
- idx = sb_skip_white (idx, in);
idx = get_token (idx, in, &formal->name);
if (formal->name.len == 0)
- break;
+ {
+ if (macro->formal_count)
+ --idx;
+ break;
+ }
idx = sb_skip_white (idx, in);
- if (formal->name.len)
+ /* This is a formal. */
+ if (idx < in->len && in->ptr[idx] == '=')
{
- /* This is a formal. */
- if (idx < in->len && in->ptr[idx] == '=')
- {
- /* Got a default. */
- idx = get_any_string (idx + 1, in, &formal->def, 1, 0);
- }
+ /* Got a default. */
+ idx = get_any_string (idx + 1, in, &formal->def, 1, 0);
+ idx = sb_skip_white (idx, in);
}
/* Add to macro's hash table. */
hash_jam (macro->formal_hash, sb_terminate (&formal->name),
formal);
- formal->index = macro->formal_count;
+ formal->index = macro->formal_count++;
+ cidx = idx;
idx = sb_skip_comma (idx, in);
- macro->formal_count++;
+ if (idx != cidx && idx >= in->len)
+ {
+ idx = cidx;
+ break;
+ }
*p = formal;
p = &formal->next;
*p = NULL;
@@ -533,8 +541,9 @@ define_macro (int idx, sb *in, sb *label
{
/* It's the label: MACRO (formals,...) sort */
idx = do_formals (macro, idx + 1, in);
- if (in->ptr[idx] != ')')
+ if (idx >= in->len || in->ptr[idx] != ')')
return _("missing ) after formals");
+ idx = sb_skip_white (idx + 1, in);
}
else
{
@@ -544,15 +553,27 @@ define_macro (int idx, sb *in, sb *label
}
else
{
+ int cidx;
+
idx = get_token (idx, in, &name);
- idx = sb_skip_comma (idx, in);
- idx = do_formals (macro, idx, in);
+ if (name.len == 0)
+ return _("Missing macro name");
+ cidx = sb_skip_white (idx, in);
+ idx = sb_skip_comma (cidx, in);
+ if (idx == cidx || idx < in->len)
+ idx = do_formals (macro, idx, in);
+ else
+ idx = cidx;
}
+ if (idx < in->len)
+ return _("Bad macro parameter list");
/* And stick it in the macro hash table. */
for (idx = 0; idx < name.len; idx++)
name.ptr[idx] = TOLOWER (name.ptr[idx]);
namestr = sb_terminate (&name);
+ if (hash_find (macro_hash, namestr))
+ return _("Macro with this name was already defined");
hash_jam (macro_hash, namestr, (PTR) macro);
macro_defined = 1;
---
/home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/read.c 2005-01-24
08:34:19.000000000 +0100
+++ 2005-01-25.13.54/gas/read.c 2005-01-26 08:33:12.715448624
+0100
@@ -214,6 +214,7 @@ static int dwarf_file_string;
static void do_align (int, char *, int, int);
static void s_align (int, int);
static void s_altmacro (int);
+static void s_bad_end (int);
static int hex_float (int, char *);
static segT get_known_segmented_expression (expressionS * expP);
static void pobegin (void);
@@ -298,7 +299,8 @@ static const pseudo_typeS potable[] = {
{"endc", s_endif, 0},
{"endfunc", s_func, 1},
{"endif", s_endif, 0},
- {"endr", s_bad_endr, 0},
+ {"endm", s_bad_end, 0},
+ {"endr", s_bad_end, 1},
/* endef */
{"equ", s_set, 0},
{"equiv", s_set, 1},
@@ -2659,12 +2661,14 @@ s_purgem (int ignore ATTRIBUTE_UNUSED)
demand_empty_rest_of_line ();
}
-/* Handle the .rept pseudo-op. */
+/* Handle the .endm/.endr pseudo-ops. */
-void
-s_bad_endr (int ignore ATTRIBUTE_UNUSED)
+static void
+s_bad_end (int endr)
{
- as_warn (_(".endr encountered without preceeding .rept, .irc, or
.irp"));
+ as_warn (_(".end%c encountered without preceeding %s"),
+ endr ? 'r' : 'm',
+ endr ? ".rept, .irp, or .irpc" : ".macro");
demand_empty_rest_of_line ();
}
---
/home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/read.h 2004-11-23
08:19:29.000000000 +0100
+++ 2005-01-25.13.54/gas/read.h 2005-01-26 08:32:37.030873504
+0100
@@ -142,7 +142,6 @@ extern symbolS *s_lcomm_internal (int, s
extern void s_app_file_string (char *, int);
extern void s_app_file (int);
extern void s_app_line (int);
-extern void s_bad_endr (int);
extern void s_comm (int);
extern void s_data (int);
extern void s_desc (int);
---
/home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/testsuite/gas/macros/badarg.l 1970-01-01
01:00:00.000000000 +0100
+++ 2005-01-25.13.54/gas/testsuite/gas/macros/badarg.l 2005-01-25
09:55:54.000000000 +0100
@@ -0,0 +1,7 @@
+.*: Assembler messages:
+.*:1: Error: .*
+.*:4: Error: .*
+.*:7: Error: .*
+.*:10: Error: .*
+.*:13: Error: .*
+.*:16: Error: .*
---
/home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/testsuite/gas/macros/badarg.s 1970-01-01
01:00:00.000000000 +0100
+++ 2005-01-25.13.54/gas/testsuite/gas/macros/badarg.s 2005-01-25
09:55:37.000000000 +0100
@@ -0,0 +1,17 @@
+ .macro
+ .endm
+
+ .macro ,arg1
+ .endm
+
+ .macro m1,
+ .endm
+
+ .macro m2,,
+ .endm
+
+ .macro m3,arg1,
+ .endm
+
+ .macro m4,,arg2
+ .endm
---
/home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/testsuite/gas/macros/end.l 1970-01-01
01:00:00.000000000 +0100
+++ 2005-01-25.13.54/gas/testsuite/gas/macros/end.l 2005-01-25
11:30:38.000000000 +0100
@@ -0,0 +1,3 @@
+.*: Assembler messages:
+.*:1: Warning: \.endm .* \.macro
+.*:2: Warning: \.endr .*
(\.rept|\.irpc?).*(\.rept|\.irpc?).*(\.rept|\.irpc?)
---
/home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/testsuite/gas/macros/end.s 1970-01-01
01:00:00.000000000 +0100
+++ 2005-01-25.13.54/gas/testsuite/gas/macros/end.s 2005-01-25
11:26:25.000000000 +0100
@@ -0,0 +1,2 @@
+ .endm
+ .endr
---
/home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/testsuite/gas/macros/macros.exp 2004-11-18
15:05:44.000000000 +0100
+++
2005-01-25.13.54/gas/testsuite/gas/macros/macros.exp 2005-01-26
08:32:37.074866816 +0100
@@ -1,5 +1,18 @@
# Run some tests of gas macros.
+proc run_list_test { name opts } {
+ global srcdir subdir
+ set testname "macros $name"
+ set file $srcdir/$subdir/$name
+ gas_run ${name}.s $opts ">&dump.out"
+ if { [regexp_diff "dump.out" "${file}.l"] } then {
+ fail $testname
+ verbose "output is [file_contents "dump.out"]" 2
+ return
+ }
+ pass $testname
+}
+
if { ![istarget hppa*-*-*] || [istarget *-*-linux*] } {
run_dump_test test1
}
@@ -47,3 +60,7 @@ run_dump_test app1
run_dump_test app2
run_dump_test app3
run_dump_test app4
+
+run_list_test badarg ""
+run_list_test end ""
+run_list_test redef ""
---
/home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/testsuite/gas/macros/redef.l 1970-01-01
01:00:00.000000000 +0100
+++ 2005-01-25.13.54/gas/testsuite/gas/macros/redef.l 2005-01-25
11:39:54.000000000 +0100
@@ -0,0 +1,2 @@
+.*: Assembler messages:
+.*:3: Error: .*
---
/home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/testsuite/gas/macros/redef.s 1970-01-01
01:00:00.000000000 +0100
+++ 2005-01-25.13.54/gas/testsuite/gas/macros/redef.s 2005-01-25
11:36:32.000000000 +0100
@@ -0,0 +1,4 @@
+ .macro m
+ .endm
+ .macro m
+ .endm
[-- Attachment #2: binutils-mainline-macro-diagnostics.patch --]
[-- Type: text/plain, Size: 8310 bytes --]
Various broken macro definitions were accepted until now.
Built and tested natively on i686-pc-linux-gnu and as cross tools for a
large number of targets.
Jan
gas/
2005-01-26 Jan Beulich <jbeulich@novell.com>
* macro.c (do_formals): Adjust to no longer accept empty parameter
names.
(define_macro): Adjust to no longer accept empty macro name, garbage
following the parameters, or macros that were previously defined.
* read.c (s_bad_end): Declare.
(potable): Add endm. Handler for endr and endm is s_bad_end.
(s_bad_end): Rename from s_bad_endr. Adjust to handle both .endm
and .endr.
* read.h (s_bad_endr): Remove.
gas/testsuite/
2005-01-26 Jan Beulich <jbeulich@novell.com>
* gas/macros/badarg.[ls]: New.
* gas/macros/end.[ls]: New.
* gas/macros/redef.[ls]: New.
* gas/macros/macros.exp (run_list_test): Copy from elsewhere.
Run new tests.
--- /home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/macro.c 2004-10-08 08:52:54.000000000 +0200
+++ 2005-01-25.13.54/gas/macro.c 2005-01-26 08:32:36.982880800 +0100
@@ -435,9 +435,11 @@ do_formals (macro_entry *macro, int idx,
macro->formal_count = 0;
macro->formal_hash = hash_new ();
+ idx = sb_skip_white (idx, in);
while (idx < in->len)
{
formal_entry *formal;
+ int cidx;
formal = (formal_entry *) xmalloc (sizeof (formal_entry));
@@ -445,27 +447,33 @@ do_formals (macro_entry *macro, int idx,
sb_new (&formal->def);
sb_new (&formal->actual);
- idx = sb_skip_white (idx, in);
idx = get_token (idx, in, &formal->name);
if (formal->name.len == 0)
- break;
+ {
+ if (macro->formal_count)
+ --idx;
+ break;
+ }
idx = sb_skip_white (idx, in);
- if (formal->name.len)
+ /* This is a formal. */
+ if (idx < in->len && in->ptr[idx] == '=')
{
- /* This is a formal. */
- if (idx < in->len && in->ptr[idx] == '=')
- {
- /* Got a default. */
- idx = get_any_string (idx + 1, in, &formal->def, 1, 0);
- }
+ /* Got a default. */
+ idx = get_any_string (idx + 1, in, &formal->def, 1, 0);
+ idx = sb_skip_white (idx, in);
}
/* Add to macro's hash table. */
hash_jam (macro->formal_hash, sb_terminate (&formal->name), formal);
- formal->index = macro->formal_count;
+ formal->index = macro->formal_count++;
+ cidx = idx;
idx = sb_skip_comma (idx, in);
- macro->formal_count++;
+ if (idx != cidx && idx >= in->len)
+ {
+ idx = cidx;
+ break;
+ }
*p = formal;
p = &formal->next;
*p = NULL;
@@ -533,8 +541,9 @@ define_macro (int idx, sb *in, sb *label
{
/* It's the label: MACRO (formals,...) sort */
idx = do_formals (macro, idx + 1, in);
- if (in->ptr[idx] != ')')
+ if (idx >= in->len || in->ptr[idx] != ')')
return _("missing ) after formals");
+ idx = sb_skip_white (idx + 1, in);
}
else
{
@@ -544,15 +553,27 @@ define_macro (int idx, sb *in, sb *label
}
else
{
+ int cidx;
+
idx = get_token (idx, in, &name);
- idx = sb_skip_comma (idx, in);
- idx = do_formals (macro, idx, in);
+ if (name.len == 0)
+ return _("Missing macro name");
+ cidx = sb_skip_white (idx, in);
+ idx = sb_skip_comma (cidx, in);
+ if (idx == cidx || idx < in->len)
+ idx = do_formals (macro, idx, in);
+ else
+ idx = cidx;
}
+ if (idx < in->len)
+ return _("Bad macro parameter list");
/* And stick it in the macro hash table. */
for (idx = 0; idx < name.len; idx++)
name.ptr[idx] = TOLOWER (name.ptr[idx]);
namestr = sb_terminate (&name);
+ if (hash_find (macro_hash, namestr))
+ return _("Macro with this name was already defined");
hash_jam (macro_hash, namestr, (PTR) macro);
macro_defined = 1;
--- /home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/read.c 2005-01-24 08:34:19.000000000 +0100
+++ 2005-01-25.13.54/gas/read.c 2005-01-26 08:33:12.715448624 +0100
@@ -214,6 +214,7 @@ static int dwarf_file_string;
static void do_align (int, char *, int, int);
static void s_align (int, int);
static void s_altmacro (int);
+static void s_bad_end (int);
static int hex_float (int, char *);
static segT get_known_segmented_expression (expressionS * expP);
static void pobegin (void);
@@ -298,7 +299,8 @@ static const pseudo_typeS potable[] = {
{"endc", s_endif, 0},
{"endfunc", s_func, 1},
{"endif", s_endif, 0},
- {"endr", s_bad_endr, 0},
+ {"endm", s_bad_end, 0},
+ {"endr", s_bad_end, 1},
/* endef */
{"equ", s_set, 0},
{"equiv", s_set, 1},
@@ -2659,12 +2661,14 @@ s_purgem (int ignore ATTRIBUTE_UNUSED)
demand_empty_rest_of_line ();
}
-/* Handle the .rept pseudo-op. */
+/* Handle the .endm/.endr pseudo-ops. */
-void
-s_bad_endr (int ignore ATTRIBUTE_UNUSED)
+static void
+s_bad_end (int endr)
{
- as_warn (_(".endr encountered without preceeding .rept, .irc, or .irp"));
+ as_warn (_(".end%c encountered without preceeding %s"),
+ endr ? 'r' : 'm',
+ endr ? ".rept, .irp, or .irpc" : ".macro");
demand_empty_rest_of_line ();
}
--- /home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/read.h 2004-11-23 08:19:29.000000000 +0100
+++ 2005-01-25.13.54/gas/read.h 2005-01-26 08:32:37.030873504 +0100
@@ -142,7 +142,6 @@ extern symbolS *s_lcomm_internal (int, s
extern void s_app_file_string (char *, int);
extern void s_app_file (int);
extern void s_app_line (int);
-extern void s_bad_endr (int);
extern void s_comm (int);
extern void s_data (int);
extern void s_desc (int);
--- /home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/testsuite/gas/macros/badarg.l 1970-01-01 01:00:00.000000000 +0100
+++ 2005-01-25.13.54/gas/testsuite/gas/macros/badarg.l 2005-01-25 09:55:54.000000000 +0100
@@ -0,0 +1,7 @@
+.*: Assembler messages:
+.*:1: Error: .*
+.*:4: Error: .*
+.*:7: Error: .*
+.*:10: Error: .*
+.*:13: Error: .*
+.*:16: Error: .*
--- /home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/testsuite/gas/macros/badarg.s 1970-01-01 01:00:00.000000000 +0100
+++ 2005-01-25.13.54/gas/testsuite/gas/macros/badarg.s 2005-01-25 09:55:37.000000000 +0100
@@ -0,0 +1,17 @@
+ .macro
+ .endm
+
+ .macro ,arg1
+ .endm
+
+ .macro m1,
+ .endm
+
+ .macro m2,,
+ .endm
+
+ .macro m3,arg1,
+ .endm
+
+ .macro m4,,arg2
+ .endm
--- /home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/testsuite/gas/macros/end.l 1970-01-01 01:00:00.000000000 +0100
+++ 2005-01-25.13.54/gas/testsuite/gas/macros/end.l 2005-01-25 11:30:38.000000000 +0100
@@ -0,0 +1,3 @@
+.*: Assembler messages:
+.*:1: Warning: \.endm .* \.macro
+.*:2: Warning: \.endr .* (\.rept|\.irpc?).*(\.rept|\.irpc?).*(\.rept|\.irpc?)
--- /home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/testsuite/gas/macros/end.s 1970-01-01 01:00:00.000000000 +0100
+++ 2005-01-25.13.54/gas/testsuite/gas/macros/end.s 2005-01-25 11:26:25.000000000 +0100
@@ -0,0 +1,2 @@
+ .endm
+ .endr
--- /home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/testsuite/gas/macros/macros.exp 2004-11-18 15:05:44.000000000 +0100
+++ 2005-01-25.13.54/gas/testsuite/gas/macros/macros.exp 2005-01-26 08:32:37.074866816 +0100
@@ -1,5 +1,18 @@
# Run some tests of gas macros.
+proc run_list_test { name opts } {
+ global srcdir subdir
+ set testname "macros $name"
+ set file $srcdir/$subdir/$name
+ gas_run ${name}.s $opts ">&dump.out"
+ if { [regexp_diff "dump.out" "${file}.l"] } then {
+ fail $testname
+ verbose "output is [file_contents "dump.out"]" 2
+ return
+ }
+ pass $testname
+}
+
if { ![istarget hppa*-*-*] || [istarget *-*-linux*] } {
run_dump_test test1
}
@@ -47,3 +60,7 @@ run_dump_test app1
run_dump_test app2
run_dump_test app3
run_dump_test app4
+
+run_list_test badarg ""
+run_list_test end ""
+run_list_test redef ""
--- /home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/testsuite/gas/macros/redef.l 1970-01-01 01:00:00.000000000 +0100
+++ 2005-01-25.13.54/gas/testsuite/gas/macros/redef.l 2005-01-25 11:39:54.000000000 +0100
@@ -0,0 +1,2 @@
+.*: Assembler messages:
+.*:3: Error: .*
--- /home/jbeulich/src/binutils/mainline/2005-01-25.13.54/gas/testsuite/gas/macros/redef.s 1970-01-01 01:00:00.000000000 +0100
+++ 2005-01-25.13.54/gas/testsuite/gas/macros/redef.s 2005-01-25 11:36:32.000000000 +0100
@@ -0,0 +1,4 @@
+ .macro m
+ .endm
+ .macro m
+ .endm
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: .macro behavior
2005-01-26 16:31 .macro behavior Jan Beulich
@ 2005-01-31 11:26 ` Nick Clifton
0 siblings, 0 replies; 5+ messages in thread
From: Nick Clifton @ 2005-01-31 11:26 UTC (permalink / raw)
To: Jan Beulich; +Cc: binutils
Hi Jan,
> gas/
> 2005-01-26 Jan Beulich <jbeulich@novell.com>
>
> * macro.c (do_formals): Adjust to no longer accept empty
> parameter
> names.
> (define_macro): Adjust to no longer accept empty macro name,
> garbage
> following the parameters, or macros that were previously
> defined.
> * read.c (s_bad_end): Declare.
> (potable): Add endm. Handler for endr and endm is s_bad_end.
> (s_bad_end): Rename from s_bad_endr. Adjust to handle both
> .endm
> and .endr.
> * read.h (s_bad_endr): Remove.
>
> gas/testsuite/
> 2005-01-26 Jan Beulich <jbeulich@novell.com>
>
> * gas/macros/badarg.[ls]: New.
> * gas/macros/end.[ls]: New.
> * gas/macros/redef.[ls]: New.
> * gas/macros/macros.exp (run_list_test): Copy from elsewhere.
> Run new tests.
>
Approved - please apply.
Cheers
Nick
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: .macro behavior
@ 2005-02-08 13:57 Jan Beulich
0 siblings, 0 replies; 5+ messages in thread
From: Jan Beulich @ 2005-02-08 13:57 UTC (permalink / raw)
To: binutils
[-- Attachment #1: Type: text/plain, Size: 13709 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 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 #2: binutils-mainline-macro-identifiers.patch --]
[-- Type: text/plain, Size: 12855 bytes --]
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 ""
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: .macro behavior
2005-01-14 16:30 Jan Beulich
@ 2005-01-14 16:50 ` Ian Lance Taylor
0 siblings, 0 replies; 5+ messages in thread
From: Ian Lance Taylor @ 2005-01-14 16:50 UTC (permalink / raw)
To: Jan Beulich; +Cc: binutils
"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.
Ian
^ permalink raw reply [flat|nested] 5+ messages in thread
* .macro behavior
@ 2005-01-14 16:30 Jan Beulich
2005-01-14 16:50 ` Ian Lance Taylor
0 siblings, 1 reply; 5+ messages in thread
From: Jan Beulich @ 2005-01-14 16:30 UTC (permalink / raw)
To: binutils
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...
Thanks, Jan
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2005-02-08 7:48 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-01-26 16:31 .macro behavior Jan Beulich
2005-01-31 11:26 ` Nick Clifton
-- strict thread matches above, loose matches on Subject: below --
2005-02-08 13:57 Jan Beulich
2005-01-14 16:30 Jan Beulich
2005-01-14 16:50 ` Ian Lance Taylor
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).