137da2899SCharles.Forsythimplement Attrdb; 237da2899SCharles.Forsyth 337da2899SCharles.Forsyth# 437da2899SCharles.Forsyth# Copyright © 2003 Vita Nuova Holdings Limited. All rights reserved. 537da2899SCharles.Forsyth# 637da2899SCharles.Forsyth 737da2899SCharles.Forsythinclude "sys.m"; 837da2899SCharles.Forsyth sys: Sys; 937da2899SCharles.Forsyth 1037da2899SCharles.Forsythinclude "bufio.m"; 1137da2899SCharles.Forsyth bufio: Bufio; 1237da2899SCharles.Forsyth Iobuf: import bufio; 1337da2899SCharles.Forsyth 1437da2899SCharles.Forsythinclude "attrdb.m"; 1537da2899SCharles.Forsyth 1637da2899SCharles.Forsythinit(): string 1737da2899SCharles.Forsyth{ 1837da2899SCharles.Forsyth sys = load Sys Sys->PATH; 1937da2899SCharles.Forsyth bufio = load Bufio Bufio->PATH; 2037da2899SCharles.Forsyth if(bufio == nil) 2137da2899SCharles.Forsyth return sys->sprint("can't load Bufio: %r"); 2237da2899SCharles.Forsyth return nil; 2337da2899SCharles.Forsyth} 2437da2899SCharles.Forsyth 2537da2899SCharles.Forsythparseentry(s: string, lno: int): (ref Dbentry, int, string) 2637da2899SCharles.Forsyth{ 2737da2899SCharles.Forsyth (nil, flds) := sys->tokenize(s, "\n"); 2837da2899SCharles.Forsyth lines: list of ref Tuples; 2937da2899SCharles.Forsyth errs: string; 3037da2899SCharles.Forsyth for(; flds != nil; flds = tl flds){ 3137da2899SCharles.Forsyth (ts, err) := parseline(hd flds, lno); 3237da2899SCharles.Forsyth if(ts != nil) 3337da2899SCharles.Forsyth lines = ts :: lines; 3437da2899SCharles.Forsyth else if(err != nil && errs == nil) 3537da2899SCharles.Forsyth errs = err; 3637da2899SCharles.Forsyth lno++; 3737da2899SCharles.Forsyth } 3837da2899SCharles.Forsyth return (ref Dbentry(0, lines), lno, errs); 3937da2899SCharles.Forsyth} 4037da2899SCharles.Forsyth 4137da2899SCharles.Forsythparseline(s: string, lno: int): (ref Tuples, string) 4237da2899SCharles.Forsyth{ 4337da2899SCharles.Forsyth attrs: list of ref Attr; 4437da2899SCharles.Forsyth quote := 0; 4537da2899SCharles.Forsyth word := ""; 4637da2899SCharles.Forsyth lastword := ""; 4737da2899SCharles.Forsyth name := ""; 4837da2899SCharles.Forsyth 4937da2899SCharles.ForsythLine: 5037da2899SCharles.Forsyth for(i := 0; i < len s; i++) { 5137da2899SCharles.Forsyth if(quote) { 5237da2899SCharles.Forsyth if(s[i] == quote) { 5337da2899SCharles.Forsyth if(i+1 >= len s || s[i+1] != quote){ 5437da2899SCharles.Forsyth quote = 0; 5537da2899SCharles.Forsyth continue; 5637da2899SCharles.Forsyth } 5737da2899SCharles.Forsyth i++; 5837da2899SCharles.Forsyth } 5937da2899SCharles.Forsyth word[len word] = s[i]; 6037da2899SCharles.Forsyth continue; 6137da2899SCharles.Forsyth } 6237da2899SCharles.Forsyth case s[i] { 6337da2899SCharles.Forsyth '\'' or '\"' => 6437da2899SCharles.Forsyth quote = s[i]; 6537da2899SCharles.Forsyth '#' => 6637da2899SCharles.Forsyth break Line; 6737da2899SCharles.Forsyth ' ' or '\t' or '\n' => 6837da2899SCharles.Forsyth if(word == nil) 6937da2899SCharles.Forsyth continue; 7037da2899SCharles.Forsyth if(lastword != nil) { 7137da2899SCharles.Forsyth # lastword space word space 7237da2899SCharles.Forsyth attrs = ref Attr(lastword, nil, 0) :: attrs; 7337da2899SCharles.Forsyth } 7437da2899SCharles.Forsyth lastword = word; 7537da2899SCharles.Forsyth word = nil; 7637da2899SCharles.Forsyth 7737da2899SCharles.Forsyth if(name != nil) { 7837da2899SCharles.Forsyth # name = lastword space 7937da2899SCharles.Forsyth attrs = ref Attr(name, lastword, 0) :: attrs; 8037da2899SCharles.Forsyth name = lastword = nil; 8137da2899SCharles.Forsyth } 8237da2899SCharles.Forsyth '=' => 8337da2899SCharles.Forsyth if(lastword == nil) { 8437da2899SCharles.Forsyth # word= 8537da2899SCharles.Forsyth lastword = word; 8637da2899SCharles.Forsyth word = nil; 8737da2899SCharles.Forsyth } 8837da2899SCharles.Forsyth if(word != nil) { 8937da2899SCharles.Forsyth # lastword word= 9037da2899SCharles.Forsyth attrs = ref Attr(lastword, nil, 0) :: attrs; 9137da2899SCharles.Forsyth lastword = word; 9237da2899SCharles.Forsyth word = nil; 9337da2899SCharles.Forsyth } 9437da2899SCharles.Forsyth if(lastword == nil) 9537da2899SCharles.Forsyth return (nil, "empty name"); 9637da2899SCharles.Forsyth name = lastword; 9737da2899SCharles.Forsyth lastword = nil; 9837da2899SCharles.Forsyth * => 9937da2899SCharles.Forsyth word[len word] = s[i]; 10037da2899SCharles.Forsyth } 10137da2899SCharles.Forsyth } 10237da2899SCharles.Forsyth if(quote) 10337da2899SCharles.Forsyth return (nil, "missing quote"); 10437da2899SCharles.Forsyth 10537da2899SCharles.Forsyth if(lastword == nil) { 10637da2899SCharles.Forsyth lastword = word; 10737da2899SCharles.Forsyth word = nil; 10837da2899SCharles.Forsyth } 10937da2899SCharles.Forsyth 11037da2899SCharles.Forsyth if(name == nil) { 11137da2899SCharles.Forsyth name = lastword; 11237da2899SCharles.Forsyth lastword = nil; 11337da2899SCharles.Forsyth } 11437da2899SCharles.Forsyth 11537da2899SCharles.Forsyth if(name != nil) 11637da2899SCharles.Forsyth attrs = ref Attr(name, lastword, 0) :: attrs; 11737da2899SCharles.Forsyth 11837da2899SCharles.Forsyth if(attrs == nil) 11937da2899SCharles.Forsyth return (nil, nil); 12037da2899SCharles.Forsyth 12137da2899SCharles.Forsyth return (ref Tuples(lno, rev(attrs)), nil); 12237da2899SCharles.Forsyth 12337da2899SCharles.Forsyth} 12437da2899SCharles.Forsyth 12537da2899SCharles.ForsythTuples.hasattr(ts: self ref Tuples, attr: string): int 12637da2899SCharles.Forsyth{ 12737da2899SCharles.Forsyth for(pl := ts.pairs; pl != nil; pl = tl pl){ 12837da2899SCharles.Forsyth a := hd pl; 12937da2899SCharles.Forsyth if(a.attr == attr) 13037da2899SCharles.Forsyth return 1; 13137da2899SCharles.Forsyth } 13237da2899SCharles.Forsyth return 0; 13337da2899SCharles.Forsyth} 13437da2899SCharles.Forsyth 13537da2899SCharles.ForsythTuples.haspair(ts: self ref Tuples, attr: string, value: string): int 13637da2899SCharles.Forsyth{ 13737da2899SCharles.Forsyth for(pl := ts.pairs; pl != nil; pl = tl pl){ 13837da2899SCharles.Forsyth a := hd pl; 13937da2899SCharles.Forsyth if(a.attr == attr && a.val == value) 14037da2899SCharles.Forsyth return 1; 14137da2899SCharles.Forsyth } 14237da2899SCharles.Forsyth return 0; 14337da2899SCharles.Forsyth} 14437da2899SCharles.Forsyth 14537da2899SCharles.ForsythTuples.find(ts: self ref Tuples, attr: string): list of ref Attr 14637da2899SCharles.Forsyth{ 14737da2899SCharles.Forsyth ra: list of ref Attr; 14837da2899SCharles.Forsyth for(pl := ts.pairs; pl != nil; pl = tl pl){ 14937da2899SCharles.Forsyth a := hd pl; 15037da2899SCharles.Forsyth if(a.attr == attr) 15137da2899SCharles.Forsyth ra = a :: ra; 15237da2899SCharles.Forsyth } 15337da2899SCharles.Forsyth return rev(ra); 15437da2899SCharles.Forsyth} 15537da2899SCharles.Forsyth 15637da2899SCharles.ForsythTuples.findbyattr(ts: self ref Tuples, attr: string, value: string, rattr: string): list of ref Attr 15737da2899SCharles.Forsyth{ 15837da2899SCharles.Forsyth if(ts.haspair(attr, value)) 15937da2899SCharles.Forsyth return ts.find(rattr); 16037da2899SCharles.Forsyth return nil; 16137da2899SCharles.Forsyth} 16237da2899SCharles.Forsyth 16337da2899SCharles.ForsythDbentry.find(e: self ref Dbentry, attr: string): list of (ref Tuples, list of ref Attr) 16437da2899SCharles.Forsyth{ 16537da2899SCharles.Forsyth rrt: list of (ref Tuples, list of ref Attr); 16637da2899SCharles.Forsyth for(lines := e.lines; lines != nil; lines = tl lines){ 16737da2899SCharles.Forsyth l := hd lines; 16837da2899SCharles.Forsyth if((ra := l.find(attr)) != nil) 16937da2899SCharles.Forsyth rrt = (l, rev(ra)) :: rrt; 17037da2899SCharles.Forsyth } 17137da2899SCharles.Forsyth rt: list of (ref Tuples, list of ref Attr); 17237da2899SCharles.Forsyth for(; rrt != nil; rrt = tl rrt) 17337da2899SCharles.Forsyth rt = hd rrt :: rt; 17437da2899SCharles.Forsyth return rt; 17537da2899SCharles.Forsyth} 17637da2899SCharles.Forsyth 17737da2899SCharles.ForsythDbentry.findfirst(e: self ref Dbentry, attr: string): string 17837da2899SCharles.Forsyth{ 17937da2899SCharles.Forsyth for(lines := e.lines; lines != nil; lines = tl lines){ 18037da2899SCharles.Forsyth l := hd lines; 18137da2899SCharles.Forsyth for(pl := l.pairs; pl != nil; pl = tl pl) 18237da2899SCharles.Forsyth if((hd pl).attr == attr) 18337da2899SCharles.Forsyth return (hd pl).val; 18437da2899SCharles.Forsyth } 18537da2899SCharles.Forsyth return nil; 18637da2899SCharles.Forsyth} 18737da2899SCharles.Forsyth 18837da2899SCharles.ForsythDbentry.findpair(e: self ref Dbentry, attr: string, value: string): list of ref Tuples 18937da2899SCharles.Forsyth{ 19037da2899SCharles.Forsyth rts: list of ref Tuples; 19137da2899SCharles.Forsyth for(lines := e.lines; lines != nil; lines = tl lines){ 19237da2899SCharles.Forsyth l := hd lines; 19337da2899SCharles.Forsyth if(l.haspair(attr, value)) 19437da2899SCharles.Forsyth rts = l :: rts; 19537da2899SCharles.Forsyth } 19637da2899SCharles.Forsyth for(; rts != nil; rts = tl rts) 19737da2899SCharles.Forsyth lines = hd rts :: lines; 19837da2899SCharles.Forsyth return lines; 19937da2899SCharles.Forsyth} 20037da2899SCharles.Forsyth 20137da2899SCharles.ForsythDbentry.findbyattr(e: self ref Dbentry, attr: string, value: string, rattr: string): list of (ref Tuples, list of ref Attr) 20237da2899SCharles.Forsyth{ 20337da2899SCharles.Forsyth rm: list of (ref Tuples, list of ref Attr); # lines with attr=value and rattr 20437da2899SCharles.Forsyth rnm: list of (ref Tuples, list of ref Attr); # lines with rattr alone 20537da2899SCharles.Forsyth for(lines := e.lines; lines != nil; lines = tl lines){ 20637da2899SCharles.Forsyth l := hd lines; 20737da2899SCharles.Forsyth ra: list of ref Attr = nil; 20837da2899SCharles.Forsyth match := 0; 20937da2899SCharles.Forsyth for(pl := l.pairs; pl != nil; pl = tl pl){ 21037da2899SCharles.Forsyth a := hd pl; 21137da2899SCharles.Forsyth if(a.attr == attr && a.val == value) 21237da2899SCharles.Forsyth match = 1; 21337da2899SCharles.Forsyth if(a.attr == rattr) 21437da2899SCharles.Forsyth ra = a :: ra; 21537da2899SCharles.Forsyth } 21637da2899SCharles.Forsyth if(ra != nil){ 21737da2899SCharles.Forsyth if(match) 21837da2899SCharles.Forsyth rm = (l, rev(ra)) :: rm; 21937da2899SCharles.Forsyth else 22037da2899SCharles.Forsyth rnm = (l, rev(ra)) :: rnm; 22137da2899SCharles.Forsyth } 22237da2899SCharles.Forsyth } 22337da2899SCharles.Forsyth rt: list of (ref Tuples, list of ref Attr); 22437da2899SCharles.Forsyth for(; rnm != nil; rnm = tl rnm) 22537da2899SCharles.Forsyth rt = hd rnm :: rt; 22637da2899SCharles.Forsyth for(; rm != nil; rm = tl rm) 22737da2899SCharles.Forsyth rt = hd rm :: rt; 22837da2899SCharles.Forsyth return rt; 22937da2899SCharles.Forsyth} 23037da2899SCharles.Forsyth 23137da2899SCharles.ForsythDbf.open(path: string): ref Dbf 23237da2899SCharles.Forsyth{ 23337da2899SCharles.Forsyth df := ref Dbf; 23437da2899SCharles.Forsyth df.lockc = chan[1] of int; 23537da2899SCharles.Forsyth df.fd = bufio->open(path, Bufio->OREAD); 23637da2899SCharles.Forsyth if(df.fd == nil) 23737da2899SCharles.Forsyth return nil; 23837da2899SCharles.Forsyth df.name = path; 23937da2899SCharles.Forsyth (ok, d) := sys->fstat(df.fd.fd); 24037da2899SCharles.Forsyth if(ok >= 0) 24137da2899SCharles.Forsyth df.dir = ref d; 24237da2899SCharles.Forsyth # TO DO: indices 24337da2899SCharles.Forsyth return df; 24437da2899SCharles.Forsyth} 24537da2899SCharles.Forsyth 24637da2899SCharles.ForsythDbf.sopen(data: string): ref Dbf 24737da2899SCharles.Forsyth{ 24837da2899SCharles.Forsyth df := ref Dbf; 24937da2899SCharles.Forsyth df.lockc = chan[1] of int; 25037da2899SCharles.Forsyth df.fd = bufio->sopen(data); 25137da2899SCharles.Forsyth if(df.fd == nil) 25237da2899SCharles.Forsyth return nil; 25337da2899SCharles.Forsyth df.name = nil; 25437da2899SCharles.Forsyth df.dir = nil; 25537da2899SCharles.Forsyth return df; 25637da2899SCharles.Forsyth} 25737da2899SCharles.Forsyth 25837da2899SCharles.ForsythDbf.reopen(df: self ref Dbf): int 25937da2899SCharles.Forsyth{ 26037da2899SCharles.Forsyth lock(df); 26137da2899SCharles.Forsyth if(df.name == nil){ 26237da2899SCharles.Forsyth unlock(df); 26337da2899SCharles.Forsyth return 0; 26437da2899SCharles.Forsyth } 26537da2899SCharles.Forsyth fd := bufio->open(df.name, Bufio->OREAD); 26637da2899SCharles.Forsyth if(fd == nil){ 26737da2899SCharles.Forsyth unlock(df); 26837da2899SCharles.Forsyth return -1; 26937da2899SCharles.Forsyth } 27037da2899SCharles.Forsyth df.fd = fd; 27137da2899SCharles.Forsyth df.dir = nil; 27237da2899SCharles.Forsyth (ok, d) := sys->fstat(fd.fd); 27337da2899SCharles.Forsyth if(ok >= 0) 27437da2899SCharles.Forsyth df.dir = ref d; 27537da2899SCharles.Forsyth # TO DO: cache, hash tables 27637da2899SCharles.Forsyth unlock(df); 27737da2899SCharles.Forsyth return 0; 27837da2899SCharles.Forsyth} 27937da2899SCharles.Forsyth 28037da2899SCharles.ForsythDbf.changed(df: self ref Dbf): int 28137da2899SCharles.Forsyth{ 28237da2899SCharles.Forsyth r: int; 28337da2899SCharles.Forsyth 28437da2899SCharles.Forsyth lock(df); 28537da2899SCharles.Forsyth if(df.name == nil){ 28637da2899SCharles.Forsyth unlock(df); 28737da2899SCharles.Forsyth return 0; 28837da2899SCharles.Forsyth } 28937da2899SCharles.Forsyth (ok, d) := sys->stat(df.name); 29037da2899SCharles.Forsyth if(ok < 0) 29137da2899SCharles.Forsyth r = df.fd != nil || df.dir == nil; 29237da2899SCharles.Forsyth else 29337da2899SCharles.Forsyth r = df.dir == nil || !samefile(*df.dir, d); 29437da2899SCharles.Forsyth unlock(df); 29537da2899SCharles.Forsyth return r; 29637da2899SCharles.Forsyth} 29737da2899SCharles.Forsyth 29837da2899SCharles.Forsythsamefile(d1, d2: Sys->Dir): int 29937da2899SCharles.Forsyth{ 30037da2899SCharles.Forsyth # ``it was black ... it was white! it was dark ... it was light! ah yes, i remember it well...'' 30137da2899SCharles.Forsyth return d1.dev==d2.dev && d1.dtype==d2.dtype && 30237da2899SCharles.Forsyth d1.qid.path==d2.qid.path && d1.qid.vers==d2.qid.vers && 30337da2899SCharles.Forsyth d1.mtime == d2.mtime; 30437da2899SCharles.Forsyth} 30537da2899SCharles.Forsyth 30637da2899SCharles.Forsythflatten(ts: list of (ref Tuples, list of ref Attr), attr: string): list of ref Attr 30737da2899SCharles.Forsyth{ 30837da2899SCharles.Forsyth l: list of ref Attr; 30937da2899SCharles.Forsyth for(; ts != nil; ts = tl ts){ 310*9b29ac7eSCharles.Forsyth (line, nil) := hd ts; 31137da2899SCharles.Forsyth t := line.find(attr); 31237da2899SCharles.Forsyth for(; t != nil; t = tl t) 31337da2899SCharles.Forsyth l = hd t :: l; 31437da2899SCharles.Forsyth } 31537da2899SCharles.Forsyth return rev(l); 31637da2899SCharles.Forsyth} 31737da2899SCharles.Forsyth 31837da2899SCharles.ForsythDb.open(path: string): ref Db 31937da2899SCharles.Forsyth{ 32037da2899SCharles.Forsyth df := Dbf.open(path); 32137da2899SCharles.Forsyth if(df == nil) 32237da2899SCharles.Forsyth return nil; 32337da2899SCharles.Forsyth db := ref Db(df :: nil); 32437da2899SCharles.Forsyth (e, nil) := db.findpair(nil, "database", ""); 32537da2899SCharles.Forsyth if(e != nil){ 32637da2899SCharles.Forsyth files := flatten(e.find("file"), "file"); 32737da2899SCharles.Forsyth if(files != nil){ 32837da2899SCharles.Forsyth dbs: list of ref Dbf; 32937da2899SCharles.Forsyth for(; files != nil; files = tl files){ 33037da2899SCharles.Forsyth name := (hd files).val; 33137da2899SCharles.Forsyth if(name == path && df != nil){ 33237da2899SCharles.Forsyth dbs = df :: dbs; 33337da2899SCharles.Forsyth df = nil; 33437da2899SCharles.Forsyth }else if((tf := Dbf.open(name)) != nil) 33537da2899SCharles.Forsyth dbs = tf :: dbs; 33637da2899SCharles.Forsyth } 33737da2899SCharles.Forsyth db.dbs = rev(dbs); 33837da2899SCharles.Forsyth if(df != nil) 33937da2899SCharles.Forsyth db.dbs = df :: db.dbs; 34037da2899SCharles.Forsyth } 34137da2899SCharles.Forsyth } 34237da2899SCharles.Forsyth return db; 34337da2899SCharles.Forsyth} 34437da2899SCharles.Forsyth 34537da2899SCharles.ForsythDb.sopen(data: string): ref Db 34637da2899SCharles.Forsyth{ 34737da2899SCharles.Forsyth df := Dbf.sopen(data); 34837da2899SCharles.Forsyth if(df == nil) 34937da2899SCharles.Forsyth return nil; 35037da2899SCharles.Forsyth return ref Db(df :: nil); 35137da2899SCharles.Forsyth} 35237da2899SCharles.Forsyth 35337da2899SCharles.ForsythDb.append(db1: self ref Db, db2: ref Db): ref Db 35437da2899SCharles.Forsyth{ 35537da2899SCharles.Forsyth if(db1 == nil) 35637da2899SCharles.Forsyth return db2; 35737da2899SCharles.Forsyth if(db2 == nil) 35837da2899SCharles.Forsyth return db1; 35937da2899SCharles.Forsyth dbs := db2.dbs; 36037da2899SCharles.Forsyth for(rl := rev(db1.dbs); rl != nil; rl = tl rl) 36137da2899SCharles.Forsyth dbs = hd rl :: dbs; 36237da2899SCharles.Forsyth return ref Db(dbs); 36337da2899SCharles.Forsyth} 36437da2899SCharles.Forsyth 36537da2899SCharles.ForsythDb.reopen(db: self ref Db): int 36637da2899SCharles.Forsyth{ 36737da2899SCharles.Forsyth f := 0; 36837da2899SCharles.Forsyth for(dbs := db.dbs; dbs != nil; dbs = tl dbs) 36937da2899SCharles.Forsyth if((hd dbs).reopen() < 0) 37037da2899SCharles.Forsyth f = -1; 37137da2899SCharles.Forsyth return f; 37237da2899SCharles.Forsyth} 37337da2899SCharles.Forsyth 37437da2899SCharles.ForsythDb.changed(db: self ref Db): int 37537da2899SCharles.Forsyth{ 37637da2899SCharles.Forsyth f := 0; 37737da2899SCharles.Forsyth for(dbs := db.dbs; dbs != nil; dbs = tl dbs) 37837da2899SCharles.Forsyth f |= (hd dbs).changed(); 37937da2899SCharles.Forsyth return f; 38037da2899SCharles.Forsyth} 38137da2899SCharles.Forsyth 38237da2899SCharles.Forsythisentry(l: string): int 38337da2899SCharles.Forsyth{ 38437da2899SCharles.Forsyth return l!=nil && l[0]!='\t' && l[0]!='\n' && l[0]!=' ' && l[0]!='#'; 38537da2899SCharles.Forsyth} 38637da2899SCharles.Forsyth 38737da2899SCharles.ForsythDbf.readentry(dbf: self ref Dbf, offset: int, attr: string, value: string, useval: int): (ref Dbentry, int, int) 38837da2899SCharles.Forsyth{ 38937da2899SCharles.Forsyth lock(dbf); 39037da2899SCharles.Forsyth fd := dbf.fd; 39137da2899SCharles.Forsyth fd.seek(big offset, 0); 39237da2899SCharles.Forsyth lines: list of ref Tuples; 39337da2899SCharles.Forsyth match := attr == nil; 39437da2899SCharles.Forsyth while((l := fd.gets('\n')) != nil){ 39537da2899SCharles.Forsyth while(isentry(l)){ 39637da2899SCharles.Forsyth lines = nil; 39737da2899SCharles.Forsyth do{ 39837da2899SCharles.Forsyth offset = int fd.offset(); 39937da2899SCharles.Forsyth (t, nil) := parseline(l, 0); 40037da2899SCharles.Forsyth if(t != nil){ 40137da2899SCharles.Forsyth lines = t :: lines; 40237da2899SCharles.Forsyth if(!match){ 40337da2899SCharles.Forsyth if(useval) 40437da2899SCharles.Forsyth match = t.haspair(attr, value); 40537da2899SCharles.Forsyth else 40637da2899SCharles.Forsyth match = t.hasattr(attr); 40737da2899SCharles.Forsyth } 40837da2899SCharles.Forsyth } 40937da2899SCharles.Forsyth l = fd.gets('\n'); 41037da2899SCharles.Forsyth }while(l != nil && !isentry(l)); 41137da2899SCharles.Forsyth if(match && lines != nil){ 41237da2899SCharles.Forsyth rl := lines; 41337da2899SCharles.Forsyth for(lines = nil; rl != nil; rl = tl rl) 41437da2899SCharles.Forsyth lines = hd rl :: lines; 41537da2899SCharles.Forsyth unlock(dbf); 41637da2899SCharles.Forsyth return (ref Dbentry(0, lines), 1, offset); 41737da2899SCharles.Forsyth } 41837da2899SCharles.Forsyth } 41937da2899SCharles.Forsyth } 42037da2899SCharles.Forsyth unlock(dbf); 42137da2899SCharles.Forsyth return (nil, 0, int fd.offset()); 42237da2899SCharles.Forsyth} 42337da2899SCharles.Forsyth 42437da2899SCharles.Forsythnextentry(db: ref Db, ptr: ref Dbptr, attr: string, value: string, useval: int): (ref Dbentry, ref Dbptr) 42537da2899SCharles.Forsyth{ 42637da2899SCharles.Forsyth if(ptr == nil){ 42737da2899SCharles.Forsyth ptr = ref Dbptr.Direct(db.dbs, nil, 0); 42837da2899SCharles.Forsyth # TO DO: index 42937da2899SCharles.Forsyth } 43037da2899SCharles.Forsyth while(ptr.dbs != nil){ 43137da2899SCharles.Forsyth offset: int; 43237da2899SCharles.Forsyth dbf := hd ptr.dbs; 43337da2899SCharles.Forsyth pick p := ptr { 43437da2899SCharles.Forsyth Direct => 43537da2899SCharles.Forsyth offset = p.offset; 43637da2899SCharles.Forsyth Hash => 43737da2899SCharles.Forsyth raise "not done yet"; 43837da2899SCharles.Forsyth } 43937da2899SCharles.Forsyth (e, match, next) := dbf.readentry(offset, attr, value, useval); 44037da2899SCharles.Forsyth if(match) 44137da2899SCharles.Forsyth return (e, ref Dbptr.Direct(ptr.dbs, nil, next)); 44237da2899SCharles.Forsyth if(e == nil) 44337da2899SCharles.Forsyth ptr = ref Dbptr.Direct(tl ptr.dbs, nil, 0); 44437da2899SCharles.Forsyth else 44537da2899SCharles.Forsyth ptr = ref Dbptr.Direct(ptr.dbs, nil, next); 44637da2899SCharles.Forsyth } 44737da2899SCharles.Forsyth return (nil, ptr); 44837da2899SCharles.Forsyth} 44937da2899SCharles.Forsyth 45037da2899SCharles.ForsythDb.find(db: self ref Db, ptr: ref Dbptr, attr: string): (ref Dbentry, ref Dbptr) 45137da2899SCharles.Forsyth{ 45237da2899SCharles.Forsyth return nextentry(db, ptr, attr, nil, 0); 45337da2899SCharles.Forsyth} 45437da2899SCharles.Forsyth 45537da2899SCharles.ForsythDb.findpair(db: self ref Db, ptr: ref Dbptr, attr: string, value: string): (ref Dbentry, ref Dbptr) 45637da2899SCharles.Forsyth{ 45737da2899SCharles.Forsyth return nextentry(db, ptr, attr, value, 1); 45837da2899SCharles.Forsyth} 45937da2899SCharles.Forsyth 46037da2899SCharles.ForsythDb.findbyattr(db: self ref Db, ptr: ref Dbptr, attr: string, value: string, rattr: string): (ref Dbentry, ref Dbptr) 46137da2899SCharles.Forsyth{ 46237da2899SCharles.Forsyth for(;;){ 46337da2899SCharles.Forsyth e: ref Dbentry; 46437da2899SCharles.Forsyth (e, ptr) = nextentry(db, ptr, attr, value, 1); 46537da2899SCharles.Forsyth if(e == nil || e.find(rattr) != nil) 46637da2899SCharles.Forsyth return (e, ptr); 46737da2899SCharles.Forsyth } 46837da2899SCharles.Forsyth} 46937da2899SCharles.Forsyth 47037da2899SCharles.Forsythrev[T](l: list of T): list of T 47137da2899SCharles.Forsyth{ 47237da2899SCharles.Forsyth rl: list of T; 47337da2899SCharles.Forsyth for(; l != nil; l = tl l) 47437da2899SCharles.Forsyth rl = hd l :: rl; 47537da2899SCharles.Forsyth return rl; 47637da2899SCharles.Forsyth} 47737da2899SCharles.Forsyth 47837da2899SCharles.Forsythlock(dbf: ref Dbf) 47937da2899SCharles.Forsyth{ 48037da2899SCharles.Forsyth dbf.lockc <-= 1; 48137da2899SCharles.Forsyth} 48237da2899SCharles.Forsyth 48337da2899SCharles.Forsythunlock(dbf: ref Dbf) 48437da2899SCharles.Forsyth{ 48537da2899SCharles.Forsyth <-dbf.lockc; 48637da2899SCharles.Forsyth} 487