/src/rotz-export.c

https://bitbucket.org/hroptatyr/rotz · C · 208 lines · 133 code · 29 blank · 46 comment · 25 complexity · 0fcd0b1e1c9aab8e3aef697806486898 MD5 · raw file

  1. /*** rotz-export.c -- rotz graph exporter
  2. *
  3. * Copyright (C) 2013-2014 Sebastian Freundt
  4. *
  5. * Author: Sebastian Freundt <freundt@ga-group.nl>
  6. *
  7. * This file is part of rotz.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. *
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. *
  16. * 2. Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in the
  18. * documentation and/or other materials provided with the distribution.
  19. *
  20. * 3. Neither the name of the author nor the names of any contributors
  21. * may be used to endorse or promote products derived from this
  22. * software without specific prior written permission.
  23. *
  24. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
  25. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  26. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  27. * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  29. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  30. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  31. * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  32. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  33. * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  34. * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35. *
  36. ***/
  37. #if defined HAVE_CONFIG_H
  38. # include "config.h"
  39. #endif /* HAVE_CONFIG_H */
  40. #include <stdlib.h>
  41. #include <stdint.h>
  42. #include <string.h>
  43. #include <stdio.h>
  44. #include "rotz.h"
  45. #include "rotz-cmd-api.h"
  46. #include "rotz-umb.h"
  47. #include "nifty.h"
  48. static int clusterp;
  49. static int
  50. iter_csv_cb(rtz_vtx_t vid, rtz_const_vtxlst_t vl, void *clo)
  51. {
  52. rtz_buf_t n = rotz_get_name_r(clo, vid);
  53. const char *vtx = n.d;
  54. if (memcmp(vtx, RTZ_SYMSPC, sizeof(RTZ_SYMSPC) - 1) == 0) {
  55. /* that's a symbol, vtx would be a tag then */
  56. return 0;
  57. } else if (memcmp(vtx, RTZ_TAGSPC, sizeof(RTZ_TAGSPC) - 1) == 0) {
  58. vtx += RTZ_PRE_Z;
  59. } else if (clusterp) {
  60. char *p = strchr(vtx, ':');
  61. *p = '\0';
  62. }
  63. for (size_t i = 0; i < vl.z; i++) {
  64. const char *vld = rotz_get_name(clo, vl.d[i]);
  65. const char *tgt = rotz_massage_name(vld);
  66. fputs(vtx, stdout);
  67. fputc('\t', stdout);
  68. fputs(tgt, stdout);
  69. fputc('\n', stdout);
  70. }
  71. rotz_free_r(n);
  72. return 0;
  73. }
  74. static int
  75. iter_dot_cb(rtz_vtx_t vid, rtz_const_vtxlst_t vl, void *clo)
  76. {
  77. rtz_buf_t n = rotz_get_name_r(clo, vid);
  78. const char *vtx = n.d;
  79. if (memcmp(vtx, RTZ_SYMSPC, sizeof(RTZ_SYMSPC) - 1) == 0) {
  80. /* that's a symbol, vtx would be a tag then */
  81. return 0;
  82. } else if (memcmp(vtx, RTZ_TAGSPC, sizeof(RTZ_TAGSPC) - 1) == 0) {
  83. vtx += RTZ_PRE_Z;
  84. } else if (clusterp) {
  85. char *p = strchr(vtx, ':');
  86. *p = '\0';
  87. }
  88. for (size_t i = 0; i < vl.z; i++) {
  89. const char *vld = rotz_get_name(clo, vl.d[i]);
  90. const char *tgt = rotz_massage_name(vld);
  91. printf(" \"%s\" -- \"%s\";\n", vtx, tgt);
  92. }
  93. rotz_free_r(n);
  94. return 0;
  95. }
  96. static int
  97. iter_gmlv_cb(rtz_vtx_t vid, const char *vtx, void *UNUSED(clo))
  98. {
  99. printf("\
  100. node [\n\
  101. id %u\n\
  102. label \"%s\"\n\
  103. ]\n", vid, rotz_massage_name(vtx));
  104. return 0;
  105. }
  106. static int
  107. iter_gmle_cb(rtz_vtx_t sid, rtz_const_vtxlst_t vl, void *clo)
  108. {
  109. const char *stx = rotz_get_name(clo, sid);
  110. if (memcmp(stx, RTZ_SYMSPC, sizeof(RTZ_SYMSPC) - 1) == 0) {
  111. return 0;
  112. }
  113. for (size_t i = 0; i < vl.z; i++) {
  114. rtz_vtx_t tid = vl.d[i];
  115. printf("\
  116. edge [\n\
  117. source %u\n\
  118. target %u\n\
  119. ]\n", sid, tid);
  120. }
  121. return 0;
  122. }
  123. static void
  124. xprt_csv(rotz_t ctx)
  125. {
  126. /* go through all edges */
  127. rotz_edg_iter(ctx, iter_csv_cb, ctx);
  128. return;
  129. }
  130. static void
  131. xprt_dot(rotz_t ctx)
  132. {
  133. puts("graph rotz {");
  134. /* go through all edges */
  135. rotz_edg_iter(ctx, iter_dot_cb, ctx);
  136. puts("}");
  137. return;
  138. }
  139. static void
  140. xprt_gml(rotz_t ctx)
  141. {
  142. puts("\
  143. graph [\n\
  144. directed 0\n\
  145. id 0\n");
  146. /* go through all vertices */
  147. rotz_vtx_iter(ctx, iter_gmlv_cb, ctx);
  148. /* go through all edges */
  149. rotz_edg_iter(ctx, iter_gmle_cb, ctx);
  150. puts("]");
  151. return;
  152. }
  153. #if defined STANDALONE
  154. int
  155. rotz_cmd_export(const struct yuck_cmd_export_s argi[static 1U])
  156. {
  157. rotz_t ctx;
  158. if (UNLIKELY((ctx = make_rotz(db)) == NULL)) {
  159. fputs("Error opening rotz datastore\n", stderr);
  160. return 1;
  161. }
  162. /* setting global opts */
  163. clusterp = argi->cluster_flag;
  164. if (argi->gml_flag) {
  165. xprt_gml(ctx);
  166. } else if (argi->dot_flag) {
  167. xprt_dot(ctx);
  168. } else {
  169. /* default file format is csv */
  170. xprt_csv(ctx);
  171. }
  172. /* big rcource freeing */
  173. free_rotz(ctx);
  174. return 0;
  175. }
  176. #endif /* STANDALONE */
  177. /* rotz-export.c ends here */