1 /* gasp.c - Gnu assembler preprocessor main program.
2 Copyright (C) 1994, 95, 96, 97, 98, 99, 2000
3 Free Software Foundation, Inc.
5 Written by Steve and Judy Chamberlain of Cygnus Support,
8 This file is part of GASP, the GNU Assembler Preprocessor.
10 GASP is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
15 GASP is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GASP; see the file COPYING. If not, write to the Free
22 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
27 This program translates the input macros and stuff into a form
28 suitable for gas to consume.
31 gasp [-sdhau] [-c char] [-o <outfile>] <infile>*
33 -s copy source to output
34 -c <char> comments are started with <char> instead of !
35 -u allow unreasonable stuff
37 -d print debugging stats
38 -s semi colons start comments
39 -a use alternate syntax
40 Pseudo ops can start with or without a .
41 Labels have to be in first column.
42 -I specify include dir
43 Macro arg parameters subsituted by name, don't need the &.
44 String can start with ' too.
45 Strings can be surrounded by <..>
46 A %<exp> in a string evaluates the expression
47 Literal char in a string with !
64 #ifdef NEED_MALLOC_DECLARATION
65 extern char *malloc ();
69 #include "libiberty.h"
74 char *program_version = "1.2";
76 /* This is normally declared in as.h, but we don't include that. We
77 need the function because other files linked with gasp.c might call
79 extern void as_abort PARAMS ((const char *, int, const char *));
81 /* The default obstack chunk size. If we set this to zero, the
82 obstack code will use whatever will fit in a 4096 byte block. This
83 is used by the hash table code used by macro.c. */
86 #define MAX_INCLUDES 30 /* Maximum include depth */
87 #define MAX_REASONABLE 1000 /* Maximum number of expansions */
89 int unreasonable; /* -u on command line */
90 int stats; /* -d on command line */
91 int print_line_number; /* -p flag on command line */
92 int copysource; /* -c flag on command line */
93 int warnings; /* Number of WARNINGs generated so far. */
94 int errors; /* Number of ERRORs generated so far. */
95 int fatals; /* Number of fatal ERRORs generated so far (either 0 or 1). */
96 int alternate = 0; /* -a on command line */
97 int mri = 0; /* -M on command line */
98 char comment_char = '!';
99 int radix = 10; /* Default radix */
101 int had_end; /* Seen .END */
103 /* The output stream */
106 /* the attributes of each character are stored as a bit pattern
107 chartype, which gives us quick tests. */
114 #define COMMENTBIT 16
116 #define ISCOMMENTCHAR(x) (chartype[(unsigned char)(x)] & COMMENTBIT)
117 #define ISFIRSTCHAR(x) (chartype[(unsigned char)(x)] & FIRSTBIT)
118 #define ISNEXTCHAR(x) (chartype[(unsigned char)(x)] & NEXTBIT)
119 #define ISSEP(x) (chartype[(unsigned char)(x)] & SEPBIT)
120 #define ISWHITE(x) (chartype[(unsigned char)(x)] & WHITEBIT)
121 #define ISBASE(x) (chartype[(unsigned char)(x)] & BASEBIT)
122 static char chartype[256];
125 /* Conditional assembly uses the `ifstack'. Each aif pushes another
126 entry onto the stack, and sets the on flag if it should. The aelse
127 sets hadelse, and toggles on. An aend pops a level. We limit to
128 100 levels of nesting, not because we're facists pigs with read
129 only minds, but because more than 100 levels of nesting is probably
130 a bug in the user's macro structure. */
132 #define IFNESTING 100
135 int on; /* is the level being output */
136 int hadelse; /* has an aelse been seen */
141 /* The final and intermediate results of expression evaluation are kept in
142 exp_t's. Note that a symbol is not an sb, but a pointer into the input
143 line. It must be coped somewhere safe before the next line is read in. */
154 int value; /* constant part */
155 symbol add_symbol; /* name part */
156 symbol sub_symbol; /* name part */
161 /* Hashing is done in a pretty standard way. A hash_table has a
162 pointer to a vector of pointers to hash_entrys, and the size of the
163 vector. A hash_entry contains a union of all the info we like to
164 store in hash table. If there is a hash collision, hash_entries
165 with the same hash are kept in a chain. */
167 /* What the data in a hash_entry means */
170 hash_integer, /* name->integer mapping */
171 hash_string, /* name->string mapping */
172 hash_macro, /* name is a macro */
173 hash_formal /* name is a formal argument */
178 sb key; /* symbol name */
179 hash_type type; /* symbol meaning */
184 struct macro_struct *m;
185 struct formal_struct *f;
187 struct hs *next; /* next hash_entry with same hash key */
197 /* how we nest files and expand macros etc.
199 we keep a stack of of include_stack structs. each include file
200 pushes a new level onto the stack. we keep an sb with a pushback
201 too. unget chars are pushed onto the pushback sb, getchars first
202 checks the pushback sb before reading from the input stream.
204 small things are expanded by adding the text of the item onto the
205 pushback sb. larger items are grown by pushing a new level and
206 allocating the entire pushback buf for the item. each time
207 something like a macro is expanded, the stack index is changed. we
208 can then perform an exitm by popping all entries off the stack with
209 the same stack index. if we're being reasonable, we can detect
210 recusive expansion by checking the index is reasonably small.
215 include_file, include_repeat, include_while, include_macro
220 sb pushback; /* current pushback stream */
221 int pushback_index; /* next char to read from stream */
222 FILE *handle; /* open file */
223 sb name; /* name of file */
224 int linecount; /* number of lines read so far */
226 int index; /* index of this layer */
228 include_stack[MAX_INCLUDES];
230 struct include_stack *sp;
231 #define isp (sp - include_stack)
233 /* Include file list */
235 typedef struct include_path
237 struct include_path *next;
241 include_path *paths_head;
242 include_path *paths_tail;
245 static void quit PARAMS ((void));
246 static void hash_new_table PARAMS ((int, hash_table *));
247 static int hash PARAMS ((sb *));
248 static hash_entry *hash_create PARAMS ((hash_table *, sb *));
249 static void hash_add_to_string_table PARAMS ((hash_table *, sb *, sb *, int));
250 static void hash_add_to_int_table PARAMS ((hash_table *, sb *, int));
251 static hash_entry *hash_lookup PARAMS ((hash_table *, sb *));
252 static void checkconst PARAMS ((int, exp_t *));
253 static int sb_strtol PARAMS ((int, sb *, int, int *));
254 static int level_0 PARAMS ((int, sb *, exp_t *));
255 static int level_1 PARAMS ((int, sb *, exp_t *));
256 static int level_2 PARAMS ((int, sb *, exp_t *));
257 static int level_3 PARAMS ((int, sb *, exp_t *));
258 static int level_4 PARAMS ((int, sb *, exp_t *));
259 static int level_5 PARAMS ((int, sb *, exp_t *));
260 static int exp_parse PARAMS ((int, sb *, exp_t *));
261 static void exp_string PARAMS ((exp_t *, sb *));
262 static int exp_get_abs PARAMS ((const char *, int, sb *, int *));
264 static void strip_comments PARAMS ((sb *));
266 static void unget PARAMS ((int));
267 static void include_buf PARAMS ((sb *, sb *, include_type, int));
268 static void include_print_where_line PARAMS ((FILE *));
269 static void include_print_line PARAMS ((FILE *));
270 static int get_line PARAMS ((sb *));
271 static int grab_label PARAMS ((sb *, sb *));
272 static void change_base PARAMS ((int, sb *, sb *));
273 static void do_end PARAMS ((sb *));
274 static void do_assign PARAMS ((int, int, sb *));
275 static void do_radix PARAMS ((sb *));
276 static int get_opsize PARAMS ((int, sb *, int *));
277 static int eol PARAMS ((int, sb *));
278 static void do_data PARAMS ((int, sb *, int));
279 static void do_datab PARAMS ((int, sb *));
280 static void do_align PARAMS ((int, sb *));
281 static void do_res PARAMS ((int, sb *, int));
282 static void do_export PARAMS ((sb *));
283 static void do_print PARAMS ((int, sb *));
284 static void do_heading PARAMS ((int, sb *));
285 static void do_page PARAMS ((void));
286 static void do_form PARAMS ((int, sb *));
287 static int get_any_string PARAMS ((int, sb *, sb *, int, int));
288 static int skip_openp PARAMS ((int, sb *));
289 static int skip_closep PARAMS ((int, sb *));
290 static int dolen PARAMS ((int, sb *, sb *));
291 static int doinstr PARAMS ((int, sb *, sb *));
292 static int dosubstr PARAMS ((int, sb *, sb *));
293 static void process_assigns PARAMS ((int, sb *, sb *));
294 static int get_and_process PARAMS ((int, sb *, sb *));
295 static void process_file PARAMS ((void));
296 static void free_old_entry PARAMS ((hash_entry *));
297 static void do_assigna PARAMS ((int, sb *));
298 static void do_assignc PARAMS ((int, sb *));
299 static void do_reg PARAMS ((int, sb *));
300 static int condass_lookup_name PARAMS ((sb *, int, sb *, int));
301 static int whatcond PARAMS ((int, sb *, int *));
302 static int istrue PARAMS ((int, sb *));
303 static void do_aif PARAMS ((int, sb *));
304 static void do_aelse PARAMS ((void));
305 static void do_aendi PARAMS ((void));
306 static int condass_on PARAMS ((void));
307 static void do_if PARAMS ((int, sb *, int));
308 static int get_mri_string PARAMS ((int, sb *, sb *, int));
309 static void do_ifc PARAMS ((int, sb *, int));
310 static void do_aendr PARAMS ((void));
311 static void do_awhile PARAMS ((int, sb *));
312 static void do_aendw PARAMS ((void));
313 static void do_exitm PARAMS ((void));
314 static void do_arepeat PARAMS ((int, sb *));
315 static void do_endm PARAMS ((void));
316 static void do_irp PARAMS ((int, sb *, int));
317 static void do_local PARAMS ((int, sb *));
318 static void do_macro PARAMS ((int, sb *));
319 static int macro_op PARAMS ((int, sb *));
320 static int getstring PARAMS ((int, sb *, sb *));
321 static void do_sdata PARAMS ((int, sb *, int));
322 static void do_sdatab PARAMS ((int, sb *));
323 static int new_file PARAMS ((const char *));
324 static void do_include PARAMS ((int, sb *));
325 static void include_pop PARAMS ((void));
326 static int get PARAMS ((void));
327 static int linecount PARAMS ((void));
328 static int include_next_index PARAMS ((void));
329 static void chartype_init PARAMS ((void));
330 static int process_pseudo_op PARAMS ((int, sb *, sb *));
331 static void add_keyword PARAMS ((const char *, int));
332 static void process_init PARAMS ((void));
333 static void do_define PARAMS ((const char *));
334 static void show_usage PARAMS ((FILE *, int));
335 static void show_help PARAMS ((void));
338 do { include_print_where_line (stderr); fprintf x ; fatals++; quit(); } while(0)
340 do { include_print_where_line (stderr); fprintf x; errors++; } while(0)
342 do { include_print_where_line (stderr); fprintf x; warnings++;} while(0)
346 /* exit the program and return the right ERROR code. */
359 for (i = 0; i < sb_max_power_two; i++)
361 fprintf (stderr, "strings size %8d : %d\n", 1<<i, string_count[i]);
367 /* hash table maintenance. */
369 /* build a new hash table with size buckets, and fill in the info at ptr. */
372 hash_new_table (size, ptr)
378 ptr->table = (hash_entry **) xmalloc (size * (sizeof (hash_entry *)));
379 /* Fill with null-pointer, not zero-bit-pattern. */
380 for (i = 0; i < size; i++)
384 /* calculate and return the hash value of the sb at key. */
393 for (i = 0; i < key->len; i++)
401 /* lookup key in hash_table tab, if present, then return it, otherwise
402 build a new one and fill it with hash_integer. */
406 hash_create (tab, key)
410 int k = hash (key) % tab->size;
412 hash_entry **table = tab->table;
420 hash_entry *n = (hash_entry *) xmalloc (sizeof (hash_entry));
423 sb_add_sb (&n->key, key);
425 n->type = hash_integer;
428 if (strncmp (table[k]->key.ptr, key->ptr, key->len) == 0)
436 /* add sb name with key into hash_table tab. if replacing old value
437 and again, then ERROR. */
441 hash_add_to_string_table (tab, key, name, again)
447 hash_entry *ptr = hash_create (tab, key);
448 if (ptr->type == hash_integer)
450 sb_new (&ptr->value.s);
452 if (ptr->value.s.len)
455 ERROR ((stderr, _("redefinition not allowed\n")));
458 ptr->type = hash_string;
459 sb_reset (&ptr->value.s);
461 sb_add_sb (&ptr->value.s, name);
464 /* add integer name to hash_table tab with sb key. */
468 hash_add_to_int_table (tab, key, name)
473 hash_entry *ptr = hash_create (tab, key);
477 /* lookup sb key in hash_table tab. if found return hash_entry result,
482 hash_lookup (tab, key)
486 int k = hash (key) % tab->size;
487 hash_entry **table = tab->table;
488 hash_entry *p = table[k];
491 if (p->key.len == key->len
492 && strncmp (p->key.ptr, key->ptr, key->len) == 0)
502 are handled in a really simple recursive decent way. each bit of
503 the machine takes an index into an sb and a pointer to an exp_t,
504 modifies the *exp_t and returns the index of the first character
505 past the part of the expression parsed.
507 expression precedence:
518 /* make sure that the exp_t at term is constant, if not the give the op ERROR. */
522 checkconst (op, term)
526 if (term->add_symbol.len
527 || term->sub_symbol.len)
529 ERROR ((stderr, _("the %c operator cannot take non-absolute arguments.\n"), op));
533 /* turn the number in string at idx into a number of base,
534 fill in ptr and return the index of the first character not in the
539 sb_strtol (idx, string, base, ptr)
546 idx = sb_skip_white (idx, string);
548 while (idx < string->len)
550 int ch = string->ptr[idx];
554 else if (ch >= 'a' && ch <= 'f')
556 else if (ch >= 'A' && ch <= 'F')
564 value = value * base + dig;
572 level_0 (idx, string, lhs)
577 lhs->add_symbol.len = 0;
578 lhs->add_symbol.name = 0;
580 lhs->sub_symbol.len = 0;
581 lhs->sub_symbol.name = 0;
583 idx = sb_skip_white (idx, string);
587 if (isdigit ((unsigned char) string->ptr[idx]))
589 idx = sb_strtol (idx, string, 10, &lhs->value);
591 else if (ISFIRSTCHAR (string->ptr[idx]))
594 lhs->add_symbol.name = string->ptr + idx;
595 while (idx < string->len && ISNEXTCHAR (string->ptr[idx]))
600 lhs->add_symbol.len = len;
602 else if (string->ptr[idx] == '"')
606 ERROR ((stderr, _("string where expression expected.\n")));
607 idx = getstring (idx, string, &acc);
612 ERROR ((stderr, _("can't find primary in expression.\n")));
615 return sb_skip_white (idx, string);
621 level_1 (idx, string, lhs)
626 idx = sb_skip_white (idx, string);
628 switch (string->ptr[idx])
631 idx = level_1 (idx + 1, string, lhs);
634 idx = level_1 (idx + 1, string, lhs);
635 checkconst ('~', lhs);
636 lhs->value = ~lhs->value;
641 idx = level_1 (idx + 1, string, lhs);
642 lhs->value = -lhs->value;
644 lhs->add_symbol = lhs->sub_symbol;
650 idx = level_5 (sb_skip_white (idx, string), string, lhs);
651 if (string->ptr[idx] != ')')
652 ERROR ((stderr, _("misplaced closing parens.\n")));
657 idx = level_0 (idx, string, lhs);
660 return sb_skip_white (idx, string);
664 level_2 (idx, string, lhs)
671 idx = level_1 (idx, string, lhs);
673 while (idx < string->len && (string->ptr[idx] == '*'
674 || string->ptr[idx] == '/'))
676 char op = string->ptr[idx++];
677 idx = level_1 (idx, string, &rhs);
681 checkconst ('*', lhs);
682 checkconst ('*', &rhs);
683 lhs->value *= rhs.value;
686 checkconst ('/', lhs);
687 checkconst ('/', &rhs);
689 ERROR ((stderr, _("attempt to divide by zero.\n")));
691 lhs->value /= rhs.value;
695 return sb_skip_white (idx, string);
700 level_3 (idx, string, lhs)
707 idx = level_2 (idx, string, lhs);
709 while (idx < string->len
710 && (string->ptr[idx] == '+'
711 || string->ptr[idx] == '-'))
713 char op = string->ptr[idx++];
714 idx = level_2 (idx, string, &rhs);
718 lhs->value += rhs.value;
719 if (lhs->add_symbol.name && rhs.add_symbol.name)
721 ERROR ((stderr, _("can't add two relocatable expressions\n")));
723 /* change nn+symbol to symbol + nn */
724 if (rhs.add_symbol.name)
726 lhs->add_symbol = rhs.add_symbol;
730 lhs->value -= rhs.value;
731 lhs->sub_symbol = rhs.add_symbol;
735 return sb_skip_white (idx, string);
739 level_4 (idx, string, lhs)
746 idx = level_3 (idx, string, lhs);
748 while (idx < string->len &&
749 string->ptr[idx] == '&')
751 char op = string->ptr[idx++];
752 idx = level_3 (idx, string, &rhs);
756 checkconst ('&', lhs);
757 checkconst ('&', &rhs);
758 lhs->value &= rhs.value;
762 return sb_skip_white (idx, string);
766 level_5 (idx, string, lhs)
773 idx = level_4 (idx, string, lhs);
775 while (idx < string->len
776 && (string->ptr[idx] == '|' || string->ptr[idx] == '~'))
778 char op = string->ptr[idx++];
779 idx = level_4 (idx, string, &rhs);
783 checkconst ('|', lhs);
784 checkconst ('|', &rhs);
785 lhs->value |= rhs.value;
788 checkconst ('~', lhs);
789 checkconst ('~', &rhs);
790 lhs->value ^= rhs.value;
794 return sb_skip_white (idx, string);
798 /* parse the expression at offset idx into string, fill up res with
799 the result. return the index of the first char past the expression.
803 exp_parse (idx, string, res)
808 return level_5 (sb_skip_white (idx, string), string, res);
812 /* turn the expression at exp into text and glue it onto the end of
816 exp_string (exp, string)
824 if (exp->add_symbol.len)
826 sb_add_buffer (string, exp->add_symbol.name, exp->add_symbol.len);
834 sb_add_char (string, '+');
835 sprintf (buf, "%d", exp->value);
836 sb_add_string (string, buf);
840 if (exp->sub_symbol.len)
842 sb_add_char (string, '-');
843 sb_add_buffer (string, exp->add_symbol.name, exp->add_symbol.len);
849 sb_add_char (string, '0');
853 /* parse the expression at offset idx into sb in, return the value in val.
854 if the expression is not constant, give ERROR emsg. returns the index
855 of the first character past the end of the expression. */
858 exp_get_abs (emsg, idx, in, val)
865 idx = exp_parse (idx, in, &res);
866 if (res.add_symbol.len || res.sub_symbol.len)
867 ERROR ((stderr, "%s", emsg));
873 sb label; /* current label parsed from line */
874 hash_table assign_hash_table; /* hash table for all assigned variables */
875 hash_table keyword_hash_table; /* hash table for keyword */
876 hash_table vars; /* hash table for eq variables */
878 #define in_comment ';'
887 for (i = 0; i < out->len; i++)
889 if (ISCOMMENTCHAR(s[i]))
898 /* push back character ch so that it can be read again. */
908 if (sp->pushback_index)
909 sp->pushback_index--;
911 sb_add_char (&sp->pushback, ch);
914 /* push the sb ptr onto the include stack, with the given name, type and index. */
918 include_buf (name, ptr, type, index)
925 if (sp - include_stack >= MAX_INCLUDES)
926 FATAL ((stderr, _("unreasonable nesting.\n")));
928 sb_add_sb (&sp->name, name);
931 sp->pushback_index = 0;
934 sb_new (&sp->pushback);
935 sb_add_sb (&sp->pushback, ptr);
939 /* used in ERROR messages, print info on where the include stack is onto file. */
942 include_print_where_line (file)
945 struct include_stack *p = include_stack + 1;
949 fprintf (file, "%s:%d ", sb_name (&p->name), p->linecount - 1);
954 /* used in listings, print the line number onto file. */
956 include_print_line (file)
960 struct include_stack *p = include_stack + 1;
962 n = fprintf (file, "%4d", p->linecount);
966 n += fprintf (file, ".%d", p->linecount);
977 /* read a line from the top of the include stack into sb in. */
988 putc (comment_char, outfile);
989 if (print_line_number)
990 include_print_line (outfile);
1004 WARNING ((stderr, _("End of file not at start of line.\n")));
1006 putc ('\n', outfile);
1025 /* continued line */
1028 putc (comment_char, outfile);
1029 putc ('+', outfile);
1042 sb_add_char (in, ch);
1050 /* find a label from sb in and put it in out. */
1053 grab_label (in, out)
1059 if (ISFIRSTCHAR (in->ptr[i]) || in->ptr[i] == '\\')
1061 sb_add_char (out, in->ptr[i]);
1063 while ((ISNEXTCHAR (in->ptr[i])
1064 || in->ptr[i] == '\\'
1065 || in->ptr[i] == '&')
1068 sb_add_char (out, in->ptr[i]);
1075 /* find all strange base stuff and turn into decimal. also
1076 find all the other numbers and convert them from the default radix */
1079 change_base (idx, in, out)
1086 while (idx < in->len)
1088 if (in->ptr[idx] == '\\'
1089 && idx + 1 < in->len
1090 && in->ptr[idx + 1] == '(')
1093 while (idx < in->len
1094 && in->ptr[idx] != ')')
1096 sb_add_char (out, in->ptr[idx]);
1102 else if (idx < in->len - 1 && in->ptr[idx + 1] == '\'' && ! mri)
1106 switch (in->ptr[idx])
1125 ERROR ((stderr, _("Illegal base character %c.\n"), in->ptr[idx]));
1130 idx = sb_strtol (idx + 2, in, base, &value);
1131 sprintf (buffer, "%d", value);
1132 sb_add_string (out, buffer);
1134 else if (ISFIRSTCHAR (in->ptr[idx]))
1136 /* copy entire names through quickly */
1137 sb_add_char (out, in->ptr[idx]);
1139 while (idx < in->len && ISNEXTCHAR (in->ptr[idx]))
1141 sb_add_char (out, in->ptr[idx]);
1145 else if (isdigit ((unsigned char) in->ptr[idx]))
1148 /* all numbers must start with a digit, let's chew it and
1150 idx = sb_strtol (idx, in, radix, &value);
1151 sprintf (buffer, "%d", value);
1152 sb_add_string (out, buffer);
1154 /* skip all undigsested letters */
1155 while (idx < in->len && ISNEXTCHAR (in->ptr[idx]))
1157 sb_add_char (out, in->ptr[idx]);
1161 else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
1163 char tchar = in->ptr[idx];
1164 /* copy entire names through quickly */
1165 sb_add_char (out, in->ptr[idx]);
1167 while (idx < in->len && in->ptr[idx] != tchar)
1169 sb_add_char (out, in->ptr[idx]);
1175 /* nothing special, just pass it through */
1176 sb_add_char (out, in->ptr[idx]);
1190 fprintf (outfile, "%s\n", sb_name (in));
1196 do_assign (again, idx, in)
1201 /* stick label in symbol table with following value */
1206 idx = exp_parse (idx, in, &e);
1207 exp_string (&e, &acc);
1208 hash_add_to_string_table (&assign_hash_table, &label, &acc, again);
1213 /* .radix [b|q|d|h] */
1220 int idx = sb_skip_white (0, ptr);
1221 switch (ptr->ptr[idx])
1240 ERROR ((stderr, _("radix is %c must be one of b, q, d or h"), radix));
1245 /* Parse off a .b, .w or .l */
1248 get_opsize (idx, in, size)
1254 if (in->ptr[idx] == '.')
1258 switch (in->ptr[idx])
1276 ERROR ((stderr, _("size must be one of b, w or l, is %c.\n"), in->ptr[idx]));
1289 idx = sb_skip_white (idx, line);
1291 && ISCOMMENTCHAR(line->ptr[idx]))
1293 if (idx >= line->len)
1298 /* .data [.b|.w|.l] <data>*
1299 or d[bwl] <data>* */
1302 do_data (idx, in, size)
1308 char *opname = ".yikes!";
1314 idx = get_opsize (idx, in, &opsize);
1333 fprintf (outfile, "%s\t", opname);
1335 idx = sb_skip_white (idx, in);
1339 && in->ptr[idx] == '"')
1342 idx = getstring (idx, in, &acc);
1343 for (i = 0; i < acc.len; i++)
1346 fprintf(outfile,",");
1347 fprintf (outfile, "%d", acc.ptr[i]);
1352 while (!eol (idx, in))
1355 idx = exp_parse (idx, in, &e);
1356 exp_string (&e, &acc);
1357 sb_add_char (&acc, 0);
1358 fprintf (outfile, "%s", acc.ptr);
1359 if (idx < in->len && in->ptr[idx] == ',')
1361 fprintf (outfile, ",");
1367 sb_print_at (outfile, idx, in);
1368 fprintf (outfile, "\n");
1371 /* .datab [.b|.w|.l] <repeat>,<fill> */
1382 idx = get_opsize (idx, in, &opsize);
1384 idx = exp_get_abs (_("datab repeat must be constant.\n"), idx, in, &repeat);
1385 idx = sb_skip_comma (idx, in);
1386 idx = exp_get_abs (_("datab data must be absolute.\n"), idx, in, &fill);
1388 fprintf (outfile, ".fill\t%d,%d,%d\n", repeat, opsize, fill);
1398 int al, have_fill, fill;
1400 idx = exp_get_abs (_("align needs absolute expression.\n"), idx, in, &al);
1401 idx = sb_skip_white (idx, in);
1404 if (! eol (idx, in))
1406 idx = sb_skip_comma (idx, in);
1407 idx = exp_get_abs (_(".align needs absolute fill value.\n"), idx, in,
1412 fprintf (outfile, ".align %d", al);
1414 fprintf (outfile, ",%d", fill);
1415 fprintf (outfile, "\n");
1418 /* .res[.b|.w|.l] <size> */
1421 do_res (idx, in, type)
1429 idx = get_opsize (idx, in, &size);
1430 while (!eol(idx, in))
1432 idx = sb_skip_white (idx, in);
1433 if (in->ptr[idx] == ',')
1435 idx = exp_get_abs (_("res needs absolute expression for fill count.\n"), idx, in, &count);
1437 if (type == 'c' || type == 'z')
1440 fprintf (outfile, ".space %d\n", count * size);
1451 fprintf (outfile, ".global %s\n", sb_name (in));
1454 /* .print [list] [nolist] */
1461 idx = sb_skip_white (idx, in);
1462 while (idx < in->len)
1464 if (strncasecmp (in->ptr + idx, "LIST", 4) == 0)
1466 fprintf (outfile, ".list\n");
1469 else if (strncasecmp (in->ptr + idx, "NOLIST", 6) == 0)
1471 fprintf (outfile, ".nolist\n");
1480 do_heading (idx, in)
1486 idx = getstring (idx, in, &head);
1487 fprintf (outfile, ".title \"%s\"\n", sb_name (&head));
1496 fprintf (outfile, ".eject\n");
1499 /* .form [lin=<value>] [col=<value>] */
1507 idx = sb_skip_white (idx, in);
1509 while (idx < in->len)
1512 if (strncasecmp (in->ptr + idx, "LIN=", 4) == 0)
1515 idx = exp_get_abs (_("form LIN= needs absolute expresssion.\n"), idx, in, &lines);
1518 if (strncasecmp (in->ptr + idx, _("COL="), 4) == 0)
1521 idx = exp_get_abs (_("form COL= needs absolute expresssion.\n"), idx, in, &columns);
1526 fprintf (outfile, ".psize %d,%d\n", lines, columns);
1531 /* Fetch string from the input stream,
1533 'Bxyx<whitespace> -> return 'Bxyza
1534 %<char> -> return string of decimal value of x
1535 "<string>" -> return string
1536 xyx<whitespace> -> return xyz
1539 get_any_string (idx, in, out, expand, pretend_quoted)
1547 idx = sb_skip_white (idx, in);
1551 if (in->len > 2 && in->ptr[idx+1] == '\'' && ISBASE (in->ptr[idx]))
1553 while (!ISSEP (in->ptr[idx]))
1554 sb_add_char (out, in->ptr[idx++]);
1556 else if (in->ptr[idx] == '%'
1562 /* Turns the next expression into a string */
1563 idx = exp_get_abs (_("% operator needs absolute expression"),
1567 sprintf(buf, "%d", val);
1568 sb_add_string (out, buf);
1570 else if (in->ptr[idx] == '"'
1571 || in->ptr[idx] == '<'
1572 || (alternate && in->ptr[idx] == '\''))
1574 if (alternate && expand)
1576 /* Keep the quotes */
1577 sb_add_char (out, '\"');
1579 idx = getstring (idx, in, out);
1580 sb_add_char (out, '\"');
1584 idx = getstring (idx, in, out);
1589 while (idx < in->len
1590 && (in->ptr[idx] == '"'
1591 || in->ptr[idx] == '\''
1593 || !ISSEP (in->ptr[idx])))
1595 if (in->ptr[idx] == '"'
1596 || in->ptr[idx] == '\'')
1598 char tchar = in->ptr[idx];
1599 sb_add_char (out, in->ptr[idx++]);
1600 while (idx < in->len
1601 && in->ptr[idx] != tchar)
1602 sb_add_char (out, in->ptr[idx++]);
1606 sb_add_char (out, in->ptr[idx++]);
1615 /* skip along sb in starting at idx, suck off whitespace a ( and more
1616 whitespace. return the idx of the next char */
1619 skip_openp (idx, in)
1623 idx = sb_skip_white (idx, in);
1624 if (in->ptr[idx] != '(')
1625 ERROR ((stderr, _("misplaced ( .\n")));
1626 idx = sb_skip_white (idx + 1, in);
1630 /* skip along sb in starting at idx, suck off whitespace a ) and more
1631 whitespace. return the idx of the next char */
1634 skip_closep (idx, in)
1638 idx = sb_skip_white (idx, in);
1639 if (in->ptr[idx] != ')')
1640 ERROR ((stderr, _("misplaced ).\n")));
1641 idx = sb_skip_white (idx + 1, in);
1648 dolen (idx, in, out)
1657 sb_new (&stringout);
1658 idx = skip_openp (idx, in);
1659 idx = get_and_process (idx, in, &stringout);
1660 idx = skip_closep (idx, in);
1661 sprintf (buffer, "%d", stringout.len);
1662 sb_add_string (out, buffer);
1664 sb_kill (&stringout);
1673 doinstr (idx, in, out)
1687 idx = skip_openp (idx, in);
1688 idx = get_and_process (idx, in, &string);
1689 idx = sb_skip_comma (idx, in);
1690 idx = get_and_process (idx, in, &search);
1691 idx = sb_skip_comma (idx, in);
1692 if (isdigit ((unsigned char) in->ptr[idx]))
1694 idx = exp_get_abs (_(".instr needs absolute expresson.\n"), idx, in, &start);
1700 idx = skip_closep (idx, in);
1702 for (i = start; i < string.len; i++)
1704 if (strncmp (string.ptr + i, search.ptr, search.len) == 0)
1710 sprintf (buffer, "%d", res);
1711 sb_add_string (out, buffer);
1719 dosubstr (idx, in, out)
1729 idx = skip_openp (idx, in);
1730 idx = get_and_process (idx, in, &string);
1731 idx = sb_skip_comma (idx, in);
1732 idx = exp_get_abs (_("need absolute position.\n"), idx, in, &pos);
1733 idx = sb_skip_comma (idx, in);
1734 idx = exp_get_abs (_("need absolute length.\n"), idx, in, &len);
1735 idx = skip_closep (idx, in);
1738 if (len < 0 || pos < 0 ||
1740 || pos + len > string.len)
1742 sb_add_string (out, " ");
1746 sb_add_char (out, '"');
1749 sb_add_char (out, string.ptr[pos++]);
1752 sb_add_char (out, '"');
1758 /* scan line, change tokens in the hash table to their replacements */
1760 process_assigns (idx, in, buf)
1765 while (idx < in->len)
1768 if (in->ptr[idx] == '\\'
1769 && idx + 1 < in->len
1770 && in->ptr[idx + 1] == '(')
1774 sb_add_char (buf, in->ptr[idx]);
1777 while (idx < in->len && in->ptr[idx - 1] != ')');
1779 else if (in->ptr[idx] == '\\'
1780 && idx + 1 < in->len
1781 && in->ptr[idx + 1] == '&')
1783 idx = condass_lookup_name (in, idx + 2, buf, 1);
1785 else if (in->ptr[idx] == '\\'
1786 && idx + 1 < in->len
1787 && in->ptr[idx + 1] == '$')
1789 idx = condass_lookup_name (in, idx + 2, buf, 0);
1791 else if (idx + 3 < in->len
1792 && in->ptr[idx] == '.'
1793 && toupper ((unsigned char) in->ptr[idx + 1]) == 'L'
1794 && toupper ((unsigned char) in->ptr[idx + 2]) == 'E'
1795 && toupper ((unsigned char) in->ptr[idx + 3]) == 'N')
1796 idx = dolen (idx + 4, in, buf);
1797 else if (idx + 6 < in->len
1798 && in->ptr[idx] == '.'
1799 && toupper ((unsigned char) in->ptr[idx + 1]) == 'I'
1800 && toupper ((unsigned char) in->ptr[idx + 2]) == 'N'
1801 && toupper ((unsigned char) in->ptr[idx + 3]) == 'S'
1802 && toupper ((unsigned char) in->ptr[idx + 4]) == 'T'
1803 && toupper ((unsigned char) in->ptr[idx + 5]) == 'R')
1804 idx = doinstr (idx + 6, in, buf);
1805 else if (idx + 7 < in->len
1806 && in->ptr[idx] == '.'
1807 && toupper ((unsigned char) in->ptr[idx + 1]) == 'S'
1808 && toupper ((unsigned char) in->ptr[idx + 2]) == 'U'
1809 && toupper ((unsigned char) in->ptr[idx + 3]) == 'B'
1810 && toupper ((unsigned char) in->ptr[idx + 4]) == 'S'
1811 && toupper ((unsigned char) in->ptr[idx + 5]) == 'T'
1812 && toupper ((unsigned char) in->ptr[idx + 6]) == 'R')
1813 idx = dosubstr (idx + 7, in, buf);
1814 else if (ISFIRSTCHAR (in->ptr[idx]))
1816 /* may be a simple name subsitution, see if we have a word */
1819 while (cur < in->len
1820 && (ISNEXTCHAR (in->ptr[cur])))
1824 sb_add_buffer (&acc, in->ptr + idx, cur - idx);
1825 ptr = hash_lookup (&assign_hash_table, &acc);
1828 /* Found a definition for it */
1829 sb_add_sb (buf, &ptr->value.s);
1833 /* No definition, just copy the word */
1834 sb_add_sb (buf, &acc);
1841 sb_add_char (buf, in->ptr[idx++]);
1847 get_and_process (idx, in, out)
1854 idx = get_any_string (idx, in, &t, 1, 0);
1855 process_assigns (0, &t, out);
1876 more = get_line (&line);
1879 /* Find any label and pseudo op that we're intested in */
1884 fprintf (outfile, "\n");
1887 && (line.ptr[0] == '*'
1888 || line.ptr[0] == '!'))
1890 /* MRI line comment. */
1891 fprintf (outfile, "%s", sb_name (&line));
1895 l = grab_label (&line, &label_in);
1898 if (line.ptr[l] == ':')
1900 while (ISWHITE (line.ptr[l]) && l < line.len)
1907 /* Munge the label, unless this is EQU or ASSIGN. */
1910 && (line.ptr[l] == '.' || alternate || mri))
1914 if (line.ptr[lx] == '.')
1916 if (lx + 3 <= line.len
1917 && strncasecmp ("EQU", line.ptr + lx, 3) == 0
1918 && (lx + 3 == line.len
1919 || ! ISFIRSTCHAR (line.ptr[lx + 3])))
1921 else if (lx + 6 <= line.len
1922 && strncasecmp ("ASSIGN", line.ptr + lx, 6) == 0
1923 && (lx + 6 == line.len
1924 || ! ISFIRSTCHAR (line.ptr[lx + 6])))
1929 process_assigns (0, &label_in, &label);
1931 sb_add_sb (&label, &label_in);
1936 if (process_pseudo_op (l, &line, &acc))
1942 else if (condass_on ())
1944 if (macro_op (l, &line))
1954 fprintf (outfile, "%s:\t", sb_name (&label));
1957 fprintf (outfile, "\t");
1959 process_assigns (l, &line, &t1);
1961 change_base (0, &t1, &t2);
1962 fprintf (outfile, "%s\n", sb_name (&t2));
1968 /* Only a label on this line */
1969 if (label.len && condass_on())
1971 fprintf (outfile, "%s:\n", sb_name (&label));
1979 more = get_line (&line);
1982 if (!had_end && !mri)
1983 WARNING ((stderr, _("END missing from end of file.\n")));
1991 free_old_entry (ptr)
1996 if (ptr->type == hash_string)
1997 sb_kill(&ptr->value.s);
2001 /* name: .ASSIGNA <value> */
2004 do_assigna (idx, in)
2012 process_assigns (idx, in, &tmp);
2013 idx = exp_get_abs (_(".ASSIGNA needs constant expression argument.\n"), 0, &tmp, &val);
2017 ERROR ((stderr, _(".ASSIGNA without label.\n")));
2021 hash_entry *ptr = hash_create (&vars, &label);
2022 free_old_entry (ptr);
2023 ptr->type = hash_integer;
2029 /* name: .ASSIGNC <string> */
2032 do_assignc (idx, in)
2038 idx = getstring (idx, in, &acc);
2042 ERROR ((stderr, _(".ASSIGNS without label.\n")));
2046 hash_entry *ptr = hash_create (&vars, &label);
2047 free_old_entry (ptr);
2048 ptr->type = hash_string;
2049 sb_new (&ptr->value.s);
2050 sb_add_sb (&ptr->value.s, &acc);
2056 /* name: .REG (reg) */
2063 /* remove reg stuff from inside parens */
2066 idx = skip_openp (idx, in);
2068 idx = sb_skip_white (idx, in);
2070 while (idx < in->len
2073 : in->ptr[idx] != ')'))
2075 sb_add_char (&what, in->ptr[idx]);
2078 hash_add_to_string_table (&assign_hash_table, &label, &what, 1);
2084 condass_lookup_name (inbuf, idx, out, warn)
2092 sb_new (&condass_acc);
2094 while (idx < inbuf->len
2095 && ISNEXTCHAR (inbuf->ptr[idx]))
2097 sb_add_char (&condass_acc, inbuf->ptr[idx++]);
2100 if (inbuf->ptr[idx] == '\'')
2102 ptr = hash_lookup (&vars, &condass_acc);
2109 WARNING ((stderr, _("Can't find preprocessor variable %s.\n"), sb_name (&condass_acc)));
2113 sb_add_string (out, "0");
2118 if (ptr->type == hash_integer)
2121 sprintf (buffer, "%d", ptr->value.i);
2122 sb_add_string (out, buffer);
2126 sb_add_sb (out, &ptr->value.s);
2129 sb_kill (&condass_acc);
2142 whatcond (idx, in, val)
2149 idx = sb_skip_white (idx, in);
2151 if (idx + 1 < in->len)
2157 a = toupper ((unsigned char) p[0]);
2158 b = toupper ((unsigned char) p[1]);
2159 if (a == 'E' && b == 'Q')
2161 else if (a == 'N' && b == 'E')
2163 else if (a == 'L' && b == 'T')
2165 else if (a == 'L' && b == 'E')
2167 else if (a == 'G' && b == 'T')
2169 else if (a == 'G' && b == 'E')
2174 ERROR ((stderr, _("Comparison operator must be one of EQ, NE, LT, LE, GT or GE.\n")));
2177 idx = sb_skip_white (idx + 2, in);
2194 idx = sb_skip_white (idx, in);
2196 if (in->ptr[idx] == '"')
2200 /* This is a string comparision */
2201 idx = getstring (idx, in, &acc_a);
2202 idx = whatcond (idx, in, &cond);
2203 idx = getstring (idx, in, &acc_b);
2204 same = acc_a.len == acc_b.len && (strncmp (acc_a.ptr, acc_b.ptr, acc_a.len) == 0);
2206 if (cond != EQ && cond != NE)
2208 ERROR ((stderr, _("Comparison operator for strings must be EQ or NE\n")));
2212 res = (cond != EQ) ^ same;
2215 /* This is a numeric expression */
2220 idx = exp_get_abs (_("Conditional operator must have absolute operands.\n"), idx, in, &vala);
2221 idx = whatcond (idx, in, &cond);
2222 idx = sb_skip_white (idx, in);
2223 if (in->ptr[idx] == '"')
2225 WARNING ((stderr, _("String compared against expression.\n")));
2230 idx = exp_get_abs (_("Conditional operator must have absolute operands.\n"), idx, in, &valb);
2273 if (ifi >= IFNESTING)
2275 FATAL ((stderr, _("AIF nesting unreasonable.\n")));
2278 ifstack[ifi].on = ifstack[ifi-1].on ? istrue (idx, in) : 0;
2279 ifstack[ifi].hadelse = 0;
2287 ifstack[ifi].on = ifstack[ifi-1].on ? !ifstack[ifi].on : 0;
2288 if (ifstack[ifi].hadelse)
2290 ERROR ((stderr, _("Multiple AELSEs in AIF.\n")));
2292 ifstack[ifi].hadelse = 1;
2306 ERROR ((stderr, _("AENDI without AIF.\n")));
2313 return ifstack[ifi].on;
2316 /* MRI IFEQ, IFNE, IFLT, IFLE, IFGE, IFGT. */
2319 do_if (idx, in, cond)
2327 if (ifi >= IFNESTING)
2329 FATAL ((stderr, _("IF nesting unreasonable.\n")));
2332 idx = exp_get_abs (_("Conditional operator must have absolute operands.\n"),
2337 case EQ: res = val == 0; break;
2338 case NE: res = val != 0; break;
2339 case LT: res = val < 0; break;
2340 case LE: res = val <= 0; break;
2341 case GE: res = val >= 0; break;
2342 case GT: res = val > 0; break;
2346 ifstack[ifi].on = ifstack[ifi-1].on ? res: 0;
2347 ifstack[ifi].hadelse = 0;
2350 /* Get a string for the MRI IFC or IFNC pseudo-ops. */
2353 get_mri_string (idx, in, val, terminator)
2359 idx = sb_skip_white (idx, in);
2362 && in->ptr[idx] == '\'')
2364 sb_add_char (val, '\'');
2365 for (++idx; idx < in->len; ++idx)
2367 sb_add_char (val, in->ptr[idx]);
2368 if (in->ptr[idx] == '\'')
2372 || in->ptr[idx] != '\'')
2376 idx = sb_skip_white (idx, in);
2382 while (idx < in->len
2383 && in->ptr[idx] != terminator)
2385 sb_add_char (val, in->ptr[idx]);
2389 while (i >= 0 && ISWHITE (val->ptr[i]))
2397 /* MRI IFC, IFNC. */
2400 do_ifc (idx, in, ifnc)
2409 if (ifi >= IFNESTING)
2411 FATAL ((stderr, _("IF nesting unreasonable.\n")));
2417 idx = get_mri_string (idx, in, &first, ',');
2419 if (idx >= in->len || in->ptr[idx] != ',')
2421 ERROR ((stderr, _("Bad format for IF or IFNC.\n")));
2425 idx = get_mri_string (idx + 1, in, &second, ';');
2427 res = (first.len == second.len
2428 && strncmp (first.ptr, second.ptr, first.len) == 0);
2432 ifstack[ifi].on = ifstack[ifi-1].on ? res : 0;
2433 ifstack[ifi].hadelse = 0;
2441 ERROR ((stderr, _("AENDR without a AREPEAT.\n")));
2443 ERROR ((stderr, _("ENDR without a REPT.\n")));
2454 int line = linecount ();
2462 process_assigns (idx, in, &exp);
2463 doit = istrue (0, &exp);
2465 if (! buffer_and_nest ("AWHILE", "AENDW", &sub, get_line))
2466 FATAL ((stderr, _("AWHILE without a AENDW at %d.\n"), line - 1));
2481 int index = include_next_index ();
2485 sb_add_sb (©, &sub);
2486 sb_add_sb (©, in);
2487 sb_add_string (©, "\n");
2488 sb_add_sb (©, &sub);
2489 sb_add_string (©, "\t.AENDW\n");
2490 /* Push another WHILE */
2491 include_buf (&exp, ©, include_while, index);
2504 ERROR ((stderr, _("AENDW without a AENDW.\n")));
2510 Pop things off the include stack until the type and index changes */
2515 include_type type = sp->type;
2516 if (type == include_repeat
2517 || type == include_while
2518 || type == include_macro)
2520 int index = sp->index;
2522 while (sp->index == index
2523 && sp->type == type)
2533 do_arepeat (idx, in)
2537 int line = linecount ();
2538 sb exp; /* buffer with expression in it */
2539 sb copy; /* expanded repeat block */
2540 sb sub; /* contents of AREPEAT */
2548 process_assigns (idx, in, &exp);
2549 idx = exp_get_abs (_("AREPEAT must have absolute operand.\n"), 0, &exp, &rc);
2551 ret = buffer_and_nest ("AREPEAT", "AENDR", &sub, get_line);
2553 ret = buffer_and_nest ("REPT", "ENDR", &sub, get_line);
2555 FATAL ((stderr, _("AREPEAT without a AENDR at %d.\n"), line - 1));
2558 /* Push back the text following the repeat, and another repeat block
2569 int index = include_next_index ();
2570 sb_add_sb (©, &sub);
2574 sprintf (buffer, "\t.AREPEAT %d\n", rc - 1);
2576 sprintf (buffer, "\tREPT %d\n", rc - 1);
2577 sb_add_string (©, buffer);
2578 sb_add_sb (©, &sub);
2580 sb_add_string (©, " .AENDR\n");
2582 sb_add_string (©, " ENDR\n");
2585 include_buf (&exp, ©, include_repeat, index);
2597 ERROR ((stderr, _(".ENDM without a matching .MACRO.\n")));
2600 /* MRI IRP pseudo-op. */
2603 do_irp (idx, in, irpc)
2613 err = expand_irp (irpc, idx, in, &out, get_line, comment_char);
2615 ERROR ((stderr, "%s\n", err));
2617 fprintf (outfile, "%s", sb_terminate (&out));
2622 /* MACRO PROCESSING */
2624 /* Parse off LOCAL n1, n2,... Invent a label name for it */
2627 do_local (idx, line)
2628 int idx ATTRIBUTE_UNUSED;
2629 sb *line ATTRIBUTE_UNUSED;
2631 ERROR ((stderr, _("LOCAL outside of MACRO")));
2640 int line = linecount ();
2642 err = define_macro (idx, in, &label, get_line, (const char **) NULL);
2644 ERROR ((stderr, _("macro at line %d: %s\n"), line - 1, err));
2656 if (! macro_defined)
2660 if (! check_macro (in->ptr + idx, &out, comment_char, &err, NULL))
2664 ERROR ((stderr, "%s\n", err));
2667 sb_add_string (&name, _("macro expansion"));
2669 include_buf (&name, &out, include_macro, include_next_index ());
2677 /* STRING HANDLING */
2680 getstring (idx, in, acc)
2685 idx = sb_skip_white (idx, in);
2687 while (idx < in->len
2688 && (in->ptr[idx] == '"'
2689 || in->ptr[idx] == '<'
2690 || (in->ptr[idx] == '\'' && alternate)))
2692 if (in->ptr[idx] == '<')
2694 if (alternate || mri)
2698 while ((in->ptr[idx] != '>' || nest)
2701 if (in->ptr[idx] == '!')
2704 sb_add_char (acc, in->ptr[idx++]);
2707 if (in->ptr[idx] == '>')
2709 if (in->ptr[idx] == '<')
2711 sb_add_char (acc, in->ptr[idx++]);
2719 idx = exp_get_abs (_("Character code in string must be absolute expression.\n"),
2721 sb_add_char (acc, code);
2723 if (in->ptr[idx] != '>')
2724 ERROR ((stderr, _("Missing > for character code.\n")));
2728 else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
2730 char tchar = in->ptr[idx];
2732 while (idx < in->len)
2734 if (alternate && in->ptr[idx] == '!')
2737 sb_add_char (acc, in->ptr[idx++]);
2740 if (in->ptr[idx] == tchar)
2743 if (idx >= in->len || in->ptr[idx] != tchar)
2746 sb_add_char (acc, in->ptr[idx]);
2756 /* .SDATA[C|Z] <string> */
2760 do_sdata (idx, in, type)
2769 fprintf (outfile, ".byte\t");
2771 while (!eol (idx, in))
2775 idx = sb_skip_white (idx, in);
2776 while (!eol (idx, in))
2778 pidx = idx = get_any_string (idx, in, &acc, 0, 1);
2783 ERROR ((stderr, _("string for SDATAC longer than 255 characters (%d).\n"), acc.len));
2785 fprintf (outfile, "%d", acc.len);
2789 for (i = 0; i < acc.len; i++)
2793 fprintf (outfile, ",");
2795 fprintf (outfile, "%d", acc.ptr[i]);
2802 fprintf (outfile, ",");
2803 fprintf (outfile, "0");
2805 idx = sb_skip_comma (idx, in);
2806 if (idx == pidx) break;
2808 if (!alternate && in->ptr[idx] != ',' && idx != in->len)
2810 fprintf (outfile, "\n");
2811 ERROR ((stderr, _("illegal character in SDATA line (0x%x).\n"), in->ptr[idx]));
2817 fprintf (outfile, "\n");
2820 /* .SDATAB <count> <string> */
2832 idx = exp_get_abs (_("Must have absolute SDATAB repeat count.\n"), idx, in, &repeat);
2835 ERROR ((stderr, _("Must have positive SDATAB repeat count (%d).\n"), repeat));
2839 idx = sb_skip_comma (idx, in);
2840 idx = getstring (idx, in, &acc);
2842 for (i = 0; i < repeat; i++)
2845 fprintf (outfile, "\t");
2846 fprintf (outfile, ".byte\t");
2847 sb_print (outfile, &acc);
2848 fprintf (outfile, "\n");
2858 FILE *newone = fopen (name, "r");
2862 if (isp == MAX_INCLUDES)
2863 FATAL ((stderr, _("Unreasonable include depth (%ld).\n"), (long) isp));
2866 sp->handle = newone;
2869 sb_add_string (&sp->name, name);
2872 sp->pushback_index = 0;
2873 sp->type = include_file;
2875 sb_new (&sp->pushback);
2880 do_include (idx, in)
2886 include_path *includes;
2892 idx = getstring (idx, in, &t);
2895 idx = sb_skip_white (idx, in);
2896 while (idx < in->len && ! ISWHITE (in->ptr[idx]))
2898 sb_add_char (&t, in->ptr[idx]);
2903 for (includes = paths_head; includes; includes = includes->next)
2906 sb_add_sb (&cat, &includes->path);
2907 sb_add_char (&cat, '/');
2908 sb_add_sb (&cat, &t);
2909 if (new_file (sb_name (&cat)))
2916 if (! new_file (sb_name (&t)))
2917 FATAL ((stderr, _("Can't open include file `%s'.\n"), sb_name (&t)));
2926 if (sp != include_stack)
2929 fclose (sp->handle);
2934 /* Get the next character from the include stack. If there's anything
2935 in the pushback buffer, take that first. If we're at eof, pop from
2936 the stack and try again. Keep the linecount up to date. */
2943 if (sp->pushback.len != sp->pushback_index)
2945 r = (char) (sp->pushback.ptr[sp->pushback_index++]);
2946 /* When they've all gone, reset the pointer */
2947 if (sp->pushback_index == sp->pushback.len)
2949 sp->pushback.len = 0;
2950 sp->pushback_index = 0;
2953 else if (sp->handle)
2955 r = getc (sp->handle);
2960 if (r == EOF && isp)
2964 while (r == EOF && isp)
2982 return sp->linecount;
2986 include_next_index ()
2990 && index > MAX_REASONABLE)
2991 FATAL ((stderr, _("Unreasonable expansion (-u turns off check).\n")));
2996 /* Initialize the chartype vector. */
3002 for (x = 0; x < 256; x++)
3004 if (isalpha (x) || x == '_' || x == '$')
3005 chartype[x] |= FIRSTBIT;
3007 if (mri && x == '.')
3008 chartype[x] |= FIRSTBIT;
3010 if (isdigit (x) || isalpha (x) || x == '_' || x == '$')
3011 chartype[x] |= NEXTBIT;
3013 if (x == ' ' || x == '\t' || x == ',' || x == '"' || x == ';'
3014 || x == '"' || x == '<' || x == '>' || x == ')' || x == '(')
3015 chartype[x] |= SEPBIT;
3017 if (x == 'b' || x == 'B'
3018 || x == 'q' || x == 'Q'
3019 || x == 'h' || x == 'H'
3020 || x == 'd' || x == 'D')
3021 chartype [x] |= BASEBIT;
3023 if (x == ' ' || x == '\t')
3024 chartype[x] |= WHITEBIT;
3026 if (x == comment_char)
3027 chartype[x] |= COMMENTBIT;
3033 /* What to do with all the keywords */
3034 #define PROCESS 0x1000 /* Run substitution over the line */
3035 #define LAB 0x2000 /* Spit out the label */
3037 #define K_EQU (PROCESS|1)
3038 #define K_ASSIGN (PROCESS|2)
3039 #define K_REG (PROCESS|3)
3040 #define K_ORG (PROCESS|4)
3041 #define K_RADIX (PROCESS|5)
3042 #define K_DATA (LAB|PROCESS|6)
3043 #define K_DATAB (LAB|PROCESS|7)
3044 #define K_SDATA (LAB|PROCESS|8)
3045 #define K_SDATAB (LAB|PROCESS|9)
3046 #define K_SDATAC (LAB|PROCESS|10)
3047 #define K_SDATAZ (LAB|PROCESS|11)
3048 #define K_RES (LAB|PROCESS|12)
3049 #define K_SRES (LAB|PROCESS|13)
3050 #define K_SRESC (LAB|PROCESS|14)
3051 #define K_SRESZ (LAB|PROCESS|15)
3052 #define K_EXPORT (LAB|PROCESS|16)
3053 #define K_GLOBAL (LAB|PROCESS|17)
3054 #define K_PRINT (LAB|PROCESS|19)
3055 #define K_FORM (LAB|PROCESS|20)
3056 #define K_HEADING (LAB|PROCESS|21)
3057 #define K_PAGE (LAB|PROCESS|22)
3058 #define K_IMPORT (LAB|PROCESS|23)
3059 #define K_PROGRAM (LAB|PROCESS|24)
3060 #define K_END (PROCESS|25)
3061 #define K_INCLUDE (PROCESS|26)
3062 #define K_IGNORED (PROCESS|27)
3063 #define K_ASSIGNA (PROCESS|28)
3064 #define K_ASSIGNC (29)
3065 #define K_AIF (PROCESS|30)
3066 #define K_AELSE (PROCESS|31)
3067 #define K_AENDI (PROCESS|32)
3068 #define K_AREPEAT (PROCESS|33)
3069 #define K_AENDR (PROCESS|34)
3070 #define K_AWHILE (35)
3071 #define K_AENDW (PROCESS|36)
3072 #define K_EXITM (37)
3073 #define K_MACRO (PROCESS|38)
3075 #define K_ALIGN (PROCESS|LAB|40)
3076 #define K_ALTERNATE (41)
3077 #define K_DB (LAB|PROCESS|42)
3078 #define K_DW (LAB|PROCESS|43)
3079 #define K_DL (LAB|PROCESS|44)
3080 #define K_LOCAL (45)
3081 #define K_IFEQ (PROCESS|46)
3082 #define K_IFNE (PROCESS|47)
3083 #define K_IFLT (PROCESS|48)
3084 #define K_IFLE (PROCESS|49)
3085 #define K_IFGE (PROCESS|50)
3086 #define K_IFGT (PROCESS|51)
3087 #define K_IFC (PROCESS|52)
3088 #define K_IFNC (PROCESS|53)
3089 #define K_IRP (PROCESS|54)
3090 #define K_IRPC (PROCESS|55)
3100 static struct keyword kinfo[] =
3102 { "EQU", K_EQU, 0 },
3103 { "ALTERNATE", K_ALTERNATE, 0 },
3104 { "ASSIGN", K_ASSIGN, 0 },
3105 { "REG", K_REG, 0 },
3106 { "ORG", K_ORG, 0 },
3107 { "RADIX", K_RADIX, 0 },
3108 { "DATA", K_DATA, 0 },
3112 { "DATAB", K_DATAB, 0 },
3113 { "SDATA", K_SDATA, 0 },
3114 { "SDATAB", K_SDATAB, 0 },
3115 { "SDATAZ", K_SDATAZ, 0 },
3116 { "SDATAC", K_SDATAC, 0 },
3117 { "RES", K_RES, 0 },
3118 { "SRES", K_SRES, 0 },
3119 { "SRESC", K_SRESC, 0 },
3120 { "SRESZ", K_SRESZ, 0 },
3121 { "EXPORT", K_EXPORT, 0 },
3122 { "GLOBAL", K_GLOBAL, 0 },
3123 { "PRINT", K_PRINT, 0 },
3124 { "FORM", K_FORM, 0 },
3125 { "HEADING", K_HEADING, 0 },
3126 { "PAGE", K_PAGE, 0 },
3127 { "PROGRAM", K_IGNORED, 0 },
3128 { "END", K_END, 0 },
3129 { "INCLUDE", K_INCLUDE, 0 },
3130 { "ASSIGNA", K_ASSIGNA, 0 },
3131 { "ASSIGNC", K_ASSIGNC, 0 },
3132 { "AIF", K_AIF, 0 },
3133 { "AELSE", K_AELSE, 0 },
3134 { "AENDI", K_AENDI, 0 },
3135 { "AREPEAT", K_AREPEAT, 0 },
3136 { "AENDR", K_AENDR, 0 },
3137 { "EXITM", K_EXITM, 0 },
3138 { "MACRO", K_MACRO, 0 },
3139 { "ENDM", K_ENDM, 0 },
3140 { "AWHILE", K_AWHILE, 0 },
3141 { "ALIGN", K_ALIGN, 0 },
3142 { "AENDW", K_AENDW, 0 },
3143 { "ALTERNATE", K_ALTERNATE, 0 },
3144 { "LOCAL", K_LOCAL, 0 },
3148 /* Although the conditional operators are handled by gas, we need to
3149 handle them here as well, in case they are used in a recursive
3150 macro to end the recursion. */
3152 static struct keyword mrikinfo[] =
3154 { "IFEQ", K_IFEQ, 0 },
3155 { "IFNE", K_IFNE, 0 },
3156 { "IFLT", K_IFLT, 0 },
3157 { "IFLE", K_IFLE, 0 },
3158 { "IFGE", K_IFGE, 0 },
3159 { "IFGT", K_IFGT, 0 },
3160 { "IFC", K_IFC, 0 },
3161 { "IFNC", K_IFNC, 0 },
3162 { "ELSEC", K_AELSE, 0 },
3163 { "ENDC", K_AENDI, 0 },
3164 { "MEXIT", K_EXITM, 0 },
3165 { "REPT", K_AREPEAT, 0 },
3166 { "IRP", K_IRP, 0 },
3167 { "IRPC", K_IRPC, 0 },
3168 { "ENDR", K_AENDR, 0 },
3172 /* Look for a pseudo op on the line. If one's there then call
3176 process_pseudo_op (idx, line, acc)
3183 if (line->ptr[idx] == '.' || alternate || mri)
3185 /* Scan forward and find pseudo name */
3191 if (line->ptr[idx] == '.')
3193 in = line->ptr + idx;
3198 while (idx < line->len && *e && ISFIRSTCHAR (*e))
3200 sb_add_char (acc, *e);
3205 ptr = hash_lookup (&keyword_hash_table, acc);
3210 /* This one causes lots of pain when trying to preprocess
3212 WARNING ((stderr, _("Unrecognised pseudo op `%s'.\n"), sb_name (acc)));
3216 if (ptr->value.i & LAB)
3217 { /* output the label */
3220 fprintf (outfile, "%s:\t", sb_name (&label));
3223 fprintf (outfile, "\t");
3226 if (mri && ptr->value.i == K_END)
3231 sb_add_buffer (&t, line->ptr + oidx, idx - oidx);
3232 fprintf (outfile, "\t%s", sb_name (&t));
3236 if (ptr->value.i & PROCESS)
3238 /* Polish the rest of the line before handling the pseudo op */
3240 strip_comments(line);
3243 process_assigns (idx, line, acc);
3245 change_base (0, acc, line);
3250 switch (ptr->value.i)
3266 switch (ptr->value.i)
3270 macro_init (1, mri, 0, exp_get_abs);
3279 ERROR ((stderr, _("ORG command not allowed.\n")));
3285 do_data (idx, line, 1);
3288 do_data (idx, line, 2);
3291 do_data (idx, line, 4);
3294 do_data (idx, line, 0);
3297 do_datab (idx, line);
3300 do_sdata (idx, line, 0);
3303 do_sdatab (idx, line);
3306 do_sdata (idx, line, 'c');
3309 do_sdata (idx, line, 'z');
3312 do_assign (0, 0, line);
3318 do_arepeat (idx, line);
3324 do_awhile (idx, line);
3330 do_assign (1, idx, line);
3333 do_align (idx, line);
3336 do_res (idx, line, 0);
3339 do_res (idx, line, 's');
3342 do_include (idx, line);
3345 do_local (idx, line);
3348 do_macro (idx, line);
3354 do_res (idx, line, 'c');
3357 do_print (idx, line);
3360 do_form (idx, line);
3363 do_heading (idx, line);
3375 do_res (idx, line, 'z');
3383 do_assigna (idx, line);
3386 do_assignc (idx, line);
3395 do_if (idx, line, EQ);
3398 do_if (idx, line, NE);
3401 do_if (idx, line, LT);
3404 do_if (idx, line, LE);
3407 do_if (idx, line, GE);
3410 do_if (idx, line, GT);
3413 do_ifc (idx, line, 0);
3416 do_ifc (idx, line, 1);
3419 do_irp (idx, line, 0);
3422 do_irp (idx, line, 1);
3432 /* Add a keyword to the hash table. */
3435 add_keyword (name, code)
3443 sb_add_string (&label, name);
3445 hash_add_to_int_table (&keyword_hash_table, &label, code);
3448 for (j = 0; name[j]; j++)
3449 sb_add_char (&label, name[j] - 'A' + 'a');
3450 hash_add_to_int_table (&keyword_hash_table, &label, code);
3455 /* Build the keyword hash table - put each keyword in the table twice,
3456 once upper and once lower case.*/
3463 for (i = 0; kinfo[i].name; i++)
3464 add_keyword (kinfo[i].name, kinfo[i].code);
3468 for (i = 0; mrikinfo[i].name; i++)
3469 add_keyword (mrikinfo[i].name, mrikinfo[i].code);
3493 sb_add_char (&value, *string);
3496 exp_get_abs (_("Invalid expression on command line.\n"), 0, &value, &res);
3500 sb_add_char (&label, *string);
3505 ptr = hash_create (&vars, &label);
3506 free_old_entry (ptr);
3507 ptr->type = hash_integer;
3513 /* The list of long options. */
3514 static struct option long_options[] =
3516 { "alternate", no_argument, 0, 'a' },
3517 { "include", required_argument, 0, 'I' },
3518 { "commentchar", required_argument, 0, 'c' },
3519 { "copysource", no_argument, 0, 's' },
3520 { "debug", no_argument, 0, 'd' },
3521 { "help", no_argument, 0, 'h' },
3522 { "mri", no_argument, 0, 'M' },
3523 { "output", required_argument, 0, 'o' },
3524 { "print", no_argument, 0, 'p' },
3525 { "unreasonable", no_argument, 0, 'u' },
3526 { "version", no_argument, 0, 'v' },
3527 { "define", required_argument, 0, 'd' },
3528 { NULL, no_argument, 0, 0 }
3531 /* Show a usage message and exit. */
3533 show_usage (file, status)
3539 [-a] [--alternate] enter alternate macro mode\n\
3540 [-c char] [--commentchar char] change the comment character from !\n\
3541 [-d] [--debug] print some debugging info\n\
3542 [-h] [--help] print this message\n\
3543 [-M] [--mri] enter MRI compatibility mode\n\
3544 [-o out] [--output out] set the output file\n\
3545 [-p] [--print] print line numbers\n"), program_name);
3547 [-s] [--copysource] copy source through as comments \n\
3548 [-u] [--unreasonable] allow unreasonable nesting\n\
3549 [-v] [--version] print the program version\n\
3550 [-Dname=value] create preprocessor variable called name, with value\n\
3551 [-Ipath] add to include path list\n\
3554 printf (_("Report bugs to %s\n"), REPORT_BUGS_TO);
3558 /* Display a help message and exit. */
3562 printf (_("%s: Gnu Assembler Macro Preprocessor\n"),
3564 show_usage (stdout, 0);
3579 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
3580 setlocale (LC_MESSAGES, "");
3582 bindtextdomain (PACKAGE, LOCALEDIR);
3583 textdomain (PACKAGE);
3585 program_name = argv[0];
3586 xmalloc_set_program_name (program_name);
3588 hash_new_table (101, &keyword_hash_table);
3589 hash_new_table (101, &assign_hash_table);
3590 hash_new_table (101, &vars);
3594 while ((opt = getopt_long (argc, argv, "I:sdhavc:upo:D:M", long_options,
3608 include_path *p = (include_path *) xmalloc (sizeof (include_path));
3611 sb_add_string (&p->path, optarg);
3613 paths_tail->next = p;
3620 print_line_number = 1;
3623 comment_char = optarg[0];
3645 /* This output is intended to follow the GNU standards document. */
3646 printf (_("GNU assembler pre-processor %s\n"), program_version);
3647 printf (_("Copyright 1996 Free Software Foundation, Inc.\n"));
3649 This program is free software; you may redistribute it under the terms of\n\
3650 the GNU General Public License. This program has absolutely no warranty.\n"));
3656 show_usage (stderr, 1);
3663 macro_init (alternate, mri, 0, exp_get_abs);
3666 outfile = fopen (out_name, "w");
3669 fprintf (stderr, _("%s: Can't open output file `%s'.\n"),
3670 program_name, out_name);
3682 /* Process all the input files */
3684 while (optind < argc)
3686 if (new_file (argv[optind]))
3692 fprintf (stderr, _("%s: Can't open input file `%s'.\n"),
3693 program_name, argv[optind]);
3703 /* This function is used because an abort in some of the other files
3704 may be compiled into as_abort because they include as.h. */
3707 as_abort (file, line, fn)
3708 const char *file, *fn;
3711 fprintf (stderr, _("Internal error, aborting at %s line %d"), file, line);
3713 fprintf (stderr, " in %s", fn);
3714 fprintf (stderr, _("\nPlease report this bug.\n"));