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