1 /* blisstog.c version 1.0; B D McKay, Sep 2012. */
2
3 #define USAGE "blisstog [-n#:#] [infile]*"
4
5 #define HELPTEXT \
6 " Read files of graphs in Bliss (Dimacs) format and write\n\
7 them to stdout in sparse6 format.\n\
8 \n\
9 -n#:# Specify a range of n values for output\n\
10 Input files with name *.gz are ungzipped\n"
11
12 #define ZCAT "gunzip -c" /* name of zcat command (might be "gunzip -c") */
13
14 /*************************************************************************/
15
16 #include "gtools.h"
17
18 typedef struct
19 {
20 int v,w;
21 } vpair;
22
23 static int
nextchar(FILE * f)24 nextchar(FILE *f)
25 {
26 char s[2];
27
28 if (fscanf(f,"%1s",s) != 1) return EOF;
29 else return s[0];
30 }
31
32 static boolean
readblissgraph(FILE * f,sparsegraph * g)33 readblissgraph(FILE *f, sparsegraph *g)
34 /* Reads a graph from Bliss format into a sparse graph */
35 {
36 int n,c;
37 unsigned long ne,j;
38 int haven;
39 int i,v,w;
40 int haveptn;
41 DYNALLSTAT(vpair,elist,elist_sz);
42
43 haven = 0;
44 j = 0;
45 while ((c = nextchar(f)) >= 0)
46 {
47 switch (c)
48 {
49 case 'c':
50 while ((c = getc(f)) != '\n' && c != EOF) {}
51 break;
52
53 case 'p':
54 if (haven)
55 {
56 fprintf(stderr,"Duplicate p line\n");
57 exit(1);
58 }
59 if (fscanf(f," edge %d %lu",&n,&ne) != 2)
60 {
61 fprintf(stderr,"Bad p line\n");
62 return FALSE;
63 }
64 haven = 1;
65 DYNALLOC1(vpair,elist,elist_sz,ne,"Alloc vpair");
66 break;
67
68 case 'n':
69 if (!haven)
70 {
71 fprintf(stderr,"Missing p line\n");
72 return FALSE;
73 }
74 if (fscanf(f,"%d%d",&w,&v) != 2 || w < 1 || w > n)
75 {
76 fprintf(stderr,"Bad n line\n");
77 return FALSE;
78 }
79 break;
80
81 case 'e':
82 if (!haven || j == ne)
83 {
84 fprintf(stderr,"Missing p line or too many e lines\n");
85 return FALSE;
86 }
87 if (fscanf(f,"%d%d",&v,&w) != 2 || v < 1 || w < 1 || v > n || w > n)
88 {
89 fprintf(stderr,"Bad e line\n");
90 return FALSE;
91 }
92 elist[j].v = v-1; elist[j].w = w-1;
93 ++j;
94 break;
95
96 default:
97 fprintf(stderr,"Unknown line %c\n",c);
98 return FALSE;
99 }
100 }
101
102 if (j != ne)
103 {
104 fprintf(stderr,"Wrong number of e lines\n");
105 exit(1);
106 }
107
108 SG_ALLOC(*g,n,2*ne,"SG_ALLOC");
109 g->nv = n;
110 g->nde = 2*ne;
111
112 for (i = 0; i < n; ++i) g->d[i] = 0;
113 for (j = 0; j < ne; ++j)
114 {
115 ++(g->d[elist[j].v]);
116 ++(g->d[elist[j].w]);
117 }
118 g->v[0] = 0;
119 for (i = 1; i < n; ++i) g->v[i] = g->v[i-1] + g->d[i-1];
120 for (i = 0; i < n; ++i) g->d[i] = 0;
121
122 for (j = 0; j < ne; ++j)
123 {
124 v = elist[j].v;
125 w = elist[j].w;
126 g->e[g->v[v]+(g->d[v])++] = w;
127 g->e[g->v[w]+(g->d[w])++] = v;
128 }
129
130 return TRUE;
131 }
132
133 /**************************************************************************/
134
135 int
main(int argc,char * argv[])136 main(int argc, char *argv[])
137 {
138 FILE *infile;
139 int j,firstarg;
140 SG_DECL(g);
141 size_t flen;
142 boolean ispipe;
143 int nmin,nmax;
144 char zcmd[515];
145
146 HELP; PUTVERSION;
147
148 nmax = -1;
149 if (argc >= 2 && argv[1][0] == '-' && argv[1][1] == 'n')
150 {
151 if (sscanf(argv[1]+2,"%d:%d",&nmin,&nmax) == 2) {}
152 else if (sscanf(argv[1]+2,":%d",&nmax) == 1) { nmin = 1; }
153 else if (sscanf(argv[1]+2,"%d:",&nmin) == 1) { nmax = NAUTY_INFINITY; }
154 else gt_abort(">E blisstog: bad -n switch\n");
155
156 firstarg = 2;
157 }
158 else
159 firstarg = 1;
160
161 if (argc == firstarg)
162 {
163 if (!readblissgraph(stdin,&g))
164 {
165 fprintf(stderr,">E Bliss error in file %s\n","stdin");
166 gt_abort(NULL);
167 }
168 else
169 writes6_sg(stdout,&g);
170 }
171 else
172 {
173 for (j = firstarg; j < argc; ++j)
174 {
175 flen = strlen(argv[j]);
176 if (flen >= 3 && strcmp(argv[j]+flen-3,".gz") == 0)
177 {
178 sprintf(zcmd,"%s \"%s\"",ZCAT,argv[j]);
179 if ((infile = popen(zcmd,"r")) == NULL)
180 {
181 fprintf(stderr,
182 ">E blisstog: cannot open zcat pipe for \"%s\"\n",
183 argv[j]);
184 gt_abort(NULL);
185 }
186 ispipe = TRUE;
187 }
188 else
189 {
190 if ((infile = fopen(argv[j],"r")) == NULL)
191 {
192 fprintf(stderr,">E Can't open file %s\n",argv[j]);
193 gt_abort(NULL);
194 }
195 ispipe = FALSE;
196 }
197
198 if (!readblissgraph(infile,&g))
199 {
200 fprintf(stderr,">E Bliss error in file %s\n",argv[j]);
201 gt_abort(NULL);
202 }
203 else if (nmax < 0 || (g.nv >= nmin && g.nv <= nmax))
204 {
205 sortlists_sg(&g);
206 writes6_sg(stdout,&g);
207 }
208
209 if (ispipe) pclose(infile); else fclose(infile);
210 }
211 }
212
213 exit(0);
214 }
215