1 /* nasmlib.c library routines for the Netwide Assembler 2 * 3 * The Netwide Assembler is copyright (C) 1996 Simon Tatham and 4 * Julian Hall. All rights reserved. The software is 5 * redistributable under the licence given in the file "Licence" 6 * distributed in the NASM archive. 7 */ 8 #include <util.h> 9 #include <libyasm/coretype.h> 10 #include <libyasm/intnum.h> 11 #include <ctype.h> 12 13 #include "nasm.h" 14 #include "nasmlib.h" 15 /*#include "insns.h"*/ /* For MAX_KEYWORD */ 16 17 #define lib_isnumchar(c) ( isalnum(c) || (c) == '$') 18 #define numvalue(c) ((c)>='a' ? (c)-'a'+10 : (c)>='A' ? (c)-'A'+10 : (c)-'0') 19 20 yasm_intnum *nasm_readnum (char *str, int *error) 21 { 22 char *r = str, *q, *p; 23 long radix; 24 yasm_intnum *intn; 25 char save; 26 int digit; 27 int sign = 0; 28 29 *error = FALSE; 30 31 while (isspace(*r)) r++; /* find start of number */ 32 33 /* 34 * If the number came from make_tok_num (as a result of an %assign), it 35 * might have a '-' built into it (rather than in a preceeding token). 36 */ 37 if (*r == '-') 38 { 39 r++; 40 sign = 1; 41 } 42 43 q = r; 44 45 while (lib_isnumchar(*q)) q++; /* find end of number */ 46 47 /* 48 * If it begins 0x, 0X or $, or ends in H, it's in hex. if it 49 * ends in Q, it's octal. if it ends in B, it's binary. 50 * Otherwise, it's ordinary decimal. 51 */ 52 if (*r=='0' && (r[1]=='x' || r[1]=='X')) 53 radix = 16, r += 2; 54 else if (*r=='$') 55 radix = 16, r++; 56 else if (q[-1]=='H' || q[-1]=='h') 57 radix = 16 , q--; 58 else if (q[-1]=='Q' || q[-1]=='q' || q[-1]=='O' || q[-1]=='o') 59 radix = 8 , q--; 60 else if (q[-1]=='B' || q[-1]=='b') 61 radix = 2 , q--; 62 else 63 radix = 10; 64 65 /* 66 * If this number has been found for us by something other than 67 * the ordinary scanners, then it might be malformed by having 68 * nothing between the prefix and the suffix. Check this case 69 * now. 70 */ 71 if (r >= q) { 72 *error = TRUE; 73 return yasm_intnum_create_uint(0); 74 } 75 76 /* Check for valid number of that radix */ 77 p = r; 78 while (*p && p < q) { 79 if (*p<'0' || (*p>'9' && *p<'A') || (digit = numvalue(*p)) >= radix) 80 { 81 *error = TRUE; 82 return yasm_intnum_create_uint(0); 83 } 84 p++; 85 } 86 87 /* Use intnum to actually do the conversion */ 88 save = *q; 89 *q = '\0'; 90 switch (radix) { 91 case 2: 92 intn = yasm_intnum_create_bin(r); 93 break; 94 case 8: 95 intn = yasm_intnum_create_oct(r); 96 break; 97 case 10: 98 intn = yasm_intnum_create_dec(r); 99 break; 100 case 16: 101 intn = yasm_intnum_create_hex(r); 102 break; 103 default: 104 *error = TRUE; 105 intn = yasm_intnum_create_uint(0); 106 break; 107 } 108 *q = save; 109 110 if (sign) 111 yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL); 112 return intn; 113 } 114 115 yasm_intnum *nasm_readstrnum (char *str, size_t length, int *warn) 116 { 117 char save; 118 yasm_intnum *intn; 119 120 *warn = FALSE; 121 122 save = str[length]; 123 str[length] = '\0'; 124 intn = yasm_intnum_create_charconst_nasm(str); 125 str[length] = save; 126 127 return intn; 128 } 129 130 static char *file_name = NULL; 131 static long line_number = 0; 132 133 char *nasm_src_set_fname(char *newname) 134 { 135 char *oldname = file_name; 136 file_name = newname; 137 return oldname; 138 } 139 140 char *nasm_src_get_fname(void) 141 { 142 return file_name; 143 } 144 145 long nasm_src_set_linnum(long newline) 146 { 147 long oldline = line_number; 148 line_number = newline; 149 return oldline; 150 } 151 152 long nasm_src_get_linnum(void) 153 { 154 return line_number; 155 } 156 157 int nasm_src_get(long *xline, char **xname) 158 { 159 if (!file_name || !*xname || strcmp(*xname, file_name)) 160 { 161 nasm_free(*xname); 162 *xname = file_name ? nasm_strdup(file_name) : NULL; 163 *xline = line_number; 164 return -2; 165 } 166 if (*xline != line_number) 167 { 168 long tmp = line_number - *xline; 169 *xline = line_number; 170 return tmp; 171 } 172 return 0; 173 } 174 175 void nasm_quote(char **str) 176 { 177 size_t ln=strlen(*str); 178 char q=(*str)[0]; 179 char *p; 180 if (ln>1 && (*str)[ln-1]==q && (q=='"' || q=='\'')) 181 return; 182 q = '"'; 183 if (strchr(*str,q)) 184 q = '\''; 185 p = nasm_malloc(ln+3); 186 strcpy(p+1, *str); 187 nasm_free(*str); 188 p[ln+1] = p[0] = q; 189 p[ln+2] = 0; 190 *str = p; 191 } 192 193 char *nasm_strcat(const char *one, const char *two) 194 { 195 char *rslt; 196 size_t l1=strlen(one); 197 rslt = nasm_malloc(l1+strlen(two)+1); 198 strcpy(rslt, one); 199 strcpy(rslt+l1, two); 200 return rslt; 201 } 202