1 /*
2  * This file is part of the Alliance CAD System
3  * Copyright (C) Laboratoire LIP6 - D�partement ASIM
4  * Universite Pierre et Marie Curie
5  *
6  * Home page          : http://www-asim.lip6.fr/alliance/
7  * E-mail             : mailto:alliance-users@asim.lip6.fr
8  *
9  * This library is free software; you  can redistribute it and/or modify it
10  * under the terms  of the GNU Library General Public  License as published
11  * by the Free Software Foundation; either version 2 of the License, or (at
12  * your option) any later version.
13  *
14  * Alliance VLSI  CAD System  is distributed  in the hope  that it  will be
15  * useful, but WITHOUT  ANY WARRANTY; without even the  implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17  * Public License for more details.
18  *
19  * You should have received a copy  of the GNU General Public License along
20  * with the GNU C Library; see the  file COPYING. If not, write to the Free
21  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23 
24 /*******************************************************************************
25 * mbk : vti parser netlist view : hns & fne formats v4r11                      *
26 *                                                                              *
27 * Based upon material provided by Alain Greiner in 1990, in lex and yacc       *
28 *                                                                              *
29 * version 0.0 written by Hichang Li in june 1991 under the supervision of      *
30 *             Frederic Petrot                                                  *
31 * version n.x is a rewitting and update of version 0.0 written by Frederic     *
32 *             Petrot on september 1991                                         *
33 *                                                                              *
34 * New versions are mostly bug corrections, or standardization matters and are  *
35 * done by Frederic Petrot, since middle 1990.                                  *
36 *                                                                              *
37 * Rc nets support done by Gregoire Avot on April 1997.                         *
38 *                                                                              *
39 *                                                                              *
40 * version : 4.12                                                               *
41 * date    : 12/06/1998                                                         *
42 *                                                                              *
43 * $Log: parse_vti_l.c,v $
44 * Revision 1.5  2012/05/14 14:20:26  alliance
45 * Updated GNU/FSF address (patch from Thibault North).
46 *
47 * Revision 1.4  2006/03/29 17:10:46  xtof
48 * * gcc4 compatible : no cast like (Foo*)bar=foo; use bar=(Bar*)foo;
49 *
50 * * ALLIANCE_CFLAGS not added anymore to CFLAGS or CXXFLAGS
51 *   by alliance.m4 -> must be added explicitely in each
52 *   Makefile.am
53 *
54 * * remove configure.in (generated by autostuff)
55 *
56 * Revision 1.3  2002/09/30 16:21:00  czo
57 * support/users
58 *
59 * Revision 1.2  2002/03/14 12:34:30  fred
60 * Using new headers
61 *                                                                        *
62 *                                                                              *
63 *******************************************************************************/
64 
65 #ident "@(#)vti logical views parser version 4.04"
66 
67 #include <ctype.h>
68 #include <string.h>
69 #include <stdlib.h>
70 #include <math.h>
71 #include <mut.h>
72 #include <mlo.h>
73 #include <mlu.h>
74 #include <rcn.h>
75 
76 #define LSIZE 16384 /* max line size for vfgets */
77 
78 enum {SYNTAX_ERROR, NET_ERROR, OPEN_ERROR, PARSE_ERROR, CLOSE_ERROR,
79 		NAME_ERROR, CON_SIGDIF, BAD_JOIN};
80 
81 /* rcnet support */
82 struct hns_X {
83 	struct hns_X *NEXT;
84 	long idx;
85 	long rcn;
86 } ;
87 
88 struct hns_I {
89 	struct hns_I *NEXT;
90 	long idx;
91 	loins_list *ins;
92 	long rcn;
93 } ;
94 
95 struct hns_P {
96 	struct hns_P *NEXT;
97 	long idx;
98 	losig_list *sig;
99 	long rcn;
100 } ;
101 
102 /* flag :
103 	 1 : node1 = hns_X
104 	 2 : node1 = hns_I
105 	 4 : node1 = hns_P
106 	 8 : node2 = hns_X
107 	16 : node2 = hns_I
108 	32 : node2 = hns_P
109 */
110 struct hns_W {
111 	struct hns_W *NEXT;
112 	long flag;
113 	void *node1;
114 	void *node2;
115 	float r;
116 	float c;
117 } ;
118 
119 struct hns_X	*HNS_X=NULL;
120 struct hns_I	*HNS_I=NULL;
121 struct hns_P	*HNS_P=NULL;
122 struct hns_W	*HNS_W=NULL;
123 chain_list	*FREE_HNS=NULL;
124 
125 #define HNSRCN         53432
126 #define HNSRCNIDX      53433
127 #define HNSPHCON       53434
128 #define HNSRCNX        53435
129 #define HNSRCNI        53436
130 
131 static void		buildrcn __P(( lofig_list* ));
132 static struct hns_I*	givehnsi __P(( lofig_list*, int, loins_list* ));
133 static struct hns_X*	givehnsx __P(( lofig_list*, int ));
134 static struct hns_P*	givehnsp __P(( losig_list*, int ));
135 static struct hns_I*	add_hns_I __P(( void ));
136 static struct hns_X*	add_hns_X __P(( void ));
137 static struct hns_P*	add_hns_P __P(( void ));
138 static struct hns_W*	add_hns_W __P(( void ));
139 static void		del_hns_X __P(( struct hns_X* ));
140 /* static void		del_hns_P __P(( struct hns_P* )); */
141 static void		del_hns_I __P(( struct hns_I* ));
142 static void		del_hns_W __P(( struct hns_W* ));
143 /* static void		movehnsw __P(( losig_list*, losig_list* )); */
144 static float	stof __P(( char* ));
145 static losig_list* givelosigalias __P(( lofig_list*, chain_list*, int ));
146 static int    compare_alias_join __P(( lofig_list*, chain_list*, chain_list** ));
147 static int    traite_join __P(( lofig_list*, chain_list* ));
148 static void   msg_err __P(( lofig_list*, chain_list*  ));
149 /* static void   debug __P(( lofig_list* )); */
150 
151 
152 /*******************************************************************************
153 * hns_error : generic error routine for vtiloadlofig function                  *
154 *******************************************************************************/
hns_error(type,name,line,string,parameter)155 static void hns_error(type, name, line, string, parameter)
156 int type;
157 long line, parameter;
158 char *name, *string;
159 {
160 	(void)fflush(stdout);
161 	(void)fprintf(stderr, "*** mbk error ***\n");
162 	switch (type) {
163 		case SYNTAX_ERROR :
164 			(void)fprintf(stderr, "syntax error");
165 			break;
166 		case NET_ERROR :
167 			(void)fprintf(stderr, "external connector %s on signal %ld",
168 								string, parameter);
169 			(void)fprintf(stderr, " is internally joined with an other");
170 			(void)fprintf(stderr, " external connector with an other name");
171 			break;
172 		case OPEN_ERROR :
173 			(void)fprintf(stderr, "can't open file : %s", name);
174 			break;
175 		case PARSE_ERROR :
176 			(void)fprintf(stderr, "abnormal parsing for : %s", name);
177 			break;
178 		case CLOSE_ERROR :
179 			(void)fprintf(stderr, "can't close file : %s", name);
180 			break;
181 		case NAME_ERROR :
182 			(void)fprintf(stderr, "name syntax error");
183 			break;
184 		case CON_SIGDIF :
185 			(void)fprintf(stderr, "two connectors with the same name on two different signals");
186 			break;
187 		case BAD_JOIN :
188 			(void)fprintf(stderr, "join of signal %ld connected on two different external connectors %s",parameter,string);
189 			break;
190 	}
191 	if (line)
192 		(void)fprintf(stderr, "\nvtiloadlofig : parsing file %s.%s line %ld\n",
193 						name, IN_LO, line);
194 	else
195 		(void)fprintf(stderr, "\nvtiloadlofig : parsing file %s.%s\n",
196 						name, IN_LO);
197 	EXIT(1);
198 }
199 
200 /*******************************************************************************
201 * vfgets: read a line of a file to a buffer, the line beeing size max or end   *
202 * with a \n. In order to properly treat vti line breaks, the -\n pattern is    *
203 * recognized and ignored                                                       *
204 *******************************************************************************/
vfgets(str,size,iob)205 static char *vfgets(str, size, iob)
206 char *str;
207 int size;
208 FILE *iob;
209 {
210 register char *cs;
211 register int c;
212 
213 	cs = str;
214 	while (--size > 0 && (c = getc(iob)) != EOF) {
215 		if ((*(cs++) = c) == '-') {
216 			if ((c = getc(iob)) == '\n') {
217         /* avant : *cs-- */
218 				cs--;
219 			} else
220 				(void)ungetc(c ,iob);
221 		} else if (c == '\n')
222 			break;
223 	}
224 	*cs = '\0';
225 	return (c == EOF && cs == str) ? (char *)NULL : str;
226 }
227 
228 /*******************************************************************************
229 * shift : shift a float 3 times to give a long in ascii                        *
230 *******************************************************************************/
231 #define shift(pt) \
232 	if (*(pt + 1) == '\0') { \
233 		*pt = '0'; \
234 		*(pt + 1) = '0'; \
235 		*(pt + 2) = '0'; \
236 		*(pt + 3) = '\0'; \
237 	} else if (*(pt + 2) == '\0') { \
238 		*pt = *(pt + 1); \
239 		*(pt + 1) = '0'; \
240 		*(pt + 2) = '0'; \
241 		*(pt + 3) = '\0'; \
242 	} else if (*(pt + 3) == '\0') { \
243 		*pt = *(pt + 1); \
244 		*(pt + 1) = *(pt + 2); \
245 		*(pt + 2) = '0'; \
246 		*(pt + 3) = '\0'; \
247 	} else { \
248 		*pt = *(pt + 1); \
249 		*(pt + 1) = *(pt + 2); \
250 		*(pt + 2) = *(pt + 3); \
251 		*(pt + 3) = '\0'; \
252 	}
253 
254 /*******************************************************************************
255 * stol : convert a string to a long                                            *
256 *******************************************************************************/
stol(token)257 static long	stol(token)
258 char	*token;
259 {
260 register char *pt;
261 
262 	if ((pt = strchr(token, '.')) == (char *)NULL)
263 		return (long)(SCALE_X * atol(token));
264 	else {
265 		shift(pt);
266 		return (long)(SCALE_X * atol(token) / 1000);
267 	}
268 }
269 
270 /*******************************************************************************
271 * stof : convert a string to a float                                           *
272 *******************************************************************************/
stof(token)273 static float stof(token)
274 char	*token;
275 {
276 	char *end;
277 	double f;
278 	f = strtod( token, &end );
279 	if( end == token )
280 		hns_error((int)SYNTAX_ERROR, NULL, (long)0, (char *)NULL, 0L);
281 	return( (float)(f) );
282 }
283 
284 
285 /*******************************************************************************
286 * checkname : check for busses                                                 *
287 *******************************************************************************/
checkname(name)288 static char *checkname(name)
289 char *name;
290 {
291 char *s, *t;
292 
293    s = t = name;
294    while (*t) {
295       if (*t == '[')
296          *t = ' ';
297       else if (*t == ']')
298       {
299          if (*(++t) == '\0') /* ok, it's finished */
300 				goto end;
301          else if (*t == '[') /* multiple array */
302             continue;
303       }
304       *s++ = *t++;
305    }
306 end:
307 	*s = '\0';
308 	return name;
309 }
310 
311 /*******************************************************************************
312 * function env()                                                               *
313 *******************************************************************************/
env(tn,tp)314 static void env(tn, tp)
315 char *tn, *tp;
316 {
317 char *s, *mbkgetenv();
318 
319 	s = mbkgetenv("MBK_VTI_TN");
320 	*tn = s ? *s : 'e';
321 	if (islower((int)*tn))
322 		*tn = toupper(*tn);
323 	s = mbkgetenv("MBK_VTI_TP");
324 	*tp = s ? *s : 'p';
325 	if (islower((int)*tp))
326 		*tp = toupper(*tp);
327 }
328 
329 
330 /*******************************************************************************
331 *        logical parser : vti2mbk                                              *
332 *******************************************************************************/
parse(fig,mode,in,fname)333 static int parse(fig, mode, in, fname)
334 lofig_list *fig;
335 char mode;
336 FILE *in;
337 char *fname;
338 {
339 char line[LSIZE+1];
340 char *t1, *t2, *t3, *t4, *t5;             /* pointers to token on a line */
341 char *t6, *t7, *t8, *t9, *t10, *t11;      /* of vti file */
342 char s[100];  /* intermediate string to process tokens */
343 long l1, l2, l3, l4;  /* results from strtol */
344 float f; /* only used for capacitances */
345 lofig_list *model = (lofig_list *)NULL; /* must be initialized */
346 num_list *ylist = (num_list *)NULL; /* must be initialized */
347 long i = 1L; /* line number */
348 static char tn, tp;
349 losig_list *cursig = NULL; /* current signal for wire */
350 ptype_list *ptl;
351 chain_list *head_join;
352 chain_list *head_sigalias;
353 losig_list      *sigct1,*sigct2;
354 
355 	head_join = head_sigalias = NULL;
356 
357 	if (!tn) /* or tp, who cares? */
358 		env(&tn, &tp);
359 
360 	while (1) {
361 		i++;
362 		if (vfgets(line, LSIZE, in) == (char *)NULL)
363 			hns_error((int)SYNTAX_ERROR, fname, (long)i, (char *)NULL, 0L);
364 		switch (line[0]) {
365 			case '#' : /* comment */
366 			case '\{' : /* comment */
367 			case ' ' : /* empty line in vti file */
368 			case ';' : /* empty line in vti file */
369 			case 'A' :
370 			case 'B' :
371 				break;
372 			case 'C' : /* C INT NOP NOP cap INT INT ; */
373 				if (mode != 'P') {
374                                         loctc_list *ptctc;
375 
376 					t1 = strtok(line + 2, " \n\t\"");
377 					l1 = atol(t1);
378 					t2 = strtok((char *)NULL, " \n\t\"");
379 					t3 = strtok((char *)NULL, " \n\t\"");
380 					t4 = strtok((char *)NULL, " \n\t\"");
381 					(void)strcpy(s, t4);
382 					f = atof(s);
383 					t5 = strtok((char *)NULL, " \n\t\"");
384 					l3 = atol(t5);
385 					t6 = strtok((char *)NULL, " \n\t\"");
386 					l4 = atol(t6);
387 					/* capacitance :
388 					   units are picofarads inside vti logical formats.
389 					   add capacitance on both signals.
390 						0 is a linear, wire, capacitance,
391 						1 is a grid capacitance,
392 					   2-5 are sidewall and surface diffusion capacitances
393 					   6 is diaphonic capacitances. */
394 					if (l1 != 1) {
395 
396             sigct1 = givelosigalias(fig, head_sigalias, (long)l3);
397             sigct2 = givelosigalias(fig, head_sigalias, (long)l4);
398 
399             if( !sigct1->PRCN )
400               addlorcnet( sigct1 );
401 
402             if( !sigct2->PRCN )
403               addlorcnet( sigct2 );
404 
405             if( ( ptctc = getloctc( sigct1, 0, sigct2, 0 ) ) )
406               ptctc->CAPA = ptctc->CAPA + f;
407             else
408               addloctc( sigct1, 0, sigct2, 0, f );
409 
410             addcapa( sigct1, f );
411             addcapa( sigct2, f );
412 					}
413 				}
414 				break;
415 			case 'E': /* E ; */
416 				{
417 				locon_list	*c1;
418 				ptype_list	*ptl;
419 				num_list	*pn;
420 				lofig_list	*ptmodel;
421 				struct hns_X	*effx;
422 				struct hns_X	*effscanx;
423 				chain_list	*scan_head_join;
424                                 losig_list      *ptsig;
425                                 locon_list      *ptcon;
426 
427 				lofigchain( fig );
428 
429 				for (c1 = fig->LOCON; c1; c1 = c1->NEXT) {
430 					ptl = getptype(c1->USER,HNSRCN);
431 					ptl->DATA = reverse( ptl->DATA );
432 				}
433 
434 				if( !compare_alias_join( fig, head_sigalias, &head_join ) ) {
435 					hns_error((int)CON_SIGDIF, fname, (long)i, (char *)NULL, 0L);
436 				}
437 
438 				if( !traite_join( fig, head_join ) ) {
439 					hns_error((int)SYNTAX_ERROR, fname, (long)i, (char *)NULL, 0L);
440 				}
441 
442 				/* Comme la fonction traite_join peut avoir deplacer des connecteurs ( passe d'un signal a un autre ), on refait un lofigchain
443 				   pour tout remettre a jour. Le lofigchain fait un nettoyage prealable, donc pas de problemes... */
444 
445 				lofigchain(fig);
446 
447 				/* On nettoie les join */
448 				for( scan_head_join = head_join; scan_head_join; scan_head_join = scan_head_join->NEXT ) {
449 					freechain( (chain_list*)(scan_head_join->DATA) );
450 				}
451 				freechain( head_join );
452 
453 				/* destroy the trhu routes connectors and signals */
454 				for (pn = ylist; pn; pn = pn->NEXT)
455                                 {
456                                   ptsig = getlosig( fig, pn->DATA );
457                                   ptl = getptype( ptsig->USER, LOFIGCHAIN );
458                                   if( !ptl->DATA )
459                                     dellosig( fig, pn->DATA );
460                                   else
461                                   {
462                                     ptcon = (locon_list*)(((chain_list*)(ptl->DATA))->DATA);
463                                     if( !((chain_list*)(ptl->DATA))->NEXT && ptcon->ROOT == fig )
464                                     {
465 			              if( (ptl = getptype( ptcon->USER, HNSRCN )) )
466                                       {
467 				        freechain( (chain_list*)(ptl->DATA) );
468 				        ptcon->USER = delptype( ptcon->USER, HNSRCN );
469                                       }
470                                       dellocon( fig, ptcon->NAME );
471                                       /*
472                                       for (delete = &fig->LOCON; *delete != NULL; )
473 					if ((*delete)->SIG->INDEX == pn->DATA)
474                                         {
475 					  c1 = (*delete)->NEXT;
476 					  if( (ptl = getptype( (*delete)->USER,HNSRCN )))
477                                           {
478 					    freechain( (chain_list*)(ptl->DATA));
479 					    (*delete)->USER = delptype( (*delete)->USER, HNSRCN );
480 					  }
481 					  mbkfree((void *)*delete);
482 					  *delete = c1;
483 					}
484                                         else
485  					  delete = &(*delete)->NEXT;
486                                       */
487 
488                                       dellosig( fig, pn->DATA );
489                                     }
490                                     else
491                                     {
492                                       fprintf( stderr, "*** mbkvti warning : Can't delete thru routes %ld.\n", ptsig->INDEX );
493                                     }
494                                   }
495                                 }
496 
497                                 freenum(ylist);
498 
499 				buildrcn(fig);
500 
501 				for( ptmodel =  model ; ptmodel; ptmodel = ptmodel->NEXT ) {
502 					freechain( (chain_list*)( getptype(ptmodel->USER, HNSPHCON)->DATA ) );
503 					for(c1 = ptmodel->LOCON; c1; c1 = c1->NEXT ) {
504 						effx = NULL;
505 						for( effscanx = (struct hns_X*)( getptype( c1->USER,HNSRCN )->DATA );
506 						     effscanx; effscanx = effscanx->NEXT ) {
507 							if( effx )
508 								del_hns_X(effx);
509 							effx = effscanx;
510 						}
511 						if( effx )
512 							del_hns_X(effx);
513 						c1->USER = delptype(c1->USER, HNSRCN);
514 					}
515 				}
516 				freelomodel(model);
517 
518 				/* successfull exit */
519 				return 0;
520 				}
521 			case 'G' : /* G INT name ; */
522 				if (mode != 'P') {
523 				losig_list *ptsig;
524 					t1 = strtok(line + 2, " \n\t\"@");
525 					l1 = atol(t1);
526 					t2 = strtok((char *)NULL, " \n\t\"@;");
527 					for (ptsig = fig->LOSIG; ptsig; ptsig = ptsig->NEXT)
528 						if (ptsig->INDEX == (long)l1) {
529 							ptsig->NAMECHAIN = addchain(ptsig->NAMECHAIN,(void *)namealloc(checkname(t2)));
530 							break;
531 						}
532 					if (ptsig == (losig_list *)NULL)
533 						(void)addlosig(fig, (long)l1, addchain((chain_list *)NULL,
534 											(void *)t2), INTERNAL);
535 				}
536 				break;
537 			case 'H' : /* H INT ; */
538 				break;
539 			case 'I' : /* I name name name | numlist | numlist ; */
540 				if (mode != 'P') {
541 				num_list *pnlist1 = (num_list *)NULL, *pnlist2 = (num_list *)NULL;
542 				char s2[100];
543 				char s3[100];
544 
545 					if (strchr(line + 2, ';') != (char *)NULL) {
546 						t1 = strtok(line + 2, " \n\t\"@");
547 						t2 = strtok((char *)NULL, " \n\t\"@");
548 						(void)strcpy(s2, t2);
549 						t3 = strtok((char *)NULL, " \n\t\"@");
550 						(void)strcpy(s3, t3);
551 						t4 = strtok((char *)NULL, " \n\t\"@");
552 						t5 = strtok((char *)NULL, " \n\t\"@");
553 						if (*t5 == '|')
554 							pnlist1 = (num_list *)NULL;
555 						else {
556 							if (*t5 == '*')
557 								pnlist1 = addnum((num_list *)NULL, 0L);
558 							else
559 								pnlist1 = addnum((num_list *)NULL, atol(t5));
560 							while (*(t5 = strtok((char *)NULL, " \n\t\"@")) != '|') {
561 								if (*t5 == '*')
562 									pnlist1 = addnum(pnlist1, 0L);
563 								else
564 									pnlist1 = addnum(pnlist1, atol(t5));
565 							}
566 						}
567 						t6 = strtok((char *)NULL, " \n\t\"@;");
568 						if (t6 == (char *)NULL)
569 							pnlist2 = (num_list *)NULL;
570 						else {
571 							if (*t6 == '*')
572 								pnlist2 = addnum((num_list *)NULL, 0L);
573 							else
574 								pnlist2 = addnum((num_list *)NULL, atol(t6));
575 							while ((t6 = strtok((char *)NULL, " \n\t\"@;"))
576 									!= (char *)NULL) {
577 								if (*t6 == '*')
578 									pnlist2 = addnum(pnlist2, 0L);
579 								else
580 									pnlist2 = addnum(pnlist2, atol(t6));
581 							}
582 						}
583 					} else
584 						hns_error((int)SYNTAX_ERROR, fname, (long)i, (char *)NULL, 0L);
585 
586 					{
587 					lofig_list	*ptmodel;
588 					chain_list	*phcon,*ch1,*ch2,*chainsig;
589 					num_list	*n1,*n2;
590 					losig_list	*ptsig;
591 					locon_list	*cm, *ci;
592 					loins_list	*ptins;
593 					struct hns_X	*scanx;
594 					struct hns_I	*newi;
595 					chain_list	*headi;
596 
597 					ptmodel = getlomodel(model,s2);
598 					phcon = (chain_list*)( (getptype(ptmodel->USER,HNSPHCON))->DATA );
599 					pnlist2 = (num_list*)reverse((chain_list*)pnlist2);
600 					chainsig = NULL;
601 
602 					for(ch1 = phcon, n1 = pnlist2; ch1 && n1; ch1 = ch1->NEXT, n1 = n1->NEXT ) {
603 						/* Verify all signals on locon are the same */
604 						for(ch2 = ch1->NEXT, n2 = n1->NEXT ; ch2 && n2 ; ch2 = ch2->NEXT, n2 = n2->NEXT ) {
605 							if( (ch1->DATA == ch2->DATA) && (n1->DATA != n2->DATA) )
606 								hns_error((int)SYNTAX_ERROR, fname, (long)i, (char*)NULL, 0L);
607 						}
608 						/* Get one signal per locon */
609 						for(ch2 = phcon; ch2!=ch1; ch2 = ch2->NEXT ) {
610 							if(ch2->DATA == ch1->DATA)
611 								break;
612 						}
613 						if(ch1 == ch2) {
614 							ptsig = givelosigalias( fig, head_sigalias, n1->DATA );
615 							chainsig = addchain(chainsig,(void*)ptsig);
616 						}
617 					}
618 					/* On recupere la liste des signaux dans l'ordre inverse ou ils apparaissent dans le
619 					   fichier, mais dans l'ordre des connecteurs du modele */
620 					ptins = addloins(fig,s3,ptmodel,chainsig);
621 					freenum(pnlist2);
622 					freenum(pnlist1); /* no more parameters */
623 
624 					for( cm = ptmodel->LOCON; cm; cm = cm->NEXT) {
625 						for( ci = ptins->LOCON; ci; ci = ci->NEXT ) {
626 							if( ci->NAME == cm->NAME )
627 								break;
628 						}
629 						headi = NULL;
630 						for(scanx=(struct hns_X*)( getptype(cm->USER,HNSRCN)->DATA );
631 						    scanx;
632 						    scanx = scanx->NEXT) {
633 							newi  = givehnsi(fig, scanx->idx,ptins);
634 							headi = addchain(headi,newi);
635 						}
636 						ci->USER = addptype(ci->USER,HNSRCN,headi);
637 					}
638 					}
639 				}
640 				break;
641 			case 'J' : /* J INT INT ; */
642 				{
643 					losig_list	*s1, *s2;
644 					chain_list	*scan_head_join1;
645 					chain_list	*scan_head_join2;
646 					chain_list	*scan_join;
647 
648 					t1 = strtok( line + 2, " \n\t\"@" );
649 					s1 = givelosig( fig, atol(t1) );
650 
651 					for( scan_head_join1 = head_join; scan_head_join1 ; scan_head_join1 = scan_head_join1->NEXT ) {
652 						for( scan_join = (chain_list*)(scan_head_join1->DATA); scan_join; scan_join = scan_join->NEXT ) {
653 							if( s1 == scan_join->DATA )
654 								break;
655 						}
656 						if( scan_join )
657 							break;
658 					}
659 
660 					if( ! scan_head_join1 ) {
661 						head_join = addchain( head_join, addchain( NULL, s1 ) );
662 						scan_head_join1 = head_join;
663 					}
664 					/* scan_head_join1 est la liste qui contient le premier signal rencontre */
665 
666 					while( (t1 = strtok( NULL, " \n\t\"@" ) ) )
667 					{
668 						if( strcmp(t1,";")==0 )
669 							break;
670 						s2 = givelosig( fig, atol(t1) );
671 
672 						for( scan_head_join2 = head_join; scan_head_join2 ; scan_head_join2 = scan_head_join2->NEXT ) {
673 							for( scan_join = (chain_list*)(scan_head_join2->DATA); scan_join; scan_join = scan_join->NEXT ) {
674 								if( s2 == scan_join->DATA )
675 									break;
676 							}
677 							if( scan_join )
678 								break;
679 						}
680 
681 						if( !scan_head_join2 ) {
682 							scan_head_join1->DATA = addchain( (chain_list*)(scan_head_join1->DATA), s2 );
683 						}
684 						else
685 						if( scan_head_join1 != scan_head_join2 ) {
686 							for( scan_join = (chain_list*)(scan_head_join2->DATA); scan_join; scan_join = scan_join->NEXT ) {
687 								scan_head_join1->DATA = addchain( (chain_list*)(scan_head_join1->DATA), scan_join->DATA );
688 							}
689 							freechain( (chain_list*)(scan_head_join2->DATA) );
690 							head_join = delchain( head_join, scan_head_join2 );
691 						}
692 					}
693 				}
694 				break;
695 			case 'M' : /* M name name | strlist | strlist | numlist ; */
696 				if (mode != 'P') {
697 				chain_list *slist2 = (chain_list *)NULL, *pt;
698 				num_list *llist3 = NULL, *ptn;
699 				chain_list *ptv;
700 				locon_list *ptcon;
701 				struct hns_X	*headX;
702 
703 					t1 = strtok(line + 2, " \n\t\"@");
704 					t2 = strtok((char *)NULL, " \n\t\"@");
705 					(void)strcpy(s, t2);
706 					t3 = strtok((char *)NULL, " \n\t\"@");     /* the seperator | */
707 
708 					if (*t3 != '|')
709 						hns_error((int)SYNTAX_ERROR, fname, (long)i, (char *)NULL, 0L);
710 
711 					/* the first strlist is to be skipped */
712 					do {
713 						t4 = strtok((char *)NULL, " \n\t\"@");
714 						if (t4 == (char *)NULL)
715 							hns_error((int)SYNTAX_ERROR, fname, (long)i, (char *)NULL, 0L);
716 					} while(*t4 != '|');
717 
718 					/* the second one contains the connectors name and order */
719 					t4 = strtok((char *)NULL, " \n\t\"@");
720 					while(*t4 != '|') {
721 						if (t4 == (char *)NULL)
722 							hns_error((int)SYNTAX_ERROR, fname, (long)i, (char *)NULL, 0L);
723 						slist2 = addchain(slist2, (void *)namealloc(checkname(t4)));
724 						t4 = strtok((char *)NULL, " \n\t\"@");
725 					}
726 
727 					/* the third  one contains the connectors ident */
728 					t4 = strtok((char *)NULL, " \n\t\"@");
729 					while(*t4 != ';') {
730 						if (t4 == (char *)NULL)
731 							hns_error((int)SYNTAX_ERROR, fname, (long)i, (char *)NULL, 0L);
732 						llist3 = addnum(llist3,atol(t4));
733 						t4 = strtok((char *)NULL, " \n\t\"@");
734 					}
735 
736 					model = addlomodel(model, s);
737 					llist3 = (num_list*)reverse((chain_list*)llist3);
738 					slist2 = reverse(slist2);
739 
740 					for (pt = slist2, ptn = llist3; pt && ptn ; pt = pt->NEXT, ptn = ptn->NEXT) {
741 
742 						headX       = add_hns_X();
743 						headX->NEXT = NULL;
744 						headX->idx  = ptn->DATA;
745 						headX->rcn  = 0;
746 
747 						for(ptv = slist2; ptv != pt; ptv = ptv->NEXT) {
748 							if( pt->DATA == ptv->DATA )
749 								break;
750 						}
751 						if(pt == ptv) {
752 							ptcon       = addlocon(model, (char *)pt->DATA,(losig_list *)NULL, 'X');
753 							ptcon->USER = addptype(ptcon->USER, HNSRCN, headX);
754 						}
755 						else {
756 							ptcon       = getlocon(model,(char*)(pt->DATA));
757 							ptl         = getptype(ptcon->USER,HNSRCN);
758 							headX->NEXT = (struct hns_X*)( ptl->DATA );
759 							ptl->DATA   = headX;
760 						}
761 					}
762 
763 					if( pt || ptn )
764 						hns_error((int)PARSE_ERROR, fname, (long)i, (char *)NULL, 0L);
765 
766 					freenum(llist3);
767 					model->USER = addptype(model->USER,HNSPHCON,slist2);
768 				}
769 				break;
770 			case 'N' : /* N INT name ; */
771 				if (mode != 'P') {
772 					losig_list *ptsig;
773 					t1 = strtok(line + 2, " \n\t\"@");
774 					l1 = atol(t1);
775 					t2 = strtok((char *)NULL, " \n\t\"@;");
776 					ptsig = givelosigalias(fig, head_sigalias, (long)l1);
777 					ptsig->NAMECHAIN = addchain(ptsig->NAMECHAIN,(void *)namealloc(checkname(t2)));
778 					cursig = givelosig( fig, (long)l1 );
779 				}
780 				break;
781 			case 'P' : /* P INT name num ; */
782 				if (mode != 'C') {
783 					t1 = strtok(line + 2, " \n\t\"@");
784 					t2 = strtok((char *)NULL, " \n\t\"@");
785 					t3 = strtok((char *)NULL, " \n\t\"@;");
786 					/* let's keep it, just in case ... */
787 				}
788 				break;
789 
790 			case 'T' : /* T name name name num num cap INT INT INT INT ; */
791 				if (mode != 'P') {
792 				char type;
793 					t1 = strtok(line + 2, " \n\t\"@");
794 					t2 = strtok((char *)NULL, " \n\t\"@[");
795 					t3 = strtok((char *)NULL, " \n\t\"@[,");
796 					t4 = strtok((char *)NULL, " \n\t\"@,]");
797 					t5 = strtok((char *)NULL, " \n\t\"@]");
798 					t6 = strtok((char *)NULL, " \n\t\"@");
799 					t7 = strtok((char *)NULL, " \n\t\"@");
800 					t8 = strtok((char *)NULL, " \n\t\"@");
801 					t9 = strtok((char *)NULL, " \n\t\"@");
802 					if (islower((int)*t1))
803 						*t1 = toupper(*t1);
804 					type = (*t1 == tn) ? TRANSN : TRANSP;
805 					(void)strcpy(s, t3);
806 					l1 = stol(s);
807 					(void)strcpy(s, t4);
808 					l2 = stol(s);
809 					if ((t10 = strtok((char *)NULL, " \n\t\"@;")) == (char *)NULL) {
810 					losig_list *ptgrid;
811 						ptgrid = givelosigalias(fig, head_sigalias, atol(t6));
812 						(void)addlotrs(fig, type, 0L, 0L,
813 											(unsigned short)l1, (unsigned short)l2,
814 											0, 0, 0, 0,
815 											ptgrid, givelosigalias(fig, head_sigalias, atol(t7)),
816 											givelosigalias(fig, head_sigalias, atol(t8)), givelosigalias(fig, head_sigalias, atol(t9) ), NULL);
817 						/* do not add grid capacatance anymore
818 						(void)addcapa(ptgrid, atof(t5));
819 						*/
820 					}
821 					else { /* T name name [num,num] num num cap INT INT INT INT; */
822 					losig_list *ptgrid;
823 						t11 = strtok((char *)NULL, " \n\t\"@;");
824 						ptgrid = givelosigalias(fig, head_sigalias, atol(t8));
825 						(void)strcpy(s, t5);
826 						l3 = stol(s);
827 						(void)strcpy(s, t6);
828 						l4 = stol(s);
829 						(void)addlotrs(fig, type, l1, l2,
830 									(unsigned short)l3, (unsigned short)l4,
831 									0, 0, 0, 0,
832 									ptgrid, givelosigalias(fig, head_sigalias, atol(t9)),
833 									givelosigalias(fig, head_sigalias, atol(t10)), givelosigalias(fig, head_sigalias, atol(t11) ), NULL);
834 						/* do not add grid capacatance anymore
835 						(void)addcapa(ptgrid, atof(t7));
836 						*/
837 					}
838 				}
839 				break;
840 
841 			case 'W' : /* W node1 node2 R C */
842 				if (mode != 'P') {
843 				char           *separ;
844 				struct hns_X   *pt_X;
845 				struct hns_P   *pt_P;
846 				struct hns_I   *pt_I;
847 				struct hns_W   *pt_W;
848 				struct hns_W   *head_W;
849 
850 				separ=" \n\t\"@";
851 				ptl = getptype(cursig->USER,HNSRCN);
852 				if(!ptl) {
853 					cursig->USER = addptype(cursig->USER,HNSRCN,NULL);
854 					ptl          = cursig->USER;
855 				}
856 				head_W = ( struct hns_W* )( ptl->DATA );
857 
858 				pt_W = add_hns_W();
859 
860 				t1 = strtok(line + 2, separ);
861 				if( strcasecmp(t1,"P")==0 ) {
862 					t2             = strtok((char*)NULL,separ);
863 					l1             = atol(t2);
864 					pt_P           = givehnsp(cursig, l1);
865 					pt_W->flag     = pt_W->flag | 4;
866 					pt_W->node1    = pt_P;
867 				}
868 				else
869 				if( strcasecmp(t1,"I")==0 ) {
870 					t2             = strtok((char*)NULL,separ);
871 					t3             = strtok((char*)NULL,separ);
872 					l1             = atol(t3);
873 
874 					pt_I           = givehnsi(fig, l1,getloins(fig,t2));
875 					pt_W->flag     = pt_W->flag | 2;
876 					pt_W->node1    = pt_I;
877 				}
878 				else
879 				if( strcasecmp(t1,"X")==0 ) {
880 					t2             = strtok((char*)NULL,separ);
881 					l1             = atol(t2);
882 
883 					pt_X           = givehnsx(fig, l1);
884 					pt_W->flag     = pt_W->flag | 1;
885 					pt_W->node1    = pt_X;
886 				}
887 				else {
888 					hns_error((int)SYNTAX_ERROR, fname, (long)i, (char *)NULL, 0L);
889 				}
890 				t1 = strtok((char*)NULL, separ);
891 				if( strcasecmp(t1,"P")==0 ) {
892 					t2             = strtok((char*)NULL,separ);
893 					l1             = atol(t2);
894 
895 					pt_P           = givehnsp(cursig, l1);
896 					pt_W->flag     = pt_W->flag | 32;
897 					pt_W->node2    = pt_P;
898 				}
899 				else
900 				if( strcasecmp(t1,"I")==0 ) {
901 					t2             = strtok((char*)NULL,separ);
902 					t3             = strtok((char*)NULL,separ);
903 					l1             = atol(t3);
904 
905 					pt_I           = givehnsi(fig, l1,getloins(fig,t2));
906 					pt_W->flag     = pt_W->flag | 16;
907 					pt_W->node2    = pt_I;
908 				}
909 				else
910 				if( strcasecmp(t1,"X")==0 ) {
911 					t2             = strtok((char*)NULL,separ);
912 					l1             = atol(t2);
913 
914 					pt_X           = givehnsx(fig, l1);
915 					pt_W->flag     = pt_W->flag | 8;
916 					pt_W->node2    = pt_X;
917 				}
918 				else {
919 					hns_error((int)SYNTAX_ERROR, fname, (long)i, (char *)NULL, 0L);
920 				}
921 
922 				t1         = strtok( NULL, separ);
923 				pt_W->r    = stof(t1);
924 				t1         = strtok( NULL, separ);
925 				pt_W->c    = stof(t1);
926 				pt_W->NEXT = head_W;
927 				head_W     = pt_W;
928 				ptl->DATA  = head_W;
929 				}
930 				break;
931 
932 			case 'X' : /* X INT bof name ; */
933 				{
934 					locon_list	*ptcon;
935 					losig_list	*ptsig;
936 					losig_list	*sig2;
937 					char		*conname;
938 					struct hns_X	*headX;
939 					ptype_list	*ptl;
940 					chain_list	*scan_head_sigalias, *scan_sigalias;
941 
942 					t1 = strtok(line + 2, " \n\t\"@");
943 					l1 = atol(t1);
944 					t2 = strtok((char *)NULL, " \n\t\"@");
945 					t3 = strtok((char *)NULL, " \n\t\"@;");
946 
947 					headX= givehnsx(fig, atol(t2));
948 
949 					conname = namealloc(checkname(t3));
950 
951 					/* Chaque locon possede un nom unique */
952 
953 					for(ptcon = fig->LOCON; ptcon; ptcon = ptcon->NEXT) {
954 						if( ptcon->NAME == conname )
955 							break;
956 					}
957 
958 					if( ptcon ) {
959 						if ( ptcon->SIG->INDEX != l1 ) {
960 							sig2 = givelosig(fig, l1);
961                                                         sig2->TYPE = EXTERNAL;
962 							for( scan_head_sigalias = head_sigalias; scan_head_sigalias; scan_head_sigalias = scan_head_sigalias->NEXT ) {
963 								for( scan_sigalias = (chain_list*)(scan_head_sigalias->DATA); scan_sigalias; scan_sigalias = scan_sigalias->NEXT ) {
964 									if( (losig_list*)( scan_sigalias->DATA ) == ptcon->SIG )
965 										break;
966 								}
967 								if( scan_sigalias )
968 									break;
969 							}
970 							if( !scan_head_sigalias ) {
971 								/* Attention : l'ordre est important : le signal qui existait avant doit etre
972 								   en fin de liste */
973 								head_sigalias = addchain( head_sigalias, addchain( addchain(NULL,ptcon->SIG), sig2 ));
974 							}
975 							else {
976 								for( scan_sigalias = (chain_list*)(scan_head_sigalias->DATA); scan_sigalias; scan_sigalias = scan_sigalias->NEXT ) {
977 									if( (losig_list*)( scan_sigalias->DATA ) == sig2 )
978 										break;
979 								}
980 								if( !scan_sigalias ) {
981 									scan_head_sigalias->DATA = addchain( (chain_list*)(scan_head_sigalias->DATA), sig2);
982 								}
983 							}
984 						}
985 
986 						/* Si on est en mode 'C', on peut se retrouver ici sans avoir de ptype */
987 						if( mode == 'C' )
988 						{
989 							ptl       = getptype(ptcon->USER,HNSRCN);
990 							if( !ptl )
991 							{
992 							  /* C'est la 1ere fois qu'on tombe sur ce locon, on lui enleve tous les connecteurs physiques
993 								 * qu'il avait */
994 							  while(ptcon->PNODE)
995 								  delloconnode( ptcon, ptcon->PNODE->DATA);
996 								ptl = ptcon->USER = addptype( ptcon->USER, HNSRCN, NULL );
997 							}
998 						}
999 						else
1000 							ptl       = getptype(ptcon->USER,HNSRCN);
1001 
1002 						ptl->DATA = addchain( (chain_list*)(ptl->DATA),headX);
1003 					}
1004 					else {
1005 						/* Si c'est il existe deja un connecteur sur ce signal, le addlosig terminera le programme. */
1006 						ptsig       = addlosig(fig, (long)l1, addchain((chain_list *)NULL,
1007 					  	                     (void *)conname), EXTERNAL);
1008 						ptcon       = addlocon( fig, conname, ptsig, 'X');
1009 						ptcon->USER = addptype( ptcon->USER, HNSRCN, addchain(NULL,headX) );
1010 					}
1011 				}
1012 
1013 				break;
1014 			case 'Y' : /* Y INT INT [ num , num ] [ num , num ] ; */
1015               break;
1016               /* t1 = strtok(line + 2, " \n\t\"@"); */
1017               /* t2 = strtok((char *)NULL, " \n\t\"@;"); */
1018               /* l2 = atol(t2); */
1019               /* ylist = addnum(ylist, l2); /\* create a list of thru routes *\/ */
1020               /* break; */
1021 			case 'Z' : /* Z INT name INT cap INT num num ; */
1022 				break;
1023 			default :
1024 				hns_error((int)SYNTAX_ERROR, fname, (long)i, (char *)NULL, 0L);
1025 				break;
1026 		}
1027 	}
1028 }
1029 
1030 /*******************************************************************************
1031 * unique function accesible from this file                                     *
1032 *******************************************************************************/
vtiloadlofig(ptfig,figname,mode)1033 void vtiloadlofig(ptfig, figname, mode)
1034 lofig_list *ptfig;
1035 char *figname;
1036 char mode;
1037 {
1038 FILE *in;
1039 
1040 	/* opening file */
1041 	if ((in = mbkfopen(figname, IN_LO, READ_TEXT)) == (FILE *)NULL)
1042 		hns_error((int)OPEN_ERROR, figname, 0L, (char *)NULL, 0L);
1043 
1044 	if (TRACE_MODE == 'Y')
1045 		(void)printf("\n--- mbk --- parsing file : %s.%s in mode %c\n",
1046 		     		figname, IN_LO, mode);
1047 
1048 	/* parsing */
1049 	if (parse(ptfig, mode, in, figname))
1050 		hns_error((int)PARSE_ERROR, figname, 0L, (char *)NULL, 0L);
1051 
1052 	if (fclose(in))
1053 		hns_error((int)CLOSE_ERROR, figname, 0L, (char *)NULL, 0L);
1054 
1055 	(void)strcpy(PARSER_INFO, "@(#)vti logical views parser version 4.04");
1056 }
1057 
add_hns_X()1058 static struct hns_X* add_hns_X()
1059 {
1060 	struct hns_X *head;
1061 	int i;
1062 
1063 	if(!HNS_X)
1064 	{
1065 		HNS_X = (struct hns_X*)mbkalloc(sizeof(struct hns_X)*64);
1066 		FREE_HNS = addchain(FREE_HNS,HNS_X);
1067 
1068 		for(i=0;i<=62;i++)
1069 			HNS_X[i].NEXT=&(HNS_X[i+1]);
1070 		HNS_X[63].NEXT=NULL;
1071 	}
1072 	head       = HNS_X;
1073 	HNS_X      = HNS_X->NEXT;
1074 
1075 	head->NEXT = NULL;
1076 	head->idx  = 0;
1077 	head->rcn  = 0;
1078 
1079 	return(head);
1080 }
1081 
del_hns_X(ptx)1082 static void del_hns_X( ptx )
1083 struct hns_X *ptx;
1084 {
1085 	ptx->NEXT = HNS_X;
1086 	HNS_X = ptx;
1087 }
1088 
add_hns_I()1089 static struct hns_I* add_hns_I()
1090 {
1091 	struct hns_I *head;
1092 	int i;
1093 
1094 	if(!HNS_I)
1095 	{
1096 		HNS_I = (struct hns_I*)mbkalloc(sizeof(struct hns_I)*64);
1097 		FREE_HNS = addchain(FREE_HNS,HNS_I);
1098 
1099 		for(i=0;i<=62;i++)
1100 			HNS_I[i].NEXT=&(HNS_I[i+1]);
1101 		HNS_I[63].NEXT=NULL;
1102 	}
1103 	head       = HNS_I;
1104 	HNS_I      = HNS_I->NEXT;
1105 
1106 	head->NEXT = NULL;
1107 	head->idx  = 0;
1108 	head->rcn  = 0;
1109 	head->ins  = NULL;
1110 
1111 	return(head);
1112 }
1113 
del_hns_I(pti)1114 static void del_hns_I( pti )
1115 struct hns_I *pti;
1116 {
1117 	pti->NEXT = HNS_I;
1118 	HNS_I = pti;
1119 }
1120 
add_hns_P()1121 static struct hns_P* add_hns_P()
1122 {
1123 	struct hns_P *head;
1124 	int i;
1125 
1126 	if(!HNS_P)
1127 	{
1128 		HNS_P = (struct hns_P*)mbkalloc(sizeof(struct hns_P)*64);
1129 		FREE_HNS = addchain(FREE_HNS,HNS_P);
1130 
1131 		for(i=0;i<=62;i++)
1132 			HNS_P[i].NEXT=&(HNS_P[i+1]);
1133 		HNS_P[63].NEXT=NULL;
1134 	}
1135 	head       = HNS_P;
1136 	HNS_P      = HNS_P->NEXT;
1137 
1138 	head->NEXT = NULL;
1139 	head->idx  = 0;
1140     head->sig  = NULL;
1141 	head->rcn  = 0;
1142 
1143 	return(head);
1144 }
1145 
1146 /*
1147 static void del_hns_P( ptp )
1148 struct hns_P *ptp;
1149 {
1150 	ptp->NEXT = HNS_P;
1151 	HNS_P = ptp;
1152 }
1153 */
1154 
add_hns_W()1155 static struct hns_W* add_hns_W()
1156 {
1157 	struct hns_W *head;
1158 	int i;
1159 
1160 	if(!HNS_W)
1161 	{
1162 		HNS_W = (struct hns_W*)mbkalloc(sizeof(struct hns_W)*64);
1163 		FREE_HNS = addchain(FREE_HNS,HNS_W);
1164 
1165 		for(i=0;i<=62;i++)
1166 			HNS_W[i].NEXT=&(HNS_W[i+1]);
1167 		HNS_W[63].NEXT=NULL;
1168 	}
1169 	head        = HNS_W;
1170 	HNS_W       = HNS_W->NEXT;
1171 
1172 	head->NEXT  = NULL;
1173 	head->flag  = 0;
1174 	head->node1 = NULL;
1175 	head->node2 = NULL;
1176 	head->r     = 0.0;
1177 	head->c     = 0.0;
1178 
1179 	return(head);
1180 }
1181 
del_hns_W(ptw)1182 static void del_hns_W( ptw )
1183 struct hns_W *ptw;
1184 {
1185 	ptw->NEXT = HNS_W;
1186 	HNS_W = ptw;
1187 }
1188 
givehnsp(ptsig,index)1189 static struct hns_P* givehnsp( ptsig, index )
1190 losig_list	*ptsig;
1191 int		 index;
1192 {
1193 	ptype_list	*ptl;
1194 	struct hns_P	*ptp;
1195 	struct hns_W	*scanw;
1196 
1197 	ptl = getptype(ptsig->USER, HNSRCN);
1198 	if( !ptl ) {
1199 		ptp      = add_hns_P();
1200 		ptp->idx = index;
1201 		ptp->sig = ptsig;
1202 		ptp->rcn = 0;
1203 		return(ptp);
1204 	}
1205 
1206 	for(scanw = (struct hns_W*)( getptype( ptsig->USER, HNSRCN )->DATA ); scanw; scanw = scanw->NEXT ) {
1207 		if(scanw->flag & 4) {
1208 			ptp = (struct hns_P*)(scanw->node1);
1209 			if( ptp->idx == index && ptp->sig == ptsig )
1210 				return(ptp);
1211 		}
1212 		if(scanw->flag & 32) {
1213 			ptp = (struct hns_P*)(scanw->node2);
1214 			if( ptp->idx == index  && ptp->sig == ptsig )
1215 				return(ptp);
1216 		}
1217 	}
1218 	ptp      = add_hns_P();
1219 	ptp->idx = index;
1220 	ptp->sig = ptsig;
1221 	ptp->rcn = 0;
1222 	return(ptp);
1223 }
1224 
givehnsx(ptfig,index)1225 static struct hns_X* givehnsx(ptfig, index)
1226 lofig_list		*ptfig;
1227 int	index;
1228 {
1229 	ptype_list	*ptl;
1230 	struct hns_X	*headx, *scanx;
1231 
1232 	ptl = getptype(	ptfig->USER, HNSRCNX );
1233 	if( !ptl ) {
1234 		ptfig->USER = addptype( ptfig->USER, HNSRCNX, NULL );
1235 		ptl = ptfig->USER;
1236 	}
1237 	headx = (struct hns_X*)(ptl->DATA);
1238 
1239 	for( scanx = headx; scanx; scanx = scanx->NEXT ) {
1240 		if (scanx->idx == index )
1241 			break;
1242 	}
1243 
1244 	if(!scanx) {
1245 		scanx       = add_hns_X();
1246 		scanx->idx  = index;
1247 		scanx->NEXT = headx;
1248 		scanx->rcn  = 0;
1249 		headx       = scanx;
1250 		ptl->DATA = headx;
1251 	}
1252 
1253 	return(scanx);
1254 }
1255 
givehnsi(ptfig,index,ptins)1256 static struct hns_I*  givehnsi(ptfig, index, ptins)
1257 lofig_list		*ptfig;
1258 int			index;
1259 loins_list		*ptins;
1260 {
1261 	ptype_list	*ptl;
1262 	struct hns_I	*headi, *scani;
1263 
1264 	ptl = getptype(	ptfig->USER, HNSRCNI );
1265 	if( !ptl ) {
1266 		ptfig->USER = addptype( ptfig->USER, HNSRCNI, NULL );
1267 		ptl = ptfig->USER;
1268 	}
1269 	headi = (struct hns_I*)(ptl->DATA);
1270 
1271 	for( scani = headi; scani; scani = scani->NEXT ) {
1272 		if (scani->idx == index && scani->ins == ptins)
1273 			break;
1274 	}
1275 
1276 	if(!scani) {
1277 		scani       = add_hns_I();
1278 		scani->idx  = index;
1279 		scani->NEXT = headi;
1280 		scani->ins  = ptins;
1281 		scani->rcn  = 0;
1282 		headi       = scani;
1283 		ptl->DATA   = headi;
1284 	}
1285 
1286 	return(scani);
1287 
1288 }
1289 
buildrcn(ptfig)1290 static void buildrcn( ptfig )
1291 lofig_list	*ptfig;
1292 {
1293 	int		 index;
1294 	losig_list	*scanlosig;
1295 	ptype_list	*ptl;
1296 	struct hns_W	*headw;
1297 	struct hns_W	*scanw;
1298 	struct hns_W	*elem_w;
1299 	struct hns_X	*elem_x;
1300 	struct hns_X	*headx;
1301 	struct hns_X	*scanx;
1302 	struct hns_I	*elem_i;
1303 	struct hns_I	*scani;
1304 	struct hns_I	*headi;
1305 	struct hns_P	*elem_p;
1306 	int		 n1=0,n2=0;
1307 	locon_list	*ptcon;
1308 	chain_list	*scan;
1309 	chain_list	*head;
1310 	chain_list	*scanchain;
1311 	locon_list	*scanlocon;
1312 	loins_list	*scanloins;
1313   ptype_list  *ptl_head;
1314 
1315 
1316 	/* On commence par remplir le champ RCN des structures */
1317 	for( scanlosig = ptfig->LOSIG; scanlosig; scanlosig = scanlosig->NEXT ) {
1318 
1319 		index = 1;
1320 		ptl = getptype( scanlosig->USER, HNSRCN );
1321 
1322 		/* Si on est en mode 'C', il se peut que certains signaux aient herites d'une vue
1323 		 * RC dans les signaux cree pour les connecteurs */
1324 
1325     headw = NULL;
1326 
1327 		if( ptl ) {
1328 
1329 			headw = (struct hns_W*)( ptl->DATA );
1330 
1331       /* On ne cree les vues RC que si on a des resistances. Tant pis pour les noeuds sur les locons */
1332       if( !scanlosig->PRCN && headw )
1333   			addlorcnet(scanlosig);
1334 
1335 			for( scanw = headw; scanw; scanw = scanw->NEXT ) {
1336 
1337 				if( scanw->flag & 1 ) {
1338 					elem_x = (struct hns_X*)( scanw->node1 );
1339 					if( elem_x->rcn == 0 )
1340 						elem_x->rcn = index++;
1341 					n1 = elem_x->rcn;
1342 				}
1343 				else if( scanw->flag & 2 ) {
1344 					elem_i = (struct hns_I*)( scanw->node1 );
1345 					if( elem_i->rcn == 0 )
1346 						elem_i->rcn = index++;
1347 					n1 = elem_i->rcn;
1348 				}
1349 				else if( scanw->flag & 4 ) {
1350 					elem_p = (struct hns_P*)( scanw->node1 );
1351 					if( elem_p->rcn == 0 )
1352 						elem_p->rcn = index++;
1353 					n1 = elem_p->rcn;
1354 				}
1355 
1356 				if( scanw->flag & 8 ) {
1357 					elem_x = (struct hns_X*)( scanw->node2 );
1358 					if( elem_x->rcn == 0 )
1359 						elem_x->rcn = index++;
1360 					n2 = elem_x->rcn;
1361 				}
1362 				else if( scanw->flag & 16 ) {
1363 					elem_i = (struct hns_I*)( scanw->node2 );
1364 					if( elem_i->rcn == 0 )
1365 						elem_i->rcn = index++;
1366 					n2 = elem_i->rcn;
1367 				}
1368 				else if( scanw->flag & 32 ) {
1369 					elem_p = (struct hns_P*)( scanw->node2 );
1370 					if( elem_p->rcn == 0 )
1371 						elem_p->rcn = index++;
1372 					n2 = elem_p->rcn;
1373 				}
1374 
1375 				addlowire( scanlosig, RCN_WIRE_UNKNOW, 0, scanw->r, scanw->c, 0l, 0l, 0l, 0l, n1, n2 );
1376                                 addcapa( scanlosig, scanw->c );
1377 			}
1378 		}
1379 
1380 		ptl = getptype( scanlosig->USER, LOFIGCHAIN );
1381 
1382 		if( ptl && headw ) {
1383 
1384 			for( scanchain = (chain_list*)( ptl->DATA ); scanchain; scanchain = scanchain->NEXT ) {
1385 
1386 				ptcon = (locon_list*)( scanchain->DATA );
1387         ptl_head = getptype( ptcon->USER, HNSRCN );
1388         if( !ptl_head )
1389           continue;
1390 
1391 				head = (chain_list*)( ptl_head->DATA );
1392 				head = reverse(head);
1393 
1394 				if( ptcon->ROOT == ptfig ) {
1395 					for(scan = head; scan; scan = scan->NEXT ) {
1396 						elem_x = (struct hns_X*)(scan->DATA);
1397 						if( elem_x->rcn == 0 )
1398 							elem_x->rcn = index++;
1399 						setloconnode( ptcon, elem_x->rcn );
1400 					}
1401 				}
1402 				else {
1403 					for(scan = head; scan; scan = scan->NEXT ) {
1404 						elem_i = (struct hns_I*)(scan->DATA);
1405 						if( elem_i->rcn == 0 )
1406 							elem_i->rcn = index++;
1407 						setloconnode( ptcon, elem_i->rcn );
1408 					}
1409 				}
1410 				head = reverse(head);
1411 			}
1412 		}
1413 	}
1414 
1415 	/* Technicien de surface */
1416 
1417 	for(scanlosig = ptfig->LOSIG; scanlosig; scanlosig = scanlosig->NEXT ) {
1418 		ptl = getptype( scanlosig->USER, HNSRCN );
1419 		if( ptl ) {
1420 			headw = (struct hns_W*)( ptl->DATA );
1421 			elem_w = NULL;
1422 			for( scanw = headw; scanw; scanw = scanw->NEXT ) {
1423 				if( elem_w )
1424 					del_hns_W( elem_w );
1425 			}
1426 			if( elem_w )
1427 				del_hns_W( elem_w );
1428 			scanlosig->USER = delptype( scanlosig->USER, HNSRCN );
1429 		}
1430 	}
1431 
1432 	for(scanlocon = ptfig->LOCON; scanlocon; scanlocon = scanlocon->NEXT ) {
1433 		freechain( (chain_list*)( getptype(scanlocon->USER,HNSRCN)->DATA ) );
1434 		scanlocon->USER = delptype( scanlocon->USER, HNSRCN );
1435 	}
1436 
1437 	for(scanloins = ptfig->LOINS; scanloins; scanloins = scanloins->NEXT ) {
1438 		for(scanlocon = scanloins->LOCON; scanlocon; scanlocon = scanlocon->NEXT ) {
1439 			freechain( (chain_list*)( getptype(scanlocon->USER,HNSRCN)->DATA ) );
1440 			scanlocon->USER = delptype( scanlocon->USER, HNSRCN );
1441 		}
1442 	}
1443 
1444 	ptl = getptype( ptfig->USER, HNSRCNX );
1445 	if(ptl) {
1446 		headx = (struct hns_X*)( ptl->DATA );
1447 		elem_x = NULL;
1448 		for( scanx = headx; scanx; scanx = scanx->NEXT ) {
1449 			if( elem_x )
1450 				del_hns_X( elem_x );
1451 			elem_x = scanx;
1452 		}
1453 		if( elem_x )
1454 			del_hns_X( elem_x );
1455 
1456 		ptfig->USER = delptype( ptfig->USER, HNSRCNX );
1457 	}
1458 
1459 	ptl = getptype( ptfig->USER, HNSRCNI );
1460 	if(ptl) {
1461 		headi = (struct hns_I*)( ptl->DATA );
1462 		elem_i = NULL;
1463 		for( scani = headi; scani; scani = scani->NEXT ) {
1464 			if( elem_i )
1465 				del_hns_I( elem_i );
1466 			elem_i = scani;
1467 		}
1468 		if( elem_i )
1469 			del_hns_I( elem_i );
1470 
1471 		ptfig->USER = delptype( ptfig->USER, HNSRCNI );
1472 	}
1473 }
1474 
1475 /*
1476 static void movehnsw( sig1, sig2)
1477 losig_list	*sig1;
1478 losig_list	*sig2;
1479 {
1480 	ptype_list	*ptl;
1481 	struct hns_W	*headw1;
1482 	struct hns_W	*headw2;
1483 
1484 	ptl = getptype( sig1->USER,HNSRCN );
1485 	if (!ptl )
1486 		headw1 = NULL;
1487 	else
1488 		headw1 = ( struct hns_W* )( ptl->DATA );
1489 
1490 	ptl = getptype( sig2->USER,HNSRCN );
1491 	if (!ptl )
1492 		headw2 = NULL;
1493 	else
1494 		headw2 = ( struct hns_W* )( ptl->DATA );
1495 
1496 	if( !headw2 )
1497 		return;
1498 
1499 	if( !headw1 ) {
1500 		sig1->USER = addptype( sig1->USER, HNSRCN, headw2 );
1501 	}
1502 	else {
1503 		for( ; headw1->NEXT; headw1 = headw1->NEXT ) ;
1504 		headw1->NEXT = headw2;
1505 	}
1506 	sig2->USER = delptype( sig2->USER, HNSRCN );
1507 }
1508 */
1509 /*
1510 void debug(ptfig)
1511 lofig_list	*ptfig;
1512 {
1513 	locon_list	*scanlocon;
1514 	ptype_list	*ptl;
1515 	chain_list	*scanchain;
1516 	struct hns_X	*elem_x;
1517 
1518 	printf("##############################################################################################\n");
1519 	for( scanlocon = ptfig->LOCON; scanlocon; scanlocon = scanlocon->NEXT ) {
1520 		printf("Connecteur %s :",scanlocon->NAME);
1521 		ptl = getptype(scanlocon->USER,HNSRCN);
1522 		if( ptl )
1523 		{
1524 			for(scanchain = (chain_list*)(ptl->DATA); scanchain; scanchain = scanchain->NEXT ) {
1525 				elem_x = (struct hns_X*)(scanchain->DATA);
1526 				printf("%ld ", elem_x->idx);
1527 			}
1528 		}
1529 		printf("\n");
1530 	}
1531 	printf("##############################################################################################\n");
1532 }
1533 */
1534 
givelosigalias(ptfig,head_sigalias,n)1535 static losig_list* givelosigalias( ptfig, head_sigalias, n )
1536 lofig_list	*ptfig;
1537 chain_list	*head_sigalias;
1538 int			 n;
1539 {
1540 	chain_list	*scan_head_sigalias;
1541 	chain_list	*scan_sigalias;
1542 	losig_list	*ptsig;
1543 	losig_list	*grpsig;
1544 
1545 	for( scan_head_sigalias = head_sigalias; scan_head_sigalias; scan_head_sigalias = scan_head_sigalias->NEXT ) {
1546 
1547 		for( scan_sigalias = (chain_list*)(scan_head_sigalias->DATA); scan_sigalias; scan_sigalias = scan_sigalias->NEXT ) {
1548 
1549 			ptsig = (losig_list*)( scan_sigalias->DATA );
1550 
1551 			if( ptsig->INDEX == n ) {
1552 				for( ; scan_sigalias->NEXT ; scan_sigalias = scan_sigalias->NEXT );
1553 				grpsig = (losig_list*)( scan_sigalias->DATA );
1554 				return( grpsig );
1555 			}
1556 		}
1557 	}
1558 
1559 	return( givelosig( ptfig, n ) );
1560 }
1561 
compare_alias_join(fig,head_sigalias,ext_join)1562 static int compare_alias_join( fig, head_sigalias, ext_join )
1563 lofig_list	*fig;
1564 chain_list	*head_sigalias;
1565 chain_list	**ext_join;
1566 {
1567 	chain_list	*scan_head_sigalias;
1568 	chain_list	*scan_sigalias;
1569 	chain_list	*scan_head_join;
1570 	chain_list	*scan_join;
1571 	chain_list	*scan_chain;
1572 	chain_list	*head_new_join;
1573 	chain_list	*add_to_head_join;
1574 	chain_list	*head_join;
1575 	int		 manque;
1576 	int	me;
1577 
1578 	head_join = *ext_join;
1579 
1580 	add_to_head_join = NULL;
1581 
1582 	for( scan_head_sigalias = head_sigalias; scan_head_sigalias; scan_head_sigalias=scan_head_sigalias->NEXT) {
1583 
1584 		manque = 0;
1585 		me=0;
1586 
1587 		scan_sigalias = (chain_list*)( scan_head_sigalias ->DATA );
1588 
1589 		for( scan_head_join = head_join; scan_head_join ; scan_head_join = scan_head_join->NEXT ) {
1590 			for( scan_join = (chain_list*)(scan_head_join->DATA); scan_join; scan_join = scan_join->NEXT ) {
1591 				if( scan_join->DATA == scan_sigalias->DATA ) {
1592 					break;
1593 				}
1594 			}
1595 			if( scan_join )
1596 				break;
1597 		}
1598 
1599 		if( !scan_head_join ) {
1600 			msg_err( fig, scan_head_sigalias->DATA );
1601 			manque = 1;
1602 			me = 1;
1603 			/*
1604 			return(0);
1605 			*/
1606 		}
1607 		else {
1608 
1609 			for( scan_sigalias = scan_sigalias->NEXT; scan_sigalias; scan_sigalias = scan_sigalias->NEXT ) {
1610 				for( scan_join = (chain_list*)(scan_head_join->DATA); scan_join; scan_join = scan_join->NEXT ) {
1611 					if ( scan_join->DATA == scan_sigalias->DATA )
1612 						break;
1613 				}
1614 				if( !scan_join )
1615 				{
1616 					if( me )
1617 						msg_err( fig, scan_head_sigalias->DATA );
1618 					manque = 1;
1619 					me = 1;
1620 					/*
1621 					return(0);
1622 					*/
1623 				}
1624 			}
1625 		}
1626 
1627 		if( manque ) {
1628 			/* Il manque un join pour regrouper des signaux */
1629 
1630 			head_new_join = NULL;
1631 
1632 			for( scan_sigalias = ((chain_list*)(scan_head_sigalias->DATA));
1633 			                     scan_sigalias;
1634 								 scan_sigalias = scan_sigalias->NEXT        ) {
1635 				head_new_join = addchain( head_new_join, scan_sigalias->DATA );
1636 			}
1637 
1638 			for( scan_head_join = head_join; scan_head_join ; scan_head_join = scan_head_join->NEXT ) {
1639 				for( scan_join = (chain_list*)(scan_head_join->DATA); scan_join; scan_join = scan_join->NEXT ) {
1640 					for( scan_sigalias = ((chain_list*)(scan_head_sigalias->DATA)); scan_sigalias;
1641 					     scan_sigalias = scan_sigalias->NEXT) {
1642 						if( scan_join->DATA == scan_sigalias->DATA ) {
1643 							break;
1644 						}
1645 					}
1646 					if( scan_sigalias )
1647 						break;
1648 				}
1649 
1650 				/* Si on a trouve au moins un element dans la liste join, on transfert toute la liste join vers la
1651 				   nouvelle et on supprime l'originale */
1652 
1653 				if( scan_join ) {
1654 					for( scan_join = (chain_list*)(scan_head_join->DATA); scan_join; scan_join = scan_join->NEXT ) {
1655 						for( scan_chain = head_new_join; scan_chain; scan_chain = scan_chain->NEXT ) {
1656 							if( scan_chain->DATA == scan_join->DATA )
1657 								break;
1658 						}
1659 						if(!scan_chain)
1660 							head_new_join = addchain( head_new_join, scan_join->DATA );
1661 					}
1662 
1663 					freechain( (chain_list*)(scan_head_join->DATA) );
1664 					scan_head_join->DATA = NULL;
1665 				}
1666 			}
1667 
1668 			/* En creant le head_new_join, on a utilise addchain, ce qui inverse l'ordre des signaux */
1669 
1670 			add_to_head_join = addchain( add_to_head_join, head_new_join );
1671 		}
1672 	}
1673 
1674 	if( head_join ) {
1675 		for( scan_head_join = head_join; scan_head_join->NEXT ; scan_head_join = scan_head_join->NEXT );
1676 		scan_head_join->NEXT = add_to_head_join;
1677 	}
1678 	else {
1679 		head_join = add_to_head_join;
1680 	}
1681 
1682 	*ext_join = head_join;
1683 	return( 1 );
1684 }
1685 
msg_err(fig,head)1686 static void msg_err(fig, head)
1687 lofig_list	*fig;
1688 chain_list	*head;
1689 {
1690 	locon_list	*ptcon = NULL;
1691 	losig_list	*ptsig;
1692 	chain_list	*scan,*slf;
1693 	ptype_list	*ptl;
1694 
1695 	for( scan = head; scan; scan = scan->NEXT ) {
1696 
1697 		ptcon = NULL;
1698 
1699 		ptsig = (losig_list*)(scan->DATA);
1700 		ptl = getptype( ptsig->USER, LOFIGCHAIN );
1701 
1702 		for( slf = (chain_list*)(ptl->DATA) ; slf; slf = slf->NEXT ) {
1703 			ptcon = (locon_list*)( slf->DATA );
1704 			if(ptcon->ROOT == fig ) {
1705 				break;
1706 			}
1707 		}
1708 
1709 		if(ptcon)
1710 			break;
1711 	}
1712 
1713         (void)fprintf(stderr,"\n*** mbk warning ***\n");
1714 	(void)fprintf(stderr,"no join for signals connected on the connector %s\n\n",ptcon->NAME);
1715 }
1716 
1717 
traite_join(fig,head_join)1718 static int traite_join( fig, head_join )
1719 lofig_list	*fig;
1720 chain_list	*head_join;
1721 {
1722 	chain_list	*scan_head_join, *scan_join;
1723 	int		 trouve;
1724 	losig_list	*ptsig;
1725 	losig_list	*grpsig = NULL;
1726 	loins_list	*scanloins;
1727 	lotrs_list	*scanlotrs;
1728 	locon_list	*scanlocon;
1729 	locon_list	*oldlocon=NULL;
1730 	chain_list	*scanchain;
1731 	ptype_list	*ptlsrc;
1732 	ptype_list	*ptldst;
1733 	ptype_list	*ptl;
1734 	struct hns_W	*scanw;
1735 	char		 errmes[256] ;
1736 	int			 externe;
1737 	chain_list	*nom,*scnom;
1738         loctc_list      *ptctc;
1739         losig_list      *s1, *s2;
1740         float            f;
1741 
1742 	for( scan_head_join = head_join; scan_head_join; scan_head_join = scan_head_join->NEXT ) {
1743       if( !scan_head_join->DATA )
1744            continue;
1745 
1746 		/* On commence par verifier qu'il n'y a seulement qu'un signal qui possede des connecteurs.
1747 		   On en profite egalement pour retrouver le signal qui regroupera les autres ( le dernier
1748 		   dans la liste des join ) */
1749 
1750 		trouve  = 0;
1751 		externe = 0;
1752 		nom     = NULL;
1753 
1754 		for( scan_join = (chain_list*)(scan_head_join->DATA); scan_join; scan_join = scan_join->NEXT ) {
1755 
1756 			ptsig = (losig_list*)(scan_join->DATA);
1757 			ptl   = getptype( ptsig->USER, LOFIGCHAIN );
1758 
1759 			if( ptsig->TYPE == EXTERNAL )
1760 				externe = 1;
1761 
1762 			for( scanchain = (chain_list*)(ptl->DATA); scanchain; scanchain = scanchain->NEXT ) {
1763 
1764 				scanlocon = (locon_list*)( scanchain->DATA );
1765 
1766 				if( scanlocon->ROOT==fig ) {
1767 					if( trouve ) {
1768                                                 sprintf(errmes,"%s and %s",oldlocon->NAME,scanlocon->NAME) ;
1769                                                 hns_error((int)BAD_JOIN, fig->NAME, (long)0,errmes,ptsig->INDEX);
1770 					}
1771 					trouve = 1;
1772                                         oldlocon = scanlocon ;
1773 				}
1774 			}
1775 
1776 			if( !scan_join->NEXT )
1777 				grpsig = ptsig;
1778 		}
1779 
1780 		/* On fait remplace par ptsig tous les signaux de la figure qui apparaissent dans le join */
1781 
1782 		/* Les connecteurs sur les instances */
1783 
1784 		for( scanloins = fig->LOINS ; scanloins; scanloins = scanloins->NEXT ) {
1785 
1786 			for( scanlocon = scanloins->LOCON; scanlocon; scanlocon = scanlocon->NEXT ) {
1787 
1788 				for( scan_join = (chain_list*)(scan_head_join->DATA); scan_join; scan_join = scan_join->NEXT ) {
1789 
1790 					if( scan_join->DATA == scanlocon->SIG ) {
1791 						scanlocon->SIG = grpsig;
1792 						break;
1793 					}
1794 				}
1795 			}
1796 		}
1797 
1798 		/* Les connecteurs de la figure */
1799 
1800 		for( scanlocon = fig->LOCON; scanlocon; scanlocon = scanlocon->NEXT ) {
1801 
1802 			for( scan_join = (chain_list*)(scan_head_join->DATA); scan_join; scan_join = scan_join->NEXT ) {
1803 
1804 				if( scan_join->DATA == scanlocon->SIG ) {
1805 
1806 					scanlocon->SIG = grpsig;
1807 					break;
1808 				}
1809 			}
1810 		}
1811 
1812 		/* Les connecteurs sur les transistors */
1813 
1814 		for( scanlotrs = fig->LOTRS; scanlotrs; scanlotrs = scanlotrs->NEXT ) {
1815 
1816 			for( scan_join = (chain_list*)(scan_head_join->DATA); scan_join; scan_join = scan_join->NEXT ) {
1817 
1818 				if( scan_join->DATA == scanlotrs->GRID->SIG )
1819 					scanlotrs->GRID->SIG   = grpsig;
1820 
1821 				if( scan_join->DATA == scanlotrs->SOURCE->SIG )
1822 					scanlotrs->SOURCE->SIG = grpsig;
1823 
1824 				if( scan_join->DATA == scanlotrs->DRAIN->SIG )
1825 					scanlotrs->DRAIN->SIG   = grpsig;
1826 
1827 				if( scan_join->DATA == scanlotrs->BULK->SIG )
1828 					scanlotrs->BULK->SIG   = grpsig;
1829 			}
1830 
1831 		}
1832 
1833 		/* On efface les signaux devenus inutiles en transferant les vues RC */
1834 
1835 		for( scan_join = ((chain_list*)(scan_head_join->DATA)); scan_join; scan_join = scan_join->NEXT ) {
1836 			ptsig = (losig_list*)(scan_join->DATA);
1837 			if( ptsig != grpsig ) {
1838                                 if ( ptsig->PRCN )
1839                                 {
1840                                         if( !grpsig->PRCN )
1841                                                 addlorcnet( grpsig );
1842         				addcapa( grpsig, ptsig->PRCN->CAPA );
1843                                 }
1844 
1845 				if( nom ) {
1846 					for( scnom = nom ; scnom->NEXT; scnom = scnom->NEXT ) ;
1847 					scnom->NEXT      = ptsig->NAMECHAIN;
1848 					ptsig->NAMECHAIN = NULL;
1849 				}
1850 				else {
1851 					nom = ptsig->NAMECHAIN;
1852 					ptsig->NAMECHAIN = NULL;
1853 				}
1854 
1855 				ptlsrc = getptype( ptsig->USER, HNSRCN );
1856 				if( ptlsrc ) {
1857 					ptldst = getptype( grpsig->USER, HNSRCN );
1858 					if( !ptldst ) {
1859 						grpsig->USER = addptype( grpsig->USER, HNSRCN, ptlsrc->DATA );
1860 					}
1861 					else {
1862 						for( scanw= (struct hns_W*)( ptlsrc->DATA ); scanw->NEXT; scanw = scanw->NEXT );
1863 						scanw->NEXT = (struct hns_W*)( ptldst->DATA );
1864 						ptldst->DATA = ptlsrc->DATA;
1865 					}
1866 					ptsig->USER  = delptype( ptsig->USER, HNSRCN );
1867 				}
1868 
1869                                 if( ptsig->PRCN )
1870                                         while( ptsig->PRCN->PCTC )
1871                                         {
1872                                                 ptctc = (loctc_list*)(ptsig->PRCN->PCTC->DATA);
1873                                                 s1 = ptctc->SIG1 ;
1874                                                 s2 = ptctc->SIG2 ;
1875                                                 f  = ptctc->CAPA ;
1876                                                 delloctc( s1, 0, s2, 0 );
1877                                                 if( s1 == ptsig )
1878                                                   s1 = grpsig;
1879                                                 if( s2 == ptsig )
1880                                                   s2 = grpsig;
1881 
1882                                                 if( s1 != s2 )
1883                                                 {
1884                                                         ptctc = getloctc( s1, 0, s2, 0 );
1885                                                         if( ptctc )
1886                                                           ptctc->CAPA = ptctc->CAPA + f;
1887                                                         else
1888                                                           addloctc( s1, 0, s2, 0, f );
1889                                                 }
1890                                         }
1891                                 dellosig( fig, ptsig->INDEX );
1892 			}
1893 		}
1894 
1895 		if( externe )
1896 			grpsig->TYPE = EXTERNAL;
1897                 else
1898 			grpsig->TYPE = INTERNAL;
1899 
1900 		if( grpsig->NAMECHAIN ) {
1901 			for( scnom = grpsig->NAMECHAIN ; scnom->NEXT; scnom = scnom->NEXT ) ;
1902 			scnom->NEXT = nom;
1903 		}
1904 		else {
1905 			grpsig->NAMECHAIN = nom;
1906 		}
1907 	}
1908 
1909 	return( 1 );
1910 }
1911