ack/lang/m2/m2mm/main.c
1987-09-28 13:45:24 +00:00

409 lines
8.1 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 *
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;
if (f == 0) return;
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_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;
a->a_filename = Salloc(a->a_filename,
strlen(a->a_filename) +
(unsigned)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");
}
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) {
if (*(a->a_filename)) {
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) || ! p->a_dir) {
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);
}
}
}
}