9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /* Copyright (c) 1988 AT&T */
23 /* All Rights Reserved */
24
25
26 /*
27 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
29 */
30
31 #pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.13 */
32
33 /*
34 NAME
35 infocmp - compare terminfo descriptions, or dump a terminfo
36 description
37
38 AUTHOR
39 Tony Hansen, February 23, 1984.
40 */
41
42 #include "curses.h"
43 #include "term.h"
44 #include "print.h"
45 #include <fcntl.h>
46 #include <stdlib.h>
47
48 /* externs from libcurses */
49 extern char *boolnames[];
50 extern char *boolcodes[];
51 extern char *boolfnames[];
52 extern char *numnames[];
168 ;
169
170 if (verbose) {
171 (void) fprintf(trace, "There are %d boolean capabilities.\n",
172 numbools);
173 (void) fprintf(trace, "There are %d numeric capabilities.\n",
174 numnums);
175 (void) fprintf(trace, "There are %d string capabilities.\n",
176 numstrs);
177 }
178
179 /* Allocate storage for the names and their values */
180 ibool = (struct boolstruct *) malloc((unsigned) numbools *
181 sizeof (struct boolstruct));
182 num = (struct numstruct *) malloc((unsigned) numnums *
183 sizeof (struct numstruct));
184 str = (struct strstruct *) malloc((unsigned) numstrs *
185 sizeof (struct strstruct));
186
187 /* Allocate array to keep track of which names have been used. */
188 if (use)
189 used = (char *) malloc((unsigned) (argc - firstoptind) *
190 sizeof (char));
191
192 if ((ibool == NULL) || (num == NULL) || (str == NULL) ||
193 (use && (used == NULL)))
194 badmalloc();
195
196 /* Fill in the names and initialize the structures. */
197 nullseen = FALSE;
198 for (i = 0; i < numbools; i++) {
199 ibool[i].infoname = boolnames[i];
200 ibool[i].capname = boolcodes[i];
201 /* This is necessary until fnames.c is */
202 /* incorporated into standard curses. */
203 if (nullseen || (boolfnames[i] == NULL)) {
204 ibool[i].fullname = "unknown_boolean";
205 nullseen = TRUE;
206 } else
207 ibool[i].fullname = boolfnames[i];
208 ibool[i].changed = FALSE;
209 ibool[i].seenagain = FALSE;
210 }
211 nullseen = 0;
212 for (i = 0; i < numnums; i++) {
213 num[i].infoname = numnames[i];
214 num[i].capname = numcodes[i];
215 if (nullseen || (numfnames[i] == NULL)) {
216 ibool[i].fullname = "unknown_number";
217 nullseen = TRUE;
218 } else
219 num[i].fullname = numfnames[i];
220 num[i].changed = FALSE;
221 num[i].seenagain = FALSE;
222 }
223 nullseen = 0;
224 for (i = 0; i < numstrs; i++) {
225 str[i].infoname = strnames[i];
226 str[i].capname = strcodes[i];
227 if (nullseen || (strfnames[i] == NULL)) {
228 str[i].fullname = "unknown_string";
229 nullseen = TRUE;
230 } else
231 str[i].fullname = strfnames[i];
232 str[i].changed = FALSE;
233 str[i].seenagain = FALSE;
234 }
235 }
236
237 /*
238 Routines to be passed to qsort(3) for comparison of the structures.
239 */
240 int
241 boolcompare(const void *x, const void *y)
242 {
243 struct boolstruct *a;
244 struct boolstruct *b;
245
246 a = (struct boolstruct *)x;
247 b = (struct boolstruct *)y;
248
249 switch ((int) sortorder) {
250 case (int) by_terminfo:
251 return (strcmp(a->infoname, b->infoname));
505 if (verbose)
506 (void) fprintf(trace, "looking at 'nl'\n");
507 retptr = cconvert(rmpadding(cursor_down, padbuffer, (int *) 0));
508 if (strcmp("\\n", retptr) != 0)
509 pr_string((char *)0, "nl", (char *)0, cursor_down);
510
511 /* Handle "ko" here: Termcap entries for other non-function keys */
512 pr_ko();
513
514 /* Ignore "ma": Arrow key map, used by vi version 2 only */
515 }
516
517 /*
518 Set up the first terminal and save the values from it.
519 */
520 void
521 initfirstterm(char *term)
522 {
523 register int i;
524
525 if (verbose)
526 (void) fprintf(trace, "setting up terminal type '%s'.\n",
527 term);
528
529 (void) setupterm(term, devnull, (int *) 0);
530
531 /* Save the name for later use. */
532 if (use) {
533 register unsigned int length;
534 savettytype = _savettytype;
535 if ((length = strlen(ttytype)) >= TTYLEN) {
536 savettytype = malloc(length);
537 if (savettytype == NULL) {
538 (void) fprintf(stderr, "%s: malloc is out "
539 "of space\n", progname);
540 (void) strncpy(_savettytype, ttytype,
541 TTYLEN-1);
542 _savettytype[TTYLEN] = '\0';
543 savettytype = _savettytype;
544 }
545 } else
546 (void) strcpy(_savettytype, ttytype);
547 }
548
549 if (printing != pr_none) {
550 pr_heading(term, ttytype);
551 pr_bheading();
552 }
553
554 /* Save the values for the first terminal. */
555 for (i = 0; i < numbools; i++) {
556 if ((ibool[i].val = tgetflag(ibool[i].capname)) &&
557 printing != pr_none)
558 pr_boolean(ibool[i].infoname, ibool[i].capname,
559 ibool[i].fullname, 1);
560 if (verbose)
561 (void) fprintf(trace, "%s=%d.\n", ibool[i].infoname,
562 ibool[i].val);
563 }
564
565 if (printing != pr_none) {
566 if (printing == pr_cap)
567 pr_bcaps();
568 pr_bfooting();
569 pr_nheading();
570 }
571
572 for (i = 0; i < numnums; i++) {
573 if (((num[i].val = tgetnum(num[i].capname)) > -1) &&
574 printing != pr_none)
575 pr_number(num[i].infoname, num[i].capname,
576 num[i].fullname, num[i].val);
577 if (verbose)
578 (void) fprintf(trace, "%s=%d.\n", num[i].infoname,
579 num[i].val);
580 }
581
582 if (printing != pr_none) {
583 if (printing == pr_cap)
584 pr_ncaps();
585 pr_nfooting();
586 pr_sheading();
587 }
588
589 for (i = 0; i < numstrs; i++) {
590 str[i].val = tgetstr(str[i].capname, (char **)0);
591 if ((str[i].val != NULL) && printing != pr_none)
592 pr_string(str[i].infoname, str[i].capname,
593 str[i].fullname, str[i].val);
594 if (verbose) {
595 (void) fprintf(trace, "%s='", str[i].infoname);
596 PR(trace, str[i].val);
597 (void) fprintf(trace, "'.\n");
598 }
599 }
600
601 if (printing == pr_cap)
602 pr_scaps();
603
604 if (printing != pr_none)
605 pr_sfooting();
606 }
607
608 /*
609 Set up the n'th terminal.
610 */
611 static void
612 check_nth_terminal(char *nterm, int n)
613 {
614 register char boolval;
615 register short numval;
616 register char *strval;
617 register int i;
618
619 if (use)
620 used[n] = FALSE;
621
622 if (verbose)
623 (void) fprintf(trace, "adding in terminal type '%s'.\n",
624 nterm);
625
626 (void) setupterm(nterm, devnull, (int *) 0);
627
628 if (printing != pr_none) {
629 pr_heading(nterm, ttytype);
630 pr_bheading();
631 }
632
633 if (diff || common || neither) {
634 if (Aflag && Bflag)
635 (void) printf("comparing %s (TERMINFO=%s) to %s "
636 "(TERMINFO=%s).\n",
637 firstterm, term1info, nterm, term2info);
638 else if (Aflag)
639 (void) printf("comparing %s (TERMINFO=%s) to %s.\n",
640 firstterm, term1info, nterm);
641 else if (Bflag)
642 (void) printf("comparing %s to %s (TERMINFO=%s).\n",
643 firstterm, nterm, term2info);
644 else
662 ** "found:\n");
663 ** (void) fprintf(trace, " %s: %s has %d, %s has"
664 ** " %d.\n",
665 ** ibool[i].capname, ibool[i].secondname,
666 ** ibool[i].secondval, nterm, boolval);
667 ** }
668 */
669 } else {
670 if (boolval == TRUE) {
671 ibool[i].seenagain = TRUE;
672 ibool[i].secondval = boolval;
673 ibool[i].secondname = nterm;
674 if (ibool[i].val != boolval)
675 ibool[i].changed = TRUE;
676 else
677 used[n] = TRUE;
678 }
679 }
680 }
681 if (boolval) {
682 if (printing != pr_none)
683 pr_boolean(ibool[i].infoname, ibool[i].capname,
684 ibool[i].fullname, 1);
685 if (common && (ibool[i].val == boolval))
686 (void) printf("\t%s= T.\n", ibool[i].infoname);
687 } else if (neither && !ibool[i].val)
688 (void) printf("\t!%s.\n", ibool[i].infoname);
689 if (diff && (ibool[i].val != boolval))
690 (void) printf("\t%s: %c:%c.\n", ibool[i].infoname,
691 ibool[i].val?'T':'F', boolval?'T':'F');
692 if (verbose)
693 (void) fprintf(trace, "%s: %d:%d, changed=%d, "
694 "seen=%d.\n", ibool[i].infoname, ibool[i].val,
695 boolval, ibool[i].changed, ibool[i].seenagain);
696 }
697
698 if (printing != pr_none) {
699 if (printing == pr_cap)
700 pr_bcaps();
701 pr_bfooting();
702 pr_nheading();
703 }
704
705 if (diff || common || neither)
706 (void) printf(" comparing numbers.\n");
707
708 for (i = 0; i < numnums; i++) {
709 numval = tgetnum(num[i].capname);
710 if (use) {
711 if (num[i].seenagain) {
712 if ((numval > -1) &&
713 (numval != num[i].secondval)) {
714 (void) fprintf(stderr,
715 "%s: use = order dependency "
716 "found:\n", progname);
717 (void) fprintf(stderr, " %s: %s "
718 "has %d, %s has %d.\n",
719 num[i].capname, num[i].secondname,
720 num[i].secondval, nterm, numval);
721 }
722 } else {
723 if (numval > -1) {
724 num[i].seenagain = TRUE;
725 num[i].secondval = numval;
726 num[i].secondname = nterm;
727 if ((numval > -1) &&
728 (num[i].val != numval))
729 num[i].changed = TRUE;
730 else
731 used[n] = TRUE;
732 }
733 }
734 }
735 if (numval > -1) {
736 if (printing != pr_none)
737 pr_number(num[i].infoname, num[i].capname,
738 num[i].fullname, numval);
739 if (common && (num[i].val == numval))
740 (void) printf("\t%s= %d.\n", num[i].infoname,
741 numval);
742 } else if (neither && (num[i].val == -1))
743 (void) printf("\t!%s.\n", num[i].infoname);
744 if (diff && (num[i].val != numval))
745 (void) printf("\t%s: %d:%d.\n",
746 num[i].infoname, num[i].val, numval);
747 if (verbose)
748 (void) fprintf(trace, "%s: %d:%d, "
749 "changed = %d, seen = %d.\n",
750 num[i].infoname, num[i].val, numval,
751 num[i].changed, num[i].seenagain);
752 }
753
754 if (printing != pr_none) {
755 if (printing == pr_cap)
756 pr_ncaps();
757 pr_nfooting();
758 pr_sheading();
759 }
760
761 if (diff || common || neither)
762 (void) printf(" comparing strings.\n");
763
764 for (i = 0; i < numstrs; i++) {
765 strval = tgetstr(str[i].capname, (char **)0);
766 if (use) {
767 if (str[i].seenagain && (strval != NULL)) {
768 if (!EQUAL(strval, str[i].secondval)) {
769 (void) fprintf(stderr,
770 "use= order dependency"
771 " found:\n");
772 (void) fprintf(stderr,
774 str[i].capname, str[i].secondname);
775 PR(stderr, str[i].secondval);
776 (void) fprintf(stderr,
777 "', %s has '", nterm);
778 PR(stderr, strval);
779 (void) fprintf(stderr, "'.\n");
780 }
781 } else {
782 if (strval != NULL) {
783 str[i].seenagain = TRUE;
784 str[i].secondval = strval;
785 str[i].secondname = nterm;
786 if (!EQUAL(str[i].val, strval))
787 str[i].changed = TRUE;
788 else
789 used[n] = TRUE;
790 }
791 }
792 }
793 if (strval != NULL) {
794 if (printing != pr_none)
795 pr_string(str[i].infoname, str[i].capname,
796 str[i].fullname, strval);
797 if (common && EQUAL(str[i].val, strval)) {
798 (void) printf("\t%s= '", str[i].infoname);
799 PR(stdout, strval);
800 (void) printf("'.\n");
801 }
802 } else if (neither && (str[i].val == NULL))
803 (void) printf("\t!%s.\n", str[i].infoname);
804 if (diff && !EQUAL(str[i].val, strval)) {
805 (void) printf("\t%s: '", str[i].infoname);
806 PR(stdout, str[i].val);
807 (void) printf("','");
808 PR(stdout, strval);
809 (void) printf("'.\n");
810 }
811 if (verbose) {
812 (void) fprintf(trace, "%s: '", str[i].infoname);
813 PR(trace, str[i].val);
814 (void) fprintf(trace, "':'");
815 PR(trace, strval);
816 (void) fprintf(trace, "',changed=%d,seen=%d.\n",
831 A capability gets an at-sign if it no longer exists, but
832 one of the relative entries contains a value for it.
833 It gets printed if the original value is not seen in ANY
834 of the relative entries, or if the FIRST relative entry that has
835 the capability gives a DIFFERENT value for the capability.
836 */
837 void
838 dorelative(int firstoptind, int argc, char **argv)
839 {
840 register int i;
841
842 /* turn off printing of termcap and long names */
843 pr_init(pr_terminfo);
844
845 /* print out the entry name */
846 pr_heading((char *)0, savettytype);
847
848 pr_bheading();
849
850 /* Print out all bools that are different. */
851 for (i = 0; i < numbools; i++)
852 if (!ibool[i].val && ibool[i].changed)
853 pr_boolean(ibool[i].infoname, (char *)0,
854 (char *)0, -1);
855 else if (ibool[i].val && (ibool[i].changed ||
856 !ibool[i].seenagain))
857 pr_boolean(ibool[i].infoname, (char *)0, (char *)0, 1);
858
859 pr_bfooting();
860 pr_nheading();
861
862 /* Print out all nums that are different. */
863 for (i = 0; i < numnums; i++)
864 if (num[i].val < 0 && num[i].changed)
865 pr_number(num[i].infoname, (char *)0, (char *)0, -1);
866 else if (num[i].val >= 0 && (num[i].changed ||
867 !num[i].seenagain))
868 pr_number(num[i].infoname, (char *)0,
869 (char *)0, num[i].val);
870
871 pr_nfooting();
872 pr_sheading();
873
874 /* Print out all strs that are different. */
875 for (i = 0; i < numstrs; i++)
876 if (str[i].val == NULL && str[i].changed)
877 pr_string(str[i].infoname, (char *)0, (char *)0,
878 (char *)0);
879 else if ((str[i].val != NULL) &&
880 (str[i].changed || !str[i].seenagain))
881 pr_string(str[i].infoname, (char *)0, (char *)0, str[i].val);
882
883 pr_sfooting();
884
885 /* Finish it up. */
886 for (i = firstoptind; i < argc; i++)
887 if (used[i - firstoptind])
888 (void) printf("\tuse=%s,\n", argv[i]);
889 else
890 (void) fprintf(stderr,
891 "%s: 'use=%s' did not add anything to the "
892 "description.\n", progname, argv[i]);
893 }
894
895 void
896 local_setenv(char *termNinfo)
897 {
898 extern char **environ;
899 static char *newenviron[2] = { 0, 0 };
900 static unsigned int termsize = BUFSIZ;
901 static char _terminfo[BUFSIZ];
902 static char *terminfo = &_terminfo[0];
903 register int termlen;
904
905 if (termNinfo && *termNinfo) {
906 if (verbose)
907 (void) fprintf(trace, "setting TERMINFO=%s.\n",
908 termNinfo);
909 termlen = strlen(termNinfo);
910 if (termlen + 10 > termsize) {
911 termsize = termlen + 20;
912 terminfo = (char *) malloc(termsize * sizeof (char));
913 }
914 if (terminfo == (char *) NULL)
915 badmalloc();
916 (void) sprintf(terminfo, "TERMINFO=%s", termNinfo);
917 newenviron[0] = terminfo;
918 } else
919 newenviron[0] = (char *) 0;
920 environ = newenviron;
921 }
922
923 int
924 main(int argc, char **argv)
925 {
926 int i, c, firstoptind;
927 char *tempargv[2];
928 char *term = getenv("TERM");
1035 }
1036
1037 /* Check for enough names. */
1038 if ((use || diff || common) && (argc <= 1)) {
1039 (void) fprintf(stderr,
1040 "%s: must have at least two terminal names for a "
1041 "comparison to be done.\n", progname);
1042 goto usage;
1043 }
1044
1045 /* Set the default of diff -d or print -I */
1046 if (!use && (printing == pr_none) && !common && !neither) {
1047 if (argc == 0 || argc == 1) {
1048 if (argc == 0) {
1049 tempargv[0] = term;
1050 argc = 1;
1051 argv = tempargv;
1052 optind = 0;
1053 }
1054 pr_init(printing = pr_terminfo);
1055 } else
1056 diff++;
1057 }
1058
1059 /* Set the default sorting order. */
1060 if (sortorder == none)
1061 switch ((int) printing) {
1062 case (int) pr_cap:
1063 sortorder = by_cap; break;
1064 case (int) pr_longnames:
1065 sortorder = by_longnames; break;
1066 case (int) pr_terminfo:
1067 case (int) pr_none:
1068 sortorder = by_terminfo; break;
1069 }
1070
1071 firstterm = argv[optind++];
1072 firstoptind = optind;
1073
1074 allocvariables(argc, firstoptind);
1075 sortnames();
1076
1077 devnull = open("/dev/null", O_RDWR);
1078 local_setenv(term1info);
1079 initfirstterm(firstterm);
1080 local_setenv(term2info);
1081 for (i = 0; optind < argc; optind++, i++)
1082 check_nth_terminal(argv[optind], i);
1083
1084 if (use)
1085 dorelative(firstoptind, argc, argv);
1086
1087 return (0);
1088 }
|
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /* Copyright (c) 1988 AT&T */
23 /* All Rights Reserved */
24
25
26 /*
27 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
29 *
30 * Copyright (c) 2019, Joyent, Inc.
31 */
32
33 /*
34 NAME
35 infocmp - compare terminfo descriptions, or dump a terminfo
36 description
37
38 AUTHOR
39 Tony Hansen, February 23, 1984.
40 */
41
42 #include "curses.h"
43 #include "term.h"
44 #include "print.h"
45 #include <fcntl.h>
46 #include <stdlib.h>
47
48 /* externs from libcurses */
49 extern char *boolnames[];
50 extern char *boolcodes[];
51 extern char *boolfnames[];
52 extern char *numnames[];
168 ;
169
170 if (verbose) {
171 (void) fprintf(trace, "There are %d boolean capabilities.\n",
172 numbools);
173 (void) fprintf(trace, "There are %d numeric capabilities.\n",
174 numnums);
175 (void) fprintf(trace, "There are %d string capabilities.\n",
176 numstrs);
177 }
178
179 /* Allocate storage for the names and their values */
180 ibool = (struct boolstruct *) malloc((unsigned) numbools *
181 sizeof (struct boolstruct));
182 num = (struct numstruct *) malloc((unsigned) numnums *
183 sizeof (struct numstruct));
184 str = (struct strstruct *) malloc((unsigned) numstrs *
185 sizeof (struct strstruct));
186
187 /* Allocate array to keep track of which names have been used. */
188 if (use) {
189 used = (char *) malloc((unsigned) (argc - firstoptind) *
190 sizeof (char));
191 }
192
193 if ((ibool == NULL) || (num == NULL) || (str == NULL) ||
194 (use && (used == NULL)))
195 badmalloc();
196
197 /* Fill in the names and initialize the structures. */
198 nullseen = FALSE;
199 for (i = 0; i < numbools; i++) {
200 ibool[i].infoname = boolnames[i];
201 ibool[i].capname = boolcodes[i];
202 /* This is necessary until fnames.c is */
203 /* incorporated into standard curses. */
204 if (nullseen || (boolfnames[i] == NULL)) {
205 ibool[i].fullname = "unknown_boolean";
206 nullseen = TRUE;
207 } else {
208 ibool[i].fullname = boolfnames[i];
209 }
210 ibool[i].changed = FALSE;
211 ibool[i].seenagain = FALSE;
212 }
213 nullseen = 0;
214 for (i = 0; i < numnums; i++) {
215 num[i].infoname = numnames[i];
216 num[i].capname = numcodes[i];
217 if (nullseen || (numfnames[i] == NULL)) {
218 ibool[i].fullname = "unknown_number";
219 nullseen = TRUE;
220 } else {
221 num[i].fullname = numfnames[i];
222 }
223 num[i].changed = FALSE;
224 num[i].seenagain = FALSE;
225 }
226 nullseen = 0;
227 for (i = 0; i < numstrs; i++) {
228 str[i].infoname = strnames[i];
229 str[i].capname = strcodes[i];
230 if (nullseen || (strfnames[i] == NULL)) {
231 str[i].fullname = "unknown_string";
232 nullseen = TRUE;
233 } else {
234 str[i].fullname = strfnames[i];
235 }
236 str[i].changed = FALSE;
237 str[i].seenagain = FALSE;
238 }
239 }
240
241 /*
242 Routines to be passed to qsort(3) for comparison of the structures.
243 */
244 int
245 boolcompare(const void *x, const void *y)
246 {
247 struct boolstruct *a;
248 struct boolstruct *b;
249
250 a = (struct boolstruct *)x;
251 b = (struct boolstruct *)y;
252
253 switch ((int) sortorder) {
254 case (int) by_terminfo:
255 return (strcmp(a->infoname, b->infoname));
509 if (verbose)
510 (void) fprintf(trace, "looking at 'nl'\n");
511 retptr = cconvert(rmpadding(cursor_down, padbuffer, (int *) 0));
512 if (strcmp("\\n", retptr) != 0)
513 pr_string((char *)0, "nl", (char *)0, cursor_down);
514
515 /* Handle "ko" here: Termcap entries for other non-function keys */
516 pr_ko();
517
518 /* Ignore "ma": Arrow key map, used by vi version 2 only */
519 }
520
521 /*
522 Set up the first terminal and save the values from it.
523 */
524 void
525 initfirstterm(char *term)
526 {
527 register int i;
528
529 if (verbose) {
530 (void) fprintf(trace, "setting up terminal type '%s'.\n",
531 term);
532 }
533
534 (void) setupterm(term, devnull, (int *) 0);
535
536 /* Save the name for later use. */
537 if (use) {
538 register unsigned int length;
539 savettytype = _savettytype;
540 if ((length = strlen(ttytype)) >= TTYLEN) {
541 savettytype = malloc(length);
542 if (savettytype == NULL) {
543 (void) fprintf(stderr, "%s: malloc is out "
544 "of space\n", progname);
545 (void) strncpy(_savettytype, ttytype,
546 TTYLEN-1);
547 _savettytype[TTYLEN] = '\0';
548 savettytype = _savettytype;
549 }
550 } else {
551 (void) strcpy(_savettytype, ttytype);
552 }
553 }
554
555 if (printing != pr_none) {
556 pr_heading(term, ttytype);
557 pr_bheading();
558 }
559
560 /* Save the values for the first terminal. */
561 for (i = 0; i < numbools; i++) {
562 if ((ibool[i].val = tgetflag(ibool[i].capname)) &&
563 printing != pr_none) {
564 pr_boolean(ibool[i].infoname, ibool[i].capname,
565 ibool[i].fullname, 1);
566 }
567
568 if (verbose) {
569 (void) fprintf(trace, "%s=%d.\n", ibool[i].infoname,
570 ibool[i].val);
571 }
572 }
573
574 if (printing != pr_none) {
575 if (printing == pr_cap)
576 pr_bcaps();
577 pr_bfooting();
578 pr_nheading();
579 }
580
581 for (i = 0; i < numnums; i++) {
582 if (((num[i].val = tgetnum(num[i].capname)) > -1) &&
583 printing != pr_none) {
584 pr_number(num[i].infoname, num[i].capname,
585 num[i].fullname, num[i].val);
586 }
587
588 if (verbose) {
589 (void) fprintf(trace, "%s=%d.\n", num[i].infoname,
590 num[i].val);
591 }
592 }
593
594 if (printing != pr_none) {
595 if (printing == pr_cap)
596 pr_ncaps();
597 pr_nfooting();
598 pr_sheading();
599 }
600
601 for (i = 0; i < numstrs; i++) {
602 str[i].val = tgetstr(str[i].capname, (char **)0);
603 if ((str[i].val != NULL) && printing != pr_none) {
604 pr_string(str[i].infoname, str[i].capname,
605 str[i].fullname, str[i].val);
606 }
607
608 if (verbose) {
609 (void) fprintf(trace, "%s='", str[i].infoname);
610 PR(trace, str[i].val);
611 (void) fprintf(trace, "'.\n");
612 }
613 }
614
615 if (printing == pr_cap)
616 pr_scaps();
617
618 if (printing != pr_none)
619 pr_sfooting();
620 }
621
622 /*
623 Set up the n'th terminal.
624 */
625 static void
626 check_nth_terminal(char *nterm, int n)
627 {
628 register char boolval;
629 register short numval;
630 register char *strval;
631 register int i;
632
633 if (use)
634 used[n] = FALSE;
635
636 if (verbose) {
637 (void) fprintf(trace, "adding in terminal type '%s'.\n",
638 nterm);
639 }
640
641 (void) setupterm(nterm, devnull, (int *) 0);
642
643 if (printing != pr_none) {
644 pr_heading(nterm, ttytype);
645 pr_bheading();
646 }
647
648 if (diff || common || neither) {
649 if (Aflag && Bflag)
650 (void) printf("comparing %s (TERMINFO=%s) to %s "
651 "(TERMINFO=%s).\n",
652 firstterm, term1info, nterm, term2info);
653 else if (Aflag)
654 (void) printf("comparing %s (TERMINFO=%s) to %s.\n",
655 firstterm, term1info, nterm);
656 else if (Bflag)
657 (void) printf("comparing %s to %s (TERMINFO=%s).\n",
658 firstterm, nterm, term2info);
659 else
677 ** "found:\n");
678 ** (void) fprintf(trace, " %s: %s has %d, %s has"
679 ** " %d.\n",
680 ** ibool[i].capname, ibool[i].secondname,
681 ** ibool[i].secondval, nterm, boolval);
682 ** }
683 */
684 } else {
685 if (boolval == TRUE) {
686 ibool[i].seenagain = TRUE;
687 ibool[i].secondval = boolval;
688 ibool[i].secondname = nterm;
689 if (ibool[i].val != boolval)
690 ibool[i].changed = TRUE;
691 else
692 used[n] = TRUE;
693 }
694 }
695 }
696 if (boolval) {
697 if (printing != pr_none) {
698 pr_boolean(ibool[i].infoname, ibool[i].capname,
699 ibool[i].fullname, 1);
700 }
701
702 if (common && (ibool[i].val == boolval))
703 (void) printf("\t%s= T.\n", ibool[i].infoname);
704 } else if (neither && !ibool[i].val) {
705 (void) printf("\t!%s.\n", ibool[i].infoname);
706 }
707 if (diff && (ibool[i].val != boolval))
708 (void) printf("\t%s: %c:%c.\n", ibool[i].infoname,
709 ibool[i].val?'T':'F', boolval?'T':'F');
710 if (verbose) {
711 (void) fprintf(trace, "%s: %d:%d, changed=%d, "
712 "seen=%d.\n", ibool[i].infoname, ibool[i].val,
713 boolval, ibool[i].changed, ibool[i].seenagain);
714 }
715 }
716
717 if (printing != pr_none) {
718 if (printing == pr_cap)
719 pr_bcaps();
720 pr_bfooting();
721 pr_nheading();
722 }
723
724 if (diff || common || neither)
725 (void) printf(" comparing numbers.\n");
726
727 for (i = 0; i < numnums; i++) {
728 numval = tgetnum(num[i].capname);
729 if (use) {
730 if (num[i].seenagain) {
731 if ((numval > -1) &&
732 (numval != num[i].secondval)) {
733 (void) fprintf(stderr,
734 "%s: use = order dependency "
735 "found:\n", progname);
736 (void) fprintf(stderr, " %s: %s "
737 "has %d, %s has %d.\n",
738 num[i].capname, num[i].secondname,
739 num[i].secondval, nterm, numval);
740 }
741 } else {
742 if (numval > -1) {
743 num[i].seenagain = TRUE;
744 num[i].secondval = numval;
745 num[i].secondname = nterm;
746 if ((numval > -1) &&
747 (num[i].val != numval))
748 num[i].changed = TRUE;
749 else
750 used[n] = TRUE;
751 }
752 }
753 }
754 if (numval > -1) {
755 if (printing != pr_none) {
756 pr_number(num[i].infoname, num[i].capname,
757 num[i].fullname, numval);
758 }
759
760 if (common && (num[i].val == numval)) {
761 (void) printf("\t%s= %d.\n", num[i].infoname,
762 numval);
763 }
764
765 } else if (neither && (num[i].val == -1)) {
766 (void) printf("\t!%s.\n", num[i].infoname);
767 }
768
769 if (diff && (num[i].val != numval)) {
770 (void) printf("\t%s: %d:%d.\n",
771 num[i].infoname, num[i].val, numval);
772 }
773
774 if (verbose) {
775 (void) fprintf(trace, "%s: %d:%d, "
776 "changed = %d, seen = %d.\n",
777 num[i].infoname, num[i].val, numval,
778 num[i].changed, num[i].seenagain);
779 }
780 }
781
782 if (printing != pr_none) {
783 if (printing == pr_cap)
784 pr_ncaps();
785 pr_nfooting();
786 pr_sheading();
787 }
788
789 if (diff || common || neither)
790 (void) printf(" comparing strings.\n");
791
792 for (i = 0; i < numstrs; i++) {
793 strval = tgetstr(str[i].capname, (char **)0);
794 if (use) {
795 if (str[i].seenagain && (strval != NULL)) {
796 if (!EQUAL(strval, str[i].secondval)) {
797 (void) fprintf(stderr,
798 "use= order dependency"
799 " found:\n");
800 (void) fprintf(stderr,
802 str[i].capname, str[i].secondname);
803 PR(stderr, str[i].secondval);
804 (void) fprintf(stderr,
805 "', %s has '", nterm);
806 PR(stderr, strval);
807 (void) fprintf(stderr, "'.\n");
808 }
809 } else {
810 if (strval != NULL) {
811 str[i].seenagain = TRUE;
812 str[i].secondval = strval;
813 str[i].secondname = nterm;
814 if (!EQUAL(str[i].val, strval))
815 str[i].changed = TRUE;
816 else
817 used[n] = TRUE;
818 }
819 }
820 }
821 if (strval != NULL) {
822 if (printing != pr_none) {
823 pr_string(str[i].infoname, str[i].capname,
824 str[i].fullname, strval);
825 }
826
827 if (common && EQUAL(str[i].val, strval)) {
828 (void) printf("\t%s= '", str[i].infoname);
829 PR(stdout, strval);
830 (void) printf("'.\n");
831 }
832 } else if (neither && (str[i].val == NULL))
833 (void) printf("\t!%s.\n", str[i].infoname);
834 if (diff && !EQUAL(str[i].val, strval)) {
835 (void) printf("\t%s: '", str[i].infoname);
836 PR(stdout, str[i].val);
837 (void) printf("','");
838 PR(stdout, strval);
839 (void) printf("'.\n");
840 }
841 if (verbose) {
842 (void) fprintf(trace, "%s: '", str[i].infoname);
843 PR(trace, str[i].val);
844 (void) fprintf(trace, "':'");
845 PR(trace, strval);
846 (void) fprintf(trace, "',changed=%d,seen=%d.\n",
861 A capability gets an at-sign if it no longer exists, but
862 one of the relative entries contains a value for it.
863 It gets printed if the original value is not seen in ANY
864 of the relative entries, or if the FIRST relative entry that has
865 the capability gives a DIFFERENT value for the capability.
866 */
867 void
868 dorelative(int firstoptind, int argc, char **argv)
869 {
870 register int i;
871
872 /* turn off printing of termcap and long names */
873 pr_init(pr_terminfo);
874
875 /* print out the entry name */
876 pr_heading((char *)0, savettytype);
877
878 pr_bheading();
879
880 /* Print out all bools that are different. */
881 for (i = 0; i < numbools; i++) {
882 if (!ibool[i].val && ibool[i].changed) {
883 pr_boolean(ibool[i].infoname, (char *)0,
884 (char *)0, -1);
885 } else if (ibool[i].val && (ibool[i].changed ||
886 !ibool[i].seenagain)) {
887 pr_boolean(ibool[i].infoname, (char *)0, (char *)0, 1);
888 }
889 }
890
891 pr_bfooting();
892 pr_nheading();
893
894 /* Print out all nums that are different. */
895 for (i = 0; i < numnums; i++) {
896 if (num[i].val < 0 && num[i].changed) {
897 pr_number(num[i].infoname, (char *)0, (char *)0, -1);
898 } else if (num[i].val >= 0 && (num[i].changed ||
899 !num[i].seenagain)) {
900 pr_number(num[i].infoname, (char *)0,
901 (char *)0, num[i].val);
902 }
903 }
904
905 pr_nfooting();
906 pr_sheading();
907
908 /* Print out all strs that are different. */
909 for (i = 0; i < numstrs; i++) {
910 if (str[i].val == NULL && str[i].changed) {
911 pr_string(str[i].infoname, (char *)0, (char *)0,
912 (char *)0);
913 } else if ((str[i].val != NULL) &&
914 (str[i].changed || !str[i].seenagain)) {
915 pr_string(str[i].infoname,
916 (char *)0, (char *)0, str[i].val);
917 }
918 }
919
920 pr_sfooting();
921
922 /* Finish it up. */
923 for (i = firstoptind; i < argc; i++) {
924 if (used[i - firstoptind]) {
925 (void) printf("\tuse=%s,\n", argv[i]);
926 } else {
927 (void) fprintf(stderr,
928 "%s: 'use=%s' did not add anything to the "
929 "description.\n", progname, argv[i]);
930 }
931 }
932 }
933
934 void
935 local_setenv(char *termNinfo)
936 {
937 extern char **environ;
938 static char *newenviron[2] = { 0, 0 };
939 static unsigned int termsize = BUFSIZ;
940 static char _terminfo[BUFSIZ];
941 static char *terminfo = &_terminfo[0];
942 register int termlen;
943
944 if (termNinfo && *termNinfo) {
945 if (verbose) {
946 (void) fprintf(trace, "setting TERMINFO=%s.\n",
947 termNinfo);
948 }
949
950 termlen = strlen(termNinfo);
951 if (termlen + 10 > termsize) {
952 termsize = termlen + 20;
953 terminfo = (char *) malloc(termsize * sizeof (char));
954 }
955 if (terminfo == (char *) NULL)
956 badmalloc();
957 (void) sprintf(terminfo, "TERMINFO=%s", termNinfo);
958 newenviron[0] = terminfo;
959 } else
960 newenviron[0] = (char *) 0;
961 environ = newenviron;
962 }
963
964 int
965 main(int argc, char **argv)
966 {
967 int i, c, firstoptind;
968 char *tempargv[2];
969 char *term = getenv("TERM");
1076 }
1077
1078 /* Check for enough names. */
1079 if ((use || diff || common) && (argc <= 1)) {
1080 (void) fprintf(stderr,
1081 "%s: must have at least two terminal names for a "
1082 "comparison to be done.\n", progname);
1083 goto usage;
1084 }
1085
1086 /* Set the default of diff -d or print -I */
1087 if (!use && (printing == pr_none) && !common && !neither) {
1088 if (argc == 0 || argc == 1) {
1089 if (argc == 0) {
1090 tempargv[0] = term;
1091 argc = 1;
1092 argv = tempargv;
1093 optind = 0;
1094 }
1095 pr_init(printing = pr_terminfo);
1096 } else {
1097 diff++;
1098 }
1099 }
1100
1101 /* Set the default sorting order. */
1102 if (sortorder == none) {
1103 switch ((int) printing) {
1104 case (int) pr_cap:
1105 sortorder = by_cap; break;
1106 case (int) pr_longnames:
1107 sortorder = by_longnames; break;
1108 case (int) pr_terminfo:
1109 case (int) pr_none:
1110 sortorder = by_terminfo; break;
1111 }
1112 }
1113
1114 firstterm = argv[optind++];
1115 firstoptind = optind;
1116
1117 allocvariables(argc, firstoptind);
1118 sortnames();
1119
1120 devnull = open("/dev/null", O_RDWR);
1121 local_setenv(term1info);
1122 initfirstterm(firstterm);
1123 local_setenv(term2info);
1124 for (i = 0; optind < argc; optind++, i++)
1125 check_nth_terminal(argv[optind], i);
1126
1127 if (use)
1128 dorelative(firstoptind, argc, argv);
1129
1130 return (0);
1131 }
|