qstring: backquoted strings seem to work now...

Hopefully backquoted strings should work correctly now.
This commit is contained in:
H. Peter Anvin 2008-06-01 21:34:49 -07:00
parent 8cad14bbcf
commit 6ecc159a54
5 changed files with 112 additions and 47 deletions

View File

@ -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)
int nasm_strnicmp(const char *s1, const char *s2, size_t 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;
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)
{

View File

@ -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

View File

@ -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;
@ -1204,6 +1201,16 @@ static int mstrcmp(const char *p, const char *q, bool casesense)
return casesense ? strcmp(p, q) : nasm_stricmp(p, q);
}
/*
* 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
@ -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;
}

17
quote.c
View File

@ -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;
}

View File

@ -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;