cql_transform_t cql_transform_open_FILE(FILE *f) { cql_transform_t ct = cql_transform_create(); char line[1024]; yaz_tok_cfg_single_tokens(ct->tok_cfg, "="); while (fgets(line, sizeof(line)-1, f)) { yaz_tok_parse_t tp = yaz_tok_parse_buf(ct->tok_cfg, line); int t; wrbuf_rewind(ct->w); t = yaz_tok_move(tp); if (t == YAZ_TOK_STRING) { char * pattern = xstrdup(yaz_tok_parse_string(tp)); t = yaz_tok_move(tp); if (t != '=') { yaz_tok_parse_destroy(tp); cql_transform_close(ct); return 0; } if (cql_transform_parse_tok_line(ct, pattern, tp)) { yaz_tok_parse_destroy(tp); cql_transform_close(ct); return 0; } xfree(pattern); } else if (t != YAZ_TOK_EOF) { yaz_tok_parse_destroy(tp); cql_transform_close(ct); return 0; } yaz_tok_parse_destroy(tp); } return ct; }
static int cql_transform_parse_tok_line(cql_transform_t ct, const char *pattern, yaz_tok_parse_t tp) { int ae_num = 0; Z_AttributeElement *ae[20]; int ret = 0; /* 0=OK, != 0 FAIL */ int t; t = yaz_tok_move(tp); while (t == YAZ_TOK_STRING && ae_num < 20) { WRBUF type_str = wrbuf_alloc(); WRBUF set_str = 0; Z_AttributeElement *elem = 0; const char *value_str = 0; /* attset type=value OR type=value */ elem = (Z_AttributeElement *) nmem_malloc(ct->nmem, sizeof(*elem)); elem->attributeSet = 0; ae[ae_num] = elem; wrbuf_puts(ct->w, yaz_tok_parse_string(tp)); wrbuf_puts(type_str, yaz_tok_parse_string(tp)); t = yaz_tok_move(tp); if (t == YAZ_TOK_EOF) { wrbuf_destroy(type_str); if (set_str) wrbuf_destroy(set_str); break; } if (t == YAZ_TOK_STRING) { wrbuf_puts(ct->w, " "); wrbuf_puts(ct->w, yaz_tok_parse_string(tp)); set_str = type_str; elem->attributeSet = yaz_string_to_oid_nmem(yaz_oid_std(), CLASS_ATTSET, wrbuf_cstr(set_str), ct->nmem); type_str = wrbuf_alloc(); wrbuf_puts(type_str, yaz_tok_parse_string(tp)); t = yaz_tok_move(tp); } elem->attributeType = nmem_intdup(ct->nmem, 0); if (sscanf(wrbuf_cstr(type_str), ODR_INT_PRINTF, elem->attributeType) != 1) { wrbuf_destroy(type_str); if (set_str) wrbuf_destroy(set_str); yaz_log(YLOG_WARN, "Expected numeric attribute type"); ret = -1; break; } wrbuf_destroy(type_str); if (set_str) wrbuf_destroy(set_str); if (t != '=') { yaz_log(YLOG_WARN, "Expected = after after attribute type"); ret = -1; break; } t = yaz_tok_move(tp); if (t != YAZ_TOK_STRING) /* value */ { yaz_log(YLOG_WARN, "Missing attribute value"); ret = -1; break; } value_str = yaz_tok_parse_string(tp); if (yaz_isdigit(*value_str)) { elem->which = Z_AttributeValue_numeric; elem->value.numeric = nmem_intdup(ct->nmem, atoi(value_str)); } else { Z_ComplexAttribute *ca = (Z_ComplexAttribute *) nmem_malloc(ct->nmem, sizeof(*ca)); elem->which = Z_AttributeValue_complex; elem->value.complex = ca; ca->num_list = 1; ca->list = (Z_StringOrNumeric **) nmem_malloc(ct->nmem, sizeof(Z_StringOrNumeric *)); ca->list[0] = (Z_StringOrNumeric *) nmem_malloc(ct->nmem, sizeof(Z_StringOrNumeric)); ca->list[0]->which = Z_StringOrNumeric_string; ca->list[0]->u.string = nmem_strdup(ct->nmem, value_str); ca->num_semanticAction = 0; ca->semanticAction = 0; } wrbuf_puts(ct->w, "="); wrbuf_puts(ct->w, yaz_tok_parse_string(tp)); t = yaz_tok_move(tp); wrbuf_puts(ct->w, " "); ae_num++; } if (ret == 0) /* OK? */ { struct cql_prop_entry **pp = &ct->entry; while (*pp) pp = &(*pp)->next; *pp = (struct cql_prop_entry *) xmalloc(sizeof(**pp)); (*pp)->pattern = xstrdup(pattern); (*pp)->value = xstrdup(wrbuf_cstr(ct->w)); (*pp)->attr_list.num_attributes = ae_num; if (ae_num == 0) (*pp)->attr_list.attributes = 0; else { (*pp)->attr_list.attributes = (Z_AttributeElement **) nmem_malloc(ct->nmem, ae_num * sizeof(Z_AttributeElement *)); memcpy((*pp)->attr_list.attributes, ae, ae_num * sizeof(Z_AttributeElement *)); } (*pp)->next = 0; if (0) { ODR pr = odr_createmem(ODR_PRINT); Z_AttributeList *alp = &(*pp)->attr_list; odr_setprint(pr, yaz_log_file()); z_AttributeList(pr, &alp, 0, 0); odr_setprint(pr, 0); odr_destroy(pr); } } return ret; }
int ccl_qual_field2(CCL_bibset bibset, const char *cp, const char *qual_name, const char **addinfo) { yaz_tok_cfg_t yt = yaz_tok_cfg_create(); int type_ar[MAX_QUAL]; int value_ar[MAX_QUAL]; char *svalue_ar[MAX_QUAL]; char *attsets[MAX_QUAL]; int pair_no = 0; char *type_str = 0; int t; yaz_tok_parse_t tp; yaz_tok_cfg_single_tokens(yt, ",="); tp = yaz_tok_parse_buf(yt, cp); yaz_tok_cfg_destroy(yt); *addinfo = 0; t = yaz_tok_move(tp); while (t == YAZ_TOK_STRING) { /* we don't know what lead is yet */ char *lead_str = xstrdup(yaz_tok_parse_string(tp)); const char *value_str = 0; int type = 0, value = 0; /* indicates attribute value UNSET */ t = yaz_tok_move(tp); if (t == ',') { /* full attribute spec: set, type = value */ /* lead is attribute set */ attsets[pair_no] = lead_str; t = yaz_tok_move(tp); if (t != YAZ_TOK_STRING) { *addinfo = "token expected"; goto out; } xfree(type_str); type_str = xstrdup(yaz_tok_parse_string(tp)); if (yaz_tok_move(tp) != '=') { *addinfo = "= expected"; goto out; } } else if (t == '=') { /* lead is attribute type */ /* attribute set omitted: type = value */ attsets[pair_no] = 0; xfree(type_str); type_str = lead_str; } else { /* lead is first of a list of qualifier aliaeses */ /* qualifier alias: q1 q2 ... */ char *qlist[10]; size_t i = 0; qlist[i++] = lead_str; while (t == YAZ_TOK_STRING) { if (i < sizeof(qlist)/sizeof(*qlist)-1) qlist[i++] = xstrdup(yaz_tok_parse_string(tp)); t = yaz_tok_move(tp); } qlist[i] = 0; yaz_tok_parse_destroy(tp); ccl_qual_add_combi (bibset, qual_name, (const char **) qlist); for (i = 0; qlist[i]; i++) xfree(qlist[i]); return 0; } while (1) /* comma separated attribute value list */ { t = yaz_tok_move(tp); /* must have a value now */ if (t != YAZ_TOK_STRING) { *addinfo = "value token expected"; goto out; } value_str = yaz_tok_parse_string(tp); if (sscanf(type_str, "%d", &type) == 1) ; else if (strlen(type_str) != 1) { *addinfo = "bad attribute type"; goto out; } else { switch (*type_str) { case 'u': case 'U': type = CCL_BIB1_USE; break; case 'r': case 'R': type = CCL_BIB1_REL; if (!ccl_stricmp (value_str, "o")) value = CCL_BIB1_REL_ORDER; else if (!ccl_stricmp (value_str, "r")) value = CCL_BIB1_REL_PORDER; else if (!ccl_stricmp (value_str, "omiteq")) value = CCL_BIB1_REL_OMIT_EQUALS; break; case 'p': case 'P': type = CCL_BIB1_POS; break; case 's': case 'S': type = CCL_BIB1_STR; if (!ccl_stricmp (value_str, "pw")) value = CCL_BIB1_STR_WP; if (!ccl_stricmp (value_str, "al")) value = CCL_BIB1_STR_AND_LIST; if (!ccl_stricmp (value_str, "ol")) value = CCL_BIB1_STR_OR_LIST; if (!ccl_stricmp (value_str, "ag")) value = CCL_BIB1_STR_AUTO_GROUP; if (!ccl_stricmp (value_str, "sl")) value = CCL_BIB1_STR_SPLIT_LIST; break; case 't': case 'T': type = CCL_BIB1_TRU; if (!ccl_stricmp (value_str, "l")) value = CCL_BIB1_TRU_CAN_LEFT; else if (!ccl_stricmp (value_str, "r")) value = CCL_BIB1_TRU_CAN_RIGHT; else if (!ccl_stricmp (value_str, "b")) value = CCL_BIB1_TRU_CAN_BOTH; else if (!ccl_stricmp (value_str, "n")) value = CCL_BIB1_TRU_CAN_NONE; else if (!ccl_stricmp (value_str, "x")) value = CCL_BIB1_TRU_CAN_REGEX; else if (!ccl_stricmp (value_str, "z")) value = CCL_BIB1_TRU_CAN_Z3958; break; case 'c': case 'C': type = CCL_BIB1_COM; break; } } if (type == 0) { /* type was not set in switch above */ *addinfo = "bad attribute type"; goto out; } type_ar[pair_no] = type; if (value) { value_ar[pair_no] = value; svalue_ar[pair_no] = 0; } else if (*value_str >= '0' && *value_str <= '9') { value_ar[pair_no] = atoi (value_str); svalue_ar[pair_no] = 0; } else { value_ar[pair_no] = 0; svalue_ar[pair_no] = xstrdup(value_str); } pair_no++; if (pair_no == MAX_QUAL) { *addinfo = "too many attribute values"; goto out; } t = yaz_tok_move(tp); if (t != ',') break; attsets[pair_no] = attsets[pair_no-1]; } } out: xfree(type_str); type_str = 0; yaz_tok_parse_destroy(tp); if (*addinfo) { int i; for (i = 0; i<pair_no; i++) { xfree(attsets[i]); xfree(svalue_ar[i]); } return -1; } ccl_qual_add_set(bibset, qual_name, pair_no, type_ar, value_ar, svalue_ar, attsets); return 0; }