home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
300-399
/
ff384.lzh
/
NorthC
/
Example2.LZH
/
make
/
reader.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-08-30
|
10KB
|
400 lines
/*
(c) 1990 S.Hawtin.
Permission is granted to copy this file provided that:
1) It is not used for commercial gain
2) This notice is included in all copies
3) Altered copies are marked as such.
No liability is accepted for the contents of the file.
reader.c within WBmake
*/
/* Read the makefile into the data structures */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "make.h"
extern FileInfo *find_file();
extern Variable *find_var();
extern ConsCell *cons();
/************************************************************/
/* Defaults for default list */
typedef struct
{char *name;
char *string[4];
} DefaultInfo;
DefaultInfo def_defaults[] =
{{".c.o",{"NorthC -Ot:$*.s $*.c",
"A68K -q -g -O$*.o t:$*.s","delete t:$*.s",NULL}},
{".asm.o",{"A68K $*.asm",NULL}},
{".s.o",{"A68K $*.s",NULL}},
{".c.s",{"NorthC -O$*.s $*.c",NULL}},
{NULL}};
/************************************************************/
FileInfo *first_file = NULL;
ConsCell *defaults = NULL;
lowerstr(str)
char *str;
{/* Convert a string to lower case */
for(;*str;str++)
*str = tolower(*str);
}
append(list,new_cons)
ConsCell *list;
ConsCell *new_cons;
{/* Add a cons cell to the end of the list */
while(list->cdr)
list = list->cdr;
list->cdr = new_cons;
}
static int line_no;
static int last_ungot;
FILE *inputs[4];
int input_level=0;
int input_feof = 0;
char *push_str = "";
static char last_ch;
char
make_getc()
{/* Get a character from the Makefile */
char temp_str[128];
int count;
char next;
again:
if(input_feof)
return('\n');
else if(*push_str)
next = *push_str++;
else if(last_ungot)
{next = last_ch;
last_ungot = 0;
}
else
next = fgetc(inputs[input_level]);
switch(next)
{case '\n':
line_no++;
default:
break;
case '#':
/* Skip comments */
next = fgetc(inputs[input_level]);
while(next!='\n' && !feof(inputs[input_level]))
next = fgetc(inputs[input_level]);
break;
case '$':
next = fgetc(inputs[input_level]);
switch(next)
{case '*':
/* Pass $* to gomake file */
push_str = "*";
next = '$';
goto out;
case '<':
/* Read file name and add to file stack */
temp_str[0] = fgetc(inputs[input_level]);
for(count=1;temp_str[count-1]!='>' && count<32;count++)
temp_str[count] = fgetc(inputs[input_level]);
temp_str[count-1] = '\0';
/* Attempt to open the file */
if(input_level>=3)
{printf("Too many file levels $<%s>\n",temp_str);
goto again;
}
inputs[input_level+1]=fopen(temp_str,"r");
if(inputs[input_level+1])
{input_level++;
}
else
printf("Cannot open %s\n",temp_str);
goto again;
default:
printf("Cannot cope with $%c\n",next);
}
break;
}
if(feof(inputs[input_level]))
{fclose(inputs[input_level]);
input_level--;
if(input_level<0)
input_feof = -1;
next = '\n';
}
out:
last_ch = next;
return(next);
}
make_ungetc(ch)
char ch;
{/* Unget a single character */
last_ungot = -1;
}
int
skip_space()
{/* Move past the space characters */
char next;
next = make_getc();
while(isspace(next))
{/* After a '#' read to next '\n' */
if(input_feof)
return(0);
next = make_getc();
}
make_ungetc(next);
return(-1);
}
next_tok(str)
char *str;
{/* Read the next token into the buffer */
char *full_str;
full_str = str;
if(!skip_space())
{*str='\0';
return;
}
*str = make_getc();
if(*str=='$')
{/* The next character tells us what to do */
str++;
*str = make_getc();
switch(*str)
{case '*':
default:
/* read to next whitespace */
goto normal_tok;
case '(':
/* Read a variable name and substitute it */
str = full_str;
*str = make_getc();
while(*str!=')')
{str++;
*str = make_getc();
}
*(++str) = '\0';
printf("Variable value %s\n",full_str);
}
}
else
{/* Normal token */
normal_tok:
while(isalnum(*str) || *str=='.' || *str=='_' || *str=='/')
{str++;
*str = make_getc();
}
make_ungetc(*str);
*str = '\0';
}
}
char
next_oper()
{/* Get the next operator */
if(skip_space())
return(make_getc());
else
return('\0');
}
String *
make_str(str)
char *str;
{/* Create a string object */
String *temp;
temp = (String *)calloc(strlen(str)+sizeof(String),1);
if(str)
strcpy(temp->contents,str);
return(temp);
}
String *
read_string(multi)
int multi;
{/* Read a string, either a variable value or how to make
something */
String *first;
String *last;
char curr_line[128];
int index;
int done;
first = NULL;
last = NULL;
for(;;)
{/* Keep reading lines until we fulfill the end condition */
index = 0;
done = -1;
curr_line[index++] = make_getc();
while((curr_line[0]==' ' || curr_line[0]=='\t') && !input_feof)
curr_line[0] = make_getc();
while(!input_feof && curr_line[index-1]!='\n' && index<127)
{
curr_line[index++] = make_getc();
}
if(index==1)
return(first);
curr_line[index-1] ='\0';
if(!multi && curr_line[index-2]=='\\')
{curr_line[index-2] = '\0';
done = 0;
}
if(first==NULL)
{first = make_str(curr_line);
last = first;
}
else
{last->next = make_str(curr_line);
last = last->next;
}
last->next = 0;
if(!multi && done)
return(first);
}
}
add_defs(file)
FileInfo *file;
{if(defaults==NULL)
{defaults = cons(file,NULL);
}
else
{append(defaults,cons(file,NULL));
}
}
next_clause()
{/* Read the next clause from the file */
Variable *var;
String *string;
FileInfo *file;
char tok[32];
char oper;
next_tok(tok);
oper = next_oper();
if(oper=='\0')
return;
switch(oper)
{case '=':
/* Set variable value */
var = find_var(tok);
var->val = read_string(0);
break;
case ':':
lowerstr(tok);
file = find_file(tok,-1);
if(first_file==NULL)
first_file = file;
if(*tok=='.')
add_defs(file);
do {
/* Read the dependancies, add them to the file */
do {/* Skip initial spaces */
oper = make_getc();
if(oper == '\\')
{oper = make_getc();
if(oper=='\n')
oper = ' ';
}
} while (oper==' ' || oper=='\t');
if(!isspace(oper))
{make_ungetc(oper);
next_tok(tok);
/* Insert on dependancies */
lowerstr(tok);
file->depends = cons(find_file(tok,-1),
file->depends);
}
} while (!isspace(oper));
string = read_string(-1);
if(string)
{
if(file->create && string)
printf("Overwriting old create for %s\n",file->name);
file->create = string;
}
break;
default:
printf("Failed to parse %c line %d\n",oper,line_no);
exit(10);
}
}
FileInfo *
read_makefile(makefile,target)
char *makefile;
char *target;
{/* Scan the makefile */
int i;
inputs[0] = fopen(makefile,"r");
input_level = 0;
input_feof = 0;
if(inputs[0]==NULL)
{printf("Cannot open \"%s\" for input\n",makefile);
return(NULL);
}
line_no = 0;
/* Set up the predefined variables */
while(!input_feof)
{/* Main loop of reader, read next item */
next_clause();
}
/* Add the implied tokens if they have not been defined */
for(i=0;def_defaults[i].name!=NULL;i++)
{
FileInfo *file;
String *string;
int j;
if(find_file(def_defaults[i].name,0)==NULL)
{/* Default has not been created, we better do it */
file = find_file(def_defaults[i].name,-1);
add_defs(file);
string = NULL;
for(j=3;j>=0;j--)
if(def_defaults[i].string[j])
{file->create = make_str(def_defaults[i].string[j]);
file->create->next = string;
string = file->create;
}
}
}
if(*target)
{lowerstr(target);
return(find_file(target,0));
}
else
return(first_file);
}