gprstate.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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. * gpr state
  12. *
  13. */
  14. #include <gvpr/gprstate.h>
  15. #include <ast/error.h>
  16. #include <stdbool.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <util/alloc.h>
  20. static int name_used;
  21. bool validTVT(long long c) {
  22. return TV_flat <= c && c <= TV_prepostrev;
  23. }
  24. void initGPRState(Gpr_t *state) {
  25. state->tgtname = strdup("gvpr_result");
  26. }
  27. Gpr_t *openGPRState(gpr_info* info)
  28. {
  29. Gpr_t *state;
  30. if (!(state = calloc(1, sizeof(Gpr_t)))) {
  31. error(ERROR_ERROR, "Could not create gvpr state: out of memory");
  32. return state;
  33. }
  34. state->tvt = TV_flat;
  35. state->name_used = name_used;
  36. state->tvroot = 0;
  37. state->tvnext = 0;
  38. state->tvedge = 0;
  39. state->outFile = info->outFile;
  40. state->argc = info->argc;
  41. state->argv = info->argv;
  42. state->errf = info->errf;
  43. state->flags = info->flags;
  44. return state;
  45. }
  46. static int
  47. bindingcmpf (const void *key, const void *ip)
  48. {
  49. return strcmp (((const gvprbinding*)key)->name, ((const gvprbinding*)ip)->name);
  50. }
  51. /* findBinding:
  52. */
  53. gvprbinding*
  54. findBinding (Gpr_t* state, char* fname)
  55. {
  56. gvprbinding key;
  57. gvprbinding* bp;
  58. if (!state->bindings) {
  59. error(ERROR_ERROR,"call(\"%s\") failed: no bindings", fname);
  60. return NULL;
  61. }
  62. if (!fname) {
  63. error(ERROR_ERROR,"NULL function name for call()");
  64. return NULL;
  65. }
  66. key.name = fname;
  67. bp = bsearch(&key, state->bindings, state->n_bindings, sizeof(gvprbinding), bindingcmpf);
  68. if (!bp)
  69. error(ERROR_ERROR, "No binding for \"%s\" in call()", fname);
  70. return bp;
  71. }
  72. /* addBindings:
  73. * Validate input, sort lexicographically, and attach
  74. */
  75. void addBindings (Gpr_t* state, gvprbinding* bindings)
  76. {
  77. size_t n = 0;
  78. gvprbinding* bp = bindings;
  79. gvprbinding* buf;
  80. gvprbinding* bufp;
  81. while (bp && bp->name) {
  82. if (bp->fn) n++;
  83. bp++;
  84. }
  85. if (n == 0) return;
  86. bufp = buf = gv_calloc(n, sizeof(gvprbinding));
  87. bp = bindings;
  88. while (bp->name) {
  89. if (bp->fn) {
  90. *bufp = *bp;
  91. bufp++;
  92. }
  93. bp++;
  94. }
  95. qsort (buf, n, sizeof(gvprbinding), bindingcmpf);
  96. state->bindings = buf;
  97. state->n_bindings = n;
  98. }
  99. void closeGPRState(Gpr_t* state)
  100. {
  101. if (!state) return;
  102. name_used = state->name_used;
  103. free(state->tgtname);
  104. free (state->dp);
  105. free (state);
  106. }