xref: /original-bsd/usr.bin/pascal/libpc/CTTOT.c (revision c3e32dec)
1 /*-
2  * Copyright (c) 1979, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)CTTOT.c	8.1 (Berkeley) 06/06/93";
10 #endif /* not lint */
11 
12 #include "whoami.h"
13 #include "h00vars.h"
14 
15 long	_mask[] = {
16 #		ifdef DEC11
17 		    0xffffffff , 0xfffffffe , 0xfffffffc , 0xfffffff8 ,
18 		    0xfffffff0 , 0xffffffe0 , 0xffffffc0 , 0xffffff80 ,
19 		    0xffffff00 , 0xfffffe00 , 0xfffffc00 , 0xfffff800 ,
20 		    0xfffff000 , 0xffffe000 , 0xffffc000 , 0xffff8000 ,
21 		    0xffff0000 , 0xfffe0000 , 0xfffc0000 , 0xfff80000 ,
22 		    0xfff00000 , 0xffe00000 , 0xffc00000 , 0xff800000 ,
23 		    0xff000000 , 0xfe000000 , 0xfc000000 , 0xf8000000 ,
24 		    0xf0000000 , 0xe0000000 , 0xc0000000 , 0x80000000 ,
25 		    0x00000000
26 #		else
27 		    0xffffffff , 0xfeffffff , 0xfcffffff , 0xf8ffffff ,
28 		    0xf0ffffff , 0xe0ffffff , 0xc0ffffff , 0x80ffffff ,
29 		    0x00ffffff , 0x00feffff , 0x00fcffff , 0x00f8ffff ,
30 		    0x00f0ffff , 0x00e0ffff , 0x00c0ffff , 0x0080ffff ,
31 		    0x0000ffff , 0x0000feff , 0x0000fcff , 0x0000f8ff ,
32 		    0x0000f0ff , 0x0000e0ff , 0x0000c0ff , 0x000080ff ,
33 		    0x000000ff , 0x000000fe , 0x000000fc , 0x000000f8 ,
34 		    0x000000f0 , 0x000000e0 , 0x000000c0 , 0x00000080 ,
35 		    0x00000000
36 #		endif DEC11
37 	    };
38 /*
39  * Constant set constructors.
40  *
41  * CTTOT is called from compiled Pascal.  It takes the list of ranges
42  * and single elements on the stack, varargs style.
43  *
44  * CTTOTA is called from the px interpreter.  It takes a pointer to the
45  * list of ranges and single elements.
46  *
47  * This was easier than changing the compiler to pass a pointer into
48  * its own partially-constructed stack, while working to make px portable.
49  */
50 
51 long *CTTOTA();
52 
53 long *
54 CTTOT(result, lwrbnd, uprbnd, paircnt, singcnt, data)
55 
56 	long	*result;	/* pointer to final set */
57 	long	lwrbnd;		/* lower bound of set */
58 	long	uprbnd;		/* upper - lower of set */
59 	long	paircnt;	/* number of pairs to construct */
60 	long	singcnt;	/* number of singles to construct */
61 	long	data;		/* paircnt plus singcnt sets of data */
62 {
63 	return CTTOTA(result, lwrbnd, uprbnd, paircnt, singcnt, &data);
64 }
65 
66 long *
67 CTTOTA(result, lwrbnd, uprbnd, paircnt, singcnt, dataptr)
68 
69 	register long	*result;	/* pointer to final set */
70 	long	lwrbnd;			/* lower bound of set */
71 	long	uprbnd;			/* upper - lower of set */
72 	long	paircnt;		/* number of pairs to construct */
73 	long	singcnt;		/* number of singles to construct */
74 	register long	*dataptr;	/* ->paircnt plus singcnt data values */
75 {
76 	int		lowerbnd = lwrbnd;
77 	int		upperbnd = uprbnd;
78 	register long	*lp;
79 	register char	*cp;
80 	register long	temp;
81 	long		*limit;
82 	int		lower;
83 	int		lowerdiv;
84 	int		lowermod;
85 	int		upper;
86 	int		upperdiv;
87 	int		uppermod;
88 	int		cnt;
89 
90 	limit = &result[(upperbnd + 1 + BITSPERLONG - 1) >> LG2BITSLONG];
91 	for (lp = result; lp < limit; )
92 		*lp++ = 0;
93 	for (cnt = 0; cnt < paircnt; cnt++) {
94 		upper = *dataptr++ - lowerbnd;
95 		if (upper < 0 || upper > upperbnd) {
96 			ERROR("Range upper bound of %D out of set bounds\n",
97 				*--dataptr);
98 		}
99 		lower = *dataptr++ - lowerbnd;
100 		if (lower < 0 || lower > upperbnd) {
101 			ERROR("Range lower bound of %D out of set bounds\n",
102 				*--dataptr);
103 		}
104 		if (lower > upper) {
105 			continue;
106 		}
107 		lowerdiv = lower >> LG2BITSLONG;
108 		lowermod = lower & MSKBITSLONG;
109 		upperdiv = upper >> LG2BITSLONG;
110 		uppermod = upper & MSKBITSLONG;
111 		temp = _mask [lowermod];
112 		if ( lowerdiv == upperdiv ) {
113 			temp &= ~_mask[ uppermod + 1 ];
114 		}
115 		result[ lowerdiv ] |= temp;
116 		limit = &result[ upperdiv-1 ];
117 		for ( lp = &result[ lowerdiv+1 ] ; lp <= limit ; lp++ ) {
118 			*lp |= ~0;
119 		}
120 		if ( lowerdiv != upperdiv ) {
121 			result[ upperdiv ] |= ~_mask[ uppermod + 1 ];
122 		}
123 	}
124 	for (cnt = 0, cp = (char *)result; cnt < singcnt; cnt++) {
125 		lower = *dataptr++ - lowerbnd;
126 		if (lower < 0 || lower > upperbnd) {
127 			ERROR("Value of %D out of set bounds\n", *--dataptr);
128 		}
129 		cp[ lower >> LG2BITSBYTE ] |= (1 << (lower & MSKBITSBYTE));
130 	}
131 	return(result);
132 }
133