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