Compare commits

..

166 Commits

Author SHA1 Message Date
Tim Edwards 93b9cf6577 Merge branch 'master' into netgen-1.5 2024-01-04 02:00:02 -05:00
Tim Edwards bf53d52970 Merge branch 'master' into netgen-1.5 2023-12-04 02:00:02 -05:00
Tim Edwards 4250525e19 Merge branch 'master' into netgen-1.5 2023-11-21 02:00:01 -05:00
Tim Edwards c1ed4ce49e Merge branch 'master' into netgen-1.5 2023-10-28 02:00:04 -04:00
Tim Edwards ab327c5f82 Merge branch 'master' into netgen-1.5 2023-10-27 02:00:02 -04:00
Tim Edwards 2cb3937ee3 Merge branch 'master' into netgen-1.5 2023-10-23 02:00:02 -04:00
Tim Edwards 9b0afa893d Merge branch 'master' into netgen-1.5 2023-10-04 02:00:01 -04:00
Tim Edwards c0f7ebd625 Merge branch 'master' into netgen-1.5 2023-09-05 02:00:01 -04:00
Tim Edwards 9e9288f746 Merge branch 'master' into netgen-1.5 2023-09-02 02:00:02 -04:00
Tim Edwards bcbc736b51 Merge branch 'master' into netgen-1.5 2023-08-28 02:00:03 -04:00
Tim Edwards f5f1240073 Merge branch 'master' into netgen-1.5 2023-07-12 02:00:03 -04:00
Tim Edwards 02d7a1bd01 Merge branch 'master' into netgen-1.5 2023-06-13 02:00:02 -04:00
Tim Edwards 7878b3cfbc Merge branch 'master' into netgen-1.5 2023-04-15 02:00:01 -04:00
Tim Edwards 7f727e6674 Merge branch 'master' into netgen-1.5 2023-04-14 02:00:01 -04:00
Tim Edwards d111fa0a3b Merge branch 'master' into netgen-1.5 2023-03-30 02:00:02 -04:00
Tim Edwards 178b172c06 Merge branch 'master' into netgen-1.5 2023-03-08 02:00:03 -05:00
Tim Edwards 7870538ec9 Merge branch 'master' into netgen-1.5 2023-03-07 02:00:02 -05:00
Tim Edwards ee4e1e087f Merge branch 'master' into netgen-1.5 2023-03-05 02:00:01 -05:00
Tim Edwards 7a8b5e835b Merge branch 'master' into netgen-1.5 2023-03-01 02:00:03 -05:00
Tim Edwards 77f7a773e3 Merge branch 'master' into netgen-1.5 2023-02-28 02:00:03 -05:00
Tim Edwards 9a48a59f68 Merge branch 'master' into netgen-1.5 2023-02-25 02:00:03 -05:00
Tim Edwards 535b8285e9 Merge branch 'master' into netgen-1.5 2022-12-20 02:00:03 -05:00
Tim Edwards 1e1d506697 Merge branch 'master' into netgen-1.5 2022-12-16 02:00:03 -05:00
Tim Edwards 4edaf0813d Merge branch 'master' into netgen-1.5 2022-11-17 02:00:01 -05:00
Tim Edwards a4ae5ed989 Merge branch 'master' into netgen-1.5 2022-11-05 02:00:01 -04:00
Tim Edwards d850586a14 Merge branch 'master' into netgen-1.5 2022-11-03 02:00:03 -04:00
Tim Edwards 4b5b117100 Merge branch 'master' into netgen-1.5 2022-11-02 02:00:02 -04:00
Tim Edwards 935e54abe6 Merge branch 'master' into netgen-1.5 2022-11-01 02:00:02 -04:00
Tim Edwards 49ccf1949a Merge branch 'master' into netgen-1.5 2022-10-30 02:00:03 -04:00
Tim Edwards 9b84776374 Merge branch 'master' into netgen-1.5 2022-10-26 02:00:01 -04:00
Tim Edwards 2af3f2a3f7 Merge branch 'master' into netgen-1.5 2022-10-25 02:00:01 -04:00
Tim Edwards 738abbdad9 Merge branch 'master' into netgen-1.5 2022-10-01 02:00:01 -04:00
Tim Edwards 8d7569e9a3 Merge branch 'master' into netgen-1.5 2022-09-24 02:00:02 -04:00
Tim Edwards d9425163e1 Merge branch 'master' into netgen-1.5 2022-09-18 02:00:02 -04:00
Tim Edwards 9ba1dfe814 Merge branch 'master' into netgen-1.5 2022-09-17 02:00:02 -04:00
Tim Edwards fadd0ae2fc Merge branch 'master' into netgen-1.5 2022-09-16 02:00:02 -04:00
Tim Edwards 153ce0e2b3 Merge branch 'master' into netgen-1.5 2022-09-14 02:00:02 -04:00
Tim Edwards bfdacab28c Merge branch 'master' into netgen-1.5 2022-09-13 02:00:02 -04:00
Tim Edwards 7e9bd9f2a0 Merge branch 'master' into netgen-1.5 2022-06-28 02:00:02 -04:00
Tim Edwards ee92d880d7 Merge branch 'master' into netgen-1.5 2022-06-27 02:00:01 -04:00
Tim Edwards d3407b3e56 Merge branch 'master' into netgen-1.5 2022-06-15 02:00:50 -04:00
Tim Edwards 0a94bec191 Merge branch 'master' into netgen-1.5 2022-06-13 02:00:18 -04:00
Tim Edwards 4a7b6bf22a Merge branch 'master' into netgen-1.5 2022-06-09 02:00:52 -04:00
Tim Edwards 661c9ee854 Merge branch 'master' into netgen-1.5 2022-04-16 02:00:16 -04:00
Tim Edwards 5b21c1be3a Merge branch 'master' into netgen-1.5 2022-04-15 02:00:16 -04:00
Tim Edwards e11dbac384 Merge branch 'master' into netgen-1.5 2022-01-17 03:00:14 -05:00
Tim Edwards 0535128421 Merge branch 'master' into netgen-1.5 2022-01-16 03:00:18 -05:00
Tim Edwards afe0e9f758 Merge branch 'master' into netgen-1.5 2022-01-01 03:00:43 -05:00
Tim Edwards e487890641 Merge branch 'master' into netgen-1.5 2021-12-31 03:00:42 -05:00
Tim Edwards bb44d3f827 Merge branch 'master' into netgen-1.5 2021-12-30 03:00:43 -05:00
Tim Edwards c25c4e1160 Merge branch 'master' into netgen-1.5 2021-12-27 03:00:18 -05:00
Tim Edwards 8ed4e3cf38 Merge branch 'master' into netgen-1.5 2021-12-20 03:00:02 -05:00
Tim Edwards 69838d79e4 Merge branch 'master' into netgen-1.5 2021-12-16 03:00:06 -05:00
Tim Edwards fc7c9371e8 Merge branch 'master' into netgen-1.5 2021-12-08 03:00:14 -05:00
Tim Edwards 0d19868145 Merge branch 'master' into netgen-1.5 2021-11-18 03:00:10 -05:00
Tim Edwards 6b4eb01ee8 Merge branch 'master' into netgen-1.5 2021-11-12 03:00:29 -05:00
Tim Edwards 737b2a73bf Merge branch 'master' into netgen-1.5 2021-10-30 03:00:02 -04:00
Tim Edwards 6b8c6d1718 Merge branch 'master' into netgen-1.5 2021-10-29 03:00:32 -04:00
Tim Edwards 610eebb758 Merge branch 'master' into netgen-1.5 2021-10-24 03:00:12 -04:00
Tim Edwards 97058c5017 Merge branch 'master' into netgen-1.5 2021-10-16 03:00:13 -04:00
Tim Edwards aa120460d0 Merge branch 'master' into netgen-1.5 2021-10-15 03:00:03 -04:00
Tim Edwards ea5cbacf1c Merge branch 'master' into netgen-1.5 2021-10-06 03:00:12 -04:00
Tim Edwards cdd768addc Merge branch 'master' into netgen-1.5 2021-09-08 03:00:04 -04:00
Tim Edwards 66cf2b82d9 Merge branch 'master' into netgen-1.5 2021-08-30 03:00:02 -04:00
Tim Edwards bc4192496b Merge branch 'master' into netgen-1.5 2021-08-28 13:15:58 -04:00
Tim Edwards 168e5502a1 Merge branch 'master' into netgen-1.5 2021-08-06 11:38:38 -04:00
Tim Edwards 8d4b621b7d Merge branch 'master' into netgen-1.5 2021-08-06 11:25:01 -04:00
Tim Edwards ba3e862552 Merge branch 'master' into netgen-1.5 2021-07-30 03:00:29 -04:00
Tim Edwards cf6dd2a638 Merge branch 'master' into netgen-1.5 2021-07-16 03:00:11 -04:00
Tim Edwards b6d896e73f Merge branch 'master' into netgen-1.5 2021-07-12 03:00:10 -04:00
Tim Edwards 9251ce2a48 Merge branch 'master' into netgen-1.5 2021-07-11 03:00:33 -04:00
Tim Edwards aa82164c08 Merge branch 'master' into netgen-1.5 2021-07-09 03:00:34 -04:00
Tim Edwards fb7876c7a6 Merge branch 'master' into netgen-1.5 2021-07-03 03:00:13 -04:00
Tim Edwards e31caa3500 Merge branch 'master' into netgen-1.5 2021-06-26 03:00:10 -04:00
Tim Edwards c1355bee45 Merge branch 'master' into netgen-1.5 2021-06-25 03:00:10 -04:00
Tim Edwards 4fb8b59a2f Merge branch 'master' into netgen-1.5 2021-06-19 03:00:10 -04:00
Tim Edwards 626faf22f9 Merge branch 'master' into netgen-1.5 2021-06-17 03:00:10 -04:00
Tim Edwards 550234dce5 Merge branch 'master' into netgen-1.5 2021-06-15 03:00:36 -04:00
Tim Edwards a4c0028706 Merge branch 'master' into netgen-1.5 2021-06-13 03:00:32 -04:00
Tim Edwards e7ae84bbc8 Merge branch 'master' into netgen-1.5 2021-06-10 03:00:09 -04:00
Tim Edwards 43c018f3bc Merge branch 'master' into netgen-1.5 2021-06-09 03:00:10 -04:00
Tim Edwards ca119edc0a Merge branch 'master' into netgen-1.5 2021-06-04 03:00:10 -04:00
Tim Edwards 84348d2fe1 Merge branch 'master' into netgen-1.5 2021-05-31 03:00:10 -04:00
Tim Edwards 813b29cdc4 Merge branch 'master' into netgen-1.5 2021-05-29 03:00:10 -04:00
Tim Edwards ccf4a0a900 Merge branch 'master' into netgen-1.5 2021-05-27 03:00:32 -04:00
Tim Edwards e34166fdb9 Merge branch 'master' into netgen-1.5 2021-05-26 03:00:32 -04:00
Tim Edwards a13491e358 Merge branch 'master' into netgen-1.5 2021-05-25 03:00:09 -04:00
Tim Edwards 1d05b8b676 Merge branch 'master' into netgen-1.5 2021-05-20 03:00:31 -04:00
Tim Edwards e97d6f1aeb Merge branch 'master' into netgen-1.5 2021-05-14 03:00:10 -04:00
Tim Edwards fb4759a8cd Merge branch 'master' into netgen-1.5 2021-05-04 03:00:10 -04:00
Tim Edwards 45d4004d43 Merge branch 'master' into netgen-1.5 2021-05-02 03:00:09 -04:00
Tim Edwards 0b014e6efd Merge branch 'master' into netgen-1.5 2021-03-20 03:00:09 -04:00
Tim Edwards 9ca713dfd9 Merge branch 'master' into netgen-1.5 2021-03-18 03:00:29 -04:00
Tim Edwards 851a1f941e Merge branch 'master' into netgen-1.5 2021-03-06 03:00:09 -05:00
Tim Edwards fb798d6ce7 Merge branch 'master' into netgen-1.5 2021-03-03 03:00:12 -05:00
Tim Edwards a888502038 Merge branch 'master' into netgen-1.5 2021-03-02 03:00:35 -05:00
Tim Edwards c16258d4d1 Merge branch 'master' into netgen-1.5 2021-02-25 03:00:36 -05:00
Tim Edwards 5341d7a5fd Merge branch 'master' into netgen-1.5 2021-02-17 03:00:31 -05:00
Tim Edwards 8395df633c Merge branch 'master' into netgen-1.5 2021-02-10 03:00:16 -05:00
Tim Edwards 6554063df3 Merge branch 'master' into netgen-1.5 2021-01-22 03:00:40 -05:00
Tim Edwards 4416a380b3 Merge branch 'master' into netgen-1.5 2021-01-18 03:00:51 -05:00
Tim Edwards 46394b2000 Merge branch 'master' into netgen-1.5 2021-01-17 03:00:15 -05:00
Tim Edwards 3fe3bc4cfa Merge branch 'master' into netgen-1.5 2021-01-09 03:00:32 -05:00
Tim Edwards 6661910672 Merge branch 'master' into netgen-1.5 2020-12-21 03:00:30 -05:00
Tim Edwards e7a36630f6 Merge branch 'master' into netgen-1.5 2020-12-16 03:00:54 -05:00
Tim Edwards f32b0b34a3 Merge branch 'master' into netgen-1.5 2020-12-06 03:00:10 -05:00
Tim Edwards 6b731ddd7a Merge branch 'master' into netgen-1.5 2020-12-04 03:00:27 -05:00
Tim Edwards 99e35d8b11 Merge branch 'master' into netgen-1.5 2020-10-09 03:00:25 -04:00
Tim Edwards 65b542f0ab Merge branch 'master' into netgen-1.5 2020-10-08 03:00:22 -04:00
Tim Edwards b826870be9 Merge branch 'master' into netgen-1.5 2020-08-09 03:01:40 -04:00
Tim Edwards ed5276d67b Merge branch 'master' into netgen-1.5 2020-08-04 03:00:31 -04:00
Tim Edwards 69c9d85be7 Merge branch 'master' into netgen-1.5 2020-08-01 03:00:23 -04:00
Tim Edwards ad05d059c7 Merge branch 'master' into netgen-1.5 2020-07-31 03:00:27 -04:00
Tim Edwards 1b2cd1497c Merge branch 'master' into netgen-1.5 2020-07-30 03:00:28 -04:00
Tim Edwards d9d5a46c6e Merge branch 'master' into netgen-1.5 2020-07-25 03:00:09 -04:00
Tim Edwards d73b711e3a Merge branch 'master' into netgen-1.5 2020-07-02 03:00:09 -04:00
Tim Edwards 1428580109 Merge branch 'master' into netgen-1.5 2020-06-17 03:00:38 -04:00
Tim Edwards 210dfb25c3 Merge branch 'master' into netgen-1.5 2020-06-04 03:00:24 -04:00
Tim Edwards 27f2ab8b3f Merge branch 'master' into netgen-1.5 2020-03-28 03:00:24 -04:00
Tim Edwards 1be00bbd99 Merge branch 'master' into netgen-1.5 2020-03-27 03:00:21 -04:00
Tim Edwards 03b241a5d4 Merge branch 'master' into netgen-1.5 2020-03-11 03:00:17 -04:00
Tim Edwards 43cebd1ef9 Merge branch 'master' into netgen-1.5 2020-03-06 03:00:39 -05:00
Tim Edwards 0490959b07 Merge branch 'master' into netgen-1.5 2020-03-05 03:00:09 -05:00
Tim Edwards dc841f3293 Merge branch 'master' into netgen-1.5 2020-02-24 17:35:04 -05:00
Tim Edwards 05bcfede69 Merge branch 'master' into netgen-1.5 2020-02-24 16:39:19 -05:00
Tim Edwards 72ed78e55a Update for change in ocd git script 2020-02-24 15:04:59 -05:00
Tim Edwards 59bb8a89c0 "ocd_git_pure automatic update to repo" 2020-02-24 15:04:27 -05:00
Tim Edwards 9bdaee652e "ocd_git_pure automatic update to repo" 2020-02-18 03:00:14 -05:00
Tim Edwards 9879b58f83 Merge branch 'master' into netgen-1.5 2020-02-18 03:00:13 -05:00
Tim Edwards 9e3b705fcc "ocd_git_pure automatic update to repo" 2020-02-11 03:00:09 -05:00
Tim Edwards d2c9129242 Merge branch 'master' into netgen-1.5 2020-02-11 03:00:09 -05:00
Tim Edwards 942f421fa3 "ocd_git_pure automatic update to repo" 2020-01-30 03:01:39 -05:00
Tim Edwards 6bc948d8ba Merge branch 'master' into netgen-1.5 2020-01-30 03:01:38 -05:00
Tim Edwards c1ad37f05a "ocd_git_pure automatic update to repo" 2020-01-14 03:00:47 -05:00
Tim Edwards 9edefe7d59 Merge branch 'master' into netgen-1.5 2020-01-14 03:00:47 -05:00
Tim Edwards f6b9629521 "ocd_git_pure automatic update to repo" 2019-11-20 03:00:33 -05:00
Tim Edwards 7b2e01f2af Merge branch 'master' into netgen-1.5 2019-11-20 03:00:33 -05:00
Tim Edwards 224050f153 "ocd_git_pure automatic update to repo" 2019-10-09 03:00:08 -04:00
Tim Edwards 74e8c3e168 Merge branch 'master' into netgen-1.5 2019-10-09 03:00:08 -04:00
Tim Edwards 95a29fcd8c "ocd_git_pure automatic update to repo" 2019-09-11 03:00:07 -04:00
Tim Edwards 723a950fd3 Merge branch 'master' into netgen-1.5 2019-09-11 03:00:07 -04:00
Tim Edwards e3368cb22a "ocd_git_pure automatic update to repo" 2019-09-10 03:00:08 -04:00
Tim Edwards f06e6548bb Merge branch 'master' into netgen-1.5 2019-09-10 03:00:08 -04:00
Tim Edwards 72ed19ff36 "ocd_git_pure automatic update to repo" 2019-09-09 03:00:10 -04:00
Tim Edwards 39b8e3d14a Merge branch 'master' into netgen-1.5 2019-09-09 03:00:10 -04:00
Tim Edwards b63dfa8638 "ocd_git_pure automatic update to repo" 2019-08-20 03:00:20 -04:00
Tim Edwards f918f33c51 Merge branch 'master' into netgen-1.5 2019-08-20 03:00:20 -04:00
Tim Edwards 63b2e48ea1 "ocd_git_pure automatic update to repo" 2019-08-13 03:00:08 -04:00
Tim Edwards 6e63f49d53 Merge branch 'master' into netgen-1.5 2019-08-13 03:00:07 -04:00
Tim Edwards 419b6de29a "ocd_git_pure automatic update to repo" 2019-08-11 03:00:07 -04:00
Tim Edwards 205cf2aa58 Merge branch 'master' into netgen-1.5 2019-08-11 03:00:07 -04:00
Tim Edwards 52b6766fc8 "ocd_git_pure automatic update to repo" 2019-08-04 03:00:20 -04:00
Tim Edwards 7b0bdd29e8 Merge branch 'master' into netgen-1.5 2019-08-04 03:00:20 -04:00
Tim Edwards 433cbd090a "ocd_git_pure automatic update to repo" 2019-07-25 03:00:16 -04:00
Tim Edwards 3087bd3337 Merge branch 'master' into netgen-1.5 2019-07-25 03:00:16 -04:00
Tim Edwards b79a29d662 "ocd_git_pure automatic update to repo" 2019-07-15 03:00:27 -04:00
Tim Edwards bf9c61e412 Merge branch 'master' into netgen-1.5 2019-07-15 03:00:27 -04:00
Tim Edwards 8d34bd372d "ocd_git_pure automatic update to repo" 2019-07-03 03:00:22 -04:00
Tim Edwards 229c2931a8 Merge branch 'master' into netgen-1.5 2019-07-03 03:00:22 -04:00
Tim Edwards b8da97deb1 "ocd_git_pure automatic update to repo" 2019-06-16 03:00:15 -04:00
Tim Edwards b7187d5899 Merge branch 'master' into netgen-1.5 2019-06-16 03:00:15 -04:00
Tim Edwards d27d441c58 "ocd_git_pure automatic update to repo" 2019-06-13 03:00:05 -04:00
Tim Edwards 48c9e6b292 Merge branch 'master' into netgen-1.5 2019-06-13 03:00:05 -04:00
Tim Edwards ced5846da3 "ocd_git_pure automatic update to repo" 2019-05-18 03:00:05 -04:00
Tim Edwards b99d33064f Merge branch 'master' into netgen-1.5 2019-05-18 03:00:04 -04:00
Tim Edwards 399472e940 "ocd_git_pure automatic update to repo" 2019-05-07 09:13:00 -04:00
20 changed files with 792 additions and 1947 deletions

View File

@ -1 +1 @@
1.5.323
1.5.265

View File

@ -22,7 +22,6 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <stdarg.h>
#include <strings.h>
#include <ctype.h>
#ifdef IBMPC
#include <stdlib.h> /* for strtol on PC */
@ -91,7 +90,7 @@ char *ActelName(char *Name)
/* strip physical-pin information, if it exists */
if ((nm = strrchr(name,PHYSICALPIN[0])) != NULL) *nm = '\0';
if (strlen(name) > 13) {
ActelIndex = (ActelIndex + 1) % ACTELNAMESIZE;
ActelIndex = (++ActelIndex) % ACTELNAMESIZE;
/* format the value of the hashed value of the string */
sprintf(ActelNames[ActelIndex], "$%lX", ActelNameHash(name));
if (Debug)
@ -102,7 +101,7 @@ Printf("ActelNameHash returns %s on name %s\n",ActelNames[ActelIndex], name);
NeedsQuoting = 0;
if (NULL != strpbrk(name, ".,:; \t\"'\n\r")) NeedsQuoting = 1;
ActelIndex = (ActelIndex + 1) % ACTELNAMESIZE;
ActelIndex = (++ActelIndex) % ACTELNAMESIZE;
if (!NeedsQuoting) {
strcpy(ActelNames[ActelIndex], name);
return(ActelNames[ActelIndex]);

View File

@ -300,6 +300,8 @@ int flattenInstancesOf(char *name, int fnum, char *instance)
return 0;
}
}
/* Placeholder cells must not be flattened */
if (ThisCell->flags & CELL_PLACEHOLDER) return 0;
FreeNodeNames(ThisCell);
@ -337,10 +339,6 @@ int flattenInstancesOf(char *name, int fnum, char *instance)
LastObj = ParentParams;
continue;
}
if (ChildCell->flags & CELL_PLACEHOLDER) {
LastObj = ParentParams;
continue; // Placeholder cells must not be flattened
}
if (ChildCell == ThisCell) {
LastObj = ParentParams;
continue; // Avoid infinite loop
@ -602,10 +600,8 @@ int flattenInstancesOf(char *name, int fnum, char *instance)
else break;
/* Put the child cell at the start of ChildObjList */
if (ChildEnd) {
ChildEnd->next = ChildObjList;
ChildObjList = ChildStart;
}
ChildEnd->next = ChildObjList;
ChildObjList = ChildStart;
}
/* Put the child cell at the start of ChildObjList */
@ -1234,10 +1230,6 @@ int UniquePins(char *name, int filenum)
* Removed the code 9/1/2023. But---Not sure if any code depends
* on shorted pins being adjacent.
*/
/* When two pins are shorted, they are by definition permutable */
PermuteSetup(ThisCell->name, ThisCell->file, ob->name,
firstport[ob->node]->name);
continue;
}
else {
@ -1308,14 +1300,6 @@ int UniquePins(char *name, int filenum)
return 1;
}
/* Structure used below for keeping track of node numbers
* belonging to removed nodes.
*/
struct LinkedNum {
int node;
struct LinkedNum *next;
};
/*------------------------------------------------------*/
/* Callback function for CleanupPins */
/* Note that if the first pin of the instance is a */
@ -1328,7 +1312,6 @@ struct nlist *cleanuppins(struct hashlist *p, void *clientdata)
struct nlist *ptr;
struct objlist *ob, *obt, *lob, *nob, *firstpin, *pob;
struct nlist *tc = (struct nlist *)clientdata;
struct LinkedNum *newnodenum, *removedNodes = (struct LinkedNum *)NULL;
int pinnum;
char *saveinst = NULL;
@ -1384,15 +1367,6 @@ struct nlist *cleanuppins(struct hashlist *p, void *clientdata)
saveinst = ob->instance.name;
}
if (ob->model.class != NULL) FREE(ob->model.class);
// Record the net number of the pin being removed, to
// check at the end if the net belonged to a pin that
// got orphaned.
newnodenum = (struct LinkedNum *)MALLOC(sizeof(struct LinkedNum));
newnodenum->node = ob->node;
newnodenum->next = removedNodes;
removedNodes = newnodenum;
FREE(ob);
}
else {
@ -1436,28 +1410,6 @@ struct nlist *cleanuppins(struct hashlist *p, void *clientdata)
}
}
while (removedNodes != NULL) {
int nodenum = removedNodes->node;
struct objlist *ob2;
/* Only concerned with nodes that are in the pin list of ptr->cell */
for (ob = ptr->cell; ob != NULL; ob = ob->next) {
if (ob->type != PORT) break;
if (ob->node == nodenum) break;
}
if (ob && (ob->type == PORT)) {
/* Check if this node number exists only in the port record */
for (nob = ob->next; nob != NULL; nob = nob->next)
if (nob->node == nodenum) break;
if (nob == NULL) {
ob->node = -1; /* This pin is now disconnected */
}
}
newnodenum = removedNodes;
removedNodes = removedNodes->next;
FREE(newnodenum);
}
if (saveinst != NULL) FREE(saveinst);
return NULL; /* Keep the search going */
}
@ -1678,7 +1630,7 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
ECompare *ecomp, *ncomp;
ECompList *list0X, *listX0;
int hascontents1, hascontents2;
int match, modified1 = 0, modified2 = 0;
int match, modified = 0;
int not_top;
if (file1 == -1)
@ -1755,26 +1707,16 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
Fprintf(stdout, "Flattening instances of %s in cell %s (%d)"
" makes a better match\n", ecomp->cell1->name,
name1, file1);
if (flattenInstancesOf(name1, file1, ecomp->cell1->name) > 0)
modified1++;
}
else if (ecomp->cell1 && (ecomp->num1 > 0)) {
Fprintf(stdout, "Flattening instances of %s in cell %s (%d)"
" would make a better match but is prohibited.\n",
ecomp->cell1->name, name1, file1);
flattenInstancesOf(name1, file1, ecomp->cell1->name);
modified++;
}
if (ecomp->cell2 && (ecomp->num2 > 0) &&
(!(ecomp->cell2->flags & CELL_PLACEHOLDER))) {
Fprintf(stdout, "Flattening instances of %s in cell %s (%d)"
" makes a better match\n", ecomp->cell2->name,
name2, file2);
if (flattenInstancesOf(name2, file2, ecomp->cell2->name) > 0)
modified2++;
}
else if (ecomp->cell2 && (ecomp->num2 > 0)) {
Fprintf(stdout, "Flattening instances of %s in cell %s (%d)"
" would make a better match but is prohibited.\n",
ecomp->cell2->name, name2, file2);
flattenInstancesOf(name2, file2, ecomp->cell2->name);
modified++;
}
}
@ -1863,13 +1805,8 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
Fprintf(stdout, "Flattening instances of %s in cell %s (%d)"
" makes a better match\n", ecomp->cell2->name,
name2, file2);
if (flattenInstancesOf(name2, file2, ecomp->cell2->name) > 0)
modified2++;
}
else if (ecomp->cell2) {
Fprintf(stdout, "Flattening instances of %s in cell %s (%d)"
" would make a better match but is prohibited.\n",
ecomp->cell2->name, name2, file2);
flattenInstancesOf(name2, file2, ecomp->cell2->name);
modified++;
}
}
}
@ -1934,13 +1871,8 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
Fprintf(stdout, "Flattening instances of %s in cell %s (%d)"
" makes a better match\n", ecomp->cell1->name,
name1, file1);
if (flattenInstancesOf(name1, file1, ecomp->cell1->name) > 0)
modified1++;
}
else if (ecomp->cell1) {
Fprintf(stdout, "Flattening instances of %s in cell %s (%d)"
" would make a better match but is prohibited.\n",
ecomp->cell1->name, name1, file1);
flattenInstancesOf(name1, file1, ecomp->cell1->name);
modified++;
}
}
}
@ -2018,11 +1950,8 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
break;
}
}
if (found) break;
}
if (found) {
/* Beware remove shorting devices that */
/* Do NOT remove shorting devices that */
/* connect two ports. Otherwise the */
/* port lists get screwed up. It is */
/* better in that case to force the */
@ -2030,10 +1959,6 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
/* This is ignored for a top-level cell */
/* because it will just show up as a */
/* port mismatch error as it should. */
/* (12/12/2025---disabling this worked; */
/* may need to go back to a failing */
/* example and determine how pin */
/* matching gets scrambled.) */
if ((not_top == TRUE) &&
(ecomp->cell1->class != CLASS_ISOURCE)) {
@ -2046,18 +1971,14 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
else if (ob2->node == node2)
found2 = TRUE;
if (found1 && found2) {
Fprintf(stdout, "Warning: "
"zero-valued device connects "
"port %s to another port; pin "
"matching may be affected.\n",
ob2->name);
// found = FALSE;
found = FALSE;
break;
}
}
}
}
if (found) break;
}
if (found) {
Fprintf(stdout, "Removing zero-valued device "
"%s from cell %s (%d) makes a better "
@ -2105,7 +2026,7 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
/* Remove from list */
ecomp->num1--;
modified1++;
modified++;
ob1 = lob;
}
@ -2243,8 +2164,8 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
}
/* Remove from list */
ecomp->num2--;
modified2++;
ecomp->num1--;
modified++;
ob2 = lob;
}
@ -2278,7 +2199,7 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
// are no other modifications, as this rule is relaxed compared to other
// rules, and the other rules should be exhaustively applied first.
if ((listX0 != NULL) && (list0X != NULL) && ((modified1 + modified2) == 0)) {
if ((listX0 != NULL) && (list0X != NULL) && (modified == 0)) {
ECompare *ecomp0X, *ecompX0;
ECompList *elist0X, *elistX0;
for (elistX0 = listX0; elistX0; elistX0 = elistX0->next) {
@ -2304,24 +2225,13 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
ecompX0->cell1->file, &compdict);
if (dstr) *dstr = '[';
if ((ncomp == ecomp0X) && (ecomp0X->num2 <= ecompX0->num1)) {
if (!(ecompX0->cell1->flags & CELL_PLACEHOLDER)) {
Fprintf(stdout, "Flattening instances of %s in cell"
" %s (%d) makes a better match\n",
ecompX0->cell1->name, name1, file1);
if (flattenInstancesOf(name1, file1,
ecompX0->cell1->name) > 0) {
ecompX0->num1 = 0;
ecomp0X->num1 += ecompX0->num1;
modified1++;
}
}
else
{
Fprintf(stdout, "Flattening instances of %s in "
"cell %s (%d) would make a better "
"match but is prohibited.\n",
ecompX0->cell1->name, name1, file1);
}
Fprintf(stdout, "Flattening instances of %s in cell %s"
"(%d) makes a better match\n",
ecompX0->cell1->name, name1, file1);
flattenInstancesOf(name1, file1, ecompX0->cell1->name);
ecompX0->num1 = 0;
ecomp0X->num1 += ecompX0->num1;
modified++;
break;
}
}
@ -2341,23 +2251,13 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
ecomp0X->cell2->file, &compdict);
if (dstr) *dstr = '[';
if ((ncomp == ecompX0) && (ecompX0->num1 <= ecomp0X->num2)) {
if (!(ecomp0X->cell2->flags & CELL_PLACEHOLDER)) {
Fprintf(stdout, "Flattening instances of %s in cell"
" %s (%d) makes a better match\n",
ecomp0X->cell2->name, name2, file2);
if (flattenInstancesOf(name2, file2,
ecomp0X->cell2->name) > 0) {
ecomp0X->num2 = 0;
ecompX0->num2 += ecomp0X->num2;
modified2++;
}
}
else {
Fprintf(stdout, "Flattening instances of %s in "
"cell %s (%d) would make a better "
"match but is prohibited.\n",
ecompX0->cell2->name, name2, file2);
}
Fprintf(stdout, "Flattening instances of %s in cell %s"
" (%d) makes a better match\n",
ecomp0X->cell2->name, name2, file2);
flattenInstancesOf(name2, file2, ecomp0X->cell2->name);
ecomp0X->num2 = 0;
ecompX0->num2 += ecomp0X->num2;
modified++;
break;
}
}
@ -2388,17 +2288,5 @@ done:
FREE(list0X);
list0X = nextptr;
}
// If either netlist was modified, rebuild its node cache
if (modified1 > 0) {
FreeNodeNames(tc1);
CacheNodeNames(tc1);
}
if (modified2 > 0) {
FreeNodeNames(tc2);
CacheNodeNames(tc2);
}
return modified1 + modified2;
return modified;
}

View File

@ -137,39 +137,32 @@ static unsigned char uppercase[] = {
// horrible things can happen, as, for example, names AOI12 and OAI12
// have exactly the same hash result. Lousy for binning and even
// lousier for generating class magic numbers.
//
// Updated again 4/2/2026 to the FNV-1a hash, which is better than
// SDBM for this application, according to ChatGPT.
unsigned long hashnocase(char *s, int hashsize)
{
unsigned long hashval = 2166136261ul;
for (; *s != '\0'; s++) {
hashval ^= uppercase[*s];
hashval *= 16777619ul;
}
unsigned long hashval;
for (hashval = 0; *s != '\0'; )
hashval = uppercase[*s++]
+ (hashval << 6) + (hashval << 16) - hashval;
return (hashsize == 0) ? hashval : (hashval % hashsize);
}
unsigned long hashcase(char *s, int hashsize)
{
unsigned long hashval = 2166136261ul;
for (; *s != '\0'; s++) {
hashval ^= (unsigned char)(*s);
hashval *= 16777619ul;
}
unsigned long hashval;
for (hashval = 0; *s != '\0'; )
hashval = (*s++) + (hashval << 6) + (hashval << 16) - hashval;
return (hashsize == 0) ? hashval : (hashval % hashsize);
}
unsigned long genhash(char *s, int c, int hashsize)
{
unsigned long hashval = 2166136261ul;
hashval ^= (unsigned long)c;
hashval *= 16777619ul;
for (; *s != '\0'; s++) {
hashval ^= (unsigned char)(*s);
hashval *= 16777619ul;
}
unsigned long hashval;
for (hashval = (unsigned long)c; *s != '\0'; )
hashval = (*s++) + (hashval << 6) + (hashval << 16) - hashval;
return (hashsize == 0) ? hashval : (hashval % hashsize);
}

File diff suppressed because it is too large Load Diff

View File

@ -62,7 +62,7 @@ extern void RegroupDataStructures();
extern void FormatIllegalElementClasses();
extern void FormatIllegalNodeClasses();
extern int ResolveAutomorphsByProperty();
extern int ResolveAutomorphsByPin(int match_nets);
extern int ResolveAutomorphsByPin();
extern void SummarizeElementClasses(struct ElementClass *EC);
extern int remove_group_tags(struct objlist *ob);
@ -70,8 +70,6 @@ extern int remove_group_tags(struct objlist *ob);
#ifdef TCL_NETGEN
extern int EquivalentNode();
extern int EquivalentElement();
extern void DeriveAreaProperty();
extern void DerivePerimeterProperty();
extern void enable_interrupt();
extern void disable_interrupt();

View File

@ -302,7 +302,7 @@ int GetNextLineNoNewline(char *delimiter)
{
char *newbuf;
int testc;
static int nested = 0;
int nested = 0;
int llen;
if (feof(infile)) return -1;
@ -329,11 +329,6 @@ int GetNextLineNoNewline(char *delimiter)
llen = strlen(line);
}
while (llen == linesize - 1) {
/* Note that in the rare case where a newline is in the last buffer
* position, we're done.
*/
if (*(line + llen - 1) == '\n') break;
newbuf = (char *)MALLOC(linesize + 501);
strcpy(newbuf, line);
FREE(line);
@ -604,7 +599,7 @@ void SpiceTokNoNewline(void)
{
int contline;
if ((nexttok = strdtok0(NULL, WHITESPACE_DELIMITER, NULL, FALSE)) != NULL) return;
if ((nexttok = strdtok(NULL, WHITESPACE_DELIMITER, NULL)) != NULL) return;
while (nexttok == NULL) {
contline = getc(infile);
@ -685,7 +680,6 @@ void SpiceSkipNewLine(void)
ungetc(contline, infile);
}
#if 0 /* Commented with "#if 0" due to comment characters in the comment */
/*----------------------------------------------------------------------*/
/* Function similar to strtok() for token parsing. The difference is */
/* that it takes two sets of delimiters. The first is whitespace */
@ -706,9 +700,8 @@ void SpiceSkipNewLine(void)
/* the first character of the delimiter string in addition to marking */
/* the boundary between two-character and one-character delimiters. */
/*----------------------------------------------------------------------*/
#endif
char *strdtok0(char *pstring, char *delim1, char *delim2, char isverilog)
char *strdtok(char *pstring, char *delim1, char *delim2)
{
static char *stoken = NULL;
static char *sstring = NULL;
@ -753,7 +746,7 @@ char *strdtok0(char *pstring, char *delim1, char *delim2, char isverilog)
/* should know whether it is parsing SPICE or verilog and handle the syntax */
/* accordingly (needs to be done). */
if (isverilog && (*s == '\\')) {
if (*s == '\\') {
s++;
while (*s != '\0') {
if ((*s == ' ') || ((*s == '\\') && (*(s + 1) == '\0'))) {
@ -824,17 +817,6 @@ char *strdtok0(char *pstring, char *delim1, char *delim2, char isverilog)
return sstring;
}
/*----------------------------------------------------------------------*/
/* strdtok() is the original string tokenizer. It calls strdtok0() */
/* with isverilog=TRUE, so that tokens are parsed as (potentially) */
/* verilog names, which includes verilog backslash notation. */
/*----------------------------------------------------------------------*/
char *strdtok(char *pstring, char *delim1, char *delim2)
{
return strdtok0(pstring, delim1, delim2, TRUE);
}
/*----------------------------------------------------------------------*/
void InputParseError(FILE *f)

View File

@ -36,7 +36,6 @@ extern struct hashdict *definitions;
extern char *nexttok;
#define SKIPTO(a) do {SkipTok(NULL);} while (!match(nexttok,a))
extern char *strdtok0(char *pstring, char *delim1, char *delim2, char isverilog);
extern char *strdtok(char *pstring, char *delim1, char *delim2);
extern char *GetLineAtTok();
extern void SkipTok(char *delimiter);

View File

@ -25,8 +25,6 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <stdlib.h> /* for strtof() */
#include <stdarg.h>
#include <string.h>
#include <strings.h>
#include <ctype.h> /* toupper() */
#ifdef IBMPC
#include <alloc.h>
@ -302,9 +300,7 @@ int ReduceOneExpression(struct valuelist *kv, struct objlist *parprops,
tstr = sstr - 1;
numlast = 1;
}
/* But might not be. . . */
if ((dval != 0) || (sstr > estr))
break;
break;
}
/* Not a number, so must be arithmetic */
*tstr = '\0';
@ -324,9 +320,7 @@ int ReduceOneExpression(struct valuelist *kv, struct objlist *parprops,
tstr = sstr - 1;
numlast = 1;
}
/* But might not be. . . */
if ((dval != 0) || (sstr > estr))
break;
break;
}
/* Not a number, so must be arithmetic */
*tstr = '\0';
@ -2250,10 +2244,7 @@ int PromoteProperty(struct property *prop, struct valuelist *vl,
if (prop == NULL || vl == NULL) return -1;
if (prop->type == vl->type) return 1; /* Nothing to do */
result = 0;
/* If vl is an expression but prop is not, then try to reduce
* the expression in vl.
*/
if (vl->type == PROP_EXPRESSION) {
if (prop->type == PROP_EXPRESSION) {
ReduceOneExpression(vl, ob, tc, FALSE);
}
switch (prop->type) {
@ -3099,7 +3090,7 @@ void add_balancing_close(struct objlist *ob1, struct objlist *ob2)
for (nob = ob1->next; nob && nob->type != FIRSTPIN; nob = nob->next)
if (nob->type == PROPERTY)
break;
if (nob == NULL || nob->type != PROPERTY) return; // shouldn't happen
if (nob->type != PROPERTY) return; // shouldn't happen
opentags = 0;
for (; nob->next && nob->next->type == PROPERTY; nob = nob->next) {
@ -3649,7 +3640,7 @@ int CombineSeries(char *model, int file)
nob->type = PROPERTY;
nob->name = strsave("properties");
nob->node = -2; /* Don't report as disconnected node */
nob->model.class = (obp == NULL || obp->model.class == NULL) ? NULL :
nob->model.class = (obp->model.class == NULL) ? NULL :
strsave(obp->model.class);
nob->instance.props = NewPropValue(2);

View File

@ -223,35 +223,12 @@ int matchnocase(char *st1, char *st2)
{
char *sp1 = st1;
char *sp2 = st2;
char v1 = FALSE, v2 = FALSE;
/* In case of a property that does not exist in one netlist, matchnocase()
* may be passed a null value, so return 0 to indicate a non-match.
* *Both* values null will also be treated as a mismatch (debatable
* behavior).
*/
if (!sp1 || !sp2) return 0;
/* Verilog back-slash escaped names should match an equivalent non-
* back-slashed name. (NOTE: This behavior needs to be added to match().)
*/
if ((*sp1 == '\\') && (*sp2 != '\\')) {
v1 = TRUE;
sp1++;
}
if ((*sp2 == '\\') && (*sp1 != '\\')) {
v2 = TRUE;
sp2++;
}
while (*sp1 != '\0' && *sp2 != '\0') {
if (to_lower[*sp1] != to_lower[*sp2]) break;
sp1++;
sp2++;
}
if (v1 && (*sp1 == ' ')) sp1++;
if (v2 && (*sp2 == ' ')) sp2++;
if ((*sp1 != '\0') || (*sp2 != '\0')) return 0;
return 1;
}
@ -282,33 +259,6 @@ int matchfilenocase(char *st1, char *st2, int f1, int f2)
return 1;
}
/* Delimiter matching---Find an opening delimiter in a string. */
/* Return the position of the first opening delimeter in the string, */
/* like strchr(). Place the actual delimeter character in *delim. */
char *get_array_delimiter(char *name, char *delim)
{
char *stest = name;
while (*stest != '\0')
{
if (to_lower[*stest] == '<') {
*delim = *stest;
return stest;
}
stest++;
}
return NULL;
}
/* Delimiter parsing---Check if a character is an opening array delimiter. */
/* Return TRUE if the character is an opening delimiter, FALSE if not. */
int is_delimiter(char testc)
{
return (to_lower[testc] == '<') ? TRUE : FALSE;
}
#ifdef HAVE_MALLINFO
void PrintMemoryStats(void)
{
@ -476,7 +426,6 @@ int removeshorted(struct hashlist *p, int file)
ob = nob;
}
}
return 1;
}
/* Remove shorted instances of class "class" from the database */
@ -567,7 +516,6 @@ int deleteclass(struct hashlist *p, int file)
}
}
FREE(checknodes);
return 1;
}
/* Remove all instances of class "class" from the database */
@ -605,7 +553,6 @@ int renameinstances(struct hashlist *p, int file)
}
}
}
return 1;
}
void InstanceRename(char *from, char *to, int file)
@ -628,10 +575,9 @@ int freeprop(struct hashlist *p)
struct property *prop;
prop = (struct property *)(p->ptr);
if (prop->type == PROP_STRING) {
if (prop->type == PROP_STRING)
if (prop->pdefault.string != NULL)
FREE(prop->pdefault.string);
}
else if (prop->type == PROP_EXPRESSION) {
struct tokstack *stackptr, *nptr;
stackptr = prop->pdefault.stack;
@ -650,65 +596,65 @@ int freeprop(struct hashlist *p)
void CellDelete(char *name, int fnum)
{
/* delete all the contents of cell 'name', and remove 'name' from
the cell hash table. NOTE: this procedure does not care or check
if 'name' has been instanced anywhere. It is assumed that if this
is the case, the user will (quickly) define a new cell of that name.
*/
struct objlist *ob, *obnext;
struct nlist *tp;
/* delete all the contents of cell 'name', and remove 'name' from
the cell hash table. NOTE: this procedure does not care or check
if 'name' has been instanced anywhere. It is assumed that if this
is the case, the user will (quickly) define a new cell of that name.
*/
struct objlist *ob, *obnext;
struct nlist *tp;
tp = LookupCellFile(name, fnum);
if (tp == NULL) {
Printf ("No cell '%s' found.\n", name);
return;
}
tp = LookupCellFile(name, fnum);
if (tp == NULL) {
Printf ("No cell '%s' found.\n", name);
return;
}
HashIntDelete(name, fnum, &cell_dict);
/* now make sure that we free all the fields of the nlist struct */
if (tp->name != NULL) FREE(tp->name);
HashKill(&(tp->objdict));
HashKill(&(tp->instdict));
RecurseHashTable(&(tp->propdict), freeprop);
HashKill(&(tp->propdict));
FreeNodeNames(tp);
ob = tp->cell;
while (ob != NULL) {
obnext = ob->next;
FreeObject (ob);
ob = obnext;
}
HashIntDelete(name, fnum, &cell_dict);
/* now make sure that we free all the fields of the nlist struct */
if (tp->name != NULL) FREE(tp->name);
HashKill(&(tp->objdict));
HashKill(&(tp->instdict));
RecurseHashTable(&(tp->propdict), freeprop);
HashKill(&(tp->propdict));
FreeNodeNames(tp);
ob = tp->cell;
while (ob != NULL) {
obnext = ob->next;
FreeObject (ob);
ob = obnext;
}
}
static int PrintCellHashTableElement(struct hashlist *p)
{
struct nlist *ptr;
struct nlist *ptr;
ptr = (struct nlist *)(p->ptr);
if ((TopFile >= 0) && (ptr->file != TopFile)) return 1;
ptr = (struct nlist *)(p->ptr);
if ((TopFile >= 0) && (ptr->file != TopFile)) return 1;
if ((ptr->class != CLASS_SUBCKT) && (ptr->class != CLASS_MODULE)) {
/* only print primitive cells if Debug is enabled */
if (Debug == 1) Printf("Cell: %s (instanced %d times); Primitive\n",
if (ptr->class != CLASS_SUBCKT) {
/* only print primitive cells if Debug is enabled */
if (Debug == 1) Printf("Cell: %s (instanced %d times); Primitive\n",
ptr->name, ptr->number);
else if (Debug == 3) { /* list */
else if (Debug == 3) { /* list */
#ifdef TCL_NETGEN
Tcl_AppendElement(netgeninterp, ptr->name);
Tcl_AppendElement(netgeninterp, ptr->name);
#else
Printf("%s ", ptr->name);
Printf("%s ", ptr->name);
#endif
}
}
else if ((Debug == 2) || (Debug == 3)) { /* list only */
}
}
else if ((Debug == 2) || (Debug == 3)) { /* list only */
#ifdef TCL_NETGEN
Tcl_AppendElement(netgeninterp, ptr->name);
Tcl_AppendElement(netgeninterp, ptr->name);
#else
Printf("%s ", ptr->name);
Printf("%s ", ptr->name);
#endif
}
else
Printf("Cell: %s (instanced %d times)\n", ptr->name, ptr->number);
return(1);
}
else
Printf("Cell: %s (instanced %d times)\n",ptr->name,ptr->number);
return(1);
}
/* Print the contents of the cell hash table. */
@ -717,65 +663,65 @@ static int PrintCellHashTableElement(struct hashlist *p)
void PrintCellHashTable(int full, int filenum)
{
int total, bins;
int OldDebug;
int total, bins;
int OldDebug;
if ((filenum == -1) && (Circuit1 != NULL) && (Circuit2 != NULL)) {
if ((filenum == -1) && (Circuit1 != NULL) && (Circuit2 != NULL)) {
PrintCellHashTable(full, Circuit1->file);
PrintCellHashTable(full, Circuit2->file);
return;
}
}
TopFile = filenum;
TopFile = filenum;
bins = RecurseHashTable(&cell_dict, CountHashTableBinsUsed);
total = RecurseHashTable(&cell_dict, CountHashTableEntries);
if (full < 2)
Printf("Hash table: %d of %d bins used; %d cells total (%.2f per bin)\n",
bins = RecurseHashTable(&cell_dict, CountHashTableBinsUsed);
total = RecurseHashTable(&cell_dict, CountHashTableEntries);
if (full < 2)
Printf("Hash table: %d of %d bins used; %d cells total (%.2f per bin)\n",
bins, CELLHASHSIZE, total, (bins == 0) ? 0 :
(float)((float)total / (float)bins));
OldDebug = Debug;
Debug = full;
RecurseHashTable(&cell_dict, PrintCellHashTableElement);
Debug = OldDebug;
OldDebug = Debug;
Debug = full;
RecurseHashTable(&cell_dict, PrintCellHashTableElement);
Debug = OldDebug;
#ifndef TCL_NETGEN
if (full >= 2) Printf("\n");
if (full >= 2) Printf("\n");
#endif
}
struct nlist *FirstCell(void)
{
return((struct nlist *)HashFirst(&cell_dict));
return((struct nlist *)HashFirst(&cell_dict));
}
struct nlist *NextCell(void)
{
return((struct nlist *)HashNext(&cell_dict));
return((struct nlist *)HashNext(&cell_dict));
}
static int ClearDumpedElement(struct hashlist *np)
{
struct nlist *p;
struct nlist *p;
p = (struct nlist *)(np->ptr);
p->dumped = 0;
return(1);
p = (struct nlist *)(np->ptr);
p->dumped = 0;
return(1);
}
void ClearDumpedList(void)
{
RecurseHashTable(&cell_dict, ClearDumpedElement);
RecurseHashTable(&cell_dict, ClearDumpedElement);
}
int RecurseCellHashTable(int (*foo)(struct hashlist *np))
{
return RecurseHashTable(&cell_dict, foo);
return RecurseHashTable(&cell_dict, foo);
}
int RecurseCellFileHashTable(int (*foo)(struct hashlist *, int), int value)
{
return RecurseHashTableValue(&cell_dict, foo, value);
return RecurseHashTableValue(&cell_dict, foo, value);
}
/* Yet another version, passing one parameter that is a pointer */
@ -783,7 +729,7 @@ int RecurseCellFileHashTable(int (*foo)(struct hashlist *, int), int value)
struct nlist *RecurseCellHashTable2(struct nlist *(*foo)(struct hashlist *,
void *), void *pointer)
{
return RecurseHashTablePointer(&cell_dict, foo, pointer);
return RecurseHashTablePointer(&cell_dict, foo, pointer);
}
/************************** WILD-CARD STUFF *******************************/

View File

@ -309,8 +309,6 @@ extern int match(char *, char *);
extern int matchnocase(char *, char *);
extern int matchfile(char *, char *, int, int);
extern int matchfilenocase(char *, char *, int, int);
extern int is_delimiter(char);
extern char *get_array_delimiter(char *, char *);
extern void GarbageCollect(void);
extern void InitGarbageCollection(void);

View File

@ -319,7 +319,7 @@ void Fanout(char *cell, char *node, int filter)
while (ob != NULL) {
char *obname = ob->name;
if (*obname == '/') obname++;
if (ob->node == nodenum) {
if (ob->node == nodenum)
if (filter == ALLOBJECTS) {
Printf(" %s (", obname);
PrintObjectType(ob->type);
@ -331,7 +331,6 @@ void Fanout(char *cell, char *node, int filter)
else if (ob->type == filter) {
Printf(" %s\n", obname);
}
}
ob = ob->next;
}
}
@ -934,7 +933,7 @@ static int PrintLeavesInCellHash(struct hashlist *p)
struct nlist *ptr;
ptr = (struct nlist *)(p->ptr);
if (ptr->class == CLASS_SUBCKT) PrintLeavesInCell(ptr->name, ptr->file);
if ((ptr->class == CLASS_SUBCKT)) PrintLeavesInCell(ptr->name, ptr->file);
return(0);
}

View File

@ -21,9 +21,6 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "config.h"
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
#if 0
#include <stdarg.h> /* what about varargs, like in pdutils.c ??? */
#endif
@ -46,7 +43,6 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "print.h"
#include "query.h"
#include "objlist.h"
#include "netcmp.h"
// Global storage for parameters from .PARAM
struct hashdict spiceparams;
@ -196,7 +192,7 @@ void SpiceSubCell(struct nlist *tp, int IsSubCell)
if (ob->type == PROPERTY) {
struct valuelist *vl;
int i;
for (i = 0;; i++) {
for (i == 0;; i++) {
vl = &(ob->instance.props[i]);
if (vl->type == PROP_ENDLIST) break;
else if (vl->type == PROP_VALUE) {
@ -216,7 +212,7 @@ void SpiceSubCell(struct nlist *tp, int IsSubCell)
if (ob->type == PROPERTY) {
struct valuelist *vl;
int i;
for (i = 0;; i++) {
for (i == 0;; i++) {
vl = &(ob->instance.props[i]);
if (vl->type == PROP_ENDLIST) break;
else if (vl->type == PROP_VALUE) {
@ -236,7 +232,7 @@ void SpiceSubCell(struct nlist *tp, int IsSubCell)
if (ob->type == PROPERTY) {
struct valuelist *vl;
int i;
for (i = 0;; i++) {
for (i == 0;; i++) {
vl = &(ob->instance.props[i]);
if (vl->type == PROP_ENDLIST) break;
else if (vl->type == PROP_VALUE) {
@ -399,7 +395,7 @@ int renamepins(struct hashlist *p, int file)
ptr = (struct nlist *)(p->ptr);
if (ptr->file != file)
return 0;
return 1;
for (ob = ptr->cell; ob != NULL; ob = ob->next) {
if (ob->type == FIRSTPIN) {
@ -426,7 +422,6 @@ int renamepins(struct hashlist *p, int file)
}
}
}
return 1;
}
/* If any pins are marked unconnected, see if there are */
@ -524,7 +519,7 @@ void ReadSpiceFile(char *fname, int filenum, struct cellstack **CellStackPtr,
char *eqptr, devtype, in_subckt;
struct keyvalue *kvlist = NULL;
char inst[MAX_STR_LEN], model[MAX_STR_LEN], instname[MAX_STR_LEN];
struct nlist *tp, *tpsave;
struct nlist *tp;
struct objlist *parent, *sobj, *nobj, *lobj, *pobj;
inst[MAX_STR_LEN-1] = '\0';
@ -536,14 +531,8 @@ void ReadSpiceFile(char *fname, int filenum, struct cellstack **CellStackPtr,
SkipTok(NULL); /* get the next token */
if ((EndParseFile()) && (nexttok == NULL)) break;
if (nexttok == NULL) break;
/* Handle comment lines. Note that some variants of CDL format
* use "*." for information that is transparent to SPICE simulators.
* Handle "*.GLOBAL" entries. All others are ignored.
*/
if ((nexttok[0] == '*') && (!matchnocase(nexttok, "*.GLOBAL")))
SkipNewLine(NULL);
if (nexttok[0] == '*') SkipNewLine(NULL);
else if (matchnocase(nexttok, ".SUBCKT")) {
SpiceTokNoNewline();
@ -568,7 +557,6 @@ void ReadSpiceFile(char *fname, int filenum, struct cellstack **CellStackPtr,
snprintf(model, MAX_STR_LEN-1, "%s", nexttok);
tp = LookupCellFile(nexttok, filenum);
tpsave = NULL;
/* Check for name conflict with duplicate cell names */
/* This may mean that the cell was used before it was */
@ -607,46 +595,11 @@ void ReadSpiceFile(char *fname, int filenum, struct cellstack **CellStackPtr,
tp = LookupCellFile(nexttok, filenum);
}
else if (tp != NULL) { /* Make a new definition for an empty cell */
/* Handle issue with SPICE read after verilog, where a placeholder
* was created from the verilog. (1) If the pin names are "1", "2",
* "3", then this is a SPICE placeholder, and just remove the CellDef
* and re-create it. Otherwise, create new cell "_PLACEHOLDER_".
* (2) After encountering .ends, run MatchPins between the two cells.
* (3) delete the original cell and rename the new cell.
*/
int i = 1;
char pname[10];
for (pobj = tp->cell; pobj && pobj->type == PORT; pobj = pobj->next) {
sprintf(pname, "%d", i);
if (!matchnocase(pobj->name, pname)) break;
i++;
}
if ((pobj == NULL) || (pobj->type != PORT)) {
/* This is a SPICE placeholder created because the cell was instanced
* before it was defined. However, the pins can be assumed to be in
* the correct order, and pin reordering does not need to be done.
*/
FreePorts(nexttok);
CellDelete(nexttok, filenum); /* This removes any PLACEHOLDER flag */
CellDef(model, filenum);
tp = LookupCellFile(model, filenum);
update = 1; /* Will need to update existing instances */
}
else {
/* This is (probably) a verilog placeholder created because the
* verilog was read before the (SPICE) definitions. The verilog
* netlist should have named the pins of the parent cell. However,
* there is no guarantee the order of pins is correct. The MatchPins()
* routine from netcmp.c can be used here to match the cell against
* the placeholder, and reorder the pins in all instances to match.
* Note that we cannot just reorder the SPICE pins to match the
* verilog order, because there may be other SPICE netlists which
* instance the cell with the correct SPICE port order.
*/
tpsave = tp;
CellDef("_PLACEHOLDER_", filenum);
tp = LookupCellFile("_PLACEHOLDER_", filenum);
}
FreePorts(nexttok);
CellDelete(nexttok, filenum); /* This removes any PLACEHOLDER flag */
CellDef(model, filenum);
tp = LookupCellFile(model, filenum);
update = 1; /* Will need to update existing instances */
}
else if (tp == NULL) { /* Completely new cell, no name conflict */
CellDef(model, filenum);
@ -738,38 +691,6 @@ skip_ends:
if (*CellStackPtr) PopStack(CellStackPtr);
if (*CellStackPtr) ReopenCellDef((*CellStackPtr)->cellname, filenum);
SkipNewLine(NULL);
if (tpsave != NULL) {
struct nlist *tpplace;
char *savename;
/* Handle a placeholder from a verilog file that has been replaced
* by a netlist with pins in a different order. The pins need to
* be matched, corrected in the original cell and all instances,
* and the new cell deleted.
*/
Printf("Verilog placeholder %s replaced by SPICE definition\n",
tpsave->name);
tpplace = LookupCellFile("_PLACEHOLDER_", filenum);
/* MatchPins is part of netcmp and normally Circuit2 is the
* circuit being matched, so set Circuit2 to the original
* verilog black-box cell, and MatchPins() will force its
* pins to be rearranged to match the SPICE definition just
* read.
*/
Circuit2 = tpsave;
MatchPins(tpplace, tpsave, 0);
savename = strsave(tpsave->name);
/* Now the original verilog black-box cell can be removed */
FreePorts(savename);
CellDelete(savename, filenum);
/* And _PLACEHOLDER_ is renamed to the original name of the cell. */
CellRehash("_PLACEHOLDER_", savename, filenum);
tpsave = NULL;
Circuit2 = NULL;
FREE(savename);
}
}
else if (matchnocase(nexttok, ".MODEL")) {
unsigned char class = CLASS_SUBCKT;
@ -831,10 +752,7 @@ skip_ends:
// Handle some commonly-used cards
/* .GLOBAL and *.GLOBAL. Note that *.GLOBAL is excepted from comment-line
* handling, above, so any line starting with '*' is "*.GLOBAL".
*/
else if (matchnocase(nexttok, ".GLOBAL") || (nexttok[0] == '*')) {
else if (matchnocase(nexttok, ".GLOBAL")) {
while (nexttok != NULL) {
int numnodes = 0;
SpiceTokNoNewline();
@ -1783,19 +1701,10 @@ skip_ends:
if (scan->next != NULL) scan = scan->next;
tail->next = NULL;
/* Check for class defined inside itself (self-referential loop) */
if (!strcasecmp(model, scan->name)) {
Fprintf(stderr, "Fatal: Class \"%s\" is instanced inside of itself!\n",
scan->name);
InputParseError(stderr);
return;
}
/* Check for ignored class */
if ((itype = IsIgnored(scan->name, filenum)) == IGNORE_CLASS) {
Printf("Class '%s' instanced in input but is being ignored.\n", scan->name);
if ((itype = IsIgnored(subcktname, filenum)) == IGNORE_CLASS) {
Printf("Class '%s' instanced in input but is being ignored.\n", model);
return;
}
@ -1810,7 +1719,7 @@ skip_ends:
break;
}
if (shorted == (unsigned char)1) {
Printf("Instance of '%s' is shorted, ignoring.\n", scan->name);
Printf("Instance of '%s' is shorted, ignoring.\n", subcktname);
while (head) {
p = head->next;
FREE(head);

View File

@ -57,7 +57,6 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "netfile.h"
#include "print.h"
#include "hash.h"
#include "netcmp.h"
// See netfile.c for explanation of delimiters. 'X'
// separates single-character delimiters from two-character delimiters.
@ -76,8 +75,7 @@ struct hashdict verilogparams;
// Global storage for verilog definitions
struct hashdict verilogdefs;
// Record file pointer that is associated with the hash tables
int hashfilep = -1; /* for parameters */
int hashfiled = -1; /* for definitions */
int hashfile = -1;
// Global storage for wire buses
struct hashdict buses;
@ -157,8 +155,7 @@ struct expr_stack {
//-------------------------------------------------------------------------
// Evaluate an expression for an array bound. This is much like
// ReduceOneExpression() in netgen.c, but only handles basic integer
// arithmetic (+,-,*,/), grouping by parentheses, bit shifts, and
// if-else operators.
// arithmetic (+,-,*,/) and grouping by parentheses.
//
// Returns 1 if successful, 0 on error.
// Evaluated result is placed in the integer pointed to by "valptr".
@ -222,39 +219,6 @@ int EvalExpr(struct expr_stack **stackptr, int *valptr)
}
}
/* Reduce (a << b) and (a >> b) */
for (texp = start; texp; texp = texp->next) {
if ((texp->last != NULL) && (texp->next != NULL) && (texp->oper != '\0')) {
if ((texp->last->oper == '\0') && (texp->next->oper == '\0')) {
if (texp->oper == '<') {
/* Left shift */
texp->last->value <<= texp->next->value;
/* Remove two items from the stack */
tmp = texp;
texp = texp->last;
texp->next = tmp->next->next;
if (tmp->next->next) tmp->next->next->last = texp;
FREE(tmp->next);
FREE(tmp);
modified = TRUE;
}
if (texp->oper == '>') {
/* Right shift */
texp->last->value >>= texp->next->value;
/* Remove two items from the stack */
tmp = texp;
texp = texp->last;
texp->next = tmp->next->next;
if (tmp->next->next) tmp->next->next->last = texp;
FREE(tmp->next);
FREE(tmp);
modified = TRUE;
}
}
}
}
/* Reduce (a * b) and (a / b) */
for (texp = start; texp; texp = texp->next) {
@ -330,39 +294,6 @@ int EvalExpr(struct expr_stack **stackptr, int *valptr)
}
}
/* Reduce (a ? b : c) */
for (texp = start; texp; texp = texp->next) {
/* There must be at least five objects on the stack */
if ((texp->last != NULL) && (texp->next != NULL) && (texp->oper != '\0')
&& (texp->next->next != NULL)
&& (texp->next->next->next != NULL)) {
if ((texp->last->oper == '\0') && (texp->next->oper == '\0')
&& (texp->next->next->next->oper == '\0')) {
if ((texp->oper == '?') && (texp->next->next->oper == ':')) {
/* If-Else conditional */
if (texp->last->value)
texp->last->value = texp->next->value;
else
texp->last->value = texp->next->next->next->value;
/* Remove four items from the stack */
tmp = texp;
texp = texp->last;
texp->next = tmp->next->next->next->next;
if (tmp->next->next->next->next)
tmp->next->next->next->next->last = texp;
FREE(tmp->next->next->next);
FREE(tmp->next->next);
FREE(tmp->next);
FREE(tmp);
modified = TRUE;
}
}
}
}
/* Reduce (a) */
for (texp = start; texp; texp = texp->next) {
@ -441,15 +372,8 @@ int ParseIntegerExpression(char *expr, int *iptr)
if (match(sptr, "+") || match(sptr, "-")
|| match(sptr, "*") || match(sptr, "/")
|| match(sptr, "(") || match(sptr, ")")
|| match(sptr, "<<") || match(sptr, ">>")
|| match(sptr, "?") || match(sptr, ":")) {
|| match(sptr, "(") || match(sptr, ")")) {
newexp = (struct expr_stack *)MALLOC(sizeof(struct expr_stack));
/* Note that "oper" is one character and that "<<" and ">>"
* become '<' and '>', respectively. The less-than and greater-
* than operators are not (yet) handled but will need to be
* recast to some other character in "oper".
*/
newexp->oper = *sptr;
newexp->value = 0;
newexp->next = NULL;
@ -464,7 +388,7 @@ int ParseIntegerExpression(char *expr, int *iptr)
if ((result = sscanf(sptr, "%d", &value)) != 1) {
// Is name in the parameter list?
kl = (struct property *)HashLookup(sptr, &verilogparams);
kl = (struct property *)HashLookup(nexttok, &verilogparams);
if (kl == NULL) {
Printf("Value %s in expression is not a number or a parameter.\n",
sptr);
@ -477,29 +401,27 @@ int ParseIntegerExpression(char *expr, int *iptr)
if (result != 1) {
Printf("Parameter %s has value %s that cannot be parsed"
" as an integer.\n",
sptr, kl->pdefault.string);
nexttok, kl->pdefault.string);
value = 0;
break;
}
}
else if (kl->type == PROP_INTEGER) {
value = kl->pdefault.ival;
result = 1; // Assert valid result
}
else if (kl->type == PROP_DOUBLE) {
value = (int)kl->pdefault.dval;
if ((double)value != kl->pdefault.dval) {
Printf("Parameter %s has value %g that cannot be parsed"
" as an integer.\n",
sptr, kl->pdefault.dval);
nexttok, kl->pdefault.dval);
value = 0;
break;
}
result = 1; // Assert valid result
}
else {
Printf("Parameter %s has unknown type; don't know how"
" to parse.\n", sptr);
" to parse.\n", nexttok);
value = 0;
break;
}
@ -593,8 +515,7 @@ int GetBusTok(struct bus *wb)
}
else if (match(nexttok, "+") || match(nexttok, "-")
|| match(nexttok, "*") || match(nexttok, "/")
|| match(nexttok, "(") || match(nexttok, ")")
|| match(nexttok, "<<") || match(nexttok, ">>")) {
|| match(nexttok, "(") || match(nexttok, ")")) {
newexp = (struct expr_stack *)MALLOC(sizeof(struct expr_stack));
newexp->oper = *nexttok;
newexp->value = 0;
@ -795,12 +716,10 @@ int GetBus(char *astr, struct bus *wb)
return 0;
}
//--------------------------------------------------------------------
// Output a Verilog Module. Note that since Verilog does not describe
// low-level devices like transistors, capacitors, etc., then this
// format is limited to black-box subcircuits. Cells containing any
// such low-level devices are ignored.
//--------------------------------------------------------------------
void VerilogModule(struct nlist *tp)
{
@ -1099,7 +1018,7 @@ void ReadVerilogFile(char *fname, int filenum, struct cellstack **CellStackPtr,
char *eqptr, *matchptr;
struct keyvalue *kvlist = NULL;
char inst[MAX_STR_LEN], model[MAX_STR_LEN], portname[MAX_STR_LEN], pkey[MAX_STR_LEN];
struct nlist *tp, *tpsave;
struct nlist *tp;
struct objlist *parent, *sobj, *nobj, *lobj, *pobj, *cref;
inst[MAX_STR_LEN-1] = '\0';
@ -1233,7 +1152,6 @@ void ReadVerilogFile(char *fname, int filenum, struct cellstack **CellStackPtr,
snprintf(model, MAX_STR_LEN-1, "%s", nexttok);
tp = LookupCellFile(nexttok, filenum);
tpsave = NULL;
hasports = (char)0;
/* Check for name conflict with duplicate cell names */
@ -1273,9 +1191,35 @@ void ReadVerilogFile(char *fname, int filenum, struct cellstack **CellStackPtr,
tp = LookupCellFile(nexttok, filenum);
}
else if (tp != NULL) { /* Cell exists, but as a placeholder */
tpsave = tp;
CellDef("_PLACEHOLDER_", filenum);
tp = LookupCellFile("_PLACEHOLDER_", filenum);
struct nlist *tptmp = NULL;
char ctemp[8];
int n = 0;
/* This redefines a placeholder module to an unused temporary cell name */
while (1) {
sprintf(ctemp, "%d", n);
tptmp = LookupCellFile(ctemp, filenum);
if (tptmp == NULL) break;
n++;
}
CellRehash(nexttok, ctemp, filenum);
tptmp = LookupCellFile(ctemp, filenum);
/* Create a new module definition */
CellDef(model, filenum);
tp = LookupCellFile(model, filenum);
/* Find an instance of this module in the netlist */
cref = FindInstanceOf(tp);
if ((cref != NULL) && (cref->name != NULL)) {
hasports = (char)1;
/* Copy ports from the original parent cell to the new parent cell */
for (pobj = tptmp->cell; pobj && (pobj->type == PORT); pobj = pobj->next)
Port(pobj->name);
}
/* Remove the original cell definition */
FreePorts(ctemp);
CellDelete(ctemp, filenum); /* This removes any PLACEHOLDER flag */
}
else if (tp == NULL) { /* Completely new cell, no name conflict */
CellDef(model, filenum);
@ -1484,93 +1428,6 @@ skip_endmodule:
if (*CellStackPtr) PopStack(CellStackPtr);
if (*CellStackPtr) ReopenCellDef((*CellStackPtr)->cellname, filenum);
SkipNewLine(VLOG_DELIMITERS);
if (tpsave != NULL) {
struct nlist *tpplace;
char *savename;
int lnum, pnum, ltest;
unsigned char valid;
struct objlist *lobj, *pobj;
/* Handle a placeholder from a verilog file that has been replaced
* by a netlist with pins in a different order. The pins need to
* be matched, corrected in the original cell and all instances,
* and the new cell deleted.
*/
Printf("Verilog placeholder module %s replaced by module definition\n",
tpsave->name);
tpplace = LookupCellFile("_PLACEHOLDER_", filenum);
/* If tpsave was generated from an instance in a SPICE netlist that
* did not have a black-box subcircuit definition, then the pins
* will all be labeled 1, 2, 3, etc. If so, then assume that the
* verilog pins are in order, and rename the placeholder pins.
* If the number of pins does not match, or if the pins are not
* labeled as ascending integers, then leave the cell alone.
* In either case, output a warning message.
*/
/* Get the number of ports in the placeholder */
pnum = 0;
for (pobj = tpplace->cell; pobj; pobj = pobj->next) {
if (pobj->type != PORT) break;
pnum++;
}
/* Get the number of ports in the saved cell and make */
/* sure that it equals the number of ports in the */
/* placeholder, and that all of the ports in the saved */
/* cell are integers in ascending order. */
valid = TRUE;
lnum = 0;
for (lobj = tpsave->cell; lobj; lobj = lobj->next) {
if (lobj->type != PORT) break;
lnum++;
if (sscanf(lobj->name, "%d", &ltest) != 1) break;
if (ltest != lnum) break;
}
if ((lobj != NULL) && (lobj->type == PORT))
valid = FALSE; /* Pins are not integers in ascending order */
if (pnum != lnum) valid = FALSE; /* Different number of pins */
if (valid == TRUE) {
Printf("Replacing pins of placeholder cell %s from cell definition.\n",
tpsave->name);
pobj = tpplace->cell;
for (lobj = tpsave->cell; lobj; lobj = lobj->next) {
if (lobj->type != PORT) break;
if (pobj == NULL) break; /* should not happen */
FREE(lobj->name);
lobj->name = (char *)MALLOC(strlen(pobj->name) + 1);
strcpy(lobj->name, pobj->name);
pobj = pobj->next;
}
}
else {
Printf("Placeholder pins of cell %s are not compatible and"
" will be left unchanged\n", tpsave->name);
}
/* MatchPins is part of netcmp and normally Circuit2 is the
* circuit being matched, so set Circuit2 to the original
* verilog black-box cell, and MatchPins() will force its
* pins to be rearranged to match the module definition just
* read.
*/
Circuit2 = tpsave;
MatchPins(tpplace, tpsave, 0);
savename = strsave(tpsave->name);
/* Now the original verilog black-box cell can be removed */
FreePorts(savename);
CellDelete(savename, filenum);
/* And _PLACEHOLDER_ is renamed to the original name of the cell. */
CellRehash("_PLACEHOLDER_", savename, filenum);
tpsave = NULL;
Circuit2 = NULL;
FREE(savename);
}
}
else if (match(nexttok, "`include")) {
@ -1913,41 +1770,8 @@ skip_endmodule:
}
else { /* "assign" */
SkipTokComments(VLOG_PIN_CHECK_DELIMITERS);
char *aptr = strvchr(nexttok, '[');
/* This is a repeat of code to handle reading of pins, and
* makes sure that all input has been read to the closing
* bracket. There needs to be a single routine to do this,
* or (better) rewrite the parser with lex instead of trying
* to enumerate all the syntax cases separately.
*/
if ((aptr != NULL) && (strvchr(nexttok, ']') == NULL))
{
/* If a bus expressions has whitespace, then concatenate
* to the closing ']'.
*/
char *array_expr = (char *)MALLOC(1);
char *new_array_expr = NULL;
*array_expr = '\0';
/* Read to "]" */
while (nexttok) {
new_array_expr = (char *)MALLOC(strlen(array_expr) +
strlen(nexttok) + 1);
/* Roundabout way to do realloc() becase there is no REALLOC() */
strcpy(new_array_expr, array_expr);
strcat(new_array_expr, nexttok);
FREE(array_expr);
array_expr = new_array_expr;
if (strchr(nexttok, ']')) break;
SkipTokComments(VLOG_PIN_CHECK_DELIMITERS);
}
if (!nexttok) {
Printf("Unterminated array in assignment %s\n", array_expr);
}
}
if (((aptr == NULL) && (GetBusTok(&wb) == 0)) ||
((aptr != NULL) && (GetBus(aptr, &wb) == 0))) {
if (GetBusTok(&wb) == 0) {
char *aptr = strvchr(nexttok, '[');
if (aptr != NULL) {
*aptr = '\0';
/* Find object of first net in bus */
@ -1965,15 +1789,6 @@ skip_endmodule:
}
else {
lhs = LookupObject(nexttok, CurrentCell);
/* Handle the case in which an assignment is made
* without first declaring a wire for the signal,
* which is considered valid syntax (patch by
* Sylvain Munaut).
*/
if (lhs == NULL) {
Node(nexttok);
lhs = LookupObject(nexttok, CurrentCell);
}
strcpy(noderoot, nexttok);
}
SkipTokComments(VLOG_DELIMITERS);
@ -1989,8 +1804,7 @@ skip_endmodule:
// Allowed uses of "assign" for netlists:
// "assign a = b" joins two nets.
// "assign a = {b, c, ...}" creates a bus from components.
// "assign" using if-else constructs or bit shifts.
// ("assign" using any other boolean arithmetic is not structural verilog.)
// "assign" using any boolean arithmetic is not structural verilog.
// "assign a = {x{b}}" creates a bus by repeating a component.
if (nexttok && match(nexttok, "=")) {
@ -2023,9 +1837,8 @@ skip_endmodule:
break;
}
else {
char *aptr = strvchr(nexttok, '[');
if (((aptr == NULL) && (GetBusTok(&wb2) == 0)) ||
((aptr != NULL) && (GetBus(aptr, &wb2) == 0))) {
if (GetBusTok(&wb2) == 0) {
char *aptr = strvchr(nexttok, '[');
j = wb2.start;
if (aptr != NULL) {
*aptr = '\0';
@ -2251,19 +2064,6 @@ nextinst:
}
SkipTokComments(VLOG_DELIMITERS);
}
else if (loop.loopvar != NULL) {
/* Instances created within a generate block for loop have an
* implicit array
*/
int loopval;
struct property *klr;
klr = (struct property *)HashLookup(loop.loopvar, &verilogparams);
loopval = klr->pdefault.ival;
arraystart = arrayend = loopval;
sprintf(instancename + strlen(instancename), "[%d]", loopval);
}
if (match(nexttok, "(")) {
char savetok = (char)0;
@ -2326,19 +2126,7 @@ nextinst:
strcat(new_wire_bundle, nexttok);
FREE(wire_bundle);
wire_bundle = new_wire_bundle;
if (!strcmp(nexttok, "}"))
{
/* If a "bundle" has only one component, then it is
* not really a bundle and should be treated as a
* single wire.
*/
if (strchr(wire_bundle, ',') == NULL) {
int blen = strlen(wire_bundle + 1) - 1;
memmove(wire_bundle, wire_bundle + 1, blen);
*(wire_bundle + blen) = '\0';
}
break;
}
if (!strcmp(nexttok, "}")) break;
SkipTokComments(VLOG_PIN_CHECK_DELIMITERS);
}
if (!nexttok) {
@ -2714,7 +2502,6 @@ nextinst:
char *brackptr;
int j;
char locinst[MAX_STR_LEN];
int arraypos = (arraystart > arrayend) ? arraymax - i : i;
if (i != -1)
sprintf(locinst, "%s[%d]", instancename, i);
@ -2751,27 +2538,18 @@ nextinst:
if (scan == NULL) {
char localnet[MAX_STR_LEN];
/* Assume an implicit unconnected pin, unless there are no pins */
if (strcmp(obpinname, "(no pins)")) {
sprintf(localnet, "_noconnect_%d_", localcount++);
Node(localnet);
join(localnet, obptr->name);
Fprintf(stdout,
/* Assume an implicit unconnected pin */
sprintf(localnet, "_noconnect_%d_", localcount++);
Node(localnet);
join(localnet, obptr->name);
Fprintf(stdout,
"Note: Implicit pin %s in instance %s of %s in cell %s\n",
obpinname, locinst, modulename, CurrentCell->name);
}
}
else if (GetBus(scan->net, &wb) == 0) {
char *bptr2;
char *scanroot;
int isbundle = FALSE;
/* Skip over a bundle delimiter */
if (*scan->net == '{') {
scanroot = strsave(scan->net + 1);
isbundle = TRUE;
}
else
scanroot = strsave(scan->net);
scanroot = strsave(scan->net);
brackptr = strvchr(scanroot, '[');
if (brackptr) *brackptr = '\0';
@ -2804,7 +2582,6 @@ nextinst:
else {
// Instance must be an array
char netname[MAX_STR_LEN];
char *spos = scanroot;
int slice, portlen, siglen;
/* Get the array size of the port for bit slicing */
@ -2816,49 +2593,27 @@ nextinst:
if (siglen < 0) siglen = -siglen;
siglen++;
// If this is a bundle, then count out to the current
// slice and read off the index. NOTE: Need to
// handle multiple bits per bundle entry!
if (isbundle) {
int j;
if (brackptr) *brackptr = '[';
for (j = 0; j < arraypos * portlen; j++) {
spos = strvchr(spos, ',');
if (spos == NULL) break;
spos++;
}
if (spos != NULL) {
brackptr = strvchr(spos, '[');
*brackptr = '\0';
sscanf(brackptr + 1, "%d", &slice);
}
else spos = scanroot; /* should emit an error here */
// If signal array is smaller than the portlength *
// length of instance array, then the signal wraps.
if (wb2.start >= wb2.end && arraystart >= arrayend) {
slice = wb.start - (arraystart - i) * portlen;
while (slice < wb2.end) slice += siglen;
}
else { /* not a bundle */
// If signal array is smaller than the portlength *
// length of instance array, then the signal wraps.
if (wb2.start >= wb2.end && arraystart >= arrayend) {
slice = wb.start - (arraystart - i) * portlen;
while (slice < wb2.end) slice += siglen;
}
else if (wb2.start < wb2.end && arraystart > arrayend) {
slice = wb.start + (arraystart - i) * portlen;
while (slice > wb2.end) slice -= siglen;
}
else if (wb2.start > wb2.end && arraystart < arrayend) {
slice = wb.start - (arraystart + i) * portlen;
while (slice < wb2.end) slice += siglen;
}
else { // (wb2.start < wb2.end && arraystart < arrayend)
slice = wb.start + (arraystart + i) * portlen;
while (slice > wb2.end) slice -= siglen;
}
spos = scanroot;
else if (wb2.start < wb2.end && arraystart > arrayend) {
slice = wb.start + (arraystart - i) * portlen;
while (slice > wb2.end) slice -= siglen;
}
else if (wb2.start > wb2.end && arraystart < arrayend) {
slice = wb.start - (arraystart + i) * portlen;
while (slice < wb2.end) slice += siglen;
}
else { // (wb2.start < wb2.end && arraystart < arrayend)
slice = wb.start + (arraystart + i) * portlen;
while (slice > wb2.end) slice -= siglen;
}
sprintf(netname, "%s[%d]", spos, slice);
sprintf(netname, "%s[%d]", scanroot, slice);
if (LookupObject(netname, CurrentCell) == NULL) Node(netname);
join(netname, obptr->name);
}
@ -3043,25 +2798,18 @@ char *ReadVerilogTop(char *fname, int *fnum, int blackbox)
hashfunc = hashcase;
}
if ((hashfilep != -1) && (hashfilep != *fnum)) {
/* Started a new file, so remove all the parameters */
if ((hashfile != -1) && (hashfile != *fnum)) {
/* Started a new file, so remove all the parameters and definitions */
RecurseHashTable(&verilogparams, freeprop);
HashKill(&verilogparams);
hashfilep = -1;
}
if ((hashfiled != -1) && (hashfiled != *fnum)) {
/* Started a new file, so remove all the definitions */
RecurseHashTable(&verilogdefs, freeprop);
HashKill(&verilogdefs);
hashfiled = -1;
hashfile = -1;
}
if (hashfilep == -1) {
if (hashfile == -1) {
InitializeHashTable(&verilogparams, OBJHASHSIZE);
hashfilep = filenum;
}
if (hashfiled == -1) {
InitializeHashTable(&verilogdefs, OBJHASHSIZE);
hashfiled = filenum;
hashfile = *fnum;
}
definitions = &verilogdefs;

51
scripts/configure vendored
View File

@ -668,6 +668,7 @@ XMKMF
HAVE_PYTHON3
EGREP
GREP
M4
RANLIB
INSTALL_DATA
INSTALL_SCRIPT
@ -3701,6 +3702,56 @@ else
fi
for ac_prog in gm4 gnum4 m4
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_path_M4+:} false; then :
$as_echo_n "(cached) " >&6
else
case $M4 in
[\\/]* | ?:[\\/]*)
ac_cv_path_M4="$M4" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_M4="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
M4=$ac_cv_path_M4
if test -n "$M4"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $M4" >&5
$as_echo "$M4" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
test -n "$M4" && break
done
test -n "$M4" || M4="no"
if test x$M4 = xno; then
as_fn_error $? "M4 is required" "$LINENO" 5
fi
if test "$CPP" = "$CC -E" ; then
CPP="$CPP -x c"

View File

@ -26,6 +26,12 @@ AC_ISC_POSIX
AC_PROG_INSTALL
AC_PROG_RANLIB
dnl GNU M4 is preferred due to some of the option switches.
AC_PATH_PROGS([M4], [gm4 gnum4 m4], [no])
if test x$M4 = xno; then
AC_MSG_ERROR([M4 is required])
fi
dnl check size of pointer for correct behavior on 64-bit systems
dnl If the C preprocessor is GCC, we need to force the flag to
dnl assert that input files are of type C, or else the preprocessing

View File

@ -68,7 +68,6 @@ LIB_SPECS = @LIB_SPECS@
LIB_SPECS_NOSTUB = @LIB_SPECS_NOSTUB@
WISH_EXE = @WISH_EXE@
TCL_LIB_DIR = @TCL_LIB_DIR@
EXTRA_CFLAGS =
CC = @CC@
CPP = @CPP@
@ -77,7 +76,7 @@ CXX = @CXX@
CPPFLAGS = -I. -I${NETGENDIR} @CPPFLAGS@
DFLAGS = @extra_defs@ @stub_defs@ @DEFS@ -DSHDLIB_EXT=\"@SHDLIB_EXT@\" -DNDEBUG
DFLAGS_NOSTUB = @extra_defs@ @DEFS@ -DSHDLIB_EXT=\"@SHDLIB_EXT@\" -DNDEBUG
CFLAGS = @CFLAGS@ @SHLIB_CFLAGS@ @INC_SPECS@ ${EXTRA_CFLAGS}
CFLAGS = @CFLAGS@ @SHLIB_CFLAGS@ @INC_SPECS@
DEPEND_FILE = Depend
DEPEND_FLAG = @DEPEND_FLAG@

View File

@ -429,7 +429,7 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} {
set file1 $name1
set cell1 $name1
}
puts stdout "Reading netlist file $file1 for $name1"
puts stdout "Reading netlist file $file1"
set fnum1 [netgen::readnet $file1]
} else {
set cell1 [lindex $flist1 0]
@ -446,7 +446,7 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} {
set file2 $name2
set cell2 $name2
}
puts stdout "Reading netlist file $file2 for $name2"
puts stdout "Reading netlist file $file2"
set fnum2 [netgen::readnet $file2]
} else {
set cell2 [lindex $flist2 0]
@ -461,7 +461,7 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} {
}
set clist1 [cells list $fnum1]
set cidx [lsearch -exact $clist1 $cell1]
set cidx [lsearch -regexp $clist1 ^$cell1$]
if {$cidx < 0} {
puts stderr "Cannot find cell $cell1 in file $file1"
return
@ -469,7 +469,7 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} {
set cell1 [lindex $clist1 $cidx]
}
set clist2 [cells list $fnum2]
set cidx [lsearch -exact $clist2 $cell2]
set cidx [lsearch -regexp $clist2 ^$cell2$]
if {$cidx < 0} {
puts stderr "Cannot find cell $cell2 in file $file2"
return
@ -477,18 +477,6 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} {
set cell2 [lindex $clist2 $cidx]
}
# The "noflat" list is non-file-specific, so run on each file.
foreach cell $noflat {
set cidx [lsearch -regexp $clist1 ^$cell$]
if {$cidx >= 0} {
netgen::flatten prohibit "$fnum1 $cell"
}
set cidx [lsearch -regexp $clist2 ^$cell$]
if {$cidx >= 0} {
netgen::flatten prohibit "$fnum2 $cell"
}
}
netgen::compare assign "$fnum1 $cell1" "$fnum2 $cell2"
if {$setupfile == ""} {
@ -516,14 +504,6 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} {
}
}
close $fsetup
if {$command != {}} {
# Incomplete command. Evaluate it to get a meaningful error message
if {[catch {uplevel 1 [list namespace eval netgen $command]} msg]} {
set msg [string trimright $msg "\n"]
puts stderr "Error $setupfile:$sline (ignoring), $msg"
incr perrors
}
}
} else {
puts stdout "Error: Cannot read the setup file $setupfile"
}
@ -614,9 +594,6 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} {
lappend properr [lindex $endval 0]
} elseif {$uresult == -2} { ;# unmatched pins
set doCheckFlatten 1
} elseif {$uresult == -4} { ;# unmatched pins and properties
lappend properr [lindex $endval 0]
set doCheckFlatten 1
}
} else {
# not equivalent
@ -678,11 +655,6 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} {
}
} elseif {[netgen::print queue] == {} && $result == 0} {
set pinMismatch 1
} else {
# This assumes that proxy pins are added correctly. Previously,
# that was not trusted, and so an initial pin mismatch would
# always force subcells to be flattened.
set doFlatten 0
}
}
if {$doFlatten} {

View File

@ -21,8 +21,6 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <stdlib.h> /* for getenv */
#include <string.h>
#include <strings.h>
#include <stdarg.h> /* for va_list */
#include <tcl.h>
@ -45,14 +43,14 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define FALSE 0
#endif
#if TCL_MAJOR_VERSION < 9
typedef int Tcl_Size;
#endif
/*-----------------------*/
/* Tcl 8.4 compatibility */
/*-----------------------*/
#ifndef CONST84
#define CONST84
#endif
Tcl_Interp *netgeninterp;
Tcl_Interp *consoleinterp;
int ColumnBase = 0;
@ -62,47 +60,47 @@ extern int PropertyErrorDetected;
/* Function prototypes for all Tcl command callbacks */
int _netgen_readnet(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netgen_readlib(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netgen_canonical(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netgen_writenet(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netgen_flatten(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netgen_nodes(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netgen_elements(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netgen_debug(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netgen_protochip(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netgen_instances(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netgen_contents(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netgen_describe(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netgen_cells(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netgen_ports(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netgen_model(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netgen_leaves(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netgen_quit(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netgen_reinit(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netgen_log(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netgen_readnet(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netgen_readlib(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netgen_canonical(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netgen_writenet(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netgen_flatten(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netgen_nodes(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netgen_elements(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netgen_debug(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netgen_protochip(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netgen_instances(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netgen_contents(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netgen_describe(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netgen_cells(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netgen_ports(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netgen_model(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netgen_leaves(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netgen_quit(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netgen_reinit(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netgen_log(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
#ifdef HAVE_MALLINFO
int _netgen_printmem(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netgen_printmem(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
#endif
int _netgen_help(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netcmp_matching(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netcmp_compare(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netcmp_iterate(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netcmp_summary(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netcmp_print(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netcmp_format(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netcmp_run(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netcmp_verify(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netcmp_automorphs(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netcmp_equate(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netcmp_ignore(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netcmp_permute(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netcmp_property(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netcmp_exhaustive(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netcmp_symmetry(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netcmp_restart(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netcmp_global(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netcmp_convert(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]);
int _netgen_help(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_matching(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_compare(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_iterate(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_summary(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_print(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_format(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_run(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_verify(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_automorphs(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_equate(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_ignore(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_permute(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_property(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_exhaustive(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_symmetry(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_restart(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_global(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_convert(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
typedef struct _Cmd {
char *name;
@ -289,7 +287,7 @@ GetTopCell(int fnum)
int
CommonGetFilenameOrFile(Tcl_Interp *interp, Tcl_Obj *fobj, int *fnumptr)
{
int result;
int result, llen;
int fnum, ftest;
char *filename;
struct nlist *tp;
@ -372,8 +370,7 @@ CommonParseCell(Tcl_Interp *interp, Tcl_Obj *objv,
struct nlist **tpr, int *fnumptr)
{
Tcl_Obj *tobj, *fobj;
int result;
Tcl_Size llen;
int result, llen;
int fnum, ftest, index;
char *filename, *cellname;
struct nlist *tp, *tp2;
@ -402,7 +399,7 @@ CommonParseCell(Tcl_Interp *interp, Tcl_Obj *objv,
Tcl_ResetResult(interp);
/* Is 1st argument a special keyword? */
if (Tcl_GetIndexFromObj(interp, tobj, (const char **)suboptions,
if (Tcl_GetIndexFromObj(interp, tobj, (CONST84 char **)suboptions,
"special", 0, &index) == TCL_OK) {
switch (index) {
case CIRCUIT1_IDX:
@ -458,7 +455,7 @@ CommonParseCell(Tcl_Interp *interp, Tcl_Obj *objv,
/* Check if 2nd item is a reserved keyword */
if (Tcl_GetIndexFromObj(interp, fobj,
(const char **)suboptions,
(CONST84 char **)suboptions,
"special", 0, &index) == TCL_OK) {
switch (index) {
case CIRCUIT1_IDX:
@ -583,7 +580,7 @@ CommonParseCell(Tcl_Interp *interp, Tcl_Obj *objv,
} else {
/* Only one name given; check if it matches subOption */
if (Tcl_GetIndexFromObj(interp, objv, (const char **)suboptions,
if (Tcl_GetIndexFromObj(interp, objv, (CONST84 char **)suboptions,
"special", 0, &index) == TCL_OK) {
switch (index) {
@ -668,7 +665,7 @@ CommonParseCell(Tcl_Interp *interp, Tcl_Obj *objv,
int
_netgen_canonical(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
int result;
struct nlist *np;
@ -707,7 +704,7 @@ _netgen_canonical(ClientData clientData,
int
_netgen_readnet(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
char *formats[] = {
"automatic", "ext", "extflat", "sim", "prm", "ntk", "spice",
@ -744,7 +741,7 @@ _netgen_readnet(ClientData clientData,
return TCL_ERROR;
}
else if (objc > 1) {
if (Tcl_GetIndexFromObj(interp, objv[1], (const char **)formats,
if (Tcl_GetIndexFromObj(interp, objv[1], (CONST84 char **)formats,
"format", 0, &index) != TCL_OK) {
if (objc == 3)
@ -853,7 +850,7 @@ _netgen_readnet(ClientData clientData,
int
_netgen_readlib(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
char *formats[] = {
"actel", "spice", "xilinx", NULL
@ -886,7 +883,7 @@ _netgen_readlib(ClientData clientData,
Tcl_WrongNumArgs(interp, 1, objv, "format [file]");
return TCL_ERROR;
}
if (Tcl_GetIndexFromObj(interp, objv[1], (const char **)formats,
if (Tcl_GetIndexFromObj(interp, objv[1], (CONST84 char **)formats,
"format", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
@ -933,7 +930,7 @@ _netgen_readlib(ClientData clientData,
int
_netgen_writenet(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
char *formats[] = {
"ext", "sim", "ntk", "actel",
@ -952,7 +949,7 @@ _netgen_writenet(ClientData clientData,
Tcl_WrongNumArgs(interp, 1, objv, "format file");
return TCL_ERROR;
}
if (Tcl_GetIndexFromObj(interp, objv[1], (const char **)formats,
if (Tcl_GetIndexFromObj(interp, objv[1], (CONST84 char **)formats,
"format", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
@ -1020,11 +1017,11 @@ _netgen_writenet(ClientData clientData,
int
_netgen_flatten(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
char *repstr, *file;
int result, filenum;
struct nlist *tp, *tp2, *tptop;
int result, llen, filenum;
struct nlist *tp, *tp2;
if ((objc < 2) || (objc > 4)) {
Tcl_WrongNumArgs(interp, 1, objv, "?class? valid_cellname");
@ -1038,7 +1035,7 @@ _netgen_flatten(ClientData clientData,
if (objc >= 3) {
char *argv = Tcl_GetString(objv[1]);
if (!strcmp(argv, "class")) {
tptop = GetTopCell(filenum);
tp = GetTopCell(filenum);
if (objc == 4) {
int numflat;
@ -1049,7 +1046,7 @@ _netgen_flatten(ClientData clientData,
}
else {
Printf("Flattening instances of %s in cell %s within file %s\n",
repstr, tp2->name, tptop->name);
repstr, tp2->name, tp->name);
numflat = flattenInstancesOf(tp2->name, filenum, repstr);
if (numflat == 0) {
Tcl_SetResult(interp, "No instances found to flatten.", NULL);
@ -1058,19 +1055,15 @@ _netgen_flatten(ClientData clientData,
}
}
else {
Printf("Flattening instances of %s in file %s\n", repstr, tptop->name);
Printf("Flattening instances of %s in file %s\n", repstr, tp->name);
FlattenInstancesOf(repstr, filenum);
}
}
else if (!strcmp(argv, "prohibit") || !strcmp(argv, "deny")) {
tptop = GetTopCell(filenum);
if (tp == NULL)
Printf("Error: Cell %s does not exist.\n", repstr);
else {
Printf("Will not flatten instances of %s in file %s\n", repstr, tptop->name);
/* Mark cell as placeholder so it will not be flattened */
tp->flags |= CELL_PLACEHOLDER;
}
tp = GetTopCell(filenum);
Printf("Will not flatten instances of %s in file %s\n", repstr, tp->name);
/* Mark cell as placeholder so it will not be flattened */
tp->flags |= CELL_PLACEHOLDER;
}
else {
Tcl_WrongNumArgs(interp, 1, objv, "class valid_cellname");
@ -1094,7 +1087,7 @@ _netgen_flatten(ClientData clientData,
int
_netgen_nodes(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
char *estr = NULL, *istr = NULL, *cstr, *fstr;
char *optstart;
@ -1212,7 +1205,7 @@ _netgen_nodes(ClientData clientData,
int
_netgen_elements(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
char *nstr = NULL, *cstr;
struct objlist * (*ListSave)();
@ -1307,7 +1300,7 @@ _netgen_elements(ClientData clientData,
int
_netgen_debug(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
char *yesno[] = {
"on", "off", NULL
@ -1321,7 +1314,7 @@ _netgen_debug(ClientData clientData,
if (objc == 1)
index = YES_IDX;
else {
if (Tcl_GetIndexFromObj(interp, objv[1], (const char **)yesno,
if (Tcl_GetIndexFromObj(interp, objv[1], (CONST84 char **)yesno,
"option", 0, &index) != TCL_OK) {
index = CMD_IDX;
}
@ -1356,7 +1349,7 @@ _netgen_debug(ClientData clientData,
int
_netgen_protochip(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
if (objc != 1) {
Tcl_WrongNumArgs(interp, 1, objv, "(no arguments)");
@ -1376,7 +1369,7 @@ _netgen_protochip(ClientData clientData,
int
_netgen_instances(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
char *repstr;
int result;
@ -1406,7 +1399,7 @@ _netgen_instances(ClientData clientData,
int
_netgen_contents(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
char *repstr;
int result;
@ -1435,7 +1428,7 @@ _netgen_contents(ClientData clientData,
int
_netgen_describe(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
char *repstr;
int file = -1;
@ -1465,7 +1458,7 @@ _netgen_describe(ClientData clientData,
int
_netgen_cells(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
char *repstr, *filename = NULL;
char *optstart;
@ -1552,7 +1545,7 @@ _netgen_cells(ClientData clientData,
int
_netgen_model(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
struct nlist *tp, *tp2;
char *model, *retclass;
@ -1602,9 +1595,10 @@ _netgen_model(ClientData clientData,
return result;
if (objc == 3) {
nports = NumberOfPorts(tp->name, fnum);
model = Tcl_GetString(objv[2]);
nports = NumberOfPorts(model, fnum);
if (Tcl_GetIndexFromObj(interp, objv[2], (const char **)modelclasses,
if (Tcl_GetIndexFromObj(interp, objv[2], (CONST84 char **)modelclasses,
"class", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
@ -1774,7 +1768,7 @@ wrongNumPorts:
int
_netgen_ports(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
char *repstr;
int result;
@ -1804,7 +1798,7 @@ _netgen_ports(ClientData clientData,
int
_netgen_leaves(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
char *repstr;
int result;
@ -1840,7 +1834,7 @@ _netgen_leaves(ClientData clientData,
int
_netgen_quit(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
if (objc != 1) {
Tcl_WrongNumArgs(interp, 1, objv, "(no arguments)");
@ -1868,7 +1862,7 @@ _netgen_quit(ClientData clientData,
int
_netgen_reinit(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
if (objc != 1) {
Tcl_WrongNumArgs(interp, 1, objv, "(no arguments)");
@ -1888,7 +1882,7 @@ _netgen_reinit(ClientData clientData,
int
_netgen_log(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
char *yesno[] = {
"start", "end", "reset", "suspend", "resume", "file", "echo", "put", NULL
@ -1905,7 +1899,7 @@ _netgen_log(ClientData clientData,
index = (LoggingFile) ? RESUME_IDX : START_IDX;
}
else {
if (Tcl_GetIndexFromObj(interp, objv[1], (const char **)yesno,
if (Tcl_GetIndexFromObj(interp, objv[1], (CONST84 char **)yesno,
"option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
@ -2032,7 +2026,7 @@ _netgen_log(ClientData clientData,
int
_netgen_printmem(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
if (objc != 1) {
Tcl_WrongNumArgs(interp, 1, objv, "(no arguments)");
@ -2054,7 +2048,7 @@ _netgen_printmem(ClientData clientData,
int
_netcmp_format(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
int col1_width = 41, col2_width = 41;
@ -2115,13 +2109,13 @@ _netcmp_format(ClientData clientData,
int
_netcmp_compare(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
char *name1, *name2, *file1, *file2, *optstart;
int fnum1, fnum2, dolist = 0;
int dohierarchy = FALSE;
int assignonly = FALSE;
int argstart = 1, qresult, result;
int argstart = 1, qresult, llen, result;
int hascontents1, hascontents2;
struct Correspond *nextcomp;
struct nlist *tp1 = NULL, *tp2 = NULL;
@ -2292,7 +2286,7 @@ _netcmp_compare(ClientData clientData,
int
_netcmp_iterate(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
if (objc != 1) {
Tcl_WrongNumArgs(interp, 1, objv, "(no arguments)");
@ -2316,7 +2310,7 @@ _netcmp_iterate(ClientData clientData,
int
_netcmp_summary(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
char *options[] = {
"nodes", "elements", NULL
@ -2331,7 +2325,7 @@ _netcmp_summary(ClientData clientData,
return TCL_ERROR;
}
if (objc == 2) {
if (Tcl_GetIndexFromObj(interp, objv[1], (const char **)options,
if (Tcl_GetIndexFromObj(interp, objv[1], (CONST84 char **)options,
"option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
@ -2357,7 +2351,7 @@ _netcmp_summary(ClientData clientData,
int
_netcmp_print(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
char *options[] = {
"nodes", "elements", "queue", NULL
@ -2395,16 +2389,16 @@ _netcmp_print(ClientData clientData,
return TCL_ERROR;
}
if (objc >= 2) {
if (Tcl_GetIndexFromObj(interp, objv[1], (const char **)options,
if (Tcl_GetIndexFromObj(interp, objv[1], (CONST84 char **)options,
"option", 0, &index) != TCL_OK) {
if ((objc == 2) && (Tcl_GetIndexFromObj(interp, objv[1],
(const char **)classes, "class", 0, &class) != TCL_OK)) {
(CONST84 char **)classes, "class", 0, &class) != TCL_OK)) {
return TCL_ERROR;
}
}
}
if (objc == 3 && index != QUEUE_IDX) {
if (Tcl_GetIndexFromObj(interp, objv[2], (const char **)classes,
if (Tcl_GetIndexFromObj(interp, objv[2], (CONST84 char **)classes,
"class", 0, &class) != TCL_OK) {
return TCL_ERROR;
}
@ -2448,7 +2442,7 @@ _netcmp_print(ClientData clientData,
int
_netcmp_run(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
char *options[] = {
"converge", "resolve", NULL
@ -2475,7 +2469,7 @@ _netcmp_run(ClientData clientData,
if (objc == 1)
index = RESOLVE_IDX;
else {
if (Tcl_GetIndexFromObj(interp, objv[1], (const char **)options,
if (Tcl_GetIndexFromObj(interp, objv[1], (CONST84 char **)options,
"option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
@ -2519,13 +2513,7 @@ _netcmp_run(ClientData clientData,
if (automorphisms > 0) {
// Next, attempt to resolve automorphisms uniquely by
// using the pin names
automorphisms = ResolveAutomorphsByPin(FALSE);
}
if (automorphisms > 0) {
// Next, attempt to resolve automorphisms uniquely by
// using the net names (should only be done after
// resolving by pin).
automorphisms = ResolveAutomorphsByPin(TRUE);
automorphisms = ResolveAutomorphsByPin();
}
if (automorphisms > 0) {
// Anything left is truly indistinguishable
@ -2535,16 +2523,8 @@ _netcmp_run(ClientData clientData,
if (automorphisms == -1)
Fprintf(stdout, "Netlists do not match.\n");
else if (automorphisms == -2) {
Fprintf(stdout, "Netlists match uniquely with port");
if (PropertyErrorDetected) {
Fprintf(stdout, " and property errors.\n");
PrintPropertyResults(dolist);
}
else {
Fprintf(stdout, " errors.\n");
}
}
else if (automorphisms == -2)
Fprintf(stdout, "Netlists match uniquely with port errors.\n");
else {
if (automorphisms == 0)
Fprintf(stdout, "Netlists match uniquely");
@ -2579,7 +2559,6 @@ _netcmp_run(ClientData clientData,
/* 0: not verified */
/* -1: no elements or nodes */
/* -3: verified with property error */
/* -4: verified with property and port errors */
/* equiv option */
/* -2: pin mismatch */
/* */
@ -2592,7 +2571,7 @@ _netcmp_run(ClientData clientData,
int
_netcmp_verify(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
char *options[] = {
"nodes", "elements", "properties", "only", "all", "equivalent", "unique", NULL
@ -2624,7 +2603,7 @@ _netcmp_verify(ClientData clientData,
return TCL_ERROR;
}
if (objc == 2) {
if (Tcl_GetIndexFromObj(interp, objv[1], (const char **)options,
if (Tcl_GetIndexFromObj(interp, objv[1], (CONST84 char **)options,
"option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
@ -2673,20 +2652,14 @@ _netcmp_verify(ClientData clientData,
disable_interrupt();
if (index == EQUIV_IDX || index == UNIQUE_IDX)
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
else {
else
Fprintf(stdout, "Netlists do not match.\n");
Fprintf(stdout, "Port matching may fail to disambiguate symmetries.\n");
}
}
else if (automorphisms == -2) {
if (index == EQUIV_IDX)
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
else if (index == UNIQUE_IDX) {
if (PropertyErrorDetected == 0)
Tcl_SetObjResult(interp, Tcl_NewIntObj(-2));
else
Tcl_SetObjResult(interp, Tcl_NewIntObj(-4));
}
else if (index == UNIQUE_IDX)
Tcl_SetObjResult(interp, Tcl_NewIntObj(-2));
else if (index > 0)
Fprintf(stdout, "Circuits match uniquely with port errors.\n");
}
@ -2781,7 +2754,7 @@ _netcmp_verify(ClientData clientData,
int
_netcmp_automorphs(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
if (objc != 1) {
Tcl_WrongNumArgs(interp, 1, objv, "(no arguments)");
@ -2802,7 +2775,7 @@ _netcmp_automorphs(ClientData clientData,
int
_netcmp_convert(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
char *cellname;
int filenum = -1;
@ -2832,10 +2805,10 @@ _netcmp_convert(ClientData clientData,
int
_netcmp_global(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
char *filename, *cellname, *pattern;
int numchanged = 0, p, fnum, result;
int numchanged = 0, p, fnum, llen, result;
struct nlist *tp;
if (objc < 2) {
@ -2869,7 +2842,7 @@ _netcmp_global(ClientData clientData,
int
_netcmp_ignore(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
char *options[] = {
"class", "shorted", NULL
@ -2883,7 +2856,7 @@ _netcmp_ignore(ClientData clientData,
char *name = NULL, *name2 = NULL;
if (objc >= 3) {
if (Tcl_GetIndexFromObj(interp, objv[1], (const char **)options,
if (Tcl_GetIndexFromObj(interp, objv[1], (CONST84 char **)options,
"option", 0, &index) == TCL_OK) {
objc--;
objv++;
@ -2917,7 +2890,7 @@ _netcmp_ignore(ClientData clientData,
int
_netcmp_equate(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
char *options[] = {
"nodes", "elements", "classes", "pins", NULL
@ -2932,8 +2905,7 @@ _netcmp_equate(ClientData clientData,
struct ElementClass *saveEclass = NULL;
struct NodeClass *saveNclass = NULL;
int file1, file2;
int i, dolist = 0, doforce = 0, dounique = 0;
Tcl_Size l1, l2, lent, ltest;
int i, l1, l2, ltest, lent, dolist = 0, doforce = 0, dounique = 0;
Tcl_Obj *tobj1, *tobj2, *tobj3;
while (objc > 1) {
@ -2963,7 +2935,7 @@ _netcmp_equate(ClientData clientData,
return TCL_ERROR;
}
else {
if (Tcl_GetIndexFromObj(interp, objv[1], (const char **)options,
if (Tcl_GetIndexFromObj(interp, objv[1], (CONST84 char **)options,
"option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
@ -3432,31 +3404,22 @@ _netcmp_equate(ClientData clientData,
int
_netcmp_property(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
int fnum, i;
int fnum, i, llen;
struct nlist *tp;
struct property *kl, *kllast, *klnext;
Tcl_Obj *tobj1, *tobj2, *tobj3;
Tcl_Size llen;
double dval;
int ival, argstart;
char *topoptions[] = {
"default", "series", "serial", "parallel", "topology", NULL
};
enum TopOptionIdx {
TOP_DEFAULT_IDX, TOP_SERIES_IDX, TOP_SERIAL_IDX, TOP_PARALLEL_IDX,
TOP_TOPOLOGY_IDX
};
char *options[] = {
"add", "create", "remove", "delete", "tolerance", "merge", "serial",
"series", "parallel", "associate", "derive", NULL
"series", "parallel", "associate", "topology", NULL
};
enum OptionIdx {
ADD_IDX, CREATE_IDX, REMOVE_IDX, DELETE_IDX, TOLERANCE_IDX, MERGE_IDX,
SERIAL_IDX, SERIES_IDX, PARALLEL_IDX, ASSOCIATE_IDX, DERIVE_IDX
SERIAL_IDX, SERIES_IDX, PARALLEL_IDX, ASSOCIATE_IDX, TOPOLOGY_IDX
};
int result, index, idx2;
@ -3491,14 +3454,6 @@ _netcmp_property(ClientData clientData,
COMB_NONE_IDX, COMB_PAR_IDX, COMB_ADD_IDX, COMB_CRITICAL_IDX
};
char *deriveoptions[] = {
"area", "perimeter", NULL
};
enum DeriveOptionIdx {
AREA_IDX, PERIMETER_IDX
};
char *yesno[] = {
"on", "yes", "true", "enable", "allow",
"off", "no", "false", "disable", "prohibit", NULL
@ -3513,13 +3468,8 @@ _netcmp_property(ClientData clientData,
"strict", "relaxed", NULL
};
/* Don't need to check return value */
index = -1;
Tcl_GetIndexFromObj(interp, objv[1], (const char **)topoptions,
"option", 0, &index);
/* Check for special command "property default" */
if ((objc == 2) && (index == TOP_DEFAULT_IDX)) {
if ((objc == 2) && (!strcmp(Tcl_GetString(objv[1]), "default"))) {
/* For each FET device, do "merge {w add_critical}" and */
/* "remove as ad ps pd". This allows parallel devices */
@ -3566,7 +3516,7 @@ _netcmp_property(ClientData clientData,
}
return TCL_OK;
}
else if ((objc == 3) && (index == TOP_PARALLEL_IDX)) {
else if ((objc == 3) && (!strcmp(Tcl_GetString(objv[1]), "parallel"))) {
if (!strcmp(Tcl_GetString(objv[2]), "none")) {
GlobalParallelNone = TRUE;
SetParallelCombine(FALSE);
@ -3588,7 +3538,8 @@ _netcmp_property(ClientData clientData,
}
return TCL_OK;
}
else if ((objc == 3) && ((index == TOP_SERIES_IDX) || (index == TOP_SERIAL_IDX))) {
else if ((objc == 3) && ((!strcmp(Tcl_GetString(objv[1]), "series")) ||
(!strcmp(Tcl_GetString(objv[1]), "serial")))) {
if (!strcmp(Tcl_GetString(objv[2]), "none")) {
SetSeriesCombine(FALSE);
}
@ -3602,7 +3553,7 @@ _netcmp_property(ClientData clientData,
}
return TCL_OK;
}
else if ((objc > 1) && (index == TOP_TOPOLOGY_IDX)) {
else if ((objc > 1) && (!strcmp(Tcl_GetString(objv[1]), "topology"))) {
if (objc == 2) {
if (ExactTopology)
Tcl_SetResult(interp, "Strict topology property matching.",
@ -3613,7 +3564,7 @@ _netcmp_property(ClientData clientData,
}
else if (objc == 3) {
if (Tcl_GetIndexFromObj(interp, objv[2],
(const char **)topo,
(CONST84 char **)topo,
"topology", 0, &idx2) == TCL_OK) {
if (idx2 == 0)
ExactTopology = TRUE;
@ -3672,7 +3623,7 @@ _netcmp_property(ClientData clientData,
Tcl_SetObjResult(interp, tobj1);
}
else {
if (Tcl_GetIndexFromObj(interp, objv[2], (const char **)options,
if (Tcl_GetIndexFromObj(interp, objv[2], (CONST84 char **)options,
"option", 0, &index) != TCL_OK) {
index = ADD_IDX;
argstart = 2;
@ -3705,7 +3656,7 @@ _netcmp_property(ClientData clientData,
// Each value must be a list of two, or a yes/no answer.
if (Tcl_GetIndexFromObj(interp, objv[i],
(const char **)yesno,
(CONST84 char **)yesno,
"combine", 0, &idx2) == TCL_OK) {
if (idx2 <= 4) { /* true, enable, etc. */
if (index == SERIAL_IDX || index == SERIES_IDX)
@ -3737,7 +3688,7 @@ _netcmp_property(ClientData clientData,
if (result != TCL_OK) return result;
result = Tcl_GetIndexFromObj(interp, tobj2,
(const char **)combineoptions,
(CONST84 char **)combineoptions,
"combine_type", 0, &idx2);
if (result != TCL_OK) return result;
@ -3822,7 +3773,7 @@ _netcmp_property(ClientData clientData,
/* {key, type} or {key, tolerance} duplet */
if (Tcl_GetIndexFromObj(interp, tobj2,
(const char **)suboptions,
(CONST84 char **)suboptions,
"type", 0, &idx2) != TCL_OK) {
Tcl_ResetResult(interp);
if (Tcl_GetDoubleFromObj(interp, tobj2, &dval)
@ -3866,7 +3817,7 @@ _netcmp_property(ClientData clientData,
/* {key, type, tolerance} triplet */
if (Tcl_GetIndexFromObj(interp, tobj2,
(const char **)suboptions,
(CONST84 char **)suboptions,
"type", 0, &idx2) != TCL_OK)
return TCL_ERROR;
@ -4009,7 +3960,7 @@ _netcmp_property(ClientData clientData,
if (result != TCL_OK) return result;
result = Tcl_GetIndexFromObj(interp, tobj2,
(const char **)mergeoptions,
(CONST84 char **)mergeoptions,
"merge_type", 0, &idx2);
if (result != TCL_OK) return result;
@ -4048,32 +3999,6 @@ _netcmp_property(ClientData clientData,
}
break;
case DERIVE_IDX:
/* Create a derived property. For now, this just creates
* "area" or "perimeter" properties. There may not (?)
* be enough cause to make other ones. Unlike other
* "property" options, this option causes the whole circuit
* database to be searched for the device in question, and
* the new property is added.
*/
if (objc < 6) {
Tcl_WrongNumArgs(interp, 2, objv, "{area|perimeter width length}");
return TCL_ERROR;
}
result = Tcl_GetIndexFromObj(interp, objv[3],
(const char **)deriveoptions,
"area|perimeter", 0, &idx2);
if (result != TCL_OK) return result;
switch (idx2) {
case AREA_IDX:
DeriveAreaProperty(tp, fnum, Tcl_GetString(objv[4]),
Tcl_GetString(objv[5]));
break;
case PERIMETER_IDX:
DerivePerimeterProperty(tp, fnum, Tcl_GetString(objv[4]),
Tcl_GetString(objv[5]));
break;
}
}
}
return TCL_OK;
@ -4093,7 +4018,7 @@ _netcmp_property(ClientData clientData,
int
_netcmp_permute(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
char *model, *pin1, *pin2;
char *permuteclass[] = {
@ -4114,7 +4039,7 @@ _netcmp_permute(ClientData clientData,
index = DEFLT_IDX;
}
else {
if (Tcl_GetIndexFromObj(interp, objv[1], (const char **)permuteclass,
if (Tcl_GetIndexFromObj(interp, objv[1], (CONST84 char **)permuteclass,
"permute class", 0, &index) != TCL_OK) {
if (objc != 4) {
Tcl_WrongNumArgs(interp, 1, objv, "?valid_cellname pin1 pin2?");
@ -4234,7 +4159,7 @@ _netcmp_permute(ClientData clientData,
int
_netcmp_symmetry(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
Printf("Symmetry breaking method has been deprecated.\n");
return TCL_OK;
@ -4250,7 +4175,7 @@ _netcmp_symmetry(ClientData clientData,
int
_netcmp_exhaustive(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
char *yesno[] = {
"on", "off", NULL
@ -4263,7 +4188,7 @@ _netcmp_exhaustive(ClientData clientData,
if (objc == 1)
index = -1;
else {
if (Tcl_GetIndexFromObj(interp, objv[1], (const char **)yesno,
if (Tcl_GetIndexFromObj(interp, objv[1], (CONST84 char **)yesno,
"option", 0, &index) != TCL_OK)
return TCL_ERROR;
}
@ -4292,7 +4217,7 @@ _netcmp_exhaustive(ClientData clientData,
int
_netcmp_restart(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
if (objc != 1) {
Tcl_WrongNumArgs(interp, 1, objv, "(no arguments)");
@ -4312,7 +4237,7 @@ _netcmp_restart(ClientData clientData,
int
_netgen_help(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
int n;
@ -4343,7 +4268,7 @@ _netgen_help(ClientData clientData,
int
_netcmp_matching(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
char *options[] = {
"nodes", "elements", NULL
@ -4365,7 +4290,7 @@ _netcmp_matching(ClientData clientData,
name = Tcl_GetString(objv[1]);
}
else {
if (Tcl_GetIndexFromObj(interp, objv[1], (const char **)options,
if (Tcl_GetIndexFromObj(interp, objv[1], (CONST84 char **)options,
"option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
@ -4494,14 +4419,14 @@ void tcl_vprintf(FILE *f, const char *fmt, va_list args_in)
void tcl_stdflush(FILE *f)
{
Tcl_InterpState state;
Tcl_SavedResult state;
static char stdstr[] = "::flush stdxxx";
char *stdptr = stdstr + 11;
state = Tcl_SaveInterpState(netgeninterp, TCL_OK);
Tcl_SaveResult(netgeninterp, &state);
strcpy(stdptr, (f == stderr) ? "err" : "out");
Tcl_Eval(netgeninterp, stdstr);
Tcl_RestoreInterpState(netgeninterp, state);
Tcl_RestoreResult(netgeninterp, &state);
}
/*------------------------------------------------------*/
@ -4531,7 +4456,7 @@ char *Tcl_Strdup(const char *s)
/*------------------------------------------------------*/
int _tkcon_interrupt(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
InterruptPending = 1;
return TCL_OK;
@ -4570,7 +4495,7 @@ int Tclnetgen_Init(Tcl_Interp *interp)
/* Remember the interpreter */
netgeninterp = interp;
if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL) return TCL_ERROR;
if (Tcl_InitStubs(interp, "8.5", 0) == NULL) return TCL_ERROR;
for (n = 0; netgen_cmds[n].name != NULL; n++) {
sprintf(keyword, "netgen::%s", netgen_cmds[n].name);
@ -4579,8 +4504,7 @@ int Tclnetgen_Init(Tcl_Interp *interp)
}
for (n = 0; netcmp_cmds[n].name != NULL; n++) {
sprintf(keyword, "netgen::%s", netcmp_cmds[n].name);
Tcl_CreateObjCommand(interp, keyword,
(Tcl_ObjCmdProc *)netcmp_cmds[n].handler,
Tcl_CreateObjCommand(interp, keyword, netcmp_cmds[n].handler,
(ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
}

View File

@ -44,8 +44,6 @@ exec ${NETGEN_WISH:=wish} "$0" ${1+"$@"}
if {$tcl_version < 8.0} {
return -code error "tkcon requires at least Tcl/Tk8"
} else {
# Prevent breaking on version 8.5.2
# package require -exact Tk $tcl_version
package require Tk $tcl_version
}
@ -61,6 +59,18 @@ foreach pkg [info loaded {}] {
}
catch {unset pkg file name version}
# Tk 8.4 makes previously exposed stuff private.
# FIX: Update tkcon to not rely on the private Tk code.
#
if {![llength [info globals tkPriv]]} {
::tk::unsupported::ExposePrivateVariable tkPriv
}
foreach cmd {SetCursor UpDownLine Transpose ScrollPages} {
if {![llength [info commands tkText$cmd]]} {
::tk::unsupported::ExposePrivateCommand tkText$cmd
}
}
# Initialize the ::tkcon namespace
#
namespace eval ::tkcon {
@ -186,7 +196,7 @@ proc ::tkcon::Init {} {
tkcon_puts tkcon_gets observe observe_var unalias which what
}
version 2.3
RCS {RCS: @(#) $Id: tkcon.tcl,v 1.2 2008/04/18 16:28:13 tim Exp $}
RCS {RCS: @(#) $Id: tkcon.tcl,v 1.2 2008/05/23 00:20:17 tim Exp $}
HEADURL {http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/tkcon/tkcon/tkcon.tcl?rev=HEAD}
docs "http://tkcon.sourceforge.net/"
email {jeff@hobbs.org}
@ -735,7 +745,7 @@ proc ::tkcon::EvalCmd {w cmd} {
$w tag bind $tag <Leave> \
[list $w tag configure $tag -underline 0]
$w tag bind $tag <ButtonRelease-1> \
"if {!\[info exists ::tk::Priv(mouseMoved)\] || !\$::tk::Priv(mouseMoved)} \
"if {!\[info exists tkPriv(mouseMoved)\] || !\$tkPriv(mouseMoved)} \
{[list edit -attach [Attach] -type error -- $PRIV(errorInfo)]}"
} else {
$w insert output $res\n stderr
@ -2464,7 +2474,7 @@ proc ::tkcon::ErrorHighlight w {
$w tag configure $tag -foreground $COLOR(stdout)
$w tag bind $tag <Enter> [list $w tag configure $tag -underline 1]
$w tag bind $tag <Leave> [list $w tag configure $tag -underline 0]
$w tag bind $tag <ButtonRelease-1> "if {!\$::tk::Priv(mouseMoved)} \
$w tag bind $tag <ButtonRelease-1> "if {!\$tkPriv(mouseMoved)} \
{[list edit -attach $app -type proc -find $what -- $cmd]}"
}
set info [string range $info $c1 end]
@ -2493,7 +2503,7 @@ proc ::tkcon::ErrorHighlight w {
$w tag configure $tag -foreground $COLOR(proc)
$w tag bind $tag <Enter> [list $w tag configure $tag -underline 1]
$w tag bind $tag <Leave> [list $w tag configure $tag -underline 0]
$w tag bind $tag <ButtonRelease-1> "if {!\$::tk::Priv(mouseMoved)} \
$w tag bind $tag <ButtonRelease-1> "if {!\$tkPriv(mouseMoved)} \
{[list edit -attach $app -type proc -- $cmd]}"
}
}
@ -2542,8 +2552,8 @@ proc tkcon {cmd args} {
## 'congets' a replacement for [gets stdin]
# Use the 'gets' alias of 'tkcon_gets' command instead of
# calling the *get* methods directly for best compatability
if {[llength $args] > 1} {
return -code error "wrong # args: must be \"tkcon congets [pfix]\""
if {[llength $args]} {
return -code error "wrong # args: must be \"tkcon congets\""
}
tkcon show
set old [bind TkConsole <<TkCon_Eval>>]
@ -2551,12 +2561,7 @@ proc tkcon {cmd args} {
set w $::tkcon::PRIV(console)
# Make sure to move the limit to get the right data
$w mark set insert end
if {[llength $args]} {
$w mark set limit insert
$w insert end $args
} else {
$w mark set limit insert
}
$w mark set limit insert
$w see end
vwait ::tkcon::PRIV(wait)
set line [::tkcon::CmdGet $w]
@ -2793,19 +2798,13 @@ proc tkcon_puts args {
foreach {arg1 arg2 arg3} $args { break }
if {$len == 1} {
set sarg $arg1
set nl 1
set farg stdout
tkcon console insert output "$arg1\n" stdout
} elseif {$len == 2} {
if {![string compare $arg1 -nonewline]} {
set sarg $arg2
set farg stdout
set nl 0
tkcon console insert output $arg2 stdout
} elseif {![string compare $arg1 stdout] \
|| ![string compare $arg1 stderr]} {
set sarg $arg2
set farg $arg1
set nl 1
tkcon console insert output "$arg2\n" $arg1
} else {
set len 0
}
@ -2813,15 +2812,11 @@ proc tkcon_puts args {
if {![string compare $arg1 -nonewline] \
&& (![string compare $arg2 stdout] \
|| ![string compare $arg2 stderr])} {
set sarg $arg3
set farg $arg2
set nl 0
tkcon console insert output $arg3 $arg2
} elseif {(![string compare $arg1 stdout] \
|| ![string compare $arg1 stderr]) \
&& ![string compare $arg3 nonewline]} {
set sarg $arg2
set farg $arg1
set nl 0
tkcon console insert output $arg2 $arg1
} else {
set len 0
}
@ -2831,42 +2826,7 @@ proc tkcon_puts args {
## $len == 0 means it wasn't handled by tkcon above.
##
if {$len != 0} {
## "poor man's" \r substitution---erase everything on the output
## line and print from character after the \r
set rpt [string last \r $sarg]
if {$rpt >= 0} {
tkcon console delete "insert linestart" "insert lineend"
set sarg [string range $sarg [expr {$rpt + 1}] end]
}
set bpt [string first \b $sarg]
if {$bpt >= 0} {
set narg [string range $sarg [expr {$bpt + 1}] end]
set sarg [string range $sarg 0 [expr {$bpt - 1}]]
set nl 0
}
if {$nl == 0} {
tkcon console insert output $sarg $farg
} else {
tkcon console insert output "$sarg\n" $farg
}
if {$bpt >= 0} {
tkcon console delete "insert -1 char" insert
if {$nl == 0} {
tkcon_puts $farg $narg nonewline
} else {
tkcon_puts $farg $narg
}
}
} else {
if {$len == 0} {
global errorCode errorInfo
if {[catch "tkcon_tcl_puts $args" msg]} {
regsub tkcon_tcl_puts $msg puts msg
@ -4146,7 +4106,7 @@ proc ::tkcon::Bindings {} {
global tcl_platform tk_version
#-----------------------------------------------------------------------
# Elements of ::tk::Priv that are used in this file:
# Elements of tkPriv that are used in this file:
#
# char - Character position on the line; kept in order
# to allow moving up or down past short lines while
@ -4174,9 +4134,6 @@ proc ::tkcon::Bindings {} {
foreach ev [bind Text] { bind TkConsole $ev [bind Text $ev] }
## We really didn't want the newline insertion
bind TkConsole <Control-Key-o> {}
## in 8.6b3, the virtual events <<NextLine>> and <<PrevLine>>
# mess up our history feature
bind TkConsole <<NextLine>> {}
bind TkConsole <<PrevLine>> {}
@ -4385,9 +4342,9 @@ proc ::tkcon::Bindings {} {
bind TkConsole <Control-a> {
if {[%W compare {limit linestart} == {insert linestart}]} {
::tk::TextSetCursor %W limit
tkTextSetCursor %W limit
} else {
::tk::TextSetCursor %W {insert linestart}
tkTextSetCursor %W {insert linestart}
}
}
bind TkConsole <Key-Home> [bind TkConsole <Control-a>]
@ -4411,14 +4368,14 @@ proc ::tkcon::Bindings {} {
}
bind TkConsole <<TkCon_Previous>> {
if {[%W compare {insert linestart} != {limit linestart}]} {
::tk::TextSetCursor %W [::tk::TextUpDownLine %W -1]
tkTextSetCursor %W [tkTextUpDownLine %W -1]
} else {
::tkcon::Event -1
}
}
bind TkConsole <<TkCon_Next>> {
if {[%W compare {insert linestart} != {end-1c linestart}]} {
::tk::TextSetCursor %W [::tk::TextUpDownLine %W 1]
tkTextSetCursor %W [tkTextUpDownLine %W 1]
} else {
::tkcon::Event 1
}
@ -4433,7 +4390,7 @@ proc ::tkcon::Bindings {} {
}
bind TkConsole <<TkCon_Transpose>> {
## Transpose current and previous chars
if {[%W compare insert > "limit+1c"]} { ::tk::TextTranspose %W }
if {[%W compare insert > "limit+1c"]} { tkTextTranspose %W }
}
bind TkConsole <<TkCon_ClearLine>> {
## Clear command line (Unix shell staple)
@ -4451,10 +4408,10 @@ proc ::tkcon::Bindings {} {
::tkcon::Insert %W $::tkcon::PRIV(tmp)
%W see end
}
catch {bind TkConsole <Key-Page_Up> { ::tk::TextScrollPages %W -1 }}
catch {bind TkConsole <Key-Prior> { ::tk::TextScrollPages %W -1 }}
catch {bind TkConsole <Key-Page_Down> { ::tk::TextScrollPages %W 1 }}
catch {bind TkConsole <Key-Next> { ::tk::TextScrollPages %W 1 }}
catch {bind TkConsole <Key-Page_Up> { tkTextScrollPages %W -1 }}
catch {bind TkConsole <Key-Prior> { tkTextScrollPages %W -1 }}
catch {bind TkConsole <Key-Page_Down> { tkTextScrollPages %W 1 }}
catch {bind TkConsole <Key-Next> { tkTextScrollPages %W 1 }}
bind TkConsole <$PRIV(meta)-d> {
if {[%W compare insert >= limit]} {
%W delete insert {insert wordend}
@ -4472,7 +4429,7 @@ proc ::tkcon::Bindings {} {
}
bind TkConsole <ButtonRelease-2> {
if {
(!$::tk::Priv(mouseMoved) || $tk_strictMotif) &&
(!$tkPriv(mouseMoved) || $tk_strictMotif) &&
![catch {::tkcon::GetSelection %W} ::tkcon::PRIV(tmp)]
} {
if {[%W compare @%x,%y < limit]} {