GRASS Programmer's Manual
6.4.2(2012)
|
00001 /* LIBDGL -- a Directed Graph Library implementation 00002 * Copyright (C) 2002 Roberto Micarelli 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00017 */ 00018 00019 /* 00020 * Source best viewed with tabstop=4 00021 */ 00022 00023 #include<stdio.h> 00024 #include<regex.h> 00025 #include<fcntl.h> 00026 #include<stdlib.h> 00027 #include<string.h> 00028 #include<sys/types.h> 00029 #include<sys/stat.h> 00030 #include<unistd.h> 00031 00032 #include "opt.h" 00033 #include "../type.h" 00034 #include "../graph.h" 00035 00036 static void _regmtostring(char *pszOut, int cszOut, char *pszIn, 00037 regmatch_t * pregm) 00038 { 00039 int i, iout; 00040 00041 for (iout = 0, i = pregm->rm_so; i < pregm->rm_eo && iout < cszOut - 1; 00042 i++) { 00043 if (i >= 0) 00044 pszOut[iout++] = pszIn[i]; 00045 } 00046 pszOut[iout] = 0; 00047 } 00048 00049 static int _sztoattr(unsigned char *pbNodeAttr, int cbNodeAttr, char *szw) 00050 { 00051 int i, ib; 00052 00053 for (ib = 0, i = 0; szw[i] && ib < cbNodeAttr; i++) { 00054 if (szw[i] == ' ') 00055 continue; 00056 pbNodeAttr[ib] = (szw[i] >= '0' && 00057 szw[i] <= '9') ? (szw[i] - '0') * 16 : (szw[i] >= 00058 'A' && 00059 szw[i] <= 00060 'F') ? (10 + 00061 (szw 00062 [i] 00063 - 00064 'A')) 00065 * 16 : (szw[i] >= 'a' && 00066 szw[i] <= 'f') ? (10 + (szw[i] - 'a')) * 16 : 0; 00067 i++; 00068 if (szw[i]) { 00069 pbNodeAttr[ib] += (szw[i] >= '0' && 00070 szw[i] <= '9') ? (szw[i] - '0') : (szw[i] >= 00071 'A' && 00072 szw[i] <= 00073 'F') ? (10 + 00074 (szw 00075 [i] 00076 - 00077 'A')) 00078 : (szw[i] >= 'a' && 00079 szw[i] <= 'f') ? (10 + (szw[i] - 'a')) : 0; 00080 } 00081 ib++; 00082 } 00083 return ib; 00084 } 00085 00086 int main(int argc, char **argv) 00087 { 00088 FILE *fp; 00089 char sz[1024]; 00090 char szw[1024]; 00091 int nret; 00092 regmatch_t aregm[64]; 00093 dglInt32_t nVersion; 00094 dglInt32_t nNodeAttrSize; 00095 dglInt32_t nEdgeAttrSize; 00096 dglInt32_t anOpaque[16]; 00097 int i, fd, cOut; 00098 00099 regex_t reVersion; 00100 regex_t reByteOrder; 00101 regex_t reNodeAttrSize; 00102 regex_t reEdgeAttrSize; 00103 regex_t reCounters; 00104 regex_t reOpaque; 00105 regex_t reNodeFrom; 00106 regex_t reNodeAttr; 00107 regex_t reEdge; 00108 regex_t reToNodeAttr; 00109 regex_t reEdgeAttr; 00110 00111 00112 dglInt32_t nNodeFrom, nNodeTo, nUser, nCost; 00113 00114 int fInOpaque; 00115 int fInBody; 00116 00117 unsigned char *pbNodeAttr, *pbEdgeAttr, *pbToNodeAttr; 00118 00119 struct stat statdata; 00120 00121 dglGraph_s graphOut; 00122 00123 /* program options 00124 */ 00125 char *pszFilein; 00126 char *pszGraphout; 00127 00128 GNO_BEGIN /* short long default variable help */ 00129 GNO_OPTION("i", "input", NULL, &pszFilein, "Input text file") 00130 GNO_OPTION("o", "output", NULL, &pszGraphout, "Output graph file") 00131 GNO_END if (GNO_PARSE(argc, argv) < 0) 00132 { 00133 return 1; 00134 } 00135 /* 00136 * options parsed 00137 */ 00138 00139 if (pszFilein == NULL) { 00140 GNO_HELP("... usage"); 00141 return 1; 00142 } 00143 00144 /* 00145 * compile header expressions 00146 */ 00147 printf("Compile header expressions..."); 00148 fflush(stdout); 00149 i = 0; 00150 if (regcomp(&reVersion, "^Version:[ ]+([0-9]+)", REG_EXTENDED) != 0) 00151 goto regc_error; 00152 i++; 00153 if (regcomp(&reByteOrder, "^Byte Order:[ ]+(.+)", REG_EXTENDED) != 0) 00154 goto regc_error; 00155 i++; 00156 if (regcomp 00157 (&reNodeAttrSize, "^Node Attribute Size:[ ]+([0-9]+)", 00158 REG_EXTENDED) != 0) 00159 goto regc_error; 00160 i++; 00161 if (regcomp 00162 (&reEdgeAttrSize, "^Edge Attribute Size:[ ]+([0-9]+)", 00163 REG_EXTENDED) != 0) 00164 goto regc_error; 00165 i++; 00166 if (regcomp(&reCounters, "^Counters:[ ]+.*", REG_EXTENDED) != 0) 00167 goto regc_error; 00168 i++; 00169 if (regcomp(&reOpaque, "^Opaque Settings:", REG_EXTENDED) != 0) 00170 goto regc_error; 00171 i++; 00172 printf("done.\n"); 00173 00174 /* 00175 * compile body expressions 00176 */ 00177 00178 printf("Compile body expressions..."); 00179 fflush(stdout); 00180 if (regcomp(&reNodeFrom, "^HEAD ([0-9]+)[ ]*- [HT/']+", REG_EXTENDED) != 00181 0) 00182 goto regc_error; 00183 i++; 00184 if (regcomp(&reNodeAttr, ".*HEAD ATTR [[]([0-9a-fA-F ]+)]", REG_EXTENDED) 00185 != 0) 00186 goto regc_error; 00187 i++; 00188 00189 if (regcomp 00190 (&reEdge, 00191 "^EDGE #([0-9]+)[ ]*: TAIL ([0-9]+)[ ]*- [HT/']+[ ]+- COST ([0-9]+)[ ]*- ID ([0-9]+)", 00192 REG_EXTENDED) != 0) 00193 goto regc_error; 00194 i++; 00195 if (regcomp 00196 (&reToNodeAttr, ".*TAIL ATTR [[]([0-9a-fA-F ]+)]", REG_EXTENDED) != 0) 00197 goto regc_error; 00198 i++; 00199 if (regcomp(&reEdgeAttr, ".*EDGE ATTR [[]([0-9a-fA-F ]+)]", REG_EXTENDED) 00200 != 0) 00201 goto regc_error; 00202 i++; 00203 00204 printf("done.\n"); 00205 00206 goto regc_ok; 00207 00208 00209 00210 00211 regc_error: 00212 fprintf(stderr, "regex compilation error %d\n", i); 00213 exit(1); 00214 00215 00216 00217 00218 00219 regc_ok: 00220 00221 if ((fp = fopen(pszFilein, "r")) == NULL) { 00222 perror("fopen"); 00223 return 1; 00224 } 00225 00226 fstat(fileno(fp), &statdata); 00227 00228 fInOpaque = 0; 00229 fInBody = 0; 00230 00231 nNodeAttrSize = 0; 00232 nEdgeAttrSize = 0; 00233 pbNodeAttr = NULL; 00234 pbToNodeAttr = NULL; 00235 pbEdgeAttr = NULL; 00236 00237 cOut = 0; 00238 00239 while (fgets(sz, sizeof(sz), fp)) { 00240 #ifndef VERBOSE 00241 if (!(cOut++ % 512) || ftell(fp) == statdata.st_size) 00242 printf("Parse input file ... status: %ld/%ld\r", ftell(fp), 00243 statdata.st_size); 00244 fflush(stdout); 00245 #endif 00246 00247 #ifdef VERYVERBOSE 00248 printf("<<<%s>>>\n", sz); 00249 #endif 00250 if (fInOpaque == 0 && fInBody == 0) { 00251 if (regexec(&reVersion, sz, 64, aregm, 0) == 0) { 00252 _regmtostring(szw, sizeof(szw), sz, &aregm[1]); 00253 nVersion = atoi(szw); 00254 #ifdef VERYVERBOSE 00255 printf("-- version %d\n", nVersion); 00256 #endif 00257 } 00258 else if (regexec(&reByteOrder, sz, 64, aregm, 0) == 0) { 00259 } 00260 else if (regexec(&reNodeAttrSize, sz, 64, aregm, 0) == 0) { 00261 _regmtostring(szw, sizeof(szw), sz, &aregm[1]); 00262 nNodeAttrSize = atoi(szw); 00263 if (nNodeAttrSize) { 00264 pbNodeAttr = (unsigned char *)malloc(nNodeAttrSize); 00265 if (pbNodeAttr == NULL) { 00266 fprintf(stderr, "Memory Exhausted\n"); 00267 exit(1); 00268 } 00269 pbToNodeAttr = (unsigned char *)malloc(nNodeAttrSize); 00270 if (pbToNodeAttr == NULL) { 00271 fprintf(stderr, "Memory Exhausted\n"); 00272 exit(1); 00273 } 00274 } 00275 #ifdef VERYVERBOSE 00276 printf("-- node attr size %d\n", nNodeAttrSize); 00277 #endif 00278 } 00279 else if (regexec(&reEdgeAttrSize, sz, 64, aregm, 0) == 0) { 00280 _regmtostring(szw, sizeof(szw), sz, &aregm[1]); 00281 nEdgeAttrSize = atoi(szw); 00282 if (nEdgeAttrSize > 0) { 00283 pbEdgeAttr = (unsigned char *)malloc(nEdgeAttrSize); 00284 if (pbEdgeAttr == NULL) { 00285 fprintf(stderr, "Memory Exhausted\n"); 00286 exit(1); 00287 } 00288 } 00289 #ifdef VERYVERBOSE 00290 printf("-- edge attr size %d\n", nEdgeAttrSize); 00291 #endif 00292 } 00293 else if (regexec(&reOpaque, sz, 64, aregm, 0) == 0) { 00294 #ifdef VERYVERBOSE 00295 printf("-- opaque...\n"); 00296 #endif 00297 fInOpaque = 1; 00298 } 00299 else if (strncmp(sz, "--", 2) == 0) { 00300 nret = dglInitialize(&graphOut, 00301 nVersion, 00302 nNodeAttrSize, nEdgeAttrSize, anOpaque); 00303 if (nret < 0) { 00304 fprintf(stderr, "dglInitialize error %s\n", 00305 dglStrerror(&graphOut)); 00306 exit(1); 00307 } 00308 #ifdef VERBOSE 00309 printf("Initialize: Version=%ld NodeAttr=%ld EdgeAttr=%ld\n", 00310 nVersion, nNodeAttrSize, nEdgeAttrSize); 00311 #endif 00312 fInBody = 1; 00313 } 00314 } 00315 else if (fInOpaque > 0 && fInBody == 0) { 00316 if (fInOpaque == 1) { 00317 sscanf(sz, "%ld %ld %ld %ld", 00318 &anOpaque[0], 00319 &anOpaque[1], &anOpaque[2], &anOpaque[3]); 00320 fInOpaque++; 00321 #ifdef VERYVERBOSE 00322 printf("opaque 1: %ld %ld %ld %ld\n", 00323 anOpaque[0], anOpaque[1], anOpaque[2], anOpaque[3]); 00324 #endif 00325 00326 } 00327 else if (fInOpaque == 2) { 00328 sscanf(sz, "%ld %ld %ld %ld", 00329 &anOpaque[4], 00330 &anOpaque[5], &anOpaque[6], &anOpaque[7]); 00331 #ifdef VERYVERBOSE 00332 printf("opaque 2: %ld %ld %ld %ld\n", 00333 anOpaque[4], anOpaque[5], anOpaque[6], anOpaque[7]); 00334 #endif 00335 fInOpaque++; 00336 } 00337 else if (fInOpaque == 3) { 00338 sscanf(sz, "%ld %ld %ld %ld", 00339 &anOpaque[8], 00340 &anOpaque[9], &anOpaque[10], &anOpaque[11]); 00341 #ifdef VERYVERBOSE 00342 printf("opaque 3: %ld %ld %ld %ld\n", 00343 anOpaque[8], anOpaque[9], anOpaque[10], anOpaque[11]); 00344 #endif 00345 fInOpaque++; 00346 } 00347 else if (fInOpaque == 4) { 00348 sscanf(sz, "%ld %ld %ld %ld", 00349 &anOpaque[12], 00350 &anOpaque[13], &anOpaque[14], &anOpaque[15]); 00351 #ifdef VERYVERBOSE 00352 printf("opaque 4: %ld %ld %ld %ld\n", 00353 anOpaque[12], 00354 anOpaque[13], anOpaque[14], anOpaque[15]); 00355 #endif 00356 fInOpaque = 0; 00357 } 00358 } 00359 else if (fInBody == 1) { 00360 if (regexec(&reNodeFrom, sz, 64, aregm, 0) == 0) { 00361 _regmtostring(szw, sizeof(szw), sz, &aregm[1]); 00362 #ifdef VERYVERBOSE 00363 printf("node from snippet = %s\n", szw); 00364 #endif 00365 nNodeFrom = atol(szw); 00366 if (nNodeAttrSize > 0) { 00367 if (regexec(&reNodeAttr, sz, 64, aregm, 0) == 0) { 00368 _regmtostring(szw, sizeof(szw), sz, &aregm[1]); 00369 if (_sztoattr(pbNodeAttr, nNodeAttrSize, szw) != 00370 nNodeAttrSize) { 00371 fprintf(stderr, "node attr size mismatch\n"); 00372 } 00373 #ifdef VERYVERBOSE 00374 { 00375 int k; 00376 00377 for (k = 0; k < nNodeAttrSize; k++) { 00378 printf("%02x", pbNodeAttr[k]); 00379 } 00380 printf("\n"); 00381 } 00382 #endif 00383 } 00384 } 00385 } 00386 else if (regexec(&reEdge, sz, 64, aregm, 0) == 0) { 00387 _regmtostring(szw, sizeof(szw), sz, &aregm[2]); 00388 nNodeTo = atol(szw); 00389 _regmtostring(szw, sizeof(szw), sz, &aregm[3]); 00390 nCost = atol(szw); 00391 _regmtostring(szw, sizeof(szw), sz, &aregm[4]); 00392 nUser = atol(szw); 00393 if (nEdgeAttrSize > 0) { 00394 if (regexec(&reEdgeAttr, sz, 64, aregm, 0) == 0) { 00395 _regmtostring(szw, sizeof(szw), sz, &aregm[1]); 00396 if (_sztoattr(pbEdgeAttr, nEdgeAttrSize, szw) != 00397 nEdgeAttrSize) { 00398 fprintf(stderr, "edge attr size mismatch\n"); 00399 } 00400 #ifdef VERYVERBOSE 00401 { 00402 int k; 00403 00404 for (k = 0; k < nEdgeAttrSize; k++) { 00405 printf("%02x", pbEdgeAttr[k]); 00406 } 00407 printf("\n"); 00408 } 00409 #endif 00410 } 00411 } 00412 if (nNodeAttrSize > 0) { 00413 if (regexec(&reToNodeAttr, sz, 64, aregm, 0) == 0) { 00414 _regmtostring(szw, sizeof(szw), sz, &aregm[1]); 00415 if (_sztoattr(pbToNodeAttr, nNodeAttrSize, szw) != 00416 nNodeAttrSize) { 00417 fprintf(stderr, "to node attr size mismatch\n"); 00418 } 00419 #ifdef VERYVERBOSE 00420 { 00421 int k; 00422 00423 for (k = 0; k < nNodeAttrSize; k++) { 00424 printf("%02x", pbToNodeAttr[k]); 00425 } 00426 printf("\n"); 00427 } 00428 #endif 00429 } 00430 } 00431 nret = dglAddEdgeX(&graphOut, 00432 nNodeFrom, 00433 nNodeTo, 00434 nCost, 00435 nUser, 00436 pbNodeAttr, pbToNodeAttr, pbEdgeAttr, 0); 00437 00438 if (nret < 0) { 00439 fprintf(stderr, "dglAddEdge error %s\n", 00440 dglStrerror(&graphOut)); 00441 exit(1); 00442 } 00443 #ifdef VERBOSE 00444 printf("AddEdge: from=%ld to=%ld cost=%ld user=%ld\n", 00445 nNodeFrom, nNodeTo, nCost, nUser); 00446 #endif 00447 } 00448 } 00449 } 00450 #ifndef VERBOSE 00451 printf("\ndone.\n"); 00452 #endif 00453 00454 fclose(fp); 00455 00456 regfree(&reVersion); 00457 regfree(&reByteOrder); 00458 regfree(&reNodeAttrSize); 00459 regfree(&reEdgeAttrSize); 00460 regfree(&reCounters); 00461 regfree(&reOpaque); 00462 regfree(&reNodeFrom); 00463 regfree(&reNodeAttr); 00464 regfree(&reEdge); 00465 regfree(&reToNodeAttr); 00466 regfree(&reEdgeAttr); 00467 00468 if (pbNodeAttr) 00469 free(pbNodeAttr); 00470 if (pbToNodeAttr) 00471 free(pbToNodeAttr); 00472 if (pbEdgeAttr) 00473 free(pbEdgeAttr); 00474 00475 00476 printf("Flatten..."); 00477 fflush(stdout); 00478 nret = dglFlatten(&graphOut); 00479 if (nret < 0) { 00480 fprintf(stderr, "dglFlatten error %s\n", dglStrerror(&graphOut)); 00481 exit(1); 00482 } 00483 printf("done.\n"); 00484 00485 if (pszGraphout) { 00486 fd = open(pszGraphout, O_WRONLY | O_CREAT | O_TRUNC, 0666); 00487 if (fd < 0) { 00488 perror("open"); 00489 exit(1); 00490 } 00491 00492 printf("Write <%s>...", pszGraphout); 00493 fflush(stdout); 00494 nret = dglWrite(&graphOut, fd); 00495 if (nret < 0) { 00496 fprintf(stderr, "dglWrite error %s\n", dglStrerror(&graphOut)); 00497 exit(1); 00498 } 00499 printf("done.\n"); 00500 close(fd); 00501 } 00502 00503 printf("Release..."); 00504 fflush(stdout); 00505 dglRelease(&graphOut); 00506 printf("done.\n"); 00507 00508 return 0; 00509 }