Graphviz 12.0.1~dev.20240715.2254
Loading...
Searching...
No Matches
tcldot-nodecmd.c
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11#include <string.h>
12#include "tcldot.h"
13
14int nodecmd(ClientData clientData, Tcl_Interp * interp,
15#ifndef TCLOBJ
16 int argc, char *argv[]
17#else /* TCLOBJ */
18 int argc, Tcl_Obj * CONST objv[]
19#endif /* TCLOBJ */
20 )
21{
22 char **argv2;
23 int i, j, argc2;
24 Agraph_t *g;
25 Agnode_t *n, *head;
26 Agedge_t *e;
27 Agsym_t *a;
28 gctx_t *gctx = (gctx_t *)clientData;
29
30 if (argc < 2) {
31 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " option ?arg arg ...?\"", NULL);
32 return TCL_ERROR;
33 }
34 n = cmd2n(argv[0]);
35 if (!n) {
36 Tcl_AppendResult(interp, "node \"", argv[0], "\" not found", NULL);
37 return TCL_ERROR;
38 }
39 g = agraphof(n);
40
41 if (strcmp("addedge", argv[1]) == 0) {
42 if ((argc < 3) || (!(argc % 2))) {
43 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " addedge head ?attributename attributevalue? ?...?\"", NULL);
44 return TCL_ERROR;
45 }
46 head = cmd2n(argv[2]);
47 if (!head) {
48 if (!(head = agfindnode(g, argv[2]))) {
49 Tcl_AppendResult(interp, "head node \"", argv[2], "\" not found.", NULL);
50 return TCL_ERROR;
51 }
52 }
53 if (agroot(g) != agroot(agraphof(head))) {
54 Tcl_AppendResult(interp, "nodes ", argv[0], " and ", argv[2], " are not in the same graph.", NULL);
55 return TCL_ERROR;
56 }
57 e = agedge(g, n, head, NULL, 1);
58 Tcl_AppendResult(interp, obj2cmd(e), NULL);
59 setedgeattributes(agroot(g), e, &argv[3], argc - 3);
60 return TCL_OK;
61
62 } else if (strcmp("delete", argv[1]) == 0) {
63 deleteNode(gctx, g, n);
64 return TCL_OK;
65
66 } else if (strcmp("findedge", argv[1]) == 0) {
67 if (argc < 3) {
68 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " findedge headnodename\"", NULL);
69 return TCL_ERROR;
70 }
71 if (!(head = agfindnode(g, argv[2]))) {
72 Tcl_AppendResult(interp, "head node \"", argv[2], "\" not found.", NULL);
73 return TCL_ERROR;
74 }
75 if (!(e = agfindedge(g, n, head))) {
76 Tcl_AppendResult(interp, "edge \"", argv[0], " - ", obj2cmd(head), "\" not found.", NULL);
77 return TCL_ERROR;
78 }
79 Tcl_AppendElement(interp, obj2cmd(head));
80 return TCL_OK;
81
82 } else if (strcmp("listattributes", argv[1]) == 0) {
83 listNodeAttrs (interp, g);
84 return TCL_OK;
85
86 } else if (strcmp("listedges", argv[1]) == 0) {
87 for (e = agfstedge(g, n); e; e = agnxtedge(g, e, n)) {
88 Tcl_AppendElement(interp, obj2cmd(e));
89 }
90 return TCL_OK;
91
92 } else if (strcmp("listinedges", argv[1]) == 0) {
93 for (e = agfstin(g, n); e; e = agnxtin(g, e)) {
94 Tcl_AppendElement(interp, obj2cmd(e));
95 }
96 return TCL_OK;
97
98 } else if (strcmp("listoutedges", argv[1]) == 0) {
99 for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
100 Tcl_AppendElement(interp, obj2cmd(e));
101 }
102 return TCL_OK;
103
104 } else if (strcmp("queryattributes", argv[1]) == 0) {
105 for (i = 2; i < argc; i++) {
106 if (Tcl_SplitList
107 (interp, argv[i], &argc2,
108 (CONST84 char ***) &argv2) != TCL_OK)
109 return TCL_ERROR;
110 for (j = 0; j < argc2; j++) {
111 if ((a = agfindnodeattr(g, argv2[j]))) {
112 Tcl_AppendElement(interp, agxget(n, a));
113 } else {
114 Tcl_AppendResult(interp, "no attribute named \"", argv2[j], "\"", NULL);
115 return TCL_ERROR;
116 }
117 }
118 Tcl_Free((char *) argv2);
119 }
120 return TCL_OK;
121
122 } else if (strcmp("queryattributevalues", argv[1]) == 0) {
123 for (i = 2; i < argc; i++) {
124 if (Tcl_SplitList
125 (interp, argv[i], &argc2,
126 (CONST84 char ***) &argv2) != TCL_OK)
127 return TCL_ERROR;
128 for (j = 0; j < argc2; j++) {
129 if ((a = agfindnodeattr(g, argv2[j]))) {
130 Tcl_AppendElement(interp, argv2[j]);
131 Tcl_AppendElement(interp, agxget(n, a));
132 } else {
133 Tcl_AppendResult(interp, "no attribute named \"", argv2[j], "\"", NULL);
134 return TCL_ERROR;
135 }
136 }
137 Tcl_Free((char *) argv2);
138 }
139 return TCL_OK;
140
141 } else if (strcmp("setattributes", argv[1]) == 0) {
142 g = agroot(g);
143 if (argc == 3) {
144 if (Tcl_SplitList
145 (interp, argv[2], &argc2,
146 (CONST84 char ***) &argv2) != TCL_OK)
147 return TCL_ERROR;
148 if ((argc2 == 0) || (argc2 % 2)) {
149 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
150 "\" setattributes attributename attributevalue ?attributename attributevalue? ?...?",
151 NULL);
152 Tcl_Free((char *) argv2);
153 return TCL_ERROR;
154 }
155 setnodeattributes(g, n, argv2, argc2);
156 Tcl_Free((char *) argv2);
157 } else {
158 if ((argc < 4) || (argc % 2)) {
159 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
160 "\" setattributes attributename attributevalue ?attributename attributevalue? ?...?",
161 NULL);
162 return TCL_ERROR;
163 }
164 setnodeattributes(g, n, &argv[2], argc - 2);
165 }
166 return TCL_OK;
167
168 } else if (strcmp("showname", argv[1]) == 0) {
169 Tcl_SetResult(interp, agnameof(n), TCL_STATIC);
170 return TCL_OK;
171
172 } else {
173 Tcl_AppendResult(interp, "bad option \"", argv[1],
174 "\": must be one of:",
175 "\n\taddedge, listattributes, listedges, listinedges,",
176 "\n\tlistoutedges, queryattributes, queryattributevalues,",
177 "\n\tsetattributes, showname.", NULL);
178 return TCL_ERROR;
179 }
180}
#define head
Definition dthdr.h:15
node NULL
Definition grammar.y:149
char * agxget(void *obj, Agsym_t *sym)
Definition attr.c:458
Agedge_t * agedge(Agraph_t *g, Agnode_t *t, Agnode_t *h, char *name, int createflag)
Definition edge.c:260
Agedge_t * agnxtin(Agraph_t *g, Agedge_t *e)
Definition edge.c:68
Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Definition edge.c:23
#define agfindedge(g, t, h)
Definition types.h:609
Agedge_t * agnxtedge(Agraph_t *g, Agedge_t *e, Agnode_t *n)
Definition edge.c:93
Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
Definition edge.c:38
Agedge_t * agfstedge(Agraph_t *g, Agnode_t *n)
Definition edge.c:84
Agedge_t * agfstin(Agraph_t *g, Agnode_t *n)
Definition edge.c:54
#define agfindnodeattr(g, a)
Definition types.h:615
#define agfindnode(g, n)
Definition types.h:611
Agraph_t * agraphof(void *obj)
Definition obj.c:184
char * agnameof(void *)
returns a string descriptor for the object.
Definition id.c:158
Agraph_t * agroot(void *obj)
Definition obj.c:167
graph or subgraph
Definition cgraph.h:425
string attribute descriptor symbol in Agattr_s.dict
Definition cgraph.h:639
int nodecmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
void listNodeAttrs(Tcl_Interp *interp, Agraph_t *g)
void deleteNode(gctx_t *gctx, Agraph_t *g, Agnode_t *n)
char * obj2cmd(void *obj)
Definition tcldot-util.c:65
Agnode_t * cmd2n(char *cmd)
Definition tcldot-util.c:47
void setnodeattributes(Agraph_t *g, Agnode_t *n, char *argv[], int argc)
void setedgeattributes(Agraph_t *g, Agedge_t *e, char *argv[], int argc)
#define CONST84
Definition tcldot.h:23