1 /* gasp.c - Gnu assembler preprocessor main program.
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
5 Written by Steve and Judy Chamberlain of Cygnus Support,
8 This file is part of GASP, the GNU Assembler Preprocessor.
10 GASP is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
15 GASP is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GASP; see the file COPYING. If not, write to the Free
22 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
26 This program translates the input macros and stuff into a form
27 suitable for gas to consume.
29 gasp [-sdhau] [-c char] [-o <outfile>] <infile>*
31 -s copy source to output
32 -c <char> comments are started with <char> instead of !
33 -u allow unreasonable stuff
35 -d print debugging stats
36 -s semi colons start comments
37 -a use alternate syntax
38 Pseudo ops can start with or without a .
39 Labels have to be in first column.
40 -I specify include dir
41 Macro arg parameters subsituted by name, don't need the &.
42 String can start with ' too.
43 Strings can be surrounded by <..>
44 A %<exp> in a string evaluates the expression
45 Literal char in a string with !
60 #ifdef NEED_MALLOC_DECLARATION
61 extern char *malloc ();
65 #include "libiberty.h"
66 #include "safe-ctype.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. */
111 #define COMMENTBIT 16
113 #define ISCOMMENTCHAR(x) (chartype[(unsigned char)(x)] & COMMENTBIT)
114 #define ISFIRSTCHAR(x) (chartype[(unsigned char)(x)] & FIRSTBIT)
115 #define ISNEXTCHAR(x) (chartype[(unsigned char)(x)] & NEXTBIT)
116 #define ISSEP(x) (chartype[(unsigned char)(x)] & SEPBIT)
117 #define ISWHITE(x) (chartype[(unsigned char)(x)] & WHITEBIT)
118 #define ISBASE(x) (chartype[(unsigned char)(x)] & BASEBIT)
119 static char chartype
[256];
121 /* Conditional assembly uses the `ifstack'. Each aif pushes another
122 entry onto the stack, and sets the on flag if it should. The aelse
123 sets hadelse, and toggles on. An aend pops a level. We limit to
124 100 levels of nesting, not because we're facists pigs with read
125 only minds, but because more than 100 levels of nesting is probably
126 a bug in the user's macro structure. */
128 #define IFNESTING 100
130 int on
; /* Is the level being output. */
131 int hadelse
; /* Has an aelse been seen. */
132 } ifstack
[IFNESTING
];
136 /* The final and intermediate results of expression evaluation are kept in
137 exp_t's. Note that a symbol is not an sb, but a pointer into the input
138 line. It must be coped somewhere safe before the next line is read in. */
146 int value
; /* Constant part. */
147 symbol add_symbol
; /* Name part. */
148 symbol sub_symbol
; /* Name part. */
151 /* Hashing is done in a pretty standard way. A hash_table has a
152 pointer to a vector of pointers to hash_entrys, and the size of the
153 vector. A hash_entry contains a union of all the info we like to
154 store in hash table. If there is a hash collision, hash_entries
155 with the same hash are kept in a chain. */
157 /* What the data in a hash_entry means. */
159 hash_integer
, /* Name->integer mapping. */
160 hash_string
, /* Name->string mapping. */
161 hash_macro
, /* Name is a macro. */
162 hash_formal
/* Name is a formal argument. */
166 sb key
; /* Symbol name. */
167 hash_type type
; /* Symbol meaning. */
171 struct macro_struct
*m
;
172 struct formal_struct
*f
;
174 struct hs
*next
; /* Next hash_entry with same hash key. */
182 /* How we nest files and expand macros etc.
184 We keep a stack of of include_stack structs. Each include file
185 pushes a new level onto the stack. We keep an sb with a pushback
186 too. unget chars are pushed onto the pushback sb, getchars first
187 checks the pushback sb before reading from the input stream.
189 Small things are expanded by adding the text of the item onto the
190 pushback sb. Larger items are grown by pushing a new level and
191 allocating the entire pushback buf for the item. Each time
192 something like a macro is expanded, the stack index is changed. We
193 can then perform an exitm by popping all entries off the stack with
194 the same stack index. If we're being reasonable, we can detect
195 recusive expansion by checking the index is reasonably small. */
198 include_file
, include_repeat
, include_while
, include_macro
201 struct include_stack
{
202 sb pushback
; /* Current pushback stream. */
203 int pushback_index
; /* Next char to read from stream. */
204 FILE *handle
; /* Open file. */
205 sb name
; /* Name of file. */
206 int linecount
; /* Number of lines read so far. */
208 int index
; /* Index of this layer. */
209 } include_stack
[MAX_INCLUDES
];
211 struct include_stack
*sp
;
212 #define isp (sp - include_stack)
214 /* Include file list. */
216 typedef struct include_path
{
217 struct include_path
*next
;
221 include_path
*paths_head
;
222 include_path
*paths_tail
;
224 static void quit
PARAMS ((void));
225 static void hash_new_table
PARAMS ((int, hash_table
*));
226 static int hash
PARAMS ((sb
*));
227 static hash_entry
*hash_create
PARAMS ((hash_table
*, sb
*));
228 static void hash_add_to_string_table
PARAMS ((hash_table
*, sb
*, sb
*, int));
229 static void hash_add_to_int_table
PARAMS ((hash_table
*, sb
*, int));
230 static hash_entry
*hash_lookup
PARAMS ((hash_table
*, sb
*));
231 static void checkconst
PARAMS ((int, exp_t
*));
232 static int is_flonum
PARAMS ((int, sb
*));
233 static int chew_flonum
PARAMS ((int, sb
*, sb
*));
234 static int sb_strtol
PARAMS ((int, sb
*, int, int *));
235 static int level_0
PARAMS ((int, sb
*, exp_t
*));
236 static int level_1
PARAMS ((int, sb
*, exp_t
*));
237 static int level_2
PARAMS ((int, sb
*, exp_t
*));
238 static int level_3
PARAMS ((int, sb
*, exp_t
*));
239 static int level_4
PARAMS ((int, sb
*, exp_t
*));
240 static int level_5
PARAMS ((int, sb
*, exp_t
*));
241 static int exp_parse
PARAMS ((int, sb
*, exp_t
*));
242 static void exp_string
PARAMS ((exp_t
*, sb
*));
243 static int exp_get_abs
PARAMS ((const char *, int, sb
*, int *));
245 static void strip_comments
PARAMS ((sb
*));
247 static void unget
PARAMS ((int));
248 static void include_buf
PARAMS ((sb
*, sb
*, include_type
, int));
249 static void include_print_where_line
PARAMS ((FILE *));
250 static void include_print_line
PARAMS ((FILE *));
251 static int get_line
PARAMS ((sb
*));
252 static int grab_label
PARAMS ((sb
*, sb
*));
253 static void change_base
PARAMS ((int, sb
*, sb
*));
254 static void do_end
PARAMS ((sb
*));
255 static void do_assign
PARAMS ((int, int, sb
*));
256 static void do_radix
PARAMS ((sb
*));
257 static int get_opsize
PARAMS ((int, sb
*, int *));
258 static int eol
PARAMS ((int, sb
*));
259 static void do_data
PARAMS ((int, sb
*, int));
260 static void do_datab
PARAMS ((int, sb
*));
261 static void do_align
PARAMS ((int, sb
*));
262 static void do_res
PARAMS ((int, sb
*, int));
263 static void do_export
PARAMS ((sb
*));
264 static void do_print
PARAMS ((int, sb
*));
265 static void do_heading
PARAMS ((int, sb
*));
266 static void do_page
PARAMS ((void));
267 static void do_form
PARAMS ((int, sb
*));
268 static int get_any_string
PARAMS ((int, sb
*, sb
*, int, int));
269 static int skip_openp
PARAMS ((int, sb
*));
270 static int skip_closep
PARAMS ((int, sb
*));
271 static int dolen
PARAMS ((int, sb
*, sb
*));
272 static int doinstr
PARAMS ((int, sb
*, sb
*));
273 static int dosubstr
PARAMS ((int, sb
*, sb
*));
274 static void process_assigns
PARAMS ((int, sb
*, sb
*));
275 static int get_and_process
PARAMS ((int, sb
*, sb
*));
276 static void process_file
PARAMS ((void));
277 static void free_old_entry
PARAMS ((hash_entry
*));
278 static void do_assigna
PARAMS ((int, sb
*));
279 static void do_assignc
PARAMS ((int, sb
*));
280 static void do_reg
PARAMS ((int, sb
*));
281 static int condass_lookup_name
PARAMS ((sb
*, int, sb
*, int));
282 static int whatcond
PARAMS ((int, sb
*, int *));
283 static int istrue
PARAMS ((int, sb
*));
284 static void do_aif
PARAMS ((int, sb
*));
285 static void do_aelse
PARAMS ((void));
286 static void do_aendi
PARAMS ((void));
287 static int condass_on
PARAMS ((void));
288 static void do_if
PARAMS ((int, sb
*, int));
289 static int get_mri_string
PARAMS ((int, sb
*, sb
*, int));
290 static void do_ifc
PARAMS ((int, sb
*, int));
291 static void do_aendr
PARAMS ((void));
292 static void do_awhile
PARAMS ((int, sb
*));
293 static void do_aendw
PARAMS ((void));
294 static void do_exitm
PARAMS ((void));
295 static void do_arepeat
PARAMS ((int, sb
*));
296 static void do_endm
PARAMS ((void));
297 static void do_irp
PARAMS ((int, sb
*, int));
298 static void do_local
PARAMS ((int, sb
*));
299 static void do_macro
PARAMS ((int, sb
*));
300 static int macro_op
PARAMS ((int, sb
*));
301 static int getstring
PARAMS ((int, sb
*, sb
*));
302 static void do_sdata
PARAMS ((int, sb
*, int));
303 static void do_sdatab
PARAMS ((int, sb
*));
304 static int new_file
PARAMS ((const char *));
305 static void do_include
PARAMS ((int, sb
*));
306 static void include_pop
PARAMS ((void));
307 static int get
PARAMS ((void));
308 static int linecount
PARAMS ((void));
309 static int include_next_index
PARAMS ((void));
310 static void chartype_init
PARAMS ((void));
311 static int process_pseudo_op
PARAMS ((int, sb
*, sb
*));
312 static void add_keyword
PARAMS ((const char *, int));
313 static void process_init
PARAMS ((void));
314 static void do_define
PARAMS ((const char *));
315 static void show_usage
PARAMS ((FILE *, int));
316 static void show_help
PARAMS ((void));
321 include_print_where_line (stderr); \
331 include_print_where_line (stderr); \
340 include_print_where_line (stderr); \
346 /* Exit the program and return the right ERROR code. */
360 for (i
= 0; i
< sb_max_power_two
; i
++)
362 fprintf (stderr
, "strings size %8d : %d\n",
363 1 << i
, string_count
[i
]);
369 /* Hash table maintenance. */
371 /* Build a new hash table with size buckets
372 and fill in the info at ptr. */
375 hash_new_table (size
, ptr
)
381 ptr
->table
= (hash_entry
**) xmalloc (size
* (sizeof (hash_entry
*)));
382 /* Fill with null-pointer, not zero-bit-pattern. */
383 for (i
= 0; i
< size
; i
++)
387 /* Calculate and return the hash value of the sb at key. */
396 for (i
= 0; i
< key
->len
; i
++)
404 /* Look up key in hash_table tab. If present, then return it,
405 otherwise build a new one and fill it with hash_integer. */
408 hash_create (tab
, key
)
412 int k
= hash (key
) % tab
->size
;
414 hash_entry
**table
= tab
->table
;
422 hash_entry
*n
= (hash_entry
*) xmalloc (sizeof (hash_entry
));
425 sb_add_sb (&n
->key
, key
);
427 n
->type
= hash_integer
;
430 if (strncmp (table
[k
]->key
.ptr
, key
->ptr
, key
->len
) == 0)
438 /* Add sb name with key into hash_table tab.
439 If replacing old value and again, then ERROR. */
442 hash_add_to_string_table (tab
, key
, name
, again
)
448 hash_entry
*ptr
= hash_create (tab
, key
);
449 if (ptr
->type
== hash_integer
)
451 sb_new (&ptr
->value
.s
);
453 if (ptr
->value
.s
.len
)
456 ERROR ((stderr
, _("redefinition not allowed\n")));
459 ptr
->type
= hash_string
;
460 sb_reset (&ptr
->value
.s
);
462 sb_add_sb (&ptr
->value
.s
, name
);
465 /* Add integer name to hash_table tab with sb key. */
468 hash_add_to_int_table (tab
, key
, name
)
473 hash_entry
*ptr
= hash_create (tab
, key
);
477 /* Look up sb key in hash_table tab.
478 If found, return hash_entry result, else 0. */
481 hash_lookup (tab
, key
)
485 int k
= hash (key
) % tab
->size
;
486 hash_entry
**table
= tab
->table
;
487 hash_entry
*p
= table
[k
];
490 if (p
->key
.len
== key
->len
491 && strncmp (p
->key
.ptr
, key
->ptr
, key
->len
) == 0)
500 are handled in a really simple recursive decent way. each bit of
501 the machine takes an index into an sb and a pointer to an exp_t,
502 modifies the *exp_t and returns the index of the first character
503 past the part of the expression parsed.
505 expression precedence:
514 /* Make sure that the exp_t at term is constant.
515 If not the give the op ERROR. */
518 checkconst (op
, term
)
522 if (term
->add_symbol
.len
523 || term
->sub_symbol
.len
)
525 ERROR ((stderr
, _("the %c operator cannot take non-absolute arguments.\n"), op
));
529 /* Chew the flonum from the string starting at idx. Adjust idx to
530 point to the next character after the flonum. */
533 chew_flonum (idx
, string
, out
)
542 /* Duplicate and null terminate `string'. */
544 sb_add_sb (&buf
, string
);
545 sb_add_char (&buf
, '\0');
547 if (regcomp (®
, "([0-9]*\\.[0-9]+([eE][+-]?[0-9]+)?)", REG_EXTENDED
) != 0)
549 if (regexec (®
, &buf
.ptr
[idx
], 1, &match
, 0) != 0)
552 /* Copy the match to the output. */
553 assert (match
.rm_eo
>= match
.rm_so
);
554 sb_add_buffer (out
, &buf
.ptr
[idx
], match
.rm_eo
- match
.rm_so
);
563 is_flonum (idx
, string
)
571 /* Duplicate and null terminate `string'. */
573 sb_add_sb (&buf
, string
);
574 sb_add_char (&buf
, '\0');
576 if (regcomp (®
, "^[0-9]*\\.[0-9]+([eE][+-]?[0-9]+)?", REG_EXTENDED
) != 0)
579 rc
= regexec (®
, &buf
.ptr
[idx
], 0, NULL
, 0);
585 /* Turn the number in string at idx into a number of base, fill in
586 ptr, and return the index of the first character not in the number. */
589 sb_strtol (idx
, string
, base
, ptr
)
596 idx
= sb_skip_white (idx
, string
);
598 while (idx
< string
->len
)
600 int ch
= string
->ptr
[idx
];
604 else if (ch
>= 'a' && ch
<= 'f')
606 else if (ch
>= 'A' && ch
<= 'F')
614 value
= value
* base
+ dig
;
622 level_0 (idx
, string
, lhs
)
627 lhs
->add_symbol
.len
= 0;
628 lhs
->add_symbol
.name
= 0;
630 lhs
->sub_symbol
.len
= 0;
631 lhs
->sub_symbol
.name
= 0;
633 idx
= sb_skip_white (idx
, string
);
637 if (ISDIGIT (string
->ptr
[idx
]))
639 idx
= sb_strtol (idx
, string
, 10, &lhs
->value
);
641 else if (ISFIRSTCHAR (string
->ptr
[idx
]))
644 lhs
->add_symbol
.name
= string
->ptr
+ idx
;
645 while (idx
< string
->len
&& ISNEXTCHAR (string
->ptr
[idx
]))
650 lhs
->add_symbol
.len
= len
;
652 else if (string
->ptr
[idx
] == '"')
656 ERROR ((stderr
, _("string where expression expected.\n")));
657 idx
= getstring (idx
, string
, &acc
);
662 ERROR ((stderr
, _("can't find primary in expression.\n")));
665 return sb_skip_white (idx
, string
);
669 level_1 (idx
, string
, lhs
)
674 idx
= sb_skip_white (idx
, string
);
676 switch (string
->ptr
[idx
])
679 idx
= level_1 (idx
+ 1, string
, lhs
);
682 idx
= level_1 (idx
+ 1, string
, lhs
);
683 checkconst ('~', lhs
);
684 lhs
->value
= ~lhs
->value
;
689 idx
= level_1 (idx
+ 1, string
, lhs
);
690 lhs
->value
= -lhs
->value
;
692 lhs
->add_symbol
= lhs
->sub_symbol
;
698 idx
= level_5 (sb_skip_white (idx
, string
), string
, lhs
);
699 if (string
->ptr
[idx
] != ')')
700 ERROR ((stderr
, _("misplaced closing parens.\n")));
705 idx
= level_0 (idx
, string
, lhs
);
708 return sb_skip_white (idx
, string
);
712 level_2 (idx
, string
, lhs
)
719 idx
= level_1 (idx
, string
, lhs
);
721 while (idx
< string
->len
&& (string
->ptr
[idx
] == '*'
722 || string
->ptr
[idx
] == '/'))
724 char op
= string
->ptr
[idx
++];
725 idx
= level_1 (idx
, string
, &rhs
);
729 checkconst ('*', lhs
);
730 checkconst ('*', &rhs
);
731 lhs
->value
*= rhs
.value
;
734 checkconst ('/', lhs
);
735 checkconst ('/', &rhs
);
737 ERROR ((stderr
, _("attempt to divide by zero.\n")));
739 lhs
->value
/= rhs
.value
;
743 return sb_skip_white (idx
, string
);
747 level_3 (idx
, string
, lhs
)
754 idx
= level_2 (idx
, string
, lhs
);
756 while (idx
< string
->len
757 && (string
->ptr
[idx
] == '+'
758 || string
->ptr
[idx
] == '-'))
760 char op
= string
->ptr
[idx
++];
761 idx
= level_2 (idx
, string
, &rhs
);
765 lhs
->value
+= rhs
.value
;
766 if (lhs
->add_symbol
.name
&& rhs
.add_symbol
.name
)
768 ERROR ((stderr
, _("can't add two relocatable expressions\n")));
770 /* Change nn+symbol to symbol + nn. */
771 if (rhs
.add_symbol
.name
)
773 lhs
->add_symbol
= rhs
.add_symbol
;
777 lhs
->value
-= rhs
.value
;
778 lhs
->sub_symbol
= rhs
.add_symbol
;
782 return sb_skip_white (idx
, string
);
786 level_4 (idx
, string
, lhs
)
793 idx
= level_3 (idx
, string
, lhs
);
795 while (idx
< string
->len
&&
796 string
->ptr
[idx
] == '&')
798 char op
= string
->ptr
[idx
++];
799 idx
= level_3 (idx
, string
, &rhs
);
803 checkconst ('&', lhs
);
804 checkconst ('&', &rhs
);
805 lhs
->value
&= rhs
.value
;
809 return sb_skip_white (idx
, string
);
813 level_5 (idx
, string
, lhs
)
820 idx
= level_4 (idx
, string
, lhs
);
822 while (idx
< string
->len
823 && (string
->ptr
[idx
] == '|' || string
->ptr
[idx
] == '~'))
825 char op
= string
->ptr
[idx
++];
826 idx
= level_4 (idx
, string
, &rhs
);
830 checkconst ('|', lhs
);
831 checkconst ('|', &rhs
);
832 lhs
->value
|= rhs
.value
;
835 checkconst ('~', lhs
);
836 checkconst ('~', &rhs
);
837 lhs
->value
^= rhs
.value
;
841 return sb_skip_white (idx
, string
);
844 /* Parse the expression at offset idx into string, fill up res with
845 the result. Return the index of the first char past the
849 exp_parse (idx
, string
, res
)
854 return level_5 (sb_skip_white (idx
, string
), string
, res
);
857 /* Turn the expression at exp into text and glue it onto the end of
861 exp_string (exp
, string
)
869 if (exp
->add_symbol
.len
)
871 sb_add_buffer (string
, exp
->add_symbol
.name
, exp
->add_symbol
.len
);
879 sb_add_char (string
, '+');
880 sprintf (buf
, "%d", exp
->value
);
881 sb_add_string (string
, buf
);
885 if (exp
->sub_symbol
.len
)
887 sb_add_char (string
, '-');
888 sb_add_buffer (string
, exp
->add_symbol
.name
, exp
->add_symbol
.len
);
894 sb_add_char (string
, '0');
897 /* Parse the expression at offset idx into sb in. Return the value in
898 val. If the expression is not constant, give ERROR emsg. Return
899 the index of the first character past the end of the expression. */
902 exp_get_abs (emsg
, idx
, in
, val
)
909 idx
= exp_parse (idx
, in
, &res
);
910 if (res
.add_symbol
.len
|| res
.sub_symbol
.len
)
911 ERROR ((stderr
, "%s", emsg
));
916 /* Current label parsed from line. */
919 /* Hash table for all assigned variables. */
920 hash_table assign_hash_table
;
922 /* Hash table for keyword. */
923 hash_table keyword_hash_table
;
925 /* Hash table for eq variables. */
928 #define in_comment ';'
937 for (i
= 0; i
< out
->len
; i
++)
939 if (ISCOMMENTCHAR (s
[i
]))
948 /* Push back character ch so that it can be read again. */
958 if (sp
->pushback_index
)
959 sp
->pushback_index
--;
961 sb_add_char (&sp
->pushback
, ch
);
964 /* Push the sb ptr onto the include stack, with the given name, type
968 include_buf (name
, ptr
, type
, index
)
975 if (sp
- include_stack
>= MAX_INCLUDES
)
976 FATAL ((stderr
, _("unreasonable nesting.\n")));
978 sb_add_sb (&sp
->name
, name
);
981 sp
->pushback_index
= 0;
984 sb_new (&sp
->pushback
);
985 sb_add_sb (&sp
->pushback
, ptr
);
988 /* Used in ERROR messages, print info on where the include stack is
992 include_print_where_line (file
)
995 struct include_stack
*p
= include_stack
+ 1;
999 fprintf (file
, "%s:%d ", sb_name (&p
->name
), p
->linecount
- 1);
1004 /* Used in listings, print the line number onto file. */
1007 include_print_line (file
)
1011 struct include_stack
*p
= include_stack
+ 1;
1013 n
= fprintf (file
, "%4d", p
->linecount
);
1017 n
+= fprintf (file
, ".%d", p
->linecount
);
1022 fprintf (file
, " ");
1027 /* Read a line from the top of the include stack into sb in. */
1038 putc (comment_char
, outfile
);
1039 if (print_line_number
)
1040 include_print_line (outfile
);
1054 WARNING ((stderr
, _("End of file not at start of line.\n")));
1056 putc ('\n', outfile
);
1075 /* Continued line. */
1078 putc (comment_char
, outfile
);
1079 putc ('+', outfile
);
1092 sb_add_char (in
, ch
);
1100 /* Find a label from sb in and put it in out. */
1103 grab_label (in
, out
)
1109 if (ISFIRSTCHAR (in
->ptr
[i
]) || in
->ptr
[i
] == '\\')
1111 sb_add_char (out
, in
->ptr
[i
]);
1113 while ((ISNEXTCHAR (in
->ptr
[i
])
1114 || in
->ptr
[i
] == '\\'
1115 || in
->ptr
[i
] == '&')
1118 sb_add_char (out
, in
->ptr
[i
]);
1125 /* Find all strange base stuff and turn into decimal. Also
1126 find all the other numbers and convert them from the default radix. */
1129 change_base (idx
, in
, out
)
1136 while (idx
< in
->len
)
1138 if (in
->ptr
[idx
] == '\\'
1139 && idx
+ 1 < in
->len
1140 && in
->ptr
[idx
+ 1] == '(')
1143 while (idx
< in
->len
1144 && in
->ptr
[idx
] != ')')
1146 sb_add_char (out
, in
->ptr
[idx
]);
1152 else if (idx
< in
->len
- 1 && in
->ptr
[idx
+ 1] == '\'' && ! mri
)
1156 switch (in
->ptr
[idx
])
1175 ERROR ((stderr
, _("Illegal base character %c.\n"), in
->ptr
[idx
]));
1180 idx
= sb_strtol (idx
+ 2, in
, base
, &value
);
1181 sprintf (buffer
, "%d", value
);
1182 sb_add_string (out
, buffer
);
1184 else if (ISFIRSTCHAR (in
->ptr
[idx
]))
1186 /* Copy entire names through quickly. */
1187 sb_add_char (out
, in
->ptr
[idx
]);
1189 while (idx
< in
->len
&& ISNEXTCHAR (in
->ptr
[idx
]))
1191 sb_add_char (out
, in
->ptr
[idx
]);
1195 else if (is_flonum (idx
, in
))
1197 idx
= chew_flonum (idx
, in
, out
);
1199 else if (ISDIGIT (in
->ptr
[idx
]))
1202 /* All numbers must start with a digit, let's chew it and
1203 spit out decimal. */
1204 idx
= sb_strtol (idx
, in
, radix
, &value
);
1205 sprintf (buffer
, "%d", value
);
1206 sb_add_string (out
, buffer
);
1208 /* Skip all undigsested letters. */
1209 while (idx
< in
->len
&& ISNEXTCHAR (in
->ptr
[idx
]))
1211 sb_add_char (out
, in
->ptr
[idx
]);
1215 else if (in
->ptr
[idx
] == '"' || in
->ptr
[idx
] == '\'')
1217 char tchar
= in
->ptr
[idx
];
1218 /* Copy entire names through quickly. */
1219 sb_add_char (out
, in
->ptr
[idx
]);
1221 while (idx
< in
->len
&& in
->ptr
[idx
] != tchar
)
1223 sb_add_char (out
, in
->ptr
[idx
]);
1229 /* Nothing special, just pass it through. */
1230 sb_add_char (out
, in
->ptr
[idx
]);
1245 fprintf (outfile
, "%s\n", sb_name (in
));
1251 do_assign (again
, idx
, in
)
1256 /* Stick label in symbol table with following value. */
1261 idx
= exp_parse (idx
, in
, &e
);
1262 exp_string (&e
, &acc
);
1263 hash_add_to_string_table (&assign_hash_table
, &label
, &acc
, again
);
1267 /* .radix [b|q|d|h] */
1273 int idx
= sb_skip_white (0, ptr
);
1274 switch (ptr
->ptr
[idx
])
1293 ERROR ((stderr
, _("radix is %c must be one of b, q, d or h"), radix
));
1297 /* Parse off a .b, .w or .l. */
1300 get_opsize (idx
, in
, size
)
1306 if (in
->ptr
[idx
] == '.')
1310 switch (in
->ptr
[idx
])
1328 ERROR ((stderr
, _("size must be one of b, w or l, is %c.\n"), in
->ptr
[idx
]));
1341 idx
= sb_skip_white (idx
, line
);
1343 && ISCOMMENTCHAR(line
->ptr
[idx
]))
1345 if (idx
>= line
->len
)
1350 /* .data [.b|.w|.l] <data>*
1351 or d[bwl] <data>* */
1354 do_data (idx
, in
, size
)
1360 char *opname
= ".yikes!";
1366 idx
= get_opsize (idx
, in
, &opsize
);
1385 fprintf (outfile
, "%s\t", opname
);
1387 idx
= sb_skip_white (idx
, in
);
1391 && in
->ptr
[idx
] == '"')
1394 idx
= getstring (idx
, in
, &acc
);
1395 for (i
= 0; i
< acc
.len
; i
++)
1398 fprintf (outfile
, ",");
1399 fprintf (outfile
, "%d", acc
.ptr
[i
]);
1404 while (!eol (idx
, in
))
1407 idx
= exp_parse (idx
, in
, &e
);
1408 exp_string (&e
, &acc
);
1409 sb_add_char (&acc
, 0);
1410 fprintf (outfile
, "%s", acc
.ptr
);
1411 if (idx
< in
->len
&& in
->ptr
[idx
] == ',')
1413 fprintf (outfile
, ",");
1419 sb_print_at (outfile
, idx
, in
);
1420 fprintf (outfile
, "\n");
1423 /* .datab [.b|.w|.l] <repeat>,<fill> */
1434 idx
= get_opsize (idx
, in
, &opsize
);
1436 idx
= exp_get_abs (_("datab repeat must be constant.\n"), idx
, in
, &repeat
);
1437 idx
= sb_skip_comma (idx
, in
);
1438 idx
= exp_get_abs (_("datab data must be absolute.\n"), idx
, in
, &fill
);
1440 fprintf (outfile
, ".fill\t%d,%d,%d\n", repeat
, opsize
, fill
);
1450 int al
, have_fill
, fill
;
1452 idx
= exp_get_abs (_("align needs absolute expression.\n"), idx
, in
, &al
);
1453 idx
= sb_skip_white (idx
, in
);
1456 if (! eol (idx
, in
))
1458 idx
= sb_skip_comma (idx
, in
);
1459 idx
= exp_get_abs (_(".align needs absolute fill value.\n"), idx
, in
,
1464 fprintf (outfile
, ".align %d", al
);
1466 fprintf (outfile
, ",%d", fill
);
1467 fprintf (outfile
, "\n");
1470 /* .res[.b|.w|.l] <size> */
1473 do_res (idx
, in
, type
)
1481 idx
= get_opsize (idx
, in
, &size
);
1482 while (!eol (idx
, in
))
1484 idx
= sb_skip_white (idx
, in
);
1485 if (in
->ptr
[idx
] == ',')
1487 idx
= exp_get_abs (_("res needs absolute expression for fill count.\n"), idx
, in
, &count
);
1489 if (type
== 'c' || type
== 'z')
1492 fprintf (outfile
, ".space %d\n", count
* size
);
1502 fprintf (outfile
, ".global %s\n", sb_name (in
));
1505 /* .print [list] [nolist] */
1512 idx
= sb_skip_white (idx
, in
);
1513 while (idx
< in
->len
)
1515 if (strncasecmp (in
->ptr
+ idx
, "LIST", 4) == 0)
1517 fprintf (outfile
, ".list\n");
1520 else if (strncasecmp (in
->ptr
+ idx
, "NOLIST", 6) == 0)
1522 fprintf (outfile
, ".nolist\n");
1532 do_heading (idx
, in
)
1538 idx
= getstring (idx
, in
, &head
);
1539 fprintf (outfile
, ".title \"%s\"\n", sb_name (&head
));
1548 fprintf (outfile
, ".eject\n");
1551 /* .form [lin=<value>] [col=<value>] */
1560 idx
= sb_skip_white (idx
, in
);
1562 while (idx
< in
->len
)
1565 if (strncasecmp (in
->ptr
+ idx
, "LIN=", 4) == 0)
1568 idx
= exp_get_abs (_("form LIN= needs absolute expresssion.\n"), idx
, in
, &lines
);
1571 if (strncasecmp (in
->ptr
+ idx
, _("COL="), 4) == 0)
1574 idx
= exp_get_abs (_("form COL= needs absolute expresssion.\n"), idx
, in
, &columns
);
1579 fprintf (outfile
, ".psize %d,%d\n", lines
, columns
);
1583 /* Fetch string from the input stream,
1585 'Bxyx<whitespace> -> return 'Bxyza
1586 %<char> -> return string of decimal value of x
1587 "<string>" -> return string
1588 xyx<whitespace> -> return xyz
1592 get_any_string (idx
, in
, out
, expand
, pretend_quoted
)
1600 idx
= sb_skip_white (idx
, in
);
1604 if (in
->len
> 2 && in
->ptr
[idx
+ 1] == '\'' && ISBASE (in
->ptr
[idx
]))
1606 while (!ISSEP (in
->ptr
[idx
]))
1607 sb_add_char (out
, in
->ptr
[idx
++]);
1609 else if (in
->ptr
[idx
] == '%'
1615 /* Turns the next expression into a string. */
1616 /* xgettext: no-c-format */
1617 idx
= exp_get_abs (_("% operator needs absolute expression"),
1621 sprintf (buf
, "%d", val
);
1622 sb_add_string (out
, buf
);
1624 else if (in
->ptr
[idx
] == '"'
1625 || in
->ptr
[idx
] == '<'
1626 || (alternate
&& in
->ptr
[idx
] == '\''))
1628 if (alternate
&& expand
)
1630 /* Keep the quotes. */
1631 sb_add_char (out
, '\"');
1633 idx
= getstring (idx
, in
, out
);
1634 sb_add_char (out
, '\"');
1639 idx
= getstring (idx
, in
, out
);
1644 while (idx
< in
->len
1645 && (in
->ptr
[idx
] == '"'
1646 || in
->ptr
[idx
] == '\''
1648 || !ISSEP (in
->ptr
[idx
])))
1650 if (in
->ptr
[idx
] == '"'
1651 || in
->ptr
[idx
] == '\'')
1653 char tchar
= in
->ptr
[idx
];
1654 sb_add_char (out
, in
->ptr
[idx
++]);
1655 while (idx
< in
->len
1656 && in
->ptr
[idx
] != tchar
)
1657 sb_add_char (out
, in
->ptr
[idx
++]);
1661 sb_add_char (out
, in
->ptr
[idx
++]);
1669 /* Skip along sb in starting at idx, suck off whitespace a ( and more
1670 whitespace. Return the idx of the next char. */
1673 skip_openp (idx
, in
)
1677 idx
= sb_skip_white (idx
, in
);
1678 if (in
->ptr
[idx
] != '(')
1679 ERROR ((stderr
, _("misplaced ( .\n")));
1680 idx
= sb_skip_white (idx
+ 1, in
);
1684 /* Skip along sb in starting at idx, suck off whitespace a ) and more
1685 whitespace. Return the idx of the next char. */
1688 skip_closep (idx
, in
)
1692 idx
= sb_skip_white (idx
, in
);
1693 if (in
->ptr
[idx
] != ')')
1694 ERROR ((stderr
, _("misplaced ).\n")));
1695 idx
= sb_skip_white (idx
+ 1, in
);
1702 dolen (idx
, in
, out
)
1711 sb_new (&stringout
);
1712 idx
= skip_openp (idx
, in
);
1713 idx
= get_and_process (idx
, in
, &stringout
);
1714 idx
= skip_closep (idx
, in
);
1715 sprintf (buffer
, "%d", stringout
.len
);
1716 sb_add_string (out
, buffer
);
1718 sb_kill (&stringout
);
1725 doinstr (idx
, in
, out
)
1739 idx
= skip_openp (idx
, in
);
1740 idx
= get_and_process (idx
, in
, &string
);
1741 idx
= sb_skip_comma (idx
, in
);
1742 idx
= get_and_process (idx
, in
, &search
);
1743 idx
= sb_skip_comma (idx
, in
);
1744 if (ISDIGIT (in
->ptr
[idx
]))
1746 idx
= exp_get_abs (_(".instr needs absolute expresson.\n"), idx
, in
, &start
);
1752 idx
= skip_closep (idx
, in
);
1754 for (i
= start
; i
< string
.len
; i
++)
1756 if (strncmp (string
.ptr
+ i
, search
.ptr
, search
.len
) == 0)
1762 sprintf (buffer
, "%d", res
);
1763 sb_add_string (out
, buffer
);
1770 dosubstr (idx
, in
, out
)
1780 idx
= skip_openp (idx
, in
);
1781 idx
= get_and_process (idx
, in
, &string
);
1782 idx
= sb_skip_comma (idx
, in
);
1783 idx
= exp_get_abs (_("need absolute position.\n"), idx
, in
, &pos
);
1784 idx
= sb_skip_comma (idx
, in
);
1785 idx
= exp_get_abs (_("need absolute length.\n"), idx
, in
, &len
);
1786 idx
= skip_closep (idx
, in
);
1788 if (len
< 0 || pos
< 0 ||
1790 || pos
+ len
> string
.len
)
1792 sb_add_string (out
, " ");
1796 sb_add_char (out
, '"');
1799 sb_add_char (out
, string
.ptr
[pos
++]);
1802 sb_add_char (out
, '"');
1808 /* Scan line, change tokens in the hash table to their replacements. */
1811 process_assigns (idx
, in
, buf
)
1816 while (idx
< in
->len
)
1819 if (in
->ptr
[idx
] == '\\'
1820 && idx
+ 1 < in
->len
1821 && in
->ptr
[idx
+ 1] == '(')
1825 sb_add_char (buf
, in
->ptr
[idx
]);
1828 while (idx
< in
->len
&& in
->ptr
[idx
- 1] != ')');
1830 else if (in
->ptr
[idx
] == '\\'
1831 && idx
+ 1 < in
->len
1832 && in
->ptr
[idx
+ 1] == '&')
1834 idx
= condass_lookup_name (in
, idx
+ 2, buf
, 1);
1836 else if (in
->ptr
[idx
] == '\\'
1837 && idx
+ 1 < in
->len
1838 && in
->ptr
[idx
+ 1] == '$')
1840 idx
= condass_lookup_name (in
, idx
+ 2, buf
, 0);
1842 else if (idx
+ 3 < in
->len
1843 && in
->ptr
[idx
] == '.'
1844 && TOUPPER (in
->ptr
[idx
+ 1]) == 'L'
1845 && TOUPPER (in
->ptr
[idx
+ 2]) == 'E'
1846 && TOUPPER (in
->ptr
[idx
+ 3]) == 'N')
1847 idx
= dolen (idx
+ 4, in
, buf
);
1848 else if (idx
+ 6 < in
->len
1849 && in
->ptr
[idx
] == '.'
1850 && TOUPPER (in
->ptr
[idx
+ 1]) == 'I'
1851 && TOUPPER (in
->ptr
[idx
+ 2]) == 'N'
1852 && TOUPPER (in
->ptr
[idx
+ 3]) == 'S'
1853 && TOUPPER (in
->ptr
[idx
+ 4]) == 'T'
1854 && TOUPPER (in
->ptr
[idx
+ 5]) == 'R')
1855 idx
= doinstr (idx
+ 6, in
, buf
);
1856 else if (idx
+ 7 < in
->len
1857 && in
->ptr
[idx
] == '.'
1858 && TOUPPER (in
->ptr
[idx
+ 1]) == 'S'
1859 && TOUPPER (in
->ptr
[idx
+ 2]) == 'U'
1860 && TOUPPER (in
->ptr
[idx
+ 3]) == 'B'
1861 && TOUPPER (in
->ptr
[idx
+ 4]) == 'S'
1862 && TOUPPER (in
->ptr
[idx
+ 5]) == 'T'
1863 && TOUPPER (in
->ptr
[idx
+ 6]) == 'R')
1864 idx
= dosubstr (idx
+ 7, in
, buf
);
1865 else if (ISFIRSTCHAR (in
->ptr
[idx
]))
1867 /* May be a simple name subsitution, see if we have a word. */
1870 while (cur
< in
->len
1871 && (ISNEXTCHAR (in
->ptr
[cur
])))
1875 sb_add_buffer (&acc
, in
->ptr
+ idx
, cur
- idx
);
1876 ptr
= hash_lookup (&assign_hash_table
, &acc
);
1879 /* Found a definition for it. */
1880 sb_add_sb (buf
, &ptr
->value
.s
);
1884 /* No definition, just copy the word. */
1885 sb_add_sb (buf
, &acc
);
1892 sb_add_char (buf
, in
->ptr
[idx
++]);
1898 get_and_process (idx
, in
, out
)
1905 idx
= get_any_string (idx
, in
, &t
, 1, 0);
1906 process_assigns (0, &t
, out
);
1926 more
= get_line (&line
);
1929 /* Find any label and pseudo op that we're intested in. */
1934 fprintf (outfile
, "\n");
1937 && (line
.ptr
[0] == '*'
1938 || line
.ptr
[0] == '!'))
1940 /* MRI line comment. */
1941 fprintf (outfile
, "%s", sb_name (&line
));
1945 l
= grab_label (&line
, &label_in
);
1948 if (line
.ptr
[l
] == ':')
1950 while (ISWHITE (line
.ptr
[l
]) && l
< line
.len
)
1957 /* Munge the label, unless this is EQU or ASSIGN. */
1960 && (line
.ptr
[l
] == '.' || alternate
|| mri
))
1964 if (line
.ptr
[lx
] == '.')
1966 if (lx
+ 3 <= line
.len
1967 && strncasecmp ("EQU", line
.ptr
+ lx
, 3) == 0
1968 && (lx
+ 3 == line
.len
1969 || ! ISFIRSTCHAR (line
.ptr
[lx
+ 3])))
1971 else if (lx
+ 6 <= line
.len
1972 && strncasecmp ("ASSIGN", line
.ptr
+ lx
, 6) == 0
1973 && (lx
+ 6 == line
.len
1974 || ! ISFIRSTCHAR (line
.ptr
[lx
+ 6])))
1979 process_assigns (0, &label_in
, &label
);
1981 sb_add_sb (&label
, &label_in
);
1986 if (process_pseudo_op (l
, &line
, &acc
))
1990 else if (condass_on ())
1992 if (macro_op (l
, &line
))
2001 fprintf (outfile
, "%s:\t", sb_name (&label
));
2004 fprintf (outfile
, "\t");
2006 process_assigns (l
, &line
, &t1
);
2008 change_base (0, &t1
, &t2
);
2009 fprintf (outfile
, "%s\n", sb_name (&t2
));
2016 /* Only a label on this line. */
2017 if (label
.len
&& condass_on ())
2019 fprintf (outfile
, "%s:\n", sb_name (&label
));
2027 more
= get_line (&line
);
2030 if (!had_end
&& !mri
)
2031 WARNING ((stderr
, _("END missing from end of file.\n")));
2035 free_old_entry (ptr
)
2040 if (ptr
->type
== hash_string
)
2041 sb_kill (&ptr
->value
.s
);
2045 /* name: .ASSIGNA <value> */
2048 do_assigna (idx
, in
)
2056 process_assigns (idx
, in
, &tmp
);
2057 idx
= exp_get_abs (_(".ASSIGNA needs constant expression argument.\n"), 0, &tmp
, &val
);
2061 ERROR ((stderr
, _(".ASSIGNA without label.\n")));
2065 hash_entry
*ptr
= hash_create (&vars
, &label
);
2066 free_old_entry (ptr
);
2067 ptr
->type
= hash_integer
;
2073 /* name: .ASSIGNC <string> */
2076 do_assignc (idx
, in
)
2082 idx
= getstring (idx
, in
, &acc
);
2086 ERROR ((stderr
, _(".ASSIGNS without label.\n")));
2090 hash_entry
*ptr
= hash_create (&vars
, &label
);
2091 free_old_entry (ptr
);
2092 ptr
->type
= hash_string
;
2093 sb_new (&ptr
->value
.s
);
2094 sb_add_sb (&ptr
->value
.s
, &acc
);
2099 /* name: .REG (reg) */
2106 /* Remove reg stuff from inside parens. */
2109 idx
= skip_openp (idx
, in
);
2111 idx
= sb_skip_white (idx
, in
);
2113 while (idx
< in
->len
2116 : in
->ptr
[idx
] != ')'))
2118 sb_add_char (&what
, in
->ptr
[idx
]);
2121 hash_add_to_string_table (&assign_hash_table
, &label
, &what
, 1);
2126 condass_lookup_name (inbuf
, idx
, out
, warn
)
2134 sb_new (&condass_acc
);
2136 while (idx
< inbuf
->len
2137 && ISNEXTCHAR (inbuf
->ptr
[idx
]))
2139 sb_add_char (&condass_acc
, inbuf
->ptr
[idx
++]);
2142 if (inbuf
->ptr
[idx
] == '\'')
2144 ptr
= hash_lookup (&vars
, &condass_acc
);
2150 WARNING ((stderr
, _("Can't find preprocessor variable %s.\n"), sb_name (&condass_acc
)));
2154 sb_add_string (out
, "0");
2159 if (ptr
->type
== hash_integer
)
2162 sprintf (buffer
, "%d", ptr
->value
.i
);
2163 sb_add_string (out
, buffer
);
2167 sb_add_sb (out
, &ptr
->value
.s
);
2170 sb_kill (&condass_acc
);
2183 whatcond (idx
, in
, val
)
2190 idx
= sb_skip_white (idx
, in
);
2192 if (idx
+ 1 < in
->len
)
2200 if (a
== 'E' && b
== 'Q')
2202 else if (a
== 'N' && b
== 'E')
2204 else if (a
== 'L' && b
== 'T')
2206 else if (a
== 'L' && b
== 'E')
2208 else if (a
== 'G' && b
== 'T')
2210 else if (a
== 'G' && b
== 'E')
2215 ERROR ((stderr
, _("Comparison operator must be one of EQ, NE, LT, LE, GT or GE.\n")));
2218 idx
= sb_skip_white (idx
+ 2, in
);
2235 idx
= sb_skip_white (idx
, in
);
2237 if (in
->ptr
[idx
] == '"')
2241 /* This is a string comparision. */
2242 idx
= getstring (idx
, in
, &acc_a
);
2243 idx
= whatcond (idx
, in
, &cond
);
2244 idx
= getstring (idx
, in
, &acc_b
);
2245 same
= acc_a
.len
== acc_b
.len
2246 && (strncmp (acc_a
.ptr
, acc_b
.ptr
, acc_a
.len
) == 0);
2248 if (cond
!= EQ
&& cond
!= NE
)
2250 ERROR ((stderr
, _("Comparison operator for strings must be EQ or NE\n")));
2254 res
= (cond
!= EQ
) ^ same
;
2257 /* This is a numeric expression. */
2262 idx
= exp_get_abs (_("Conditional operator must have absolute operands.\n"), idx
, in
, &vala
);
2263 idx
= whatcond (idx
, in
, &cond
);
2264 idx
= sb_skip_white (idx
, in
);
2265 if (in
->ptr
[idx
] == '"')
2267 WARNING ((stderr
, _("String compared against expression.\n")));
2272 idx
= exp_get_abs (_("Conditional operator must have absolute operands.\n"), idx
, in
, &valb
);
2316 if (ifi
>= IFNESTING
)
2318 FATAL ((stderr
, _("AIF nesting unreasonable.\n")));
2321 ifstack
[ifi
].on
= ifstack
[ifi
- 1].on
? istrue (idx
, in
) : 0;
2322 ifstack
[ifi
].hadelse
= 0;
2330 ifstack
[ifi
].on
= ifstack
[ifi
- 1].on
? !ifstack
[ifi
].on
: 0;
2331 if (ifstack
[ifi
].hadelse
)
2333 ERROR ((stderr
, _("Multiple AELSEs in AIF.\n")));
2335 ifstack
[ifi
].hadelse
= 1;
2349 ERROR ((stderr
, _("AENDI without AIF.\n")));
2356 return ifstack
[ifi
].on
;
2359 /* MRI IFEQ, IFNE, IFLT, IFLE, IFGE, IFGT. */
2362 do_if (idx
, in
, cond
)
2370 if (ifi
>= IFNESTING
)
2372 FATAL ((stderr
, _("IF nesting unreasonable.\n")));
2375 idx
= exp_get_abs (_("Conditional operator must have absolute operands.\n"),
2380 case EQ
: res
= val
== 0; break;
2381 case NE
: res
= val
!= 0; break;
2382 case LT
: res
= val
< 0; break;
2383 case LE
: res
= val
<= 0; break;
2384 case GE
: res
= val
>= 0; break;
2385 case GT
: res
= val
> 0; break;
2389 ifstack
[ifi
].on
= ifstack
[ifi
- 1].on
? res
: 0;
2390 ifstack
[ifi
].hadelse
= 0;
2393 /* Get a string for the MRI IFC or IFNC pseudo-ops. */
2396 get_mri_string (idx
, in
, val
, terminator
)
2402 idx
= sb_skip_white (idx
, in
);
2405 && in
->ptr
[idx
] == '\'')
2407 sb_add_char (val
, '\'');
2408 for (++idx
; idx
< in
->len
; ++idx
)
2410 sb_add_char (val
, in
->ptr
[idx
]);
2411 if (in
->ptr
[idx
] == '\'')
2415 || in
->ptr
[idx
] != '\'')
2419 idx
= sb_skip_white (idx
, in
);
2425 while (idx
< in
->len
2426 && in
->ptr
[idx
] != terminator
)
2428 sb_add_char (val
, in
->ptr
[idx
]);
2432 while (i
>= 0 && ISWHITE (val
->ptr
[i
]))
2443 do_ifc (idx
, in
, ifnc
)
2452 if (ifi
>= IFNESTING
)
2454 FATAL ((stderr
, _("IF nesting unreasonable.\n")));
2460 idx
= get_mri_string (idx
, in
, &first
, ',');
2462 if (idx
>= in
->len
|| in
->ptr
[idx
] != ',')
2464 ERROR ((stderr
, _("Bad format for IF or IFNC.\n")));
2468 idx
= get_mri_string (idx
+ 1, in
, &second
, ';');
2470 res
= (first
.len
== second
.len
2471 && strncmp (first
.ptr
, second
.ptr
, first
.len
) == 0);
2475 ifstack
[ifi
].on
= ifstack
[ifi
- 1].on
? res
: 0;
2476 ifstack
[ifi
].hadelse
= 0;
2485 ERROR ((stderr
, _("AENDR without a AREPEAT.\n")));
2487 ERROR ((stderr
, _("ENDR without a REPT.\n")));
2497 int line
= linecount ();
2505 process_assigns (idx
, in
, &exp
);
2506 doit
= istrue (0, &exp
);
2508 if (! buffer_and_nest ("AWHILE", "AENDW", &sub
, get_line
))
2509 FATAL ((stderr
, _("AWHILE without a AENDW at %d.\n"), line
- 1));
2524 int index
= include_next_index ();
2528 sb_add_sb (©
, &sub
);
2529 sb_add_sb (©
, in
);
2530 sb_add_string (©
, "\n");
2531 sb_add_sb (©
, &sub
);
2532 sb_add_string (©
, "\t.AENDW\n");
2533 /* Push another WHILE. */
2534 include_buf (&exp
, ©
, include_while
, index
);
2546 ERROR ((stderr
, _("AENDW without a AENDW.\n")));
2551 Pop things off the include stack until the type and index changes. */
2556 include_type type
= sp
->type
;
2557 if (type
== include_repeat
2558 || type
== include_while
2559 || type
== include_macro
)
2561 int index
= sp
->index
;
2563 while (sp
->index
== index
2564 && sp
->type
== type
)
2574 do_arepeat (idx
, in
)
2578 int line
= linecount ();
2579 sb exp
; /* Buffer with expression in it. */
2580 sb copy
; /* Expanded repeat block. */
2581 sb sub
; /* Contents of AREPEAT. */
2589 process_assigns (idx
, in
, &exp
);
2590 idx
= exp_get_abs (_("AREPEAT must have absolute operand.\n"), 0, &exp
, &rc
);
2592 ret
= buffer_and_nest ("AREPEAT", "AENDR", &sub
, get_line
);
2594 ret
= buffer_and_nest ("REPT", "ENDR", &sub
, get_line
);
2596 FATAL ((stderr
, _("AREPEAT without a AENDR at %d.\n"), line
- 1));
2599 /* Push back the text following the repeat, and another repeat block
2610 int index
= include_next_index ();
2611 sb_add_sb (©
, &sub
);
2615 sprintf (buffer
, "\t.AREPEAT %d\n", rc
- 1);
2617 sprintf (buffer
, "\tREPT %d\n", rc
- 1);
2618 sb_add_string (©
, buffer
);
2619 sb_add_sb (©
, &sub
);
2621 sb_add_string (©
, " .AENDR\n");
2623 sb_add_string (©
, " ENDR\n");
2626 include_buf (&exp
, ©
, include_repeat
, index
);
2638 ERROR ((stderr
, _(".ENDM without a matching .MACRO.\n")));
2641 /* MRI IRP pseudo-op. */
2644 do_irp (idx
, in
, irpc
)
2654 err
= expand_irp (irpc
, idx
, in
, &out
, get_line
, comment_char
);
2656 ERROR ((stderr
, "%s\n", err
));
2658 fprintf (outfile
, "%s", sb_terminate (&out
));
2663 /* Macro processing. */
2665 /* Parse off LOCAL n1, n2,... Invent a label name for it. */
2668 do_local (idx
, line
)
2669 int idx ATTRIBUTE_UNUSED
;
2670 sb
*line ATTRIBUTE_UNUSED
;
2672 ERROR ((stderr
, _("LOCAL outside of MACRO")));
2681 int line
= linecount ();
2683 err
= define_macro (idx
, in
, &label
, get_line
, (const char **) NULL
);
2685 ERROR ((stderr
, _("macro at line %d: %s\n"), line
- 1, err
));
2697 if (! macro_defined
)
2701 if (! check_macro (in
->ptr
+ idx
, &out
, comment_char
, &err
, NULL
))
2705 ERROR ((stderr
, "%s\n", err
));
2708 sb_add_string (&name
, _("macro expansion"));
2710 include_buf (&name
, &out
, include_macro
, include_next_index ());
2718 /* String handling. */
2721 getstring (idx
, in
, acc
)
2726 idx
= sb_skip_white (idx
, in
);
2728 while (idx
< in
->len
2729 && (in
->ptr
[idx
] == '"'
2730 || in
->ptr
[idx
] == '<'
2731 || (in
->ptr
[idx
] == '\'' && alternate
)))
2733 if (in
->ptr
[idx
] == '<')
2735 if (alternate
|| mri
)
2739 while ((in
->ptr
[idx
] != '>' || nest
)
2742 if (in
->ptr
[idx
] == '!')
2745 sb_add_char (acc
, in
->ptr
[idx
++]);
2749 if (in
->ptr
[idx
] == '>')
2751 if (in
->ptr
[idx
] == '<')
2753 sb_add_char (acc
, in
->ptr
[idx
++]);
2762 idx
= exp_get_abs (_("Character code in string must be absolute expression.\n"),
2764 sb_add_char (acc
, code
);
2766 if (in
->ptr
[idx
] != '>')
2767 ERROR ((stderr
, _("Missing > for character code.\n")));
2771 else if (in
->ptr
[idx
] == '"' || in
->ptr
[idx
] == '\'')
2773 char tchar
= in
->ptr
[idx
];
2775 while (idx
< in
->len
)
2777 if (alternate
&& in
->ptr
[idx
] == '!')
2780 sb_add_char (acc
, in
->ptr
[idx
++]);
2784 if (in
->ptr
[idx
] == tchar
)
2787 if (idx
>= in
->len
|| in
->ptr
[idx
] != tchar
)
2790 sb_add_char (acc
, in
->ptr
[idx
]);
2800 /* .SDATA[C|Z] <string> */
2803 do_sdata (idx
, in
, type
)
2812 fprintf (outfile
, ".byte\t");
2814 while (!eol (idx
, in
))
2818 idx
= sb_skip_white (idx
, in
);
2819 while (!eol (idx
, in
))
2821 pidx
= idx
= get_any_string (idx
, in
, &acc
, 0, 1);
2826 ERROR ((stderr
, _("string for SDATAC longer than 255 characters (%d).\n"), acc
.len
));
2828 fprintf (outfile
, "%d", acc
.len
);
2832 for (i
= 0; i
< acc
.len
; i
++)
2836 fprintf (outfile
, ",");
2838 fprintf (outfile
, "%d", acc
.ptr
[i
]);
2845 fprintf (outfile
, ",");
2846 fprintf (outfile
, "0");
2848 idx
= sb_skip_comma (idx
, in
);
2852 if (!alternate
&& in
->ptr
[idx
] != ',' && idx
!= in
->len
)
2854 fprintf (outfile
, "\n");
2855 ERROR ((stderr
, _("illegal character in SDATA line (0x%x).\n"),
2862 fprintf (outfile
, "\n");
2865 /* .SDATAB <count> <string> */
2877 idx
= exp_get_abs (_("Must have absolute SDATAB repeat count.\n"), idx
, in
, &repeat
);
2880 ERROR ((stderr
, _("Must have positive SDATAB repeat count (%d).\n"), repeat
));
2884 idx
= sb_skip_comma (idx
, in
);
2885 idx
= getstring (idx
, in
, &acc
);
2887 for (i
= 0; i
< repeat
; i
++)
2890 fprintf (outfile
, "\t");
2891 fprintf (outfile
, ".byte\t");
2892 sb_print (outfile
, &acc
);
2893 fprintf (outfile
, "\n");
2903 FILE *newone
= fopen (name
, "r");
2907 if (isp
== MAX_INCLUDES
)
2908 FATAL ((stderr
, _("Unreasonable include depth (%ld).\n"), (long) isp
));
2911 sp
->handle
= newone
;
2914 sb_add_string (&sp
->name
, name
);
2917 sp
->pushback_index
= 0;
2918 sp
->type
= include_file
;
2920 sb_new (&sp
->pushback
);
2925 do_include (idx
, in
)
2931 include_path
*includes
;
2937 idx
= getstring (idx
, in
, &t
);
2940 idx
= sb_skip_white (idx
, in
);
2941 while (idx
< in
->len
&& ! ISWHITE (in
->ptr
[idx
]))
2943 sb_add_char (&t
, in
->ptr
[idx
]);
2948 for (includes
= paths_head
; includes
; includes
= includes
->next
)
2951 sb_add_sb (&cat
, &includes
->path
);
2952 sb_add_char (&cat
, '/');
2953 sb_add_sb (&cat
, &t
);
2954 if (new_file (sb_name (&cat
)))
2961 if (! new_file (sb_name (&t
)))
2962 FATAL ((stderr
, _("Can't open include file `%s'.\n"), sb_name (&t
)));
2971 if (sp
!= include_stack
)
2974 fclose (sp
->handle
);
2979 /* Get the next character from the include stack. If there's anything
2980 in the pushback buffer, take that first. If we're at eof, pop from
2981 the stack and try again. Keep the linecount up to date. */
2988 if (sp
->pushback
.len
!= sp
->pushback_index
)
2990 r
= (char) (sp
->pushback
.ptr
[sp
->pushback_index
++]);
2991 /* When they've all gone, reset the pointer. */
2992 if (sp
->pushback_index
== sp
->pushback
.len
)
2994 sp
->pushback
.len
= 0;
2995 sp
->pushback_index
= 0;
2998 else if (sp
->handle
)
3000 r
= getc (sp
->handle
);
3005 if (r
== EOF
&& isp
)
3009 while (r
== EOF
&& isp
)
3027 return sp
->linecount
;
3031 include_next_index ()
3035 && index
> MAX_REASONABLE
)
3036 FATAL ((stderr
, _("Unreasonable expansion (-u turns off check).\n")));
3040 /* Initialize the chartype vector. */
3046 for (x
= 0; x
< 256; x
++)
3048 if (ISALPHA (x
) || x
== '_' || x
== '$')
3049 chartype
[x
] |= FIRSTBIT
;
3051 if (mri
&& x
== '.')
3052 chartype
[x
] |= FIRSTBIT
;
3054 if (ISDIGIT (x
) || ISALPHA (x
) || x
== '_' || x
== '$')
3055 chartype
[x
] |= NEXTBIT
;
3057 if (x
== ' ' || x
== '\t' || x
== ',' || x
== '"' || x
== ';'
3058 || x
== '"' || x
== '<' || x
== '>' || x
== ')' || x
== '(')
3059 chartype
[x
] |= SEPBIT
;
3061 if (x
== 'b' || x
== 'B'
3062 || x
== 'q' || x
== 'Q'
3063 || x
== 'h' || x
== 'H'
3064 || x
== 'd' || x
== 'D')
3065 chartype
[x
] |= BASEBIT
;
3067 if (x
== ' ' || x
== '\t')
3068 chartype
[x
] |= WHITEBIT
;
3070 if (x
== comment_char
)
3071 chartype
[x
] |= COMMENTBIT
;
3075 /* What to do with all the keywords. */
3076 #define PROCESS 0x1000 /* Run substitution over the line. */
3077 #define LAB 0x2000 /* Spit out the label. */
3079 #define K_EQU (PROCESS|1)
3080 #define K_ASSIGN (PROCESS|2)
3081 #define K_REG (PROCESS|3)
3082 #define K_ORG (PROCESS|4)
3083 #define K_RADIX (PROCESS|5)
3084 #define K_DATA (LAB|PROCESS|6)
3085 #define K_DATAB (LAB|PROCESS|7)
3086 #define K_SDATA (LAB|PROCESS|8)
3087 #define K_SDATAB (LAB|PROCESS|9)
3088 #define K_SDATAC (LAB|PROCESS|10)
3089 #define K_SDATAZ (LAB|PROCESS|11)
3090 #define K_RES (LAB|PROCESS|12)
3091 #define K_SRES (LAB|PROCESS|13)
3092 #define K_SRESC (LAB|PROCESS|14)
3093 #define K_SRESZ (LAB|PROCESS|15)
3094 #define K_EXPORT (LAB|PROCESS|16)
3095 #define K_GLOBAL (LAB|PROCESS|17)
3096 #define K_PRINT (LAB|PROCESS|19)
3097 #define K_FORM (LAB|PROCESS|20)
3098 #define K_HEADING (LAB|PROCESS|21)
3099 #define K_PAGE (LAB|PROCESS|22)
3100 #define K_IMPORT (LAB|PROCESS|23)
3101 #define K_PROGRAM (LAB|PROCESS|24)
3102 #define K_END (PROCESS|25)
3103 #define K_INCLUDE (PROCESS|26)
3104 #define K_IGNORED (PROCESS|27)
3105 #define K_ASSIGNA (PROCESS|28)
3106 #define K_ASSIGNC (29)
3107 #define K_AIF (PROCESS|30)
3108 #define K_AELSE (PROCESS|31)
3109 #define K_AENDI (PROCESS|32)
3110 #define K_AREPEAT (PROCESS|33)
3111 #define K_AENDR (PROCESS|34)
3112 #define K_AWHILE (35)
3113 #define K_AENDW (PROCESS|36)
3114 #define K_EXITM (37)
3115 #define K_MACRO (PROCESS|38)
3117 #define K_ALIGN (PROCESS|LAB|40)
3118 #define K_ALTERNATE (41)
3119 #define K_DB (LAB|PROCESS|42)
3120 #define K_DW (LAB|PROCESS|43)
3121 #define K_DL (LAB|PROCESS|44)
3122 #define K_LOCAL (45)
3123 #define K_IFEQ (PROCESS|46)
3124 #define K_IFNE (PROCESS|47)
3125 #define K_IFLT (PROCESS|48)
3126 #define K_IFLE (PROCESS|49)
3127 #define K_IFGE (PROCESS|50)
3128 #define K_IFGT (PROCESS|51)
3129 #define K_IFC (PROCESS|52)
3130 #define K_IFNC (PROCESS|53)
3131 #define K_IRP (PROCESS|54)
3132 #define K_IRPC (PROCESS|55)
3140 static struct keyword kinfo
[] = {
3141 { "EQU", K_EQU
, 0 },
3142 { "ALTERNATE", K_ALTERNATE
, 0 },
3143 { "ASSIGN", K_ASSIGN
, 0 },
3144 { "REG", K_REG
, 0 },
3145 { "ORG", K_ORG
, 0 },
3146 { "RADIX", K_RADIX
, 0 },
3147 { "DATA", K_DATA
, 0 },
3151 { "DATAB", K_DATAB
, 0 },
3152 { "SDATA", K_SDATA
, 0 },
3153 { "SDATAB", K_SDATAB
, 0 },
3154 { "SDATAZ", K_SDATAZ
, 0 },
3155 { "SDATAC", K_SDATAC
, 0 },
3156 { "RES", K_RES
, 0 },
3157 { "SRES", K_SRES
, 0 },
3158 { "SRESC", K_SRESC
, 0 },
3159 { "SRESZ", K_SRESZ
, 0 },
3160 { "EXPORT", K_EXPORT
, 0 },
3161 { "GLOBAL", K_GLOBAL
, 0 },
3162 { "PRINT", K_PRINT
, 0 },
3163 { "FORM", K_FORM
, 0 },
3164 { "HEADING", K_HEADING
, 0 },
3165 { "PAGE", K_PAGE
, 0 },
3166 { "PROGRAM", K_IGNORED
, 0 },
3167 { "END", K_END
, 0 },
3168 { "INCLUDE", K_INCLUDE
, 0 },
3169 { "ASSIGNA", K_ASSIGNA
, 0 },
3170 { "ASSIGNC", K_ASSIGNC
, 0 },
3171 { "AIF", K_AIF
, 0 },
3172 { "AELSE", K_AELSE
, 0 },
3173 { "AENDI", K_AENDI
, 0 },
3174 { "AREPEAT", K_AREPEAT
, 0 },
3175 { "AENDR", K_AENDR
, 0 },
3176 { "EXITM", K_EXITM
, 0 },
3177 { "MACRO", K_MACRO
, 0 },
3178 { "ENDM", K_ENDM
, 0 },
3179 { "AWHILE", K_AWHILE
, 0 },
3180 { "ALIGN", K_ALIGN
, 0 },
3181 { "AENDW", K_AENDW
, 0 },
3182 { "ALTERNATE", K_ALTERNATE
, 0 },
3183 { "LOCAL", K_LOCAL
, 0 },
3187 /* Although the conditional operators are handled by gas, we need to
3188 handle them here as well, in case they are used in a recursive
3189 macro to end the recursion. */
3191 static struct keyword mrikinfo
[] = {
3192 { "IFEQ", K_IFEQ
, 0 },
3193 { "IFNE", K_IFNE
, 0 },
3194 { "IFLT", K_IFLT
, 0 },
3195 { "IFLE", K_IFLE
, 0 },
3196 { "IFGE", K_IFGE
, 0 },
3197 { "IFGT", K_IFGT
, 0 },
3198 { "IFC", K_IFC
, 0 },
3199 { "IFNC", K_IFNC
, 0 },
3200 { "ELSEC", K_AELSE
, 0 },
3201 { "ENDC", K_AENDI
, 0 },
3202 { "MEXIT", K_EXITM
, 0 },
3203 { "REPT", K_AREPEAT
, 0 },
3204 { "IRP", K_IRP
, 0 },
3205 { "IRPC", K_IRPC
, 0 },
3206 { "ENDR", K_AENDR
, 0 },
3210 /* Look for a pseudo op on the line. If one's there then call
3214 process_pseudo_op (idx
, line
, acc
)
3221 if (line
->ptr
[idx
] == '.' || alternate
|| mri
)
3223 /* Scan forward and find pseudo name. */
3229 if (line
->ptr
[idx
] == '.')
3231 in
= line
->ptr
+ idx
;
3236 while (idx
< line
->len
&& *e
&& ISFIRSTCHAR (*e
))
3238 sb_add_char (acc
, *e
);
3243 ptr
= hash_lookup (&keyword_hash_table
, acc
);
3248 /* This one causes lots of pain when trying to preprocess
3250 WARNING ((stderr
, _("Unrecognised pseudo op `%s'.\n"),
3255 if (ptr
->value
.i
& LAB
)
3257 /* Output the label. */
3260 fprintf (outfile
, "%s:\t", sb_name (&label
));
3263 fprintf (outfile
, "\t");
3266 if (mri
&& ptr
->value
.i
== K_END
)
3271 sb_add_buffer (&t
, line
->ptr
+ oidx
, idx
- oidx
);
3272 fprintf (outfile
, "\t%s", sb_name (&t
));
3276 if (ptr
->value
.i
& PROCESS
)
3278 /* Polish the rest of the line before handling the pseudo op. */
3280 strip_comments (line
);
3283 process_assigns (idx
, line
, acc
);
3285 change_base (0, acc
, line
);
3290 switch (ptr
->value
.i
)
3306 switch (ptr
->value
.i
)
3310 macro_init (1, mri
, 0, exp_get_abs
);
3319 ERROR ((stderr
, _("ORG command not allowed.\n")));
3325 do_data (idx
, line
, 1);
3328 do_data (idx
, line
, 2);
3331 do_data (idx
, line
, 4);
3334 do_data (idx
, line
, 0);
3337 do_datab (idx
, line
);
3340 do_sdata (idx
, line
, 0);
3343 do_sdatab (idx
, line
);
3346 do_sdata (idx
, line
, 'c');
3349 do_sdata (idx
, line
, 'z');
3352 do_assign (0, 0, line
);
3358 do_arepeat (idx
, line
);
3364 do_awhile (idx
, line
);
3370 do_assign (1, idx
, line
);
3373 do_align (idx
, line
);
3376 do_res (idx
, line
, 0);
3379 do_res (idx
, line
, 's');
3382 do_include (idx
, line
);
3385 do_local (idx
, line
);
3388 do_macro (idx
, line
);
3394 do_res (idx
, line
, 'c');
3397 do_print (idx
, line
);
3400 do_form (idx
, line
);
3403 do_heading (idx
, line
);
3415 do_res (idx
, line
, 'z');
3423 do_assigna (idx
, line
);
3426 do_assignc (idx
, line
);
3435 do_if (idx
, line
, EQ
);
3438 do_if (idx
, line
, NE
);
3441 do_if (idx
, line
, LT
);
3444 do_if (idx
, line
, LE
);
3447 do_if (idx
, line
, GE
);
3450 do_if (idx
, line
, GT
);
3453 do_ifc (idx
, line
, 0);
3456 do_ifc (idx
, line
, 1);
3459 do_irp (idx
, line
, 0);
3462 do_irp (idx
, line
, 1);
3470 /* Add a keyword to the hash table. */
3473 add_keyword (name
, code
)
3481 sb_add_string (&label
, name
);
3483 hash_add_to_int_table (&keyword_hash_table
, &label
, code
);
3486 for (j
= 0; name
[j
]; j
++)
3487 sb_add_char (&label
, name
[j
] - 'A' + 'a');
3488 hash_add_to_int_table (&keyword_hash_table
, &label
, code
);
3493 /* Build the keyword hash table - put each keyword in the table twice,
3494 once upper and once lower case. */
3501 for (i
= 0; kinfo
[i
].name
; i
++)
3502 add_keyword (kinfo
[i
].name
, kinfo
[i
].code
);
3506 for (i
= 0; mrikinfo
[i
].name
; i
++)
3507 add_keyword (mrikinfo
[i
].name
, mrikinfo
[i
].code
);
3529 sb_add_char (&value
, *string
);
3532 exp_get_abs (_("Invalid expression on command line.\n"),
3537 sb_add_char (&label
, *string
);
3542 ptr
= hash_create (&vars
, &label
);
3543 free_old_entry (ptr
);
3544 ptr
->type
= hash_integer
;
3551 /* The list of long options. */
3552 static struct option long_options
[] =
3554 { "alternate", no_argument
, 0, 'a' },
3555 { "include", required_argument
, 0, 'I' },
3556 { "commentchar", required_argument
, 0, 'c' },
3557 { "copysource", no_argument
, 0, 's' },
3558 { "debug", no_argument
, 0, 'd' },
3559 { "help", no_argument
, 0, 'h' },
3560 { "mri", no_argument
, 0, 'M' },
3561 { "output", required_argument
, 0, 'o' },
3562 { "print", no_argument
, 0, 'p' },
3563 { "unreasonable", no_argument
, 0, 'u' },
3564 { "version", no_argument
, 0, 'v' },
3565 { "define", required_argument
, 0, 'd' },
3566 { NULL
, no_argument
, 0, 0 }
3569 /* Show a usage message and exit. */
3571 show_usage (file
, status
)
3577 [-a] [--alternate] enter alternate macro mode\n\
3578 [-c char] [--commentchar char] change the comment character from !\n\
3579 [-d] [--debug] print some debugging info\n\
3580 [-h] [--help] print this message\n\
3581 [-M] [--mri] enter MRI compatibility mode\n\
3582 [-o out] [--output out] set the output file\n\
3583 [-p] [--print] print line numbers\n"), program_name
);
3585 [-s] [--copysource] copy source through as comments \n\
3586 [-u] [--unreasonable] allow unreasonable nesting\n\
3587 [-v] [--version] print the program version\n\
3588 [-Dname=value] create preprocessor variable called name, with value\n\
3589 [-Ipath] add to include path list\n\
3592 printf (_("Report bugs to %s\n"), REPORT_BUGS_TO
);
3596 /* Display a help message and exit. */
3601 printf (_("%s: Gnu Assembler Macro Preprocessor\n"), program_name
);
3602 show_usage (stdout
, 0);
3605 int main
PARAMS ((int, char **));
3619 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
3620 setlocale (LC_MESSAGES
, "");
3622 #if defined (HAVE_SETLOCALE)
3623 setlocale (LC_CTYPE
, "");
3625 bindtextdomain (PACKAGE
, LOCALEDIR
);
3626 textdomain (PACKAGE
);
3628 program_name
= argv
[0];
3629 xmalloc_set_program_name (program_name
);
3631 hash_new_table (101, &keyword_hash_table
);
3632 hash_new_table (101, &assign_hash_table
);
3633 hash_new_table (101, &vars
);
3637 while ((opt
= getopt_long (argc
, argv
, "I:sdhavc:upo:D:M", long_options
,
3651 include_path
*p
= (include_path
*) xmalloc (sizeof (include_path
));
3654 sb_add_string (&p
->path
, optarg
);
3656 paths_tail
->next
= p
;
3663 print_line_number
= 1;
3666 comment_char
= optarg
[0];
3688 /* This output is intended to follow the GNU standards document. */
3689 printf (_("GNU assembler pre-processor %s\n"), program_version
);
3690 printf (_("Copyright 1996 Free Software Foundation, Inc.\n"));
3692 This program is free software; you may redistribute it under the terms of\n\
3693 the GNU General Public License. This program has absolutely no warranty.\n"));
3699 show_usage (stderr
, 1);
3706 macro_init (alternate
, mri
, 0, exp_get_abs
);
3710 outfile
= fopen (out_name
, "w");
3713 fprintf (stderr
, _("%s: Can't open output file `%s'.\n"),
3714 program_name
, out_name
);
3727 /* Process all the input files. */
3729 while (optind
< argc
)
3731 if (new_file (argv
[optind
]))
3737 fprintf (stderr
, _("%s: Can't open input file `%s'.\n"),
3738 program_name
, argv
[optind
]);
3748 /* This function is used because an abort in some of the other files
3749 may be compiled into as_abort because they include as.h. */
3752 as_abort (file
, line
, fn
)
3753 const char *file
, *fn
;
3756 fprintf (stderr
, _("Internal error, aborting at %s line %d"), file
, line
);
3758 fprintf (stderr
, " in %s", fn
);
3759 fprintf (stderr
, _("\nPlease report this bug.\n"));