1114402Sru// -*- C++ -*-
2114402Sru/* Copyright (C) 1989-1992, 2000, 2001 Free Software Foundation, Inc.
3114402Sru     Written by James Clark (jjc@jclark.com)
4114402Sru
5114402SruThis file is part of groff.
6114402Sru
7114402Srugroff is free software; you can redistribute it and/or modify it under
8114402Sruthe terms of the GNU General Public License as published by the Free
9114402SruSoftware Foundation; either version 2, or (at your option) any later
10114402Sruversion.
11114402Sru
12114402Srugroff is distributed in the hope that it will be useful, but WITHOUT ANY
13114402SruWARRANTY; without even the implied warranty of MERCHANTABILITY or
14114402SruFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15114402Srufor more details.
16114402Sru
17114402SruYou should have received a copy of the GNU General Public License along
18114402Sruwith groff; see the file COPYING.  If not, write to the Free Software
19151497SruFoundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
20114402Sru
21114402Sru#include "lib.h"
22114402Sru
23114402Sru#include <stdlib.h>
24114402Sru#include <errno.h>
25114402Sru#include <assert.h>
26114402Sru
27114402Sru#include "errarg.h"
28114402Sru#include "error.h"
29114402Sru
30114402Sru#include "defs.h"
31114402Sru#include "refid.h"
32114402Sru#include "search.h"
33114402Sru
34114402Sruextern "C" const char *Version_string;
35114402Sru
36114402Srustatic void usage(FILE *stream)
37114402Sru{
38114402Sru  fprintf(stream, "usage: %s [-nv] [-p database] [-i XYZ] [-t N] keys ...\n",
39114402Sru	  program_name);
40114402Sru}
41114402Sru
42114402Sruint main(int argc, char **argv)
43114402Sru{
44114402Sru  program_name = argv[0];
45114402Sru  static char stderr_buf[BUFSIZ];
46114402Sru  setbuf(stderr, stderr_buf);
47114402Sru  int search_default = 1;
48114402Sru  search_list list;
49114402Sru  int opt;
50114402Sru  static const struct option long_options[] = {
51114402Sru    { "help", no_argument, 0, CHAR_MAX + 1 },
52114402Sru    { "version", no_argument, 0, 'v' },
53114402Sru    { NULL, 0, 0, 0 }
54114402Sru  };
55114402Sru  while ((opt = getopt_long(argc, argv, "nvVi:t:p:", long_options, NULL))
56114402Sru	 != EOF)
57114402Sru    switch (opt) {
58114402Sru    case 'V':
59114402Sru      verify_flag = 1;
60114402Sru      break;
61114402Sru    case 'n':
62114402Sru      search_default = 0;
63114402Sru      break;
64114402Sru    case 'i':
65114402Sru      linear_ignore_fields = optarg;
66114402Sru      break;
67114402Sru    case 't':
68114402Sru      {
69114402Sru	char *ptr;
70114402Sru	long n = strtol(optarg, &ptr, 10);
71114402Sru	if (n == 0 && ptr == optarg) {
72114402Sru	  error("bad integer `%1' in `t' option", optarg);
73114402Sru	  break;
74114402Sru	}
75114402Sru	if (n < 1)
76114402Sru	  n = 1;
77114402Sru	linear_truncate_len = int(n);
78114402Sru	break;
79114402Sru      }
80114402Sru    case 'v':
81114402Sru      {
82114402Sru	printf("GNU lkbib (groff) version %s\n", Version_string);
83114402Sru	exit(0);
84114402Sru	break;
85114402Sru      }
86114402Sru    case 'p':
87114402Sru      list.add_file(optarg);
88114402Sru      break;
89114402Sru    case CHAR_MAX + 1: // --help
90114402Sru      usage(stdout);
91114402Sru      exit(0);
92114402Sru      break;
93114402Sru    case '?':
94114402Sru      usage(stderr);
95114402Sru      exit(1);
96114402Sru      break;
97114402Sru    default:
98114402Sru      assert(0);
99114402Sru    }
100114402Sru  if (optind >= argc) {
101114402Sru    usage(stderr);
102114402Sru    exit(1);
103114402Sru  }
104114402Sru  char *filename = getenv("REFER");
105114402Sru  if (filename)
106114402Sru    list.add_file(filename);
107114402Sru  else if (search_default)
108114402Sru    list.add_file(DEFAULT_INDEX, 1);
109114402Sru  if (list.nfiles() == 0)
110114402Sru    fatal("no databases");
111114402Sru  int total_len = 0;
112114402Sru  int i;
113114402Sru  for (i = optind; i < argc; i++)
114114402Sru    total_len += strlen(argv[i]);
115114402Sru  total_len += argc - optind - 1 + 1; // for spaces and '\0'
116114402Sru  char *buffer = new char[total_len];
117114402Sru  char *ptr = buffer;
118114402Sru  for (i = optind; i < argc; i++) {
119114402Sru    if (i > optind)
120114402Sru      *ptr++ = ' ';
121114402Sru    strcpy(ptr, argv[i]);
122114402Sru    ptr = strchr(ptr, '\0');
123114402Sru  }
124114402Sru  search_list_iterator iter(&list, buffer);
125114402Sru  const char *start;
126114402Sru  int len;
127114402Sru  int count;
128114402Sru  for (count = 0; iter.next(&start, &len); count++) {
129114402Sru    if (fwrite(start, 1, len, stdout) != (size_t)len)
130114402Sru      fatal("write error on stdout: %1", strerror(errno));
131114402Sru    // Can happen for last reference in file.
132114402Sru    if (start[len - 1] != '\n')
133114402Sru      putchar('\n');
134114402Sru    putchar('\n');
135114402Sru  }
136114402Sru  return !count;
137114402Sru}
138