Subversion Repositories Vertical

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  *  $Id: rename.c,v 1.2 2003/11/06 04:36:03 mjames Exp $
  3.  *
  4.  * $Log: rename.c,v $
  5.  * Revision 1.2  2003/11/06 04:36:03  mjames
  6.  * Checkin : builds but has problems with object renaming
  7.  *
  8.  * Revision 1.1.1.1  2003/11/04 23:34:57  mjames
  9.  * Imported into local repositrory
  10.  *
  11.  * Revision 1.24  2003/01/02 21:37:17  mjames
  12.  * Experiment on creating NOT_ROUTABLE_H and NOT_ROUTABLE_L
  13.  * properties on the nets so that pin jumpers can be made without a problem.
  14.  *
  15.  * Still need to sort out pin assignments made to these not_routable nets
  16.  * which will become legal in some cases so that pullups and pulldown
  17.  * pins can be used on the FPGA.
  18.  *
  19.  * Revision 1.23  2002/10/02 18:41:24  MJAMES
  20.  * Dont print '&a' if the pin_column is expression is less than or equal to zero
  21.  *
  22.  * Revision 1.22  2002/09/18 08:50:10  mjames
  23.  * Removed further sidefects of redefining pin 'a' as 1 in place of '0'
  24.  *
  25.  * Revision 1.21  2002/09/16 14:41:43  mjames
  26.  * Merge back pin indexing bug that meant
  27.  * pin AZ12 was indistinguishable from pin Z12 in
  28.  * rename ident/name commands
  29.  *
  30.  * Revision 1.19  2002/08/23 14:17:29  mjames
  31.  * Regular expressions extended to
  32.  * &a, &n &d , &i as special replacement patterns
  33.  *
  34.  * Revision 1.18  2002/01/21 09:33:30  mjames
  35.  * Appended a null character when copying regular expression
  36.  * matched pattern.
  37.  *
  38.  * Revision 1.17  2001/12/24 20:07:18  mjames
  39.  * Added &D for device identifier in the replacement string in edit_pin as well
  40.  * as &0 .. &9
  41.  *
  42.  * Revision 1.16  2001/12/11 20:30:26  mjames
  43.  * Implemented  regular expression pin  name editing
  44.  *
  45.  * Revision 1.15  2001/11/19 10:21:04  mjames
  46.  * Fixed errors
  47.  *
  48.  * Revision 1.14  2001/11/19 10:02:23  mjames
  49.  * Merge back
  50.  *
  51.  * Revision 1.13.2.1  2001/11/15 22:03:52  mjames
  52.  * Altered the 'alter' command to use two arguments rather than one
  53.  * after TH suggestion.
  54.  *
  55.  * Revision 1.13  2001/10/31 22:28:27  mjames
  56.  * Problems with regular expression argument lists.
  57.  *
  58.  * Revision 1.12  2001/10/31 22:20:14  mjames
  59.  * Tidying up problematical comments caused by CVS
  60.  * 'intelligent' comment guessing
  61.  *
  62.  * Revision 1.11  2001/10/31 16:18:05  mjames
  63.  * Added a datastructure to hide regular expression information from programs.
  64.  * Changed call to regexec to indicate 0 subexpressions to be matched
  65.  * rather than a number dependent on strlen(string) which was wrong.
  66.  *
  67.  * Revision 1.10  2001/10/18 21:36:17  mjames
  68.  * Added modify pins command : nets inherit identifier from selected socket and pin on that socket to ease cross referencing.
  69.  *
  70.  * Revision 1.9  2001/10/11 16:10:16  mjames
  71.  * Corrections to the SWAP command, and printout so that
  72.  * WRITE net now outputs all chips in the design so that their generics
  73.  * can be passed forward to the next phase.
  74.  *
  75.  * Revision 1.8  2001/10/10 20:18:21  mjames
  76.  * Added a vert_regcomp function to compile regular expressions
  77.  * with '^' (match start string) and  '$' (match end string) bracketing
  78.  * this => wildcard must match entire string not just a part of it.
  79.  *
  80.  * Revision 1.7  2001/10/07 20:50:52  mjames
  81.  * Added wildcard checking (warn user about
  82.  * using wildcard '*' on the end of a string in stead of wildcard '.*')
  83.  *
  84.  * Revision 1.6  2001/09/25 23:15:23  mjames
  85.  * Converted wildcards to use proper regexp pattern match library
  86.  *
  87.  * Revision 1.5  2001/08/31 09:37:42  mjames
  88.  * modified rename rules so that un-named objects do not get
  89.  * name suffixes appended.
  90.  *
  91.  * Revision 1.4  2001/07/20 14:49:42  mjames
  92.  * Corrected reading names in on multiple boards : if present in a database file
  93.  * when reading in a suffixed design
  94.  * e.g. CHIP fred
  95.  * Will also get its name suffixed.
  96.  *
  97.  * Revision 1.3  2001/06/06 12:10:18  mjames
  98.  * Move from HPUX
  99.  *
  100.  * Revision 1.2  2001/01/26 21:50:10  mjames
  101.  * Managed to get vertical non TCL to compile again
  102.  *
  103.  * Conversion to argv, argc[] mode of operation continues
  104.  *
  105.  * Revision 1.1.1.1  2000/10/19 21:58:39  mjames
  106.  * Mike put it here
  107.  *
  108.  *
  109.  * Revision 1.26  2000/08/25  09:57:15  09:57:15  mjames (Mike James)
  110.  * Modified for Vertical2 : support COMPONENTS and SIGNALS
  111.  *
  112.  * Revision 1.26  2000/08/25  09:57:15  09:57:15  mjames (Mike James)
  113.  * Part of Release Aug25_alpha
  114.  *
  115.  * Revision 1.25  2000/08/16  08:57:31  08:57:31  mjames (Mike James)
  116.  * Part of Release CD01_Aug2000
  117.  *
  118.  * Revision 1.24  2000/08/14  14:45:12  14:45:12  mjames (Mike James)
  119.  * Part of Release Aug_14_2000
  120.  *
  121.  * Revision 1.23  2000/08/11  08:30:33  08:30:33  mjames (Mike James)
  122.  * Part of Release Aug_11_2000
  123.  *
  124.  * Revision 1.22  2000/08/09  10:31:48  10:31:48  mjames (Mike James)
  125.  * Part of Release Aug__9_2000
  126.  *
  127.  * Revision 1.21  2000/05/31  11:42:58  11:42:58  mjames (Mike James)
  128.  * Part of Release May_31_2000
  129.  *
  130.  * Revision 1.20  2000/05/08  17:01:38  17:01:38  mjames (Mike James)
  131.  * Part of Release May__8_2000
  132.  *
  133.  * Revision 1.19  2000/05/08  16:59:31  16:59:31  mjames (Mike James)
  134.  * Part of Release May__8_2000
  135.  *
  136.  * Revision 1.18  2000/05/08  16:57:08  16:57:08  mjames (Mike James)
  137.  * Part of Release May__8_2000
  138.  *
  139.  * Revision 1.17  2000/03/08  16:19:26  16:19:26  mjames (Mike James)
  140.  * New version including PC
  141.  *
  142.  * Revision 1.14  2000/01/20  15:58:48  15:58:48  mjames (Mike James)
  143.  * Part of Release R22
  144.  *
  145.  * Revision 1.13  99/12/22  11:15:29  11:15:29  mjames (Mike James)
  146.  * Part of Release Dec_22_1999
  147.  *
  148.  * Revision 1.12  99/06/25  14:35:49  14:35:49  mjames (Mike James)
  149.  * Added in reference to expression.h, but no changes made
  150.  * to the function of acfread yet.
  151.  *
  152.  * Revision 1.11  99/05/04  09:52:43  09:52:43  mjames (Mike James)
  153.  * General checkin
  154.  *
  155.  * Revision 1.10  98/08/12  14:22:18  14:22:18  mjames (Mike James)
  156.  * Corrected include file list
  157.  *
  158.  * Revision 1.9  98/04/24  14:07:51  14:07:51  mjames (Mike James)
  159.  *  Added pin name swapping code
  160.  *
  161.  * Revision 1.8  98/03/16  11:38:24  11:38:24  mjames (Mike James)
  162.  * Removed an old bug - suffixing of PCB names has been broken for about
  163.  * a year. If a pcb were read in non-suffixed and then another with a suffix,
  164.  * the suffix would be applied over all of the sockets and nets, not just the new ones.
  165.  *
  166.  * Revision 1.7  98/02/11  11:27:06  11:27:06  mjames (Mike James)
  167.  * Checked in for version 6.2a
  168.  *
  169.  * Revision 1.6  97/04/23  08:43:22  08:43:22  mjames (Mike James)
  170.  * CHecked in for release rel23041997
  171.  *
  172.  * Revision 1.5  96/07/19  14:38:51  14:38:51  mjames (Mike James)
  173.  * Update to give to PRL
  174.  *
  175.  * Revision 1.4  1996/07/12  15:52:12  mjames
  176.  * Sorted out things like Alias and Jumpers
  177.  * Work Correctly
  178.  * Print COrrectly
  179.  *
  180.  * Revision 1.4  1996/07/12  15:52:12  mjames
  181.  * Sorted out things like Alias and Jumpers
  182.  * Work Correctly
  183.  * Print COrrectly
  184.  *
  185.  * Revision 1.3  96/06/04  11:53:28  11:53:28  mjames (Mike James)
  186.  * Corrected the operation of the renaming function
  187.  *
  188.  * Revision 1.2  96/05/29  11:00:10  11:00:10  mjames (Mike James)
  189.  * Added explanatory comments
  190.  *
  191.  * Revision 1.1  96/05/29  10:53:13  10:53:13  mjames (Mike James)
  192.  * Initial revision
  193.  *  */
  194.  
  195.  
  196. #include <stdio.h>
  197. #include <string.h>
  198. #include <stdlib.h>
  199. #include <ctype.h>
  200. #include <sys/types.h>
  201. #include <regex.h>
  202.  
  203.  
  204.  
  205. #include "vertcl_main.h"
  206. #include "expression.h"
  207. #include "generic.h"
  208. #include "database.h"
  209. #include "rename.h"
  210. #include "cmdparse.h"
  211. #include "cmdlog.h"
  212. #include "lx_support.h"
  213. #include "chck_names.h"
  214. #include "sorting.h"
  215.  
  216. #ident "@(#)$Header: c:\\cygwin\\cvsroot/Vert03/vertlib/rename.c,v 1.2 2003/11/06 04:36:03 mjames Exp $"
  217.  
  218. /* added on to suffix all signal names */
  219. /* all new objects will appear after the 'mark'. Only
  220.    these new objects need to be renamed by adding a suffix.
  221.    Older objects have already been renamed. */
  222.  
  223. static net_t * mark_nets = NULL;
  224. static socket_t * mark_skts = NULL;
  225.  
  226. /* record the last known net and socket before
  227.    reading in new nets and sockets */
  228.  
  229. void mark_board_objects(void) {
  230.   net_t    * net = routed_list;
  231.   socket_t * skt = socket_head;
  232.   while(net && net->next )   {
  233.     net = net->next;
  234.     }
  235.   mark_nets = net;
  236.   while(skt && skt->next ) {
  237.     skt = skt->next;
  238.     }
  239.    mark_skts = skt;
  240. /*
  241.   printf("Mark at net=%p and skt=%p\n",mark_nets,mark_skts);
  242. */  
  243.   }
  244.  
  245.  
  246. /* only name nets that are not null names */
  247. static char * alter_id(char * id,char * suffix)
  248.   {
  249.   if(!ISNULLSTR(id) && !ISNULLSTR(suffix))
  250.     {
  251.     id = realloc(id,strlen(id)+strlen(suffix)+1);
  252.     strcat (id,suffix);
  253.     return(id);
  254.     }
  255.   return NULL;
  256.  }
  257.  
  258.  
  259. /* suffixes all net and component identifiers
  260.    since the last 'mark_board_objects' call with the string s */
  261.  
  262. void set_board_suffix(char * s)
  263. {
  264.   net_t * net    = mark_nets;
  265.   socket_t * skt = mark_skts;
  266.  
  267.  
  268. /*
  269.   printf("Mark at net=%p and skt=%p\n",mark_nets,mark_skts);
  270. */
  271.   /* flag the nets and sockets as having been renamed */
  272.   mark_nets = NULL;
  273.   mark_skts = NULL;
  274.  
  275.   if(net)
  276.     net=net->next; /* move to next one (new one) */
  277.   else
  278.     net=routed_list;  
  279.   if(skt)
  280.     skt=skt->next; /* ditto */
  281.   else
  282.     skt=socket_head;  
  283.  
  284.  
  285.   /* rename all of the net identifiers */
  286.   while(net) {
  287.     struct net * sub_n = net->subnets;
  288.  
  289.     /* jumpered nets have their subnets renamed */
  290.     if(sub_n && net->how_joined == Jumpered)
  291.       while (sub_n) {
  292.         sub_n->identifier = alter_id(sub_n->identifier,s);
  293.         sub_n = sub_n -> subnets;
  294.         }
  295.     else
  296.       net->identifier = alter_id(net->identifier,s);
  297.     net = net->next;
  298.     }  
  299.    /* rename all of the socket identifiers */
  300.    while(skt) {
  301.      skt->identifier = alter_id(skt->identifier,s);
  302.      if(skt->name) /* mod MDJ July 2001 */
  303.        skt->name     = alter_id(skt->name,s);
  304.      skt = skt->next;
  305.      }  
  306.  
  307.  
  308.   }
  309.  
  310. /*********************************************************************/
  311. /* Pin_swapping : reverse A23 to 23a                                 */
  312. /* allow up to lead_chars before digits to permit pin swap           */
  313. /* lead_chars = 2  -> aa23 maps to 23aa but pin23 remains unswapped  */
  314. /*********************************************************************/
  315. /* modified from the original, now allows swapping 1a to a1 if
  316.  * AlphaSwap_t == Want_A1
  317.  * or allows swapping a1 to 1a if
  318.  * AlphaSwap_t == Want_1A
  319.  * probably better using the renaming command below.
  320.  */
  321. void pin_id_swap(char * template,
  322.                         int lead_chars,
  323.                         AlphaSwap_t lead_alpha) {
  324.   enum {First_Char,
  325.         Leading_Chars,
  326.         Trailing_Digits,
  327.         Leading_Digits,
  328.         Trailing_Chars,
  329.         No_Swap } SwapState;
  330.   int rc;
  331.   socket_t * chip;
  332.   node_t * nodes;
  333.   /* compile regular expression */
  334.   vert_regex_t  * preg;
  335.  
  336.  
  337.   if(ISNULLSTR(template)) {
  338.     template = ".*";
  339.     }
  340.   rc = vert_regcomp(&preg,template);
  341.   if (rc != 0 )
  342.     {
  343.     char errbuff[100];
  344.     regerror(rc,preg->preg,errbuff,100);
  345.     Log(LOG_ERROR,"-- Problem (rc=%d) %s with '%s' as regular expression\n",rc,errbuff,template);
  346.    
  347. /*    return TCL_ERROR;
  348. */
  349.     return;
  350.     }
  351.   else
  352.     {
  353.     Log(LOG_GENERAL,"-- Using '%s' as match pattern\n",template);
  354.     }
  355.  
  356.  
  357.   if (lead_alpha == Want_A1) {
  358.     Log(LOG_GENERAL,"-- Swapping pin identifiers with up to %d leading letters\n",
  359.        lead_chars);
  360.     }
  361.   else {
  362.     Log(LOG_GENERAL,"-- Swapping pin identifiers with up to %d trailing letters\n",
  363.        lead_chars);
  364.     }
  365.   Log(LOG_GENERAL,"-- for sockets matching template '%s' --\n",
  366.        template?template:"[ALL Sockets]");
  367.    
  368.   chip = socket_head;
  369.   while(chip) {
  370.     int found;
  371.  
  372.  
  373.     found  = regexec(preg->preg,chip->identifier,0,preg->regpatt,0);
  374.  
  375.     if(!found)  {
  376.       Log(LOG_GENERAL,"-- Processing socket '%s' --\n",chip->identifier);
  377.  
  378.       nodes = chip -> nodes ;
  379.       while(nodes)  {
  380.         int lead_count = 0;
  381.         int done       = 0;
  382.         char new_id [MAXIDLEN];
  383.         char * pos = nodes->identifier;
  384.         SwapState = First_Char;
  385.         while(pos && *pos && !done) {
  386.        
  387. /*
  388.           printf("%s (%c) State %d\n",nodes->identifier,*pos,SwapState);
  389. */
  390.           switch(SwapState) {
  391.             case First_Char:
  392.  
  393.               if(lead_alpha== Want_A1 &&isdigit(*pos) && lead_chars > 0) {
  394.                   SwapState = Leading_Digits;
  395.                   lead_count = 1;
  396.                   break;
  397.                   }  
  398.               if(lead_alpha== Want_1A &&isalpha(*pos) && lead_chars > 0) {
  399.                   SwapState = Leading_Chars;
  400.                   lead_count = 1;
  401.                   break;
  402.                   }  
  403.                /* no action needed, so continue */
  404.                SwapState = No_Swap;
  405.                done = 1;
  406.                break;
  407.                
  408.             case Leading_Chars:
  409.              
  410.                 if (isdigit (*pos)) {
  411.                   if(lead_count <= lead_chars) { /* encountered a digit after a character success so far */
  412.                     SwapState = Trailing_Digits;
  413.                     break;
  414.                     }
  415.                   else{
  416.                     SwapState = No_Swap;
  417.                     done = 1;
  418.                     break;
  419.                     }
  420.                   }
  421.                 if(isalpha ( *pos)) {
  422.                   lead_count++;
  423.                   break;
  424.                   }
  425.                 SwapState = No_Swap;
  426.                 done = 1;
  427.                 break;
  428.  
  429.             case Leading_Digits:
  430.              
  431.                 if (isalpha (*pos)) {
  432.                   if(lead_count <= lead_chars) { /* encountered a character after a number success so far */
  433.                     SwapState = Trailing_Chars;
  434.                     break;
  435.                     }
  436.                   else{
  437.                     SwapState = No_Swap;
  438.                     done = 1;
  439.                     break;
  440.                     }
  441.                   }
  442.                 if(isdigit ( *pos)) { /* continue ok */
  443.                   lead_count++;
  444.                   break;
  445.                   }
  446.                 SwapState = No_Swap;
  447.                 done = 1;
  448.                 break;
  449.  
  450.                
  451.             case Trailing_Digits:
  452.                
  453.                 if (!isdigit (*pos)){
  454.                   SwapState = No_Swap;
  455.                   done = 1;
  456.                   }
  457.                 break;
  458.             case Trailing_Chars:
  459.                
  460.                 if (!isalpha (*pos)){
  461.                   SwapState = No_Swap;
  462.                   done = 1;
  463.                   }
  464.                 break;
  465.           default: break;  
  466.           }
  467.           pos++;
  468.           }
  469.         /* on arrival here in either state we can swap the two parts of the ident */
  470.         if (SwapState == Trailing_Digits || SwapState == Trailing_Chars) {
  471.           int i,l;
  472.           strcpy  (new_id,(nodes->identifier)+lead_count);
  473.           strncat (new_id,nodes->identifier,lead_count);
  474.           l = strlen(new_id);
  475.           for(i=0;i<l;i++)
  476.             new_id[i] = tolower(new_id[i]);
  477.           Log(LOG_GENERAL,"# Renaming %s(%s) to %s(%s)\n",
  478.             chip->identifier,   nodes->identifier,
  479.             chip->identifier,   new_id);
  480.           strcpy (nodes->identifier,new_id);
  481.           }        
  482.         nodes = nodes->sktnext;
  483.         }  
  484.       }
  485.     chip = chip->next;
  486.     }
  487.   vert_regfree(&preg);
  488.   }
  489.    
  490.    
  491. /***************************************************************************************/
  492. /* Name nets after node name on device instead of pcb CAD name                         */
  493. /* Initially lookup all matching sockets                                               */
  494.  
  495.  
  496. void alter_net_to_socket_name(char * chip_id_template,char * prefix_opt)
  497.   {
  498.   node_t * chip_node ;
  499.   int found,rc,count = 0;
  500.   socket_t * socket;
  501.   vert_regex_t * preg;
  502.  
  503.   socket = socket_head;
  504.  
  505. /*  create_unrouted_list(); */
  506.   /* compile regular expression */
  507.  
  508.  
  509.   if(!chip_id_template) {
  510.     chip_id_template = ".*";
  511.     }
  512.  
  513.   rc = vert_regcomp(&preg,chip_id_template);
  514.   if (rc != 0 )
  515.     {
  516.     char errbuff[100];
  517.     regerror(rc,preg->preg,errbuff,100);
  518.     Log(LOG_ERROR,"-- Problem (rc=%d) %s with '%s' as regular expression\n",rc,errbuff,chip_id_template);
  519.    
  520. /*    return TCL_ERROR;
  521. */
  522.     return;
  523.     }
  524.   else
  525.     {
  526.     Log(LOG_GENERAL,"-- Using '%s' as match pattern\n",chip_id_template);
  527.     }
  528.   while(socket )
  529.     {
  530.  
  531.     found  = regexec(preg->preg,socket->identifier,0,preg->regpatt,0);
  532.  
  533.     if(!found) {
  534. /*
  535.       Log(LOG_GENERAL,"found %s\n",skt->identifier);
  536. */
  537.       count++;
  538.       chip_node = socket-> nodes;
  539.       while (chip_node)
  540.         {
  541.         char name_buff[MAXIDLEN];
  542.         int count;
  543.         net_t * net = chip_node->net;
  544.         if(net && IS_ROUTABLE(net->how_routed))
  545.           {
  546.           if (prefix_opt) /* TH requests this change. Not a problem */
  547.             {
  548.             count = sprintf(name_buff,"%s%s",prefix_opt,chip_node->identifier);
  549.             }
  550.           else
  551.             {
  552.             count = sprintf(name_buff,"%s_%s",socket->identifier,chip_node->identifier);
  553.             }
  554.           net->identifier = realloc(net->identifier,count+1);
  555.           strcpy(net->identifier,name_buff);
  556. /*          printf("-- id = %s\n",name_buff); */
  557.           }
  558.         chip_node = chip_node -> sktnext;      
  559.         }
  560.  
  561.       }
  562.     socket = socket->next;
  563.     }
  564.   Log(LOG_GENERAL,"-- processed %d sockets\n",count);
  565.   vert_regfree(&preg);
  566.  
  567.   }
  568.  
  569.  
  570.  
  571.  
  572.  
  573. static char pin_map_chars[] = PIN_MAP_LEGAL_CHARS;
  574.  
  575. static int row_index,col_index; /* Made static so I can check them later .*/
  576.  
  577. /***************************************************************************************/
  578. /* Name nets after node name on device instead of pcb CAD name                         */
  579. /* Initially lookup all matching sockets                                               */
  580. /* change device template pin identifiers */
  581.  
  582. void edit_socket_pin_name(char * chip_id_template,char * pin_patt, char * pin_repl, property_t search_space)
  583.   {
  584.   node_t * chip_node ;
  585.   int found,rc,count = 0;
  586.   int subexpressions;
  587.   socket_t * socket;
  588.   vert_regex_t * preg;
  589.   vert_regex_t * ppin_reg;
  590.   int loop;  
  591.  
  592.   if (ISNULLSTR(pin_patt))
  593.     {
  594.     return;
  595.     }
  596.  
  597.   socket = template_head;
  598.  
  599. /*  create_unrouted_list(); */
  600.   /* compile regular expression for chip type */
  601.  
  602.   if(!chip_id_template) {
  603.     chip_id_template = ".*";
  604.     }
  605.  
  606.   rc = vert_regcomp(&preg,chip_id_template);
  607.   if (rc != 0 )
  608.     {
  609.     char errbuff[100];
  610.     regerror(rc,preg->preg,errbuff,100);
  611.     Log(LOG_ERROR,"-- Problem (rc=%d) %s with '%s' as regular expression\n",rc,errbuff,chip_id_template);
  612.    
  613. /*    return TCL_ERROR;
  614. */
  615.     return;
  616.     }
  617.   else
  618.     {
  619.     Log(LOG_GENERAL,"-- Using '%s' as match pattern for chip %s\n",chip_id_template,search_space==Type?"type":"ident");
  620.     }
  621.  
  622.  
  623.   /* now compile pin regexp match pattern */
  624.   rc = vert_regcomp(&ppin_reg,pin_patt);
  625.   if (rc != 0 )
  626.     {
  627.     char errbuff[100];
  628.     regerror(rc,ppin_reg->preg,errbuff,100);
  629.     Log(LOG_ERROR,"-- Problem (rc=%d) %s with '%s' as regular expression\n",rc,errbuff,pin_patt);
  630.    
  631. /*    return TCL_ERROR;
  632. */
  633.     return;
  634.     }
  635.   else
  636.     {
  637.     subexpressions = ppin_reg->preg->re_nsub+1; /* count up subexpressions */
  638.     Log(LOG_GENERAL,"-- Using '%s' as chip pin ID matching pattern (%d subexpressions)\n",pin_patt,subexpressions);
  639.     }
  640.  
  641.  
  642.  
  643.   if (subexpressions >  MAX_REGEXP_SUBEXPR)
  644.     {
  645.     Log(LOG_ERROR,"-- Too many (>%d) subexpressions\n",MAX_REGEXP_SUBEXPR);
  646.     return;
  647.     }
  648. /* decode the command type */
  649.  
  650.   switch (search_space)
  651.     {
  652.     case Ident: loop = 1; break;
  653.     case Type : loop = 2; break;
  654.     default :   loop = 0; break;
  655.     }
  656.  
  657. /* loop 2,1, 0 or 1,0 dependent on whether search is type or ident based */
  658.   while(loop)
  659.    {
  660.  
  661.   switch (loop)
  662.     {
  663.     case 1: socket = socket_head;   break;
  664.     case 2: socket = template_head; break;
  665.     default : break;
  666.     }
  667.   loop--;
  668.   while(socket )
  669.     {
  670.     if(search_space == Type)
  671.       {
  672.       found  = regexec(preg->preg,socket->type,0,preg->regpatt,0);
  673.       }
  674.     else
  675.       {
  676.       found  = regexec(preg->preg,socket->identifier,0,preg->regpatt,0);
  677.       }
  678.     if(!found) {
  679. /*
  680.       Log(LOG_GENERAL,"found %s\n",skt->identifier);
  681. */
  682.  
  683.  
  684.       int rows,columns;
  685. /*      int row_index,col_index;  Made static so I can check them later .*/
  686.  
  687.      
  688.       generic_info_t info,* row_expr, * col_expr;
  689.      
  690.        
  691. /* Setup the row and column variables for this device */  
  692. /* these are input names that can be used in an expression */
  693.       info.g_type = IS_ATTRIBUTE;
  694.       info.g_class= DEFINED;
  695.  
  696. /* info is copied, simply change the variable parts and call the compile
  697.     and set functions */
  698.       info.name = "pin_row";
  699.       info.expr   = compile_variable_reference(&row_index,"pin_row");
  700.       set_generic_value(&socket->generics, &info);
  701.  
  702.       info.name = "pin_col";
  703.       info.expr   = compile_variable_reference(&row_index,"pin_col");
  704.       set_generic_value(&socket->generics, &info);
  705.  
  706.  
  707. /* this expression will be evaluated when &n is seen in the
  708.     input file */
  709.       row_expr = get_generic_ref(&socket->generics,"row_expr");
  710.  
  711. /*
  712.       if(row_expr && row_expr->expr)
  713.         {
  714.         printf("row = ");
  715.         print_expression(stdout,row_expr->expr,NO_RECURSE);
  716.         printf("\n");
  717.         }
  718. */
  719.      
  720. /* this expression will be evaluated when &a is seen in the
  721.     input file */
  722.       col_expr = get_generic_ref(&socket->generics,"col_expr");
  723. /*      
  724.       if(col_expr && col_expr->expr)
  725.         {
  726.         printf("col = ");
  727.         print_expression(stdout,col_expr->expr,NO_RECURSE);
  728.         printf("\n");
  729.         }
  730. */      
  731.       count++;
  732.       sort_nodes(socket,EXTRACT_XY); /* sort pins , determine pin row and column*/
  733.      
  734.       rows    = socket->max_pin_row - socket->min_pin_row+1;
  735.       columns = socket->max_pin_col - socket->min_pin_col+1;
  736.  
  737.       chip_node = socket-> nodes;
  738.       while (chip_node)
  739.         {
  740.         char * str;
  741.         str = chip_node->identifier;
  742.         /* allow one bracketed subexpression in pin names */
  743.         found = regexec(ppin_reg->preg,str,subexpressions,ppin_reg->regpatt,0);
  744.         if(!found)
  745.           {
  746.           char name_buff[MAXIDLEN];
  747.           int count,fail;
  748.           int editp,copyp;
  749.           name_buff[0] = 0;
  750.           /* get length of replacement string */
  751.           editp = 0;
  752.           count = 0;
  753.           fail  = 0;
  754. /*          printf("Processing '%s'\n",pin_repl); */
  755.           while(pin_repl[editp] && !fail)
  756.             {
  757.             /* escape anything */
  758.             if(pin_repl[editp] == '\\')
  759.               {
  760.               editp++;      
  761.               name_buff[count++]= pin_repl[editp];
  762.               if(pin_repl[editp])
  763.                 {
  764.                 editp++;
  765.                 }
  766.               }
  767.             /* replace matched patterns */
  768.             else if(pin_repl[editp] == '&')
  769.               {
  770.               int index,len;
  771.               char c;
  772.               char temp[30];
  773.               int digits;
  774. /* change values to those seen on this pin */
  775.               col_index = chip_node -> pin_col;
  776.               row_index = chip_node -> pin_row;
  777.  
  778.  
  779.  
  780.               editp++;
  781.               c = pin_repl[editp];
  782.               if(c)
  783.                  {
  784. /*                 printf("c='%c' row = %d col =%d\n",c,chip_node->pin_row ,chip_node->pin_col); */
  785.                  editp++;
  786.                 switch(c)
  787.                   {
  788.                   case 'c':
  789.                   case 'C':
  790.                     if (chip_node->net && chip_node->net->name)
  791.                       {
  792.                       len   = strlen(chip_node->net->name);
  793.                       strncpy(name_buff+count,chip_node->net->name,len);
  794.                       count += len;
  795.                       }
  796.                     else
  797.                       {
  798.                       fail = 1;
  799.                       }
  800.                     break;
  801.                    
  802.                          
  803.  
  804.                 /* &d or &D is the device identifier */
  805.                   case 'd':
  806.                   case 'D':
  807.                     len   = strlen(socket->identifier);
  808.                     strncpy(name_buff+count,socket->identifier,len);
  809.                     count += len;
  810.                     break;
  811.                 /* &p or &P is the pin identifier */
  812.                   case 'p':
  813.                   case 'P':
  814.                     len = strlen(chip_node->identifier);
  815.                     strncpy(name_buff+count,chip_node->identifier,len);
  816.                     count += len;
  817.                     break;
  818.                 /* &a is the alpha component of the identifier */
  819.                   case 'a':
  820.                   case 'A':
  821.                     /* always synthesise pin column from the info left by sort_nodes */                  
  822.                     if(col_expr && col_expr->expr)
  823.                       {
  824.                       index = eval_expression(col_expr->expr,&socket->generics);
  825.                       }
  826.                     else
  827.                       {
  828.                       index = chip_node -> pin_col;
  829.                       }
  830. /*                    printf("Alpha %d : ",index);   */
  831.                     digits = 0;
  832.                     /* always at least a single char */
  833.                     if(index>0) /* index = 0 means no chars at all ! */
  834.                       {
  835.                       do
  836.                         {
  837.                         if(c=='a')  /* lower case idents if lower case 'a' is used */
  838.                           {
  839.                           temp[digits++] = tolower(pin_map_chars[index % (PIN_MAP_LEGAL_CHAR_COUNT+1)-1]);
  840.                           }
  841.                         else
  842.                           {
  843.                           temp[digits++] = pin_map_chars[index % (PIN_MAP_LEGAL_CHAR_COUNT+1)-1];
  844.                           }
  845.                      
  846.                         index /= (PIN_MAP_LEGAL_CHAR_COUNT+1);
  847.                         }
  848.                       while(index);
  849.                       temp[digits]= 0;
  850. /*                      printf("conversion '%s'\n",temp); */
  851.                     /* reverse copy string, at least one char */
  852.                       for(;digits>0;name_buff[count++]=temp[--digits]);
  853.                       }
  854.                     else
  855.                       {
  856. /* error in the expansion as the index < 0 */                      
  857. /* Leave it blank as there is a danger elsewhere
  858.                       name_buff[count++] = '&';
  859.                       name_buff[count++] = c;
  860. */                      
  861.                       }              
  862.                     break;
  863.                 /* &n is the alpha component of the identifier */
  864.                   case 'n':
  865.                   case 'N':
  866.                     if(row_expr && row_expr->expr)
  867.                       {
  868.                       index = eval_expression(row_expr->expr,&socket->generics);
  869.                       }
  870.                     else
  871.                       {
  872.                       index = chip_node -> pin_row;
  873.                       }
  874. /*                    printf("Numeric %d\n",index); */
  875.                     if(index>0) /* index = 0 means no chars at all ! */
  876.                       {
  877.  
  878.                       sprintf(temp,"%d",index);
  879.                       len = strlen(temp);
  880.                       strncpy(name_buff+count,temp,len);
  881. /*                    printf("result: '%s' %d\n",name_buff,strlen(name_buff)); */
  882.                       count += len;
  883.                       }
  884.                     else
  885.                       {
  886. /* error in the expansion as the index < 0 */                      
  887.                       name_buff[count++] = '&';
  888.                       name_buff[count++] = c;
  889.                      
  890.                       }              
  891.                      
  892.                     break;
  893.                   case 'i':
  894.                   case 'I':
  895.                     sprintf(temp,"%d",chip_node->pin_row - socket->min_pin_row +
  896.                              (chip_node->pin_col - socket->min_pin_col) * rows +1);
  897.                            
  898.                     len = strlen(temp);
  899.                     strncpy(name_buff+count,temp,len);
  900.                     count += len;
  901.                     break;
  902.                 /* &0 to &9 or whatever is the regular expression bracketed
  903.                    section */
  904.                   default:
  905.                     index = c -'0';
  906.                     if(index <0 || index > subexpressions)
  907.                       {
  908.                       fail = 1;
  909.                       }
  910.                     else
  911.                       {
  912.                       /* copy subexpression over */
  913.                       copyp = ppin_reg->regpatt[index].rm_so;
  914.                       if (copyp >=0 )
  915.                         {
  916.                         while(copyp < ppin_reg->regpatt[index].rm_eo)
  917.                           {
  918.                           name_buff[count++] = str[copyp++];
  919.                           }
  920.                         }
  921.                       else
  922.                         {
  923.                         name_buff[count++] = '@';
  924.                         }
  925.                       }
  926.                     }
  927.                   }
  928.                 }
  929.              
  930.             else
  931.               {
  932.               name_buff[count++]=pin_repl[editp++];
  933.               }
  934.             }
  935.           if(!fail)
  936.             {
  937.             name_buff[count] = 0;
  938. /*
  939.             printf("replacing '%s' with '%s'\n",chip_node->identifier,name_buff);
  940. */
  941.             chip_node->identifier = realloc(chip_node->identifier,count+1);
  942.             strcpy(chip_node->identifier,name_buff);
  943.             }
  944.           }
  945.         chip_node=chip_node->sktnext;
  946.         }
  947.       }
  948.     sort_nodes(socket,NO_EXTRACT_XY);
  949.     socket = socket->next;
  950.     }
  951.  
  952.    }
  953.   Log(LOG_GENERAL,"-- processed %d sockets\n",count);
  954.   vert_regfree(&preg);
  955.   vert_regfree(&ppin_reg);
  956.   }
  957.  
  958.  
  959.  
  960. /***************************************************************************************/
  961. /* allows for net renaming : currently in the routed list only  */
  962. void  edit_net_names(char * pin_patt, char * pin_repl,property_t search_space)
  963.   {
  964.   net_t * curr_net ;
  965.   int found,rc = 0;
  966.   int subexpressions;
  967.   int net_count;
  968.   vert_regex_t * ppin_reg;
  969.   int loop;  
  970.   net_count = 0;
  971.  
  972.   if (ISNULLSTR(pin_patt))
  973.     {
  974.     return;
  975.     }
  976.  
  977.   curr_net = routed_list;
  978.  
  979.  
  980.   /* now compile pin regexp match pattern */
  981.   rc = vert_regcomp(&ppin_reg,pin_patt);
  982.   if (rc != 0 )
  983.     {
  984.     char errbuff[100];
  985.     regerror(rc,ppin_reg->preg,errbuff,100);
  986.     Log(LOG_ERROR,"-- Problem (rc=%d) %s with '%s' as regular expression\n",rc,errbuff,pin_patt);
  987.    
  988. /*    return TCL_ERROR;
  989. */
  990.     return;
  991.     }
  992.   else
  993.     {
  994.     subexpressions = ppin_reg->preg->re_nsub+1; /* count up subexpressions */
  995.     Log(LOG_GENERAL,"-- Using '%s' as net matching pattern (%d subexpressions)\n",pin_patt,subexpressions);
  996.     }
  997.  
  998.  
  999.  
  1000.   if (subexpressions >  MAX_REGEXP_SUBEXPR)
  1001.     {
  1002.     Log(LOG_ERROR,"-- Too many (>%d) subexpressions\n",MAX_REGEXP_SUBEXPR);
  1003.     return;
  1004.     }
  1005. /* decode the command type */
  1006. /*
  1007.   switch (search_space)
  1008.     {
  1009.     case Ident: loop = 1; break;
  1010.     case Type : loop = 2; break;
  1011.     default :   loop = 0; break;
  1012.     }
  1013. */
  1014.  
  1015.   loop = 3;
  1016. /* loop 2,1, 0 or 1,0 dependent on whether search is type or ident based */
  1017.   while(loop)
  1018.     {
  1019.     char * str;
  1020.     printf("In loop %d\n",loop);
  1021.     switch (loop)
  1022.       {
  1023.       case 1: curr_net = routed_list;   break;
  1024.       case 2: curr_net = unrouted_list; break;
  1025.       case 3: curr_net = named_list; break;
  1026.       default : curr_net = NULL; break;
  1027.       }
  1028.     loop--;
  1029.     while(curr_net )
  1030.       {
  1031.       found = 1;
  1032.       str = "nothing";
  1033.       if(search_space == Name && !ISNULLSTR(curr_net->name))
  1034.         {
  1035.         found  = regexec(ppin_reg->preg,curr_net->name,0,ppin_reg->regpatt,0);
  1036.         str = curr_net -> name;
  1037.         }
  1038.  
  1039.       if(search_space == Ident && !ISNULLSTR(curr_net->identifier))
  1040.         {
  1041.         found  = regexec(ppin_reg->preg,curr_net->identifier,0,ppin_reg->regpatt,0);
  1042.         str = curr_net -> identifier;
  1043.         }
  1044. /*      printf("Checking '%s'\n",str);  */
  1045.  
  1046.    /* found will not be set if neither Name or Ident is used */
  1047.       if(!found)
  1048.         {
  1049.         char name_buff[MAXIDLEN];
  1050.         int fail,count;
  1051.         int editp,copyp;
  1052.         name_buff[0] = 0;
  1053.           /* get length of replacement string */
  1054.         editp = 0;
  1055.         fail  = 0;
  1056.         count = 0;
  1057.         net_count ++;
  1058.          printf("Processing '%s'\n",str);
  1059.         while(pin_repl[editp] && !fail)
  1060.           {
  1061.             /* escape anything */
  1062.           if(pin_repl[editp] == '\\')
  1063.             {
  1064.             editp++;      
  1065.             name_buff[count++]= pin_repl[editp];
  1066.             if(pin_repl[editp])
  1067.               {
  1068.               editp++;
  1069.               }
  1070.             }
  1071.             /* replace matched patterns */
  1072.           else if(pin_repl[editp] == '&')
  1073.             {
  1074.             int index,len;
  1075.             char c;
  1076.             editp++;
  1077.             c = pin_repl[editp];
  1078.             if(c)
  1079.                {
  1080.                editp++;
  1081.                switch(c)
  1082.                  {
  1083. /* replace with name part of net */
  1084.                  case 'n':
  1085.                  case 'N':
  1086.                    if (!ISNULLSTR(curr_net->name))
  1087.                      {
  1088.                      len   = strlen(curr_net->name);
  1089.                      strncpy(name_buff+count,curr_net->name,len);
  1090.                      count += len;
  1091.                      }
  1092.                    else
  1093.                      {
  1094.                      fail = 1;
  1095.                      }
  1096.                    break;
  1097.                  
  1098.                  case 'i':
  1099.                  case 'I':
  1100.                    if (!ISNULLSTR(curr_net->identifier))
  1101.                      {
  1102.                      len   = strlen(curr_net->identifier);
  1103.                      strncpy(name_buff+count,curr_net->identifier,len);
  1104.                      count += len;
  1105.                      }
  1106.                    else
  1107.                      {
  1108.                      fail = 1;
  1109.                      }
  1110.                    break;
  1111.                          
  1112.  
  1113.                 /* &0 to &9 or whatever is the regular expression bracketed
  1114.                    section */
  1115.                  default:
  1116.                    index = c -'0';
  1117.                    if(index <0 || index > subexpressions)
  1118.                      {
  1119.                      fail = 1;
  1120.                      }
  1121.                    else
  1122.                      {
  1123.                      /* copy subexpression over */
  1124.                      copyp = ppin_reg->regpatt[index].rm_so;
  1125.                      if (copyp >=0 )
  1126.                        {
  1127.                        while(copyp < ppin_reg->regpatt[index].rm_eo)
  1128.                          {
  1129.                          name_buff[count++] = str[copyp++];
  1130.                          }
  1131.                        }
  1132.                      else
  1133.                        {
  1134.                        name_buff[count++] = '@';
  1135.                        }
  1136.                      }
  1137.                    } /* cae */
  1138.                  }
  1139.                }
  1140.              
  1141.              else
  1142.                {
  1143.                name_buff[count++]=pin_repl[editp++];
  1144.                }
  1145.              }
  1146.            if(!fail)
  1147.              {
  1148.              name_buff[count] = 0;
  1149. /*
  1150.             printf("replacing '%s' with '%s'\n",chip_node->identifier,name_buff);
  1151. */           if(search_space == Ident)
  1152.                {
  1153.                curr_net->identifier = realloc(curr_net->identifier,count+1);
  1154.  
  1155.                printf("replacing '%s' with '%s'\n",curr_net->identifier,name_buff);
  1156.                strcpy(curr_net->identifier,name_buff);
  1157.                }
  1158.              if(search_space == Name)
  1159.                {
  1160.                curr_net->name = realloc(curr_net->name,count+1);
  1161.                printf("replacing '%s' with '%s'\n",curr_net->name,name_buff);
  1162.                strcpy(curr_net->name,name_buff);
  1163.                }
  1164.  
  1165.              }
  1166.            }
  1167.           curr_net=curr_net->next;
  1168.           }
  1169.        }
  1170.    Log(LOG_GENERAL,"-- processed %d nets\n",net_count);
  1171.    vert_regfree(&ppin_reg);
  1172.    }
  1173.