You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1491 lines
44 KiB

  1. /**CFile**********************************************************************
  2. FileName [dddmpLoad.c]
  3. PackageName [dddmp]
  4. Synopsis [Functions to read in bdds to file]
  5. Description [Functions to read in bdds to file. BDDs
  6. are represended on file either in text or binary format under the
  7. following rules. A file contains a forest of BDDs (a vector of
  8. Boolean functions). BDD nodes are numbered with contiguous numbers,
  9. from 1 to NNodes (total number of nodes on a file). 0 is not used to
  10. allow negative node indexes for complemented edges. A file contains
  11. a header, including information about variables and roots to BDD
  12. functions, followed by the list of nodes. BDD nodes are listed
  13. according to their numbering, and in the present implementation
  14. numbering follows a post-order strategy, in such a way that a node
  15. is never listed before its Then/Else children.
  16. ]
  17. Author [Gianpiero Cabodi and Stefano Quer]
  18. Copyright [
  19. Copyright (c) 2004 by Politecnico di Torino.
  20. All Rights Reserved. This software is for educational purposes only.
  21. Permission is given to academic institutions to use, copy, and modify
  22. this software and its documentation provided that this introductory
  23. message is not removed, that this software and its documentation is
  24. used for the institutions' internal research and educational purposes,
  25. and that no monies are exchanged. No guarantee is expressed or implied
  26. by the distribution of this code.
  27. Send bug-reports and/or questions to:
  28. {gianpiero.cabodi,stefano.quer}@polito.it.
  29. ]
  30. ******************************************************************************/
  31. #include "dddmpInt.h"
  32. /*---------------------------------------------------------------------------*/
  33. /* Stucture declarations */
  34. /*---------------------------------------------------------------------------*/
  35. /*---------------------------------------------------------------------------*/
  36. /* Type declarations */
  37. /*---------------------------------------------------------------------------*/
  38. /*---------------------------------------------------------------------------*/
  39. /* Variable declarations */
  40. /*---------------------------------------------------------------------------*/
  41. /*---------------------------------------------------------------------------*/
  42. /* Macro declarations */
  43. /*---------------------------------------------------------------------------*/
  44. #define matchkeywd(str,key) (strncmp(str,key,strlen(key))==0)
  45. /**AutomaticStart*************************************************************/
  46. /*---------------------------------------------------------------------------*/
  47. /* Static function prototypes */
  48. /*---------------------------------------------------------------------------*/
  49. static int DddmpCuddDdArrayLoad(Dddmp_DecompType ddType, DdManager *ddMgr, Dddmp_RootMatchType rootMatchMode, char **rootmatchnames, Dddmp_VarMatchType varMatchMode, char **varmatchnames, int *varmatchauxids, int *varcomposeids, int mode, char *file, FILE *fp, DdNode ***pproots);
  50. static Dddmp_Hdr_t * DddmpBddReadHeader(char *file, FILE *fp);
  51. static void DddmpFreeHeader(Dddmp_Hdr_t *Hdr);
  52. /**AutomaticEnd***************************************************************/
  53. /*---------------------------------------------------------------------------*/
  54. /* Definition of exported functions */
  55. /*---------------------------------------------------------------------------*/
  56. /**Function********************************************************************
  57. Synopsis [Reads a dump file representing the argument BDD.]
  58. Description [Reads a dump file representing the argument BDD.
  59. Dddmp_cuddBddArrayLoad is used through a dummy array (see this
  60. function's description for more details).
  61. Mode, the requested input file format, is checked against
  62. the file format.
  63. The loaded BDDs is referenced before returning it.
  64. ]
  65. SideEffects [A vector of pointers to DD nodes is allocated and freed.]
  66. SeeAlso [Dddmp_cuddBddStore, Dddmp_cuddBddArrayLoad]
  67. ******************************************************************************/
  68. DdNode *
  69. Dddmp_cuddBddLoad (
  70. DdManager *ddMgr /* IN: DD Manager */,
  71. Dddmp_VarMatchType varMatchMode /* IN: storing mode selector */,
  72. char **varmatchnames /* IN: array of variable names - by IDs */,
  73. int *varmatchauxids /* IN: array of variable auxids - by IDs */,
  74. int *varcomposeids /* IN: array of new ids accessed - by IDs */,
  75. int mode /* IN: requested input file format */,
  76. char *file /* IN: file name */,
  77. FILE *fp /* IN: file pointer */
  78. )
  79. {
  80. DdNode *f , **tmpArray;
  81. int i, nRoots;
  82. nRoots = Dddmp_cuddBddArrayLoad(ddMgr,DDDMP_ROOT_MATCHLIST,NULL,
  83. varMatchMode,varmatchnames,varmatchauxids,varcomposeids,
  84. mode,file,fp,&tmpArray);
  85. if (nRoots == 0) {
  86. return (NULL);
  87. } else {
  88. f = tmpArray[0];
  89. if (nRoots > 1) {
  90. fprintf (stderr,
  91. "Warning: %d BDD roots found in file. Only first retrieved.\n",
  92. nRoots);
  93. for (i=1; i<nRoots; i++) {
  94. Cudd_RecursiveDeref (ddMgr, tmpArray[i]);
  95. }
  96. }
  97. DDDMP_FREE (tmpArray);
  98. return (f);
  99. }
  100. }
  101. /**Function********************************************************************
  102. Synopsis [Reads a dump file representing the argument BDDs.]
  103. Description [Reads a dump file representing the argument BDDs. The header is
  104. common to both text and binary mode. The node list is either
  105. in text or binary format. A dynamic vector of DD pointers
  106. is allocated to support conversion from DD indexes to pointers.
  107. Several criteria are supported for variable match between file
  108. and dd manager. Several changes/permutations/compositions are allowed
  109. for variables while loading DDs. Variable of the dd manager are allowed
  110. to match with variables on file on ids, permids, varnames,
  111. varauxids; also direct composition between ids and
  112. composeids is supported. More in detail:
  113. <ol>
  114. <li> varMatchMode=DDDMP_VAR_MATCHIDS <p>
  115. allows the loading of a DD keeping variable IDs unchanged
  116. (regardless of the variable ordering of the reading manager); this
  117. is useful, for example, when swapping DDs to file and restoring them
  118. later from file, after possible variable reordering activations.
  119. <li> varMatchMode=DDDMP_VAR_MATCHPERMIDS <p>
  120. is used to allow variable match according to the position in the
  121. ordering.
  122. <li> varMatchMode=DDDMP_VAR_MATCHNAMES <p>
  123. requires a non NULL varmatchnames parameter; this is a vector of
  124. strings in one-to-one correspondence with variable IDs of the
  125. reading manager. Variables in the DD file read are matched with
  126. manager variables according to their name (a non NULL varnames
  127. parameter was required while storing the DD file).
  128. <li> varMatchMode=DDDMP_VAR_MATCHIDS <p>
  129. has a meaning similar to DDDMP_VAR_MATCHNAMES, but integer auxiliary
  130. IDs are used instead of strings; the additional non NULL
  131. varmatchauxids parameter is needed.
  132. <li> varMatchMode=DDDMP_VAR_COMPOSEIDS <p>
  133. uses the additional varcomposeids parameter is used as array of
  134. variable ids to be composed with ids stored in file.
  135. </ol>
  136. In the present implementation, the array varnames (3), varauxids (4)
  137. and composeids (5) need to have one entry for each variable in the
  138. DD manager (NULL pointers are allowed for unused variables
  139. in varnames). Hence variables need to be already present in the
  140. manager. All arrays are sorted according to IDs.
  141. All the loaded BDDs are referenced before returning them.
  142. ]
  143. SideEffects [A vector of pointers to DD nodes is allocated and freed.]
  144. SeeAlso [Dddmp_cuddBddArrayStore]
  145. ******************************************************************************/
  146. int
  147. Dddmp_cuddBddArrayLoad (
  148. DdManager *ddMgr /* IN: DD Manager */,
  149. Dddmp_RootMatchType rootMatchMode /* IN: storing mode selector */,
  150. char **rootmatchnames /* IN: sorted names for loaded roots */,
  151. Dddmp_VarMatchType varMatchMode /* IN: storing mode selector */,
  152. char **varmatchnames /* IN: array of variable names, by ids */,
  153. int *varmatchauxids /* IN: array of variable auxids, by ids */,
  154. int *varcomposeids /* IN: array of new ids, by ids */,
  155. int mode /* IN: requested input file format */,
  156. char *file /* IN: file name */,
  157. FILE *fp /* IN: file pointer */,
  158. DdNode ***pproots /* OUT: array of returned BDD roots */
  159. )
  160. {
  161. int retValue;
  162. #ifdef DDDMP_DEBUG
  163. #ifndef __alpha__
  164. int retValueBis;
  165. retValueBis = Cudd_DebugCheck (ddMgr);
  166. if (retValueBis == 1) {
  167. fprintf (stderr, "Inconsistency Found During BDD Load.\n");
  168. fflush (stderr);
  169. } else {
  170. if (retValueBis == CUDD_OUT_OF_MEM) {
  171. fprintf (stderr, "Out of Memory During BDD Load.\n");
  172. fflush (stderr);
  173. }
  174. }
  175. #endif
  176. #endif
  177. retValue = DddmpCuddDdArrayLoad (DDDMP_BDD, ddMgr, rootMatchMode,
  178. rootmatchnames, varMatchMode, varmatchnames, varmatchauxids,
  179. varcomposeids, mode, file, fp, pproots);
  180. #ifdef DDDMP_DEBUG
  181. #ifndef __alpha__
  182. retValueBis = Cudd_DebugCheck (ddMgr);
  183. if (retValueBis == 1) {
  184. fprintf (stderr, "Inconsistency Found During BDD Load.\n");
  185. fflush (stderr);
  186. } else {
  187. if (retValueBis == CUDD_OUT_OF_MEM) {
  188. fprintf (stderr, "Out of Memory During BDD Load.\n");
  189. fflush (stderr);
  190. }
  191. }
  192. #endif
  193. #endif
  194. return (retValue);
  195. }
  196. /**Function********************************************************************
  197. Synopsis [Reads a dump file representing the argument ADD.]
  198. Description [Reads a dump file representing the argument ADD.
  199. Dddmp_cuddAddArrayLoad is used through a dummy array.
  200. ]
  201. SideEffects [A vector of pointers to DD nodes is allocated and freed.]
  202. SeeAlso [Dddmp_cuddAddStore, Dddmp_cuddAddArrayLoad]
  203. ******************************************************************************/
  204. DdNode *
  205. Dddmp_cuddAddLoad (
  206. DdManager *ddMgr /* IN: Manager */,
  207. Dddmp_VarMatchType varMatchMode /* IN: storing mode selector */,
  208. char **varmatchnames /* IN: array of variable names by IDs */,
  209. int *varmatchauxids /* IN: array of variable auxids by IDs */,
  210. int *varcomposeids /* IN: array of new ids by IDs */,
  211. int mode /* IN: requested input file format */,
  212. char *file /* IN: file name */,
  213. FILE *fp /* IN: file pointer */
  214. )
  215. {
  216. DdNode *f , **tmpArray;
  217. int i, nRoots;
  218. nRoots = Dddmp_cuddAddArrayLoad (ddMgr, DDDMP_ROOT_MATCHLIST,NULL,
  219. varMatchMode, varmatchnames, varmatchauxids, varcomposeids,
  220. mode, file, fp, &tmpArray);
  221. if (nRoots == 0) {
  222. return (NULL);
  223. } else {
  224. f = tmpArray[0];
  225. if (nRoots > 1) {
  226. fprintf (stderr,
  227. "Warning: %d BDD roots found in file. Only first retrieved.\n",
  228. nRoots);
  229. for (i=1; i<nRoots; i++) {
  230. Cudd_RecursiveDeref (ddMgr, tmpArray[i]);
  231. }
  232. }
  233. DDDMP_FREE (tmpArray);
  234. return (f);
  235. }
  236. }
  237. /**Function********************************************************************
  238. Synopsis [Reads a dump file representing the argument ADDs.]
  239. Description [Reads a dump file representing the argument ADDs. See
  240. BDD load functions for detailed explanation.
  241. ]
  242. SideEffects [A vector of pointers to DD nodes is allocated and freed.]
  243. SeeAlso [Dddmp_cuddBddArrayStore]
  244. ******************************************************************************/
  245. int
  246. Dddmp_cuddAddArrayLoad (
  247. DdManager *ddMgr /* IN: DD Manager */,
  248. Dddmp_RootMatchType rootMatchMode /* IN: storing mode selector */,
  249. char **rootmatchnames /* IN: sorted names for loaded roots */,
  250. Dddmp_VarMatchType varMatchMode /* IN: storing mode selector */,
  251. char **varmatchnames /* IN: array of variable names, by ids */,
  252. int *varmatchauxids /* IN: array of variable auxids, by ids */,
  253. int *varcomposeids /* IN: array of new ids, by ids */,
  254. int mode /* IN: requested input file format */,
  255. char *file /* IN: file name */,
  256. FILE *fp /* IN: file pointer */,
  257. DdNode ***pproots /* OUT: array of returned BDD roots */
  258. )
  259. {
  260. int retValue;
  261. #if 0
  262. #ifdef DDDMP_DEBUG
  263. #ifndef __alpha__
  264. int retValueBis;
  265. retValueBis = Cudd_DebugCheck (ddMgr);
  266. if (retValueBis == 1) {
  267. fprintf (stderr, "Inconsistency Found During ADD Load.\n");
  268. fflush (stderr);
  269. } else {
  270. if (retValueBis == CUDD_OUT_OF_MEM) {
  271. fprintf (stderr, "Out of Memory During ADD Load.\n");
  272. fflush (stderr);
  273. }
  274. }
  275. #endif
  276. #endif
  277. #endif
  278. retValue = DddmpCuddDdArrayLoad (DDDMP_ADD, ddMgr, rootMatchMode,
  279. rootmatchnames, varMatchMode, varmatchnames, varmatchauxids,
  280. varcomposeids, mode, file, fp, pproots);
  281. #if 0
  282. #ifdef DDDMP_DEBUG
  283. #ifndef __alpha__
  284. retValueBis = Cudd_DebugCheck (ddMgr);
  285. if (retValueBis == 1) {
  286. fprintf (stderr, "Inconsistency Found During ADD Load.\n");
  287. fflush (stderr);
  288. } else {
  289. if (retValueBis == CUDD_OUT_OF_MEM) {
  290. fprintf (stderr, "Out of Memory During ADD Load.\n");
  291. fflush (stderr);
  292. }
  293. }
  294. #endif
  295. #endif
  296. #endif
  297. return (retValue);
  298. }
  299. /**Function********************************************************************
  300. Synopsis [Reads the header of a dump file representing the argument BDDs]
  301. Description [Reads the header of a dump file representing the argument BDDs.
  302. Returns main information regarding DD type stored in the file,
  303. the variable ordering used, the number of variables, etc.
  304. It reads only the header of the file NOT the BDD/ADD section.
  305. ]
  306. SideEffects []
  307. SeeAlso [Dddmp_cuddBddArrayLoad]
  308. ******************************************************************************/
  309. int
  310. Dddmp_cuddHeaderLoad (
  311. Dddmp_DecompType *ddType /* OUT: selects the proper decomp type */,
  312. int *nVars /* OUT: number of DD variables */,
  313. int *nsuppvars /* OUT: number of support variables */,
  314. char ***suppVarNames /* OUT: array of support variable names */,
  315. char ***orderedVarNames /* OUT: array of variable names */,
  316. int **varIds /* OUT: array of variable ids */,
  317. int **varComposeIds /* OUT: array of permids ids */,
  318. int **varAuxIds /* OUT: array of variable aux ids */,
  319. int *nRoots /* OUT: number of root in the file */,
  320. char *file /* IN: file name */,
  321. FILE *fp /* IN: file pointer */
  322. )
  323. {
  324. Dddmp_Hdr_t *Hdr;
  325. int i, fileToClose;
  326. int *tmpVarIds = NULL;
  327. int *tmpVarComposeIds = NULL;
  328. int *tmpVarAuxIds = NULL;
  329. fileToClose = 0;
  330. if (fp == NULL) {
  331. fp = fopen (file, "r");
  332. Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.",
  333. failure);
  334. fileToClose = 1;
  335. }
  336. Hdr = DddmpBddReadHeader (NULL, fp);
  337. Dddmp_CheckAndGotoLabel (Hdr->nnodes==0, "Zero number of nodes.",
  338. failure);
  339. /*
  340. * Type, number of variables (tot and support)
  341. */
  342. *ddType = Hdr->ddType;
  343. *nVars = Hdr->nVars;
  344. *nsuppvars = Hdr->nsuppvars;
  345. /*
  346. * Support Varnames
  347. */
  348. if (Hdr->suppVarNames != NULL) {
  349. *suppVarNames = DDDMP_ALLOC (char *, *nsuppvars);
  350. Dddmp_CheckAndGotoLabel (*suppVarNames==NULL,
  351. "Error allocating memory.", failure);
  352. for (i=0; i<*nsuppvars; i++) {
  353. (*suppVarNames)[i] = DDDMP_ALLOC (char,
  354. (strlen (Hdr->suppVarNames[i]) + 1));
  355. Dddmp_CheckAndGotoLabel (Hdr->suppVarNames[i]==NULL,
  356. "Support Variable Name Missing in File.", failure);
  357. strcpy ((*suppVarNames)[i], Hdr->suppVarNames[i]);
  358. }
  359. } else {
  360. *suppVarNames = NULL;
  361. }
  362. /*
  363. * Ordered Varnames
  364. */
  365. if (Hdr->orderedVarNames != NULL) {
  366. *orderedVarNames = DDDMP_ALLOC (char *, *nVars);
  367. Dddmp_CheckAndGotoLabel (*orderedVarNames==NULL,
  368. "Error allocating memory.", failure);
  369. for (i=0; i<*nVars; i++) {
  370. (*orderedVarNames)[i] = DDDMP_ALLOC (char,
  371. (strlen (Hdr->orderedVarNames[i]) + 1));
  372. Dddmp_CheckAndGotoLabel (Hdr->orderedVarNames[i]==NULL,
  373. "Support Variable Name Missing in File.", failure);
  374. strcpy ((*orderedVarNames)[i], Hdr->orderedVarNames[i]);
  375. }
  376. } else {
  377. *orderedVarNames = NULL;
  378. }
  379. /*
  380. * Variable Ids
  381. */
  382. if (Hdr->ids != NULL) {
  383. tmpVarIds = DDDMP_ALLOC (int, *nsuppvars);
  384. Dddmp_CheckAndGotoLabel (tmpVarIds==NULL, "Error allocating memory.",
  385. failure);
  386. for (i=0; i<*nsuppvars; i++) {
  387. tmpVarIds[i] = Hdr->ids[i];
  388. }
  389. *varIds = tmpVarIds;
  390. } else {
  391. *varIds = NULL;
  392. }
  393. /*
  394. * Variable Compose Ids
  395. */
  396. if (Hdr->permids != NULL) {
  397. tmpVarComposeIds = DDDMP_ALLOC (int, *nsuppvars);
  398. Dddmp_CheckAndGotoLabel (tmpVarComposeIds==NULL,
  399. "Error allocating memory.", failure);
  400. for (i=0; i<*nsuppvars; i++) {
  401. tmpVarComposeIds[i] = Hdr->permids[i];
  402. }
  403. *varComposeIds = tmpVarComposeIds;
  404. } else {
  405. *varComposeIds = NULL;
  406. }
  407. /*
  408. * Variable Auxiliary Ids
  409. */
  410. if (Hdr->auxids != NULL) {
  411. tmpVarAuxIds = DDDMP_ALLOC (int, *nsuppvars);
  412. Dddmp_CheckAndGotoLabel (tmpVarAuxIds==NULL,
  413. "Error allocating memory.", failure);
  414. for (i=0; i<*nsuppvars; i++) {
  415. tmpVarAuxIds[i] = Hdr->auxids[i];
  416. }
  417. *varAuxIds = tmpVarAuxIds;
  418. } else {
  419. *varAuxIds = NULL;
  420. }
  421. /*
  422. * Number of roots
  423. */
  424. *nRoots = Hdr->nRoots;
  425. /*
  426. * Free and Return
  427. */
  428. if (fileToClose == 1) {
  429. fclose (fp);
  430. }
  431. DddmpFreeHeader(Hdr);
  432. return (DDDMP_SUCCESS);
  433. failure:
  434. return (DDDMP_FAILURE);
  435. }
  436. /*---------------------------------------------------------------------------*/
  437. /* Definition of internal functions */
  438. /*---------------------------------------------------------------------------*/
  439. /*---------------------------------------------------------------------------*/
  440. /* Definition of static functions */
  441. /*---------------------------------------------------------------------------*/
  442. /**Function********************************************************************
  443. Synopsis [Reads a dump file representing the argument BDDs.]
  444. Description [Reads a dump file representing the argument BDDs. The header is
  445. common to both text and binary mode. The node list is either
  446. in text or binary format. A dynamic vector of DD pointers
  447. is allocated to support conversion from DD indexes to pointers.
  448. Several criteria are supported for variable match between file
  449. and dd manager. Several changes/permutations/compositions are allowed
  450. for variables while loading DDs. Variable of the dd manager are allowed
  451. to match with variables on file on ids, permids, varnames,
  452. varauxids; also direct composition between ids and
  453. composeids is supported. More in detail:
  454. <ol>
  455. <li> varMatchMode=DDDMP_VAR_MATCHIDS <p>
  456. allows the loading of a DD keeping variable IDs unchanged
  457. (regardless of the variable ordering of the reading manager); this
  458. is useful, for example, when swapping DDs to file and restoring them
  459. later from file, after possible variable reordering activations.
  460. <li> varMatchMode=DDDMP_VAR_MATCHPERMIDS <p>
  461. is used to allow variable match according to the position in the ordering.
  462. <li> varMatchMode=DDDMP_VAR_MATCHNAMES <p>
  463. requires a non NULL varmatchnames parameter; this is a vector of
  464. strings in one-to-one correspondence with variable IDs of the
  465. reading manager. Variables in the DD file read are matched with
  466. manager variables according to their name (a non NULL varnames
  467. parameter was required while storing the DD file).
  468. <li> varMatchMode=DDDMP_VAR_MATCHIDS <p>
  469. has a meaning similar to DDDMP_VAR_MATCHNAMES, but integer auxiliary
  470. IDs are used instead of strings; the additional non NULL
  471. varmatchauxids parameter is needed.
  472. <li> varMatchMode=DDDMP_VAR_COMPOSEIDS <p>
  473. uses the additional varcomposeids parameter is used as array of
  474. variable ids to be composed with ids stored in file.
  475. </ol>
  476. In the present implementation, the array varnames (3), varauxids (4)
  477. and composeids (5) need to have one entry for each variable in the
  478. DD manager (NULL pointers are allowed for unused variables
  479. in varnames). Hence variables need to be already present in the
  480. manager. All arrays are sorted according to IDs.
  481. ]
  482. SideEffects [A vector of pointers to DD nodes is allocated and freed.]
  483. SeeAlso [Dddmp_cuddBddArrayStore]
  484. ******************************************************************************/
  485. static int
  486. DddmpCuddDdArrayLoad (
  487. Dddmp_DecompType ddType /* IN: Selects decomp type */,
  488. DdManager *ddMgr /* IN: DD Manager */,
  489. Dddmp_RootMatchType rootMatchMode /* IN: storing mode selector */,
  490. char **rootmatchnames /* IN: sorted names for loaded roots */,
  491. Dddmp_VarMatchType varMatchMode /* IN: storing mode selector */,
  492. char **varmatchnames /* IN: array of variable names, by ids */,
  493. int *varmatchauxids /* IN: array of variable auxids, by ids */,
  494. int *varcomposeids /* IN: array of new ids, by ids */,
  495. int mode /* IN: requested input file format */,
  496. char *file /* IN: file name */,
  497. FILE *fp /* IN: file pointer */,
  498. DdNode ***pproots /* OUT: array BDD roots (by reference) */
  499. )
  500. {
  501. Dddmp_Hdr_t *Hdr = NULL;
  502. DdNode *f = NULL;
  503. DdNode *T = NULL;
  504. DdNode *E = NULL;
  505. struct binary_dd_code code;
  506. char buf[DDDMP_MAXSTRLEN];
  507. int retValue, id, size, maxv;
  508. int i, j, k, maxaux, var, vT, vE, idT, idE;
  509. double addConstant;
  510. int *permsupport = NULL;
  511. int *convertids = NULL;
  512. int *invconvertids = NULL;
  513. int *invauxids = NULL;
  514. char **sortedvarnames = NULL;
  515. int nddvars, nRoots;
  516. DdNode **pnodes = NULL;
  517. unsigned char *pvars1byte = NULL;
  518. unsigned short *pvars2byte = NULL;
  519. DdNode **proots = NULL;
  520. int fileToClose = 0;
  521. char *retval;
  522. *pproots = NULL;
  523. if (fp == NULL) {
  524. fp = fopen (file, "r");
  525. Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.",
  526. failure);
  527. fileToClose = 1;
  528. }
  529. nddvars = ddMgr->size;
  530. Hdr = DddmpBddReadHeader (NULL, fp);
  531. Dddmp_CheckAndGotoLabel (Hdr->nnodes==0, "Zero number of nodes.",
  532. failure);
  533. nRoots = Hdr->nRoots;
  534. if (Hdr->ddType != ddType) {
  535. (void) fprintf (stderr, "DdLoad Error: ddType mismatch\n");
  536. if (Hdr->ddType == DDDMP_BDD)
  537. (void) fprintf (stderr, "BDD found\n");
  538. if (Hdr->ddType == DDDMP_ADD)
  539. (void) fprintf (stderr, "ADD found\n");
  540. if (ddType == DDDMP_BDD)
  541. (void) fprintf (stderr, "when loading a BDD\n");
  542. if (ddType == DDDMP_ADD)
  543. (void) fprintf (stderr, "when loading an ADD\n");
  544. fflush (stderr);
  545. goto failure;
  546. }
  547. if (Hdr->mode != mode) {
  548. Dddmp_CheckAndGotoLabel (mode!=DDDMP_MODE_DEFAULT,
  549. "Mode Mismatch.", failure);
  550. mode = Hdr->mode;
  551. }
  552. /*
  553. * For each variable in the support
  554. * compute the relative position in the ordering
  555. * (within the support only)
  556. */
  557. permsupport = DDDMP_ALLOC (int, Hdr->nsuppvars);
  558. Dddmp_CheckAndGotoLabel (permsupport==NULL, "Error allocating memory.",
  559. failure);
  560. for (i=0,k=0; i < Hdr->nVars; i++) {
  561. for (j=0; j < Hdr->nsuppvars; j++) {
  562. if (Hdr->permids[j] == i) {
  563. permsupport[j] = k++;
  564. }
  565. }
  566. }
  567. Dddmp_Assert (k==Hdr->nsuppvars, "k==Hdr->nsuppvars");
  568. if (Hdr->suppVarNames != NULL) {
  569. /*
  570. * Varnames are sorted for binary search
  571. */
  572. sortedvarnames = DDDMP_ALLOC(char *, Hdr->nsuppvars);
  573. Dddmp_CheckAndGotoLabel (sortedvarnames==NULL, "Error allocating memory.",
  574. failure);
  575. for (i=0; i<Hdr->nsuppvars; i++) {
  576. Dddmp_CheckAndGotoLabel (Hdr->suppVarNames[i]==NULL,
  577. "Support Variable Name Missing in File.", failure);
  578. sortedvarnames[i] = Hdr->suppVarNames[i];
  579. }
  580. qsort ((void *) sortedvarnames, Hdr->nsuppvars,
  581. sizeof(char *), QsortStrcmp);
  582. }
  583. /*
  584. * Convertids is the array used to convert variable ids from positional
  585. * (shrinked) ids used within the DD file.
  586. * Positions in the file are from 0 to nsuppvars-1.
  587. */
  588. convertids = DDDMP_ALLOC (int, Hdr->nsuppvars);
  589. Dddmp_CheckAndGotoLabel (convertids==NULL, "Error allocating memory.",
  590. failure);
  591. again_matchmode:
  592. switch (varMatchMode) {
  593. case DDDMP_VAR_MATCHIDS:
  594. for (i=0; i<Hdr->nsuppvars; i++) {
  595. convertids[permsupport[i]] = Hdr->ids[i];
  596. }
  597. break;
  598. case DDDMP_VAR_MATCHPERMIDS:
  599. for (i=0; i<Hdr->nsuppvars; i++) {
  600. convertids[permsupport[i]] = Cudd_ReadInvPerm (ddMgr,
  601. Hdr->permids[i]);
  602. }
  603. break;
  604. case DDDMP_VAR_MATCHAUXIDS:
  605. if (Hdr->auxids == NULL) {
  606. (void) fprintf (stderr,
  607. "DdLoad Error: variable auxids matching requested\n");
  608. (void) fprintf (stderr, "but .auxids not found in BDD file\n");
  609. (void) fprintf (stderr, "Matching IDs forced.\n");
  610. fflush (stderr);
  611. varMatchMode = DDDMP_VAR_MATCHIDS;
  612. goto again_matchmode;
  613. }
  614. /* find max auxid value to alloc invaux array */
  615. for (i=0,maxaux= -1; i<nddvars; i++) {
  616. if (varmatchauxids[i]>maxaux) {
  617. maxaux = varmatchauxids[i];
  618. }
  619. }
  620. /* generate invaux array */
  621. invauxids = DDDMP_ALLOC (int, maxaux+1);
  622. Dddmp_CheckAndGotoLabel (invauxids==NULL, "Error allocating memory.",
  623. failure);
  624. for (i=0; i<=maxaux; i++) {
  625. invauxids[i] = -1;
  626. }
  627. for (i=0; i<Hdr->nsuppvars; i++) {
  628. invauxids[varmatchauxids[Hdr->ids[i]]] = Hdr->ids[i];
  629. }
  630. /* generate convertids array */
  631. for (i=0; i<Hdr->nsuppvars; i++) {
  632. if ((Hdr->auxids[i]>maxaux) || (invauxids[Hdr->auxids[i]]<0)) {
  633. (void) fprintf (stderr,
  634. "DdLoad Error: auxid %d not found in DD manager.\n",
  635. Hdr->auxids[i]);
  636. (void) fprintf (stderr, "ID matching forced (%d).\n", i);
  637. (void) fprintf (stderr,
  638. "Beware of possible overlappings with other variables\n");
  639. fflush (stderr);
  640. convertids[permsupport[i]] = i;
  641. } else {
  642. convertids[permsupport[i]] = invauxids[Hdr->auxids[i]];
  643. }
  644. }
  645. break;
  646. case DDDMP_VAR_MATCHNAMES:
  647. if (Hdr->suppVarNames == NULL) {
  648. (void) fprintf (stderr,
  649. "DdLoad Error: variable names matching requested\n");
  650. (void) fprintf (stderr, "but .suppvarnames not found in BDD file\n");
  651. (void) fprintf (stderr, "Matching IDs forced.\n");
  652. fflush (stderr);
  653. varMatchMode = DDDMP_VAR_MATCHIDS;
  654. goto again_matchmode;
  655. }
  656. /* generate invaux array */
  657. invauxids = DDDMP_ALLOC (int, Hdr->nsuppvars);
  658. Dddmp_CheckAndGotoLabel (invauxids==NULL, "Error allocating memory.",
  659. failure);
  660. for (i=0; i<Hdr->nsuppvars; i++) {
  661. invauxids[i] = -1;
  662. }
  663. for (i=0; i<nddvars; i++) {
  664. if (varmatchnames[i]==NULL) {
  665. (void) fprintf (stderr,
  666. "DdLoad Warning: NULL match variable name (id: %d). Ignored.\n",
  667. i);
  668. fflush (stderr);
  669. }
  670. else
  671. if ((j=FindVarname(varmatchnames[i],sortedvarnames,Hdr->nsuppvars))
  672. >=0) {
  673. Dddmp_Assert (j<Hdr->nsuppvars, "j<Hdr->nsuppvars");
  674. invauxids[j] = i;
  675. }
  676. }
  677. /* generate convertids array */
  678. for (i=0; i<Hdr->nsuppvars; i++) {
  679. Dddmp_Assert (Hdr->suppVarNames[i]!=NULL,
  680. "Hdr->suppVarNames[i] != NULL");
  681. j=FindVarname(Hdr->suppVarNames[i],sortedvarnames,Hdr->nsuppvars);
  682. Dddmp_Assert ((j>=0) && (j<Hdr->nsuppvars),
  683. "(j>=0) && (j<Hdr->nsuppvars)");
  684. if (invauxids[j]<0) {
  685. fprintf (stderr,
  686. "DdLoad Error: varname %s not found in DD manager.",
  687. Hdr->suppVarNames[i]);
  688. fprintf (stderr, "ID matching forced (%d)\n", i);
  689. fflush (stderr);
  690. convertids[permsupport[i]]=i;
  691. } else {
  692. convertids[permsupport[i]] = invauxids[j];
  693. }
  694. }
  695. break;
  696. case DDDMP_VAR_COMPOSEIDS:
  697. for (i=0; i<Hdr->nsuppvars; i++) {
  698. convertids[permsupport[i]] = varcomposeids[Hdr->ids[i]];
  699. }
  700. break;
  701. }
  702. maxv = (-1);
  703. for (i=0; i<Hdr->nsuppvars; i++) {
  704. if (convertids[i] > maxv) {
  705. maxv = convertids[i];
  706. }
  707. }
  708. invconvertids = DDDMP_ALLOC (int, maxv+1);
  709. Dddmp_CheckAndGotoLabel (invconvertids==NULL, "Error allocating memory.",
  710. failure);
  711. for (i=0; i<=maxv; i++) {
  712. invconvertids[i]= -1;
  713. }
  714. for (i=0; i<Hdr->nsuppvars; i++) {
  715. invconvertids[convertids[i]] = i;
  716. }
  717. pnodes = DDDMP_ALLOC(DdNode *,(Hdr->nnodes+1));
  718. Dddmp_CheckAndGotoLabel (pnodes==NULL, "Error allocating memory.",
  719. failure);
  720. if (Hdr->nsuppvars < 256) {
  721. pvars1byte = DDDMP_ALLOC(unsigned char,(Hdr->nnodes+1));
  722. Dddmp_CheckAndGotoLabel (pvars1byte==NULL, "Error allocating memory.",
  723. failure);
  724. }
  725. else if (Hdr->nsuppvars < 0xffff) {
  726. pvars2byte = DDDMP_ALLOC(unsigned short,(Hdr->nnodes+1));
  727. Dddmp_CheckAndGotoLabel (pvars2byte==NULL, "Error allocating memory.",
  728. failure);
  729. } else {
  730. (void) fprintf (stderr,
  731. "DdLoad Error: more than %d variables. Not supported.\n", 0xffff);
  732. fflush (stderr);
  733. goto failure;
  734. }
  735. /*-------------- Deal With Nodes ... One Row File at a Time --------------*/
  736. for (i=1; i<=Hdr->nnodes; i++) {
  737. Dddmp_CheckAndGotoLabel (feof(fp),
  738. "Unexpected EOF While Reading DD Nodes.", failure);
  739. switch (mode) {
  740. /*
  741. * Text FORMAT
  742. */
  743. case DDDMP_MODE_TEXT:
  744. switch (Hdr->varinfo) {
  745. case DDDMP_VARIDS:
  746. case DDDMP_VARPERMIDS:
  747. case DDDMP_VARAUXIDS:
  748. case DDDMP_VARNAMES:
  749. retValue = fscanf(fp, "%d %*s %s %d %d\n", &id, buf, &idT, &idE);
  750. Dddmp_CheckAndGotoLabel (retValue<4,
  751. "Error Reading Nodes in Text Mode.", failure);
  752. break;
  753. case DDDMP_VARDEFAULT:
  754. retValue = fscanf(fp, "%d %s %d %d\n", &id, buf, &idT, &idE);
  755. Dddmp_CheckAndGotoLabel (retValue<4,
  756. "Error Reading Nodes in Text Mode.", failure);
  757. break;
  758. }
  759. #ifdef DDDMP_DEBUG
  760. Dddmp_Assert (id==i, "id == i");
  761. #endif
  762. if (idT==0 && idE==0) {
  763. /* leaf node: a constant */
  764. if (strcmp(buf, "1") == 0) {
  765. pnodes[i] = Cudd_ReadOne (ddMgr);
  766. } else {
  767. /* this is an ADD constant ! */
  768. if (strcmp(buf, "0") == 0) {
  769. pnodes[i] = Cudd_ReadZero (ddMgr);
  770. } else {
  771. addConstant = atof(buf);
  772. pnodes[i] = Cudd_addConst (ddMgr,
  773. (CUDD_VALUE_TYPE) addConstant);
  774. }
  775. }
  776. /* StQ 11.02.2004:
  777. Bug fixed --> Reference All Nodes for ADD */
  778. Cudd_Ref (pnodes[i]);
  779. Dddmp_CheckAndGotoLabel (pnodes[i]==NULL, "NULL pnodes.",
  780. failure);
  781. continue;
  782. } else {
  783. #ifdef DDDMP_DEBUG
  784. Dddmp_Assert (idT>0, "id > 0");
  785. #endif
  786. var = atoi(buf);
  787. T = pnodes[idT];
  788. if(idE<0) {
  789. idE = -idE;
  790. E = pnodes[idE];
  791. E = Cudd_Not(E);
  792. } else {
  793. E = pnodes[idE];
  794. }
  795. }
  796. break;
  797. /*
  798. * Binary FORMAT
  799. */
  800. case DDDMP_MODE_BINARY:
  801. Dddmp_CheckAndGotoLabel (DddmpReadCode(fp,&code) == 0,
  802. "Error Reading witn ReadCode.", failure);
  803. switch (code.V) {
  804. case DDDMP_TERMINAL:
  805. /* only 1 terminal presently supported */
  806. pnodes[i] = Cudd_ReadOne (ddMgr);
  807. continue;
  808. break;
  809. case DDDMP_RELATIVE_1:
  810. break;
  811. case DDDMP_RELATIVE_ID:
  812. case DDDMP_ABSOLUTE_ID:
  813. size = DddmpReadInt (fp, &var);
  814. Dddmp_CheckAndGotoLabel (size==0, "Error reading size.",
  815. failure);
  816. break;
  817. }
  818. switch (code.T) {
  819. case DDDMP_TERMINAL:
  820. idT = 1;
  821. break;
  822. case DDDMP_RELATIVE_1:
  823. idT = i-1;
  824. break;
  825. case DDDMP_RELATIVE_ID:
  826. size = DddmpReadInt (fp, &id);
  827. Dddmp_CheckAndGotoLabel (size==0, "Error reading size.",
  828. failure);
  829. idT = i-id;
  830. break;
  831. case DDDMP_ABSOLUTE_ID:
  832. size = DddmpReadInt (fp, &idT);
  833. Dddmp_CheckAndGotoLabel (size==0, "Error reading size.",
  834. failure);
  835. break;
  836. }
  837. switch (code.E) {
  838. case DDDMP_TERMINAL:
  839. idE = 1;
  840. break;
  841. case DDDMP_RELATIVE_1:
  842. idE = i-1;
  843. break;
  844. case DDDMP_RELATIVE_ID:
  845. size = DddmpReadInt (fp, &id);
  846. Dddmp_CheckAndGotoLabel (size==0, "Error reading size.",
  847. failure);
  848. idE = i-id;
  849. break;
  850. case DDDMP_ABSOLUTE_ID:
  851. size = DddmpReadInt (fp, &idE);
  852. Dddmp_CheckAndGotoLabel (size==0, "Error reading size.",
  853. failure);
  854. break;
  855. }
  856. #ifdef DDDMP_DEBUG
  857. Dddmp_Assert (idT<i, "id<i");
  858. #endif
  859. T = pnodes[idT];
  860. if (cuddIsConstant(T))
  861. vT = Hdr->nsuppvars;
  862. else {
  863. if (pvars1byte != NULL)
  864. vT = pvars1byte[idT];
  865. else if (pvars2byte != NULL)
  866. vT = pvars2byte[idT];
  867. else
  868. vT = invconvertids[T->index];
  869. }
  870. #ifdef DDDMP_DEBUG
  871. Dddmp_Assert (vT>0, "vT > 0");
  872. Dddmp_Assert (vT<=Hdr->nsuppvars, "vT <= Hdr->nsuppvars");
  873. #endif
  874. #ifdef DDDMP_DEBUG
  875. Dddmp_Assert (idE<i, "idE < i");
  876. #endif
  877. E = pnodes[idE];
  878. if (cuddIsConstant(E))
  879. vE = Hdr->nsuppvars;
  880. else {
  881. if (pvars1byte != NULL)
  882. vE = pvars1byte[idE];
  883. else if (pvars2byte != NULL)
  884. vE = pvars2byte[idE];
  885. else
  886. vE = invconvertids[E->index];
  887. }
  888. #ifdef DDDMP_DEBUG
  889. Dddmp_Assert (vE>0, "vE > 0");
  890. Dddmp_Assert (vE<=Hdr->nsuppvars, "vE <= Hdr->nsuppvars");
  891. #endif
  892. switch (code.V) {
  893. case DDDMP_TERMINAL:
  894. case DDDMP_ABSOLUTE_ID:
  895. break;
  896. case DDDMP_RELATIVE_1:
  897. var = (vT<vE) ? vT-1 : vE-1;
  898. break;
  899. case DDDMP_RELATIVE_ID:
  900. var = (vT<vE) ? vT-var : vE-var;
  901. break;
  902. }
  903. if (code.Ecompl) {
  904. E = Cudd_Not(E);
  905. }
  906. #ifdef DDDMP_DEBUG
  907. Dddmp_Assert (var<Hdr->nsuppvars, "var < Hdr->nsuppvars");
  908. #endif
  909. break;
  910. }
  911. if (pvars1byte != NULL) {
  912. pvars1byte[i] = (unsigned char) var;
  913. } else {
  914. if (pvars2byte != NULL) {
  915. pvars2byte[i] = (unsigned short) var;
  916. }
  917. }
  918. var = convertids[var];
  919. switch (ddType) {
  920. case DDDMP_BDD:
  921. pnodes[i] = Cudd_bddIte (ddMgr, Cudd_bddIthVar (ddMgr, var),
  922. T, E);
  923. break;
  924. case DDDMP_ADD:
  925. {
  926. DdNode *tmp = Cudd_addIthVar (ddMgr, var);
  927. Cudd_Ref (tmp);
  928. pnodes[i] = Cudd_addIte (ddMgr, tmp, T, E);
  929. Cudd_RecursiveDeref (ddMgr, tmp);
  930. break;
  931. }
  932. case DDDMP_CNF:
  933. case DDDMP_NONE:
  934. Dddmp_Warning (1, "Wrong DD Type.");
  935. break;
  936. }
  937. cuddRef (pnodes[i]);
  938. }
  939. /*------------------------ Deal With the File Tail -----------------------*/
  940. retval = fgets (buf, DDDMP_MAXSTRLEN-1,fp);
  941. Dddmp_CheckAndGotoLabel (!retval, "Error on reading file tail.", failure);
  942. Dddmp_CheckAndGotoLabel (!matchkeywd(buf, ".end"),
  943. "Error .end not found.", failure);
  944. /* Close File IFF Necessary */
  945. if (fileToClose) {
  946. fclose (fp);
  947. }
  948. /* BDD Roots */
  949. proots = DDDMP_ALLOC(DdNode *,nRoots);
  950. Dddmp_CheckAndGotoLabel (proots==NULL, "Error allocating memory.",
  951. failure);
  952. for(i=0; i<nRoots; ++i) {
  953. switch (rootMatchMode) {
  954. case DDDMP_ROOT_MATCHNAMES:
  955. for (j=0; j<nRoots; j++) {
  956. if (strcmp(rootmatchnames[i], Hdr->rootnames[j]) == 0)
  957. break;
  958. }
  959. if (j>=nRoots) {
  960. /* rootname not found */
  961. fprintf (stderr, "Warning: unable to match root name <%s>\n",
  962. rootmatchnames[i]);
  963. }
  964. break;
  965. case DDDMP_ROOT_MATCHLIST:
  966. j = i;
  967. break;
  968. }
  969. id = Hdr->rootids[i];
  970. if (id==0) {
  971. (void) fprintf (stderr, "DdLoad Warning: NULL root found in file\n");
  972. fflush (stderr);
  973. f = NULL;
  974. } else {
  975. if (id<0) {
  976. f = Cudd_Not(pnodes[-id]);
  977. } else {
  978. f = pnodes[id];
  979. }
  980. }
  981. proots[i] = f;
  982. cuddRef (f);
  983. } /* end for i = 0..nRoots */
  984. /*
  985. * Decrease Reference for all Nodes
  986. */
  987. /* StQ 11.02.2004:
  988. Bug fixed --> De-Reference All Nodes for ADD */
  989. for (i=1; i<=Hdr->nnodes; i++) {
  990. f = pnodes[i];
  991. Cudd_RecursiveDeref (ddMgr, f);
  992. }
  993. /*
  994. * Free Memory: load_end label
  995. */
  996. load_end:
  997. DddmpFreeHeader(Hdr);
  998. DDDMP_FREE (pnodes);
  999. DDDMP_FREE (pvars1byte);
  1000. DDDMP_FREE (pvars2byte);
  1001. /* variable names are not freed because they were shared with varnames */
  1002. DDDMP_FREE (sortedvarnames);
  1003. DDDMP_FREE (permsupport);
  1004. DDDMP_FREE (convertids);
  1005. DDDMP_FREE (invconvertids);
  1006. DDDMP_FREE (invauxids);
  1007. *pproots = proots;
  1008. return (nRoots);
  1009. /*
  1010. * Failure Condition
  1011. */
  1012. failure:
  1013. if (fileToClose) {
  1014. fclose (fp);
  1015. }
  1016. nRoots = 0; /* return 0 on error ! */
  1017. DDDMP_FREE (proots);
  1018. goto load_end; /* this is done to free memory */
  1019. }
  1020. /**Function********************************************************************
  1021. Synopsis [Reads a the header of a dump file representing the
  1022. argument BDDs.
  1023. ]
  1024. Description [Reads the header of a dump file. Builds a Dddmp_Hdr_t struct
  1025. containing all infos in the header, for next manipulations.
  1026. ]
  1027. SideEffects [none]
  1028. SeeAlso []
  1029. ******************************************************************************/
  1030. static Dddmp_Hdr_t *
  1031. DddmpBddReadHeader (
  1032. char *file /* IN: file name */,
  1033. FILE *fp /* IN: file pointer */
  1034. )
  1035. {
  1036. Dddmp_Hdr_t *Hdr = NULL;
  1037. char buf[DDDMP_MAXSTRLEN];
  1038. int retValue, fileToClose = 0;
  1039. char *retval;
  1040. if (fp == NULL) {
  1041. fp = fopen (file, "r");
  1042. Dddmp_CheckAndGotoLabel (fp==NULL, "Error opening file.",
  1043. failure);
  1044. fileToClose = 1;
  1045. }
  1046. /* START HEADER */
  1047. Hdr = DDDMP_ALLOC (Dddmp_Hdr_t,1);
  1048. if (Hdr == NULL) {
  1049. return NULL;
  1050. }
  1051. Hdr->ver = NULL;
  1052. Hdr->mode = 0;
  1053. Hdr->ddType = DDDMP_BDD;
  1054. Hdr->varinfo = DDDMP_VARIDS;
  1055. Hdr->dd = NULL;
  1056. Hdr->nnodes = 0;
  1057. Hdr->nVars = 0;
  1058. Hdr->nsuppvars = 0;
  1059. Hdr->suppVarNames = NULL;
  1060. Hdr->orderedVarNames = NULL;
  1061. Hdr->ids = NULL;
  1062. Hdr->permids = NULL;
  1063. Hdr->auxids = NULL;
  1064. Hdr->cnfids = NULL;
  1065. Hdr->nRoots = 0;
  1066. Hdr->rootids = NULL;
  1067. Hdr->rootnames = NULL;
  1068. Hdr->nAddedCnfVar = 0;
  1069. Hdr->nVarsCnf = 0;
  1070. Hdr->nClausesCnf = 0;
  1071. while (fscanf(fp, "%s", buf)!=EOF) {
  1072. /* comment */
  1073. if (buf[0] == '#') {
  1074. retval = fgets(buf,DDDMP_MAXSTRLEN,fp);
  1075. Dddmp_CheckAndGotoLabel (!retval, "Error on reading comment.", failure);
  1076. continue;
  1077. }
  1078. Dddmp_CheckAndGotoLabel (buf[0] != '.',
  1079. "Error; line must begin with '.' or '#'.",
  1080. failure);
  1081. if (matchkeywd(buf, ".ver")) {
  1082. /* this not checked so far: only read */
  1083. retValue = fscanf (fp, "%s", buf);
  1084. Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading from file.",
  1085. failure);
  1086. Hdr->ver=DddmpStrDup(buf);
  1087. Dddmp_CheckAndGotoLabel (Hdr->ver==NULL,
  1088. "Error allocating memory.", failure);
  1089. continue;
  1090. }
  1091. if (matchkeywd(buf, ".add")) {
  1092. Hdr->ddType = DDDMP_ADD;
  1093. continue;
  1094. }
  1095. if (matchkeywd(buf, ".bdd")) {
  1096. Hdr->ddType = DDDMP_BDD;
  1097. continue;
  1098. }
  1099. if (matchkeywd(buf, ".mode")) {
  1100. retValue = fscanf (fp, "%s", buf);
  1101. Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading to file.",
  1102. failure);
  1103. Hdr->mode = buf[0];
  1104. continue;
  1105. }
  1106. if (matchkeywd(buf, ".varinfo")) {
  1107. int readMe;
  1108. retValue = fscanf (fp, "%d", &readMe);
  1109. Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.",
  1110. failure);
  1111. Hdr->varinfo = (Dddmp_VarInfoType) readMe;
  1112. continue;
  1113. }
  1114. if (matchkeywd(buf, ".dd")) {
  1115. retValue = fscanf (fp, "%s", buf);
  1116. Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.",
  1117. failure);
  1118. Hdr->dd = DddmpStrDup (buf);
  1119. Dddmp_CheckAndGotoLabel (Hdr->dd==NULL, "Error allocating memory.",
  1120. failure);
  1121. continue;
  1122. }
  1123. if (matchkeywd(buf, ".nnodes")) {
  1124. retValue = fscanf (fp, "%d", &(Hdr->nnodes));
  1125. Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.",
  1126. failure);
  1127. continue;
  1128. }
  1129. if (matchkeywd(buf, ".nvars")) {
  1130. retValue = fscanf (fp, "%d", &(Hdr->nVars));
  1131. Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.",
  1132. failure);
  1133. continue;
  1134. }
  1135. if (matchkeywd(buf, ".nsuppvars")) {
  1136. retValue = fscanf (fp, "%d", &(Hdr->nsuppvars));
  1137. Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.",
  1138. failure);
  1139. continue;
  1140. }
  1141. if (matchkeywd(buf, ".orderedvarnames")) {
  1142. Hdr->orderedVarNames = DddmpStrArrayRead (fp, Hdr->nVars);
  1143. Dddmp_CheckAndGotoLabel (Hdr->orderedVarNames==NULL,
  1144. "Error allocating memory.", failure);
  1145. continue;
  1146. }
  1147. if (matchkeywd(buf, ".suppvarnames") ||
  1148. (Hdr->ver != NULL && (strcmp (Hdr->ver, "DDDMP-1.0") == 0) &&
  1149. matchkeywd (buf, ".varnames"))) {
  1150. Hdr->suppVarNames = DddmpStrArrayRead (fp, Hdr->nsuppvars);
  1151. Dddmp_CheckAndGotoLabel (Hdr->suppVarNames==NULL,
  1152. "Error allocating memory.", failure);
  1153. continue;
  1154. }
  1155. if matchkeywd(buf, ".ids") {
  1156. Hdr->ids = DddmpIntArrayRead(fp,Hdr->nsuppvars);
  1157. Dddmp_CheckAndGotoLabel (Hdr->ids==NULL,
  1158. "Error allocating memory.", failure);
  1159. continue;
  1160. }
  1161. if (matchkeywd(buf, ".permids")) {
  1162. Hdr->permids = DddmpIntArrayRead(fp,Hdr->nsuppvars);
  1163. Dddmp_CheckAndGotoLabel (Hdr->permids==NULL,
  1164. "Error allocating memory.", failure);
  1165. continue;
  1166. }
  1167. if (matchkeywd(buf, ".auxids")) {
  1168. Hdr->auxids = DddmpIntArrayRead(fp,Hdr->nsuppvars);
  1169. Dddmp_CheckAndGotoLabel (Hdr->auxids==NULL,
  1170. "Error allocating memory.", failure);
  1171. continue;
  1172. }
  1173. if (matchkeywd(buf, ".nroots")) {
  1174. retValue = fscanf (fp, "%d", &(Hdr->nRoots));
  1175. Dddmp_CheckAndGotoLabel (retValue==EOF, "Error reading file.",
  1176. failure);
  1177. continue;
  1178. }
  1179. if (matchkeywd(buf, ".rootids")) {
  1180. Hdr->rootids = DddmpIntArrayRead(fp,Hdr->nRoots);
  1181. Dddmp_CheckAndGotoLabel (Hdr->rootids==NULL,
  1182. "Error allocating memory.", failure);
  1183. continue;
  1184. }
  1185. if (matchkeywd(buf, ".rootnames")) {
  1186. Hdr->rootnames = DddmpStrArrayRead(fp,Hdr->nRoots);
  1187. Dddmp_CheckAndGotoLabel (Hdr->rootnames==NULL,
  1188. "Error allocating memory.", failure);
  1189. continue;
  1190. }
  1191. if (matchkeywd(buf, ".nodes")) {
  1192. retval = fgets(buf,DDDMP_MAXSTRLEN,fp);
  1193. Dddmp_CheckAndGotoLabel (!retval, "Error on reading nodes.", failure);
  1194. break;
  1195. }
  1196. }
  1197. /* END HEADER */
  1198. return (Hdr);
  1199. failure:
  1200. if (fileToClose == 1) {
  1201. fclose (fp);
  1202. }
  1203. DddmpFreeHeader(Hdr);
  1204. return (NULL);
  1205. }
  1206. /**Function********************************************************************
  1207. Synopsis [Frees the internal header structure.]
  1208. Description [Frees the internal header structureby freeing all internal
  1209. fields first.
  1210. ]
  1211. SideEffects []
  1212. SeeAlso []
  1213. ******************************************************************************/
  1214. static void
  1215. DddmpFreeHeader (
  1216. Dddmp_Hdr_t *Hdr /* IN: pointer to header */
  1217. )
  1218. {
  1219. DDDMP_FREE (Hdr->ver);
  1220. DDDMP_FREE (Hdr->dd);
  1221. DddmpStrArrayFree (Hdr->orderedVarNames, Hdr->nVars);
  1222. DddmpStrArrayFree (Hdr->suppVarNames, Hdr->nsuppvars);
  1223. DDDMP_FREE (Hdr->ids);
  1224. DDDMP_FREE (Hdr->permids);
  1225. DDDMP_FREE (Hdr->auxids);
  1226. DDDMP_FREE (Hdr->rootids);
  1227. DddmpStrArrayFree (Hdr->rootnames, Hdr->nRoots);
  1228. DDDMP_FREE (Hdr);
  1229. return;
  1230. }