6 * PCB, interactive printed circuit board design
7 * Copyright (C) 1994,1995,1996, 2005 Thomas Nau
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * Contact addresses for paper mail and Email:
24 * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
25 * Thomas.Nau@rz.uni-ulm.de
29 /* generic netlist operations
41 #include <sys/types.h>
65 #if defined(HAVE_REGCOMP) || defined(HAVE_RE_COMP)
69 #ifdef HAVE_LIBDMALLOC
76 int PCB->NetlistLib.MenuN
77 char * PCB->NetlistLib.Menu[i].Name
78 [0] == '*' (ok for rats) or ' ' (skip for rats)
81 char * PCB->NetlistLib.Menu[i].Style
82 int PCB->NetlistLib.Menu[i].EntryN
83 char * PCB->NetlistLib.Menu[i].Entry[j].ListEntry
86 typedef void (*NFunc
) (LibraryMenuType
*, LibraryEntryType
*);
89 netnode_to_netname (char *nodename
)
92 /*printf("nodename [%s]\n", nodename);*/
93 for (i
=0; i
<PCB
->NetlistLib
.MenuN
; i
++)
95 for (j
=0; j
<PCB
->NetlistLib
.Menu
[i
].EntryN
; j
++)
97 if (strcmp (PCB
->NetlistLib
.Menu
[i
].Entry
[j
].ListEntry
, nodename
) == 0)
99 /*printf(" in [%s]\n", PCB->NetlistLib.Menu[i].Name);*/
100 return & (PCB
->NetlistLib
.Menu
[i
]);
108 netname_to_netname (char *netname
)
112 if ((netname
[0] == '*' || netname
[0] == ' ') && netname
[1] == ' ')
114 /* Looks like we were passed an internal netname, skip the prefix */
117 for (i
=0; i
<PCB
->NetlistLib
.MenuN
; i
++)
119 if (strcmp (PCB
->NetlistLib
.Menu
[i
].Name
+ 2, netname
) == 0)
121 return & (PCB
->NetlistLib
.Menu
[i
]);
128 pin_name_to_xy (LibraryEntryType
* pin
, int *x
, int *y
)
131 if (!SeekPad (pin
, &conn
, False
))
136 *x
= ((PinType
*) (conn
.ptr2
))->X
;
137 *y
= ((PinType
*) (conn
.ptr2
))->Y
;
140 *x
= ((PadType
*) (conn
.ptr2
))->Point1
.X
;
141 *y
= ((PadType
*) (conn
.ptr2
))->Point1
.Y
;
148 netlist_find (LibraryMenuType
* net
, LibraryEntryType
* pin
)
151 if (pin_name_to_xy (net
->Entry
, &x
, &y
))
153 LookupConnection (x
, y
, 1, 1, FOUNDFLAG
);
157 netlist_select (LibraryMenuType
* net
, LibraryEntryType
* pin
)
160 if (pin_name_to_xy (net
->Entry
, &x
, &y
))
162 LookupConnection (x
, y
, 1, 1, SELECTEDFLAG
);
166 netlist_rats (LibraryMenuType
* net
, LibraryEntryType
* pin
)
170 hid_action ("NetlistChanged");
174 netlist_norats (LibraryMenuType
* net
, LibraryEntryType
* pin
)
178 hid_action ("NetlistChanged");
182 static const char netlist_syntax
[] =
183 "Net(find|select|rats|norats[,net[,pin]])";
185 static const char netlist_help
[] = "Perform various actions on netlists.";
187 /* %start-doc actions Netlist
189 Each of these actions apply to a specified set of nets. @var{net} and
190 @var{pin} are patterns which match one or more nets or pins; these
191 patterns may be full names or regular expressions. If an exact match
192 is found, it is the only match; if no exact match is found,
193 @emph{then} the pattern is tried as a regular expression.
195 If neither @var{net} nor @var{pin} are specified, all nets apply. If
196 @var{net} is specified but not @var{pin}, all nets matching @var{net}
197 apply. If both are specified, nets which match @var{net} and contain
198 a pin matching @var{pin} apply.
203 Nets which apply are marked @emph{found} and are drawn in the
204 @code{connected-color} color.
207 Nets which apply are selected.
210 Nets which apply are marked as available for the rats nest.
213 Nets which apply are marked as not available for the rats nest.
220 Netlist (int argc
, char **argv
, int x
, int y
)
224 LibraryMenuType
*net
;
225 LibraryEntryType
*pin
;
231 #if defined(HAVE_REGCOMP)
235 #if defined(HAVE_RE_COMP)
243 Message (netlist_syntax
);
246 if (strcasecmp (argv
[0], "find") == 0)
248 else if (strcasecmp (argv
[0], "select") == 0)
249 func
= netlist_select
;
250 else if (strcasecmp (argv
[0], "rats") == 0)
252 else if (strcasecmp (argv
[0], "norats") == 0)
253 func
= netlist_norats
;
256 Message (netlist_syntax
);
265 for (i
= 0; i
< PCB
->NetlistLib
.MenuN
; i
++)
267 net
= PCB
->NetlistLib
.Menu
+ i
;
268 if (strcasecmp (argv
[1], net
->Name
+ 2) == 0)
273 #if defined(HAVE_REGCOMP)
275 regcomp (&elt_pattern
, argv
[1],
276 REG_EXTENDED
| REG_ICASE
| REG_NOSUB
);
279 char errorstring
[128];
281 regerror (result
, &elt_pattern
, errorstring
, 128);
282 Message (_("regexp error: %s\n"), errorstring
);
283 regfree (&elt_pattern
);
287 #if defined(HAVE_RE_COMP)
288 if ((elt_pattern
= re_comp (argv
[1])) != NULL
)
290 Message (_("re_comp error: %s\n"), elt_pattern
);
298 for (i
= 0; i
< PCB
->NetlistLib
.MenuN
; i
++)
300 net
= PCB
->NetlistLib
.Menu
+ i
;
307 #if defined(HAVE_REGCOMP)
308 if (regexec (&elt_pattern
, net
->Name
+ 2, 1, &match
, 0) != 0)
311 #if defined(HAVE_RE_COMP)
312 if (re_exec (net
->Name
+ 2) != 1)
318 if (strcasecmp (net
->Name
+ 2, argv
[1]))
326 int l
= strlen (argv
[2]);
327 for (j
= 0; j
< net
->EntryN
; j
++)
328 if (strcasecmp (net
->Entry
[j
].ListEntry
, argv
[2]) == 0
329 || (strncasecmp (net
->Entry
[j
].ListEntry
, argv
[2], l
) == 0
330 && net
->Entry
[j
].ListEntry
[l
] == '-'))
332 pin
= net
->Entry
+ j
;
341 if (argc
> 2 && !pin_found
)
343 gui
->log ("Net %s has no pin %s\n", argv
[1], argv
[2]);
348 gui
->log ("No net named %s\n", argv
[1]);
352 regfree (&elt_pattern
);
358 HID_Action netlist_action_list
[] = {
360 netlist_help
, netlist_syntax
}
362 {"netlist", 0, Netlist
,
363 netlist_help
, netlist_syntax
}
366 REGISTER_ACTIONS (netlist_action_list
)