Exemple #1
0
/* compare:
 * Lexicographic ordering of objects.
 */
int compare(Agobj_t * l, Agobj_t * r)
{
    char lkind, rkind;
    if (l == NULL) {
	if (r == NULL)
	    return 0;
	else
	    return -1;
    } else if (r == NULL) {
	return 1;
    }
    if (AGID(l) < AGID(r))
	return -1;
    else if (AGID(l) > AGID(r))
	return 1;
    lkind = AGTYPE(l);
    rkind = AGTYPE(r);
    if (lkind == 3)
	lkind = 2;
    if (rkind == 3)
	rkind = 2;
    if (lkind == rkind)
	return 0;
    else if (lkind < rkind)
	return -1;
    else
	return 1;
}
Exemple #2
0
/* external entry point (this seems to be one of those ineffective
 * comments censured in books on programming style) */
int agapply(Agraph_t * g, Agobj_t * obj, agobjfn_t fn, void *arg,
	    int preorder)
{
    Agobj_t *subobj;

    agobjsearchfn_t objsearch;
    switch (AGTYPE(obj)) {
    case AGRAPH:
	objsearch = subgraph_search;
	break;
    case AGNODE:
	objsearch = subnode_search;
	break;
    case AGOUTEDGE:
    case AGINEDGE:
	objsearch = subedge_search;
	break;
    default:
	agerr(AGERR, "agapply: unknown object type %d\n", AGTYPE(obj));
	return FAILURE;
	break;
    }
    if ((subobj = objsearch(g, obj))) {
	rec_apply(g, subobj, fn, arg, objsearch, preorder);
	return SUCCESS;
    } else
	return FAILURE;
}
Exemple #3
0
/* copyAttr:
 * Copy attributes from src to tgt. Overrides currently
 * defined values.
 * FIX: we should probably use the default value of the source
 * graph when initializing the attribute, rather than "".
 * NOTE: We do not assume src and tgt have the same kind.
 */
int copyAttr(Agobj_t * src, Agobj_t * tgt)
{
    Agraph_t *srcg;
    Agraph_t *tgtg;
    Agsym_t *sym = 0;
    Agsym_t *tsym = 0;
    int skind = AGTYPE(src);
    int tkind = AGTYPE(tgt);
    char* val;

    srcg = agraphof(src);
    tgtg = agraphof(tgt);
    while ((sym = agnxtattr(srcg, skind, sym))) {
	tsym = agattrsym(tgt, sym->name);
	if (!tsym)
	    tsym = agattr(tgtg, tkind, sym->name, sym->defval);
	val = agxget(src, sym);
	if (aghtmlstr (val)) {
	    val = agstrdup_html (tgtg, val);
	    agxset(tgt, tsym, val);
	    agstrfree (tgtg, val);
	}
	else
	    agxset(tgt, tsym, val);
    }
    return 0;
}
Exemple #4
0
/*-------------------------------------------------------------------------*\
 * Generic method: type = obj.type(self)
 * Returns type of a graph object.
 * Returns the type as string: 'graph', 'node' or 'edge'.
 * Example:
 * type = n:type()
\*-------------------------------------------------------------------------*/
int get_object_type(lua_State *L)
{
  gr_object_t *ud = toobject(L, 1, NULL, STRICT);
  lua_pushstring(L, AGTYPE(ud->p.p) == AGGRAPH ? "graph" :
		 AGTYPE(ud->p.p) == AGNODE ? "node" :
		 AGTYPE(ud->p.p) == AGEDGE ? "edge" : "unkown");
  return 1;
}
Agedge_t *findedge(Agnode_t *t, Agnode_t *h)
{
    if (!t || !h)
        return NULL;
    if (AGTYPE(t) == AGRAPH || AGTYPE(h) == AGRAPH)
	return NULL;
    return agfindedge(agraphof(t), t, h);
}
Agedge_t *edge(Agnode_t *t, Agnode_t *h)
{
    if (!gvc || !t || !h)
        return NULL;
    // edges from/to the protonode are not permitted
    if (AGTYPE(t) == AGRAPH || AGTYPE(h) == AGRAPH)
	return NULL;
    return agedge(agraphof(t), t, h, NULL, 1);
}
Exemple #7
0
static void set_data(Agobj_t * obj, Agrec_t * data, int mtflock)
{
    Agedge_t *e;

    obj->data = data;
    obj->tag.mtflock = mtflock;
    if ((AGTYPE(obj) == AGINEDGE) || (AGTYPE(obj) == AGOUTEDGE)) {
	e = agopp((Agedge_t *) obj);
	AGDATA(e) = data;
	e->base.tag.mtflock = mtflock;
    }
}
Exemple #8
0
/* deleteObj:
 * Remove obj from g.
 * obj may belong to a subgraph of g, so we first must map
 * obj to its version in g.
 * If g is null, remove object from root graph.
 * If obj is a (sub)graph, close it. The g parameter is unused.
 * Return 0 on success, non-zero on failure.
 */
int deleteObj(Agraph_t * g, Agobj_t * obj)
{
    gdata *data;
    if (AGTYPE(obj) == AGRAPH) {
	g = (Agraph_t *) obj;
	if (g != agroot(g))
	    return agclose(g);
	data = gData(g);
	if (data->lock & 1) {
	    error(ERROR_WARNING, "Cannot delete locked graph %s",
		  agnameof(g));
	    data->lock |= 2;
	    return -1;
	} else
	    return agclose(g);
    }

    /* node or edge */
    if (!g)
	g = agroot(agraphof(obj));
    if (obj)
	return agdelete(g, obj);
    else
	return -1;
}
Agraph_t *graphof(Agedge_t *e)
{
    if (!e)
        return NULL;
    if (AGTYPE(e) == AGRAPH)
	return (Agraph_t*)e; /* graph of protoedge is itself recast */
    return agraphof(agtail(e));
}
//-------------------------------------------------
char *getv(Agnode_t *n, Agsym_t *a)
{
    if (!n || !a)
        return NULL;
    if (AGTYPE(n) == AGRAPH) // protonode   
	return NULL;   // FIXME ??
    return myagxget(n, a);
}
Agraph_t *graphof(Agnode_t *n)
{
    if (!n)
        return NULL;
    if (AGTYPE(n) == AGRAPH)
	return (Agraph_t*)n;  /* graph of protonode is itself recast */
    return agraphof(n);
}
Agnode_t *headof(Agedge_t *e)
{
    if (!e)
        return NULL;
    if (AGTYPE(e) == AGRAPH)
	return NULL;
    return aghead(e);
}
//-------------------------------------------------
char *getv(Agedge_t *e, Agsym_t *a)
{
    if (!e || !a)
        return NULL;
    if (AGTYPE(e) == AGRAPH) // protoedge   
	return NULL;   // FIXME ??
    return myagxget(e, a);
}
Agnode_t *tailof(Agedge_t *e)
{
    if (!e)
        return NULL;
    if (AGTYPE(e) == AGRAPH)
	return NULL;
    return agtail(e);
}
char *nameof(Agnode_t *n)
{
    if (!n)
        return NULL;
    if (AGTYPE(n) == AGRAPH)
	return NULL;
    return agnameof(n);
}
char *setv(Agedge_t *e, Agsym_t *a, char *val)
{
    if (!e || !a || !val)
        return NULL;
    if (AGTYPE(e) == AGRAPH) // protoedge   
	return NULL;   // FIXME ??
    myagxset(e, a, val);
    return val;
}
char *setv(Agnode_t *n, Agsym_t *a, char *val)
{
    if (!n || !a || !val)
        return NULL;
    if (AGTYPE(n) == AGRAPH) // protonode   
	return NULL;   // FIXME ??
    myagxset(n, a, val);
    return val;
}
Exemple #18
0
/* copyAttr;
 * Copy attributes from src to tgt. Overrides currently
 * defined values.
 * FIX: we should probably use the default value of the source
 * graph when initializing the attribute, rather than "".
 * NOTE: We do not assume src and tgt have the same kind.
 */
int copyAttr(Agobj_t * src, Agobj_t * tgt)
{
    Agraph_t *srcg;
    Agraph_t *tgtg;
    Agsym_t *sym = 0;
    Agsym_t *tsym = 0;
    int skind = AGTYPE(src);
    int tkind = AGTYPE(tgt);

    srcg = agraphof(src);
    tgtg = agraphof(tgt);
    while ((sym = agnxtattr(srcg, skind, sym))) {
	tsym = agattrsym(tgt, sym->name);
	if (!tsym)
	    tsym = agattr(tgtg, tkind, sym->name, "");
	agxset(tgt, tsym, agxget(src, sym));
    }
    return 0;
}
Exemple #19
0
static void my_ins(Agobj_t * obj, void *context)
{
    Agnode_t *n;

    if (AGTYPE(obj) == AGNODE) {
	n = (Agnode_t *) obj;
	fprintf(stderr, "%s initialized with label %s\n", agnameof(n),
		agget(n, "label"));
    }
}
Exemple #20
0
char *obj2cmd (void *obj) {
    static char buf[32];

    switch (AGTYPE(obj)) {
        case AGRAPH: sprintf(buf,"graph%p",obj); break;
        case AGNODE: sprintf(buf,"node%p",obj); break;
        case AGINEDGE: 
        case AGOUTEDGE: sprintf(buf,"edge%p",obj); break;
    }
    return buf;
}
Exemple #21
0
char *agnameof(void *obj)
{
    Agraph_t *g;
    char *rv;
    char buf[32];

    /* perform internal lookup first */
    g = agraphof(obj);
    if ((rv = aginternalmapprint(g, AGTYPE(obj), AGID(obj))))
	return rv;

    if (AGDISC(g, id)->print) {
	if ((rv =
	     AGDISC(g, id)->print(AGCLOS(g, id), AGTYPE(obj), AGID(obj))))
	    return rv;
    }
    if (AGTYPE(obj) != AGEDGE)
	sprintf(buf, "%c%ld", LOCALNAMEPREFIX, AGID(obj));
    else
	buf[0] = 0;
    return agstrdup(g, buf);
}
char *getv(Agedge_t *e, char *attr)
{
    Agraph_t *g;
    Agsym_t *a;

    if (!e || !attr)
        return NULL;
    if (AGTYPE(e) == AGRAPH) // protoedge   
	return NULL;   // FIXME ??
    g = agraphof(agtail(e));
    a = agattr(g, AGEDGE, attr, NULL);
    return myagxget(e, a);
}
Exemple #23
0
/* isIn:
 * Return 1 if object objp is in subgraph gp.
 */
int isIn(Agraph_t * gp, Agobj_t * objp)
{
    if (!sameG(gp, objp, "isIn", 0))
	return 0;
    switch (AGTYPE(objp)) {
    case AGRAPH:
	return (agparent((Agraph_t *) objp) == gp);
    case AGNODE:
	return (agidnode(gp, AGID(objp), 0) != 0);
    default:
	return (agsubedge(gp, (Agedge_t *) objp, 0) != 0);
    }
}
char *getv(Agnode_t *n, char *attr)
{
    Agraph_t *g;
    Agsym_t *a;

    if (!n || !attr)
        return NULL;
    if (AGTYPE(n) == AGRAPH) // protonode   
	return NULL;   // FIXME ??
    g = agroot(agraphof(n));
    a = agattr(g, AGNODE, attr, NULL);
    return myagxget(n, a);
}
Exemple #25
0
/* clone:
 * Create new object of type AGTYPE(obj) with all of its
 * attributes and substructure.
 * If obj is an edge, end nodes are cloned if necessary.
 * If obj is a graph, if g is null, create a clone top-level
 * graph. Otherwise, create a clone subgraph of g.
 * Assume obj != NULL.
 */
Agobj_t *clone(Agraph_t * g, Agobj_t * obj)
{
    Agobj_t *nobj = 0;
    Agedge_t *e;
    Agnode_t *h;
    Agnode_t *t;
    int kind = AGTYPE(obj);
    char *name;

    if ((kind != AGRAPH) && !g) {
	exerror("NULL graph with non-graph object in clone()");
	return 0;
    }

    switch (kind) {
    case AGNODE:		/* same as copy node */
	name = agnameof(obj);
	nobj = (Agobj_t *) openNode(g, name);
	if (nobj)
	    copyAttr(obj, nobj);
	break;
    case AGRAPH:
	name = agnameof(obj);
	if (g)
	    nobj = (Agobj_t *) openSubg(g, name);
	else
	    nobj = (Agobj_t *) openG(name, ((Agraph_t *) obj)->desc);
	if (nobj) {
	    copyAttr(obj, nobj);
	    cloneGraph((Agraph_t *) nobj, (Agraph_t *) obj);
	}
	break;
    case AGINEDGE:
    case AGOUTEDGE:
	e = (Agedge_t *) obj;
	t = (Agnode_t *) clone(g, OBJ(agtail(e)));
	h = (Agnode_t *) clone(g, OBJ(aghead(e)));
	name = agnameof (AGMKOUT(e));
	nobj = (Agobj_t *) openEdge(g, t, h, name);
	if (nobj)
	    copyAttr(obj, nobj);
	break;
    }

    return nobj;
}
Exemple #26
0
Agedge_t *agnxtedge(Agraph_t * g, Agedge_t * e, Agnode_t * n)
{
    Agedge_t *rv;

    if (AGTYPE(e) == AGOUTEDGE) {
	rv = agnxtout(g, e);
	if (rv == NILedge) {
	    do {
		rv = !rv ? agfstin(g, n) : agnxtin(g,rv);
	    } while (rv && (rv->node == n));
	}
    } else {
	do {
	    rv = agnxtin(g, e);		/* so that we only see each edge once, */
		e = rv;
	} while (rv && (rv->node == n));	/* ignore loops as in-edges */
    }
    return rv;
}
Exemple #27
0
/*
 * Open a new main graph with the given descriptor (directed, strict, etc.)
 */
Agraph_t *agopen(char *name, Agdesc_t desc, Agdisc_t * arg_disc)
{
    Agraph_t *g;
    Agclos_t *clos;
    unsigned long gid;

    clos = agclos(arg_disc);
    g = clos->disc.mem->alloc(clos->state.mem, sizeof(Agraph_t));
    AGTYPE(g) = AGRAPH;
    g->clos = clos;
    g->desc = desc;
    g->desc.maingraph = TRUE;
    g->root = g;
    g->clos->state.id = g->clos->disc.id->open(g);
    if (agmapnametoid(g, AGRAPH, name, &gid, TRUE))
	AGID(g) = gid;
    /* else AGID(g) = 0 because we have no alternatives */
    return agopen1(g);
}
char *setv(Agnode_t *n, char *attr, char *val)
{
    Agraph_t *g;
    Agsym_t *a;

    if (!n || !attr || !val)
        return NULL;
    if (AGTYPE(n) == AGRAPH) { // protonode   
	g = (Agraph_t*)n;
    	a = agattr(g, AGNODE, attr, val); // create default attribute in psuodo protonode
	    // FIXME? - deal with html in "label" attributes
	return val;
    }
    g = agroot(agraphof(n));
    a = agattr(g, AGNODE, attr, NULL);
    if (!a)
        a = agnodeattr(g, attr, emptystring);
    myagxset(n, a, val);
    return val;
}
Exemple #29
0
static void write_attrs(Agobj_t * obj, GVJ_t * job, state_t* sp)
{
    Agraph_t* g = agroot(obj);
    int type = AGTYPE(obj);
    char* attrval;
    Agsym_t* sym = agnxtattr(g, type, NULL);
    if (!sym) return;

    for (; sym; sym = agnxtattr(g, type, sym)) {
	if (!(attrval = agxget(obj, sym))) continue;
	if ((*attrval == '\0') && !streq(sym->name, "label")) continue;
	gvputs(job, ",\n");
	indent(job, sp->Level);
	gvprintf(job, "\"%s\": ", stoj(sym->name, sp));
	if (sp->doXDot && isXDot(sym->name))
	    write_xdots(agxget(obj, sym), job, sp);
	else
	    gvprintf(job, "\"%s\"", stoj(agxget(obj, sym), sp));
    }
}
char *setv(Agedge_t *e, char *attr, char *val)
{
    Agraph_t *g;
    Agsym_t *a;

    if (!e || !attr || !val)
        return NULL;
    if (AGTYPE(e) == AGRAPH) { // protoedge   
	g = (Agraph_t*)e;
    	a = agattr(g, AGEDGE, attr, val); // create default attribute in pseudo protoedge
	    // FIXME? - deal with html in "label" attributes
	return val;
    }
    g = agroot(agraphof(agtail(e)));
    a = agattr(g, AGEDGE, attr, NULL);
    if (!a)
        a = agattr(g, AGEDGE, attr, emptystring);
    myagxset(e, a, val);
    return val;
}