PageRenderTime 55ms CodeModel.GetById 22ms app.highlight 27ms RepoModel.GetById 1ms app.codeStats 0ms

/contrib/groff/src/libs/libbib/search.cpp

https://bitbucket.org/freebsd/freebsd-head/
C++ | 133 lines | 96 code | 17 blank | 20 comment | 13 complexity | 432bb9838282d39a93988a974cada61d MD5 | raw file
  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}