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 > 3/cla< / 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 '3/pth' 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" > foundation< / a > < / li > < li > < a href = "index.html#3" > Chapter 3: The Operating System< / a > < / li > < li > < b > Pathnames< / b > < / li > < / ul > < p class = "purpose" > To manage references to locations in the host computer's file system.< / p >
< ul class = "toc" > < li > < a href = "#SP1" > § 1. About pathnames< / a > < / li > < li > < a href = "#SP2" > § 2. Home folder< / a > < / li > < li > < a href = "#SP3" > § 3. Installation folder< / a > < / li > < li > < a href = "#SP4" > § 4. Creation< / a > < / li > < li > < a href = "#SP5" > § 5. Text to pathnames< / a > < / li > < li > < a href = "#SP6" > § 6. Writer< / a > < / li > < li > < a href = "#SP7" > § 7. Relative pathnames< / a > < / li > < li > < a href = "#SP8" > § 8. Existence in the file system< / a > < / li > < / ul > < hr class = "tocbar" >
< p class = "inwebparagraph" > < a id = "SP1" > < / a > < b > § 1. About pathnames. < / b > We use the word "pathname" to mean a file-system location of a folder (or
directory), and "filename" to mean a location of a file. For example:
< / p >
< p class = "inwebparagraph" > < / p >
< pre class = "display" >
< span class = "plain" > /Users/rblackmore/Documents/Fireball< / span >
< / pre >
< p class = "inwebparagraph" > is a pathname, whereas
< / p >
< p class = "inwebparagraph" > < / p >
< pre class = "display" >
< span class = "plain" > /Users/rblackmore/Documents/Fireball/whoosh.aiff< / span >
< / pre >
< p class = "inwebparagraph" > is a filename. All references to folder locations in the filing system will be
held internally as < code class = "display" > < span class = "extract" > pathname< / span > < / code > objects, and all references to file locations as
< code class = "display" > < span class = "extract" > filename< / span > < / code > objects. Once created, these are never destroyed or modified,
so that it's safe to store a pointer to a pathname or filename anywhere.
< / p >
< p class = "inwebparagraph" > Note that a pathname may well be hypothetical, that is, it may well
describe a folder which doesn't exist on disc.
< / p >
< p class = "inwebparagraph" > A full path is a linked list, but reverse-ordered: thus,
< / p >
< p class = "inwebparagraph" > < / p >
< pre class = "display" >
< span class = "plain" > /Users/rblackmore/Documents/< / span >
< / pre >
< p class = "inwebparagraph" > would be represented as a pointer to the < code class = "display" > < span class = "extract" > pathname< / span > < / code > for "Documents", which
in turn points to one for "rblackmore", which in turn points to "/Users".
Thus the root of the filing system is represented by the null pointer.
< / p >
< p class = "inwebparagraph" > Each < code class = "display" > < span class = "extract" > pathname< / span > < / code > can represent only a single level in the hierarchy, and
its textual name is not allowed to contain the < code class = "display" > < span class = "extract" > FOLDER_SEPARATOR< / span > < / code > character,
with just one exception: the < code class = "display" > < span class = "extract" > pathname< / span > < / code > at the end of the chain is allowed
to begin with < code class = "display" > < span class = "extract" > FOLDER_SEPARATOR< / span > < / code > to denote that it's at the root of the
host file system.
< / 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" > pathname< / 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" > intermediate< / 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" > pathname_of_parent< / span > < span class = "plain" > ;< / span >
< span class = "reserved" > int< / span > < span class = "plain" > < / span > < span class = "identifier" > known_to_exist< / span > < span class = "plain" > ; < / span > < span class = "comment" > corresponds to a directory in the filing system< / span >
< span class = "constant" > MEMORY_MANAGEMENT< / span >
< span class = "plain" > } < / span > < span class = "reserved" > pathname< / span > < span class = "plain" > ;< / span >
< / pre >
< p class = "inwebparagraph" > < / p >
< p class = "endnote" > The structure pathname is accessed in 3/fln and here.< / p >
< p class = "inwebparagraph" > < a id = "SP2" > < / a > < b > § 2. Home folder. < / b > We get the path to the user's home folder from the environment variable
< code class = "display" > < span class = "extract" > HOME< / span > < / code > , if it exists.
< / p >
< pre class = "display" >
< span class = "reserved" > pathname< / span > < span class = "plain" > *< / span > < span class = "identifier" > home_path< / span > < span class = "plain" > = < / span > < span class = "identifier" > NULL< / span > < span class = "plain" > ;< / span >
< span class = "reserved" > void< / span > < span class = "plain" > < / span > < span class = "functiontext" > Pathnames::start< / span > < span class = "plain" > (< / span > < span class = "reserved" > void< / span > < span class = "plain" > ) {< / span >
< span class = "reserved" > char< / span > < span class = "plain" > *< / span > < span class = "identifier" > home< / span > < span class = "plain" > = (< / span > < span class = "reserved" > char< / span > < span class = "plain" > *) (< / span > < span class = "functiontext" > Platform::getenv< / span > < span class = "plain" > (< / span > < span class = "string" > "HOME"< / span > < span class = "plain" > ));< / span >
< span class = "reserved" > if< / span > < span class = "plain" > (< / span > < span class = "identifier" > home< / span > < span class = "plain" > ) {< / span >
< span class = "reserved" > text_stream< / span > < span class = "plain" > *< / span > < span class = "identifier" > H< / span > < span class = "plain" > = < / span > < span class = "functiontext" > Str::new_from_locale_string< / span > < span class = "plain" > (< / span > < span class = "identifier" > home< / span > < span class = "plain" > );< / span >
< span class = "identifier" > home_path< / span > < span class = "plain" > = < / span > < span class = "functiontext" > Pathnames::from_text< / span > < span class = "plain" > (< / span > < span class = "identifier" > H< / span > < span class = "plain" > );< / span >
< span class = "identifier" > home_path< / span > < span class = "plain" > -< / span > < span class = "element" > > known_to_exist< / span > < span class = "plain" > = < / span > < span class = "constant" > TRUE< / span > < span class = "plain" > ;< / span >
< span class = "plain" > }< / span >
< span class = "plain" > }< / span >
< / pre >
< p class = "inwebparagraph" > < / p >
< p class = "endnote" > The function Pathnames::start appears nowhere else.< / p >
< p class = "inwebparagraph" > < a id = "SP3" > < / a > < b > § 3. Installation folder. < / b > < / p >
< pre class = "display" >
< span class = "reserved" > pathname< / span > < span class = "plain" > *< / span > < span class = "identifier" > installation_path< / span > < span class = "plain" > = < / span > < span class = "identifier" > NULL< / span > < span class = "plain" > ;< / span >
< span class = "reserved" > void< / span > < span class = "plain" > < / span > < span class = "functiontext" > Pathnames::set_installation_path< / 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 = "identifier" > installation_path< / span > < span class = "plain" > = < / span > < span class = "identifier" > P< / span > < span class = "plain" > ;< / span >
< span class = "plain" > }< / span >
< span class = "reserved" > pathname< / span > < span class = "plain" > *< / span > < span class = "functiontext" > Pathnames::installation_path< / span > < span class = "plain" > (< / span > < span class = "reserved" > const< / span > < span class = "plain" > < / span > < span class = "reserved" > char< / span > < span class = "plain" > *< / span > < span class = "identifier" > V< / span > < span class = "plain" > , < / span > < span class = "reserved" > text_stream< / span > < span class = "plain" > *< / span > < span class = "identifier" > def< / span > < span class = "plain" > ) {< / span >
< span class = "reserved" > if< / span > < span class = "plain" > (< / span > < span class = "identifier" > installation_path< / span > < span class = "plain" > ) < / span > < span class = "reserved" > return< / span > < span class = "plain" > < / span > < span class = "identifier" > installation_path< / span > < span class = "plain" > ;< / span >
< span class = "identifier" > wchar_t< / span > < span class = "plain" > < / span > < span class = "identifier" > where< / span > < span class = "plain" > [4*< / span > < span class = "constant" > MAX_FILENAME_LENGTH< / span > < span class = "plain" > ];< / span >
< span class = "identifier" > where< / span > < span class = "plain" > [0] = 0;< / span >
< span class = "functiontext" > Platform::where_am_i< / span > < span class = "plain" > (< / span > < span class = "identifier" > where< / span > < span class = "plain" > , 4*< / span > < span class = "constant" > MAX_FILENAME_LENGTH< / span > < span class = "plain" > );< / span >
< span class = "reserved" > if< / span > < span class = "plain" > (< / span > < span class = "identifier" > where< / span > < span class = "plain" > [0]) {< / span >
< span class = "reserved" > text_stream< / span > < span class = "plain" > *< / span > < span class = "identifier" > v< / span > < span class = "plain" > = < / span > < span class = "functiontext" > Str::new_from_wide_string< / span > < span class = "plain" > (< / span > < span class = "identifier" > where< / span > < span class = "plain" > );< / span >
< span class = "reserved" > filename< / span > < span class = "plain" > *< / span > < span class = "identifier" > F< / span > < span class = "plain" > = < / span > < span class = "functiontext" > Filenames::from_text< / span > < span class = "plain" > (< / span > < span class = "identifier" > v< / 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" > Filenames::get_path_to< / span > < span class = "plain" > (< / span > < span class = "identifier" > F< / span > < span class = "plain" > );< / span >
< span class = "reserved" > if< / span > < span class = "plain" > ((< / span > < span class = "identifier" > P< / span > < span class = "plain" > ) & & (< / span > < span class = "functiontext" > Str::eq< / span > < span class = "plain" > (< / span > < span class = "identifier" > P< / span > < span class = "plain" > -< / span > < span class = "element" > > intermediate< / span > < span class = "plain" > , < / span > < span class = "identifier" > I< / span > < span class = "string" > "Tangled"< / span > < span class = "plain" > )))< / span >
< span class = "identifier" > P< / span > < span class = "plain" > = < / span > < span class = "identifier" > P< / span > < span class = "plain" > -< / span > < span class = "element" > > pathname_of_parent< / span > < span class = "plain" > ;< / span >
< span class = "reserved" > return< / span > < span class = "plain" > < / span > < span class = "identifier" > P< / span > < span class = "plain" > ;< / span >
< span class = "plain" > }< / span >
< span class = "reserved" > if< / span > < span class = "plain" > (< / span > < span class = "identifier" > V< / span > < span class = "plain" > ) {< / span >
< span class = "reserved" > char< / span > < span class = "plain" > *< / span > < span class = "identifier" > val< / span > < span class = "plain" > = < / span > < span class = "functiontext" > Platform::getenv< / span > < span class = "plain" > (< / span > < span class = "identifier" > V< / span > < span class = "plain" > );< / span >
< span class = "reserved" > if< / span > < span class = "plain" > ((< / span > < span class = "identifier" > val< / span > < span class = "plain" > ) & & (< / span > < span class = "identifier" > val< / span > < span class = "plain" > [0])) {< / span >
< span class = "reserved" > text_stream< / span > < span class = "plain" > *< / span > < span class = "identifier" > v< / span > < span class = "plain" > = < / span > < span class = "functiontext" > Str::new_from_locale_string< / span > < span class = "plain" > (< / span > < span class = "identifier" > val< / span > < span class = "plain" > );< / span >
< span class = "reserved" > return< / span > < span class = "plain" > < / span > < span class = "functiontext" > Pathnames::from_text< / span > < span class = "plain" > (< / span > < span class = "identifier" > v< / span > < span class = "plain" > );< / span >
< span class = "plain" > }< / span >
< span class = "plain" > }< / span >
< span class = "reserved" > if< / span > < span class = "plain" > (< / span > < span class = "identifier" > def< / span > < span class = "plain" > ) < / span > < span class = "reserved" > return< / span > < span class = "plain" > < / span > < span class = "functiontext" > Pathnames::from_text< / span > < span class = "plain" > (< / span > < span class = "identifier" > def< / 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 Pathnames::set_installation_path is used in 3/cla (< a href = "3-cla.html#SP8_1" > § 8.1< / a > ).< / p >
< p class = "endnote" > The function Pathnames::installation_path appears nowhere else.< / p >
< p class = "inwebparagraph" > < a id = "SP4" > < / a > < b > § 4. Creation. < / b > A subfolder is made by taking an existing pathname (or possible < code class = "display" > < span class = "extract" > NULL< / span > < / code > ) and
then going one level deeper, using the supplied name.
< / p >
< pre class = "display" >
< span class = "reserved" > pathname< / span > < span class = "plain" > *< / span > < span class = "functiontext" > Pathnames::subfolder< / 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" > text_stream< / span > < span class = "plain" > *< / span > < span class = "identifier" > folder_name< / span > < span class = "plain" > ) {< / span >
< span class = "reserved" > return< / span > < span class = "plain" > < / span > < span class = "functiontext" > Pathnames::primitive< / span > < span class = "plain" > (< / span > < span class = "identifier" > folder_name< / span > < span class = "plain" > , 0, < / span > < span class = "functiontext" > Str::len< / span > < span class = "plain" > (< / span > < span class = "identifier" > folder_name< / span > < span class = "plain" > ), < / span > < span class = "identifier" > P< / span > < span class = "plain" > );< / span >
< span class = "plain" > }< / span >
< span class = "reserved" > pathname< / span > < span class = "plain" > *< / span > < span class = "functiontext" > Pathnames::primitive< / span > < span class = "plain" > (< / span > < span class = "reserved" > text_stream< / span > < span class = "plain" > *< / span > < span class = "identifier" > str< / span > < span class = "plain" > , < / span > < span class = "reserved" > int< / span > < span class = "plain" > < / span > < span class = "identifier" > from< / span > < span class = "plain" > , < / span > < span class = "reserved" > int< / span > < span class = "plain" > < / span > < span class = "identifier" > to< / span > < span class = "plain" > , < / span > < span class = "reserved" > pathname< / span > < span class = "plain" > *< / span > < span class = "identifier" > par< / 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 = "identifier" > CREATE< / 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 = "element" > > pathname_of_parent< / span > < span class = "plain" > = < / span > < span class = "identifier" > par< / span > < span class = "plain" > ;< / span >
< span class = "identifier" > P< / span > < span class = "plain" > -< / span > < span class = "element" > > known_to_exist< / span > < span class = "plain" > = < / span > < span class = "constant" > FALSE< / span > < span class = "plain" > ;< / span >
< span class = "reserved" > if< / span > < span class = "plain" > (< / span > < span class = "identifier" > to< / span > < span class = "plain" > -< / span > < span class = "identifier" > from< / span > < span class = "plain" > < = 0) < / span > < span class = "identifier" > internal_error< / span > < span class = "plain" > (< / span > < span class = "string" > "empty intermediate pathname"< / span > < span class = "plain" > );< / span >
< span class = "identifier" > P< / span > < span class = "plain" > -< / span > < span class = "element" > > intermediate< / span > < span class = "plain" > = < / span > < span class = "functiontext" > Str::new_with_capacity< / span > < span class = "plain" > (< / span > < span class = "identifier" > to< / span > < span class = "plain" > -< / span > < span class = "identifier" > from< / span > < span class = "plain" > +1);< / span >
< span class = "reserved" > if< / span > < span class = "plain" > (< / span > < span class = "identifier" > str< / span > < span class = "plain" > )< / 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" > = < / span > < span class = "identifier" > from< / span > < span class = "plain" > ; < / span > < span class = "identifier" > i< / span > < span class = "plain" > < < / span > < span class = "identifier" > to< / span > < span class = "plain" > ; < / span > < span class = "identifier" > i< / span > < span class = "plain" > ++)< / span >
< span class = "identifier" > PUT_TO< / span > < span class = "plain" > (< / span > < span class = "identifier" > P< / span > < span class = "plain" > -< / span > < span class = "element" > > intermediate< / span > < span class = "plain" > , < / span > < span class = "functiontext" > Str::get< / span > < span class = "plain" > (< / span > < span class = "functiontext" > Str::at< / span > < span class = "plain" > (< / span > < span class = "identifier" > str< / span > < span class = "plain" > , < / span > < span class = "identifier" > i< / span > < span class = "plain" > )));< / span >
< span class = "reserved" > return< / span > < span class = "plain" > < / span > < span class = "identifier" > P< / span > < span class = "plain" > ;< / span >
< span class = "plain" > }< / span >
< / pre >
< p class = "inwebparagraph" > < / p >
< p class = "endnote" > The function Pathnames::subfolder is used in 5/ee (< a href = "5-ee.html#SP6" > § 6< / a > , < a href = "5-ee.html#SP6_2" > § 6.2< / a > ).< / p >
2019-02-09 12:33:40 +00:00
< p class = "endnote" > The function Pathnames::primitive is used in < a href = "#SP5" > § 5< / a > .< / p >
2019-02-04 22:26:45 +00:00
< p class = "inwebparagraph" > < a id = "SP5" > < / a > < b > § 5. Text to pathnames. < / b > The following takes a text of a name and returns a pathname,
possibly relative to the home folder. Empty folder names are ignored
except possibly for an initial slash, so for example < code class = "display" > < span class = "extract" > paris/roubaix< / span > < / code > ,
< code class = "display" > < span class = "extract" > paris//roubaix< / span > < / code > and < code class = "display" > < span class = "extract" > paris/roubaix/< / span > < / code > are indistinguishable here, but
< code class = "display" > < span class = "extract" > /paris/roubaix< / span > < / code > is different.
< / p >
< pre class = "display" >
< span class = "reserved" > pathname< / span > < span class = "plain" > *< / span > < span class = "functiontext" > Pathnames::from_text< / span > < span class = "plain" > (< / span > < span class = "reserved" > text_stream< / span > < span class = "plain" > *< / span > < span class = "identifier" > path< / span > < span class = "plain" > ) {< / span >
< span class = "reserved" > return< / span > < span class = "plain" > < / span > < span class = "functiontext" > Pathnames::from_text_relative< / span > < span class = "plain" > (< / span > < span class = "identifier" > NULL< / span > < span class = "plain" > , < / span > < span class = "identifier" > path< / span > < span class = "plain" > );< / span >
< span class = "plain" > }< / span >
< span class = "reserved" > pathname< / span > < span class = "plain" > *< / span > < span class = "functiontext" > Pathnames::from_text_relative< / 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" > text_stream< / span > < span class = "plain" > *< / span > < span class = "identifier" > path< / 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 = "identifier" > P< / 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" > pos< / span > < span class = "plain" > = 0;< / span >
< span class = "reserved" > if< / span > < span class = "plain" > ((< / span > < span class = "functiontext" > Str::get< / span > < span class = "plain" > (< / span > < span class = "functiontext" > Str::start< / span > < span class = "plain" > (< / span > < span class = "identifier" > path< / span > < span class = "plain" > ))) & & (< / span > < span class = "identifier" > P< / span > < span class = "plain" > == < / span > < span class = "identifier" > NULL< / span > < span class = "plain" > )) < / span > < span class = "identifier" > i< / span > < span class = "plain" > ++;< / span >
< span class = "reserved" > for< / span > < span class = "plain" > (; < / span > < span class = "identifier" > i< / span > < span class = "plain" > < < / span > < span class = "functiontext" > Str::len< / span > < span class = "plain" > (< / span > < span class = "identifier" > path< / span > < span class = "plain" > ); < / span > < span class = "identifier" > i< / span > < span class = "plain" > ++)< / span >
< span class = "reserved" > if< / span > < span class = "plain" > (< / span > < span class = "functiontext" > Str::get< / span > < span class = "plain" > (< / span > < span class = "functiontext" > Str::at< / span > < span class = "plain" > (< / span > < span class = "identifier" > path< / span > < span class = "plain" > , < / span > < span class = "identifier" > i< / span > < span class = "plain" > )) == < / span > < span class = "constant" > FOLDER_SEPARATOR< / span > < span class = "plain" > ) {< / span >
< span class = "reserved" > if< / span > < span class = "plain" > (< / span > < span class = "identifier" > i< / span > < span class = "plain" > > < / span > < span class = "identifier" > pos< / span > < span class = "plain" > ) < / span > < span class = "identifier" > at< / span > < span class = "plain" > = < / span > < span class = "functiontext" > Pathnames::primitive< / span > < span class = "plain" > (< / span > < span class = "identifier" > path< / span > < span class = "plain" > , < / span > < span class = "identifier" > pos< / span > < span class = "plain" > , < / span > < span class = "identifier" > i< / span > < span class = "plain" > , < / span > < span class = "identifier" > at< / span > < span class = "plain" > );< / span >
< span class = "identifier" > pos< / span > < span class = "plain" > = < / span > < span class = "identifier" > i< / span > < span class = "plain" > +1;< / span >
< span class = "plain" > }< / span >
< span class = "reserved" > if< / span > < span class = "plain" > (< / span > < span class = "identifier" > i< / span > < span class = "plain" > > < / span > < span class = "identifier" > pos< / span > < span class = "plain" > ) < / span > < span class = "identifier" > at< / span > < span class = "plain" > = < / span > < span class = "functiontext" > Pathnames::primitive< / span > < span class = "plain" > (< / span > < span class = "identifier" > path< / span > < span class = "plain" > , < / span > < span class = "identifier" > pos< / span > < span class = "plain" > , < / span > < span class = "identifier" > i< / span > < span class = "plain" > , < / span > < span class = "identifier" > at< / span > < span class = "plain" > );< / span >
< span class = "reserved" > return< / span > < span class = "plain" > < / span > < span class = "identifier" > at< / span > < span class = "plain" > ;< / span >
< span class = "plain" > }< / span >
< / pre >
< p class = "inwebparagraph" > < / p >
2019-02-09 12:33:40 +00:00
< p class = "endnote" > The function Pathnames::from_text is used in < a href = "#SP2" > § 2< / a > , < a href = "#SP3" > § 3< / a > , 3/cla (< a href = "3-cla.html#SP8_1" > § 8.1< / a > , < a href = "3-cla.html#SP8_1_1" > § 8.1.1< / a > ), 3/fln (< a href = "3-fln.html#SP3" > § 3< / a > ), 5/ee (< a href = "5-ee.html#SP7_4" > § 7.4< / a > ).< / p >
2019-02-04 22:26:45 +00:00
< p class = "endnote" > The function Pathnames::from_text_relative appears nowhere else.< / p >
< p class = "inwebparagraph" > < a id = "SP6" > < / a > < b > § 6. Writer. < / b > Conversely, by the miracle of depth-first recursion:
< / p >
< pre class = "display" >
< span class = "reserved" > void< / span > < span class = "plain" > < / span > < span class = "functiontext" > Pathnames::writer< / span > < span class = "plain" > (< / span > < span class = "constant" > OUTPUT_STREAM< / span > < span class = "plain" > , < / span > < span class = "reserved" > char< / span > < span class = "plain" > *< / span > < span class = "identifier" > format_string< / span > < span class = "plain" > , < / span > < span class = "reserved" > void< / span > < span class = "plain" > *< / span > < span class = "identifier" > vP< / 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" > pathname< / span > < span class = "plain" > *) < / span > < span class = "identifier" > vP< / span > < span class = "plain" > ;< / span >
< span class = "reserved" > int< / span > < span class = "plain" > < / span > < span class = "identifier" > divider< / span > < span class = "plain" > = < / span > < span class = "constant" > FOLDER_SEPARATOR< / span > < span class = "plain" > ;< / span >
< span class = "reserved" > if< / span > < span class = "plain" > (< / span > < span class = "identifier" > format_string< / span > < span class = "plain" > [0] == < / span > < span class = "character" > '/'< / span > < span class = "plain" > ) < / span > < span class = "identifier" > divider< / span > < span class = "plain" > = < / span > < span class = "character" > '/'< / span > < span class = "plain" > ;< / span >
< span class = "reserved" > if< / span > < span class = "plain" > (< / span > < span class = "identifier" > P< / span > < span class = "plain" > ) < / span > < span class = "functiontext" > Pathnames::writer_r< / span > < span class = "plain" > (< / span > < span class = "identifier" > OUT< / span > < span class = "plain" > , < / span > < span class = "identifier" > P< / span > < span class = "plain" > , < / span > < span class = "identifier" > divider< / span > < span class = "plain" > ); < / span > < span class = "reserved" > else< / span > < span class = "plain" > < / span > < span class = "identifier" > WRITE< / span > < span class = "plain" > (< / span > < span class = "string" > "."< / span > < span class = "plain" > );< / span >
< span class = "plain" > }< / span >
< span class = "reserved" > void< / span > < span class = "plain" > < / span > < span class = "functiontext" > Pathnames::writer_r< / span > < span class = "plain" > (< / span > < span class = "constant" > OUTPUT_STREAM< / 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" > int< / span > < span class = "plain" > < / span > < span class = "identifier" > divider< / span > < span class = "plain" > ) {< / span >
< span class = "reserved" > if< / span > < span class = "plain" > (< / span > < span class = "identifier" > P< / span > < span class = "plain" > -< / span > < span class = "element" > > pathname_of_parent< / span > < span class = "plain" > ) {< / span >
< span class = "functiontext" > Pathnames::writer_r< / span > < span class = "plain" > (< / span > < span class = "identifier" > OUT< / span > < span class = "plain" > , < / span > < span class = "identifier" > P< / span > < span class = "plain" > -< / span > < span class = "element" > > pathname_of_parent< / span > < span class = "plain" > , < / span > < span class = "identifier" > divider< / span > < span class = "plain" > );< / span >
< span class = "identifier" > PUT< / span > < span class = "plain" > (< / span > < span class = "identifier" > divider< / span > < span class = "plain" > );< / span >
< span class = "plain" > }< / span >
< span class = "identifier" > WRITE< / span > < span class = "plain" > (< / span > < span class = "string" > "%S"< / span > < span class = "plain" > , < / span > < span class = "identifier" > P< / span > < span class = "plain" > -< / span > < span class = "element" > > intermediate< / span > < span class = "plain" > );< / span >
< span class = "plain" > }< / span >
< / pre >
< p class = "inwebparagraph" > < / p >
< p class = "endnote" > The function Pathnames::writer is used in 1/fnd (< a href = "1-fnd.html#SP8_1" > § 8.1< / a > ), 3/fln (< a href = "3-fln.html#SP4" > § 4< / a > ).< / p >
< p class = "endnote" > The function Pathnames::writer_r appears nowhere else.< / p >
< p class = "inwebparagraph" > < a id = "SP7" > < / a > < b > § 7. Relative pathnames. < / b > Occasionally we want to shorten a pathname relative to another one:
for example,
< / p >
< p class = "inwebparagraph" > < / p >
< pre class = "display" >
< span class = "plain" > /Users/rblackmore/Documents/Fireball/tablature< / span >
< / pre >
< p class = "inwebparagraph" > relative to
< / p >
< p class = "inwebparagraph" > < / p >
< pre class = "display" >
< span class = "plain" > /Users/rblackmore/Documents/< / span >
< / pre >
< p class = "inwebparagraph" > would be
< / p >
< p class = "inwebparagraph" > < / p >
< pre class = "display" >
< span class = "plain" > Fireball/tablature< / span >
< / pre >
< p class = "inwebparagraph" > Note that this does not correctly handle symlinks, < code class = "display" > < span class = "extract" > .< / span > < / code > , < code class = "display" > < span class = "extract" > ..< / span > < / code > and so on,
so it's probably not wise to use it with filenames typed in at the command
line.
< / p >
< pre class = "display" >
< span class = "reserved" > void< / span > < span class = "plain" > < / span > < span class = "functiontext" > Pathnames::to_text_relative< / span > < span class = "plain" > (< / span > < span class = "constant" > OUTPUT_STREAM< / 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" > pathname< / span > < span class = "plain" > *< / span > < span class = "identifier" > R< / span > < span class = "plain" > ) {< / span >
< span class = "identifier" > TEMPORARY_TEXT< / span > < span class = "plain" > (< / span > < span class = "identifier" > rt< / span > < span class = "plain" > );< / span >
< span class = "identifier" > TEMPORARY_TEXT< / span > < span class = "plain" > (< / span > < span class = "identifier" > pt< / span > < span class = "plain" > );< / span >
< span class = "identifier" > WRITE_TO< / span > < span class = "plain" > (< / span > < span class = "identifier" > rt< / span > < span class = "plain" > , < / span > < span class = "string" > "%p"< / span > < span class = "plain" > , < / span > < span class = "identifier" > R< / span > < span class = "plain" > );< / span >
< span class = "identifier" > WRITE_TO< / span > < span class = "plain" > (< / span > < span class = "identifier" > pt< / span > < span class = "plain" > , < / span > < span class = "string" > "%p"< / span > < span class = "plain" > , < / span > < span class = "identifier" > P< / span > < span class = "plain" > );< / span >
< span class = "reserved" > int< / span > < span class = "plain" > < / span > < span class = "identifier" > n< / span > < span class = "plain" > = < / span > < span class = "functiontext" > Str::len< / span > < span class = "plain" > (< / span > < span class = "identifier" > pt< / span > < span class = "plain" > );< / span >
< span class = "reserved" > if< / span > < span class = "plain" > ((< / span > < span class = "functiontext" > Str::prefix_eq< / span > < span class = "plain" > (< / span > < span class = "identifier" > rt< / span > < span class = "plain" > , < / span > < span class = "identifier" > pt< / span > < span class = "plain" > , < / span > < span class = "identifier" > n< / span > < span class = "plain" > )) & & (< / span > < span class = "functiontext" > Str::get_at< / span > < span class = "plain" > (< / span > < span class = "identifier" > rt< / span > < span class = "plain" > , < / span > < span class = "identifier" > n< / span > < span class = "plain" > )==< / span > < span class = "constant" > FOLDER_SEPARATOR< / span > < span class = "plain" > )) {< / span >
< span class = "functiontext" > Str::delete_n_characters< / span > < span class = "plain" > (< / span > < span class = "identifier" > rt< / span > < span class = "plain" > , < / span > < span class = "identifier" > n< / span > < span class = "plain" > +1);< / span >
< span class = "identifier" > WRITE< / span > < span class = "plain" > (< / span > < span class = "string" > "%S"< / span > < span class = "plain" > , < / span > < span class = "identifier" > rt< / span > < span class = "plain" > );< / span >
< span class = "plain" > } < / span > < span class = "reserved" > else< / span > < span class = "plain" > < / span > < span class = "identifier" > internal_error< / span > < span class = "plain" > (< / span > < span class = "string" > "pathname not relative to pathname"< / span > < span class = "plain" > );< / span >
< span class = "identifier" > DISCARD_TEXT< / span > < span class = "plain" > (< / span > < span class = "identifier" > rt< / span > < span class = "plain" > );< / span >
< span class = "identifier" > DISCARD_TEXT< / span > < span class = "plain" > (< / span > < span class = "identifier" > pt< / span > < span class = "plain" > );< / span >
< span class = "plain" > }< / span >
< span class = "reserved" > pathname< / span > < span class = "plain" > *< / span > < span class = "functiontext" > Pathnames::up< / 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" > if< / span > < span class = "plain" > (< / span > < span class = "identifier" > P< / 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" > "can't go up from root directory"< / span > < span class = "plain" > );< / span >
< span class = "reserved" > return< / span > < span class = "plain" > < / span > < span class = "identifier" > P< / span > < span class = "plain" > -< / span > < span class = "element" > > pathname_of_parent< / span > < span class = "plain" > ;< / span >
< span class = "plain" > }< / span >
< span class = "reserved" > text_stream< / span > < span class = "plain" > *< / span > < span class = "functiontext" > Pathnames::directory_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 = "reserved" > if< / span > < span class = "plain" > (< / span > < span class = "identifier" > P< / span > < span class = "plain" > == < / span > < span class = "identifier" > NULL< / 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 = "reserved" > return< / span > < span class = "plain" > < / span > < span class = "identifier" > P< / span > < span class = "plain" > -< / span > < span class = "element" > > intermediate< / span > < span class = "plain" > ;< / span >
< span class = "plain" > }< / span >
< / pre >
< p class = "inwebparagraph" > < / p >
< p class = "endnote" > The function Pathnames::to_text_relative appears nowhere else.< / p >
< p class = "endnote" > The function Pathnames::up appears nowhere else.< / p >
< p class = "endnote" > The function Pathnames::directory_name appears nowhere else.< / p >
< p class = "inwebparagraph" > < a id = "SP8" > < / a > < b > § 8. Existence in the file system. < / b > Just because we have a pathname, it doesn't follow that any folder exists
on the file system with that path.
< / p >
< pre class = "display" >
< span class = "reserved" > int< / span > < span class = "plain" > < / span > < span class = "functiontext" > Pathnames::create_in_file_system< / 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" > if< / span > < span class = "plain" > (< / span > < span class = "identifier" > P< / span > < span class = "plain" > == < / span > < span class = "identifier" > NULL< / span > < span class = "plain" > ) < / span > < span class = "reserved" > return< / span > < span class = "plain" > < / span > < span class = "constant" > TRUE< / span > < span class = "plain" > ; < / span > < span class = "comment" > the root of the file system always exists< / span >
< span class = "reserved" > if< / span > < span class = "plain" > (< / span > < span class = "identifier" > P< / span > < span class = "plain" > -< / span > < span class = "element" > > known_to_exist< / span > < span class = "plain" > ) < / span > < span class = "reserved" > return< / span > < span class = "plain" > < / span > < span class = "constant" > TRUE< / span > < span class = "plain" > ;< / span >
< span class = "reserved" > char< / span > < span class = "plain" > < / span > < span class = "identifier" > transcoded_pathname< / span > < span class = "plain" > [4*< / span > < span class = "constant" > MAX_FILENAME_LENGTH< / span > < span class = "plain" > ];< / span >
< span class = "identifier" > TEMPORARY_TEXT< / span > < span class = "plain" > (< / span > < span class = "identifier" > pn< / span > < span class = "plain" > );< / span >
< span class = "identifier" > WRITE_TO< / span > < span class = "plain" > (< / span > < span class = "identifier" > pn< / span > < span class = "plain" > , < / span > < span class = "string" > "%p"< / span > < span class = "plain" > , < / span > < span class = "identifier" > P< / span > < span class = "plain" > );< / span >
< span class = "functiontext" > Str::copy_to_locale_string< / span > < span class = "plain" > (< / span > < span class = "identifier" > transcoded_pathname< / span > < span class = "plain" > , < / span > < span class = "identifier" > pn< / span > < span class = "plain" > , 4*< / span > < span class = "constant" > MAX_FILENAME_LENGTH< / span > < span class = "plain" > );< / span >
< span class = "identifier" > DISCARD_TEXT< / span > < span class = "plain" > (< / span > < span class = "identifier" > pn< / span > < span class = "plain" > );< / span >
< span class = "identifier" > P< / span > < span class = "plain" > -< / span > < span class = "element" > > known_to_exist< / span > < span class = "plain" > = < / span > < span class = "functiontext" > Platform::mkdir< / span > < span class = "plain" > (< / span > < span class = "identifier" > transcoded_pathname< / span > < span class = "plain" > );< / span >
< span class = "reserved" > return< / span > < span class = "plain" > < / span > < span class = "identifier" > P< / span > < span class = "plain" > -< / span > < span class = "element" > > known_to_exist< / span > < span class = "plain" > ;< / span >
< span class = "plain" > }< / span >
< / pre >
< p class = "inwebparagraph" > < / p >
< p class = "endnote" > The function Pathnames::create_in_file_system is used in 5/ee (< a href = "5-ee.html#SP6" > § 6< / a > , < a href = "5-ee.html#SP6_2" > § 6.2< / a > ).< / p >
2019-03-12 23:32:12 +00:00
< hr class = "tocbar" >
< ul class = "toc" > < li > < a href = "3-cla.html" > Back to 'Command Line Arguments'< / a > < / li > < li > < a href = "3-fln.html" > Continue with 'Filenames'< / a > < / li > < / ul > < hr class = "tocbar" >
2019-03-18 11:16:10 +00:00
<!-- End of weave -->
2019-02-04 22:26:45 +00:00
< / body >
< / html >