• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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