1 /* gEDA - GPL Electronic Design Automation
2 * gsymcheck - gEDA Symbol Check
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., 675 Mass Ave, Cambridge, MA 02139, USA.
34 #include <libgeda/libgeda.h>
36 #include "../include/struct.h"
37 #include "../include/globals.h"
38 #include "../include/prototype.h"
41 s_check_all(TOPLEVEL
*pr_current
)
48 for ( iter
= geda_list_get_glist( pr_current
->pages
);
50 iter
= g_list_next( iter
) ) {
52 p_current
= (PAGE
*)iter
->data
;
54 if (p_current
->object_head
) {
55 return_status
= return_status
+
56 s_check_symbol(pr_current
, p_current
,
57 p_current
->object_head
);
58 if (!quiet_mode
) s_log_message("\n");
62 return(return_status
);
67 s_check_symbol(TOPLEVEL
*pr_current
, PAGE
*p_current
, OBJECT
*object_head
)
69 SYMCHECK
*s_symcheck
=NULL
;
70 int errors
=0, warnings
=0;
72 s_symcheck
= s_symstruct_init();
75 s_log_message("Checking: %s\n", p_current
->page_filename
);
78 /* check version number */
79 /* s_check_version(object_head, s_symcheck); out */
81 /* check for graphical attribute */
82 s_check_graphical(object_head
, s_symcheck
);
84 /* check for device attribute */
85 s_check_device(object_head
, s_symcheck
);
87 /* check for missing attributes */
88 s_check_missing_attributes(object_head
, s_symcheck
);
90 /* check for obsolete attributes */
91 s_check_obsolete_forbidden_attributes(object_head
, s_symcheck
);
93 /* check for pintype attribute (and multiples) on all pins */
94 s_check_pintype(object_head
, s_symcheck
);
96 /* check for pinseq attribute (and multiples) on all pins */
97 s_check_pinseq(object_head
, s_symcheck
);
99 /* check for pinnumber attribute (and multiples) on all pins */
100 s_check_pinnumber(object_head
, s_symcheck
);
102 /* check for whether all pins are on grid */
103 s_check_pin_ongrid(object_head
, s_symcheck
);
105 /* check for slotdef attribute on all pins (if numslots exists) */
106 s_check_slotdef(object_head
, s_symcheck
);
108 /* check for old pin#=# attributes */
109 s_check_oldpin(object_head
, s_symcheck
);
111 /* check for old pin#=# attributes */
112 s_check_oldslot(object_head
, s_symcheck
);
114 /* check for nets or buses within the symbol (completely disallowed) */
115 s_check_nets_buses(object_head
, s_symcheck
);
117 /* check for connections with in a symbol (completely disallowed) */
118 s_check_connections(object_head
, s_symcheck
);
120 /* now report the info/warnings/errors to the user */
123 /* done, now print out the messages */
124 s_symstruct_print(s_symcheck
);
126 if (s_symcheck
->warning_count
> 0) {
127 s_log_message("%d warnings found ",
128 s_symcheck
->warning_count
);
129 if (verbose_mode
< 2) {
130 s_log_message("(use -vv to view details)\n");
136 if (s_symcheck
->error_count
== 0) {
137 s_log_message("No errors found\n");
138 } else if (s_symcheck
->error_count
== 1) {
139 s_log_message("1 ERROR found ");
140 if (verbose_mode
< 1) {
141 s_log_message("(use -v to view details)\n");
146 } else if (s_symcheck
->error_count
> 1) {
147 s_log_message("%d ERRORS found ",
148 s_symcheck
->error_count
);
149 if (verbose_mode
< 1) {
150 s_log_message("(use -v to view details)\n");
157 errors
= s_symcheck
->error_count
;
158 warnings
= s_symcheck
->warning_count
;
159 s_symstruct_free(s_symcheck
);
162 } else if (warnings
) {
171 s_check_graphical(OBJECT
*o_current
, SYMCHECK
*s_current
)
175 /* look for special graphical tag */
176 temp
= o_attrib_search_name(o_current
, "graphical", 0);
179 s_current
->graphical_symbol
=TRUE
;
185 s_check_device(OBJECT
*o_current
, SYMCHECK
*s_current
)
190 /* search for device attribute */
191 temp
= o_attrib_search_name(o_current
, "device", 0);
193 /* did not find device= attribute */
194 message
= g_strdup ("Missing device= attribute\n");
195 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
197 s_current
->missing_device_attrib
=TRUE
;
198 s_current
->error_count
++;
200 /* found device= attribute */
201 s_current
->missing_device_attrib
=FALSE
;
202 s_current
->device_attribute
=
203 (char *) g_malloc(sizeof(char)*(strlen(temp
)+1));
204 strcpy(s_current
->device_attribute
, temp
);
205 message
= g_strdup_printf ("Found device=%s\n", temp
);
206 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
210 /* check for device = none for graphical symbols */
211 if (temp
&& s_current
->graphical_symbol
&& (strcmp(temp
, "none") == 0)) {
212 s_current
->device_attribute_incorrect
=FALSE
;
213 message
= g_strdup ("Found graphical symbol, device=none\n");
214 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
216 } else if (s_current
->graphical_symbol
) {
217 s_current
->device_attribute_incorrect
=TRUE
;
218 message
= g_strdup ("Found graphical symbol, device= should be set to none\n");
219 s_current
->warning_messages
= g_list_append(s_current
->warning_messages
,
221 s_current
->warning_count
++;
230 s_check_pinseq(OBJECT
*object_head
, SYMCHECK
*s_current
)
234 int found_first
=FALSE
;
235 int missing_pinseq_attrib_sum
=0;
236 int multiple_pinseq_attrib_sum
=0;
239 GList
*found_numbers
= NULL
;
245 o_current
= object_head
;
246 while(o_current
!= NULL
)
249 if (o_current
->type
== OBJ_PIN
)
251 missing_pinseq_attrib_sum
= 0;
252 multiple_pinseq_attrib_sum
= 0;
256 string
= o_attrib_search_name_single_count(o_current
, "pinseq",
260 message
= g_strdup ("Missing pinseq= attribute\n");
261 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
263 missing_pinseq_attrib_sum
++;
264 s_current
->error_count
++;
270 message
= g_strdup_printf ("Found pinseq=%s attribute\n", string
);
271 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
274 number
= g_strdup (string
);
276 if (strcmp(number
, "0") == 0) {
277 message
= g_strdup ("Found pinseq=0 attribute\n");
278 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
280 s_current
->error_count
++;
284 message
= g_strdup_printf (
285 "Found multiple pinseq=%s attributes on one pin\n",
287 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
289 multiple_pinseq_attrib_sum
++;
290 s_current
->error_count
++;
295 /* this is the first attribute found */
297 found_numbers
= g_list_append(found_numbers
, number
);
305 string
= o_attrib_search_name_single_count(o_current
, "pinseq",
309 s_current
->missing_pinseq_attrib
+= missing_pinseq_attrib_sum
;
310 s_current
->multiple_pinseq_attrib
+= multiple_pinseq_attrib_sum
;
314 o_current
= o_current
->next
;
317 ptr1
= found_numbers
;
320 char *string
= (char *) ptr1
->data
;
323 ptr2
= found_numbers
;
324 while(ptr2
&& string
)
326 char *current
= (char *) ptr2
->data
;
328 if (current
&& strcmp(string
, current
) == 0) {
332 ptr2
= g_list_next(ptr2
);
337 message
= g_strdup_printf (
338 "Found duplicate pinseq=%s attribute in the symbol\n",
340 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
342 s_current
->error_count
++;
343 s_current
->duplicate_pinseq_attrib
++;
346 ptr1
= g_list_next(ptr1
);
349 ptr1
= found_numbers
;
353 ptr1
= g_list_next(ptr1
);
355 g_list_free(found_numbers
);
361 s_check_pinnumber(OBJECT
*object_head
, SYMCHECK
*s_current
)
365 int found_first
=FALSE
;
366 int missing_pinnumber_attrib_sum
=0;
367 int multiple_pinnumber_attrib_sum
=0;
371 GList
*found_numbers
= NULL
;
378 char *netpins
= NULL
;
383 while( (net
= o_attrib_search_toplevel(object_head
, "net", counter
)) != NULL
)
385 message
= g_strdup_printf ("Found net=%s attribute\n", net
);
386 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
389 netpins
= u_basic_breakup_string(net
, ':', 1);
392 message
= g_strdup ("Bad net= attribute\n");
393 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
395 s_current
->error_count
++;
409 number
= u_basic_breakup_string(netpins
, ',', j
);
414 message
= g_strdup_printf ("Found pin number %s in net attribute\n",
416 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
420 if (strcmp(number
, "0") == 0) {
421 message
= g_strdup ("Found pinnumber 0 in net= attribute\n");
422 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
424 s_current
->error_count
++;
427 temp
= g_strdup(number
);
428 found_numbers
= g_list_append(found_numbers
, temp
);
430 s_current
->numnetpins
++;
446 o_current
= object_head
;
447 while(o_current
!= NULL
)
450 if (o_current
->type
== OBJ_PIN
)
452 s_current
->numpins
++;
454 missing_pinnumber_attrib_sum
= 0;
455 multiple_pinnumber_attrib_sum
= 0;
459 string
= o_attrib_search_name_single_count(o_current
, "pinnumber",
463 message
= g_strdup ("Missing pinnumber= attribute\n");
464 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
466 missing_pinnumber_attrib_sum
++;
467 s_current
->error_count
++;
472 message
= g_strdup_printf ("Found pinnumber=%s attribute\n", string
);
473 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
477 message
= g_strdup_printf (
478 "Found multiple pinnumber=%s attributes on one pin\n",
480 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
482 multiple_pinnumber_attrib_sum
++;
483 s_current
->error_count
++;
486 number
= g_strdup (string
);
489 if (strcmp(number
, "0") == 0) {
490 message
= g_strdup ("Found pinnumber=0 attribute\n");
491 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
493 s_current
->error_count
++;
496 /* this is the first attribute found */
498 found_numbers
= g_list_append(found_numbers
, number
);
506 string
= o_attrib_search_name_single_count(o_current
, "pinnumber",
510 s_current
->missing_pinnumber_attrib
+= missing_pinnumber_attrib_sum
;
511 s_current
->multiple_pinnumber_attrib
+= multiple_pinnumber_attrib_sum
;
514 o_current
= o_current
->next
;
520 ptr1
= found_numbers
;
523 char *string
= (char *) ptr1
->data
;
526 ptr2
= found_numbers
;
527 while(ptr2
&& string
)
529 char *current
= (char *) ptr2
->data
;
531 if (current
&& strcmp(string
, current
) == 0) {
535 ptr2
= g_list_next(ptr2
);
540 message
= g_strdup_printf (
541 "Found duplicate pinnumber=%s attribute in the symbol\n",
543 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
545 s_current
->error_count
++;
546 s_current
->duplicate_pinnumber_attrib
++;
549 ptr1
= g_list_next(ptr1
);
552 ptr1
= found_numbers
;
556 ptr1
= g_list_next(ptr1
);
558 g_list_free(found_numbers
);
561 sprintf(tempstr
, "%d", s_current
->numpins
+ s_current
->numnetpins
);
562 message
= g_strdup_printf ("Found %s pins inside symbol\n", tempstr
);
563 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
568 s_check_pin_ongrid(OBJECT
*object_head
, SYMCHECK
*s_current
)
575 for (o_current
= object_head
;
577 o_current
= o_current
->next
) {
578 if (o_current
->type
== OBJ_PIN
) {
579 x1
= o_current
->line
->x
[0];
580 y1
= o_current
->line
->y
[0];
581 x2
= o_current
->line
->x
[1];
582 y2
= o_current
->line
->y
[1];
584 if (x1
% 100 != 0 || y1
% 100 != 0) {
585 message
= g_strdup_printf("Found offgrid pin at location"
586 " (x1=%d,y1=%d)\n", x1
, y1
);
587 /* error if it is the whichend, warning if not */
588 if (o_current
->whichend
== 0) {
589 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
591 s_current
->error_count
++;
594 s_current
->warning_messages
= g_list_append(s_current
->warning_messages
,
596 s_current
->warning_count
++;
599 if (x2
% 100 != 0 || y2
% 100 != 0) {
600 message
= g_strdup_printf("Found offgrid pin at location"
601 " (x2=%d,y2=%d)\n", x2
, y2
);
602 /* error when whichend, warning if not */
603 if (o_current
-> whichend
!= 0) {
604 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
606 s_current
->error_count
++;
609 s_current
->warning_messages
= g_list_append(s_current
->warning_messages
,
611 s_current
->warning_count
++;
620 s_check_slotdef(OBJECT
*object_head
, SYMCHECK
*s_current
)
623 char* slotdef
= NULL
;
624 char* slotnum
= NULL
;
627 char numslots_str
[10];
632 /* pinlist will store the pin definitions for each slot */
633 /* example: pinlist[0] = 3,2,8,4,1 ; pinlist[1] = 5,6,8,4,7 */
634 char** pinlist
= NULL
;
639 gboolean error_parsing
= FALSE
;
640 int errors_found
= 0;
642 /* look for numslots to see if this symbol has slotting info */
643 value
= o_attrib_search_name(object_head
, "numslots", 0);
646 message
= g_strdup ("Did not find numslots= attribute, not checking slotting\n");
647 s_current
->warning_messages
= g_list_append(s_current
->warning_messages
,
649 s_current
->warning_count
++;
650 message
= g_strdup ("If this symbol does not need slotting, set numslots to zero (numslots=0)\n");
651 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
656 s_current
->numslots
=atoi(value
);
657 sprintf(numslots_str
, "%d", s_current
->numslots
);
660 message
= g_strdup_printf ("Found numslots=%s attribute\n", numslots_str
);
661 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
664 if (s_current
->numslots
== 0) {
665 message
= g_strdup ("numslots set to zero, symbol does not have slots\n");
666 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
672 pinlist
= (char**)g_malloc0(sizeof(*pinlist
) * s_current
->numslots
);
675 /* get the slotdef attribute */
676 slotdef
= o_attrib_search_name(object_head
, "slotdef", 0);
677 while ((slotdef
!= NULL
) && (!error_parsing
))
680 if (i
> s_current
->numslots
-1) {
682 sprintf(tempstr1
, "%d", i
+1); /* i starts at zero */
683 message
= g_strdup_printf (
684 "Found %s slotdef= attributes. Expecting %s slotdef= attributes\n",
685 tempstr1
, numslots_str
);
686 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
689 s_current
->error_count
++;
690 s_current
->slotting_errors
++;
693 message
= g_strdup_printf ("Found slotdef=%s attribute\n", slotdef
);
694 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
697 slotnum
= u_basic_breakup_string(slotdef
, ':', 0);
700 message
= g_strdup_printf (
701 "Invalid slotdef=%s attributes, not continuing\n",
703 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
705 s_current
->error_count
++;
706 s_current
->slotting_errors
++;
707 error_parsing
= TRUE
;
711 if (strcmp(slotnum
, "0") == 0) {
712 message
= g_strdup_printf (
713 "Found a zero slot in slotdef=%s\n",
715 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
717 s_current
->error_count
++;
720 slot
= atoi(slotnum
);
723 /* make sure that the slot # is less than the number of slots */
724 if (slot
> s_current
->numslots
) {
725 sprintf(tempstr1
, "%d", slot
);
726 message
= g_strdup_printf (
727 "Slot %s is larger then the maximum number (%s) of slots\n",
728 tempstr1
, numslots_str
);
729 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
732 s_current
->error_count
++;
733 s_current
->slotting_errors
++;
736 /* skip over the : */
737 pins
= strchr(slotdef
, ':');
739 message
= g_strdup_printf (
740 "Invalid slotdef=%s attributes, not continuing\n",
742 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
744 s_current
->error_count
++;
745 s_current
->slotting_errors
++;
746 error_parsing
= TRUE
;
749 pins
++; /* get past that : */
751 message
= g_strdup_printf (
752 "Invalid slotdef=%s attributes, not continuing\n",
754 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
756 s_current
->error_count
++;
757 s_current
->slotting_errors
++;
758 error_parsing
= TRUE
;
763 message
= g_strdup_printf (
764 "Invalid slotdef=%s attributes, not continuing\n",
766 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
768 s_current
->error_count
++;
769 s_current
->slotting_errors
++;
770 error_parsing
= TRUE
;
774 if ((slot
> 0) && (slot
<= s_current
->numslots
)) {
775 if (pinlist
[slot
-1]) {
776 message
= g_strdup_printf ("Duplicate slot number in slotdef=%s\n",
778 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
780 s_current
->error_count
++;
781 s_current
->slotting_errors
++;
783 pinlist
[slot
-1] = g_strdup_printf(",%s,", pins
);
794 temp
= u_basic_breakup_string(pins
, ',', j
);
796 if (!temp
&& j
< s_current
->numpins
) {
797 message
= g_strdup_printf (
798 "Not enough pins in slotdef=%s\n",
800 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
802 s_current
->error_count
++;
803 s_current
->slotting_errors
++;
807 if (j
> s_current
->numpins
) {
808 message
= g_strdup_printf (
809 "Too many pins in slotdef=%s\n",
811 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
813 s_current
->error_count
++;
814 s_current
->slotting_errors
++;
820 if (temp
&& strcmp(temp
, "0") == 0) {
821 message
= g_strdup_printf (
822 "Found a zero pin in slotdef=%s\n",
824 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
826 s_current
->error_count
++;
839 slotdef
= o_attrib_search_name(object_head
, "slotdef", i
);
842 if (!slotdef
&& i
< s_current
->numslots
) {
843 message
= g_strdup_printf (
844 "Missing slotdef= (there should be %s slotdef= attributes)\n",
846 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
848 s_current
->error_count
++;
849 s_current
->slotting_errors
++;
852 /* Validate that pinslist does not contain a null entry. If any entry */
853 /* is null, that means the slotdef= attribute was malformed to start */
855 for (i
= 0; i
< s_current
->numslots
; i
++) {
856 if (pinlist
[i
] == NULL
) {
862 message
= g_strdup_printf(
863 "Malformed slotdef= (the format is #:#,#,#,...)\n");
864 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
866 s_current
->error_count
++;
867 s_current
->slotting_errors
++;
869 /* Now compare each pin with the rest */
870 s_current
->numslotpins
= 0;
871 for (i
= 0; i
< s_current
->numslots
; i
++) {
872 for (n
= 1; n
<= s_current
->numpins
; n
++) {
873 /* Get the number of one pin */
874 pin
= u_basic_breakup_string(pinlist
[i
], ',', n
);
877 for (j
= i
- 1; j
>= 0 && !match
; j
--) {
878 for (m
= 1; m
<= s_current
->numpins
&& !match
; m
++) {
879 /* Get the number of the other pin */
880 cmp
= u_basic_breakup_string(pinlist
[j
], ',', m
);
882 match
= (0 == strcmp (pin
, cmp
));
888 /* If they don't match, then increase the number of pins */
889 s_current
->numslotpins
++;
895 message
= g_strdup_printf ("Found %d distinct pins in slots\n",
896 s_current
->numslotpins
);
897 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
906 /* Free the pinlist */
907 for (i
= 0; i
< s_current
->numslots
; i
++) {
920 s_check_oldpin(OBJECT
*object_head
, SYMCHECK
*s_current
)
924 int found_old
= FALSE
;
925 int number_counter
= 0;
928 o_current
= object_head
;
929 while(o_current
!= NULL
)
932 if (o_current
->type
== OBJ_TEXT
)
934 if (strstr(o_current
->text
->string
, "pin"))
936 /* skip over "pin" */
937 ptr
= o_current
->text
->string
+ 3;
941 while (ptr
&& *ptr
> '0' && *ptr
< '9')
947 if (ptr
&& *ptr
== '=')
954 o_current
= o_current
->next
;
958 /* found no numbers inbetween pin and = */
959 if (number_counter
== 0)
961 o_current
= o_current
->next
;
965 /* skip over = char */
968 while (ptr
&& *ptr
> '0' && *ptr
< '9')
978 /* 2 matches -> number found after pin and only numbers after = sign */
981 message
= g_strdup_printf (
982 "Found old pin#=# attribute: %s\n",
983 o_current
->text
->string
);
984 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
987 s_current
->found_oldpin_attrib
+= found_old
;
988 s_current
->error_count
++;
994 o_current
= o_current
->next
;
1001 s_check_oldslot(OBJECT
*object_head
, SYMCHECK
*s_current
)
1005 int found_old
= FALSE
;
1006 int number_counter
= 0;
1009 o_current
= object_head
;
1010 while(o_current
!= NULL
)
1013 if (o_current
->type
== OBJ_TEXT
)
1015 if (strstr(o_current
->text
->string
, "slot"))
1017 /* skip over "slot" */
1018 ptr
= o_current
->text
->string
+ 4;
1022 while (ptr
&& *ptr
> '0' && *ptr
< '9')
1028 if (ptr
&& *ptr
== '=')
1035 o_current
= o_current
->next
;
1039 /* found no numbers inbetween pin and = */
1040 if (number_counter
== 0)
1042 o_current
= o_current
->next
;
1046 /* skip over = char */
1049 while ((ptr
&& (*ptr
> '0') && (*ptr
< '9')) || (*ptr
== ','))
1059 /* 2 matches -> number found after slot and only numbers after = */
1062 message
= g_strdup_printf (
1063 "Found old slot#=# attribute: %s\n",
1064 o_current
->text
->string
);
1065 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
1067 s_current
->found_oldslot_attrib
+= found_old
;
1068 s_current
->error_count
++;
1074 o_current
= o_current
->next
;
1080 s_check_nets_buses(OBJECT
*object_head
, SYMCHECK
*s_current
)
1085 o_current
= object_head
;
1086 while(o_current
!= NULL
)
1088 if (o_current
->type
== OBJ_NET
)
1091 g_strdup ("Found a net inside a symbol\n");
1092 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
1094 s_current
->found_net
++;
1095 s_current
->error_count
++;
1098 if (o_current
->type
== OBJ_BUS
)
1101 g_strdup ("Found a bus inside a symbol\n");
1102 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
1104 s_current
->found_bus
++;
1105 s_current
->error_count
++;
1109 o_current
= o_current
->next
;
1114 s_check_connections(OBJECT
*object_head
, SYMCHECK
*s_current
)
1119 o_current
= object_head
;
1120 while(o_current
!= NULL
)
1123 if (o_current
->conn_list
) {
1125 g_strdup ("Found a connection inside a symbol\n");
1126 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
1128 s_current
->found_connection
++;
1129 s_current
->error_count
++;
1132 o_current
= o_current
->next
;
1137 s_check_obsolete_forbidden_attributes(OBJECT
*object_head
, SYMCHECK
*s_current
)
1143 o_current
= object_head
;
1144 while(o_current
!= NULL
)
1146 if (o_current
->type
== OBJ_TEXT
)
1149 attrib
= strstr(o_current
->text
->string
, "label=");
1150 /* make sure we only check for label= and not pinlabel= */
1151 if (attrib
&& attrib
== o_current
->text
->string
) {
1152 message
= g_strdup_printf (
1153 "Found obsolete label= attribute: %s\n",
1154 o_current
->text
->string
);
1155 s_current
->warning_messages
=
1156 g_list_append(s_current
->warning_messages
, message
);
1157 s_current
->found_label
++;
1158 s_current
->warning_count
++;
1161 if (strstr(o_current
->text
->string
, "uref=")) {
1162 message
= g_strdup_printf (
1163 "Found obsolete uref= attribute: %s\n",
1164 o_current
->text
->string
);
1165 s_current
->warning_messages
=
1166 g_list_append(s_current
->warning_messages
, message
);
1167 s_current
->found_uref
++;
1168 s_current
->warning_count
++;
1171 attrib
= strstr(o_current
->text
->string
, "type=");
1172 /* make sure we only check for type= and not pintype= */
1173 if (attrib
&& attrib
== o_current
->text
->string
) {
1174 message
= g_strdup_printf (
1175 "Found forbidden type= attribute: %s\n",
1176 o_current
->text
->string
);
1177 s_current
->error_messages
=
1178 g_list_append(s_current
->error_messages
, message
);
1179 s_current
->found_type
++;
1180 s_current
->error_count
++;
1183 attrib
= strstr(o_current
->text
->string
, "name=");
1184 if (attrib
&& attrib
== o_current
->text
->string
) {
1185 message
= g_strdup_printf (
1186 "Found forbidden name= attribute: %s\n",
1187 o_current
->text
->string
);
1188 s_current
->error_messages
=
1189 g_list_append(s_current
->error_messages
, message
);
1190 s_current
->found_name
++;
1191 s_current
->error_count
++;
1195 o_current
= o_current
->next
;
1202 s_check_missing_attribute(OBJECT
*object
, char *attribute
, SYMCHECK
*s_current
)
1205 int found_first
=FALSE
;
1213 string
= o_attrib_search_name_single_count(object
, attribute
,
1217 message
= g_strdup_printf (
1218 "Missing %s= attribute\n",
1220 s_current
->warning_messages
= g_list_append(s_current
->warning_messages
,
1222 s_current
->warning_count
++;
1229 message
= g_strdup_printf (
1230 "Found multiple %s=%s attributes on one pin\n",
1232 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
1234 s_current
->error_count
++;
1237 /* this is the first attribute found */
1240 message
= g_strdup_printf (
1241 "Found %s=%s attribute\n",
1243 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
1251 string
= o_attrib_search_name_single_count(object
, attribute
,
1258 s_check_missing_attributes(OBJECT
*object_head
, SYMCHECK
*s_current
)
1263 o_current
= object_head
;
1264 while(o_current
!= NULL
)
1266 if (o_current
->type
== OBJ_PIN
)
1268 s_check_missing_attribute(o_current
, "pinlabel", s_current
);
1269 s_check_missing_attribute(o_current
, "pintype", s_current
);
1272 if (o_current
->type
== OBJ_TEXT
)
1274 if (strstr(o_current
->text
->string
, "footprint=")) {
1275 message
= g_strdup_printf (
1276 "Found %s attribute\n",
1277 o_current
->text
->string
);
1278 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
1280 s_current
->found_footprint
++;
1283 if (strstr(o_current
->text
->string
, "refdes=")) {
1284 message
= g_strdup_printf (
1285 "Found %s attribute\n",
1286 o_current
->text
->string
);
1287 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
1289 s_current
->found_refdes
++;
1294 o_current
= o_current
->next
;
1297 if (s_current
->found_footprint
== 0) {
1298 message
= g_strdup ("Missing footprint= attribute\n");
1299 s_current
->warning_messages
= g_list_append(s_current
->warning_messages
,
1301 s_current
->warning_count
++;
1304 if (s_current
->found_footprint
> 1) {
1305 message
= g_strdup ("Multiple footprint= attributes found\n");
1306 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
1308 s_current
->error_count
++;
1312 if (s_current
->found_refdes
== 0) {
1313 message
= g_strdup ("Missing refdes= attribute\n");
1314 s_current
->warning_messages
= g_list_append(s_current
->warning_messages
,
1316 s_current
->warning_count
++;
1320 if (s_current
->found_refdes
> 1) {
1321 message
= g_strdup ("Multiple refdes= attributes found\n");
1322 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
1324 s_current
->error_count
++;
1329 void s_check_pintype(OBJECT
*object_head
, SYMCHECK
*s_current
)
1333 int missing_pintype_attrib_sum
= 0;
1334 int multiple_pintype_attrib_sum
= 0;
1335 int invalid_pintype_attrib_sum
= 0;
1336 int found_first
=FALSE
;
1342 o_current
= object_head
;
1343 while(o_current
!= NULL
)
1346 if (o_current
->type
== OBJ_PIN
)
1348 missing_pintype_attrib_sum
= 0;
1349 multiple_pintype_attrib_sum
= 0;
1350 invalid_pintype_attrib_sum
= 0;
1351 found_first
= FALSE
;
1354 string
= o_attrib_search_name_single_count(o_current
, "pintype",
1358 /* Missing pintype is already checked. */
1359 /* message = g_strdup ("Missing pintype= attribute\n"); */
1360 /* s_current->error_messages = g_list_append(s_current->error_messages, */
1362 /* missing_pintype_attrib_sum++; */
1363 /* s_current->error_count++; */
1369 message
= g_strdup_printf("Found pintype=%s attribute\n", string
);
1370 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
1373 pintype
= g_strdup (string
);
1375 if ( (strcmp(pintype
, "in") != 0) &&
1376 (strcmp(pintype
, "out") != 0) &&
1377 (strcmp(pintype
, "io") != 0) &&
1378 (strcmp(pintype
, "oc") != 0) &&
1379 (strcmp(pintype
, "oe") != 0) &&
1380 (strcmp(pintype
, "pas") != 0) &&
1381 (strcmp(pintype
, "tp") != 0) &&
1382 (strcmp(pintype
, "tri") != 0) &&
1383 (strcmp(pintype
, "clk") != 0) &&
1384 (strcmp(pintype
, "pwr") != 0) ) {
1386 message
= g_strdup_printf ("Invalid pintype=%s attribute\n", pintype
);
1387 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
1389 invalid_pintype_attrib_sum
++;
1390 s_current
->error_count
++;
1394 /* if (found_first) { */
1395 /* Multiple pintype attributes already checked. */
1396 /* message = g_strdup_printf ("Found multiple pintype=%s attributes on one pin\n", string); */
1397 /* s_current->error_messages = g_list_append(s_current->error_messages, */
1399 /* multiple_pintype_attrib_sum++; */
1400 /* s_current->error_count++; */
1409 string
= o_attrib_search_name_single_count(o_current
, "pintype",
1413 s_current
->missing_pintype_attrib
+= missing_pintype_attrib_sum
;
1414 s_current
->multiple_pintype_attrib
+= multiple_pintype_attrib_sum
;
1418 o_current
= o_current
->next
;