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 <stdlib.h> 22 #include <unistd.h> 23 #include <stdio.h> 24 #include <errno.h> 25 #include <string.h> 26 #include <assert.h> 27 28 #include "lib.h" 29 #include "errarg.h" 30 #include "error.h" 31 32 #include "defs.h" 33 #include "refid.h" 34 #include "search.h" 35 36 static void usage() 37 { 38 fprintf(stderr, "usage: %s [-nv] [-p database] [-i XYZ] [-t N] keys ...\n", 39 program_name); 40 exit(1); 41 } 42 43 main(int argc, char **argv) 44 { 45 program_name = argv[0]; 46 static char stderr_buf[BUFSIZ]; 47 setbuf(stderr, stderr_buf); 48 int search_default = 1; 49 search_list list; 50 int opt; 51 while ((opt = getopt(argc, argv, "nvVi:t:p:")) != EOF) 52 switch (opt) { 53 case 'V': 54 verify_flag = 1; 55 break; 56 case 'n': 57 search_default = 0; 58 break; 59 case 'i': 60 linear_ignore_fields = optarg; 61 break; 62 case 't': 63 { 64 char *ptr; 65 long n = strtol(optarg, &ptr, 10); 66 if (n == 0 && ptr == optarg) { 67 error("bad integer `%1' in `t' option", optarg); 68 break; 69 } 70 if (n < 1) 71 n = 1; 72 linear_truncate_len = int(n); 73 break; 74 } 75 case 'v': 76 { 77 extern const char *version_string; 78 fprintf(stderr, "GNU lkbib version %s\n", version_string); 79 fflush(stderr); 80 break; 81 } 82 case 'p': 83 list.add_file(optarg); 84 break; 85 case '?': 86 usage(); 87 default: 88 assert(0); 89 } 90 if (optind >= argc) 91 usage(); 92 char *filename = getenv("REFER"); 93 if (filename) 94 list.add_file(filename); 95 else if (search_default) 96 list.add_file(DEFAULT_INDEX, 1); 97 if (list.nfiles() == 0) 98 fatal("no databases"); 99 int total_len = 0; 100 for (int i = optind; i < argc; i++) 101 total_len += strlen(argv[i]); 102 total_len += argc - optind - 1 + 1; // for spaces and '\0' 103 char *buffer = new char[total_len]; 104 char *ptr = buffer; 105 for (i = optind; i < argc; i++) { 106 if (i > optind) 107 *ptr++ = ' '; 108 strcpy(ptr, argv[i]); 109 ptr = strchr(ptr, '\0'); 110 } 111 search_list_iterator iter(&list, buffer); 112 const char *start; 113 int len; 114 for (int count = 0; iter.next(&start, &len); count++) { 115 if (fwrite(start, 1, len, stdout) != len) 116 fatal("write error on stdout: %1", strerror(errno)); 117 // Can happen for last reference in file. 118 if (start[len - 1] != '\n') 119 putchar('\n'); 120 putchar('\n'); 121 } 122 exit(!count); 123 } 124