229b80a004
aprintf() returns a const char *; the assignment to char * caused both
clang and gcc to warn of the dropped const.
Commit 893471a
introduced a tiny memory leak, because GetFile()
stopped freeing buf. The const return type of aprintf() suggests that
the buffer must not be freed.
Now use Malloc() to allocate the buffer and free() to free it. This
also checks if we are out of memory, because Malloc() does the check
and aprintf() currently doesn't.
184 lines
3.6 KiB
C
184 lines
3.6 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
|
|
*/
|
|
|
|
/* 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 <alloc.h>
|
|
#include <assert.h>
|
|
#include <em_arith.h>
|
|
#include <em_label.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#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;
|
|
}
|