Blame


1 c8af1ab1 2004-04-19 devnull #include <u.h>
2 c8af1ab1 2004-04-19 devnull #include <libc.h>
3 c8af1ab1 2004-04-19 devnull #include <bio.h>
4 c8af1ab1 2004-04-19 devnull /* Macros for Rune support of ctype.h-like functions */
5 c8af1ab1 2004-04-19 devnull
6 b4a659b6 2004-04-19 devnull #undef isupper
7 b4a659b6 2004-04-19 devnull #undef islower
8 b4a659b6 2004-04-19 devnull #undef isalpha
9 b4a659b6 2004-04-19 devnull #undef isdigit
10 b4a659b6 2004-04-19 devnull #undef isalnum
11 b4a659b6 2004-04-19 devnull #undef isspace
12 b4a659b6 2004-04-19 devnull #undef tolower
13 bb0266fe 2005-05-07 devnull #define isupper(r) ('A' <= (r) && (r) <= 'Z')
14 bb0266fe 2005-05-07 devnull #define islower(r) ('a' <= (r) && (r) <= 'z')
15 c8af1ab1 2004-04-19 devnull #define isalpha(r) (isupper(r) || islower(r))
16 c8af1ab1 2004-04-19 devnull #define islatin1(r) (0xC0 <= (r) && (r) <= 0xFF)
17 c8af1ab1 2004-04-19 devnull
18 bb0266fe 2005-05-07 devnull #define isdigit(r) ('0' <= (r) && (r) <= '9')
19 c8af1ab1 2004-04-19 devnull
20 c8af1ab1 2004-04-19 devnull #define isalnum(r) (isalpha(r) || isdigit(r))
21 c8af1ab1 2004-04-19 devnull
22 bb0266fe 2005-05-07 devnull #define isspace(r) ((r) == ' ' || (r) == '\t' \
23 c8af1ab1 2004-04-19 devnull || (0x0A <= (r) && (r) <= 0x0D))
24 c8af1ab1 2004-04-19 devnull
25 c8af1ab1 2004-04-19 devnull #define tolower(r) ((r)-'A'+'a')
26 c8af1ab1 2004-04-19 devnull
27 c8af1ab1 2004-04-19 devnull #define sgn(v) ((v) < 0 ? -1 : ((v) > 0 ? 1 : 0))
28 c8af1ab1 2004-04-19 devnull
29 c8af1ab1 2004-04-19 devnull #define WORDSIZ 4000
30 c8af1ab1 2004-04-19 devnull char *filename = "#9/lib/words";
31 c8af1ab1 2004-04-19 devnull Biobuf *dfile;
32 c8af1ab1 2004-04-19 devnull Biobuf bout;
33 c8af1ab1 2004-04-19 devnull Biobuf bin;
34 c8af1ab1 2004-04-19 devnull
35 c8af1ab1 2004-04-19 devnull int fold;
36 c8af1ab1 2004-04-19 devnull int direc;
37 c8af1ab1 2004-04-19 devnull int exact;
38 c8af1ab1 2004-04-19 devnull int iflag;
39 c8af1ab1 2004-04-19 devnull int rev = 1; /*-1 for reverse-ordered file, not implemented*/
40 c8af1ab1 2004-04-19 devnull int (*compare)(Rune*, Rune*);
41 c8af1ab1 2004-04-19 devnull Rune tab = '\t';
42 c8af1ab1 2004-04-19 devnull Rune entry[WORDSIZ];
43 c8af1ab1 2004-04-19 devnull Rune word[WORDSIZ];
44 c8af1ab1 2004-04-19 devnull Rune key[50], orig[50];
45 c8af1ab1 2004-04-19 devnull Rune latin_fold_tab[] =
46 c8af1ab1 2004-04-19 devnull {
47 c8af1ab1 2004-04-19 devnull /* Table to fold latin 1 characters to ASCII equivalents
48 c8af1ab1 2004-04-19 devnull based at Rune value 0xc0
49 c8af1ab1 2004-04-19 devnull
50 c8af1ab1 2004-04-19 devnull À Á Â Ã Ä Å Æ Ç
51 c8af1ab1 2004-04-19 devnull È É Ê Ë Ì Í Î Ï
52 c8af1ab1 2004-04-19 devnull Ð Ñ Ò Ó Ô Õ Ö ×
53 c8af1ab1 2004-04-19 devnull Ø Ù Ú Û Ü Ý Þ ß
54 c8af1ab1 2004-04-19 devnull à á â ã ä å æ ç
55 c8af1ab1 2004-04-19 devnull è é ê ë ì í î ï
56 c8af1ab1 2004-04-19 devnull ð ñ ò ó ô õ ö ÷
57 c8af1ab1 2004-04-19 devnull ø ù ú û ü ý þ ÿ
58 c8af1ab1 2004-04-19 devnull */
59 c8af1ab1 2004-04-19 devnull 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'c',
60 c8af1ab1 2004-04-19 devnull 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i',
61 c8af1ab1 2004-04-19 devnull 'd', 'n', 'o', 'o', 'o', 'o', 'o', 0 ,
62 c8af1ab1 2004-04-19 devnull 'o', 'u', 'u', 'u', 'u', 'y', 0 , 0 ,
63 c8af1ab1 2004-04-19 devnull 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'c',
64 c8af1ab1 2004-04-19 devnull 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i',
65 c8af1ab1 2004-04-19 devnull 'd', 'n', 'o', 'o', 'o', 'o', 'o', 0 ,
66 c8af1ab1 2004-04-19 devnull 'o', 'u', 'u', 'u', 'u', 'y', 0 , 'y',
67 c8af1ab1 2004-04-19 devnull };
68 c8af1ab1 2004-04-19 devnull
69 c8af1ab1 2004-04-19 devnull int locate(void);
70 c8af1ab1 2004-04-19 devnull int acomp(Rune*, Rune*);
71 c8af1ab1 2004-04-19 devnull int getword(Biobuf*, Rune *rp, int n);
72 c8af1ab1 2004-04-19 devnull void torune(char*, Rune*);
73 c8af1ab1 2004-04-19 devnull void rcanon(Rune*, Rune*);
74 c8af1ab1 2004-04-19 devnull int ncomp(Rune*, Rune*);
75 c8af1ab1 2004-04-19 devnull
76 c8af1ab1 2004-04-19 devnull void
77 c8af1ab1 2004-04-19 devnull main(int argc, char *argv[])
78 c8af1ab1 2004-04-19 devnull {
79 c8af1ab1 2004-04-19 devnull int n;
80 c8af1ab1 2004-04-19 devnull
81 c8af1ab1 2004-04-19 devnull filename = unsharp(filename);
82 c8af1ab1 2004-04-19 devnull
83 c8af1ab1 2004-04-19 devnull Binit(&bin, 0, OREAD);
84 c8af1ab1 2004-04-19 devnull Binit(&bout, 1, OWRITE);
85 c8af1ab1 2004-04-19 devnull compare = acomp;
86 c8af1ab1 2004-04-19 devnull ARGBEGIN{
87 c8af1ab1 2004-04-19 devnull case 'd':
88 c8af1ab1 2004-04-19 devnull direc++;
89 c8af1ab1 2004-04-19 devnull break;
90 c8af1ab1 2004-04-19 devnull case 'f':
91 c8af1ab1 2004-04-19 devnull fold++;
92 c8af1ab1 2004-04-19 devnull break;
93 fa325e9b 2020-01-10 cross case 'i':
94 c8af1ab1 2004-04-19 devnull iflag++;
95 c8af1ab1 2004-04-19 devnull break;
96 c8af1ab1 2004-04-19 devnull case 'n':
97 c8af1ab1 2004-04-19 devnull compare = ncomp;
98 c8af1ab1 2004-04-19 devnull break;
99 c8af1ab1 2004-04-19 devnull case 't':
100 c8af1ab1 2004-04-19 devnull chartorune(&tab,ARGF());
101 c8af1ab1 2004-04-19 devnull break;
102 c8af1ab1 2004-04-19 devnull case 'x':
103 c8af1ab1 2004-04-19 devnull exact++;
104 c8af1ab1 2004-04-19 devnull break;
105 c8af1ab1 2004-04-19 devnull default:
106 c8af1ab1 2004-04-19 devnull fprint(2, "%s: bad option %c\n", argv0, ARGC());
107 c8af1ab1 2004-04-19 devnull fprint(2, "usage: %s -[dfinx] [-t c] [string] [file]\n", argv0);
108 c8af1ab1 2004-04-19 devnull exits("usage");
109 c8af1ab1 2004-04-19 devnull } ARGEND
110 c8af1ab1 2004-04-19 devnull if(!iflag){
111 c8af1ab1 2004-04-19 devnull if(argc >= 1) {
112 c8af1ab1 2004-04-19 devnull torune(argv[0], orig);
113 c8af1ab1 2004-04-19 devnull argv++;
114 c8af1ab1 2004-04-19 devnull argc--;
115 c8af1ab1 2004-04-19 devnull } else
116 c8af1ab1 2004-04-19 devnull iflag++;
117 c8af1ab1 2004-04-19 devnull }
118 c8af1ab1 2004-04-19 devnull if(argc < 1) {
119 c8af1ab1 2004-04-19 devnull direc++;
120 c8af1ab1 2004-04-19 devnull fold++;
121 fa325e9b 2020-01-10 cross } else
122 c8af1ab1 2004-04-19 devnull filename = argv[0];
123 c8af1ab1 2004-04-19 devnull if (!iflag)
124 c8af1ab1 2004-04-19 devnull rcanon(orig, key);
125 c8af1ab1 2004-04-19 devnull dfile = Bopen(filename, OREAD);
126 c8af1ab1 2004-04-19 devnull if(dfile == 0) {
127 c8af1ab1 2004-04-19 devnull fprint(2, "look: can't open %s\n", filename);
128 c8af1ab1 2004-04-19 devnull exits("no dictionary");
129 c8af1ab1 2004-04-19 devnull }
130 c8af1ab1 2004-04-19 devnull if(!iflag)
131 c8af1ab1 2004-04-19 devnull if(!locate())
132 c8af1ab1 2004-04-19 devnull exits("not found");
133 c8af1ab1 2004-04-19 devnull do {
134 c8af1ab1 2004-04-19 devnull if(iflag) {
135 c8af1ab1 2004-04-19 devnull Bflush(&bout);
136 c8af1ab1 2004-04-19 devnull if(!getword(&bin, orig, sizeof(orig)/sizeof(orig[0])))
137 c8af1ab1 2004-04-19 devnull exits(0);
138 c8af1ab1 2004-04-19 devnull rcanon(orig, key);
139 c8af1ab1 2004-04-19 devnull if(!locate())
140 c8af1ab1 2004-04-19 devnull continue;
141 c8af1ab1 2004-04-19 devnull }
142 c8af1ab1 2004-04-19 devnull if (!exact || !acomp(word, key))
143 c8af1ab1 2004-04-19 devnull Bprint(&bout, "%S\n", entry);
144 c8af1ab1 2004-04-19 devnull while(getword(dfile, entry, sizeof(entry)/sizeof(entry[0]))) {
145 c8af1ab1 2004-04-19 devnull rcanon(entry, word);
146 c8af1ab1 2004-04-19 devnull n = compare(key, word);
147 c8af1ab1 2004-04-19 devnull switch(n) {
148 c8af1ab1 2004-04-19 devnull case -1:
149 c8af1ab1 2004-04-19 devnull if(exact)
150 c8af1ab1 2004-04-19 devnull break;
151 c8af1ab1 2004-04-19 devnull case 0:
152 c8af1ab1 2004-04-19 devnull if (!exact || !acomp(word, orig))
153 c8af1ab1 2004-04-19 devnull Bprint(&bout, "%S\n", entry);
154 c8af1ab1 2004-04-19 devnull continue;
155 c8af1ab1 2004-04-19 devnull }
156 c8af1ab1 2004-04-19 devnull break;
157 c8af1ab1 2004-04-19 devnull }
158 c8af1ab1 2004-04-19 devnull } while(iflag);
159 c8af1ab1 2004-04-19 devnull exits(0);
160 c8af1ab1 2004-04-19 devnull }
161 c8af1ab1 2004-04-19 devnull
162 c8af1ab1 2004-04-19 devnull int
163 c8af1ab1 2004-04-19 devnull locate(void)
164 c8af1ab1 2004-04-19 devnull {
165 b707cb51 2004-06-13 devnull vlong top, bot, mid;
166 b707cb51 2004-06-13 devnull int c;
167 c8af1ab1 2004-04-19 devnull int n;
168 c8af1ab1 2004-04-19 devnull
169 c8af1ab1 2004-04-19 devnull bot = 0;
170 c8af1ab1 2004-04-19 devnull top = Bseek(dfile, 0L, 2);
171 c8af1ab1 2004-04-19 devnull for(;;) {
172 c8af1ab1 2004-04-19 devnull mid = (top+bot) / 2;
173 c8af1ab1 2004-04-19 devnull Bseek(dfile, mid, 0);
174 c8af1ab1 2004-04-19 devnull do
175 c8af1ab1 2004-04-19 devnull c = Bgetrune(dfile);
176 c8af1ab1 2004-04-19 devnull while(c>=0 && c!='\n');
177 c8af1ab1 2004-04-19 devnull mid = Boffset(dfile);
178 c8af1ab1 2004-04-19 devnull if(!getword(dfile, entry, sizeof(entry)/sizeof(entry[0])))
179 c8af1ab1 2004-04-19 devnull break;
180 c8af1ab1 2004-04-19 devnull rcanon(entry, word);
181 c8af1ab1 2004-04-19 devnull n = compare(key, word);
182 c8af1ab1 2004-04-19 devnull switch(n) {
183 c8af1ab1 2004-04-19 devnull case -2:
184 c8af1ab1 2004-04-19 devnull case -1:
185 c8af1ab1 2004-04-19 devnull case 0:
186 c8af1ab1 2004-04-19 devnull if(top <= mid)
187 c8af1ab1 2004-04-19 devnull break;
188 c8af1ab1 2004-04-19 devnull top = mid;
189 c8af1ab1 2004-04-19 devnull continue;
190 c8af1ab1 2004-04-19 devnull case 1:
191 c8af1ab1 2004-04-19 devnull case 2:
192 c8af1ab1 2004-04-19 devnull bot = mid;
193 c8af1ab1 2004-04-19 devnull continue;
194 c8af1ab1 2004-04-19 devnull }
195 c8af1ab1 2004-04-19 devnull break;
196 c8af1ab1 2004-04-19 devnull }
197 c8af1ab1 2004-04-19 devnull Bseek(dfile, bot, 0);
198 c8af1ab1 2004-04-19 devnull while(getword(dfile, entry, sizeof(entry)/sizeof(entry[0]))) {
199 c8af1ab1 2004-04-19 devnull rcanon(entry, word);
200 c8af1ab1 2004-04-19 devnull n = compare(key, word);
201 c8af1ab1 2004-04-19 devnull switch(n) {
202 c8af1ab1 2004-04-19 devnull case -2:
203 c8af1ab1 2004-04-19 devnull return 0;
204 c8af1ab1 2004-04-19 devnull case -1:
205 c8af1ab1 2004-04-19 devnull if(exact)
206 c8af1ab1 2004-04-19 devnull return 0;
207 c8af1ab1 2004-04-19 devnull case 0:
208 c8af1ab1 2004-04-19 devnull return 1;
209 c8af1ab1 2004-04-19 devnull case 1:
210 c8af1ab1 2004-04-19 devnull case 2:
211 c8af1ab1 2004-04-19 devnull continue;
212 c8af1ab1 2004-04-19 devnull }
213 c8af1ab1 2004-04-19 devnull }
214 c8af1ab1 2004-04-19 devnull return 0;
215 c8af1ab1 2004-04-19 devnull }
216 c8af1ab1 2004-04-19 devnull
217 c8af1ab1 2004-04-19 devnull /*
218 c8af1ab1 2004-04-19 devnull * acomp(s, t) returns:
219 c8af1ab1 2004-04-19 devnull * -2 if s strictly precedes t
220 c8af1ab1 2004-04-19 devnull * -1 if s is a prefix of t
221 c8af1ab1 2004-04-19 devnull * 0 if s is the same as t
222 c8af1ab1 2004-04-19 devnull * 1 if t is a prefix of s
223 c8af1ab1 2004-04-19 devnull * 2 if t strictly precedes s
224 c8af1ab1 2004-04-19 devnull */
225 c8af1ab1 2004-04-19 devnull
226 c8af1ab1 2004-04-19 devnull int
227 c8af1ab1 2004-04-19 devnull acomp(Rune *s, Rune *t)
228 c8af1ab1 2004-04-19 devnull {
229 c8af1ab1 2004-04-19 devnull int cs, ct;
230 c8af1ab1 2004-04-19 devnull
231 c8af1ab1 2004-04-19 devnull for(;;) {
232 c8af1ab1 2004-04-19 devnull cs = *s;
233 c8af1ab1 2004-04-19 devnull ct = *t;
234 c8af1ab1 2004-04-19 devnull if(cs != ct)
235 c8af1ab1 2004-04-19 devnull break;
236 c8af1ab1 2004-04-19 devnull if(cs == 0)
237 c8af1ab1 2004-04-19 devnull return 0;
238 c8af1ab1 2004-04-19 devnull s++;
239 c8af1ab1 2004-04-19 devnull t++;
240 c8af1ab1 2004-04-19 devnull }
241 c8af1ab1 2004-04-19 devnull if(cs == 0)
242 c8af1ab1 2004-04-19 devnull return -1;
243 c8af1ab1 2004-04-19 devnull if(ct == 0)
244 c8af1ab1 2004-04-19 devnull return 1;
245 c8af1ab1 2004-04-19 devnull if(cs < ct)
246 c8af1ab1 2004-04-19 devnull return -2;
247 c8af1ab1 2004-04-19 devnull return 2;
248 c8af1ab1 2004-04-19 devnull }
249 c8af1ab1 2004-04-19 devnull
250 c8af1ab1 2004-04-19 devnull void
251 c8af1ab1 2004-04-19 devnull torune(char *old, Rune *new)
252 c8af1ab1 2004-04-19 devnull {
253 c8af1ab1 2004-04-19 devnull do old += chartorune(new, old);
254 c8af1ab1 2004-04-19 devnull while(*new++);
255 c8af1ab1 2004-04-19 devnull }
256 c8af1ab1 2004-04-19 devnull
257 c8af1ab1 2004-04-19 devnull void
258 c8af1ab1 2004-04-19 devnull rcanon(Rune *old, Rune *new)
259 c8af1ab1 2004-04-19 devnull {
260 c8af1ab1 2004-04-19 devnull Rune r;
261 c8af1ab1 2004-04-19 devnull
262 c8af1ab1 2004-04-19 devnull while((r = *old++) && r != tab) {
263 c8af1ab1 2004-04-19 devnull if (islatin1(r) && latin_fold_tab[r-0xc0])
264 c8af1ab1 2004-04-19 devnull r = latin_fold_tab[r-0xc0];
265 c8af1ab1 2004-04-19 devnull if(direc)
266 bb0266fe 2005-05-07 devnull if(!(isalnum(r) || r == ' ' || r == '\t'))
267 c8af1ab1 2004-04-19 devnull continue;
268 c8af1ab1 2004-04-19 devnull if(fold)
269 c8af1ab1 2004-04-19 devnull if(isupper(r))
270 c8af1ab1 2004-04-19 devnull r = tolower(r);
271 c8af1ab1 2004-04-19 devnull *new++ = r;
272 c8af1ab1 2004-04-19 devnull }
273 c8af1ab1 2004-04-19 devnull *new = 0;
274 c8af1ab1 2004-04-19 devnull }
275 c8af1ab1 2004-04-19 devnull
276 c8af1ab1 2004-04-19 devnull int
277 c8af1ab1 2004-04-19 devnull ncomp(Rune *s, Rune *t)
278 c8af1ab1 2004-04-19 devnull {
279 c8af1ab1 2004-04-19 devnull Rune *is, *it, *js, *jt;
280 c8af1ab1 2004-04-19 devnull int a, b;
281 c8af1ab1 2004-04-19 devnull int ssgn, tsgn;
282 c8af1ab1 2004-04-19 devnull
283 c8af1ab1 2004-04-19 devnull while(isspace(*s))
284 c8af1ab1 2004-04-19 devnull s++;
285 c8af1ab1 2004-04-19 devnull while(isspace(*t))
286 c8af1ab1 2004-04-19 devnull t++;
287 c8af1ab1 2004-04-19 devnull ssgn = tsgn = -2*rev;
288 c8af1ab1 2004-04-19 devnull if(*s == '-') {
289 c8af1ab1 2004-04-19 devnull s++;
290 c8af1ab1 2004-04-19 devnull ssgn = -ssgn;
291 c8af1ab1 2004-04-19 devnull }
292 c8af1ab1 2004-04-19 devnull if(*t == '-') {
293 c8af1ab1 2004-04-19 devnull t++;
294 c8af1ab1 2004-04-19 devnull tsgn = -tsgn;
295 c8af1ab1 2004-04-19 devnull }
296 c8af1ab1 2004-04-19 devnull for(is = s; isdigit(*is); is++)
297 c8af1ab1 2004-04-19 devnull ;
298 c8af1ab1 2004-04-19 devnull for(it = t; isdigit(*it); it++)
299 c8af1ab1 2004-04-19 devnull ;
300 c8af1ab1 2004-04-19 devnull js = is;
301 c8af1ab1 2004-04-19 devnull jt = it;
302 c8af1ab1 2004-04-19 devnull a = 0;
303 c8af1ab1 2004-04-19 devnull if(ssgn == tsgn)
304 c8af1ab1 2004-04-19 devnull while(it>t && is>s)
305 c8af1ab1 2004-04-19 devnull if(b = *--it - *--is)
306 c8af1ab1 2004-04-19 devnull a = b;
307 c8af1ab1 2004-04-19 devnull while(is > s)
308 c8af1ab1 2004-04-19 devnull if(*--is != '0')
309 c8af1ab1 2004-04-19 devnull return -ssgn;
310 c8af1ab1 2004-04-19 devnull while(it > t)
311 c8af1ab1 2004-04-19 devnull if(*--it != '0')
312 c8af1ab1 2004-04-19 devnull return tsgn;
313 c8af1ab1 2004-04-19 devnull if(a)
314 c8af1ab1 2004-04-19 devnull return sgn(a)*ssgn;
315 c8af1ab1 2004-04-19 devnull if(*(s=js) == '.')
316 c8af1ab1 2004-04-19 devnull s++;
317 c8af1ab1 2004-04-19 devnull if(*(t=jt) == '.')
318 c8af1ab1 2004-04-19 devnull t++;
319 c8af1ab1 2004-04-19 devnull if(ssgn == tsgn)
320 c8af1ab1 2004-04-19 devnull while(isdigit(*s) && isdigit(*t))
321 c8af1ab1 2004-04-19 devnull if(a = *t++ - *s++)
322 c8af1ab1 2004-04-19 devnull return sgn(a)*ssgn;
323 c8af1ab1 2004-04-19 devnull while(isdigit(*s))
324 c8af1ab1 2004-04-19 devnull if(*s++ != '0')
325 c8af1ab1 2004-04-19 devnull return -ssgn;
326 c8af1ab1 2004-04-19 devnull while(isdigit(*t))
327 c8af1ab1 2004-04-19 devnull if(*t++ != '0')
328 c8af1ab1 2004-04-19 devnull return tsgn;
329 c8af1ab1 2004-04-19 devnull return 0;
330 c8af1ab1 2004-04-19 devnull }
331 c8af1ab1 2004-04-19 devnull
332 c8af1ab1 2004-04-19 devnull int
333 c8af1ab1 2004-04-19 devnull getword(Biobuf *f, Rune *rp, int n)
334 c8af1ab1 2004-04-19 devnull {
335 c8af1ab1 2004-04-19 devnull long c;
336 c8af1ab1 2004-04-19 devnull
337 c8af1ab1 2004-04-19 devnull while(n-- > 0) {
338 c8af1ab1 2004-04-19 devnull c = Bgetrune(f);
339 c8af1ab1 2004-04-19 devnull if(c < 0)
340 c8af1ab1 2004-04-19 devnull return 0;
341 c8af1ab1 2004-04-19 devnull if(c == '\n') {
342 bb0266fe 2005-05-07 devnull *rp = '\0';
343 c8af1ab1 2004-04-19 devnull return 1;
344 c8af1ab1 2004-04-19 devnull }
345 c8af1ab1 2004-04-19 devnull *rp++ = c;
346 c8af1ab1 2004-04-19 devnull }
347 c8af1ab1 2004-04-19 devnull fprint(2, "Look: word too long. Bailing out.\n");
348 c8af1ab1 2004-04-19 devnull return 0;
349 c8af1ab1 2004-04-19 devnull }