* Europagate, 1995
*
* $Log: cclfind.c,v $
- * Revision 1.9 1997-09-29 08:56:37 adam
+ * Revision 1.15 2000-02-24 23:49:13 adam
+ * Fixed memory allocation problem.
+ *
+ * Revision 1.14 2000/01/31 13:15:21 adam
+ * Removed uses of assert(3). Cleanup of ODR. CCL parser update so
+ * that some characters are not surrounded by spaces in resulting term.
+ * ILL-code updates.
+ *
+ * Revision 1.13 1999/12/22 13:13:32 adam
+ * Search terms may include "operators" without causing error.
+ *
+ * Revision 1.12 1999/11/30 13:47:11 adam
+ * Improved installation. Moved header files to include/yaz.
+ *
+ * Revision 1.11 1999/03/31 11:15:37 adam
+ * Fixed memory leaks in ccl_find_str and ccl_qual_rm.
+ *
+ * Revision 1.10 1998/02/11 11:53:33 adam
+ * Changed code so that it compiles as C++.
+ *
+ * Revision 1.9 1997/09/29 08:56:37 adam
* Changed CCL parser to be thread safe. New type, CCL_parser, declared
* and a create/destructers ccl_parser_create/ccl_parser/destory has
* been added.
#include <stdio.h>
#include <stdlib.h>
-#include <assert.h>
#include <string.h>
-#include <ccl.h>
+#include <yaz/ccl.h>
/* returns type of current lookahead */
#define KIND (cclp->look_token->kind)
*/
static char *copy_token_name (struct ccl_token *tp)
{
- char *str = malloc (tp->len + 1);
- assert (str);
+ char *str = (char *)malloc (tp->len + 1);
+ ccl_assert (str);
memcpy (str, tp->name, tp->len);
str[tp->len] = '\0';
return str;
static struct ccl_rpn_node *mk_node (int kind)
{
struct ccl_rpn_node *p;
- p = malloc (sizeof(*p));
- assert (p);
+ p = (struct ccl_rpn_node *)malloc (sizeof(*p));
+ ccl_assert (p);
p->kind = kind;
return p;
}
static struct ccl_rpn_node *find_spec (CCL_parser cclp,
struct ccl_rpn_attr **qa);
+
+static int is_term_ok (int look, int *list)
+{
+ for (;*list >= 0; list++)
+ if (look == *list)
+ return 1;
+ return 0;
+}
+
static struct ccl_rpn_node *search_terms (CCL_parser cclp,
struct ccl_rpn_attr **qa);
{
struct ccl_rpn_attr *n;
- n = malloc (sizeof(*n));
- assert (n);
+ n = (struct ccl_rpn_attr *)malloc (sizeof(*n));
+ ccl_assert (n);
n->type = type;
n->value = value;
n->next = p->u.t.attr_list;
* qa: Qualifier attributes already applied.
* return: pointer to node(s); NULL on error.
*/
-static struct ccl_rpn_node *search_term (CCL_parser cclp,
- struct ccl_rpn_attr **qa)
+static struct ccl_rpn_node *search_term_x (CCL_parser cclp,
+ struct ccl_rpn_attr **qa,
+ int *term_list)
{
+ struct ccl_rpn_attr *qa_tmp[2];
struct ccl_rpn_node *p;
struct ccl_token *lookahead = cclp->look_token;
int len = 0;
int truncation_value = -1;
int completeness_value = -1;
- if (KIND != CCL_TOK_TERM)
+ if (!is_term_ok(KIND, term_list))
{
cclp->error_code = CCL_ERR_TERM_EXPECTED;
return NULL;
{
/* no qualifier(s) applied. Use 'term' if it is defined */
- qa = malloc (2*sizeof(*qa));
- assert (qa);
+ qa = qa_tmp;
+ ccl_assert (qa);
qa[0] = ccl_qual_search (cclp, "term", 4);
qa[1] = NULL;
}
/* go through each TERM token. If no truncation attribute is yet
met, then look for left/right truncation markers (?) and
set left_trunc/right_trunc/mid_trunc accordingly */
- for (no = 0; lookahead->kind == CCL_TOK_TERM; no++)
+ for (no = 0; is_term_ok(lookahead->kind, term_list); no++)
{
for (i = 0; i<lookahead->len; i++)
if (truncation_value == -1 && lookahead->name[i] == '?')
{
if (no == 0 && i == 0 && lookahead->len >= 1)
left_trunc = 1;
- else if (lookahead->next->kind != CCL_TOK_TERM &&
+ else if (!is_term_ok(lookahead->next->kind, term_list) &&
i == lookahead->len-1 && i >= 1)
right_trunc = 1;
else
}
/* make the RPN token */
- p->u.t.term = malloc (len);
- assert (p->u.t.term);
+ p->u.t.term = (char *)malloc (len);
+ ccl_assert (p->u.t.term);
p->u.t.term[0] = '\0';
for (i = 0; i<no; i++)
{
}
else if (i == no-1 && right_trunc)
src_len--;
- if (i)
- strcat (p->u.t.term, " ");
+ if (src_len)
+ {
+ int len = strlen(p->u.t.term);
+ if (len &&
+ !strchr("-+", *src_str) &&
+ !strchr("-+", p->u.t.term[len-1]))
+ {
+ strcat (p->u.t.term, " ");
+ }
+ }
strxcat (p->u.t.term, src_str, src_len);
ADVANCE;
}
if (!qual_val_type (qa, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_BOTH))
{
cclp->error_code = CCL_ERR_TRUNC_NOT_BOTH;
- free (qa);
ccl_rpn_delete (p);
return NULL;
}
if (!qual_val_type (qa, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_RIGHT))
{
cclp->error_code = CCL_ERR_TRUNC_NOT_RIGHT;
- free (qa);
ccl_rpn_delete (p);
return NULL;
}
if (!qual_val_type (qa, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_LEFT))
{
cclp->error_code = CCL_ERR_TRUNC_NOT_LEFT;
- free (qa);
ccl_rpn_delete (p);
return NULL;
}
return p;
}
+static struct ccl_rpn_node *search_term (CCL_parser cclp,
+ struct ccl_rpn_attr **qa)
+{
+ static int list[] = {CCL_TOK_TERM, CCL_TOK_COMMA, -1};
+ return search_term_x(cclp, qa, list);
+}
+
/*
* qualifiers: Parse CCL qualifiers and search terms.
* cclp: CCL Parser
if (qa)
for (i=0; qa[i]; i++)
no++;
- ap = malloc ((no+1) * sizeof(*ap));
- assert (ap);
+ ap = (struct ccl_rpn_attr **)malloc ((no+1) * sizeof(*ap));
+ ccl_assert (ap);
for (i = 0; cclp->look_token != la; i++)
{
ap[i] = ccl_qual_search (cclp, cclp->look_token->name,
free (ap);
return p;
}
+ /* ordered relation ... */
rel = 0;
if (cclp->look_token->len == 1)
{
static struct ccl_rpn_node *search_terms (CCL_parser cclp,
struct ccl_rpn_attr **qa)
{
+ static int list[] = {
+ CCL_TOK_TERM, CCL_TOK_COMMA,CCL_TOK_EQ,
+ CCL_TOK_REL, CCL_TOK_MINUS, -1};
struct ccl_rpn_node *p1, *p2, *pn;
- p1 = search_term (cclp, qa);
+ p1 = search_term_x (cclp, qa, list);
if (!p1)
return NULL;
while (1)
if (KIND == CCL_TOK_PROX)
{
ADVANCE;
- p2 = search_term (cclp, qa);
+ p2 = search_term_x (cclp, qa, list);
if (!p2)
{
ccl_rpn_delete (p1);
pn->u.p[1] = p2;
p1 = pn;
}
- else if (KIND == CCL_TOK_TERM)
+ else if (is_term_ok(KIND, list))
{
- p2 = search_term (cclp, qa);
+ p2 = search_term_x (cclp, qa, list);
if (!p2)
{
ccl_rpn_delete (p1);
if (*error)
*pos = cclp->error_pos - str;
ccl_parser_destroy (cclp);
+ ccl_token_del (list);
return p;
}