gsch2pcb: Make --m4-file and -m4-pcbdir arguments work again.
[geda-gaf/peter-b.git] / gnetlist / src / g_netlist.c
blobcf6d5108e2362152f5cfcd46b3d13c4d3146d9d2
1 /* gEDA - GPL Electronic Design Automation
2 * gnetlist - gEDA Netlist
3 * Copyright (C) 1998-2010 Ales Hvezda
4 * Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details)
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include <config.h>
22 #include <missing.h>
24 #include <stdio.h>
25 #ifdef HAVE_STRING_H
26 #include <string.h>
27 #endif
28 #include <math.h>
30 #include <libgeda/libgeda.h>
31 #include <libgeda/libgedaguile.h>
33 #include "../include/globals.h"
34 #include "../include/prototype.h"
36 #ifdef HAVE_LIBDMALLOC
37 #include <dmalloc.h>
38 #endif
41 SCM g_scm_c_get_uref (TOPLEVEL *toplevel, OBJECT *object)
43 SCM func = scm_variable_ref (scm_c_lookup ("get-uref"));
44 SCM object_smob = edascm_from_object (object);
45 SCM exp = scm_list_2 (func, object_smob);
47 return g_scm_eval_protected (exp, SCM_UNDEFINED);
51 /* this function will only return a unique list of packages */
52 SCM g_get_packages(SCM level)
54 SCM list = SCM_EOL;
55 GHashTable *ht;
57 NETLIST *nl_current = NULL;
59 SCM_ASSERT(scm_is_string (level), level, SCM_ARG1, "gnetlist:get-pins");
61 /* build a hash table */
62 ht = g_hash_table_new (g_str_hash, g_str_equal);
63 for (nl_current = netlist_head; nl_current != NULL;
64 nl_current = nl_current->next) {
65 if (nl_current->component_uref != NULL) {
66 /* add component_uref in the hash table */
67 /* uniqueness of component_uref is guaranteed by the hashtable */
69 if (g_hash_table_lookup (ht, nl_current->component_uref) == NULL) {
70 g_hash_table_insert (ht, nl_current->component_uref,
71 nl_current->component_uref);
72 list = scm_cons (scm_from_utf8_string (nl_current->component_uref),
73 list);
77 g_hash_table_destroy (ht);
79 return list;
82 /* this function will only return a non unique list of packages */
83 SCM g_get_non_unique_packages(SCM level)
85 SCM list = SCM_EOL;
87 NETLIST *nl_current = NULL;
89 SCM_ASSERT(scm_is_string (level), level, SCM_ARG1, "gnetlist:get-pins");
91 for (nl_current = netlist_head; nl_current != NULL;
92 nl_current = nl_current->next) {
93 if (nl_current->component_uref != NULL) {
94 list = scm_cons (scm_from_utf8_string (nl_current->component_uref),
95 list);
99 return list;
103 SCM g_get_pins(SCM scm_uref)
105 char *uref;
106 SCM list = SCM_EOL;
107 NETLIST *nl_current;
108 CPINLIST *pl_current;
110 SCM_ASSERT(scm_is_string (scm_uref), scm_uref, SCM_ARG1, "gnetlist:get-pins");
112 uref = scm_to_utf8_string (scm_uref);
114 /* here is where you make it multi page aware */
115 nl_current = netlist_head;
117 /* search for the first instance */
118 /* through the entire list */
119 while (nl_current != NULL) {
121 if (nl_current->component_uref) {
122 if (strcmp(nl_current->component_uref, uref) == 0) {
124 pl_current = nl_current->cpins;
125 while (pl_current != NULL) {
126 if (pl_current->pin_number) {
127 list = scm_cons (scm_from_utf8_string (pl_current->pin_number),
128 list);
130 pl_current = pl_current->next;
134 nl_current = nl_current->next;
137 free (uref);
139 return (list);
142 SCM g_get_all_nets(SCM scm_level)
145 SCM list = SCM_EOL;
146 NETLIST *nl_current;
147 CPINLIST *pl_current;
148 char *net_name;
150 SCM_ASSERT(scm_is_string (scm_level), scm_level, SCM_ARG1,
151 "gnetlist:get-all-nets");
153 nl_current = netlist_head;
155 /* walk through the list of components, and through the list
156 * of individual pins on each, adding net names to the list
157 * being careful to ignore duplicates, and unconnected pins
159 while (nl_current != NULL) {
160 pl_current = nl_current->cpins;
161 while (pl_current != NULL) {
162 if (pl_current->net_name) {
164 net_name = pl_current->net_name;
165 /* filter off unconnected pins */
166 if (strncmp(net_name, "unconnected_pin", 15) != 0) {
167 /*printf("Got net: `%s'\n",net_name); */
168 /* add the net name to the list */
169 #if DEBUG
170 printf("Got net: `%s'\n", net_name);
171 printf("pin %s\n", pl_current->pin_number);
172 #endif
173 list = scm_cons (scm_from_utf8_string (net_name),
174 list);
177 pl_current = pl_current->next;
179 nl_current = nl_current->next;
182 return list;
185 SCM g_get_all_unique_nets(SCM scm_level)
188 SCM list = SCM_EOL;
189 SCM x = SCM_EOL;
190 NETLIST *nl_current;
191 CPINLIST *pl_current;
192 char *net_name;
194 SCM_ASSERT(scm_is_string (scm_level), scm_level, SCM_ARG1,
195 "gnetlist:get-all-unique-nets");
197 nl_current = netlist_head;
199 /* walk through the list of components, and through the list
200 * of individual pins on each, adding net names to the list
201 * being careful to ignore duplicates, and unconnected pins
203 while (nl_current != NULL) {
204 pl_current = nl_current->cpins;
205 while (pl_current != NULL) {
206 if (pl_current->net_name) {
208 net_name = pl_current->net_name;
209 /* filter off unconnected pins */
210 if (strncmp(net_name, "unconnected_pin", 15) != 0) {
211 /* add the net name to the list */
212 /*printf("Got net: `%s'\n",net_name); */
214 x = scm_from_utf8_string (net_name);
215 if (scm_is_false (scm_member (x, list))) {
216 list = scm_cons (x, list);
220 pl_current = pl_current->next;
222 nl_current = nl_current->next;
225 return list;
228 /* given a net name, return all connections */
229 SCM g_get_all_connections(SCM scm_netname)
232 SCM list = SCM_EOL;
233 SCM x = SCM_EOL;
234 SCM is_member = SCM_EOL;
235 SCM connlist = SCM_EOL;
236 SCM pairlist = SCM_EOL;
237 NETLIST *nl_current;
238 CPINLIST *pl_current;
239 NET *n_current;
240 char *wanted_net_name;
241 char *net_name;
242 char *pin;
243 char *uref;
245 SCM_ASSERT(scm_is_string(scm_netname), scm_netname, SCM_ARG1,
246 "gnetlist:get-all-connections");
248 wanted_net_name = scm_to_utf8_string (scm_netname);
250 if (wanted_net_name == NULL) {
251 return list;
255 nl_current = netlist_head;
257 /* walk through the list of components, and through the list
258 * of individual pins on each, adding net names to the list
259 * being careful to ignore duplicates, and unconnected pins
261 while (nl_current != NULL) {
262 pl_current = nl_current->cpins;
263 while (pl_current != NULL) {
264 if (pl_current->net_name) {
266 net_name = pl_current->net_name;
267 /* filter off unconnected pins */
268 if (strcmp(net_name, wanted_net_name) == 0) {
269 /* add the net name to the list */
271 #if DEBUG
272 printf("found net: `%s'\n", net_name);
273 #endif
275 n_current = pl_current->nets;
276 while (n_current != NULL) {
278 if (n_current->connected_to) {
280 pairlist = SCM_EOL;
281 pin = (char *) g_malloc(sizeof(char) *
282 strlen(n_current->
283 connected_to));
284 uref =
285 (char *) g_malloc(sizeof(char) *
286 strlen(n_current->
287 connected_to));
289 sscanf(n_current->connected_to,
290 "%s %s", uref, pin);
292 pairlist = scm_list_n (scm_from_utf8_string (uref),
293 scm_from_utf8_string (pin),
294 SCM_UNDEFINED);
296 x = pairlist;
297 is_member = scm_member(x, connlist);
299 if (scm_is_false (is_member)) {
300 connlist = scm_cons (pairlist, connlist);
303 g_free(uref);
304 g_free(pin);
306 n_current = n_current->next;
310 pl_current = pl_current->next;
312 nl_current = nl_current->next;
315 free (wanted_net_name);
316 return connlist;
319 /* Given a uref and a pin number return a list of: */
320 /* (netname (uref pin) (uref pin) ... ) */
321 SCM g_get_nets(SCM scm_uref, SCM scm_pin)
323 SCM outerlist = SCM_EOL;
324 SCM pinslist = SCM_EOL;
325 SCM pairlist = SCM_EOL;
326 NETLIST *nl_current = NULL;
327 CPINLIST *pl_current = NULL;
328 NET *n_current;
329 char *wanted_uref = NULL;
330 char *wanted_pin = NULL;
331 char *net_name = NULL;
333 char *pin;
334 char *uref;
336 SCM_ASSERT(scm_is_string (scm_uref), scm_uref, SCM_ARG1,
337 "gnetlist:get-nets");
339 SCM_ASSERT(scm_is_string (scm_pin), scm_pin, SCM_ARG2,
340 "gnetlist:get-nets");
342 scm_dynwind_begin (0);
344 wanted_uref = scm_to_utf8_string (scm_uref);
345 scm_dynwind_free (wanted_uref);
347 wanted_pin = scm_to_utf8_string (scm_pin);
348 scm_dynwind_free (wanted_pin);
350 nl_current = netlist_head;
352 /* search for the first instance */
353 /* through the entire list */
354 while (nl_current != NULL) {
356 if (nl_current->component_uref) {
358 if (strcmp(nl_current->component_uref, wanted_uref) == 0) {
360 pl_current = nl_current->cpins;
361 while (pl_current != NULL) {
363 if (pl_current->pin_number) {
364 if (strcmp(pl_current->pin_number, wanted_pin) ==
365 0) {
367 n_current = pl_current->nets;
369 if (pl_current->net_name) {
370 net_name = pl_current->net_name;
373 while (n_current != NULL) {
375 if (n_current->connected_to) {
377 pairlist = SCM_EOL;
378 pin = (char *) g_malloc(sizeof(char) *
379 strlen
380 (n_current->
381 connected_to));
382 uref =
383 (char *) g_malloc(sizeof(char) *
384 strlen(n_current->
385 connected_to));
387 sscanf(n_current->connected_to,
388 "%s %s", uref, pin);
390 pairlist = scm_list_n (scm_from_utf8_string (uref),
391 scm_from_utf8_string (pin),
392 SCM_UNDEFINED);
394 pinslist = scm_cons (pairlist, pinslist);
396 g_free(uref);
397 g_free(pin);
399 n_current = n_current->next;
403 pl_current = pl_current->next;
407 nl_current = nl_current->next;
410 scm_dynwind_end ();
412 if (net_name != NULL) {
413 outerlist = scm_cons (scm_from_utf8_string (net_name), pinslist);
414 } else {
415 outerlist = scm_cons (scm_from_utf8_string ("ERROR_INVALID_PIN"),
416 outerlist);
417 fprintf(stderr, "Invalid wanted_pin passed to get-nets [%s]\n",
418 wanted_pin);
421 return (outerlist);
425 /* Given a uref, Return a list of pairs, each pair contains the name
426 * of the pin, and the name of the net connected to that pin.
428 SCM g_get_pins_nets(SCM scm_uref)
430 SCM pinslist = SCM_EOL;
431 SCM pairlist = SCM_EOL;
432 NETLIST *nl_current = NULL;
433 CPINLIST *pl_current = NULL;
435 char *wanted_uref = NULL;
436 char *net_name = NULL;
437 char *pin = NULL;
439 SCM_ASSERT(scm_is_string (scm_uref),
440 scm_uref, SCM_ARG1, "gnetlist:get-pins-nets");
442 wanted_uref = scm_to_utf8_string (scm_uref);
444 /* search for the any instances */
445 /* through the entire list */
446 for (nl_current = netlist_head; nl_current != NULL;
447 nl_current = nl_current->next) {
449 /* is there a uref? */
450 if (nl_current->component_uref) {
451 /* is it the one we want ? */
452 if (strcmp(nl_current->component_uref, wanted_uref) == 0) {
454 for (pl_current = nl_current->cpins; pl_current != NULL;
455 pl_current = pl_current->next) {
456 /* is there a valid pin number and a valid name ? */
457 if (pl_current->pin_number) {
458 if (pl_current->net_name) {
459 /* yes, add it to the list */
460 pin = pl_current->pin_number;
461 net_name = pl_current->net_name;
463 pairlist = scm_cons (scm_from_utf8_string (pin),
464 scm_from_utf8_string (net_name));
465 pinslist = scm_cons (pairlist, pinslist);
474 free (wanted_uref);
476 pinslist = scm_reverse (pinslist); /* pins are in reverse order on the way
477 * out
479 return (pinslist);
483 /*! \brief Get attribute value(s) from a package with given uref.
484 * \par Function Description
485 * This function returns the values of a specific attribute type
486 * attached to the symbol instances with the given refdes.
488 * Every first attribute value found is added to the return list. A
489 * Scheme false value is added if the instance has no such attribute.
491 * \note The order of the values in the return list is the order of
492 * symbol instances within gnetlist (the first element is the value
493 * associated with the first symbol instance).
495 * \param [in] scm_uref Package reference.
496 * \param [in] scm_wanted_attrib Attribute name.
497 * \return A list of attribute values as strings and #f.
499 SCM g_get_all_package_attributes(SCM scm_uref, SCM scm_wanted_attrib)
501 SCM ret = SCM_EOL;
502 NETLIST *nl_current;
503 char *uref;
504 char *wanted_attrib;
506 SCM_ASSERT(scm_is_string (scm_uref),
507 scm_uref, SCM_ARG1, "gnetlist:get-all-package-attributes");
509 SCM_ASSERT(scm_is_string (scm_wanted_attrib),
510 scm_wanted_attrib, SCM_ARG2, "gnetlist:get-all-package-attributes");
512 uref = scm_to_utf8_string (scm_uref);
513 wanted_attrib = scm_to_utf8_string (scm_wanted_attrib);
515 /* here is where you make it multi page aware */
516 nl_current = netlist_head;
518 /* search for uref instances and through the entire list */
519 while (nl_current != NULL) {
521 if (nl_current->component_uref) {
522 if (strcmp(nl_current->component_uref, uref) == 0) {
523 char *value =
524 o_attrib_search_object_attribs_by_name (nl_current->object_ptr,
525 wanted_attrib, 0);
527 ret = scm_cons (value ? scm_from_utf8_string (value) : SCM_BOOL_F, ret);
529 g_free (value);
532 nl_current = nl_current->next;
535 free (uref);
536 free (wanted_attrib);
538 return scm_reverse_x (ret, SCM_EOL);
541 /* takes a uref and pinseq number and returns wanted_attribute associated */
542 /* with that pinseq pin and component */
543 SCM g_get_attribute_by_pinseq(SCM scm_uref, SCM scm_pinseq,
544 SCM scm_wanted_attrib)
546 SCM scm_return_value;
547 NETLIST *nl_current;
548 char *uref;
549 char *pinseq;
550 char *wanted_attrib;
551 char *return_value = NULL;
552 OBJECT *o_pin_object;
554 SCM_ASSERT(scm_is_string (scm_uref),
555 scm_uref, SCM_ARG1, "gnetlist:get-pin-number-seq");
557 SCM_ASSERT(scm_is_string (scm_pinseq),
558 scm_pinseq, SCM_ARG2, "gnetlist:get-pin-number-seq");
561 SCM_ASSERT(scm_is_string (scm_wanted_attrib),
562 scm_wanted_attrib, SCM_ARG3, "gnetlist:get-pin-attribute-seq");
564 scm_dynwind_begin (0);
566 uref = scm_to_utf8_string (scm_uref);
567 scm_dynwind_free (uref);
569 pinseq = scm_to_utf8_string (scm_pinseq);
570 scm_dynwind_free (pinseq);
572 wanted_attrib = scm_to_utf8_string (scm_wanted_attrib);
573 scm_dynwind_free (wanted_attrib);
575 #if DEBUG
576 printf("gnetlist:g_netlist.c:g_get_attribute_by_pinseq -- \n");
577 printf(" wanted uref = %s\n", uref);
578 printf(" wanted_pin_seq = %s\n", pinseq);
579 printf(" wanted_attrib = %s\n", wanted_attrib);
580 #endif
582 /* here is where you make it multi page aware */
583 nl_current = netlist_head;
585 /* search for the first instance */
586 /* through the entire list */
587 while (nl_current != NULL) {
589 if (nl_current->component_uref) {
590 if (strcmp(nl_current->component_uref, uref) == 0) {
592 o_pin_object = o_complex_find_pin_by_attribute (nl_current->object_ptr,
593 "pinseq", pinseq);
595 if (o_pin_object) {
596 return_value =
597 o_attrib_search_object_attribs_by_name (o_pin_object,
598 wanted_attrib, 0);
599 if (return_value) {
600 break;
604 /* Don't break until we search the whole netlist to handle slotted */
605 /* parts. 4.28.2007 -- SDB. */
608 nl_current = nl_current->next;
611 scm_dynwind_end ();
613 if (return_value) {
614 scm_return_value = scm_from_utf8_string (return_value);
615 } else {
616 scm_return_value = scm_from_utf8_string ("unknown");
619 #if DEBUG
620 printf("gnetlist:g_netlist.c:g_get_attribute_by_pinseq -- ");
621 printf("return_value: %s\n", return_value);
622 #endif
624 return (scm_return_value);
627 /* this takes a pin number and returns the appropriate attribute on that pin*/
628 /* scm_pin is the value associated with the pinnumber= attribute and uref */
629 SCM g_get_attribute_by_pinnumber(SCM scm_uref, SCM scm_pin, SCM
630 scm_wanted_attrib)
632 SCM scm_return_value;
633 NETLIST *nl_current;
634 OBJECT *pin_object;
635 char *uref;
636 char *pin;
637 char *wanted_attrib;
638 char *return_value = NULL;
639 int done = FALSE;
641 SCM_ASSERT(scm_is_string (scm_uref),
642 scm_uref, SCM_ARG1, "gnetlist:get-pin-attribute");
644 SCM_ASSERT(scm_is_string (scm_pin),
645 scm_pin, SCM_ARG2, "gnetlist:get-pin-attribute");
647 SCM_ASSERT(scm_is_string (scm_wanted_attrib),
648 scm_wanted_attrib, SCM_ARG3, "gnetlist:get-pin-attribute");
650 scm_dynwind_begin (0);
652 uref = scm_to_utf8_string (scm_uref);
653 scm_dynwind_free (uref);
655 pin = scm_to_utf8_string (scm_pin);
656 scm_dynwind_free (pin);
658 wanted_attrib = scm_to_utf8_string (scm_wanted_attrib);
659 scm_dynwind_free (wanted_attrib);
661 /* here is where you make it multi page aware */
662 nl_current = netlist_head;
664 /* search for the first instance */
665 /* through the entire list */
666 while (nl_current != NULL && !done) {
667 if (nl_current->component_uref) {
668 if (strcmp(nl_current->component_uref, uref) == 0) {
670 pin_object =
671 o_complex_find_pin_by_attribute (nl_current->object_ptr,
672 "pinnumber", pin);
674 if (pin_object) {
676 /* only look for the first occurance of wanted_attrib */
677 return_value =
678 o_attrib_search_object_attribs_by_name (pin_object,
679 wanted_attrib, 0);
680 #if DEBUG
681 if (return_value) {
682 printf("GOT IT: %s\n", return_value);
684 #endif
685 } else if (strcmp("pintype",
686 wanted_attrib) == 0) {
687 if (nl_current->cpins) {
688 CPINLIST *pinobject =
689 s_cpinlist_search_pin(nl_current->cpins, pin);
690 if (pinobject) {
691 return_value="pwr";
692 #if DEBUG
694 printf("Supplied pintype 'pwr' for artificial pin '%s' of '%s'\n",
695 pin, uref);
696 #endif
702 nl_current = nl_current->next;
705 scm_dynwind_end ();
707 if (return_value) {
708 scm_return_value = scm_from_utf8_string (return_value);
709 } else {
710 scm_return_value = scm_from_utf8_string ("unknown");
713 return (scm_return_value);
717 /* returns value of attribute otherwise string "none" */
718 /* still highly temp and doesn't work right */
719 SCM g_get_toplevel_attribute(SCM scm_wanted_attrib)
721 const GList *p_iter;
722 PAGE *p_current;
723 char *wanted_attrib;
724 char *attrib_value = NULL;
725 SCM scm_return_value;
726 TOPLEVEL *toplevel = edascm_c_current_toplevel ();
728 SCM_ASSERT(scm_is_string (scm_wanted_attrib),
729 scm_wanted_attrib, SCM_ARG1, "gnetlist:get-toplevel-attribute");
731 wanted_attrib = scm_to_utf8_string (scm_wanted_attrib);
733 for (p_iter = geda_list_get_glist (toplevel->pages); p_iter != NULL;
734 p_iter = g_list_next (p_iter)) {
735 p_current = p_iter->data;
737 /* only look for first occurrance of the attribute on each page */
738 attrib_value =
739 o_attrib_search_floating_attribs_by_name (s_page_objects (p_current),
740 wanted_attrib, 0);
742 /* Stop when we find the first one */
743 if (attrib_value != NULL)
744 break;
747 free (wanted_attrib);
749 if (attrib_value != NULL) {
750 scm_return_value = scm_from_utf8_string (attrib_value);
751 g_free (attrib_value);
752 } else {
753 scm_return_value = scm_from_utf8_string ("not found");
756 return (scm_return_value);
760 /*! \brief Obtain a list of `-O' backend arguments.
761 * \par Function Description
762 * Returns a list of arguments passed to the gnetlist backend via the
763 * `-O' gnetlist command-line option.
766 g_get_backend_arguments()
768 SCM result = SCM_EOL;
769 GSList *iter;
771 for (iter = backend_params; iter != NULL; iter = g_slist_next (iter)) {
772 result = scm_cons (scm_from_locale_string ((char *) iter->data),
773 result);
776 return scm_reverse_x (result, SCM_UNDEFINED);
780 /*! \brief Get input files from command line.
781 * \par Function Description
782 * This function returns a list of the files named on the command line.
784 * \return A list of filenames as strings.
786 SCM g_get_input_files()
788 SCM list = SCM_EOL;
789 GSList *current = input_files;
791 while (current != NULL) {
792 list = scm_cons (scm_from_locale_string (current->data), list);
793 current = g_slist_next(current);
796 return scm_reverse_x (list, SCM_EOL);
800 /* given a net name, an attribute, and a wanted attribute, return all
801 the given attribute of all the graphical objects connected to that
802 net name */
803 SCM g_graphical_objs_in_net_with_attrib_get_attrib (SCM scm_netname, SCM scm_has_attribute, SCM scm_wanted_attribute)
806 SCM list = SCM_EOL;
807 NETLIST *nl_current;
808 CPINLIST *pl_current;
809 char *wanted_net_name;
810 char *wanted_attrib;
811 char *has_attrib;
812 char *net_name;
813 char *attrib_value=NULL;
814 char *has_attrib_value = NULL;
815 char *has_attrib_name = NULL;
817 SCM_ASSERT(scm_is_string (scm_netname), scm_netname, SCM_ARG1,
818 "gnetlist:get-attr-of-conn-graph-objs-with-attr");
820 SCM_ASSERT(scm_is_string (scm_wanted_attribute),
821 scm_wanted_attribute, SCM_ARG3,
822 "gnetlist:get-attr-of-conn-graph-objs-with-attr");
824 SCM_ASSERT(scm_is_string (scm_has_attribute),
825 scm_has_attribute, SCM_ARG2,
826 "gnetlist:get-attr-of-conn-graph-objs-with-attr");
828 scm_dynwind_begin (0);
830 wanted_net_name = scm_to_utf8_string (scm_netname);
831 if (wanted_net_name == NULL) {
832 return list;
835 scm_dynwind_free (wanted_net_name);
837 wanted_attrib = scm_to_utf8_string (scm_wanted_attribute);
838 scm_dynwind_free (wanted_attrib);
840 has_attrib = scm_to_utf8_string (scm_has_attribute);
841 scm_dynwind_free (has_attrib);
843 nl_current = graphical_netlist_head;
845 /* walk through the list of components, and through the list
846 * of individual pins on each, adding net names to the list
847 * being careful to ignore duplicates, and unconnected pins
849 while (nl_current != NULL) {
850 pl_current = nl_current->cpins;
851 while (pl_current != NULL) {
852 if (pl_current->net_name) {
853 net_name = pl_current->net_name;
854 if (strcmp(net_name, wanted_net_name) == 0) {
856 if (o_attrib_string_get_name_value (has_attrib, &has_attrib_name,
857 &has_attrib_value) != 0) {
858 attrib_value =
859 o_attrib_search_object_attribs_by_name (nl_current->object_ptr,
860 has_attrib_name, 0);
862 if ( ((has_attrib_value == NULL) && (attrib_value == NULL)) ||
863 ((has_attrib_value != NULL) && (attrib_value != NULL) &&
864 (strcmp(attrib_value, has_attrib_value) == 0)) ) {
865 g_free (attrib_value);
866 attrib_value =
867 o_attrib_search_object_attribs_by_name (nl_current->object_ptr,
868 wanted_attrib, 0);
869 if (attrib_value) {
870 list = scm_cons (scm_from_utf8_string (attrib_value), list);
872 g_free (attrib_value);
874 g_free (has_attrib_name);
875 g_free (has_attrib_value);
879 pl_current = pl_current->next;
881 nl_current = nl_current->next;
884 scm_dynwind_end ();
885 return list;
893 * This function is in s_rename.c: SCM g_get_renamed_nets(SCM scm_level)