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
);