169493Sbostic // -*- C++ -*-
269493Sbostic /* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
369493Sbostic      Written by James Clark (jjc@jclark.com)
469493Sbostic 
569493Sbostic This file is part of groff.
669493Sbostic 
769493Sbostic groff is free software; you can redistribute it and/or modify it under
869493Sbostic the terms of the GNU General Public License as published by the Free
969493Sbostic Software Foundation; either version 2, or (at your option) any later
1069493Sbostic version.
1169493Sbostic 
1269493Sbostic groff is distributed in the hope that it will be useful, but WITHOUT ANY
1369493Sbostic WARRANTY; without even the implied warranty of MERCHANTABILITY or
1469493Sbostic FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1569493Sbostic for more details.
1669493Sbostic 
1769493Sbostic You should have received a copy of the GNU General Public License along
1869493Sbostic with groff; see the file COPYING.  If not, write to the Free Software
1969493Sbostic Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
2069493Sbostic 
2169493Sbostic #include <stdio.h>
22*69503Sbostic #include <unistd.h>
2369493Sbostic #include <stdlib.h>
2469493Sbostic #include <string.h>
2569493Sbostic #include <assert.h>
2669493Sbostic #include <errno.h>
2769493Sbostic 
2869493Sbostic #include "errarg.h"
2969493Sbostic #include "error.h"
3069493Sbostic #include "lib.h"
3169493Sbostic #include "cset.h"
3269493Sbostic 
3369493Sbostic #include "refid.h"
3469493Sbostic #include "search.h"
3569493Sbostic 
3669493Sbostic extern "C" {
3769493Sbostic   int isatty(int);
3869493Sbostic }
3969493Sbostic 
usage()4069493Sbostic static void usage()
4169493Sbostic {
4269493Sbostic   fprintf(stderr, "usage: %s [-v] [-i XYZ] [-t N] database ...\n",
4369493Sbostic 	  program_name);
4469493Sbostic   exit(1);
4569493Sbostic }
4669493Sbostic 
main(int argc,char ** argv)4769493Sbostic main(int argc, char **argv)
4869493Sbostic {
4969493Sbostic   program_name = argv[0];
5069493Sbostic   static char stderr_buf[BUFSIZ];
5169493Sbostic   setbuf(stderr, stderr_buf);
5269493Sbostic   int opt;
5369493Sbostic   while ((opt = getopt(argc, argv, "vVi:t:")) != EOF)
5469493Sbostic     switch (opt) {
5569493Sbostic     case 'V':
5669493Sbostic       verify_flag = 1;
5769493Sbostic       break;
5869493Sbostic     case 'i':
5969493Sbostic       linear_ignore_fields = optarg;
6069493Sbostic       break;
6169493Sbostic     case 't':
6269493Sbostic       {
6369493Sbostic 	char *ptr;
6469493Sbostic 	long n = strtol(optarg, &ptr, 10);
6569493Sbostic 	if (n == 0 && ptr == optarg) {
6669493Sbostic 	  error("bad integer `%1' in `t' option", optarg);
6769493Sbostic 	  break;
6869493Sbostic 	}
6969493Sbostic 	if (n < 1)
7069493Sbostic 	  n = 1;
7169493Sbostic 	linear_truncate_len = int(n);
7269493Sbostic 	break;
7369493Sbostic       }
7469493Sbostic     case 'v':
7569493Sbostic       {
7669493Sbostic 	extern const char *version_string;
7769493Sbostic 	fprintf(stderr, "GNU lookbib version %s\n", version_string);
7869493Sbostic 	fflush(stderr);
7969493Sbostic 	break;
8069493Sbostic       }
8169493Sbostic     case '?':
8269493Sbostic       usage();
8369493Sbostic     default:
8469493Sbostic       assert(0);
8569493Sbostic     }
8669493Sbostic   if (optind >= argc)
8769493Sbostic     usage();
8869493Sbostic   search_list list;
8969493Sbostic   for (int i = optind; i < argc; i++)
9069493Sbostic     list.add_file(argv[i]);
9169493Sbostic   if (list.nfiles() == 0)
9269493Sbostic     fatal("no databases");
9369493Sbostic   char line[1024];
9469493Sbostic   int interactive = isatty(fileno(stdin));
9569493Sbostic   for (;;) {
9669493Sbostic     if (interactive) {
9769493Sbostic       fputs("> ", stderr);
9869493Sbostic       fflush(stderr);
9969493Sbostic     }
10069493Sbostic     if (!fgets(line, sizeof(line), stdin))
10169493Sbostic       break;
10269493Sbostic     char *ptr = line;
10369493Sbostic     while (csspace(*ptr))
10469493Sbostic       ptr++;
10569493Sbostic     if (*ptr == '\0')
10669493Sbostic       continue;
10769493Sbostic     search_list_iterator iter(&list, line);
10869493Sbostic     const char *start;
10969493Sbostic     int len;
11069493Sbostic     for (int count = 0; iter.next(&start, &len); count++) {
11169493Sbostic       if (fwrite(start, 1, len, stdout) != len)
11269493Sbostic 	fatal("write error on stdout: %1", strerror(errno));
11369493Sbostic       // Can happen for last reference in file.
11469493Sbostic       if (start[len - 1] != '\n')
11569493Sbostic 	putchar('\n');
11669493Sbostic       putchar('\n');
11769493Sbostic     }
11869493Sbostic     fflush(stdout);
11969493Sbostic     if (interactive) {
12069493Sbostic       fprintf(stderr, "%d found\n", count);
12169493Sbostic       fflush(stderr);
12269493Sbostic     }
12369493Sbostic   }
12469493Sbostic   if (interactive)
12569493Sbostic     putc('\n', stderr);
12669493Sbostic   return 0;
12769493Sbostic }
12869493Sbostic 
129