cvtgxl.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /**
  2. * @file
  3. * @brief <a href=https://en.wikipedia.org/wiki/GXL>GXL</a> converting program
  4. */
  5. /*************************************************************************
  6. * Copyright (c) 2011 AT&T Intellectual Property
  7. * All rights reserved. This program and the accompanying materials
  8. * are made available under the terms of the Eclipse Public License v1.0
  9. * which accompanies this distribution, and is available at
  10. * https://www.eclipse.org/legal/epl-v10.html
  11. *
  12. * Contributors: Details at https://graphviz.org
  13. *************************************************************************/
  14. /*
  15. * Written by Emden R. Gansner and Krishnam Pericherla
  16. */
  17. #include "config.h"
  18. #include <getopt.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include "convert.h"
  22. #include "openFile.h"
  23. #include <cgraph/gv_ctype.h>
  24. #include <cgraph/ingraphs.h>
  25. #include <util/exit.h>
  26. typedef enum { Unset, ToGV, ToGXL } mode;
  27. static FILE *outFile;
  28. static char *CmdName;
  29. static char **Files;
  30. static mode act = Unset;
  31. #ifdef HAVE_EXPAT
  32. static FILE *getFile(void)
  33. {
  34. FILE *rv = NULL;
  35. static FILE *savef = NULL;
  36. static int cnt = 0;
  37. if (Files == NULL) {
  38. if (cnt++ == 0) {
  39. rv = stdin;
  40. }
  41. } else {
  42. if (savef)
  43. fclose(savef);
  44. while (Files[cnt]) {
  45. if ((rv = fopen(Files[cnt++], "r")) != 0)
  46. break;
  47. else
  48. fprintf(stderr, "Can't open %s\n", Files[cnt - 1]);
  49. }
  50. }
  51. savef = rv;
  52. return rv;
  53. }
  54. #endif
  55. static const char *use = "Usage: %s [-gd?] [-o<file>] [<graphs>]\n\
  56. -g : convert to GXL\n\
  57. -d : convert to GV\n\
  58. -o<file> : output to <file> (stdout)\n\
  59. -? : usage\n";
  60. static void usage(int v)
  61. {
  62. fprintf(stderr, use, CmdName);
  63. graphviz_exit(v);
  64. }
  65. static char *cmdName(char *path)
  66. {
  67. char *sp;
  68. sp = strrchr(path, '/');
  69. if (sp)
  70. sp++;
  71. else
  72. sp = path;
  73. #ifdef _WIN32
  74. char *sp2 = strrchr(sp, '\\');
  75. if (sp2 != NULL)
  76. sp = sp2 + 1;
  77. #endif
  78. return sp;
  79. }
  80. static void checkInput(void)
  81. {
  82. char *ep;
  83. ep = strrchr(*Files, '.');
  84. if (!ep)
  85. return;
  86. ep++;
  87. if (strcmp(ep, "gv") == 0)
  88. act = ToGXL;
  89. else if (strcmp(ep, "dot") == 0)
  90. act = ToGXL;
  91. else if (strcmp(ep, "gxl") == 0)
  92. act = ToGV;
  93. }
  94. static void setAction(void)
  95. {
  96. if (gv_tolower(CmdName[0]) == 'd')
  97. act = ToGXL;
  98. else if (gv_tolower(CmdName[0]) == 'g') {
  99. if (gv_tolower(CmdName[1]) == 'v')
  100. act = ToGXL;
  101. else
  102. act = ToGV;
  103. }
  104. else if (Files)
  105. checkInput();
  106. if (act == Unset) {
  107. fprintf(stderr, "Cannot determine conversion type\n");
  108. usage(1);
  109. }
  110. }
  111. static void initargs(int argc, char **argv)
  112. {
  113. int c;
  114. CmdName = cmdName(argv[0]);
  115. opterr = 0;
  116. while ((c = getopt(argc, argv, ":gdo:")) != -1) {
  117. switch (c) {
  118. case 'd':
  119. act = ToGV;
  120. break;
  121. case 'g':
  122. act = ToGXL;
  123. break;
  124. case 'o':
  125. if (outFile != NULL)
  126. fclose(outFile);
  127. outFile = openFile(CmdName, optarg, "w");
  128. break;
  129. case ':':
  130. fprintf(stderr, "%s: option -%c missing argument\n", CmdName, optopt);
  131. break;
  132. case '?':
  133. if (optopt == '?')
  134. usage(0);
  135. else {
  136. fprintf(stderr, "%s: option -%c unrecognized\n", CmdName,
  137. optopt);
  138. graphviz_exit(1);
  139. }
  140. break;
  141. default:
  142. fprintf(stderr, "cvtgxl: unexpected error\n");
  143. graphviz_exit(EXIT_FAILURE);
  144. }
  145. }
  146. argv += optind;
  147. argc -= optind;
  148. if (argc > 0)
  149. Files = argv;
  150. if (!outFile)
  151. outFile = stdout;
  152. if (act == Unset)
  153. setAction();
  154. }
  155. int main(int argc, char **argv)
  156. {
  157. Agraph_t *G;
  158. Agraph_t *prev = 0;
  159. initargs(argc, argv);
  160. if (act == ToGXL) {
  161. ingraph_state ig;
  162. newIngraph(&ig, Files);
  163. while ((G = nextGraph(&ig))) {
  164. if (prev)
  165. agclose(prev);
  166. prev = G;
  167. gv_to_gxl(G, outFile);
  168. fflush(outFile);
  169. }
  170. } else {
  171. #ifdef HAVE_EXPAT
  172. FILE *inFile;
  173. while ((inFile = getFile())) {
  174. while ((G = gxl_to_gv(inFile))) {
  175. if (prev)
  176. agclose(prev);
  177. prev = G;
  178. agwrite(G, outFile);
  179. fflush(outFile);
  180. }
  181. }
  182. #else
  183. fputs("cvtgxl: not configured for conversion from GXL to GV\n",
  184. stderr);
  185. graphviz_exit(1);
  186. #endif
  187. }
  188. graphviz_exit(0);
  189. }