xref: /original-bsd/usr.bin/pascal/libpc/CTTOT.c (revision c577960b)
1 /* Copyright (c) 1979 Regents of the University of California */
2 
3 static char sccsid[] = "@(#)CTTOT.c 1.4 06/10/81";
4 
5 #include "whoami.h"
6 #include "h00vars.h"
7 
8 long	_mask[] = {
9 #		ifdef DEC11
10 		    0xffffffff , 0xfffffffe , 0xfffffffc , 0xfffffff8 ,
11 		    0xfffffff0 , 0xffffffe0 , 0xffffffc0 , 0xffffff80 ,
12 		    0xffffff00 , 0xfffffe00 , 0xfffffc00 , 0xfffff800 ,
13 		    0xfffff000 , 0xffffe000 , 0xffffc000 , 0xffff8000 ,
14 		    0xffff0000 , 0xfffe0000 , 0xfffc0000 , 0xfff80000 ,
15 		    0xfff00000 , 0xffe00000 , 0xffc00000 , 0xff800000 ,
16 		    0xff000000 , 0xfe000000 , 0xfc000000 , 0xf8000000 ,
17 		    0xf0000000 , 0xe0000000 , 0xc0000000 , 0x80000000 ,
18 		    0x00000000
19 #		else
20 		    0xffffffff , 0xfeffffff , 0xfcffffff , 0xf8ffffff ,
21 		    0xf0ffffff , 0xe0ffffff , 0xc0ffffff , 0x80ffffff ,
22 		    0x00ffffff , 0x00feffff , 0x00fcffff , 0x00f8ffff ,
23 		    0x00f0ffff , 0x00e0ffff , 0x00c0ffff , 0x0080ffff ,
24 		    0x0000ffff , 0x0000feff , 0x0000fcff , 0x0000f8ff ,
25 		    0x0000f0ff , 0x0000e0ff , 0x0000c0ff , 0x000080ff ,
26 		    0x000000ff , 0x000000fe , 0x000000fc , 0x000000f8 ,
27 		    0x000000f0 , 0x000000e0 , 0x000000c0 , 0x00000080 ,
28 		    0x00000000
29 #		endif DEC11
30 	    };
31 /*
32  * Constant set constructor
33  */
34 
35 long *
36 CTTOT(result0, lwrbnd, uprbnd, paircnt, singcnt, data)
37 
38 	long	*result0;	/* pointer to final set */
39 	long	lwrbnd;		/* lower bound of set */
40 	long	uprbnd;		/* upper - lower of set */
41 	long	paircnt;	/* number of pairs to construct */
42 	long	singcnt;	/* number of singles to construct */
43 	long	data;		/* paircnt plus singcnt sets of data */
44 {
45 	register long	*result = result0;
46 	register long	*dataptr = &data;
47 	int		lowerbnd = lwrbnd;
48 	int		upperbnd = uprbnd;
49 	register long	*lp;
50 	register char	*cp;
51 	register long	temp;
52 	long		*limit;
53 	int		lower;
54 	int		lowerdiv;
55 	int		lowermod;
56 	int		upper;
57 	int		upperdiv;
58 	int		uppermod;
59 	int		cnt;
60 
61 	limit = &result[(upperbnd + 1 + BITSPERLONG - 1) >> LG2BITSLONG];
62 	for (lp = result; lp < limit; )
63 		*lp++ = 0;
64 	for (cnt = 0; cnt < paircnt; cnt++) {
65 		upper = *dataptr++ - lowerbnd;
66 		if (upper < 0 || upper > upperbnd) {
67 			ERROR("Range upper bound of %D out of set bounds\n",
68 				*--dataptr);
69 			return;
70 		}
71 		lower = *dataptr++ - lowerbnd;
72 		if (lower < 0 || lower > upperbnd) {
73 			ERROR("Range lower bound of %D out of set bounds\n",
74 				*--dataptr);
75 			return;
76 		}
77 		if (lower > upper) {
78 			continue;
79 		}
80 		lowerdiv = lower >> LG2BITSLONG;
81 		lowermod = lower & MSKBITSLONG;
82 		upperdiv = upper >> LG2BITSLONG;
83 		uppermod = upper & MSKBITSLONG;
84 		temp = _mask [lowermod];
85 		if ( lowerdiv == upperdiv ) {
86 			temp &= ~_mask[ uppermod + 1 ];
87 		}
88 		result[ lowerdiv ] |= temp;
89 		limit = &result[ upperdiv-1 ];
90 		for ( lp = &result[ lowerdiv+1 ] ; lp <= limit ; lp++ ) {
91 			*lp |= ~0;
92 		}
93 		if ( lowerdiv != upperdiv ) {
94 			result[ upperdiv ] |= ~_mask[ uppermod + 1 ];
95 		}
96 	}
97 	for (cnt = 0, cp = (char *)result; cnt < singcnt; cnt++) {
98 		lower = *dataptr++ - lowerbnd;
99 		if (lower < 0 || lower > upperbnd) {
100 			ERROR("Value of %D out of set bounds\n", *--dataptr);
101 			return;
102 		}
103 		cp[ lower >> LG2BITSBYTE ] |= (1 << (lower & MSKBITSBYTE));
104 	}
105 	return(result);
106 }
107