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