Placated unreferenced types.
[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(char *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(char *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(char *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 char *nasm_strdup_log(char *file, int line, const char *s)
90 #else
91 char *nasm_strdup(const char *s)
92 #endif
93 {
94     char *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 char *nasm_strndup_log(char *file, int line, char *s, size_t len)
111 #else
112 char *nasm_strndup(char *s, size_t len)
113 #endif
114 {
115     char *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 char *s1, const char *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 char *s1, const char *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(char *str, int *error)
163 {
164     char *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(char *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(char *inname, char *outname, char *extension,
310                         efunc error)
311 {
312     char *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 char *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     char *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     char *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     char *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     char *data;
650     int32_t len;
651
652     saa_rewind(s);
653 //    while ((data = saa_rbytes(s, &len)))
654     for (; (data = saa_rbytes(s, &len));)
655         fwrite(data, 1, len, fp);
656 }
657
658 /*
659  * Register, instruction, condition-code and prefix keywords used
660  * by the scanner.
661  */
662 #include "names.c"
663 static const char *special_names[] = {
664     "byte", "dword", "far", "long", "near", "nosplit", "qword",
665     "short", "strict", "to", "tword", "word"
666 };
667 static const char *prefix_names[] = {
668     "a16", "a32", "lock", "o16", "o32", "rep", "repe", "repne",
669     "repnz", "repz", "times"
670 };
671
672 /*
673  * Standard scanner routine used by parser.c and some output
674  * formats. It keeps a succession of temporary-storage strings in
675  * stdscan_tempstorage, which can be cleared using stdscan_reset.
676  */
677 static char **stdscan_tempstorage = NULL;
678 static int stdscan_tempsize = 0, stdscan_templen = 0;
679 #define STDSCAN_TEMP_DELTA 256
680
681 static void stdscan_pop(void)
682 {
683     nasm_free(stdscan_tempstorage[--stdscan_templen]);
684 }
685
686 void stdscan_reset(void)
687 {
688     while (stdscan_templen > 0)
689         stdscan_pop();
690 }
691
692 /*
693  * Unimportant cleanup is done to avoid confusing people who are trying
694  * to debug real memory leaks
695  */
696 void nasmlib_cleanup(void)
697 {
698     stdscan_reset();
699     nasm_free(stdscan_tempstorage);
700 }
701
702 static char *stdscan_copy(char *p, int len)
703 {
704     char *text;
705
706     text = nasm_malloc(len + 1);
707     strncpy(text, p, len);
708     text[len] = '\0';
709
710     if (stdscan_templen >= stdscan_tempsize) {
711         stdscan_tempsize += STDSCAN_TEMP_DELTA;
712         stdscan_tempstorage = nasm_realloc(stdscan_tempstorage,
713                                            stdscan_tempsize *
714                                            sizeof(char *));
715     }
716     stdscan_tempstorage[stdscan_templen++] = text;
717
718     return text;
719 }
720
721 char *stdscan_bufptr = NULL;
722 int stdscan(void *private_data, struct tokenval *tv)
723 {
724     char ourcopy[MAX_KEYWORD + 1], *r, *s;
725
726     (void)private_data;         /* Don't warn that this parameter is unused */
727
728     while (isspace(*stdscan_bufptr))
729         stdscan_bufptr++;
730     if (!*stdscan_bufptr)
731         return tv->t_type = 0;
732
733     /* we have a token; either an id, a number or a char */
734     if (isidstart(*stdscan_bufptr) ||
735         (*stdscan_bufptr == '$' && isidstart(stdscan_bufptr[1]))) {
736         /* now we've got an identifier */
737         int i;
738         int is_sym = FALSE;
739
740         if (*stdscan_bufptr == '$') {
741             is_sym = TRUE;
742             stdscan_bufptr++;
743         }
744
745         r = stdscan_bufptr++;
746         /* read the entire buffer to advance the buffer pointer but... */
747         while (isidchar(*stdscan_bufptr))
748             stdscan_bufptr++;
749
750         /* ... copy only up to IDLEN_MAX-1 characters */
751         tv->t_charptr = stdscan_copy(r, stdscan_bufptr - r < IDLEN_MAX ?
752                                      stdscan_bufptr - r : IDLEN_MAX - 1);
753
754         if (is_sym || stdscan_bufptr - r > MAX_KEYWORD)
755             return tv->t_type = TOKEN_ID;       /* bypass all other checks */
756
757         for (s = tv->t_charptr, r = ourcopy; *s; s++)
758             *r++ = tolower(*s);
759         *r = '\0';
760         /* right, so we have an identifier sitting in temp storage. now,
761          * is it actually a register or instruction name, or what? */
762         if ((tv->t_integer = bsi(ourcopy, reg_names,
763                                  elements(reg_names))) >= 0) {
764             tv->t_integer += EXPR_REG_START;
765             return tv->t_type = TOKEN_REG;
766         } else if ((tv->t_integer = bsi(ourcopy, insn_names,
767                                         elements(insn_names))) >= 0) {
768             return tv->t_type = TOKEN_INSN;
769         }
770         for (i = 0; i < elements(icn); i++)
771             if (!strncmp(ourcopy, icn[i], strlen(icn[i]))) {
772                 char *p = ourcopy + strlen(icn[i]);
773                 tv->t_integer = ico[i];
774                 if ((tv->t_inttwo = bsi(p, conditions,
775                                         elements(conditions))) >= 0)
776                     return tv->t_type = TOKEN_INSN;
777             }
778         if ((tv->t_integer = bsi(ourcopy, prefix_names,
779                                  elements(prefix_names))) >= 0) {
780             tv->t_integer += PREFIX_ENUM_START;
781             return tv->t_type = TOKEN_PREFIX;
782         }
783         if ((tv->t_integer = bsi(ourcopy, special_names,
784                                  elements(special_names))) >= 0)
785             return tv->t_type = TOKEN_SPECIAL;
786         if (!nasm_stricmp(ourcopy, "seg"))
787             return tv->t_type = TOKEN_SEG;
788         if (!nasm_stricmp(ourcopy, "wrt"))
789             return tv->t_type = TOKEN_WRT;
790         return tv->t_type = TOKEN_ID;
791     } else if (*stdscan_bufptr == '$' && !isnumchar(stdscan_bufptr[1])) {
792         /*
793          * It's a $ sign with no following hex number; this must
794          * mean it's a Here token ($), evaluating to the current
795          * assembly location, or a Base token ($$), evaluating to
796          * the base of the current segment.
797          */
798         stdscan_bufptr++;
799         if (*stdscan_bufptr == '$') {
800             stdscan_bufptr++;
801             return tv->t_type = TOKEN_BASE;
802         }
803         return tv->t_type = TOKEN_HERE;
804     } else if (isnumstart(*stdscan_bufptr)) {   /* now we've got a number */
805         int rn_error;
806
807         r = stdscan_bufptr++;
808         while (isnumchar(*stdscan_bufptr))
809             stdscan_bufptr++;
810
811         if (*stdscan_bufptr == '.') {
812             /*
813              * a floating point constant
814              */
815             stdscan_bufptr++;
816             while (isnumchar(*stdscan_bufptr) ||
817                    ((stdscan_bufptr[-1] == 'e'
818                      || stdscan_bufptr[-1] == 'E')
819                     && (*stdscan_bufptr == '-' || *stdscan_bufptr == '+'))) {
820                 stdscan_bufptr++;
821             }
822             tv->t_charptr = stdscan_copy(r, stdscan_bufptr - r);
823             return tv->t_type = TOKEN_FLOAT;
824         }
825         r = stdscan_copy(r, stdscan_bufptr - r);
826         tv->t_integer = readnum(r, &rn_error);
827         stdscan_pop();
828         if (rn_error)
829             return tv->t_type = TOKEN_ERRNUM;   /* some malformation occurred */
830         tv->t_charptr = NULL;
831         return tv->t_type = TOKEN_NUM;
832     } else if (*stdscan_bufptr == '\'' || *stdscan_bufptr == '"') {     /* a char constant */
833         char quote = *stdscan_bufptr++, *r;
834         int rn_warn;
835         r = tv->t_charptr = stdscan_bufptr;
836         while (*stdscan_bufptr && *stdscan_bufptr != quote)
837             stdscan_bufptr++;
838         tv->t_inttwo = stdscan_bufptr - r;      /* store full version */
839         if (!*stdscan_bufptr)
840             return tv->t_type = TOKEN_ERRNUM;   /* unmatched quotes */
841         stdscan_bufptr++;       /* skip over final quote */
842         tv->t_integer = readstrnum(r, tv->t_inttwo, &rn_warn);
843         /* FIXME: rn_warn is not checked! */
844         return tv->t_type = TOKEN_NUM;
845     } else if (*stdscan_bufptr == ';') {        /* a comment has happened - stay */
846         return tv->t_type = 0;
847     } else if (stdscan_bufptr[0] == '>' && stdscan_bufptr[1] == '>') {
848         stdscan_bufptr += 2;
849         return tv->t_type = TOKEN_SHR;
850     } else if (stdscan_bufptr[0] == '<' && stdscan_bufptr[1] == '<') {
851         stdscan_bufptr += 2;
852         return tv->t_type = TOKEN_SHL;
853     } else if (stdscan_bufptr[0] == '/' && stdscan_bufptr[1] == '/') {
854         stdscan_bufptr += 2;
855         return tv->t_type = TOKEN_SDIV;
856     } else if (stdscan_bufptr[0] == '%' && stdscan_bufptr[1] == '%') {
857         stdscan_bufptr += 2;
858         return tv->t_type = TOKEN_SMOD;
859     } else if (stdscan_bufptr[0] == '=' && stdscan_bufptr[1] == '=') {
860         stdscan_bufptr += 2;
861         return tv->t_type = TOKEN_EQ;
862     } else if (stdscan_bufptr[0] == '<' && stdscan_bufptr[1] == '>') {
863         stdscan_bufptr += 2;
864         return tv->t_type = TOKEN_NE;
865     } else if (stdscan_bufptr[0] == '!' && stdscan_bufptr[1] == '=') {
866         stdscan_bufptr += 2;
867         return tv->t_type = TOKEN_NE;
868     } else if (stdscan_bufptr[0] == '<' && stdscan_bufptr[1] == '=') {
869         stdscan_bufptr += 2;
870         return tv->t_type = TOKEN_LE;
871     } else if (stdscan_bufptr[0] == '>' && stdscan_bufptr[1] == '=') {
872         stdscan_bufptr += 2;
873         return tv->t_type = TOKEN_GE;
874     } else if (stdscan_bufptr[0] == '&' && stdscan_bufptr[1] == '&') {
875         stdscan_bufptr += 2;
876         return tv->t_type = TOKEN_DBL_AND;
877     } else if (stdscan_bufptr[0] == '^' && stdscan_bufptr[1] == '^') {
878         stdscan_bufptr += 2;
879         return tv->t_type = TOKEN_DBL_XOR;
880     } else if (stdscan_bufptr[0] == '|' && stdscan_bufptr[1] == '|') {
881         stdscan_bufptr += 2;
882         return tv->t_type = TOKEN_DBL_OR;
883     } else                      /* just an ordinary char */
884         return tv->t_type = (uint8_t)(*stdscan_bufptr++);
885 }
886
887 /*
888  * Return TRUE if the argument is a simple scalar. (Or a far-
889  * absolute, which counts.)
890  */
891 int is_simple(expr * vect)
892 {
893     while (vect->type && !vect->value)
894         vect++;
895     if (!vect->type)
896         return 1;
897     if (vect->type != EXPR_SIMPLE)
898         return 0;
899     do {
900         vect++;
901     } while (vect->type && !vect->value);
902     if (vect->type && vect->type < EXPR_SEGBASE + SEG_ABS)
903         return 0;
904     return 1;
905 }
906
907 /*
908  * Return TRUE if the argument is a simple scalar, _NOT_ a far-
909  * absolute.
910  */
911 int is_really_simple(expr * vect)
912 {
913     while (vect->type && !vect->value)
914         vect++;
915     if (!vect->type)
916         return 1;
917     if (vect->type != EXPR_SIMPLE)
918         return 0;
919     do {
920         vect++;
921     } while (vect->type && !vect->value);
922     if (vect->type)
923         return 0;
924     return 1;
925 }
926
927 /*
928  * Return TRUE if the argument is relocatable (i.e. a simple
929  * scalar, plus at most one segment-base, plus possibly a WRT).
930  */
931 int is_reloc(expr * vect)
932 {
933     while (vect->type && !vect->value)  /* skip initial value-0 terms */
934         vect++;
935     if (!vect->type)            /* trivially return TRUE if nothing */
936         return 1;               /* is present apart from value-0s */
937     if (vect->type < EXPR_SIMPLE)       /* FALSE if a register is present */
938         return 0;
939     if (vect->type == EXPR_SIMPLE) {    /* skip over a pure number term... */
940         do {
941             vect++;
942         } while (vect->type && !vect->value);
943         if (!vect->type)        /* ...returning TRUE if that's all */
944             return 1;
945     }
946     if (vect->type == EXPR_WRT) {       /* skip over a WRT term... */
947         do {
948             vect++;
949         } while (vect->type && !vect->value);
950         if (!vect->type)        /* ...returning TRUE if that's all */
951             return 1;
952     }
953     if (vect->value != 0 && vect->value != 1)
954         return 0;               /* segment base multiplier non-unity */
955     do {                        /* skip over _one_ seg-base term... */
956         vect++;
957     } while (vect->type && !vect->value);
958     if (!vect->type)            /* ...returning TRUE if that's all */
959         return 1;
960     return 0;                   /* And return FALSE if there's more */
961 }
962
963 /*
964  * Return TRUE if the argument contains an `unknown' part.
965  */
966 int is_unknown(expr * vect)
967 {
968     while (vect->type && vect->type < EXPR_UNKNOWN)
969         vect++;
970     return (vect->type == EXPR_UNKNOWN);
971 }
972
973 /*
974  * Return TRUE if the argument contains nothing but an `unknown'
975  * part.
976  */
977 int is_just_unknown(expr * vect)
978 {
979     while (vect->type && !vect->value)
980         vect++;
981     return (vect->type == EXPR_UNKNOWN);
982 }
983
984 /*
985  * Return the scalar part of a relocatable vector. (Including
986  * simple scalar vectors - those qualify as relocatable.)
987  */
988 int64_t reloc_value(expr * vect)
989 {
990     while (vect->type && !vect->value)
991         vect++;
992     if (!vect->type)
993         return 0;
994     if (vect->type == EXPR_SIMPLE)
995         return vect->value;
996     else
997         return 0;
998 }
999
1000 /*
1001  * Return the segment number of a relocatable vector, or NO_SEG for
1002  * simple scalars.
1003  */
1004 int32_t reloc_seg(expr * vect)
1005 {
1006     while (vect->type && (vect->type == EXPR_WRT || !vect->value))
1007         vect++;
1008     if (vect->type == EXPR_SIMPLE) {
1009         do {
1010             vect++;
1011         } while (vect->type && (vect->type == EXPR_WRT || !vect->value));
1012     }
1013     if (!vect->type)
1014         return NO_SEG;
1015     else
1016         return vect->type - EXPR_SEGBASE;
1017 }
1018
1019 /*
1020  * Return the WRT segment number of a relocatable vector, or NO_SEG
1021  * if no WRT part is present.
1022  */
1023 int32_t reloc_wrt(expr * vect)
1024 {
1025     while (vect->type && vect->type < EXPR_WRT)
1026         vect++;
1027     if (vect->type == EXPR_WRT) {
1028         return vect->value;
1029     } else
1030         return NO_SEG;
1031 }
1032
1033 /*
1034  * Binary search.
1035  */
1036 int bsi(char *string, const char **array, int size)
1037 {
1038     int i = -1, j = size;       /* always, i < index < j */
1039     while (j - i >= 2) {
1040         int k = (i + j) / 2;
1041         int l = strcmp(string, array[k]);
1042         if (l < 0)              /* it's in the first half */
1043             j = k;
1044         else if (l > 0)         /* it's in the second half */
1045             i = k;
1046         else                    /* we've got it :) */
1047             return k;
1048     }
1049     return -1;                  /* we haven't got it :( */
1050 }
1051
1052 static char *file_name = NULL;
1053 static int32_t line_number = 0;
1054
1055 char *src_set_fname(char *newname)
1056 {
1057     char *oldname = file_name;
1058     file_name = newname;
1059     return oldname;
1060 }
1061
1062 int32_t src_set_linnum(int32_t newline)
1063 {
1064     int32_t oldline = line_number;
1065     line_number = newline;
1066     return oldline;
1067 }
1068
1069 int32_t src_get_linnum(void)
1070 {
1071     return line_number;
1072 }
1073
1074 int src_get(int32_t *xline, char **xname)
1075 {
1076     if (!file_name || !*xname || strcmp(*xname, file_name)) {
1077         nasm_free(*xname);
1078         *xname = file_name ? nasm_strdup(file_name) : NULL;
1079         *xline = line_number;
1080         return -2;
1081     }
1082     if (*xline != line_number) {
1083         int32_t tmp = line_number - *xline;
1084         *xline = line_number;
1085         return tmp;
1086     }
1087     return 0;
1088 }
1089
1090 void nasm_quote(char **str)
1091 {
1092     int ln = strlen(*str);
1093     char q = (*str)[0];
1094     char *p;
1095     if (ln > 1 && (*str)[ln - 1] == q && (q == '"' || q == '\''))
1096         return;
1097     q = '"';
1098     if (strchr(*str, q))
1099         q = '\'';
1100     p = nasm_malloc(ln + 3);
1101     strcpy(p + 1, *str);
1102     nasm_free(*str);
1103     p[ln + 1] = p[0] = q;
1104     p[ln + 2] = 0;
1105     *str = p;
1106 }
1107
1108 char *nasm_strcat(char *one, char *two)
1109 {
1110     char *rslt;
1111     int l1 = strlen(one);
1112     rslt = nasm_malloc(l1 + strlen(two) + 1);
1113     strcpy(rslt, one);
1114     strcpy(rslt + l1, two);
1115     return rslt;
1116 }
1117
1118 void null_debug_init(struct ofmt *of, void *id, FILE * fp, efunc error)
1119 {
1120         (void)of;
1121         (void)id;
1122         (void)fp;
1123         (void)error;
1124 }
1125 void null_debug_linenum(const char *filename, int32_t linenumber, int32_t segto)
1126 {
1127         (void)filename;
1128         (void)linenumber;
1129         (void)segto;    
1130 }
1131 void null_debug_deflabel(char *name, int32_t segment, int32_t offset,
1132                          int is_global, char *special)
1133 {
1134         (void)name;
1135         (void)segment;
1136         (void)offset;
1137         (void)is_global;
1138         (void)special;
1139 }
1140 void null_debug_routine(const char *directive, const char *params)
1141 {
1142         (void)directive;
1143         (void)params;
1144 }
1145 void null_debug_typevalue(int32_t type)
1146 {
1147         (void)type;
1148 }
1149 void null_debug_output(int type, void *param)
1150 {
1151         (void)type;
1152         (void)param;
1153 }
1154 void null_debug_cleanup(void)
1155 {
1156 }
1157
1158 struct dfmt null_debug_form = {
1159     "Null debug format",
1160     "null",
1161     null_debug_init,
1162     null_debug_linenum,
1163     null_debug_deflabel,
1164     null_debug_routine,
1165     null_debug_typevalue,
1166     null_debug_output,
1167     null_debug_cleanup
1168 };
1169
1170 struct dfmt *null_debug_arr[2] = { &null_debug_form, NULL };