#include "make.h" char *ReadFile( name ) char *name; { char *first; char *line; char *ep, *lp, *cp; char toktype, gathering; char *stpbrk(), *stpchr(); BPTR fp; TNODE *nodep; STRNODE *lastcmd, *thiscmd, *namenode, *lastname; lastcmd = lastname = NULL; nodep = NULL; first = NULL; if ( (fp = Open( name, MODE_OLDFILE )) == NULL) { msg("Unable to open '%s' for rules\n", name ); return(NULL); } gathering = FALSE; while ( (line = getline(MAXILINE, fp)) != NULL) { if (PrintMakeFile) puts(line); tstbreak(); if (*line != COMMENT) { /* are we in the process of gathering commands ? */ if (gathering && *line == ' ') { /* create a command node for us */ thiscmd = (STRNODE *)gmem( sizeof(STRNODE) ); thiscmd->next = NULL; thiscmd->string = line; /* add this to the current command */ if (nodep->commands == NULL) nodep->commands = thiscmd; else lastcmd->next = thiscmd; /* remember where to put the next command */ lastcmd = thiscmd; } else { gathering = FALSE; /* make sure we don't have a blank line to deal with */ if (*line) { /* commands may be in any of two forms: */ /* = string */ /* : */ /* := [a-zA-Z_@@][a-zA-Z_0-9@@@-]* */ /* may contain macro calls and patterns */ /* Do a preliminary scan to see what we have */ if ( (lp = stpbrk(line, ":=")) == NULL) err( "Invalid statement:'%s'", line ); /* do we have a macro definition ? */ if (*lp == '=') { ep = lp; /* null out equals sign and skip over blanks */ for ( *lp++ = 0; isspace(*lp); lp++ ); /* remove any trailing blanks from the target or symbol */ for ( --ep; isspace(*ep); *ep-- = 0 ); /* we have a macro command so store it */ tree( line, lp, &Macros); } else { /* we have a dependancy line (we hope) */ nodep = (TNODE *) gmem( sizeof(TNODE) ); gathering = TRUE; nodep->commands = NULL; nodep->targets = NULL; nodep->depends = NULL; nodep->error = 0; cp = line; while ( (toktype = parse( &cp, &namenode )) != COLON ) { if (toktype != FILENAME) err("Missing ':' in '%s'", line); if (nodep->targets == NULL) { if (first==NULL && (*(namenode->string) != '.') && (stpchr(namenode->string,'/') == NULL)) first = namenode->string; nodep->targets = namenode; } else lastname->next = namenode; lastname = namenode; /* add this target to the dependancy list */ tree( namenode->string, nodep, &Root ); } while ( (toktype = parse( &cp, &namenode )) == FILENAME ) { if (nodep->depends == NULL) nodep->depends = namenode; else lastname->next = namenode; lastname = namenode; } if (toktype == SEMICOLON) { /* create a command node for us */ thiscmd = (STRNODE *)gmem( sizeof(STRNODE) ); thiscmd->next = NULL; thiscmd->string = cp; nodep->commands = thiscmd; /* remember where to put the next command */ lastcmd = thiscmd; } else if (toktype != EOS) err("Invalid command '%s'", line); } } } } }; Close(fp); return(first); } /*------------------------------------------------------------------------*/ int parse( parseptr, result ) char **parseptr; STRNODE **result; { char *textbuff, *start, *endp, *stpchr(), *stpbrk(); int len; start = *parseptr; /* skip over any leading whitespace */ while(isspace(*start)) start++; switch(*start) { case 0: /* end of string */ *parseptr = start; return(EOS); break; case COLON: case SEMICOLON: *parseptr = start+1; return((int)*start); break; case '\'': /* single quoted file names */ case '"' : /* double quoted file names */ if ( (endp=stpchr(start+1, *start)) == NULL ) err("missing quote for '%s'", start); /* figure out the length to copy */ len = endp-(start++); /* update the parse pointer */ *parseptr = endp+1; goto makename; default: if ( (endp=stpbrk(start, " '\";:")) == NULL ) len = strlen(start); else len = endp-start; *parseptr = start+len; makename: textbuff = (char *)gmem( len+1 ); movmem( start, textbuff, len); *(textbuff+len) = 0; *result = (STRNODE *)gmem( sizeof(STRNODE) ); (*result)->string = textbuff; (*result)->next = NULL; return(FILENAME); } }