ack/lang/m2/comp/defmodule.c
George Koehler 229b80a004 Free buf in GetFile().
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.
2017-11-13 21:34:31 -05:00

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;
}