parse 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  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. s = s "#include \"../../libc/9syscall/sys.h\"\n\n";
  190. t = "";
  191. while(getline < "../../libc/9syscall/sys.h"){
  192. if($1 != "#define" || NF != 3)
  193. continue;
  194. f = "sys" tolower($2);
  195. if($2 == "SYSR1")
  196. f = "sysr1";
  197. if($2 == "RENDEZVOUS")
  198. n = "Rendez";
  199. else if($2 == "BRK_")
  200. n = "Brk";
  201. else
  202. n = substr($2, 1, 1) tolower(substr($2, 2));
  203. s = s "extern void " f "(Ar0*, ...);\n";
  204. t = t "\t[" $2 "]\t";
  205. if(length($2) < 6)
  206. t = t "\t";
  207. t = t "{ \"" n "\", " f ", ";
  208. #
  209. # The following should really be defined properly in the
  210. # manual and code, but changing Plan 9 now is too awkward.
  211. # It will matter more when sizeof(long) != sizeof(int).
  212. #
  213. # if($2 ~ "(FVERSION|STAT|FSTAT|WSTAT|FWSTAT|AWAIT)")
  214. # t = t "{ .u = 0 } },\n";
  215. #
  216. # if($2 ~ "(BIND|_MOUNT|MOUNT)")
  217. # t = t "{ .l = -1 } },\n";
  218. #
  219. if($2 ~ "(EXEC|SEGBRK|SEGATTACH|RENDEZVOUS)")
  220. t = t "{ .v = (void*)-1 } },\n";
  221. else if($2 ~ "(ALARM|_READ|_WRITE|PREAD|PWRITE)")
  222. t = t "{ .l = -1 } },\n";
  223. else if($2 ~ "(NSEC)")
  224. t = t "{ .vl = -1LL } },\n";
  225. else
  226. t = t "{ .i = -1 } },\n";
  227. }
  228. if("syscall" in section){
  229. for(i = 1; i < section["syscall"]; i++){
  230. if(split(line["syscall", i], a) != 8)
  231. continue;
  232. if(line["syscall", i] !~ /#define.*{ \.[ilpuv] = .* }$/)
  233. continue;
  234. f = "sys" tolower(a[2]);
  235. n = substr(a[2], 1, 1) tolower(substr(a[2], 2));
  236. s = s "\nSyscall " f ";\n";
  237. t = t a[1] " " a[2] "\t" a[3] "\n\t[" a[2] "]\t";
  238. if(length(a[2]) < 6)
  239. t = t "\t";
  240. split(line["syscall", i], a, "{");
  241. t = t "{ \"" n "\", " f ", {" a[2] " },\n";
  242. }
  243. }
  244. #s = s "struct {\n\tchar*\tn;\n\tvoid (*f)(Ar0*, ...);\n\tAr0\tr;\n}";
  245. s = s " systab_t systab = {\n" t "};\n\nint nsyscall = nelem(systab);\n";
  246. return s;
  247. }
  248. function mkerrstr( a, s){
  249. FS="[ \t;]+";
  250. while(getline < "../port/error.h"){
  251. split($0, a, /\/\* | \*\//);
  252. s = s $2 " " $3 " = \"" a[2] "\";\n";
  253. }
  254. FS=" ";
  255. return s;
  256. }
  257. function mkdevc( a, d, i, m, n, s, t, u, name, cname){
  258. s = "#include \"u.h\"\n";
  259. s = s "#include \"../port/lib.h\"\n";
  260. s = s "#include \"mem.h\"\n";
  261. s = s "#include \"dat.h\"\n";
  262. s = s "#include \"fns.h\"\n";
  263. s = s "#include \"../port/error.h\"\n\n";
  264. s = s "#include \"io.h\"\n\n";
  265. t = "";
  266. for(i = 1; i < section["dev"]; i++){
  267. split(line["dev", i], a);
  268. s = s "extern Dev " a[1] "devtab;\n";
  269. t = t "\t&" a[1] "devtab,\n";
  270. d[a[1]]++;
  271. }
  272. s = s "Dev* devtab[] = {\n" t "\tnil,\n};\n\n";
  273. mkrootrules(name, cname, m);
  274. t = "";
  275. for(i = 1; i < section["rootdir"]; i++){
  276. s = s "extern unsigned char " cname[i] "code[];\n";
  277. s = s "extern usize " cname[i] "len;\n";
  278. t = t "\taddbootfile(\"" name[i] "\", " cname[i] "code, " cname[i] "len);\n";
  279. }
  280. for(i = 1; i < section["link"]; i++){
  281. split(line["link", i], a);
  282. s = s "extern void " a[1] "link(void);\n";
  283. t = t "\t" a[1] "link();\n";
  284. }
  285. s = s "void\nlinks(void)\n{\n" t "}\n\n";
  286. if("ip" in d && "ip" in section){
  287. t = "";
  288. s = s "#include \"../ip/ip.h\"\n";
  289. for(i = 1; i < section["ip"]; i++){
  290. split(line["ip", i], a);
  291. s = s "extern void " a[1] "init(Fs*);\n";
  292. t = t "\t" a[1] "init,\n";
  293. }
  294. s = s "void (*ipprotoinit[])(Fs*) = {\n" t "\tnil,\n};\n\n";
  295. }
  296. if("sd" in d && "sd" in section){
  297. t = "";
  298. s = s "#include \"../port/sd.h\"\n";
  299. for(i = 1; i < section["sd"]; i++){
  300. split(line["sd", i], a);
  301. s = s "extern SDifc " a[1] "ifc;\n";
  302. t = t "\t&" a[1] "ifc,\n";
  303. }
  304. s = s "SDifc* sdifc[] = {\n" t "\tnil,\n};\n\n";
  305. }
  306. if("uart" in d && "uart" in section){
  307. t = "";
  308. for(i = 1; i < section["uart"]; i++){
  309. split(line["uart", i], a);
  310. a[1] = substr(a[1], 5, length(a[1])-4) "physuart";
  311. s = s "extern PhysUart " a[1] ";\n";
  312. t = t "\t&" a[1] ",\n";
  313. }
  314. s = s "PhysUart* physuart[] = {\n" t "\tnil,\n};\n\n";
  315. }
  316. t = "";
  317. n = 0;
  318. if("physseg" in section){
  319. for(i = 1; i < section["physseg"]; i++){
  320. u = line["physseg", i];
  321. if(u ~ /^\.[_A-Za-z][_A-Za-z0-9]*/)
  322. t = t "\t";
  323. t = t "\t" u "\n";
  324. if(sub(/.*\.pgalloc.*=[^_A-Za-z]*/, "", u)){
  325. if(match(u, /^[_A-Za-z][_A-Za-z0-9]*/)){
  326. u = substr(u, RSTART, RLENGTH);
  327. s = s "extern Page *(*" u ")(Segment*, uintptr);\n";
  328. }
  329. }
  330. else if(sub(/.*\.pgfree.*=[^_A-Za-z]*/, "", u)){
  331. if(match(u, /^[_A-Za-z][_A-Za-z0-9]*/)){
  332. u = substr(u, RSTART, RLENGTH);
  333. s = s "extern void (*" u ")(Page*);\n";
  334. }
  335. }
  336. if(match(u, /}/))
  337. n++;
  338. }
  339. }
  340. s = s "Physseg physseg[" n+8 "] = {\n";
  341. s = s "\t{\t.attr\t= SG_SHARED,\n";
  342. s = s "\t\t.name\t= \"shared\",\n";
  343. s = s "\t\t.size\t= SEGMAXPG,\n\t},\n";
  344. s = s "\t{\t.attr\t= SG_BSS,\n";
  345. s = s "\t\t.name\t= \"memory\",\n";
  346. s = s "\t\t.size\t= SEGMAXPG,\n\t},\n";
  347. s = s t "};\nint nphysseg = " n+8 ";\n\n";
  348. s = s "char dbgflg[256]";
  349. t = "";
  350. for(u in dbgflg)
  351. t = t "\t[" u "]\t" dbgflg[u] ",\n";
  352. if(t != "")
  353. s = s " = {\n" t "}";
  354. s = s ";\n\n";
  355. for(i in m)
  356. delete m[i];
  357. for(i = 1; i < section["misc"]; i++){
  358. split(line["misc", i], a);
  359. m[a[1]] = line["misc", i];
  360. }
  361. if("cache" in m){
  362. s = s "extern void cinit(void);\n";
  363. s = s "extern void copen(Chan*);\n";
  364. s = s "extern int cread(Chan*, unsigned char*, int, int64_t);\n";
  365. s = s "extern void cupdate(Chan*, unsigned char*, int, int64_t);\n";
  366. s = s "extern void cwrite(Chan*, unsigned char*, int, int64_t);\n\n";
  367. s = s "void (*mfcinit)(void) = cinit;\n";
  368. s = s "void (*mfcopen)(Chan*) = copen;\n";
  369. s = s "int (*mfcread)(Chan*, unsigned char*, int, int64_t) = cread;\n";
  370. s = s "void (*mfcupdate)(Chan*, unsigned char*, int, int64_t) = cupdate;\n";
  371. s = s "void (*mfcwrite)(Chan*, unsigned char*, int, int64_t) = cwrite;\n\n";
  372. }
  373. else{
  374. s = s "void (*mfcinit)(void) = nil;\n";
  375. s = s "void (*mfcopen)(Chan*) = nil;\n";
  376. s = s "int (*mfcread)(Chan*, unsigned char*, int, int64_t) = nil;\n";
  377. s = s "void (*mfcupdate)(Chan*, unsigned char*, int, int64_t) = nil;\n";
  378. s = s "void (*mfcwrite)(Chan*, unsigned char*, int, int64_t) = nil;\n\n";
  379. }
  380. if(!("rdb" in misc)){
  381. s = s "void\n";
  382. s = s "rdb(void)\n";
  383. s = s "{\n";
  384. s = s "\tsplhi();\n";
  385. s = s "\tiprint(\"rdb...not installed\\n\");\n";
  386. s = s "\tfor(;;);\n";
  387. s = s "}\n\n";
  388. }
  389. if(objtype == "power"){
  390. for(i = 1; i < section[objtype]; i++){
  391. split(line[objtype, i], a);
  392. m[a[1]] = line[objtype, i];
  393. }
  394. if(!("cnksyscall" in m)){
  395. s = s "void\n";
  396. s = s "cnksyscall(Ureg*)\n";
  397. s = s "{\n";
  398. s = s "\tpanic(\"cnkemu...not installed\\n\");\n";
  399. s = s "\tfor(;;);\n";
  400. s = s "}\n\n";
  401. s = s "void*\n";
  402. s = s "cnksysexecregs(uintptr, uint32_t, uint32_t)\n";
  403. s = s "{\n";
  404. s = s "\tpanic(\"cnkemu...not installed\\n\");\n";
  405. s = s "\tfor(;;);\n";
  406. s = s "}\n\n";
  407. }
  408. }
  409. if("conf" in section){
  410. for(i = 1; i < section["conf"]; i++)
  411. s = s line["conf", i] "\n";
  412. s = s "\n";
  413. }
  414. t = ".";
  415. while("pwd" | getline > 0){
  416. if($0 ~ /^\//)
  417. t = $0;
  418. }
  419. s = s "char* conffile = \"" t "/" ARGV[argc] "\";\n";
  420. s = s "uint32_t kerndate = KERNDATE;\n";
  421. return s;
  422. }
  423. function mkrootrules(name, cname, src, a, i, n){
  424. for(i = 1; i < section["rootdir"]; i++){
  425. n = split(line["rootdir", i], a);
  426. if(n >= 2)
  427. name[i] = a[2];
  428. else
  429. name[i] = a[1];
  430. sub(/.*\//, "", name[i]);
  431. cname[i] = a[1];
  432. gsub(/[^a-zA-Z0-9_]/, "_", cname[i]);
  433. src[i] = a[1];
  434. }
  435. }
  436. function mkrules(dir, exists, ameta, cmeta, flags, f, i, s, t){
  437. for(i in ameta)
  438. delete ameta[i];
  439. for(i in cmeta)
  440. delete cmeta[i];
  441. s = "";
  442. while("cd " dir "; ls *.[cs]" | getline > 0){
  443. if($0 !~ /^[A-Za-z0-9]*\.[cs]$/)
  444. continue;
  445. f = $0;
  446. if(!sub(/\.[cs]$/, ""))
  447. continue;
  448. if($0 in exists)
  449. continue;
  450. exists[$0] = dir;
  451. if(f ~ /\.c$/){
  452. if(!($0 in dbgc)){
  453. cmeta[$0]++;
  454. continue;
  455. }
  456. t = "$CC $CFLAGS " flags;
  457. }
  458. else{
  459. if(!($0 in dbgc)){
  460. ameta[$0]++;
  461. continue;
  462. }
  463. t = "$AS $AFLAGS " flags;
  464. }
  465. s = s $0 ".$O:\t" dir "/" f "\n";
  466. # s = s "\t" t " -D'_DBGC_='" dbgc[$0] "'' " dir "/" f "\n";
  467. s = s "\t" t " -c " dir "/" f "\n";
  468. }
  469. return s;
  470. }
  471. function mkport( array){
  472. arrayify(array, "port", "", ".$O", 1);
  473. return listolate(array, " ");
  474. }
  475. function mklib( array){
  476. arrayify(array, "lib", "/$objtype/lib/", ".a", 1);
  477. return listolate(array," ");
  478. }
  479. function mkmach( a, i, s){
  480. s = "";
  481. for(i = 1; i < section[objtype]; i++){
  482. if(!split(line[objtype, i], a))
  483. continue;
  484. if(s == "")
  485. s = a[1] ".$O";
  486. else
  487. s = s " " a[1] ".$O";
  488. }
  489. return s;
  490. }
  491. function mkdevlist( a, array, i, j, n, s){
  492. for(s in section){
  493. if(line[s, 0] !~ /[ \t]\+dev[^_A-Za-z0-9]*/)
  494. continue;
  495. if(s == "dev")
  496. arrayify(array, s, "dev", ".$O", 1);
  497. else if(s == objtype)
  498. arrayify(array, s, "", ".$O", 0);
  499. else
  500. arrayify(array, s, "", ".$O", 1);
  501. }
  502. return listolate(array, " ");
  503. }
  504. function listolate(array, sep, a, s){
  505. s = "";
  506. for(a in array){
  507. if(s == "")
  508. s = a;
  509. else
  510. s = a sep s;
  511. }
  512. return s;
  513. }
  514. function arrayify(array, tag, prefix, suffix, one, a, i, j, n){
  515. for(i = 1; i < section[tag]; i++){
  516. n = split(line[tag, i], a);
  517. if(one)
  518. array[prefix a[1] suffix]++;
  519. for(j = 2; j <= n; j++){
  520. if(a[$j] ~ /[+=-].*/)
  521. continue;
  522. array[a[j] suffix]++;
  523. }
  524. }
  525. }