RCS file: RCS/plan.py,v Working file: plan.py head: 1.28 branch: locks: strict access list: symbolic names: keyword substitution: kv total revisions: 28; selected revisions: 28 description: ---------------------------- revision 1.28 date: 2000/05/11 23:23:54; author: john; state: Exp; lines: +67 -27 Trace table verification of Topic.expand() was getting ridiculous because there were too many cases. Accordingly, the logic now in Topic.__pageUpToDate() was removed from that method. There was one minor functional change. If the body file does not exist, in the previous version this was detected in the process of comparing body and HTML file timestamps. In the current version, if the body file does not exist, that problem will not be detected until slightly later, in the call to the Body() constructor. This is not a great impact---the error will still be detected. ---------------------------- revision 1.27 date: 2000/05/09 21:09:01; author: john; state: Exp; lines: +5 -3 Some minor clarifications of I/Fs pursuant to trace table verification. ---------------------------- revision 1.26 date: 2000/05/05 22:07:27; author: john; state: Exp; lines: +306 -4 Large amounts of new logic added to implement Topic.expandTree(). ---------------------------- revision 1.25 date: 2000/05/03 20:32:39; author: john; state: Exp; lines: +58 -9 Assorted minor corrections: - Detect duplicate titles in the Plan file. - Define cmp() for LinkVar objects. - Correct misstated I/F for Topic.fullPath(). ---------------------------- revision 1.24 date: 2000/04/08 22:48:14; author: john; state: Exp; lines: +11 -14 Made some changes to Topic.relPath() based on trace table verification. ---------------------------- revision 1.23 date: 2000/03/29 02:11:40; author: john; state: Exp; lines: +55 -12 - New method added: Topic.isOnPath(nodeId) is a predicate to test whether a topic is on a path specified by a NodeId. - New method added: Topic.find(nodeId) tries to find the Topic node specified by a NodeId object. - The addition of the above methods allowed me to make the Topic object's internal Tree object once again private. ---------------------------- revision 1.22 date: 2000/03/27 07:36:54; author: john; state: Exp; lines: +1 -6 Deleted leftover debug writes ---------------------------- revision 1.21 date: 2000/03/27 07:36:00; author: john; state: Exp; lines: +22 -22 ---------------------------------------------------------------- T2 Plan.__adjustTopicStack() needs scan for error reporting ---------------------------------------------------------------- B6 In Plan.__adjustTopicStack, this line does not change the caller's topicStack: topicStack = topicStack[:newDepth] but this does: del topicStack[newDepth:] ---------------------------------------------------------------- Also, not charged to this module: Topic.tree must be public because planview.py needs to pass the tree node to NodeId.find(). ---------------------------- revision 1.20 date: 2000/03/27 06:41:29; author: john; state: Exp; lines: +22 -16 B5 Plan.__buildTopic(): The checking and trimming of topicStack suffers from off-by-one errors that may result from translating the Icon version, since Icon has origine-one indexing. The root problem is that rawTopic.depth is expressed in the number of stars, but some calculations seem to assume that depth is 0 for the root, not 1. The cure for this affects several areas: - In class RawTopic, change the definition of the depth element so 0 means root, 1 means child of root, etc. - In Plan.__buildTopic(), rewrite prime #2 using zero-origin depth. - In Plan.__parseTopic(), subtract one from number of stars to get depth passed to RawTopic() constructor. - In Plan.__adjustTopicStack, same changes as previous step. - In class Topic, clarify that depth is 0-origin. ---------------------------- revision 1.19 date: 2000/03/27 05:27:08; author: john; state: Exp; lines: +2 -2 Forgot the `self' argument to Topic.fullpath(). ---------------------------- revision 1.18 date: 2000/03/27 05:25:47; author: john; state: Exp; lines: +12 -1 This delta was due to a bug in planview.py that required a feature to be added here (the bug is charged to planview.py and not to plan.py): T4 In NodeId.isonPath() and also in showClosedTopic(), I assumed that the Topic object had a public member .tree, but it's not public. So I added a Topic.fullPath() method that delegates to Tree.fullPath(). ---------------------------- revision 1.17 date: 2000/03/27 01:12:02; author: john; state: Exp; lines: +3 -3 Untabified, no other changes. ---------------------------- revision 1.16 date: 2000/03/27 01:00:42; author: john; state: Exp; lines: +6 -6 B4 In Plan.__read(), blank lines are being flagged as invalid. This condition won't work: if ( ( not scan.atEndLine() ) and ( scan.tabMatchArb ( CONTROL_LINE_CHAR ) ) ): self.__controlLine ( scan ) else: self.__buildTopic ( scan, topicStack ) Should be: if not scan.atEndLine(): if scan.tabMatchArb ( CONTROL_LINE_CHAR ): self.__controlLine ( scan ) else: self.__buildTopic ( scan, topicStack ) ---------------------------- revision 1.15 date: 2000/03/27 00:57:01; author: john; state: Exp; lines: +3 -3 B3 In Plan.__read(), the test for properly balanced $template control lines is that the final size of self.tmplStack is 1, not 0---due to the default template at the base of the stack. ---------------------------- revision 1.14 date: 2000/03/27 00:54:29; author: john; state: Exp; lines: +2 -1 Neglected to import the `tree' module from my standard library. ---------------------------- revision 1.13 date: 2000/03/27 00:31:47; author: john; state: Exp; lines: +24 -12 - The TmplPool object wants to open Template in the current directory, which will not work for planview.cgi. Hence, it will now accept a `defTemplate' argument specifying the default template name, and the Plan() constructor will have to pass that in. - Neglected to set up Plan.tmplStack[0] invariant. ---------------------------- revision 1.12 date: 2000/03/26 23:35:44; author: john; state: Exp; lines: +7 -5 B1 No one ever initialized Plan.shortNameMap. In __init__(), it was delegated to .__read(): #-- 4 -- # [ if fileName names a readable, valid plan file -> # ... # self.shortNameMap := as invariant # ... # else ... ] self.__read ( fileName ) The overall I/F for .__read() included this same line, but its third prime assumed that the element had been initialized: #-- 3 -- # [ if topicStack is a list of the path of nodes in the topic tree # from the root (if any) to the previous topic (if any) -> # ... # self.shortNameMap +:= new entries added mapping shortName # |-> topic for valid topics from the # remainder of scan # ... In the trace table file, the relevant case is: #### Case 5: fileName is readable and valid I had the same mental lapse in verification as I did in writing. State before step 3: topicStack: [] self.root: None errCount: @(Log().count()) scan: a Scan object pointing at start of fileName After step 3, the relevant line is: self.shortNameMap: @+(entries mapping short name |-> topic from fileName) Suggestion for future improvement: instead of just saying `as invariant', copy the actual invariant into the I/F, and perhaps I'll notice the lack of a value. When I wrote __init__(), I probably should have created the dictionary there. This also points to another weakness of my method: before the constructor is completed (which may involve many sub-methods), I have a tendency to play fast and loose with partially established class invariants. ---------------------------- revision 1.11 date: 2000/03/26 23:10:05; author: john; state: Exp; lines: +5 -5 The two precompiled patterns (reAnchor and topicPat) are in the object name spaces, not the global name spaces, of their class's methods. ---------------------------- revision 1.10 date: 2000/03/26 22:45:30; author: john; state: Exp; lines: +1 -7 Deleted a stray block of text that somehow wound up at the end of the source file. ---------------------------- revision 1.9 date: 2000/03/25 02:00:45; author: john; state: Exp; lines: +20 -4 Added a new method, Topic.url(), that returns the URL of the HTML page related to a given topic. ---------------------------- revision 1.8 date: 2000/03/24 00:36:22; author: john; state: Exp; lines: +10 -5 More problems detected by trace table verification: - References to error messages sent to scan changed to go to Log() - Plan.__addTopic(): Set the root if the parent is None. ---------------------------- revision 1.7 date: 2000/03/20 02:29:22; author: john; state: Exp; lines: +8 -3 - Plan.__adjustTopicStack(): Add missing I/F for first prime. - Plan.__adjustTopicStack(): Overall I/F refers to `rawTopic' which is not a name known in its scope. Change to refer to `newDepth'. - Plan.__addTopic(): Clarified I/F---talk about `last' element of `topicStack' because `top' is ambiguous. ---------------------------- revision 1.6 date: 2000/03/20 02:06:43; author: john; state: Exp; lines: +5 -5 Fixed the regular expression pattern used in Plan.__parseTopic() after side testing using the script `test/topictest'. This was necessary because I was using `|' to match that character, but the `re' module uses that to mean either-or, so I had to escape it with a backslash. ---------------------------- revision 1.5 date: 2000/03/20 01:43:25; author: john; state: Exp; lines: +12 -7 Changes made during trace table verification: - Plan.__controlLine(): Removed unnecessary `return' in prime #2. - Plan.__buildTopic(): Note that there is a side effect on `topicStack' for some error cases. - Plan.__buildTopic(): Explain in more detail in the I/Fs exactly where the new Topic object is added to the self.root tree. - Plan.__parseTopic(): Add side effect on position of scan. ---------------------------- revision 1.4 date: 2000/03/17 22:30:06; author: john; state: Exp; lines: +47 -14 Numerous changes due to trace table verification. Highlights: - Plan: Clarify invariant on .tmplPool. - Plan.__init__(): Clarify defaulting of fileName. - Plan.__init(): Initialize self.tmplStack. - Plan.__read(): Check that self.tmplStack is empty at end of file. - Plan.__read(): Check that file includes at least one valid topic. - Added new verification function, path-to-topic(), and used it where appropriate. ---------------------------- revision 1.3 date: 2000/03/17 05:40:17; author: john; state: Exp; lines: +6 -3 Two changes from trace table verification: - Plan.lookupTemplate(): In precondition, allow fileName to be None - Plan.lookupTemplate(): If TmplPool[...] raises IOError, convert that to KeyError as in the I/F. ---------------------------- revision 1.2 date: 2000/02/13 22:44:22; author: john; state: Exp; lines: +162 -18 Added code to handle $template lines in the plan file. ---------------------------- revision 1.1 date: 1999/11/16 22:52:12; author: john; state: Exp; Initial revision =============================================================================