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