mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-03-11 22:53:13 +01:00
First merge of 2.064 beta.
This corresponds to DMD commit a913ce4bc59a94a022a27e390fc841f4aededffb. Doesn't build Phobos yet.
This commit is contained in:
committed by
Kai Nacke
parent
c400d180d2
commit
cb341586e3
367
dmd2/module.c
367
dmd2/module.c
@@ -34,8 +34,11 @@ DsymbolTable *Module::modules;
|
||||
Modules Module::amodules;
|
||||
|
||||
Dsymbols Module::deferred; // deferred Dsymbol's needing semantic() run on them
|
||||
Dsymbols Module::deferred3;
|
||||
unsigned Module::dprogress;
|
||||
|
||||
const char *lookForSourceFile(const char *filename);
|
||||
|
||||
void Module::init()
|
||||
{
|
||||
modules = new DsymbolTable();
|
||||
@@ -59,13 +62,7 @@ Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen
|
||||
needmoduleinfo = 0;
|
||||
selfimports = 0;
|
||||
insearch = 0;
|
||||
searchCacheIdent = NULL;
|
||||
searchCacheSymbol = NULL;
|
||||
searchCacheFlags = 0;
|
||||
semanticstarted = 0;
|
||||
semanticRun = 0;
|
||||
decldefs = NULL;
|
||||
vmoduleinfo = NULL;
|
||||
#if IN_DMD
|
||||
massert = NULL;
|
||||
munittest = NULL;
|
||||
@@ -78,7 +75,6 @@ Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen
|
||||
stest = NULL;
|
||||
sfilename = NULL;
|
||||
#endif
|
||||
root = 0;
|
||||
importedFrom = NULL;
|
||||
srcfile = NULL;
|
||||
objfile = NULL;
|
||||
@@ -134,7 +130,6 @@ Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen
|
||||
moduleInfoVar = NULL;
|
||||
this->doDocComment = doDocComment;
|
||||
this->doHdrGen = doHdrGen;
|
||||
this->isRoot = false;
|
||||
this->arrayfuncs = 0;
|
||||
#endif
|
||||
}
|
||||
@@ -241,55 +236,23 @@ Module *Module::load(Loc loc, Identifiers *packages, Identifier *ident)
|
||||
m = new Module(filename, ident, 0, 0);
|
||||
m->loc = loc;
|
||||
|
||||
/* Search along global.path for .di file, then .d file.
|
||||
/* Look for the source file
|
||||
*/
|
||||
const char *result = NULL;
|
||||
const char *fdi = FileName::forceExt(filename, global.hdr_ext);
|
||||
const char *fd = FileName::forceExt(filename, global.mars_ext);
|
||||
const char *sdi = fdi;
|
||||
const char *sd = fd;
|
||||
|
||||
if (FileName::exists(sdi))
|
||||
result = sdi;
|
||||
else if (FileName::exists(sd))
|
||||
result = sd;
|
||||
else if (FileName::absolute(filename))
|
||||
;
|
||||
else if (!global.path)
|
||||
;
|
||||
else
|
||||
{
|
||||
for (size_t i = 0; i < global.path->dim; i++)
|
||||
{
|
||||
const char *p = (*global.path)[i];
|
||||
const char *n = FileName::combine(p, sdi);
|
||||
if (FileName::exists(n))
|
||||
{ result = n;
|
||||
break;
|
||||
}
|
||||
FileName::free(n);
|
||||
n = FileName::combine(p, sd);
|
||||
if (FileName::exists(n))
|
||||
{ result = n;
|
||||
break;
|
||||
}
|
||||
FileName::free(n);
|
||||
}
|
||||
}
|
||||
const char *result = lookForSourceFile(filename);
|
||||
if (result)
|
||||
m->srcfile = new File(result);
|
||||
|
||||
if (global.params.verbose)
|
||||
{
|
||||
printf("import ");
|
||||
fprintf(global.stdmsg, "import ");
|
||||
if (packages)
|
||||
{
|
||||
for (size_t i = 0; i < packages->dim; i++)
|
||||
{ Identifier *pid = (*packages)[i];
|
||||
printf("%s.", pid->toChars());
|
||||
fprintf(global.stdmsg, "%s.", pid->toChars());
|
||||
}
|
||||
}
|
||||
printf("%s\t(%s)\n", ident->toChars(), m->srcfile->toChars());
|
||||
fprintf(global.stdmsg, "%s\t(%s)\n", ident->toChars(), m->srcfile->toChars());
|
||||
}
|
||||
|
||||
if (!m->read(loc))
|
||||
@@ -316,7 +279,15 @@ bool Module::read(Loc loc)
|
||||
}
|
||||
else
|
||||
{
|
||||
error(loc, "is in file '%s' which cannot be read", srcfile->toChars());
|
||||
// if module is not named 'package' but we're trying to read 'package.d', we're looking for a package module
|
||||
bool isPackageMod = (strcmp(toChars(), "package") != 0) &&
|
||||
(strcmp(srcfile->name->name(), "package.d") == 0);
|
||||
|
||||
if (isPackageMod)
|
||||
::error(loc, "importing package '%s' requires a 'package.d' file which cannot be found in '%s'",
|
||||
toChars(), srcfile->toChars());
|
||||
else
|
||||
error(loc, "is in file '%s' which cannot be read", srcfile->toChars());
|
||||
}
|
||||
|
||||
if (!global.gag)
|
||||
@@ -422,7 +393,7 @@ void Module::parse()
|
||||
char *srcname = srcfile->name->toChars();
|
||||
//printf("Module::parse(srcname = '%s')\n", srcname);
|
||||
|
||||
unsigned char *buf = srcfile->buffer;
|
||||
utf8_t *buf = srcfile->buffer;
|
||||
size_t buflen = srcfile->len;
|
||||
|
||||
if (buflen >= 2)
|
||||
@@ -472,7 +443,7 @@ void Module::parse()
|
||||
}
|
||||
dbuf.writeByte(0); // add 0 as sentinel for scanner
|
||||
buflen = dbuf.offset - 1; // don't include sentinel in count
|
||||
buf = (unsigned char *) dbuf.extractData();
|
||||
buf = (utf8_t *) dbuf.extractData();
|
||||
}
|
||||
else
|
||||
{ // UTF-16LE (X86)
|
||||
@@ -525,7 +496,7 @@ void Module::parse()
|
||||
}
|
||||
dbuf.writeByte(0); // add 0 as sentinel for scanner
|
||||
buflen = dbuf.offset - 1; // don't include sentinel in count
|
||||
buf = (unsigned char *) dbuf.extractData();
|
||||
buf = (utf8_t *) dbuf.extractData();
|
||||
}
|
||||
}
|
||||
else if (buf[0] == 0xFE && buf[1] == 0xFF)
|
||||
@@ -586,14 +557,6 @@ void Module::parse()
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef IN_GCC
|
||||
// dump utf-8 encoded source
|
||||
if (global.params.dump_source)
|
||||
{ // %% srcname could contain a path ...
|
||||
d_gcc_dump_source(srcname, "utf-8", buf, buflen);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If it starts with the string "Ddoc", then it's a documentation
|
||||
* source file.
|
||||
*/
|
||||
@@ -623,25 +586,36 @@ void Module::parse()
|
||||
srcfile->len = 0;
|
||||
|
||||
md = p.md;
|
||||
numlines = p.loc.linnum;
|
||||
numlines = p.scanloc.linnum;
|
||||
|
||||
/* The symbol table into which the module is to be inserted.
|
||||
*/
|
||||
DsymbolTable *dst;
|
||||
|
||||
if (md)
|
||||
{ this->ident = md->id;
|
||||
{ /* A ModuleDeclaration, md, was provided.
|
||||
* The ModuleDeclaration sets the packages this module appears in, and
|
||||
* the name of this module.
|
||||
*/
|
||||
this->ident = md->id;
|
||||
this->safe = md->safe;
|
||||
Package *ppack = NULL;
|
||||
dst = Package::resolve(md->packages, &this->parent, &ppack);
|
||||
assert(dst);
|
||||
#if 0
|
||||
if (ppack && ppack->isModule())
|
||||
{
|
||||
error(loc, "package name '%s' in file %s conflicts with usage as a module name in file %s",
|
||||
ppack->toChars(), srcname, ppack->isModule()->srcfile->toChars());
|
||||
dst = modules;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
dst = modules;
|
||||
{ /* The name of the module is set to the source file name.
|
||||
* There are no packages.
|
||||
*/
|
||||
dst = modules; // and so this module goes into global module symbol table
|
||||
|
||||
/* Check to see if module name is a valid identifier
|
||||
*/
|
||||
@@ -649,9 +623,40 @@ void Module::parse()
|
||||
error("has non-identifier characters in filename, use module declaration instead");
|
||||
}
|
||||
|
||||
// Update global list of modules
|
||||
if (!dst->insert(this))
|
||||
// Insert module into the symbol table
|
||||
Dsymbol *s = this;
|
||||
bool isPackageMod = strcmp(srcfile->name->name(), "package.d") == 0;
|
||||
if (isPackageMod)
|
||||
{
|
||||
/* If the source tree is as follows:
|
||||
* pkg/
|
||||
* +- package.d
|
||||
* +- common.d
|
||||
* the 'pkg' will be incorporated to the internal package tree in two ways:
|
||||
* import pkg;
|
||||
* and:
|
||||
* import pkg.common;
|
||||
*
|
||||
* If both are used in one compilation, 'pkg' as a module (== pkg/package.d)
|
||||
* and a package name 'pkg' will conflict each other.
|
||||
*
|
||||
* To avoid the conflict:
|
||||
* 1. If preceding package name insertion had occurred by Package::resolve,
|
||||
* later package.d loading will change Package::isPkgMod to PKGmodule and set Package::mod.
|
||||
* 2. Otherwise, 'package.d' wrapped by 'Package' is inserted to the internal tree in here.
|
||||
*/
|
||||
Package *p = new Package(ident);
|
||||
p->parent = this->parent;
|
||||
p->isPkgMod = PKGmodule;
|
||||
p->mod = this;
|
||||
p->symtab = new DsymbolTable();
|
||||
s = p;
|
||||
}
|
||||
if (!dst->insert(s))
|
||||
{
|
||||
/* It conflicts with a name that is already in the symbol table.
|
||||
* Figure out what went wrong, and issue error message.
|
||||
*/
|
||||
Dsymbol *prev = dst->lookup(ident);
|
||||
assert(prev);
|
||||
Module *mprev = prev->isModule();
|
||||
@@ -668,12 +673,22 @@ void Module::parse()
|
||||
{
|
||||
Package *pkg = prev->isPackage();
|
||||
assert(pkg);
|
||||
error(pkg->loc, "from file %s conflicts with package name %s",
|
||||
srcname, pkg->toChars());
|
||||
if (pkg->isPkgMod == PKGunknown && isPackageMod)
|
||||
{
|
||||
/* If the previous inserted Package is not yet determined as package.d,
|
||||
* link it to the actual module.
|
||||
*/
|
||||
pkg->isPkgMod = PKGmodule;
|
||||
pkg->mod = this;
|
||||
}
|
||||
else
|
||||
error(pkg->loc, "from file %s conflicts with package name %s",
|
||||
srcname, pkg->toChars());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add to global array of all modules
|
||||
amodules.push(this);
|
||||
}
|
||||
}
|
||||
@@ -743,18 +758,18 @@ void Module::importAll(Scope *prevsc)
|
||||
|
||||
void Module::semantic()
|
||||
{
|
||||
if (semanticstarted)
|
||||
if (semanticRun != PASSinit)
|
||||
return;
|
||||
|
||||
//printf("+Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent);
|
||||
semanticstarted = 1;
|
||||
semanticRun = PASSsemantic;
|
||||
|
||||
// Note that modules get their own scope, from scratch.
|
||||
// This is so regardless of where in the syntax a module
|
||||
// gets imported, it is unaffected by context.
|
||||
Scope *sc = scope; // see if already got one from importAll()
|
||||
if (!sc)
|
||||
{ printf("test2\n");
|
||||
{
|
||||
Scope::createGlobal(this); // create root scope
|
||||
}
|
||||
|
||||
@@ -786,14 +801,6 @@ void Module::semantic()
|
||||
}
|
||||
#endif
|
||||
|
||||
// Do semantic() on members that don't depend on others
|
||||
for (size_t i = 0; i < members->dim; i++)
|
||||
{ Dsymbol *s = (*members)[i];
|
||||
|
||||
//printf("\tModule('%s'): '%s'.semantic0()\n", toChars(), s->toChars());
|
||||
s->semantic0(sc);
|
||||
}
|
||||
|
||||
// Pass 1 semantic routines: do public side of the definition
|
||||
for (size_t i = 0; i < members->dim; i++)
|
||||
{ Dsymbol *s = (*members)[i];
|
||||
@@ -807,7 +814,7 @@ void Module::semantic()
|
||||
{ sc = sc->pop();
|
||||
sc->pop(); // 2 pops because Scope::createGlobal() created 2
|
||||
}
|
||||
semanticRun = semanticstarted;
|
||||
semanticRun = PASSsemanticdone;
|
||||
//printf("-Module::semantic(this = %p, '%s'): parent = %p\n", this, toChars(), parent);
|
||||
}
|
||||
|
||||
@@ -824,12 +831,9 @@ void Module::semantic2()
|
||||
return;
|
||||
}
|
||||
//printf("Module::semantic2('%s'): parent = %p\n", toChars(), parent);
|
||||
if (semanticRun == 0) // semantic() not completed yet - could be recursive call
|
||||
if (semanticRun != PASSsemanticdone) // semantic() not completed yet - could be recursive call
|
||||
return;
|
||||
if (semanticstarted >= 2)
|
||||
return;
|
||||
assert(semanticstarted == 1);
|
||||
semanticstarted = 2;
|
||||
semanticRun = PASSsemantic2;
|
||||
|
||||
// Note that modules get their own scope, from scratch.
|
||||
// This is so regardless of where in the syntax a module
|
||||
@@ -847,17 +851,16 @@ void Module::semantic2()
|
||||
|
||||
sc = sc->pop();
|
||||
sc->pop();
|
||||
semanticRun = semanticstarted;
|
||||
semanticRun = PASSsemantic2done;
|
||||
//printf("-Module::semantic2('%s'): parent = %p\n", toChars(), parent);
|
||||
}
|
||||
|
||||
void Module::semantic3()
|
||||
{
|
||||
//printf("Module::semantic3('%s'): parent = %p\n", toChars(), parent);
|
||||
if (semanticstarted >= 3)
|
||||
if (semanticRun != PASSsemantic2done)
|
||||
return;
|
||||
assert(semanticstarted == 2);
|
||||
semanticstarted = 3;
|
||||
semanticRun = PASSsemantic3;
|
||||
|
||||
// Note that modules get their own scope, from scratch.
|
||||
// This is so regardless of where in the syntax a module
|
||||
@@ -876,15 +879,14 @@ void Module::semantic3()
|
||||
|
||||
sc = sc->pop();
|
||||
sc->pop();
|
||||
semanticRun = semanticstarted;
|
||||
semanticRun = PASSsemantic3done;
|
||||
}
|
||||
|
||||
void Module::inlineScan()
|
||||
{
|
||||
if (semanticstarted >= 4)
|
||||
if (semanticRun != PASSsemantic3done)
|
||||
return;
|
||||
assert(semanticstarted == 3);
|
||||
semanticstarted = 4;
|
||||
semanticRun = PASSinline;
|
||||
|
||||
// Note that modules get their own scope, from scratch.
|
||||
// This is so regardless of where in the syntax a module
|
||||
@@ -894,11 +896,11 @@ void Module::inlineScan()
|
||||
for (size_t i = 0; i < members->dim; i++)
|
||||
{ Dsymbol *s = (*members)[i];
|
||||
//if (global.params.verbose)
|
||||
//printf("inline scan symbol %s\n", s->toChars());
|
||||
//fprintf(global.stdmsg, "inline scan symbol %s\n", s->toChars());
|
||||
|
||||
s->inlineScan();
|
||||
}
|
||||
semanticRun = semanticstarted;
|
||||
semanticRun = PASSinlinedone;
|
||||
}
|
||||
|
||||
/****************************************************
|
||||
@@ -951,38 +953,15 @@ Dsymbol *Module::search(Loc loc, Identifier *ident, int flags)
|
||||
Dsymbol *s;
|
||||
if (insearch)
|
||||
s = NULL;
|
||||
else if (searchCacheIdent == ident && searchCacheFlags == flags)
|
||||
{
|
||||
s = searchCacheSymbol;
|
||||
//printf("%s Module::search('%s', flags = %d) insearch = %d searchCacheSymbol = %s\n", toChars(), ident->toChars(), flags, insearch, searchCacheSymbol ? searchCacheSymbol->toChars() : "null");
|
||||
}
|
||||
else
|
||||
{
|
||||
insearch = 1;
|
||||
s = ScopeDsymbol::search(loc, ident, flags);
|
||||
insearch = 0;
|
||||
|
||||
searchCacheIdent = ident;
|
||||
searchCacheSymbol = s;
|
||||
searchCacheFlags = flags;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
Dsymbol *Module::symtabInsert(Dsymbol *s)
|
||||
{
|
||||
searchCacheIdent = NULL; // symbol is inserted, so invalidate cache
|
||||
return Package::symtabInsert(s);
|
||||
}
|
||||
|
||||
void Module::clearCache()
|
||||
{
|
||||
for (size_t i = 0; i < amodules.dim; i++)
|
||||
{ Module *m = amodules[i];
|
||||
m->searchCacheIdent = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************
|
||||
* Can't run semantic on s now, try again later.
|
||||
*/
|
||||
@@ -1057,6 +1036,33 @@ void Module::runDeferredSemantic()
|
||||
//printf("-Module::runDeferredSemantic(), len = %d\n", deferred.dim);
|
||||
}
|
||||
|
||||
void Module::addDeferredSemantic3(Dsymbol *s)
|
||||
{
|
||||
// Don't add it if it is already there
|
||||
for (size_t i = 0; i < deferred3.dim; i++)
|
||||
{
|
||||
Dsymbol *sd = deferred3[i];
|
||||
if (sd == s)
|
||||
return;
|
||||
}
|
||||
deferred3.push(s);
|
||||
}
|
||||
|
||||
void Module::runDeferredSemantic3()
|
||||
{
|
||||
Dsymbols *a = &Module::deferred3;
|
||||
for (size_t i = 0; i < a->dim; i++)
|
||||
{
|
||||
Dsymbol *s = (*a)[i];
|
||||
//printf("[%d] %s semantic3a\n", i, s->toPrettyChars());
|
||||
|
||||
s->semantic3(NULL);
|
||||
|
||||
if (global.errors)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************
|
||||
* Recursively look at every module this module imports,
|
||||
* return TRUE if it imports m.
|
||||
@@ -1116,8 +1122,9 @@ int Module::selfImports()
|
||||
|
||||
/* =========================== ModuleDeclaration ===================== */
|
||||
|
||||
ModuleDeclaration::ModuleDeclaration(Identifiers *packages, Identifier *id, bool safe)
|
||||
ModuleDeclaration::ModuleDeclaration(Loc loc, Identifiers *packages, Identifier *id, bool safe)
|
||||
{
|
||||
this->loc = loc;
|
||||
this->packages = packages;
|
||||
this->id = id;
|
||||
this->safe = safe;
|
||||
@@ -1146,6 +1153,8 @@ char *ModuleDeclaration::toChars()
|
||||
Package::Package(Identifier *ident)
|
||||
: ScopeDsymbol(ident)
|
||||
{
|
||||
this->isPkgMod = PKGunknown;
|
||||
this->mod = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -1154,6 +1163,15 @@ const char *Package::kind()
|
||||
return "package";
|
||||
}
|
||||
|
||||
/****************************************************
|
||||
* Input:
|
||||
* packages[] the pkg1.pkg2 of pkg1.pkg2.mod
|
||||
* Returns:
|
||||
* the symbol table that mod should be inserted into
|
||||
* Output:
|
||||
* *pparent the rightmost package, i.e. pkg2, or NULL if no packages
|
||||
* *ppkg the leftmost package, i.e. pkg1, or NULL if no packages
|
||||
*/
|
||||
|
||||
DsymbolTable *Package::resolve(Identifiers *packages, Dsymbol **pparent, Package **ppkg)
|
||||
{
|
||||
@@ -1168,39 +1186,126 @@ DsymbolTable *Package::resolve(Identifiers *packages, Dsymbol **pparent, Package
|
||||
{
|
||||
for (size_t i = 0; i < packages->dim; i++)
|
||||
{ Identifier *pid = (*packages)[i];
|
||||
Dsymbol *p;
|
||||
|
||||
p = dst->lookup(pid);
|
||||
Package *pkg;
|
||||
Dsymbol *p = dst->lookup(pid);
|
||||
if (!p)
|
||||
{
|
||||
p = new Package(pid);
|
||||
dst->insert(p);
|
||||
p->parent = parent;
|
||||
((ScopeDsymbol *)p)->symtab = new DsymbolTable();
|
||||
pkg = new Package(pid);
|
||||
dst->insert(pkg);
|
||||
pkg->parent = parent;
|
||||
pkg->symtab = new DsymbolTable();
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(p->isPackage());
|
||||
pkg = p->isPackage();
|
||||
assert(pkg);
|
||||
// It might already be a module, not a package, but that needs
|
||||
// to be checked at a higher level, where a nice error message
|
||||
// can be generated.
|
||||
// dot net needs modules and packages with same name
|
||||
|
||||
// But we still need a symbol table for it
|
||||
if (!pkg->symtab)
|
||||
pkg->symtab = new DsymbolTable();
|
||||
}
|
||||
parent = p;
|
||||
dst = ((Package *)p)->symtab;
|
||||
parent = pkg;
|
||||
dst = pkg->symtab;
|
||||
if (ppkg && !*ppkg)
|
||||
*ppkg = (Package *)p;
|
||||
if (p->isModule())
|
||||
*ppkg = pkg;
|
||||
#if 0
|
||||
if (pkg->isModule())
|
||||
{ // Return the module so that a nice error message can be generated
|
||||
if (ppkg)
|
||||
*ppkg = (Package *)p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pparent)
|
||||
{
|
||||
*pparent = parent;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (pparent)
|
||||
*pparent = parent;
|
||||
return dst;
|
||||
}
|
||||
|
||||
Dsymbol *Package::search(Loc loc, Identifier *ident, int flags)
|
||||
{
|
||||
if (!isModule() && mod)
|
||||
{
|
||||
// Prefer full package name.
|
||||
Dsymbol *s = symtab ? symtab->lookup(ident) : NULL;
|
||||
if (s)
|
||||
return s;
|
||||
//printf("[%s] through pkdmod: %s\n", loc.toChars(), toChars());
|
||||
return mod->search(loc, ident, flags);
|
||||
}
|
||||
|
||||
return ScopeDsymbol::search(loc, ident, flags);
|
||||
}
|
||||
|
||||
/* =========================== ===================== */
|
||||
|
||||
/********************************************
|
||||
* Look for the source file if it's different from filename.
|
||||
* Look for .di, .d, directory, and along global.path.
|
||||
* Does not open the file.
|
||||
* Input:
|
||||
* filename as supplied by the user
|
||||
* global.path
|
||||
* Returns:
|
||||
* NULL if it's not different from filename.
|
||||
*/
|
||||
|
||||
const char *lookForSourceFile(const char *filename)
|
||||
{
|
||||
|
||||
/* Search along global.path for .di file, then .d file.
|
||||
*/
|
||||
|
||||
const char *sdi = FileName::forceExt(filename, global.hdr_ext);
|
||||
if (FileName::exists(sdi) == 1)
|
||||
return sdi;
|
||||
|
||||
const char *sd = FileName::forceExt(filename, global.mars_ext);
|
||||
if (FileName::exists(sd) == 1)
|
||||
return sd;
|
||||
|
||||
if (FileName::exists(filename) == 2)
|
||||
{
|
||||
/* The filename exists and it's a directory.
|
||||
* Therefore, the result should be: filename/package.d
|
||||
*/
|
||||
return FileName::combine(filename, "package.d");
|
||||
}
|
||||
|
||||
if (FileName::absolute(filename))
|
||||
return NULL;
|
||||
|
||||
if (!global.path)
|
||||
return NULL;
|
||||
|
||||
for (size_t i = 0; i < global.path->dim; i++)
|
||||
{
|
||||
const char *p = (*global.path)[i];
|
||||
|
||||
const char *n = FileName::combine(p, sdi);
|
||||
if (FileName::exists(n) == 1)
|
||||
return n;
|
||||
FileName::free(n);
|
||||
|
||||
n = FileName::combine(p, sd);
|
||||
if (FileName::exists(n) == 1)
|
||||
return n;
|
||||
FileName::free(n);
|
||||
|
||||
const char *b = FileName::removeExt(filename);
|
||||
n = FileName::combine(p, b);
|
||||
FileName::free(b);
|
||||
if (FileName::exists(n) == 2)
|
||||
return FileName::combine(n, "package.d");
|
||||
FileName::free(n);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user