Changeset 41

Show
Ignore:
Timestamp:
04/06/06 02:45:23 (6 years ago)
Author:
Derek Parnell
Message:

Upload on version 2.10 (Build #1556)

See Docs/CHANGE_LOG.html for details
modified trunk/Source/build.cfg
modified trunk/Source/build.d
modified trunk/Source/build.def
modified trunk/Source/build.ksp
modified trunk/Source/build.rsp
modified trunk/Source/build_bn.d
modified trunk/Source/source.d
modified trunk/Source/source_bn.d
modified trunk/Source/util/fdt_bn.d
modified trunk/Source/util/fileex.d
modified trunk/Source/util/fileex_bn.d
modified trunk/Source/util/linetoken_bn.d
modified trunk/Source/util/pathex.d
modified trunk/Source/util/pathex_bn.d
modified trunk/Source/util/str.d
modified trunk/Source/util/str_bn.d
added downloads/build-2.10.doc.zip
added downloads/build-2.10.src.zip
added downloads/build_win_2.10.exe
added trunk/Docs/autobuild.html
added trunk/Docs/change_log.html
added trunk/Docs/command_line.html
added trunk/Docs/configuration_file.html
added trunk/Docs/dlls.html
added trunk/Docs/introduction.html
added trunk/Docs/pragmas.html
added trunk/Docs/response_file.html
added trunk/Docs/rules.html
added trunk/Docs/style.css
added trunk/Docs/switches.html
added trunk/Docs/todo.html
added trunk/Docs/User_Manual.html
added trunk/Source/docsrc
added trunk/Source/docsrc/autobuild.d
added trunk/Source/docsrc/change_log.d
added trunk/Source/docsrc/command_line.d
added trunk/Source/docsrc/configuration_file.d
added trunk/Source/docsrc/dlls.d
added trunk/Source/docsrc/introduction.d
added trunk/Source/docsrc/pragmas.d
added trunk/Source/docsrc/response_file.d
added trunk/Source/docsrc/rules.d
added trunk/Source/docsrc/style.css
added trunk/Source/docsrc/switches.d
added trunk/Source/docsrc/todo.d
added trunk/Source/docsrc/um.d
added trunk/Source/docsrc/User_Manual.d
added trunk/Source/docsrc/user_manual.ddoc
added trunk/Source/example_build.cfg
added trunk/Source/util/booltype.d

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/Source/build.cfg

    r38 r41  
    11CMDLINE=-info           # Show the version of build 
    2 CMDLINE=-silent         # hide linker output 
     2CMDLINE=-Iy:\d_proj\build\trunk\source 
     3CMDLINE=-Iy:\dlibs 
     4CMDLINE=-Ic:\dmd\import 
    35 
    46LIBCMD=%@D%\..\..\dm\bin\lib.exe 
    57 
     8 
     9BMD=@S\djp.bmd 
     10 
    611[dbg] 
    7 CMDLINE=-unittest --release --inline -g -w -full 
     12CMDLINE=--release --inline -unittest -g -w -full 
    813CMDLINE=-T{Target}_{Group} 
    914 
  • trunk/Source/build.d

    r38 r41  
    1 /************************************************************************** 
    2  
    3         @file build.d 
    4  
    5         Copyright (c) 2005 Derek Parnell 
    6  
     1/* ******************************************************* 
     2   Build is a tool to assist building applications and libraries written 
     3   using the D programming language. 
     4 
     5 Copyright: (c) 2005 Derek Parnell 
     6 Authors: Derek Parnell, Melbourne 
     7 Initial Creation: January 2005 
     8 Version: 2.10 
     9 Date: August 2005 
     10 License: 
    711        This software is provided 'as-is', without any express or implied 
    812        warranty. In no event will the authors be held liable for damages 
    913        of any kind arising from the use of this software. 
    10  
    1114        Permission is hereby granted to anyone to use this software for any 
    1215        purpose, including commercial applications, and to alter it and/or 
    13         redistribute it freely, subject to the following restrictions: 
    14  
     16        redistribute it freely, subject to the following restrictions:$(NL) 
    1517        1. The origin of this software must not be misrepresented; you must 
    1618           not claim that you wrote the original software. If you use this 
    1719           software in a product, an acknowledgment within documentation of 
    18            said product would be appreciated but is not required. 
    19  
     20           said product would be appreciated but is not required.$(NL) 
    2021        2. Altered source versions must be plainly marked as such, and must 
    21            not be misrepresented as being the original software. 
    22  
     22           not be misrepresented as being the original software.$(NL) 
    2323        3. This notice may not be removed or altered from any distribution 
    24            of the source. 
    25  
     24           of the source.$(NL) 
    2625        4. Derivative works are permitted, but they must carry this notice 
    2726           in full and credit the original source. 
    28  
    29  
    30                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    31  
    32  
    33         @version        Initial version, January 2005 
    34         @author         Derek Parnell, Melbourne, Australia. 
    35  
    36  
    37 **************************************************************************/ 
    38 /* 
    39    A utility for building executables from source code written 
    40    with the D programming language. 
    41  
    42    This examines a set of D source code files to determine what 
    43    to build and what needs to be included in the build. It then 
    44    checks to see which components are current and creates a list 
    45    of files that need to be compiled and/or included in the target 
    46    file. 
    47  
    48    This is based on the work called 'dmake v0.21' by Helmut Leitner 
    49 */ 
    50  
    51 /* --------- CHANGE LOG -------------------- 
    52 __ /makedoc title Documentation for Build v2.09 
    53  
    54 __ /topic Change Log 
    55 __ /info 
    56 __ A list of changes and fixes that have been made. 
    57 __ 
    58 __ /b"-- v2.09 -- 10/Aug/2005" 
    59 __ <ul> 
    60 __ /li ** /b FIX: /i"thanks to barrett9h (rodolfo)": Now correctly handles the return value 
    61 __ from Unix system() call. 
    62 __ /li ** /b FIX: /i"thanks to oniony": Now handles non_ASCII characters in PATH 
    63 __ environment symbol. 
    64 __ /li ** /b CHG: The "-silent" switch now also hides the linker stdout display. 
    65 __ /li ** /b CHG: Now supports and requires DMD v0.126 and GDC v0.13 or later. 
    66 __ /li ** /b ENH: New pragma(export_version) allows specified version identifiers to 
    67 __ be passed to all modules being compiled. 
    68 __ /li ** /b ENH: New command line switch "-run" to run the program 
    69 __ after a successful link. 
    70 __ </ul> 
    71 __ 
    72 __ /b"-- v2.08 -- 29/May/2005" 
    73 __ <ul> 
    74 __ /li ** /b FIX: /i"thanks to teqdruid": In Unix environments, 
    75 __ any pragma(link, ~<name~>) statements were not sending the correct 
    76 __ syntax to the compiler's command line. The "~<name~>" is now prefixed 
    77 __ with "-L-l" for Unix systems. 
    78 __ /li ** /b FIX: /i"thanks to Carlos": In Unix environments, any "-version" 
    79 __ switch on the Utility's command line was not being converted to the correct Unix 
    80 __ format of "-fversion...". So now, if the Build tool gets 
    81 __ either "-version..." or "-fversion=..." on its command line, it will 
    82 __ recognise it as a 'Version' request for the compiler /b and output 
    83 __ it on the command line in the correct format for the environment it 
    84 __ is running in, namely "-fversion..." for GNU (gdc) and "-version..." 
    85 __ for Windows. /n 
    86 __ /b"Note:" The same applies to the "-debug..." and "-fdebug..." switches. 
    87 __ /li ** /b FIX: The pragma(nolink) was being ignored under some circumstances. 
    88 __ Now it splits the compilation phase 
    89 __ from the linking phase and excludes the 'nolink' files from the linker's 
    90 __ command line. 
    91 __ /li ** /b FIX: /i"thanks to kris": 'debug' statements were not being taken into account when 
    92 __ examining code for import statements. 
    93 __ /li ** /b FIX: 'debug' and 'version' levels are now being taken into account. 
    94 __ /li ** /b FIX: 'debug' and 'version' values being set inside a source file 
    95 __ were being made global rather than module scoped. 
    96 __ /li ** /b FIX: /i"thanks to carlos": The utility was not processing the 
    97 __ -I switch correctly when using GDC compiler. 
    98 __ /li ** /b ENH: The utility can now accept the -I switch in two forms: 
    99 __ /b"-I~<path~>" and /b"-I ~<path~>" on its command line, regardless of which 
    100 __ compiler is being used. When invoking the compiler, it uses the correct 
    101 __ format on the command line of the compiler being used, namely "-I~<path~>" to 
    102 __ DMD compiler and "-I ~<path~>" to GDC. 
    103 __ /li ** /b ENH: The path of any source file that imports a module 
    104 __ will be added to the list of root paths to search for module source 
    105 __ files. This means that you can now have module source files referenced 
    106 __ relative to the source file that imports them. This is the new default 
    107 __ behaviour but it can be turned off by using the new -noautoimport switch 
    108 __ or for individual files by placing them inside parenthesis. 
    109 __ /li ** /b ENH: New switch /i"-noautoimport" is used to turn off the 
    110 __ automatic adding of search roots based on the path of the source files 
    111 __ being compiled. 
    112 __ /li ** /b ENH: New switch /i"-LIBPATH=" is used to add search paths for 
    113 __ library files. 
    114 __ /li ** /b WARN: The utility only does a single scan of each source file 
    115 __ and thus if an file sets a 'debug' or 'version' value after a function 
    116 __ which uses that value, it will be ignored. You are requested to ensure that 
    117 __ all your 'debug' and 'version' setting is done prior to the first module 
    118 __ member. 
    119 __ </ul> 
    120 __ 
    121 __ /b"-- v2.07 -- 06/May/2005" 
    122 __ <ul> 
    123 __ /li ** /b ENH: New switch /i"-nodef" to prevent the utility from 
    124 __ automatically creating a Module Definition File (.def) 
    125 __ /li ** /b ENH: You can now specify default, and special, settings for 
    126 __ the utility's command line. These are placed in a text configuration file called 
    127 __ /b"build.cfg". The utility first looks in the same directory as the 
    128 __ utility's executable for the configuration file. After processing any 
    129 __ configuration file found there, it then looks in the same directory as 
    130 __ the compiler for a configuration file (build.cfg) and processes it if 
    131 __ found. 
    132 __ /li ** /b ENH: To support special command line settings that may be 
    133 __ specified in the utility's configuration file(s), you can indicate 
    134 __ one or more setting groups on the command line. These take the format of 
    135 __ +groupname. The configuration file(s) are scanned for special group settings 
    136 __ after the default ones have been processed. 
    137 __ /li ** /b ENH: To remove an earlier specified command line switch, you 
    138 __ can prepend it with a hyphen. This new feature may be needed when command 
    139 __ line switches can come from multiple sources (the original command line, 
    140 __ utility response files, and utility configuration files), and you need 
    141 __ to remove a switch that may have been provided by some other source. /n 
    142 __ For example to negate an earlier "-unittest" switch you code add "--unittest" 
    143 __ to the command line. 
    144 __ /li ** /b ENH: New switch /i"-od" is used to nominate a directory for 
    145 __ temporary files. For the DigitalMars compiler, this also is used as the location 
    146 __ to create object files. 
    147 __ </ul> 
    148 __ 
    149 __  /b"-- v2.06 -- 04/May/2005" 
    150 __ <ul> 
    151 __ /li ** /b FIX: /i"thanks to phoenix": When emitting commandline parameters for 
    152 __ the compiler or librarian, it was possible to have some ending with /b'\"' which caused 
    153 __ the shell to /i escape the quote character and thus provide incorrect parameters to 
    154 __ the compiler. 
    155 __ </ul> 
    156 __  /b"-- v2.05 -- 02/May/2005" 
    157 __ <ul> 
    158 __ /li ** /b FIX: When supplying some forms of relative paths, the 
    159 __ utility would crash or give the wrong canonical form of the path. This 
    160 __ effected formats like \..\anything and  C:..\anything 
    161 __ /li ** /b FIX: The utility now assumes the current directory if it can not 
    162 __ locate the compiler using the paths on the system PATH symbol. 
    163 __ /li ** /b FIX: The utility now assumes the compiler's location if no path 
    164 __ for the configuration file has been specified. 
    165 __ /li ** /b FIX: The utility now supports better parsing of the lines in the 
    166 __ configuration file. It handles odd variations of embedded quotes. 
    167 __ /li ** /b ENH: The utility now supports Windows 95/98/ME for file times. 
    168 __ </ul> 
    169 __ 
    170 __  /b"-- v2.04 -- 29/Apr/2005" 
    171 __ <ul> 
    172 __ /li ** /b FIX: /i"thanks to Nils Hensel": The utility was not correctly 
    173 __ parsing the DFLAGS line in the configuration file when it contained 
    174 __ embedded quote characters. 
    175 __ /li ** /b FIX: /i"thanks to Anders F Bjoerklund": The utility was not treating 
    176 __ directory names that contained dots correctly. 
    177 __ /li ** /b FIX: /i"thanks to Carlos": Unix-style files that end with a nested comment 
    178 __ delimiter are now handled correctly. 
    179 __ /li ** /b ENH: /i"thanks to qbert(Charlie)": The location of the librarian tool can now 
    180 __ be specified. It can be explictly named on a LIBCMD= line inside the 
    181 __ DMD configuration file, or failing that, implictly assumed to be in the 
    182 __ same directory as the DMD linker. 
    183 __ /li ** /b ENH: A new commandline switch -LIBOPT which allows you to pass 
    184 __ commandline options to the librarian. 
    185 __ </ul> 
    186 __ 
    187 __  /b"-- v2.03 -- 20/Apr/2005" 
    188 __ <ul> 
    189 __ /li ** /b FIX: /i"thanks to Carlos": The linux build had a spelling mistake 
    190 __ in source.d (line 286). The indentifier "lNextMod" should have been coded 
    191 __  as "lNextModule". 
    192 __ </ul> 
    193 __ 
    194 __  /b"-- v2.02 -- 19/Apr/2005" 
    195 __ <ul> 
    196 __ /li ** /b FIX: /i"thanks to Carlos": The utility was not handling the situation 
    197 __ where a simple statement, rather than a block statement, followed a version 
    198 __ directive. 
    199 __ /li ** /b FIX: /i"thanks to aldacron": The utility now respects the compiler's 
    200 __ 'Output file' switch. Which is '-of[filename]' for DMD and '-o [filename]' 
    201 __ for GNU. The utility treats it as an alias for its -T switch. 
    202 __ /li ** /b FIX: /i"thanks to aldacron": The utility now respects the DMD compiler's 
    203 __ 'Object Path' switch. If you have '-odsomepath' on the command line, the 
    204 __ utility adds this to the search path when checking for up-to-date files, 
    205 __ and will clean up files in that directory if requested to (-clean). It will 
    206 __ also create the directory if it doesn't exist. 
    207 __ </ul> 
    208 __ 
    209 __  /b"-- v2.01 -- 18/Apr/2005" 
    210 __ <ul> 
    211 __ /li ** /b FIX: /i"thanks to Justin (jcc7)": If an excluded module (-X) was 
    212 __ in a package at the current directory level, it was not being excluded. 
    213 __ </ul> 
    214 __ 
    215 __  /b"-- v2.00 -- 08/Apr/2005" 
    216 __ <ul> 
    217 __ /li ** /b FIX: Now supports the raw-string delimiter ` in Build's own 
    218 __ pragma commands. 
    219 __ /li ** /b FIX: Now handles backslash escapes in Build's own 
    220 __ pragma commands. 
    221 __ /li ** /b ENH: New -silent switch avoids all unnecessary messages. 
    222 __ /li ** /b ENH: New -help switch displays full usage text. Aliases: -h, -? 
    223 __ </ul> 
    224 __ 
    225 __  /b"-- v1.19 -- 04/Apr/2005" 
    226 __ <ul> 
    227 __ /li ** /b FIX: /i"thanks to Ben Hinkle". When creating a library in Linux, 
    228 __ the utility was looking for /i".obj" files instead of /i".o" files. 
    229 __ /li ** /b FIX" When creating a library, if a source file had more than one 
    230 __ /i".d" in its name, the utility would look for the wrong object file for it. 
    231 __ </ul> 
    232 __ 
    233 __  /b"-- v1.18 -- 03/Apr/2005" 
    234 __ <ul> 
    235 __ /li ** /b FIX: If mixed case was used, it was possible to have duplicate 
    236 __ element types in a OptLink module definition file. Effected the use of 
    237 __ pragma(build_def). 
    238 __ /li ** /b ENH: Some performance improvements. 
    239 __ </ul> 
    240 __ 
    241 __  /b"-- v1.17 -- 30/Mar/2005" 
    242 __ <ul> 
    243 __ /li ** /b FIX: In Windows systems, the utility now does case-insensitive 
    244 __  path name compares. 
    245 __ /li ** /b FIX: A bug in the String Search function crashed the utility 
    246 __ when the -T switch was used with target names less than 9 characters long. 
    247 __ /li ** /b ENH: The new switch /b"-obj" is available. This is just a shorthand 
    248 __ for having both /i"-nolib" and /i"-nolink" on the command line. 
    249 __ </ul> 
    250 __ 
    251 __  /b"-- v1.16 -- 28/Mar/2005" 
    252 __ <ul> 
    253 __ /li ** /b FIX: The utility now handles quotes around pragma(link) references. 
    254 __ /li ** /b FIX: The utility now handles multiple references to the same module 
    255 __ even though they are using different 'path' specifications. 
    256 __ /li ** /b ENH: The utility now has support for making Windows DLL files. 
    257 __ </ul> 
    258 __ 
    259 __  /b"-- v1.15 -- 24/Mar/2005" 
    260 __ <ul> 
    261 __ /li ** /b FIX: The utility now checks for more recent libraries and 
    262 __ object files as added by pragma(link), pragma(build), and command line. It 
    263 __ didn't used to rebuild the executable if only a new version of a library 
    264 __ was present. 
    265 __ /li ** /b FIX: The order of the librarian parameters was incorrect. 
    266 __ /li ** /b FIX: The utility was not using the correct path name if importing 
    267 __ modules from some Import paths. 
    268 __ /li ** /b ENH: Verbose mode now shows the ignored and noticed packages. 
    269 __ </ul> 
    270 __ 
    271 __  /b"-- v1.14 -- 23/Mar/2005" 
    272 __ <ul> 
    273 __ /li ** /b FIX: /i"Thanks to teqDruid." For GNU platforms, the utility 
    274 __  now passes any library name found in pragma(link,...) to the linker. 
    275 __ /li ** /b FIX: Nows correctly handles unix and Microsoft line-ends. 
    276 __ /li ** /b FIX: /i"Thanks to Ben Hinkle." Using relative paths '..' and '.' 
    277 __ now work correctly on the -I switch. 
    278 __ /li ** /b FIX: /i"Thanks to Ben Hinkle." The correct librarian program 'ar' 
    279 __ is now called on unix systems. 
    280 __ /li ** /b ENH: The new switch -names displays the names of the files 
    281 __ used in building the target. This is not a noisy as verbose mode. 
    282 __ /li ** /b ENH: New pragma /b include used to identify a file that 
    283 __ must be included in the compilation process but is not one that 
    284 __ is imported by any file in the group. Only needed if command line 
    285 __  file does not otherwise import the required file. Can be used to 
    286 __  include the file containing the 'main' function from a file that 
    287 __ does not import that file. Rarely needed. 
    288 __ /li ** /b ENH: New pragma /b build used to build 'foreign' file types 
    289 __ that D doesn't know about. 
    290 __ /li ** /b ENH: New pragma /b target used to nominate the default target 
    291 __ file name. 
    292 __ /li ** /b ENH: You can now use a symbolic target name on the -T switch. 
    293 __ </ul> 
    294 __ 
    295 __  /b"-- v1.13 -- 13/Mar/2005" 
    296 __ <ul> 
    297 __ /li ** /b FIX: Explictly included paths entered on the -I switch are 
    298 __ now added to the dmd command line. 
    299 __ /li ** /b FIX: Explictly excluded modules (via -X) were only checking package 
    300 __ names. They also check for module names now. 
    301 __ /li ** /b FIX: Imported files are now looked for relative to the current directory 
    302 __ before the import paths are checked. 
    303 __ /li ** /b FIX: The utility now checks the DFLAG environment symbol in 
    304 __ non-DigitalMars D compilers. 
    305 __ /li ** /b CHG: The switch -nounittest is now deprecated and ignored if used. 
    306 __ The default setting is no longer to compile with unittests turned on. 
    307 __ </ul> 
    308 __  /b"-- v1.12 -- 6/Mar/2005" 
    309 __ <ul> 
    310 __ /li ** /b FIX: The response file (-Ry) is now only the default when using 
    311 __ DigitalMars tools on Windows. All other environments do not use the response 
    312 __ file by default. 
    313 __ </ul> 
    314 __  /b"-- v1.11 -- 4/Mar/2005" 
    315 __ <ul> 
    316 __ /li ** /b FIX: No long outputs empty compiler tool switches. 
    317 __ </ul> 
    318 __ 
    319 __  /b"-- v1.10 -- 4/Mar/2005" 
    320 __ <ul> 
    321 __ /li ** /b FIX: /i"Thanks to Carlos." Better support for GDC command line switches. 
    322 __ /li ** /b FIX: /i"Thanks to Carlos." Cause 'Unix' version to trigger Posix code. 
    323 __ /li ** /b FIX: /i"Thanks to Carlos." The vUseResponseFile variable was only being 
    324 __ declared in the Windows version. 
    325 __ /li ** /b FIX: No passes space-embedded switches and paths to the compiler 
    326 __ tools correctly. 
    327 __ /li ** /b ENH: If an environment symbol called DFLAGS has been defined, it is 
    328 __ analyzed. This is done before any configuration file processing. 
    329 __ /li ** /b ENH: New command line switch -test. This shows the command lines 
    330 __ instead of running them. No compiling or linking is done. 
    331 __ </ul> 
    332 __ 
    333 __  /b"-- v1.9 -- 3/Mar/2005" 
    334 __ <ul> 
    335 __ /li ** /b FIX: /i"Thanks to Carlos." For unix, it now uses ':' instead of ';' for path 
    336 __ separators when parsing the configuration file lines. 
    337 __ /li ** /b FIX: /i"Thanks to Carlos." The default location for the configuration 
    338 __ file was being ignored. 
    339 __ /li ** /b ENH: A new command line switch /b"-R" used to control the use 
    340 __  of a response file for the compiler tools. 
    341 __ </ul> 
    342 __ 
    343 __  /b"-- v1.8 -- 1/Mar/2005" 
    344 __ <ul> 
    345 __ /li ** /b FIX: /i"Thanks to Anders F Bjoerklund:" Removed nonASCII chars from source code. 
    346 __ /li ** /b FIX: /i"Thanks to Anders F Bjoerklund:" Changed version(GDC) to version(GNU) 
    347 __ /li ** /b FIX: Changed compiler name for GNU versions from 'dmd' to 'gdc' 
    348 __ /li ** /b FIX: /i"Thanks to Carlos." The application was incorrectly parsing the DFLAGS sc.ini line. 
    349 __ /li ** /b ENH: /i"Thanks to Anders F Bjoerklund:" Provided a Makefile for the initial 
    350 __ compile of the application. 
    351 __ </ul> 
    352 __ 
    353 __  /b"-- v1.7 -- 28/Feb/2005" 
    354 __ <ul> 
    355 __ /li ** /b FIX: /i"Thanks to clayasaurus." Linux edition was not compiling 
    356 __ due to a missing 'version(Windows)' block around the use of vWinVer 
    357 __ </ul> 
    358 __ 
    359 __  /b"-- v1.6 -- 28/Feb/2005" 
    360 __ <ul> 
    361 __ /li ** /b FIX: /i"Thanks to Kris." The utility was not including the DCPATH value 
    362 __ when invoking the compiler. 
    363 __ /li ** /b ENH: When building a Windows app, the .DEF file now includes the 
    364 __ version of windows that /i this application is being run on. 
    365 __ /li ** /b ENH: The command line switch /b"-gui" can now have an optional 
    366 __  version information to specify which Windows version to build for. 
    367 __ The default Windows Version used is the one for the version running 
    368 __  this utility. 
    369 __ /li ** /b ENH: New command line switch -info to display the utility's version #. 
    370 __ </ul> 
    371 __  /b"-- v1.5 -- 25/Feb/2005" 
    372 __ <ul> 
    373 __ /li ** /b FIX: /i"Thanks to clayasaurus." Now only displays the CFPATH 
    374 __  and DCPATH messages when /i verbose mode is on. 
    375 __ /li ** /b FIX: /i"Thanks to kris." Hardcoded default for DMD path was 
    376 __ misleading when dmd.exe was not in the Windows PATH. 
    377 __ /li ** /b FIX: The utility was not correctly parsing empty raw strings ``. 
    378 __ /li ** /b ENH: /i"Thanks to kris." If the -DCPATH switch is used, then 
    379 __ if the existing DCPATH and CFPATH are the same, this switch changes both. 
    380 __ </ul> 
    381 __ 
    382 __  /b"-- v1.4 -- 24/Feb/2005" 
    383 __ <ul> 
    384 __ /li ** /b FIX: /i"Thanks to Abscissa." The -version switch was being interpreted as 
    385 __  a file to compile. 
    386 __ /li ** /b FIX: /i"Thanks to brad." Linux version was using the wrong package name 
    387 __ when formatting a file date for display. 
    388 __ /li ** /b FIX: /i"Thanks to brad." Linux version was not setting the target 
    389 __ name correctly which resulted in the first source file being compiled twice. 
    390 __ /li ** /b FIX: /i"Thanks to brad." Parsing the DFLAG line in the dmd options 
    391 __ file was not dealing with whitespace delimiters. 
    392 __ /li ** /b ENH: When specifing an alternate target file, you can now also 
    393 __  specify a path for the target, and that path is created for you if it 
    394 __ doesn't exist. 
    395 __ </ul> 
    396 __ 
    397 __  /b"-- v1.3 -- 23/Feb/2005" 
    398 __ <ul> 
    399 __ /li ** /b ENH: Put in a workaround for DMD (Windows) not using the sc.ini 
    400 __ file correctly. The utility now explicitly adds any DFLAG options from 
    401 __ the sc.ini file into the .rsp file. 
    402 __ /li ** /b FIX: The utility now correctly handles ';' delimited DFLAG options 
    403 __ in the sc.ini file. 
    404 __ /li ** /b ENH: Now supports the use of 'response' files on the command line 
    405 __ /li ** /b ENH: Now supports the -T command line switch to supply an 
    406 __  alternate tareget name. 
    407 __ 
    408 __ </ul> 
    409 __  /b"-- v1.2 -- 21/Feb/2005" 
    410 __ <ul> 
    411 __ /li ** /b ENH: /i"Thanks to Anders F Bjoerklund:" Added better support for 'darwin' 
    412 __        and 'gdc'. 
    413 __ </ul> 
    414 */ 
     27******************************************************* */ 
    41528 
    41629module build; 
    41730private import build_bn;    // This module's build number 
    41831 
    419 version(unix)  version = Unix; 
    420 version(Unix)  version = Posix; 
     32version(unix)  version = Unix; 
     33version(Unix)  version = Posix; 
    42134version(linux)  version = Posix; 
    42235version(darwin) version = Posix; 
     
    42639    version(Windows) { 
    42740        // OptLink Definition File 
    428         pragma (build_def, "VERSION 2.9"); 
     41        pragma (build_def, "VERSION 2.10"); 
    42942    } 
    43043} 
     
    43346private{ 
    43447    // --------- imports ---------------- 
    435     import source;         // Source File class 
    436  
    437     import util.str;       // non-standard string routines. 
    438     import util.fdt;       // File Date-Time class 
    439     import util.pathex;    // Extended Path routines. 
    440     import util.fileex;    // Extended File routines. 
    441     import util.macro;     // Macro processing routines. 
     48    import source;          // Source File class 
     49 
     50    import util.str;        // non-standard string routines. 
     51    import util.fdt;        // File Date-Time class 
     52    import util.pathex;     // Extended Path routines. 
     53    import util.fileex;     // Extended File routines. 
     54    import util.macro;      // Macro processing routines. 
     55    import util.booltype;   // definition of True and False 
    44256 
    44357    import std.c.stdio; 
     
    488102        char[] kSrcExtention=`d`; 
    489103        char[] kMacroExtention=`mac`; 
     104        char[] kDdocExtention=`ddoc`; 
    490105 
    491106    } 
     
    494109    version(DigitalMars) { 
    495110        version(Windows) { 
    496             char[] vCompiler=`dmd.exe`; 
    497             char[] vCompilerSwitch= ` -c`; 
    498             char[] vLinker=`dmd.exe`; 
     111            char[] vCompilerExe=`dmd.exe`; 
     112            char[] vCompileOnlySwitch = ` -c`; 
     113            char[] vLinkerExe=`link.exe`; 
    499114            char[] vConfigFile=`sc.ini`; 
    500115            char[] vCompilerPath=``; 
     116            char[] vLinkerPath=``; 
     117            char[] vLinkerDefSwitches=`/noi/map`; 
    501118            char[] vConfigPath=``; 
    502119            char[] vLibPaths = ``; 
     
    507124 
    508125        version(Posix) { 
    509             char[] vCompiler=`dmd`; 
    510             char[] vCompilerSwitch= ` -c`; 
    511             char[] vLinker=`dmd`; 
     126            char[] vCompilerExe=`dmd`; 
     127            char[] vCompileOnlySwitch= ` -c`; 
     128            char[] vLinkerExe=`ld`; 
    512129            char[] vConfigFile=`dmd.conf`; 
    513130            char[] vCompilerPath=``; 
     131            char[] vLinkerPath=``; 
     132            char[] vLinkerDefSwitches=`/noi/map`; 
    514133            char[] vConfigPath=`/etc/`; 
    515134            char[] vLibPaths = ``; 
     
    529148    version(GNU) { 
    530149        version(Windows) { 
    531             char[] vCompiler=`gdc.exe`; 
    532             char[] vCompilerSwitch= ` -c`; 
    533             char[] vLinker=`gdc.exe`; 
     150            char[] vCompilerExe=`gdc.exe`; 
     151            char[] vCompileOnlySwitch= ` -c`; 
     152            char[] vLinkerExe=`gdc.exe`; 
    534153            char[] vConfigFile=null; 
    535154            char[] vCompilerPath=``; 
     155            char[] vLinkerPath=``; 
     156            char[] vLinkerDefSwitches=``; 
    536157            char[] vConfigPath=null; 
    537158            char[] vLibPaths = ``; 
     
    542163 
    543164        version(Posix) { 
    544             char[] vCompiler=`gdc`; 
    545             char[] vCompilerSwitch= ` -c`; 
    546             char[] vLinker=`gdc`; 
     165            char[] vCompilerExe=`gdc`; 
     166            char[] vCompileOnlySwitch= ` -c`; 
     167            char[] vLinkerExe=`ld`; 
    547168            char[] vConfigFile=null; 
    548169            char[] vCompilerPath=`/opt/gdc/bin`; 
     170            char[] vLinkerPath=``; 
     171            char[] vLinkerDefSwitches=``; 
    549172            char[] vConfigPath=null; 
    550173            char[] vLibPaths = ``; 
     
    563186    char[]       vBuildImportPathSwitch = "-I"; 
    564187    char[]       vTemporaryPathSwitch = "-od"; 
    565     char[]       vRunSwitch = "-run"; 
     188    char[]       vRunSwitch = "-exec"; 
    566189    char[]       vLibrarianPath = ""; 
    567190    char[]*      vDelayedValue = null; 
    568191    char[]       vTemporaryPath = ""; 
    569     bool         vTestRun = false; 
    570     bool         vNoLink = false; 
    571     bool         vForceCompile = false; 
    572     bool         vSilent = false; 
    573     bool         vCleanup = false; 
    574     bool         vVerbose = false; 
    575     bool         vNames = false; 
    576     bool         vAllObjects = false; 
    577     bool         vNoDef = false; 
    578     bool         vAutoImports = true; 
    579     bool         vMacroInput = true; 
    580     bool         vExecuteProgram = false; 
     192 
     193    Bool         vTestRun; 
     194    Bool         vScanImports; 
     195    Bool         vNoLink; 
     196    Bool         vForceCompile; 
     197    Bool         vSilent; 
     198    Bool         vCleanup; 
     199    Bool         vVerbose; 
     200    Bool         vMacroInput; 
     201    Bool         vNames; 
     202    Bool         vAllObjects; 
     203    Bool         vNoDef; 
     204    Bool         vAutoImports; 
     205    Bool         vExecuteProgram; 
     206    Bool         vUseResponseFile; 
     207    Bool         vConsoleApp; 
    581208    char[]       vRunParms; 
    582209    char[]       vTargetExe; 
     
    590217    char[]       vAppPath; 
    591218    char[]       vAppName; 
    592     char[]       vAppVersion = "2.9"; 
     219    char[]       vAppVersion = "2.10"; 
    593220    char[]       vTargetName;           // Output name from first file name. 
    594221    char[]       vPragmaTargetName;     // Output name from pragma. 
     
    599226    char[][]     vBuildArgs;            // Arguments passed to build 
    600227    char[][]     vCompilerArgs;         // Arguments passed to compiler 
    601     bool         vUseResponseFile; 
    602     bool         vConsoleApp = true; 
     228    char[][]     vSourceScanList;       // The list of places to find source files. 
    603229    char[]       vRDFName = "default.rdf"; 
    604230    bool[char[]] vNestedDelim; 
     
    612238    Substitute[] vSubstitutions; 
    613239 
    614  version(Windows) { 
    615     char[]       vWinVer = ""; 
    616     ubyte        vWinVerNum; 
     240 
     241    const static char[] kPathId = "PATH";   // Used to locate the environment symbol 
     242 
     243    version(Windows) 
     244    { 
     245        char[]       vWinVer = ""; 
     246        ubyte        vWinVerNum; 
    617247    } 
    618248 
     
    624254//------------------------------------------------------- 
    625255{ 
    626     source.ActivateVersion("build"); 
     256    source.ActivateVersion("build"); //todo 
    627257 
    628258    vDefaultCompArgs ~= vKeepPathSwitch;     // Keep object files in same folder as source. 
    629259    vModulesToIgnore ~= "phobos";  // Assume phobos will be ignored. 
     260    vSourceScanList ~= "." ~ std.path.sep; 
     261    vNoLink = False; 
     262    vTestRun = False; 
     263    vScanImports = False; 
     264    vForceCompile = False; 
     265    vSilent = False; 
     266    vCleanup = False; 
     267    vVerbose = False; 
     268    vMacroInput = True; 
     269    vNames = False; 
     270    vAllObjects = False; 
     271    vNoDef = False; 
     272    vAutoImports = True; 
     273    vExecuteProgram = False; 
     274    vUseResponseFile = False; 
     275    vConsoleApp = True; 
    630276 
    631277    version(Posix){ 
     
    640286    version(DigitalMars) { 
    641287        version(Windows) { 
    642             vUseResponseFile = true; 
     288            vUseResponseFile = True; 
    643289        } 
    644290        else 
    645291        { 
    646             vUseResponseFile = false; 
     292            vUseResponseFile = False; 
    647293        } 
    648294     } else 
    649295     { 
    650         vUseResponseFile = false; 
     296        vUseResponseFile = False; 
    651297     } 
    652298 
     
    657303} 
    658304 
     305static ~this() 
     306{ 
     307    // Clean up any resources held by the source files. 
     308    Source.Finalize(); 
     309} 
    659310 
    660311//------------------------------------------------------- 
     
    727378    writefln("               -Rn will cause command line arguments to be used."); 
    728379    writefln("               -R will reverse the current usage."); 
     380    writefln("  -PP<path>  Add a path to the Source Search List"); 
    729381 
    730382  version(DigitalMars) { 
     
    737389    writefln("               ** The default is to use command line arguments"); } 
    738390 
    739     writefln("  -run<param> If the link is successful, this will cause the"); 
     391    writefln("  -exec<param> If the link is successful, this will cause the"); 
    740392    writefln("               executable just created to run. You can give it "); 
    741     writefln("               run time parameters. Anything after the '-run' will"); 
     393    writefln("               run time parameters. Anything after the '-exec' will"); 
    742394    writefln("               placed in the program's command line. You will need"); 
    743395    writefln("               to quote any embedded spaces."); 
     
    779431    int lTrueRC; 
    780432 
    781     if (vTestRun) { 
     433    if (vTestRun == True) { 
    782434        writefln("Command: '%s'",pCommand); 
    783435        return 0; 
     
    787439 
    788440 
    789         if(vVerbose) { 
     441        if(vVerbose == True) { 
    790442            writefln("Running '%s'",pCommand); 
    791443        } 
     
    795447        version(Windows) lTrueRC = lRC; 
    796448 
    797         if(vVerbose) { 
     449        if(vVerbose == True) { 
    798450            if (lTrueRC == 0){ 
    799451                writefln("Successful"); 
     
    822474    FileDateTime lModsTime = new FileDateTime(); 
    823475 
    824     foreach(int i, char[] lFileName; Source.SourceIndex.keys
     476    foreach(int i, char[] lFileName; Source.ScanOrder
    825477    { 
    826478        // Get the next Source object to examine. 
     
    832484        lSource.search(); 
    833485 
    834         if(vVerbose) { 
     486        if(vVerbose == True) { 
    835487            writefln("source file[%d] %s", i, 
    836488                    util.pathex.AbbreviateFileName(lFileName)); 
    837489        } 
    838         else if(vNames) { 
     490        else if(vNames == True) { 
    839491            writefln(" [ %s ]", util.pathex.AbbreviateFileName(lFileName)); 
    840492        } 
     
    842494        if (lSource.DependantsTime > lModsTime) 
    843495        { 
    844             if(vVerbose) { 
     496            if(vVerbose == True) { 
    845497                writefln("Newer time: from %s to %s", 
    846498                    lModsTime.toString(), 
     
    858510        FileDateTime lLinkTime = GetFileTime(lFileName); 
    859511 
    860         if(vVerbose) { 
     512        if(vVerbose == True) { 
    861513            writefln("link file[%d] %s %s", i, 
    862514                    util.pathex.AbbreviateFileName(lFileName), lLinkTime.toString()); 
    863515        } 
    864         else if(vNames) { 
     516        else if(vNames == True) { 
    865517            writefln(" [ %s ]", util.pathex.AbbreviateFileName(lFileName)); 
    866518        } 
     
    868520        if (lLinkTime > lModsTime) 
    869521        { 
    870             if(vVerbose) { 
     522            if(vVerbose == True) { 
    871523                writefln("Newer time: from %s to %s", 
    872524                    lModsTime.toString(), 
     
    890542}; 
    891543 
     544 
    892545//------------------------------------------------------- 
    893546Rule[] LoadRules() 
     
    898551    char[] lRuleDefnFile; 
    899552 
     553    static char[] kRuleKey = "rule="; 
    900554 
    901555    lRuleDefnFile = util.pathex.LocateFile(vRDFName, 
    902                         getDirName(vAppPath) ~ std.path.pathsep ~ GetEnv("PATH")); 
    903     if (vVerbose
     556                        getDirName(vAppPath) ~ std.path.pathsep ~ GetEnv(kPathId)); 
     557    if (vVerbose == True
    904558        writefln("Rule Definitions from %s", lRuleDefnFile); 
    905     lRuleText = GetTextLines( lRuleDefnFile); 
     559    GetTextLines( lRuleDefnFile, lRuleText ); 
    906560    foreach(char[] lLine; lRuleText) 
    907561    { 
    908         lLine = std.string.strip(lLine); 
    909         if (util.str.begins(lLine, "rule=") > 0
     562        lLine = util.str.strip(lLine); 
     563        if (util.str.begins(lLine, kRuleKey ) == True
    910564        { 
    911565            lRules.length = lRules.length + 1; 
     
    914568        else if (lRules.length > 0) 
    915569        { 
    916             if (util.str.begins(lLine, "in=") > 0
     570            if (util.str.begins(lLine, "in=") == True
    917571                lRules[$-1].Input = lLine[3..$]; 
    918             else if (util.str.begins(lLine, "out=") > 0
     572            else if (util.str.begins(lLine, "out=") == True
    919573                lRules[$-1].Output = lLine[4..$]; 
    920             else if (util.str.begins(lLine, "tool=") > 0
     574            else if (util.str.begins(lLine, "tool=") == True
    921575                lRules[$-1].Tool = lLine[5..$]; 
    922576        } 
    923577    } 
    924578 
    925     if (vVerbose
     579    if (vVerbose == True
    926580    { 
    927581        foreach(Rule r; lRules) 
     
    984638        lOutDate = new FileDateTime(lOutFile); 
    985639 
    986         if ((lInDate > lOutDate) || vForceCompile
     640        if ((lInDate > lOutDate) || (vForceCompile == True)
    987641        { 
    988642            char[] lKeyValues; 
     
    1015669//------------------------------------------------------- 
    1016670{ 
    1017     bool        lBuildRequired; 
     671    Bool        lCompiling; 
     672    Bool        lLinking; 
     673    Bool        lBuildRequired; 
    1018674    char[][]    lFilesToLink; 
    1019675    char[][]    lFilesToCompile; 
     
    1023679    FileDateTime lTargetTime; 
    1024680    FileDateTime lMostRecentTime; 
    1025     bool        lCompiling; 
    1026     bool        lLinking; 
    1027     Source[]    lNonLinkingSources; 
     681    auto Source[]    lNonLinkingSources; 
    1028682    char[]      lDResponseFileName; 
    1029683    char[]      lLinkResponseFileName; 
     
    1031685    char[]      lDefName; 
    1032686    char[]      lOutText; 
     687    char[]      lCompilerOpts; 
    1033688    char[]      lSourcesToCompile; 
    1034689    char[]      lCommand; 
    1035  
     690    char[][]    lObjectFiles; 
     691    char[][]    lLibraryFiles; 
     692 
     693 
     694    lCompiling = False; 
     695    lLinking = False; 
     696    lBuildRequired = False; 
    1036697 
    1037698    // Examine each supplied source file. 
    1038699    foreach( char[] lFile; vCmdLineSourceFiles) 
    1039700    { 
    1040         new Source(GetFullPathname(lFile)); 
     701        new Source(GetFullPathname(lFile, vSourceScanList)); 
    1041702    } 
    1042703 
     
    1045706    lLinking =  (vLibraryAction == LibOpt.Build) || 
    1046707                (Source.WasMainFound == false) || 
    1047                 (vNoLink == true) 
    1048                ? false : true; 
     708                (vNoLink == True) 
     709               ? False : True; 
    1049710 
    1050711    lMostRecentTime = GetNewestDateTime(); 
     
    1062723 
    1063724    // I'm either creating a library, an executable or neither. 
     725 
     726    // If a target name was supplied in a pragma, use that as the 
     727    // default target name. 
    1064728    if (vPragmaTargetName.length != 0) 
    1065729        vTargetName = vPragmaTargetName; 
     730 
     731    // If a target name was supplied on the command line, use that 
     732    // instead of the default name. 
    1066733    if (vCommandTargetName.length != 0) 
    1067734    { 
     
    1080747    } 
    1081748 
     749    // Ensure that the path to the target's location will exist. 
    1082750    util.pathex.MakePath(vTargetName); 
    1083751 
     752 
    1084753    if (vLibraryAction == LibOpt.Build) 
     754        // Target is a library. 
    1085755        lTargetName = ReplaceExtention(vTargetName, kLibExtention); 
    1086     else if (vNoLink == false) 
     756 
     757    else if (vNoLink == False) 
     758    { 
    1087759        if (Source.WasMainFound) 
    1088760            if (Source.WasMainDLL) 
     761                // Target is a shared library. 
    1089762                lTargetName = ReplaceExtention(vTargetName, kShrLibExtention); 
    1090             else { 
     763            else 
     764            { 
     765                // Target is an executable 
    1091766                lTargetName = ReplaceExtention(vTargetName, kExeExtention); 
    1092767                vTargetExe = lTargetName; 
    1093768            } 
    1094769        else 
    1095             lTargetName = "not defined"; 
     770        { 
     771            // Possible error. The user wants to link but no 'main' detected 
     772            // so assume they know what they are doing and also assume an 
     773            // executable is required. 
     774            lTargetName = ReplaceExtention(vTargetName, kExeExtention); 
     775            vTargetExe = lTargetName; 
     776        } 
     777    } 
    1096778    else 
     779        // Not linking and not archiving, so no target is required. 
    1097780        lTargetName = ""; 
    1098781 
    1099     lTargetName = util.pathex.CanonicalPath(lTargetName, false); 
    1100     lTargetName = util.pathex.AbbreviateFileName(lTargetName); 
    1101  
    1102     if(vVerbose || vNames) { 
    1103         writefln("\nBuilding target '%s'", lTargetName); 
    1104     } 
    1105  
    1106     if (lTargetName.length > 0 ) 
    1107     { 
    1108         lTargetName =  util.pathex.CanonicalPath(lTargetName, false); 
     782    if (lTargetName.length > 0) 
     783    { 
     784        // Get the full name of the target's location. 
     785        lTargetName = util.pathex.CanonicalPath(lTargetName, false); 
    1109786        lTargetDir = getDirName(lTargetName); 
    1110787 
     788        // Show user if required to. 
     789        if((vVerbose == True) || (vNames == True) ) { 
     790            writefln("\nBuilding target '%s'", lTargetName); 
     791        } 
     792 
     793        // Shorten the target name for future usages. 
     794        lTargetName = util.pathex.AbbreviateFileName(lTargetName); 
     795 
     796 
     797        // If the target doesn't exist or it is older than 
     798        // most recently modified dependant file, we need to 
     799        // rebuild the target. 
    1111800        lTargetTime = util.fdt.GetFileTime (lTargetName); 
    1112         if(vVerbose) { 
     801        if(vVerbose == True) { 
    1113802            writefln("Time %s for %s (target)", lTargetTime.toString(), lTargetName); 
    1114803            writefln("Time %s (most recent)", lMostRecentTime.toString()); 
    1115804        } 
    1116  
    1117805        if(lTargetTime < lMostRecentTime) { 
    1118             // If the target doesn't exist or it is older than 
    1119             // most recently modified dependant file, we need to 
    1120             // rebuild the target. 
    1121             lBuildRequired = true; 
    1122         } 
    1123     } 
    1124  
     806            lBuildRequired = True; 
     807        } 
     808    } 
     809    else if((vVerbose == True) || (vNames == True) ) { 
     810            writefln("\nCompiling only. No target will be built."); 
     811        } 
     812 
     813    // Run any external tools referenced in the source files. 
    1125814    foreach( ExternRef lRef; vExternals) 
    1126815    { 
    1127816        lRunResult = ProcessExternal( lRef ); 
    1128817        if (lRunResult != 0) 
     818            // If an external tool fails, stop immediately. 
    1129819            return lRunResult; 
    1130820    } 
     
    1142832        { 
    1143833            // Only include OBJECT files. 
    1144             if (util.str.ends(lFileName , kObjExtention) >= 0
     834            if (util.str.ends(lFileName , kObjExtention) == True
    1145835                lFilesToLink ~= lFileName; 
    1146836        } 
    1147837    } 
    1148     else foreach (int i, char[] lFileName; Source.SourceIndex.keys
     838    else foreach (int i, char[] lFileName; Source.ScanOrder
    1149839    { 
    1150840        // Check each source to see if we need to recompile it. 
    1151841        Source lCurrentSource; 
    1152         bool lNeedsCompiling; 
     842        Bool lNeedsCompiling; 
    1153843        char[] lShortFileName; 
     844        char[] lFileType; 
    1154845 
    1155846        lNeedsCompiling = vForceCompile; 
     
    1160851 
    1161852        lShortFileName = util.pathex.AbbreviateFileName(lFileName); 
    1162         if (std.path.getExt(lShortFileName) != kSrcExtention) 
     853        lFileType = std.path.getExt(lShortFileName); 
     854        if (lFileType != kSrcExtention && lFileType != kDdocExtention) 
    1163855            continue; 
    1164856 
    1165857        // Only source files are examined from here on. 
    1166         if (lCurrentSource.NoLink) 
     858        if (lCurrentSource.NoLink || lFileType == kDdocExtention) 
     859        { 
    1167860            lNonLinkingSources ~= lCurrentSource; 
     861        } 
    1168862 
    1169863        if(lCurrentSource.FilesTime > lCurrentSource.ObjectsTime) 
    1170864        { 
    1171             if (vVerbose
     865            if (vVerbose == True
    1172866                writefln("%s newer than its object file", lShortFileName); 
    1173             lNeedsCompiling=true; 
     867            lNeedsCompiling = True; 
    1174868 
    1175869        } else if(lCurrentSource.DependantsTime > lCurrentSource.ObjectsTime) { 
    1176             if (vVerbose
     870            if (vVerbose == True
    1177871                writefln("%s has newer dependants than its object file.", 
    1178872                                lShortFileName); 
    1179873 
    1180             lNeedsCompiling=true; 
    1181         } 
    1182  
    1183         if(lNeedsCompiling
    1184         { 
    1185             lBuildRequired = true; 
    1186             lCompiling = true; 
     874            lNeedsCompiling = True; 
     875        } 
     876 
     877        if(lNeedsCompiling == True
     878        { 
     879            lBuildRequired = True; 
     880            lCompiling = True; 
    1187881            lFilesToCompile ~= lShortFileName; 
    1188882 
     
    1191885                lFilesToLink ~= util.pathex.AbbreviateFileName(lCurrentSource.ObjectName); 
    1192886 
    1193             if (! vTestRun
     887            if (vTestRun == False
    1194888            { 
    1195889                if (lCurrentSource.IncrementBuildNumber()) 
    1196890                { 
    1197                     if (vVerbose
     891                    if (vVerbose == True
    1198892                        writefln("New build number %d for %s", 
    1199893                               lCurrentSource.BuildNumber, 
     
    1210904    } 
    1211905 
    1212     if( lBuildRequired == false ) 
    1213     { 
    1214         if (vSilent == false) 
     906    if( lBuildRequired == False ) 
     907    { 
     908        if (vSilent == False) 
    1215909            writefln ("Files are up to date, no build required."); 
    1216910        return 0; 
    1217911    } 
    1218  
    1219     lOutText ~= GatherCompilerArgs(lLinking); 
    1220912 
    1221913    foreach(char[] lFileName; lFilesToCompile) 
     
    1245937            AddBuildDef("DATA PRELOAD SINGLE WRITE"); 
    1246938        } 
    1247         else if (vConsoleApp) { 
     939        else if (vConsoleApp == True) { 
    1248940            AddBuildDef(`EXETYPE DOS`); 
    1249941        } 
    1250942 
    1251         if ((vNoDef == false) && (vBuildDef.length > 0)) 
     943        if ((vNoDef == False) && (vBuildDef.length > 0)) 
    1252944        { 
    1253945            lDefName = ReplaceExtention(lTargetName, "def"); 
     
    1259951            util.fileex.CreateTextFile(lDefName, vBuildDef); 
    1260952 
    1261             lOutText ~= util.str.enquote(lDefName) ~ "\n"; 
    1262         } 
    1263     } 
    1264  
     953        } 
     954    } 
     955 
     956    version(Posix) 
     957    { 
     958            vDefaultLibs ~= "c"; 
     959    } 
    1265960    // Add any library or external obj files required. 
    1266     if (lLinking) { 
     961    if (lLinking == True) 
     962    { 
     963        lLibraryFiles.length = 0; 
    1267964 
    1268965        foreach (char[] lFileName; vLinkFiles.keys) 
    1269966        { 
    1270967            char[] lCmdItem; 
    1271             version(Posix) 
    1272                 char[] lPrefix; 
    1273  
    1274             if (lFileName.length > 0) { 
     968 
     969            if (lFileName.length > 0) 
     970            { 
    1275971                lCmdItem = lFileName; 
    1276                 version(Posix) 
    1277                 { 
    1278                     int lCut; 
    1279                     if ( (lCut = util.str.ends(lCmdItem, "." ~ kLibExtention)) >= 0) 
    1280                     { 
    1281                         lCmdItem = lCmdItem[0 .. lCut]; // Cut off extentsion. 
    1282                         lPrefix = "-L-l"; // Needed for linker to find the library. 
    1283                     } 
    1284                 } 
    1285                 lCmdItem = util.str.enquote(lCmdItem) ~ "\n"; 
    1286  
    1287                 version(Posix) 
    1288                     lOutText ~= lPrefix ~ lCmdItem; 
    1289                 version(Windows) 
    1290                     lOutText ~= lCmdItem; 
    1291  
    1292             } 
    1293         } 
    1294     } 
    1295  
    1296     if (lLinking || lCompiling) 
    1297     { 
    1298  
    1299  
    1300         // COMPILE phase 
     972                if ( util.str.ends(lCmdItem, "." ~ kLibExtention) == True) 
     973                { 
     974                    // Cut off extention. 
     975                    lCmdItem.length = lCmdItem.length - kLibExtention.length - 1; 
     976//                        lPrefix = "-L-l"; // Needed for linker to find the library. 
     977                    lLibraryFiles ~= lCmdItem; 
     978                } 
     979                else 
     980                { 
     981                    lFilesToLink ~= lCmdItem; 
     982                } 
     983            } 
     984        } 
     985    } 
     986 
     987    if ((lLinking == True) || (lCompiling == True)) 
     988    { 
     989        // COMPILE phase ... 
    1301990        if (lSourcesToCompile.length > 0) 
    1302991        { 
     992            // Ok, I have some compiling to do! 
    1303993            char[] lCommandLine; 
    1304994 
    1305             lCommandLine = lOutText ~ lSourcesToCompile; 
    1306  
    1307             if (vUseResponseFile) { 
     995            lCommandLine = GatherCompilerArgs(lLinking) ~ lSourcesToCompile; 
     996 
     997            if (vUseResponseFile == True) 
     998            { 
    1308999                lDResponseFileName = ReplaceExtention(lTargetName, "rsp"); 
    13091000                if (vTemporaryPath.length != 0) 
     
    13131004                lDResponseFileName = util.pathex.AbbreviateFileName(lDResponseFileName); 
    13141005                util.fileex.CreateTextFile(lDResponseFileName,lCommandLine); 
    1315                 lCommand = vCompilerPath ~ vCompiler ~ vCompilerSwitch ~ " @" ~ lDResponseFileName; 
     1006                lCommand = vCompilerPath ~ vCompilerExe ~ vCompileOnlySwitch ~ " @" ~ lDResponseFileName; 
    13161007            } 
    13171008            else 
    13181009            {   // using commandline; may run into limits 
    13191010                lCommandLine=std.string.replace(lCommandLine, "\n", " "); 
    1320                 lCommand = vCompilerPath ~ vCompiler  ~ vCompilerSwitch ~ " " ~ lCommandLine; 
    1321             } 
    1322  
    1323             if (vVerbose) { 
     1011                lCommand = vCompilerPath ~ vCompilerExe  ~ vCompileOnlySwitch ~ " " ~ lCommandLine; 
     1012            } 
     1013 
     1014            if (vVerbose == True) { 
    13241015                writefln("Compiling with ..........\n%s\n", lCommandLine); 
    13251016            } 
     
    13281019            lRunResult = RunCommand(lCommand); 
    13291020            if (lRunResult != 0) 
    1330                 vExecuteProgram = false; 
    1331         } 
    1332  
    1333         if ( (lRunResult == 0) && (lFilesToLink.length > 0) && (lLinking == true)) 
     1021                vExecuteProgram = False; 
     1022        } 
     1023 
     1024        // LINK phase ... 
     1025        if ( (lRunResult == 0) && (lFilesToLink.length > 0) && (lLinking == True)) 
    13341026        { 
    13351027            char[] lCommandLine; 
    1336  
    1337             // Ensure the linker gets the right executable name to create. 
    1338             char[] lSmallName; 
    1339             lSmallName = util.pathex.AbbreviateFileName(lTargetName); 
    1340             if (find(lSmallName, " ") != -1) { 
    1341                 version(Posix) { 
    1342                     lOutText ~= std.string.format(`%s"%s"`,vOutFileSwitch,lSmallName); 
    1343                 } 
    1344                 else { 
    1345                     lOutText ~= std.string.format(`"%s%s"`,vOutFileSwitch,lSmallName); 
    1346                 } 
    1347             } 
    1348             else 
    1349                 lOutText ~= std.string.format(`%s%s`,vOutFileSwitch,lSmallName); 
    1350  
    1351             // Terminate with a newline char. 
    1352             lOutText ~= "\n"; 
    1353  
    1354             // Include the default libraries. 
    1355             foreach( char[] lLib; vDefaultLibs) 
    1356             { 
    1357                 lLib = util.str.enquote(lLib) ~"\n"; 
    1358                 version(Windows) 
    1359                     lOutText ~= lLib; 
    1360                 version(Posix) 
    1361                     lOutText ~= "-L-l" ~ lLib; 
    1362             } 
    1363  
    1364             if (vLibPaths.length > 1) 
    1365             { 
    1366                 vLibPaths = vLibPaths[1..$]; 
    1367  
    1368                 // Include the paths to the libraries. 
    1369                 version(Windows) { 
    1370  
    1371                     if (vVerbose) 
    1372                         writefln("Setting LIB=%s", vLibPaths); 
    1373                     putenv("LIB=" ~ vLibPaths[1..$]); 
    1374                 } 
    1375                 version(Posix) 
    1376                 { 
    1377                     if (vVerbose) 
    1378                         writefln("Setting LIB=%s", vLibPaths); 
    1379                     char[][] lLibPaths; 
    1380                     lLibPaths = std.string.split(vLibPaths, vConfigSep); 
    1381                     foreach(char[] lLib; lLibPaths) 
    1382                     { 
    1383                         if (lLib.length > 0) 
    1384                             lOutText ~= "-L-L" ~ lLib ~ "\n"; 
    1385                     } 
    1386                 } 
    1387             } 
    1388  
    1389  
    1390             lCommandLine = lOutText; 
    1391             foreach(char[] lFile; lFilesToLink) 
    1392                 lCommandLine ~= lFile ~ "\n"; 
    1393  
    1394             if (vUseResponseFile) { 
     1028            char[] lLinkerSwitches; 
     1029            Bool IsMapping = False; 
     1030 
     1031            // Build the command line for the linker. 
     1032            lCommandLine = ""; 
     1033            version(Windows) 
     1034            { 
     1035                // Transfer linker switches from Compiler switches. 
     1036                foreach (char[] lCompileArg; vCompilerArgs) 
     1037                { 
     1038                    if (util.str.begins(lCompileArg, "-L") == True) 
     1039                    { 
     1040                        lLinkerSwitches ~= lCompileArg[2..$]; 
     1041                    } 
     1042                } 
     1043                foreach( char[] lSwitch; std.string.split(vLinkerDefSwitches ~ lLinkerSwitches, "/")) 
     1044                { 
     1045                    if (lSwitch == "nomap") 
     1046                    { 
     1047                        IsMapping = False; 
     1048                    } 
     1049                    else if (lSwitch == "map") 
     1050                    { 
     1051                        IsMapping = True; 
     1052                    } 
     1053                } 
     1054 
     1055                // (1) Gather the object file names 
     1056                foreach(char[] lFile; lFilesToLink) 
     1057                { 
     1058                    lCommandLine ~= lFile ~ "+"; 
     1059                } 
     1060                if (lCommandLine.length > 0) 
     1061                    lCommandLine[$-1] = '\n'; 
     1062 
     1063                // (2) Set the output file name 
     1064                lCommandLine ~= util.str.enquote(util.pathex.AbbreviateFileName(lTargetName)) ~ "\n"; 
     1065 
     1066                // (3) Set the map name 
     1067                if (IsMapping == True) 
     1068                    lCommandLine ~= ReplaceExtention(lTargetName, "map"); 
     1069 
     1070                lCommandLine ~= "\n"; 
     1071 
     1072                // (4) Gather the libraries names. 
     1073                // Include the default libraries first. 
     1074                lLibraryFiles = vDefaultLibs ~ lLibraryFiles; 
     1075                if (lLibraryFiles.length > 0) 
     1076                { 
     1077                    foreach( char[] lLib; lLibraryFiles) 
     1078                    { 
     1079                        lCommandLine ~= util.str.enquote(lLib) ~"+"; 
     1080                    } 
     1081                    lCommandLine[$-1] = '\n'; 
     1082                } 
     1083                else 
     1084                    lCommandLine ~= "\n"; 
     1085 
     1086                // Include the explictly named libraries. 
     1087                if (vLibPaths.length > 1) 
     1088                { 
     1089                    if (vLibPaths[0..1] == vConfigSep) 
     1090                        vLibPaths = vLibPaths[1..$]; 
     1091 
     1092                    // Include the paths to the libraries. 
     1093                    if (vVerbose == True) 
     1094                        writefln("Setting LIB=%s", vLibPaths); 
     1095                    putenv("LIB=" ~ vLibPaths[1..$]); 
     1096                } 
     1097 
     1098                // (5) Set the 'def' file name 
     1099                if (lDefName.length > 0) 
     1100                    lCommandLine ~= util.str.enquote(lDefName) ~ "\n"; 
     1101                else 
     1102                    lCommandLine ~= "\n"; 
     1103 
     1104                // (6) Gather the resource file names 
     1105 
     1106                // (7) Gather then switches 
     1107                lCommandLine ~= vLinkerDefSwitches; 
     1108                lCommandLine ~= lLinkerSwitches; 
     1109                lCommandLine ~= "\n"; 
     1110            } 
     1111 
     1112            version(Posix) 
     1113            { 
     1114                // Transfer linker switches from Compiler switches. 
     1115                foreach (char[] lCompileArg; vCompilerArgs) 
     1116                { 
     1117                    if (util.str.begins(lCompileArg, "-L") == True) 
     1118                    { 
     1119                        lLinkerSwitches ~= lCompileArg[2..$]; 
     1120                    } 
     1121                } 
     1122                foreach( char[] lSwitch; std.string.split(vLinkerDefSwitches ~ lLinkerSwitches, "/")) 
     1123                { 
     1124                    if (lSwitch == "nomap") 
     1125                    { 
     1126                        IsMapping = False; 
     1127                    } 
     1128                    else if (lSwitch == "map") 
     1129                    { 
     1130                        IsMapping = True; 
     1131                    } 
     1132                } 
     1133 
     1134                // (1) Gather the object file names 
     1135                foreach(char[] lFile; lFilesToLink) 
     1136                { 
     1137                    lCommandLine ~= lFile ~ "\n"; 
     1138                } 
     1139 
     1140                // (2) Set the output file name 
     1141                lCommandLine ~= "-o " ~ util.str.enquote(util.pathex.AbbreviateFileName(lTargetName)) ~ "\n"; 
     1142 
     1143                // (3) Set the map name 
     1144                if (IsMapping == True) 
     1145                    lCommandLine ~= "-M\n"; 
     1146 
     1147                // (4) Gather the libraries names. 
     1148                // Include the default libraries first. 
     1149                foreach( char[] lLib; vDefaultLibs ~ lLibraryFiles) 
     1150                { 
     1151                    lCommandLine ~= "-l" ~ util.str.enquote(lLib) ~ "\n"; 
     1152                } 
     1153 
     1154                if (vLibPaths.length > 1) 
     1155                { 
     1156                    if (vLibPaths[0..1] == vConfigSep) 
     1157                        vLibPaths = vLibPaths[1..$]; 
     1158 
     1159                    // Include the paths to the libraries. 
     1160                    if (vVerbose == True) 
     1161                        writefln("Setting LIB=%s", vLibPaths); 
     1162                    char[][] lLibPaths; 
     1163                    lLibPaths = std.string.split(vLibPaths, vConfigSep); 
     1164                    foreach(char[] lLib; lLibPaths) 
     1165                    { 
     1166                        if (lLib.length > 0) 
     1167                            lCommandLine ~= "-L" ~ util.str.enquote(lLib) ~ "\n"; 
     1168                    } 
     1169                } 
     1170 
     1171                // (4) Gather then switches 
     1172                lCommandLine ~= vLinkerDefSwitches; 
     1173                lCommandLine ~= lLinkerSwitches; 
     1174                lCommandLine ~= "\n"; 
     1175            } 
     1176 
     1177            if (vUseResponseFile == True) 
     1178            { 
    13951179                lLinkResponseFileName = ReplaceExtention(lTargetName, "ksp"); 
    13961180                if (vTemporaryPath.length != 0) 
     
    14001184                lLinkResponseFileName = util.pathex.AbbreviateFileName(lLinkResponseFileName); 
    14011185                util.fileex.CreateTextFile(lLinkResponseFileName,lCommandLine); 
    1402                 lCommand = vCompilerPath ~ vLinker ~ " @" ~ lLinkResponseFileName; 
     1186                lCommand = vLinkerPath ~ vLinkerExe ~ " @" ~ lLinkResponseFileName; 
    14031187            } 
    14041188            else 
    14051189            {   // using commandline; may run into limits 
    14061190                lCommandLine=std.string.replace(lCommandLine, "\n", " "); 
    1407                 lCommand = vCompilerPath ~ vLinker ~ " " ~ lCommandLine; 
    1408             } 
    1409  
    1410             if (vVerbose) { 
     1191                lCommand = vLinkerPath ~ vLinkerExe ~ " " ~ lCommandLine; 
     1192            } 
     1193 
     1194            if (vVerbose == True) { 
    14111195                writefln("Linking with ..........\n%s\n", lCommandLine); 
    14121196            } 
    14131197 
    14141198            // Run Linker 
    1415             if (vSilent
     1199            if (vSilent == True
    14161200            { 
    14171201                version(Posix) lCommand ~= " >/dev/null"; 
     
    14211205            lRunResult = RunCommand(lCommand); 
    14221206            if (lRunResult != 0) 
    1423                 vExecuteProgram = false; 
     1207                vExecuteProgram = False; 
    14241208        } 
    14251209 
     
    14271211    else 
    14281212    { 
    1429         if (vSilent == false) 
     1213        if (vSilent == False) 
    14301214            writefln("No build required."); 
    14311215        lRunResult = 0; 
     
    14391223        ulong[] lImpManf; 
    14401224 
    1441         vExecuteProgram = false; 
    1442  
    1443         lImpLibPath = util.pathex.LocateFile("implib.exe", GetEnv("PATH")); 
     1225        vExecuteProgram = False; 
     1226 
     1227        lImpLibPath = util.pathex.LocateFile("implib.exe", GetEnv(kPathId)); 
    14441228        if (util.fileex.FileExists(lImpLibPath)) 
    14451229        { 
     
    14551239        } 
    14561240    } 
    1457     else if ( (vLibraryAction == LibOpt.Build) && (lRunResult == 0) ) 
    1458     { 
    1459         vExecuteProgram = false; 
    1460  
    1461         lOutText.length = 0; 
    1462         lOutText ~= vLibrarianOpts ~ std.path.linesep; 
     1241    else if ( (vLibraryAction == LibOpt.Build) && (lRunResult == 0)) 
     1242    { 
     1243        int lFileCount; 
     1244 
     1245        vExecuteProgram = False; 
     1246 
     1247        lOutText = vLibrarianOpts ~ std.path.linesep; 
    14631248        lOutText ~= lTargetName ~  std.path.linesep;  // Create a new library 
    14641249 
    1465         foreach( char[] lFileName; lFilesToLink) { 
     1250        foreach( char[] lFileName; lFilesToLink) 
     1251        { 
    14661252            char[] lFileDir; 
    14671253 
    14681254            lFileDir = getDirName(lFileName); 
    1469             if (vAllObjects || lFileDir == "" || lFileDir == lTargetDir) { 
     1255            if ((vAllObjects == True) || lFileDir == "" || lFileDir == lTargetDir) 
     1256            { 
    14701257                if (lFileName.length > 1 + kSrcExtention.length) 
    14711258                { 
     
    14751262                    } 
    14761263                } 
    1477  
     1264                lFileCount++; 
    14781265                lOutText ~= lFileName ~ std.path.linesep; 
    14791266            } 
    14801267        } 
    14811268 
    1482         if (vUseResponseFile) { 
    1483             lLResponseFileName = ReplaceExtention(lTargetName, "lsp"); 
    1484             if (vTemporaryPath.length != 0) 
    1485             { 
    1486                 lLResponseFileName = vTemporaryPath ~ std.path.getBaseName(lLResponseFileName); 
    1487             } 
    1488             util.fileex.CreateTextFile(lLResponseFileName,lOutText); 
    1489             lCommand = vLibrarianPath ~ vLibrarian ~ " @" ~ lLResponseFileName; 
    1490         } 
    1491         else 
    1492         {   // using commandline, may run into limits 
    1493             lCommand  = vLibrarianPath ~ vLibrarian ~ " " ~ std.string.replace(lOutText,std.path.linesep," "); 
    1494         } 
    1495  
    1496         if (vVerbose) { 
    1497             writefln("Librarian with ..........\n%s\n", lOutText); 
    1498         } 
    1499  
    1500         lRunResult = RunCommand(lCommand); 
     1269        if (lFileCount > 0) 
     1270        { 
     1271            if (vUseResponseFile == True) { 
     1272                lLResponseFileName = ReplaceExtention(lTargetName, "lsp"); 
     1273                if (vTemporaryPath.length != 0) 
     1274                { 
     1275                    lLResponseFileName = vTemporaryPath ~ std.path.getBaseName(lLResponseFileName); 
     1276                } 
     1277                util.fileex.CreateTextFile(lLResponseFileName,lOutText); 
     1278                lCommand = vLibrarianPath ~ vLibrarian ~ " @" ~ lLResponseFileName; 
     1279            } 
     1280            else 
     1281            {   // using commandline, may run into limits 
     1282                lCommand  = vLibrarianPath ~ vLibrarian ~ " " ~ std.string.replace(lOutText,std.path.linesep," "); 
     1283            } 
     1284 
     1285            if (vVerbose == True) { 
     1286                writefln("Librarian with ..........\n%s\n", lOutText); 
     1287            } 
     1288 
     1289            lRunResult = RunCommand(lCommand); 
     1290        } 
    15011291    } 
    15021292 
    15031293    // Optional clean up. 
    1504     if (vCleanup) { 
     1294    if (vCleanup == True) 
     1295    { 
    15051296        char[][] lHitList; 
    15061297 
    1507         if (vVerbose) { 
     1298        if (vVerbose == True) { 
    15081299            writefln("Cleaning up ..."); 
    15091300        } 
    1510         foreach(char[] lFileName; Source.SourceIndex.keys
     1301        foreach(char[] lFileName; Source.ScanOrder
    15111302        { 
    15121303            Source lSource; 
     
    15381329                if (util.fileex.FileExists( lFilename ) ) 
    15391330                { 
    1540                     if (vVerbose) { 
     1331                    if (vVerbose == True) { 
    15411332                        writefln("  removing %s", lFilename); 
    15421333                    } 
     
    15531344 
    15541345// ------------------------------------------- 
    1555 char [] GatherCompilerArgs(bool pLinking) 
     1346char [] GatherCompilerArgs(Bool pLinking) 
    15561347// ------------------------------------------- 
    15571348{ 
     
    15971388    } 
    15981389 
    1599     if (pLinking == false) 
     1390    if (pLinking == False) 
    16001391    { // No linking allowed. 
    16011392        if (vNoLinkSwitch.length > 0) 
     
    16321423        vExternals[$-1].FilePath = pPath; 
    16331424        vExternals[$-1].ToolOpts = pOpts; 
    1634         if (vVerbose) { 
     1425        if (vVerbose == True) { 
    16351426            writef("Added external file to be built: %s", pPath); 
    16361427            foreach( char[] lOpt; pOpts) 
     
    16611452        vPragmaTargetName = pPath; 
    16621453    else if (vPragmaTargetName != pPath) { 
    1663         if (vVerbose) { 
     1454        if (vVerbose == True) { 
    16641455            writefln("Multiple pragma(target,...) detected. '%s' will be used and '%s' rejected.", 
    16651456                    vPragmaTargetName, pPath ); 
     
    16771468    static uint[ char[] ] lElementIdx; 
    16781469 
    1679     if (vNoDef == true) 
     1470    if (vNoDef == True) 
    16801471        return; 
    16811472 
     
    17421533    version(Windows) lSearchName = std.string.tolower(lFullName); 
    17431534    version(Posix)   lSearchName = lFullName; 
    1744     if( !(lSearchName in lRootHash) ) { 
     1535    if( !(lSearchName in lRootHash) ) 
     1536    { 
    17451537        vImportRoots ~= lFullName; 
    17461538        lRootHash[lSearchName] = true; 
     
    17521544} 
    17531545 
    1754 bool AutoImports() 
     1546Bool AutoImports() 
    17551547{ 
    17561548    return vAutoImports; 
     
    17961588                else 
    17971589                { 
    1798                     lSymName = GetEnv(lSymName); 
     1590                    lSymName = (GetEnv(std.utf.toUTF8(lSymName))); 
    17991591                } 
    18001592                lLine ~= lSymName; 
     
    18861678                        vDefaultCompArgs ~= vImportPathSwitch ~ lRoot; 
    18871679                        */ 
    1888                     if(vVerbose) { 
     1680                    if(vVerbose == True) { 
    18891681                        if (lRootName.length > 0){ 
    18901682                            writefln(" added root from config file %s", lRootName); 
     
    18971689                version(DigitalMars) 
    18981690                { 
    1899                 if (util.str.IsLike(lSwitch,  (vOutFileSwitch ~ "*"))
     1691                if (util.str.IsLike(lSwitch,  (vOutFileSwitch ~ "*")) == True
    19001692                { 
    19011693                    // Target name (eg. -oftestapp) 
     
    19171709                } 
    19181710 
    1919                 if (util.str.IsLike(lSwitch,  std.utf.toUTF32(vTemporaryPathSwitch ~ "*"))
     1711                if (util.str.IsLike(lSwitch,  std.utf.toUTF32(vTemporaryPathSwitch ~ "*")) == True
    19201712                { 
    19211713                    char[] lbRoot; 
     
    19291721                        lbRoot = AddRoot(vTemporaryPath); 
    19301722                        if (lbRoot.length > 0){ 
    1931                             if(vVerbose) { 
     1723                            if(vVerbose == True) { 
    19321724                                    writefln("Added root from config file Object Write Path = %s",lbRoot); 
    19331725                            } 
     
    19561748    if (lSymValue.length > 0 ) 
    19571749    { 
    1958         if (vVerbose
     1750        if (vVerbose == True
    19591751            writefln("Analyzing environment symbol DFLAGS=%s", lSymValue); 
    19601752        Process_DFLAGS( lSymValue ); 
     
    19701762    int      lPos; 
    19711763 
    1972     if (vConfigFile is null
     1764    if (vConfigFile.length == 0
    19731765    { 
    19741766        // There is no configuration file to process 
     
    19771769 
    19781770    lPath = vConfigPath ~ vConfigFile ; 
    1979     lTextLines = util.fileex.GetTextLines(lPath, util.fileex.GetOpt.Exists); 
    1980  
    1981     if (vVerbose) { 
     1771    util.fileex.GetTextLines(lPath, lTextLines, util.fileex.GetOpt.Exists); 
     1772 
     1773    if (vVerbose == True) { 
    19821774        writefln("Reading from config: %s", lPath); 
    19831775    } 
     
    19861778    { 
    19871779        // Strip off trailing whitespace. 
    1988         while(lLine.length > 0 && lLine[lLine.length-1] <= ' ') { 
    1989             lLine.length = lLine.length-1; 
    1990         } 
     1780        lLine = util.str.stripr(lLine); 
     1781 
    19911782        // Replace any environment symbols with their value. 
    1992         if (vVerbose) { 
     1783        if (vVerbose == True) { 
    19931784            writefln(" Line %d: %s", i+1, lLine); 
    19941785        } 
     
    20321823                        lPath = lPath[1..length-1]; 
    20331824                    } 
    2034                     vLibPaths ~= vConfigSep; 
    2035                     vLibPaths ~= ("\"" ~ util.pathex.CanonicalPath(lPath) ~ "\""); 
    2036                 } 
    2037             } 
    2038             if(vVerbose) 
     1825                    vLibPaths ~= vConfigSep ~ `"` ~ util.pathex.CanonicalPath(lPath) ~ `"`; 
     1826                } 
     1827            } 
     1828            if(vVerbose == True) 
    20391829            { 
    20401830                writefln(" use %s",vLibPaths); 
     
    20521842            } 
    20531843 
    2054             if (vLibrarianPath.length == 0) 
    2055             { 
    2056                 vLibrarianPath = std.path.getDirName(lLine[8..$]) ~ std.path.sep; 
    2057                 vLibrarianPath = util.pathex.CanonicalPath(vLibrarianPath); 
    2058                 if(vVerbose) { 
    2059                     writefln(" librarian path %s",vLibrarianPath); 
    2060                 } 
     1844            vLinkerPath = std.path.getDirName(lLine[8..$]) ~ std.path.sep; 
     1845            vLinkerPath = util.pathex.CanonicalPath(vLinkerPath); 
     1846            vLinkerExe = std.path.getBaseName(lLine[7..$]); 
     1847            if(vVerbose == True) { 
     1848                writefln(" linker path %s",vLinkerPath); 
     1849                writefln(" linker is %s",vLinkerExe); 
    20611850            } 
    20621851            continue; 
     
    20741863 
    20751864            vLibrarian = std.path.getBaseName(lLine[7..$]); 
    2076             if(vVerbose) { 
     1865            if(vVerbose == True) { 
    20771866                writefln(" librarian path %s",vLibrarianPath); 
    20781867                writefln(" librarian is %s",vLibrarian); 
    20791868            } 
    20801869        } 
     1870 
     1871 
     1872        if (vLinkerPath.length == 0) 
     1873            vLinkerPath = vCompilerPath; 
     1874        if (vLibrarianPath.length == 0) 
     1875            vLibrarianPath = vLinkerPath; 
    20811876    } 
    20821877} 
     
    21291924 
    21301925// ------------------------------------------------ 
    2131 char[] GetFullPathname(char[] pFileName) 
     1926char[] GetFullPathnameScan(char[] pFileName, int pScanList) 
     1927// ------------------------------------------- 
     1928
     1929    if (pScanList == 0) 
     1930        return GetFullPathname(pFileName); 
     1931    else 
     1932        return GetFullPathname(pFileName, vSourceScanList); 
     1933
     1934 
     1935// ------------------------------------------------ 
     1936char[] GetFullPathname(char[] pFileName, char[][] pScanList = null) 
    21321937// ------------------------------------------- 
    21331938{ 
    21341939    char[] lPossiblePath; 
    21351940    char[] lLocalPath; 
     1941 
     1942    if (util.pathex.IsRelativePath(pFileName) == True && pScanList.length > 0) 
     1943    { 
     1944        // Do explicit scanning of supplied paths. 
     1945        foreach(char[] lNextRoot; pScanList) { 
     1946            lPossiblePath = ( lNextRoot ~ pFileName ); 
     1947            if(util.fileex.FileExists(lPossiblePath)) { 
     1948                return util.pathex.AbbreviateFileName(lPossiblePath); 
     1949            } 
     1950        } 
     1951 
     1952        // If not found in scan list, drop through to standard scan. 
     1953    } 
    21361954 
    21371955    // Look for file in current folder first. 
     
    22132031    source.AddBuildDef      = &AddBuildDef; 
    22142032    source.GetFullPathname  = &GetFullPathname; 
     2033    source.GetFullPathnameScan = &GetFullPathnameScan; 
    22152034    source.GetObjWritePath  = &GetTemporaryPath; 
    22162035    source.GetMacros        = &GetMacros; 
     
    22182037 
    22192038    // Scan the PATH env symbol to locate the D compiler. 
    2220     lCompPath = FindFileInPathList("PATH", vCompiler); 
     2039    lCompPath = FindFileInPathList(kPathId, vCompilerExe); 
    22212040    if (lCompPath.length > 0){ 
    22222041        if (lCompPath[length-1] != std.path.sep[0]) 
     
    22572076    GatherArgs( pArgs ); 
    22582077    source.mVerboseMode = vVerbose; 
    2259     if (vVerbose){ 
     2078    if (vVerbose == True){ 
    22602079        writefln("*** build v%s (build %d)***", vAppVersion, build_bn.auto_build_number); 
    22612080    } 
     
    22662085 
    22672086    source.mMacroInput = vMacroInput; 
    2268     if (vMacroInput
     2087    if (vMacroInput == True
    22692088        ProcessMacroDefs(vVerbose); 
    22702089 
     
    22732092    } 
    22742093 
    2275     if (vVerbose || vNames
     2094    if ((vVerbose == True) || (vNames == True)
    22762095        writefln("Current Dir '%s'", util.pathex.GetInitCurDir()); 
    22772096 
    22782097    if (lSetPath) 
    22792098    { 
    2280         if (vVerbose
     2099        if (vVerbose == True
    22812100        { 
    22822101            writefln("%s not found in PATH symbol, so assuming current directory", 
    2283                         vCompiler); 
     2102                        vCompilerExe); 
    22842103        } 
    22852104    } 
     
    22922111    { 
    22932112        vConfigPath = vCompilerPath; 
    2294         if (vVerbose
     2113        if (vVerbose == True
    22952114        { 
    22962115            writefln("No configuration file path, so assuming current directory"); 
    22972116        } 
    22982117    } 
    2299     if (vConfigPath[length-1] != std.path.sep[0]
     2118    if (util.str.ends(vConfigPath, std.path.sep) is False
    23002119        vConfigPath ~= std.path.sep; 
    23012120 
     
    23092128    } 
    23102129 
    2311     if (util.fileex.FileExists(vCompilerPath ~ vCompiler) == false) 
     2130    if (util.fileex.FileExists(vCompilerPath ~ vCompilerExe) == false) 
    23122131    { 
    23132132        throw new Exception(std.string.format("The compiler '%s' was not found.", 
    2314                 vCompilerPath ~ vCompiler)); 
    2315     } 
    2316  
    2317     if (vVerbose){ 
     2133                vCompilerPath ~ vCompilerExe)); 
     2134    } 
     2135 
     2136    if (vVerbose == True){ 
    23182137        writefln("Compiler installed in %s",vCompilerPath); 
    23192138        writefln("Configuration File installed in %s",vConfigPath); 
     
    23452164    foreach( char[] lFile; vCmdLineSourceFiles) 
    23462165    { 
    2347         if (! util.fileex.FileExists( lFile ) ) 
    2348         { 
    2349             if (vSilent == false) 
     2166        if (! util.fileex.FileExists( GetFullPathname(lFile, vSourceScanList)) ) 
     2167        { 
     2168            if (vSilent == False) 
    23502169                writefln("** File '%s' not found.", lFile); 
    23512170            lAllExist = false; 
     
    23602179    lBuildResult = Build(); 
    23612180 
    2362     if(vVerbose) { 
     2181    if(vVerbose == True) { 
    23632182        writefln(""); 
    23642183        DisplayItems(vBuildArgs,      "build args: ..............."); 
    23652184        DisplayItems(vCompilerArgs,   "compiler args: ................"); 
    23662185        DisplayItems(vCmdLineSourceFiles,   "command line files: ..............."); 
    2367         DisplayItems(Source.SourceIndex.keys
     2186        DisplayItems(Source.ScanOrder
    23682187                                      "source files: ..............."); 
    23692188        DisplayItems(vLinkFiles.keys, "link files: ..............."); 
     
    23742193    } 
    23752194 
    2376     if (vExecuteProgram && (vTargetExe.length > 0)) 
     2195    if ((vExecuteProgram == True) && (vTargetExe.length > 0)) 
    23772196    { 
    23782197        RunCommand( vTargetExe ~ " " ~ std.string.strip(vRunParms)); 
     
    23842203} 
    23852204 
    2386 void ProcessResponseFile(char[] pArg, bool pVerbose) 
     2205void ProcessResponseFile(char[] pArg, Bool pVerbose) 
    23872206{ 
    23882207    // A response file is being used. 
     
    23912210 
    23922211    if (pArg.length == 1) 
    2393         lRespFileName = "@build.brf"; 
     2212        lRespFileName = "build.brf"; 
    23942213    else 
    23952214        lRespFileName = pArg[1..length].dup; 
     
    24002219    } 
    24012220 
    2402     if (pVerbose
     2221    if (pVerbose == True
    24032222        writefln("Response file %s", lRespFileName); 
    24042223 
     
    24162235        lArg = std.string.strip(lArg); 
    24172236        if (lArg.length > 1){ 
    2418             if (pVerbose
     2237            if (pVerbose == True
    24192238                writefln("Response file arg: %s", lArg); 
    24202239            GatherOneArg( lArg ); 
     
    24272246    char[] lNewPath; 
    24282247    static char[] lImportSwitch; 
    2429     int lCut; 
    2430  
    2431     if(util.str.begins(pArg, "-version=") > 0) { 
     2248 
     2249    if(util.str.begins(pArg, "-version=") == True) { 
    24322250        char[] lVersionString; 
    24332251 
     
    24362254        pArg = vVersionSwitch ~ lVersionString; 
    24372255    } 
    2438     else if(util.str.begins(pArg, "-fversion=") > 0) { 
     2256    else if(util.str.begins(pArg, "-fversion=") == True) { 
    24392257        char[] lVersionString; 
    24402258 
     
    24522270        pArg = vDebugSwitch; 
    24532271    } 
    2454     else if(util.str.begins(pArg, "-fdebug=") > 0) { 
     2272    else if(util.str.begins(pArg, "-fdebug=") == True) { 
    24552273        char[] lDebugString; 
    24562274 
     
    24592277        pArg = vDebugSwitch ~ "=" ~ lDebugString; 
    24602278    } 
    2461     else if(util.str.begins(pArg, "-debug=") > 0) { 
     2279    else if(util.str.begins(pArg, "-debug=") == True) { 
    24622280        char[] lDebugString; 
    24632281 
     
    24692287    switch(pArg) { 
    24702288        case "-full": 
    2471             vForceCompile = true; 
     2289            vForceCompile = True; 
    24722290            vBuildArgs ~= pArg; 
    24732291            // Not passed thru. 
     
    24812299 
    24822300        case "-nolink": 
    2483             vNoLink = true; 
     2301            vNoLink = True; 
    24842302            vBuildArgs ~= pArg; 
    24852303            // Not passed thru. 
     
    25002318        case "-obj": 
    25012319            vLibraryAction = LibOpt.DontBuild; 
    2502             vNoLink = true; 
     2320            vNoLink = True; 
    25032321            vBuildArgs ~= pArg; 
    25042322            // Not passed thru. 
     
    25072325        case "-nounittest": 
    25082326            // Not passed thru. Deprecated switch is now ignored. 
    2509             if (vSilent == false) 
     2327            if (vSilent == False) 
    25102328                writefln("Note: '-nounittest' ignored. This switch is no longer used."); 
    25112329            break; 
     
    25182336 
    25192337        case "-silent": 
    2520             vSilent = true; 
     2338            vSilent = True; 
    25212339            vBuildArgs ~= pArg; 
    25222340            // Not passed thru. 
     
    25242342 
    25252343        case "-noautoimport": 
    2526             vAutoImports = false; 
     2344            vAutoImports = False; 
    25272345            vBuildArgs ~= pArg; 
    25282346            // Not passed thru 
     
    25302348 
    25312349        case "-nodef": 
    2532             vNoDef = true; 
     2350            vNoDef = True; 
    25332351            vBuildArgs ~= pArg; 
    25342352            // Not passed thru. 
     
    25362354 
    25372355        case "-nomacro": 
    2538             vMacroInput = false; 
     2356            vMacroInput = False; 
    25392357            vBuildArgs ~= pArg; 
    25402358            // Not passed thru. 
     
    25512369 
    25522370        case "-allobj": 
    2553             vAllObjects = true; 
     2371            vAllObjects = True; 
    25542372            vBuildArgs ~= pArg; 
    25552373            // Not passed thru. 
     
    25572375 
    25582376        case "-test": 
    2559             vTestRun = true; 
     2377            vTestRun = True; 
    25602378            vBuildArgs ~= pArg; 
    25612379            // Not passed thru. 
     
    25652383            // drop through ... 
    25662384        case "-clean": 
    2567             vCleanup = true; 
     2385            vCleanup = True; 
    25682386            vBuildArgs ~= pArg; 
    25692387            // Not passed thru. 
     
    25772395        case "-names": 
    25782396            vBuildArgs ~= pArg; 
    2579             vNames = true; 
     2397            vNames = True; 
    25802398            // Not passed thru. 
    25812399            break; 
     
    25852403            { 
    25862404            if (pArg[0] == '-') { 
     2405                if (pArg == "-g") 
     2406                { 
     2407                    // Requires symbolic debug info. 
     2408                    vLinkerDefSwitches ~= "/co"; 
     2409                    AddCompilerArg(pArg); 
     2410                    break; 
     2411                } 
     2412 
    25872413                // Test for Librarian options. 
    2588                 if (util.str.IsLike(pArg, cast(dchar[])"-LIBOPT*")
     2414                if (util.str.IsLike(pArg, "-LIBOPT*"d) == True
    25892415                { 
    25902416                    vLibrarianOpts ~= " " ~ pArg[7..$].dup; 
     
    25942420                } 
    25952421 
    2596                 if (util.str.begins(pArg, "-LIBPATH=") >= 0
     2422                if (util.str.begins(pArg, "-LIBPATH=") == True
    25972423                { 
    25982424                    vLibPaths ~= vConfigSep ~ pArg[9..$].dup; 
     
    26022428 
    26032429                // Test for alternate install locations. 
    2604                 if (util.str.IsLike(pArg, cast(dchar[])"-DCPATH*")
     2430                if (util.str.IsLike(pArg, "-DCPATH?*"d) == True
    26052431                { 
    26062432                    lNewPath = pArg[7..length].dup; 
    26072433                    if (vCompilerPath == vConfigPath) 
    26082434                    { 
    2609                         if (vVerbose
     2435                        if (vVerbose == True
    26102436                            writefln("CFPATH was %s now %s", vConfigPath, lNewPath); 
    26112437                        vConfigPath = lNewPath; 
    26122438                    } 
    2613                     if (vVerbose
     2439                    if (vVerbose == True
    26142440                        writefln("DCPATH was %s now %s", vCompilerPath, lNewPath); 
    26152441                    vCompilerPath = lNewPath; 
     
    26192445                } 
    26202446 
    2621                 if (util.str.IsLike(pArg,  cast(dchar[])"-CFPATH*")
    2622                 { 
    2623                     if (vVerbose
     2447                if (util.str.IsLike(pArg,  "-CFPATH?*"d) == True
     2448                { 
     2449                    if (vVerbose == True
    26242450                        writefln("CFPATH was %s now %s", vConfigPath, pArg[7..length]); 
    26252451                    vConfigPath = pArg[7..length].dup; 
     
    26292455                } 
    26302456 
    2631                 if (util.str.IsLike(pArg,  cast(dchar[])"-RDF*")) 
    2632                 { 
    2633                     if (vVerbose) 
     2457                if (util.str.IsLike(pArg,  "-PP?*"d) == True) 
     2458                { 
     2459                    char[] lNewPath; 
     2460                    lNewPath = pArg[3..length].dup; 
     2461                    if (vVerbose == True) 
     2462                        writefln("Added %s to Source Scan List", lNewPath); 
     2463                    vBuildArgs ~= pArg; 
     2464                    if ( util.str.ends(lNewPath, std.path.sep) == False) 
     2465                        lNewPath ~= std.path.sep; 
     2466                    vSourceScanList ~= lNewPath; 
     2467                    break; 
     2468 
     2469                } 
     2470 
     2471                if (util.str.IsLike(pArg,  "-RDF?*"d) == True) 
     2472                { 
     2473                    if (vVerbose == True) 
    26342474                        writefln("RDF was %s now %s", vRDFName, pArg[4..$]); 
    26352475                    vRDFName = pArg[4..$].dup; 
     
    26452485                    break; 
    26462486                } 
    2647                 else if ( (lCut = util.str.begins(pArg, vBuildImportPathSwitch)) >= 0
     2487                else if ( util.str.begins(pArg, vBuildImportPathSwitch) == True
    26482488                { 
    26492489                    char [] lRoot; 
    2650                     foreach(char[] lCmdRoot; std.string.split(pArg[lCut..$], ";")) 
     2490                    foreach(char[] lCmdRoot; std.string.split(pArg[vBuildImportPathSwitch.length .. $], ";")) 
    26512491                    { 
    26522492                        lRoot = AddRoot(lCmdRoot); 
    26532493                        if (lRoot.length > 0){ 
    2654                             if(vVerbose) { 
     2494                            if(vVerbose == True) { 
    26552495                                    writefln("Added root from command line = %s",lRoot); 
    26562496                            } 
     
    26592499                    break; 
    26602500                } 
    2661                 if (util.str.IsLike(pArg,  std.utf.toUTF32(vRunSwitch ~ "*"))) 
     2501 
     2502                if (util.str.IsLike(pArg,  std.utf.toUTF32(vRunSwitch ~ "*")) == True) 
    26622503                { 
    26632504                    vRunParms ~= pArg[vRunSwitch.length .. $] ~ " "; 
    2664                     vExecuteProgram = true; 
     2505                    vExecuteProgram = True; 
    26652506                    vBuildArgs ~= pArg; 
    26662507                    break; 
     
    26712512                version(DigitalMars) 
    26722513                { 
    2673                 if (util.str.IsLike(pArg,  std.utf.toUTF32(vTemporaryPathSwitch ~ "*"))
     2514                if (util.str.IsLike(pArg,  std.utf.toUTF32(vTemporaryPathSwitch ~ "*")) == True
    26742515                { 
    26752516                    char[] lRoot; 
     
    26812522                    lRoot = AddRoot(vTemporaryPath); 
    26822523                    if (lRoot.length > 0){ 
    2683                         if(vVerbose) { 
     2524                        if(vVerbose == True) { 
    26842525                                writefln("Added root from Object Write Path = %s",lRoot); 
    26852526                        } 
     
    26922533                } 
    26932534 
    2694                 if (util.str.IsLike(pArg,  cast(dchar[])"-X*")
     2535                if (util.str.IsLike(pArg,  "-X?*"d) == True
    26952536                { 
    26962537                    // Modules to ignore (eg. -Xmylib) 
     
    27002541                } 
    27012542 
    2702                 if (util.str.IsLike(pArg,  cast(dchar[])"-M*")
     2543                if (util.str.IsLike(pArg,  "-M?*"d) == True
    27032544                { 
    27042545                    // Modules to notice (eg. -Mphobos) 
     
    27082549                } 
    27092550 
    2710                 if (util.str.IsLike(pArg,  cast(dchar[])"-T*")
     2551                if (util.str.IsLike(pArg,  "-T?*"d) == True
    27112552                { 
    27122553                    // Target name (eg. -Ttestapp) 
     
    27182559                version(DigitalMars) 
    27192560                { 
    2720                 if (util.str.IsLike(pArg,  (vOutFileSwitch ~ "*"))
     2561                if (util.str.IsLike(pArg,  (vOutFileSwitch ~ "*")) == True
    27212562                { 
    27222563                    // Target name (eg. -oftestapp) 
     
    27382579                } 
    27392580 
    2740                 if (util.str.IsLike(pArg,  cast(dchar[])"-R*")
     2581                if (util.str.IsLike(pArg,  "-R*"d) == True
    27412582                { 
    27422583                    // Response file usage (eg. -Ry) 
    27432584                    if (pArg.length == 2) 
    2744                         vUseResponseFile = (vUseResponseFile ? false : true)
     2585                        vUseResponseFile = ~vUseResponseFile
    27452586 
    27462587                    else if (pArg[2] == 'y') 
    2747                         vUseResponseFile = true; 
     2588                        vUseResponseFile = True; 
    27482589 
    27492590                    else 
    2750                         vUseResponseFile = false; 
     2591                        vUseResponseFile = False; 
    27512592 
    27522593                    vBuildArgs ~= pArg; 
     
    27552596 
    27562597                version(Windows) { 
    2757                     if (util.str.IsLike(pArg,  cast(dchar[])"-gui*")
     2598                    if (util.str.IsLike(pArg,  "-gui*"d) == True
    27582599                    { 
    27592600                            Source.WasMainGUI = true; 
     
    27672608                            break; 
    27682609                    } 
     2610 
    27692611                    if (pArg == "-dll") 
    27702612                    { 
     
    27902632                            lRoot = AddRoot(lCmdRoot); 
    27912633                            if (lRoot.length > 0){ 
    2792                                 if(vVerbose) { 
     2634                                if(vVerbose == True) { 
    27932635                                        writefln("Added root from command line = %s",lRoot); 
    27942636                                } 
     
    28052647                } 
    28062648 
     2649                version(Windows) 
     2650                { 
     2651                    // Convert non-standard but sometimes used unix seps 
     2652                    // with standard Windows seps. 
     2653                    pArg = std.string.replace(pArg, "/", std.path.sep); 
     2654                } 
    28072655                switch(std.path.getExt(pArg)) { 
    28082656                   case "": 
     
    28132661                   case kSrcExtention: 
    28142662                   case kMacroExtention: 
     2663                   case kDdocExtention: 
    28152664                       vCmdLineSourceFiles ~= pArg; 
    28162665                       break; 
     
    28372686 
    28382687    if ((pArg == "-V") || (pArg == "-v")) 
    2839         vVerbose = true; 
     2688        vVerbose = True; 
    28402689 
    28412690    if ( pArg.length >= 2 && pArg[0..2] == "--") 
     
    28432692        pArg = pArg[1..$]; 
    28442693        if ((pArg == "-V") || (pArg == "-v")) 
    2845             vVerbose = false; 
     2694            vVerbose = False; 
    28462695        for(int i = vCombinedArgs.length-1; i >= 0; i--) 
    28472696        { 
    28482697            if (pArg[$-1] == '*') 
    28492698            { 
    2850                 if (vCombinedArgs[i].begins(pArg[0..$-1]) > 0
     2699                if (vCombinedArgs[i].begins(pArg[0..$-1]) == True
    28512700                { 
    28522701                    vCombinedArgs = vCombinedArgs[0..i] ~ 
     
    28962745} 
    28972746 
    2898 void ProcessMacroDefs(bool pVerbose) 
     2747void ProcessMacroDefs(Bool pVerbose) 
    28992748{ 
    29002749    // From build.exe location 
     
    29062755} 
    29072756 
    2908 void ProcessOneMacroDef(bool pVerbose, char[] pPath) 
     2757void ProcessOneMacroDef(Bool pVerbose, char[] pPath) 
    29092758{ 
    29102759    char[] lMacroDefFileName; 
     
    29362785 
    29372786 
    2938     if (pVerbose && util.fileex.FileExists(lMacroDefFileName) ) 
     2787    if ((pVerbose == True) && util.fileex.FileExists(lMacroDefFileName) ) 
    29392788        writefln("Build Macro Definition file %s", lMacroDefFileName); 
    29402789    lMacroDefLines = util.fileex.GetTextLines(lMacroDefFileName, util.fileex.GetOpt.Always); 
     
    29572806        { 
    29582807 
    2959             if (lArg.begins("replace ") > 0
     2808            if (lArg.begins("replace ") == True
    29602809            { 
    29612810                int lStartPos; 
     
    30342883 
    30352884            } 
    3036             else if (lArg.begins("delim ") > 0
     2885            else if (lArg.begins("delim ") == True
    30372886            { 
    30382887 
     
    30722921                                break; 
    30732922                            default: 
    3074                                 if (pVerbose
     2923                                if (pVerbose == True
    30752924                                    writefln("Bad Macro 'delim' option '%s'", 
    30762925                                            lOption); 
     
    30812930                } 
    30822931            } 
    3083             else if (vVerbose
     2932            else if (vVerbose == True
    30842933            { 
    30852934                writefln("Bad configuration command '%s'", lArg); 
     
    30892938} 
    30902939 
    3091 void ProcessBuildConfig(char[] pArg, bool pVerbose) 
     2940void ProcessBuildConfig(char[] pArg, Bool pVerbose) 
    30922941{ 
    30932942    // From build.exe location 
     
    30972946    ProcessOneBuildConfig(pArg, pVerbose, vCompilerPath); 
    30982947 
    3099 
    3100  
    3101 void ProcessOneBuildConfig(char[] pArg, bool pVerbose, char[] pPath) 
     2948    // From current location 
     2949    ProcessOneBuildConfig(pArg, pVerbose, util.pathex.GetInitCurDir() ); 
     2950 
     2951
     2952 
     2953void ProcessOneBuildConfig(char[] pArg, Bool pVerbose, char[] pPath) 
    31022954{ 
    31032955    char[] lConfigFileName; 
     
    31142966    lConfigFileName ~= "build.cfg"; 
    31152967 
    3116     if (pVerbose  && util.fileex.FileExists(lConfigFileName)) 
     2968    if ((pVerbose == True)  && util.fileex.FileExists(lConfigFileName)) 
    31172969        writefln("Build Configuration file %s [%s]", lConfigFileName, pArg); 
    31182970 
     
    31543006                    break; // Don't process any more lines. 
    31553007 
    3156                 if (pVerbose
     3008                if (pVerbose == True
    31573009                    writefln("Build Configuration file arg: %s", lArg); 
    31583010 
     
    31633015                } 
    31643016 
    3165                 if (lArg.begins("CMDLINE=") > 0
     3017                if (lArg.begins("CMDLINE=") == True
    31663018                { 
    31673019                    int lStartPos; 
     
    31963048 
    31973049                } 
    3198                 else if (lArg.begins("LIBCMD=") > 0
     3050                else if (lArg.begins("LIBCMD=") == True
    31993051                { 
    32003052                    int lPos; 
     
    32083060 
    32093061                    vLibrarian = std.path.getBaseName(lArg[7..$]); 
    3210                     if(vVerbose) { 
     3062                    if(vVerbose == True) { 
    32113063                        writefln(" librarian path %s",vLibrarianPath); 
    32123064                        writefln(" librarian is %s",vLibrarian); 
    32133065                    } 
    32143066                } 
    3215                 else if (vVerbose) 
     3067                else if (lArg.begins("LINKSWITCH=") == True) 
     3068                { 
     3069                    vLinkerDefSwitches = lArg[11..$].dup; 
     3070                } 
     3071                else if (vVerbose == True) 
    32163072                { 
    32173073                    writefln("Bad configuration command '%s'", lArg); 
     
    32213077    } 
    32223078} 
    3223  
    3224 /* ============= The User Manual ====================================== 
    3225 __ /topic Introduction 
    3226 __ /info 
    3227 __ This is a utility to build an application using the D programming language. 
    3228 __ It does this by examining the source file supplied on the command line 
    3229 __ to work out its dependant files, and then determines which need to be 
    3230 __  compiled and which need to be linked to create the executable. 
    3231 __ 
    3232 __ Alternatively, it can be used to create a Library file rather than an 
    3233 __  executable. 
    3234 __ 
    3235 __ The aim of the utility is to help remove the need for /i make files 
    3236 __  or similar devices. 
    3237  
    3238 __ /topic Pragma 
    3239 __ /info 
    3240 __ The /b build utility supports the use of various pragma statements. 
    3241 __ A pragma is a special statement embedded in the source code that 
    3242 __  provides information to tools reading the source code. 
    3243 __ 
    3244 __ They take the forms ... 
    3245 __ /code 
    3246 __       /b"pragma(" ~<name~> /b");" 
    3247 __       /b"pragma(" ~<name~> /b"," ~<option~> [ /b","~<option~>] /b");" 
    3248 __ /endcode 
    3249 __ 
    3250 __ If the D compiler doesn't recognise the pragma, it will fail. So to 
    3251 __  'hide' them from the compiler, you need to wrap them in a /b version 
    3252 __  block. All the pragmas used by this utility need to be enclosed in 
    3253 __  a /i build version. 
    3254 __ 
    3255 __ Example: 
    3256 __ /code 
    3257 __       version(build) { pragma(nolink); } 
    3258 __ /endcode 
    3259  
    3260 __ /topic Pragma 
    3261 __ /pragma link 
    3262 __ /desc This nominates one or more libraries that are required to be linked in. 
    3263 __ If your applications needs code from a library to be linked in, rather than 
    3264 __  supplying source code, you can tell /i build which libraries are needed. 
    3265 __ This can happen when using a library provided by a third-party. 
    3266 __ 
    3267 __ Example 1: 
    3268 __ /code 
    3269 __       /// This app needs the MyGUI.lib library to be used. 
    3270 __       version(build) { pragma(link, MyGUI); } 
    3271 __ /endcode 
    3272 __ 
    3273 __ Example 2: 
    3274 __ /code 
    3275 __       /// This app needs the a DB library and TCP library to be used. 
    3276 __       version(build) { pragma(link, EuDB, TCP4Win); } 
    3277 __ /endcode 
    3278  
    3279 __ /topic Pragma 
    3280 __ /pragma nolink 
    3281 __ /desc This identifies that the current module is not to be be linked in. 
    3282 __ Normally, each object file created by the compiler is linked in, but 
    3283 __  if the supplied source file is just a stub for code which is externally 
    3284 __  defined in a library, then you do not need the 'stub' object file. 
    3285 __ 
    3286 __ Example: 
    3287 __ /code 
    3288 __       version(build) { pragma(nolink); } 
    3289 __ /endcode 
    3290  
    3291 __ /topic Pragma 
    3292 __ /pragma include 
    3293 __ /desc This identifies a required file which is not otherwise imported. 
    3294 __ In some applications, especially ones converted over from C, it is 
    3295 __ possible that the file on the /i Build command line does not directly 
    3296 __ or indirectly import a required file. In those situations, you can 
    3297 __ use this pragma to tell build to include it in the compilation checking 
    3298 __ process. 
    3299 __ 
    3300 __ Example: 
    3301 __ /code 
    3302 __       // Tell 'build' that prime.d must be included (it contains the main function.) 
    3303 __       version(build) { pragma(include, "prime"); } 
    3304 __ /endcode 
    3305  
    3306 __ /topic Pragma 
    3307 __ /pragma target 
    3308 __ /desc This identifies the basename of the target file. 
    3309 __ By default, the target name is based on the first file on the command line. 
    3310 __ But if you include this pragma, the name identified in the pragma becomes 
    3311 __ the default name. In either case, the -T switch overrides the default name. 
    3312 __ 
    3313 __  If two or more /i target pragmas are found, the first one is the one 
    3314 __  that is used and the others are ignored (though mentioned if in 
    3315 __  verbose mode). 
    3316 __ Example: 
    3317 __ /code 
    3318 __       //// Tell 'build' to create WhizzBang.exe 
    3319 __       version(build) { pragma(target, "WhizzBang"); } 
    3320 __ /endcode 
    3321  
    3322 __ /topic Pragma 
    3323 __ /pragma build 
    3324 __ /desc This identifies a file that needs an external program to build it. 
    3325 __ Some applications need to link in object files created by C source, or 
    3326 __ by a /i resource compiler, or whatever. This pragma identifies a file 
    3327 __ that needs to be linked in, but cannot be created by the D compiler. The 
    3328 __ format is /n 
    3329 __ /code 
    3330 __     pragma(build, "FILENAME" [, "OPTIONS"] ...); 
    3331 __ /endcode 
    3332 __ where /i FILENAME is either the file to link in, or the file to use when 
    3333 __ creating the file to link in. For example, if you had a Windows resource file 
    3334 __ that needed to be compiled, you could code the pragma as either ... 
    3335 __ 
    3336 __ /code 
    3337 __     //// Compile the images into a resource obj and add images.res to linker. 
    3338 __     pragma(build, "images.rc"); 
    3339 __ /endcode 
    3340 __ or /n 
    3341 __ /code 
    3342 __     //// Compile the images into a resource obj and add images.res to linker. 
    3343 __     pragma(build, "images.res"); 
    3344 __ /endcode 
    3345 __ 
    3346 __ The first example specifies the source file to be passed to the resource 
    3347 __ compiler and the second example specifies the output of the resource compiler. 
    3348 __ In either case, this utility uses the rules in a /"Rule Definition File" to 
    3349 __ decide what to do. 
    3350 __ 
    3351 __ The utility searches for the /i"FILENAME" in the currently defined 'import' 
    3352 __ paths. 
    3353 __ 
    3354 __ The /i OPTIONS can be included if you need to pass any special values 
    3355 __ to the external tool. There can be any number of these, but each one must 
    3356 __ take the form ~<KEYWORD>=~<VALUE>. For example /n 
    3357 __ /code 
    3358 __       pragma(build, "dbapi.c", "COPT=-wc -x", "HDR=abc.hp"); 
    3359 __ /endcode 
    3360 __ The OPTIONS values are used as replacement text for token in the 
    3361 __ Rule Definition File's 'tool' specification. In the example above, 
    3362 __ the tokens {COPT} and {HDR}, if found in the 'tool' line, would be 
    3363 __ replaced with /i"-wc -x" and /i"abc.hp" respectively. 
    3364 __ 
    3365 __ The output file to the external tool is checked to see if it is still 
    3366 __ up to date. 
    3367 __ 
    3368 __ The output file from the external tool is added to the linkage set. 
    3369 __ 
    3370 __ All such external programs are run before the D compiler is invoked. 
    3371 __ 
    3372 __ Example: 
    3373 __ /code 
    3374 __       //// Tell 'build' that it needs to call an external program 
    3375 __       //// to build an up-to-date version of 'images.rc' 
    3376 __       version(build) { pragma(build, "images.rc"); } 
    3377 __ /endcode 
    3378  
    3379 __ /topic Rule Definition File 
    3380 __ /info 
    3381 __ Defines the rules used to build non-D source files. 
    3382 __ This is not as advanced as the typical /b makefile abilities and is 
    3383 __ only useful for simple situations. Specifically, it only caters for 
    3384 __ applications that take a single input file to create the required 
    3385 __ output file. 
    3386 __ 
    3387 __ The default Rule Definition File is called "default.rdf". It is found by 
    3388 __ first looking in the directory where the utility is installed, and if 
    3389 __ it is not found there, the directories in the PATH environment symbol 
    3390 __ are scanned. 
    3391 __ 
    3392 __ The default RDF can be overridden by the -RDF command line switch. 
    3393 __ 
    3394 __ Each rule is defined in a set of four mandatory lines ... /n 
    3395 __ /li rule=~<name> 
    3396 __ /li source=~<extention> 
    3397 __ /li target=~<extention> 
    3398 __ /li tool=~<command pattern> 
    3399 __ 
    3400 __ Any other line in the file, not starting with one of the above keywords 
    3401 __ is simply ignored (treated as comments). 
    3402 __ 
    3403 __ The /i"tool" line can contain special tokens. These are keywords enclosed 
    3404 __ in braces. At compile time, the tokens are replaced by replacement text 
    3405 __ taken from the pragma(build) statement. There are two predefined tokens 
    3406 __ that can be used. /b"{@IN}" is replaced by the name of the input file, 
    3407 __ and /b"{@OUT}" is replaced by the name of the output file. 
    3408 __ 
    3409 __ /code 
    3410 __  ----- Windows Resource Compiler ----- 
    3411 __  This uses ` pragma(/b'build', ~<sourcefile>.rc); ` 
    3412 __  ------------------------------------- 
    3413 __  rule=Resources 
    3414 __  source=rc 
    3415 __  target=res 
    3416 __ tool=rc //r {@IN} //fo {@OUT} 
    3417 __ 
    3418 __  ------------------------------------- 
    3419 __  DMD C linkage 
    3420 __  This uses ` pragma(build, ~<sourcefile>.c, "COPT=~<options>", "HDR=~<whatever>"); ` 
    3421 __  ------------------------------------- 
    3422 __ rule=DMD C/C++ 
    3423 __  source=c 
    3424 __  target=obj 
    3425 __  tool=dmc -c {COPT} {@IN} -o{@OUT} {HDR} 
    3426 __ 
    3427 __ /endcode 
    3428  
    3429 __ /topic Pragma 
    3430 __ /pragma export_version 
    3431 __ /desc This allows you to set a global version identifier. 
    3432 __ DMD allows you to set a version identifier in your code, but the scope 
    3433 __ of that is only for the module it is set in. This pragma gives you the 
    3434 __ ability to declare a version identifier which is applied to all modules 
    3435 __ being compiled, and not just the 'current' module. 
    3436 __ 
    3437 __ Example: 
    3438 __ /code 
    3439 __     version(build) pragma(export_version, Unix); 
    3440 __     version(build) pragma(export_version, Limited); 
    3441 __ /endcode 
    3442 __ These lines will cause the compiler to have these version identifiers 
    3443 __ added to the command line switches, thus making them effectively global. 
    3444 __ 
    3445 __ You can list more than one identifier on the pragma statement ... 
    3446 __ /code 
    3447 __     version(build) pragma(export_version, Unix, Limited); 
    3448 __ /endcode 
    3449  
    3450 __ /topic Pragma 
    3451 __ /pragma build_def 
    3452 __ /desc This supplies an option to be placed in an OptLink definition file. 
    3453 __ You can have /i build create a customised OptLink definition file 
    3454 __ by coding as many /i build_def pragmas as required. However, /i build will 
    3455 __ only allow the first of each type of Definition File command to be used. THis 
    3456 __ means that if you code ... /n 
    3457 __ /code 
    3458 __       pragma (build_def, "EXETYPE DOS"); 
    3459 __       pragma (build_def, "EXETYPE NT"); 
    3460 __ /endcode 
    3461 __ Then the EXETYPE DOS will be used and the 'NT' line ignored. You can use 
    3462 __ explicit build_def pragmas to override the default ones generated by 
    3463 __  /i build for Windows programs or DLL libraries. 
    3464 __ 
    3465 __ The syntax for these pragma is /n 
    3466 __ /code 
    3467 __           pragma(build_def, ~<QUOTED_STRING~> ); 
    3468 __ /endcode 
    3469 __ 
    3470 __ Example: 
    3471 __ /code 
    3472 __   version(build) { 
    3473 __     pragma (build_def, "VERSION 1.1"); 
    3474 __     version(DOS) { 
    3475 __       pragma (build_def, "EXETYPE DOS"); 
    3476 __     } 
    3477 __     version(WIN) { 
    3478 __       pragma (build_def, "EXETYPE NT"); 
    3479 __       pragma (build_def, "SUBSYSTEM WINDOWS,4.0"); 
    3480 __     } 
    3481 __   } 
    3482 __ /endcode 
    3483 __ 
    3484 __ You can supply /b any text string and it is used verbatim. There is no 
    3485 __  restrictions on what you can include in the pragma. 
    3486  
    3487 __ /topic Auto Build Number 
    3488 __ /info 
    3489 __ Automatically Incremented Build Numbering for Modules 
    3490 __ You can optionally specify that the /i build utility automatically 
    3491 __ increments a build number for any module. You do this by supplying 
    3492 __  a single line in your source code in the form ... /n 
    3493 __ /code 
    3494 __       private import /b"~<modulename~>"_bn; 
    3495 __ /endcode 
    3496 __ Typically this line is placed immediately after the source file's 
    3497 __ /b module statement, but that is not strictly necessary. 
    3498 __ 
    3499 __ By having this line in your code, /i build then uses a file with the 
    3500 __  suffix "_bn.d" to maintain 
    3501 __ the current build number for the ~<modulename~>. Note that /i build 
    3502 __  will create this file if it doesn't exist. Also note that 
    3503 __  /i build will update this file whenever the module file has been 
    3504 __  updated or its object file needs to be rebuilt, so you really 
    3505 __ shouldn't modify it manually. Any manual changes will be deleted 
    3506 __  by /i build. /n 
    3507 __ 
    3508 __ Example: /n 
    3509 __ If your module is called "parser.d" you would have the lines ... 
    3510 __ /code 
    3511 __   module parser; 
    3512 __   private import parser_bn; 
    3513 __ /endcode 
    3514 __ 
    3515 __ You can access the build number from within the module thus ... /n 
    3516 __ 
    3517 __ /code 
    3518 __           writefln("Build number is %d", auto_build_number); 
    3519 __ /endcode 
    3520 __ You can access the build numbers of other modules in you application 
    3521 __  by importing the appropriate file and prefixing the references with 
    3522 __  the module names. /n 
    3523 __ Example: 
    3524 __ /code 
    3525 __       module parser;  /// This module's name. 
    3526 __       private import parser_bn;   /// This module's B/N 
    3527 __       private import tokenizer_bn; /// Another module's B/N 
    3528 __       . . . 
    3529 __       writefln("Builds..."); 
    3530 __       writefln("  Parser %d", parser_bn.auto_build_number); 
    3531 __       writefln("  Tokens %d", tokenizer_bn.auto_build_number); 
    3532 __ /endcode 
    3533 __ 
    3534 __ The "_bn.d" file created by /i build for this module would look like ... /n 
    3535 __ /code 
    3536 __   module parser_bn; 
    3537 __   /// This file is automatically maintained by the BUILD utility, 
    3538 __   /// Please refrain from manually editing it. 
    3539 __   long auto_build_number = 77; 
    3540 __ /endcode 
    3541 __ Of course the number /i 77 is just an example. This number would actually 
    3542 __  start at 1 and increment whenever /i build needed to create a new object 
    3543 __ file for the module. 
    3544  
    3545 __ /topic Command Line 
    3546 __ /info 
    3547 __ The /i build utility supplies the source file and optional switches via the command line. 
    3548 __ The typical format of the /i build utility's command line is ... /n 
    3549 __ /code 
    3550 __       /b build ~<sourcefile~> [ ~<switches~> ] [ ~<otherfiles~> ] 
    3551 __ /endcode 
    3552 __ You can however specify the files and switches in any order you like. 
    3553 __ 
    3554 __ Normally you would only supply a single file name to /i build, that being 
    3555 __  the source file of the top-level file in the application. Typically 
    3556 __  the one that has the 'main()' or 'WinMain()' function, though this is 
    3557 __  not strictly necessary. 
    3558 __ 
    3559 __ If you run the utility without any files and without any switches, it 
    3560 __  display a /i help screen with some details about the switches. That looks 
    3561 __  like this ... 
    3562 __ /code 
    3563 __   Path and Version : C:\Program Files\build.exe v3.6(339) 
    3564 __   Usage: build sourcefile [options objectfiles libraries] 
    3565 __     /b sourcefile D source file 
    3566 __     /b"-v"         Verbose (passed through to D) 
    3567 __     /b"-V"         Verbose (NOT passed through) 
    3568 __     /b"-names"     Displays the names of the files used to build the target. 
    3569 __     /b"-DCPATH~<path~> ~<path~>" is where the compiler has been installed. 
    3570 __                Only needed if the compiler is not in the system's 
    3571 __                PATH list. Used if you are testing an alternate 
    3572 __                version of the compiler. 
    3573 __     /b"-CFPATH~<path~> ~<path~>" is where the D config file has been installed. 
    3574 __     /b"-full"      Causes all source files, except ignored modules, 
    3575 __                 to be compiled. 
    3576 __     /b"-link"      Forces the linker to be called instead of the librarian. 
    3577 __                 (Only needed if the source files do not contain 
    3578 __                  main/WinMain) 
    3579 __     /b"-nolink"    Ensures that the linker is not called. 
    3580 __                 (Only needed if main/WinMain is found in the source 
    3581 __                  files and you do NOT want an executable created.) 
    3582 __     /b"-lib"       Forces the object files to be placed in a library. 
    3583 __                 (Only needed if main/WinMain is found in the source 
    3584 __                  files AND you want it in a library instead of 
    3585 __                  an executable.) 
    3586 __     /b"-nolib"     Ensures that the object files are not used to form 
    3587 __                 a library. 
    3588 __                 (Only needed if main/WinMain is not found in the source 
    3589 __                  files and you do NOT want a library. 
    3590 __     /b"-obj"       This is the same as having both -nolink and -nolib 
    3591 __                 switches on the command line. It is just a shorthand. 
    3592 __     /b"-allobj"    Ensures that all object files are added to a 
    3593 __                 library. 
    3594 __                 (Normally only those in the same directory are added.) 
    3595 __     /b"-cleanup"   Ensures that all object files created during the run 
    3596 __                 are removed at the end of the run, plus other work files. 
    3597 __     /b"-clean"     Same as -cleanup 
    3598 __     /b"-test"      Does everything as normal except it displays the commands 
    3599 __                   instead of running them. Also, the auto-build-numbers are 
    3600 __                   not incremented. 
    3601 __     /b"-RDF~<path~>"  Overrides the default Rule Definition File 
    3602 __     /b"-gui[:x.y]" Forces a GUI application to be created. The optional 
    3603 __                 :x.y can be used to build an application for a 
    3604 __                 specific version of Windows. eg. -gui:4.0 
    3605 __                 (Only needed if WinMain is not found in the source files 
    3606 __                 or if you wish to override the default Windows version) 
    3607 __     /b"-dll"       Forces a DLL library to be created. 
    3608 __                       (Only needed if DllMain is not found in the source files. 
    3609 __     /b"-LIBOPT~<opt~>" Allows you to pass ~<opt~> to the librarian 
    3610 __     /b"-LIBPATH=~<pathlist~>" Used to add a semi-colon delimited list 
    3611 __                 of search paths for library files. 
    3612 __     /b"-X~<module~>" Packages and Modules to ignore (eg. -Xmylib) 
    3613 __     /b"-M~<module~>" Packages and Modules to notice (eg. -Mphobos) 
    3614 __     /b"-T~<targetname~>" The name of the target file to create. Normally 
    3615 __                 the target name istaken from the first or only name 
    3616 __                 of the command line. 
    3617 __     /b"-R~<y|n~>" Indicates whether to use a response file or command line 
    3618 __                    arguments with the compiler tools. 
    3619 __                  /b"-Ry" will cause a response to be used. 
    3620 __                  /b"-Rn" will cause command line arguments to be used. 
    3621 __                  /b"-R" will reverse the current usage. 
    3622 __                   Note that the default for Windows DigitalMars is to use a response file 
    3623 __                   but for all other environments it is to use command line arguments. 
    3624 __     /b"-info"      Displays the version and path of the Build application 
    3625 __     /b"-help"      Displays the full 'usage' help text. 
    3626 __     /b"-h"         Same as /-help, displays the full 'usage' help text. 
    3627 __     /b"-?   "      Same as /-help, displays the full 'usage' help text. 
    3628 __     /b"-silent"    Avoids unnecessary messages being displayed. 
    3629 __     /b"-noautoimport" Turns off the automatic addition of source paths 
    3630 __                    to the list of Import Roots. 
    3631 __     /b"-run~<param~>"   If the link is successful, this will cause the 
    3632 __                    executable just created to run. You can give it 
    3633 __                    run time parameters. Anything after the '-run' will 
    3634 __                    placed in the program's command line. You will need 
    3635 __                    to quote any embedded spaces. 
    3636 __     /b"-od~<path~>"  Nominate the directory where temporary (work) files 
    3637 __                    are to be created. By default they are created in 
    3638 __                    the same directory as the target file. 
    3639 __     /b"-nodef"     Prevents a Module Definition File being automatically created. 
    3640 __                 This will override any pragma(/build_def) statements in the 
    3641 __                 source code. 
    3642 __     /b"[...]"      All other options, objectfiles and libraries are 
    3643 __                 passed to the compiler 
    3644 __ /endcode 
    3645 __ 
    3646 __ See also /"Response File" 
    3647  
    3648 __ /topic Switches 
    3649 __ /info 
    3650 __ /i Build supports a number of command line switches to control its default assumptions. 
    3651  
    3652  
    3653 __ /topic switches 
    3654 __ /switch -nodef 
    3655 __ /desc Prevent a Module Definition File being created. 
    3656 __ Normally, the utility will automatically create a Module Definition File 
    3657 __ for the linker. This will typically contain the EXETYPE command and any other 
    3658 __ commands as specified in any pragma(/build_def) statements found in the source files. 
    3659 __ If you specify this switch, you will have to provide your own Module Definition 
    3660 __ File or its equivalent on the command line. 
    3661  
    3662 __ /topic switches 
    3663 __ /switch -v 
    3664 __ /desc Set /i verbose mode on for both /i build and for the compiler 
    3665  
    3666 __ /topic switches 
    3667 __ /switch -V 
    3668 __ /desc Set /i verbose mode on for just /i build and not for the compiler 
    3669  
    3670 __ /topic switches 
    3671 __ /switch -names 
    3672 __ /desc Displays the names of the files used in building the target. 
    3673  
    3674 __ /topic switches 
    3675 __ /switch -DCPATH 
    3676 __ /desc  Identifies where the compiler has been installed. 
    3677 __ Normally, /i build scans the PATH environment symbol to find where the 
    3678 __  D compiler is located. However, if you need to use the compiler from 
    3679 __  a different location, you would use this switch to tell /i build where 
    3680 __  it is. 
    3681 __ 
    3682 __ /b"Note:" If you use this switch, and the current CFPATH value is 
    3683 __ identical to the current DCPATH value, then this switch will change 
    3684 __ both to the new value. The assumption is that the configuration 
    3685 __ file is in the same directory as the compiler. If this is not the case, 
    3686 __ you will also need to use the /-CFPATH switch. 
    3687 __ 
    3688 __ Example: 
    3689 __ /code 
    3690 __   -DCPATHc:\old\dmd\bin 
    3691 __ /endcode 
    3692  
    3693 __ /topic switches 
    3694 __ /switch -CFPATH 
    3695 __ /desc Identifies where the D config file has been installed. 
    3696 __ Normally, /i build looks in the same place that the compiler is 
    3697 __  installed in, but if you need to use a different configuration 
    3698 __  path from that, you would use this switch to tell /i build where 
    3699 __  it is. 
    3700 __ 
    3701 __ Example: 
    3702 __ /code 
    3703 __   -CFPATHc:\myproject\configs 
    3704 __ /endcode 
    3705  
    3706 __ /topic switches 
    3707 __ /switch -full 
    3708 __ /desc Causes all source files, except ignored modules, to be compiled. 
    3709 __ Normally, /i build only compiles a source file if it's object file 
    3710 __ is out of date or missing. This switch forces all source files to be 
    3711 __  recompiled, even if not strictly required. 
    3712 __ 
    3713 __ /b "Note:" Modules in the /i ignore list are still ignored though. 
    3714  
    3715 __ /topic switches 
    3716 __ /switch -link 
    3717 __ /desc Forces the linker to be called instead of the librarian. 
    3718 __ Normally, if /i build does not find a main() or WinMain() function 
    3719 __  in the source files, it creates a library to contain the object 
    3720 __ files. But when this switch is used, /i build will attempt to 
    3721 __  create an application by calling the linker rather than the librarian. 
    3722 __ 
    3723 __ You would typically use this if the main() function was being supplied 
    3724 __ from an existing library file rather than one you your source files. 
    3725  
    3726 __ /topic switches 
    3727 __ /switch -run 
    3728 __ /desc Runs a program after successful linking. 
    3729 __ If the link is successful, this will cause the 
    3730 __ executable just created to run. You can give it 
    3731 __ run time parameters. Anything after the '-run' will 
    3732 __ placed in the program's command line. You will need 
    3733 __ to quote any embedded spaces. 
    3734 __ 
    3735 __Example: 
    3736 __/code 
    3737 __     -run"abc.de second" 
    3738 __/endcode 
    3739  
    3740 __ /topic switches 
    3741 __ /switch -od 
    3742 __ /desc Nominates the temporary file directory. 
    3743 __ By default, the utility creates any work files in the same directory 
    3744 __ as the target file. You can use this switch to nominate an alternative 
    3745 __ location for these files. The directory is created if it doesn't exist. 
    3746 __ 
    3747 __ For the DigitalMars compiler, this also specifies the top-level 
    3748 __ location where object files are created. By default, object files 
    3749 __ are created in the same directory as the corresponding source file. 
    3750 __ 
    3751 __ Example: 
    3752 __ /code 
    3753 __         -odC:\temp\workarea 
    3754 __ /endcode 
    3755  
    3756 __ /topic switches 
    3757 __ /switch -nolink 
    3758 __ /desc  Ensures that the linker is not called. 
    3759 __ Normally, if /i build finds a main() or WinMain() function, it 
    3760 __ tries to create an application by calling the linker. If you use 
    3761 __  this switch however, the linker will not be called. 
    3762 __ 
    3763 __ You would typically do this if you wanted to create a library that 
    3764 __ stores your 'main' function in it, in which case you'd also use the /-lib 
    3765 __  switch. But you could just create a set of object files without linking 
    3766 __  them with this switch. 
    3767  
    3768 __ /topic switches 
    3769 __ /switch -lib 
    3770 __ /desc Forces the object files to be placed in a library. 
    3771 __ Normally, if /i build finds a main() or WinMain() function, it 
    3772 __ tries to create an application by calling the linker. But if you 
    3773 __  use this switch, the librarian is called instead of the linker. 
    3774 __ 
    3775 __ You would typically do this if you wanted to create a library that 
    3776 __ stores your 'main' function in it, in which case you'd also use the /-nolink 
    3777 __ switch. 
    3778  
    3779 __ /topic switches 
    3780 __ /switch -obj 
    3781 __ /desc Shorthand for using both /"-nolink" and /"-nolib" switches. 
    3782 __ This is literally the same has if you had placed both -nolink and 
    3783 __ -nolib on the command line. As this is a common way to just compile 
    3784 __ modules to get the object files for them, without doing anything else, 
    3785 __ a neat shorthand is available. 
    3786  
    3787 __ /topic switches 
    3788 __ /switch -nolib 
    3789 __ /desc Ensures that the object files are not used to form a library. 
    3790 __ Normally, if /i build does not find a main() or WinMain() function, 
    3791 __  it calls the librarian to create a library for all your object files. 
    3792 __ But if you use this switch, the librarian is not called. 
    3793 __ 
    3794 __ Typically, you would do this if you just wanted to create one or more 
    3795 __  object files and do nothing else. 
    3796  
    3797 __ /topic switches 
    3798 __ /switch -allobj 
    3799 __ /desc Ensures that all object files are added to a library. 
    3800 __ Normally, /i build will only create a library using the object files 
    3801 __  that are in the same directory as the new library. You would use 
    3802 __  this switch if you wanted all object files created by this build 
    3803 __ session to be included in the library. 
    3804  
    3805 __ /topic switches 
    3806 __ /switch -cleanup 
    3807 __ /desc Ensures that all working files created during the run are removed. 
    3808 __ Normally, /i build does not delete any object files or working files 
    3809 __ when it finishes a session. You can use this switch to have /i build 
    3810 __  clean up after itself. This will remove all object files created 
    3811 __  in this run, plus any .rsp, .lsp, .bak, .map, .lst, .def files. 
    3812 __ 
    3813 __  /b Note: This can also be supplied as /b"-clean" as an alias. 
    3814  
    3815 __ /topic switches 
    3816 __ /switch -LIBOPT 
    3817 __ /desc Allows commandline options to be passed to the librarian. 
    3818 __ Example: 
    3819 __ /code 
    3820 __     (Set the page size to 32Kb) 
    3821 __     -LIBOPT-p32 
    3822 __ 
    3823 __     (Embedded spaces enclosed in quotes.) 
    3824 __     "-LIBOPT -l -i" 
    3825 __ /endcode 
    3826  
    3827 __ /topic switches 
    3828 __ /switch -LIBPATH 
    3829 __ /desc Used to add a list of search paths for library files. 
    3830 __This might be used when you don't want to permanently update the 
    3831 __ standard search paths. 
    3832 __ Example: 
    3833 __ /code 
    3834 __     -LIBPATH=c:\mylibs;d:\3rdparty;c:\lib\debuglibs 
    3835 __ /endcode 
    3836  
    3837 __ /topic switches 
    3838 __ /switch -R 
    3839 __ /desc Determines if the compiler tools use a response file or not. 
    3840 __ For /i DigitalMars tools in the Windows environment, a response file is 
    3841 __  the default, but for /i other tools and other operating systems the 
    3842 __  default is to use command line arguments. 
    3843 __ 
    3844 __ The switch has three formats: /n 
    3845 __  -Ry to use a response file /n 
    3846 __  -Rn to use command line arguments /n 
    3847 __  -R to reverse the current setting. 
    3848 __ 
    3849 __ The use of a response file is only really needed when the command line 
    3850 __ arguments are going to be more than the operating system can handle 
    3851 __ on a single command line. However, it is always a safe option, so if 
    3852 __ in doubt you may as well use it. 
    3853 __ 
    3854 __ A response file contains all the arguments that would have gone on the 
    3855 __ command line. They are arranged as one argument per line. 
    3856 __ 
    3857 __ Not all tools respect the response file idea however the Windows based 
    3858 __  DigitalMars tools do understand it. 
    3859 __ 
    3860 __  Without a response file the compiler might be invoked thus: 
    3861 __ /code 
    3862 __   dmd -op -release appmain.d somemod.obj -IC:\DLibs 
    3863 __ /endcode 
    3864 __ But with a response file, these arguments are first written out to 
    3865 __ a text file (the response file) and the compiler is invoked : 
    3866 __ /code 
    3867 __   dmd @appmain.rsp 
    3868 __ /endcode 
    3869 __ The /i "appmain.rsp" would contain the lines : 
    3870 __ /code 
    3871 __   -op 
    3872 __   -release 
    3873 __   appmain.d 
    3874 __   somemod.obj 
    3875 __   -IC:\DLibs 
    3876 __ /endcode 
    3877  
    3878 __ /topic switches 
    3879 __ /switch -test 
    3880 __ /desc Does a test run only. No compiling, linking or library work is done. 
    3881 __ This will display the command lines instead of running them. It can be used 
    3882 __ to see what would happen without actually building anything. 
    3883  
    3884 __ /topic switches 
    3885 __ /switch -RDF 
    3886 __ /desc Defines a file to override the default /"Rule Definition File" 
    3887 __ The default file is called "default.rdf". If you need to provide 
    3888 __ an alternate file, you can use this switch. 
    3889 __ 
    3890 __ Example: 
    3891 __ /code 
    3892 __     -RDFmyrules.xyz 
    3893 __ /endcode 
    3894  
    3895 __ /topic switches 
    3896 __ /switch -dll 
    3897 __ /desc Forces a DLL library to be created. 
    3898 __ /b"Note:" This only applies to Windows environment. 
    3899 __ 
    3900 __ Normally, if /i build finds a DllMain() function it automatically 
    3901 __  creates a DLL library. However, if you need to force a DLL 
    3902 __  library, you would use this switch. 
    3903  
    3904 __ /topic switches 
    3905 __ /switch -gui 
    3906 __ /desc Forces a GUI application to be created. 
    3907 __ /b"Note:" This only applies to Windows environment. 
    3908 __ 
    3909 __ Normally, if /i build finds a WinMain() function it automatically 
    3910 __  creates a GUI application. However, if you need to force a GUI 
    3911 __  application, you would use this switch. 
    3912 __ 
    3913 __ This switch can also be used to specify which version of Windows to 
    3914 __  build the application for. To do this, it takes the format of 
    3915 __ -gui:X.Y where /i"X.Y" is the Windows version number. Use 4.0 
    3916 __  for Windows NT, 2000, and ME, and 5.0 for Windows XP. 
    3917 __ 
    3918 __ By default, /i build uses the version of Windows it is running under. 
    3919  
    3920 __ /topic switches 
    3921 __ /switch -info 
    3922 __ /desc Displays the version and path of the /i build application 
    3923  
    3924 __ /topic switches 
    3925 __ /switch -help 
    3926 __ /desc Displays the full text of the Usage information. 
    3927 __ This has the aliases of "-h" and "-?" 
    3928  
    3929 __ /topic switches 
    3930 __ /switch -silent 
    3931 __ /desc Prevents unnecessary messages being displayed. 
    3932 __ Some messages are just informational and under some circumstances they 
    3933 __ can interfer with reading the output. 
    3934  
    3935 __ /topic switches 
    3936 __ /switch -noautoimport 
    3937 __ /desc Prevents source file paths from being added to the list of Import Roots 
    3938 __ By default, for each source file that imports a module, it's path is added 
    3939 __ to the list of paths that will be searched for module source files. If you 
    3940 __ do not wish that behaviour, you will need to use this switch. In that case, 
    3941 __ the compiler will only search the paths specified in the compiler's 
    3942 __ configuration file, the current directory, and any explicitly added paths 
    3943 __ on the command line. 
    3944 __ 
    3945 __ Example: 
    3946 __ /code 
    3947 __      build myApp -noautoimport 
    3948 __ /endcode 
    3949  
    3950 __ /topic switches 
    3951 __ /switch -X 
    3952 __ /desc Identifies a module or package to ignore 
    3953 __ Normally, /i build assumes that all imported modules are available 
    3954 __ to be recompiled if required. You would use this switch if you explictly 
    3955 __  did not want /i build to recompile a module. 
    3956 __ 
    3957 __ /b"Note:" The /i Phobos package of modules is automatically ignored. This 
    3958 __  means that /i build does not try to recompile phobos. 
    3959 __ 
    3960 __ Example - ignore the 'parser' module (or package) 
    3961 __ /code 
    3962 __       -Xparser 
    3963 __ /endcode 
    3964  
    3965 __ /topic switches 
    3966 __ /switch -M 
    3967 __ /desc Identifies a module or a package to notice (not ignore) 
    3968 __ You would use this to name any module that is not part of the target's 
    3969 __ dependancies, or is one of the /i ignored modules. 
    3970 __ 
    3971 __ You can use this switch to recompile /i phobos. 
    3972 __ 
    3973 __ Example (notice the Phobos package): 
    3974 __ /code 
    3975 __   -Mphobos 
    3976 __ /endcode 
    3977  
    3978 __ /topic switches 
    3979 __ /switch -T 
    3980 __ /desc Identifies the target name to build. 
    3981 __ Normally, /i build derives the target name from the first file name 
    3982 __ on the command line, or from the pragma(target) if present. 
    3983 __ If however, you wish to override that, use this switch. 
    3984 __ 
    3985 __ /b"Note:" This switch allows the use of a special token, /b"{Target}", 
    3986 __ which is replaced by the default target name. You can use 
    3987 __ to create a generic /"Response File" that can be used for building 
    3988 __ any application. 
    3989 __ 
    3990 __ Example 
    3991 __ /code 
    3992 __       -Ttestapp 
    3993 __ 
    3994 __       -Ttest_(Target}  # Generate a name based on the default name. 
    3995 __ /endcode 
    3996  
    3997 __ /topic Response File 
    3998 __ /info 
    3999 __ A response file is a file that contains command line values. 
    4000 __ 
    4001 __ You can specify all or any command line values in a 
    4002 __ response file. Each value appears in its own line in the 
    4003 __ response file and you reference this file by prefixing 
    4004 __ its name with an '@' symbol on the command line. 
    4005 __ 
    4006 __ You may place comments in a response file. A comment starts 
    4007 __  with a /b'#' character and extends to the end of the line. 
    4008 __ 
    4009 __ Example: 
    4010 __ /code 
    4011 __    build @final 
    4012 __ /endcode 
    4013 __ where a file called 'final.brf' contains the command 
    4014 __ line values, including other response file references. 
    4015 __ 
    4016 __ Example: (contents of final.brf) 
    4017 __ /code 
    4018 __     # This creates a production (release) edition of the app. 
    4019 __     -T{Target}_release  # Set the name of the executable. 
    4020 __     -release   # Don't generate runtime checks. 
    4021 __     -full      # Force compilation of all files. 
    4022 __     -cleanup   # remove work files when completed 
    4023 __     -inline    # Allow inlining to occur 
    4024 __ /endcode 
    4025 __ 
    4026 __ The command line for your build could then look like ... 
    4027 __ /code 
    4028 __     build myapp @final 
    4029 __ /endcode 
    4030 __ 
    4031 __ If the response file reference is just a single '@' then 
    4032 __  build looks for a file called 'build.brf' 
    4033 __ 
    4034 __ You can any number of response file references on a command line. They 
    4035 __  are processed in the order they appear. 
    4036  
    4037  
    4038 __ /topic Configuration File 
    4039 __ /info 
    4040 __ The utility configuration file is used to specify your default options for the utility. 
    4041 __ 
    4042 __ Each option is specified in a single text line, but you can have any 
    4043 __ number of option lines in the configuration file. 
    4044 __ 
    4045 __ The options take the form of 
    4046 __ /code 
    4047 __      ~<COMMAND~>=~<VALUE~> 
    4048 __ /endcode 
    4049 __ 
    4050 __ /b"Supported Commands" /n 
    4051 __ The commands currently supported are ... /n 
    4052 __ /b CMDLINE /n 
    4053 __ You can specify all command line switch values with this configuration 
    4054 __ option. You can also specify multiple switches on the same option line./n 
    4055 __ /code 
    4056 __     CMDLINE=-inline -w 
    4057 __ /endcode 
    4058 __ 
    4059 __ /b LIBCMD /n 
    4060 __ This specifies the location and program name for the librarian application 
    4061 __ you want to invoke when creating libraries. /n 
    4062 __ /code 
    4063 __    LIBCMD=D:\Applications\dm\bin\lib.exe 
    4064 __ /endcode 
    4065 __ 
    4066 __ /b"Environment Symbol Substitution" /n 
    4067 __ Before each configuration file option line is processed, it is first checked 
    4068 __ for any references to Environment symbols. Each reference is replaced by 
    4069 __ the value of that symbol. References take the form /b"%~<SYMNAME~>%" /n 
    4070 __ There are two special symbols: /b"@D" is replaced by the compiler's 
    4071 __ path, and /b"@P" is replaced by the compiler's configuration file's path. 
    4072 __ 
    4073 __Example: Assuming you had set BUILDOPTS=-w -g 
    4074 __ /code 
    4075 __   CMDLINE=%BUILDOPTS%    # Allow switches to be passed via enviroment symbol. 
    4076 __ /endcode 
    4077 __ would mean that "-w -g" would be automatically placed on the utility's 
    4078 __ commandline whenever you ran it. 
    4079 __ 
    4080 __ /b"Groups" /n 
    4081 __ It is possible to specify groups of configuration options that are only 
    4082 __ applied if explictly nominated on the command line. A group starts with 
    4083 __ a line in the format /b"[~<groupname~>]" where /i groupname can be any 
    4084 __ text that doesn't include spaces. A group ends on the last line before the 
    4085 __ next group in the file. 
    4086 __ 
    4087 __ Example of a Group 
    4088 __ /code 
    4089 __    [dbg] # To produce a debug edition of an application. 
    4090 __    CMDLINE=-unittest 
    4091 __    CMDLINE=--release 
    4092 __    CMDLINE=--inline 
    4093 __    CMDLINE=-g 
    4094 __    CMDLINE=-w 
    4095 __    CMDLINE=-full 
    4096 __    CMDLINE=-T{Target}_{Group} 
    4097 __ /endcode 
    4098 __ 
    4099 __ All the options lines before the first group are known as the default 
    4100 __ options because these are always applied. To apply the options in a group 
    4101 __ you need to specify which group(s) you want on the command line, or via 
    4102 __ a /"response file". The group name is prepended with a plus sign on 
    4103 __ the command line. To apply the 'debug' group in the above example, you 
    4104 __ place on the command line /b"+dbg" 
    4105 __ 
    4106 __ /b"Comments" /n 
    4107 __ You may place comments in a configuration file. A comment starts 
    4108 __  with a /b'#' character and extends to the end of the line. 
    4109 __ 
    4110 __ Example: 
    4111 __ /code 
    4112 __    build myapp.d +final 
    4113 __ /endcode 
    4114 __ where if a group called '[final]' is contained in any configuration 
    4115 __ file, the options in that group are used. 
    4116 __ 
    4117 __ Example: (contents of [final]) 
    4118 __ /code 
    4119 __     # This creates a production (release) edition of the app. 
    4120 __     [final] 
    4121 __     CMDLINE=-T{Target}_{Group}  # Set the name of the executable. 
    4122 __     CMDLINE=-release   # Don't generate runtime checks. 
    4123 __     CMDLINE=-full      # Force compilation of all files. 
    4124 __     CMDLINE=-cleanup   # remove work files when completed 
    4125 __     CMDLINE=-inline    # Allow inlining to occur 
    4126 __     CMDLINE=--debug*   # Turn off any debug switches 
    4127 __     CMDLINE=--unittest # Turn off any unittest switches 
    4128 __     CMDLINE=--w        # Turn off warnings 
    4129 __     CMDLINE=--g        # Turn off embedded debug symbolic info. 
    4130 __ /endcode 
    4131 __ 
    4132 __ You can any number of configuration file group references on a command line. They 
    4133 __  are processed in the order they appear. 
    4134  
    4135 __ /topic To Do 
    4136 __ /info 
    4137 __ Ideas that have yet to be implemented. 
    4138 __ Note that some of these may never be implemented but they are still 
    4139 __ listed here as a reminder. 
    4140 __ 
    4141 __ /li Be able to update a library rather than just create libraries. 
    4142 __ /li Support the concept of a 'Plugin' block of code. /n 
    4143 __ /code 
    4144 __  version (build) pragma(plugin, ~<tool>[,delim=xxx],[, ~<parms>] ) { [body] } 
    4145 __ /endcode 
    4146 __ This block would be replaced by the stdout data of calling 'tool ~<params>' and 
    4147 __  sending it the content of ~<body> via stdin. 
    4148 __ /li Support limited preprocessor capability. /n 
    4149 __ Something like pragma(macro, ~<preprocessor commands>); and replacing 
    4150 __ source text of the form @{tokenname}@ with the value of the token. 
    4151  
    4152 __ /topic DLL Libraries 
    4153 __ /info 
    4154 __ How to create a DLL library using Build. 
    4155 __ When Build finds a DllMain() function, or the -dll switch is used, it 
    4156 __ creates a special type of Module Definition file, and sets the target to 
    4157 __ to be a DLL file. The Module Definition file generated takes the form ... 
    4158 __ /code 
    4159 __     LIBRARY "~<targetname>.dll"; 
    4160 __     EXETYPE NT 
    4161 __     SUBSYSTEM WINDOWS,~<version> 
    4162 __     CODE PRELOAD DISCARDABLE SHARED EXECUTE 
    4163 __     DATA PRELOAD SINGLE WRITE 
    4164 __ /endcode 
    4165 __ 
    4166 __ You can replace any of these by explicitly coding a pragma(/build_def) 
    4167 __ with different options than these defaults shown here. 
    4168 __ 
    4169 __ Also, if you have the program /b implib in your path, it will be run 
    4170 __ after the DLL file is created, in order to also create a /b".lib" 
    4171 __ library to interface with the DLL. Build currently supports both the 
    4172 __ DigitalMars version and the Borland (Inprise) version of /b implib. 
    4173 */ 
  • trunk/Source/build.def

    r38 r41  
    1 VERSION 2.9 
     1VERSION 2.10 
    22EXETYPE DOS 
  • trunk/Source/build.ksp

    r38 r41  
    1 -release 
    2 -inline 
    3 -op 
    4 -Iz:\d_proj\build\trunk\source\ 
    5 -Iz:\dlibs\ 
    6 -Iz:\dmd\src\phobos\ 
    7 -IZ:\D_Proj\build\trunk\Source\util\ 
     1build.obj+build_bn.obj+source.obj+source_bn.obj+util\str.obj+util\str_bn.obj+util\linetoken.obj+util\linetoken_bn.obj+util\booltype.obj+util\fdt.obj+util\fdt_bn.obj+util\pathex.obj+util\pathex_bn.obj+util\fileex.obj+util\fileex_bn.obj+util\macro.obj 
     2build.exe 
     3build.map 
     4 
    85build.def 
    9 -ofbuild.exe 
    10 util\linetoken.obj 
    11 build_bn.obj 
    12 util\pathex.obj 
    13 util\fileex.obj 
    14 util\str_bn.obj 
    15 util\macro.obj 
    16 source.obj 
    17 source_bn.obj 
    18 build.obj 
    19 util\fdt.obj 
    20 util\pathex_bn.obj 
    21 util\linetoken_bn.obj 
    22 util\str.obj 
    23 util\fdt_bn.obj 
    24 util\fileex_bn.obj 
     6/noi/map 
  • trunk/Source/build.rsp

    r38 r41  
    1 -release 
    2 -inline 
    31-op 
    4 -Iz:\d_proj\build\trunk\source\ 
    5 -Iz:\dlibs\ 
    6 -Iz:\dmd\src\phobos\ 
    7 -IZ:\D_Proj\build\trunk\Source\util\ 
    8 build.def 
    9 util\linetoken.d 
     2-Iy:\dmd\src\phobos\ 
     3-IY:\D_Proj\build\trunk\Source\ 
     4-IY:\D_Proj\build\trunk\Source\util\ 
     5build.d 
    106build_bn.d 
    11 util\pathex.d 
    12 util\fileex.d 
    13 util\str_bn.d 
    14 util\macro.d 
    157source.d 
    168source_bn.d 
    17 build.d 
     9util\str.d 
     10util\str_bn.d 
     11util\linetoken.d 
     12util\linetoken_bn.d 
     13util\booltype.d 
    1814util\fdt.d 
     15util\fdt_bn.d 
     16util\pathex.d 
    1917util\pathex_bn.d 
    20 util\linetoken_bn.d 
    21 util\str.d 
    22 util\fdt_bn.d 
     18util\fileex.d 
    2319util\fileex_bn.d 
     20util\macro.d 
  • trunk/Source/build_bn.d

    r38 r41  
    22// This file is automatically maintained by the BUILD utility, 
    33// Please refrain from manually editing it. 
    4 long auto_build_number = 1197; 
     4long auto_build_number = 1557; 
  • trunk/Source/source.d

    r38 r41  
    5151    import util.fileex; 
    5252    import util.macro; 
     53    import util.booltype; 
    5354 
    5455    import std.stdio; 
     
    9697    void function(char[] pArg) AddCompilerArg; 
    9798    char[][] function () GetImportRoots; 
    98     bool function() AutoImports; 
     99    Bool function() AutoImports; 
    99100    void function(char[] pPath) AddTarget; 
    100101    void function(char[] pPath) AddLink; 
     
    102103    void function(char[] pText, bool pReplace=false) AddBuildDef; 
    103104    char[][] function( ) ModulesToIgnore; 
    104     char[] function(char[] pFile) GetFullPathname; 
     105    char[] function(char[] pFile, char[][] pScanList = null) GetFullPathname; 
     106    char[] function(char[] pFile, int pScanList) GetFullPathnameScan; 
    105107    char[] function() GetObjWritePath; 
    106108    Substitute[] function() GetMacros; 
    107109 
    108     bool mVerboseMode = false; 
    109     bool mMacroInput = false
     110    Bool mVerboseMode; 
     111    Bool mMacroInput
    110112 
    111113} 
     
    122124    AttributeBlocks["public"] = true; 
    123125    AttributeBlocks["export"] = true; 
     126    mVerboseMode = False; 
     127    mMacroInput = False; 
    124128    debug(1) 
    125129    { 
     
    130134public class Source { 
    131135    private static Source[char[]] SourceIndex; 
     136    private static char[][] ScanOrder; 
    132137 
    133138    private { 
     
    180185 
    181186// -------------------------------------------------------------------- 
     187    static void Finalize() 
     188// -------------------------------------------------------------------- 
     189    { 
     190        for(int i = ScanOrder.length-1; i >= 0; i--) 
     191        { 
     192            Source x; 
     193            x = SourceIndex[ScanOrder[i]]; 
     194            delete x; 
     195        } 
     196    } 
     197 
     198// -------------------------------------------------------------------- 
    182199    this(char[] pFileName) 
    183200// -------------------------------------------------------------------- 
     
    187204        mReferencedImports.length = 0; 
    188205        mHasBeenSearched = false; 
    189         mNoLink = false; 
    190206        mIgnore = false; 
    191207        mFileName = pFileName; 
    192         mModuleName = FileToModulename(pFileName); 
    193         lObjectName = addExt(pFileName,ObjExt); 
    194         mObjectName = GetFullPathname(lObjectName); 
     208        if (std.path.getExt(pFileName) != "ddoc") 
     209        { 
     210            mNoLink = false; 
     211            mModuleName = FileToModulename(pFileName); 
     212            lObjectName = addExt(pFileName,ObjExt); 
     213            mObjectName = GetFullPathname(lObjectName); 
     214        } 
     215        else 
     216        { 
     217            mNoLink = true; 
     218            mModuleName = ""; 
     219            lObjectName = ""; 
     220            mObjectName = ""; 
     221        } 
    195222 
    196223        version(DigitalMars) 
     
    201228           prepend the specified object location path. 
    202229        */ 
    203         if (GetObjWritePath().length != 0
     230        if (GetObjWritePath().length != 0 && mObjectName.length != 0
    204231        { 
    205232            if (mObjectName == lObjectName) 
     
    219246        UpdateDependantTime(mObjectTime); 
    220247 
    221         if(mVerboseMode) { 
     248        if(mVerboseMode == True) { 
    222249            writefln("Time %s for %s",mFileTime.toString(),mFileName); 
    223250            writefln("Time %s for %s",mObjectTime.toString(),mObjectName); 
     
    230257    } 
    231258 
     259// -------------------------------------------------------------------- 
     260    ~this() 
     261// -------------------------------------------------------------------- 
     262    { 
     263        // writefln("Finis: %s", mFileName); 
     264    } 
     265 
     266 
     267// -------------------------------------------------------------------- 
    232268    void search() { 
     269// -------------------------------------------------------------------- 
    233270        char[] [] lFiles; 
    234271        FileDateTime lCurFileTime; 
     
    237274        char[] lFileText; 
    238275 
    239         if(mHasBeenSearched) { 
     276        if(mHasBeenSearched) 
     277        { 
    240278            return; 
    241279        } 
    242         else { 
    243         if(mVerboseMode) { 
    244           writefln("Scanning %s", util.pathex.AbbreviateFileName(mFileName)); 
    245         } 
    246  
    247         // Grab the original text. 
    248         lFileText = GetText(mFileName); 
     280 
     281        if(mVerboseMode == True) 
     282        { 
     283            writefln("Scanning %s", util.pathex.AbbreviateFileName(mFileName)); 
     284        } 
     285        ScanOrder.length = ScanOrder.length + 1; 
     286        ScanOrder[$-1] = mFileName; 
     287 
     288        // Grab the original text, which must exist. 
     289        lFileText = GetText(mFileName, GetOpt.Exists); 
    249290 
    250291        // Check if any macro processing is required. 
    251         if (mMacroInput && (std.path.getExt(mFileName) != "d")) 
     292        if ((mMacroInput == True) && (std.path.getExt(mFileName) != "d")) 
    252293        { 
    253294            if (util.macro.RunMacro(lFileText, GetMacros())) 
     
    258299                mHasBeenSearched = true; 
    259300                mIgnore = true; 
    260                 if(mVerboseMode) { 
     301                if(mVerboseMode == True) { 
    261302                  writefln("Macro output %s", lNewFile); 
    262303                } 
     
    271312        lCurFileTime = new FileDateTime(); 
    272313        // Examine each extracted module file. 
    273         if ( (mReferencedImports.length > 0) && (AutoImports() == true)) 
     314        if ( (mReferencedImports.length > 0) && (AutoImports() == True)) 
    274315        { 
    275316 
    276317            AddRoot( std.path.getDirName(util.pathex.CanonicalPath(mFileName, false)) ); 
    277318        } 
    278         foreach(char[] lNextFile; mReferencedImports) { 
     319        foreach(char[] lNextFile; mReferencedImports) 
     320        { 
    279321            if(lNextFile in SourceIndex) { 
    280322                // Known file so just grab its mod time 
     
    348390 
    349391                        if( lFindPos >= 0) { 
    350                             if (mVerboseMode
     392                            if (mVerboseMode == True
    351393                                writefln("Ignoring %s (%s: %s)", lNextFile, lType, lNextModule); 
    352394 
     
    358400                if (lCanUse){ 
    359401                    // Not known yet, so add it and grab its mod time 
    360                     lNextFile = GetFullPathname(lNextFile); 
     402                    lNextFile = GetFullPathnameScan(lNextFile, ~0); 
    361403                    lCurFileTime = (new Source(lNextFile)).DependantsTime; 
    362404                } 
     
    369411 
    370412        mHasBeenSearched = true; 
    371        
    372     } 
    373  
     413   
     414 
     415// -------------------------------------------------------------------- 
    374416    void UpdateDependantTime(FileDateTime pDateTime) 
     417// -------------------------------------------------------------------- 
    375418    { 
    376419        if (pDateTime > mDependantsTime) 
    377420        { 
    378             if (mVerboseMode
     421            if (mVerboseMode == True
    379422            { 
    380423                writefln("Updating %s dependants time from %s to %s", 
     
    397440    static void WasMainDLL(bool pValue) { mainDLL = pValue; } 
    398441 
     442// -------------------------------------------------------------------- 
    399443    bool IncrementBuildNumber() 
     444// -------------------------------------------------------------------- 
    400445    { 
    401446        char[] lFileName; 
     
    535580 
    536581        lblNextToken: 
    537         while ((lPrevToken = lCurToken.dup, lCurToken = GetNextToken (pFileText, pPos)) !is null) { 
    538  
     582        while ((lPrevToken = lCurToken.dup, lCurToken = GetNextToken (pFileText, pPos)) !is null) 
     583        { 
    539584            switch(lCurToken) { 
    540585                case kOpenBrace: 
     
    602647                    break; 
    603648 
     649                case "Ddoc": 
     650                    if (lPrevToken.length == 0) 
     651                    { 
     652                        // Only applies if 'Ddoc' is first token in file. 
     653                        mNoLink = true; 
     654                        break lblNextToken; 
     655                    } 
     656                    break; 
     657 
    604658                case "pragma": 
    605659                    doPragma(pFileText, pPos); 
     
    906960        { 
    907961            mModuleName = lModName; 
    908             if (mVerboseMode
     962            if (mVerboseMode == True
    909963            { 
    910964                writefln("Module name set to '%s'", mModuleName); 
     
    10491103                { 
    10501104                    lCurrentToken = GetNextToken(pFileText,pPos); 
    1051                     if ( (lCurrentToken == "\"") || (lCurrentToken == "`") ) { 
     1105                    if ( (lCurrentToken == "\"") || (lCurrentToken == "`") ) 
     1106                    { 
    10521107                        lCurrentToken = GetStringLit(pFileText,pPos, lCurrentToken[0]); 
    10531108                    } 
    1054                 mReferencedImports ~= ModuleToFilename(lCurrentToken); 
     1109                    else 
     1110                    { 
     1111                        char[] lLookAhead; 
     1112                        lSavedPos = pPos; 
     1113                        lLookAhead = GetNextToken(pFileText,pPos); 
     1114                        while(lLookAhead != kCloseParen) 
     1115                        {   // Append everything until we find a closing paren. 
     1116                            lCurrentToken ~= lLookAhead; 
     1117                            lSavedPos = pPos; 
     1118                            lLookAhead = GetNextToken(pFileText,pPos); 
     1119                        } 
     1120                        pPos = lSavedPos; 
     1121                    } 
     1122                    if (std.string.tolower(std.path.getExt(lCurrentToken)) == "ddoc") 
     1123                    { 
     1124                        mReferencedImports ~= lCurrentToken; 
     1125                    } 
     1126                    else 
     1127                    { 
     1128                        mReferencedImports ~= ModuleToFilename(lCurrentToken); 
     1129                    } 
    10551130                } 
    10561131 
     
    12601335    lFileName = util.str.ReplaceChar(pModuleName.dup, '.', std.path.sep[0]); 
    12611336    // Add the 'd' extention and append the full path 
    1262     lFileName = GetFullPathname( addExt( lFileName, "d" ) ); 
    1263  
    1264     if(mVerboseMode) { 
     1337    lFileName = GetFullPathnameScan( addExt( lFileName, "d" ), ~0 ); 
     1338 
     1339    if(mVerboseMode == True) { 
    12651340        writefln(" module->file %s => %s",pModuleName,lFileName); 
    12661341    } 
     
    12971372    lModuleName = util.str.ReplaceChar(lModuleName, std.path.sep[0], '.'); 
    12981373 
    1299     if(mVerboseMode) { 
     1374    if(mVerboseMode == True) { 
    13001375        writefln(" file->module %s => %s",pFileName,lModuleName); 
    13011376    } 
     
    13241399        foreach (char[] lLine; lFileLines) 
    13251400        { 
    1326             if ( util.str.IsLike(lLine, cast(dchar[])"*long auto_build_number = *;*")
     1401            if ( util.str.IsLike(lLine, cast(dchar[])"*long auto_build_number = *;*") == True
    13271402            { 
    13281403                for(int i = find(lLine,"=") + 2; i < lLine.length; i++) 
     
    14061481    version(D_InlineAsm)  ActivateVersion("D_InlineAsm"); 
    14071482 
    1408     if (mVerboseMode
     1483    if (mVerboseMode == True
    14091484        foreach(char[] k; vActiveVersions.keys){ 
    14101485            writefln("Active Version: '%s'", k); 
  • trunk/Source/source_bn.d

    r38 r41  
    22// This file is automatically maintained by the BUILD utility, 
    33// Please refrain from manually editing it. 
    4 long auto_build_number = 1049; 
     4long auto_build_number = 1409; 
  • trunk/Source/util/fdt_bn.d

    r38 r41  
    22// This file is automatically maintained by the BUILD utility, 
    33// Please refrain from manually editing it. 
    4 long auto_build_number = 815; 
     4long auto_build_number = 1175; 
  • trunk/Source/util/fileex.d

    r38 r41  
    4545    import std.path; 
    4646    import std.ctype; 
    47  
    48     debug(1) 
    49     { 
    50         import std.stdio; 
    51     } 
    52  
    53  
     47    import std.regexp; 
     48 
     49    import std.stdio; 
     50 
     51    char[][] vGrepOpts; 
    5452 
    5553} 
     
    7775{ 
    7876    char[] lFileText; 
    79  
    8077    if (std.file.exists( pFileName)) 
    8178    { 
     
    9794    char[][] lLines; 
    9895    char[]   lText; 
    99  
    10096    lText = GetText(pFileName, pOpt); 
    101     lLines = std.string.splitlines( lText ); 
     97    lLines = util.str.splitlines( lText ); 
    10298    return lLines; 
    10399} 
     100void GetTextLines(char[] pFileName, out dchar[][] pResult, GetOpt pOpt = GetOpt.Always) 
     101{ 
     102    dchar[]   lText; 
     103 
     104    lText = std.utf.toUTF32(GetText(pFileName, pOpt)); 
     105    pResult = util.str.splitlines( lText ); 
     106} 
     107 
     108void GetTextLines(char[] pFileName, out wchar[][] pResult, GetOpt pOpt = GetOpt.Always) 
     109{ 
     110    wchar[]   lText; 
     111 
     112    lText = std.utf.toUTF16(GetText(pFileName, pOpt)); 
     113    pResult = util.str.splitlines( lText ); 
     114} 
     115 
     116void GetTextLines(char[] pFileName, out char[][] pResult, GetOpt pOpt = GetOpt.Always) 
     117{ 
     118    char[]   lText; 
     119 
     120    lText = GetText(pFileName, pOpt); 
     121    pResult = util.str.splitlines( lText ); 
     122} 
     123 
    104124 
    105125enum CreateOpt 
     
    129149        for(int i = lText.length-1; i >= 0; i--) 
    130150        { 
    131             if (find(std.path.linesep, lText[i]) == -1) 
     151            if (std.string.find(std.path.linesep, lText[i]) == -1) 
    132152            { 
    133153                if (i != lText.length-1) 
     
    150170 
    151171    // Split into lines, disregarding line-end conventions. 
    152     lLines = std.string.splitlines(pLines); 
     172    lLines = util.str.splitlines(pLines); 
    153173    // Write out the text using the opsys' line-end convention. 
    154174    CreateTextFile(pFileName, lLines, pOpt); 
     175} 
     176 
     177int grep(char[] pData, char[] pPattern) 
     178{ 
     179    return std.regexp.find(pData, pPattern, vGrepOpts[$-1]); 
    155180} 
    156181 
     
    163188    auto char[] lBuffer; 
    164189    int lPos; 
     190    int lStartPos; 
    165191    ulong[] lResult; 
    166  
    167     // TODO // 
    168     // Implement options. ---------------------------------- // 
     192    int function(char[] a, char[] b) lFind; 
     193    char[] lGrepOpt; 
     194 
    169195 
    170196    lCaseSensitive = true; 
    171     if (find(pOptions, 'i') != -1) 
    172         lCaseSensitive = true; 
    173     if (find(pOptions, 'I') != -1) 
    174         lCaseSensitive = true; 
    175  
    176197    lRegExp = false; 
    177     if (find(pOptions, 'r') != -1) 
    178         lRegExp = true; 
    179     if (find(pOptions, 'R') != -1) 
    180         lRegExp = true; 
    181  
     198    lGrepOpt = "m"; 
    182199    lWordOnly = false; 
    183     if (find(pOptions, 'w') != -1) 
    184         lWordOnly = true; 
    185     if (find(pOptions, 'W') != -1) 
    186         lWordOnly = true; 
    187  
    188200    lCounting = true; 
    189     if (find(pOptions, 'a') != -1) 
    190         lCounting = false; 
    191     if (find(pOptions, 'A') != -1) 
    192         lCounting = false; 
    193  
     201    foreach (char c; pOptions) 
     202    { 
     203        switch (c) 
     204        { 
     205            case 'i', 'I': 
     206                lCaseSensitive = false; 
     207                break; 
     208 
     209            case 'r', 'R': 
     210                lRegExp = true; 
     211                break; 
     212 
     213            case 'w', 'W': 
     214                lWordOnly = true; 
     215                break; 
     216 
     217            case 'a', 'A': 
     218                lCounting = false; 
     219                break; 
     220 
     221            case 'd', 'D': 
     222                lCaseSensitive = true; 
     223                lRegExp = false; 
     224                lWordOnly = false; 
     225                lCounting = true; 
     226                break; 
     227 
     228            default: 
     229                // Ignore unrecognized options. 
     230                break; 
     231        } 
     232    } 
     233 
     234    if (lRegExp) 
     235    { 
     236        lFind = &grep; 
     237        if (lCaseSensitive) 
     238            lGrepOpt ~= 'i'; 
     239 
     240        vGrepOpts ~= lGrepOpt; 
     241        lWordOnly = false; 
     242    } 
     243    else 
     244    { 
     245        if (lCaseSensitive) 
     246            lFind = &std.string.find; 
     247        else 
     248            lFind = &std.string.ifind; 
     249    } 
     250 
     251    // Pull the entire text into RAM. 
    194252    lBuffer = cast(char[])std.file.read(pFileName); 
    195     lResult.length = 0; 
    196     lPos = 0; 
    197  
    198     while ( (lPos = find(lBuffer[lPos..$], pText)) != -1) 
    199     { 
     253 
     254    // Locate next instance and process it. 
     255    while ( lStartPos = lPos, (lPos = lFind(lBuffer[lStartPos..$], pText)) != -1) 
     256    { 
     257        lPos += lStartPos; 
    200258        if (lWordOnly) 
    201259        { 
     260            // A 'word' is an instance not surrounded by alphanumerics. 
    202261            if (lPos > 0) 
    203262            { 
    204263                if (std.ctype.isalnum(lBuffer[lPos-1]) ) 
    205264                { 
     265                    // Instance preceeded by a alphanumic so I 
     266                    // move one place to the right and try to find 
     267                    // another instance. 
    206268                    lPos++; 
    207269                    continue; 
     
    212274                if (std.ctype.isalnum(lBuffer[lPos + pText.length - 1]) ) 
    213275                { 
     276                    // Instance followed by a alphanumic so I 
     277                    // move one place to the right and try to find 
     278                    // another instance. 
    214279                    lPos++; 
    215280                    continue; 
     
    218283        } 
    219284 
    220         lResult.length = lResult.length + 1; 
    221         lResult[$-1] = lPos; 
     285        // Add this instance's position to the results list. 
     286        lResult ~= lPos; 
     287 
     288        // If I'm counting the number of hits, see if I've got the 
     289        // requested number yet. If so, stop searching. 
    222290        if (lCounting) 
    223291        { 
     
    227295        } 
    228296 
     297        // Skip over current instance. 
    229298        lPos += pText.length; 
     299 
     300        // If there is not enough characters left, then stop searching. 
    230301        if ((lBuffer.length - lPos) < pText.length) 
    231302            break; 
    232     } 
     303 
     304    } 
     305    if (vGrepOpts.length > 0) 
     306        vGrepOpts.length = vGrepOpts.length - 1; 
     307 
    233308    return lResult; 
    234309} 
  • trunk/Source/util/fileex_bn.d

    r38 r41  
    22// This file is automatically maintained by the BUILD utility, 
    33// Please refrain from manually editing it. 
    4 long auto_build_number = 758
     4long auto_build_number = 1243
  • trunk/Source/util/linetoken_bn.d

    r38 r41  
    22// This file is automatically maintained by the BUILD utility, 
    33// Please refrain from manually editing it. 
    4 long auto_build_number = 859
     4long auto_build_number = 1322
  • trunk/Source/util/pathex.d

    r38 r41  
    4646    import util.str; 
    4747    import util.fileex; 
     48    import util.booltype; 
    4849 
    4950    import std.path; 
     
    8182    lCurDir =  getcwd(); 
    8283    // Ensure that it ends in a path separator. 
    83     if (lCurDir[$-std.path.sep.le