More consistent handling of radix letters
[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 "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         free(q);
100 #ifdef LOGALLOC
101         fprintf(logfp, "%s %d free(%p)\n", file, line, q);
102 #endif
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 radix;
223     uint64_t result, checklimit;
224     int digit, last;
225     bool warn = false;
226     int sign = 1;
227
228     *error = false;
229
230     while (isspace(*r))
231         r++;                    /* find start of number */
232
233     /*
234      * If the number came from make_tok_num (as a result of an %assign), it
235      * might have a '-' built into it (rather than in a preceeding token).
236      */
237     if (*r == '-') {
238         r++;
239         sign = -1;
240     }
241
242     q = r;
243
244     while (lib_isnumchar(*q))
245         q++;                    /* find end of number */
246
247     /*
248      * Handle radix formats:
249      *
250      * 0<radix-letter><string>
251      * $<string>                (hexadecimal)
252      * <string><radix-letter>
253      */
254     if (*r == '0' && (radix = radix_letter(r[1])))
255         r += 2;
256     else if (*r == '$')
257         radix = 16, r++;
258     else if ((radix = radix_letter(q[-1])) != 0)
259         q--;
260     else
261         radix = 10;
262
263     /*
264      * If this number has been found for us by something other than
265      * the ordinary scanners, then it might be malformed by having
266      * nothing between the prefix and the suffix. Check this case
267      * now.
268      */
269     if (r >= q) {
270         *error = true;
271         return 0;
272     }
273
274     /*
275      * `checklimit' must be 2**(32|64) / radix. We can't do that in
276      * 32/64-bit arithmetic, which we're (probably) using, so we
277      * cheat: since we know that all radices we use are even, we
278      * can divide 2**(31|63) by radix/2 instead.
279      */
280     if (globalbits == 64)
281         checklimit = 0x8000000000000000ULL / (radix >> 1);
282     else
283         checklimit = 0x80000000UL / (radix >> 1);
284
285     /*
286      * Calculate the highest allowable value for the last digit of a
287      * 32-bit constant... in radix 10, it is 6, otherwise it is 0
288      */
289     last = (radix == 10 ? 6 : 0);
290
291     result = 0;
292     while (*r && r < q) {
293         if (*r != '_') {
294             if (*r < '0' || (*r > '9' && *r < 'A')
295                 || (digit = numvalue(*r)) >= radix) {
296                 *error = true;
297                 return 0;
298             }
299             if (result > checklimit ||
300                 (result == checklimit && digit >= last)) {
301                 warn = true;
302             }
303
304             result = radix * result + digit;
305         }
306         r++;
307     }
308
309     if (warn)
310         nasm_malloc_error(ERR_WARNING | ERR_PASS1 | ERR_WARN_NOV,
311                           "numeric constant %s does not fit in 32 bits",
312                           str);
313
314     return result * sign;
315 }
316
317 int64_t readstrnum(char *str, int length, bool *warn)
318 {
319     int64_t charconst = 0;
320     int i;
321
322     *warn = false;
323
324     str += length;
325     if (globalbits == 64) {
326         for (i = 0; i < length; i++) {
327             if (charconst & 0xFF00000000000000ULL)
328                 *warn = true;
329             charconst = (charconst << 8) + (uint8_t)*--str;
330         }
331     } else {
332         for (i = 0; i < length; i++) {
333             if (charconst & 0xFF000000UL)
334                 *warn = true;
335             charconst = (charconst << 8) + (uint8_t)*--str;
336         }
337     }
338     return charconst;
339 }
340
341 static int32_t next_seg;
342
343 void seg_init(void)
344 {
345     next_seg = 0;
346 }
347
348 int32_t seg_alloc(void)
349 {
350     return (next_seg += 2) - 2;
351 }
352
353 void fwriteint16_t(int data, FILE * fp)
354 {
355     fputc((int)(data & 255), fp);
356     fputc((int)((data >> 8) & 255), fp);
357 }
358
359 void fwriteint32_t(int32_t data, FILE * fp)
360 {
361     fputc((int)(data & 255), fp);
362     fputc((int)((data >> 8) & 255), fp);
363     fputc((int)((data >> 16) & 255), fp);
364     fputc((int)((data >> 24) & 255), fp);
365 }
366
367 void fwriteint64_t(int64_t data, FILE * fp)
368 {
369     fputc((int)(data & 255), fp);
370     fputc((int)((data >> 8) & 255), fp);
371     fputc((int)((data >> 16) & 255), fp);
372     fputc((int)((data >> 24) & 255), fp);
373     fputc((int)((data >> 32) & 255), fp);
374     fputc((int)((data >> 40) & 255), fp);
375     fputc((int)((data >> 48) & 255), fp);
376     fputc((int)((data >> 56) & 255), fp);
377 }
378
379 void standard_extension(char *inname, char *outname, char *extension,
380                         efunc error)
381 {
382     char *p, *q;
383
384     if (*outname)               /* file name already exists, */
385         return;                 /* so do nothing */
386     q = inname;
387     p = outname;
388     while (*q)
389         *p++ = *q++;            /* copy, and find end of string */
390     *p = '\0';                  /* terminate it */
391     while (p > outname && *--p != '.') ;        /* find final period (or whatever) */
392     if (*p != '.')
393         while (*p)
394             p++;                /* go back to end if none found */
395     if (!strcmp(p, extension)) {        /* is the extension already there? */
396         if (*extension)
397             error(ERR_WARNING | ERR_NOFILE,
398                   "file name already ends in `%s': "
399                   "output will be in `nasm.out'", extension);
400         else
401             error(ERR_WARNING | ERR_NOFILE,
402                   "file name already has no extension: "
403                   "output will be in `nasm.out'");
404         strcpy(outname, "nasm.out");
405     } else
406         strcpy(p, extension);
407 }
408
409 #define LEAFSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_LEAF))
410 #define BRANCHSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_BRANCH))
411
412 #define LAYERSIZ(r) ( (r)->layers==0 ? RAA_BLKSIZE : RAA_LAYERSIZE )
413
414 static struct RAA *real_raa_init(int layers)
415 {
416     struct RAA *r;
417     int i;
418
419     if (layers == 0) {
420         r = nasm_zalloc(LEAFSIZ);
421         r->stepsize = 1L;
422     } else {
423         r = nasm_malloc(BRANCHSIZ);
424         r->layers = layers;
425         for (i = 0; i < RAA_LAYERSIZE; i++)
426             r->u.b.data[i] = NULL;
427         r->stepsize = RAA_BLKSIZE;
428         while (--layers)
429             r->stepsize *= RAA_LAYERSIZE;
430     }
431     return r;
432 }
433
434 struct RAA *raa_init(void)
435 {
436     return real_raa_init(0);
437 }
438
439 void raa_free(struct RAA *r)
440 {
441     if (r->layers == 0)
442         nasm_free(r);
443     else {
444         struct RAA **p;
445         for (p = r->u.b.data; p - r->u.b.data < RAA_LAYERSIZE; p++)
446             if (*p)
447                 raa_free(*p);
448     }
449 }
450
451 int32_t raa_read(struct RAA *r, int32_t posn)
452 {
453     if (posn >= r->stepsize * LAYERSIZ(r))
454         return 0;               /* Return 0 for undefined entries */
455     while (r->layers > 0) {
456         ldiv_t l;
457         l = ldiv(posn, r->stepsize);
458         r = r->u.b.data[l.quot];
459         posn = l.rem;
460         if (!r)
461             return 0;           /* Return 0 for undefined entries */
462     }
463     return r->u.l.data[posn];
464 }
465
466 struct RAA *raa_write(struct RAA *r, int32_t posn, int32_t value)
467 {
468     struct RAA *result;
469
470     if (posn < 0)
471         nasm_malloc_error(ERR_PANIC, "negative position in raa_write");
472
473     while (r->stepsize * LAYERSIZ(r) <= posn) {
474         /*
475          * Must add a layer.
476          */
477         struct RAA *s;
478         int i;
479
480         s = nasm_malloc(BRANCHSIZ);
481         for (i = 0; i < RAA_LAYERSIZE; i++)
482             s->u.b.data[i] = NULL;
483         s->layers = r->layers + 1;
484         s->stepsize = LAYERSIZ(r) * r->stepsize;
485         s->u.b.data[0] = r;
486         r = s;
487     }
488
489     result = r;
490
491     while (r->layers > 0) {
492         ldiv_t l;
493         struct RAA **s;
494         l = ldiv(posn, r->stepsize);
495         s = &r->u.b.data[l.quot];
496         if (!*s)
497             *s = real_raa_init(r->layers - 1);
498         r = *s;
499         posn = l.rem;
500     }
501
502     r->u.l.data[posn] = value;
503
504     return result;
505 }
506
507 /* Aggregate SAA components smaller than this */
508 #define SAA_BLKLEN 65536
509
510 struct SAA *saa_init(size_t elem_len)
511 {
512     struct SAA *s;
513     char *data;
514
515     s = nasm_zalloc(sizeof(struct SAA));
516
517     if (elem_len >= SAA_BLKLEN)
518         s->blk_len = elem_len;
519     else
520         s->blk_len = SAA_BLKLEN - (SAA_BLKLEN % elem_len);
521
522     s->elem_len = elem_len;
523     s->length = s->blk_len;
524     data = nasm_malloc(s->blk_len);
525     s->nblkptrs = s->nblks = 1;
526     s->blk_ptrs = nasm_malloc(sizeof(char *));
527     s->blk_ptrs[0] = data;
528     s->wblk = s->rblk = &s->blk_ptrs[0];
529
530     return s;
531 }
532
533 void saa_free(struct SAA *s)
534 {
535     char **p;
536     size_t n;
537
538     for (p = s->blk_ptrs, n = s->nblks; n; p++, n--)
539         nasm_free(*p);
540
541     nasm_free(s->blk_ptrs);
542     nasm_free(s);
543 }
544
545 /* Add one allocation block to an SAA */
546 static void saa_extend(struct SAA *s)
547 {
548     size_t blkn = s->nblks++;
549
550     if (blkn >= s->nblkptrs) {
551         size_t rindex = s->rblk - s->blk_ptrs;
552         size_t windex = s->wblk - s->blk_ptrs;
553
554         s->nblkptrs <<= 1;
555         s->blk_ptrs = nasm_realloc(s->blk_ptrs, s->nblkptrs*sizeof(char *));
556
557         s->rblk = s->blk_ptrs + rindex;
558         s->wblk = s->blk_ptrs + windex;
559     }
560
561     s->blk_ptrs[blkn] = nasm_malloc(s->blk_len);
562     s->length += s->blk_len;
563 }
564
565 void *saa_wstruct(struct SAA *s)
566 {
567     void *p;
568
569     if (s->wpos % s->elem_len)
570             nasm_malloc_error(ERR_PANIC|ERR_NOFILE,
571                               "misaligned wpos in saa_wstruct");
572
573     if (s->wpos + s->elem_len > s->blk_len) {
574         if (s->wpos != s->blk_len)
575             nasm_malloc_error(ERR_PANIC|ERR_NOFILE,
576                               "unfilled block in saa_wstruct");
577
578         if (s->wptr + s->elem_len > s->length)
579             saa_extend(s);
580         s->wblk++;
581         s->wpos = 0;
582     }
583
584     p = *s->wblk + s->wpos;
585     s->wpos += s->elem_len;
586     s->wptr += s->elem_len;
587
588     if (s->wptr > s->datalen)
589         s->datalen = s->wptr;
590
591     return p;
592 }
593
594 void saa_wbytes(struct SAA *s, const void *data, size_t len)
595 {
596     const char *d = data;
597
598     while (len) {
599         size_t l = s->blk_len - s->wpos;
600         if (l > len)
601             l = len;
602         if (l) {
603             if (d) {
604                 memcpy(*s->wblk + s->wpos, d, l);
605                 d += l;
606             } else
607                 memset(*s->wblk + s->wpos, 0, l);
608             s->wpos += l;
609             s->wptr += l;
610             len -= l;
611
612             if (s->datalen < s->wptr)
613                 s->datalen = s->wptr;
614         }
615         if (len) {
616             if (s->wptr >= s->length)
617                 saa_extend(s);
618             s->wblk++;
619             s->wpos = 0;
620         }
621     }
622 }
623
624 void saa_rewind(struct SAA *s)
625 {
626     s->rblk = s->blk_ptrs;
627     s->rpos = s->rptr = 0;
628 }
629
630 void *saa_rstruct(struct SAA *s)
631 {
632     void *p;
633
634     if (s->rptr + s->elem_len > s->datalen)
635         return NULL;
636
637     if (s->rpos % s->elem_len)
638             nasm_malloc_error(ERR_PANIC|ERR_NOFILE,
639                               "misaligned rpos in saa_rstruct");
640
641     if (s->rpos + s->elem_len > s->blk_len) {
642         s->rblk++;
643         s->rpos = 0;
644     }
645
646     p = *s->rblk + s->rpos;
647     s->rpos += s->elem_len;
648     s->rptr += s->elem_len;
649
650     return p;
651 }
652
653 const void *saa_rbytes(struct SAA *s, size_t *lenp)
654 {
655     const void *p;
656     size_t len;
657
658     if (s->rptr >= s->datalen) {
659         *lenp = 0;
660         return NULL;
661     }
662
663     if (s->rpos >= s->blk_len) {
664         s->rblk++;
665         s->rpos = 0;
666     }
667
668     len = *lenp;
669     if (len > s->datalen - s->rptr)
670         len = s->datalen - s->rptr;
671     if (len > s->blk_len - s->rpos)
672         len = s->blk_len - s->rpos;
673
674     *lenp = len;
675     p = *s->rblk + s->rpos;
676
677     s->rpos += len;
678     s->rptr += len;
679
680     return p;
681 }
682
683 void saa_rnbytes(struct SAA *s, void *data, size_t len)
684 {
685     char *d = data;
686
687     if (s->rptr + len > s->datalen) {
688         nasm_malloc_error(ERR_PANIC|ERR_NOFILE, "overrun in saa_rnbytes");
689         return;
690     }
691
692     while (len) {
693         size_t l;
694         const void *p;
695
696         l = len;
697         p = saa_rbytes(s, &l);
698
699         memcpy(d, p, l);
700         d   += l;
701         len -= l;
702     }
703 }
704
705 /* Same as saa_rnbytes, except position the counter first */
706 void saa_fread(struct SAA *s, size_t posn, void *data, size_t len)
707 {
708     size_t ix;
709
710     if (posn+len > s->datalen) {
711         nasm_malloc_error(ERR_PANIC|ERR_NOFILE, "overrun in saa_fread");
712         return;
713     }
714
715     ix = posn / s->blk_len;
716     s->rptr = posn;
717     s->rpos = posn % s->blk_len;
718     s->rblk = &s->blk_ptrs[ix];
719
720     saa_rnbytes(s, data, len);
721 }
722
723 /* Same as saa_wbytes, except position the counter first */
724 void saa_fwrite(struct SAA *s, size_t posn, const void *data, size_t len)
725 {
726     size_t ix;
727
728     if (posn > s->datalen) {
729         /* Seek beyond the end of the existing array not supported */
730         nasm_malloc_error(ERR_PANIC|ERR_NOFILE, "overrun in saa_fwrite");
731         return;
732     }
733
734     ix = posn / s->blk_len;
735     s->wptr = posn;
736     s->wpos = posn % s->blk_len;
737     s->wblk = &s->blk_ptrs[ix];
738
739     if (!s->wpos) {
740         s->wpos = s->blk_len;
741         s->wblk--;
742     }
743
744     saa_wbytes(s, data, len);
745 }
746
747 void saa_fpwrite(struct SAA *s, FILE * fp)
748 {
749     const char *data;
750     size_t len;
751
752     saa_rewind(s);
753     while (len = s->datalen, (data = saa_rbytes(s, &len)) != NULL)
754         fwrite(data, 1, len, fp);
755 }
756
757 /*
758  * Common list of prefix names
759  */
760 static const char *prefix_names[] = {
761     "a16", "a32", "lock", "o16", "o32", "rep", "repe", "repne",
762     "repnz", "repz", "times"
763 };
764
765 const char *prefix_name(int token)
766 {
767     unsigned int prefix = token-PREFIX_ENUM_START;
768     if (prefix > sizeof prefix_names / sizeof(const char *))
769         return NULL;
770
771     return prefix_names[prefix];
772 }
773
774 /*
775  * Binary search.
776  */
777 int bsi(char *string, const char **array, int size)
778 {
779     int i = -1, j = size;       /* always, i < index < j */
780     while (j - i >= 2) {
781         int k = (i + j) / 2;
782         int l = strcmp(string, array[k]);
783         if (l < 0)              /* it's in the first half */
784             j = k;
785         else if (l > 0)         /* it's in the second half */
786             i = k;
787         else                    /* we've got it :) */
788             return k;
789     }
790     return -1;                  /* we haven't got it :( */
791 }
792
793 int bsii(char *string, const char **array, int size)
794 {
795     int i = -1, j = size;       /* always, i < index < j */
796     while (j - i >= 2) {
797         int k = (i + j) / 2;
798         int l = nasm_stricmp(string, array[k]);
799         if (l < 0)              /* it's in the first half */
800             j = k;
801         else if (l > 0)         /* it's in the second half */
802             i = k;
803         else                    /* we've got it :) */
804             return k;
805     }
806     return -1;                  /* we haven't got it :( */
807 }
808
809 static char *file_name = NULL;
810 static int32_t line_number = 0;
811
812 char *src_set_fname(char *newname)
813 {
814     char *oldname = file_name;
815     file_name = newname;
816     return oldname;
817 }
818
819 int32_t src_set_linnum(int32_t newline)
820 {
821     int32_t oldline = line_number;
822     line_number = newline;
823     return oldline;
824 }
825
826 int32_t src_get_linnum(void)
827 {
828     return line_number;
829 }
830
831 int src_get(int32_t *xline, char **xname)
832 {
833     if (!file_name || !*xname || strcmp(*xname, file_name)) {
834         nasm_free(*xname);
835         *xname = file_name ? nasm_strdup(file_name) : NULL;
836         *xline = line_number;
837         return -2;
838     }
839     if (*xline != line_number) {
840         int32_t tmp = line_number - *xline;
841         *xline = line_number;
842         return tmp;
843     }
844     return 0;
845 }
846
847 void nasm_quote(char **str)
848 {
849     int ln = strlen(*str);
850     char q = (*str)[0];
851     char *p;
852     if (ln > 1 && (*str)[ln - 1] == q && (q == '"' || q == '\''))
853         return;
854     q = '"';
855     if (strchr(*str, q))
856         q = '\'';
857     p = nasm_malloc(ln + 3);
858     strcpy(p + 1, *str);
859     nasm_free(*str);
860     p[ln + 1] = p[0] = q;
861     p[ln + 2] = 0;
862     *str = p;
863 }
864
865 char *nasm_strcat(char *one, char *two)
866 {
867     char *rslt;
868     int l1 = strlen(one);
869     rslt = nasm_malloc(l1 + strlen(two) + 1);
870     strcpy(rslt, one);
871     strcpy(rslt + l1, two);
872     return rslt;
873 }
874
875 void null_debug_init(struct ofmt *of, void *id, FILE * fp, efunc error)
876 {
877         (void)of;
878         (void)id;
879         (void)fp;
880         (void)error;
881 }
882 void null_debug_linenum(const char *filename, int32_t linenumber, int32_t segto)
883 {
884         (void)filename;
885         (void)linenumber;
886         (void)segto;
887 }
888 void null_debug_deflabel(char *name, int32_t segment, int32_t offset,
889                          int is_global, char *special)
890 {
891         (void)name;
892         (void)segment;
893         (void)offset;
894         (void)is_global;
895         (void)special;
896 }
897 void null_debug_routine(const char *directive, const char *params)
898 {
899         (void)directive;
900         (void)params;
901 }
902 void null_debug_typevalue(int32_t type)
903 {
904         (void)type;
905 }
906 void null_debug_output(int type, void *param)
907 {
908         (void)type;
909         (void)param;
910 }
911 void null_debug_cleanup(void)
912 {
913 }
914
915 struct dfmt null_debug_form = {
916     "Null debug format",
917     "null",
918     null_debug_init,
919     null_debug_linenum,
920     null_debug_deflabel,
921     null_debug_routine,
922     null_debug_typevalue,
923     null_debug_output,
924     null_debug_cleanup
925 };
926
927 struct dfmt *null_debug_arr[2] = { &null_debug_form, NULL };