tcldot-edgecmd.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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. #include "tcldot.h"
  11. #include <string.h>
  12. #include <util/streq.h>
  13. static int edgecmd_internal(ClientData clientData, Tcl_Interp *interp, int argc,
  14. char *argv[]) {
  15. char **argv2;
  16. int i, j, argc2;
  17. Agraph_t *g;
  18. Agedge_t *e;
  19. Agsym_t *a;
  20. gctx_t *gctx = (gctx_t *)clientData;
  21. if (argc < 2) {
  22. Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  23. "\" option ?arg arg ...?", NULL);
  24. return TCL_ERROR;
  25. }
  26. e = cmd2e(argv[0]);
  27. if (!e) {
  28. Tcl_AppendResult(interp, "edge \"", argv[0], "\" not found", NULL);
  29. return TCL_ERROR;
  30. }
  31. g = agraphof(agtail(e));
  32. if (streq("delete", argv[1])) {
  33. deleteEdge(gctx, g, e);
  34. return TCL_OK;
  35. } else if (streq("listattributes", argv[1])) {
  36. listEdgeAttrs(interp, g);
  37. return TCL_OK;
  38. } else if (streq("listnodes", argv[1])) {
  39. Tcl_AppendElement(interp, obj2cmd(agtail(e)));
  40. Tcl_AppendElement(interp, obj2cmd(aghead(e)));
  41. return TCL_OK;
  42. } else if (streq("queryattributes", argv[1])) {
  43. for (i = 2; i < argc; i++) {
  44. if (Tcl_SplitList(interp, argv[i], &argc2, (const char ***)&argv2) !=
  45. TCL_OK)
  46. return TCL_ERROR;
  47. for (j = 0; j < argc2; j++) {
  48. if ((a = agfindedgeattr(g, argv2[j]))) {
  49. Tcl_AppendElement(interp, agxget(e, a));
  50. } else {
  51. Tcl_AppendResult(interp, "no attribute named \"", argv2[j], "\"",
  52. NULL);
  53. Tcl_Free((char *)argv2);
  54. return TCL_ERROR;
  55. }
  56. }
  57. Tcl_Free((char *)argv2);
  58. }
  59. return TCL_OK;
  60. } else if (streq("queryattributevalues", argv[1])) {
  61. for (i = 2; i < argc; i++) {
  62. if (Tcl_SplitList(interp, argv[i], &argc2, (const char ***)&argv2) !=
  63. TCL_OK)
  64. return TCL_ERROR;
  65. for (j = 0; j < argc2; j++) {
  66. if ((a = agfindedgeattr(g, argv2[j]))) {
  67. Tcl_AppendElement(interp, argv2[j]);
  68. Tcl_AppendElement(interp, agxget(e, a));
  69. } else {
  70. Tcl_AppendResult(interp, "no attribute named \"", argv2[j], "\"",
  71. NULL);
  72. Tcl_Free((char *)argv2);
  73. return TCL_ERROR;
  74. }
  75. }
  76. Tcl_Free((char *)argv2);
  77. }
  78. return TCL_OK;
  79. } else if (streq("setattributes", argv[1])) {
  80. if (argc == 3) {
  81. if (Tcl_SplitList(interp, argv[2], &argc2, (const char ***)&argv2) !=
  82. TCL_OK)
  83. return TCL_ERROR;
  84. if ((argc2 == 0) || (argc2 % 2)) {
  85. Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  86. "\" setattributes attributename attributevalue "
  87. "?attributename attributevalue? ?...?",
  88. NULL);
  89. Tcl_Free((char *)argv2);
  90. return TCL_ERROR;
  91. }
  92. setedgeattributes(agroot(g), e, argv2, argc2);
  93. Tcl_Free((char *)argv2);
  94. } else {
  95. if ((argc < 4) || (argc % 2)) {
  96. Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  97. "\" setattributes attributename attributevalue "
  98. "?attributename attributevalue? ?...?",
  99. NULL);
  100. return TCL_ERROR;
  101. }
  102. setedgeattributes(agroot(g), e, &argv[2], argc - 2);
  103. }
  104. return TCL_OK;
  105. } else if (streq("showname", argv[1])) {
  106. const char *const s = agisdirected(g) ? "->" : "--";
  107. Tcl_AppendResult(interp, agnameof(agtail(e)), s, agnameof(aghead(e)), NULL);
  108. return TCL_OK;
  109. } else {
  110. Tcl_AppendResult(interp, "bad option \"", argv[1], "\": must be one of:",
  111. "\n\tdelete, listattributes, listnodes,",
  112. "\n\tueryattributes, queryattributevalues,",
  113. "\n\tsetattributes, showname", NULL);
  114. return TCL_ERROR;
  115. }
  116. }
  117. int edgecmd(ClientData clientData, Tcl_Interp *interp, int argc,
  118. const char *argv[]) {
  119. char **argv_copy = tcldot_argv_dup(argc, argv);
  120. int rc = edgecmd_internal(clientData, interp, argc, argv_copy);
  121. tcldot_argv_free(argc, argv_copy);
  122. return rc;
  123. }