289 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			289 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/*************************************************************************
 | 
						|
 *
 | 
						|
 *  m a k e :   m a i n . c
 | 
						|
 *
 | 
						|
 *========================================================================
 | 
						|
 * Edition history
 | 
						|
 *
 | 
						|
 *  #    Date                         Comments                       By
 | 
						|
 * --- -------- ---------------------------------------------------- ---
 | 
						|
 *   1    ??                                                         ??
 | 
						|
 *   2 01.07.89 strcmp(makefile,..) only if makefile a valid ptr.    RAL
 | 
						|
 *   3 23.08.89 initname() added                                     RAL
 | 
						|
 *   4 30.08.89 argument parsing impr., indention ch., macro fl. add.PSH,RAL
 | 
						|
 *   5 03.09.89 k-option added, initname -> init changed             RAL
 | 
						|
 *   6 06.09.89 environment, MAKEFLAGS, e,d,a options added,         RAL
 | 
						|
 *   7 09.09.89 tos support added, fatal args added, fopen makefile  PHH,RAL
 | 
						|
 *   8 17.09.89 setoptions fixed for __STDC__                        RAL
 | 
						|
 * ------------ Version 2.0 released ------------------------------- RAL
 | 
						|
 *
 | 
						|
 *************************************************************************/
 | 
						|
 | 
						|
/*
 | 
						|
 *	make:
 | 
						|
 *
 | 
						|
 *	-a try to guess undefined ambiguous macros (*,<)
 | 
						|
 *	-d print debugging info
 | 
						|
 *	-e environment macro def. overwrite makefile def.
 | 
						|
 *	-f makefile name
 | 
						|
 *	-i ignore exit status
 | 
						|
 *	-k continue on errors
 | 
						|
 *	-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
 | 
						|
 *	-m Change memory requirements (EON only)
 | 
						|
 */
 | 
						|
 | 
						|
#define EXTERN
 | 
						|
#define INIT(x) = x
 | 
						|
#define INITARRAY
 | 
						|
#include "h.h"
 | 
						|
 | 
						|
static char version[]= "2.0";
 | 
						|
 | 
						|
static FILE *ifd;           /*  Input file desciptor  */
 | 
						|
static char *ptrmakeflags;
 | 
						|
 | 
						|
/* There must be enough 'space' for all possible flags ! */
 | 
						|
static char  makeflags[] = "MAKEFLAGS=                    ";
 | 
						|
 | 
						|
void main(argc, argv)
 | 
						|
int    argc;
 | 
						|
char **argv;
 | 
						|
{
 | 
						|
  register char        *p;		/*  For argument processing  */
 | 
						|
  int                   estat = 0;	/*  For question  */
 | 
						|
  register struct name *np;
 | 
						|
  struct macro         *mp;
 | 
						|
  int                   targc;		/* temporary for multiple scans */
 | 
						|
  char                **targv;
 | 
						|
  char                **nargv;		/* for removing items from argv */
 | 
						|
  char                **envp;      /* enivironment ptr */
 | 
						|
 | 
						|
 | 
						|
  ptrmakeflags = &makeflags[10];
 | 
						|
  myname = (argc-- < 1) ? "make" : *argv++;
 | 
						|
#ifdef tos
 | 
						|
  myname = "Make";
 | 
						|
#endif
 | 
						|
 | 
						|
  targc = argc;
 | 
						|
  targv = nargv = argv;
 | 
						|
  while (targc--) {
 | 
						|
	if((p = strchr(*targv, '=')) != (char *)NULL) {
 | 
						|
		*p = '\0';
 | 
						|
		mp = setmacro(*targv, p + 1);
 | 
						|
		mp->m_flag |= M_OVERRIDE;
 | 
						|
		--argc;
 | 
						|
	} else
 | 
						|
		*nargv++ = *targv;
 | 
						|
 | 
						|
	++targv;
 | 
						|
  }
 | 
						|
 | 
						|
  targc = argc;
 | 
						|
  targv = nargv = argv;
 | 
						|
  while (targc--) {
 | 
						|
	if (**targv == '-') {
 | 
						|
		--argc;
 | 
						|
		p = *targv++;
 | 
						|
		while (*++p != '\0') {
 | 
						|
			switch(mylower(*p)) {
 | 
						|
			case 'f':	/*  Alternate file name  */
 | 
						|
				if (*++p == '\0') {
 | 
						|
					--argc;
 | 
						|
					if (targc-- == 0)
 | 
						|
						usage();
 | 
						|
					p = *targv++;
 | 
						|
				}
 | 
						|
				makefile = p;
 | 
						|
				goto end_of_args;
 | 
						|
#ifdef eon
 | 
						|
			case 'm':	/*  Change space requirements  */
 | 
						|
				if (*++p == '\0') {
 | 
						|
					--argc;
 | 
						|
					if (targc-- <= 0)
 | 
						|
						usage();
 | 
						|
					p = *targv++;
 | 
						|
				}
 | 
						|
				memspace = atoi(p);
 | 
						|
				goto end_of_args;
 | 
						|
#endif
 | 
						|
			default :
 | 
						|
				setoption(*p);
 | 
						|
				break;
 | 
						|
			}
 | 
						|
		}
 | 
						|
	end_of_args:;
 | 
						|
	} else
 | 
						|
		*nargv++ = *targv++;
 | 
						|
  }
 | 
						|
 | 
						|
  /* evaluate and update environment MAKEFLAGS */
 | 
						|
  if((p =getenv("MAKEFLAGS")) != (char *)0)
 | 
						|
	while(*p) setoption(*p++);
 | 
						|
  for( p = ptrmakeflags; !isspace((int)*p); p++) ;
 | 
						|
  *p = '\0';
 | 
						|
  putenv(makeflags);
 | 
						|
 | 
						|
 | 
						|
#ifdef eon
 | 
						|
  if (initalloc(memspace) == 0xffff)  /*  Must get memory for alloc  */
 | 
						|
	fatal("Cannot initalloc memory",(char *)0,0);
 | 
						|
#endif
 | 
						|
 | 
						|
  if (makefile && strcmp(makefile, "-") == 0)  /*   use stdin as makefile  */
 | 
						|
	ifd = stdin;
 | 
						|
  else if (!makefile) {    /*  If no file, then use default */
 | 
						|
	if ((ifd = fopen(makefile = DEFN1, "r")) == (FILE *)0) {
 | 
						|
		if (errno != MNOENT || !DEFN2)
 | 
						|
			fatal("Can't open %s: %s", DEFN1, errno);
 | 
						|
		else if ((ifd = fopen(makefile = DEFN2, "r")) == (FILE *)0)
 | 
						|
			fatal("Can't open %s: %s", DEFN2, errno);
 | 
						|
	}
 | 
						|
  }
 | 
						|
  else if ((ifd = fopen(makefile, "r")) == (FILE *)0)
 | 
						|
	fatal("Can't open %s: %s", makefile, errno);
 | 
						|
 | 
						|
  init();
 | 
						|
 | 
						|
  makerules();
 | 
						|
 | 
						|
  mp = setmacro("MAKE", myname);
 | 
						|
  mp->m_flag |= M_MAKE;
 | 
						|
  setmacro("$", "$");
 | 
						|
 | 
						|
  /* set environment macros */
 | 
						|
  envp = environ; /* get actual environment ptr. */
 | 
						|
  while (*envp) {
 | 
						|
	if((p = strchr(*envp, '=')) != (char *)NULL) {
 | 
						|
		*p = '\0';
 | 
						|
		mp = setmacro(*envp, p + 1);
 | 
						|
		*p = '=';
 | 
						|
		if (useenv) mp->m_flag |= M_OVERRIDE;
 | 
						|
	} else
 | 
						|
		fatal("invalid environment: %s",*envp,0);
 | 
						|
 | 
						|
	++envp;
 | 
						|
  }
 | 
						|
 | 
						|
  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",(char *)0,0);
 | 
						|
 | 
						|
  circh();	/*  Check circles in target definitions  */
 | 
						|
 | 
						|
  if (!argc)
 | 
						|
	estat = make(firstname, 0);
 | 
						|
  else
 | 
						|
	while (argc--) {
 | 
						|
		estat |= make(newname(*argv++), 0);
 | 
						|
	}
 | 
						|
 | 
						|
  if (quest)
 | 
						|
	exit(estat);
 | 
						|
  else
 | 
						|
		exit(0);
 | 
						|
}
 | 
						|
 | 
						|
#ifdef __STDC__
 | 
						|
void setoption(char option)
 | 
						|
#else
 | 
						|
void setoption(option)
 | 
						|
char option;
 | 
						|
#endif
 | 
						|
{
 | 
						|
  register char *c;
 | 
						|
 | 
						|
  option = mylower(option);
 | 
						|
  switch(option) {
 | 
						|
	case 'n':	/*  Pretend mode  */
 | 
						|
		domake = FALSE;
 | 
						|
		break;
 | 
						|
	case 'i':	/*  Ignore fault mode  */
 | 
						|
		ignore = TRUE;
 | 
						|
		break;
 | 
						|
	case 'k':	/*  Continue on errror  */
 | 
						|
		conterr = TRUE;
 | 
						|
		break;
 | 
						|
	case 's':	/*  Silent about commands  */
 | 
						|
		silent = TRUE;
 | 
						|
		break;
 | 
						|
	case 'p':
 | 
						|
		print = TRUE;
 | 
						|
		break;
 | 
						|
	case 'r':
 | 
						|
		rules = FALSE;
 | 
						|
		break;
 | 
						|
	case 't':
 | 
						|
		dotouch = TRUE;
 | 
						|
		break;
 | 
						|
	case 'q':
 | 
						|
		quest = TRUE;
 | 
						|
		break;
 | 
						|
	case 'e':
 | 
						|
		useenv = TRUE;
 | 
						|
		break;
 | 
						|
	case 'd':
 | 
						|
		dbginfo = TRUE;
 | 
						|
		break;
 | 
						|
	case 'a':
 | 
						|
		ambigmac = TRUE;
 | 
						|
		break;
 | 
						|
	default:	/*  Wrong option  */
 | 
						|
		usage();
 | 
						|
  }
 | 
						|
  for( c = ptrmakeflags; !isspace((int)*c); c++)
 | 
						|
	if ( *c == option) return;
 | 
						|
  *c = option;
 | 
						|
}
 | 
						|
 | 
						|
void usage()
 | 
						|
{
 | 
						|
  fprintf(stderr, "Syntax: %s [{options | macro=val | target}]\n", myname);
 | 
						|
  fprintf(stderr, "Function: maintaining computer programs      V%s\n",version);
 | 
						|
  fprintf(stderr, "Options : -a : try to guess undefined ambiguous macros (*,<)\n");
 | 
						|
  fprintf(stderr, "          -d : print debugging information\n");
 | 
						|
  fprintf(stderr, "          -e : environment macro def. overwrite makefile def.\n");
 | 
						|
  fprintf(stderr, "          -f filename : makefile name (default: makefile, Makefile)\n");
 | 
						|
  fprintf(stderr, "          -i : ignore exit status of executed commands\n");
 | 
						|
  fprintf(stderr, "          -k : continue with unrelated branches on errors\n");
 | 
						|
  fprintf(stderr, "          -n : pretend to make\n");
 | 
						|
  fprintf(stderr, "          -p : print all macros & targets\n");
 | 
						|
  fprintf(stderr, "          -q : question up-to-dateness of target\n");
 | 
						|
  fprintf(stderr, "          -r : don't use inbuilt rules\n");
 | 
						|
  fprintf(stderr, "          -s : make silently\n");
 | 
						|
  fprintf(stderr, "          -t : touch files instead of making them\n");
 | 
						|
  fprintf(stderr, "Environment: MAKEFLAGS\n");
 | 
						|
  exit(1);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void fatal(msg, a1, a2)
 | 
						|
char *msg;
 | 
						|
char *a1;
 | 
						|
int   a2;
 | 
						|
{
 | 
						|
  fprintf(stderr, "%s: ", myname);
 | 
						|
  fprintf(stderr, msg, a1, strerror(a2));
 | 
						|
  fputc('\n', stderr);
 | 
						|
  exit(1);
 | 
						|
}
 |