/***********************************
  (C) Copyright 1993; dit/upm
   Distributed under the conditions stated in the
   TOPO General Public License (see file LICENSE)
 ***********************************
 $Log: context.c,v $
 * Revision 2.8  1994/12/19  15:11:25  lotos
 * prototypes integrated into topo
 * new pieces convention, and integrated into topo
 * clean objects
 *
 * Revision 2.7  1993/10/16  10:00:00  lotos
 * add xlola
 *
 * Revision 2.6  1993/09/30  13:17:15  lotos
 * context file may be explicit
 *
 * Revision 2.5  1993/07/22  16:42:15  lotos
 * fix version reporting
 *
 * Revision 2.4  1993/06/24  09:22:47  lotos
 * TOPO is mandatory in the environment
 *
 * Revision 2.3  1993/06/23  16:06:35  lotos
 * new option -verbose
 *
 * Revision 2.2  1993/06/15  12:51:12  lotos
 * if there is no .ctx file, generate one with defaults
 *
 * Revision 2.1  1993/06/10  14:10:24  lotos
 * extract context common part
 * extract C and Ada generation and cleaning functions
 * lots of bugs fixed
 *
 ***********************************/

#ifndef lint
static char rcsid[]= "$Id: context.c,v 2.8 1994/12/19 15:11:25 lotos Exp $";
#endif

/* LINTLIBRARY */

#include "context.h"

/* KJT 11/03/98: added for NS/OS */

#ifdef __NeXT__
char *strdup(s) register char *s; {

  register char *ns;

  return(((ns=malloc(strlen(s)+1))==0)?0:strcpy(ns,s)); }
#endif

char* getenv ();
PUBLIC char filename[BUFSIZ];
PUBLIC char command[BUFSIZ];
PUBLIC char buffer[BUFSIZ];
PUBLIC int FlagVerbose= FALSE;

PUBLIC char TOPO[VSIZE];
PUBLIC char TOPOINC[VSIZE];
PUBLIC char TOPOLIB[VSIZE];
PUBLIC char TOPOBIN[VSIZE];
PUBLIC char TOPOSTDLIB[VSIZE];

PUBLIC char SPEC[VSIZE]=	"";
PUBLIC char CONTEXT[VSIZE]=	"";

PUBLIC char LIB[VSIZE]=		"";
PUBLIC char LIBLOT[VSIZE]=	"";
PUBLIC char LIBLSA[VSIZE]=	"";

PUBLIC char LANGUAGE[VSIZE]=	"C";
PUBLIC char TNAME[VSIZE]=	"lbc";
PUBLIC char DNAME[VSIZE]=	"ldc";
PUBLIC char TPCS[VSIZE]=	"1";
PUBLIC char DPCS[VSIZE]=	"1";
PUBLIC char GLDLIB[VSIZE]=	"";
PUBLIC char MAKEFILE[VSIZE]=	"";
PUBLIC int Modified= FALSE;

/* KJT 20/01/23: added prefix "/tmp/topo." */
PUBLIC char TMP[VSIZE]=	        "/tmp/topo.TXXXXXX";
PUBLIC char MAKE[VSIZE]=	"/tmp/topo.MXXXXXX";

PUBLIC char LSA[VSIZE]=		"lsa";
PUBLIC char GLAD[VSIZE]=	"glad";
PUBLIC char IDLE[VSIZE]=	"idle";
PUBLIC char OMLBC[VSIZE]=	"omlbC";
PUBLIC char D2C[VSIZE]=		"d2c";
PUBLIC char LOLA[VSIZE]=	"lola";
PUBLIC char XLOLA[VSIZE]=	"xlola";

PUBLIC char TOPOF_LFE[VSIZE]	= "";
PUBLIC char TOPOF_LSA[VSIZE]	= "";
PUBLIC char TOPOF_GLAD[VSIZE]	= "";
PUBLIC char TOPOF_OM[VSIZE]	= "";
PUBLIC char TOPOF_OMLBC[VSIZE]	= "";
PUBLIC char TOPOF_IDLE[VSIZE]	= "";
PUBLIC char TOPOF_D2H[VSIZE]	= "";
PUBLIC char TOPOF_D2C[VSIZE]	= "";

PUBLIC char OMLBADA[VSIZE]=	"omlbADA";
PUBLIC char D2ADA_B[VSIZE]=	"d2ada_b";
PUBLIC char TOPOF_OMLBADA[VSIZE]	= "";
PUBLIC char TOPOF_D2ADA[VSIZE]		= "";
PUBLIC char TOPOF_D2ADA_B[VSIZE]	= "";
PUBLIC char TOPOF_ADACPL[VSIZE]	= "";
PUBLIC char TOPOF_ADARTS[VSIZE]	= "";

PUBLIC int
read_ok (f)
  char* f;
{
  return (access (f, R_OK) == 0);
}

PUBLIC void
read_env ()
{
  char* s;

  if ((s= getenv ("TOPO")) != NULL)
    (void) strcpy (TOPO, s);
  else {
    (void) fprintf (stderr, "TOPO must be defined in the environment!\n");
    exit (1);
  }

  /* KJT 28/08/00: sign-on omitted if NDEBUG macro defined */
  #ifndef NDEBUG
    if (strcmp (VERSION, "") != 0)
      (void) fprintf (stderr, "%s (%s) %s\n", VERSION, TODAY, TOPO);
    else
      (void) fprintf (stderr, "development (%s) %s\n", TODAY, TOPO);
  #endif
  (void) sprintf (TOPOBIN, "%s%cbin", TOPO, DIRSEP);
  (void) sprintf (TOPOINC, "%s%clib", TOPO, DIRSEP);
  (void) sprintf (TOPOLIB, "%s%clib", TOPO, DIRSEP);
  (void) sprintf (TOPOSTDLIB, "%s%cstdlib", TOPO, DIRSEP);

  if ((s= getenv ("TOPOBIN")) != NULL)
    (void) strcpy (TOPOBIN, s);

  if ((s= getenv ("TOPOINC")) != NULL)
    (void) strcpy (TOPOINC, s);

  if ((s= getenv ("TOPOLIB")) != NULL)
    (void) strcpy (TOPOLIB, s);

  if ((s= getenv ("TOPOSTDLIB")) != NULL)
    (void) strcpy (TOPOSTDLIB, s);

	/* in MSDOS, the environment mut be already set */
	/* in UNIX, let's enforce it */

/* KJT 11/03/98: changed for NS/OS */

#if !defined(__NeXT__) && !defined(MSDOS)
  (void) strcpy (command, "PATH=.:");
  (void) strcat (command, TOPOBIN);
  (void) strcat (command, ":");
  (void) strcat (command, getenv("PATH"));
  (void) putenv (strdup (command));

  if (getenv ("TOPO") == NULL) {
    (void) sprintf (command, "TOPO=%s", TOPO);
    (void) putenv (strdup (command));
  }
  if (getenv ("TOPOBIN") == NULL) {
    (void) sprintf (command, "TOPOBIN=%s", TOPOBIN);
    (void) putenv (strdup (command));
  }
  if (getenv ("TOPOINC") == NULL) {
    (void) sprintf (command, "TOPOINC=%s", TOPOINC);
    (void) putenv (strdup (command));
  }
  if (getenv ("TOPOLIB") == NULL) {
    (void) sprintf (command, "TOPOLIB=%s", TOPOLIB);
    (void) putenv (strdup (command));
  }
  if (getenv ("TOPOSTDLIB") == NULL) {
    (void) sprintf (command, "TOPOSTDLIB=%s", TOPOSTDLIB);
    (void) putenv (strdup (command));
  }
#endif
}

PUBLIC void
read_ctx ()
{
  FILE* fp;
  char* s1;
  char* s2;

  if (strcmp (CONTEXT, "") == 0)
    (void) strcpy (filename, SPEC);
  else
    (void) strcpy (filename, CONTEXT);
  (void) strcat (filename, ".ctx");

  if ((fp= fopen (filename, "r")) != NULL) {
    while (fgets (buffer, BUFSIZ, fp) != NULL) {
      buffer [strlen (buffer) -1]= 0;
      if (buffer[0] == '#')
	continue;
      for (s1= buffer; isspace (*s1); s1++)
	;
      for (s2= s1; (*s2 != '\0') && (! isspace (*s2)); s2++)
	;
      if (*s2 != '\0') {
	*s2= 0;
	for (s2++; isspace (*s2); s2++)
	  ;
      }

      if (strcmp (s1, "Library") == 0)
	(void) strcpy (LIB, s2);
      else if (strcmp (s1, "Language") == 0)
	(void) strcpy (LANGUAGE, s2);
      else if (strcmp (s1, "BehaviourName") == 0)
	(void) strcpy (TNAME, s2);
      else if (strcmp (s1, "DataName") == 0)
	(void) strcpy (DNAME, s2);
      else if (strcmp (s1, "BehaviourPieces") == 0)
	(void) strcpy (TPCS, s2);
      else if (strcmp (s1, "DataPieces") == 0)
	(void) strcpy (DPCS, s2);
      else if (strcmp (s1, "GladLibrary") == 0)
	(void) strcpy (GLDLIB, s2);
      else if (strcmp (s1, "Makefile") == 0)
	(void) strcpy (MAKEFILE, s2);

      else if (strcmp (s1, "Names") == 0) {
	if (strcmp (s2, "internal") == 0)
	  (void) sprintf (GLDLIB, "%s%cinternal.gld", TOPOSTDLIB, DIRSEP);
	else if (strcmp (s2, "lexical") == 0)
	  (void) sprintf (GLDLIB, "%s%clexical.gld", TOPOSTDLIB, DIRSEP);
      }
    }
    (void) fclose (fp);
  }
  else
    Modified= TRUE;
}

PUBLIC void
write_ctx ()
{
  FILE* fp;

  if (strcmp (CONTEXT, "") == 0)
    (void) strcpy (filename, SPEC);
  else
    (void) strcpy (filename, CONTEXT);
  (void) strcat (filename, ".ctx");

  /* sanity checks */
  if (strcmp (TNAME, DNAME) == 0) {
    (void) fprintf (stderr, "toposet: -do & -to names must be different\n");
    (void) fprintf (stderr, "toposet: %s is not modified\n", filename);
    exit (1);
  }

  if (Modified || ! read_ok (filename)) {
    if ((fp= fopen (filename, "w")) == NULL) {
      (void) fprintf (stderr, "can't open %s (w)\n", filename);
      exit (1);
    }
    list_ctx (fp);
    (void) fclose (fp);
  }
}

PUBLIC void
list_ctx (fp)
  FILE* fp;
{
  (void) fprintf (fp, "Library %s\n", LIB);
  (void) fprintf (fp, "Language %s\n", LANGUAGE);
  (void) fprintf (fp, "BehaviourName %s\n", TNAME);
  (void) fprintf (fp, "DataName %s\n", DNAME);
  (void) fprintf (fp, "BehaviourPieces %s\n", TPCS);
  (void) fprintf (fp, "DataPieces %s\n", DPCS);
  (void) fprintf (fp, "GladLibrary %s\n", GLDLIB);
  (void) fprintf (fp, "Makefile %s\n", MAKEFILE);
}

PUBLIC int
my_system (cmd)
  char *cmd;
{
  int status;

  if (FlagVerbose)
    if (strncmp (cmd, "make ", 5) != 0)
      (void) fprintf (stderr, "%s\n", cmd);
  status= system (cmd);
#ifdef MSDOS
    return status;
#endif

  switch (status & 0xFF) {
  case 0x00:
    status= status >> 8;
    break;
  case 0x7F:
    status= 0x7F;
    break;
  default:
    status= 0xFF;
    break;
  }
  return status;
}

PUBLIC void
unlink_pcs (name, ext, pcs)
  char *name;
  char *ext;
  int pcs;
{
  int digits= 0;
  int i;

  for (i= pcs - 1; i > 0; i/= 10)
    ++digits;
  for (i= 1; i < pcs; ++i) {
    (void) sprintf(filename, "%s%0*u.%s", name, digits, i, ext);
    (void) unlink (filename);
  }
}

