General push for x86-64 support, dubbed 0.99.00.
[platform/upstream/nasm.git] / nasmlib.c
1 /* nasmlib.c    library routines for the Netwide Assembler
2  *
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  */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <ctype.h>
13 #include <inttypes.h>
14
15 #include "nasm.h"
16 #include "nasmlib.h"
17 #include "insns.h"              /* For MAX_KEYWORD */
18
19 int globalbits = 0;    /* defined in nasm.h, works better here for ASM+DISASM */
20
21 static efunc nasm_malloc_error;
22
23 #ifdef LOGALLOC
24 static FILE *logfp;
25 #endif
26
27 void nasm_set_malloc_error(efunc error)
28 {
29     nasm_malloc_error = error;
30 #ifdef LOGALLOC
31     logfp = fopen("malloc.log", "w");
32     setvbuf(logfp, NULL, _IOLBF, BUFSIZ);
33     fprintf(logfp, "null pointer is %p\n", NULL);
34 #endif
35 }
36
37 #ifdef LOGALLOC
38 void *nasm_malloc_log(int8_t *file, int line, size_t size)
39 #else
40 void *nasm_malloc(size_t size)
41 #endif
42 {
43     void *p = malloc(size);
44     if (!p)
45         nasm_malloc_error(ERR_FATAL | ERR_NOFILE, "out of memory");
46 #ifdef LOGALLOC
47     else
48         fprintf(logfp, "%s %d malloc(%ld) returns %p\n",
49                 file, line, (int32_t)size, p);
50 #endif
51     return p;
52 }
53
54 #ifdef LOGALLOC
55 void *nasm_realloc_log(int8_t *file, int line, void *q, size_t size)
56 #else
57 void *nasm_realloc(void *q, size_t size)
58 #endif
59 {
60     void *p = q ? realloc(q, size) : malloc(size);
61     if (!p)
62         nasm_malloc_error(ERR_FATAL | ERR_NOFILE, "out of memory");
63 #ifdef LOGALLOC
64     else if (q)
65         fprintf(logfp, "%s %d realloc(%p,%ld) returns %p\n",
66                 file, line, q, (int32_t)size, p);
67     else
68         fprintf(logfp, "%s %d malloc(%ld) returns %p\n",
69                 file, line, (int32_t)size, p);
70 #endif
71     return p;
72 }
73
74 #ifdef LOGALLOC
75 void nasm_free_log(int8_t *file, int line, void *q)
76 #else
77 void nasm_free(void *q)
78 #endif
79 {
80     if (q) {
81         free(q);
82 #ifdef LOGALLOC
83         fprintf(logfp, "%s %d free(%p)\n", file, line, q);
84 #endif
85     }
86 }
87
88 #ifdef LOGALLOC
89 int8_t *nasm_strdup_log(int8_t *file, int line, const int8_t *s)
90 #else
91 int8_t *nasm_strdup(const int8_t *s)
92 #endif
93 {
94     int8_t *p;
95     int size = strlen(s) + 1;
96
97     p = malloc(size);
98     if (!p)
99         nasm_malloc_error(ERR_FATAL | ERR_NOFILE, "out of memory");
100 #ifdef LOGALLOC
101     else
102         fprintf(logfp, "%s %d strdup(%ld) returns %p\n",
103                 file, line, (int32_t)size, p);
104 #endif
105     strcpy(p, s);
106     return p;
107 }
108
109 #ifdef LOGALLOC
110 int8_t *nasm_strndup_log(int8_t *file, int line, int8_t *s, size_t len)
111 #else
112 int8_t *nasm_strndup(int8_t *s, size_t len)
113 #endif
114 {
115     int8_t *p;
116     int size = len + 1;
117
118     p = malloc(size);
119     if (!p)
120         nasm_malloc_error(ERR_FATAL | ERR_NOFILE, "out of memory");
121 #ifdef LOGALLOC
122     else
123         fprintf(logfp, "%s %d strndup(%ld) returns %p\n",
124                 file, line, (int32_t)size, p);
125 #endif
126     strncpy(p, s, len);
127     p[len] = '\0';
128     return p;
129 }
130
131 #if !defined(stricmp) && !defined(strcasecmp)
132 int nasm_stricmp(const int8_t *s1, const int8_t *s2)
133 {
134     while (*s1 && tolower(*s1) == tolower(*s2))
135         s1++, s2++;
136     if (!*s1 && !*s2)
137         return 0;
138     else if (tolower(*s1) < tolower(*s2))
139         return -1;
140     else
141         return 1;
142 }
143 #endif
144
145 #if !defined(strnicmp) && !defined(strncasecmp)
146 int nasm_strnicmp(const int8_t *s1, const int8_t *s2, int n)
147 {
148     while (n > 0 && *s1 && tolower(*s1) == tolower(*s2))
149         s1++, s2++, n--;
150     if ((!*s1 && !*s2) || n == 0)
151         return 0;
152     else if (tolower(*s1) < tolower(*s2))
153         return -1;
154     else
155         return 1;
156 }
157 #endif
158
159 #define lib_isnumchar(c)   ( isalnum(c) || (c) == '$')
160 #define numvalue(c)  ((c)>='a' ? (c)-'a'+10 : (c)>='A' ? (c)-'A'+10 : (c)-'0')
161
162 int64_t readnum(int8_t *str, int *error)
163 {
164     int8_t *r = str, *q;
165     int32_t radix;
166     uint64_t result, checklimit;
167     int digit, last;
168     int warn = FALSE;
169     int sign = 1;
170
171     *error = FALSE;
172
173     while (isspace(*r))
174         r++;                    /* find start of number */
175
176     /*
177      * If the number came from make_tok_num (as a result of an %assign), it
178      * might have a '-' built into it (rather than in a preceeding token).
179      */
180     if (*r == '-') {
181         r++;
182         sign = -1;
183     }
184
185     q = r;
186
187     while (lib_isnumchar(*q))
188         q++;                    /* find end of number */
189
190     /*
191      * If it begins 0x, 0X or $, or ends in H, it's in hex. if it
192      * ends in Q, it's octal. if it ends in B, it's binary.
193      * Otherwise, it's ordinary decimal.
194      */
195     if (*r == '0' && (r[1] == 'x' || r[1] == 'X'))
196         radix = 16, r += 2;
197     else if (*r == '$')
198         radix = 16, r++;
199     else if (q[-1] == 'H' || q[-1] == 'h')
200         radix = 16, q--;
201     else if (q[-1] == 'Q' || q[-1] == 'q' || q[-1] == 'O' || q[-1] == 'o')
202         radix = 8, q--;
203     else if (q[-1] == 'B' || q[-1] == 'b')
204         radix = 2, q--;
205     else
206         radix = 10;
207
208     /*
209      * If this number has been found for us by something other than
210      * the ordinary scanners, then it might be malformed by having
211      * nothing between the prefix and the suffix. Check this case
212      * now.
213      */
214     if (r >= q) {
215         *error = TRUE;
216         return 0;
217     }
218     
219     /*
220      * `checklimit' must be 2**(32|64) / radix. We can't do that in
221      * 32/64-bit arithmetic, which we're (probably) using, so we
222      * cheat: since we know that all radices we use are even, we
223      * can divide 2**(31|63) by radix/2 instead.
224      */
225     if (globalbits == 64)
226         checklimit = 0x8000000000000000ULL / (radix >> 1);
227     else
228         checklimit = 0x80000000UL / (radix >> 1);
229
230     /*
231      * Calculate the highest allowable value for the last digit of a
232      * 32-bit constant... in radix 10, it is 6, otherwise it is 0
233      */
234     last = (radix == 10 ? 6 : 0);
235
236     result = 0;
237     while (*r && r < q) {
238         if (*r < '0' || (*r > '9' && *r < 'A')
239             || (digit = numvalue(*r)) >= radix) {
240             *error = TRUE;
241             return 0;
242         }
243         if (result > checklimit || (result == checklimit && digit >= last)) {
244             warn = TRUE;
245         }
246
247         result = radix * result + digit;
248         r++;
249     }
250
251     if (warn)
252         nasm_malloc_error(ERR_WARNING | ERR_PASS1 | ERR_WARN_NOV,
253                           "numeric constant %s does not fit in 32 bits",
254                           str);
255
256     return result * sign;
257 }
258
259 int64_t readstrnum(int8_t *str, int length, int *warn)
260 {
261     int64_t charconst = 0;
262     int i;
263
264     *warn = FALSE;
265
266     str += length;
267     if (globalbits == 64) {
268         for (i = 0; i < length; i++) {
269             if (charconst & 0xFF00000000000000ULL)
270                 *warn = TRUE;
271             charconst = (charconst << 8) + (uint8_t)*--str;
272         }
273     } else {
274         for (i = 0; i < length; i++) {
275             if (charconst & 0xFF000000UL)
276                 *warn = TRUE;
277             charconst = (charconst << 8) + (uint8_t)*--str;
278         }
279     }
280     return charconst;
281 }
282
283 static int32_t next_seg;
284
285 void seg_init(void)
286 {
287     next_seg = 0;
288 }
289
290 int32_t seg_alloc(void)
291 {
292     return (next_seg += 2) - 2;
293 }
294
295 void fwriteint16_t(int data, FILE * fp)
296 {
297     fputc((int)(data & 255), fp);
298     fputc((int)((data >> 8) & 255), fp);
299 }
300
301 void fwriteint32_t(int32_t data, FILE * fp)
302 {
303     fputc((int)(data & 255), fp);
304     fputc((int)((data >> 8) & 255), fp);
305     fputc((int)((data >> 16) & 255), fp);
306     fputc((int)((data >> 24) & 255), fp);
307 }
308
309 void standard_extension(int8_t *inname, int8_t *outname, int8_t *extension,
310                         efunc error)
311 {
312     int8_t *p, *q;
313
314     if (*outname)               /* file name already exists, */
315         return;                 /* so do nothing */
316     q = inname;
317     p = outname;
318     while (*q)
319         *p++ = *q++;            /* copy, and find end of string */
320     *p = '\0';                  /* terminate it */
321     while (p > outname && *--p != '.') ;        /* find final period (or whatever) */
322     if (*p != '.')
323         while (*p)
324             p++;                /* go back to end if none found */
325     if (!strcmp(p, extension)) {        /* is the extension already there? */
326         if (*extension)
327             error(ERR_WARNING | ERR_NOFILE,
328                   "file name already ends in `%s': "
329                   "output will be in `nasm.out'", extension);
330         else
331             error(ERR_WARNING | ERR_NOFILE,
332                   "file name already has no extension: "
333                   "output will be in `nasm.out'");
334         strcpy(outname, "nasm.out");
335     } else
336         strcpy(p, extension);
337 }
338
339 #define LEAFSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_LEAF))
340 #define BRANCHSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_BRANCH))
341
342 #define LAYERSIZ(r) ( (r)->layers==0 ? RAA_BLKSIZE : RAA_LAYERSIZE )
343
344 static struct RAA *real_raa_init(int layers)
345 {
346     struct RAA *r;
347     int i;
348
349     if (layers == 0) {
350         r = nasm_malloc(LEAFSIZ);
351         r->layers = 0;
352         memset(r->u.l.data, 0, sizeof(r->u.l.data));
353         r->stepsize = 1L;
354     } else {
355         r = nasm_malloc(BRANCHSIZ);
356         r->layers = layers;
357         for (i = 0; i < RAA_LAYERSIZE; i++)
358             r->u.b.data[i] = NULL;
359         r->stepsize = RAA_BLKSIZE;
360         while (--layers)
361             r->stepsize *= RAA_LAYERSIZE;
362     }
363     return r;
364 }
365
366 struct RAA *raa_init(void)
367 {
368     return real_raa_init(0);
369 }
370
371 void raa_free(struct RAA *r)
372 {
373     if (r->layers == 0)
374         nasm_free(r);
375     else {
376         struct RAA **p;
377         for (p = r->u.b.data; p - r->u.b.data < RAA_LAYERSIZE; p++)
378             if (*p)
379                 raa_free(*p);
380     }
381 }
382
383 int32_t raa_read(struct RAA *r, int32_t posn)
384 {
385     if (posn >= r->stepsize * LAYERSIZ(r))
386         return 0;               /* Return 0 for undefined entries */
387     while (r->layers > 0) {
388         ldiv_t l;
389         l = ldiv(posn, r->stepsize);
390         r = r->u.b.data[l.quot];
391         posn = l.rem;
392         if (!r)
393             return 0;           /* Return 0 for undefined entries */
394     }
395     return r->u.l.data[posn];
396 }
397
398 struct RAA *raa_write(struct RAA *r, int32_t posn, int32_t value)
399 {
400     struct RAA *result;
401
402     if (posn < 0)
403         nasm_malloc_error(ERR_PANIC, "negative position in raa_write");
404
405     while (r->stepsize * LAYERSIZ(r) <= posn) {
406         /*
407          * Must add a layer.
408          */
409         struct RAA *s;
410         int i;
411
412         s = nasm_malloc(BRANCHSIZ);
413         for (i = 0; i < RAA_LAYERSIZE; i++)
414             s->u.b.data[i] = NULL;
415         s->layers = r->layers + 1;
416         s->stepsize = LAYERSIZ(r) * r->stepsize;
417         s->u.b.data[0] = r;
418         r = s;
419     }
420
421     result = r;
422
423     while (r->layers > 0) {
424         ldiv_t l;
425         struct RAA **s;
426         l = ldiv(posn, r->stepsize);
427         s = &r->u.b.data[l.quot];
428         if (!*s)
429             *s = real_raa_init(r->layers - 1);
430         r = *s;
431         posn = l.rem;
432     }
433
434     r->u.l.data[posn] = value;
435
436     return result;
437 }
438
439 #define SAA_MAXLEN 8192
440
441 struct SAA *saa_init(int32_t elem_len)
442 {
443     struct SAA *s;
444
445     if (elem_len > SAA_MAXLEN)
446         nasm_malloc_error(ERR_PANIC | ERR_NOFILE,
447                           "SAA with huge elements");
448
449     s = nasm_malloc(sizeof(struct SAA));
450     s->posn = s->start = 0L;
451     s->elem_len = elem_len;
452     s->length = SAA_MAXLEN - (SAA_MAXLEN % elem_len);
453     s->data = nasm_malloc(s->length);
454     s->next = NULL;
455     s->end = s;
456
457     return s;
458 }
459
460 void saa_free(struct SAA *s)
461 {
462     struct SAA *t;
463
464     while (s) {
465         t = s->next;
466         nasm_free(s->data);
467         nasm_free(s);
468         s = t;
469     }
470 }
471
472 void *saa_wstruct(struct SAA *s)
473 {
474     void *p;
475
476     if (s->end->length - s->end->posn < s->elem_len) {
477         s->end->next = nasm_malloc(sizeof(struct SAA));
478         s->end->next->start = s->end->start + s->end->posn;
479         s->end = s->end->next;
480         s->end->length = s->length;
481         s->end->next = NULL;
482         s->end->posn = 0L;
483         s->end->data = nasm_malloc(s->length);
484     }
485
486     p = s->end->data + s->end->posn;
487     s->end->posn += s->elem_len;
488     return p;
489 }
490
491 void saa_wbytes(struct SAA *s, const void *data, int32_t len)
492 {
493     const int8_t *d = data;
494
495     while (len > 0) {
496         int32_t l = s->end->length - s->end->posn;
497         if (l > len)
498             l = len;
499         if (l > 0) {
500             if (d) {
501                 memcpy(s->end->data + s->end->posn, d, l);
502                 d += l;
503             } else
504                 memset(s->end->data + s->end->posn, 0, l);
505             s->end->posn += l;
506             len -= l;
507         }
508         if (len > 0) {
509             s->end->next = nasm_malloc(sizeof(struct SAA));
510             s->end->next->start = s->end->start + s->end->posn;
511             s->end = s->end->next;
512             s->end->length = s->length;
513             s->end->next = NULL;
514             s->end->posn = 0L;
515             s->end->data = nasm_malloc(s->length);
516         }
517     }
518 }
519
520 void saa_rewind(struct SAA *s)
521 {
522     s->rptr = s;
523     s->rpos = 0L;
524 }
525
526 void *saa_rstruct(struct SAA *s)
527 {
528     void *p;
529
530     if (!s->rptr)
531         return NULL;
532
533     if (s->rptr->posn - s->rpos < s->elem_len) {
534         s->rptr = s->rptr->next;
535         if (!s->rptr)
536             return NULL;        /* end of array */
537         s->rpos = 0L;
538     }
539
540     p = s->rptr->data + s->rpos;
541     s->rpos += s->elem_len;
542     return p;
543 }
544
545 void *saa_rbytes(struct SAA *s, int32_t *len)
546 {
547     void *p;
548
549     if (!s->rptr)
550         return NULL;
551
552     p = s->rptr->data + s->rpos;
553     *len = s->rptr->posn - s->rpos;
554     s->rptr = s->rptr->next;
555     s->rpos = 0L;
556     return p;
557 }
558
559 void saa_rnbytes(struct SAA *s, void *data, int32_t len)
560 {
561     int8_t *d = data;
562
563     while (len > 0) {
564         int32_t l;
565
566         if (!s->rptr)
567             return;
568
569         l = s->rptr->posn - s->rpos;
570         if (l > len)
571             l = len;
572         if (l > 0) {
573             memcpy(d, s->rptr->data + s->rpos, l);
574             d += l;
575             s->rpos += l;
576             len -= l;
577         }
578         if (len > 0) {
579             s->rptr = s->rptr->next;
580             s->rpos = 0L;
581         }
582     }
583 }
584
585 void saa_fread(struct SAA *s, int32_t posn, void *data, int32_t len)
586 {
587     struct SAA *p;
588     int64_t pos;
589     int8_t *cdata = data;
590
591     if (!s->rptr || posn < s->rptr->start)
592         saa_rewind(s);
593     p = s->rptr;
594     while (posn >= p->start + p->posn) {
595         p = p->next;
596         if (!p)
597             return;             /* what else can we do?! */
598     }
599
600     pos = posn - p->start;
601     while (len) {
602         int64_t l = p->posn - pos;
603         if (l > len)
604             l = len;
605         memcpy(cdata, p->data + pos, l);
606         len -= l;
607         cdata += l;
608         p = p->next;
609         if (!p)
610             return;
611         pos = 0LL;
612     }
613     s->rptr = p;
614 }
615
616 void saa_fwrite(struct SAA *s, int32_t posn, void *data, int32_t len)
617 {
618     struct SAA *p;
619     int64_t pos;
620     int8_t *cdata = data;
621
622     if (!s->rptr || posn < s->rptr->start)
623         saa_rewind(s);
624     p = s->rptr;
625     while (posn >= p->start + p->posn) {
626         p = p->next;
627         if (!p)
628             return;             /* what else can we do?! */
629     }
630
631     pos = posn - p->start;
632     while (len) {
633         int64_t l = p->posn - pos;
634         if (l > len)
635             l = len;
636         memcpy(p->data + pos, cdata, l);
637         len -= l;
638         cdata += l;
639         p = p->next;
640         if (!p)
641             return;
642         pos = 0LL;
643     }
644     s->rptr = p;
645 }
646
647 void saa_fpwrite(struct SAA *s, FILE * fp)
648 {
649     int8_t *data;
650     int32_t len;
651
652     saa_rewind(s);
653     while ((data = saa_rbytes(s, &len)))
654         fwrite(data, 1, len, fp);
655 }
656
657 /*
658  * Register, instruction, condition-code and prefix keywords used
659  * by the scanner.
660  */
661 #include "names.c"
662 static const int8_t *special_names[] = {
663     "byte", "dword", "far", "long", "near", "nosplit", "qword",
664     "short", "strict", "to", "tword", "word"
665 };
666 static const int8_t *prefix_names[] = {
667     "a16", "a32", "lock", "o16", "o32", "rep", "repe", "repne",
668     "repnz", "repz", "times"
669 };
670
671 /*
672  * Standard scanner routine used by parser.c and some output
673  * formats. It keeps a succession of temporary-storage strings in
674  * stdscan_tempstorage, which can be cleared using stdscan_reset.
675  */
676 static int8_t **stdscan_tempstorage = NULL;
677 static int stdscan_tempsize = 0, stdscan_templen = 0;
678 #define STDSCAN_TEMP_DELTA 256
679
680 static void stdscan_pop(void)
681 {
682     nasm_free(stdscan_tempstorage[--stdscan_templen]);
683 }
684
685 void stdscan_reset(void)
686 {
687     while (stdscan_templen > 0)
688         stdscan_pop();
689 }
690
691 /*
692  * Unimportant cleanup is done to avoid confusing people who are trying
693  * to debug real memory leaks
694  */
695 void nasmlib_cleanup(void)
696 {
697     stdscan_reset();
698     nasm_free(stdscan_tempstorage);
699 }
700
701 static int8_t *stdscan_copy(int8_t *p, int len)
702 {
703     int8_t *text;
704
705     text = nasm_malloc(len + 1);
706     strncpy(text, p, len);
707     text[len] = '\0';
708
709     if (stdscan_templen >= stdscan_tempsize) {
710         stdscan_tempsize += STDSCAN_TEMP_DELTA;
711         stdscan_tempstorage = nasm_realloc(stdscan_tempstorage,
712                                            stdscan_tempsize *
713                                            sizeof(int8_t *));
714     }
715     stdscan_tempstorage[stdscan_templen++] = text;
716
717     return text;
718 }
719
720 int8_t *stdscan_bufptr = NULL;
721 int stdscan(void *private_data, struct tokenval *tv)
722 {
723     int8_t ourcopy[MAX_KEYWORD + 1], *r, *s;
724
725     (void)private_data;         /* Don't warn that this parameter is unused */
726
727     while (isspace(*stdscan_bufptr))
728         stdscan_bufptr++;
729     if (!*stdscan_bufptr)
730         return tv->t_type = 0;
731
732     /* we have a token; either an id, a number or a char */
733     if (isidstart(*stdscan_bufptr) ||
734         (*stdscan_bufptr == '$' && isidstart(stdscan_bufptr[1]))) {
735         /* now we've got an identifier */
736         int i;
737         int is_sym = FALSE;
738
739         if (*stdscan_bufptr == '$') {
740             is_sym = TRUE;
741             stdscan_bufptr++;
742         }
743
744         r = stdscan_bufptr++;
745         /* read the entire buffer to advance the buffer pointer but... */
746         while (isidchar(*stdscan_bufptr))
747             stdscan_bufptr++;
748
749         /* ... copy only up to IDLEN_MAX-1 characters */
750         tv->t_charptr = stdscan_copy(r, stdscan_bufptr - r < IDLEN_MAX ?
751                                      stdscan_bufptr - r : IDLEN_MAX - 1);
752
753         if (is_sym || stdscan_bufptr - r > MAX_KEYWORD)
754             return tv->t_type = TOKEN_ID;       /* bypass all other checks */
755
756         for (s = tv->t_charptr, r = ourcopy; *s; s++)
757             *r++ = tolower(*s);
758         *r = '\0';
759         /* right, so we have an identifier sitting in temp storage. now,
760          * is it actually a register or instruction name, or what? */
761         if ((tv->t_integer = bsi(ourcopy, reg_names,
762                                  elements(reg_names))) >= 0) {
763             tv->t_integer += EXPR_REG_START;
764             return tv->t_type = TOKEN_REG;
765         } else if ((tv->t_integer = bsi(ourcopy, insn_names,
766                                         elements(insn_names))) >= 0) {
767             return tv->t_type = TOKEN_INSN;
768         }
769         for (i = 0; i < elements(icn); i++)
770             if (!strncmp(ourcopy, icn[i], strlen(icn[i]))) {
771                 int8_t *p = ourcopy + strlen(icn[i]);
772                 tv->t_integer = ico[i];
773                 if ((tv->t_inttwo = bsi(p, conditions,
774                                         elements(conditions))) >= 0)
775                     return tv->t_type = TOKEN_INSN;
776             }
777         if ((tv->t_integer = bsi(ourcopy, prefix_names,
778                                  elements(prefix_names))) >= 0) {
779             tv->t_integer += PREFIX_ENUM_START;
780             return tv->t_type = TOKEN_PREFIX;
781         }
782         if ((tv->t_integer = bsi(ourcopy, special_names,
783                                  elements(special_names))) >= 0)
784             return tv->t_type = TOKEN_SPECIAL;
785         if (!nasm_stricmp(ourcopy, "seg"))
786             return tv->t_type = TOKEN_SEG;
787         if (!nasm_stricmp(ourcopy, "wrt"))
788             return tv->t_type = TOKEN_WRT;
789         return tv->t_type = TOKEN_ID;
790     } else if (*stdscan_bufptr == '$' && !isnumchar(stdscan_bufptr[1])) {
791         /*
792          * It's a $ sign with no following hex number; this must
793          * mean it's a Here token ($), evaluating to the current
794          * assembly location, or a Base token ($$), evaluating to
795          * the base of the current segment.
796          */
797         stdscan_bufptr++;
798         if (*stdscan_bufptr == '$') {
799             stdscan_bufptr++;
800             return tv->t_type = TOKEN_BASE;
801         }
802         return tv->t_type = TOKEN_HERE;
803     } else if (isnumstart(*stdscan_bufptr)) {   /* now we've got a number */
804         int rn_error;
805
806         r = stdscan_bufptr++;
807         while (isnumchar(*stdscan_bufptr))
808             stdscan_bufptr++;
809
810         if (*stdscan_bufptr == '.') {
811             /*
812              * a floating point constant
813              */
814             stdscan_bufptr++;
815             while (isnumchar(*stdscan_bufptr) ||
816                    ((stdscan_bufptr[-1] == 'e'
817                      || stdscan_bufptr[-1] == 'E')
818                     && (*stdscan_bufptr == '-' || *stdscan_bufptr == '+'))) {
819                 stdscan_bufptr++;
820             }
821             tv->t_charptr = stdscan_copy(r, stdscan_bufptr - r);
822             return tv->t_type = TOKEN_FLOAT;
823         }
824         r = stdscan_copy(r, stdscan_bufptr - r);
825         tv->t_integer = readnum(r, &rn_error);
826         stdscan_pop();
827         if (rn_error)
828             return tv->t_type = TOKEN_ERRNUM;   /* some malformation occurred */
829         tv->t_charptr = NULL;
830         return tv->t_type = TOKEN_NUM;
831     } else if (*stdscan_bufptr == '\'' || *stdscan_bufptr == '"') {     /* a char constant */
832         int8_t quote = *stdscan_bufptr++, *r;
833         int rn_warn;
834         r = tv->t_charptr = stdscan_bufptr;
835         while (*stdscan_bufptr && *stdscan_bufptr != quote)
836             stdscan_bufptr++;
837         tv->t_inttwo = stdscan_bufptr - r;      /* store full version */
838         if (!*stdscan_bufptr)
839             return tv->t_type = TOKEN_ERRNUM;   /* unmatched quotes */
840         stdscan_bufptr++;       /* skip over final quote */
841         tv->t_integer = readstrnum(r, tv->t_inttwo, &rn_warn);
842         /* FIXME: rn_warn is not checked! */
843         return tv->t_type = TOKEN_NUM;
844     } else if (*stdscan_bufptr == ';') {        /* a comment has happened - stay */
845         return tv->t_type = 0;
846     } else if (stdscan_bufptr[0] == '>' && stdscan_bufptr[1] == '>') {
847         stdscan_bufptr += 2;
848         return tv->t_type = TOKEN_SHR;
849     } else if (stdscan_bufptr[0] == '<' && stdscan_bufptr[1] == '<') {
850         stdscan_bufptr += 2;
851         return tv->t_type = TOKEN_SHL;
852     } else if (stdscan_bufptr[0] == '/' && stdscan_bufptr[1] == '/') {
853         stdscan_bufptr += 2;
854         return tv->t_type = TOKEN_SDIV;
855     } else if (stdscan_bufptr[0] == '%' && stdscan_bufptr[1] == '%') {
856         stdscan_bufptr += 2;
857         return tv->t_type = TOKEN_SMOD;
858     } else if (stdscan_bufptr[0] == '=' && stdscan_bufptr[1] == '=') {
859         stdscan_bufptr += 2;
860         return tv->t_type = TOKEN_EQ;
861     } else if (stdscan_bufptr[0] == '<' && stdscan_bufptr[1] == '>') {
862         stdscan_bufptr += 2;
863         return tv->t_type = TOKEN_NE;
864     } else if (stdscan_bufptr[0] == '!' && stdscan_bufptr[1] == '=') {
865         stdscan_bufptr += 2;
866         return tv->t_type = TOKEN_NE;
867     } else if (stdscan_bufptr[0] == '<' && stdscan_bufptr[1] == '=') {
868         stdscan_bufptr += 2;
869         return tv->t_type = TOKEN_LE;
870     } else if (stdscan_bufptr[0] == '>' && stdscan_bufptr[1] == '=') {
871         stdscan_bufptr += 2;
872         return tv->t_type = TOKEN_GE;
873     } else if (stdscan_bufptr[0] == '&' && stdscan_bufptr[1] == '&') {
874         stdscan_bufptr += 2;
875         return tv->t_type = TOKEN_DBL_AND;
876     } else if (stdscan_bufptr[0] == '^' && stdscan_bufptr[1] == '^') {
877         stdscan_bufptr += 2;
878         return tv->t_type = TOKEN_DBL_XOR;
879     } else if (stdscan_bufptr[0] == '|' && stdscan_bufptr[1] == '|') {
880         stdscan_bufptr += 2;
881         return tv->t_type = TOKEN_DBL_OR;
882     } else                      /* just an ordinary char */
883         return tv->t_type = (uint8_t)(*stdscan_bufptr++);
884 }
885
886 /*
887  * Return TRUE if the argument is a simple scalar. (Or a far-
888  * absolute, which counts.)
889  */
890 int is_simple(expr * vect)
891 {
892     while (vect->type && !vect->value)
893         vect++;
894     if (!vect->type)
895         return 1;
896     if (vect->type != EXPR_SIMPLE)
897         return 0;
898     do {
899         vect++;
900     } while (vect->type && !vect->value);
901     if (vect->type && vect->type < EXPR_SEGBASE + SEG_ABS)
902         return 0;
903     return 1;
904 }
905
906 /*
907  * Return TRUE if the argument is a simple scalar, _NOT_ a far-
908  * absolute.
909  */
910 int is_really_simple(expr * vect)
911 {
912     while (vect->type && !vect->value)
913         vect++;
914     if (!vect->type)
915         return 1;
916     if (vect->type != EXPR_SIMPLE)
917         return 0;
918     do {
919         vect++;
920     } while (vect->type && !vect->value);
921     if (vect->type)
922         return 0;
923     return 1;
924 }
925
926 /*
927  * Return TRUE if the argument is relocatable (i.e. a simple
928  * scalar, plus at most one segment-base, plus possibly a WRT).
929  */
930 int is_reloc(expr * vect)
931 {
932     while (vect->type && !vect->value)  /* skip initial value-0 terms */
933         vect++;
934     if (!vect->type)            /* trivially return TRUE if nothing */
935         return 1;               /* is present apart from value-0s */
936     if (vect->type < EXPR_SIMPLE)       /* FALSE if a register is present */
937         return 0;
938     if (vect->type == EXPR_SIMPLE) {    /* skip over a pure number term... */
939         do {
940             vect++;
941         } while (vect->type && !vect->value);
942         if (!vect->type)        /* ...returning TRUE if that's all */
943             return 1;
944     }
945     if (vect->type == EXPR_WRT) {       /* skip over a WRT term... */
946         do {
947             vect++;
948         } while (vect->type && !vect->value);
949         if (!vect->type)        /* ...returning TRUE if that's all */
950             return 1;
951     }
952     if (vect->value != 0 && vect->value != 1)
953         return 0;               /* segment base multiplier non-unity */
954     do {                        /* skip over _one_ seg-base term... */
955         vect++;
956     } while (vect->type && !vect->value);
957     if (!vect->type)            /* ...returning TRUE if that's all */
958         return 1;
959     return 0;                   /* And return FALSE if there's more */
960 }
961
962 /*
963  * Return TRUE if the argument contains an `unknown' part.
964  */
965 int is_unknown(expr * vect)
966 {
967     while (vect->type && vect->type < EXPR_UNKNOWN)
968         vect++;
969     return (vect->type == EXPR_UNKNOWN);
970 }
971
972 /*
973  * Return TRUE if the argument contains nothing but an `unknown'
974  * part.
975  */
976 int is_just_unknown(expr * vect)
977 {
978     while (vect->type && !vect->value)
979         vect++;
980     return (vect->type == EXPR_UNKNOWN);
981 }
982
983 /*
984  * Return the scalar part of a relocatable vector. (Including
985  * simple scalar vectors - those qualify as relocatable.)
986  */
987 int64_t reloc_value(expr * vect)
988 {
989     while (vect->type && !vect->value)
990         vect++;
991     if (!vect->type)
992         return 0;
993     if (vect->type == EXPR_SIMPLE)
994         return vect->value;
995     else
996         return 0;
997 }
998
999 /*
1000  * Return the segment number of a relocatable vector, or NO_SEG for
1001  * simple scalars.
1002  */
1003 int32_t reloc_seg(expr * vect)
1004 {
1005     while (vect->type && (vect->type == EXPR_WRT || !vect->value))
1006         vect++;
1007     if (vect->type == EXPR_SIMPLE) {
1008         do {
1009             vect++;
1010         } while (vect->type && (vect->type == EXPR_WRT || !vect->value));
1011     }
1012     if (!vect->type)
1013         return NO_SEG;
1014     else
1015         return vect->type - EXPR_SEGBASE;
1016 }
1017
1018 /*
1019  * Return the WRT segment number of a relocatable vector, or NO_SEG
1020  * if no WRT part is present.
1021  */
1022 int32_t reloc_wrt(expr * vect)
1023 {
1024     while (vect->type && vect->type < EXPR_WRT)
1025         vect++;
1026     if (vect->type == EXPR_WRT) {
1027         return vect->value;
1028     } else
1029         return NO_SEG;
1030 }
1031
1032 /*
1033  * Binary search.
1034  */
1035 int bsi(int8_t *string, const int8_t **array, int size)
1036 {
1037     int i = -1, j = size;       /* always, i < index < j */
1038     while (j - i >= 2) {
1039         int k = (i + j) / 2;
1040         int l = strcmp(string, array[k]);
1041         if (l < 0)              /* it's in the first half */
1042             j = k;
1043         else if (l > 0)         /* it's in the second half */
1044             i = k;
1045         else                    /* we've got it :) */
1046             return k;
1047     }
1048     return -1;                  /* we haven't got it :( */
1049 }
1050
1051 static int8_t *file_name = NULL;
1052 static int32_t line_number = 0;
1053
1054 int8_t *src_set_fname(int8_t *newname)
1055 {
1056     int8_t *oldname = file_name;
1057     file_name = newname;
1058     return oldname;
1059 }
1060
1061 int32_t src_set_linnum(int32_t newline)
1062 {
1063     int32_t oldline = line_number;
1064     line_number = newline;
1065     return oldline;
1066 }
1067
1068 int32_t src_get_linnum(void)
1069 {
1070     return line_number;
1071 }
1072
1073 int src_get(int32_t *xline, int8_t **xname)
1074 {
1075     if (!file_name || !*xname || strcmp(*xname, file_name)) {
1076         nasm_free(*xname);
1077         *xname = file_name ? nasm_strdup(file_name) : NULL;
1078         *xline = line_number;
1079         return -2;
1080     }
1081     if (*xline != line_number) {
1082         int32_t tmp = line_number - *xline;
1083         *xline = line_number;
1084         return tmp;
1085     }
1086     return 0;
1087 }
1088
1089 void nasm_quote(int8_t **str)
1090 {
1091     int ln = strlen(*str);
1092     int8_t q = (*str)[0];
1093     int8_t *p;
1094     if (ln > 1 && (*str)[ln - 1] == q && (q == '"' || q == '\''))
1095         return;
1096     q = '"';
1097     if (strchr(*str, q))
1098         q = '\'';
1099     p = nasm_malloc(ln + 3);
1100     strcpy(p + 1, *str);
1101     nasm_free(*str);
1102     p[ln + 1] = p[0] = q;
1103     p[ln + 2] = 0;
1104     *str = p;
1105 }
1106
1107 int8_t *nasm_strcat(int8_t *one, int8_t *two)
1108 {
1109     int8_t *rslt;
1110     int l1 = strlen(one);
1111     rslt = nasm_malloc(l1 + strlen(two) + 1);
1112     strcpy(rslt, one);
1113     strcpy(rslt + l1, two);
1114     return rslt;
1115 }
1116
1117 void null_debug_init(struct ofmt *of, void *id, FILE * fp, efunc error)
1118 {
1119 }
1120 void null_debug_linenum(const int8_t *filename, int32_t linenumber, int32_t segto)
1121 {
1122 }
1123 void null_debug_deflabel(int8_t *name, int32_t segment, int32_t offset,
1124                          int is_global, int8_t *special)
1125 {
1126 }
1127 void null_debug_routine(const int8_t *directive, const int8_t *params)
1128 {
1129 }
1130 void null_debug_typevalue(int32_t type)
1131 {
1132 }
1133 void null_debug_output(int type, void *param)
1134 {
1135 }
1136 void null_debug_cleanup(void)
1137 {
1138 }
1139
1140 struct dfmt null_debug_form = {
1141     "Null debug format",
1142     "null",
1143     null_debug_init,
1144     null_debug_linenum,
1145     null_debug_deflabel,
1146     null_debug_routine,
1147     null_debug_typevalue,
1148     null_debug_output,
1149     null_debug_cleanup
1150 };
1151
1152 struct dfmt *null_debug_arr[2] = { &null_debug_form, NULL };