Updated copyright date for the new year.
[geda-gaf/whiteaudio.git] / gsymcheck / src / s_check.c
blobae5f0597e0f90f0e9adb55e5e74c29997e2e06cf
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.
21 #include <config.h>
23 #include <stdio.h>
24 #ifdef HAVE_STRING_H
25 #include <string.h>
26 #endif
27 #ifdef HAVE_STRINGS_H
28 #include <strings.h>
29 #endif
30 #ifdef HAVE_UNISTD_H
31 #include <unistd.h>
32 #endif
34 #include <libgeda/libgeda.h>
36 #include "../include/struct.h"
37 #include "../include/globals.h"
38 #include "../include/prototype.h"
40 int
41 s_check_all(TOPLEVEL *pr_current)
43 GList *iter;
44 PAGE *p_current;
45 int return_status=0;
48 for ( iter = geda_list_get_glist( pr_current->pages );
49 iter != NULL;
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);
66 int
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();
74 if (!quiet_mode) {
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 */
121 if (!quiet_mode) {
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");
131 } else {
132 s_log_message("\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");
142 } else {
143 s_log_message("\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");
151 } else {
152 s_log_message("\n");
157 errors = s_symcheck->error_count;
158 warnings = s_symcheck->warning_count;
159 s_symstruct_free(s_symcheck);
160 if (errors) {
161 return(2);
162 } else if (warnings) {
163 return(1);
164 } else {
165 return(0);
170 void
171 s_check_graphical(OBJECT *o_current, SYMCHECK *s_current)
173 char *temp;
175 /* look for special graphical tag */
176 temp = o_attrib_search_name(o_current, "graphical", 0);
178 if (temp) {
179 s_current->graphical_symbol=TRUE;
180 g_free(temp);
184 void
185 s_check_device(OBJECT *o_current, SYMCHECK *s_current)
187 char *temp;
188 char *message;
190 /* search for device attribute */
191 temp = o_attrib_search_name(o_current, "device", 0);
192 if (!temp) {
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,
196 message);
197 s_current->missing_device_attrib=TRUE;
198 s_current->error_count++;
199 } else {
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,
207 message);
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,
215 message);
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,
220 message);
221 s_current->warning_count++;
224 if (temp)
225 g_free(temp);
229 void
230 s_check_pinseq(OBJECT *object_head, SYMCHECK *s_current)
232 OBJECT *o_current;
233 char *string;
234 int found_first=FALSE;
235 int missing_pinseq_attrib_sum=0;
236 int multiple_pinseq_attrib_sum=0;
237 int counter=0;
239 GList *found_numbers = NULL;
240 GList *ptr1 = NULL;
241 GList *ptr2 = NULL;
242 char *number;
243 char *message;
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;
253 found_first = FALSE;
254 counter = 0;
256 string = o_attrib_search_name_single_count(o_current, "pinseq",
257 counter);
258 if (!string)
260 message = g_strdup ("Missing pinseq= attribute\n");
261 s_current->error_messages = g_list_append(s_current->error_messages,
262 message);
263 missing_pinseq_attrib_sum++;
264 s_current->error_count++;
267 while (string)
270 message = g_strdup_printf ("Found pinseq=%s attribute\n", string);
271 s_current->info_messages = g_list_append(s_current->info_messages,
272 message);
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,
279 message);
280 s_current->error_count++;
283 if (found_first) {
284 message = g_strdup_printf (
285 "Found multiple pinseq=%s attributes on one pin\n",
286 string);
287 s_current->error_messages = g_list_append(s_current->error_messages,
288 message);
289 multiple_pinseq_attrib_sum++;
290 s_current->error_count++;
293 g_free(string);
295 /* this is the first attribute found */
296 if (!found_first) {
297 found_numbers = g_list_append(found_numbers, number);
298 found_first=TRUE;
299 } else {
300 if (number)
301 g_free(number);
304 counter++;
305 string = o_attrib_search_name_single_count(o_current, "pinseq",
306 counter);
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;
318 while (ptr1)
320 char *string = (char *) ptr1->data;
321 int found = 0;
323 ptr2 = found_numbers;
324 while(ptr2 && string)
326 char *current = (char *) ptr2->data;
328 if (current && strcmp(string, current) == 0) {
329 found++;
332 ptr2 = g_list_next(ptr2);
335 if (found > 1)
337 message = g_strdup_printf (
338 "Found duplicate pinseq=%s attribute in the symbol\n",
339 string);
340 s_current->error_messages = g_list_append(s_current->error_messages,
341 message);
342 s_current->error_count++;
343 s_current->duplicate_pinseq_attrib++;
346 ptr1 = g_list_next(ptr1);
349 ptr1 = found_numbers;
350 while (ptr1)
352 g_free(ptr1->data);
353 ptr1 = g_list_next(ptr1);
355 g_list_free(found_numbers);
360 void
361 s_check_pinnumber(OBJECT *object_head, SYMCHECK *s_current)
363 OBJECT *o_current;
364 char *string;
365 int found_first=FALSE;
366 int missing_pinnumber_attrib_sum=0;
367 int multiple_pinnumber_attrib_sum=0;
368 int counter=0;
369 int j;
371 GList *found_numbers = NULL;
372 GList *ptr1 = NULL;
373 GList *ptr2 = NULL;
374 char *number = NULL;
375 char *message;
376 char *net = NULL;
377 char *temp;
378 char *netpins = NULL;
379 char tempstr[10];
381 counter = 0;
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,
387 message);
389 netpins = u_basic_breakup_string(net, ':', 1);
391 if (!netpins) {
392 message = g_strdup ("Bad net= attribute\n");
393 s_current->error_messages = g_list_append(s_current->error_messages,
394 message);
395 s_current->error_count++;
397 g_free(net);
398 counter++;
399 continue;
402 j = 0;
403 do {
404 if (number) {
405 g_free(number);
406 number = NULL;
409 number = u_basic_breakup_string(netpins, ',', j);
411 if (!number)
412 break;
414 message = g_strdup_printf ("Found pin number %s in net attribute\n",
415 number);
416 s_current->info_messages = g_list_append(s_current->info_messages,
417 message);
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,
423 message);
424 s_current->error_count++;
427 temp = g_strdup(number);
428 found_numbers = g_list_append(found_numbers, temp);
430 s_current->numnetpins++;
432 j++;
433 } while (number);
435 if (number)
436 g_free(number);
439 g_free(net);
440 g_free(netpins);
442 counter++;
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;
456 found_first = FALSE;
457 counter = 0;
459 string = o_attrib_search_name_single_count(o_current, "pinnumber",
460 counter);
461 if (!string)
463 message = g_strdup ("Missing pinnumber= attribute\n");
464 s_current->error_messages = g_list_append(s_current->error_messages,
465 message);
466 missing_pinnumber_attrib_sum++;
467 s_current->error_count++;
470 while (string)
472 message = g_strdup_printf ("Found pinnumber=%s attribute\n", string);
473 s_current->info_messages = g_list_append(s_current->info_messages,
474 message);
476 if (found_first) {
477 message = g_strdup_printf (
478 "Found multiple pinnumber=%s attributes on one pin\n",
479 string);
480 s_current->error_messages = g_list_append(s_current->error_messages,
481 message);
482 multiple_pinnumber_attrib_sum++;
483 s_current->error_count++;
486 number = g_strdup (string);
487 g_free(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,
492 message);
493 s_current->error_count++;
496 /* this is the first attribute found */
497 if (!found_first) {
498 found_numbers = g_list_append(found_numbers, number);
499 found_first=TRUE;
500 } else {
501 if (number)
502 g_free(number);
505 counter++;
506 string = o_attrib_search_name_single_count(o_current, "pinnumber",
507 counter);
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;
521 while (ptr1)
523 char *string = (char *) ptr1->data;
524 int found = 0;
526 ptr2 = found_numbers;
527 while(ptr2 && string)
529 char *current = (char *) ptr2->data;
531 if (current && strcmp(string, current) == 0) {
532 found++;
535 ptr2 = g_list_next(ptr2);
538 if (found > 1)
540 message = g_strdup_printf (
541 "Found duplicate pinnumber=%s attribute in the symbol\n",
542 string);
543 s_current->error_messages = g_list_append(s_current->error_messages,
544 message);
545 s_current->error_count++;
546 s_current->duplicate_pinnumber_attrib++;
549 ptr1 = g_list_next(ptr1);
552 ptr1 = found_numbers;
553 while (ptr1)
555 g_free(ptr1->data);
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,
564 message);
567 void
568 s_check_pin_ongrid(OBJECT *object_head, SYMCHECK *s_current)
570 int x1, x2, y1, y2;
571 OBJECT *o_current;
572 char *message;
575 for (o_current = object_head;
576 o_current != NULL;
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,
590 message);
591 s_current->error_count++;
593 else {
594 s_current->warning_messages = g_list_append(s_current->warning_messages,
595 message);
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,
605 message);
606 s_current->error_count++;
608 else {
609 s_current->warning_messages = g_list_append(s_current->warning_messages,
610 message);
611 s_current->warning_count++;
619 void
620 s_check_slotdef(OBJECT *object_head, SYMCHECK *s_current)
622 char* value = NULL;
623 char* slotdef = NULL;
624 char* slotnum = NULL;
625 char* pins = NULL;
626 char* temp = NULL;
627 char numslots_str[10];
628 int slot;
629 int i,j;
630 char *message;
631 char tempstr1[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;
635 int n,m;
636 char* pin;
637 char* cmp;
638 int match;
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);
645 if (!value) {
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,
648 message);
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,
652 message);
653 return;
656 s_current->numslots=atoi(value);
657 sprintf(numslots_str, "%d", s_current->numslots);
658 g_free(value);
660 message = g_strdup_printf ("Found numslots=%s attribute\n", numslots_str);
661 s_current->info_messages = g_list_append(s_current->info_messages,
662 message);
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,
667 message);
668 return;
672 pinlist = (char**)g_malloc0(sizeof(*pinlist) * s_current->numslots);
674 i = 0;
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,
687 message);
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,
695 message);
697 slotnum = u_basic_breakup_string(slotdef, ':', 0);
698 if (!slotnum)
700 message = g_strdup_printf (
701 "Invalid slotdef=%s attributes, not continuing\n",
702 slotdef);
703 s_current->error_messages = g_list_append(s_current->error_messages,
704 message);
705 s_current->error_count++;
706 s_current->slotting_errors++;
707 error_parsing = TRUE;
708 continue;
711 if (strcmp(slotnum, "0") == 0) {
712 message = g_strdup_printf (
713 "Found a zero slot in slotdef=%s\n",
714 slotdef);
715 s_current->error_messages = g_list_append(s_current->error_messages,
716 message);
717 s_current->error_count++;
720 slot = atoi(slotnum);
721 g_free(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,
730 message);
732 s_current->error_count++;
733 s_current->slotting_errors++;
736 /* skip over the : */
737 pins = strchr(slotdef, ':');
738 if (!pins) {
739 message = g_strdup_printf (
740 "Invalid slotdef=%s attributes, not continuing\n",
741 slotdef);
742 s_current->error_messages = g_list_append(s_current->error_messages,
743 message);
744 s_current->error_count++;
745 s_current->slotting_errors++;
746 error_parsing = TRUE;
747 continue;
749 pins++; /* get past that : */
750 if (!pins) {
751 message = g_strdup_printf (
752 "Invalid slotdef=%s attributes, not continuing\n",
753 slotdef);
754 s_current->error_messages = g_list_append(s_current->error_messages,
755 message);
756 s_current->error_count++;
757 s_current->slotting_errors++;
758 error_parsing = TRUE;
759 continue;
762 if (*pins == '\0') {
763 message = g_strdup_printf (
764 "Invalid slotdef=%s attributes, not continuing\n",
765 slotdef);
766 s_current->error_messages = g_list_append(s_current->error_messages,
767 message);
768 s_current->error_count++;
769 s_current->slotting_errors++;
770 error_parsing = TRUE;
771 continue;
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",
777 slotdef);
778 s_current->error_messages = g_list_append(s_current->error_messages,
779 message);
780 s_current->error_count++;
781 s_current->slotting_errors++;
782 } else {
783 pinlist[slot-1] = g_strdup_printf(",%s,", pins);
787 j = 0;
788 do {
789 if (temp) {
790 g_free(temp);
791 temp = NULL;
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",
799 slotdef);
800 s_current->error_messages = g_list_append(s_current->error_messages,
801 message);
802 s_current->error_count++;
803 s_current->slotting_errors++;
804 break;
807 if (j > s_current->numpins) {
808 message = g_strdup_printf (
809 "Too many pins in slotdef=%s\n",
810 slotdef);
811 s_current->error_messages = g_list_append(s_current->error_messages,
812 message);
813 s_current->error_count++;
814 s_current->slotting_errors++;
815 g_free(temp);
816 temp = NULL;
817 break;
820 if (temp && strcmp(temp, "0") == 0) {
821 message = g_strdup_printf (
822 "Found a zero pin in slotdef=%s\n",
823 slotdef);
824 s_current->error_messages = g_list_append(s_current->error_messages,
825 message);
826 s_current->error_count++;
829 j++;
830 } while (temp);
832 if (temp)
833 g_free(temp);
835 g_free(slotdef);
836 slotdef = NULL;
838 i++;
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",
845 numslots_str);
846 s_current->error_messages = g_list_append(s_current->error_messages,
847 message);
848 s_current->error_count++;
849 s_current->slotting_errors++;
850 } else {
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 */
854 /* with. */
855 for (i = 0; i < s_current->numslots; i++) {
856 if (pinlist[i] == NULL) {
857 errors_found++;
861 if (errors_found) {
862 message = g_strdup_printf(
863 "Malformed slotdef= (the format is #:#,#,#,...)\n");
864 s_current->error_messages = g_list_append(s_current->error_messages,
865 message);
866 s_current->error_count++;
867 s_current->slotting_errors++;
868 } else {
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);
875 if (pin && *pin) {
876 match = FALSE;
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);
881 if (cmp && *cmp) {
882 match = (0 == strcmp (pin, cmp));
883 g_free(cmp);
887 if (!match) {
888 /* If they don't match, then increase the number of pins */
889 s_current->numslotpins++;
891 g_free(pin);
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,
898 message);
902 if (slotdef) {
903 g_free(slotdef);
905 if (pinlist) {
906 /* Free the pinlist */
907 for (i = 0; i < s_current->numslots; i++) {
908 if (pinlist[i]) {
909 g_free(pinlist[i]);
912 g_free(pinlist);
915 return;
919 void
920 s_check_oldpin(OBJECT *object_head, SYMCHECK *s_current)
922 OBJECT *o_current;
923 char *ptr;
924 int found_old = FALSE;
925 int number_counter = 0;
926 char *message;
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;
939 found_old = FALSE;
940 number_counter = 0;
941 while (ptr && *ptr > '0' && *ptr < '9')
943 number_counter++;
944 ptr++;
947 if (ptr && *ptr == '=')
949 found_old++;
952 if (!ptr)
954 o_current = o_current->next;
955 continue;
958 /* found no numbers inbetween pin and = */
959 if (number_counter == 0)
961 o_current = o_current->next;
962 continue;
965 /* skip over = char */
966 ptr++;
968 while (ptr && *ptr > '0' && *ptr < '9')
970 ptr++;
973 if (*ptr == '\0')
975 found_old++;
978 /* 2 matches -> number found after pin and only numbers after = sign */
979 if (found_old == 2)
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,
985 message);
987 s_current->found_oldpin_attrib += found_old;
988 s_current->error_count++;
994 o_current = o_current->next;
1000 void
1001 s_check_oldslot(OBJECT *object_head, SYMCHECK *s_current)
1003 OBJECT *o_current;
1004 char *ptr;
1005 int found_old = FALSE;
1006 int number_counter = 0;
1007 char *message;
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;
1020 found_old = FALSE;
1021 number_counter = 0;
1022 while (ptr && *ptr > '0' && *ptr < '9')
1024 number_counter++;
1025 ptr++;
1028 if (ptr && *ptr == '=')
1030 found_old++;
1033 if (!ptr)
1035 o_current = o_current->next;
1036 continue;
1039 /* found no numbers inbetween pin and = */
1040 if (number_counter == 0)
1042 o_current = o_current->next;
1043 continue;
1046 /* skip over = char */
1047 ptr++;
1049 while ((ptr && (*ptr > '0') && (*ptr < '9')) || (*ptr == ','))
1051 ptr++;
1054 if (*ptr == '\0')
1056 found_old++;
1059 /* 2 matches -> number found after slot and only numbers after = */
1060 if (found_old == 2)
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,
1066 message);
1067 s_current->found_oldslot_attrib += found_old;
1068 s_current->error_count++;
1074 o_current = o_current->next;
1079 void
1080 s_check_nets_buses(OBJECT *object_head, SYMCHECK *s_current)
1082 OBJECT *o_current;
1083 char *message;
1085 o_current = object_head;
1086 while(o_current != NULL)
1088 if (o_current->type == OBJ_NET)
1090 message =
1091 g_strdup ("Found a net inside a symbol\n");
1092 s_current->error_messages = g_list_append(s_current->error_messages,
1093 message);
1094 s_current->found_net++;
1095 s_current->error_count++;
1098 if (o_current->type == OBJ_BUS)
1100 message =
1101 g_strdup ("Found a bus inside a symbol\n");
1102 s_current->error_messages = g_list_append(s_current->error_messages,
1103 message);
1104 s_current->found_bus++;
1105 s_current->error_count++;
1109 o_current = o_current->next;
1113 void
1114 s_check_connections(OBJECT *object_head, SYMCHECK *s_current)
1116 OBJECT *o_current;
1117 char *message;
1119 o_current = object_head;
1120 while(o_current != NULL)
1123 if (o_current->conn_list) {
1124 message =
1125 g_strdup ("Found a connection inside a symbol\n");
1126 s_current->error_messages = g_list_append(s_current->error_messages,
1127 message);
1128 s_current->found_connection++;
1129 s_current->error_count++;
1132 o_current = o_current->next;
1136 void
1137 s_check_obsolete_forbidden_attributes(OBJECT *object_head, SYMCHECK *s_current)
1139 OBJECT *o_current;
1140 char *message;
1141 char *attrib;
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;
1201 void
1202 s_check_missing_attribute(OBJECT *object, char *attribute, SYMCHECK *s_current)
1204 char *string;
1205 int found_first=FALSE;
1206 int counter=0;
1207 char *message;
1209 if (!attribute) {
1210 return;
1213 string = o_attrib_search_name_single_count(object, attribute,
1214 counter);
1215 if (!string)
1217 message = g_strdup_printf (
1218 "Missing %s= attribute\n",
1219 attribute);
1220 s_current->warning_messages = g_list_append(s_current->warning_messages,
1221 message);
1222 s_current->warning_count++;
1225 while (string)
1228 if (found_first) {
1229 message = g_strdup_printf (
1230 "Found multiple %s=%s attributes on one pin\n",
1231 attribute, string);
1232 s_current->error_messages = g_list_append(s_current->error_messages,
1233 message);
1234 s_current->error_count++;
1237 /* this is the first attribute found */
1238 if (!found_first) {
1240 message = g_strdup_printf (
1241 "Found %s=%s attribute\n",
1242 attribute, string);
1243 s_current->info_messages = g_list_append(s_current->info_messages,
1244 message);
1245 found_first=TRUE;
1248 g_free(string);
1250 counter++;
1251 string = o_attrib_search_name_single_count(object, attribute,
1252 counter);
1257 void
1258 s_check_missing_attributes(OBJECT *object_head, SYMCHECK *s_current)
1260 OBJECT *o_current;
1261 char *message;
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,
1279 message);
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,
1288 message);
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,
1300 message);
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,
1307 message);
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,
1315 message);
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,
1323 message);
1324 s_current->error_count++;
1329 void s_check_pintype(OBJECT *object_head, SYMCHECK *s_current)
1331 OBJECT *o_current;
1332 char *string;
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;
1337 int counter=0;
1339 char *pintype;
1340 char *message;
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;
1352 counter = 0;
1354 string = o_attrib_search_name_single_count(o_current, "pintype",
1355 counter);
1356 /* if (!string) */
1357 /* { */
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, */
1361 /* message); */
1362 /* missing_pintype_attrib_sum++; */
1363 /* s_current->error_count++; */
1364 /* } */
1366 while (string)
1369 message = g_strdup_printf("Found pintype=%s attribute\n", string);
1370 s_current->info_messages = g_list_append(s_current->info_messages,
1371 message);
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,
1388 message);
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, */
1398 /* message); */
1399 /* multiple_pintype_attrib_sum++; */
1400 /* s_current->error_count++; */
1401 /* } */
1403 g_free(string);
1405 if (pintype)
1406 g_free(pintype);
1408 counter++;
1409 string = o_attrib_search_name_single_count(o_current, "pintype",
1410 counter);
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;