/* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * Source best viewed with tabstop=4 */ #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) || ftell(fp) == statdata.st_size ) printf( "Parse input file ... status: %ld/%ld\r", 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 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 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..." , 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; }