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