X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Fgasp.c;h=b38bbf83f721290a36e54acad94ea5572b98fa2a;hb=d0398d6ac6e557e0b32628c7acd307b7dd538ef1;hp=c164412a89a1ea5e1756da5aaa25f47981a028e8;hpb=5f57cea3f66564abf5062e33ea31c0acd09efe82;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/gasp.c b/gas/gasp.c index c164412a89..b38bbf83f7 100644 --- a/gas/gasp.c +++ b/gas/gasp.c @@ -1,5 +1,6 @@ /* gasp.c - Gnu assembler preprocessor main program. - Copyright (C) 1994 Free Software Foundation, Inc. + Copyright (C) 1994, 95, 96, 97, 98, 99, 2000 + Free Software Foundation, Inc. Written by Steve and Judy Chamberlain of Cygnus Support, sac@cygnus.com @@ -17,15 +18,14 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with GASP; see the file COPYING. If not, write to - the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + along with GASP; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ /* - This program translates the input macros and stuff into a form suitable for gas to consume. - gasp [-sdhau] [-c char] [-o ] * -s copy source to output @@ -37,16 +37,16 @@ suitable for gas to consume. -a use alternate syntax Pseudo ops can start with or without a . Labels have to be in first column. + -I specify include dir Macro arg parameters subsituted by name, don't need the &. String can start with ' too. Strings can be surrounded by <..> - A % in a string evaluates the expression + A % in a string evaluates the expression Literal char in a string with ! - - */ #include "config.h" +#include "bin-bugs.h" #include #include @@ -61,98 +61,46 @@ suitable for gas to consume. extern char *malloc (); #endif +#include "ansidecl.h" #include "libiberty.h" +#include "sb.h" +#include "macro.h" +#include "asintl.h" char *program_version = "1.2"; -#define MAX_INCLUDES 30 /* Maximum include depth */ -#define MAX_REASONABLE 1000 /* Maximum number of expansions */ - -int unreasonable; /* -u on command line */ -int stats; /* -d on command line */ -int print_line_number; /* -p flag on command line */ -int copysource; /* -c flag on command line */ -int warnings; /* Number of WARNINGs generated so far. */ -int errors; /* Number of ERRORs generated so far. */ -int fatals; /* Number of fatal ERRORs generated so far (either 0 or 1). */ -int alternate = 0; /* -a on command line */ +/* This is normally declared in as.h, but we don't include that. We + need the function because other files linked with gasp.c might call + it. */ +extern void as_abort PARAMS ((const char *, int, const char *)); + +/* The default obstack chunk size. If we set this to zero, the + obstack code will use whatever will fit in a 4096 byte block. This + is used by the hash table code used by macro.c. */ +int chunksize = 0; + +#define MAX_INCLUDES 30 /* Maximum include depth. */ +#define MAX_REASONABLE 1000 /* Maximum number of expansions. */ + +int unreasonable; /* -u on command line. */ +int stats; /* -d on command line. */ +int print_line_number; /* -p flag on command line. */ +int copysource; /* -c flag on command line. */ +int warnings; /* Number of WARNINGs generated so far. */ +int errors; /* Number of ERRORs generated so far. */ +int fatals; /* Number of fatal ERRORs generated so far (either 0 or 1). */ +int alternate = 0; /* -a on command line. */ +int mri = 0; /* -M on command line. */ char comment_char = '!'; -int radix = 10; /* Default radix */ +int radix = 10; /* Default radix. */ -int had_end; /* Seen .END */ +int had_end; /* Seen .END. */ -/* The output stream */ +/* The output stream. */ FILE *outfile; - -/* Forward declarations. */ -static int condass_lookup_name(); -static int condass_on(); -static int get(); -static int get_and_process(); -static int get_token(); -static int getstring(); -static int include_next_index(); -static int macro_op(); -static int linecount(); -static int process_pseudo_op(); -static void include_pop(); -static void include_print_where_line(); -/* string blocks - - I had a couple of choices when deciding upon this data structure. - gas uses null terminated strings for all its internal work. This - often means that parts of the program that want to examine - substrings have to manipulate the data in the string to do the - right thing (a common operation is to single out a bit of text by - saving away the character after it, nulling it out, operating on - the substring and then replacing the character which was under the - null). This is a pain and I remember a load of problems that I had with - code in gas which almost got this right. Also, it's harder to grow and - allocate null terminated strings efficiently. - - Obstacks provide all the functionality needed, but are too - complicated, hence the sb. - - An sb is allocated by the caller, and is initialzed to point to an - sb_element. sb_elements are kept on a free lists, and used when - needed, replaced onto the free list when unused. - */ - -#define max_power_two 30 /* don't allow strings more than - 2^max_power_two long */ -/* structure of an sb */ -typedef struct sb - { - char *ptr; /* points to the current block. */ - int len; /* how much is used. */ - int pot; /* the maximum length is 1<integer mapping */ - hash_string, /* name->string mapping */ - hash_macro, /* name is a macro */ - hash_formal /* name is a formal argument */ - } hash_type; - -typedef struct hs - { - sb key; /* symbol name */ - hash_type type; /* symbol meaning */ - union - { - sb s; - int i; - struct macro_struct *m; - struct formal_struct *f; - } value; - struct hs *next; /* next hash_entry with same hash key */ - } hash_entry; - -typedef struct - { - hash_entry **table; - int size; - } hash_table; - - -/* Structures used to store macros. - - Each macro knows its name and included text. It gets built with a - list of formal arguments, and also keeps a hash table which points - into the list to speed up formal search. Each formal knows its - name and its default value. Each time the macro is expanded, the - formals get the actual values attatched to them. */ - -/* describe the formal arguments to a macro */ - -typedef struct formal_struct - { - struct formal_struct *next; /* next formal in list */ - sb name; /* name of the formal */ - sb def; /* the default value */ - sb actual; /* the actual argument (changed on each expansion) */ - int index; /* the index of the formal 0..formal_count-1 */ - } -formal_entry; - -/* describe the macro. */ - -typedef struct macro_struct - { - sb sub; /* substitution text. */ - int formal_count; /* number of formal args. */ - formal_entry *formals; /* pointer to list of formal_structs */ - hash_table formal_hash; /* hash table of formals. */ - } -macro_entry; - -/* how we nest files and expand macros etc. - - we keep a stack of of include_stack structs. each include file - pushes a new level onto the stack. we keep an sb with a pushback + with the same hash are kept in a chain. */ + +/* What the data in a hash_entry means. */ +typedef enum { + hash_integer, /* Name->integer mapping. */ + hash_string, /* Name->string mapping. */ + hash_macro, /* Name is a macro. */ + hash_formal /* Name is a formal argument. */ +} hash_type; + +typedef struct hs { + sb key; /* Symbol name. */ + hash_type type; /* Symbol meaning. */ + union { + sb s; + int i; + struct macro_struct *m; + struct formal_struct *f; + } value; + struct hs *next; /* Next hash_entry with same hash key. */ +} hash_entry; + +typedef struct { + hash_entry **table; + int size; +} hash_table; + +/* How we nest files and expand macros etc. + + We keep a stack of of include_stack structs. Each include file + pushes a new level onto the stack. We keep an sb with a pushback too. unget chars are pushed onto the pushback sb, getchars first checks the pushback sb before reading from the input stream. - small things are expanded by adding the text of the item onto the - pushback sb. larger items are grown by pushing a new level and - allocating the entire pushback buf for the item. each time - something like a macro is expanded, the stack index is changed. we + Small things are expanded by adding the text of the item onto the + pushback sb. Larger items are grown by pushing a new level and + allocating the entire pushback buf for the item. Each time + something like a macro is expanded, the stack index is changed. We can then perform an exitm by popping all entries off the stack with - the same stack index. if we're being reasonable, we can detect - recusive expansion by checking the index is reasonably small. - */ - -typedef enum - { - include_file, include_repeat, include_while, include_macro - } include_type; - -struct include_stack - { - sb pushback; /* current pushback stream */ - int pushback_index; /* next char to read from stream */ - FILE *handle; /* open file */ - sb name; /* name of file */ - int linecount; /* number of lines read so far */ - include_type type; - int index; /* index of this layer */ - } -include_stack[MAX_INCLUDES]; + the same stack index. If we're being reasonable, we can detect + recusive expansion by checking the index is reasonably small. */ + +typedef enum { + include_file, include_repeat, include_while, include_macro +} include_type; + +struct include_stack { + sb pushback; /* Current pushback stream. */ + int pushback_index; /* Next char to read from stream. */ + FILE *handle; /* Open file. */ + sb name; /* Name of file. */ + int linecount; /* Number of lines read so far. */ + include_type type; + int index; /* Index of this layer. */ +} include_stack[MAX_INCLUDES]; struct include_stack *sp; #define isp (sp - include_stack) -#define dsize 5 - - -void include_print_where_line (); - - -#define FATAL(x) \ - do { include_print_where_line (stderr); fprintf x ; fatals++; quit(); } while(0) -#define ERROR(x) \ - do { include_print_where_line (stderr); fprintf x; errors++; } while(0) -#define WARNING(x) \ - do { include_print_where_line (stderr); fprintf x; warnings++;} while(0) - - +/* Include file list. */ + +typedef struct include_path { + struct include_path *next; + sb path; +} include_path; + +include_path *paths_head; +include_path *paths_tail; + +static void quit PARAMS ((void)); +static void hash_new_table PARAMS ((int, hash_table *)); +static int hash PARAMS ((sb *)); +static hash_entry *hash_create PARAMS ((hash_table *, sb *)); +static void hash_add_to_string_table PARAMS ((hash_table *, sb *, sb *, int)); +static void hash_add_to_int_table PARAMS ((hash_table *, sb *, int)); +static hash_entry *hash_lookup PARAMS ((hash_table *, sb *)); +static void checkconst PARAMS ((int, exp_t *)); +static int sb_strtol PARAMS ((int, sb *, int, int *)); +static int level_0 PARAMS ((int, sb *, exp_t *)); +static int level_1 PARAMS ((int, sb *, exp_t *)); +static int level_2 PARAMS ((int, sb *, exp_t *)); +static int level_3 PARAMS ((int, sb *, exp_t *)); +static int level_4 PARAMS ((int, sb *, exp_t *)); +static int level_5 PARAMS ((int, sb *, exp_t *)); +static int exp_parse PARAMS ((int, sb *, exp_t *)); +static void exp_string PARAMS ((exp_t *, sb *)); +static int exp_get_abs PARAMS ((const char *, int, sb *, int *)); +#if 0 +static void strip_comments PARAMS ((sb *)); +#endif +static void unget PARAMS ((int)); +static void include_buf PARAMS ((sb *, sb *, include_type, int)); +static void include_print_where_line PARAMS ((FILE *)); +static void include_print_line PARAMS ((FILE *)); +static int get_line PARAMS ((sb *)); +static int grab_label PARAMS ((sb *, sb *)); +static void change_base PARAMS ((int, sb *, sb *)); +static void do_end PARAMS ((sb *)); +static void do_assign PARAMS ((int, int, sb *)); +static void do_radix PARAMS ((sb *)); +static int get_opsize PARAMS ((int, sb *, int *)); +static int eol PARAMS ((int, sb *)); +static void do_data PARAMS ((int, sb *, int)); +static void do_datab PARAMS ((int, sb *)); +static void do_align PARAMS ((int, sb *)); +static void do_res PARAMS ((int, sb *, int)); +static void do_export PARAMS ((sb *)); +static void do_print PARAMS ((int, sb *)); +static void do_heading PARAMS ((int, sb *)); +static void do_page PARAMS ((void)); +static void do_form PARAMS ((int, sb *)); +static int get_any_string PARAMS ((int, sb *, sb *, int, int)); +static int skip_openp PARAMS ((int, sb *)); +static int skip_closep PARAMS ((int, sb *)); +static int dolen PARAMS ((int, sb *, sb *)); +static int doinstr PARAMS ((int, sb *, sb *)); +static int dosubstr PARAMS ((int, sb *, sb *)); +static void process_assigns PARAMS ((int, sb *, sb *)); +static int get_and_process PARAMS ((int, sb *, sb *)); +static void process_file PARAMS ((void)); +static void free_old_entry PARAMS ((hash_entry *)); +static void do_assigna PARAMS ((int, sb *)); +static void do_assignc PARAMS ((int, sb *)); +static void do_reg PARAMS ((int, sb *)); +static int condass_lookup_name PARAMS ((sb *, int, sb *, int)); +static int whatcond PARAMS ((int, sb *, int *)); +static int istrue PARAMS ((int, sb *)); +static void do_aif PARAMS ((int, sb *)); +static void do_aelse PARAMS ((void)); +static void do_aendi PARAMS ((void)); +static int condass_on PARAMS ((void)); +static void do_if PARAMS ((int, sb *, int)); +static int get_mri_string PARAMS ((int, sb *, sb *, int)); +static void do_ifc PARAMS ((int, sb *, int)); +static void do_aendr PARAMS ((void)); +static void do_awhile PARAMS ((int, sb *)); +static void do_aendw PARAMS ((void)); +static void do_exitm PARAMS ((void)); +static void do_arepeat PARAMS ((int, sb *)); +static void do_endm PARAMS ((void)); +static void do_irp PARAMS ((int, sb *, int)); +static void do_local PARAMS ((int, sb *)); +static void do_macro PARAMS ((int, sb *)); +static int macro_op PARAMS ((int, sb *)); +static int getstring PARAMS ((int, sb *, sb *)); +static void do_sdata PARAMS ((int, sb *, int)); +static void do_sdatab PARAMS ((int, sb *)); +static int new_file PARAMS ((const char *)); +static void do_include PARAMS ((int, sb *)); +static void include_pop PARAMS ((void)); +static int get PARAMS ((void)); +static int linecount PARAMS ((void)); +static int include_next_index PARAMS ((void)); +static void chartype_init PARAMS ((void)); +static int process_pseudo_op PARAMS ((int, sb *, sb *)); +static void add_keyword PARAMS ((const char *, int)); +static void process_init PARAMS ((void)); +static void do_define PARAMS ((const char *)); +static void show_usage PARAMS ((FILE *, int)); +static void show_help PARAMS ((void)); + +#define FATAL(x) \ + do \ + { \ + include_print_where_line (stderr); \ + fprintf x; \ + fatals++; \ + quit (); \ + } \ + while (0) + +#define ERROR(x) \ + do \ + { \ + include_print_where_line (stderr); \ + fprintf x; \ + errors++; \ + } \ + while (0) + +#define WARNING(x) \ + do \ + { \ + include_print_where_line (stderr); \ + fprintf x; \ + warnings++; \ + } \ + while (0) + +/* Exit the program and return the right ERROR code. */ -/* exit the program and return the right ERROR code. */ -void +static void quit () { int exitcode; @@ -333,256 +350,22 @@ quit () else exitcode = 0; - if (stats) + if (stats) { int i; - for (i = 0; i < max_power_two; i++) + for (i = 0; i < sb_max_power_two; i++) { - fprintf (stderr, "strings size %8d : %d\n", 1<ptr[*]; - sb_kill (&foo); - -*/ - -/* initializes an sb. */ - -void -sb_build (ptr, size) - sb *ptr; - int size; -{ - /* see if we can find one to allocate */ - sb_element *e; - - if (size > max_power_two) - { - FATAL ((stderr, "string longer than %d bytes requested.\n", - 1 << max_power_two)); - } - e = free_list.size[size]; - if (!e) - { - /* nothing there, allocate one and stick into the free list */ - e = (sb_element *) xmalloc (sizeof (sb_element) + (1 << size)); - e->next = free_list.size[size]; - e->size = 1 << size; - free_list.size[size] = e; - string_count[size]++; - } - - /* remove from free list */ - - free_list.size[size] = e->next; - - /* copy into callers world */ - ptr->ptr = e->data; - ptr->pot = size; - ptr->len = 0; - ptr->item = e; -} - - -static void -sb_new (ptr) - sb *ptr; -{ - sb_build (ptr, dsize); -} - -/* deallocate the sb at ptr */ - -static -void -sb_kill (ptr) - sb *ptr; -{ - /* return item to free list */ - ptr->item->next = free_list.size[ptr->pot]; - free_list.size[ptr->pot] = ptr->item; -} - -/* add the sb at s to the end of the sb at ptr */ - -static void sb_check (); - -static -void -sb_add_sb (ptr, s) - sb *ptr; - sb *s; -{ - sb_check (ptr, s->len); - memcpy (ptr->ptr + ptr->len, s->ptr, s->len); - ptr->len += s->len; -} - -/* make sure that the sb at ptr has room for another len characters, - and grow it if it doesn't. */ - -static void -sb_check (ptr, len) - sb *ptr; - int len; -{ - if (ptr->len + len >= 1 << ptr->pot) - { - sb tmp; - int pot = ptr->pot; - while (ptr->len + len >= 1 << pot) - pot++; - sb_build (&tmp, pot); - sb_add_sb (&tmp, ptr); - sb_kill (ptr); - *ptr = tmp; - } -} - -/* make the sb at ptr point back to the beginning. */ - -static void -sb_reset (ptr) - sb *ptr; -{ - ptr->len = 0; -} - -/* add character c to the end of the sb at ptr. */ - -void -sb_add_char (ptr, c) - sb *ptr; - char c; -{ - sb_check (ptr, 1); - ptr->ptr[ptr->len++] = c; -} - -/* add null terminated string s to the end of sb at ptr. */ - -static void -sb_add_string (ptr, s) - sb *ptr; - char *s; -{ - int len = strlen (s); - sb_check (ptr, len); - memcpy (ptr->ptr + ptr->len, s, len); - ptr->len += len; -} - -/* add string at s of length len to sb at ptr */ - -static void -sb_add_buffer (ptr, s, len) - sb *ptr; - char *s; - int len; -{ - sb_check (ptr, len); - memcpy (ptr->ptr + ptr->len, s, len); - ptr->len += len; -} - - -/* print the sb at ptr to the output file */ - -static -void -sb_print (ptr) - sb *ptr; -{ - int i; - int nc = 0; - - for (i = 0; i < ptr->len; i++) - { - if (nc) - { - fprintf (outfile, ","); - } - fprintf (outfile, "%d", ptr->ptr[i]); - nc = 1; - } -} - -static -void -sb_print_at (idx, ptr) -int idx; -sb *ptr; -{ - int i; - for (i = idx; i < ptr->len; i++) - putc (ptr->ptr[i], outfile); -} -/* put a null at the end of the sb at in and return the start of the - string, so that it can be used as an arg to printf %s. */ - -static -char * -sb_name (in) - sb *in; -{ - /* stick a null on the end of the string */ - sb_add_char (in, 0); - return in->ptr; -} - -/* start at the index idx into the string in sb at ptr and skip - whitespace. return the index of the first non whitespace character */ - -static int -sb_skip_white (idx, ptr) - int idx; - sb *ptr; -{ - while (idx < ptr->len && ISWHITE (ptr->ptr[idx])) - idx++; - return idx; -} - -/* start at the index idx into the sb at ptr. skips whitespace, - a comma and any following whitespace. returnes the index of the - next character. */ - -static int -sb_skip_comma (idx, ptr) - int idx; - sb *ptr; -{ - while (idx < ptr->len && ISWHITE (ptr->ptr[idx])) - idx++; - - if (idx < ptr->len - && ptr->ptr[idx] == ',') - idx++; - - while (idx < ptr->len && ISWHITE (ptr->ptr[idx])) - idx++; - - return idx; -} - - -/* hash table maintenance. */ - -/* build a new hash table with size buckets, and fill in the info at ptr. */ +/* Build a new hash table with size buckets + and fill in the info at ptr. */ static void hash_new_table (size, ptr) @@ -597,7 +380,7 @@ hash_new_table (size, ptr) ptr->table[i] = 0; } -/* calculate and return the hash value of the sb at key. */ +/* Calculate and return the hash value of the sb at key. */ static int hash (key) @@ -614,11 +397,10 @@ hash (key) return k & 0xf0fff; } -/* lookup key in hash_table tab, if present, then return it, otherwise - build a new one and fill it with hash_integer. */ +/* Look up key in hash_table tab. If present, then return it, + otherwise build a new one and fill it with hash_integer. */ -static -hash_entry * +static hash_entry * hash_create (tab, key) hash_table *tab; sb *key; @@ -649,11 +431,10 @@ hash_create (tab, key) } } -/* add sb name with key into hash_table tab. if replacing old value - and again, then ERROR. */ +/* Add sb name with key into hash_table tab. + If replacing old value and again, then ERROR. */ -static -void +static void hash_add_to_string_table (tab, key, name, again) hash_table *tab; sb *key; @@ -668,19 +449,18 @@ hash_add_to_string_table (tab, key, name, again) if (ptr->value.s.len) { if (!again) - ERROR ((stderr, "redefintion not allowed")); + ERROR ((stderr, _("redefinition not allowed\n"))); } ptr->type = hash_string; sb_reset (&ptr->value.s); - + sb_add_sb (&ptr->value.s, name); } -/* add integer name to hash_table tab with sb key. */ +/* Add integer name to hash_table tab with sb key. */ -static -void +static void hash_add_to_int_table (tab, key, name) hash_table *tab; sb *key; @@ -690,11 +470,10 @@ hash_add_to_int_table (tab, key, name) ptr->value.i = name; } -/* lookup sb key in hash_table tab. if found return hash_entry result, - else 0. */ - -static -hash_entry * +/* Look up sb key in hash_table tab. + If found, return hash_entry result, else 0. */ + +static hash_entry * hash_lookup (tab, key) hash_table *tab; sb *key; @@ -712,7 +491,6 @@ hash_lookup (tab, key) return 0; } - /* expressions are handled in a really simple recursive decent way. each bit of @@ -727,31 +505,27 @@ hash_lookup (tab, key) + - & | ~ - */ +/* Make sure that the exp_t at term is constant. + If not the give the op ERROR. */ -/* make sure that the exp_t at term is constant, if not the give the op ERROR. */ - -static -void +static void checkconst (op, term) - char op; + int op; exp_t *term; { if (term->add_symbol.len || term->sub_symbol.len) { - ERROR ((stderr, "the %c operator cannot take non-absolute arguments.\n", op)); + ERROR ((stderr, _("the %c operator cannot take non-absolute arguments.\n"), op)); } } -/* turn the number in string at idx into a number of base, - fill in ptr and return the index of the first character not in the - number. */ +/* Turn the number in string at idx into a number of base, fill in + ptr, and return the index of the first character not in the number. */ -static -int +static int sb_strtol (idx, string, base, ptr) int idx; sb *string; @@ -784,9 +558,7 @@ sb_strtol (idx, string, base, ptr) return idx; } -static int level_5 (); - -int +static int level_0 (idx, string, lhs) int idx; sb *string; @@ -802,7 +574,7 @@ level_0 (idx, string, lhs) lhs->value = 0; - if (isdigit (string->ptr[idx])) + if (isdigit ((unsigned char) string->ptr[idx])) { idx = sb_strtol (idx, string, 10, &lhs->value); } @@ -821,20 +593,18 @@ level_0 (idx, string, lhs) { sb acc; sb_new (&acc); - ERROR ((stderr, "string where expression expected.\n")); + ERROR ((stderr, _("string where expression expected.\n"))); idx = getstring (idx, string, &acc); sb_kill (&acc); } else { - ERROR ((stderr, "can't find primary in expression.\n")); + ERROR ((stderr, _("can't find primary in expression.\n"))); idx++; } return sb_skip_white (idx, string); } - - static int level_1 (idx, string, lhs) int idx; @@ -867,7 +637,7 @@ level_1 (idx, string, lhs) idx++; idx = level_5 (sb_skip_white (idx, string), string, lhs); if (string->ptr[idx] != ')') - ERROR ((stderr, "misplaced closing parens.\n")); + ERROR ((stderr, _("misplaced closing parens.\n"))); else idx++; break; @@ -904,7 +674,7 @@ level_2 (idx, string, lhs) checkconst ('/', lhs); checkconst ('/', &rhs); if (rhs.value == 0) - ERROR ((stderr, "attempt to divide by zero.\n")); + ERROR ((stderr, _("attempt to divide by zero.\n"))); else lhs->value /= rhs.value; break; @@ -913,7 +683,6 @@ level_2 (idx, string, lhs) return sb_skip_white (idx, string); } - static int level_3 (idx, string, lhs) int idx; @@ -936,9 +705,9 @@ level_3 (idx, string, lhs) lhs->value += rhs.value; if (lhs->add_symbol.name && rhs.add_symbol.name) { - ERROR ((stderr, "can't add two relocatable expressions\n")); + ERROR ((stderr, _("can't add two relocatable expressions\n"))); } - /* change nn+symbol to symbol + nn */ + /* Change nn+symbol to symbol + nn. */ if (rhs.add_symbol.name) { lhs->add_symbol = rhs.add_symbol; @@ -1012,10 +781,9 @@ level_5 (idx, string, lhs) return sb_skip_white (idx, string); } - -/* parse the expression at offset idx into string, fill up res with - the result. return the index of the first char past the expression. - */ +/* Parse the expression at offset idx into string, fill up res with + the result. Return the index of the first char past the + expression. */ static int exp_parse (idx, string, res) @@ -1026,9 +794,8 @@ exp_parse (idx, string, res) return level_5 (sb_skip_white (idx, string), string, res); } - -/* turn the expression at exp into text and glue it onto the end of - string. */ +/* Turn the expression at exp into text and glue it onto the end of + string. */ static void exp_string (exp, string) @@ -1067,14 +834,13 @@ exp_string (exp, string) sb_add_char (string, '0'); } - -/* parse the expression at offset idx into sb in, return the value in val. - if the expression is not constant, give ERROR emsg. returns the index - of the first character past the end of the expression. */ +/* Parse the expression at offset idx into sb in. Return the value in + val. If the expression is not constant, give ERROR emsg. Return + the index of the first character past the end of the expression. */ static int exp_get_abs (emsg, idx, in, val) - char *emsg; + const char *emsg; int idx; sb *in; int *val; @@ -1082,21 +848,27 @@ exp_get_abs (emsg, idx, in, val) exp_t res; idx = exp_parse (idx, in, &res); if (res.add_symbol.len || res.sub_symbol.len) - ERROR ((stderr, emsg)); + ERROR ((stderr, "%s", emsg)); *val = res.value; return idx; } +/* Current label parsed from line. */ +sb label; + +/* Hash table for all assigned variables. */ +hash_table assign_hash_table; -sb label; /* current label parsed from line */ -hash_table assign_hash_table; /* hash table for all assigned variables */ -hash_table keyword_hash_table; /* hash table for keyword */ -hash_table vars; /* hash table for eq variables */ +/* Hash table for keyword. */ +hash_table keyword_hash_table; + +/* Hash table for eq variables. */ +hash_table vars; #define in_comment ';' -#if 1 -void +#if 0 +static void strip_comments (out) sb *out; { @@ -1104,7 +876,7 @@ strip_comments (out) int i = 0; for (i = 0; i < out->len; i++) { - if (ISCOMMENTCHAR(s[i])) + if (ISCOMMENTCHAR (s[i])) { out->len = i; return; @@ -1113,9 +885,9 @@ strip_comments (out) } #endif -/* push back character ch so that it can be read again. */ +/* Push back character ch so that it can be read again. */ -void +static void unget (ch) int ch; { @@ -1129,10 +901,10 @@ unget (ch) sb_add_char (&sp->pushback, ch); } -/* push the sb ptr onto the include stack, with the given name, type and index. */ +/* Push the sb ptr onto the include stack, with the given name, type + and index. */ -static -void +static void include_buf (name, ptr, type, index) sb *name; sb *ptr; @@ -1141,7 +913,7 @@ include_buf (name, ptr, type, index) { sp++; if (sp - include_stack >= MAX_INCLUDES) - FATAL ((stderr, "unreasonable nesting.\n")); + FATAL ((stderr, _("unreasonable nesting.\n"))); sb_new (&sp->name); sb_add_sb (&sp->name, name); sp->handle = 0; @@ -1153,10 +925,10 @@ include_buf (name, ptr, type, index) sb_add_sb (&sp->pushback, ptr); } +/* Used in ERROR messages, print info on where the include stack is + onto file. */ -/* used in ERROR messages, print info on where the include stack is onto file. */ -static -void +static void include_print_where_line (file) FILE *file; { @@ -1164,12 +936,13 @@ include_print_where_line (file) while (p <= sp) { - fprintf (file, "%s:%d ", sb_name (&p->name), p->linecount - ((p == sp) ? 1 : 0)); + fprintf (file, "%s:%d ", sb_name (&p->name), p->linecount - 1); p++; } } -/* used in listings, print the line number onto file. */ +/* Used in listings, print the line number onto file. */ + static void include_print_line (file) FILE *file; @@ -1191,8 +964,7 @@ include_print_line (file) } } - -/* read a line from the top of the include stack into sb in. */ +/* Read a line from the top of the include stack into sb in. */ static int get_line (in) @@ -1219,7 +991,7 @@ get_line (in) { if (online) { - WARNING ((stderr, "End of file not at start of line.\n")); + WARNING ((stderr, _("End of file not at start of line.\n"))); if (copysource) putc ('\n', outfile); ch = '\n'; @@ -1240,7 +1012,7 @@ get_line (in) online = 0; if (ch == '+') { - /* continued line */ + /* Continued line. */ if (copysource) { putc (comment_char, outfile); @@ -1265,7 +1037,7 @@ get_line (in) return more; } -/* find a label from sb in and put it in out. */ +/* Find a label from sb in and put it in out. */ static int grab_label (in, out) @@ -1274,13 +1046,13 @@ grab_label (in, out) { int i = 0; sb_reset (out); - if (ISFIRSTCHAR (in->ptr[i])) + if (ISFIRSTCHAR (in->ptr[i]) || in->ptr[i] == '\\') { sb_add_char (out, in->ptr[i]); i++; - while ((ISNEXTCHAR (in->ptr[i]) + while ((ISNEXTCHAR (in->ptr[i]) || in->ptr[i] == '\\' - || in->ptr[i] == '&') + || in->ptr[i] == '&') && i < in->len) { sb_add_char (out, in->ptr[i]); @@ -1290,8 +1062,8 @@ grab_label (in, out) return i; } -/* find all strange base stuff and turn into decimal. also - find all the other numbers and convert them from the default radix */ +/* Find all strange base stuff and turn into decimal. Also + find all the other numbers and convert them from the default radix. */ static void change_base (idx, in, out) @@ -1303,7 +1075,21 @@ change_base (idx, in, out) while (idx < in->len) { - if (idx < in->len - 1 && in->ptr[idx + 1] == '\'') + if (in->ptr[idx] == '\\' + && idx + 1 < in->len + && in->ptr[idx + 1] == '(') + { + idx += 2; + while (idx < in->len + && in->ptr[idx] != ')') + { + sb_add_char (out, in->ptr[idx]); + idx++; + } + if (idx < in->len) + idx++; + } + else if (idx < in->len - 1 && in->ptr[idx + 1] == '\'' && ! mri) { int base; int value; @@ -1326,7 +1112,7 @@ change_base (idx, in, out) base = 10; break; default: - ERROR ((stderr, "Illegal base character %c.\n", in->ptr[idx])); + ERROR ((stderr, _("Illegal base character %c.\n"), in->ptr[idx])); base = 10; break; } @@ -1337,7 +1123,7 @@ change_base (idx, in, out) } else if (ISFIRSTCHAR (in->ptr[idx])) { - /* copy entire names through quickly */ + /* Copy entire names through quickly. */ sb_add_char (out, in->ptr[idx]); idx++; while (idx < in->len && ISNEXTCHAR (in->ptr[idx])) @@ -1346,16 +1132,16 @@ change_base (idx, in, out) idx++; } } - else if (isdigit (in->ptr[idx])) + else if (isdigit ((unsigned char) in->ptr[idx])) { int value; - /* all numbers must start with a digit, let's chew it and - spit out decimal */ + /* All numbers must start with a digit, let's chew it and + spit out decimal. */ idx = sb_strtol (idx, in, radix, &value); sprintf (buffer, "%d", value); sb_add_string (out, buffer); - /* skip all undigsested letters */ + /* Skip all undigsested letters. */ while (idx < in->len && ISNEXTCHAR (in->ptr[idx])) { sb_add_char (out, in->ptr[idx]); @@ -1365,7 +1151,7 @@ change_base (idx, in, out) else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'') { char tchar = in->ptr[idx]; - /* copy entire names through quickly */ + /* Copy entire names through quickly. */ sb_add_char (out, in->ptr[idx]); idx++; while (idx < in->len && in->ptr[idx] != tchar) @@ -1376,7 +1162,7 @@ change_base (idx, in, out) } else { - /* nothing special, just pass it through */ + /* Nothing special, just pass it through. */ sb_add_char (out, in->ptr[idx]); idx++; } @@ -1384,14 +1170,18 @@ change_base (idx, in, out) } -/* .end */ +/* .end */ + static void -do_end () +do_end (in) + sb *in; { had_end = 1; + if (mri) + fprintf (outfile, "%s\n", sb_name (in)); } -/* .assign */ +/* .assign */ static void do_assign (again, idx, in) @@ -1399,7 +1189,7 @@ do_assign (again, idx, in) int idx; sb *in; { - /* stick label in symbol table with following value */ + /* Stick label in symbol table with following value. */ exp_t e; sb acc; @@ -1410,11 +1200,9 @@ do_assign (again, idx, in) sb_kill (&acc); } +/* .radix [b|q|d|h] */ -/* .radix [b|q|d|h] */ - -static -void +static void do_radix (ptr) sb *ptr; { @@ -1438,18 +1226,17 @@ do_radix (ptr) radix = 16; break; default: - ERROR ((stderr, "radix is %c must be one of b, q, d or h", radix)); + ERROR ((stderr, _("radix is %c must be one of b, q, d or h"), radix)); } } - -/* Parse off a .b, .w or .l */ +/* Parse off a .b, .w or .l. */ static int get_opsize (idx, in, size) -int idx; -sb *in; -int *size; + int idx; + sb *in; + int *size; { *size = 4; if (in->ptr[idx] == '.') @@ -1474,7 +1261,7 @@ int *size; case '\t': break; default: - ERROR ((stderr, "size must be one of b, w or l, is %c.\n", in->ptr[idx])); + ERROR ((stderr, _("size must be one of b, w or l, is %c.\n"), in->ptr[idx])); break; } idx++; @@ -1482,13 +1269,13 @@ int *size; return idx; } -static -int eol(idx, line) -int idx; -sb *line; +static int +eol (idx, line) + int idx; + sb *line; { idx = sb_skip_white (idx, line); - if (idx < line->len + if (idx < line->len && ISCOMMENTCHAR(line->ptr[idx])) return 1; if (idx >= line->len) @@ -1496,8 +1283,8 @@ sb *line; return 0; } -/* .data [.b|.w|.l] * - or d[bwl] * */ +/* .data [.b|.w|.l] * + or d[bwl] * */ static void do_data (idx, in, size) @@ -1510,13 +1297,14 @@ do_data (idx, in, size) sb acc; sb_new (&acc); - if (!size) + if (!size) { idx = get_opsize (idx, in, &opsize); } - else { - opsize = size; - } + else + { + opsize = size; + } switch (opsize) { case 4: @@ -1530,13 +1318,12 @@ do_data (idx, in, size) break; } - fprintf (outfile, "%s\t", opname); - idx = sb_skip_white (idx, in); + idx = sb_skip_white (idx, in); - if (alternate - && idx < in->len + if (alternate + && idx < in->len && in->ptr[idx] == '"') { int i; @@ -1544,11 +1331,11 @@ do_data (idx, in, size) for (i = 0; i < acc.len; i++) { if (i) - fprintf(outfile,","); + fprintf (outfile, ","); fprintf (outfile, "%d", acc.ptr[i]); } } - else + else { while (!eol (idx, in)) { @@ -1556,7 +1343,7 @@ do_data (idx, in, size) idx = exp_parse (idx, in, &e); exp_string (&e, &acc); sb_add_char (&acc, 0); - fprintf (outfile, acc.ptr); + fprintf (outfile, "%s", acc.ptr); if (idx < in->len && in->ptr[idx] == ',') { fprintf (outfile, ","); @@ -1565,11 +1352,11 @@ do_data (idx, in, size) } } sb_kill (&acc); - sb_print_at (idx, in); + sb_print_at (outfile, idx, in); fprintf (outfile, "\n"); } -/* .datab [.b|.w|.l] , */ +/* .datab [.b|.w|.l] , */ static void do_datab (idx, in) @@ -1582,49 +1369,58 @@ do_datab (idx, in) idx = get_opsize (idx, in, &opsize); - idx = exp_get_abs ("datab repeat must be constant.\n", idx, in, &repeat); + idx = exp_get_abs (_("datab repeat must be constant.\n"), idx, in, &repeat); idx = sb_skip_comma (idx, in); - idx = exp_get_abs ("datab data must be absolute.\n", idx, in, &fill); + idx = exp_get_abs (_("datab data must be absolute.\n"), idx, in, &fill); fprintf (outfile, ".fill\t%d,%d,%d\n", repeat, opsize, fill); } -/* .align */ +/* .align */ -void +static void do_align (idx, in) int idx; sb *in; { - int al; - idx = exp_get_abs ("align needs absolute expression.\n", idx, in, &al); + int al, have_fill, fill; - if (al != 1 - && al != 2 - && al != 4) - WARNING ((stderr, "alignment must be one of 1, 2 or 4.\n")); + idx = exp_get_abs (_("align needs absolute expression.\n"), idx, in, &al); + idx = sb_skip_white (idx, in); + have_fill = 0; + fill = 0; + if (! eol (idx, in)) + { + idx = sb_skip_comma (idx, in); + idx = exp_get_abs (_(".align needs absolute fill value.\n"), idx, in, + &fill); + have_fill = 1; + } - fprintf (outfile, ".align %d\n", al); + fprintf (outfile, ".align %d", al); + if (have_fill) + fprintf (outfile, ",%d", fill); + fprintf (outfile, "\n"); } -/* .res[.b|.w|.l] */ +/* .res[.b|.w|.l] */ -void +static void do_res (idx, in, type) int idx; sb *in; - char type; + int type; { int size = 4; int count = 0; idx = get_opsize (idx, in, &size); - while (!eol(idx, in)) + while (!eol (idx, in)) { idx = sb_skip_white (idx, in); if (in->ptr[idx] == ',') idx++; - idx = exp_get_abs ("res needs absolute expression for fill count.\n", idx, in, &count); + idx = exp_get_abs (_("res needs absolute expression for fill count.\n"), idx, in, &count); if (type == 'c' || type == 'z') count++; @@ -1633,19 +1429,18 @@ do_res (idx, in, type) } } +/* .export */ -/* .export */ - -void +static void do_export (in) sb *in; { fprintf (outfile, ".global %s\n", sb_name (in)); } -/* .print [list] [nolist] */ +/* .print [list] [nolist] */ -void +static void do_print (idx, in) int idx; sb *in; @@ -1667,8 +1462,9 @@ do_print (idx, in) } } -/* .head */ -void +/* .head */ + +static void do_heading (idx, in) int idx; sb *in; @@ -1680,16 +1476,17 @@ do_heading (idx, in) sb_kill (&head); } -/* .page */ +/* .page */ -void +static void do_page () { fprintf (outfile, ".eject\n"); } -/* .form [lin=] [col=] */ -void +/* .form [lin=] [col=] */ + +static void do_form (idx, in) int idx; sb *in; @@ -1704,13 +1501,13 @@ do_form (idx, in) if (strncasecmp (in->ptr + idx, "LIN=", 4) == 0) { idx += 4; - idx = exp_get_abs ("form LIN= needs absolute expresssion.\n", idx, in, &lines); + idx = exp_get_abs (_("form LIN= needs absolute expresssion.\n"), idx, in, &lines); } - if (strncasecmp (in->ptr + idx, "COL=", 4) == 0) + if (strncasecmp (in->ptr + idx, _("COL="), 4) == 0) { idx += 4; - idx = exp_get_abs ("form COL= needs absolute expresssion.\n", idx, in, &columns); + idx = exp_get_abs (_("form COL= needs absolute expresssion.\n"), idx, in, &columns); } idx++; @@ -1719,7 +1516,6 @@ do_form (idx, in) } - /* Fetch string from the input stream, rules: 'Bxyx -> return 'Bxyza @@ -1727,7 +1523,8 @@ do_form (idx, in) "" -> return string xyx -> return xyz */ -int + +static int get_any_string (idx, in, out, expand, pretend_quoted) int idx; sb *in; @@ -1740,7 +1537,7 @@ get_any_string (idx, in, out, expand, pretend_quoted) if (idx < in->len) { - if (in->len > 2 && in->ptr[idx+1] == '\'' && ISBASE (in->ptr[idx])) + if (in->len > 2 && in->ptr[idx + 1] == '\'' && ISBASE (in->ptr[idx])) { while (!ISSEP (in->ptr[idx])) sb_add_char (out, in->ptr[idx++]); @@ -1751,12 +1548,12 @@ get_any_string (idx, in, out, expand, pretend_quoted) { int val; char buf[20]; - /* Turns the next expression into a string */ - idx = exp_get_abs ("% operator needs absolute expression", + /* Turns the next expression into a string. */ + idx = exp_get_abs (_("% operator needs absolute expression"), idx + 1, in, &val); - sprintf(buf, "%d", val); + sprintf (buf, "%d", val); sb_add_string (out, buf); } else if (in->ptr[idx] == '"' @@ -1765,35 +1562,36 @@ get_any_string (idx, in, out, expand, pretend_quoted) { if (alternate && expand) { - /* Keep the quotes */ - sb_add_char (out, '\"'); - - idx = getstring (idx, in, out); - sb_add_char (out, '\"'); + /* Keep the quotes. */ + sb_add_char (out, '\"'); + + idx = getstring (idx, in, out); + sb_add_char (out, '\"'); } - else { - idx = getstring (idx, in, out); - } + else + { + idx = getstring (idx, in, out); + } } - else + else { - while (idx < in->len + while (idx < in->len && (in->ptr[idx] == '"' || in->ptr[idx] == '\'' - || pretend_quoted + || pretend_quoted || !ISSEP (in->ptr[idx]))) { - if (in->ptr[idx] == '"' + if (in->ptr[idx] == '"' || in->ptr[idx] == '\'') { char tchar = in->ptr[idx]; sb_add_char (out, in->ptr[idx++]); while (idx < in->len && in->ptr[idx] != tchar) - sb_add_char (out, in->ptr[idx++]); + sb_add_char (out, in->ptr[idx++]); if (idx == in->len) - return idx; + return idx; } sb_add_char (out, in->ptr[idx++]); } @@ -1803,40 +1601,39 @@ get_any_string (idx, in, out, expand, pretend_quoted) return idx; } +/* Skip along sb in starting at idx, suck off whitespace a ( and more + whitespace. Return the idx of the next char. */ -/* skip along sb in starting at idx, suck off whitespace a ( and more - whitespace. return the idx of the next char */ - -int +static int skip_openp (idx, in) int idx; sb *in; { idx = sb_skip_white (idx, in); if (in->ptr[idx] != '(') - ERROR ((stderr, "misplaced ( .\n")); + ERROR ((stderr, _("misplaced ( .\n"))); idx = sb_skip_white (idx + 1, in); return idx; } -/* skip along sb in starting at idx, suck off whitespace a ) and more - whitespace. return the idx of the next char */ +/* Skip along sb in starting at idx, suck off whitespace a ) and more + whitespace. Return the idx of the next char. */ -int +static int skip_closep (idx, in) int idx; sb *in; { idx = sb_skip_white (idx, in); if (in->ptr[idx] != ')') - ERROR ((stderr, "misplaced ).\n")); + ERROR ((stderr, _("misplaced ).\n"))); idx = sb_skip_white (idx + 1, in); return idx; } -/* .len */ +/* .len */ -int +static int dolen (idx, in, out) int idx; sb *in; @@ -1857,11 +1654,9 @@ dolen (idx, in, out) return idx; } +/* .instr */ -/* .instr */ - -static -int +static int doinstr (idx, in, out) int idx; sb *in; @@ -1881,9 +1676,9 @@ doinstr (idx, in, out) idx = sb_skip_comma (idx, in); idx = get_and_process (idx, in, &search); idx = sb_skip_comma (idx, in); - if (isdigit (in->ptr[idx])) + if (isdigit ((unsigned char) in->ptr[idx])) { - idx = exp_get_abs (".instr needs absolute expresson.\n", idx, in, &start); + idx = exp_get_abs (_(".instr needs absolute expresson.\n"), idx, in, &start); } else { @@ -1906,7 +1701,6 @@ doinstr (idx, in, out) return idx; } - static int dosubstr (idx, in, out) int idx; @@ -1921,19 +1715,18 @@ dosubstr (idx, in, out) idx = skip_openp (idx, in); idx = get_and_process (idx, in, &string); idx = sb_skip_comma (idx, in); - idx = exp_get_abs ("need absolute position.\n", idx, in, &pos); + idx = exp_get_abs (_("need absolute position.\n"), idx, in, &pos); idx = sb_skip_comma (idx, in); - idx = exp_get_abs ("need absolute length.\n", idx, in, &len); + idx = exp_get_abs (_("need absolute length.\n"), idx, in, &len); idx = skip_closep (idx, in); - if (len < 0 || pos < 0 || pos > string.len || pos + len > string.len) { sb_add_string (out, " "); } - else + else { sb_add_char (out, '"'); while (len > 0) @@ -1943,12 +1736,13 @@ dosubstr (idx, in, out) } sb_add_char (out, '"'); } - sb_kill(&string); + sb_kill (&string); return idx; } -/* scan line, change tokens in the hash table to their replacements */ -void +/* Scan line, change tokens in the hash table to their replacements. */ + +static void process_assigns (idx, in, buf) int idx; sb *in; @@ -1958,11 +1752,24 @@ process_assigns (idx, in, buf) { hash_entry *ptr; if (in->ptr[idx] == '\\' + && idx + 1 < in->len + && in->ptr[idx + 1] == '(') + { + do + { + sb_add_char (buf, in->ptr[idx]); + idx++; + } + while (idx < in->len && in->ptr[idx - 1] != ')'); + } + else if (in->ptr[idx] == '\\' + && idx + 1 < in->len && in->ptr[idx + 1] == '&') { idx = condass_lookup_name (in, idx + 2, buf, 1); } else if (in->ptr[idx] == '\\' + && idx + 1 < in->len && in->ptr[idx + 1] == '$') { idx = condass_lookup_name (in, idx + 2, buf, 0); @@ -1992,7 +1799,7 @@ process_assigns (idx, in, buf) idx = dosubstr (idx + 7, in, buf); else if (ISFIRSTCHAR (in->ptr[idx])) { - /* may be a simple name subsitution, see if we have a word */ + /* May be a simple name subsitution, see if we have a word. */ sb acc; int cur = idx + 1; while (cur < in->len @@ -2004,12 +1811,12 @@ process_assigns (idx, in, buf) ptr = hash_lookup (&assign_hash_table, &acc); if (ptr) { - /* Found a definition for it */ + /* Found a definition for it. */ sb_add_sb (buf, &ptr->value.s); } else { - /* No definition, just copy the word */ + /* No definition, just copy the word. */ sb_add_sb (buf, &acc); } sb_kill (&acc); @@ -2036,8 +1843,7 @@ get_and_process (idx, in, out) return idx; } -static -void +static void process_file () { sb line; @@ -2049,42 +1855,71 @@ process_file () sb_new (&line); sb_new (&t1); sb_new (&t2); - sb_new(&acc); + sb_new (&acc); sb_new (&label_in); sb_reset (&line); more = get_line (&line); while (more) { - /* Find any label and pseudo op that we're intested in */ + /* Find any label and pseudo op that we're intested in. */ int l; if (line.len == 0) { if (condass_on ()) fprintf (outfile, "\n"); } + else if (mri + && (line.ptr[0] == '*' + || line.ptr[0] == '!')) + { + /* MRI line comment. */ + fprintf (outfile, "%s", sb_name (&line)); + } else { l = grab_label (&line, &label_in); - sb_reset (&label); - if (label_in.len) - { - /* Munge any label */ - - - process_assigns (0, &label_in, &label); - } + sb_reset (&label); if (line.ptr[l] == ':') l++; while (ISWHITE (line.ptr[l]) && l < line.len) l++; - if (l < line.len) + if (label_in.len) { - if (process_pseudo_op (l, &line, &acc)) + int do_assigns; + + /* Munge the label, unless this is EQU or ASSIGN. */ + do_assigns = 1; + if (l < line.len + && (line.ptr[l] == '.' || alternate || mri)) { + int lx = l; + + if (line.ptr[lx] == '.') + ++lx; + if (lx + 3 <= line.len + && strncasecmp ("EQU", line.ptr + lx, 3) == 0 + && (lx + 3 == line.len + || ! ISFIRSTCHAR (line.ptr[lx + 3]))) + do_assigns = 0; + else if (lx + 6 <= line.len + && strncasecmp ("ASSIGN", line.ptr + lx, 6) == 0 + && (lx + 6 == line.len + || ! ISFIRSTCHAR (line.ptr[lx + 6]))) + do_assigns = 0; + } + if (do_assigns) + process_assigns (0, &label_in, &label); + else + sb_add_sb (&label, &label_in); + } + if (l < line.len) + { + if (process_pseudo_op (l, &line, &acc)) + { } else if (condass_on ()) @@ -2092,7 +1927,6 @@ process_file () if (macro_op (l, &line)) { - } else { @@ -2103,7 +1937,7 @@ process_file () } else fprintf (outfile, "\t"); - sb_reset(&t1); + sb_reset (&t1); process_assigns (l, &line, &t1); sb_reset (&t2); change_base (0, &t1, &t2); @@ -2112,13 +1946,14 @@ process_file () } } } - else { - /* Only a label on this line */ - if (label.len && condass_on()) - { - fprintf (outfile, "%s:\n", sb_name (&label)); - } - } + else + { + /* Only a label on this line. */ + if (label.len && condass_on ()) + { + fprintf (outfile, "%s:\n", sb_name (&label)); + } + } } if (had_end) @@ -2127,14 +1962,10 @@ process_file () more = get_line (&line); } - if (!had_end) - WARNING ((stderr, "END missing from end of file.\n")); + if (!had_end && !mri) + WARNING ((stderr, _("END missing from end of file.\n"))); } - - - - static void free_old_entry (ptr) hash_entry *ptr; @@ -2142,13 +1973,13 @@ free_old_entry (ptr) if (ptr) { if (ptr->type == hash_string) - sb_kill(&ptr->value.s); + sb_kill (&ptr->value.s); } } -/* name: .ASSIGNA */ +/* name: .ASSIGNA */ -void +static void do_assigna (idx, in) int idx; sb *in; @@ -2158,11 +1989,11 @@ do_assigna (idx, in) sb_new (&tmp); process_assigns (idx, in, &tmp); - idx = exp_get_abs (".ASSIGNA needs constant expression argument.\n", 0, &tmp, &val); + idx = exp_get_abs (_(".ASSIGNA needs constant expression argument.\n"), 0, &tmp, &val); if (!label.len) { - ERROR ((stderr, ".ASSIGNA without label.\n")); + ERROR ((stderr, _(".ASSIGNA without label.\n"))); } else { @@ -2174,9 +2005,9 @@ do_assigna (idx, in) sb_kill (&tmp); } -/* name: .ASSIGNC */ +/* name: .ASSIGNC */ -void +static void do_assignc (idx, in) int idx; sb *in; @@ -2187,7 +2018,7 @@ do_assignc (idx, in) if (!label.len) { - ERROR ((stderr, ".ASSIGNS without label.\n")); + ERROR ((stderr, _(".ASSIGNS without label.\n"))); } else { @@ -2200,19 +2031,24 @@ do_assignc (idx, in) sb_kill (&acc); } - -/* name: .REG (reg) */ +/* name: .REG (reg) */ static void do_reg (idx, in) int idx; sb *in; { - /* remove reg stuff from inside parens */ + /* Remove reg stuff from inside parens. */ sb what; - idx = skip_openp (idx, in); + if (!mri) + idx = skip_openp (idx, in); + else + idx = sb_skip_white (idx, in); sb_new (&what); - while (idx < in->len && in->ptr[idx] != ')') + while (idx < in->len + && (mri + ? ! eol (idx, in) + : in->ptr[idx] != ')')) { sb_add_char (&what, in->ptr[idx]); idx++; @@ -2221,7 +2057,6 @@ do_reg (idx, in) sb_kill (&what); } - static int condass_lookup_name (inbuf, idx, out, warn) sb *inbuf; @@ -2243,14 +2078,13 @@ condass_lookup_name (inbuf, idx, out, warn) idx++; ptr = hash_lookup (&vars, &condass_acc); - if (!ptr) { - if (warn) + if (warn) { - WARNING ((stderr, "Can't find preprocessor variable %s.\n", sb_name (&condass_acc))); + WARNING ((stderr, _("Can't find preprocessor variable %s.\n"), sb_name (&condass_acc))); } - else + else { sb_add_string (out, "0"); } @@ -2280,7 +2114,7 @@ condass_lookup_name (inbuf, idx, out, warn) #define GT 6 #define NEVER 7 -int +static int whatcond (idx, in, val) int idx; sb *in; @@ -2313,7 +2147,7 @@ whatcond (idx, in, val) } if (cond == NEVER) { - ERROR ((stderr, "Comparison operator must be one of EQ, NE, LT, LE, GT or GE.\n")); + ERROR ((stderr, _("Comparison operator must be one of EQ, NE, LT, LE, GT or GE.\n"))); cond = NEVER; } idx = sb_skip_white (idx + 2, in); @@ -2321,7 +2155,7 @@ whatcond (idx, in, val) return idx; } -int +static int istrue (idx, in) int idx; sb *in; @@ -2339,37 +2173,38 @@ istrue (idx, in) { int cond; int same; - /* This is a string comparision */ + /* This is a string comparision. */ idx = getstring (idx, in, &acc_a); idx = whatcond (idx, in, &cond); idx = getstring (idx, in, &acc_b); - same = acc_a.len == acc_b.len && (strncmp (acc_a.ptr, acc_b.ptr, acc_a.len) == 0); + same = acc_a.len == acc_b.len + && (strncmp (acc_a.ptr, acc_b.ptr, acc_a.len) == 0); if (cond != EQ && cond != NE) { - ERROR ((stderr, "Comparison operator for strings must be EQ or NE\n")); + ERROR ((stderr, _("Comparison operator for strings must be EQ or NE\n"))); res = 0; } else res = (cond != EQ) ^ same; } else - /* This is a numeric expression */ + /* This is a numeric expression. */ { int vala; int valb; int cond; - idx = exp_get_abs ("Conditional operator must have absolute operands.\n", idx, in, &vala); + idx = exp_get_abs (_("Conditional operator must have absolute operands.\n"), idx, in, &vala); idx = whatcond (idx, in, &cond); idx = sb_skip_white (idx, in); if (in->ptr[idx] == '"') { - WARNING ((stderr, "String compared against expression.\n")); + WARNING ((stderr, _("String compared against expression.\n"))); res = 0; } else { - idx = exp_get_abs ("Conditional operator must have absolute operands.\n", idx, in, &valb); + idx = exp_get_abs (_("Conditional operator must have absolute operands.\n"), idx, in, &valb); switch (cond) { default: @@ -2406,7 +2241,8 @@ istrue (idx, in) return res; } -/* .AIF */ +/* .AIF */ + static void do_aif (idx, in) int idx; @@ -2414,28 +2250,28 @@ do_aif (idx, in) { if (ifi >= IFNESTING) { - FATAL ((stderr, "AIF nesting unreasonable.\n")); + FATAL ((stderr, _("AIF nesting unreasonable.\n"))); } ifi++; - ifstack[ifi].on = ifstack[ifi-1].on ? istrue (idx, in) : 0; + ifstack[ifi].on = ifstack[ifi - 1].on ? istrue (idx, in) : 0; ifstack[ifi].hadelse = 0; } +/* .AELSE */ -/* .AELSE */ static void do_aelse () { - ifstack[ifi].on = ifstack[ifi-1].on ? !ifstack[ifi].on : 0; + ifstack[ifi].on = ifstack[ifi - 1].on ? !ifstack[ifi].on : 0; if (ifstack[ifi].hadelse) { - ERROR ((stderr, "Multiple AELSEs in AIF.\n")); + ERROR ((stderr, _("Multiple AELSEs in AIF.\n"))); } ifstack[ifi].hadelse = 1; } +/* .AENDI */ -/* .AENDI */ static void do_aendi () { @@ -2445,7 +2281,7 @@ do_aendi () } else { - ERROR ((stderr, "AENDI without AIF.\n")); + ERROR ((stderr, _("AENDI without AIF.\n"))); } } @@ -2455,115 +2291,157 @@ condass_on () return ifstack[ifi].on; } - -/* Read input lines till we get to a TO string. - Increase nesting depth if we geta FROM string. - Put the results into sb at PTR. */ +/* MRI IFEQ, IFNE, IFLT, IFLE, IFGE, IFGT. */ static void -buffer_and_nest (from, to, ptr) - char *from; - char *to; - sb *ptr; +do_if (idx, in, cond) + int idx; + sb *in; + int cond; { - int from_len = strlen (from); - int to_len = strlen (to); - int depth = 1; - int line_start = ptr->len; - int line = linecount (); - - int more = get_line (ptr); + int val; + int res; - while (more) + if (ifi >= IFNESTING) { - /* Try and find the first pseudo op on the line */ - int i = line_start; - - if (!alternate) - { - /* With normal syntax we can suck what we want till we get to the dot. - With the alternate, labels have to start in the first column, since - we cant tell what's a label and whats a pseudoop */ + FATAL ((stderr, _("IF nesting unreasonable.\n"))); + } - /* Skip leading whitespace */ - while (i < ptr->len - && ISWHITE (ptr->ptr[i])) - i++; + idx = exp_get_abs (_("Conditional operator must have absolute operands.\n"), + idx, in, &val); + switch (cond) + { + default: + case EQ: res = val == 0; break; + case NE: res = val != 0; break; + case LT: res = val < 0; break; + case LE: res = val <= 0; break; + case GE: res = val >= 0; break; + case GT: res = val > 0; break; + } - /* Skip over a label */ - while (i < ptr->len - && ISNEXTCHAR (ptr->ptr[i])) - i++; + ifi++; + ifstack[ifi].on = ifstack[ifi - 1].on ? res : 0; + ifstack[ifi].hadelse = 0; +} - /* And a colon */ - if (i < ptr->len - && ptr->ptr[i] == ':') - i++; +/* Get a string for the MRI IFC or IFNC pseudo-ops. */ - } - /* Skip trailing whitespace */ - while (i < ptr->len - && ISWHITE (ptr->ptr[i])) - i++; +static int +get_mri_string (idx, in, val, terminator) + int idx; + sb *in; + sb *val; + int terminator; +{ + idx = sb_skip_white (idx, in); - if (i < ptr->len && (ptr->ptr[i] == '.' - || alternate)) + if (idx < in->len + && in->ptr[idx] == '\'') + { + sb_add_char (val, '\''); + for (++idx; idx < in->len; ++idx) { - if (ptr->ptr[i] == '.') - i++; - if (strncasecmp (ptr->ptr + i, from, from_len) == 0) - depth++; - if (strncasecmp (ptr->ptr + i, to, to_len) == 0) + sb_add_char (val, in->ptr[idx]); + if (in->ptr[idx] == '\'') { - depth--; - if (depth == 0) - { - /* Reset the string to not include the ending rune */ - ptr->len = line_start; - break; - } + ++idx; + if (idx >= in->len + || in->ptr[idx] != '\'') + break; } } + idx = sb_skip_white (idx, in); + } + else + { + int i; + + while (idx < in->len + && in->ptr[idx] != terminator) + { + sb_add_char (val, in->ptr[idx]); + ++idx; + } + i = val->len - 1; + while (i >= 0 && ISWHITE (val->ptr[i])) + --i; + val->len = i + 1; + } + + return idx; +} + +/* MRI IFC, IFNC */ - /* Add a CR to the end and keep running */ - sb_add_char (ptr, '\n'); - line_start = ptr->len; - more = get_line (ptr); +static void +do_ifc (idx, in, ifnc) + int idx; + sb *in; + int ifnc; +{ + sb first; + sb second; + int res; + + if (ifi >= IFNESTING) + { + FATAL ((stderr, _("IF nesting unreasonable.\n"))); } + sb_new (&first); + sb_new (&second); + + idx = get_mri_string (idx, in, &first, ','); + + if (idx >= in->len || in->ptr[idx] != ',') + { + ERROR ((stderr, _("Bad format for IF or IFNC.\n"))); + return; + } - if (depth) - FATAL ((stderr, "End of file whilst inside %s, started on line %d.\n", from, line)); + idx = get_mri_string (idx + 1, in, &second, ';'); + + res = (first.len == second.len + && strncmp (first.ptr, second.ptr, first.len) == 0); + res ^= ifnc; + + ifi++; + ifstack[ifi].on = ifstack[ifi - 1].on ? res : 0; + ifstack[ifi].hadelse = 0; } +/* .ENDR */ -/* .ENDR */ -void +static void do_aendr () { - ERROR ((stderr, "AENDR without a AREPEAT.\n")); + if (!mri) + ERROR ((stderr, _("AENDR without a AREPEAT.\n"))); + else + ERROR ((stderr, _("ENDR without a REPT.\n"))); } -/* .AWHILE */ +/* .AWHILE */ -static -void +static void do_awhile (idx, in) int idx; sb *in; { + int line = linecount (); sb exp; - sb sub; - int doit; + sb_new (&sub); sb_new (&exp); process_assigns (idx, in, &exp); doit = istrue (0, &exp); - buffer_and_nest ("AWHILE", "AENDW", &sub); + if (! buffer_and_nest ("AWHILE", "AENDW", &sub, get_line)) + FATAL ((stderr, _("AWHILE without a AENDW at %d.\n"), line - 1)); /* Turn .AWHILE exp @@ -2574,7 +2452,7 @@ do_awhile (idx, in) .AWHILE exp foo .ENDW - */ + */ if (doit) { @@ -2587,7 +2465,7 @@ do_awhile (idx, in) sb_add_string (©, "\n"); sb_add_sb (©, &sub); sb_add_string (©, "\t.AENDW\n"); - /* Push another WHILE */ + /* Push another WHILE. */ include_buf (&exp, ©, include_while, index); sb_kill (©); } @@ -2595,19 +2473,17 @@ do_awhile (idx, in) sb_kill (&sub); } - -/* .AENDW */ +/* .AENDW */ static void do_aendw () { - ERROR ((stderr, "AENDW without a AENDW.\n")); + ERROR ((stderr, _("AENDW without a AENDW.\n"))); } - /* .EXITM - - Pop things off the include stack until the type and index changes */ + + Pop things off the include stack until the type and index changes. */ static void do_exitm () @@ -2627,24 +2503,32 @@ do_exitm () } } -/* .AREPEAT */ +/* .AREPEAT */ static void do_arepeat (idx, in) int idx; sb *in; { - sb exp; /* buffer with expression in it */ - sb copy; /* expanded repeat block */ - sb sub; /* contents of AREPEAT */ + int line = linecount (); + sb exp; /* Buffer with expression in it. */ + sb copy; /* Expanded repeat block. */ + sb sub; /* Contents of AREPEAT. */ int rc; + int ret; char buffer[30]; + sb_new (&exp); sb_new (©); sb_new (&sub); process_assigns (idx, in, &exp); - idx = exp_get_abs ("AREPEAT must have absolute operand.\n", 0, &exp, &rc); - buffer_and_nest ("AREPEAT", "AENDR", &sub); + idx = exp_get_abs (_("AREPEAT must have absolute operand.\n"), 0, &exp, &rc); + if (!mri) + ret = buffer_and_nest ("AREPEAT", "AENDR", &sub, get_line); + else + ret = buffer_and_nest ("REPT", "ENDR", &sub, get_line); + if (! ret) + FATAL ((stderr, _("AREPEAT without a AENDR at %d.\n"), line - 1)); if (rc > 0) { /* Push back the text following the repeat, and another repeat block @@ -2657,15 +2541,21 @@ do_arepeat (idx, in) .AREPEAT 19 foo .AENDR - */ + */ int index = include_next_index (); sb_add_sb (©, &sub); if (rc > 1) { - sprintf (buffer, "\t.AREPEAT %d\n", rc - 1); + if (!mri) + sprintf (buffer, "\t.AREPEAT %d\n", rc - 1); + else + sprintf (buffer, "\tREPT %d\n", rc - 1); sb_add_string (©, buffer); sb_add_sb (©, &sub); - sb_add_string (©, " .AENDR\n"); + if (!mri) + sb_add_string (©, " .AENDR\n"); + else + sb_add_string (©, " ENDR\n"); } include_buf (&exp, ©, include_repeat, index); @@ -2675,440 +2565,92 @@ do_arepeat (idx, in) sb_kill (©); } -/* .ENDM */ +/* .ENDM */ static void do_endm () { - ERROR ((stderr, ".ENDM without a matching .MACRO.\n")); + ERROR ((stderr, _(".ENDM without a matching .MACRO.\n"))); } +/* MRI IRP pseudo-op. */ -/* MARRO PROCESSING */ - -static int number; -hash_table macro_table; - -/* Understand - - .MACRO - stuff - .ENDM -*/ - -static int -do_formals (macro, idx, in) - macro_entry *macro; +static void +do_irp (idx, in, irpc) int idx; sb *in; + int irpc; { - formal_entry **p = ¯o->formals; - macro->formal_count = 0; - hash_new_table (5, ¯o->formal_hash); - while (idx < in->len) - { - formal_entry *formal; + const char *err; + sb out; - formal = (formal_entry *) xmalloc (sizeof (formal_entry)); + sb_new (&out); - sb_new (&formal->name); - sb_new (&formal->def); - sb_new (&formal->actual); + err = expand_irp (irpc, idx, in, &out, get_line, comment_char); + if (err != NULL) + ERROR ((stderr, "%s\n", err)); - idx = sb_skip_white (idx, in); - idx = get_token (idx, in, &formal->name); - if (formal->name.len == 0) - break; - idx = sb_skip_white (idx, in); - if (formal->name.len) - { - /* This is a formal */ - if (idx < in->len && in->ptr[idx] == '=') - { - /* Got a default */ - idx = get_any_string (idx + 1, in, &formal->def, 1, 0); - } - } + fprintf (outfile, "%s", sb_terminate (&out)); - { - /* Add to macro's hash table */ + sb_kill (&out); +} - hash_entry *p = hash_create (¯o->formal_hash, &formal->name); - p->type = hash_formal; - p->value.f = formal; - } +/* Macro processing. */ - formal->index = macro->formal_count; - idx = sb_skip_comma (idx, in); - macro->formal_count++; - *p = formal; - p = &formal->next; - } - return idx; -} +/* Parse off LOCAL n1, n2,... Invent a label name for it. */ -/* Parse off LOCAL n1, n2,... Invent a label name for it */ -static -void +static void do_local (idx, line) - int idx; - sb *line; + int idx ATTRIBUTE_UNUSED; + sb *line ATTRIBUTE_UNUSED; { - static int ln; - sb acc; - sb sub; - char subs[10]; - sb_new (&acc); - sb_new (&sub); - idx = sb_skip_white (idx, line); - while (!eol(idx, line)) - { - sb_reset (&acc); - sb_reset (&sub); - ln++; - sprintf(subs, "LL%04x", ln); - idx = get_token(idx, line, &acc); - sb_add_string (&sub, subs); - hash_add_to_string_table (&assign_hash_table, &acc, &sub, 1); - idx = sb_skip_comma (idx, line); - } - sb_kill (&sub); - sb_kill (&acc); + ERROR ((stderr, _("LOCAL outside of MACRO"))); } -static -void +static void do_macro (idx, in) int idx; sb *in; { - macro_entry *macro; - sb name; - - macro = (macro_entry *) xmalloc (sizeof (macro_entry)); - sb_new (¯o->sub); - sb_new (&name); - - macro->formal_count = 0; - macro->formals = 0; - - idx = sb_skip_white (idx, in); - buffer_and_nest ("MACRO", "ENDM", ¯o->sub); - if (label.len) - { - - sb_add_sb (&name, &label); - if (in->ptr[idx] == '(') - { - /* It's the label: MACRO (formals,...) sort */ - idx = do_formals (macro, idx + 1, in); - if (in->ptr[idx] != ')') - ERROR ((stderr, "Missing ) after formals.\n")); - } - else { - /* It's the label: MACRO formals,... sort */ - idx = do_formals (macro, idx, in); - } - } - else - { - idx = get_token (idx, in, &name); - idx = sb_skip_white (idx, in); - idx = do_formals (macro, idx, in); - } - - /* and stick it in the macro hash table */ - hash_create (¯o_table, &name)->value.m = macro; -} - -static -int -get_token (idx, in, name) - int idx; - sb *in; - sb *name; -{ - if (idx < in->len - && ISFIRSTCHAR (in->ptr[idx])) - { - sb_add_char (name, in->ptr[idx++]); - while (idx < in->len - && ISNEXTCHAR (in->ptr[idx])) - { - sb_add_char (name, in->ptr[idx++]); - } - } - /* Ignore trailing & */ - if (alternate && idx < in->len && in->ptr[idx] == '&') - idx++; - return idx; -} + const char *err; + int line = linecount (); -/* Scan a token, but stop if a ' is seen */ -static int -get_apost_token (idx, in, name, kind) - int idx; - sb *in; - sb *name; - int kind; -{ - idx = get_token (idx, in, name); - if (idx < in->len && in->ptr[idx] == kind) - idx++; - return idx; + err = define_macro (idx, in, &label, get_line, (const char **) NULL); + if (err != NULL) + ERROR ((stderr, _("macro at line %d: %s\n"), line - 1, err)); } static int -sub_actual (src, in, t, m, kind, out, copyifnotthere) - int src; - sb *in; - sb *t; - macro_entry *m; - int kind; - sb *out; - int copyifnotthere; -{ - /* This is something to take care of */ - hash_entry *ptr; - src = get_apost_token (src, in, t, kind); - /* See if it's in the macro's hash table */ - ptr = hash_lookup (&m->formal_hash, t); - if (ptr) - { - if (ptr->value.f->actual.len) - { - sb_add_sb (out, &ptr->value.f->actual); - } - else - { - sb_add_sb (out, &ptr->value.f->def); - } - } - else if (copyifnotthere) - { - sb_add_sb (out, t); - } - else - { - sb_add_char (out, '\\'); - sb_add_sb (out, t); - } - return src; -} - -static -void -macro_expand (name, idx, in, m) - sb *name; +macro_op (idx, in) int idx; sb *in; - macro_entry *m; { - sb t; + const char *err; sb out; - hash_entry *ptr; - formal_entry *f; - int is_positional = 0; - int is_keyword = 0; - - sb_new (&t); - sb_new (&out); - - /* Reset any old value the actuals may have */ - for (f = m->formals; f; f = f->next) - sb_reset (&f->actual); - f = m->formals; - /* Peel off the actuals and store them away in the hash tables' actuals */ - while (!eol(idx, in)) - { - int scan; - idx = sb_skip_white (idx, in); - /* Look and see if it's a positional or keyword arg */ - scan = idx; - while (scan < in->len - && !ISSEP (in->ptr[scan]) - && (!alternate && in->ptr[scan] != '=')) - scan++; - if (scan < in->len && (!alternate) && in->ptr[scan] == '=') - { - is_keyword = 1; - if (is_positional) - { - ERROR ((stderr, "Can't mix positional and keyword arguments.\n")); - return; - } - /* This is a keyword arg, fetch the formal name and - then the actual stuff */ - sb_reset (&t); - idx = get_token (idx, in, &t); - if (in->ptr[idx] != '=') - ERROR ((stderr, "confused about formal params.\n")); - - /* Lookup the formal in the macro's list */ - ptr = hash_lookup (&m->formal_hash, &t); - if (!ptr) - { - ERROR ((stderr, "MACRO formal argument %s does not exist.\n", sb_name (&t))); - return; - } - else - { - /* Insert this value into the right place */ - sb_reset (&ptr->value.f->actual); - idx = get_any_string (idx + 1, in, &ptr->value.f->actual, 0, 0); - } - } - else - { - /* This is a positional arg */ - is_positional = 1; - if (is_keyword) - { - ERROR ((stderr, "Can't mix positional and keyword arguments.\n")); - return; - } - if (!f) - { - ERROR ((stderr, "Too many positional arguments.\n")); - return; - } - - sb_reset (&f->actual); - idx = get_any_string (idx, in, &f->actual, 1, 0); - f = f->next; - } - idx = sb_skip_comma (idx, in); - } - - /* Copy the stuff from the macro buffer into a safe place and substitute any args */ - - { - int src = 0; - int inquote = 0; - sb *in = &m->sub; - sb_reset (&out); + sb name; - while (src < in->len) - { - if (in->ptr[src] == '&') - { - sb_reset (&t); - src = sub_actual (src + 1, in, &t, m, '&', &out, 0); - } - else if (in->ptr[src] == '\\') - { - src++; - if (in->ptr[src] == comment_char) - { - /* This is a comment, just drop the rest of the line */ - while (src < in->len - && in->ptr[src] != '\n') - src++; - - } - else if (in->ptr[src] == '(') - { - /* Sub in till the next ')' literally */ - src++; - while (src < in->len && in->ptr[src] != ')') - { - sb_add_char (&out, in->ptr[src++]); - } - if (in->ptr[src] == ')') - src++; - else - ERROR ((stderr, "Missplaced ).\n")); - } - else if (in->ptr[src] == '@') - { - /* Sub in the macro invocation number */ - - char buffer[6]; - src++; - sprintf (buffer, "%05d", number); - sb_add_string (&out, buffer); - } - else if (in->ptr[src] == '&') - { - /* This is a preprocessor variable name, we don't do them - here */ - sb_add_char (&out, '\\'); - sb_add_char (&out, '&'); - src++; - } - else - { - sb_reset (&t); - src = sub_actual (src, in, &t, m, '\'', &out, 0); - } - } - else if (ISFIRSTCHAR (in->ptr[src]) && alternate) - { - sb_reset (&t); - src = sub_actual (src, in, &t, m, '\'', &out, 1); - } - else if (ISCOMMENTCHAR (in->ptr[src]) - && src + 1 < in->len - && ISCOMMENTCHAR (in->ptr[src+1]) - && !inquote) - { - /* Two comment chars in a row cause the rest of the line to be dropped */ - while (src < in->len && in->ptr[src] != '\n') - src++; - } - else if (in->ptr[src] == '"') - { - inquote = !inquote; - sb_add_char (&out, in->ptr[src++]); - } - else - { - sb_add_char (&out, in->ptr[src++]); - } - } - include_buf (name, &out, include_macro, include_next_index ()); - } - sb_kill (&t); - sb_kill (&out); - number++; -} + if (! macro_defined) + return 0; -static int -macro_op (idx, in) - int idx; - sb *in; -{ - int res = 0; - /* The macro name must be the first thing on the line */ - if (idx < in->len) - { - sb name; - hash_entry *ptr; - sb_new (&name); - idx = get_token (idx, in, &name); + sb_terminate (in); + if (! check_macro (in->ptr + idx, &out, comment_char, &err, NULL)) + return 0; - if (name.len) - { - /* Got a name, look it up */ + if (err != NULL) + ERROR ((stderr, "%s\n", err)); - ptr = hash_lookup (¯o_table, &name); + sb_new (&name); + sb_add_string (&name, _("macro expansion")); - if (ptr) - { - /* It's in the table, copy out the stuff and convert any macro args */ - macro_expand (&name, idx, in, ptr->value.m); - res = 1; - } - } - sb_kill (&name); - } + include_buf (&name, &out, include_macro, include_next_index ()); + sb_kill (&name); + sb_kill (&out); - return res; + return 1; } - -/* STRING HANDLING */ +/* String handling. */ static int getstring (idx, in, acc) @@ -3119,13 +2661,13 @@ getstring (idx, in, acc) idx = sb_skip_white (idx, in); while (idx < in->len - && (in->ptr[idx] == '"' - || in->ptr[idx] == '<' + && (in->ptr[idx] == '"' + || in->ptr[idx] == '<' || (in->ptr[idx] == '\'' && alternate))) { if (in->ptr[idx] == '<') { - if (alternate) + if (alternate || mri) { int nest = 0; idx++; @@ -3134,30 +2676,32 @@ getstring (idx, in, acc) { if (in->ptr[idx] == '!') { - idx++ ; + idx++; + sb_add_char (acc, in->ptr[idx++]); + } + else + { + if (in->ptr[idx] == '>') + nest--; + if (in->ptr[idx] == '<') + nest++; sb_add_char (acc, in->ptr[idx++]); } - else { - if (in->ptr[idx] == '>') - nest--; - if (in->ptr[idx] == '<') - nest++; - sb_add_char (acc, in->ptr[idx++]); - } } idx++; } - else { - int code; - idx++; - idx = exp_get_abs ("Character code in string must be absolute expression.\n", - idx, in, &code); - sb_add_char (acc, code); + else + { + int code; + idx++; + idx = exp_get_abs (_("Character code in string must be absolute expression.\n"), + idx, in, &code); + sb_add_char (acc, code); - if (in->ptr[idx] != '>') - ERROR ((stderr, "Missing > for character code.\n")); - idx++; - } + if (in->ptr[idx] != '>') + ERROR ((stderr, _("Missing > for character code.\n"))); + idx++; + } } else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'') { @@ -3167,34 +2711,34 @@ getstring (idx, in, acc) { if (alternate && in->ptr[idx] == '!') { - idx++ ; + idx++; sb_add_char (acc, in->ptr[idx++]); } - else { - if (in->ptr[idx] == tchar) - { - idx++; - if (idx >= in->len || in->ptr[idx] != tchar) - break; - } - sb_add_char (acc, in->ptr[idx]); - idx++; - } + else + { + if (in->ptr[idx] == tchar) + { + idx++; + if (idx >= in->len || in->ptr[idx] != tchar) + break; + } + sb_add_char (acc, in->ptr[idx]); + idx++; + } } } } - + return idx; } -/* .SDATA[C|Z] */ +/* .SDATA[C|Z] */ -static -void +static void do_sdata (idx, in, type) int idx; sb *in; - char type; + int type; { int nc = 0; int pidx = -1; @@ -3214,7 +2758,7 @@ do_sdata (idx, in, type) { if (acc.len > 255) { - ERROR ((stderr, "string for SDATAC longer than 255 characters (%d).\n", acc.len)); + ERROR ((stderr, _("string for SDATAC longer than 255 characters (%d).\n"), acc.len)); } fprintf (outfile, "%d", acc.len); nc = 1; @@ -3237,12 +2781,14 @@ do_sdata (idx, in, type) fprintf (outfile, "0"); } idx = sb_skip_comma (idx, in); - if (idx == pidx) break; + if (idx == pidx) + break; } if (!alternate && in->ptr[idx] != ',' && idx != in->len) { fprintf (outfile, "\n"); - ERROR ((stderr, "illegal character in SDATA line (0x%x).\n", in->ptr[idx])); + ERROR ((stderr, _("illegal character in SDATA line (0x%x).\n"), + in->ptr[idx])); break; } idx++; @@ -3251,7 +2797,7 @@ do_sdata (idx, in, type) fprintf (outfile, "\n"); } -/* .SDATAB */ +/* .SDATAB */ static void do_sdatab (idx, in) @@ -3263,10 +2809,10 @@ do_sdatab (idx, in) sb acc; sb_new (&acc); - idx = exp_get_abs ("Must have absolute SDATAB repeat count.\n", idx, in, &repeat); + idx = exp_get_abs (_("Must have absolute SDATAB repeat count.\n"), idx, in, &repeat); if (repeat <= 0) { - ERROR ((stderr, "Must have positive SDATAB repeat count (%d).\n", repeat)); + ERROR ((stderr, _("Must have positive SDATAB repeat count (%d).\n"), repeat)); repeat = 1; } @@ -3278,23 +2824,23 @@ do_sdatab (idx, in) if (i) fprintf (outfile, "\t"); fprintf (outfile, ".byte\t"); - sb_print (&acc); + sb_print (outfile, &acc); fprintf (outfile, "\n"); } sb_kill (&acc); } -int +static int new_file (name) - char *name; + const char *name; { FILE *newone = fopen (name, "r"); if (!newone) return 0; if (isp == MAX_INCLUDES) - FATAL ((stderr, "Unreasonable include depth (%ld).\n", (long) isp)); + FATAL ((stderr, _("Unreasonable include depth (%ld).\n"), (long) isp)); sp++; sp->handle = newone; @@ -3316,14 +2862,41 @@ do_include (idx, in) sb *in; { sb t; - char *text; + sb cat; + include_path *includes; + sb_new (&t); - idx = getstring (idx, in, &t); - text = sb_name (&t); - if (!new_file (text)) + sb_new (&cat); + + if (! mri) + idx = getstring (idx, in, &t); + else + { + idx = sb_skip_white (idx, in); + while (idx < in->len && ! ISWHITE (in->ptr[idx])) + { + sb_add_char (&t, in->ptr[idx]); + ++idx; + } + } + + for (includes = paths_head; includes; includes = includes->next) + { + sb_reset (&cat); + sb_add_sb (&cat, &includes->path); + sb_add_char (&cat, '/'); + sb_add_sb (&cat, &t); + if (new_file (sb_name (&cat))) + { + break; + } + } + if (!includes) { - FATAL ((stderr, "Can't open include file `%s'.\n", text)); + if (! new_file (sb_name (&t))) + FATAL ((stderr, _("Can't open include file `%s'.\n"), sb_name (&t))); } + sb_kill (&cat); sb_kill (&t); } @@ -3340,7 +2913,7 @@ include_pop () /* Get the next character from the include stack. If there's anything in the pushback buffer, take that first. If we're at eof, pop from - the stack and try again. Keep the linecount up to date. */ + the stack and try again. Keep the linecount up to date. */ static int get () @@ -3350,7 +2923,7 @@ get () if (sp->pushback.len != sp->pushback_index) { r = (char) (sp->pushback.ptr[sp->pushback_index++]); - /* When they've all gone, reset the pointer */ + /* When they've all gone, reset the pointer. */ if (sp->pushback_index == sp->pushback.len) { sp->pushback.len = 0; @@ -3395,12 +2968,11 @@ include_next_index () static int index; if (!unreasonable && index > MAX_REASONABLE) - FATAL ((stderr, "Unreasonable expansion (-u turns off check).\n")); + FATAL ((stderr, _("Unreasonable expansion (-u turns off check).\n"))); return ++index; } - -/* Initialize the chartype vector. */ +/* Initialize the chartype vector. */ static void chartype_init () @@ -3411,6 +2983,9 @@ chartype_init () if (isalpha (x) || x == '_' || x == '$') chartype[x] |= FIRSTBIT; + if (mri && x == '.') + chartype[x] |= FIRSTBIT; + if (isdigit (x) || isalpha (x) || x == '_' || x == '$') chartype[x] |= NEXTBIT; @@ -3423,7 +2998,7 @@ chartype_init () || x == 'h' || x == 'H' || x == 'd' || x == 'D') chartype [x] |= BASEBIT; - + if (x == ' ' || x == '\t') chartype[x] |= WHITEBIT; @@ -3432,66 +3007,72 @@ chartype_init () } } - - -/* What to do with all the keywords */ -#define PROCESS 0x1000 /* Run substitution over the line */ -#define LAB 0x2000 /* Spit out the label */ - -#define K_EQU PROCESS|1 -#define K_ASSIGN PROCESS|2 -#define K_REG PROCESS|3 -#define K_ORG PROCESS|4 -#define K_RADIX PROCESS|5 -#define K_DATA LAB|PROCESS|6 -#define K_DATAB LAB|PROCESS|7 -#define K_SDATA LAB|PROCESS|8 -#define K_SDATAB LAB|PROCESS|9 -#define K_SDATAC LAB|PROCESS|10 -#define K_SDATAZ LAB|PROCESS|11 -#define K_RES LAB|PROCESS|12 -#define K_SRES LAB|PROCESS|13 -#define K_SRESC LAB|PROCESS|14 -#define K_SRESZ LAB|PROCESS|15 -#define K_EXPORT LAB|PROCESS|16 -#define K_GLOBAL LAB|PROCESS|17 -#define K_PRINT LAB|PROCESS|19 -#define K_FORM LAB|PROCESS|20 -#define K_HEADING LAB|PROCESS|21 -#define K_PAGE LAB|PROCESS|22 -#define K_IMPORT LAB|PROCESS|23 -#define K_PROGRAM LAB|PROCESS|24 -#define K_END PROCESS|25 -#define K_INCLUDE PROCESS|26 -#define K_IGNORED PROCESS|27 -#define K_ASSIGNA PROCESS|28 -#define K_ASSIGNC 29 -#define K_AIF PROCESS|30 -#define K_AELSE PROCESS|31 -#define K_AENDI PROCESS|32 -#define K_AREPEAT PROCESS|33 -#define K_AENDR PROCESS|34 -#define K_AWHILE 35 -#define K_AENDW PROCESS|36 -#define K_EXITM 37 -#define K_MACRO PROCESS|38 -#define K_ENDM 39 -#define K_ALIGN PROCESS|LAB|40 -#define K_ALTERNATE 41 -#define K_DB LAB|PROCESS|42 -#define K_DW LAB|PROCESS|43 -#define K_DL LAB|PROCESS|44 -#define K_LOCAL 45 - - -static struct -{ +/* What to do with all the keywords. */ +#define PROCESS 0x1000 /* Run substitution over the line. */ +#define LAB 0x2000 /* Spit out the label. */ + +#define K_EQU (PROCESS|1) +#define K_ASSIGN (PROCESS|2) +#define K_REG (PROCESS|3) +#define K_ORG (PROCESS|4) +#define K_RADIX (PROCESS|5) +#define K_DATA (LAB|PROCESS|6) +#define K_DATAB (LAB|PROCESS|7) +#define K_SDATA (LAB|PROCESS|8) +#define K_SDATAB (LAB|PROCESS|9) +#define K_SDATAC (LAB|PROCESS|10) +#define K_SDATAZ (LAB|PROCESS|11) +#define K_RES (LAB|PROCESS|12) +#define K_SRES (LAB|PROCESS|13) +#define K_SRESC (LAB|PROCESS|14) +#define K_SRESZ (LAB|PROCESS|15) +#define K_EXPORT (LAB|PROCESS|16) +#define K_GLOBAL (LAB|PROCESS|17) +#define K_PRINT (LAB|PROCESS|19) +#define K_FORM (LAB|PROCESS|20) +#define K_HEADING (LAB|PROCESS|21) +#define K_PAGE (LAB|PROCESS|22) +#define K_IMPORT (LAB|PROCESS|23) +#define K_PROGRAM (LAB|PROCESS|24) +#define K_END (PROCESS|25) +#define K_INCLUDE (PROCESS|26) +#define K_IGNORED (PROCESS|27) +#define K_ASSIGNA (PROCESS|28) +#define K_ASSIGNC (29) +#define K_AIF (PROCESS|30) +#define K_AELSE (PROCESS|31) +#define K_AENDI (PROCESS|32) +#define K_AREPEAT (PROCESS|33) +#define K_AENDR (PROCESS|34) +#define K_AWHILE (35) +#define K_AENDW (PROCESS|36) +#define K_EXITM (37) +#define K_MACRO (PROCESS|38) +#define K_ENDM (39) +#define K_ALIGN (PROCESS|LAB|40) +#define K_ALTERNATE (41) +#define K_DB (LAB|PROCESS|42) +#define K_DW (LAB|PROCESS|43) +#define K_DL (LAB|PROCESS|44) +#define K_LOCAL (45) +#define K_IFEQ (PROCESS|46) +#define K_IFNE (PROCESS|47) +#define K_IFLT (PROCESS|48) +#define K_IFLE (PROCESS|49) +#define K_IFGE (PROCESS|50) +#define K_IFGT (PROCESS|51) +#define K_IFC (PROCESS|52) +#define K_IFNC (PROCESS|53) +#define K_IRP (PROCESS|54) +#define K_IRPC (PROCESS|55) + +struct keyword { char *name; int code; int extra; -} -kinfo[] = -{ +}; + +static struct keyword kinfo[] = { { "EQU", K_EQU, 0 }, { "ALTERNATE", K_ALTERNATE, 0 }, { "ASSIGN", K_ASSIGN, 0 }, @@ -3538,8 +3119,31 @@ kinfo[] = { NULL, 0, 0 } }; +/* Although the conditional operators are handled by gas, we need to + handle them here as well, in case they are used in a recursive + macro to end the recursion. */ + +static struct keyword mrikinfo[] = { + { "IFEQ", K_IFEQ, 0 }, + { "IFNE", K_IFNE, 0 }, + { "IFLT", K_IFLT, 0 }, + { "IFLE", K_IFLE, 0 }, + { "IFGE", K_IFGE, 0 }, + { "IFGT", K_IFGT, 0 }, + { "IFC", K_IFC, 0 }, + { "IFNC", K_IFNC, 0 }, + { "ELSEC", K_AELSE, 0 }, + { "ENDC", K_AENDI, 0 }, + { "MEXIT", K_EXITM, 0 }, + { "REPT", K_AREPEAT, 0 }, + { "IRP", K_IRP, 0 }, + { "IRPC", K_IRPC, 0 }, + { "ENDR", K_AENDR, 0 }, + { NULL, 0, 0 } +}; + /* Look for a pseudo op on the line. If one's there then call - its handler. */ + its handler. */ static int process_pseudo_op (idx, line, acc) @@ -3547,11 +3151,11 @@ process_pseudo_op (idx, line, acc) sb *line; sb *acc; { + int oidx = idx; - - if (line->ptr[idx] == '.' || alternate) + if (line->ptr[idx] == '.' || alternate || mri) { - /* Scan forward and find pseudo name */ + /* Scan forward and find pseudo name. */ char *in; hash_entry *ptr; @@ -3577,13 +3181,15 @@ process_pseudo_op (idx, line, acc) { #if 0 /* This one causes lots of pain when trying to preprocess - ordinary code */ - WARNING ((stderr, "Unrecognised pseudo op `%s'.\n", sb_name (acc))); + ordinary code. */ + WARNING ((stderr, _("Unrecognised pseudo op `%s'.\n"), + sb_name (acc))); #endif return 0; } if (ptr->value.i & LAB) - { /* output the label */ + { + /* Output the label. */ if (label.len) { fprintf (outfile, "%s:\t", sb_name (&label)); @@ -3592,15 +3198,25 @@ process_pseudo_op (idx, line, acc) fprintf (outfile, "\t"); } + if (mri && ptr->value.i == K_END) + { + sb t; + + sb_new (&t); + sb_add_buffer (&t, line->ptr + oidx, idx - oidx); + fprintf (outfile, "\t%s", sb_name (&t)); + sb_kill (&t); + } + if (ptr->value.i & PROCESS) { - /* Polish the rest of the line before handling the pseudo op */ + /* Polish the rest of the line before handling the pseudo op. */ #if 0 - strip_comments(line); + strip_comments (line); #endif sb_reset (acc); process_assigns (idx, line, acc); - sb_reset(line); + sb_reset (line); change_base (0, acc, line); idx = 0; } @@ -3626,6 +3242,7 @@ process_pseudo_op (idx, line, acc) { case K_ALTERNATE: alternate = 1; + macro_init (1, mri, 0, exp_get_abs); return 1; case K_AELSE: do_aelse (); @@ -3634,7 +3251,7 @@ process_pseudo_op (idx, line, acc) do_aendi (); return 1; case K_ORG: - ERROR ((stderr, "ORG command not allowed.\n")); + ERROR ((stderr, _("ORG command not allowed.\n"))); break; case K_RADIX: do_radix (line); @@ -3667,7 +3284,7 @@ process_pseudo_op (idx, line, acc) do_sdata (idx, line, 'z'); return 1; case K_ASSIGN: - do_assign (1, 0, line); + do_assign (0, 0, line); return 1; case K_AIF: do_aif (idx, line); @@ -3685,7 +3302,7 @@ process_pseudo_op (idx, line, acc) do_aendr (); return 1; case K_EQU: - do_assign (0, idx, line); + do_assign (1, idx, line); return 1; case K_ALIGN: do_align (idx, line); @@ -3735,7 +3352,7 @@ process_pseudo_op (idx, line, acc) case K_IGNORED: return 1; case K_END: - do_end (); + do_end (line); return 1; case K_ASSIGNA: do_assigna (idx, line); @@ -3749,16 +3366,67 @@ process_pseudo_op (idx, line, acc) case K_REG: do_reg (idx, line); return 1; + case K_IFEQ: + do_if (idx, line, EQ); + return 1; + case K_IFNE: + do_if (idx, line, NE); + return 1; + case K_IFLT: + do_if (idx, line, LT); + return 1; + case K_IFLE: + do_if (idx, line, LE); + return 1; + case K_IFGE: + do_if (idx, line, GE); + return 1; + case K_IFGT: + do_if (idx, line, GT); + return 1; + case K_IFC: + do_ifc (idx, line, 0); + return 1; + case K_IFNC: + do_ifc (idx, line, 1); + return 1; + case K_IRP: + do_irp (idx, line, 0); + return 1; + case K_IRPC: + do_irp (idx, line, 1); + return 1; } } } return 0; } +/* Add a keyword to the hash table. */ + +static void +add_keyword (name, code) + const char *name; + int code; +{ + sb label; + int j; + + sb_new (&label); + sb_add_string (&label, name); + + hash_add_to_int_table (&keyword_hash_table, &label, code); + sb_reset (&label); + for (j = 0; name[j]; j++) + sb_add_char (&label, name[j] - 'A' + 'a'); + hash_add_to_int_table (&keyword_hash_table, &label, code); + + sb_kill (&label); +} /* Build the keyword hash table - put each keyword in the table twice, - once upper and once lower case.*/ + once upper and once lower case. */ static void process_init () @@ -3766,37 +3434,27 @@ process_init () int i; for (i = 0; kinfo[i].name; i++) - { - sb label; - int j; - sb_new (&label); - sb_add_string (&label, kinfo[i].name); - - hash_add_to_int_table (&keyword_hash_table, &label, kinfo[i].code); - - sb_reset (&label); - for (j = 0; kinfo[i].name[j]; j++) - sb_add_char (&label, kinfo[i].name[j] - 'A' + 'a'); - hash_add_to_int_table (&keyword_hash_table, &label, kinfo[i].code); + add_keyword (kinfo[i].name, kinfo[i].code); - sb_kill (&label); + if (mri) + { + for (i = 0; mrikinfo[i].name; i++) + add_keyword (mrikinfo[i].name, mrikinfo[i].code); } } - static void do_define (string) -char *string; + const char *string; { sb label; int res = 1; hash_entry *ptr; sb_new (&label); - while (*string) { - if (*string == '=') + if (*string == '=') { sb value; sb_new (&value); @@ -3806,13 +3464,14 @@ char *string; sb_add_char (&value, *string); string++; } - exp_get_abs ("Invalid expression on command line.\n", 0, &value, &res); + exp_get_abs (_("Invalid expression on command line.\n"), + 0, &value, &res); sb_kill (&value); break; } sb_add_char (&label, *string); - string ++; + string++; } ptr = hash_create (&vars, &label); @@ -3821,16 +3480,19 @@ char *string; ptr->value.i = res; sb_kill (&label); } + char *program_name; /* The list of long options. */ static struct option long_options[] = { { "alternate", no_argument, 0, 'a' }, + { "include", required_argument, 0, 'I' }, { "commentchar", required_argument, 0, 'c' }, { "copysource", no_argument, 0, 's' }, { "debug", no_argument, 0, 'd' }, { "help", no_argument, 0, 'h' }, + { "mri", no_argument, 0, 'M' }, { "output", required_argument, 0, 'o' }, { "print", no_argument, 0, 'p' }, { "unreasonable", no_argument, 0, 'u' }, @@ -3845,28 +3507,33 @@ show_usage (file, status) FILE *file; int status; { - fprintf (file, "\ + fprintf (file, _("\ Usage: %s \n\ [-a] [--alternate] enter alternate macro mode\n\ [-c char] [--commentchar char] change the comment character from !\n\ [-d] [--debug] print some debugging info\n\ [-h] [--help] print this message\n\ + [-M] [--mri] enter MRI compatibility mode\n\ [-o out] [--output out] set the output file\n\ - [-p] [--print] print line numbers\n\ + [-p] [--print] print line numbers\n"), program_name); + fprintf (file, _("\ [-s] [--copysource] copy source through as comments \n\ [-u] [--unreasonable] allow unreasonable nesting\n\ [-v] [--version] print the program version\n\ [-Dname=value] create preprocessor variable called name, with value\n\ - [in-file]\n", program_name); + [-Ipath] add to include path list\n\ + [in-file]\n")); + if (status == 0) + printf (_("Report bugs to %s\n"), REPORT_BUGS_TO); exit (status); } /* Display a help message and exit. */ + static void show_help () { - printf ("%s: Gnu Assembler Macro Preprocessor\n", - program_name); + printf (_("%s: Gnu Assembler Macro Preprocessor\n"), program_name); show_usage (stdout, 0); } @@ -3882,20 +3549,22 @@ main (argc, argv) ifstack[0].on = 1; ifi = 0; - +#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) + setlocale (LC_MESSAGES, ""); +#endif + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); program_name = argv[0]; xmalloc_set_program_name (program_name); - hash_new_table (101, ¯o_table); hash_new_table (101, &keyword_hash_table); hash_new_table (101, &assign_hash_table); hash_new_table (101, &vars); sb_new (&label); - process_init (); - while ((opt = getopt_long (argc, argv, "sdhavc:upo:D:", long_options, + while ((opt = getopt_long (argc, argv, "I:sdhavc:upo:D:M", long_options, (int *) NULL)) != EOF) { @@ -3907,6 +3576,19 @@ main (argc, argv) case 'u': unreasonable = 1; break; + case 'I': + { + include_path *p = (include_path *) xmalloc (sizeof (include_path)); + p->next = NULL; + sb_new (&p->path); + sb_add_string (&p->path, optarg); + if (paths_tail) + paths_tail->next = p; + else + paths_head = p; + paths_tail = p; + } + break; case 'p': print_line_number = 1; break; @@ -3925,40 +3607,54 @@ main (argc, argv) case 'D': do_define (optarg); break; + case 'M': + mri = 1; + comment_char = ';'; + break; case 'h': show_help (); - /*NOTREACHED*/ + /* NOTREACHED */ case 'v': - printf ("GNU %s version %s\n", program_name, program_version); + /* This output is intended to follow the GNU standards document. */ + printf (_("GNU assembler pre-processor %s\n"), program_version); + printf (_("Copyright 1996 Free Software Foundation, Inc.\n")); + printf (_("\ +This program is free software; you may redistribute it under the terms of\n\ +the GNU General Public License. This program has absolutely no warranty.\n")); exit (0); - /*NOTREACHED*/ + /* NOTREACHED */ case 0: break; default: show_usage (stderr, 1); - /*NOTREACHED*/ + /* NOTREACHED */ } } + process_init (); - if (out_name) { - outfile = fopen (out_name, "w"); - if (!outfile) - { - fprintf (stderr, "%s: Can't open output file `%s'.\n", - program_name, out_name); - exit (1); - } - } - else { - outfile = stdout; - } + macro_init (alternate, mri, 0, exp_get_abs); + + if (out_name) + { + outfile = fopen (out_name, "w"); + if (!outfile) + { + fprintf (stderr, _("%s: Can't open output file `%s'.\n"), + program_name, out_name); + exit (1); + } + } + else + { + outfile = stdout; + } chartype_init (); if (!outfile) outfile = stdout; - /* Process all the input files */ + /* Process all the input files. */ while (optind < argc) { @@ -3968,7 +3664,7 @@ main (argc, argv) } else { - fprintf (stderr, "%s: Can't open input file `%s'.\n", + fprintf (stderr, _("%s: Can't open input file `%s'.\n"), program_name, argv[optind]); exit (1); } @@ -3978,3 +3674,18 @@ main (argc, argv) quit (); return 0; } + +/* This function is used because an abort in some of the other files + may be compiled into as_abort because they include as.h. */ + +void +as_abort (file, line, fn) + const char *file, *fn; + int line; +{ + fprintf (stderr, _("Internal error, aborting at %s line %d"), file, line); + if (fn) + fprintf (stderr, " in %s", fn); + fprintf (stderr, _("\nPlease report this bug.\n")); + exit (1); +}