summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2008-06-01 21:34:49 -0700
committerH. Peter Anvin <hpa@zytor.com>2008-06-01 21:34:49 -0700
commit6ecc159a54c643a46c5682fd9245601c252924f5 (patch)
tree19ee83dab5cca46eb0840a6d1fcf92f7eaa907ac
parent8cad14bbcf0b8c056e6f81dccf4af38537e0bac6 (diff)
downloadnasm-6ecc159a54c643a46c5682fd9245601c252924f5.tar.gz
nasm-6ecc159a54c643a46c5682fd9245601c252924f5.tar.bz2
nasm-6ecc159a54c643a46c5682fd9245601c252924f5.zip
qstring: backquoted strings seem to work now...
Hopefully backquoted strings should work correctly now.
-rw-r--r--nasmlib.c63
-rw-r--r--nasmlib.h4
-rw-r--r--preproc.c48
-rw-r--r--quote.c17
-rw-r--r--stdscan.c29
5 files changed, 113 insertions, 48 deletions
diff --git a/nasmlib.c b/nasmlib.c
index d74b8ac..a4e7915 100644
--- a/nasmlib.c
+++ b/nasmlib.c
@@ -149,31 +149,58 @@ char *nasm_strndup(char *s, size_t len)
#ifndef nasm_stricmp
int nasm_stricmp(const char *s1, const char *s2)
{
- while (*s1 && tolower(*s1) == tolower(*s2))
- s1++, s2++;
- if (!*s1 && !*s2)
- return 0;
- else if (tolower(*s1) < tolower(*s2))
- return -1;
- else
- return 1;
+ unsigned char c1, c2;
+ int d;
+
+ while (1) {
+ c1 = *s1++;
+ c2 = *s2++;
+ d = c1-c2;
+
+ if (d)
+ return d;
+ if (!c1)
+ break;
+ }
+ return 0;
}
#endif
#ifndef nasm_strnicmp
-int nasm_strnicmp(const char *s1, const char *s2, int n)
-{
- while (n > 0 && *s1 && tolower(*s1) == tolower(*s2))
- s1++, s2++, n--;
- if ((!*s1 && !*s2) || n == 0)
- return 0;
- else if (tolower(*s1) < tolower(*s2))
- return -1;
- else
- return 1;
+int nasm_strnicmp(const char *s1, const char *s2, size_t n)
+{
+ unsigned char c1, c2;
+ int d;
+
+ while (n--) {
+ c1 = *s1++;
+ c2 = *s2++;
+ d = c1-c2;
+
+ if (d)
+ return d;
+ if (!c1)
+ break;
+ }
+ return 0;
}
#endif
+int nasm_memicmp(const char *s1, const char *s2, size_t n)
+{
+ unsigned char c1, c2;
+ int d;
+
+ while (n--) {
+ c1 = tolower(*s1++);
+ c2 = tolower(*s2++);
+ d = c1-c2;
+ if (d)
+ return d;
+ }
+ return 0;
+}
+
#ifndef nasm_strsep
char *nasm_strsep(char **stringp, const char *delim)
{
diff --git a/nasmlib.h b/nasmlib.h
index 39137af..7eb5c47 100644
--- a/nasmlib.h
+++ b/nasmlib.h
@@ -122,9 +122,11 @@ int nasm_stricmp(const char *, const char *);
#elif defined(HAVE_STRNICMP)
#define nasm_strnicmp strnicmp
#else
-int nasm_strnicmp(const char *, const char *, int);
+int nasm_strnicmp(const char *, const char *, size_t);
#endif
+int nasm_memicmp(const char *, const char *, size_t);
+
#if defined(HAVE_STRSEP)
#define nasm_strsep strsep
#else
diff --git a/preproc.c b/preproc.c
index 46f8c6b..3a33858 100644
--- a/preproc.c
+++ b/preproc.c
@@ -985,7 +985,8 @@ static void delete_Blocks(void)
* back to the caller. It sets the type and text elements, and
* also the mac and next elements to NULL.
*/
-static Token *new_Token(Token * next, enum pp_token_type type, char *text, int txtlen)
+static Token *new_Token(Token * next, enum pp_token_type type,
+ char *text, int txtlen)
{
Token *t;
int i;
@@ -1006,8 +1007,8 @@ static Token *new_Token(Token * next, enum pp_token_type type, char *text, int t
} else {
if (txtlen == 0)
txtlen = strlen(text);
- t->text = nasm_malloc(1 + txtlen);
- strncpy(t->text, text, txtlen);
+ t->text = nasm_malloc(txtlen+1);
+ memcpy(t->text, text, txtlen);
t->text[txtlen] = '\0';
}
return t;
@@ -1144,16 +1145,12 @@ static int ppscan(void *private_data, struct tokenval *tokval)
if (tline->type == TOK_STRING) {
bool rn_warn;
- char q, *r;
- int l;
+ size_t l;
- r = tline->text;
- q = *r++;
- l = strlen(r);
+ l = nasm_unquote(tline->text);
+ /* TOKEN_ERRNUM if improperly quoted... */
- if (l == 0 || r[l - 1] != q)
- return tokval->t_type = TOKEN_ERRNUM;
- tokval->t_integer = readstrnum(r, l - 1, &rn_warn);
+ tokval->t_integer = readstrnum(tline->text, l, &rn_warn);
if (rn_warn)
error(ERR_WARNING | ERR_PASS1, "character constant too long");
tokval->t_charptr = NULL;
@@ -1205,6 +1202,16 @@ static int mstrcmp(const char *p, const char *q, bool casesense)
}
/*
+ * Compare a string to the name of an existing macro; this is a
+ * simple wrapper which calls either strcmp or nasm_stricmp
+ * depending on the value of the `casesense' parameter.
+ */
+static int mmemcmp(const char *p, const char *q, size_t l, bool casesense)
+{
+ return casesense ? memcmp(p, q, l) : nasm_memicmp(p, q, l);
+}
+
+/*
* Return the Context structure associated with a %$ token. Return
* NULL, having _already_ reported an error condition, if the
* context stack isn't deep enough for the supplied number of $
@@ -1511,13 +1518,20 @@ static bool if_condition(Token * tline, enum preproc_token ct)
j = false; /* found mismatching tokens */
break;
}
- /* Unify surrounding quotes for strings */
- /* XXX: this doesn't work anymore */
+ /* When comparing strings, need to unquote them first */
if (t->type == TOK_STRING) {
- tt->text[0] = t->text[0];
- tt->text[strlen(tt->text) - 1] = t->text[0];
- }
- if (mstrcmp(tt->text, t->text, i == PPC_IFIDN) != 0) {
+ size_t l1 = nasm_unquote(t->text);
+ size_t l2 = nasm_unquote(tt->text);
+
+ if (l1 != l2) {
+ j = false;
+ break;
+ }
+ if (mmemcmp(t->text, tt->text, l1, i == PPC_IFIDN)) {
+ j = false;
+ break;
+ }
+ } else if (mstrcmp(tt->text, t->text, i == PPC_IFIDN) != 0) {
j = false; /* found mismatching tokens */
break;
}
diff --git a/quote.c b/quote.c
index 0d8ee2b..f926b85 100644
--- a/quote.c
+++ b/quote.c
@@ -340,6 +340,23 @@ size_t nasm_unquote(char *str)
break;
}
}
+ switch (state) {
+ case st_start:
+ case st_backslash:
+ break;
+ case st_oct:
+ *q++ = nval;
+ break;
+ case st_hex:
+ *q++ = ndig ? nval : *escp;
+ break;
+ case st_ucs:
+ if (ndig)
+ q = emit_utf8(q, nval);
+ else
+ *q++ = *escp;
+ break;
+ }
*q = '\0';
return q-str;
}
diff --git a/stdscan.c b/stdscan.c
index 30269e4..0fdd7af 100644
--- a/stdscan.c
+++ b/stdscan.c
@@ -8,6 +8,7 @@
#include "nasm.h"
#include "nasmlib.h"
+#include "quote.h"
#include "stdscan.h"
#include "insns.h"
@@ -166,26 +167,30 @@ int stdscan(void *private_data, struct tokenval *tv)
r = stdscan_copy(r, stdscan_bufptr - r);
tv->t_integer = readnum(r, &rn_error);
stdscan_pop();
- if (rn_error)
- return tv->t_type = TOKEN_ERRNUM; /* some malformation occurred */
+ if (rn_error) {
+ /* some malformation occurred */
+ return tv->t_type = TOKEN_ERRNUM;
+ }
tv->t_charptr = NULL;
return tv->t_type = TOKEN_NUM;
}
- } else if (*stdscan_bufptr == '\'' || *stdscan_bufptr == '"') {
+ } else if (*stdscan_bufptr == '\'' || *stdscan_bufptr == '"' ||
+ *stdscan_bufptr == '`') {
/* a char constant */
- char quote = *stdscan_bufptr++, *r;
+ char s;
bool rn_warn;
- r = tv->t_charptr = stdscan_bufptr;
- while (*stdscan_bufptr && *stdscan_bufptr != quote)
- stdscan_bufptr++;
- tv->t_inttwo = stdscan_bufptr - r; /* store full version */
- if (!*stdscan_bufptr)
+ stdscan_bufptr = nasm_skip_string(tv->t_charptr = stdscan_bufptr);
+ s = *stdscan_bufptr;
+ tv->t_inttwo = nasm_unquote(tv->t_charptr);
+ if (!s)
return tv->t_type = TOKEN_ERRNUM; /* unmatched quotes */
stdscan_bufptr++; /* skip over final quote */
- tv->t_integer = readstrnum(r, tv->t_inttwo, &rn_warn);
- /* rn_warn is not checked on purpose; it might not be a valid number */
+ tv->t_integer = readstrnum(tv->t_charptr, tv->t_inttwo, &rn_warn);
+ /* Issue: can't readily check rn_warn, because we might be in
+ a db family context... */
return tv->t_type = TOKEN_NUM;
- } else if (*stdscan_bufptr == ';') { /* a comment has happened - stay */
+ } else if (*stdscan_bufptr == ';') {
+ /* a comment has happened - stay */
return tv->t_type = 0;
} else if (stdscan_bufptr[0] == '>' && stdscan_bufptr[1] == '>') {
stdscan_bufptr += 2;