Example #1
0
static void
tr_find_parent(
    Element_t	*e,
    Descent_t	*ds
)
{
    if (QRelation(e, ds->gi, REL_Parent)) {
	if (ds->action[0]) TranTByAction(e, ds->action, ds->fp);
    }
}
Example #2
0
int
CheckRelation(
    Element_t	*e,
    char	*relname,	/* relationship name */
    char	*related,	/* related element */
    char	*actname,	/* action to take */
    FILE	*fp,
    RelAction_t	flag
)
{
    Element_t	*ep;
    Relation_t	r;

    if ((r = FindRelByName(relname)) == REL_Unknown) return 0;
    if (!(ep=QRelation(e, related, r)))	return 0;

    if (!actname) return 1;		/* no action - return what we found */

    switch (flag) {
	case RA_Related:	TranByAction(ep, atoi(actname), fp);	break;
	case RA_Current:	TranByAction(e, atoi(actname), fp);	break;
    }
    return 1;
}
Example #3
0
Trans_t *
FindTrans(
    Element_t	*e
)
{
    char	context[LINESIZE], *cp, **vec, *atval;
    int		i, a, match;
    Trans_t	*t, *tt;

    /* loop through all transpecs */
    for (t=TrSpecs; t; t=t->next)
    {
	/* Only one of gi or gilist will be set. */
	/* Check if elem name matches */
	if (t->gi && !StrEq(t->gi, e->gi)) continue;

	/* Match one in the list of GIs? */
	if (t->gilist) {
	    for (match=0,vec=t->gilist; *vec; vec++) {
		if (StrEq(*vec, e->gi)) {
		    match = 1;
		    break;
		}
	    }
	    if (!match) continue;
	}

	/* Check context */

	/* Special case of context */
	if (t->parent)
	    if (!QRelation(e, t->parent, REL_Parent)) continue;

	if (t->context) {	/* no context specified -> a match */
	    FindContext(e, t->depth, context);

	    /* If reg expr set, do regex compare; else just string compare. */
	    if (t->context_re) {
		if (! tpt_regexec(t->context_re, context)) continue;
	    }
	    else {
		/* Is depth of spec deeper than element's depth? */
		if (t->depth > e->depth) continue;

		/* See if context of element matches "context" of transpec */
		match = ( (t->context[0] == context[0]) &&
			    !strcmp(t->context, context) );
		if (!match) continue;
	    }
	}

	/* Check attributes.  Loop through list, comparing each. */
	if (t->nattpairs) {	/* no att specified -> a match */
	    for (match=1,a=0; a<t->nattpairs; a++) {
		if (!(atval = FindAttValByName(e, t->attpair[a].name))) {
		    match = 0;
		    break;
		}
		if (!tpt_regexec(t->attpair[a].rex, atval)) match = 0;
	    }
	    if (!match) continue;
	}

	/* Check relationships:  child, parent, ancestor, sib, ...  */
	if (t->relations) {
	    Mapping_t *r;
	    match = 1;
	    for (r=t->relations->maps,i=0; i<t->relations->n_used; i++) {
		if (!CheckRelation(e, r[i].name, r[i].sval, 0, 0, RA_Current)) {
		    match = 0;
		    break;
		}
	    }
	    if (!match) continue;
	}

	/* check this element's parent's attribute */
	if (t->pattrset && e->parent) {
	    char *p, **tok;

	    i = 2;
	    match = 1;
	    tok = Split(t->pattrset, &i, S_STRDUP);
	    if ( i == 2 ) {
		p = FindAttValByName(e->parent, tok[0]);
		if ( !p || strcmp(p, tok[1]) )
		    match = 0;
	    } else {
		if (!FindAttValByName(e->parent, t->pattrset))
		    match = 0;
	    }
	    free(tok[0]);
	    if (!match) continue;
	}

	/* check this element's "birth order" */
	if (t->nth_child) {
	    /* First one is called "1" by the user.  Internally called "0". */
	    i = t->nth_child;
	    if (i > 0) {	/* positive # -- count from beginning */
		if (e->my_eorder != (i-1)) continue;
	    }
	    else {		/* negative # -- count from end */
		i = e->parent->necont + i;
		if (e->my_eorder != i) continue;
	    }
	}

	/* check that variables match */
	if (t->var_name) {
	    cp = FindMappingVal(Variables, t->var_name);
	    if (!cp || strcmp(cp, t->var_value)) continue;
	}

	/* check content */
	if (t->content) {		/* no att specified -> a match */
	    for (match=0,i=0; i<e->ndcont; i++) {
		if (tpt_regexec(t->content_re, e->dcont[i])) {
		    match = 1;
		    break;
		}
	    }
	    if (!match) continue;
	}

	/* -------- at this point we've passed all criteria -------- */

	/* See if we should be using another transpec's actions. */
	if (t->use_id) {
	    if (t->use_id < 0) return &NullTrans;	/* missing? */
	    /* see if we have a pointer to that transpec */
	    if (t->use_trans) return t->use_trans;
	    for (tt=TrSpecs; tt; tt=tt->next) {
		if (t->use_id == tt->my_id) {
		    /* remember pointer for next time */
		    t->use_trans = tt;
		    return t->use_trans;
		}
	    }
	    t->use_id = -1;	/* flag it as missing */
	    fprintf(stderr, "Warning: transpec ID (%d) not found for %s.\n",
		t->use_id, e->gi);
	    return &NullTrans;
	}

	return t;
    }

    /* At this point, we have not found a matching spec.  See if there
     * is a wildcard, and if so, use it. (Wildcard GI is named "*".) */
    if ((t = FindTransByName("*"))) return t;

    if (warnings)
	fprintf(stderr, "Warning: transpec not found for %s\n", e->gi);

    /* default spec - pass character data and descend node */
    return &NullTrans;
}