示例#1
0
文件: utf.c 项目: droyo/APL
int main(void) {
	Rune r; char *s; int n = 0;
	Biobuf *i = Bfdopen(0,O_RDONLY);
	print("enum codepoints {");
	while((r=Bgetrune(i))>0 && r != '\n') {
		s = Brdline(i,'\n');
		if(!Blinelen(i)) break;
		s[Blinelen(i)-1] = '\0';
		*s = 'U';
		print("%s\n\t%-8s = 0x%X",n?",":"", s,r);
		n = 1;
	}
	print("\n};\n");
	Bterm(i);
	return 0;
}
示例#2
0
文件: main.c 项目: 8l/go-learn
void
main(int argc, char **argv)
{
	int p[2], pid, i, j, n, off, npad, prefix;
	char **av, *q, *r, *tofree, *name;
	char nambuf[100];
	Biobuf *bin, *bout;
	Type *t;
	Field *f;

	quotefmtinstall();

	oargc = argc;
	oargv = argv;
	av = emalloc((30+argc)*sizeof av[0]);
	atexit(waitforgcc);

	n = 0;
	av[n++] = "gcc";
	av[n++] = "-c";
	av[n++] = "-fdollars-in-identifiers";
	av[n++] = "-S";	// write assembly
	av[n++] = "-gstabs";	// include stabs info
	av[n++] = "-o-";	// to stdout
	av[n++] = "-xc";	// read C

	ARGBEGIN{
	case 'g':
		lang = &go;
		pkg = EARGF(usage());
		break;
	case 'c':
		av[0] = EARGF(usage());
		break;
	case 'f':
		av[n++] = EARGF(usage());
		break;
	default:
		usage();
	}ARGEND

	if(argc == 0)
		av[n++] = "-";
	else
		av[n++] = argv[0];
	av[n] = nil;

	// Run gcc writing assembly and stabs debugging to p[1].
	if(pipe(p) < 0)
		sysfatal("pipe: %r");

	pid = fork();
	if(pid < 0)
		sysfatal("fork: %r");
	if(pid == 0) {
		close(p[0]);
		dup(p[1], 1);
		if(argc == 0) {
			exec(av[0], av);
			fprint(2, "exec gcc: %r\n");
			exit(1);
		}
		// Some versions of gcc do not accept -S with multiple files.
		// Run gcc once for each file.
		close(0);
		open("/dev/null", OREAD);
		for(i=0; i<argc; i++) {
			pid = fork();
			if(pid < 0)
				sysfatal("fork: %r");
			if(pid == 0) {
				av[n-1] = argv[i];
				exec(av[0], av);
				fprint(2, "exec gcc: %r\n");
				exit(1);
			}
			waitpid();
		}
		exit(0);
	}
	close(p[1]);

	// Read assembly, pulling out .stabs lines.
	bin = Bfdopen(p[0], OREAD);
	while((q = Brdstr(bin, '\n', 1)) != nil) {
		//	.stabs	"float:t(0,12)=r(0,1);4;0;",128,0,0,0
		tofree = q;
		while(*q == ' ' || *q == '\t')
			q++;
		if(strncmp(q, ".stabs", 6) != 0)
			goto Continue;
		q += 6;
		while(*q == ' ' || *q == '\t')
			q++;
		if(*q++ != '\"') {
		Bad:
			sysfatal("cannot parse .stabs line:\n%s", tofree);
		}

		r = strchr(q, '\"');
		if(r == nil)
			goto Bad;
		*r++ = '\0';
		if(*r++ != ',')
			goto Bad;
		if(*r < '0' || *r > '9')
			goto Bad;
		if(atoi(r) != 128)	// stabs kind = local symbol
			goto Continue;

		parsestabtype(q);

	Continue:
		free(tofree);
	}
	Bterm(bin);
	waitpid();

	// Write defs to standard output.
	bout = Bfdopen(1, OWRITE);
	fmtinstall('T', lang->typefmt);

	// Echo original command line in header.
	Bprint(bout, "//");
	for(i=0; i<oargc; i++)
		Bprint(bout, " %q", oargv[i]);
	Bprint(bout, "\n");
	Bprint(bout, "\n");
	Bprint(bout, "// MACHINE GENERATED - DO NOT EDIT.\n");
	Bprint(bout, "\n");

	if(pkg)
		Bprint(bout, "package %s\n\n", pkg);

	// Constants.
	Bprint(bout, "// Constants\n");
	if(ncon > 0) {
		Bprint(bout, lang->constbegin);
		for(i=0; i<ncon; i++)
			Bprint(bout, lang->constfmt, con[i].name, con[i].value);
		Bprint(bout, lang->constend);
	}
	Bprint(bout, "\n");

	// Types

	// push our names down
	for(i=0; i<ntyp; i++) {
		t = typ[i];
		name = t->name;
		while(t && t->kind == Typedef)
			t = t->type;
		if(t)
			t->name = name;
	}

	Bprint(bout, "// Types\n");

	// Have to turn off structure padding in Plan 9 compiler,
	// mainly because it is more aggressive than gcc tends to be.
	if(lang == &c)
		Bprint(bout, "#pragma pack on\n");

	for(i=0; i<ntyp; i++) {
		Bprint(bout, "\n");
		t = typ[i];
		name = t->name;
		while(t && t->kind == Typedef) {
			if(name == nil && t->name != nil) {
				name = t->name;
				if(t->printed)
					break;
			}
			t = t->type;
		}
		if(name == nil && t->name != nil) {
			name = t->name;
			if(t->printed)
				continue;
			t->printed = 1;
		}
		if(name == nil) {
			fprint(2, "unknown name for %T", typ[i]);
			continue;
		}
		if(name[0] == '$')
			name++;
		npad = 0;
		off = 0;
		switch(t->kind) {
		case 0:
			fprint(2, "unknown type definition for %s\n", name);
			break;
		default:	// numeric, array, or pointer
		case Array:
		case Ptr:
			Bprint(bout, "%s %lT\n", lang->typdef, name, t);
			break;
		case Union:
			// In Go, print union as struct with only first element,
			// padded the rest of the way.
			Bprint(bout, lang->unionbegin, name, name, name);
			goto StructBody;
		case Struct:
			Bprint(bout, lang->structbegin, name, name, name);
		StructBody:
			prefix = 0;
			if(lang == &go)
				prefix = prefixlen(t);
			for(j=0; j<t->nf; j++) {
				f = &t->f[j];
				// padding
				if(t->kind == Struct || lang == &go) {
					if(f->offset%8 != 0 || f->size%8 != 0) {
						fprint(2, "ignoring bitfield %s.%s\n", t->name, f->name);
						continue;
					}
					if(f->offset < off)
						sysfatal("%s: struct fields went backward", t->name);
					if(off < f->offset) {
						Bprint(bout, lang->structpadfmt, npad++, (f->offset - off) / 8);
						off = f->offset;
					}
					off += f->size;
				}
				name = f->name;
				if(cutprefix(name))
					name += prefix;
				if(strcmp(name, "") == 0) {
					snprint(nambuf, sizeof nambuf, "Pad%d", npad++);
					name = nambuf;
				}
				Bprint(bout, "\t%#lT;\n", name, f->type);
				if(t->kind == Union && lang == &go)
					break;
			}
			// final padding
			if(t->kind == Struct || lang == &go) {
				if(off/8 < t->size)
					Bprint(bout, lang->structpadfmt, npad++, t->size - off/8);
			}
			Bprint(bout, lang->structend);
		}
	}
	if(lang == &c)
		Bprint(bout, "#pragma pack off\n");
	Bterm(bout);
	exit(0);
}