NASM 0.94
[nasm/avx512.git] / nasmlib.c
blobb2441c7bf7de39578d4a45d28bf61a5bd6a989de
1 /* nasmlib.c library routines for the Netwide Assembler
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 */
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <ctype.h>
14 #include "nasm.h"
15 #include "nasmlib.h"
17 static efunc nasm_malloc_error;
19 #ifdef LOGALLOC
20 static FILE *logfp;
21 #endif
23 void nasm_set_malloc_error (efunc error) {
24 nasm_malloc_error = error;
25 #ifdef LOGALLOC
26 logfp = fopen ("malloc.log", "w");
27 setvbuf (logfp, NULL, _IOLBF, BUFSIZ);
28 fprintf (logfp, "null pointer is %p\n", NULL);
29 #endif
32 #ifdef LOGALLOC
33 void *nasm_malloc_log (char *file, int line, size_t size)
34 #else
35 void *nasm_malloc (size_t size)
36 #endif
38 void *p = malloc(size);
39 if (!p)
40 nasm_malloc_error (ERR_FATAL | ERR_NOFILE, "out of memory");
41 #ifdef LOGALLOC
42 else
43 fprintf(logfp, "%s %d malloc(%ld) returns %p\n",
44 file, line, (long)size, p);
45 #endif
46 return p;
49 #ifdef LOGALLOC
50 void *nasm_realloc_log (char *file, int line, void *q, size_t size)
51 #else
52 void *nasm_realloc (void *q, size_t size)
53 #endif
55 void *p = q ? realloc(q, size) : malloc(size);
56 if (!p)
57 nasm_malloc_error (ERR_FATAL | ERR_NOFILE, "out of memory");
58 #ifdef LOGALLOC
59 else if (q)
60 fprintf(logfp, "%s %d realloc(%p,%ld) returns %p\n",
61 file, line, q, (long)size, p);
62 else
63 fprintf(logfp, "%s %d malloc(%ld) returns %p\n",
64 file, line, (long)size, p);
65 #endif
66 return p;
69 #ifdef LOGALLOC
70 void nasm_free_log (char *file, int line, void *q)
71 #else
72 void nasm_free (void *q)
73 #endif
75 if (q) {
76 free (q);
77 #ifdef LOGALLOC
78 fprintf(logfp, "%s %d free(%p)\n",
79 file, line, q);
80 #endif
84 #ifdef LOGALLOC
85 char *nasm_strdup_log (char *file, int line, char *s)
86 #else
87 char *nasm_strdup (char *s)
88 #endif
90 char *p;
91 int size = strlen(s)+1;
93 p = malloc(size);
94 if (!p)
95 nasm_malloc_error (ERR_FATAL | ERR_NOFILE, "out of memory");
96 #ifdef LOGALLOC
97 else
98 fprintf(logfp, "%s %d strdup(%ld) returns %p\n",
99 file, line, (long)size, p);
100 #endif
101 strcpy (p, s);
102 return p;
105 int nasm_stricmp (char *s1, char *s2) {
106 while (*s1 && toupper(*s1) == toupper(*s2))
107 s1++, s2++;
108 if (!*s1 && !*s2)
109 return 0;
110 else if (toupper(*s1) < toupper(*s2))
111 return -1;
112 else
113 return 1;
116 int nasm_strnicmp (char *s1, char *s2, int n) {
117 while (n > 0 && *s1 && toupper(*s1) == toupper(*s2))
118 s1++, s2++, n--;
119 if ((!*s1 && !*s2) || n==0)
120 return 0;
121 else if (toupper(*s1) < toupper(*s2))
122 return -1;
123 else
124 return 1;
127 #define lib_isnumchar(c) ( isalnum(c) || (c) == '$')
128 #define numvalue(c) ((c)>='a' ? (c)-'a'+10 : (c)>='A' ? (c)-'A'+10 : (c)-'0')
130 long readnum (char *str, int *error) {
131 char *r = str, *q;
132 long radix;
133 long result;
135 *error = FALSE;
137 while (isspace(*r)) r++; /* find start of number */
138 q = r;
140 while (lib_isnumchar(*q)) q++; /* find end of number */
143 * If it begins 0x, 0X or $, or ends in H, it's in hex. if it
144 * ends in Q, it's octal. if it ends in B, it's binary.
145 * Otherwise, it's ordinary decimal.
147 if (*r=='0' && (r[1]=='x' || r[1]=='X'))
148 radix = 16, r += 2;
149 else if (*r=='$')
150 radix = 16, r++;
151 else if (q[-1]=='H' || q[-1]=='h')
152 radix = 16 , q--;
153 else if (q[-1]=='Q' || q[-1]=='q')
154 radix = 8 , q--;
155 else if (q[-1]=='B' || q[-1]=='b')
156 radix = 2 , q--;
157 else
158 radix = 10;
160 result = 0;
161 while (*r && r < q) {
162 if (*r<'0' || (*r>'9' && *r<'A') || numvalue(*r)>=radix) {
163 *error = TRUE;
164 return 0;
166 result = radix * result + numvalue(*r);
167 r++;
169 return result;
172 static long next_seg;
174 void seg_init(void) {
175 next_seg = 0;
178 long seg_alloc(void) {
179 return (next_seg += 2) - 2;
182 void fwriteshort (int data, FILE *fp) {
183 fputc ((int) (data & 255), fp);
184 fputc ((int) ((data >> 8) & 255), fp);
187 void fwritelong (long data, FILE *fp) {
188 fputc ((int) (data & 255), fp);
189 fputc ((int) ((data >> 8) & 255), fp);
190 fputc ((int) ((data >> 16) & 255), fp);
191 fputc ((int) ((data >> 24) & 255), fp);
194 void standard_extension (char *inname, char *outname, char *extension,
195 efunc error) {
196 char *p, *q;
198 q = inname;
199 p = outname;
200 while (*q) *p++ = *q++; /* copy, and find end of string */
201 *p = '\0'; /* terminate it */
202 while (p > outname && *--p != '.');/* find final period (or whatever) */
203 if (*p != '.') while (*p) p++; /* go back to end if none found */
204 if (!strcmp(p, extension)) { /* is the extension already there? */
205 if (*extension)
206 error(ERR_WARNING | ERR_NOFILE,
207 "file name already ends in `%s': "
208 "output will be in `nasm.out'",
209 extension);
210 else
211 error(ERR_WARNING | ERR_NOFILE,
212 "file name already has no extension: "
213 "output will be in `nasm.out'");
214 strcpy(outname, "nasm.out");
215 } else
216 strcpy(p, extension);
219 #define RAA_BLKSIZE 4096 /* this many longs allocated at once */
220 #define RAA_LAYERSIZE 1024 /* this many _pointers_ allocated */
222 typedef struct RAA RAA;
223 typedef union RAA_UNION RAA_UNION;
224 typedef struct RAA_LEAF RAA_LEAF;
225 typedef struct RAA_BRANCH RAA_BRANCH;
227 struct RAA {
228 int layers;
229 long stepsize;
230 union RAA_UNION {
231 struct RAA_LEAF {
232 long data[RAA_BLKSIZE];
233 } l;
234 struct RAA_BRANCH {
235 struct RAA *data[RAA_LAYERSIZE];
236 } b;
237 } u;
240 #define LEAFSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_LEAF))
241 #define BRANCHSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_BRANCH))
243 #define LAYERSIZ(r) ( (r)->layers==0 ? RAA_BLKSIZE : RAA_LAYERSIZE )
245 static struct RAA *real_raa_init (int layers) {
246 struct RAA *r;
248 if (layers == 0) {
249 r = nasm_malloc (LEAFSIZ);
250 memset (r->u.l.data, 0, sizeof(r->u.l.data));
251 r->layers = 0;
252 r->stepsize = 1L;
253 } else {
254 r = nasm_malloc (BRANCHSIZ);
255 memset (r->u.b.data, 0, sizeof(r->u.b.data));
256 r->layers = layers;
257 r->stepsize = 1L;
258 while (layers--)
259 r->stepsize *= RAA_LAYERSIZE;
261 return r;
264 struct RAA *raa_init (void) {
265 return real_raa_init (0);
268 void raa_free (struct RAA *r) {
269 if (r->layers == 0)
270 nasm_free (r);
271 else {
272 struct RAA **p;
273 for (p = r->u.b.data; p - r->u.b.data < RAA_LAYERSIZE; p++)
274 if (*p)
275 raa_free (*p);
279 long raa_read (struct RAA *r, long posn) {
280 if (posn > r->stepsize * LAYERSIZ(r))
281 return 0L;
282 while (r->layers > 0) {
283 ldiv_t l;
284 l = ldiv (posn, r->stepsize);
285 r = r->u.b.data[l.quot];
286 posn = l.rem;
287 if (!r) /* better check this */
288 return 0L;
290 return r->u.l.data[posn];
293 struct RAA *raa_write (struct RAA *r, long posn, long value) {
294 struct RAA *result;
296 if (posn < 0)
297 nasm_malloc_error (ERR_PANIC, "negative position in raa_write");
299 while (r->stepsize * LAYERSIZ(r) < posn) {
301 * Must go up a layer.
303 struct RAA *s;
305 s = nasm_malloc (BRANCHSIZ);
306 memset (s->u.b.data, 0, sizeof(r->u.b.data));
307 s->layers = r->layers + 1;
308 s->stepsize = RAA_LAYERSIZE * r->stepsize;
309 s->u.b.data[0] = r;
310 r = s;
313 result = r;
315 while (r->layers > 0) {
316 ldiv_t l;
317 struct RAA **s;
318 l = ldiv (posn, r->stepsize);
319 s = &r->u.b.data[l.quot];
320 if (!*s)
321 *s = real_raa_init (r->layers - 1);
322 r = *s;
323 posn = l.rem;
326 r->u.l.data[posn] = value;
328 return result;
331 #define SAA_MAXLEN 8192
333 struct SAA {
335 * members `end' and `elem_len' are only valid in first link in
336 * list; `rptr' and `rpos' are used for reading
338 struct SAA *next, *end, *rptr;
339 long elem_len, length, posn, start, rpos;
340 char *data;
343 struct SAA *saa_init (long elem_len) {
344 struct SAA *s;
346 if (elem_len > SAA_MAXLEN)
347 nasm_malloc_error (ERR_PANIC | ERR_NOFILE, "SAA with huge elements");
349 s = nasm_malloc (sizeof(struct SAA));
350 s->posn = s->start = 0L;
351 s->elem_len = elem_len;
352 s->length = SAA_MAXLEN - (SAA_MAXLEN % elem_len);
353 s->data = nasm_malloc (s->length);
354 s->next = NULL;
355 s->end = s;
357 return s;
360 void saa_free (struct SAA *s) {
361 struct SAA *t;
363 while (s) {
364 t = s->next;
365 nasm_free (s->data);
366 nasm_free (s);
367 s = t;
371 void *saa_wstruct (struct SAA *s) {
372 void *p;
374 if (s->end->length - s->end->posn < s->elem_len) {
375 s->end->next = nasm_malloc (sizeof(struct SAA));
376 s->end->next->start = s->end->start + s->end->posn;
377 s->end = s->end->next;
378 s->end->length = s->length;
379 s->end->next = NULL;
380 s->end->posn = 0L;
381 s->end->data = nasm_malloc (s->length);
384 p = s->end->data + s->end->posn;
385 s->end->posn += s->elem_len;
386 return p;
389 void saa_wbytes (struct SAA *s, void *data, long len) {
390 char *d = data;
392 while (len > 0) {
393 long l = s->end->length - s->end->posn;
394 if (l > len)
395 l = len;
396 if (l > 0) {
397 if (d) {
398 memcpy (s->end->data + s->end->posn, d, l);
399 d += l;
400 } else
401 memset (s->end->data + s->end->posn, 0, l);
402 s->end->posn += l;
403 len -= l;
405 if (len > 0) {
406 s->end->next = nasm_malloc (sizeof(struct SAA));
407 s->end->next->start = s->end->start + s->end->posn;
408 s->end = s->end->next;
409 s->end->length = s->length;
410 s->end->next = NULL;
411 s->end->posn = 0L;
412 s->end->data = nasm_malloc (s->length);
417 void saa_rewind (struct SAA *s) {
418 s->rptr = s;
419 s->rpos = 0L;
422 void *saa_rstruct (struct SAA *s) {
423 void *p;
425 if (!s->rptr)
426 return NULL;
428 if (s->rptr->posn - s->rpos < s->elem_len) {
429 s->rptr = s->rptr->next;
430 if (!s->rptr)
431 return NULL; /* end of array */
432 s->rpos = 0L;
435 p = s->rptr->data + s->rpos;
436 s->rpos += s->elem_len;
437 return p;
440 void *saa_rbytes (struct SAA *s, long *len) {
441 void *p;
443 if (!s->rptr)
444 return NULL;
446 p = s->rptr->data + s->rpos;
447 *len = s->rptr->posn - s->rpos;
448 s->rptr = s->rptr->next;
449 s->rpos = 0L;
450 return p;
453 void saa_rnbytes (struct SAA *s, void *data, long len) {
454 char *d = data;
456 while (len > 0) {
457 long l;
459 if (!s->rptr)
460 return;
462 l = s->rptr->posn - s->rpos;
463 if (l > len)
464 l = len;
465 if (l > 0) {
466 memcpy (d, s->rptr->data + s->rpos, l);
467 d += l;
468 s->rpos += l;
469 len -= l;
471 if (len > 0) {
472 s->rptr = s->rptr->next;
473 s->rpos = 0L;
478 void saa_fread (struct SAA *s, long posn, void *data, long len) {
479 struct SAA *p;
480 long pos;
481 char *cdata = data;
483 if (!s->rptr || posn > s->rptr->start + s->rpos)
484 saa_rewind (s);
485 while (posn >= s->rptr->start + s->rptr->posn) {
486 s->rptr = s->rptr->next;
487 if (!s->rptr)
488 return; /* what else can we do?! */
491 p = s->rptr;
492 pos = posn - s->rptr->start;
493 while (len) {
494 long l = s->rptr->posn - pos;
495 if (l > len)
496 l = len;
497 memcpy (cdata, s->rptr->data+pos, l);
498 len -= l;
499 cdata += l;
500 p = p->next;
501 if (!p)
502 return;
503 pos = 0L;
507 void saa_fwrite (struct SAA *s, long posn, void *data, long len) {
508 struct SAA *p;
509 long pos;
510 char *cdata = data;
512 if (!s->rptr || posn > s->rptr->start + s->rpos)
513 saa_rewind (s);
514 while (posn >= s->rptr->start + s->rptr->posn) {
515 s->rptr = s->rptr->next;
516 if (!s->rptr)
517 return; /* what else can we do?! */
520 p = s->rptr;
521 pos = posn - s->rptr->start;
522 while (len) {
523 long l = s->rptr->posn - pos;
524 if (l > len)
525 l = len;
526 memcpy (s->rptr->data+pos, cdata, l);
527 len -= l;
528 cdata += l;
529 p = p->next;
530 if (!p)
531 return;
532 pos = 0L;
536 void saa_fpwrite (struct SAA *s, FILE *fp) {
537 char *data;
538 long len;
540 saa_rewind (s);
541 while ( (data = saa_rbytes (s, &len)) )
542 fwrite (data, 1, len, fp);