SRI-NOSC/ncpd/util.c
#
/* util.c */
/* globals declared in thsi file:
queue
functions declared in this file:
q_enter
q_dlink
set_bit
reset_bit
bit_on
find_bit
*/
/* SCCS PROGRAM IDENTIFICATION STRING */
char id_util[] "~|^`util.c\tV3.9E0\tJan78\n";
struct queue /* defines q link as a structure for the queue
manipulation procedures */
{
struct queue *q_link;
};
/*name:
q_enter
function:
enters an element in a queue.
algorithm:
if the queue isempty (q head = 0), point the element at itself
and point the q head at it.
otherwise,
point the element at the current 1st element.
point the current last element at the element.
point the q head at the element, which thus becomes the
new last element.
parameters:
qha the address of the q head.
elemp the address of the element to be put at the end of
the q.
returns:
nothing.
globals:
host= (for error message)
calls:
nothing.
called by:
qup_pro
history:
initial coding 12/11/74 by G. R. Grossman.
modified 31Aug77 by J.S.Kravitz to complain if zero
passed as element address.
*/
q_enter(qha,elemp)
struct queue **qha,
*elemp;
{
extern int host; /* JSK 31Aug77 */
if (!elemp)
{
log_bin ("Qenter (x,0)", &host, 1);
return;
}
if ( *qha == 0 ) /* is q empty? */
*qha = elemp->q_link = elemp; /* point element at itself
and q head at element */
else /* q wasn't empty */
{
elemp->q_link = qha->q_link->q_link; /* point element at
current 1st
element */
qha->q_link =
qha->q_link->q_link =
elemp; /* point last element at
new element, q head at
new element, which thus
becomes new last element */
}
}
/*name:
q_dlink
function:
delinks the 1st entry in a queue and returns a pointer to it.
returns zero if the q was empty.
algorithm:
if the queue is non-empty (q head != 0):
set result to address of current 1st element.
delink current 1st element.
if this reveals that it was the only element:
zero the q head.
otherwise set result to zero.
return result.
parameters:
qha the address of the q head from which the 1st element
is to be delinked.
returns:
address of the former 1st element of the q, if q was non-empty.
otherwise (q was empty) returns zero.
globals:
none.
calls:
nothing.
called by:
ir_rfnm
pb_flush
history:
initial coding 12/12/74 by G. R. Grossman.
*/
struct queue *q_dlink(qha)
struct queue **qha;
{
register struct queue **qhp, /* will hold qha for
efficiency */
*result; /* holds result temporarily */
qhp = qha;
if ( qhp->q_link != 0 ) /* is q non-empty? */
{
result = qhp->q_link->q_link; /* 1st element in q is pointed
to by last element which
is pointed to by head */
if ( (qhp->q_link->q_link = qhp->q_link->q_link->q_link)
== result ) /* is the new 1st element the same
as the old one? */
qhp->q_link = 0; /* mark q empty if so */
return ( result ); /* return pointer to former
1st element */
} /* end q was not empty */
else
return(0); /* signifies q was empty */
}
/*name:
set_bit
function:
sets a bit in a bit map.
algorithm:
the bit map is considered to be an array of bytes each of which
contains 8 bits numbered from the low-order bit. the byte is
selected by taking the bit number / 8; the correct bit is set
by or'ing the byte with 1 shifted left (bit number mod 8).
parameters:
map_addr the address of the char[] containing the bit map.
bit_num number of the bit to be set.
returns:
nothing.
globals:
none.
calls:
nothing.
called by:
asn_lnkn
send_pro
history:
initial coding 12/12/74 by G. R. Grossman.
*/
set_bit(map_addr,bit_num)
char *map_addr;
int bit_num;
{
map_addr[bit_num>>3] =| (1 << (bit_num & 07));
}
/*name:
reset_bit
function:
reset a bit in a bit_map.
algorithm:
same as set_bit except that instead of or, the logical function
is "and not".
parameters:
same as set_bit.
returns:
nothing.
globals:
none.
calls:
nothing.
called by:
ir_rfnm
ir_re_x
history:
initial coding 12/12/74 by G. R. Grossman.
*/
reset_bit(map_addr,bit_num)
char *map_addr;
int bit_num;
{
map_addr[bit_num>>3] =& ~(1 << (bit_num & 07));
}
/*name:
bit_on
function:
tests a bit in a bit map.
algorithm:
same as set_bit, but logical function is and and the result is
returned.
parameters:
same as set_bit.
returns:
zero if the bit is off.
a one in the bit position of the byte if the bit is on.
globals:
none.
calls:
nothing.
called by:
send_pro
history:
initial coding 12/12/74 by G. R. Grossman.
*/
int bit_on(map_addr,bit_num)
char *map_addr;
int bit_num;
{
return( map_addr[bit_num>>3] & (1 << (bit_num & 07)) );
}
/*name:
find_bit
function:
finds the 1st "one" bit in a bit mapfrom a given starting point.
algorithm:
if start < map_size:
take map_size /8 (now in bytes)
set i to start / 8
set n to start mod 8
set m 1*(2**n) {mask for testing bits}
go to commence
outer loop:
increment i and fall out if >= map_size.
if map_addr[i] !=0:
set m to 1
commence: loop on n from 0 to 7:
if bit n of byte i is set:
return bit number
otherwise:
shift m left 1 for next test
if start was >= map_size or fell out of search loop, return -1.
parameters:
map_addr address of the char[] containing the bit map.
map_size size of map in bits (should be multiple of 8).
start bit number at which to start search (1st bit in
map is numbered 0).
returns:
if the search is successful, the number of the 1st set bit whose
number is >= start.
otherwise, -1.
globals:
none.
calls:
nothing.
called by:
asn_sktn
asn_lnkn
history:
initial coding 12/12/74 by G. R. Grossman.
*/
int find_bit(map_addr,map_size,start)
char *map_addr;
int map_size,
start;
{
register int i, /* will hold byte number in map */
m, /* will hold testing mask */
n; /* will hold bit number in byte */
if ( start < map_size ) /* start within map? */
{
map_size =>> 3; /* size now in bytes */
i = start >> 3; /* starting byte */
n = start & 07; /* starting bit */
m = 1 << n; /* starting test mask */
goto commence; /* enter loop in appropriate place */
for ( ; i < map_size ; i++ ) /* loop thru map bytes */
if ( map_addr[i] != 0 ) /* this byte have any 1's? */
{
m=1; /* set initial test mask */
for ( n = 0 ; n < 8 ; n++ ) /* loop thru bits */
{
commence: /* here's where we enter loop 1st time */
if ( map_addr[i] & m ) /* bit on? */
return( (i<<3) | n );
/* bit number is
(byte number)*8
+ (bit number) */
m =<< 1; /* otherwise shift mask
*/
}
}
}
return ( -1 ); /* search failed */
}