Add support for filling / thindrawing raw polygons to the HID interface
[geda-pcb/gde.git] / src / netlist.c
blobd9592b0b0207cb90be70d7ab0dfba5467302e07d
1 /* $Id$ */
3 /*
4 * COPYRIGHT
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
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
36 #include <stdlib.h>
37 #ifdef HAVE_STRING_H
38 #include <string.h>
39 #endif
40 #include <ctype.h>
41 #include <sys/types.h>
42 #ifdef HAVE_REGEX_H
43 #include <regex.h>
44 #endif
46 #include "global.h"
47 #include "action.h"
48 #include "buffer.h"
49 #include "command.h"
50 #include "data.h"
51 #include "djopt.h"
52 #include "error.h"
53 #include "file.h"
54 #include "find.h"
55 #include "mymem.h"
56 #include "misc.h"
57 #include "rats.h"
58 #include "set.h"
59 #include "vendor.h"
61 #ifdef HAVE_REGCOMP
62 #undef HAVE_RE_COMP
63 #endif
65 #if defined(HAVE_REGCOMP) || defined(HAVE_RE_COMP)
66 #define USE_RE
67 #endif
69 #ifdef HAVE_LIBDMALLOC
70 #include <dmalloc.h>
71 #endif
73 RCSID ("$Id$");
76 int PCB->NetlistLib.MenuN
77 char * PCB->NetlistLib.Menu[i].Name
78 [0] == '*' (ok for rats) or ' ' (skip for rats)
79 [1] == unused
80 [2..] actual name
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 *);
88 LibraryMenuTypePtr
89 netnode_to_netname (char *nodename)
91 int i, j;
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]);
104 return 0;
107 LibraryMenuTypePtr
108 netname_to_netname (char *netname)
110 int i;
112 if ((netname[0] == '*' || netname[0] == ' ') && netname[1] == ' ')
114 /* Looks like we were passed an internal netname, skip the prefix */
115 netname += 2;
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]);
124 return 0;
127 static int
128 pin_name_to_xy (LibraryEntryType * pin, int *x, int *y)
130 ConnectionType conn;
131 if (!SeekPad (pin, &conn, False))
132 return 1;
133 switch (conn.type)
135 case PIN_TYPE:
136 *x = ((PinType *) (conn.ptr2))->X;
137 *y = ((PinType *) (conn.ptr2))->Y;
138 return 0;
139 case PAD_TYPE:
140 *x = ((PadType *) (conn.ptr2))->Point1.X;
141 *y = ((PadType *) (conn.ptr2))->Point1.Y;
142 return 0;
144 return 1;
147 static void
148 netlist_find (LibraryMenuType * net, LibraryEntryType * pin)
150 int x, y;
151 if (pin_name_to_xy (net->Entry, &x, &y))
152 return;
153 LookupConnection (x, y, 1, 1, FOUNDFLAG);
156 static void
157 netlist_select (LibraryMenuType * net, LibraryEntryType * pin)
159 int x, y;
160 if (pin_name_to_xy (net->Entry, &x, &y))
161 return;
162 LookupConnection (x, y, 1, 1, SELECTEDFLAG);
165 static void
166 netlist_rats (LibraryMenuType * net, LibraryEntryType * pin)
168 net->Name[0] = ' ';
169 net->flag = 1;
170 hid_action ("NetlistChanged");
173 static void
174 netlist_norats (LibraryMenuType * net, LibraryEntryType * pin)
176 net->Name[0] = '*';
177 net->flag = 0;
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.
200 @table @code
202 @item find
203 Nets which apply are marked @emph{found} and are drawn in the
204 @code{connected-color} color.
206 @item select
207 Nets which apply are selected.
209 @item rats
210 Nets which apply are marked as available for the rats nest.
212 @item norats
213 Nets which apply are marked as not available for the rats nest.
215 @end table
217 %end-doc */
219 static int
220 Netlist (int argc, char **argv, int x, int y)
222 NFunc func;
223 int i, j;
224 LibraryMenuType *net;
225 LibraryEntryType *pin;
226 int net_found = 0;
227 int pin_found = 0;
228 #if defined(USE_RE)
229 int use_re = 0;
230 #endif
231 #if defined(HAVE_REGCOMP)
232 regex_t elt_pattern;
233 regmatch_t match;
234 #endif
235 #if defined(HAVE_RE_COMP)
236 char *elt_pattern;
237 #endif
239 if (!PCB)
240 return 1;
241 if (argc == 0)
243 Message (netlist_syntax);
244 return 1;
246 if (strcasecmp (argv[0], "find") == 0)
247 func = netlist_find;
248 else if (strcasecmp (argv[0], "select") == 0)
249 func = netlist_select;
250 else if (strcasecmp (argv[0], "rats") == 0)
251 func = netlist_rats;
252 else if (strcasecmp (argv[0], "norats") == 0)
253 func = netlist_norats;
254 else
256 Message (netlist_syntax);
257 return 1;
260 #if defined(USE_RE)
261 if (argc > 1)
263 int result;
264 use_re = 1;
265 for (i = 0; i < PCB->NetlistLib.MenuN; i++)
267 net = PCB->NetlistLib.Menu + i;
268 if (strcasecmp (argv[1], net->Name + 2) == 0)
269 use_re = 0;
271 if (use_re)
273 #if defined(HAVE_REGCOMP)
274 result =
275 regcomp (&elt_pattern, argv[1],
276 REG_EXTENDED | REG_ICASE | REG_NOSUB);
277 if (result)
279 char errorstring[128];
281 regerror (result, &elt_pattern, errorstring, 128);
282 Message (_("regexp error: %s\n"), errorstring);
283 regfree (&elt_pattern);
284 return (1);
286 #endif
287 #if defined(HAVE_RE_COMP)
288 if ((elt_pattern = re_comp (argv[1])) != NULL)
290 Message (_("re_comp error: %s\n"), elt_pattern);
291 return (False);
293 #endif
296 #endif
298 for (i = 0; i < PCB->NetlistLib.MenuN; i++)
300 net = PCB->NetlistLib.Menu + i;
302 if (argc > 1)
304 #if defined(USE_RE)
305 if (use_re)
307 #if defined(HAVE_REGCOMP)
308 if (regexec (&elt_pattern, net->Name + 2, 1, &match, 0) != 0)
309 continue;
310 #endif
311 #if defined(HAVE_RE_COMP)
312 if (re_exec (net->Name + 2) != 1)
313 continue;
314 #endif
316 else
317 #endif
318 if (strcasecmp (net->Name + 2, argv[1]))
319 continue;
321 net_found = 1;
323 pin = 0;
324 if (argc > 2)
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;
333 pin_found = 1;
334 func (net, pin);
337 else
338 func (net, 0);
341 if (argc > 2 && !pin_found)
343 gui->log ("Net %s has no pin %s\n", argv[1], argv[2]);
344 return 1;
346 else if (!net_found)
348 gui->log ("No net named %s\n", argv[1]);
350 #ifdef HAVE_REGCOMP
351 if (use_re)
352 regfree (&elt_pattern);
353 #endif
355 return 0;
358 HID_Action netlist_action_list[] = {
359 {"net", 0, Netlist,
360 netlist_help, netlist_syntax}
362 {"netlist", 0, Netlist,
363 netlist_help, netlist_syntax}
366 REGISTER_ACTIONS (netlist_action_list)