static char *SccsId = "@(#)dmgproc.c 3.7 (TU-Delft) 03/26/91";
/**********************************************************

Name/Version      : The Design Data Management Project

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

Author(s)         : S. de Graaf
                    A. van der Hoeven
                    T.G.R. van Leuken
                    N. van der Meijs
		    T. Vogel
		    P. van der Wolf
Creation date     : 04-Dec-1986
Modified by       : P. van der Wolf
Modification date : 17-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) 1985-1987 , All rights reserved
**********************************************************/
#include "dmstd.h"

#ifdef hpux
#define index strchr
#define rindex strrchr
#endif

char   *index ();
char   *rindex ();

#define ALLOC(ptr,el,name) \
if(!(ptr=(name *)malloc((unsigned)((el)*sizeof(name)))))goto e3

/*
** _dmGetProcess is used to read the process data in core,
** after which it is accessible by the calling program.
*/

DM_PROCDATA * _dmGetProcess (dmproject)
DM_PROJECT * dmproject;
{
    DM_PROCDATA * _dmDoGetProcess ();
    DM_PROCDATA * _dmSearchProcInProjKeys ();

    if ((dmproject -> maskdata =
		    _dmSearchProcInProjKeys (dmproject -> procid)) == NULL) {
	/* not yet present, do the actual getting of the maskdata */
	dmproject -> maskdata = _dmDoGetProcess (dmproject -> procid);
    }
    return (dmproject -> maskdata);
}

/* actual getting of process information is localized in a
** separate routine with the process_id as its argument, to
** allow dedicated programs to use it without opening a project.
** Tecc needs a filename.
*/

DM_PROCDATA * _dmDoGetProcess (process_id)
int process_id;
{
    char   *path;
    DM_PROCDATA * _dmDoGetProcessFile ();
    char * _dmDoGetProcPath();

    if ((path = _dmDoGetProcPath (process_id, "maskdata")) == NULL)
	return (NULL);
    else
	return (_dmDoGetProcessFile (path));
}

DM_PROCDATA * _dmDoGetProcessFile (path)
char * path;
{
    FILE * fp;
    char    buf[MAXLINE];
    char   *proc_name;
    char   *cp;
    char   *end_p;
    int     nomasks;
    int     mask_index;
    int     i;
    DM_PROCDATA * process;

    fp = fopen (path, "r");

#ifdef DM_DEBUG
    IFDEBUG
	fprintf (stderr, "fildes: %d, path: %s\n",
	    (fp ? fileno (fp) : -1), path);
#endif /* DM_DEBUG */

    if (fp == NULL)
	goto e2;

    ALLOC (process, 1, DM_PROCDATA);

    do {
	if (!fgets (buf, MAXLINE, fp))
	    goto e4;
    } while (*buf == '#');

    if (sscanf (buf, "%d", &nomasks) != 1
	    || nomasks <= 0
	    || nomasks > DM_MAXNOMASKS)
	goto e4;

/* decode process-type from buf */
    if ((cp = index (buf, '"')) == NULL)
	goto e4;	/* pr_type should be present */
    cp++;
    if ((end_p = index (cp, '"')) == NULL)
	goto e4;
    *end_p = '\0';

    ALLOC (process -> pr_type, end_p - cp + 1, char);
    _dmSprintf (process -> pr_type, "%s", cp);

/* decode optional process_info from remaining part of buf */
    if ((cp = index (end_p + 1, '"')) == NULL) {
	cp = "";	/* no pr_info present */
	end_p = cp;
    }
    else {
	cp++;
	if ((end_p = index (cp, '"')) == NULL)
	    goto e4;
	*end_p = '\0';
    }

    ALLOC (process -> pr_info, end_p - cp + 1, char);
    _dmSprintf (process -> pr_info, "%s", cp);

/* pr_name must be decoded from path */
    if ((cp = rindex (path, '/')) == NULL)
	goto e4;
    *cp = '\0';
    if ((proc_name = rindex (path, '/')) == NULL)
	goto e4;
    proc_name++;
/* allocate and fill pr_name */
    ALLOC (process -> pr_name, strlen (proc_name) + 1, char);
    _dmSprintf (process -> pr_name, "%s", proc_name);

/* allocate mask_name, mask_no and mask_type pointers	*/

    ALLOC (process -> mask_name, nomasks, char *);
    ALLOC (process -> mask_info, nomasks, char *);
    ALLOC (process -> mask_no, nomasks, int);
    ALLOC (process -> mask_type, nomasks, int);

/* allocate pgt_ pointers */

    ALLOC (process -> pgt_no, nomasks, int);
    ALLOC (process -> pgt_type, nomasks, int);

/* allocate pointers to dev structures of:
** ColorMask, RamTek and PLOTter
*/
    ALLOC (process -> CM, nomasks, struct device   *);
    ALLOC (process -> RT, nomasks, struct device   *);
    ALLOC (process -> PLOT, nomasks, struct device *);

    process -> nomasks = nomasks;

    for (i = 0; i < nomasks; i++) {
	ALLOC (process -> mask_name[i], DM_MAXLAY + 1, char);
	ALLOC (process -> CM[i], 1, struct device);
	ALLOC (process -> RT[i], 1, struct device);
	ALLOC (process -> PLOT[i], 1, struct device);
	process -> mask_no [i] = -1;
    }

/* store mask information into process structure */

    for (i = 0; i < nomasks; i++) {
	do {
	    if (!fgets (buf, MAXLINE, fp))
		goto e4;
	} while (*buf == '#');

	if (sscanf (buf, "%d", &mask_index) != 1)
	    goto e4;

	/* test mask_index: in valid range and entry should be free */
	if (mask_index < 0 || mask_index >= nomasks
			    || process -> mask_no[mask_index] != -1) {
	    goto e4;
	}

	if (sscanf (buf, "%d%s%d%d%d%d%d%d%d%d%d",
		    &process -> mask_no[mask_index],
		    process -> mask_name[mask_index],
		    &process -> mask_type[mask_index],
		    &process -> pgt_no[mask_index],
		    &process -> pgt_type[mask_index],
		    &process -> CM[mask_index] -> code,
		    &process -> CM[mask_index] -> fill,
		    &process -> RT[mask_index] -> code,
		    &process -> RT[mask_index] -> fill,
		    &process -> PLOT[mask_index] -> code,
		    &process -> PLOT[mask_index] -> fill) != 11)
	    goto e4;

	/* decode optional mask_info from buf */
	if ((cp = index (buf, '"')) == NULL) {
	    cp = "";	/* no mask_info present */
	    end_p = cp;
	}
	else {
	    cp++;
	    if ((end_p = index (cp, '"')) == NULL)
		goto e4;
	    *end_p = '\0';
	}

	ALLOC (process -> mask_info[mask_index], end_p - cp + 1, char);
	_dmSprintf (process -> mask_info[mask_index], "%s", cp);
    }

    if (i != nomasks)
	goto e4;

    fclose (fp);
    return (process);
e2: 
    dmerrno = DME_PRDATA;
    goto ret;
e3: 
    dmerrno = DME_CORE;
    goto ret;
e4: 
    dmerrno = DME_PRREAD;
ret: 
    dmError ("_dmGetProcess");
    return (NULL);
}
