are (associative) arrays.
.PP
Constants follow C syntax, but strings may be quoted with either
-\fB"..."\fP or \fB'...'\fP. In certain contexts, string values are
-interpreted as patterns for the purpose of regular expression matching.
-Patterns use
-.IR ksh (1)
-file match pattern syntax.
+\fB"..."\fP or \fB'...'\fP.
\fBgvpr\fP accepts C++ comments as well as cpp\(hytype comments.
For the latter, if a line begins with a '#' character, the rest of
the line is ignored.
.PP
Expressions include the usual C expressions.
String comparisons using \fB==\fP and \fB!=\fP
-treat the right hand operand as a pattern.
+treat the right hand operand as a pattern
+for the purpose of regular expression matching.
+Patterns use
+.IR ksh (1)
+file match pattern syntax.
+(For simple string equality, use the \fBstrcmp\fP function.
+.PP
\fBgvpr\fP will attempt to use an expression as a string or numeric value
-as appropriate.
+as appropriate. Both C-like casts and function templates will cause
+conversions to be performed, if possible.
.PP
Expressions of graphical type (i.e., \fBgraph_t, node_t,
edge_t, obj_t\fP) may be followed by a field reference in the
\fBisIn\fP(\fIg\fP : \fBgraph_t\fP, \fIx\fP : \fBobj_t\fP) : \fBint\fP
returns true if \fIx\fP is in subgraph \fIg\fP.
.TP
+\fBcloneG\fP(\fIg\fP : \fBgraph_t\fP, \fIs\fP : \fBstring\fP) : \fBgraph_t\fP
+creates a clone of graph \fIg\fP with name of \fIs\fP.
+If \fIs\fP is "", the created graph has the same name as \fIg\fP.
+.TP
\fBclone\fP(\fIg\fP : \fBgraph_t\fP, \fIx\fP : \fBobj_t\fP) : \fBobj_t\fP
creates a clone of object \fIx\fP in graph \fIg\fP.
In particular, the new object has the same name/value attributes
If a graph is cloned, all nodes, edges and subgraphs are implicitly
cloned.
If \fIx\fP is a graph, \fIg\fP may be \fBNULL\fP, in which case the cloned
-object will be a new root graph.
+object will be a new root graph. In this case, the call is equivalent
+to \fBcloneG(\fP\fIx\fP\fB,"")\fP.
.TP
\fBcopy\fP(\fIg\fP : \fBgraph_t\fP, \fIx\fP : \fBobj_t\fP) : \fBobj_t\fP
creates a copy of object \fIx\fP in graph \fIg\fP,
case, if \fIlen\fP is negative or \fIidx\fP + \fIlen\fP is greater than the
length of \fIstr\fP, a fatal error occurs.
.TP
-\fBlength\fP(\fIs\fP : \fBstring\fP) : \fBint\fP
-returns the length of the string \fIs\fP.
+\fBstrcmp\fP(\fIs1\fP : \fBstring\fP, \fIs2\fP : \fBstring\fP) : \fBint\fP
+provides the standard C function
+.IR strcmp (3).
.TP
\fBindex\fP(\fIs\fP : \fBstring\fP, \fIt\fP : \fBstring\fP) : \fBint\fP
.TP
}
}
-/* copyAttr;
+/* copyAttr:
* Copy attributes from src to tgt. Overrides currently
* defined values.
* FIX: we should probably use the default value of the source
free (data);
}
+/* cloneG:
+ */
+Agraph_t *cloneG(Agraph_t * g, char* name)
+{
+ Agraph_t* ng;
+
+ if (!name || (*name == '\0'))
+ name = agnameof (g);
+ ng = openG(name, g->desc);
+ if (ng) {
+ copyAttr((Agobj_t*)g, (Agobj_t*)ng);
+ cloneGraph(ng, g);
+ }
+ return ng;
+}
+
/* clone:
* Create new object of type AGTYPE(obj) with all of its
* attributes and substructure.
nobj = (Agobj_t *) openSubg(g, name);
else
nobj = (Agobj_t *) openG(name, ((Agraph_t *) obj)->desc);
- if (nobj)
+ if (nobj) {
copyAttr(obj, nobj);
- cloneGraph((Agraph_t *) nobj, (Agraph_t *) obj);
+ cloneGraph((Agraph_t *) nobj, (Agraph_t *) obj);
+ }
break;
case AGINEDGE:
case AGOUTEDGE:
extern void nodeInduce(Agraph_t * selected);
extern Agobj_t *clone(Agraph_t * g, Agobj_t * obj);
+ extern Agraph_t *cloneG(Agraph_t * g, char* name);
extern Agobj_t *copy(Agraph_t * g, Agobj_t * obj);
extern int copyAttr(Agobj_t * obj, Agobj_t * obj1);
extern int indexOf(char *s1, char *s2);
if (gp) {
gp = openSubg(gp, args[1].string);
v.integer = PTR2INT(gp);
+ } else {
+ error(ERROR_WARNING, "NULL graph passed to subg()");
+ v.integer = 0;
}
break;
case F_issubg:
} else
v.integer = PTR2INT(clone(gp, objp));
break;
+ case F_cloneG:
+ gp = INT2PTR(Agraph_t *, args[0].integer);
+ if (gp) {
+ gp = cloneG(gp, args[1].string);
+ v.integer = PTR2INT(gp);
+ } else {
+ error(ERROR_WARNING, "NULL graph passed to cloneG()");
+ v.integer = 0;
+ }
+ break;
case F_copya:
objp = INT2PTR(Agobj_t *, args[0].integer);
objp1 = INT2PTR(Agobj_t *, args[1].integer);
case F_colorx:
v.string = colorx(pgm, args[0].string, args[1].string, state->tmp);
break;
+ case F_strcmp:
+ if (args[0].string) {
+ if (args[1].string)
+ v.integer = strcmp(args[0].string,args[1].string);
+ else
+ v.integer = -1;
+ } else if (args[1].string)
+ v.integer = 1;
+ else
+ v.integer = 0;
+ break;
case F_toupper:
v.string = toUpper(pgm, args[0].string, state->tmp);
break;
F_isstrict "isStrict" FUNCTION I|A(1,G)
F_delete "delete" FUNCTION I|A(1,G)|A(2,O)
F_clone "clone" FUNCTION O|A(1,G)|A(2,O)
+F_cloneG "cloneG" FUNCTION G|A(1,G)|A(2,S)
F_copy "copy" FUNCTION O|A(1,G)|A(2,O)
F_copya "copyA" FUNCTION I|A(1,O)|A(2,O)
F_lock "lock" FUNCTION I|A(1,G)|A(2,I)
F_nxtattr "nxtAttr" FUNCTION S|A(1,G)|A(2,S)|A(3,S)
F_tolower "tolower" FUNCTION S|A(1,S)
F_toupper "toupper" FUNCTION S|A(1,S)
+F_strcmp "strcmp" FUNCTION I|A(1,S)|A(2,S)
F_atoi "atoi" FUNCTION I|A(1,S)
F_atof "atof" FUNCTION F|A(1,S)
F_colorx "colorx" FUNCTION S|A(1,S)|A(2,S)