Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

411 lines
6.7 KiB

  1. /* asmcond.c -- microsoft 80x86 assembler
  2. **
  3. ** microsoft (r) macro assembler
  4. ** copyright (c) microsoft corp 1986. all rights reserved
  5. **
  6. ** randy nevin
  7. **
  8. ** 10/90 - Quick conversion to 32 bit by Jeff Spencer
  9. */
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include "asm86.h"
  13. #include "asmfcn.h"
  14. #include "asmctype.h"
  15. static UCHAR PASCAL CODESIZE argsame(void);
  16. static char elsetable[ELSEMAX];
  17. #define F_TRUECOND 1
  18. #define F_ELSE 2
  19. /*** elsedir - processs <else>
  20. *
  21. * elsedir ();
  22. *
  23. * Entry
  24. * Exit
  25. * Returns
  26. * Calls
  27. */
  28. VOID PASCAL CODESIZE
  29. elsedir (
  30. ){
  31. if (elseflag == F_ELSE)
  32. /* ELSE already given */
  33. errorc (E_ELS);
  34. else if (condlevel == 0)
  35. /* Not in conditional block */
  36. errorc (E_NCB);
  37. else if (generate) {
  38. generate = FALSE;
  39. lastcondon--;
  40. }
  41. else if (lastcondon + 1 == condlevel && elseflag != F_TRUECOND) {
  42. generate = TRUE;
  43. lastcondon++;
  44. }
  45. elseflag = F_ELSE;
  46. }
  47. /*** endifdir - process <endif> directive
  48. *
  49. * endifdir ();
  50. *
  51. * Entry
  52. * Exit
  53. * Returns
  54. * Calls
  55. */
  56. VOID PASCAL CODESIZE
  57. endifdir (
  58. ){
  59. if (!condlevel)
  60. /* Not in conditional block */
  61. errorc (E_NCB);
  62. else {
  63. if (lastcondon == condlevel)
  64. lastcondon--;
  65. condlevel--;
  66. /* Pop back 1 cond level */
  67. /* generate if level is true */
  68. generate = (condlevel == lastcondon);
  69. if (generate && !condflag && !elseflag && !loption)
  70. fSkipList++;
  71. if (condlevel)
  72. /* Restore ELSE context */
  73. elseflag = elsetable[condlevel - 1];
  74. }
  75. }
  76. /*** argblank - check for blank <...>
  77. *
  78. * flag = argblank ();
  79. *
  80. * Entry
  81. * Exit
  82. * Returns TRUE if <...> is not blank
  83. * Calls
  84. */
  85. UCHAR PASCAL CODESIZE
  86. argblank (
  87. ){
  88. REG3 char *start;
  89. register char cc;
  90. register char *end;
  91. if ((cc = NEXTC ()) != '<')
  92. error (E_EXP,"<");
  93. start = lbufp;
  94. while (((cc = NEXTC ()) != '>') && (cc != '\0'))
  95. ;
  96. if (cc != '>') {
  97. error (E_EXP,">");
  98. return (FALSE);
  99. }
  100. if (((end = lbufp) - 1) == start)
  101. return (TRUE);
  102. lbufp = start;
  103. while ((cc = NEXTC ()) != '>')
  104. if (cc != ' ') {
  105. lbufp = end;
  106. return (FALSE);
  107. }
  108. return (TRUE);
  109. }
  110. /*** argscan - return argument of <arg>
  111. *
  112. * count = argscan (str);
  113. *
  114. * Entry str = pointer to beginning of argument string <....>
  115. * Exit none
  116. * Returns number of characters in string <....>
  117. * Calls
  118. */
  119. USHORT PASCAL CODESIZE
  120. argscan (
  121. register UCHAR *str
  122. ){
  123. register SHORT i;
  124. if (*str++ != '<') {
  125. error (E_EXP,"<");
  126. return(0);
  127. }
  128. for (i = 2; *str && *str != '>'; i++, str++) ;
  129. if (*str != '>')
  130. error (E_EXP,">");
  131. return (i);
  132. }
  133. /*** argsame - check for both arguments of <....> same
  134. *
  135. * flag = argsame ();
  136. *
  137. * Entry
  138. * Exit
  139. * Returns
  140. * Calls argscan
  141. */
  142. static UCHAR PASCAL CODESIZE
  143. argsame (
  144. ){
  145. register SHORT c1;
  146. register SHORT c2;
  147. char *p1;
  148. char *p2;
  149. p1 = lbufp;
  150. c1 = argscan (p1);
  151. lbufp += c1;
  152. skipblanks ();
  153. if (NEXTC () != ',')
  154. error (E_EXP,"comma");
  155. skipblanks ();
  156. p2 = lbufp;
  157. c2 = argscan (p2);
  158. lbufp += c2;
  159. if (c1 == c2)
  160. return( (UCHAR)(! ( (opkind & IGNORECASE)?
  161. _memicmp( p1, p2, c1 ): memcmp( p1, p2, c1 ) ) ));
  162. else
  163. return( FALSE );
  164. }
  165. /*** conddir - process <IFxxx> directives
  166. *
  167. * flag = conddir ();
  168. *
  169. * Entry
  170. * Exit
  171. * Returns
  172. * Calls
  173. * Note 1F1 True if pass 1
  174. * IF2 True if pass 2
  175. * IF <expr> True if non-zero
  176. * IFE <expr> True if zero
  177. * IFDEF <sym> True if defined
  178. * IFNDEF <sym> True if undefined
  179. * IFB <arg> True if blank
  180. * IFNB <arg> True if not blank
  181. * IFDIF <arg1>,<arg2> True if args are different
  182. * IFIDN <arg1>,<arg2> True if args are identical
  183. */
  184. VOID PASCAL CODESIZE
  185. conddir (
  186. ){
  187. register UCHAR condtrue;
  188. switch (optyp) {
  189. case TIF1:
  190. condtrue = !pass2;
  191. break;
  192. case TIF2:
  193. condtrue = pass2;
  194. break;
  195. case TIF:
  196. condtrue = (exprconst () != 0);
  197. break;
  198. case TIFE:
  199. condtrue = !exprconst ();
  200. break;
  201. case TIFDEF:
  202. case TIFNDEF:
  203. getatom ();
  204. if (condtrue = symsrch ())
  205. condtrue = M_DEFINED & symptr->attr;
  206. if (optyp == TIFNDEF)
  207. condtrue = !condtrue;
  208. break;
  209. case TIFB:
  210. condtrue = argblank ();
  211. break;
  212. case TIFNB:
  213. condtrue = !argblank ();
  214. break;
  215. case TIFIDN:
  216. case TIFDIF:
  217. condtrue = argsame ();
  218. if (optyp == TIFDIF)
  219. condtrue = !condtrue;
  220. break;
  221. }
  222. if (!(opkind & CONDCONT)) { /* not ELSEIF form */
  223. if (condlevel && condlevel <= ELSEMAX)
  224. elsetable[condlevel - 1] = elseflag;
  225. /* Another conditional */
  226. condlevel++;
  227. elseflag = FALSE;
  228. if (generate) /* If generating before this cond */
  229. if (condtrue) { /* Another true cond */
  230. lastcondon = condlevel;
  231. elseflag = F_TRUECOND;
  232. } else
  233. generate = FALSE;
  234. else
  235. /* No errors in false */
  236. errorcode = 0;
  237. } else { /* ELSEIF FORM */
  238. if (elseflag == F_ELSE)
  239. /* ELSE already given */
  240. errorc (E_ELS);
  241. else if (condlevel == 0)
  242. /* Not in conditional block */
  243. errorc (E_NCB);
  244. else if (generate) {
  245. generate = FALSE;
  246. lastcondon--;
  247. errorcode = 0;
  248. } else if (lastcondon + 1 == condlevel && condtrue
  249. && elseflag != F_TRUECOND) {
  250. generate = TRUE;
  251. lastcondon++;
  252. elseflag = F_TRUECOND;
  253. } else if (!generate)
  254. errorcode = 0;
  255. }
  256. if (errorcode == E_SND){
  257. errorcode = E_PS1&E_ERRMASK;
  258. fPass1Err++;
  259. }
  260. }
  261. /*** errdir - process <ERRxxx> directives
  262. *
  263. * errdir ();
  264. *
  265. * Entry
  266. * Exit
  267. * Returns
  268. * Calls
  269. * Note ERR Error
  270. * ERR1 Error if pass 1
  271. * ERR2 Error if pass 2
  272. * ERRE <expr> Error if zero
  273. * ERRNZ <expr> Error if non-zero
  274. * ERRDEF <sym> Error if defined
  275. * ERRNDEF <sym> Error if undefined
  276. * ERRB <arg> Error if blank
  277. * ERRNB <arg> Error if not blank
  278. * ERRDIF <arg1>,<arg2> Error if args are different
  279. * ERRIDN <arg1>,<arg2> Error if args are identical
  280. */
  281. VOID PASCAL CODESIZE
  282. errdir (
  283. ){
  284. register UCHAR errtrue;
  285. register SHORT ecode;
  286. switch (optyp) {
  287. case TERR:
  288. errtrue = TRUE;
  289. ecode = E_ERR;
  290. break;
  291. case TERR1:
  292. errtrue = !pass2;
  293. ecode = E_EP1;
  294. break;
  295. case TERR2:
  296. errtrue = pass2;
  297. ecode = E_EP2;
  298. break;
  299. case TERRE:
  300. errtrue = (exprconst () == 0 ? TRUE : FALSE);
  301. ecode = E_ERE;
  302. break;
  303. case TERRNZ:
  304. errtrue = (exprconst () == 0 ? FALSE : TRUE);
  305. ecode = E_ENZ;
  306. break;
  307. case TERRDEF:
  308. case TERRNDEF:
  309. getatom ();
  310. if (errtrue = symsrch ())
  311. errtrue = M_DEFINED & symptr->attr;
  312. if (optyp == TERRNDEF) {
  313. errtrue = !errtrue;
  314. ecode = E_END;
  315. }
  316. else
  317. ecode = E_ESD;
  318. break;
  319. case TERRB:
  320. errtrue = argblank ();
  321. ecode = E_EBL;
  322. break;
  323. case TERRNB:
  324. errtrue = !argblank ();
  325. ecode = E_ENB;
  326. break;
  327. case TERRIDN:
  328. case TERRDIF:
  329. errtrue = argsame ();
  330. if (optyp == TERRDIF) {
  331. errtrue = !errtrue;
  332. ecode = E_EDF;
  333. }
  334. else
  335. ecode = E_EID;
  336. break;
  337. }
  338. if (errorcode == E_SND){
  339. errorcode = E_PS1&E_ERRMASK;
  340. fPass1Err++;
  341. }
  342. if (errtrue)
  343. errorc (ecode);
  344. }