-
-/* Return a hash value for the pointer pointed to by DEF. */
-
-static hashval_t
-leading_ptr_hash (const void *def)
-{
- return htab_hash_pointer (*(const void *const *) def);
-}
-
-/* Return true if DEF1 and DEF2 are pointers to the same pointer. */
-
-static int
-leading_ptr_eq_p (const void *def1, const void *def2)
-{
- return *(const void *const *) def1 == *(const void *const *) def2;
-}
-
-/* Associate PTR with the file position given by FILENAME and LINENO. */
-
-static void
-set_rtx_ptr_loc (const void *ptr, const char *filename, int lineno)
-{
- struct ptr_loc *loc;
-
- loc = (struct ptr_loc *) obstack_alloc (&ptr_loc_obstack,
- sizeof (struct ptr_loc));
- loc->ptr = ptr;
- loc->filename = filename;
- loc->lineno = lineno;
- *htab_find_slot (ptr_locs, loc, INSERT) = loc;
-}
-
-/* Return the position associated with pointer PTR. Return null if no
- position was set. */
-
-static const struct ptr_loc *
-get_rtx_ptr_loc (const void *ptr)
-{
- return (const struct ptr_loc *) htab_find (ptr_locs, &ptr);
-}
-
-/* Associate NEW_PTR with the same file position as OLD_PTR. */
-
-void
-copy_rtx_ptr_loc (const void *new_ptr, const void *old_ptr)
-{
- const struct ptr_loc *loc = get_rtx_ptr_loc (old_ptr);
- if (loc != 0)
- set_rtx_ptr_loc (new_ptr, loc->filename, loc->lineno);
-}
-
-/* If PTR is associated with a known file position, print a #line
- directive for it. */
-
-void
-print_rtx_ptr_loc (const void *ptr)
-{
- const struct ptr_loc *loc = get_rtx_ptr_loc (ptr);
- if (loc != 0)
- printf ("#line %d \"%s\"\n", loc->lineno, loc->filename);
-}
-
-/* Return a condition that satisfies both COND1 and COND2. Either string
- may be null or empty. */
-
-const char *
-join_c_conditions (const char *cond1, const char *cond2)
-{
- char *result;
- const void **entry;
-
- if (cond1 == 0 || cond1[0] == 0)
- return cond2;
-
- if (cond2 == 0 || cond2[0] == 0)
- return cond1;
-
- if (strcmp (cond1, cond2) == 0)
- return cond1;
-
- result = concat ("(", cond1, ") && (", cond2, ")", NULL);
- obstack_ptr_grow (&joined_conditions_obstack, result);
- obstack_ptr_grow (&joined_conditions_obstack, cond1);
- obstack_ptr_grow (&joined_conditions_obstack, cond2);
- entry = XOBFINISH (&joined_conditions_obstack, const void **);
- *htab_find_slot (joined_conditions, entry, INSERT) = entry;
- return result;
-}
-
-/* Print condition COND, wrapped in brackets. If COND was created by
- join_c_conditions, recursively invoke this function for the original
- conditions and join the result with "&&". Otherwise print a #line
- directive for COND if its original file position is known. */
-
-void
-print_c_condition (const char *cond)
-{
- const char **halves = (const char **) htab_find (joined_conditions, &cond);
- if (halves != 0)
- {
- printf ("(");
- print_c_condition (halves[1]);
- printf (" && ");
- print_c_condition (halves[2]);
- printf (")");
- }
- else
- {
- putc ('\n', stdout);
- print_rtx_ptr_loc (cond);
- printf ("(%s)", cond);
- }
-}
-
-/* Read chars from INFILE until a non-whitespace char
- and return that. Comments, both Lisp style and C style,
- are treated as whitespace.
- Tools such as genflags use this function. */
-
-int
-read_skip_spaces (FILE *infile)
-{
- int c;
-
- while (1)
- {
- c = getc (infile);
- switch (c)
- {
- case '\n':
- read_rtx_lineno++;
- break;
-
- case ' ': case '\t': case '\f': case '\r':
- break;
-
- case ';':
- do
- c = getc (infile);
- while (c != '\n' && c != EOF);
- read_rtx_lineno++;
- break;
-
- case '/':
- {
- int prevc;
- c = getc (infile);
- if (c != '*')
- fatal_expected_char (infile, '*', c);
-
- prevc = 0;
- while ((c = getc (infile)) && c != EOF)
- {
- if (c == '\n')
- read_rtx_lineno++;
- else if (prevc == '*' && c == '/')
- break;
- prevc = c;
- }
- }
- break;
-
- default:
- return c;
- }
- }
-}
-
-/* Read an rtx code name into the buffer STR[].
- It is terminated by any of the punctuation chars of rtx printed syntax. */
-
-static void
-read_name (char *str, FILE *infile)
-{
- char *p;
- int c;
-
- c = read_skip_spaces (infile);
-
- p = str;
- while (1)
- {
- if (c == ' ' || c == '\n' || c == '\t' || c == '\f' || c == '\r' || c == EOF)
- break;
- if (c == ':' || c == ')' || c == ']' || c == '"' || c == '/'
- || c == '(' || c == '[')
- {
- ungetc (c, infile);
- break;
- }
- *p++ = c;
- c = getc (infile);
- }
- if (p == str)
- fatal_with_file_and_line (infile, "missing name or number");
- if (c == '\n')
- read_rtx_lineno++;
-
- *p = 0;
-
- if (md_constants)
- {
- /* Do constant expansion. */
- struct md_constant *def;
-
- p = str;
- do
- {
- struct md_constant tmp_def;
-
- tmp_def.name = p;
- def = (struct md_constant *) htab_find (md_constants, &tmp_def);
- if (def)
- p = def->value;
- } while (def);
- if (p != str)
- strcpy (str, p);
- }
-}
-
-/* Subroutine of the string readers. Handles backslash escapes.
- Caller has read the backslash, but not placed it into the obstack. */
-static void
-read_escape (FILE *infile)
-{
- int c = getc (infile);
-
- switch (c)
- {
- /* Backslash-newline is replaced by nothing, as in C. */
- case '\n':
- read_rtx_lineno++;
- return;
-
- /* \" \' \\ are replaced by the second character. */
- case '\\':
- case '"':
- case '\'':
- break;
-
- /* Standard C string escapes:
- \a \b \f \n \r \t \v
- \[0-7] \x
- all are passed through to the output string unmolested.
- In normal use these wind up in a string constant processed
- by the C compiler, which will translate them appropriately.
- We do not bother checking that \[0-7] are followed by up to
- two octal digits, or that \x is followed by N hex digits.
- \? \u \U are left out because they are not in traditional C. */
- case 'a': case 'b': case 'f': case 'n': case 'r': case 't': case 'v':
- case '0': case '1': case '2': case '3': case '4': case '5': case '6':
- case '7': case 'x':
- obstack_1grow (&string_obstack, '\\');
- break;
-
- /* \; makes stuff for a C string constant containing
- newline and tab. */
- case ';':
- obstack_grow (&string_obstack, "\\n\\t", 4);
- return;
-
- /* pass anything else through, but issue a warning. */
- default:
- fprintf (stderr, "%s:%d: warning: unrecognized escape \\%c\n",
- read_rtx_filename, read_rtx_lineno, c);
- obstack_1grow (&string_obstack, '\\');
- break;
- }
-
- obstack_1grow (&string_obstack, c);
-}
-
-
-/* Read a double-quoted string onto the obstack. Caller has scanned
- the leading quote. */
-static char *
-read_quoted_string (FILE *infile)
-{
- int c;
-
- while (1)
- {
- c = getc (infile); /* Read the string */
- if (c == '\n')
- read_rtx_lineno++;
- else if (c == '\\')
- {
- read_escape (infile);
- continue;
- }
- else if (c == '"' || c == EOF)
- break;
-
- obstack_1grow (&string_obstack, c);
- }
-
- obstack_1grow (&string_obstack, 0);
- return XOBFINISH (&string_obstack, char *);
-}
-
-/* Read a braced string (a la Tcl) onto the string obstack. Caller
- has scanned the leading brace. Note that unlike quoted strings,
- the outermost braces _are_ included in the string constant. */
-static char *
-read_braced_string (FILE *infile)
-{
- int c;
- int brace_depth = 1; /* caller-processed */
- unsigned long starting_read_rtx_lineno = read_rtx_lineno;
-
- obstack_1grow (&string_obstack, '{');
- while (brace_depth)
- {
- c = getc (infile); /* Read the string */
-
- if (c == '\n')
- read_rtx_lineno++;
- else if (c == '{')
- brace_depth++;
- else if (c == '}')
- brace_depth--;
- else if (c == '\\')
- {
- read_escape (infile);
- continue;
- }
- else if (c == EOF)
- fatal_with_file_and_line
- (infile, "missing closing } for opening brace on line %lu",
- starting_read_rtx_lineno);
-
- obstack_1grow (&string_obstack, c);
- }
-
- obstack_1grow (&string_obstack, 0);
- return XOBFINISH (&string_obstack, char *);
-}
-
-/* Read some kind of string constant. This is the high-level routine
- used by read_rtx. It handles surrounding parentheses, leading star,
- and dispatch to the appropriate string constant reader. */
-
-static char *
-read_string (FILE *infile, int star_if_braced)
-{
- char *stringbuf;
- int saw_paren = 0;
- int c, old_lineno;
-
- c = read_skip_spaces (infile);
- if (c == '(')
- {
- saw_paren = 1;
- c = read_skip_spaces (infile);
- }
-
- old_lineno = read_rtx_lineno;
- if (c == '"')
- stringbuf = read_quoted_string (infile);
- else if (c == '{')
- {
- if (star_if_braced)
- obstack_1grow (&string_obstack, '*');
- stringbuf = read_braced_string (infile);
- }
- else
- fatal_with_file_and_line (infile, "expected `\"' or `{', found `%c'", c);
-
- if (saw_paren)
- {
- c = read_skip_spaces (infile);
- if (c != ')')
- fatal_expected_char (infile, ')', c);
- }
-
- set_rtx_ptr_loc (stringbuf, read_rtx_filename, old_lineno);
- return stringbuf;
-}