/*
 *   PROGRAM: mxsc.c
 *   Batch manager of the PASCAL-XSC Compiler
 *
{*  last modification:	02.04.92  16:50   }

 * uli 08.08.91 : run: p and VAX_VMS added.
 * uli 05.09.91 : run: VAX_VMS removed, because "[]" added by exefnam.
		  filename is extern now, prgname removed.
 * uli 05.09.91 : "verbose" flag respected.
 * uli 13.09.91 : binpath added.
 * uli 07.02.92 : main: help message improved.
 * uli 02.04.92 : append_stub called, statements moved to depend.c
 * PJ  31.03.95 : #ifdef LINT_ARGS added for edit, main.
*/

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

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


#define global extern

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


#ifdef LINT_ARGS
static  void    wait    (void);
static  void    comp    (void);
static  void    link    (void);
static  int     type    (void);
static  int     list    (void);
static  void    edit    (char *, char *);
#else
static  void    wait    ();
static  void    comp    ();
static  void    link    ();
static  int     type    ();
static  int     list    ();
static  void    edit    ();
#endif
static  int    retc;

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

static  char fnbuff[FILENAME_MAX] ; /* buffer for filename without extension */
extern  char * filename ;       /* declared in depend.c */
char   user_c_opt [100] = " ";

/*-----------------------------------------------------*/
/*----------------  implementation  -------------------*/
/*-----------------------------------------------------*/

                                                              /*-----------*/
static void wait ()                                           /*  w a i t  */
{
  printf ("press <ENTER> to go on");
  while (getchar () != '\n') ;
  printf ("\n");
}                                                             /*  w a i t  */
                                                              /*-----------*/



                                                              /*-----------*/
static void   comp()                                          /*  c o m p  */
{
  char *p;
  strcpy (sys_call, c_command);
  strcat (sys_call, " ");
  strcat (sys_call, pre_c_opt);
  strcat (sys_call, user_c_opt);
  strcat (sys_call, " ");

  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);

}                                                             /*  c o m p  */
                                                              /*-----------*/




                                                              /*-----------*/
static void   link ()                                         /*  l i n k  */
{ char * p;
char buf [20];
/*  strcpy (fn, lnkfnam());  */
/*  lnkfile = fopen (fn, "r"); */

  p = linkstring (filename) ;   /* 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()) ,
      remove (linkinfo ) ;
  } else
  {
    if (verbose)
      printf ("\nLinker unsuccessful. \n");
    exit(4);
  }

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


							      /*-----------*/
static int    list()                                          /*  l i s t  */
{
  if (binpath)
    strcpy (sys_call, binpath);
  else  *sys_call = '\0' ;
  strcat (sys_call, e88_name);
  strcat (sys_call, " ");
  strcat (sys_call, srcfnam());
  strcat (sys_call, " ");
  strcat (sys_call, lstfnam());

  if  (on_debug)   printf ("list= %s\n", sys_call) ;
  if (sys_call)
    return (1);
  else
    return (0);
}                                                             /*  l i s t  */
							      /*-----------*/



							      /*-----------*/
static int    type()                                          /*  t y p e  */
{
  strcpy (sys_call, t_command);
  strcat (sys_call, " ");
  strcat (sys_call, lstfnam());

  if  (on_debug)   printf ("type= %s\n", sys_call) ;
  if (sys_call)
    return (1);
  else
    return (0);
}                                                             /*  t y p e  */
							      /*-----------*/

/* PJ 31.03.95  #ifdef LINT_ARGS added */
#ifdef LINT_ARGS
static void edit( char* name, char* ext )
#else
static void edit (name, ext)
  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 ("ed= %s\n", ed_call) ;
  system (ed_call);
}

/* 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
{
  char * p , * envname;
  int    i;
  int    go_on  = 0;

  int    do_wait = 0;
  int    do_edit = 0;
  int    do_outp = 0;
  int    do_exec = 0;

  int    is_prog = 0;

  filename = fnbuff ;
  libinit() ;

  if (argc < 2) {
    printf ("\n");
    printf ("Syntax : %s [opt] [_v] [_e] [_x] pascalfile\n", argv[0]);
    printf ("\n");
    printf ("  opt are options for the PASCAL-XSC COMPILER\n");
 /* printf ("  _w    : wait between steps \n");            */
    printf ("  _e    : edit source-file before compilation \n");
    printf ("  _v    : suppress manager infos \n");
    printf ("  _t    : display commands as executed \n");
    printf ("  _c... : add a C-compiler option\n");
    printf ("  _x    : execute program after linkage\n");
    printf ("\n");
    if (binpath)
      strcpy (sys_call, binpath);
    else  *sys_call = '\0' ;
    strcat (sys_call, p88_name);
    system (sys_call) ; /* Compiler call to display options */
    exit (-1);
  }

  envname = setdefault () ;

  p = getenv (P88EDIT) ;
  if  (p)   ed_name = p ;
  if  (ed_name == NULL)   /* P88EDIT not defined */
   {
     printf (" No editor available. Define the environment variable %s.\n",
	     P88EDIT) ;
   }

  if (binpath)
    strcpy (sys_call, binpath);
  else  *sys_call = '\0' ;
  strcat (sys_call, p88_name);
  for (i=1; i<argc; i++) {              /* 0th argument is program-name */
    if (argv[i][0] != '_') {
      strcat (sys_call, " ");           /* append p88-options and filename */
      strcat (sys_call, argv[i]);       /* to name of p88-pre-compiler */
      if (argv[i][0] != '+' && argv[i][0] != '-')
	strcpy (filename, argv[i]) ,
	fnaminit (argv[i]);
    }
    else {
      switch (argv[i][1]) {
        case 'w' :    do_wait = 1; break;
        case 'e' :    do_edit = 1; break;
	case 'c' :    strcat (user_c_opt, argv[i]+2) ;
		      strcat (user_c_opt, " ") ;
		      break;
	case 'o' :    do_outp = 1; break;
	case 'v' :    verbose = 0; break;
	case 't' :    on_debug = 1; break;
        case 'x' :    do_exec = 1; break;
        default  :    printf ("option not valid\n"), exit (-1);
      }
    }
  }

  if  (on_debug)
    if (envname)   printf ("Configuration file %s found\n", envname) ;
	   else    printf ("Configuration file not found\n") ;

  if  (verbose)
     printf ("Manager for the PASCAL-XSC to C Compiler\n");


  if (do_edit) {
    edit (srcfnam(), "");
    if (do_wait)
      wait ();
  }

  if (! exist ("", srcfnam())) {
     printf ("Pascal source file %s not found.\n", srcfnam()) ;
     exit (-1) ;
  }

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

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

  if (ok_retc) {                        /* if use of retc-value is possible */
    go_on = (retc==0);                  /* retc==0 means no errors */
  }
  else {
    go_on = exist ("", codfnam());
  }

  if (go_on) {
    if (verbose)
      printf ("Pascal Compiler successful\n");
    remove (lstfnam()) ;
  }
  else {
    if (verbose)
      printf ("\nPascal Compilation unsuccessful. \n\n");
    if (list())                         /* side-effects : changes sys_call */
      retc = system (sys_call);         /* system call of Listing generator */
    if (type())                         /* side-effects : changes sys_call */
      retc = system (sys_call);         /* system call of Type Listing */
    if (verbose)
      printf ("\nThis Listing is placed in file %s\n", lstfnam()) ;

    exit (2);
  }

  is_prog = exist (linkinfo, "");

  if (do_wait)
    wait ();

  if (do_outp) {
    if (exist ("", codfnam()))
      edit ("", codfnam());
    if (exist ("", dclfnam()))
      edit ("", dclfnam());
    if (exist ("", lstfnam()))
      edit ("", lstfnam());

    if (do_wait)
      wait ();
  }


  comp() ;                            /* side-effects : changes sys_call */

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

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

  if (ok_retc) {                        /* if use of retc-value is possible */
    go_on = (retc==0);                  /* retc==0 means no errors */
  }
  else {
    go_on = exist ("", objmain());
  }

  if (go_on) {
    if (verbose)
      printf ("C-compiler successful\n");
    if (on_remove)
      remove ( codfnam()) ;
  }
  else {
    if (verbose)
      printf ("\nC-compiler unsuccessful : errors occured in compile\n");
    exit (3);
  }

  if (do_wait)
    wait ();

  if (is_prog){
    link();
  }else {
     printf ("\n%s is module : no linker call\n", filename);
  }

  if (do_wait)
    wait ();

  if (do_exec) {
    char * p = exefnam();

    if (exist ("", p))
      if  (r_command)  {
	strcpy (sys_call, r_command) ;
#if 0 /* VAX_VMS_C    done by exefnam */
	if (*p != '[')   strcat (sys_call, "[]") ;
#endif
	strcat (sys_call, p) ;

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

	system (sys_call) ;
      }
      else {

	if  (on_debug)   printf ("run= %s\n", exefnam()) ;

	system (exefnam());
      }
    else
      printf ("no executable file\n");
  }

  return (0);
}                                                              /*  m a i n  */
                                                               /*-----------*/
