static char *SccsId = "@(#)readCom.c 3.1 (TU-Delft) 06/08/90";
/**********************************************************

Name/Version      : nspice/3.1

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

Author(s)         : A.J. van Genderen
Creation date     : 8-June-1990
Modified by       :
Modification date :


        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) 1990 , All rights reserved
**********************************************************/
#include <stdio.h>

#include "define.h"
#include "type.h"
#include "extern.h"

extern char *fn_cmd;

extern FILE *yyin;

extern struct node * Begin_node;
extern struct node * End_node;

extern double sigtimeunit;
extern int simperiod;

long curr_time;
long newEndtime;
double Timeconvert;
struct signal *Old_end_signal;

int readCom (name)
char *name;
{
    char tmp[32];
    char help[48];
    int i;
    char *filename;
    struct signal *sig;
    struct sig_value *sval;
    struct node *n;


    sprintf (tmp, "%s", name);
    i = 0;
    while (tmp[i] != ' ' && tmp[i] != '\0') i++;
    tmp[i] = '\0';

    NEW (filename, strlen (tmp) + 5, char);
    sprintf (filename, "%s", tmp);

    if ((yyin = fopen (filename, "r")) == NULL) {
	sprintf (help, "Cannot open %s", filename);
	message (help);
	return (0);
    }

    fn_cmd = filename;

    cmdinits ();

    yyparse ();

    Nr_signals = 0;

    Begin_signal = NULL;
    End_signal = NULL;

    Timescaling = sigtimeunit;

    if (simperiod >= 0) {

	newEndtime = simperiod;
    }
    else
	newEndtime = 0;  /* for initialization */

    n = Begin_node;
    while (n) {
	Nr_signals++;
	NEW (sig, 1, struct signal);
	sig -> name = n -> name;
	sig -> next = NULL;
	sig -> prev = NULL;
	sig -> layover = NULL;
	sig -> begin_value = NULL;
	sig -> end_value = NULL;
	sig -> begin_value_L = NULL;
	sig -> end_value_L = NULL;
	sig -> begin_value_U = NULL;
	sig -> end_value_U = NULL;
	if (End_signal) {
	    End_signal -> next = sig;
	    sig -> prev = End_signal;
	    End_signal = sig;
	}
	else {
	    Begin_signal = End_signal = sig;
	}

        curr_time = 0;
        if (addSgnPart (sig, n -> expr, 1) < 0)
	    return (0);

        n = n -> next;
    }

    /* make all new signals end at the time that is Endtime 
       for the current input file */

    sig = Begin_signal;
    while (sig) {
	if (sig -> end_value && sig -> end_value -> time < newEndtime) {
	    NEW (sval, 1, struct sig_value);
	    sval -> time = newEndtime;
	    sval -> value = sig -> end_value -> value;
	    sval -> next = NULL;
	    sig -> end_value -> next = sval;
	    sval -> prev = sig -> end_value;
	    sig -> end_value = sval;
	}
	sig = sig -> next;
    }

    Endtime = newEndtime;

    return (1);
}

int addSgnPart (sig, expr, nr)
struct signal *sig;
SIGNALELEMENT *expr;
int nr;
{
    struct sig_value *sval;
    SIGNALELEMENT *sibling_expr;
    int value;
    int ret;
    int newnr;

    while (nr > 0 || nr == -1) {

	sibling_expr = expr -> sibling;

	while (sibling_expr) {

	    if (sibling_expr -> child) {
		if (sibling_expr -> len > 0 
		    && sibling_expr -> child -> len > 0) {
		    newnr = sibling_expr -> len / sibling_expr -> child -> len;
		}
		else {
		    newnr = -1;
		}
		ret = addSgnPart (sig, sibling_expr -> child, newnr);
		if (ret != 0)
		    return (ret);
	    }
	    else {
		if (sibling_expr -> val == H_state) {
		    value = 2;
		}
		else if (sibling_expr -> val == L_state) {
		    value = 0;
		}
		else if (sibling_expr -> val == X_state) {
		    value = 1;
		}
		else if (sibling_expr -> val == Free_state) {
		    value = -1;
		}
		else {
		    fprintf (stderr, "He ?\n");
		}

		if (!sig -> end_value || sig -> end_value -> value != value) {

		    NEW (sval, 1, struct sig_value);

		    sval -> time = curr_time;

		    sval -> value = value;
		    sval -> next = NULL;
		    sval -> prev = NULL;

		    if (sig -> end_value) {
			sig -> end_value -> next = sval;
			sval -> prev = sig -> end_value;
			sig -> end_value = sval;
		    }
		    else {
			sig -> begin_value = sig -> end_value = sval;
		    }
		}

                if (sibling_expr -> len > 0)
		    curr_time = curr_time + sibling_expr -> len;
		else
		    curr_time = simperiod;

		if (simperiod < 0) {
		    if (curr_time > newEndtime)
			newEndtime = curr_time;
		}

		if (simperiod > 0 && curr_time > simperiod) {
		    return (1);                 /* end of signal reached */
		}
	    }

	    sibling_expr = sibling_expr -> sibling;
	}

	if (nr != -1)
	    nr--;
    }

    return (0);
}
