1114402Sru// -*- C++ -*-
2114402Sru/* Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001
3114402Sru   Free Software Foundation, Inc.
4114402Sru     Written by James Clark (jjc@jclark.com)
5114402Sru
6114402SruThis file is part of groff.
7114402Sru
8114402Srugroff is free software; you can redistribute it and/or modify it under
9114402Sruthe terms of the GNU General Public License as published by the Free
10114402SruSoftware Foundation; either version 2, or (at your option) any later
11114402Sruversion.
12114402Sru
13114402Srugroff is distributed in the hope that it will be useful, but WITHOUT ANY
14114402SruWARRANTY; without even the implied warranty of MERCHANTABILITY or
15114402SruFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16114402Srufor more details.
17114402Sru
18114402SruYou should have received a copy of the GNU General Public License along
19114402Sruwith groff; see the file COPYING.  If not, write to the Free Software
20151497SruFoundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
21114402Sru
22114402Sru#include "lib.h"
23114402Sru
24114402Sru#include <stdlib.h>
25114402Sru#include <assert.h>
26114402Sru#include <errno.h>
27114402Sru
28114402Sru#include "posix.h"
29114402Sru#include "errarg.h"
30114402Sru#include "error.h"
31114402Sru#include "nonposix.h"
32114402Sru
33114402Sru#include "refid.h"
34114402Sru#include "search.h"
35114402Sru
36114402Sruint linear_truncate_len = 6;
37114402Sruconst char *linear_ignore_fields = "XYZ";
38114402Sru
39114402Srusearch_list::search_list()
40114402Sru: list(0), niterators(0), next_fid(1)
41114402Sru{
42114402Sru}
43114402Sru
44114402Srusearch_list::~search_list()
45114402Sru{
46114402Sru  assert(niterators == 0);
47114402Sru  while (list) {
48114402Sru    search_item *tem = list->next;
49114402Sru    delete list;
50114402Sru    list = tem;
51114402Sru  }
52114402Sru}
53114402Sru
54114402Sruvoid search_list::add_file(const char *filename, int silent)
55114402Sru{
56114402Sru  search_item *p = make_index_search_item(filename, next_fid);
57114402Sru  if (!p) {
58114402Sru    int fd = open(filename, O_RDONLY | O_BINARY);
59114402Sru    if (fd < 0) {
60114402Sru      if (!silent)
61114402Sru	error("can't open `%1': %2", filename, strerror(errno));
62114402Sru    }
63114402Sru    else
64114402Sru      p = make_linear_search_item(fd, filename, next_fid);
65114402Sru  }
66114402Sru  if (p) {
67114402Sru    search_item **pp;
68114402Sru    for (pp = &list; *pp; pp = &(*pp)->next)
69114402Sru      ;
70114402Sru    *pp = p;
71114402Sru    next_fid = p->next_filename_id();
72114402Sru  }
73114402Sru}
74114402Sru
75114402Sruint search_list::nfiles() const
76114402Sru{
77114402Sru  int n = 0;
78114402Sru  for (search_item *ptr = list; ptr; ptr = ptr->next)
79114402Sru    n++;
80114402Sru  return n;
81114402Sru}
82114402Sru
83114402Srusearch_list_iterator::search_list_iterator(search_list *p, const char *q)
84114402Sru: list(p), ptr(p->list), iter(0), query(strsave(q)),
85114402Sru  searcher(q, strlen(q), linear_ignore_fields, linear_truncate_len)
86114402Sru{
87114402Sru  list->niterators += 1;
88114402Sru}
89114402Sru
90114402Srusearch_list_iterator::~search_list_iterator()
91114402Sru{
92114402Sru  list->niterators -= 1;
93114402Sru  a_delete query;
94114402Sru  delete iter;
95114402Sru}
96114402Sru
97114402Sruint search_list_iterator::next(const char **pp, int *lenp, reference_id *ridp)
98114402Sru{
99114402Sru  while (ptr) {
100114402Sru    if (iter == 0)
101114402Sru      iter = ptr->make_search_item_iterator(query);
102114402Sru    if (iter->next(searcher, pp, lenp, ridp))
103114402Sru      return 1;
104114402Sru    delete iter;
105114402Sru    iter = 0;
106114402Sru    ptr = ptr->next;
107114402Sru  }
108114402Sru  return 0;
109114402Sru}
110114402Sru
111114402Srusearch_item::search_item(const char *nm, int fid)
112114402Sru: name(strsave(nm)), filename_id(fid), next(0)
113114402Sru{
114114402Sru}
115114402Sru
116114402Srusearch_item::~search_item()
117114402Sru{
118114402Sru  a_delete name;
119114402Sru}
120114402Sru
121114402Sruint search_item::is_named(const char *nm) const
122114402Sru{
123114402Sru  return strcmp(name, nm) == 0;
124114402Sru}
125114402Sru
126114402Sruint search_item::next_filename_id() const
127114402Sru{
128114402Sru  return filename_id + 1;
129114402Sru}
130114402Sru
131114402Srusearch_item_iterator::~search_item_iterator()
132114402Sru{
133114402Sru}
134