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