1 /*
2 *
3 * idxname.c - Idx handling routines.
4 *
5 * $Id: idxname.c,v 1.25.8.10 2009-02-17 08:45:14 opengl2772 Exp $
6 *
7 * Copyright (C) 1997-1999 Satoru Takabayashi All rights reserved.
8 * Copyright (C) 2000-2009 Namazu Project All rights reserved.
9 * Copyright (C) 1999 NOKUBI Takatsugu All rights reserved.
10 * This is free software with ABSOLUTELY NO WARRANTY.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 * 02111-1307, USA
26 *
27 *
28 */
29
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33 #ifdef HAVE_SUPPORT_H
34 # include "support.h"
35 #endif
36
37 #ifdef HAVE_ERRNO_H
38 # include <errno.h>
39 #endif
40
41 #ifdef HAVE_STDLIB_H
42 # include <stdlib.h>
43 #endif
44 #include <ctype.h>
45
46 #ifdef HAVE_STRING_H
47 # include <string.h>
48 #else
49 # include <strings.h>
50 #endif
51
52 #include "libnamazu.h"
53 #include "search.h"
54 #include "alias.h"
55 #include "var.h"
56 #include "idxname.h"
57 #include "util.h"
58
59 static struct nmz_indices indices = {0}; /* Initialize member `num' with 0 */
60
61 /*
62 * Default directory to place index. This setting can be
63 * changed with nmz_set_defaultidx().
64 */
65 static char defaultidx[BUFSIZE] = OPT_INDEXDIR;
66
67 /*
68 *
69 * Public functions
70 *
71 */
72
73 enum nmz_stat
nmz_add_index(const char * idxname)74 nmz_add_index(const char *idxname)
75 {
76 int newidxnum = indices.num;
77
78 if (newidxnum >= INDEX_MAX) {
79 nmz_warn_printf("Too many indices.\n");
80 return FAILURE;
81 }
82 indices.names[newidxnum] = malloc(strlen(idxname) + 1);
83 if (indices.names[newidxnum] == NULL)
84 return FAILURE;
85 strcpy(indices.names[newidxnum], idxname);
86 indices.hitnumlists[newidxnum] = NULL;
87 indices.num = newidxnum + 1;
88
89 return SUCCESS;
90 }
91
92 void
nmz_free_idxnames(void)93 nmz_free_idxnames(void)
94 {
95 int i;
96 for (i = 0; i < indices.num; i++) {
97 free(indices.names[i]);
98 nmz_free_hitnums(indices.hitnumlists[i]);
99 }
100 indices.num = 0;
101 }
102
103 /*
104 * Except duplicated indices with a simple O(n^2) algorithm.
105 */
106 void
nmz_uniq_idxnames(void)107 nmz_uniq_idxnames(void)
108 {
109 int i, j, k;
110
111 for (i = 0; i < indices.num - 1; i++) {
112 for (j = i + 1; j < indices.num; j++) {
113 if (strcmp(indices.names[i], indices.names[j]) == 0) {
114 free(indices.names[j]);
115 for (k = j + 1; k < indices.num; k++) {
116 indices.names[k - 1] = indices.names[k];
117 }
118 indices.num--;
119 j--;
120 }
121 }
122 }
123 }
124
125 /*
126 * Expand index name aliases defined in namazurc.
127 * e.g., Alias quux /home/foobar/NMZ/quux
128 */
129 int
nmz_expand_idxname_aliases(void)130 nmz_expand_idxname_aliases(void)
131 {
132 int i;
133
134 for (i = 0; i < indices.num; i++) {
135 struct nmz_alias *list = nmz_get_aliases();
136 while (list != NULL) {
137 if (strcmp(indices.names[i], list->alias) == 0) {
138 free(indices.names[i]);
139 indices.names[i] = malloc(strlen(list->real) + 1);
140 if (indices.names[i] == NULL) {
141 nmz_set_dyingmsg(nmz_msg("%s", strerror(errno)));
142 return FAILURE;
143 }
144 strcpy(indices.names[i], list->real);
145 }
146 list = list->next;
147 }
148 }
149 return 0;
150 }
151
152 /*
153 * Complete an abbreviated index name to completed one.
154 * e.g., +foobar -> (defaultidx)/foobar
155 */
156 int
nmz_complete_idxnames(void)157 nmz_complete_idxnames(void)
158 {
159 int i;
160
161 for (i = 0; i < indices.num; i++) {
162 if (*indices.names[i] == '+' &&
163 nmz_isalnum((unsigned char)*(indices.names[i] + 1))) {
164 char *tmp;
165 tmp = malloc(strlen(defaultidx)
166 + 1 + strlen(indices.names[i]) + 1);
167 if (tmp == NULL) {
168 nmz_set_dyingmsg(nmz_msg("%s", strerror(errno)));
169 return FAILURE;
170 }
171 strcpy(tmp, defaultidx);
172 strcat(tmp, "/");
173 strcat(tmp, indices.names[i] + 1); /* +1 means '+' */
174 free(indices.names[i]);
175 indices.names[i] = tmp;
176 }
177 }
178 return 0;
179 }
180
181 /*
182 * Get the name of the index specified by id.
183 */
184 char *
nmz_get_idxname(int id)185 nmz_get_idxname(int id)
186 {
187 return indices.names[id];
188 }
189
190 /*
191 * Get the total number of indices to search.
192 */
193 int
nmz_get_idxnum()194 nmz_get_idxnum()
195 {
196 return indices.num;
197 }
198
199 /*
200 * Set the total hit number of the index specified by id.
201 */
202 void
nmz_set_idx_totalhitnum(int id,int hitnum)203 nmz_set_idx_totalhitnum(int id, int hitnum)
204 {
205 indices.totalhitnums[id] = hitnum;
206 }
207
208 /*
209 * Get the total hit number of the index specified by id.
210 */
211 int
nmz_get_idx_totalhitnum(int id)212 nmz_get_idx_totalhitnum(int id)
213 {
214 return indices.totalhitnums[id];
215 }
216
217 /*
218 * Get the hitnumlist of the index specified by id.
219 */
220 struct nmz_hitnumlist *
nmz_get_idx_hitnumlist(int id)221 nmz_get_idx_hitnumlist(int id)
222 {
223 return indices.hitnumlists[id];
224 }
225
226 void
nmz_set_idx_hitnumlist(int id,struct nmz_hitnumlist * hnlist)227 nmz_set_idx_hitnumlist(int id, struct nmz_hitnumlist *hnlist)
228 {
229 indices.hitnumlists[id] = hnlist;
230 }
231
232 /*
233 * Push something and return pushed list.
234 */
235 struct nmz_hitnumlist *
nmz_push_hitnum(struct nmz_hitnumlist * hn,const char * str,int hitnum,enum nmz_stat stat)236 nmz_push_hitnum(struct nmz_hitnumlist *hn,
237 const char *str,
238 int hitnum,
239 enum nmz_stat stat
240 )
241 {
242 struct nmz_hitnumlist *hnptr = hn, *prevhnptr = hn;
243 while (hnptr != NULL) {
244 prevhnptr = hnptr;
245 hnptr = hnptr->next;
246 }
247 if ((hnptr = malloc(sizeof(struct nmz_hitnumlist))) == NULL) {
248 nmz_set_dyingmsg(nmz_msg("%s", strerror(errno)));
249 return NULL;
250 }
251 if (prevhnptr != NULL)
252 prevhnptr->next = hnptr;
253 hnptr->hitnum = hitnum;
254 hnptr->stat = stat;
255 hnptr->phrase = NULL;
256 hnptr->next = NULL;
257 if ((hnptr->word = malloc(strlen(str) +1)) == NULL) {
258 nmz_set_dyingmsg(nmz_msg("%s", strerror(errno)));
259 return NULL;
260 }
261 strcpy(hnptr->word, str);
262
263 if (hn == NULL)
264 return hnptr;
265 return hn;
266 }
267
268
269 void
nmz_set_defaultidx(const char * idx)270 nmz_set_defaultidx(const char *idx)
271 {
272 strncpy(defaultidx, idx, BUFSIZE - 1);
273 defaultidx[BUFSIZE - 1] = '\0';
274 }
275
276 char *
nmz_get_defaultidx(void)277 nmz_get_defaultidx(void)
278 {
279 return defaultidx;
280 }
281