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