/* * (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 #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 options[128]; int DefinitionModule; 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 * 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 = "ack"; char *suff = "o"; 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\n", mflags, compiler, suff); 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 = *parglist, *b = 0; while (a && strcmp(a->a_filename, f) != 0) { b = a; a = a->a_next; } 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; } ProcessArgs() { register struct file_list *a = arglist; char *fn; while (a) { register char *p = strrindex(a->a_filename, '.'); CurrentArg = a; DEFPATH[0] = a->a_dir; if ( p && strcmp(p, ".def") == 0) { ForeignFlag = 0; if (! InsertFile(a->a_filename, DEFPATH, &fn)) { Gerror("Could not find %s", a->a_filename); a = a->a_next; continue; } FileName = fn; a->a_dir = WorkingDir = getwdir(FileName); DefModule(); } else if (p && strcmp(p, ".mod") == 0) { if (! InsertFile(a->a_filename, DEFPATH, &fn)) { Gerror("Could not find %s", a->a_filename); *p = 0; /* prevent from being used later */ a->a_filename = Salloc(a->a_filename, strlen(a->a_filename) + 11); strcat(a->a_filename, ".$(SUFFIX)"); a = a->a_next; continue; } FileName = fn; a->a_dir = WorkingDir = getwdir(FileName); CompUnit(); } else fatal("No Modula-2 file: %s", a->a_filename); a = a->a_next; } } No_Mem() { fatal("out of memory"); } C_failed() { fatal("write failed"); } 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 = arglist; print("\nall:\t"); while (arg) { char *dotspot = strrindex(arg->a_filename, '.'); if (dotspot && strcmp(dotspot, ".mod") == 0) { register struct idf *id = arg->a_idf; if (id) { if (id->id_type == PROGRAM) { print("%s ", id->id_text); } file_dep(id); } } arg = arg->a_next; } print("\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); for (p = iid->id_ddependson; p; p = p->a_next) { Add(&(id->id_ddependson), p->a_filename, p->a_dir, 0); Add(&(id->id_mdependson), p->a_filename, p->a_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_def, iid->id_dir, 0)) { register struct file_list *p; file_dep(iid); for (p = iid->id_ddependson; p; p = p->a_next) { Add(&(id->id_mdependson), p->a_filename, p->a_dir, 0); } } } } char * object(arg) register struct file_list *arg; { static char buf[512]; char *dotp = strrindex(arg->a_filename, '.'); buf[0] = 0; /* if (strcmp(arg->a_dir, ".") != 0) { strcpy(buf, arg->a_dir); strcat(buf, "/"); } */ *dotp = 0; strcat(buf, arg->a_filename); *dotp = '.'; strcat(buf, ".$(SUFFIX)"); return buf; } pr_arg(a) register struct file_list *a; { if (strcmp(a->a_dir, ".") == 0) { print(a->a_filename); } else print("%s/%s", a->a_dir, a->a_filename); } print_dep() { register struct file_list *arg = arglist; while (arg) { char *dotspot = strrindex(arg->a_filename, '.'); if (dotspot && strcmp(dotspot, ".mod") == 0) { register struct idf *id = arg->a_idf; if (id) { char *obj = object(arg); register struct file_list *a; print("%s: \\\n\t", obj); pr_arg(arg); for (a = id->id_mdependson; a; a = a->a_next) { print(" \\\n\t"); pr_arg(a); } print("\n\t$(MOD) -c $(M2FLAGS) $(IFLAGS) "); pr_arg(arg); print("\n"); } } arg = arg->a_next; } } prog_dep(id) register struct idf *id; { register struct lnk *m; register struct file_list *p; id->id_mdependson = 0; id->id_def = 0; 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); for (p = iid->id_mdependson; p; p = p->a_next) { Add(&(id->id_mdependson), p->a_filename, p->a_dir, 0); } } } } module_in_arglist(n) char *n; { register struct file_list *a; for (a = arglist; a; a = a->a_next) { char *dotp = strrindex(a->a_filename, '.'); if (dotp && strcmp(dotp, ".mod") == 0) { *dotp = 0; if (strcmp(a->a_filename, n) == 0) { *dotp = '.'; return 1; } *dotp = '.'; } } return 0; } pr_prog_dep(id) register struct idf *id; { register struct file_list *p; print("\nOBS_%s = ", id->id_text); for (p = id->id_mdependson; p; p = p->a_next) { if (module_in_arglist(p->a_filename)) { print("\\\n\t%s.$(SUFFIX)", p->a_filename); } else if (! is_library_dir(p->a_dir)) { print("\\\n\t%s/%s.$(SUFFIX)", p->a_dir, p->a_filename); } } print("\n\n"); print("%s:\t$(OBS_%s)\n", id->id_text, id->id_text); print("\t$(MOD) -.mod -o %s $(M2FLAGS) $(OBS_%s)\n", id->id_text, id->id_text); } programs() { register struct file_list *a; for (a = arglist; a; a = a->a_next) { char *dotspot = strrindex(a->a_filename, '.'); if (dotspot && strcmp(dotspot, ".mod") == 0) { register struct idf *id = a->a_idf; if (id && id->id_type == PROGRAM) { prog_dep(id); pr_prog_dep(id); } } } }