X-Git-Url: http://git.indexdata.com/?p=idzebra-moved-to-github.git;a=blobdiff_plain;f=data1%2Fd1_read.c;h=30e9732e0daa9b71ae9098fa71c513808238e375;hp=438f85d2823de171d4353fb3eaff609abd7095ea;hb=ca820b5e84bec416bf0f5790d1aac509842b4faf;hpb=0a5aa3b65fe14789bcada545a0e399545725d1ff diff --git a/data1/d1_read.c b/data1/d1_read.c index 438f85d..30e9732 100644 --- a/data1/d1_read.c +++ b/data1/d1_read.c @@ -1,6 +1,6 @@ -/* $Id: d1_read.c,v 1.3 2003-02-28 12:33:38 oleg Exp $ - Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002 - Index Data Aps +/* $Id: d1_read.c,v 1.27 2007-06-27 22:04:45 adam Exp $ + Copyright (C) 1995-2007 + Index Data ApS This file is part of the Zebra server. @@ -15,9 +15,9 @@ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with Zebra; see the file LICENSE.zebra. If not, write to the -Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ @@ -29,10 +29,8 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #include -#include #include -#include -#include +#include data1_node *data1_get_root_tag (data1_handle dh, data1_node *n) { @@ -118,7 +116,7 @@ static void data1_init_node (data1_handle dh, data1_node *r, int type) r->u.preprocess.attributes = 0; break; default: - logf (LOG_WARN, "data_mk_node_type. bad type = %d\n", type); + yaz_log (YLOG_WARN, "data_mk_node_type. bad type = %d\n", type); } } @@ -127,14 +125,13 @@ data1_node *data1_append_node (data1_handle dh, NMEM m, int type, { data1_node *r = (data1_node *)nmem_malloc(m, sizeof(*r)); r->next = r->child = r->last_child = 0; - r->destroy = 0; - + + r->parent = parent; if (!parent) r->root = r; else { r->root = parent->root; - r->parent = parent; if (!parent->child) parent->child = parent->last_child = r; else @@ -156,7 +153,6 @@ data1_node *data1_insert_node (data1_handle dh, NMEM m, int type, { data1_node *r = (data1_node *)nmem_malloc(m, sizeof(*r)); r->next = r->child = r->last_child = 0; - r->destroy = 0; if (!parent) r->root = r; @@ -174,27 +170,14 @@ data1_node *data1_insert_node (data1_handle dh, NMEM m, int type, return r; } -void data1_free_tree (data1_handle dh, data1_node *t) -{ - data1_node *p = t->child, *pn; - - while (p) - { - pn = p->next; - data1_free_tree (dh, p); - p = pn; - } - if (t->destroy) - (*t->destroy)(t); -} - data1_node *data1_mk_root (data1_handle dh, NMEM nmem, const char *name) { - data1_absyn *absyn = data1_get_absyn (dh, name); + data1_absyn *absyn = data1_get_absyn(dh, name, 1); data1_node *res; + if (!absyn) { - yaz_log(LOG_WARN, "Unable to acquire abstract syntax " "for '%s'", + yaz_log(YLOG_WARN, "Unable to acquire abstract syntax " "for '%s'", name); /* It's now OK for a record not to have an absyn */ } @@ -207,12 +190,31 @@ data1_node *data1_mk_root (data1_handle dh, NMEM nmem, const char *name) void data1_set_root(data1_handle dh, data1_node *res, NMEM nmem, const char *name) { - data1_absyn *absyn = data1_get_absyn (dh, name); + data1_absyn *absyn = data1_get_absyn( + dh, name, DATA1_XPATH_INDEXING_ENABLE); res->u.root.type = data1_insert_string (dh, res, nmem, name); res->u.root.absyn = absyn; } +void data1_add_attrs(data1_handle dh, NMEM nmem, const char **attr, + data1_xattr **p) +{ + while (*p) + p = &(*p)->next; + + while (attr && *attr) + { + *p = (data1_xattr*) nmem_malloc (nmem, sizeof(**p)); + (*p)->name = nmem_strdup (nmem, *attr++); + (*p)->value = nmem_strdup (nmem, *attr++); + (*p)->what = DATA1I_text; + + p = &(*p)->next; + } + *p = 0; +} + data1_node *data1_mk_preprocess (data1_handle dh, NMEM nmem, const char *target, const char **attr, data1_node *at) @@ -225,22 +227,31 @@ data1_node *data1_mk_preprocess_n (data1_handle dh, NMEM nmem, const char *target, size_t len, const char **attr, data1_node *at) { - data1_xattr **p; data1_node *res = data1_mk_node2 (dh, nmem, DATA1N_preprocess, at); res->u.preprocess.target = data1_insert_string_n (dh, res, nmem, target, len); - p = &res->u.preprocess.attributes; - while (attr && *attr) - { - *p = (data1_xattr*) nmem_malloc (nmem, sizeof(**p)); - (*p)->name = nmem_strdup (nmem, *attr++); - (*p)->value = nmem_strdup (nmem, *attr++); - (*p)->what = DATA1I_text; + data1_add_attrs(dh, nmem, attr, &res->u.preprocess.attributes); + return res; +} - p = &(*p)->next; - } - *p = 0; +data1_node *data1_insert_preprocess (data1_handle dh, NMEM nmem, + const char *target, + const char **attr, data1_node *at) +{ + return data1_insert_preprocess_n (dh, nmem, target, strlen(target), + attr, at); +} + +data1_node *data1_insert_preprocess_n (data1_handle dh, NMEM nmem, + const char *target, size_t len, + const char **attr, data1_node *at) +{ + data1_node *res = data1_insert_node (dh, nmem, DATA1N_preprocess, at); + res->u.preprocess.target = data1_insert_string_n (dh, res, nmem, + target, len); + + data1_add_attrs(dh, nmem, attr, &res->u.preprocess.attributes); return res; } @@ -250,7 +261,6 @@ data1_node *data1_mk_tag_n (data1_handle dh, NMEM nmem, { data1_node *partag = get_parent_tag(dh, at); data1_node *res = data1_mk_node2 (dh, nmem, DATA1N_tag, at); - data1_xattr **p; data1_element *e = 0; res->u.tag.tag = data1_insert_string_n (dh, res, nmem, tag, len); @@ -268,40 +278,17 @@ data1_node *data1_mk_tag_n (data1_handle dh, NMEM nmem, e, res->u.tag.tag); } res->u.tag.element = e; - p = &res->u.tag.attributes; - while (attr && *attr) - { - *p = (data1_xattr*) nmem_malloc (nmem, sizeof(**p)); - (*p)->name = nmem_strdup (nmem, *attr++); - (*p)->value = nmem_strdup (nmem, *attr++); - (*p)->what = DATA1I_text; - p = &(*p)->next; - } - *p = 0; + data1_add_attrs(dh, nmem, attr, &res->u.tag.attributes); return res; } void data1_tag_add_attr (data1_handle dh, NMEM nmem, data1_node *res, const char **attr) { - data1_xattr **p; - if (res->which != DATA1N_tag) return; - p = &res->u.tag.attributes; - while (*p) - p = &(*p)->next; - - while (attr && *attr) - { - *p = (data1_xattr*) nmem_malloc (nmem, sizeof(**p)); - (*p)->name = nmem_strdup (nmem, *attr++); - (*p)->value = nmem_strdup (nmem, *attr++); - (*p)->what = DATA1I_text; - p = &(*p)->next; - } - *p = 0; + data1_add_attrs(dh, nmem, attr, &res->u.tag.attributes); } data1_node *data1_mk_tag (data1_handle dh, NMEM nmem, @@ -467,8 +454,8 @@ data1_node *data1_add_taggeddata (data1_handle dh, data1_node *root, return data1_add_insert_taggeddata (dh, at, tagname, m, 1, 0); } -data1_node *data1_mk_tag_data_int (data1_handle dh, data1_node *at, - const char *tag, int num, +data1_node *data1_mk_tag_data_zint (data1_handle dh, data1_node *at, + const char *tag, zint num, NMEM nmem) { data1_node *node_data; @@ -478,11 +465,18 @@ data1_node *data1_mk_tag_data_int (data1_handle dh, data1_node *at, return 0; node_data->u.data.what = DATA1I_num; node_data->u.data.data = node_data->lbuf; - sprintf (node_data->u.data.data, "%d", num); + sprintf (node_data->u.data.data, ZINT_FORMAT, num); node_data->u.data.len = strlen (node_data->u.data.data); return node_data; } +data1_node *data1_mk_tag_data_int (data1_handle dh, data1_node *at, + const char *tag, int num, + NMEM nmem) +{ + return data1_mk_tag_data_zint(dh, at, tag, num, nmem); +} + data1_node *data1_mk_tag_data_oid (data1_handle dh, data1_node *at, const char *tag, Odr_oid *oid, NMEM nmem) @@ -599,7 +593,6 @@ data1_xattr *data1_read_xattr (data1_handle dh, NMEM m, for (;;) { data1_xattr *p; - int len; while (*amp || (c && d1_isspace(c))) c = ampr (get_byte, fh, amp); if (*amp == 0 && (c == 0 || c == '>' || c == '/')) @@ -616,10 +609,7 @@ data1_xattr *data1_read_xattr (data1_handle dh, NMEM m, wrbuf_putc (wrbuf, c); c = ampr (get_byte, fh, amp); } - wrbuf_putc (wrbuf, '\0'); - len = wrbuf_len(wrbuf); - p->name = (char*) nmem_malloc (m, len); - strcpy (p->name, wrbuf_buf(wrbuf)); + p->name = nmem_strdup (m, wrbuf_cstr(wrbuf)); if (c == '=') { c = ampr (get_byte, fh, amp); @@ -656,10 +646,7 @@ data1_xattr *data1_read_xattr (data1_handle dh, NMEM m, c = ampr (get_byte, fh, amp); } } - wrbuf_putc (wrbuf, '\0'); - len = wrbuf_len(wrbuf); - p->value = (char*) nmem_malloc (m, len); - strcpy (p->value, wrbuf_buf(wrbuf)); + p->value = nmem_strdup(m, wrbuf_cstr(wrbuf)); } } *ch = c; @@ -689,8 +676,7 @@ data1_node *data1_read_nodex (data1_handle dh, NMEM m, { data1_xattr *xattr; - char tag[64]; - char args[256]; + char tag[256]; int null_tag = 0; int end_tag = 0; size_t i = 0; @@ -701,6 +687,33 @@ data1_node *data1_read_nodex (data1_handle dh, NMEM m, end_tag = 1; c = ampr (get_byte, fh, &); } + else if (amp == 0 && c == '?') + { + int quote_mode = 0; + while ((c = ampr(get_byte, fh, &))) + { + if (amp) + continue; + if (quote_mode == 0) + { + if (c == '"') + quote_mode = c; + else if (c == '\'') + quote_mode = c; + else if (c == '>') + { + c = ampr(get_byte, fh, &); + break; + } + } + else + { + if (amp == 0 && c == quote_mode) + quote_mode = 0; + } + } + continue; + } else if (amp == 0 && c == '!') { int c0, amp0; @@ -768,7 +781,6 @@ data1_node *data1_read_nodex (data1_handle dh, NMEM m, } tag[i] = '\0'; xattr = data1_read_xattr (dh, m, get_byte, fh, wrbuf, &c, &); - args[0] = '\0'; if (amp == 0 && c == '/') { /* or */ null_tag = 1; @@ -776,7 +788,7 @@ data1_node *data1_read_nodex (data1_handle dh, NMEM m, } if (amp || c != '>') { - yaz_log(LOG_WARN, "d1: %d: Malformed tag", line); + yaz_log(YLOG_WARN, "d1: %d: Malformed tag", line); return 0; } else @@ -804,7 +816,7 @@ data1_node *data1_read_nodex (data1_handle dh, NMEM m, } if (i != level) { - yaz_log (LOG_WARN, "%d: no begin tag for %s", + yaz_log (YLOG_WARN, "%d: no begin tag for %s", line, tag); break; } @@ -821,17 +833,20 @@ data1_node *data1_read_nodex (data1_handle dh, NMEM m, } continue; } - else if (!strcmp(tag, "var")) + else if (!strcmp(tag, "var") + && xattr && xattr->next && xattr->next->next + && xattr->value == 0 + && xattr->next->value == 0 + && xattr->next->next->value == 0) { - char tclass[DATA1_MAX_SYMBOL], type[DATA1_MAX_SYMBOL]; + /* */ + const char *tclass = xattr->name; + const char *type = xattr->next->name; + const char *value = xattr->next->name; data1_vartype *tp; - int val_offset; - if (sscanf(args, "%s %s %n", tclass, type, &val_offset) != 2) - { - yaz_log(LOG_WARN, "Malformed variant triple at '%s'", tag); - continue; - } + yaz_log(YLOG_LOG, "Variant class=%s type=%s value=%s", + tclass, type, value); if (!(tp = data1_getvartypebyct(dh, parent->root->u.root.absyn->varset, @@ -861,7 +876,7 @@ data1_node *data1_read_nodex (data1_handle dh, NMEM m, res = data1_mk_node2 (dh, m, DATA1N_variant, parent); res->u.variant.type = tp; res->u.variant.value = - data1_insert_string (dh, res, m, args + val_offset); + data1_insert_string (dh, res, m, value); } } else @@ -944,7 +959,7 @@ data1_node *data1_read_node (data1_handle dh, const char **buf, NMEM m) data1_node *node; node = data1_read_nodex(dh, m, getc_mem, (void *) (buf), wrbuf); - wrbuf_free (wrbuf, 1); + wrbuf_destroy(wrbuf); return node; } @@ -989,34 +1004,12 @@ data1_node *data1_read_sgml (data1_handle dh, NMEM m, const char *buf) } -static int conv_item (NMEM m, yaz_iconv_t t, - WRBUF wrbuf, char *inbuf, size_t inlen) +static int conv_item(NMEM m, yaz_iconv_t t, + WRBUF wrbuf, char *inbuf, size_t inlen) { - wrbuf_rewind (wrbuf); - if (wrbuf->size < 10) - wrbuf_grow (wrbuf, 10); - for (;;) - { - char *outbuf = wrbuf->buf + wrbuf->pos; - size_t outlen = wrbuf->size - wrbuf->pos; - if (yaz_iconv (t, &inbuf, &inlen, &outbuf, &outlen) == - (size_t)(-1) && yaz_iconv_error(t) != YAZ_ICONV_E2BIG) - { - /* bad data. stop and skip conversion entirely */ - return -1; - } - else if (inlen == 0) - { /* finished converting */ - wrbuf->pos = wrbuf->size - outlen; - break; - } - else - { - /* buffer too small: make sure we expand buffer */ - wrbuf->pos = wrbuf->size - outlen; - wrbuf_grow(wrbuf, 20); - } - } + wrbuf_rewind(wrbuf); + wrbuf_iconv_write(wrbuf, t, inbuf, inlen); + wrbuf_iconv_reset(wrbuf, t); return 0; } @@ -1054,8 +1047,7 @@ static void data1_iconv_s (data1_handle dh, NMEM m, data1_node *n, conv_item(m, t, wrbuf, p->value, strlen(p->value)) == 0) { - wrbuf_puts (wrbuf, ""); - p->value = nmem_strdup (m, wrbuf->buf); + p->value = nmem_strdup(m, wrbuf_cstr(wrbuf)); } } } @@ -1094,18 +1086,89 @@ const char *data1_get_encoding (data1_handle dh, data1_node *n) } int data1_iconv (data1_handle dh, NMEM m, data1_node *n, - const char *tocode, - const char *fromcode) + const char *tocode, + const char *fromcode) { if (yaz_matchstr (tocode, fromcode)) { WRBUF wrbuf = wrbuf_alloc(); - yaz_iconv_t t = yaz_iconv_open (tocode, fromcode); + yaz_iconv_t t = yaz_iconv_open(tocode, fromcode); if (!t) + { + wrbuf_destroy(wrbuf); return -1; - data1_iconv_s (dh, m, n, t, wrbuf, tocode); - yaz_iconv_close (t); - wrbuf_free (wrbuf, 1); + } + data1_iconv_s(dh, m, n, t, wrbuf, tocode); + yaz_iconv_close(t); + wrbuf_destroy(wrbuf); } return 0; } + +void data1_chop_text(data1_handle dh, NMEM m, data1_node *n) +{ + for (; n; n = n->next) + { + if (n->which == DATA1N_data) + { + + int sz = n->u.data.len; + const char *ndata = n->u.data.data; + int off = 0; + + for (off = 0; off < sz; off++) + if (!d1_isspace(ndata[off])) + break; + sz = sz - off; + ndata += off; + + while (sz && d1_isspace(ndata[sz - 1])) + sz--; + + n->u.data.data = nmem_malloc(m, sz); + n->u.data.len = sz; + memcpy(n->u.data.data, ndata, sz); + + } + data1_chop_text(dh, m, n->child); + } +} + +void data1_concat_text(data1_handle dh, NMEM m, data1_node *n) +{ + for (; n; n = n->next) + { + if (n->which == DATA1N_data && n->next && + n->next->which == DATA1N_data) + { + int sz = 0; + int off = 0; + char *ndata; + data1_node *np; + for (np = n; np && np->which == DATA1N_data; np=np->next) + sz += np->u.data.len; + ndata = nmem_malloc(m, sz); + for (np = n; np && np->which == DATA1N_data; np=np->next) + { + memcpy(ndata+off, np->u.data.data, np->u.data.len); + off += np->u.data.len; + } + n->u.data.data = ndata; + n->u.data.len = sz; + n->next = np; + if (!np && n->parent) + n->parent->last_child = n; + + } + data1_concat_text(dh, m, n->child); + } +} + +/* + * Local variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ +