PageRenderTime 28ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/src/base/cmd/cmdPlugin.c

https://bitbucket.org/alanmi/abc/
C | 773 lines | 430 code | 72 blank | 271 comment | 103 complexity | ba7d3129e9ab519d92c787645cb5f23a MD5 | raw file
Possible License(s): BSD-3-Clause
  1. /**CFile****************************************************************
  2. FileName [cmdPlugin.c]
  3. SystemName [ABC: Logic synthesis and verification system.]
  4. PackageName [Command processing package.]
  5. Synopsis [Integrating external binary.]
  6. Author [Alan Mishchenko, Niklas Een]
  7. Affiliation [UC Berkeley]
  8. Date [Ver. 1.0. Started - September 29, 2010.]
  9. Revision [$Id: cmdPlugin.c,v 1.00 2010/09/29 00:00:00 alanmi Exp $]
  10. ***********************************************************************/
  11. #ifdef WIN32
  12. #include <io.h>
  13. #include <process.h>
  14. #else
  15. #include <unistd.h>
  16. #endif
  17. #include "base/abc/abc.h"
  18. #include "base/main/mainInt.h"
  19. #include "cmd.h"
  20. #include "cmdInt.h"
  21. #include "misc/util/utilSignal.h"
  22. ABC_NAMESPACE_IMPL_START
  23. ////////////////////////////////////////////////////////////////////////
  24. /// DECLARATIONS ///
  25. ////////////////////////////////////////////////////////////////////////
  26. /*
  27. -------- Original Message --------
  28. Subject: ABC/ZZ integration
  29. Date: Wed, 29 Sep 2010 00:34:32 -0700
  30. From: Niklas Een <niklas@een.se>
  31. To: Alan Mishchenko <alanmi@EECS.Berkeley.EDU>
  32. Hi Alan,
  33. Since the interface is file-based, it is important that we generate
  34. good, unique filenames (we may run multiple instances of ABC in the
  35. same directory), so I have attached some portable code for doing that
  36. (tmpFile.c). You can integrate it appropriately.
  37. This is how my interface is meant to work:
  38. (1) As part of your call to Bip, give it first argument "-abc".
  39. This will alter Bip's behavior slightly.
  40. (2) To list the commands, call 'bip -list-commands'.
  41. My commands begin with a comma (so that's my prefix).
  42. (3) All commands expect an input file and an output file.
  43. The input file should be in AIGER format.
  44. The output will be a text file.
  45. Example:
  46. bip -input=tmp.aig -output=tmp.out ,pdr -check -prop=5
  47. So you just auto-generate the two temporary files (output file is
  48. closed and left empty) and stitch the ABC command line at the end.
  49. All you need to check for is if the ABC line begins with a comma.
  50. (4) The result written to the output file will contain a number
  51. of object. Each object is on a separate line of the form:
  52. <object name>: <object data>
  53. That is: name, colon, space, data, newline. If you see a name you don't
  54. recognize, just skip that line (so you will ignore future extensions by me).
  55. I currently define the following objects:
  56. result:
  57. counter-example:
  58. proof-invariant:
  59. bug-free-depth:
  60. abstraction:
  61. "result:" is one of "proved", "failed", "undetermined" (=reached resource limit), "error"
  62. (only used by the abstraction command, and only if resource limit was so tight that the
  63. abstraction was still empty -- no abstraction is returned in this special case).
  64. "counter-example:" -- same format as before
  65. "proof-invariant:" contains an text-encoded single-output AIG. If you want
  66. you can parse it and validate the invariant.
  67. "bug-free-depth:" the depth up to which the procedure has checked for counter-example.
  68. Starts at -1 (not even the initial states have been verified).
  69. "abstraction:" -- same format as before
  70. (5) I propose that you add a command "load_plugin <path/binary>". That way Bob can put
  71. Bip where ever he likes and just modify his abc_rc file.
  72. The intention is that ABC can read this file and act on it without knowing what
  73. particular command was used. If there is an abstraction, you will always apply it.
  74. If there is a "bug-free-depth" you will store that data somewhere so that Bob can query
  75. it through the Python interface, and so on. If we need different actions for different
  76. command, then we add a new object for the new action.
  77. // N.
  78. */
  79. ////////////////////////////////////////////////////////////////////////
  80. /// FUNCTION DEFINITIONS ///
  81. ////////////////////////////////////////////////////////////////////////
  82. /**Function*************************************************************
  83. Synopsis []
  84. Description []
  85. SideEffects []
  86. SeeAlso []
  87. ***********************************************************************/
  88. char * Abc_GetBinaryName( Abc_Frame_t * pAbc, int argc, char ** argv )
  89. {
  90. char * pTemp;
  91. int i;
  92. Vec_PtrForEachEntry( char *, pAbc->vPlugInComBinPairs, pTemp, i )
  93. {
  94. i++;
  95. if ( strcmp( pTemp, argv[0] ) == 0 )
  96. return (char *)Vec_PtrEntry( pAbc->vPlugInComBinPairs, i );
  97. }
  98. assert( 0 );
  99. return NULL;
  100. }
  101. /**Function*************************************************************
  102. Synopsis [Read flop map.]
  103. Description []
  104. SideEffects []
  105. SeeAlso []
  106. ***********************************************************************/
  107. Vec_Str_t * Abc_ManReadFile( char * pFileName )
  108. {
  109. FILE * pFile;
  110. Vec_Str_t * vStr;
  111. int c;
  112. pFile = fopen( pFileName, "r" );
  113. if ( pFile == NULL )
  114. {
  115. printf( "Cannot open file \"%s\".\n", pFileName );
  116. return NULL;
  117. }
  118. vStr = Vec_StrAlloc( 100 );
  119. while ( (c = fgetc(pFile)) != EOF )
  120. Vec_StrPush( vStr, (char)c );
  121. Vec_StrPush( vStr, '\0' );
  122. fclose( pFile );
  123. return vStr;
  124. }
  125. /**Function*************************************************************
  126. Synopsis [Read flop map.]
  127. Description []
  128. SideEffects []
  129. SeeAlso []
  130. ***********************************************************************/
  131. Vec_Int_t * Abc_ManReadBinary( char * pFileName, char * pToken )
  132. {
  133. Vec_Int_t * vMap = NULL;
  134. Vec_Str_t * vStr;
  135. char * pStr;
  136. int i, Length;
  137. vStr = Abc_ManReadFile( pFileName );
  138. if ( vStr == NULL )
  139. return NULL;
  140. pStr = Vec_StrArray( vStr );
  141. pStr = strstr( pStr, pToken );
  142. if ( pStr != NULL )
  143. {
  144. pStr += strlen( pToken );
  145. vMap = Vec_IntAlloc( 100 );
  146. Length = strlen( pStr );
  147. for ( i = 0; i < Length; i++ )
  148. {
  149. if ( pStr[i] == '0' || pStr[i] == '?' )
  150. Vec_IntPush( vMap, 0 );
  151. else if ( pStr[i] == '1' )
  152. Vec_IntPush( vMap, 1 );
  153. if ( ('a' <= pStr[i] && pStr[i] <= 'z') ||
  154. ('A' <= pStr[i] && pStr[i] <= 'Z') )
  155. break;
  156. }
  157. }
  158. Vec_StrFree( vStr );
  159. return vMap;
  160. }
  161. /**Function*************************************************************
  162. Synopsis [Read flop map.]
  163. Description []
  164. SideEffects []
  165. SeeAlso []
  166. ***********************************************************************/
  167. int Abc_ManReadInteger( char * pFileName, char * pToken )
  168. {
  169. int Result = -1;
  170. Vec_Str_t * vStr;
  171. char * pStr;
  172. vStr = Abc_ManReadFile( pFileName );
  173. if ( vStr == NULL )
  174. return -1;
  175. pStr = Vec_StrArray( vStr );
  176. pStr = strstr( pStr, pToken );
  177. if ( pStr != NULL )
  178. Result = atoi( pStr + strlen(pToken) );
  179. Vec_StrFree( vStr );
  180. return Result;
  181. }
  182. /**Function*************************************************************
  183. Synopsis [Read flop map.]
  184. Description []
  185. SideEffects []
  186. SeeAlso []
  187. ***********************************************************************/
  188. int Abc_ManReadStatus( char * pFileName, char * pToken )
  189. {
  190. int Result = -1;
  191. Vec_Str_t * vStr;
  192. char * pStr;
  193. vStr = Abc_ManReadFile( pFileName );
  194. if ( vStr == NULL )
  195. return -1;
  196. pStr = Vec_StrArray( vStr );
  197. pStr = strstr( pStr, pToken );
  198. if ( pStr != NULL )
  199. {
  200. if ( strncmp(pStr+8, "proved", 6) == 0 )
  201. Result = 1;
  202. else if ( strncmp(pStr+8, "failed", 6) == 0 )
  203. Result = 0;
  204. }
  205. Vec_StrFree( vStr );
  206. return Result;
  207. }
  208. /**Function*************************************************************
  209. Synopsis [Work-around to insert 0s for PIs without fanout.]
  210. Description []
  211. SideEffects []
  212. SeeAlso []
  213. ***********************************************************************/
  214. Vec_Int_t * Abc_ManExpandCex( Gia_Man_t * pGia, Vec_Int_t * vCex )
  215. {
  216. Vec_Int_t * vCexNew;
  217. Gia_Obj_t * pObj;
  218. int i, k;
  219. // start with register outputs
  220. vCexNew = Vec_IntAlloc( Vec_IntSize(vCex) );
  221. Gia_ManForEachRo( pGia, pObj, i )
  222. Vec_IntPush( vCexNew, 0 );
  223. ABC_FREE( pGia->pRefs );
  224. Gia_ManCreateRefs( pGia );
  225. k = Gia_ManRegNum( pGia );
  226. while ( 1 )
  227. {
  228. Gia_ManForEachPi( pGia, pObj, i )
  229. {
  230. if ( Gia_ObjRefNum(pGia, pObj) == 0 )
  231. Vec_IntPush( vCexNew, 0 );
  232. else
  233. {
  234. if ( k == Vec_IntSize(vCex) )
  235. break;
  236. Vec_IntPush( vCexNew, Vec_IntEntry(vCex, k++) );
  237. }
  238. }
  239. if ( k == Vec_IntSize(vCex) )
  240. break;
  241. }
  242. return vCexNew;
  243. }
  244. /**Function*************************************************************
  245. Synopsis [Procedure to convert the AIG from text into binary form.]
  246. Description []
  247. SideEffects []
  248. SeeAlso []
  249. ***********************************************************************/
  250. static unsigned textToBin(char* text, unsigned long text_sz)
  251. {
  252. char* dst = text;
  253. const char* src = text;
  254. unsigned sz, i;
  255. sscanf(src, "%u ", &sz);
  256. while(*src++ != ' ');
  257. for ( i = 0; i < sz; i += 3 )
  258. {
  259. dst[0] = (char)( (unsigned)src[0] - '0') | (((unsigned)src[1] - '0') << 6);
  260. dst[1] = (char)(((unsigned)src[1] - '0') >> 2) | (((unsigned)src[2] - '0') << 4);
  261. dst[2] = (char)(((unsigned)src[2] - '0') >> 4) | (((unsigned)src[3] - '0') << 2);
  262. src += 4;
  263. dst += 3;
  264. }
  265. return sz;
  266. }
  267. /**Function*************************************************************
  268. Synopsis [Derives AIG from the text string in the file.]
  269. Description []
  270. SideEffects []
  271. SeeAlso []
  272. ***********************************************************************/
  273. Gia_Man_t * Abc_ManReadAig( char * pFileName, char * pToken )
  274. {
  275. Gia_Man_t * pGia = NULL;
  276. unsigned nBinaryPart;
  277. Vec_Str_t * vStr;
  278. char * pStr, * pEnd;
  279. vStr = Abc_ManReadFile( pFileName );
  280. if ( vStr == NULL )
  281. return NULL;
  282. pStr = Vec_StrArray( vStr );
  283. pStr = strstr( pStr, pToken );
  284. if ( pStr != NULL )
  285. {
  286. // skip token
  287. pStr += strlen(pToken);
  288. // skip spaces
  289. while ( *pStr == ' ' )
  290. pStr++;
  291. // set the end at newline
  292. for ( pEnd = pStr; *pEnd; pEnd++ )
  293. if ( *pEnd == '\r' || *pEnd == '\n' )
  294. {
  295. *pEnd = 0;
  296. break;
  297. }
  298. // convert into binary AIGER
  299. nBinaryPart = textToBin( pStr, strlen(pStr) );
  300. // dump it into file
  301. if ( 0 )
  302. {
  303. FILE * pFile = fopen( "test.aig", "wb" );
  304. fwrite( pStr, 1, nBinaryPart, pFile );
  305. fclose( pFile );
  306. }
  307. // derive AIG
  308. pGia = Gia_AigerReadFromMemory( pStr, nBinaryPart, 0, 0, 0 );
  309. }
  310. Vec_StrFree( vStr );
  311. return pGia;
  312. }
  313. /**Function*************************************************************
  314. Synopsis []
  315. Description []
  316. SideEffects []
  317. SeeAlso []
  318. ***********************************************************************/
  319. int Cmd_CommandAbcPlugIn( Abc_Frame_t * pAbc, int argc, char ** argv )
  320. {
  321. char * pFileIn, * pFileOut;
  322. Vec_Str_t * vCommand;
  323. Vec_Int_t * vCex;
  324. FILE * pFile;
  325. Gia_Man_t * pGia;
  326. int i, fd;
  327. abctime clk;
  328. int fLeaveFiles;
  329. /*
  330. Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
  331. if ( pNtk == NULL )
  332. {
  333. Abc_Print( -1, "Current network does not exist\n" );
  334. return 1;
  335. }
  336. if ( !Abc_NtkIsStrash( pNtk) )
  337. {
  338. Abc_Print( -1, "The current network is not an AIG. Cannot continue.\n" );
  339. return 1;
  340. }
  341. */
  342. if ( pAbc->pGia == NULL )
  343. {
  344. if (argc == 2 && strcmp(argv[1], "-h") == 0)
  345. {
  346. // Run command to produce help string:
  347. vCommand = Vec_StrAlloc( 100 );
  348. Vec_StrAppend( vCommand, Abc_GetBinaryName( pAbc, argc, argv ) );
  349. Vec_StrAppend( vCommand, " -abc " );
  350. Vec_StrAppend( vCommand, argv[0] );
  351. Vec_StrAppend( vCommand, " -h" );
  352. Vec_StrPush( vCommand, 0 );
  353. Util_SignalSystem( Vec_StrArray(vCommand) );
  354. Vec_StrFree( vCommand );
  355. }
  356. else
  357. {
  358. Abc_Print( -1, "Current AIG does not exist (try command &ps).\n" );
  359. }
  360. return 1;
  361. }
  362. // create temp file
  363. fd = Util_SignalTmpFile( "__abctmp_", ".aig", &pFileIn );
  364. if ( fd == -1 )
  365. {
  366. Abc_Print( -1, "Cannot create a temporary file.\n" );
  367. return 1;
  368. }
  369. #ifdef WIN32
  370. _close( fd );
  371. #else
  372. close( fd );
  373. #endif
  374. // create temp file
  375. fd = Util_SignalTmpFile( "__abctmp_", ".out", &pFileOut );
  376. if ( fd == -1 )
  377. {
  378. ABC_FREE( pFileIn );
  379. Abc_Print( -1, "Cannot create a temporary file.\n" );
  380. return 1;
  381. }
  382. #ifdef WIN32
  383. _close( fd );
  384. #else
  385. close( fd );
  386. #endif
  387. // write current network into a file
  388. /*
  389. {
  390. extern Aig_Man_t * Abc_NtkToDar( Abc_Ntk_t * pNtk, int fExors, int fRegisters );
  391. Aig_Man_t * pAig;
  392. pAig = Abc_NtkToDar( pNtk, 0, 1 );
  393. Ioa_WriteAiger( pAig, pFileIn, 0, 0 );
  394. Aig_ManStop( pAig );
  395. }
  396. */
  397. // check what to do with the files
  398. fLeaveFiles = 0;
  399. if ( strcmp( argv[argc-1], "!" ) == 0 )
  400. {
  401. Abc_Print( 0, "Input file \"%s\" and output file \"%s\" are not deleted.\n", pFileIn, pFileOut );
  402. fLeaveFiles = 1;
  403. argc--;
  404. }
  405. // create input file
  406. Gia_AigerWrite( pAbc->pGia, pFileIn, 0, 0 );
  407. // create command line
  408. vCommand = Vec_StrAlloc( 100 );
  409. Vec_StrAppend( vCommand, Abc_GetBinaryName( pAbc, argc, argv ) );
  410. // add input/output file
  411. Vec_StrAppend( vCommand, " -abc" );
  412. // Vec_StrAppend( vCommand, " -input=C:/_projects/abc/_TEST/hwmcc/139442p0.aig" );
  413. Vec_StrAppend( vCommand, " -input=" );
  414. Vec_StrAppend( vCommand, pFileIn );
  415. Vec_StrAppend( vCommand, " -output=" );
  416. Vec_StrAppend( vCommand, pFileOut );
  417. // add other arguments
  418. for ( i = 0; i < argc; i++ )
  419. {
  420. Vec_StrAppend( vCommand, " " );
  421. Vec_StrAppend( vCommand, argv[i] );
  422. }
  423. Vec_StrPush( vCommand, 0 );
  424. // run the command line
  425. //printf( "Running command line: %s\n", Vec_StrArray(vCommand) );
  426. clk = Abc_Clock();
  427. if ( Util_SignalSystem( Vec_StrArray(vCommand) ) )
  428. {
  429. Abc_Print( -1, "The following command has returned non-zero exit status:\n" );
  430. Abc_Print( -1, "\"%s\"\n", Vec_StrArray(vCommand) );
  431. return 1;
  432. }
  433. clk = Abc_Clock() - clk;
  434. Vec_StrFree( vCommand );
  435. // check if the output file exists
  436. if ( (pFile = fopen( pFileOut, "r" )) == NULL )
  437. {
  438. Abc_Print( -1, "There is no output file \"%s\".\n", pFileOut );
  439. return 1;
  440. }
  441. fclose( pFile );
  442. // process the output
  443. if ( Extra_FileSize(pFileOut) > 0 )
  444. {
  445. // get status
  446. pAbc->Status = Abc_ManReadStatus( pFileOut, "result:" );
  447. // get bug-free depth
  448. pAbc->nFrames = Abc_ManReadInteger( pFileOut, "bug-free-depth:" );
  449. // get abstraction
  450. pAbc->pGia->vFlopClasses = Abc_ManReadBinary( pFileOut, "abstraction:" );
  451. // get counter-example
  452. vCex = Abc_ManReadBinary( pFileOut, "counter-example:" );
  453. if ( vCex )
  454. {
  455. int nFrames, nRemain;
  456. nFrames = (Vec_IntSize(vCex) - Gia_ManRegNum(pAbc->pGia)) / Gia_ManPiNum(pAbc->pGia);
  457. nRemain = (Vec_IntSize(vCex) - Gia_ManRegNum(pAbc->pGia)) % Gia_ManPiNum(pAbc->pGia);
  458. if ( nRemain != 0 )
  459. {
  460. Vec_Int_t * vTemp;
  461. Abc_Print( 1, "Adjusting counter-example by adding zeros for PIs without fanout.\n" );
  462. // expand the counter-example to include PIs without fanout
  463. vCex = Abc_ManExpandCex( pAbc->pGia, vTemp = vCex );
  464. Vec_IntFree( vTemp );
  465. }
  466. nFrames = (Vec_IntSize(vCex) - Gia_ManRegNum(pAbc->pGia)) / Gia_ManPiNum(pAbc->pGia);
  467. nRemain = (Vec_IntSize(vCex) - Gia_ManRegNum(pAbc->pGia)) % Gia_ManPiNum(pAbc->pGia);
  468. if ( nRemain != 0 )
  469. Abc_Print( 1, "Counter example has a wrong length.\n" );
  470. else
  471. {
  472. Abc_Print( 1, "Problem is satisfiable. Found counter-example in frame %d. ", nFrames-1 );
  473. Abc_PrintTime( 1, "Time", clk );
  474. ABC_FREE( pAbc->pCex );
  475. pAbc->pCex = Abc_CexCreate( Gia_ManRegNum(pAbc->pGia), Gia_ManPiNum(pAbc->pGia), Vec_IntArray(vCex), nFrames-1, 0, 0 );
  476. // Abc_CexPrint( pAbc->pCex );
  477. // if ( !Gia_ManVerifyCex( pAbc->pGia, pAbc->pCex, 0 ) )
  478. // Abc_Print( 1, "Generated counter-example is INVALID.\n" );
  479. // remporary work-around to detect the output number - October 18, 2010
  480. pAbc->pCex->iPo = Gia_ManFindFailedPoCex( pAbc->pGia, pAbc->pCex, 0 );
  481. if ( pAbc->pCex->iPo == -1 )
  482. {
  483. Abc_Print( 1, "Generated counter-example is INVALID.\n" );
  484. ABC_FREE( pAbc->pCex );
  485. }
  486. else
  487. {
  488. Abc_Print( 1, "Returned counter-example successfully verified in ABC.\n" );
  489. }
  490. }
  491. Vec_IntFreeP( &vCex );
  492. }
  493. // get AIG if present
  494. pGia = Abc_ManReadAig( pFileOut, "aig:" );
  495. if ( pGia != NULL )
  496. {
  497. Gia_ManStopP( &pAbc->pGia );
  498. pAbc->pGia = pGia;
  499. }
  500. }
  501. // clean up
  502. Util_SignalTmpFileRemove( pFileIn, fLeaveFiles );
  503. Util_SignalTmpFileRemove( pFileOut, fLeaveFiles );
  504. ABC_FREE( pFileIn );
  505. ABC_FREE( pFileOut );
  506. return 0;
  507. }
  508. /**Function*************************************************************
  509. Synopsis []
  510. Description []
  511. SideEffects []
  512. SeeAlso []
  513. ***********************************************************************/
  514. int Cmd_CommandAbcLoadPlugIn( Abc_Frame_t * pAbc, int argc, char ** argv )
  515. {
  516. int fPath, fVerbose;
  517. int fd = -1, RetValue = -1, c;
  518. FILE * pFile = NULL;
  519. char * pStrDirBin = NULL, * pStrSection = NULL;
  520. Vec_Str_t * sCommandLine = NULL;
  521. char * pTempFile = NULL;
  522. char pBuffer[1000];
  523. // set defaults
  524. fPath = 0;
  525. fVerbose = 0;
  526. Extra_UtilGetoptReset();
  527. while ( ( c = Extra_UtilGetopt( argc, argv, "vph" ) ) != EOF )
  528. {
  529. switch ( c )
  530. {
  531. case 'p':
  532. fPath ^= 1;
  533. break;
  534. case 'v':
  535. fVerbose ^= 1;
  536. break;
  537. default:
  538. goto usage;
  539. }
  540. }
  541. if ( argc != globalUtilOptind + 2 )
  542. goto usage;
  543. pStrDirBin = argv[argc-2];
  544. pStrSection = argv[argc-1];
  545. // check if the file exists
  546. if ( !fPath )
  547. {
  548. FILE* pFile = fopen( pStrDirBin, "r" );
  549. if ( !pFile )
  550. {
  551. Abc_Print( ABC_ERROR, "Cannot run the binary \"%s\". File does not exist.\n", pStrDirBin );
  552. goto cleanup;
  553. }
  554. fclose( pFile );
  555. }
  556. // create temp file
  557. fd = Util_SignalTmpFile( "__abctmp_", ".txt", &pTempFile );
  558. if ( fd == -1 )
  559. {
  560. Abc_Print( ABC_ERROR, "Cannot create a temporary file.\n" );
  561. goto cleanup;
  562. }
  563. #ifdef WIN32
  564. _close( fd );
  565. #else
  566. close( fd );
  567. #endif
  568. // get command list
  569. sCommandLine = Vec_StrAlloc(1000);
  570. Vec_StrPrintF(sCommandLine, "%s -abc -list-commands > %s", pStrDirBin, pTempFile );
  571. Vec_StrPush(sCommandLine, '\0');
  572. if(fVerbose)
  573. {
  574. Abc_Print(ABC_VERBOSE, "Running command %s\n", Vec_StrArray(sCommandLine));
  575. }
  576. RetValue = Util_SignalSystem( Vec_StrArray(sCommandLine) );
  577. if ( RetValue != 0 )
  578. {
  579. Abc_Print( ABC_ERROR, "Command \"%s\" failed.\n", Vec_StrArray(sCommandLine) );
  580. goto cleanup;
  581. }
  582. // create commands
  583. pFile = fopen( pTempFile, "r" );
  584. if ( pFile == NULL )
  585. {
  586. Abc_Print( -1, "Cannot open file with the list of commands.\n" );
  587. RetValue = -1;
  588. goto cleanup;
  589. }
  590. while ( fgets( pBuffer, 1000, pFile ) != NULL )
  591. {
  592. if ( pBuffer[strlen(pBuffer)-1] == '\n' )
  593. pBuffer[strlen(pBuffer)-1] = 0;
  594. Cmd_CommandAdd( pAbc, pStrSection, pBuffer, Cmd_CommandAbcPlugIn, 1 );
  595. Vec_PtrPush( pAbc->vPlugInComBinPairs, Extra_UtilStrsav(pBuffer) );
  596. Vec_PtrPush( pAbc->vPlugInComBinPairs, Extra_UtilStrsav(pStrDirBin) );
  597. if ( fVerbose )
  598. {
  599. Abc_Print(ABC_VERBOSE, "Creating command %s with binary %s\n", pBuffer, pStrDirBin);
  600. }
  601. }
  602. cleanup:
  603. if( pFile )
  604. fclose( pFile );
  605. if( pTempFile )
  606. Util_SignalTmpFileRemove( pTempFile, 0 );
  607. Vec_StrFreeP(&sCommandLine);
  608. ABC_FREE( pTempFile );
  609. return RetValue;
  610. usage:
  611. Abc_Print( -2, "usage: load_plugin [-pvh] <plugin_dir\\binary_name> <section_name>\n" );
  612. Abc_Print( -2, "\t loads external binary as a plugin\n" );
  613. Abc_Print( -2, "\t-p : toggle searching the command in PATH [default = %s].\n", fPath? "yes": "no" );
  614. Abc_Print( -2, "\t-v : enable verbose output [default = %s].\n", fVerbose? "yes": "no" );
  615. Abc_Print( -2, "\t-h : print the command usage\n");
  616. return 1;
  617. }
  618. ////////////////////////////////////////////////////////////////////////
  619. /// END OF FILE ///
  620. ////////////////////////////////////////////////////////////////////////
  621. ABC_NAMESPACE_IMPL_END