/* LIBDGL -- a Directed Graph Library implementation * Copyright (C) 2002 Roberto Micarelli * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* * Source best viewed with tabstop=4 */ #include #include #include #include #include #include #include #include #include #include "opt.h" #include "../type.h" #include "../graph.h" static void _regmtostring(char *pszOut, int cszOut, char *pszIn, regmatch_t * pregm) { int i, iout; for (iout = 0, i = pregm->rm_so; i < pregm->rm_eo && iout < cszOut - 1; i++) { if (i >= 0) pszOut[iout++] = pszIn[i]; } pszOut[iout] = 0; } static int _sztoattr(unsigned char *pbNodeAttr, int cbNodeAttr, char *szw) { int i, ib; for (ib = 0, i = 0; szw[i] && ib < cbNodeAttr; i++) { if (szw[i] == ' ') continue; pbNodeAttr[ib] = (szw[i] >= '0' && szw[i] <= '9') ? (szw[i] - '0') * 16 : (szw[i] >= 'A' && szw[i] <= 'F') ? (10 + (szw [i] - 'A')) * 16 : (szw[i] >= 'a' && szw[i] <= 'f') ? (10 + (szw[i] - 'a')) * 16 : 0; i++; if (szw[i]) { pbNodeAttr[ib] += (szw[i] >= '0' && szw[i] <= '9') ? (szw[i] - '0') : (szw[i] >= 'A' && szw[i] <= 'F') ? (10 + (szw [i] - 'A')) : (szw[i] >= 'a' && szw[i] <= 'f') ? (10 + (szw[i] - 'a')) : 0; } ib++; } return ib; } int main(int argc, char **argv) { FILE *fp; char sz[1024]; char szw[1024]; int nret; regmatch_t aregm[64]; dglInt32_t nVersion; dglInt32_t nNodeAttrSize; dglInt32_t nEdgeAttrSize; dglInt32_t anOpaque[16]; int i, fd, cOut; regex_t reVersion; regex_t reByteOrder; regex_t reNodeAttrSize; regex_t reEdgeAttrSize; regex_t reCounters; regex_t reOpaque; regex_t reNodeFrom; regex_t reNodeAttr; regex_t reEdge; regex_t reToNodeAttr; regex_t reEdgeAttr; dglInt32_t nNodeFrom, nNodeTo, nUser, nCost; int fInOpaque; int fInBody; unsigned char *pbNodeAttr, *pbEdgeAttr, *pbToNodeAttr; struct stat statdata; dglGraph_s graphOut; /* program options */ char *pszFilein; char *pszGraphout; GNO_BEGIN /* short long default variable help */ GNO_OPTION("i", "input", NULL, &pszFilein, "Input text file") GNO_OPTION("o", "output", NULL, &pszGraphout, "Output graph file") GNO_END if (GNO_PARSE(argc, argv) < 0) { return 1; } /* * options parsed */ if (pszFilein == NULL) { GNO_HELP("... usage"); return 1; } /* * compile header expressions */ printf("Compile header expressions..."); fflush(stdout); i = 0; if (regcomp(&reVersion, "^Version:[ ]+([0-9]+)", REG_EXTENDED) != 0) goto regc_error; i++; if (regcomp(&reByteOrder, "^Byte Order:[ ]+(.+)", REG_EXTENDED) != 0) goto regc_error; i++; if (regcomp (&reNodeAttrSize, "^Node Attribute Size:[ ]+([0-9]+)", REG_EXTENDED) != 0) goto regc_error; i++; if (regcomp (&reEdgeAttrSize, "^Edge Attribute Size:[ ]+([0-9]+)", REG_EXTENDED) != 0) goto regc_error; i++; if (regcomp(&reCounters, "^Counters:[ ]+.*", REG_EXTENDED) != 0) goto regc_error; i++; if (regcomp(&reOpaque, "^Opaque Settings:", REG_EXTENDED) != 0) goto regc_error; i++; printf("done.\n"); /* * compile body expressions */ printf("Compile body expressions..."); fflush(stdout); if (regcomp(&reNodeFrom, "^HEAD ([0-9]+)[ ]*- [HT/']+", REG_EXTENDED) != 0) goto regc_error; i++; if (regcomp(&reNodeAttr, ".*HEAD ATTR [[]([0-9a-fA-F ]+)]", REG_EXTENDED) != 0) goto regc_error; i++; if (regcomp (&reEdge, "^EDGE #([0-9]+)[ ]*: TAIL ([0-9]+)[ ]*- [HT/']+[ ]+- COST ([0-9]+)[ ]*- ID ([0-9]+)", REG_EXTENDED) != 0) goto regc_error; i++; if (regcomp (&reToNodeAttr, ".*TAIL ATTR [[]([0-9a-fA-F ]+)]", REG_EXTENDED) != 0) goto regc_error; i++; if (regcomp(&reEdgeAttr, ".*EDGE ATTR [[]([0-9a-fA-F ]+)]", REG_EXTENDED) != 0) goto regc_error; i++; printf("done.\n"); goto regc_ok; regc_error: fprintf(stderr, "regex compilation error %d\n", i); exit(1); regc_ok: if ((fp = fopen(pszFilein, "r")) == NULL) { perror("fopen"); return 1; } fstat(fileno(fp), &statdata); fInOpaque = 0; fInBody = 0; nNodeAttrSize = 0; nEdgeAttrSize = 0; pbNodeAttr = NULL; pbToNodeAttr = NULL; pbEdgeAttr = NULL; cOut = 0; while (fgets(sz, sizeof(sz), fp)) { #ifndef VERBOSE if (!(cOut++ % 512) || G_ftell(fp) == statdata.st_size) printf("Parse input file ... status: %ld/%ld\r", G_ftell(fp), statdata.st_size); fflush(stdout); #endif #ifdef VERYVERBOSE printf("<<<%s>>>\n", sz); #endif if (fInOpaque == 0 && fInBody == 0) { if (regexec(&reVersion, sz, 64, aregm, 0) == 0) { _regmtostring(szw, sizeof(szw), sz, &aregm[1]); nVersion = atoi(szw); #ifdef VERYVERBOSE printf("-- version %d\n", nVersion); #endif } else if (regexec(&reByteOrder, sz, 64, aregm, 0) == 0) { } else if (regexec(&reNodeAttrSize, sz, 64, aregm, 0) == 0) { _regmtostring(szw, sizeof(szw), sz, &aregm[1]); nNodeAttrSize = atoi(szw); if (nNodeAttrSize) { pbNodeAttr = (unsigned char *)malloc(nNodeAttrSize); if (pbNodeAttr == NULL) { fprintf(stderr, "Memory Exhausted\n"); exit(1); } pbToNodeAttr = (unsigned char *)malloc(nNodeAttrSize); if (pbToNodeAttr == NULL) { fprintf(stderr, "Memory Exhausted\n"); exit(1); } } #ifdef VERYVERBOSE printf("-- node attr size %d\n", nNodeAttrSize); #endif } else if (regexec(&reEdgeAttrSize, sz, 64, aregm, 0) == 0) { _regmtostring(szw, sizeof(szw), sz, &aregm[1]); nEdgeAttrSize = atoi(szw); if (nEdgeAttrSize > 0) { pbEdgeAttr = (unsigned char *)malloc(nEdgeAttrSize); if (pbEdgeAttr == NULL) { fprintf(stderr, "Memory Exhausted\n"); exit(1); } } #ifdef VERYVERBOSE printf("-- edge attr size %d\n", nEdgeAttrSize); #endif } else if (regexec(&reOpaque, sz, 64, aregm, 0) == 0) { #ifdef VERYVERBOSE printf("-- opaque...\n"); #endif fInOpaque = 1; } else if (strncmp(sz, "--", 2) == 0) { nret = dglInitialize(&graphOut, nVersion, nNodeAttrSize, nEdgeAttrSize, anOpaque); if (nret < 0) { fprintf(stderr, "dglInitialize error %s\n", dglStrerror(&graphOut)); exit(1); } #ifdef VERBOSE printf("Initialize: Version=%ld NodeAttr=%ld EdgeAttr=%ld\n", nVersion, nNodeAttrSize, nEdgeAttrSize); #endif fInBody = 1; } } else if (fInOpaque > 0 && fInBody == 0) { if (fInOpaque == 1) { sscanf(sz, "%ld %ld %ld %ld", &anOpaque[0], &anOpaque[1], &anOpaque[2], &anOpaque[3]); fInOpaque++; #ifdef VERYVERBOSE printf("opaque 1: %ld %ld %ld %ld\n", anOpaque[0], anOpaque[1], anOpaque[2], anOpaque[3]); #endif } else if (fInOpaque == 2) { sscanf(sz, "%ld %ld %ld %ld", &anOpaque[4], &anOpaque[5], &anOpaque[6], &anOpaque[7]); #ifdef VERYVERBOSE printf("opaque 2: %ld %ld %ld %ld\n", anOpaque[4], anOpaque[5], anOpaque[6], anOpaque[7]); #endif fInOpaque++; } else if (fInOpaque == 3) { sscanf(sz, "%ld %ld %ld %ld", &anOpaque[8], &anOpaque[9], &anOpaque[10], &anOpaque[11]); #ifdef VERYVERBOSE printf("opaque 3: %ld %ld %ld %ld\n", anOpaque[8], anOpaque[9], anOpaque[10], anOpaque[11]); #endif fInOpaque++; } else if (fInOpaque == 4) { sscanf(sz, "%ld %ld %ld %ld", &anOpaque[12], &anOpaque[13], &anOpaque[14], &anOpaque[15]); #ifdef VERYVERBOSE printf("opaque 4: %ld %ld %ld %ld\n", anOpaque[12], anOpaque[13], anOpaque[14], anOpaque[15]); #endif fInOpaque = 0; } } else if (fInBody == 1) { if (regexec(&reNodeFrom, sz, 64, aregm, 0) == 0) { _regmtostring(szw, sizeof(szw), sz, &aregm[1]); #ifdef VERYVERBOSE printf("node from snippet = %s\n", szw); #endif nNodeFrom = atol(szw); if (nNodeAttrSize > 0) { if (regexec(&reNodeAttr, sz, 64, aregm, 0) == 0) { _regmtostring(szw, sizeof(szw), sz, &aregm[1]); if (_sztoattr(pbNodeAttr, nNodeAttrSize, szw) != nNodeAttrSize) { fprintf(stderr, "node attr size mismatch\n"); } #ifdef VERYVERBOSE { int k; for (k = 0; k < nNodeAttrSize; k++) { printf("%02x", pbNodeAttr[k]); } printf("\n"); } #endif } } } else if (regexec(&reEdge, sz, 64, aregm, 0) == 0) { _regmtostring(szw, sizeof(szw), sz, &aregm[2]); nNodeTo = atol(szw); _regmtostring(szw, sizeof(szw), sz, &aregm[3]); nCost = atol(szw); _regmtostring(szw, sizeof(szw), sz, &aregm[4]); nUser = atol(szw); if (nEdgeAttrSize > 0) { if (regexec(&reEdgeAttr, sz, 64, aregm, 0) == 0) { _regmtostring(szw, sizeof(szw), sz, &aregm[1]); if (_sztoattr(pbEdgeAttr, nEdgeAttrSize, szw) != nEdgeAttrSize) { fprintf(stderr, "edge attr size mismatch\n"); } #ifdef VERYVERBOSE { int k; for (k = 0; k < nEdgeAttrSize; k++) { printf("%02x", pbEdgeAttr[k]); } printf("\n"); } #endif } } if (nNodeAttrSize > 0) { if (regexec(&reToNodeAttr, sz, 64, aregm, 0) == 0) { _regmtostring(szw, sizeof(szw), sz, &aregm[1]); if (_sztoattr(pbToNodeAttr, nNodeAttrSize, szw) != nNodeAttrSize) { fprintf(stderr, "to node attr size mismatch\n"); } #ifdef VERYVERBOSE { int k; for (k = 0; k < nNodeAttrSize; k++) { printf("%02x", pbToNodeAttr[k]); } printf("\n"); } #endif } } nret = dglAddEdgeX(&graphOut, nNodeFrom, nNodeTo, nCost, nUser, pbNodeAttr, pbToNodeAttr, pbEdgeAttr, 0); if (nret < 0) { fprintf(stderr, "dglAddEdge error %s\n", dglStrerror(&graphOut)); exit(1); } #ifdef VERBOSE printf("AddEdge: from=%ld to=%ld cost=%ld user=%ld\n", nNodeFrom, nNodeTo, nCost, nUser); #endif } } } #ifndef VERBOSE printf("\ndone.\n"); #endif fclose(fp); regfree(&reVersion); regfree(&reByteOrder); regfree(&reNodeAttrSize); regfree(&reEdgeAttrSize); regfree(&reCounters); regfree(&reOpaque); regfree(&reNodeFrom); regfree(&reNodeAttr); regfree(&reEdge); regfree(&reToNodeAttr); regfree(&reEdgeAttr); if (pbNodeAttr) free(pbNodeAttr); if (pbToNodeAttr) free(pbToNodeAttr); if (pbEdgeAttr) free(pbEdgeAttr); printf("Flatten..."); fflush(stdout); nret = dglFlatten(&graphOut); if (nret < 0) { fprintf(stderr, "dglFlatten error %s\n", dglStrerror(&graphOut)); exit(1); } printf("done.\n"); if (pszGraphout) { fd = open(pszGraphout, O_WRONLY | O_CREAT | O_TRUNC, 0666); if (fd < 0) { perror("open"); exit(1); } printf("Write <%s>...", pszGraphout); fflush(stdout); nret = dglWrite(&graphOut, fd); if (nret < 0) { fprintf(stderr, "dglWrite error %s\n", dglStrerror(&graphOut)); exit(1); } printf("done.\n"); close(fd); } printf("Release..."); fflush(stdout); dglRelease(&graphOut); printf("done.\n"); return 0; }