github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/src/cmd/cc/lex.c (about)

     1  // Inferno utils/cc/lex.c
     2  // http://code.google.com/p/inferno-os/source/browse/utils/cc/lex.c
     3  //
     4  //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
     5  //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
     6  //	Portions Copyright © 1997-1999 Vita Nuova Limited
     7  //	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
     8  //	Portions Copyright © 2004,2006 Bruce Ellis
     9  //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
    10  //	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
    11  //	Portions Copyright © 2009 The Go Authors.  All rights reserved.
    12  //
    13  // Permission is hereby granted, free of charge, to any person obtaining a copy
    14  // of this software and associated documentation files (the "Software"), to deal
    15  // in the Software without restriction, including without limitation the rights
    16  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    17  // copies of the Software, and to permit persons to whom the Software is
    18  // furnished to do so, subject to the following conditions:
    19  //
    20  // The above copyright notice and this permission notice shall be included in
    21  // all copies or substantial portions of the Software.
    22  //
    23  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    24  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    25  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    26  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    27  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    28  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    29  // THE SOFTWARE.
    30  
    31  #include	<u.h>
    32  #include	"cc.h"
    33  #include	"y.tab.h"
    34  
    35  #ifndef	CPP
    36  #define	CPP	"cpp"
    37  #endif
    38  
    39  int
    40  systemtype(int sys)
    41  {
    42  #ifdef _WIN32
    43  	return sys&Windows;
    44  #else
    45  	return sys&Plan9;
    46  #endif
    47  }
    48  
    49  int
    50  pathchar(void)
    51  {
    52  	return '/';
    53  }
    54  
    55  /*
    56   * known debug flags
    57   *	-a		acid declaration output
    58   *	-A		!B
    59   *	-B		non ANSI
    60   *	-d		print declarations
    61   *	-D name		define
    62   *	-F		format specification check
    63   *	-G		print pgen stuff
    64   *	-g		print cgen trees
    65   *	-i		print initialization
    66   *	-I path		include
    67   *	-l		generate little-endian code
    68   *	-L		print every NAME symbol
    69   *	-M		constant multiplication
    70   *	-m		print add/sub/mul trees
    71   *	-n		print acid or godefs to file (%.c=%.acid) (with -a or -aa)
    72   *	-o file		output file
    73   *	-p		use standard cpp ANSI preprocessor (not on windows)
    74   *	-p		something with peepholes
    75   *	-q		print equivalent Go code for variables and types (lower-case identifiers)
    76   *	-Q		print equivalent Go code for variables and types (upper-case identifiers)
    77   *	-r		print registerization
    78   *	-s		print structure offsets (with -a or -aa)
    79   *	-S		print assembly
    80   *	-t		print type trees
    81   *	-V		enable void* conversion warnings
    82   *	-v		verbose printing
    83   *	-w		print warnings
    84   *	-X		abort on error
    85   *	-.		Inhibit search for includes in source directory
    86   */
    87  
    88  void
    89  usage(void)
    90  {
    91  	print("usage: %cc [options] file.c...\n", thechar);
    92  	flagprint(1);
    93  	errorexit();
    94  }
    95  
    96  void
    97  dospim(void)
    98  {
    99  	thechar = '0';
   100  	thestring = "spim";
   101  }
   102  
   103  char **defs;
   104  int ndef;
   105  
   106  void
   107  dodef(char *p)
   108  {
   109  	if(ndef%8 == 0)
   110  		defs = allocn(defs, ndef*sizeof(char *),
   111  			8*sizeof(char *));
   112  	defs[ndef++] = p;
   113  	dodefine(p);
   114  }
   115  
   116  void
   117  main(int argc, char *argv[])
   118  {
   119  	int c;
   120  	char *p;
   121  
   122  	// Allow GOARCH=thestring or GOARCH=thestringsuffix,
   123  	// but not other values.	
   124  	p = getgoarch();
   125  	if(strncmp(p, thestring, strlen(thestring)) != 0)
   126  		sysfatal("cannot use %cc with GOARCH=%s", thechar, p);
   127  	if(strcmp(p, "amd64p32") == 0) // must be before cinit
   128  		ewidth[TIND] = 4;
   129  		
   130  	nacl = strcmp(getgoos(), "nacl") == 0;
   131  	if(nacl)
   132  		flag_largemodel = 1;
   133  
   134  	quotefmtinstall(); // before cinit, which overrides %Q
   135  
   136  	linkarchinit();
   137  	ctxt = linknew(thelinkarch);
   138  	ctxt->diag = yyerror;
   139  	ctxt->bso = &bstdout;
   140  	Binit(&bstdout, 1, OWRITE);
   141  
   142  	ensuresymb(NSYMB);
   143  	memset(debug, 0, sizeof(debug));
   144  	tinit();
   145  	cinit();
   146  	ginit();
   147  	arginit();
   148  	
   149  	fmtstrinit(&pragcgobuf);
   150  
   151  	tufield = simplet((1L<<tfield->etype) | BUNSIGNED);
   152  	ndef = 0;
   153  	defs = nil;
   154  	outfile = 0;
   155  	setinclude(".");
   156  
   157  	flagcount("+", "pass -+ to preprocessor", &debug['+']);	
   158  	flagcount(".", "pass -. to preprocessor", &debug['.']);	
   159  	flagcount("<", "debug shift", &debug['<']);
   160  	flagcount("A", "debug alignment", &debug['A']);
   161  	flagcount("B", "allow pre-ANSI code", &debug['B']);
   162  	if(thechar == '5')
   163  		flagcount("C", "debug constant propagation", &debug['C']);
   164  	flagfn1("D", "name[=value]: add #define", dodef);
   165  	flagcount("F", "enable print format checks", &debug['F']);
   166  	if(thechar == '5')
   167  		flagcount("H", "debug shift propagation", &debug['H']);
   168  	flagfn1("I", "dir: add dir to include path", setinclude);
   169  	flagcount("L", "debug lexer", &debug['L']);
   170  	flagcount("M", "debug move generation", &debug['M']);
   171  	flagcount("N", "disable optimizations", &debug['N']);
   172  	flagcount("P", "debug peephole optimizer", &debug['P']);
   173  	flagcount("Q", "print exported Go definitions", &debug['Q']);
   174  	flagcount("R", "debug register optimizer", &debug['R']);
   175  	flagcount("S", "print assembly", &debug['S']);
   176  	flagcount("T", "enable type signatures", &debug['T']);
   177  	flagcount("V", "enable pointer type checks", &debug['V']);
   178  	flagcount("W", "debug switch generation", &debug['W']);
   179  	flagcount("X", "abort on error", &debug['X']);
   180  	flagcount("Y", "debug index generation", &debug['Y']);
   181  	flagcount("Z", "skip code generation", &debug['Z']);
   182  	flagcount("a", "print acid definitions", &debug['a']);
   183  	flagcount("c", "debug constant evaluation", &debug['c']);
   184  	flagcount("d", "debug declarations", &debug['d']);
   185  	flagcount("e", "debug macro expansion", &debug['e']);
   186  	flagcount("f", "debug pragmas", &debug['f']);
   187  	flagcount("g", "debug code generation", &debug['g']);
   188  	flagcount("i", "debug initialization", &debug['i']);
   189  	if(thechar == 'v')
   190  		flagfn0("l", "little-endian mips mode", dospim);
   191  	flagcount("m", "debug multiplication", &debug['m']);
   192  	flagcount("n", "print acid/Go to file, not stdout", &debug['n']);
   193  	flagstr("o", "file: set output file", &outfile);
   194  	flagcount("p", "invoke C preprocessor", &debug['p']);	
   195  	flagcount("q", "print Go definitions", &debug['q']);
   196  	flagcount("s", "print #define assembly offsets", &debug['s']);
   197  	flagcount("t", "debug code generation", &debug['t']);
   198  	flagstr("trimpath", "prefix: remove prefix from recorded source file paths", &ctxt->trimpath);
   199  	flagcount("w", "enable warnings", &debug['w']);
   200  	flagcount("v", "increase debug verbosity", &debug['v']);	
   201  	if(thechar == '6')
   202  		flagcount("largemodel", "generate code that assumes a large memory model", &flag_largemodel);
   203  	
   204  	flagparse(&argc, &argv, usage);
   205  	ctxt->debugasm = debug['S'];
   206  
   207  	if(argc < 1 && outfile == 0)
   208  		usage();
   209  
   210  	if(argc > 1){
   211  		print("can't compile multiple files\n");
   212  		errorexit();
   213  	}
   214  
   215  	if(argc == 0)
   216  		c = compile("stdin", defs, ndef);
   217  	else
   218  		c = compile(argv[0], defs, ndef);
   219  
   220  	Bflush(&bstdout);
   221  	if(c)
   222  		errorexit();
   223  	exits(0);
   224  }
   225  
   226  int
   227  compile(char *file, char **defs, int ndef)
   228  {
   229  	char *ofile;
   230  	char *p, **av, opt[256];
   231  	int i, c, fd[2];
   232  	static int first = 1;
   233  
   234  	ofile = alloc(strlen(file)+10);
   235  	strcpy(ofile, file);
   236  	p = utfrrune(ofile, pathchar());
   237  	if(p) {
   238  		*p++ = 0;
   239  		if(!debug['.'])
   240  			include[0] = strdup(ofile);
   241  	} else
   242  		p = ofile;
   243  
   244  	if(outfile == 0) {
   245  		outfile = p;
   246  		if(outfile) {
   247  			if(p = utfrrune(outfile, '.'))
   248  				if(p[1] == 'c' && p[2] == 0)
   249  					p[0] = 0;
   250  			p = utfrune(outfile, 0);
   251  			if(debug['a'] && debug['n'])
   252  				strcat(p, ".acid");
   253  			else if((debug['q'] || debug['Q']) && debug['n'])
   254  				strcat(p, ".go");
   255  			else {
   256  				p[0] = '.';
   257  				p[1] = thechar;
   258  				p[2] = 0;
   259  			}
   260  		} else
   261  			outfile = "/dev/null";
   262  	}
   263  
   264  	if (first)
   265  		Binit(&diagbuf, 1, OWRITE);
   266  	/*
   267  	 * if we're writing acid to standard output, don't keep scratching
   268  	 * outbuf.
   269  	 */
   270  	if((debug['a'] || debug['q'] || debug['Q']) && !debug['n']) {
   271  		if (first) {
   272  			outfile = 0;
   273  			Binit(&outbuf, dup(1, -1), OWRITE);
   274  			dup(2, 1);
   275  		}
   276  	} else {
   277  		c = create(outfile, OWRITE, 0664);
   278  		if(c < 0) {
   279  			diag(Z, "cannot open %s - %r", outfile);
   280  			outfile = 0;
   281  			errorexit();
   282  		}
   283  		Binit(&outbuf, c, OWRITE);
   284  		outfile = strdup(outfile);
   285  	}
   286  	newio();
   287  	first = 0;
   288  
   289  	/* Use an ANSI preprocessor */
   290  	if(debug['p']) {
   291  		if(systemtype(Windows)) {
   292  			diag(Z, "-p option not supported on windows");
   293  			errorexit();
   294  		}
   295  		if(access(file, AREAD) < 0) {
   296  			diag(Z, "%s does not exist", file);
   297  			errorexit();
   298  		}
   299  		if(pipe(fd) < 0) {
   300  			diag(Z, "pipe failed");
   301  			errorexit();
   302  		}
   303  		switch(fork()) {
   304  		case -1:
   305  			diag(Z, "fork failed");
   306  			errorexit();
   307  		case 0:
   308  			close(fd[0]);
   309  			dup(fd[1], 1);
   310  			close(fd[1]);
   311  			av = alloc((ndef+ninclude+5)*sizeof(char *));
   312  			av[0] = CPP;
   313  			i = 1;
   314  			if(debug['.']){
   315  				sprint(opt, "-.");
   316  				av[i++] = strdup(opt);
   317  			}
   318  			if(debug['+']) {
   319  				sprint(opt, "-+");
   320  				av[i++] = strdup(opt);
   321  			}
   322  			for(c = 0; c < ndef; c++)
   323  				av[i++] = smprint("-D%s", defs[c]);
   324  			for(c = 0; c < ninclude; c++)
   325  				av[i++] = smprint("-I%s", include[c]);
   326  			if(strcmp(file, "stdin") != 0)
   327  				av[i++] = file;
   328  			av[i] = 0;
   329  			if(debug['p'] > 1) {
   330  				for(c = 0; c < i; c++)
   331  					fprint(2, "%s ", av[c]);
   332  				fprint(2, "\n");
   333  			}
   334  			exec(av[0], av);
   335  			fprint(2, "can't exec C preprocessor %s: %r\n", CPP);
   336  			errorexit();
   337  		default:
   338  			close(fd[1]);
   339  			newfile(file, fd[0]);
   340  			break;
   341  		}
   342  	} else {
   343  		if(strcmp(file, "stdin") == 0)
   344  			newfile(file, 0);
   345  		else
   346  			newfile(file, -1);
   347  	}
   348  	yyparse();
   349  	if(!debug['a'] && !debug['q'] && !debug['Q'])
   350  		gclean();
   351  	return nerrors;
   352  }
   353  
   354  void
   355  errorexit(void)
   356  {
   357  	Bflush(&bstdout);
   358  	if(outfile)
   359  		remove(outfile);
   360  	exits("error");
   361  }
   362  
   363  void
   364  pushio(void)
   365  {
   366  	Io *i;
   367  
   368  	i = iostack;
   369  	if(i == I) {
   370  		yyerror("botch in pushio");
   371  		errorexit();
   372  	}
   373  	i->p = fi.p;
   374  	i->c = fi.c;
   375  }
   376  
   377  void
   378  newio(void)
   379  {
   380  	Io *i;
   381  	static int pushdepth = 0;
   382  
   383  	i = iofree;
   384  	if(i == I) {
   385  		pushdepth++;
   386  		if(pushdepth > 1000) {
   387  			yyerror("macro/io expansion too deep");
   388  			errorexit();
   389  		}
   390  		i = alloc(sizeof(*i));
   391  	} else
   392  		iofree = i->link;
   393  	i->c = 0;
   394  	i->f = -1;
   395  	ionext = i;
   396  }
   397  
   398  void
   399  newfile(char *s, int f)
   400  {
   401  	Io *i;
   402  
   403  	if(debug['e'])
   404  		print("%L: %s\n", lineno, s);
   405  
   406  	i = ionext;
   407  	i->link = iostack;
   408  	iostack = i;
   409  	i->f = f;
   410  	if(f < 0)
   411  		i->f = open(s, 0);
   412  	if(i->f < 0) {
   413  		yyerror("%cc: %r: %s", thechar, s);
   414  		errorexit();
   415  	}
   416  	fi.c = 0;
   417  	linklinehist(ctxt, lineno, s, 0);
   418  }
   419  
   420  Sym*
   421  slookup(char *s)
   422  {
   423  	ensuresymb(strlen(s));
   424  	strcpy(symb, s);
   425  	return lookup();
   426  }
   427  
   428  Sym*
   429  lookup(void)
   430  {
   431  	Sym *s;
   432  	uint32 h;
   433  	char *p;
   434  	int c, n;
   435  	char *r, *w;
   436  
   437  	if((uchar)symb[0] == 0xc2 && (uchar)symb[1] == 0xb7) {
   438  		// turn leading · into ""·
   439  		h = strlen(symb);
   440  		ensuresymb(h+2);
   441  		memmove(symb+2, symb, h+1);
   442  		symb[0] = '"';
   443  		symb[1] = '"';
   444  	}
   445  
   446  	for(r=w=symb; *r; r++) {
   447  		// turn · (U+00B7) into .
   448  		// turn ∕ (U+2215) into /
   449  		if((uchar)*r == 0xc2 && (uchar)*(r+1) == 0xb7) {
   450  			*w++ = '.';
   451  			r++;
   452  		}else if((uchar)*r == 0xe2 && (uchar)*(r+1) == 0x88 && (uchar)*(r+2) == 0x95) {
   453  			*w++ = '/';
   454  			r++;
   455  			r++;
   456  		}else
   457  			*w++ = *r;
   458  	}
   459  	*w = '\0';
   460  
   461  	h = 0;
   462  	for(p=symb; *p;) {
   463  		h = h * 3;
   464  		h += *p++;
   465  	}
   466  	n = (p - symb) + 1;
   467  	h &= 0xffffff;
   468  	h %= NHASH;
   469  	c = symb[0];
   470  	for(s = hash[h]; s != S; s = s->link) {
   471  		if(s->name[0] != c)
   472  			continue;
   473  		if(strcmp(s->name, symb) == 0)
   474  			return s;
   475  	}
   476  	s = alloc(sizeof(*s));
   477  	s->name = alloc(n);
   478  	memmove(s->name, symb, n);
   479  	s->link = hash[h];
   480  	hash[h] = s;
   481  	syminit(s);
   482  
   483  	return s;
   484  }
   485  
   486  void
   487  syminit(Sym *s)
   488  {
   489  	s->lexical = LNAME;
   490  	s->block = 0;
   491  	s->offset = 0;
   492  	s->type = T;
   493  	s->suetag = T;
   494  	s->class = CXXX;
   495  	s->aused = 0;
   496  	s->sig = SIGNONE;
   497  }
   498  
   499  #define	EOF	(-1)
   500  #define	IGN	(-2)
   501  #define	ESC	(1<<20)
   502  #define	GETC()	((--fi.c < 0)? filbuf(): (*fi.p++ & 0xff))
   503  
   504  enum
   505  {
   506  	Numdec		= 1<<0,
   507  	Numlong		= 1<<1,
   508  	Numuns		= 1<<2,
   509  	Numvlong	= 1<<3,
   510  	Numflt		= 1<<4,
   511  };
   512  
   513  int32
   514  yylex(void)
   515  {
   516  	vlong vv;
   517  	int32 c, c1, t;
   518  	char *cp;
   519  	Rune rune;
   520  	Sym *s;
   521  
   522  	if(peekc != IGN) {
   523  		c = peekc;
   524  		peekc = IGN;
   525  		goto l1;
   526  	}
   527  l0:
   528  	c = GETC();
   529  
   530  l1:
   531  	if(c >= Runeself) {
   532  		/*
   533  		 * extension --
   534  		 *	all multibyte runes are alpha
   535  		 */
   536  		cp = symb;
   537  		goto talph;
   538  	}
   539  	if(isspace(c)) {
   540  		if(c == '\n')
   541  			lineno++;
   542  		goto l0;
   543  	}
   544  	if(isalpha(c)) {
   545  		cp = symb;
   546  		if(c != 'L')
   547  			goto talph;
   548  		*cp++ = c;
   549  		c = GETC();
   550  		if(c == '\'') {
   551  			/* L'x' */
   552  			c = escchar('\'', 1, 0);
   553  			if(c == EOF)
   554  				c = '\'';
   555  			c1 = escchar('\'', 1, 0);
   556  			if(c1 != EOF) {
   557  				yyerror("missing '");
   558  				peekc = c1;
   559  			}
   560  			yylval.vval = convvtox(c, TRUNE);
   561  			return LUCONST;
   562  		}
   563  		if(c == '"') {
   564  			goto caselq;
   565  		}
   566  		goto talph;
   567  	}
   568  	if(isdigit(c))
   569  		goto tnum;
   570  	switch(c)
   571  	{
   572  
   573  	case EOF:
   574  		peekc = EOF;
   575  		return -1;
   576  
   577  	case '_':
   578  		cp = symb;
   579  		goto talph;
   580  
   581  	case '#':
   582  		domacro();
   583  		goto l0;
   584  
   585  	case '.':
   586  		c1 = GETC();
   587  		if(isdigit(c1)) {
   588  			cp = symb;
   589  			*cp++ = c;
   590  			c = c1;
   591  			c1 = 0;
   592  			goto casedot;
   593  		}
   594  		break;
   595  
   596  	case '"':
   597  		strcpy(symb, "\"<string>\"");
   598  		cp = alloc(0);
   599  		c1 = 0;
   600  
   601  		/* "..." */
   602  		for(;;) {
   603  			c = escchar('"', 0, 1);
   604  			if(c == EOF)
   605  				break;
   606  			if(c & ESC) {
   607  				cp = allocn(cp, c1, 1);
   608  				cp[c1++] = c;
   609  			} else {
   610  				rune = c;
   611  				c = runelen(rune);
   612  				cp = allocn(cp, c1, c);
   613  				runetochar(cp+c1, &rune);
   614  				c1 += c;
   615  			}
   616  		}
   617  		yylval.sval.l = c1;
   618  		do {
   619  			cp = allocn(cp, c1, 1);
   620  			cp[c1++] = 0;
   621  		} while(c1 & MAXALIGN);
   622  		yylval.sval.s = cp;
   623  		return LSTRING;
   624  
   625  	caselq:
   626  		/* L"..." */
   627  		strcpy(symb, "\"L<string>\"");
   628  		cp = alloc(0);
   629  		c1 = 0;
   630  		for(;;) {
   631  			c = escchar('"', 1, 0);
   632  			if(c == EOF)
   633  				break;
   634  			cp = allocn(cp, c1, sizeof(TRune));
   635  			*(TRune*)(cp + c1) = c;
   636  			c1 += sizeof(TRune);
   637  		}
   638  		yylval.sval.l = c1;
   639  		do {
   640  			cp = allocn(cp, c1, sizeof(TRune));
   641  			*(TRune*)(cp + c1) = 0;
   642  			c1 += sizeof(TRune);
   643  		} while(c1 & MAXALIGN);
   644  		yylval.sval.s = cp;
   645  		return LLSTRING;
   646  
   647  	case '\'':
   648  		/* '.' */
   649  		c = escchar('\'', 0, 0);
   650  		if(c == EOF)
   651  			c = '\'';
   652  		c1 = escchar('\'', 0, 0);
   653  		if(c1 != EOF) {
   654  			yyerror("missing '");
   655  			peekc = c1;
   656  		}
   657  		vv = c;
   658  		yylval.vval = convvtox(vv, TUCHAR);
   659  		if(yylval.vval != vv)
   660  			yyerror("overflow in character constant: 0x%x", c);
   661  		else
   662  		if(c & 0x80){
   663  			nearln = lineno;
   664  			warn(Z, "sign-extended character constant");
   665  		}
   666  		yylval.vval = convvtox(vv, TCHAR);
   667  		return LCONST;
   668  
   669  	case '/':
   670  		c1 = GETC();
   671  		if(c1 == '*') {
   672  			for(;;) {
   673  				c = getr();
   674  				while(c == '*') {
   675  					c = getr();
   676  					if(c == '/')
   677  						goto l0;
   678  				}
   679  				if(c == EOF) {
   680  					yyerror("eof in comment");
   681  					errorexit();
   682  				}
   683  			}
   684  		}
   685  		if(c1 == '/') {
   686  			for(;;) {
   687  				c = getr();
   688  				if(c == '\n')
   689  					goto l0;
   690  				if(c == EOF) {
   691  					yyerror("eof in comment");
   692  					errorexit();
   693  				}
   694  			}
   695  		}
   696  		if(c1 == '=')
   697  			return LDVE;
   698  		break;
   699  
   700  	case '*':
   701  		c1 = GETC();
   702  		if(c1 == '=')
   703  			return LMLE;
   704  		break;
   705  
   706  	case '%':
   707  		c1 = GETC();
   708  		if(c1 == '=')
   709  			return LMDE;
   710  		break;
   711  
   712  	case '+':
   713  		c1 = GETC();
   714  		if(c1 == '+')
   715  			return LPP;
   716  		if(c1 == '=')
   717  			return LPE;
   718  		break;
   719  
   720  	case '-':
   721  		c1 = GETC();
   722  		if(c1 == '-')
   723  			return LMM;
   724  		if(c1 == '=')
   725  			return LME;
   726  		if(c1 == '>')
   727  			return LMG;
   728  		break;
   729  
   730  	case '>':
   731  		c1 = GETC();
   732  		if(c1 == '>') {
   733  			c = LRSH;
   734  			c1 = GETC();
   735  			if(c1 == '=')
   736  				return LRSHE;
   737  			break;
   738  		}
   739  		if(c1 == '=')
   740  			return LGE;
   741  		break;
   742  
   743  	case '<':
   744  		c1 = GETC();
   745  		if(c1 == '<') {
   746  			c = LLSH;
   747  			c1 = GETC();
   748  			if(c1 == '=')
   749  				return LLSHE;
   750  			break;
   751  		}
   752  		if(c1 == '=')
   753  			return LLE;
   754  		break;
   755  
   756  	case '=':
   757  		c1 = GETC();
   758  		if(c1 == '=')
   759  			return LEQ;
   760  		break;
   761  
   762  	case '!':
   763  		c1 = GETC();
   764  		if(c1 == '=')
   765  			return LNE;
   766  		break;
   767  
   768  	case '&':
   769  		c1 = GETC();
   770  		if(c1 == '&')
   771  			return LANDAND;
   772  		if(c1 == '=')
   773  			return LANDE;
   774  		break;
   775  
   776  	case '|':
   777  		c1 = GETC();
   778  		if(c1 == '|')
   779  			return LOROR;
   780  		if(c1 == '=')
   781  			return LORE;
   782  		break;
   783  
   784  	case '^':
   785  		c1 = GETC();
   786  		if(c1 == '=')
   787  			return LXORE;
   788  		break;
   789  
   790  	default:
   791  		return c;
   792  	}
   793  	peekc = c1;
   794  	return c;
   795  
   796  talph:
   797  	/*
   798  	 * cp is set to symb and some
   799  	 * prefix has been stored
   800  	 */
   801  	for(;;) {
   802  		if(c >= Runeself) {
   803  			for(c1=0;;) {
   804  				cp[c1++] = c;
   805  				if(fullrune(cp, c1))
   806  					break;
   807  				c = GETC();
   808  			}
   809  			cp += c1;
   810  			c = GETC();
   811  			continue;
   812  		}
   813  		if(!isalnum(c) && c != '_')
   814  			break;
   815  		*cp++ = c;
   816  		c = GETC();
   817  	}
   818  	*cp = 0;
   819  	if(debug['L'])
   820  		print("%L: %s\n", lineno, symb);
   821  	peekc = c;
   822  	s = lookup();
   823  	if(s->macro) {
   824  		newio();
   825  		cp = ionext->b;
   826  		macexpand(s, cp);
   827  		pushio();
   828  		ionext->link = iostack;
   829  		iostack = ionext;
   830  		fi.p = cp;
   831  		fi.c = strlen(cp);
   832  		if(peekc != IGN) {
   833  			cp[fi.c++] = peekc;
   834  			cp[fi.c] = 0;
   835  			peekc = IGN;
   836  		}
   837  		goto l0;
   838  	}
   839  	yylval.sym = s;
   840  	if(s->class == CTYPEDEF || s->class == CTYPESTR)
   841  		return LTYPE;
   842  	return s->lexical;
   843  
   844  tnum:
   845  	c1 = 0;
   846  	cp = symb;
   847  	if(c != '0') {
   848  		c1 |= Numdec;
   849  		for(;;) {
   850  			*cp++ = c;
   851  			c = GETC();
   852  			if(isdigit(c))
   853  				continue;
   854  			goto dc;
   855  		}
   856  	}
   857  	*cp++ = c;
   858  	c = GETC();
   859  	if(c == 'x' || c == 'X')
   860  		for(;;) {
   861  			*cp++ = c;
   862  			c = GETC();
   863  			if(isdigit(c))
   864  				continue;
   865  			if(c >= 'a' && c <= 'f')
   866  				continue;
   867  			if(c >= 'A' && c <= 'F')
   868  				continue;
   869  			if(cp == symb+2)
   870  				yyerror("malformed hex constant");
   871  			goto ncu;
   872  		}
   873  	if(c < '0' || c > '7')
   874  		goto dc;
   875  	for(;;) {
   876  		if(c >= '0' && c <= '7') {
   877  			*cp++ = c;
   878  			c = GETC();
   879  			continue;
   880  		}
   881  		goto ncu;
   882  	}
   883  
   884  dc:
   885  	if(c == '.')
   886  		goto casedot;
   887  	if(c == 'e' || c == 'E')
   888  		goto casee;
   889  
   890  ncu:
   891  	if((c == 'U' || c == 'u') && !(c1 & Numuns)) {
   892  		c = GETC();
   893  		c1 |= Numuns;
   894  		goto ncu;
   895  	}
   896  	if((c == 'L' || c == 'l') && !(c1 & Numvlong)) {
   897  		c = GETC();
   898  		if(c1 & Numlong)
   899  			c1 |= Numvlong;
   900  		c1 |= Numlong;
   901  		goto ncu;
   902  	}
   903  	*cp = 0;
   904  	peekc = c;
   905  	if(mpatov(symb, &yylval.vval))
   906  		yyerror("overflow in constant");
   907  
   908  	vv = yylval.vval;
   909  	if(c1 & Numvlong) {
   910  		if((c1 & Numuns) || convvtox(vv, TVLONG) < 0) {
   911  			c = LUVLCONST;
   912  			t = TUVLONG;
   913  			goto nret;
   914  		}
   915  		c = LVLCONST;
   916  		t = TVLONG;
   917  		goto nret;
   918  	}
   919  	if(c1 & Numlong) {
   920  		if((c1 & Numuns) || convvtox(vv, TLONG) < 0) {
   921  			c = LULCONST;
   922  			t = TULONG;
   923  			goto nret;
   924  		}
   925  		c = LLCONST;
   926  		t = TLONG;
   927  		goto nret;
   928  	}
   929  	if((c1 & Numuns) || convvtox(vv, TINT) < 0) {
   930  		c = LUCONST;
   931  		t = TUINT;
   932  		goto nret;
   933  	}
   934  	c = LCONST;
   935  	t = TINT;
   936  	goto nret;
   937  
   938  nret:
   939  	yylval.vval = convvtox(vv, t);
   940  	if(yylval.vval != vv){
   941  		nearln = lineno;
   942  		warn(Z, "truncated constant: %T %s", types[t], symb);
   943  	}
   944  	return c;
   945  
   946  casedot:
   947  	for(;;) {
   948  		*cp++ = c;
   949  		c = GETC();
   950  		if(!isdigit(c))
   951  			break;
   952  	}
   953  	if(c != 'e' && c != 'E')
   954  		goto caseout;
   955  
   956  casee:
   957  	*cp++ = 'e';
   958  	c = GETC();
   959  	if(c == '+' || c == '-') {
   960  		*cp++ = c;
   961  		c = GETC();
   962  	}
   963  	if(!isdigit(c))
   964  		yyerror("malformed fp constant exponent");
   965  	while(isdigit(c)) {
   966  		*cp++ = c;
   967  		c = GETC();
   968  	}
   969  
   970  caseout:
   971  	if(c == 'L' || c == 'l') {
   972  		c = GETC();
   973  		c1 |= Numlong;
   974  	} else
   975  	if(c == 'F' || c == 'f') {
   976  		c = GETC();
   977  		c1 |= Numflt;
   978  	}
   979  	*cp = 0;
   980  	peekc = c;
   981  	yylval.dval = strtod(symb, nil);
   982  	if(isInf(yylval.dval, 1) || isInf(yylval.dval, -1)) {
   983  		yyerror("overflow in float constant");
   984  		yylval.dval = 0;
   985  	}
   986  	if(c1 & Numflt)
   987  		return LFCONST;
   988  	return LDCONST;
   989  }
   990  
   991  /*
   992   * convert a string, s, to vlong in *v
   993   * return conversion overflow.
   994   * required syntax is [0[x]]d*
   995   */
   996  int
   997  mpatov(char *s, vlong *v)
   998  {
   999  	vlong n, nn;
  1000  	int c;
  1001  
  1002  	n = 0;
  1003  	c = *s;
  1004  	if(c == '0')
  1005  		goto oct;
  1006  	while(c = *s++) {
  1007  		if(c >= '0' && c <= '9')
  1008  			nn = n*10 + c-'0';
  1009  		else
  1010  			goto bad;
  1011  		if(n < 0 && nn >= 0)
  1012  			goto bad;
  1013  		n = nn;
  1014  	}
  1015  	goto out;
  1016  
  1017  oct:
  1018  	s++;
  1019  	c = *s;
  1020  	if(c == 'x' || c == 'X')
  1021  		goto hex;
  1022  	while(c = *s++) {
  1023  		if(c >= '0' || c <= '7')
  1024  			nn = n*8 + c-'0';
  1025  		else
  1026  			goto bad;
  1027  		if(n < 0 && nn >= 0)
  1028  			goto bad;
  1029  		n = nn;
  1030  	}
  1031  	goto out;
  1032  
  1033  hex:
  1034  	s++;
  1035  	while(c = *s++) {
  1036  		if(c >= '0' && c <= '9')
  1037  			c += 0-'0';
  1038  		else
  1039  		if(c >= 'a' && c <= 'f')
  1040  			c += 10-'a';
  1041  		else
  1042  		if(c >= 'A' && c <= 'F')
  1043  			c += 10-'A';
  1044  		else
  1045  			goto bad;
  1046  		nn = (uvlong)n*16 + c;
  1047  		if(n < 0 && nn >= 0)
  1048  			goto bad;
  1049  		n = nn;
  1050  	}
  1051  out:
  1052  	*v = n;
  1053  	return 0;
  1054  
  1055  bad:
  1056  	*v = ~0;
  1057  	return 1;
  1058  }
  1059  
  1060  int
  1061  getc(void)
  1062  {
  1063  	int c;
  1064  
  1065  	if(peekc != IGN) {
  1066  		c = peekc;
  1067  		peekc = IGN;
  1068  	} else
  1069  		c = GETC();
  1070  	if(c == '\n')
  1071  		lineno++;
  1072  	if(c == EOF) {
  1073  		yyerror("End of file");
  1074  		errorexit();
  1075  	}
  1076  	return c;
  1077  }
  1078  
  1079  int32
  1080  getr(void)
  1081  {
  1082  	int c, i;
  1083  	char str[UTFmax+1];
  1084  	Rune rune;
  1085  
  1086  
  1087  	c = getc();
  1088  	if(c < Runeself)
  1089  		return c;
  1090  	i = 0;
  1091  	str[i++] = c;
  1092  
  1093  loop:
  1094  	c = getc();
  1095  	str[i++] = c;
  1096  	if(!fullrune(str, i))
  1097  		goto loop;
  1098  	c = chartorune(&rune, str);
  1099  	if(rune == Runeerror && c == 1) {
  1100  		nearln = lineno;
  1101  		diag(Z, "illegal rune in string");
  1102  		for(c=0; c<i; c++)
  1103  			print(" %.2x", *(uchar*)(str+c));
  1104  		print("\n");
  1105  	}
  1106  	return rune;
  1107  }
  1108  
  1109  int
  1110  getnsc(void)
  1111  {
  1112  	int c;
  1113  
  1114  	if(peekc != IGN) {
  1115  		c = peekc;
  1116  		peekc = IGN;
  1117  	} else
  1118  		c = GETC();
  1119  	for(;;) {
  1120  		if(c >= Runeself || !isspace(c))
  1121  			return c;
  1122  		if(c == '\n') {
  1123  			lineno++;
  1124  			return c;
  1125  		}
  1126  		c = GETC();
  1127  	}
  1128  }
  1129  
  1130  void
  1131  unget(int c)
  1132  {
  1133  
  1134  	peekc = c;
  1135  	if(c == '\n')
  1136  		lineno--;
  1137  }
  1138  
  1139  int32
  1140  escchar(int32 e, int longflg, int escflg)
  1141  {
  1142  	int32 c, l;
  1143  	int i;
  1144  
  1145  loop:
  1146  	c = getr();
  1147  	if(c == '\n') {
  1148  		yyerror("newline in string");
  1149  		return EOF;
  1150  	}
  1151  	if(c != '\\') {
  1152  		if(c == e)
  1153  			c = EOF;
  1154  		return c;
  1155  	}
  1156  	c = getr();
  1157  	if(c == 'x') {
  1158  		/*
  1159  		 * note this is not ansi,
  1160  		 * supposed to only accept 2 hex
  1161  		 */
  1162  		i = 2;
  1163  		if(longflg)
  1164  			i = 6;
  1165  		l = 0;
  1166  		for(; i>0; i--) {
  1167  			c = getc();
  1168  			if(c >= '0' && c <= '9') {
  1169  				l = l*16 + c-'0';
  1170  				continue;
  1171  			}
  1172  			if(c >= 'a' && c <= 'f') {
  1173  				l = l*16 + c-'a' + 10;
  1174  				continue;
  1175  			}
  1176  			if(c >= 'A' && c <= 'F') {
  1177  				l = l*16 + c-'A' + 10;
  1178  				continue;
  1179  			}
  1180  			unget(c);
  1181  			break;
  1182  		}
  1183  		if(escflg)
  1184  			l |= ESC;
  1185  		return l;
  1186  	}
  1187  	if(c >= '0' && c <= '7') {
  1188  		/*
  1189  		 * note this is not ansi,
  1190  		 * supposed to only accept 3 oct
  1191  		 */
  1192  		i = 2;
  1193  		if(longflg)
  1194  			i = 8;
  1195  		l = c - '0';
  1196  		for(; i>0; i--) {
  1197  			c = getc();
  1198  			if(c >= '0' && c <= '7') {
  1199  				l = l*8 + c-'0';
  1200  				continue;
  1201  			}
  1202  			unget(c);
  1203  		}
  1204  		if(escflg)
  1205  			l |= ESC;
  1206  		return l;
  1207  	}
  1208  	switch(c)
  1209  	{
  1210  	case '\n':	goto loop;
  1211  	case 'n':	return '\n';
  1212  	case 't':	return '\t';
  1213  	case 'b':	return '\b';
  1214  	case 'r':	return '\r';
  1215  	case 'f':	return '\f';
  1216  	case 'a':	return '\a';
  1217  	case 'v':	return '\v';
  1218  	}
  1219  	return c;
  1220  }
  1221  
  1222  struct
  1223  {
  1224  	char	*name;
  1225  	ushort	lexical;
  1226  	ushort	type;
  1227  } itab[] =
  1228  {
  1229  	"auto",		LAUTO,		0,
  1230  	"break",	LBREAK,		0,
  1231  	"case",		LCASE,		0,
  1232  	"char",		LCHAR,		TCHAR,
  1233  	"const",	LCONSTNT,	0,
  1234  	"continue",	LCONTINUE,	0,
  1235  	"default",	LDEFAULT,	0,
  1236  	"do",		LDO,		0,
  1237  	"double",	LDOUBLE,	TDOUBLE,
  1238  	"else",		LELSE,		0,
  1239  	"enum",		LENUM,		0,
  1240  	"extern",	LEXTERN,	0,
  1241  	"float",	LFLOAT,		TFLOAT,
  1242  	"for",		LFOR,		0,
  1243  	"goto",		LGOTO,		0,
  1244  	"if",		LIF,		0,
  1245  	"inline",	LINLINE,	0,
  1246  	"int",		LINT,		TINT,
  1247  	"long",		LLONG,		TLONG,
  1248  	"PREFETCH",	LPREFETCH,	0,
  1249  	"register",	LREGISTER,	0,
  1250  	"restrict",	LRESTRICT,	0,
  1251  	"return",	LRETURN,	0,
  1252  	"SET",		LSET,		0,
  1253  	"short",	LSHORT,		TSHORT,
  1254  	"signed",	LSIGNED,	0,
  1255  	"signof",	LSIGNOF,	0,
  1256  	"sizeof",	LSIZEOF,	0,
  1257  	"static",	LSTATIC,	0,
  1258  	"struct",	LSTRUCT,	0,
  1259  	"switch",	LSWITCH,	0,
  1260  	"typedef",	LTYPEDEF,	0,
  1261  	"typestr",	LTYPESTR,	0,
  1262  	"union",	LUNION,		0,
  1263  	"unsigned",	LUNSIGNED,	0,
  1264  	"USED",		LUSED,		0,
  1265  	"void",		LVOID,		TVOID,
  1266  	"volatile",	LVOLATILE,	0,
  1267  	"while",	LWHILE,		0,
  1268  	0
  1269  };
  1270  
  1271  void
  1272  cinit(void)
  1273  {
  1274  	Sym *s;
  1275  	int i;
  1276  	Type *t;
  1277  
  1278  	nerrors = 0;
  1279  	lineno = 1;
  1280  	iostack = I;
  1281  	iofree = I;
  1282  	peekc = IGN;
  1283  	nhunk = 0;
  1284  
  1285  	types[TXXX] = T;
  1286  	types[TCHAR] = typ(TCHAR, T);
  1287  	types[TUCHAR] = typ(TUCHAR, T);
  1288  	types[TSHORT] = typ(TSHORT, T);
  1289  	types[TUSHORT] = typ(TUSHORT, T);
  1290  	types[TINT] = typ(TINT, T);
  1291  	types[TUINT] = typ(TUINT, T);
  1292  	types[TLONG] = typ(TLONG, T);
  1293  	types[TULONG] = typ(TULONG, T);
  1294  	types[TVLONG] = typ(TVLONG, T);
  1295  	types[TUVLONG] = typ(TUVLONG, T);
  1296  	types[TFLOAT] = typ(TFLOAT, T);
  1297  	types[TDOUBLE] = typ(TDOUBLE, T);
  1298  	types[TVOID] = typ(TVOID, T);
  1299  	types[TENUM] = typ(TENUM, T);
  1300  	types[TFUNC] = typ(TFUNC, types[TINT]);
  1301  	types[TIND] = typ(TIND, types[TVOID]);
  1302  
  1303  	for(i=0; i<NHASH; i++)
  1304  		hash[i] = S;
  1305  	for(i=0; itab[i].name; i++) {
  1306  		s = slookup(itab[i].name);
  1307  		s->lexical = itab[i].lexical;
  1308  		if(itab[i].type != 0)
  1309  			s->type = types[itab[i].type];
  1310  	}
  1311  	blockno = 0;
  1312  	autobn = 0;
  1313  	autoffset = 0;
  1314  
  1315  	t = typ(TARRAY, types[TCHAR]);
  1316  	t->width = 0;
  1317  	symstring = slookup(".string");
  1318  	symstring->class = CSTATIC;
  1319  	symstring->type = t;
  1320  
  1321  	t = typ(TARRAY, types[TCHAR]);
  1322  	t->width = 0;
  1323  
  1324  	nodproto = new(OPROTO, Z, Z);
  1325  	dclstack = D;
  1326  
  1327  	fmtinstall('O', Oconv);
  1328  	fmtinstall('T', Tconv);
  1329  	fmtinstall('F', FNconv);
  1330  	fmtinstall('L', Lconv);
  1331  	fmtinstall('Q', Qconv);
  1332  	fmtinstall('|', VBconv);
  1333  	fmtinstall('U', Uconv);
  1334  	fmtinstall('B', Bconv);
  1335  }
  1336  
  1337  int
  1338  filbuf(void)
  1339  {
  1340  	Io *i;
  1341  
  1342  loop:
  1343  	i = iostack;
  1344  	if(i == I)
  1345  		return EOF;
  1346  	if(i->f < 0)
  1347  		goto pop;
  1348  	fi.c = read(i->f, i->b, BUFSIZ) - 1;
  1349  	if(fi.c < 0) {
  1350  		close(i->f);
  1351  		linklinehist(ctxt, lineno, nil, 0);
  1352  		goto pop;
  1353  	}
  1354  	fi.p = i->b + 1;
  1355  	return i->b[0] & 0xff;
  1356  
  1357  pop:
  1358  	iostack = i->link;
  1359  	i->link = iofree;
  1360  	iofree = i;
  1361  	i = iostack;
  1362  	if(i == I)
  1363  		return EOF;
  1364  	fi.p = i->p;
  1365  	fi.c = i->c;
  1366  	if(--fi.c < 0)
  1367  		goto loop;
  1368  	return *fi.p++ & 0xff;
  1369  }
  1370  
  1371  int
  1372  Oconv(Fmt *fp)
  1373  {
  1374  	int a;
  1375  
  1376  	a = va_arg(fp->args, int);
  1377  	if(a < OXXX || a > OEND)
  1378  		return fmtprint(fp, "***badO %d***", a);
  1379  
  1380  	return fmtstrcpy(fp, onames[a]);
  1381  }
  1382  
  1383  int
  1384  Lconv(Fmt *fp)
  1385  {
  1386  	return linklinefmt(ctxt, fp);
  1387  }
  1388  
  1389  int
  1390  Tconv(Fmt *fp)
  1391  {
  1392  	char str[STRINGSZ+20], s[STRINGSZ+20];
  1393  	Type *t, *t1;
  1394  	int et;
  1395  	int32 n;
  1396  
  1397  	str[0] = 0;
  1398  	for(t = va_arg(fp->args, Type*); t != T; t = t->link) {
  1399  		et = t->etype;
  1400  		if(str[0])
  1401  			strcat(str, " ");
  1402  		if(t->garb&~GINCOMPLETE) {
  1403  			sprint(s, "%s ", gnames[t->garb&~GINCOMPLETE]);
  1404  			if(strlen(str) + strlen(s) < STRINGSZ)
  1405  				strcat(str, s);
  1406  		}
  1407  		sprint(s, "%s", tnames[et]);
  1408  		if(strlen(str) + strlen(s) < STRINGSZ)
  1409  			strcat(str, s);
  1410  		if(et == TFUNC && (t1 = t->down)) {
  1411  			sprint(s, "(%T", t1);
  1412  			if(strlen(str) + strlen(s) < STRINGSZ)
  1413  				strcat(str, s);
  1414  			while(t1 = t1->down) {
  1415  				sprint(s, ", %T", t1);
  1416  				if(strlen(str) + strlen(s) < STRINGSZ)
  1417  					strcat(str, s);
  1418  			}
  1419  			if(strlen(str) + strlen(s) < STRINGSZ)
  1420  				strcat(str, ")");
  1421  		}
  1422  		if(et == TARRAY) {
  1423  			n = t->width;
  1424  			if(t->link && t->link->width)
  1425  				n /= t->link->width;
  1426  			sprint(s, "[%d]", n);
  1427  			if(strlen(str) + strlen(s) < STRINGSZ)
  1428  				strcat(str, s);
  1429  		}
  1430  		if(t->nbits) {
  1431  			sprint(s, " %d:%d", t->shift, t->nbits);
  1432  			if(strlen(str) + strlen(s) < STRINGSZ)
  1433  				strcat(str, s);
  1434  		}
  1435  		if(typesu[et]) {
  1436  			if(t->tag) {
  1437  				strcat(str, " ");
  1438  				if(strlen(str) + strlen(t->tag->name) < STRINGSZ)
  1439  					strcat(str, t->tag->name);
  1440  			} else
  1441  				strcat(str, " {}");
  1442  			break;
  1443  		}
  1444  	}
  1445  	return fmtstrcpy(fp, str);
  1446  }
  1447  
  1448  int
  1449  FNconv(Fmt *fp)
  1450  {
  1451  	char *str;
  1452  	Node *n;
  1453  
  1454  	n = va_arg(fp->args, Node*);
  1455  	str = "<indirect>";
  1456  	if(n != Z && (n->op == ONAME || n->op == ODOT || n->op == OELEM))
  1457  		str = n->sym->name;
  1458  	return fmtstrcpy(fp, str);
  1459  }
  1460  
  1461  int
  1462  Qconv(Fmt *fp)
  1463  {
  1464  	char str[STRINGSZ+20], *s;
  1465  	int32 b;
  1466  	int i;
  1467  
  1468  	str[0] = 0;
  1469  	for(b = va_arg(fp->args, int32); b;) {
  1470  		i = bitno(b);
  1471  		if(str[0])
  1472  			strcat(str, " ");
  1473  		s = qnames[i];
  1474  		if(strlen(str) + strlen(s) >= STRINGSZ)
  1475  			break;
  1476  		strcat(str, s);
  1477  		b &= ~(1L << i);
  1478  	}
  1479  	return fmtstrcpy(fp, str);
  1480  }
  1481  
  1482  int
  1483  VBconv(Fmt *fp)
  1484  {
  1485  	char str[STRINGSZ];
  1486  	int i, n, t, pc;
  1487  
  1488  	n = va_arg(fp->args, int);
  1489  	pc = 0;	/* BUG: was printcol */
  1490  	i = 0;
  1491  	while(pc < n) {
  1492  		t = (pc+4) & ~3;
  1493  		if(t <= n) {
  1494  			str[i++] = '\t';
  1495  			pc = t;
  1496  			continue;
  1497  		}
  1498  		str[i++] = ' ';
  1499  		pc++;
  1500  	}
  1501  	str[i] = 0;
  1502  
  1503  	return fmtstrcpy(fp, str);
  1504  }
  1505  
  1506  int
  1507  Bconv(Fmt *fp)
  1508  {
  1509  	char str[STRINGSZ], ss[STRINGSZ], *s;
  1510  	Bits bits;
  1511  	int i;
  1512  
  1513  	str[0] = 0;
  1514  	bits = va_arg(fp->args, Bits);
  1515  	while(bany(&bits)) {
  1516  		i = bnum(bits);
  1517  		if(str[0])
  1518  			strcat(str, " ");
  1519  		if(var[i].sym == nil) {
  1520  			sprint(ss, "$%lld", var[i].offset);
  1521  			s = ss;
  1522  		} else
  1523  			s = var[i].sym->name;
  1524  		if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
  1525  			break;
  1526  		strcat(str, s);
  1527  		bits.b[i/32] &= ~(1L << (i%32));
  1528  	}
  1529  	return fmtstrcpy(fp, str);
  1530  }
  1531  
  1532  void
  1533  setinclude(char *p)
  1534  {
  1535  	int i;
  1536  
  1537  	if(*p != 0) {
  1538  		for(i=1; i < ninclude; i++)
  1539  			if(strcmp(p, include[i]) == 0)
  1540  				return;
  1541  
  1542  		if(ninclude%8 == 0)
  1543  			include = allocn(include, ninclude*sizeof(char *),
  1544  				8*sizeof(char *));
  1545  		include[ninclude++] = p;
  1546  	}
  1547  }
  1548  
  1549  void*
  1550  alloc(int32 n)
  1551  {
  1552  	void *p;
  1553  
  1554  	p = malloc(n);
  1555  	if(p == nil) {
  1556  		print("alloc out of mem\n");
  1557  		exits("alloc: out of mem");
  1558  	}
  1559  	memset(p, 0, n);
  1560  	return p;
  1561  }
  1562  
  1563  void*
  1564  allocn(void *p, int32 n, int32 d)
  1565  {
  1566  	if(p == nil)
  1567  		return alloc(n+d);
  1568  	p = realloc(p, n+d);
  1569  	if(p == nil) {
  1570  		print("allocn out of mem\n");
  1571  		exits("allocn: out of mem");
  1572  	}
  1573  	if(d > 0)
  1574  		memset((char*)p+n, 0, d);
  1575  	return p;
  1576  }
  1577  
  1578  void
  1579  ensuresymb(int32 n)
  1580  {
  1581  	if(symb == nil) {
  1582  		symb = alloc(NSYMB+1);
  1583  		nsymb = NSYMB;
  1584  	}
  1585  
  1586  	if(n > nsymb) {
  1587  		symb = allocn(symb, nsymb, n+1-nsymb);
  1588  		nsymb = n;
  1589  	}
  1590  }