2017 Sep 20 8:43 AM
i have some thousands of lines in my code, so i need to know the flow of my program, apart from debugging, if so how can i achive that.
2017 Sep 20 10:04 AM
My method for getting to grips with a large program involves eyes, pencil, paper, coffee.
2017 Sep 20 10:04 AM
My method for getting to grips with a large program involves eyes, pencil, paper, coffee.
2017 Sep 20 10:45 AM
2017 Sep 20 10:46 AM
Apart from debugging.. read out line by line and pen down.. connect the dots manually to build the flow!! That's I can think of now!!
2017 Sep 21 5:22 PM
Hello,
You may find some ideas in this raw example. This program reads source code recursively in includes and function module called (no method explorer yet) where it search for some statements key words to create blocs by level.
Just copy paste in a new local test program 🙂
REPORT ztest_code_reader.
*----------------------------------------------------------------------*
* CLASS lcl_code_reader DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_code_reader DEFINITION.
PUBLIC SECTION.
TYPES : BEGIN OF tt_count,
report TYPE programm,
count TYPE i,
END OF tt_count.
DATA oref TYPE REF TO cl_demo_output_stream.
DATA t_count TYPE TABLE OF tt_count.
DATA max_level TYPE i.
DATA level TYPE i.
DATA display_include TYPE c.
DATA stop_detail. " When TRUE : no need to detailed (until FALSE)
METHODS :
analyse IMPORTING report TYPE programm,
check_statement IMPORTING line TYPE string,
display.
METHODS constructor IMPORTING maxlvl TYPE i.
ENDCLASS. "lcl_code_reader DEFINITION
*----------------------------------------------------------------------*
* CLASS lcl_code_reader IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_code_reader IMPLEMENTATION.
METHOD constructor.
oref = cl_demo_output_stream=>open( ).
SET HANDLER cl_demo_output_html=>handle_output FOR oref.
cl_demo_output_html=>set_display( abap_true ).
max_level = maxlvl.
level = 1.
display_include = abap_false.
ENDMETHOD. "constructor
METHOD analyse.
DATA t_code TYPE TABLE OF string.
FIELD-SYMBOLS <code> LIKE LINE OF t_code.
DATA w_s TYPE string.
DATA w_level LIKE level.
IF level IS INITIAL.
w_level = 1.
ELSE.
w_level = level.
ENDIF.
FIELD-SYMBOLS <count> LIKE LINE OF t_count.
READ TABLE t_count WITH KEY report = report ASSIGNING <count>.
IF sy-subrc IS NOT INITIAL.
APPEND INITIAL LINE TO t_count ASSIGNING <count>.
<count>-report = report.
<count>-count = 1.
READ REPORT report INTO t_code.
LOOP AT t_code ASSIGNING <code>.
CHECK <code> is NOT INITIAL.
check_statement( EXPORTING line = <code> ).
ENDLOOP.
ELSE.
ADD 1 TO <count>-count.
w_s = <count>-count.
CONCATENATE '(n°' w_s ') ' report INTO w_s SEPARATED BY space.
oref->write_text( iv_text = w_s
iv_format = if_demo_output_formats=>nonprop ).
ENDIF.
ENDMETHOD. "analyse
METHOD check_statement.
DATA w_line(1023).
w_line = line.
CONDENSE w_line.
TRANSLATE w_line TO UPPER CASE.
DATA w_next_prog TYPE programm.
DATA w_fin TYPE i.
DATA w_s TYPE string.
*--------------------------------------------------------------------*
* Analyse include
IF w_line(8) = 'INCLUDE '
AND w_line(18) <> 'INCLUDE STRUCTURE '.
w_next_prog = w_line+8.
FIND '.' IN w_next_prog MATCH OFFSET w_fin.
w_next_prog = w_next_prog(w_fin).
IF level < max_level.
ADD 1 TO level.
analyse( EXPORTING report = w_next_prog ).
SUBTRACT 1 FROM level.
ELSE.
IF display_include = abap_true AND stop_detail = abap_false.
w_s = max_level + 1.
CONCATENATE w_s ') Include ' w_next_prog INTO w_s SEPARATED BY space.
oref->write_text( iv_text = w_s
iv_format = if_demo_output_formats=>nonprop ).
ENDIF.
ENDIF.
*--------------------------------------------------------------------*
* Analyse Call function
ELSEIF w_line(14) = 'CALL FUNCTION ' AND stop_detail = abap_false.
w_next_prog = w_line+14.
REPLACE ALL OCCURRENCES OF '''' IN w_next_prog WITH ''.
IF level < max_level.
ADD 1 TO level.
data w_INCLUDE type RS38L-INCLUDE.
w_s = level.
CONCATENATE w_s ') Call Function ' w_next_prog into w_s SEPARATED BY space.
oref->write_text( iv_text = w_s
iv_format = if_demo_output_formats=>heading ).
CALL FUNCTION 'FUNCTION_INCLUDE_INFO'
IMPORTING
PNAME = w_next_prog
CHANGING
INCLUDE = w_INCLUDE
EXCEPTIONS
FUNCTION_NOT_EXISTS = 1
INCLUDE_NOT_EXISTS = 2
GROUP_NOT_EXISTS = 3
NO_SELECTIONS = 4
NO_FUNCTION_INCLUDE = 5
OTHERS = 6.
analyse( EXPORTING report = w_INCLUDE ).
SUBTRACT 1 FROM level.
ELSE.
w_s = max_level + 1.
CONCATENATE w_s ') Call function ' w_next_prog INTO w_s SEPARATED BY space.
oref->write_text( iv_text = w_s
iv_format = if_demo_output_formats=>nonprop ).
ENDIF.
*--------------------------------------------------------------------*
* Analyse Call method
ELSEIF w_line(14) = 'CALL METHOD ' AND stop_detail = abap_false.
w_s = w_line.
oref->write_text( iv_text = w_s
iv_format = if_demo_output_formats=>nonprop ).
*--------------------------------------------------------------------*
* Analyse perform
ELSEIF w_line(8) = 'PERFORM ' AND stop_detail = abap_false.
w_s = w_line.
oref->write_text( iv_text = w_s
iv_format = if_demo_output_formats=>nonprop ).
*--------------------------------------------------------------------*
* Détection bloc
ELSEIF w_line(15) = 'INITIALIZATION.'
OR w_line(19) = 'AT SELECTION-SCREEN'
OR w_line(16) = 'LOAD-OF-PROGRAM.'
OR w_line(19) = 'START-OF-SELECTION.'
OR ( w_line(4) = 'GET ' AND w_line+4(4) <> 'REFE'
AND w_line+4(4) <> 'PARA'
AND w_line+4(3) <> 'BIT'
AND w_line+4(4) <> 'CURS' )
OR w_line(17) = 'END-OF-SELECTION.'
.
stop_detail = abap_false.
CONCATENATE '<hr/><h3><center>' w_line '</center></h3>' INTO w_s.
oref->write_html( iv_html = w_s ).
*--------------------------------------------------------------------*
* Détection form
ELSEIF w_line(5) = 'FORM '.
ADD 1 TO level.
stop_detail = abap_true.
ELSEIF w_line(8) = 'ENDFORM.'.
stop_detail = abap_false.
SUBTRACT 1 FROM level.
*--------------------------------------------------------------------*
* Détection macro
ELSEIF w_line(7) = 'DEFINE '.
ADD 1 TO level.
stop_detail = abap_true.
ELSEIF w_line(18) = 'END-OF-DEFINITION.'.
stop_detail = abap_false.
SUBTRACT 1 FROM level.
*--------------------------------------------------------------------*
* Détection DO
ELSEIF w_line(3) = 'DO ' AND stop_detail = abap_false.
ADD 1 TO level.
w_s = level.
CONCATENATE w_s ')' w_line INTO w_s SEPARATED BY space.
oref->write_text( iv_text = w_s
iv_format = if_demo_output_formats=>nonprop ).
ELSEIF w_line(6) = 'ENDDO.' AND stop_detail = abap_false.
SUBTRACT 1 FROM level.
*--------------------------------------------------------------------*
* Détection LOOP
ELSEIF w_line(5) = 'LOOP ' AND stop_detail = abap_false.
ADD 1 TO level.
w_s = level.
CONCATENATE w_s ')' w_line INTO w_s SEPARATED BY space.
oref->write_text( iv_text = w_s
iv_format = if_demo_output_formats=>nonprop ).
ELSEIF w_line(8) = 'ENDLOOP.' AND stop_detail = abap_false.
SUBTRACT 1 FROM level.
*--------------------------------------------------------------------*
* Détection CLASS
ELSEIF w_line(6) = 'CLASS ' AND stop_detail = abap_false." AND started = abap_true.
ADD 1 TO level.
stop_detail = abap_true.
ELSEIF w_line(9) = 'ENDCLASS.' AND stop_detail = abap_false.
stop_detail = abap_false.
SUBTRACT 1 FROM level.
ENDIF.
*--------------------------------------------------------------------*
* Others analyses ...
DATA w_comm TYPE i.
DATA w_line_sans_comm LIKE w_line.
FIND '"' IN w_line MATCH OFFSET w_comm.
IF w_comm > 0.
w_line_sans_comm = w_line(w_comm).
ELSE.
w_line_sans_comm = w_line.
ENDIF.
* Call stastic method
IF w_line_sans_comm CS '=>' AND w_line_sans_comm(1) CN '*"' AND stop_detail = abap_false.
w_s = level.
CONCATENATE w_s ')' w_line INTO w_s SEPARATED BY space.
oref->write_text( iv_text = w_s
iv_format = if_demo_output_formats=>nonprop ).
* Call implemented method
ELSEIF w_line_sans_comm CS '->' AND w_line_sans_comm(1) CN '*"' AND stop_detail = abap_false.
w_s = level.
CONCATENATE w_s ')' w_line INTO w_s SEPARATED BY space.
oref->write_text( iv_text = w_s
iv_format = if_demo_output_formats=>nonprop ).
ENDIF.
ENDMETHOD. "check_statement
METHOD display.
oref->close( ).
ENDMETHOD. "display
ENDCLASS. "lcl_code_reader IMPLEMENTATION
PARAMETERS p_report TYPE programm.
PARAMETERS p_maxlvl TYPE i DEFAULT 10.
START-OF-SELECTION.
DATA my_code_reader TYPE REF TO lcl_code_reader.
CREATE OBJECT my_code_reader
EXPORTING
maxlvl = p_maxlvl.
my_code_reader->analyse( report = p_report ).
my_code_reader->display( ).
END-OF-SELECTION.
Best regards
Bertrand
2017 Sep 21 7:08 PM
For programs using ABAP Objects, I don't know, but for old programs not based on ABAP Objects, there are 2 options: either use the transaction code SE93 to display the procedure flow of the program behind it, or use the transaction code SQF (blog post ABAP static analysis tool SQF, by Jerry Wang, on 2013/12/23).