1 /* gasp.c - Gnu assembler preprocessor main program.
2 Copyright (C) 1994, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
4 Written by Steve and Judy Chamberlain of Cygnus Support,
7 This file is part of GASP, the GNU Assembler Preprocessor.
9 GASP is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
14 GASP is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GASP; see the file COPYING. If not, write to the Free
21 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.
30 gasp [-sdhau] [-c char] [-o <outfile>] <infile>*
32 -s copy source to output
33 -c <char> comments are started with <char> instead of !
34 -u allow unreasonable stuff
36 -d print debugging stats
37 -s semi colons start comments
38 -a use alternate syntax
39 Pseudo ops can start with or without a .
40 Labels have to be in first column.
41 -I specify include dir
42 Macro arg parameters subsituted by name, don't need the &.
43 String can start with ' too.
44 Strings can be surrounded by <..>
45 A %<exp> in a string evaluates the expression
46 Literal char in a string with !
62 #ifdef NEED_MALLOC_DECLARATION
63 extern char *malloc ();
67 #include "libiberty.h"
72 char *program_version
= "1.2";
74 /* This is normally declared in as.h, but we don't include that. We
75 need the function because other files linked with gasp.c might call
77 extern void as_abort
PARAMS ((const char *, int, const char *));
79 /* The default obstack chunk size. If we set this to zero, the
80 obstack code will use whatever will fit in a 4096 byte block. This
81 is used by the hash table code used by macro.c. */
84 #define MAX_INCLUDES 30 /* Maximum include depth */
85 #define MAX_REASONABLE 1000 /* Maximum number of expansions */
87 int unreasonable
; /* -u on command line */
88 int stats
; /* -d on command line */
89 int print_line_number
; /* -p flag on command line */
90 int copysource
; /* -c flag on command line */
91 int warnings
; /* Number of WARNINGs generated so far. */
92 int errors
; /* Number of ERRORs generated so far. */
93 int fatals
; /* Number of fatal ERRORs generated so far (either 0 or 1). */
94 int alternate
= 0; /* -a on command line */
95 int mri
= 0; /* -M on command line */
96 char comment_char
= '!';
97 int radix
= 10; /* Default radix */
99 int had_end
; /* Seen .END */
101 /* The output stream */
104 /* the attributes of each character are stored as a bit pattern
105 chartype, which gives us quick tests. */
112 #define COMMENTBIT 16
114 #define ISCOMMENTCHAR(x) (chartype[(unsigned char)(x)] & COMMENTBIT)
115 #define ISFIRSTCHAR(x) (chartype[(unsigned char)(x)] & FIRSTBIT)
116 #define ISNEXTCHAR(x) (chartype[(unsigned char)(x)] & NEXTBIT)
117 #define ISSEP(x) (chartype[(unsigned char)(x)] & SEPBIT)
118 #define ISWHITE(x) (chartype[(unsigned char)(x)] & WHITEBIT)
119 #define ISBASE(x) (chartype[(unsigned char)(x)] & BASEBIT)
120 static char chartype
[256];
123 /* Conditional assembly uses the `ifstack'. Each aif pushes another
124 entry onto the stack, and sets the on flag if it should. The aelse
125 sets hadelse, and toggles on. An aend pops a level. We limit to
126 100 levels of nesting, not because we're facists pigs with read
127 only minds, but because more than 100 levels of nesting is probably
128 a bug in the user's macro structure. */
130 #define IFNESTING 100
133 int on
; /* is the level being output */
134 int hadelse
; /* has an aelse been seen */
139 /* The final and intermediate results of expression evaluation are kept in
140 exp_t's. Note that a symbol is not an sb, but a pointer into the input
141 line. It must be coped somewhere safe before the next line is read in. */
152 int value
; /* constant part */
153 symbol add_symbol
; /* name part */
154 symbol sub_symbol
; /* name part */
159 /* Hashing is done in a pretty standard way. A hash_table has a
160 pointer to a vector of pointers to hash_entrys, and the size of the
161 vector. A hash_entry contains a union of all the info we like to
162 store in hash table. If there is a hash collision, hash_entries
163 with the same hash are kept in a chain. */
165 /* What the data in a hash_entry means */
168 hash_integer
, /* name->integer mapping */
169 hash_string
, /* name->string mapping */
170 hash_macro
, /* name is a macro */
171 hash_formal
/* name is a formal argument */
176 sb key
; /* symbol name */
177 hash_type type
; /* symbol meaning */
182 struct macro_struct
*m
;
183 struct formal_struct
*f
;
185 struct hs
*next
; /* next hash_entry with same hash key */
195 /* Structures used to store macros.
197 Each macro knows its name and included text. It gets built with a
198 list of formal arguments, and also keeps a hash table which points
199 into the list to speed up formal search. Each formal knows its
200 name and its default value. Each time the macro is expanded, the
201 formals get the actual values attatched to them. */
203 /* describe the formal arguments to a macro */
205 typedef struct formal_struct
207 struct formal_struct
*next
; /* next formal in list */
208 sb name
; /* name of the formal */
209 sb def
; /* the default value */
210 sb actual
; /* the actual argument (changed on each expansion) */
211 int index
; /* the index of the formal 0..formal_count-1 */
215 /* describe the macro. */
217 typedef struct macro_struct
219 sb sub
; /* substitution text. */
220 int formal_count
; /* number of formal args. */
221 formal_entry
*formals
; /* pointer to list of formal_structs */
222 hash_table formal_hash
; /* hash table of formals. */
226 /* how we nest files and expand macros etc.
228 we keep a stack of of include_stack structs. each include file
229 pushes a new level onto the stack. we keep an sb with a pushback
230 too. unget chars are pushed onto the pushback sb, getchars first
231 checks the pushback sb before reading from the input stream.
233 small things are expanded by adding the text of the item onto the
234 pushback sb. larger items are grown by pushing a new level and
235 allocating the entire pushback buf for the item. each time
236 something like a macro is expanded, the stack index is changed. we
237 can then perform an exitm by popping all entries off the stack with
238 the same stack index. if we're being reasonable, we can detect
239 recusive expansion by checking the index is reasonably small.
244 include_file
, include_repeat
, include_while
, include_macro
249 sb pushback
; /* current pushback stream */
250 int pushback_index
; /* next char to read from stream */
251 FILE *handle
; /* open file */
252 sb name
; /* name of file */
253 int linecount
; /* number of lines read so far */
255 int index
; /* index of this layer */
257 include_stack
[MAX_INCLUDES
];
259 struct include_stack
*sp
;
260 #define isp (sp - include_stack)
262 /* Include file list */
264 typedef struct include_path
266 struct include_path
*next
;
270 include_path
*paths_head
;
271 include_path
*paths_tail
;
274 static void quit
PARAMS ((void));
275 static void hash_new_table
PARAMS ((int, hash_table
*));
276 static int hash
PARAMS ((sb
*));
277 static hash_entry
*hash_create
PARAMS ((hash_table
*, sb
*));
278 static void hash_add_to_string_table
PARAMS ((hash_table
*, sb
*, sb
*, int));
279 static void hash_add_to_int_table
PARAMS ((hash_table
*, sb
*, int));
280 static hash_entry
*hash_lookup
PARAMS ((hash_table
*, sb
*));
281 static void checkconst
PARAMS ((int, exp_t
*));
282 static int sb_strtol
PARAMS ((int, sb
*, int, int *));
283 static int level_0
PARAMS ((int, sb
*, exp_t
*));
284 static int level_1
PARAMS ((int, sb
*, exp_t
*));
285 static int level_2
PARAMS ((int, sb
*, exp_t
*));
286 static int level_3
PARAMS ((int, sb
*, exp_t
*));
287 static int level_4
PARAMS ((int, sb
*, exp_t
*));
288 static int level_5
PARAMS ((int, sb
*, exp_t
*));
289 static int exp_parse
PARAMS ((int, sb
*, exp_t
*));
290 static void exp_string
PARAMS ((exp_t
*, sb
*));
291 static int exp_get_abs
PARAMS ((const char *, int, sb
*, int *));
293 static void strip_comments
PARAMS ((sb
*));
295 static void unget
PARAMS ((int));
296 static void include_buf
PARAMS ((sb
*, sb
*, include_type
, int));
297 static void include_print_where_line
PARAMS ((FILE *));
298 static void include_print_line
PARAMS ((FILE *));
299 static int get_line
PARAMS ((sb
*));
300 static int grab_label
PARAMS ((sb
*, sb
*));
301 static void change_base
PARAMS ((int, sb
*, sb
*));
302 static void do_end
PARAMS ((sb
*));
303 static void do_assign
PARAMS ((int, int, sb
*));
304 static void do_radix
PARAMS ((sb
*));
305 static int get_opsize
PARAMS ((int, sb
*, int *));
306 static int eol
PARAMS ((int, sb
*));
307 static void do_data
PARAMS ((int, sb
*, int));
308 static void do_datab
PARAMS ((int, sb
*));
309 static void do_align
PARAMS ((int, sb
*));
310 static void do_res
PARAMS ((int, sb
*, int));
311 static void do_export
PARAMS ((sb
*));
312 static void do_print
PARAMS ((int, sb
*));
313 static void do_heading
PARAMS ((int, sb
*));
314 static void do_page
PARAMS ((void));
315 static void do_form
PARAMS ((int, sb
*));
316 static int get_any_string
PARAMS ((int, sb
*, sb
*, int, int));
317 static int skip_openp
PARAMS ((int, sb
*));
318 static int skip_closep
PARAMS ((int, sb
*));
319 static int dolen
PARAMS ((int, sb
*, sb
*));
320 static int doinstr
PARAMS ((int, sb
*, sb
*));
321 static int dosubstr
PARAMS ((int, sb
*, sb
*));
322 static void process_assigns
PARAMS ((int, sb
*, sb
*));
323 static int get_and_process
PARAMS ((int, sb
*, sb
*));
324 static void process_file
PARAMS ((void));
325 static void free_old_entry
PARAMS ((hash_entry
*));
326 static void do_assigna
PARAMS ((int, sb
*));
327 static void do_assignc
PARAMS ((int, sb
*));
328 static void do_reg
PARAMS ((int, sb
*));
329 static int condass_lookup_name
PARAMS ((sb
*, int, sb
*, int));
330 static int whatcond
PARAMS ((int, sb
*, int *));
331 static int istrue
PARAMS ((int, sb
*));
332 static void do_aif
PARAMS ((int, sb
*));
333 static void do_aelse
PARAMS ((void));
334 static void do_aendi
PARAMS ((void));
335 static int condass_on
PARAMS ((void));
336 static void do_if
PARAMS ((int, sb
*, int));
337 static int get_mri_string
PARAMS ((int, sb
*, sb
*, int));
338 static void do_ifc
PARAMS ((int, sb
*, int));
339 static void do_aendr
PARAMS ((void));
340 static void do_awhile
PARAMS ((int, sb
*));
341 static void do_aendw
PARAMS ((void));
342 static void do_exitm
PARAMS ((void));
343 static void do_arepeat
PARAMS ((int, sb
*));
344 static void do_endm
PARAMS ((void));
345 static void do_irp
PARAMS ((int, sb
*, int));
346 static void do_local
PARAMS ((int, sb
*));
347 static void do_macro
PARAMS ((int, sb
*));
348 static int macro_op
PARAMS ((int, sb
*));
349 static int getstring
PARAMS ((int, sb
*, sb
*));
350 static void do_sdata
PARAMS ((int, sb
*, int));
351 static void do_sdatab
PARAMS ((int, sb
*));
352 static int new_file
PARAMS ((const char *));
353 static void do_include
PARAMS ((int, sb
*));
354 static void include_pop
PARAMS ((void));
355 static int get
PARAMS ((void));
356 static int linecount
PARAMS ((void));
357 static int include_next_index
PARAMS ((void));
358 static void chartype_init
PARAMS ((void));
359 static int process_pseudo_op
PARAMS ((int, sb
*, sb
*));
360 static void add_keyword
PARAMS ((const char *, int));
361 static void process_init
PARAMS ((void));
362 static void do_define
PARAMS ((const char *));
363 static void show_usage
PARAMS ((FILE *, int));
364 static void show_help
PARAMS ((void));
367 do { include_print_where_line (stderr); fprintf x ; fatals++; quit(); } while(0)
369 do { include_print_where_line (stderr); fprintf x; errors++; } while(0)
371 do { include_print_where_line (stderr); fprintf x; warnings++;} while(0)
375 /* exit the program and return the right ERROR code. */
388 for (i
= 0; i
< sb_max_power_two
; i
++)
390 fprintf (stderr
, "strings size %8d : %d\n", 1<<i
, string_count
[i
]);
396 /* hash table maintenance. */
398 /* build a new hash table with size buckets, and fill in the info at ptr. */
401 hash_new_table (size
, ptr
)
407 ptr
->table
= (hash_entry
**) xmalloc (size
* (sizeof (hash_entry
*)));
408 /* Fill with null-pointer, not zero-bit-pattern. */
409 for (i
= 0; i
< size
; i
++)
413 /* calculate and return the hash value of the sb at key. */
422 for (i
= 0; i
< key
->len
; i
++)
430 /* lookup key in hash_table tab, if present, then return it, otherwise
431 build a new one and fill it with hash_integer. */
435 hash_create (tab
, key
)
439 int k
= hash (key
) % tab
->size
;
441 hash_entry
**table
= tab
->table
;
449 hash_entry
*n
= (hash_entry
*) xmalloc (sizeof (hash_entry
));
452 sb_add_sb (&n
->key
, key
);
454 n
->type
= hash_integer
;
457 if (strncmp (table
[k
]->key
.ptr
, key
->ptr
, key
->len
) == 0)
465 /* add sb name with key into hash_table tab. if replacing old value
466 and again, then ERROR. */
470 hash_add_to_string_table (tab
, key
, name
, again
)
476 hash_entry
*ptr
= hash_create (tab
, key
);
477 if (ptr
->type
== hash_integer
)
479 sb_new (&ptr
->value
.s
);
481 if (ptr
->value
.s
.len
)
484 ERROR ((stderr
, _("redefinition not allowed\n")));
487 ptr
->type
= hash_string
;
488 sb_reset (&ptr
->value
.s
);
490 sb_add_sb (&ptr
->value
.s
, name
);
493 /* add integer name to hash_table tab with sb key. */
497 hash_add_to_int_table (tab
, key
, name
)
502 hash_entry
*ptr
= hash_create (tab
, key
);
506 /* lookup sb key in hash_table tab. if found return hash_entry result,
511 hash_lookup (tab
, key
)
515 int k
= hash (key
) % tab
->size
;
516 hash_entry
**table
= tab
->table
;
517 hash_entry
*p
= table
[k
];
520 if (p
->key
.len
== key
->len
521 && strncmp (p
->key
.ptr
, key
->ptr
, key
->len
) == 0)
531 are handled in a really simple recursive decent way. each bit of
532 the machine takes an index into an sb and a pointer to an exp_t,
533 modifies the *exp_t and returns the index of the first character
534 past the part of the expression parsed.
536 expression precedence:
547 /* make sure that the exp_t at term is constant, if not the give the op ERROR. */
551 checkconst (op
, term
)
555 if (term
->add_symbol
.len
556 || term
->sub_symbol
.len
)
558 ERROR ((stderr
, _("the %c operator cannot take non-absolute arguments.\n"), op
));
562 /* turn the number in string at idx into a number of base,
563 fill in ptr and return the index of the first character not in the
568 sb_strtol (idx
, string
, base
, ptr
)
575 idx
= sb_skip_white (idx
, string
);
577 while (idx
< string
->len
)
579 int ch
= string
->ptr
[idx
];
583 else if (ch
>= 'a' && ch
<= 'f')
585 else if (ch
>= 'A' && ch
<= 'F')
593 value
= value
* base
+ dig
;
601 level_0 (idx
, string
, lhs
)
606 lhs
->add_symbol
.len
= 0;
607 lhs
->add_symbol
.name
= 0;
609 lhs
->sub_symbol
.len
= 0;
610 lhs
->sub_symbol
.name
= 0;
612 idx
= sb_skip_white (idx
, string
);
616 if (isdigit ((unsigned char) string
->ptr
[idx
]))
618 idx
= sb_strtol (idx
, string
, 10, &lhs
->value
);
620 else if (ISFIRSTCHAR (string
->ptr
[idx
]))
623 lhs
->add_symbol
.name
= string
->ptr
+ idx
;
624 while (idx
< string
->len
&& ISNEXTCHAR (string
->ptr
[idx
]))
629 lhs
->add_symbol
.len
= len
;
631 else if (string
->ptr
[idx
] == '"')
635 ERROR ((stderr
, _("string where expression expected.\n")));
636 idx
= getstring (idx
, string
, &acc
);
641 ERROR ((stderr
, _("can't find primary in expression.\n")));
644 return sb_skip_white (idx
, string
);
650 level_1 (idx
, string
, lhs
)
655 idx
= sb_skip_white (idx
, string
);
657 switch (string
->ptr
[idx
])
660 idx
= level_1 (idx
+ 1, string
, lhs
);
663 idx
= level_1 (idx
+ 1, string
, lhs
);
664 checkconst ('~', lhs
);
665 lhs
->value
= ~lhs
->value
;
670 idx
= level_1 (idx
+ 1, string
, lhs
);
671 lhs
->value
= -lhs
->value
;
673 lhs
->add_symbol
= lhs
->sub_symbol
;
679 idx
= level_5 (sb_skip_white (idx
, string
), string
, lhs
);
680 if (string
->ptr
[idx
] != ')')
681 ERROR ((stderr
, _("misplaced closing parens.\n")));
686 idx
= level_0 (idx
, string
, lhs
);
689 return sb_skip_white (idx
, string
);
693 level_2 (idx
, string
, lhs
)
700 idx
= level_1 (idx
, string
, lhs
);
702 while (idx
< string
->len
&& (string
->ptr
[idx
] == '*'
703 || string
->ptr
[idx
] == '/'))
705 char op
= string
->ptr
[idx
++];
706 idx
= level_1 (idx
, string
, &rhs
);
710 checkconst ('*', lhs
);
711 checkconst ('*', &rhs
);
712 lhs
->value
*= rhs
.value
;
715 checkconst ('/', lhs
);
716 checkconst ('/', &rhs
);
718 ERROR ((stderr
, _("attempt to divide by zero.\n")));
720 lhs
->value
/= rhs
.value
;
724 return sb_skip_white (idx
, string
);
729 level_3 (idx
, string
, lhs
)
736 idx
= level_2 (idx
, string
, lhs
);
738 while (idx
< string
->len
739 && (string
->ptr
[idx
] == '+'
740 || string
->ptr
[idx
] == '-'))
742 char op
= string
->ptr
[idx
++];
743 idx
= level_2 (idx
, string
, &rhs
);
747 lhs
->value
+= rhs
.value
;
748 if (lhs
->add_symbol
.name
&& rhs
.add_symbol
.name
)
750 ERROR ((stderr
, _("can't add two relocatable expressions\n")));
752 /* change nn+symbol to symbol + nn */
753 if (rhs
.add_symbol
.name
)
755 lhs
->add_symbol
= rhs
.add_symbol
;
759 lhs
->value
-= rhs
.value
;
760 lhs
->sub_symbol
= rhs
.add_symbol
;
764 return sb_skip_white (idx
, string
);
768 level_4 (idx
, string
, lhs
)
775 idx
= level_3 (idx
, string
, lhs
);
777 while (idx
< string
->len
&&
778 string
->ptr
[idx
] == '&')
780 char op
= string
->ptr
[idx
++];
781 idx
= level_3 (idx
, string
, &rhs
);
785 checkconst ('&', lhs
);
786 checkconst ('&', &rhs
);
787 lhs
->value
&= rhs
.value
;
791 return sb_skip_white (idx
, string
);
795 level_5 (idx
, string
, lhs
)
802 idx
= level_4 (idx
, string
, lhs
);
804 while (idx
< string
->len
805 && (string
->ptr
[idx
] == '|' || string
->ptr
[idx
] == '~'))
807 char op
= string
->ptr
[idx
++];
808 idx
= level_4 (idx
, string
, &rhs
);
812 checkconst ('|', lhs
);
813 checkconst ('|', &rhs
);
814 lhs
->value
|= rhs
.value
;
817 checkconst ('~', lhs
);
818 checkconst ('~', &rhs
);
819 lhs
->value
^= rhs
.value
;
823 return sb_skip_white (idx
, string
);
827 /* parse the expression at offset idx into string, fill up res with
828 the result. return the index of the first char past the expression.
832 exp_parse (idx
, string
, res
)
837 return level_5 (sb_skip_white (idx
, string
), string
, res
);
841 /* turn the expression at exp into text and glue it onto the end of
845 exp_string (exp
, string
)
853 if (exp
->add_symbol
.len
)
855 sb_add_buffer (string
, exp
->add_symbol
.name
, exp
->add_symbol
.len
);
863 sb_add_char (string
, '+');
864 sprintf (buf
, "%d", exp
->value
);
865 sb_add_string (string
, buf
);
869 if (exp
->sub_symbol
.len
)
871 sb_add_char (string
, '-');
872 sb_add_buffer (string
, exp
->add_symbol
.name
, exp
->add_symbol
.len
);
878 sb_add_char (string
, '0');
882 /* parse the expression at offset idx into sb in, return the value in val.
883 if the expression is not constant, give ERROR emsg. returns the index
884 of the first character past the end of the expression. */
887 exp_get_abs (emsg
, idx
, in
, val
)
894 idx
= exp_parse (idx
, in
, &res
);
895 if (res
.add_symbol
.len
|| res
.sub_symbol
.len
)
896 ERROR ((stderr
, emsg
));
902 sb label
; /* current label parsed from line */
903 hash_table assign_hash_table
; /* hash table for all assigned variables */
904 hash_table keyword_hash_table
; /* hash table for keyword */
905 hash_table vars
; /* hash table for eq variables */
907 #define in_comment ';'
916 for (i
= 0; i
< out
->len
; i
++)
918 if (ISCOMMENTCHAR(s
[i
]))
927 /* push back character ch so that it can be read again. */
937 if (sp
->pushback_index
)
938 sp
->pushback_index
--;
940 sb_add_char (&sp
->pushback
, ch
);
943 /* push the sb ptr onto the include stack, with the given name, type and index. */
947 include_buf (name
, ptr
, type
, index
)
954 if (sp
- include_stack
>= MAX_INCLUDES
)
955 FATAL ((stderr
, _("unreasonable nesting.\n")));
957 sb_add_sb (&sp
->name
, name
);
960 sp
->pushback_index
= 0;
963 sb_new (&sp
->pushback
);
964 sb_add_sb (&sp
->pushback
, ptr
);
968 /* used in ERROR messages, print info on where the include stack is onto file. */
971 include_print_where_line (file
)
974 struct include_stack
*p
= include_stack
+ 1;
978 fprintf (file
, "%s:%d ", sb_name (&p
->name
), p
->linecount
- 1);
983 /* used in listings, print the line number onto file. */
985 include_print_line (file
)
989 struct include_stack
*p
= include_stack
+ 1;
991 n
= fprintf (file
, "%4d", p
->linecount
);
995 n
+= fprintf (file
, ".%d", p
->linecount
);
1000 fprintf (file
, " ");
1006 /* read a line from the top of the include stack into sb in. */
1017 putc (comment_char
, outfile
);
1018 if (print_line_number
)
1019 include_print_line (outfile
);
1033 WARNING ((stderr
, _("End of file not at start of line.\n")));
1035 putc ('\n', outfile
);
1054 /* continued line */
1057 putc (comment_char
, outfile
);
1058 putc ('+', outfile
);
1071 sb_add_char (in
, ch
);
1079 /* find a label from sb in and put it in out. */
1082 grab_label (in
, out
)
1088 if (ISFIRSTCHAR (in
->ptr
[i
]) || in
->ptr
[i
] == '\\')
1090 sb_add_char (out
, in
->ptr
[i
]);
1092 while ((ISNEXTCHAR (in
->ptr
[i
])
1093 || in
->ptr
[i
] == '\\'
1094 || in
->ptr
[i
] == '&')
1097 sb_add_char (out
, in
->ptr
[i
]);
1104 /* find all strange base stuff and turn into decimal. also
1105 find all the other numbers and convert them from the default radix */
1108 change_base (idx
, in
, out
)
1115 while (idx
< in
->len
)
1117 if (in
->ptr
[idx
] == '\\'
1118 && idx
+ 1 < in
->len
1119 && in
->ptr
[idx
+ 1] == '(')
1122 while (idx
< in
->len
1123 && in
->ptr
[idx
] != ')')
1125 sb_add_char (out
, in
->ptr
[idx
]);
1131 else if (idx
< in
->len
- 1 && in
->ptr
[idx
+ 1] == '\'' && ! mri
)
1135 switch (in
->ptr
[idx
])
1154 ERROR ((stderr
, _("Illegal base character %c.\n"), in
->ptr
[idx
]));
1159 idx
= sb_strtol (idx
+ 2, in
, base
, &value
);
1160 sprintf (buffer
, "%d", value
);
1161 sb_add_string (out
, buffer
);
1163 else if (ISFIRSTCHAR (in
->ptr
[idx
]))
1165 /* copy entire names through quickly */
1166 sb_add_char (out
, in
->ptr
[idx
]);
1168 while (idx
< in
->len
&& ISNEXTCHAR (in
->ptr
[idx
]))
1170 sb_add_char (out
, in
->ptr
[idx
]);
1174 else if (isdigit ((unsigned char) in
->ptr
[idx
]))
1177 /* all numbers must start with a digit, let's chew it and
1179 idx
= sb_strtol (idx
, in
, radix
, &value
);
1180 sprintf (buffer
, "%d", value
);
1181 sb_add_string (out
, buffer
);
1183 /* skip all undigsested letters */
1184 while (idx
< in
->len
&& ISNEXTCHAR (in
->ptr
[idx
]))
1186 sb_add_char (out
, in
->ptr
[idx
]);
1190 else if (in
->ptr
[idx
] == '"' || in
->ptr
[idx
] == '\'')
1192 char tchar
= in
->ptr
[idx
];
1193 /* copy entire names through quickly */
1194 sb_add_char (out
, in
->ptr
[idx
]);
1196 while (idx
< in
->len
&& in
->ptr
[idx
] != tchar
)
1198 sb_add_char (out
, in
->ptr
[idx
]);
1204 /* nothing special, just pass it through */
1205 sb_add_char (out
, in
->ptr
[idx
]);
1219 fprintf (outfile
, "%s\n", sb_name (in
));
1225 do_assign (again
, idx
, in
)
1230 /* stick label in symbol table with following value */
1235 idx
= exp_parse (idx
, in
, &e
);
1236 exp_string (&e
, &acc
);
1237 hash_add_to_string_table (&assign_hash_table
, &label
, &acc
, again
);
1242 /* .radix [b|q|d|h] */
1249 int idx
= sb_skip_white (0, ptr
);
1250 switch (ptr
->ptr
[idx
])
1269 ERROR ((stderr
, _("radix is %c must be one of b, q, d or h"), radix
));
1274 /* Parse off a .b, .w or .l */
1277 get_opsize (idx
, in
, size
)
1283 if (in
->ptr
[idx
] == '.')
1287 switch (in
->ptr
[idx
])
1305 ERROR ((stderr
, _("size must be one of b, w or l, is %c.\n"), in
->ptr
[idx
]));
1318 idx
= sb_skip_white (idx
, line
);
1320 && ISCOMMENTCHAR(line
->ptr
[idx
]))
1322 if (idx
>= line
->len
)
1327 /* .data [.b|.w|.l] <data>*
1328 or d[bwl] <data>* */
1331 do_data (idx
, in
, size
)
1337 char *opname
= ".yikes!";
1343 idx
= get_opsize (idx
, in
, &opsize
);
1362 fprintf (outfile
, "%s\t", opname
);
1364 idx
= sb_skip_white (idx
, in
);
1368 && in
->ptr
[idx
] == '"')
1371 idx
= getstring (idx
, in
, &acc
);
1372 for (i
= 0; i
< acc
.len
; i
++)
1375 fprintf(outfile
,",");
1376 fprintf (outfile
, "%d", acc
.ptr
[i
]);
1381 while (!eol (idx
, in
))
1384 idx
= exp_parse (idx
, in
, &e
);
1385 exp_string (&e
, &acc
);
1386 sb_add_char (&acc
, 0);
1387 fprintf (outfile
, acc
.ptr
);
1388 if (idx
< in
->len
&& in
->ptr
[idx
] == ',')
1390 fprintf (outfile
, ",");
1396 sb_print_at (outfile
, idx
, in
);
1397 fprintf (outfile
, "\n");
1400 /* .datab [.b|.w|.l] <repeat>,<fill> */
1411 idx
= get_opsize (idx
, in
, &opsize
);
1413 idx
= exp_get_abs (_("datab repeat must be constant.\n"), idx
, in
, &repeat
);
1414 idx
= sb_skip_comma (idx
, in
);
1415 idx
= exp_get_abs (_("datab data must be absolute.\n"), idx
, in
, &fill
);
1417 fprintf (outfile
, ".fill\t%d,%d,%d\n", repeat
, opsize
, fill
);
1427 int al
, have_fill
, fill
;
1429 idx
= exp_get_abs (_("align needs absolute expression.\n"), idx
, in
, &al
);
1430 idx
= sb_skip_white (idx
, in
);
1433 if (! eol (idx
, in
))
1435 idx
= sb_skip_comma (idx
, in
);
1436 idx
= exp_get_abs (_(".align needs absolute fill value.\n"), idx
, in
,
1444 WARNING ((stderr
, _("alignment must be one of 1, 2 or 4.\n")));
1446 fprintf (outfile
, ".align %d", al
);
1448 fprintf (outfile
, ",%d", fill
);
1449 fprintf (outfile
, "\n");
1452 /* .res[.b|.w|.l] <size> */
1455 do_res (idx
, in
, type
)
1463 idx
= get_opsize (idx
, in
, &size
);
1464 while (!eol(idx
, in
))
1466 idx
= sb_skip_white (idx
, in
);
1467 if (in
->ptr
[idx
] == ',')
1469 idx
= exp_get_abs (_("res needs absolute expression for fill count.\n"), idx
, in
, &count
);
1471 if (type
== 'c' || type
== 'z')
1474 fprintf (outfile
, ".space %d\n", count
* size
);
1485 fprintf (outfile
, ".global %s\n", sb_name (in
));
1488 /* .print [list] [nolist] */
1495 idx
= sb_skip_white (idx
, in
);
1496 while (idx
< in
->len
)
1498 if (strncasecmp (in
->ptr
+ idx
, "LIST", 4) == 0)
1500 fprintf (outfile
, ".list\n");
1503 else if (strncasecmp (in
->ptr
+ idx
, "NOLIST", 6) == 0)
1505 fprintf (outfile
, ".nolist\n");
1514 do_heading (idx
, in
)
1520 idx
= getstring (idx
, in
, &head
);
1521 fprintf (outfile
, ".title \"%s\"\n", sb_name (&head
));
1530 fprintf (outfile
, ".eject\n");
1533 /* .form [lin=<value>] [col=<value>] */
1541 idx
= sb_skip_white (idx
, in
);
1543 while (idx
< in
->len
)
1546 if (strncasecmp (in
->ptr
+ idx
, "LIN=", 4) == 0)
1549 idx
= exp_get_abs (_("form LIN= needs absolute expresssion.\n"), idx
, in
, &lines
);
1552 if (strncasecmp (in
->ptr
+ idx
, _("COL="), 4) == 0)
1555 idx
= exp_get_abs (_("form COL= needs absolute expresssion.\n"), idx
, in
, &columns
);
1560 fprintf (outfile
, ".psize %d,%d\n", lines
, columns
);
1565 /* Fetch string from the input stream,
1567 'Bxyx<whitespace> -> return 'Bxyza
1568 %<char> -> return string of decimal value of x
1569 "<string>" -> return string
1570 xyx<whitespace> -> return xyz
1573 get_any_string (idx
, in
, out
, expand
, pretend_quoted
)
1581 idx
= sb_skip_white (idx
, in
);
1585 if (in
->len
> 2 && in
->ptr
[idx
+1] == '\'' && ISBASE (in
->ptr
[idx
]))
1587 while (!ISSEP (in
->ptr
[idx
]))
1588 sb_add_char (out
, in
->ptr
[idx
++]);
1590 else if (in
->ptr
[idx
] == '%'
1596 /* Turns the next expression into a string */
1597 idx
= exp_get_abs (_("% operator needs absolute expression"),
1601 sprintf(buf
, "%d", val
);
1602 sb_add_string (out
, buf
);
1604 else if (in
->ptr
[idx
] == '"'
1605 || in
->ptr
[idx
] == '<'
1606 || (alternate
&& in
->ptr
[idx
] == '\''))
1608 if (alternate
&& expand
)
1610 /* Keep the quotes */
1611 sb_add_char (out
, '\"');
1613 idx
= getstring (idx
, in
, out
);
1614 sb_add_char (out
, '\"');
1618 idx
= getstring (idx
, in
, out
);
1623 while (idx
< in
->len
1624 && (in
->ptr
[idx
] == '"'
1625 || in
->ptr
[idx
] == '\''
1627 || !ISSEP (in
->ptr
[idx
])))
1629 if (in
->ptr
[idx
] == '"'
1630 || in
->ptr
[idx
] == '\'')
1632 char tchar
= in
->ptr
[idx
];
1633 sb_add_char (out
, in
->ptr
[idx
++]);
1634 while (idx
< in
->len
1635 && in
->ptr
[idx
] != tchar
)
1636 sb_add_char (out
, in
->ptr
[idx
++]);
1640 sb_add_char (out
, in
->ptr
[idx
++]);
1649 /* skip along sb in starting at idx, suck off whitespace a ( and more
1650 whitespace. return the idx of the next char */
1653 skip_openp (idx
, in
)
1657 idx
= sb_skip_white (idx
, in
);
1658 if (in
->ptr
[idx
] != '(')
1659 ERROR ((stderr
, _("misplaced ( .\n")));
1660 idx
= sb_skip_white (idx
+ 1, in
);
1664 /* skip along sb in starting at idx, suck off whitespace a ) and more
1665 whitespace. return the idx of the next char */
1668 skip_closep (idx
, in
)
1672 idx
= sb_skip_white (idx
, in
);
1673 if (in
->ptr
[idx
] != ')')
1674 ERROR ((stderr
, _("misplaced ).\n")));
1675 idx
= sb_skip_white (idx
+ 1, in
);
1682 dolen (idx
, in
, out
)
1691 sb_new (&stringout
);
1692 idx
= skip_openp (idx
, in
);
1693 idx
= get_and_process (idx
, in
, &stringout
);
1694 idx
= skip_closep (idx
, in
);
1695 sprintf (buffer
, "%d", stringout
.len
);
1696 sb_add_string (out
, buffer
);
1698 sb_kill (&stringout
);
1707 doinstr (idx
, in
, out
)
1721 idx
= skip_openp (idx
, in
);
1722 idx
= get_and_process (idx
, in
, &string
);
1723 idx
= sb_skip_comma (idx
, in
);
1724 idx
= get_and_process (idx
, in
, &search
);
1725 idx
= sb_skip_comma (idx
, in
);
1726 if (isdigit ((unsigned char) in
->ptr
[idx
]))
1728 idx
= exp_get_abs (_(".instr needs absolute expresson.\n"), idx
, in
, &start
);
1734 idx
= skip_closep (idx
, in
);
1736 for (i
= start
; i
< string
.len
; i
++)
1738 if (strncmp (string
.ptr
+ i
, search
.ptr
, search
.len
) == 0)
1744 sprintf (buffer
, "%d", res
);
1745 sb_add_string (out
, buffer
);
1753 dosubstr (idx
, in
, out
)
1763 idx
= skip_openp (idx
, in
);
1764 idx
= get_and_process (idx
, in
, &string
);
1765 idx
= sb_skip_comma (idx
, in
);
1766 idx
= exp_get_abs (_("need absolute position.\n"), idx
, in
, &pos
);
1767 idx
= sb_skip_comma (idx
, in
);
1768 idx
= exp_get_abs (_("need absolute length.\n"), idx
, in
, &len
);
1769 idx
= skip_closep (idx
, in
);
1772 if (len
< 0 || pos
< 0 ||
1774 || pos
+ len
> string
.len
)
1776 sb_add_string (out
, " ");
1780 sb_add_char (out
, '"');
1783 sb_add_char (out
, string
.ptr
[pos
++]);
1786 sb_add_char (out
, '"');
1792 /* scan line, change tokens in the hash table to their replacements */
1794 process_assigns (idx
, in
, buf
)
1799 while (idx
< in
->len
)
1802 if (in
->ptr
[idx
] == '\\'
1803 && idx
+ 1 < in
->len
1804 && in
->ptr
[idx
+ 1] == '(')
1808 sb_add_char (buf
, in
->ptr
[idx
]);
1811 while (idx
< in
->len
&& in
->ptr
[idx
- 1] != ')');
1813 else if (in
->ptr
[idx
] == '\\'
1814 && idx
+ 1 < in
->len
1815 && in
->ptr
[idx
+ 1] == '&')
1817 idx
= condass_lookup_name (in
, idx
+ 2, buf
, 1);
1819 else if (in
->ptr
[idx
] == '\\'
1820 && idx
+ 1 < in
->len
1821 && in
->ptr
[idx
+ 1] == '$')
1823 idx
= condass_lookup_name (in
, idx
+ 2, buf
, 0);
1825 else if (idx
+ 3 < in
->len
1826 && in
->ptr
[idx
] == '.'
1827 && toupper ((unsigned char) in
->ptr
[idx
+ 1]) == 'L'
1828 && toupper ((unsigned char) in
->ptr
[idx
+ 2]) == 'E'
1829 && toupper ((unsigned char) in
->ptr
[idx
+ 3]) == 'N')
1830 idx
= dolen (idx
+ 4, in
, buf
);
1831 else if (idx
+ 6 < in
->len
1832 && in
->ptr
[idx
] == '.'
1833 && toupper ((unsigned char) in
->ptr
[idx
+ 1]) == 'I'
1834 && toupper ((unsigned char) in
->ptr
[idx
+ 2]) == 'N'
1835 && toupper ((unsigned char) in
->ptr
[idx
+ 3]) == 'S'
1836 && toupper ((unsigned char) in
->ptr
[idx
+ 4]) == 'T'
1837 && toupper ((unsigned char) in
->ptr
[idx
+ 5]) == 'R')
1838 idx
= doinstr (idx
+ 6, in
, buf
);
1839 else if (idx
+ 7 < in
->len
1840 && in
->ptr
[idx
] == '.'
1841 && toupper ((unsigned char) in
->ptr
[idx
+ 1]) == 'S'
1842 && toupper ((unsigned char) in
->ptr
[idx
+ 2]) == 'U'
1843 && toupper ((unsigned char) in
->ptr
[idx
+ 3]) == 'B'
1844 && toupper ((unsigned char) in
->ptr
[idx
+ 4]) == 'S'
1845 && toupper ((unsigned char) in
->ptr
[idx
+ 5]) == 'T'
1846 && toupper ((unsigned char) in
->ptr
[idx
+ 6]) == 'R')
1847 idx
= dosubstr (idx
+ 7, in
, buf
);
1848 else if (ISFIRSTCHAR (in
->ptr
[idx
]))
1850 /* may be a simple name subsitution, see if we have a word */
1853 while (cur
< in
->len
1854 && (ISNEXTCHAR (in
->ptr
[cur
])))
1858 sb_add_buffer (&acc
, in
->ptr
+ idx
, cur
- idx
);
1859 ptr
= hash_lookup (&assign_hash_table
, &acc
);
1862 /* Found a definition for it */
1863 sb_add_sb (buf
, &ptr
->value
.s
);
1867 /* No definition, just copy the word */
1868 sb_add_sb (buf
, &acc
);
1875 sb_add_char (buf
, in
->ptr
[idx
++]);
1881 get_and_process (idx
, in
, out
)
1888 idx
= get_any_string (idx
, in
, &t
, 1, 0);
1889 process_assigns (0, &t
, out
);
1910 more
= get_line (&line
);
1913 /* Find any label and pseudo op that we're intested in */
1918 fprintf (outfile
, "\n");
1921 && (line
.ptr
[0] == '*'
1922 || line
.ptr
[0] == '!'))
1924 /* MRI line comment. */
1925 fprintf (outfile
, sb_name (&line
));
1929 l
= grab_label (&line
, &label_in
);
1932 if (line
.ptr
[l
] == ':')
1934 while (ISWHITE (line
.ptr
[l
]) && l
< line
.len
)
1941 /* Munge the label, unless this is EQU or ASSIGN. */
1944 && (line
.ptr
[l
] == '.' || alternate
|| mri
))
1948 if (line
.ptr
[lx
] == '.')
1950 if (lx
+ 3 <= line
.len
1951 && strncasecmp ("EQU", line
.ptr
+ lx
, 3) == 0
1952 && (lx
+ 3 == line
.len
1953 || ! ISFIRSTCHAR (line
.ptr
[lx
+ 3])))
1955 else if (lx
+ 6 <= line
.len
1956 && strncasecmp ("ASSIGN", line
.ptr
+ lx
, 6) == 0
1957 && (lx
+ 6 == line
.len
1958 || ! ISFIRSTCHAR (line
.ptr
[lx
+ 6])))
1963 process_assigns (0, &label_in
, &label
);
1965 sb_add_sb (&label
, &label_in
);
1970 if (process_pseudo_op (l
, &line
, &acc
))
1976 else if (condass_on ())
1978 if (macro_op (l
, &line
))
1988 fprintf (outfile
, "%s:\t", sb_name (&label
));
1991 fprintf (outfile
, "\t");
1993 process_assigns (l
, &line
, &t1
);
1995 change_base (0, &t1
, &t2
);
1996 fprintf (outfile
, "%s\n", sb_name (&t2
));
2002 /* Only a label on this line */
2003 if (label
.len
&& condass_on())
2005 fprintf (outfile
, "%s:\n", sb_name (&label
));
2013 more
= get_line (&line
);
2016 if (!had_end
&& !mri
)
2017 WARNING ((stderr
, _("END missing from end of file.\n")));
2025 free_old_entry (ptr
)
2030 if (ptr
->type
== hash_string
)
2031 sb_kill(&ptr
->value
.s
);
2035 /* name: .ASSIGNA <value> */
2038 do_assigna (idx
, in
)
2046 process_assigns (idx
, in
, &tmp
);
2047 idx
= exp_get_abs (_(".ASSIGNA needs constant expression argument.\n"), 0, &tmp
, &val
);
2051 ERROR ((stderr
, _(".ASSIGNA without label.\n")));
2055 hash_entry
*ptr
= hash_create (&vars
, &label
);
2056 free_old_entry (ptr
);
2057 ptr
->type
= hash_integer
;
2063 /* name: .ASSIGNC <string> */
2066 do_assignc (idx
, in
)
2072 idx
= getstring (idx
, in
, &acc
);
2076 ERROR ((stderr
, _(".ASSIGNS without label.\n")));
2080 hash_entry
*ptr
= hash_create (&vars
, &label
);
2081 free_old_entry (ptr
);
2082 ptr
->type
= hash_string
;
2083 sb_new (&ptr
->value
.s
);
2084 sb_add_sb (&ptr
->value
.s
, &acc
);
2090 /* name: .REG (reg) */
2097 /* remove reg stuff from inside parens */
2100 idx
= skip_openp (idx
, in
);
2102 idx
= sb_skip_white (idx
, in
);
2104 while (idx
< in
->len
2107 : in
->ptr
[idx
] != ')'))
2109 sb_add_char (&what
, in
->ptr
[idx
]);
2112 hash_add_to_string_table (&assign_hash_table
, &label
, &what
, 1);
2118 condass_lookup_name (inbuf
, idx
, out
, warn
)
2126 sb_new (&condass_acc
);
2128 while (idx
< inbuf
->len
2129 && ISNEXTCHAR (inbuf
->ptr
[idx
]))
2131 sb_add_char (&condass_acc
, inbuf
->ptr
[idx
++]);
2134 if (inbuf
->ptr
[idx
] == '\'')
2136 ptr
= hash_lookup (&vars
, &condass_acc
);
2143 WARNING ((stderr
, _("Can't find preprocessor variable %s.\n"), sb_name (&condass_acc
)));
2147 sb_add_string (out
, "0");
2152 if (ptr
->type
== hash_integer
)
2155 sprintf (buffer
, "%d", ptr
->value
.i
);
2156 sb_add_string (out
, buffer
);
2160 sb_add_sb (out
, &ptr
->value
.s
);
2163 sb_kill (&condass_acc
);
2176 whatcond (idx
, in
, val
)
2183 idx
= sb_skip_white (idx
, in
);
2185 if (idx
+ 1 < in
->len
)
2191 a
= toupper ((unsigned char) p
[0]);
2192 b
= toupper ((unsigned char) p
[1]);
2193 if (a
== 'E' && b
== 'Q')
2195 else if (a
== 'N' && b
== 'E')
2197 else if (a
== 'L' && b
== 'T')
2199 else if (a
== 'L' && b
== 'E')
2201 else if (a
== 'G' && b
== 'T')
2203 else if (a
== 'G' && b
== 'E')
2208 ERROR ((stderr
, _("Comparison operator must be one of EQ, NE, LT, LE, GT or GE.\n")));
2211 idx
= sb_skip_white (idx
+ 2, in
);
2228 idx
= sb_skip_white (idx
, in
);
2230 if (in
->ptr
[idx
] == '"')
2234 /* This is a string comparision */
2235 idx
= getstring (idx
, in
, &acc_a
);
2236 idx
= whatcond (idx
, in
, &cond
);
2237 idx
= getstring (idx
, in
, &acc_b
);
2238 same
= acc_a
.len
== acc_b
.len
&& (strncmp (acc_a
.ptr
, acc_b
.ptr
, acc_a
.len
) == 0);
2240 if (cond
!= EQ
&& cond
!= NE
)
2242 ERROR ((stderr
, _("Comparison operator for strings must be EQ or NE\n")));
2246 res
= (cond
!= EQ
) ^ same
;
2249 /* This is a numeric expression */
2254 idx
= exp_get_abs (_("Conditional operator must have absolute operands.\n"), idx
, in
, &vala
);
2255 idx
= whatcond (idx
, in
, &cond
);
2256 idx
= sb_skip_white (idx
, in
);
2257 if (in
->ptr
[idx
] == '"')
2259 WARNING ((stderr
, _("String compared against expression.\n")));
2264 idx
= exp_get_abs (_("Conditional operator must have absolute operands.\n"), idx
, in
, &valb
);
2307 if (ifi
>= IFNESTING
)
2309 FATAL ((stderr
, _("AIF nesting unreasonable.\n")));
2312 ifstack
[ifi
].on
= ifstack
[ifi
-1].on
? istrue (idx
, in
) : 0;
2313 ifstack
[ifi
].hadelse
= 0;
2321 ifstack
[ifi
].on
= ifstack
[ifi
-1].on
? !ifstack
[ifi
].on
: 0;
2322 if (ifstack
[ifi
].hadelse
)
2324 ERROR ((stderr
, _("Multiple AELSEs in AIF.\n")));
2326 ifstack
[ifi
].hadelse
= 1;
2340 ERROR ((stderr
, _("AENDI without AIF.\n")));
2347 return ifstack
[ifi
].on
;
2350 /* MRI IFEQ, IFNE, IFLT, IFLE, IFGE, IFGT. */
2353 do_if (idx
, in
, cond
)
2361 if (ifi
>= IFNESTING
)
2363 FATAL ((stderr
, _("IF nesting unreasonable.\n")));
2366 idx
= exp_get_abs (_("Conditional operator must have absolute operands.\n"),
2371 case EQ
: res
= val
== 0; break;
2372 case NE
: res
= val
!= 0; break;
2373 case LT
: res
= val
< 0; break;
2374 case LE
: res
= val
<= 0; break;
2375 case GE
: res
= val
>= 0; break;
2376 case GT
: res
= val
> 0; break;
2380 ifstack
[ifi
].on
= ifstack
[ifi
-1].on
? res
: 0;
2381 ifstack
[ifi
].hadelse
= 0;
2384 /* Get a string for the MRI IFC or IFNC pseudo-ops. */
2387 get_mri_string (idx
, in
, val
, terminator
)
2393 idx
= sb_skip_white (idx
, in
);
2396 && in
->ptr
[idx
] == '\'')
2398 sb_add_char (val
, '\'');
2399 for (++idx
; idx
< in
->len
; ++idx
)
2401 sb_add_char (val
, in
->ptr
[idx
]);
2402 if (in
->ptr
[idx
] == '\'')
2406 || in
->ptr
[idx
] != '\'')
2410 idx
= sb_skip_white (idx
, in
);
2416 while (idx
< in
->len
2417 && in
->ptr
[idx
] != terminator
)
2419 sb_add_char (val
, in
->ptr
[idx
]);
2423 while (i
>= 0 && ISWHITE (val
->ptr
[i
]))
2431 /* MRI IFC, IFNC. */
2434 do_ifc (idx
, in
, ifnc
)
2443 if (ifi
>= IFNESTING
)
2445 FATAL ((stderr
, _("IF nesting unreasonable.\n")));
2451 idx
= get_mri_string (idx
, in
, &first
, ',');
2453 if (idx
>= in
->len
|| in
->ptr
[idx
] != ',')
2455 ERROR ((stderr
, _("Bad format for IF or IFNC.\n")));
2459 idx
= get_mri_string (idx
+ 1, in
, &second
, ';');
2461 res
= (first
.len
== second
.len
2462 && strncmp (first
.ptr
, second
.ptr
, first
.len
) == 0);
2466 ifstack
[ifi
].on
= ifstack
[ifi
-1].on
? res
: 0;
2467 ifstack
[ifi
].hadelse
= 0;
2475 ERROR ((stderr
, _("AENDR without a AREPEAT.\n")));
2477 ERROR ((stderr
, _("ENDR without a REPT.\n")));
2488 int line
= linecount ();
2496 process_assigns (idx
, in
, &exp
);
2497 doit
= istrue (0, &exp
);
2499 if (! buffer_and_nest ("AWHILE", "AENDW", &sub
, get_line
))
2500 FATAL ((stderr
, _("AWHILE without a AENDW at %d.\n"), line
- 1));
2515 int index
= include_next_index ();
2519 sb_add_sb (©
, &sub
);
2520 sb_add_sb (©
, in
);
2521 sb_add_string (©
, "\n");
2522 sb_add_sb (©
, &sub
);
2523 sb_add_string (©
, "\t.AENDW\n");
2524 /* Push another WHILE */
2525 include_buf (&exp
, ©
, include_while
, index
);
2538 ERROR ((stderr
, _("AENDW without a AENDW.\n")));
2544 Pop things off the include stack until the type and index changes */
2549 include_type type
= sp
->type
;
2550 if (type
== include_repeat
2551 || type
== include_while
2552 || type
== include_macro
)
2554 int index
= sp
->index
;
2556 while (sp
->index
== index
2557 && sp
->type
== type
)
2567 do_arepeat (idx
, in
)
2571 int line
= linecount ();
2572 sb exp
; /* buffer with expression in it */
2573 sb copy
; /* expanded repeat block */
2574 sb sub
; /* contents of AREPEAT */
2582 process_assigns (idx
, in
, &exp
);
2583 idx
= exp_get_abs (_("AREPEAT must have absolute operand.\n"), 0, &exp
, &rc
);
2585 ret
= buffer_and_nest ("AREPEAT", "AENDR", &sub
, get_line
);
2587 ret
= buffer_and_nest ("REPT", "ENDR", &sub
, get_line
);
2589 FATAL ((stderr
, _("AREPEAT without a AENDR at %d.\n"), line
- 1));
2592 /* Push back the text following the repeat, and another repeat block
2603 int index
= include_next_index ();
2604 sb_add_sb (©
, &sub
);
2608 sprintf (buffer
, "\t.AREPEAT %d\n", rc
- 1);
2610 sprintf (buffer
, "\tREPT %d\n", rc
- 1);
2611 sb_add_string (©
, buffer
);
2612 sb_add_sb (©
, &sub
);
2614 sb_add_string (©
, " .AENDR\n");
2616 sb_add_string (©
, " ENDR\n");
2619 include_buf (&exp
, ©
, include_repeat
, index
);
2631 ERROR ((stderr
, _(".ENDM without a matching .MACRO.\n")));
2634 /* MRI IRP pseudo-op. */
2637 do_irp (idx
, in
, irpc
)
2647 err
= expand_irp (irpc
, idx
, in
, &out
, get_line
, comment_char
);
2649 ERROR ((stderr
, "%s\n", err
));
2651 fprintf (outfile
, "%s", sb_terminate (&out
));
2656 /* MACRO PROCESSING */
2658 /* Parse off LOCAL n1, n2,... Invent a label name for it */
2661 do_local (idx
, line
)
2665 ERROR ((stderr
, _("LOCAL outside of MACRO")));
2674 int line
= linecount ();
2676 err
= define_macro (idx
, in
, &label
, get_line
, (const char **) NULL
);
2678 ERROR ((stderr
, _("macro at line %d: %s\n"), line
- 1, err
));
2690 if (! macro_defined
)
2694 if (! check_macro (in
->ptr
+ idx
, &out
, comment_char
, &err
))
2698 ERROR ((stderr
, "%s\n", err
));
2701 sb_add_string (&name
, _("macro expansion"));
2703 include_buf (&name
, &out
, include_macro
, include_next_index ());
2711 /* STRING HANDLING */
2714 getstring (idx
, in
, acc
)
2719 idx
= sb_skip_white (idx
, in
);
2721 while (idx
< in
->len
2722 && (in
->ptr
[idx
] == '"'
2723 || in
->ptr
[idx
] == '<'
2724 || (in
->ptr
[idx
] == '\'' && alternate
)))
2726 if (in
->ptr
[idx
] == '<')
2728 if (alternate
|| mri
)
2732 while ((in
->ptr
[idx
] != '>' || nest
)
2735 if (in
->ptr
[idx
] == '!')
2738 sb_add_char (acc
, in
->ptr
[idx
++]);
2741 if (in
->ptr
[idx
] == '>')
2743 if (in
->ptr
[idx
] == '<')
2745 sb_add_char (acc
, in
->ptr
[idx
++]);
2753 idx
= exp_get_abs (_("Character code in string must be absolute expression.\n"),
2755 sb_add_char (acc
, code
);
2757 if (in
->ptr
[idx
] != '>')
2758 ERROR ((stderr
, _("Missing > for character code.\n")));
2762 else if (in
->ptr
[idx
] == '"' || in
->ptr
[idx
] == '\'')
2764 char tchar
= in
->ptr
[idx
];
2766 while (idx
< in
->len
)
2768 if (alternate
&& in
->ptr
[idx
] == '!')
2771 sb_add_char (acc
, in
->ptr
[idx
++]);
2774 if (in
->ptr
[idx
] == tchar
)
2777 if (idx
>= in
->len
|| in
->ptr
[idx
] != tchar
)
2780 sb_add_char (acc
, in
->ptr
[idx
]);
2790 /* .SDATA[C|Z] <string> */
2794 do_sdata (idx
, in
, type
)
2803 fprintf (outfile
, ".byte\t");
2805 while (!eol (idx
, in
))
2809 idx
= sb_skip_white (idx
, in
);
2810 while (!eol (idx
, in
))
2812 pidx
= idx
= get_any_string (idx
, in
, &acc
, 0, 1);
2817 ERROR ((stderr
, _("string for SDATAC longer than 255 characters (%d).\n"), acc
.len
));
2819 fprintf (outfile
, "%d", acc
.len
);
2823 for (i
= 0; i
< acc
.len
; i
++)
2827 fprintf (outfile
, ",");
2829 fprintf (outfile
, "%d", acc
.ptr
[i
]);
2836 fprintf (outfile
, ",");
2837 fprintf (outfile
, "0");
2839 idx
= sb_skip_comma (idx
, in
);
2840 if (idx
== pidx
) break;
2842 if (!alternate
&& in
->ptr
[idx
] != ',' && idx
!= in
->len
)
2844 fprintf (outfile
, "\n");
2845 ERROR ((stderr
, _("illegal character in SDATA line (0x%x).\n"), in
->ptr
[idx
]));
2851 fprintf (outfile
, "\n");
2854 /* .SDATAB <count> <string> */
2866 idx
= exp_get_abs (_("Must have absolute SDATAB repeat count.\n"), idx
, in
, &repeat
);
2869 ERROR ((stderr
, _("Must have positive SDATAB repeat count (%d).\n"), repeat
));
2873 idx
= sb_skip_comma (idx
, in
);
2874 idx
= getstring (idx
, in
, &acc
);
2876 for (i
= 0; i
< repeat
; i
++)
2879 fprintf (outfile
, "\t");
2880 fprintf (outfile
, ".byte\t");
2881 sb_print (outfile
, &acc
);
2882 fprintf (outfile
, "\n");
2892 FILE *newone
= fopen (name
, "r");
2896 if (isp
== MAX_INCLUDES
)
2897 FATAL ((stderr
, _("Unreasonable include depth (%ld).\n"), (long) isp
));
2900 sp
->handle
= newone
;
2903 sb_add_string (&sp
->name
, name
);
2906 sp
->pushback_index
= 0;
2907 sp
->type
= include_file
;
2909 sb_new (&sp
->pushback
);
2914 do_include (idx
, in
)
2920 include_path
*includes
;
2926 idx
= getstring (idx
, in
, &t
);
2929 idx
= sb_skip_white (idx
, in
);
2930 while (idx
< in
->len
&& ! ISWHITE (in
->ptr
[idx
]))
2932 sb_add_char (&t
, in
->ptr
[idx
]);
2937 for (includes
= paths_head
; includes
; includes
= includes
->next
)
2940 sb_add_sb (&cat
, &includes
->path
);
2941 sb_add_char (&cat
, '/');
2942 sb_add_sb (&cat
, &t
);
2943 if (new_file (sb_name (&cat
)))
2950 if (! new_file (sb_name (&t
)))
2951 FATAL ((stderr
, _("Can't open include file `%s'.\n"), sb_name (&t
)));
2960 if (sp
!= include_stack
)
2963 fclose (sp
->handle
);
2968 /* Get the next character from the include stack. If there's anything
2969 in the pushback buffer, take that first. If we're at eof, pop from
2970 the stack and try again. Keep the linecount up to date. */
2977 if (sp
->pushback
.len
!= sp
->pushback_index
)
2979 r
= (char) (sp
->pushback
.ptr
[sp
->pushback_index
++]);
2980 /* When they've all gone, reset the pointer */
2981 if (sp
->pushback_index
== sp
->pushback
.len
)
2983 sp
->pushback
.len
= 0;
2984 sp
->pushback_index
= 0;
2987 else if (sp
->handle
)
2989 r
= getc (sp
->handle
);
2994 if (r
== EOF
&& isp
)
2998 while (r
== EOF
&& isp
)
3016 return sp
->linecount
;
3020 include_next_index ()
3024 && index
> MAX_REASONABLE
)
3025 FATAL ((stderr
, _("Unreasonable expansion (-u turns off check).\n")));
3030 /* Initialize the chartype vector. */
3036 for (x
= 0; x
< 256; x
++)
3038 if (isalpha (x
) || x
== '_' || x
== '$')
3039 chartype
[x
] |= FIRSTBIT
;
3041 if (mri
&& x
== '.')
3042 chartype
[x
] |= FIRSTBIT
;
3044 if (isdigit (x
) || isalpha (x
) || x
== '_' || x
== '$')
3045 chartype
[x
] |= NEXTBIT
;
3047 if (x
== ' ' || x
== '\t' || x
== ',' || x
== '"' || x
== ';'
3048 || x
== '"' || x
== '<' || x
== '>' || x
== ')' || x
== '(')
3049 chartype
[x
] |= SEPBIT
;
3051 if (x
== 'b' || x
== 'B'
3052 || x
== 'q' || x
== 'Q'
3053 || x
== 'h' || x
== 'H'
3054 || x
== 'd' || x
== 'D')
3055 chartype
[x
] |= BASEBIT
;
3057 if (x
== ' ' || x
== '\t')
3058 chartype
[x
] |= WHITEBIT
;
3060 if (x
== comment_char
)
3061 chartype
[x
] |= COMMENTBIT
;
3067 /* What to do with all the keywords */
3068 #define PROCESS 0x1000 /* Run substitution over the line */
3069 #define LAB 0x2000 /* Spit out the label */
3071 #define K_EQU (PROCESS|1)
3072 #define K_ASSIGN (PROCESS|2)
3073 #define K_REG (PROCESS|3)
3074 #define K_ORG (PROCESS|4)
3075 #define K_RADIX (PROCESS|5)
3076 #define K_DATA (LAB|PROCESS|6)
3077 #define K_DATAB (LAB|PROCESS|7)
3078 #define K_SDATA (LAB|PROCESS|8)
3079 #define K_SDATAB (LAB|PROCESS|9)
3080 #define K_SDATAC (LAB|PROCESS|10)
3081 #define K_SDATAZ (LAB|PROCESS|11)
3082 #define K_RES (LAB|PROCESS|12)
3083 #define K_SRES (LAB|PROCESS|13)
3084 #define K_SRESC (LAB|PROCESS|14)
3085 #define K_SRESZ (LAB|PROCESS|15)
3086 #define K_EXPORT (LAB|PROCESS|16)
3087 #define K_GLOBAL (LAB|PROCESS|17)
3088 #define K_PRINT (LAB|PROCESS|19)
3089 #define K_FORM (LAB|PROCESS|20)
3090 #define K_HEADING (LAB|PROCESS|21)
3091 #define K_PAGE (LAB|PROCESS|22)
3092 #define K_IMPORT (LAB|PROCESS|23)
3093 #define K_PROGRAM (LAB|PROCESS|24)
3094 #define K_END (PROCESS|25)
3095 #define K_INCLUDE (PROCESS|26)
3096 #define K_IGNORED (PROCESS|27)
3097 #define K_ASSIGNA (PROCESS|28)
3098 #define K_ASSIGNC (29)
3099 #define K_AIF (PROCESS|30)
3100 #define K_AELSE (PROCESS|31)
3101 #define K_AENDI (PROCESS|32)
3102 #define K_AREPEAT (PROCESS|33)
3103 #define K_AENDR (PROCESS|34)
3104 #define K_AWHILE (35)
3105 #define K_AENDW (PROCESS|36)
3106 #define K_EXITM (37)
3107 #define K_MACRO (PROCESS|38)
3109 #define K_ALIGN (PROCESS|LAB|40)
3110 #define K_ALTERNATE (41)
3111 #define K_DB (LAB|PROCESS|42)
3112 #define K_DW (LAB|PROCESS|43)
3113 #define K_DL (LAB|PROCESS|44)
3114 #define K_LOCAL (45)
3115 #define K_IFEQ (PROCESS|46)
3116 #define K_IFNE (PROCESS|47)
3117 #define K_IFLT (PROCESS|48)
3118 #define K_IFLE (PROCESS|49)
3119 #define K_IFGE (PROCESS|50)
3120 #define K_IFGT (PROCESS|51)
3121 #define K_IFC (PROCESS|52)
3122 #define K_IFNC (PROCESS|53)
3123 #define K_IRP (PROCESS|54)
3124 #define K_IRPC (PROCESS|55)
3134 static struct keyword kinfo
[] =
3136 { "EQU", K_EQU
, 0 },
3137 { "ALTERNATE", K_ALTERNATE
, 0 },
3138 { "ASSIGN", K_ASSIGN
, 0 },
3139 { "REG", K_REG
, 0 },
3140 { "ORG", K_ORG
, 0 },
3141 { "RADIX", K_RADIX
, 0 },
3142 { "DATA", K_DATA
, 0 },
3146 { "DATAB", K_DATAB
, 0 },
3147 { "SDATA", K_SDATA
, 0 },
3148 { "SDATAB", K_SDATAB
, 0 },
3149 { "SDATAZ", K_SDATAZ
, 0 },
3150 { "SDATAC", K_SDATAC
, 0 },
3151 { "RES", K_RES
, 0 },
3152 { "SRES", K_SRES
, 0 },
3153 { "SRESC", K_SRESC
, 0 },
3154 { "SRESZ", K_SRESZ
, 0 },
3155 { "EXPORT", K_EXPORT
, 0 },
3156 { "GLOBAL", K_GLOBAL
, 0 },
3157 { "PRINT", K_PRINT
, 0 },
3158 { "FORM", K_FORM
, 0 },
3159 { "HEADING", K_HEADING
, 0 },
3160 { "PAGE", K_PAGE
, 0 },
3161 { "PROGRAM", K_IGNORED
, 0 },
3162 { "END", K_END
, 0 },
3163 { "INCLUDE", K_INCLUDE
, 0 },
3164 { "ASSIGNA", K_ASSIGNA
, 0 },
3165 { "ASSIGNC", K_ASSIGNC
, 0 },
3166 { "AIF", K_AIF
, 0 },
3167 { "AELSE", K_AELSE
, 0 },
3168 { "AENDI", K_AENDI
, 0 },
3169 { "AREPEAT", K_AREPEAT
, 0 },
3170 { "AENDR", K_AENDR
, 0 },
3171 { "EXITM", K_EXITM
, 0 },
3172 { "MACRO", K_MACRO
, 0 },
3173 { "ENDM", K_ENDM
, 0 },
3174 { "AWHILE", K_AWHILE
, 0 },
3175 { "ALIGN", K_ALIGN
, 0 },
3176 { "AENDW", K_AENDW
, 0 },
3177 { "ALTERNATE", K_ALTERNATE
, 0 },
3178 { "LOCAL", K_LOCAL
, 0 },
3182 /* Although the conditional operators are handled by gas, we need to
3183 handle them here as well, in case they are used in a recursive
3184 macro to end the recursion. */
3186 static struct keyword mrikinfo
[] =
3188 { "IFEQ", K_IFEQ
, 0 },
3189 { "IFNE", K_IFNE
, 0 },
3190 { "IFLT", K_IFLT
, 0 },
3191 { "IFLE", K_IFLE
, 0 },
3192 { "IFGE", K_IFGE
, 0 },
3193 { "IFGT", K_IFGT
, 0 },
3194 { "IFC", K_IFC
, 0 },
3195 { "IFNC", K_IFNC
, 0 },
3196 { "ELSEC", K_AELSE
, 0 },
3197 { "ENDC", K_AENDI
, 0 },
3198 { "MEXIT", K_EXITM
, 0 },
3199 { "REPT", K_AREPEAT
, 0 },
3200 { "IRP", K_IRP
, 0 },
3201 { "IRPC", K_IRPC
, 0 },
3202 { "ENDR", K_AENDR
, 0 },
3206 /* Look for a pseudo op on the line. If one's there then call
3210 process_pseudo_op (idx
, line
, acc
)
3217 if (line
->ptr
[idx
] == '.' || alternate
|| mri
)
3219 /* Scan forward and find pseudo name */
3225 if (line
->ptr
[idx
] == '.')
3227 in
= line
->ptr
+ idx
;
3232 while (idx
< line
->len
&& *e
&& ISFIRSTCHAR (*e
))
3234 sb_add_char (acc
, *e
);
3239 ptr
= hash_lookup (&keyword_hash_table
, acc
);
3244 /* This one causes lots of pain when trying to preprocess
3246 WARNING ((stderr
, _("Unrecognised pseudo op `%s'.\n"), sb_name (acc
)));
3250 if (ptr
->value
.i
& LAB
)
3251 { /* output the label */
3254 fprintf (outfile
, "%s:\t", sb_name (&label
));
3257 fprintf (outfile
, "\t");
3260 if (mri
&& ptr
->value
.i
== K_END
)
3265 sb_add_buffer (&t
, line
->ptr
+ oidx
, idx
- oidx
);
3266 fprintf (outfile
, "\t%s", sb_name (&t
));
3270 if (ptr
->value
.i
& PROCESS
)
3272 /* Polish the rest of the line before handling the pseudo op */
3274 strip_comments(line
);
3277 process_assigns (idx
, line
, acc
);
3279 change_base (0, acc
, line
);
3284 switch (ptr
->value
.i
)
3300 switch (ptr
->value
.i
)
3304 macro_init (1, mri
, 0, exp_get_abs
);
3313 ERROR ((stderr
, _("ORG command not allowed.\n")));
3319 do_data (idx
, line
, 1);
3322 do_data (idx
, line
, 2);
3325 do_data (idx
, line
, 4);
3328 do_data (idx
, line
, 0);
3331 do_datab (idx
, line
);
3334 do_sdata (idx
, line
, 0);
3337 do_sdatab (idx
, line
);
3340 do_sdata (idx
, line
, 'c');
3343 do_sdata (idx
, line
, 'z');
3346 do_assign (0, 0, line
);
3352 do_arepeat (idx
, line
);
3358 do_awhile (idx
, line
);
3364 do_assign (1, idx
, line
);
3367 do_align (idx
, line
);
3370 do_res (idx
, line
, 0);
3373 do_res (idx
, line
, 's');
3376 do_include (idx
, line
);
3379 do_local (idx
, line
);
3382 do_macro (idx
, line
);
3388 do_res (idx
, line
, 'c');
3391 do_print (idx
, line
);
3394 do_form (idx
, line
);
3397 do_heading (idx
, line
);
3409 do_res (idx
, line
, 'z');
3417 do_assigna (idx
, line
);
3420 do_assignc (idx
, line
);
3429 do_if (idx
, line
, EQ
);
3432 do_if (idx
, line
, NE
);
3435 do_if (idx
, line
, LT
);
3438 do_if (idx
, line
, LE
);
3441 do_if (idx
, line
, GE
);
3444 do_if (idx
, line
, GT
);
3447 do_ifc (idx
, line
, 0);
3450 do_ifc (idx
, line
, 1);
3453 do_irp (idx
, line
, 0);
3456 do_irp (idx
, line
, 1);
3466 /* Add a keyword to the hash table. */
3469 add_keyword (name
, code
)
3477 sb_add_string (&label
, name
);
3479 hash_add_to_int_table (&keyword_hash_table
, &label
, code
);
3482 for (j
= 0; name
[j
]; j
++)
3483 sb_add_char (&label
, name
[j
] - 'A' + 'a');
3484 hash_add_to_int_table (&keyword_hash_table
, &label
, code
);
3489 /* Build the keyword hash table - put each keyword in the table twice,
3490 once upper and once lower case.*/
3497 for (i
= 0; kinfo
[i
].name
; i
++)
3498 add_keyword (kinfo
[i
].name
, kinfo
[i
].code
);
3502 for (i
= 0; mrikinfo
[i
].name
; i
++)
3503 add_keyword (mrikinfo
[i
].name
, mrikinfo
[i
].code
);
3527 sb_add_char (&value
, *string
);
3530 exp_get_abs (_("Invalid expression on command line.\n"), 0, &value
, &res
);
3534 sb_add_char (&label
, *string
);
3539 ptr
= hash_create (&vars
, &label
);
3540 free_old_entry (ptr
);
3541 ptr
->type
= hash_integer
;
3547 /* The list of long options. */
3548 static struct option long_options
[] =
3550 { "alternate", no_argument
, 0, 'a' },
3551 { "include", required_argument
, 0, 'I' },
3552 { "commentchar", required_argument
, 0, 'c' },
3553 { "copysource", no_argument
, 0, 's' },
3554 { "debug", no_argument
, 0, 'd' },
3555 { "help", no_argument
, 0, 'h' },
3556 { "mri", no_argument
, 0, 'M' },
3557 { "output", required_argument
, 0, 'o' },
3558 { "print", no_argument
, 0, 'p' },
3559 { "unreasonable", no_argument
, 0, 'u' },
3560 { "version", no_argument
, 0, 'v' },
3561 { "define", required_argument
, 0, 'd' },
3562 { NULL
, no_argument
, 0, 0 }
3565 /* Show a usage message and exit. */
3567 show_usage (file
, status
)
3573 [-a] [--alternate] enter alternate macro mode\n\
3574 [-c char] [--commentchar char] change the comment character from !\n\
3575 [-d] [--debug] print some debugging info\n\
3576 [-h] [--help] print this message\n\
3577 [-M] [--mri] enter MRI compatibility mode\n\
3578 [-o out] [--output out] set the output file\n\
3579 [-p] [--print] print line numbers\n"), program_name
);
3581 [-s] [--copysource] copy source through as comments \n\
3582 [-u] [--unreasonable] allow unreasonable nesting\n\
3583 [-v] [--version] print the program version\n\
3584 [-Dname=value] create preprocessor variable called name, with value\n\
3585 [-Ipath] add to include path list\n\
3588 printf (_("\nReport bugs to bug-gnu-utils@gnu.org\n"));
3592 /* Display a help message and exit. */
3596 printf (_("%s: Gnu Assembler Macro Preprocessor\n"),
3598 show_usage (stdout
, 0);
3613 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
3614 setlocale (LC_MESSAGES
, "");
3616 bindtextdomain (PACKAGE
, LOCALEDIR
);
3617 textdomain (PACKAGE
);
3619 program_name
= argv
[0];
3620 xmalloc_set_program_name (program_name
);
3622 hash_new_table (101, &keyword_hash_table
);
3623 hash_new_table (101, &assign_hash_table
);
3624 hash_new_table (101, &vars
);
3628 while ((opt
= getopt_long (argc
, argv
, "I:sdhavc:upo:D:M", long_options
,
3642 include_path
*p
= (include_path
*) xmalloc (sizeof (include_path
));
3645 sb_add_string (&p
->path
, optarg
);
3647 paths_tail
->next
= p
;
3654 print_line_number
= 1;
3657 comment_char
= optarg
[0];
3679 /* This output is intended to follow the GNU standards document. */
3680 printf (_("GNU assembler pre-processor %s\n"), program_version
);
3681 printf (_("Copyright 1996 Free Software Foundation, Inc.\n"));
3683 This program is free software; you may redistribute it under the terms of\n\
3684 the GNU General Public License. This program has absolutely no warranty.\n"));
3690 show_usage (stderr
, 1);
3697 macro_init (alternate
, mri
, 0, exp_get_abs
);
3700 outfile
= fopen (out_name
, "w");
3703 fprintf (stderr
, _("%s: Can't open output file `%s'.\n"),
3704 program_name
, out_name
);
3716 /* Process all the input files */
3718 while (optind
< argc
)
3720 if (new_file (argv
[optind
]))
3726 fprintf (stderr
, _("%s: Can't open input file `%s'.\n"),
3727 program_name
, argv
[optind
]);
3737 /* This function is used because an abort in some of the other files
3738 may be compiled into as_abort because they include as.h. */
3741 as_abort (file
, line
, fn
)
3742 const char *file
, *fn
;
3745 fprintf (stderr
, _("Internal error, aborting at %s line %d"), file
, line
);
3747 fprintf (stderr
, " in %s", fn
);
3748 fprintf (stderr
, _("\nPlease report this bug.\n"));