Graphviz 13.0.0~dev.20241220.2304
Loading...
Searching...
No Matches
tcldot-edgecmd.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 "tcldot.h"
12#include <string.h>
13#include <util/streq.h>
14
15static int edgecmd_internal(ClientData clientData, Tcl_Interp *interp, int argc,
16 char *argv[]) {
17 char **argv2;
18 int i, j, argc2;
19 Agraph_t *g;
20 Agedge_t *e;
21 Agsym_t *a;
22 gctx_t *gctx = (gctx_t *)clientData;
23
24 if (argc < 2) {
25 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
26 "\" option ?arg arg ...?", NULL);
27 return TCL_ERROR;
28 }
29 e = cmd2e(argv[0]);
30 if (!e) {
31 Tcl_AppendResult(interp, "edge \"", argv[0], "\" not found", NULL);
32 return TCL_ERROR;
33 }
34 g = agraphof(agtail(e));
35
36 if (streq("delete", argv[1])) {
37 deleteEdge(gctx, g, e);
38 return TCL_OK;
39
40 } else if (streq("listattributes", argv[1])) {
41 listEdgeAttrs(interp, g);
42 return TCL_OK;
43
44 } else if (streq("listnodes", argv[1])) {
45 Tcl_AppendElement(interp, obj2cmd(agtail(e)));
46 Tcl_AppendElement(interp, obj2cmd(aghead(e)));
47 return TCL_OK;
48
49 } else if (streq("queryattributes", argv[1])) {
50 for (i = 2; i < argc; i++) {
51 if (Tcl_SplitList(interp, argv[i], &argc2, (const char ***)&argv2) !=
52 TCL_OK)
53 return TCL_ERROR;
54 for (j = 0; j < argc2; j++) {
55 if ((a = agfindedgeattr(g, argv2[j]))) {
56 Tcl_AppendElement(interp, agxget(e, a));
57 } else {
58 Tcl_AppendResult(interp, "no attribute named \"", argv2[j], "\"",
59 NULL);
60 Tcl_Free((char *)argv2);
61 return TCL_ERROR;
62 }
63 }
64 Tcl_Free((char *)argv2);
65 }
66 return TCL_OK;
67
68 } else if (streq("queryattributevalues", argv[1])) {
69 for (i = 2; i < argc; i++) {
70 if (Tcl_SplitList(interp, argv[i], &argc2, (const char ***)&argv2) !=
71 TCL_OK)
72 return TCL_ERROR;
73 for (j = 0; j < argc2; j++) {
74 if ((a = agfindedgeattr(g, argv2[j]))) {
75 Tcl_AppendElement(interp, argv2[j]);
76 Tcl_AppendElement(interp, agxget(e, a));
77 } else {
78 Tcl_AppendResult(interp, "no attribute named \"", argv2[j], "\"",
79 NULL);
80 Tcl_Free((char *)argv2);
81 return TCL_ERROR;
82 }
83 }
84 Tcl_Free((char *)argv2);
85 }
86 return TCL_OK;
87
88 } else if (streq("setattributes", argv[1])) {
89 if (argc == 3) {
90 if (Tcl_SplitList(interp, argv[2], &argc2, (const char ***)&argv2) !=
91 TCL_OK)
92 return TCL_ERROR;
93 if ((argc2 == 0) || (argc2 % 2)) {
94 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
95 "\" setattributes attributename attributevalue "
96 "?attributename attributevalue? ?...?",
97 NULL);
98 Tcl_Free((char *)argv2);
99 return TCL_ERROR;
100 }
101 setedgeattributes(agroot(g), e, argv2, argc2);
102 Tcl_Free((char *)argv2);
103 } else {
104 if ((argc < 4) || (argc % 2)) {
105 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
106 "\" setattributes attributename attributevalue "
107 "?attributename attributevalue? ?...?",
108 NULL);
109 return TCL_ERROR;
110 }
111 setedgeattributes(agroot(g), e, &argv[2], argc - 2);
112 }
113 return TCL_OK;
114
115 } else if (streq("showname", argv[1])) {
116 const char *const s = agisdirected(g) ? "->" : "--";
117 Tcl_AppendResult(interp, agnameof(agtail(e)), s, agnameof(aghead(e)), NULL);
118 return TCL_OK;
119
120 } else {
121 Tcl_AppendResult(interp, "bad option \"", argv[1], "\": must be one of:",
122 "\n\tdelete, listattributes, listnodes,",
123 "\n\tueryattributes, queryattributevalues,",
124 "\n\tsetattributes, showname", NULL);
125 return TCL_ERROR;
126 }
127}
128
129int edgecmd(ClientData clientData, Tcl_Interp *interp, int argc,
130 const char *argv[]) {
131 char **argv_copy = tcldot_argv_dup(argc, argv);
132 int rc = edgecmd_internal(clientData, interp, argc, argv_copy);
133 tcldot_argv_free(argc, argv_copy);
134 return rc;
135}
node NULL
Definition grammar.y:163
char * agxget(void *obj, Agsym_t *sym)
Definition attr.c:455
#define agfindedgeattr(g, a)
Definition types.h:617
#define agtail(e)
Definition cgraph.h:880
#define aghead(e)
Definition cgraph.h:881
int agisdirected(Agraph_t *g)
Definition graph.c:190
Agraph_t * agraphof(void *obj)
Definition obj.c:185
char * agnameof(void *)
returns a string descriptor for the object.
Definition id.c:158
Agraph_t * agroot(void *obj)
Definition obj.c:168
static bool streq(const char *a, const char *b)
are a and b equal?
Definition streq.h:11
graph or subgraph
Definition cgraph.h:425
string attribute descriptor symbol in Agattr_s.dict
Definition cgraph.h:637
static int edgecmd_internal(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
int edgecmd(ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[])
void deleteEdge(gctx_t *gctx, Agraph_t *g, Agedge_t *e)
Definition tcldot-util.c:80
char * obj2cmd(void *obj)
Definition tcldot-util.c:66
void listEdgeAttrs(Tcl_Interp *interp, Agraph_t *g)
Agedge_t * cmd2e(const char *cmd)
Definition tcldot-util.c:55
void setedgeattributes(Agraph_t *g, Agedge_t *e, char *argv[], int argc)
void tcldot_argv_free(int argc, char *argv[])
free the strings pointed to by argv
char ** tcldot_argv_dup(int argc, const char *argv[])
duplicate the strings pointed to by argv as non-const strings
Definition grammar.c:93