1 // -*- C++ -*- 2 /* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. 3 Written by James Clark (jjc@jclark.com) 4 5 This file is part of groff. 6 7 groff is free software; you can redistribute it and/or modify it under 8 the terms of the GNU General Public License as published by the Free 9 Software Foundation; either version 2, or (at your option) any later 10 version. 11 12 groff is distributed in the hope that it will be useful, but WITHOUT ANY 13 WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 for more details. 16 17 You should have received a copy of the GNU General Public License along 18 with groff; see the file COPYING. If not, write to the Free Software 19 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 20 21 #include <stdio.h> 22 #include <unistd.h> 23 #include <stdlib.h> 24 #include <string.h> 25 #include <assert.h> 26 #include <errno.h> 27 28 #include "errarg.h" 29 #include "error.h" 30 #include "lib.h" 31 #include "cset.h" 32 33 #include "refid.h" 34 #include "search.h" 35 36 extern "C" { 37 int isatty(int); 38 } 39 40 static void usage() 41 { 42 fprintf(stderr, "usage: %s [-v] [-i XYZ] [-t N] database ...\n", 43 program_name); 44 exit(1); 45 } 46 47 main(int argc, char **argv) 48 { 49 program_name = argv[0]; 50 static char stderr_buf[BUFSIZ]; 51 setbuf(stderr, stderr_buf); 52 int opt; 53 while ((opt = getopt(argc, argv, "vVi:t:")) != EOF) 54 switch (opt) { 55 case 'V': 56 verify_flag = 1; 57 break; 58 case 'i': 59 linear_ignore_fields = optarg; 60 break; 61 case 't': 62 { 63 char *ptr; 64 long n = strtol(optarg, &ptr, 10); 65 if (n == 0 && ptr == optarg) { 66 error("bad integer `%1' in `t' option", optarg); 67 break; 68 } 69 if (n < 1) 70 n = 1; 71 linear_truncate_len = int(n); 72 break; 73 } 74 case 'v': 75 { 76 extern const char *version_string; 77 fprintf(stderr, "GNU lookbib version %s\n", version_string); 78 fflush(stderr); 79 break; 80 } 81 case '?': 82 usage(); 83 default: 84 assert(0); 85 } 86 if (optind >= argc) 87 usage(); 88 search_list list; 89 for (int i = optind; i < argc; i++) 90 list.add_file(argv[i]); 91 if (list.nfiles() == 0) 92 fatal("no databases"); 93 char line[1024]; 94 int interactive = isatty(fileno(stdin)); 95 for (;;) { 96 if (interactive) { 97 fputs("> ", stderr); 98 fflush(stderr); 99 } 100 if (!fgets(line, sizeof(line), stdin)) 101 break; 102 char *ptr = line; 103 while (csspace(*ptr)) 104 ptr++; 105 if (*ptr == '\0') 106 continue; 107 search_list_iterator iter(&list, line); 108 const char *start; 109 int len; 110 for (int count = 0; iter.next(&start, &len); count++) { 111 if (fwrite(start, 1, len, stdout) != len) 112 fatal("write error on stdout: %1", strerror(errno)); 113 // Can happen for last reference in file. 114 if (start[len - 1] != '\n') 115 putchar('\n'); 116 putchar('\n'); 117 } 118 fflush(stdout); 119 if (interactive) { 120 fprintf(stderr, "%d found\n", count); 121 fflush(stderr); 122 } 123 } 124 if (interactive) 125 putc('\n', stderr); 126 return 0; 127 } 128 129