diff options
Diffstat (limited to 'gas/gasp.c')
-rw-r--r-- | gas/gasp.c | 64 |
1 files changed, 64 insertions, 0 deletions
@@ -48,6 +48,7 @@ suitable for gas to consume. #include "config.h" #include "bin-bugs.h" +#include <assert.h> #include <stdio.h> #include <string.h> #include <getopt.h> @@ -66,6 +67,7 @@ extern char *malloc (); #include "sb.h" #include "macro.h" #include "asintl.h" +#include "xregex.h" char *program_version = "1.2"; @@ -227,6 +229,8 @@ static void hash_add_to_string_table PARAMS ((hash_table *, sb *, sb *, int)); static void hash_add_to_int_table PARAMS ((hash_table *, sb *, int)); static hash_entry *hash_lookup PARAMS ((hash_table *, sb *)); static void checkconst PARAMS ((int, exp_t *)); +static int is_flonum PARAMS ((int, sb *)); +static int chew_flonum PARAMS ((int, sb *, sb *)); static int sb_strtol PARAMS ((int, sb *, int, int *)); static int level_0 PARAMS ((int, sb *, exp_t *)); static int level_1 PARAMS ((int, sb *, exp_t *)); @@ -522,6 +526,62 @@ checkconst (op, term) } } +/* Chew the flonum from the string starting at idx. Adjust idx to + point to the next character after the flonum. */ + +static int +chew_flonum (idx, string, out) + int idx; + sb *string; + sb *out; +{ + sb buf; + regex_t reg; + regmatch_t match; + + /* Duplicate and null terminate `string'. */ + sb_new (&buf); + sb_add_sb (&buf, string); + sb_add_char (&buf, '\0'); + + if (regcomp (®, "([0-9]*\\.[0-9]+([eE][+-]?[0-9]+)?)", REG_EXTENDED) != 0) + return idx; + if (regexec (®, &buf.ptr[idx], 1, &match, 0) != 0) + return idx; + + /* Copy the match to the output. */ + assert (match.rm_eo >= match.rm_so); + sb_add_buffer (out, &buf.ptr[idx], match.rm_eo - match.rm_so); + + sb_kill (&buf); + regfree (®); + idx += match.rm_eo; + return idx; +} + +static int +is_flonum (idx, string) + int idx; + sb *string; +{ + sb buf; + regex_t reg; + int rc; + + /* Duplicate and null terminate `string'. */ + sb_new (&buf); + sb_add_sb (&buf, string); + sb_add_char (&buf, '\0'); + + if (regcomp (®, "^[0-9]*\\.[0-9]+([eE][+-]?[0-9]+)?", REG_EXTENDED) != 0) + return 0; + + rc = regexec (®, &buf.ptr[idx], 0, NULL, 0); + sb_kill (&buf); + regfree (®); + return (rc == 0); +} + /* Turn the number in string at idx into a number of base, fill in ptr, and return the index of the first character not in the number. */ @@ -1132,6 +1192,10 @@ change_base (idx, in, out) idx++; } } + else if (is_flonum (idx, in)) + { + idx = chew_flonum (idx, in, out); + } else if (ISDIGIT (in->ptr[idx])) { int value; |