forsyth20121205-174063a80cc13 years agoHistory
305 lines · 5.3 KB · Brainfuck
RawDownload
#	# Copyright © 2001 Vita Nuova (Holdings) Limited.  All rights reserved.	# implement Wrap2list; # make a version list suitable for SDS from /wrap include "sys.m";	sys : Sys;include "draw.m";include "bufio.m";	bufio : Bufio;	Iobuf : import bufio;include "crc.m";	crcm : Crc;include "wrap.m";	wrap: Wrap; Wrap2list: module{	init : fn(ctxt: ref Draw->Context, argv: list of string);}; stderr: ref Sys->FD; HASHSZ: con 64; Element: type string; Hash: adt{	elems: array of Element;	nelems: int;}; List: adt{	tabs: array of ref Hash;	init: fn(l: self ref List);	add: fn(l: self ref List, e: Element);	subtract: fn(l: self ref List, e: Element);	end: fn(l: self ref List): array of Element;}; flist: ref List; hash(s: string): int{	h := 0;	n := len s;	for(i := 0; i < n; i++)		h += s[i];	if(h < 0)		h = -h;	return h%HASHSZ;} List.init(l: self ref List){	ts := l.tabs = array[HASHSZ] of ref Hash;	for(i := 0; i < HASHSZ; i++){		t := ts[i] = ref Hash;		t.elems = array[HASHSZ] of Element;		t.nelems = 0;	}} List.add(l: self ref List, e: Element){	h := hash(e);	t := l.tabs[h];	n := t.nelems;	es := t.elems;	for(i := 0; i < n; i++){		if(e == es[i])			return;	}	if(n == len es)		es = t.elems = (array[2*n] of Element)[0:] = es;	es[t.nelems++] = e;# sys->print("+ %s\n", e);} List.subtract(l: self ref List, e: Element){	h := hash(e);	t := l.tabs[h];	n := t.nelems;	es := t.elems;	for(i := 0; i < n; i++){		if(e == es[i]){			es[i] = nil;			break;		}	}# sys->print("- %s\n", e);} List.end(l: self ref List): array of Element{	tot := 0;	ts := l.tabs;	for(i := 0; i < HASHSZ; i++)		tot += ts[i].nelems;	a := array[tot] of Element;	m := 0;	for(i = 0; i < HASHSZ; i++){		t := ts[i];		n := t.nelems;		es := t.elems;		a[m:] = es[0: n];		m += n;	}	return a;} usage(){	sys->fprint(stderr, "Usage: wrap2list [ file ... ]\n");	exit;} init(nil: ref Draw->Context, argv: list of string){	sys = load Sys Sys->PATH;	bufio = load Bufio Bufio->PATH;	crcm = load Crc Crc->PATH;	wrap = load Wrap Wrap->PATH;	wrap->init(bufio);	if(argv != nil)		argv = tl argv;	init := 0;	if(argv != nil && hd argv == "-i"){		init = 1;		argv = tl argv;	}	stderr = sys->fildes(2);	# root := "/";	flist = ref List;	flist.init();	fd := sys->open("/wrap", Sys->OREAD);	for(;;){		(nd, d) := sys->dirread(fd);		if(nd <= 0)			break;		for(i:=0; i<nd; i++){			if((d[0].mode & Sys->DMDIR) && (w := wrap->openwrap(d[i].name, "/", 1)) != nil){				# sys->fprint(stderr, "%s %s %d %d\n", w.name, w.root, w.tfull, w.nu);				for(j := 0; j < w.nu; j++){					addfiles(w.u[j].bmd5);					if((b := bufio->open(w.u[j].dir+"/remove", Bufio->OREAD)) != nil)						subtractfiles(b);					# sys->fprint(stderr, "%d: %s %s %d %d %d\n", i, w.u[j].desc, w.u[j].dir, w.u[j].time, w.u[j].utime, w.u[j].typ);				}			}		}	}	for( ; argv != nil; argv = tl argv){		if((b := bufio->open(hd argv, Bufio->OREAD)) != nil)			addfiles(b);	}	out(uniq(rmnil(sort(flist.end()))), init);} addfiles(b: ref Bufio->Iobuf){	b.seek(big 0, Bufio->SEEKSTART);	while((s := b.gets('\n')) != nil){		(n, l) := sys->tokenize(s, " \n");		if(n > 0)			flist.add(hd l);	}} subtractfiles(b: ref Bufio->Iobuf){	b.seek(big 0, Bufio->SEEKSTART);	while((s := b.gets('\n')) != nil){		(n, l) := sys->tokenize(s, " \n");		if(n > 0)			flist.subtract(hd l);	}} out(fs: array of Element, init: int){	nf := len fs;	for(i := 0; i < nf; i++){		f := fs[i];		outl(f, nil, init);		l := len f;		if(l >= 7 && f[l-7:] == "emu.new"){			g := f;			f[l-3] = 'e';			f[l-2] = 'x';			f[l-1] = 'e';			outl(f, g, init);		# try emu.exe			outl(f[0: l-4], g, init);	# try emu# sys->fprint(sys->fildes(2), "%s %s\n", f, g);		}	}} outl(f: string, g: string, init: int){	(ok, d) := sys->stat(f);	if(ok < 0){		# sys->fprint(stderr, "cannot open %s\n", f);		return;	}	if(g == nil)		g = "-";	if(d.mode & Sys->DMDIR)		d.length = big 0;	if(init)		mtime := 0;	else		mtime = d.mtime;	sys->print("%s	%s	%d	%d	%d	%d	%d\n", f, g, int d.length, d.mode, mtime, crc(f, d), 0);} crc(f: string, d: Sys->Dir): int{	crcs := crcm->init(0, int 16rffffffff);	if(d.mode & Sys->DMDIR)		return 0;	fd := sys->open(f, Sys->OREAD);	if(fd == nil){		sys->fprint(stderr, "cannot open %s\n", f);		return 0;	}	crc := 0;	buf := array[Sys->ATOMICIO] of byte;	for(;;){		nr := sys->read(fd, buf, len buf);		if(nr < 0){			sys->fprint(stderr, "bad read on %s : %r\n", f);			return 0;		}		if(nr <= 0)			break;		crc = crcm->crc(crcs, buf, nr);	}	crcm->reset(crcs);	return crc;} sort(a: array of Element): array of Element{	qsort(a, len a);	return a;} rmnil(a: array of Element): array of Element{	n := len a;	for(i := 0; i < n; i++)		if(a[i] != nil)			break;	return a[i: n];} uniq(a: array of Element): array of Element{	n := len a;	for(i := 0; i < n-1; ){		if(a[i] == a[i+1])			a[i+1:] = a[i+2: n--];		else			i++;	}	return a[0: n];} qsort(a: array of Element, n: int){	i, j: int;	t: Element; 	while(n > 1){		i = n>>1;		t = a[0]; a[0] = a[i]; a[i] = t;		i = 0;		j = n;		for(;;){			do				i++;			while(i < n && a[i] < a[0]);			do				j--;			while(j > 0 && a[j] > a[0]);			if(j < i)				break;			t = a[i]; a[i] = a[j]; a[j] = t;		}		t = a[0]; a[0] = a[j]; a[j] = t;		n = n-j-1;		if(j >= n){			qsort(a, j);			a = a[j+1:];		}else{			qsort(a[j+1:], n);			n = j;		}	}}