Updated all ChangeLogs to pick up all new commits
[geda-gaf/whiteaudio.git] / gsymcheck / src / s_check.c
blobf6483a06af7e8c01febd25114f78b27b48bbd3a2
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 /* 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 */
118 if (!quiet_mode) {
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");
128 } else {
129 s_log_message("\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");
139 } else {
140 s_log_message("\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");
148 } else {
149 s_log_message("\n");
154 errors = s_symcheck->error_count;
155 warnings = s_symcheck->warning_count;
156 s_symstruct_free(s_symcheck);
157 if (errors) {
158 return(2);
159 } else if (warnings) {
160 return(1);
161 } else {
162 return(0);
167 gboolean
168 s_check_list_has_item(char **list , char *item)
170 gint cur;
171 for (cur = 0; list[cur] != NULL; cur++) {
172 if (strcmp(item, list[cur]) == 0)
173 return TRUE;
175 return FALSE;
178 void
179 s_check_symbol_structure(OBJECT *object_head, SYMCHECK *s_current)
181 OBJECT *o_current;
183 gchar *message;
184 gchar **tokens;
186 char *valid_pin_attributes[] = {"pinlabel", "pintype",
187 "pinseq", "pinnumber",
188 NULL};
189 char *valid_attributes[] = {"device", "graphical", "description",
190 "author", "comment", "numslots",
191 "slotdef", "footprint", "documentation",
192 "refdes", "slot", "net", "value",
193 "symversion", "dist-license",
194 NULL};
195 char *obsolete_attributes[] = {"uref", "label", "email",
196 NULL};
197 char *forbidden_attributes[] = {"type", "name",
198 NULL};
199 /* pin# ?, slot# ? */
201 for (o_current = object_head;
202 o_current != NULL;
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])) {
233 #if 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++;
239 #endif
241 else if (o_current->attached_to != NULL) {
242 message = g_strdup_printf ("Found wrongly attached attribute: "
243 "[%s=%s]\n",
244 tokens[0], tokens[1]);
245 s_current->error_messages =
246 g_list_append(s_current->error_messages, message);
247 s_current->error_count++;
250 g_strfreev(tokens);
255 void
256 s_check_graphical(OBJECT *o_current, SYMCHECK *s_current)
258 char *temp;
260 /* look for special graphical tag */
261 temp = o_attrib_search_name(o_current, "graphical", 0);
263 if (temp) {
264 s_current->graphical_symbol=TRUE;
265 g_free(temp);
269 void
270 s_check_device(OBJECT *o_current, SYMCHECK *s_current)
272 char *temp;
273 char *message;
275 /* search for device attribute */
276 temp = o_attrib_search_name(o_current, "device", 0);
277 if (!temp) {
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,
281 message);
282 s_current->missing_device_attrib=TRUE;
283 s_current->error_count++;
284 } else {
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,
292 message);
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,
300 message);
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,
305 message);
306 s_current->warning_count++;
309 if (temp)
310 g_free(temp);
314 void
315 s_check_pinseq(OBJECT *object_head, SYMCHECK *s_current)
317 OBJECT *o_current;
318 char *string;
319 int found_first=FALSE;
320 int missing_pinseq_attrib_sum=0;
321 int multiple_pinseq_attrib_sum=0;
322 int counter=0;
324 GList *found_numbers = NULL;
325 GList *ptr1 = NULL;
326 GList *ptr2 = NULL;
327 char *number;
328 char *message;
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;
338 found_first = FALSE;
339 counter = 0;
341 string = o_attrib_search_name_single_count(o_current, "pinseq",
342 counter);
343 if (!string)
345 message = g_strdup ("Missing pinseq= attribute\n");
346 s_current->error_messages = g_list_append(s_current->error_messages,
347 message);
348 missing_pinseq_attrib_sum++;
349 s_current->error_count++;
352 while (string)
355 message = g_strdup_printf ("Found pinseq=%s attribute\n", string);
356 s_current->info_messages = g_list_append(s_current->info_messages,
357 message);
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,
364 message);
365 s_current->error_count++;
368 if (found_first) {
369 message = g_strdup_printf (
370 "Found multiple pinseq=%s attributes on one pin\n",
371 string);
372 s_current->error_messages = g_list_append(s_current->error_messages,
373 message);
374 multiple_pinseq_attrib_sum++;
375 s_current->error_count++;
378 g_free(string);
380 /* this is the first attribute found */
381 if (!found_first) {
382 found_numbers = g_list_append(found_numbers, number);
383 found_first=TRUE;
384 } else {
385 if (number)
386 g_free(number);
389 counter++;
390 string = o_attrib_search_name_single_count(o_current, "pinseq",
391 counter);
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;
403 while (ptr1)
405 char *string = (char *) ptr1->data;
406 int found = 0;
408 ptr2 = found_numbers;
409 while(ptr2 && string)
411 char *current = (char *) ptr2->data;
413 if (current && strcmp(string, current) == 0) {
414 found++;
417 ptr2 = g_list_next(ptr2);
420 if (found > 1)
422 message = g_strdup_printf (
423 "Found duplicate pinseq=%s attribute in the symbol\n",
424 string);
425 s_current->error_messages = g_list_append(s_current->error_messages,
426 message);
427 s_current->error_count++;
428 s_current->duplicate_pinseq_attrib++;
431 ptr1 = g_list_next(ptr1);
434 ptr1 = found_numbers;
435 while (ptr1)
437 g_free(ptr1->data);
438 ptr1 = g_list_next(ptr1);
440 g_list_free(found_numbers);
445 void
446 s_check_pinnumber(OBJECT *object_head, SYMCHECK *s_current)
448 OBJECT *o_current;
449 char *string;
450 int found_first=FALSE;
451 int missing_pinnumber_attrib_sum=0;
452 int multiple_pinnumber_attrib_sum=0;
453 int counter=0;
454 int j;
456 GList *found_numbers = NULL;
457 GList *ptr1 = NULL;
458 GList *ptr2 = NULL;
459 char *number = NULL;
460 char *message;
461 char *net = NULL;
462 char *temp;
463 char *netpins = NULL;
464 char tempstr[10];
466 counter = 0;
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,
472 message);
474 netpins = u_basic_breakup_string(net, ':', 1);
476 if (!netpins) {
477 message = g_strdup ("Bad net= attribute\n");
478 s_current->error_messages = g_list_append(s_current->error_messages,
479 message);
480 s_current->error_count++;
482 g_free(net);
483 counter++;
484 continue;
487 j = 0;
488 do {
489 if (number) {
490 g_free(number);
491 number = NULL;
494 number = u_basic_breakup_string(netpins, ',', j);
496 if (!number)
497 break;
499 message = g_strdup_printf ("Found pin number %s in net attribute\n",
500 number);
501 s_current->info_messages = g_list_append(s_current->info_messages,
502 message);
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,
508 message);
509 s_current->error_count++;
512 temp = g_strdup(number);
513 found_numbers = g_list_append(found_numbers, temp);
515 s_current->numnetpins++;
517 j++;
518 } while (number);
520 if (number)
521 g_free(number);
524 g_free(net);
525 g_free(netpins);
527 counter++;
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;
541 found_first = FALSE;
542 counter = 0;
544 string = o_attrib_search_name_single_count(o_current, "pinnumber",
545 counter);
546 if (!string)
548 message = g_strdup ("Missing pinnumber= attribute\n");
549 s_current->error_messages = g_list_append(s_current->error_messages,
550 message);
551 missing_pinnumber_attrib_sum++;
552 s_current->error_count++;
555 while (string)
557 message = g_strdup_printf ("Found pinnumber=%s attribute\n", string);
558 s_current->info_messages = g_list_append(s_current->info_messages,
559 message);
561 if (found_first) {
562 message = g_strdup_printf (
563 "Found multiple pinnumber=%s attributes on one pin\n",
564 string);
565 s_current->error_messages = g_list_append(s_current->error_messages,
566 message);
567 multiple_pinnumber_attrib_sum++;
568 s_current->error_count++;
571 number = g_strdup (string);
572 g_free(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,
577 message);
578 s_current->error_count++;
581 /* this is the first attribute found */
582 if (!found_first) {
583 found_numbers = g_list_append(found_numbers, number);
584 found_first=TRUE;
585 } else {
586 if (number)
587 g_free(number);
590 counter++;
591 string = o_attrib_search_name_single_count(o_current, "pinnumber",
592 counter);
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;
606 while (ptr1)
608 char *string = (char *) ptr1->data;
609 int found = 0;
611 ptr2 = found_numbers;
612 while(ptr2 && string)
614 char *current = (char *) ptr2->data;
616 if (current && strcmp(string, current) == 0) {
617 found++;
620 ptr2 = g_list_next(ptr2);
623 if (found > 1)
625 message = g_strdup_printf (
626 "Found duplicate pinnumber=%s attribute in the symbol\n",
627 string);
628 s_current->error_messages = g_list_append(s_current->error_messages,
629 message);
630 s_current->error_count++;
631 s_current->duplicate_pinnumber_attrib++;
634 ptr1 = g_list_next(ptr1);
637 ptr1 = found_numbers;
638 while (ptr1)
640 g_free(ptr1->data);
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,
649 message);
652 void
653 s_check_pin_ongrid(OBJECT *object_head, SYMCHECK *s_current)
655 int x1, x2, y1, y2;
656 OBJECT *o_current;
657 char *message;
660 for (o_current = object_head;
661 o_current != NULL;
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,
675 message);
676 s_current->error_count++;
678 else {
679 s_current->warning_messages = g_list_append(s_current->warning_messages,
680 message);
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,
690 message);
691 s_current->error_count++;
693 else {
694 s_current->warning_messages = g_list_append(s_current->warning_messages,
695 message);
696 s_current->warning_count++;
704 void
705 s_check_slotdef(OBJECT *object_head, SYMCHECK *s_current)
707 char* value = NULL;
708 char* slotdef = NULL;
709 char* slotnum = NULL;
710 char* pins = NULL;
711 char* temp = NULL;
712 char numslots_str[10];
713 int slot;
714 int i,j;
715 char *message;
716 char tempstr1[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;
720 int n,m;
721 char* pin;
722 char* cmp;
723 int match;
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);
730 if (!value) {
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,
733 message);
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,
737 message);
738 return;
741 s_current->numslots=atoi(value);
742 sprintf(numslots_str, "%d", s_current->numslots);
743 g_free(value);
745 message = g_strdup_printf ("Found numslots=%s attribute\n", numslots_str);
746 s_current->info_messages = g_list_append(s_current->info_messages,
747 message);
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,
752 message);
753 return;
757 pinlist = (char**)g_malloc0(sizeof(*pinlist) * s_current->numslots);
759 i = 0;
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,
772 message);
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,
780 message);
782 slotnum = u_basic_breakup_string(slotdef, ':', 0);
783 if (!slotnum)
785 message = g_strdup_printf (
786 "Invalid slotdef=%s attributes, not continuing\n",
787 slotdef);
788 s_current->error_messages = g_list_append(s_current->error_messages,
789 message);
790 s_current->error_count++;
791 s_current->slotting_errors++;
792 error_parsing = TRUE;
793 continue;
796 if (strcmp(slotnum, "0") == 0) {
797 message = g_strdup_printf (
798 "Found a zero slot 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++;
805 slot = atoi(slotnum);
806 g_free(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,
815 message);
817 s_current->error_count++;
818 s_current->slotting_errors++;
821 /* skip over the : */
822 pins = strchr(slotdef, ':');
823 if (!pins) {
824 message = g_strdup_printf (
825 "Invalid slotdef=%s attributes, not continuing\n",
826 slotdef);
827 s_current->error_messages = g_list_append(s_current->error_messages,
828 message);
829 s_current->error_count++;
830 s_current->slotting_errors++;
831 error_parsing = TRUE;
832 continue;
834 pins++; /* get past that : */
835 if (!pins) {
836 message = g_strdup_printf (
837 "Invalid slotdef=%s attributes, not continuing\n",
838 slotdef);
839 s_current->error_messages = g_list_append(s_current->error_messages,
840 message);
841 s_current->error_count++;
842 s_current->slotting_errors++;
843 error_parsing = TRUE;
844 continue;
847 if (*pins == '\0') {
848 message = g_strdup_printf (
849 "Invalid slotdef=%s attributes, not continuing\n",
850 slotdef);
851 s_current->error_messages = g_list_append(s_current->error_messages,
852 message);
853 s_current->error_count++;
854 s_current->slotting_errors++;
855 error_parsing = TRUE;
856 continue;
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",
862 slotdef);
863 s_current->error_messages = g_list_append(s_current->error_messages,
864 message);
865 s_current->error_count++;
866 s_current->slotting_errors++;
867 } else {
868 pinlist[slot-1] = g_strdup_printf(",%s,", pins);
872 j = 0;
873 do {
874 if (temp) {
875 g_free(temp);
876 temp = NULL;
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",
884 slotdef);
885 s_current->error_messages = g_list_append(s_current->error_messages,
886 message);
887 s_current->error_count++;
888 s_current->slotting_errors++;
889 break;
892 if (j > s_current->numpins) {
893 message = g_strdup_printf (
894 "Too many pins in slotdef=%s\n",
895 slotdef);
896 s_current->error_messages = g_list_append(s_current->error_messages,
897 message);
898 s_current->error_count++;
899 s_current->slotting_errors++;
900 g_free(temp);
901 temp = NULL;
902 break;
905 if (temp && strcmp(temp, "0") == 0) {
906 message = g_strdup_printf (
907 "Found a zero pin in slotdef=%s\n",
908 slotdef);
909 s_current->error_messages = g_list_append(s_current->error_messages,
910 message);
911 s_current->error_count++;
914 j++;
915 } while (temp);
917 if (temp)
918 g_free(temp);
920 g_free(slotdef);
921 slotdef = NULL;
923 i++;
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",
930 numslots_str);
931 s_current->error_messages = g_list_append(s_current->error_messages,
932 message);
933 s_current->error_count++;
934 s_current->slotting_errors++;
935 } else {
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 */
939 /* with. */
940 for (i = 0; i < s_current->numslots; i++) {
941 if (pinlist[i] == NULL) {
942 errors_found++;
946 if (errors_found) {
947 message = g_strdup_printf(
948 "Malformed slotdef= (the format is #:#,#,#,...)\n");
949 s_current->error_messages = g_list_append(s_current->error_messages,
950 message);
951 s_current->error_count++;
952 s_current->slotting_errors++;
953 } else {
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);
960 if (pin && *pin) {
961 match = FALSE;
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);
966 if (cmp && *cmp) {
967 match = (0 == strcmp (pin, cmp));
968 g_free(cmp);
972 if (!match) {
973 /* If they don't match, then increase the number of pins */
974 s_current->numslotpins++;
976 g_free(pin);
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,
983 message);
987 if (slotdef) {
988 g_free(slotdef);
990 if (pinlist) {
991 /* Free the pinlist */
992 for (i = 0; i < s_current->numslots; i++) {
993 if (pinlist[i]) {
994 g_free(pinlist[i]);
997 g_free(pinlist);
1000 return;
1004 void
1005 s_check_oldpin(OBJECT *object_head, SYMCHECK *s_current)
1007 OBJECT *o_current;
1008 char *ptr;
1009 int found_old = FALSE;
1010 int number_counter = 0;
1011 char *message;
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;
1024 found_old = FALSE;
1025 number_counter = 0;
1026 while (ptr && *ptr > '0' && *ptr < '9')
1028 number_counter++;
1029 ptr++;
1032 if (ptr && *ptr == '=')
1034 found_old++;
1037 if (!ptr)
1039 o_current = o_current->next;
1040 continue;
1043 /* found no numbers inbetween pin and = */
1044 if (number_counter == 0)
1046 o_current = o_current->next;
1047 continue;
1050 /* skip over = char */
1051 ptr++;
1053 while (ptr && *ptr > '0' && *ptr < '9')
1055 ptr++;
1058 if (*ptr == '\0')
1060 found_old++;
1063 /* 2 matches -> number found after pin and only numbers after = sign */
1064 if (found_old == 2)
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,
1070 message);
1072 s_current->found_oldpin_attrib += found_old;
1073 s_current->error_count++;
1079 o_current = o_current->next;
1085 void
1086 s_check_oldslot(OBJECT *object_head, SYMCHECK *s_current)
1088 OBJECT *o_current;
1089 char *ptr;
1090 int found_old = FALSE;
1091 int number_counter = 0;
1092 char *message;
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;
1105 found_old = FALSE;
1106 number_counter = 0;
1107 while (ptr && *ptr > '0' && *ptr < '9')
1109 number_counter++;
1110 ptr++;
1113 if (ptr && *ptr == '=')
1115 found_old++;
1118 if (!ptr)
1120 o_current = o_current->next;
1121 continue;
1124 /* found no numbers inbetween pin and = */
1125 if (number_counter == 0)
1127 o_current = o_current->next;
1128 continue;
1131 /* skip over = char */
1132 ptr++;
1134 while ((ptr && (*ptr > '0') && (*ptr < '9')) || (*ptr == ','))
1136 ptr++;
1139 if (*ptr == '\0')
1141 found_old++;
1144 /* 2 matches -> number found after slot and only numbers after = */
1145 if (found_old == 2)
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,
1151 message);
1152 s_current->found_oldslot_attrib += found_old;
1153 s_current->error_count++;
1159 o_current = o_current->next;
1164 void
1165 s_check_nets_buses(OBJECT *object_head, SYMCHECK *s_current)
1167 OBJECT *o_current;
1168 char *message;
1170 o_current = object_head;
1171 while(o_current != NULL)
1173 if (o_current->type == OBJ_NET)
1175 message =
1176 g_strdup ("Found a net inside a symbol\n");
1177 s_current->error_messages = g_list_append(s_current->error_messages,
1178 message);
1179 s_current->found_net++;
1180 s_current->error_count++;
1183 if (o_current->type == OBJ_BUS)
1185 message =
1186 g_strdup ("Found a bus inside a symbol\n");
1187 s_current->error_messages = g_list_append(s_current->error_messages,
1188 message);
1189 s_current->found_bus++;
1190 s_current->error_count++;
1194 o_current = o_current->next;
1198 void
1199 s_check_connections(OBJECT *object_head, SYMCHECK *s_current)
1201 OBJECT *o_current;
1202 char *message;
1204 o_current = object_head;
1205 while(o_current != NULL)
1208 if (o_current->conn_list) {
1209 message =
1210 g_strdup ("Found a connection inside a symbol\n");
1211 s_current->error_messages = g_list_append(s_current->error_messages,
1212 message);
1213 s_current->found_connection++;
1214 s_current->error_count++;
1217 o_current = o_current->next;
1221 void
1222 s_check_missing_attribute(OBJECT *object, char *attribute, SYMCHECK *s_current)
1224 char *string;
1225 int found_first=FALSE;
1226 int counter=0;
1227 char *message;
1229 if (!attribute) {
1230 return;
1233 string = o_attrib_search_name_single_count(object, attribute,
1234 counter);
1235 if (!string)
1237 message = g_strdup_printf (
1238 "Missing %s= attribute\n",
1239 attribute);
1240 s_current->warning_messages = g_list_append(s_current->warning_messages,
1241 message);
1242 s_current->warning_count++;
1245 while (string)
1248 if (found_first) {
1249 message = g_strdup_printf (
1250 "Found multiple %s=%s attributes on one pin\n",
1251 attribute, string);
1252 s_current->error_messages = g_list_append(s_current->error_messages,
1253 message);
1254 s_current->error_count++;
1257 /* this is the first attribute found */
1258 if (!found_first) {
1260 message = g_strdup_printf (
1261 "Found %s=%s attribute\n",
1262 attribute, string);
1263 s_current->info_messages = g_list_append(s_current->info_messages,
1264 message);
1265 found_first=TRUE;
1268 g_free(string);
1270 counter++;
1271 string = o_attrib_search_name_single_count(object, attribute,
1272 counter);
1277 void
1278 s_check_missing_attributes(OBJECT *object_head, SYMCHECK *s_current)
1280 OBJECT *o_current;
1281 char *message;
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,
1299 message);
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,
1308 message);
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,
1320 message);
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,
1327 message);
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,
1335 message);
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,
1343 message);
1344 s_current->error_count++;
1349 void s_check_pintype(OBJECT *object_head, SYMCHECK *s_current)
1351 OBJECT *o_current;
1352 int counter=0;
1353 char *pintype;
1354 char *message;
1355 char *pintypes[] = {"in", "out", "io", "oc", "oe",
1356 "pas", "tp", "tri", "clk", "pwr",
1357 NULL};
1359 for (o_current = object_head;
1360 o_current != NULL;
1361 o_current = o_current->next) {
1363 if (o_current->type == OBJ_PIN) {
1365 for (counter = 0;
1366 (pintype = o_attrib_search_name_single_count(o_current, "pintype",
1367 counter)) != NULL;
1368 counter++) {
1370 message = g_strdup_printf("Found pintype=%s attribute\n", pintype);
1371 s_current->info_messages = g_list_append(s_current->info_messages,
1372 message);
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,
1377 message);
1378 s_current->error_count++;
1381 g_free(pintype);