1// -*- C++ -*- 2/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001 3 Free Software Foundation, Inc. 4 Written by James Clark (jjc@jclark.com) 5 6This file is part of groff. 7 8groff is free software; you can redistribute it and/or modify it under 9the terms of the GNU General Public License as published by the Free 10Software Foundation; either version 2, or (at your option) any later 11version. 12 13groff is distributed in the hope that it will be useful, but WITHOUT ANY 14WARRANTY; without even the implied warranty of MERCHANTABILITY or 15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16for more details. 17 18You should have received a copy of the GNU General Public License along 19with groff; see the file COPYING. If not, write to the Free Software 20Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */ 21 22#include "lib.h" 23 24#include <stdlib.h> 25#include <assert.h> 26#include <errno.h> 27 28#include "posix.h" 29#include "errarg.h" 30#include "error.h" 31#include "nonposix.h" 32 33#include "refid.h" 34#include "search.h" 35 36int linear_truncate_len = 6; 37const char *linear_ignore_fields = "XYZ"; 38 39search_list::search_list() 40: list(0), niterators(0), next_fid(1) 41{ 42} 43 44search_list::~search_list() 45{ 46 assert(niterators == 0); 47 while (list) { 48 search_item *tem = list->next; 49 delete list; 50 list = tem; 51 } 52} 53 54void search_list::add_file(const char *filename, int silent) 55{ 56 search_item *p = make_index_search_item(filename, next_fid); 57 if (!p) { 58 int fd = open(filename, O_RDONLY | O_BINARY); 59 if (fd < 0) { 60 if (!silent) 61 error("can't open `%1': %2", filename, strerror(errno)); 62 } 63 else 64 p = make_linear_search_item(fd, filename, next_fid); 65 } 66 if (p) { 67 search_item **pp; 68 for (pp = &list; *pp; pp = &(*pp)->next) 69 ; 70 *pp = p; 71 next_fid = p->next_filename_id(); 72 } 73} 74 75int search_list::nfiles() const 76{ 77 int n = 0; 78 for (search_item *ptr = list; ptr; ptr = ptr->next) 79 n++; 80 return n; 81} 82 83search_list_iterator::search_list_iterator(search_list *p, const char *q) 84: list(p), ptr(p->list), iter(0), query(strsave(q)), 85 searcher(q, strlen(q), linear_ignore_fields, linear_truncate_len) 86{ 87 list->niterators += 1; 88} 89 90search_list_iterator::~search_list_iterator() 91{ 92 list->niterators -= 1; 93 a_delete query; 94 delete iter; 95} 96 97int search_list_iterator::next(const char **pp, int *lenp, reference_id *ridp) 98{ 99 while (ptr) { 100 if (iter == 0) 101 iter = ptr->make_search_item_iterator(query); 102 if (iter->next(searcher, pp, lenp, ridp)) 103 return 1; 104 delete iter; 105 iter = 0; 106 ptr = ptr->next; 107 } 108 return 0; 109} 110 111search_item::search_item(const char *nm, int fid) 112: name(strsave(nm)), filename_id(fid), next(0) 113{ 114} 115 116search_item::~search_item() 117{ 118 a_delete name; 119} 120 121int search_item::is_named(const char *nm) const 122{ 123 return strcmp(name, nm) == 0; 124} 125 126int search_item::next_filename_id() const 127{ 128 return filename_id + 1; 129} 130 131search_item_iterator::~search_item_iterator() 132{ 133} 134