* tiny
[mascara-docs.git] / compilers / bcc / linux86-0.16.17 / as / macro.c
bloba858141d18b3bc1d5241f923b9c25044d16c433c
1 /* macro.c - expand macros for assembler */
3 #include "syshead.h"
4 #include "const.h"
5 #include "type.h"
6 #include "globvar.h"
7 #include "scan.h"
8 #undef EXTERN
9 #define EXTERN
10 #include "macro.h"
13 Enter macro: stack macro and get its parameters.
14 Parameters form a linked list of null-terminated strings of form
15 next:string. The first string is the macro number in 4 bytes.
18 PUBLIC void entermac(symptr)
19 struct sym_s *symptr;
21 if (maclevel >= MAXMAC)
22 error(MACOV);
23 else if (macpar + 2 > macptop)
24 error(PAROV); /* no room for 0th param */
25 /* (2 structs to fit it!) */
26 else
28 char ch;
29 struct schain_s *param1;
30 register char *reglineptr;
31 register char *stringptr;
33 ++maclevel;
34 (--macstak)->text = (char *) symptr->value_reg_or_op.value;
35 macstak->parameters = param1 = macpar;
36 param1->next = NUL_PTR;
37 *(stringptr = build_number(++macnum, 3, param1->string)) = 0;
38 macpar = (struct schain_s *) (stringptr + 1);
39 /* TODO: alignment */
40 getsym();
41 if (sym == EOLSYM)
42 return; /* no other params */
43 if (sym != LPAREN)
44 reglineptr = symname;
45 else
46 reglineptr = lineptr;
47 stringptr = macpar->string;
48 while (TRUE)
50 if (stringptr >= (char *) macptop)
52 symname = reglineptr;
53 error(PAROV);
54 return;
56 ch = *reglineptr++;
57 if (ch == '\\')
58 /* escaped means no special meaning for slash, comma, paren */
59 ch = *reglineptr++;
60 else if (ch == ',' || ch == ')' || ch == '!' || ch == ';'
61 || ch == '\n' || ch == 0)
63 if (stringptr >= (char *) macptop)
65 symname = reglineptr;
66 error(PAROV); /* no room for null */
67 return;
69 *stringptr = 0;
70 param1->next = macpar; /* ptr from previous */
71 (param1 = macpar)->next = NUL_PTR;
72 /* this goes nowhere */
73 macpar = (struct schain_s *) (stringptr + 1);
74 /* but is finished OK - TODO align */
75 stringptr = macpar->string;
76 if (ch != ',')
77 return;
78 continue;
80 if ((*stringptr++ = ch) == 0)
82 symname = reglineptr;
83 error(RPEXP);
84 return;
90 /* MACRO pseudo-op */
92 PUBLIC void pmacro()
94 bool_t saving;
95 bool_t savingc;
96 struct sym_s *symptr=0;
97 int maclen = 8;
98 int macoff = 0;
99 char * macbuf = asalloc(8);
101 saving = /* prepare for bad macro */
102 savingc = FALSE; /* normally don't save comments */
103 macload = TRUE; /* show loading */
104 if (label != NUL_PTR)
105 error(ILLAB);
106 else if (sym != IDENT)
107 error(LABEXP);
108 else
110 symptr = gsymptr;
111 if (symptr->type & MNREGBIT)
112 error(LABEXP);
113 else if (symptr->type & LABIT || symptr->data & FORBIT)
114 error(RELAB);
115 else if (pass != last_pass || symptr->type & REDBIT)
116 /* copy on pass 0, also pass 1 if redefined */
118 saving = TRUE;
119 if (symptr->type & MACBIT)
120 symptr->type |= REDBIT;
121 else
122 symptr->type |= MACBIT;
123 symptr->data = UNDBIT; /* undefined till end */
124 symptr->value_reg_or_op.value = (offset_t) macbuf;
125 getsym_nolookup(); /* test for "C" */
126 if (sym == IDENT && lineptr == symname + 1 && *symname == 'C')
127 savingc = TRUE;
130 while (TRUE)
132 skipline();
133 listline();
134 readline();
135 if (!macload)
136 break; /* macload cleared to show eof */
137 getsym_nolookup();
138 if (sym == IDENT)
140 if (lineptr == symname + 4 &&
141 ( strncmp(symname, "MEND", 4) == 0 || strncmp(symname, "mend", 4) == 0) )
143 getsym();
144 break;
147 else if (sym != MACROARG)
149 if (!savingc)
150 continue; /* don't save comment */
152 if (!saving)
153 continue;
155 char * p = strchr(linebuf, EOLCHAR);
156 int len = (p-linebuf+1);
158 if ( macoff + len > maclen-4 )
160 maclen = maclen * 2 + len;
161 macbuf = asrealloc(macbuf, maclen);
163 memcpy(macbuf+macoff, linebuf, len);
164 macoff += len;
168 macload = FALSE;
169 if (saving)
171 macbuf[macoff] = ETB;
172 symptr->value_reg_or_op.value = (offset_t) macbuf;
173 symptr->data = 0;