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