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