qsubst.c revision 1.7 1 1.7 jmmv /* $NetBSD: qsubst.c,v 1.7 2004/01/05 23:23:36 jmmv Exp $ */
2 1.2 perry
3 1.1 perry /*
4 1.1 perry * qsubst -- designed for renaming routines existing in a whole bunch
5 1.1 perry * of files. Needs -ltermcap.
6 1.1 perry *
7 1.1 perry * Usage:
8 1.1 perry *
9 1.1 perry * qsubst str1 str2 [ options ]
10 1.1 perry *
11 1.1 perry * qsubst reads its options (see below) to get a list of files. For
12 1.1 perry * each file on this list, it then replaces str1 with str2 wherever
13 1.1 perry * possible in that file, depending on user input (see below). The
14 1.1 perry * result is written back onto the original file.
15 1.1 perry *
16 1.1 perry * For each possible substitution, the user is prompted with a few
17 1.1 perry * lines before and after the line containing the string to be
18 1.1 perry * substituted. The string itself is displayed using the terminal's
19 1.1 perry * standout mode, if any. Then one character is read from the
20 1.1 perry * terminal. This is then interpreted as follows (this is designed to
21 1.1 perry * be like Emacs' query-replace-string):
22 1.1 perry *
23 1.1 perry * space replace this occurrence and go on to the next one
24 1.1 perry * . replace this occurrence and don't change any more in
25 1.1 perry * this file (ie, go on to the next file).
26 1.1 perry * , tentatively replace this occurrence. The lines as they
27 1.1 perry * would look if the substitution were made are printed
28 1.1 perry * out. Then another character is read and it is used to
29 1.1 perry * decide the result (possibly undoing the tentative
30 1.1 perry * replacement).
31 1.1 perry * n don't change this one, but go on to the next one
32 1.1 perry * ^G don't change this one or any others in this file, but
33 1.1 perry * instead go on to the next file.
34 1.1 perry * ! change the rest in this file without asking, then go on
35 1.1 perry * to the next file (at which point qsubst will start
36 1.1 perry * asking again).
37 1.1 perry * ? print out the current filename and ask again.
38 1.1 perry *
39 1.1 perry * The first two arguments to qsubst are always the string to replace
40 1.1 perry * and the string to replace it with. The options are as follows:
41 1.1 perry *
42 1.1 perry * -w The search string is considered as a C symbol; it must
43 1.1 perry * be bounded by non-symbol characters. This option
44 1.1 perry * toggles. (`w' for `word'.)
45 1.1 perry * -! Enter ! mode automatically at the beginning of each
46 1.1 perry * file.
47 1.1 perry * -go Same as -!
48 1.1 perry * -noask Same as -!
49 1.1 perry * -nogo Negate -go
50 1.1 perry * -ask Negate -noask (same as -nogo)
51 1.1 perry * -cN (N is a number) Give N lines of context above and below
52 1.1 perry * the line with the match when prompting the user.
53 1.1 perry * -CAN (N is a number) Give N lines of context above the line
54 1.1 perry * with the match when prompting the user.
55 1.1 perry * -CBN (N is a number) Give N lines of context below the line
56 1.1 perry * with the match when prompting the user.
57 1.1 perry * -f filename
58 1.1 perry * The filename following the -f argument is one of the
59 1.1 perry * files qsubst should perform substitutions in.
60 1.1 perry * -F filename
61 1.1 perry * qsubst should read the named file to get the names of
62 1.1 perry * files to perform substitutions in. The names should
63 1.1 perry * appear one to a line.
64 1.1 perry *
65 1.1 perry * The default amount of context is -c2, that is, two lines above and
66 1.1 perry * two lines below the line with the match.
67 1.1 perry *
68 1.1 perry * Arguments not beginning with a - sign in the options field are
69 1.1 perry * implicitly preceded by -f. Thus, -f is really needed only when the
70 1.1 perry * file name begins with a - sign.
71 1.1 perry *
72 1.1 perry * qsubst reads its options in order and processes files as it gets
73 1.1 perry * them. This means, for example, that a -go will affect only files
74 1.1 perry * from -f or -F options appearing after the -go option.
75 1.1 perry *
76 1.1 perry * The most context you can get is ten lines each, above and below
77 1.1 perry * (corresponding to -c10).
78 1.1 perry *
79 1.1 perry * Str1 is limited to 512 characters; there is no limit on the size of
80 1.1 perry * str2. Neither one may contain a NUL.
81 1.1 perry *
82 1.1 perry * NULs in the file may cause qsubst to make various mistakes.
83 1.1 perry *
84 1.1 perry * If any other program modifies the file while qsubst is running, all
85 1.1 perry * bets are off.
86 1.1 perry *
87 1.1 perry * This program is in the public domain. Anyone may use it in any way
88 1.1 perry * for any purpose. Of course, it's also up to you to determine
89 1.1 perry * whether what it does is suitable for you; the above comments may
90 1.1 perry * help, but I can't promise they're accurate. It's free, and you get
91 1.1 perry * what you pay for.
92 1.1 perry *
93 1.1 perry * If you find any bugs I would appreciate hearing about them,
94 1.1 perry * especially if you also fix them.
95 1.1 perry *
96 1.1 perry * der Mouse
97 1.1 perry *
98 1.1 perry * mouse (at) rodents.montreal.qc.ca
99 1.1 perry */
100 1.6 agc #include <sys/cdefs.h>
101 1.6 agc
102 1.6 agc #ifndef lint
103 1.7 jmmv __RCSID("$NetBSD: qsubst.c,v 1.7 2004/01/05 23:23:36 jmmv Exp $");
104 1.6 agc #endif
105 1.1 perry
106 1.2 perry #include <sys/file.h>
107 1.2 perry
108 1.1 perry #include <ctype.h>
109 1.1 perry #include <errno.h>
110 1.2 perry #include <signal.h>
111 1.2 perry #include <stdio.h>
112 1.1 perry #include <stdlib.h>
113 1.1 perry #include <strings.h>
114 1.2 perry #include <termcap.h>
115 1.1 perry #include <termios.h>
116 1.2 perry #include <unistd.h>
117 1.1 perry
118 1.1 perry extern const char *__progname;
119 1.1 perry
120 1.1 perry #define MAX_C_A 10
121 1.1 perry #define MAX_C_B 10
122 1.1 perry #define BUF_SIZ 1024
123 1.1 perry
124 1.1 perry static int debugging;
125 1.1 perry static FILE *tempf;
126 1.2 perry static long tbeg;
127 1.1 perry static FILE *workf;
128 1.1 perry static char *str1;
129 1.1 perry static char *str2;
130 1.1 perry static int s1l;
131 1.1 perry static int s2l;
132 1.5 perry static long nls[MAX_C_A + 1];
133 1.5 perry static char buf[(BUF_SIZ * 2) + 2];
134 1.1 perry static char *bufp;
135 1.1 perry static char *bufp0;
136 1.1 perry static char *bufpmax;
137 1.1 perry static int rahead;
138 1.1 perry static int cabove;
139 1.1 perry static int cbelow;
140 1.1 perry static int wordmode;
141 1.1 perry static int flying;
142 1.1 perry static int flystate;
143 1.1 perry static int allfly;
144 1.1 perry static const char *nullstr = "";
145 1.1 perry static int ul_;
146 1.1 perry static char *current_file;
147 1.1 perry static const char *beginul;
148 1.1 perry static const char *endul;
149 1.1 perry static char tcp_buf[1024];
150 1.1 perry static char cap_buf[1024];
151 1.1 perry static struct termios orig_tio;
152 1.1 perry
153 1.5 perry static void
154 1.5 perry tstp_self(void)
155 1.1 perry {
156 1.5 perry void (*old_tstp) (int);
157 1.5 perry int mask;
158 1.1 perry
159 1.5 perry mask = sigblock(0);
160 1.5 perry kill(getpid(), SIGTSTP);
161 1.5 perry old_tstp = signal(SIGTSTP, SIG_DFL);
162 1.5 perry sigsetmask(mask & ~sigmask(SIGTSTP));
163 1.5 perry signal(SIGTSTP, old_tstp);
164 1.1 perry }
165 1.1 perry
166 1.2 perry /* ARGSUSED */
167 1.5 perry static void
168 1.5 perry sigtstp(int sig)
169 1.1 perry {
170 1.5 perry struct termios tio;
171 1.1 perry
172 1.5 perry if (tcgetattr(0, &tio) < 0) {
173 1.5 perry tstp_self();
174 1.5 perry return;
175 1.5 perry }
176 1.5 perry tcsetattr(0, TCSAFLUSH | TCSASOFT, &orig_tio);
177 1.5 perry tstp_self();
178 1.5 perry tcsetattr(0, TCSADRAIN | TCSASOFT, &tio);
179 1.5 perry }
180 1.5 perry
181 1.5 perry static void
182 1.5 perry limit_above_below(void)
183 1.5 perry {
184 1.5 perry if (cabove > MAX_C_A) {
185 1.5 perry cabove = MAX_C_A;
186 1.5 perry }
187 1.5 perry if (cbelow > MAX_C_B) {
188 1.5 perry cbelow = MAX_C_B;
189 1.5 perry }
190 1.5 perry }
191 1.5 perry
192 1.5 perry static int
193 1.5 perry issymchar(char c)
194 1.5 perry {
195 1.5 perry return (isascii(c) && (isalnum(c) || (c == '_') || (c == '$')));
196 1.5 perry }
197 1.5 perry
198 1.5 perry static int
199 1.5 perry foundit(void)
200 1.5 perry {
201 1.5 perry if (wordmode) {
202 1.5 perry return (!issymchar(bufp[-1]) &&
203 1.5 perry !issymchar(bufp[-2 - s1l]) &&
204 1.5 perry !bcmp(bufp - 1 - s1l, str1, s1l));
205 1.5 perry } else {
206 1.5 perry return (!bcmp(bufp - s1l, str1, s1l));
207 1.5 perry }
208 1.5 perry }
209 1.5 perry
210 1.5 perry static int
211 1.5 perry putcharf(int c)
212 1.5 perry {
213 1.5 perry return (putchar(c));
214 1.5 perry }
215 1.5 perry
216 1.5 perry static void
217 1.5 perry put_ul(char *s)
218 1.5 perry {
219 1.5 perry if (ul_) {
220 1.5 perry for (; *s; s++) {
221 1.5 perry printf("_\b%c", *s);
222 1.5 perry }
223 1.5 perry } else {
224 1.5 perry tputs(beginul, 1, putcharf);
225 1.5 perry fputs(s, stdout);
226 1.5 perry tputs(endul, 1, putcharf);
227 1.5 perry }
228 1.5 perry }
229 1.5 perry
230 1.5 perry static int
231 1.5 perry getc_cbreak(void)
232 1.5 perry {
233 1.5 perry struct termios tio;
234 1.5 perry struct termios otio;
235 1.5 perry char c;
236 1.5 perry
237 1.5 perry if (tcgetattr(0, &tio) < 0)
238 1.5 perry return (getchar());
239 1.5 perry otio = tio;
240 1.5 perry tio.c_lflag &= ~(ICANON | ECHOKE | ECHOE | ECHO | ECHONL);
241 1.5 perry tio.c_cc[VMIN] = 1;
242 1.5 perry tio.c_cc[VTIME] = 0;
243 1.5 perry tcsetattr(0, TCSANOW | TCSASOFT, &tio);
244 1.5 perry switch (read(0, &c, 1)) {
245 1.5 perry case -1:
246 1.5 perry break;
247 1.5 perry case 0:
248 1.5 perry break;
249 1.5 perry case 1:
250 1.5 perry break;
251 1.5 perry }
252 1.5 perry tcsetattr(0, TCSANOW | TCSASOFT, &otio);
253 1.5 perry return (c);
254 1.5 perry }
255 1.5 perry
256 1.5 perry static int
257 1.5 perry doit(void)
258 1.5 perry {
259 1.5 perry long save;
260 1.5 perry int i;
261 1.5 perry int lastnl;
262 1.5 perry int use_replacement;
263 1.5 perry
264 1.5 perry if (flying) {
265 1.5 perry return (flystate);
266 1.5 perry }
267 1.5 perry use_replacement = 0;
268 1.5 perry save = ftell(workf);
269 1.5 perry do {
270 1.5 perry for (i = MAX_C_A - cabove; nls[i] < 0; i++);
271 1.5 perry fseek(workf, nls[i], 0);
272 1.5 perry for (i = save - nls[i] - rahead; i; i--) {
273 1.5 perry putchar(getc(workf));
274 1.5 perry }
275 1.5 perry put_ul(use_replacement ? str2 : str1);
276 1.5 perry fseek(workf, save + s1l - rahead, 0);
277 1.5 perry lastnl = 0;
278 1.5 perry i = cbelow + 1;
279 1.5 perry while (i > 0) {
280 1.5 perry int c;
281 1.5 perry c = getc(workf);
282 1.5 perry if (c == EOF) {
283 1.5 perry clearerr(workf);
284 1.5 perry break;
285 1.5 perry }
286 1.5 perry putchar(c);
287 1.5 perry lastnl = 0;
288 1.5 perry if (c == '\n') {
289 1.5 perry i--;
290 1.5 perry lastnl = 1;
291 1.5 perry }
292 1.5 perry }
293 1.5 perry if (!lastnl)
294 1.5 perry printf("\n[no final newline] ");
295 1.5 perry fseek(workf, save, 0);
296 1.5 perry i = -1;
297 1.5 perry while (i == -1) {
298 1.5 perry switch (getc_cbreak()) {
299 1.5 perry case ' ':
300 1.5 perry i = 1;
301 1.5 perry break;
302 1.5 perry case '.':
303 1.5 perry i = 1;
304 1.5 perry flying = 1;
305 1.5 perry flystate = 0;
306 1.5 perry break;
307 1.5 perry case 'n':
308 1.5 perry i = 0;
309 1.5 perry break;
310 1.5 perry case '\7':
311 1.5 perry i = 0;
312 1.5 perry flying = 1;
313 1.5 perry flystate = 0;
314 1.5 perry break;
315 1.5 perry case '!':
316 1.5 perry i = 1;
317 1.5 perry flying = 1;
318 1.5 perry flystate = 1;
319 1.5 perry break;
320 1.5 perry case ',':
321 1.5 perry use_replacement = !use_replacement;
322 1.5 perry i = -2;
323 1.5 perry printf("(using %s string gives)\n",
324 1.5 perry use_replacement ? "new" : "old");
325 1.5 perry break;
326 1.5 perry case '?':
327 1.5 perry printf("File is `%s'\n", current_file);
328 1.5 perry break;
329 1.5 perry default:
330 1.5 perry putchar('\7');
331 1.5 perry break;
332 1.5 perry }
333 1.5 perry }
334 1.5 perry } while (i < 0);
335 1.5 perry if (i) {
336 1.5 perry printf("(replacing");
337 1.5 perry } else {
338 1.5 perry printf("(leaving");
339 1.5 perry }
340 1.5 perry if (flying) {
341 1.5 perry if (flystate == i) {
342 1.5 perry printf(" this and all the rest");
343 1.5 perry } else if (flystate) {
344 1.5 perry printf(" this, replacing all the rest");
345 1.5 perry } else {
346 1.5 perry printf(" this, leaving all the rest");
347 1.5 perry }
348 1.5 perry }
349 1.5 perry printf(")\n");
350 1.5 perry return (i);
351 1.5 perry }
352 1.5 perry
353 1.5 perry static void
354 1.5 perry add_shift(long *a, long e, int n)
355 1.5 perry {
356 1.5 perry int i;
357 1.5 perry
358 1.5 perry n--;
359 1.5 perry for (i = 0; i < n; i++) {
360 1.5 perry a[i] = a[i + 1];
361 1.5 perry }
362 1.5 perry a[n] = e;
363 1.5 perry }
364 1.5 perry
365 1.5 perry static void
366 1.5 perry process_file(char *fn)
367 1.5 perry {
368 1.5 perry int i;
369 1.5 perry long n;
370 1.5 perry int c;
371 1.5 perry
372 1.5 perry workf = fopen(fn, "r+");
373 1.5 perry if (workf == NULL) {
374 1.5 perry fprintf(stderr, "%s: cannot read %s\n", __progname, fn);
375 1.5 perry return;
376 1.5 perry }
377 1.5 perry printf("(file: %s)\n", fn);
378 1.5 perry current_file = fn;
379 1.5 perry for (i = 0; i <= MAX_C_A; i++) {
380 1.5 perry nls[i] = -1;
381 1.5 perry }
382 1.5 perry nls[MAX_C_A] = 0;
383 1.5 perry tbeg = -1;
384 1.5 perry if (wordmode) {
385 1.5 perry bufp0 = &buf[1];
386 1.5 perry rahead = s1l + 1;
387 1.5 perry buf[0] = '\0';
388 1.5 perry } else {
389 1.5 perry bufp0 = &buf[0];
390 1.5 perry rahead = s1l;
391 1.5 perry }
392 1.5 perry if (debugging) {
393 1.5 perry printf("[rahead = %d, bufp0-buf = %ld]\n",
394 1.5 perry rahead, (long) (bufp0 - &buf[0]));
395 1.5 perry }
396 1.5 perry n = 0;
397 1.5 perry bufp = bufp0;
398 1.5 perry bufpmax = &buf[sizeof(buf) - s1l - 2];
399 1.5 perry flying = allfly;
400 1.5 perry flystate = 1;
401 1.5 perry while (1) {
402 1.5 perry c = getc(workf);
403 1.5 perry if (c == EOF) {
404 1.5 perry if (tbeg >= 0) {
405 1.5 perry if (bufp > bufp0)
406 1.5 perry fwrite(bufp0, 1, bufp - bufp0, tempf);
407 1.5 perry fseek(workf, tbeg, 0);
408 1.5 perry n = ftell(tempf);
409 1.5 perry fseek(tempf, 0L, 0);
410 1.5 perry for (; n; n--) {
411 1.5 perry putc(getc(tempf), workf);
412 1.5 perry }
413 1.5 perry fflush(workf);
414 1.5 perry ftruncate(fileno(workf), ftell(workf));
415 1.5 perry }
416 1.5 perry fclose(workf);
417 1.5 perry return;
418 1.5 perry }
419 1.5 perry *bufp++ = c;
420 1.5 perry n++;
421 1.5 perry if (debugging) {
422 1.5 perry printf("[got %c, n now %ld, bufp-buf %ld]\n",
423 1.5 perry c, n, (long) (bufp - bufp0));
424 1.5 perry }
425 1.5 perry if ((n >= rahead) && foundit() && doit()) {
426 1.5 perry int wbehind;
427 1.5 perry if (debugging) {
428 1.5 perry printf("[doing change]\n");
429 1.5 perry }
430 1.5 perry wbehind = 1;
431 1.5 perry if (tbeg < 0) {
432 1.5 perry tbeg = ftell(workf) - rahead;
433 1.5 perry fseek(tempf, 0L, 0);
434 1.5 perry if (debugging) {
435 1.5 perry printf("[tbeg set to %d]\n",
436 1.5 perry (int)tbeg);
437 1.5 perry }
438 1.5 perry wbehind = 0;
439 1.5 perry }
440 1.5 perry if (bufp[-1] == '\n')
441 1.5 perry add_shift(nls, ftell(workf), MAX_C_A + 1);
442 1.5 perry if ((n > rahead) && wbehind) {
443 1.5 perry fwrite(bufp0, 1, n - rahead, tempf);
444 1.5 perry if (debugging) {
445 1.5 perry printf("[writing %ld from bufp0]\n",
446 1.5 perry n - rahead);
447 1.5 perry }
448 1.5 perry }
449 1.5 perry fwrite(str2, 1, s2l, tempf);
450 1.5 perry n = rahead - s1l;
451 1.5 perry if (debugging) {
452 1.5 perry printf("[n now %ld]\n", n);
453 1.5 perry }
454 1.5 perry if (n > 0) {
455 1.5 perry bcopy(bufp - n, bufp0, n);
456 1.5 perry if (debugging) {
457 1.5 perry printf("[copying %ld back]\n", n);
458 1.5 perry }
459 1.5 perry }
460 1.5 perry bufp = bufp0 + n;
461 1.5 perry } else {
462 1.5 perry if (bufp[-1] == '\n')
463 1.5 perry add_shift(nls, ftell(workf), MAX_C_A + 1);
464 1.5 perry if (bufp >= bufpmax) {
465 1.5 perry if (tbeg >= 0) {
466 1.5 perry fwrite(bufp0, 1, n - rahead, tempf);
467 1.5 perry if (debugging) {
468 1.5 perry printf("[flushing %ld]\n",
469 1.5 perry n - rahead);
470 1.5 perry }
471 1.5 perry }
472 1.5 perry n = rahead;
473 1.5 perry bcopy(bufp - n, bufp0, n);
474 1.5 perry if (debugging) {
475 1.5 perry printf("[n now %ld]\n[copying %ld back]\n", n, n);
476 1.5 perry }
477 1.5 perry bufp = bufp0 + n;
478 1.5 perry }
479 1.5 perry }
480 1.5 perry }
481 1.5 perry }
482 1.5 perry
483 1.5 perry static void
484 1.5 perry process_indir_file(char *fn)
485 1.5 perry {
486 1.5 perry char newfn[1024];
487 1.5 perry FILE *f;
488 1.5 perry
489 1.5 perry f = fopen(fn, "r");
490 1.5 perry if (f == NULL) {
491 1.5 perry fprintf(stderr, "%s: cannot read %s\n", __progname, fn);
492 1.5 perry return;
493 1.5 perry }
494 1.5 perry while (fgets(newfn, sizeof(newfn), f) == newfn) {
495 1.5 perry newfn[strlen(newfn) - 1] = '\0';
496 1.5 perry process_file(newfn);
497 1.5 perry }
498 1.5 perry fclose(f);
499 1.5 perry }
500 1.5 perry
501 1.5 perry int
502 1.5 perry main(int ac, char **av)
503 1.5 perry {
504 1.5 perry int skip;
505 1.5 perry char *cp;
506 1.5 perry
507 1.5 perry if (ac < 3) {
508 1.7 jmmv fprintf(stderr, "usage: %s str1 str2 [ -w -! -noask -go -f file -F file ]\n",
509 1.5 perry __progname);
510 1.5 perry exit(1);
511 1.5 perry }
512 1.5 perry cp = getenv("TERM");
513 1.5 perry if (cp == 0) {
514 1.5 perry beginul = nullstr;
515 1.1 perry endul = nullstr;
516 1.5 perry } else {
517 1.5 perry if (tgetent(tcp_buf, cp) != 1) {
518 1.5 perry beginul = nullstr;
519 1.5 perry endul = nullstr;
520 1.5 perry } else {
521 1.5 perry cp = cap_buf;
522 1.5 perry if (tgetflag("os") || tgetflag("ul")) {
523 1.5 perry ul_ = 1;
524 1.5 perry } else {
525 1.5 perry ul_ = 0;
526 1.5 perry beginul = tgetstr("us", &cp);
527 1.5 perry if (beginul == 0) {
528 1.5 perry beginul = tgetstr("so", &cp);
529 1.5 perry if (beginul == 0) {
530 1.5 perry beginul = nullstr;
531 1.5 perry endul = nullstr;
532 1.5 perry } else {
533 1.5 perry endul = tgetstr("se", &cp);
534 1.5 perry }
535 1.5 perry } else {
536 1.5 perry endul = tgetstr("ue", &cp);
537 1.5 perry }
538 1.5 perry }
539 1.5 perry }
540 1.5 perry }
541 1.5 perry {
542 1.5 perry static char tmp[] = "/tmp/qsubst.XXXXXX";
543 1.5 perry int fd;
544 1.5 perry fd = mkstemp(&tmp[0]);
545 1.5 perry if (fd < 0) {
546 1.5 perry fprintf(stderr, "%s: cannot create temp file: %s\n",
547 1.5 perry __progname, strerror(errno));
548 1.5 perry exit(1);
549 1.5 perry }
550 1.5 perry tempf = fdopen(fd, "w+");
551 1.5 perry }
552 1.5 perry if ((access(av[1], R_OK | W_OK) == 0) &&
553 1.5 perry (access(av[ac - 1], R_OK | W_OK) < 0) &&
554 1.5 perry (access(av[ac - 2], R_OK | W_OK) < 0)) {
555 1.5 perry fprintf(stderr, "%s: argument order has changed, it's now: str1 str2 files...\n", __progname);
556 1.5 perry }
557 1.5 perry str1 = av[1];
558 1.5 perry str2 = av[2];
559 1.5 perry av += 2;
560 1.5 perry ac -= 2;
561 1.5 perry s1l = strlen(str1);
562 1.5 perry s2l = strlen(str2);
563 1.5 perry if (s1l > BUF_SIZ) {
564 1.5 perry fprintf(stderr, "%s: search string too long (max %d chars)\n",
565 1.5 perry __progname, BUF_SIZ);
566 1.5 perry exit(1);
567 1.5 perry }
568 1.5 perry tcgetattr(0, &orig_tio);
569 1.5 perry signal(SIGTSTP, sigtstp);
570 1.5 perry allfly = 0;
571 1.5 perry cabove = 2;
572 1.5 perry cbelow = 2;
573 1.5 perry skip = 0;
574 1.5 perry for (ac--, av++; ac; ac--, av++) {
575 1.5 perry if (skip > 0) {
576 1.5 perry skip--;
577 1.5 perry continue;
578 1.5 perry }
579 1.5 perry if (**av == '-') {
580 1.5 perry ++*av;
581 1.5 perry if (!strcmp(*av, "debug")) {
582 1.5 perry debugging++;
583 1.5 perry } else if (!strcmp(*av, "w")) {
584 1.5 perry wordmode = !wordmode;
585 1.5 perry } else if ((strcmp(*av, "!") == 0) ||
586 1.5 perry (strcmp(*av, "go") == 0) ||
587 1.5 perry (strcmp(*av, "noask") == 0)) {
588 1.5 perry allfly = 1;
589 1.5 perry } else if ((strcmp(*av, "nogo") == 0) ||
590 1.5 perry (strcmp(*av, "ask") == 0)) {
591 1.5 perry allfly = 0;
592 1.5 perry } else if (**av == 'c') {
593 1.5 perry cabove = atoi(++*av);
594 1.5 perry cbelow = cabove;
595 1.5 perry limit_above_below();
596 1.5 perry } else if (**av == 'C') {
597 1.5 perry ++*av;
598 1.5 perry if (**av == 'A') {
599 1.5 perry cabove = atoi(++*av);
600 1.5 perry limit_above_below();
601 1.5 perry } else if (**av == 'B') {
602 1.5 perry cbelow = atoi(++*av);
603 1.5 perry limit_above_below();
604 1.5 perry } else {
605 1.5 perry fprintf(stderr, "%s: -C must be -CA or -CB\n", __progname);
606 1.5 perry }
607 1.5 perry } else if ((strcmp(*av, "f") == 0) ||
608 1.5 perry (strcmp(*av, "F") == 0)) {
609 1.5 perry if (++skip >= ac) {
610 1.5 perry fprintf(stderr, "%s: -%s what?\n",
611 1.5 perry __progname, *av);
612 1.5 perry } else {
613 1.5 perry if (**av == 'f') {
614 1.5 perry process_file(av[skip]);
615 1.5 perry } else {
616 1.5 perry process_indir_file(av[skip]);
617 1.5 perry }
618 1.5 perry }
619 1.5 perry }
620 1.5 perry } else {
621 1.5 perry process_file(*av);
622 1.5 perry }
623 1.5 perry }
624 1.5 perry exit(0);
625 1.1 perry }
626