summaryrefslogtreecommitdiff
path: root/src/cmd/cc/lex.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/cc/lex.c')
-rw-r--r--src/cmd/cc/lex.c1593
1 files changed, 0 insertions, 1593 deletions
diff --git a/src/cmd/cc/lex.c b/src/cmd/cc/lex.c
deleted file mode 100644
index 7c9f718c0..000000000
--- a/src/cmd/cc/lex.c
+++ /dev/null
@@ -1,1593 +0,0 @@
-// Inferno utils/cc/lex.c
-// http://code.google.com/p/inferno-os/source/browse/utils/cc/lex.c
-//
-// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
-// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
-// Portions Copyright © 1997-1999 Vita Nuova Limited
-// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-// Portions Copyright © 2004,2006 Bruce Ellis
-// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
-// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-// Portions Copyright © 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include <u.h>
-#include "cc.h"
-#include "y.tab.h"
-#include "../ld/textflag.h"
-
-#ifndef CPP
-#define CPP "cpp"
-#endif
-
-int
-systemtype(int sys)
-{
-#ifdef _WIN32
- return sys&Windows;
-#else
- return sys&Plan9;
-#endif
-}
-
-int
-pathchar(void)
-{
- return '/';
-}
-
-/*
- * known debug flags
- * -a acid declaration output
- * -A !B
- * -B non ANSI
- * -d print declarations
- * -D name define
- * -F format specification check
- * -G print pgen stuff
- * -g print cgen trees
- * -i print initialization
- * -I path include
- * -l generate little-endian code
- * -L print every NAME symbol
- * -M constant multiplication
- * -m print add/sub/mul trees
- * -n print acid or godefs to file (%.c=%.acid) (with -a or -aa)
- * -o file output file
- * -p use standard cpp ANSI preprocessor (not on windows)
- * -p something with peepholes
- * -q print equivalent Go code for variables and types (lower-case identifiers)
- * -Q print equivalent Go code for variables and types (upper-case identifiers)
- * -r print registerization
- * -s print structure offsets (with -a or -aa)
- * -S print assembly
- * -t print type trees
- * -V enable void* conversion warnings
- * -v verbose printing
- * -w print warnings
- * -X abort on error
- * -. Inhibit search for includes in source directory
- */
-
-void
-usage(void)
-{
- print("usage: %cc [options] file.c...\n", thechar);
- flagprint(1);
- errorexit();
-}
-
-void
-dospim(void)
-{
- thechar = '0';
- thestring = "spim";
-}
-
-char **defs;
-int ndef;
-
-void
-dodef(char *p)
-{
- if(ndef%8 == 0)
- defs = allocn(defs, ndef*sizeof(char *),
- 8*sizeof(char *));
- defs[ndef++] = p;
- dodefine(p);
-}
-
-void
-main(int argc, char *argv[])
-{
- int c;
- char *p;
-
- // Allow GOARCH=thestring or GOARCH=thestringsuffix,
- // but not other values.
- p = getgoarch();
- if(strncmp(p, thestring, strlen(thestring)) != 0)
- sysfatal("cannot use %cc with GOARCH=%s", thechar, p);
- if(strcmp(p, "amd64p32") == 0) // must be before cinit
- ewidth[TIND] = 4;
-
- nacl = strcmp(getgoos(), "nacl") == 0;
- if(nacl)
- flag_largemodel = 1;
-
- quotefmtinstall(); // before cinit, which overrides %Q
-
- linkarchinit();
- ctxt = linknew(thelinkarch);
- ctxt->diag = yyerror;
- ctxt->bso = &bstdout;
- Binit(&bstdout, 1, OWRITE);
-
- ensuresymb(NSYMB);
- memset(debug, 0, sizeof(debug));
- tinit();
- cinit();
- ginit();
- arginit();
-
- fmtstrinit(&pragcgobuf);
-
- tufield = simplet((1L<<tfield->etype) | BUNSIGNED);
- ndef = 0;
- defs = nil;
- outfile = 0;
- setinclude(".");
-
- flagcount("+", "pass -+ to preprocessor", &debug['+']);
- flagcount(".", "pass -. to preprocessor", &debug['.']);
- flagcount("<", "debug shift", &debug['<']);
- flagcount("A", "debug alignment", &debug['A']);
- flagcount("B", "allow pre-ANSI code", &debug['B']);
- if(thechar == '5')
- flagcount("C", "debug constant propagation", &debug['C']);
- flagfn1("D", "name[=value]: add #define", dodef);
- flagcount("F", "enable print format checks", &debug['F']);
- if(thechar == '5')
- flagcount("H", "debug shift propagation", &debug['H']);
- flagfn1("I", "dir: add dir to include path", setinclude);
- flagcount("L", "debug lexer", &debug['L']);
- flagcount("M", "debug move generation", &debug['M']);
- flagcount("N", "disable optimizations", &debug['N']);
- flagcount("P", "debug peephole optimizer", &debug['P']);
- flagcount("Q", "print exported Go definitions", &debug['Q']);
- flagcount("R", "debug register optimizer", &debug['R']);
- flagcount("S", "print assembly", &debug['S']);
- flagcount("T", "enable type signatures", &debug['T']);
- flagcount("V", "enable pointer type checks", &debug['V']);
- flagcount("W", "debug switch generation", &debug['W']);
- flagcount("X", "abort on error", &debug['X']);
- flagcount("Y", "debug index generation", &debug['Y']);
- flagcount("Z", "skip code generation", &debug['Z']);
- flagcount("a", "print acid definitions", &debug['a']);
- flagcount("c", "debug constant evaluation", &debug['c']);
- flagcount("d", "debug declarations", &debug['d']);
- flagcount("e", "debug macro expansion", &debug['e']);
- flagcount("f", "debug pragmas", &debug['f']);
- flagcount("g", "debug code generation", &debug['g']);
- flagcount("i", "debug initialization", &debug['i']);
- if(thechar == 'v')
- flagfn0("l", "little-endian mips mode", dospim);
- flagcount("m", "debug multiplication", &debug['m']);
- flagcount("n", "print acid/Go to file, not stdout", &debug['n']);
- flagstr("o", "file: set output file", &outfile);
- flagcount("p", "invoke C preprocessor", &debug['p']);
- flagcount("q", "print Go definitions", &debug['q']);
- flagcount("s", "print #define assembly offsets", &debug['s']);
- flagcount("t", "debug code generation", &debug['t']);
- flagstr("trimpath", "prefix: remove prefix from recorded source file paths", &ctxt->trimpath);
- flagcount("w", "enable warnings", &debug['w']);
- flagcount("v", "increase debug verbosity", &debug['v']);
- if(thechar == '6')
- flagcount("largemodel", "generate code that assumes a large memory model", &flag_largemodel);
-
- flagparse(&argc, &argv, usage);
- ctxt->debugasm = debug['S'];
- ctxt->debugvlog = debug['v'];
-
- if(argc < 1 && outfile == 0)
- usage();
-
- if(argc > 1){
- print("can't compile multiple files\n");
- errorexit();
- }
-
- if(argc == 0)
- c = compile("stdin", defs, ndef);
- else
- c = compile(argv[0], defs, ndef);
-
- Bflush(&bstdout);
- if(c)
- errorexit();
- exits(0);
-}
-
-int
-compile(char *file, char **defs, int ndef)
-{
- char *ofile;
- char *p, **av, opt[256];
- int i, c, fd[2];
- static int first = 1;
-
- ofile = alloc(strlen(file)+10);
- strcpy(ofile, file);
- p = utfrrune(ofile, pathchar());
- if(p) {
- *p++ = 0;
- if(!debug['.'])
- include[0] = strdup(ofile);
- } else
- p = ofile;
-
- if(outfile == 0) {
- outfile = p;
- if(outfile) {
- if(p = utfrrune(outfile, '.'))
- if(p[1] == 'c' && p[2] == 0)
- p[0] = 0;
- p = utfrune(outfile, 0);
- if(debug['a'] && debug['n'])
- strcat(p, ".acid");
- else if((debug['q'] || debug['Q']) && debug['n'])
- strcat(p, ".go");
- else {
- p[0] = '.';
- p[1] = thechar;
- p[2] = 0;
- }
- } else
- outfile = "/dev/null";
- }
-
- if (first)
- Binit(&diagbuf, 1, OWRITE);
- /*
- * if we're writing acid to standard output, don't keep scratching
- * outbuf.
- */
- if((debug['a'] || debug['q'] || debug['Q']) && !debug['n']) {
- if (first) {
- outfile = 0;
- Binit(&outbuf, dup(1, -1), OWRITE);
- dup(2, 1);
- }
- } else {
- c = create(outfile, OWRITE, 0664);
- if(c < 0) {
- diag(Z, "cannot open %s - %r", outfile);
- outfile = 0;
- errorexit();
- }
- Binit(&outbuf, c, OWRITE);
- outfile = strdup(outfile);
- }
- newio();
- first = 0;
-
- /* Use an ANSI preprocessor */
- if(debug['p']) {
- if(systemtype(Windows)) {
- diag(Z, "-p option not supported on windows");
- errorexit();
- }
- if(access(file, AREAD) < 0) {
- diag(Z, "%s does not exist", file);
- errorexit();
- }
- if(pipe(fd) < 0) {
- diag(Z, "pipe failed");
- errorexit();
- }
- switch(fork()) {
- case -1:
- diag(Z, "fork failed");
- errorexit();
- case 0:
- close(fd[0]);
- dup(fd[1], 1);
- close(fd[1]);
- av = alloc((ndef+ninclude+5)*sizeof(char *));
- av[0] = CPP;
- i = 1;
- if(debug['.']){
- sprint(opt, "-.");
- av[i++] = strdup(opt);
- }
- if(debug['+']) {
- sprint(opt, "-+");
- av[i++] = strdup(opt);
- }
- for(c = 0; c < ndef; c++)
- av[i++] = smprint("-D%s", defs[c]);
- for(c = 0; c < ninclude; c++)
- av[i++] = smprint("-I%s", include[c]);
- if(strcmp(file, "stdin") != 0)
- av[i++] = file;
- av[i] = 0;
- if(debug['p'] > 1) {
- for(c = 0; c < i; c++)
- fprint(2, "%s ", av[c]);
- fprint(2, "\n");
- }
- exec(av[0], av);
- fprint(2, "can't exec C preprocessor %s: %r\n", CPP);
- errorexit();
- default:
- close(fd[1]);
- newfile(file, fd[0]);
- break;
- }
- } else {
- if(strcmp(file, "stdin") == 0)
- newfile(file, 0);
- else
- newfile(file, -1);
- }
- yyparse();
- if(!debug['a'] && !debug['q'] && !debug['Q'])
- gclean();
- return nerrors;
-}
-
-void
-errorexit(void)
-{
- Bflush(&bstdout);
- if(outfile)
- remove(outfile);
- exits("error");
-}
-
-void
-pushio(void)
-{
- Io *i;
-
- i = iostack;
- if(i == I) {
- yyerror("botch in pushio");
- errorexit();
- }
- i->p = fi.p;
- i->c = fi.c;
-}
-
-void
-newio(void)
-{
- Io *i;
- static int pushdepth = 0;
-
- i = iofree;
- if(i == I) {
- pushdepth++;
- if(pushdepth > 1000) {
- yyerror("macro/io expansion too deep");
- errorexit();
- }
- i = alloc(sizeof(*i));
- } else
- iofree = i->link;
- i->c = 0;
- i->f = -1;
- ionext = i;
-}
-
-void
-newfile(char *s, int f)
-{
- Io *i;
-
- if(debug['e'])
- print("%L: %s\n", lineno, s);
-
- i = ionext;
- i->link = iostack;
- iostack = i;
- i->f = f;
- if(f < 0)
- i->f = open(s, 0);
- if(i->f < 0) {
- yyerror("%cc: %r: %s", thechar, s);
- errorexit();
- }
- fi.c = 0;
- linklinehist(ctxt, lineno, s, 0);
-}
-
-Sym*
-slookup(char *s)
-{
- ensuresymb(strlen(s));
- strcpy(symb, s);
- return lookup();
-}
-
-Sym*
-lookup(void)
-{
- Sym *s;
- uint32 h;
- char *p;
- int c, n;
- char *r, *w;
-
- if((uchar)symb[0] == 0xc2 && (uchar)symb[1] == 0xb7) {
- // turn leading · into ""·
- h = strlen(symb);
- ensuresymb(h+2);
- memmove(symb+2, symb, h+1);
- symb[0] = '"';
- symb[1] = '"';
- }
-
- for(r=w=symb; *r; r++) {
- // turn · (U+00B7) into .
- // turn ∕ (U+2215) into /
- if((uchar)*r == 0xc2 && (uchar)*(r+1) == 0xb7) {
- *w++ = '.';
- r++;
- }else if((uchar)*r == 0xe2 && (uchar)*(r+1) == 0x88 && (uchar)*(r+2) == 0x95) {
- *w++ = '/';
- r++;
- r++;
- }else
- *w++ = *r;
- }
- *w = '\0';
-
- h = 0;
- for(p=symb; *p;) {
- h = h * 3;
- h += *p++;
- }
- n = (p - symb) + 1;
- h &= 0xffffff;
- h %= NHASH;
- c = symb[0];
- for(s = hash[h]; s != S; s = s->link) {
- if(s->name[0] != c)
- continue;
- if(strcmp(s->name, symb) == 0)
- return s;
- }
- s = alloc(sizeof(*s));
- s->name = alloc(n);
- memmove(s->name, symb, n);
- s->link = hash[h];
- hash[h] = s;
- syminit(s);
-
- return s;
-}
-
-void
-syminit(Sym *s)
-{
- s->lexical = LNAME;
- s->block = 0;
- s->offset = 0;
- s->type = T;
- s->suetag = T;
- s->class = CXXX;
- s->aused = 0;
- s->sig = SIGNONE;
-}
-
-#define EOF (-1)
-#define IGN (-2)
-#define ESC (1<<20)
-#define GETC() ((--fi.c < 0)? filbuf(): (*fi.p++ & 0xff))
-
-enum
-{
- Numdec = 1<<0,
- Numlong = 1<<1,
- Numuns = 1<<2,
- Numvlong = 1<<3,
- Numflt = 1<<4,
-};
-
-int32
-yylex(void)
-{
- vlong vv;
- int32 c, c1, t;
- char *cp;
- Rune rune;
- Sym *s;
-
- if(peekc != IGN) {
- c = peekc;
- peekc = IGN;
- goto l1;
- }
-l0:
- c = GETC();
-
-l1:
- if(c >= Runeself) {
- /*
- * extension --
- * all multibyte runes are alpha
- */
- cp = symb;
- goto talph;
- }
- if(isspace(c)) {
- if(c == '\n')
- lineno++;
- goto l0;
- }
- if(isalpha(c)) {
- cp = symb;
- if(c != 'L')
- goto talph;
- *cp++ = c;
- c = GETC();
- if(c == '\'') {
- /* L'x' */
- c = escchar('\'', 1, 0);
- if(c == EOF)
- c = '\'';
- c1 = escchar('\'', 1, 0);
- if(c1 != EOF) {
- yyerror("missing '");
- peekc = c1;
- }
- yylval.vval = convvtox(c, TRUNE);
- return LUCONST;
- }
- if(c == '"') {
- goto caselq;
- }
- goto talph;
- }
- if(isdigit(c))
- goto tnum;
- switch(c)
- {
-
- case EOF:
- peekc = EOF;
- return -1;
-
- case '_':
- cp = symb;
- goto talph;
-
- case '#':
- domacro();
- goto l0;
-
- case '.':
- c1 = GETC();
- if(isdigit(c1)) {
- cp = symb;
- *cp++ = c;
- c = c1;
- c1 = 0;
- goto casedot;
- }
- break;
-
- case '"':
- strcpy(symb, "\"<string>\"");
- cp = alloc(0);
- c1 = 0;
-
- /* "..." */
- for(;;) {
- c = escchar('"', 0, 1);
- if(c == EOF)
- break;
- if(c & ESC) {
- cp = allocn(cp, c1, 1);
- cp[c1++] = c;
- } else {
- rune = c;
- c = runelen(rune);
- cp = allocn(cp, c1, c);
- runetochar(cp+c1, &rune);
- c1 += c;
- }
- }
- yylval.sval.l = c1;
- do {
- cp = allocn(cp, c1, 1);
- cp[c1++] = 0;
- } while(c1 & MAXALIGN);
- yylval.sval.s = cp;
- return LSTRING;
-
- caselq:
- /* L"..." */
- strcpy(symb, "\"L<string>\"");
- cp = alloc(0);
- c1 = 0;
- for(;;) {
- c = escchar('"', 1, 0);
- if(c == EOF)
- break;
- cp = allocn(cp, c1, sizeof(TRune));
- *(TRune*)(cp + c1) = c;
- c1 += sizeof(TRune);
- }
- yylval.sval.l = c1;
- do {
- cp = allocn(cp, c1, sizeof(TRune));
- *(TRune*)(cp + c1) = 0;
- c1 += sizeof(TRune);
- } while(c1 & MAXALIGN);
- yylval.sval.s = cp;
- return LLSTRING;
-
- case '\'':
- /* '.' */
- c = escchar('\'', 0, 0);
- if(c == EOF)
- c = '\'';
- c1 = escchar('\'', 0, 0);
- if(c1 != EOF) {
- yyerror("missing '");
- peekc = c1;
- }
- vv = c;
- yylval.vval = convvtox(vv, TUCHAR);
- if(yylval.vval != vv)
- yyerror("overflow in character constant: 0x%x", c);
- else
- if(c & 0x80){
- nearln = lineno;
- warn(Z, "sign-extended character constant");
- }
- yylval.vval = convvtox(vv, TCHAR);
- return LCONST;
-
- case '/':
- c1 = GETC();
- if(c1 == '*') {
- for(;;) {
- c = getr();
- while(c == '*') {
- c = getr();
- if(c == '/')
- goto l0;
- }
- if(c == EOF) {
- yyerror("eof in comment");
- errorexit();
- }
- }
- }
- if(c1 == '/') {
- for(;;) {
- c = getr();
- if(c == '\n')
- goto l0;
- if(c == EOF) {
- yyerror("eof in comment");
- errorexit();
- }
- }
- }
- if(c1 == '=')
- return LDVE;
- break;
-
- case '*':
- c1 = GETC();
- if(c1 == '=')
- return LMLE;
- break;
-
- case '%':
- c1 = GETC();
- if(c1 == '=')
- return LMDE;
- break;
-
- case '+':
- c1 = GETC();
- if(c1 == '+')
- return LPP;
- if(c1 == '=')
- return LPE;
- break;
-
- case '-':
- c1 = GETC();
- if(c1 == '-')
- return LMM;
- if(c1 == '=')
- return LME;
- if(c1 == '>')
- return LMG;
- break;
-
- case '>':
- c1 = GETC();
- if(c1 == '>') {
- c = LRSH;
- c1 = GETC();
- if(c1 == '=')
- return LRSHE;
- break;
- }
- if(c1 == '=')
- return LGE;
- break;
-
- case '<':
- c1 = GETC();
- if(c1 == '<') {
- c = LLSH;
- c1 = GETC();
- if(c1 == '=')
- return LLSHE;
- break;
- }
- if(c1 == '=')
- return LLE;
- break;
-
- case '=':
- c1 = GETC();
- if(c1 == '=')
- return LEQ;
- break;
-
- case '!':
- c1 = GETC();
- if(c1 == '=')
- return LNE;
- break;
-
- case '&':
- c1 = GETC();
- if(c1 == '&')
- return LANDAND;
- if(c1 == '=')
- return LANDE;
- break;
-
- case '|':
- c1 = GETC();
- if(c1 == '|')
- return LOROR;
- if(c1 == '=')
- return LORE;
- break;
-
- case '^':
- c1 = GETC();
- if(c1 == '=')
- return LXORE;
- break;
-
- default:
- return c;
- }
- peekc = c1;
- return c;
-
-talph:
- /*
- * cp is set to symb and some
- * prefix has been stored
- */
- for(;;) {
- if(c >= Runeself) {
- for(c1=0;;) {
- cp[c1++] = c;
- if(fullrune(cp, c1))
- break;
- c = GETC();
- }
- cp += c1;
- c = GETC();
- continue;
- }
- if(!isalnum(c) && c != '_')
- break;
- *cp++ = c;
- c = GETC();
- }
- *cp = 0;
- if(debug['L'])
- print("%L: %s\n", lineno, symb);
- peekc = c;
- s = lookup();
- if(s->macro) {
- newio();
- cp = ionext->b;
- macexpand(s, cp);
- pushio();
- ionext->link = iostack;
- iostack = ionext;
- fi.p = cp;
- fi.c = strlen(cp);
- if(peekc != IGN) {
- cp[fi.c++] = peekc;
- cp[fi.c] = 0;
- peekc = IGN;
- }
- goto l0;
- }
- yylval.sym = s;
- if(s->class == CTYPEDEF || s->class == CTYPESTR)
- return LTYPE;
- return s->lexical;
-
-tnum:
- c1 = 0;
- cp = symb;
- if(c != '0') {
- c1 |= Numdec;
- for(;;) {
- *cp++ = c;
- c = GETC();
- if(isdigit(c))
- continue;
- goto dc;
- }
- }
- *cp++ = c;
- c = GETC();
- if(c == 'x' || c == 'X')
- for(;;) {
- *cp++ = c;
- c = GETC();
- if(isdigit(c))
- continue;
- if(c >= 'a' && c <= 'f')
- continue;
- if(c >= 'A' && c <= 'F')
- continue;
- if(cp == symb+2)
- yyerror("malformed hex constant");
- goto ncu;
- }
- if(c < '0' || c > '7')
- goto dc;
- for(;;) {
- if(c >= '0' && c <= '7') {
- *cp++ = c;
- c = GETC();
- continue;
- }
- goto ncu;
- }
-
-dc:
- if(c == '.')
- goto casedot;
- if(c == 'e' || c == 'E')
- goto casee;
-
-ncu:
- if((c == 'U' || c == 'u') && !(c1 & Numuns)) {
- c = GETC();
- c1 |= Numuns;
- goto ncu;
- }
- if((c == 'L' || c == 'l') && !(c1 & Numvlong)) {
- c = GETC();
- if(c1 & Numlong)
- c1 |= Numvlong;
- c1 |= Numlong;
- goto ncu;
- }
- *cp = 0;
- peekc = c;
- if(mpatov(symb, &yylval.vval))
- yyerror("overflow in constant");
-
- vv = yylval.vval;
- if(c1 & Numvlong) {
- if((c1 & Numuns) || convvtox(vv, TVLONG) < 0) {
- c = LUVLCONST;
- t = TUVLONG;
- goto nret;
- }
- c = LVLCONST;
- t = TVLONG;
- goto nret;
- }
- if(c1 & Numlong) {
- if((c1 & Numuns) || convvtox(vv, TLONG) < 0) {
- c = LULCONST;
- t = TULONG;
- goto nret;
- }
- c = LLCONST;
- t = TLONG;
- goto nret;
- }
- if((c1 & Numuns) || convvtox(vv, TINT) < 0) {
- c = LUCONST;
- t = TUINT;
- goto nret;
- }
- c = LCONST;
- t = TINT;
- goto nret;
-
-nret:
- yylval.vval = convvtox(vv, t);
- if(yylval.vval != vv){
- nearln = lineno;
- warn(Z, "truncated constant: %T %s", types[t], symb);
- }
- return c;
-
-casedot:
- for(;;) {
- *cp++ = c;
- c = GETC();
- if(!isdigit(c))
- break;
- }
- if(c != 'e' && c != 'E')
- goto caseout;
-
-casee:
- *cp++ = 'e';
- c = GETC();
- if(c == '+' || c == '-') {
- *cp++ = c;
- c = GETC();
- }
- if(!isdigit(c))
- yyerror("malformed fp constant exponent");
- while(isdigit(c)) {
- *cp++ = c;
- c = GETC();
- }
-
-caseout:
- if(c == 'L' || c == 'l') {
- c = GETC();
- c1 |= Numlong;
- } else
- if(c == 'F' || c == 'f') {
- c = GETC();
- c1 |= Numflt;
- }
- *cp = 0;
- peekc = c;
- yylval.dval = strtod(symb, nil);
- if(isInf(yylval.dval, 1) || isInf(yylval.dval, -1)) {
- yyerror("overflow in float constant");
- yylval.dval = 0;
- }
- if(c1 & Numflt)
- return LFCONST;
- return LDCONST;
-}
-
-/*
- * convert a string, s, to vlong in *v
- * return conversion overflow.
- * required syntax is [0[x]]d*
- */
-int
-mpatov(char *s, vlong *v)
-{
- vlong n, nn;
- int c;
-
- n = 0;
- c = *s;
- if(c == '0')
- goto oct;
- while(c = *s++) {
- if(c >= '0' && c <= '9')
- nn = n*10 + c-'0';
- else
- goto bad;
- if(n < 0 && nn >= 0)
- goto bad;
- n = nn;
- }
- goto out;
-
-oct:
- s++;
- c = *s;
- if(c == 'x' || c == 'X')
- goto hex;
- while(c = *s++) {
- if(c >= '0' || c <= '7')
- nn = n*8 + c-'0';
- else
- goto bad;
- if(n < 0 && nn >= 0)
- goto bad;
- n = nn;
- }
- goto out;
-
-hex:
- s++;
- while(c = *s++) {
- if(c >= '0' && c <= '9')
- c += 0-'0';
- else
- if(c >= 'a' && c <= 'f')
- c += 10-'a';
- else
- if(c >= 'A' && c <= 'F')
- c += 10-'A';
- else
- goto bad;
- nn = (uvlong)n*16 + c;
- if(n < 0 && nn >= 0)
- goto bad;
- n = nn;
- }
-out:
- *v = n;
- return 0;
-
-bad:
- *v = ~0;
- return 1;
-}
-
-int
-getc(void)
-{
- int c;
-
- if(peekc != IGN) {
- c = peekc;
- peekc = IGN;
- } else
- c = GETC();
- if(c == '\n')
- lineno++;
- if(c == EOF) {
- yyerror("End of file");
- errorexit();
- }
- return c;
-}
-
-int32
-getr(void)
-{
- int c, i;
- char str[UTFmax+1];
- Rune rune;
-
-
- c = getc();
- if(c < Runeself)
- return c;
- i = 0;
- str[i++] = c;
-
-loop:
- c = getc();
- str[i++] = c;
- if(!fullrune(str, i))
- goto loop;
- c = chartorune(&rune, str);
- if(rune == Runeerror && c == 1) {
- nearln = lineno;
- diag(Z, "illegal rune in string");
- for(c=0; c<i; c++)
- print(" %.2x", *(uchar*)(str+c));
- print("\n");
- }
- return rune;
-}
-
-int
-getnsc(void)
-{
- int c;
-
- if(peekc != IGN) {
- c = peekc;
- peekc = IGN;
- } else
- c = GETC();
- for(;;) {
- if(c >= Runeself || !isspace(c))
- return c;
- if(c == '\n') {
- lineno++;
- return c;
- }
- c = GETC();
- }
-}
-
-void
-unget(int c)
-{
-
- peekc = c;
- if(c == '\n')
- lineno--;
-}
-
-int32
-escchar(int32 e, int longflg, int escflg)
-{
- int32 c, l;
- int i;
-
-loop:
- c = getr();
- if(c == '\n') {
- yyerror("newline in string");
- return EOF;
- }
- if(c != '\\') {
- if(c == e)
- c = EOF;
- return c;
- }
- c = getr();
- if(c == 'x') {
- /*
- * note this is not ansi,
- * supposed to only accept 2 hex
- */
- i = 2;
- if(longflg)
- i = 6;
- l = 0;
- for(; i>0; i--) {
- c = getc();
- if(c >= '0' && c <= '9') {
- l = l*16 + c-'0';
- continue;
- }
- if(c >= 'a' && c <= 'f') {
- l = l*16 + c-'a' + 10;
- continue;
- }
- if(c >= 'A' && c <= 'F') {
- l = l*16 + c-'A' + 10;
- continue;
- }
- unget(c);
- break;
- }
- if(escflg)
- l |= ESC;
- return l;
- }
- if(c >= '0' && c <= '7') {
- /*
- * note this is not ansi,
- * supposed to only accept 3 oct
- */
- i = 2;
- if(longflg)
- i = 8;
- l = c - '0';
- for(; i>0; i--) {
- c = getc();
- if(c >= '0' && c <= '7') {
- l = l*8 + c-'0';
- continue;
- }
- unget(c);
- }
- if(escflg)
- l |= ESC;
- return l;
- }
- switch(c)
- {
- case '\n': goto loop;
- case 'n': return '\n';
- case 't': return '\t';
- case 'b': return '\b';
- case 'r': return '\r';
- case 'f': return '\f';
- case 'a': return '\a';
- case 'v': return '\v';
- }
- return c;
-}
-
-struct
-{
- char *name;
- ushort lexical;
- ushort type;
-} itab[] =
-{
- "auto", LAUTO, 0,
- "break", LBREAK, 0,
- "case", LCASE, 0,
- "char", LCHAR, TCHAR,
- "const", LCONSTNT, 0,
- "continue", LCONTINUE, 0,
- "default", LDEFAULT, 0,
- "do", LDO, 0,
- "double", LDOUBLE, TDOUBLE,
- "else", LELSE, 0,
- "enum", LENUM, 0,
- "extern", LEXTERN, 0,
- "float", LFLOAT, TFLOAT,
- "for", LFOR, 0,
- "goto", LGOTO, 0,
- "if", LIF, 0,
- "inline", LINLINE, 0,
- "int", LINT, TINT,
- "long", LLONG, TLONG,
- "PREFETCH", LPREFETCH, 0,
- "register", LREGISTER, 0,
- "restrict", LRESTRICT, 0,
- "return", LRETURN, 0,
- "SET", LSET, 0,
- "short", LSHORT, TSHORT,
- "signed", LSIGNED, 0,
- "signof", LSIGNOF, 0,
- "sizeof", LSIZEOF, 0,
- "static", LSTATIC, 0,
- "struct", LSTRUCT, 0,
- "switch", LSWITCH, 0,
- "typedef", LTYPEDEF, 0,
- "typestr", LTYPESTR, 0,
- "union", LUNION, 0,
- "unsigned", LUNSIGNED, 0,
- "USED", LUSED, 0,
- "void", LVOID, TVOID,
- "volatile", LVOLATILE, 0,
- "while", LWHILE, 0,
- 0
-};
-
-void
-cinit(void)
-{
- Sym *s;
- int i;
- Type *t;
-
- nerrors = 0;
- lineno = 1;
- iostack = I;
- iofree = I;
- peekc = IGN;
- nhunk = 0;
-
- types[TXXX] = T;
- types[TCHAR] = typ(TCHAR, T);
- types[TUCHAR] = typ(TUCHAR, T);
- types[TSHORT] = typ(TSHORT, T);
- types[TUSHORT] = typ(TUSHORT, T);
- types[TINT] = typ(TINT, T);
- types[TUINT] = typ(TUINT, T);
- types[TLONG] = typ(TLONG, T);
- types[TULONG] = typ(TULONG, T);
- types[TVLONG] = typ(TVLONG, T);
- types[TUVLONG] = typ(TUVLONG, T);
- types[TFLOAT] = typ(TFLOAT, T);
- types[TDOUBLE] = typ(TDOUBLE, T);
- types[TVOID] = typ(TVOID, T);
- types[TENUM] = typ(TENUM, T);
- types[TFUNC] = typ(TFUNC, types[TINT]);
- types[TIND] = typ(TIND, types[TVOID]);
-
- for(i=0; i<NHASH; i++)
- hash[i] = S;
- for(i=0; itab[i].name; i++) {
- s = slookup(itab[i].name);
- s->lexical = itab[i].lexical;
- if(itab[i].type != 0)
- s->type = types[itab[i].type];
- }
- blockno = 0;
- autobn = 0;
- autoffset = 0;
-
- t = typ(TARRAY, types[TCHAR]);
- t->width = 0;
- symstring = slookup(".string");
- symstring->class = CSTATIC;
- symstring->dataflag = NOPTR;
- symstring->type = t;
-
- t = typ(TARRAY, types[TCHAR]);
- t->width = 0;
-
- nodproto = new(OPROTO, Z, Z);
- dclstack = D;
-
- fmtinstall('O', Oconv);
- fmtinstall('T', Tconv);
- fmtinstall('F', FNconv);
- fmtinstall('L', Lconv);
- fmtinstall('Q', Qconv);
- fmtinstall('|', VBconv);
- fmtinstall('U', Uconv);
- fmtinstall('B', Bconv);
-}
-
-int
-filbuf(void)
-{
- Io *i;
-
-loop:
- i = iostack;
- if(i == I)
- return EOF;
- if(i->f < 0)
- goto pop;
- fi.c = read(i->f, i->b, BUFSIZ) - 1;
- if(fi.c < 0) {
- close(i->f);
- linklinehist(ctxt, lineno, nil, 0);
- goto pop;
- }
- fi.p = i->b + 1;
- return i->b[0] & 0xff;
-
-pop:
- iostack = i->link;
- i->link = iofree;
- iofree = i;
- i = iostack;
- if(i == I)
- return EOF;
- fi.p = i->p;
- fi.c = i->c;
- if(--fi.c < 0)
- goto loop;
- return *fi.p++ & 0xff;
-}
-
-int
-Oconv(Fmt *fp)
-{
- int a;
-
- a = va_arg(fp->args, int);
- if(a < OXXX || a > OEND)
- return fmtprint(fp, "***badO %d***", a);
-
- return fmtstrcpy(fp, onames[a]);
-}
-
-int
-Lconv(Fmt *fp)
-{
- return linklinefmt(ctxt, fp);
-}
-
-int
-Tconv(Fmt *fp)
-{
- char str[STRINGSZ+20], s[STRINGSZ+20];
- Type *t, *t1;
- int et;
- int32 n;
-
- str[0] = 0;
- for(t = va_arg(fp->args, Type*); t != T; t = t->link) {
- et = t->etype;
- if(str[0])
- strcat(str, " ");
- if(t->garb&~GINCOMPLETE) {
- sprint(s, "%s ", gnames[t->garb&~GINCOMPLETE]);
- if(strlen(str) + strlen(s) < STRINGSZ)
- strcat(str, s);
- }
- sprint(s, "%s", tnames[et]);
- if(strlen(str) + strlen(s) < STRINGSZ)
- strcat(str, s);
- if(et == TFUNC && (t1 = t->down)) {
- sprint(s, "(%T", t1);
- if(strlen(str) + strlen(s) < STRINGSZ)
- strcat(str, s);
- while(t1 = t1->down) {
- sprint(s, ", %T", t1);
- if(strlen(str) + strlen(s) < STRINGSZ)
- strcat(str, s);
- }
- if(strlen(str) + strlen(s) < STRINGSZ)
- strcat(str, ")");
- }
- if(et == TARRAY) {
- n = t->width;
- if(t->link && t->link->width)
- n /= t->link->width;
- sprint(s, "[%d]", n);
- if(strlen(str) + strlen(s) < STRINGSZ)
- strcat(str, s);
- }
- if(t->nbits) {
- sprint(s, " %d:%d", t->shift, t->nbits);
- if(strlen(str) + strlen(s) < STRINGSZ)
- strcat(str, s);
- }
- if(typesu[et]) {
- if(t->tag) {
- strcat(str, " ");
- if(strlen(str) + strlen(t->tag->name) < STRINGSZ)
- strcat(str, t->tag->name);
- } else
- strcat(str, " {}");
- break;
- }
- }
- return fmtstrcpy(fp, str);
-}
-
-int
-FNconv(Fmt *fp)
-{
- char *str;
- Node *n;
-
- n = va_arg(fp->args, Node*);
- str = "<indirect>";
- if(n != Z && (n->op == ONAME || n->op == ODOT || n->op == OELEM))
- str = n->sym->name;
- return fmtstrcpy(fp, str);
-}
-
-int
-Qconv(Fmt *fp)
-{
- char str[STRINGSZ+20], *s;
- int32 b;
- int i;
-
- str[0] = 0;
- for(b = va_arg(fp->args, int32); b;) {
- i = bitno(b);
- if(str[0])
- strcat(str, " ");
- s = qnames[i];
- if(strlen(str) + strlen(s) >= STRINGSZ)
- break;
- strcat(str, s);
- b &= ~(1L << i);
- }
- return fmtstrcpy(fp, str);
-}
-
-int
-VBconv(Fmt *fp)
-{
- char str[STRINGSZ];
- int i, n, t, pc;
-
- n = va_arg(fp->args, int);
- pc = 0; /* BUG: was printcol */
- i = 0;
- while(pc < n) {
- t = (pc+4) & ~3;
- if(t <= n) {
- str[i++] = '\t';
- pc = t;
- continue;
- }
- str[i++] = ' ';
- pc++;
- }
- str[i] = 0;
-
- return fmtstrcpy(fp, str);
-}
-
-int
-Bconv(Fmt *fp)
-{
- char str[STRINGSZ], ss[STRINGSZ], *s;
- Bits bits;
- int i;
-
- str[0] = 0;
- bits = va_arg(fp->args, Bits);
- while(bany(&bits)) {
- i = bnum(bits);
- if(str[0])
- strcat(str, " ");
- if(var[i].sym == nil) {
- sprint(ss, "$%lld", var[i].offset);
- s = ss;
- } else
- s = var[i].sym->name;
- if(strlen(str) + strlen(s) + 1 >= STRINGSZ)
- break;
- strcat(str, s);
- bits.b[i/32] &= ~(1L << (i%32));
- }
- return fmtstrcpy(fp, str);
-}
-
-void
-setinclude(char *p)
-{
- int i;
-
- if(*p != 0) {
- for(i=1; i < ninclude; i++)
- if(strcmp(p, include[i]) == 0)
- return;
-
- if(ninclude%8 == 0)
- include = allocn(include, ninclude*sizeof(char *),
- 8*sizeof(char *));
- include[ninclude++] = p;
- }
-}
-
-void*
-alloc(int32 n)
-{
- void *p;
-
- p = malloc(n);
- if(p == nil) {
- print("alloc out of mem\n");
- exits("alloc: out of mem");
- }
- memset(p, 0, n);
- return p;
-}
-
-void*
-allocn(void *p, int32 n, int32 d)
-{
- if(p == nil)
- return alloc(n+d);
- p = realloc(p, n+d);
- if(p == nil) {
- print("allocn out of mem\n");
- exits("allocn: out of mem");
- }
- if(d > 0)
- memset((char*)p+n, 0, d);
- return p;
-}
-
-void
-ensuresymb(int32 n)
-{
- if(symb == nil) {
- symb = alloc(NSYMB+1);
- nsymb = NSYMB;
- }
-
- if(n > nsymb) {
- symb = allocn(symb, nsymb, n+1-nsymb);
- nsymb = n;
- }
-}