diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2014-12-03 20:35:39 -0800 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2014-12-03 20:35:39 -0800 |
commit | 705006a64830a4b08bce2310d3c118e47770ad7c (patch) | |
tree | a73fb8b5d18d786ccaad055594c6afa7e54d98f0 /src | |
parent | e970aa8521002b242deb259690d1cad67367fb11 (diff) | |
download | abc-705006a64830a4b08bce2310d3c118e47770ad7c.tar.gz abc-705006a64830a4b08bce2310d3c118e47770ad7c.tar.bz2 abc-705006a64830a4b08bce2310d3c118e47770ad7c.zip |
Changes to the parser.
Diffstat (limited to 'src')
-rw-r--r-- | src/base/abci/abc.c | 4 | ||||
-rw-r--r-- | src/base/cba/cba.h | 22 | ||||
-rw-r--r-- | src/base/cba/cbaPrs.h | 70 | ||||
-rw-r--r-- | src/base/cba/cbaReadBlif.c | 351 | ||||
-rw-r--r-- | src/base/cba/cbaReadVer.c | 48 | ||||
-rw-r--r-- | src/base/cba/cbaWriteBlif.c | 13 | ||||
-rw-r--r-- | src/misc/util/utilNam.c | 21 | ||||
-rw-r--r-- | src/misc/vec/vecStr.h | 12 |
8 files changed, 354 insertions, 187 deletions
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 4ba39ffc..b3ac0280 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -10834,6 +10834,10 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_IsopTestNew(); } */ + { + extern void Cba_PrsReadBlifTest(); + Cba_PrsReadBlifTest(); + } return 0; usage: Abc_Print( -2, "usage: test [-CKDNM] [-aovwh] <file_name>\n" ); diff --git a/src/base/cba/cba.h b/src/base/cba/cba.h index 810e2d23..0a519893 100644 --- a/src/base/cba/cba.h +++ b/src/base/cba/cba.h @@ -150,7 +150,7 @@ static inline Cba_Ntk_t * Cba_NtkAlloc( Cba_Man_t * p, char * pName ) { Cba_Ntk_t * pNtk = ABC_CALLOC( Cba_Ntk_t, 1 ); pNtk->pDesign = p; - pNtk->pName = pName; + pNtk->pName = Abc_UtilStrsav(pName); Vec_PtrPush( &p->vNtks, pNtk ); return pNtk; } @@ -169,9 +169,13 @@ static inline void Cba_NtkFree( Cba_Ntk_t * p ) Vec_IntErase( &p->vNameIds ); Vec_IntErase( &p->vRanges ); Vec_IntErase( &p->vCopies ); + ABC_FREE( p->pName ); ABC_FREE( p ); } - +static inline int Cba_NtkMemory( Cba_Ntk_t * p ) +{ + return Vec_WecMemory(&p->vFanins); +} static inline Cba_Man_t * Cba_ManAlloc( char * pFileName ) { @@ -193,6 +197,7 @@ static inline void Cba_ManFree( Cba_Man_t * p ) Cba_Ntk_t * pNtk; int i; Cba_ManForEachNtk( p, pNtk, i ) Cba_NtkFree( pNtk ); + ABC_FREE( p->vNtks.pArray ); Mem_FlexStop( p->pMem, 0 ); // design names Abc_NamStop( p->pNames ); @@ -202,6 +207,19 @@ static inline void Cba_ManFree( Cba_Man_t * p ) ABC_FREE( p->pSpec ); ABC_FREE( p ); } +static inline int Cba_ManMemory( Cba_Man_t * p ) +{ + Cba_Ntk_t * pNtk; int i; + int nMem = sizeof(Cba_Man_t); + nMem += Abc_NamMemUsed(p->pNames); + nMem += Abc_NamMemUsed(p->pModels); + nMem += Abc_NamMemUsed(p->pFuncs); + nMem += Mem_FlexReadMemUsage(p->pMem); + nMem += (int)Vec_PtrMemory(&p->vNtks); + Cba_ManForEachNtk( p, pNtk, i ) + nMem += Cba_NtkMemory( pNtk ); + return nMem; +} /*=== cbaReadBlif.c =========================================================*/ diff --git a/src/base/cba/cbaPrs.h b/src/base/cba/cbaPrs.h index 1418ffdb..e668679f 100644 --- a/src/base/cba/cbaPrs.h +++ b/src/base/cba/cbaPrs.h @@ -78,19 +78,19 @@ struct Cba_Prs_t_ Cba_Man_t * pDesign; // interface collected by the parser int iModuleName; // name Id - Vec_Int_t * vInoutsCur; // inouts - Vec_Int_t * vInputsCur; // inputs - Vec_Int_t * vOutputsCur; // outputs - Vec_Int_t * vWiresCur; // wires + Vec_Int_t vInoutsCur; // inouts + Vec_Int_t vInputsCur; // inputs + Vec_Int_t vOutputsCur; // outputs + Vec_Int_t vWiresCur; // wires // objects collected by the parser - Vec_Int_t * vTypesCur; // Cba_PrsType_t - Vec_Int_t * vFuncsCur; // functions (node->func; box->module; gate->cell; latch->init; concat->unused) - Vec_Int_t * vInstIdsCur; // instance names - Vec_Wec_t * vFaninsCur; // instances + Vec_Int_t vTypesCur; // Cba_PrsType_t + Vec_Int_t vFuncsCur; // functions (node->func; box->module; gate->cell; latch->init; concat->unused) + Vec_Int_t vInstIdsCur; // instance names + Vec_Wec_t vFaninsCur; // instances // temporary data - Vec_Str_t * vCover; // one SOP cover - Vec_Int_t * vTemp; // array of tokens - Vec_Int_t * vTemp2; // array of tokens + Vec_Str_t vCover; // one SOP cover + Vec_Int_t vTemp; // array of tokens + Vec_Int_t vTemp2; // array of tokens // error handling char ErrorStr[1000]; // error }; @@ -132,16 +132,16 @@ static inline void Cba_PrsSetupVecInt( Cba_Prs_t * p, Vec_Int_t * vTo, Vec_Int_t static inline Cba_Ntk_t * Cba_PrsAddCurrentModel( Cba_Prs_t * p, int iNameId ) { Cba_Ntk_t * pNtk = Cba_NtkAlloc( p->pDesign, Abc_NamStr(p->pDesign->pNames, iNameId) ); - assert( Vec_IntSize(p->vInputsCur) != 0 && Vec_IntSize(p->vOutputsCur) != 0 ); - Cba_PrsSetupVecInt( p, &pNtk->vInouts, p->vInoutsCur ); - Cba_PrsSetupVecInt( p, &pNtk->vInputs, p->vInputsCur ); - Cba_PrsSetupVecInt( p, &pNtk->vOutputs, p->vOutputsCur ); - Cba_PrsSetupVecInt( p, &pNtk->vWires, p->vWiresCur ); - Cba_PrsSetupVecInt( p, &pNtk->vTypes, p->vTypesCur ); - Cba_PrsSetupVecInt( p, &pNtk->vFuncs, p->vFuncsCur ); - Cba_PrsSetupVecInt( p, &pNtk->vInstIds, p->vInstIdsCur ); - pNtk->vFanins = *p->vFaninsCur; - Vec_WecZero( &pNtk->vFanins ); + assert( Vec_IntSize(&p->vInputsCur) != 0 || Vec_IntSize(&p->vOutputsCur) != 0 ); + Cba_PrsSetupVecInt( p, &pNtk->vInouts, &p->vInoutsCur ); + Cba_PrsSetupVecInt( p, &pNtk->vInputs, &p->vInputsCur ); + Cba_PrsSetupVecInt( p, &pNtk->vOutputs, &p->vOutputsCur ); + Cba_PrsSetupVecInt( p, &pNtk->vWires, &p->vWiresCur ); + Cba_PrsSetupVecInt( p, &pNtk->vTypes, &p->vTypesCur ); + Cba_PrsSetupVecInt( p, &pNtk->vFuncs, &p->vFuncsCur ); + Cba_PrsSetupVecInt( p, &pNtk->vInstIds, &p->vInstIdsCur ); + pNtk->vFanins = p->vFaninsCur; + Vec_WecZero( &p->vFaninsCur ); return pNtk; } @@ -185,29 +185,25 @@ static inline Cba_Prs_t * Cba_PrsAlloc( char * pFileName ) p->pLimit = pLimit; p->pCur = pBuffer; p->pDesign = Cba_ManAlloc( pFileName ); - // temporaries - p->vCover = Vec_StrAlloc( 1000 ); - p->vTemp = Vec_IntAlloc( 1000 ); - p->vTemp2 = Vec_IntAlloc( 1000 ); return p; } static inline void Cba_PrsFree( Cba_Prs_t * p ) { if ( p->pDesign ) Cba_ManFree( p->pDesign ); - Vec_IntFreeP( &p->vInoutsCur ); - Vec_IntFreeP( &p->vInputsCur ); - Vec_IntFreeP( &p->vOutputsCur ); - Vec_IntFreeP( &p->vWiresCur ); - - Vec_IntFreeP( &p->vTypesCur ); - Vec_IntFreeP( &p->vFuncsCur ); - Vec_IntFreeP( &p->vInstIdsCur ); - Vec_WecFreeP( &p->vFaninsCur ); + Vec_IntErase( &p->vInoutsCur ); + Vec_IntErase( &p->vInputsCur ); + Vec_IntErase( &p->vOutputsCur ); + Vec_IntErase( &p->vWiresCur ); + + Vec_IntErase( &p->vTypesCur ); + Vec_IntErase( &p->vFuncsCur ); + Vec_IntErase( &p->vInstIdsCur ); + ABC_FREE( p->vFaninsCur.pArray ); // temporary - Vec_StrFreeP( &p->vCover ); - Vec_IntFreeP( &p->vTemp ); - Vec_IntFreeP( &p->vTemp2 ); + Vec_StrErase( &p->vCover ); + Vec_IntErase( &p->vTemp ); + Vec_IntErase( &p->vTemp2 ); ABC_FREE( p->pBuffer ); ABC_FREE( p ); } diff --git a/src/base/cba/cbaReadBlif.c b/src/base/cba/cbaReadBlif.c index c324b37f..34353496 100644 --- a/src/base/cba/cbaReadBlif.c +++ b/src/base/cba/cbaReadBlif.c @@ -29,29 +29,33 @@ ABC_NAMESPACE_IMPL_START // BLIF keywords typedef enum { - CBA_BLIF_NONE = 0, // 0: unused - CBA_BLIF_MODEL, // 1: .model - CBA_BLIF_INPUTS, // 2: .inputs - CBA_BLIF_OUTPUTS, // 3: .outputs - CBA_BLIF_NAMES, // 4: .names - CBA_BLIF_SUBCKT, // 5: .subckt - CBA_BLIF_GATE, // 6: .gate - CBA_BLIF_LATCH, // 7: .latch - CBA_BLIF_END, // 8: .end - CBA_BLIF_UNKNOWN // 9: unknown + CBA_BLIF_NONE = 0, // 0: unused + CBA_BLIF_MODEL, // 1: .model + CBA_BLIF_INOUTS, // 2: .inouts + CBA_BLIF_INPUTS, // 3: .inputs + CBA_BLIF_OUTPUTS, // 4: .outputs + CBA_BLIF_NAMES, // 5: .names + CBA_BLIF_SUBCKT, // 6: .subckt + CBA_BLIF_GATE, // 7: .gate + CBA_BLIF_LATCH, // 8: .latch + CBA_BLIF_SHORT, // 9: .short + CBA_BLIF_END, // 10: .end + CBA_BLIF_UNKNOWN // 11: unknown } Cba_BlifType_t; const char * s_BlifTypes[CBA_BLIF_UNKNOWN+1] = { - NULL, // 0: unused - ".model", // 1: .model - ".inputs", // 2: .inputs - ".outputs", // 3: .outputs - ".names", // 4: .names - ".subckt", // 5: .subckt - ".gate", // 6: .gate - ".latch", // 7: .latch - ".end", // 8: .end - NULL // 9: unknown + NULL, // 0: unused + ".model", // 1: .model + ".inouts", // 2: .inputs + ".inputs", // 3: .inputs + ".outputs", // 4: .outputs + ".names", // 5: .names + ".subckt", // 6: .subckt + ".gate", // 7: .gate + ".latch", // 8: .latch + ".short", // 9: .short + ".end", // 10: .end + NULL // 11: unknown }; static inline void Cba_PrsAddBlifDirectives( Cba_Prs_t * p ) @@ -60,15 +64,11 @@ static inline void Cba_PrsAddBlifDirectives( Cba_Prs_t * p ) for ( i = 1; s_BlifTypes[i]; i++ ) Abc_NamStrFindOrAdd( p->pDesign->pNames, (char *)s_BlifTypes[i], NULL ); assert( Abc_NamObjNumMax(p->pDesign->pNames) == i ); + Abc_NamStrFindOrAdd( p->pDesign->pFuncs, (char *)" 0\n", NULL ); // default const 0 function + Abc_NamStrFindOrAdd( p->pDesign->pFuncs, (char *)"1 1\n", NULL ); // default buffer function + assert( Abc_NamObjNumMax(p->pDesign->pFuncs) == 3 ); } -static inline int Cba_PrsIsSpace( char c ) { return c == ' ' || c == '\t' || c == '\r'; } -static inline int Cba_PrsIsOk( Cba_Prs_t * p ) { return (int)(p->pCur < p->pLimit); } -static inline int Cba_PrsIsChar( Cba_Prs_t * p, char c ) { return *p->pCur == 'c'; } -static inline int Cba_PrsIsLit( Cba_Prs_t * p ) { return *p->pCur == '0' || *p->pCur == '1' || *p->pCur == '-'; } -static inline void Cba_PrsSkipToChar( Cba_Prs_t * p, char c ) { while ( *p->pCur != c ) p->pCur++; } -static inline char Cba_PrsSkip( Cba_Prs_t * p ) { return *p->pCur++; } - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -76,6 +76,32 @@ static inline char Cba_PrsSkip( Cba_Prs_t * p ) { return *p->pCur /**Function************************************************************* + Synopsis [Reading characters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Cba_CharIsSpace( char c ) { return c == ' ' || c == '\t' || c == '\r'; } +static inline int Cba_CharIsStop( char c ) { return c == '#' || c == '\\' || c == '\n' || c == '='; } +static inline int Cba_CharIsLit( char c ) { return c == '0' || c == '1' || c == '-'; } + +static inline int Cba_PrsIsSpace( Cba_Prs_t * p ) { return Cba_CharIsSpace(*p->pCur); } +static inline int Cba_PrsIsStop( Cba_Prs_t * p ) { return Cba_CharIsStop(*p->pCur); } +static inline int Cba_PrsIsLit( Cba_Prs_t * p ) { return Cba_CharIsLit(*p->pCur); } + +static inline int Cba_PrsIsChar( Cba_Prs_t * p, char c ) { return *p->pCur == c; } +static inline int Cba_PrsIsChar2( Cba_Prs_t * p, char c ) { return *p->pCur++ == c; } + +static inline void Cba_PrsSkip( Cba_Prs_t * p ) { p->pCur++; } +static inline char Cba_PrsSkip2( Cba_Prs_t * p ) { return *p->pCur++; } + + +/**Function************************************************************* + Synopsis [Reading names.] Description [] @@ -85,36 +111,81 @@ static inline char Cba_PrsSkip( Cba_Prs_t * p ) { return *p->pCur SeeAlso [] ***********************************************************************/ +static inline void Cba_PrsSkipToChar( Cba_Prs_t * p, char c ) +{ + while ( !Cba_PrsIsChar(p, c) ) + Cba_PrsSkip(p); +} static inline void Cba_PrsSkipSpaces( Cba_Prs_t * p ) { - while ( Cba_PrsIsSpace(*p->pCur) ) - Cba_PrsSkip(p); - if ( Cba_PrsIsChar(p, '#') ) - Cba_PrsSkipToChar( p, '\n' ); - else if ( Cba_PrsIsChar(p, '\\') ) + while ( 1 ) { - Cba_PrsSkipToChar( p, '\n' ); - Cba_PrsSkip(p); - Cba_PrsSkipSpaces( p ); - } + while ( Cba_PrsIsSpace(p) ) + Cba_PrsSkip(p); + if ( Cba_PrsIsChar(p, '\\') ) + { + Cba_PrsSkipToChar( p, '\n' ); + Cba_PrsSkip(p); + continue; + } + if ( Cba_PrsIsChar(p, '#') ) + Cba_PrsSkipToChar( p, '\n' ); + break; + } + assert( !Cba_PrsIsSpace(p) ); } static inline int Cba_PrsReadName( Cba_Prs_t * p ) { - char * pStart = p->pCur; - while ( !Cba_PrsIsSpace(*p->pCur) && !Cba_PrsIsChar(p, '\\') ) + char * pStart; + Cba_PrsSkipSpaces( p ); + if ( Cba_PrsIsChar(p, '\n') ) + return 0; + pStart = p->pCur; + while ( !Cba_PrsIsSpace(p) && !Cba_PrsIsStop(p) ) Cba_PrsSkip(p); if ( pStart == p->pCur ) return 0; + assert( pStart < p->pCur ); return Abc_NamStrFindOrAddLim( p->pDesign->pNames, pStart, p->pCur, NULL ); } -static inline int Cba_PrsReadName2( Cba_Prs_t * p ) +static inline int Cba_PrsReadList( Cba_Prs_t * p ) { - char * pStart = p->pCur; - while ( !Cba_PrsIsSpace(*p->pCur) && !Cba_PrsIsChar(p, '\\') && !Cba_PrsIsChar(p, '=') ) - Cba_PrsSkip(p); - if ( pStart == p->pCur ) - return 0; - return Abc_NamStrFindOrAddLim( p->pDesign->pNames, pStart, p->pCur, NULL ); + int iToken; + Vec_IntClear( &p->vTemp ); + while ( (iToken = Cba_PrsReadName(p)) ) + Vec_IntPush( &p->vTemp, iToken ); + if ( Vec_IntSize(&p->vTemp) == 0 ) return Cba_PrsErrorSet(p, "Signal list is empty.", 1); + return 0; +} +static inline int Cba_PrsReadList2( Cba_Prs_t * p ) +{ + int iToken; + Vec_IntFill( &p->vTemp, 1, -1 ); + while ( (iToken = Cba_PrsReadName(p)) ) + Vec_IntPush( &p->vTemp, iToken ); + iToken = Vec_IntPop(&p->vTemp); + if ( Vec_IntSize(&p->vTemp) == 0 ) return Cba_PrsErrorSet(p, "Signal list is empty.", 1); + Vec_IntWriteEntry( &p->vTemp, 0, iToken ); + return 0; +} +static inline int Cba_PrsReadList3( Cba_Prs_t * p ) +{ + Vec_IntClear( &p->vTemp ); + while ( !Cba_PrsIsChar(p, '\n') ) + { + int iToken = Cba_PrsReadName(p); + if ( iToken == 0 ) return Cba_PrsErrorSet(p, "Cannot read formal name.", 1); + Vec_IntPush( &p->vTemp, iToken ); + Cba_PrsSkipSpaces( p ); + if ( !Cba_PrsIsChar2(p, '=') ) return Cba_PrsErrorSet(p, "Cannot find symbol \"=\".", 1); + iToken = Cba_PrsReadName(p); + if ( iToken == 0 ) return Cba_PrsErrorSet(p, "Cannot read actual name.", 1); + Vec_IntPush( &p->vTemp, iToken ); + Cba_PrsSkipSpaces( p ); + } + if ( Vec_IntSize(&p->vTemp) == 0 ) return Cba_PrsErrorSet(p, "Cannot read a list of formal/actual names.", 1); + if ( Vec_IntSize(&p->vTemp) % 2 ) return Cba_PrsErrorSet(p, "The number of formal/actual names is not even.", 1); + return 0; } /**Function************************************************************* @@ -130,23 +201,36 @@ static inline int Cba_PrsReadName2( Cba_Prs_t * p ) ***********************************************************************/ static inline int Cba_PrsReadCube( Cba_Prs_t * p ) { + assert( Cba_PrsIsLit(p) ); while ( Cba_PrsIsLit(p) ) - Vec_StrPush( p->vCover, Cba_PrsSkip(p) ); + Vec_StrPush( &p->vCover, Cba_PrsSkip2(p) ); Cba_PrsSkipSpaces( p ); - Vec_StrPush( p->vCover, ' ' ); - if ( !Cba_PrsIsLit(p) ) return Cba_PrsErrorSet(p, "Cannot detect output literal.", 1); - Vec_StrPush( p->vCover, Cba_PrsSkip(p) ); - return 1; + if ( Cba_PrsIsChar(p, '\n') ) + { + if ( Vec_StrSize(&p->vCover) != 1 ) return Cba_PrsErrorSet(p, "Cannot read cube.", 1); + // fix single literal cube by adding space + Vec_StrPush( &p->vCover, Vec_StrEntry(&p->vCover,0) ); + Vec_StrWriteEntry( &p->vCover, 0, ' ' ); + Vec_StrPush( &p->vCover, '\n' ); + return 0; + } + if ( !Cba_PrsIsLit(p) ) return Cba_PrsErrorSet(p, "Cannot read output literal.", 1); + Vec_StrPush( &p->vCover, ' ' ); + Vec_StrPush( &p->vCover, Cba_PrsSkip2(p) ); + Vec_StrPush( &p->vCover, '\n' ); + Cba_PrsSkipSpaces( p ); + if ( !Cba_PrsIsChar(p, '\n') ) return Cba_PrsErrorSet(p, "Cannot read end of cube.", 1); + return 0; } static inline void Cba_PrsSaveCover( Cba_Prs_t * p ) { int iToken; - assert( Vec_StrSize(p->vCover) > 0 ); - Vec_StrPush( p->vCover, '\0' ); - iToken = Abc_NamStrFindOrAdd( p->pDesign->pFuncs, Vec_StrArray(p->vCover), NULL ); - Vec_StrClear( p->vCover ); - assert( Vec_IntEntryLast(p->vFuncsCur) == 1 ); - Vec_IntWriteEntry( p->vFuncsCur, Vec_IntSize(p->vFuncsCur)-1, iToken ); + assert( Vec_StrSize(&p->vCover) > 0 ); + Vec_StrPush( &p->vCover, '\0' ); + iToken = Abc_NamStrFindOrAdd( p->pDesign->pFuncs, Vec_StrArray(&p->vCover), NULL ); + assert( Vec_IntEntryLast(&p->vFuncsCur) == 1 ); + Vec_IntWriteEntry( &p->vFuncsCur, Vec_IntSize(&p->vFuncsCur)-1, iToken ); + Vec_StrClear( &p->vCover ); } /**Function************************************************************* @@ -160,98 +244,100 @@ static inline void Cba_PrsSaveCover( Cba_Prs_t * p ) SeeAlso [] ***********************************************************************/ -static inline int Cba_PrsReadSignals( Cba_Prs_t * p, int fSkipFirst ) +static inline int Cba_PrsReadInouts( Cba_Prs_t * p ) { - Cba_PrsSkipSpaces( p ); - Vec_IntFill( p->vTemp, fSkipFirst, -1 ); - while ( !Cba_PrsIsChar(p, '\n') ) - { - Vec_IntPush( p->vTemp, Cba_PrsReadName(p) ); - Cba_PrsSkipSpaces( p ); - } - if ( Vec_IntSize(p->vTemp) == 0 ) return Cba_PrsErrorSet(p, "List of signals is empty.", 1); - if ( Vec_IntCountZero(p->vTemp) ) return Cba_PrsErrorSet(p, "Cannot read names in the list.", 1); + if ( Cba_PrsReadList(p) ) return 1; + Vec_IntAppend( &p->vInoutsCur, &p->vTemp ); return 0; } static inline int Cba_PrsReadInputs( Cba_Prs_t * p ) { - if ( Cba_PrsReadSignals(p, 0) ) return 1; - Vec_IntAppend( p->vInputsCur, p->vTemp ); + if ( Cba_PrsReadList(p) ) return 1; + Vec_IntAppend( &p->vInputsCur, &p->vTemp ); return 0; } static inline int Cba_PrsReadOutputs( Cba_Prs_t * p ) { - if ( Cba_PrsReadSignals(p, 0) ) return 1; - Vec_IntAppend( p->vOutputsCur, p->vTemp ); + if ( Cba_PrsReadList(p) ) return 1; + Vec_IntAppend( &p->vOutputsCur, &p->vTemp ); return 0; } static inline int Cba_PrsReadNode( Cba_Prs_t * p ) { - if ( Cba_PrsReadSignals(p, 1) ) return 1; - Vec_IntWriteEntry( p->vTemp, 0, Vec_IntPop(p->vTemp) ); + if ( Cba_PrsReadList2(p) ) return 1; // save results - Vec_IntPush( p->vFuncsCur, 1 ); - Vec_IntPush( p->vTypesCur, CBA_PRS_NODE ); - Cba_PrsSetupVecInt( p, Vec_WecPushLevel(p->vFaninsCur), p->vTemp ); + Vec_IntPush( &p->vTypesCur, CBA_PRS_NODE ); + Vec_IntPush( &p->vFuncsCur, 1 ); // default const 0 function + Cba_PrsSetupVecInt( p, Vec_WecPushLevel(&p->vFaninsCur), &p->vTemp ); return 0; } static inline int Cba_PrsReadBox( Cba_Prs_t * p, int fGate ) { - Cba_PrsSkipSpaces( p ); - if ( Cba_PrsIsChar(p, '\n') ) return Cba_PrsErrorSet(p, "Cannot read model name.", 1); - Vec_IntPush( p->vFuncsCur, Cba_PrsReadName(p) ); - Cba_PrsSkipSpaces( p ); - if ( Cba_PrsIsChar(p, '\n') ) return Cba_PrsErrorSet(p, "Cannot read formal/actual inputs.", 1); - while ( !Cba_PrsIsChar(p, '\n') ) - { - Vec_IntPush( p->vTemp, Cba_PrsReadName(p) ); - Cba_PrsSkipSpaces( p ); - if ( !Cba_PrsIsChar(p, '=') ) return Cba_PrsErrorSet(p, "Cannot find symbol \'=\'.", 1); - p->pCur++; - Cba_PrsSkipSpaces( p ); - Vec_IntPush( p->vTemp, Cba_PrsReadName(p) ); - Cba_PrsSkipSpaces( p ); - } + int iToken = Cba_PrsReadName(p); + if ( iToken == 0 ) return Cba_PrsErrorSet(p, "Cannot read model name.", 1); + if ( Cba_PrsReadList3(p) ) return 1; // save results - Vec_IntPush( p->vTypesCur, CBA_PRS_BOX ); - Cba_PrsSetupVecInt( p, Vec_WecPushLevel(p->vFaninsCur), p->vTemp ); + Vec_IntPush( &p->vTypesCur, CBA_PRS_BOX ); + Vec_IntPush( &p->vFuncsCur, iToken ); + Cba_PrsSetupVecInt( p, Vec_WecPushLevel(&p->vFaninsCur), &p->vTemp ); return 0; } static inline int Cba_PrsReadLatch( Cba_Prs_t * p ) { - Vec_IntFill( p->vTemp, 2, -1 ); - Cba_PrsSkipSpaces( p ); - if ( Cba_PrsIsChar(p, '\n') ) return Cba_PrsErrorSet(p, "Cannot read latch input.", 1); - Vec_IntWriteEntry( p->vTemp, 1, Cba_PrsReadName(p) ); + int iToken = Cba_PrsReadName(p); + Vec_IntFill( &p->vTemp, 2, -1 ); + if ( iToken == 0 ) return Cba_PrsErrorSet(p, "Cannot read latch input.", 1); + Vec_IntWriteEntry( &p->vTemp, 1, iToken ); + iToken = Cba_PrsReadName(p); + if ( iToken == 0 ) return Cba_PrsErrorSet(p, "Cannot read latch output.", 1); + Vec_IntWriteEntry( &p->vTemp, 0, iToken ); Cba_PrsSkipSpaces( p ); - if ( Cba_PrsIsChar(p, '\n') ) return Cba_PrsErrorSet(p, "Cannot read latch output.", 1); - Vec_IntWriteEntry( p->vTemp, 0, Cba_PrsReadName(p) ); if ( Cba_PrsIsChar(p, '0') ) - Vec_IntPush( p->vFuncsCur, 0 ); + iToken = 0; else if ( Cba_PrsIsChar(p, '1') ) - Vec_IntPush( p->vFuncsCur, 1 ); - else if ( Cba_PrsIsChar(p, '2') || Cba_PrsIsChar(p, '\n') ) - Vec_IntPush( p->vFuncsCur, 2 ); - else return Cba_PrsErrorSet(p, "Cannot read latch init value.", 1); + iToken = 1; + else + iToken = 2; + Cba_PrsSkipToChar( p, '\n' ); // save results - Vec_IntPush( p->vTypesCur, CBA_PRS_LATCH ); - Cba_PrsSetupVecInt( p, Vec_WecPushLevel(p->vFaninsCur), p->vTemp ); + Vec_IntPush( &p->vTypesCur, CBA_PRS_LATCH ); + Vec_IntPush( &p->vFuncsCur, iToken ); + Cba_PrsSetupVecInt( p, Vec_WecPushLevel(&p->vFaninsCur), &p->vTemp ); return 0; } -static inline int Cba_PrsReadModel( Cba_Prs_t * p ) +static inline int Cba_PrsReadShort( Cba_Prs_t * p ) { + int iToken = Cba_PrsReadName(p); + Vec_IntFill( &p->vTemp, 2, -1 ); + if ( iToken == 0 ) return Cba_PrsErrorSet(p, "Cannot read .short input.", 1); + Vec_IntWriteEntry( &p->vTemp, 1, iToken ); + iToken = Cba_PrsReadName(p); + if ( iToken == 0 ) return Cba_PrsErrorSet(p, "Cannot read .short output.", 1); + Vec_IntWriteEntry( &p->vTemp, 0, iToken ); Cba_PrsSkipSpaces( p ); - if ( Vec_IntSize(p->vInputsCur) > 0 ) return Cba_PrsErrorSet(p, "Parsing previous model is unfinished.", 1); - p->iModuleName = Cba_PrsReadName( p ); - if ( p->iModuleName == 0 ) return Cba_PrsErrorSet(p, "Cannot read model name.", 1); + if ( !Cba_PrsIsChar(p, '\n') ) return Cba_PrsErrorSet(p, "Trailing symbols on .short line.", 1); + // save results + Vec_IntPush( &p->vTypesCur, CBA_PRS_NODE ); + Vec_IntPush( &p->vFuncsCur, 2 ); // default buffer function + Cba_PrsSetupVecInt( p, Vec_WecPushLevel(&p->vFaninsCur), &p->vTemp ); + return 0; +} +static inline int Cba_PrsReadModel( Cba_Prs_t * p ) +{ + if ( p->iModuleName > 0 ) return Cba_PrsErrorSet(p, "Parsing previous model is unfinished.", 1); + p->iModuleName = Cba_PrsReadName(p); Cba_PrsSkipSpaces( p ); - if ( !Cba_PrsIsChar(p, '\n') ) return Cba_PrsErrorSet(p, "Trailing symbols on .model line.", 1); + if ( !Cba_PrsIsChar(p, '\n') ) return Cba_PrsErrorSet(p, "Trailing symbols on .model line.", 1); return 0; } static inline int Cba_PrsReadEnd( Cba_Prs_t * p ) { - if ( Vec_IntSize(p->vInputsCur) == 0 ) return Cba_PrsErrorSet(p, "Directive .end without .model.", 1); + if ( p->iModuleName == 0 ) return Cba_PrsErrorSet(p, "Directive .end without .model.", 1); + //printf( "Saving model \"%s\".\n", Abc_NamStr(p->pDesign->pNames, p->iModuleName) ); Cba_PrsAddCurrentModel( p, p->iModuleName ); + p->iModuleName = 0; + Cba_PrsSkipSpaces( p ); + if ( !Cba_PrsIsChar(p, '\n') ) return Cba_PrsErrorSet(p, "Trailing symbols on .end line.", 1); return 0; } @@ -260,11 +346,13 @@ static inline int Cba_PrsReadDirective( Cba_Prs_t * p ) int iToken; if ( !Cba_PrsIsChar(p, '.') ) return Cba_PrsReadCube( p ); - if ( Vec_StrSize(p->vCover) > 0 ) // SOP was specified for the previous node + if ( Vec_StrSize(&p->vCover) > 0 ) // SOP was specified for the previous node Cba_PrsSaveCover( p ); iToken = Cba_PrsReadName( p ); if ( iToken == CBA_BLIF_MODEL ) return Cba_PrsReadModel( p ); + if ( iToken == CBA_BLIF_INOUTS ) + return Cba_PrsReadInouts( p ); if ( iToken == CBA_BLIF_INPUTS ) return Cba_PrsReadInputs( p ); if ( iToken == CBA_BLIF_OUTPUTS ) @@ -277,19 +365,23 @@ static inline int Cba_PrsReadDirective( Cba_Prs_t * p ) return Cba_PrsReadBox( p, 1 ); if ( iToken == CBA_BLIF_LATCH ) return Cba_PrsReadLatch( p ); + if ( iToken == CBA_BLIF_SHORT ) + return Cba_PrsReadShort( p ); if ( iToken == CBA_BLIF_END ) return Cba_PrsReadEnd( p ); - assert( 0 ); + printf( "Cannot read directive \"%s\".\n", Abc_NamStr(p->pDesign->pNames, iToken) ); return 1; } static inline int Cba_PrsReadLines( Cba_Prs_t * p ) { - while ( Cba_PrsIsChar(p, '\n') ) + while ( p->pCur[1] != '\0' ) { - p->pCur++; Cba_PrsSkipSpaces( p ); - if ( Cba_PrsIsChar(p, '\n') ) + assert( Cba_PrsIsChar(p, '\n') ); + Cba_PrsSkip(p); + Cba_PrsSkipSpaces( p ); + if ( Cba_PrsIsChar(p, '\n') ) continue; - if ( Cba_PrsReadDirective( p ) ) + if ( Cba_PrsReadDirective(p) ) return 1; } return 0; @@ -320,6 +412,31 @@ Cba_Man_t * Cba_PrsReadBlif( char * pFileName ) return pDesign; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cba_PrsReadBlifTest( char * pFileName ) +{ + abctime clk = Abc_Clock(); + extern void Cba_PrsWriteBlif( char * pFileName, Cba_Man_t * pDes ); + Cba_Man_t * p = Cba_PrsReadBlif( "aga/ray/ray_hie_oper.blif" ); + if ( !p ) return; + printf( "Finished reading %d networks. ", Cba_ManNtkNum(p) ); + printf( "Memory = %.2f MB. ", 1.0*Cba_ManMemory(p)/(1<<20) ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); +// Abc_NamPrint( p->pDesign->pNames ); + Cba_PrsWriteBlif( "aga/ray/ray_hie_oper_out.blif", p ); + Cba_ManFree( p ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/base/cba/cbaReadVer.c b/src/base/cba/cbaReadVer.c index 2000289c..f0ccd559 100644 --- a/src/base/cba/cbaReadVer.c +++ b/src/base/cba/cbaReadVer.c @@ -264,24 +264,24 @@ static inline int Cba_PrsReadRange( Cba_Prs_t * p ) { if ( !Cba_PrsIsChar(p, '[') ) return 0; - Vec_StrClear( p->vCover ); - Vec_StrPush( p->vCover, *p->pCur++ ); + Vec_StrClear( &p->vCover ); + Vec_StrPush( &p->vCover, *p->pCur++ ); Cba_PrsUtilSkipSpaces( p ); if ( !Cba_PrsIsDigit(p) ) return Cba_PrsErrorSet(p, "Cannot read digit in range specification.", 2); while ( Cba_PrsIsDigit(p) ) - Vec_StrPush( p->vCover, *p->pCur++ ); + Vec_StrPush( &p->vCover, *p->pCur++ ); Cba_PrsUtilSkipSpaces( p ); if ( Cba_PrsIsChar(p, ':') ) { - Vec_StrPush( p->vCover, *p->pCur++ ); + Vec_StrPush( &p->vCover, *p->pCur++ ); if ( !Cba_PrsIsDigit(p) ) return Cba_PrsErrorSet(p, "Cannot read digit in range specification.", 2); while ( Cba_PrsIsDigit(p) ) - Vec_StrPush( p->vCover, *p->pCur++ ); + Vec_StrPush( &p->vCover, *p->pCur++ ); Cba_PrsUtilSkipSpaces( p ); } if ( !Cba_PrsIsChar(p, ']') ) return Cba_PrsErrorSet(p, "Cannot read closing brace in range specification.", 2); - Vec_StrPush( p->vCover, *p->pCur++ ); - return Abc_NamStrFindOrAddLim( p->pDesign->pNames, Vec_StrArray(p->vCover), Vec_StrArray(p->vCover)+Vec_StrSize(p->vCover), NULL ); + Vec_StrPush( &p->vCover, *p->pCur++ ); + return Abc_NamStrFindOrAddLim( p->pDesign->pNames, Vec_StrArray(&p->vCover), Vec_StrArray(&p->vCover)+Vec_StrSize(&p->vCover), NULL ); } static inline void Cba_PrsReadSignalList( Cba_Prs_t * p, Vec_Int_t * vTemp ) { @@ -303,12 +303,12 @@ static inline void Cba_PrsReadSignalList( Cba_Prs_t * p, Vec_Int_t * vTemp ) static inline int Cba_PrsReadDeclaration( Cba_Prs_t * p, int Type ) { int NameId, RangeId, RangeIdTemp; - Vec_Int_t * vSigs[4] = { p->vInoutsCur, p->vInputsCur, p->vOutputsCur, p->vWiresCur }; + Vec_Int_t * vSigs[4] = { &p->vInoutsCur, &p->vInputsCur, &p->vOutputsCur, &p->vWiresCur }; assert( Type >= CBA_VER_INOUT && Type <= CBA_VER_WIRE ); Cba_PrsUtilSkipSpaces( p ); RangeId = Cba_PrsReadRange( p ); - Cba_PrsReadSignalList( p, p->vTemp ); - Vec_IntForEachEntryDouble( p->vTemp, NameId, RangeId, RangeIdTemp ) + Cba_PrsReadSignalList( p, &p->vTemp ); + Vec_IntForEachEntryDouble( &p->vTemp, NameId, RangeId, RangeIdTemp ) { if ( !RangeIdTemp ) return Cba_PrsErrorSet(p, "Range is specified twice in the declaration.", 0); Vec_IntPushTwo( vSigs[Type - CBA_VER_INOUT], NameId, RangeId ); @@ -317,17 +317,17 @@ static inline int Cba_PrsReadDeclaration( Cba_Prs_t * p, int Type ) } static inline int Cba_PrsReadConcat( Cba_Prs_t * p ) { - int iToken = Vec_WecSize( p->vFaninsCur ); + int iToken = Vec_WecSize( &p->vFaninsCur ); assert( Cba_PrsIsChar(p, '{') ); p->pCur++; - Cba_PrsReadSignalList( p, p->vTemp2 ); + Cba_PrsReadSignalList( p, &p->vTemp2 ); if ( !Cba_PrsIsChar(p, '}') ) return Cba_PrsErrorSet(p, "Cannot read concatenation.", 0); p->pCur++; // assign - Vec_IntPush( p->vTypesCur, CBA_PRS_CONCAT ); - Vec_IntPush( p->vFuncsCur, 0 ); - Vec_IntPush( p->vInstIdsCur, 0 ); - Cba_PrsSetupVecInt( p, Vec_WecPushLevel(p->vFaninsCur), p->vTemp2 ); + Vec_IntPush( &p->vTypesCur, CBA_PRS_CONCAT ); + Vec_IntPush( &p->vFuncsCur, 0 ); + Vec_IntPush( &p->vInstIdsCur, 0 ); + Cba_PrsSetupVecInt( p, Vec_WecPushLevel(&p->vFaninsCur), &p->vTemp2 ); return iToken; } @@ -335,7 +335,7 @@ static inline int Cba_PrsReadInstance( Cba_Prs_t * p, int Func ) { // have to assign Type, Func, InstId, vFanins int FormId, NameId, RangeId, Type, InstId; - Vec_IntClear( p->vTemp ); + Vec_IntClear( &p->vTemp ); Cba_PrsUtilSkipSpaces( p ); if ( Cba_PrsIsChar(p, '(') ) // node { @@ -355,7 +355,7 @@ static inline int Cba_PrsReadInstance( Cba_Prs_t * p, int Func ) NameId = Cba_PrsReadName( p ); RangeId = Cba_PrsReadRange( p ); } - Vec_IntPushTwo( p->vTemp, NameId, RangeId ); + Vec_IntPushTwo( &p->vTemp, NameId, RangeId ); Cba_PrsUtilSkipSpaces( p ); if ( Cba_PrsIsChar(p, ')') ) break; @@ -390,7 +390,7 @@ static inline int Cba_PrsReadInstance( Cba_Prs_t * p, int Func ) NameId = Cba_PrsReadName( p ); RangeId = Cba_PrsReadRange( p ); } - Vec_IntPushTwo( p->vTemp, NameId, RangeId ); + Vec_IntPushTwo( &p->vTemp, NameId, RangeId ); Cba_PrsUtilSkipSpaces( p ); if ( !Cba_PrsIsChar(p, ')') ) return Cba_PrsErrorSet(p, "Expecting opening paranthesis after the acctual name.", 2); p->pCur++; @@ -402,10 +402,10 @@ static inline int Cba_PrsReadInstance( Cba_Prs_t * p, int Func ) } } // assign - Vec_IntPush( p->vTypesCur, Type ); - Vec_IntPush( p->vFuncsCur, Func ); - Vec_IntPush( p->vInstIdsCur, InstId ); - Cba_PrsSetupVecInt( p, Vec_WecPushLevel(p->vFaninsCur), p->vTemp ); + Vec_IntPush( &p->vTypesCur, Type ); + Vec_IntPush( &p->vFuncsCur, Func ); + Vec_IntPush( &p->vInstIdsCur, InstId ); + Cba_PrsSetupVecInt( p, Vec_WecPushLevel(&p->vFaninsCur), &p->vTemp ); return 0; } @@ -414,7 +414,7 @@ static inline int Cba_PrsReadInstance( Cba_Prs_t * p, int Func ) static inline int Cba_PrsReadModule( Cba_Prs_t * p ) { int fKnown, iToken, iNameId; - assert( Vec_IntSize(p->vInputsCur) == 0 && Vec_IntSize(p->vOutputsCur) == 0 ); + assert( Vec_IntSize(&p->vInputsCur) == 0 && Vec_IntSize(&p->vOutputsCur) == 0 ); Cba_PrsUtilSkipSpaces( p ); if ( !Cba_PrsOk(p) ) return 0; // read keyword diff --git a/src/base/cba/cbaWriteBlif.c b/src/base/cba/cbaWriteBlif.c index a5d96279..5ef31ac3 100644 --- a/src/base/cba/cbaWriteBlif.c +++ b/src/base/cba/cbaWriteBlif.c @@ -57,6 +57,7 @@ void Cba_PrsWriteBlifArray2( FILE * pFile, Cba_Ntk_t * p, Vec_Int_t * vFanins ) assert( Vec_IntSize(vFanins) % 2 == 0 ); Vec_IntForEachEntryDouble( vFanins, FormId, NameId, i ) fprintf( pFile, " %s=%s", Cba_NtkStr(p, FormId), Cba_NtkStr(p, NameId) ); + fprintf( pFile, "\n" ); } void Cba_PrsWriteBlifLines( FILE * pFile, Cba_Ntk_t * p ) { @@ -67,19 +68,19 @@ void Cba_PrsWriteBlifLines( FILE * pFile, Cba_Ntk_t * p ) { fprintf( pFile, ".names" ); Cba_PrsWriteBlifArray( pFile, p, vFanins, 1 ); - fprintf( pFile, " %s", Cba_NtkStr(p, Func) ); + fprintf( pFile, "%s", Cba_NtkFuncStr(p, Func) ); } else if ( Type == CBA_PRS_BOX ) // .names/assign/box2 (no formal/actual binding) { fprintf( pFile, ".subckt" ); - fprintf( pFile, " %s", Cba_NtkFuncStr(p, Func) ); + fprintf( pFile, " %s", Cba_NtkStr(p, Func) ); Cba_PrsWriteBlifArray2( pFile, p, vFanins ); } else if ( Type == CBA_PRS_LATCH ) // .names/assign/box2 (no formal/actual binding) { fprintf( pFile, ".latch" ); - fprintf( pFile, " %s", Cba_NtkFuncStr(p, Vec_IntEntry(vFanins, 1)) ); - fprintf( pFile, " %s", Cba_NtkFuncStr(p, Vec_IntEntry(vFanins, 0)) ); + fprintf( pFile, " %s", Cba_NtkStr(p, Vec_IntEntry(vFanins, 1)) ); + fprintf( pFile, " %s", Cba_NtkStr(p, Vec_IntEntry(vFanins, 0)) ); fprintf( pFile, " %c\n", '0' + Func ); } } @@ -89,7 +90,9 @@ void Cba_PrsWriteBlifNtk( FILE * pFile, Cba_Ntk_t * p ) assert( Vec_IntSize(&p->vFuncs) == Cba_NtkObjNum(p) ); // write header fprintf( pFile, ".model %s\n", Cba_NtkName(p) ); + if ( Vec_IntSize(&p->vInouts) ) fprintf( pFile, ".inouts" ); + if ( Vec_IntSize(&p->vInouts) ) Cba_PrsWriteBlifArray( pFile, p, &p->vInouts, 0 ); fprintf( pFile, ".inputs" ); Cba_PrsWriteBlifArray( pFile, p, &p->vInputs, 0 ); @@ -97,7 +100,7 @@ void Cba_PrsWriteBlifNtk( FILE * pFile, Cba_Ntk_t * p ) Cba_PrsWriteBlifArray( pFile, p, &p->vOutputs, 0 ); // write objects Cba_PrsWriteBlifLines( pFile, p ); - fprintf( pFile, ".end\n" ); + fprintf( pFile, ".end\n\n" ); } void Cba_PrsWriteBlif( char * pFileName, Cba_Man_t * pDes ) { diff --git a/src/misc/util/utilNam.c b/src/misc/util/utilNam.c index 76c86aff..96c3b283 100644 --- a/src/misc/util/utilNam.c +++ b/src/misc/util/utilNam.c @@ -257,7 +257,7 @@ int Abc_NamStrHash( const char * pStr, const char * pLim, int nTableSize ) unsigned i, uHash; if ( pLim ) { - for ( uHash = 0, i = 0; pStr < pLim; i++ ) + for ( uHash = 0, i = 0; pStr+i < pLim; i++ ) if ( i & 1 ) uHash *= pStr[i] * s_FPrimes[i & 0x7F]; else @@ -285,6 +285,23 @@ int Abc_NamStrHash( const char * pStr, const char * pLim, int nTableSize ) SeeAlso [] ***********************************************************************/ +static inline int Abc_NamStrcmp( char * pStr, char * pLim, char * pThis ) +{ + if ( pLim ) + { + while ( pStr < pLim ) + if ( *pStr++ != *pThis++ ) + return 1; + return *pThis != '\0'; + } + else + { + while ( *pStr ) + if ( *pStr++ != *pThis++ ) + return 1; + return *pThis != '\0'; + } +} static inline int * Abc_NamStrHashFind( Abc_Nam_t * p, const char * pStr, const char * pLim ) { char * pThis; @@ -293,7 +310,7 @@ static inline int * Abc_NamStrHashFind( Abc_Nam_t * p, const char * pStr, const for ( pThis = (*pPlace)? Abc_NamIntToStr(p, *pPlace) : NULL; pThis; pPlace = Abc_NamIntToNextP(p, *pPlace), pThis = (*pPlace)? Abc_NamIntToStr(p, *pPlace) : NULL ) - if ( !strcmp( pStr, pThis ) ) + if ( !Abc_NamStrcmp( (char *)pStr, (char *)pLim, pThis ) ) break; return pPlace; } diff --git a/src/misc/vec/vecStr.h b/src/misc/vec/vecStr.h index f8452bdd..5f04615c 100644 --- a/src/misc/vec/vecStr.h +++ b/src/misc/vec/vecStr.h @@ -201,6 +201,18 @@ static inline Vec_Str_t * Vec_StrDupArray( Vec_Str_t * pVec ) SeeAlso [] ***********************************************************************/ +static inline void Vec_StrZero( Vec_Str_t * p ) +{ + p->pArray = NULL; + p->nSize = 0; + p->nCap = 0; +} +static inline void Vec_StrErase( Vec_Str_t * p ) +{ + ABC_FREE( p->pArray ); + p->nSize = 0; + p->nCap = 0; +} static inline void Vec_StrFree( Vec_Str_t * p ) { ABC_FREE( p->pArray ); |