aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Schmidt <wschmidt@linux.ibm.com>2021-07-16 12:21:08 -0400
committerBill Schmidt <wschmidt@linux.ibm.com>2021-07-16 12:52:39 -0400
commit9abd2ac5a9b694bcdd871165d109f94866032534 (patch)
tree6a1709e37f7f683f85957f7b00d9091950f37013
parent43fa306f1d723d9d6c0884e38b102b954d3a4c30 (diff)
downloadgcc-9abd2ac5a9b694bcdd871165d109f94866032534.zip
gcc-9abd2ac5a9b694bcdd871165d109f94866032534.tar.gz
gcc-9abd2ac5a9b694bcdd871165d109f94866032534.tar.bz2
rs6000: Add helper functions for parsing
2021-07-16 Bill Schmidt <wschmidt@linux.ibm.com> gcc/ * config/rs6000/rs6000-gen-builtins.c (consume_whitespace): New function. (advance_line): Likewise. (safe_inc_pos): Likewise. (match_identifier): Likewise. (match_integer): Likewise. (match_to_right_bracket): Likewise.
-rw-r--r--gcc/config/rs6000/rs6000-gen-builtins.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c b/gcc/config/rs6000/rs6000-gen-builtins.c
index 3c53c34..7923cc4 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -210,3 +210,113 @@ ovld_diag (const char * fmt, ...)
vfprintf (stderr, fmt, args);
va_end (args);
}
+
+/* Pass over whitespace (other than a newline, which terminates the scan). */
+static void
+consume_whitespace (void)
+{
+ while (pos < LINELEN && isspace(linebuf[pos]) && linebuf[pos] != '\n')
+ pos++;
+ return;
+}
+
+/* Get the next nonblank, noncomment line, returning 0 on EOF, 1 otherwise. */
+static int
+advance_line (FILE *file)
+{
+ while (1)
+ {
+ /* Read ahead one line and check for EOF. */
+ if (!fgets (linebuf, sizeof linebuf, file))
+ return 0;
+ line++;
+ size_t len = strlen (linebuf);
+ if (linebuf[len - 1] != '\n')
+ (*diag) ("line doesn't terminate with newline\n");
+ pos = 0;
+ consume_whitespace ();
+ if (linebuf[pos] != '\n' && linebuf[pos] != ';')
+ return 1;
+ }
+}
+
+static inline void
+safe_inc_pos (void)
+{
+ if (pos++ >= LINELEN)
+ {
+ (*diag) ("line length overrun.\n");
+ exit (1);
+ }
+}
+
+/* Match an identifier, returning NULL on failure, else a pointer to a
+ buffer containing the identifier. */
+static char *
+match_identifier (void)
+{
+ int lastpos = pos - 1;
+ while (isalnum (linebuf[lastpos + 1]) || linebuf[lastpos + 1] == '_')
+ ++lastpos;
+
+ if (lastpos < pos)
+ return 0;
+
+ char *buf = (char *) malloc (lastpos - pos + 2);
+ memcpy (buf, &linebuf[pos], lastpos - pos + 1);
+ buf[lastpos - pos + 1] = '\0';
+
+ pos = lastpos + 1;
+ return buf;
+}
+
+/* Match an integer and return the string representing its value,
+ or a null string on failure. */
+static char *
+match_integer (void)
+{
+ int startpos = pos;
+ if (linebuf[pos] == '-')
+ safe_inc_pos ();
+
+ int lastpos = pos - 1;
+ while (isdigit (linebuf[lastpos + 1]))
+ ++lastpos;
+
+ if (lastpos < pos)
+ return NULL;
+
+ pos = lastpos + 1;
+ char *buf = (char *) malloc (lastpos - startpos + 2);
+ memcpy (buf, &linebuf[startpos], lastpos - startpos + 1);
+ buf[lastpos - startpos + 1] = '\0';
+ return buf;
+}
+
+/* Match a string up to but not including a ']', and return its value,
+ or zero if there is nothing before the ']'. Error if we don't find
+ such a character. */
+static const char *
+match_to_right_bracket (void)
+{
+ int lastpos = pos - 1;
+ while (linebuf[lastpos + 1] != ']')
+ {
+ if (linebuf[lastpos + 1] == '\n')
+ {
+ (*diag) ("no ']' found before end of line.\n");
+ exit (1);
+ }
+ ++lastpos;
+ }
+
+ if (lastpos < pos)
+ return 0;
+
+ char *buf = (char *) malloc (lastpos - pos + 2);
+ memcpy (buf, &linebuf[pos], lastpos - pos + 1);
+ buf[lastpos - pos + 1] = '\0';
+
+ pos = lastpos + 1;
+ return buf;
+}