462 lines
		
	
	
	
		
			9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			462 lines
		
	
	
	
		
			9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
 | |
|  * See the copyright notice in the ACK home directory, in the file "Copyright".
 | |
|  *
 | |
|  * Author: Ceriel J.H. Jacobs
 | |
|  */
 | |
| 
 | |
| /* M A I N   P R O G R A M */
 | |
| 
 | |
| /* stripped down version from the one in the Modula-2 compiler */
 | |
| 
 | |
| /* $Header$ */
 | |
| 
 | |
| #include	<alloc.h>
 | |
| 
 | |
| #include	"input.h"
 | |
| #include	"f_info.h"
 | |
| #include	"idf.h"
 | |
| #include	"LLlex.h"
 | |
| #include	"Lpars.h"
 | |
| #include	"tokenname.h"
 | |
| 
 | |
| int		state;			/* either IMPLEMENTATION or PROGRAM */
 | |
| char		*ProgName;
 | |
| char		**DEFPATH;
 | |
| int		nDEF, mDEF;
 | |
| struct file_list *CurrentArg;
 | |
| extern int 	err_occurred;
 | |
| extern int 	Roption;
 | |
| extern char	*strrindex();
 | |
| extern char	*strcpy(), *strcat();
 | |
| 
 | |
| char *
 | |
| basename(s)
 | |
| 	char *s;
 | |
| {
 | |
| 	static char buf[256];
 | |
| 	char *p = strrindex(s, '.');
 | |
| 
 | |
| 	if (p != 0) *p = 0;
 | |
| 	strcpy(buf, s);
 | |
| 	if (p != 0) *p = '.';
 | |
| 	return buf;
 | |
| }
 | |
| 
 | |
| char *
 | |
| getwdir(fn)
 | |
|         register char *fn;
 | |
| {
 | |
|         register char *p;
 | |
| 
 | |
|         p = strrindex(fn, '/');
 | |
|         while (p && *(p + 1) == '\0') { /* remove trailing /'s */
 | |
|                 *p = '\0';
 | |
|                 p = strrindex(fn, '/');
 | |
|         }
 | |
| 
 | |
|         if (p) {
 | |
| 		register char **d = DEFPATH;
 | |
| 
 | |
|                 *p = '\0';
 | |
| 		while (*d && strcmp(*d, fn) != 0) d++;
 | |
|                 if (*d) {
 | |
|                 	*p = '/';
 | |
| 			return *d;
 | |
| 		}
 | |
|                 fn = Salloc(fn, (unsigned) (p - &fn[0] + 1));
 | |
| 		*p = '/';
 | |
| 		return fn;
 | |
|         }
 | |
|         return ".";
 | |
| }
 | |
| 
 | |
| static struct file_list *arglist;
 | |
| 
 | |
| char *mflags = "";
 | |
| char *compiler = M2COMPILER;
 | |
| char *suff = "o";
 | |
| char *llibs = 0;
 | |
| 
 | |
| main(argc, argv)
 | |
| 	register char **argv;
 | |
| {
 | |
| 	extern struct tokenname tkidf[];
 | |
| 	extern char *getwdir();
 | |
| 	int i;
 | |
| 
 | |
| 	ProgName = *argv++;
 | |
| 	DEFPATH = (char **) Malloc(10 * sizeof(char *));
 | |
| 	mDEF = 10;
 | |
| 	nDEF = 1;
 | |
| 
 | |
| 	while (--argc > 0) {
 | |
| 		if (**argv == '-')
 | |
| 			DoOption((*argv++) + 1);
 | |
| 		else {
 | |
| 			Add(&arglist, *argv, getwdir(*argv), 1);
 | |
| 			argv++;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	init_idf();
 | |
| 	reserve(tkidf);
 | |
| 	print("IFLAGS =");
 | |
| 	for (i = 1; i < nDEF; i++) {
 | |
| 		print(" -I%s", DEFPATH[i]);
 | |
| 	}
 | |
| 	print("\nM2FLAGS = %s\nMOD = %s\nSUFFIX = %s\nLIBS = %s\n", mflags, compiler, suff, llibs ? llibs : "");
 | |
| 	init_lib();
 | |
| 	ProcessArgs();
 | |
| 	find_dependencies();
 | |
| 	print_dep();
 | |
| 	programs();
 | |
| 	exit(err_occurred);
 | |
| }
 | |
| 
 | |
| struct file_list *
 | |
| new_file_list()
 | |
| {
 | |
| 	static struct file_list *p;
 | |
| 	static int cnt;
 | |
| 	extern char *calloc();
 | |
| 
 | |
| 	if (cnt--) return p++;
 | |
| 	p = (struct file_list *)calloc(50, sizeof(struct file_list));
 | |
| 	cnt = 49;
 | |
| 	return p++;
 | |
| }
 | |
| 
 | |
| Add(parglist, f, d, copy)
 | |
| 	char *f, *d;
 | |
| 	struct file_list **parglist;
 | |
| {
 | |
| 	register struct file_list *a, *b = 0;
 | |
| 
 | |
| 	if (f == 0) return;
 | |
| 
 | |
| 	f_walk(*parglist, a) {
 | |
| 		if (strcmp(f_filename(a), f) == 0) break;
 | |
| 		b = a;
 | |
| 	}
 | |
| 	if (a) return 0;
 | |
| 	a = new_file_list();
 | |
| 	if (copy) {
 | |
| 		a->a_filename = Salloc(f, (unsigned) (strlen(f)+1));
 | |
| 	}
 | |
| 	else {
 | |
| 		a->a_filename = f;
 | |
| 	}
 | |
| 	a->a_dir = d;
 | |
| 	if (! b) *parglist = a;
 | |
| 	else b->a_next = a;
 | |
| 	return 1;
 | |
| }
 | |
| 
 | |
| int
 | |
| openfile(a)
 | |
| 	register struct file_list *a;
 | |
| {
 | |
| 	char *fn;
 | |
| 
 | |
| 	if (!f_notfound(a) && ! InsertFile(f_filename(a), DEFPATH, &fn)) {
 | |
| 		a->a_notfound = 1;
 | |
| 		Gerror("Could not find %s", f_filename(a));
 | |
| 		return 0;
 | |
| 	}
 | |
| 	FileName = fn;
 | |
| 	LineNumber = 1;
 | |
| 	a->a_dir = WorkingDir = getwdir(FileName);
 | |
| 	return 1;
 | |
| }
 | |
| 
 | |
| ProcessArgs()
 | |
| {
 | |
| 	register struct file_list *a;
 | |
| 
 | |
| 	f_walk(arglist, a) {
 | |
| 		register char *p = strrindex(f_filename(a), '.');
 | |
| 
 | |
| 		CurrentArg = a;
 | |
| 		DEFPATH[0] = f_dir(a);
 | |
| 		if ( p && strcmp(p, ".def") == 0) {
 | |
| 			ForeignFlag = 0;
 | |
| 			if (! openfile(a)) {
 | |
| 				continue;
 | |
| 			}
 | |
| 			DefModule();
 | |
| 		}
 | |
| 		else if (p && strcmp(p, ".mod") == 0) {
 | |
| 			if (! openfile(a)) {
 | |
| 				*p = 0;		/* ??? */
 | |
| 				continue;
 | |
| 			}
 | |
| 			CompUnit();
 | |
| 		}
 | |
| 		else fatal("No Modula-2 file: %s", f_filename(a));
 | |
| 	}
 | |
| }
 | |
| 
 | |
| No_Mem()
 | |
| {
 | |
| 	fatal("out of memory");
 | |
| }
 | |
| 
 | |
| AddToList(name, ext)
 | |
| 	char *name, *ext;
 | |
| {
 | |
| 	/*	Try to find a file with basename "name" and extension ".def",
 | |
| 		in the directories mentioned in "DEFPATH".
 | |
| 	*/
 | |
| 	char buf[15];
 | |
| 	char *strncpy();
 | |
| 
 | |
| 	if (strcmp(name, "SYSTEM") != 0 && ! is_library_dir(WorkingDir)) {
 | |
| 		strncpy(buf, name, 10);
 | |
| 		buf[10] = '\0';			/* maximum length */
 | |
| 		strcat(buf, ext);
 | |
| 		Add(&arglist, buf, WorkingDir, 1);
 | |
| 		return 1;
 | |
| 	}
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| find_dependencies()
 | |
| {
 | |
| 	register struct file_list *arg;
 | |
| 
 | |
| 	print("\nall:\t");
 | |
| 	f_walk(arglist, arg) {
 | |
| 		char *fn = f_filename(arg);
 | |
| 		char *dotspot = strrindex(fn, '.');
 | |
| 
 | |
| 		if (dotspot && strcmp(dotspot, ".mod") == 0) {
 | |
| 			register struct idf *id = f_idf(arg);
 | |
| 
 | |
| 			if (! f_notfound(arg) && id) {
 | |
| 				if (id->id_type == PROGRAM) {
 | |
| 					*dotspot = 0;
 | |
| 					print("%s ", fn);
 | |
| 					*dotspot = '.';
 | |
| 				}
 | |
| 				file_dep(id);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	print("\n\n");
 | |
| 	print("objects:\t");
 | |
| 	f_walk(arglist, arg) {
 | |
| 		char *fn = f_filename(arg);
 | |
| 		char *dotspot = strrindex(fn, '.');
 | |
| 
 | |
| 		if (dotspot && strcmp(dotspot, ".mod") == 0) {
 | |
| 			register struct idf *id = f_idf(arg);
 | |
| 
 | |
| 			if (! f_notfound(arg) && id) {
 | |
| 				if (id->id_type == PROGRAM) {
 | |
| 					*dotspot = 0;
 | |
| 					print("%s_o_files ", fn);
 | |
| 					*dotspot = '.';
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	print("\n\n\n");
 | |
| }
 | |
| 
 | |
| file_dep(id)
 | |
| 	register struct idf *id;
 | |
| {
 | |
| 	register struct lnk *m;
 | |
| 
 | |
| 	if (id->id_ddependson || id->id_mdependson) return;
 | |
| 	if (id->id_def) Add(&(id->id_mdependson), id->id_def, id->id_dir, 0);
 | |
| 	for (m = id->id_defimports; m; m = m->lnk_next) {
 | |
| 		register struct idf *iid = m->lnk_imp;
 | |
| 
 | |
| 		Add(&(id->id_mdependson), iid->id_def, iid->id_dir, 0);
 | |
| 		if (Add(&(id->id_ddependson), iid->id_def, iid->id_dir, 0)) {
 | |
| 			register struct file_list *p;
 | |
| 
 | |
| 			file_dep(iid);
 | |
| 			f_walk(iid->id_ddependson, p) {
 | |
| 				Add(&(id->id_ddependson), f_filename(p),
 | |
| 				    f_dir(p), 0);
 | |
| 				Add(&(id->id_mdependson), f_filename(p),
 | |
| 				    f_dir(p), 0);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	for (m = id->id_modimports; m; m = m->lnk_next) {
 | |
| 		register struct idf *iid = m->lnk_imp;
 | |
| 
 | |
| 		if (Add(&(id->id_mdependson), iid->id_def, iid->id_dir, 0)) {
 | |
| 			register struct file_list *p;
 | |
| 
 | |
| 			file_dep(iid);
 | |
| 			f_walk(iid->id_ddependson, p) {
 | |
| 				Add(&(id->id_mdependson), f_filename(p),
 | |
| 				    f_dir(p), 0);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| char *
 | |
| object(arg)
 | |
| 	register struct file_list *arg;
 | |
| {
 | |
| 	static char buf[512];
 | |
| 	char *dotp = strrindex(f_filename(arg), '.');
 | |
| 
 | |
| 	buf[0] = 0;
 | |
| /*
 | |
| 	if (strcmp(f_dir(arg), ".") != 0) {
 | |
| 		strcpy(buf, f_dir(arg));
 | |
| 		strcat(buf, "/");
 | |
| 	}
 | |
| */
 | |
| 	if (dotp) *dotp = 0;
 | |
| 	strcat(buf, f_filename(arg));
 | |
| 	if (dotp) *dotp = '.';
 | |
| 	strcat(buf, ".$(SUFFIX)");
 | |
| 	return buf;
 | |
| }
 | |
| 
 | |
| pr_arg(a)
 | |
| 	register struct file_list *a;
 | |
| {
 | |
| 	char *f = f_filename(a);
 | |
| 	char *d = f_dir(a);
 | |
| 
 | |
| 	if (strcmp(d, ".") == 0 || *f == '/' || *f == '.') {
 | |
| 		print(f);
 | |
| 	}
 | |
| 	else	print("%s/%s", d, f);
 | |
| }
 | |
| 
 | |
| print_dep()
 | |
| {
 | |
| 	register struct file_list *arg;
 | |
| 
 | |
| 	f_walk(arglist, arg) {
 | |
| 		char *dotspot = strrindex(f_filename(arg), '.');
 | |
| 
 | |
| 		if (dotspot && strcmp(dotspot, ".mod") == 0) {
 | |
| 			register struct idf *id = f_idf(arg);
 | |
| 
 | |
| 			if (! f_notfound(arg) && id) {
 | |
| 				char *obj = object(arg);
 | |
| 				register struct file_list *a;
 | |
| 
 | |
| 				print("%s: \\\n\t", obj);
 | |
| 				pr_arg(arg);
 | |
| 				f_walk(id->id_mdependson, a) {
 | |
| 					if (*(f_filename(a))) /* ??? */ {
 | |
| 						print(" \\\n\t");
 | |
| 						pr_arg(a);
 | |
| 					}
 | |
| 				}
 | |
| 				print("\n\t$(MOD) -c $(M2FLAGS) $(IFLAGS) ");
 | |
| 				pr_arg(arg);
 | |
| 				print("\n");
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| prog_dep(id, a)
 | |
| 	register struct idf *id;
 | |
| 	struct file_list *a;
 | |
| {
 | |
| 	register struct lnk *m;
 | |
| 	register struct file_list *p;
 | |
| 
 | |
| 	id->id_mdependson = 0;
 | |
| 	id->id_def = 0;
 | |
| 	if (id->id_type == PROGRAM) {
 | |
| 		Add(&(id->id_mdependson), f_filename(a), f_dir(a), 0);
 | |
| 	}
 | |
| 	else {
 | |
| 		if (strlen(id->id_text) >= 10) id->id_text[10] = 0;
 | |
| 		Add(&(id->id_mdependson), id->id_text, id->id_dir, 0);
 | |
| 	}
 | |
| 	for (m = id->id_modimports; m; m = m->lnk_next) {
 | |
| 		register struct idf *iid = m->lnk_imp;
 | |
| 
 | |
| 		if (Add(&(id->id_mdependson), iid->id_text, iid->id_dir, 0)) {
 | |
| 			if (iid->id_def) prog_dep(iid);
 | |
| 			f_walk(iid->id_mdependson, p) {
 | |
| 				Add(&(id->id_mdependson), f_filename(p),
 | |
| 				    f_dir(p), 0);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| module_in_arglist(n)
 | |
| 	char *n;
 | |
| {
 | |
| 	register struct file_list *a;
 | |
| 
 | |
| 	f_walk(arglist, a) {
 | |
| 		char *dotp = strrindex(f_filename(a), '.');
 | |
| 
 | |
| 		if (dotp && strcmp(dotp, ".mod") == 0 && ! f_notfound(a)) {
 | |
| 			*dotp = 0;
 | |
| 			if (strcmp(f_filename(a), n) == 0) {
 | |
| 				*dotp = '.';
 | |
| 				return 1;
 | |
| 			}
 | |
| 			*dotp = '.';
 | |
| 		}
 | |
| 	}
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| pr_prog_dep(id, a)
 | |
| 	register struct idf *id;
 | |
| 	struct file_list *a;
 | |
| {
 | |
| 	register struct file_list *p;
 | |
| 
 | |
| 	print("\nOBS_%s =", id->id_text);
 | |
| 	f_walk(id->id_mdependson, p) {
 | |
| 		if (module_in_arglist(f_filename(p)) || ! f_dir(p)) {
 | |
| 			print(" \\\n\t%s", object(p));
 | |
| 		}
 | |
| 	}
 | |
| 	print("\n\nOBS2_%s =", id->id_text);
 | |
| 	f_walk(id->id_mdependson, p) {
 | |
| 		if (module_in_arglist(f_filename(p)) || ! f_dir(p)) {
 | |
| 			/* nothing */
 | |
| 		}
 | |
| 		else if (! is_library_dir(f_dir(p))) {
 | |
| 			print(" \\\n\t%s/%s", f_dir(p), object(p));
 | |
| 		}
 | |
| 	}
 | |
| 	print("\n\n");
 | |
| 	print("%s_o_files:\t$(OBS_%s)\n\n", basename(f_filename(a)), id->id_text);
 | |
| 	print("%s:\t$(OBS_%s) $(OBS2_%s)\n", basename(f_filename(a)), id->id_text, id->id_text);
 | |
| 	print("\t$(MOD) -o %s $(M2FLAGS) $(OBS_%s) $(OBS2_%s) $(LIBS)\n", basename(f_filename(a)), id->id_text, id->id_text);
 | |
| }
 | |
| 
 | |
| programs()
 | |
| {
 | |
| 	register struct file_list *a;
 | |
| 
 | |
| 	f_walk(arglist, a) {
 | |
| 		char *dotspot = strrindex(f_filename(a), '.');
 | |
| 
 | |
| 		if (dotspot && strcmp(dotspot, ".mod") == 0) {
 | |
| 			register struct idf *id = f_idf(a);
 | |
| 
 | |
| 			if (! f_notfound(a) && id && id->id_type == PROGRAM) {
 | |
| 				prog_dep(id, a);
 | |
| 				/* *dotspot = 0; */
 | |
| 				pr_prog_dep(id, a);
 | |
| 				/* *dotspot = '.'; */
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 |