! File: ATG$FORMAT_C.TPU Format the current buffer
! Creation: 20 November 1988
! Author: Nick de Smith
! Applied Telematics Services, 7 Vale Avenue, Tunbridge Wells, Kent TN1 1DJ, England.
! +44 892 511000, PSI%234213300154::NICK
!
! Scan through the current buffer, line by line, and call process_line with a range specifying each
! line in turn.
! The overall effect of this routine is to line up the comments in a C program to fit the ATG coding standard.
! Invoke as:
! $ EDIT/TPU/SECTION=ATG_EVE /COMMAND=dev:
FORMAT_C file.typ
!
! The use F9 to format the current buffer.
! Although this routine is designed to work with ATG_EVE, it is very simple to change for any TPU based editor.
! (just change references to atg$message() to message()).
!
! Use this routine as a template for formatting any language/buffer.
!
! Edit Edit date By Why
! 01 15-Mar-89 NMdS New
!
!
! ATG$FORMAT_C format current buffer for C
!
! Read each line from the current buffer in turn and pass it to process_line(). Highlight the line we are
! working on.
!
procedure atg$format_c
local mark_1,
range_1,
line_range;
on_error
[TPU$_STRNOTFOUND]:
[OTHERWISE]:
endon_error;
atg$message('Starting formatting'); ! Say that we are done now
position(beginning_of(current_buffer)); ! Move to start of buffer
loop
exitif mark(none) = end_of(current_buffer); ! Exit if we are at the end of the buffer
range_1 := search_quietly(line_begin,forward,exact); ! Look for the next line
exitif range_1 = 0; ! Exit if no more lines in buffer
mark_1 := end_of(range_1); ! Save start of line marker
position(mark_1); ! Move to start of line
position(end_of(search_quietly(line_end,forward,exact))); ! Find end of line
if mark_1 < mark(none) then ! If there was some data on the line
move_horizontal(-1); ! ...back off one character to leave EOL
endif;
line_range := create_range(mark_1,mark(none),BOLD); ! Select the current line (excluding EOL)
! (much faster if you use NONE instead of BOLD)
atg$process_line(line_range); ! Process the current line
position(mark_1); ! Go back to start of line
delete(line_range); ! Remove the range (else last line is BOLD)
move_horizontal(1); ! Move off of the BOL (or we will loop)
endloop;
position(beginning_of(current_buffer)); ! Move to start of buffer
atg$message('Finished formatting'); ! Say that we are done now
endprocedure
!
! ATG$PROCESS_LINE Process one line of buffer
!
! Only process lines which have some code and a complete comment, ie. the general format is:
! some-c-code /* a complete comment */
! This will leave comments blocked between sections of code alone.
! If the start of the comment is a lower case letter, upper case it.
! Try to position the comment between columns "k_comment_start" and "k_comment_end".
!
procedure atg$process_line(
line_range ) ! TPU range specifying the line to format.
local the_line , ! Code portion of the line
the_comment , ! Comment portion of the line
temp_1,temp_2,temp_3; ! Junk variables
constant k_tab_width := 8; ! Width of one tab
constant k_comment_start:= 9 * k_tab_width; ! Start of comment
constant k_comment_end := 14 * k_tab_width; ! End of comment field
constant x_comment_start:= "/*"; ! Start of a C comment
constant x_comment_end := "*/"; ! End of a C comment
update(current_window); ! Show where we are
the_line := str(line_range); ! Get a copy of the line to modify
edit(the_line,trim_trailing); ! Remove trailing spaces and tabs
temp_3 := the_line; ! Get a local copy of the line
edit(temp_3,collapse); ! Generate a clean line
temp_1 := index(temp_3,x_comment_start); ! Look for comment start
if temp_1 > 1 then ! If there was a comment start
temp_1 := index(the_line,x_comment_start); ! Look for comment start
temp_2 := index(the_line,x_comment_end); ! ...look for comment end
if temp_2 <> 0 then ! If there was a comment end...
! Extract and process the comment
the_comment := substr(the_line,temp_1+2,temp_2-temp_1-2); ! ...extract the comment
edit(the_comment,trim); ! Lose leading and trailing spaces
temp_3 := substr(the_comment,1,1); ! Look at first character of comment
if (temp_3 >= "a") and (temp_3 <= "z") then ! If it is a lower case alpha...
the_comment := ascii(ascii(temp_3)-32) + substr(the_comment,2,length(the_comment)-1);
endif;
! Extract and process the code
the_line := substr(the_line,1,temp_1-1); ! Lose comment from the line...
edit(the_line,trim_trailing); ! ...and trim line again
! Build final, formatted line
atg$pad_line_length(the_line,k_comment_start); ! Pad line to correct length
the_line := the_line + x_comment_start + " " + the_comment; ! Add in the comment start
atg$pad_line_length(the_line,k_comment_end); ! Pad line to correct length again
the_line := the_line + x_comment_end; ! Add the closing comment
! Replace the existing line with the formatted one in the current buffer
erase(line_range); ! Lose the current line...
position(line_range); ! Move to the start of the range
copy_text(the_line); ! Insert the new line
endif;
endif;
endprocedure
!
! ATG$PAD_LINE_LENGTH
!
! Pad the passed line to the specified length with TABs. If the line is already at or beyond
! the specified length, just add a SPACE.
! "length" in the context of this routine is actually the column position on the screen. This means
! that TABs are correctly accounted for.
!
procedure atg$pad_line_length(
the_line , ! Line of text to pad
the_length ) ! Length (column) to pad it to
local line_length,
temp_1;
constant tab := ascii(9); ! TAB character
line_length := 0; ! Start with line length of zero
temp_1 := 0; ! Count of character offset in line
loop
exitif temp_1 = length(the_line); ! Quit if last character
temp_1 := temp_1 + 1; ! Step to next character (first is 1)
if substr(the_line,temp_1,1) = tab then ! If character is a TAB then...
line_length := line_length + (8-(line_length and 7)); ! ...round up to next tab position
else
line_length := line_length + 1; ! ...else just add one character
endif;
endloop;
if line_length >= the_length then ! If we are already at the required length...
the_line := the_line + " "; ! ...just add a space
else
temp_1 := (the_length - (line_length and not 7))/8; ! Decide how many tabs are needed
loop
exitif temp_1 = 0; ! Stop if at the end
the_line := the_line + tab; ! Add in a tab
temp_1 := temp_1 - 1; ! One less tab to add
endloop;
endif;
endprocedure
define_key("atg$format_c", F9, "format C source"); ! Define a key to do formatting