Charles.Forsyth20070607-163224a543919 years agoHistory
139 lines · 3.2 KB · Brainfuck
RawDownload
implement Man; include "sys.m";	sys: Sys;include "filepat.m";include "bufio.m";include "man.m"; MANPATH: con "/man/";PATHDEPTH: con 1; indices: list of (string, list of (string, string)); loadsections(scanlist: list of string): string{	sys = load Sys Sys->PATH;	bufio := load Bufio Bufio->PATH;	Iobuf: import bufio; 	if (bufio == nil)		return sys->sprint("cannot load %s: %r", Bufio->PATH); 	indexpaths: list of string;	if (scanlist == nil) {		filepat := load Filepat Filepat->PATH;		if (filepat == nil)			return sys->sprint("cannot load %s: %r", Filepat->PATH); 		indexpaths = filepat->expand(MANPATH + "[0-9]*/INDEX");		if (indexpaths == nil)			return "cannot find man pages";	} else {		for (; scanlist != nil; scanlist = tl scanlist)			indexpaths = MANPATH + trimdot(hd scanlist) + "/INDEX" :: indexpaths;		indexpaths = sortuniq(indexpaths);	} 	sections: list of string;	for (; indexpaths != nil; indexpaths = tl indexpaths) {		path := hd indexpaths;		(nil, toks) := sys->tokenize(path, "/");		for (d := 0; d < PATHDEPTH; d++)			toks = tl toks;		sections = hd toks :: sections;	} 	for (sl := sections; sl != nil; sl = tl sl) {		section := hd sl;		path := MANPATH + section + "/INDEX";		iob := bufio->open(path, Sys->OREAD);		if (iob == nil)			continue;		pairs: list of (string, string) = nil;				while((s := iob.gets('\n')) != nil) {			if (s[len s - 1] == '\n')				s = s[0:len s - 1];			(n, toks) := sys->tokenize(s, " ");			if (n != 2)				continue;			pairs = (hd toks, hd tl toks) :: pairs;		}		iob.close();		indices = (section, pairs) :: indices;	}	return nil;} trimdot(s: string): string{	for(i := 0; i < len s; i++)		if(s[i] == '.')			return s[0: i];	return s;} getfiles(sections: list of string, keys: list of string): list of (int, string, string){	ixl: list of (string, list of (string, string)); 	if (sections == nil)		ixl = indices;	else {		for (; sections != nil; sections = tl sections) {			section := trimdot(hd sections);			for (il := indices; il != nil; il = tl il) {				(s, mapl) := hd il;				if (s == section) {					ixl = (s, mapl) :: ixl;					break;				}			}		}	}	paths: list of (int, string, string);	for(keyl := keys; keyl != nil; keyl = tl keyl){		for (; ixl != nil; ixl = tl ixl) {			for ((s, mapl) := hd ixl; mapl != nil; mapl = tl mapl) {				(kw, file) := hd mapl;				if (hd keyl == kw) {					p := MANPATH + trimdot(s) + "/" + file;					paths = (int s, kw, p) :: paths;				}			}			# allow files not in the index			if(paths == nil || (hd paths).t0 != int s || (hd paths).t1 != hd keyl){				p := MANPATH + string int s + "/" + hd keyl;				if(sys->stat(p).t0 != -1)					paths = (int s, hd keyl, p) :: paths;			}		}	}	return paths;} sortuniq(strlist: list of string): list of string{	strs := array [len strlist] of string;	for (i := 0; strlist != nil; (i, strlist) = (i+1, tl strlist))		strs[i] = hd strlist; 	# simple sort (greatest first)	for (i = 0; i < len strs - 1; i++) {		for (j := i+1; j < len strs; j++)			if (strs[i] < strs[j])				(strs[i], strs[j]) = (strs[j], strs[i]);	} 	# construct list (result is ascending)	r: list of string;	prev := "";	for (i = 0; i < len strs; i++) {		if (strs[i] != prev) {			r = strs[i] :: r;			prev = strs[i];		}	}	return r;}