aaz@pucc-j (Marc Mengel) (12/06/85)
Here is a (painfully) simple version of make (everyones favorite
unix utility) I hacked together for the Amiga. It only does
explicit rules, and doesn't quite figure out when it doesn't know
how to make something... but It does work. I may give it some
useful options (like make -t) in the future, but right now it
only knows -f (for a makefile other than Makefile) and -d (which
prints hoards of debug info). Included here is a sample makefile
that can be used to compile/maintain/alter it. (You will need
to change the specification of where the include librarys are...)
The following is a shell archive. Give it as input to a shell...
-----------------------------cut here--------------------------------------
sed -e "s/^X//" > Makefile << Y
XSRC = make.c vars.c rules.c
XHDR = vars.h rules.h
XOBJ = make.o vars.o rules.o
X
Xmake : ${OBJ}
X alink \
X from cbench:lib/Lstartup.obj+make.o+vars.o+rules.o \
X library cbench:lib/lc.lib+cbench:lib/amiga.lib \
X to make \
X map nil:
X
Xmake.o : make.c vars.h rules.h
X lc -icbench:include/ make.c
X
Xvars.o : vars.c vars.h
X lc vars.c
X
Xrules.o : rules.c rules.h
X lc rules.c
X
Xlist : makefile ${SRC} ${HDR}
X echo "on what?"
X
Xclean :
X rm ${OBJ}
Y
sed -e "s/^X//" > make.c << Y
X#include "rules.h"
X#include "vars.h"
X#include <stdio.h>
X#include <libraries/dos.h>
X
Xint debug;
Xlong int days, mins, secs;
X
Xmain( argc, argv )
X int argc;
X char **argv;
X{
X FILE *MakeFile;
X int i,j;
X
X printf("Make V1.0 (c) 1985 by General Overall Design.\n");
X printf("May (only) be distributed free of charge.\n");
X /* General Overall Design
X * P.O. Box 2039
X * W. Lavayette IN 47906
X */
X if( argc > 2 && strcmp(argv[1], "-f")==0 ){ /* make -f file ... */
X MakeFile = fopen( argv[2] , "r" );
X argc -= 2;
X argv += 2;
X } else
X MakeFile = fopen("makefile" , "r");
X
X if( argc > 1 && strcmp( argv[1], "-d" ) == 0 ){
X debug=1;
X argc--;
X argv++;
X printf("debug on.\n");
X }
X
X if( MakeFile == NULL ){ /* open failed */
X printf("make: can't open makefile\n");
X exit( 1 );
X }
X if ( debug )
X printf("makefile open\n");
X
X Parse( MakeFile );
X
X if( debug ){
X printf("Variables:\n");
X for( i=0 ; i < n_Vars ; i++ )
X printf( "%s = '%s'\n", avr_Vars[i].pch_name , avr_Vars[i].string );
X printf("Rules:\n");
X for( i=0 ; i < n_Rules ; i++ ){
X printf( "%s : ", arl_Rules[i].pch_target );
X for( j = 0; j < arl_Rules[i].c_depend; j++ )
X printf("'%s' ", arl_Rules[i].apch_depend[ j ] );
X printf("\n");
X for( j = 0; j < arl_Rules[i].c_action; j++ )
X printf("%s\n", arl_Rules[i].apch_action[j] );
X }
X }
X
X if( argc == 1 )
X make( arl_Rules[0].pch_target, &days, &mins, &secs );
X else
X while( --argc != 0 )
X make( *++argv, &days, &mins, &secs );
X
X printf("done.\n");
X}
X
Xstatic char *GetLine(), *NextWord(), *malloc();
X
XParse( fd )
X FILE *fd;
X{
X char *pch_Position, *pch_Word, *pch_Target;
X
X pch_Position = GetLine( fd );
X while( pch_Position ){
X if( debug )
X printf("Parsing:%s\n", pch_Position );
X if( '#' == *pch_Position ){
X pch_Position = GetLine(fd);
X continue;
X }
X pch_Word = pch_Position;
X pch_Position = NextWord( pch_Position );
X if( *pch_Position == '=' ){
X DefineVar( pch_Word, ++ pch_Position );
X pch_Position = GetLine( fd );
X } else {
X pch_Target = pch_Word;
X pch_Word = pch_Position = NextWord( pch_Position );
X pch_Position = NextWord( pch_Position );
X while( pch_Word ){
X AddDependant( pch_Word, pch_Target );
X pch_Word = pch_Position;
X pch_Position = NextWord( pch_Position );
X }
X pch_Position = GetLine( fd );
X while( ' ' == *pch_Position ){
X AddAction( pch_Position , pch_Target );
X pch_Position = GetLine( fd );
X }
X }
X }
X}
X
Xchar *
XNextWord( pch )
X char *pch;
X{
X if( NULL == pch || NULL == *pch )
X return NULL;
X while( *pch && *pch != ' ' && *pch != '\t' && *pch != ',' )
X pch++;
X if( *pch == '\0' )
X return NULL;
X else
X *pch = '\0';
X do
X pch++;
X while ( *pch && (' ' == *pch || '\t' == *pch || ',' == *pch ));
X if(*pch == '\0')
X return NULL;
X else
X return pch;
X}
X
X/* states for GetLine */
X#define HALT -1
X#define IGNOREWHITE 0
X#define START 1
X#define NONWHITE 2
X#define BACKSLASH 3
X#define VARIABLE 4
Xchar *names[]={"ignorewhite","start","nonwhite","backslash","variable"};
X
Xstatic char *
XGetLine( fd )
X FILE *fd;
X{
X static char buf[ 1024 ];
X auto int pos = 0;
X auto int state = START;
X int ch;
X char *pch_var, *pch_replace;
X
X ch = getc(fd);
X if( EOF == ch )
X return NULL;
X while( state != HALT ){
X if( debug )
X printf( "state: %s\n", names[state]);
X switch( state ){
X case IGNOREWHITE:
X if ( ' ' == ch || '\t' == ch || ',' == ch )
X ch = getc(fd);
X else
X state = START;
X break;
X case START:
X if( ' ' == ch || '\t' == ch || ',' == ch ) {
X buf[pos++] = ch;
X ch = getc(fd);
X state = IGNOREWHITE;
X break;
X } else if( '$' == ch ) {
X state = VARIABLE;
X ch = getc(fd);
X break;
X } else if( '\\' == ch ) {
X ch = getc(fd);
X state = BACKSLASH;
X break;
X } else if( '\n' == ch || EOF == ch ) {
X state = HALT;
X break;
X } else {
X state = NONWHITE;
X break;
X }
X case NONWHITE :
X if( ch != EOF && ch != '\n' && ch != '$' &&
X ch != '\\' && ch != ' ' && ch != '\t' && ch != ',' ) {
X buf[ pos++ ] = ch;
X ch = getc(fd);
X } else
X state = START;
X break;
X case BACKSLASH:
X if( ch != '\n' ){
X buf[pos++] = '\\';
X buf[pos++] = ch;
X }
X ch = getc(fd );
X state = START;
X break;
X case VARIABLE:
X if( '$' == ch ) {
X buf[pos++] = ch;
X state = START;
X } else if ( '{'== ch || '(' == ch ) {
X ch = getc(fd);
X pch_var = &buf[ pos ];
X while ( ')' != ch && '}' != ch ){
X buf[ pos++ ] = ch;
X ch = getc(fd);
X }
X ch = getc(fd);
X buf[pos]=NULL;
X pch_replace = VarLookup( pch_var );
X strcpy( pch_var , pch_replace );
X pos = strlen( buf );
X state = START;
X }
X break;
X }
X }
X buf[pos] = NULL;
X if( debug )
X printf("buf='%s'\n", buf );
X pch_replace = malloc( strlen(buf) + 1 );
X if( pch_replace == NULL ){
X printf("make: out of memory" );
X exit(1);
X }
X strcpy( pch_replace , buf );
X return pch_replace;
X}
X
Xmake( pch_Target, mydays, mymins, mytics )
X char *pch_Target;
X long int *mydays, *mymins, *mytics;
X{
X long int hisdays, hismins, histics;
X int fl_Action;
X char **depends, **actions;
X
X GetDate( pch_Target, mydays, mymins, mytics );
X if( debug )
X printf("make(): %s %ld %ld:%ld\n",pch_Target,*mydays,*mymins,*mytics );
X depends = GetDependants( pch_Target );
X actions = GetActions( pch_Target );
X fl_Action = *mydays == 0 && *mymins == 0 && *mytics == 0;
X while( *depends ){
X if( make( *depends++, &hisdays, &hismins, &histics ) )
X fl_Action = 1;
X if( hisdays > *mydays || (hisdays == *mydays &&
X ( hismins > *mymins || (hismins == *mymins && histics > *mytics ))))
X fl_Action = 1;
X }
X if( fl_Action )
X while( *actions ) {
X printf("%s\n", *actions );
X Execute( *actions, 0, 0 );
X actions++;
X }
X return fl_Action;
X}
X
XGetDate( pch_FileName, days, mins, secs )
X char *pch_FileName;
X long int *days, *mins, *secs;
X{
X static struct FileInfoBlock buf;
X char *p;
X
X if( p = (char *)Lock( pch_FileName, ACCESS_READ )){
X if( Examine( p , &buf ) ) {
X *days = buf.fib_Date.ds_Days;
X *mins = buf.fib_Date.ds_Minute;
X *secs = buf.fib_Date.ds_Tick;
X } else
X printf("Couldn't get info for %s\n", pch_FileName );
X UnLock( p );
X } else {
X if ( debug )
X printf("couldn't lock %s\n", pch_FileName );
X *days = *mins = *secs = 0;
X }
X}
Y
sed -e "s/^X//" > rules.c << Y
X#include "rules.h"
Xextern int debug;
X
XAddDependant( pch_name, pch_target )
X char *pch_name, *pch_target;
X{
X int pos;
X
X pos = _Lookup( pch_target );
X if( debug )
X printf("Found %s at pos %d\n", pch_target, pos );
X arl_Rules[ pos ].apch_depend[ arl_Rules[ pos ].c_depend++ ] = pch_name;
X}
X
Xchar **
XGetDependants( pch_target )
X char *pch_target;
X{
X int pos;
X
X pos = _Lookup( pch_target );
X return arl_Rules[ pos ].apch_depend;
X}
X
XAddAction( pch_action, pch_target )
X char *pch_action, *pch_target;
X{
X int pos;
X
X pos = _Lookup( pch_target );
X if( debug )
X printf("Found %s at pos %d\n", pch_target, pos );
X arl_Rules[ pos ].apch_action[ arl_Rules[ pos ].c_action++ ] = pch_action;
X}
X
Xchar **
XGetActions( pch_target )
X char *pch_target;
X{
X int pos;
X
X pos = _Lookup( pch_target );
X return arl_Rules[ pos ].apch_action;
X}
X
Xint n_Rules = 0;
Xstruct rule arl_Rules[ MAXRULES ];
X
X_Lookup( pch_target )
X char *pch_target;
X{
X int pos = 0;
X
X arl_Rules[ n_Rules ].pch_target = pch_target;
X arl_Rules[ n_Rules ].c_action = 0;
X arl_Rules[ n_Rules ].c_depend = 0;
X while( strcmp( arl_Rules[pos].pch_target , pch_target ) )
X pos++;
X if ( pos == n_Rules )
X n_Rules++;
X return pos;
X}
Y
sed -e "s/^X//" > rules.h << Y
X#define MAXDEPEND 100
X#define MAXACTION 20
X#define MAXRULES 50
X
X/*
X * struct rule -- storage for a rule of the form
X *
X * target : depend[0] depend[1] ... depend[c_depend]
X * action[0]
X * action[1]
X * :
X * action[c_action]
X *
X */
X
Xextern struct rule {
X char *pch_target;
X int c_depend;
X char *apch_depend[ MAXDEPEND ];
X int c_action;
X char *apch_action[ MAXACTION ];
X} arl_Rules[ MAXRULES ];
X
Xextern int n_Rules;
Xextern char **GetDependants(), **GetActions();
Y
sed -e "s/^X//" > vars.c << Y
X#include "vars.h"
X#define NULL 0
Xextern int debug;
X
XDefineVar( pch_varname , pch_value )
X char *pch_varname, *pch_value;
X{
X int pos;
X
X pos = _Lookup( pch_varname );
X if( debug )
X printf( "Found var '%s' at position %d, defining as %s\n", pch_varname,pos, pch_value );
X if( NULL != avr_Vars[ pos ].string)
X printf("Redefining %s\n", pch_varname );
X avr_Vars[pos].string = pch_value;
X}
X
Xchar *
XVarLookup( pch_varname )
X char *pch_varname;
X{
X int pos;
X
X pos = _Lookup( pch_varname );
X if( debug )
X printf("found '%s' at position %d, value is %s\n", pch_varname, pos, avr_Vars[pos].string );
X return avr_Vars[pos].string;
X}
X
Xstatic int
X_Lookup( pch_varname )
X char *pch_varname;
X{
X int pos;
X
X avr_Vars[n_Vars].pch_name = pch_varname;
X avr_Vars[n_Vars].string = NULL;
X pos = 0;
X while( strcmp(pch_varname, avr_Vars[pos].pch_name ))
X pos++;
X if( pos == n_Vars )
X n_Vars++;
X return pos;
X}
X
Xint n_Vars = 0;
Xstruct var avr_Vars[ MAXVARS ];
Y
sed -e "s/^X//" > vars.h << Y
X#define MAXVARS 50
X
X/*
X * struct var -- storage for variable
X * assignments of the form
X *
X * name = string
X *
X */
X
Xextern struct var {
X char *pch_name;
X char *string;
X} avr_Vars[ MAXVARS ];
X
Xextern int n_Vars; /* count of defined variables */
Xextern DefineVar();
Xextern char *VarLookup();
Y