/*
* $Id: rename.c,v 1.2 2003/11/06 04:36:03 mjames Exp $
*
* $Log: rename.c,v $
* Revision 1.2 2003/11/06 04:36:03 mjames
* Checkin : builds but has problems with object renaming
*
* Revision 1.1.1.1 2003/11/04 23:34:57 mjames
* Imported into local repositrory
*
* Revision 1.24 2003/01/02 21:37:17 mjames
* Experiment on creating NOT_ROUTABLE_H and NOT_ROUTABLE_L
* properties on the nets so that pin jumpers can be made without a problem.
*
* Still need to sort out pin assignments made to these not_routable nets
* which will become legal in some cases so that pullups and pulldown
* pins can be used on the FPGA.
*
* Revision 1.23 2002/10/02 18:41:24 MJAMES
* Dont print '&a' if the pin_column is expression is less than or equal to zero
*
* Revision 1.22 2002/09/18 08:50:10 mjames
* Removed further sidefects of redefining pin 'a' as 1 in place of '0'
*
* Revision 1.21 2002/09/16 14:41:43 mjames
* Merge back pin indexing bug that meant
* pin AZ12 was indistinguishable from pin Z12 in
* rename ident/name commands
*
* Revision 1.19 2002/08/23 14:17:29 mjames
* Regular expressions extended to
* &a, &n &d , &i as special replacement patterns
*
* Revision 1.18 2002/01/21 09:33:30 mjames
* Appended a null character when copying regular expression
* matched pattern.
*
* Revision 1.17 2001/12/24 20:07:18 mjames
* Added &D for device identifier in the replacement string in edit_pin as well
* as &0 .. &9
*
* Revision 1.16 2001/12/11 20:30:26 mjames
* Implemented regular expression pin name editing
*
* Revision 1.15 2001/11/19 10:21:04 mjames
* Fixed errors
*
* Revision 1.14 2001/11/19 10:02:23 mjames
* Merge back
*
* Revision 1.13.2.1 2001/11/15 22:03:52 mjames
* Altered the 'alter' command to use two arguments rather than one
* after TH suggestion.
*
* Revision 1.13 2001/10/31 22:28:27 mjames
* Problems with regular expression argument lists.
*
* Revision 1.12 2001/10/31 22:20:14 mjames
* Tidying up problematical comments caused by CVS
* 'intelligent' comment guessing
*
* Revision 1.11 2001/10/31 16:18:05 mjames
* Added a datastructure to hide regular expression information from programs.
* Changed call to regexec to indicate 0 subexpressions to be matched
* rather than a number dependent on strlen(string) which was wrong.
*
* Revision 1.10 2001/10/18 21:36:17 mjames
* Added modify pins command : nets inherit identifier from selected socket and pin on that socket to ease cross referencing.
*
* Revision 1.9 2001/10/11 16:10:16 mjames
* Corrections to the SWAP command, and printout so that
* WRITE net now outputs all chips in the design so that their generics
* can be passed forward to the next phase.
*
* Revision 1.8 2001/10/10 20:18:21 mjames
* Added a vert_regcomp function to compile regular expressions
* with '^' (match start string) and '$' (match end string) bracketing
* this => wildcard must match entire string not just a part of it.
*
* Revision 1.7 2001/10/07 20:50:52 mjames
* Added wildcard checking (warn user about
* using wildcard '*' on the end of a string in stead of wildcard '.*')
*
* Revision 1.6 2001/09/25 23:15:23 mjames
* Converted wildcards to use proper regexp pattern match library
*
* Revision 1.5 2001/08/31 09:37:42 mjames
* modified rename rules so that un-named objects do not get
* name suffixes appended.
*
* Revision 1.4 2001/07/20 14:49:42 mjames
* Corrected reading names in on multiple boards : if present in a database file
* when reading in a suffixed design
* e.g. CHIP fred
* Will also get its name suffixed.
*
* Revision 1.3 2001/06/06 12:10:18 mjames
* Move from HPUX
*
* Revision 1.2 2001/01/26 21:50:10 mjames
* Managed to get vertical non TCL to compile again
*
* Conversion to argv, argc[] mode of operation continues
*
* Revision 1.1.1.1 2000/10/19 21:58:39 mjames
* Mike put it here
*
*
* Revision 1.26 2000/08/25 09:57:15 09:57:15 mjames (Mike James)
* Modified for Vertical2 : support COMPONENTS and SIGNALS
*
* Revision 1.26 2000/08/25 09:57:15 09:57:15 mjames (Mike James)
* Part of Release Aug25_alpha
*
* Revision 1.25 2000/08/16 08:57:31 08:57:31 mjames (Mike James)
* Part of Release CD01_Aug2000
*
* Revision 1.24 2000/08/14 14:45:12 14:45:12 mjames (Mike James)
* Part of Release Aug_14_2000
*
* Revision 1.23 2000/08/11 08:30:33 08:30:33 mjames (Mike James)
* Part of Release Aug_11_2000
*
* Revision 1.22 2000/08/09 10:31:48 10:31:48 mjames (Mike James)
* Part of Release Aug__9_2000
*
* Revision 1.21 2000/05/31 11:42:58 11:42:58 mjames (Mike James)
* Part of Release May_31_2000
*
* Revision 1.20 2000/05/08 17:01:38 17:01:38 mjames (Mike James)
* Part of Release May__8_2000
*
* Revision 1.19 2000/05/08 16:59:31 16:59:31 mjames (Mike James)
* Part of Release May__8_2000
*
* Revision 1.18 2000/05/08 16:57:08 16:57:08 mjames (Mike James)
* Part of Release May__8_2000
*
* Revision 1.17 2000/03/08 16:19:26 16:19:26 mjames (Mike James)
* New version including PC
*
* Revision 1.14 2000/01/20 15:58:48 15:58:48 mjames (Mike James)
* Part of Release R22
*
* Revision 1.13 99/12/22 11:15:29 11:15:29 mjames (Mike James)
* Part of Release Dec_22_1999
*
* Revision 1.12 99/06/25 14:35:49 14:35:49 mjames (Mike James)
* Added in reference to expression.h, but no changes made
* to the function of acfread yet.
*
* Revision 1.11 99/05/04 09:52:43 09:52:43 mjames (Mike James)
* General checkin
*
* Revision 1.10 98/08/12 14:22:18 14:22:18 mjames (Mike James)
* Corrected include file list
*
* Revision 1.9 98/04/24 14:07:51 14:07:51 mjames (Mike James)
* Added pin name swapping code
*
* Revision 1.8 98/03/16 11:38:24 11:38:24 mjames (Mike James)
* Removed an old bug - suffixing of PCB names has been broken for about
* a year. If a pcb were read in non-suffixed and then another with a suffix,
* the suffix would be applied over all of the sockets and nets, not just the new ones.
*
* Revision 1.7 98/02/11 11:27:06 11:27:06 mjames (Mike James)
* Checked in for version 6.2a
*
* Revision 1.6 97/04/23 08:43:22 08:43:22 mjames (Mike James)
* CHecked in for release rel23041997
*
* Revision 1.5 96/07/19 14:38:51 14:38:51 mjames (Mike James)
* Update to give to PRL
*
* Revision 1.4 1996/07/12 15:52:12 mjames
* Sorted out things like Alias and Jumpers
* Work Correctly
* Print COrrectly
*
* Revision 1.4 1996/07/12 15:52:12 mjames
* Sorted out things like Alias and Jumpers
* Work Correctly
* Print COrrectly
*
* Revision 1.3 96/06/04 11:53:28 11:53:28 mjames (Mike James)
* Corrected the operation of the renaming function
*
* Revision 1.2 96/05/29 11:00:10 11:00:10 mjames (Mike James)
* Added explanatory comments
*
* Revision 1.1 96/05/29 10:53:13 10:53:13 mjames (Mike James)
* Initial revision
* */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/types.h>
#include <regex.h>
#include "vertcl_main.h"
#include "expression.h"
#include "generic.h"
#include "database.h"
#include "rename.h"
#include "cmdparse.h"
#include "cmdlog.h"
#include "lx_support.h"
#include "chck_names.h"
#include "sorting.h"
#ident "@(#)$Header: c:\\cygwin\\cvsroot/Vert03/vertlib/rename.c,v 1.2 2003/11/06 04:36:03 mjames Exp $"
/* added on to suffix all signal names */
/* all new objects will appear after the 'mark'. Only
these new objects need to be renamed by adding a suffix.
Older objects have already been renamed. */
static net_t * mark_nets = NULL;
static socket_t * mark_skts = NULL;
/* record the last known net and socket before
reading in new nets and sockets */
void mark_board_objects(void) {
net_t * net = routed_list;
socket_t * skt = socket_head;
while(net && net->next ) {
net = net->next;
}
mark_nets = net;
while(skt && skt->next ) {
skt = skt->next;
}
mark_skts = skt;
/*
printf("Mark at net=%p and skt=%p\n",mark_nets,mark_skts);
*/
}
/* only name nets that are not null names */
static char * alter_id(char * id,char * suffix)
{
if(!ISNULLSTR(id) && !ISNULLSTR(suffix))
{
return(id);
}
return NULL;
}
/* suffixes all net and component identifiers
since the last 'mark_board_objects' call with the string s */
void set_board_suffix(char * s)
{
net_t * net = mark_nets;
socket_t * skt = mark_skts;
/*
printf("Mark at net=%p and skt=%p\n",mark_nets,mark_skts);
*/
/* flag the nets and sockets as having been renamed */
mark_nets = NULL;
mark_skts = NULL;
if(net)
net=net->next; /* move to next one (new one) */
else
net=routed_list;
if(skt)
skt=skt->next; /* ditto */
else
skt=socket_head;
/* rename all of the net identifiers */
while(net) {
struct net * sub_n = net->subnets;
/* jumpered nets have their subnets renamed */
if(sub_n && net->how_joined == Jumpered)
while (sub_n) {
sub_n->identifier = alter_id(sub_n->identifier,s);
sub_n = sub_n -> subnets;
}
else
net->identifier = alter_id(net->identifier,s);
net = net->next;
}
/* rename all of the socket identifiers */
while(skt) {
skt->identifier = alter_id(skt->identifier,s);
if(skt->name) /* mod MDJ July 2001 */
skt->name = alter_id(skt->name,s);
skt = skt->next;
}
}
/*********************************************************************/
/* Pin_swapping : reverse A23 to 23a */
/* allow up to lead_chars before digits to permit pin swap */
/* lead_chars = 2 -> aa23 maps to 23aa but pin23 remains unswapped */
/*********************************************************************/
/* modified from the original, now allows swapping 1a to a1 if
* AlphaSwap_t == Want_A1
* or allows swapping a1 to 1a if
* AlphaSwap_t == Want_1A
* probably better using the renaming command below.
*/
void pin_id_swap(char * template,
int lead_chars,
AlphaSwap_t lead_alpha) {
enum {First_Char,
Leading_Chars,
Trailing_Digits,
Leading_Digits,
Trailing_Chars,
No_Swap } SwapState;
int rc;
socket_t * chip;
node_t * nodes;
/* compile regular expression */
vert_regex_t * preg;
if(ISNULLSTR(template)) {
template = ".*";
}
rc = vert_regcomp(&preg,template);
if (rc != 0 )
{
char errbuff[100];
regerror(rc,preg->preg,errbuff,100);
Log(LOG_ERROR,"-- Problem (rc=%d) %s with '%s' as regular expression\n",rc,errbuff,template);
/* return TCL_ERROR;
*/
return;
}
else
{
Log(LOG_GENERAL,"-- Using '%s' as match pattern\n",template);
}
if (lead_alpha == Want_A1) {
Log(LOG_GENERAL,"-- Swapping pin identifiers with up to %d leading letters\n",
lead_chars);
}
else {
Log(LOG_GENERAL,"-- Swapping pin identifiers with up to %d trailing letters\n",
lead_chars);
}
Log(LOG_GENERAL,"-- for sockets matching template '%s' --\n",
template?template:"[ALL Sockets]");
chip = socket_head;
while(chip) {
int found;
found = regexec(preg->preg,chip->identifier,0,preg->regpatt,0);
if(!found) {
Log(LOG_GENERAL,"-- Processing socket '%s' --\n",chip->identifier);
nodes = chip -> nodes ;
while(nodes) {
int lead_count = 0;
int done = 0;
char new_id [MAXIDLEN];
char * pos = nodes->identifier;
SwapState = First_Char;
while(pos && *pos && !done) {
/*
printf("%s (%c) State %d\n",nodes->identifier,*pos,SwapState);
*/
switch(SwapState) {
case First_Char:
if(lead_alpha
== Want_A1
&&isdigit(*pos
) && lead_chars
> 0) {
SwapState = Leading_Digits;
lead_count = 1;
break;
}
if(lead_alpha
== Want_1A
&&isalpha(*pos
) && lead_chars
> 0) {
SwapState = Leading_Chars;
lead_count = 1;
break;
}
/* no action needed, so continue */
SwapState = No_Swap;
done = 1;
break;
case Leading_Chars:
if(lead_count <= lead_chars) { /* encountered a digit after a character success so far */
SwapState = Trailing_Digits;
break;
}
else{
SwapState = No_Swap;
done = 1;
break;
}
}
lead_count++;
break;
}
SwapState = No_Swap;
done = 1;
break;
case Leading_Digits:
if(lead_count <= lead_chars) { /* encountered a character after a number success so far */
SwapState = Trailing_Chars;
break;
}
else{
SwapState = No_Swap;
done = 1;
break;
}
}
if(isdigit ( *pos
)) { /* continue ok */
lead_count++;
break;
}
SwapState = No_Swap;
done = 1;
break;
case Trailing_Digits:
SwapState = No_Swap;
done = 1;
}
break;
case Trailing_Chars:
SwapState = No_Swap;
done = 1;
}
break;
default: break;
}
pos++;
}
/* on arrival here in either state we can swap the two parts of the ident */
if (SwapState == Trailing_Digits || SwapState == Trailing_Chars) {
int i,l;
strcpy (new_id
,(nodes
->identifier
)+lead_count
);
strncat (new_id
,nodes
->identifier
,lead_count
);
for(i=0;i<l;i++)
Log(LOG_GENERAL,"# Renaming %s(%s) to %s(%s)\n",
chip->identifier, nodes->identifier,
chip->identifier, new_id);
strcpy (nodes
->identifier
,new_id
);
}
nodes = nodes->sktnext;
}
}
chip = chip->next;
}
vert_regfree(&preg);
}
/***************************************************************************************/
/* Name nets after node name on device instead of pcb CAD name */
/* Initially lookup all matching sockets */
void alter_net_to_socket_name(char * chip_id_template,char * prefix_opt)
{
node_t * chip_node ;
int found,rc,count = 0;
socket_t * socket;
vert_regex_t * preg;
socket = socket_head;
/* create_unrouted_list(); */
/* compile regular expression */
if(!chip_id_template) {
chip_id_template = ".*";
}
rc = vert_regcomp(&preg,chip_id_template);
if (rc != 0 )
{
char errbuff[100];
regerror(rc,preg->preg,errbuff,100);
Log(LOG_ERROR,"-- Problem (rc=%d) %s with '%s' as regular expression\n",rc,errbuff,chip_id_template);
/* return TCL_ERROR;
*/
return;
}
else
{
Log(LOG_GENERAL,"-- Using '%s' as match pattern\n",chip_id_template);
}
while(socket )
{
found = regexec(preg->preg,socket->identifier,0,preg->regpatt,0);
if(!found) {
/*
Log(LOG_GENERAL,"found %s\n",skt->identifier);
*/
count++;
chip_node = socket-> nodes;
while (chip_node)
{
char name_buff[MAXIDLEN];
int count;
net_t * net = chip_node->net;
if(net && IS_ROUTABLE(net->how_routed))
{
if (prefix_opt) /* TH requests this change. Not a problem */
{
count
= sprintf(name_buff
,"%s%s",prefix_opt
,chip_node
->identifier
);
}
else
{
count
= sprintf(name_buff
,"%s_%s",socket
->identifier
,chip_node
->identifier
);
}
net
->identifier
= realloc(net
->identifier
,count
+1);
strcpy(net
->identifier
,name_buff
);
/* printf("-- id = %s\n",name_buff); */
}
chip_node = chip_node -> sktnext;
}
}
socket = socket->next;
}
Log(LOG_GENERAL,"-- processed %d sockets\n",count);
vert_regfree(&preg);
}
static char pin_map_chars[] = PIN_MAP_LEGAL_CHARS;
static int row_index,col_index; /* Made static so I can check them later .*/
/***************************************************************************************/
/* Name nets after node name on device instead of pcb CAD name */
/* Initially lookup all matching sockets */
/* change device template pin identifiers */
void edit_socket_pin_name(char * chip_id_template,char * pin_patt, char * pin_repl, property_t search_space)
{
node_t * chip_node ;
int found,rc,count = 0;
int subexpressions;
socket_t * socket;
vert_regex_t * preg;
vert_regex_t * ppin_reg;
int loop;
if (ISNULLSTR(pin_patt))
{
return;
}
socket = template_head;
/* create_unrouted_list(); */
/* compile regular expression for chip type */
if(!chip_id_template) {
chip_id_template = ".*";
}
rc = vert_regcomp(&preg,chip_id_template);
if (rc != 0 )
{
char errbuff[100];
regerror(rc,preg->preg,errbuff,100);
Log(LOG_ERROR,"-- Problem (rc=%d) %s with '%s' as regular expression\n",rc,errbuff,chip_id_template);
/* return TCL_ERROR;
*/
return;
}
else
{
Log(LOG_GENERAL,"-- Using '%s' as match pattern for chip %s\n",chip_id_template,search_space==Type?"type":"ident");
}
/* now compile pin regexp match pattern */
rc = vert_regcomp(&ppin_reg,pin_patt);
if (rc != 0 )
{
char errbuff[100];
regerror(rc,ppin_reg->preg,errbuff,100);
Log(LOG_ERROR,"-- Problem (rc=%d) %s with '%s' as regular expression\n",rc,errbuff,pin_patt);
/* return TCL_ERROR;
*/
return;
}
else
{
subexpressions = ppin_reg->preg->re_nsub+1; /* count up subexpressions */
Log(LOG_GENERAL,"-- Using '%s' as chip pin ID matching pattern (%d subexpressions)\n",pin_patt,subexpressions);
}
if (subexpressions > MAX_REGEXP_SUBEXPR)
{
Log(LOG_ERROR,"-- Too many (>%d) subexpressions\n",MAX_REGEXP_SUBEXPR);
return;
}
/* decode the command type */
switch (search_space)
{
case Ident: loop = 1; break;
case Type : loop = 2; break;
default : loop = 0; break;
}
/* loop 2,1, 0 or 1,0 dependent on whether search is type or ident based */
while(loop)
{
switch (loop)
{
case 1: socket = socket_head; break;
case 2: socket = template_head; break;
default : break;
}
loop--;
while(socket )
{
if(search_space == Type)
{
found = regexec(preg->preg,socket->type,0,preg->regpatt,0);
}
else
{
found = regexec(preg->preg,socket->identifier,0,preg->regpatt,0);
}
if(!found) {
/*
Log(LOG_GENERAL,"found %s\n",skt->identifier);
*/
int rows,columns;
/* int row_index,col_index; Made static so I can check them later .*/
generic_info_t info,* row_expr, * col_expr;
/* Setup the row and column variables for this device */
/* these are input names that can be used in an expression */
info.g_type = IS_ATTRIBUTE;
info.g_class= DEFINED;
/* info is copied, simply change the variable parts and call the compile
and set functions */
info.name = "pin_row";
info.expr = compile_variable_reference(&row_index,"pin_row");
set_generic_value(&socket->generics, &info);
info.name = "pin_col";
info.expr = compile_variable_reference(&row_index,"pin_col");
set_generic_value(&socket->generics, &info);
/* this expression will be evaluated when &n is seen in the
input file */
row_expr = get_generic_ref(&socket->generics,"row_expr");
/*
if(row_expr && row_expr->expr)
{
printf("row = ");
print_expression(stdout,row_expr->expr,NO_RECURSE);
printf("\n");
}
*/
/* this expression will be evaluated when &a is seen in the
input file */
col_expr = get_generic_ref(&socket->generics,"col_expr");
/*
if(col_expr && col_expr->expr)
{
printf("col = ");
print_expression(stdout,col_expr->expr,NO_RECURSE);
printf("\n");
}
*/
count++;
sort_nodes(socket,EXTRACT_XY); /* sort pins , determine pin row and column*/
rows = socket->max_pin_row - socket->min_pin_row+1;
columns = socket->max_pin_col - socket->min_pin_col+1;
chip_node = socket-> nodes;
while (chip_node)
{
char * str;
str = chip_node->identifier;
/* allow one bracketed subexpression in pin names */
found = regexec(ppin_reg->preg,str,subexpressions,ppin_reg->regpatt,0);
if(!found)
{
char name_buff[MAXIDLEN];
int count,fail;
int editp,copyp;
name_buff[0] = 0;
/* get length of replacement string */
editp = 0;
count = 0;
fail = 0;
/* printf("Processing '%s'\n",pin_repl); */
while(pin_repl[editp] && !fail)
{
/* escape anything */
if(pin_repl[editp] == '\\')
{
editp++;
name_buff[count++]= pin_repl[editp];
if(pin_repl[editp])
{
editp++;
}
}
/* replace matched patterns */
else if(pin_repl[editp] == '&')
{
int index,len;
char c;
char temp[30];
int digits;
/* change values to those seen on this pin */
col_index = chip_node -> pin_col;
row_index = chip_node -> pin_row;
editp++;
c = pin_repl[editp];
if(c)
{
/* printf("c='%c' row = %d col =%d\n",c,chip_node->pin_row ,chip_node->pin_col); */
editp++;
switch(c)
{
case 'c':
case 'C':
if (chip_node->net && chip_node->net->name)
{
len
= strlen(chip_node
->net
->name
);
strncpy(name_buff
+count
,chip_node
->net
->name
,len
);
count += len;
}
else
{
fail = 1;
}
break;
/* &d or &D is the device identifier */
case 'd':
case 'D':
len
= strlen(socket
->identifier
);
strncpy(name_buff
+count
,socket
->identifier
,len
);
count += len;
break;
/* &p or &P is the pin identifier */
case 'p':
case 'P':
len
= strlen(chip_node
->identifier
);
strncpy(name_buff
+count
,chip_node
->identifier
,len
);
count += len;
break;
/* &a is the alpha component of the identifier */
case 'a':
case 'A':
/* always synthesise pin column from the info left by sort_nodes */
if(col_expr && col_expr->expr)
{
index = eval_expression(col_expr->expr,&socket->generics);
}
else
{
index = chip_node -> pin_col;
}
/* printf("Alpha %d : ",index); */
digits = 0;
/* always at least a single char */
if(index>0) /* index = 0 means no chars at all ! */
{
do
{
if(c=='a') /* lower case idents if lower case 'a' is used */
{
temp
[digits
++] = tolower(pin_map_chars
[index
% (PIN_MAP_LEGAL_CHAR_COUNT
+1)-1]);
}
else
{
temp[digits++] = pin_map_chars[index % (PIN_MAP_LEGAL_CHAR_COUNT+1)-1];
}
index /= (PIN_MAP_LEGAL_CHAR_COUNT+1);
}
while(index);
temp[digits]= 0;
/* printf("conversion '%s'\n",temp); */
/* reverse copy string, at least one char */
for(;digits>0;name_buff[count++]=temp[--digits]);
}
else
{
/* error in the expansion as the index < 0 */
/* Leave it blank as there is a danger elsewhere
name_buff[count++] = '&';
name_buff[count++] = c;
*/
}
break;
/* &n is the alpha component of the identifier */
case 'n':
case 'N':
if(row_expr && row_expr->expr)
{
index = eval_expression(row_expr->expr,&socket->generics);
}
else
{
index = chip_node -> pin_row;
}
/* printf("Numeric %d\n",index); */
if(index>0) /* index = 0 means no chars at all ! */
{
/* printf("result: '%s' %d\n",name_buff,strlen(name_buff)); */
count += len;
}
else
{
/* error in the expansion as the index < 0 */
name_buff[count++] = '&';
name_buff[count++] = c;
}
break;
case 'i':
case 'I':
sprintf(temp
,"%d",chip_node
->pin_row
- socket
->min_pin_row
+
(chip_node->pin_col - socket->min_pin_col) * rows +1);
count += len;
break;
/* &0 to &9 or whatever is the regular expression bracketed
section */
default:
index = c -'0';
if(index <0 || index > subexpressions)
{
fail = 1;
}
else
{
/* copy subexpression over */
copyp = ppin_reg->regpatt[index].rm_so;
if (copyp >=0 )
{
while(copyp < ppin_reg->regpatt[index].rm_eo)
{
name_buff[count++] = str[copyp++];
}
}
else
{
name_buff[count++] = '@';
}
}
}
}
}
else
{
name_buff[count++]=pin_repl[editp++];
}
}
if(!fail)
{
name_buff[count] = 0;
/*
printf("replacing '%s' with '%s'\n",chip_node->identifier,name_buff);
*/
chip_node
->identifier
= realloc(chip_node
->identifier
,count
+1);
strcpy(chip_node
->identifier
,name_buff
);
}
}
chip_node=chip_node->sktnext;
}
}
sort_nodes(socket,NO_EXTRACT_XY);
socket = socket->next;
}
}
Log(LOG_GENERAL,"-- processed %d sockets\n",count);
vert_regfree(&preg);
vert_regfree(&ppin_reg);
}
/***************************************************************************************/
/* allows for net renaming : currently in the routed list only */
void edit_net_names(char * pin_patt, char * pin_repl,property_t search_space)
{
net_t * curr_net ;
int found,rc = 0;
int subexpressions;
int net_count;
vert_regex_t * ppin_reg;
int loop;
net_count = 0;
if (ISNULLSTR(pin_patt))
{
return;
}
curr_net = routed_list;
/* now compile pin regexp match pattern */
rc = vert_regcomp(&ppin_reg,pin_patt);
if (rc != 0 )
{
char errbuff[100];
regerror(rc,ppin_reg->preg,errbuff,100);
Log(LOG_ERROR,"-- Problem (rc=%d) %s with '%s' as regular expression\n",rc,errbuff,pin_patt);
/* return TCL_ERROR;
*/
return;
}
else
{
subexpressions = ppin_reg->preg->re_nsub+1; /* count up subexpressions */
Log(LOG_GENERAL,"-- Using '%s' as net matching pattern (%d subexpressions)\n",pin_patt,subexpressions);
}
if (subexpressions > MAX_REGEXP_SUBEXPR)
{
Log(LOG_ERROR,"-- Too many (>%d) subexpressions\n",MAX_REGEXP_SUBEXPR);
return;
}
/* decode the command type */
/*
switch (search_space)
{
case Ident: loop = 1; break;
case Type : loop = 2; break;
default : loop = 0; break;
}
*/
loop = 3;
/* loop 2,1, 0 or 1,0 dependent on whether search is type or ident based */
while(loop)
{
char * str;
switch (loop)
{
case 1: curr_net = routed_list; break;
case 2: curr_net = unrouted_list; break;
case 3: curr_net = named_list; break;
default : curr_net = NULL; break;
}
loop--;
while(curr_net )
{
found = 1;
str = "nothing";
if(search_space == Name && !ISNULLSTR(curr_net->name))
{
found = regexec(ppin_reg->preg,curr_net->name,0,ppin_reg->regpatt,0);
str = curr_net -> name;
}
if(search_space == Ident && !ISNULLSTR(curr_net->identifier))
{
found = regexec(ppin_reg->preg,curr_net->identifier,0,ppin_reg->regpatt,0);
str = curr_net -> identifier;
}
/* printf("Checking '%s'\n",str); */
/* found will not be set if neither Name or Ident is used */
if(!found)
{
char name_buff[MAXIDLEN];
int fail,count;
int editp,copyp;
name_buff[0] = 0;
/* get length of replacement string */
editp = 0;
fail = 0;
count = 0;
net_count ++;
printf("Processing '%s'\n",str
);
while(pin_repl[editp] && !fail)
{
/* escape anything */
if(pin_repl[editp] == '\\')
{
editp++;
name_buff[count++]= pin_repl[editp];
if(pin_repl[editp])
{
editp++;
}
}
/* replace matched patterns */
else if(pin_repl[editp] == '&')
{
int index,len;
char c;
editp++;
c = pin_repl[editp];
if(c)
{
editp++;
switch(c)
{
/* replace with name part of net */
case 'n':
case 'N':
if (!ISNULLSTR(curr_net->name))
{
strncpy(name_buff
+count
,curr_net
->name
,len
);
count += len;
}
else
{
fail = 1;
}
break;
case 'i':
case 'I':
if (!ISNULLSTR(curr_net->identifier))
{
len
= strlen(curr_net
->identifier
);
strncpy(name_buff
+count
,curr_net
->identifier
,len
);
count += len;
}
else
{
fail = 1;
}
break;
/* &0 to &9 or whatever is the regular expression bracketed
section */
default:
index = c -'0';
if(index <0 || index > subexpressions)
{
fail = 1;
}
else
{
/* copy subexpression over */
copyp = ppin_reg->regpatt[index].rm_so;
if (copyp >=0 )
{
while(copyp < ppin_reg->regpatt[index].rm_eo)
{
name_buff[count++] = str[copyp++];
}
}
else
{
name_buff[count++] = '@';
}
}
} /* cae */
}
}
else
{
name_buff[count++]=pin_repl[editp++];
}
}
if(!fail)
{
name_buff[count] = 0;
/*
printf("replacing '%s' with '%s'\n",chip_node->identifier,name_buff);
*/ if(search_space == Ident)
{
curr_net
->identifier
= realloc(curr_net
->identifier
,count
+1);
printf("replacing '%s' with '%s'\n",curr_net
->identifier
,name_buff
);
strcpy(curr_net
->identifier
,name_buff
);
}
if(search_space == Name)
{
curr_net
->name
= realloc(curr_net
->name
,count
+1);
printf("replacing '%s' with '%s'\n",curr_net
->name
,name_buff
);
strcpy(curr_net
->name
,name_buff
);
}
}
}
curr_net=curr_net->next;
}
}
Log(LOG_GENERAL,"-- processed %d nets\n",net_count);
vert_regfree(&ppin_reg);
}