/* read.c - read a source file -
- Copyright (C) 1986, 1987, 1990, 1991, 1993, 1994
+ Copyright (C) 1986, 87, 90, 91, 92, 93, 94, 95, 1996
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
#include "as.h"
#include "subsegs.h"
+#include "sb.h"
+#include "macro.h"
#include "libiberty.h"
#include "obstack.h"
#include "listing.h"
#define LEX_PCT 0
#endif
+#ifndef LEX_QM
+/* The PowerPC Windows NT assemblers permits ? inside label names. */
+#define LEX_QM 0
+#endif
+
+#ifndef LEX_DOLLAR
+/* The a29k assembler does not permits labels to start with $. */
+#define LEX_DOLLAR 3
+#endif
+
/* used by is_... macros. our ctype[] */
char lex_type[256] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ABCDEFGHIJKLMNO */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* PQRSTUVWXYZ[\]^_ */
- 0, 0, 0, 0, 3, LEX_PCT, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /* _!"#$%&'()*+,-./ */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0123456789:;<=>? */
+ 0, 0, 0, 0, LEX_DOLLAR, LEX_PCT, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /* _!"#$%&'()*+,-./ */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, LEX_QM, /* 0123456789:;<=>? */
LEX_AT, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* @ABCDEFGHIJKLMNO */
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, LEX_BR, 0, LEX_BR, 0, 3, /* PQRSTUVWXYZ[\]^_ */
0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* `abcdefghijklmno */
/* If this line had an MRI style label, it is stored in this variable.
This is used by some of the MRI pseudo-ops. */
-symbolS *mri_line_label;
+symbolS *line_label;
/* This global variable is used to support MRI common sections. We
translate such sections into a common symbol. This variable is
may be needed. */
static int mri_pending_align;
-static void do_align PARAMS ((int, char *));
+static int scrub_from_string PARAMS ((char **));
+static void do_align PARAMS ((int, char *, int));
static int hex_float PARAMS ((int, char *));
static void do_org PARAMS ((segT, expressionS *, int));
char *demand_copy_string PARAMS ((int *lenP));
static segT get_segmented_expression PARAMS ((expressionS *expP));
static segT get_known_segmented_expression PARAMS ((expressionS * expP));
static void pobegin PARAMS ((void));
+static int get_line_sb PARAMS ((sb *));
\f
void
/* Something close -- but not too close -- to a multiple of 1024.
The debugging malloc I'm using has 24 bytes of overhead. */
- obstack_begin (¬es, 5090);
- obstack_begin (&cond_obstack, 990);
+ obstack_begin (¬es, chunksize);
+ obstack_begin (&cond_obstack, chunksize);
/* Use machine dependent syntax */
for (p = line_separator_chars; *p; p++)
{"ascii", stringer, 0},
{"asciz", stringer, 1},
{"balign", s_align_bytes, 0},
+ {"balignw", s_align_bytes, -2},
+ {"balignl", s_align_bytes, -4},
/* block */
{"byte", cons, 1},
{"comm", s_comm, 0},
{"ds.s", s_space, 4},
{"ds.w", s_space, 2},
{"ds.x", s_space, 12},
+ {"debug", s_ignore, 0},
#ifdef S_SET_DESC
{"desc", s_desc, 0},
#endif
{"endif", s_endif, 0},
/* endef */
{"equ", s_set, 0},
-/* err */
+ {"err", s_err, 0},
+ {"exitm", s_mexit, 0},
/* extend */
{"extern", s_ignore, 0}, /* We treat all undef as ext */
{"appfile", s_app_file, 1},
{"globl", s_globl, 0},
{"hword", cons, 2},
{"if", s_if, (int) O_ne},
+ {"ifc", s_ifc, 0},
{"ifdef", s_ifdef, 0},
{"ifeq", s_if, (int) O_eq},
{"ifeqs", s_ifeqs, 0},
{"ifgt", s_if, (int) O_gt},
{"ifle", s_if, (int) O_le},
{"iflt", s_if, (int) O_lt},
+ {"ifnc", s_ifc, 1},
{"ifndef", s_ifdef, 1},
{"ifne", s_if, (int) O_ne},
{"ifnes", s_ifeqs, 1},
{"ifnotdef", s_ifdef, 1},
{"include", s_include, 0},
{"int", cons, 4},
+ {"irp", s_irp, 0},
+ {"irep", s_irp, 0},
+ {"irpc", s_irp, 1},
+ {"irepc", s_irp, 1},
{"lcomm", s_lcomm, 0},
{"lflags", listing_flags, 0}, /* Listing flags */
+ {"linkonce", s_linkonce, 0},
{"list", listing_list, 1}, /* Turn listing on */
{"llen", listing_psize, 1},
{"long", cons, 4},
{"lsym", s_lsym, 0},
+ {"macro", s_macro, 0},
+ {"mexit", s_mexit, 0},
+ {"mri", s_mri, 0},
+ {".mri", s_mri, 0}, /* Special case so .mri works in MRI mode. */
+ {"name", s_ignore, 0},
{"noformat", s_ignore, 0},
{"nolist", listing_list, 0}, /* Turn listing off */
{"nopage", listing_nopage, 0},
{"offset", s_struct, 0},
{"org", s_org, 0},
{"p2align", s_align_ptwo, 0},
+ {"p2alignw", s_align_ptwo, -2},
+ {"p2alignl", s_align_ptwo, -4},
{"page", listing_eject, 0},
{"plen", listing_psize, 0},
+ {"print", s_print, 0},
{"psize", listing_psize, 0}, /* set paper size */
-/* print */
+ {"purgem", s_purgem, 0},
{"quad", cons, 8},
+ {"rep", s_rept, 0},
+ {"rept", s_rept, 0},
+ {"rva", s_rva, 4},
{"sbttl", listing_title, 1}, /* Subtitle of listing */
/* scl */
/* sect */
{"single", float_cons, 'f'},
/* size */
{"space", s_space, 0},
+ {"skip", s_space, 0},
+ {"spc", s_ignore, 0},
{"stabd", s_stab, 'd'},
{"stabn", s_stab, 'n'},
{"stabs", s_stab, 's'},
{"this_gcc_requires_the_gnu_assembler", s_ignore, 0},
{"title", listing_title, 0}, /* Listing title */
+ {"ttl", listing_title, 0},
/* type */
/* use */
/* val */
+ {"xcom", s_comm, 0},
{"xdef", s_globl, 0},
+ {"xref", s_ignore, 0},
{"xstabs", s_xstab, 's'},
{"word", cons, 2},
{"zero", s_space, 0},
{
errtxt = hash_insert (po_hash, pop->poc_name, (char *) pop);
if (errtxt && (!pop_override_ok || strcmp (errtxt, "exists")))
- as_fatal ("error constructing %s pseudo-op table", pop_table_name);
+ as_fatal ("error constructing %s pseudo-op table: %s", pop_table_name,
+ errtxt);
}
}
}
+/* This function is used when scrubbing the characters between #APP
+ and #NO_APP. */
+
+static char *scrub_string;
+static char *scrub_string_end;
+
+static int
+scrub_from_string (from)
+ char **from;
+{
+ int size;
+
+ *from = scrub_string;
+ size = scrub_string_end - scrub_string;
+ scrub_string = scrub_string_end;
+ return size;
+}
+
/* read_a_source_file()
*
* We read the file, putting things into a web that
if (input_line_pointer[-1] == '\n')
bump_line_counters ();
- if (flag_mri
+ line_label = NULL;
+
+ if (flag_m68k_mri
#ifdef LABELS_WITHOUT_COLONS
|| 1
#endif
)
{
- mri_line_label = NULL;
-
/* Text at the start of a line must be a label, we
run down and stick a colon in. */
if (is_name_beginner (*input_line_pointer))
{
char *line_start = input_line_pointer;
- char c = get_symbol_end ();
+ char c;
+
+ HANDLE_CONDITIONAL_ASSEMBLY ();
- if (! ignore_input ())
+ c = get_symbol_end ();
+
+ /* In MRI mode, the EQU pseudoop must be
+ handled specially. */
+ if (flag_m68k_mri)
{
- /* In MRI mode, the EQU pseudoop must be
- handled specially. */
- if (flag_mri)
+ char *rest = input_line_pointer + 1;
+
+ if (*rest == ':')
+ ++rest;
+ if (*rest == ' ' || *rest == '\t')
+ ++rest;
+ if ((strncasecmp (rest, "EQU", 3) == 0
+ || strncasecmp (rest, "SET", 3) == 0)
+ && (rest[3] == ' ' || rest[3] == '\t'))
{
- if (((strncasecmp (input_line_pointer + 1,
- "EQU", 3) == 0)
- || (strncasecmp (input_line_pointer + 1,
- "SET", 3) == 0))
- && (input_line_pointer[4] == ' '
- || input_line_pointer[4] == '\t'))
- {
- input_line_pointer += 4;
- equals (line_start);
- continue;
- }
+ input_line_pointer = rest + 3;
+ equals (line_start);
+ continue;
}
-
- mri_line_label = colon (line_start);
}
+ line_label = colon (line_start);
+
*input_line_pointer = c;
if (c == ':')
input_line_pointer++;
*/
if (TC_START_LABEL(c, input_line_pointer))
{
- colon (s); /* user-defined label */
+ if (flag_m68k_mri)
+ {
+ char *rest = input_line_pointer + 1;
+
+ /* In MRI mode, \tsym: set 0 is permitted. */
+
+ if (*rest == ':')
+ ++rest;
+ if (*rest == ' ' || *rest == '\t')
+ ++rest;
+ if ((strncasecmp (rest, "EQU", 3) == 0
+ || strncasecmp (rest, "SET", 3) == 0)
+ && (rest[3] == ' ' || rest[3] == '\t'))
+ {
+ input_line_pointer = rest + 3;
+ equals (s);
+ continue;
+ }
+ }
+
+ line_label = colon (s); /* user-defined label */
*input_line_pointer++ = ':'; /* Put ':' back for error messages' sake. */
/* Input_line_pointer->after ':'. */
SKIP_WHITESPACE ();
}
#endif
- if (flag_mri
+ if (flag_m68k_mri
#ifdef NO_PSEUDO_DOT
|| 1
#endif
pop = NULL;
}
- if (pop != NULL || *s == '.')
+ if (pop != NULL
+ || (! flag_m68k_mri && *s == '.'))
{
/*
* PSEUDO - OP.
|| (pop->poc_handler == s_space
&& pop->poc_val == 1))))
{
- do_align (1, (char *) NULL);
+ do_align (1, (char *) NULL, 0);
mri_pending_align = 0;
}
}
else
{ /* machine instruction */
+ int inquote = 0;
+
if (mri_pending_align)
{
- do_align (1, (char *) NULL);
+ do_align (1, (char *) NULL, 0);
mri_pending_align = 0;
}
/* Also: input_line_pointer->`\0` where c was. */
*input_line_pointer = c;
while (!is_end_of_line[(unsigned char) *input_line_pointer]
+ || inquote
#ifdef TC_EOL_IN_INSN
|| TC_EOL_IN_INSN (input_line_pointer)
#endif
)
{
+ if (flag_m68k_mri && *input_line_pointer == '\'')
+ inquote = ! inquote;
input_line_pointer++;
}
}
#endif
+ if (macro_defined)
+ {
+ sb out;
+ const char *err;
+
+ if (check_macro (s, &out, '\0', &err))
+ {
+ if (err != NULL)
+ as_bad (err);
+ *input_line_pointer++ = c;
+ input_scrub_include_sb (&out,
+ input_line_pointer);
+ sb_kill (&out);
+ buffer_limit =
+ input_scrub_next_buffer (&input_line_pointer);
+ continue;
+ }
+ }
+
md_assemble (s); /* Assemble 1 instruction. */
*input_line_pointer++ = c;
char *new_tmp;
unsigned int new_length;
char *tmp_buf = 0;
- extern char *scrub_string, *scrub_last_string;
bump_line_counters ();
s = input_line_pointer;
{
input_line_pointer = ends + 8;
}
- new_buf = xmalloc (100);
- new_length = 100;
- new_tmp = new_buf;
scrub_string = s;
- scrub_last_string = ends;
+ scrub_string_end = ends;
+
+ new_length = ends - s;
+ new_buf = (char *) xmalloc (new_length);
+ new_tmp = new_buf;
for (;;)
{
- int ch;
+ int space;
+ int size;
- ch = do_scrub_next_char (scrub_from_string, scrub_to_string);
- if (ch == EOF)
- break;
- *new_tmp++ = ch;
- if (new_tmp == new_buf + new_length)
+ space = (new_buf + new_length) - new_tmp;
+ size = do_scrub_chars (scrub_from_string, new_tmp, space);
+
+ if (size < space)
{
- new_buf = xrealloc (new_buf, new_length + 100);
- new_tmp = new_buf + new_length;
- new_length += 100;
+ new_tmp += size;
+ break;
}
+
+ new_buf = xrealloc (new_buf, new_length + 100);
+ new_tmp = new_buf + new_length;
+ new_length += 100;
}
if (tmp_buf)
HANDLE_CONDITIONAL_ASSEMBLY ();
+#ifdef tc_unrecognized_line
+ if (tc_unrecognized_line (c))
+ continue;
+#endif
+
/* as_warn("Junk character %d.",c); Now done by ignore_rest */
input_line_pointer--; /* Report unknown char as ignored. */
ignore_rest_of_line ();
if (old_buffer)
{
+ free (buffer);
bump_line_counters ();
if (old_input != 0)
{
input_scrub_close (); /* Close the input file */
}
+/* For most MRI pseudo-ops, the line actually ends at the first
+ nonquoted space. This function looks for that point, stuffs a null
+ in, and sets *STOPCP to the character that used to be there, and
+ returns the location.
+
+ Until I hear otherwise, I am going to assume that this is only true
+ for the m68k MRI assembler. */
+
+char *
+mri_comment_field (stopcp)
+ char *stopcp;
+{
+#ifdef TC_M68K
+
+ char *s;
+ int inquote = 0;
+
+ know (flag_m68k_mri);
+
+ for (s = input_line_pointer;
+ ((! is_end_of_line[(unsigned char) *s] && *s != ' ' && *s != '\t')
+ || inquote);
+ s++)
+ {
+ if (*s == '\'')
+ inquote = ! inquote;
+ }
+ *stopcp = *s;
+ *s = '\0';
+ return s;
+
+#else
+
+ char *s;
+
+ for (s = input_line_pointer; ! is_end_of_line[(unsigned char) *s]; s++)
+ ;
+ *stopcp = *s;
+ *s = '\0';
+ return s;
+
+#endif
+
+}
+
+/* Skip to the end of an MRI comment field. */
+
+void
+mri_comment_end (stop, stopc)
+ char *stop;
+ int stopc;
+{
+ know (flag_mri);
+
+ input_line_pointer = stop;
+ *stop = stopc;
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+}
+
void
s_abort (ignore)
int ignore;
/* Guts of .align directive. */
static void
-do_align (n, fill)
+do_align (n, fill, len)
int n;
char *fill;
+ int len;
{
#ifdef md_do_align
- md_do_align (n, fill, just_record_alignment);
+ md_do_align (n, fill, len, just_record_alignment);
#endif
if (!fill)
{
{
fill = &zero;
}
+ len = 1;
}
+
/* Only make a frag if we HAVE to. . . */
if (n && !need_pass_2)
- frag_align (n, *fill);
+ {
+ if (len <= 1)
+ frag_align (n, *fill);
+ else
+ frag_align_pattern (n, fill, len);
+ }
#ifdef md_do_align
just_record_alignment:
char temp_fill;
unsigned int i = 0;
unsigned long max_alignment = 1 << 15;
+ char *stop = NULL;
+ char stopc;
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
if (is_end_of_line[(unsigned char) *input_line_pointer])
- temp = arg; /* Default value from pseudo-op table */
+ {
+ if (arg < 0)
+ temp = 0;
+ else
+ temp = arg; /* Default value from pseudo-op table */
+ }
else
temp = get_absolute_expression ();
temp = i;
if (*input_line_pointer == ',')
{
+ offsetT fillval;
+ int len;
+
input_line_pointer++;
- temp_fill = get_absolute_expression ();
- do_align (temp, &temp_fill);
+ fillval = get_absolute_expression ();
+ if (arg >= 0)
+ len = 1;
+ else
+ len = - arg;
+ if (len <= 1)
+ {
+ temp_fill = fillval;
+ do_align (temp, &temp_fill, len);
+ }
+ else
+ {
+ char ab[16];
+
+ if (len > sizeof ab)
+ abort ();
+ md_number_to_chars (ab, fillval, len);
+ do_align (temp, ab, len);
+ }
}
else
- do_align (temp, (char *) 0);
+ {
+ if (arg < 0)
+ as_warn ("expected fill pattern missing");
+ do_align (temp, (char *) NULL, 0);
+ }
+
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
demand_empty_rest_of_line ();
}
/* For machines where ".align 4" means align to 2**4 boundary. */
void
-s_align_ptwo (ignore)
- int ignore;
+s_align_ptwo (arg)
+ int arg;
{
register int temp;
char temp_fill;
long max_alignment = 15;
+ char *stop = NULL;
+ char stopc;
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
temp = get_absolute_expression ();
if (temp > max_alignment)
}
if (*input_line_pointer == ',')
{
+ offsetT fillval;
+ int len;
+
input_line_pointer++;
- temp_fill = get_absolute_expression ();
- do_align (temp, &temp_fill);
+ fillval = get_absolute_expression ();
+ if (arg >= 0)
+ len = 1;
+ else
+ len = - arg;
+ if (len <= 1)
+ {
+ temp_fill = fillval;
+ do_align (temp, &temp_fill, len);
+ }
+ else
+ {
+ char ab[16];
+
+ if (len > sizeof ab)
+ abort ();
+ md_number_to_chars (ab, fillval, len);
+ do_align (temp, ab, len);
+ }
}
else
- do_align (temp, (char *) 0);
+ {
+ if (arg < 0)
+ as_warn ("expected fill pattern missing");
+ do_align (temp, (char *) NULL, 0);
+ }
+
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
demand_empty_rest_of_line ();
}
register char *p;
offsetT temp;
register symbolS *symbolP;
+ char *stop = NULL;
+ char stopc;
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
name = input_line_pointer;
c = get_symbol_end ();
if (*input_line_pointer != ',')
{
as_bad ("Expected comma after symbol-name: rest of line ignored.");
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
ignore_rest_of_line ();
return;
}
if ((temp = get_absolute_expression ()) < 0)
{
as_warn (".COMMon length (%ld.) <0! Ignored.", (long) temp);
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
ignore_rest_of_line ();
return;
}
{
as_bad ("Ignoring attempt to re-define symbol `%s'.",
S_GET_NAME (symbolP));
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
ignore_rest_of_line ();
return;
}
}
#endif /* not OBJ_VMS */
know (symbolP->sy_frag == &zero_address_frag);
+
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+
demand_empty_rest_of_line ();
} /* s_comm() */
char *alc = NULL;
symbolS *sym;
offsetT align;
+ char *stop = NULL;
+ char stopc;
if (! flag_mri)
{
return;
}
+ stop = mri_comment_field (&stopc);
+
SKIP_WHITESPACE ();
name = input_line_pointer;
c = *input_line_pointer;
*input_line_pointer = '\0';
- if (mri_line_label != NULL)
+ if (line_label != NULL)
{
- alc = (char *) xmalloc (strlen (S_GET_NAME (mri_line_label))
+ alc = (char *) xmalloc (strlen (S_GET_NAME (line_label))
+ (input_line_pointer - name)
+ 1);
- sprintf (alc, "%s%s", name, S_GET_NAME (mri_line_label));
+ sprintf (alc, "%s%s", name, S_GET_NAME (line_label));
name = alc;
}
}
#endif
{
as_bad ("attempt to re-define symbol `%s'", S_GET_NAME (sym));
+ mri_comment_end (stop, stopc);
ignore_rest_of_line ();
return;
}
S_SET_ALIGN (sym, align);
#endif
- if (mri_line_label != NULL)
+ if (line_label != NULL)
{
- mri_line_label->sy_value.X_op = O_symbol;
- mri_line_label->sy_value.X_add_symbol = sym;
- mri_line_label->sy_value.X_add_number = S_GET_VALUE (sym);
- mri_line_label->sy_frag = &zero_address_frag;
- S_SET_SEGMENT (mri_line_label, expr_section);
+ line_label->sy_value.X_op = O_symbol;
+ line_label->sy_value.X_add_symbol = sym;
+ line_label->sy_value.X_add_number = S_GET_VALUE (sym);
+ line_label->sy_frag = &zero_address_frag;
+ S_SET_SEGMENT (line_label, expr_section);
}
/* FIXME: We just ignore the small argument, which distinguishes
input_line_pointer += 2;
if (*input_line_pointer == ',')
input_line_pointer += 2;
+
+ mri_comment_end (stop, stopc);
+
demand_empty_rest_of_line ();
}
}
/* Handle the .appfile pseudo-op. This is automatically generated by
- do_scrub_next_char when a preprocessor # line comment is seen with
- a file name. This default definition may be overridden by the
- object or CPU specific pseudo-ops. This function is also the
- default definition for .file; the APPFILE argument is 1 for
- .appfile, 0 for .file. */
+ do_scrub_chars when a preprocessor # line comment is seen with a
+ file name. This default definition may be overridden by the object
+ or CPU specific pseudo-ops. This function is also the default
+ definition for .file; the APPFILE argument is 1 for .appfile, 0 for
+ .file. */
void
s_app_file (appfile)
the buffer. Passing -2 to new_logical_line tells it to
account for it. */
new_logical_line (s, appfile ? -2 : -1);
+
+ /* In MRI mode, the preprocessor may have inserted an extraneous
+ backquote. */
+ if (flag_m68k_mri
+ && *input_line_pointer == '\''
+ && is_end_of_line[(unsigned char) input_line_pointer[1]])
+ ++input_line_pointer;
+
demand_empty_rest_of_line ();
#ifdef LISTING
if (listing)
}
/* Handle the .appline pseudo-op. This is automatically generated by
- do_scrub_next_char when a preprocessor # line comment is seen.
- This default definition may be overridden by the object or CPU
- specific pseudo-ops. */
+ do_scrub_chars when a preprocessor # line comment is seen. This
+ default definition may be overridden by the object or CPU specific
+ pseudo-ops. */
void
s_app_line (ignore)
/* The MRI assembler permits the start symbol to follow .end,
but we don't support that. */
SKIP_WHITESPACE ();
- if (! is_end_of_line[(unsigned char) *input_line_pointer])
+ if (! is_end_of_line[(unsigned char) *input_line_pointer]
+ && *input_line_pointer != '*'
+ && *input_line_pointer != '!')
as_warn ("start address not supported");
}
}
+/* Handle the .err pseudo-op. */
+
+void
+s_err (ignore)
+ int ignore;
+{
+ as_bad (".err encountered");
+ demand_empty_rest_of_line ();
+}
+
/* Handle the MRI fail pseudo-op. */
void
int ignore;
{
offsetT temp;
+ char *stop = NULL;
+ char stopc;
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
temp = get_absolute_expression ();
if (temp >= 500)
as_warn (".fail %ld encountered", (long) temp);
else
as_bad (".fail %ld encountered", (long) temp);
+
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+
demand_empty_rest_of_line ();
}
register long temp_fill = 0;
char *p;
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
temp_repeat = get_absolute_expression ();
if (*input_line_pointer == ',')
char *name;
int c;
symbolS *symbolP;
+ char *stop = NULL;
+ char stopc;
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
do
{
}
}
while (c == ',');
+
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the MRI IRP and IRPC pseudo-ops. */
+
+void
+s_irp (irpc)
+ int irpc;
+{
+ char *file;
+ unsigned int line;
+ sb s;
+ const char *err;
+ sb out;
+
+ as_where (&file, &line);
+
+ sb_new (&s);
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ sb_add_char (&s, *input_line_pointer++);
+
+ sb_new (&out);
+
+ err = expand_irp (irpc, 0, &s, &out, get_line_sb, '\0');
+ if (err != NULL)
+ as_bad_where (file, line, "%s", err);
+
+ sb_kill (&s);
+
+ input_scrub_include_sb (&out, input_line_pointer);
+ sb_kill (&out);
+ buffer_limit = input_scrub_next_buffer (&input_line_pointer);
+}
+
+/* Handle the .linkonce pseudo-op. This tells the assembler to mark
+ the section to only be linked once. However, this is not supported
+ by most object file formats. This takes an optional argument,
+ which is what to do about duplicates. */
+
+void
+s_linkonce (ignore)
+ int ignore;
+{
+ enum linkonce_type type;
+
+ SKIP_WHITESPACE ();
+
+ type = LINKONCE_DISCARD;
+
+ if (! is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ char *s;
+ char c;
+
+ s = input_line_pointer;
+ c = get_symbol_end ();
+ if (strcasecmp (s, "discard") == 0)
+ type = LINKONCE_DISCARD;
+ else if (strcasecmp (s, "one_only") == 0)
+ type = LINKONCE_ONE_ONLY;
+ else if (strcasecmp (s, "same_size") == 0)
+ type = LINKONCE_SAME_SIZE;
+ else if (strcasecmp (s, "same_contents") == 0)
+ type = LINKONCE_SAME_CONTENTS;
+ else
+ as_warn ("unrecognized .linkonce type `%s'", s);
+
+ *input_line_pointer = c;
+ }
+
+#ifdef obj_handle_link_once
+ obj_handle_link_once (type);
+#else /* ! defined (obj_handle_link_once) */
+#ifdef BFD_ASSEMBLER
+ {
+ flagword flags;
+
+ if ((bfd_applicable_section_flags (stdoutput) & SEC_LINK_ONCE) == 0)
+ as_warn (".linkonce is not supported for this object file format");
+
+ flags = bfd_get_section_flags (stdoutput, now_seg);
+ flags |= SEC_LINK_ONCE;
+ switch (type)
+ {
+ default:
+ abort ();
+ case LINKONCE_DISCARD:
+ flags |= SEC_LINK_DUPLICATES_DISCARD;
+ break;
+ case LINKONCE_ONE_ONLY:
+ flags |= SEC_LINK_DUPLICATES_ONE_ONLY;
+ break;
+ case LINKONCE_SAME_SIZE:
+ flags |= SEC_LINK_DUPLICATES_SAME_SIZE;
+ break;
+ case LINKONCE_SAME_CONTENTS:
+ flags |= SEC_LINK_DUPLICATES_SAME_CONTENTS;
+ break;
+ }
+ if (! bfd_set_section_flags (stdoutput, now_seg, flags))
+ as_bad ("bfd_set_section_flags: %s",
+ bfd_errmsg (bfd_get_error ()));
+ }
+#else /* ! defined (BFD_ASSEMBLER) */
+ as_warn (".linkonce is not supported for this object file format");
+#endif /* ! defined (BFD_ASSEMBLER) */
+#endif /* ! defined (obj_handle_link_once) */
+
demand_empty_rest_of_line ();
}
{
bss_seg = subseg_new (".sbss", 1);
seg_info (bss_seg)->bss = 1;
+#ifdef BFD_ASSEMBLER
+ if (! bfd_set_section_flags (stdoutput, bss_seg, SEC_ALLOC))
+ as_warn ("error setting flags for \".sbss\": %s",
+ bfd_errmsg (bfd_get_error ()));
+#endif
}
}
#endif
S_SET_STORAGE_CLASS (symbolP, C_STAT);
}
#endif /* OBJ_COFF */
+
+#ifdef S_SET_SIZE
+ S_SET_SIZE (symbolP, temp);
+#endif
}
else
as_bad ("Ignoring attempt to re-define symbol `%s'.",
demand_empty_rest_of_line ();
} /* s_lsym() */
+/* Read a line into an sb. */
+
+static int
+get_line_sb (line)
+ sb *line;
+{
+ if (input_line_pointer[-1] == '\n')
+ bump_line_counters ();
+
+ if (input_line_pointer >= buffer_limit)
+ {
+ buffer_limit = input_scrub_next_buffer (&input_line_pointer);
+ if (buffer_limit == 0)
+ return 0;
+ }
+
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ sb_add_char (line, *input_line_pointer++);
+ while (input_line_pointer < buffer_limit
+ && is_end_of_line[(unsigned char) *input_line_pointer])
+ {
+ if (input_line_pointer[-1] == '\n')
+ bump_line_counters ();
+ ++input_line_pointer;
+ }
+ return 1;
+}
+
+/* Define a macro. This is an interface to macro.c, which is shared
+ between gas and gasp. */
+
+void
+s_macro (ignore)
+ int ignore;
+{
+ char *file;
+ unsigned int line;
+ sb s;
+ sb label;
+ const char *err;
+
+ as_where (&file, &line);
+
+ sb_new (&s);
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ sb_add_char (&s, *input_line_pointer++);
+
+ sb_new (&label);
+ if (line_label != NULL)
+ sb_add_string (&label, S_GET_NAME (line_label));
+
+ err = define_macro (0, &s, &label, get_line_sb);
+ if (err != NULL)
+ as_bad_where (file, line, "%s", err);
+ else
+ {
+ if (line_label != NULL)
+ {
+ S_SET_SEGMENT (line_label, undefined_section);
+ S_SET_VALUE (line_label, 0);
+ line_label->sy_frag = &zero_address_frag;
+ }
+ }
+
+ sb_kill (&s);
+}
+
+/* Handle the .mexit pseudo-op, which immediately exits a macro
+ expansion. */
+
+void
+s_mexit (ignore)
+ int ignore;
+{
+ buffer_limit = input_scrub_next_buffer (&input_line_pointer);
+}
+
+/* Switch in and out of MRI mode. */
+
+void
+s_mri (ignore)
+ int ignore;
+{
+ int on, old_flag;
+
+ on = get_absolute_expression ();
+ old_flag = flag_mri;
+ if (on != 0)
+ {
+ flag_mri = 1;
+#ifdef TC_M68K
+ flag_m68k_mri = 1;
+#endif
+ }
+ else
+ {
+ flag_mri = 0;
+ flag_m68k_mri = 0;
+ }
+
+#ifdef MRI_MODE_CHANGE
+ if (on != old_flag)
+ MRI_MODE_CHANGE (on);
+#endif
+
+ demand_empty_rest_of_line ();
+}
+
/* Handle changing the location counter. */
static void
expressionS exp;
register long temp_fill;
- /* The MRI assembler has a different meaning for .org. It means to
- create an absolute section at a given address. We can't support
- that--use a linker script instead. */
- if (flag_mri)
+ /* The m68k MRI assembler has a different meaning for .org. It
+ means to create an absolute section at a given address. We can't
+ support that--use a linker script instead. */
+ if (flag_m68k_mri)
{
as_bad ("MRI style ORG pseudo-op not supported");
ignore_rest_of_line ();
demand_empty_rest_of_line ();
} /* s_org() */
+/* Handle parsing for the MRI SECT/SECTION pseudo-op. This should be
+ called by the obj-format routine which handles section changing
+ when in MRI mode. It will create a new section, and return it. It
+ will set *TYPE to the section type: one of 'C' (code), 'D' (data),
+ 'M' (mixed), or 'R' (romable). If BFD_ASSEMBLER is defined, the
+ flags will be set in the section. */
+
+void
+s_mri_sect (type)
+ char *type;
+{
+#ifdef TC_M68K
+
+ char *name;
+ char c;
+ segT seg;
+
+ SKIP_WHITESPACE ();
+
+ name = input_line_pointer;
+ if (! isdigit ((unsigned char) *name))
+ c = get_symbol_end ();
+ else
+ {
+ do
+ {
+ ++input_line_pointer;
+ }
+ while (isdigit ((unsigned char) *input_line_pointer));
+ c = *input_line_pointer;
+ *input_line_pointer = '\0';
+ }
+
+ name = xstrdup (name);
+
+ *input_line_pointer = c;
+
+ seg = subseg_new (name, 0);
+
+ if (*input_line_pointer == ',')
+ {
+ int align;
+
+ ++input_line_pointer;
+ align = get_absolute_expression ();
+ record_alignment (seg, align);
+ }
+
+ *type = 'C';
+ if (*input_line_pointer == ',')
+ {
+ c = *++input_line_pointer;
+ c = toupper ((unsigned char) c);
+ if (c == 'C' || c == 'D' || c == 'M' || c == 'R')
+ *type = c;
+ else
+ as_bad ("unrecognized section type");
+ ++input_line_pointer;
+
+#ifdef BFD_ASSEMBLER
+ {
+ flagword flags;
+
+ flags = SEC_NO_FLAGS;
+ if (*type == 'C')
+ flags = SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE;
+ else if (*type == 'D' || *type == 'M')
+ flags = SEC_ALLOC | SEC_LOAD | SEC_DATA;
+ else if (*type == 'R')
+ flags = SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_READONLY | SEC_ROM;
+ if (flags != SEC_NO_FLAGS)
+ {
+ if (! bfd_set_section_flags (stdoutput, seg, flags))
+ as_warn ("error setting flags for \"%s\": %s",
+ bfd_section_name (stdoutput, seg),
+ bfd_errmsg (bfd_get_error ()));
+ }
+ }
+#endif
+ }
+
+ /* Ignore the HP type. */
+ if (*input_line_pointer == ',')
+ input_line_pointer += 2;
+
+ demand_empty_rest_of_line ();
+
+#else /* ! TC_M68K */
+#ifdef TC_I960
+
+ char *name;
+ char c;
+ segT seg;
+
+ SKIP_WHITESPACE ();
+
+ name = input_line_pointer;
+ c = get_symbol_end ();
+
+ name = xstrdup (name);
+
+ *input_line_pointer = c;
+
+ seg = subseg_new (name, 0);
+
+ if (*input_line_pointer != ',')
+ *type = 'C';
+ else
+ {
+ char *sectype;
+
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ sectype = input_line_pointer;
+ c = get_symbol_end ();
+ if (*sectype == '\0')
+ *type = 'C';
+ else if (strcasecmp (sectype, "text") == 0)
+ *type = 'C';
+ else if (strcasecmp (sectype, "data") == 0)
+ *type = 'D';
+ else if (strcasecmp (sectype, "romdata") == 0)
+ *type = 'R';
+ else
+ as_warn ("unrecognized section type `%s'", sectype);
+ *input_line_pointer = c;
+ }
+
+ if (*input_line_pointer == ',')
+ {
+ char *seccmd;
+
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ seccmd = input_line_pointer;
+ c = get_symbol_end ();
+ if (strcasecmp (seccmd, "absolute") == 0)
+ {
+ as_bad ("absolute sections are not supported");
+ *input_line_pointer = c;
+ ignore_rest_of_line ();
+ return;
+ }
+ else if (strcasecmp (seccmd, "align") == 0)
+ {
+ int align;
+
+ *input_line_pointer = c;
+ align = get_absolute_expression ();
+ record_alignment (seg, align);
+ }
+ else
+ {
+ as_warn ("unrecognized section command `%s'", seccmd);
+ *input_line_pointer = c;
+ }
+ }
+
+ demand_empty_rest_of_line ();
+
+#else /* ! TC_I960 */
+ /* The MRI assembler seems to use different forms of .sect for
+ different targets. */
+ abort ();
+#endif /* ! TC_I960 */
+#endif /* ! TC_M68K */
+}
+
+/* Handle the .print pseudo-op. */
+
+void
+s_print (ignore)
+ int ignore;
+{
+ char *s;
+ int len;
+
+ s = demand_copy_C_string (&len);
+ printf ("%s\n", s);
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .purgem pseudo-op. */
+
+void
+s_purgem (ignore)
+ int ignore;
+{
+ if (is_it_end_of_statement ())
+ {
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ do
+ {
+ char *name;
+ char c;
+
+ SKIP_WHITESPACE ();
+ name = input_line_pointer;
+ c = get_symbol_end ();
+ delete_macro (name);
+ *input_line_pointer = c;
+ SKIP_WHITESPACE ();
+ }
+ while (*input_line_pointer++ == ',');
+
+ --input_line_pointer;
+ demand_empty_rest_of_line ();
+}
+
+/* Handle the .rept pseudo-op. */
+
+void
+s_rept (ignore)
+ int ignore;
+{
+ int count;
+ sb one;
+ sb many;
+
+ count = get_absolute_expression ();
+
+ sb_new (&one);
+ if (! buffer_and_nest ("REPT", "ENDR", &one, get_line_sb))
+ {
+ as_bad ("rept without endr");
+ return;
+ }
+
+ sb_new (&many);
+ while (count-- > 0)
+ sb_add_sb (&many, &one);
+
+ sb_kill (&one);
+
+ input_scrub_include_sb (&many, input_line_pointer);
+ sb_kill (&many);
+ buffer_limit = input_scrub_next_buffer (&input_line_pointer);
+}
+
void
s_set (ignore)
int ignore;
/* Turn '. = mumble' into a .org mumble */
register segT segment;
expressionS exp;
- register char *ptr;
segment = get_known_segmented_expression (&exp);
int mult;
{
expressionS exp;
- long temp_fill;
+ expressionS val;
char *p = 0;
+ char *stop = NULL;
+ char stopc;
#ifdef md_flush_pending_output
md_flush_pending_output ();
#endif
- /* Just like .fill, but temp_size = 1 */
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+
expression (&exp);
- if (exp.X_op == O_constant)
- {
- long repeat;
- repeat = exp.X_add_number;
- if (mult)
- repeat *= mult;
- if (repeat <= 0)
- {
- as_warn (".space repeat count is %s, ignored",
- repeat ? "negative" : "zero");
- ignore_rest_of_line ();
- return;
- }
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer == ',')
+ {
+ ++input_line_pointer;
+ expression (&val);
+ }
+ else
+ {
+ val.X_op = O_constant;
+ val.X_add_number = 0;
+ }
- /* If we are in the absolute section, just bump the offset. */
- if (now_seg == absolute_section)
+ if (val.X_op != O_constant
+ || val.X_add_number < - 0x80
+ || val.X_add_number > 0xff
+ || (mult != 0 && mult != 1 && val.X_add_number != 0))
+ {
+ if (exp.X_op != O_constant)
+ as_bad ("Unsupported variable size or fill value");
+ else
{
- abs_section_offset += repeat;
- demand_empty_rest_of_line ();
- return;
- }
+ offsetT i;
- /* If we are secretly in an MRI common section, then creating
- space just increases the size of the common symbol. */
- if (mri_common_symbol != NULL)
- {
- S_SET_VALUE (mri_common_symbol,
- S_GET_VALUE (mri_common_symbol) + repeat);
- demand_empty_rest_of_line ();
- return;
+ if (mult == 0)
+ mult = 1;
+ for (i = 0; i < exp.X_add_number; i++)
+ emit_expr (&val, mult);
}
-
- if (!need_pass_2)
- p = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) 0,
- repeat, (char *) 0);
}
else
{
- if (now_seg == absolute_section)
+ if (exp.X_op == O_constant)
{
- as_bad ("space allocation too complex in absolute section");
- subseg_set (text_section, 0);
+ long repeat;
+
+ repeat = exp.X_add_number;
+ if (mult)
+ repeat *= mult;
+ if (repeat <= 0)
+ {
+ if (! flag_mri || repeat < 0)
+ as_warn (".space repeat count is %s, ignored",
+ repeat ? "negative" : "zero");
+ goto getout;
+ }
+
+ /* If we are in the absolute section, just bump the offset. */
+ if (now_seg == absolute_section)
+ {
+ abs_section_offset += repeat;
+ goto getout;
+ }
+
+ /* If we are secretly in an MRI common section, then
+ creating space just increases the size of the common
+ symbol. */
+ if (mri_common_symbol != NULL)
+ {
+ S_SET_VALUE (mri_common_symbol,
+ S_GET_VALUE (mri_common_symbol) + repeat);
+ goto getout;
+ }
+
+ if (!need_pass_2)
+ p = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) 0,
+ repeat, (char *) 0);
}
- if (mri_common_symbol != NULL)
+ else
{
- as_bad ("space allocation too complex in common section");
- mri_common_symbol = NULL;
+ if (now_seg == absolute_section)
+ {
+ as_bad ("space allocation too complex in absolute section");
+ subseg_set (text_section, 0);
+ }
+ if (mri_common_symbol != NULL)
+ {
+ as_bad ("space allocation too complex in common section");
+ mri_common_symbol = NULL;
+ }
+ if (!need_pass_2)
+ p = frag_var (rs_space, 1, 1, (relax_substateT) 0,
+ make_expr_symbol (&exp), 0L, (char *) 0);
}
- if (!need_pass_2)
- p = frag_var (rs_space, 1, 1, (relax_substateT) 0,
- make_expr_symbol (&exp), 0L, (char *) 0);
- }
- SKIP_WHITESPACE ();
- if (*input_line_pointer == ',')
- {
- input_line_pointer++;
- temp_fill = get_absolute_expression ();
- }
- else
- {
- temp_fill = 0;
- }
- if (p)
- {
- *p = temp_fill;
+
+ if (p)
+ *p = val.X_add_number;
}
+
+ getout:
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+
demand_empty_rest_of_line ();
}
offsetT count;
int flen;
char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT];
+ char *stop = NULL;
+ char stopc;
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
count = get_absolute_expression ();
if (*input_line_pointer != ',')
{
as_bad ("missing value");
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
ignore_rest_of_line ();
return;
}
flen = hex_float (float_type, temp);
if (flen < 0)
{
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
ignore_rest_of_line ();
return;
}
if (err)
{
as_bad ("Bad floating literal: %s", err);
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
ignore_rest_of_line ();
return;
}
memcpy (p, temp, (unsigned int) flen);
}
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+
demand_empty_rest_of_line ();
}
s_struct (ignore)
int ignore;
{
+ char *stop = NULL;
+ char stopc;
+
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
abs_section_offset = get_absolute_expression ();
subseg_set (absolute_section, 0);
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
demand_empty_rest_of_line ();
}
/* worker to do .byte etc statements */
/* clobbers input_line_pointer, checks */
/* end-of-line. */
-void
-cons (nbytes)
+static void
+cons_worker (nbytes, rva)
register int nbytes; /* 1=.byte, 2=.word, 4=.long */
+ int rva;
{
int c;
expressionS exp;
+ char *stop = NULL;
+ char stopc;
#ifdef md_flush_pending_output
md_flush_pending_output ();
#endif
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+
if (is_it_end_of_statement ())
{
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
demand_empty_rest_of_line ();
return;
}
c = 0;
do
{
- if (flag_mri)
+ if (flag_m68k_mri)
parse_mri_cons (&exp, (unsigned int) nbytes);
else
TC_PARSE_CONS_EXPRESSION (&exp, (unsigned int) nbytes);
+
+ if (rva)
+ {
+ if (exp.X_op == O_symbol)
+ exp.X_op = O_symbol_rva;
+ else
+ as_fatal ("rva without symbol");
+ }
emit_expr (&exp, (unsigned int) nbytes);
++c;
}
mri_pending_align = 1;
input_line_pointer--; /* Put terminator back into stream. */
+
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
+
demand_empty_rest_of_line ();
}
+
+void
+cons (size)
+ int size;
+{
+ cons_worker (size, 0);
+}
+
+void
+s_rva (size)
+ int size;
+{
+ cons_worker (size, 1);
+}
+
+
/* Put the contents of expression EXP into the object file using
NBYTES bytes. If need_pass_2 is 1, this does nothing. */
fix_new_exp (frag_now, p - frag_now->fr_literal, (int) nbytes, exp, 0,
/* @@ Should look at CPU word size. */
nbytes == 2 ? BFD_RELOC_16
- : nbytes == 8 ? BFD_RELOC_64
- : BFD_RELOC_32);
+ : nbytes == 8 ? BFD_RELOC_64
+ : BFD_RELOC_32);
#endif
#else
#ifdef TC_CONS_FIX_NEW
d += hex_value (*input_line_pointer);
++input_line_pointer;
}
- bytes[i++] = d;
+ if (target_big_endian)
+ bytes[i] = d;
+ else
+ bytes[length - i - 1] = d;
+ ++i;
}
if (i < length)
- memset (bytes + i, 0, length - i);
+ {
+ if (target_big_endian)
+ memset (bytes + i, 0, length - i);
+ else
+ memset (bytes, 0, length - i);
+ }
return length;
}
{
register int len;
- for (len = *len_pointer;
- len > 0;
- len--)
+ for (len = *len_pointer; len > 0; len--)
{
if (*s == 0)
{
}
}
}
- return (s);
+ return s;
}
\f
/*
obstack_1grow (¬es, c);
len++;
}
- /* JF this next line is so demand_copy_C_string will return a null
- termanated string. */
+ /* JF this next line is so demand_copy_C_string will return a
+ null terminated string. */
obstack_1grow (¬es, '\0');
retval = obstack_finish (¬es);
}
char *sym_name;
{
register symbolS *symbolP; /* symbol we are working with */
+ char *stop;
+ char stopc;
input_line_pointer++;
if (*input_line_pointer == '=')
while (*input_line_pointer == ' ' || *input_line_pointer == '\t')
input_line_pointer++;
+ if (flag_mri)
+ stop = mri_comment_field (&stopc);
+
if (sym_name[0] == '.' && sym_name[1] == '\0')
{
/* Turn '. = mumble' into a .org mumble */
register segT segment;
expressionS exp;
- register char *p;
segment = get_known_segmented_expression (&exp);
if (!need_pass_2)
symbolP = symbol_find_or_make (sym_name);
pseudo_set (symbolP);
}
+
+ if (flag_mri)
+ mri_comment_end (stop, stopc);
} /* equals() */
/* .include -- include a file at this point. */
FILE *try;
char *path;
- filename = demand_copy_string (&i);
+ if (! flag_m68k_mri)
+ filename = demand_copy_string (&i);
+ else
+ {
+ SKIP_WHITESPACE ();
+ i = 0;
+ while (! is_end_of_line[(unsigned char) *input_line_pointer]
+ && *input_line_pointer != ' '
+ && *input_line_pointer != '\t')
+ {
+ obstack_1grow (¬es, *input_line_pointer);
+ ++input_line_pointer;
+ ++i;
+ }
+ obstack_1grow (¬es, '\0');
+ filename = obstack_finish (¬es);
+ while (! is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ }
demand_empty_rest_of_line ();
path = xmalloc ((unsigned long) i + include_dir_maxlen + 5 /* slop */ );
for (i = 0; i < include_dir_count; i++)
}
+void
+read_print_statistics (file)
+ FILE *file;
+{
+ hash_print_statistics (file, "pseudo-op table", po_hash);
+}
+
/* end of read.c */