1 /* gasp.c - Gnu assembler preprocessor main program.
2 Copyright (C) 1994, 95, 96, 97, 1998 Free Software Foundation, Inc.
4 Written by Steve and Judy Chamberlain of Cygnus Support,
7 This file is part of GASP, the GNU Assembler Preprocessor.
9 GASP is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
14 GASP is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GASP; see the file COPYING. If not, write to the Free
21 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
26 This program translates the input macros and stuff into a form
27 suitable for gas to consume.
30 gasp [-sdhau] [-c char] [-o <outfile>] <infile>*
32 -s copy source to output
33 -c <char> comments are started with <char> instead of !
34 -u allow unreasonable stuff
36 -d print debugging stats
37 -s semi colons start comments
38 -a use alternate syntax
39 Pseudo ops can start with or without a .
40 Labels have to be in first column.
41 -I specify include dir
42 Macro arg parameters subsituted by name, don't need the &.
43 String can start with ' too.
44 Strings can be surrounded by <..>
45 A %<exp> in a string evaluates the expression
46 Literal char in a string with !
62 #ifdef NEED_MALLOC_DECLARATION
63 extern char *malloc ();
67 #include "libiberty.h"
72 char *program_version = "1.2";
74 /* This is normally declared in as.h, but we don't include that. We
75 need the function because other files linked with gasp.c might call
77 extern void as_abort PARAMS ((const char *, int, const char *));
79 #define MAX_INCLUDES 30 /* Maximum include depth */
80 #define MAX_REASONABLE 1000 /* Maximum number of expansions */
82 int unreasonable; /* -u on command line */
83 int stats; /* -d on command line */
84 int print_line_number; /* -p flag on command line */
85 int copysource; /* -c flag on command line */
86 int warnings; /* Number of WARNINGs generated so far. */
87 int errors; /* Number of ERRORs generated so far. */
88 int fatals; /* Number of fatal ERRORs generated so far (either 0 or 1). */
89 int alternate = 0; /* -a on command line */
90 int mri = 0; /* -M on command line */
91 char comment_char = '!';
92 int radix = 10; /* Default radix */
94 int had_end; /* Seen .END */
96 /* The output stream */
99 /* the attributes of each character are stored as a bit pattern
100 chartype, which gives us quick tests. */
107 #define COMMENTBIT 16
109 #define ISCOMMENTCHAR(x) (chartype[(unsigned char)(x)] & COMMENTBIT)
110 #define ISFIRSTCHAR(x) (chartype[(unsigned char)(x)] & FIRSTBIT)
111 #define ISNEXTCHAR(x) (chartype[(unsigned char)(x)] & NEXTBIT)
112 #define ISSEP(x) (chartype[(unsigned char)(x)] & SEPBIT)
113 #define ISWHITE(x) (chartype[(unsigned char)(x)] & WHITEBIT)
114 #define ISBASE(x) (chartype[(unsigned char)(x)] & BASEBIT)
115 static char chartype[256];
118 /* Conditional assembly uses the `ifstack'. Each aif pushes another
119 entry onto the stack, and sets the on flag if it should. The aelse
120 sets hadelse, and toggles on. An aend pops a level. We limit to
121 100 levels of nesting, not because we're facists pigs with read
122 only minds, but because more than 100 levels of nesting is probably
123 a bug in the user's macro structure. */
125 #define IFNESTING 100
128 int on; /* is the level being output */
129 int hadelse; /* has an aelse been seen */
134 /* The final and intermediate results of expression evaluation are kept in
135 exp_t's. Note that a symbol is not an sb, but a pointer into the input
136 line. It must be coped somewhere safe before the next line is read in. */
147 int value; /* constant part */
148 symbol add_symbol; /* name part */
149 symbol sub_symbol; /* name part */
154 /* Hashing is done in a pretty standard way. A hash_table has a
155 pointer to a vector of pointers to hash_entrys, and the size of the
156 vector. A hash_entry contains a union of all the info we like to
157 store in hash table. If there is a hash collision, hash_entries
158 with the same hash are kept in a chain. */
160 /* What the data in a hash_entry means */
163 hash_integer, /* name->integer mapping */
164 hash_string, /* name->string mapping */
165 hash_macro, /* name is a macro */
166 hash_formal /* name is a formal argument */
171 sb key; /* symbol name */
172 hash_type type; /* symbol meaning */
177 struct macro_struct *m;
178 struct formal_struct *f;
180 struct hs *next; /* next hash_entry with same hash key */
190 /* Structures used to store macros.
192 Each macro knows its name and included text. It gets built with a
193 list of formal arguments, and also keeps a hash table which points
194 into the list to speed up formal search. Each formal knows its
195 name and its default value. Each time the macro is expanded, the
196 formals get the actual values attatched to them. */
198 /* describe the formal arguments to a macro */
200 typedef struct formal_struct
202 struct formal_struct *next; /* next formal in list */
203 sb name; /* name of the formal */
204 sb def; /* the default value */
205 sb actual; /* the actual argument (changed on each expansion) */
206 int index; /* the index of the formal 0..formal_count-1 */
210 /* describe the macro. */
212 typedef struct macro_struct
214 sb sub; /* substitution text. */
215 int formal_count; /* number of formal args. */
216 formal_entry *formals; /* pointer to list of formal_structs */
217 hash_table formal_hash; /* hash table of formals. */
221 /* how we nest files and expand macros etc.
223 we keep a stack of of include_stack structs. each include file
224 pushes a new level onto the stack. we keep an sb with a pushback
225 too. unget chars are pushed onto the pushback sb, getchars first
226 checks the pushback sb before reading from the input stream.
228 small things are expanded by adding the text of the item onto the
229 pushback sb. larger items are grown by pushing a new level and
230 allocating the entire pushback buf for the item. each time
231 something like a macro is expanded, the stack index is changed. we
232 can then perform an exitm by popping all entries off the stack with
233 the same stack index. if we're being reasonable, we can detect
234 recusive expansion by checking the index is reasonably small.
239 include_file, include_repeat, include_while, include_macro
244 sb pushback; /* current pushback stream */
245 int pushback_index; /* next char to read from stream */
246 FILE *handle; /* open file */
247 sb name; /* name of file */
248 int linecount; /* number of lines read so far */
250 int index; /* index of this layer */
252 include_stack[MAX_INCLUDES];
254 struct include_stack *sp;
255 #define isp (sp - include_stack)
257 /* Include file list */
259 typedef struct include_path
261 struct include_path *next;
265 include_path *paths_head;
266 include_path *paths_tail;
269 static void quit PARAMS ((void));
270 static void hash_new_table PARAMS ((int, hash_table *));
271 static int hash PARAMS ((sb *));
272 static hash_entry *hash_create PARAMS ((hash_table *, sb *));
273 static void hash_add_to_string_table PARAMS ((hash_table *, sb *, sb *, int));
274 static void hash_add_to_int_table PARAMS ((hash_table *, sb *, int));
275 static hash_entry *hash_lookup PARAMS ((hash_table *, sb *));
276 static void checkconst PARAMS ((int, exp_t *));
277 static int sb_strtol PARAMS ((int, sb *, int, int *));
278 static int level_0 PARAMS ((int, sb *, exp_t *));
279 static int level_1 PARAMS ((int, sb *, exp_t *));
280 static int level_2 PARAMS ((int, sb *, exp_t *));
281 static int level_3 PARAMS ((int, sb *, exp_t *));
282 static int level_4 PARAMS ((int, sb *, exp_t *));
283 static int level_5 PARAMS ((int, sb *, exp_t *));
284 static int exp_parse PARAMS ((int, sb *, exp_t *));
285 static void exp_string PARAMS ((exp_t *, sb *));
286 static int exp_get_abs PARAMS ((const char *, int, sb *, int *));
288 static void strip_comments PARAMS ((sb *));
290 static void unget PARAMS ((int));
291 static void include_buf PARAMS ((sb *, sb *, include_type, int));
292 static void include_print_where_line PARAMS ((FILE *));
293 static void include_print_line PARAMS ((FILE *));
294 static int get_line PARAMS ((sb *));
295 static int grab_label PARAMS ((sb *, sb *));
296 static void change_base PARAMS ((int, sb *, sb *));
297 static void do_end PARAMS ((sb *));
298 static void do_assign PARAMS ((int, int, sb *));
299 static void do_radix PARAMS ((sb *));
300 static int get_opsize PARAMS ((int, sb *, int *));
301 static int eol PARAMS ((int, sb *));
302 static void do_data PARAMS ((int, sb *, int));
303 static void do_datab PARAMS ((int, sb *));
304 static void do_align PARAMS ((int, sb *));
305 static void do_res PARAMS ((int, sb *, int));
306 static void do_export PARAMS ((sb *));
307 static void do_print PARAMS ((int, sb *));
308 static void do_heading PARAMS ((int, sb *));
309 static void do_page PARAMS ((void));
310 static void do_form PARAMS ((int, sb *));
311 static int get_any_string PARAMS ((int, sb *, sb *, int, int));
312 static int skip_openp PARAMS ((int, sb *));
313 static int skip_closep PARAMS ((int, sb *));
314 static int dolen PARAMS ((int, sb *, sb *));
315 static int doinstr PARAMS ((int, sb *, sb *));
316 static int dosubstr PARAMS ((int, sb *, sb *));
317 static void process_assigns PARAMS ((int, sb *, sb *));
318 static int get_and_process PARAMS ((int, sb *, sb *));
319 static void process_file PARAMS ((void));
320 static void free_old_entry PARAMS ((hash_entry *));
321 static void do_assigna PARAMS ((int, sb *));
322 static void do_assignc PARAMS ((int, sb *));
323 static void do_reg PARAMS ((int, sb *));
324 static int condass_lookup_name PARAMS ((sb *, int, sb *, int));
325 static int whatcond PARAMS ((int, sb *, int *));
326 static int istrue PARAMS ((int, sb *));
327 static void do_aif PARAMS ((int, sb *));
328 static void do_aelse PARAMS ((void));
329 static void do_aendi PARAMS ((void));
330 static int condass_on PARAMS ((void));
331 static void do_if PARAMS ((int, sb *, int));
332 static int get_mri_string PARAMS ((int, sb *, sb *, int));
333 static void do_ifc PARAMS ((int, sb *, int));
334 static void do_aendr PARAMS ((void));
335 static void do_awhile PARAMS ((int, sb *));
336 static void do_aendw PARAMS ((void));
337 static void do_exitm PARAMS ((void));
338 static void do_arepeat PARAMS ((int, sb *));
339 static void do_endm PARAMS ((void));
340 static void do_irp PARAMS ((int, sb *, int));
341 static void do_local PARAMS ((int, sb *));
342 static void do_macro PARAMS ((int, sb *));
343 static int macro_op PARAMS ((int, sb *));
344 static int getstring PARAMS ((int, sb *, sb *));
345 static void do_sdata PARAMS ((int, sb *, int));
346 static void do_sdatab PARAMS ((int, sb *));
347 static int new_file PARAMS ((const char *));
348 static void do_include PARAMS ((int, sb *));
349 static void include_pop PARAMS ((void));
350 static int get PARAMS ((void));
351 static int linecount PARAMS ((void));
352 static int include_next_index PARAMS ((void));
353 static void chartype_init PARAMS ((void));
354 static int process_pseudo_op PARAMS ((int, sb *, sb *));
355 static void add_keyword PARAMS ((const char *, int));
356 static void process_init PARAMS ((void));
357 static void do_define PARAMS ((const char *));
358 static void show_usage PARAMS ((FILE *, int));
359 static void show_help PARAMS ((void));
362 do { include_print_where_line (stderr); fprintf x ; fatals++; quit(); } while(0)
364 do { include_print_where_line (stderr); fprintf x; errors++; } while(0)
366 do { include_print_where_line (stderr); fprintf x; warnings++;} while(0)
370 /* exit the program and return the right ERROR code. */
383 for (i = 0; i < sb_max_power_two; i++)
385 fprintf (stderr, "strings size %8d : %d\n", 1<<i, string_count[i]);
391 /* hash table maintenance. */
393 /* build a new hash table with size buckets, and fill in the info at ptr. */
396 hash_new_table (size, ptr)
402 ptr->table = (hash_entry **) xmalloc (size * (sizeof (hash_entry *)));
403 /* Fill with null-pointer, not zero-bit-pattern. */
404 for (i = 0; i < size; i++)
408 /* calculate and return the hash value of the sb at key. */
417 for (i = 0; i < key->len; i++)
425 /* lookup key in hash_table tab, if present, then return it, otherwise
426 build a new one and fill it with hash_integer. */
430 hash_create (tab, key)
434 int k = hash (key) % tab->size;
436 hash_entry **table = tab->table;
444 hash_entry *n = (hash_entry *) xmalloc (sizeof (hash_entry));
447 sb_add_sb (&n->key, key);
449 n->type = hash_integer;
452 if (strncmp (table[k]->key.ptr, key->ptr, key->len) == 0)
460 /* add sb name with key into hash_table tab. if replacing old value
461 and again, then ERROR. */
465 hash_add_to_string_table (tab, key, name, again)
471 hash_entry *ptr = hash_create (tab, key);
472 if (ptr->type == hash_integer)
474 sb_new (&ptr->value.s);
476 if (ptr->value.s.len)
479 ERROR ((stderr, _("redefinition not allowed\n")));
482 ptr->type = hash_string;
483 sb_reset (&ptr->value.s);
485 sb_add_sb (&ptr->value.s, name);
488 /* add integer name to hash_table tab with sb key. */
492 hash_add_to_int_table (tab, key, name)
497 hash_entry *ptr = hash_create (tab, key);
501 /* lookup sb key in hash_table tab. if found return hash_entry result,
506 hash_lookup (tab, key)
510 int k = hash (key) % tab->size;
511 hash_entry **table = tab->table;
512 hash_entry *p = table[k];
515 if (p->key.len == key->len
516 && strncmp (p->key.ptr, key->ptr, key->len) == 0)
526 are handled in a really simple recursive decent way. each bit of
527 the machine takes an index into an sb and a pointer to an exp_t,
528 modifies the *exp_t and returns the index of the first character
529 past the part of the expression parsed.
531 expression precedence:
542 /* make sure that the exp_t at term is constant, if not the give the op ERROR. */
546 checkconst (op, term)
550 if (term->add_symbol.len
551 || term->sub_symbol.len)
553 ERROR ((stderr, _("the %c operator cannot take non-absolute arguments.\n"), op));
557 /* turn the number in string at idx into a number of base,
558 fill in ptr and return the index of the first character not in the
563 sb_strtol (idx, string, base, ptr)
570 idx = sb_skip_white (idx, string);
572 while (idx < string->len)
574 int ch = string->ptr[idx];
578 else if (ch >= 'a' && ch <= 'f')
580 else if (ch >= 'A' && ch <= 'F')
588 value = value * base + dig;
596 level_0 (idx, string, lhs)
601 lhs->add_symbol.len = 0;
602 lhs->add_symbol.name = 0;
604 lhs->sub_symbol.len = 0;
605 lhs->sub_symbol.name = 0;
607 idx = sb_skip_white (idx, string);
611 if (isdigit ((unsigned char) string->ptr[idx]))
613 idx = sb_strtol (idx, string, 10, &lhs->value);
615 else if (ISFIRSTCHAR (string->ptr[idx]))
618 lhs->add_symbol.name = string->ptr + idx;
619 while (idx < string->len && ISNEXTCHAR (string->ptr[idx]))
624 lhs->add_symbol.len = len;
626 else if (string->ptr[idx] == '"')
630 ERROR ((stderr, _("string where expression expected.\n")));
631 idx = getstring (idx, string, &acc);
636 ERROR ((stderr, _("can't find primary in expression.\n")));
639 return sb_skip_white (idx, string);
645 level_1 (idx, string, lhs)
650 idx = sb_skip_white (idx, string);
652 switch (string->ptr[idx])
655 idx = level_1 (idx + 1, string, lhs);
658 idx = level_1 (idx + 1, string, lhs);
659 checkconst ('~', lhs);
660 lhs->value = ~lhs->value;
665 idx = level_1 (idx + 1, string, lhs);
666 lhs->value = -lhs->value;
668 lhs->add_symbol = lhs->sub_symbol;
674 idx = level_5 (sb_skip_white (idx, string), string, lhs);
675 if (string->ptr[idx] != ')')
676 ERROR ((stderr, _("misplaced closing parens.\n")));
681 idx = level_0 (idx, string, lhs);
684 return sb_skip_white (idx, string);
688 level_2 (idx, string, lhs)
695 idx = level_1 (idx, string, lhs);
697 while (idx < string->len && (string->ptr[idx] == '*'
698 || string->ptr[idx] == '/'))
700 char op = string->ptr[idx++];
701 idx = level_1 (idx, string, &rhs);
705 checkconst ('*', lhs);
706 checkconst ('*', &rhs);
707 lhs->value *= rhs.value;
710 checkconst ('/', lhs);
711 checkconst ('/', &rhs);
713 ERROR ((stderr, _("attempt to divide by zero.\n")));
715 lhs->value /= rhs.value;
719 return sb_skip_white (idx, string);
724 level_3 (idx, string, lhs)
731 idx = level_2 (idx, string, lhs);
733 while (idx < string->len
734 && (string->ptr[idx] == '+'
735 || string->ptr[idx] == '-'))
737 char op = string->ptr[idx++];
738 idx = level_2 (idx, string, &rhs);
742 lhs->value += rhs.value;
743 if (lhs->add_symbol.name && rhs.add_symbol.name)
745 ERROR ((stderr, _("can't add two relocatable expressions\n")));
747 /* change nn+symbol to symbol + nn */
748 if (rhs.add_symbol.name)
750 lhs->add_symbol = rhs.add_symbol;
754 lhs->value -= rhs.value;
755 lhs->sub_symbol = rhs.add_symbol;
759 return sb_skip_white (idx, string);
763 level_4 (idx, string, lhs)
770 idx = level_3 (idx, string, lhs);
772 while (idx < string->len &&
773 string->ptr[idx] == '&')
775 char op = string->ptr[idx++];
776 idx = level_3 (idx, string, &rhs);
780 checkconst ('&', lhs);
781 checkconst ('&', &rhs);
782 lhs->value &= rhs.value;
786 return sb_skip_white (idx, string);
790 level_5 (idx, string, lhs)
797 idx = level_4 (idx, string, lhs);
799 while (idx < string->len
800 && (string->ptr[idx] == '|' || string->ptr[idx] == '~'))
802 char op = string->ptr[idx++];
803 idx = level_4 (idx, string, &rhs);
807 checkconst ('|', lhs);
808 checkconst ('|', &rhs);
809 lhs->value |= rhs.value;
812 checkconst ('~', lhs);
813 checkconst ('~', &rhs);
814 lhs->value ^= rhs.value;
818 return sb_skip_white (idx, string);
822 /* parse the expression at offset idx into string, fill up res with
823 the result. return the index of the first char past the expression.
827 exp_parse (idx, string, res)
832 return level_5 (sb_skip_white (idx, string), string, res);
836 /* turn the expression at exp into text and glue it onto the end of
840 exp_string (exp, string)
848 if (exp->add_symbol.len)
850 sb_add_buffer (string, exp->add_symbol.name, exp->add_symbol.len);
858 sb_add_char (string, '+');
859 sprintf (buf, "%d", exp->value);
860 sb_add_string (string, buf);
864 if (exp->sub_symbol.len)
866 sb_add_char (string, '-');
867 sb_add_buffer (string, exp->add_symbol.name, exp->add_symbol.len);
873 sb_add_char (string, '0');
877 /* parse the expression at offset idx into sb in, return the value in val.
878 if the expression is not constant, give ERROR emsg. returns the index
879 of the first character past the end of the expression. */
882 exp_get_abs (emsg, idx, in, val)
889 idx = exp_parse (idx, in, &res);
890 if (res.add_symbol.len || res.sub_symbol.len)
891 ERROR ((stderr, emsg));
897 sb label; /* current label parsed from line */
898 hash_table assign_hash_table; /* hash table for all assigned variables */
899 hash_table keyword_hash_table; /* hash table for keyword */
900 hash_table vars; /* hash table for eq variables */
902 #define in_comment ';'
911 for (i = 0; i < out->len; i++)
913 if (ISCOMMENTCHAR(s[i]))
922 /* push back character ch so that it can be read again. */
932 if (sp->pushback_index)
933 sp->pushback_index--;
935 sb_add_char (&sp->pushback, ch);
938 /* push the sb ptr onto the include stack, with the given name, type and index. */
942 include_buf (name, ptr, type, index)
949 if (sp - include_stack >= MAX_INCLUDES)
950 FATAL ((stderr, _("unreasonable nesting.\n")));
952 sb_add_sb (&sp->name, name);
955 sp->pushback_index = 0;
958 sb_new (&sp->pushback);
959 sb_add_sb (&sp->pushback, ptr);
963 /* used in ERROR messages, print info on where the include stack is onto file. */
966 include_print_where_line (file)
969 struct include_stack *p = include_stack + 1;
973 fprintf (file, "%s:%d ", sb_name (&p->name), p->linecount - 1);
978 /* used in listings, print the line number onto file. */
980 include_print_line (file)
984 struct include_stack *p = include_stack + 1;
986 n = fprintf (file, "%4d", p->linecount);
990 n += fprintf (file, ".%d", p->linecount);
1001 /* read a line from the top of the include stack into sb in. */
1012 putc (comment_char, outfile);
1013 if (print_line_number)
1014 include_print_line (outfile);
1028 WARNING ((stderr, _("End of file not at start of line.\n")));
1030 putc ('\n', outfile);
1049 /* continued line */
1052 putc (comment_char, outfile);
1053 putc ('+', outfile);
1066 sb_add_char (in, ch);
1074 /* find a label from sb in and put it in out. */
1077 grab_label (in, out)
1083 if (ISFIRSTCHAR (in->ptr[i]) || in->ptr[i] == '\\')
1085 sb_add_char (out, in->ptr[i]);
1087 while ((ISNEXTCHAR (in->ptr[i])
1088 || in->ptr[i] == '\\'
1089 || in->ptr[i] == '&')
1092 sb_add_char (out, in->ptr[i]);
1099 /* find all strange base stuff and turn into decimal. also
1100 find all the other numbers and convert them from the default radix */
1103 change_base (idx, in, out)
1110 while (idx < in->len)
1112 if (in->ptr[idx] == '\\'
1113 && idx + 1 < in->len
1114 && in->ptr[idx + 1] == '(')
1117 while (idx < in->len
1118 && in->ptr[idx] != ')')
1120 sb_add_char (out, in->ptr[idx]);
1126 else if (idx < in->len - 1 && in->ptr[idx + 1] == '\'' && ! mri)
1130 switch (in->ptr[idx])
1149 ERROR ((stderr, _("Illegal base character %c.\n"), in->ptr[idx]));
1154 idx = sb_strtol (idx + 2, in, base, &value);
1155 sprintf (buffer, "%d", value);
1156 sb_add_string (out, buffer);
1158 else if (ISFIRSTCHAR (in->ptr[idx]))
1160 /* copy entire names through quickly */
1161 sb_add_char (out, in->ptr[idx]);
1163 while (idx < in->len && ISNEXTCHAR (in->ptr[idx]))
1165 sb_add_char (out, in->ptr[idx]);
1169 else if (isdigit ((unsigned char) in->ptr[idx]))
1172 /* all numbers must start with a digit, let's chew it and
1174 idx = sb_strtol (idx, in, radix, &value);
1175 sprintf (buffer, "%d", value);
1176 sb_add_string (out, buffer);
1178 /* skip all undigsested letters */
1179 while (idx < in->len && ISNEXTCHAR (in->ptr[idx]))
1181 sb_add_char (out, in->ptr[idx]);
1185 else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
1187 char tchar = in->ptr[idx];
1188 /* copy entire names through quickly */
1189 sb_add_char (out, in->ptr[idx]);
1191 while (idx < in->len && in->ptr[idx] != tchar)
1193 sb_add_char (out, in->ptr[idx]);
1199 /* nothing special, just pass it through */
1200 sb_add_char (out, in->ptr[idx]);
1214 fprintf (outfile, "%s\n", sb_name (in));
1220 do_assign (again, idx, in)
1225 /* stick label in symbol table with following value */
1230 idx = exp_parse (idx, in, &e);
1231 exp_string (&e, &acc);
1232 hash_add_to_string_table (&assign_hash_table, &label, &acc, again);
1237 /* .radix [b|q|d|h] */
1244 int idx = sb_skip_white (0, ptr);
1245 switch (ptr->ptr[idx])
1264 ERROR ((stderr, _("radix is %c must be one of b, q, d or h"), radix));
1269 /* Parse off a .b, .w or .l */
1272 get_opsize (idx, in, size)
1278 if (in->ptr[idx] == '.')
1282 switch (in->ptr[idx])
1300 ERROR ((stderr, _("size must be one of b, w or l, is %c.\n"), in->ptr[idx]));
1313 idx = sb_skip_white (idx, line);
1315 && ISCOMMENTCHAR(line->ptr[idx]))
1317 if (idx >= line->len)
1322 /* .data [.b|.w|.l] <data>*
1323 or d[bwl] <data>* */
1326 do_data (idx, in, size)
1332 char *opname = ".yikes!";
1338 idx = get_opsize (idx, in, &opsize);
1357 fprintf (outfile, "%s\t", opname);
1359 idx = sb_skip_white (idx, in);
1363 && in->ptr[idx] == '"')
1366 idx = getstring (idx, in, &acc);
1367 for (i = 0; i < acc.len; i++)
1370 fprintf(outfile,",");
1371 fprintf (outfile, "%d", acc.ptr[i]);
1376 while (!eol (idx, in))
1379 idx = exp_parse (idx, in, &e);
1380 exp_string (&e, &acc);
1381 sb_add_char (&acc, 0);
1382 fprintf (outfile, acc.ptr);
1383 if (idx < in->len && in->ptr[idx] == ',')
1385 fprintf (outfile, ",");
1391 sb_print_at (outfile, idx, in);
1392 fprintf (outfile, "\n");
1395 /* .datab [.b|.w|.l] <repeat>,<fill> */
1406 idx = get_opsize (idx, in, &opsize);
1408 idx = exp_get_abs (_("datab repeat must be constant.\n"), idx, in, &repeat);
1409 idx = sb_skip_comma (idx, in);
1410 idx = exp_get_abs (_("datab data must be absolute.\n"), idx, in, &fill);
1412 fprintf (outfile, ".fill\t%d,%d,%d\n", repeat, opsize, fill);
1422 int al, have_fill, fill;
1424 idx = exp_get_abs (_("align needs absolute expression.\n"), idx, in, &al);
1425 idx = sb_skip_white (idx, in);
1428 if (! eol (idx, in))
1430 idx = sb_skip_comma (idx, in);
1431 idx = exp_get_abs (_(".align needs absolute fill value.\n"), idx, in,
1439 WARNING ((stderr, _("alignment must be one of 1, 2 or 4.\n")));
1441 fprintf (outfile, ".align %d", al);
1443 fprintf (outfile, ",%d", fill);
1444 fprintf (outfile, "\n");
1447 /* .res[.b|.w|.l] <size> */
1450 do_res (idx, in, type)
1458 idx = get_opsize (idx, in, &size);
1459 while (!eol(idx, in))
1461 idx = sb_skip_white (idx, in);
1462 if (in->ptr[idx] == ',')
1464 idx = exp_get_abs (_("res needs absolute expression for fill count.\n"), idx, in, &count);
1466 if (type == 'c' || type == 'z')
1469 fprintf (outfile, ".space %d\n", count * size);
1480 fprintf (outfile, ".global %s\n", sb_name (in));
1483 /* .print [list] [nolist] */
1490 idx = sb_skip_white (idx, in);
1491 while (idx < in->len)
1493 if (strncasecmp (in->ptr + idx, "LIST", 4) == 0)
1495 fprintf (outfile, ".list\n");
1498 else if (strncasecmp (in->ptr + idx, "NOLIST", 6) == 0)
1500 fprintf (outfile, ".nolist\n");
1509 do_heading (idx, in)
1515 idx = getstring (idx, in, &head);
1516 fprintf (outfile, ".title \"%s\"\n", sb_name (&head));
1525 fprintf (outfile, ".eject\n");
1528 /* .form [lin=<value>] [col=<value>] */
1536 idx = sb_skip_white (idx, in);
1538 while (idx < in->len)
1541 if (strncasecmp (in->ptr + idx, "LIN=", 4) == 0)
1544 idx = exp_get_abs (_("form LIN= needs absolute expresssion.\n"), idx, in, &lines);
1547 if (strncasecmp (in->ptr + idx, _("COL="), 4) == 0)
1550 idx = exp_get_abs (_("form COL= needs absolute expresssion.\n"), idx, in, &columns);
1555 fprintf (outfile, ".psize %d,%d\n", lines, columns);
1560 /* Fetch string from the input stream,
1562 'Bxyx<whitespace> -> return 'Bxyza
1563 %<char> -> return string of decimal value of x
1564 "<string>" -> return string
1565 xyx<whitespace> -> return xyz
1568 get_any_string (idx, in, out, expand, pretend_quoted)
1576 idx = sb_skip_white (idx, in);
1580 if (in->len > 2 && in->ptr[idx+1] == '\'' && ISBASE (in->ptr[idx]))
1582 while (!ISSEP (in->ptr[idx]))
1583 sb_add_char (out, in->ptr[idx++]);
1585 else if (in->ptr[idx] == '%'
1591 /* Turns the next expression into a string */
1592 idx = exp_get_abs (_("% operator needs absolute expression"),
1596 sprintf(buf, "%d", val);
1597 sb_add_string (out, buf);
1599 else if (in->ptr[idx] == '"'
1600 || in->ptr[idx] == '<'
1601 || (alternate && in->ptr[idx] == '\''))
1603 if (alternate && expand)
1605 /* Keep the quotes */
1606 sb_add_char (out, '\"');
1608 idx = getstring (idx, in, out);
1609 sb_add_char (out, '\"');
1613 idx = getstring (idx, in, out);
1618 while (idx < in->len
1619 && (in->ptr[idx] == '"'
1620 || in->ptr[idx] == '\''
1622 || !ISSEP (in->ptr[idx])))
1624 if (in->ptr[idx] == '"'
1625 || in->ptr[idx] == '\'')
1627 char tchar = in->ptr[idx];
1628 sb_add_char (out, in->ptr[idx++]);
1629 while (idx < in->len
1630 && in->ptr[idx] != tchar)
1631 sb_add_char (out, in->ptr[idx++]);
1635 sb_add_char (out, in->ptr[idx++]);
1644 /* skip along sb in starting at idx, suck off whitespace a ( and more
1645 whitespace. return the idx of the next char */
1648 skip_openp (idx, in)
1652 idx = sb_skip_white (idx, in);
1653 if (in->ptr[idx] != '(')
1654 ERROR ((stderr, _("misplaced ( .\n")));
1655 idx = sb_skip_white (idx + 1, in);
1659 /* skip along sb in starting at idx, suck off whitespace a ) and more
1660 whitespace. return the idx of the next char */
1663 skip_closep (idx, in)
1667 idx = sb_skip_white (idx, in);
1668 if (in->ptr[idx] != ')')
1669 ERROR ((stderr, _("misplaced ).\n")));
1670 idx = sb_skip_white (idx + 1, in);
1677 dolen (idx, in, out)
1686 sb_new (&stringout);
1687 idx = skip_openp (idx, in);
1688 idx = get_and_process (idx, in, &stringout);
1689 idx = skip_closep (idx, in);
1690 sprintf (buffer, "%d", stringout.len);
1691 sb_add_string (out, buffer);
1693 sb_kill (&stringout);
1702 doinstr (idx, in, out)
1716 idx = skip_openp (idx, in);
1717 idx = get_and_process (idx, in, &string);
1718 idx = sb_skip_comma (idx, in);
1719 idx = get_and_process (idx, in, &search);
1720 idx = sb_skip_comma (idx, in);
1721 if (isdigit ((unsigned char) in->ptr[idx]))
1723 idx = exp_get_abs (_(".instr needs absolute expresson.\n"), idx, in, &start);
1729 idx = skip_closep (idx, in);
1731 for (i = start; i < string.len; i++)
1733 if (strncmp (string.ptr + i, search.ptr, search.len) == 0)
1739 sprintf (buffer, "%d", res);
1740 sb_add_string (out, buffer);
1748 dosubstr (idx, in, out)
1758 idx = skip_openp (idx, in);
1759 idx = get_and_process (idx, in, &string);
1760 idx = sb_skip_comma (idx, in);
1761 idx = exp_get_abs (_("need absolute position.\n"), idx, in, &pos);
1762 idx = sb_skip_comma (idx, in);
1763 idx = exp_get_abs (_("need absolute length.\n"), idx, in, &len);
1764 idx = skip_closep (idx, in);
1767 if (len < 0 || pos < 0 ||
1769 || pos + len > string.len)
1771 sb_add_string (out, " ");
1775 sb_add_char (out, '"');
1778 sb_add_char (out, string.ptr[pos++]);
1781 sb_add_char (out, '"');
1787 /* scan line, change tokens in the hash table to their replacements */
1789 process_assigns (idx, in, buf)
1794 while (idx < in->len)
1797 if (in->ptr[idx] == '\\'
1798 && idx + 1 < in->len
1799 && in->ptr[idx + 1] == '(')
1803 sb_add_char (buf, in->ptr[idx]);
1806 while (idx < in->len && in->ptr[idx - 1] != ')');
1808 else if (in->ptr[idx] == '\\'
1809 && idx + 1 < in->len
1810 && in->ptr[idx + 1] == '&')
1812 idx = condass_lookup_name (in, idx + 2, buf, 1);
1814 else if (in->ptr[idx] == '\\'
1815 && idx + 1 < in->len
1816 && in->ptr[idx + 1] == '$')
1818 idx = condass_lookup_name (in, idx + 2, buf, 0);
1820 else if (idx + 3 < in->len
1821 && in->ptr[idx] == '.'
1822 && toupper ((unsigned char) in->ptr[idx + 1]) == 'L'
1823 && toupper ((unsigned char) in->ptr[idx + 2]) == 'E'
1824 && toupper ((unsigned char) in->ptr[idx + 3]) == 'N')
1825 idx = dolen (idx + 4, in, buf);
1826 else if (idx + 6 < in->len
1827 && in->ptr[idx] == '.'
1828 && toupper ((unsigned char) in->ptr[idx + 1]) == 'I'
1829 && toupper ((unsigned char) in->ptr[idx + 2]) == 'N'
1830 && toupper ((unsigned char) in->ptr[idx + 3]) == 'S'
1831 && toupper ((unsigned char) in->ptr[idx + 4]) == 'T'
1832 && toupper ((unsigned char) in->ptr[idx + 5]) == 'R')
1833 idx = doinstr (idx + 6, in, buf);
1834 else if (idx + 7 < in->len
1835 && in->ptr[idx] == '.'
1836 && toupper ((unsigned char) in->ptr[idx + 1]) == 'S'
1837 && toupper ((unsigned char) in->ptr[idx + 2]) == 'U'
1838 && toupper ((unsigned char) in->ptr[idx + 3]) == 'B'
1839 && toupper ((unsigned char) in->ptr[idx + 4]) == 'S'
1840 && toupper ((unsigned char) in->ptr[idx + 5]) == 'T'
1841 && toupper ((unsigned char) in->ptr[idx + 6]) == 'R')
1842 idx = dosubstr (idx + 7, in, buf);
1843 else if (ISFIRSTCHAR (in->ptr[idx]))
1845 /* may be a simple name subsitution, see if we have a word */
1848 while (cur < in->len
1849 && (ISNEXTCHAR (in->ptr[cur])))
1853 sb_add_buffer (&acc, in->ptr + idx, cur - idx);
1854 ptr = hash_lookup (&assign_hash_table, &acc);
1857 /* Found a definition for it */
1858 sb_add_sb (buf, &ptr->value.s);
1862 /* No definition, just copy the word */
1863 sb_add_sb (buf, &acc);
1870 sb_add_char (buf, in->ptr[idx++]);
1876 get_and_process (idx, in, out)
1883 idx = get_any_string (idx, in, &t, 1, 0);
1884 process_assigns (0, &t, out);
1905 more = get_line (&line);
1908 /* Find any label and pseudo op that we're intested in */
1913 fprintf (outfile, "\n");
1916 && (line.ptr[0] == '*'
1917 || line.ptr[0] == '!'))
1919 /* MRI line comment. */
1920 fprintf (outfile, sb_name (&line));
1924 l = grab_label (&line, &label_in);
1927 if (line.ptr[l] == ':')
1929 while (ISWHITE (line.ptr[l]) && l < line.len)
1936 /* Munge the label, unless this is EQU or ASSIGN. */
1939 && (line.ptr[l] == '.' || alternate || mri))
1943 if (line.ptr[lx] == '.')
1945 if (lx + 3 <= line.len
1946 && strncasecmp ("EQU", line.ptr + lx, 3) == 0
1947 && (lx + 3 == line.len
1948 || ! ISFIRSTCHAR (line.ptr[lx + 3])))
1950 else if (lx + 6 <= line.len
1951 && strncasecmp ("ASSIGN", line.ptr + lx, 6) == 0
1952 && (lx + 6 == line.len
1953 || ! ISFIRSTCHAR (line.ptr[lx + 6])))
1958 process_assigns (0, &label_in, &label);
1960 sb_add_sb (&label, &label_in);
1965 if (process_pseudo_op (l, &line, &acc))
1971 else if (condass_on ())
1973 if (macro_op (l, &line))
1983 fprintf (outfile, "%s:\t", sb_name (&label));
1986 fprintf (outfile, "\t");
1988 process_assigns (l, &line, &t1);
1990 change_base (0, &t1, &t2);
1991 fprintf (outfile, "%s\n", sb_name (&t2));
1997 /* Only a label on this line */
1998 if (label.len && condass_on())
2000 fprintf (outfile, "%s:\n", sb_name (&label));
2008 more = get_line (&line);
2011 if (!had_end && !mri)
2012 WARNING ((stderr, _("END missing from end of file.\n")));
2020 free_old_entry (ptr)
2025 if (ptr->type == hash_string)
2026 sb_kill(&ptr->value.s);
2030 /* name: .ASSIGNA <value> */
2033 do_assigna (idx, in)
2041 process_assigns (idx, in, &tmp);
2042 idx = exp_get_abs (_(".ASSIGNA needs constant expression argument.\n"), 0, &tmp, &val);
2046 ERROR ((stderr, _(".ASSIGNA without label.\n")));
2050 hash_entry *ptr = hash_create (&vars, &label);
2051 free_old_entry (ptr);
2052 ptr->type = hash_integer;
2058 /* name: .ASSIGNC <string> */
2061 do_assignc (idx, in)
2067 idx = getstring (idx, in, &acc);
2071 ERROR ((stderr, _(".ASSIGNS without label.\n")));
2075 hash_entry *ptr = hash_create (&vars, &label);
2076 free_old_entry (ptr);
2077 ptr->type = hash_string;
2078 sb_new (&ptr->value.s);
2079 sb_add_sb (&ptr->value.s, &acc);
2085 /* name: .REG (reg) */
2092 /* remove reg stuff from inside parens */
2095 idx = skip_openp (idx, in);
2097 idx = sb_skip_white (idx, in);
2099 while (idx < in->len
2102 : in->ptr[idx] != ')'))
2104 sb_add_char (&what, in->ptr[idx]);
2107 hash_add_to_string_table (&assign_hash_table, &label, &what, 1);
2113 condass_lookup_name (inbuf, idx, out, warn)
2121 sb_new (&condass_acc);
2123 while (idx < inbuf->len
2124 && ISNEXTCHAR (inbuf->ptr[idx]))
2126 sb_add_char (&condass_acc, inbuf->ptr[idx++]);
2129 if (inbuf->ptr[idx] == '\'')
2131 ptr = hash_lookup (&vars, &condass_acc);
2138 WARNING ((stderr, _("Can't find preprocessor variable %s.\n"), sb_name (&condass_acc)));
2142 sb_add_string (out, "0");
2147 if (ptr->type == hash_integer)
2150 sprintf (buffer, "%d", ptr->value.i);
2151 sb_add_string (out, buffer);
2155 sb_add_sb (out, &ptr->value.s);
2158 sb_kill (&condass_acc);
2171 whatcond (idx, in, val)
2178 idx = sb_skip_white (idx, in);
2180 if (idx + 1 < in->len)
2186 a = toupper ((unsigned char) p[0]);
2187 b = toupper ((unsigned char) p[1]);
2188 if (a == 'E' && b == 'Q')
2190 else if (a == 'N' && b == 'E')
2192 else if (a == 'L' && b == 'T')
2194 else if (a == 'L' && b == 'E')
2196 else if (a == 'G' && b == 'T')
2198 else if (a == 'G' && b == 'E')
2203 ERROR ((stderr, _("Comparison operator must be one of EQ, NE, LT, LE, GT or GE.\n")));
2206 idx = sb_skip_white (idx + 2, in);
2223 idx = sb_skip_white (idx, in);
2225 if (in->ptr[idx] == '"')
2229 /* This is a string comparision */
2230 idx = getstring (idx, in, &acc_a);
2231 idx = whatcond (idx, in, &cond);
2232 idx = getstring (idx, in, &acc_b);
2233 same = acc_a.len == acc_b.len && (strncmp (acc_a.ptr, acc_b.ptr, acc_a.len) == 0);
2235 if (cond != EQ && cond != NE)
2237 ERROR ((stderr, _("Comparison operator for strings must be EQ or NE\n")));
2241 res = (cond != EQ) ^ same;
2244 /* This is a numeric expression */
2249 idx = exp_get_abs (_("Conditional operator must have absolute operands.\n"), idx, in, &vala);
2250 idx = whatcond (idx, in, &cond);
2251 idx = sb_skip_white (idx, in);
2252 if (in->ptr[idx] == '"')
2254 WARNING ((stderr, _("String compared against expression.\n")));
2259 idx = exp_get_abs (_("Conditional operator must have absolute operands.\n"), idx, in, &valb);
2302 if (ifi >= IFNESTING)
2304 FATAL ((stderr, _("AIF nesting unreasonable.\n")));
2307 ifstack[ifi].on = ifstack[ifi-1].on ? istrue (idx, in) : 0;
2308 ifstack[ifi].hadelse = 0;
2316 ifstack[ifi].on = ifstack[ifi-1].on ? !ifstack[ifi].on : 0;
2317 if (ifstack[ifi].hadelse)
2319 ERROR ((stderr, _("Multiple AELSEs in AIF.\n")));
2321 ifstack[ifi].hadelse = 1;
2335 ERROR ((stderr, _("AENDI without AIF.\n")));
2342 return ifstack[ifi].on;
2345 /* MRI IFEQ, IFNE, IFLT, IFLE, IFGE, IFGT. */
2348 do_if (idx, in, cond)
2356 if (ifi >= IFNESTING)
2358 FATAL ((stderr, _("IF nesting unreasonable.\n")));
2361 idx = exp_get_abs (_("Conditional operator must have absolute operands.\n"),
2366 case EQ: res = val == 0; break;
2367 case NE: res = val != 0; break;
2368 case LT: res = val < 0; break;
2369 case LE: res = val <= 0; break;
2370 case GE: res = val >= 0; break;
2371 case GT: res = val > 0; break;
2375 ifstack[ifi].on = ifstack[ifi-1].on ? res: 0;
2376 ifstack[ifi].hadelse = 0;
2379 /* Get a string for the MRI IFC or IFNC pseudo-ops. */
2382 get_mri_string (idx, in, val, terminator)
2388 idx = sb_skip_white (idx, in);
2391 && in->ptr[idx] == '\'')
2393 sb_add_char (val, '\'');
2394 for (++idx; idx < in->len; ++idx)
2396 sb_add_char (val, in->ptr[idx]);
2397 if (in->ptr[idx] == '\'')
2401 || in->ptr[idx] != '\'')
2405 idx = sb_skip_white (idx, in);
2411 while (idx < in->len
2412 && in->ptr[idx] != terminator)
2414 sb_add_char (val, in->ptr[idx]);
2418 while (i >= 0 && ISWHITE (val->ptr[i]))
2426 /* MRI IFC, IFNC. */
2429 do_ifc (idx, in, ifnc)
2438 if (ifi >= IFNESTING)
2440 FATAL ((stderr, _("IF nesting unreasonable.\n")));
2446 idx = get_mri_string (idx, in, &first, ',');
2448 if (idx >= in->len || in->ptr[idx] != ',')
2450 ERROR ((stderr, _("Bad format for IF or IFNC.\n")));
2454 idx = get_mri_string (idx + 1, in, &second, ';');
2456 res = (first.len == second.len
2457 && strncmp (first.ptr, second.ptr, first.len) == 0);
2461 ifstack[ifi].on = ifstack[ifi-1].on ? res : 0;
2462 ifstack[ifi].hadelse = 0;
2470 ERROR ((stderr, _("AENDR without a AREPEAT.\n")));
2472 ERROR ((stderr, _("ENDR without a REPT.\n")));
2483 int line = linecount ();
2491 process_assigns (idx, in, &exp);
2492 doit = istrue (0, &exp);
2494 if (! buffer_and_nest ("AWHILE", "AENDW", &sub, get_line))
2495 FATAL ((stderr, _("AWHILE without a AENDW at %d.\n"), line - 1));
2510 int index = include_next_index ();
2514 sb_add_sb (©, &sub);
2515 sb_add_sb (©, in);
2516 sb_add_string (©, "\n");
2517 sb_add_sb (©, &sub);
2518 sb_add_string (©, "\t.AENDW\n");
2519 /* Push another WHILE */
2520 include_buf (&exp, ©, include_while, index);
2533 ERROR ((stderr, _("AENDW without a AENDW.\n")));
2539 Pop things off the include stack until the type and index changes */
2544 include_type type = sp->type;
2545 if (type == include_repeat
2546 || type == include_while
2547 || type == include_macro)
2549 int index = sp->index;
2551 while (sp->index == index
2552 && sp->type == type)
2562 do_arepeat (idx, in)
2566 int line = linecount ();
2567 sb exp; /* buffer with expression in it */
2568 sb copy; /* expanded repeat block */
2569 sb sub; /* contents of AREPEAT */
2577 process_assigns (idx, in, &exp);
2578 idx = exp_get_abs (_("AREPEAT must have absolute operand.\n"), 0, &exp, &rc);
2580 ret = buffer_and_nest ("AREPEAT", "AENDR", &sub, get_line);
2582 ret = buffer_and_nest ("REPT", "ENDR", &sub, get_line);
2584 FATAL ((stderr, _("AREPEAT without a AENDR at %d.\n"), line - 1));
2587 /* Push back the text following the repeat, and another repeat block
2598 int index = include_next_index ();
2599 sb_add_sb (©, &sub);
2603 sprintf (buffer, "\t.AREPEAT %d\n", rc - 1);
2605 sprintf (buffer, "\tREPT %d\n", rc - 1);
2606 sb_add_string (©, buffer);
2607 sb_add_sb (©, &sub);
2609 sb_add_string (©, " .AENDR\n");
2611 sb_add_string (©, " ENDR\n");
2614 include_buf (&exp, ©, include_repeat, index);
2626 ERROR ((stderr, _(".ENDM without a matching .MACRO.\n")));
2629 /* MRI IRP pseudo-op. */
2632 do_irp (idx, in, irpc)
2642 err = expand_irp (irpc, idx, in, &out, get_line, comment_char);
2644 ERROR ((stderr, "%s\n", err));
2646 fprintf (outfile, "%s", sb_terminate (&out));
2651 /* MACRO PROCESSING */
2653 /* Parse off LOCAL n1, n2,... Invent a label name for it */
2656 do_local (idx, line)
2660 ERROR ((stderr, _("LOCAL outside of MACRO")));
2669 int line = linecount ();
2671 err = define_macro (idx, in, &label, get_line, (const char **) NULL);
2673 ERROR ((stderr, _("macro at line %d: %s\n"), line - 1, err));
2685 if (! macro_defined)
2689 if (! check_macro (in->ptr + idx, &out, comment_char, &err))
2693 ERROR ((stderr, "%s\n", err));
2696 sb_add_string (&name, _("macro expansion"));
2698 include_buf (&name, &out, include_macro, include_next_index ());
2706 /* STRING HANDLING */
2709 getstring (idx, in, acc)
2714 idx = sb_skip_white (idx, in);
2716 while (idx < in->len
2717 && (in->ptr[idx] == '"'
2718 || in->ptr[idx] == '<'
2719 || (in->ptr[idx] == '\'' && alternate)))
2721 if (in->ptr[idx] == '<')
2723 if (alternate || mri)
2727 while ((in->ptr[idx] != '>' || nest)
2730 if (in->ptr[idx] == '!')
2733 sb_add_char (acc, in->ptr[idx++]);
2736 if (in->ptr[idx] == '>')
2738 if (in->ptr[idx] == '<')
2740 sb_add_char (acc, in->ptr[idx++]);
2748 idx = exp_get_abs (_("Character code in string must be absolute expression.\n"),
2750 sb_add_char (acc, code);
2752 if (in->ptr[idx] != '>')
2753 ERROR ((stderr, _("Missing > for character code.\n")));
2757 else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
2759 char tchar = in->ptr[idx];
2761 while (idx < in->len)
2763 if (alternate && in->ptr[idx] == '!')
2766 sb_add_char (acc, in->ptr[idx++]);
2769 if (in->ptr[idx] == tchar)
2772 if (idx >= in->len || in->ptr[idx] != tchar)
2775 sb_add_char (acc, in->ptr[idx]);
2785 /* .SDATA[C|Z] <string> */
2789 do_sdata (idx, in, type)
2798 fprintf (outfile, ".byte\t");
2800 while (!eol (idx, in))
2804 idx = sb_skip_white (idx, in);
2805 while (!eol (idx, in))
2807 pidx = idx = get_any_string (idx, in, &acc, 0, 1);
2812 ERROR ((stderr, _("string for SDATAC longer than 255 characters (%d).\n"), acc.len));
2814 fprintf (outfile, "%d", acc.len);
2818 for (i = 0; i < acc.len; i++)
2822 fprintf (outfile, ",");
2824 fprintf (outfile, "%d", acc.ptr[i]);
2831 fprintf (outfile, ",");
2832 fprintf (outfile, "0");
2834 idx = sb_skip_comma (idx, in);
2835 if (idx == pidx) break;
2837 if (!alternate && in->ptr[idx] != ',' && idx != in->len)
2839 fprintf (outfile, "\n");
2840 ERROR ((stderr, _("illegal character in SDATA line (0x%x).\n"), in->ptr[idx]));
2846 fprintf (outfile, "\n");
2849 /* .SDATAB <count> <string> */
2861 idx = exp_get_abs (_("Must have absolute SDATAB repeat count.\n"), idx, in, &repeat);
2864 ERROR ((stderr, _("Must have positive SDATAB repeat count (%d).\n"), repeat));
2868 idx = sb_skip_comma (idx, in);
2869 idx = getstring (idx, in, &acc);
2871 for (i = 0; i < repeat; i++)
2874 fprintf (outfile, "\t");
2875 fprintf (outfile, ".byte\t");
2876 sb_print (outfile, &acc);
2877 fprintf (outfile, "\n");
2887 FILE *newone = fopen (name, "r");
2891 if (isp == MAX_INCLUDES)
2892 FATAL ((stderr, _("Unreasonable include depth (%ld).\n"), (long) isp));
2895 sp->handle = newone;
2898 sb_add_string (&sp->name, name);
2901 sp->pushback_index = 0;
2902 sp->type = include_file;
2904 sb_new (&sp->pushback);
2909 do_include (idx, in)
2915 include_path *includes;
2921 idx = getstring (idx, in, &t);
2924 idx = sb_skip_white (idx, in);
2925 while (idx < in->len && ! ISWHITE (in->ptr[idx]))
2927 sb_add_char (&t, in->ptr[idx]);
2932 for (includes = paths_head; includes; includes = includes->next)
2935 sb_add_sb (&cat, &includes->path);
2936 sb_add_char (&cat, '/');
2937 sb_add_sb (&cat, &t);
2938 if (new_file (sb_name (&cat)))
2945 if (! new_file (sb_name (&t)))
2946 FATAL ((stderr, _("Can't open include file `%s'.\n"), sb_name (&t)));
2955 if (sp != include_stack)
2958 fclose (sp->handle);
2963 /* Get the next character from the include stack. If there's anything
2964 in the pushback buffer, take that first. If we're at eof, pop from
2965 the stack and try again. Keep the linecount up to date. */
2972 if (sp->pushback.len != sp->pushback_index)
2974 r = (char) (sp->pushback.ptr[sp->pushback_index++]);
2975 /* When they've all gone, reset the pointer */
2976 if (sp->pushback_index == sp->pushback.len)
2978 sp->pushback.len = 0;
2979 sp->pushback_index = 0;
2982 else if (sp->handle)
2984 r = getc (sp->handle);
2989 if (r == EOF && isp)
2993 while (r == EOF && isp)
3011 return sp->linecount;
3015 include_next_index ()
3019 && index > MAX_REASONABLE)
3020 FATAL ((stderr, _("Unreasonable expansion (-u turns off check).\n")));
3025 /* Initialize the chartype vector. */
3031 for (x = 0; x < 256; x++)
3033 if (isalpha (x) || x == '_' || x == '$')
3034 chartype[x] |= FIRSTBIT;
3036 if (mri && x == '.')
3037 chartype[x] |= FIRSTBIT;
3039 if (isdigit (x) || isalpha (x) || x == '_' || x == '$')
3040 chartype[x] |= NEXTBIT;
3042 if (x == ' ' || x == '\t' || x == ',' || x == '"' || x == ';'
3043 || x == '"' || x == '<' || x == '>' || x == ')' || x == '(')
3044 chartype[x] |= SEPBIT;
3046 if (x == 'b' || x == 'B'
3047 || x == 'q' || x == 'Q'
3048 || x == 'h' || x == 'H'
3049 || x == 'd' || x == 'D')
3050 chartype [x] |= BASEBIT;
3052 if (x == ' ' || x == '\t')
3053 chartype[x] |= WHITEBIT;
3055 if (x == comment_char)
3056 chartype[x] |= COMMENTBIT;
3062 /* What to do with all the keywords */
3063 #define PROCESS 0x1000 /* Run substitution over the line */
3064 #define LAB 0x2000 /* Spit out the label */
3066 #define K_EQU (PROCESS|1)
3067 #define K_ASSIGN (PROCESS|2)
3068 #define K_REG (PROCESS|3)
3069 #define K_ORG (PROCESS|4)
3070 #define K_RADIX (PROCESS|5)
3071 #define K_DATA (LAB|PROCESS|6)
3072 #define K_DATAB (LAB|PROCESS|7)
3073 #define K_SDATA (LAB|PROCESS|8)
3074 #define K_SDATAB (LAB|PROCESS|9)
3075 #define K_SDATAC (LAB|PROCESS|10)
3076 #define K_SDATAZ (LAB|PROCESS|11)
3077 #define K_RES (LAB|PROCESS|12)
3078 #define K_SRES (LAB|PROCESS|13)
3079 #define K_SRESC (LAB|PROCESS|14)
3080 #define K_SRESZ (LAB|PROCESS|15)
3081 #define K_EXPORT (LAB|PROCESS|16)
3082 #define K_GLOBAL (LAB|PROCESS|17)
3083 #define K_PRINT (LAB|PROCESS|19)
3084 #define K_FORM (LAB|PROCESS|20)
3085 #define K_HEADING (LAB|PROCESS|21)
3086 #define K_PAGE (LAB|PROCESS|22)
3087 #define K_IMPORT (LAB|PROCESS|23)
3088 #define K_PROGRAM (LAB|PROCESS|24)
3089 #define K_END (PROCESS|25)
3090 #define K_INCLUDE (PROCESS|26)
3091 #define K_IGNORED (PROCESS|27)
3092 #define K_ASSIGNA (PROCESS|28)
3093 #define K_ASSIGNC (29)
3094 #define K_AIF (PROCESS|30)
3095 #define K_AELSE (PROCESS|31)
3096 #define K_AENDI (PROCESS|32)
3097 #define K_AREPEAT (PROCESS|33)
3098 #define K_AENDR (PROCESS|34)
3099 #define K_AWHILE (35)
3100 #define K_AENDW (PROCESS|36)
3101 #define K_EXITM (37)
3102 #define K_MACRO (PROCESS|38)
3104 #define K_ALIGN (PROCESS|LAB|40)
3105 #define K_ALTERNATE (41)
3106 #define K_DB (LAB|PROCESS|42)
3107 #define K_DW (LAB|PROCESS|43)
3108 #define K_DL (LAB|PROCESS|44)
3109 #define K_LOCAL (45)
3110 #define K_IFEQ (PROCESS|46)
3111 #define K_IFNE (PROCESS|47)
3112 #define K_IFLT (PROCESS|48)
3113 #define K_IFLE (PROCESS|49)
3114 #define K_IFGE (PROCESS|50)
3115 #define K_IFGT (PROCESS|51)
3116 #define K_IFC (PROCESS|52)
3117 #define K_IFNC (PROCESS|53)
3118 #define K_IRP (PROCESS|54)
3119 #define K_IRPC (PROCESS|55)
3129 static struct keyword kinfo[] =
3131 { "EQU", K_EQU, 0 },
3132 { "ALTERNATE", K_ALTERNATE, 0 },
3133 { "ASSIGN", K_ASSIGN, 0 },
3134 { "REG", K_REG, 0 },
3135 { "ORG", K_ORG, 0 },
3136 { "RADIX", K_RADIX, 0 },
3137 { "DATA", K_DATA, 0 },
3141 { "DATAB", K_DATAB, 0 },
3142 { "SDATA", K_SDATA, 0 },
3143 { "SDATAB", K_SDATAB, 0 },
3144 { "SDATAZ", K_SDATAZ, 0 },
3145 { "SDATAC", K_SDATAC, 0 },
3146 { "RES", K_RES, 0 },
3147 { "SRES", K_SRES, 0 },
3148 { "SRESC", K_SRESC, 0 },
3149 { "SRESZ", K_SRESZ, 0 },
3150 { "EXPORT", K_EXPORT, 0 },
3151 { "GLOBAL", K_GLOBAL, 0 },
3152 { "PRINT", K_PRINT, 0 },
3153 { "FORM", K_FORM, 0 },
3154 { "HEADING", K_HEADING, 0 },
3155 { "PAGE", K_PAGE, 0 },
3156 { "PROGRAM", K_IGNORED, 0 },
3157 { "END", K_END, 0 },
3158 { "INCLUDE", K_INCLUDE, 0 },
3159 { "ASSIGNA", K_ASSIGNA, 0 },
3160 { "ASSIGNC", K_ASSIGNC, 0 },
3161 { "AIF", K_AIF, 0 },
3162 { "AELSE", K_AELSE, 0 },
3163 { "AENDI", K_AENDI, 0 },
3164 { "AREPEAT", K_AREPEAT, 0 },
3165 { "AENDR", K_AENDR, 0 },
3166 { "EXITM", K_EXITM, 0 },
3167 { "MACRO", K_MACRO, 0 },
3168 { "ENDM", K_ENDM, 0 },
3169 { "AWHILE", K_AWHILE, 0 },
3170 { "ALIGN", K_ALIGN, 0 },
3171 { "AENDW", K_AENDW, 0 },
3172 { "ALTERNATE", K_ALTERNATE, 0 },
3173 { "LOCAL", K_LOCAL, 0 },
3177 /* Although the conditional operators are handled by gas, we need to
3178 handle them here as well, in case they are used in a recursive
3179 macro to end the recursion. */
3181 static struct keyword mrikinfo[] =
3183 { "IFEQ", K_IFEQ, 0 },
3184 { "IFNE", K_IFNE, 0 },
3185 { "IFLT", K_IFLT, 0 },
3186 { "IFLE", K_IFLE, 0 },
3187 { "IFGE", K_IFGE, 0 },
3188 { "IFGT", K_IFGT, 0 },
3189 { "IFC", K_IFC, 0 },
3190 { "IFNC", K_IFNC, 0 },
3191 { "ELSEC", K_AELSE, 0 },
3192 { "ENDC", K_AENDI, 0 },
3193 { "MEXIT", K_EXITM, 0 },
3194 { "REPT", K_AREPEAT, 0 },
3195 { "IRP", K_IRP, 0 },
3196 { "IRPC", K_IRPC, 0 },
3197 { "ENDR", K_AENDR, 0 },
3201 /* Look for a pseudo op on the line. If one's there then call
3205 process_pseudo_op (idx, line, acc)
3212 if (line->ptr[idx] == '.' || alternate || mri)
3214 /* Scan forward and find pseudo name */
3220 if (line->ptr[idx] == '.')
3222 in = line->ptr + idx;
3227 while (idx < line->len && *e && ISFIRSTCHAR (*e))
3229 sb_add_char (acc, *e);
3234 ptr = hash_lookup (&keyword_hash_table, acc);
3239 /* This one causes lots of pain when trying to preprocess
3241 WARNING ((stderr, _("Unrecognised pseudo op `%s'.\n"), sb_name (acc)));
3245 if (ptr->value.i & LAB)
3246 { /* output the label */
3249 fprintf (outfile, "%s:\t", sb_name (&label));
3252 fprintf (outfile, "\t");
3255 if (mri && ptr->value.i == K_END)
3260 sb_add_buffer (&t, line->ptr + oidx, idx - oidx);
3261 fprintf (outfile, "\t%s", sb_name (&t));
3265 if (ptr->value.i & PROCESS)
3267 /* Polish the rest of the line before handling the pseudo op */
3269 strip_comments(line);
3272 process_assigns (idx, line, acc);
3274 change_base (0, acc, line);
3279 switch (ptr->value.i)
3295 switch (ptr->value.i)
3299 macro_init (1, mri, 0, exp_get_abs);
3308 ERROR ((stderr, _("ORG command not allowed.\n")));
3314 do_data (idx, line, 1);
3317 do_data (idx, line, 2);
3320 do_data (idx, line, 4);
3323 do_data (idx, line, 0);
3326 do_datab (idx, line);
3329 do_sdata (idx, line, 0);
3332 do_sdatab (idx, line);
3335 do_sdata (idx, line, 'c');
3338 do_sdata (idx, line, 'z');
3341 do_assign (0, 0, line);
3347 do_arepeat (idx, line);
3353 do_awhile (idx, line);
3359 do_assign (1, idx, line);
3362 do_align (idx, line);
3365 do_res (idx, line, 0);
3368 do_res (idx, line, 's');
3371 do_include (idx, line);
3374 do_local (idx, line);
3377 do_macro (idx, line);
3383 do_res (idx, line, 'c');
3386 do_print (idx, line);
3389 do_form (idx, line);
3392 do_heading (idx, line);
3404 do_res (idx, line, 'z');
3412 do_assigna (idx, line);
3415 do_assignc (idx, line);
3424 do_if (idx, line, EQ);
3427 do_if (idx, line, NE);
3430 do_if (idx, line, LT);
3433 do_if (idx, line, LE);
3436 do_if (idx, line, GE);
3439 do_if (idx, line, GT);
3442 do_ifc (idx, line, 0);
3445 do_ifc (idx, line, 1);
3448 do_irp (idx, line, 0);
3451 do_irp (idx, line, 1);
3461 /* Add a keyword to the hash table. */
3464 add_keyword (name, code)
3472 sb_add_string (&label, name);
3474 hash_add_to_int_table (&keyword_hash_table, &label, code);
3477 for (j = 0; name[j]; j++)
3478 sb_add_char (&label, name[j] - 'A' + 'a');
3479 hash_add_to_int_table (&keyword_hash_table, &label, code);
3484 /* Build the keyword hash table - put each keyword in the table twice,
3485 once upper and once lower case.*/
3492 for (i = 0; kinfo[i].name; i++)
3493 add_keyword (kinfo[i].name, kinfo[i].code);
3497 for (i = 0; mrikinfo[i].name; i++)
3498 add_keyword (mrikinfo[i].name, mrikinfo[i].code);
3522 sb_add_char (&value, *string);
3525 exp_get_abs (_("Invalid expression on command line.\n"), 0, &value, &res);
3529 sb_add_char (&label, *string);
3534 ptr = hash_create (&vars, &label);
3535 free_old_entry (ptr);
3536 ptr->type = hash_integer;
3542 /* The list of long options. */
3543 static struct option long_options[] =
3545 { "alternate", no_argument, 0, 'a' },
3546 { "include", required_argument, 0, 'I' },
3547 { "commentchar", required_argument, 0, 'c' },
3548 { "copysource", no_argument, 0, 's' },
3549 { "debug", no_argument, 0, 'd' },
3550 { "help", no_argument, 0, 'h' },
3551 { "mri", no_argument, 0, 'M' },
3552 { "output", required_argument, 0, 'o' },
3553 { "print", no_argument, 0, 'p' },
3554 { "unreasonable", no_argument, 0, 'u' },
3555 { "version", no_argument, 0, 'v' },
3556 { "define", required_argument, 0, 'd' },
3557 { NULL, no_argument, 0, 0 }
3560 /* Show a usage message and exit. */
3562 show_usage (file, status)
3568 [-a] [--alternate] enter alternate macro mode\n\
3569 [-c char] [--commentchar char] change the comment character from !\n\
3570 [-d] [--debug] print some debugging info\n\
3571 [-h] [--help] print this message\n\
3572 [-M] [--mri] enter MRI compatibility mode\n\
3573 [-o out] [--output out] set the output file\n\
3574 [-p] [--print] print line numbers\n"), program_name);
3576 [-s] [--copysource] copy source through as comments \n\
3577 [-u] [--unreasonable] allow unreasonable nesting\n\
3578 [-v] [--version] print the program version\n\
3579 [-Dname=value] create preprocessor variable called name, with value\n\
3580 [-Ipath] add to include path list\n\
3587 /* Display a help message and exit. */
3591 printf (_("%s: Gnu Assembler Macro Preprocessor\n"),
3593 show_usage (stdout, 0);
3608 #ifdef HAVE_SETLOCALE
3609 setlocale (LC_MESSAGES, "");
3611 bindtextdomain (PACKAGE, LOCALEDIR);
3612 textdomain (PACKAGE);
3614 program_name = argv[0];
3615 xmalloc_set_program_name (program_name);
3617 hash_new_table (101, &keyword_hash_table);
3618 hash_new_table (101, &assign_hash_table);
3619 hash_new_table (101, &vars);
3623 while ((opt = getopt_long (argc, argv, "I:sdhavc:upo:D:M", long_options,
3637 include_path *p = (include_path *) xmalloc (sizeof (include_path));
3640 sb_add_string (&p->path, optarg);
3642 paths_tail->next = p;
3649 print_line_number = 1;
3652 comment_char = optarg[0];
3674 /* This output is intended to follow the GNU standards document. */
3675 printf (_("GNU assembler pre-processor %s\n"), program_version);
3676 printf (_("Copyright 1996 Free Software Foundation, Inc.\n"));
3678 This program is free software; you may redistribute it under the terms of\n\
3679 the GNU General Public License. This program has absolutely no warranty.\n"));
3685 show_usage (stderr, 1);
3692 macro_init (alternate, mri, 0, exp_get_abs);
3695 outfile = fopen (out_name, "w");
3698 fprintf (stderr, _("%s: Can't open output file `%s'.\n"),
3699 program_name, out_name);
3711 /* Process all the input files */
3713 while (optind < argc)
3715 if (new_file (argv[optind]))
3721 fprintf (stderr, _("%s: Can't open input file `%s'.\n"),
3722 program_name, argv[optind]);
3732 /* This function is used because an abort in some of the other files
3733 may be compiled into as_abort because they include as.h. */
3736 as_abort (file, line, fn)
3737 const char *file, *fn;
3740 fprintf (stderr, _("Internal error, aborting at %s line %d"), file, line);
3742 fprintf (stderr, " in %s", fn);
3743 fprintf (stderr, _("\nPlease report this bug.\n"));