1 #include "l.h"
2
3 static usize nhunk;
4 static usize tothunk;
5 static char* hunk;
6
7 void
diag(char * fmt,...)8 diag(char *fmt, ...)
9 {
10 char buf[STRINGSZ], *tn;
11 va_list arg;
12
13 tn = "??none??";
14 if(curtext != P && curtext->from.sym != S)
15 tn = curtext->from.sym->name;
16 va_start(arg, fmt);
17 vseprint(buf, buf+sizeof(buf), fmt, arg);
18 va_end(arg);
19 print("%s: %s\n", tn, buf);
20
21 nerrors++;
22 if(nerrors > 10) {
23 print("too many errors\n");
24 errorexit();
25 }
26 }
27
28 void
errorexit(void)29 errorexit(void)
30 {
31
32 if(nerrors) {
33 if(cout >= 0)
34 remove(outfile);
35 exits("error");
36 }
37 exits(0);
38 }
39
40 void
prasm(Prog * p)41 prasm(Prog *p)
42 {
43 print("%P\n", p);
44 }
45
46 int
Sconv(Fmt * fp)47 Sconv(Fmt *fp)
48 {
49 int i, c;
50 char str[STRINGSZ], *p, *a;
51
52 a = va_arg(fp->args, char*);
53 p = str;
54 for(i=0; i<sizeof(long); i++) {
55 c = a[i] & 0xff;
56 if(c >= 'a' && c <= 'z' ||
57 c >= 'A' && c <= 'Z' ||
58 c >= '0' && c <= '9' ||
59 c == ' ' || c == '%') {
60 *p++ = c;
61 continue;
62 }
63 *p++ = '\\';
64 switch(c) {
65 case 0:
66 *p++ = 'z';
67 continue;
68 case '\\':
69 case '"':
70 *p++ = c;
71 continue;
72 case '\n':
73 *p++ = 'n';
74 continue;
75 case '\t':
76 *p++ = 't';
77 continue;
78 }
79 *p++ = (c>>6) + '0';
80 *p++ = ((c>>3) & 7) + '0';
81 *p++ = (c & 7) + '0';
82 }
83 *p = 0;
84 return fmtstrcpy(fp, str);
85 }
86
87 void
nopstat(char * f,Count * c)88 nopstat(char *f, Count *c)
89 {
90 if(c->outof)
91 Bprint(&bso, "%s delay %ld/%ld (%.2f)\n", f,
92 c->outof - c->count, c->outof,
93 (double)(c->outof - c->count)/c->outof);
94 }
95
96 void
xdefine(char * p,int t,vlong v)97 xdefine(char *p, int t, vlong v)
98 {
99 Sym *s;
100
101 s = lookup(p, 0);
102 if(s->type == 0 || s->type == SXREF) {
103 s->type = t;
104 s->value = v;
105 }
106 }
107
108 void
undef(void)109 undef(void)
110 {
111 int i;
112 Sym *s;
113
114 for(i=0; i<NHASH; i++)
115 for(s = hash[i]; s != S; s = s->link)
116 if(s->type == SXREF)
117 diag("%s: not defined", s->name);
118 }
119
120 vlong
atolwhex(char * s)121 atolwhex(char *s)
122 {
123 vlong n;
124 int f;
125
126 n = 0;
127 f = 0;
128 while(*s == ' ' || *s == '\t')
129 s++;
130 if(*s == '-' || *s == '+') {
131 if(*s++ == '-')
132 f = 1;
133 while(*s == ' ' || *s == '\t')
134 s++;
135 }
136 if(s[0]=='0' && s[1]){
137 if(s[1]=='x' || s[1]=='X'){
138 s += 2;
139 for(;;){
140 if(*s >= '0' && *s <= '9')
141 n = n*16 + *s++ - '0';
142 else if(*s >= 'a' && *s <= 'f')
143 n = n*16 + *s++ - 'a' + 10;
144 else if(*s >= 'A' && *s <= 'F')
145 n = n*16 + *s++ - 'A' + 10;
146 else
147 break;
148 }
149 } else
150 while(*s >= '0' && *s <= '7')
151 n = n*8 + *s++ - '0';
152 } else
153 while(*s >= '0' && *s <= '9')
154 n = n*10 + *s++ - '0';
155 if(f)
156 n = -n;
157 return n;
158 }
159
160 vlong
rnd(vlong v,long r)161 rnd(vlong v, long r)
162 {
163 long c;
164
165 if(r <= 0)
166 return v;
167 v += r - 1;
168 c = v % r;
169 if(c < 0)
170 c += r;
171 v -= c;
172 return v;
173 }
174
175 Prog*
prg(void)176 prg(void)
177 {
178 Prog *p;
179
180 while(nhunk < sizeof(Prog))
181 gethunk();
182 p = (Prog*)hunk;
183 nhunk -= sizeof(Prog);
184 hunk += sizeof(Prog);
185
186 *p = zprg;
187 return p;
188 }
189
190 void*
halloc(usize n)191 halloc(usize n)
192 {
193 void *p;
194
195 n = (n+7)&~7;
196 while(nhunk < n)
197 gethunk();
198 p = hunk;
199 nhunk -= n;
200 hunk += n;
201 return p;
202 }
203
204 void
gethunk(void)205 gethunk(void)
206 {
207 char *h;
208 long nh;
209
210 nh = NHUNK;
211 if(tothunk >= 5L*NHUNK) {
212 nh = 5L*NHUNK;
213 if(tothunk >= 25L*NHUNK)
214 nh = 25L*NHUNK;
215 }
216 h = mysbrk(nh);
217 if(h == (void*)-1) {
218 diag("out of memory");
219 errorexit();
220 }
221
222 hunk = h;
223 nhunk = nh;
224 tothunk += nh;
225 }
226
227 long
hunkspace(void)228 hunkspace(void)
229 {
230 return tothunk;
231 }
232
233 void
strnput(char * s,int n)234 strnput(char *s, int n)
235 {
236 for(; *s; s++){
237 cput(*s);
238 n--;
239 }
240 for(; n > 0; n--)
241 cput(0);
242 }
243
244 void
cput(int c)245 cput(int c)
246 {
247 cbp[0] = c;
248 cbp++;
249 cbc--;
250 if(cbc <= 0)
251 cflush();
252 }
253
254 void
cflush(void)255 cflush(void)
256 {
257 int n;
258
259 n = sizeof(buf.cbuf) - cbc;
260 if(n)
261 write(cout, buf.cbuf, n);
262 cbp = buf.cbuf;
263 cbc = sizeof(buf.cbuf);
264 }
265