static char *SccsId = "@(#)expNet.c 4.2 (TU-Delft) 03/20/91";
/**********************************************************

Name/Version      : xsls/4.2

Language          : C
Operating system  : UNIX SYSTEM V
Host machine      : HP9000

Author(s)         : A.J. van Genderen
Creation date     : 16-Feb-1987
Modified by       : A.J. van Genderen
Modification date : 16-Feb-1987


        Delft University of Technology
        Department of Electrical Engineering
        Network Theory Section
        Mekelweg 4 - P.O.Box 5031
        2600 GA DELFT
        The Netherlands

        Phone : 015 - 786234

        COPYRIGHT (C) 1987 , All rights reserved
**********************************************************/
#include "incl.h"

static struct net_ref *cn_stock = NULL;
static struct net_ref *cn_last = NULL;
static int cn_reset = 0;

/* expNet will expand the net which is given as an argument,
   and will return the result in a list of cir_net structures.
   Each net structure returned will be reused during a next call,
   while each net_ref structure will not be reused.
*/
   
struct net_ref * expNet (net)
struct cir_net *net;
{
    int i;
    int increment;
    int ready;
    long x1vector[25]; /* assume maximum nbr of indices = 25 */
    long x2vector[25];
    long x3vector[25];
    struct net_ref *begin_list;
    struct net_ref *end_list;
    struct net_ref *newnref;
    struct cir_net *newn;
    struct cir_net *newExpNet ();

    begin_list = NULL;
    end_list = NULL;

    for (i = 0; i < net -> net_dim; i++) {
	x1vector[i] = net -> net_lower[i];
    }
    
    for (i = 0; i < net -> inst_dim; i++) {
	x2vector[i] = net -> inst_lower[i];
    }
    
    for (i = 0; i < net -> ref_dim; i++) {
	x3vector[i] = net -> ref_lower[i];
    }
    
    cn_reset = 1;

    ready = 0;
    while (! ready) {

        newn = newExpNet ();
	strcpy (newn -> net_name, net -> net_name);
	strcpy (newn -> inst_name, net -> inst_name);
	newn -> net_dim = net -> net_dim;
	newn -> inst_dim = net -> inst_dim;
	newn -> ref_dim = net -> ref_dim;

        if (newn -> net_dim > 0) {
	    PALLOC (newn -> net_lower, newn -> net_dim, long);
	    PALLOC (newn -> net_upper, newn -> net_dim, long);
	}

        if (newn -> inst_dim > 0) {
	    PALLOC (newn -> inst_lower, newn -> inst_dim, long);
	    PALLOC (newn -> inst_upper, newn -> inst_dim, long);
	}

        if (newn -> ref_dim > 0) {
	    PALLOC (newn -> ref_lower, newn -> ref_dim, long);
	    PALLOC (newn -> ref_upper, newn -> ref_dim, long);
	}

	for (i = 0; i < net -> net_dim; i++) {
	    newn -> net_lower[i] = newn -> net_upper[i] = x1vector[i];
	}
	
	for (i = 0; i < net -> inst_dim; i++) {
	    newn -> inst_lower[i] = newn -> inst_upper[i] = x2vector[i];
	}
	
	for (i = 0; i < net -> ref_dim; i++) {
	    newn -> ref_lower[i] = newn -> ref_upper[i] = x3vector[i];
	}
	
	PALLOC (newnref, 1, struct net_ref);
	newnref -> n = newn;

	if (begin_list == NULL) {
	    begin_list = newnref;
	}
	else {
	    end_list -> next = newnref;
	}
	end_list = newnref;

	increment = 0;
	for (i = net -> net_dim - 1; i >= 0 && ! increment; i--) {
	    x1vector[i]++;
	    if (x1vector[i] <= net -> net_upper[i]) {
		increment = 1;
		break;
	    }
	    else {
		x1vector[i] = net -> net_lower[i];
	    }
	}
	for (i = net -> inst_dim - 1; i >= 0 && ! increment; i--) {
	    x2vector[i]++;
	    if (x2vector[i] <= net -> inst_upper[i]) {
		increment = 1;
		break;
	    }
	    else {
		x2vector[i] = net -> inst_lower[i];
	    }
	}

	if (increment)
	    ready = 0;
	else
	    ready = 1;

	for (i = net -> ref_dim - 1; i >= 0; i--) {
	    x3vector[i]++;
	    if (x3vector[i] <= net -> ref_upper[i]) {
		break;
	    }
	    else {
		x3vector[i] = net -> ref_lower[i];
	    }
	}
    }

    return (begin_list);
}

struct cir_net *newExpNet ()
{
    if (cn_stock == NULL) {
	PALLOC (cn_stock, 1, struct net_ref);
	cn_stock -> next = NULL;
	PALLOC (cn_stock -> n, 1, struct cir_net);
	cn_stock -> n -> net_lower = NULL;
	cn_stock -> n -> net_upper = NULL;
	cn_stock -> n -> inst_lower = NULL;
	cn_stock -> n -> inst_upper = NULL;
	cn_stock -> n -> ref_lower = NULL;
	cn_stock -> n -> ref_upper = NULL;
	cn_last = cn_stock;
    }
    else {

	if (cn_reset) {
	    cn_last = cn_stock;
	}
	else {
	    if (cn_last -> next == NULL) {
		PALLOC (cn_last -> next, 1, struct net_ref);
		cn_last -> next -> next = NULL;
		PALLOC (cn_last -> next -> n, 1, struct cir_net);
		cn_last -> next  -> n -> net_lower = NULL;
		cn_last -> next  -> n -> net_upper = NULL;
		cn_last -> next  -> n -> inst_lower = NULL;
		cn_last -> next  -> n -> inst_upper = NULL;
		cn_last -> next  -> n -> ref_lower = NULL;
		cn_last -> next  -> n -> ref_upper = NULL;
	    }

	    cn_last = cn_last -> next;
	}
    }

    FREE (cn_last -> n -> net_lower);
    FREE (cn_last -> n -> net_upper);
    FREE (cn_last -> n -> inst_lower);
    FREE (cn_last -> n -> inst_upper);
    FREE (cn_last -> n -> ref_lower);
    FREE (cn_last -> n -> ref_upper);

    cn_reset = 0;

    return (cn_last -> n);
}
