/*
 *	make [-f makefile] [-ins] [target(s) ...]
 *
 *	(Better than EON mk but not quite as good as UNIX make)
 *
 *	-f makefile name
 *	-i ignore exit status
 *	-n Pretend to make
 *	-p Print all macros & targets
 *	-q Question up-to-dateness of target.  Return exit status 1 if not
 *	-r Don't not use inbuilt rules
 *	-s Make silently
 *	-t Touch files instead of making them
 */

#include "h.h"

char *myname;
char *prgversion = "1.04";

FILE *ifd;		/*  Input file desciptor  */
bool domake = TRUE;	/*  Go through the motions option  */
bool ignore = FALSE;	/*  Ignore exit status option  */
bool silent = FALSE;	/*  Silent option  */
bool print = FALSE;	/*  Print debuging information  */
bool rules = TRUE;	/*  Use inbuilt rules  */
bool dotouch = FALSE;   /*  Touch files instead of making  */
bool quest = FALSE;	/*  Question up-to-dateness of file  */

char *makefile = NULL;	/*  The make file  */

int main(int argc,char **argv)
{
  register char        *p;		/*  For argument processing  */
  int		       estat = 0;	/*  For question  */
  int                  arg;
  register struct name *np;
  long clockStart = clock();

  myname = argv[0];

  for (arg = 1;arg < argc;arg++)
    {
      p = argv[arg];
      if (*p++ != '-')
	break;
      while (*p != '\0')
	{
	  if (*p == 'n') {	/*  Pretend mode  */
	    domake = FALSE;
	    p++;
	    continue;
	  }

	  if (*p == 'i') {	/*  Ignore fault mode  */
	    ignore = TRUE;
	    p++;
	    continue;
	  }

	  if (*p == 's') {	/*  Silent about commands  */
	    silent = TRUE;
	    p++;
	    continue;
	  }

	  if (*p == 'p') {
	    print = TRUE;
	    p++;
	    continue;
	  }

	  if (*p == 'r') {
	    rules = FALSE;
	    p++;
	    continue;
	  }  

	  if (*p == 't') {
	    dotouch = TRUE;
	    p++;
	    continue;
	  }

	  if (*p == 'q') {
	    quest = TRUE;
	    p++;
	    continue;
	  }

	  if (*p == 'f') {	/*  Alternate file name  */
	    if (p[1] != '\0') {
	      makefile = &p[1];
	      arg ++;
	      break;		/* while (*p != 0) */
	    }
	    if (arg == argc) {
	      usage(1);
	      return -1;
	    }
	    makefile = argv[++arg];
	    break;		/* while (*p != 0) */
	  }

	  usage( (*p == 'h') ? 1 : 0);		/* help or default : ???   */

	} /* while (*p != 0) */

    } /* for (arg = 1;arg < argc;arg++) */


  if (makefile == NULL)
    makefile = DEFN1;

  ifd = fopen(makefile,"r");
  if (ifd == NULL)
    fatal("Can't open %s",makefile);

  makerules();
  setmacro("$", "$");
  setmacro("MAKEFILE",makefile);

  while (arg < argc)
    {
      char buffer[128];

      strcpy(buffer,argv[arg]);
      if ((p = strchr(buffer,'=')) == NULL)
	break;
      *p++ = '\0';
      setmacro(buffer, p);
      arg++;
    }

  input(ifd);	/*  Input all the gunga  */
  fclose(ifd);	/*  Finished with makefile  */
  lineno = 0;	/*  Any calls to error now print no line number */
  
  if (print)
    prt();	/*  Print out structures  */
  
  np = newname(".SILENT");
  if (np->n_flag & N_TARG)
    silent = TRUE;
  
  np = newname(".IGNORE");
  if (np->n_flag & N_TARG)
    ignore = TRUE;
  
  precious();
  
  if (!firstname)
    fatal("No targets defined");

  circh();	/*  Check circles in target definitions  */
  
  if (arg >= argc) {
    estat = make(firstname, 0);
  } else {
    while (arg < argc) 
      estat |= make(newname(argv[arg++]), 0);
  }
  printf("Time: %g seconds\n",(double)(clock() - clockStart)/1000.0);
  if (quest)
    exit(estat);
  else
    exit(0);
}


usage(exitvalue)
int exitvalue;
{
  fprintf(stderr, 
	  "make version %s ("__DATE__")\n"
	  "Usage:\n"
	  " %s [-f makefile] [-inpqrst] [macro=val ...] [target...]\n"
	  " Options :\n"
	  "   -f makefile name\n"
	  "   -i ignore exit status\n"
	  "   -n Pretend to make\n"
	  "   -p Print all macros & targets\n"
	  "   -q Question up-to-dateness of target.  (1 = not up to date)\n"
	  "   -r Don't not use inbuilt rules\n"
	  "   -s Make silently\n"
	  "   -t Touch files instead of making them\n"
	  "   -h This help menu\n\n", 
	  prgversion,myname); 
  exit(exitvalue);
}

void fatal(const char *msg,...)
{
  va_list msgargs;

  fprintf(stderr, "%s: ", myname);
  va_start (msgargs,msg);
  vfprintf(stderr, msg, msgargs);
  va_end (msgargs);
  fputc('\n', stderr);
  exit(1);
}

