1# Copyright 2003 Dave Abrahams 2# Copyright 2003, 2006 Rene Rivera 3# Copyright 2003, 2006 Vladimir Prus 4# Distributed under the Boost Software License, Version 1.0. 5# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) 6 7# This module is the plug-in handler for the --help and --help-.* 8# command-line options 9import modules ; 10import assert ; 11import doc : do-scan set-option set-output set-output-file print-help-usage print-help-top ; 12import sequence ; 13import set ; 14import project ; 15import print ; 16import os ; 17import version ; 18import path ; 19 20# List of possible modules, but which really aren't. 21# 22.not-modules = 23 boost-build bootstrap site-config test user-config 24 -tools allyourbase boost-base features python stlport testing unit-tests ; 25 26# The help system options are parsed here and handed off to the doc 27# module to translate into documentation requests and actions. The 28# understood options are: 29# 30# --help-disable-<option> 31# --help-doc-options 32# --help-enable-<option> 33# --help-internal 34# --help-options 35# --help-usage 36# --help-output <type> 37# --help-output-file <file> 38# --help [<module-or-class>] 39# 40rule process ( 41 command # The option. 42 : values * # The values, starting after the "=". 43 ) 44{ 45 assert.result --help : MATCH ^(--help).* : $(command) ; 46 local did-help = ; 47 switch $(command) 48 { 49 case --help-internal : 50 local path-to-modules = [ modules.peek : BOOST_BUILD_PATH ] ; 51 path-to-modules += . ; 52 local possible-modules = [ GLOB $(path-to-modules) : *\\.jam ] ; 53 local not-modules = [ GLOB $(path-to-modules) : *$(.not-modules)\\.jam ] ; 54 local modules-to-list = 55 [ sequence.insertion-sort 56 [ set.difference $(possible-modules:D=:S=) : $(not-modules:D=:S=) ] ] ; 57 local modules-to-scan ; 58 for local m in $(modules-to-list) 59 { 60 local module-files = [ GLOB $(path-to-modules) : $(m)\\.jam ] ; 61 modules-to-scan += $(module-files[1]) ; 62 } 63 do-scan $(modules-to-scan) : print-help-all ; 64 did-help = true ; 65 66 case --help-enable-* : 67 local option = [ MATCH --help-enable-(.*) : $(command) ] ; option = $(option:L) ; 68 set-option $(option) : enabled ; 69 did-help = true ; 70 71 case --help-disable-* : 72 local option = [ MATCH --help-disable-(.*) : $(command) ] ; option = $(option:L) ; 73 set-option $(option) ; 74 did-help = true ; 75 76 case --help-output : 77 set-output $(values[1]) ; 78 did-help = true ; 79 80 case --help-output-file : 81 set-output-file $(values[1]) ; 82 did-help = true ; 83 84 case --help-doc-options : 85 local doc-module-spec = [ split-symbol doc ] ; 86 do-scan $(doc-module-spec[1]) : print-help-options ; 87 did-help = true ; 88 89 case --help-options : 90 print-help-usage ; 91 local BOOST_BUILD_PATH = [ modules.peek : BOOST_BUILD_PATH ] ; 92 local plugin-dir = options ; 93 local option-files = [ GLOB $(plugin-dir:D=$(BOOST_BUILD_PATH)) : *.jam ] ; 94 if $(option-files) 95 { 96 for local file in $(option-files) 97 { 98 do-scan $(file) : print-help-options ; 99 } 100 } 101 did-help = true ; 102 103 case --help : 104 local spec = $(values[1]) ; 105 if $(spec) 106 { 107 local spec-parts = [ split-symbol $(spec) ] ; 108 if $(spec-parts) 109 { 110 if $(spec-parts[2]) 111 { 112 do-scan $(spec-parts[1]) : print-help-classes $(spec-parts[2]) ; 113 do-scan $(spec-parts[1]) : print-help-rules $(spec-parts[2]) ; 114 do-scan $(spec-parts[1]) : print-help-variables $(spec-parts[2]) ; 115 } 116 else 117 { 118 do-scan $(spec-parts[1]) : print-help-module ; 119 } 120 } 121 else 122 { 123 EXIT "Unrecognized help option '"$(command)" "$(spec)"'." ; 124 } 125 } 126 else 127 { 128 version.print ; 129 ECHO ; 130 # First print documentation from the current Jamfile, if any. 131 # FIXME: Generally, this duplication of project.jam logic is bad. 132 local names = [ modules.peek project : JAMROOT ] 133 [ modules.peek project : JAMFILE ] ; 134 local project-file = [ path.glob . : $(names) ] ; 135 if ! $(project-file) 136 { 137 project-file = [ path.glob-in-parents . : $(names) ] ; 138 } 139 140 for local p in $(project-file) 141 { 142 do-scan $(p) : print-help-project $(p) ; 143 } 144 145 # Next any user-config help. 146 local user-path = [ os.home-directories ] [ os.environ BOOST_BUILD_PATH ] ; 147 local user-config = [ GLOB $(user-path) : user-config.jam ] ; 148 if $(user-config) 149 { 150 do-scan $(user-config[1]) : print-help-config user $(user-config[1]) ; 151 } 152 153 # Next any site-config help. 154 local site-config = [ GLOB $(user-path) : site-config.jam ] ; 155 if $(site-config) 156 { 157 do-scan $(site-config[1]) : print-help-config site $(site-config[1]) ; 158 } 159 160 # Then the overall help. 161 print-help-top ; 162 } 163 did-help = true ; 164 } 165 if $(did-help) 166 { 167 UPDATE all ; 168 NOCARE all ; 169 } 170 return $(did-help) ; 171} 172 173# Split a reference to a symbol into module and symbol parts. 174# 175local rule split-symbol ( 176 symbol # The symbol to split. 177 ) 178{ 179 local path-to-modules = [ modules.peek : BOOST_BUILD_PATH ] ; 180 path-to-modules += . ; 181 local module-name = $(symbol) ; 182 local symbol-name = ; 183 local result = ; 184 while ! $(result) 185 { 186 local module-path = [ GLOB $(path-to-modules) : $(module-name)\\.jam ] ; 187 if $(module-path) 188 { 189 # The 'module-name' in fact refers to module. Return the full 190 # module path and a symbol within it. If 'symbol' passed to this 191 # rule is already module, 'symbol-name' will be empty. Otherwise, 192 # it's initialized on the previous loop iteration. 193 # In case there are several modules by this name, 194 # use the first one. 195 result = $(module-path[1]) $(symbol-name) ; 196 } 197 else 198 { 199 if ! $(module-name:S) 200 { 201 result = - ; 202 } 203 else 204 { 205 local next-symbol-part = [ MATCH ^.(.*) : $(module-name:S) ] ; 206 if $(symbol-name) 207 { 208 symbol-name = $(next-symbol-part).$(symbol-name) ; 209 } 210 else 211 { 212 symbol-name = $(next-symbol-part) ; 213 } 214 module-name = $(module-name:B) ; 215 } 216 } 217 } 218 if $(result) != - 219 { 220 return $(result) ; 221 } 222} 223