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
usage()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
main(int argc,char ** argv)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