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 }