# - - - P a t h M a p . _ _ i n i t _ _ - - - #### Case 1: fileName names a readable, valid PathMap file #-- 1 -- # [ errCount := count of errors from Log() ] errCount: @(Log().count()) #-- 2 -- # [ if fileName is a readable, valid PathMap file -> # self := self with entries added from that file # else -> # self := self with valid entries from that file added # Log() +:= error message(s) ] errCount: @(Log().count()) self: @ with entries added from that file #-- 3 -- # [ if Log() has more than errCount errors -> ... # else -> I ] errCount: @(Log().count()) self: @ with entries added from that file #-- TARGET -- OK [ if fileName is a string -> if fileName names a readable, valid PathMap file -> return a new PathMap object representing that file else -> ... ] # - - - P a t h M a p . _ _ i n i t _ _ - - - #### Case 2: fileName is not readable or not a valid PathMap file #-- 1 -- # [ errCount := count of errors from Log() ] errCount: @(Log().count()) #-- 2 -- # [ if fileName is a readable, valid PathMap file -> ... # else -> # self := self with valid entries from that file added # Log() +:= error message(s) ] errCount: @(Log().count()) self: @+(valid entries from fileName) Log(): @+(error(s)) #-- 3 -- # [ if Log() has more than errCount errors -> # Log() +:= error message # stop execution # else -> I ] errCount: @(Log().count()) self: @+(valid entries from fileName) Log(): @+(error(s))+(error message) stop execution #-- TARGET -- OK [ if fileName is a string -> if fileName names a readable, valid PathMap file -> ... else -> Log() +:= error message(s) stop execution ] # - - - P a t h M a p . _ _ r e a d F i l e - - - #### Case 1: fileName names a readable, valid PathMap file #-- 1 -- # [ errCount := count of errors from Log() ] errCount: @(Log().count()) self.__shortPathMap: {} #-- 2 -- # [ if fileName can be opened for reading -> # scan := a Scan object pointing to the start of that file # else -> ... ] errCount: @(Log().count()) scan: a Scan object pointing to the start of fileName #-- 3 -- # [ if scan contains one line starting with "http://" -> # scan := scan advanced to the next line # self.rootURL := that line, without trailing whitespace # else -> ... ] errCount: @(Log().count()) scan: a Scan object pointing to the second line of fileName self.rootURL: first line from fileName, without trailing whitespace #-- 4 -- # [ if the remainder of scan consists of valid path map lines -> # scan := scan advanced to EOF # self.__shortPathMap +:= entries mapping short name |-> # corresponding full path name ] errCount: @(Log().count()) scan: a Scan object at EOF self.rootURL: first line from fileName, without trailing whitespace self.__shortPathMap: dictionary mapping short names from fileName |-> corresponding full path names #-- 5 -- # [ if Log() has more errors than errCount -> ... # else -> I ] errCount: @(Log().count()) scan: a Scan object at EOF self.rootURL: first line from fileName, without trailing whitespace self.__shortPathMap: dictionary mapping short names from fileName |-> corresponding full path names #-- TARGET -- OK [ if fileName is a string -> if fileName names a readable, valid PathMap file -> self.rootURL := the root URL name from that file self.__shortPathMap := a dictionary that maps each short name from that file |-> corresponding full path name else -> ... ] # - - - P a t h M a p . _ _ r e a d F i l e - - - #### Case 2: fileName is not readable #-- 1 -- # [ errCount := count of errors from Log() # self.__shortPathMap := a new, empty dictionary ] errCount: @(Log().count()) self.__shortPathMap: {} #-- 2 -- # [ if fileName can be opened for reading -> ... # else -> # Log() +:= error message # return ] errCount: @(Log().count()) self.__shortPathMap: {} Log(): @+(error(s)) return #-- TARGET -- OK [ if fileName is a string -> if fileName names a readable, valid PathMap file -> ... else -> self := self with valid entries from that file added Log() +:= error message(s) ] # - - - P a t h M a p . _ _ r e a d F i l e - - - #### Case 3: fileName is readable but first line absent or wrong prefix #-- 1 -- # [ errCount := count of errors from Log() # self.__shortPathMap := a new, empty dictionary ] errCount: @(Log().count()) self.__shortPathMap: {} #-- 2 -- # [ if fileName can be opened for reading -> # scan := a Scan object pointing to the start of that file # else -> # Log() +:= error message # return ] errCount: @(Log().count()) self.__shortPathMap: {} scan: a Scan object pointing to the start of fileName #-- 3 -- # [ if scan contains one line starting with "http://" -> ... # else -> # Log() +:= error message # return ] errCount: @(Log().count()) self.__shortPathMap: {} scan: a Scan object pointing to the start of fileName Log(): @+(error(s)) return #-- TARGET -- OK [ if fileName is a string -> if fileName names a readable, valid PathMap file -> ... else -> self := self with valid entries from that file added Log() +:= error message(s) ] # - - - P a t h M a p . _ _ r e a d F i l e - - - #### Case 4: fileName's first line is okay but has errors in map lines #-- 1 -- # [ errCount := count of errors from Log() # self.__shortPathMap := a new, empty dictionary ] errCount: @(Log().count()) self.__shortPathMap: {} #-- 2 -- # [ if fileName can be opened for reading -> # scan := a Scan object pointing to the start of that file # else -> ... ] errCount: @(Log().count()) self.__shortPathMap: {} scan: a Scan object pointing at the start of fileName #-- 3 -- # [ if scan contains one line starting with "http://" -> # scan := scan advanced to the next line # self.rootURL := that line, without trailing whitespace # else -> ... ] errCount: @(Log().count()) self.__shortPathMap: {} scan: a Scan object pointing at the second line of fileName self.rootURL: first line from fileName, without trailing whitespace #-- 4 -- # [ if the remainder of scan consists of valid path map lines -> ... # else -> # scan := scan advanced to EOF # self.__shortPathMap +:= entries mapping valid short names |-> # corresponding full path names # Log() +:= error messages about invalid lines ] errCount: @(Log().count()) self.__shortPathMap: dictionary mapping valid short names from scan |-> corresponding full path names scan: a Scan object at EOF self.rootURL: first line from fileName, without trailing whitespace Log(): @+(error(s)) #-- TARGET -- OK [ if fileName is a string -> if fileName names a readable, valid PathMap file -> ... else -> self := self with valid entries from that file added Log() +:= error message(s) ] # - - - P a t h M a p . _ _ r e a d P a t h L i n e - - - #### Case 1: line in scan is a valid path map line, and its short #### name is not a key in self.__shortPathMap #-- 1 -- # [ if line in scan matches linePat -> ... # scan := scan advanced to end of line # m := a Match object describing the matched fields # else -> ... ] m: a Match object with short=(short name) and full=(full path) from line in scan #-- 2 -- # [ if (m is None) # or (self.__shortPathMap already contains a key like # the group from m) -> # Log() +:= error message # else -> # self.__shortPathMap +:= a new entry mapping the # group from m |-> the group ] m: a Match object with short=(short name) and full=(full path) from line in scan self.__shortPathMap: @+(entry mapping short name from line in scan |-> full path from line in scan) #-- TARGET -- OK [ if scan is a Scan object -> if the line in scan is a valid path map line -> self.__shortPathMap +:= entry mapping short name |-> corresponding full path name else -> ... ] # - - - P a t h M a p . _ _ r e a d P a t h L i n e - - - #### Case 2: line in scan is a valid path map line, but its short #### name *is* a key in self.__shortPathMap #-- 1 -- # [ if line in scan matches linePat -> # scan := scan advanced to end of line # m := a Match object describing the matched fields # else -> # m := None ] m: a Match object with short=(short name) and full=(full path) from line in scan #-- 2 -- # [ if (m is None) # or (self.__shortPathMap already contains a key like # the group from m) -> # Log() +:= error message # else -> # self.__shortPathMap +:= a new entry mapping the # group from m |-> the group ] m: a Match object with short=(short name) and full=(full path) from line in scan Log(): @+(error msg) #-- TARGET -- OK [ if scan is a Scan object -> if the line in scan is a valid path map line -> ... else -> Log() +:= error message(s) ] # - - - P a t h M a p . _ _ r e a d P a t h L i n e - - - #### Case 3: line in scan is not in valid path map line format #-- 1 -- # [ if line in scan matches linePat -> # scan := scan advanced to end of line # m := a Match object describing the matched fields # else -> # m := None ] m: None #-- 2 -- # [ if (m is None) # or (self.__shortPathMap already contains a key like # the group from m) -> # Log() +:= error message # else -> ... ] m: None Log(): @+(error msg) #-- TARGET -- OK [ if scan is a Scan object -> if the line in scan is a valid path map line -> ... else -> Log() +:= error message(s) ] # - - - P a t h M a p . e x p a n d S h o r t N a m e - - - #### Case 1: (s has the form "spath/sfile[#anchor]") #### and (spath is a key in self.__shortPathMap) #-- 1 -- # [ if there is a slash in s -> # shortPath := characters from s up to the first slash # filePart := characters from first slash through end # else -> # return s ] shortPath: characters from s up to first slash filePart: characters from s from first slash through end #-- 2 -- # [ if shortPath is not a key in self.__shortPathMap -> ... # else -> # return self.__shortPathMap[shortPath] + "/" + filePart ] shortPath: characters from s up to first slash filePart: characters from s from first slash through end return self.__shortPathMap[(chars from s up to first slash)]+"/"+ (chars from s from first slash through end ) #-- TARGET -- OK [ if (s has the form "spath/sfile[#anchor]") and (spath is a key in self.__shortPathMap) -> return self.__shortPathMap[spath] + "/" + sfile[#anchor] else ... ] # - - - P a t h M a p . e x p a n d S h o r t N a m e - - - #### Case 2: (s has the form "spath/sfile[#anchor]") #### but (spath is NOT a key in self.__shortPathMap) #-- 1 -- # [ if there is a slash in s -> # shortPath := characters from s up to the first slash # filePart := characters from first slash through end # else -> # return s ] shortPath: (chars from s up to first slash) filePart: (chars from first slash in s to end) #-- 2 -- # [ if shortPath is not a key in self.__shortPathMap -> # return None # else -> # return self.__shortPathMap[shortPath] + "/" + filePart ] shortPath: (chars from s up to first slash) filePart: (chars from first slash in s to end) return None #-- TARGET -- OK [ if (s has the form "spath/sfile[#anchor]") and (spath is a key in self.__shortPathMap) -> ... else if (s has the form "spath/sfile[#anchor]") and (spath is not a key in self.__shortPathMap) -> return None else -> ... ] # - - - P a t h M a p . e x p a n d S h o r t N a m e - - - #### Case 3: s contains no slash #-- 1 -- # [ if there is a slash in s -> ... # else -> # return s ] return s #-- TARGET -- OK [ if (s has the form "spath/sfile[#anchor]") and (spath is a key in self.__shortPathMap) -> ... else if (s has the form "spath/sfile[#anchor]") and (spath is not a key in self.__shortPathMap) -> ... else -> return s ]