Charles.Forsyth20060303a828770d19 years agoHistory
267 lines · 5.1 KB · Brainfuck
RawDownload
implement Ckproto; include "sys.m";	sys: Sys;include "draw.m";include "bufio.m";	bufio: Bufio;	Iobuf: import bufio;include "arg.m";	arg: Arg;include "readdir.m";	readdir : Readdir;include "proto.m";	proto : Proto;include "protocaller.m";	protocaller : Protocaller; WARN, ERROR, FATAL : import Protocaller; Ckproto: module{	init:	fn(nil: ref Draw->Context, nil: list of string);	protofile: fn(new : string, old : string, d : ref Sys->Dir);	protoerr: fn(lev : int, line : int, err : string);}; Dir : adt {	name : string;	proto : string;	parent : cyclic ref Dir;	child : cyclic ref Dir;	sibling : cyclic ref Dir;}; root := "/";droot : ref Dir;protof : string;stderr : ref Sys->FD;omitgen := 0;			# forget generated filesverbose : int;ckmode: int; init(nil: ref Draw->Context, args: list of string){	sys = load Sys Sys->PATH;	bufio = load Bufio Bufio->PATH;	arg = load Arg Arg->PATH;	readdir = load Readdir Readdir->PATH;	proto = load Proto Proto->PATH;	protocaller = load Protocaller "$self"; 	stderr = sys->fildes(2);	sys->pctl(Sys->NEWPGRP|Sys->FORKNS|Sys->FORKFD, nil);	arg->init(args);	while ((c := arg->opt()) != 0) {		case c {			'r' =>				root = arg->arg();				if (root == nil)					fatal("missing argument to -r");			'o' =>				omitgen = 1;			'v' =>				verbose = 1;			'm' =>				ckmode = 1;			* =>				fatal("usage: install/ckproto [-o] [-v] [-m] [-r root] protofile ....");		}	}	droot = ref Dir("/", nil, nil, nil, nil);	droot.parent = droot;	args = arg->argv();	while (args != nil) {		protof = hd args;		proto->rdproto(hd args, root, protocaller);		args = tl args;	}	if (verbose)		prtree(droot, -1);	ckdir(root, droot);} protofile(new : string, old : string, nil : ref Sys->Dir){	if (verbose) {		if (old == new)			sys->print("%s\n", new);		else	 		sys->print("%s %s\n", new, old);	}	addfile(droot, old);	if (new != old)		addfile(droot, new);} protoerr(lev : int, line : int, err : string){	s := "line " + string line + " : " + err;	case lev {		WARN => warn(s);		ERROR => error(s);		FATAL => fatal(s);	}} ckdir(d : string, dird : ref Dir){	(dir, n) := readdir->init(d, Readdir->NAME|Readdir->COMPACT);	for (i := 0; i < n; i++) {		dire := lookup(dird, dir[i].name);		if(omitgen && generated(dir[i].name))			continue;		if (dire == nil){			sys->print("%s missing\n", mkpath(d, dir[i].name));			continue;		}		if(ckmode){			if(dir[i].mode & Sys->DMDIR){				if((dir[i].mode & 8r775) != 8r775)					sys->print("directory %s not 775 at least\n", mkpath(d, dir[i].name));			}			else{				if((dir[i].mode & 8r664) != 8r664)					sys->print("file %s not 664 at least\n", mkpath(d, dir[i].name));			}		}		if (dir[i].mode & Sys->DMDIR)			ckdir(mkpath(d, dir[i].name), dire);	}} addfile(root : ref Dir, path : string){	elem : string; 	# ckexists(path);		curd := root;	opath := path;	while (path != nil) {		(elem, path) = split(path);		d := lookup(curd, elem);		if (d == nil) {			d = ref Dir(elem, protof, curd, nil, nil);			if (curd.child == nil)				curd.child = d;			else {				prev, this : ref Dir; 				for (this = curd.child; this != nil; this = this.sibling) {					if (elem < this.name) {						d.sibling = this;						if (prev == nil)							curd.child = d;						else							prev.sibling = d;						break;					}					prev = this;				}				if (this == nil)					prev.sibling = d;			}		}		else if (path == nil && d.proto == protof)			sys->print("%s repeated in proto %s\n", opath, protof);		curd = d;	}} lookup(p : ref Dir, f : string) : ref Dir{	if (f == ".")		return p;	if (f == "..")		return p.parent;	for (d := p.child; d != nil; d = d.sibling) {		if (d.name == f)			return d;		if (d.name > f)			return nil;	}	return nil;} prtree(root : ref Dir, indent : int){	if (indent >= 0)		sys->print("%s%s\n", string array[indent] of { * => byte '\t' }, root.name);	for (s := root.child; s != nil; s = s.sibling)		prtree(s, indent+1);} mkpath(prefix, elem: string): string{	slash1 := slash2 := 0;	if (len prefix > 0)		slash1 = prefix[len prefix - 1] == '/';	if (len elem > 0)		slash2 = elem[0] == '/';	if (slash1 && slash2)		return prefix+elem[1:];	if (!slash1 && !slash2)		return prefix+"/"+elem;	return prefix+elem;} split(p : string) : (string, string){	if (p == nil)		fatal("nil string in split");	if (p[0] != '/')		fatal("p0 notg / in split");	while (p[0] == '/')		p = p[1:];	i := 0;	while (i < len p && p[i] != '/')		i++;	if (i == len p)		return (p, nil);	else		return (p[0:i], p[i:]);}  gens := array[] of {	"dis", "sbl", "out", "0", "1", "2", "5", "8", "k", "q", "v", "t"}; generated(f : string) : int{	for (i := len f -1; i >= 0; i--)		if (f[i] == '.')			break;	if (i < 0)		return 0;	suff := f[i+1:];	for (i = 0; i < len gens; i++)		if (suff == gens[i])			return 1;	return 0;} warn(s: string){	sys->print("%s: %s\n", protof, s);} error(s: string){	sys->fprint(stderr, "%s: %s\n", protof, s);	exit;;} fatal(s: string){	sys->fprint(stderr, "fatal: %s\n", s);	exit;} ckexists(path: string){	s := mkpath(root, path);	(ok, nil) := sys->stat(s);	if(ok < 0)		sys->print("%s does not exist\n", s);}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t