doc@pucc-j.UUCP (07/22/86)
[* Note: This was posted to the net several months ago by a former roomate of mine, and I think it has made its way onto AMICUS disk #2, but it is here per request of several people. The authors new net address is "ihnp4!cuuxb!mwm" *] 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...) Marc Mengel Hackers Liberation Front # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # makefile # make.c # rules.c # vars.c # rules.h # vars.h # This archive created: Tue Jul 22 15:15:18 1986 # By: Craig Norborg (Purdue University Computing Center) cat << \SHAR_EOF > makefile #This is a makefile for make using lattice C. SRC = make.c vars.c rules.c HDR = vars.h rules.h OBJ = make.o vars.o rules.o make : ${OBJ} alink \ from cbench:lib/Lstartup.obj+make.o+vars.o+rules.o \ library cbench:lib/lc.lib+cbench:lib/amiga.lib \ to make \ map nil: make.o : make.c vars.h rules.h lc -icbench:include/ make.c vars.o : vars.c vars.h lc vars.c rules.o : rules.c rules.h lc rules.c list : makefile ${SRC} ${HDR} echo "on what?" clean : rm ${OBJ} SHAR_EOF cat << \SHAR_EOF > make.c /* make.c */ #include "rules.h" #include "vars.h" #include <stdio.h> #include <libraries/dos.h> int debug; long int days, mins, secs; main( argc, argv ) int argc; char **argv; { FILE *MakeFile; int i,j; printf("Make V1.0 (c) 1985 by General Overall Design.\n"); printf("May (only) be distributed free of charge.\n"); /* General Overall Design * P.O. Box 2039 * W. Lavayette IN 47906 */ if( argc > 2 && strcmp(argv[1], "-f")==0 ){ /* make -f file ... */ MakeFile = fopen( argv[2] , "r" ); argc -= 2; argv += 2; } else MakeFile = fopen("makefile" , "r"); if( argc > 1 && strcmp( argv[1], "-d" ) == 0 ){ debug=1; argc--; argv++; printf("debug on.\n"); } if( MakeFile == NULL ){ /* open failed */ printf("make: can't open makefile\n"); exit( 1 ); } if ( debug ) printf("makefile open\n"); Parse( MakeFile ); if( debug ){ printf("Variables:\n"); for( i=0 ; i < n_Vars ; i++ ) printf( "%s = '%s'\n", avr_Vars[i].pch_name , avr_Vars[i].string ); printf("Rules:\n"); for( i=0 ; i < n_Rules ; i++ ){ printf( "%s : ", arl_Rules[i].pch_target ); for( j = 0; j < arl_Rules[i].c_depend; j++ ) printf("'%s' ", arl_Rules[i].apch_depend[ j ] ); printf("\n"); for( j = 0; j < arl_Rules[i].c_action; j++ ) printf("%s\n", arl_Rules[i].apch_action[j] ); } } if( argc == 1 ) make( arl_Rules[0].pch_target, &days, &mins, &secs ); else while( --argc != 0 ) make( *++argv, &days, &mins, &secs ); printf("done.\n"); } static char *GetLine(), *NextWord(), *malloc(); Parse( fd ) FILE *fd; { char *pch_Position, *pch_Word, *pch_Target; pch_Position = GetLine( fd ); while( pch_Position ){ if( debug ) printf("Parsing:%s\n", pch_Position ); if( '#' == *pch_Position ){ pch_Position = GetLine(fd); continue; } pch_Word = pch_Position; pch_Position = NextWord( pch_Position ); if( *pch_Position == '=' ){ DefineVar( pch_Word, ++ pch_Position ); pch_Position = GetLine( fd ); } else { pch_Target = pch_Word; pch_Word = pch_Position = NextWord( pch_Position ); pch_Position = NextWord( pch_Position ); while( pch_Word ){ AddDependant( pch_Word, pch_Target ); pch_Word = pch_Position; pch_Position = NextWord( pch_Position ); } pch_Position = GetLine( fd ); while( ' ' == *pch_Position ){ AddAction( pch_Position , pch_Target ); pch_Position = GetLine( fd ); } } } } char * NextWord( pch ) char *pch; { if( NULL == pch || NULL == *pch ) return NULL; while( *pch && *pch != ' ' && *pch != '\t' && *pch != ',' ) pch++; if( *pch == '\0' ) return NULL; else *pch = '\0'; do pch++; while ( *pch && (' ' == *pch || '\t' == *pch || ',' == *pch )); if(*pch == '\0') return NULL; else return pch; } /* states for GetLine */ #define HALT -1 #define IGNOREWHITE 0 #define START 1 #define NONWHITE 2 #define BACKSLASH 3 #define VARIABLE 4 char *names[]={"ignorewhite","start","nonwhite","backslash","variable"}; static char * GetLine( fd ) FILE *fd; { static char buf[ 1024 ]; auto int pos = 0; auto int state = START; int ch; char *pch_var, *pch_replace; ch = getc(fd); if( EOF == ch ) return NULL; while( state != HALT ){ if( debug ) printf( "state: %s\n", names[state]); switch( state ){ case IGNOREWHITE: if ( ' ' == ch || '\t' == ch || ',' == ch ) ch = getc(fd); else state = START; break; case START: if( ' ' == ch || '\t' == ch || ',' == ch ) { buf[pos++] = ch; ch = getc(fd); state = IGNOREWHITE; break; } else if( '$' == ch ) { state = VARIABLE; ch = getc(fd); break; } else if( '\\' == ch ) { ch = getc(fd); state = BACKSLASH; break; } else if( '\n' == ch || EOF == ch ) { state = HALT; break; } else { state = NONWHITE; break; } case NONWHITE : if( ch != EOF && ch != '\n' && ch != '$' && ch != '\\' && ch != ' ' && ch != '\t' && ch != ',' ) { buf[ pos++ ] = ch; ch = getc(fd); } else state = START; break; case BACKSLASH: if( ch != '\n' ){ buf[pos++] = '\\'; buf[pos++] = ch; } ch = getc(fd ); state = START; break; case VARIABLE: if( '$' == ch ) { buf[pos++] = ch; state = START; } else if ( '{'== ch || '(' == ch ) { ch = getc(fd); pch_var = &buf[ pos ]; while ( ')' != ch && '}' != ch ){ buf[ pos++ ] = ch; ch = getc(fd); } ch = getc(fd); buf[pos]=NULL; pch_replace = VarLookup( pch_var ); strcpy( pch_var , pch_replace ); pos = strlen( buf ); state = START; } break; } } buf[pos] = NULL; if( debug ) printf("buf='%s'\n", buf ); pch_replace = malloc( strlen(buf) + 1 ); if( pch_replace == NULL ){ printf("make: out of memory" ); exit(1); } strcpy( pch_replace , buf ); return pch_replace; } make( pch_Target, mydays, mymins, mytics ) char *pch_Target; long int *mydays, *mymins, *mytics; { long int hisdays, hismins, histics; int fl_Action; char **depends, **actions; GetDate( pch_Target, mydays, mymins, mytics ); if( debug ) printf("make(): %s %ld %ld:%ld\n",pch_Target,*mydays,*mymins,*mytics ); depends = GetDependants( pch_Target ); actions = GetActions( pch_Target ); fl_Action = *mydays == 0 && *mymins == 0 && *mytics == 0; while( *depends ){ if( make( *depends++, &hisdays, &hismins, &histics ) ) fl_Action = 1; if( hisdays > *mydays || (hisdays == *mydays && ( hismins > *mymins || (hismins == *mymins && histics > *mytics )))) fl_Action = 1; } if( fl_Action ) while( *actions ) { printf("%s\n", *actions ); Execute( *actions, 0, 0 ); actions++; } return fl_Action; } GetDate( pch_FileName, days, mins, secs ) char *pch_FileName; long int *days, *mins, *secs; { static struct FileInfoBlock buf; char *p; if( p = (char *)Lock( pch_FileName, ACCESS_READ )){ if( Examine( p , &buf ) ) { *days = buf.fib_Date.ds_Days; *mins = buf.fib_Date.ds_Minute; *secs = buf.fib_Date.ds_Tick; } else printf("Couldn't get info for %s\n", pch_FileName ); UnLock( p ); } else { if ( debug ) printf("couldn't lock %s\n", pch_FileName ); *days = *mins = *secs = 0; } } SHAR_EOF cat << \SHAR_EOF > rules.c /* rules.c */ #include "rules.h" extern int debug; AddDependant( pch_name, pch_target ) char *pch_name, *pch_target; { int pos; pos = _Lookup( pch_target ); if( debug ) printf("Found %s at pos %d\n", pch_target, pos ); arl_Rules[ pos ].apch_depend[ arl_Rules[ pos ].c_depend++ ] = pch_name; } char ** GetDependants( pch_target ) char *pch_target; { int pos; pos = _Lookup( pch_target ); return arl_Rules[ pos ].apch_depend; } AddAction( pch_action, pch_target ) char *pch_action, *pch_target; { int pos; pos = _Lookup( pch_target ); if( debug ) printf("Found %s at pos %d\n", pch_target, pos ); arl_Rules[ pos ].apch_action[ arl_Rules[ pos ].c_action++ ] = pch_action; } char ** GetActions( pch_target ) char *pch_target; { int pos; pos = _Lookup( pch_target ); return arl_Rules[ pos ].apch_action; } int n_Rules = 0; struct rule arl_Rules[ MAXRULES ]; _Lookup( pch_target ) char *pch_target; { int pos = 0; arl_Rules[ n_Rules ].pch_target = pch_target; arl_Rules[ n_Rules ].c_action = 0; arl_Rules[ n_Rules ].c_depend = 0; while( strcmp( arl_Rules[pos].pch_target , pch_target ) ) pos++; if ( pos == n_Rules ) n_Rules++; return pos; } SHAR_EOF cat << \SHAR_EOF > vars.c /* vars.c */ #include "vars.h" #define NULL 0 extern int debug; DefineVar( pch_varname , pch_value ) char *pch_varname, *pch_value; { int pos; pos = _Lookup( pch_varname ); if( debug ) printf( "Found var '%s' at position %d, defining as %s\n", pch_varname,pos, pch_value ); if( NULL != avr_Vars[ pos ].string) printf("Redefining %s\n", pch_varname ); avr_Vars[pos].string = pch_value; } char * VarLookup( pch_varname ) char *pch_varname; { int pos; pos = _Lookup( pch_varname ); if( debug ) printf("found '%s' at position %d, value is %s\n", pch_varname, pos, avr_Vars[pos].string ); return avr_Vars[pos].string; } static int _Lookup( pch_varname ) char *pch_varname; { int pos; avr_Vars[n_Vars].pch_name = pch_varname; avr_Vars[n_Vars].string = NULL; pos = 0; while( strcmp(pch_varname, avr_Vars[pos].pch_name )) pos++; if( pos == n_Vars ) n_Vars++; return pos; } int n_Vars = 0; struct var avr_Vars[ MAXVARS ]; SHAR_EOF cat << \SHAR_EOF > rules.h /* rules.h */ #define MAXDEPEND 100 #define MAXACTION 20 #define MAXRULES 50 /* * struct rule -- storage for a rule of the form * * target : depend[0] depend[1] ... depend[c_depend] * action[0] * action[1] * : * action[c_action] * */ extern struct rule { char *pch_target; int c_depend; char *apch_depend[ MAXDEPEND ]; int c_action; char *apch_action[ MAXACTION ]; } arl_Rules[ MAXRULES ]; extern int n_Rules; extern char **GetDependants(), **GetActions(); SHAR_EOF cat << \SHAR_EOF > vars.h /* vars.h */ #define MAXVARS 50 /* * struct var -- storage for variable * assignments of the form * * name = string * */ extern struct var { char *pch_name; char *string; } avr_Vars[ MAXVARS ]; extern int n_Vars; /* count of defined variables */ extern DefineVar(); extern char *VarLookup(); SHAR_EOF # End of shell archive exit 0