allbery@ncoast.UUCP (06/15/87)
This has appeared on mod.sources, and is thus available from the archive sites. However, since it is very small, I'd like to see it posted in .misc so people can get up to speed with PD cron without waiting for it. [Done. ++bsa] #! /bin/sh ## This is a shell archive. Remove anything before this line, then unpack ## it by saving it into a file and typing "sh file". To overwrite existing ## files, type "sh file -c". You can also feed this as standard input via ## unshar, or by typing "sh <file". If this archive is complete, you will ## see the following message at the end: # "End of archive 1 (of 1)." # Contents: MANIFEST Makefile bitstring.3 bitstring.h test.c # Wrapped by paul@vixie on Sun Jun 14 17:54:03 1987 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f MANIFEST -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"MANIFEST\" else echo shar: Extracting \"MANIFEST\" \(246 characters\) sed "s/^X//" >MANIFEST <<'END_OF_MANIFEST' X File Name Archive # Description X----------------------------------------------------------- X MANIFEST 1 X Makefile 1 X bitstring.3 1 X bitstring.h 1 X test.c 1 END_OF_MANIFEST if test 246 -ne `wc -c <MANIFEST`; then echo shar: \"MANIFEST\" unpacked with wrong size! fi # end of overwriting check fi if test -f Makefile -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"Makefile\" else echo shar: Extracting \"Makefile\" \(784 characters\) sed "s/^X//" >Makefile <<'END_OF_Makefile' X# Makefile for bitstring macros X# vix 26feb87 [written] X# vix 25mar87 [added test program] X# X X# INCDIR might be /usr/local/include or /usr/include/local or some X# variant, but your cc(1) may not be looking there. If you put it X# somewhere your cc(1) doesn't usually look for include files, you X# will have to compile things with -I or this one won't be found. X XINCDIR=/usr/include X X# MANEXT and MANDIR will vary from system to system, but usually on X# a BSD you put the man page for foobar in /usr/man/manl/foobar.l. X# On SysV, start looking in /usr/catman, and after that, you're on X# your own. X XMANEXT=l XMANDIR=/usr/man/man$(MANEXT) X Xall : bitstring.3 bitstring.h X cp bitstring.3 $(MANDIR)/bitstring.$(MANEXT) X cp bitstring.h $(INCDIR) X Xtest : test.c X cc -O -o test test.c END_OF_Makefile if test 784 -ne `wc -c <Makefile`; then echo shar: \"Makefile\" unpacked with wrong size! fi # end of overwriting check fi if test -f bitstring.3 -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"bitstring.3\" else echo shar: Extracting \"bitstring.3\" \(2223 characters\) sed "s/^X//" >bitstring.3 <<'END_OF_bitstring.3' X.TH BITSTRING 3 "26 March 1987" X.UC 4 X.SH NAME Xbit_decl, bit_ref, bit_test, bit_set, bit_clear, Xbit_setall, bit_clearall \- bit-string manipulation macros for C X.SH SYNOPSIS X.nf X.B #include <bitstring.h> X.PP X.B bit_decl(Name, Nbits) X.PP X.B bit_ref(Name) X.PP X.B bit_test(Name, BitNum) X.PP X.B bit_set(Name, BitNum) X.PP X.B bit_clear(Name, BitNum) X.PP X.B bit_setall(Name, Nbits) X.PP X.B bit_clearall(Name, Nbits) X.PP X.fi X.SH DESCRIPTION XThese functions operate on strings of bits. These strings are held in Xinteger arrays, but this detail is transparent in actual use. X.PP X.I Bit_decl Xdeclares a bit string called X.I Name Xas a C variable able to contain X.I Nbits Xbits. This is suitable for actually creating the variable. X.I Bit_ref Xcreates a reference to a bit-string called X.IR Name ; Xthis is suitable for declaring an external variable, or receiving a Xbit string as a function argument. X.PP X.I Bit_test Xis an expression that examines bit X.I BitNum X(numbered from 0) of string X.IR Name , Xevaluating to a non-zero if the bit is set, zero otherwise. X.PP X.I Bit_set Xand X.I bit_clear Xrespectively set and clear bit X.I BitNum X(numbered from 0, as above) in string X.IR Name . X.PP X.I Bit_setall Xand X.I bit_clearall Xrespectively set and clear all bits from 0 through X.I Nbits X(which must the actual length) of string X.IR Name . X.SH AUTHOR X.nf XPaul A. Vixie, Esq. Xucbvax!dual!ptsfa!vixie!paul Xpaul@vixie.UUCP X.fi X.SH EXAMPLE X.nf X#include <bitstring.h> X.PP Xmain() X{ X bit_decl(foobits, 300) X.PP X . . . X barfunc(foobits); X . . . X} X.PP Xbarfunc(bits) X bit_ref(bits) X{ X if (bit_test(bits, 25)) { X bit_clearall(300) X bit_set(bits, 26) X } X} X.PP X.fi X(note: semicolons were not omitted accidentally, above: the macros that Xgenerate declarations or statements have their own semicolons.) X.SH BUGS XGiven the level of abstraction, it is possible to store the length of the Xstring internally, making it possible to do run-time checking on X.IR bit_test , X.IR bit_set , Xand X.IR bit_clear , Xand making it unneccessary to pass the string length to X.I bit_setall Xand X.IR bit_clearall . XThis should be done as a compile-time option, determined by the value Xof some macro at the point where <bitstring.h> is included. END_OF_bitstring.3 if test 2223 -ne `wc -c <bitstring.3`; then echo shar: \"bitstring.3\" unpacked with wrong size! fi # end of overwriting check fi if test -f bitstring.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"bitstring.h\" else echo shar: Extracting \"bitstring.h\" \(2652 characters\) sed "s/^X//" >bitstring.h <<'END_OF_bitstring.h' X/* bitstring.h - bit string manipulation macros X * vix 26feb87 [written] X * vix 03mar87 [fixed stupid bug in setall/clearall] X * vix 25mar87 [last-minute cleanup before mod.sources gets it] X */ X X#ifndef _bitstring_defined X#define _bitstring_defined X X/* X * there is something like this in 4.3, but that's licensed source code that X * I'd rather not depend on, so I'll reinvent the wheel (incompatibly). X */ X X/* X * except for the number of bits per int, and the other constants, this should X * port painlessly just about anywhere. please #ifdef any changes with your X * compiler-induced constants (check the CC man page, it'll be something like X * 'vax' or 'mc68000' or 'sun' or some such). also please mail any changes X * back to me (ucbvax!dual!ptsfa!vixie!paul) for inclusion in future releases. X */ X X/* X * (constants used internally -- these can change from machine to machine) X */ X /* X * how many bits in the unit returned by sizeof ? X */ X#define _bit_charsize 8 X X /* X * what type will the bitstring be an array of ? X */ X#define _bit_type unsigned int X X /* X * how many bits in an int ? X */ X#define _bit_intsiz (sizeof(_bit_type) * _bit_charsize) X X /* X * an int of all '0' bits X */ X#define _bit_0s ((_bit_type)0) X X /* X * an int of all '1' bits X */ X#define _bit_1s ((_bit_type)~0) X X/* X * (macros used internally) X */ X /* X * how many int's in a string of N bits? X */ X#define _bit_size(N) \ X ((N / _bit_intsiz) + ((N % _bit_intsiz) ? 1 : 0)) X X /* X * which int of the string is bit N in? X */ X#define _bit_intn(N) \ X ((N) / _bit_intsiz) X X /* X * mask for bit N in it's int X */ X#define _bit_mask(N) \ X (1 << ((N) % _bit_intsiz)) X X/* X * (macros used externally) X */ X /* X * declare (create) Name as a string of N bits X */ X#define bit_decl(Name, N) \ X _bit_type Name[_bit_size(N)]; X X /* X * declare (reference) Name as a bit string X */ X#define bit_ref(Name) \ X _bit_type Name[]; X X /* X * is bit N of string Name set? X */ X#define bit_test(Name, N) \ X ((Name)[_bit_intn(N)] & _bit_mask(N)) X X /* X * set bit N of string Name X */ X#define bit_set(Name, N) \ X { (Name)[_bit_intn(N)] |= _bit_mask(N); } X X /* X * clear bit N of string Name X */ X#define bit_clear(Name, N) \ X { (Name)[_bit_intn(N)] &= ~_bit_mask(N); } X X /* X * set bits 0..N in string Name X */ X#define bit_setall(Name, N) \ X { register _bit_i; \ X for (_bit_i = _bit_size(N)-1; _bit_i >= 0; _bit_i--) \ X Name[_bit_i]=_bit_1s; \ X } X X /* X * clear bits 0..N in string Name X */ X#define bit_clearall(Name, N) \ X { register _bit_i; \ X for (_bit_i = _bit_size(N)-1; _bit_i >= 0; _bit_i--) \ X Name[_bit_i]=_bit_0s; \ X } X X#endif _bitstring_defined END_OF_bitstring.h if test 2652 -ne `wc -c <bitstring.h`; then echo shar: \"bitstring.h\" unpacked with wrong size! fi # end of overwriting check fi if test -f test.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"test.c\" else echo shar: Extracting \"test.c\" \(756 characters\) sed "s/^X//" >test.c <<'END_OF_test.c' X/* test.c - a test jig for bitstring X * vix 25mar87 [all test programs are messy] X */ X X#include <stdio.h> X#include "bitstring.h" X X#define SIZE 50 X Xmain() X{ X char t[10]; X bit_decl(string, SIZE) X X while (test(string)) X ; X} X Xstatic test(s) X bit_ref(s) X{ X int i; X char t[10], cmd; X X for (i = 0; i < SIZE; i++) X putchar(bit_test(s, i) ? '1' : '0'); X putchar('\n'); X X printf("set, clear, Setall, Clearall: "); fflush(stdout); X gets(t); if (!t[0]) return 0; else cmd=t[0]; X if (cmd=='s' || cmd=='c') X { printf("\t#"); fflush(stdout); gets(t); i=atoi(t); } X X switch (cmd) X { X case 's': bit_set(s, i); break; X case 'c': bit_clear(s, i); break; X case 'S': bit_setall(s, SIZE); break; X case 'C': bit_clearall(s, SIZE); break; X default: return 0; X } X return 1; X} END_OF_test.c if test 756 -ne `wc -c <test.c`; then echo shar: \"test.c\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of archive 1 \(of 1\). cp /dev/null ark1isdone MISSING="" for I in 1 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 1 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0