* dbxread.c (dbx_symfile_init): Make size of the string table
[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
RP
29
30#define MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT (16)
6efd877d
KR
31/* This is the largest known floating point */
32/* format (for now). It will grow when we */
33/* do 4361 style flonums. */
fecd2382
RP
34
35
016e0d42
ILT
36/* Routines that read assembler source text to build spagetti in memory.
37 Another group of these functions is in the expr.c module. */
fecd2382 38
6efd877d
KR
39#include <ctype.h>
40
fecd2382
RP
41#include "as.h"
42
43#include "obstack.h"
f8701a3f 44#include "listing.h"
fecd2382 45
016e0d42
ILT
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
54char *input_line_pointer; /*->next char of source file to parse. */
fecd2382
RP
55
56#if BITS_PER_CHAR != 8
6efd877d
KR
57/* The following table is indexed by[(char)] and will break if
58 a char does not have exactly 256 states (hopefully 0:255!)! */
59die horribly;
fecd2382 60#endif
f8701a3f 61
016e0d42
ILT
62/* used by is_... macros. our ctype[] */
63const 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/*
fecd2382
RP
84 * In: a character.
85 * Out: 1 if this character ends a line.
86 */
87#define _ (0)
016e0d42
ILT
88char is_end_of_line[256] =
89{
fecd2382 90#ifdef CR_EOL
016e0d42 91 _, _, _, _, _, _, _, _, _, _, 99, _, _, 99, _, _, /* @abcdefghijklmno */
fecd2382 92#else
016e0d42 93 _, _, _, _, _, _, _, _, _, _, 99, _, _, _, _, _, /* @abcdefghijklmno */
fecd2382 94#endif
016e0d42
ILT
95 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
96 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
97 _, _, _, _, _, _, _, _, _, _, _, 99, _, _, _, _, /* 0123456789:;<=>? */
98 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
99 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
100 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
101 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
102 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
103 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
104 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
105 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
106 _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, /* */
107};
fecd2382
RP
108#undef _
109
016e0d42
ILT
110/* Functions private to this file. */
111
112static char *buffer; /* 1st char of each buffer of lines is here. */
113static char *buffer_limit; /*->1 + last char in buffer. */
fecd2382 114
016e0d42
ILT
115static char *bignum_low; /* Lowest char of bignum. */
116static char *bignum_limit; /* 1st illegal address of bignum. */
117static char *bignum_high; /* Highest char of bignum. */
118/* May point to (bignum_start-1). */
119/* Never >= bignum_limit. */
fecd2382 120
016e0d42
ILT
121static char *old_buffer = 0; /* JF a hack */
122static char *old_input;
123static char *old_limit;
fecd2382 124
016e0d42 125/* Variables for handling include file directory list. */
fecd2382 126
016e0d42
ILT
127char **include_dirs; /* List of pointers to directories to
128 search for .include's */
129int include_dir_count; /* How many are in the list */
130int include_dir_maxlen = 1;/* Length of longest in list */
fecd2382
RP
131
132#ifndef WORKING_DOT_WORD
016e0d42
ILT
133struct broken_word *broken_words;
134int new_broken_words = 0;
fecd2382
RP
135#endif
136
016e0d42
ILT
137static char *demand_copy_string PARAMS ((int *lenP));
138int is_it_end_of_statement PARAMS ((void));
139unsigned int next_char_of_string PARAMS ((void));
140static segT get_known_segmented_expression PARAMS ((expressionS * expP));
141static void grow_bignum PARAMS ((void));
142static void pobegin PARAMS ((void));
143void stringer PARAMS ((int append_zero));
fecd2382 144
016e0d42 145extern int listing;
fecd2382 146\f
6efd877d 147
016e0d42
ILT
148void
149read_begin ()
fecd2382 150{
016e0d42 151 const char *p;
f8701a3f 152
6efd877d
KR
153 pobegin ();
154 obj_read_begin_hook ();
f8701a3f 155
6efd877d
KR
156 obstack_begin (&notes, 5000);
157 obstack_begin (&cond_obstack, 960);
f8701a3f 158
fecd2382 159#define BIGNUM_BEGIN_SIZE (16)
6efd877d 160 bignum_low = xmalloc ((long) BIGNUM_BEGIN_SIZE);
f8701a3f
SC
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. */
fecd2382
RP
167}
168\f
169/* set up pseudo-op tables */
170
c8863a58 171struct hash_control *po_hash;
fecd2382 172
016e0d42 173static const pseudo_typeS potable[] =
fecd2382 174{
6efd877d
KR
175 {"abort", s_abort, 0},
176 {"align", s_align_ptwo, 0},
177 {"ascii", stringer, 0},
178 {"asciz", stringer, 1},
f8701a3f 179/* block */
6efd877d
KR
180 {"byte", cons, 1},
181 {"comm", s_comm, 0},
182 {"data", s_data, 0},
f8701a3f 183/* dim */
6efd877d 184 {"double", float_cons, 'd'},
f8701a3f 185/* dsect */
6efd877d
KR
186 {"eject", listing_eject, 0}, /* Formfeed listing */
187 {"else", s_else, 0},
188 {"end", s_end, 0},
189 {"endif", s_endif, 0},
f8701a3f 190/* endef */
6efd877d 191 {"equ", s_set, 0},
f8701a3f
SC
192/* err */
193/* extend */
6efd877d
KR
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'},
f8701a3f 199#ifdef DONTDEF
6efd877d
KR
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},
f8701a3f 206#endif
6efd877d
KR
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 */
f8701a3f 227/* print */
6efd877d
KR
228 {"quad", big_cons, 8},
229 {"sbttl", listing_title, 1}, /* Subtitle of listing */
f8701a3f
SC
230/* scl */
231/* sect */
6efd877d
KR
232 {"set", s_set, 0},
233 {"short", cons, 2},
234 {"single", float_cons, 'f'},
f8701a3f 235/* size */
6efd877d 236 {"space", s_space, 0},
f8701a3f 237/* tag */
6efd877d
KR
238 {"text", s_text, 0},
239 {"title", listing_title, 0}, /* Listing title */
f8701a3f
SC
240/* type */
241/* use */
242/* val */
6efd877d
KR
243 {"word", cons, 2},
244 {NULL} /* end sentinel */
fecd2382
RP
245};
246
6efd877d
KR
247static void
248pobegin ()
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 {
fecd2382 273#ifdef DIE_ON_OVERRIDES
6efd877d 274 as_fatal ("pseudo op \".%s\" overridden.\n", pop->poc_name);
fecd2382 275#endif /* DIE_ON_OVERRIDES */
6efd877d
KR
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 {
fecd2382 293#ifdef DIE_ON_OVERRIDES
6efd877d 294 as_fatal ("pseudo op \".%s\" overridden.\n", pop->poc_name);
fecd2382 295#endif /* DIE_ON_OVERRIDES */
6efd877d
KR
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() */
fecd2382
RP
307\f
308#define HANDLE_CONDITIONAL_ASSEMBLY() \
f8701a3f
SC
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 }
a39116f1 316
fecd2382
RP
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 */
6efd877d
KR
323void
324read_a_source_file (name)
325 char *name;
fecd2382 326{
f8701a3f 327 register char c;
6efd877d 328 register char *s; /* string of symbol, '\0' appended */
f8701a3f 329 register int temp;
6efd877d
KR
330 /* register struct frag * fragP; JF unused *//* a frag we just made */
331 pseudo_typeS *pop;
f8701a3f 332
6efd877d 333 buffer = input_scrub_new_file (name);
f8701a3f 334
6efd877d
KR
335 listing_file (name);
336 listing_newline ("");
f8701a3f 337
6efd877d
KR
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
f8701a3f 342 the whole input section here? Pleeze??? */
6efd877d
KR
343 while (input_line_pointer < buffer_limit)
344 { /* We have more of this buffer to parse. */
f8701a3f
SC
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 */
6efd877d
KR
351 if (input_line_pointer[-1] == '\n')
352 {
353 bump_line_counters ();
f8701a3f
SC
354
355#ifdef MRI
356 /* Text at the start of a line must be a label, we run down and stick a colon in */
6efd877d
KR
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 }
f8701a3f 367#endif
6efd877d
KR
368 } /* just passed a newline */
369
f8701a3f
SC
370
371
372
373
f8701a3f
SC
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 */
6efd877d
KR
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 ();
f8701a3f
SC
394 /*
395 * C is the 1st significant character.
396 * Input_line_pointer points after that character.
397 */
6efd877d
KR
398 if (is_name_beginner (c))
399 { /* want user-defined label or pseudo/opcode */
400 HANDLE_CONDITIONAL_ASSEMBLY ();
401
f8701a3f 402 s = --input_line_pointer;
6efd877d 403 c = get_symbol_end (); /* name's delimiter */
f8701a3f
SC
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 */
6efd877d
KR
411 if (c == ':')
412 {
413 colon (s); /* user-defined label */
414 *input_line_pointer++ = ':'; /* Put ':' back for error messages' sake. */
f8701a3f 415 /* Input_line_pointer->after ':'. */
6efd877d
KR
416 SKIP_WHITESPACE ();
417
f8701a3f 418
6efd877d
KR
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 */
f8701a3f 427#ifdef MRI
6efd877d
KR
428 if (!done_pseudo (s))
429
f8701a3f 430#else
6efd877d
KR
431 if (*s == '.')
432 {
433 /*
f8701a3f
SC
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 */
6efd877d
KR
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);
f8701a3f 447 *input_line_pointer = c;
6efd877d
KR
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 /*
f8701a3f
SC
461 * Input_line is restored.
462 * Input_line_pointer->1st non-blank char
463 * after pseudo-operation.
464 */
6efd877d
KR
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
f8701a3f 476#endif
6efd877d
KR
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 }
f8701a3f 485
6efd877d
KR
486 c = *input_line_pointer;
487 *input_line_pointer = '\0';
f8701a3f 488
6efd877d 489 md_assemble (s); /* Assemble 1 instruction. */
f8701a3f 490
6efd877d 491 *input_line_pointer++ = c;
f8701a3f 492
6efd877d
KR
493 /* We resume loop AFTER the end-of-line from this instruction */
494 } /* if (*s=='.') */
495
496 } /* if c==':' */
f8701a3f 497 continue;
6efd877d 498 } /* if (is_name_beginner(c) */
f8701a3f 499
f8701a3f 500
6efd877d
KR
501 if (is_end_of_line[c])
502 {
f8701a3f 503 continue;
6efd877d
KR
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 }
f8701a3f 537#endif /* LOCAL_LABELS_DOLLAR */
6efd877d 538
f8701a3f 539#ifdef LOCAL_LABELS_FB
6efd877d
KR
540 if (*input_line_pointer++ == ':')
541 {
542 fb_label_instance_inc (temp);
543 colon (fb_label_name (temp, 0));
544 continue;
545 }
f8701a3f 546#endif /* LOCAL_LABELS_FB */
6efd877d
KR
547
548 input_line_pointer = backup;
549 } /* local label ("4:") */
f8701a3f
SC
550#endif /* LOCAL_LABELS_DOLLAR or LOCAL_LABELS_FB */
551
6efd877d
KR
552 if (c && strchr (line_comment_chars, c))
553 { /* Its a comment. Better say APP or NO_APP */
f8701a3f
SC
554 char *ends;
555 char *new_buf;
556 char *new_tmp;
557 int new_length;
558 char *tmp_buf = 0;
6efd877d
KR
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 {
f8701a3f
SC
571 int tmp_len;
572 int num;
6efd877d 573
f8701a3f
SC
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. . . */
6efd877d 578 tmp_len = buffer_limit - s;
85825401 579 tmp_buf = xmalloc (tmp_len + 1);
6efd877d
KR
580 bcopy (s, tmp_buf, tmp_len);
581 do
582 {
583 new_tmp = input_scrub_next_buffer (&buffer);
f8701a3f 584 if (!new_tmp)
6efd877d 585 break;
f8701a3f 586 else
6efd877d 587 buffer_limit = new_tmp;
f8701a3f 588 input_line_pointer = buffer;
6efd877d 589 ends = strstr (buffer, "#NO_APP\n");
f8701a3f 590 if (ends)
6efd877d 591 num = ends - buffer;
f8701a3f 592 else
6efd877d
KR
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;
f8701a3f 616 scrub_last_string = ends;
6efd877d
KR
617 for (;;)
618 {
f8701a3f
SC
619 int ch;
620
6efd877d
KR
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;
f8701a3f 630 }
fecd2382 631 }
f8701a3f
SC
632
633 if (tmp_buf)
6efd877d
KR
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;
f8701a3f
SC
641 continue;
642 }
643
6efd877d 644 HANDLE_CONDITIONAL_ASSEMBLY ();
f8701a3f
SC
645
646 /* as_warn("Junk character %d.",c); Now done by ignore_rest */
647 input_line_pointer--; /* Report unknown char as ignored. */
6efd877d
KR
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;
f8701a3f
SC
658 old_buffer = 0;
659 goto contin;
660 }
661 }
6efd877d
KR
662 } /* while (more buffers to scan) */
663 input_scrub_close (); /* Close the input file */
f8701a3f 664
6efd877d 665} /* read_a_source_file() */
fecd2382 666
6efd877d
KR
667void
668s_abort ()
669{
670 as_fatal (".abort detected. Abandoning ship.");
671} /* s_abort() */
fecd2382
RP
672
673/* For machines where ".align 4" means align to a 4 byte boundary. */
6efd877d
KR
674void
675s_align_bytes (arg)
676 int arg;
fecd2382 677{
6efd877d
KR
678 register unsigned int temp;
679 register long temp_fill;
680 unsigned int i = 0;
681 unsigned long max_alignment = 1 << 15;
f8701a3f 682
6efd877d
KR
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 ();
f8701a3f 687
6efd877d
KR
688 if (temp > max_alignment)
689 {
690 as_bad ("Alignment too large: %d. assumed.", temp = max_alignment);
f8701a3f
SC
691 }
692
6efd877d 693 /*
f8701a3f
SC
694 * For the sparc, `.align (1<<n)' actually means `.align n'
695 * so we have to convert it.
696 */
6efd877d
KR
697 if (temp != 0)
698 {
699 for (i = 0; (temp & 1) == 0; temp >>= 1, ++i)
700 ;
f8701a3f 701 }
6efd877d
KR
702 if (temp != 1)
703 as_bad ("Alignment not a power of 2");
f8701a3f 704
6efd877d
KR
705 temp = i;
706 if (*input_line_pointer == ',')
707 {
708 input_line_pointer++;
709 temp_fill = get_absolute_expression ();
f8701a3f 710 }
016e0d42
ILT
711 else if (now_seg != SEG_DATA && now_seg != SEG_BSS)
712 temp_fill = NOP_OPCODE;
6efd877d 713 else
016e0d42 714 temp_fill = 0;
6efd877d
KR
715 /* Only make a frag if we HAVE to. . . */
716 if (temp && !need_pass_2)
717 frag_align (temp, (int) temp_fill);
f8701a3f 718
6efd877d
KR
719 demand_empty_rest_of_line ();
720} /* s_align_bytes() */
fecd2382
RP
721
722/* For machines where ".align 4" means align to 2**4 boundary. */
6efd877d
KR
723void
724s_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 }
016e0d42
ILT
743 else if (now_seg != SEG_DATA && now_seg != SEG_BSS)
744 temp_fill = NOP_OPCODE;
6efd877d
KR
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
756void
757s_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 }
fecd2382 806#ifdef VMS
6efd877d
KR
807 if (!temp)
808 symbolP->sy_other = const_flag;
fecd2382 809#endif
6efd877d
KR
810 know (symbolP->sy_frag == &zero_address_frag);
811 demand_empty_rest_of_line ();
812} /* s_comm() */
fecd2382
RP
813
814void
6efd877d 815s_data ()
fecd2382 816{
6efd877d 817 register int temp;
f8701a3f 818
6efd877d 819 temp = get_absolute_expression ();
db81c5e7 820#ifdef BFD_ASSEMBLER
c8863a58 821 subseg_set (data_section, (subsegT) temp);
db81c5e7
KR
822#else
823 subseg_change (data_section, (subsegT) temp);
824#endif
f8701a3f 825
fecd2382 826#ifdef VMS
6efd877d 827 const_flag = 0;
fecd2382 828#endif
6efd877d 829 demand_empty_rest_of_line ();
fecd2382
RP
830}
831
6efd877d
KR
832void
833s_app_file ()
834{
835 register char *s;
836 int length;
f8701a3f 837
6efd877d
KR
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 }
fecd2382 844#ifdef OBJ_COFF
6efd877d 845 c_dot_file_symbol (s);
fecd2382 846#endif /* OBJ_COFF */
6efd877d 847} /* s_app_file() */
fecd2382 848
6efd877d
KR
849void
850s_fill ()
851{
852 long temp_repeat = 0;
853 long temp_size = 1;
854 register long temp_fill = 0;
855 char *p;
f8701a3f 856
7c2d4011 857
6efd877d
KR
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 == ',')
7c2d4011
SC
864 {
865 input_line_pointer++;
6efd877d 866 temp_fill = get_absolute_expression ();
fecd2382 867 }
6efd877d 868 }
c8863a58 869 /* This is to be compatible with BSD 4.2 AS, not for any rational reason. */
fecd2382 870#define BSD_FILL_SIZE_CROCK_8 (8)
6efd877d
KR
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 }
7fd3560a 886
6efd877d
KR
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);
c8863a58
KR
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. */
fecd2382 896#define BSD_FILL_SIZE_CROCK_4 (4)
c8863a58
KR
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 */
6efd877d 905 }
6efd877d 906 demand_empty_rest_of_line ();
f8701a3f
SC
907}
908
6efd877d
KR
909void
910s_globl ()
911{
912 register char *name;
913 register int c;
914 register symbolS *symbolP;
fecd2382 915
6efd877d
KR
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
936void
937s_lcomm (needs_align)
c8863a58
KR
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;
fecd2382 941{
6efd877d
KR
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 }
f8701a3f 961
6efd877d 962 ++input_line_pointer;
f8701a3f 963
6efd877d
KR
964 if (*input_line_pointer == '\n')
965 {
966 as_bad ("Missing size expression");
967 return;
968 }
f8701a3f 969
6efd877d
KR
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 }
f8701a3f 976
6efd877d
KR
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 }
c8863a58 1005 record_alignment (bss_section, align);
6efd877d 1006 } /* if needs align */
f8701a3f 1007
6efd877d
KR
1008 *p = 0;
1009 symbolP = symbol_find_or_make (name);
1010 *p = c;
f8701a3f 1011
6efd877d 1012 if (
fecd2382 1013#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
6efd877d
KR
1014 S_GET_OTHER (symbolP) == 0 &&
1015 S_GET_DESC (symbolP) == 0 &&
fecd2382 1016#endif /* OBJ_AOUT or OBJ_BOUT */
c8863a58 1017 (S_GET_SEGMENT (symbolP) == bss_section
6efd877d
KR
1018 || (!S_IS_DEFINED (symbolP) && S_GET_VALUE (symbolP) == 0)))
1019 {
85825401
ILT
1020 char *p;
1021 segT current_seg = now_seg;
1022 subsegT current_subseg = now_subseg;
1023
c8863a58 1024 subseg_new (bss_section, 1);
85825401
ILT
1025
1026 if (align)
1027 frag_align (align, 0);
1028 /* detach from old frag */
c8863a58 1029 if (S_GET_SEGMENT (symbolP) == bss_section)
85825401
ILT
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;
f8701a3f 1036
c8863a58 1037 S_SET_SEGMENT (symbolP, bss_section);
85825401 1038
fecd2382 1039#ifdef OBJ_COFF
6efd877d 1040 /* The symbol may already have been created with a preceding
c8863a58
KR
1041 ".globl" directive -- be careful not to step on storage class
1042 in that case. Otherwise, set it to static. */
6efd877d
KR
1043 if (S_GET_STORAGE_CLASS (symbolP) != C_EXT)
1044 {
1045 S_SET_STORAGE_CLASS (symbolP, C_STAT);
fecd2382 1046 }
6efd877d 1047#endif /* OBJ_COFF */
85825401 1048 subseg_new (current_seg, current_subseg);
6efd877d
KR
1049 }
1050 else
1051 {
85825401 1052 as_bad ("Ignoring attempt to re-define symbol %s.", name);
6efd877d
KR
1053 }
1054 demand_empty_rest_of_line ();
f8701a3f 1055
6efd877d
KR
1056 return;
1057} /* s_lcomm() */
fecd2382
RP
1058
1059void
6efd877d 1060s_long ()
fecd2382 1061{
6efd877d 1062 cons (4);
fecd2382
RP
1063}
1064
1065void
6efd877d 1066s_int ()
fecd2382 1067{
6efd877d 1068 cons (4);
fecd2382
RP
1069}
1070
6efd877d
KR
1071void
1072s_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
a39116f1 1098#ifdef MANY_SEGMENTS
6efd877d 1099 && !(segment >= SEG_E0 && segment <= SEG_UNKNOWN)
a39116f1 1100#else
6efd877d
KR
1101 && segment != SEG_DATA
1102 && segment != SEG_TEXT
1103 && segment != SEG_BSS
a39116f1 1104#endif
6efd877d
KR
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);
f8701a3f 1113
c8863a58
KR
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. */
f8701a3f 1120
6efd877d
KR
1121 if (S_GET_SEGMENT (symbolP) == SEG_UNKNOWN
1122 && S_GET_VALUE (symbolP) == 0)
1123 {
c8863a58
KR
1124 /* The name might be an undefined .global symbol; be sure to
1125 keep the "external" bit. */
6efd877d
KR
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
1137void
1138s_org ()
1139{
1140 register segT segment;
1141 expressionS exp;
1142 register long temp_fill;
1143 register char *p;
1144 /*
f8701a3f
SC
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 */
6efd877d 1156 /*
f8701a3f
SC
1157 * Don't make frag if need_pass_2==1.
1158 */
6efd877d
KR
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
1179void
1180s_set ()
1181{
1182 register char *name;
1183 register char delim;
1184 register char *end_name;
1185 register symbolS *symbolP;
1186
1187 /*
c8863a58
KR
1188 * Especial apologies for the random logic:
1189 * this just grew, and could be parsed much more simply!
1190 * Dean in haste.
1191 */
6efd877d
KR
1192 name = input_line_pointer;
1193 delim = get_symbol_end ();
1194 end_name = input_line_pointer;
1195 *end_name = delim;
1196 SKIP_WHITESPACE ();
f8701a3f 1197
6efd877d
KR
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);
f8701a3f 1218
6efd877d
KR
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);
fecd2382 1241#ifdef OBJ_COFF
6efd877d
KR
1242 /* "set" symbols are local unless otherwise specified. */
1243 SF_SET_LOCAL (symbolP);
fecd2382 1244#endif /* OBJ_COFF */
f8701a3f 1245
6efd877d 1246 } /* make a new symbol */
f8701a3f 1247
6efd877d 1248 symbol_table_insert (symbolP);
f8701a3f 1249
6efd877d
KR
1250 *end_name = delim;
1251 pseudo_set (symbolP);
1252 demand_empty_rest_of_line ();
1253} /* s_set() */
fecd2382 1254
6efd877d
KR
1255void
1256s_space (mult)
1257 int mult;
b53ccaac 1258{
6efd877d
KR
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() */
fecd2382
RP
1291
1292void
6efd877d 1293s_text ()
fecd2382 1294{
6efd877d 1295 register int temp;
f8701a3f 1296
6efd877d 1297 temp = get_absolute_expression ();
a39116f1 1298#ifdef MANY_SEGMENTS
6efd877d 1299 subseg_new (SEG_E0, (subsegT) temp);
a39116f1 1300#else
6efd877d 1301 subseg_new (SEG_TEXT, (subsegT) temp);
a39116f1 1302#endif
6efd877d
KR
1303 demand_empty_rest_of_line ();
1304} /* s_text() */
fecd2382 1305\f
6efd877d 1306
fecd2382
RP
1307/*(JF was static, but can't be if machine dependent pseudo-ops are to use it */
1308
6efd877d
KR
1309void
1310demand_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. */
fecd2382
RP
1323
1324void
6efd877d 1325ignore_rest_of_line () /* For suspect lines: gives warning. */
fecd2382 1326{
6efd877d 1327 if (!is_end_of_line[*input_line_pointer])
f8701a3f 1328 {
6efd877d
KR
1329 if (isprint (*input_line_pointer))
1330 as_bad ("Rest of line ignored. First ignored character is `%c'.",
f8701a3f
SC
1331 *input_line_pointer);
1332 else
6efd877d 1333 as_bad ("Rest of line ignored. First ignored character valued 0x%x.",
f8701a3f
SC
1334 *input_line_pointer);
1335 while (input_line_pointer < buffer_limit
6efd877d 1336 && !is_end_of_line[*input_line_pointer])
f8701a3f 1337 {
6efd877d 1338 input_line_pointer++;
f8701a3f
SC
1339 }
1340 }
6efd877d
KR
1341 input_line_pointer++; /* Return pointing just after end-of-line. */
1342 know (is_end_of_line[input_line_pointer[-1]]);
fecd2382
RP
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 */
1356void
f8701a3f 1357pseudo_set (symbolP)
6efd877d 1358 symbolS *symbolP;
fecd2382 1359{
6efd877d
KR
1360 expressionS exp;
1361 register segT segment;
fecd2382 1362#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
f8701a3f 1363 int ext;
fecd2382 1364#endif /* OBJ_AOUT or OBJ_BOUT */
f8701a3f 1365
6efd877d 1366 know (symbolP); /* NULL pointer is logic error. */
fecd2382 1367#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
6efd877d 1368 ext = S_IS_EXTERNAL (symbolP);
fecd2382 1369#endif /* OBJ_AOUT or OBJ_BOUT */
f8701a3f 1370
6efd877d 1371 if ((segment = expression (&exp)) == SEG_ABSENT)
f8701a3f 1372 {
6efd877d
KR
1373 as_bad ("Missing expression: absolute 0 assumed");
1374 exp.X_seg = SEG_ABSOLUTE;
1375 exp.X_add_number = 0;
f8701a3f
SC
1376 }
1377
1378 switch (segment)
1379 {
6efd877d
KR
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;
f8701a3f
SC
1384 break;
1385
1386 case SEG_BIG:
6efd877d
KR
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);
fecd2382 1390#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
6efd877d
KR
1391 ext ? S_SET_EXTERNAL (symbolP) :
1392 S_CLEAR_EXTERNAL (symbolP);
fecd2382 1393#endif /* OBJ_AOUT or OBJ_BOUT */
6efd877d
KR
1394 S_SET_VALUE (symbolP, 0);
1395 symbolP->sy_frag = &zero_address_frag;
f8701a3f
SC
1396 break;
1397
1398 case SEG_ABSENT:
6efd877d
KR
1399 as_warn ("No expression: Using absolute 0");
1400 S_SET_SEGMENT (symbolP, SEG_ABSOLUTE);
fecd2382 1401#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
6efd877d
KR
1402 ext ? S_SET_EXTERNAL (symbolP) :
1403 S_CLEAR_EXTERNAL (symbolP);
fecd2382 1404#endif /* OBJ_AOUT or OBJ_BOUT */
6efd877d
KR
1405 S_SET_VALUE (symbolP, 0);
1406 symbolP->sy_frag = &zero_address_frag;
f8701a3f
SC
1407 break;
1408
1409 case SEG_DIFFERENCE:
1410 if (exp.X_add_symbol && exp.X_subtract_symbol
6efd877d
KR
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);
f8701a3f 1422 }
6efd877d
KR
1423 else
1424 as_bad ("Complex expression. Absolute segment assumed.");
f8701a3f 1425 case SEG_ABSOLUTE:
6efd877d 1426 S_SET_SEGMENT (symbolP, SEG_ABSOLUTE);
fecd2382 1427#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
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;
f8701a3f
SC
1433 break;
1434
1435 default:
a39116f1 1436#ifdef MANY_SEGMENTS
6efd877d 1437 S_SET_SEGMENT (symbolP, segment);
a39116f1 1438#else
6efd877d
KR
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;
f8701a3f 1450
6efd877d
KR
1451 default:
1452 as_fatal ("failed sanity check.");
1453 } /* switch on segment */
a39116f1 1454#endif
fecd2382 1455#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
6efd877d
KR
1456 if (ext)
1457 {
1458 S_SET_EXTERNAL (symbolP);
1459 }
1460 else
1461 {
1462 S_CLEAR_EXTERNAL (symbolP);
1463 } /* if external */
fecd2382 1464#endif /* OBJ_AOUT or OBJ_BOUT */
f8701a3f 1465
6efd877d
KR
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;
f8701a3f
SC
1468 break;
1469
1470 case SEG_PASS1: /* Not an error. Just try another pass. */
6efd877d
KR
1471 symbolP->sy_forward = exp.X_add_symbol;
1472 as_bad ("Unknown expression");
1473 know (need_pass_2 == 1);
f8701a3f
SC
1474 break;
1475
1476 case SEG_UNKNOWN:
6efd877d 1477 symbolP->sy_forward = exp.X_add_symbol;
f8701a3f
SC
1478 /* as_warn("unknown symbol"); */
1479 /* need_pass_2 = 1; */
1480 break;
1481
1482
1483
1484 }
fecd2382
RP
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
6efd877d
KR
1502/* worker to do .byte etc statements */
1503/* clobbers input_line_pointer, checks */
1504/* end-of-line. */
1505void
1506cons (nbytes)
1507 register unsigned int nbytes; /* 1=.byte, 2=.word, 4=.long */
fecd2382 1508{
f8701a3f 1509 register char c;
6efd877d 1510 register long mask; /* High-order bits we will left-truncate, */
f8701a3f 1511 /* but includes sign bit also. */
6efd877d
KR
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;
f8701a3f
SC
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
6efd877d
KR
1526 if (nbytes >= sizeof (long))
1527 {
f8701a3f 1528 mask = 0;
6efd877d
KR
1529 }
1530 else
1531 {
1532 mask = ~0 << (BITS_PER_CHAR * nbytes); /* Don't store these bits. */
1533 } /* bigger than a long */
f8701a3f 1534
6efd877d 1535 unmask = ~mask; /* Do store these bits. */
f8701a3f 1536
fecd2382 1537#ifdef NEVER
f8701a3f 1538 "Do this mod if you want every overflow check to assume SIGNED 2's complement data.";
6efd877d 1539 mask = ~(unmask >> 1); /* Includes sign bit now. */
fecd2382 1540#endif
f8701a3f
SC
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 */
6efd877d
KR
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 */
f8701a3f
SC
1557
1558 /* Do loop. */
6efd877d
KR
1559 while (c == ',')
1560 {
fecd2382 1561#ifdef WANT_BITFIELDS
f8701a3f
SC
1562 unsigned int bits_available = BITS_PER_CHAR * nbytes;
1563 /* used for error messages and rescanning */
1564 char *hold = input_line_pointer;
fecd2382 1565#endif /* WANT_BITFIELDS */
f8701a3f 1566#ifdef MRI
6efd877d
KR
1567 if (*input_line_pointer == '\'')
1568 {
1569 /* An MRI style string, cut into as many bytes as will fit
f8701a3f
SC
1570 into a nbyte chunk, left justify if necessary, and sepatate
1571 with commas so we can try again later */
6efd877d
KR
1572 int scan = 0;
1573 unsigned int result = 0;
1574 input_line_pointer++;
1575 for (scan = 0; scan < nbytes; scan++)
f8701a3f 1576 {
6efd877d
KR
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++);
f8701a3f 1587 }
6efd877d
KR
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
f8701a3f 1610 }
6efd877d 1611 else
f8701a3f 1612#endif
6efd877d
KR
1613 /* At least scan over the expression. */
1614 segment = expression (&exp);
f8701a3f 1615
a39116f1 1616#ifdef WANT_BITFIELDS
f8701a3f
SC
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.
6efd877d 1624
f8701a3f
SC
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".
6efd877d 1630
f8701a3f
SC
1631 FIXME-SOMEDAY: If this is considered generally
1632 useful, this logic should probably be reworked.
1633 xoxorich. */
1634
6efd877d
KR
1635 if (*input_line_pointer == ':')
1636 { /* bitfields */
f8701a3f
SC
1637 long value = 0;
1638
6efd877d
KR
1639 for (;;)
1640 {
f8701a3f 1641 unsigned long width;
6efd877d
KR
1642
1643 if (*input_line_pointer != ':')
1644 {
f8701a3f
SC
1645 input_line_pointer = hold;
1646 break;
6efd877d
KR
1647 } /* next piece is not a bitfield */
1648
f8701a3f
SC
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.
6efd877d 1657
f8701a3f
SC
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. */
6efd877d
KR
1666
1667 if (segment == SEG_ABSENT)
1668 {
1669 as_warn ("Using a bit field width of zero.");
f8701a3f
SC
1670 exp.X_add_number = 0;
1671 segment = SEG_ABSOLUTE;
6efd877d
KR
1672 } /* implied zero width bitfield */
1673
1674 if (segment != SEG_ABSOLUTE)
1675 {
f8701a3f 1676 *input_line_pointer = '\0';
6efd877d 1677 as_bad ("Field width \"%s\" too complex for a bitfield.\n", hold);
f8701a3f 1678 *input_line_pointer = ':';
6efd877d 1679 demand_empty_rest_of_line ();
f8701a3f 1680 return;
6efd877d
KR
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));
f8701a3f 1687 width = BITS_PER_CHAR * nbytes;
6efd877d
KR
1688 } /* too big */
1689
1690 if (width > bits_available)
1691 {
f8701a3f
SC
1692 /* FIXME-SOMEDAY: backing up and
1693 reparsing is wasteful */
1694 input_line_pointer = hold;
1695 exp.X_add_number = value;
1696 break;
6efd877d
KR
1697 } /* won't fit */
1698
1699 hold = ++input_line_pointer; /* skip ':' */
1700
1701 if ((segment = expression (&exp)) != SEG_ABSOLUTE)
1702 {
f8701a3f 1703 char cache = *input_line_pointer;
6efd877d 1704
f8701a3f 1705 *input_line_pointer = '\0';
6efd877d 1706 as_bad ("Field value \"%s\" too complex for a bitfield.\n", hold);
f8701a3f 1707 *input_line_pointer = cache;
6efd877d 1708 demand_empty_rest_of_line ();
f8701a3f 1709 return;
6efd877d
KR
1710 } /* too complex */
1711
f8701a3f 1712 value |= (~(-1 << width) & exp.X_add_number)
6efd877d
KR
1713 << ((BITS_PER_CHAR * nbytes) - bits_available);
1714
f8701a3f 1715 if ((bits_available -= width) == 0
6efd877d
KR
1716 || is_it_end_of_statement ()
1717 || *input_line_pointer != ',')
1718 {
f8701a3f 1719 break;
6efd877d 1720 } /* all the bitfields we're gonna get */
f8701a3f
SC
1721
1722 hold = ++input_line_pointer;
6efd877d
KR
1723 segment = expression (&exp);
1724 } /* forever loop */
f8701a3f
SC
1725
1726 exp.X_add_number = value;
1727 segment = SEG_ABSOLUTE;
6efd877d 1728 } /* if looks like a bitfield */
a39116f1 1729#endif /* WANT_BITFIELDS */
f8701a3f 1730
6efd877d
KR
1731 if (!need_pass_2)
1732 { /* Still worthwhile making frags. */
f8701a3f
SC
1733
1734 /* Don't call this if we are going to junk this pass anyway! */
6efd877d 1735 know (segment != SEG_PASS1);
f8701a3f 1736
6efd877d
KR
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)));
f8701a3f
SC
1742 segment = SEG_ABSOLUTE;
1743 /* Leave exp . X_add_number alone. */
1744 }
6efd877d
KR
1745 p = frag_more (nbytes);
1746 switch (segment)
1747 {
f8701a3f 1748 case SEG_BIG:
6efd877d
KR
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);
f8701a3f
SC
1752 break;
1753
1754 case SEG_ABSENT:
6efd877d
KR
1755 as_warn ("0 assumed for missing expression");
1756 exp.X_add_number = 0;
1757 know (exp.X_add_symbol == NULL);
f8701a3f
SC
1758 /* fall into SEG_ABSOLUTE */
1759 case SEG_ABSOLUTE:
6efd877d 1760 get = exp.X_add_number;
f8701a3f
SC
1761 use = get & unmask;
1762 if ((get & mask) && (get & mask) != mask)
6efd877d
KR
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. */
f8701a3f
SC
1767 break;
1768
1769 case SEG_DIFFERENCE:
fecd2382 1770#ifndef WORKING_DOT_WORD
6efd877d
KR
1771 if (nbytes == 2)
1772 {
f8701a3f
SC
1773 struct broken_word *x;
1774
6efd877d
KR
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;
f8701a3f
SC
1785 new_broken_words++;
1786 break;
1787 }
1788 /* Else Fall through into. . . */
fecd2382 1789#endif
f8701a3f
SC
1790 default:
1791 case SEG_UNKNOWN:
fecd2382 1792#ifdef TC_NS32K
f8701a3f 1793 fix_new_ns32k (frag_now, p - frag_now->fr_literal, nbytes,
6efd877d
KR
1794 exp.X_add_symbol, exp.X_subtract_symbol,
1795 exp.X_add_number, 0, 0, 2, 0, 0);
fecd2382 1796#else
f8701a3f
SC
1797# if defined(TC_SPARC) || defined(TC_A29K)
1798 fix_new (frag_now, p - frag_now->fr_literal, nbytes,
6efd877d
KR
1799 exp.X_add_symbol, exp.X_subtract_symbol,
1800 exp.X_add_number, 0, RELOC_32);
f8701a3f
SC
1801# else
1802# if defined(TC_H8300)
1803 fix_new (frag_now, p - frag_now->fr_literal, nbytes,
6efd877d
KR
1804 exp.X_add_symbol, exp.X_subtract_symbol,
1805 exp.X_add_number, 0, R_RELWORD);
f8701a3f
SC
1806
1807# else
6efd877d 1808#ifdef NO_RELOC
f8701a3f 1809 fix_new (frag_now, p - frag_now->fr_literal, nbytes,
6efd877d
KR
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 */
fecd2382 1819#endif /* TC_NS32K */
f8701a3f 1820 break;
6efd877d
KR
1821 } /* switch(segment) */
1822 } /* if (!need_pass_2) */
f8701a3f 1823 c = *input_line_pointer++;
6efd877d
KR
1824 } /* while(c==',') */
1825 input_line_pointer--; /* Put terminator back into stream. */
1826 demand_empty_rest_of_line ();
1827} /* cons() */
fecd2382
RP
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
6efd877d
KR
1854void
1855big_cons (nbytes)
f8701a3f 1856 register int nbytes;
fecd2382 1857{
6efd877d 1858 register char c; /* input_line_pointer->c. */
f8701a3f 1859 register int radix;
6efd877d
KR
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. */
f8701a3f
SC
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 */
6efd877d 1874 if (is_it_end_of_statement ())
f8701a3f
SC
1875 {
1876 c = 0; /* Skip loop. */
1877 }
1878 else
1879 {
1880 c = ','; /* Do loop. */
6efd877d 1881 --input_line_pointer;
f8701a3f
SC
1882 }
1883 while (c == ',')
1884 {
6efd877d
KR
1885 ++input_line_pointer;
1886 SKIP_WHITESPACE ();
1887 c = *input_line_pointer;
f8701a3f
SC
1888 /* C contains 1st non-blank character of what we hope is a number. */
1889 if (c == '0')
1890 {
6efd877d
KR
1891 c = *++input_line_pointer;
1892 if (c == 'x' || c == 'X')
fecd2382 1893 {
6efd877d 1894 c = *++input_line_pointer;
f8701a3f 1895 radix = 16;
fecd2382 1896 }
f8701a3f 1897 else
fecd2382 1898 {
f8701a3f 1899 radix = 8;
fecd2382 1900 }
f8701a3f
SC
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 */
6efd877d
KR
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)
f8701a3f
SC
1917 {
1918 /* Multiply existing number by radix, then add digit. */
1919 carry = digit;
6efd877d 1920 for (p = bignum_low; p <= bignum_high; p++)
fecd2382 1921 {
f8701a3f
SC
1922 work = (*p & MASK_CHAR) * radix + carry;
1923 *p = work & MASK_CHAR;
1924 carry = work >> BITS_PER_CHAR;
fecd2382 1925 }
f8701a3f
SC
1926 if (carry)
1927 {
6efd877d
KR
1928 grow_bignum ();
1929 *bignum_high = carry & MASK_CHAR;
1930 know ((carry & ~MASK_CHAR) == 0);
f8701a3f
SC
1931 }
1932 }
1933 length = bignum_high - bignum_low + 1;
1934 if (length > nbytes)
1935 {
6efd877d 1936 as_warn ("Most significant bits truncated in integer constant.");
f8701a3f
SC
1937 }
1938 else
1939 {
1940 register long leading_zeroes;
fecd2382 1941
6efd877d
KR
1942 for (leading_zeroes = nbytes - length;
1943 leading_zeroes;
1944 leading_zeroes--)
a39116f1 1945 {
6efd877d
KR
1946 grow_bignum ();
1947 *bignum_high = 0;
a39116f1 1948 }
f8701a3f 1949 }
6efd877d 1950 if (!need_pass_2)
f8701a3f
SC
1951 {
1952 p = frag_more (nbytes);
6efd877d 1953 bcopy (bignum_low, p, (int) nbytes);
f8701a3f
SC
1954 }
1955 /* C contains character after number. */
6efd877d
KR
1956 SKIP_WHITESPACE ();
1957 c = *input_line_pointer;
f8701a3f
SC
1958 /* C contains 1st non-blank character after number. */
1959 }
6efd877d
KR
1960 demand_empty_rest_of_line ();
1961} /* big_cons() */
f8701a3f 1962
6efd877d
KR
1963/* Extend bignum by 1 char. */
1964static void
1965grow_bignum ()
1966{
f8701a3f
SC
1967 register long length;
1968
6efd877d 1969 bignum_high++;
f8701a3f
SC
1970 if (bignum_high >= bignum_limit)
1971 {
1972 length = bignum_limit - bignum_low;
6efd877d 1973 bignum_low = xrealloc (bignum_low, length + length);
f8701a3f
SC
1974 bignum_high = bignum_low + length;
1975 bignum_limit = bignum_low + length + length;
1976 }
6efd877d 1977} /* grow_bignum(); */
fecd2382
RP
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
6efd877d
KR
1999void /* JF was static, but can't be if VAX.C is goning to use it */
2000float_cons (float_type) /* Worker to do .float etc statements. */
2001 /* Clobbers input_line-pointer, checks end-of-line. */
f8701a3f 2002 register int float_type; /* 'f':.ffloat ... 'F':.float ... */
fecd2382 2003{
6efd877d 2004 register char *p;
f8701a3f 2005 register char c;
6efd877d
KR
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];
f8701a3f
SC
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 */
6efd877d 2016 if (is_it_end_of_statement ())
f8701a3f
SC
2017 {
2018 c = 0; /* Skip loop. */
6efd877d 2019 ++input_line_pointer; /*->past termintor. */
f8701a3f
SC
2020 }
2021 else
2022 {
2023 c = ','; /* Do loop. */
2024 }
2025 while (c == ',')
2026 {
2027 /* input_line_pointer->1st char of a flonum (we hope!). */
6efd877d 2028 SKIP_WHITESPACE ();
f8701a3f
SC
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
6efd877d
KR
2035 if (input_line_pointer[0] == '0' && isalpha (input_line_pointer[1]))
2036 input_line_pointer += 2;
f8701a3f
SC
2037
2038 err = md_atof (float_type, temp, &length);
6efd877d
KR
2039 know (length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
2040 know (length > 0);
2041 if (*err)
f8701a3f 2042 {
6efd877d
KR
2043 as_bad ("Bad floating literal: %s", err);
2044 ignore_rest_of_line ();
f8701a3f
SC
2045 /* Input_line_pointer->just after end-of-line. */
2046 c = 0; /* Break out of loop. */
2047 }
2048 else
2049 {
6efd877d 2050 if (!need_pass_2)
a39116f1 2051 {
f8701a3f
SC
2052 p = frag_more (length);
2053 bcopy (temp, p, length);
a39116f1 2054 }
6efd877d
KR
2055 SKIP_WHITESPACE ();
2056 c = *input_line_pointer++;
f8701a3f
SC
2057 /* C contains 1st non-white character after number. */
2058 /* input_line_pointer->just after terminator (c). */
542e1629 2059 }
f8701a3f 2060 }
6efd877d
KR
2061 --input_line_pointer; /*->terminator (is not ','). */
2062 demand_empty_rest_of_line ();
f8701a3f 2063} /* float_cons() */
fecd2382
RP
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 */
a39116f1
RP
2072
2073
6efd877d
KR
2074void
2075stringer (append_zero) /* Worker to do .ascii etc statements. */
2076 /* Checks end-of-line. */
f8701a3f 2077 register int append_zero; /* 0: don't append '\0', else 1 */
fecd2382 2078{
f8701a3f 2079 /* register char * p; JF unused */
6efd877d 2080 /* register int length; JF unused *//* Length of string we read, excluding */
f8701a3f
SC
2081 /* trailing '\0' implied by closing quote. */
2082 /* register char * where; JF unused */
2083 /* register fragS * fragP; JF unused */
2084 register unsigned int c;
6efd877d 2085
f8701a3f
SC
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 */
6efd877d
KR
2094 if (is_it_end_of_statement ())
2095 {
2096 c = 0; /* Skip loop. */
2097 ++input_line_pointer; /* Compensate for end of loop. */
2098 }
f8701a3f 2099 else
6efd877d
KR
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;
f8701a3f 2136 }
f8701a3f 2137
6efd877d
KR
2138 demand_empty_rest_of_line ();
2139} /* stringer() */
fecd2382 2140\f
6efd877d 2141/* FIXME-SOMEDAY: I had trouble here on characters with the
f8701a3f
SC
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. */
fecd2382 2145
6efd877d
KR
2146unsigned int
2147next_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
fecd2382 2181#ifdef BACKSLASH_V
6efd877d
KR
2182 case 'v':
2183 c = '\013';
2184 break;
fecd2382 2185#endif
6efd877d
KR
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
fecd2382 2221#ifdef ONLY_STANDARD_ESCAPES
6efd877d
KR
2222 as_bad ("Bad escaped character in string, '?' assumed");
2223 c = '?';
fecd2382 2224#endif /* ONLY_STANDARD_ESCAPES */
6efd877d
KR
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() */
fecd2382
RP
2235\f
2236static segT
f8701a3f 2237get_segmented_expression (expP)
6efd877d 2238 register expressionS *expP;
fecd2382 2239{
6efd877d 2240 register segT retval;
f8701a3f 2241
6efd877d 2242 if ((retval = expression (expP)) == SEG_PASS1 || retval == SEG_ABSENT || retval == SEG_BIG)
f8701a3f 2243 {
6efd877d 2244 as_bad ("Expected address expression: absolute 0 assumed");
f8701a3f 2245 retval = expP->X_seg = SEG_ABSOLUTE;
6efd877d
KR
2246 expP->X_add_number = 0;
2247 expP->X_add_symbol = expP->X_subtract_symbol = 0;
f8701a3f
SC
2248 }
2249 return (retval); /* SEG_ ABSOLUTE,UNKNOWN,DATA,TEXT,BSS */
fecd2382
RP
2250}
2251
6efd877d
KR
2252static segT
2253get_known_segmented_expression (expP)
2254 register expressionS *expP;
fecd2382 2255{
6efd877d
KR
2256 register segT retval;
2257 register char *name1;
2258 register char *name2;
f8701a3f
SC
2259
2260 if ((retval = get_segmented_expression (expP)) == SEG_UNKNOWN)
2261 {
6efd877d 2262 name1 = expP->X_add_symbol ? S_GET_NAME (expP->X_add_symbol) : "";
f8701a3f 2263 name2 = expP->X_subtract_symbol ?
6efd877d
KR
2264 S_GET_NAME (expP->X_subtract_symbol) :
2265 "";
f8701a3f
SC
2266 if (name1 && name2)
2267 {
6efd877d
KR
2268 as_warn ("Symbols \"%s\" \"%s\" are undefined: absolute 0 assumed.",
2269 name1, name2);
f8701a3f
SC
2270 }
2271 else
2272 {
6efd877d
KR
2273 as_warn ("Symbol \"%s\" undefined: absolute 0 assumed.",
2274 name1 ? name1 : name2);
f8701a3f
SC
2275 }
2276 retval = expP->X_seg = SEG_ABSOLUTE;
6efd877d
KR
2277 expP->X_add_number = 0;
2278 expP->X_add_symbol = expP->X_subtract_symbol = NULL;
f8701a3f 2279 }
a39116f1 2280#ifndef MANY_SEGMENTS
6efd877d 2281 know (retval == SEG_ABSOLUTE || retval == SEG_DATA || retval == SEG_TEXT || retval == SEG_BSS || retval == SEG_DIFFERENCE);
a39116f1 2282#endif
f8701a3f
SC
2283 return (retval);
2284
fecd2382
RP
2285} /* get_known_segmented_expression() */
2286
2287
2288
6efd877d 2289/* static */ long /* JF was static, but can't be if the MD pseudos are to use it */
f8701a3f 2290get_absolute_expression ()
fecd2382 2291{
6efd877d 2292 expressionS exp;
f8701a3f
SC
2293 register segT s;
2294
6efd877d 2295 if ((s = expression (&exp)) != SEG_ABSOLUTE)
f8701a3f
SC
2296 {
2297 if (s != SEG_ABSENT)
2298 {
6efd877d 2299 as_bad ("Bad Absolute Expression, absolute 0 assumed.");
f8701a3f 2300 }
6efd877d 2301 exp.X_add_number = 0;
f8701a3f 2302 }
6efd877d 2303 return (exp.X_add_number);
fecd2382
RP
2304}
2305
6efd877d
KR
2306char /* return terminator */
2307get_absolute_expression_and_terminator (val_pointer)
2308 long *val_pointer; /* return value of expression */
fecd2382 2309{
6efd877d
KR
2310 *val_pointer = get_absolute_expression ();
2311 return (*input_line_pointer++);
fecd2382
RP
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 */
2320char *
f8701a3f 2321demand_copy_C_string (len_pointer)
6efd877d 2322 int *len_pointer;
fecd2382 2323{
6efd877d 2324 register char *s;
f8701a3f 2325
6efd877d 2326 if ((s = demand_copy_string (len_pointer)) != 0)
f8701a3f
SC
2327 {
2328 register int len;
2329
6efd877d 2330 for (len = *len_pointer;
f8701a3f
SC
2331 len > 0;
2332 len--)
2333 {
6efd877d 2334 if (*s == 0)
fecd2382 2335 {
f8701a3f
SC
2336 s = 0;
2337 len = 1;
6efd877d
KR
2338 *len_pointer = 0;
2339 as_bad ("This string may not contain \'\\0\'");
fecd2382 2340 }
f8701a3f
SC
2341 }
2342 }
2343 return (s);
fecd2382
RP
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 */
6efd877d
KR
2352static char *
2353demand_copy_string (lenP)
2354 int *lenP;
fecd2382 2355{
6efd877d
KR
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++;
fecd2382 2370 }
6efd877d
KR
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() */
fecd2382
RP
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.
f8701a3f 2394*/
6efd877d
KR
2395int
2396is_it_end_of_statement ()
2397{
2398 SKIP_WHITESPACE ();
2399 return (is_end_of_line[*input_line_pointer]);
2400} /* is_it_end_of_statement() */
fecd2382 2401
6efd877d
KR
2402void
2403equals (sym_name)
2404 char *sym_name;
fecd2382 2405{
6efd877d 2406 register symbolS *symbolP; /* symbol we are working with */
f8701a3f
SC
2407
2408 input_line_pointer++;
6efd877d 2409 if (*input_line_pointer == '=')
f8701a3f
SC
2410 input_line_pointer++;
2411
6efd877d 2412 while (*input_line_pointer == ' ' || *input_line_pointer == '\t')
f8701a3f
SC
2413 input_line_pointer++;
2414
6efd877d
KR
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;
f8701a3f 2421
6efd877d
KR
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() */
fecd2382
RP
2440
2441/* .include -- include a file at this point. */
2442
2443/* ARGSUSED */
6efd877d
KR
2444void
2445s_include (arg)
2446 int arg;
fecd2382 2447{
f8701a3f
SC
2448 char *newbuf;
2449 char *filename;
2450 int i;
2451 FILE *try;
2452 char *path;
2453
6efd877d
KR
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);
f8701a3f
SC
2469 path = filename;
2470gotit:
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);
6efd877d 2474} /* s_include() */
fecd2382 2475
6efd877d
KR
2476void
2477add_include_dir (path)
2478 char *path;
fecd2382 2479{
f8701a3f
SC
2480 int i;
2481
2482 if (include_dir_count == 0)
2483 {
6efd877d 2484 include_dirs = (char **) xmalloc (2 * sizeof (*include_dirs));
f8701a3f
SC
2485 include_dirs[0] = "."; /* Current dir */
2486 include_dir_count = 2;
2487 }
2488 else
2489 {
2490 include_dir_count++;
6efd877d
KR
2491 include_dirs = (char **) realloc (include_dirs,
2492 include_dir_count * sizeof (*include_dirs));
f8701a3f
SC
2493 }
2494
6efd877d 2495 include_dirs[include_dir_count - 1] = path; /* New one */
f8701a3f 2496
6efd877d
KR
2497 i = strlen (path);
2498 if (i > include_dir_maxlen)
2499 include_dir_maxlen = i;
2500} /* add_include_dir() */
fecd2382 2501
6efd877d
KR
2502void
2503s_ignore (arg)
2504 int arg;
fecd2382 2505{
6efd877d 2506 extern char is_end_of_line[];
f8701a3f 2507
6efd877d
KR
2508 while (!is_end_of_line[*input_line_pointer])
2509 {
2510 ++input_line_pointer;
2511 }
2512 ++input_line_pointer;
fecd2382 2513
6efd877d
KR
2514 return;
2515} /* s_ignore() */
fecd2382
RP
2516
2517/* end of read.c */
This page took 0.18017 seconds and 4 git commands to generate.