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