/* nasmlib.c library routines for the Netwide Assembler * * The Netwide Assembler is copyright (C) 1996 Simon Tatham and * Julian Hall. All rights reserved. The software is * redistributable under the licence given in the file "Licence" * distributed in the NASM archive. */ #include #include #include #include #include "nasm.h" #include "nasmlib.h" /*#include "insns.h"*/ /* For MAX_KEYWORD */ #define lib_isnumchar(c) ( isalnum(c) || (c) == '$') #define numvalue(c) ((c)>='a' ? (c)-'a'+10 : (c)>='A' ? (c)-'A'+10 : (c)-'0') yasm_intnum *nasm_readnum (char *str, int *error) { char *r = str, *q, *p; long radix; yasm_intnum *intn; char save; int digit; int sign = 0; *error = FALSE; while (isspace(*r)) r++; /* find start of number */ /* * If the number came from make_tok_num (as a result of an %assign), it * might have a '-' built into it (rather than in a preceeding token). */ if (*r == '-') { r++; sign = 1; } q = r; while (lib_isnumchar(*q)) q++; /* find end of number */ /* * If it begins 0x, 0X or $, or ends in H, it's in hex. if it * ends in Q, it's octal. if it ends in B, it's binary. * Otherwise, it's ordinary decimal. */ if (*r=='0' && (r[1]=='x' || r[1]=='X')) radix = 16, r += 2; else if (*r=='$') radix = 16, r++; else if (q[-1]=='H' || q[-1]=='h') radix = 16 , q--; else if (q[-1]=='Q' || q[-1]=='q' || q[-1]=='O' || q[-1]=='o') radix = 8 , q--; else if (q[-1]=='B' || q[-1]=='b') radix = 2 , q--; else radix = 10; /* * If this number has been found for us by something other than * the ordinary scanners, then it might be malformed by having * nothing between the prefix and the suffix. Check this case * now. */ if (r >= q) { *error = TRUE; return yasm_intnum_create_uint(0); } /* Check for valid number of that radix */ p = r; while (*p && p < q) { if (*p<'0' || (*p>'9' && *p<'A') || (digit = numvalue(*p)) >= radix) { *error = TRUE; return yasm_intnum_create_uint(0); } p++; } /* Use intnum to actually do the conversion */ save = *q; *q = '\0'; switch (radix) { case 2: intn = yasm_intnum_create_bin(r); break; case 8: intn = yasm_intnum_create_oct(r); break; case 10: intn = yasm_intnum_create_dec(r); break; case 16: intn = yasm_intnum_create_hex(r); break; default: *error = TRUE; intn = yasm_intnum_create_uint(0); break; } *q = save; if (sign) yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL); return intn; } yasm_intnum *nasm_readstrnum (char *str, size_t length, int *warn) { char save; yasm_intnum *intn; *warn = FALSE; save = str[length]; str[length] = '\0'; intn = yasm_intnum_create_charconst_nasm(str); str[length] = save; return intn; } static char *file_name = NULL; static long line_number = 0; char *nasm_src_set_fname(char *newname) { char *oldname = file_name; file_name = newname; return oldname; } char *nasm_src_get_fname(void) { return file_name; } long nasm_src_set_linnum(long newline) { long oldline = line_number; line_number = newline; return oldline; } long nasm_src_get_linnum(void) { return line_number; } int nasm_src_get(long *xline, char **xname) { if (!file_name || !*xname || strcmp(*xname, file_name)) { nasm_free(*xname); *xname = file_name ? nasm_strdup(file_name) : NULL; *xline = line_number; return -2; } if (*xline != line_number) { long tmp = line_number - *xline; *xline = line_number; return tmp; } return 0; } void nasm_quote(char **str) { size_t ln=strlen(*str); char q=(*str)[0]; char *p; if (ln>1 && (*str)[ln-1]==q && (q=='"' || q=='\'')) return; q = '"'; if (strchr(*str,q)) q = '\''; p = nasm_malloc(ln+3); strcpy(p+1, *str); nasm_free(*str); p[ln+1] = p[0] = q; p[ln+2] = 0; *str = p; } char *nasm_strcat(const char *one, const char *two) { char *rslt; size_t l1=strlen(one); rslt = nasm_malloc(l1+strlen(two)+1); strcpy(rslt, one); strcpy(rslt+l1, two); return rslt; }