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.
17 static efunc nasm_malloc_error;
23 void nasm_set_malloc_error (efunc error) {
24 nasm_malloc_error = error;
26 logfp = fopen ("malloc.log", "w");
27 setvbuf (logfp, NULL, _IOLBF, BUFSIZ);
28 fprintf (logfp, "null pointer is %p\n", NULL);
33 void *nasm_malloc_log (char *file, int line, size_t size)
35 void *nasm_malloc (size_t size)
38 void *p = malloc(size);
40 nasm_malloc_error (ERR_FATAL | ERR_NOFILE, "out of memory");
43 fprintf(logfp, "%s %d malloc(%ld) returns %p\n",
44 file, line, (long)size, p);
50 void *nasm_realloc_log (char *file, int line, void *q, size_t size)
52 void *nasm_realloc (void *q, size_t size)
55 void *p = q ? realloc(q, size) : malloc(size);
57 nasm_malloc_error (ERR_FATAL | ERR_NOFILE, "out of memory");
60 fprintf(logfp, "%s %d realloc(%p,%ld) returns %p\n",
61 file, line, q, (long)size, p);
63 fprintf(logfp, "%s %d malloc(%ld) returns %p\n",
64 file, line, (long)size, p);
70 void nasm_free_log (char *file, int line, void *q)
72 void nasm_free (void *q)
78 fprintf(logfp, "%s %d free(%p)\n",
85 char *nasm_strdup_log (char *file, int line, char *s)
87 char *nasm_strdup (char *s)
91 int size = strlen(s)+1;
95 nasm_malloc_error (ERR_FATAL | ERR_NOFILE, "out of memory");
98 fprintf(logfp, "%s %d strdup(%ld) returns %p\n",
99 file, line, (long)size, p);
105 int nasm_stricmp (char *s1, char *s2) {
106 while (*s1 && toupper(*s1) == toupper(*s2))
110 else if (toupper(*s1) < toupper(*s2))
116 int nasm_strnicmp (char *s1, char *s2, int n) {
117 while (n > 0 && *s1 && toupper(*s1) == toupper(*s2))
119 if ((!*s1 && !*s2) || n==0)
121 else if (toupper(*s1) < toupper(*s2))
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) {
137 while (isspace(*r)) r++; /* find start of number */
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'))
151 else if (q[-1]=='H' || q[-1]=='h')
153 else if (q[-1]=='Q' || q[-1]=='q')
155 else if (q[-1]=='B' || q[-1]=='b')
161 while (*r && r < q) {
162 if (*r<'0' || (*r>'9' && *r<'A') || numvalue(*r)>=radix) {
166 result = radix * result + numvalue(*r);
172 static long next_seg;
174 void seg_init(void) {
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,
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? */
206 error(ERR_WARNING | ERR_NOFILE,
207 "file name already ends in `%s': "
208 "output will be in `nasm.out'",
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");
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;
232 long data[RAA_BLKSIZE];
235 struct RAA *data[RAA_LAYERSIZE];
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) {
249 r = nasm_malloc (LEAFSIZ);
250 memset (r->u.l.data, 0, sizeof(r->u.l.data));
254 r = nasm_malloc (BRANCHSIZ);
255 memset (r->u.b.data, 0, sizeof(r->u.b.data));
259 r->stepsize *= RAA_LAYERSIZE;
264 struct RAA *raa_init (void) {
265 return real_raa_init (0);
268 void raa_free (struct RAA *r) {
273 for (p = r->u.b.data; p - r->u.b.data < RAA_LAYERSIZE; p++)
279 long raa_read (struct RAA *r, long posn) {
280 if (posn > r->stepsize * LAYERSIZ(r))
282 while (r->layers > 0) {
284 l = ldiv (posn, r->stepsize);
285 r = r->u.b.data[l.quot];
287 if (!r) /* better check this */
290 return r->u.l.data[posn];
293 struct RAA *raa_write (struct RAA *r, long posn, long value) {
297 nasm_malloc_error (ERR_PANIC, "negative position in raa_write");
299 while (r->stepsize * LAYERSIZ(r) < posn) {
301 * Must go up a layer.
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;
315 while (r->layers > 0) {
318 l = ldiv (posn, r->stepsize);
319 s = &r->u.b.data[l.quot];
321 *s = real_raa_init (r->layers - 1);
326 r->u.l.data[posn] = value;
331 #define SAA_MAXLEN 8192
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;
343 struct SAA *saa_init (long elem_len) {
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);
360 void saa_free (struct SAA *s) {
371 void *saa_wstruct (struct SAA *s) {
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;
381 s->end->data = nasm_malloc (s->length);
384 p = s->end->data + s->end->posn;
385 s->end->posn += s->elem_len;
389 void saa_wbytes (struct SAA *s, void *data, long len) {
393 long l = s->end->length - s->end->posn;
398 memcpy (s->end->data + s->end->posn, d, l);
401 memset (s->end->data + s->end->posn, 0, l);
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;
412 s->end->data = nasm_malloc (s->length);
417 void saa_rewind (struct SAA *s) {
422 void *saa_rstruct (struct SAA *s) {
428 if (s->rptr->posn - s->rpos < s->elem_len) {
429 s->rptr = s->rptr->next;
431 return NULL; /* end of array */
435 p = s->rptr->data + s->rpos;
436 s->rpos += s->elem_len;
440 void *saa_rbytes (struct SAA *s, long *len) {
446 p = s->rptr->data + s->rpos;
447 *len = s->rptr->posn - s->rpos;
448 s->rptr = s->rptr->next;
453 void saa_rnbytes (struct SAA *s, void *data, long len) {
462 l = s->rptr->posn - s->rpos;
466 memcpy (d, s->rptr->data + s->rpos, l);
472 s->rptr = s->rptr->next;
478 void saa_fread (struct SAA *s, long posn, void *data, long len) {
483 if (!s->rptr || posn > s->rptr->start + s->rpos)
485 while (posn >= s->rptr->start + s->rptr->posn) {
486 s->rptr = s->rptr->next;
488 return; /* what else can we do?! */
492 pos = posn - s->rptr->start;
494 long l = s->rptr->posn - pos;
497 memcpy (cdata, s->rptr->data+pos, l);
507 void saa_fwrite (struct SAA *s, long posn, void *data, long len) {
512 if (!s->rptr || posn > s->rptr->start + s->rpos)
514 while (posn >= s->rptr->start + s->rptr->posn) {
515 s->rptr = s->rptr->next;
517 return; /* what else can we do?! */
521 pos = posn - s->rptr->start;
523 long l = s->rptr->posn - pos;
526 memcpy (s->rptr->data+pos, cdata, l);
536 void saa_fpwrite (struct SAA *s, FILE *fp) {
541 while ( (data = saa_rbytes (s, &len)) )
542 fwrite (data, 1, len, fp);