/*
 *  program dxsc.c
 *  PASCAL-XSC development system
 *
{*  last modification:	02.04.92  16:50   }

 * uli 02.08.91 : "?" in main menu answered by "Enter d"
 * uli 08.08.91 : run: p and VAX_VMS added.
 * uli 30.08.91 : list: rename not available on i860.
 * uli 05.09.91 : run: VAX_VMS removed, because "[]" added by exefnam.
 * uli 06.09.91 : Option menu added.
 * uli 13.09.91 : binpath added.
 * uli 04.02.92 : case is_pas added.
 * uli 02.04.92 : append_stub called, statements moved to depend.c
 * PJ  31.03.95 : #ifdef LINT_ARGS added for switchfile, edit, printcmd, main.
                  Casts for ANSI compatibility added
*/

/* #define TEST_RUN      /* display debug information */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

#define global extern

#include "defs.h"
#include "depend.h"
#include "sysutil.h"
#include "p88hlp.h"

#define HLPfnam         "dxsc.hlp"

typedef enum fileClass {is_prg, is_mod, is_pas, is_oth} fileClass ;

extern  char * filename ;       /* declared in depend.c */
static  char *  prgname = NULL;
static  char *  modname = NULL;
static  char *  othname = NULL;
static  fileClass  Class ;
static  struct { char *    name ;
                 fileClass Class ;
               } slot [10] ;
static  char * params = NULL;      /* parameters of RUN command */

static  int    retc;
static  int    savesrc = true ;
static  int    off_remove ;

#if INDIRECT
static char   sys_call[256];            /* buffer for system-call strings */
#else
static char   sys_call[2560];           /* buffer for system-call strings */
#endif

#ifdef LINT_ARGS
static  void   whichClass (void);
static  void   setClass (void);
static  int    clrslot (void);
static  int    switchfile (char * fn) ;
static  void   filecmd (void);
static  void   batch (void);
static  void   syscmd(void);

static  void    comp    (void);
static  void    link    (void);
static  void    list    (void);
static  void    run     (void);
static  void    edit    (char *, char *);
static  void    printcmd(char *, char *);
#else
static  void    whichClass ();
static  void    setClass ();
static  int     clrslot ();
static  int     switchfile () ;
static  void    filecmd ();
static  void    batch ();
static  void    syscmd();
static  void    comp    ();
static  void    link    ();
static  void    list    ();
static  void    run     ();
static  void    edit    ();
static  void    printcmd();
#endif


/****************/
/*  file tools  */
/****************/



                                                /*----------------------*/
static void whichClass ()                       /*  w h i c h c l a s s */
{ char * p ;

  p = filename + strlen (filename) - strlen (srcext()) ;
  if  (strcmp (p, srcext()) == 0)  {    /* pascal extension specified */
     *p = '\0' ;                        /* delete it */
     fnaminit (filename) ;
     Class = is_pas ;
   } else
     Class = is_oth ;

   if  (exist (filename, srcext()))
    {
     fnaminit (filename) ;
     if  (exist (intfnam(), "")) {
       Class = is_mod ;
       modname = filename ;
     } else {
     if  (exist (exefnam(), "")) {
       Class = is_prg ;
       prgname = filename ;
     } else {
       Class = is_pas ;
       if  (not prgname)   prgname = filename ;
     }
    }
   } else {
     if  (Class == is_oth)
       othname = filename ;
     else
       if  (not prgname)   prgname = filename ;
   }
}                                               /*  w h i c h c l a s s */
						/*----------------------*/

						/*------------------*/
static void setClass ()                         /*  s e t c l a s s */
{ int i ;

  for (i=0; i<10; i++)               /* for all slots */
    if  (slot[i].name and strcmp (slot[i].name, filename) == 0)
      slot[i].Class = Class ;
}                                               /*  s e t c l a s s */
						/*------------------*/


                                                        /*-----------------*/
static int  clrslot ()                                  /*  c l r s l o t  */
{ int i ;
 while (1) {
  for (i=0; i<10; i++)               /* scan slots */
    if  (slot[i].name == NULL)   return i ;

  printf ("\nWarning!! Only  10  filenames may be managed.\n") ;
  printf ("You have drop some filenames or to skip further filenames.\n") ;

  printf ("Enter the identification number(s) of the filename(s) to be dropped!\n") ;

  for (i=0; i<10; i++)               /* all slots */
    printf ("  %1d  =  %s\n", i, slot[i].name) ;
  printf ("  s  =  skip further filenames\n") ;
  prompt ("identification number(s)? ") ;
  i = tty ;
  while (i != '\n' and i != EOF) {
    if  (i == 's' or i == 'S') {
       do  { tty = getchar() ; }        /* skip line */
       while (tty != '\n' and tty != EOF) ;
       return -1 ;                      /* and leave clrslot */
     }
   else
    if  ('0' <= i  and i <= '9')
     { char * p = slot[i-'0'].name ;
       slot[i-'0'].name = NULL ;
       if  (prgname == p)   prgname = NULL ;
       if  (modname == p)   modname = NULL ;
       if  (othname == p)   othname = NULL ;
       /* if  (filename != p)   free (p) ; */
     }
    i = getchar() ;
  }
  tty = i ;
 } /* until slot free */
}                                                       /*  c l r s l o t  */
                                                        /*-----------------*/


/* PJ 31.03.95  #ifdef LINT_ARGS added */

                                                /*-----------------------*/
#ifdef LINT_ARGS
static int switchfile( char* fn )
#else
static int     switchfile (fn)                  /*  s w i t c h f i l e  */
  /* switches filename to fn, if fn in any slot */
  /* returns true if fails */
  char * fn ;
#endif
{
  int i ;

  for (i=0; i<10; i++)                    /* search all slots */
    if (slot[i].name and strcmp(fn, slot[i].name) == 0)   break ;
  if  (i<10) {                            /* slot found */
     filename = slot[i].name ;
     Class    = slot[i].Class;
     switch (Class) {
       case is_prg:  prgname = filename ;    break ;
       case is_mod:  modname = filename ;    break ;
       case is_oth:  othname = filename ;
       case is_pas:  ;
     }
     fnaminit (filename) ;
  } else {                                /* slot not found */
     printf ("\nFirst use the command   F N %s\n", fn) ;
     if  (Class == is_prg or Class == is_pas)
       printf (" or recompile %s\n", filename) ;
     screenisclear = false ;
     return true ;
  }
  return false ;
} /* switchfile */



/******************/
/*  d88 commands  */
/******************/

                                                        /*-----------------*/
static void filecmd ()                                  /*  f i l e c m d  */
{ int i ;
  int subcmd ;

  while  (tty == ' ' or tty == '\t')  tty = getchar () ;
  do   {
    if  (tty == '\n')  {
      if  (prgname and *prgname != '\0')
       printf (" P  =  switch to pascal Program %s%s\n", prgname, srcext()) ;
      if  (modname and *modname != '\0')
       printf (" M  =  switch to pascal Module  %s%s\n", modname, srcext()) ;
      if  (othname and *othname != '\0')
       printf (" O  =  switch to Other file     %s\n", othname) ;
      for (i=0; i<10; i++)
        if  (slot[i].name)
	 printf (" %1d  =  switch to   %c   file     %s%s\n", i,
		 on_debug ?
		    ( slot[i].Class==is_prg ? 'P' :
		      slot[i].Class==is_mod ? 'M' :
		      slot[i].Class==is_pas ? 'S' :
		      slot[i].Class==is_oth ? 'O' : '?' ) :
		    ' ',
		 slot[i].name, ( slot[i].Class==is_oth ? "" : srcext())) ;
      printf (" N  =  enter new file name\n") ;
    }
    prompt ("File specification (p/m/o/n/h/q) or ? for help : ");
    subcmd = readtty () ;
    if  (subcmd != '?' and subcmd != 'h')   break ;
    helpon ('F') ;
  } while  (subcmd == '?' or subcmd == 'h') ;

  switch (subcmd) {
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
      i = subcmd - '0' ;
      if  (slot[i].name == NULL)    break ;
      filename = slot[i].name ;
      Class    = slot[i].Class;
      switch (Class) {
	case is_prg:  prgname = filename ;    break ;
	case is_mod:  modname = filename ;    break ;
	case is_oth:  othname = filename ;    break ;
        case is_pas: ;
      }
      if (Class != is_oth)   fnaminit (filename) ;
    break;

    case    'p':
      if  (prgname and *prgname) {
        Class = is_prg ;
        filename = prgname ;
	if (Class != is_oth)   fnaminit (filename) ;
      }
    break;
    case    'm':
      if  (modname and *modname) {
        Class = is_mod ;
        filename = modname ;
	if (Class != is_oth)   fnaminit (filename) ;
      }
    break;
    case    'o':
      if  (othname and *othname) {
        Class = is_oth ;
        filename = othname ;
      }
    break;
    case    'n':
      ask (" Filename ", &filename) ;
      whichClass() ;
      i = clrslot () ;
      if  (i != -1)  {
        slot[i].name  = filename ;
        slot[i].Class = Class ;
      }
    break;
    case    'h':
      helpon ('F') ;
    break;
    case    'q':
      printf ("Current filename is  %s%s\n", filename,
	      Class==is_oth ? "" : srcext()) ;
    break;
    default: ;
  }
}                                                       /*  f i l e c m d  */
                                                        /*-----------------*/


/* PJ 31.03.95  #ifdef LINT_ARGS added */
                                                              /*-----------*/
#ifdef LINT_ARGS
static void edit( char* name, char * ext )
#else
static void edit (name, ext)                                  /*  e d i t  */
  char * name;
  char * ext;
#endif
{
  char ed_call[100];

  strcpy (ed_call, ed_name);
  strcat (ed_call, " ");
  strcat (ed_call, name);
  strcat (ed_call, ext);

  if (on_debug)   printf ("e= %s\n", ed_call) ;

  retc = system (ed_call);
  if  (retc)   printf ("\nEditor returned with return code %d.\n", retc) ;
}

/* PJ 31.03.95  #ifdef LINT_ARGS added */

                                                      /*-------------------*/
#ifdef LINT_ARGS
static void printcmd( char* name, char* ext )
#else
static void printcmd (name, ext)                      /*  p r i n t c m d  */
  char * name;
  char * ext;
#endif
{
  char pr_call[100];

  strcpy (pr_call, pr_command);
  strcat (pr_call, " ");
  strcat (pr_call, name);
  strcat (pr_call, ext);

  if (on_debug)   printf ("print= %s\n", pr_call) ;

  retc = system (pr_call);
  if  (retc)   printf ("\nPrint returned with return code %d.\n", retc) ;
}

                                                              /*-----------*/
static void   link ()                                         /*  l i n k  */
{ char * p;
  char buf [20];
/*  strcpy (fn, filename); */
/*  strcat (fn, lnkfext);  */
/*  lnkfile = fopen (fn, "r"); */
  if (Class == is_mod)  {
    printf ("\n%s is module : no linker call\n", filename);
    screenisclear = false ;
    return ;
  } ;

  p = linkstring (prgname) ;    /* create link command string */
  if  (not p)   return ;        /* return if fails */

  if (on_debug)   printf ("link= %s\n", p) ;

  retc = system (p);            /* system call of Linker */

  if (ok_retc ? (retc==0) : exist (exefnam(), ""))
  {
    if (verbose)
      printf ("\nLinkage complete. \n");
    if (on_remove)
      remove (objmain()) ;
    if (not off_remove)
      remove (linkinfo ) ;
  } else
  {
    if (verbose)
      printf ("\nLinker unsuccessful. \n");
  }

#if GNU_386_C
  append_stub();
#endif
  screenisclear = false ;
}                                                             /*  l i n k  */
                                                              /*-----------*/


                                                              /*-------------*/
static void  batch ()                                         /*  b a t c h  */
{
  FILE * lnkfile;
  FILE * batfile;
  char   fn[100];
  char * oldname = filename ;
  char * p ;
  boolean diff ;   /* linkinfo different from current filename */
  int    c;
  int    i;

  off_remove = true ;  /* prevents delete linkinfo */

  if (prgname and *prgname)
    if (strcmp (filename, prgname) != 0)   {    /* compare filenames */
       if (switchfile(prgname)) return ;
    }

/*  strcpy (fn, filename); */
/*  strcat (fn, lnkfext);  */
/*  lnkfile = fopen (fn, "r"); */
  lnkfile = fopen (linkinfo, "r");
  if (not lnkfile)   {
    printf (" No pascal program compiled. First compile a PASCAL-XSC main program.\n") ;
    if  (oldname != filename)   (void) switchfile(oldname) ;
    return ;
  }
  p88_fgets (fn, 256, lnkfile) ;        /* read source name from linkinfo */
  fclose (lnkfile) ;
  if (fn [strlen(fn)-1] == '\n')
      fn [strlen(fn)-1] = '\0' ;        /* delete newline char */

  if  (prgname and *prgname)
    diff =  strcmp (objmain(), fn) != 0 ; /* compare filenames */
  else   diff = true ;

  fn [strlen(fn)-objelen()] = '\0' ;    /* delete extension */

  if (diff)   {
     if ( prgname and *prgname)
      printf ("Warning: Program  %s  is  not  the current main program  %s\n",
	      fn, filename) ;
     if (switchfile (fn))  {    /* failed */
       if  (oldname != filename)   (void) switchfile(oldname) ;
       return ;         /* switch back and leave */
     }
  }

  batfile = fopen (batname, "w") ;
  if  (not batfile)  {
    printf ("Can not write on file %s\n", batname) ;
    if  (oldname != filename)   (void) switchfile(oldname) ;
    return ;
  }
  fprintf (batfile, "%s %s ", c_command, pre_c_opt) ;
 /* fprintf (batfile, "%s ",  c_opt);     only in comp! */

  if (inc_c_opt) {
      p=getenv(P88SYS);
      fprintf (batfile, "%s%s ", inc_c_opt, (p)?p:sysdir);
    }
  fprintf (batfile, "%s %s\n", codfnam(), post_c_opt);

  p = linkstring (prgname) ;
  if (p)  fprintf (batfile, p) ;
  fprintf (batfile, "\n") ;
  fclose (batfile);

#if UNIXsys
  strcpy (sys_call, "chmod +x ") ;
  strcat (sys_call, batname) ;
  system (sys_call) ;
#endif

#if INDIRECT
  if  (p)
    printf ("Option file  %s  created for program  %s\n",
	    loptname, exefnam()) ;
#endif
  if  (p)
  printf ("Batch  file  %s  created for program  %s\n",
	  batname, exefnam()) ;
  if  (oldname != filename)   (void) switchfile(oldname) ;
}                                                             /*  b a t c h  */
                                                              /*-------------*/


                                                              /*-----------*/
static void  comp ()                                          /*  c o m p  */
{
  char *p;
  char p_opt[128], * c_opt ;

  if (Class == is_oth)  {
    printf ("\nCannot compile non-Pascal file %s !\n", filename) ;
    return ;
  }

  if (! exist ( srcfnam(),"")) {
     printf ("\nPascal source file %s  n o t  found.\n", srcfnam()) ;
     screenisclear = false ;
     return ;
  }

  p = p_opt;
  while  (tty != '\n' and tty != ';' and tty != EOF)
   {                                       /* scan PASCAL options */
    *p = tty ; tty = getchar ()  ;   p++ ;
   }
  *p = '\0';

  if  (tty == ';')   tty = getchar () ;
  c_opt = scan();                          /* scan C options */

  if (binpath)
    strcpy (sys_call, binpath);
  else  *sys_call = '\0' ;
  strcat (sys_call, p88_name);
  strcat (sys_call, " ");
  strcat (sys_call, p_opt);
  strcat (sys_call, " ");
  strcat (sys_call, filename);

  if (on_debug)   printf ("P-Call= %s \n", sys_call) ;

  retc = system (sys_call);             /* call of p88-pre-compiler */

  if (exist (linkinfo, ""))  {
    Class = is_prg ;
    setClass() ;
    prgname = filename ;
  } else {
    Class = is_mod ;
    setClass() ;
    modname = filename ;
  }

  if (not (ok_retc ? (retc==0) : exist ( codfnam(), "")))
  {
    if (verbose)
      printf ("\nPascal Compilation unsuccessful. \n\n");
    if (binpath)
      strcpy (sys_call, binpath);
    else  *sys_call = '\0' ;
    strcat (sys_call, e88_name);
    if (on_debug)   printf ("List-call= %s \n", sys_call) ;

    retc = system (sys_call);         /* system call of Listing generator */
    if  (retc)   printf (
         "\nListing generator returned with return code %d.\n", retc) ;
  }
  else
  {
    char s [100] ;

    savesrc = true ;
    if (verbose)
      printf ("Pascal Compiler successful\n");
    remove (lstfnam()) ;

    strcpy (sys_call, c_command);
    strcat (sys_call, " ");
    strcat (sys_call, pre_c_opt);
    strcat (sys_call, " ");
    strcat (sys_call, c_opt);
    strcat (sys_call, " ");
    free (c_opt) ;

    if (inc_c_opt) {
      p=getenv(P88SYS);
      strcat(sys_call, inc_c_opt);
      strcat(sys_call,(p)?p:sysdir);
      strcat (sys_call, " ");
    }

    strcat (sys_call, codfnam());
    strcat (sys_call, " ");
    strcat (sys_call, post_c_opt);

    if (on_debug)   printf ("cc= %s\n", sys_call) ;

    retc = system (sys_call);           /* system call of C-compiler */

    if (ok_retc ? (retc==0) : exist (objmain(), ""))
    {
      if (verbose)
	printf ("C-compiler successful\n");
      if (on_remove)
	remove ( codfnam()) ;
      link() ;
    }
    else {
      if (verbose)
        printf ("\nC-compiler unsuccessful : errors occured in compile\n");
    }
  } /* Pascalcomp OK */
  screenisclear = false ;
}                                                             /*  c o m p  */
                                                              /*-----------*/


                                                              /*-----------*/
static void   list()                                          /*  l i s t  */
{
 char fn [256] ;
 char * answer ;
 FILE * f ;

 f = fopen (errfnam(), "r") ;
 if  (f)
 {                                           /* first check source file */
  p88_fgets (fn, 256, f) ;                   /* read source name from errmess */
  fclose (f) ;
  fn [strlen(fn)-1-strlen(srcext())] = '\0' ; /* clear file extension and \n */
  if  (strcmp (filename, fn) != 0) {         /* differs from current file? */
    if  (switchfile (fn))   return ;
    printf ("\nCurrent file changed to %s\n", srcfnam()) ;
  }

  printf ("\nCreating PASCAL-XSC listing file %s\n", lstfnam());
  if (binpath)
    strcpy (sys_call, binpath);
  else  *sys_call = '\0' ;
  strcat (sys_call, lister) ;
  strcat (sys_call, " OUTPUT=");
  strcat (sys_call, lstfnam());

  if (on_debug)   printf ("list= %s\n", sys_call) ;

  retc = system (sys_call);             /* call of p88-listing generator */
  if  (retc)   printf ("\nListing generator returned with return code %d.\n", retc) ;

  strcpy (sys_call, ed_name);
  strcat (sys_call, " ");
  strcat (sys_call, lstfnam());

  if (on_debug)   printf ("e= %s\n", sys_call) ;

  retc = system (sys_call);             /* Editor call */
  if  (retc)   printf ("\nEditor returned with return code %d.\n", retc) ;

  printf ("Do you really want your Pascal Source file  %s\n", srcfnam()) ;

  printf (" to be reconstructed from the listing file  %s   (y/n)?", lstfnam()) ;
  fflush (stdout) ;
  READLN ;
  tty = getchar () ;
  if  ( tty != 'y' and  tty != 'Y')
   { READLN ;
     screenisclear = true ;
     return ;                           /* leave list command */
   }
  READLN ;

#if  i860_HIGH_C==0
  if  (savesrc) {
    printf ("\nSaving old pascal source to %s%s\n", filename, savfext) ;
    strcpy (sys_call, srcfnam());
    strcpy (fn      , filename);
    strcat (fn      , savfext);
    retc = rename (sys_call, fn);          /* save source file */
    if  (retc)   printf ("Failed to save source file\n") ;
    else
       savesrc = false ;
  }
#endif

  if (binpath)
    strcpy (sys_call, binpath);
  else  *sys_call = '\0' ;
  strcat (sys_call, l2p_command);
  strcat (sys_call, " ");
  strcat (sys_call, lstfnam());
  strcat (sys_call, " ");
  strcat (sys_call, srcfnam());

  if (on_debug)   printf ("l2p= %s\n", sys_call) ;

  retc = system (sys_call);            /* create a new source from listing */
  if  (retc)   printf ("\nSource rebuilder returned with return code %d.\n", retc) ;
  else   printf ("\nPascal source %s updated\n", srcfnam()) ;
 } else
  printf (" No listing to edit\n") ;
  screenisclear = false ;
}                                                             /*  l i s t  */
                                                              /*-----------*/


                                                              /*-----------*/
static void   run ()                                          /*  r u n    */
{ char * oldname = filename ;
  char * p ;

  if  (prgname == NULL) {
    printf ("No program available\n") ;
    return ;
  }
  if  (strcmp (filename, prgname) != 0)  /* differs from current file? */
    if  (switchfile (prgname))   return ;
  if  (r_command)                           /* run command */
    strcpy (sys_call, r_command);
  else   *sys_call = '\0' ;  /* set empty */

  p = exefnam() ;
#if 0 /* VAX_VMS_C    done by exefnam */
  if  (*p != '[')   strcat (sys_call, "[]") ;
#endif
  strcat (sys_call, p);
  strcat (sys_call, " ");
  if (params)   strcat (sys_call, params);
  printf ("running  %s\n\n", sys_call) ;

  retc = system (sys_call);            /* run compiled program */
  if  (retc)   printf ("\n%s returned with return code %d.\n",
			  exefnam(), retc) ;
  printf ("\n") ;
  if  (oldname != filename)   (void) switchfile(oldname) ;
}                                                             /*  r u n    */
                                                              /*-----------*/

                                                        /*---------------*/
static void   syscmd()                                  /*  s y s c m d  */
{
  char * cmd = NULL ;

  ask (" System command ", &cmd) ;
  printf ("running  %s\n\n", cmd) ;
#if OWN_SYSTEM
#undef system
       /* spawn does not work with internal commands */
#endif
  retc = system (cmd);
#if OWN_SYSTEM
#define system   msc_system
#endif
  if  (retc)   printf ("\nSystem call returned with return code %d.\n", retc) ;
  free (cmd) ;
  printf ("\n") ;
}                                                        /*  s y s c m d  */
                                                         /*---------------*/


/******************/
/*  main program  */
/******************/

/* PJ 31.03.95  #ifdef LINT_ARGS added */

                                                              /*-----------*/
#ifdef LINT_ARGS
int main( int argc, char* argv[] )
#else
int main (argc, argv)                                         /*  m a i n  */
  int   argc;
  char *argv[];
#endif
{
static char * mainprompt = "Command (f/e/p/c/m/b/r/y/q/d/h/o/l) or ? for help : " ;
  int i,j ;
  int cmd, subcmd ;   /* command chars */
  char * p ;

  printf ("\n   PASCAL-XSC to C   Development System\n\n");

  libinit() ;
  p = setdefault () ;
  if (on_debug)   if (p)   printf ("Configuration file %s found\n", p) ;

  hlpinit (HLPfnam) ;

  if  (not ok_retc and (not on_remove or  on_code and os_code))
     helpon ('R') ;

  off_remove = not on_remove ; /* prevents delete linkinfo */
  for (i=0; i<10; i++)   slot[i].name = NULL, slot[i].Class = is_oth ;

#ifdef ANSI
  if  (system(NULL)==0) {
    printf ("There is no command processor available.\nProgram terminated.\n") ;
    exit (1) ;
  }
#endif

  p = getenv (P88EDIT) ;
  if  (p)   ed_name = p ;
  if  (ed_name == NULL)   /* P88EDIT not defined */
   {
     ask (" Editorname ", &ed_name) ;
     if  (ed_name and *ed_name)
      { char cmd [128] ;
        strcpy (sys_call, setenvcmd) ;
        strcat (sys_call, " ") ;
        strcat (sys_call, P88EDIT) ;
        strcat (sys_call, setenvdelim) ;
        strcat (sys_call, ed_name) ;
	strcpy (cmd, sys_call) ;
        retc = system (sys_call) ;
        if  (retc)   printf ("\n%s returned with return code %d.\n",
                             setenvcmd, retc) ;
        printf (" Put the command \n    %s\n into your  %s  to suppress this request.\n",
		  cmd, profile) ;
        screenisclear = false ;
      }
   }

  for (i=1; i<argc; i++)               /* 0th argument is program-name */
    if (argv[i][0] != '_' and argv[i][0] != '+' and argv[i][0] != '-') {
      /* PJ 31.03.95  cast to char* added */
      filename = ( char* ) malloc (strlen (argv[i]) + 1) ;
      strcpy (filename, argv[i]) ;
      whichClass () ;
      j = clrslot() ;
      if  (j == -1)   break ;
      slot[j].name  = filename ;
      slot[j].Class = Class ;
    }

  if  (filename == NULL or  *filename =='\0')  {
      ask (" Filename ", &filename) ;
      whichClass() ;
      j = clrslot() ;
      slot[j].name  = filename ;
      slot[j].Class = Class ;
    }

  if (mainmenu)  {
     clearscreen () ;
     helpon ('D') ;
  }
  printf ("  Current file is %s%s\n",
	     filename, (Class==is_oth ? "" : srcext())) ;
  prompt (mainprompt);
  while((tty!='q') and (tty!='Q')) {
    cmd = readtty () ;
    screenisclear = false ;  /* save screen to show errormessages */
    switch (cmd) {

      case    'f':
        filecmd () ;
        screenisclear = true ;    /* screen may be cleared */
      break;

      case    'e':
        if  (tty == '\n')
          if  (Class == is_oth)
             edit (filename, "");
          else
	     edit (srcfnam(), "");
        else
          {  char * fn = scan () ;
             edit (fn, "") ;
             free (fn) ;
          }
        if (mainmenu)
          printf ("\n   <<< Check for errormessages and then >>>") ;
      break;

      case    'p':
        if  (tty == '\n')
          if  (Class == is_oth)
             printcmd (filename, "");
          else
	     printcmd (filename, srcext());
        else
          {  char * fn = scan () ;
             printcmd (fn, "") ;
             free (fn) ;
          }
      break;

      case    'c':   case    'm':
        comp () ;
      break;

      case    'b':
        batch () ;
      break;

      case    'l':
        list ();
      break;

      case    'r':
        if (tty == 'r' or tty == 'R')  {
          subcmd = readtty () ;
          run () ;
        } else  {
          ask (" Program parameters ", &params) ;
          run () ;
        }
      break;

      case    'y':
        if (tty == '\n') {
          printf ("\nType  %s  to return to the PASCAL-XSC development System\n",
                  sysreturn) ;
          retc = system (sh_command) ;
          if  (retc)   printf ("\nShell returned with return code %d.\n", retc) ;
          screenisclear = true ;    /* screen may be cleared */
        } else  {
          syscmd () ;
        }
      break;

      case    'd':
        mainmenu = not mainmenu ;
        screenisclear = true ;    /* screen may be cleared */
      break;

      case    '?':
        helpon ('?') ;
	if  (not mainmenu)
	  printf("   Enter the letter \"d\" to display the main menu.\n\n") ;
      break;

      case    'h':
	if (tty == '\n')   helpon ('H') ;
	do   {
	  prompt ("Help on (f/e/p/c/m/b/r/y/q/h/o/l) or ? for help : ");
	  subcmd = readtty () ;
	  if  (subcmd != '?')   break ;
	  helpon ('H') ;
	} while  (subcmd == '?') ;
	helpon (subcmd) ;
	printf ("\nNow you are back in the main menu.\n") ;
	break;

      case    'o':
	if (tty == '\n')   helpon ('O') ;
        do   {
	  prompt ("Option command (c/e/l/t/h/q) or ? for help : ");
          subcmd = readtty () ;
	  if  (subcmd != '?' and subcmd != 'h')   break ;
	  helpon ('O') ;
	} while  (true) ;

	switch (subcmd) {
	  case    't':  on_debug = ! on_debug ;
			printf ("\nTest output %sabled\n",
				on_debug ? "en" : "dis") ;
	  break ;

	  case    'c':
	      if (binpath)
		strcpy (sys_call, binpath);
	      else  *sys_call = '\0' ;
	      strcat (sys_call, cfg_name) ;
	      if (on_debug)   printf ("cfg= %s\n", sys_call) ;
	      retc = system (sys_call) ;
	      printf ("\nLeaving Configuration program\n") ;
	      if (retc) printf ("\nCfg returned with return code %d.\n", retc) ;
	      p = setdefault () ;
	      if (p)  printf ("Configuration file %s read.\n", p) ;
	      if  (not ok_retc and (not on_remove or  on_code and os_code))
		 helpon ('R') ;
	  break ;

	  case    'e':
	      if (getenv(P88EDIT))
		printf (" Note: Environment variable %s is in use.\n", P88EDIT) ;
	      p = ed_name ;
	      if (tty=='\n')   printf ("Enter RETURN for no change\n") ;
	      ask (" Editorname ", &p) ;
	      if  (*p)   ed_name = p ;
	      else
		begin
		  free (p) ;
		  printf (" Editorname unchanged.\n") ;
		end
	  break ;

	  case    'l':
#if ATARI_TURBO_C
	      printf ("Edit the file %spost.lnk\n",
		      getenv (P88SYS) ? getenv (P88SYS) : sysdir) ;
#else
	      if (getenv(P88LIB))
		printf (" Note: Environment variable %s is in use.\n", P88LIB) ;
	      p = p88_lib ;
	      if (tty=='\n')   printf ("Enter RETURN for no change\n") ;
	      ask (" Library ", &p) ;
	      if  (*p)   p88_lib = p ;
	      else
		begin
		  free (p) ;
		  printf (" Library unchanged.\n") ;
		end
#endif
	  break ;

	  case    'q':    break ;
	  default:
	      READLN ;
	      printf("Unknown option command: %c = 0x%x\n",
		     (char)subcmd, subcmd);
	}
        break;

      default:
	  READLN ;
          printf("Unknown command: %c = 0x%x\n", (char)cmd, cmd);
    }  /* switch */
  if(tty==EOF) break;

  if (mainmenu)  {
     clearscreen () ;
     helpon ('D') ;
  }
  printf ("  Current file is %s%s\n",
	     filename, (Class==is_oth ? "" : srcext())) ;
  prompt(mainprompt);
  }  /* until quit or exit */

  return (0) ;
END /* main */
