1 /* This file is part of the Zebra server.
2 Copyright (C) 2004-2013 Index Data
3
4 Zebra is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
7 version.
8
9 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
18 */
19
20 #if HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 #include <assert.h>
24 #include <stdlib.h>
25 #include <ctype.h>
26
27 #include <charmap.h>
28 #include <attrfind.h>
29 #include <yaz/yaz-util.h>
30
31 #if YAZ_HAVE_ICU
32 #include <yaz/icu.h>
33 #endif
34 #include <zebramap.h>
35
36 #define ZEBRA_MAP_TYPE_SORT 1
37 #define ZEBRA_MAP_TYPE_INDEX 2
38 #define ZEBRA_MAP_TYPE_STATICRANK 3
39
40 #define ZEBRA_REPLACE_ANY 300
41
42 struct zebra_map {
43 const char *id;
44 int completeness;
45 int positioned;
46 int alwaysmatches;
47 int first_in_field;
48 int type;
49 int use_chain;
50 int debug;
51 union {
52 struct {
53 int entry_size;
54 } sort;
55 } u;
56 chrmaptab maptab;
57 const char *maptab_name;
58 zebra_maps_t zebra_maps;
59 #if YAZ_HAVE_XML2
60 xmlDocPtr doc;
61 #endif
62 #if YAZ_HAVE_ICU
63 struct icu_chain *icu_chain;
64 #endif
65 WRBUF input_str;
66 WRBUF print_str;
67 size_t simple_off;
68 struct zebra_map *next;
69 };
70
71 struct zebra_maps_s {
72 char *tabpath;
73 char *tabroot;
74 NMEM nmem;
75 char temp_map_str[2];
76 const char *temp_map_ptr[2];
77 WRBUF wrbuf_1;
78 int no_files_read;
79 zebra_map_t map_list;
80 zebra_map_t last_map;
81 };
82
zebra_maps_close(zebra_maps_t zms)83 void zebra_maps_close(zebra_maps_t zms)
84 {
85 struct zebra_map *zm = zms->map_list;
86 while (zm)
87 {
88 if (zm->maptab)
89 chrmaptab_destroy(zm->maptab);
90 #if YAZ_HAVE_ICU
91 if (zm->icu_chain)
92 icu_chain_destroy(zm->icu_chain);
93 #endif
94 #if YAZ_HAVE_XML2
95 xmlFreeDoc(zm->doc);
96 #endif
97 wrbuf_destroy(zm->input_str);
98 wrbuf_destroy(zm->print_str);
99 zm = zm->next;
100 }
101 wrbuf_destroy(zms->wrbuf_1);
102 nmem_destroy(zms->nmem);
103 xfree(zms);
104 }
105
zebra_add_map(zebra_maps_t zms,const char * index_type,int map_type)106 zebra_map_t zebra_add_map(zebra_maps_t zms, const char *index_type,
107 int map_type)
108 {
109 zebra_map_t zm = (zebra_map_t) nmem_malloc(zms->nmem, sizeof(*zm));
110
111 zm->zebra_maps = zms;
112 zm->id = nmem_strdup(zms->nmem, index_type);
113 zm->maptab_name = 0;
114 zm->use_chain = 0;
115 zm->debug = 0;
116 zm->maptab = 0;
117 zm->type = map_type;
118 zm->completeness = 0;
119 zm->positioned = 0;
120 zm->alwaysmatches = 0;
121 zm->first_in_field = 0;
122
123 if (zms->last_map)
124 zms->last_map->next = zm;
125 else
126 zms->map_list = zm;
127 zms->last_map = zm;
128 zm->next = 0;
129 #if YAZ_HAVE_ICU
130 zm->icu_chain = 0;
131 #endif
132 #if YAZ_HAVE_XML2
133 zm->doc = 0;
134 #endif
135 zm->input_str = wrbuf_alloc();
136 zm->print_str = wrbuf_alloc();
137 return zm;
138 }
139
parse_command(zebra_maps_t zms,int argc,char ** argv,const char * fname,int lineno)140 static int parse_command(zebra_maps_t zms, int argc, char **argv,
141 const char *fname, int lineno)
142 {
143 zebra_map_t zm = zms->last_map;
144 if (argc == 1)
145 {
146 yaz_log(YLOG_WARN, "%s:%d: Missing arguments for '%s'",
147 fname, lineno, argv[0]);
148 return -1;
149 }
150 if (argc > 2)
151 {
152 yaz_log(YLOG_WARN, "%s:%d: Too many arguments for '%s'",
153 fname, lineno, argv[0]);
154 return -1;
155 }
156 if (!yaz_matchstr(argv[0], "index"))
157 {
158 zm = zebra_add_map(zms, argv[1], ZEBRA_MAP_TYPE_INDEX);
159 zm->positioned = 1;
160 }
161 else if (!yaz_matchstr(argv[0], "sort"))
162 {
163 zm = zebra_add_map(zms, argv[1], ZEBRA_MAP_TYPE_SORT);
164 zm->u.sort.entry_size = 80;
165 }
166 else if (!yaz_matchstr(argv[0], "staticrank"))
167 {
168 zm = zebra_add_map(zms, argv[1], ZEBRA_MAP_TYPE_STATICRANK);
169 zm->completeness = 1;
170 }
171 else if (!zm)
172 {
173 yaz_log(YLOG_WARN, "%s:%d: Missing sort/index before '%s'",
174 fname, lineno, argv[0]);
175 return -1;
176 }
177 else if (!yaz_matchstr(argv[0], "charmap") && argc == 2)
178 {
179 if (zm->type != ZEBRA_MAP_TYPE_STATICRANK)
180 zm->maptab_name = nmem_strdup(zms->nmem, argv[1]);
181 else
182 {
183 yaz_log(YLOG_WARN|YLOG_FATAL, "%s:%d: charmap for "
184 "staticrank is invalid", fname, lineno);
185 yaz_log(YLOG_LOG, "Type is %d", zm->type);
186 return -1;
187 }
188 }
189 else if (!yaz_matchstr(argv[0], "completeness") && argc == 2)
190 {
191 zm->completeness = atoi(argv[1]);
192 }
193 else if (!yaz_matchstr(argv[0], "position") && argc == 2)
194 {
195 zm->positioned = atoi(argv[1]);
196 }
197 else if (!yaz_matchstr(argv[0], "alwaysmatches") && argc == 2)
198 {
199 if (zm->type != ZEBRA_MAP_TYPE_STATICRANK)
200 zm->alwaysmatches = atoi(argv[1]);
201 else
202 {
203 yaz_log(YLOG_WARN|YLOG_FATAL, "%s:%d: alwaysmatches for "
204 "staticrank is invalid", fname, lineno);
205 return -1;
206 }
207 }
208 else if (!yaz_matchstr(argv[0], "firstinfield") && argc == 2)
209 {
210 zm->first_in_field = atoi(argv[1]);
211 }
212 else if (!yaz_matchstr(argv[0], "entrysize") && argc == 2)
213 {
214 if (zm->type == ZEBRA_MAP_TYPE_SORT)
215 zm->u.sort.entry_size = atoi(argv[1]);
216 else
217 {
218 yaz_log(YLOG_WARN,
219 "%s:%d: entrysize only valid in sort section",
220 fname, lineno);
221 return -1;
222 }
223 }
224 else if (!yaz_matchstr(argv[0], "simplechain"))
225 {
226 zm->use_chain = 1;
227 #if YAZ_HAVE_ICU
228 zm->icu_chain = 0;
229 #endif
230 }
231 else if (!yaz_matchstr(argv[0], "icuchain"))
232 {
233 char full_path[1024];
234 if (!yaz_filepath_resolve(argv[1], zms->tabpath, zms->tabroot,
235 full_path))
236 {
237 yaz_log(YLOG_WARN, "%s:%d: Could not locate icuchain config '%s'",
238 fname, lineno, argv[1]);
239 return -1;
240 }
241 #if YAZ_HAVE_XML2
242 zm->doc = xmlParseFile(full_path);
243 if (!zm->doc)
244 {
245 yaz_log(YLOG_WARN, "%s:%d: Could not load icuchain config '%s'",
246 fname, lineno, argv[1]);
247 return -1;
248 }
249 else
250 {
251 #if YAZ_HAVE_ICU
252 UErrorCode status;
253 xmlNode *xml_node = xmlDocGetRootElement(zm->doc);
254 zm->icu_chain =
255 icu_chain_xml_config(xml_node,
256 /* not sure about sort for this function yet.. */
257 #if 1
258 1,
259 #else
260 zm->type == ZEBRA_MAP_TYPE_SORT,
261 #endif
262 &status);
263 if (!zm->icu_chain)
264 {
265 yaz_log(YLOG_WARN, "%s:%d: Failed to load ICU chain %s",
266 fname, lineno, argv[1]);
267 }
268 zm->use_chain = 1;
269 #else
270 yaz_log(YLOG_WARN, "%s:%d: ICU support unavailable",
271 fname, lineno);
272 return -1;
273 #endif
274 }
275 #else
276 yaz_log(YLOG_WARN, "%s:%d: XML support unavailable",
277 fname, lineno);
278 return -1;
279 #endif
280 }
281 else if (!yaz_matchstr(argv[0], "debug") && argc == 2)
282 {
283 zm->debug = atoi(argv[1]);
284 }
285 else
286 {
287 yaz_log(YLOG_WARN, "%s:%d: Unrecognized directive '%s'",
288 fname, lineno, argv[0]);
289 return -1;
290 }
291 return 0;
292 }
293
zebra_maps_read_file(zebra_maps_t zms,const char * fname)294 ZEBRA_RES zebra_maps_read_file(zebra_maps_t zms, const char *fname)
295 {
296 FILE *f;
297 char line[512];
298 char *argv[10];
299 int argc;
300 int lineno = 0;
301 int failures = 0;
302
303 if (!(f = yaz_fopen(zms->tabpath, fname, "r", zms->tabroot)))
304 {
305 yaz_log(YLOG_ERRNO|YLOG_FATAL, "%s", fname);
306 return ZEBRA_FAIL;
307 }
308 while ((argc = readconf_line(f, &lineno, line, 512, argv, 10)))
309 {
310 int r = parse_command(zms, argc, argv, fname, lineno);
311 if (r)
312 failures++;
313 }
314 yaz_fclose(f);
315
316 if (failures)
317 return ZEBRA_FAIL;
318
319 (zms->no_files_read)++;
320 return ZEBRA_OK;
321 }
322
zebra_maps_open(Res res,const char * base_path,const char * profile_path)323 zebra_maps_t zebra_maps_open(Res res, const char *base_path,
324 const char *profile_path)
325 {
326 zebra_maps_t zms = (zebra_maps_t) xmalloc(sizeof(*zms));
327
328 zms->nmem = nmem_create();
329 zms->tabpath = profile_path ? nmem_strdup(zms->nmem, profile_path) : 0;
330 zms->tabroot = 0;
331 if (base_path)
332 zms->tabroot = nmem_strdup(zms->nmem, base_path);
333 zms->map_list = 0;
334 zms->last_map = 0;
335
336 zms->temp_map_str[0] = '\0';
337 zms->temp_map_str[1] = '\0';
338
339 zms->temp_map_ptr[0] = zms->temp_map_str;
340 zms->temp_map_ptr[1] = NULL;
341
342 zms->wrbuf_1 = wrbuf_alloc();
343
344 zms->no_files_read = 0;
345 return zms;
346 }
347
zebra_maps_define_default_sort(zebra_maps_t zms)348 void zebra_maps_define_default_sort(zebra_maps_t zms)
349 {
350 zebra_map_t zm = zebra_add_map(zms, "s", ZEBRA_MAP_TYPE_SORT);
351 zm->u.sort.entry_size = 80;
352 }
353
zebra_map_get(zebra_maps_t zms,const char * id)354 zebra_map_t zebra_map_get(zebra_maps_t zms, const char *id)
355 {
356 zebra_map_t zm;
357 for (zm = zms->map_list; zm; zm = zm->next)
358 if (!strcmp(zm->id, id))
359 break;
360 return zm;
361 }
362
zebra_map_get_or_add(zebra_maps_t zms,const char * id)363 zebra_map_t zebra_map_get_or_add(zebra_maps_t zms, const char *id)
364 {
365 struct zebra_map *zm = zebra_map_get(zms, id);
366 if (!zm)
367 {
368 zm = zebra_add_map(zms, id, ZEBRA_MAP_TYPE_INDEX);
369
370 /* no reason to warn if no maps are read from file */
371 if (zms->no_files_read)
372 yaz_log(YLOG_WARN, "Unknown register type: %s", id);
373
374 zm->maptab_name = nmem_strdup(zms->nmem, "@");
375 zm->completeness = 0;
376 zm->positioned = 1;
377 }
378 return zm;
379 }
380
zebra_charmap_get(zebra_map_t zm)381 chrmaptab zebra_charmap_get(zebra_map_t zm)
382 {
383 if (!zm->maptab)
384 {
385 if (!zm->maptab_name || !yaz_matchstr(zm->maptab_name, "@"))
386 return NULL;
387 if (!(zm->maptab = chrmaptab_create(zm->zebra_maps->tabpath,
388 zm->maptab_name,
389 zm->zebra_maps->tabroot)))
390 yaz_log(YLOG_WARN, "Failed to read character table %s",
391 zm->maptab_name);
392 else
393 yaz_log(YLOG_DEBUG, "Read character table %s", zm->maptab_name);
394 }
395 return zm->maptab;
396 }
397
zebra_maps_input(zebra_map_t zm,const char ** from,int len,int first)398 const char **zebra_maps_input(zebra_map_t zm,
399 const char **from, int len, int first)
400 {
401 chrmaptab maptab = zebra_charmap_get(zm);
402 if (maptab)
403 return chr_map_input(maptab, from, len, first);
404
405 zm->zebra_maps->temp_map_str[0] = **from;
406
407 (*from)++;
408 return zm->zebra_maps->temp_map_ptr;
409 }
410
zebra_maps_search(zebra_map_t zm,const char ** from,int len,int * q_map_match)411 const char **zebra_maps_search(zebra_map_t zm,
412 const char **from, int len, int *q_map_match)
413 {
414 chrmaptab maptab;
415
416 *q_map_match = 0;
417 maptab = zebra_charmap_get(zm);
418 if (maptab)
419 {
420 const char **map;
421 map = chr_map_q_input(maptab, from, len, 0);
422 if (map && map[0])
423 {
424 *q_map_match = 1;
425 return map;
426 }
427 map = chr_map_input(maptab, from, len, 0);
428 if (map)
429 return map;
430 }
431 zm->zebra_maps->temp_map_str[0] = **from;
432
433 (*from)++;
434 return zm->zebra_maps->temp_map_ptr;
435 }
436
zebra_maps_output(zebra_map_t zm,const char ** from)437 const char *zebra_maps_output(zebra_map_t zm,
438 const char **from)
439 {
440 chrmaptab maptab = zebra_charmap_get(zm);
441 if (!maptab)
442 return 0;
443 return chr_map_output(maptab, from, 1);
444 }
445
446
447 /* ------------------------------------ */
448
zebra_maps_is_complete(zebra_map_t zm)449 int zebra_maps_is_complete(zebra_map_t zm)
450 {
451 if (zm)
452 return zm->completeness;
453 return 0;
454 }
455
zebra_maps_is_positioned(zebra_map_t zm)456 int zebra_maps_is_positioned(zebra_map_t zm)
457 {
458 if (zm)
459 return zm->positioned;
460 return 0;
461 }
462
zebra_maps_is_index(zebra_map_t zm)463 int zebra_maps_is_index(zebra_map_t zm)
464 {
465 if (zm)
466 return zm->type == ZEBRA_MAP_TYPE_INDEX;
467 return 0;
468 }
469
zebra_maps_is_staticrank(zebra_map_t zm)470 int zebra_maps_is_staticrank(zebra_map_t zm)
471 {
472 if (zm)
473 return zm->type == ZEBRA_MAP_TYPE_STATICRANK;
474 return 0;
475 }
476
zebra_maps_is_sort(zebra_map_t zm)477 int zebra_maps_is_sort(zebra_map_t zm)
478 {
479 if (zm)
480 return zm->type == ZEBRA_MAP_TYPE_SORT;
481 return 0;
482 }
483
zebra_maps_is_alwaysmatches(zebra_map_t zm)484 int zebra_maps_is_alwaysmatches(zebra_map_t zm)
485 {
486 if (zm)
487 return zm->alwaysmatches;
488 return 0;
489 }
490
zebra_maps_is_first_in_field(zebra_map_t zm)491 int zebra_maps_is_first_in_field(zebra_map_t zm)
492 {
493 if (zm)
494 return zm->first_in_field;
495 return 0;
496 }
497
zebra_maps_sort(zebra_maps_t zms,Z_SortAttributes * sortAttributes,int * numerical)498 int zebra_maps_sort(zebra_maps_t zms, Z_SortAttributes *sortAttributes,
499 int *numerical)
500 {
501 AttrType use;
502 AttrType structure;
503 int structure_value;
504 attr_init_AttrList(&use, sortAttributes->list, 1);
505 attr_init_AttrList(&structure, sortAttributes->list, 4);
506
507 *numerical = 0;
508 structure_value = attr_find(&structure, 0);
509 if (structure_value == 109)
510 *numerical = 1;
511 return attr_find(&use, NULL);
512 }
513
zebra_maps_attr(zebra_maps_t zms,Z_AttributesPlusTerm * zapt,const char ** index_type,char ** search_type,char * rank_type,int * complete_flag,int * sort_flag)514 int zebra_maps_attr(zebra_maps_t zms, Z_AttributesPlusTerm *zapt,
515 const char **index_type, char **search_type, char *rank_type,
516 int *complete_flag, int *sort_flag)
517 {
518 AttrType completeness;
519 AttrType structure;
520 AttrType relation;
521 AttrType sort_relation;
522 AttrType weight;
523 AttrType use;
524 int completeness_value;
525 int structure_value;
526 const char *structure_str = 0;
527 int relation_value;
528 int sort_relation_value;
529 int weight_value;
530 int use_value;
531
532 attr_init_APT(&structure, zapt, 4);
533 attr_init_APT(&completeness, zapt, 6);
534 attr_init_APT(&relation, zapt, 2);
535 attr_init_APT(&sort_relation, zapt, 7);
536 attr_init_APT(&weight, zapt, 9);
537 attr_init_APT(&use, zapt, 1);
538
539 completeness_value = attr_find(&completeness, NULL);
540 structure_value = attr_find_ex(&structure, NULL, &structure_str);
541 relation_value = attr_find(&relation, NULL);
542 sort_relation_value = attr_find(&sort_relation, NULL);
543 weight_value = attr_find(&weight, NULL);
544 use_value = attr_find(&use, NULL);
545
546 if (completeness_value == 2 || completeness_value == 3)
547 *complete_flag = 1;
548 else
549 *complete_flag = 0;
550 *index_type = 0;
551
552 *sort_flag =(sort_relation_value > 0) ? 1 : 0;
553 *search_type = "phrase";
554 strcpy(rank_type, "void");
555 if (relation_value == 102)
556 {
557 if (weight_value == -1)
558 weight_value = 34;
559 sprintf(rank_type, "rank,w=%d,u=%d", weight_value, use_value);
560 }
561 if (*complete_flag)
562 *index_type = "p";
563 else
564 *index_type = "w";
565 switch (structure_value)
566 {
567 case 6: /* word list */
568 *search_type = "and-list";
569 break;
570 case 105: /* free-form-text */
571 *search_type = "or-list";
572 break;
573 case 106: /* document-text */
574 *search_type = "or-list";
575 break;
576 case -1:
577 case 1: /* phrase */
578 case 2: /* word */
579 case 108: /* string */
580 *search_type = "phrase";
581 break;
582 case 107: /* local-number */
583 *search_type = "local";
584 *index_type = 0;
585 break;
586 case 109: /* numeric string */
587 *index_type = "n";
588 *search_type = "numeric";
589 break;
590 case 104: /* urx */
591 *index_type = "u";
592 *search_type = "phrase";
593 break;
594 case 3: /* key */
595 *index_type = "0";
596 *search_type = "phrase";
597 break;
598 case 4: /* year */
599 *index_type = "y";
600 *search_type = "phrase";
601 break;
602 case 5: /* date */
603 *index_type = "d";
604 *search_type = "phrase";
605 break;
606 case -2:
607 if (structure_str && *structure_str)
608 *index_type = structure_str;
609 else
610 return -1;
611 break;
612 default:
613 return -1;
614 }
615 return 0;
616 }
617
zebra_replace(zebra_map_t zm,const char * ex_list,const char * input_str,int input_len)618 WRBUF zebra_replace(zebra_map_t zm, const char *ex_list,
619 const char *input_str, int input_len)
620 {
621 wrbuf_rewind(zm->zebra_maps->wrbuf_1);
622 wrbuf_write(zm->zebra_maps->wrbuf_1, input_str, input_len);
623 return zm->zebra_maps->wrbuf_1;
624 }
625
626 #define SE_CHARS ";,.()-/?<> \r\n\t"
627
tokenize_simple(zebra_map_t zm,const char ** result_buf,size_t * result_len)628 static int tokenize_simple(zebra_map_t zm,
629 const char **result_buf, size_t *result_len)
630 {
631 char *buf = wrbuf_buf(zm->input_str);
632 size_t len = wrbuf_len(zm->input_str);
633 size_t i = zm->simple_off;
634 size_t start;
635
636 while (i < len && strchr(SE_CHARS, buf[i]))
637 i++;
638 start = i;
639 while (i < len && !strchr(SE_CHARS, buf[i]))
640 {
641 if (buf[i] > 32 && buf[i] < 127)
642 buf[i] = tolower(buf[i]);
643 i++;
644 }
645
646 zm->simple_off = i;
647 if (start != i)
648 {
649 *result_buf = buf + start;
650 *result_len = i - start;
651 return 1;
652 }
653 return 0;
654 }
655
656
zebra_map_tokenize_next(zebra_map_t zm,const char ** result_buf,size_t * result_len,const char ** display_buf,size_t * display_len)657 int zebra_map_tokenize_next(zebra_map_t zm,
658 const char **result_buf, size_t *result_len,
659 const char **display_buf, size_t *display_len)
660 {
661 assert(zm->use_chain);
662
663 #if YAZ_HAVE_ICU
664 if (!zm->icu_chain)
665 return tokenize_simple(zm, result_buf, result_len);
666 else
667 {
668 UErrorCode status;
669 while (icu_chain_next_token(zm->icu_chain, &status))
670 {
671 if (!U_SUCCESS(status))
672 return 0;
673 *result_buf = icu_chain_token_sortkey(zm->icu_chain);
674 assert(*result_buf);
675
676 *result_len = strlen(*result_buf);
677
678 if (display_buf)
679 {
680 *display_buf = icu_chain_token_display(zm->icu_chain);
681 if (display_len)
682 *display_len = strlen(*display_buf);
683 }
684 if (zm->debug)
685 {
686 wrbuf_rewind(zm->print_str);
687 wrbuf_write_escaped(zm->print_str, *result_buf, *result_len);
688 yaz_log(YLOG_LOG, "output %s", wrbuf_cstr(zm->print_str));
689 }
690
691 if (**result_buf != '\0')
692 return 1;
693 }
694 }
695 return 0;
696 #else
697 return tokenize_simple(zm, result_buf, result_len);
698 #endif
699 }
700
zebra_map_tokenize_start(zebra_map_t zm,const char * buf,size_t len)701 int zebra_map_tokenize_start(zebra_map_t zm,
702 const char *buf, size_t len)
703 {
704 #if YAZ_HAVE_ICU
705 int ret;
706 #endif
707 assert(zm->use_chain);
708
709 wrbuf_rewind(zm->input_str);
710 wrbuf_write(zm->input_str, buf, len);
711 zm->simple_off = 0;
712 #if YAZ_HAVE_ICU
713 if (zm->icu_chain)
714 {
715 UErrorCode status;
716 if (zm->debug)
717 {
718 wrbuf_rewind(zm->print_str);
719 wrbuf_write_escaped(zm->print_str, wrbuf_buf(zm->input_str),
720 wrbuf_len(zm->input_str));
721
722 yaz_log(YLOG_LOG, "input %s",
723 wrbuf_cstr(zm->print_str));
724 }
725 ret = icu_chain_assign_cstr(zm->icu_chain,
726 wrbuf_cstr(zm->input_str), &status);
727 if (!ret && !U_SUCCESS(status))
728 {
729 if (zm->debug)
730 {
731 yaz_log(YLOG_WARN, "bad encoding for input");
732 }
733 return -1;
734 }
735 }
736 #endif
737 return 0;
738 }
739
zebra_maps_is_icu(zebra_map_t zm)740 int zebra_maps_is_icu(zebra_map_t zm)
741 {
742 assert(zm);
743 #if YAZ_HAVE_ICU
744 return zm->use_chain;
745 #else
746 return 0;
747 #endif
748 }
749
750
751 /*
752 * Local variables:
753 * c-basic-offset: 4
754 * c-file-style: "Stroustrup"
755 * indent-tabs-mode: nil
756 * End:
757 * vim: shiftwidth=4 tabstop=8 expandtab
758 */
759
760