1 /* gasp.c - Gnu assembler preprocessor main program.
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
5 Written by Steve and Judy Chamberlain of Cygnus Support,
8 This file is part of GASP, the GNU Assembler Preprocessor.
10 GASP is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
15 GASP is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GASP; see the file COPYING. If not, write to the Free
22 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
26 This program translates the input macros and stuff into a form
27 suitable for gas to consume.
29 gasp [-sdhau] [-c char] [-o <outfile>] <infile>*
31 -s copy source to output
32 -c <char> comments are started with <char> instead of !
33 -u allow unreasonable stuff
35 -d print debugging stats
36 -s semi colons start comments
37 -a use alternate syntax
38 Pseudo ops can start with or without a .
39 Labels have to be in first column.
40 -I specify include dir
41 Macro arg parameters subsituted by name, don't need the &.
42 String can start with ' too.
43 Strings can be surrounded by <..>
44 A %<exp> in a string evaluates the expression
45 Literal char in a string with !
59 #ifdef NEED_MALLOC_DECLARATION
60 extern char *malloc ();
64 #include "libiberty.h"
65 #include "safe-ctype.h"
70 char *program_version
= "1.2";
72 /* This is normally declared in as.h, but we don't include that. We
73 need the function because other files linked with gasp.c might call
75 extern void as_abort
PARAMS ((const char *, int, const char *));
77 /* The default obstack chunk size. If we set this to zero, the
78 obstack code will use whatever will fit in a 4096 byte block. This
79 is used by the hash table code used by macro.c. */
82 #define MAX_INCLUDES 30 /* Maximum include depth. */
83 #define MAX_REASONABLE 1000 /* Maximum number of expansions. */
85 int unreasonable
; /* -u on command line. */
86 int stats
; /* -d on command line. */
87 int print_line_number
; /* -p flag on command line. */
88 int copysource
; /* -c flag on command line. */
89 int warnings
; /* Number of WARNINGs generated so far. */
90 int errors
; /* Number of ERRORs generated so far. */
91 int fatals
; /* Number of fatal ERRORs generated so far (either 0 or 1). */
92 int alternate
= 0; /* -a on command line. */
93 int mri
= 0; /* -M on command line. */
94 char comment_char
= '!';
95 int radix
= 10; /* Default radix. */
97 int had_end
; /* Seen .END. */
99 /* The output stream. */
102 /* The attributes of each character are stored as a bit pattern
103 chartype, which gives us quick tests. */
109 #define COMMENTBIT 16
111 #define ISCOMMENTCHAR(x) (chartype[(unsigned char)(x)] & COMMENTBIT)
112 #define ISFIRSTCHAR(x) (chartype[(unsigned char)(x)] & FIRSTBIT)
113 #define ISNEXTCHAR(x) (chartype[(unsigned char)(x)] & NEXTBIT)
114 #define ISSEP(x) (chartype[(unsigned char)(x)] & SEPBIT)
115 #define ISWHITE(x) (chartype[(unsigned char)(x)] & WHITEBIT)
116 #define ISBASE(x) (chartype[(unsigned char)(x)] & BASEBIT)
117 static char chartype
[256];
119 /* Conditional assembly uses the `ifstack'. Each aif pushes another
120 entry onto the stack, and sets the on flag if it should. The aelse
121 sets hadelse, and toggles on. An aend pops a level. We limit to
122 100 levels of nesting, not because we're facists pigs with read
123 only minds, but because more than 100 levels of nesting is probably
124 a bug in the user's macro structure. */
126 #define IFNESTING 100
128 int on
; /* Is the level being output. */
129 int hadelse
; /* Has an aelse been seen. */
130 } ifstack
[IFNESTING
];
134 /* The final and intermediate results of expression evaluation are kept in
135 exp_t's. Note that a symbol is not an sb, but a pointer into the input
136 line. It must be coped somewhere safe before the next line is read in. */
144 int value
; /* Constant part. */
145 symbol add_symbol
; /* Name part. */
146 symbol sub_symbol
; /* Name part. */
149 /* Hashing is done in a pretty standard way. A hash_table has a
150 pointer to a vector of pointers to hash_entrys, and the size of the
151 vector. A hash_entry contains a union of all the info we like to
152 store in hash table. If there is a hash collision, hash_entries
153 with the same hash are kept in a chain. */
155 /* What the data in a hash_entry means. */
157 hash_integer
, /* Name->integer mapping. */
158 hash_string
, /* Name->string mapping. */
159 hash_macro
, /* Name is a macro. */
160 hash_formal
/* Name is a formal argument. */
164 sb key
; /* Symbol name. */
165 hash_type type
; /* Symbol meaning. */
169 struct macro_struct
*m
;
170 struct formal_struct
*f
;
172 struct hs
*next
; /* Next hash_entry with same hash key. */
180 /* How we nest files and expand macros etc.
182 We keep a stack of of include_stack structs. Each include file
183 pushes a new level onto the stack. We keep an sb with a pushback
184 too. unget chars are pushed onto the pushback sb, getchars first
185 checks the pushback sb before reading from the input stream.
187 Small things are expanded by adding the text of the item onto the
188 pushback sb. Larger items are grown by pushing a new level and
189 allocating the entire pushback buf for the item. Each time
190 something like a macro is expanded, the stack index is changed. We
191 can then perform an exitm by popping all entries off the stack with
192 the same stack index. If we're being reasonable, we can detect
193 recusive expansion by checking the index is reasonably small. */
196 include_file
, include_repeat
, include_while
, include_macro
199 struct include_stack
{
200 sb pushback
; /* Current pushback stream. */
201 int pushback_index
; /* Next char to read from stream. */
202 FILE *handle
; /* Open file. */
203 sb name
; /* Name of file. */
204 int linecount
; /* Number of lines read so far. */
206 int index
; /* Index of this layer. */
207 } include_stack
[MAX_INCLUDES
];
209 struct include_stack
*sp
;
210 #define isp (sp - include_stack)
212 /* Include file list. */
214 typedef struct include_path
{
215 struct include_path
*next
;
219 include_path
*paths_head
;
220 include_path
*paths_tail
;
222 static void quit
PARAMS ((void));
223 static void hash_new_table
PARAMS ((int, hash_table
*));
224 static int hash
PARAMS ((sb
*));
225 static hash_entry
*hash_create
PARAMS ((hash_table
*, sb
*));
226 static void hash_add_to_string_table
PARAMS ((hash_table
*, sb
*, sb
*, int));
227 static void hash_add_to_int_table
PARAMS ((hash_table
*, sb
*, int));
228 static hash_entry
*hash_lookup
PARAMS ((hash_table
*, sb
*));
229 static void checkconst
PARAMS ((int, exp_t
*));
230 static int sb_strtol
PARAMS ((int, sb
*, int, int *));
231 static int level_0
PARAMS ((int, sb
*, exp_t
*));
232 static int level_1
PARAMS ((int, sb
*, exp_t
*));
233 static int level_2
PARAMS ((int, sb
*, exp_t
*));
234 static int level_3
PARAMS ((int, sb
*, exp_t
*));
235 static int level_4
PARAMS ((int, sb
*, exp_t
*));
236 static int level_5
PARAMS ((int, sb
*, exp_t
*));
237 static int exp_parse
PARAMS ((int, sb
*, exp_t
*));
238 static void exp_string
PARAMS ((exp_t
*, sb
*));
239 static int exp_get_abs
PARAMS ((const char *, int, sb
*, int *));
241 static void strip_comments
PARAMS ((sb
*));
243 static void unget
PARAMS ((int));
244 static void include_buf
PARAMS ((sb
*, sb
*, include_type
, int));
245 static void include_print_where_line
PARAMS ((FILE *));
246 static void include_print_line
PARAMS ((FILE *));
247 static int get_line
PARAMS ((sb
*));
248 static int grab_label
PARAMS ((sb
*, sb
*));
249 static void change_base
PARAMS ((int, sb
*, sb
*));
250 static void do_end
PARAMS ((sb
*));
251 static void do_assign
PARAMS ((int, int, sb
*));
252 static void do_radix
PARAMS ((sb
*));
253 static int get_opsize
PARAMS ((int, sb
*, int *));
254 static int eol
PARAMS ((int, sb
*));
255 static void do_data
PARAMS ((int, sb
*, int));
256 static void do_datab
PARAMS ((int, sb
*));
257 static void do_align
PARAMS ((int, sb
*));
258 static void do_res
PARAMS ((int, sb
*, int));
259 static void do_export
PARAMS ((sb
*));
260 static void do_print
PARAMS ((int, sb
*));
261 static void do_heading
PARAMS ((int, sb
*));
262 static void do_page
PARAMS ((void));
263 static void do_form
PARAMS ((int, sb
*));
264 static int get_any_string
PARAMS ((int, sb
*, sb
*, int, int));
265 static int skip_openp
PARAMS ((int, sb
*));
266 static int skip_closep
PARAMS ((int, sb
*));
267 static int dolen
PARAMS ((int, sb
*, sb
*));
268 static int doinstr
PARAMS ((int, sb
*, sb
*));
269 static int dosubstr
PARAMS ((int, sb
*, sb
*));
270 static void process_assigns
PARAMS ((int, sb
*, sb
*));
271 static int get_and_process
PARAMS ((int, sb
*, sb
*));
272 static void process_file
PARAMS ((void));
273 static void free_old_entry
PARAMS ((hash_entry
*));
274 static void do_assigna
PARAMS ((int, sb
*));
275 static void do_assignc
PARAMS ((int, sb
*));
276 static void do_reg
PARAMS ((int, sb
*));
277 static int condass_lookup_name
PARAMS ((sb
*, int, sb
*, int));
278 static int whatcond
PARAMS ((int, sb
*, int *));
279 static int istrue
PARAMS ((int, sb
*));
280 static void do_aif
PARAMS ((int, sb
*));
281 static void do_aelse
PARAMS ((void));
282 static void do_aendi
PARAMS ((void));
283 static int condass_on
PARAMS ((void));
284 static void do_if
PARAMS ((int, sb
*, int));
285 static int get_mri_string
PARAMS ((int, sb
*, sb
*, int));
286 static void do_ifc
PARAMS ((int, sb
*, int));
287 static void do_aendr
PARAMS ((void));
288 static void do_awhile
PARAMS ((int, sb
*));
289 static void do_aendw
PARAMS ((void));
290 static void do_exitm
PARAMS ((void));
291 static void do_arepeat
PARAMS ((int, sb
*));
292 static void do_endm
PARAMS ((void));
293 static void do_irp
PARAMS ((int, sb
*, int));
294 static void do_local
PARAMS ((int, sb
*));
295 static void do_macro
PARAMS ((int, sb
*));
296 static int macro_op
PARAMS ((int, sb
*));
297 static int getstring
PARAMS ((int, sb
*, sb
*));
298 static void do_sdata
PARAMS ((int, sb
*, int));
299 static void do_sdatab
PARAMS ((int, sb
*));
300 static int new_file
PARAMS ((const char *));
301 static void do_include
PARAMS ((int, sb
*));
302 static void include_pop
PARAMS ((void));
303 static int get
PARAMS ((void));
304 static int linecount
PARAMS ((void));
305 static int include_next_index
PARAMS ((void));
306 static void chartype_init
PARAMS ((void));
307 static int process_pseudo_op
PARAMS ((int, sb
*, sb
*));
308 static void add_keyword
PARAMS ((const char *, int));
309 static void process_init
PARAMS ((void));
310 static void do_define
PARAMS ((const char *));
311 static void show_usage
PARAMS ((FILE *, int));
312 static void show_help
PARAMS ((void));
317 include_print_where_line (stderr); \
327 include_print_where_line (stderr); \
336 include_print_where_line (stderr); \
342 /* Exit the program and return the right ERROR code. */
356 for (i
= 0; i
< sb_max_power_two
; i
++)
358 fprintf (stderr
, "strings size %8d : %d\n",
359 1 << i
, string_count
[i
]);
365 /* Hash table maintenance. */
367 /* Build a new hash table with size buckets
368 and fill in the info at ptr. */
371 hash_new_table (size
, ptr
)
377 ptr
->table
= (hash_entry
**) xmalloc (size
* (sizeof (hash_entry
*)));
378 /* Fill with null-pointer, not zero-bit-pattern. */
379 for (i
= 0; i
< size
; i
++)
383 /* Calculate and return the hash value of the sb at key. */
392 for (i
= 0; i
< key
->len
; i
++)
400 /* Look up key in hash_table tab. If present, then return it,
401 otherwise build a new one and fill it with hash_integer. */
404 hash_create (tab
, key
)
408 int k
= hash (key
) % tab
->size
;
410 hash_entry
**table
= tab
->table
;
418 hash_entry
*n
= (hash_entry
*) xmalloc (sizeof (hash_entry
));
421 sb_add_sb (&n
->key
, key
);
423 n
->type
= hash_integer
;
426 if (strncmp (table
[k
]->key
.ptr
, key
->ptr
, key
->len
) == 0)
434 /* Add sb name with key into hash_table tab.
435 If replacing old value and again, then ERROR. */
438 hash_add_to_string_table (tab
, key
, name
, again
)
444 hash_entry
*ptr
= hash_create (tab
, key
);
445 if (ptr
->type
== hash_integer
)
447 sb_new (&ptr
->value
.s
);
449 if (ptr
->value
.s
.len
)
452 ERROR ((stderr
, _("redefinition not allowed\n")));
455 ptr
->type
= hash_string
;
456 sb_reset (&ptr
->value
.s
);
458 sb_add_sb (&ptr
->value
.s
, name
);
461 /* Add integer name to hash_table tab with sb key. */
464 hash_add_to_int_table (tab
, key
, name
)
469 hash_entry
*ptr
= hash_create (tab
, key
);
473 /* Look up sb key in hash_table tab.
474 If found, return hash_entry result, else 0. */
477 hash_lookup (tab
, key
)
481 int k
= hash (key
) % tab
->size
;
482 hash_entry
**table
= tab
->table
;
483 hash_entry
*p
= table
[k
];
486 if (p
->key
.len
== key
->len
487 && strncmp (p
->key
.ptr
, key
->ptr
, key
->len
) == 0)
496 are handled in a really simple recursive decent way. each bit of
497 the machine takes an index into an sb and a pointer to an exp_t,
498 modifies the *exp_t and returns the index of the first character
499 past the part of the expression parsed.
501 expression precedence:
510 /* Make sure that the exp_t at term is constant.
511 If not the give the op ERROR. */
514 checkconst (op
, term
)
518 if (term
->add_symbol
.len
519 || term
->sub_symbol
.len
)
521 ERROR ((stderr
, _("the %c operator cannot take non-absolute arguments.\n"), op
));
525 /* Turn the number in string at idx into a number of base, fill in
526 ptr, and return the index of the first character not in the number. */
529 sb_strtol (idx
, string
, base
, ptr
)
536 idx
= sb_skip_white (idx
, string
);
538 while (idx
< string
->len
)
540 int ch
= string
->ptr
[idx
];
544 else if (ch
>= 'a' && ch
<= 'f')
546 else if (ch
>= 'A' && ch
<= 'F')
554 value
= value
* base
+ dig
;
562 level_0 (idx
, string
, lhs
)
567 lhs
->add_symbol
.len
= 0;
568 lhs
->add_symbol
.name
= 0;
570 lhs
->sub_symbol
.len
= 0;
571 lhs
->sub_symbol
.name
= 0;
573 idx
= sb_skip_white (idx
, string
);
577 if (ISDIGIT (string
->ptr
[idx
]))
579 idx
= sb_strtol (idx
, string
, 10, &lhs
->value
);
581 else if (ISFIRSTCHAR (string
->ptr
[idx
]))
584 lhs
->add_symbol
.name
= string
->ptr
+ idx
;
585 while (idx
< string
->len
&& ISNEXTCHAR (string
->ptr
[idx
]))
590 lhs
->add_symbol
.len
= len
;
592 else if (string
->ptr
[idx
] == '"')
596 ERROR ((stderr
, _("string where expression expected.\n")));
597 idx
= getstring (idx
, string
, &acc
);
602 ERROR ((stderr
, _("can't find primary in expression.\n")));
605 return sb_skip_white (idx
, string
);
609 level_1 (idx
, string
, lhs
)
614 idx
= sb_skip_white (idx
, string
);
616 switch (string
->ptr
[idx
])
619 idx
= level_1 (idx
+ 1, string
, lhs
);
622 idx
= level_1 (idx
+ 1, string
, lhs
);
623 checkconst ('~', lhs
);
624 lhs
->value
= ~lhs
->value
;
629 idx
= level_1 (idx
+ 1, string
, lhs
);
630 lhs
->value
= -lhs
->value
;
632 lhs
->add_symbol
= lhs
->sub_symbol
;
638 idx
= level_5 (sb_skip_white (idx
, string
), string
, lhs
);
639 if (string
->ptr
[idx
] != ')')
640 ERROR ((stderr
, _("misplaced closing parens.\n")));
645 idx
= level_0 (idx
, string
, lhs
);
648 return sb_skip_white (idx
, string
);
652 level_2 (idx
, string
, lhs
)
659 idx
= level_1 (idx
, string
, lhs
);
661 while (idx
< string
->len
&& (string
->ptr
[idx
] == '*'
662 || string
->ptr
[idx
] == '/'))
664 char op
= string
->ptr
[idx
++];
665 idx
= level_1 (idx
, string
, &rhs
);
669 checkconst ('*', lhs
);
670 checkconst ('*', &rhs
);
671 lhs
->value
*= rhs
.value
;
674 checkconst ('/', lhs
);
675 checkconst ('/', &rhs
);
677 ERROR ((stderr
, _("attempt to divide by zero.\n")));
679 lhs
->value
/= rhs
.value
;
683 return sb_skip_white (idx
, string
);
687 level_3 (idx
, string
, lhs
)
694 idx
= level_2 (idx
, string
, lhs
);
696 while (idx
< string
->len
697 && (string
->ptr
[idx
] == '+'
698 || string
->ptr
[idx
] == '-'))
700 char op
= string
->ptr
[idx
++];
701 idx
= level_2 (idx
, string
, &rhs
);
705 lhs
->value
+= rhs
.value
;
706 if (lhs
->add_symbol
.name
&& rhs
.add_symbol
.name
)
708 ERROR ((stderr
, _("can't add two relocatable expressions\n")));
710 /* Change nn+symbol to symbol + nn. */
711 if (rhs
.add_symbol
.name
)
713 lhs
->add_symbol
= rhs
.add_symbol
;
717 lhs
->value
-= rhs
.value
;
718 lhs
->sub_symbol
= rhs
.add_symbol
;
722 return sb_skip_white (idx
, string
);
726 level_4 (idx
, string
, lhs
)
733 idx
= level_3 (idx
, string
, lhs
);
735 while (idx
< string
->len
&&
736 string
->ptr
[idx
] == '&')
738 char op
= string
->ptr
[idx
++];
739 idx
= level_3 (idx
, string
, &rhs
);
743 checkconst ('&', lhs
);
744 checkconst ('&', &rhs
);
745 lhs
->value
&= rhs
.value
;
749 return sb_skip_white (idx
, string
);
753 level_5 (idx
, string
, lhs
)
760 idx
= level_4 (idx
, string
, lhs
);
762 while (idx
< string
->len
763 && (string
->ptr
[idx
] == '|' || string
->ptr
[idx
] == '~'))
765 char op
= string
->ptr
[idx
++];
766 idx
= level_4 (idx
, string
, &rhs
);
770 checkconst ('|', lhs
);
771 checkconst ('|', &rhs
);
772 lhs
->value
|= rhs
.value
;
775 checkconst ('~', lhs
);
776 checkconst ('~', &rhs
);
777 lhs
->value
^= rhs
.value
;
781 return sb_skip_white (idx
, string
);
784 /* Parse the expression at offset idx into string, fill up res with
785 the result. Return the index of the first char past the
789 exp_parse (idx
, string
, res
)
794 return level_5 (sb_skip_white (idx
, string
), string
, res
);
797 /* Turn the expression at exp into text and glue it onto the end of
801 exp_string (exp
, string
)
809 if (exp
->add_symbol
.len
)
811 sb_add_buffer (string
, exp
->add_symbol
.name
, exp
->add_symbol
.len
);
819 sb_add_char (string
, '+');
820 sprintf (buf
, "%d", exp
->value
);
821 sb_add_string (string
, buf
);
825 if (exp
->sub_symbol
.len
)
827 sb_add_char (string
, '-');
828 sb_add_buffer (string
, exp
->add_symbol
.name
, exp
->add_symbol
.len
);
834 sb_add_char (string
, '0');
837 /* Parse the expression at offset idx into sb in. Return the value in
838 val. If the expression is not constant, give ERROR emsg. Return
839 the index of the first character past the end of the expression. */
842 exp_get_abs (emsg
, idx
, in
, val
)
849 idx
= exp_parse (idx
, in
, &res
);
850 if (res
.add_symbol
.len
|| res
.sub_symbol
.len
)
851 ERROR ((stderr
, "%s", emsg
));
856 /* Current label parsed from line. */
859 /* Hash table for all assigned variables. */
860 hash_table assign_hash_table
;
862 /* Hash table for keyword. */
863 hash_table keyword_hash_table
;
865 /* Hash table for eq variables. */
868 #define in_comment ';'
877 for (i
= 0; i
< out
->len
; i
++)
879 if (ISCOMMENTCHAR (s
[i
]))
888 /* Push back character ch so that it can be read again. */
898 if (sp
->pushback_index
)
899 sp
->pushback_index
--;
901 sb_add_char (&sp
->pushback
, ch
);
904 /* Push the sb ptr onto the include stack, with the given name, type
908 include_buf (name
, ptr
, type
, index
)
915 if (sp
- include_stack
>= MAX_INCLUDES
)
916 FATAL ((stderr
, _("unreasonable nesting.\n")));
918 sb_add_sb (&sp
->name
, name
);
921 sp
->pushback_index
= 0;
924 sb_new (&sp
->pushback
);
925 sb_add_sb (&sp
->pushback
, ptr
);
928 /* Used in ERROR messages, print info on where the include stack is
932 include_print_where_line (file
)
935 struct include_stack
*p
= include_stack
+ 1;
939 fprintf (file
, "%s:%d ", sb_name (&p
->name
), p
->linecount
- 1);
944 /* Used in listings, print the line number onto file. */
947 include_print_line (file
)
951 struct include_stack
*p
= include_stack
+ 1;
953 n
= fprintf (file
, "%4d", p
->linecount
);
957 n
+= fprintf (file
, ".%d", p
->linecount
);
967 /* Read a line from the top of the include stack into sb in. */
978 putc (comment_char
, outfile
);
979 if (print_line_number
)
980 include_print_line (outfile
);
994 WARNING ((stderr
, _("End of file not at start of line.\n")));
996 putc ('\n', outfile
);
1015 /* Continued line. */
1018 putc (comment_char
, outfile
);
1019 putc ('+', outfile
);
1032 sb_add_char (in
, ch
);
1040 /* Find a label from sb in and put it in out. */
1043 grab_label (in
, out
)
1049 if (ISFIRSTCHAR (in
->ptr
[i
]) || in
->ptr
[i
] == '\\')
1051 sb_add_char (out
, in
->ptr
[i
]);
1053 while ((ISNEXTCHAR (in
->ptr
[i
])
1054 || in
->ptr
[i
] == '\\'
1055 || in
->ptr
[i
] == '&')
1058 sb_add_char (out
, in
->ptr
[i
]);
1065 /* Find all strange base stuff and turn into decimal. Also
1066 find all the other numbers and convert them from the default radix. */
1069 change_base (idx
, in
, out
)
1076 while (idx
< in
->len
)
1078 if (in
->ptr
[idx
] == '\\'
1079 && idx
+ 1 < in
->len
1080 && in
->ptr
[idx
+ 1] == '(')
1083 while (idx
< in
->len
1084 && in
->ptr
[idx
] != ')')
1086 sb_add_char (out
, in
->ptr
[idx
]);
1092 else if (idx
< in
->len
- 1 && in
->ptr
[idx
+ 1] == '\'' && ! mri
)
1096 switch (in
->ptr
[idx
])
1115 ERROR ((stderr
, _("Illegal base character %c.\n"), in
->ptr
[idx
]));
1120 idx
= sb_strtol (idx
+ 2, in
, base
, &value
);
1121 sprintf (buffer
, "%d", value
);
1122 sb_add_string (out
, buffer
);
1124 else if (ISFIRSTCHAR (in
->ptr
[idx
]))
1126 /* Copy entire names through quickly. */
1127 sb_add_char (out
, in
->ptr
[idx
]);
1129 while (idx
< in
->len
&& ISNEXTCHAR (in
->ptr
[idx
]))
1131 sb_add_char (out
, in
->ptr
[idx
]);
1135 else if (ISDIGIT (in
->ptr
[idx
]))
1138 /* All numbers must start with a digit, let's chew it and
1139 spit out decimal. */
1140 idx
= sb_strtol (idx
, in
, radix
, &value
);
1141 sprintf (buffer
, "%d", value
);
1142 sb_add_string (out
, buffer
);
1144 /* Skip all undigsested letters. */
1145 while (idx
< in
->len
&& ISNEXTCHAR (in
->ptr
[idx
]))
1147 sb_add_char (out
, in
->ptr
[idx
]);
1151 else if (in
->ptr
[idx
] == '"' || in
->ptr
[idx
] == '\'')
1153 char tchar
= in
->ptr
[idx
];
1154 /* Copy entire names through quickly. */
1155 sb_add_char (out
, in
->ptr
[idx
]);
1157 while (idx
< in
->len
&& in
->ptr
[idx
] != tchar
)
1159 sb_add_char (out
, in
->ptr
[idx
]);
1165 /* Nothing special, just pass it through. */
1166 sb_add_char (out
, in
->ptr
[idx
]);
1181 fprintf (outfile
, "%s\n", sb_name (in
));
1187 do_assign (again
, idx
, in
)
1192 /* Stick label in symbol table with following value. */
1197 idx
= exp_parse (idx
, in
, &e
);
1198 exp_string (&e
, &acc
);
1199 hash_add_to_string_table (&assign_hash_table
, &label
, &acc
, again
);
1203 /* .radix [b|q|d|h] */
1209 int idx
= sb_skip_white (0, ptr
);
1210 switch (ptr
->ptr
[idx
])
1229 ERROR ((stderr
, _("radix is %c must be one of b, q, d or h"), radix
));
1233 /* Parse off a .b, .w or .l. */
1236 get_opsize (idx
, in
, size
)
1242 if (in
->ptr
[idx
] == '.')
1246 switch (in
->ptr
[idx
])
1264 ERROR ((stderr
, _("size must be one of b, w or l, is %c.\n"), in
->ptr
[idx
]));
1277 idx
= sb_skip_white (idx
, line
);
1279 && ISCOMMENTCHAR(line
->ptr
[idx
]))
1281 if (idx
>= line
->len
)
1286 /* .data [.b|.w|.l] <data>*
1287 or d[bwl] <data>* */
1290 do_data (idx
, in
, size
)
1296 char *opname
= ".yikes!";
1302 idx
= get_opsize (idx
, in
, &opsize
);
1321 fprintf (outfile
, "%s\t", opname
);
1323 idx
= sb_skip_white (idx
, in
);
1327 && in
->ptr
[idx
] == '"')
1330 idx
= getstring (idx
, in
, &acc
);
1331 for (i
= 0; i
< acc
.len
; i
++)
1334 fprintf (outfile
, ",");
1335 fprintf (outfile
, "%d", acc
.ptr
[i
]);
1340 while (!eol (idx
, in
))
1343 idx
= exp_parse (idx
, in
, &e
);
1344 exp_string (&e
, &acc
);
1345 sb_add_char (&acc
, 0);
1346 fprintf (outfile
, "%s", acc
.ptr
);
1347 if (idx
< in
->len
&& in
->ptr
[idx
] == ',')
1349 fprintf (outfile
, ",");
1355 sb_print_at (outfile
, idx
, in
);
1356 fprintf (outfile
, "\n");
1359 /* .datab [.b|.w|.l] <repeat>,<fill> */
1370 idx
= get_opsize (idx
, in
, &opsize
);
1372 idx
= exp_get_abs (_("datab repeat must be constant.\n"), idx
, in
, &repeat
);
1373 idx
= sb_skip_comma (idx
, in
);
1374 idx
= exp_get_abs (_("datab data must be absolute.\n"), idx
, in
, &fill
);
1376 fprintf (outfile
, ".fill\t%d,%d,%d\n", repeat
, opsize
, fill
);
1386 int al
, have_fill
, fill
;
1388 idx
= exp_get_abs (_("align needs absolute expression.\n"), idx
, in
, &al
);
1389 idx
= sb_skip_white (idx
, in
);
1392 if (! eol (idx
, in
))
1394 idx
= sb_skip_comma (idx
, in
);
1395 idx
= exp_get_abs (_(".align needs absolute fill value.\n"), idx
, in
,
1400 fprintf (outfile
, ".align %d", al
);
1402 fprintf (outfile
, ",%d", fill
);
1403 fprintf (outfile
, "\n");
1406 /* .res[.b|.w|.l] <size> */
1409 do_res (idx
, in
, type
)
1417 idx
= get_opsize (idx
, in
, &size
);
1418 while (!eol (idx
, in
))
1420 idx
= sb_skip_white (idx
, in
);
1421 if (in
->ptr
[idx
] == ',')
1423 idx
= exp_get_abs (_("res needs absolute expression for fill count.\n"), idx
, in
, &count
);
1425 if (type
== 'c' || type
== 'z')
1428 fprintf (outfile
, ".space %d\n", count
* size
);
1438 fprintf (outfile
, ".global %s\n", sb_name (in
));
1441 /* .print [list] [nolist] */
1448 idx
= sb_skip_white (idx
, in
);
1449 while (idx
< in
->len
)
1451 if (strncasecmp (in
->ptr
+ idx
, "LIST", 4) == 0)
1453 fprintf (outfile
, ".list\n");
1456 else if (strncasecmp (in
->ptr
+ idx
, "NOLIST", 6) == 0)
1458 fprintf (outfile
, ".nolist\n");
1468 do_heading (idx
, in
)
1474 idx
= getstring (idx
, in
, &head
);
1475 fprintf (outfile
, ".title \"%s\"\n", sb_name (&head
));
1484 fprintf (outfile
, ".eject\n");
1487 /* .form [lin=<value>] [col=<value>] */
1496 idx
= sb_skip_white (idx
, in
);
1498 while (idx
< in
->len
)
1501 if (strncasecmp (in
->ptr
+ idx
, "LIN=", 4) == 0)
1504 idx
= exp_get_abs (_("form LIN= needs absolute expresssion.\n"), idx
, in
, &lines
);
1507 if (strncasecmp (in
->ptr
+ idx
, _("COL="), 4) == 0)
1510 idx
= exp_get_abs (_("form COL= needs absolute expresssion.\n"), idx
, in
, &columns
);
1515 fprintf (outfile
, ".psize %d,%d\n", lines
, columns
);
1519 /* Fetch string from the input stream,
1521 'Bxyx<whitespace> -> return 'Bxyza
1522 %<char> -> return string of decimal value of x
1523 "<string>" -> return string
1524 xyx<whitespace> -> return xyz
1528 get_any_string (idx
, in
, out
, expand
, pretend_quoted
)
1536 idx
= sb_skip_white (idx
, in
);
1540 if (in
->len
> 2 && in
->ptr
[idx
+ 1] == '\'' && ISBASE (in
->ptr
[idx
]))
1542 while (!ISSEP (in
->ptr
[idx
]))
1543 sb_add_char (out
, in
->ptr
[idx
++]);
1545 else if (in
->ptr
[idx
] == '%'
1551 /* Turns the next expression into a string. */
1552 /* xgettext: no-c-format */
1553 idx
= exp_get_abs (_("% operator needs absolute expression"),
1557 sprintf (buf
, "%d", val
);
1558 sb_add_string (out
, buf
);
1560 else if (in
->ptr
[idx
] == '"'
1561 || in
->ptr
[idx
] == '<'
1562 || (alternate
&& in
->ptr
[idx
] == '\''))
1564 if (alternate
&& expand
)
1566 /* Keep the quotes. */
1567 sb_add_char (out
, '\"');
1569 idx
= getstring (idx
, in
, out
);
1570 sb_add_char (out
, '\"');
1575 idx
= getstring (idx
, in
, out
);
1580 while (idx
< in
->len
1581 && (in
->ptr
[idx
] == '"'
1582 || in
->ptr
[idx
] == '\''
1584 || !ISSEP (in
->ptr
[idx
])))
1586 if (in
->ptr
[idx
] == '"'
1587 || in
->ptr
[idx
] == '\'')
1589 char tchar
= in
->ptr
[idx
];
1590 sb_add_char (out
, in
->ptr
[idx
++]);
1591 while (idx
< in
->len
1592 && in
->ptr
[idx
] != tchar
)
1593 sb_add_char (out
, in
->ptr
[idx
++]);
1597 sb_add_char (out
, in
->ptr
[idx
++]);
1605 /* Skip along sb in starting at idx, suck off whitespace a ( and more
1606 whitespace. Return the idx of the next char. */
1609 skip_openp (idx
, in
)
1613 idx
= sb_skip_white (idx
, in
);
1614 if (in
->ptr
[idx
] != '(')
1615 ERROR ((stderr
, _("misplaced ( .\n")));
1616 idx
= sb_skip_white (idx
+ 1, in
);
1620 /* Skip along sb in starting at idx, suck off whitespace a ) and more
1621 whitespace. Return the idx of the next char. */
1624 skip_closep (idx
, in
)
1628 idx
= sb_skip_white (idx
, in
);
1629 if (in
->ptr
[idx
] != ')')
1630 ERROR ((stderr
, _("misplaced ).\n")));
1631 idx
= sb_skip_white (idx
+ 1, in
);
1638 dolen (idx
, in
, out
)
1647 sb_new (&stringout
);
1648 idx
= skip_openp (idx
, in
);
1649 idx
= get_and_process (idx
, in
, &stringout
);
1650 idx
= skip_closep (idx
, in
);
1651 sprintf (buffer
, "%d", stringout
.len
);
1652 sb_add_string (out
, buffer
);
1654 sb_kill (&stringout
);
1661 doinstr (idx
, in
, out
)
1675 idx
= skip_openp (idx
, in
);
1676 idx
= get_and_process (idx
, in
, &string
);
1677 idx
= sb_skip_comma (idx
, in
);
1678 idx
= get_and_process (idx
, in
, &search
);
1679 idx
= sb_skip_comma (idx
, in
);
1680 if (ISDIGIT (in
->ptr
[idx
]))
1682 idx
= exp_get_abs (_(".instr needs absolute expresson.\n"), idx
, in
, &start
);
1688 idx
= skip_closep (idx
, in
);
1690 for (i
= start
; i
< string
.len
; i
++)
1692 if (strncmp (string
.ptr
+ i
, search
.ptr
, search
.len
) == 0)
1698 sprintf (buffer
, "%d", res
);
1699 sb_add_string (out
, buffer
);
1706 dosubstr (idx
, in
, out
)
1716 idx
= skip_openp (idx
, in
);
1717 idx
= get_and_process (idx
, in
, &string
);
1718 idx
= sb_skip_comma (idx
, in
);
1719 idx
= exp_get_abs (_("need absolute position.\n"), idx
, in
, &pos
);
1720 idx
= sb_skip_comma (idx
, in
);
1721 idx
= exp_get_abs (_("need absolute length.\n"), idx
, in
, &len
);
1722 idx
= skip_closep (idx
, in
);
1724 if (len
< 0 || pos
< 0 ||
1726 || pos
+ len
> string
.len
)
1728 sb_add_string (out
, " ");
1732 sb_add_char (out
, '"');
1735 sb_add_char (out
, string
.ptr
[pos
++]);
1738 sb_add_char (out
, '"');
1744 /* Scan line, change tokens in the hash table to their replacements. */
1747 process_assigns (idx
, in
, buf
)
1752 while (idx
< in
->len
)
1755 if (in
->ptr
[idx
] == '\\'
1756 && idx
+ 1 < in
->len
1757 && in
->ptr
[idx
+ 1] == '(')
1761 sb_add_char (buf
, in
->ptr
[idx
]);
1764 while (idx
< in
->len
&& in
->ptr
[idx
- 1] != ')');
1766 else if (in
->ptr
[idx
] == '\\'
1767 && idx
+ 1 < in
->len
1768 && in
->ptr
[idx
+ 1] == '&')
1770 idx
= condass_lookup_name (in
, idx
+ 2, buf
, 1);
1772 else if (in
->ptr
[idx
] == '\\'
1773 && idx
+ 1 < in
->len
1774 && in
->ptr
[idx
+ 1] == '$')
1776 idx
= condass_lookup_name (in
, idx
+ 2, buf
, 0);
1778 else if (idx
+ 3 < in
->len
1779 && in
->ptr
[idx
] == '.'
1780 && TOUPPER (in
->ptr
[idx
+ 1]) == 'L'
1781 && TOUPPER (in
->ptr
[idx
+ 2]) == 'E'
1782 && TOUPPER (in
->ptr
[idx
+ 3]) == 'N')
1783 idx
= dolen (idx
+ 4, in
, buf
);
1784 else if (idx
+ 6 < in
->len
1785 && in
->ptr
[idx
] == '.'
1786 && TOUPPER (in
->ptr
[idx
+ 1]) == 'I'
1787 && TOUPPER (in
->ptr
[idx
+ 2]) == 'N'
1788 && TOUPPER (in
->ptr
[idx
+ 3]) == 'S'
1789 && TOUPPER (in
->ptr
[idx
+ 4]) == 'T'
1790 && TOUPPER (in
->ptr
[idx
+ 5]) == 'R')
1791 idx
= doinstr (idx
+ 6, in
, buf
);
1792 else if (idx
+ 7 < in
->len
1793 && in
->ptr
[idx
] == '.'
1794 && TOUPPER (in
->ptr
[idx
+ 1]) == 'S'
1795 && TOUPPER (in
->ptr
[idx
+ 2]) == 'U'
1796 && TOUPPER (in
->ptr
[idx
+ 3]) == 'B'
1797 && TOUPPER (in
->ptr
[idx
+ 4]) == 'S'
1798 && TOUPPER (in
->ptr
[idx
+ 5]) == 'T'
1799 && TOUPPER (in
->ptr
[idx
+ 6]) == 'R')
1800 idx
= dosubstr (idx
+ 7, in
, buf
);
1801 else if (ISFIRSTCHAR (in
->ptr
[idx
]))
1803 /* May be a simple name subsitution, see if we have a word. */
1806 while (cur
< in
->len
1807 && (ISNEXTCHAR (in
->ptr
[cur
])))
1811 sb_add_buffer (&acc
, in
->ptr
+ idx
, cur
- idx
);
1812 ptr
= hash_lookup (&assign_hash_table
, &acc
);
1815 /* Found a definition for it. */
1816 sb_add_sb (buf
, &ptr
->value
.s
);
1820 /* No definition, just copy the word. */
1821 sb_add_sb (buf
, &acc
);
1828 sb_add_char (buf
, in
->ptr
[idx
++]);
1834 get_and_process (idx
, in
, out
)
1841 idx
= get_any_string (idx
, in
, &t
, 1, 0);
1842 process_assigns (0, &t
, out
);
1862 more
= get_line (&line
);
1865 /* Find any label and pseudo op that we're intested in. */
1870 fprintf (outfile
, "\n");
1873 && (line
.ptr
[0] == '*'
1874 || line
.ptr
[0] == '!'))
1876 /* MRI line comment. */
1877 fprintf (outfile
, "%s", sb_name (&line
));
1881 l
= grab_label (&line
, &label_in
);
1884 if (line
.ptr
[l
] == ':')
1886 while (ISWHITE (line
.ptr
[l
]) && l
< line
.len
)
1893 /* Munge the label, unless this is EQU or ASSIGN. */
1896 && (line
.ptr
[l
] == '.' || alternate
|| mri
))
1900 if (line
.ptr
[lx
] == '.')
1902 if (lx
+ 3 <= line
.len
1903 && strncasecmp ("EQU", line
.ptr
+ lx
, 3) == 0
1904 && (lx
+ 3 == line
.len
1905 || ! ISFIRSTCHAR (line
.ptr
[lx
+ 3])))
1907 else if (lx
+ 6 <= line
.len
1908 && strncasecmp ("ASSIGN", line
.ptr
+ lx
, 6) == 0
1909 && (lx
+ 6 == line
.len
1910 || ! ISFIRSTCHAR (line
.ptr
[lx
+ 6])))
1915 process_assigns (0, &label_in
, &label
);
1917 sb_add_sb (&label
, &label_in
);
1922 if (process_pseudo_op (l
, &line
, &acc
))
1926 else if (condass_on ())
1928 if (macro_op (l
, &line
))
1937 fprintf (outfile
, "%s:\t", sb_name (&label
));
1940 fprintf (outfile
, "\t");
1942 process_assigns (l
, &line
, &t1
);
1944 change_base (0, &t1
, &t2
);
1945 fprintf (outfile
, "%s\n", sb_name (&t2
));
1952 /* Only a label on this line. */
1953 if (label
.len
&& condass_on ())
1955 fprintf (outfile
, "%s:\n", sb_name (&label
));
1963 more
= get_line (&line
);
1966 if (!had_end
&& !mri
)
1967 WARNING ((stderr
, _("END missing from end of file.\n")));
1971 free_old_entry (ptr
)
1976 if (ptr
->type
== hash_string
)
1977 sb_kill (&ptr
->value
.s
);
1981 /* name: .ASSIGNA <value> */
1984 do_assigna (idx
, in
)
1992 process_assigns (idx
, in
, &tmp
);
1993 idx
= exp_get_abs (_(".ASSIGNA needs constant expression argument.\n"), 0, &tmp
, &val
);
1997 ERROR ((stderr
, _(".ASSIGNA without label.\n")));
2001 hash_entry
*ptr
= hash_create (&vars
, &label
);
2002 free_old_entry (ptr
);
2003 ptr
->type
= hash_integer
;
2009 /* name: .ASSIGNC <string> */
2012 do_assignc (idx
, in
)
2018 idx
= getstring (idx
, in
, &acc
);
2022 ERROR ((stderr
, _(".ASSIGNS without label.\n")));
2026 hash_entry
*ptr
= hash_create (&vars
, &label
);
2027 free_old_entry (ptr
);
2028 ptr
->type
= hash_string
;
2029 sb_new (&ptr
->value
.s
);
2030 sb_add_sb (&ptr
->value
.s
, &acc
);
2035 /* name: .REG (reg) */
2042 /* Remove reg stuff from inside parens. */
2045 idx
= skip_openp (idx
, in
);
2047 idx
= sb_skip_white (idx
, in
);
2049 while (idx
< in
->len
2052 : in
->ptr
[idx
] != ')'))
2054 sb_add_char (&what
, in
->ptr
[idx
]);
2057 hash_add_to_string_table (&assign_hash_table
, &label
, &what
, 1);
2062 condass_lookup_name (inbuf
, idx
, out
, warn
)
2070 sb_new (&condass_acc
);
2072 while (idx
< inbuf
->len
2073 && ISNEXTCHAR (inbuf
->ptr
[idx
]))
2075 sb_add_char (&condass_acc
, inbuf
->ptr
[idx
++]);
2078 if (inbuf
->ptr
[idx
] == '\'')
2080 ptr
= hash_lookup (&vars
, &condass_acc
);
2086 WARNING ((stderr
, _("Can't find preprocessor variable %s.\n"), sb_name (&condass_acc
)));
2090 sb_add_string (out
, "0");
2095 if (ptr
->type
== hash_integer
)
2098 sprintf (buffer
, "%d", ptr
->value
.i
);
2099 sb_add_string (out
, buffer
);
2103 sb_add_sb (out
, &ptr
->value
.s
);
2106 sb_kill (&condass_acc
);
2119 whatcond (idx
, in
, val
)
2126 idx
= sb_skip_white (idx
, in
);
2128 if (idx
+ 1 < in
->len
)
2136 if (a
== 'E' && b
== 'Q')
2138 else if (a
== 'N' && b
== 'E')
2140 else if (a
== 'L' && b
== 'T')
2142 else if (a
== 'L' && b
== 'E')
2144 else if (a
== 'G' && b
== 'T')
2146 else if (a
== 'G' && b
== 'E')
2151 ERROR ((stderr
, _("Comparison operator must be one of EQ, NE, LT, LE, GT or GE.\n")));
2154 idx
= sb_skip_white (idx
+ 2, in
);
2171 idx
= sb_skip_white (idx
, in
);
2173 if (in
->ptr
[idx
] == '"')
2177 /* This is a string comparision. */
2178 idx
= getstring (idx
, in
, &acc_a
);
2179 idx
= whatcond (idx
, in
, &cond
);
2180 idx
= getstring (idx
, in
, &acc_b
);
2181 same
= acc_a
.len
== acc_b
.len
2182 && (strncmp (acc_a
.ptr
, acc_b
.ptr
, acc_a
.len
) == 0);
2184 if (cond
!= EQ
&& cond
!= NE
)
2186 ERROR ((stderr
, _("Comparison operator for strings must be EQ or NE\n")));
2190 res
= (cond
!= EQ
) ^ same
;
2193 /* This is a numeric expression. */
2198 idx
= exp_get_abs (_("Conditional operator must have absolute operands.\n"), idx
, in
, &vala
);
2199 idx
= whatcond (idx
, in
, &cond
);
2200 idx
= sb_skip_white (idx
, in
);
2201 if (in
->ptr
[idx
] == '"')
2203 WARNING ((stderr
, _("String compared against expression.\n")));
2208 idx
= exp_get_abs (_("Conditional operator must have absolute operands.\n"), idx
, in
, &valb
);
2252 if (ifi
>= IFNESTING
)
2254 FATAL ((stderr
, _("AIF nesting unreasonable.\n")));
2257 ifstack
[ifi
].on
= ifstack
[ifi
- 1].on
? istrue (idx
, in
) : 0;
2258 ifstack
[ifi
].hadelse
= 0;
2266 ifstack
[ifi
].on
= ifstack
[ifi
- 1].on
? !ifstack
[ifi
].on
: 0;
2267 if (ifstack
[ifi
].hadelse
)
2269 ERROR ((stderr
, _("Multiple AELSEs in AIF.\n")));
2271 ifstack
[ifi
].hadelse
= 1;
2285 ERROR ((stderr
, _("AENDI without AIF.\n")));
2292 return ifstack
[ifi
].on
;
2295 /* MRI IFEQ, IFNE, IFLT, IFLE, IFGE, IFGT. */
2298 do_if (idx
, in
, cond
)
2306 if (ifi
>= IFNESTING
)
2308 FATAL ((stderr
, _("IF nesting unreasonable.\n")));
2311 idx
= exp_get_abs (_("Conditional operator must have absolute operands.\n"),
2316 case EQ
: res
= val
== 0; break;
2317 case NE
: res
= val
!= 0; break;
2318 case LT
: res
= val
< 0; break;
2319 case LE
: res
= val
<= 0; break;
2320 case GE
: res
= val
>= 0; break;
2321 case GT
: res
= val
> 0; break;
2325 ifstack
[ifi
].on
= ifstack
[ifi
- 1].on
? res
: 0;
2326 ifstack
[ifi
].hadelse
= 0;
2329 /* Get a string for the MRI IFC or IFNC pseudo-ops. */
2332 get_mri_string (idx
, in
, val
, terminator
)
2338 idx
= sb_skip_white (idx
, in
);
2341 && in
->ptr
[idx
] == '\'')
2343 sb_add_char (val
, '\'');
2344 for (++idx
; idx
< in
->len
; ++idx
)
2346 sb_add_char (val
, in
->ptr
[idx
]);
2347 if (in
->ptr
[idx
] == '\'')
2351 || in
->ptr
[idx
] != '\'')
2355 idx
= sb_skip_white (idx
, in
);
2361 while (idx
< in
->len
2362 && in
->ptr
[idx
] != terminator
)
2364 sb_add_char (val
, in
->ptr
[idx
]);
2368 while (i
>= 0 && ISWHITE (val
->ptr
[i
]))
2379 do_ifc (idx
, in
, ifnc
)
2388 if (ifi
>= IFNESTING
)
2390 FATAL ((stderr
, _("IF nesting unreasonable.\n")));
2396 idx
= get_mri_string (idx
, in
, &first
, ',');
2398 if (idx
>= in
->len
|| in
->ptr
[idx
] != ',')
2400 ERROR ((stderr
, _("Bad format for IF or IFNC.\n")));
2404 idx
= get_mri_string (idx
+ 1, in
, &second
, ';');
2406 res
= (first
.len
== second
.len
2407 && strncmp (first
.ptr
, second
.ptr
, first
.len
) == 0);
2411 ifstack
[ifi
].on
= ifstack
[ifi
- 1].on
? res
: 0;
2412 ifstack
[ifi
].hadelse
= 0;
2421 ERROR ((stderr
, _("AENDR without a AREPEAT.\n")));
2423 ERROR ((stderr
, _("ENDR without a REPT.\n")));
2433 int line
= linecount ();
2441 process_assigns (idx
, in
, &exp
);
2442 doit
= istrue (0, &exp
);
2444 if (! buffer_and_nest ("AWHILE", "AENDW", &sub
, get_line
))
2445 FATAL ((stderr
, _("AWHILE without a AENDW at %d.\n"), line
- 1));
2460 int index
= include_next_index ();
2464 sb_add_sb (©
, &sub
);
2465 sb_add_sb (©
, in
);
2466 sb_add_string (©
, "\n");
2467 sb_add_sb (©
, &sub
);
2468 sb_add_string (©
, "\t.AENDW\n");
2469 /* Push another WHILE. */
2470 include_buf (&exp
, ©
, include_while
, index
);
2482 ERROR ((stderr
, _("AENDW without a AENDW.\n")));
2487 Pop things off the include stack until the type and index changes. */
2492 include_type type
= sp
->type
;
2493 if (type
== include_repeat
2494 || type
== include_while
2495 || type
== include_macro
)
2497 int index
= sp
->index
;
2499 while (sp
->index
== index
2500 && sp
->type
== type
)
2510 do_arepeat (idx
, in
)
2514 int line
= linecount ();
2515 sb exp
; /* Buffer with expression in it. */
2516 sb copy
; /* Expanded repeat block. */
2517 sb sub
; /* Contents of AREPEAT. */
2525 process_assigns (idx
, in
, &exp
);
2526 idx
= exp_get_abs (_("AREPEAT must have absolute operand.\n"), 0, &exp
, &rc
);
2528 ret
= buffer_and_nest ("AREPEAT", "AENDR", &sub
, get_line
);
2530 ret
= buffer_and_nest ("REPT", "ENDR", &sub
, get_line
);
2532 FATAL ((stderr
, _("AREPEAT without a AENDR at %d.\n"), line
- 1));
2535 /* Push back the text following the repeat, and another repeat block
2546 int index
= include_next_index ();
2547 sb_add_sb (©
, &sub
);
2551 sprintf (buffer
, "\t.AREPEAT %d\n", rc
- 1);
2553 sprintf (buffer
, "\tREPT %d\n", rc
- 1);
2554 sb_add_string (©
, buffer
);
2555 sb_add_sb (©
, &sub
);
2557 sb_add_string (©
, " .AENDR\n");
2559 sb_add_string (©
, " ENDR\n");
2562 include_buf (&exp
, ©
, include_repeat
, index
);
2574 ERROR ((stderr
, _(".ENDM without a matching .MACRO.\n")));
2577 /* MRI IRP pseudo-op. */
2580 do_irp (idx
, in
, irpc
)
2590 err
= expand_irp (irpc
, idx
, in
, &out
, get_line
, comment_char
);
2592 ERROR ((stderr
, "%s\n", err
));
2594 fprintf (outfile
, "%s", sb_terminate (&out
));
2599 /* Macro processing. */
2601 /* Parse off LOCAL n1, n2,... Invent a label name for it. */
2604 do_local (idx
, line
)
2605 int idx ATTRIBUTE_UNUSED
;
2606 sb
*line ATTRIBUTE_UNUSED
;
2608 ERROR ((stderr
, _("LOCAL outside of MACRO")));
2617 int line
= linecount ();
2619 err
= define_macro (idx
, in
, &label
, get_line
, (const char **) NULL
);
2621 ERROR ((stderr
, _("macro at line %d: %s\n"), line
- 1, err
));
2633 if (! macro_defined
)
2637 if (! check_macro (in
->ptr
+ idx
, &out
, comment_char
, &err
, NULL
))
2641 ERROR ((stderr
, "%s\n", err
));
2644 sb_add_string (&name
, _("macro expansion"));
2646 include_buf (&name
, &out
, include_macro
, include_next_index ());
2654 /* String handling. */
2657 getstring (idx
, in
, acc
)
2662 idx
= sb_skip_white (idx
, in
);
2664 while (idx
< in
->len
2665 && (in
->ptr
[idx
] == '"'
2666 || in
->ptr
[idx
] == '<'
2667 || (in
->ptr
[idx
] == '\'' && alternate
)))
2669 if (in
->ptr
[idx
] == '<')
2671 if (alternate
|| mri
)
2675 while ((in
->ptr
[idx
] != '>' || nest
)
2678 if (in
->ptr
[idx
] == '!')
2681 sb_add_char (acc
, in
->ptr
[idx
++]);
2685 if (in
->ptr
[idx
] == '>')
2687 if (in
->ptr
[idx
] == '<')
2689 sb_add_char (acc
, in
->ptr
[idx
++]);
2698 idx
= exp_get_abs (_("Character code in string must be absolute expression.\n"),
2700 sb_add_char (acc
, code
);
2702 if (in
->ptr
[idx
] != '>')
2703 ERROR ((stderr
, _("Missing > for character code.\n")));
2707 else if (in
->ptr
[idx
] == '"' || in
->ptr
[idx
] == '\'')
2709 char tchar
= in
->ptr
[idx
];
2711 while (idx
< in
->len
)
2713 if (alternate
&& in
->ptr
[idx
] == '!')
2716 sb_add_char (acc
, in
->ptr
[idx
++]);
2720 if (in
->ptr
[idx
] == tchar
)
2723 if (idx
>= in
->len
|| in
->ptr
[idx
] != tchar
)
2726 sb_add_char (acc
, in
->ptr
[idx
]);
2736 /* .SDATA[C|Z] <string> */
2739 do_sdata (idx
, in
, type
)
2748 fprintf (outfile
, ".byte\t");
2750 while (!eol (idx
, in
))
2754 idx
= sb_skip_white (idx
, in
);
2755 while (!eol (idx
, in
))
2757 pidx
= idx
= get_any_string (idx
, in
, &acc
, 0, 1);
2762 ERROR ((stderr
, _("string for SDATAC longer than 255 characters (%d).\n"), acc
.len
));
2764 fprintf (outfile
, "%d", acc
.len
);
2768 for (i
= 0; i
< acc
.len
; i
++)
2772 fprintf (outfile
, ",");
2774 fprintf (outfile
, "%d", acc
.ptr
[i
]);
2781 fprintf (outfile
, ",");
2782 fprintf (outfile
, "0");
2784 idx
= sb_skip_comma (idx
, in
);
2788 if (!alternate
&& in
->ptr
[idx
] != ',' && idx
!= in
->len
)
2790 fprintf (outfile
, "\n");
2791 ERROR ((stderr
, _("illegal character in SDATA line (0x%x).\n"),
2798 fprintf (outfile
, "\n");
2801 /* .SDATAB <count> <string> */
2813 idx
= exp_get_abs (_("Must have absolute SDATAB repeat count.\n"), idx
, in
, &repeat
);
2816 ERROR ((stderr
, _("Must have positive SDATAB repeat count (%d).\n"), repeat
));
2820 idx
= sb_skip_comma (idx
, in
);
2821 idx
= getstring (idx
, in
, &acc
);
2823 for (i
= 0; i
< repeat
; i
++)
2826 fprintf (outfile
, "\t");
2827 fprintf (outfile
, ".byte\t");
2828 sb_print (outfile
, &acc
);
2829 fprintf (outfile
, "\n");
2839 FILE *newone
= fopen (name
, "r");
2843 if (isp
== MAX_INCLUDES
)
2844 FATAL ((stderr
, _("Unreasonable include depth (%ld).\n"), (long) isp
));
2847 sp
->handle
= newone
;
2850 sb_add_string (&sp
->name
, name
);
2853 sp
->pushback_index
= 0;
2854 sp
->type
= include_file
;
2856 sb_new (&sp
->pushback
);
2861 do_include (idx
, in
)
2867 include_path
*includes
;
2873 idx
= getstring (idx
, in
, &t
);
2876 idx
= sb_skip_white (idx
, in
);
2877 while (idx
< in
->len
&& ! ISWHITE (in
->ptr
[idx
]))
2879 sb_add_char (&t
, in
->ptr
[idx
]);
2884 for (includes
= paths_head
; includes
; includes
= includes
->next
)
2887 sb_add_sb (&cat
, &includes
->path
);
2888 sb_add_char (&cat
, '/');
2889 sb_add_sb (&cat
, &t
);
2890 if (new_file (sb_name (&cat
)))
2897 if (! new_file (sb_name (&t
)))
2898 FATAL ((stderr
, _("Can't open include file `%s'.\n"), sb_name (&t
)));
2907 if (sp
!= include_stack
)
2910 fclose (sp
->handle
);
2915 /* Get the next character from the include stack. If there's anything
2916 in the pushback buffer, take that first. If we're at eof, pop from
2917 the stack and try again. Keep the linecount up to date. */
2924 if (sp
->pushback
.len
!= sp
->pushback_index
)
2926 r
= (char) (sp
->pushback
.ptr
[sp
->pushback_index
++]);
2927 /* When they've all gone, reset the pointer. */
2928 if (sp
->pushback_index
== sp
->pushback
.len
)
2930 sp
->pushback
.len
= 0;
2931 sp
->pushback_index
= 0;
2934 else if (sp
->handle
)
2936 r
= getc (sp
->handle
);
2941 if (r
== EOF
&& isp
)
2945 while (r
== EOF
&& isp
)
2963 return sp
->linecount
;
2967 include_next_index ()
2971 && index
> MAX_REASONABLE
)
2972 FATAL ((stderr
, _("Unreasonable expansion (-u turns off check).\n")));
2976 /* Initialize the chartype vector. */
2982 for (x
= 0; x
< 256; x
++)
2984 if (ISALPHA (x
) || x
== '_' || x
== '$')
2985 chartype
[x
] |= FIRSTBIT
;
2987 if (mri
&& x
== '.')
2988 chartype
[x
] |= FIRSTBIT
;
2990 if (ISDIGIT (x
) || ISALPHA (x
) || x
== '_' || x
== '$')
2991 chartype
[x
] |= NEXTBIT
;
2993 if (x
== ' ' || x
== '\t' || x
== ',' || x
== '"' || x
== ';'
2994 || x
== '"' || x
== '<' || x
== '>' || x
== ')' || x
== '(')
2995 chartype
[x
] |= SEPBIT
;
2997 if (x
== 'b' || x
== 'B'
2998 || x
== 'q' || x
== 'Q'
2999 || x
== 'h' || x
== 'H'
3000 || x
== 'd' || x
== 'D')
3001 chartype
[x
] |= BASEBIT
;
3003 if (x
== ' ' || x
== '\t')
3004 chartype
[x
] |= WHITEBIT
;
3006 if (x
== comment_char
)
3007 chartype
[x
] |= COMMENTBIT
;
3011 /* What to do with all the keywords. */
3012 #define PROCESS 0x1000 /* Run substitution over the line. */
3013 #define LAB 0x2000 /* Spit out the label. */
3015 #define K_EQU (PROCESS|1)
3016 #define K_ASSIGN (PROCESS|2)
3017 #define K_REG (PROCESS|3)
3018 #define K_ORG (PROCESS|4)
3019 #define K_RADIX (PROCESS|5)
3020 #define K_DATA (LAB|PROCESS|6)
3021 #define K_DATAB (LAB|PROCESS|7)
3022 #define K_SDATA (LAB|PROCESS|8)
3023 #define K_SDATAB (LAB|PROCESS|9)
3024 #define K_SDATAC (LAB|PROCESS|10)
3025 #define K_SDATAZ (LAB|PROCESS|11)
3026 #define K_RES (LAB|PROCESS|12)
3027 #define K_SRES (LAB|PROCESS|13)
3028 #define K_SRESC (LAB|PROCESS|14)
3029 #define K_SRESZ (LAB|PROCESS|15)
3030 #define K_EXPORT (LAB|PROCESS|16)
3031 #define K_GLOBAL (LAB|PROCESS|17)
3032 #define K_PRINT (LAB|PROCESS|19)
3033 #define K_FORM (LAB|PROCESS|20)
3034 #define K_HEADING (LAB|PROCESS|21)
3035 #define K_PAGE (LAB|PROCESS|22)
3036 #define K_IMPORT (LAB|PROCESS|23)
3037 #define K_PROGRAM (LAB|PROCESS|24)
3038 #define K_END (PROCESS|25)
3039 #define K_INCLUDE (PROCESS|26)
3040 #define K_IGNORED (PROCESS|27)
3041 #define K_ASSIGNA (PROCESS|28)
3042 #define K_ASSIGNC (29)
3043 #define K_AIF (PROCESS|30)
3044 #define K_AELSE (PROCESS|31)
3045 #define K_AENDI (PROCESS|32)
3046 #define K_AREPEAT (PROCESS|33)
3047 #define K_AENDR (PROCESS|34)
3048 #define K_AWHILE (35)
3049 #define K_AENDW (PROCESS|36)
3050 #define K_EXITM (37)
3051 #define K_MACRO (PROCESS|38)
3053 #define K_ALIGN (PROCESS|LAB|40)
3054 #define K_ALTERNATE (41)
3055 #define K_DB (LAB|PROCESS|42)
3056 #define K_DW (LAB|PROCESS|43)
3057 #define K_DL (LAB|PROCESS|44)
3058 #define K_LOCAL (45)
3059 #define K_IFEQ (PROCESS|46)
3060 #define K_IFNE (PROCESS|47)
3061 #define K_IFLT (PROCESS|48)
3062 #define K_IFLE (PROCESS|49)
3063 #define K_IFGE (PROCESS|50)
3064 #define K_IFGT (PROCESS|51)
3065 #define K_IFC (PROCESS|52)
3066 #define K_IFNC (PROCESS|53)
3067 #define K_IRP (PROCESS|54)
3068 #define K_IRPC (PROCESS|55)
3076 static struct keyword kinfo
[] = {
3077 { "EQU", K_EQU
, 0 },
3078 { "ALTERNATE", K_ALTERNATE
, 0 },
3079 { "ASSIGN", K_ASSIGN
, 0 },
3080 { "REG", K_REG
, 0 },
3081 { "ORG", K_ORG
, 0 },
3082 { "RADIX", K_RADIX
, 0 },
3083 { "DATA", K_DATA
, 0 },
3087 { "DATAB", K_DATAB
, 0 },
3088 { "SDATA", K_SDATA
, 0 },
3089 { "SDATAB", K_SDATAB
, 0 },
3090 { "SDATAZ", K_SDATAZ
, 0 },
3091 { "SDATAC", K_SDATAC
, 0 },
3092 { "RES", K_RES
, 0 },
3093 { "SRES", K_SRES
, 0 },
3094 { "SRESC", K_SRESC
, 0 },
3095 { "SRESZ", K_SRESZ
, 0 },
3096 { "EXPORT", K_EXPORT
, 0 },
3097 { "GLOBAL", K_GLOBAL
, 0 },
3098 { "PRINT", K_PRINT
, 0 },
3099 { "FORM", K_FORM
, 0 },
3100 { "HEADING", K_HEADING
, 0 },
3101 { "PAGE", K_PAGE
, 0 },
3102 { "PROGRAM", K_IGNORED
, 0 },
3103 { "END", K_END
, 0 },
3104 { "INCLUDE", K_INCLUDE
, 0 },
3105 { "ASSIGNA", K_ASSIGNA
, 0 },
3106 { "ASSIGNC", K_ASSIGNC
, 0 },
3107 { "AIF", K_AIF
, 0 },
3108 { "AELSE", K_AELSE
, 0 },
3109 { "AENDI", K_AENDI
, 0 },
3110 { "AREPEAT", K_AREPEAT
, 0 },
3111 { "AENDR", K_AENDR
, 0 },
3112 { "EXITM", K_EXITM
, 0 },
3113 { "MACRO", K_MACRO
, 0 },
3114 { "ENDM", K_ENDM
, 0 },
3115 { "AWHILE", K_AWHILE
, 0 },
3116 { "ALIGN", K_ALIGN
, 0 },
3117 { "AENDW", K_AENDW
, 0 },
3118 { "ALTERNATE", K_ALTERNATE
, 0 },
3119 { "LOCAL", K_LOCAL
, 0 },
3123 /* Although the conditional operators are handled by gas, we need to
3124 handle them here as well, in case they are used in a recursive
3125 macro to end the recursion. */
3127 static struct keyword mrikinfo
[] = {
3128 { "IFEQ", K_IFEQ
, 0 },
3129 { "IFNE", K_IFNE
, 0 },
3130 { "IFLT", K_IFLT
, 0 },
3131 { "IFLE", K_IFLE
, 0 },
3132 { "IFGE", K_IFGE
, 0 },
3133 { "IFGT", K_IFGT
, 0 },
3134 { "IFC", K_IFC
, 0 },
3135 { "IFNC", K_IFNC
, 0 },
3136 { "ELSEC", K_AELSE
, 0 },
3137 { "ENDC", K_AENDI
, 0 },
3138 { "MEXIT", K_EXITM
, 0 },
3139 { "REPT", K_AREPEAT
, 0 },
3140 { "IRP", K_IRP
, 0 },
3141 { "IRPC", K_IRPC
, 0 },
3142 { "ENDR", K_AENDR
, 0 },
3146 /* Look for a pseudo op on the line. If one's there then call
3150 process_pseudo_op (idx
, line
, acc
)
3157 if (line
->ptr
[idx
] == '.' || alternate
|| mri
)
3159 /* Scan forward and find pseudo name. */
3165 if (line
->ptr
[idx
] == '.')
3167 in
= line
->ptr
+ idx
;
3172 while (idx
< line
->len
&& *e
&& ISFIRSTCHAR (*e
))
3174 sb_add_char (acc
, *e
);
3179 ptr
= hash_lookup (&keyword_hash_table
, acc
);
3184 /* This one causes lots of pain when trying to preprocess
3186 WARNING ((stderr
, _("Unrecognised pseudo op `%s'.\n"),
3191 if (ptr
->value
.i
& LAB
)
3193 /* Output the label. */
3196 fprintf (outfile
, "%s:\t", sb_name (&label
));
3199 fprintf (outfile
, "\t");
3202 if (mri
&& ptr
->value
.i
== K_END
)
3207 sb_add_buffer (&t
, line
->ptr
+ oidx
, idx
- oidx
);
3208 fprintf (outfile
, "\t%s", sb_name (&t
));
3212 if (ptr
->value
.i
& PROCESS
)
3214 /* Polish the rest of the line before handling the pseudo op. */
3216 strip_comments (line
);
3219 process_assigns (idx
, line
, acc
);
3221 change_base (0, acc
, line
);
3226 switch (ptr
->value
.i
)
3242 switch (ptr
->value
.i
)
3246 macro_init (1, mri
, 0, exp_get_abs
);
3255 ERROR ((stderr
, _("ORG command not allowed.\n")));
3261 do_data (idx
, line
, 1);
3264 do_data (idx
, line
, 2);
3267 do_data (idx
, line
, 4);
3270 do_data (idx
, line
, 0);
3273 do_datab (idx
, line
);
3276 do_sdata (idx
, line
, 0);
3279 do_sdatab (idx
, line
);
3282 do_sdata (idx
, line
, 'c');
3285 do_sdata (idx
, line
, 'z');
3288 do_assign (0, 0, line
);
3294 do_arepeat (idx
, line
);
3300 do_awhile (idx
, line
);
3306 do_assign (1, idx
, line
);
3309 do_align (idx
, line
);
3312 do_res (idx
, line
, 0);
3315 do_res (idx
, line
, 's');
3318 do_include (idx
, line
);
3321 do_local (idx
, line
);
3324 do_macro (idx
, line
);
3330 do_res (idx
, line
, 'c');
3333 do_print (idx
, line
);
3336 do_form (idx
, line
);
3339 do_heading (idx
, line
);
3351 do_res (idx
, line
, 'z');
3359 do_assigna (idx
, line
);
3362 do_assignc (idx
, line
);
3371 do_if (idx
, line
, EQ
);
3374 do_if (idx
, line
, NE
);
3377 do_if (idx
, line
, LT
);
3380 do_if (idx
, line
, LE
);
3383 do_if (idx
, line
, GE
);
3386 do_if (idx
, line
, GT
);
3389 do_ifc (idx
, line
, 0);
3392 do_ifc (idx
, line
, 1);
3395 do_irp (idx
, line
, 0);
3398 do_irp (idx
, line
, 1);
3406 /* Add a keyword to the hash table. */
3409 add_keyword (name
, code
)
3417 sb_add_string (&label
, name
);
3419 hash_add_to_int_table (&keyword_hash_table
, &label
, code
);
3422 for (j
= 0; name
[j
]; j
++)
3423 sb_add_char (&label
, name
[j
] - 'A' + 'a');
3424 hash_add_to_int_table (&keyword_hash_table
, &label
, code
);
3429 /* Build the keyword hash table - put each keyword in the table twice,
3430 once upper and once lower case. */
3437 for (i
= 0; kinfo
[i
].name
; i
++)
3438 add_keyword (kinfo
[i
].name
, kinfo
[i
].code
);
3442 for (i
= 0; mrikinfo
[i
].name
; i
++)
3443 add_keyword (mrikinfo
[i
].name
, mrikinfo
[i
].code
);
3465 sb_add_char (&value
, *string
);
3468 exp_get_abs (_("Invalid expression on command line.\n"),
3473 sb_add_char (&label
, *string
);
3478 ptr
= hash_create (&vars
, &label
);
3479 free_old_entry (ptr
);
3480 ptr
->type
= hash_integer
;
3487 /* The list of long options. */
3488 static struct option long_options
[] =
3490 { "alternate", no_argument
, 0, 'a' },
3491 { "include", required_argument
, 0, 'I' },
3492 { "commentchar", required_argument
, 0, 'c' },
3493 { "copysource", no_argument
, 0, 's' },
3494 { "debug", no_argument
, 0, 'd' },
3495 { "help", no_argument
, 0, 'h' },
3496 { "mri", no_argument
, 0, 'M' },
3497 { "output", required_argument
, 0, 'o' },
3498 { "print", no_argument
, 0, 'p' },
3499 { "unreasonable", no_argument
, 0, 'u' },
3500 { "version", no_argument
, 0, 'v' },
3501 { "define", required_argument
, 0, 'd' },
3502 { NULL
, no_argument
, 0, 0 }
3505 /* Show a usage message and exit. */
3507 show_usage (file
, status
)
3513 [-a] [--alternate] enter alternate macro mode\n\
3514 [-c char] [--commentchar char] change the comment character from !\n\
3515 [-d] [--debug] print some debugging info\n\
3516 [-h] [--help] print this message\n\
3517 [-M] [--mri] enter MRI compatibility mode\n\
3518 [-o out] [--output out] set the output file\n\
3519 [-p] [--print] print line numbers\n"), program_name
);
3521 [-s] [--copysource] copy source through as comments \n\
3522 [-u] [--unreasonable] allow unreasonable nesting\n\
3523 [-v] [--version] print the program version\n\
3524 [-Dname=value] create preprocessor variable called name, with value\n\
3525 [-Ipath] add to include path list\n\
3528 printf (_("Report bugs to %s\n"), REPORT_BUGS_TO
);
3532 /* Display a help message and exit. */
3537 printf (_("%s: Gnu Assembler Macro Preprocessor\n"), program_name
);
3538 show_usage (stdout
, 0);
3541 int main
PARAMS ((int, char **));
3555 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
3556 setlocale (LC_MESSAGES
, "");
3558 #if defined (HAVE_SETLOCALE)
3559 setlocale (LC_CTYPE
, "");
3561 bindtextdomain (PACKAGE
, LOCALEDIR
);
3562 textdomain (PACKAGE
);
3564 program_name
= argv
[0];
3565 xmalloc_set_program_name (program_name
);
3567 hash_new_table (101, &keyword_hash_table
);
3568 hash_new_table (101, &assign_hash_table
);
3569 hash_new_table (101, &vars
);
3573 while ((opt
= getopt_long (argc
, argv
, "I:sdhavc:upo:D:M", long_options
,
3587 include_path
*p
= (include_path
*) xmalloc (sizeof (include_path
));
3590 sb_add_string (&p
->path
, optarg
);
3592 paths_tail
->next
= p
;
3599 print_line_number
= 1;
3602 comment_char
= optarg
[0];
3624 /* This output is intended to follow the GNU standards document. */
3625 printf (_("GNU assembler pre-processor %s\n"), program_version
);
3626 printf (_("Copyright 1996 Free Software Foundation, Inc.\n"));
3628 This program is free software; you may redistribute it under the terms of\n\
3629 the GNU General Public License. This program has absolutely no warranty.\n"));
3635 show_usage (stderr
, 1);
3642 macro_init (alternate
, mri
, 0, exp_get_abs
);
3646 outfile
= fopen (out_name
, "w");
3649 fprintf (stderr
, _("%s: Can't open output file `%s'.\n"),
3650 program_name
, out_name
);
3663 /* Process all the input files. */
3665 while (optind
< argc
)
3667 if (new_file (argv
[optind
]))
3673 fprintf (stderr
, _("%s: Can't open input file `%s'.\n"),
3674 program_name
, argv
[optind
]);
3684 /* This function is used because an abort in some of the other files
3685 may be compiled into as_abort because they include as.h. */
3688 as_abort (file
, line
, fn
)
3689 const char *file
, *fn
;
3692 fprintf (stderr
, _("Internal error, aborting at %s line %d"), file
, line
);
3694 fprintf (stderr
, " in %s", fn
);
3695 fprintf (stderr
, _("\nPlease report this bug.\n"));