| @@ -28,13 +28,11 @@ bout: ref Iobuf; · 27 unmodified lines |
| 28 | 28 | debug := 0; |
| 29 | 29 | fold, direc, exact, iflag, range: int; |
| 30 | 30 | rev := 1; # -1 for reverse-ordered file, not implemented |
| 31 | +compare: ref fn(a, b: string): int; |
| 31 | 32 | tab := '\t'; |
| 32 | | −nflag := 0; |
| 33 | 33 | entry: string; |
| 34 | 34 | word: string; |
| 35 | 35 | key: string; |
| 36 | | −orig: string; |
| 37 | | −targ: string; |
| 38 | 36 | latin_fold_tab := array[64] of { |
| 39 | 37 | # Table to fold latin 1 characters to ASCII equivalents |
| 40 | 38 | # based at Rune value 0xc0 |
| @@ -64,10 +62,15 @@ init(nil: ref Draw->Context, args: list of string) · 23 unmodified lines |
| 64 | 62 | bufio = load Bufio Bufio->PATH; |
| 65 | 63 | arg := load Arg Arg->PATH; |
| 66 | 64 | |
| 65 | + lastkey: string; |
| 66 | + |
| 67 | 67 | arg->init(args); |
| 68 | | − arg->setusage(arg->progname()+" -[dfinx] [-r orig] [-t c] [string] [file]"); |
| 68 | + arg->setusage("look -[dfinx] [-r lastkey] [-t c] [string] [file]"); |
| 69 | + compare = acomp; |
| 69 | 70 | while((c := arg->opt()) != 0) |
| 70 | 71 | case c { |
| 72 | + 'D' => |
| 73 | + debug = 1; |
| 71 | 74 | 'd' => |
| 72 | 75 | direc++; |
| 73 | 76 | 'f' => |
| @@ -75,37 +78,37 @@ init(nil: ref Draw->Context, args: list of string) · 1 unmodified line |
| 75 | 78 | 'i' => |
| 76 | 79 | iflag++; |
| 77 | 80 | 'n' => |
| 78 | | − nflag = 1; |
| 81 | + compare = ncomp; |
| 79 | 82 | 't' => |
| 80 | 83 | tab = (arg->earg())[0]; |
| 81 | 84 | 'x' => |
| 82 | 85 | exact++; |
| 83 | 86 | 'r' => |
| 84 | 87 | range++; |
| 85 | | − orig = arg->earg(); |
| 86 | | − targ = rcanon(orig); |
| 88 | + lastkey = rcanon(arg->earg()); |
| 87 | 89 | * => |
| 88 | | − sys->fprint(sys->fildes(2), "%s: bad option %c\n", arg->progname(), c); |
| 89 | | − sys->fprint(sys->fildes(2), "usage: %s -[dfinx] [-t c] [-r limit] [string] [file]\n", arg->progname()); |
| 90 | | − raise "fail:usage"; |
| 90 | + arg->usage(); |
| 91 | 91 | } |
| 92 | 92 | args = arg->argv(); |
| 93 | 93 | arg = nil; |
| 94 | 94 | |
| 95 | 95 | bin := bufio->fopen(sys->fildes(0), Sys->OREAD); |
| 96 | 96 | bout = bufio->fopen(sys->fildes(1), Sys->OWRITE); |
| 97 | | − if(!iflag) |
| 97 | + orig: string; |
| 98 | + if(!iflag){ |
| 98 | 99 | if(args != nil){ |
| 99 | 100 | orig = hd args; |
| 100 | 101 | args = tl args; |
| 101 | | − key = rcanon(orig); |
| 102 | 102 | }else |
| 103 | 103 | iflag++; |
| 104 | + } |
| 104 | 105 | if(args == nil){ |
| 105 | 106 | direc++; |
| 106 | 107 | fold++; |
| 107 | 108 | }else |
| 108 | 109 | filename = hd args; |
| 110 | + if(!iflag) |
| 111 | + key = rcanon(orig); |
| 109 | 112 | if(debug) |
| 110 | 113 | sys->fprint(sys->fildes(2), "orig %s key %s %s\n", orig, key, filename); |
| 111 | 114 | dfile = bufio->open(filename, Sys->OREAD); |
| @@ -114,7 +117,7 @@ init(nil: ref Draw->Context, args: list of string) · 2 unmodified lines |
| 114 | 117 | raise "fail:no dictionary"; |
| 115 | 118 | } |
| 116 | 119 | if(!iflag) |
| 117 | | − if(!locate() && !range && exact) |
| 120 | + if(!locate() && !range) |
| 118 | 121 | raise "fail:not found"; |
| 119 | 122 | do{ |
| 120 | 123 | if(iflag){ |
| @@ -126,36 +129,34 @@ init(nil: ref Draw->Context, args: list of string) · 5 unmodified lines |
| 126 | 129 | continue; |
| 127 | 130 | } |
| 128 | 131 | if(range){ |
| 129 | | − if(compare(key, word) <= 0 && compare(word, targ) <= 0) |
| 132 | + if(compare(key, word) <= 0 && compare(word, lastkey) <= 0) |
| 130 | 133 | bout.puts(entry); |
| 131 | | − }else if(!exact || !compare(word, key)) |
| 134 | + }else if(!exact || acomp(word, orig) == 0) |
| 132 | 135 | bout.puts(entry); |
| 136 | + Matches: |
| 133 | 137 | while((entry = dfile.gets('\n')) != nil){ |
| 134 | 138 | word = rcanon(entry); |
| 135 | 139 | if(range) |
| 136 | | − n := compare(word, targ); |
| 140 | + n := compare(word, lastkey); |
| 137 | 141 | else |
| 138 | 142 | n = compare(key, word); |
| 139 | 143 | if(debug) |
| 140 | | − sys->print("compare %d\n", n); |
| 144 | + sys->print("compare %d %q\n", n, word); |
| 141 | 145 | case n { |
| 142 | 146 | -2 => |
| 143 | | − if(range){ |
| 144 | | − bout.puts(entry); |
| 145 | | − continue; |
| 146 | | − } |
| 147 | + if(!range) |
| 148 | + break Matches; |
| 149 | + bout.puts(entry); |
| 147 | 150 | -1 => |
| 148 | 151 | if(exact) |
| 149 | | − break; |
| 150 | | − if(!exact || !compare(word, key)) |
| 151 | | − bout.puts(entry); |
| 152 | | − continue; |
| 152 | + break Matches; |
| 153 | + bout.puts(entry); |
| 153 | 154 | 0 => |
| 154 | | − if(!exact || !compare(word, key)) |
| 155 | + if(!exact || acomp(word, orig) == 0) |
| 155 | 156 | bout.puts(entry); |
| 156 | | − continue; |
| 157 | + * => |
| 158 | + break Matches; |
| 157 | 159 | } |
| 158 | | − break; |
| 159 | 160 | } |
| 160 | 161 | }while(iflag); |
| 161 | 162 | bout.flush(); |
| @@ -208,26 +209,16 @@ Search: · 46 unmodified lines |
| 208 | 209 | -2 => |
| 209 | 210 | return 0; |
| 210 | 211 | -1 => |
| 211 | | − if(exact) |
| 212 | | − return 0; |
| 213 | | − return 1; |
| 212 | + return !exact; |
| 214 | 213 | 0 => |
| 215 | 214 | return 1; |
| 216 | 215 | 1 or 2 => |
| 217 | | − continue; |
| 216 | + ; |
| 218 | 217 | } |
| 219 | 218 | } |
| 220 | 219 | return 0; |
| 221 | 220 | } |
| 222 | 221 | |
| 223 | | −compare(s, t: string): int |
| 224 | | −{ |
| 225 | | − if(nflag) |
| 226 | | − return ncomp(s, t); |
| 227 | | − else |
| 228 | | − return acomp(s, t); |
| 229 | | −} |
| 230 | | − |
| 231 | 222 | # |
| 232 | 223 | # acomp(s, t) returns: |
| 233 | 224 | # -2 if s strictly precedes t |
| @@ -265,7 +256,7 @@ rcanon(s: string): string · 31 unmodified lines |
| 265 | 256 | s = s[0: len s - 1]; |
| 266 | 257 | o := 0; |
| 267 | 258 | for(i := 0; i < len s && (r := s[i]) != tab; i++){ |
| 268 | | − if(16rc0 <= r && r <= 16rff && (mr := latin_fold_tab[r-16rc0]) != 0) |
| 259 | + if(islatin1(r) && (mr := latin_fold_tab[r-16rc0]) != 0) |
| 269 | 260 | r = mr; |
| 270 | 261 | if(direc) |
| 271 | 262 | if(!(isalnum(r) || r == ' ' || r == '\t')) |