AutoDox Readme

AutoDox is intended to promote code reuse by documenting key programs, including their parameters, internal procedures, and functions. One specific purpose is to use this product to generate documentation for your persistent procedures, so that all developers, particularly those who are learning your software application, will be able to easily look up key features of the most important programs to be reused.

AutoDox documents all of the procedures and functions in your programs, including those found in include files. Because Proparse does its own preprocessing, AutoDox works as if working with preprocessed source, rather than with raw, un-preprocessed source.

Future Directions

AutoDox is an open-source project, and as such, contributions are welcome. This section describes some of the things that we will do... if nobody else does them first. :-) Most urgently: AutoDox must be made accessible and customizable.

Accessible

Currently, AutoDox takes a list of programs to document, and generates detail pages, the table of contents, the index frame, and the summary page, all in one pass. This does not make it easy to regenerate the detail page for a single compile unit, nor does it make it easy to add a single new program to the documentation set.

Customizable

The AutoDox code is mostly one large program file. It must be restructured so that individual bits of it can be over-ridden, without making it difficult to accept new versions of AutoDox.

We recognize that the easiest way to do this would be with V9 features, but we feel that there are still enough people on 8.3 that it is important to to find another way. Perhaps we could structure things so that the core code can be over-ridden, using V9 features, but the core code still works with 8.3?

Methods from Include Files

AutoDox currently shows all methods and all functions, even those which come from include files. It would be good to be able to specify include files which are commonly used, whose methods should only be documented once in a separate details page. The include file would then be documented more like a distinct "method library". The programs which reference that include would then just have a link from their page to the include's page.

Instructions

As needed, identification of other significant code structures can be added to autodox/autodox2.p and thus to the resulting documentation. These may perhaps include definition of global variables, external procedure RUN statements, etc.

Generated HTML Files

This program generates the following set of .html files containing the documentation:



Customizing AutoDox For Your Application

AutoDox may be customized as necessary to tailor the result to your application. The following sections will help with this. See also the Future Directions section above.

AutoDox HTML Notes

Since autodox/autodox2.p generates HTML which will then be analyzed and displayed by your web browser, please note the following:

Working with the Parse Tree

AutoDox uses Proparse to generate a parse tree of your program, then does various manipulations through this tree (using the Proparse API) to gather the data for the HTML documentation. For more information about working with parse trees and using the Proparse API, see your Proparse Documentation.

Looking for Comments

Points to note when looking for your program's comments and white space when working with the Proparse-generated parse tree:

autodox/autodox2.p contains two internal procedures for finding comments, called getCommentBefore and getCommentAfter.

Configuration Parameters

The following configuration parameters in autodox/autodox.p are used to change where AutoDox will look for your comments. Unfortunately, using a generalization like this will miss certain comments in your code unless your code is incredibly consistently commented. For example, it is fairly common that when programmers comment variable definitions, they will put the comment to the right ("after") the DEFINE statement if it is a short comment, and put it on the line above ("before") the DEFINE statement if it is a long comment. Only one of these at a time can be meaningfully picked up by AutoDox, so it is best to configure AutoDox to aim for the majority of cases based on your own code.

Internal Procedure Comments

Use setProcCommentLoc = TRUE (before) to look for a comment before the procedure statement, actually immediately before the PROCEDURE node itself, for example when your code looks like this:

  /* comment for myProc */
  PROCEDURE myProc:   ...

Use setProcCommentLoc = FALSE (after) to look for a comment after the procedure statement, more specifically after the COLON (LEXCOLON) or PERIOD terminating your PROCEDURE statement, for example when your code looks like this:

  PROCEDURE myProc.     /* the comment I'm looking for */ 
    /* rest of myProc */
  END PROCEDURE.
or: 
  PROCEDURE myExtProc EXTERNAL "myProc.dll":   /* the comment I'm looking for */ 
    /* rest of myExtProc */
  END PROCEDURE.

Function Comments

Use setFuncCommentLoc = TRUE (before) to look for a comment before the function statement, actually immediately before the FUNCTION node itself, for example when your code looks like this:

  /* comment for myFunc */
  FUNCTION myFunc:   ...

Use setFuncCommentLoc = FALSE (after) to look for a comment after the function statement, more specifically after the COLON (LEXCOLON) or PERIOD terminating your FUNCTION statement, for example when your code looks like this:

  FUNCTION myFunc RETURNS LOGICAL FORWARD.   /* the comment I'm looking for */ 
or: 
  FUNCTION myFunc RETURNS LOGICAL:           /* the comment I'm looking for */ 
    /* rest of myFunc */
  END FUNCTION.

Parameter Comments

Use setParamCommentLoc = TRUE (before) to look for a comment before the DEFINE PARAMETER statement, actually immediately before the DEFINE node itself, for example when your code looks like this:

  /* comment for myParam */
  DEFINE INPUT PARAMETER myParam AS CHARACTER NO-UNDO. 

Use setParamCommentLoc = FALSE (after) to look for a comment after the DEFINE PARAMETER statement, more specifically after the PERIOD terminating your DEFINE statement, for example when your code looks like this:

  DEFINE INPUT PARAMETER myParam AS CHARACTER NO-UNDO.   /* the comment I'm looking for */ 

Note: for parameter comments after the DEFINE statement, it is best to only accept comments that are on the same line as the DEFINE statement. Otherwise, you may pick up a comment after your DEFINE and before the next DEFINE statement, but that belongs to the next DEFINE statement. For example, with this code you could accidentally pick up the comment for myParam3 when you are really looking for the comment AFTER myParam2, which doesn't exist:

  DEFINE INPUT PARAMETER myParam1 AS CHARACTER NO-UNDO.   /* the comment for myParam1 */ 
  DEFINE INPUT PARAMETER myParam2 AS CHARACTER NO-UNDO.   

  /* the comment for myParam3, in a BEFORE position. */ 
  DEFINE INPUT PARAMETER myParam3 AS CHARACTER NO-UNDO.   
See autodox/autodox2.p internal procedure getCommentAfter for an example of checking that your comments are on the same line.

Finding the First Comment in a Program

This is the first step in documenting a program. See autodox/autodox2.p Step 1. (internal procedure getProcComment).

To find the first comment in a program, (hopefully a description of the program!), start at the topmost node, the Program_root node. This is a synthetic node (didn't exist in the original program, but exists for working with the parse tree). In a loop, do a parserNodeFirstChild of this synthetic Program_root node (and its' children's children as needed) until you find a real node instead of a synthetic node. Real nodes are the nodes for which parserGetNodeText() will return true. They have text because they existed in the original program text.

Then, from this first real node, work backwards through any hidden tokens linked to it (only real nodes will have hidden text, i.e. comments and whitespace, linked to them) by doing a parserHiddenGetBefore(), then as many parserHiddenGetPrevious() calls as necessary and discarding any hidden nodes that are not parserHiddenGetType() = "COMMENT". When you run out of hidden nodes linked to the beginning of the real node ("before" the real node), the last (uppermost) hidden "COMMENT" node you found will be the first comment appearing in the original program text. You may need more than this one node depending on the commenting convention in your programs, for example if you have each comment line as its' own comment (one /* */ pair on each line).

Hidden node examples:

  /* This is all 
   * one hidden comment
   * token, with line 
   * feeds 
   * and all */
  
  /* This is a hidden token on its' own (of parserHiddenGetType() = "COMMENT") */
  /* and this is another separate hidden comment token. */

(These last two hidden comment tokens are actually separated by a line feed, which is in yet another hidden token, of parserHiddenGetType() = "WS".)