/*
#ident	"@(#)smail/src:RELEASE-3_2_0_120:list.c,v 1.9 2004/02/02 03:24:44 woods Exp"
 */

/*
 *    Copyright (C) 1987, 1988 Ronald S. Karr and Landon Curt Noll
 *    Copyright (C) 1992  Ronald S. Karr
 * 
 * See the file COPYING, distributed with smail, for restriction
 * and warranty information.
 */

/*
 * list.c:
 *
 *	external functions: add_intlist, remove_intlist_matching, remove_intlist_at
 */

#include "defs.h"

#include <sys/types.h>
#include <stdio.h>

#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
#  include <stdlib.h>
# endif
#endif

#ifdef HAVE_STRING_H
# if !defined(STDC_HEADERS) && defined(HAVE_MEMORY_H)
#  include <memory.h>
# endif
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif

#ifdef __STDC__
# include <stdarg.h>
#else
# include <varargs.h>
#endif

#include "smail.h"
#include "smailstring.h"
#include "addr.h"			/* for "log.h" */
#include "log.h"
#include "main.h"
#include "alloc.h"
#include "list.h"
#include "debug.h"
#include "smailport.h"

/*
 * add_intlist - add an int value to a list of int values
 *
 * Look through the list headed by lp for unused entries and record the given
 * value in the data field of the list note.  If no unused entry is found then
 * add a new entry to the head of the list and use it.
 *
 * Returns the (possibly new) head of the list.
 */
intlist_t *
add_intlist(lp, val)
    intlist_t *lp;
    int val;
{
    register intlist_t *nc;

    for (nc = lp; nc; nc = nc->succ) {
	if (!nc->i_used) {
	    nc->i_val = val;		/* store it here */
	    nc->i_used = TRUE;		/* mark this one re-used */

	    return lp;			/* return old header */
	}
    }
    /*
     * no unused entries -- add a new one to the head of the list
     */
    nc = (intlist_t *) xmalloc(sizeof(intlist_t)); /* create it */
    nc->i_val = val;			/* store it */
    nc->i_used = TRUE;			/* mark it used */
    nc->succ = lp;			/* link it in at the head */

    return nc;				/* return new list header */
}


/*
 * remove_intlist_matching - remove an item from a list of unique int values
 *
 * We don't bother actually try to free allocated list nodes -- instead we just
 * mark entries as "unused".
 *
 * Returns TRUE if the item was found in the list, FALSE otherwise.
 */
int
remove_intlist_matching(lp, val)
    register intlist_t *lp;
    register int val;
{
    register intlist_t *nc;

    for (nc = lp; nc; nc = nc->succ) {
	if (nc->i_used && nc->i_val == val) {
	    nc->i_used = FALSE;		/* mark this entry unused */

	    return TRUE;
	}
    }
    /* note this function is called for every child, not just runq's... */

    return FALSE;
}

/*
 * add_charplist - add a char * value to a list of char * values
 *
 * Returns the (possibly new) head of the list.
 */
charplist_t *
add_charplist(lp, val)
    charplist_t *lp;
    char *val;
{
    register charplist_t *nc;

    nc = (charplist_t *) xmalloc(sizeof(charplist_t)); /* create it */
    nc->text = val;			/* store it */
    nc->succ = lp;			/* link it in at the head */

    return nc;				/* return new list header */
}

#ifndef NODEBUG

int
count_charplist(lp)
    register charplist_t *lp;
{
    register charplist_t *nc;
    register int i = 0;
    register int j = 0;

    for (nc = lp; nc; nc = nc->succ) {
	i++;
	if (nc->text) {
	    j++;
	}
    }
    DEBUG2(DBG_MAIN_LO, "count_charp_list(): found %d entries, %d valid strings\n", i, j);

    return i;
}

void
print_charplist(lp)
    register charplist_t *lp;
{
    register charplist_t *nc;
    register int i = 0;
    int odebug = debug;

    debug = DBG_MAIN_LO;			/* force the issue */
    for (nc = lp; nc; nc = nc->succ) {
	i++;
	if (nc->text) {
	    DEBUG2(DBG_MAIN_LO, "print_charp_list(): lp entry # %d =  '%v'\n", i, nc->text);
	}
    }
    debug = odebug;

    return;
}

int
count_intlist(lp)
    register intlist_t *lp;
{
    register intlist_t *nc;
    register int i = 0;
    register int j = 0;

    for (nc = lp; nc; nc = nc->succ) {
	i++;
	if (nc->i_used != 0) {
	    j++;
	}
    }
    DEBUG2(DBG_MAIN_LO, "count_int_list(): found %d entries, %d valid PIDs\n", i, j);

    return i;
}

void
print_intlist(lp)
    register intlist_t *lp;
{
    register intlist_t *nc;
    register int i = 0;
    int odebug = debug;

    debug = DBG_MAIN_LO;			/* force the issue */
    for (nc = lp; nc; nc = nc->succ) {
	i++;
	if (nc->i_used != 0) {
	    DEBUG2(DBG_MAIN_LO, "print_int_list(): lp entry # %d =  %d\n", i, nc->i_val);
	}
    }
    debug = odebug;

    return;
}

#endif /* NODEBUG */

/* 
 * Local Variables:
 * c-file-style: "smail"
 * End:
 */
