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 /* overal symbol structure test */
79 s_check_symbol_structure(object_head
, s_symcheck
);
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 pintype attribute (and multiples) on all pins */
91 s_check_pintype(object_head
, s_symcheck
);
93 /* check for pinseq attribute (and multiples) on all pins */
94 s_check_pinseq(object_head
, s_symcheck
);
96 /* check for pinnumber attribute (and multiples) on all pins */
97 s_check_pinnumber(object_head
, s_symcheck
);
99 /* check for whether all pins are on grid */
100 s_check_pin_ongrid(object_head
, s_symcheck
);
102 /* check for slotdef attribute on all pins (if numslots exists) */
103 s_check_slotdef(object_head
, s_symcheck
);
105 /* check for old pin#=# attributes */
106 s_check_oldpin(object_head
, s_symcheck
);
108 /* check for old pin#=# attributes */
109 s_check_oldslot(object_head
, s_symcheck
);
111 /* check for nets or buses within the symbol (completely disallowed) */
112 s_check_nets_buses(object_head
, s_symcheck
);
114 /* check for connections with in a symbol (completely disallowed) */
115 s_check_connections(object_head
, s_symcheck
);
117 /* now report the info/warnings/errors to the user */
120 /* done, now print out the messages */
121 s_symstruct_print(s_symcheck
);
123 if (s_symcheck
->warning_count
> 0) {
124 s_log_message("%d warnings found ",
125 s_symcheck
->warning_count
);
126 if (verbose_mode
< 2) {
127 s_log_message("(use -vv to view details)\n");
133 if (s_symcheck
->error_count
== 0) {
134 s_log_message("No errors found\n");
135 } else if (s_symcheck
->error_count
== 1) {
136 s_log_message("1 ERROR found ");
137 if (verbose_mode
< 1) {
138 s_log_message("(use -v to view details)\n");
143 } else if (s_symcheck
->error_count
> 1) {
144 s_log_message("%d ERRORS found ",
145 s_symcheck
->error_count
);
146 if (verbose_mode
< 1) {
147 s_log_message("(use -v to view details)\n");
154 errors
= s_symcheck
->error_count
;
155 warnings
= s_symcheck
->warning_count
;
156 s_symstruct_free(s_symcheck
);
159 } else if (warnings
) {
168 s_check_list_has_item(char **list
, char *item
)
171 for (cur
= 0; list
[cur
] != NULL
; cur
++) {
172 if (strcmp(item
, list
[cur
]) == 0)
179 s_check_symbol_structure(OBJECT
*object_head
, SYMCHECK
*s_current
)
186 char *valid_pin_attributes
[] = {"pinlabel", "pintype",
187 "pinseq", "pinnumber",
189 char *valid_attributes
[] = {"device", "graphical", "description",
190 "author", "comment", "numslots",
191 "slotdef", "footprint", "documentation",
192 "refdes", "slot", "net", "value",
193 "symversion", "dist-license",
195 char *obsolete_attributes
[] = {"uref", "label", "email",
197 char *forbidden_attributes
[] = {"type", "name",
199 /* pin# ?, slot# ? */
201 for (o_current
= object_head
;
203 o_current
= o_current
->next
) {
205 if (o_current
->type
== OBJ_TEXT
) {
206 tokens
= g_strsplit(o_current
->text
->string
,"=", 2);
207 if (tokens
[0] != NULL
&& tokens
[1] != NULL
) {
208 if (s_check_list_has_item(forbidden_attributes
, tokens
[0])) {
209 message
= g_strdup_printf ("Found forbidden %s= attribute: [%s=%s]\n",
210 tokens
[0], tokens
[0], tokens
[1]);
211 s_current
->error_messages
=
212 g_list_append(s_current
->error_messages
, message
);
213 s_current
->error_count
++;
215 else if (s_check_list_has_item(obsolete_attributes
, tokens
[0])) {
216 message
= g_strdup_printf ("Found obsolete %s= attribute: [%s=%s]\n",
217 tokens
[0], tokens
[0], tokens
[1]);
218 s_current
->warning_messages
=
219 g_list_append(s_current
->warning_messages
, message
);
220 s_current
->warning_count
++;
222 else if (s_check_list_has_item(valid_pin_attributes
, tokens
[0])) {
223 if (o_current
->attached_to
== NULL
224 || o_current
->attached_to
->type
!= OBJ_PIN
) {
225 message
= g_strdup_printf ("Found misplaced pin attribute:"
226 " [%s=%s]\n", tokens
[0], tokens
[1]);
227 s_current
->error_messages
=
228 g_list_append(s_current
->error_messages
, message
);
229 s_current
->error_count
++;
232 else if (!s_check_list_has_item(valid_attributes
, tokens
[0])) {
234 message
= g_strdup_printf ("Found unknown %s= attribute: [%s=%s]\n",
235 token
[0], tokens
[0], tokens
[1]);
236 s_current
->warning_messages
=
237 g_list_append(s_current
->warning_messages
, message
);
238 s_current
->warning_count
++;
241 else if (o_current
->attached_to
!= NULL
) {
242 message
= g_strdup_printf ("Found wrongly attached attribute: "
244 tokens
[0], tokens
[1]);
245 s_current
->error_messages
=
246 g_list_append(s_current
->error_messages
, message
);
247 s_current
->error_count
++;
256 s_check_graphical(OBJECT
*o_current
, SYMCHECK
*s_current
)
260 /* look for special graphical tag */
261 temp
= o_attrib_search_name(o_current
, "graphical", 0);
264 s_current
->graphical_symbol
=TRUE
;
270 s_check_device(OBJECT
*o_current
, SYMCHECK
*s_current
)
275 /* search for device attribute */
276 temp
= o_attrib_search_name(o_current
, "device", 0);
278 /* did not find device= attribute */
279 message
= g_strdup ("Missing device= attribute\n");
280 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
282 s_current
->missing_device_attrib
=TRUE
;
283 s_current
->error_count
++;
285 /* found device= attribute */
286 s_current
->missing_device_attrib
=FALSE
;
287 s_current
->device_attribute
=
288 (char *) g_malloc(sizeof(char)*(strlen(temp
)+1));
289 strcpy(s_current
->device_attribute
, temp
);
290 message
= g_strdup_printf ("Found device=%s\n", temp
);
291 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
295 /* check for device = none for graphical symbols */
296 if (temp
&& s_current
->graphical_symbol
&& (strcmp(temp
, "none") == 0)) {
297 s_current
->device_attribute_incorrect
=FALSE
;
298 message
= g_strdup ("Found graphical symbol, device=none\n");
299 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
301 } else if (s_current
->graphical_symbol
) {
302 s_current
->device_attribute_incorrect
=TRUE
;
303 message
= g_strdup ("Found graphical symbol, device= should be set to none\n");
304 s_current
->warning_messages
= g_list_append(s_current
->warning_messages
,
306 s_current
->warning_count
++;
315 s_check_pinseq(OBJECT
*object_head
, SYMCHECK
*s_current
)
319 int found_first
=FALSE
;
320 int missing_pinseq_attrib_sum
=0;
321 int multiple_pinseq_attrib_sum
=0;
324 GList
*found_numbers
= NULL
;
330 o_current
= object_head
;
331 while(o_current
!= NULL
)
334 if (o_current
->type
== OBJ_PIN
)
336 missing_pinseq_attrib_sum
= 0;
337 multiple_pinseq_attrib_sum
= 0;
341 string
= o_attrib_search_name_single_count(o_current
, "pinseq",
345 message
= g_strdup ("Missing pinseq= attribute\n");
346 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
348 missing_pinseq_attrib_sum
++;
349 s_current
->error_count
++;
355 message
= g_strdup_printf ("Found pinseq=%s attribute\n", string
);
356 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
359 number
= g_strdup (string
);
361 if (strcmp(number
, "0") == 0) {
362 message
= g_strdup ("Found pinseq=0 attribute\n");
363 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
365 s_current
->error_count
++;
369 message
= g_strdup_printf (
370 "Found multiple pinseq=%s attributes on one pin\n",
372 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
374 multiple_pinseq_attrib_sum
++;
375 s_current
->error_count
++;
380 /* this is the first attribute found */
382 found_numbers
= g_list_append(found_numbers
, number
);
390 string
= o_attrib_search_name_single_count(o_current
, "pinseq",
394 s_current
->missing_pinseq_attrib
+= missing_pinseq_attrib_sum
;
395 s_current
->multiple_pinseq_attrib
+= multiple_pinseq_attrib_sum
;
399 o_current
= o_current
->next
;
402 ptr1
= found_numbers
;
405 char *string
= (char *) ptr1
->data
;
408 ptr2
= found_numbers
;
409 while(ptr2
&& string
)
411 char *current
= (char *) ptr2
->data
;
413 if (current
&& strcmp(string
, current
) == 0) {
417 ptr2
= g_list_next(ptr2
);
422 message
= g_strdup_printf (
423 "Found duplicate pinseq=%s attribute in the symbol\n",
425 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
427 s_current
->error_count
++;
428 s_current
->duplicate_pinseq_attrib
++;
431 ptr1
= g_list_next(ptr1
);
434 ptr1
= found_numbers
;
438 ptr1
= g_list_next(ptr1
);
440 g_list_free(found_numbers
);
446 s_check_pinnumber(OBJECT
*object_head
, SYMCHECK
*s_current
)
450 int found_first
=FALSE
;
451 int missing_pinnumber_attrib_sum
=0;
452 int multiple_pinnumber_attrib_sum
=0;
456 GList
*found_numbers
= NULL
;
463 char *netpins
= NULL
;
468 while( (net
= o_attrib_search_toplevel(object_head
, "net", counter
)) != NULL
)
470 message
= g_strdup_printf ("Found net=%s attribute\n", net
);
471 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
474 netpins
= u_basic_breakup_string(net
, ':', 1);
477 message
= g_strdup ("Bad net= attribute\n");
478 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
480 s_current
->error_count
++;
494 number
= u_basic_breakup_string(netpins
, ',', j
);
499 message
= g_strdup_printf ("Found pin number %s in net attribute\n",
501 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
505 if (strcmp(number
, "0") == 0) {
506 message
= g_strdup ("Found pinnumber 0 in net= attribute\n");
507 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
509 s_current
->error_count
++;
512 temp
= g_strdup(number
);
513 found_numbers
= g_list_append(found_numbers
, temp
);
515 s_current
->numnetpins
++;
531 o_current
= object_head
;
532 while(o_current
!= NULL
)
535 if (o_current
->type
== OBJ_PIN
)
537 s_current
->numpins
++;
539 missing_pinnumber_attrib_sum
= 0;
540 multiple_pinnumber_attrib_sum
= 0;
544 string
= o_attrib_search_name_single_count(o_current
, "pinnumber",
548 message
= g_strdup ("Missing pinnumber= attribute\n");
549 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
551 missing_pinnumber_attrib_sum
++;
552 s_current
->error_count
++;
557 message
= g_strdup_printf ("Found pinnumber=%s attribute\n", string
);
558 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
562 message
= g_strdup_printf (
563 "Found multiple pinnumber=%s attributes on one pin\n",
565 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
567 multiple_pinnumber_attrib_sum
++;
568 s_current
->error_count
++;
571 number
= g_strdup (string
);
574 if (strcmp(number
, "0") == 0) {
575 message
= g_strdup ("Found pinnumber=0 attribute\n");
576 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
578 s_current
->error_count
++;
581 /* this is the first attribute found */
583 found_numbers
= g_list_append(found_numbers
, number
);
591 string
= o_attrib_search_name_single_count(o_current
, "pinnumber",
595 s_current
->missing_pinnumber_attrib
+= missing_pinnumber_attrib_sum
;
596 s_current
->multiple_pinnumber_attrib
+= multiple_pinnumber_attrib_sum
;
599 o_current
= o_current
->next
;
605 ptr1
= found_numbers
;
608 char *string
= (char *) ptr1
->data
;
611 ptr2
= found_numbers
;
612 while(ptr2
&& string
)
614 char *current
= (char *) ptr2
->data
;
616 if (current
&& strcmp(string
, current
) == 0) {
620 ptr2
= g_list_next(ptr2
);
625 message
= g_strdup_printf (
626 "Found duplicate pinnumber=%s attribute in the symbol\n",
628 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
630 s_current
->error_count
++;
631 s_current
->duplicate_pinnumber_attrib
++;
634 ptr1
= g_list_next(ptr1
);
637 ptr1
= found_numbers
;
641 ptr1
= g_list_next(ptr1
);
643 g_list_free(found_numbers
);
646 sprintf(tempstr
, "%d", s_current
->numpins
+ s_current
->numnetpins
);
647 message
= g_strdup_printf ("Found %s pins inside symbol\n", tempstr
);
648 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
653 s_check_pin_ongrid(OBJECT
*object_head
, SYMCHECK
*s_current
)
660 for (o_current
= object_head
;
662 o_current
= o_current
->next
) {
663 if (o_current
->type
== OBJ_PIN
) {
664 x1
= o_current
->line
->x
[0];
665 y1
= o_current
->line
->y
[0];
666 x2
= o_current
->line
->x
[1];
667 y2
= o_current
->line
->y
[1];
669 if (x1
% 100 != 0 || y1
% 100 != 0) {
670 message
= g_strdup_printf("Found offgrid pin at location"
671 " (x1=%d,y1=%d)\n", x1
, y1
);
672 /* error if it is the whichend, warning if not */
673 if (o_current
->whichend
== 0) {
674 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
676 s_current
->error_count
++;
679 s_current
->warning_messages
= g_list_append(s_current
->warning_messages
,
681 s_current
->warning_count
++;
684 if (x2
% 100 != 0 || y2
% 100 != 0) {
685 message
= g_strdup_printf("Found offgrid pin at location"
686 " (x2=%d,y2=%d)\n", x2
, y2
);
687 /* error when whichend, warning if not */
688 if (o_current
-> whichend
!= 0) {
689 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
691 s_current
->error_count
++;
694 s_current
->warning_messages
= g_list_append(s_current
->warning_messages
,
696 s_current
->warning_count
++;
705 s_check_slotdef(OBJECT
*object_head
, SYMCHECK
*s_current
)
708 char* slotdef
= NULL
;
709 char* slotnum
= NULL
;
712 char numslots_str
[10];
717 /* pinlist will store the pin definitions for each slot */
718 /* example: pinlist[0] = 3,2,8,4,1 ; pinlist[1] = 5,6,8,4,7 */
719 char** pinlist
= NULL
;
724 gboolean error_parsing
= FALSE
;
725 int errors_found
= 0;
727 /* look for numslots to see if this symbol has slotting info */
728 value
= o_attrib_search_name(object_head
, "numslots", 0);
731 message
= g_strdup ("Did not find numslots= attribute, not checking slotting\n");
732 s_current
->warning_messages
= g_list_append(s_current
->warning_messages
,
734 s_current
->warning_count
++;
735 message
= g_strdup ("If this symbol does not need slotting, set numslots to zero (numslots=0)\n");
736 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
741 s_current
->numslots
=atoi(value
);
742 sprintf(numslots_str
, "%d", s_current
->numslots
);
745 message
= g_strdup_printf ("Found numslots=%s attribute\n", numslots_str
);
746 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
749 if (s_current
->numslots
== 0) {
750 message
= g_strdup ("numslots set to zero, symbol does not have slots\n");
751 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
757 pinlist
= (char**)g_malloc0(sizeof(*pinlist
) * s_current
->numslots
);
760 /* get the slotdef attribute */
761 slotdef
= o_attrib_search_name(object_head
, "slotdef", 0);
762 while ((slotdef
!= NULL
) && (!error_parsing
))
765 if (i
> s_current
->numslots
-1) {
767 sprintf(tempstr1
, "%d", i
+1); /* i starts at zero */
768 message
= g_strdup_printf (
769 "Found %s slotdef= attributes. Expecting %s slotdef= attributes\n",
770 tempstr1
, numslots_str
);
771 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
774 s_current
->error_count
++;
775 s_current
->slotting_errors
++;
778 message
= g_strdup_printf ("Found slotdef=%s attribute\n", slotdef
);
779 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
782 slotnum
= u_basic_breakup_string(slotdef
, ':', 0);
785 message
= g_strdup_printf (
786 "Invalid slotdef=%s attributes, not continuing\n",
788 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
790 s_current
->error_count
++;
791 s_current
->slotting_errors
++;
792 error_parsing
= TRUE
;
796 if (strcmp(slotnum
, "0") == 0) {
797 message
= g_strdup_printf (
798 "Found a zero slot in slotdef=%s\n",
800 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
802 s_current
->error_count
++;
805 slot
= atoi(slotnum
);
808 /* make sure that the slot # is less than the number of slots */
809 if (slot
> s_current
->numslots
) {
810 sprintf(tempstr1
, "%d", slot
);
811 message
= g_strdup_printf (
812 "Slot %s is larger then the maximum number (%s) of slots\n",
813 tempstr1
, numslots_str
);
814 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
817 s_current
->error_count
++;
818 s_current
->slotting_errors
++;
821 /* skip over the : */
822 pins
= strchr(slotdef
, ':');
824 message
= g_strdup_printf (
825 "Invalid slotdef=%s attributes, not continuing\n",
827 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
829 s_current
->error_count
++;
830 s_current
->slotting_errors
++;
831 error_parsing
= TRUE
;
834 pins
++; /* get past that : */
836 message
= g_strdup_printf (
837 "Invalid slotdef=%s attributes, not continuing\n",
839 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
841 s_current
->error_count
++;
842 s_current
->slotting_errors
++;
843 error_parsing
= TRUE
;
848 message
= g_strdup_printf (
849 "Invalid slotdef=%s attributes, not continuing\n",
851 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
853 s_current
->error_count
++;
854 s_current
->slotting_errors
++;
855 error_parsing
= TRUE
;
859 if ((slot
> 0) && (slot
<= s_current
->numslots
)) {
860 if (pinlist
[slot
-1]) {
861 message
= g_strdup_printf ("Duplicate slot number in slotdef=%s\n",
863 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
865 s_current
->error_count
++;
866 s_current
->slotting_errors
++;
868 pinlist
[slot
-1] = g_strdup_printf(",%s,", pins
);
879 temp
= u_basic_breakup_string(pins
, ',', j
);
881 if (!temp
&& j
< s_current
->numpins
) {
882 message
= g_strdup_printf (
883 "Not enough pins in slotdef=%s\n",
885 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
887 s_current
->error_count
++;
888 s_current
->slotting_errors
++;
892 if (j
> s_current
->numpins
) {
893 message
= g_strdup_printf (
894 "Too many pins in slotdef=%s\n",
896 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
898 s_current
->error_count
++;
899 s_current
->slotting_errors
++;
905 if (temp
&& strcmp(temp
, "0") == 0) {
906 message
= g_strdup_printf (
907 "Found a zero pin in slotdef=%s\n",
909 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
911 s_current
->error_count
++;
924 slotdef
= o_attrib_search_name(object_head
, "slotdef", i
);
927 if (!slotdef
&& i
< s_current
->numslots
) {
928 message
= g_strdup_printf (
929 "Missing slotdef= (there should be %s slotdef= attributes)\n",
931 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
933 s_current
->error_count
++;
934 s_current
->slotting_errors
++;
937 /* Validate that pinslist does not contain a null entry. If any entry */
938 /* is null, that means the slotdef= attribute was malformed to start */
940 for (i
= 0; i
< s_current
->numslots
; i
++) {
941 if (pinlist
[i
] == NULL
) {
947 message
= g_strdup_printf(
948 "Malformed slotdef= (the format is #:#,#,#,...)\n");
949 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
951 s_current
->error_count
++;
952 s_current
->slotting_errors
++;
954 /* Now compare each pin with the rest */
955 s_current
->numslotpins
= 0;
956 for (i
= 0; i
< s_current
->numslots
; i
++) {
957 for (n
= 1; n
<= s_current
->numpins
; n
++) {
958 /* Get the number of one pin */
959 pin
= u_basic_breakup_string(pinlist
[i
], ',', n
);
962 for (j
= i
- 1; j
>= 0 && !match
; j
--) {
963 for (m
= 1; m
<= s_current
->numpins
&& !match
; m
++) {
964 /* Get the number of the other pin */
965 cmp
= u_basic_breakup_string(pinlist
[j
], ',', m
);
967 match
= (0 == strcmp (pin
, cmp
));
973 /* If they don't match, then increase the number of pins */
974 s_current
->numslotpins
++;
980 message
= g_strdup_printf ("Found %d distinct pins in slots\n",
981 s_current
->numslotpins
);
982 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
991 /* Free the pinlist */
992 for (i
= 0; i
< s_current
->numslots
; i
++) {
1005 s_check_oldpin(OBJECT
*object_head
, SYMCHECK
*s_current
)
1009 int found_old
= FALSE
;
1010 int number_counter
= 0;
1013 o_current
= object_head
;
1014 while(o_current
!= NULL
)
1017 if (o_current
->type
== OBJ_TEXT
)
1019 if (strstr(o_current
->text
->string
, "pin"))
1021 /* skip over "pin" */
1022 ptr
= o_current
->text
->string
+ 3;
1026 while (ptr
&& *ptr
> '0' && *ptr
< '9')
1032 if (ptr
&& *ptr
== '=')
1039 o_current
= o_current
->next
;
1043 /* found no numbers inbetween pin and = */
1044 if (number_counter
== 0)
1046 o_current
= o_current
->next
;
1050 /* skip over = char */
1053 while (ptr
&& *ptr
> '0' && *ptr
< '9')
1063 /* 2 matches -> number found after pin and only numbers after = sign */
1066 message
= g_strdup_printf (
1067 "Found old pin#=# attribute: %s\n",
1068 o_current
->text
->string
);
1069 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
1072 s_current
->found_oldpin_attrib
+= found_old
;
1073 s_current
->error_count
++;
1079 o_current
= o_current
->next
;
1086 s_check_oldslot(OBJECT
*object_head
, SYMCHECK
*s_current
)
1090 int found_old
= FALSE
;
1091 int number_counter
= 0;
1094 o_current
= object_head
;
1095 while(o_current
!= NULL
)
1098 if (o_current
->type
== OBJ_TEXT
)
1100 if (strstr(o_current
->text
->string
, "slot"))
1102 /* skip over "slot" */
1103 ptr
= o_current
->text
->string
+ 4;
1107 while (ptr
&& *ptr
> '0' && *ptr
< '9')
1113 if (ptr
&& *ptr
== '=')
1120 o_current
= o_current
->next
;
1124 /* found no numbers inbetween pin and = */
1125 if (number_counter
== 0)
1127 o_current
= o_current
->next
;
1131 /* skip over = char */
1134 while ((ptr
&& (*ptr
> '0') && (*ptr
< '9')) || (*ptr
== ','))
1144 /* 2 matches -> number found after slot and only numbers after = */
1147 message
= g_strdup_printf (
1148 "Found old slot#=# attribute: %s\n",
1149 o_current
->text
->string
);
1150 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
1152 s_current
->found_oldslot_attrib
+= found_old
;
1153 s_current
->error_count
++;
1159 o_current
= o_current
->next
;
1165 s_check_nets_buses(OBJECT
*object_head
, SYMCHECK
*s_current
)
1170 o_current
= object_head
;
1171 while(o_current
!= NULL
)
1173 if (o_current
->type
== OBJ_NET
)
1176 g_strdup ("Found a net inside a symbol\n");
1177 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
1179 s_current
->found_net
++;
1180 s_current
->error_count
++;
1183 if (o_current
->type
== OBJ_BUS
)
1186 g_strdup ("Found a bus inside a symbol\n");
1187 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
1189 s_current
->found_bus
++;
1190 s_current
->error_count
++;
1194 o_current
= o_current
->next
;
1199 s_check_connections(OBJECT
*object_head
, SYMCHECK
*s_current
)
1204 o_current
= object_head
;
1205 while(o_current
!= NULL
)
1208 if (o_current
->conn_list
) {
1210 g_strdup ("Found a connection inside a symbol\n");
1211 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
1213 s_current
->found_connection
++;
1214 s_current
->error_count
++;
1217 o_current
= o_current
->next
;
1222 s_check_missing_attribute(OBJECT
*object
, char *attribute
, SYMCHECK
*s_current
)
1225 int found_first
=FALSE
;
1233 string
= o_attrib_search_name_single_count(object
, attribute
,
1237 message
= g_strdup_printf (
1238 "Missing %s= attribute\n",
1240 s_current
->warning_messages
= g_list_append(s_current
->warning_messages
,
1242 s_current
->warning_count
++;
1249 message
= g_strdup_printf (
1250 "Found multiple %s=%s attributes on one pin\n",
1252 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
1254 s_current
->error_count
++;
1257 /* this is the first attribute found */
1260 message
= g_strdup_printf (
1261 "Found %s=%s attribute\n",
1263 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
1271 string
= o_attrib_search_name_single_count(object
, attribute
,
1278 s_check_missing_attributes(OBJECT
*object_head
, SYMCHECK
*s_current
)
1283 o_current
= object_head
;
1284 while(o_current
!= NULL
)
1286 if (o_current
->type
== OBJ_PIN
)
1288 s_check_missing_attribute(o_current
, "pinlabel", s_current
);
1289 s_check_missing_attribute(o_current
, "pintype", s_current
);
1292 if (o_current
->type
== OBJ_TEXT
)
1294 if (strstr(o_current
->text
->string
, "footprint=")) {
1295 message
= g_strdup_printf (
1296 "Found %s attribute\n",
1297 o_current
->text
->string
);
1298 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
1300 s_current
->found_footprint
++;
1303 if (strstr(o_current
->text
->string
, "refdes=")) {
1304 message
= g_strdup_printf (
1305 "Found %s attribute\n",
1306 o_current
->text
->string
);
1307 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
1309 s_current
->found_refdes
++;
1314 o_current
= o_current
->next
;
1317 if (s_current
->found_footprint
== 0) {
1318 message
= g_strdup ("Missing footprint= attribute\n");
1319 s_current
->warning_messages
= g_list_append(s_current
->warning_messages
,
1321 s_current
->warning_count
++;
1324 if (s_current
->found_footprint
> 1) {
1325 message
= g_strdup ("Multiple footprint= attributes found\n");
1326 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
1328 s_current
->error_count
++;
1332 if (s_current
->found_refdes
== 0) {
1333 message
= g_strdup ("Missing refdes= attribute\n");
1334 s_current
->warning_messages
= g_list_append(s_current
->warning_messages
,
1336 s_current
->warning_count
++;
1340 if (s_current
->found_refdes
> 1) {
1341 message
= g_strdup ("Multiple refdes= attributes found\n");
1342 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
1344 s_current
->error_count
++;
1349 void s_check_pintype(OBJECT
*object_head
, SYMCHECK
*s_current
)
1355 char *pintypes
[] = {"in", "out", "io", "oc", "oe",
1356 "pas", "tp", "tri", "clk", "pwr",
1359 for (o_current
= object_head
;
1361 o_current
= o_current
->next
) {
1363 if (o_current
->type
== OBJ_PIN
) {
1366 (pintype
= o_attrib_search_name_single_count(o_current
, "pintype",
1370 message
= g_strdup_printf("Found pintype=%s attribute\n", pintype
);
1371 s_current
->info_messages
= g_list_append(s_current
->info_messages
,
1374 if ( ! s_check_list_has_item(pintypes
, pintype
)) {
1375 message
= g_strdup_printf ("Invalid pintype=%s attribute\n", pintype
);
1376 s_current
->error_messages
= g_list_append(s_current
->error_messages
,
1378 s_current
->error_count
++;