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 /* Structures used to store macros.
198 Each macro knows its name and included text. It gets built with a
199 list of formal arguments, and also keeps a hash table which points
200 into the list to speed up formal search. Each formal knows its
201 name and its default value. Each time the macro is expanded, the
202 formals get the actual values attatched to them. */
204 /* describe the formal arguments to a macro */
206 typedef struct formal_struct
208 struct formal_struct
*next
; /* next formal in list */
209 sb name
; /* name of the formal */
210 sb def
; /* the default value */
211 sb actual
; /* the actual argument (changed on each expansion) */
212 int index
; /* the index of the formal 0..formal_count-1 */
216 /* describe the macro. */
218 typedef struct macro_struct
220 sb sub
; /* substitution text. */
221 int formal_count
; /* number of formal args. */
222 formal_entry
*formals
; /* pointer to list of formal_structs */
223 hash_table formal_hash
; /* hash table of formals. */
227 /* how we nest files and expand macros etc.
229 we keep a stack of of include_stack structs. each include file
230 pushes a new level onto the stack. we keep an sb with a pushback
231 too. unget chars are pushed onto the pushback sb, getchars first
232 checks the pushback sb before reading from the input stream.
234 small things are expanded by adding the text of the item onto the
235 pushback sb. larger items are grown by pushing a new level and
236 allocating the entire pushback buf for the item. each time
237 something like a macro is expanded, the stack index is changed. we
238 can then perform an exitm by popping all entries off the stack with
239 the same stack index. if we're being reasonable, we can detect
240 recusive expansion by checking the index is reasonably small.
245 include_file
, include_repeat
, include_while
, include_macro
250 sb pushback
; /* current pushback stream */
251 int pushback_index
; /* next char to read from stream */
252 FILE *handle
; /* open file */
253 sb name
; /* name of file */
254 int linecount
; /* number of lines read so far */
256 int index
; /* index of this layer */
258 include_stack
[MAX_INCLUDES
];
260 struct include_stack
*sp
;
261 #define isp (sp - include_stack)
263 /* Include file list */
265 typedef struct include_path
267 struct include_path
*next
;
271 include_path
*paths_head
;
272 include_path
*paths_tail
;
275 static void quit
PARAMS ((void));
276 static void hash_new_table
PARAMS ((int, hash_table
*));
277 static int hash
PARAMS ((sb
*));
278 static hash_entry
*hash_create
PARAMS ((hash_table
*, sb
*));
279 static void hash_add_to_string_table
PARAMS ((hash_table
*, sb
*, sb
*, int));
280 static void hash_add_to_int_table
PARAMS ((hash_table
*, sb
*, int));
281 static hash_entry
*hash_lookup
PARAMS ((hash_table
*, sb
*));
282 static void checkconst
PARAMS ((int, exp_t
*));
283 static int sb_strtol
PARAMS ((int, sb
*, int, int *));
284 static int level_0
PARAMS ((int, sb
*, exp_t
*));
285 static int level_1
PARAMS ((int, sb
*, exp_t
*));
286 static int level_2
PARAMS ((int, sb
*, exp_t
*));
287 static int level_3
PARAMS ((int, sb
*, exp_t
*));
288 static int level_4
PARAMS ((int, sb
*, exp_t
*));
289 static int level_5
PARAMS ((int, sb
*, exp_t
*));
290 static int exp_parse
PARAMS ((int, sb
*, exp_t
*));
291 static void exp_string
PARAMS ((exp_t
*, sb
*));
292 static int exp_get_abs
PARAMS ((const char *, int, sb
*, int *));
294 static void strip_comments
PARAMS ((sb
*));
296 static void unget
PARAMS ((int));
297 static void include_buf
PARAMS ((sb
*, sb
*, include_type
, int));
298 static void include_print_where_line
PARAMS ((FILE *));
299 static void include_print_line
PARAMS ((FILE *));
300 static int get_line
PARAMS ((sb
*));
301 static int grab_label
PARAMS ((sb
*, sb
*));
302 static void change_base
PARAMS ((int, sb
*, sb
*));
303 static void do_end
PARAMS ((sb
*));
304 static void do_assign
PARAMS ((int, int, sb
*));
305 static void do_radix
PARAMS ((sb
*));
306 static int get_opsize
PARAMS ((int, sb
*, int *));
307 static int eol
PARAMS ((int, sb
*));
308 static void do_data
PARAMS ((int, sb
*, int));
309 static void do_datab
PARAMS ((int, sb
*));
310 static void do_align
PARAMS ((int, sb
*));
311 static void do_res
PARAMS ((int, sb
*, int));
312 static void do_export
PARAMS ((sb
*));
313 static void do_print
PARAMS ((int, sb
*));
314 static void do_heading
PARAMS ((int, sb
*));
315 static void do_page
PARAMS ((void));
316 static void do_form
PARAMS ((int, sb
*));
317 static int get_any_string
PARAMS ((int, sb
*, sb
*, int, int));
318 static int skip_openp
PARAMS ((int, sb
*));
319 static int skip_closep
PARAMS ((int, sb
*));
320 static int dolen
PARAMS ((int, sb
*, sb
*));
321 static int doinstr
PARAMS ((int, sb
*, sb
*));
322 static int dosubstr
PARAMS ((int, sb
*, sb
*));
323 static void process_assigns
PARAMS ((int, sb
*, sb
*));
324 static int get_and_process
PARAMS ((int, sb
*, sb
*));
325 static void process_file
PARAMS ((void));
326 static void free_old_entry
PARAMS ((hash_entry
*));
327 static void do_assigna
PARAMS ((int, sb
*));
328 static void do_assignc
PARAMS ((int, sb
*));
329 static void do_reg
PARAMS ((int, sb
*));
330 static int condass_lookup_name
PARAMS ((sb
*, int, sb
*, int));
331 static int whatcond
PARAMS ((int, sb
*, int *));
332 static int istrue
PARAMS ((int, sb
*));
333 static void do_aif
PARAMS ((int, sb
*));
334 static void do_aelse
PARAMS ((void));
335 static void do_aendi
PARAMS ((void));
336 static int condass_on
PARAMS ((void));
337 static void do_if
PARAMS ((int, sb
*, int));
338 static int get_mri_string
PARAMS ((int, sb
*, sb
*, int));
339 static void do_ifc
PARAMS ((int, sb
*, int));
340 static void do_aendr
PARAMS ((void));
341 static void do_awhile
PARAMS ((int, sb
*));
342 static void do_aendw
PARAMS ((void));
343 static void do_exitm
PARAMS ((void));
344 static void do_arepeat
PARAMS ((int, sb
*));
345 static void do_endm
PARAMS ((void));
346 static void do_irp
PARAMS ((int, sb
*, int));
347 static void do_local
PARAMS ((int, sb
*));
348 static void do_macro
PARAMS ((int, sb
*));
349 static int macro_op
PARAMS ((int, sb
*));
350 static int getstring
PARAMS ((int, sb
*, sb
*));
351 static void do_sdata
PARAMS ((int, sb
*, int));
352 static void do_sdatab
PARAMS ((int, sb
*));
353 static int new_file
PARAMS ((const char *));
354 static void do_include
PARAMS ((int, sb
*));
355 static void include_pop
PARAMS ((void));
356 static int get
PARAMS ((void));
357 static int linecount
PARAMS ((void));
358 static int include_next_index
PARAMS ((void));
359 static void chartype_init
PARAMS ((void));
360 static int process_pseudo_op
PARAMS ((int, sb
*, sb
*));
361 static void add_keyword
PARAMS ((const char *, int));
362 static void process_init
PARAMS ((void));
363 static void do_define
PARAMS ((const char *));
364 static void show_usage
PARAMS ((FILE *, int));
365 static void show_help
PARAMS ((void));
368 do { include_print_where_line (stderr); fprintf x ; fatals++; quit(); } while(0)
370 do { include_print_where_line (stderr); fprintf x; errors++; } while(0)
372 do { include_print_where_line (stderr); fprintf x; warnings++;} while(0)
376 /* exit the program and return the right ERROR code. */
389 for (i
= 0; i
< sb_max_power_two
; i
++)
391 fprintf (stderr
, "strings size %8d : %d\n", 1<<i
, string_count
[i
]);
397 /* hash table maintenance. */
399 /* build a new hash table with size buckets, and fill in the info at ptr. */
402 hash_new_table (size
, ptr
)
408 ptr
->table
= (hash_entry
**) xmalloc (size
* (sizeof (hash_entry
*)));
409 /* Fill with null-pointer, not zero-bit-pattern. */
410 for (i
= 0; i
< size
; i
++)
414 /* calculate and return the hash value of the sb at key. */
423 for (i
= 0; i
< key
->len
; i
++)
431 /* lookup key in hash_table tab, if present, then return it, otherwise
432 build a new one and fill it with hash_integer. */
436 hash_create (tab
, key
)
440 int k
= hash (key
) % tab
->size
;
442 hash_entry
**table
= tab
->table
;
450 hash_entry
*n
= (hash_entry
*) xmalloc (sizeof (hash_entry
));
453 sb_add_sb (&n
->key
, key
);
455 n
->type
= hash_integer
;
458 if (strncmp (table
[k
]->key
.ptr
, key
->ptr
, key
->len
) == 0)
466 /* add sb name with key into hash_table tab. if replacing old value
467 and again, then ERROR. */
471 hash_add_to_string_table (tab
, key
, name
, again
)
477 hash_entry
*ptr
= hash_create (tab
, key
);
478 if (ptr
->type
== hash_integer
)
480 sb_new (&ptr
->value
.s
);
482 if (ptr
->value
.s
.len
)
485 ERROR ((stderr
, _("redefinition not allowed\n")));
488 ptr
->type
= hash_string
;
489 sb_reset (&ptr
->value
.s
);
491 sb_add_sb (&ptr
->value
.s
, name
);
494 /* add integer name to hash_table tab with sb key. */
498 hash_add_to_int_table (tab
, key
, name
)
503 hash_entry
*ptr
= hash_create (tab
, key
);
507 /* lookup sb key in hash_table tab. if found return hash_entry result,
512 hash_lookup (tab
, key
)
516 int k
= hash (key
) % tab
->size
;
517 hash_entry
**table
= tab
->table
;
518 hash_entry
*p
= table
[k
];
521 if (p
->key
.len
== key
->len
522 && strncmp (p
->key
.ptr
, key
->ptr
, key
->len
) == 0)
532 are handled in a really simple recursive decent way. each bit of
533 the machine takes an index into an sb and a pointer to an exp_t,
534 modifies the *exp_t and returns the index of the first character
535 past the part of the expression parsed.
537 expression precedence:
548 /* make sure that the exp_t at term is constant, if not the give the op ERROR. */
552 checkconst (op
, term
)
556 if (term
->add_symbol
.len
557 || term
->sub_symbol
.len
)
559 ERROR ((stderr
, _("the %c operator cannot take non-absolute arguments.\n"), op
));
563 /* turn the number in string at idx into a number of base,
564 fill in ptr and return the index of the first character not in the
569 sb_strtol (idx
, string
, base
, ptr
)
576 idx
= sb_skip_white (idx
, string
);
578 while (idx
< string
->len
)
580 int ch
= string
->ptr
[idx
];
584 else if (ch
>= 'a' && ch
<= 'f')
586 else if (ch
>= 'A' && ch
<= 'F')
594 value
= value
* base
+ dig
;
602 level_0 (idx
, string
, lhs
)
607 lhs
->add_symbol
.len
= 0;
608 lhs
->add_symbol
.name
= 0;
610 lhs
->sub_symbol
.len
= 0;
611 lhs
->sub_symbol
.name
= 0;
613 idx
= sb_skip_white (idx
, string
);
617 if (isdigit ((unsigned char) string
->ptr
[idx
]))
619 idx
= sb_strtol (idx
, string
, 10, &lhs
->value
);
621 else if (ISFIRSTCHAR (string
->ptr
[idx
]))
624 lhs
->add_symbol
.name
= string
->ptr
+ idx
;
625 while (idx
< string
->len
&& ISNEXTCHAR (string
->ptr
[idx
]))
630 lhs
->add_symbol
.len
= len
;
632 else if (string
->ptr
[idx
] == '"')
636 ERROR ((stderr
, _("string where expression expected.\n")));
637 idx
= getstring (idx
, string
, &acc
);
642 ERROR ((stderr
, _("can't find primary in expression.\n")));
645 return sb_skip_white (idx
, string
);
651 level_1 (idx
, string
, lhs
)
656 idx
= sb_skip_white (idx
, string
);
658 switch (string
->ptr
[idx
])
661 idx
= level_1 (idx
+ 1, string
, lhs
);
664 idx
= level_1 (idx
+ 1, string
, lhs
);
665 checkconst ('~', lhs
);
666 lhs
->value
= ~lhs
->value
;
671 idx
= level_1 (idx
+ 1, string
, lhs
);
672 lhs
->value
= -lhs
->value
;
674 lhs
->add_symbol
= lhs
->sub_symbol
;
680 idx
= level_5 (sb_skip_white (idx
, string
), string
, lhs
);
681 if (string
->ptr
[idx
] != ')')
682 ERROR ((stderr
, _("misplaced closing parens.\n")));
687 idx
= level_0 (idx
, string
, lhs
);
690 return sb_skip_white (idx
, string
);
694 level_2 (idx
, string
, lhs
)
701 idx
= level_1 (idx
, string
, lhs
);
703 while (idx
< string
->len
&& (string
->ptr
[idx
] == '*'
704 || string
->ptr
[idx
] == '/'))
706 char op
= string
->ptr
[idx
++];
707 idx
= level_1 (idx
, string
, &rhs
);
711 checkconst ('*', lhs
);
712 checkconst ('*', &rhs
);
713 lhs
->value
*= rhs
.value
;
716 checkconst ('/', lhs
);
717 checkconst ('/', &rhs
);
719 ERROR ((stderr
, _("attempt to divide by zero.\n")));
721 lhs
->value
/= rhs
.value
;
725 return sb_skip_white (idx
, string
);
730 level_3 (idx
, string
, lhs
)
737 idx
= level_2 (idx
, string
, lhs
);
739 while (idx
< string
->len
740 && (string
->ptr
[idx
] == '+'
741 || string
->ptr
[idx
] == '-'))
743 char op
= string
->ptr
[idx
++];
744 idx
= level_2 (idx
, string
, &rhs
);
748 lhs
->value
+= rhs
.value
;
749 if (lhs
->add_symbol
.name
&& rhs
.add_symbol
.name
)
751 ERROR ((stderr
, _("can't add two relocatable expressions\n")));
753 /* change nn+symbol to symbol + nn */
754 if (rhs
.add_symbol
.name
)
756 lhs
->add_symbol
= rhs
.add_symbol
;
760 lhs
->value
-= rhs
.value
;
761 lhs
->sub_symbol
= rhs
.add_symbol
;
765 return sb_skip_white (idx
, string
);
769 level_4 (idx
, string
, lhs
)
776 idx
= level_3 (idx
, string
, lhs
);
778 while (idx
< string
->len
&&
779 string
->ptr
[idx
] == '&')
781 char op
= string
->ptr
[idx
++];
782 idx
= level_3 (idx
, string
, &rhs
);
786 checkconst ('&', lhs
);
787 checkconst ('&', &rhs
);
788 lhs
->value
&= rhs
.value
;
792 return sb_skip_white (idx
, string
);
796 level_5 (idx
, string
, lhs
)
803 idx
= level_4 (idx
, string
, lhs
);
805 while (idx
< string
->len
806 && (string
->ptr
[idx
] == '|' || string
->ptr
[idx
] == '~'))
808 char op
= string
->ptr
[idx
++];
809 idx
= level_4 (idx
, string
, &rhs
);
813 checkconst ('|', lhs
);
814 checkconst ('|', &rhs
);
815 lhs
->value
|= rhs
.value
;
818 checkconst ('~', lhs
);
819 checkconst ('~', &rhs
);
820 lhs
->value
^= rhs
.value
;
824 return sb_skip_white (idx
, string
);
828 /* parse the expression at offset idx into string, fill up res with
829 the result. return the index of the first char past the expression.
833 exp_parse (idx
, string
, res
)
838 return level_5 (sb_skip_white (idx
, string
), string
, res
);
842 /* turn the expression at exp into text and glue it onto the end of
846 exp_string (exp
, string
)
854 if (exp
->add_symbol
.len
)
856 sb_add_buffer (string
, exp
->add_symbol
.name
, exp
->add_symbol
.len
);
864 sb_add_char (string
, '+');
865 sprintf (buf
, "%d", exp
->value
);
866 sb_add_string (string
, buf
);
870 if (exp
->sub_symbol
.len
)
872 sb_add_char (string
, '-');
873 sb_add_buffer (string
, exp
->add_symbol
.name
, exp
->add_symbol
.len
);
879 sb_add_char (string
, '0');
883 /* parse the expression at offset idx into sb in, return the value in val.
884 if the expression is not constant, give ERROR emsg. returns the index
885 of the first character past the end of the expression. */
888 exp_get_abs (emsg
, idx
, in
, val
)
895 idx
= exp_parse (idx
, in
, &res
);
896 if (res
.add_symbol
.len
|| res
.sub_symbol
.len
)
897 ERROR ((stderr
, "%s", emsg
));
903 sb label
; /* current label parsed from line */
904 hash_table assign_hash_table
; /* hash table for all assigned variables */
905 hash_table keyword_hash_table
; /* hash table for keyword */
906 hash_table vars
; /* hash table for eq variables */
908 #define in_comment ';'
917 for (i
= 0; i
< out
->len
; i
++)
919 if (ISCOMMENTCHAR(s
[i
]))
928 /* push back character ch so that it can be read again. */
938 if (sp
->pushback_index
)
939 sp
->pushback_index
--;
941 sb_add_char (&sp
->pushback
, ch
);
944 /* push the sb ptr onto the include stack, with the given name, type and index. */
948 include_buf (name
, ptr
, type
, index
)
955 if (sp
- include_stack
>= MAX_INCLUDES
)
956 FATAL ((stderr
, _("unreasonable nesting.\n")));
958 sb_add_sb (&sp
->name
, name
);
961 sp
->pushback_index
= 0;
964 sb_new (&sp
->pushback
);
965 sb_add_sb (&sp
->pushback
, ptr
);
969 /* used in ERROR messages, print info on where the include stack is onto file. */
972 include_print_where_line (file
)
975 struct include_stack
*p
= include_stack
+ 1;
979 fprintf (file
, "%s:%d ", sb_name (&p
->name
), p
->linecount
- 1);
984 /* used in listings, print the line number onto file. */
986 include_print_line (file
)
990 struct include_stack
*p
= include_stack
+ 1;
992 n
= fprintf (file
, "%4d", p
->linecount
);
996 n
+= fprintf (file
, ".%d", p
->linecount
);
1001 fprintf (file
, " ");
1007 /* read a line from the top of the include stack into sb in. */
1018 putc (comment_char
, outfile
);
1019 if (print_line_number
)
1020 include_print_line (outfile
);
1034 WARNING ((stderr
, _("End of file not at start of line.\n")));
1036 putc ('\n', outfile
);
1055 /* continued line */
1058 putc (comment_char
, outfile
);
1059 putc ('+', outfile
);
1072 sb_add_char (in
, ch
);
1080 /* find a label from sb in and put it in out. */
1083 grab_label (in
, out
)
1089 if (ISFIRSTCHAR (in
->ptr
[i
]) || in
->ptr
[i
] == '\\')
1091 sb_add_char (out
, in
->ptr
[i
]);
1093 while ((ISNEXTCHAR (in
->ptr
[i
])
1094 || in
->ptr
[i
] == '\\'
1095 || in
->ptr
[i
] == '&')
1098 sb_add_char (out
, in
->ptr
[i
]);
1105 /* find all strange base stuff and turn into decimal. also
1106 find all the other numbers and convert them from the default radix */
1109 change_base (idx
, in
, out
)
1116 while (idx
< in
->len
)
1118 if (in
->ptr
[idx
] == '\\'
1119 && idx
+ 1 < in
->len
1120 && in
->ptr
[idx
+ 1] == '(')
1123 while (idx
< in
->len
1124 && in
->ptr
[idx
] != ')')
1126 sb_add_char (out
, in
->ptr
[idx
]);
1132 else if (idx
< in
->len
- 1 && in
->ptr
[idx
+ 1] == '\'' && ! mri
)
1136 switch (in
->ptr
[idx
])
1155 ERROR ((stderr
, _("Illegal base character %c.\n"), in
->ptr
[idx
]));
1160 idx
= sb_strtol (idx
+ 2, in
, base
, &value
);
1161 sprintf (buffer
, "%d", value
);
1162 sb_add_string (out
, buffer
);
1164 else if (ISFIRSTCHAR (in
->ptr
[idx
]))
1166 /* copy entire names through quickly */
1167 sb_add_char (out
, in
->ptr
[idx
]);
1169 while (idx
< in
->len
&& ISNEXTCHAR (in
->ptr
[idx
]))
1171 sb_add_char (out
, in
->ptr
[idx
]);
1175 else if (isdigit ((unsigned char) in
->ptr
[idx
]))
1178 /* all numbers must start with a digit, let's chew it and
1180 idx
= sb_strtol (idx
, in
, radix
, &value
);
1181 sprintf (buffer
, "%d", value
);
1182 sb_add_string (out
, buffer
);
1184 /* skip all undigsested letters */
1185 while (idx
< in
->len
&& ISNEXTCHAR (in
->ptr
[idx
]))
1187 sb_add_char (out
, in
->ptr
[idx
]);
1191 else if (in
->ptr
[idx
] == '"' || in
->ptr
[idx
] == '\'')
1193 char tchar
= in
->ptr
[idx
];
1194 /* copy entire names through quickly */
1195 sb_add_char (out
, in
->ptr
[idx
]);
1197 while (idx
< in
->len
&& in
->ptr
[idx
] != tchar
)
1199 sb_add_char (out
, in
->ptr
[idx
]);
1205 /* nothing special, just pass it through */
1206 sb_add_char (out
, in
->ptr
[idx
]);
1220 fprintf (outfile
, "%s\n", sb_name (in
));
1226 do_assign (again
, idx
, in
)
1231 /* stick label in symbol table with following value */
1236 idx
= exp_parse (idx
, in
, &e
);
1237 exp_string (&e
, &acc
);
1238 hash_add_to_string_table (&assign_hash_table
, &label
, &acc
, again
);
1243 /* .radix [b|q|d|h] */
1250 int idx
= sb_skip_white (0, ptr
);
1251 switch (ptr
->ptr
[idx
])
1270 ERROR ((stderr
, _("radix is %c must be one of b, q, d or h"), radix
));
1275 /* Parse off a .b, .w or .l */
1278 get_opsize (idx
, in
, size
)
1284 if (in
->ptr
[idx
] == '.')
1288 switch (in
->ptr
[idx
])
1306 ERROR ((stderr
, _("size must be one of b, w or l, is %c.\n"), in
->ptr
[idx
]));
1319 idx
= sb_skip_white (idx
, line
);
1321 && ISCOMMENTCHAR(line
->ptr
[idx
]))
1323 if (idx
>= line
->len
)
1328 /* .data [.b|.w|.l] <data>*
1329 or d[bwl] <data>* */
1332 do_data (idx
, in
, size
)
1338 char *opname
= ".yikes!";
1344 idx
= get_opsize (idx
, in
, &opsize
);
1363 fprintf (outfile
, "%s\t", opname
);
1365 idx
= sb_skip_white (idx
, in
);
1369 && in
->ptr
[idx
] == '"')
1372 idx
= getstring (idx
, in
, &acc
);
1373 for (i
= 0; i
< acc
.len
; i
++)
1376 fprintf(outfile
,",");
1377 fprintf (outfile
, "%d", acc
.ptr
[i
]);
1382 while (!eol (idx
, in
))
1385 idx
= exp_parse (idx
, in
, &e
);
1386 exp_string (&e
, &acc
);
1387 sb_add_char (&acc
, 0);
1388 fprintf (outfile
, "%s", acc
.ptr
);
1389 if (idx
< in
->len
&& in
->ptr
[idx
] == ',')
1391 fprintf (outfile
, ",");
1397 sb_print_at (outfile
, idx
, in
);
1398 fprintf (outfile
, "\n");
1401 /* .datab [.b|.w|.l] <repeat>,<fill> */
1412 idx
= get_opsize (idx
, in
, &opsize
);
1414 idx
= exp_get_abs (_("datab repeat must be constant.\n"), idx
, in
, &repeat
);
1415 idx
= sb_skip_comma (idx
, in
);
1416 idx
= exp_get_abs (_("datab data must be absolute.\n"), idx
, in
, &fill
);
1418 fprintf (outfile
, ".fill\t%d,%d,%d\n", repeat
, opsize
, fill
);
1428 int al
, have_fill
, fill
;
1430 idx
= exp_get_abs (_("align needs absolute expression.\n"), idx
, in
, &al
);
1431 idx
= sb_skip_white (idx
, in
);
1434 if (! eol (idx
, in
))
1436 idx
= sb_skip_comma (idx
, in
);
1437 idx
= exp_get_abs (_(".align needs absolute fill value.\n"), idx
, in
,
1445 WARNING ((stderr
, _("alignment must be one of 1, 2 or 4.\n")));
1447 fprintf (outfile
, ".align %d", al
);
1449 fprintf (outfile
, ",%d", fill
);
1450 fprintf (outfile
, "\n");
1453 /* .res[.b|.w|.l] <size> */
1456 do_res (idx
, in
, type
)
1464 idx
= get_opsize (idx
, in
, &size
);
1465 while (!eol(idx
, in
))
1467 idx
= sb_skip_white (idx
, in
);
1468 if (in
->ptr
[idx
] == ',')
1470 idx
= exp_get_abs (_("res needs absolute expression for fill count.\n"), idx
, in
, &count
);
1472 if (type
== 'c' || type
== 'z')
1475 fprintf (outfile
, ".space %d\n", count
* size
);
1486 fprintf (outfile
, ".global %s\n", sb_name (in
));
1489 /* .print [list] [nolist] */
1496 idx
= sb_skip_white (idx
, in
);
1497 while (idx
< in
->len
)
1499 if (strncasecmp (in
->ptr
+ idx
, "LIST", 4) == 0)
1501 fprintf (outfile
, ".list\n");
1504 else if (strncasecmp (in
->ptr
+ idx
, "NOLIST", 6) == 0)
1506 fprintf (outfile
, ".nolist\n");
1515 do_heading (idx
, in
)
1521 idx
= getstring (idx
, in
, &head
);
1522 fprintf (outfile
, ".title \"%s\"\n", sb_name (&head
));
1531 fprintf (outfile
, ".eject\n");
1534 /* .form [lin=<value>] [col=<value>] */
1542 idx
= sb_skip_white (idx
, in
);
1544 while (idx
< in
->len
)
1547 if (strncasecmp (in
->ptr
+ idx
, "LIN=", 4) == 0)
1550 idx
= exp_get_abs (_("form LIN= needs absolute expresssion.\n"), idx
, in
, &lines
);
1553 if (strncasecmp (in
->ptr
+ idx
, _("COL="), 4) == 0)
1556 idx
= exp_get_abs (_("form COL= needs absolute expresssion.\n"), idx
, in
, &columns
);
1561 fprintf (outfile
, ".psize %d,%d\n", lines
, columns
);
1566 /* Fetch string from the input stream,
1568 'Bxyx<whitespace> -> return 'Bxyza
1569 %<char> -> return string of decimal value of x
1570 "<string>" -> return string
1571 xyx<whitespace> -> return xyz
1574 get_any_string (idx
, in
, out
, expand
, pretend_quoted
)
1582 idx
= sb_skip_white (idx
, in
);
1586 if (in
->len
> 2 && in
->ptr
[idx
+1] == '\'' && ISBASE (in
->ptr
[idx
]))
1588 while (!ISSEP (in
->ptr
[idx
]))
1589 sb_add_char (out
, in
->ptr
[idx
++]);
1591 else if (in
->ptr
[idx
] == '%'
1597 /* Turns the next expression into a string */
1598 idx
= exp_get_abs (_("% operator needs absolute expression"),
1602 sprintf(buf
, "%d", val
);
1603 sb_add_string (out
, buf
);
1605 else if (in
->ptr
[idx
] == '"'
1606 || in
->ptr
[idx
] == '<'
1607 || (alternate
&& in
->ptr
[idx
] == '\''))
1609 if (alternate
&& expand
)
1611 /* Keep the quotes */
1612 sb_add_char (out
, '\"');
1614 idx
= getstring (idx
, in
, out
);
1615 sb_add_char (out
, '\"');
1619 idx
= getstring (idx
, in
, out
);
1624 while (idx
< in
->len
1625 && (in
->ptr
[idx
] == '"'
1626 || in
->ptr
[idx
] == '\''
1628 || !ISSEP (in
->ptr
[idx
])))
1630 if (in
->ptr
[idx
] == '"'
1631 || in
->ptr
[idx
] == '\'')
1633 char tchar
= in
->ptr
[idx
];
1634 sb_add_char (out
, in
->ptr
[idx
++]);
1635 while (idx
< in
->len
1636 && in
->ptr
[idx
] != tchar
)
1637 sb_add_char (out
, in
->ptr
[idx
++]);
1641 sb_add_char (out
, in
->ptr
[idx
++]);
1650 /* skip along sb in starting at idx, suck off whitespace a ( and more
1651 whitespace. return the idx of the next char */
1654 skip_openp (idx
, in
)
1658 idx
= sb_skip_white (idx
, in
);
1659 if (in
->ptr
[idx
] != '(')
1660 ERROR ((stderr
, _("misplaced ( .\n")));
1661 idx
= sb_skip_white (idx
+ 1, in
);
1665 /* skip along sb in starting at idx, suck off whitespace a ) and more
1666 whitespace. return the idx of the next char */
1669 skip_closep (idx
, in
)
1673 idx
= sb_skip_white (idx
, in
);
1674 if (in
->ptr
[idx
] != ')')
1675 ERROR ((stderr
, _("misplaced ).\n")));
1676 idx
= sb_skip_white (idx
+ 1, in
);
1683 dolen (idx
, in
, out
)
1692 sb_new (&stringout
);
1693 idx
= skip_openp (idx
, in
);
1694 idx
= get_and_process (idx
, in
, &stringout
);
1695 idx
= skip_closep (idx
, in
);
1696 sprintf (buffer
, "%d", stringout
.len
);
1697 sb_add_string (out
, buffer
);
1699 sb_kill (&stringout
);
1708 doinstr (idx
, in
, out
)
1722 idx
= skip_openp (idx
, in
);
1723 idx
= get_and_process (idx
, in
, &string
);
1724 idx
= sb_skip_comma (idx
, in
);
1725 idx
= get_and_process (idx
, in
, &search
);
1726 idx
= sb_skip_comma (idx
, in
);
1727 if (isdigit ((unsigned char) in
->ptr
[idx
]))
1729 idx
= exp_get_abs (_(".instr needs absolute expresson.\n"), idx
, in
, &start
);
1735 idx
= skip_closep (idx
, in
);
1737 for (i
= start
; i
< string
.len
; i
++)
1739 if (strncmp (string
.ptr
+ i
, search
.ptr
, search
.len
) == 0)
1745 sprintf (buffer
, "%d", res
);
1746 sb_add_string (out
, buffer
);
1754 dosubstr (idx
, in
, out
)
1764 idx
= skip_openp (idx
, in
);
1765 idx
= get_and_process (idx
, in
, &string
);
1766 idx
= sb_skip_comma (idx
, in
);
1767 idx
= exp_get_abs (_("need absolute position.\n"), idx
, in
, &pos
);
1768 idx
= sb_skip_comma (idx
, in
);
1769 idx
= exp_get_abs (_("need absolute length.\n"), idx
, in
, &len
);
1770 idx
= skip_closep (idx
, in
);
1773 if (len
< 0 || pos
< 0 ||
1775 || pos
+ len
> string
.len
)
1777 sb_add_string (out
, " ");
1781 sb_add_char (out
, '"');
1784 sb_add_char (out
, string
.ptr
[pos
++]);
1787 sb_add_char (out
, '"');
1793 /* scan line, change tokens in the hash table to their replacements */
1795 process_assigns (idx
, in
, buf
)
1800 while (idx
< in
->len
)
1803 if (in
->ptr
[idx
] == '\\'
1804 && idx
+ 1 < in
->len
1805 && in
->ptr
[idx
+ 1] == '(')
1809 sb_add_char (buf
, in
->ptr
[idx
]);
1812 while (idx
< in
->len
&& in
->ptr
[idx
- 1] != ')');
1814 else if (in
->ptr
[idx
] == '\\'
1815 && idx
+ 1 < in
->len
1816 && in
->ptr
[idx
+ 1] == '&')
1818 idx
= condass_lookup_name (in
, idx
+ 2, buf
, 1);
1820 else if (in
->ptr
[idx
] == '\\'
1821 && idx
+ 1 < in
->len
1822 && in
->ptr
[idx
+ 1] == '$')
1824 idx
= condass_lookup_name (in
, idx
+ 2, buf
, 0);
1826 else if (idx
+ 3 < in
->len
1827 && in
->ptr
[idx
] == '.'
1828 && toupper ((unsigned char) in
->ptr
[idx
+ 1]) == 'L'
1829 && toupper ((unsigned char) in
->ptr
[idx
+ 2]) == 'E'
1830 && toupper ((unsigned char) in
->ptr
[idx
+ 3]) == 'N')
1831 idx
= dolen (idx
+ 4, in
, buf
);
1832 else if (idx
+ 6 < in
->len
1833 && in
->ptr
[idx
] == '.'
1834 && toupper ((unsigned char) in
->ptr
[idx
+ 1]) == 'I'
1835 && toupper ((unsigned char) in
->ptr
[idx
+ 2]) == 'N'
1836 && toupper ((unsigned char) in
->ptr
[idx
+ 3]) == 'S'
1837 && toupper ((unsigned char) in
->ptr
[idx
+ 4]) == 'T'
1838 && toupper ((unsigned char) in
->ptr
[idx
+ 5]) == 'R')
1839 idx
= doinstr (idx
+ 6, in
, buf
);
1840 else if (idx
+ 7 < in
->len
1841 && in
->ptr
[idx
] == '.'
1842 && toupper ((unsigned char) in
->ptr
[idx
+ 1]) == 'S'
1843 && toupper ((unsigned char) in
->ptr
[idx
+ 2]) == 'U'
1844 && toupper ((unsigned char) in
->ptr
[idx
+ 3]) == 'B'
1845 && toupper ((unsigned char) in
->ptr
[idx
+ 4]) == 'S'
1846 && toupper ((unsigned char) in
->ptr
[idx
+ 5]) == 'T'
1847 && toupper ((unsigned char) in
->ptr
[idx
+ 6]) == 'R')
1848 idx
= dosubstr (idx
+ 7, in
, buf
);
1849 else if (ISFIRSTCHAR (in
->ptr
[idx
]))
1851 /* may be a simple name subsitution, see if we have a word */
1854 while (cur
< in
->len
1855 && (ISNEXTCHAR (in
->ptr
[cur
])))
1859 sb_add_buffer (&acc
, in
->ptr
+ idx
, cur
- idx
);
1860 ptr
= hash_lookup (&assign_hash_table
, &acc
);
1863 /* Found a definition for it */
1864 sb_add_sb (buf
, &ptr
->value
.s
);
1868 /* No definition, just copy the word */
1869 sb_add_sb (buf
, &acc
);
1876 sb_add_char (buf
, in
->ptr
[idx
++]);
1882 get_and_process (idx
, in
, out
)
1889 idx
= get_any_string (idx
, in
, &t
, 1, 0);
1890 process_assigns (0, &t
, out
);
1911 more
= get_line (&line
);
1914 /* Find any label and pseudo op that we're intested in */
1919 fprintf (outfile
, "\n");
1922 && (line
.ptr
[0] == '*'
1923 || line
.ptr
[0] == '!'))
1925 /* MRI line comment. */
1926 fprintf (outfile
, "%s", sb_name (&line
));
1930 l
= grab_label (&line
, &label_in
);
1933 if (line
.ptr
[l
] == ':')
1935 while (ISWHITE (line
.ptr
[l
]) && l
< line
.len
)
1942 /* Munge the label, unless this is EQU or ASSIGN. */
1945 && (line
.ptr
[l
] == '.' || alternate
|| mri
))
1949 if (line
.ptr
[lx
] == '.')
1951 if (lx
+ 3 <= line
.len
1952 && strncasecmp ("EQU", line
.ptr
+ lx
, 3) == 0
1953 && (lx
+ 3 == line
.len
1954 || ! ISFIRSTCHAR (line
.ptr
[lx
+ 3])))
1956 else if (lx
+ 6 <= line
.len
1957 && strncasecmp ("ASSIGN", line
.ptr
+ lx
, 6) == 0
1958 && (lx
+ 6 == line
.len
1959 || ! ISFIRSTCHAR (line
.ptr
[lx
+ 6])))
1964 process_assigns (0, &label_in
, &label
);
1966 sb_add_sb (&label
, &label_in
);
1971 if (process_pseudo_op (l
, &line
, &acc
))
1977 else if (condass_on ())
1979 if (macro_op (l
, &line
))
1989 fprintf (outfile
, "%s:\t", sb_name (&label
));
1992 fprintf (outfile
, "\t");
1994 process_assigns (l
, &line
, &t1
);
1996 change_base (0, &t1
, &t2
);
1997 fprintf (outfile
, "%s\n", sb_name (&t2
));
2003 /* Only a label on this line */
2004 if (label
.len
&& condass_on())
2006 fprintf (outfile
, "%s:\n", sb_name (&label
));
2014 more
= get_line (&line
);
2017 if (!had_end
&& !mri
)
2018 WARNING ((stderr
, _("END missing from end of file.\n")));
2026 free_old_entry (ptr
)
2031 if (ptr
->type
== hash_string
)
2032 sb_kill(&ptr
->value
.s
);
2036 /* name: .ASSIGNA <value> */
2039 do_assigna (idx
, in
)
2047 process_assigns (idx
, in
, &tmp
);
2048 idx
= exp_get_abs (_(".ASSIGNA needs constant expression argument.\n"), 0, &tmp
, &val
);
2052 ERROR ((stderr
, _(".ASSIGNA without label.\n")));
2056 hash_entry
*ptr
= hash_create (&vars
, &label
);
2057 free_old_entry (ptr
);
2058 ptr
->type
= hash_integer
;
2064 /* name: .ASSIGNC <string> */
2067 do_assignc (idx
, in
)
2073 idx
= getstring (idx
, in
, &acc
);
2077 ERROR ((stderr
, _(".ASSIGNS without label.\n")));
2081 hash_entry
*ptr
= hash_create (&vars
, &label
);
2082 free_old_entry (ptr
);
2083 ptr
->type
= hash_string
;
2084 sb_new (&ptr
->value
.s
);
2085 sb_add_sb (&ptr
->value
.s
, &acc
);
2091 /* name: .REG (reg) */
2098 /* remove reg stuff from inside parens */
2101 idx
= skip_openp (idx
, in
);
2103 idx
= sb_skip_white (idx
, in
);
2105 while (idx
< in
->len
2108 : in
->ptr
[idx
] != ')'))
2110 sb_add_char (&what
, in
->ptr
[idx
]);
2113 hash_add_to_string_table (&assign_hash_table
, &label
, &what
, 1);
2119 condass_lookup_name (inbuf
, idx
, out
, warn
)
2127 sb_new (&condass_acc
);
2129 while (idx
< inbuf
->len
2130 && ISNEXTCHAR (inbuf
->ptr
[idx
]))
2132 sb_add_char (&condass_acc
, inbuf
->ptr
[idx
++]);
2135 if (inbuf
->ptr
[idx
] == '\'')
2137 ptr
= hash_lookup (&vars
, &condass_acc
);
2144 WARNING ((stderr
, _("Can't find preprocessor variable %s.\n"), sb_name (&condass_acc
)));
2148 sb_add_string (out
, "0");
2153 if (ptr
->type
== hash_integer
)
2156 sprintf (buffer
, "%d", ptr
->value
.i
);
2157 sb_add_string (out
, buffer
);
2161 sb_add_sb (out
, &ptr
->value
.s
);
2164 sb_kill (&condass_acc
);
2177 whatcond (idx
, in
, val
)
2184 idx
= sb_skip_white (idx
, in
);
2186 if (idx
+ 1 < in
->len
)
2192 a
= toupper ((unsigned char) p
[0]);
2193 b
= toupper ((unsigned char) p
[1]);
2194 if (a
== 'E' && b
== 'Q')
2196 else if (a
== 'N' && b
== 'E')
2198 else if (a
== 'L' && b
== 'T')
2200 else if (a
== 'L' && b
== 'E')
2202 else if (a
== 'G' && b
== 'T')
2204 else if (a
== 'G' && b
== 'E')
2209 ERROR ((stderr
, _("Comparison operator must be one of EQ, NE, LT, LE, GT or GE.\n")));
2212 idx
= sb_skip_white (idx
+ 2, in
);
2229 idx
= sb_skip_white (idx
, in
);
2231 if (in
->ptr
[idx
] == '"')
2235 /* This is a string comparision */
2236 idx
= getstring (idx
, in
, &acc_a
);
2237 idx
= whatcond (idx
, in
, &cond
);
2238 idx
= getstring (idx
, in
, &acc_b
);
2239 same
= acc_a
.len
== acc_b
.len
&& (strncmp (acc_a
.ptr
, acc_b
.ptr
, acc_a
.len
) == 0);
2241 if (cond
!= EQ
&& cond
!= NE
)
2243 ERROR ((stderr
, _("Comparison operator for strings must be EQ or NE\n")));
2247 res
= (cond
!= EQ
) ^ same
;
2250 /* This is a numeric expression */
2255 idx
= exp_get_abs (_("Conditional operator must have absolute operands.\n"), idx
, in
, &vala
);
2256 idx
= whatcond (idx
, in
, &cond
);
2257 idx
= sb_skip_white (idx
, in
);
2258 if (in
->ptr
[idx
] == '"')
2260 WARNING ((stderr
, _("String compared against expression.\n")));
2265 idx
= exp_get_abs (_("Conditional operator must have absolute operands.\n"), idx
, in
, &valb
);
2308 if (ifi
>= IFNESTING
)
2310 FATAL ((stderr
, _("AIF nesting unreasonable.\n")));
2313 ifstack
[ifi
].on
= ifstack
[ifi
-1].on
? istrue (idx
, in
) : 0;
2314 ifstack
[ifi
].hadelse
= 0;
2322 ifstack
[ifi
].on
= ifstack
[ifi
-1].on
? !ifstack
[ifi
].on
: 0;
2323 if (ifstack
[ifi
].hadelse
)
2325 ERROR ((stderr
, _("Multiple AELSEs in AIF.\n")));
2327 ifstack
[ifi
].hadelse
= 1;
2341 ERROR ((stderr
, _("AENDI without AIF.\n")));
2348 return ifstack
[ifi
].on
;
2351 /* MRI IFEQ, IFNE, IFLT, IFLE, IFGE, IFGT. */
2354 do_if (idx
, in
, cond
)
2362 if (ifi
>= IFNESTING
)
2364 FATAL ((stderr
, _("IF nesting unreasonable.\n")));
2367 idx
= exp_get_abs (_("Conditional operator must have absolute operands.\n"),
2372 case EQ
: res
= val
== 0; break;
2373 case NE
: res
= val
!= 0; break;
2374 case LT
: res
= val
< 0; break;
2375 case LE
: res
= val
<= 0; break;
2376 case GE
: res
= val
>= 0; break;
2377 case GT
: res
= val
> 0; break;
2381 ifstack
[ifi
].on
= ifstack
[ifi
-1].on
? res
: 0;
2382 ifstack
[ifi
].hadelse
= 0;
2385 /* Get a string for the MRI IFC or IFNC pseudo-ops. */
2388 get_mri_string (idx
, in
, val
, terminator
)
2394 idx
= sb_skip_white (idx
, in
);
2397 && in
->ptr
[idx
] == '\'')
2399 sb_add_char (val
, '\'');
2400 for (++idx
; idx
< in
->len
; ++idx
)
2402 sb_add_char (val
, in
->ptr
[idx
]);
2403 if (in
->ptr
[idx
] == '\'')
2407 || in
->ptr
[idx
] != '\'')
2411 idx
= sb_skip_white (idx
, in
);
2417 while (idx
< in
->len
2418 && in
->ptr
[idx
] != terminator
)
2420 sb_add_char (val
, in
->ptr
[idx
]);
2424 while (i
>= 0 && ISWHITE (val
->ptr
[i
]))
2432 /* MRI IFC, IFNC. */
2435 do_ifc (idx
, in
, ifnc
)
2444 if (ifi
>= IFNESTING
)
2446 FATAL ((stderr
, _("IF nesting unreasonable.\n")));
2452 idx
= get_mri_string (idx
, in
, &first
, ',');
2454 if (idx
>= in
->len
|| in
->ptr
[idx
] != ',')
2456 ERROR ((stderr
, _("Bad format for IF or IFNC.\n")));
2460 idx
= get_mri_string (idx
+ 1, in
, &second
, ';');
2462 res
= (first
.len
== second
.len
2463 && strncmp (first
.ptr
, second
.ptr
, first
.len
) == 0);
2467 ifstack
[ifi
].on
= ifstack
[ifi
-1].on
? res
: 0;
2468 ifstack
[ifi
].hadelse
= 0;
2476 ERROR ((stderr
, _("AENDR without a AREPEAT.\n")));
2478 ERROR ((stderr
, _("ENDR without a REPT.\n")));
2489 int line
= linecount ();
2497 process_assigns (idx
, in
, &exp
);
2498 doit
= istrue (0, &exp
);
2500 if (! buffer_and_nest ("AWHILE", "AENDW", &sub
, get_line
))
2501 FATAL ((stderr
, _("AWHILE without a AENDW at %d.\n"), line
- 1));
2516 int index
= include_next_index ();
2520 sb_add_sb (©
, &sub
);
2521 sb_add_sb (©
, in
);
2522 sb_add_string (©
, "\n");
2523 sb_add_sb (©
, &sub
);
2524 sb_add_string (©
, "\t.AENDW\n");
2525 /* Push another WHILE */
2526 include_buf (&exp
, ©
, include_while
, index
);
2539 ERROR ((stderr
, _("AENDW without a AENDW.\n")));
2545 Pop things off the include stack until the type and index changes */
2550 include_type type
= sp
->type
;
2551 if (type
== include_repeat
2552 || type
== include_while
2553 || type
== include_macro
)
2555 int index
= sp
->index
;
2557 while (sp
->index
== index
2558 && sp
->type
== type
)
2568 do_arepeat (idx
, in
)
2572 int line
= linecount ();
2573 sb exp
; /* buffer with expression in it */
2574 sb copy
; /* expanded repeat block */
2575 sb sub
; /* contents of AREPEAT */
2583 process_assigns (idx
, in
, &exp
);
2584 idx
= exp_get_abs (_("AREPEAT must have absolute operand.\n"), 0, &exp
, &rc
);
2586 ret
= buffer_and_nest ("AREPEAT", "AENDR", &sub
, get_line
);
2588 ret
= buffer_and_nest ("REPT", "ENDR", &sub
, get_line
);
2590 FATAL ((stderr
, _("AREPEAT without a AENDR at %d.\n"), line
- 1));
2593 /* Push back the text following the repeat, and another repeat block
2604 int index
= include_next_index ();
2605 sb_add_sb (©
, &sub
);
2609 sprintf (buffer
, "\t.AREPEAT %d\n", rc
- 1);
2611 sprintf (buffer
, "\tREPT %d\n", rc
- 1);
2612 sb_add_string (©
, buffer
);
2613 sb_add_sb (©
, &sub
);
2615 sb_add_string (©
, " .AENDR\n");
2617 sb_add_string (©
, " ENDR\n");
2620 include_buf (&exp
, ©
, include_repeat
, index
);
2632 ERROR ((stderr
, _(".ENDM without a matching .MACRO.\n")));
2635 /* MRI IRP pseudo-op. */
2638 do_irp (idx
, in
, irpc
)
2648 err
= expand_irp (irpc
, idx
, in
, &out
, get_line
, comment_char
);
2650 ERROR ((stderr
, "%s\n", err
));
2652 fprintf (outfile
, "%s", sb_terminate (&out
));
2657 /* MACRO PROCESSING */
2659 /* Parse off LOCAL n1, n2,... Invent a label name for it */
2662 do_local (idx
, line
)
2663 int idx ATTRIBUTE_UNUSED
;
2664 sb
*line ATTRIBUTE_UNUSED
;
2666 ERROR ((stderr
, _("LOCAL outside of MACRO")));
2675 int line
= linecount ();
2677 err
= define_macro (idx
, in
, &label
, get_line
, (const char **) NULL
);
2679 ERROR ((stderr
, _("macro at line %d: %s\n"), line
- 1, err
));
2691 if (! macro_defined
)
2695 if (! check_macro (in
->ptr
+ idx
, &out
, comment_char
, &err
))
2699 ERROR ((stderr
, "%s\n", err
));
2702 sb_add_string (&name
, _("macro expansion"));
2704 include_buf (&name
, &out
, include_macro
, include_next_index ());
2712 /* STRING HANDLING */
2715 getstring (idx
, in
, acc
)
2720 idx
= sb_skip_white (idx
, in
);
2722 while (idx
< in
->len
2723 && (in
->ptr
[idx
] == '"'
2724 || in
->ptr
[idx
] == '<'
2725 || (in
->ptr
[idx
] == '\'' && alternate
)))
2727 if (in
->ptr
[idx
] == '<')
2729 if (alternate
|| mri
)
2733 while ((in
->ptr
[idx
] != '>' || nest
)
2736 if (in
->ptr
[idx
] == '!')
2739 sb_add_char (acc
, in
->ptr
[idx
++]);
2742 if (in
->ptr
[idx
] == '>')
2744 if (in
->ptr
[idx
] == '<')
2746 sb_add_char (acc
, in
->ptr
[idx
++]);
2754 idx
= exp_get_abs (_("Character code in string must be absolute expression.\n"),
2756 sb_add_char (acc
, code
);
2758 if (in
->ptr
[idx
] != '>')
2759 ERROR ((stderr
, _("Missing > for character code.\n")));
2763 else if (in
->ptr
[idx
] == '"' || in
->ptr
[idx
] == '\'')
2765 char tchar
= in
->ptr
[idx
];
2767 while (idx
< in
->len
)
2769 if (alternate
&& in
->ptr
[idx
] == '!')
2772 sb_add_char (acc
, in
->ptr
[idx
++]);
2775 if (in
->ptr
[idx
] == tchar
)
2778 if (idx
>= in
->len
|| in
->ptr
[idx
] != tchar
)
2781 sb_add_char (acc
, in
->ptr
[idx
]);
2791 /* .SDATA[C|Z] <string> */
2795 do_sdata (idx
, in
, type
)
2804 fprintf (outfile
, ".byte\t");
2806 while (!eol (idx
, in
))
2810 idx
= sb_skip_white (idx
, in
);
2811 while (!eol (idx
, in
))
2813 pidx
= idx
= get_any_string (idx
, in
, &acc
, 0, 1);
2818 ERROR ((stderr
, _("string for SDATAC longer than 255 characters (%d).\n"), acc
.len
));
2820 fprintf (outfile
, "%d", acc
.len
);
2824 for (i
= 0; i
< acc
.len
; i
++)
2828 fprintf (outfile
, ",");
2830 fprintf (outfile
, "%d", acc
.ptr
[i
]);
2837 fprintf (outfile
, ",");
2838 fprintf (outfile
, "0");
2840 idx
= sb_skip_comma (idx
, in
);
2841 if (idx
== pidx
) break;
2843 if (!alternate
&& in
->ptr
[idx
] != ',' && idx
!= in
->len
)
2845 fprintf (outfile
, "\n");
2846 ERROR ((stderr
, _("illegal character in SDATA line (0x%x).\n"), in
->ptr
[idx
]));
2852 fprintf (outfile
, "\n");
2855 /* .SDATAB <count> <string> */
2867 idx
= exp_get_abs (_("Must have absolute SDATAB repeat count.\n"), idx
, in
, &repeat
);
2870 ERROR ((stderr
, _("Must have positive SDATAB repeat count (%d).\n"), repeat
));
2874 idx
= sb_skip_comma (idx
, in
);
2875 idx
= getstring (idx
, in
, &acc
);
2877 for (i
= 0; i
< repeat
; i
++)
2880 fprintf (outfile
, "\t");
2881 fprintf (outfile
, ".byte\t");
2882 sb_print (outfile
, &acc
);
2883 fprintf (outfile
, "\n");
2893 FILE *newone
= fopen (name
, "r");
2897 if (isp
== MAX_INCLUDES
)
2898 FATAL ((stderr
, _("Unreasonable include depth (%ld).\n"), (long) isp
));
2901 sp
->handle
= newone
;
2904 sb_add_string (&sp
->name
, name
);
2907 sp
->pushback_index
= 0;
2908 sp
->type
= include_file
;
2910 sb_new (&sp
->pushback
);
2915 do_include (idx
, in
)
2921 include_path
*includes
;
2927 idx
= getstring (idx
, in
, &t
);
2930 idx
= sb_skip_white (idx
, in
);
2931 while (idx
< in
->len
&& ! ISWHITE (in
->ptr
[idx
]))
2933 sb_add_char (&t
, in
->ptr
[idx
]);
2938 for (includes
= paths_head
; includes
; includes
= includes
->next
)
2941 sb_add_sb (&cat
, &includes
->path
);
2942 sb_add_char (&cat
, '/');
2943 sb_add_sb (&cat
, &t
);
2944 if (new_file (sb_name (&cat
)))
2951 if (! new_file (sb_name (&t
)))
2952 FATAL ((stderr
, _("Can't open include file `%s'.\n"), sb_name (&t
)));
2961 if (sp
!= include_stack
)
2964 fclose (sp
->handle
);
2969 /* Get the next character from the include stack. If there's anything
2970 in the pushback buffer, take that first. If we're at eof, pop from
2971 the stack and try again. Keep the linecount up to date. */
2978 if (sp
->pushback
.len
!= sp
->pushback_index
)
2980 r
= (char) (sp
->pushback
.ptr
[sp
->pushback_index
++]);
2981 /* When they've all gone, reset the pointer */
2982 if (sp
->pushback_index
== sp
->pushback
.len
)
2984 sp
->pushback
.len
= 0;
2985 sp
->pushback_index
= 0;
2988 else if (sp
->handle
)
2990 r
= getc (sp
->handle
);
2995 if (r
== EOF
&& isp
)
2999 while (r
== EOF
&& isp
)
3017 return sp
->linecount
;
3021 include_next_index ()
3025 && index
> MAX_REASONABLE
)
3026 FATAL ((stderr
, _("Unreasonable expansion (-u turns off check).\n")));
3031 /* Initialize the chartype vector. */
3037 for (x
= 0; x
< 256; x
++)
3039 if (isalpha (x
) || x
== '_' || x
== '$')
3040 chartype
[x
] |= FIRSTBIT
;
3042 if (mri
&& x
== '.')
3043 chartype
[x
] |= FIRSTBIT
;
3045 if (isdigit (x
) || isalpha (x
) || x
== '_' || x
== '$')
3046 chartype
[x
] |= NEXTBIT
;
3048 if (x
== ' ' || x
== '\t' || x
== ',' || x
== '"' || x
== ';'
3049 || x
== '"' || x
== '<' || x
== '>' || x
== ')' || x
== '(')
3050 chartype
[x
] |= SEPBIT
;
3052 if (x
== 'b' || x
== 'B'
3053 || x
== 'q' || x
== 'Q'
3054 || x
== 'h' || x
== 'H'
3055 || x
== 'd' || x
== 'D')
3056 chartype
[x
] |= BASEBIT
;
3058 if (x
== ' ' || x
== '\t')
3059 chartype
[x
] |= WHITEBIT
;
3061 if (x
== comment_char
)
3062 chartype
[x
] |= COMMENTBIT
;
3068 /* What to do with all the keywords */
3069 #define PROCESS 0x1000 /* Run substitution over the line */
3070 #define LAB 0x2000 /* Spit out the label */
3072 #define K_EQU (PROCESS|1)
3073 #define K_ASSIGN (PROCESS|2)
3074 #define K_REG (PROCESS|3)
3075 #define K_ORG (PROCESS|4)
3076 #define K_RADIX (PROCESS|5)
3077 #define K_DATA (LAB|PROCESS|6)
3078 #define K_DATAB (LAB|PROCESS|7)
3079 #define K_SDATA (LAB|PROCESS|8)
3080 #define K_SDATAB (LAB|PROCESS|9)
3081 #define K_SDATAC (LAB|PROCESS|10)
3082 #define K_SDATAZ (LAB|PROCESS|11)
3083 #define K_RES (LAB|PROCESS|12)
3084 #define K_SRES (LAB|PROCESS|13)
3085 #define K_SRESC (LAB|PROCESS|14)
3086 #define K_SRESZ (LAB|PROCESS|15)
3087 #define K_EXPORT (LAB|PROCESS|16)
3088 #define K_GLOBAL (LAB|PROCESS|17)
3089 #define K_PRINT (LAB|PROCESS|19)
3090 #define K_FORM (LAB|PROCESS|20)
3091 #define K_HEADING (LAB|PROCESS|21)
3092 #define K_PAGE (LAB|PROCESS|22)
3093 #define K_IMPORT (LAB|PROCESS|23)
3094 #define K_PROGRAM (LAB|PROCESS|24)
3095 #define K_END (PROCESS|25)
3096 #define K_INCLUDE (PROCESS|26)
3097 #define K_IGNORED (PROCESS|27)
3098 #define K_ASSIGNA (PROCESS|28)
3099 #define K_ASSIGNC (29)
3100 #define K_AIF (PROCESS|30)
3101 #define K_AELSE (PROCESS|31)
3102 #define K_AENDI (PROCESS|32)
3103 #define K_AREPEAT (PROCESS|33)
3104 #define K_AENDR (PROCESS|34)
3105 #define K_AWHILE (35)
3106 #define K_AENDW (PROCESS|36)
3107 #define K_EXITM (37)
3108 #define K_MACRO (PROCESS|38)
3110 #define K_ALIGN (PROCESS|LAB|40)
3111 #define K_ALTERNATE (41)
3112 #define K_DB (LAB|PROCESS|42)
3113 #define K_DW (LAB|PROCESS|43)
3114 #define K_DL (LAB|PROCESS|44)
3115 #define K_LOCAL (45)
3116 #define K_IFEQ (PROCESS|46)
3117 #define K_IFNE (PROCESS|47)
3118 #define K_IFLT (PROCESS|48)
3119 #define K_IFLE (PROCESS|49)
3120 #define K_IFGE (PROCESS|50)
3121 #define K_IFGT (PROCESS|51)
3122 #define K_IFC (PROCESS|52)
3123 #define K_IFNC (PROCESS|53)
3124 #define K_IRP (PROCESS|54)
3125 #define K_IRPC (PROCESS|55)
3135 static struct keyword kinfo
[] =
3137 { "EQU", K_EQU
, 0 },
3138 { "ALTERNATE", K_ALTERNATE
, 0 },
3139 { "ASSIGN", K_ASSIGN
, 0 },
3140 { "REG", K_REG
, 0 },
3141 { "ORG", K_ORG
, 0 },
3142 { "RADIX", K_RADIX
, 0 },
3143 { "DATA", K_DATA
, 0 },
3147 { "DATAB", K_DATAB
, 0 },
3148 { "SDATA", K_SDATA
, 0 },
3149 { "SDATAB", K_SDATAB
, 0 },
3150 { "SDATAZ", K_SDATAZ
, 0 },
3151 { "SDATAC", K_SDATAC
, 0 },
3152 { "RES", K_RES
, 0 },
3153 { "SRES", K_SRES
, 0 },
3154 { "SRESC", K_SRESC
, 0 },
3155 { "SRESZ", K_SRESZ
, 0 },
3156 { "EXPORT", K_EXPORT
, 0 },
3157 { "GLOBAL", K_GLOBAL
, 0 },
3158 { "PRINT", K_PRINT
, 0 },
3159 { "FORM", K_FORM
, 0 },
3160 { "HEADING", K_HEADING
, 0 },
3161 { "PAGE", K_PAGE
, 0 },
3162 { "PROGRAM", K_IGNORED
, 0 },
3163 { "END", K_END
, 0 },
3164 { "INCLUDE", K_INCLUDE
, 0 },
3165 { "ASSIGNA", K_ASSIGNA
, 0 },
3166 { "ASSIGNC", K_ASSIGNC
, 0 },
3167 { "AIF", K_AIF
, 0 },
3168 { "AELSE", K_AELSE
, 0 },
3169 { "AENDI", K_AENDI
, 0 },
3170 { "AREPEAT", K_AREPEAT
, 0 },
3171 { "AENDR", K_AENDR
, 0 },
3172 { "EXITM", K_EXITM
, 0 },
3173 { "MACRO", K_MACRO
, 0 },
3174 { "ENDM", K_ENDM
, 0 },
3175 { "AWHILE", K_AWHILE
, 0 },
3176 { "ALIGN", K_ALIGN
, 0 },
3177 { "AENDW", K_AENDW
, 0 },
3178 { "ALTERNATE", K_ALTERNATE
, 0 },
3179 { "LOCAL", K_LOCAL
, 0 },
3183 /* Although the conditional operators are handled by gas, we need to
3184 handle them here as well, in case they are used in a recursive
3185 macro to end the recursion. */
3187 static struct keyword mrikinfo
[] =
3189 { "IFEQ", K_IFEQ
, 0 },
3190 { "IFNE", K_IFNE
, 0 },
3191 { "IFLT", K_IFLT
, 0 },
3192 { "IFLE", K_IFLE
, 0 },
3193 { "IFGE", K_IFGE
, 0 },
3194 { "IFGT", K_IFGT
, 0 },
3195 { "IFC", K_IFC
, 0 },
3196 { "IFNC", K_IFNC
, 0 },
3197 { "ELSEC", K_AELSE
, 0 },
3198 { "ENDC", K_AENDI
, 0 },
3199 { "MEXIT", K_EXITM
, 0 },
3200 { "REPT", K_AREPEAT
, 0 },
3201 { "IRP", K_IRP
, 0 },
3202 { "IRPC", K_IRPC
, 0 },
3203 { "ENDR", K_AENDR
, 0 },
3207 /* Look for a pseudo op on the line. If one's there then call
3211 process_pseudo_op (idx
, line
, acc
)
3218 if (line
->ptr
[idx
] == '.' || alternate
|| mri
)
3220 /* Scan forward and find pseudo name */
3226 if (line
->ptr
[idx
] == '.')
3228 in
= line
->ptr
+ idx
;
3233 while (idx
< line
->len
&& *e
&& ISFIRSTCHAR (*e
))
3235 sb_add_char (acc
, *e
);
3240 ptr
= hash_lookup (&keyword_hash_table
, acc
);
3245 /* This one causes lots of pain when trying to preprocess
3247 WARNING ((stderr
, _("Unrecognised pseudo op `%s'.\n"), sb_name (acc
)));
3251 if (ptr
->value
.i
& LAB
)
3252 { /* output the label */
3255 fprintf (outfile
, "%s:\t", sb_name (&label
));
3258 fprintf (outfile
, "\t");
3261 if (mri
&& ptr
->value
.i
== K_END
)
3266 sb_add_buffer (&t
, line
->ptr
+ oidx
, idx
- oidx
);
3267 fprintf (outfile
, "\t%s", sb_name (&t
));
3271 if (ptr
->value
.i
& PROCESS
)
3273 /* Polish the rest of the line before handling the pseudo op */
3275 strip_comments(line
);
3278 process_assigns (idx
, line
, acc
);
3280 change_base (0, acc
, line
);
3285 switch (ptr
->value
.i
)
3301 switch (ptr
->value
.i
)
3305 macro_init (1, mri
, 0, exp_get_abs
);
3314 ERROR ((stderr
, _("ORG command not allowed.\n")));
3320 do_data (idx
, line
, 1);
3323 do_data (idx
, line
, 2);
3326 do_data (idx
, line
, 4);
3329 do_data (idx
, line
, 0);
3332 do_datab (idx
, line
);
3335 do_sdata (idx
, line
, 0);
3338 do_sdatab (idx
, line
);
3341 do_sdata (idx
, line
, 'c');
3344 do_sdata (idx
, line
, 'z');
3347 do_assign (0, 0, line
);
3353 do_arepeat (idx
, line
);
3359 do_awhile (idx
, line
);
3365 do_assign (1, idx
, line
);
3368 do_align (idx
, line
);
3371 do_res (idx
, line
, 0);
3374 do_res (idx
, line
, 's');
3377 do_include (idx
, line
);
3380 do_local (idx
, line
);
3383 do_macro (idx
, line
);
3389 do_res (idx
, line
, 'c');
3392 do_print (idx
, line
);
3395 do_form (idx
, line
);
3398 do_heading (idx
, line
);
3410 do_res (idx
, line
, 'z');
3418 do_assigna (idx
, line
);
3421 do_assignc (idx
, line
);
3430 do_if (idx
, line
, EQ
);
3433 do_if (idx
, line
, NE
);
3436 do_if (idx
, line
, LT
);
3439 do_if (idx
, line
, LE
);
3442 do_if (idx
, line
, GE
);
3445 do_if (idx
, line
, GT
);
3448 do_ifc (idx
, line
, 0);
3451 do_ifc (idx
, line
, 1);
3454 do_irp (idx
, line
, 0);
3457 do_irp (idx
, line
, 1);
3467 /* Add a keyword to the hash table. */
3470 add_keyword (name
, code
)
3478 sb_add_string (&label
, name
);
3480 hash_add_to_int_table (&keyword_hash_table
, &label
, code
);
3483 for (j
= 0; name
[j
]; j
++)
3484 sb_add_char (&label
, name
[j
] - 'A' + 'a');
3485 hash_add_to_int_table (&keyword_hash_table
, &label
, code
);
3490 /* Build the keyword hash table - put each keyword in the table twice,
3491 once upper and once lower case.*/
3498 for (i
= 0; kinfo
[i
].name
; i
++)
3499 add_keyword (kinfo
[i
].name
, kinfo
[i
].code
);
3503 for (i
= 0; mrikinfo
[i
].name
; i
++)
3504 add_keyword (mrikinfo
[i
].name
, mrikinfo
[i
].code
);
3528 sb_add_char (&value
, *string
);
3531 exp_get_abs (_("Invalid expression on command line.\n"), 0, &value
, &res
);
3535 sb_add_char (&label
, *string
);
3540 ptr
= hash_create (&vars
, &label
);
3541 free_old_entry (ptr
);
3542 ptr
->type
= hash_integer
;
3548 /* The list of long options. */
3549 static struct option long_options
[] =
3551 { "alternate", no_argument
, 0, 'a' },
3552 { "include", required_argument
, 0, 'I' },
3553 { "commentchar", required_argument
, 0, 'c' },
3554 { "copysource", no_argument
, 0, 's' },
3555 { "debug", no_argument
, 0, 'd' },
3556 { "help", no_argument
, 0, 'h' },
3557 { "mri", no_argument
, 0, 'M' },
3558 { "output", required_argument
, 0, 'o' },
3559 { "print", no_argument
, 0, 'p' },
3560 { "unreasonable", no_argument
, 0, 'u' },
3561 { "version", no_argument
, 0, 'v' },
3562 { "define", required_argument
, 0, 'd' },
3563 { NULL
, no_argument
, 0, 0 }
3566 /* Show a usage message and exit. */
3568 show_usage (file
, status
)
3574 [-a] [--alternate] enter alternate macro mode\n\
3575 [-c char] [--commentchar char] change the comment character from !\n\
3576 [-d] [--debug] print some debugging info\n\
3577 [-h] [--help] print this message\n\
3578 [-M] [--mri] enter MRI compatibility mode\n\
3579 [-o out] [--output out] set the output file\n\
3580 [-p] [--print] print line numbers\n"), program_name
);
3582 [-s] [--copysource] copy source through as comments \n\
3583 [-u] [--unreasonable] allow unreasonable nesting\n\
3584 [-v] [--version] print the program version\n\
3585 [-Dname=value] create preprocessor variable called name, with value\n\
3586 [-Ipath] add to include path list\n\
3589 printf (_("\nReport bugs to bug-gnu-utils@gnu.org\n"));
3593 /* Display a help message and exit. */
3597 printf (_("%s: Gnu Assembler Macro Preprocessor\n"),
3599 show_usage (stdout
, 0);
3614 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
3615 setlocale (LC_MESSAGES
, "");
3617 bindtextdomain (PACKAGE
, LOCALEDIR
);
3618 textdomain (PACKAGE
);
3620 program_name
= argv
[0];
3621 xmalloc_set_program_name (program_name
);
3623 hash_new_table (101, &keyword_hash_table
);
3624 hash_new_table (101, &assign_hash_table
);
3625 hash_new_table (101, &vars
);
3629 while ((opt
= getopt_long (argc
, argv
, "I:sdhavc:upo:D:M", long_options
,
3643 include_path
*p
= (include_path
*) xmalloc (sizeof (include_path
));
3646 sb_add_string (&p
->path
, optarg
);
3648 paths_tail
->next
= p
;
3655 print_line_number
= 1;
3658 comment_char
= optarg
[0];
3680 /* This output is intended to follow the GNU standards document. */
3681 printf (_("GNU assembler pre-processor %s\n"), program_version
);
3682 printf (_("Copyright 1996 Free Software Foundation, Inc.\n"));
3684 This program is free software; you may redistribute it under the terms of\n\
3685 the GNU General Public License. This program has absolutely no warranty.\n"));
3691 show_usage (stderr
, 1);
3698 macro_init (alternate
, mri
, 0, exp_get_abs
);
3701 outfile
= fopen (out_name
, "w");
3704 fprintf (stderr
, _("%s: Can't open output file `%s'.\n"),
3705 program_name
, out_name
);
3717 /* Process all the input files */
3719 while (optind
< argc
)
3721 if (new_file (argv
[optind
]))
3727 fprintf (stderr
, _("%s: Can't open input file `%s'.\n"),
3728 program_name
, argv
[optind
]);
3738 /* This function is used because an abort in some of the other files
3739 may be compiled into as_abort because they include as.h. */
3742 as_abort (file
, line
, fn
)
3743 const char *file
, *fn
;
3746 fprintf (stderr
, _("Internal error, aborting at %s line %d"), file
, line
);
3748 fprintf (stderr
, " in %s", fn
);
3749 fprintf (stderr
, _("\nPlease report this bug.\n"));