1 1.8 dsl /* $NetBSD: qsubst.c,v 1.8 2004/11/01 21:36:11 dsl 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.8 dsl __RCSID("$NetBSD: qsubst.c,v 1.8 2004/11/01 21:36:11 dsl 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.8 dsl issymchar(unsigned 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