nasmlib.c 4.5 KB

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