************************************************************************ * ABAP Name: ZABAPDOC * * ABAP Description: Utility to document ABAP programs in HTML * * format. * * HTML File can be included into Word or Lotus * * Notes document or published on the Intranet. * * Created By: Kevin Neale * * Created On: July 3 2001 * * Version: 1.0 * ************************************************************************ * Modification Log: * *----------------------------------------------------------------------* * Date | Programmer | Correction | Description * * | | | * ************************************************************************ report zabapdoc message-id zf. ************************************************************************ * Tables * ************************************************************************ tables: trdir, "System table TRDIR dokhl, "Documentation: Headers dd17s. "R/3 S_SECINDEX: secondary indexes, fields ************************************************************************ * SELECTION SCREEN * ************************************************************************ selection-screen begin of block sel_block_1 with frame title text-001. selection-screen skip. select-options: s_pname for trdir-name no-extension no intervals obligatory. selection-screen skip. parameters: p_path(128) obligatory lower case, p_incld. selection-screen end of block sel_block_1. ************************************************************************ * DATA DECLARATIONS * ************************************************************************ *----------------------------------------------------------------------* * Internal Tables * *----------------------------------------------------------------------* * Used to hold the program to be generated. data: begin of it_program occurs 0, text(1024), key(5), keyname(30), progname like sy-repid, progline type i, end of it_program. * Used to hold the data ready for output to a local file. data: begin of it_output occurs 0, text(1024), end of it_output. * Used to hold ABAP keywords and flag for indentation. data: begin of it_keyword occurs 0, word(25), indent, end of it_keyword. * Used to hold the individual words in a statement. data: begin of it_words occurs 0, word(80), end of it_words. * Used to hold the literals position within a line. data: begin of it_lit occurs 0, start type i, end type i, end of it_lit. * Used to hold the critique comments. data: begin of it_messages occurs 0, progname like sy-repid, tabix(5) type n, text(128), end of it_messages. ************************************************************************ * Global Data Variables * ************************************************************************ data: vx_local, vx_literal, vx_start_statement, v_fill_space(2), v_make_space(2), v_text(1024), v_indent(280), vx_indent, vx_pend_indent, vx_hanging, v_line_count type i, v_keys_count type i, v_proc_count type i, v_filename like rlgrap-filename, v_comments(6) type p decimals 2, v_white_space type i. ************************************************************************ * CONSTANTS * ************************************************************************ constants: c_fill_chr type x value '07', c_form_key(3) value 'FRM', c_start_of_select_key(3) value 'SOS', c_end_of_select_key(3) value 'EOS', c_top_of_page(3) value 'TOP', c_at_line_select(3) value 'ALS', c_at_user_command(3) value 'AUC', c_init(3) value 'INI', c_at_select_scrn(3) value 'ASS', c_at_select_scrn_on(3) value 'ASO', c_perform_key(3) value 'PFM', c_endform_key(3) value 'EFM', c_comment_key(3) value 'CMT', c_head(6) value '', c_end_head(7) value '', c_title(7) value '', c_end_title(8) value '', c_body(6) value '', c_end_body(7) value '', c_html(6) value '', c_end_html(7) value '', c_tag_ref(10) value '', "Right angle bracket. c_tag_anchor(10) value ' 0. check v_temp+v_pos(1) eq space. endif. it_program-key = p_key. v_pos = sy-fdpos + v_keylen. v_text = v_temp+v_pos. shift v_text left deleting leading space. shift v_text left by 1 places. split v_text at c_fill_chr into it_program-keyname v_junk. modify it_program transporting key keyname. endif. endif. endloop. add 1 to v_proc_count. endform. " F_SET_KEY *&---------------------------------------------------------------------* *& Form F_OUTPUT *&---------------------------------------------------------------------* * Processes the program file using the keys already set up * and outputs the result. *----------------------------------------------------------------------* form f_output. perform f_open_output changing v_filename. perform f_output_forms. perform f_output_implementation. perform f_output_critique. endform. " F_OUTPUT *&---------------------------------------------------------------------* *& Form F_WRITE_OUTPUT *&---------------------------------------------------------------------* * Formats a line of text and places it into the output * internal table or writes it directly to a file. *----------------------------------------------------------------------* form f_write_output using value(p_text). it_output-text = p_text. translate it_output using v_make_space. if vx_local = cx_true. append it_output. else. transfer it_output to v_filename. endif. endform. " F_WRITE_OUTPUT *&---------------------------------------------------------------------* *& Form F_OPEN_OUTPUT *&---------------------------------------------------------------------* * Opens the output file if this is writing to the SAP machine * or sets the LOCAL flag to true if it is to a local file. *----------------------------------------------------------------------* form f_open_output changing p_filename. concatenate p_path s_pname-low '.html' into p_filename. if p_path(1) = '\' or p_path(1) = '/'. vx_local = space. open dataset p_filename for output in text mode message v_text. if sy-subrc ne 0. message e999 with 'Unable to open file.' v_text. endif. else. vx_local = cx_true. endif. endform. " F_OPEN_OUTPUT *&---------------------------------------------------------------------* *& Form F_WRITE_HEADER *&---------------------------------------------------------------------* * Writes the HTML header to the file. *----------------------------------------------------------------------* form f_write_header. perform f_write_output using c_html. perform f_write_output using c_head. perform f_write_output using c_title. concatenate 'ABAP Documentation for' c_fill_chr s_pname-low into v_text. perform f_write_output using v_text. perform f_write_output using c_end_title. move '' to v_text. perform f_write_output using v_text. perform f_write_output using c_end_head. perform f_write_output using c_body. concatenate '' to v_text. perform f_write_output using v_text. concatenate '

' c_para c_fill_chr 'ALIGN="CENTER"' c_rab c_tag_font c_fill_chr c_color c_fill_chr c_literal_color c_rab 'Documentation for ABAP program' c_fill_chr s_pname-low c_tag_endfont c_end_para '

' c_break into v_text. perform f_write_output using v_text. move c_end_table_def_tag to v_text. perform f_write_output using v_text. move c_end_table_row_tag to v_text. perform f_write_output using v_text. move c_table_row_tag to v_text. perform f_write_output using v_text. move '
' to v_text. perform f_write_output using v_text. concatenate '

' c_tag_font c_fill_chr c_color c_fill_chr c_literal_color c_rab 'There are three levels; The ABAP events,' c_fill_chr 'the form descriptions and the form implementation.' c_fill_chr 'Click on the form within an event or form description' c_fill_chr 'to read it' c_literal 's description. If the ABAP code has been' c_fill_chr 'written well with well chosen form names this should' c_fill_chr 'be a good overview of the program and how it works' c_fill_chr 'but you can then click on implementation to read' c_fill_chr 'the actual code (properly indented and colour coded)' c_fill_chr 'for each form.' c_tag_endfont c_end_para '

' c_break into v_text. perform f_write_output using v_text. move c_end_table_def_tag to v_text. perform f_write_output using v_text. move c_end_table_row_tag to v_text. perform f_write_output using v_text. move c_table_row_tag to v_text. perform f_write_output using v_text. move '

PROGRAM HEADER

' to v_text. perform f_write_output using v_text. concatenate 'Documentation by' to v_text. perform f_write_output using v_text. move '' to v_text. perform f_write_output using v_text. move '

Your Logo and Organisation Name


' to v_text. perform f_write_output using v_text. move '
www.A-Wizard.com.au
' to v_text. perform f_write_output using v_text. move c_end_table_def_tag to v_text. perform f_write_output using v_text. move c_end_table_row_tag to v_text. perform f_write_output using v_text. endform. " F_WRITE_HEADER *&---------------------------------------------------------------------* *& Form F_PRINT_EVENT *&---------------------------------------------------------------------* * Prints a line to the output file for any events used. *----------------------------------------------------------------------* form f_print_event using value(p_event). concatenate c_table_row_tag c_table_def_tag c_para c_rab c_tag_font c_fill_chr 'BORDER=5 BGCOLOR=' c_fill_chr c_bg_evnt_color c_fill_chr 'COLOR=' c_txt_event_color c_rab p_event c_end_table_def_tag c_end_table_row_tag into v_text. perform f_write_output using v_text. concatenate c_para c_rab into v_text. perform f_write_output using v_text. endform. " F_PRINT_EVENT *&---------------------------------------------------------------------* *& Form F_PRINT_FORM *&---------------------------------------------------------------------* * Prints details of a form with a reference (name) tag * to the HTML file. *----------------------------------------------------------------------* form f_print_form using value(p_save_loc). data: v_save_tabix like sy-tabix, v_save_keyname like it_program-keyname. v_save_tabix = sy-tabix - 1. v_save_keyname = it_program-keyname. concatenate c_table_tag c_fill_chr 'CELLPADDING=1 CELLSPACING=1' c_fill_chr 'BORDER=5 BGCOLOR=' c_bg_body_color c_fill_chr 'width=100%' c_rab into v_text. perform f_write_output using v_text. concatenate c_table_row_tag c_table_def_tag c_tag_ref v_save_keyname '"' c_rab c_break c_end_table_def_tag c_end_table_row_tag into v_text. perform f_write_output using v_text. if p_save_loc > 0. loop at it_program from p_save_loc to v_save_tabix. shift it_program-text left. concatenate c_table_row_tag c_table_def_tag it_program-text c_break c_end_table_def_tag c_end_table_row_tag into v_text. perform f_write_output using v_text. endloop. endif. concatenate c_table_row_tag c_table_def_tag c_tag_anchor v_save_keyname '_imp"' c_rab 'Implementation' c_endtag_anchor c_end_table_def_tag c_end_table_row_tag into v_text. perform f_write_output using v_text. endform. " F_PRINT_FORM *&---------------------------------------------------------------------* *& Form F_PRINT_PERFORM *&---------------------------------------------------------------------* * Prints a line with an anchor tag for any perform statement. *----------------------------------------------------------------------* form f_print_perform using p_tabix. data: vx_first_line, vx_last_line, v_len type i. concatenate c_table_row_tag c_table_def_tag c_para c_rab c_tag_anchor it_program-keyname '"' c_rab 'Perform' c_fill_chr it_program-keyname c_endtag_anchor c_end_table_def_tag c_end_table_row_tag into v_text. perform f_write_output using v_text. vx_first_line = cx_true. loop at it_program from p_tabix. if it_program-text cs '.'. vx_last_line = cx_true. endif. if vx_first_line = cx_true. shift it_program-text left deleting leading space. v_len = strlen( it_program-keyname ) + 8. shift it_program-text left by v_len places. endif. v_len = strlen( it_program-text ). if v_len > 1. concatenate c_table_row_tag c_table_def_tag it_program-text c_break c_end_table_def_tag c_end_table_row_tag into v_text. perform f_write_output using v_text. endif. if vx_last_line = cx_true. exit. endif. endloop. endform. " F_PRINT_PERFORM *&---------------------------------------------------------------------* *& Form F_PRINT_LAST *&---------------------------------------------------------------------* * Prints the end of the HTML document. *----------------------------------------------------------------------* form f_print_last. perform f_write_output using c_end_table_tag. perform f_write_output using c_end_body. perform f_write_output using c_end_html. endform. " F_PRINT_LAST *&---------------------------------------------------------------------* *& Form F_SET_UP *&---------------------------------------------------------------------* * Set up the program *----------------------------------------------------------------------* form f_set_up. data: v_pos type i. select distinct object into table it_keyword from dokhl where id = 'SD' and object like 'ABAP%' and langu eq 'E'. loop at it_keyword. shift it_keyword-word left by 4 places. case it_keyword-word. * Indent the line following the next full-stop. when 'SELECT' or 'IF' or 'FORM' or 'LOOP' OR 'CALL'. it_keyword-indent = '+'. when 'DO' or 'WHILE'. it_keyword-indent = '+'. * Outdent from this line. when 'ENDSELECT' or 'ENDIF' or 'ENDFORM' or 'ENDLOOP' or 'ENDDO' or 'WHEN'. it_keyword-indent = '-'. when 'ENDCASE' or 'END'. it_keyword-indent = '-'. * Indent from the next line. when 'BEGIN'. " OR 'CASE'. it_keyword-indent = 'h'. * Outdent this line and indent the next line after the full-stop. when 'ELSEIF' or 'ELSE' or 'TABLES' or 'EXCEPTIONS'. it_keyword-indent = 'k'. when 'FROM_CLAUSE'. it_keyword-word = 'FROM'. when 'INTO_CLAUSE'. it_keyword-word = 'INTO'. endcase. modify it_keyword. endloop. it_keyword-word = 'AND'. it_keyword-indent = space. append it_keyword. it_keyword-word = 'EXCEPTIONS'. it_keyword-indent = space. append it_keyword. sort it_keyword. concatenate space c_fill_chr into v_fill_space. concatenate c_fill_chr space into v_make_space. v_pos = strlen( p_path ) - 1. if p_path+v_pos(1) ne '\'. concatenate p_path '\' into p_path. endif. endform. " F_INITIALISE *&---------------------------------------------------------------------* *& Form F_HIGHLIGHT_KEYWORD *&---------------------------------------------------------------------* * Highlight key words within the program code *----------------------------------------------------------------------* form f_highlight_keywords. data: vx_comment, vx_newline, v_pos type i, v_len type i, v_end type i, v_text_begin(128), v_text_keyword(128), v_text_end(128), v_word(150), v_junk, v_cur_indent. statics: v_tabix like sy-tabix. shift it_program-text left deleting leading space. split it_program-text at space into v_word v_junk. translate v_word using '. '. translate v_word using ': '. translate v_word to upper case. read table it_keyword with key word = v_word. if sy-subrc eq 0. v_cur_indent = it_keyword-indent. endif. if it_program-text(1) = '*'. concatenate c_tag_font c_fill_chr 'color=' c_comment_color c_rab it_program-text c_tag_endfont c_break into it_program-text. exit. endif. v_pos = strlen( it_program-text ). check v_pos > 0. split it_program-text at space into table it_words. delete it_words where word = ''. v_text = it_program-text. translate v_text using v_fill_space. move v_text(v_pos) to it_program-text. clear vx_literal. loop at it_words. if vx_literal = cx_true. if it_words-word cs c_literal. clear vx_literal. endif. continue. endif. if it_words-word cs c_literal. vx_literal = cx_true. continue. endif. v_tabix = sy-tabix. v_word = it_words-word. translate v_word using '. '. translate v_word using ': '. translate v_word to upper case. perform f_remove_formatting changing v_word. read table it_keyword with key word = v_word. if sy-subrc = 0. if it_program-text cs it_words-word. v_pos = sy-fdpos. v_len = strlen( it_words-word ). v_end = v_pos + v_len. if v_pos > 0. concatenate it_program-text(v_pos) c_fill_chr into v_text_begin. else. clear v_text_begin. endif. v_text_keyword = it_program-text+v_pos(v_len). v_text_end = it_program-text+v_end. concatenate v_text_begin "c_fill_chr c_tag_font c_fill_chr 'color=' c_keyword_color c_rab v_text_keyword c_fill_chr c_tag_endfont v_text_end into it_program-text. endif. endif. translate it_words-word to upper case. if it_words-word eq 'TABLE' or it_words-word eq 'SINGLE'. clear: vx_pend_indent, v_cur_indent. endif. endloop. v_len = strlen( it_program-text ). if v_len gt 0. perform f_check_indent using v_tabix v_cur_indent. concatenate v_indent it_program-text c_break into it_program-text. endif. * If the line contains an inline comment and is not a literal. if it_program-text cs '"' and vx_literal ne cx_true. v_pos = sy-fdpos. if v_pos > 0. v_text_begin = it_program-text(v_pos). else. clear v_text_begin. endif. v_text_end = it_program-text+v_pos. perform f_check_indent using v_tabix v_cur_indent. concatenate v_text_begin "c_fill_chr c_tag_font c_fill_chr 'color=' c_comment_color c_rab v_text_end c_tag_endfont into it_program-text. endif. endform. " F_HIGHLIGHT_KEYWORD *&---------------------------------------------------------------------* *& Form F_SET_UP_KEYS *&---------------------------------------------------------------------* * Set up the Keys to be used during code parsing *----------------------------------------------------------------------* form f_set_up_keys. v_keys_count = v_line_count * 11. v_proc_count = 0. perform f_set_key using: 'ENDFORM' c_endform_key, 'PERFORM' c_perform_key, 'FORM' c_form_key, 'INITIALIZATION' c_init, 'AT SELECTION-SCREEN ON' c_at_select_scrn_on, 'AT SELECTION-SCREEN' c_at_select_scrn, 'START-OF-SELECTION' c_start_of_select_key, 'END-OF-SELECTION' c_end_of_select_key, 'TOP-OF-PAGE' c_top_of_page, 'AT LINE-SELECTION' c_at_line_select, 'AT USER-COMMAND' c_at_user_command. endform. " F_SET_UP_KEYS *&---------------------------------------------------------------------* *& Form F_CHECK_INDENT *&---------------------------------------------------------------------* * Check the indent for the implentation code *----------------------------------------------------------------------* form f_check_indent using value(p_tabix) value(p_indent). data: v_word(80), v_tabix like sy-tabix. statics: sx_select_in_progress. if vx_indent = cx_true. perform f_modify_indent using '+' changing v_indent. clear vx_indent. endif. if vx_pend_indent = cx_true. read table it_words index p_tabix. if it_words cs '.'. vx_indent = cx_true. clear vx_pend_indent. endif. read table it_words index v_tabix. endif. if p_indent = '+' or p_indent = 'h' or p_indent = 'k'. v_tabix = p_tabix. describe table it_words. if p_tabix <= sy-tfill. read table it_words index p_tabix. if it_words cs '.'. vx_indent = cx_true. else. vx_pend_indent = cx_true. endif. read table it_words index v_tabix. endif. endif. if p_indent = 'h'. if vx_hanging eq cx_true. perform f_modify_indent using '-' changing v_indent. vx_indent = cx_true. endif. vx_indent = cx_true. vx_hanging = cx_true. endif. if p_indent = 'i'. if vx_hanging eq cx_true. perform f_modify_indent using '-' changing v_indent. perform f_modify_indent using '-' changing v_indent. clear vx_indent. clear vx_hanging. endif. endif. if p_indent = '-'. perform f_modify_indent using '-' changing v_indent. endif. if p_indent = 'k'. perform f_modify_indent using '-' changing v_indent. vx_indent = cx_true. endif. endform. " F_CHECK_INDENT *&---------------------------------------------------------------------* *& Form F_PRINT_COMMENT *&---------------------------------------------------------------------* * Write out a comment to the HTML file *----------------------------------------------------------------------* form f_print_comment. concatenate c_table_row_tag c_table_def_tag c_para c_rab it_program-text c_end_table_def_tag c_end_table_row_tag into v_text. perform f_write_output using v_text. endform. " F_PRINT_COMMENT *&---------------------------------------------------------------------* *& Form F_PARSE_LINE *&---------------------------------------------------------------------* * Sort out the comments and the literals from the program line. *----------------------------------------------------------------------* form f_parse_line using p_text changing v_temp_prog. data: v_pos type i, v_text_begin(128), v_build_prog(70), v_text_end(128), begin of it_temp_prog occurs 0, text(70), end of it_temp_prog. * Check for a comment line. check it_program-text(1) ne c_asterisk. * Translate to lower case for consistency. translate it_program-text to lower case. * Save the program line into a temp variable. v_temp_prog = it_program-text. clear v_build_prog. * Check for literals and remove them temporarily. while v_temp_prog cs c_literal. * Update sy-fdpos. if v_temp_prog cs c_literal. endif. if sy-fdpos > 0. v_pos = sy-fdpos. * If this is a new literal take the code before it... if vx_literal is initial. vx_literal = cx_true. concatenate v_build_prog v_temp_prog(v_pos) into v_build_prog. shift v_temp_prog left by v_pos places. shift v_temp_prog left by 1 places. * ...otherwise take the code after it. else. clear vx_literal. add 1 to v_pos. concatenate v_build_prog v_temp_prog+v_pos into v_build_prog. shift v_temp_prog left by v_pos places. endif. else. v_temp_prog = ''. endif. endwhile. if not v_build_prog is initial. v_temp_prog = v_build_prog. endif. clear v_build_prog. * Check for inline comments and remove them temporarily. if v_temp_prog cs c_inline_comment. v_pos = sy-fdpos. if v_pos > 0. v_temp_prog = v_temp_prog(v_pos). endif. endif. * Replace spaces with unprintable character X07 so that a word search * can be performed. perform f_translate using space c_fill_chr v_temp_prog. endform. " F_PARSE_LINE *&---------------------------------------------------------------------* *& Form f_remove_formatting *&---------------------------------------------------------------------* * Remove the formatting characters from the text *----------------------------------------------------------------------* form f_remove_formatting changing p_word. data: v_len type i, v_count type i. v_len = strlen( p_word ). if v_len > 1. while p_word(1) = '<'. while p_word(1) <> '>' and v_count < 80. shift p_word left. add 1 to v_count. endwhile. shift p_word left. endwhile. endif. endform. " f_remove_formatting *&---------------------------------------------------------------------* *& Form f_output_forms *&---------------------------------------------------------------------* * Add the FORM to the HTML file *----------------------------------------------------------------------* form f_output_forms. data: v_save_loc like sy-tabix, v_tabix like sy-tabix, vx_prog_header. vx_prog_header = cx_true. loop at it_program. v_tabix = sy-tabix. at first. perform f_write_header. move c_table_row_tag to v_text. perform f_write_output using v_text. move '
' to v_text. perform f_write_output using v_text. endat. if vx_prog_header = cx_true. perform f_program_header changing vx_prog_header. endif. if it_program-text(1) = '*' and v_save_loc is initial. v_save_loc = sy-tabix. endif. case it_program-key. when c_start_of_select_key. perform f_print_event using 'START OF SELECTION'. when c_at_select_scrn. perform f_print_event using 'AT SELECTION SCREEN'. when c_at_select_scrn_on. perform f_print_event using 'AT SELECTION SCREEN ON'. when c_end_of_select_key. perform f_print_event using 'END OF SELECTION'. when c_top_of_page. perform f_print_event using 'TOP OF PAGE'. when c_at_line_select. perform f_print_event using 'AT LINE SELECT'. when c_at_user_command. perform f_print_event using 'AT USER COMMAND'. when c_init. perform f_print_event using 'INITIALIZATION'. when c_perform_key. perform f_print_perform using v_tabix. when c_form_key. perform f_print_form using v_save_loc. when c_endform_key. perform f_write_output using c_end_table_tag. concatenate c_para c_rab into v_text. perform f_write_output using v_text. when c_comment_key. perform f_print_comment. endcase. if it_program-text(1) ne '*'. clear v_save_loc. endif. endloop. endform. " f_output_forms *&---------------------------------------------------------------------* *& Form f_output_implementation *&---------------------------------------------------------------------* * Add the implementation to the HTML file *----------------------------------------------------------------------* form f_output_implementation. data: vx_output_form. loop at it_program. if it_program-key = c_form_key. concatenate c_table_tag c_fill_chr 'CELLPADDING=1 CELLSPACING=1' c_fill_chr 'BORDER=2 BGCOLOR=' c_bg_impl_color c_fill_chr 'width=100%' c_rab into v_text. perform f_write_output using v_text. vx_output_form = cx_true. concatenate c_table_row_tag c_table_def_tag c_tag_ref it_program-keyname '_imp"' c_rab c_endtag_anchor "c_end_table_def_tag c_end_table_row_tag into v_text. perform f_write_output using v_text. endif. if vx_output_form = cx_true. perform f_highlight_keywords. translate it_program-text to lower case. perform f_write_output using it_program-text. endif. if it_program-key = c_endform_key. vx_output_form = space. concatenate c_end_table_def_tag c_end_table_row_tag c_end_table_tag into v_text. clear: v_indent. perform f_write_output using v_text. concatenate c_para c_rab into v_text. perform f_write_output using v_text. endif. endloop. perform f_write_output using v_text. perform f_print_last. if vx_local = cx_true. call function 'WS_DOWNLOAD' exporting filename = v_filename filetype = 'ASC' tables data_tab = it_output exceptions file_open_error = 1 file_write_error = 2 invalid_filesize = 3 invalid_table_width = 4 invalid_type = 5 no_batch = 6 unknown_error = 7 others = 8. if sy-subrc ne 0. message id sy-msgid type sy-msgty number sy-msgno with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. endif. else. close dataset v_filename. endif. endform. " f_output_implementation *&---------------------------------------------------------------------* *& Form f_output_critique *&---------------------------------------------------------------------* * Print the critique *----------------------------------------------------------------------* form f_output_critique. data: vx_constants, vx_parameters, vx_done, vx_select, vx_where, vx_key_found, v_table_name like dd03l-fieldname, junk, v_pos type i, v_keyflag, v_field_count type i, v_text(256), v_test(256), v_tabix_start like sy-tabix, begin of tbl_fields occurs 0, field like dd03l-fieldname, end of tbl_fields. loop at it_program. perform f_user1. clear: vx_done, it_lit[]. * Ignore comment and blank lines first. it_messages-tabix = it_program-progline. it_messages-progname = it_program-progname. if it_program-text(1) = '*'. add 1 to v_comments. continue. endif. if it_program-text = space. add 1 to v_white_space. continue. endif. * Find the location of any literals. v_pos = 0. while v_pos < 128 and vx_done is initial. if it_program-text+v_pos cs c_literal. it_lit-start = v_pos + sy-fdpos. v_pos = it_lit-start + 1. if it_program-text+v_pos cs c_literal. it_lit-end = v_pos + sy-fdpos. v_pos = it_lit-end + 1. else. vx_done = cx_true. endif. append it_lit. else. vx_done = cx_true. endif. endwhile. * Check for inline comments. if it_program-text cs c_inline_comment. v_pos = sy-fdpos. perform f_check_literals changing v_pos. if v_pos > 0. it_program-text = it_program-text(sy-fdpos). endif. add '0.5' to v_comments. endif. * Convert the text to lowercase. translate it_program-text to lower case. * Check the constants switch. if it_program-text cs 'constants'. v_pos = sy-fdpos - 1. if v_pos < 0 or it_program-text+v_pos(1) = space. add 1 to v_pos. perform f_check_literals changing v_pos. if v_pos > -1. move cx_true to vx_constants. endif. endif. endif. * Check the parameters switch. if it_program-text cs 'parameters'. move cx_true to vx_parameters. endif. * Check for "Select *". if it_program-text cs 'select *'. v_pos = sy-fdpos. perform f_check_literals changing v_pos. if v_pos > -1. move 'select * - It is better to specify the fields required.'(101) to it_messages-text. endif. append it_messages. endif. * Save the last table name being accessed. if it_program-text cs 'from'. v_pos = sy-fdpos + 5. v_table_name = it_program-text+v_pos. shift v_table_name left deleting leading space. split v_table_name at space into v_table_name junk. translate v_table_name to upper case. endif. * Switch on the select clause flag. shift it_program-text left deleting leading space. split it_program-text at space into v_test junk. if v_test eq 'select '. vx_select = cx_true. clear: vx_key_found, v_field_count. endif. * Switch on the where clause flag. if it_program-text cs 'where '. vx_where = cx_true. endif. * Check key access to tables. if vx_where eq cx_true and vx_select eq cx_true. clear vx_key_found. split it_program-text at space into table tbl_fields. delete tbl_fields where field eq space. loop at tbl_fields. if tbl_fields cs '~'. v_pos = sy-fdpos + 1. tbl_fields = tbl_fields+v_pos. endif. translate tbl_fields to upper case. select keyflag up to 1 rows into v_keyflag from dd03l where tabname eq v_table_name and fieldname eq tbl_fields-field. endselect. if sy-subrc eq 0. if v_keyflag eq space. select indexname position up to 1 rows into (dd17s-indexname, dd17s-position) from dd17s where sqltab eq v_table_name and fieldname eq tbl_fields-field. endselect. if dd17s-position > '0002'. add 1 to v_field_count. if v_field_count = 1. move 'first select field ought to be a key field.'(105) to it_messages-text. append it_messages. endif. else. vx_key_found = cx_true. endif. else. vx_key_found = cx_true. endif. endif. endloop. endif. * Switch off the where clause and select clause flag. if it_program-text cs '.'. if vx_where = cx_true. clear vx_where. endif. if vx_select = cx_true. clear vx_select. if vx_key_found is initial. concatenate 'key field not used for select statement on'(104) v_table_name into it_messages-text separated by space. append it_messages. endif. endif. endif. * Check for literals. if it_program-text cs c_literal and vx_constants is initial and vx_parameters is initial. v_pos = sy-fdpos + 1. v_text = it_program-text+v_pos. * Ignore call function literal name. if it_program-text cs 'call' and it_program-text cs 'function'. continue. endif. * Ignore set cursor field. if it_program-text cs 'set cursor field'. continue. endif. if v_text cs c_literal. v_pos = v_pos + sy-fdpos + 1. if it_program-text+v_pos(1) eq '(' and it_program-text+v_pos(5) cs ')'. "Text has been copied to textpool." else. move 'literals should be put in the textpool or a constant.' to it_messages-text. append it_messages. endif. else. move 'text should not expand across two lines.' to it_messages-text. append it_messages. endif. endif. * Check for end of constants or parameters. if it_program-text cs '.'. v_pos = strlen( it_program-text ) - 1. if sy-fdpos = v_pos. if vx_constants eq cx_true. v_pos = sy-fdpos. perform f_check_literals changing v_pos. if v_pos > -1. clear vx_constants. endif. elseif vx_parameters eq cx_true. clear vx_parameters. endif. endif. endif. perform f_user2. endloop. endform. " f_output_critique *&---------------------------------------------------------------------* *& Form f_print_report *&---------------------------------------------------------------------* * Print the audit report *----------------------------------------------------------------------* form f_print_report. data: v_comment_pcent(4) type p decimals 2, v_white_space_pcent(4) type p decimals 2, v_messages type i. loop at it_messages. at first. write at: /001 'Program', 031 'Line', 038 'Comment'. endat. at new progname. write at: /001 it_messages-progname. endat. write at: /031 it_messages-tabix, 038 it_messages-text. endloop. describe table it_messages lines v_messages. describe table it_program. if sy-tfill ne 0. v_comment_pcent = v_comments * 100 / sy-tfill. v_white_space_pcent = v_white_space * 100 / sy-tfill. skip 2. write at: /001 'Number of critique points:', 030 v_messages, /001 'Number of program lines:', 030 sy-tfill, /001 'Percent of comments:', 030 v_comment_pcent, /001 'Percent of white space:', 030 v_white_space_pcent. endif. endform. " f_print_report *&---------------------------------------------------------------------* *& Form f_check_literals *&---------------------------------------------------------------------* * Check for literals within then code *----------------------------------------------------------------------* form f_check_literals changing p_pos. loop at it_lit. if p_pos > it_lit-start and p_pos < it_lit-end. p_pos = -1. exit. endif. endloop. endform. " f_check_literals *&---------------------------------------------------------------------* *& Form f_fetch_includes *&---------------------------------------------------------------------* * Fetch any includes and insert them into the main program. * Search through the code looking for the key word INCLUDE but * first remove any literals and inline comments in order to * avoid picking up invalid lines. *----------------------------------------------------------------------* FORM f_fetch_includes. data: v_tabix like sy-tabix, v_pos like sy-fdpos, v_temp_prog(70), v_include(70), v_junk, v_line_number type i, it_temp(70) occurs 0. loop at it_program. perform f_parse_line using it_program-text changing v_temp_prog. * Test for an include. if v_temp_prog cs 'include'. v_pos = sy-fdpos + 8. v_include = v_temp_prog+v_pos. perform f_translate using c_fill_chr space v_include. shift v_include left deleting leading space. split v_include at space into v_include v_junk. v_pos = strlen( v_include ) - 1. if v_include+v_pos = '.'. v_include = v_include(v_pos). endif. translate v_include to lower case. if v_include ne 'structure'. read report v_include into it_temp. describe table it_temp. if sy-tfill > 0. add 1 to v_tabix. insert lines of it_temp into it_program index v_tabix. concatenate 'Reading' v_include into v_text separated by space. perform f_show_progress using -1 v_text. subtract 1 from v_tabix. clear v_line_number. loop at it_program where progname eq space. v_line_number = v_line_number + 1. it_program-progline = v_line_number. modify it_program transporting progline. endloop. it_program-progname = v_include. modify it_program transporting progname where progname = space. endif. endif. endif. endloop. ENDFORM. " f_fetch_includes form f_show_progress using value(p_percent_complete) type i value(p_message_text). data: v_status_text(50), v_percent(3). if p_percent_complete gt -1. move p_percent_complete to v_percent. concatenate p_message_text ':' v_percent '% complete' into v_status_text separated by space. * Change to update the progress meter after reaching the value. if p_percent_complete > 4. p_percent_complete = p_percent_complete - 4. endif. else. move p_message_text to v_status_text. endif. call function 'SAPGUI_PROGRESS_INDICATOR' exporting percentage = p_percent_complete text = v_status_text exceptions others = 1. endform. "F_SHOW_PROGRESS *&---------------------------------------------------------------------* *& Form f_read_program *&---------------------------------------------------------------------* * Read the main program into internal table it_program. *----------------------------------------------------------------------* FORM f_read_program. concatenate 'Reading' s_pname-low into v_text separated by space. perform f_show_progress using -1 v_text. read report s_pname-low into it_program. it_program-progname = s_pname-low. modify it_program transporting progname where progname = space. loop at it_program. it_program-progline = sy-tabix. modify it_program transporting progline. endloop. if not p_incld is initial. perform f_fetch_includes. endif. ENDFORM. " f_read_program *&---------------------------------------------------------------------* *& Form f_translate *&---------------------------------------------------------------------* * Replace one character with an unprintable character such as X07 * the SAP translate does not work here. *----------------------------------------------------------------------* FORM f_translate using p_from p_to changing p_object. data: begin of it_temp occurs 0, text(256), end of it_temp, v_len type i. split p_object at p_from into table it_temp. delete it_temp where text = space. clear p_object. loop at it_temp. concatenate p_object it_temp p_to into p_object. endloop. ENDFORM. " f_translate *&---------------------------------------------------------------------* *& Form f_modify_indent *&---------------------------------------------------------------------* * Change the indentation. Either increase or decrease. *----------------------------------------------------------------------* FORM f_modify_indent USING p_in_out changing p_indent. data: v_pos type i, v_len type i. v_len = strlen( c_nbsp ). if p_in_out = '+'. do c_indent times. concatenate p_indent c_nbsp into p_indent. enddo. else. v_pos = ( ( strlen( p_indent ) / v_len ) - c_indent ) * v_len. if v_pos > 0. p_indent = p_indent(v_pos). else. p_indent = ''. endif. endif. ENDFORM. " f_modify_indent *&---------------------------------------------------------------------* *& Form f_program_header. *&---------------------------------------------------------------------* * Create the Program Header in the HTML document. *----------------------------------------------------------------------* FORM f_program_header changing px_prog_header. data: v_len type i, v_pos type i, v_pos1 type i, v_xlate(2). v_len = strlen( it_program-text ). if v_len > 0 and it_program-text(1) <> c_asterisk. if it_program-text cs 'REPORT' or it_program-text cs 'LINE-SIZE' or it_program-text cs 'LINE-COUNT' or it_program-text cs 'STANDARD PAGE HEADING' or it_program-text cs 'MESSAGE-ID'. else. move c_end_table_tag to v_text. perform f_write_output using v_text. concatenate c_table_tag c_fill_chr 'CELLPADDING=0' c_fill_chr 'CELLSPACING=0' c_fill_chr 'BORDER=5 BGCOLOR=' c_fill_chr c_bg_header_color c_fill_chr 'WIDTH=100%' c_rab into v_text. perform f_write_output using v_text. clear px_prog_header. endif. else. perform f_translate using space c_nbsp it_program-text. concatenate it_program-text c_break into v_text. perform f_write_output using v_text. endif. ENDFORM. " f_program_header include zabapdo1.