github.com/hbdrawn/golang@v0.0.0-20141214014649-6b835209aba2/src/cmd/dist/buildgc.c (about)

     1  // Copyright 2012 The Go Authors.  All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  #include "a.h"
     6  
     7  /*
     8   * Helpers for building cmd/gc.
     9   */
    10  
    11  // gcopnames creates opnames.h from go.h.
    12  // It finds the OXXX enum, pulls out all the constants
    13  // from OXXX to OEND, and writes a table mapping
    14  // op to string.
    15  void
    16  gcopnames(char *dir, char *file)
    17  {
    18  	char *p, *q;
    19  	int i, j, end;
    20  	Buf in, b, out;
    21  	Vec lines, fields;
    22  	
    23  	binit(&in);
    24  	binit(&b);
    25  	binit(&out);
    26  	vinit(&lines);
    27  	vinit(&fields);
    28  	
    29  	bwritestr(&out, bprintf(&b, "// auto generated by go tool dist\n"));
    30  	bwritestr(&out, bprintf(&b, "static char *opnames[] = {\n"));
    31  
    32  	readfile(&in, bprintf(&b, "%s/go.h", dir));
    33  	splitlines(&lines, bstr(&in));
    34  	i = 0;
    35  	while(i<lines.len && !contains(lines.p[i], "OXXX"))
    36  		i++;
    37  	end = 0;
    38  	for(; i<lines.len && !end; i++) {
    39  		p = xstrstr(lines.p[i], "//");
    40  		if(p != nil)
    41  			*p = '\0';
    42  		end = contains(lines.p[i], "OEND");
    43  		splitfields(&fields, lines.p[i]);
    44  		for(j=0; j<fields.len; j++) {
    45  			q = fields.p[j];
    46  			if(*q == 'O')
    47  				q++;
    48  			p = q+xstrlen(q)-1;
    49  			if(*p == ',')
    50  				*p = '\0';
    51  			bwritestr(&out, bprintf(&b, "	[O%s] = \"%s\",\n", q, q));
    52  		}
    53  	}
    54  	
    55  	bwritestr(&out, bprintf(&b, "};\n"));
    56  
    57  	writefile(&out, file, 0);
    58  
    59  	bfree(&in);
    60  	bfree(&b);
    61  	bfree(&out);
    62  	vfree(&lines);
    63  	vfree(&fields);
    64  }
    65  
    66  static int
    67  xatoi(char *s, char **end)
    68  {
    69  	int val = 0;
    70  	for(; *s && *s >= '0' && *s <= '9'; ++s)
    71  		val = val * 10 + (*s - '0');
    72  	*end = s;
    73  	return val;
    74  }
    75  
    76  // mkanames reads [5689].out.h and writes anames[5689].c
    77  // The format is much the same as the Go opcodes above.
    78  // It also writes out cnames array for C_* constants and the dnames
    79  // array for D_* constants.
    80  void
    81  mkanames(char *dir, char *file)
    82  {
    83  	int i, j, ch, n, unknown;
    84  	Buf in, b, out, out2;
    85  	Vec lines;
    86  	char *p, *p2;
    87  	Vec dnames[128];
    88  
    89  	binit(&b);
    90  	binit(&in);
    91  	binit(&out);
    92  	binit(&out2);
    93  	vinit(&lines);
    94  	for(i=0; i<nelem(dnames); i++)
    95  		vinit(&dnames[i]);
    96  
    97  	ch = file[xstrlen(file)-3];
    98  	bprintf(&b, "%s/../cmd/%cl/%c.out.h", dir, ch, ch);
    99  	readfile(&in, bstr(&b));
   100  	splitlines(&lines, bstr(&in));
   101  	
   102  	// Include link.h so that the extern declaration there is
   103  	// checked against the non-extern declaration we are generating.
   104  	bwritestr(&out, bprintf(&b, "// auto generated by go tool dist\n"));
   105  	bwritestr(&out, bprintf(&b, "#include <u.h>\n"));
   106  	bwritestr(&out, bprintf(&b, "#include <libc.h>\n"));
   107  	bwritestr(&out, bprintf(&b, "#include <bio.h>\n"));
   108  	bwritestr(&out, bprintf(&b, "#include <link.h>\n"));
   109  	bwritestr(&out, bprintf(&b, "#include \"../cmd/%cl/%c.out.h\"\n", ch, ch));
   110  	bwritestr(&out, bprintf(&b, "\n"));
   111  
   112  	bwritestr(&out, bprintf(&b, "char*	anames%c[] = {\n", ch));
   113  	for(i=0; i<lines.len; i++) {
   114  		if(hasprefix(lines.p[i], "\tA")) {
   115  			p = xstrstr(lines.p[i], ",");
   116  			if(p)
   117  				*p = '\0';
   118  			p = xstrstr(lines.p[i], "\n");
   119  			if(p)
   120  				*p = '\0';
   121  			p = lines.p[i] + 2;
   122  			bwritestr(&out, bprintf(&b, "\t\"%s\",\n", p));
   123  		}
   124  	}
   125  	bwritestr(&out, "};\n");
   126  
   127  	j=0;
   128  	bprintf(&out2, "char*	cnames%c[] = {\n", ch);
   129  	for(i=0; i<lines.len; i++) {
   130  		if(hasprefix(lines.p[i], "\tC_")) {
   131  			p = xstrstr(lines.p[i], ",");
   132  			if(p)
   133  				*p = '\0';
   134  			p = xstrstr(lines.p[i], "\n");
   135  			if(p)
   136  				*p = '\0';
   137  			p = lines.p[i] + 3;
   138  			bwritestr(&out2, bprintf(&b, "\t\"%s\",\n", p));
   139  			j++;
   140  		}
   141  	}
   142  	bwritestr(&out2, "};\n");
   143  	if(j>0)
   144  		bwriteb(&out, &out2);
   145  
   146  	j=unknown=0;
   147  	n=-1;
   148  	for(i=0; i<lines.len; i++) {
   149  		if(hasprefix(lines.p[i], "\tD_")) {
   150  			p = xstrstr(lines.p[i], ",");
   151  			if(p)
   152  				*p = '\0';
   153  			p = xstrstr(lines.p[i], "\n");
   154  			if(p)
   155  				*p = '\0';
   156  
   157  			// Parse explicit value, if any
   158  			p = xstrstr(lines.p[i], "=");
   159  			if(p) {
   160  				// Skip space after '='
   161  				p2 = p + 1;
   162  				while(*p2 == ' ' || *p2 == '\t')
   163  					p2++;
   164  				n = xatoi(p2, &p2);
   165  				// We can't do anything about
   166  				// non-numeric values or anything that
   167  				// follows
   168  				while(*p2 == ' ' || *p2 == '\t')
   169  					p2++;
   170  				if(*p2 != 0) {
   171  					unknown = 1;
   172  					continue;
   173  				}
   174  				// Truncate space before '='
   175  				while(*(p-1) == ' ' || *(p-1) == '\t')
   176  					p--;
   177  				*p = '\0';
   178  				unknown = 0;
   179  			} else {
   180  				n++;
   181  			}
   182  
   183  			if(unknown || n >= nelem(dnames))
   184  				continue;
   185  
   186  			p = lines.p[i] + 3;
   187  			if(xstrcmp(p, "LAST") == 0)
   188  				continue;
   189  			vadd(&dnames[n], p);
   190  			j++;
   191  		}
   192  	}
   193  	if(j>0){
   194  		bwritestr(&out, bprintf(&b, "char*	dnames%c[D_LAST] = {\n", ch));
   195  		for(i=0; i<nelem(dnames); i++) {
   196  			if(dnames[i].len == 0)
   197  				continue;
   198  			bwritestr(&out, bprintf(&b, "\t[D_%s] = \"", dnames[i].p[0]));
   199  			for(j=0; j<dnames[i].len; j++) {
   200  				if(j != 0)
   201  					bwritestr(&out, "/");
   202  				bwritestr(&out, dnames[i].p[j]);
   203  			}
   204  			bwritestr(&out, "\",\n");
   205  		}
   206  		bwritestr(&out, "};\n");
   207  	}
   208  
   209  	writefile(&out, file, 0);
   210  
   211  	bfree(&b);
   212  	bfree(&in);
   213  	bfree(&out);
   214  	bfree(&out2);
   215  	vfree(&lines);
   216  	for(i=0; i<nelem(dnames); i++)
   217  		vfree(&dnames[i]);
   218  }