Example Source file, with rules. Jim Bostwick 14-NOV-1988 11:37:38 Below is an example of what I consider a well-constructed source module. The following items are considered mandatory: 1. File identification line. Give file name, extension, either directory or logical name where file may be found. Note that although this example uses a hard directory, I am moving twoard use of logical names. PAS$SRC might be good for this one. 2. Last Edit line. This is required for the automatic last edit update in EDTINI.EDT to work. Syntax is "Last Edit:". Note that case is not significant, but the colon is.[ On VMS, LSE is smart enough to insert my initials before the date.] The above are the only two *REQUIRED* items. The remainder are optional, but recommended. They are explained below. 3. TITLE and IDENT lines. For MACRO sources, these propogate to the listing, and to the MAP (IDENT appears in the MAP). I Don't try to keep ident current, but usually do update it on major revisions. 4. AUTHOR Line. This is pretty self-explanatory. 5. Desc line. (Short for Description). This is a recent innovation, which I find quite useful. Provide a one-line 'title-style' description of the module's function. The goal here is to have the first page of the file provide a good, quick, overview of what it is. 6. History line. Shows brief entry for each revision. Usually, these are functionality changes or bug fixes. Do *NOT* clutter this up with random comments during development! Recently, I've taken to listing these in REVERSE chronological order (we historically use Ascending order). This is to keep the most recent changes on the first screen. ** Philosophy 101 - It is very handy to scan through a directory with VTL to get a quick look at what's there. Much of the current format is directed twoard putting the most useful information on the first page of such a scan. In particular, this is the motivation for the DESC line and the reverse ordering of the History entries. 7. Pascal External Comment This area includes the external header definition, User, and Wizard comments. These are, by convention, contained in a single MACRO REMark block. Also by convention, I use the vertical bar (|) as the delimiter. 8. External Header. For direct extraction by PASEXT, in form required by pascal compiler. Note the embedded comment. Note also that the parameters each live on a separate line. This makes for much more readability. Moreover, when we get to VAX Pascal, the identifiers and types are often so long as to require a single line format. This is also the conventional formatting for all VAX languages (it's given to you by LSE, for example). 9. USER Documentation. This is for the user of the library - e.g., an applications programmer. Format is "{*USER*" on it's own line, followed by a blank line, followed by text to be included in RUNOFF source. Terminates by "}" on a separate line. 10. Wizard documentation. (Yep - I WAS spelling it wrong!) Same as User, but keyword is "{*WIZARD*". Also note blank line before text. 11. CALL Line - (NEW). This line identifies the beginning of the call site - the Pascal external header in this case. Syntax is "{*CALL*" on it's own line. Because un-terminated comments can be a real pain, it is OK to terminate the comment as shown. 12. Library statement. Embedding library and include file references in the source has proven highly beneficial to Pascal. As of the last couple of versions of MACRO, the .LIBRARY and .INCLUDE statements are supported. The use and suggested order for these statements is illustrated. NOTE: I have started using PAS$EXT:PASMAC.MAC for the include. This requires that a copy of PASMAC live in with the externals. Seems like a good idea to me, as PAS$EXT is the only directory guaranteed to live on the field system. I would also like to put PxUTIL.OLB in PAS$EXT as well - and for the same reason. Like to have one logical point to all of the 'field-installed' pasutil stuff. This is a recommended change independent of the source file formats. Note on comments: (not shown, but I'll throw it in here anyway). I generally format stand-alone comments as follows: Open comment in either Col 1 or lined up with the source indentation. If comment spans more than one line, the comment delimiters go on separate lines. The close delimiter usually goes one column indented from the opening one - this is esthetically pleasing. For example { This is a one-line comment. } { This is a longer comment. It is indented from the comment delimiters, and the close delimiter is also indented. } My only hard rule as to comments is to *NEVER* start a comment after a source line which then continues onto another line! It's too easy to then move the source line, or insert another after it, and end up with either a broken comment, or (worse!) the inserted line as PART of the comment! Example program source follows: .TITLE NTCON *** 3 *** .ENABLE LC .IDENT /010688/ *** 3 *** ; ; File:[22,310]NTCON.MAC *** 1 *** ; Author: Jim Bostwick 1-JUN-1988 *** 4 *** ; ; Last Edit: 14-NOV-1988 11:37:23 *** 2 *** ; ; Desc: Request DECnet logical Link Connection *** 5 *** ; ; History: *** 6 *** ; 23-JUN-1988 21:17:17 - JMB PA3UTL upgrade. ; 1-JUN-1988 01:32:41 - JMB Creation. ; .REM | *** 7 *** {*CALL*} *** 11 *** Procedure NTCON ( *** 8 *** lun: integer; EFN: Event_flag; Out_MSG: CH16; { user message sent to remote task } VAR Conb: Net_request_block; VAR In_MSG: CH16; VAR IOSB: Io_Status_block );External; {*USER* *** 9 *** Request a logical link with remote task. Build Conb with call to NTCONB prior to invoking NTCON. OUT_MSG contains user data sent to remote task (it get's it in the NTGND call). In_MSG will receive data sent by the remote task in it's NTACC call. } {*WIZARD* *** 10 *** AST, NOFLOW, short connect blocks not implemented. } | ; ; Assemble with PASMAC.MAC as prefix file. ; &&&&& .library /lb:[1,1]netlib.mlb/ *** 12 *** .MCALL CONW$S,CRBDF$ ***<- these come from netlib .include /PAS$EXT:PASMAC/ *** 12 *** CRBDF$ PROC NTCON PARAM LUN, Integer PARAM EFN, Char PARAM OutMsg, 16.*Char PARAM Conb, Address PARAM InMsg, Address PARAM IOSB, Address SAVE BEGIN mov sp, r0 movb efn(sp), r1 ; get EFN bic #^C377, r1 mov r0, r2 ; get outmsg pointer add #outmsg, r2 ; ... tstb (r2) ; null message? bne 10$ ; no - send it clr r2 ; say no message 10$: conw$s lun(r0),r1,iosb(r0),, ENDPR .END