commit 77b69ae26c69fd4b8f9d6b7de65da5f61d09f2b0
parent e3f7a65bec715d1b15a6a31139d5938a1bb83f7c
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Thu, 11 Jan 2018 09:11:12 +0000
[as] Trim characters from fields
It was creating some stupid problems and the code
wasn't very optimal. This new version is simpler
(if you can read good C code) and avoid an additional
run over the field.
Diffstat:
M | as/parser.c | | | 43 | +++++++++++++++++++++++++------------------ |
1 file changed, 25 insertions(+), 18 deletions(-)
diff --git a/as/parser.c b/as/parser.c
@@ -53,23 +53,29 @@ getargs(char *s)
static char *
field(char **oldp, size_t *siz)
{
- char *s, *begin;
+ char *s, *t, *begin;
+ size_t n;
if ((begin = *oldp) == NULL)
return NULL;
- if (*begin == '/') {
- *begin = '\0';
- *oldp = NULL;
- } else if (s = memchr(begin, '\t', *siz)) {
- *s++ = '\0';
- *siz -= s - begin;
- *oldp = s;
- } else {
- *oldp = NULL;
+ for (s = begin; *s == ' '; ++s)
+ ;
+ if (*s == '\0' || *s == '/' || *s == ';') {
+ *t = '\0';
+ return *oldp = NULL;
}
- return (*begin != '\0') ? begin : NULL;
+ for (t = s; *t && *t != '\t'; ++t)
+ ;
+ if (*t == '\t')
+ *t++ = '\0';
+ *siz -= begin - t;
+ *oldp = t;
+
+ while (t >= s && *t == ' ')
+ *t-- = '\0';
+ return (*s != '\0') ? s : NULL;
}
static int
@@ -86,6 +92,11 @@ validlabel(char *name)
case '.':
case '$':
continue;
+ case ':':
+ if (*name != '\0')
+ return 0;
+ *--name = '\0';
+ continue;
default:
return 0;
}
@@ -98,14 +109,8 @@ extract(char *s, size_t len, struct line *lp)
{
int r = 0;
- if (lp->label = field(&s, &len)) {
- size_t n = strlen(lp->label);
- if (lp->label[n-1] == ':')
- lp->label[n-1] = '\0';
- if (!validlabel(lp->label))
- error("incorrect label name '%s'", lp->label);
+ if (lp->label = field(&s, &len))
r++;
- }
if (lp->op = field(&s, &len))
r++;
if (lp->args = field(&s, &len))
@@ -113,6 +118,8 @@ extract(char *s, size_t len, struct line *lp)
if (s && *s && *s != '/')
error("trailing characters at the end of the line");
+ if (lp->label && !validlabel(lp->label))
+ error("incorrect label name '%s'", lp->label);
return r;
}