Updated copyright text/header in most source files.
[geda-gaf.git] / gnetlist / src / g_netlist.c
blob7f89ebe432a283fd3ff2f24b7f8541864a5bf88d
1 /* gEDA - GPL Electronic Design Automation
2 * gnetlist - gEDA Netlist
3 * Copyright (C) 1998-2007 Ales Hvezda
4 * Copyright (C) 1998-2007 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., 59 Temple Place, Suite 330, Boston, MA 02111 USA
21 #include <config.h>
23 #include <stdio.h>
24 #ifdef HAVE_STRING_H
25 #include <string.h>
26 #endif
27 #include <math.h>
29 #include <libgeda/libgeda.h>
31 #include "../include/globals.h"
32 #include "../include/prototype.h"
34 #ifdef HAVE_LIBDMALLOC
35 #include <dmalloc.h>
36 #endif
39 /* current project */
40 static TOPLEVEL *project_current;
42 void g_set_project_current(TOPLEVEL * pr_current)
44 project_current = pr_current;
48 static void
49 hash_table_2_list (gpointer key,
50 gpointer value,
51 gpointer user_data)
53 SCM* plist = (SCM*)user_data;
55 *plist = scm_cons (scm_makfrom0str ((char*)value),
56 *plist);
59 /* this function will only return a unique list of packages */
60 SCM g_get_packages(SCM level)
62 SCM list = SCM_EOL;
63 GHashTable *ht;
65 NETLIST *nl_current = NULL;
67 SCM_ASSERT(scm_is_string (level), level, SCM_ARG1, "gnetlist:get-pins");
69 /* build a hash table */
70 ht = g_hash_table_new (g_str_hash, g_str_equal);
71 for (nl_current = netlist_head; nl_current != NULL;
72 nl_current = nl_current->next) {
73 if (nl_current->component_uref != NULL) {
74 /* add component_uref in the hash table */
75 /* uniqueness of component_uref is guaranteed by the hashtable */
76 g_hash_table_insert (ht,
77 nl_current->component_uref,
78 nl_current->component_uref);
81 /* now create a scheme list of the entries in the hash table */
82 g_hash_table_foreach (ht, hash_table_2_list, &list);
83 g_hash_table_destroy (ht);
85 return list;
88 /* this function will only return a non unique list of packages */
89 SCM g_get_non_unique_packages(SCM level)
91 SCM list = SCM_EOL;
93 NETLIST *nl_current = NULL;
95 SCM_ASSERT(scm_is_string (level), level, SCM_ARG1, "gnetlist:get-pins");
97 for (nl_current = netlist_head; nl_current != NULL;
98 nl_current = nl_current->next) {
99 if (nl_current->component_uref != NULL) {
100 list = scm_cons (scm_makfrom0str (nl_current->component_uref),
101 list);
105 return list;
109 SCM g_get_pins(SCM uref)
111 SCM list = SCM_EOL;
112 NETLIST *nl_current;
113 CPINLIST *pl_current;
115 SCM_ASSERT(scm_is_string (uref), uref, SCM_ARG1, "gnetlist:get-pins");
117 /* here is where you make it multi page aware */
118 nl_current = netlist_head;
120 /* search for the first instance */
121 /* through the entire list */
122 while (nl_current != NULL) {
124 if (nl_current->component_uref) {
125 if (strcmp(nl_current->component_uref, SCM_STRING_CHARS (uref)) == 0) {
127 pl_current = nl_current->cpins;
128 while (pl_current != NULL) {
129 if (pl_current->pin_number) {
130 list = scm_cons (scm_makfrom0str (pl_current->pin_number),
131 list);
133 pl_current = pl_current->next;
137 nl_current = nl_current->next;
140 return (list);
143 SCM g_get_all_nets(SCM scm_level)
146 SCM list = SCM_EOL;
147 NETLIST *nl_current;
148 CPINLIST *pl_current;
149 char *net_name;
151 SCM_ASSERT(scm_is_string (scm_level), scm_level, SCM_ARG1,
152 "gnetlist:get-all-nets");
154 nl_current = netlist_head;
156 /* walk through the list of components, and through the list
157 * of individual pins on each, adding net names to the list
158 * being careful to ignore duplicates, and unconnected pins
160 while (nl_current != NULL) {
161 pl_current = nl_current->cpins;
162 while (pl_current != NULL) {
163 if (pl_current->net_name) {
165 net_name = pl_current->net_name;
166 /* filter off unconnected pins */
167 if (strncmp(net_name, "unconnected_pin", 15) != 0) {
168 /*printf("Got net: `%s'\n",net_name); */
169 /* add the net name to the list */
170 #if DEBUG
171 printf("Got net: `%s'\n", net_name);
172 printf("pin %s\n", pl_current->pin_number);
173 #endif
174 list = scm_cons (scm_makfrom0str (net_name),
175 list);
178 pl_current = pl_current->next;
180 nl_current = nl_current->next;
183 return list;
186 SCM g_get_all_unique_nets(SCM scm_level)
189 SCM list = SCM_EOL;
190 SCM x = SCM_EOL;
191 NETLIST *nl_current;
192 CPINLIST *pl_current;
193 char *net_name;
195 SCM_ASSERT(scm_is_string (scm_level), scm_level, SCM_ARG1,
196 "gnetlist:get-all-unique-nets");
198 nl_current = netlist_head;
200 /* walk through the list of components, and through the list
201 * of individual pins on each, adding net names to the list
202 * being careful to ignore duplicates, and unconnected pins
204 while (nl_current != NULL) {
205 pl_current = nl_current->cpins;
206 while (pl_current != NULL) {
207 if (pl_current->net_name) {
209 net_name = pl_current->net_name;
210 /* filter off unconnected pins */
211 if (strncmp(net_name, "unconnected_pin", 15) != 0) {
212 /* add the net name to the list */
213 /*printf("Got net: `%s'\n",net_name); */
215 x = scm_makfrom0str (net_name);
216 if (scm_member(x, list) == SCM_BOOL_F) {
217 list = scm_cons (x, list);
221 pl_current = pl_current->next;
223 nl_current = nl_current->next;
226 return list;
229 /* given a net name, return all connections */
230 SCM g_get_all_connections(SCM scm_netname)
233 SCM list = SCM_EOL;
234 SCM x = SCM_EOL;
235 SCM is_member = SCM_EOL;
236 SCM connlist = SCM_EOL;
237 SCM pairlist = SCM_EOL;
238 NETLIST *nl_current;
239 CPINLIST *pl_current;
240 NET *n_current;
241 char *wanted_net_name;
242 char *net_name;
243 char *pin;
244 char *uref;
246 SCM_ASSERT(scm_is_string(scm_netname), scm_netname, SCM_ARG1,
247 "gnetlist:get-all-connections");
249 wanted_net_name = SCM_STRING_CHARS (scm_netname);
251 if (wanted_net_name == NULL) {
252 return list;
256 nl_current = netlist_head;
258 /* walk through the list of components, and through the list
259 * of individual pins on each, adding net names to the list
260 * being careful to ignore duplicates, and unconnected pins
262 while (nl_current != NULL) {
263 pl_current = nl_current->cpins;
264 while (pl_current != NULL) {
265 if (pl_current->net_name) {
267 net_name = pl_current->net_name;
268 /* filter off unconnected pins */
269 if (strcmp(net_name, wanted_net_name) == 0) {
270 /* add the net name to the list */
272 #if DEBUG
273 printf("found net: `%s'\n", net_name);
274 #endif
276 n_current = pl_current->nets;
277 while (n_current != NULL) {
279 if (n_current->connected_to) {
281 pairlist = SCM_EOL;
282 pin = (char *) g_malloc(sizeof(char) *
283 strlen(n_current->
284 connected_to));
285 uref =
286 (char *) g_malloc(sizeof(char) *
287 strlen(n_current->
288 connected_to));
290 sscanf(n_current->connected_to,
291 "%s %s", uref, pin);
293 pairlist = scm_list_n (scm_makfrom0str (uref),
294 scm_makfrom0str (pin),
295 SCM_UNDEFINED);
297 x = pairlist;
298 is_member = scm_member(x, connlist);
300 if (is_member == SCM_BOOL_F) {
301 connlist = scm_cons (pairlist, connlist);
304 g_free(uref);
305 g_free(pin);
307 n_current = n_current->next;
311 pl_current = pl_current->next;
313 nl_current = nl_current->next;
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");
343 wanted_uref = SCM_STRING_CHARS (scm_uref);
344 wanted_pin = SCM_STRING_CHARS (scm_pin);
346 nl_current = netlist_head;
348 /* search for the first instance */
349 /* through the entire list */
350 while (nl_current != NULL) {
352 if (nl_current->component_uref) {
354 if (strcmp(nl_current->component_uref, wanted_uref) == 0) {
356 pl_current = nl_current->cpins;
357 while (pl_current != NULL) {
359 if (pl_current->pin_number) {
360 if (strcmp(pl_current->pin_number, wanted_pin) ==
361 0) {
363 n_current = pl_current->nets;
365 if (pl_current->net_name) {
366 net_name = pl_current->net_name;
369 while (n_current != NULL) {
371 if (n_current->connected_to) {
373 pairlist = SCM_EOL;
374 pin = (char *) g_malloc(sizeof(char) *
375 strlen
376 (n_current->
377 connected_to));
378 uref =
379 (char *) g_malloc(sizeof(char) *
380 strlen(n_current->
381 connected_to));
383 sscanf(n_current->connected_to,
384 "%s %s", uref, pin);
386 pairlist = scm_list_n (scm_makfrom0str (uref),
387 scm_makfrom0str (pin),
388 SCM_UNDEFINED);
390 pinslist = scm_cons (pairlist, pinslist);
392 g_free(uref);
393 g_free(pin);
395 n_current = n_current->next;
399 pl_current = pl_current->next;
403 nl_current = nl_current->next;
406 if (net_name != NULL) {
407 outerlist = scm_cons (scm_makfrom0str (net_name), pinslist);
408 } else {
409 outerlist = scm_cons (scm_makfrom0str ("ERROR_INVALID_PIN"),
410 outerlist);
411 fprintf(stderr, "Invalid wanted_pin passed to get-nets [%s]\n",
412 wanted_pin);
415 return (outerlist);
419 /* Given a uref, Return a list of pairs, each pair contains the name
420 * of the pin, and the name of the net connected to that pin.
422 SCM g_get_pins_nets(SCM scm_uref)
424 SCM pinslist = SCM_EOL;
425 SCM pairlist = SCM_EOL;
426 NETLIST *nl_current = NULL;
427 CPINLIST *pl_current = NULL;
429 char *wanted_uref = NULL;
430 char *net_name = NULL;
431 char *pin = NULL;
433 SCM_ASSERT(scm_is_string (scm_uref),
434 scm_uref, SCM_ARG1, "gnetlist:get-pins-nets");
436 wanted_uref = SCM_STRING_CHARS (scm_uref);
438 /* search for the any instances */
439 /* through the entire list */
440 for (nl_current = netlist_head; nl_current != NULL;
441 nl_current = nl_current->next) {
443 /* is there a uref? */
444 if (nl_current->component_uref) {
445 /* is it the one we want ? */
446 if (strcmp(nl_current->component_uref, wanted_uref) == 0) {
448 for (pl_current = nl_current->cpins; pl_current != NULL;
449 pl_current = pl_current->next) {
450 /* is there a valid pin number and a valid name ? */
451 if (pl_current->pin_number) {
452 if (pl_current->net_name) {
453 /* yes, add it to the list */
454 pin = pl_current->pin_number;
455 net_name = pl_current->net_name;
457 pairlist = scm_cons (scm_makfrom0str (pin),
458 scm_makfrom0str (net_name));
459 pinslist = scm_cons (pairlist, pinslist);
468 pinslist = scm_reverse (pinslist); /* pins are in reverse order on the way
469 * out
471 return (pinslist);
475 SCM g_get_package_attribute(SCM scm_uref, SCM scm_wanted_attrib)
477 SCM scm_return_value;
478 NETLIST *nl_current;
479 char *uref;
480 char *wanted_attrib;
481 char *return_value = NULL;
483 SCM_ASSERT(scm_is_string (scm_uref),
484 scm_uref, SCM_ARG1, "gnetlist:get-package-attribute");
486 SCM_ASSERT(scm_is_string (scm_wanted_attrib),
487 scm_wanted_attrib, SCM_ARG2, "gnetlist:get-package-attribute");
489 uref = SCM_STRING_CHARS (scm_uref);
490 wanted_attrib = SCM_STRING_CHARS (scm_wanted_attrib);
492 /* here is where you make it multi page aware */
493 nl_current = netlist_head;
495 /* search for the first instance */
496 /* through the entire list */
497 while (nl_current != NULL) {
499 if (nl_current->component_uref) {
500 if (strcmp(nl_current->component_uref, uref) == 0) {
502 /* first search outside the symbol */
503 return_value =
504 o_attrib_search_name_single(nl_current->object_ptr,
505 wanted_attrib, NULL);
507 if (return_value) {
508 break;
511 /* now search inside the symbol */
512 return_value =
513 o_attrib_search_name(nl_current->object_ptr->
514 complex->prim_objs, wanted_attrib,
517 break;
520 nl_current = nl_current->next;
523 if (return_value) {
524 scm_return_value = scm_makfrom0str (return_value);
525 } else {
526 scm_return_value = scm_makfrom0str ("unknown");
529 return (scm_return_value);
532 /* takes a uref and pinseq number and returns wanted_attribute associated */
533 /* with that pinseq pin and component */
534 SCM g_get_attribute_by_pinseq(SCM scm_uref, SCM scm_pinseq,
535 SCM scm_wanted_attrib)
537 SCM scm_return_value;
538 NETLIST *nl_current;
539 char *uref;
540 char *pinseq;
541 char *wanted_attrib;
542 char *pinseq_attrib;
543 char *return_value = NULL;
544 OBJECT *o_text_object;
545 OBJECT *o_pin_object;
547 SCM_ASSERT(scm_is_string (scm_uref),
548 scm_uref, SCM_ARG1, "gnetlist:get-pin-number-seq");
550 SCM_ASSERT(scm_is_string (scm_pinseq),
551 scm_pinseq, SCM_ARG2, "gnetlist:get-pin-number-seq");
554 SCM_ASSERT(scm_is_string (scm_wanted_attrib),
555 scm_wanted_attrib, SCM_ARG3, "gnetlist:get-pin-attribute-seq");
557 uref = SCM_STRING_CHARS (scm_uref);
558 pinseq = SCM_STRING_CHARS (scm_pinseq);
559 wanted_attrib = SCM_STRING_CHARS (scm_wanted_attrib);
561 pinseq_attrib = g_strconcat ("pinseq=", pinseq, NULL);
563 #if DEBUG
564 printf("gnetlist:g_netlist.c:g_get_attribute_by_pinseq -- \n");
565 printf(" wanted uref = %s\n", uref);
566 printf(" wanted_pin_seq = %s\n", pinseq);
567 printf(" wanted_attrib = %s\n", wanted_attrib);
568 #endif
570 /* here is where you make it multi page aware */
571 nl_current = netlist_head;
573 /* search for the first instance */
574 /* through the entire list */
575 while (nl_current != NULL) {
577 if (nl_current->component_uref) {
578 if (strcmp(nl_current->component_uref, uref) == 0) {
580 /* first search outside the symbol */
581 /* This checks for attributes attached to this component */
582 /* at schematic level */
583 o_text_object = o_attrib_search_string_single(nl_current->object_ptr,
584 pinseq_attrib);
585 if (o_text_object && o_text_object->attached_to) {
586 o_pin_object = o_attrib_return_parent(o_text_object->attached_to);
588 if (o_pin_object) {
589 return_value = o_attrib_search_name_single(o_pin_object,
590 wanted_attrib,
591 NULL);
592 if (return_value) {
593 break;
597 } else {
598 #if DEBUG
599 printf("gnetlist:g_netlist.c:g_get_attribute_by_pinseq -- ");
600 printf("can't find pinseq at schematic level\n");
601 #endif
605 /* now search inside the symbol */
606 /* This checks for attributes attached at the symbol level */
607 o_text_object =
608 o_attrib_search_string_list(nl_current->object_ptr->
609 complex->prim_objs, pinseq_attrib);
611 if (o_text_object && o_text_object->attached_to) {
612 o_pin_object = o_attrib_return_parent(o_text_object->attached_to);
613 if (o_pin_object) {
614 return_value = o_attrib_search_name_single(o_pin_object,
615 wanted_attrib,
616 NULL);
617 if (return_value) {
618 break;
622 /* Don't break until we search the whole netlist to handle slotted */
623 /* parts. 4.28.2007 -- SDB. */
626 nl_current = nl_current->next;
629 if (return_value) {
630 scm_return_value = scm_makfrom0str (return_value);
631 } else {
632 scm_return_value = scm_makfrom0str ("unknown");
635 #if DEBUG
636 printf("gnetlist:g_netlist.c:g_get_attribute_by_pinseq -- ");
637 printf("return_value: %s\n", return_value);
638 #endif
640 g_free(pinseq_attrib);
642 return (scm_return_value);
645 /* this takes a pin number and returns the appropriate attribute on that pin*/
646 /* scm_pin is the value associated with the pinnumber= attribute and uref */
647 SCM g_get_attribute_by_pinnumber(SCM scm_uref, SCM scm_pin, SCM
648 scm_wanted_attrib)
650 SCM scm_return_value;
651 NETLIST *nl_current;
652 OBJECT *pin_object;
653 char *uref;
654 char *pin;
655 char *wanted_attrib;
656 char *return_value = NULL;
657 int done = FALSE;
659 SCM_ASSERT(scm_is_string (scm_uref),
660 scm_uref, SCM_ARG1, "gnetlist:get-pin-attribute");
662 SCM_ASSERT(scm_is_string (scm_pin),
663 scm_pin, SCM_ARG2, "gnetlist:get-pin-attribute");
665 SCM_ASSERT(scm_is_string (scm_wanted_attrib),
666 scm_wanted_attrib, SCM_ARG3, "gnetlist:get-pin-attribute");
668 uref = SCM_STRING_CHARS (scm_uref);
669 pin = SCM_STRING_CHARS (scm_pin);
670 wanted_attrib = SCM_STRING_CHARS (scm_wanted_attrib);
672 /* here is where you make it multi page aware */
673 nl_current = netlist_head;
675 /* search for the first instance */
676 /* through the entire list */
677 while (nl_current != NULL && !done) {
678 if (nl_current->component_uref) {
679 if (strcmp(nl_current->component_uref, uref) == 0) {
681 pin_object =
682 o_complex_return_pin_object(nl_current->object_ptr,
683 pin);
685 if (pin_object) {
687 /* only look for the first occurance of wanted_attrib */
688 return_value =
689 o_attrib_search_attrib_name(pin_object->attribs,
690 wanted_attrib, 0);
691 #if DEBUG
692 if (return_value) {
693 printf("GOT IT: %s\n", return_value);
695 #endif
696 } else if (strcmp("pintype",
697 wanted_attrib) == 0) {
698 if (nl_current->cpins) {
699 CPINLIST *pinobject =
700 s_cpinlist_search_pin(nl_current->cpins, pin);
701 if (pinobject) {
702 return_value="pwr";
703 #if DEBUG
705 printf("Supplied pintype 'pwr' for artificial pin '%s' of '%s'\n",
706 pin, uref);
707 #endif
713 nl_current = nl_current->next;
716 if (return_value) {
717 scm_return_value = scm_makfrom0str (return_value);
718 } else {
719 scm_return_value = scm_makfrom0str ("unknown");
722 return (scm_return_value);
726 /* returns value of attribute otherwise string "none" */
727 /* still highly temp and doesn't work right */
728 SCM g_get_toplevel_attribute(SCM scm_wanted_attrib)
730 char *wanted_attrib;
731 char *return_value;
732 SCM scm_return_value;
734 SCM_ASSERT(scm_is_string (scm_wanted_attrib),
735 scm_wanted_attrib, SCM_ARG1, "gnetlist:get-toplevel-attribute");
737 wanted_attrib = SCM_STRING_CHARS (scm_wanted_attrib);
739 return_value = o_attrib_search_toplevel_all(project_current->page_head,
740 wanted_attrib);
742 if (return_value) {
743 scm_return_value = scm_makfrom0str (return_value);
744 g_free(return_value);
745 } else {
746 scm_return_value = scm_makfrom0str ("not found");
749 return (scm_return_value);
752 #if 0 /* No longer needed, but the netlist_mode variable is still used */
753 SCM g_set_netlist_mode(SCM mode)
755 char *string;
757 string = SCM_STRING_CHARS (mode);
759 if (strcmp(string, "gEDA") == 0) {
760 netlist_mode = gEDA;
761 } else if (strcmp(string, "SPICE") == 0) {
762 netlist_mode = SPICE;
763 } else if (strcmp(string, "TANGO") == 0) {
764 netlist_mode = TANGO;
766 #if DEBUG
767 printf("netlist_mode: %s %d\n", string, netlist_mode);
768 #endif
770 return (scm_from_int (0));
772 #endif
774 /* Given an uref, return a list of used slots in the schematic */
775 /* in the form: (1 2 3 4). Repeated slots are returned. */
776 SCM g_get_slots(SCM scm_uref)
778 NETLIST *nl_current;
779 char *uref;
780 gchar *slot = NULL;
781 char *slot_tmp = NULL;
782 SCM slots_list = SCM_EOL;
783 SCM slot_number;
786 SCM_ASSERT(scm_is_string (scm_uref),
787 scm_uref, SCM_ARG1, "gnetlist:get-slots-used-of-package");
789 uref = SCM_STRING_CHARS (scm_uref);
791 /* here is where you make it multi page aware */
792 nl_current = netlist_head;
794 /* search for the first instance */
795 /* through the entire list */
796 while (nl_current != NULL) {
798 if (nl_current->component_uref) {
799 if (strcmp(nl_current->component_uref, uref) == 0) {
801 /* first search outside the symbol */
802 slot_tmp =
803 o_attrib_search_name_single(nl_current->object_ptr,
804 "slot", NULL);
806 if (!slot_tmp) {
807 /* if not found, search inside the symbol */
808 slot_tmp =
809 o_attrib_search_name(nl_current->object_ptr->
810 complex->prim_objs, "slot",
813 /* When a package has no slot attribute, then assume it's slot number 1 */
814 if (!slot_tmp) {
815 slot_tmp=g_strdup("1");
817 slot = g_strconcat ("#d", slot_tmp, NULL);
818 g_free (slot_tmp);
819 slot_number = scm_string_to_number(scm_makfrom0str (slot),
820 scm_from_int(10));
821 g_free (slot);
822 if (slot_number != SCM_BOOL_F) {
823 slots_list = scm_cons (slot_number, slots_list);
825 else
826 fprintf(stderr, "Uref %s: Bad slot number: %s.\n", uref, slot_tmp);
829 nl_current = nl_current->next;
832 slots_list = scm_sort_list_x(slots_list,
833 SCM_VARIABLE_REF (scm_c_module_lookup (
834 scm_current_module (), "<")));
836 return (slots_list);
839 /* Given an uref, return a unique list of used slots in the schematic */
840 /* in the form: (1 2 3 4). Repeated slots are NOT returned */
841 SCM g_get_unique_slots(SCM scm_uref)
843 NETLIST *nl_current;
844 char *uref;
845 gchar *slot = NULL;
846 char *slot_tmp = NULL;
847 SCM slots_list = SCM_EOL;
848 SCM slot_number;
851 SCM_ASSERT(scm_is_string (scm_uref),
852 scm_uref, SCM_ARG1, "gnetlist:get-unique-slots-used-of-package");
854 uref = SCM_STRING_CHARS (scm_uref);
856 /* here is where you make it multi page aware */
857 nl_current = netlist_head;
859 /* search for the first instance */
860 /* through the entire list */
861 while (nl_current != NULL) {
863 if (nl_current->component_uref) {
864 if (strcmp(nl_current->component_uref, uref) == 0) {
866 /* first search outside the symbol */
867 slot_tmp =
868 o_attrib_search_name_single(nl_current->object_ptr,
869 "slot", NULL);
871 if (!slot_tmp) {
872 /* if not found, search inside the symbol */
873 slot_tmp =
874 o_attrib_search_name(nl_current->object_ptr->
875 complex->prim_objs, "slot",
878 /* When a package has no slot attribute, then assume it's slot number 1 */
879 if (!slot_tmp) {
880 slot_tmp=g_strdup("1");
882 slot = g_strconcat ("#d", slot_tmp, NULL);
883 g_free (slot_tmp);
884 slot_number = scm_string_to_number(scm_makfrom0str (slot),
885 scm_from_int(10));
886 g_free (slot);
887 if (slot_number != SCM_BOOL_F) {
888 if (scm_member(slot_number, slots_list) == SCM_BOOL_F) {
889 slots_list = scm_cons (slot_number, slots_list);
892 else
893 fprintf(stderr, "Uref %s: Bad slot number: %s.\n", uref, slot_tmp);
896 nl_current = nl_current->next;
899 slots_list = scm_sort_list_x(slots_list,
900 SCM_VARIABLE_REF (scm_c_module_lookup (
901 scm_current_module (), "<")));
902 return (slots_list);
907 This function returns certain calling flags to the calling guile prog.
908 The calling flags are returned to Guile as a list of option/value pairs [e.g.
909 ((verbose_mode #t) (interactive_mode #f) . . . ) ]
910 It is used primarily to enable refdes sorting during netlisting via
911 the -s flag. Note that this prog is not very flexible -- the allowed
912 calling flags are hard coded into the function. At some point this
913 should be fixed . . .
914 9.1.2003 -- SDB
916 8.2.2005 -- Carlos Nieves Onega
917 Different modes are now included in the backend_params list, as well as
918 the backend parameters given from the command line. Since the function
919 calling-flag? in scheme/gnetlist.scm returns false if the calling flag was
920 not found, it's only necessary to include the flags being true.
922 SCM g_get_calling_flags()
924 SCM arglist = SCM_EOL;
926 GSList *aux;
928 aux = backend_params;
929 while (aux != NULL) {
930 arglist = scm_cons (scm_list_n (scm_makfrom0str (aux->data),
931 SCM_BOOL (TRUE),
932 SCM_UNDEFINED),
933 arglist);
934 aux = aux->next;
937 return (arglist);
941 /* -------------------------------------------------------------------- *
942 * This fcn returns the command line with which gnetlist was invoked.
943 * It is used to write the first line of a SPICE file when netlisting
944 * to SPICE.
945 * SDB -- 8.22.2004.
946 * -------------------------------------------------------------------- */
947 SCM g_get_command_line()
949 SCM commandline;
951 commandline = scm_makfrom0str (command_line);
953 return (commandline);
957 /* given a net name, an attribute, and a wanted attribute, return all
958 the given attribute of all the graphical objects connected to that
959 net name */
960 SCM g_graphical_objs_in_net_with_attrib_get_attrib (SCM scm_netname, SCM scm_has_attribute, SCM scm_wanted_attribute)
963 SCM list = SCM_EOL;
964 NETLIST *nl_current;
965 CPINLIST *pl_current;
966 char *wanted_net_name;
967 char *wanted_attrib;
968 char *has_attrib;
969 char *net_name;
970 char *attrib_value=NULL;
971 char *has_attrib_value = NULL;
972 char *has_attrib_name = NULL;
974 SCM_ASSERT(scm_is_string (scm_netname), scm_netname, SCM_ARG1,
975 "gnetlist:get-attr-of-conn-graph-objs-with-attr");
977 SCM_ASSERT(scm_is_string (scm_wanted_attribute),
978 scm_wanted_attribute, SCM_ARG2,
979 "gnetlist:get-attr-of-conn-graph-objs-with-attr");
981 SCM_ASSERT(scm_is_string (scm_has_attribute),
982 scm_has_attribute, SCM_ARG3,
983 "gnetlist:get-attr-of-conn-graph-objs-with-attr");
985 wanted_net_name = SCM_STRING_CHARS (scm_netname);
986 wanted_attrib = SCM_STRING_CHARS (scm_wanted_attribute);
987 has_attrib = SCM_STRING_CHARS (scm_has_attribute);
989 if (wanted_net_name == NULL) {
990 return list;
994 nl_current = graphical_netlist_head;
996 /* walk through the list of components, and through the list
997 * of individual pins on each, adding net names to the list
998 * being careful to ignore duplicates, and unconnected pins
1000 while (nl_current != NULL) {
1001 pl_current = nl_current->cpins;
1002 while (pl_current != NULL) {
1003 if (pl_current->net_name) {
1004 net_name = pl_current->net_name;
1005 if (strcmp(net_name, wanted_net_name) == 0) {
1007 if (o_attrib_get_name_value (has_attrib, &has_attrib_name,
1008 &has_attrib_value) != 0) {
1009 attrib_value =
1010 o_attrib_search_name_single(nl_current->object_ptr,
1011 has_attrib_name, NULL);
1013 if ( ((has_attrib_value == NULL) && (attrib_value == NULL)) ||
1014 ((has_attrib_value != NULL) && (attrib_value != NULL) &&
1015 (strcmp(attrib_value, has_attrib_value) == 0)) ) {
1016 g_free (attrib_value);
1017 attrib_value = o_attrib_search_name_single(nl_current->object_ptr,
1018 wanted_attrib, NULL);
1019 if (attrib_value) {
1020 list = scm_cons (scm_makfrom0str (attrib_value), list);
1022 g_free (attrib_value);
1024 g_free (has_attrib_name);
1025 g_free (has_attrib_value);
1029 pl_current = pl_current->next;
1031 nl_current = nl_current->next;
1034 return list;
1042 * This function is in s_rename.c: SCM g_get_renamed_nets(SCM scm_level)