Home | History | Annotate | Download | only in nasm
      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