# - - - T o p i c . e x p a n d T r e e - - - #### Case 1: (not args.force) and (self's output page exists and #### is up to date) #-- 1 -- # [ if (not args.force) # and (self's output page exists and is up to date) -> # I # else (if self's body page exists and is valid and its # template exists and is valid) -> # self's output page := expansion of self's body page # in context of plan and the body page's template # else -> # Log() +:= error message(s) ] I #-- 2 -- # [ same intended function as above recursively applied to # all self's descendants ] subtree-output-pages(self's descendants, args, pathMap, plan): subtree-contents(self's descendants, args, pathMap, plan, subtree-files(self, pathMap, plan)) Log() +:= errors, if any, from expansion of self's descendants plan := plan with text variants added from elements in self's descendants #-- TARGET -- OK [ subtree-output-pages(self, args, pathMap, plan) := subtree-contents(self, args, pathMap, plan, subtree-files(self, pathMap, plan)) Log() +:= errors, if any, from that expansion plan := plan with text variants added from elements in subtree-files ] # - - - T o p i c . e x p a n d T r e e - - - #### Case 2: ((args.force) or (self's output page doesn't exist) or #### (self's page is not up to date)) and (self's body page exists #### and is valid) and (self's template exists and is valid) #-- 1 -- # [ if (not args.force) # and (self's output page exists and is up to date) -> # I # else (if self's body page exists and is valid and its # template exists and is valid) -> # self's output page := expansion of self's body page # in context of plan and the body page's template # else -> # Log() +:= error message(s) ] self.expand () self's output page: expansion of self's body page in context of plan and the body page's template #-- 2 -- # [ same intended function as above recursively applied to # all self's descendants ] self's output page: expansion of self's body page in context of plan and the body page's template subtree-output-pages(self's descendants, args, pathMap, plan): subtree-contents(self's descendants, args, pathMap, plan, subtree-files(self, pathMap, plan)) Log() +:= errors, if any, from expansion of self's descendants plan := plan with text variants added from elements in self's descendants #-- TARGET -- OK [ subtree-output-pages(self, args, pathMap, plan) := subtree-contents(self, args, pathMap, plan, subtree-files(self, pathMap, plan)) Log() +:= errors, if any, from that expansion plan := plan with text variants added from elements in subtree-files ] # - - - T o p i c . e x p a n d T r e e - - - #### Case 2: ((args.force) or (self's output page doesn't exist) or #### (self's page is not up to date)) and ((self's body page doesn't #### exist) or (self's body page is not valid) or (self's template #### doesn't exist) or (self's template is not valid) #-- 1 -- # [ if (not args.force) # and (self's output page exists and is up to date) -> # I # else (if self's body page exists and is valid and its # template exists and is valid) -> # self's output page := expansion of self's body page # in context of plan and the body page's template # else -> # Log() +:= error message(s) ] Log(): @+(error message(s)) #-- 2 -- # [ same intended function as above recursively applied to # all self's descendants ] Log(): @+(error message(s)) subtree-output-pages(self's descendants, args, pathMap, plan): subtree-contents(self's descendants, args, pathMap, plan, subtree-files(self, pathMap, plan)) Log() +:= errors, if any, from expansion of self's descendants plan := plan with text variants added from elements in self's descendants #-- TARGET -- OK [ subtree-output-pages(self, args, pathMap, plan) := subtree-contents(self, args, pathMap, plan, subtree-files(self, pathMap, plan)) Log() +:= errors, if any, from that expansion plan := plan with text variants added from elements in subtree-files ] # - - - T o p i c . e x p a n d - - - #### Case 1: (not args.force) and (self's body page exists) and #### (self's output page exists and is up to date) #-- 1 -- # [ bodyName := name of self's body file # htmlName := name of self's output file ] bodyName: name of self's body file htmlName: name of self's output file #-- 2 -- # [ if (self's output page exists and is up to date) # and (not args.force) -> # return # else -> I ] return #-- TARGET -- OK [ if (not args.force) and (self's body page exists) and (self's output page exists and is up to date) -> I else ... ] # - - - T o p i c . e x p a n d - - - #### Case 2: ((args.force) or (self's body page does not exists) or #### (self's output page does not exists or is not up to date)) and #### (self's body page exists and is valid and its template exists #### and is valid) and (output file can be created anew) #-- 1 -- # [ bodyName := name of self's body file # htmlName := name of self's output file ] bodyName: name of self's body file htmlName: name of self's output file #-- 2 -- # [ if (self's output page exists and is up to date) # and (not args.force) -> ... # else -> I ] bodyName: name of self's body file htmlName: name of self's output file #-- 3 -- # [ if bodyName is readable and valid and its # effective template is readable and valid -> # body := a new Body object representing that file # self.plan := self.plan with that effective template # added if not already present # else -> ... ] bodyName: name of self's body file htmlName: name of self's output file body: a Body object representing bodyName plan: @+(self's body's effective template, if not already present) #-- 4 -- # [ if self's output file can be created anew, with any # directories between output-root(args) and that file # created if necessary -> # outFile := a writeable handle for that new, empty file # else -> # Log() +:= error message(s) # return ] bodyName: name of self's body file htmlName: name of self's output file body: a Body object representing bodyName plan: @+(self's body's effective template, if not already present) self's output page: empty outFile: handle to self's new, empty page #-- 5 -- # [ outFile +:= expansion of body using body.etemplate as # its template ] bodyName: name of self's body file htmlName: name of self's output file body: a Body object representing bodyName plan: @+(self's body's effective template, if not already present) self's output page: expansion of a Body object representing bodyName and using bodyName's file's effective template outFile: @+(expansion of a Body object representing bodyName and using bodyName's file's effective template) #-- TARGET -- OK [ if (not args.force) and (self's body page exists) and (self's output page exists and is up to date) -> I else (if self's body page exists and is valid and its template exists and is valid) -> self's output page := expansion of self's body page in context of plan and the body page's template plan := plan with self's effective template added if not already present else -> ... ] # - - - T o p i c . e x p a n d - - - #### Case 3: ((args.force) or (self's body page does not exists) or #### (self's output page does not exists or is not up to date)) and #### (self's body page exists and is valid and its template exists #### and is valid) and (output file cannot be created anew) #-- 1 -- # [ bodyName := name of self's body file # htmlName := name of self's output file ] bodyName: name of self's body file htmlName: name of self's output file #-- 2 -- # [ if (self's output page exists and is up to date) # and (not args.force) -> ... # else -> I ] bodyName: name of self's body file htmlName: name of self's output file #-- 3 -- # [ if bodyName is readable and valid and its # effective template is readable and valid -> # body := a new Body object representing that file # self.plan := self.plan with that effective template # added if not already present # else -> ... ] bodyName: name of self's body file htmlName: name of self's output file body: a Body object representing bodyName plan: @+(self's body's effective template, if not already present) #-- 4 -- # [ if self's output file can be created anew, with any # directories between output-root(args) and that file # created if necessary -> ... # else -> # Log() +:= error message(s) # return ] Log(): @+(err msg) return #-- TARGET -- OK [ if (not args.force) and (self's body page exists) and (self's output page exists and is up to date) -> ... else (if self's body page exists and is valid and its template exists and is valid) -> ... else -> Log() +:= error message(s) ] # - - - T o p i c . _ _ p a g e U p T o D a t e - - - #### Case 1: (self's body file does not exist) and (self's output page #### does not exist) #-- 1 -- # [ if htmlName names an existing file -> # oldModTime := its modification timestamp as epoch time # else -> # oldModTime := None ] oldModTime: None #-- 2 -- # [ if bodyName names an existing file -> # bodyModTime := its modification epoch time # else -> # return 0 ] return 0 #-- TARGET -- OK [ if (bodyName is the name of self's body page as a string) and (htmlName is the name of self's output page as a string) -> if (self's output page exists and is up to date) and (not args.force) -> return 1 else -> return 0 ] # - - - T o p i c . _ _ p a g e U p T o D a t e - - - #### Case 2: (self's body file does not exist) and #### (self's output page does not exist) #-- 1 -- # [ if htmlName names an existing file -> # oldModTime := its modification timestamp as epoch time # else -> # oldModTime := None ] oldModTime: None #-- 2 -- # [ if bodyName names an existing file -> # bodyModTime := its modification epoch time # else -> # return 0 ] return 0 #-- TARGET -- OK [ if (bodyName is the name of self's body page as a string) and (htmlName is the name of self's output page as a string) -> if (self's output page exists and is up to date) and (self's body page exists) and (not args.force) -> return 1 else -> return 0 ] # - - - T o p i c . _ _ p a g e U p T o D a t e - - - #### Case 3: (self's body file exists) and (self's output file exists #### and is NOT up to date) #-- 1 -- # [ if htmlName names an existing file -> # oldModTime := its modification timestamp as epoch time # else -> # oldModTime := None ] oldModTime: mod-time of file named by htmlName #-- 2 -- # [ if bodyName names an existing file -> # bodyModTime := its modification epoch time # else -> # return 0 ] oldModTime: mod-time of file named by htmlName bodyModTime: mod-time of file named by bodyName, which is <= oldModTime by case assumption #-- 3 -- if ( ( not args.force ) and ( oldModTime ) and ( oldModTime > bodyModTime ) ): return 1 else: return 0 return 0 (since oldModTime <= bodyModTime) #-- TARGET -- OK [ if (bodyName is the name of self's body page as a string) and (htmlName is the name of self's output page as a string) -> if (self's output page exists and is up to date) and (self's body page exists) and (not args.force) -> return 1 else -> return 0 ] # - - - T o p i c . _ _ p a g e U p T o D a t e - - - #### Case 4: (self's body file exists) and (self's output file exists #### and is up to date) and (not args.force) #-- 1 -- # [ if htmlName names an existing file -> # oldModTime := its modification timestamp as epoch time # else -> # oldModTime := None ] oldModTime: mod-time of file named by htmlName #-- 2 -- # [ if bodyName names an existing file -> # bodyModTime := its modification epoch time # else -> # return 0 ] oldModTime: mod-time of file named by htmlName bodyModTime: mod-time of file named by bodyName, <= oldModTime by case assumption #-- 3 -- if ( ( oldModTime ) and ( oldModTime > bodyModTime ) and ( not args.force ) ): return 1 else: return 0 return 1 #-- TARGET -- OK [ if (bodyName is the name of self's body page as a string) and (htmlName is the name of self's output page as a string) -> if (self's output page exists and is up to date) and (self's body page exists) and (not args.force) -> return 1 else -> return 0 ] # - - - T o p i c . _ _ p a g e U p T o D a t e - - - #### Case 5: (self's body file exists) and (self's output file exists #### and is up to date) and (args.force) #-- 1 -- # [ if htmlName names an existing file -> # oldModTime := its modification timestamp as epoch time # else -> # oldModTime := None ] oldModTime: mod-time of file named by htmlName #-- 2 -- # [ if bodyName names an existing file -> # bodyModTime := its modification epoch time # else -> # return 0 ] oldModTime: mod-time of file named by htmlName bodyModTime: mod-time of file named by bodyName, <= oldModTime by case assumption #-- 3 -- if ( ( oldModTime ) and ( oldModTime > bodyModTime ) and ( not args.force ) ): return 1 else: return 0 return 0 #-- TARGET -- OK [ if (bodyName is the name of self's body page as a string) and (htmlName is the name of self's output page as a string) -> if (self's output page exists and is up to date) and (self's body page exists) and (not args.force) -> return 1 else -> return 0 ] # - - - T o p i c . _ _ o u t P a t h - - - #### Case 1: outRoot is None #-- 1 -- relPath = self.path + HTML_EXT relPath: (self.path + HTML_EXT) #-- 2 -- # [ if outRoot is None -> I # else -> # relPath := outRoot + ( "/" if necessary ) + relPath ] relPath: (self.path + HTML_EXT) #-- 3 -- return relPath return (self.path + HTML_EXT) #-- TARGET -- OK [ if outRoot is None or a string -> if outRoot is None -> return self.path + HTML_EXT else -> return outRoot + ("/" if needed) + self.path + HTML_EXT ] # - - - T o p i c . _ _ o u t P a t h - - - #### Case 2: outRoot is None #-- 1 -- relPath = self.path + HTML_EXT relPath: (self.path + HTML_EXT) #-- 2 -- # [ if outRoot is None -> I # else -> # relPath := outRoot + ( "/" if necessary ) + relPath ] relPath: (outRoot) + ("/" if necessary) + (self.path + HTML_EXT) #-- 3 -- return relPath return (outRoot) + ("/" if necessary) + (self.path + HTML_EXT) #-- TARGET -- OK [ if outRoot is None or a string -> if outRoot is None -> return self.path + HTML_EXT else -> return outRoot + ("/" if needed) + self.path + HTML_EXT ] # - - - T o p i c . _ _ o p e n O u t - - - #### Case 1: all directories in outName's path exist, and #### the file can be opened anew #-- 1 -- # [ if outName can opened anew -> # return a writeable file handle to that file, empty # else -> I ] return a writeable file handle to a new empty file named outName #-- TARGET -- OK [ if outName is a string -> if outName can be created anew, with any directories between output-root(args) and that file created if necessary -> return a writeable handle for that new, empty file else -> Log() +:= error message(s) return ] # - - - T o p i c . _ _ o p e n O u t - - - #### Case 2: not all directories in outName's path exist, #### but the missing ones can be created and the file can be opened anew #-- 1 -- # [ if outName can opened anew -> ... # else -> I ] I #-- 2 -- # [ if all directories in outName's path exist -> I # else if all nonexistent directories in outName's path can be # created top to bottom -> # create those directories # else -> # Log() +:= error message(s) # return None ] create all missing directories from outName's path #-- 3 -- # [ if outName can opened anew -> # return a writeable file handle to that file, empty # else -> # Log() +:= error message(s) # return None ] create all missing directories from outName's path return a writeable file handle to a new, empty file named outName #-- TARGET -- OK [ if outName is a string -> if outName can be created anew, with any directories between output-root(args) and that file created if necessary -> return a writeable handle for that new, empty file else -> Log() +:= error message(s) return ] # - - - T o p i c . _ _ o p e n O u t - - - #### Case 3: (not all directories in outName's path exist but the #### missing ones can be created) and (outName cannot be created new) #-- 1 -- # [ if outName can opened anew -> # return a writeable file handle to that file, empty # else -> I ] I #-- 2 -- # [ if all directories in outName's path exist -> I # else if all nonexistent directories in outName's path can be # created top to bottom -> # create those directories # else -> # Log() +:= error message(s) # return None ] create all missing directories in outName's path #-- 3 -- # [ if outName can opened anew -> # return a writeable file handle to that file, empty # else -> # Log() +:= error message(s) # return None ] create all missing directories in outName's path Log(): @+(error message(s)) return None #-- TARGET -- OK [ if outName is a string -> if outName can be created anew, with any directories between output-root(args) and that file created if necessary -> return a writeable handle for that new, empty file else -> possibly create some of the directories in outName's path Log() +:= error message(s) return None ] # - - - T o p i c . _ _ o p e n O u t - - - #### Case 4: (not all directories in outName's path exist) and (at #### least one cannot be created) #-- 1 -- # [ if outName can opened anew -> # return a writeable file handle to that file, empty # else -> I ] I #-- 2 -- # [ if all directories in outName's path exist -> I # else if all nonexistent directories in outName's path can be # created top to bottom -> # create those directories # else -> # possibly create some directories # Log() +:= error message(s) # return None ] possibly create some directories in outName's path Log() +:= error message(s) return None #-- TARGET -- OK [ if outName is a string -> if outName can be created anew, with any directories between output-root(args) and that file created if necessary -> return a writeable handle for that new, empty file else -> possibly create some of the directories in outName's path Log() +:= error message(s) return None ] # - - - T o p i c . _ _ m a k e D i r s - - - #### Case 1: All directories in path exist #-- 1 -- # [ dirList := a list of the names of each directory in path, # left to right ] dirList: list of names of each directory in path, left to right #-- 2 -- # [ if all elements of dirList are existing directories -> # I # else if all nonexistent elements of dirList can be created # as directories -> # create those directories # else -> # create directories up to the first one that can't be created # Log() +:= error message(s) # return 0 ] dirList: list of names of each directory in path, left to right #-- 3 -- return 1 return 1 #-- TARGET -- OK [ if path is a path name as a string -> if all directories in path exist -> return 1 else ... ] # - - - T o p i c . _ _ m a k e D i r s - - - #### Case 2: Some directories don't exist but they can be created #-- 1 -- # [ dirList := a list of the names of each directory in path, # left to right ] dirList: list of names of each directory in path, left to right #-- 2 -- # [ if all elements of dirList are existing directories -> # I # else if all nonexistent elements of dirList can be created # as directories -> # create those directories # else -> # create directories up to the first one that can't be created # Log() +:= error message(s) # return 0 ] dirList: list of names of each directory in path, left to right create nonexistent directories in path, left to right #-- 3 -- return 1 dirList: list of names of each directory in path, left to right create nonexistent directories in path, left to right return 1 #-- TARGET -- OK [ if path is a path name as a string -> if all directories in path exist -> ... else if all nonexistent directories in path can be created top to bottom -> create those directories return 1 else -> ... ] # - - - T o p i c . _ _ m a k e D i r s - - - #### Case 3: some element U of dirList can't be created #-- 1 -- # [ dirList := a list of the names of each directory in path, # left to right ] dirList: a list of the names of each directory in path, left to right #-- 2 -- # [ if all elements of dirList are existing directories -> # I # else if all nonexistent elements of dirList can be created # as directories -> # create those directories # else -> # create directories up to the first one that can't be created # Log() +:= error message(s) # return 0 ] dirList: a list of the names of each directory in path, left to right create any nonexistent directories before U in path Log(): @+(err msg(s)) return 0 #-- TARGET -- OK [ if path is a path name as a string -> if all directories in path exist -> ... else if all nonexistent directories in path can be created top to bottom -> ... else -> possibly create some of those directories Log() +:= error message(s) return 0 ] # - - - T o p i c . _ _ b u i l d D i r L i s t - - - #### Main sequence #### NB: The construct `list of slash-separated strings in s' is assumed to #### correspond to the operation of string.split(s, "/"). In particular, #### if s starts with a slash, the result list will start with an empty #### string, and if s ends with a slash, the result list will end with #### an empty string. So, e.g., string.split("/", "/") -> ["", ""] #-- 1 -- # [ if path contains no "/" -> # dirPart := "" # else -> # dirPart := text from path up to the last "/" ] dirPart: text from path up to last "/" #-- 2 -- # [ L := list of strings in dirPart separated by "/" # result := a new, empty list # sep := "" ] dirPart: text from path up to last "/" L: list of slash-separated strings in (path up to last "/") result: [] sep: "" #-- 3 -- # # [ result := result + nonempty members of the sequence # [ L[0], L[0]+"/"+L[1], ..., # L[0]+"/"+L[1]+"/"+...+"/"+L[-1]] # curPath := L[0]+"/"+L[1]+"/"+...+"/"+L[-1] # sep := "/" ] dirPart: text from path up to last "/" L: list of slash-separated strings in (path up to last "/") result: nonempty members of sequence [L[0], L[0]+"/"+L[1], ...] curPath: L[0]+"/"+L[1]+"/"+...+"/"+L[-1] sep: "/" #-- 4 -- return result return nonempty members of sequence [L[0], L[0]+"/"+L[1], ...] where L is list of slash-separated in strings in (path up to last "/") #-- TARGET -- OK [ if path is a string containing a path name -> if path has the form "/d0/d1/.../dn/f" -> return a list ["/d0", "/d0/d1", ..., "/d0/d1/.../dn"] else -> return a list ["d0", "d0/d1", ..., "d0/d1/.../dn" ] # - - - T o p i c . _ _ b u i l d D i r L i s t - - - #### Definite iteration of prime 3: false case #-- TARGET -- OK # [ result := result + nonempty members of the sequence # [ L[0], L[0]+"/"+L[1], ..., # L[0]+"/"+L[1]+"/"+...+"/"+L[-1]] # curPath := curPath+L[0]+"/"+L[1]+"/"+...+"/"+L[-1] # sep := "/" if len(L)>0, else unchanged ] # - - - T o p i c . _ _ b u i l d D i r L i s t - - - #### Definite iteration of prime 3: true case 1, L[0] is "" path: "" #-- 3 body -- # [ if part is "" -> # curPath := curPath+sep+part # sep := "/" # else -> ... ] curPath: @+@(sep) sep: "/" # [ result := result + nonempty members of the sequence # [ curPath+sep+L[0], curPath+sep+L[0]+"/"+L[1], ..., # curPath+sep+L[0]+"/"+L[1]+"/"+...+"/"+L[-1]] # curPath := curPath+sep+L[0]+"/"+L[1]+"/"+...+"/"+L[-1] # sep := "/" if len(L)>0, else unchanged ] result: @+nonempty members of the sequence [@(curPath)+@(sep), @(curPath)+@(sep)+"/"+L[1], @(curPath)+@(sep)+"/"+L[1]+"/"+L[2], ...] curPath: @+@(sep)+"/"+L[1]+"/"+L[2]+"/"+...+"/"+L[-1] sep: "/" #-- TARGET -- OK # [ result := result + nonempty members of the sequence # [ curPath+sep+L[0], curPath+sep+L[0]+"/"+L[1], ..., # curPath+sep+L[0]+"/"+L[1]+"/"+...+"/"+L[-1]] # curPath := curPath+sep+L[0]+"/"+L[1]+"/"+...+"/"+L[-1] # sep := "/" if len(L)>0, else unchanged ] # - - - T o p i c . _ _ b u i l d D i r L i s t - - - #### Definite iteration of prime 3: true case 2, L[0] is not "" path: nonempty L[0] #-- 3 body -- # [ if part is "" -> ... # else -> # result := result + [curPath+sep+part] # curPath := curPath+sep+part # sep := "/" ] result: @+[@(curPath)+@(sep)+L[0]] curPath: @+@(sep)+L[0] sep: "/" # [ result := result + nonempty members of the sequence # [ curPath+sep+L[0], curPath+sep+L[0]+"/"+L[1], ..., # curPath+sep+L[0]+"/"+L[1]+"/"+...+"/"+L[-1]] # curPath := curPath+sep+L[0]+"/"+L[1]+"/"+...+"/"+L[-1] # sep := "/" if len(L)>0, else unchanged ] result: @+[@(curPath)+@(sep)+L[0], @(curPath)+@(sep)+L[0]+"/"+L[1], ...] curPath: @+@(sep)+L[0]+"/"+L[1]+"/"+...+"/"+L[-1] sep: "/" #-- TARGET -- OK # [ result := result + nonempty members of the sequence # [ curPath+sep+L[0], curPath+sep+L[0]+"/"+L[1], ..., # curPath+sep+L[0]+"/"+L[1]+"/"+...+"/"+L[-1]] # curPath := curPath+sep+L[0]+"/"+L[1]+"/"+...+"/"+L[-1] # sep := "/" if len(L)>0, else unchanged ] # - - - T o p i c . _ _ c r e D i r - - - #### Case 1: path names an existing directory #-- 1 -- # [ if path can be statted -> # info := a PathInfo object representing that path # else -> ... ] info: a PathInfo object describing path #-- 2 -- # [ if info is None -> I # else if info is a directory -> return 1 # else -> # Log() +:= error message(s) # return 0 ] return 1 #-- TARGET -- OK [ if path is a string -> if path names an existing directory -> return 1 else ... ] # - - - T o p i c . _ _ c r e D i r - - - #### Case 2: (path names a nonexistent path) and (we can create #### a directory there) #-- 1 -- # [ if path can be statted -> # info := a PathInfo object representing that path # else -> # info := None ] info: None #-- 2 -- # [ if info is None -> I # else ... ] info: None #-- 3 -- # [ if a directory named path can be created -> # create it # return 1 # else -> # Log() +:= error message(s) # return 0 ] create path as an empty directory return 1 #-- TARGET -- OK [ if path is a string -> if path names an existing directory -> ... else if path names a directory that can be created -> create that directory return 1 else -> ... ] # - - - T o p i c . _ _ c r e D i r - - - #### Case 3: (path names an existing path that is not a directory) #-- 1 -- # [ if path can be statted -> # info := a PathInfo object representing that path # else -> # info := None ] info: a PathInfo object describing what is at path #-- 2 -- # [ if info is None -> I # else if info is a directory -> return 1 # else -> # Log() +:= error message(s) # return 0 ] Log(): @+(err msg(s)) return 0 #-- TARGET -- OK [ if path is a string -> if path names an existing directory -> ... else if path names a directory that can be created -> ... else -> Log() +:= error message(s) return 0 ] # - - - T o p i c . _ _ c r e D i r - - - #### Case 4: (path names a nonexistent path but we can't create a #### directory there) #-- 1 -- # [ if path can be statted -> ... # else -> # info := None ] info: None #-- 2 -- # [ if info is None -> I # else ... ] info: None #-- 3 -- # [ if a directory named path can be created -> # create it # return 1 # else -> # Log() +:= error message(s) # return 0 ] Log(): @+(err msg(s)) return 0 #-- TARGET -- [ if path is a string -> if path names an existing directory -> ... else if path names a directory that can be created -> ... else -> Log() +:= error message(s) return 0 ]