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
27 This program translates the input macros and stuff into a form
28 suitable for gas to consume.
31 gasp [-sdhau] [-c char] [-o <outfile>] <infile>*
33 -s copy source to output
34 -c <char> comments are started with <char> instead of !
35 -u allow unreasonable stuff
37 -d print debugging stats
38 -s semi colons start comments
39 -a use alternate syntax
40 Pseudo ops can start with or without a .
41 Labels have to be in first column.
42 -I specify include dir
43 Macro arg parameters subsituted by name, don't need the &.
44 String can start with ' too.
45 Strings can be surrounded by <..>
46 A %<exp> in a string evaluates the expression
47 Literal char in a string with !
63 #ifdef NEED_MALLOC_DECLARATION
64 extern char *malloc ();
68 #include "libiberty.h"
73 char *program_version
= "1.2";
75 /* This is normally declared in as.h, but we don't include that. We
76 need the function because other files linked with gasp.c might call
78 extern void as_abort
PARAMS ((const char *, int, const char *));
80 /* The default obstack chunk size. If we set this to zero, the
81 obstack code will use whatever will fit in a 4096 byte block. This
82 is used by the hash table code used by macro.c. */
85 #define MAX_INCLUDES 30 /* Maximum include depth */
86 #define MAX_REASONABLE 1000 /* Maximum number of expansions */
88 int unreasonable
; /* -u on command line */
89 int stats
; /* -d on command line */
90 int print_line_number
; /* -p flag on command line */
91 int copysource
; /* -c flag on command line */
92 int warnings
; /* Number of WARNINGs generated so far. */
93 int errors
; /* Number of ERRORs generated so far. */
94 int fatals
; /* Number of fatal ERRORs generated so far (either 0 or 1). */
95 int alternate
= 0; /* -a on command line */
96 int mri
= 0; /* -M on command line */
97 char comment_char
= '!';
98 int radix
= 10; /* Default radix */
100 int had_end
; /* Seen .END */
102 /* The output stream */
105 /* the attributes of each character are stored as a bit pattern
106 chartype, which gives us quick tests. */
113 #define COMMENTBIT 16
115 #define ISCOMMENTCHAR(x) (chartype[(unsigned char)(x)] & COMMENTBIT)
116 #define ISFIRSTCHAR(x) (chartype[(unsigned char)(x)] & FIRSTBIT)
117 #define ISNEXTCHAR(x) (chartype[(unsigned char)(x)] & NEXTBIT)
118 #define ISSEP(x) (chartype[(unsigned char)(x)] & SEPBIT)
119 #define ISWHITE(x) (chartype[(unsigned char)(x)] & WHITEBIT)
120 #define ISBASE(x) (chartype[(unsigned char)(x)] & BASEBIT)
121 static char chartype
[256];
124 /* Conditional assembly uses the `ifstack'. Each aif pushes another
125 entry onto the stack, and sets the on flag if it should. The aelse
126 sets hadelse, and toggles on. An aend pops a level. We limit to
127 100 levels of nesting, not because we're facists pigs with read
128 only minds, but because more than 100 levels of nesting is probably
129 a bug in the user's macro structure. */
131 #define IFNESTING 100
134 int on
; /* is the level being output */
135 int hadelse
; /* has an aelse been seen */
140 /* The final and intermediate results of expression evaluation are kept in
141 exp_t's. Note that a symbol is not an sb, but a pointer into the input
142 line. It must be coped somewhere safe before the next line is read in. */
153 int value
; /* constant part */
154 symbol add_symbol
; /* name part */
155 symbol sub_symbol
; /* name part */
160 /* Hashing is done in a pretty standard way. A hash_table has a
161 pointer to a vector of pointers to hash_entrys, and the size of the
162 vector. A hash_entry contains a union of all the info we like to
163 store in hash table. If there is a hash collision, hash_entries
164 with the same hash are kept in a chain. */
166 /* What the data in a hash_entry means */
169 hash_integer
, /* name->integer mapping */
170 hash_string
, /* name->string mapping */
171 hash_macro
, /* name is a macro */
172 hash_formal
/* name is a formal argument */
177 sb key
; /* symbol name */
178 hash_type type
; /* symbol meaning */
183 struct macro_struct
*m
;
184 struct formal_struct
*f
;
186 struct hs
*next
; /* next hash_entry with same hash key */
196 /* how we nest files and expand macros etc.
198 we keep a stack of of include_stack structs. each include file
199 pushes a new level onto the stack. we keep an sb with a pushback
200 too. unget chars are pushed onto the pushback sb, getchars first
201 checks the pushback sb before reading from the input stream.
203 small things are expanded by adding the text of the item onto the
204 pushback sb. larger items are grown by pushing a new level and
205 allocating the entire pushback buf for the item. each time
206 something like a macro is expanded, the stack index is changed. we
207 can then perform an exitm by popping all entries off the stack with
208 the same stack index. if we're being reasonable, we can detect
209 recusive expansion by checking the index is reasonably small.
214 include_file
, include_repeat
, include_while
, include_macro
219 sb pushback
; /* current pushback stream */
220 int pushback_index
; /* next char to read from stream */
221 FILE *handle
; /* open file */
222 sb name
; /* name of file */
223 int linecount
; /* number of lines read so far */
225 int index
; /* index of this layer */
227 include_stack
[MAX_INCLUDES
];
229 struct include_stack
*sp
;
230 #define isp (sp - include_stack)
232 /* Include file list */
234 typedef struct include_path
236 struct include_path
*next
;
240 include_path
*paths_head
;
241 include_path
*paths_tail
;
244 static void quit
PARAMS ((void));
245 static void hash_new_table
PARAMS ((int, hash_table
*));
246 static int hash
PARAMS ((sb
*));
247 static hash_entry
*hash_create
PARAMS ((hash_table
*, sb
*));
248 static void hash_add_to_string_table
PARAMS ((hash_table
*, sb
*, sb
*, int));
249 static void hash_add_to_int_table
PARAMS ((hash_table
*, sb
*, int));
250 static hash_entry
*hash_lookup
PARAMS ((hash_table
*, sb
*));
251 static void checkconst
PARAMS ((int, exp_t
*));
252 static int sb_strtol
PARAMS ((int, sb
*, int, int *));
253 static int level_0
PARAMS ((int, sb
*, exp_t
*));
254 static int level_1
PARAMS ((int, sb
*, exp_t
*));
255 static int level_2
PARAMS ((int, sb
*, exp_t
*));
256 static int level_3
PARAMS ((int, sb
*, exp_t
*));
257 static int level_4
PARAMS ((int, sb
*, exp_t
*));
258 static int level_5
PARAMS ((int, sb
*, exp_t
*));
259 static int exp_parse
PARAMS ((int, sb
*, exp_t
*));
260 static void exp_string
PARAMS ((exp_t
*, sb
*));
261 static int exp_get_abs
PARAMS ((const char *, int, sb
*, int *));
263 static void strip_comments
PARAMS ((sb
*));
265 static void unget
PARAMS ((int));
266 static void include_buf
PARAMS ((sb
*, sb
*, include_type
, int));
267 static void include_print_where_line
PARAMS ((FILE *));
268 static void include_print_line
PARAMS ((FILE *));
269 static int get_line
PARAMS ((sb
*));
270 static int grab_label
PARAMS ((sb
*, sb
*));
271 static void change_base
PARAMS ((int, sb
*, sb
*));
272 static void do_end
PARAMS ((sb
*));
273 static void do_assign
PARAMS ((int, int, sb
*));
274 static void do_radix
PARAMS ((sb
*));
275 static int get_opsize
PARAMS ((int, sb
*, int *));
276 static int eol
PARAMS ((int, sb
*));
277 static void do_data
PARAMS ((int, sb
*, int));
278 static void do_datab
PARAMS ((int, sb
*));
279 static void do_align
PARAMS ((int, sb
*));
280 static void do_res
PARAMS ((int, sb
*, int));
281 static void do_export
PARAMS ((sb
*));
282 static void do_print
PARAMS ((int, sb
*));
283 static void do_heading
PARAMS ((int, sb
*));
284 static void do_page
PARAMS ((void));
285 static void do_form
PARAMS ((int, sb
*));
286 static int get_any_string
PARAMS ((int, sb
*, sb
*, int, int));
287 static int skip_openp
PARAMS ((int, sb
*));
288 static int skip_closep
PARAMS ((int, sb
*));
289 static int dolen
PARAMS ((int, sb
*, sb
*));
290 static int doinstr
PARAMS ((int, sb
*, sb
*));
291 static int dosubstr
PARAMS ((int, sb
*, sb
*));
292 static void process_assigns
PARAMS ((int, sb
*, sb
*));
293 static int get_and_process
PARAMS ((int, sb
*, sb
*));
294 static void process_file
PARAMS ((void));
295 static void free_old_entry
PARAMS ((hash_entry
*));
296 static void do_assigna
PARAMS ((int, sb
*));
297 static void do_assignc
PARAMS ((int, sb
*));
298 static void do_reg
PARAMS ((int, sb
*));
299 static int condass_lookup_name
PARAMS ((sb
*, int, sb
*, int));
300 static int whatcond
PARAMS ((int, sb
*, int *));
301 static int istrue
PARAMS ((int, sb
*));
302 static void do_aif
PARAMS ((int, sb
*));
303 static void do_aelse
PARAMS ((void));
304 static void do_aendi
PARAMS ((void));
305 static int condass_on
PARAMS ((void));
306 static void do_if
PARAMS ((int, sb
*, int));
307 static int get_mri_string
PARAMS ((int, sb
*, sb
*, int));
308 static void do_ifc
PARAMS ((int, sb
*, int));
309 static void do_aendr
PARAMS ((void));
310 static void do_awhile
PARAMS ((int, sb
*));
311 static void do_aendw
PARAMS ((void));
312 static void do_exitm
PARAMS ((void));
313 static void do_arepeat
PARAMS ((int, sb
*));
314 static void do_endm
PARAMS ((void));
315 static void do_irp
PARAMS ((int, sb
*, int));
316 static void do_local
PARAMS ((int, sb
*));
317 static void do_macro
PARAMS ((int, sb
*));
318 static int macro_op
PARAMS ((int, sb
*));
319 static int getstring
PARAMS ((int, sb
*, sb
*));
320 static void do_sdata
PARAMS ((int, sb
*, int));
321 static void do_sdatab
PARAMS ((int, sb
*));
322 static int new_file
PARAMS ((const char *));
323 static void do_include
PARAMS ((int, sb
*));
324 static void include_pop
PARAMS ((void));
325 static int get
PARAMS ((void));
326 static int linecount
PARAMS ((void));
327 static int include_next_index
PARAMS ((void));
328 static void chartype_init
PARAMS ((void));
329 static int process_pseudo_op
PARAMS ((int, sb
*, sb
*));
330 static void add_keyword
PARAMS ((const char *, int));
331 static void process_init
PARAMS ((void));
332 static void do_define
PARAMS ((const char *));
333 static void show_usage
PARAMS ((FILE *, int));
334 static void show_help
PARAMS ((void));
337 do { include_print_where_line (stderr); fprintf x ; fatals++; quit(); } while(0)
339 do { include_print_where_line (stderr); fprintf x; errors++; } while(0)
341 do { include_print_where_line (stderr); fprintf x; warnings++;} while(0)
345 /* exit the program and return the right ERROR code. */
358 for (i
= 0; i
< sb_max_power_two
; i
++)
360 fprintf (stderr
, "strings size %8d : %d\n", 1<<i
, string_count
[i
]);
366 /* hash table maintenance. */
368 /* build a new hash table with size buckets, 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 /* lookup key in hash_table tab, if present, then return it, otherwise
401 build a new one and fill it with hash_integer. */
405 hash_create (tab
, key
)
409 int k
= hash (key
) % tab
->size
;
411 hash_entry
**table
= tab
->table
;
419 hash_entry
*n
= (hash_entry
*) xmalloc (sizeof (hash_entry
));
422 sb_add_sb (&n
->key
, key
);
424 n
->type
= hash_integer
;
427 if (strncmp (table
[k
]->key
.ptr
, key
->ptr
, key
->len
) == 0)
435 /* add sb name with key into hash_table tab. if replacing old value
436 and again, then ERROR. */
440 hash_add_to_string_table (tab
, key
, name
, again
)
446 hash_entry
*ptr
= hash_create (tab
, key
);
447 if (ptr
->type
== hash_integer
)
449 sb_new (&ptr
->value
.s
);
451 if (ptr
->value
.s
.len
)
454 ERROR ((stderr
, _("redefinition not allowed\n")));
457 ptr
->type
= hash_string
;
458 sb_reset (&ptr
->value
.s
);
460 sb_add_sb (&ptr
->value
.s
, name
);
463 /* add integer name to hash_table tab with sb key. */
467 hash_add_to_int_table (tab
, key
, name
)
472 hash_entry
*ptr
= hash_create (tab
, key
);
476 /* lookup sb key in hash_table tab. if found return hash_entry result,
481 hash_lookup (tab
, key
)
485 int k
= hash (key
) % tab
->size
;
486 hash_entry
**table
= tab
->table
;
487 hash_entry
*p
= table
[k
];
490 if (p
->key
.len
== key
->len
491 && strncmp (p
->key
.ptr
, key
->ptr
, key
->len
) == 0)
501 are handled in a really simple recursive decent way. each bit of
502 the machine takes an index into an sb and a pointer to an exp_t,
503 modifies the *exp_t and returns the index of the first character
504 past the part of the expression parsed.
506 expression precedence:
517 /* make sure that the exp_t at term is constant, if not the give the op ERROR. */
521 checkconst (op
, term
)
525 if (term
->add_symbol
.len
526 || term
->sub_symbol
.len
)
528 ERROR ((stderr
, _("the %c operator cannot take non-absolute arguments.\n"), op
));
532 /* turn the number in string at idx into a number of base,
533 fill in ptr and return the index of the first character not in the
538 sb_strtol (idx
, string
, base
, ptr
)
545 idx
= sb_skip_white (idx
, string
);
547 while (idx
< string
->len
)
549 int ch
= string
->ptr
[idx
];
553 else if (ch
>= 'a' && ch
<= 'f')
555 else if (ch
>= 'A' && ch
<= 'F')
563 value
= value
* base
+ dig
;
571 level_0 (idx
, string
, lhs
)
576 lhs
->add_symbol
.len
= 0;
577 lhs
->add_symbol
.name
= 0;
579 lhs
->sub_symbol
.len
= 0;
580 lhs
->sub_symbol
.name
= 0;
582 idx
= sb_skip_white (idx
, string
);
586 if (isdigit ((unsigned char) string
->ptr
[idx
]))
588 idx
= sb_strtol (idx
, string
, 10, &lhs
->value
);
590 else if (ISFIRSTCHAR (string
->ptr
[idx
]))
593 lhs
->add_symbol
.name
= string
->ptr
+ idx
;
594 while (idx
< string
->len
&& ISNEXTCHAR (string
->ptr
[idx
]))
599 lhs
->add_symbol
.len
= len
;
601 else if (string
->ptr
[idx
] == '"')
605 ERROR ((stderr
, _("string where expression expected.\n")));
606 idx
= getstring (idx
, string
, &acc
);
611 ERROR ((stderr
, _("can't find primary in expression.\n")));
614 return sb_skip_white (idx
, string
);
620 level_1 (idx
, string
, lhs
)
625 idx
= sb_skip_white (idx
, string
);
627 switch (string
->ptr
[idx
])
630 idx
= level_1 (idx
+ 1, string
, lhs
);
633 idx
= level_1 (idx
+ 1, string
, lhs
);
634 checkconst ('~', lhs
);
635 lhs
->value
= ~lhs
->value
;
640 idx
= level_1 (idx
+ 1, string
, lhs
);
641 lhs
->value
= -lhs
->value
;
643 lhs
->add_symbol
= lhs
->sub_symbol
;
649 idx
= level_5 (sb_skip_white (idx
, string
), string
, lhs
);
650 if (string
->ptr
[idx
] != ')')
651 ERROR ((stderr
, _("misplaced closing parens.\n")));
656 idx
= level_0 (idx
, string
, lhs
);
659 return sb_skip_white (idx
, string
);
663 level_2 (idx
, string
, lhs
)
670 idx
= level_1 (idx
, string
, lhs
);
672 while (idx
< string
->len
&& (string
->ptr
[idx
] == '*'
673 || string
->ptr
[idx
] == '/'))
675 char op
= string
->ptr
[idx
++];
676 idx
= level_1 (idx
, string
, &rhs
);
680 checkconst ('*', lhs
);
681 checkconst ('*', &rhs
);
682 lhs
->value
*= rhs
.value
;
685 checkconst ('/', lhs
);
686 checkconst ('/', &rhs
);
688 ERROR ((stderr
, _("attempt to divide by zero.\n")));
690 lhs
->value
/= rhs
.value
;
694 return sb_skip_white (idx
, string
);
699 level_3 (idx
, string
, lhs
)
706 idx
= level_2 (idx
, string
, lhs
);
708 while (idx
< string
->len
709 && (string
->ptr
[idx
] == '+'
710 || string
->ptr
[idx
] == '-'))
712 char op
= string
->ptr
[idx
++];
713 idx
= level_2 (idx
, string
, &rhs
);
717 lhs
->value
+= rhs
.value
;
718 if (lhs
->add_symbol
.name
&& rhs
.add_symbol
.name
)
720 ERROR ((stderr
, _("can't add two relocatable expressions\n")));
722 /* change nn+symbol to symbol + nn */
723 if (rhs
.add_symbol
.name
)
725 lhs
->add_symbol
= rhs
.add_symbol
;
729 lhs
->value
-= rhs
.value
;
730 lhs
->sub_symbol
= rhs
.add_symbol
;
734 return sb_skip_white (idx
, string
);
738 level_4 (idx
, string
, lhs
)
745 idx
= level_3 (idx
, string
, lhs
);
747 while (idx
< string
->len
&&
748 string
->ptr
[idx
] == '&')
750 char op
= string
->ptr
[idx
++];
751 idx
= level_3 (idx
, string
, &rhs
);
755 checkconst ('&', lhs
);
756 checkconst ('&', &rhs
);
757 lhs
->value
&= rhs
.value
;
761 return sb_skip_white (idx
, string
);
765 level_5 (idx
, string
, lhs
)
772 idx
= level_4 (idx
, string
, lhs
);
774 while (idx
< string
->len
775 && (string
->ptr
[idx
] == '|' || string
->ptr
[idx
] == '~'))
777 char op
= string
->ptr
[idx
++];
778 idx
= level_4 (idx
, string
, &rhs
);
782 checkconst ('|', lhs
);
783 checkconst ('|', &rhs
);
784 lhs
->value
|= rhs
.value
;
787 checkconst ('~', lhs
);
788 checkconst ('~', &rhs
);
789 lhs
->value
^= rhs
.value
;
793 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 expression.
802 exp_parse (idx
, string
, res
)
807 return level_5 (sb_skip_white (idx
, string
), string
, res
);
811 /* turn the expression at exp into text and glue it onto the end of
815 exp_string (exp
, string
)
823 if (exp
->add_symbol
.len
)
825 sb_add_buffer (string
, exp
->add_symbol
.name
, exp
->add_symbol
.len
);
833 sb_add_char (string
, '+');
834 sprintf (buf
, "%d", exp
->value
);
835 sb_add_string (string
, buf
);
839 if (exp
->sub_symbol
.len
)
841 sb_add_char (string
, '-');
842 sb_add_buffer (string
, exp
->add_symbol
.name
, exp
->add_symbol
.len
);
848 sb_add_char (string
, '0');
852 /* parse the expression at offset idx into sb in, return the value in val.
853 if the expression is not constant, give ERROR emsg. returns the index
854 of the first character past the end of the expression. */
857 exp_get_abs (emsg
, idx
, in
, val
)
864 idx
= exp_parse (idx
, in
, &res
);
865 if (res
.add_symbol
.len
|| res
.sub_symbol
.len
)
866 ERROR ((stderr
, "%s", emsg
));
872 sb label
; /* current label parsed from line */
873 hash_table assign_hash_table
; /* hash table for all assigned variables */
874 hash_table keyword_hash_table
; /* hash table for keyword */
875 hash_table vars
; /* hash table for eq variables */
877 #define in_comment ';'
886 for (i
= 0; i
< out
->len
; i
++)
888 if (ISCOMMENTCHAR(s
[i
]))
897 /* push back character ch so that it can be read again. */
907 if (sp
->pushback_index
)
908 sp
->pushback_index
--;
910 sb_add_char (&sp
->pushback
, ch
);
913 /* push the sb ptr onto the include stack, with the given name, type and index. */
917 include_buf (name
, ptr
, type
, index
)
924 if (sp
- include_stack
>= MAX_INCLUDES
)
925 FATAL ((stderr
, _("unreasonable nesting.\n")));
927 sb_add_sb (&sp
->name
, name
);
930 sp
->pushback_index
= 0;
933 sb_new (&sp
->pushback
);
934 sb_add_sb (&sp
->pushback
, ptr
);
938 /* used in ERROR messages, print info on where the include stack is onto file. */
941 include_print_where_line (file
)
944 struct include_stack
*p
= include_stack
+ 1;
948 fprintf (file
, "%s:%d ", sb_name (&p
->name
), p
->linecount
- 1);
953 /* used in listings, print the line number onto file. */
955 include_print_line (file
)
959 struct include_stack
*p
= include_stack
+ 1;
961 n
= fprintf (file
, "%4d", p
->linecount
);
965 n
+= fprintf (file
, ".%d", p
->linecount
);
976 /* read a line from the top of the include stack into sb in. */
987 putc (comment_char
, outfile
);
988 if (print_line_number
)
989 include_print_line (outfile
);
1003 WARNING ((stderr
, _("End of file not at start of line.\n")));
1005 putc ('\n', outfile
);
1024 /* continued line */
1027 putc (comment_char
, outfile
);
1028 putc ('+', outfile
);
1041 sb_add_char (in
, ch
);
1049 /* find a label from sb in and put it in out. */
1052 grab_label (in
, out
)
1058 if (ISFIRSTCHAR (in
->ptr
[i
]) || in
->ptr
[i
] == '\\')
1060 sb_add_char (out
, in
->ptr
[i
]);
1062 while ((ISNEXTCHAR (in
->ptr
[i
])
1063 || in
->ptr
[i
] == '\\'
1064 || in
->ptr
[i
] == '&')
1067 sb_add_char (out
, in
->ptr
[i
]);
1074 /* find all strange base stuff and turn into decimal. also
1075 find all the other numbers and convert them from the default radix */
1078 change_base (idx
, in
, out
)
1085 while (idx
< in
->len
)
1087 if (in
->ptr
[idx
] == '\\'
1088 && idx
+ 1 < in
->len
1089 && in
->ptr
[idx
+ 1] == '(')
1092 while (idx
< in
->len
1093 && in
->ptr
[idx
] != ')')
1095 sb_add_char (out
, in
->ptr
[idx
]);
1101 else if (idx
< in
->len
- 1 && in
->ptr
[idx
+ 1] == '\'' && ! mri
)
1105 switch (in
->ptr
[idx
])
1124 ERROR ((stderr
, _("Illegal base character %c.\n"), in
->ptr
[idx
]));
1129 idx
= sb_strtol (idx
+ 2, in
, base
, &value
);
1130 sprintf (buffer
, "%d", value
);
1131 sb_add_string (out
, buffer
);
1133 else if (ISFIRSTCHAR (in
->ptr
[idx
]))
1135 /* copy entire names through quickly */
1136 sb_add_char (out
, in
->ptr
[idx
]);
1138 while (idx
< in
->len
&& ISNEXTCHAR (in
->ptr
[idx
]))
1140 sb_add_char (out
, in
->ptr
[idx
]);
1144 else if (isdigit ((unsigned char) in
->ptr
[idx
]))
1147 /* all numbers must start with a digit, let's chew it and
1149 idx
= sb_strtol (idx
, in
, radix
, &value
);
1150 sprintf (buffer
, "%d", value
);
1151 sb_add_string (out
, buffer
);
1153 /* skip all undigsested letters */
1154 while (idx
< in
->len
&& ISNEXTCHAR (in
->ptr
[idx
]))
1156 sb_add_char (out
, in
->ptr
[idx
]);
1160 else if (in
->ptr
[idx
] == '"' || in
->ptr
[idx
] == '\'')
1162 char tchar
= in
->ptr
[idx
];
1163 /* copy entire names through quickly */
1164 sb_add_char (out
, in
->ptr
[idx
]);
1166 while (idx
< in
->len
&& in
->ptr
[idx
] != tchar
)
1168 sb_add_char (out
, in
->ptr
[idx
]);
1174 /* nothing special, just pass it through */
1175 sb_add_char (out
, in
->ptr
[idx
]);
1189 fprintf (outfile
, "%s\n", sb_name (in
));
1195 do_assign (again
, idx
, in
)
1200 /* stick label in symbol table with following value */
1205 idx
= exp_parse (idx
, in
, &e
);
1206 exp_string (&e
, &acc
);
1207 hash_add_to_string_table (&assign_hash_table
, &label
, &acc
, again
);
1212 /* .radix [b|q|d|h] */
1219 int idx
= sb_skip_white (0, ptr
);
1220 switch (ptr
->ptr
[idx
])
1239 ERROR ((stderr
, _("radix is %c must be one of b, q, d or h"), radix
));
1244 /* Parse off a .b, .w or .l */
1247 get_opsize (idx
, in
, size
)
1253 if (in
->ptr
[idx
] == '.')
1257 switch (in
->ptr
[idx
])
1275 ERROR ((stderr
, _("size must be one of b, w or l, is %c.\n"), in
->ptr
[idx
]));
1288 idx
= sb_skip_white (idx
, line
);
1290 && ISCOMMENTCHAR(line
->ptr
[idx
]))
1292 if (idx
>= line
->len
)
1297 /* .data [.b|.w|.l] <data>*
1298 or d[bwl] <data>* */
1301 do_data (idx
, in
, size
)
1307 char *opname
= ".yikes!";
1313 idx
= get_opsize (idx
, in
, &opsize
);
1332 fprintf (outfile
, "%s\t", opname
);
1334 idx
= sb_skip_white (idx
, in
);
1338 && in
->ptr
[idx
] == '"')
1341 idx
= getstring (idx
, in
, &acc
);
1342 for (i
= 0; i
< acc
.len
; i
++)
1345 fprintf(outfile
,",");
1346 fprintf (outfile
, "%d", acc
.ptr
[i
]);
1351 while (!eol (idx
, in
))
1354 idx
= exp_parse (idx
, in
, &e
);
1355 exp_string (&e
, &acc
);
1356 sb_add_char (&acc
, 0);
1357 fprintf (outfile
, "%s", acc
.ptr
);
1358 if (idx
< in
->len
&& in
->ptr
[idx
] == ',')
1360 fprintf (outfile
, ",");
1366 sb_print_at (outfile
, idx
, in
);
1367 fprintf (outfile
, "\n");
1370 /* .datab [.b|.w|.l] <repeat>,<fill> */
1381 idx
= get_opsize (idx
, in
, &opsize
);
1383 idx
= exp_get_abs (_("datab repeat must be constant.\n"), idx
, in
, &repeat
);
1384 idx
= sb_skip_comma (idx
, in
);
1385 idx
= exp_get_abs (_("datab data must be absolute.\n"), idx
, in
, &fill
);
1387 fprintf (outfile
, ".fill\t%d,%d,%d\n", repeat
, opsize
, fill
);
1397 int al
, have_fill
, fill
;
1399 idx
= exp_get_abs (_("align needs absolute expression.\n"), idx
, in
, &al
);
1400 idx
= sb_skip_white (idx
, in
);
1403 if (! eol (idx
, in
))
1405 idx
= sb_skip_comma (idx
, in
);
1406 idx
= exp_get_abs (_(".align needs absolute fill value.\n"), idx
, in
,
1411 fprintf (outfile
, ".align %d", al
);
1413 fprintf (outfile
, ",%d", fill
);
1414 fprintf (outfile
, "\n");
1417 /* .res[.b|.w|.l] <size> */
1420 do_res (idx
, in
, type
)
1428 idx
= get_opsize (idx
, in
, &size
);
1429 while (!eol(idx
, in
))
1431 idx
= sb_skip_white (idx
, in
);
1432 if (in
->ptr
[idx
] == ',')
1434 idx
= exp_get_abs (_("res needs absolute expression for fill count.\n"), idx
, in
, &count
);
1436 if (type
== 'c' || type
== 'z')
1439 fprintf (outfile
, ".space %d\n", count
* size
);
1450 fprintf (outfile
, ".global %s\n", sb_name (in
));
1453 /* .print [list] [nolist] */
1460 idx
= sb_skip_white (idx
, in
);
1461 while (idx
< in
->len
)
1463 if (strncasecmp (in
->ptr
+ idx
, "LIST", 4) == 0)
1465 fprintf (outfile
, ".list\n");
1468 else if (strncasecmp (in
->ptr
+ idx
, "NOLIST", 6) == 0)
1470 fprintf (outfile
, ".nolist\n");
1479 do_heading (idx
, in
)
1485 idx
= getstring (idx
, in
, &head
);
1486 fprintf (outfile
, ".title \"%s\"\n", sb_name (&head
));
1495 fprintf (outfile
, ".eject\n");
1498 /* .form [lin=<value>] [col=<value>] */
1506 idx
= sb_skip_white (idx
, in
);
1508 while (idx
< in
->len
)
1511 if (strncasecmp (in
->ptr
+ idx
, "LIN=", 4) == 0)
1514 idx
= exp_get_abs (_("form LIN= needs absolute expresssion.\n"), idx
, in
, &lines
);
1517 if (strncasecmp (in
->ptr
+ idx
, _("COL="), 4) == 0)
1520 idx
= exp_get_abs (_("form COL= needs absolute expresssion.\n"), idx
, in
, &columns
);
1525 fprintf (outfile
, ".psize %d,%d\n", lines
, columns
);
1530 /* Fetch string from the input stream,
1532 'Bxyx<whitespace> -> return 'Bxyza
1533 %<char> -> return string of decimal value of x
1534 "<string>" -> return string
1535 xyx<whitespace> -> return xyz
1538 get_any_string (idx
, in
, out
, expand
, pretend_quoted
)
1546 idx
= sb_skip_white (idx
, in
);
1550 if (in
->len
> 2 && in
->ptr
[idx
+1] == '\'' && ISBASE (in
->ptr
[idx
]))
1552 while (!ISSEP (in
->ptr
[idx
]))
1553 sb_add_char (out
, in
->ptr
[idx
++]);
1555 else if (in
->ptr
[idx
] == '%'
1561 /* Turns the next expression into a string */
1562 idx
= exp_get_abs (_("% operator needs absolute expression"),
1566 sprintf(buf
, "%d", val
);
1567 sb_add_string (out
, buf
);
1569 else if (in
->ptr
[idx
] == '"'
1570 || in
->ptr
[idx
] == '<'
1571 || (alternate
&& in
->ptr
[idx
] == '\''))
1573 if (alternate
&& expand
)
1575 /* Keep the quotes */
1576 sb_add_char (out
, '\"');
1578 idx
= getstring (idx
, in
, out
);
1579 sb_add_char (out
, '\"');
1583 idx
= getstring (idx
, in
, out
);
1588 while (idx
< in
->len
1589 && (in
->ptr
[idx
] == '"'
1590 || in
->ptr
[idx
] == '\''
1592 || !ISSEP (in
->ptr
[idx
])))
1594 if (in
->ptr
[idx
] == '"'
1595 || in
->ptr
[idx
] == '\'')
1597 char tchar
= in
->ptr
[idx
];
1598 sb_add_char (out
, in
->ptr
[idx
++]);
1599 while (idx
< in
->len
1600 && in
->ptr
[idx
] != tchar
)
1601 sb_add_char (out
, in
->ptr
[idx
++]);
1605 sb_add_char (out
, in
->ptr
[idx
++]);
1614 /* skip along sb in starting at idx, suck off whitespace a ( and more
1615 whitespace. return the idx of the next char */
1618 skip_openp (idx
, in
)
1622 idx
= sb_skip_white (idx
, in
);
1623 if (in
->ptr
[idx
] != '(')
1624 ERROR ((stderr
, _("misplaced ( .\n")));
1625 idx
= sb_skip_white (idx
+ 1, in
);
1629 /* skip along sb in starting at idx, suck off whitespace a ) and more
1630 whitespace. return the idx of the next char */
1633 skip_closep (idx
, in
)
1637 idx
= sb_skip_white (idx
, in
);
1638 if (in
->ptr
[idx
] != ')')
1639 ERROR ((stderr
, _("misplaced ).\n")));
1640 idx
= sb_skip_white (idx
+ 1, in
);
1647 dolen (idx
, in
, out
)
1656 sb_new (&stringout
);
1657 idx
= skip_openp (idx
, in
);
1658 idx
= get_and_process (idx
, in
, &stringout
);
1659 idx
= skip_closep (idx
, in
);
1660 sprintf (buffer
, "%d", stringout
.len
);
1661 sb_add_string (out
, buffer
);
1663 sb_kill (&stringout
);
1672 doinstr (idx
, in
, out
)
1686 idx
= skip_openp (idx
, in
);
1687 idx
= get_and_process (idx
, in
, &string
);
1688 idx
= sb_skip_comma (idx
, in
);
1689 idx
= get_and_process (idx
, in
, &search
);
1690 idx
= sb_skip_comma (idx
, in
);
1691 if (isdigit ((unsigned char) in
->ptr
[idx
]))
1693 idx
= exp_get_abs (_(".instr needs absolute expresson.\n"), idx
, in
, &start
);
1699 idx
= skip_closep (idx
, in
);
1701 for (i
= start
; i
< string
.len
; i
++)
1703 if (strncmp (string
.ptr
+ i
, search
.ptr
, search
.len
) == 0)
1709 sprintf (buffer
, "%d", res
);
1710 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
);
1737 if (len
< 0 || pos
< 0 ||
1739 || pos
+ len
> string
.len
)
1741 sb_add_string (out
, " ");
1745 sb_add_char (out
, '"');
1748 sb_add_char (out
, string
.ptr
[pos
++]);
1751 sb_add_char (out
, '"');
1757 /* 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
);
1875 more
= get_line (&line
);
1878 /* Find any label and pseudo op that we're intested in */
1883 fprintf (outfile
, "\n");
1886 && (line
.ptr
[0] == '*'
1887 || line
.ptr
[0] == '!'))
1889 /* MRI line comment. */
1890 fprintf (outfile
, "%s", sb_name (&line
));
1894 l
= grab_label (&line
, &label_in
);
1897 if (line
.ptr
[l
] == ':')
1899 while (ISWHITE (line
.ptr
[l
]) && l
< line
.len
)
1906 /* Munge the label, unless this is EQU or ASSIGN. */
1909 && (line
.ptr
[l
] == '.' || alternate
|| mri
))
1913 if (line
.ptr
[lx
] == '.')
1915 if (lx
+ 3 <= line
.len
1916 && strncasecmp ("EQU", line
.ptr
+ lx
, 3) == 0
1917 && (lx
+ 3 == line
.len
1918 || ! ISFIRSTCHAR (line
.ptr
[lx
+ 3])))
1920 else if (lx
+ 6 <= line
.len
1921 && strncasecmp ("ASSIGN", line
.ptr
+ lx
, 6) == 0
1922 && (lx
+ 6 == line
.len
1923 || ! ISFIRSTCHAR (line
.ptr
[lx
+ 6])))
1928 process_assigns (0, &label_in
, &label
);
1930 sb_add_sb (&label
, &label_in
);
1935 if (process_pseudo_op (l
, &line
, &acc
))
1941 else if (condass_on ())
1943 if (macro_op (l
, &line
))
1953 fprintf (outfile
, "%s:\t", sb_name (&label
));
1956 fprintf (outfile
, "\t");
1958 process_assigns (l
, &line
, &t1
);
1960 change_base (0, &t1
, &t2
);
1961 fprintf (outfile
, "%s\n", sb_name (&t2
));
1967 /* Only a label on this line */
1968 if (label
.len
&& condass_on())
1970 fprintf (outfile
, "%s:\n", sb_name (&label
));
1978 more
= get_line (&line
);
1981 if (!had_end
&& !mri
)
1982 WARNING ((stderr
, _("END missing from end of file.\n")));
1990 free_old_entry (ptr
)
1995 if (ptr
->type
== hash_string
)
1996 sb_kill(&ptr
->value
.s
);
2000 /* name: .ASSIGNA <value> */
2003 do_assigna (idx
, in
)
2011 process_assigns (idx
, in
, &tmp
);
2012 idx
= exp_get_abs (_(".ASSIGNA needs constant expression argument.\n"), 0, &tmp
, &val
);
2016 ERROR ((stderr
, _(".ASSIGNA without label.\n")));
2020 hash_entry
*ptr
= hash_create (&vars
, &label
);
2021 free_old_entry (ptr
);
2022 ptr
->type
= hash_integer
;
2028 /* name: .ASSIGNC <string> */
2031 do_assignc (idx
, in
)
2037 idx
= getstring (idx
, in
, &acc
);
2041 ERROR ((stderr
, _(".ASSIGNS without label.\n")));
2045 hash_entry
*ptr
= hash_create (&vars
, &label
);
2046 free_old_entry (ptr
);
2047 ptr
->type
= hash_string
;
2048 sb_new (&ptr
->value
.s
);
2049 sb_add_sb (&ptr
->value
.s
, &acc
);
2055 /* name: .REG (reg) */
2062 /* remove reg stuff from inside parens */
2065 idx
= skip_openp (idx
, in
);
2067 idx
= sb_skip_white (idx
, in
);
2069 while (idx
< in
->len
2072 : in
->ptr
[idx
] != ')'))
2074 sb_add_char (&what
, in
->ptr
[idx
]);
2077 hash_add_to_string_table (&assign_hash_table
, &label
, &what
, 1);
2083 condass_lookup_name (inbuf
, idx
, out
, warn
)
2091 sb_new (&condass_acc
);
2093 while (idx
< inbuf
->len
2094 && ISNEXTCHAR (inbuf
->ptr
[idx
]))
2096 sb_add_char (&condass_acc
, inbuf
->ptr
[idx
++]);
2099 if (inbuf
->ptr
[idx
] == '\'')
2101 ptr
= hash_lookup (&vars
, &condass_acc
);
2108 WARNING ((stderr
, _("Can't find preprocessor variable %s.\n"), sb_name (&condass_acc
)));
2112 sb_add_string (out
, "0");
2117 if (ptr
->type
== hash_integer
)
2120 sprintf (buffer
, "%d", ptr
->value
.i
);
2121 sb_add_string (out
, buffer
);
2125 sb_add_sb (out
, &ptr
->value
.s
);
2128 sb_kill (&condass_acc
);
2141 whatcond (idx
, in
, val
)
2148 idx
= sb_skip_white (idx
, in
);
2150 if (idx
+ 1 < in
->len
)
2156 a
= toupper ((unsigned char) p
[0]);
2157 b
= toupper ((unsigned char) p
[1]);
2158 if (a
== 'E' && b
== 'Q')
2160 else if (a
== 'N' && b
== 'E')
2162 else if (a
== 'L' && b
== 'T')
2164 else if (a
== 'L' && b
== 'E')
2166 else if (a
== 'G' && b
== 'T')
2168 else if (a
== 'G' && b
== 'E')
2173 ERROR ((stderr
, _("Comparison operator must be one of EQ, NE, LT, LE, GT or GE.\n")));
2176 idx
= sb_skip_white (idx
+ 2, in
);
2193 idx
= sb_skip_white (idx
, in
);
2195 if (in
->ptr
[idx
] == '"')
2199 /* This is a string comparision */
2200 idx
= getstring (idx
, in
, &acc_a
);
2201 idx
= whatcond (idx
, in
, &cond
);
2202 idx
= getstring (idx
, in
, &acc_b
);
2203 same
= acc_a
.len
== acc_b
.len
&& (strncmp (acc_a
.ptr
, acc_b
.ptr
, acc_a
.len
) == 0);
2205 if (cond
!= EQ
&& cond
!= NE
)
2207 ERROR ((stderr
, _("Comparison operator for strings must be EQ or NE\n")));
2211 res
= (cond
!= EQ
) ^ same
;
2214 /* This is a numeric expression */
2219 idx
= exp_get_abs (_("Conditional operator must have absolute operands.\n"), idx
, in
, &vala
);
2220 idx
= whatcond (idx
, in
, &cond
);
2221 idx
= sb_skip_white (idx
, in
);
2222 if (in
->ptr
[idx
] == '"')
2224 WARNING ((stderr
, _("String compared against expression.\n")));
2229 idx
= exp_get_abs (_("Conditional operator must have absolute operands.\n"), idx
, in
, &valb
);
2272 if (ifi
>= IFNESTING
)
2274 FATAL ((stderr
, _("AIF nesting unreasonable.\n")));
2277 ifstack
[ifi
].on
= ifstack
[ifi
-1].on
? istrue (idx
, in
) : 0;
2278 ifstack
[ifi
].hadelse
= 0;
2286 ifstack
[ifi
].on
= ifstack
[ifi
-1].on
? !ifstack
[ifi
].on
: 0;
2287 if (ifstack
[ifi
].hadelse
)
2289 ERROR ((stderr
, _("Multiple AELSEs in AIF.\n")));
2291 ifstack
[ifi
].hadelse
= 1;
2305 ERROR ((stderr
, _("AENDI without AIF.\n")));
2312 return ifstack
[ifi
].on
;
2315 /* MRI IFEQ, IFNE, IFLT, IFLE, IFGE, IFGT. */
2318 do_if (idx
, in
, cond
)
2326 if (ifi
>= IFNESTING
)
2328 FATAL ((stderr
, _("IF nesting unreasonable.\n")));
2331 idx
= exp_get_abs (_("Conditional operator must have absolute operands.\n"),
2336 case EQ
: res
= val
== 0; break;
2337 case NE
: res
= val
!= 0; break;
2338 case LT
: res
= val
< 0; break;
2339 case LE
: res
= val
<= 0; break;
2340 case GE
: res
= val
>= 0; break;
2341 case GT
: res
= val
> 0; break;
2345 ifstack
[ifi
].on
= ifstack
[ifi
-1].on
? res
: 0;
2346 ifstack
[ifi
].hadelse
= 0;
2349 /* Get a string for the MRI IFC or IFNC pseudo-ops. */
2352 get_mri_string (idx
, in
, val
, terminator
)
2358 idx
= sb_skip_white (idx
, in
);
2361 && in
->ptr
[idx
] == '\'')
2363 sb_add_char (val
, '\'');
2364 for (++idx
; idx
< in
->len
; ++idx
)
2366 sb_add_char (val
, in
->ptr
[idx
]);
2367 if (in
->ptr
[idx
] == '\'')
2371 || in
->ptr
[idx
] != '\'')
2375 idx
= sb_skip_white (idx
, in
);
2381 while (idx
< in
->len
2382 && in
->ptr
[idx
] != terminator
)
2384 sb_add_char (val
, in
->ptr
[idx
]);
2388 while (i
>= 0 && ISWHITE (val
->ptr
[i
]))
2396 /* MRI IFC, IFNC. */
2399 do_ifc (idx
, in
, ifnc
)
2408 if (ifi
>= IFNESTING
)
2410 FATAL ((stderr
, _("IF nesting unreasonable.\n")));
2416 idx
= get_mri_string (idx
, in
, &first
, ',');
2418 if (idx
>= in
->len
|| in
->ptr
[idx
] != ',')
2420 ERROR ((stderr
, _("Bad format for IF or IFNC.\n")));
2424 idx
= get_mri_string (idx
+ 1, in
, &second
, ';');
2426 res
= (first
.len
== second
.len
2427 && strncmp (first
.ptr
, second
.ptr
, first
.len
) == 0);
2431 ifstack
[ifi
].on
= ifstack
[ifi
-1].on
? res
: 0;
2432 ifstack
[ifi
].hadelse
= 0;
2440 ERROR ((stderr
, _("AENDR without a AREPEAT.\n")));
2442 ERROR ((stderr
, _("ENDR without a REPT.\n")));
2453 int line
= linecount ();
2461 process_assigns (idx
, in
, &exp
);
2462 doit
= istrue (0, &exp
);
2464 if (! buffer_and_nest ("AWHILE", "AENDW", &sub
, get_line
))
2465 FATAL ((stderr
, _("AWHILE without a AENDW at %d.\n"), line
- 1));
2480 int index
= include_next_index ();
2484 sb_add_sb (©
, &sub
);
2485 sb_add_sb (©
, in
);
2486 sb_add_string (©
, "\n");
2487 sb_add_sb (©
, &sub
);
2488 sb_add_string (©
, "\t.AENDW\n");
2489 /* Push another WHILE */
2490 include_buf (&exp
, ©
, include_while
, index
);
2503 ERROR ((stderr
, _("AENDW without a AENDW.\n")));
2509 Pop things off the include stack until the type and index changes */
2514 include_type type
= sp
->type
;
2515 if (type
== include_repeat
2516 || type
== include_while
2517 || type
== include_macro
)
2519 int index
= sp
->index
;
2521 while (sp
->index
== index
2522 && sp
->type
== type
)
2532 do_arepeat (idx
, in
)
2536 int line
= linecount ();
2537 sb exp
; /* buffer with expression in it */
2538 sb copy
; /* expanded repeat block */
2539 sb sub
; /* contents of AREPEAT */
2547 process_assigns (idx
, in
, &exp
);
2548 idx
= exp_get_abs (_("AREPEAT must have absolute operand.\n"), 0, &exp
, &rc
);
2550 ret
= buffer_and_nest ("AREPEAT", "AENDR", &sub
, get_line
);
2552 ret
= buffer_and_nest ("REPT", "ENDR", &sub
, get_line
);
2554 FATAL ((stderr
, _("AREPEAT without a AENDR at %d.\n"), line
- 1));
2557 /* Push back the text following the repeat, and another repeat block
2568 int index
= include_next_index ();
2569 sb_add_sb (©
, &sub
);
2573 sprintf (buffer
, "\t.AREPEAT %d\n", rc
- 1);
2575 sprintf (buffer
, "\tREPT %d\n", rc
- 1);
2576 sb_add_string (©
, buffer
);
2577 sb_add_sb (©
, &sub
);
2579 sb_add_string (©
, " .AENDR\n");
2581 sb_add_string (©
, " ENDR\n");
2584 include_buf (&exp
, ©
, include_repeat
, index
);
2596 ERROR ((stderr
, _(".ENDM without a matching .MACRO.\n")));
2599 /* MRI IRP pseudo-op. */
2602 do_irp (idx
, in
, irpc
)
2612 err
= expand_irp (irpc
, idx
, in
, &out
, get_line
, comment_char
);
2614 ERROR ((stderr
, "%s\n", err
));
2616 fprintf (outfile
, "%s", sb_terminate (&out
));
2621 /* MACRO PROCESSING */
2623 /* Parse off LOCAL n1, n2,... Invent a label name for it */
2626 do_local (idx
, line
)
2627 int idx ATTRIBUTE_UNUSED
;
2628 sb
*line ATTRIBUTE_UNUSED
;
2630 ERROR ((stderr
, _("LOCAL outside of MACRO")));
2639 int line
= linecount ();
2641 err
= define_macro (idx
, in
, &label
, get_line
, (const char **) NULL
);
2643 ERROR ((stderr
, _("macro at line %d: %s\n"), line
- 1, err
));
2655 if (! macro_defined
)
2659 if (! check_macro (in
->ptr
+ idx
, &out
, comment_char
, &err
, NULL
))
2663 ERROR ((stderr
, "%s\n", err
));
2666 sb_add_string (&name
, _("macro expansion"));
2668 include_buf (&name
, &out
, include_macro
, include_next_index ());
2676 /* STRING HANDLING */
2679 getstring (idx
, in
, acc
)
2684 idx
= sb_skip_white (idx
, in
);
2686 while (idx
< in
->len
2687 && (in
->ptr
[idx
] == '"'
2688 || in
->ptr
[idx
] == '<'
2689 || (in
->ptr
[idx
] == '\'' && alternate
)))
2691 if (in
->ptr
[idx
] == '<')
2693 if (alternate
|| mri
)
2697 while ((in
->ptr
[idx
] != '>' || nest
)
2700 if (in
->ptr
[idx
] == '!')
2703 sb_add_char (acc
, in
->ptr
[idx
++]);
2706 if (in
->ptr
[idx
] == '>')
2708 if (in
->ptr
[idx
] == '<')
2710 sb_add_char (acc
, in
->ptr
[idx
++]);
2718 idx
= exp_get_abs (_("Character code in string must be absolute expression.\n"),
2720 sb_add_char (acc
, code
);
2722 if (in
->ptr
[idx
] != '>')
2723 ERROR ((stderr
, _("Missing > for character code.\n")));
2727 else if (in
->ptr
[idx
] == '"' || in
->ptr
[idx
] == '\'')
2729 char tchar
= in
->ptr
[idx
];
2731 while (idx
< in
->len
)
2733 if (alternate
&& in
->ptr
[idx
] == '!')
2736 sb_add_char (acc
, in
->ptr
[idx
++]);
2739 if (in
->ptr
[idx
] == tchar
)
2742 if (idx
>= in
->len
|| in
->ptr
[idx
] != tchar
)
2745 sb_add_char (acc
, in
->ptr
[idx
]);
2755 /* .SDATA[C|Z] <string> */
2759 do_sdata (idx
, in
, type
)
2768 fprintf (outfile
, ".byte\t");
2770 while (!eol (idx
, in
))
2774 idx
= sb_skip_white (idx
, in
);
2775 while (!eol (idx
, in
))
2777 pidx
= idx
= get_any_string (idx
, in
, &acc
, 0, 1);
2782 ERROR ((stderr
, _("string for SDATAC longer than 255 characters (%d).\n"), acc
.len
));
2784 fprintf (outfile
, "%d", acc
.len
);
2788 for (i
= 0; i
< acc
.len
; i
++)
2792 fprintf (outfile
, ",");
2794 fprintf (outfile
, "%d", acc
.ptr
[i
]);
2801 fprintf (outfile
, ",");
2802 fprintf (outfile
, "0");
2804 idx
= sb_skip_comma (idx
, in
);
2805 if (idx
== pidx
) break;
2807 if (!alternate
&& in
->ptr
[idx
] != ',' && idx
!= in
->len
)
2809 fprintf (outfile
, "\n");
2810 ERROR ((stderr
, _("illegal character in SDATA line (0x%x).\n"), in
->ptr
[idx
]));
2816 fprintf (outfile
, "\n");
2819 /* .SDATAB <count> <string> */
2831 idx
= exp_get_abs (_("Must have absolute SDATAB repeat count.\n"), idx
, in
, &repeat
);
2834 ERROR ((stderr
, _("Must have positive SDATAB repeat count (%d).\n"), repeat
));
2838 idx
= sb_skip_comma (idx
, in
);
2839 idx
= getstring (idx
, in
, &acc
);
2841 for (i
= 0; i
< repeat
; i
++)
2844 fprintf (outfile
, "\t");
2845 fprintf (outfile
, ".byte\t");
2846 sb_print (outfile
, &acc
);
2847 fprintf (outfile
, "\n");
2857 FILE *newone
= fopen (name
, "r");
2861 if (isp
== MAX_INCLUDES
)
2862 FATAL ((stderr
, _("Unreasonable include depth (%ld).\n"), (long) isp
));
2865 sp
->handle
= newone
;
2868 sb_add_string (&sp
->name
, name
);
2871 sp
->pushback_index
= 0;
2872 sp
->type
= include_file
;
2874 sb_new (&sp
->pushback
);
2879 do_include (idx
, in
)
2885 include_path
*includes
;
2891 idx
= getstring (idx
, in
, &t
);
2894 idx
= sb_skip_white (idx
, in
);
2895 while (idx
< in
->len
&& ! ISWHITE (in
->ptr
[idx
]))
2897 sb_add_char (&t
, in
->ptr
[idx
]);
2902 for (includes
= paths_head
; includes
; includes
= includes
->next
)
2905 sb_add_sb (&cat
, &includes
->path
);
2906 sb_add_char (&cat
, '/');
2907 sb_add_sb (&cat
, &t
);
2908 if (new_file (sb_name (&cat
)))
2915 if (! new_file (sb_name (&t
)))
2916 FATAL ((stderr
, _("Can't open include file `%s'.\n"), sb_name (&t
)));
2925 if (sp
!= include_stack
)
2928 fclose (sp
->handle
);
2933 /* Get the next character from the include stack. If there's anything
2934 in the pushback buffer, take that first. If we're at eof, pop from
2935 the stack and try again. Keep the linecount up to date. */
2942 if (sp
->pushback
.len
!= sp
->pushback_index
)
2944 r
= (char) (sp
->pushback
.ptr
[sp
->pushback_index
++]);
2945 /* When they've all gone, reset the pointer */
2946 if (sp
->pushback_index
== sp
->pushback
.len
)
2948 sp
->pushback
.len
= 0;
2949 sp
->pushback_index
= 0;
2952 else if (sp
->handle
)
2954 r
= getc (sp
->handle
);
2959 if (r
== EOF
&& isp
)
2963 while (r
== EOF
&& isp
)
2981 return sp
->linecount
;
2985 include_next_index ()
2989 && index
> MAX_REASONABLE
)
2990 FATAL ((stderr
, _("Unreasonable expansion (-u turns off check).\n")));
2995 /* Initialize the chartype vector. */
3001 for (x
= 0; x
< 256; x
++)
3003 if (isalpha (x
) || x
== '_' || x
== '$')
3004 chartype
[x
] |= FIRSTBIT
;
3006 if (mri
&& x
== '.')
3007 chartype
[x
] |= FIRSTBIT
;
3009 if (isdigit (x
) || isalpha (x
) || x
== '_' || x
== '$')
3010 chartype
[x
] |= NEXTBIT
;
3012 if (x
== ' ' || x
== '\t' || x
== ',' || x
== '"' || x
== ';'
3013 || x
== '"' || x
== '<' || x
== '>' || x
== ')' || x
== '(')
3014 chartype
[x
] |= SEPBIT
;
3016 if (x
== 'b' || x
== 'B'
3017 || x
== 'q' || x
== 'Q'
3018 || x
== 'h' || x
== 'H'
3019 || x
== 'd' || x
== 'D')
3020 chartype
[x
] |= BASEBIT
;
3022 if (x
== ' ' || x
== '\t')
3023 chartype
[x
] |= WHITEBIT
;
3025 if (x
== comment_char
)
3026 chartype
[x
] |= COMMENTBIT
;
3032 /* What to do with all the keywords */
3033 #define PROCESS 0x1000 /* Run substitution over the line */
3034 #define LAB 0x2000 /* Spit out the label */
3036 #define K_EQU (PROCESS|1)
3037 #define K_ASSIGN (PROCESS|2)
3038 #define K_REG (PROCESS|3)
3039 #define K_ORG (PROCESS|4)
3040 #define K_RADIX (PROCESS|5)
3041 #define K_DATA (LAB|PROCESS|6)
3042 #define K_DATAB (LAB|PROCESS|7)
3043 #define K_SDATA (LAB|PROCESS|8)
3044 #define K_SDATAB (LAB|PROCESS|9)
3045 #define K_SDATAC (LAB|PROCESS|10)
3046 #define K_SDATAZ (LAB|PROCESS|11)
3047 #define K_RES (LAB|PROCESS|12)
3048 #define K_SRES (LAB|PROCESS|13)
3049 #define K_SRESC (LAB|PROCESS|14)
3050 #define K_SRESZ (LAB|PROCESS|15)
3051 #define K_EXPORT (LAB|PROCESS|16)
3052 #define K_GLOBAL (LAB|PROCESS|17)
3053 #define K_PRINT (LAB|PROCESS|19)
3054 #define K_FORM (LAB|PROCESS|20)
3055 #define K_HEADING (LAB|PROCESS|21)
3056 #define K_PAGE (LAB|PROCESS|22)
3057 #define K_IMPORT (LAB|PROCESS|23)
3058 #define K_PROGRAM (LAB|PROCESS|24)
3059 #define K_END (PROCESS|25)
3060 #define K_INCLUDE (PROCESS|26)
3061 #define K_IGNORED (PROCESS|27)
3062 #define K_ASSIGNA (PROCESS|28)
3063 #define K_ASSIGNC (29)
3064 #define K_AIF (PROCESS|30)
3065 #define K_AELSE (PROCESS|31)
3066 #define K_AENDI (PROCESS|32)
3067 #define K_AREPEAT (PROCESS|33)
3068 #define K_AENDR (PROCESS|34)
3069 #define K_AWHILE (35)
3070 #define K_AENDW (PROCESS|36)
3071 #define K_EXITM (37)
3072 #define K_MACRO (PROCESS|38)
3074 #define K_ALIGN (PROCESS|LAB|40)
3075 #define K_ALTERNATE (41)
3076 #define K_DB (LAB|PROCESS|42)
3077 #define K_DW (LAB|PROCESS|43)
3078 #define K_DL (LAB|PROCESS|44)
3079 #define K_LOCAL (45)
3080 #define K_IFEQ (PROCESS|46)
3081 #define K_IFNE (PROCESS|47)
3082 #define K_IFLT (PROCESS|48)
3083 #define K_IFLE (PROCESS|49)
3084 #define K_IFGE (PROCESS|50)
3085 #define K_IFGT (PROCESS|51)
3086 #define K_IFC (PROCESS|52)
3087 #define K_IFNC (PROCESS|53)
3088 #define K_IRP (PROCESS|54)
3089 #define K_IRPC (PROCESS|55)
3099 static struct keyword kinfo
[] =
3101 { "EQU", K_EQU
, 0 },
3102 { "ALTERNATE", K_ALTERNATE
, 0 },
3103 { "ASSIGN", K_ASSIGN
, 0 },
3104 { "REG", K_REG
, 0 },
3105 { "ORG", K_ORG
, 0 },
3106 { "RADIX", K_RADIX
, 0 },
3107 { "DATA", K_DATA
, 0 },
3111 { "DATAB", K_DATAB
, 0 },
3112 { "SDATA", K_SDATA
, 0 },
3113 { "SDATAB", K_SDATAB
, 0 },
3114 { "SDATAZ", K_SDATAZ
, 0 },
3115 { "SDATAC", K_SDATAC
, 0 },
3116 { "RES", K_RES
, 0 },
3117 { "SRES", K_SRES
, 0 },
3118 { "SRESC", K_SRESC
, 0 },
3119 { "SRESZ", K_SRESZ
, 0 },
3120 { "EXPORT", K_EXPORT
, 0 },
3121 { "GLOBAL", K_GLOBAL
, 0 },
3122 { "PRINT", K_PRINT
, 0 },
3123 { "FORM", K_FORM
, 0 },
3124 { "HEADING", K_HEADING
, 0 },
3125 { "PAGE", K_PAGE
, 0 },
3126 { "PROGRAM", K_IGNORED
, 0 },
3127 { "END", K_END
, 0 },
3128 { "INCLUDE", K_INCLUDE
, 0 },
3129 { "ASSIGNA", K_ASSIGNA
, 0 },
3130 { "ASSIGNC", K_ASSIGNC
, 0 },
3131 { "AIF", K_AIF
, 0 },
3132 { "AELSE", K_AELSE
, 0 },
3133 { "AENDI", K_AENDI
, 0 },
3134 { "AREPEAT", K_AREPEAT
, 0 },
3135 { "AENDR", K_AENDR
, 0 },
3136 { "EXITM", K_EXITM
, 0 },
3137 { "MACRO", K_MACRO
, 0 },
3138 { "ENDM", K_ENDM
, 0 },
3139 { "AWHILE", K_AWHILE
, 0 },
3140 { "ALIGN", K_ALIGN
, 0 },
3141 { "AENDW", K_AENDW
, 0 },
3142 { "ALTERNATE", K_ALTERNATE
, 0 },
3143 { "LOCAL", K_LOCAL
, 0 },
3147 /* Although the conditional operators are handled by gas, we need to
3148 handle them here as well, in case they are used in a recursive
3149 macro to end the recursion. */
3151 static struct keyword mrikinfo
[] =
3153 { "IFEQ", K_IFEQ
, 0 },
3154 { "IFNE", K_IFNE
, 0 },
3155 { "IFLT", K_IFLT
, 0 },
3156 { "IFLE", K_IFLE
, 0 },
3157 { "IFGE", K_IFGE
, 0 },
3158 { "IFGT", K_IFGT
, 0 },
3159 { "IFC", K_IFC
, 0 },
3160 { "IFNC", K_IFNC
, 0 },
3161 { "ELSEC", K_AELSE
, 0 },
3162 { "ENDC", K_AENDI
, 0 },
3163 { "MEXIT", K_EXITM
, 0 },
3164 { "REPT", K_AREPEAT
, 0 },
3165 { "IRP", K_IRP
, 0 },
3166 { "IRPC", K_IRPC
, 0 },
3167 { "ENDR", K_AENDR
, 0 },
3171 /* Look for a pseudo op on the line. If one's there then call
3175 process_pseudo_op (idx
, line
, acc
)
3182 if (line
->ptr
[idx
] == '.' || alternate
|| mri
)
3184 /* Scan forward and find pseudo name */
3190 if (line
->ptr
[idx
] == '.')
3192 in
= line
->ptr
+ idx
;
3197 while (idx
< line
->len
&& *e
&& ISFIRSTCHAR (*e
))
3199 sb_add_char (acc
, *e
);
3204 ptr
= hash_lookup (&keyword_hash_table
, acc
);
3209 /* This one causes lots of pain when trying to preprocess
3211 WARNING ((stderr
, _("Unrecognised pseudo op `%s'.\n"), sb_name (acc
)));
3215 if (ptr
->value
.i
& LAB
)
3216 { /* output the label */
3219 fprintf (outfile
, "%s:\t", sb_name (&label
));
3222 fprintf (outfile
, "\t");
3225 if (mri
&& ptr
->value
.i
== K_END
)
3230 sb_add_buffer (&t
, line
->ptr
+ oidx
, idx
- oidx
);
3231 fprintf (outfile
, "\t%s", sb_name (&t
));
3235 if (ptr
->value
.i
& PROCESS
)
3237 /* Polish the rest of the line before handling the pseudo op */
3239 strip_comments(line
);
3242 process_assigns (idx
, line
, acc
);
3244 change_base (0, acc
, line
);
3249 switch (ptr
->value
.i
)
3265 switch (ptr
->value
.i
)
3269 macro_init (1, mri
, 0, exp_get_abs
);
3278 ERROR ((stderr
, _("ORG command not allowed.\n")));
3284 do_data (idx
, line
, 1);
3287 do_data (idx
, line
, 2);
3290 do_data (idx
, line
, 4);
3293 do_data (idx
, line
, 0);
3296 do_datab (idx
, line
);
3299 do_sdata (idx
, line
, 0);
3302 do_sdatab (idx
, line
);
3305 do_sdata (idx
, line
, 'c');
3308 do_sdata (idx
, line
, 'z');
3311 do_assign (0, 0, line
);
3317 do_arepeat (idx
, line
);
3323 do_awhile (idx
, line
);
3329 do_assign (1, idx
, line
);
3332 do_align (idx
, line
);
3335 do_res (idx
, line
, 0);
3338 do_res (idx
, line
, 's');
3341 do_include (idx
, line
);
3344 do_local (idx
, line
);
3347 do_macro (idx
, line
);
3353 do_res (idx
, line
, 'c');
3356 do_print (idx
, line
);
3359 do_form (idx
, line
);
3362 do_heading (idx
, line
);
3374 do_res (idx
, line
, 'z');
3382 do_assigna (idx
, line
);
3385 do_assignc (idx
, line
);
3394 do_if (idx
, line
, EQ
);
3397 do_if (idx
, line
, NE
);
3400 do_if (idx
, line
, LT
);
3403 do_if (idx
, line
, LE
);
3406 do_if (idx
, line
, GE
);
3409 do_if (idx
, line
, GT
);
3412 do_ifc (idx
, line
, 0);
3415 do_ifc (idx
, line
, 1);
3418 do_irp (idx
, line
, 0);
3421 do_irp (idx
, line
, 1);
3431 /* Add a keyword to the hash table. */
3434 add_keyword (name
, code
)
3442 sb_add_string (&label
, name
);
3444 hash_add_to_int_table (&keyword_hash_table
, &label
, code
);
3447 for (j
= 0; name
[j
]; j
++)
3448 sb_add_char (&label
, name
[j
] - 'A' + 'a');
3449 hash_add_to_int_table (&keyword_hash_table
, &label
, code
);
3454 /* Build the keyword hash table - put each keyword in the table twice,
3455 once upper and once lower case.*/
3462 for (i
= 0; kinfo
[i
].name
; i
++)
3463 add_keyword (kinfo
[i
].name
, kinfo
[i
].code
);
3467 for (i
= 0; mrikinfo
[i
].name
; i
++)
3468 add_keyword (mrikinfo
[i
].name
, mrikinfo
[i
].code
);
3492 sb_add_char (&value
, *string
);
3495 exp_get_abs (_("Invalid expression on command line.\n"), 0, &value
, &res
);
3499 sb_add_char (&label
, *string
);
3504 ptr
= hash_create (&vars
, &label
);
3505 free_old_entry (ptr
);
3506 ptr
->type
= hash_integer
;
3512 /* The list of long options. */
3513 static struct option long_options
[] =
3515 { "alternate", no_argument
, 0, 'a' },
3516 { "include", required_argument
, 0, 'I' },
3517 { "commentchar", required_argument
, 0, 'c' },
3518 { "copysource", no_argument
, 0, 's' },
3519 { "debug", no_argument
, 0, 'd' },
3520 { "help", no_argument
, 0, 'h' },
3521 { "mri", no_argument
, 0, 'M' },
3522 { "output", required_argument
, 0, 'o' },
3523 { "print", no_argument
, 0, 'p' },
3524 { "unreasonable", no_argument
, 0, 'u' },
3525 { "version", no_argument
, 0, 'v' },
3526 { "define", required_argument
, 0, 'd' },
3527 { NULL
, no_argument
, 0, 0 }
3530 /* Show a usage message and exit. */
3532 show_usage (file
, status
)
3538 [-a] [--alternate] enter alternate macro mode\n\
3539 [-c char] [--commentchar char] change the comment character from !\n\
3540 [-d] [--debug] print some debugging info\n\
3541 [-h] [--help] print this message\n\
3542 [-M] [--mri] enter MRI compatibility mode\n\
3543 [-o out] [--output out] set the output file\n\
3544 [-p] [--print] print line numbers\n"), program_name
);
3546 [-s] [--copysource] copy source through as comments \n\
3547 [-u] [--unreasonable] allow unreasonable nesting\n\
3548 [-v] [--version] print the program version\n\
3549 [-Dname=value] create preprocessor variable called name, with value\n\
3550 [-Ipath] add to include path list\n\
3553 printf (_("\nReport bugs to bug-gnu-utils@gnu.org\n"));
3557 /* Display a help message and exit. */
3561 printf (_("%s: Gnu Assembler Macro Preprocessor\n"),
3563 show_usage (stdout
, 0);
3578 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
3579 setlocale (LC_MESSAGES
, "");
3581 bindtextdomain (PACKAGE
, LOCALEDIR
);
3582 textdomain (PACKAGE
);
3584 program_name
= argv
[0];
3585 xmalloc_set_program_name (program_name
);
3587 hash_new_table (101, &keyword_hash_table
);
3588 hash_new_table (101, &assign_hash_table
);
3589 hash_new_table (101, &vars
);
3593 while ((opt
= getopt_long (argc
, argv
, "I:sdhavc:upo:D:M", long_options
,
3607 include_path
*p
= (include_path
*) xmalloc (sizeof (include_path
));
3610 sb_add_string (&p
->path
, optarg
);
3612 paths_tail
->next
= p
;
3619 print_line_number
= 1;
3622 comment_char
= optarg
[0];
3644 /* This output is intended to follow the GNU standards document. */
3645 printf (_("GNU assembler pre-processor %s\n"), program_version
);
3646 printf (_("Copyright 1996 Free Software Foundation, Inc.\n"));
3648 This program is free software; you may redistribute it under the terms of\n\
3649 the GNU General Public License. This program has absolutely no warranty.\n"));
3655 show_usage (stderr
, 1);
3662 macro_init (alternate
, mri
, 0, exp_get_abs
);
3665 outfile
= fopen (out_name
, "w");
3668 fprintf (stderr
, _("%s: Can't open output file `%s'.\n"),
3669 program_name
, out_name
);
3681 /* Process all the input files */
3683 while (optind
< argc
)
3685 if (new_file (argv
[optind
]))
3691 fprintf (stderr
, _("%s: Can't open input file `%s'.\n"),
3692 program_name
, argv
[optind
]);
3702 /* This function is used because an abort in some of the other files
3703 may be compiled into as_abort because they include as.h. */
3706 as_abort (file
, line
, fn
)
3707 const char *file
, *fn
;
3710 fprintf (stderr
, _("Internal error, aborting at %s line %d"), file
, line
);
3712 fprintf (stderr
, " in %s", fn
);
3713 fprintf (stderr
, _("\nPlease report this bug.\n"));