From 56e948455fa33703a3e108faeb8e92acdc6f124e Mon Sep 17 00:00:00 2001 From: Rene Rivera Date: Fri, 3 May 2002 04:44:19 +0000 Subject: [PATCH] Slightly more functionality for print and doc. Not really working yet. [SVN r13631] --- src/util/doc.jam | 492 ++++++++++++++++++--------------------------- src/util/print.jam | 158 ++++++++++++--- 2 files changed, 322 insertions(+), 328 deletions(-) diff --git a/src/util/doc.jam b/src/util/doc.jam index 523c94f73..249667a2e 100644 --- a/src/util/doc.jam +++ b/src/util/doc.jam @@ -10,6 +10,11 @@ import modules ; import print ; +import set ; + +# List of possible modules, but which really aren't. +# +not-modules = boost-build test ; # Handle --help options, displaying or generating instructions and # documentation. If this does generate any help it exits after doing @@ -39,6 +44,7 @@ rule help ( ) help = [ MATCH --help-(.*) : $(arg) ] ; } } + #> ECHO module-name={$(module-name)} - help={$(help)} ; if ! $(module-name) { # Any help. @@ -49,55 +55,20 @@ rule help ( ) help = ; } # Only modules? - if $(help) && $(help) = modules + if $(help) && $(help) = "module" { 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 ] + local module-path = [ GLOB $(path-to-modules) : $(help)\\.jam ] ; + if $(help) && $(module-path) { - print-help-modules $(help) ; + do-scan $(module-path[1]) : print-help-module ; did-help = true ; help = ; } @@ -116,6 +87,27 @@ rule help ( ) return $(did-help) ; } +# Extracts the brief comment from a complete comment. The brief +# comment is the first sentence. +# +local rule brief-comment ( + docs + # The comment documentation. + ) +{ + local d = $(docs:J=" ") ; + local p = [ MATCH ".*([.])$" : $(d) ] ; + if ! $(p) { d = $(d)"." ; } + d = $(d)" " ; + local m = [ MATCH "^([^.]+[.])(.*)" : $(d) ] ; + local brief = $(m[1]) ; + while $(m[2]) && [ MATCH "^([^ ])" : $(m[2]) ] + { + m = [ MATCH "^([^.]+[.])(.*)" : $(m[2]) ] ; + brief += $(m[1]) ; + } + return $(brief:J="") ; +} + # Specifies the documentation for the current module. # local rule set-module-doc ( @@ -125,7 +117,7 @@ local rule set-module-doc ( { module-name ?= * ; - $(module-name).brief = [ MATCH "([^\\.]*\\.)" : $(docs:J=" ") ] ; + $(module-name).brief = [ brief-comment $(docs) ] ; $(module-name).docs = $(docs) ; if ! $(module-name) in $(documented-modules) @@ -143,7 +135,7 @@ local rule set-module-copyright ( { module-name ?= * ; - $(module-name).copy-brief = [ MATCH "([^\\.]*\\.)" : $(docs:J=" ") ] ; + $(module-name).copy-brief = [ brief-comment $(copyright) ] ; $(module-name).copy-docs = $(docs) ; if ! $(module-name) in $(documented-modules) @@ -157,13 +149,13 @@ local rule set-module-copyright ( # local rule set-rule-doc ( name # The name of the rule. - module-name ? # THe name of the module to document. + 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).brief = [ brief-comment $(docs) ] ; $(module-name).$(name).docs = $(docs) ; if ! $(name) in $($(module-name).rules) @@ -183,7 +175,7 @@ local rule set-variable-doc ( { module-name ?= * ; - $(module-name).$(name).brief = [ MATCH "([^\\.]*\\.)" : $(docs:J=" ") ] ; + $(module-name).$(name).brief = [ brief-comment $(docs) ] ; $(module-name).$(name).docs = $(docs) ; if ! $(name) in $($(module-name).variables) @@ -197,97 +189,80 @@ local rule set-variable-doc ( 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." + 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-item --help; This help message. ; + print.list-item --help-modules; Brief information on available modules. ; print.list-end ; } local rule print-help-module-section ( - module - section - : section-head - section-description ? - ) + module + section + : section-head + section-description * + ) { - if $($(module-name).$(section)) + if $($(module).$(section)) + { + print.section $(section-head) $(section-description) ; + print.list-start ; + for local item in $($(module).$(section)) + { + print.list-item '$(item)'; $($(module).$(item).brief) ; + } + print.list-end ; + } +} + +# Generate documentation for possible modules. We attempt to list all known +# modules, and a brief description of each. +# +local rule print-help-modules ( ) +{ + print.section "Modules" + "These are all the known modules. Use --help- to get more" + "detailed information." + ; + local modules-to-list = + [ set.difference + [ GLOB [ modules.peek : BOOST_BUILD_PATH ] : *.jam ] + : $(not-modules) ] ; + if $(modules-to-list) { - print.section $(section-head) $(section-description) ; print.list-start ; - for local item in $($(module-name).$(section)) + for local module-name in $(modules-to-list:B) { - print.list-item '$(item)'; $($(module-name).$(item).brief) ; + # 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 ; } } -# List of possible modules, but which really aren't. +# Generate documentation for a module. Basic information about +# the module is generated. # -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. +local rule print-help-module ( + module-name # The module 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)". to get more information." ; - - # Print out the documented variables. - print-help-module-section $(module-name) variables : "Variables" - "Use --help-"$(module-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- 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 ; - } - } + # 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). to get more information. ; + + # Print out the documented variables. + print-help-module-section $(module-name) variables : "Variables" + Use --help-$(module-name). to get more information. ; } # Extract the next document item from the given variable. The variable @@ -309,179 +284,85 @@ local rule extract-next-doc-item ( 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. +# Generate documentation for a set of rules in a module. # local rule print-help-rules ( - module ? # Optional module of the rules. + module-name # 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) = - { - 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) = - { - 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-" - "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 ; - } - } - } + name ?= $($(module-name).rules) ; + if [ set.intersection $(name) : $($(module-name).rules) ] + { + # 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) = + { + print.list-item $(doc-item[1]:G=)";" $(doc-item[2-]) ; + } + } + 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. +# Generate documentation for a set of variables in a module. # local rule print-help-variables ( - module ? # Optional module of the variables. + module-name ? # 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) = - { - 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) = - { - 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-" - "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 ; - } - } - } + name ?= $($(module-name).variables) ; + if [ set.intersection $(name) : $($(module-name).variables) ] + { + # 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) = + { + print.list-item "default value;" $(doc-item[2]) ; + } + } + print.list-end ; + } + } + } } local rule __test__ { } +ws = " " ; + local rule extract-comment ( var ) { local comment = ; local line = $($(var)[1]) ; - while [ MATCH "^[ ]*(#)" : $(line) ] && $($(var)) + while [ MATCH "^[$(ws)]*(#)" : $(line) ] && $($(var)) { - comment += [ MATCH "^[ ]*#[ ]*(.*)$" : $(line) ] ; + comment += [ MATCH "^[$(ws)]*#[$(ws)]*(.*)$" : $(line) ] ; $(var) = $($(var)[2-]) ; line = $($(var)[1]) ; } @@ -492,9 +373,9 @@ local rule extract-syntax ( var ) { local syntax = ; local line = $($(var)[1]) ; - while ! $(syntax) && ! [ MATCH "^[ ]*(#)" : $(line) ] && $($(var)) + while ! $(syntax) && ! [ MATCH "^[$(ws)]*(#)" : $(line) ] && $($(var)) { - local m = [ MATCH "^[ ]*(.*)$" : $(line) ] ; + local m = [ MATCH "^[$(ws)]*(.*)$" : $(line) ] ; if $(m) && ! $(m) = "" { syntax = $(m) ; @@ -507,10 +388,10 @@ local rule extract-syntax ( var ) rule scan-module ( target : text * ) { - ECHO -**- scan-module "(" $(1)... ")" ; - local module-name = $(.module<$(target)>) ; - ECHO " " module ==> $(module-name) ; - local module-documented = ; + #> ECHO -**- scan-module "(" $(1)... ")" ; + local module-name = $(.module<$(target)>.name) ; + #> ECHO " " module ==> $(module-name) ; + local module-documented = ; local comment-block = ; local syntax-block = ; while $(text) @@ -520,42 +401,57 @@ rule scan-module ( target : text * ) syntax-block = [ extract-syntax text ] ; #> ECHO "<>" '$(syntax-block)' ; local rule-parts = - [ MATCH "^[ ]*(rule|local[ ]*rule)[ ]+([^ ]+)[ ]*(.*)" : $(syntax-block:J=" ") ] ; + [ MATCH "^[$(ws)]*(rule|local[$(ws)]*rule)[$(ws)]+([^$(ws)]+)[$(ws)]*(.*)" : $(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) ; + local rule-name = $(rule-parts[2]) ; + local is-local = [ MATCH "^(local).*" : $(rule-parts[1]) ] ; + if $(comment-block) + { + set-rule-doc $(rule-name) $(module-name) : $(comment-block) ; #$(is-local) ; + } # parse args of rule. - ECHO [] |$(rule-parts)| ; + #> 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) ; + set-module-copyright $(module-name) : $(comment-block) ; + } + else if ! $(module-documented) + { + # document the module. + set-module-doc $(module-name) : $(comment-block) ; + module-documented = true ; } - else if ! $(module-documented) - { - # document the module. - set-module-doc $(module-name) : $(comment-block) ; - module-documented = true ; - } } - print-help-modules $(module-name) ; + #> print.output $(module-name).txt ; + for local action in $(.module<$(target)>.actions) + { + local ignored = [ $(action) $(module-name) : $(.module<$(target).action<$(action)>.arg) ] ; + } } -# HDRSCAN on [ modules.binding $(module-name) ] = "^((rule.*)|(local rule.*))$" ; - -local rule do-scan ( module-name ) +local rule do-scan ( modules + : action arg ? ) { - 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 ; + #> ECHO === $(modules) ; + local targets = ; + for local module-file in $(modules) + { + local module-name = $(module-path:B) ; + .module<$(module-file)>.name = $(module-name) ; + .module<$(module-file)>.actions += $(action) ; + .module<$(module-file)>.action<$(action)>.arg = $(arg) ; + 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) ; + targets += $(module-name).scan ; + #> ALWAYS $(module-name).txt ; + #> DEPENDS $(module-name).txt : $(module-name).scan ; + #> targets += $(module-name).txt ; + } + DEPENDS all : $(targets) ; } diff --git a/src/util/print.jam b/src/util/print.jam index eb52715eb..ce8520b0c 100644 --- a/src/util/print.jam +++ b/src/util/print.jam @@ -1,4 +1,4 @@ -# Copyright (C) Rene Rivera 2002. Permission to copy, use, modify, sell and +# 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. @@ -8,6 +8,30 @@ # and html. import modules ; +import numbers ; +import string ; + +# The current output target. Defaults to console. +output-target = console ; + +# The current output type. Defaults to plain. +output-type = plain ; + +# Set the target and type of output to generate. This sets both +# the destination output and the type of docs to generate to that +# output. The target can be either a file or "console" for echoing +# to the console. If the type of output is not specified it defaults +# to plain text. +# +rule output ( + target # The target file or device; file or "console". + type ? # The type of output; "plain", or "html". + ) +{ + type ?= plain ; + output-target = $(target) ; + output-type = $(type) ; +} # Generate a section with a description. The type of output can be # controlled by the value of the 'output-type' variable. If not set @@ -19,16 +43,14 @@ rule section ( description * # A number of description lines. ) { - local output = $(output-type) ; - output ?= console ; - if $(output) = console + if $(output-type) = plain { - ECHO $(name): ; - ECHO ; + lines $(name): ; + lines ; if $(description) { - echo-with-wordwrap " " $(description) : " " ; - ECHO ; + lines [ split-at-words " " $(description) ] : " " ; + lines ; } } } @@ -40,9 +62,7 @@ rule section ( # rule list-start ( ) { - local output = $(output-type) ; - output ?= console ; - if $(output) = console + if $(output-type) = plain { } } @@ -56,11 +76,9 @@ rule list-item ( item + # The item to list. ) { - local output = $(output-type) ; - output ?= console ; - if $(output) = console + if $(output-type) = plain { - echo-with-wordwrap "*" $(item) : " " ; + lines [ split-at-words "*" $(item) ] : " " ; } } @@ -71,31 +89,35 @@ rule list-item ( # rule list-end ( ) { - local output = $(output-type) ; - output ?= console ; - if $(output) = console + if $(output-type) = plain { - ECHO ; + lines ; } } -# Echo to console the given text word-wrapping to a 78 character margin. +# Split the given text into separate lines, word-wrapping to a margin. +# The default margin is 78 characters. # -rule echo-with-wordwrap ( - text + # The text to echo. - : indent ? # An optional indentation applied to wrapped lines. +rule split-at-words ( + text + # The text to split. + : margin ? # An optional margin, default is 78. ) { + local lines = ; text = $(text:J=" ") ; - indent ?= "" ; - local use-indent = "" ; - local char-match = - ".?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?" ; + margin ?= 78 ; + local char-match-1 = ".?" ; + local char-match = "" ; + while $(margin) != 0 + { + char-match = $(char-match)$(char-match-1) ; + margin = [ numbers.decrement $(margin) ] ; + } while $(text) { local s = "" ; local t = "" ; - # divide s into the first 78 characters and the rest + # divide s into the first X characters and the rest s = [ MATCH "^($(char-match))(.*)" : $(text) ] ; if $(s[2]) @@ -114,7 +136,83 @@ rule echo-with-wordwrap ( } text = $(t[2])$(s[2]) ; - ECHO $(use-indent)$(t[1]) ; - use-indent = $(indent) ; + lines += $(t[1]) ; + } + return $(lines) ; +} + +# Generate a set of fixed lines. Each single item passed in is +# output on a separate line. For console this just echos each line, +# but for html this will split them with
. +# +rule lines ( + text * # The lines of text. + : indent ? # Optional indentation prepended to each line after the first one. + ) +{ + text ?= " " ; + indent ?= "" ; + if $(output-type) = plain + { + text $(text[1]) $(indent)$(text[2-]) ; + } + else if $(output-type) = html + { + local indent-chars = [ string.chars $(indent) ] ; + indent = "" ; + for local c in $(indent-chars) + { + if $(c) = " " { c =   ; } + else if $(c) = " " { c =      ; } + indent = $(indent)$(c) ; + } + text $(text[1])
$(indent)$(text[2-])
; } } + +# Output text directly to the current target. +# +rule text ( + strings * # The strings of text to output. + ) +{ + if $(output-target) = console + { + while $(strings) + { + ECHO $(strings[1]) ; + strings = $(strings[2-]) ; + } + } + else if $(output-target) + { + $(output-target).line ?= 0 ; + while $(strings) + { + local line-v = $(output-target).line.$($(output-target).line) ; + $(line-v) on $(output-target) = $(strings[1]) ; + NOCARE $(line-v) ; + NOTFILE $(line-v) ; + text-action $(output-target) : $(line-v) ; + strings = $(strings[2-]) ; + $(output-target).line = [ numbers.increment $($(output-target).line) ] ; + } + } +} + +# Append single line to target file. +# +actions quietly text-action +{ + echo '$($(>))' >> $(<) +} + +local rule __test__ ( ) +{ + import assert ; + + assert.result one two three : split-at-words one two three : 5 ; + assert.result "one two" three : split-at-words one two three : 8 ; + assert.result "one two" three : split-at-words one two three : 9 ; + assert.result "one two three" : split-at-words one two three ; +}