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