Sat Dec 12 15:26:34 1992 Ian Lance Taylor (ian@cygnus.com)
[platform/upstream/binutils.git] / gas / read.c
1 /* read.c - read a source file -
2    Copyright (C) 1986, 1987, 1990, 1991 Free Software Foundation, Inc.
3
4 This file is part of GAS, the GNU Assembler.
5
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING.  If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 #if 0
21 #define MASK_CHAR (0xFF)        /* If your chars aren't 8 bits, you will
22                                    change this a bit.  But then, GNU isn't
23                                    spozed to run on your machine anyway.
24                                    (RMS is so shortsighted sometimes.)
25                                    */
26 #else
27 #define MASK_CHAR ((int)(unsigned char)-1)
28 #endif
29
30 #define MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT (16)
31 /* This is the largest known floating point */
32 /* format (for now). It will grow when we */
33 /* do 4361 style flonums. */
34
35
36 /* Routines that read assembler source text to build spagetti in memory.
37    Another group of these functions is in the expr.c module.  */
38
39 #include <ctype.h>
40
41 #include "as.h"
42
43 #include "obstack.h"
44 #include "listing.h"
45
46 /* The NOP_OPCODE is for the alignment fill value.
47  * fill it a nop instruction so that the disassembler does not choke
48  * on it
49  */
50 #ifndef NOP_OPCODE
51 #define NOP_OPCODE 0x00
52 #endif
53
54 char *input_line_pointer;       /*->next char of source file to parse. */
55
56 #if BITS_PER_CHAR != 8
57 /*  The following table is indexed by[(char)] and will break if
58     a char does not have exactly 256 states (hopefully 0:255!)!  */
59 die horribly;
60 #endif
61
62 /* used by is_... macros. our ctype[] */
63 const char lex_type[256] =
64 {
65   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,       /* @ABCDEFGHIJKLMNO */
66   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,       /* PQRSTUVWXYZ[\]^_ */
67   0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,       /* _!"#$%&'()*+,-./ */
68   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,       /* 0123456789:;<=>? */
69   0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,       /* @ABCDEFGHIJKLMNO */
70   3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 3,       /* PQRSTUVWXYZ[\]^_ */
71   0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,       /* `abcdefghijklmno */
72   3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0,       /* pqrstuvwxyz{|}~. */
73   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
74   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
75   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
76   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
77   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
78   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
79   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
80 };
81
82
83 /*
84  * In: a character.
85  * Out: 1 if this character ends a line.
86  */
87 #define _ (0)
88 char is_end_of_line[256] =
89 {
90 #ifdef CR_EOL
91   _, _, _, _, _, _, _, _, _, _, 99, _, _, 99, _, _,     /* @abcdefghijklmno */
92 #else
93   _, _, _, _, _, _, _, _, _, _, 99, _, _, _, _, _,      /* @abcdefghijklmno */
94 #endif
95   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,       /* */
96   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,       /* */
97   _, _, _, _, _, _, _, _, _, _, _, 99, _, _, _, _,      /* 0123456789:;<=>? */
98   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,       /* */
99   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,       /* */
100   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,       /* */
101   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,       /* */
102   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,       /* */
103   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,       /* */
104   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,       /* */
105   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,       /* */
106   _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,       /* */
107 };
108 #undef _
109
110 /* Functions private to this file. */
111
112 static char *buffer;    /* 1st char of each buffer of lines is here. */
113 static char *buffer_limit;      /*->1 + last char in buffer. */
114
115 static char *bignum_low;        /* Lowest char of bignum. */
116 static char *bignum_limit;      /* 1st illegal address of bignum. */
117 static char *bignum_high;       /* Highest char of bignum. */
118 /* May point to (bignum_start-1). */
119 /* Never >= bignum_limit. */
120
121 static char *old_buffer = 0;    /* JF a hack */
122 static char *old_input;
123 static char *old_limit;
124
125 /* Variables for handling include file directory list. */
126
127 char **include_dirs;    /* List of pointers to directories to
128                            search for .include's */
129 int include_dir_count;  /* How many are in the list */
130 int include_dir_maxlen = 1;/* Length of longest in list */
131
132 #ifndef WORKING_DOT_WORD
133 struct broken_word *broken_words;
134 int new_broken_words = 0;
135 #endif
136
137 static char *demand_copy_string PARAMS ((int *lenP));
138 int is_it_end_of_statement PARAMS ((void));
139 unsigned int next_char_of_string PARAMS ((void));
140 static segT get_known_segmented_expression PARAMS ((expressionS * expP));
141 static void grow_bignum PARAMS ((void));
142 static void pobegin PARAMS ((void));
143 void stringer PARAMS ((int append_zero));
144
145 extern int listing;
146 \f
147
148 void
149 read_begin ()
150 {
151   const char *p;
152
153   pobegin ();
154   obj_read_begin_hook ();
155
156   obstack_begin (&notes, 5000);
157   obstack_begin (&cond_obstack, 960);
158
159 #define BIGNUM_BEGIN_SIZE (16)
160   bignum_low = xmalloc ((long) BIGNUM_BEGIN_SIZE);
161   bignum_limit = bignum_low + BIGNUM_BEGIN_SIZE;
162
163   /* Use machine dependent syntax */
164   for (p = line_separator_chars; *p; p++)
165     is_end_of_line[*p] = 1;
166   /* Use more.  FIXME-SOMEDAY. */
167 }
168 \f
169 /* set up pseudo-op tables */
170
171 struct hash_control *po_hash = NULL; /* use before set up: NULL->address error */
172
173 #ifdef DONTDEF
174 void s_gdbline (), s_gdblinetab ();
175 void s_gdbbeg (), s_gdbblock (), s_gdbend (), s_gdbsym ();
176 #endif
177
178 static const pseudo_typeS potable[] =
179 {
180   {"abort", s_abort, 0},
181   {"align", s_align_ptwo, 0},
182   {"ascii", stringer, 0},
183   {"asciz", stringer, 1},
184 /* block */
185   {"byte", cons, 1},
186   {"comm", s_comm, 0},
187   {"data", s_data, 0},
188 /* dim */
189   {"double", float_cons, 'd'},
190 /* dsect */
191   {"eject", listing_eject, 0},  /* Formfeed listing */
192   {"else", s_else, 0},
193   {"end", s_end, 0},
194   {"endif", s_endif, 0},
195 /* endef */
196   {"equ", s_set, 0},
197 /* err */
198 /* extend */
199   {"extern", s_ignore, 0},      /* We treat all undef as ext */
200   {"app-file", s_app_file, 0},
201   {"file", s_app_file, 0},
202   {"fill", s_fill, 0},
203   {"float", float_cons, 'f'},
204 #ifdef DONTDEF
205   {"gdbbeg", s_gdbbeg, 0},
206   {"gdbblock", s_gdbblock, 0},
207   {"gdbend", s_gdbend, 0},
208   {"gdbsym", s_gdbsym, 0},
209   {"gdbline", s_gdbline, 0},
210   {"gdblinetab", s_gdblinetab, 0},
211 #endif
212   {"global", s_globl, 0},
213   {"globl", s_globl, 0},
214   {"hword", cons, 2},
215   {"if", s_if, 0},
216   {"ifdef", s_ifdef, 0},
217   {"ifeqs", s_ifeqs, 0},
218   {"ifndef", s_ifdef, 1},
219   {"ifnes", s_ifeqs, 1},
220   {"ifnotdef", s_ifdef, 1},
221   {"include", s_include, 0},
222   {"int", cons, 4},
223   {"lcomm", s_lcomm, 0},
224   {"lflags", listing_flags, 0}, /* Listing flags */
225   {"list", listing_list, 1},    /* Turn listing on */
226   {"long", cons, 4},
227   {"lsym", s_lsym, 0},
228   {"nolist", listing_list, 0},  /* Turn listing off */
229   {"octa", big_cons, 16},
230   {"org", s_org, 0},
231   {"psize", listing_psize, 0},  /* set paper size */
232 /* print */
233   {"quad", big_cons, 8},
234   {"sbttl", listing_title, 1},  /* Subtitle of listing */
235 /* scl */
236 /* sect */
237   {"set", s_set, 0},
238   {"short", cons, 2},
239   {"single", float_cons, 'f'},
240 /* size */
241   {"space", s_space, 0},
242 /* tag */
243   {"text", s_text, 0},
244   {"title", listing_title, 0},  /* Listing title */
245 /* type */
246 /* use */
247 /* val */
248   {"word", cons, 2},
249   {NULL}                        /* end sentinel */
250 };
251
252 static void 
253 pobegin ()
254 {
255   char *errtxt;                 /* error text */
256   const pseudo_typeS *pop;
257
258   po_hash = hash_new ();
259
260   /* Do the target-specific pseudo ops. */
261   for (pop = md_pseudo_table; pop->poc_name; pop++)
262     {
263       errtxt = hash_insert (po_hash, pop->poc_name, (char *) pop);
264       if (errtxt && *errtxt)
265         {
266           as_fatal ("error constructing md pseudo-op table");
267         }                       /* on error */
268     }                           /* for each op */
269
270   /* Now object specific.  Skip any that were in the target table. */
271   for (pop = obj_pseudo_table; pop->poc_name; pop++)
272     {
273       errtxt = hash_insert (po_hash, pop->poc_name, (char *) pop);
274       if (errtxt && *errtxt)
275         {
276           if (!strcmp (errtxt, "exists"))
277             {
278 #ifdef DIE_ON_OVERRIDES
279               as_fatal ("pseudo op \".%s\" overridden.\n", pop->poc_name);
280 #endif /* DIE_ON_OVERRIDES */
281               continue;         /* OK if target table overrides. */
282             }
283           else
284             {
285               as_fatal ("error constructing obj pseudo-op table");
286             }                   /* if overridden */
287         }                       /* on error */
288     }                           /* for each op */
289
290   /* Now portable ones.  Skip any that we've seen already. */
291   for (pop = potable; pop->poc_name; pop++)
292     {
293       errtxt = hash_insert (po_hash, pop->poc_name, (char *) pop);
294       if (errtxt && *errtxt)
295         {
296           if (!strcmp (errtxt, "exists"))
297             {
298 #ifdef DIE_ON_OVERRIDES
299               as_fatal ("pseudo op \".%s\" overridden.\n", pop->poc_name);
300 #endif /* DIE_ON_OVERRIDES */
301               continue;         /* OK if target table overrides. */
302             }
303           else
304             {
305               as_fatal ("error constructing obj pseudo-op table");
306             }                   /* if overridden */
307         }                       /* on error */
308     }                           /* for each op */
309
310   return;
311 }                               /* pobegin() */
312 \f
313 #define HANDLE_CONDITIONAL_ASSEMBLY()   \
314   if (ignore_input ())                                  \
315     {                                                   \
316       while (! is_end_of_line[*input_line_pointer++])   \
317         if (input_line_pointer == buffer_limit)         \
318           break;                                        \
319       continue;                                         \
320     }
321
322
323 /*      read_a_source_file()
324  *
325  * We read the file, putting things into a web that
326  * represents what we have been reading.
327  */
328 void 
329 read_a_source_file (name)
330      char *name;
331 {
332   register char c;
333   register char *s;             /* string of symbol, '\0' appended */
334   register int temp;
335   /* register struct frag * fragP; JF unused *//* a frag we just made */
336   pseudo_typeS *pop;
337 #ifdef DONTDEF
338   void gdb_block_beg ();
339   void gdb_block_position ();
340   void gdb_block_end ();
341   void gdb_symbols_fixup ();
342 #endif
343
344   buffer = input_scrub_new_file (name);
345
346   listing_file (name);
347   listing_newline ("");
348
349   while ((buffer_limit = input_scrub_next_buffer (&input_line_pointer)) != 0)
350     {                           /* We have another line to parse. */
351       know (buffer_limit[-1] == '\n');  /* Must have a sentinel. */
352     contin:                     /* JF this goto is my fault I admit it.  Someone brave please re-write
353                the whole input section here?  Pleeze??? */
354       while (input_line_pointer < buffer_limit)
355         {                       /* We have more of this buffer to parse. */
356
357           /*
358            * We now have input_line_pointer->1st char of next line.
359            * If input_line_pointer [-1] == '\n' then we just
360            * scanned another line: so bump line counters.
361            */
362           if (input_line_pointer[-1] == '\n')
363             {
364               bump_line_counters ();
365
366 #ifdef MRI
367               /* Text at the start of a line must be a label, we run down and stick a colon in */
368               if (is_name_beginner (*input_line_pointer))
369                 {
370                   char *line_start = input_line_pointer;
371                   char c = get_symbol_end ();
372                   colon (line_start);
373                   *input_line_pointer = c;
374                   if (c == ':')
375                     input_line_pointer++;
376
377                 }
378 #endif
379             }                   /* just passed a newline */
380
381
382
383
384
385           /*
386            * We are at the begining of a line, or similar place.
387            * We expect a well-formed assembler statement.
388            * A "symbol-name:" is a statement.
389            *
390            * Depending on what compiler is used, the order of these tests
391            * may vary to catch most common case 1st.
392            * Each test is independent of all other tests at the (top) level.
393            * PLEASE make a compiler that doesn't use this assembler.
394            * It is crufty to waste a compiler's time encoding things for this
395            * assembler, which then wastes more time decoding it.
396            * (And communicating via (linear) files is silly!
397            * If you must pass stuff, please pass a tree!)
398            */
399           if ((c = *input_line_pointer++) == '\t' || c == ' ' || c == '\f' || c == 0)
400             {
401               c = *input_line_pointer++;
402             }
403           know (c != ' ');      /* No further leading whitespace. */
404           LISTING_NEWLINE ();
405           /*
406            * C is the 1st significant character.
407            * Input_line_pointer points after that character.
408            */
409           if (is_name_beginner (c))
410             {                   /* want user-defined label or pseudo/opcode */
411               HANDLE_CONDITIONAL_ASSEMBLY ();
412
413               s = --input_line_pointer;
414               c = get_symbol_end ();    /* name's delimiter */
415               /*
416                * C is character after symbol.
417                * That character's place in the input line is now '\0'.
418                * S points to the beginning of the symbol.
419                *   [In case of pseudo-op, s->'.'.]
420                * Input_line_pointer->'\0' where c was.
421                */
422               if (c == ':')
423                 {
424                   colon (s);    /* user-defined label */
425                   *input_line_pointer++ = ':';  /* Put ':' back for error messages' sake. */
426                   /* Input_line_pointer->after ':'. */
427                   SKIP_WHITESPACE ();
428
429
430                 }
431               else if (c == '=' || input_line_pointer[1] == '=')
432                 {               /* JF deal with FOO=BAR */
433                   equals (s);
434                   demand_empty_rest_of_line ();
435                 }
436               else
437                 {               /* expect pseudo-op or machine instruction */
438 #ifdef MRI
439                   if (!done_pseudo (s))
440
441 #else
442                   if (*s == '.')
443                     {
444                       /*
445                            * PSEUDO - OP.
446                            *
447                            * WARNING: c has next char, which may be end-of-line.
448                            * We lookup the pseudo-op table with s+1 because we
449                            * already know that the pseudo-op begins with a '.'.
450                            */
451
452                       pop = (pseudo_typeS *) hash_find (po_hash, s + 1);
453
454                       /* Print the error msg now, while we still can */
455                       if (!pop)
456                         {
457                           as_bad ("Unknown pseudo-op:  `%s'", s);
458                           *input_line_pointer = c;
459                           s_ignore (0);
460                           break;
461                         }
462
463                       /* Put it back for error messages etc. */
464                       *input_line_pointer = c;
465                       /* The following skip of whitespace is compulsory. */
466                       /* A well shaped space is sometimes all that separates keyword from operands. */
467                       if (c == ' ' || c == '\t')
468                         {
469                           input_line_pointer++;
470                         }       /* Skip seperator after keyword. */
471                       /*
472                            * Input_line is restored.
473                            * Input_line_pointer->1st non-blank char
474                            * after pseudo-operation.
475                            */
476                       if (!pop)
477                         {
478                           ignore_rest_of_line ();
479                           break;
480                         }
481                       else
482                         {
483                           (*pop->poc_handler) (pop->poc_val);
484                         }       /* if we have one */
485                     }
486                   else
487 #endif
488                     {           /* machine instruction */
489                       /* WARNING: c has char, which may be end-of-line. */
490                       /* Also: input_line_pointer->`\0` where c was. */
491                       *input_line_pointer = c;
492                       while (!is_end_of_line[*input_line_pointer])
493                         {
494                           input_line_pointer++;
495                         }
496
497                       c = *input_line_pointer;
498                       *input_line_pointer = '\0';
499
500                       md_assemble (s);  /* Assemble 1 instruction. */
501
502                       *input_line_pointer++ = c;
503
504                       /* We resume loop AFTER the end-of-line from this instruction */
505                     }           /* if (*s=='.') */
506
507                 }               /* if c==':' */
508               continue;
509             }                   /* if (is_name_beginner(c) */
510
511
512           if (is_end_of_line[c])
513             {
514               continue;
515             }                   /* empty statement */
516
517
518 #if defined(LOCAL_LABELS_DOLLAR) || defined(LOCAL_LABELS_FB)
519           if (isdigit (c))
520             {                   /* local label  ("4:") */
521               char *backup = input_line_pointer;
522
523               HANDLE_CONDITIONAL_ASSEMBLY ();
524
525               temp = c - '0';
526
527               while (isdigit (*input_line_pointer))
528                 {
529                   temp = (temp * 10) + *input_line_pointer - '0';
530                   ++input_line_pointer;
531                 }               /* read the whole number */
532
533 #ifdef LOCAL_LABELS_DOLLAR
534               if (*input_line_pointer == '$'
535                   && *(input_line_pointer + 1) == ':')
536                 {
537                   input_line_pointer += 2;
538
539                   if (dollar_label_defined (temp))
540                     {
541                       as_fatal ("label \"%d$\" redefined", temp);
542                     }
543
544                   define_dollar_label (temp);
545                   colon (dollar_label_name (temp, 0));
546                   continue;
547                 }
548 #endif /* LOCAL_LABELS_DOLLAR */
549
550 #ifdef LOCAL_LABELS_FB
551               if (*input_line_pointer++ == ':')
552                 {
553                   fb_label_instance_inc (temp);
554                   colon (fb_label_name (temp, 0));
555                   continue;
556                 }
557 #endif /* LOCAL_LABELS_FB */
558
559               input_line_pointer = backup;
560             }                   /* local label  ("4:") */
561 #endif /* LOCAL_LABELS_DOLLAR or LOCAL_LABELS_FB */
562
563           if (c && strchr (line_comment_chars, c))
564             {                   /* Its a comment.  Better say APP or NO_APP */
565               char *ends;
566               char *new_buf;
567               char *new_tmp;
568               int new_length;
569               char *tmp_buf = 0;
570               extern char *scrub_string, *scrub_last_string;
571
572               bump_line_counters ();
573               s = input_line_pointer;
574               if (strncmp (s, "APP\n", 4))
575                 continue;       /* We ignore it */
576               s += 4;
577
578               ends = strstr (s, "#NO_APP\n");
579
580               if (!ends)
581                 {
582                   int tmp_len;
583                   int num;
584
585                   /* The end of the #APP wasn't in this buffer.  We
586                      keep reading in buffers until we find the #NO_APP
587                      that goes with this #APP  There is one.  The specs
588                      guarentee it. . . */
589                   tmp_len = buffer_limit - s;
590                   tmp_buf = xmalloc (tmp_len);
591                   bcopy (s, tmp_buf, tmp_len);
592                   do
593                     {
594                       new_tmp = input_scrub_next_buffer (&buffer);
595                       if (!new_tmp)
596                         break;
597                       else
598                         buffer_limit = new_tmp;
599                       input_line_pointer = buffer;
600                       ends = strstr (buffer, "#NO_APP\n");
601                       if (ends)
602                         num = ends - buffer;
603                       else
604                         num = buffer_limit - buffer;
605
606                       tmp_buf = xrealloc (tmp_buf, tmp_len + num);
607                       bcopy (buffer, tmp_buf + tmp_len, num);
608                       tmp_len += num;
609                     }
610                   while (!ends);
611
612                   input_line_pointer = ends ? ends + 8 : NULL;
613
614                   s = tmp_buf;
615                   ends = s + tmp_len;
616
617                 }
618               else
619                 {
620                   input_line_pointer = ends + 8;
621                 }
622               new_buf = xmalloc (100);
623               new_length = 100;
624               new_tmp = new_buf;
625
626               scrub_string = s;
627               scrub_last_string = ends;
628               for (;;)
629                 {
630                   int ch;
631
632                   ch = do_scrub_next_char (scrub_from_string, scrub_to_string);
633                   if (ch == EOF)
634                     break;
635                   *new_tmp++ = ch;
636                   if (new_tmp == new_buf + new_length)
637                     {
638                       new_buf = xrealloc (new_buf, new_length + 100);
639                       new_tmp = new_buf + new_length;
640                       new_length += 100;
641                     }
642                 }
643
644               if (tmp_buf)
645                 free (tmp_buf);
646               old_buffer = buffer;
647               old_input = input_line_pointer;
648               old_limit = buffer_limit;
649               buffer = new_buf;
650               input_line_pointer = new_buf;
651               buffer_limit = new_tmp;
652               continue;
653             }
654
655           HANDLE_CONDITIONAL_ASSEMBLY ();
656
657           /* as_warn("Junk character %d.",c);  Now done by ignore_rest */
658           input_line_pointer--; /* Report unknown char as ignored. */
659           ignore_rest_of_line ();
660         }                       /* while (input_line_pointer<buffer_limit) */
661       if (old_buffer)
662         {
663           bump_line_counters ();
664           if (old_input != 0)
665             {
666               buffer = old_buffer;
667               input_line_pointer = old_input;
668               buffer_limit = old_limit;
669               old_buffer = 0;
670               goto contin;
671             }
672         }
673     }                           /* while (more buffers to scan) */
674   input_scrub_close ();         /* Close the input file */
675
676 }                               /* read_a_source_file() */
677
678 void 
679 s_abort ()
680 {
681   as_fatal (".abort detected.  Abandoning ship.");
682 }                               /* s_abort() */
683
684 /* For machines where ".align 4" means align to a 4 byte boundary. */
685 void 
686 s_align_bytes (arg)
687      int arg;
688 {
689   register unsigned int temp;
690   register long temp_fill;
691   unsigned int i = 0;
692   unsigned long max_alignment = 1 << 15;
693
694   if (is_end_of_line[*input_line_pointer])
695     temp = arg;                 /* Default value from pseudo-op table */
696   else
697     temp = get_absolute_expression ();
698
699   if (temp > max_alignment)
700     {
701       as_bad ("Alignment too large: %d. assumed.", temp = max_alignment);
702     }
703
704   /*
705      * For the sparc, `.align (1<<n)' actually means `.align n'
706      * so we have to convert it.
707      */
708   if (temp != 0)
709     {
710       for (i = 0; (temp & 1) == 0; temp >>= 1, ++i)
711         ;
712     }
713   if (temp != 1)
714     as_bad ("Alignment not a power of 2");
715
716   temp = i;
717   if (*input_line_pointer == ',')
718     {
719       input_line_pointer++;
720       temp_fill = get_absolute_expression ();
721     }
722   else if (now_seg != SEG_DATA && now_seg != SEG_BSS)
723     temp_fill = NOP_OPCODE;
724   else
725     temp_fill = 0;
726   /* Only make a frag if we HAVE to. . . */
727   if (temp && !need_pass_2)
728     frag_align (temp, (int) temp_fill);
729
730   demand_empty_rest_of_line ();
731 }                               /* s_align_bytes() */
732
733 /* For machines where ".align 4" means align to 2**4 boundary. */
734 void 
735 s_align_ptwo ()
736 {
737   register int temp;
738   register long temp_fill;
739   long max_alignment = 15;
740
741   temp = get_absolute_expression ();
742   if (temp > max_alignment)
743     as_bad ("Alignment too large: %d. assumed.", temp = max_alignment);
744   else if (temp < 0)
745     {
746       as_bad ("Alignment negative. 0 assumed.");
747       temp = 0;
748     }
749   if (*input_line_pointer == ',')
750     {
751       input_line_pointer++;
752       temp_fill = get_absolute_expression ();
753     }
754   else if (now_seg != SEG_DATA && now_seg != SEG_BSS)
755     temp_fill = NOP_OPCODE;
756   else
757     temp_fill = 0;
758   /* Only make a frag if we HAVE to. . . */
759   if (temp && !need_pass_2)
760     frag_align (temp, (int) temp_fill);
761
762   record_alignment (now_seg, temp);
763
764   demand_empty_rest_of_line ();
765 }                               /* s_align_ptwo() */
766
767 void 
768 s_comm ()
769 {
770   register char *name;
771   register char c;
772   register char *p;
773   register int temp;
774   register symbolS *symbolP;
775
776   name = input_line_pointer;
777   c = get_symbol_end ();
778   /* just after name is now '\0' */
779   p = input_line_pointer;
780   *p = c;
781   SKIP_WHITESPACE ();
782   if (*input_line_pointer != ',')
783     {
784       as_bad ("Expected comma after symbol-name: rest of line ignored.");
785       ignore_rest_of_line ();
786       return;
787     }
788   input_line_pointer++;         /* skip ',' */
789   if ((temp = get_absolute_expression ()) < 0)
790     {
791       as_warn (".COMMon length (%d.) <0! Ignored.", temp);
792       ignore_rest_of_line ();
793       return;
794     }
795   *p = 0;
796   symbolP = symbol_find_or_make (name);
797   *p = c;
798   if (S_IS_DEFINED (symbolP))
799     {
800       as_bad ("Ignoring attempt to re-define symbol");
801       ignore_rest_of_line ();
802       return;
803     }
804   if (S_GET_VALUE (symbolP))
805     {
806       if (S_GET_VALUE (symbolP) != temp)
807         as_bad ("Length of .comm \"%s\" is already %d. Not changed to %d.",
808                 S_GET_NAME (symbolP),
809                 S_GET_VALUE (symbolP),
810                 temp);
811     }
812   else
813     {
814       S_SET_VALUE (symbolP, temp);
815       S_SET_EXTERNAL (symbolP);
816     }
817 #ifdef VMS
818   if (!temp)
819     symbolP->sy_other = const_flag;
820 #endif
821   know (symbolP->sy_frag == &zero_address_frag);
822   demand_empty_rest_of_line ();
823 }                               /* s_comm() */
824
825 void
826 s_data ()
827 {
828   register int temp;
829
830   temp = get_absolute_expression ();
831 #ifdef MANY_SEGMENTS
832   subseg_new (SEG_E1, (subsegT) temp);
833 #else
834   subseg_new (SEG_DATA, (subsegT) temp);
835 #endif
836
837 #ifdef VMS
838   const_flag = 0;
839 #endif
840   demand_empty_rest_of_line ();
841 }
842
843 void 
844 s_app_file ()
845 {
846   register char *s;
847   int length;
848
849   /* Some assemblers tolerate immediately following '"' */
850   if ((s = demand_copy_string (&length)) != 0)
851     {
852       new_logical_line (s, -1);
853       demand_empty_rest_of_line ();
854     }
855 #ifdef OBJ_COFF
856   c_dot_file_symbol (s);
857 #endif /* OBJ_COFF */
858 }                               /* s_app_file() */
859
860 void 
861 s_fill ()
862 {
863   long temp_repeat = 0;
864   long temp_size = 1;
865   register long temp_fill = 0;
866   char *p;
867
868
869   temp_repeat = get_absolute_expression ();
870   if (*input_line_pointer == ',')
871     {
872       input_line_pointer++;
873       temp_size = get_absolute_expression ();
874       if (*input_line_pointer == ',')
875         {
876           input_line_pointer++;
877           temp_fill = get_absolute_expression ();
878         }
879     }
880   /*
881          * This is to be compatible with BSD 4.2 AS, not for any rational reason.
882          */
883 #define BSD_FILL_SIZE_CROCK_8 (8)
884   if (temp_size > BSD_FILL_SIZE_CROCK_8)
885     {
886       as_warn (".fill size clamped to %d.", BSD_FILL_SIZE_CROCK_8);
887       temp_size = BSD_FILL_SIZE_CROCK_8;
888     }
889   if (temp_size < 0)
890     {
891       as_warn ("Size negative: .fill ignored.");
892       temp_size = 0;
893     }
894   else if (temp_repeat <= 0)
895     {
896       as_warn ("Repeat < 0, .fill ignored");
897       temp_size = 0;
898     }
899
900   if (temp_size && !need_pass_2)
901     {
902       p = frag_var (rs_fill, (int) temp_size, (int) temp_size, (relax_substateT) 0, (symbolS *) 0, temp_repeat, (char *) 0);
903       bzero (p, (int) temp_size);
904       /*
905  * The magic number BSD_FILL_SIZE_CROCK_4 is from BSD 4.2 VAX flavoured AS.
906  * The following bizzare behaviour is to be compatible with above.
907  * I guess they tried to take up to 8 bytes from a 4-byte expression
908  * and they forgot to sign extend. Un*x Sux.
909  */
910 #define BSD_FILL_SIZE_CROCK_4 (4)
911       md_number_to_chars (p, temp_fill, temp_size > BSD_FILL_SIZE_CROCK_4 ? BSD_FILL_SIZE_CROCK_4 : (int) temp_size);
912       /*
913  * Note: .fill (),0 emits no frag (since we are asked to .fill 0 bytes)
914  * but emits no error message because it seems a legal thing to do.
915  * It is a degenerate case of .fill but could be emitted by a compiler.
916  */
917     }
918   demand_empty_rest_of_line ();
919 }
920
921 #ifdef DONTDEF
922 void
923 s_gdbbeg ()
924 {
925   register int temp;
926
927   temp = get_absolute_expression ();
928   if (temp < 0)
929     as_warn ("Block number <0. Ignored.");
930   else if (flagseen['G'])
931     gdb_block_beg ((long) temp, frag_now, (long) (obstack_next_free (&frags) - frag_now->fr_literal));
932   demand_empty_rest_of_line ();
933 }
934
935 void
936 s_gdbblock ()
937 {
938   register int position;
939   int temp;
940
941   if (get_absolute_expression_and_terminator (&temp) != ',')
942     {
943       as_bad ("expected comma before position in .gdbblock");
944       --input_line_pointer;
945       ignore_rest_of_line ();
946       return;
947     }
948   position = get_absolute_expression ();
949   if (flagseen['G'])
950     gdb_block_position ((long) temp, (long) position);
951   demand_empty_rest_of_line ();
952 }
953
954 void
955 s_gdbend ()
956 {
957   register int temp;
958
959   temp = get_absolute_expression ();
960   if (temp < 0)
961     as_warn ("Block number <0. Ignored.");
962   else if (flagseen['G'])
963     gdb_block_end ((long) temp, frag_now, (long) (obstack_next_free (&frags) - frag_now->fr_literal));
964   demand_empty_rest_of_line ();
965 }
966
967 void
968 s_gdbsym ()
969 {
970   register char *name, *p;
971   register char c;
972   register symbolS *symbolP;
973   register int temp;
974
975   name = input_line_pointer;
976   c = get_symbol_end ();
977   p = input_line_pointer;
978   symbolP = symbol_find_or_make (name);
979   *p = c;
980   SKIP_WHITESPACE ();
981   if (*input_line_pointer != ',')
982     {
983       as_bad ("Expected comma after name");
984       ignore_rest_of_line ();
985       return;
986     }
987   input_line_pointer++;
988   if ((temp = get_absolute_expression ()) < 0)
989     {
990       as_bad ("Bad GDB symbol file offset (%d.) <0! Ignored.", temp);
991       ignore_rest_of_line ();
992       return;
993     }
994   if (flagseen['G'])
995     gdb_symbols_fixup (symbolP, (long) temp);
996   demand_empty_rest_of_line ();
997 }
998
999 void
1000 s_gdbline ()
1001 {
1002   int file_number, lineno;
1003
1004   if (get_absolute_expression_and_terminator (&file_number) != ',')
1005     {
1006       as_bad ("expected comman after filenum in .gdbline");
1007       ignore_rest_of_line ();
1008       return;
1009     }
1010   lineno = get_absolute_expression ();
1011   if (flagseen['G'])
1012     gdb_line (file_number, lineno);
1013   demand_empty_rest_of_line ();
1014 }
1015
1016
1017 void
1018 s_gdblinetab ()
1019 {
1020   int file_number, offset;
1021
1022   if (get_absolute_expression_and_terminator (&file_number) != ',')
1023     {
1024       as_bad ("expected comma after filenum in .gdblinetab");
1025       ignore_rest_of_line ();
1026       return;
1027     }
1028   offset = get_absolute_expression ();
1029   if (flagseen['G'])
1030     gdb_line_tab (file_number, offset);
1031   demand_empty_rest_of_line ();
1032 }
1033
1034 #endif
1035
1036 void 
1037 s_globl ()
1038 {
1039   register char *name;
1040   register int c;
1041   register symbolS *symbolP;
1042
1043   do
1044     {
1045       name = input_line_pointer;
1046       c = get_symbol_end ();
1047       symbolP = symbol_find_or_make (name);
1048       *input_line_pointer = c;
1049       SKIP_WHITESPACE ();
1050       S_SET_EXTERNAL (symbolP);
1051       if (c == ',')
1052         {
1053           input_line_pointer++;
1054           SKIP_WHITESPACE ();
1055           if (*input_line_pointer == '\n')
1056             c = '\n';
1057         }
1058     }
1059   while (c == ',');
1060   demand_empty_rest_of_line ();
1061 }                               /* s_globl() */
1062
1063 void 
1064 s_lcomm (needs_align)
1065      int needs_align;           /* 1 if this was a ".bss" directive, which may require
1066                          *      a 3rd argument (alignment).
1067                          * 0 if it was an ".lcomm" (2 args only)
1068                          */
1069 {
1070   register char *name;
1071   register char c;
1072   register char *p;
1073   register int temp;
1074   register symbolS *symbolP;
1075   const int max_alignment = 15;
1076   int align = 0;
1077
1078   name = input_line_pointer;
1079   c = get_symbol_end ();
1080   p = input_line_pointer;
1081   *p = c;
1082   SKIP_WHITESPACE ();
1083   if (*input_line_pointer != ',')
1084     {
1085       as_bad ("Expected comma after name");
1086       ignore_rest_of_line ();
1087       return;
1088     }
1089
1090   ++input_line_pointer;
1091
1092   if (*input_line_pointer == '\n')
1093     {
1094       as_bad ("Missing size expression");
1095       return;
1096     }
1097
1098   if ((temp = get_absolute_expression ()) < 0)
1099     {
1100       as_warn ("BSS length (%d.) <0! Ignored.", temp);
1101       ignore_rest_of_line ();
1102       return;
1103     }
1104
1105   if (needs_align)
1106     {
1107       align = 0;
1108       SKIP_WHITESPACE ();
1109       if (*input_line_pointer != ',')
1110         {
1111           as_bad ("Expected comma after size");
1112           ignore_rest_of_line ();
1113           return;
1114         }
1115       input_line_pointer++;
1116       SKIP_WHITESPACE ();
1117       if (*input_line_pointer == '\n')
1118         {
1119           as_bad ("Missing alignment");
1120           return;
1121         }
1122       align = get_absolute_expression ();
1123       if (align > max_alignment)
1124         {
1125           align = max_alignment;
1126           as_warn ("Alignment too large: %d. assumed.", align);
1127         }
1128       else if (align < 0)
1129         {
1130           align = 0;
1131           as_warn ("Alignment negative. 0 assumed.");
1132         }
1133 #ifdef MANY_SEGMENTS
1134 #define SEG_BSS SEG_E2
1135       record_alignment (SEG_E2, align);
1136 #else
1137       record_alignment (SEG_BSS, align);
1138 #endif
1139     }                           /* if needs align */
1140
1141   *p = 0;
1142   symbolP = symbol_find_or_make (name);
1143   *p = c;
1144
1145   if (
1146 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1147        S_GET_OTHER (symbolP) == 0 &&
1148        S_GET_DESC (symbolP) == 0 &&
1149 #endif /* OBJ_AOUT or OBJ_BOUT */
1150        (((S_GET_SEGMENT (symbolP) == SEG_BSS) && (S_GET_VALUE (symbolP) == local_bss_counter))
1151         || (!S_IS_DEFINED (symbolP) && S_GET_VALUE (symbolP) == 0)))
1152     {
1153       if (needs_align)
1154         {
1155           /* Align */
1156           align = ~((~0) << align);     /* Convert to a mask */
1157           local_bss_counter =
1158             (local_bss_counter + align) & (~align);
1159         }
1160
1161       S_SET_VALUE (symbolP, local_bss_counter);
1162       S_SET_SEGMENT (symbolP, SEG_BSS);
1163 #ifdef OBJ_COFF
1164       /* The symbol may already have been created with a preceding
1165                  * ".globl" directive -- be careful not to step on storage
1166                  * class in that case.  Otherwise, set it to static.
1167                  */
1168       if (S_GET_STORAGE_CLASS (symbolP) != C_EXT)
1169         {
1170           S_SET_STORAGE_CLASS (symbolP, C_STAT);
1171         }
1172 #endif /* OBJ_COFF */
1173       symbolP->sy_frag = &bss_address_frag;
1174       local_bss_counter += temp;
1175     }
1176   else
1177     {
1178       as_bad ("Ignoring attempt to re-define symbol from %d. to %d.",
1179               S_GET_VALUE (symbolP), local_bss_counter);
1180     }
1181   demand_empty_rest_of_line ();
1182
1183   return;
1184 }                               /* s_lcomm() */
1185
1186 void
1187 s_long ()
1188 {
1189   cons (4);
1190 }
1191
1192 void
1193 s_int ()
1194 {
1195   cons (4);
1196 }
1197
1198 void 
1199 s_lsym ()
1200 {
1201   register char *name;
1202   register char c;
1203   register char *p;
1204   register segT segment;
1205   expressionS exp;
1206   register symbolS *symbolP;
1207
1208   /* we permit ANY defined expression: BSD4.2 demands constants */
1209   name = input_line_pointer;
1210   c = get_symbol_end ();
1211   p = input_line_pointer;
1212   *p = c;
1213   SKIP_WHITESPACE ();
1214   if (*input_line_pointer != ',')
1215     {
1216       *p = 0;
1217       as_bad ("Expected comma after name \"%s\"", name);
1218       *p = c;
1219       ignore_rest_of_line ();
1220       return;
1221     }
1222   input_line_pointer++;
1223   segment = expression (&exp);
1224   if (segment != SEG_ABSOLUTE
1225 #ifdef MANY_SEGMENTS
1226       && !(segment >= SEG_E0 && segment <= SEG_UNKNOWN)
1227 #else
1228       && segment != SEG_DATA
1229       && segment != SEG_TEXT
1230       && segment != SEG_BSS
1231 #endif
1232       && segment != SEG_REGISTER)
1233     {
1234       as_bad ("Bad expression: %s", segment_name (segment));
1235       ignore_rest_of_line ();
1236       return;
1237     }
1238   *p = 0;
1239   symbolP = symbol_find_or_make (name);
1240
1241   /* FIXME-SOON I pulled a (&& symbolP->sy_other == 0
1242            && symbolP->sy_desc == 0) out of this test
1243            because coff doesn't have those fields, and I
1244            can't see when they'd ever be tripped.  I don't
1245            think I understand why they were here so I may
1246            have introduced a bug. As recently as 1.37 didn't
1247            have this test anyway.  xoxorich. */
1248
1249   if (S_GET_SEGMENT (symbolP) == SEG_UNKNOWN
1250       && S_GET_VALUE (symbolP) == 0)
1251     {
1252       /* The name might be an undefined .global symbol; be
1253                    sure to keep the "external" bit. */
1254       S_SET_SEGMENT (symbolP, segment);
1255       S_SET_VALUE (symbolP, (valueT) (exp.X_add_number));
1256     }
1257   else
1258     {
1259       as_bad ("Symbol %s already defined", name);
1260     }
1261   *p = c;
1262   demand_empty_rest_of_line ();
1263 }                               /* s_lsym() */
1264
1265 void 
1266 s_org ()
1267 {
1268   register segT segment;
1269   expressionS exp;
1270   register long temp_fill;
1271   register char *p;
1272   /*
1273  * Don't believe the documentation of BSD 4.2 AS.
1274  * There is no such thing as a sub-segment-relative origin.
1275  * Any absolute origin is given a warning, then assumed to be segment-relative.
1276  * Any segmented origin expression ("foo+42") had better be in the right
1277  * segment or the .org is ignored.
1278  *
1279  * BSD 4.2 AS warns if you try to .org backwards. We cannot because we
1280  * never know sub-segment sizes when we are reading code.
1281  * BSD will crash trying to emit -ve numbers of filler bytes in certain
1282  * .orgs. We don't crash, but see as-write for that code.
1283  */
1284   /*
1285  * Don't make frag if need_pass_2==1.
1286  */
1287   segment = get_known_segmented_expression (&exp);
1288   if (*input_line_pointer == ',')
1289     {
1290       input_line_pointer++;
1291       temp_fill = get_absolute_expression ();
1292     }
1293   else
1294     temp_fill = 0;
1295   if (!need_pass_2)
1296     {
1297       if (segment != now_seg && segment != SEG_ABSOLUTE)
1298         as_bad ("Invalid segment \"%s\". Segment \"%s\" assumed.",
1299                 segment_name (segment), segment_name (now_seg));
1300       p = frag_var (rs_org, 1, 1, (relax_substateT) 0, exp.X_add_symbol,
1301                     exp.X_add_number, (char *) 0);
1302       *p = temp_fill;
1303     }                           /* if (ok to make frag) */
1304   demand_empty_rest_of_line ();
1305 }                               /* s_org() */
1306
1307 void 
1308 s_set ()
1309 {
1310   register char *name;
1311   register char delim;
1312   register char *end_name;
1313   register symbolS *symbolP;
1314
1315   /*
1316          * Especial apologies for the random logic:
1317          * this just grew, and could be parsed much more simply!
1318          * Dean in haste.
1319          */
1320   name = input_line_pointer;
1321   delim = get_symbol_end ();
1322   end_name = input_line_pointer;
1323   *end_name = delim;
1324   SKIP_WHITESPACE ();
1325
1326   if (*input_line_pointer != ',')
1327     {
1328       *end_name = 0;
1329       as_bad ("Expected comma after name \"%s\"", name);
1330       *end_name = delim;
1331       ignore_rest_of_line ();
1332       return;
1333     }
1334
1335   input_line_pointer++;
1336   *end_name = 0;
1337
1338   if (name[0] == '.' && name[1] == '\0')
1339     {
1340       /* Turn '. = mumble' into a .org mumble */
1341       register segT segment;
1342       expressionS exp;
1343       register char *ptr;
1344
1345       segment = get_known_segmented_expression (&exp);
1346
1347       if (!need_pass_2)
1348         {
1349           if (segment != now_seg && segment != SEG_ABSOLUTE)
1350             as_bad ("Invalid segment \"%s\". Segment \"%s\" assumed.",
1351                     segment_name (segment),
1352                     segment_name (now_seg));
1353           ptr = frag_var (rs_org, 1, 1, (relax_substateT) 0, exp.X_add_symbol,
1354                           exp.X_add_number, (char *) 0);
1355           *ptr = 0;
1356         }                       /* if (ok to make frag) */
1357
1358       *end_name = delim;
1359       return;
1360     }
1361
1362   if ((symbolP = symbol_find (name)) == NULL
1363       && (symbolP = md_undefined_symbol (name)) == NULL)
1364     {
1365       symbolP = symbol_new (name,
1366                             SEG_UNKNOWN,
1367                             0,
1368                             &zero_address_frag);
1369 #ifdef OBJ_COFF
1370       /* "set" symbols are local unless otherwise specified. */
1371       SF_SET_LOCAL (symbolP);
1372 #endif /* OBJ_COFF */
1373
1374     }                           /* make a new symbol */
1375
1376   symbol_table_insert (symbolP);
1377
1378   *end_name = delim;
1379   pseudo_set (symbolP);
1380   demand_empty_rest_of_line ();
1381 }                               /* s_set() */
1382
1383 void 
1384 s_space (mult)
1385      int mult;
1386 {
1387   long temp_repeat;
1388   register long temp_fill;
1389   register char *p;
1390
1391   /* Just like .fill, but temp_size = 1 */
1392   if (get_absolute_expression_and_terminator (&temp_repeat) == ',')
1393     {
1394       temp_fill = get_absolute_expression ();
1395     }
1396   else
1397     {
1398       input_line_pointer--;     /* Backup over what was not a ','. */
1399       temp_fill = 0;
1400     }
1401   if (mult)
1402     {
1403       temp_fill *= mult;
1404     }
1405   if (temp_repeat <= 0)
1406     {
1407       as_warn ("Repeat < 0, .space ignored");
1408       ignore_rest_of_line ();
1409       return;
1410     }
1411   if (!need_pass_2)
1412     {
1413       p = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) 0,
1414                     temp_repeat, (char *) 0);
1415       *p = temp_fill;
1416     }
1417   demand_empty_rest_of_line ();
1418 }                               /* s_space() */
1419
1420 void
1421 s_text ()
1422 {
1423   register int temp;
1424
1425   temp = get_absolute_expression ();
1426 #ifdef MANY_SEGMENTS
1427   subseg_new (SEG_E0, (subsegT) temp);
1428 #else
1429   subseg_new (SEG_TEXT, (subsegT) temp);
1430 #endif
1431   demand_empty_rest_of_line ();
1432 }                               /* s_text() */
1433 \f
1434
1435 /*(JF was static, but can't be if machine dependent pseudo-ops are to use it */
1436
1437 void 
1438 demand_empty_rest_of_line ()
1439 {
1440   SKIP_WHITESPACE ();
1441   if (is_end_of_line[*input_line_pointer])
1442     {
1443       input_line_pointer++;
1444     }
1445   else
1446     {
1447       ignore_rest_of_line ();
1448     }
1449   /* Return having already swallowed end-of-line. */
1450 }                               /* Return pointing just after end-of-line. */
1451
1452 void
1453 ignore_rest_of_line ()          /* For suspect lines: gives warning. */
1454 {
1455   if (!is_end_of_line[*input_line_pointer])
1456     {
1457       if (isprint (*input_line_pointer))
1458         as_bad ("Rest of line ignored. First ignored character is `%c'.",
1459                 *input_line_pointer);
1460       else
1461         as_bad ("Rest of line ignored. First ignored character valued 0x%x.",
1462                 *input_line_pointer);
1463       while (input_line_pointer < buffer_limit
1464              && !is_end_of_line[*input_line_pointer])
1465         {
1466           input_line_pointer++;
1467         }
1468     }
1469   input_line_pointer++;         /* Return pointing just after end-of-line. */
1470   know (is_end_of_line[input_line_pointer[-1]]);
1471 }
1472
1473 /*
1474  *                      pseudo_set()
1475  *
1476  * In:  Pointer to a symbol.
1477  *      Input_line_pointer->expression.
1478  *
1479  * Out: Input_line_pointer->just after any whitespace after expression.
1480  *      Tried to set symbol to value of expression.
1481  *      Will change symbols type, value, and frag;
1482  *      May set need_pass_2 == 1.
1483  */
1484 void
1485 pseudo_set (symbolP)
1486      symbolS *symbolP;
1487 {
1488   expressionS exp;
1489   register segT segment;
1490 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1491   int ext;
1492 #endif /* OBJ_AOUT or OBJ_BOUT */
1493
1494   know (symbolP);               /* NULL pointer is logic error. */
1495 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1496   ext = S_IS_EXTERNAL (symbolP);
1497 #endif /* OBJ_AOUT or OBJ_BOUT */
1498
1499   if ((segment = expression (&exp)) == SEG_ABSENT)
1500     {
1501       as_bad ("Missing expression: absolute 0 assumed");
1502       exp.X_seg = SEG_ABSOLUTE;
1503       exp.X_add_number = 0;
1504     }
1505
1506   switch (segment)
1507     {
1508     case SEG_REGISTER:
1509       S_SET_SEGMENT (symbolP, SEG_REGISTER);
1510       S_SET_VALUE (symbolP, exp.X_add_number);
1511       symbolP->sy_frag = &zero_address_frag;
1512       break;
1513
1514     case SEG_BIG:
1515       as_bad ("%s number invalid. Absolute 0 assumed.",
1516               exp.X_add_number > 0 ? "Bignum" : "Floating-Point");
1517       S_SET_SEGMENT (symbolP, SEG_ABSOLUTE);
1518 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1519       ext ? S_SET_EXTERNAL (symbolP) :
1520         S_CLEAR_EXTERNAL (symbolP);
1521 #endif /* OBJ_AOUT or OBJ_BOUT */
1522       S_SET_VALUE (symbolP, 0);
1523       symbolP->sy_frag = &zero_address_frag;
1524       break;
1525
1526     case SEG_ABSENT:
1527       as_warn ("No expression:  Using absolute 0");
1528       S_SET_SEGMENT (symbolP, SEG_ABSOLUTE);
1529 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1530       ext ? S_SET_EXTERNAL (symbolP) :
1531         S_CLEAR_EXTERNAL (symbolP);
1532 #endif /* OBJ_AOUT or OBJ_BOUT */
1533       S_SET_VALUE (symbolP, 0);
1534       symbolP->sy_frag = &zero_address_frag;
1535       break;
1536
1537     case SEG_DIFFERENCE:
1538       if (exp.X_add_symbol && exp.X_subtract_symbol
1539           && (S_GET_SEGMENT (exp.X_add_symbol) ==
1540               S_GET_SEGMENT (exp.X_subtract_symbol)))
1541         {
1542           if (exp.X_add_symbol->sy_frag != exp.X_subtract_symbol->sy_frag)
1543             {
1544               as_bad ("Unknown expression: symbols %s and %s are in different frags.",
1545                       S_GET_NAME (exp.X_add_symbol), S_GET_NAME (exp.X_subtract_symbol));
1546               need_pass_2++;
1547             }
1548           exp.X_add_number += S_GET_VALUE (exp.X_add_symbol) -
1549             S_GET_VALUE (exp.X_subtract_symbol);
1550         }
1551       else
1552         as_bad ("Complex expression. Absolute segment assumed.");
1553     case SEG_ABSOLUTE:
1554       S_SET_SEGMENT (symbolP, SEG_ABSOLUTE);
1555 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1556       ext ? S_SET_EXTERNAL (symbolP) :
1557         S_CLEAR_EXTERNAL (symbolP);
1558 #endif /* OBJ_AOUT or OBJ_BOUT */
1559       S_SET_VALUE (symbolP, exp.X_add_number);
1560       symbolP->sy_frag = &zero_address_frag;
1561       break;
1562
1563     default:
1564 #ifdef MANY_SEGMENTS
1565       S_SET_SEGMENT (symbolP, segment);
1566 #else
1567       switch (segment)
1568         {
1569         case SEG_DATA:
1570           S_SET_SEGMENT (symbolP, SEG_DATA);
1571           break;
1572         case SEG_TEXT:
1573           S_SET_SEGMENT (symbolP, SEG_TEXT);
1574           break;
1575         case SEG_BSS:
1576           S_SET_SEGMENT (symbolP, SEG_BSS);
1577           break;
1578
1579         default:
1580           as_fatal ("failed sanity check.");
1581         }                       /* switch on segment */
1582 #endif
1583 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
1584       if (ext)
1585         {
1586           S_SET_EXTERNAL (symbolP);
1587         }
1588       else
1589         {
1590           S_CLEAR_EXTERNAL (symbolP);
1591         }                       /* if external */
1592 #endif /* OBJ_AOUT or OBJ_BOUT */
1593
1594       S_SET_VALUE (symbolP, exp.X_add_number + S_GET_VALUE (exp.X_add_symbol));
1595       symbolP->sy_frag = exp.X_add_symbol->sy_frag;
1596       break;
1597
1598     case SEG_PASS1:             /* Not an error. Just try another pass. */
1599       symbolP->sy_forward = exp.X_add_symbol;
1600       as_bad ("Unknown expression");
1601       know (need_pass_2 == 1);
1602       break;
1603
1604     case SEG_UNKNOWN:
1605       symbolP->sy_forward = exp.X_add_symbol;
1606       /* as_warn("unknown symbol"); */
1607       /* need_pass_2 = 1; */
1608       break;
1609
1610
1611
1612     }
1613 }
1614 \f
1615 /*
1616  *                      cons()
1617  *
1618  * CONStruct more frag of .bytes, or .words etc.
1619  * Should need_pass_2 be 1 then emit no frag(s).
1620  * This understands EXPRESSIONS, as opposed to big_cons().
1621  *
1622  * Bug (?)
1623  *
1624  * This has a split personality. We use expression() to read the
1625  * value. We can detect if the value won't fit in a byte or word.
1626  * But we can't detect if expression() discarded significant digits
1627  * in the case of a long. Not worth the crocks required to fix it.
1628  */
1629
1630 /* worker to do .byte etc statements */
1631 /* clobbers input_line_pointer, checks */
1632 /* end-of-line. */
1633 void 
1634 cons (nbytes)
1635      register unsigned int nbytes;      /* 1=.byte, 2=.word, 4=.long */
1636 {
1637   register char c;
1638   register long mask;           /* High-order bits we will left-truncate, */
1639   /* but includes sign bit also. */
1640   register long get;            /* what we get */
1641   register long use;            /* get after truncation. */
1642   register long unmask;         /* what bits we will store */
1643   register char *p;
1644   register segT segment;
1645   expressionS exp;
1646
1647   /*
1648    * Input_line_pointer->1st char after pseudo-op-code and could legally
1649    * be a end-of-line. (Or, less legally an eof - which we cope with.)
1650    */
1651   /* JF << of >= number of bits in the object is undefined.  In particular
1652      SPARC (Sun 4) has problems */
1653
1654   if (nbytes >= sizeof (long))
1655     {
1656       mask = 0;
1657     }
1658   else
1659     {
1660       mask = ~0 << (BITS_PER_CHAR * nbytes);    /* Don't store these bits. */
1661     }                           /* bigger than a long */
1662
1663   unmask = ~mask;               /* Do store these bits. */
1664
1665 #ifdef NEVER
1666   "Do this mod if you want every overflow check to assume SIGNED 2's complement data.";
1667   mask = ~(unmask >> 1);        /* Includes sign bit now. */
1668 #endif
1669
1670   /*
1671    * The following awkward logic is to parse ZERO or more expressions,
1672    * comma seperated. Recall an expression includes its leading &
1673    * trailing blanks. We fake a leading ',' if there is (supposed to
1674    * be) a 1st expression, and keep demanding 1 expression for each ','.
1675    */
1676   if (is_it_end_of_statement ())
1677     {
1678       c = 0;                    /* Skip loop. */
1679       input_line_pointer++;     /* Matches end-of-loop 'correction'. */
1680     }
1681   else
1682     {
1683       c = ',';
1684     }                           /* if the end else fake it */
1685
1686   /* Do loop. */
1687   while (c == ',')
1688     {
1689 #ifdef WANT_BITFIELDS
1690       unsigned int bits_available = BITS_PER_CHAR * nbytes;
1691       /* used for error messages and rescanning */
1692       char *hold = input_line_pointer;
1693 #endif /* WANT_BITFIELDS */
1694 #ifdef MRI
1695       if (*input_line_pointer == '\'')
1696         {
1697           /* An MRI style string, cut into as many bytes as will fit
1698            into a nbyte chunk, left justify if necessary, and sepatate
1699            with commas so we can try again later */
1700           int scan = 0;
1701           unsigned int result = 0;
1702           input_line_pointer++;
1703           for (scan = 0; scan < nbytes; scan++)
1704             {
1705               if (*input_line_pointer == '\'')
1706                 {
1707                   if (input_line_pointer[1] == '\'')
1708                     {
1709                       input_line_pointer++;
1710                     }
1711                   else
1712                     break;
1713                 }
1714               result = (result << 8) | (*input_line_pointer++);
1715             }
1716
1717           /* Left justify */
1718           while (scan < nbytes)
1719             {
1720               result <<= 8;
1721               scan++;
1722             }
1723           /* Create correct expression */
1724           exp.X_add_symbol = 0;
1725           exp.X_add_number = result;
1726           exp.X_seg = segment = SEG_ABSOLUTE;
1727           /* Fake it so that we can read the next char too */
1728           if (input_line_pointer[0] != '\'' ||
1729            (input_line_pointer[0] == '\'' && input_line_pointer[1] == '\''))
1730             {
1731               input_line_pointer -= 2;
1732               input_line_pointer[0] = ',';
1733               input_line_pointer[1] = '\'';
1734             }
1735           else
1736             input_line_pointer++;
1737
1738         }
1739       else
1740 #endif
1741         /* At least scan over the expression. */
1742         segment = expression (&exp);
1743
1744 #ifdef WANT_BITFIELDS
1745       /* Some other assemblers, (eg, asm960), allow
1746          bitfields after ".byte" as w:x,y:z, where w and
1747          y are bitwidths and x and y are values.  They
1748          then pack them all together. We do a little
1749          better in that we allow them in words, longs,
1750          etc. and we'll pack them in target byte order
1751          for you.
1752         
1753          The rules are: pack least significat bit first,
1754          if a field doesn't entirely fit, put it in the
1755          next unit.  Overflowing the bitfield is
1756          explicitly *not* even a warning.  The bitwidth
1757          should be considered a "mask".
1758         
1759          FIXME-SOMEDAY: If this is considered generally
1760          useful, this logic should probably be reworked.
1761          xoxorich. */
1762
1763       if (*input_line_pointer == ':')
1764         {                       /* bitfields */
1765           long value = 0;
1766
1767           for (;;)
1768             {
1769               unsigned long width;
1770
1771               if (*input_line_pointer != ':')
1772                 {
1773                   input_line_pointer = hold;
1774                   break;
1775                 }               /* next piece is not a bitfield */
1776
1777               /* In the general case, we can't allow
1778                  full expressions with symbol
1779                  differences and such.  The relocation
1780                  entries for symbols not defined in this
1781                  assembly would require arbitrary field
1782                  widths, positions, and masks which most
1783                  of our current object formats don't
1784                  support.
1785                 
1786                  In the specific case where a symbol
1787                  *is* defined in this assembly, we
1788                  *could* build fixups and track it, but
1789                  this could lead to confusion for the
1790                  backends.  I'm lazy. I'll take any
1791                  SEG_ABSOLUTE. I think that means that
1792                  you can use a previous .set or
1793                  .equ type symbol.  xoxorich. */
1794
1795               if (segment == SEG_ABSENT)
1796                 {
1797                   as_warn ("Using a bit field width of zero.");
1798                   exp.X_add_number = 0;
1799                   segment = SEG_ABSOLUTE;
1800                 }               /* implied zero width bitfield */
1801
1802               if (segment != SEG_ABSOLUTE)
1803                 {
1804                   *input_line_pointer = '\0';
1805                   as_bad ("Field width \"%s\" too complex for a bitfield.\n", hold);
1806                   *input_line_pointer = ':';
1807                   demand_empty_rest_of_line ();
1808                   return;
1809                 }               /* too complex */
1810
1811               if ((width = exp.X_add_number) > (BITS_PER_CHAR * nbytes))
1812                 {
1813                   as_warn ("Field width %d too big to fit in %d bytes: truncated to %d bits.",
1814                            width, nbytes, (BITS_PER_CHAR * nbytes));
1815                   width = BITS_PER_CHAR * nbytes;
1816                 }               /* too big */
1817
1818               if (width > bits_available)
1819                 {
1820                   /* FIXME-SOMEDAY: backing up and
1821                      reparsing is wasteful */
1822                   input_line_pointer = hold;
1823                   exp.X_add_number = value;
1824                   break;
1825                 }               /* won't fit */
1826
1827               hold = ++input_line_pointer;      /* skip ':' */
1828
1829               if ((segment = expression (&exp)) != SEG_ABSOLUTE)
1830                 {
1831                   char cache = *input_line_pointer;
1832
1833                   *input_line_pointer = '\0';
1834                   as_bad ("Field value \"%s\" too complex for a bitfield.\n", hold);
1835                   *input_line_pointer = cache;
1836                   demand_empty_rest_of_line ();
1837                   return;
1838                 }               /* too complex */
1839
1840               value |= (~(-1 << width) & exp.X_add_number)
1841                 << ((BITS_PER_CHAR * nbytes) - bits_available);
1842
1843               if ((bits_available -= width) == 0
1844                   || is_it_end_of_statement ()
1845                   || *input_line_pointer != ',')
1846                 {
1847                   break;
1848                 }               /* all the bitfields we're gonna get */
1849
1850               hold = ++input_line_pointer;
1851               segment = expression (&exp);
1852             }                   /* forever loop */
1853
1854           exp.X_add_number = value;
1855           segment = SEG_ABSOLUTE;
1856         }                       /* if looks like a bitfield */
1857 #endif /* WANT_BITFIELDS */
1858
1859       if (!need_pass_2)
1860         {                       /* Still worthwhile making frags. */
1861
1862           /* Don't call this if we are going to junk this pass anyway! */
1863           know (segment != SEG_PASS1);
1864
1865           if (segment == SEG_DIFFERENCE && exp.X_add_symbol == NULL)
1866             {
1867               as_bad ("Subtracting symbol \"%s\"(segment\"%s\") is too hard. Absolute segment assumed.",
1868                       S_GET_NAME (exp.X_subtract_symbol),
1869                       segment_name (S_GET_SEGMENT (exp.X_subtract_symbol)));
1870               segment = SEG_ABSOLUTE;
1871               /* Leave exp . X_add_number alone. */
1872             }
1873           p = frag_more (nbytes);
1874           switch (segment)
1875             {
1876             case SEG_BIG:
1877               as_bad ("%s number invalid. Absolute 0 assumed.",
1878                       exp.X_add_number > 0 ? "Bignum" : "Floating-Point");
1879               md_number_to_chars (p, (long) 0, nbytes);
1880               break;
1881
1882             case SEG_ABSENT:
1883               as_warn ("0 assumed for missing expression");
1884               exp.X_add_number = 0;
1885               know (exp.X_add_symbol == NULL);
1886               /* fall into SEG_ABSOLUTE */
1887             case SEG_ABSOLUTE:
1888               get = exp.X_add_number;
1889               use = get & unmask;
1890               if ((get & mask) && (get & mask) != mask)
1891                 {               /* Leading bits contain both 0s & 1s. */
1892                   as_warn ("Value 0x%x truncated to 0x%x.", get, use);
1893                 }
1894               md_number_to_chars (p, use, nbytes);      /* put bytes in right order. */
1895               break;
1896
1897             case SEG_DIFFERENCE:
1898 #ifndef WORKING_DOT_WORD
1899               if (nbytes == 2)
1900                 {
1901                   struct broken_word *x;
1902
1903                   x = (struct broken_word *) xmalloc (sizeof (struct broken_word));
1904                   x->next_broken_word = broken_words;
1905                   broken_words = x;
1906                   x->frag = frag_now;
1907                   x->word_goes_here = p;
1908                   x->dispfrag = 0;
1909                   x->add = exp.X_add_symbol;
1910                   x->sub = exp.X_subtract_symbol;
1911                   x->addnum = exp.X_add_number;
1912                   x->added = 0;
1913                   new_broken_words++;
1914                   break;
1915                 }
1916               /* Else Fall through into. . . */
1917 #endif
1918             default:
1919             case SEG_UNKNOWN:
1920 #ifdef TC_NS32K
1921               fix_new_ns32k (frag_now, p - frag_now->fr_literal, nbytes,
1922                              exp.X_add_symbol, exp.X_subtract_symbol,
1923                              exp.X_add_number, 0, 0, 2, 0, 0);
1924 #else
1925 # if defined(TC_SPARC) || defined(TC_A29K)
1926               fix_new (frag_now, p - frag_now->fr_literal, nbytes,
1927                        exp.X_add_symbol, exp.X_subtract_symbol,
1928                        exp.X_add_number, 0, RELOC_32);
1929 # else
1930 #  if defined(TC_H8300)
1931               fix_new (frag_now, p - frag_now->fr_literal, nbytes,
1932                        exp.X_add_symbol, exp.X_subtract_symbol,
1933                        exp.X_add_number, 0, R_RELWORD);
1934
1935 #  else
1936 #ifdef NO_RELOC
1937               fix_new (frag_now, p - frag_now->fr_literal, nbytes,
1938                        exp.X_add_symbol, exp.X_subtract_symbol,
1939                        exp.X_add_number, 0, NO_RELOC);
1940 #else
1941               fix_new (frag_now, p - frag_now->fr_literal, nbytes,
1942                        exp.X_add_symbol, exp.X_subtract_symbol,
1943                        exp.X_add_number, 0, 0);
1944 #endif /* NO_RELOC */
1945 #  endif                        /* tc_h8300 */
1946 # endif                         /* tc_sparc|tc_a29k */
1947 #endif /* TC_NS32K */
1948               break;
1949             }                   /* switch(segment) */
1950         }                       /* if (!need_pass_2) */
1951       c = *input_line_pointer++;
1952     }                           /* while(c==',') */
1953   input_line_pointer--;         /* Put terminator back into stream. */
1954   demand_empty_rest_of_line ();
1955 }                               /* cons() */
1956 \f
1957 /*
1958  *                      big_cons()
1959  *
1960  * CONStruct more frag(s) of .quads, or .octa etc.
1961  * Makes 0 or more new frags.
1962  * If need_pass_2 == 1, generate no frag.
1963  * This understands only bignums, not expressions. Cons() understands
1964  * expressions.
1965  *
1966  * Constants recognised are '0...'(octal) '0x...'(hex) '...'(decimal).
1967  *
1968  * This creates objects with struct obstack_control objs, destroying
1969  * any context objs held about a partially completed object. Beware!
1970  *
1971  *
1972  * I think it sucks to have 2 different types of integers, with 2
1973  * routines to read them, store them etc.
1974  * It would be nicer to permit bignums in expressions and only
1975  * complain if the result overflowed. However, due to "efficiency"...
1976  */
1977 /* worker to do .quad etc statements */
1978 /* clobbers input_line_pointer, checks */
1979 /* end-of-line. */
1980 /* 8=.quad 16=.octa ... */
1981
1982 void 
1983 big_cons (nbytes)
1984      register int nbytes;
1985 {
1986   register char c;              /* input_line_pointer->c. */
1987   register int radix;
1988   register long length;         /* Number of chars in an object. */
1989   register int digit;           /* Value of 1 digit. */
1990   register int carry;           /* For multi-precision arithmetic. */
1991   register int work;            /* For multi-precision arithmetic. */
1992   register char *p;             /* For multi-precision arithmetic. */
1993
1994   extern char hex_value[];      /* In hex_value.c. */
1995
1996   /*
1997    * The following awkward logic is to parse ZERO or more strings,
1998    * comma seperated. Recall an expression includes its leading &
1999    * trailing blanks. We fake a leading ',' if there is (supposed to
2000    * be) a 1st expression, and keep demanding 1 expression for each ','.
2001    */
2002   if (is_it_end_of_statement ())
2003     {
2004       c = 0;                    /* Skip loop. */
2005     }
2006   else
2007     {
2008       c = ',';                  /* Do loop. */
2009       --input_line_pointer;
2010     }
2011   while (c == ',')
2012     {
2013       ++input_line_pointer;
2014       SKIP_WHITESPACE ();
2015       c = *input_line_pointer;
2016       /* C contains 1st non-blank character of what we hope is a number. */
2017       if (c == '0')
2018         {
2019           c = *++input_line_pointer;
2020           if (c == 'x' || c == 'X')
2021             {
2022               c = *++input_line_pointer;
2023               radix = 16;
2024             }
2025           else
2026             {
2027               radix = 8;
2028             }
2029         }
2030       else
2031         {
2032           radix = 10;
2033         }
2034       /*
2035        * This feature (?) is here to stop people worrying about
2036        * mysterious zero constants: which is what they get when
2037        * they completely omit digits.
2038        */
2039       if (hex_value[c] >= radix)
2040         {
2041           as_bad ("Missing digits. 0 assumed.");
2042         }
2043       bignum_high = bignum_low - 1;     /* Start constant with 0 chars. */
2044       for (; (digit = hex_value[c]) < radix; c = *++input_line_pointer)
2045         {
2046           /* Multiply existing number by radix, then add digit. */
2047           carry = digit;
2048           for (p = bignum_low; p <= bignum_high; p++)
2049             {
2050               work = (*p & MASK_CHAR) * radix + carry;
2051               *p = work & MASK_CHAR;
2052               carry = work >> BITS_PER_CHAR;
2053             }
2054           if (carry)
2055             {
2056               grow_bignum ();
2057               *bignum_high = carry & MASK_CHAR;
2058               know ((carry & ~MASK_CHAR) == 0);
2059             }
2060         }
2061       length = bignum_high - bignum_low + 1;
2062       if (length > nbytes)
2063         {
2064           as_warn ("Most significant bits truncated in integer constant.");
2065         }
2066       else
2067         {
2068           register long leading_zeroes;
2069
2070           for (leading_zeroes = nbytes - length;
2071                leading_zeroes;
2072                leading_zeroes--)
2073             {
2074               grow_bignum ();
2075               *bignum_high = 0;
2076             }
2077         }
2078       if (!need_pass_2)
2079         {
2080           p = frag_more (nbytes);
2081           bcopy (bignum_low, p, (int) nbytes);
2082         }
2083       /* C contains character after number. */
2084       SKIP_WHITESPACE ();
2085       c = *input_line_pointer;
2086       /* C contains 1st non-blank character after number. */
2087     }
2088   demand_empty_rest_of_line ();
2089 }                               /* big_cons() */
2090
2091 /* Extend bignum by 1 char. */
2092 static void 
2093 grow_bignum ()
2094 {
2095   register long length;
2096
2097   bignum_high++;
2098   if (bignum_high >= bignum_limit)
2099     {
2100       length = bignum_limit - bignum_low;
2101       bignum_low = xrealloc (bignum_low, length + length);
2102       bignum_high = bignum_low + length;
2103       bignum_limit = bignum_low + length + length;
2104     }
2105 }                               /* grow_bignum(); */
2106 \f
2107 /*
2108  *                      float_cons()
2109  *
2110  * CONStruct some more frag chars of .floats .ffloats etc.
2111  * Makes 0 or more new frags.
2112  * If need_pass_2 == 1, no frags are emitted.
2113  * This understands only floating literals, not expressions. Sorry.
2114  *
2115  * A floating constant is defined by atof_generic(), except it is preceded
2116  * by 0d 0f 0g or 0h. After observing the STRANGE way my BSD AS does its
2117  * reading, I decided to be incompatible. This always tries to give you
2118  * rounded bits to the precision of the pseudo-op. Former AS did premature
2119  * truncatation, restored noisy bits instead of trailing 0s AND gave you
2120  * a choice of 2 flavours of noise according to which of 2 floating-point
2121  * scanners you directed AS to use.
2122  *
2123  * In:  input_line_pointer->whitespace before, or '0' of flonum.
2124  *
2125  */
2126
2127 void                            /* JF was static, but can't be if VAX.C is goning to use it */
2128 float_cons (float_type)         /* Worker to do .float etc statements. */
2129      /* Clobbers input_line-pointer, checks end-of-line. */
2130      register int float_type;   /* 'f':.ffloat ... 'F':.float ... */
2131 {
2132   register char *p;
2133   register char c;
2134   int length;                   /* Number of chars in an object. */
2135   register char *err;           /* Error from scanning floating literal. */
2136   char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];
2137
2138   /*
2139    * The following awkward logic is to parse ZERO or more strings,
2140    * comma seperated. Recall an expression includes its leading &
2141    * trailing blanks. We fake a leading ',' if there is (supposed to
2142    * be) a 1st expression, and keep demanding 1 expression for each ','.
2143    */
2144   if (is_it_end_of_statement ())
2145     {
2146       c = 0;                    /* Skip loop. */
2147       ++input_line_pointer;     /*->past termintor. */
2148     }
2149   else
2150     {
2151       c = ',';                  /* Do loop. */
2152     }
2153   while (c == ',')
2154     {
2155       /* input_line_pointer->1st char of a flonum (we hope!). */
2156       SKIP_WHITESPACE ();
2157       /* Skip any 0{letter} that may be present. Don't even check if the
2158        * letter is legal. Someone may invent a "z" format and this routine
2159        * has no use for such information. Lusers beware: you get
2160        * diagnostics if your input is ill-conditioned.
2161        */
2162
2163       if (input_line_pointer[0] == '0' && isalpha (input_line_pointer[1]))
2164         input_line_pointer += 2;
2165
2166       err = md_atof (float_type, temp, &length);
2167       know (length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
2168       know (length > 0);
2169       if (*err)
2170         {
2171           as_bad ("Bad floating literal: %s", err);
2172           ignore_rest_of_line ();
2173           /* Input_line_pointer->just after end-of-line. */
2174           c = 0;                /* Break out of loop. */
2175         }
2176       else
2177         {
2178           if (!need_pass_2)
2179             {
2180               p = frag_more (length);
2181               bcopy (temp, p, length);
2182             }
2183           SKIP_WHITESPACE ();
2184           c = *input_line_pointer++;
2185           /* C contains 1st non-white character after number. */
2186           /* input_line_pointer->just after terminator (c). */
2187         }
2188     }
2189   --input_line_pointer;         /*->terminator (is not ','). */
2190   demand_empty_rest_of_line ();
2191 }                               /* float_cons() */
2192 \f
2193 /*
2194  *                      stringer()
2195  *
2196  * We read 0 or more ',' seperated, double-quoted strings.
2197  *
2198  * Caller should have checked need_pass_2 is FALSE because we don't check it.
2199  */
2200
2201
2202 void 
2203 stringer (append_zero)          /* Worker to do .ascii etc statements. */
2204      /* Checks end-of-line. */
2205      register int append_zero;  /* 0: don't append '\0', else 1 */
2206 {
2207   /* register char *    p; JF unused */
2208   /* register int length; JF unused *//* Length of string we read, excluding */
2209   /* trailing '\0' implied by closing quote. */
2210   /* register char *    where; JF unused */
2211   /* register fragS *   fragP; JF unused */
2212   register unsigned int c;
2213
2214   /*
2215    * The following awkward logic is to parse ZERO or more strings,
2216    * comma seperated. Recall a string expression includes spaces
2217    * before the opening '\"' and spaces after the closing '\"'.
2218    * We fake a leading ',' if there is (supposed to be)
2219    * a 1st, expression. We keep demanding expressions for each
2220    * ','.
2221    */
2222   if (is_it_end_of_statement ())
2223     {
2224       c = 0;                    /* Skip loop. */
2225       ++input_line_pointer;     /* Compensate for end of loop. */
2226     }
2227   else
2228     {
2229       c = ',';                  /* Do loop. */
2230     }
2231   while (c == ',' || c == '<' || c == '"')
2232     {
2233       SKIP_WHITESPACE ();
2234       switch (*input_line_pointer)
2235         {
2236         case '\"':
2237           ++input_line_pointer; /*->1st char of string. */
2238           while (is_a_char (c = next_char_of_string ()))
2239             {
2240               FRAG_APPEND_1_CHAR (c);
2241             }
2242           if (append_zero)
2243             {
2244               FRAG_APPEND_1_CHAR (0);
2245             }
2246           know (input_line_pointer[-1] == '\"');
2247           break;
2248         case '<':
2249           input_line_pointer++;
2250           c = get_single_number ();
2251           FRAG_APPEND_1_CHAR (c);
2252           if (*input_line_pointer != '>')
2253             {
2254               as_bad ("Expected <nn>");
2255             }
2256           input_line_pointer++;
2257           break;
2258         case ',':
2259           input_line_pointer++;
2260           break;
2261         }
2262       SKIP_WHITESPACE ();
2263       c = *input_line_pointer;
2264     }
2265
2266   demand_empty_rest_of_line ();
2267 }                               /* stringer() */
2268 \f
2269 /* FIXME-SOMEDAY: I had trouble here on characters with the
2270     high bits set.  We'll probably also have trouble with
2271     multibyte chars, wide chars, etc.  Also be careful about
2272     returning values bigger than 1 byte.  xoxorich. */
2273
2274 unsigned int 
2275 next_char_of_string ()
2276 {
2277   register unsigned int c;
2278
2279   c = *input_line_pointer++ & CHAR_MASK;
2280   switch (c)
2281     {
2282     case '\"':
2283       c = NOT_A_CHAR;
2284       break;
2285
2286     case '\\':
2287       switch (c = *input_line_pointer++)
2288         {
2289         case 'b':
2290           c = '\b';
2291           break;
2292
2293         case 'f':
2294           c = '\f';
2295           break;
2296
2297         case 'n':
2298           c = '\n';
2299           break;
2300
2301         case 'r':
2302           c = '\r';
2303           break;
2304
2305         case 't':
2306           c = '\t';
2307           break;
2308
2309 #ifdef BACKSLASH_V
2310         case 'v':
2311           c = '\013';
2312           break;
2313 #endif
2314
2315         case '\\':
2316         case '"':
2317           break;                /* As itself. */
2318
2319         case '0':
2320         case '1':
2321         case '2':
2322         case '3':
2323         case '4':
2324         case '5':
2325         case '6':
2326         case '7':
2327         case '8':
2328         case '9':
2329           {
2330             long number;
2331
2332             for (number = 0; isdigit (c); c = *input_line_pointer++)
2333               {
2334                 number = number * 8 + c - '0';
2335               }
2336             c = number & 0xff;
2337           }
2338           --input_line_pointer;
2339           break;
2340
2341         case '\n':
2342           /* To be compatible with BSD 4.2 as: give the luser a linefeed!! */
2343           as_warn ("Unterminated string: Newline inserted.");
2344           c = '\n';
2345           break;
2346
2347         default:
2348
2349 #ifdef ONLY_STANDARD_ESCAPES
2350           as_bad ("Bad escaped character in string, '?' assumed");
2351           c = '?';
2352 #endif /* ONLY_STANDARD_ESCAPES */
2353
2354           break;
2355         }                       /* switch on escaped char */
2356       break;
2357
2358     default:
2359       break;
2360     }                           /* switch on char */
2361   return (c);
2362 }                               /* next_char_of_string() */
2363 \f
2364 static segT
2365 get_segmented_expression (expP)
2366      register expressionS *expP;
2367 {
2368   register segT retval;
2369
2370   if ((retval = expression (expP)) == SEG_PASS1 || retval == SEG_ABSENT || retval == SEG_BIG)
2371     {
2372       as_bad ("Expected address expression: absolute 0 assumed");
2373       retval = expP->X_seg = SEG_ABSOLUTE;
2374       expP->X_add_number = 0;
2375       expP->X_add_symbol = expP->X_subtract_symbol = 0;
2376     }
2377   return (retval);              /* SEG_ ABSOLUTE,UNKNOWN,DATA,TEXT,BSS */
2378 }
2379
2380 static segT 
2381 get_known_segmented_expression (expP)
2382      register expressionS *expP;
2383 {
2384   register segT retval;
2385   register char *name1;
2386   register char *name2;
2387
2388   if ((retval = get_segmented_expression (expP)) == SEG_UNKNOWN)
2389     {
2390       name1 = expP->X_add_symbol ? S_GET_NAME (expP->X_add_symbol) : "";
2391       name2 = expP->X_subtract_symbol ?
2392         S_GET_NAME (expP->X_subtract_symbol) :
2393         "";
2394       if (name1 && name2)
2395         {
2396           as_warn ("Symbols \"%s\" \"%s\" are undefined: absolute 0 assumed.",
2397                    name1, name2);
2398         }
2399       else
2400         {
2401           as_warn ("Symbol \"%s\" undefined: absolute 0 assumed.",
2402                    name1 ? name1 : name2);
2403         }
2404       retval = expP->X_seg = SEG_ABSOLUTE;
2405       expP->X_add_number = 0;
2406       expP->X_add_symbol = expP->X_subtract_symbol = NULL;
2407     }
2408 #ifndef MANY_SEGMENTS
2409   know (retval == SEG_ABSOLUTE || retval == SEG_DATA || retval == SEG_TEXT || retval == SEG_BSS || retval == SEG_DIFFERENCE);
2410 #endif
2411   return (retval);
2412
2413 }                               /* get_known_segmented_expression() */
2414
2415
2416
2417 /* static */ long               /* JF was static, but can't be if the MD pseudos are to use it */
2418 get_absolute_expression ()
2419 {
2420   expressionS exp;
2421   register segT s;
2422
2423   if ((s = expression (&exp)) != SEG_ABSOLUTE)
2424     {
2425       if (s != SEG_ABSENT)
2426         {
2427           as_bad ("Bad Absolute Expression, absolute 0 assumed.");
2428         }
2429       exp.X_add_number = 0;
2430     }
2431   return (exp.X_add_number);
2432 }
2433
2434 char                            /* return terminator */
2435 get_absolute_expression_and_terminator (val_pointer)
2436      long *val_pointer;         /* return value of expression */
2437 {
2438   *val_pointer = get_absolute_expression ();
2439   return (*input_line_pointer++);
2440 }
2441 \f
2442 /*
2443  *                      demand_copy_C_string()
2444  *
2445  * Like demand_copy_string, but return NULL if the string contains any '\0's.
2446  * Give a warning if that happens.
2447  */
2448 char *
2449 demand_copy_C_string (len_pointer)
2450      int *len_pointer;
2451 {
2452   register char *s;
2453
2454   if ((s = demand_copy_string (len_pointer)) != 0)
2455     {
2456       register int len;
2457
2458       for (len = *len_pointer;
2459            len > 0;
2460            len--)
2461         {
2462           if (*s == 0)
2463             {
2464               s = 0;
2465               len = 1;
2466               *len_pointer = 0;
2467               as_bad ("This string may not contain \'\\0\'");
2468             }
2469         }
2470     }
2471   return (s);
2472 }
2473 \f
2474 /*
2475  *                      demand_copy_string()
2476  *
2477  * Demand string, but return a safe (=private) copy of the string.
2478  * Return NULL if we can't read a string here.
2479  */
2480 static char *
2481 demand_copy_string (lenP)
2482      int *lenP;
2483 {
2484   register unsigned int c;
2485   register int len;
2486   char *retval;
2487
2488   len = 0;
2489   SKIP_WHITESPACE ();
2490   if (*input_line_pointer == '\"')
2491     {
2492       input_line_pointer++;     /* Skip opening quote. */
2493
2494       while (is_a_char (c = next_char_of_string ()))
2495         {
2496           obstack_1grow (&notes, c);
2497           len++;
2498         }
2499       /* JF this next line is so demand_copy_C_string will return a null
2500                    termanated string. */
2501       obstack_1grow (&notes, '\0');
2502       retval = obstack_finish (&notes);
2503     }
2504   else
2505     {
2506       as_warn ("Missing string");
2507       retval = NULL;
2508       ignore_rest_of_line ();
2509     }
2510   *lenP = len;
2511   return (retval);
2512 }                               /* demand_copy_string() */
2513 \f
2514 /*
2515  *              is_it_end_of_statement()
2516  *
2517  * In:  Input_line_pointer->next character.
2518  *
2519  * Do:  Skip input_line_pointer over all whitespace.
2520  *
2521  * Out: 1 if input_line_pointer->end-of-line.
2522 */
2523 int 
2524 is_it_end_of_statement ()
2525 {
2526   SKIP_WHITESPACE ();
2527   return (is_end_of_line[*input_line_pointer]);
2528 }                               /* is_it_end_of_statement() */
2529
2530 void 
2531 equals (sym_name)
2532      char *sym_name;
2533 {
2534   register symbolS *symbolP;    /* symbol we are working with */
2535
2536   input_line_pointer++;
2537   if (*input_line_pointer == '=')
2538     input_line_pointer++;
2539
2540   while (*input_line_pointer == ' ' || *input_line_pointer == '\t')
2541     input_line_pointer++;
2542
2543   if (sym_name[0] == '.' && sym_name[1] == '\0')
2544     {
2545       /* Turn '. = mumble' into a .org mumble */
2546       register segT segment;
2547       expressionS exp;
2548       register char *p;
2549
2550       segment = get_known_segmented_expression (&exp);
2551       if (!need_pass_2)
2552         {
2553           if (segment != now_seg && segment != SEG_ABSOLUTE)
2554             as_warn ("Illegal segment \"%s\". Segment \"%s\" assumed.",
2555                      segment_name (segment),
2556                      segment_name (now_seg));
2557           p = frag_var (rs_org, 1, 1, (relax_substateT) 0, exp.X_add_symbol,
2558                         exp.X_add_number, (char *) 0);
2559           *p = 0;
2560         }                       /* if (ok to make frag) */
2561     }
2562   else
2563     {
2564       symbolP = symbol_find_or_make (sym_name);
2565       pseudo_set (symbolP);
2566     }
2567 }                               /* equals() */
2568
2569 /* .include -- include a file at this point. */
2570
2571 /* ARGSUSED */
2572 void 
2573 s_include (arg)
2574      int arg;
2575 {
2576   char *newbuf;
2577   char *filename;
2578   int i;
2579   FILE *try;
2580   char *path;
2581
2582   filename = demand_copy_string (&i);
2583   demand_empty_rest_of_line ();
2584   path = xmalloc (i + include_dir_maxlen + 5 /* slop */ );
2585   for (i = 0; i < include_dir_count; i++)
2586     {
2587       strcpy (path, include_dirs[i]);
2588       strcat (path, "/");
2589       strcat (path, filename);
2590       if (0 != (try = fopen (path, "r")))
2591         {
2592           fclose (try);
2593           goto gotit;
2594         }
2595     }
2596   free (path);
2597   path = filename;
2598 gotit:
2599   /* malloc Storage leak when file is found on path.  FIXME-SOMEDAY. */
2600   newbuf = input_scrub_include_file (path, input_line_pointer);
2601   buffer_limit = input_scrub_next_buffer (&input_line_pointer);
2602 }                               /* s_include() */
2603
2604 void 
2605 add_include_dir (path)
2606      char *path;
2607 {
2608   int i;
2609
2610   if (include_dir_count == 0)
2611     {
2612       include_dirs = (char **) xmalloc (2 * sizeof (*include_dirs));
2613       include_dirs[0] = ".";    /* Current dir */
2614       include_dir_count = 2;
2615     }
2616   else
2617     {
2618       include_dir_count++;
2619       include_dirs = (char **) realloc (include_dirs,
2620                                 include_dir_count * sizeof (*include_dirs));
2621     }
2622
2623   include_dirs[include_dir_count - 1] = path;   /* New one */
2624
2625   i = strlen (path);
2626   if (i > include_dir_maxlen)
2627     include_dir_maxlen = i;
2628 }                               /* add_include_dir() */
2629
2630 void 
2631 s_ignore (arg)
2632      int arg;
2633 {
2634   extern char is_end_of_line[];
2635
2636   while (!is_end_of_line[*input_line_pointer])
2637     {
2638       ++input_line_pointer;
2639     }
2640   ++input_line_pointer;
2641
2642   return;
2643 }                               /* s_ignore() */
2644
2645 /* end of read.c */