1 /* gasp.c - Gnu assembler preprocessor main program.
2 Copyright (C) 1994, 95, 96, 97, 98, 99, 2000
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 !
60 #ifdef NEED_MALLOC_DECLARATION
61 extern char *malloc ();
65 #include "libiberty.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
129 int on
; /* Is the level being output. */
130 int hadelse
; /* Has an aelse been seen. */
135 /* The final and intermediate results of expression evaluation are kept in
136 exp_t's. Note that a symbol is not an sb, but a pointer into the input
137 line. It must be coped somewhere safe before the next line is read in. */
148 int value
; /* Constant part. */
149 symbol add_symbol
; /* Name part. */
150 symbol sub_symbol
; /* Name part. */
154 /* Hashing is done in a pretty standard way. A hash_table has a
155 pointer to a vector of pointers to hash_entrys, and the size of the
156 vector. A hash_entry contains a union of all the info we like to
157 store in hash table. If there is a hash collision, hash_entries
158 with the same hash are kept in a chain. */
160 /* What the data in a hash_entry means. */
163 hash_integer
, /* Name->integer mapping. */
164 hash_string
, /* Name->string mapping. */
165 hash_macro
, /* Name is a macro. */
166 hash_formal
/* Name is a formal argument. */
171 sb key
; /* Symbol name. */
172 hash_type type
; /* Symbol meaning. */
177 struct macro_struct
*m
;
178 struct formal_struct
*f
;
180 struct hs
*next
; /* Next hash_entry with same hash key. */
189 /* How we nest files and expand macros etc.
191 We keep a stack of of include_stack structs. Each include file
192 pushes a new level onto the stack. We keep an sb with a pushback
193 too. unget chars are pushed onto the pushback sb, getchars first
194 checks the pushback sb before reading from the input stream.
196 Small things are expanded by adding the text of the item onto the
197 pushback sb. Larger items are grown by pushing a new level and
198 allocating the entire pushback buf for the item. Each time
199 something like a macro is expanded, the stack index is changed. We
200 can then perform an exitm by popping all entries off the stack with
201 the same stack index. If we're being reasonable, we can detect
202 recusive expansion by checking the index is reasonably small. */
206 include_file
, include_repeat
, include_while
, include_macro
211 sb pushback
; /* Current pushback stream. */
212 int pushback_index
; /* Next char to read from stream. */
213 FILE *handle
; /* Open file. */
214 sb name
; /* Name of file. */
215 int linecount
; /* Number of lines read so far. */
217 int index
; /* Index of this layer. */
219 include_stack
[MAX_INCLUDES
];
221 struct include_stack
*sp
;
222 #define isp (sp - include_stack)
224 /* Include file list. */
226 typedef struct include_path
228 struct include_path
*next
;
232 include_path
*paths_head
;
233 include_path
*paths_tail
;
235 static void quit
PARAMS ((void));
236 static void hash_new_table
PARAMS ((int, hash_table
*));
237 static int hash
PARAMS ((sb
*));
238 static hash_entry
*hash_create
PARAMS ((hash_table
*, sb
*));
239 static void hash_add_to_string_table
PARAMS ((hash_table
*, sb
*, sb
*, int));
240 static void hash_add_to_int_table
PARAMS ((hash_table
*, sb
*, int));
241 static hash_entry
*hash_lookup
PARAMS ((hash_table
*, sb
*));
242 static void checkconst
PARAMS ((int, exp_t
*));
243 static int sb_strtol
PARAMS ((int, sb
*, int, int *));
244 static int level_0
PARAMS ((int, sb
*, exp_t
*));
245 static int level_1
PARAMS ((int, sb
*, exp_t
*));
246 static int level_2
PARAMS ((int, sb
*, exp_t
*));
247 static int level_3
PARAMS ((int, sb
*, exp_t
*));
248 static int level_4
PARAMS ((int, sb
*, exp_t
*));
249 static int level_5
PARAMS ((int, sb
*, exp_t
*));
250 static int exp_parse
PARAMS ((int, sb
*, exp_t
*));
251 static void exp_string
PARAMS ((exp_t
*, sb
*));
252 static int exp_get_abs
PARAMS ((const char *, int, sb
*, int *));
254 static void strip_comments
PARAMS ((sb
*));
256 static void unget
PARAMS ((int));
257 static void include_buf
PARAMS ((sb
*, sb
*, include_type
, int));
258 static void include_print_where_line
PARAMS ((FILE *));
259 static void include_print_line
PARAMS ((FILE *));
260 static int get_line
PARAMS ((sb
*));
261 static int grab_label
PARAMS ((sb
*, sb
*));
262 static void change_base
PARAMS ((int, sb
*, sb
*));
263 static void do_end
PARAMS ((sb
*));
264 static void do_assign
PARAMS ((int, int, sb
*));
265 static void do_radix
PARAMS ((sb
*));
266 static int get_opsize
PARAMS ((int, sb
*, int *));
267 static int eol
PARAMS ((int, sb
*));
268 static void do_data
PARAMS ((int, sb
*, int));
269 static void do_datab
PARAMS ((int, sb
*));
270 static void do_align
PARAMS ((int, sb
*));
271 static void do_res
PARAMS ((int, sb
*, int));
272 static void do_export
PARAMS ((sb
*));
273 static void do_print
PARAMS ((int, sb
*));
274 static void do_heading
PARAMS ((int, sb
*));
275 static void do_page
PARAMS ((void));
276 static void do_form
PARAMS ((int, sb
*));
277 static int get_any_string
PARAMS ((int, sb
*, sb
*, int, int));
278 static int skip_openp
PARAMS ((int, sb
*));
279 static int skip_closep
PARAMS ((int, sb
*));
280 static int dolen
PARAMS ((int, sb
*, sb
*));
281 static int doinstr
PARAMS ((int, sb
*, sb
*));
282 static int dosubstr
PARAMS ((int, sb
*, sb
*));
283 static void process_assigns
PARAMS ((int, sb
*, sb
*));
284 static int get_and_process
PARAMS ((int, sb
*, sb
*));
285 static void process_file
PARAMS ((void));
286 static void free_old_entry
PARAMS ((hash_entry
*));
287 static void do_assigna
PARAMS ((int, sb
*));
288 static void do_assignc
PARAMS ((int, sb
*));
289 static void do_reg
PARAMS ((int, sb
*));
290 static int condass_lookup_name
PARAMS ((sb
*, int, sb
*, int));
291 static int whatcond
PARAMS ((int, sb
*, int *));
292 static int istrue
PARAMS ((int, sb
*));
293 static void do_aif
PARAMS ((int, sb
*));
294 static void do_aelse
PARAMS ((void));
295 static void do_aendi
PARAMS ((void));
296 static int condass_on
PARAMS ((void));
297 static void do_if
PARAMS ((int, sb
*, int));
298 static int get_mri_string
PARAMS ((int, sb
*, sb
*, int));
299 static void do_ifc
PARAMS ((int, sb
*, int));
300 static void do_aendr
PARAMS ((void));
301 static void do_awhile
PARAMS ((int, sb
*));
302 static void do_aendw
PARAMS ((void));
303 static void do_exitm
PARAMS ((void));
304 static void do_arepeat
PARAMS ((int, sb
*));
305 static void do_endm
PARAMS ((void));
306 static void do_irp
PARAMS ((int, sb
*, int));
307 static void do_local
PARAMS ((int, sb
*));
308 static void do_macro
PARAMS ((int, sb
*));
309 static int macro_op
PARAMS ((int, sb
*));
310 static int getstring
PARAMS ((int, sb
*, sb
*));
311 static void do_sdata
PARAMS ((int, sb
*, int));
312 static void do_sdatab
PARAMS ((int, sb
*));
313 static int new_file
PARAMS ((const char *));
314 static void do_include
PARAMS ((int, sb
*));
315 static void include_pop
PARAMS ((void));
316 static int get
PARAMS ((void));
317 static int linecount
PARAMS ((void));
318 static int include_next_index
PARAMS ((void));
319 static void chartype_init
PARAMS ((void));
320 static int process_pseudo_op
PARAMS ((int, sb
*, sb
*));
321 static void add_keyword
PARAMS ((const char *, int));
322 static void process_init
PARAMS ((void));
323 static void do_define
PARAMS ((const char *));
324 static void show_usage
PARAMS ((FILE *, int));
325 static void show_help
PARAMS ((void));
330 include_print_where_line (stderr); \
340 include_print_where_line (stderr); \
349 include_print_where_line (stderr); \
355 /* Exit the program and return the right ERROR code. */
369 for (i
= 0; i
< sb_max_power_two
; i
++)
371 fprintf (stderr
, "strings size %8d : %d\n",
372 1 << i
, string_count
[i
]);
378 /* Hash table maintenance. */
380 /* Build a new hash table with size buckets
381 and fill in the info at ptr. */
384 hash_new_table (size
, ptr
)
390 ptr
->table
= (hash_entry
**) xmalloc (size
* (sizeof (hash_entry
*)));
391 /* Fill with null-pointer, not zero-bit-pattern. */
392 for (i
= 0; i
< size
; i
++)
396 /* Calculate and return the hash value of the sb at key. */
405 for (i
= 0; i
< key
->len
; i
++)
413 /* Look up key in hash_table tab. If present, then return it,
414 otherwise build a new one and fill it with hash_integer. */
417 hash_create (tab
, key
)
421 int k
= hash (key
) % tab
->size
;
423 hash_entry
**table
= tab
->table
;
431 hash_entry
*n
= (hash_entry
*) xmalloc (sizeof (hash_entry
));
434 sb_add_sb (&n
->key
, key
);
436 n
->type
= hash_integer
;
439 if (strncmp (table
[k
]->key
.ptr
, key
->ptr
, key
->len
) == 0)
447 /* Add sb name with key into hash_table tab.
448 If replacing old value and again, then ERROR. */
451 hash_add_to_string_table (tab
, key
, name
, again
)
457 hash_entry
*ptr
= hash_create (tab
, key
);
458 if (ptr
->type
== hash_integer
)
460 sb_new (&ptr
->value
.s
);
462 if (ptr
->value
.s
.len
)
465 ERROR ((stderr
, _("redefinition not allowed\n")));
468 ptr
->type
= hash_string
;
469 sb_reset (&ptr
->value
.s
);
471 sb_add_sb (&ptr
->value
.s
, name
);
474 /* Add integer name to hash_table tab with sb key. */
477 hash_add_to_int_table (tab
, key
, name
)
482 hash_entry
*ptr
= hash_create (tab
, key
);
486 /* Look up sb key in hash_table tab.
487 If found, return hash_entry result, else 0. */
490 hash_lookup (tab
, key
)
494 int k
= hash (key
) % tab
->size
;
495 hash_entry
**table
= tab
->table
;
496 hash_entry
*p
= table
[k
];
499 if (p
->key
.len
== key
->len
500 && strncmp (p
->key
.ptr
, key
->ptr
, key
->len
) == 0)
509 are handled in a really simple recursive decent way. each bit of
510 the machine takes an index into an sb and a pointer to an exp_t,
511 modifies the *exp_t and returns the index of the first character
512 past the part of the expression parsed.
514 expression precedence:
523 /* Make sure that the exp_t at term is constant.
524 If not the give the op ERROR. */
527 checkconst (op
, term
)
531 if (term
->add_symbol
.len
532 || term
->sub_symbol
.len
)
534 ERROR ((stderr
, _("the %c operator cannot take non-absolute arguments.\n"), op
));
538 /* Turn the number in string at idx into a number of base, fill in
539 ptr, and return the index of the first character not in the number. */
542 sb_strtol (idx
, string
, base
, ptr
)
549 idx
= sb_skip_white (idx
, string
);
551 while (idx
< string
->len
)
553 int ch
= string
->ptr
[idx
];
557 else if (ch
>= 'a' && ch
<= 'f')
559 else if (ch
>= 'A' && ch
<= 'F')
567 value
= value
* base
+ dig
;
575 level_0 (idx
, string
, lhs
)
580 lhs
->add_symbol
.len
= 0;
581 lhs
->add_symbol
.name
= 0;
583 lhs
->sub_symbol
.len
= 0;
584 lhs
->sub_symbol
.name
= 0;
586 idx
= sb_skip_white (idx
, string
);
590 if (isdigit ((unsigned char) string
->ptr
[idx
]))
592 idx
= sb_strtol (idx
, string
, 10, &lhs
->value
);
594 else if (ISFIRSTCHAR (string
->ptr
[idx
]))
597 lhs
->add_symbol
.name
= string
->ptr
+ idx
;
598 while (idx
< string
->len
&& ISNEXTCHAR (string
->ptr
[idx
]))
603 lhs
->add_symbol
.len
= len
;
605 else if (string
->ptr
[idx
] == '"')
609 ERROR ((stderr
, _("string where expression expected.\n")));
610 idx
= getstring (idx
, string
, &acc
);
615 ERROR ((stderr
, _("can't find primary in expression.\n")));
618 return sb_skip_white (idx
, string
);
622 level_1 (idx
, string
, lhs
)
627 idx
= sb_skip_white (idx
, string
);
629 switch (string
->ptr
[idx
])
632 idx
= level_1 (idx
+ 1, string
, lhs
);
635 idx
= level_1 (idx
+ 1, string
, lhs
);
636 checkconst ('~', lhs
);
637 lhs
->value
= ~lhs
->value
;
642 idx
= level_1 (idx
+ 1, string
, lhs
);
643 lhs
->value
= -lhs
->value
;
645 lhs
->add_symbol
= lhs
->sub_symbol
;
651 idx
= level_5 (sb_skip_white (idx
, string
), string
, lhs
);
652 if (string
->ptr
[idx
] != ')')
653 ERROR ((stderr
, _("misplaced closing parens.\n")));
658 idx
= level_0 (idx
, string
, lhs
);
661 return sb_skip_white (idx
, string
);
665 level_2 (idx
, string
, lhs
)
672 idx
= level_1 (idx
, string
, lhs
);
674 while (idx
< string
->len
&& (string
->ptr
[idx
] == '*'
675 || string
->ptr
[idx
] == '/'))
677 char op
= string
->ptr
[idx
++];
678 idx
= level_1 (idx
, string
, &rhs
);
682 checkconst ('*', lhs
);
683 checkconst ('*', &rhs
);
684 lhs
->value
*= rhs
.value
;
687 checkconst ('/', lhs
);
688 checkconst ('/', &rhs
);
690 ERROR ((stderr
, _("attempt to divide by zero.\n")));
692 lhs
->value
/= rhs
.value
;
696 return sb_skip_white (idx
, string
);
700 level_3 (idx
, string
, lhs
)
707 idx
= level_2 (idx
, string
, lhs
);
709 while (idx
< string
->len
710 && (string
->ptr
[idx
] == '+'
711 || string
->ptr
[idx
] == '-'))
713 char op
= string
->ptr
[idx
++];
714 idx
= level_2 (idx
, string
, &rhs
);
718 lhs
->value
+= rhs
.value
;
719 if (lhs
->add_symbol
.name
&& rhs
.add_symbol
.name
)
721 ERROR ((stderr
, _("can't add two relocatable expressions\n")));
723 /* Change nn+symbol to symbol + nn. */
724 if (rhs
.add_symbol
.name
)
726 lhs
->add_symbol
= rhs
.add_symbol
;
730 lhs
->value
-= rhs
.value
;
731 lhs
->sub_symbol
= rhs
.add_symbol
;
735 return sb_skip_white (idx
, string
);
739 level_4 (idx
, string
, lhs
)
746 idx
= level_3 (idx
, string
, lhs
);
748 while (idx
< string
->len
&&
749 string
->ptr
[idx
] == '&')
751 char op
= string
->ptr
[idx
++];
752 idx
= level_3 (idx
, string
, &rhs
);
756 checkconst ('&', lhs
);
757 checkconst ('&', &rhs
);
758 lhs
->value
&= rhs
.value
;
762 return sb_skip_white (idx
, string
);
766 level_5 (idx
, string
, lhs
)
773 idx
= level_4 (idx
, string
, lhs
);
775 while (idx
< string
->len
776 && (string
->ptr
[idx
] == '|' || string
->ptr
[idx
] == '~'))
778 char op
= string
->ptr
[idx
++];
779 idx
= level_4 (idx
, string
, &rhs
);
783 checkconst ('|', lhs
);
784 checkconst ('|', &rhs
);
785 lhs
->value
|= rhs
.value
;
788 checkconst ('~', lhs
);
789 checkconst ('~', &rhs
);
790 lhs
->value
^= rhs
.value
;
794 return sb_skip_white (idx
, string
);
797 /* Parse the expression at offset idx into string, fill up res with
798 the result. Return the index of the first char past the
802 exp_parse (idx
, string
, res
)
807 return level_5 (sb_skip_white (idx
, string
), string
, res
);
810 /* Turn the expression at exp into text and glue it onto the end of
814 exp_string (exp
, string
)
822 if (exp
->add_symbol
.len
)
824 sb_add_buffer (string
, exp
->add_symbol
.name
, exp
->add_symbol
.len
);
832 sb_add_char (string
, '+');
833 sprintf (buf
, "%d", exp
->value
);
834 sb_add_string (string
, buf
);
838 if (exp
->sub_symbol
.len
)
840 sb_add_char (string
, '-');
841 sb_add_buffer (string
, exp
->add_symbol
.name
, exp
->add_symbol
.len
);
847 sb_add_char (string
, '0');
850 /* Parse the expression at offset idx into sb in. Return the value in
851 val. If the expression is not constant, give ERROR emsg. Return
852 the index of the first character past the end of the expression. */
855 exp_get_abs (emsg
, idx
, in
, val
)
862 idx
= exp_parse (idx
, in
, &res
);
863 if (res
.add_symbol
.len
|| res
.sub_symbol
.len
)
864 ERROR ((stderr
, "%s", emsg
));
869 /* Current label parsed from line. */
872 /* Hash table for all assigned variables. */
873 hash_table assign_hash_table
;
875 /* Hash table for keyword. */
876 hash_table keyword_hash_table
;
878 /* Hash table for eq variables. */
881 #define in_comment ';'
890 for (i
= 0; i
< out
->len
; i
++)
892 if (ISCOMMENTCHAR (s
[i
]))
901 /* Push back character ch so that it can be read again. */
911 if (sp
->pushback_index
)
912 sp
->pushback_index
--;
914 sb_add_char (&sp
->pushback
, ch
);
917 /* Push the sb ptr onto the include stack, with the given name, type
921 include_buf (name
, ptr
, type
, index
)
928 if (sp
- include_stack
>= MAX_INCLUDES
)
929 FATAL ((stderr
, _("unreasonable nesting.\n")));
931 sb_add_sb (&sp
->name
, name
);
934 sp
->pushback_index
= 0;
937 sb_new (&sp
->pushback
);
938 sb_add_sb (&sp
->pushback
, ptr
);
941 /* Used in ERROR messages, print info on where the include stack is
945 include_print_where_line (file
)
948 struct include_stack
*p
= include_stack
+ 1;
952 fprintf (file
, "%s:%d ", sb_name (&p
->name
), p
->linecount
- 1);
957 /* Used in listings, print the line number onto file. */
960 include_print_line (file
)
964 struct include_stack
*p
= include_stack
+ 1;
966 n
= fprintf (file
, "%4d", p
->linecount
);
970 n
+= fprintf (file
, ".%d", p
->linecount
);
980 /* Read a line from the top of the include stack into sb in. */
991 putc (comment_char
, outfile
);
992 if (print_line_number
)
993 include_print_line (outfile
);
1007 WARNING ((stderr
, _("End of file not at start of line.\n")));
1009 putc ('\n', outfile
);
1028 /* Continued line. */
1031 putc (comment_char
, outfile
);
1032 putc ('+', outfile
);
1045 sb_add_char (in
, ch
);
1053 /* Find a label from sb in and put it in out. */
1056 grab_label (in
, out
)
1062 if (ISFIRSTCHAR (in
->ptr
[i
]) || in
->ptr
[i
] == '\\')
1064 sb_add_char (out
, in
->ptr
[i
]);
1066 while ((ISNEXTCHAR (in
->ptr
[i
])
1067 || in
->ptr
[i
] == '\\'
1068 || in
->ptr
[i
] == '&')
1071 sb_add_char (out
, in
->ptr
[i
]);
1078 /* Find all strange base stuff and turn into decimal. Also
1079 find all the other numbers and convert them from the default radix. */
1082 change_base (idx
, in
, out
)
1089 while (idx
< in
->len
)
1091 if (in
->ptr
[idx
] == '\\'
1092 && idx
+ 1 < in
->len
1093 && in
->ptr
[idx
+ 1] == '(')
1096 while (idx
< in
->len
1097 && in
->ptr
[idx
] != ')')
1099 sb_add_char (out
, in
->ptr
[idx
]);
1105 else if (idx
< in
->len
- 1 && in
->ptr
[idx
+ 1] == '\'' && ! mri
)
1109 switch (in
->ptr
[idx
])
1128 ERROR ((stderr
, _("Illegal base character %c.\n"), in
->ptr
[idx
]));
1133 idx
= sb_strtol (idx
+ 2, in
, base
, &value
);
1134 sprintf (buffer
, "%d", value
);
1135 sb_add_string (out
, buffer
);
1137 else if (ISFIRSTCHAR (in
->ptr
[idx
]))
1139 /* Copy entire names through quickly. */
1140 sb_add_char (out
, in
->ptr
[idx
]);
1142 while (idx
< in
->len
&& ISNEXTCHAR (in
->ptr
[idx
]))
1144 sb_add_char (out
, in
->ptr
[idx
]);
1148 else if (isdigit ((unsigned char) in
->ptr
[idx
]))
1151 /* All numbers must start with a digit, let's chew it and
1152 spit out decimal. */
1153 idx
= sb_strtol (idx
, in
, radix
, &value
);
1154 sprintf (buffer
, "%d", value
);
1155 sb_add_string (out
, buffer
);
1157 /* Skip all undigsested letters. */
1158 while (idx
< in
->len
&& ISNEXTCHAR (in
->ptr
[idx
]))
1160 sb_add_char (out
, in
->ptr
[idx
]);
1164 else if (in
->ptr
[idx
] == '"' || in
->ptr
[idx
] == '\'')
1166 char tchar
= in
->ptr
[idx
];
1167 /* Copy entire names through quickly. */
1168 sb_add_char (out
, in
->ptr
[idx
]);
1170 while (idx
< in
->len
&& in
->ptr
[idx
] != tchar
)
1172 sb_add_char (out
, in
->ptr
[idx
]);
1178 /* Nothing special, just pass it through. */
1179 sb_add_char (out
, in
->ptr
[idx
]);
1194 fprintf (outfile
, "%s\n", sb_name (in
));
1200 do_assign (again
, idx
, in
)
1205 /* Stick label in symbol table with following value. */
1210 idx
= exp_parse (idx
, in
, &e
);
1211 exp_string (&e
, &acc
);
1212 hash_add_to_string_table (&assign_hash_table
, &label
, &acc
, again
);
1216 /* .radix [b|q|d|h] */
1222 int idx
= sb_skip_white (0, ptr
);
1223 switch (ptr
->ptr
[idx
])
1242 ERROR ((stderr
, _("radix is %c must be one of b, q, d or h"), radix
));
1246 /* Parse off a .b, .w or .l. */
1249 get_opsize (idx
, in
, size
)
1255 if (in
->ptr
[idx
] == '.')
1259 switch (in
->ptr
[idx
])
1277 ERROR ((stderr
, _("size must be one of b, w or l, is %c.\n"), in
->ptr
[idx
]));
1290 idx
= sb_skip_white (idx
, line
);
1292 && ISCOMMENTCHAR(line
->ptr
[idx
]))
1294 if (idx
>= line
->len
)
1299 /* .data [.b|.w|.l] <data>*
1300 or d[bwl] <data>* */
1303 do_data (idx
, in
, size
)
1309 char *opname
= ".yikes!";
1315 idx
= get_opsize (idx
, in
, &opsize
);
1334 fprintf (outfile
, "%s\t", opname
);
1336 idx
= sb_skip_white (idx
, in
);
1340 && in
->ptr
[idx
] == '"')
1343 idx
= getstring (idx
, in
, &acc
);
1344 for (i
= 0; i
< acc
.len
; i
++)
1347 fprintf (outfile
, ",");
1348 fprintf (outfile
, "%d", acc
.ptr
[i
]);
1353 while (!eol (idx
, in
))
1356 idx
= exp_parse (idx
, in
, &e
);
1357 exp_string (&e
, &acc
);
1358 sb_add_char (&acc
, 0);
1359 fprintf (outfile
, "%s", acc
.ptr
);
1360 if (idx
< in
->len
&& in
->ptr
[idx
] == ',')
1362 fprintf (outfile
, ",");
1368 sb_print_at (outfile
, idx
, in
);
1369 fprintf (outfile
, "\n");
1372 /* .datab [.b|.w|.l] <repeat>,<fill> */
1383 idx
= get_opsize (idx
, in
, &opsize
);
1385 idx
= exp_get_abs (_("datab repeat must be constant.\n"), idx
, in
, &repeat
);
1386 idx
= sb_skip_comma (idx
, in
);
1387 idx
= exp_get_abs (_("datab data must be absolute.\n"), idx
, in
, &fill
);
1389 fprintf (outfile
, ".fill\t%d,%d,%d\n", repeat
, opsize
, fill
);
1399 int al
, have_fill
, fill
;
1401 idx
= exp_get_abs (_("align needs absolute expression.\n"), idx
, in
, &al
);
1402 idx
= sb_skip_white (idx
, in
);
1405 if (! eol (idx
, in
))
1407 idx
= sb_skip_comma (idx
, in
);
1408 idx
= exp_get_abs (_(".align needs absolute fill value.\n"), idx
, in
,
1413 fprintf (outfile
, ".align %d", al
);
1415 fprintf (outfile
, ",%d", fill
);
1416 fprintf (outfile
, "\n");
1419 /* .res[.b|.w|.l] <size> */
1422 do_res (idx
, in
, type
)
1430 idx
= get_opsize (idx
, in
, &size
);
1431 while (!eol (idx
, in
))
1433 idx
= sb_skip_white (idx
, in
);
1434 if (in
->ptr
[idx
] == ',')
1436 idx
= exp_get_abs (_("res needs absolute expression for fill count.\n"), idx
, in
, &count
);
1438 if (type
== 'c' || type
== 'z')
1441 fprintf (outfile
, ".space %d\n", count
* size
);
1451 fprintf (outfile
, ".global %s\n", sb_name (in
));
1454 /* .print [list] [nolist] */
1461 idx
= sb_skip_white (idx
, in
);
1462 while (idx
< in
->len
)
1464 if (strncasecmp (in
->ptr
+ idx
, "LIST", 4) == 0)
1466 fprintf (outfile
, ".list\n");
1469 else if (strncasecmp (in
->ptr
+ idx
, "NOLIST", 6) == 0)
1471 fprintf (outfile
, ".nolist\n");
1481 do_heading (idx
, in
)
1487 idx
= getstring (idx
, in
, &head
);
1488 fprintf (outfile
, ".title \"%s\"\n", sb_name (&head
));
1497 fprintf (outfile
, ".eject\n");
1500 /* .form [lin=<value>] [col=<value>] */
1509 idx
= sb_skip_white (idx
, in
);
1511 while (idx
< in
->len
)
1514 if (strncasecmp (in
->ptr
+ idx
, "LIN=", 4) == 0)
1517 idx
= exp_get_abs (_("form LIN= needs absolute expresssion.\n"), idx
, in
, &lines
);
1520 if (strncasecmp (in
->ptr
+ idx
, _("COL="), 4) == 0)
1523 idx
= exp_get_abs (_("form COL= needs absolute expresssion.\n"), idx
, in
, &columns
);
1528 fprintf (outfile
, ".psize %d,%d\n", lines
, columns
);
1532 /* Fetch string from the input stream,
1534 'Bxyx<whitespace> -> return 'Bxyza
1535 %<char> -> return string of decimal value of x
1536 "<string>" -> return string
1537 xyx<whitespace> -> return xyz
1541 get_any_string (idx
, in
, out
, expand
, pretend_quoted
)
1549 idx
= sb_skip_white (idx
, in
);
1553 if (in
->len
> 2 && in
->ptr
[idx
+ 1] == '\'' && ISBASE (in
->ptr
[idx
]))
1555 while (!ISSEP (in
->ptr
[idx
]))
1556 sb_add_char (out
, in
->ptr
[idx
++]);
1558 else if (in
->ptr
[idx
] == '%'
1564 /* Turns the next expression into a string. */
1565 idx
= exp_get_abs (_("% operator needs absolute expression"),
1569 sprintf (buf
, "%d", val
);
1570 sb_add_string (out
, buf
);
1572 else if (in
->ptr
[idx
] == '"'
1573 || in
->ptr
[idx
] == '<'
1574 || (alternate
&& in
->ptr
[idx
] == '\''))
1576 if (alternate
&& expand
)
1578 /* Keep the quotes. */
1579 sb_add_char (out
, '\"');
1581 idx
= getstring (idx
, in
, out
);
1582 sb_add_char (out
, '\"');
1587 idx
= getstring (idx
, in
, out
);
1592 while (idx
< in
->len
1593 && (in
->ptr
[idx
] == '"'
1594 || in
->ptr
[idx
] == '\''
1596 || !ISSEP (in
->ptr
[idx
])))
1598 if (in
->ptr
[idx
] == '"'
1599 || in
->ptr
[idx
] == '\'')
1601 char tchar
= in
->ptr
[idx
];
1602 sb_add_char (out
, in
->ptr
[idx
++]);
1603 while (idx
< in
->len
1604 && in
->ptr
[idx
] != tchar
)
1605 sb_add_char (out
, in
->ptr
[idx
++]);
1609 sb_add_char (out
, in
->ptr
[idx
++]);
1617 /* Skip along sb in starting at idx, suck off whitespace a ( and more
1618 whitespace. Return the idx of the next char. */
1621 skip_openp (idx
, in
)
1625 idx
= sb_skip_white (idx
, in
);
1626 if (in
->ptr
[idx
] != '(')
1627 ERROR ((stderr
, _("misplaced ( .\n")));
1628 idx
= sb_skip_white (idx
+ 1, in
);
1632 /* Skip along sb in starting at idx, suck off whitespace a ) and more
1633 whitespace. Return the idx of the next char. */
1636 skip_closep (idx
, in
)
1640 idx
= sb_skip_white (idx
, in
);
1641 if (in
->ptr
[idx
] != ')')
1642 ERROR ((stderr
, _("misplaced ).\n")));
1643 idx
= sb_skip_white (idx
+ 1, in
);
1650 dolen (idx
, in
, out
)
1659 sb_new (&stringout
);
1660 idx
= skip_openp (idx
, in
);
1661 idx
= get_and_process (idx
, in
, &stringout
);
1662 idx
= skip_closep (idx
, in
);
1663 sprintf (buffer
, "%d", stringout
.len
);
1664 sb_add_string (out
, buffer
);
1666 sb_kill (&stringout
);
1673 doinstr (idx
, in
, out
)
1687 idx
= skip_openp (idx
, in
);
1688 idx
= get_and_process (idx
, in
, &string
);
1689 idx
= sb_skip_comma (idx
, in
);
1690 idx
= get_and_process (idx
, in
, &search
);
1691 idx
= sb_skip_comma (idx
, in
);
1692 if (isdigit ((unsigned char) in
->ptr
[idx
]))
1694 idx
= exp_get_abs (_(".instr needs absolute expresson.\n"), idx
, in
, &start
);
1700 idx
= skip_closep (idx
, in
);
1702 for (i
= start
; i
< string
.len
; i
++)
1704 if (strncmp (string
.ptr
+ i
, search
.ptr
, search
.len
) == 0)
1710 sprintf (buffer
, "%d", res
);
1711 sb_add_string (out
, buffer
);
1718 dosubstr (idx
, in
, out
)
1728 idx
= skip_openp (idx
, in
);
1729 idx
= get_and_process (idx
, in
, &string
);
1730 idx
= sb_skip_comma (idx
, in
);
1731 idx
= exp_get_abs (_("need absolute position.\n"), idx
, in
, &pos
);
1732 idx
= sb_skip_comma (idx
, in
);
1733 idx
= exp_get_abs (_("need absolute length.\n"), idx
, in
, &len
);
1734 idx
= skip_closep (idx
, in
);
1736 if (len
< 0 || pos
< 0 ||
1738 || pos
+ len
> string
.len
)
1740 sb_add_string (out
, " ");
1744 sb_add_char (out
, '"');
1747 sb_add_char (out
, string
.ptr
[pos
++]);
1750 sb_add_char (out
, '"');
1756 /* Scan line, change tokens in the hash table to their replacements. */
1759 process_assigns (idx
, in
, buf
)
1764 while (idx
< in
->len
)
1767 if (in
->ptr
[idx
] == '\\'
1768 && idx
+ 1 < in
->len
1769 && in
->ptr
[idx
+ 1] == '(')
1773 sb_add_char (buf
, in
->ptr
[idx
]);
1776 while (idx
< in
->len
&& in
->ptr
[idx
- 1] != ')');
1778 else if (in
->ptr
[idx
] == '\\'
1779 && idx
+ 1 < in
->len
1780 && in
->ptr
[idx
+ 1] == '&')
1782 idx
= condass_lookup_name (in
, idx
+ 2, buf
, 1);
1784 else if (in
->ptr
[idx
] == '\\'
1785 && idx
+ 1 < in
->len
1786 && in
->ptr
[idx
+ 1] == '$')
1788 idx
= condass_lookup_name (in
, idx
+ 2, buf
, 0);
1790 else if (idx
+ 3 < in
->len
1791 && in
->ptr
[idx
] == '.'
1792 && toupper ((unsigned char) in
->ptr
[idx
+ 1]) == 'L'
1793 && toupper ((unsigned char) in
->ptr
[idx
+ 2]) == 'E'
1794 && toupper ((unsigned char) in
->ptr
[idx
+ 3]) == 'N')
1795 idx
= dolen (idx
+ 4, in
, buf
);
1796 else if (idx
+ 6 < in
->len
1797 && in
->ptr
[idx
] == '.'
1798 && toupper ((unsigned char) in
->ptr
[idx
+ 1]) == 'I'
1799 && toupper ((unsigned char) in
->ptr
[idx
+ 2]) == 'N'
1800 && toupper ((unsigned char) in
->ptr
[idx
+ 3]) == 'S'
1801 && toupper ((unsigned char) in
->ptr
[idx
+ 4]) == 'T'
1802 && toupper ((unsigned char) in
->ptr
[idx
+ 5]) == 'R')
1803 idx
= doinstr (idx
+ 6, in
, buf
);
1804 else if (idx
+ 7 < in
->len
1805 && in
->ptr
[idx
] == '.'
1806 && toupper ((unsigned char) in
->ptr
[idx
+ 1]) == 'S'
1807 && toupper ((unsigned char) in
->ptr
[idx
+ 2]) == 'U'
1808 && toupper ((unsigned char) in
->ptr
[idx
+ 3]) == 'B'
1809 && toupper ((unsigned char) in
->ptr
[idx
+ 4]) == 'S'
1810 && toupper ((unsigned char) in
->ptr
[idx
+ 5]) == 'T'
1811 && toupper ((unsigned char) in
->ptr
[idx
+ 6]) == 'R')
1812 idx
= dosubstr (idx
+ 7, in
, buf
);
1813 else if (ISFIRSTCHAR (in
->ptr
[idx
]))
1815 /* May be a simple name subsitution, see if we have a word. */
1818 while (cur
< in
->len
1819 && (ISNEXTCHAR (in
->ptr
[cur
])))
1823 sb_add_buffer (&acc
, in
->ptr
+ idx
, cur
- idx
);
1824 ptr
= hash_lookup (&assign_hash_table
, &acc
);
1827 /* Found a definition for it. */
1828 sb_add_sb (buf
, &ptr
->value
.s
);
1832 /* No definition, just copy the word. */
1833 sb_add_sb (buf
, &acc
);
1840 sb_add_char (buf
, in
->ptr
[idx
++]);
1846 get_and_process (idx
, in
, out
)
1853 idx
= get_any_string (idx
, in
, &t
, 1, 0);
1854 process_assigns (0, &t
, out
);
1874 more
= get_line (&line
);
1877 /* Find any label and pseudo op that we're intested in. */
1882 fprintf (outfile
, "\n");
1885 && (line
.ptr
[0] == '*'
1886 || line
.ptr
[0] == '!'))
1888 /* MRI line comment. */
1889 fprintf (outfile
, "%s", sb_name (&line
));
1893 l
= grab_label (&line
, &label_in
);
1896 if (line
.ptr
[l
] == ':')
1898 while (ISWHITE (line
.ptr
[l
]) && l
< line
.len
)
1905 /* Munge the label, unless this is EQU or ASSIGN. */
1908 && (line
.ptr
[l
] == '.' || alternate
|| mri
))
1912 if (line
.ptr
[lx
] == '.')
1914 if (lx
+ 3 <= line
.len
1915 && strncasecmp ("EQU", line
.ptr
+ lx
, 3) == 0
1916 && (lx
+ 3 == line
.len
1917 || ! ISFIRSTCHAR (line
.ptr
[lx
+ 3])))
1919 else if (lx
+ 6 <= line
.len
1920 && strncasecmp ("ASSIGN", line
.ptr
+ lx
, 6) == 0
1921 && (lx
+ 6 == line
.len
1922 || ! ISFIRSTCHAR (line
.ptr
[lx
+ 6])))
1927 process_assigns (0, &label_in
, &label
);
1929 sb_add_sb (&label
, &label_in
);
1934 if (process_pseudo_op (l
, &line
, &acc
))
1938 else if (condass_on ())
1940 if (macro_op (l
, &line
))
1949 fprintf (outfile
, "%s:\t", sb_name (&label
));
1952 fprintf (outfile
, "\t");
1954 process_assigns (l
, &line
, &t1
);
1956 change_base (0, &t1
, &t2
);
1957 fprintf (outfile
, "%s\n", sb_name (&t2
));
1964 /* Only a label on this line. */
1965 if (label
.len
&& condass_on ())
1967 fprintf (outfile
, "%s:\n", sb_name (&label
));
1975 more
= get_line (&line
);
1978 if (!had_end
&& !mri
)
1979 WARNING ((stderr
, _("END missing from end of file.\n")));
1983 free_old_entry (ptr
)
1988 if (ptr
->type
== hash_string
)
1989 sb_kill (&ptr
->value
.s
);
1993 /* name: .ASSIGNA <value> */
1996 do_assigna (idx
, in
)
2004 process_assigns (idx
, in
, &tmp
);
2005 idx
= exp_get_abs (_(".ASSIGNA needs constant expression argument.\n"), 0, &tmp
, &val
);
2009 ERROR ((stderr
, _(".ASSIGNA without label.\n")));
2013 hash_entry
*ptr
= hash_create (&vars
, &label
);
2014 free_old_entry (ptr
);
2015 ptr
->type
= hash_integer
;
2021 /* name: .ASSIGNC <string> */
2024 do_assignc (idx
, in
)
2030 idx
= getstring (idx
, in
, &acc
);
2034 ERROR ((stderr
, _(".ASSIGNS without label.\n")));
2038 hash_entry
*ptr
= hash_create (&vars
, &label
);
2039 free_old_entry (ptr
);
2040 ptr
->type
= hash_string
;
2041 sb_new (&ptr
->value
.s
);
2042 sb_add_sb (&ptr
->value
.s
, &acc
);
2047 /* name: .REG (reg) */
2054 /* Remove reg stuff from inside parens. */
2057 idx
= skip_openp (idx
, in
);
2059 idx
= sb_skip_white (idx
, in
);
2061 while (idx
< in
->len
2064 : in
->ptr
[idx
] != ')'))
2066 sb_add_char (&what
, in
->ptr
[idx
]);
2069 hash_add_to_string_table (&assign_hash_table
, &label
, &what
, 1);
2074 condass_lookup_name (inbuf
, idx
, out
, warn
)
2082 sb_new (&condass_acc
);
2084 while (idx
< inbuf
->len
2085 && ISNEXTCHAR (inbuf
->ptr
[idx
]))
2087 sb_add_char (&condass_acc
, inbuf
->ptr
[idx
++]);
2090 if (inbuf
->ptr
[idx
] == '\'')
2092 ptr
= hash_lookup (&vars
, &condass_acc
);
2098 WARNING ((stderr
, _("Can't find preprocessor variable %s.\n"), sb_name (&condass_acc
)));
2102 sb_add_string (out
, "0");
2107 if (ptr
->type
== hash_integer
)
2110 sprintf (buffer
, "%d", ptr
->value
.i
);
2111 sb_add_string (out
, buffer
);
2115 sb_add_sb (out
, &ptr
->value
.s
);
2118 sb_kill (&condass_acc
);
2131 whatcond (idx
, in
, val
)
2138 idx
= sb_skip_white (idx
, in
);
2140 if (idx
+ 1 < in
->len
)
2146 a
= toupper ((unsigned char) p
[0]);
2147 b
= toupper ((unsigned char) p
[1]);
2148 if (a
== 'E' && b
== 'Q')
2150 else if (a
== 'N' && b
== 'E')
2152 else if (a
== 'L' && b
== 'T')
2154 else if (a
== 'L' && b
== 'E')
2156 else if (a
== 'G' && b
== 'T')
2158 else if (a
== 'G' && b
== 'E')
2163 ERROR ((stderr
, _("Comparison operator must be one of EQ, NE, LT, LE, GT or GE.\n")));
2166 idx
= sb_skip_white (idx
+ 2, in
);
2183 idx
= sb_skip_white (idx
, in
);
2185 if (in
->ptr
[idx
] == '"')
2189 /* This is a string comparision. */
2190 idx
= getstring (idx
, in
, &acc_a
);
2191 idx
= whatcond (idx
, in
, &cond
);
2192 idx
= getstring (idx
, in
, &acc_b
);
2193 same
= acc_a
.len
== acc_b
.len
2194 && (strncmp (acc_a
.ptr
, acc_b
.ptr
, acc_a
.len
) == 0);
2196 if (cond
!= EQ
&& cond
!= NE
)
2198 ERROR ((stderr
, _("Comparison operator for strings must be EQ or NE\n")));
2202 res
= (cond
!= EQ
) ^ same
;
2205 /* This is a numeric expression. */
2210 idx
= exp_get_abs (_("Conditional operator must have absolute operands.\n"), idx
, in
, &vala
);
2211 idx
= whatcond (idx
, in
, &cond
);
2212 idx
= sb_skip_white (idx
, in
);
2213 if (in
->ptr
[idx
] == '"')
2215 WARNING ((stderr
, _("String compared against expression.\n")));
2220 idx
= exp_get_abs (_("Conditional operator must have absolute operands.\n"), idx
, in
, &valb
);
2264 if (ifi
>= IFNESTING
)
2266 FATAL ((stderr
, _("AIF nesting unreasonable.\n")));
2269 ifstack
[ifi
].on
= ifstack
[ifi
- 1].on
? istrue (idx
, in
) : 0;
2270 ifstack
[ifi
].hadelse
= 0;
2278 ifstack
[ifi
].on
= ifstack
[ifi
- 1].on
? !ifstack
[ifi
].on
: 0;
2279 if (ifstack
[ifi
].hadelse
)
2281 ERROR ((stderr
, _("Multiple AELSEs in AIF.\n")));
2283 ifstack
[ifi
].hadelse
= 1;
2297 ERROR ((stderr
, _("AENDI without AIF.\n")));
2304 return ifstack
[ifi
].on
;
2307 /* MRI IFEQ, IFNE, IFLT, IFLE, IFGE, IFGT. */
2310 do_if (idx
, in
, cond
)
2318 if (ifi
>= IFNESTING
)
2320 FATAL ((stderr
, _("IF nesting unreasonable.\n")));
2323 idx
= exp_get_abs (_("Conditional operator must have absolute operands.\n"),
2328 case EQ
: res
= val
== 0; break;
2329 case NE
: res
= val
!= 0; break;
2330 case LT
: res
= val
< 0; break;
2331 case LE
: res
= val
<= 0; break;
2332 case GE
: res
= val
>= 0; break;
2333 case GT
: res
= val
> 0; break;
2337 ifstack
[ifi
].on
= ifstack
[ifi
- 1].on
? res
: 0;
2338 ifstack
[ifi
].hadelse
= 0;
2341 /* Get a string for the MRI IFC or IFNC pseudo-ops. */
2344 get_mri_string (idx
, in
, val
, terminator
)
2350 idx
= sb_skip_white (idx
, in
);
2353 && in
->ptr
[idx
] == '\'')
2355 sb_add_char (val
, '\'');
2356 for (++idx
; idx
< in
->len
; ++idx
)
2358 sb_add_char (val
, in
->ptr
[idx
]);
2359 if (in
->ptr
[idx
] == '\'')
2363 || in
->ptr
[idx
] != '\'')
2367 idx
= sb_skip_white (idx
, in
);
2373 while (idx
< in
->len
2374 && in
->ptr
[idx
] != terminator
)
2376 sb_add_char (val
, in
->ptr
[idx
]);
2380 while (i
>= 0 && ISWHITE (val
->ptr
[i
]))
2391 do_ifc (idx
, in
, ifnc
)
2400 if (ifi
>= IFNESTING
)
2402 FATAL ((stderr
, _("IF nesting unreasonable.\n")));
2408 idx
= get_mri_string (idx
, in
, &first
, ',');
2410 if (idx
>= in
->len
|| in
->ptr
[idx
] != ',')
2412 ERROR ((stderr
, _("Bad format for IF or IFNC.\n")));
2416 idx
= get_mri_string (idx
+ 1, in
, &second
, ';');
2418 res
= (first
.len
== second
.len
2419 && strncmp (first
.ptr
, second
.ptr
, first
.len
) == 0);
2423 ifstack
[ifi
].on
= ifstack
[ifi
- 1].on
? res
: 0;
2424 ifstack
[ifi
].hadelse
= 0;
2433 ERROR ((stderr
, _("AENDR without a AREPEAT.\n")));
2435 ERROR ((stderr
, _("ENDR without a REPT.\n")));
2445 int line
= linecount ();
2453 process_assigns (idx
, in
, &exp
);
2454 doit
= istrue (0, &exp
);
2456 if (! buffer_and_nest ("AWHILE", "AENDW", &sub
, get_line
))
2457 FATAL ((stderr
, _("AWHILE without a AENDW at %d.\n"), line
- 1));
2472 int index
= include_next_index ();
2476 sb_add_sb (©
, &sub
);
2477 sb_add_sb (©
, in
);
2478 sb_add_string (©
, "\n");
2479 sb_add_sb (©
, &sub
);
2480 sb_add_string (©
, "\t.AENDW\n");
2481 /* Push another WHILE. */
2482 include_buf (&exp
, ©
, include_while
, index
);
2494 ERROR ((stderr
, _("AENDW without a AENDW.\n")));
2499 Pop things off the include stack until the type and index changes. */
2504 include_type type
= sp
->type
;
2505 if (type
== include_repeat
2506 || type
== include_while
2507 || type
== include_macro
)
2509 int index
= sp
->index
;
2511 while (sp
->index
== index
2512 && sp
->type
== type
)
2522 do_arepeat (idx
, in
)
2526 int line
= linecount ();
2527 sb exp
; /* Buffer with expression in it. */
2528 sb copy
; /* Expanded repeat block. */
2529 sb sub
; /* Contents of AREPEAT. */
2537 process_assigns (idx
, in
, &exp
);
2538 idx
= exp_get_abs (_("AREPEAT must have absolute operand.\n"), 0, &exp
, &rc
);
2540 ret
= buffer_and_nest ("AREPEAT", "AENDR", &sub
, get_line
);
2542 ret
= buffer_and_nest ("REPT", "ENDR", &sub
, get_line
);
2544 FATAL ((stderr
, _("AREPEAT without a AENDR at %d.\n"), line
- 1));
2547 /* Push back the text following the repeat, and another repeat block
2558 int index
= include_next_index ();
2559 sb_add_sb (©
, &sub
);
2563 sprintf (buffer
, "\t.AREPEAT %d\n", rc
- 1);
2565 sprintf (buffer
, "\tREPT %d\n", rc
- 1);
2566 sb_add_string (©
, buffer
);
2567 sb_add_sb (©
, &sub
);
2569 sb_add_string (©
, " .AENDR\n");
2571 sb_add_string (©
, " ENDR\n");
2574 include_buf (&exp
, ©
, include_repeat
, index
);
2586 ERROR ((stderr
, _(".ENDM without a matching .MACRO.\n")));
2589 /* MRI IRP pseudo-op. */
2592 do_irp (idx
, in
, irpc
)
2602 err
= expand_irp (irpc
, idx
, in
, &out
, get_line
, comment_char
);
2604 ERROR ((stderr
, "%s\n", err
));
2606 fprintf (outfile
, "%s", sb_terminate (&out
));
2611 /* Macro processing. */
2613 /* Parse off LOCAL n1, n2,... Invent a label name for it. */
2616 do_local (idx
, line
)
2617 int idx ATTRIBUTE_UNUSED
;
2618 sb
*line ATTRIBUTE_UNUSED
;
2620 ERROR ((stderr
, _("LOCAL outside of MACRO")));
2629 int line
= linecount ();
2631 err
= define_macro (idx
, in
, &label
, get_line
, (const char **) NULL
);
2633 ERROR ((stderr
, _("macro at line %d: %s\n"), line
- 1, err
));
2645 if (! macro_defined
)
2649 if (! check_macro (in
->ptr
+ idx
, &out
, comment_char
, &err
, NULL
))
2653 ERROR ((stderr
, "%s\n", err
));
2656 sb_add_string (&name
, _("macro expansion"));
2658 include_buf (&name
, &out
, include_macro
, include_next_index ());
2666 /* String handling. */
2669 getstring (idx
, in
, acc
)
2674 idx
= sb_skip_white (idx
, in
);
2676 while (idx
< in
->len
2677 && (in
->ptr
[idx
] == '"'
2678 || in
->ptr
[idx
] == '<'
2679 || (in
->ptr
[idx
] == '\'' && alternate
)))
2681 if (in
->ptr
[idx
] == '<')
2683 if (alternate
|| mri
)
2687 while ((in
->ptr
[idx
] != '>' || nest
)
2690 if (in
->ptr
[idx
] == '!')
2693 sb_add_char (acc
, in
->ptr
[idx
++]);
2697 if (in
->ptr
[idx
] == '>')
2699 if (in
->ptr
[idx
] == '<')
2701 sb_add_char (acc
, in
->ptr
[idx
++]);
2710 idx
= exp_get_abs (_("Character code in string must be absolute expression.\n"),
2712 sb_add_char (acc
, code
);
2714 if (in
->ptr
[idx
] != '>')
2715 ERROR ((stderr
, _("Missing > for character code.\n")));
2719 else if (in
->ptr
[idx
] == '"' || in
->ptr
[idx
] == '\'')
2721 char tchar
= in
->ptr
[idx
];
2723 while (idx
< in
->len
)
2725 if (alternate
&& in
->ptr
[idx
] == '!')
2728 sb_add_char (acc
, in
->ptr
[idx
++]);
2732 if (in
->ptr
[idx
] == tchar
)
2735 if (idx
>= in
->len
|| in
->ptr
[idx
] != tchar
)
2738 sb_add_char (acc
, in
->ptr
[idx
]);
2748 /* .SDATA[C|Z] <string> */
2751 do_sdata (idx
, in
, type
)
2760 fprintf (outfile
, ".byte\t");
2762 while (!eol (idx
, in
))
2766 idx
= sb_skip_white (idx
, in
);
2767 while (!eol (idx
, in
))
2769 pidx
= idx
= get_any_string (idx
, in
, &acc
, 0, 1);
2774 ERROR ((stderr
, _("string for SDATAC longer than 255 characters (%d).\n"), acc
.len
));
2776 fprintf (outfile
, "%d", acc
.len
);
2780 for (i
= 0; i
< acc
.len
; i
++)
2784 fprintf (outfile
, ",");
2786 fprintf (outfile
, "%d", acc
.ptr
[i
]);
2793 fprintf (outfile
, ",");
2794 fprintf (outfile
, "0");
2796 idx
= sb_skip_comma (idx
, in
);
2800 if (!alternate
&& in
->ptr
[idx
] != ',' && idx
!= in
->len
)
2802 fprintf (outfile
, "\n");
2803 ERROR ((stderr
, _("illegal character in SDATA line (0x%x).\n"),
2810 fprintf (outfile
, "\n");
2813 /* .SDATAB <count> <string> */
2825 idx
= exp_get_abs (_("Must have absolute SDATAB repeat count.\n"), idx
, in
, &repeat
);
2828 ERROR ((stderr
, _("Must have positive SDATAB repeat count (%d).\n"), repeat
));
2832 idx
= sb_skip_comma (idx
, in
);
2833 idx
= getstring (idx
, in
, &acc
);
2835 for (i
= 0; i
< repeat
; i
++)
2838 fprintf (outfile
, "\t");
2839 fprintf (outfile
, ".byte\t");
2840 sb_print (outfile
, &acc
);
2841 fprintf (outfile
, "\n");
2851 FILE *newone
= fopen (name
, "r");
2855 if (isp
== MAX_INCLUDES
)
2856 FATAL ((stderr
, _("Unreasonable include depth (%ld).\n"), (long) isp
));
2859 sp
->handle
= newone
;
2862 sb_add_string (&sp
->name
, name
);
2865 sp
->pushback_index
= 0;
2866 sp
->type
= include_file
;
2868 sb_new (&sp
->pushback
);
2873 do_include (idx
, in
)
2879 include_path
*includes
;
2885 idx
= getstring (idx
, in
, &t
);
2888 idx
= sb_skip_white (idx
, in
);
2889 while (idx
< in
->len
&& ! ISWHITE (in
->ptr
[idx
]))
2891 sb_add_char (&t
, in
->ptr
[idx
]);
2896 for (includes
= paths_head
; includes
; includes
= includes
->next
)
2899 sb_add_sb (&cat
, &includes
->path
);
2900 sb_add_char (&cat
, '/');
2901 sb_add_sb (&cat
, &t
);
2902 if (new_file (sb_name (&cat
)))
2909 if (! new_file (sb_name (&t
)))
2910 FATAL ((stderr
, _("Can't open include file `%s'.\n"), sb_name (&t
)));
2919 if (sp
!= include_stack
)
2922 fclose (sp
->handle
);
2927 /* Get the next character from the include stack. If there's anything
2928 in the pushback buffer, take that first. If we're at eof, pop from
2929 the stack and try again. Keep the linecount up to date. */
2936 if (sp
->pushback
.len
!= sp
->pushback_index
)
2938 r
= (char) (sp
->pushback
.ptr
[sp
->pushback_index
++]);
2939 /* When they've all gone, reset the pointer. */
2940 if (sp
->pushback_index
== sp
->pushback
.len
)
2942 sp
->pushback
.len
= 0;
2943 sp
->pushback_index
= 0;
2946 else if (sp
->handle
)
2948 r
= getc (sp
->handle
);
2953 if (r
== EOF
&& isp
)
2957 while (r
== EOF
&& isp
)
2975 return sp
->linecount
;
2979 include_next_index ()
2983 && index
> MAX_REASONABLE
)
2984 FATAL ((stderr
, _("Unreasonable expansion (-u turns off check).\n")));
2988 /* Initialize the chartype vector. */
2994 for (x
= 0; x
< 256; x
++)
2996 if (isalpha (x
) || x
== '_' || x
== '$')
2997 chartype
[x
] |= FIRSTBIT
;
2999 if (mri
&& x
== '.')
3000 chartype
[x
] |= FIRSTBIT
;
3002 if (isdigit (x
) || isalpha (x
) || x
== '_' || x
== '$')
3003 chartype
[x
] |= NEXTBIT
;
3005 if (x
== ' ' || x
== '\t' || x
== ',' || x
== '"' || x
== ';'
3006 || x
== '"' || x
== '<' || x
== '>' || x
== ')' || x
== '(')
3007 chartype
[x
] |= SEPBIT
;
3009 if (x
== 'b' || x
== 'B'
3010 || x
== 'q' || x
== 'Q'
3011 || x
== 'h' || x
== 'H'
3012 || x
== 'd' || x
== 'D')
3013 chartype
[x
] |= BASEBIT
;
3015 if (x
== ' ' || x
== '\t')
3016 chartype
[x
] |= WHITEBIT
;
3018 if (x
== comment_char
)
3019 chartype
[x
] |= COMMENTBIT
;
3023 /* What to do with all the keywords. */
3024 #define PROCESS 0x1000 /* Run substitution over the line. */
3025 #define LAB 0x2000 /* Spit out the label. */
3027 #define K_EQU (PROCESS|1)
3028 #define K_ASSIGN (PROCESS|2)
3029 #define K_REG (PROCESS|3)
3030 #define K_ORG (PROCESS|4)
3031 #define K_RADIX (PROCESS|5)
3032 #define K_DATA (LAB|PROCESS|6)
3033 #define K_DATAB (LAB|PROCESS|7)
3034 #define K_SDATA (LAB|PROCESS|8)
3035 #define K_SDATAB (LAB|PROCESS|9)
3036 #define K_SDATAC (LAB|PROCESS|10)
3037 #define K_SDATAZ (LAB|PROCESS|11)
3038 #define K_RES (LAB|PROCESS|12)
3039 #define K_SRES (LAB|PROCESS|13)
3040 #define K_SRESC (LAB|PROCESS|14)
3041 #define K_SRESZ (LAB|PROCESS|15)
3042 #define K_EXPORT (LAB|PROCESS|16)
3043 #define K_GLOBAL (LAB|PROCESS|17)
3044 #define K_PRINT (LAB|PROCESS|19)
3045 #define K_FORM (LAB|PROCESS|20)
3046 #define K_HEADING (LAB|PROCESS|21)
3047 #define K_PAGE (LAB|PROCESS|22)
3048 #define K_IMPORT (LAB|PROCESS|23)
3049 #define K_PROGRAM (LAB|PROCESS|24)
3050 #define K_END (PROCESS|25)
3051 #define K_INCLUDE (PROCESS|26)
3052 #define K_IGNORED (PROCESS|27)
3053 #define K_ASSIGNA (PROCESS|28)
3054 #define K_ASSIGNC (29)
3055 #define K_AIF (PROCESS|30)
3056 #define K_AELSE (PROCESS|31)
3057 #define K_AENDI (PROCESS|32)
3058 #define K_AREPEAT (PROCESS|33)
3059 #define K_AENDR (PROCESS|34)
3060 #define K_AWHILE (35)
3061 #define K_AENDW (PROCESS|36)
3062 #define K_EXITM (37)
3063 #define K_MACRO (PROCESS|38)
3065 #define K_ALIGN (PROCESS|LAB|40)
3066 #define K_ALTERNATE (41)
3067 #define K_DB (LAB|PROCESS|42)
3068 #define K_DW (LAB|PROCESS|43)
3069 #define K_DL (LAB|PROCESS|44)
3070 #define K_LOCAL (45)
3071 #define K_IFEQ (PROCESS|46)
3072 #define K_IFNE (PROCESS|47)
3073 #define K_IFLT (PROCESS|48)
3074 #define K_IFLE (PROCESS|49)
3075 #define K_IFGE (PROCESS|50)
3076 #define K_IFGT (PROCESS|51)
3077 #define K_IFC (PROCESS|52)
3078 #define K_IFNC (PROCESS|53)
3079 #define K_IRP (PROCESS|54)
3080 #define K_IRPC (PROCESS|55)
3089 static struct keyword kinfo
[] =
3091 { "EQU", K_EQU
, 0 },
3092 { "ALTERNATE", K_ALTERNATE
, 0 },
3093 { "ASSIGN", K_ASSIGN
, 0 },
3094 { "REG", K_REG
, 0 },
3095 { "ORG", K_ORG
, 0 },
3096 { "RADIX", K_RADIX
, 0 },
3097 { "DATA", K_DATA
, 0 },
3101 { "DATAB", K_DATAB
, 0 },
3102 { "SDATA", K_SDATA
, 0 },
3103 { "SDATAB", K_SDATAB
, 0 },
3104 { "SDATAZ", K_SDATAZ
, 0 },
3105 { "SDATAC", K_SDATAC
, 0 },
3106 { "RES", K_RES
, 0 },
3107 { "SRES", K_SRES
, 0 },
3108 { "SRESC", K_SRESC
, 0 },
3109 { "SRESZ", K_SRESZ
, 0 },
3110 { "EXPORT", K_EXPORT
, 0 },
3111 { "GLOBAL", K_GLOBAL
, 0 },
3112 { "PRINT", K_PRINT
, 0 },
3113 { "FORM", K_FORM
, 0 },
3114 { "HEADING", K_HEADING
, 0 },
3115 { "PAGE", K_PAGE
, 0 },
3116 { "PROGRAM", K_IGNORED
, 0 },
3117 { "END", K_END
, 0 },
3118 { "INCLUDE", K_INCLUDE
, 0 },
3119 { "ASSIGNA", K_ASSIGNA
, 0 },
3120 { "ASSIGNC", K_ASSIGNC
, 0 },
3121 { "AIF", K_AIF
, 0 },
3122 { "AELSE", K_AELSE
, 0 },
3123 { "AENDI", K_AENDI
, 0 },
3124 { "AREPEAT", K_AREPEAT
, 0 },
3125 { "AENDR", K_AENDR
, 0 },
3126 { "EXITM", K_EXITM
, 0 },
3127 { "MACRO", K_MACRO
, 0 },
3128 { "ENDM", K_ENDM
, 0 },
3129 { "AWHILE", K_AWHILE
, 0 },
3130 { "ALIGN", K_ALIGN
, 0 },
3131 { "AENDW", K_AENDW
, 0 },
3132 { "ALTERNATE", K_ALTERNATE
, 0 },
3133 { "LOCAL", K_LOCAL
, 0 },
3137 /* Although the conditional operators are handled by gas, we need to
3138 handle them here as well, in case they are used in a recursive
3139 macro to end the recursion. */
3141 static struct keyword mrikinfo
[] =
3143 { "IFEQ", K_IFEQ
, 0 },
3144 { "IFNE", K_IFNE
, 0 },
3145 { "IFLT", K_IFLT
, 0 },
3146 { "IFLE", K_IFLE
, 0 },
3147 { "IFGE", K_IFGE
, 0 },
3148 { "IFGT", K_IFGT
, 0 },
3149 { "IFC", K_IFC
, 0 },
3150 { "IFNC", K_IFNC
, 0 },
3151 { "ELSEC", K_AELSE
, 0 },
3152 { "ENDC", K_AENDI
, 0 },
3153 { "MEXIT", K_EXITM
, 0 },
3154 { "REPT", K_AREPEAT
, 0 },
3155 { "IRP", K_IRP
, 0 },
3156 { "IRPC", K_IRPC
, 0 },
3157 { "ENDR", K_AENDR
, 0 },
3161 /* Look for a pseudo op on the line. If one's there then call
3165 process_pseudo_op (idx
, line
, acc
)
3172 if (line
->ptr
[idx
] == '.' || alternate
|| mri
)
3174 /* Scan forward and find pseudo name. */
3180 if (line
->ptr
[idx
] == '.')
3182 in
= line
->ptr
+ idx
;
3187 while (idx
< line
->len
&& *e
&& ISFIRSTCHAR (*e
))
3189 sb_add_char (acc
, *e
);
3194 ptr
= hash_lookup (&keyword_hash_table
, acc
);
3199 /* This one causes lots of pain when trying to preprocess
3201 WARNING ((stderr
, _("Unrecognised pseudo op `%s'.\n"),
3206 if (ptr
->value
.i
& LAB
)
3208 /* Output the label. */
3211 fprintf (outfile
, "%s:\t", sb_name (&label
));
3214 fprintf (outfile
, "\t");
3217 if (mri
&& ptr
->value
.i
== K_END
)
3222 sb_add_buffer (&t
, line
->ptr
+ oidx
, idx
- oidx
);
3223 fprintf (outfile
, "\t%s", sb_name (&t
));
3227 if (ptr
->value
.i
& PROCESS
)
3229 /* Polish the rest of the line before handling the pseudo op. */
3231 strip_comments (line
);
3234 process_assigns (idx
, line
, acc
);
3236 change_base (0, acc
, line
);
3241 switch (ptr
->value
.i
)
3257 switch (ptr
->value
.i
)
3261 macro_init (1, mri
, 0, exp_get_abs
);
3270 ERROR ((stderr
, _("ORG command not allowed.\n")));
3276 do_data (idx
, line
, 1);
3279 do_data (idx
, line
, 2);
3282 do_data (idx
, line
, 4);
3285 do_data (idx
, line
, 0);
3288 do_datab (idx
, line
);
3291 do_sdata (idx
, line
, 0);
3294 do_sdatab (idx
, line
);
3297 do_sdata (idx
, line
, 'c');
3300 do_sdata (idx
, line
, 'z');
3303 do_assign (0, 0, line
);
3309 do_arepeat (idx
, line
);
3315 do_awhile (idx
, line
);
3321 do_assign (1, idx
, line
);
3324 do_align (idx
, line
);
3327 do_res (idx
, line
, 0);
3330 do_res (idx
, line
, 's');
3333 do_include (idx
, line
);
3336 do_local (idx
, line
);
3339 do_macro (idx
, line
);
3345 do_res (idx
, line
, 'c');
3348 do_print (idx
, line
);
3351 do_form (idx
, line
);
3354 do_heading (idx
, line
);
3366 do_res (idx
, line
, 'z');
3374 do_assigna (idx
, line
);
3377 do_assignc (idx
, line
);
3386 do_if (idx
, line
, EQ
);
3389 do_if (idx
, line
, NE
);
3392 do_if (idx
, line
, LT
);
3395 do_if (idx
, line
, LE
);
3398 do_if (idx
, line
, GE
);
3401 do_if (idx
, line
, GT
);
3404 do_ifc (idx
, line
, 0);
3407 do_ifc (idx
, line
, 1);
3410 do_irp (idx
, line
, 0);
3413 do_irp (idx
, line
, 1);
3421 /* Add a keyword to the hash table. */
3424 add_keyword (name
, code
)
3432 sb_add_string (&label
, name
);
3434 hash_add_to_int_table (&keyword_hash_table
, &label
, code
);
3437 for (j
= 0; name
[j
]; j
++)
3438 sb_add_char (&label
, name
[j
] - 'A' + 'a');
3439 hash_add_to_int_table (&keyword_hash_table
, &label
, code
);
3444 /* Build the keyword hash table - put each keyword in the table twice,
3445 once upper and once lower case. */
3452 for (i
= 0; kinfo
[i
].name
; i
++)
3453 add_keyword (kinfo
[i
].name
, kinfo
[i
].code
);
3457 for (i
= 0; mrikinfo
[i
].name
; i
++)
3458 add_keyword (mrikinfo
[i
].name
, mrikinfo
[i
].code
);
3480 sb_add_char (&value
, *string
);
3483 exp_get_abs (_("Invalid expression on command line.\n"),
3488 sb_add_char (&label
, *string
);
3493 ptr
= hash_create (&vars
, &label
);
3494 free_old_entry (ptr
);
3495 ptr
->type
= hash_integer
;
3502 /* The list of long options. */
3503 static struct option long_options
[] =
3505 { "alternate", no_argument
, 0, 'a' },
3506 { "include", required_argument
, 0, 'I' },
3507 { "commentchar", required_argument
, 0, 'c' },
3508 { "copysource", no_argument
, 0, 's' },
3509 { "debug", no_argument
, 0, 'd' },
3510 { "help", no_argument
, 0, 'h' },
3511 { "mri", no_argument
, 0, 'M' },
3512 { "output", required_argument
, 0, 'o' },
3513 { "print", no_argument
, 0, 'p' },
3514 { "unreasonable", no_argument
, 0, 'u' },
3515 { "version", no_argument
, 0, 'v' },
3516 { "define", required_argument
, 0, 'd' },
3517 { NULL
, no_argument
, 0, 0 }
3520 /* Show a usage message and exit. */
3522 show_usage (file
, status
)
3528 [-a] [--alternate] enter alternate macro mode\n\
3529 [-c char] [--commentchar char] change the comment character from !\n\
3530 [-d] [--debug] print some debugging info\n\
3531 [-h] [--help] print this message\n\
3532 [-M] [--mri] enter MRI compatibility mode\n\
3533 [-o out] [--output out] set the output file\n\
3534 [-p] [--print] print line numbers\n"), program_name
);
3536 [-s] [--copysource] copy source through as comments \n\
3537 [-u] [--unreasonable] allow unreasonable nesting\n\
3538 [-v] [--version] print the program version\n\
3539 [-Dname=value] create preprocessor variable called name, with value\n\
3540 [-Ipath] add to include path list\n\
3543 printf (_("Report bugs to %s\n"), REPORT_BUGS_TO
);
3547 /* Display a help message and exit. */
3552 printf (_("%s: Gnu Assembler Macro Preprocessor\n"), program_name
);
3553 show_usage (stdout
, 0);
3568 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
3569 setlocale (LC_MESSAGES
, "");
3571 bindtextdomain (PACKAGE
, LOCALEDIR
);
3572 textdomain (PACKAGE
);
3574 program_name
= argv
[0];
3575 xmalloc_set_program_name (program_name
);
3577 hash_new_table (101, &keyword_hash_table
);
3578 hash_new_table (101, &assign_hash_table
);
3579 hash_new_table (101, &vars
);
3583 while ((opt
= getopt_long (argc
, argv
, "I:sdhavc:upo:D:M", long_options
,
3597 include_path
*p
= (include_path
*) xmalloc (sizeof (include_path
));
3600 sb_add_string (&p
->path
, optarg
);
3602 paths_tail
->next
= p
;
3609 print_line_number
= 1;
3612 comment_char
= optarg
[0];
3634 /* This output is intended to follow the GNU standards document. */
3635 printf (_("GNU assembler pre-processor %s\n"), program_version
);
3636 printf (_("Copyright 1996 Free Software Foundation, Inc.\n"));
3638 This program is free software; you may redistribute it under the terms of\n\
3639 the GNU General Public License. This program has absolutely no warranty.\n"));
3645 show_usage (stderr
, 1);
3652 macro_init (alternate
, mri
, 0, exp_get_abs
);
3656 outfile
= fopen (out_name
, "w");
3659 fprintf (stderr
, _("%s: Can't open output file `%s'.\n"),
3660 program_name
, out_name
);
3673 /* Process all the input files. */
3675 while (optind
< argc
)
3677 if (new_file (argv
[optind
]))
3683 fprintf (stderr
, _("%s: Can't open input file `%s'.\n"),
3684 program_name
, argv
[optind
]);
3694 /* This function is used because an abort in some of the other files
3695 may be compiled into as_abort because they include as.h. */
3698 as_abort (file
, line
, fn
)
3699 const char *file
, *fn
;
3702 fprintf (stderr
, _("Internal error, aborting at %s line %d"), file
, line
);
3704 fprintf (stderr
, " in %s", fn
);
3705 fprintf (stderr
, _("\nPlease report this bug.\n"));