| 1 |
/************************************************************************** |
|---|
| 2 |
|
|---|
| 3 |
@file source.d |
|---|
| 4 |
|
|---|
| 5 |
Copyright (c) 2005 Derek Parnell |
|---|
| 6 |
|
|---|
| 7 |
This software is provided 'as-is', without any express or implied |
|---|
| 8 |
warranty. In no event will the authors be held liable for damages |
|---|
| 9 |
of any kind arising from the use of this software. |
|---|
| 10 |
|
|---|
| 11 |
Permission is hereby granted to anyone to use this software for any |
|---|
| 12 |
purpose, including commercial applications, and to alter it and/or |
|---|
| 13 |
redistribute it freely, subject to the following restrictions: |
|---|
| 14 |
|
|---|
| 15 |
1. The origin of this software must not be misrepresented; you must |
|---|
| 16 |
not claim that you wrote the original software. If you use this |
|---|
| 17 |
software in a product, an acknowledgment within documentation of |
|---|
| 18 |
said product would be appreciated but is not required. |
|---|
| 19 |
|
|---|
| 20 |
2. Altered source versions must be plainly marked as such, and must |
|---|
| 21 |
not be misrepresented as being the original software. |
|---|
| 22 |
|
|---|
| 23 |
3. This notice may not be removed or altered from any distribution |
|---|
| 24 |
of the source. |
|---|
| 25 |
|
|---|
| 26 |
4. Derivative works are permitted, but they must carry this notice |
|---|
| 27 |
in full and credit the original source. |
|---|
| 28 |
|
|---|
| 29 |
|
|---|
| 30 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 31 |
|
|---|
| 32 |
|
|---|
| 33 |
@version Initial version, January 2005 |
|---|
| 34 |
@author Derek Parnell |
|---|
| 35 |
|
|---|
| 36 |
|
|---|
| 37 |
**************************************************************************/ |
|---|
| 38 |
|
|---|
| 39 |
module source; |
|---|
| 40 |
private import source_bn; // Build number for this module |
|---|
| 41 |
version(D_Version2) |
|---|
| 42 |
{ |
|---|
| 43 |
mixin("alias const(wchar)[] wstring;"); |
|---|
| 44 |
mixin("alias const(dchar)[] dstring;"); |
|---|
| 45 |
mixin("alias const(dchar) dcharc;"); |
|---|
| 46 |
mixin("alias const(wchar) wcharc;"); |
|---|
| 47 |
mixin("alias const(char) charc;"); |
|---|
| 48 |
} |
|---|
| 49 |
else |
|---|
| 50 |
{ |
|---|
| 51 |
alias char[] string; |
|---|
| 52 |
alias wchar[] wstring; |
|---|
| 53 |
alias dchar[] dstring; |
|---|
| 54 |
alias wchar wcharc; |
|---|
| 55 |
alias dchar dcharc; |
|---|
| 56 |
alias char charc; |
|---|
| 57 |
} |
|---|
| 58 |
|
|---|
| 59 |
|
|---|
| 60 |
version(unix) version = Unix; |
|---|
| 61 |
version(Unix) version = Posix; |
|---|
| 62 |
version(linux) version = Posix; |
|---|
| 63 |
version(darwin) version = Posix; |
|---|
| 64 |
|
|---|
| 65 |
private |
|---|
| 66 |
{ |
|---|
| 67 |
// alias char[] string; |
|---|
| 68 |
|
|---|
| 69 |
static import opts; |
|---|
| 70 |
|
|---|
| 71 |
static import util.str; |
|---|
| 72 |
static import util.fdt; |
|---|
| 73 |
static import util.pathex; |
|---|
| 74 |
static import util.fileex; |
|---|
| 75 |
static import util.macroex; |
|---|
| 76 |
static import util.booltype; // definition of True and False |
|---|
| 77 |
alias util.booltype.True True; |
|---|
| 78 |
alias util.booltype.False False; |
|---|
| 79 |
alias util.booltype.Bool Bool; |
|---|
| 80 |
|
|---|
| 81 |
static import std.stdio; |
|---|
| 82 |
static import std.path; |
|---|
| 83 |
static import std.ctype; |
|---|
| 84 |
static import std.file; |
|---|
| 85 |
static import std.string; |
|---|
| 86 |
} |
|---|
| 87 |
|
|---|
| 88 |
public |
|---|
| 89 |
{ |
|---|
| 90 |
enum eRuleUsage |
|---|
| 91 |
{ |
|---|
| 92 |
Ignore, |
|---|
| 93 |
Compile, |
|---|
| 94 |
Link |
|---|
| 95 |
} |
|---|
| 96 |
string function(string pPath) AddRoot; |
|---|
| 97 |
void function(string pArg) AddCompilerArg; |
|---|
| 98 |
string[] function () GetImportRoots; |
|---|
| 99 |
Bool function() AutoImports; |
|---|
| 100 |
void function(string pPath) AddTarget; |
|---|
| 101 |
void function(string pPath) AddLink; |
|---|
| 102 |
void function(string pText, bool pReplace=false) AddBuildDef; |
|---|
| 103 |
string[] function( ) ModulesToIgnore; |
|---|
| 104 |
string function(string pFile, string[] pScanList = null) GetFullPathname; |
|---|
| 105 |
string function(string pFile, int pScanList) GetFullPathnameScan; |
|---|
| 106 |
string function() GetAppPath; |
|---|
| 107 |
|
|---|
| 108 |
Bool mMacroInput; |
|---|
| 109 |
Bool mCollectUses; |
|---|
| 110 |
string ObjWritePath; |
|---|
| 111 |
|
|---|
| 112 |
} |
|---|
| 113 |
|
|---|
| 114 |
private |
|---|
| 115 |
{ |
|---|
| 116 |
import util.str; |
|---|
| 117 |
import util.fdt; |
|---|
| 118 |
import util.pathex; |
|---|
| 119 |
import util.fileex; |
|---|
| 120 |
import util.macroex; |
|---|
| 121 |
import util.booltype; |
|---|
| 122 |
|
|---|
| 123 |
import std.stdio; |
|---|
| 124 |
import std.path; |
|---|
| 125 |
import std.ctype; |
|---|
| 126 |
import std.file; |
|---|
| 127 |
import std.string; |
|---|
| 128 |
|
|---|
| 129 |
const { |
|---|
| 130 |
|
|---|
| 131 |
// Using these as the literals confuses my text editor's |
|---|
| 132 |
// 'bracket matching' algorithm. |
|---|
| 133 |
static string kOpenBrace = "\x7B"; |
|---|
| 134 |
static string kCloseBrace = "\x7D"; |
|---|
| 135 |
static string kOpenParen = "\x28"; |
|---|
| 136 |
static string kCloseParen = "\x29"; |
|---|
| 137 |
|
|---|
| 138 |
} |
|---|
| 139 |
|
|---|
| 140 |
bool [string] AttributeBlocks; |
|---|
| 141 |
Bool mainFound; |
|---|
| 142 |
bool mainGUI; |
|---|
| 143 |
bool mainDLL; |
|---|
| 144 |
bool[string] vActiveVersions; |
|---|
| 145 |
long vVersionLevel = 0; |
|---|
| 146 |
bool[string] vActiveDebugs; |
|---|
| 147 |
long vDebugLevel = 0; |
|---|
| 148 |
string[eRuleUsage] vUseNames; |
|---|
| 149 |
|
|---|
| 150 |
|
|---|
| 151 |
class SourceException : Error |
|---|
| 152 |
{ |
|---|
| 153 |
this(string pMsg) |
|---|
| 154 |
{ |
|---|
| 155 |
super (Source.classinfo.name ~ ":" ~ pMsg); |
|---|
| 156 |
} |
|---|
| 157 |
} |
|---|
| 158 |
|
|---|
| 159 |
} |
|---|
| 160 |
|
|---|
| 161 |
debug(1) |
|---|
| 162 |
{ |
|---|
| 163 |
private import std.stdio; |
|---|
| 164 |
} |
|---|
| 165 |
|
|---|
| 166 |
// Module Constructor ----------------- |
|---|
| 167 |
static this() |
|---|
| 168 |
{ |
|---|
| 169 |
AttributeBlocks["private"] = true; |
|---|
| 170 |
AttributeBlocks["package"] = true; |
|---|
| 171 |
AttributeBlocks["protected"] = true; |
|---|
| 172 |
AttributeBlocks["public"] = true; |
|---|
| 173 |
AttributeBlocks["export"] = true; |
|---|
| 174 |
mMacroInput = False; |
|---|
| 175 |
mainFound = False; |
|---|
| 176 |
vUseNames[eRuleUsage.Ignore] = "ignore"; |
|---|
| 177 |
vUseNames[eRuleUsage.Compile] = "compile"; |
|---|
| 178 |
vUseNames[eRuleUsage.Link] = "link"; |
|---|
| 179 |
debug(1) |
|---|
| 180 |
{ |
|---|
| 181 |
writefln("%s: " ~ __FILE__ ~ " build #%d", opts.MyName, source_bn.auto_build_number); |
|---|
| 182 |
} |
|---|
| 183 |
} |
|---|
| 184 |
|
|---|
| 185 |
// Module Destructor ----------------- |
|---|
| 186 |
static ~this() |
|---|
| 187 |
{ |
|---|
| 188 |
// Clean up any resources held by the source files. |
|---|
| 189 |
Source.Finalize(); |
|---|
| 190 |
} |
|---|
| 191 |
|
|---|
| 192 |
// Class ----------------- |
|---|
| 193 |
public class Source { |
|---|
| 194 |
static { |
|---|
| 195 |
private |
|---|
| 196 |
{ |
|---|
| 197 |
Source[string] smSourceIndex; |
|---|
| 198 |
string[] smScanOrder; |
|---|
| 199 |
bool[string] smUses; |
|---|
| 200 |
bool[string] smUsedBy; |
|---|
| 201 |
} |
|---|
| 202 |
public |
|---|
| 203 |
{ |
|---|
| 204 |
enum EMode |
|---|
| 205 |
{ |
|---|
| 206 |
New, // Must be a new source file |
|---|
| 207 |
Update // Must update an existing record |
|---|
| 208 |
} |
|---|
| 209 |
int FileCount() { return smSourceIndex.length; } |
|---|
| 210 |
|
|---|
| 211 |
Source opIndex(string pFileName) |
|---|
| 212 |
{ |
|---|
| 213 |
Source* lObject; |
|---|
| 214 |
if ((lObject = (pFileName in smSourceIndex)) !is null) |
|---|
| 215 |
return *lObject; |
|---|
| 216 |
if ((lObject = (ReducePathName(pFileName) in smSourceIndex)) !is null) |
|---|
| 217 |
return *lObject; |
|---|
| 218 |
return null; |
|---|
| 219 |
} |
|---|
| 220 |
|
|---|
| 221 |
int AllFiles(int delegate(inout int lCnt, inout Source) dg) |
|---|
| 222 |
{ |
|---|
| 223 |
int result = 0; |
|---|
| 224 |
int lCnt = 0; |
|---|
| 225 |
|
|---|
| 226 |
foreach (string lFileName; smScanOrder) |
|---|
| 227 |
{ |
|---|
| 228 |
result = dg(lCnt, smSourceIndex[lFileName]); |
|---|
| 229 |
if (result != 0) |
|---|
| 230 |
break; |
|---|
| 231 |
lCnt++; |
|---|
| 232 |
} |
|---|
| 233 |
return result; |
|---|
| 234 |
} |
|---|
| 235 |
|
|---|
| 236 |
string[] AllFiles() |
|---|
| 237 |
{ |
|---|
| 238 |
return smScanOrder; |
|---|
| 239 |
} |
|---|
| 240 |
|
|---|
| 241 |
string[] Uses() { return smUses.keys; } |
|---|
| 242 |
string[] UsedBy() { return smUsedBy.keys; } |
|---|
| 243 |
|
|---|
| 244 |
} |
|---|
| 245 |
} // static |
|---|
| 246 |
|
|---|
| 247 |
private |
|---|
| 248 |
{ |
|---|
| 249 |
string mFileName; |
|---|
| 250 |
string mModuleName; |
|---|
| 251 |
string mObjectName; |
|---|
| 252 |
FileDateTime mObjectTime; /* time of object file, must be newest, otherwise compile */ |
|---|
| 253 |
FileDateTime mDependantsTime; /* time of newest of all dependencies */ |
|---|
| 254 |
FileDateTime mFileTime; |
|---|
| 255 |
bool mHasBeenSearched; |
|---|
| 256 |
bool mNoLink; |
|---|
| 257 |
bool mNoCompile; |
|---|
| 258 |
bool mIgnore; |
|---|
| 259 |
int mBuildNumber; |
|---|
| 260 |
string[] mReferencedImports; |
|---|
| 261 |
bool[string] mActiveVersions; |
|---|
| 262 |
long mVersionLevel = 0; |
|---|
| 263 |
bool[string] mActiveDebugs; |
|---|
| 264 |
long mDebugLevel = 0; |
|---|
| 265 |
string mLocalArgs; |
|---|
| 266 |
} // private |
|---|
| 267 |
|
|---|
| 268 |
public |
|---|
| 269 |
{ |
|---|
| 270 |
// FileName (read only) |
|---|
| 271 |
string FileName () { return mFileName; } |
|---|
| 272 |
|
|---|
| 273 |
// DependantsTime (read only) |
|---|
| 274 |
FileDateTime DependantsTime() { return mDependantsTime; } |
|---|
| 275 |
|
|---|
| 276 |
// ObjectsTime (read only) |
|---|
| 277 |
FileDateTime ObjectsTime() { return mObjectTime; } |
|---|
| 278 |
|
|---|
| 279 |
// FilesTime (read only) |
|---|
| 280 |
FileDateTime FilesTime() { return mFileTime; } |
|---|
| 281 |
|
|---|
| 282 |
// ModuleName (read only) |
|---|
| 283 |
string ModuleName() { return mModuleName; } |
|---|
| 284 |
|
|---|
| 285 |
// ObjectName (read only) |
|---|
| 286 |
string ObjectName() { return mObjectName; } |
|---|
| 287 |
|
|---|
| 288 |
// NoLink (read only) |
|---|
| 289 |
bool NoLink() { return mNoLink; } |
|---|
| 290 |
|
|---|
| 291 |
// NoCompile (read only) |
|---|
| 292 |
bool NoCompile() { return mNoCompile; } |
|---|
| 293 |
|
|---|
| 294 |
// Ignore |
|---|
| 295 |
bool Ignore() { return mIgnore; } |
|---|
| 296 |
bool Ignore(bool pNew) { mIgnore = pNew; return pNew;} |
|---|
| 297 |
|
|---|
| 298 |
// BuildNumber (read only) |
|---|
| 299 |
int BuildNumber() { return mBuildNumber; } |
|---|
| 300 |
|
|---|
| 301 |
// LocalArgs (read only) |
|---|
| 302 |
string LocalArgs () { return mLocalArgs; } |
|---|
| 303 |
|
|---|
| 304 |
// HasBeenScanned (read only) |
|---|
| 305 |
bool HasBeenScanned () { return mHasBeenSearched; } |
|---|
| 306 |
|
|---|
| 307 |
// -------------------------------------------------------------------- |
|---|
| 308 |
static void Finalize() |
|---|
| 309 |
// -------------------------------------------------------------------- |
|---|
| 310 |
{ |
|---|
| 311 |
for(int i = smScanOrder.length-1; i >= 0; i--) |
|---|
| 312 |
{ |
|---|
| 313 |
Source x; |
|---|
| 314 |
x = smSourceIndex[smScanOrder[i]]; |
|---|
| 315 |
delete x; |
|---|
| 316 |
} |
|---|
| 317 |
} |
|---|
| 318 |
// -------------------------------------------------------------------- |
|---|
| 319 |
this(string pFileName, EMode pMode = Source.EMode.New) |
|---|
| 320 |
// -------------------------------------------------------------------- |
|---|
| 321 |
{ |
|---|
| 322 |
if (pFileName in Source.smSourceIndex) |
|---|
| 323 |
{ |
|---|
| 324 |
if (pMode == Source.EMode.Update) |
|---|
| 325 |
{ |
|---|
| 326 |
Source.smSourceIndex[pFileName].create(""); |
|---|
| 327 |
} |
|---|
| 328 |
else |
|---|
| 329 |
{ |
|---|
| 330 |
mIgnore = true; |
|---|
| 331 |
mHasBeenSearched = true; |
|---|
| 332 |
mNoLink = true; |
|---|
| 333 |
} |
|---|
| 334 |
|
|---|
| 335 |
} |
|---|
| 336 |
else |
|---|
| 337 |
{ |
|---|
| 338 |
create(pFileName); |
|---|
| 339 |
} |
|---|
| 340 |
} |
|---|
| 341 |
|
|---|
| 342 |
// -------------------------------------------------------------------- |
|---|
| 343 |
void create(string pFileName) |
|---|
| 344 |
// -------------------------------------------------------------------- |
|---|
| 345 |
{ |
|---|
| 346 |
string lObjectName; |
|---|
| 347 |
|
|---|
| 348 |
mReferencedImports.length = 0; |
|---|
| 349 |
mHasBeenSearched = false; |
|---|
| 350 |
mIgnore = false; |
|---|
| 351 |
if (pFileName.length > 0) |
|---|
| 352 |
{ |
|---|
| 353 |
mFileName = pFileName; |
|---|
| 354 |
// Store this instantiation in the list of known files. |
|---|
| 355 |
smSourceIndex[pFileName] = this; |
|---|
| 356 |
} |
|---|
| 357 |
else |
|---|
| 358 |
{ |
|---|
| 359 |
pFileName = mFileName; |
|---|
| 360 |
} |
|---|
| 361 |
|
|---|
| 362 |
if (std.path.getExt(pFileName) != "ddoc") |
|---|
| 363 |
{ |
|---|
| 364 |
string lAltName; |
|---|
| 365 |
mNoLink = (std.path.getExt(pFileName) == "di"); |
|---|
| 366 |
mModuleName = FileToModulename(pFileName, lAltName); |
|---|
| 367 |
lObjectName = addExt(pFileName,opts.ObjExtension); |
|---|
| 368 |
mObjectName = ReducePathName(ExpandPathName(lObjectName, False)); |
|---|
| 369 |
} |
|---|
| 370 |
else |
|---|
| 371 |
{ |
|---|
| 372 |
mNoLink = true; |
|---|
| 373 |
mModuleName = ""; |
|---|
| 374 |
lObjectName = ""; |
|---|
| 375 |
mObjectName = ""; |
|---|
| 376 |
} |
|---|
| 377 |
|
|---|
| 378 |
/* If a specific path for object files has been supplied |
|---|
| 379 |
on the command line, and the current source file is |
|---|
| 380 |
relative to the current directory, then we need to |
|---|
| 381 |
prepend the specified object location path. |
|---|
| 382 |
*/ |
|---|
| 383 |
if (ObjWritePath.length != 0 && mObjectName.length != 0) |
|---|
| 384 |
{ |
|---|
| 385 |
if (mObjectName == lObjectName) |
|---|
| 386 |
{ |
|---|
| 387 |
mObjectName = ObjWritePath ~ std.path.getBaseName(mObjectName); |
|---|
| 388 |
util.pathex.MakePath(mObjectName); |
|---|
| 389 |
} |
|---|
| 390 |
} |
|---|
| 391 |
|
|---|
| 392 |
if (opts.UseModBaseName == True) |
|---|
| 393 |
{ |
|---|
| 394 |
mObjectName = getBaseName(mObjectName); |
|---|
| 395 |
} |
|---|
| 396 |
|
|---|
| 397 |
mBuildNumber = -1; |
|---|
| 398 |
|
|---|
| 399 |
mFileTime = new util.fdt.FileDateTime(pFileName); |
|---|
| 400 |
mDependantsTime = mFileTime; |
|---|
| 401 |
|
|---|
| 402 |
mObjectTime = new util.fdt.FileDateTime(mObjectName); |
|---|
| 403 |
UpdateDependantTime(mObjectTime); |
|---|
| 404 |
version(BuildVerbose) |
|---|
| 405 |
{ |
|---|
| 406 |
if(opts.Verbose == True) |
|---|
| 407 |
{ |
|---|
| 408 |
if (mFileTime !is null) |
|---|
| 409 |
writefln("%s: Time %s for source %s", opts.MyName, mFileTime.toString(), mFileName); |
|---|
| 410 |
|
|---|
| 411 |
if (mObjectTime !is null) |
|---|
| 412 |
writefln("%s: Time %s for object %s", opts.MyName, mObjectTime.toString(), mObjectName); |
|---|
| 413 |
} |
|---|
| 414 |
} |
|---|
| 415 |
|
|---|
| 416 |
search(); |
|---|
| 417 |
} |
|---|
| 418 |
|
|---|
| 419 |
debug(dtor) |
|---|
| 420 |
{ |
|---|
| 421 |
// -------------------------------------------------------------------- |
|---|
| 422 |
~this() |
|---|
| 423 |
// -------------------------------------------------------------------- |
|---|
| 424 |
{ |
|---|
| 425 |
writefln("%s: Finis: %s", opts.MyName, mFileName); |
|---|
| 426 |
} |
|---|
| 427 |
} |
|---|
| 428 |
|
|---|
| 429 |
|
|---|
| 430 |
// -------------------------------------------------------------------- |
|---|
| 431 |
void search() |
|---|
| 432 |
// -------------------------------------------------------------------- |
|---|
| 433 |
{ |
|---|
| 434 |
FileDateTime lCurFileTime; |
|---|
| 435 |
bool lCanUse; |
|---|
| 436 |
int lTextPos = 0; |
|---|
| 437 |
string lFileText; |
|---|
| 438 |
|
|---|
| 439 |
|
|---|
| 440 |
if(mHasBeenSearched) |
|---|
| 441 |
{ |
|---|
| 442 |
return; |
|---|
| 443 |
} |
|---|
| 444 |
|
|---|
| 445 |
if (util.file2.FileExists(mFileName) == false) |
|---|
| 446 |
{ |
|---|
| 447 |
throw new SourceException("File '" ~ mFileName ~ "' does not exist."); |
|---|
| 448 |
//return; |
|---|
| 449 |
} |
|---|
| 450 |
|
|---|
| 451 |
version(BuildVerbose) |
|---|
| 452 |
{ |
|---|
| 453 |
if(opts.Verbose == True) |
|---|
| 454 |
writefln("%s: Scanning %s", opts.MyName, ReducePathName(mFileName)); |
|---|
| 455 |
} |
|---|
| 456 |
|
|---|
| 457 |
if (mHasBeenSearched == false) |
|---|
| 458 |
{ |
|---|
| 459 |
smScanOrder.length = smScanOrder.length + 1; |
|---|
| 460 |
smScanOrder[$-1] = mFileName; |
|---|
| 461 |
} |
|---|
| 462 |
|
|---|
| 463 |
if (std.path.getExt(mFileName) != "ddoc") |
|---|
| 464 |
{ |
|---|
| 465 |
// Grab the original text, which must exist. |
|---|
| 466 |
lFileText = GetText(mFileName, GetOpt.Exists); |
|---|
| 467 |
|
|---|
| 468 |
// Check if any macro processing is required. |
|---|
| 469 |
if ((mMacroInput == True) && (std.path.getExt(mFileName) != "d")) |
|---|
| 470 |
{ |
|---|
| 471 |
string lNewFile; |
|---|
| 472 |
bool lChanged; |
|---|
| 473 |
lNewFile = util.pathex.ReplaceExtension(mFileName, "d"); |
|---|
| 474 |
if (util.macroex.RunMacro(lFileText, "build", lNewFile, lChanged)) |
|---|
| 475 |
{ |
|---|
| 476 |
std.file.write(lNewFile, lFileText); |
|---|
| 477 |
mHasBeenSearched = true; |
|---|
| 478 |
mIgnore = true; |
|---|
| 479 |
version(BuildVerbose) |
|---|
| 480 |
{ |
|---|
| 481 |
if(opts.Verbose == True) |
|---|
| 482 |
writefln("%s: Macro output %s", opts.MyName, lNewFile); |
|---|
| 483 |
} |
|---|
| 484 |
new Source(lNewFile); |
|---|
| 485 |
delete lFileText; |
|---|
| 486 |
return; |
|---|
| 487 |
} |
|---|
| 488 |
} |
|---|
| 489 |
|
|---|
| 490 |
// Extract all the module references. |
|---|
| 491 |
ProcessTokens(lFileText, lTextPos); |
|---|
| 492 |
delete lFileText; // Remove it from GC control. |
|---|
| 493 |
|
|---|
| 494 |
lCurFileTime = new FileDateTime(); |
|---|
| 495 |
// Examine each extracted module file. |
|---|
| 496 |
if ( (mReferencedImports.length > 0) && (AutoImports() == True)) |
|---|
| 497 |
{ |
|---|
| 498 |
|
|---|
| 499 |
AddRoot( std.path.getDirName(ExpandPathName(mFileName, False)) ); |
|---|
| 500 |
} |
|---|
| 501 |
|
|---|
| 502 |
foreach(string lNextFile; mReferencedImports) |
|---|
| 503 |
{ |
|---|
| 504 |
if (mCollectUses) |
|---|
| 505 |
{ |
|---|
| 506 |
smUses[mFileName ~ " <> " ~ lNextFile] = true; |
|---|
| 507 |
smUsedBy[lNextFile ~ " <> " ~ mFileName] = true; |
|---|
| 508 |
} |
|---|
| 509 |
if(lNextFile in smSourceIndex) |
|---|
| 510 |
{ |
|---|
| 511 |
// Known file so just grab its mod time |
|---|
| 512 |
lCurFileTime = smSourceIndex[lNextFile].DependantsTime; |
|---|
| 513 |
} |
|---|
| 514 |
else |
|---|
| 515 |
{ |
|---|
| 516 |
// Ignore specified modules as we assume they are in the lib. |
|---|
| 517 |
lCanUse = true; |
|---|
| 518 |
if (!(ModulesToIgnore is null)) |
|---|
| 519 |
{ |
|---|
| 520 |
foreach(string lNextModule; ModulesToIgnore() ){ |
|---|
| 521 |
int lFindPos; |
|---|
| 522 |
string lType = "package"; |
|---|
| 523 |
string lFullFileName; |
|---|
| 524 |
version(Windows) |
|---|
| 525 |
{ |
|---|
| 526 |
string lLowerMod; |
|---|
| 527 |
lFullFileName = std.string.tolower(ExpandPathName(lNextFile, True)); |
|---|
| 528 |
lLowerMod = std.string.tolower(lNextModule); |
|---|
| 529 |
version(Windows) |
|---|
| 530 |
{ |
|---|
| 531 |
// Just in case a Windows user used unix style separators. |
|---|
| 532 |
lLowerMod = std.string.replace(lLowerMod, `/`, `\`); |
|---|
| 533 |
} |
|---|
| 534 |
|
|---|
| 535 |
// Check for package name |
|---|
| 536 |
lFindPos = std.string.find(lFullFileName, |
|---|
| 537 |
std.path.sep ~ lLowerMod ~ std.path.sep); |
|---|
| 538 |
if (lFindPos == -1) { |
|---|
| 539 |
// It might be a package at the current module level. |
|---|
| 540 |
lFindPos = std.string.find(lFullFileName, |
|---|
| 541 |
lLowerMod ~ std.path.sep); |
|---|
| 542 |
if (lFindPos != 0) |
|---|
| 543 |
lFindPos = -1; |
|---|
| 544 |
} |
|---|
| 545 |
// Check for module in subdirectory |
|---|
| 546 |
if (lFindPos == -1) { |
|---|
| 547 |
lType = "module"; |
|---|
| 548 |
lFindPos = std.string.find(lFullFileName, |
|---|
| 549 |
std.path.sep ~ lLowerMod ~ ".d"); |
|---|
| 550 |
} |
|---|
| 551 |
// Check for module in current directory |
|---|
| 552 |
if (lFindPos == -1) |
|---|
| 553 |
{ |
|---|
| 554 |
lType = "module"; |
|---|
| 555 |
if (lFullFileName == source.ExpandPathName(lLowerMod ~ ".d", True)) |
|---|
| 556 |
lFindPos = 0; |
|---|
| 557 |
} |
|---|
| 558 |
} |
|---|
| 559 |
version(Posix) |
|---|
| 560 |
{ |
|---|
| 561 |
// Check for package name |
|---|
| 562 |
lFullFileName = source.ExpandPathName(lNextFile, True); |
|---|
| 563 |
lFindPos = std.string.find(lFullFileName, |
|---|
| 564 |
std.path.sep ~ lNextModule ~ std.path.sep); |
|---|
| 565 |
if (lFindPos == -1) { |
|---|
| 566 |
// It might be a package at the current module level. |
|---|
| 567 |
lFindPos = std.string.find(lFullFileName, |
|---|
| 568 |
lNextModule ~ std.path.sep); |
|---|
| 569 |
if (lFindPos != 0) |
|---|
| 570 |
lFindPos = -1; |
|---|
| 571 |
} |
|---|
| 572 |
// Check for module in subdirectory |
|---|
| 573 |
if (lFindPos == -1) { |
|---|
| 574 |
lType = "module"; |
|---|
| 575 |
lFindPos = std.string.find(lFullFileName, |
|---|
| 576 |
std.path.sep ~ lNextModule ~ ".d"); |
|---|
| 577 |
} |
|---|
| 578 |
// Check for module in current directory |
|---|
| 579 |
if (lFindPos == -1) { |
|---|
| 580 |
lType = "module"; |
|---|
| 581 |
if (lFullFileName == ExpandPathName(lNextModule ~ ".d", False)) |
|---|
| 582 |
lFindPos = 0; |
|---|
| 583 |
} |
|---|
| 584 |
} |
|---|
| 585 |
|
|---|
| 586 |
if( lFindPos >= 0) { |
|---|
| 587 |
version(BuildVerbose) |
|---|
| 588 |
{ |
|---|
| 589 |
if (opts.Verbose == True) |
|---|
| 590 |
writefln("%s: Ignoring %s (%s: %s)", opts.MyName, lNextFile, lType, lNextModule); |
|---|
| 591 |
} |
|---|
| 592 |
|
|---|
| 593 |
lCanUse = false; |
|---|
| 594 |
break; |
|---|
| 595 |
} |
|---|
| 596 |
} |
|---|
| 597 |
} |
|---|
| 598 |
if (lCanUse && (opts.Explicit == False)) |
|---|
| 599 |
{ |
|---|
| 600 |
// Not known yet, so add it and grab its mod time |
|---|
| 601 |
string lUseName = GetFullPathnameScan(lNextFile, ~0); |
|---|
| 602 |
lCurFileTime = (new Source(lUseName)).DependantsTime; |
|---|
| 603 |
} |
|---|
| 604 |
|
|---|
| 605 |
} |
|---|
| 606 |
} |
|---|
| 607 |
|
|---|
| 608 |
// Ensure we get the most recent mod time. |
|---|
| 609 |
UpdateDependantTime (lCurFileTime); |
|---|
| 610 |
|
|---|
| 611 |
} |
|---|
| 612 |
mHasBeenSearched = true; |
|---|
|
|---|