GRASS Programmer's Manual  6.4.2(2012)
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
parse.c
Go to the documentation of this file.
1 /* LIBDGL -- a Directed Graph Library implementation
2  * Copyright (C) 2002 Roberto Micarelli
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 /*
20  * Source best viewed with tabstop=4
21  */
22 
23 #include<stdio.h>
24 #include<regex.h>
25 #include<fcntl.h>
26 #include<stdlib.h>
27 #include<string.h>
28 #include<sys/types.h>
29 #include<sys/stat.h>
30 #include<unistd.h>
31 
32 #include "opt.h"
33 #include "../type.h"
34 #include "../graph.h"
35 
36 static void _regmtostring(char *pszOut, int cszOut, char *pszIn,
37  regmatch_t * pregm)
38 {
39  int i, iout;
40 
41  for (iout = 0, i = pregm->rm_so; i < pregm->rm_eo && iout < cszOut - 1;
42  i++) {
43  if (i >= 0)
44  pszOut[iout++] = pszIn[i];
45  }
46  pszOut[iout] = 0;
47 }
48 
49 static int _sztoattr(unsigned char *pbNodeAttr, int cbNodeAttr, char *szw)
50 {
51  int i, ib;
52 
53  for (ib = 0, i = 0; szw[i] && ib < cbNodeAttr; i++) {
54  if (szw[i] == ' ')
55  continue;
56  pbNodeAttr[ib] = (szw[i] >= '0' &&
57  szw[i] <= '9') ? (szw[i] - '0') * 16 : (szw[i] >=
58  'A' &&
59  szw[i] <=
60  'F') ? (10 +
61  (szw
62  [i]
63  -
64  'A'))
65  * 16 : (szw[i] >= 'a' &&
66  szw[i] <= 'f') ? (10 + (szw[i] - 'a')) * 16 : 0;
67  i++;
68  if (szw[i]) {
69  pbNodeAttr[ib] += (szw[i] >= '0' &&
70  szw[i] <= '9') ? (szw[i] - '0') : (szw[i] >=
71  'A' &&
72  szw[i] <=
73  'F') ? (10 +
74  (szw
75  [i]
76  -
77  'A'))
78  : (szw[i] >= 'a' &&
79  szw[i] <= 'f') ? (10 + (szw[i] - 'a')) : 0;
80  }
81  ib++;
82  }
83  return ib;
84 }
85 
86 int main(int argc, char **argv)
87 {
88  FILE *fp;
89  char sz[1024];
90  char szw[1024];
91  int nret;
92  regmatch_t aregm[64];
93  dglInt32_t nVersion;
94  dglInt32_t nNodeAttrSize;
95  dglInt32_t nEdgeAttrSize;
96  dglInt32_t anOpaque[16];
97  int i, fd, cOut;
98 
99  regex_t reVersion;
100  regex_t reByteOrder;
101  regex_t reNodeAttrSize;
102  regex_t reEdgeAttrSize;
103  regex_t reCounters;
104  regex_t reOpaque;
105  regex_t reNodeFrom;
106  regex_t reNodeAttr;
107  regex_t reEdge;
108  regex_t reToNodeAttr;
109  regex_t reEdgeAttr;
110 
111 
112  dglInt32_t nNodeFrom, nNodeTo, nUser, nCost;
113 
114  int fInOpaque;
115  int fInBody;
116 
117  unsigned char *pbNodeAttr, *pbEdgeAttr, *pbToNodeAttr;
118 
119  struct stat statdata;
120 
121  dglGraph_s graphOut;
122 
123  /* program options
124  */
125  char *pszFilein;
126  char *pszGraphout;
127 
128  GNO_BEGIN /* short long default variable help */
129  GNO_OPTION("i", "input", NULL, &pszFilein, "Input text file")
130  GNO_OPTION("o", "output", NULL, &pszGraphout, "Output graph file")
131  GNO_END if (GNO_PARSE(argc, argv) < 0)
132  {
133  return 1;
134  }
135  /*
136  * options parsed
137  */
138 
139  if (pszFilein == NULL) {
140  GNO_HELP("... usage");
141  return 1;
142  }
143 
144  /*
145  * compile header expressions
146  */
147  printf("Compile header expressions...");
148  fflush(stdout);
149  i = 0;
150  if (regcomp(&reVersion, "^Version:[ ]+([0-9]+)", REG_EXTENDED) != 0)
151  goto regc_error;
152  i++;
153  if (regcomp(&reByteOrder, "^Byte Order:[ ]+(.+)", REG_EXTENDED) != 0)
154  goto regc_error;
155  i++;
156  if (regcomp
157  (&reNodeAttrSize, "^Node Attribute Size:[ ]+([0-9]+)",
158  REG_EXTENDED) != 0)
159  goto regc_error;
160  i++;
161  if (regcomp
162  (&reEdgeAttrSize, "^Edge Attribute Size:[ ]+([0-9]+)",
163  REG_EXTENDED) != 0)
164  goto regc_error;
165  i++;
166  if (regcomp(&reCounters, "^Counters:[ ]+.*", REG_EXTENDED) != 0)
167  goto regc_error;
168  i++;
169  if (regcomp(&reOpaque, "^Opaque Settings:", REG_EXTENDED) != 0)
170  goto regc_error;
171  i++;
172  printf("done.\n");
173 
174  /*
175  * compile body expressions
176  */
177 
178  printf("Compile body expressions...");
179  fflush(stdout);
180  if (regcomp(&reNodeFrom, "^HEAD ([0-9]+)[ ]*- [HT/']+", REG_EXTENDED) !=
181  0)
182  goto regc_error;
183  i++;
184  if (regcomp(&reNodeAttr, ".*HEAD ATTR [[]([0-9a-fA-F ]+)]", REG_EXTENDED)
185  != 0)
186  goto regc_error;
187  i++;
188 
189  if (regcomp
190  (&reEdge,
191  "^EDGE #([0-9]+)[ ]*: TAIL ([0-9]+)[ ]*- [HT/']+[ ]+- COST ([0-9]+)[ ]*- ID ([0-9]+)",
192  REG_EXTENDED) != 0)
193  goto regc_error;
194  i++;
195  if (regcomp
196  (&reToNodeAttr, ".*TAIL ATTR [[]([0-9a-fA-F ]+)]", REG_EXTENDED) != 0)
197  goto regc_error;
198  i++;
199  if (regcomp(&reEdgeAttr, ".*EDGE ATTR [[]([0-9a-fA-F ]+)]", REG_EXTENDED)
200  != 0)
201  goto regc_error;
202  i++;
203 
204  printf("done.\n");
205 
206  goto regc_ok;
207 
208 
209 
210 
211  regc_error:
212  fprintf(stderr, "regex compilation error %d\n", i);
213  exit(1);
214 
215 
216 
217 
218 
219  regc_ok:
220 
221  if ((fp = fopen(pszFilein, "r")) == NULL) {
222  perror("fopen");
223  return 1;
224  }
225 
226  fstat(fileno(fp), &statdata);
227 
228  fInOpaque = 0;
229  fInBody = 0;
230 
231  nNodeAttrSize = 0;
232  nEdgeAttrSize = 0;
233  pbNodeAttr = NULL;
234  pbToNodeAttr = NULL;
235  pbEdgeAttr = NULL;
236 
237  cOut = 0;
238 
239  while (fgets(sz, sizeof(sz), fp)) {
240 #ifndef VERBOSE
241  if (!(cOut++ % 512) || ftell(fp) == statdata.st_size)
242  printf("Parse input file ... status: %ld/%ld\r", ftell(fp),
243  statdata.st_size);
244  fflush(stdout);
245 #endif
246 
247 #ifdef VERYVERBOSE
248  printf("<<<%s>>>\n", sz);
249 #endif
250  if (fInOpaque == 0 && fInBody == 0) {
251  if (regexec(&reVersion, sz, 64, aregm, 0) == 0) {
252  _regmtostring(szw, sizeof(szw), sz, &aregm[1]);
253  nVersion = atoi(szw);
254 #ifdef VERYVERBOSE
255  printf("-- version %d\n", nVersion);
256 #endif
257  }
258  else if (regexec(&reByteOrder, sz, 64, aregm, 0) == 0) {
259  }
260  else if (regexec(&reNodeAttrSize, sz, 64, aregm, 0) == 0) {
261  _regmtostring(szw, sizeof(szw), sz, &aregm[1]);
262  nNodeAttrSize = atoi(szw);
263  if (nNodeAttrSize) {
264  pbNodeAttr = (unsigned char *)malloc(nNodeAttrSize);
265  if (pbNodeAttr == NULL) {
266  fprintf(stderr, "Memory Exhausted\n");
267  exit(1);
268  }
269  pbToNodeAttr = (unsigned char *)malloc(nNodeAttrSize);
270  if (pbToNodeAttr == NULL) {
271  fprintf(stderr, "Memory Exhausted\n");
272  exit(1);
273  }
274  }
275 #ifdef VERYVERBOSE
276  printf("-- node attr size %d\n", nNodeAttrSize);
277 #endif
278  }
279  else if (regexec(&reEdgeAttrSize, sz, 64, aregm, 0) == 0) {
280  _regmtostring(szw, sizeof(szw), sz, &aregm[1]);
281  nEdgeAttrSize = atoi(szw);
282  if (nEdgeAttrSize > 0) {
283  pbEdgeAttr = (unsigned char *)malloc(nEdgeAttrSize);
284  if (pbEdgeAttr == NULL) {
285  fprintf(stderr, "Memory Exhausted\n");
286  exit(1);
287  }
288  }
289 #ifdef VERYVERBOSE
290  printf("-- edge attr size %d\n", nEdgeAttrSize);
291 #endif
292  }
293  else if (regexec(&reOpaque, sz, 64, aregm, 0) == 0) {
294 #ifdef VERYVERBOSE
295  printf("-- opaque...\n");
296 #endif
297  fInOpaque = 1;
298  }
299  else if (strncmp(sz, "--", 2) == 0) {
300  nret = dglInitialize(&graphOut,
301  nVersion,
302  nNodeAttrSize, nEdgeAttrSize, anOpaque);
303  if (nret < 0) {
304  fprintf(stderr, "dglInitialize error %s\n",
305  dglStrerror(&graphOut));
306  exit(1);
307  }
308 #ifdef VERBOSE
309  printf("Initialize: Version=%ld NodeAttr=%ld EdgeAttr=%ld\n",
310  nVersion, nNodeAttrSize, nEdgeAttrSize);
311 #endif
312  fInBody = 1;
313  }
314  }
315  else if (fInOpaque > 0 && fInBody == 0) {
316  if (fInOpaque == 1) {
317  sscanf(sz, "%ld %ld %ld %ld",
318  &anOpaque[0],
319  &anOpaque[1], &anOpaque[2], &anOpaque[3]);
320  fInOpaque++;
321 #ifdef VERYVERBOSE
322  printf("opaque 1: %ld %ld %ld %ld\n",
323  anOpaque[0], anOpaque[1], anOpaque[2], anOpaque[3]);
324 #endif
325 
326  }
327  else if (fInOpaque == 2) {
328  sscanf(sz, "%ld %ld %ld %ld",
329  &anOpaque[4],
330  &anOpaque[5], &anOpaque[6], &anOpaque[7]);
331 #ifdef VERYVERBOSE
332  printf("opaque 2: %ld %ld %ld %ld\n",
333  anOpaque[4], anOpaque[5], anOpaque[6], anOpaque[7]);
334 #endif
335  fInOpaque++;
336  }
337  else if (fInOpaque == 3) {
338  sscanf(sz, "%ld %ld %ld %ld",
339  &anOpaque[8],
340  &anOpaque[9], &anOpaque[10], &anOpaque[11]);
341 #ifdef VERYVERBOSE
342  printf("opaque 3: %ld %ld %ld %ld\n",
343  anOpaque[8], anOpaque[9], anOpaque[10], anOpaque[11]);
344 #endif
345  fInOpaque++;
346  }
347  else if (fInOpaque == 4) {
348  sscanf(sz, "%ld %ld %ld %ld",
349  &anOpaque[12],
350  &anOpaque[13], &anOpaque[14], &anOpaque[15]);
351 #ifdef VERYVERBOSE
352  printf("opaque 4: %ld %ld %ld %ld\n",
353  anOpaque[12],
354  anOpaque[13], anOpaque[14], anOpaque[15]);
355 #endif
356  fInOpaque = 0;
357  }
358  }
359  else if (fInBody == 1) {
360  if (regexec(&reNodeFrom, sz, 64, aregm, 0) == 0) {
361  _regmtostring(szw, sizeof(szw), sz, &aregm[1]);
362 #ifdef VERYVERBOSE
363  printf("node from snippet = %s\n", szw);
364 #endif
365  nNodeFrom = atol(szw);
366  if (nNodeAttrSize > 0) {
367  if (regexec(&reNodeAttr, sz, 64, aregm, 0) == 0) {
368  _regmtostring(szw, sizeof(szw), sz, &aregm[1]);
369  if (_sztoattr(pbNodeAttr, nNodeAttrSize, szw) !=
370  nNodeAttrSize) {
371  fprintf(stderr, "node attr size mismatch\n");
372  }
373 #ifdef VERYVERBOSE
374  {
375  int k;
376 
377  for (k = 0; k < nNodeAttrSize; k++) {
378  printf("%02x", pbNodeAttr[k]);
379  }
380  printf("\n");
381  }
382 #endif
383  }
384  }
385  }
386  else if (regexec(&reEdge, sz, 64, aregm, 0) == 0) {
387  _regmtostring(szw, sizeof(szw), sz, &aregm[2]);
388  nNodeTo = atol(szw);
389  _regmtostring(szw, sizeof(szw), sz, &aregm[3]);
390  nCost = atol(szw);
391  _regmtostring(szw, sizeof(szw), sz, &aregm[4]);
392  nUser = atol(szw);
393  if (nEdgeAttrSize > 0) {
394  if (regexec(&reEdgeAttr, sz, 64, aregm, 0) == 0) {
395  _regmtostring(szw, sizeof(szw), sz, &aregm[1]);
396  if (_sztoattr(pbEdgeAttr, nEdgeAttrSize, szw) !=
397  nEdgeAttrSize) {
398  fprintf(stderr, "edge attr size mismatch\n");
399  }
400 #ifdef VERYVERBOSE
401  {
402  int k;
403 
404  for (k = 0; k < nEdgeAttrSize; k++) {
405  printf("%02x", pbEdgeAttr[k]);
406  }
407  printf("\n");
408  }
409 #endif
410  }
411  }
412  if (nNodeAttrSize > 0) {
413  if (regexec(&reToNodeAttr, sz, 64, aregm, 0) == 0) {
414  _regmtostring(szw, sizeof(szw), sz, &aregm[1]);
415  if (_sztoattr(pbToNodeAttr, nNodeAttrSize, szw) !=
416  nNodeAttrSize) {
417  fprintf(stderr, "to node attr size mismatch\n");
418  }
419 #ifdef VERYVERBOSE
420  {
421  int k;
422 
423  for (k = 0; k < nNodeAttrSize; k++) {
424  printf("%02x", pbToNodeAttr[k]);
425  }
426  printf("\n");
427  }
428 #endif
429  }
430  }
431  nret = dglAddEdgeX(&graphOut,
432  nNodeFrom,
433  nNodeTo,
434  nCost,
435  nUser,
436  pbNodeAttr, pbToNodeAttr, pbEdgeAttr, 0);
437 
438  if (nret < 0) {
439  fprintf(stderr, "dglAddEdge error %s\n",
440  dglStrerror(&graphOut));
441  exit(1);
442  }
443 #ifdef VERBOSE
444  printf("AddEdge: from=%ld to=%ld cost=%ld user=%ld\n",
445  nNodeFrom, nNodeTo, nCost, nUser);
446 #endif
447  }
448  }
449  }
450 #ifndef VERBOSE
451  printf("\ndone.\n");
452 #endif
453 
454  fclose(fp);
455 
456  regfree(&reVersion);
457  regfree(&reByteOrder);
458  regfree(&reNodeAttrSize);
459  regfree(&reEdgeAttrSize);
460  regfree(&reCounters);
461  regfree(&reOpaque);
462  regfree(&reNodeFrom);
463  regfree(&reNodeAttr);
464  regfree(&reEdge);
465  regfree(&reToNodeAttr);
466  regfree(&reEdgeAttr);
467 
468  if (pbNodeAttr)
469  free(pbNodeAttr);
470  if (pbToNodeAttr)
471  free(pbToNodeAttr);
472  if (pbEdgeAttr)
473  free(pbEdgeAttr);
474 
475 
476  printf("Flatten...");
477  fflush(stdout);
478  nret = dglFlatten(&graphOut);
479  if (nret < 0) {
480  fprintf(stderr, "dglFlatten error %s\n", dglStrerror(&graphOut));
481  exit(1);
482  }
483  printf("done.\n");
484 
485  if (pszGraphout) {
486  fd = open(pszGraphout, O_WRONLY | O_CREAT | O_TRUNC, 0666);
487  if (fd < 0) {
488  perror("open");
489  exit(1);
490  }
491 
492  printf("Write <%s>...", pszGraphout);
493  fflush(stdout);
494  nret = dglWrite(&graphOut, fd);
495  if (nret < 0) {
496  fprintf(stderr, "dglWrite error %s\n", dglStrerror(&graphOut));
497  exit(1);
498  }
499  printf("done.\n");
500  close(fd);
501  }
502 
503  printf("Release...");
504  fflush(stdout);
505  dglRelease(&graphOut);
506  printf("done.\n");
507 
508  return 0;
509 }