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