* Europagate, 1995
*
* $Log: cclfind.c,v $
- * Revision 1.1 1995/02/13 12:35:20 adam
+ * Revision 1.2 1995/02/13 15:15:07 adam
+ * Added handling of qualifiers. Not finished yet.
+ *
+ * Revision 1.1 1995/02/13 12:35:20 adam
* First version of CCL. Qualifiers aren't handled yet.
*
*/
static struct ccl_token *look_token;
static int ccl_error;
+static CCL_bibset bibset;
#define KIND (look_token->kind)
#define ADVANCE look_token = look_token->next
static char *copy_token_name (struct ccl_token *tp)
{
char *str = malloc (tp->len + 1);
+ assert (str);
memcpy (str, tp->name, tp->len);
str[tp->len] = '\0';
return str;
void ccl_rpn_delete (struct ccl_rpn_node *rpn)
{
+ struct ccl_rpn_attr *attr, *attr1;
if (!rpn)
return;
switch (rpn->kind)
break;
case TERM:
free (rpn->u.t.term);
- /* attr list */
+ for (attr = rpn->u.t.attr_list; attr; attr = attr1)
+ {
+ attr1 = attr->next;
+ free (attr);
+ }
break;
case SET:
free (rpn->u.setname);
free (rpn);
}
-static struct ccl_rpn_node *find_spec (void);
+static struct ccl_rpn_node *find_spec (struct ccl_qualifier **qa);
+static struct ccl_rpn_node *search_terms (struct ccl_qualifier **qa);
+
+static void add_attr (struct ccl_rpn_node *p, int type, int value)
+{
+ struct ccl_rpn_attr *n;
+
+ n = malloc (sizeof(*n));
+ assert (n);
+ n->type = type;
+ n->value = value;
+ n->next = p->u.t.attr_list;
+ p->u.t.attr_list = n;
+}
-static struct ccl_rpn_node *search_term (void)
+static struct ccl_rpn_node *search_term (struct ccl_qualifier **qa)
{
struct ccl_rpn_node *p;
struct ccl_token *lookahead = look_token;
int len = 0;
+ int no = 0;
if (KIND != CCL_TOK_TERM)
{
}
while (lookahead->kind == CCL_TOK_TERM)
{
+ no++;
len += 1+lookahead->len;
lookahead = lookahead->next;
}
strxcat (p->u.t.term, look_token->name, look_token->len);
ADVANCE;
}
+ if (qa)
+ {
+ int i;
+ /* use ... */
+ for (i=0; qa[i]; i++)
+ {
+ int j;
+ for (j=0; j<qa[i]->nuse; j++)
+ add_attr (p, 1, qa[i]->use[j]);
+ }
+ /* structure ... */
+ if (qa[0]->structure == 0)
+ {
+ if (no == 1)
+ add_attr (p, 4, 2);
+ else
+ add_attr (p, 4, 1);
+ }
+ else if (qa[0]->structure > 0)
+ add_attr (p, 4, qa[0]->structure);
+ }
return p;
}
-static struct ccl_rpn_node *qualifiers (struct ccl_token *la)
+static struct ccl_rpn_node *qualifiers (struct ccl_token *la,
+ struct ccl_qualifier **qa)
{
+ struct ccl_token *lookahead = look_token;
+ struct ccl_qualifier **ap;
+ int no = 1;
+ int i;
+
+ if (qa)
+ {
+ ccl_error = CCL_ERR_DOBBLE_QUAL;
+ return NULL;
+ }
+ for (lookahead = look_token; lookahead != la; lookahead=lookahead->next)
+ no++;
+ ap = malloc (no * sizeof(*ap));
+ assert (ap);
+ for (i=0; look_token != la; i++)
+ {
+ ap[i] = ccl_qual_search (bibset, lookahead->name);
+ if (!ap[i])
+ {
+ ccl_error = CCL_ERR_UNKNOWN_QUAL;
+ free (ap);
+ return NULL;
+ }
+ ADVANCE;
+ if (KIND == CCL_TOK_COMMA)
+ ADVANCE;
+ }
+ ap[i] = NULL;
+ if (ap[0]->relation != 0)
+ {
+ /* unordered relation */
+ struct ccl_rpn_node *p;
+ if (KIND != CCL_TOK_EQ)
+ {
+ ccl_error = CCL_ERR_EQ_EXPECTED;
+ free (ap);
+ return NULL;
+ }
+ ADVANCE;
+ if (KIND == CCL_TOK_LP)
+ {
+ ADVANCE;
+ if (!(p = find_spec (ap)))
+ {
+ free (ap);
+ return NULL;
+ }
+ if (KIND != CCL_TOK_RP)
+ {
+ ccl_error = CCL_ERR_RP_EXPECTED;
+ ccl_rpn_delete (p);
+ free (ap);
+ return NULL;
+ }
+ ADVANCE;
+ }
+ else
+ p = search_terms (ap);
+ free (ap);
+ return p;
+ }
+ /* ordered relation ... */
assert (0);
+ free (ap);
return NULL;
}
-static struct ccl_rpn_node *search_terms (void)
+static struct ccl_rpn_node *search_terms (struct ccl_qualifier **qa)
{
struct ccl_rpn_node *p1, *p2, *pn;
- p1 = search_term ();
+ p1 = search_term (qa);
if (!p1)
return NULL;
while (1)
if (KIND == CCL_TOK_PROX)
{
ADVANCE;
- p2 = search_term ();
+ p2 = search_term (qa);
if (!p2)
{
ccl_rpn_delete (p1);
}
else if (KIND == CCL_TOK_TERM)
{
- p2 = search_term ();
+ p2 = search_term (qa);
if (!p2)
{
ccl_rpn_delete (p1);
return p1;
}
-static struct ccl_rpn_node *search_elements (void)
+static struct ccl_rpn_node *search_elements (struct ccl_qualifier **qa)
{
struct ccl_rpn_node *p1;
struct ccl_token *lookahead;
if (KIND == CCL_TOK_LP)
{
ADVANCE;
- p1 = find_spec ();
+ p1 = find_spec (qa);
if (!p1)
return NULL;
if (KIND != CCL_TOK_RP)
while (lookahead->kind==CCL_TOK_TERM || lookahead->kind==CCL_TOK_COMMA)
lookahead = lookahead->next;
if (lookahead->kind == CCL_TOK_REL || lookahead->kind == CCL_TOK_EQ)
- return qualifiers (lookahead);
- return search_terms ();
+ return qualifiers (lookahead, qa);
+ return search_terms (qa);
}
-static struct ccl_rpn_node *find_spec (void)
+static struct ccl_rpn_node *find_spec (struct ccl_qualifier **qa)
{
struct ccl_rpn_node *p1, *p2, *pn;
- if (!(p1 = search_elements ()))
+ if (!(p1 = search_elements (qa)))
return NULL;
while (1)
{
{
case CCL_TOK_AND:
ADVANCE;
- p2 = search_elements ();
+ p2 = search_elements (qa);
if (!p2)
{
ccl_rpn_delete (p1);
continue;
case CCL_TOK_OR:
ADVANCE;
- p2 = search_elements ();
+ p2 = search_elements (qa);
if (!p2)
{
ccl_rpn_delete (p1);
continue;
case CCL_TOK_NOT:
ADVANCE;
- p2 = search_elements ();
+ p2 = search_elements (qa);
if (!p2)
{
ccl_rpn_delete (p1);
return p1;
}
-struct ccl_rpn_node *ccl_find (struct ccl_token *list,
+struct ccl_rpn_node *ccl_find (CCL_bibset abibset, struct ccl_token *list,
int *error, const char **pos)
{
struct ccl_rpn_node *p;
look_token = list;
- p = find_spec ();
+ bibset = abibset;
+ p = find_spec (NULL);
if (p && KIND != CCL_TOK_EOL)
{
if (KIND == CCL_TOK_RP)
static void pr_tree (struct ccl_rpn_node *rpn)
{
+
switch (rpn->kind)
{
case TERM:
printf ("\"%s\"", rpn->u.t.term);
+ if (rpn->u.t.attr_list)
+ {
+ struct ccl_rpn_attr *attr;
+ printf ("[ ");
+ for (attr = rpn->u.t.attr_list; attr; attr = attr->next)
+ printf ("%d=%d ", attr->type, attr->value);
+ printf ("] ");
+ }
break;
case AND:
printf ("(");
}
}
-void ccl_find_str (const char *str, int *error, int *pos)
+struct ccl_rpn_node *ccl_find_str (CCL_bibset bibset, const char *str,
+ int *error, int *pos)
{
struct ccl_token *list, *li;
struct ccl_rpn_node *rpn;
for (li = list; li; li = li->next)
printf ("kind=%d, str='%.*s'\n", li->kind, li->len, li->name);
#endif
- rpn = ccl_find (list, error, &char_pos);
+ rpn = ccl_find (bibset, list, error, &char_pos);
if (! *error)
{
pr_tree (rpn);
{
*pos = char_pos - str;
}
+ return rpn;
}