unflatten.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /**
  2. * @file
  3. * @brief adjust directed graphs to improve layout aspect ratio
  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 Stephen North
  16. * Updated by Emden Gansner
  17. */
  18. #include <stdbool.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <cgraph/cgraph.h>
  22. #include <cgraph/ingraphs.h>
  23. #include <getopt.h>
  24. #include "openFile.h"
  25. #include <util/exit.h>
  26. #include <util/unreachable.h>
  27. typedef graphviz_unflatten_options_t opts_t;
  28. static FILE *outFile;
  29. static char *cmd;
  30. static char *useString =
  31. "Usage: %s [-f?] [-l <M>] [-c <N>] [-o <outfile>] <files>\n\
  32. -o <outfile> - put output in <outfile>\n\
  33. -f - adjust immediate fanout chains\n\
  34. -l <M> - stagger length of leaf edges between [1,<M>]\n\
  35. -c <N> - put disconnected nodes in chains of length <N>\n\
  36. -? - print usage\n";
  37. static void usage(int v)
  38. {
  39. fprintf(stderr, useString, cmd);
  40. graphviz_exit(v);
  41. }
  42. static char **scanargs(opts_t *opts, int argc, char **argv) {
  43. int c, ival;
  44. cmd = argv[0];
  45. opterr = 0;
  46. while ((c = getopt(argc, argv, ":fl:c:o:")) != -1) {
  47. switch (c) {
  48. case 'f':
  49. opts->Do_fans = true;
  50. break;
  51. case 'l':
  52. ival = atoi(optarg);
  53. if (ival > 0)
  54. opts->MaxMinlen = ival;
  55. break;
  56. case 'c':
  57. ival = atoi(optarg);
  58. if (ival > 0)
  59. opts->ChainLimit = ival;
  60. break;
  61. case 'o':
  62. if (outFile != NULL)
  63. fclose(outFile);
  64. outFile = openFile(cmd, optarg, "w");
  65. break;
  66. case '?':
  67. if (optopt == '?')
  68. usage(0);
  69. else {
  70. fprintf(stderr, "%s: option -%c unrecognized\n", cmd,
  71. optopt);
  72. usage(-1);
  73. }
  74. break;
  75. case ':':
  76. fprintf(stderr, "%s: missing argument for option -%c\n",
  77. cmd, optopt);
  78. usage(-1);
  79. break;
  80. default:
  81. UNREACHABLE();
  82. }
  83. }
  84. if (opts->Do_fans && opts->MaxMinlen < 1)
  85. fprintf(stderr, "%s: Warning: -f requires -l flag\n", cmd);
  86. argv += optind;
  87. argc -= optind;
  88. if (!outFile)
  89. outFile = stdout;
  90. if (argc)
  91. return argv;
  92. else
  93. return 0;
  94. }
  95. int main(int argc, char **argv)
  96. {
  97. Agraph_t *g;
  98. ingraph_state ig;
  99. char **files;
  100. opts_t opts = {0};
  101. files = scanargs(&opts, argc, argv);
  102. newIngraph(&ig, files);
  103. while ((g = nextGraph(&ig))) {
  104. graphviz_unflatten(g, &opts);
  105. agwrite(g, outFile);
  106. }
  107. graphviz_exit(0);
  108. }