tcldot-id.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  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 <stdint.h>
  11. #include <util/alloc.h>
  12. #include <util/unreachable.h>
  13. #include "tcldot.h"
  14. // Agiddisc functions
  15. static void *myiddisc_open(Agraph_t *g, Agdisc_t *disc) {
  16. ictx_t *ictx = (ictx_t *)disc;
  17. gctx_t *gctx;
  18. gctx = gv_alloc(sizeof(gctx_t));
  19. gctx->g = g;
  20. gctx->ictx = ictx;
  21. return gctx;
  22. }
  23. static long myiddisc_map(void *state, int objtype, char *str, uint64_t *id, int createflag) {
  24. (void)objtype;
  25. gctx_t *gctx = state;
  26. ictx_t *ictx = gctx->ictx;
  27. char *s;
  28. if (str) {
  29. if (createflag)
  30. s = agstrdup(gctx->g, str);
  31. else
  32. s = agstrbind(gctx->g, str);
  33. *id = (uint64_t)(uintptr_t)s;
  34. } else {
  35. *id = ictx->ctr; /* counter maintained in per-interp space, so that
  36. ids are unique across all graphs in the interp */
  37. ictx->ctr += 2;
  38. }
  39. return 1;
  40. }
  41. /* we don't allow users to explicitly set IDs, either */
  42. static long myiddisc_alloc(void *state, int objtype, uint64_t request_id) {
  43. (void)state;
  44. (void)objtype;
  45. (void)request_id;
  46. return 0;
  47. }
  48. static void myiddisc_free(void *state, int objtype, uint64_t id) {
  49. (void)objtype;
  50. gctx_t *gctx = state;
  51. /* FIXME no obj* available
  52. ictx_t *ictx = gctx->ictx;
  53. char buf[32] = "";
  54. switch (objtype) {
  55. case AGRAPH: sprintf(buf,"graph%lu",id); break;
  56. case AGNODE: sprintf(buf,"node%lu",id); break;
  57. case AGINEDGE:
  58. case AGOUTEDGE: sprintf(buf,"edge%lu",id); break;
  59. }
  60. Tcl_DeleteCommand(ictx->interp, buf);
  61. */
  62. if (id % 2 == 0)
  63. agstrfree(gctx->g, (char *)(uintptr_t)id);
  64. }
  65. static char *myiddisc_print(void *state, int objtype, uint64_t id) {
  66. (void)state;
  67. (void)objtype;
  68. if (id % 2 == 0)
  69. return (char *)(uintptr_t)id;
  70. else
  71. return "";
  72. }
  73. static void myiddisc_idregister(void *state, int objtype, void *obj) {
  74. gctx_t *gctx = state;
  75. ictx_t *ictx = gctx->ictx;
  76. Tcl_Interp *interp = ictx->interp;
  77. Tcl_CmdProc *proc = NULL;
  78. switch (objtype) {
  79. case AGRAPH: proc=graphcmd; break;
  80. case AGNODE: proc=nodecmd; break;
  81. case AGINEDGE:
  82. case AGOUTEDGE: proc=edgecmd; break;
  83. default: UNREACHABLE();
  84. }
  85. Tcl_CreateCommand(interp, obj2cmd(obj), proc, (ClientData) gctx, NULL);
  86. }
  87. Agiddisc_t myiddisc = {
  88. myiddisc_open,
  89. myiddisc_map,
  90. myiddisc_alloc,
  91. myiddisc_free,
  92. myiddisc_print,
  93. free,
  94. myiddisc_idregister
  95. };