[mod.amiga.sources] PD Make

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