Beispiel #1
0
/*! Create a new vector, initialize the first element to the contents of 'var'
 *
 * @param[in] var      cg_var to clone and add to vector
 * @retval    cvec     allocated cvec
 */
cvec *
cvec_from_var(cg_var *cv)
{
    cvec   *newvec = NULL;
    cg_var *tail = NULL;

    if (cv && (newvec = cvec_new(0))) {
        if ((tail = cvec_append_var(newvec, cv)) == NULL) {
            cvec_free(newvec);
            newvec = NULL;
        }
    }
    return newvec;
}
Beispiel #2
0
/*! Recursively copy callback structure to all terminal nodes in the parse-tree.
 * XXX: Actually copies to every node, even if not terminal
 * Problem is that the argument is modified according to reference rule
 * @param[in]  pt   Parse-tree
 * @param[in]  cc0  This is the parameter (calling) callback. eg fn in @sub,fn().
 *
 * The function installs the calling callback in all executable non-terminal nodes.
 * That is, it only install callbacks in non-terminal with NULL child which is 
 * where a ';' is in the syntax, eg:
 *	   a ;{} # Here a is executable
 *	   b {}  # But b is not
 * Somewhat strange semantics though:
 * - Always replace (or add if empty) original callback in co0
 * - Use local argument-list _unless_ there is none, then use callback list from cc0
 */
static int
pt_callback_reference(parse_tree          pt, 
		      struct cg_callback *cc0)
{
    int                 i;
    cg_obj             *co;
    parse_tree         *ptc;
    int                 retval = -1;
    struct cg_callback *cc;
    cg_var             *cv;
		    
    for (i=0; i<pt.pt_len; i++){    
	if ((co = pt.pt_vec[i]) == NULL)
	    continue;
	ptc = &co->co_pt;
	/* Filter out non-executable non-terminals. */
	if (ptc->pt_len && ptc->pt_vec[0] == NULL){
	    /* Copy the callback from top */
	    if ((cc = co->co_callbacks) == NULL){
		if (co_callback_copy(cc0, &co->co_callbacks) < 0)
		    return -1;
	    }
	    else {
#ifdef CALLBACK_SINGLEARG
		cc->cc_fn = cc0->cc_fn; /* iterate */
#endif
		cc->cc_fn_vec = cc0->cc_fn_vec; /*  */
		if (cc0->cc_fn_str){
		    if (cc->cc_fn_str)
			free (cc->cc_fn_str);
		    cc->cc_fn_str = strdup(cc0->cc_fn_str);
		}
		/* Append original parameters to end of call */
		if (cc0->cc_cvec){
		    cv = NULL;
		    while ((cv = cvec_each(cc0->cc_cvec, cv)) != NULL)
			cvec_append_var(cc->cc_cvec, cv);
		}
		
	    }
	}
	if (pt_callback_reference(co->co_pt, cc0) < 0)
	    goto done;
    }
    retval = 0;
  done:
    return retval;
}