qstring: first cut at full quoted string support in the preprocessor
[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 license given in the file "LICENSE"
6  * distributed in the NASM archive.
7  */
8
9 #include "compiler.h"
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <ctype.h>
15 #include <inttypes.h>
16
17 #include "nasm.h"
18 #include "nasmlib.h"
19 #include "insns.h"
20
21 int globalbits = 0;    /* defined in nasm.h, works better here for ASM+DISASM */
22 efunc nasm_malloc_error;        /* Exported for the benefit of vsnprintf.c */
23
24 #ifdef LOGALLOC
25 static FILE *logfp;
26 #endif
27
28 void nasm_set_malloc_error(efunc error)
29 {
30     nasm_malloc_error = error;
31 #ifdef LOGALLOC
32     logfp = fopen("malloc.log", "w");
33     setvbuf(logfp, NULL, _IOLBF, BUFSIZ);
34     fprintf(logfp, "null pointer is %p\n", NULL);
35 #endif
36 }
37
38 #ifdef LOGALLOC
39 void *nasm_malloc_log(char *file, int line, size_t size)
40 #else
41 void *nasm_malloc(size_t size)
42 #endif
43 {
44     void *p = malloc(size);
45     if (!p)
46         nasm_malloc_error(ERR_FATAL | ERR_NOFILE, "out of memory");
47 #ifdef LOGALLOC
48     else
49         fprintf(logfp, "%s %d malloc(%ld) returns %p\n",
50                 file, line, (long)size, p);
51 #endif
52     return p;
53 }
54
55 #ifdef LOGALLOC
56 void *nasm_zalloc_log(char *file, int line, size_t size)
57 #else
58 void *nasm_zalloc(size_t size)
59 #endif
60 {
61     void *p = calloc(size, 1);
62     if (!p)
63         nasm_malloc_error(ERR_FATAL | ERR_NOFILE, "out of memory");
64 #ifdef LOGALLOC
65     else
66         fprintf(logfp, "%s %d calloc(%ld, 1) returns %p\n",
67                 file, line, (long)size, p);
68 #endif
69     return p;
70 }
71
72 #ifdef LOGALLOC
73 void *nasm_realloc_log(char *file, int line, void *q, size_t size)
74 #else
75 void *nasm_realloc(void *q, size_t size)
76 #endif
77 {
78     void *p = q ? realloc(q, size) : malloc(size);
79     if (!p)
80         nasm_malloc_error(ERR_FATAL | ERR_NOFILE, "out of memory");
81 #ifdef LOGALLOC
82     else if (q)
83         fprintf(logfp, "%s %d realloc(%p,%ld) returns %p\n",
84                 file, line, q, (long)size, p);
85     else
86         fprintf(logfp, "%s %d malloc(%ld) returns %p\n",
87                 file, line, (long)size, p);
88 #endif
89     return p;
90 }
91
92 #ifdef LOGALLOC
93 void nasm_free_log(char *file, int line, void *q)
94 #else
95 void nasm_free(void *q)
96 #endif
97 {
98     if (q) {
99 #ifdef LOGALLOC
100         fprintf(logfp, "%s %d free(%p)\n", file, line, q);
101 #endif
102         free(q);
103     }
104 }
105
106 #ifdef LOGALLOC
107 char *nasm_strdup_log(char *file, int line, const char *s)
108 #else
109 char *nasm_strdup(const char *s)
110 #endif
111 {
112     char *p;
113     int size = strlen(s) + 1;
114
115     p = malloc(size);
116     if (!p)
117         nasm_malloc_error(ERR_FATAL | ERR_NOFILE, "out of memory");
118 #ifdef LOGALLOC
119     else
120         fprintf(logfp, "%s %d strdup(%ld) returns %p\n",
121                 file, line, (long)size, p);
122 #endif
123     strcpy(p, s);
124     return p;
125 }
126
127 #ifdef LOGALLOC
128 char *nasm_strndup_log(char *file, int line, char *s, size_t len)
129 #else
130 char *nasm_strndup(char *s, size_t len)
131 #endif
132 {
133     char *p;
134     int size = len + 1;
135
136     p = malloc(size);
137     if (!p)
138         nasm_malloc_error(ERR_FATAL | ERR_NOFILE, "out of memory");
139 #ifdef LOGALLOC
140     else
141         fprintf(logfp, "%s %d strndup(%ld) returns %p\n",
142                 file, line, (long)size, p);
143 #endif
144     strncpy(p, s, len);
145     p[len] = '\0';
146     return p;
147 }
148
149 #ifndef nasm_stricmp
150 int nasm_stricmp(const char *s1, const char *s2)
151 {
152     while (*s1 && tolower(*s1) == tolower(*s2))
153         s1++, s2++;
154     if (!*s1 && !*s2)
155         return 0;
156     else if (tolower(*s1) < tolower(*s2))
157         return -1;
158     else
159         return 1;
160 }
161 #endif
162
163 #ifndef nasm_strnicmp
164 int nasm_strnicmp(const char *s1, const char *s2, int n)
165 {
166     while (n > 0 && *s1 && tolower(*s1) == tolower(*s2))
167         s1++, s2++, n--;
168     if ((!*s1 && !*s2) || n == 0)
169         return 0;
170     else if (tolower(*s1) < tolower(*s2))
171         return -1;
172     else
173         return 1;
174 }
175 #endif
176
177 #ifndef nasm_strsep
178 char *nasm_strsep(char **stringp, const char *delim)
179 {
180         char *s = *stringp;
181         char *e;
182
183         if (!s)
184                 return NULL;
185
186         e = strpbrk(s, delim);
187         if (e)
188                 *e++ = '\0';
189
190         *stringp = e;
191         return s;
192 }
193 #endif
194
195
196 #define lib_isnumchar(c)   (isalnum(c) || (c) == '$' || (c) == '_')
197 #define numvalue(c)  ((c)>='a' ? (c)-'a'+10 : (c)>='A' ? (c)-'A'+10 : (c)-'0')
198
199 static int radix_letter(char c)
200 {
201     switch (c) {
202     case 'b': case 'B':
203     case 'y': case 'Y':
204         return 2;               /* Binary */
205     case 'o': case 'O':
206     case 'q': case 'Q':
207         return 8;               /* Octal */
208     case 'h': case 'H':
209     case 'x': case 'X':
210         return 16;              /* Hexadecimal */
211     case 'd': case 'D':
212     case 't': case 'T':
213         return 10;              /* Decimal */
214     default:
215         return 0;               /* Not a known radix letter */
216     }
217 }
218
219 int64_t readnum(char *str, bool *error)
220 {
221     char *r = str, *q;
222     int32_t pradix, sradix, radix;
223     int plen, slen, len;
224     uint64_t result, checklimit;
225     int digit, last;
226     bool warn = false;
227     int sign = 1;
228
229     *error = false;
230
231     while (isspace(*r))
232         r++;                    /* find start of number */
233
234     /*
235      * If the number came from make_tok_num (as a result of an %assign), it
236      * might have a '-' built into it (rather than in a preceeding token).
237      */
238     if (*r == '-') {
239         r++;
240         sign = -1;
241     }
242
243     q = r;
244
245     while (lib_isnumchar(*q))
246         q++;                    /* find end of number */
247
248     len = q-r;
249     if (!len) {
250         /* Not numeric */
251         *error = true;
252         return 0;
253     }
254
255     /*
256      * Handle radix formats:
257      *
258      * 0<radix-letter><string>
259      * $<string>                (hexadecimal)
260      * <string><radix-letter>
261      */
262     pradix = sradix = 0;
263     plen = slen = 0;
264
265     if (len > 2 && *r == '0' && (pradix = radix_letter(r[1])) != 0)
266         plen = 2;
267     else if (len > 1 && *r == '$')
268         pradix = 16, plen = 1;
269
270     if (len > 1 && (sradix = radix_letter(q[-1])) != 0)
271         slen = 1;
272
273     if (pradix > sradix) {
274         radix = pradix;
275         r += plen;
276     } else if (sradix > pradix) {
277         radix = sradix;
278         q -= slen;
279     } else {
280         /* Either decimal, or invalid -- if invalid, we'll trip up
281            further down. */
282         radix = 10;
283     }
284
285     /*
286      * `checklimit' must be 2**64 / radix. We can't do that in
287      * 64-bit arithmetic, which we're (probably) using, so we
288      * cheat: since we know that all radices we use are even, we
289      * can divide 2**63 by radix/2 instead.
290      */
291     checklimit = 0x8000000000000000ULL / (radix >> 1);
292
293     /*
294      * Calculate the highest allowable value for the last digit of a
295      * 64-bit constant... in radix 10, it is 6, otherwise it is 0
296      */
297     last = (radix == 10 ? 6 : 0);
298
299     result = 0;
300     while (*r && r < q) {
301         if (*r != '_') {
302             if (*r < '0' || (*r > '9' && *r < 'A')
303                 || (digit = numvalue(*r)) >= radix) {
304                 *error = true;
305                 return 0;
306             }
307             if (result > checklimit ||
308                 (result == checklimit && digit >= last)) {
309                 warn = true;
310             }
311
312             result = radix * result + digit;
313         }
314         r++;
315     }
316
317     if (warn)
318         nasm_malloc_error(ERR_WARNING | ERR_PASS1 | ERR_WARN_NOV,
319                           "numeric constant %s does not fit in 64 bits",
320                           str);
321
322     return result * sign;
323 }
324
325 int64_t readstrnum(char *str, int length, bool *warn)
326 {
327     int64_t charconst = 0;
328     int i;
329
330     *warn = false;
331
332     str += length;
333     if (globalbits == 64) {
334         for (i = 0; i < length; i++) {
335             if (charconst & 0xFF00000000000000ULL)
336                 *warn = true;
337             charconst = (charconst << 8) + (uint8_t)*--str;
338         }
339     } else {
340         for (i = 0; i < length; i++) {
341             if (charconst & 0xFF000000UL)
342                 *warn = true;
343             charconst = (charconst << 8) + (uint8_t)*--str;
344         }
345     }
346     return charconst;
347 }
348
349 static int32_t next_seg;
350
351 void seg_init(void)
352 {
353     next_seg = 0;
354 }
355
356 int32_t seg_alloc(void)
357 {
358     return (next_seg += 2) - 2;
359 }
360
361 #if X86_MEMORY
362
363 void fwriteint16_t(uint16_t data, FILE * fp)
364 {
365     fwrite(&data, 1, 2, fp);
366 }
367
368 void fwriteint32_t(uint32_t data, FILE * fp)
369 {
370     fwrite(&data, 1, 4, fp);
371 }
372
373 void fwriteint64_t(uint64_t data, FILE * fp)
374 {
375     fwrite(&data, 1, 8, fp);
376 }
377
378 void fwriteaddr(uint64_t data, int size, FILE * fp)
379 {
380     fwrite(&data, 1, size, fp);
381 }
382
383 #else /* !X86_MEMORY */
384
385 void fwriteint16_t(uint16_t data, FILE * fp)
386 {
387     char buffer[2], *p = buffer;
388     WRITESHORT(p, data);
389     fwrite(buffer, 1, 2, fp);
390 }
391
392 void fwriteint32_t(uint32_t data, FILE * fp)
393 {
394     char buffer[4], *p = buffer;
395     WRITELONG(p, data);
396     fwrite(buffer, 1, 4, fp);
397 }
398
399 void fwriteint64_t(uint64_t data, FILE * fp)
400 {
401     char buffer[8], *p = buffer;
402     WRITEDLONG(p, data);
403     fwrite(buffer, 1, 8, fp);
404 }
405
406 void fwriteaddr(uint64_t data, int size, FILE * fp)
407 {
408     char buffer[8], *p = buffer;
409     WRITEADDR(p, data, size);
410     fwrite(buffer, 1, size, fp);
411 }
412
413 #endif
414
415 void standard_extension(char *inname, char *outname, char *extension,
416                         efunc error)
417 {
418     char *p, *q;
419
420     if (*outname)               /* file name already exists, */
421         return;                 /* so do nothing */
422     q = inname;
423     p = outname;
424     while (*q)
425         *p++ = *q++;            /* copy, and find end of string */
426     *p = '\0';                  /* terminate it */
427     while (p > outname && *--p != '.') ;        /* find final period (or whatever) */
428     if (*p != '.')
429         while (*p)
430             p++;                /* go back to end if none found */
431     if (!strcmp(p, extension)) {        /* is the extension already there? */
432         if (*extension)
433             error(ERR_WARNING | ERR_NOFILE,
434                   "file name already ends in `%s': "
435                   "output will be in `nasm.out'", extension);
436         else
437             error(ERR_WARNING | ERR_NOFILE,
438                   "file name already has no extension: "
439                   "output will be in `nasm.out'");
440         strcpy(outname, "nasm.out");
441     } else
442         strcpy(p, extension);
443 }
444
445 #define LEAFSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_LEAF))
446 #define BRANCHSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_BRANCH))
447
448 #define LAYERSHIFT(r) ( (r)->layers==0 ? RAA_BLKSHIFT : RAA_LAYERSHIFT )
449
450 static struct RAA *real_raa_init(int layers)
451 {
452     struct RAA *r;
453     int i;
454
455     if (layers == 0) {
456         r = nasm_zalloc(LEAFSIZ);
457         r->shift = 0;
458     } else {
459         r = nasm_malloc(BRANCHSIZ);
460         r->layers = layers;
461         for (i = 0; i < RAA_LAYERSIZE; i++)
462             r->u.b.data[i] = NULL;
463         r->shift = (RAA_BLKSHIFT-RAA_LAYERSHIFT) + layers*RAA_LAYERSHIFT;
464     }
465     return r;
466 }
467
468 struct RAA *raa_init(void)
469 {
470     return real_raa_init(0);
471 }
472
473 void raa_free(struct RAA *r)
474 {
475     if (r->layers) {
476         struct RAA **p;
477         for (p = r->u.b.data; p - r->u.b.data < RAA_LAYERSIZE; p++)
478             if (*p)
479                 raa_free(*p);
480     }
481     nasm_free(r);
482 }
483
484 int64_t raa_read(struct RAA *r, int32_t posn)
485 {
486     if ((uint32_t)posn >= (UINT32_C(1) << (r->shift + LAYERSHIFT(r))))
487         return 0;               /* Return 0 for undefined entries */
488     while (r->layers > 0) {
489         int32_t l = posn >> r->shift;
490         posn &= (UINT32_C(1) << r->shift)-1;
491         r = r->u.b.data[l];
492         if (!r)
493             return 0;           /* Return 0 for undefined entries */
494     }
495     return r->u.l.data[posn];
496 }
497
498 struct RAA *raa_write(struct RAA *r, int32_t posn, int64_t value)
499 {
500     struct RAA *result;
501
502     if (posn < 0)
503         nasm_malloc_error(ERR_PANIC, "negative position in raa_write");
504
505     while ((UINT32_C(1) << (r->shift+LAYERSHIFT(r))) <= (uint32_t)posn) {
506         /*
507          * Must add a layer.
508          */
509         struct RAA *s;
510         int i;
511
512         s = nasm_malloc(BRANCHSIZ);
513         for (i = 0; i < RAA_LAYERSIZE; i++)
514             s->u.b.data[i] = NULL;
515         s->layers = r->layers + 1;
516         s->shift = LAYERSHIFT(r) + r->shift;
517         s->u.b.data[0] = r;
518         r = s;
519     }
520
521     result = r;
522
523     while (r->layers > 0) {
524         struct RAA **s;
525         int32_t l = posn >> r->shift;
526         posn &= (UINT32_C(1) << r->shift)-1;
527         s = &r->u.b.data[l];
528         if (!*s)
529             *s = real_raa_init(r->layers - 1);
530         r = *s;
531     }
532
533     r->u.l.data[posn] = value;
534
535     return result;
536 }
537
538 /* Aggregate SAA components smaller than this */
539 #define SAA_BLKLEN 65536
540
541 struct SAA *saa_init(size_t elem_len)
542 {
543     struct SAA *s;
544     char *data;
545
546     s = nasm_zalloc(sizeof(struct SAA));
547
548     if (elem_len >= SAA_BLKLEN)
549         s->blk_len = elem_len;
550     else
551         s->blk_len = SAA_BLKLEN - (SAA_BLKLEN % elem_len);
552
553     s->elem_len = elem_len;
554     s->length = s->blk_len;
555     data = nasm_malloc(s->blk_len);
556     s->nblkptrs = s->nblks = 1;
557     s->blk_ptrs = nasm_malloc(sizeof(char *));
558     s->blk_ptrs[0] = data;
559     s->wblk = s->rblk = &s->blk_ptrs[0];
560
561     return s;
562 }
563
564 void saa_free(struct SAA *s)
565 {
566     char **p;
567     size_t n;
568
569     for (p = s->blk_ptrs, n = s->nblks; n; p++, n--)
570         nasm_free(*p);
571
572     nasm_free(s->blk_ptrs);
573     nasm_free(s);
574 }
575
576 /* Add one allocation block to an SAA */
577 static void saa_extend(struct SAA *s)
578 {
579     size_t blkn = s->nblks++;
580
581     if (blkn >= s->nblkptrs) {
582         size_t rindex = s->rblk - s->blk_ptrs;
583         size_t windex = s->wblk - s->blk_ptrs;
584
585         s->nblkptrs <<= 1;
586         s->blk_ptrs = nasm_realloc(s->blk_ptrs, s->nblkptrs*sizeof(char *));
587
588         s->rblk = s->blk_ptrs + rindex;
589         s->wblk = s->blk_ptrs + windex;
590     }
591
592     s->blk_ptrs[blkn] = nasm_malloc(s->blk_len);
593     s->length += s->blk_len;
594 }
595
596 void *saa_wstruct(struct SAA *s)
597 {
598     void *p;
599
600     if (s->wpos % s->elem_len)
601             nasm_malloc_error(ERR_PANIC|ERR_NOFILE,
602                               "misaligned wpos in saa_wstruct");
603
604     if (s->wpos + s->elem_len > s->blk_len) {
605         if (s->wpos != s->blk_len)
606             nasm_malloc_error(ERR_PANIC|ERR_NOFILE,
607                               "unfilled block in saa_wstruct");
608
609         if (s->wptr + s->elem_len > s->length)
610             saa_extend(s);
611         s->wblk++;
612         s->wpos = 0;
613     }
614
615     p = *s->wblk + s->wpos;
616     s->wpos += s->elem_len;
617     s->wptr += s->elem_len;
618
619     if (s->wptr > s->datalen)
620         s->datalen = s->wptr;
621
622     return p;
623 }
624
625 void saa_wbytes(struct SAA *s, const void *data, size_t len)
626 {
627     const char *d = data;
628
629     while (len) {
630         size_t l = s->blk_len - s->wpos;
631         if (l > len)
632             l = len;
633         if (l) {
634             if (d) {
635                 memcpy(*s->wblk + s->wpos, d, l);
636                 d += l;
637             } else
638                 memset(*s->wblk + s->wpos, 0, l);
639             s->wpos += l;
640             s->wptr += l;
641             len -= l;
642
643             if (s->datalen < s->wptr)
644                 s->datalen = s->wptr;
645         }
646         if (len) {
647             if (s->wptr >= s->length)
648                 saa_extend(s);
649             s->wblk++;
650             s->wpos = 0;
651         }
652     }
653 }
654
655 /* write unsigned LEB128 value to SAA */
656 void saa_wleb128u(struct SAA *psaa, int value)
657 {
658   char temp[64], *ptemp;
659   uint8_t byte;
660   int len;
661
662   ptemp = temp;
663   len = 0;
664   do
665   {
666      byte = value & 127;
667      value >>= 7;
668      if (value != 0) /* more bytes to come */
669         byte |= 0x80;
670      *ptemp = byte;
671      ptemp++;
672      len++;
673   } while (value != 0);
674   saa_wbytes(psaa, temp, len);
675 }
676
677 /* write signed LEB128 value to SAA */
678 void saa_wleb128s(struct SAA *psaa, int value)
679 {
680   char temp[64], *ptemp;
681   uint8_t byte;
682   bool more, negative;
683   int size, len;
684
685   ptemp = temp;
686   more = 1;
687   negative = (value < 0);
688   size = sizeof(int) * 8;
689   len = 0;
690   while(more)
691   {
692     byte = value & 0x7f;
693     value >>= 7;
694     if (negative)
695      /* sign extend */
696      value |= - (1 <<(size - 7));
697     /* sign bit of byte is second high order bit (0x40) */
698     if ((value == 0 && ! (byte & 0x40)) ||
699        ((value == -1) && (byte & 0x40)))
700        more = 0;
701     else
702       byte |= 0x80;
703     *ptemp = byte;
704     ptemp++;
705     len++;
706   }
707   saa_wbytes(psaa, temp, len);
708 }
709
710 void saa_rewind(struct SAA *s)
711 {
712     s->rblk = s->blk_ptrs;
713     s->rpos = s->rptr = 0;
714 }
715
716 void *saa_rstruct(struct SAA *s)
717 {
718     void *p;
719
720     if (s->rptr + s->elem_len > s->datalen)
721         return NULL;
722
723     if (s->rpos % s->elem_len)
724             nasm_malloc_error(ERR_PANIC|ERR_NOFILE,
725                               "misaligned rpos in saa_rstruct");
726
727     if (s->rpos + s->elem_len > s->blk_len) {
728         s->rblk++;
729         s->rpos = 0;
730     }
731
732     p = *s->rblk + s->rpos;
733     s->rpos += s->elem_len;
734     s->rptr += s->elem_len;
735
736     return p;
737 }
738
739 const void *saa_rbytes(struct SAA *s, size_t *lenp)
740 {
741     const void *p;
742     size_t len;
743
744     if (s->rptr >= s->datalen) {
745         *lenp = 0;
746         return NULL;
747     }
748
749     if (s->rpos >= s->blk_len) {
750         s->rblk++;
751         s->rpos = 0;
752     }
753
754     len = *lenp;
755     if (len > s->datalen - s->rptr)
756         len = s->datalen - s->rptr;
757     if (len > s->blk_len - s->rpos)
758         len = s->blk_len - s->rpos;
759
760     *lenp = len;
761     p = *s->rblk + s->rpos;
762
763     s->rpos += len;
764     s->rptr += len;
765
766     return p;
767 }
768
769 void saa_rnbytes(struct SAA *s, void *data, size_t len)
770 {
771     char *d = data;
772
773     if (s->rptr + len > s->datalen) {
774         nasm_malloc_error(ERR_PANIC|ERR_NOFILE, "overrun in saa_rnbytes");
775         return;
776     }
777
778     while (len) {
779         size_t l;
780         const void *p;
781
782         l = len;
783         p = saa_rbytes(s, &l);
784
785         memcpy(d, p, l);
786         d   += l;
787         len -= l;
788     }
789 }
790
791 /* Same as saa_rnbytes, except position the counter first */
792 void saa_fread(struct SAA *s, size_t posn, void *data, size_t len)
793 {
794     size_t ix;
795
796     if (posn+len > s->datalen) {
797         nasm_malloc_error(ERR_PANIC|ERR_NOFILE, "overrun in saa_fread");
798         return;
799     }
800
801     ix = posn / s->blk_len;
802     s->rptr = posn;
803     s->rpos = posn % s->blk_len;
804     s->rblk = &s->blk_ptrs[ix];
805
806     saa_rnbytes(s, data, len);
807 }
808
809 /* Same as saa_wbytes, except position the counter first */
810 void saa_fwrite(struct SAA *s, size_t posn, const void *data, size_t len)
811 {
812     size_t ix;
813
814     if (posn > s->datalen) {
815         /* Seek beyond the end of the existing array not supported */
816         nasm_malloc_error(ERR_PANIC|ERR_NOFILE, "overrun in saa_fwrite");
817         return;
818     }
819
820     ix = posn / s->blk_len;
821     s->wptr = posn;
822     s->wpos = posn % s->blk_len;
823     s->wblk = &s->blk_ptrs[ix];
824
825     if (!s->wpos) {
826         s->wpos = s->blk_len;
827         s->wblk--;
828     }
829
830     saa_wbytes(s, data, len);
831 }
832
833 void saa_fpwrite(struct SAA *s, FILE * fp)
834 {
835     const char *data;
836     size_t len;
837
838     saa_rewind(s);
839     while (len = s->datalen, (data = saa_rbytes(s, &len)) != NULL)
840         fwrite(data, 1, len, fp);
841 }
842
843 /*
844  * Common list of prefix names
845  */
846 static const char *prefix_names[] = {
847     "a16", "a32", "lock", "o16", "o32", "rep", "repe", "repne",
848     "repnz", "repz", "times"
849 };
850
851 const char *prefix_name(int token)
852 {
853     unsigned int prefix = token-PREFIX_ENUM_START;
854     if (prefix > elements(prefix_names))
855         return NULL;
856
857     return prefix_names[prefix];
858 }
859
860 /*
861  * Binary search.
862  */
863 int bsi(const char *string, const char **array, int size)
864 {
865     int i = -1, j = size;       /* always, i < index < j */
866     while (j - i >= 2) {
867         int k = (i + j) / 2;
868         int l = strcmp(string, array[k]);
869         if (l < 0)              /* it's in the first half */
870             j = k;
871         else if (l > 0)         /* it's in the second half */
872             i = k;
873         else                    /* we've got it :) */
874             return k;
875     }
876     return -1;                  /* we haven't got it :( */
877 }
878
879 int bsii(const char *string, const char **array, int size)
880 {
881     int i = -1, j = size;       /* always, i < index < j */
882     while (j - i >= 2) {
883         int k = (i + j) / 2;
884         int l = nasm_stricmp(string, array[k]);
885         if (l < 0)              /* it's in the first half */
886             j = k;
887         else if (l > 0)         /* it's in the second half */
888             i = k;
889         else                    /* we've got it :) */
890             return k;
891     }
892     return -1;                  /* we haven't got it :( */
893 }
894
895 static char *file_name = NULL;
896 static int32_t line_number = 0;
897
898 char *src_set_fname(char *newname)
899 {
900     char *oldname = file_name;
901     file_name = newname;
902     return oldname;
903 }
904
905 int32_t src_set_linnum(int32_t newline)
906 {
907     int32_t oldline = line_number;
908     line_number = newline;
909     return oldline;
910 }
911
912 int32_t src_get_linnum(void)
913 {
914     return line_number;
915 }
916
917 int src_get(int32_t *xline, char **xname)
918 {
919     if (!file_name || !*xname || strcmp(*xname, file_name)) {
920         nasm_free(*xname);
921         *xname = file_name ? nasm_strdup(file_name) : NULL;
922         *xline = line_number;
923         return -2;
924     }
925     if (*xline != line_number) {
926         int32_t tmp = line_number - *xline;
927         *xline = line_number;
928         return tmp;
929     }
930     return 0;
931 }
932
933 char *nasm_strcat(char *one, char *two)
934 {
935     char *rslt;
936     int l1 = strlen(one);
937     rslt = nasm_malloc(l1 + strlen(two) + 1);
938     strcpy(rslt, one);
939     strcpy(rslt + l1, two);
940     return rslt;
941 }
942
943 void null_debug_init(struct ofmt *of, void *id, FILE * fp, efunc error)
944 {
945         (void)of;
946         (void)id;
947         (void)fp;
948         (void)error;
949 }
950 void null_debug_linenum(const char *filename, int32_t linenumber, int32_t segto)
951 {
952         (void)filename;
953         (void)linenumber;
954         (void)segto;
955 }
956 void null_debug_deflabel(char *name, int32_t segment, int64_t offset,
957                          int is_global, char *special)
958 {
959         (void)name;
960         (void)segment;
961         (void)offset;
962         (void)is_global;
963         (void)special;
964 }
965 void null_debug_routine(const char *directive, const char *params)
966 {
967         (void)directive;
968         (void)params;
969 }
970 void null_debug_typevalue(int32_t type)
971 {
972         (void)type;
973 }
974 void null_debug_output(int type, void *param)
975 {
976         (void)type;
977         (void)param;
978 }
979 void null_debug_cleanup(void)
980 {
981 }
982
983 struct dfmt null_debug_form = {
984     "Null debug format",
985     "null",
986     null_debug_init,
987     null_debug_linenum,
988     null_debug_deflabel,
989     null_debug_routine,
990     null_debug_typevalue,
991     null_debug_output,
992     null_debug_cleanup
993 };
994
995 struct dfmt *null_debug_arr[2] = { &null_debug_form, NULL };