| awk ' | 
 | BEGIN{ | 
 | 		if (ARGC < 2) | 
 | 			exit "usage"; | 
 |  | 
 | 		conf = ARGV[1]; | 
 | 		infernoroot = ENVIRON["ROOT"]; | 
 | 		init = ENVIRON["INIT"]; | 
 | 		data2c = ENVIRON["DATA2C"]; | 
 | 		if(data2c == "") | 
 | 			data2c = "data2c" | 
 | 		nroot = 0; | 
 | } | 
 | /^$/{ | 
 | 		next; | 
 | } | 
 | /^#/{ | 
 | 		next; | 
 | } | 
 | collect && /^[^	\t]/{ | 
 | 		collect = 0; | 
 | } | 
 | collect && section ~ "root"{ | 
 | 		dst[nroot] = $1; | 
 | 		if (NF > 1) | 
 | 			src[nroot] = infernoroot $2; | 
 | 		else if (dst[nroot] == "/osinit.dis") | 
 | 			src[nroot] = infernoroot "/dis/" init ".dis"; | 
 | 		else | 
 | 			src[nroot] = infernoroot $1; | 
 | 		for(i=0; i<nroot; i++) | 
 | 			if(dst[i] == dst[nroot]) | 
 | 				break; | 
 | 		if(i == nroot) | 
 | 			nroot++; | 
 | } | 
 | $0 ~ /^[^ \t]/{ | 
 | 		if($0 ~ "(code|dev|ether|ip|lib|link|mod|misc|port|root|vga)"){ | 
 | 			section = $0; | 
 | 			collect = 1; | 
 | 		} | 
 | 		next; | 
 | } | 
 | END{ | 
 | 		rootdata = conf ".root.c"; | 
 | 		system("rm -f " rootdata); | 
 | 		print("/* Generated by mkroot */") >rootdata; | 
 | 		close(rootdata); | 
 | 		isdir[0] = 1; | 
 | 		dotdot[0] = 0; | 
 | 		qid = 1; | 
 | 		for (i = 0; i < nroot; i++) { | 
 | 			ncomp = split(dst[i], comp, "/"); | 
 | 			if (comp[1] != "" || ncomp < 2) | 
 | 				continue; | 
 | 			q = 0; | 
 | 			for (j = 2; j <= ncomp; j++) { | 
 | 				key = q "/" comp[j]; | 
 | 				if (walk[key] == 0) { | 
 | 					walk[key] = qid; | 
 | 					dotdot[qid] = q; | 
 | 					q = qid++; | 
 | 					name[q] = comp[j]; | 
 | 					if (j < ncomp) | 
 | 						isdir[q] = 1; | 
 | 				} | 
 | 				else | 
 | 					q = walk[key]; | 
 | 			} | 
 | 			if (system("test -d " src[i]) == 0) | 
 | 				isdir[q] = 1; | 
 | 			else { | 
 | 				if (system(data2c " root" q " <" src[i] " >>" rootdata) != 0) | 
 | 					exit 1; | 
 | 				print("extern unsigned char root" q "code[];"); | 
 | 				print("extern int root" q "len;"); | 
 | 			} | 
 | 		} | 
 |  | 
 | 		x = 1; | 
 | 		sort[0] = 0; | 
 | 		unsort[0] = 0; | 
 | 		for (q = 0; q < qid; q++) { | 
 | 			if (isdir[q]) { | 
 | 				nchild[q] = 0; | 
 | 				for (q2 = 1; q2 < qid; q2++) { | 
 | 					if (dotdot[q2] == q) { | 
 | 						if (nchild[q]++ == 0) | 
 | 							child0[q] = x; | 
 | 						sort[q2] = x++; | 
 | 						unsort[sort[q2]] = q2; | 
 | 					} | 
 | 				} | 
 | 			} | 
 | 		} | 
 |  | 
 | 		print("int rootmaxq = " qid ";"); | 
 |  | 
 | 		print("Dirtab roottab[" qid "] = {"); | 
 | 		for (oq = 0; oq < qid; oq++) { | 
 | 			q = unsort[oq]; | 
 | 			if (!isdir[q]) | 
 | 				print("\t\"" name[q] "\",\t{" oq ", 0, QTFILE},\t", "0,\t0444,"); | 
 | 			else | 
 | 				print("\t\"" name[q] "\",\t{" oq ", 0, QTDIR},\t", "0,\t0555,"); | 
 | 		} | 
 | 		print("};"); | 
 |  | 
 | 		print("Rootdata rootdata[" qid "] = {"); | 
 | 		for (oq = 0; oq < qid; oq++) { | 
 | 			q = unsort[oq]; | 
 | 			if (!isdir[q]) | 
 | 				print("\t" sort[dotdot[q]] ",\t", "root" q "code,\t", "0,\t", "&root" q "len,"); | 
 | 			else if (nchild[q]) | 
 | 				print("\t" sort[dotdot[q]] ",\t", "&roottab[" child0[q] "],\t", nchild[q] ",\tnil,"); | 
 | 			else | 
 | 				print("\t" sort[dotdot[q]] ",\t", "nil,\t", "0,\t", "nil,"); | 
 | 		} | 
 | 		print("};"); | 
 | } | 
 | ' $1 >$1.root.h |