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
nasm_readnum(char * str,int * error)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
nasm_readstrnum(char * str,size_t length,int * warn)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
nasm_src_set_fname(char * newname)133 char *nasm_src_set_fname(char *newname)
134 {
135 char *oldname = file_name;
136 file_name = newname;
137 return oldname;
138 }
139
nasm_src_get_fname(void)140 char *nasm_src_get_fname(void)
141 {
142 return file_name;
143 }
144
nasm_src_set_linnum(long newline)145 long nasm_src_set_linnum(long newline)
146 {
147 long oldline = line_number;
148 line_number = newline;
149 return oldline;
150 }
151
nasm_src_get_linnum(void)152 long nasm_src_get_linnum(void)
153 {
154 return line_number;
155 }
156
nasm_src_get(long * xline,char ** xname)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
nasm_quote(char ** str)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
nasm_strcat(const char * one,const char * two)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