parse 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. BEGIN{
  2. oargc = 0;
  3. for(argc = 1; argc < ARGC; argc++){
  4. if(ARGV[argc] !~ /^-.+/ || ARGV[argc] ~ /--/)
  5. break;
  6. if(ARGV[argc] != "-D")
  7. oargv[ARGV[argc]] = oargc++;
  8. else
  9. DEBUG = 1;
  10. ARGV[argc] = "";
  11. }
  12. # objtype = ENVIRON["objtype"];
  13. objtype = "amd64";
  14. while(getline > 0){
  15. if(/^[ \t]*$/ || /^#/)
  16. continue;
  17. if(/^[^ \t]/){
  18. #section[$1] = 0;
  19. tag = $1;
  20. }
  21. if(!tag)
  22. continue;
  23. sub(/^[ \t]*/, "");
  24. line[tag, section[tag]++] = $0;
  25. }
  26. o = "";
  27. if(!oargc || ("-mkdevlist" in oargv)){
  28. s = mkdevlist();
  29. if(!("-mkdevlist" in oargv) || (oargc > 1))
  30. s = "DEVS=" s;
  31. o = o s "\n";
  32. }
  33. if((!oargc || ("-mkmach" in oargv)) && (objtype in section)){
  34. s = mkmach();
  35. if(!("-mkmach" in oargv) || (oargc > 1))
  36. s = "MACH=" s;
  37. o = o s "\n";
  38. }
  39. if((!oargc || ("-mklib" in oargv)) && ("lib" in section)){
  40. s = mklib();
  41. if(!("-mklib" in oargv) || (oargc > 1))
  42. s = "LIB=" s;
  43. o = o s "\n";
  44. }
  45. if((!oargc || ("-mkport" in oargv) ) && ("port" in section)){
  46. s = mkport();
  47. if(!("-mkport" in oargv) || (oargc > 1))
  48. s = "PORT=" s;
  49. o = o s "\n";
  50. }
  51. if("dbgflg" in section){
  52. for(i = 1; i < section["dbgflg"]; i++){
  53. n = split(line["dbgflg", i], a);
  54. if(n < 2 || n > 4 || a[2] !~ /'[a-zA-Z]'/)
  55. continue;
  56. if(n > 2 && a[3] !~ /'[a-zA-Z]'/)
  57. continue;
  58. if(n == 4 && (a[4] < 1 || a[4] >= 128))
  59. continue;
  60. dbgc[a[1]] = a[2];
  61. if(n == 4)
  62. dbgflg[a[3]] = a[4];
  63. else if(n == 3)
  64. dbgflg[a[3]] = 1;
  65. }
  66. }
  67. if((!oargc || ("-mkrules" in oargv)) && ("dir" in section)){
  68. o = o mkrules(".", exists, a, c, "-I.");
  69. for(i = 1; i < section["dir"]; i++){
  70. n = split(line["dir", i], a);
  71. dir = "../" a[1];
  72. if(n == 1)
  73. a[2] = "-I.";
  74. s = a[2];
  75. o = o mkrules(dir, exists, a, c, s);
  76. l = listolate(a, "|");
  77. if(l != ""){
  78. o = o "^(" l ")\\.$O:R: " dir "/\\1.s\n";
  79. o = o "\t$AS $AFLAGS -o /$stem1.o " s " -c " dir "/$stem1.s\n";
  80. }
  81. l = listolate(c, "|");
  82. if(l != ""){
  83. o = o "^(" l ")\\.$O:R: " dir "/\\1.c\n";
  84. o = o "\t$CC $CFLAGS " s " -c " dir "/$stem1.c\n";
  85. }
  86. }
  87. }
  88. if((!oargc || ("-mkrootrules" in oargv)) && ("rootdir" in section)){
  89. mkrootrules(name, cname, src);
  90. s = ARGV[argc] ".root.c:D:";
  91. for(i = 1; i < section["rootdir"]; i++)
  92. s = s " " src[i];
  93. s = s "\n\t../mk/mkrootall\\\n";
  94. for(i = 1; i < section["rootdir"]; i++)
  95. s = s "\t\t" name[i] " " cname[i] " " src[i] "\\\n";
  96. s = s "\t>$target\n";
  97. if(section["rootdir"] > 1)
  98. o = o s;
  99. }
  100. if((!oargc || ("-mkrrrules" in oargv)) && ("rr" in section)){
  101. n = split(line["rr", 0], a);
  102. if(n == 1)
  103. a[2] = ARGV[argc] ".proto";
  104. s = "$CONF.rr:\t../mk/mkrr $CONF " a[2] "\n";
  105. s = s "\t../mk/mkrr $CONF " a[2] "\n";
  106. for(i = 1; i < section["rr"]; i++)
  107. s = s "$CONF.rr:\t" line["rr", i] "\n";
  108. o = o s;
  109. }
  110. if("-mkdevc" in oargv)
  111. o = o mkdevc();
  112. if("-mkerrstr" in oargv)
  113. o = o mkerrstr();
  114. if("-mksystab" in oargv)
  115. o = o mksystab();
  116. if("-mkbootconf" in oargv)
  117. o = o mkbootconf();
  118. #
  119. # to do:
  120. # bootmkfile
  121. # mkrootall (can it be done at all?)
  122. #
  123. printf o;
  124. exit 0;
  125. }
  126. function mkbootconf( a, n, s, t, u, c, d, p, r){
  127. s = "#include <u.h>\n";
  128. s = s "#include <libc.h>\n\n";
  129. s = s "#include \"../boot/boot.h\"\n\n";
  130. s = s "Method method[] = {\n";
  131. c = "0";
  132. d = "#S/sdC0/";
  133. p = "boot";
  134. r = "/root";
  135. for(i = 0; i < section["boot"]; i++){ # NOTE: start at 0
  136. n = split(line["boot", i], a);
  137. if(a[1] == "boot"){
  138. if(a[2] == "cpu"){
  139. c = "1";
  140. if(n == 4 && a[3] == "boot")
  141. d = a[4];
  142. }
  143. else if(a[2] == "rootdir" && n == 3)
  144. r = a[3];
  145. else if(a[2] ~ /^(bboot|dosboot|romboot)$/){
  146. c = "1";
  147. p = a[2];
  148. }
  149. else if(a[2] == "boot" && n == 3)
  150. d = a[3];
  151. continue;
  152. }
  153. s = s "\t{ \"" a[1] "\", config" a[1] ", connect" a[1] ", ";
  154. t = "nil";
  155. if(n > 1){
  156. u = line["boot", i];
  157. if(sub(/^[_A-Za-z][_A-Za-z0-9]*[ \t]*/, "", u)){
  158. if(match(u, /^".*"$/))
  159. u = substr(u, RSTART+1, RLENGTH-2);
  160. t = "\"" u "\"";
  161. }
  162. }
  163. s = s t ", },\n";
  164. }
  165. s = s "\t{ nil },\n};\n\n";
  166. s = s "int cpuflag = " c ";\n";
  167. s = s "char* rootdir = \"" r "\";\n";
  168. s = s "char* bootdisk = \"" d "\";\n";
  169. s = s "extern void " p "(int, char**);\n\n";
  170. s = s "void\nmain(int argc, char **argv)\n";
  171. s = s "{\n\t" p "(argc, argv);\n}\n"
  172. t = "int (*cfs)(int) = 0;\n";
  173. for(i = 1; i < section["rootdir"]; i++){
  174. if($1 !~ /\/bin\/cfs$/)
  175. continue;
  176. t = "int (*cfs)(int) = cache;\n";
  177. break;
  178. }
  179. s = s t;
  180. return s;
  181. }
  182. function mksystab( a, i, f, n, s, t){
  183. s = "#include \"u.h\"\n";
  184. s = s "#include \"../port/lib.h\"\n";
  185. s = s "#include \"mem.h\"\n";
  186. s = s "#include \"dat.h\"\n";
  187. s = s "#include \"fns.h\"\n\n";
  188. s = s "#include \"/sys/src/libc/9syscall/sys.h\"\n\n";
  189. t = "";
  190. while(getline < "/sys/src/libc/9syscall/sys.h"){
  191. if($1 != "#define" || NF != 3)
  192. continue;
  193. f = "sys" tolower($2);
  194. if($2 == "SYSR1")
  195. f = "sysr1";
  196. if($2 == "RENDEZVOUS")
  197. n = "Rendez";
  198. else if($2 == "BRK_")
  199. n = "Brk";
  200. else
  201. n = substr($2, 1, 1) tolower(substr($2, 2));
  202. s = s "extern void " f "(Ar0*, ...);\n";
  203. t = t "\t[" $2 "]\t";
  204. if(length($2) < 6)
  205. t = t "\t";
  206. t = t "{ \"" n "\", " f ", ";
  207. #
  208. # The following should really be defined properly in the
  209. # manual and code, but changing Plan 9 now is too awkward.
  210. # It will matter more when sizeof(long) != sizeof(int).
  211. #
  212. # if($2 ~ "(FVERSION|STAT|FSTAT|WSTAT|FWSTAT|AWAIT)")
  213. # t = t "{ .u = 0 } },\n";
  214. #
  215. # if($2 ~ "(BIND|_MOUNT|MOUNT)")
  216. # t = t "{ .l = -1 } },\n";
  217. #
  218. if($2 ~ "(EXEC|SEGBRK|SEGATTACH|RENDEZVOUS)")
  219. t = t "{ .v = (void*)-1 } },\n";
  220. else if($2 ~ "(ALARM|_READ|_WRITE|PREAD|PWRITE)")
  221. t = t "{ .l = -1 } },\n";
  222. else if($2 ~ "(NSEC)")
  223. t = t "{ .vl = -1LL } },\n";
  224. else
  225. t = t "{ .i = -1 } },\n";
  226. }
  227. if("syscall" in section){
  228. for(i = 1; i < section["syscall"]; i++){
  229. if(split(line["syscall", i], a) != 8)
  230. continue;
  231. if(line["syscall", i] !~ /#define.*{ \.[ilpuv] = .* }$/)
  232. continue;
  233. f = "sys" tolower(a[2]);
  234. n = substr(a[2], 1, 1) tolower(substr(a[2], 2));
  235. s = s "\nSyscall " f ";\n";
  236. t = t a[1] " " a[2] "\t" a[3] "\n\t[" a[2] "]\t";
  237. if(length(a[2]) < 6)
  238. t = t "\t";
  239. split(line["syscall", i], a, "{");
  240. t = t "{ \"" n "\", " f ", {" a[2] " },\n";
  241. }
  242. }
  243. #s = s "struct {\n\tchar*\tn;\n\tvoid (*f)(Ar0*, ...);\n\tAr0\tr;\n}";
  244. s = s " systab_t systab = {\n" t "};\n\nint nsyscall = nelem(systab);\n";
  245. return s;
  246. }
  247. function mkerrstr( a, s){
  248. FS="[ \t;]+";
  249. while(getline < "../port/error.h"){
  250. split($0, a, /\/\* | \*\//);
  251. s = s $2 " " $3 " = \"" a[2] "\";\n";
  252. }
  253. FS=" ";
  254. return s;
  255. }
  256. function mkdevc( a, d, i, m, n, s, t, u, name, cname){
  257. s = "#include \"u.h\"\n";
  258. s = s "#include \"../port/lib.h\"\n";
  259. s = s "#include \"mem.h\"\n";
  260. s = s "#include \"dat.h\"\n";
  261. s = s "#include \"fns.h\"\n";
  262. s = s "#include \"../port/error.h\"\n\n";
  263. s = s "#include \"io.h\"\n\n";
  264. t = "";
  265. for(i = 1; i < section["dev"]; i++){
  266. split(line["dev", i], a);
  267. s = s "extern Dev " a[1] "devtab;\n";
  268. t = t "\t&" a[1] "devtab,\n";
  269. d[a[1]]++;
  270. }
  271. s = s "Dev* devtab[] = {\n" t "\tnil,\n};\n\n";
  272. mkrootrules(name, cname, m);
  273. t = "";
  274. for(i = 1; i < section["rootdir"]; i++){
  275. s = s "extern unsigned char " cname[i] "code[];\n";
  276. s = s "extern usize " cname[i] "len;\n";
  277. t = t "\taddbootfile(\"" name[i] "\", " cname[i] "code, " cname[i] "len);\n";
  278. }
  279. for(i = 1; i < section["link"]; i++){
  280. split(line["link", i], a);
  281. s = s "extern void " a[1] "link(void);\n";
  282. t = t "\t" a[1] "link();\n";
  283. }
  284. s = s "void\nlinks(void)\n{\n" t "}\n\n";
  285. if("ip" in d && "ip" in section){
  286. t = "";
  287. s = s "#include \"../ip/ip.h\"\n";
  288. for(i = 1; i < section["ip"]; i++){
  289. split(line["ip", i], a);
  290. s = s "extern void " a[1] "init(Fs*);\n";
  291. t = t "\t" a[1] "init,\n";
  292. }
  293. s = s "void (*ipprotoinit[])(Fs*) = {\n" t "\tnil,\n};\n\n";
  294. }
  295. if("sd" in d && "sd" in section){
  296. t = "";
  297. s = s "#include \"../port/sd.h\"\n";
  298. for(i = 1; i < section["sd"]; i++){
  299. split(line["sd", i], a);
  300. s = s "extern SDifc " a[1] "ifc;\n";
  301. t = t "\t&" a[1] "ifc,\n";
  302. }
  303. s = s "SDifc* sdifc[] = {\n" t "\tnil,\n};\n\n";
  304. }
  305. if("uart" in d && "uart" in section){
  306. t = "";
  307. for(i = 1; i < section["uart"]; i++){
  308. split(line["uart", i], a);
  309. a[1] = substr(a[1], 5, length(a[1])-4) "physuart";
  310. s = s "extern PhysUart " a[1] ";\n";
  311. t = t "\t&" a[1] ",\n";
  312. }
  313. s = s "PhysUart* physuart[] = {\n" t "\tnil,\n};\n\n";
  314. }
  315. t = "";
  316. n = 0;
  317. if("physseg" in section){
  318. for(i = 1; i < section["physseg"]; i++){
  319. u = line["physseg", i];
  320. if(u ~ /^\.[_A-Za-z][_A-Za-z0-9]*/)
  321. t = t "\t";
  322. t = t "\t" u "\n";
  323. if(sub(/.*\.pgalloc.*=[^_A-Za-z]*/, "", u)){
  324. if(match(u, /^[_A-Za-z][_A-Za-z0-9]*/)){
  325. u = substr(u, RSTART, RLENGTH);
  326. s = s "extern Page *(*" u ")(Segment*, uintptr);\n";
  327. }
  328. }
  329. else if(sub(/.*\.pgfree.*=[^_A-Za-z]*/, "", u)){
  330. if(match(u, /^[_A-Za-z][_A-Za-z0-9]*/)){
  331. u = substr(u, RSTART, RLENGTH);
  332. s = s "extern void (*" u ")(Page*);\n";
  333. }
  334. }
  335. if(match(u, /}/))
  336. n++;
  337. }
  338. }
  339. s = s "Physseg physseg[" n+8 "] = {\n";
  340. s = s "\t{\t.attr\t= SG_SHARED,\n";
  341. s = s "\t\t.name\t= \"shared\",\n";
  342. s = s "\t\t.size\t= SEGMAXPG,\n\t},\n";
  343. s = s "\t{\t.attr\t= SG_BSS,\n";
  344. s = s "\t\t.name\t= \"memory\",\n";
  345. s = s "\t\t.size\t= SEGMAXPG,\n\t},\n";
  346. s = s t "};\nint nphysseg = " n+8 ";\n\n";
  347. s = s "char dbgflg[256]";
  348. t = "";
  349. for(u in dbgflg)
  350. t = t "\t[" u "]\t" dbgflg[u] ",\n";
  351. if(t != "")
  352. s = s " = {\n" t "}";
  353. s = s ";\n\n";
  354. for(i in m)
  355. delete m[i];
  356. for(i = 1; i < section["misc"]; i++){
  357. split(line["misc", i], a);
  358. m[a[1]] = line["misc", i];
  359. }
  360. if("cache" in m){
  361. s = s "extern void cinit(void);\n";
  362. s = s "extern void copen(Chan*);\n";
  363. s = s "extern int cread(Chan*, unsigned char*, int, int64_t);\n";
  364. s = s "extern void cupdate(Chan*, unsigned char*, int, int64_t);\n";
  365. s = s "extern void cwrite(Chan*, unsigned char*, int, int64_t);\n\n";
  366. s = s "void (*mfcinit)(void) = cinit;\n";
  367. s = s "void (*mfcopen)(Chan*) = copen;\n";
  368. s = s "int (*mfcread)(Chan*, unsigned char*, int, int64_t) = cread;\n";
  369. s = s "void (*mfcupdate)(Chan*, unsigned char*, int, int64_t) = cupdate;\n";
  370. s = s "void (*mfcwrite)(Chan*, unsigned char*, int, int64_t) = cwrite;\n\n";
  371. }
  372. else{
  373. s = s "void (*mfcinit)(void) = nil;\n";
  374. s = s "void (*mfcopen)(Chan*) = nil;\n";
  375. s = s "int (*mfcread)(Chan*, unsigned char*, int, int64_t) = nil;\n";
  376. s = s "void (*mfcupdate)(Chan*, unsigned char*, int, int64_t) = nil;\n";
  377. s = s "void (*mfcwrite)(Chan*, unsigned char*, int, int64_t) = nil;\n\n";
  378. }
  379. if(!("rdb" in misc)){
  380. s = s "void\n";
  381. s = s "rdb(void)\n";
  382. s = s "{\n";
  383. s = s "\tsplhi();\n";
  384. s = s "\tiprint(\"rdb...not installed\\n\");\n";
  385. s = s "\tfor(;;);\n";
  386. s = s "}\n\n";
  387. }
  388. if(objtype == "power"){
  389. for(i = 1; i < section[objtype]; i++){
  390. split(line[objtype, i], a);
  391. m[a[1]] = line[objtype, i];
  392. }
  393. if(!("cnksyscall" in m)){
  394. s = s "void\n";
  395. s = s "cnksyscall(Ureg*)\n";
  396. s = s "{\n";
  397. s = s "\tpanic(\"cnkemu...not installed\\n\");\n";
  398. s = s "\tfor(;;);\n";
  399. s = s "}\n\n";
  400. s = s "void*\n";
  401. s = s "cnksysexecregs(uintptr, uint32_t, uint32_t)\n";
  402. s = s "{\n";
  403. s = s "\tpanic(\"cnkemu...not installed\\n\");\n";
  404. s = s "\tfor(;;);\n";
  405. s = s "}\n\n";
  406. }
  407. }
  408. if("conf" in section){
  409. for(i = 1; i < section["conf"]; i++)
  410. s = s line["conf", i] "\n";
  411. s = s "\n";
  412. }
  413. t = ".";
  414. while("pwd" | getline > 0){
  415. if($0 ~ /^\//)
  416. t = $0;
  417. }
  418. s = s "char* conffile = \"" t "/" ARGV[argc] "\";\n";
  419. s = s "uint32_t kerndate = KERNDATE;\n";
  420. return s;
  421. }
  422. function mkrootrules(name, cname, src, a, i, n){
  423. for(i = 1; i < section["rootdir"]; i++){
  424. n = split(line["rootdir", i], a);
  425. if(n >= 2)
  426. name[i] = a[2];
  427. else
  428. name[i] = a[1];
  429. sub(/.*\//, "", name[i]);
  430. cname[i] = a[1];
  431. gsub(/[^a-zA-Z0-9_]/, "_", cname[i]);
  432. src[i] = a[1];
  433. }
  434. }
  435. function mkrules(dir, exists, ameta, cmeta, flags, f, i, s, t){
  436. for(i in ameta)
  437. delete ameta[i];
  438. for(i in cmeta)
  439. delete cmeta[i];
  440. s = "";
  441. while("cd " dir "; ls *.[cs]" | getline > 0){
  442. if($0 !~ /^[A-Za-z0-9]*\.[cs]$/)
  443. continue;
  444. f = $0;
  445. if(!sub(/\.[cs]$/, ""))
  446. continue;
  447. if($0 in exists)
  448. continue;
  449. exists[$0] = dir;
  450. if(f ~ /\.c$/){
  451. if(!($0 in dbgc)){
  452. cmeta[$0]++;
  453. continue;
  454. }
  455. t = "$CC $CFLAGS " flags;
  456. }
  457. else{
  458. if(!($0 in dbgc)){
  459. ameta[$0]++;
  460. continue;
  461. }
  462. t = "$AS $AFLAGS " flags;
  463. }
  464. s = s $0 ".$O:\t" dir "/" f "\n";
  465. # s = s "\t" t " -D'_DBGC_='" dbgc[$0] "'' " dir "/" f "\n";
  466. s = s "\t" t " -c " dir "/" f "\n";
  467. }
  468. return s;
  469. }
  470. function mkport( array){
  471. arrayify(array, "port", "", ".$O", 1);
  472. return listolate(array, " ");
  473. }
  474. function mklib( array){
  475. arrayify(array, "lib", "/$objtype/lib/", ".a", 1);
  476. return listolate(array," ");
  477. }
  478. function mkmach( a, i, s){
  479. s = "";
  480. for(i = 1; i < section[objtype]; i++){
  481. if(!split(line[objtype, i], a))
  482. continue;
  483. if(s == "")
  484. s = a[1] ".$O";
  485. else
  486. s = s " " a[1] ".$O";
  487. }
  488. return s;
  489. }
  490. function mkdevlist( a, array, i, j, n, s){
  491. for(s in section){
  492. if(line[s, 0] !~ /[ \t]\+dev[^_A-Za-z0-9]*/)
  493. continue;
  494. if(s == "dev")
  495. arrayify(array, s, "dev", ".$O", 1);
  496. else if(s == objtype)
  497. arrayify(array, s, "", ".$O", 0);
  498. else
  499. arrayify(array, s, "", ".$O", 1);
  500. }
  501. return listolate(array, " ");
  502. }
  503. function listolate(array, sep, a, s){
  504. s = "";
  505. for(a in array){
  506. if(s == "")
  507. s = a;
  508. else
  509. s = a sep s;
  510. }
  511. return s;
  512. }
  513. function arrayify(array, tag, prefix, suffix, one, a, i, j, n){
  514. for(i = 1; i < section[tag]; i++){
  515. n = split(line[tag, i], a);
  516. if(one)
  517. array[prefix a[1] suffix]++;
  518. for(j = 2; j <= n; j++){
  519. if(a[$j] ~ /[+=-].*/)
  520. continue;
  521. array[a[j] suffix]++;
  522. }
  523. }
  524. }