/* * (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 */ /* D E F I N I T I O N M O D U L E S */ /* $Id$ */ #include "debug.h" #include "parameters.h" #include #include #include #include #include #include #include "LLlex.h" #include "Lpars.h" #include "def.h" #include "f_info.h" #include "idf.h" #include "input.h" #include "main.h" #include "misc.h" #include "node.h" #include "scope.h" #include "type.h" #ifdef DEBUG long sys_filesize(); #endif t_idf* DefId; char* getwdir(fn) register char* fn; { register char* p; char* strrchr(); while ((p = strrchr(fn, '/')) && *(p + 1) == '\0') { /* remove trailing /'s */ *p = '\0'; } if (p) { *p = '\0'; fn = Salloc(fn, (unsigned)(p - &fn[0] + 1)); *p = '/'; return fn; } return ""; } STATIC int GetFile(name) char* name; { /* Try to find a file with basename "name" and extension ".def", in the directories mentioned in "DEFPATH". */ size_t len; int found; char *buf; len = strlen(name); buf = Malloc(len + 5); memcpy(buf, name, len); memcpy(buf + len, ".def", 5); DEFPATH[0] = WorkingDir; found = InsertFile(buf, DEFPATH, &(FileName)); free(buf); if (!found) { error("could not find a DEFINITION MODULE for \"%s\"", name); return 0; } WorkingDir = getwdir(FileName); LineNumber = 1; DO_DEBUG(options['F'], debug("File %s : %ld characters", FileName, sys_filesize(FileName))); return 1; } t_def* GetDefinitionModule(id, incr) register t_idf* id; { /* Return a pointer to the "def" structure of the definition module indicated by "id". We may have to read the definition module itself. Also increment level by "incr". */ register t_def* df; static int level; t_scopelist* vis; char* fn = FileName; int ln = LineNumber; t_scope* newsc; level += incr; df = lookup(id, GlobalScope, D_IMPORTED, 0); if (!df) { /* Read definition module. Make an exception for SYSTEM. */ extern int ForeignFlag; ForeignFlag = 0; DefId = id; open_scope(CLOSEDSCOPE); newsc = CurrentScope; vis = CurrVis; newsc->sc_defmodule = incr; if (!strcmp(id->id_text, "SYSTEM")) { do_SYSTEM(); df = lookup(id, GlobalScope, D_IMPORTED, 0); } else { if (!is_anon_idf(id) && GetFile(id->id_text)) { char* f = FileName; DefModule(); df = lookup(id, GlobalScope, D_IMPORTED, 0); if (level == 1 && (df && !(df->df_flags & D_FOREIGN))) { /* The module is directly imported by the currently defined module, and is not foreign, so we have to remember its name because we have to call its initialization routine */ static t_node* nd_end; register t_node* n; extern t_node* Modules; n = dot2leaf(Def); n->nd_def = newsc->sc_definedby; if (nd_end) nd_end->nd_NEXT = n; else Modules = n; nd_end = n; } free(f); } else { df = lookup(id, GlobalScope, D_IMPORTED, 0); newsc->sc_name = id->id_text; } } close_scope(SC_CHKFORW); if (!df) { df = MkDef(id, GlobalScope, D_ERROR); df->mod_vis = vis; newsc->sc_definedby = df; } } else if (df->df_flags & D_BUSY) { error("definition module \"%s\" depends on itself", id->id_text); } else if (df == Defined && level == 1) { error("cannot import from current module \"%s\"", id->id_text); df->df_kind = D_ERROR; } FileName = fn; LineNumber = ln; assert(df); level -= incr; return df; }