Subversion Repositories Vertical

Rev

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

Rev Author Line No. Line
2 mjames 1
/*
11 mjames 2
 *  $Id: rename.c,v 1.2 2003/11/06 04:36:03 mjames Exp $
2 mjames 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
11 mjames 68
 * Added modify pins command : nets inherit identifier from selected socket and pin on that socket to ease cross referencing.
2 mjames 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
11 mjames 111
 *
2 mjames 112
 * Revision 1.26  2000/08/25  09:57:15  09:57:15  mjames (Mike James)
113
 * Part of Release Aug25_alpha
11 mjames 114
 *
2 mjames 115
 * Revision 1.25  2000/08/16  08:57:31  08:57:31  mjames (Mike James)
116
 * Part of Release CD01_Aug2000
11 mjames 117
 *
2 mjames 118
 * Revision 1.24  2000/08/14  14:45:12  14:45:12  mjames (Mike James)
119
 * Part of Release Aug_14_2000
11 mjames 120
 *
2 mjames 121
 * Revision 1.23  2000/08/11  08:30:33  08:30:33  mjames (Mike James)
122
 * Part of Release Aug_11_2000
11 mjames 123
 *
2 mjames 124
 * Revision 1.22  2000/08/09  10:31:48  10:31:48  mjames (Mike James)
125
 * Part of Release Aug__9_2000
11 mjames 126
 *
2 mjames 127
 * Revision 1.21  2000/05/31  11:42:58  11:42:58  mjames (Mike James)
128
 * Part of Release May_31_2000
11 mjames 129
 *
2 mjames 130
 * Revision 1.20  2000/05/08  17:01:38  17:01:38  mjames (Mike James)
131
 * Part of Release May__8_2000
11 mjames 132
 *
2 mjames 133
 * Revision 1.19  2000/05/08  16:59:31  16:59:31  mjames (Mike James)
134
 * Part of Release May__8_2000
11 mjames 135
 *
2 mjames 136
 * Revision 1.18  2000/05/08  16:57:08  16:57:08  mjames (Mike James)
137
 * Part of Release May__8_2000
11 mjames 138
 *
2 mjames 139
 * Revision 1.17  2000/03/08  16:19:26  16:19:26  mjames (Mike James)
140
 * New version including PC
11 mjames 141
 *
2 mjames 142
 * Revision 1.14  2000/01/20  15:58:48  15:58:48  mjames (Mike James)
143
 * Part of Release R22
11 mjames 144
 *
2 mjames 145
 * Revision 1.13  99/12/22  11:15:29  11:15:29  mjames (Mike James)
146
 * Part of Release Dec_22_1999
11 mjames 147
 *
2 mjames 148
 * Revision 1.12  99/06/25  14:35:49  14:35:49  mjames (Mike James)
11 mjames 149
 * Added in reference to expression.h, but no changes made
2 mjames 150
 * to the function of acfread yet.
11 mjames 151
 *
2 mjames 152
 * Revision 1.11  99/05/04  09:52:43  09:52:43  mjames (Mike James)
153
 * General checkin
11 mjames 154
 *
2 mjames 155
 * Revision 1.10  98/08/12  14:22:18  14:22:18  mjames (Mike James)
156
 * Corrected include file list
11 mjames 157
 *
2 mjames 158
 * Revision 1.9  98/04/24  14:07:51  14:07:51  mjames (Mike James)
159
 *  Added pin name swapping code
11 mjames 160
 *
2 mjames 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.
11 mjames 165
 *
2 mjames 166
 * Revision 1.7  98/02/11  11:27:06  11:27:06  mjames (Mike James)
167
 * Checked in for version 6.2a
11 mjames 168
 *
2 mjames 169
 * Revision 1.6  97/04/23  08:43:22  08:43:22  mjames (Mike James)
170
 * CHecked in for release rel23041997
11 mjames 171
 *
2 mjames 172
 * Revision 1.5  96/07/19  14:38:51  14:38:51  mjames (Mike James)
173
 * Update to give to PRL
11 mjames 174
 *
2 mjames 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
11 mjames 187
 *
2 mjames 188
 * Revision 1.2  96/05/29  11:00:10  11:00:10  mjames (Mike James)
189
 * Added explanatory comments
11 mjames 190
 *
2 mjames 191
 * Revision 1.1  96/05/29  10:53:13  10:53:13  mjames (Mike James)
192
 * Initial revision
193
 *  */
194
 
195
 
11 mjames 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"
2 mjames 206
#include "expression.h"
207
#include "generic.h"
11 mjames 208
#include "database.h"
209
#include "rename.h"
210
#include "cmdparse.h"
211
#include "cmdlog.h"
2 mjames 212
#include "lx_support.h"
11 mjames 213
#include "chck_names.h"
2 mjames 214
#include "sorting.h"
215
 
11 mjames 216
#ident "@(#)$Header: c:\\cygwin\\cvsroot/Vert03/vertlib/rename.c,v 1.2 2003/11/06 04:36:03 mjames Exp $"
2 mjames 217
 
218
/* added on to suffix all signal names */
219
/* all new objects will appear after the 'mark'. Only
11 mjames 220
   these new objects need to be renamed by adding a suffix.
2 mjames 221
   Older objects have already been renamed. */
222
 
11 mjames 223
static net_t * mark_nets = NULL;
224
static socket_t * mark_skts = NULL;
2 mjames 225
 
226
/* record the last known net and socket before
227
   reading in new nets and sockets */
228
 
11 mjames 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
  }
2 mjames 244
 
11 mjames 245
 
2 mjames 246
/* only name nets that are not null names */
11 mjames 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)
2 mjames 263
{
11 mjames 264
  net_t * net    = mark_nets;
265
  socket_t * skt = mark_skts;
266
 
2 mjames 267
 
11 mjames 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;
2 mjames 274
 
11 mjames 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;  
2 mjames 283
 
284
 
11 mjames 285
  /* rename all of the net identifiers */
286
  while(net) {
287
    struct net * sub_n = net->subnets;
2 mjames 288
 
11 mjames 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
  }
2 mjames 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
/*********************************************************************/
11 mjames 315
/* modified from the original, now allows swapping 1a to a1 if
2 mjames 316
 * AlphaSwap_t == Want_A1
11 mjames 317
 * or allows swapping a1 to 1a if
2 mjames 318
 * AlphaSwap_t == Want_1A
319
 * probably better using the renaming command below.
320
 */
11 mjames 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;
2 mjames 335
 
336
 
11 mjames 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
    }
2 mjames 355
 
356
 
11 mjames 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;
2 mjames 371
 
372
 
11 mjames 373
    found  = regexec(preg->preg,chip->identifier,0,preg->regpatt,0);
2 mjames 374
 
11 mjames 375
    if(!found)  {
376
      Log(LOG_GENERAL,"-- Processing socket '%s' --\n",chip->identifier);
2 mjames 377
 
11 mjames 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:
2 mjames 392
 
11 mjames 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;
2 mjames 428
 
11 mjames 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;
2 mjames 449
 
11 mjames 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                                               */
2 mjames 494
 
495
 
11 mjames 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;
2 mjames 504
 
11 mjames 505
/*  create_unrouted_list(); */
506
  /* compile regular expression */
2 mjames 507
 
508
 
11 mjames 509
  if(!chip_id_template) {
510
    chip_id_template = ".*";
511
    }
2 mjames 512
 
11 mjames 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);
2 mjames 532
 
11 mjames 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)
2 mjames 540
        {
11 mjames 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;      
2 mjames 559
        }
560
 
11 mjames 561
      }
562
    socket = socket->next;
563
    }
564
  Log(LOG_GENERAL,"-- processed %d sockets\n",count);
565
  vert_regfree(&preg);
2 mjames 566
 
11 mjames 567
  }
2 mjames 568
 
569
 
11 mjames 570
 
571
 
572
 
2 mjames 573
static char pin_map_chars[] = PIN_MAP_LEGAL_CHARS;
574
 
11 mjames 575
static int row_index,col_index; /* Made static so I can check them later .*/
2 mjames 576
 
577
/***************************************************************************************/
578
/* Name nets after node name on device instead of pcb CAD name                         */
11 mjames 579
/* Initially lookup all matching sockets                                               */
2 mjames 580
/* change device template pin identifiers */
581
 
11 mjames 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;  
2 mjames 591
 
11 mjames 592
  if (ISNULLSTR(pin_patt))
593
    {
594
    return;
595
    }
2 mjames 596
 
11 mjames 597
  socket = template_head;
2 mjames 598
 
11 mjames 599
/*  create_unrouted_list(); */
600
  /* compile regular expression for chip type */
2 mjames 601
 
11 mjames 602
  if(!chip_id_template) {
603
    chip_id_template = ".*";
604
    }
2 mjames 605
 
11 mjames 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
    }
2 mjames 621
 
622
 
11 mjames 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
    }
2 mjames 640
 
641
 
11 mjames 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)
2 mjames 713
        {
11 mjames 714
        printf("row = ");
715
        print_expression(stdout,row_expr->expr,NO_RECURSE);
716
        printf("\n");
2 mjames 717
        }
11 mjames 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)
2 mjames 725
        {
11 mjames 726
        printf("col = ");
727
        print_expression(stdout,col_expr->expr,NO_RECURSE);
728
        printf("\n");
2 mjames 729
        }
11 mjames 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;
2 mjames 736
 
11 mjames 737
      chip_node = socket-> nodes;
738
      while (chip_node)
2 mjames 739
        {
11 mjames 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])
2 mjames 763
                {
11 mjames 764
                editp++;
2 mjames 765
                }
11 mjames 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
2 mjames 836
                        {
11 mjames 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);
2 mjames 847
                        }
11 mjames 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 )
2 mjames 915
                        {
11 mjames 916
                        while(copyp < ppin_reg->regpatt[index].rm_eo)
917
                          {
918
                          name_buff[count++] = str[copyp++];
919
                          }
2 mjames 920
                        }
11 mjames 921
                      else
2 mjames 922
                        {
11 mjames 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
    }
2 mjames 951
 
11 mjames 952
   }
953
  Log(LOG_GENERAL,"-- processed %d sockets\n",count);
954
  vert_regfree(&preg);
955
  vert_regfree(&ppin_reg);
956
  }
2 mjames 957
 
958
 
959
 
11 mjames 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;
2 mjames 971
 
11 mjames 972
  if (ISNULLSTR(pin_patt))
973
    {
974
    return;
975
    }
2 mjames 976
 
11 mjames 977
  curr_net = routed_list;
2 mjames 978
 
979
 
11 mjames 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
    }
2 mjames 997
 
998
 
999
 
11 mjames 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
*/
2 mjames 1014
 
11 mjames 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))
2 mjames 1034
        {
11 mjames 1035
        found  = regexec(ppin_reg->preg,curr_net->name,0,ppin_reg->regpatt,0);
1036
        str = curr_net -> name;
2 mjames 1037
        }
11 mjames 1038
 
1039
      if(search_space == Ident && !ISNULLSTR(curr_net->identifier))
2 mjames 1040
        {
11 mjames 1041
        found  = regexec(ppin_reg->preg,curr_net->identifier,0,ppin_reg->regpatt,0);
1042
        str = curr_net -> identifier;
2 mjames 1043
        }
11 mjames 1044
/*      printf("Checking '%s'\n",str);  */
2 mjames 1045
 
11 mjames 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] == '\\')
2 mjames 1063
            {
11 mjames 1064
            editp++;      
1065
            name_buff[count++]= pin_repl[editp];
1066
            if(pin_repl[editp])
1067
              {
1068
              editp++;
1069
              }
2 mjames 1070
            }
11 mjames 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
 
2 mjames 1112
 
11 mjames 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);
2 mjames 1154
 
11 mjames 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
               }
2 mjames 1164
 
11 mjames 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
   }