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