gen_runtime.cpp revision ea877edd85a9b030fec742491322ee58324b7ae6
1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <stdio.h> 18#include <vector> 19#include <list> 20#include <string> 21 22using namespace std; 23 24FILE *gIn; 25FILE *gOut; 26 27class Func { 28public: 29 Func() { 30 mMinVersion = 0; 31 mMaxVersion = 0; 32 } 33 34 string mName; 35 int mMinVersion; 36 int mMaxVersion; 37 38 vector<vector<string> > mReplaceables; 39 vector<string> mArgs; 40 string mRet; 41 vector<string> mComment; 42 vector<string> mInline; 43 44}; 45 46vector<Func *> gFuncs; 47 48bool getNextLine(FILE *in, string *s) { 49 s->clear(); 50 while (1) { 51 int c = fgetc(in); 52 if (c == EOF) return s->size() != 0; 53 if (c == '\n') break; 54 s->push_back((char)c); 55 } 56 return true; 57} 58 59void trim(string *s, size_t start) { 60 if (start > 0) { 61 s->erase(0, start); 62 } 63 64 while (s->size() && (s->at(0) == ' ')) { 65 s->erase(0, 1); 66 } 67 68 size_t p = s->find_first_of("\n\r"); 69 if (p != string::npos) { 70 s->erase(p); 71 } 72 73 while ((s->size() > 0) && (s->at(s->size()-1) == ' ')) { 74 s->erase(s->size() -1); 75 } 76} 77 78Func * scanFunction(FILE *in) { 79 Func *f = new Func(); 80 bool modeComment = false; 81 bool modeInline = false; 82 size_t replacables = 0; 83 84 while (1) { 85 string s; 86 bool ret = getNextLine(in, &s); 87 if (!ret) break; 88 89 if (modeComment) { 90 if (!s.size() || (s[0] == ' ')) { 91 trim(&s, 0); 92 f->mComment.push_back(s); 93 continue; 94 } else { 95 modeComment = false; 96 } 97 } 98 99 if (modeInline) { 100 if (!s.size() || (s[0] == ' ')) { 101 trim(&s, 0); 102 f->mInline.push_back(s); 103 continue; 104 } else { 105 modeInline = false; 106 } 107 } 108 109 if (s[0] == '#') { 110 continue; 111 } 112 113 if (s.compare(0, 5, "name:") == 0) { 114 trim(&s, 5); 115 f->mName = s; 116 continue; 117 } 118 119 if (s.compare(0, 4, "arg:") == 0) { 120 trim(&s, 4); 121 f->mArgs.push_back(s); 122 continue; 123 } 124 125 if (s.compare(0, 4, "ret:") == 0) { 126 trim(&s, 4); 127 f->mRet = s; 128 continue; 129 } 130 131 if (s.compare(0, 4, "end:") == 0) { 132 return f; 133 } 134 135 if (s.compare(0, 8, "comment:") == 0) { 136 modeComment = true; 137 continue; 138 } 139 140 if (s.compare(0, 7, "inline:") == 0) { 141 modeInline = true; 142 continue; 143 } 144 145 if (s.compare(0, 8, "version:") == 0) { 146 trim(&s, 8); 147 sscanf(s.c_str(), "%i %i", &f->mMinVersion, &f->mMaxVersion); 148 continue; 149 } 150 151 if (s.compare(0, 8, "start:") == 0) { 152 continue; 153 } 154 155 if (s.compare(0, 2, "w:") == 0) { 156 vector<string> t; 157 if (s.find("1") != string::npos) { 158 t.push_back(""); 159 } 160 if (s.find("2") != string::npos) { 161 t.push_back("2"); 162 } 163 if (s.find("3") != string::npos) { 164 t.push_back("3"); 165 } 166 if (s.find("4") != string::npos) { 167 t.push_back("4"); 168 } 169 f->mReplaceables.push_back(t); 170 continue; 171 } 172 173 if (s.compare(0, 2, "t:") == 0) { 174 vector<string> t; 175 if (s.find("f16") != string::npos) { 176 t.push_back("half"); 177 } 178 if (s.find("f32") != string::npos) { 179 t.push_back("float"); 180 } 181 if (s.find("f64") != string::npos) { 182 t.push_back("double"); 183 } 184 if (s.find("i8") != string::npos) { 185 t.push_back("char"); 186 } 187 if (s.find("u8") != string::npos) { 188 t.push_back("uchar"); 189 } 190 if (s.find("i16") != string::npos) { 191 t.push_back("short"); 192 } 193 if (s.find("u16") != string::npos) { 194 t.push_back("ushort"); 195 } 196 if (s.find("i32") != string::npos) { 197 t.push_back("int"); 198 } 199 if (s.find("u32") != string::npos) { 200 t.push_back("uint"); 201 } 202 if (s.find("i64") != string::npos) { 203 t.push_back("long"); 204 } 205 if (s.find("u64") != string::npos) { 206 t.push_back("ulong"); 207 } 208 f->mReplaceables.push_back(t); 209 continue; 210 } 211 212 if (s.size() == 0) { 213 // eat empty line 214 continue; 215 } 216 217 printf("Error, line:\n"); 218 printf(" %s\n", s.c_str()); 219 } 220 221 delete f; 222 return NULL; 223} 224 225string stringReplace(string s, string match, string rep) { 226 while(1) { 227 size_t p = s.find(match); 228 if (p == string::npos) break; 229 230 s.erase(p, match.size()); 231 s.insert(p, rep); 232 } 233 return s; 234} 235 236string stringExpand(string s, const Func *f, int i1, int i2, int i3, int i4) { 237 if (f->mReplaceables.size() > 0) { 238 s = stringReplace(s, "#1", f->mReplaceables[0][i1]); 239 } 240 if (f->mReplaceables.size() > 1) { 241 s = stringReplace(s, "#2", f->mReplaceables[1][i2]); 242 } 243 if (f->mReplaceables.size() > 2) { 244 s = stringReplace(s, "#3", f->mReplaceables[2][i3]); 245 } 246 if (f->mReplaceables.size() > 3) { 247 s = stringReplace(s, "#4", f->mReplaceables[3][i4]); 248 } 249 return s; 250} 251 252void writeLegal(FILE *o) { 253 fprintf(o, "/*\n"); 254 fprintf(o, " * Copyright (C) 2014 The Android Open Source Project\n"); 255 fprintf(o, " *\n"); 256 fprintf(o, " * Licensed under the Apache License, Version 2.0 (the \"License\");\n"); 257 fprintf(o, " * you may not use this file except in compliance with the License.\n"); 258 fprintf(o, " * You may obtain a copy of the License at\n"); 259 fprintf(o, " *\n"); 260 fprintf(o, " * http://www.apache.org/licenses/LICENSE-2.0\n"); 261 fprintf(o, " *\n"); 262 fprintf(o, " * Unless required by applicable law or agreed to in writing, software\n"); 263 fprintf(o, " * distributed under the License is distributed on an \"AS IS\" BASIS,\n"); 264 fprintf(o, " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"); 265 fprintf(o, " * See the License for the specific language governing permissions and\n"); 266 fprintf(o, " * limitations under the License.\n"); 267 fprintf(o, " */\n\n"); 268} 269 270void writeIfdef(FILE *o, string filename, bool isStart) { 271 string t = "__"; 272 t += filename; 273 t += "__"; 274 275 for (size_t i = 2; i < t.size(); i++) { 276 if (t[i] == '.') { 277 t[i] = '_'; 278 } 279 } 280 281 if (isStart) { 282 fprintf(o, "#ifndef %s\n", t.c_str()); 283 fprintf(o, "#define %s\n", t.c_str()); 284 } else { 285 fprintf(o, "#endif // %s\n", t.c_str()); 286 } 287} 288 289 290 291void writeHeaderFunc(FILE *o, const Func *f, int i1, int i2, int i3, int i4) { 292 string s; 293 294 if (f->mMinVersion || f->mMaxVersion) { 295 if (f->mMaxVersion) { 296 fprintf(o, "#if (defined(RS_VERSION) && (RS_VERSION >= %i) && (RS_VERSION <= %i))\n", 297 f->mMinVersion, f->mMaxVersion); 298 } else { 299 fprintf(o, "#if (defined(RS_VERSION) && (RS_VERSION >= %i))\n", 300 f->mMinVersion); 301 } 302 } 303 304 fprintf(o, "/*\n"); 305 for (size_t ct=0; ct < f->mComment.size(); ct++) { 306 s = stringExpand(f->mComment[ct], f, i1, i2, i3, i4); 307 if (s.size()) { 308 fprintf(o, " * %s\n", s.c_str()); 309 } else { 310 fprintf(o, " *\n"); 311 } 312 } 313 fprintf(o, " *\n"); 314 if (f->mMinVersion || f->mMaxVersion) { 315 if (f->mMaxVersion) { 316 fprintf(o, " * Suppored by API versions %i - %i\n", 317 f->mMinVersion, f->mMaxVersion); 318 } else { 319 fprintf(o, " * Supported by API versions %i and newer.\n", 320 f->mMinVersion); 321 } 322 } 323 324 fprintf(o, " */\n"); 325 326 s.clear(); 327 if (f->mInline.size() > 0) { 328 s += "static "; 329 } else { 330 s += "extern "; 331 } 332 s += f->mRet; 333 s += " __attribute__((const, overloadable))"; 334 s += f->mName; 335 s += "("; 336 if (f->mArgs.size()) { 337 s += f->mArgs[0]; 338 } 339 for (size_t ct=1; ct < f->mArgs.size(); ct++) { 340 s += ", "; 341 s += f->mArgs[ct]; 342 } 343 if (f->mInline.size() > 0) { 344 s += ") {"; 345 } else { 346 s += ");"; 347 } 348 s = stringExpand(s, f, i1, i2, i3, i4); 349 fprintf(o, "%s\n", s.c_str()); 350 351 if (f->mInline.size() > 0) { 352 for (size_t ct=0; ct < f->mInline.size(); ct++) { 353 s = stringExpand(f->mInline[ct], f, i1, i2, i3, i4); 354 fprintf(o, " %s\n", s.c_str()); 355 } 356 fprintf(o, "}\n"); 357 } 358 359 if (f->mMinVersion || f->mMaxVersion) { 360 fprintf(o, "#endif\n"); 361 } 362 363 fprintf(o, "\n", s.c_str()); 364} 365 366 367void writeHeaderFuncs(FILE *o, const Func *f) { 368 switch(f->mReplaceables.size()) { 369 case 0: 370 writeHeaderFunc(o, f, -1, -1, -1, -1); 371 break; 372 case 1: 373 for (size_t i1 = 0; i1 < f->mReplaceables[0].size(); i1++) { 374 writeHeaderFunc(o, f, i1, -1, -1, -1); 375 } 376 break; 377 case 2: 378 for (size_t i2 = 0; i2 < f->mReplaceables[1].size(); i2++) { 379 for (size_t i1 = 0; i1 < f->mReplaceables[0].size(); i1++) { 380 writeHeaderFunc(o, f, i1, i2, -1, -1); 381 } 382 } 383 break; 384 case 3: 385 for (size_t i3 = 0; i3 < f->mReplaceables[2].size(); i3++) { 386 for (size_t i2 = 0; i2 < f->mReplaceables[1].size(); i2++) { 387 for (size_t i1 = 0; i1 < f->mReplaceables[0].size(); i1++) { 388 writeHeaderFunc(o, f, i1, i2, i3, -1); 389 } 390 } 391 } 392 break; 393 case 4: 394 for (size_t i4 = 0; i4 < f->mReplaceables[3].size(); i4++) { 395 for (size_t i3 = 0; i3 < f->mReplaceables[2].size(); i3++) { 396 for (size_t i2 = 0; i2 < f->mReplaceables[1].size(); i2++) { 397 for (size_t i1 = 0; i1 < f->mReplaceables[0].size(); i1++) { 398 writeHeaderFunc(o, f, i1, i2, i3, i4); 399 } 400 } 401 } 402 } 403 break; 404 } 405} 406 407 408 409int main(int argc, char* argv[]) 410{ 411 const char *inpath = "runtime.spec"; 412 const char *outpath = "rs_core_math.rsh"; 413 414 gIn = fopen(inpath, "rt"); 415 if (!gIn) { 416 printf("Error opening input file: %s", inpath); 417 return -1; 418 } 419 420 while (1) { 421 Func *f = scanFunction(gIn); 422 if (f != NULL) { 423 gFuncs.push_back(f); 424 } else { 425 break; 426 } 427 } 428 429 gOut = fopen(outpath, "wt"); 430 if (!gOut) { 431 printf("Error opening output file: %s", outpath); 432 return -1; 433 } 434 435 writeLegal(gOut); 436 writeIfdef(gOut, outpath, true); 437 for (size_t ct=0; ct < gFuncs.size(); ct++) { 438 writeHeaderFuncs(gOut, gFuncs[ct]); 439 } 440 writeIfdef(gOut, outpath, false); 441 442 fclose (gIn); 443 fclose (gOut); 444 445 printf("%i Functions processed.\n", (int)gFuncs.size()); 446 447 return 0; 448} 449 450 451