~ubuntu-branches/ubuntu/lucid/graphviz/lucid-security

« back to all changes in this revision

Viewing changes to tools/src/ccomps.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephen M Moraco
  • Date: 2002-02-05 18:52:12 UTC
  • Revision ID: james.westby@ubuntu.com-20020205185212-8i04c70te00rc40y
Tags: upstream-1.7.16
ImportĀ upstreamĀ versionĀ 1.7.16

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    This software may only be used by you under license from AT&T Corp.
 
3
    ("AT&T").  A copy of AT&T's Source Code Agreement is available at
 
4
    AT&T's Internet website having the URL:
 
5
    <http://www.research.att.com/sw/tools/graphviz/license/source.html>
 
6
    If you received this software without first entering into a license
 
7
    with AT&T, you have an infringing copy of this software and cannot use
 
8
    it without violating AT&T's intellectual property rights.
 
9
*/
 
10
 
 
11
/*
 
12
 * Written by Stephen North
 
13
 * Updated by Emden Gansner
 
14
 */
 
15
 
 
16
typedef char Agraphinfo_t;
 
17
typedef struct Agnodeinfo_t { char mark; } Agnodeinfo_t;
 
18
typedef char Agedgeinfo_t;
 
19
 
 
20
#include <graph.h>
 
21
#include <unistd.h>
 
22
#include <string.h>
 
23
#include <ingraphs.h>
 
24
 
 
25
#ifdef NO_OPTOPT_DECL
 
26
#include "getopt.h"
 
27
#endif
 
28
 
 
29
#define INTERNAL 0
 
30
#define EXTERNAL 1
 
31
#define SILENT   2
 
32
 
 
33
char** Files;
 
34
int    verbose;
 
35
int    printMode = INTERNAL;
 
36
char*  suffix = 0;
 
37
char*  outfile = 0;
 
38
char*  path = 0;
 
39
int    sufcnt = 0;
 
40
 
 
41
static char* useString = 
 
42
"Usage: ccomps [-svx?] [-o <out template>] <files>\n\
 
43
  -s - silent\n\
 
44
  -x - external\n\
 
45
  -v - verbose\n\
 
46
  -o - output file template\n\
 
47
  -? - print usage\n\
 
48
If no files are specified, stdin is used\n";
 
49
 
 
50
static void
 
51
usage (int v)
 
52
{
 
53
    printf (useString);
 
54
    exit (v);
 
55
}
 
56
 
 
57
static void
 
58
split (char* name)
 
59
{
 
60
  char* sfx = 0;
 
61
  int   size;
 
62
 
 
63
  sfx = strrchr (name, '.');
 
64
  if (sfx) {
 
65
    suffix = sfx+1;
 
66
    size = sfx-name;
 
67
    path = (char*)malloc (size+1);
 
68
    strncpy (path, name, size);
 
69
    *(path+size) = '\0';
 
70
  }
 
71
  else {
 
72
    path = name;
 
73
  }
 
74
}
 
75
 
 
76
static void
 
77
init (int argc, char* argv[])
 
78
{
 
79
  int c;
 
80
 
 
81
  aginit ();
 
82
  while ((c = getopt(argc, argv, ":o:xsv?")) != -1) {
 
83
    switch (c) {
 
84
    case 'o':
 
85
      outfile = optarg;
 
86
      split (outfile);
 
87
      break;
 
88
    case 'x':
 
89
      printMode = EXTERNAL;
 
90
      break;
 
91
    case 's':
 
92
      printMode = SILENT;
 
93
      verbose = 1;
 
94
      break;
 
95
    case 'v':
 
96
      verbose = 1;
 
97
      break;
 
98
    case '?':
 
99
      if (optopt == '?') usage(0);
 
100
      else fprintf(stderr,"ccomps: option -%c unrecognized - ignored\n", c);
 
101
      break;
 
102
    }
 
103
  }
 
104
  argv += optind;
 
105
  argc -= optind;
 
106
  
 
107
  if (argc) Files = argv;
 
108
}
 
109
 
 
110
static int
 
111
dfs(Agraph_t* g, Agnode_t* n, Agraph_t* out, int cnt)
 
112
{
 
113
  Agedge_t    *e;
 
114
  Agnode_t    *other;
 
115
 
 
116
  n->u.mark = 1;
 
117
  cnt++;
 
118
  aginsert(out,n);
 
119
  for (e = agfstedge(g,n); e ; e = agnxtedge(g,e,n)) {
 
120
    if ((other = e->tail) == n) other = e->head;
 
121
    if (other->u.mark == 0) cnt = dfs(g,other,out,cnt);
 
122
  }
 
123
  return cnt;
 
124
}
 
125
 
 
126
static int
 
127
nodeInduce (Agraph_t* g)
 
128
{
 
129
  Agnode_t    *n;
 
130
  Agedge_t    *e;
 
131
  int          e_cnt = 0;
 
132
 
 
133
  for (n = agfstnode(g); n; n = agnxtnode(g,n)) {
 
134
    for (e = agfstout(g->root,n); e; e = agnxtout(g->root,e)) {
 
135
      if (agcontains(g,e->head)) {
 
136
        aginsert(g,e);
 
137
        e_cnt++;
 
138
      }
 
139
    }
 
140
  }
 
141
  return e_cnt;
 
142
}
 
143
 
 
144
static char*
 
145
getName ()
 
146
{
 
147
  char* name;
 
148
  static char* buf = 0;
 
149
 
 
150
  if (sufcnt == 0) name = outfile;
 
151
  else {
 
152
    if (!buf) 
 
153
      buf = (char*)malloc(strlen(outfile)+20); /* enough to handle '_number' */
 
154
    if (suffix) sprintf (buf, "%s_%d.%s", path, sufcnt, suffix);
 
155
    else sprintf (buf, "%s_%d", path, sufcnt);
 
156
    name = buf;
 
157
  }
 
158
  sufcnt++;
 
159
  return name;
 
160
}
 
161
 
 
162
static void
 
163
gwrite (Agraph_t* g)
 
164
{
 
165
  FILE* outf;
 
166
  char* name;
 
167
 
 
168
  if (!outfile) agwrite (g, stdout);
 
169
  else {
 
170
    name = getName();
 
171
    outf = fopen (name, "w");
 
172
    if (!outf) {
 
173
      fprintf (stderr, "Could not open %s for writing\n", name);
 
174
      perror ("ccomps");
 
175
    }
 
176
    agwrite (g, outf);
 
177
    fclose (outf);
 
178
  }
 
179
}
 
180
 
 
181
static void
 
182
process (Agraph_t* g)
 
183
{
 
184
  long        n_cnt,c_cnt,e_cnt;
 
185
  char        name[64];
 
186
  Agraph_t    *out;
 
187
  Agnode_t    *n;
 
188
 
 
189
  c_cnt = 0;
 
190
  for (n = agfstnode(g); n; n = agnxtnode(g,n)) {
 
191
    if (n->u.mark) continue;
 
192
    sprintf(name,"%s_component_%d",g->name,c_cnt);
 
193
    out = agsubg(g,name);
 
194
    n_cnt = dfs(g,n,out,0);
 
195
    e_cnt = nodeInduce(out);
 
196
    if (printMode == EXTERNAL) gwrite(out);
 
197
    if (printMode != INTERNAL)
 
198
      agdelete (g, out);
 
199
    if (verbose)
 
200
      fprintf(stderr,"(%4d) %7ld nodes %7ld edges\n",
 
201
        c_cnt, n_cnt, e_cnt);
 
202
    c_cnt++;
 
203
  }
 
204
 
 
205
  if (printMode == INTERNAL) gwrite(g);
 
206
 
 
207
  if(verbose)
 
208
    fprintf(stderr,"       %7ld nodes %7ld edges %7ld components %s\n",
 
209
      agnnodes(g),agnedges(g),c_cnt,g->name);
 
210
}
 
211
 
 
212
int
 
213
main (int argc, char* argv[])
 
214
{
 
215
  Agraph_t*     g;
 
216
  ingraph_state ig;
 
217
 
 
218
  init (argc, argv);
 
219
  newIngraph (&ig, Files, agread);
 
220
  
 
221
  while ((g = nextGraph(&ig)) != 0) {
 
222
      process (g);
 
223
      agclose (g);
 
224
  }
 
225
 
 
226
  return 0;
 
227
}
 
228