mirror of
https://github.com/boostorg/build.git
synced 2026-02-21 15:02:19 +00:00
562 lines
17 KiB
Plaintext
562 lines
17 KiB
Plaintext
# Copyright (C) 2002, Rene Rivera. Permission to copy, use, modify, sell and
|
|
# distribute this software is granted provided this copyright notice appears in
|
|
# all copies. This software is provided "as is" without express or implied
|
|
# warranty, and with no claim as to its suitability for any purpose.
|
|
|
|
# Documentation system, handles --help requests.
|
|
# It defines rules that attach documentation to modules, rules, and variables.
|
|
# Collects and generates documentation for the various parts of the build system.
|
|
# The documentation is collected from comments integrated into the code.
|
|
|
|
import modules ;
|
|
import print ;
|
|
|
|
# Handle --help options, displaying or generating instructions and
|
|
# documentation. If this does generate any help it exits after doing
|
|
# so, to prevent any build actions from occuring.
|
|
#
|
|
rule help ( )
|
|
{
|
|
local args = [ modules.peek : ARGV ] ;
|
|
local did-help = ;
|
|
for local arg in $(args[2-])
|
|
{
|
|
local module-name = ;
|
|
local help = ;
|
|
if $(arg) = --help
|
|
{
|
|
help = _any_ ;
|
|
}
|
|
else
|
|
{
|
|
if [ MATCH --help-[^\\.]*(\\.) : $(arg) ]
|
|
{
|
|
module-name = [ MATCH --help-([^\\.]*) : $(arg) ] ;
|
|
help = [ MATCH --help-[^\\.]*\\.(.*) : $(arg) ] ;
|
|
}
|
|
else
|
|
{
|
|
help = [ MATCH --help-(.*) : $(arg) ] ;
|
|
}
|
|
}
|
|
if ! $(module-name)
|
|
{
|
|
# Any help.
|
|
if $(help) && $(help) = _any_
|
|
{
|
|
print-help-any ;
|
|
did-help = true ;
|
|
help = ;
|
|
}
|
|
# Only modules?
|
|
if $(help) && $(help) = modules
|
|
{
|
|
print-help-modules ;
|
|
did-help = true ;
|
|
help = ;
|
|
}
|
|
# Global rules?
|
|
if $(help) && $(help) = rules
|
|
{
|
|
print-help-rules ;
|
|
did-help = true ;
|
|
help = ;
|
|
}
|
|
# Global vars?
|
|
if $(help) && $(help) = variables
|
|
{
|
|
print-help-variables ;
|
|
did-help = true ;
|
|
help = ;
|
|
}
|
|
}
|
|
####
|
|
if $(help) && $(help) = scan
|
|
{
|
|
do-scan $(module-name) ;
|
|
did-help = true ;
|
|
help = ;
|
|
}
|
|
####
|
|
# Is it a variable?
|
|
if $(help) && $(help) in $($(module-name).variables)
|
|
{
|
|
print-help-variables $(module-name) : $(help) ;
|
|
did-help = true ;
|
|
help = ;
|
|
}
|
|
# Is it a rule?
|
|
if $(help) && $(help) in [ RULENAMES $(module-name) ]
|
|
{
|
|
print-help-rules $(module-name) : $(help) ;
|
|
did-help = true ;
|
|
help = ;
|
|
}
|
|
# Is it a module?
|
|
local path-to-modules = [ modules.peek : BOOST_BUILD_PATH ] ;
|
|
path-to-modules ?= . ;
|
|
if $(help) && [ GLOB $(path-to-modules) : $(help)\\.jam ]
|
|
{
|
|
print-help-modules $(help) ;
|
|
did-help = true ;
|
|
help = ;
|
|
}
|
|
# Unrecognized.
|
|
if $(help)
|
|
{
|
|
EXIT "Unrecognized help option '"$(arg)"'." ;
|
|
}
|
|
}
|
|
#> if $(did-help)
|
|
#> {
|
|
#> EXIT
|
|
#> "For more information consult the documentation at"
|
|
#> "'http://www.boost.org'." ;
|
|
#> }
|
|
return $(did-help) ;
|
|
}
|
|
|
|
# Specifies the documentation for the current module.
|
|
#
|
|
local rule set-module-doc (
|
|
module-name ? # The name of the module to document.
|
|
: docs + # The documentation for the module.
|
|
)
|
|
{
|
|
module-name ?= * ;
|
|
|
|
$(module-name).brief = [ MATCH "([^\\.]*\\.)" : $(docs:J=" ") ] ;
|
|
$(module-name).docs = $(docs) ;
|
|
|
|
if ! $(module-name) in $(documented-modules)
|
|
{
|
|
documented-modules += $(module-name) ;
|
|
}
|
|
}
|
|
|
|
# Specifies the documentation for the current module.
|
|
#
|
|
local rule set-module-copyright (
|
|
module-name ? # The name of the module to document.
|
|
: copyright + # The copyright for the module.
|
|
)
|
|
{
|
|
module-name ?= * ;
|
|
|
|
$(module-name).copy-brief = [ MATCH "([^\\.]*\\.)" : $(docs:J=" ") ] ;
|
|
$(module-name).copy-docs = $(docs) ;
|
|
|
|
if ! $(module-name) in $(documented-modules)
|
|
{
|
|
documented-modules += $(module-name) ;
|
|
}
|
|
}
|
|
|
|
# Specifies the documentation for a rule in the current module.
|
|
# If called in the global module, this documents a global rule.
|
|
#
|
|
local rule set-rule-doc (
|
|
name # The name of the rule.
|
|
module-name ? # THe name of the module to document.
|
|
: docs + # The documentation for the rule.
|
|
)
|
|
{
|
|
module-name ?= * ;
|
|
|
|
$(module-name).$(name).brief = [ MATCH "([^\\.]*\\.)" : $(docs:J=" ") ] ;
|
|
$(module-name).$(name).docs = $(docs) ;
|
|
|
|
if ! $(name) in $($(module-name).rules)
|
|
{
|
|
$(module-name).rules += $(name) ;
|
|
}
|
|
}
|
|
|
|
# Specifies the documentation for a variable in the current module.
|
|
# If called in the global module, the global variable is documented.
|
|
#
|
|
local rule set-variable-doc (
|
|
name # The name of the variable.
|
|
module-name ? # THe name of the module to document.
|
|
: docs + # The documentation for the variable.
|
|
)
|
|
{
|
|
module-name ?= * ;
|
|
|
|
$(module-name).$(name).brief = [ MATCH "([^\\.]*\\.)" : $(docs:J=" ") ] ;
|
|
$(module-name).$(name).docs = $(docs) ;
|
|
|
|
if ! $(name) in $($(module-name).variables)
|
|
{
|
|
$(module-name).variables += $(name) ;
|
|
}
|
|
}
|
|
|
|
# Generates a general description of the documentation and help system.
|
|
#
|
|
local rule print-help-any ( )
|
|
{
|
|
print.section "Available Help"
|
|
"These are the available options for obtaining documentation."
|
|
"Some options have additional instructions on how to get more"
|
|
"detailed information."
|
|
;
|
|
print.list-start ;
|
|
print.list-item --help; "This help message." ;
|
|
print.list-item --help-modules; "Brief information on available modules." ;
|
|
print.list-item --help-rules; "Brief information on global rules." ;
|
|
print.list-item --help-variables; "Brief information on global variables." ;
|
|
print.list-end ;
|
|
}
|
|
|
|
local rule print-help-module-section (
|
|
module
|
|
section
|
|
: section-head
|
|
section-description ?
|
|
)
|
|
{
|
|
if $($(module-name).$(section))
|
|
{
|
|
print.section $(section-head) $(section-description) ;
|
|
print.list-start ;
|
|
for local item in $($(module-name).$(section))
|
|
{
|
|
print.list-item '$(item)'; $($(module-name).$(item).brief) ;
|
|
}
|
|
print.list-end ;
|
|
}
|
|
}
|
|
|
|
# List of possible modules, but which really aren't.
|
|
#
|
|
not-modules = boost-build ;
|
|
|
|
# Generate documentation for a set modules. For modules that are given
|
|
# basic information about the module is generated. If no modules are given
|
|
# it attempts to list all known modules, and a brief description of each.
|
|
#
|
|
local rule print-help-modules (
|
|
modules * # Optional list of modules to generate docs for.
|
|
)
|
|
{
|
|
if $(modules)
|
|
{
|
|
# Print doc for specific modules.
|
|
#
|
|
for local module-name in $(modules)
|
|
{
|
|
# Make sure we have the docs for the module.
|
|
modules.load $(module-name) ;
|
|
|
|
# Print the docs.
|
|
print.section "'"$(module-name)"'" $($(module-name).docs) ;
|
|
|
|
# Print out the documented rules.
|
|
print-help-module-section $(module-name) rules : "Rules"
|
|
"Use --help-"$(module-name)".<rule-name> to get more information." ;
|
|
|
|
# Print out the documented variables.
|
|
print-help-module-section $(module-name) variables : "Variables"
|
|
"Use --help-"$(module-name)".<variable-name> to get more information." ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
# No specific modules to doc, try to load and list them all.
|
|
#
|
|
print.section "Modules"
|
|
"These are all the known modules. Use --help-<module> to get more"
|
|
"detailed information."
|
|
;
|
|
local modules-to-list =
|
|
[ GLOB [ modules.peek : BOOST_BUILD_PATH ] : *.jam ] ;
|
|
if $(modules-to-list)
|
|
{
|
|
print.list-start ;
|
|
for local module-name in $(modules-to-list:B)
|
|
{
|
|
if ! $(module-name) in $(not-modules)
|
|
{
|
|
# Make sure we have the docs for the module.
|
|
modules.load $(module-name) ;
|
|
|
|
# The brief docs for each module.
|
|
print.list-item "'"$(module-name)"';" $($(module-name).brief) ;
|
|
}
|
|
}
|
|
print.list-end ;
|
|
}
|
|
}
|
|
}
|
|
|
|
# Extract the next document item from the given variable. The variable
|
|
# is changed to no longer contain that next item which is returned as
|
|
# the result. The next item is considered anything up to, but not
|
|
# including, the next gristed element.
|
|
#
|
|
local rule extract-next-doc-item (
|
|
var # The name of the variable to extract from.
|
|
)
|
|
{
|
|
local doc-item = $($(var)[1]) ;
|
|
$(var) = $($(var)[2-]) ;
|
|
while $($(var)) && ! $($(var)[1]:G)
|
|
{
|
|
doc-item += $($(var)[1]) ;
|
|
$(var) = $($(var)[2-]) ;
|
|
}
|
|
return $(doc-item) ;
|
|
}
|
|
|
|
# Generate documentation for a set of rules, either in a module or global.
|
|
# If no module is given, the given rules of the global scope are documented.
|
|
#
|
|
local rule print-help-rules (
|
|
module ? # Optional module of the rules.
|
|
: name * # Optional list of rules to describe.
|
|
)
|
|
{
|
|
if $(module)
|
|
{
|
|
# Make sure we have the docs for the module.
|
|
modules.load $(module) ;
|
|
|
|
if $(name)
|
|
{
|
|
# Print out the given rules.
|
|
for local rule-name in $(name)
|
|
{
|
|
local docs = $($(module).$(rule-name).docs) ;
|
|
print.section "'"$(module).$(rule-name)"'"
|
|
[ extract-next-doc-item docs ] ;
|
|
if $(docs)
|
|
{
|
|
print.list-start ;
|
|
while $(docs)
|
|
{
|
|
local doc-item = [ extract-next-doc-item docs ] ;
|
|
if $(doc-item[1]:G) = <argument>
|
|
{
|
|
print.list-item $(doc-item[1]:G=)";" $(doc-item[2-]) ;
|
|
}
|
|
}
|
|
print.list-end ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if $(name)
|
|
{
|
|
# Print out the given global rules.
|
|
for local rule-name in $(name)
|
|
{
|
|
local docs = $(*.$(rule-name).docs) ;
|
|
print.section "'"$(rule-name)"'"
|
|
[ extract-next-doc-item docs ] ;
|
|
if $(docs)
|
|
{
|
|
print.list-start ;
|
|
while $(docs)
|
|
{
|
|
local doc-item = [ extract-next-doc-item docs ] ;
|
|
if $(doc-item[1]:G) = <argument>
|
|
{
|
|
print.list-item $(doc-item[1]:G=)";" $(doc-item[2-]) ;
|
|
}
|
|
}
|
|
print.list-end ;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if $(*.rules)
|
|
{
|
|
# Print out all the known global rules.
|
|
print.section "Global rules"
|
|
"These are all the documented global rules. Use --help-<rule-name>"
|
|
"to obtain more detailed information." ;
|
|
print.list-start ;
|
|
for local rule-name in $(*.rules)
|
|
{
|
|
print.list-item "'"$(rule-name)"';" $(*.$(rule-name).brief) ;
|
|
}
|
|
print.list-end ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# Generate documentation for a set of variables, either in a module or global.
|
|
# If no module is given, the given variables of the global scope are documented.
|
|
#
|
|
local rule print-help-variables (
|
|
module ? # Optional module of the variables.
|
|
: name * # Optional list of variables to describe.
|
|
)
|
|
{
|
|
if $(module)
|
|
{
|
|
# Make sure we have the docs for the module.
|
|
modules.load $(module) ;
|
|
|
|
if $(name)
|
|
{
|
|
# Print out the given variables.
|
|
for local variable-name in $(name)
|
|
{
|
|
local docs = $($(module).$(variable-name).docs) ;
|
|
print.section "'"$(module).$(variable-name)"'"
|
|
[ extract-next-doc-item docs ] ;
|
|
if $(docs)
|
|
{
|
|
print.list-start ;
|
|
while $(docs)
|
|
{
|
|
local doc-item = [ extract-next-doc-item docs ] ;
|
|
if $(doc-item[1]:G) = <default-value>
|
|
{
|
|
print.list-item "default value;" $(doc-item[2]) ;
|
|
}
|
|
}
|
|
print.list-end ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if $(name)
|
|
{
|
|
# Print out the given global variables.
|
|
for local variable-name in $(name)
|
|
{
|
|
local docs = $(*.$(variable-name).docs) ;
|
|
print.section "'"$(variable-name)"'"
|
|
[ extract-next-doc-item docs ] ;
|
|
if $(docs)
|
|
{
|
|
print.list-start ;
|
|
while $(docs)
|
|
{
|
|
local doc-item = [ extract-next-doc-item docs ] ;
|
|
if $(doc-item[1]:G) = <default-value>
|
|
{
|
|
print.list-item "default value;" $(doc-item[2]) ;
|
|
}
|
|
}
|
|
print.list-end ;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if $(*.variables)
|
|
{
|
|
# Print out all the known global variables.
|
|
print.section "Global variables"
|
|
"These are all the documented global variables. Use --help-<variable-name>"
|
|
"to obtain more detailed information." ;
|
|
print.list-start ;
|
|
for local variable-name in $(*.variables)
|
|
{
|
|
print.list-item "'"$(variable-name)"';" $(*.$(variable-name).brief) ;
|
|
}
|
|
print.list-end ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
local rule __test__
|
|
{
|
|
}
|
|
|
|
local rule extract-comment ( var )
|
|
{
|
|
local comment = ;
|
|
local line = $($(var)[1]) ;
|
|
while [ MATCH "^[ ]*(#)" : $(line) ] && $($(var))
|
|
{
|
|
comment += [ MATCH "^[ ]*#[ ]*(.*)$" : $(line) ] ;
|
|
$(var) = $($(var)[2-]) ;
|
|
line = $($(var)[1]) ;
|
|
}
|
|
return $(comment) ;
|
|
}
|
|
|
|
local rule extract-syntax ( var )
|
|
{
|
|
local syntax = ;
|
|
local line = $($(var)[1]) ;
|
|
while ! $(syntax) && ! [ MATCH "^[ ]*(#)" : $(line) ] && $($(var))
|
|
{
|
|
local m = [ MATCH "^[ ]*(.*)$" : $(line) ] ;
|
|
if $(m) && ! $(m) = ""
|
|
{
|
|
syntax = $(m) ;
|
|
}
|
|
$(var) = $($(var)[2-]) ;
|
|
line = $($(var)[1]) ;
|
|
}
|
|
return $(syntax) ;
|
|
}
|
|
|
|
rule scan-module ( target : text * )
|
|
{
|
|
ECHO -**- scan-module "(" $(1)... ")" ;
|
|
local module-name = $(.module<$(target)>) ;
|
|
ECHO " " module ==> $(module-name) ;
|
|
local module-documented = ;
|
|
local comment-block = ;
|
|
local syntax-block = ;
|
|
while $(text)
|
|
{
|
|
comment-block = [ extract-comment text ] ;
|
|
#> ECHO "##" '$(comment-block)' ;
|
|
syntax-block = [ extract-syntax text ] ;
|
|
#> ECHO "<>" '$(syntax-block)' ;
|
|
local rule-parts =
|
|
[ MATCH "^[ ]*(rule|local[ ]*rule)[ ]+([^ ]+)[ ]*(.*)" : $(syntax-block:J=" ") ] ;
|
|
if $(rule-parts[2])
|
|
{
|
|
# mark as doc for rule.
|
|
local rule-name = $(rule-parts[2]) ;
|
|
local is-local = [ MATCH "^(local).*" : $(rule-parts[1]) ] ;
|
|
set-rule-doc $(rule-name) $(module-name) : $(comment-block) <is-local>$(is-local) ;
|
|
# parse args of rule.
|
|
ECHO [] |$(rule-parts)| ;
|
|
}
|
|
else if [ MATCH .*([cC]opyright).* : $(comment-block:J=" ") ]
|
|
{
|
|
# mark as the copy for the module.
|
|
set-module-copyright $(module-name) : $(comment-block) ;
|
|
}
|
|
else if ! $(module-documented)
|
|
{
|
|
# document the module.
|
|
set-module-doc $(module-name) : $(comment-block) ;
|
|
module-documented = true ;
|
|
}
|
|
}
|
|
print-help-modules $(module-name) ;
|
|
}
|
|
|
|
# HDRSCAN on [ modules.binding $(module-name) ] = "^((rule.*)|(local rule.*))$" ;
|
|
|
|
local rule do-scan ( module-name )
|
|
{
|
|
modules.load $(module-name) ;
|
|
local module-file = [ modules.binding $(module-name) ] ;
|
|
.module<$(module-file)> = $(module-name) ;
|
|
HDRSCAN on $(module-file) = "^(.*).$" ;
|
|
HDRRULE on $(module-file) = doc.scan-module ;
|
|
NOTFILE $(module-name).scan ;
|
|
ALWAYS $(module-name).scan ;
|
|
INCLUDES $(module-name).scan : $(module-file) ;
|
|
DEPENDS all : $(module-name).scan ;
|
|
}
|