2019-02-04 22:26:45 +00:00
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
< html >
< head >
< title > 2/tr< / title >
< meta http-equiv = "Content-Type" content = "text/html; charset=utf-8" >
< meta http-equiv = "Content-Language" content = "en-gb" >
< link href = "inweb.css" rel = "stylesheet" rev = "stylesheet" type = "text/css" >
< / head >
< body >
2019-02-09 12:33:40 +00:00
<!-- Weave of '2/mdl' generated by 7 -->
2019-02-04 22:26:45 +00:00
< ul class = "crumbs" > < li > < a href = "../webs.html" > ★ < / a > < / li > < li > < a href = "index.html" > inweb 7< / a > < / li > < li > < a href = "index.html#2" > Chapter 2: Parsing a Web< / a > < / li > < li > < b > Modules< / b > < / li > < / ul > < p class = "purpose" > To search for included modules, and track dependencies between them.< / p >
< ul class = "toc" > < li > < a href = "#SP1" > § 1. Creation< / a > < / li > < li > < a href = "#SP4" > § 4. Dependencies< / a > < / li > < li > < a href = "#SP5" > § 5. Searching< / a > < / li > < / ul > < hr class = "tocbar" >
< p class = "inwebparagraph" > < a id = "SP1" > < / a > < b > § 1. Creation. < / b > Each web of source material discovered by Inweb is given one of the following.
Ordinarily these are found only when reading in a web for weaving, tangling
and so on: in the vast majority of Inweb runs, all modules will have the
"module origin marker" < code class = "display" > < span class = "extract" > READING_WEB_MOM< / span > < / code > . But when Inweb is constructing a
makefile for a suite of tools, it can also discover multiple webs by other
means.
< / p >
< pre class = "definitions" >
< span class = "definitionkeyword" > enum< / span > < span class = "constant" > READING_WEB_MOM< / span > < span class = "definitionkeyword" > from < / span > < span class = "constant" > 0< / span >
< span class = "definitionkeyword" > enum< / span > < span class = "constant" > MAKEFILE_TOOL_MOM< / span >
< span class = "definitionkeyword" > enum< / span > < span class = "constant" > MAKEFILE_MODULE_MOM< / span >
< / pre >
< pre class = "display" >
< span class = "reserved" > typedef< / span > < span class = "plain" > < / span > < span class = "reserved" > struct< / span > < span class = "plain" > < / span > < span class = "reserved" > module< / span > < span class = "plain" > {< / span >
< span class = "reserved" > struct< / span > < span class = "plain" > < / span > < span class = "reserved" > pathname< / span > < span class = "plain" > *< / span > < span class = "identifier" > module_location< / span > < span class = "plain" > ;< / span >
< span class = "reserved" > struct< / span > < span class = "plain" > < / span > < span class = "reserved" > text_stream< / span > < span class = "plain" > *< / span > < span class = "identifier" > module_name< / span > < span class = "plain" > ;< / span >
< span class = "reserved" > struct< / span > < span class = "plain" > < / span > < span class = "reserved" > linked_list< / span > < span class = "plain" > *< / span > < span class = "identifier" > dependencies< / span > < span class = "plain" > ; < / span > < span class = "comment" > of < code class = "display" > < span class = "extract" > module< / span > < / code > : which other modules does this need?< / span >
< span class = "reserved" > int< / span > < span class = "plain" > < / span > < span class = "identifier" > origin_marker< / span > < span class = "plain" > ; < / span > < span class = "comment" > one of the < code class = "display" > < span class = "extract" > *_MOM< / span > < / code > values above< / span >
< span class = "constant" > MEMORY_MANAGEMENT< / span >
< span class = "plain" > } < / span > < span class = "reserved" > module< / span > < span class = "plain" > ;< / span >
< / pre >
< p class = "inwebparagraph" > < / p >
< p class = "endnote" > The structure module is accessed in 6/mkf and here.< / p >
< p class = "inwebparagraph" > < a id = "SP2" > < / a > < b > § 2. < / b > < / p >
< pre class = "display" >
< span class = "reserved" > module< / span > < span class = "plain" > *< / span > < span class = "functiontext" > Modules::new< / span > < span class = "plain" > (< / span > < span class = "reserved" > text_stream< / span > < span class = "plain" > *< / span > < span class = "identifier" > name< / span > < span class = "plain" > , < / span > < span class = "reserved" > pathname< / span > < span class = "plain" > *< / span > < span class = "identifier" > at< / span > < span class = "plain" > , < / span > < span class = "reserved" > int< / span > < span class = "plain" > < / span > < span class = "identifier" > m< / span > < span class = "plain" > ) {< / span >
< span class = "reserved" > module< / span > < span class = "plain" > *< / span > < span class = "identifier" > M< / span > < span class = "plain" > = < / span > < span class = "identifier" > CREATE< / span > < span class = "plain" > (< / span > < span class = "reserved" > module< / span > < span class = "plain" > );< / span >
< span class = "identifier" > M< / span > < span class = "plain" > -< / span > < span class = "element" > > module_location< / span > < span class = "plain" > = < / span > < span class = "identifier" > at< / span > < span class = "plain" > ;< / span >
< span class = "identifier" > M< / span > < span class = "plain" > -< / span > < span class = "element" > > module_name< / span > < span class = "plain" > = < / span > < span class = "functiontext" > Str::duplicate< / span > < span class = "plain" > (< / span > < span class = "identifier" > name< / span > < span class = "plain" > );< / span >
< span class = "identifier" > M< / span > < span class = "plain" > -< / span > < span class = "element" > > dependencies< / span > < span class = "plain" > = < / span > < span class = "identifier" > NEW_LINKED_LIST< / span > < span class = "plain" > (< / span > < span class = "reserved" > module< / span > < span class = "plain" > );< / span >
< span class = "identifier" > M< / span > < span class = "plain" > -< / span > < span class = "element" > > origin_marker< / span > < span class = "plain" > = < / span > < span class = "identifier" > m< / span > < span class = "plain" > ;< / span >
< span class = "reserved" > return< / span > < span class = "plain" > < / span > < span class = "identifier" > M< / span > < span class = "plain" > ;< / span >
< span class = "plain" > }< / span >
< / pre >
< p class = "inwebparagraph" > < / p >
< p class = "endnote" > The function Modules::new is used in < a href = "#SP3" > § 3< / a > , < a href = "#SP7_1" > § 7.1< / a > , 6/mkf (< a href = "6-mkf.html#SP2_7" > § 2.7< / a > , < a href = "6-mkf.html#SP2_8" > § 2.8< / a > ).< / p >
< p class = "inwebparagraph" > < a id = "SP3" > < / a > < b > § 3. < / b > In the Inweb documentation, "module" is used to refer to a sidekick web which
contains a suite of utility routines, or a major component of a program, but
which is not a program in its own right.
< / p >
< p class = "inwebparagraph" > Internally, though, every web produces a < code class = "display" > < span class = "extract" > module< / span > < / code > structure. The one for the
main web — which can be tangled, and results in an actual program — is
internally named < code class = "display" > < span class = "extract" > "(main)"< / span > < / code > , a name which the user will never see.
< / p >
< pre class = "display" >
< span class = "reserved" > module< / span > < span class = "plain" > *< / span > < span class = "functiontext" > Modules::main_module< / span > < span class = "plain" > (< / span > < span class = "reserved" > web< / span > < span class = "plain" > *< / span > < span class = "identifier" > W< / span > < span class = "plain" > ) {< / span >
< span class = "reserved" > return< / span > < span class = "plain" > < / span > < span class = "functiontext" > Modules::new< / span > < span class = "plain" > (< / span > < span class = "identifier" > I< / span > < span class = "string" > "(main)"< / span > < span class = "plain" > , < / span > < span class = "identifier" > W< / span > < span class = "plain" > -< / span > < span class = "element" > > path_to_web< / span > < span class = "plain" > , < / span > < span class = "constant" > READING_WEB_MOM< / span > < span class = "plain" > );< / span >
< span class = "plain" > }< / span >
< / pre >
< p class = "inwebparagraph" > < / p >
< p class = "endnote" > The function Modules::main_module is used in 2/tr (< a href = "2-tr.html#SP2" > § 2< / a > ).< / p >
< p class = "inwebparagraph" > < a id = "SP4" > < / a > < b > § 4. Dependencies. < / b > When web A imports module B, we will say that A is dependent on B. A web
can import multiple modules, so there can a list of dependencies. These are
needed when constructing makefiles, since the source code in B affects the
program generated by A.
< / p >
< pre class = "display" >
< span class = "reserved" > void< / span > < span class = "plain" > < / span > < span class = "functiontext" > Modules::dependency< / span > < span class = "plain" > (< / span > < span class = "reserved" > module< / span > < span class = "plain" > *< / span > < span class = "identifier" > A< / span > < span class = "plain" > , < / span > < span class = "reserved" > module< / span > < span class = "plain" > *< / span > < span class = "identifier" > B< / span > < span class = "plain" > ) {< / span >
< span class = "reserved" > if< / span > < span class = "plain" > ((< / span > < span class = "identifier" > A< / span > < span class = "plain" > == < / span > < span class = "identifier" > NULL< / span > < span class = "plain" > ) || (< / span > < span class = "identifier" > B< / span > < span class = "plain" > == < / span > < span class = "identifier" > NULL< / span > < span class = "plain" > )) < / span > < span class = "identifier" > internal_error< / span > < span class = "plain" > (< / span > < span class = "string" > "no module"< / span > < span class = "plain" > );< / span >
< span class = "identifier" > ADD_TO_LINKED_LIST< / span > < span class = "plain" > (< / span > < span class = "identifier" > B< / span > < span class = "plain" > , < / span > < span class = "reserved" > module< / span > < span class = "plain" > , < / span > < span class = "identifier" > A< / span > < span class = "plain" > -< / span > < span class = "element" > > dependencies< / span > < span class = "plain" > );< / span >
< span class = "plain" > }< / span >
< / pre >
< p class = "inwebparagraph" > < / p >
< p class = "endnote" > The function Modules::dependency is used in < a href = "#SP7_1" > § 7.1< / a > , 6/mkf (< a href = "6-mkf.html#SP2_9" > § 2.9< / a > ).< / p >
< p class = "inwebparagraph" > < a id = "SP5" > < / a > < b > § 5. Searching. < / b > The following abstracts the idea of a place where modules might be found.
(At one time there was going to be a more elaborate search hierarchy.)
< / p >
< pre class = "display" >
< span class = "reserved" > typedef< / span > < span class = "plain" > < / span > < span class = "reserved" > struct< / span > < span class = "plain" > < / span > < span class = "reserved" > module_search< / span > < span class = "plain" > {< / span >
< span class = "reserved" > struct< / span > < span class = "plain" > < / span > < span class = "reserved" > pathname< / span > < span class = "plain" > *< / span > < span class = "identifier" > path_to_search< / span > < span class = "plain" > ;< / span >
< span class = "constant" > MEMORY_MANAGEMENT< / span >
< span class = "plain" > } < / span > < span class = "reserved" > module_search< / span > < span class = "plain" > ;< / span >
< / pre >
< p class = "inwebparagraph" > < / p >
< p class = "endnote" > The structure module_search is private to this section.< / p >
< p class = "inwebparagraph" > < a id = "SP6" > < / a > < b > § 6. < / b > < / p >
< pre class = "display" >
< span class = "reserved" > module_search< / span > < span class = "plain" > *< / span > < span class = "functiontext" > Modules::make_search_path< / span > < span class = "plain" > (< / span > < span class = "reserved" > pathname< / span > < span class = "plain" > *< / span > < span class = "identifier" > ext_path< / span > < span class = "plain" > ) {< / span >
< span class = "reserved" > module_search< / span > < span class = "plain" > *< / span > < span class = "identifier" > ms< / span > < span class = "plain" > = < / span > < span class = "identifier" > CREATE< / span > < span class = "plain" > (< / span > < span class = "reserved" > module_search< / span > < span class = "plain" > );< / span >
< span class = "identifier" > ms< / span > < span class = "plain" > -< / span > < span class = "element" > > path_to_search< / span > < span class = "plain" > = < / span > < span class = "identifier" > ext_path< / span > < span class = "plain" > ;< / span >
< span class = "reserved" > return< / span > < span class = "plain" > < / span > < span class = "identifier" > ms< / span > < span class = "plain" > ;< / span >
< span class = "plain" > }< / span >
< / pre >
< p class = "inwebparagraph" > < / p >
2019-03-12 23:32:12 +00:00
< p class = "endnote" > The function Modules::make_search_path is used in 1/pc (< a href = "1-pc.html#SP7" > § 7< / a > ).< / p >
2019-02-04 22:26:45 +00:00
< p class = "inwebparagraph" > < a id = "SP7" > < / a > < b > § 7. < / b > When a web's contents page says to < code class = "display" > < span class = "extract" > import Blah< / span > < / code > , how do we find the module
called < code class = "display" > < span class = "extract" > Blah< / span > < / code > on disc? We try four possibilities in sequence:
< / p >
< pre class = "display" >
< span class = "reserved" > pathname< / span > < span class = "plain" > *< / span > < span class = "functiontext" > Modules::find< / span > < span class = "plain" > (< / span > < span class = "reserved" > web< / span > < span class = "plain" > *< / span > < span class = "identifier" > W< / span > < span class = "plain" > , < / span > < span class = "reserved" > module_search< / span > < span class = "plain" > *< / span > < span class = "identifier" > ms< / span > < span class = "plain" > , < / span > < span class = "reserved" > text_stream< / span > < span class = "plain" > *< / span > < span class = "identifier" > name< / span > < span class = "plain" > ) {< / span >
< span class = "reserved" > pathname< / span > < span class = "plain" > *< / span > < span class = "identifier" > tries< / span > < span class = "plain" > [4];< / span >
< span class = "identifier" > tries< / span > < span class = "plain" > [0] = < / span > < span class = "identifier" > W< / span > < span class = "plain" > ?(< / span > < span class = "identifier" > W< / span > < span class = "plain" > -< / span > < span class = "element" > > path_to_web< / span > < span class = "plain" > ):< / span > < span class = "identifier" > NULL< / span > < span class = "plain" > ;< / span >
< span class = "identifier" > tries< / span > < span class = "plain" > [1] = < / span > < span class = "functiontext" > Pathnames::up< / span > < span class = "plain" > (< / span > < span class = "identifier" > tries< / span > < span class = "plain" > [0]);< / span >
2019-03-12 23:32:12 +00:00
< span class = "identifier" > tries< / span > < span class = "plain" > [2] = < / span > < span class = "identifier" > path_to_inweb< / span > < span class = "plain" > ;< / span >
2019-02-04 22:26:45 +00:00
< span class = "identifier" > tries< / span > < span class = "plain" > [3] = < / span > < span class = "identifier" > ms< / span > < span class = "plain" > -< / span > < span class = "element" > > path_to_search< / span > < span class = "plain" > ;< / span >
< span class = "reserved" > int< / span > < span class = "plain" > < / span > < span class = "identifier" > N< / span > < span class = "plain" > = 4;< / span >
< span class = "reserved" > for< / span > < span class = "plain" > (< / span > < span class = "reserved" > int< / span > < span class = "plain" > < / span > < span class = "identifier" > i< / span > < span class = "plain" > =0; < / span > < span class = "identifier" > i< / span > < span class = "plain" > < < / span > < span class = "identifier" > N< / span > < span class = "plain" > ; < / span > < span class = "identifier" > i< / span > < span class = "plain" > ++) {< / span >
< span class = "identifier" > TEMPORARY_TEXT< / span > < span class = "plain" > (< / span > < span class = "identifier" > T< / span > < span class = "plain" > );< / span >
< span class = "identifier" > WRITE_TO< / span > < span class = "plain" > (< / span > < span class = "identifier" > T< / span > < span class = "plain" > , < / span > < span class = "string" > "%S-module"< / span > < span class = "plain" > , < / span > < span class = "identifier" > name< / span > < span class = "plain" > );< / span >
< span class = "reserved" > pathname< / span > < span class = "plain" > *< / span > < span class = "identifier" > P< / span > < span class = "plain" > = < / span > < span class = "functiontext" > Pathnames::from_text_relative< / span > < span class = "plain" > (< / span > < span class = "identifier" > tries< / span > < span class = "plain" > [< / span > < span class = "identifier" > i< / span > < span class = "plain" > ], < / span > < span class = "identifier" > T< / span > < span class = "plain" > );< / span >
< span class = "reserved" > if< / span > < span class = "plain" > (< / span > < span class = "functiontext" > Modules::exists< / span > < span class = "plain" > (< / span > < span class = "identifier" > P< / span > < span class = "plain" > )) < / span > < < span class = "cwebmacro" > Accept this directory as the module< / span > < span class = "cwebmacronumber" > 7.1< / span > > < span class = "plain" > ;< / span >
< span class = "identifier" > DISCARD_TEXT< / span > < span class = "plain" > (< / span > < span class = "identifier" > T< / span > < span class = "plain" > );< / span >
< span class = "plain" > }< / span >
< span class = "reserved" > return< / span > < span class = "plain" > < / span > < span class = "identifier" > NULL< / span > < span class = "plain" > ;< / span >
< span class = "plain" > }< / span >
< / pre >
< p class = "inwebparagraph" > < / p >
< p class = "endnote" > The function Modules::find is used in 2/tr (< a href = "2-tr.html#SP9_3_3_2" > § 9.3.3.2< / a > ).< / p >
< p class = "inwebparagraph" > < a id = "SP7_1" > < / a > < b > § 7.1. < / b > When the module is found (if it is), a suitable module structure is made,
and a dependency created from the web's < code class = "display" > < span class = "extract" > (main)< / span > < / code > module to this one.
< / p >
< p class = "macrodefinition" > < code class = "display" >
< < span class = "cwebmacrodefn" > Accept this directory as the module< / span > < span class = "cwebmacronumber" > 7.1< / span > > =
< / code > < / p >
< pre class = "displaydefn" >
< span class = "reserved" > module< / span > < span class = "plain" > *< / span > < span class = "identifier" > M< / span > < span class = "plain" > = < / span > < span class = "functiontext" > Modules::new< / span > < span class = "plain" > (< / span > < span class = "identifier" > name< / span > < span class = "plain" > , < / span > < span class = "identifier" > P< / span > < span class = "plain" > , < / span > < span class = "constant" > READING_WEB_MOM< / span > < span class = "plain" > );< / span >
< span class = "functiontext" > Modules::dependency< / span > < span class = "plain" > (< / span > < span class = "identifier" > W< / span > < span class = "plain" > -< / span > < span class = "element" > > as_module< / span > < span class = "plain" > , < / span > < span class = "identifier" > M< / span > < span class = "plain" > );< / span >
< span class = "reserved" > return< / span > < span class = "plain" > < / span > < span class = "identifier" > P< / span > < span class = "plain" > ;< / span >
< / pre >
< p class = "inwebparagraph" > < / p >
< p class = "endnote" > This code is used in < a href = "#SP7" > § 7< / a > .< / p >
< p class = "inwebparagraph" > < a id = "SP8" > < / a > < b > § 8. < / b > We accept that a plausibly-named directory is indeed the module being
sought if it contains a file called < code class = "display" > < span class = "extract" > Contents.w< / span > < / code > : it's then certainly going
to be a web of some kind.
< / p >
< pre class = "display" >
< span class = "reserved" > int< / span > < span class = "plain" > < / span > < span class = "functiontext" > Modules::exists< / span > < span class = "plain" > (< / span > < span class = "reserved" > pathname< / span > < span class = "plain" > *< / span > < span class = "identifier" > P< / span > < span class = "plain" > ) {< / span >
< span class = "reserved" > filename< / span > < span class = "plain" > *< / span > < span class = "identifier" > Contents< / span > < span class = "plain" > = < / span > < span class = "functiontext" > Filenames::in_folder< / span > < span class = "plain" > (< / span > < span class = "identifier" > P< / span > < span class = "plain" > , < / span > < span class = "identifier" > I< / span > < span class = "string" > "Contents.w"< / span > < span class = "plain" > );< / span >
< span class = "reserved" > return< / span > < span class = "plain" > < / span > < span class = "functiontext" > TextFiles::exists< / span > < span class = "plain" > (< / span > < span class = "identifier" > Contents< / span > < span class = "plain" > );< / span >
< span class = "plain" > }< / span >
< / pre >
< p class = "inwebparagraph" > < / p >
< p class = "endnote" > The function Modules::exists is used in < a href = "#SP7" > § 7< / a > .< / p >
< p class = "inwebparagraph" > < a id = "SP9" > < / a > < b > § 9. < / b > Once loaded, wherever they came from, we sometimes need to look up a
module by name.
< / p >
< pre class = "display" >
< span class = "reserved" > module< / span > < span class = "plain" > *< / span > < span class = "functiontext" > Modules::find_loaded_by_name< / span > < span class = "plain" > (< / span > < span class = "reserved" > text_file_position< / span > < span class = "plain" > *< / span > < span class = "identifier" > tfp< / span > < span class = "plain" > , < / span > < span class = "reserved" > text_stream< / span > < span class = "plain" > *< / span > < span class = "identifier" > name< / span > < span class = "plain" > ) {< / span >
< span class = "reserved" > module< / span > < span class = "plain" > *< / span > < span class = "identifier" > M< / span > < span class = "plain" > ;< / span >
< span class = "identifier" > LOOP_OVER< / span > < span class = "plain" > (< / span > < span class = "identifier" > M< / span > < span class = "plain" > , < / span > < span class = "reserved" > module< / span > < span class = "plain" > )< / span >
< span class = "reserved" > if< / span > < span class = "plain" > (< / span > < span class = "functiontext" > Str::eq< / span > < span class = "plain" > (< / span > < span class = "identifier" > name< / span > < span class = "plain" > , < / span > < span class = "identifier" > M< / span > < span class = "plain" > -< / span > < span class = "element" > > module_name< / span > < span class = "plain" > ))< / span >
< span class = "reserved" > return< / span > < span class = "plain" > < / span > < span class = "identifier" > M< / span > < span class = "plain" > ;< / span >
< span class = "functiontext" > Errors::in_text_file< / span > < span class = "plain" > (< / span > < span class = "string" > "unknown module name"< / span > < span class = "plain" > , < / span > < span class = "identifier" > tfp< / span > < span class = "plain" > );< / span >
< span class = "reserved" > return< / span > < span class = "plain" > < / span > < span class = "identifier" > NULL< / span > < span class = "plain" > ;< / span >
< span class = "plain" > }< / span >
< / pre >
< p class = "inwebparagraph" > < / p >
< p class = "endnote" > The function Modules::find_loaded_by_name is used in 6/mkf (< a href = "6-mkf.html#SP2_9" > § 2.9< / a > , < a href = "6-mkf.html#SP2_11" > § 2.11< / a > ).< / p >
2019-03-12 23:32:12 +00:00
< hr class = "tocbar" >
< ul class = "toc" > < li > < a href = "2-tr.html" > Back to 'The Reader'< / a > < / li > < li > < a href = "2-lc.html" > Continue with 'Line Categories'< / a > < / li > < / ul > < hr class = "tocbar" >
2019-03-17 12:53:52 +00:00
<!-- End of weave: 131 lines from a web of 21211 -->
2019-02-04 22:26:45 +00:00
< / body >
< / html >