/* gasp.c - Gnu assembler preprocessor main program.
- Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+ Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
Written by Steve and Judy Chamberlain of Cygnus Support,
sac@cygnus.com
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. */
+ 02111-1307, USA. */
/*
-
This program translates the input macros and stuff into a form
suitable for gas to consume.
-
gasp [-sdhau] [-c char] [-o <outfile>] <infile>*
-s copy source to output
Macro arg parameters subsituted by name, don't need the &.
String can start with ' too.
Strings can be surrounded by <..>
- A %<exp> in a string evaluates the expression
+ A %<exp> in a string evaluates the expression
Literal char in a string with !
-
-
*/
#include "config.h"
+#include "bin-bugs.h"
+#include <assert.h>
#include <stdio.h>
#include <string.h>
-#include <getopt.h>
-#include <ctype.h>
+#include "getopt.h"
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#include "ansidecl.h"
#include "libiberty.h"
+#include "safe-ctype.h"
+#include "sb.h"
+#include "macro.h"
+#include "asintl.h"
+#include "xregex.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 */
-int mri = 0; /* -M 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;
-/* 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<<pot */
- struct le *item;
- }
-sb;
-
-/* Structure of the free list object of an sb */
-typedef struct le
- {
- struct le *next;
- int size;
- char data[1];
- }
-sb_element;
-
-/* The free list */
-typedef struct
- {
- sb_element *size[max_power_two];
- } sb_list_vector;
-
-sb_list_vector free_list;
-
-int string_count[max_power_two];
-
-/* the attributes of each character are stored as a bit pattern
- chartype, which gives us quick tests. */
-
+/* The attributes of each character are stored as a bit pattern
+ chartype, which gives us quick tests. */
#define FIRSTBIT 1
#define NEXTBIT 2
#define WHITEBIT 8
#define COMMENTBIT 16
#define BASEBIT 32
-#define ISCOMMENTCHAR(x) (chartype[(unsigned)(x)] & COMMENTBIT)
-#define ISFIRSTCHAR(x) (chartype[(unsigned)(x)] & FIRSTBIT)
-#define ISNEXTCHAR(x) (chartype[(unsigned)(x)] & NEXTBIT)
-#define ISSEP(x) (chartype[(unsigned)(x)] & SEPBIT)
-#define ISWHITE(x) (chartype[(unsigned)(x)] & WHITEBIT)
-#define ISBASE(x) (chartype[(unsigned)(x)] & BASEBIT)
+#define ISCOMMENTCHAR(x) (chartype[(unsigned char)(x)] & COMMENTBIT)
+#define ISFIRSTCHAR(x) (chartype[(unsigned char)(x)] & FIRSTBIT)
+#define ISNEXTCHAR(x) (chartype[(unsigned char)(x)] & NEXTBIT)
+#define ISSEP(x) (chartype[(unsigned char)(x)] & SEPBIT)
+#define ISWHITE(x) (chartype[(unsigned char)(x)] & WHITEBIT)
+#define ISBASE(x) (chartype[(unsigned char)(x)] & BASEBIT)
static char chartype[256];
-
/* Conditional assembly uses the `ifstack'. Each aif pushes another
entry onto the stack, and sets the on flag if it should. The aelse
sets hadelse, and toggles on. An aend pops a level. We limit to
a bug in the user's macro structure. */
#define IFNESTING 100
-struct
- {
- int on; /* is the level being output */
- int hadelse; /* has an aelse been seen */
- }
-ifstack[IFNESTING];
+struct {
+ int on; /* Is the level being output. */
+ int hadelse; /* Has an aelse been seen. */
+} ifstack[IFNESTING];
+
int ifi;
/* The final and intermediate results of expression evaluation are kept in
exp_t's. Note that a symbol is not an sb, but a pointer into the input
- line. It must be coped somewhere safe before the next line is read in. */
-
-typedef struct
- {
- char *name;
- int len;
- }
-symbol;
+ line. It must be coped somewhere safe before the next line is read in. */
-typedef struct
- {
- int value; /* constant part */
- symbol add_symbol; /* name part */
- symbol sub_symbol; /* name part */
- }
-exp_t;
+typedef struct {
+ char *name;
+ int len;
+} symbol;
+typedef struct {
+ int value; /* Constant part. */
+ symbol add_symbol; /* Name part. */
+ symbol sub_symbol; /* Name part. */
+} exp_t;
/* Hashing is done in a pretty standard way. A hash_table has a
pointer to a vector of pointers to hash_entrys, and the size of the
vector. A hash_entry contains a union of all the info we like to
store in hash table. If there is a hash collision, hash_entries
- 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;
-
-
-/* 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
-
+/* Include file list. */
-
-/* Include file list */
-
-typedef struct include_path
-{
+typedef struct include_path {
struct include_path *next;
sb path;
-} include_path;
+} include_path;
include_path *paths_head;
include_path *paths_tail;
-
static void quit PARAMS ((void));
-static void sb_build PARAMS ((sb *, int));
-static void sb_new PARAMS ((sb *));
-static void sb_kill PARAMS ((sb *));
-static void sb_add_sb PARAMS ((sb *, sb *));
-static void sb_check PARAMS ((sb *, int));
-static void sb_reset PARAMS ((sb *));
-static void sb_add_char PARAMS ((sb *, int));
-static void sb_add_string PARAMS ((sb *, const char *));
-static void sb_add_buffer PARAMS ((sb *, const char *, int));
-static void sb_print PARAMS ((sb *));
-static void sb_print_at PARAMS ((int, sb *));
-static char *sb_name PARAMS ((sb *));
-static int sb_skip_white PARAMS ((int, sb *));
-static int sb_skip_comma PARAMS ((int, sb *));
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_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 is_flonum PARAMS ((int, sb *));
+static int chew_flonum PARAMS ((int, sb *, sb *));
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 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 buffer_and_nest PARAMS ((const char *, const char *, sb *));
static void do_aendr PARAMS ((void));
static void do_awhile PARAMS ((int, sb *));
static void do_aendw PARAMS ((void));
static void do_arepeat PARAMS ((int, sb *));
static void do_endm PARAMS ((void));
static void do_irp PARAMS ((int, sb *, int));
-static int do_formals PARAMS ((macro_entry *, int, sb *));
static void do_local PARAMS ((int, sb *));
static void do_macro PARAMS ((int, sb *));
-static int get_token PARAMS ((int, sb *, sb *));
-static int get_apost_token PARAMS ((int, sb *, sb *, int));
-static int sub_actual
- PARAMS ((int, sb *, sb *, hash_table *, int, sb *, int));
-static void macro_expand_body
- PARAMS ((sb *, sb *, sb *, formal_entry *, hash_table *));
-static void macro_expand PARAMS ((sb *, int, sb *, macro_entry *));
static int macro_op PARAMS ((int, sb *));
static int getstring PARAMS ((int, sb *, sb *));
static void do_sdata PARAMS ((int, sb *, int));
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)
+#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. */
static void
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<<i, string_count[i]);
+ fprintf (stderr, "strings size %8d : %d\n",
+ 1 << i, string_count[i]);
}
}
exit (exitcode);
}
+/* Hash table maintenance. */
-/* this program is about manipulating strings.
- they are managed in things called `sb's which is an abbreviation
- for string buffers. an sb has to be created, things can be glued
- on to it, and at the end of it's life it should be freed. the
- contents should never be pointed at whilst it is still growing,
- since it could be moved at any time
-
- eg:
- sb_new (&foo);
- sb_grow... (&foo,...);
- use foo->ptr[*];
- sb_kill (&foo);
-
-*/
-
-/* initializes an sb. */
-
-static 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. */
-
-static void
-sb_add_char (ptr, c)
- sb *ptr;
- int 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;
- const 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;
- const 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)
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)
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;
}
}
-/* 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;
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;
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;
return 0;
}
-
/* expressions
are handled in a really simple recursive decent way. each bit of
+ -
&
| ~
-
*/
+/* 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)
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. */
+/* Chew the flonum from the string starting at idx. Adjust idx to
+ point to the next character after the flonum. */
-static
-int
+static int
+chew_flonum (idx, string, out)
+ int idx;
+ sb *string;
+ sb *out;
+{
+ sb buf;
+ regex_t reg;
+ regmatch_t match;
+
+ /* Duplicate and null terminate `string'. */
+ sb_new (&buf);
+ sb_add_sb (&buf, string);
+ sb_add_char (&buf, '\0');
+
+ if (regcomp (®, "([0-9]*\\.[0-9]+([eE][+-]?[0-9]+)?)", REG_EXTENDED) != 0)
+ return idx;
+ if (regexec (®, &buf.ptr[idx], 1, &match, 0) != 0)
+ return idx;
+
+ /* Copy the match to the output. */
+ assert (match.rm_eo >= match.rm_so);
+ sb_add_buffer (out, &buf.ptr[idx], match.rm_eo - match.rm_so);
+
+ sb_kill (&buf);
+ regfree (®);
+ idx += match.rm_eo;
+ return idx;
+}
+
+static int
+is_flonum (idx, string)
+ int idx;
+ sb *string;
+{
+ sb buf;
+ regex_t reg;
+ int rc;
+
+ /* Duplicate and null terminate `string'. */
+ sb_new (&buf);
+ sb_add_sb (&buf, string);
+ sb_add_char (&buf, '\0');
+
+ if (regcomp (®, "^[0-9]*\\.[0-9]+([eE][+-]?[0-9]+)?", REG_EXTENDED) != 0)
+ return 0;
+
+ rc = regexec (®, &buf.ptr[idx], 0, NULL, 0);
+ sb_kill (&buf);
+ regfree (®);
+ return (rc == 0);
+}
+
+/* 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
sb_strtol (idx, string, base, ptr)
int idx;
sb *string;
{
int ch = string->ptr[idx];
int dig = 0;
- if (isdigit (ch))
+ if (ISDIGIT (ch))
dig = ch - '0';
else if (ch >= 'a' && ch <= 'f')
dig = ch - 'a' + 10;
lhs->value = 0;
- if (isdigit (string->ptr[idx]))
+ if (ISDIGIT (string->ptr[idx]))
{
idx = sb_strtol (idx, string, 10, &lhs->value);
}
{
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;
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;
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;
return sb_skip_white (idx, string);
}
-
static int
level_3 (idx, string, lhs)
int idx;
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;
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)
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)
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)
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;
-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 all assigned variables. */
+hash_table assign_hash_table;
+
+/* Hash table for keyword. */
+hash_table keyword_hash_table;
+
+/* Hash table for eq variables. */
+hash_table vars;
#define in_comment ';'
int i = 0;
for (i = 0; i < out->len; i++)
{
- if (ISCOMMENTCHAR(s[i]))
+ if (ISCOMMENTCHAR (s[i]))
{
out->len = i;
return;
}
#endif
-/* push back character ch so that it can be read again. */
+/* Push back character ch so that it can be read again. */
static void
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;
{
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;
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;
{
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;
}
}
-
-/* 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)
{
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';
online = 0;
if (ch == '+')
{
- /* continued line */
+ /* Continued line. */
if (copysource)
{
putc (comment_char, outfile);
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)
{
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]);
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)
while (idx < in->len)
{
- if (idx < in->len - 1 && in->ptr[idx + 1] == '\'' && ! mri)
+ 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;
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;
}
}
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]))
idx++;
}
}
- else if (isdigit (in->ptr[idx]))
+ else if (is_flonum (idx, in))
+ {
+ idx = chew_flonum (idx, in, out);
+ }
+ else if (ISDIGIT (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]);
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)
}
else
{
- /* nothing special, just pass it through */
+ /* Nothing special, just pass it through. */
sb_add_char (out, in->ptr[idx]);
idx++;
}
}
-/* .end */
+/* .end */
+
static void
do_end (in)
sb *in;
fprintf (outfile, "%s\n", sb_name (in));
}
-/* .assign */
+/* .assign */
static void
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;
sb_kill (&acc);
}
+/* .radix [b|q|d|h] */
-/* .radix [b|q|d|h] */
-
-static
-void
+static void
do_radix (ptr)
sb *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)
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++;
return idx;
}
-static
-int eol(idx, 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)
return 0;
}
-/* .data [.b|.w|.l] <data>*
- or d[bwl] <data>* */
+/* .data [.b|.w|.l] <data>*
+ or d[bwl] <data>* */
static void
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:
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;
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))
{
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, ",");
}
}
sb_kill (&acc);
- sb_print_at (idx, in);
+ sb_print_at (outfile, idx, in);
fprintf (outfile, "\n");
}
-/* .datab [.b|.w|.l] <repeat>,<fill> */
+/* .datab [.b|.w|.l] <repeat>,<fill> */
static void
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 <size> */
+/* .align <size> */
-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] <size> */
+/* .res[.b|.w|.l] <size> */
static void
do_res (idx, in, type)
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++;
}
}
-
-/* .export */
+/* .export */
static void
do_export (in)
fprintf (outfile, ".global %s\n", sb_name (in));
}
-/* .print [list] [nolist] */
+/* .print [list] [nolist] */
static void
do_print (idx, in)
}
}
-/* .head */
+/* .head */
+
static void
do_heading (idx, in)
int idx;
sb_kill (&head);
}
-/* .page */
+/* .page */
static void
do_page ()
fprintf (outfile, ".eject\n");
}
-/* .form [lin=<value>] [col=<value>] */
+/* .form [lin=<value>] [col=<value>] */
+
static void
do_form (idx, in)
int idx;
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++;
}
-
/* Fetch string from the input stream,
rules:
'Bxyx<whitespace> -> return 'Bxyza
"<string>" -> return string
xyx<whitespace> -> return xyz
*/
-int
+
+static int
get_any_string (idx, in, out, expand, pretend_quoted)
int idx;
sb *in;
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++]);
{
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. */
+ /* xgettext: no-c-format */
+ 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] == '"'
{
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++]);
}
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. */
static int
skip_openp (idx, 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. */
static int
skip_closep (idx, 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 */
static int
dolen (idx, in, out)
return idx;
}
+/* .instr */
-/* .instr */
-
-static
-int
+static int
doinstr (idx, in, out)
int idx;
sb *in;
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 (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
{
return idx;
}
-
static int
dosubstr (idx, in, out)
int idx;
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)
}
sb_add_char (out, '"');
}
- sb_kill(&string);
+ sb_kill (&string);
return idx;
}
-/* scan line, change tokens in the hash table to their replacements */
+/* Scan line, change tokens in the hash table to their replacements. */
+
static void
process_assigns (idx, in, buf)
int idx;
{
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);
}
else if (idx + 3 < in->len
&& in->ptr[idx] == '.'
- && toupper ((unsigned char) in->ptr[idx + 1]) == 'L'
- && toupper ((unsigned char) in->ptr[idx + 2]) == 'E'
- && toupper ((unsigned char) in->ptr[idx + 3]) == 'N')
+ && TOUPPER (in->ptr[idx + 1]) == 'L'
+ && TOUPPER (in->ptr[idx + 2]) == 'E'
+ && TOUPPER (in->ptr[idx + 3]) == 'N')
idx = dolen (idx + 4, in, buf);
else if (idx + 6 < in->len
&& in->ptr[idx] == '.'
- && toupper ((unsigned char) in->ptr[idx + 1]) == 'I'
- && toupper ((unsigned char) in->ptr[idx + 2]) == 'N'
- && toupper ((unsigned char) in->ptr[idx + 3]) == 'S'
- && toupper ((unsigned char) in->ptr[idx + 4]) == 'T'
- && toupper ((unsigned char) in->ptr[idx + 5]) == 'R')
+ && TOUPPER (in->ptr[idx + 1]) == 'I'
+ && TOUPPER (in->ptr[idx + 2]) == 'N'
+ && TOUPPER (in->ptr[idx + 3]) == 'S'
+ && TOUPPER (in->ptr[idx + 4]) == 'T'
+ && TOUPPER (in->ptr[idx + 5]) == 'R')
idx = doinstr (idx + 6, in, buf);
else if (idx + 7 < in->len
&& in->ptr[idx] == '.'
- && toupper ((unsigned char) in->ptr[idx + 1]) == 'S'
- && toupper ((unsigned char) in->ptr[idx + 2]) == 'U'
- && toupper ((unsigned char) in->ptr[idx + 3]) == 'B'
- && toupper ((unsigned char) in->ptr[idx + 4]) == 'S'
- && toupper ((unsigned char) in->ptr[idx + 5]) == 'T'
- && toupper ((unsigned char) in->ptr[idx + 6]) == 'R')
+ && TOUPPER (in->ptr[idx + 1]) == 'S'
+ && TOUPPER (in->ptr[idx + 2]) == 'U'
+ && TOUPPER (in->ptr[idx + 3]) == 'B'
+ && TOUPPER (in->ptr[idx + 4]) == 'S'
+ && TOUPPER (in->ptr[idx + 5]) == 'T'
+ && TOUPPER (in->ptr[idx + 6]) == 'R')
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
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);
return idx;
}
-static
-void
+static void
process_file ()
{
sb line;
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 ())
if (macro_op (l, &line))
{
-
}
else
{
}
else
fprintf (outfile, "\t");
- sb_reset(&t1);
+ sb_reset (&t1);
process_assigns (l, &line, &t1);
sb_reset (&t2);
change_base (0, &t1, &t2);
}
}
}
- 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)
}
if (!had_end && !mri)
- WARNING ((stderr, "END missing from end of file.\n"));
+ WARNING ((stderr, _("END missing from end of file.\n")));
}
-
-
-
-
static void
free_old_entry (ptr)
hash_entry *ptr;
if (ptr)
{
if (ptr->type == hash_string)
- sb_kill(&ptr->value.s);
+ sb_kill (&ptr->value.s);
}
}
-/* name: .ASSIGNA <value> */
+/* name: .ASSIGNA <value> */
-void
+static void
do_assigna (idx, in)
int idx;
sb *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
{
sb_kill (&tmp);
}
-/* name: .ASSIGNC <string> */
+/* name: .ASSIGNC <string> */
-void
+static void
do_assignc (idx, in)
int idx;
sb *in;
if (!label.len)
{
- ERROR ((stderr, ".ASSIGNS without label.\n"));
+ ERROR ((stderr, _(".ASSIGNS without label.\n")));
}
else
{
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++;
sb_kill (&what);
}
-
static int
condass_lookup_name (inbuf, idx, out, warn)
sb *inbuf;
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");
}
char a, b;
p = in->ptr + idx;
- a = toupper ((unsigned char) p[0]);
- b = toupper ((unsigned char) p[1]);
+ a = TOUPPER (p[0]);
+ b = TOUPPER (p[1]);
if (a == 'E' && b == 'Q')
cond = EQ;
else if (a == 'N' && b == 'E')
}
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);
{
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:
return res;
}
-/* .AIF */
+/* .AIF */
+
static void
do_aif (idx, in)
int idx;
{
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 ()
{
}
else
{
- ERROR ((stderr, "AENDI without AIF.\n"));
+ ERROR ((stderr, _("AENDI without AIF.\n")));
}
}
if (ifi >= IFNESTING)
{
- FATAL ((stderr, "IF nesting unreasonable.\n"));
+ FATAL ((stderr, _("IF nesting unreasonable.\n")));
}
- idx = exp_get_abs ("Conditional operator must have absolute operands.\n",
+ idx = exp_get_abs (_("Conditional operator must have absolute operands.\n"),
idx, in, &val);
switch (cond)
{
}
ifi++;
- ifstack[ifi].on = ifstack[ifi-1].on ? res: 0;
+ ifstack[ifi].on = ifstack[ifi - 1].on ? res : 0;
ifstack[ifi].hadelse = 0;
}
return idx;
}
-/* MRI IFC, IFNC. */
+/* MRI IFC, IFNC */
static void
do_ifc (idx, in, ifnc)
if (ifi >= IFNESTING)
{
- FATAL ((stderr, "IF nesting unreasonable.\n"));
+ FATAL ((stderr, _("IF nesting unreasonable.\n")));
}
sb_new (&first);
if (idx >= in->len || in->ptr[idx] != ',')
{
- ERROR ((stderr, "Bad format for IF or IFNC.\n"));
+ ERROR ((stderr, _("Bad format for IF or IFNC.\n")));
return;
}
res ^= ifnc;
ifi++;
- ifstack[ifi].on = ifstack[ifi-1].on ? res : 0;
+ ifstack[ifi].on = ifstack[ifi - 1].on ? res : 0;
ifstack[ifi].hadelse = 0;
}
-/* 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. */
-
-static void
-buffer_and_nest (from, to, ptr)
- const char *from;
- const char *to;
- sb *ptr;
-{
- 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);
-
- while (more)
- {
- /* Try and find the first pseudo op on the line */
- int i = line_start;
-
- if (!alternate && !mri)
- {
- /* 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 */
-
- /* Skip leading whitespace */
- while (i < ptr->len
- && ISWHITE (ptr->ptr[i]))
- i++;
-
- /* Skip over a label */
- while (i < ptr->len
- && ISNEXTCHAR (ptr->ptr[i]))
- i++;
-
- /* And a colon */
- if (i < ptr->len
- && ptr->ptr[i] == ':')
- i++;
-
- }
- /* Skip trailing whitespace */
- while (i < ptr->len
- && ISWHITE (ptr->ptr[i]))
- i++;
-
- if (i < ptr->len && (ptr->ptr[i] == '.'
- || alternate
- || mri))
- {
- if (ptr->ptr[i] == '.')
- i++;
- if (strncasecmp (ptr->ptr + i, from, from_len) == 0)
- depth++;
- if (strncasecmp (ptr->ptr + i, to, to_len) == 0)
- {
- depth--;
- if (depth == 0)
- {
- /* Reset the string to not include the ending rune */
- ptr->len = line_start;
- break;
- }
- }
- }
-
- /* Add a CR to the end and keep running */
- sb_add_char (ptr, '\n');
- line_start = ptr->len;
- more = get_line (ptr);
- }
-
-
- if (depth)
- FATAL ((stderr, "End of file whilst inside %s, started on line %d.\n", from, line));
-}
-
+/* .ENDR */
-/* .ENDR */
static void
do_aendr ()
{
if (!mri)
- ERROR ((stderr, "AENDR without a AREPEAT.\n"));
+ ERROR ((stderr, _("AENDR without a AREPEAT.\n")));
else
- ERROR ((stderr, "ENDR without a REPT.\n"));
+ 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
.AWHILE exp
foo
.ENDW
- */
+ */
if (doit)
{
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 (©);
}
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 ()
}
}
-/* .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);
+ idx = exp_get_abs (_("AREPEAT must have absolute operand.\n"), 0, &exp, &rc);
if (!mri)
- buffer_and_nest ("AREPEAT", "AENDR", &sub);
+ ret = buffer_and_nest ("AREPEAT", "AENDR", &sub, get_line);
else
- buffer_and_nest ("REPT", "ENDR", &sub);
+ 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
.AREPEAT 19
foo
.AENDR
- */
+ */
int index = include_next_index ();
sb_add_sb (©, &sub);
if (rc > 1)
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. */
sb *in;
int irpc;
{
- const char *mn;
- sb sub;
- formal_entry f;
- hash_table h;
- hash_entry *p;
- sb name;
+ const char *err;
sb out;
- if (irpc)
- mn = "IRPC";
- else
- mn = "IRP";
-
- idx = sb_skip_white (idx, in);
-
- sb_new (&sub);
- buffer_and_nest (mn, "ENDR", &sub);
-
- sb_new (&f.name);
- sb_new (&f.def);
- sb_new (&f.actual);
-
- idx = get_token (idx, in, &f.name);
- if (f.name.len == 0)
- {
- ERROR ((stderr, "Missing model parameter in %s", mn));
- return;
- }
-
- hash_new_table (1, &h);
- p = hash_create (&h, &f.name);
- p->type = hash_formal;
- p->value.f = &f;
-
- f.index = 1;
- f.next = NULL;
-
- sb_new (&name);
- sb_add_string (&name, mn);
-
sb_new (&out);
- idx = sb_skip_comma (idx, in);
- if (eol (idx, in))
- {
- /* Expand once with a null string. */
- macro_expand_body (&name, &sub, &out, &f, &h);
- fprintf (outfile, "%s", sb_name (&out));
- }
- else
- {
- while (!eol (idx, in))
- {
- if (!irpc)
- idx = get_any_string (idx, in, &f.actual, 1, 0);
- else
- {
- sb_reset (&f.actual);
- sb_add_char (&f.actual, in->ptr[idx]);
- ++idx;
- }
- sb_reset (&out);
- macro_expand_body (&name, &sub, &out, &f, &h);
- fprintf (outfile, "%s", sb_name (&out));
- if (!irpc)
- idx = sb_skip_comma (idx, in);
- else
- idx = sb_skip_white (idx, in);
- }
- }
+ err = expand_irp (irpc, idx, in, &out, get_line, comment_char);
+ if (err != NULL)
+ ERROR ((stderr, "%s\n", err));
+
+ fprintf (outfile, "%s", sb_terminate (&out));
- sb_kill (&sub);
- sb_kill (&name);
sb_kill (&out);
}
-/* MACRO PROCESSING */
-
-static int number;
-hash_table macro_table;
-
-/* Understand
-
- .MACRO <name>
- stuff
- .ENDM
-*/
-
-static int
-do_formals (macro, idx, in)
- macro_entry *macro;
- int idx;
- sb *in;
-{
- formal_entry **p = ¯o->formals;
- macro->formal_count = 0;
- hash_new_table (5, ¯o->formal_hash);
- while (idx < in->len)
- {
- formal_entry *formal;
-
- formal = (formal_entry *) xmalloc (sizeof (formal_entry));
-
- sb_new (&formal->name);
- sb_new (&formal->def);
- sb_new (&formal->actual);
-
- 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);
- }
- }
-
- {
- /* Add to macro's hash table */
-
- hash_entry *p = hash_create (¯o->formal_hash, &formal->name);
- p->type = hash_formal;
- p->value.f = formal;
- }
-
- formal->index = macro->formal_count;
- idx = sb_skip_comma (idx, in);
- macro->formal_count++;
- *p = formal;
- p = &formal->next;
- *p = NULL;
- }
-
- if (mri)
- {
- formal_entry *formal;
-
- /* Add a special NARG formal, which macro_expand will set to the
- number of arguments. */
- formal = (formal_entry *) xmalloc (sizeof (formal_entry));
-
- sb_new (&formal->name);
- sb_new (&formal->def);
- sb_new (&formal->actual);
-
- sb_add_string (&formal->name, "NARG");
-
- {
- /* Add to macro's hash table */
-
- hash_entry *p = hash_create (¯o->formal_hash, &formal->name);
- p->type = hash_formal;
- p->value.f = formal;
- }
+/* Macro processing. */
- formal->index = -2;
- *p = formal;
- formal->next = NULL;
- }
-
- 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, formal_hash, kind, out, copyifnotthere)
- int src;
- sb *in;
- sb *t;
- hash_table *formal_hash;
- 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 (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;
-}
-
-/* Copy the body from the macro buffer into a safe place and
- substitute any args. */
-
-static void
-macro_expand_body (name, in, out, formals, formal_hash)
- sb *name;
- sb *in;
- sb *out;
- formal_entry *formals;
- hash_table *formal_hash;
-{
- sb t;
- int src = 0;
- int inquote = 0;
-
- sb_new (&t);
-
- while (src < in->len)
- {
- if (in->ptr[src] == '&')
- {
- sb_reset (&t);
- if (mri && src + 1 < in->len && in->ptr[src + 1] == '&')
- {
- src = sub_actual (src + 2, in, &t, formal_hash, '\'', out, 1);
- }
- else
- {
- src = sub_actual (src + 1, in, &t, formal_hash, '&', 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 if (mri
- && isalnum ((unsigned char) in->ptr[src]))
- {
- int ind;
- formal_entry *f;
-
- if (isdigit ((unsigned char) in->ptr[src]))
- ind = in->ptr[src] - '0';
- else if (isupper ((unsigned char) in->ptr[src]))
- ind = in->ptr[src] - 'A' + 10;
- else
- ind = in->ptr[src] - 'a' + 10;
- ++src;
- for (f = formals; f != NULL; f = f->next)
- {
- if (f->index == ind - 1)
- {
- if (f->actual.len != 0)
- sb_add_sb (out, &f->actual);
- else
- sb_add_sb (out, &f->def);
- break;
- }
- }
- }
- else
- {
- sb_reset (&t);
- src = sub_actual (src, in, &t, formal_hash, '\'', out, 0);
- }
- }
- else if (ISFIRSTCHAR (in->ptr[src]) && (alternate || mri))
- {
- sb_reset (&t);
- src = sub_actual (src, in, &t, formal_hash, '\'', 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] == '"'
- || (mri && in->ptr[src] == '\''))
- {
- inquote = !inquote;
- sb_add_char (out, in->ptr[src++]);
- }
- else if (mri
- && in->ptr[src] == '='
- && src + 1 < in->len
- && in->ptr[src + 1] == '=')
- {
- hash_entry *ptr;
-
- sb_reset (&t);
- src = get_token (src + 2, in, &t);
- ptr = hash_lookup (formal_hash, &t);
- if (ptr == NULL)
- {
- ERROR ((stderr, "MACRO formal argument %s does not exist.\n",
- sb_name (&t)));
- }
- else
- {
- if (ptr->value.f->actual.len)
- {
- sb_add_string (out, "-1");
- }
- else
- {
- sb_add_char (out, '0');
- }
- }
- }
- else
- {
- sb_add_char (out, in->ptr[src++]);
- }
- }
-
- sb_kill (&t);
-}
-
-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;
- int narg = 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;
-
- if (mri)
- {
- /* The macro may be called with an optional qualifier, which may
- be referred to in the macro body as \0. */
- if (idx < in->len && in->ptr[idx] == '.')
- {
- formal_entry *n;
-
- n = (formal_entry *) xmalloc (sizeof (formal_entry));
- sb_new (&n->name);
- sb_new (&n->def);
- sb_new (&n->actual);
- n->index = -1;
-
- n->next = m->formals;
- m->formals = n;
-
- idx = get_any_string (idx + 1, in, &n->actual, 1, 0);
- }
- }
-
- /* 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);
- if (ptr->value.f->actual.len > 0)
- ++narg;
- }
- }
- 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)
- {
- formal_entry **pf;
- int c;
-
- if (!mri)
- {
- ERROR ((stderr, "Too many positional arguments.\n"));
- return;
- }
- f = (formal_entry *) xmalloc (sizeof (formal_entry));
- sb_new (&f->name);
- sb_new (&f->def);
- sb_new (&f->actual);
- f->next = NULL;
-
- c = -1;
- for (pf = &m->formals; *pf != NULL; pf = &(*pf)->next)
- if ((*pf)->index >= c)
- c = (*pf)->index + 1;
- *pf = f;
- f->index = c;
- }
-
- sb_reset (&f->actual);
- idx = get_any_string (idx, in, &f->actual, 1, 0);
- if (f->actual.len > 0)
- ++narg;
- do
- {
- f = f->next;
- }
- while (f != NULL && f->index < 0);
- }
-
- idx = sb_skip_comma (idx, in);
- }
+ sb name;
- if (mri)
- {
- char buffer[20];
-
- sb_reset (&t);
- sb_add_string (&t, "NARG");
- ptr = hash_lookup (&m->formal_hash, &t);
- sb_reset (&ptr->value.f->actual);
- sprintf (buffer, "%d", narg);
- sb_add_string (&ptr->value.f->actual, buffer);
- }
+ if (! macro_defined)
+ return 0;
- macro_expand_body (name, &m->sub, &out, m->formals, &m->formal_hash);
+ sb_terminate (in);
+ if (! check_macro (in->ptr + idx, &out, comment_char, &err, NULL))
+ return 0;
- include_buf (name, &out, include_macro, include_next_index ());
+ if (err != NULL)
+ ERROR ((stderr, "%s\n", err));
- if (mri)
- {
- formal_entry **pf;
+ sb_new (&name);
+ sb_add_string (&name, _("macro expansion"));
- /* Discard any unnamed formal arguments. */
- pf = &m->formals;
- while (*pf != NULL)
- {
- if ((*pf)->name.len != 0)
- pf = &(*pf)->next;
- else
- {
- sb_kill (&(*pf)->name);
- sb_kill (&(*pf)->def);
- sb_kill (&(*pf)->actual);
- f = (*pf)->next;
- free (*pf);
- *pf = f;
- }
- }
- }
+ include_buf (&name, &out, include_macro, include_next_index ());
- sb_kill (&t);
+ sb_kill (&name);
sb_kill (&out);
- number++;
-}
-
-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);
-
- if (name.len)
- {
- /* Got a name, look it up */
-
- ptr = hash_lookup (¯o_table, &name);
-
- 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);
- }
-
- return res;
+ return 1;
}
-
-/* STRING HANDLING */
+/* String handling. */
static int
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 (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] == '\'')
{
{
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] <string> */
+/* .SDATA[C|Z] <string> */
-static
-void
+static void
do_sdata (idx, in, type)
int idx;
sb *in;
{
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;
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++;
fprintf (outfile, "\n");
}
-/* .SDATAB <count> <string> */
+/* .SDATAB <count> <string> */
static void
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;
}
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)
const char *name;
{
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;
{
sb t;
sb cat;
- char *text;
include_path *includes;
+
sb_new (&t);
sb_new (&cat);
- idx = getstring (idx, in, &t);
+ 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)
{
}
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);
/* 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 ()
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;
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 ()
int x;
for (x = 0; x < 256; x++)
{
- if (isalpha (x) || x == '_' || x == '$')
+ if (ISALPHA (x) || x == '_' || x == '$')
chartype[x] |= FIRSTBIT;
- if (isdigit (x) || isalpha (x) || x == '_' || x == '$')
+ if (mri && x == '.')
+ chartype[x] |= FIRSTBIT;
+
+ if (ISDIGIT (x) || ISALPHA (x) || x == '_' || x == '$')
chartype[x] |= NEXTBIT;
if (x == ' ' || x == '\t' || x == ',' || x == '"' || x == ';'
|| x == 'h' || x == 'H'
|| x == 'd' || x == 'D')
chartype [x] |= BASEBIT;
-
+
if (x == ' ' || x == '\t')
chartype[x] |= WHITEBIT;
}
}
-
-
-/* What to do with all the keywords */
-#define PROCESS 0x1000 /* Run substitution over the line */
-#define LAB 0x2000 /* Spit out the label */
+/* 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_IRP (PROCESS|54)
#define K_IRPC (PROCESS|55)
-
-struct keyword
-{
+struct keyword {
char *name;
int code;
int extra;
};
-static struct keyword kinfo[] =
-{
+static struct keyword kinfo[] = {
{ "EQU", K_EQU, 0 },
{ "ALTERNATE", K_ALTERNATE, 0 },
{ "ASSIGN", K_ASSIGN, 0 },
handle them here as well, in case they are used in a recursive
macro to end the recursion. */
-static struct keyword mrikinfo[] =
-{
- { "IF", K_IFNE, 0 },
+static struct keyword mrikinfo[] = {
{ "IFEQ", K_IFEQ, 0 },
{ "IFNE", K_IFNE, 0 },
{ "IFLT", K_IFLT, 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)
if (line->ptr[idx] == '.' || alternate || mri)
{
- /* Scan forward and find pseudo name */
+ /* Scan forward and find pseudo name. */
char *in;
hash_entry *ptr;
{
#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));
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;
}
{
case K_ALTERNATE:
alternate = 1;
+ macro_init (1, mri, 0, exp_get_abs);
return 1;
case K_AELSE:
do_aelse ();
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);
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);
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);
return 0;
}
-
-
/* Add a keyword to the hash table. */
static void
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 ()
}
}
-
static void
do_define (string)
const char *string;
hash_entry *ptr;
sb_new (&label);
-
while (*string)
{
- if (*string == '=')
+ if (*string == '=')
{
sb value;
sb_new (&value);
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);
ptr->value.i = res;
sb_kill (&label);
}
+
char *program_name;
/* The list of long options. */
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\
[-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\
[-Ipath] add to include path list\n\
- [in-file]\n", program_name);
+ [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);
}
+int main PARAMS ((int, char **));
+
int
main (argc, argv)
int argc;
ifstack[0].on = 1;
ifi = 0;
-
+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
+ setlocale (LC_MESSAGES, "");
+#endif
+#if defined (HAVE_SETLOCALE)
+ setlocale (LC_CTYPE, "");
+#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);
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)
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)
{
}
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);
}
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);
+}