+zebra_map_t zebra_add_map(zebra_maps_t zms, const char *index_type,
+ int map_type)
+{
+ zebra_map_t zm = (zebra_map_t) nmem_malloc(zms->nmem, sizeof(*zm));
+
+ zm->zebra_maps = zms;
+ zm->id = nmem_strdup(zms->nmem, index_type);
+ zm->maptab_name = 0;
+ zm->use_chain = 0;
+ zm->debug = 0;
+ zm->maptab = 0;
+ zm->type = map_type;
+ zm->completeness = 0;
+ zm->positioned = 0;
+ zm->alwaysmatches = 0;
+ zm->first_in_field = 0;
+
+ if (zms->last_map)
+ zms->last_map->next = zm;
+ else
+ zms->map_list = zm;
+ zms->last_map = zm;
+ zm->next = 0;
+#if YAZ_HAVE_ICU
+ zm->icu_chain = 0;
+#endif
+#if YAZ_HAVE_XML2
+ zm->doc = 0;
+#endif
+ zm->input_str = wrbuf_alloc();
+ zm->print_str = wrbuf_alloc();
+ return zm;
+}
+
+static int parse_command(zebra_maps_t zms, int argc, char **argv,
+ const char *fname, int lineno)
+{
+ zebra_map_t zm = zms->last_map;
+ if (argc == 1)
+ {
+ yaz_log(YLOG_WARN, "%s:%d: Missing arguments for '%s'",
+ fname, lineno, argv[0]);
+ return -1;
+ }
+ if (argc > 2)
+ {
+ yaz_log(YLOG_WARN, "%s:%d: Too many arguments for '%s'",
+ fname, lineno, argv[0]);
+ return -1;
+ }
+ if (!yaz_matchstr(argv[0], "index"))
+ {
+ zm = zebra_add_map(zms, argv[1], ZEBRA_MAP_TYPE_INDEX);
+ zm->positioned = 1;
+ }
+ else if (!yaz_matchstr(argv[0], "sort"))
+ {
+ zm = zebra_add_map(zms, argv[1], ZEBRA_MAP_TYPE_SORT);
+ zm->u.sort.entry_size = 80;
+ }
+ else if (!yaz_matchstr(argv[0], "staticrank"))
+ {
+ zm = zebra_add_map(zms, argv[1], ZEBRA_MAP_TYPE_STATICRANK);
+ zm->completeness = 1;
+ }
+ else if (!zm)
+ {
+ yaz_log(YLOG_WARN, "%s:%d: Missing sort/index before '%s'",
+ fname, lineno, argv[0]);
+ return -1;
+ }
+ else if (!yaz_matchstr(argv[0], "charmap") && argc == 2)
+ {
+ if (zm->type != ZEBRA_MAP_TYPE_STATICRANK)
+ zm->maptab_name = nmem_strdup(zms->nmem, argv[1]);
+ else
+ {
+ yaz_log(YLOG_WARN|YLOG_FATAL, "%s:%d: charmap for "
+ "staticrank is invalid", fname, lineno);
+ yaz_log(YLOG_LOG, "Type is %d", zm->type);
+ return -1;
+ }
+ }
+ else if (!yaz_matchstr(argv[0], "completeness") && argc == 2)
+ {
+ zm->completeness = atoi(argv[1]);
+ }
+ else if (!yaz_matchstr(argv[0], "position") && argc == 2)
+ {
+ zm->positioned = atoi(argv[1]);
+ }
+ else if (!yaz_matchstr(argv[0], "alwaysmatches") && argc == 2)
+ {
+ if (zm->type != ZEBRA_MAP_TYPE_STATICRANK)
+ zm->alwaysmatches = atoi(argv[1]);
+ else
+ {
+ yaz_log(YLOG_WARN|YLOG_FATAL, "%s:%d: alwaysmatches for "
+ "staticrank is invalid", fname, lineno);
+ return -1;
+ }
+ }
+ else if (!yaz_matchstr(argv[0], "firstinfield") && argc == 2)
+ {
+ zm->first_in_field = atoi(argv[1]);
+ }
+ else if (!yaz_matchstr(argv[0], "entrysize") && argc == 2)
+ {
+ if (zm->type == ZEBRA_MAP_TYPE_SORT)
+ zm->u.sort.entry_size = atoi(argv[1]);
+ else
+ {
+ yaz_log(YLOG_WARN,
+ "%s:%d: entrysize only valid in sort section",
+ fname, lineno);
+ return -1;
+ }
+ }
+ else if (!yaz_matchstr(argv[0], "simplechain"))
+ {
+ zm->use_chain = 1;
+#if YAZ_HAVE_ICU
+ zm->icu_chain = 0;
+#endif
+ }
+ else if (!yaz_matchstr(argv[0], "icuchain"))
+ {
+ char full_path[1024];
+ if (!yaz_filepath_resolve(argv[1], zms->tabpath, zms->tabroot,
+ full_path))
+ {
+ yaz_log(YLOG_WARN, "%s:%d: Could not locate icuchain config '%s'",
+ fname, lineno, argv[1]);
+ return -1;
+ }
+#if YAZ_HAVE_XML2
+ zm->doc = xmlParseFile(full_path);
+ if (!zm->doc)
+ {
+ yaz_log(YLOG_WARN, "%s:%d: Could not load icuchain config '%s'",
+ fname, lineno, argv[1]);
+ return -1;
+ }
+ else
+ {
+#if YAZ_HAVE_ICU
+ UErrorCode status;
+ xmlNode *xml_node = xmlDocGetRootElement(zm->doc);
+ zm->icu_chain =
+ icu_chain_xml_config(xml_node,
+/* not sure about sort for this function yet.. */
+#if 1
+ 1,
+#else
+ zm->type == ZEBRA_MAP_TYPE_SORT,
+#endif
+ &status);
+ if (!zm->icu_chain)
+ {
+ yaz_log(YLOG_WARN, "%s:%d: Failed to load ICU chain %s",
+ fname, lineno, argv[1]);
+ }
+ zm->use_chain = 1;
+#else
+ yaz_log(YLOG_WARN, "%s:%d: ICU support unavailable",
+ fname, lineno);
+ return -1;
+#endif
+ }
+#else
+ yaz_log(YLOG_WARN, "%s:%d: XML support unavailable",
+ fname, lineno);
+ return -1;
+#endif
+ }
+ else if (!yaz_matchstr(argv[0], "debug") && argc == 2)
+ {
+ zm->debug = atoi(argv[1]);
+ }
+ else
+ {
+ yaz_log(YLOG_WARN, "%s:%d: Unrecognized directive '%s'",
+ fname, lineno, argv[0]);
+ return -1;
+ }
+ return 0;
+}
+
+ZEBRA_RES zebra_maps_read_file(zebra_maps_t zms, const char *fname)