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