text: // Copyright 2012 The Go Authors.  All rights reserved.
  // Use of this source code is governed by a BSD-style
  // license that can be found in the LICENSE file.
  
  #include "a.h"
  
  /*
   * Helpers for building cmd/gc.
   */
  
  // gcopnames creates opnames.h from go.h.
  // It finds the OXXX enum, pulls out all the constants
  // from OXXX to OEND, and writes a table mapping
  // op to string.
  void
  gcopnames(char *dir, char *file)
  {
  	char *p, *q;
  	int i, j, end;
  	Buf in, b, out;
  	Vec lines, fields;
  	
  	binit(&in);
  	binit(&b);
  	binit(&out);
  	vinit(&lines);
  	vinit(&fields);
  	
  	bwritestr(&out, bprintf(&b, "// auto generated by go tool dist\n"));
  	bwritestr(&out, bprintf(&b, "static char *opnames[] = {\n"));
  
  	readfile(&in, bprintf(&b, "%s/go.h", dir));
  	splitlines(&lines, bstr(&in));
  	i = 0;
  	while(i<lines.len && !contains(lines.p[i], "OXXX"))
  		i++;
  	end = 0;
  	for(; i<lines.len && !end; i++) {
  		p = xstrstr(lines.p[i], "//");
  		if(p != nil)
  			*p = '\0';
  		end = contains(lines.p[i], "OEND");
  		splitfields(&fields, lines.p[i]);
  		for(j=0; j<fields.len; j++) {
  			q = fields.p[j];
  			if(*q == 'O')
  				q++;
  			p = q+xstrlen(q)-1;
  			if(*p == ',')
  				*p = '\0';
  			bwritestr(&out, bprintf(&b, "	[O%s] = \"%s\",\n", q, q));
  		}
  	}
  	
  	bwritestr(&out, bprintf(&b, "};\n"));
  
  	writefile(&out, file, 0);
  
  	bfree(&in);
  	bfree(&b);
  	bfree(&out);
  	vfree(&lines);
  	vfree(&fields);
  }
  
  // mkanames reads [568].out.h and writes anames[568].c
  // The format is much the same as the Go opcodes above.
  // it also writes out cnames array for C_* constants.
  void
  mkanames(char *dir, char *file)
  {
  	int i, j, ch;
  	Buf in, b, out, out2;
  	Vec lines;
  	char *p;
  
  	binit(&b);
  	binit(&in);
  	binit(&out);
  	binit(&out2);
  	vinit(&lines);
  
  	ch = file[xstrlen(file)-3];
  	bprintf(&b, "%s/../cmd/%cl/%c.out.h", dir, ch, ch);
  	readfile(&in, bstr(&b));
  	splitlines(&lines, bstr(&in));
  	
  	// Include link.h so that the extern declaration there is
  	// checked against the non-extern declaration we are generating.
  	bwritestr(&out, bprintf(&b, "#include <u.h>\n"));
  	bwritestr(&out, bprintf(&b, "#include <libc.h>\n"));
  	bwritestr(&out, bprintf(&b, "#include <bio.h>\n"));
  	bwritestr(&out, bprintf(&b, "#include <link.h>\n"));
  	bwritestr(&out, bprintf(&b, "\n"));
  
  	bwritestr(&out, bprintf(&b, "char*	anames%c[] = {\n", ch));
  	for(i=0; i<lines.len; i++) {
  		if(hasprefix(lines.p[i], "\tA")) {
  			p = xstrstr(lines.p[i], ",");
  			if(p)
  				*p = '\0';
  			p = xstrstr(lines.p[i], "\n");
  			if(p)
  				*p = '\0';
  			p = lines.p[i] + 2;
  			bwritestr(&out, bprintf(&b, "\t\"%s\",\n", p));
  		}
  	}
  	bwritestr(&out, "};\n");
  
  	j=0;
  	bprintf(&out2, "char*	cnames%c[] = {\n", ch);
  	for(i=0; i<lines.len; i++) {
  		if(hasprefix(lines.p[i], "\tC_")) {
  			p = xstrstr(lines.p[i], ",");
  			if(p)
  				*p = '\0';
  			p = xstrstr(lines.p[i], "\n");
  			if(p)
  				*p = '\0';
  			p = lines.p[i] + 3;
  			bwritestr(&out2, bprintf(&b, "\t\"%s\",\n", p));
  			j++;
  		}
  	}
  	bwritestr(&out2, "};\n");
  	if(j>0)
  		bwriteb(&out, &out2);
  
  	writefile(&out, file, 0);
  
  	bfree(&b);
  	bfree(&in);
  	bfree(&out);
  	bfree(&out2);
  	vfree(&lines);
  }
  