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
;
19 void nasm_set_malloc_error (efunc error
) {
20 nasm_malloc_error
= error
;
23 void *nasm_malloc (size_t size
) {
24 void *p
= malloc(size
);
26 nasm_malloc_error (ERR_FATAL
| ERR_NOFILE
, "out of memory");
30 void *nasm_realloc (void *q
, size_t size
) {
31 void *p
= q
? realloc(q
, size
) : malloc(size
);
33 nasm_malloc_error (ERR_FATAL
| ERR_NOFILE
, "out of memory");
37 void nasm_free (void *q
) {
42 char *nasm_strdup (char *s
) {
45 p
= nasm_malloc(strlen(s
)+1);
50 int nasm_stricmp (char *s1
, char *s2
) {
51 while (*s1
&& toupper(*s1
) == toupper(*s2
))
55 else if (toupper(*s1
) < toupper(*s2
))
61 int nasm_strnicmp (char *s1
, char *s2
, int n
) {
62 while (n
> 0 && *s1
&& toupper(*s1
) == toupper(*s2
))
64 if ((!*s1
&& !*s2
) || n
==0)
66 else if (toupper(*s1
) < toupper(*s2
))
72 #define isnumchar(c) ( isalnum(c) || (c) == '$')
73 #define numvalue(c) ((c)>='a' ? (c)-'a'+10 : (c)>='A' ? (c)-'A'+10 : (c)-'0')
75 long readnum (char *str
, int *error
) {
82 while (isspace(*r
)) r
++; /* find start of number */
85 while (isnumchar(*q
)) q
++; /* find end of number */
88 * If it begins 0x, 0X or $, or ends in H, it's in hex. if it
89 * ends in Q, it's octal. if it ends in B, it's binary.
90 * Otherwise, it's ordinary decimal.
92 if (*r
=='0' && (r
[1]=='x' || r
[1]=='X'))
96 else if (q
[-1]=='H' || q
[-1]=='h')
98 else if (q
[-1]=='Q' || q
[-1]=='q')
100 else if (q
[-1]=='B' || q
[-1]=='b')
106 while (*r
&& r
< q
) {
107 if (*r
<'0' || (*r
>'9' && *r
<'A') || numvalue(*r
)>=radix
) {
111 result
= radix
* result
+ numvalue(*r
);
117 static long next_seg
;
119 void seg_init(void) {
123 long seg_alloc(void) {
124 return (next_seg
+= 2) - 2;
127 void fwriteshort (int data
, FILE *fp
) {
128 fputc (data
& 255, fp
);
129 fputc ((data
>> 8) & 255, fp
);
132 void fwritelong (long data
, FILE *fp
) {
133 fputc (data
& 255, fp
);
134 fputc ((data
>> 8) & 255, fp
);
135 fputc ((data
>> 16) & 255, fp
);
136 fputc ((data
>> 24) & 255, fp
);
139 void standard_extension (char *inname
, char *outname
, char *extension
,
145 while (*q
) *p
++ = *q
++; /* copy, and find end of string */
146 *p
= '\0'; /* terminate it */
147 while (p
> outname
&& *--p
!= '.');/* find final period (or whatever) */
148 if (*p
!= '.') while (*p
) p
++; /* go back to end if none found */
149 if (!strcmp(p
, extension
)) { /* is the extension already there? */
151 error(ERR_WARNING
| ERR_NOFILE
,
152 "file name already ends in `%s': "
153 "output will be in `nasm.out'",
156 error(ERR_WARNING
| ERR_NOFILE
,
157 "file name already has no extension: "
158 "output will be in `nasm.out'");
159 strcpy(outname
, "nasm.out");
161 strcpy(p
, extension
);
164 #define RAA_BLKSIZE 4096 /* this many longs allocated at once */
165 #define RAA_LAYERSIZE 1024 /* this many _pointers_ allocated */
167 typedef struct RAA RAA
;
168 typedef union RAA_UNION RAA_UNION
;
169 typedef struct RAA_LEAF RAA_LEAF
;
170 typedef struct RAA_BRANCH RAA_BRANCH
;
177 long data
[RAA_BLKSIZE
];
180 struct RAA
*data
[RAA_LAYERSIZE
];
185 #define LEAFSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_LEAF))
186 #define BRANCHSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_BRANCH))
188 #define LAYERSIZ(r) ( (r)->layers==0 ? RAA_BLKSIZE : RAA_LAYERSIZE )
190 static struct RAA
*real_raa_init (int layers
) {
194 r
= nasm_malloc (LEAFSIZ
);
195 memset (r
->u
.l
.data
, 0, sizeof(r
->u
.l
.data
));
199 r
= nasm_malloc (BRANCHSIZ
);
200 memset (r
->u
.b
.data
, 0, sizeof(r
->u
.b
.data
));
204 r
->stepsize
*= RAA_LAYERSIZE
;
209 struct RAA
*raa_init (void) {
210 return real_raa_init (0);
213 void raa_free (struct RAA
*r
) {
218 for (p
= r
->u
.b
.data
; p
- r
->u
.b
.data
< RAA_LAYERSIZE
; p
++)
224 long raa_read (struct RAA
*r
, long posn
) {
225 if (posn
> r
->stepsize
* LAYERSIZ(r
))
227 while (r
->layers
> 0) {
229 l
= ldiv (posn
, r
->stepsize
);
230 r
= r
->u
.b
.data
[l
.quot
];
232 if (!r
) /* better check this */
235 return r
->u
.l
.data
[posn
];
238 struct RAA
*raa_write (struct RAA
*r
, long posn
, long value
) {
242 nasm_malloc_error (ERR_PANIC
, "negative position in raa_write");
244 while (r
->stepsize
* LAYERSIZ(r
) < posn
) {
246 * Must go up a layer.
250 s
= nasm_malloc (BRANCHSIZ
);
251 memset (s
->u
.b
.data
, 0, sizeof(r
->u
.b
.data
));
252 s
->layers
= r
->layers
+ 1;
253 s
->stepsize
= RAA_LAYERSIZE
* r
->stepsize
;
260 while (r
->layers
> 0) {
263 l
= ldiv (posn
, r
->stepsize
);
264 s
= &r
->u
.b
.data
[l
.quot
];
266 *s
= real_raa_init (r
->layers
- 1);
271 r
->u
.l
.data
[posn
] = value
;
276 #define SAA_MAXLEN 8192
280 * members `end' and `elem_len' are only valid in first link in
281 * list; `rptr' and `rpos' are used for reading
283 struct SAA
*next
, *end
, *rptr
;
284 long elem_len
, length
, posn
, start
, rpos
;
288 struct SAA
*saa_init (long elem_len
) {
291 if (elem_len
> SAA_MAXLEN
)
292 nasm_malloc_error (ERR_PANIC
| ERR_NOFILE
, "SAA with huge elements");
294 s
= nasm_malloc (sizeof(struct SAA
));
295 s
->posn
= s
->start
= 0L;
296 s
->elem_len
= elem_len
;
297 s
->length
= SAA_MAXLEN
- (SAA_MAXLEN
% elem_len
);
298 s
->data
= nasm_malloc (s
->length
);
305 void saa_free (struct SAA
*s
) {
316 void *saa_wstruct (struct SAA
*s
) {
319 if (s
->end
->length
- s
->end
->posn
< s
->elem_len
) {
320 s
->end
->next
= nasm_malloc (sizeof(struct SAA
));
321 s
->end
->next
->start
= s
->end
->start
+ s
->end
->posn
;
322 s
->end
= s
->end
->next
;
323 s
->end
->length
= s
->length
;
326 s
->end
->data
= nasm_malloc (s
->length
);
329 p
= s
->end
->data
+ s
->end
->posn
;
330 s
->end
->posn
+= s
->elem_len
;
334 void saa_wbytes (struct SAA
*s
, void *data
, long len
) {
338 long l
= s
->end
->length
- s
->end
->posn
;
343 memcpy (s
->end
->data
+ s
->end
->posn
, d
, l
);
346 memset (s
->end
->data
+ s
->end
->posn
, 0, l
);
351 s
->end
->next
= nasm_malloc (sizeof(struct SAA
));
352 s
->end
->next
->start
= s
->end
->start
+ s
->end
->posn
;
353 s
->end
= s
->end
->next
;
354 s
->end
->length
= s
->length
;
357 s
->end
->data
= nasm_malloc (s
->length
);
362 void saa_rewind (struct SAA
*s
) {
367 void *saa_rstruct (struct SAA
*s
) {
373 if (s
->rptr
->posn
- s
->rpos
< s
->elem_len
) {
374 s
->rptr
= s
->rptr
->next
;
376 return NULL
; /* end of array */
380 p
= s
->rptr
->data
+ s
->rpos
;
381 s
->rpos
+= s
->elem_len
;
385 void *saa_rbytes (struct SAA
*s
, long *len
) {
391 p
= s
->rptr
->data
+ s
->rpos
;
392 *len
= s
->rptr
->posn
- s
->rpos
;
393 s
->rptr
= s
->rptr
->next
;
398 void saa_rnbytes (struct SAA
*s
, void *data
, long len
) {
407 l
= s
->rptr
->posn
- s
->rpos
;
411 memcpy (d
, s
->rptr
->data
+ s
->rpos
, l
);
417 s
->rptr
= s
->rptr
->next
;
423 void saa_fread (struct SAA
*s
, long posn
, void *data
, long len
) {
428 if (!s
->rptr
|| posn
> s
->rptr
->start
+ s
->rpos
)
430 while (posn
>= s
->rptr
->start
+ s
->rptr
->posn
) {
431 s
->rptr
= s
->rptr
->next
;
433 return; /* what else can we do?! */
437 pos
= posn
- s
->rptr
->start
;
439 long l
= s
->rptr
->posn
- pos
;
442 memcpy (cdata
, s
->rptr
->data
+pos
, l
);
452 void saa_fwrite (struct SAA
*s
, long posn
, void *data
, long len
) {
457 if (!s
->rptr
|| posn
> s
->rptr
->start
+ s
->rpos
)
459 while (posn
>= s
->rptr
->start
+ s
->rptr
->posn
) {
460 s
->rptr
= s
->rptr
->next
;
462 return; /* what else can we do?! */
466 pos
= posn
- s
->rptr
->start
;
468 long l
= s
->rptr
->posn
- pos
;
471 memcpy (s
->rptr
->data
+pos
, cdata
, l
);
481 void saa_fpwrite (struct SAA
*s
, FILE *fp
) {
486 while ( (data
= saa_rbytes (s
, &len
)) )
487 fwrite (data
, 1, len
, fp
);