! 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