static char *SccsId = "@(#)dmprlst.c 3.7 (TU-Delft) 04/28/93";
/**********************************************************

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       : S. de Graaf
Modification date : 11-Mar-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"

/* we cannot include <stdlib.h> to prototype getenv() because of
 * the malloc hacks in dmmem.h and the fact that some machines
 * prototype malloc in stdlib.h.
 */
#ifdef __STDC__
extern char *getenv(char *);
#else
extern char *getenv();
#endif

static char *projbuf[DM_MAXPROJECTS];

char *_dmExtractEnvironentVariable();
char *dmSubstituteEnvironmentVars();

char  ** _dmProjectlist (dmproject)
DM_PROJECT * dmproject;
{
    FILE * fp;
    char    buf[DM_MAXNAME + 10];
    char    path[MAXLINE];
    int     i = 0;

    _dmSprintf (path, "%s/projlist", dmproject -> dmpath);

    dmSubstituteEnvironmentVars(path);

    if (!(fp = fopen (path, "r"))) {
	dmerrno = DME_NOPRJL;
	dmError ("_dmProjectlist: no projlist");
	return (NULL);
    }

    while (fscanf (fp, "%s", buf) != EOF) {
	projbuf[i++] = _dmStrSave (buf);
	if (i == DM_MAXPROJECTS)
	    _dmFatal ("_dmProjectlist: too many projects", "", "");
    }
    projbuf[i] = NULL;

#ifdef DM_DEBUG
    IFDEBUG {
	fprintf (stderr, "_dmProjectlist: ");
	for (i = 0; projbuf[i] != NULL; i++)
	    fprintf (stderr, "%s%s", projbuf[i], projbuf[i + 1] ? ", " : "\n");
    }
#endif /* DM_DEBUG */

    fclose (fp);
    return (projbuf);
}



/* this function substitutes all occurrences of $SOMETHING in PATH by the value
 * of the environment variable SOMETHING. It is an error if SOMETHING is not
 * set in the environment. The expanded PATH is returned as a pointer to a
 * static character array. It will be overwritten by the next call to
 * dmSubstituteEnvironmentVars(). 
 */

char *dmSubstituteEnvironmentVars(path)
   char *path;
{
   static char epath[1 + MAXLINE];
   int i = 0;
   char c, *p = path;
   if (path == NULL) return NULL; /* nothing to do */
   while ((c = *p++) != '\0')
   {
      if ( c != '$')
      {
	 epath[i++] = c;	  /* no special char, copy it to epath */
      }
      else if (*p == '$')
      { /* the special construct "$$" is just replaced by a singe '$': */
	 epath[i++] = c;	  /* copy a single '$', then proceed normally*/
	 p++;
      }
      else
      {  /* OK, found a real environment var... which one is it? */
	 char *env = _dmExtractEnvironentVariable(&p);
	 char *value_of_env = getenv(env);
	 if (value_of_env == NULL)
	 {
	    char s[MAXLINE];
	    sprintf(s,
		    "_dmProjectlist: The environment variable \"%s\" is not set!",
		    env);
	    dmError(s);
	 }
	 while ( epath[i++] = *value_of_env++ ) /* the cryptic sort of C! */
	    ;   /* this actually copies the value of the env var to epath */
	 i--;	       /* the last one was a '\0' that we did not ask for */
      }
   }
   epath[i] = '\0';
   return epath;
}


/* extract the environment variable from *str and return it. Leave str pointing
 * just past the end of the environment variable name. Env. names may contain
 * alphas, digits and underscores. They may be enclosed in curly braces {}, in
 * which case these braces are not returned as part of the env. name.
 *
 * Examples:
 * str = "SOMETHING/seadif" returns "SOMETHING" and leaves str pointing
 *       to "/seadif".
 *
 * str = "{SOMETHING}/seadif" also returns "SOMETHING" and also leaves str
 *       pointing to "/seadif".
 */
char *_dmExtractEnvironentVariable(str)
   char **str;
{
   static char name[MAXLINE], c;
   char *p = *str;
   int i = 0;
   int inCurlyBraces = (*p == '{');
   if (inCurlyBraces)
      p++;
   while ((c = *p) != '\0')
   {
      if (inCurlyBraces && c == '}')
      {
	 p++;
	 break;
      }
      if (!inCurlyBraces && !isalnum(c) && c != '_')
	 break;
      name[i++] = c;
      p++;
   }
   name[i] = '\0';
   *str = p;
   return name;
}

