home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / orx7.zip / orx_analyze_html.cmd < prev    next >
OS/2 REXX Batch file  |  1997-07-21  |  78KB  |  2,033 lines

  1. /*
  2. program:   orx_analyze_html.cmd
  3. type:      Object REXX, REXXSAA 6.0
  4. purpose:   formats analyzed REXX-program for HTML
  5. version:   1.00
  6. date:      1995-11
  7. changed:   1997-04-15; ---rgf, adapted for the new module structure
  8.  
  9. author:    Rony G. Flatscher
  10.            Rony.Flatscher@wu-wien.ac.at
  11.            (Wirtschaftsuniversitaet Wien, University of Economics and Business
  12.            Administration, Vienna/Austria/Europe)
  13. needs:     ---
  14.  
  15. usage:     orx_analyze_html some_rexx_file
  16.  
  17.            ... produces HTML-files, main file being named "HTML_Summary.html"
  18.  
  19. comments:  not finished yet
  20.  
  21. All rights reserved, copyrighted 1995-1997, no guarantee that it works without
  22. errors, etc. etc.
  23.  
  24. You are granted the right to use this module under the condition that you don't charge money for this module (as you didn't write
  25. it in the first place) or modules directly derived from this module, that you document the original author (to give appropriate
  26. credit) with the original name of the module and that you make the unaltered, original source-code of this module available on
  27. demand.  If that holds, you may even bundle this module (either in source or compiled form) with commercial software.
  28.  
  29. If you find an error, please send me the description (preferably a *very* short example); I'll try to fix it and re-release it to
  30. the net.
  31.  
  32. */
  33.  
  34. /* retrieve methods of classes defined in .environment ? */
  35. .local ~ bQueryEnvClassMethods        = .false
  36.  
  37. /* HUGE performance penalty, HUGE html-files results, if methods are shown too (> 800K) !! */
  38. .local ~ bShowEnvTilingWithMethodsEnv = .false  /* show methods while tiling classes of .environment ? */
  39.  
  40. /* perfomance penalty */
  41. .local ~ bShowEnvMethods              = .false  /* show .environment class methods while tiling non .environment classes ? */
  42.  
  43.  
  44. /* --- rgf : delete: */
  45. .local ~ bQueryEnvClassMethods        = .true
  46. .local ~ bShowEnvTilingWithMethodsEnv = .true   /* show methods while tiling classes of .environment ? */
  47. /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
  48.  
  49.  
  50.  
  51.  
  52.  
  53. PARSE ARG start_file
  54.  
  55. CALL TIME "Reset"                               /* time start */
  56. ctl. = orx_analyze( start_file )                /* have file parsed */
  57. PARSE VALUE TIME("Reset") WITH analyzeTime
  58.  
  59. .local ~ missing.class = ctl.eMissingClass      /* sentinel object, indicating a missing class */
  60.  
  61. /* not a time saver ...
  62. .local ~ kappitalize = .directory ~ new         /* stores smartCap'ped or Capitalize'd strings
  63. ... */
  64.                                                    for faster retrieval */
  65.  
  66. /*
  67. icon_path = "/orx/icons/"
  68. */
  69.  
  70. icon_path = get_icon_path( "RedDot.gif" )       /* try to locate the gif-s */
  71.  
  72. .local ~ Blu.Dot = '<IMG SRC="'  || icon_path || 'BluDot.gif" WIDTH=14 HEIGHT=14 ALIGN=TOP>'
  73. .local ~ Grn.Dot = '<IMG SRC="'  || icon_path || 'GrnDot.gif" WIDTH=14 HEIGHT=14 ALIGN=TOP>'
  74. .local ~ Org.Dot = '<IMG SRC="'  || icon_path || 'OrgDot.gif" WIDTH=14 HEIGHT=14 ALIGN=TOP>'
  75. .local ~ Pnk.Dot = '<IMG SRC="'  || icon_path || 'PinkDot.gif" WIDTH=14 HEIGHT=14 ALIGN=TOP>'
  76. .local ~ Prp.Dot = '<IMG SRC="'  || icon_path || 'PurDot.gif" WIDTH=14 HEIGHT=14 ALIGN=TOP>'
  77. .local ~ Red.Dot = '<IMG SRC="'  || icon_path || 'RedDot.gif" WIDTH=14 HEIGHT=14 ALIGN=TOP>'
  78. .local ~ Whi.Dot = '<IMG SRC="'  || icon_path || 'WhiteDot.gif" WIDTH=14 HEIGHT=14 ALIGN=TOP>'
  79. .local ~ Yel.Dot = '<IMG SRC="'  || icon_path || 'YelDot.gif" WIDTH=14 HEIGHT=14 ALIGN=TOP>'
  80.  
  81.  
  82. CALL create_html_file_names             /* determine names to be given to the analyzed files */
  83. CALL build_stats                        /* build "stats."-stem to contain text for statistical */
  84.  
  85. htmlDoc = .html_doc ~ new( .html.Summary, ,             /* create HTML-file */
  86.                          "Summary results of analyzing:" pp( ctl.eFileStart ~ name ), ,
  87.                          .true )     /* replace file, if it exists */
  88.  
  89. CALL sayError
  90. CALL sayError "Formatting summary ..."  /* summary results */
  91. CALL file_statistics htmlDoc
  92.  
  93. CALL sayError "Formatting details ..."  /* details results */
  94. CALL file_details
  95.  
  96. PARSE VALUE TIME("Elapsed") WITH formatTime
  97. CALL leadin htmlDoc, analyzeTime, formatTime, start_file
  98. htmlDoc ~ close                         /* close HTML-summary file */
  99. /*
  100. call x2cp .html.Summary                 /* use SGML-entities for chars > x7F    */
  101. */
  102. CALL CPFile2SGMLEntity .html.Summary    /* use SGML-entities for chars > x7F    */
  103.  
  104. .html.reference ~ sayStatistics         /* show # of references    */
  105.  
  106. EXIT
  107.  
  108.  
  109. /* find path for icons on local drive */
  110. GET_ICON_PATH : PROCEDURE
  111.     USE ARG icon_name
  112.  
  113.     CALL SysFileTree icon_name, "files.", "FSO"         /* search a gif, starting with local directory */
  114.  
  115.     IF files.0 = 0 THEN                                 /* not found, start search from root */
  116.        CALL SysFileTree "\" || icon_name, "files.", "FSO"
  117.  
  118.     IF files.0 = 0 THEN                                 /* not found, return empty string */
  119.        RETURN ""
  120.  
  121.     act_dir = FILESPEC( "Path", DIRECTORY() || "\" )    /* get present directory */
  122.     found = FILESPEC( "Path", files.1 )                 /* extract path-name */
  123.  
  124.     IF ABBREV( found, act_dir ) THEN
  125.     DO
  126.        IF found = act_dir THEN                          /* icons in present directory, no path necessary */
  127.           found = ""
  128.        ELSE
  129.           found = SUBSTR( found, LENGTH( act_dir ) + 1 )/* keep path relative ! */
  130.     END
  131.  
  132.     found = TRANSLATE( found, "/", "\" )                /* bug in WebExplorer; if full path given, forward slashes ! */
  133.  
  134.     RETURN found
  135.  
  136.  
  137. /* ---------------------------------------------------------------------------------------- */
  138. /* create names for html-files (summary plus details)   */
  139. CREATE_HTML_FILE_NAMES: PROCEDURE EXPOSE ctl.
  140.  
  141.     stem  = "HTML"
  142.     trail = "html"
  143.  
  144.     .local ~ html.Summary = stem || "_Summary." || trail
  145.  
  146.     i = 0
  147.     DO File OVER ctl.eFiles        /* iterate over directory */
  148.        i = i + 1
  149.        tmpFile = ctl.eFiles ~ entry( File )  /* get file object */
  150.  
  151.        FileName = stem || "_Detail_" || i || "." || trail
  152.        tmpFile ~ User_Slot ~ setentry( "HTMLFileName", FileName ) /* store with object data */
  153.     END
  154.     RETURN
  155.  
  156.  
  157.  
  158. /* ---------------------------------------------------------------------------------------- */
  159. /* show header */
  160. LEADIN: PROCEDURE EXPOSE ctl.
  161.    USE ARG html, analyzeTime, formatTime, fileName
  162.  
  163.    PARSE SOURCE op_sys call_type proc_name
  164.  
  165.    html ~ h5( "File" smartCap( pp( fileName ) ) )
  166.    html ~~ lineout( pp( DATE( "Sorted" ) ),
  167.            pp( TIME( "Normal" )  ) "running" smartCap( pp( proc_name ) ),
  168.           "under" pp( smartCap( op_sys ) ) ) ~~ p
  169.  
  170.    IF VAR( "analyzeTime" ) THEN         /* if analyze time given ... */
  171.    DO
  172.       html ~~ p( "Times given for analyzing and formatting <STRONG>all</STRONG> files:" ) ~~ br ~~ br
  173.       html ~~ lineout( "Time to analyze:" pp( FORMAT( analyzeTime, , 2  ) ) "seconds" ) ~~ br
  174.    END
  175.  
  176.    html ~~ lineout( "Time to format:" pp( FORMAT( formatTime, , 2  ) ) "seconds" ) ~~ hr
  177.    RETURN
  178. /* ------------------------------------------------------------------------- */
  179.  
  180.  
  181. /* ------------------------------------------------------------------------- */
  182. /* show dependency tree of encountered ::REQUIRES directives */
  183. REQUIRE_STRUCTURE: PROCEDURE  EXPOSE ctl.
  184.    USE ARG html, tmpFile, level
  185.  
  186.    IF tmpFile ~ requires_files ~ items = 0 THEN         /* if no files are required, then return */
  187.       RETURN
  188.  
  189.    html ~ h2( "Required Files", "ALIGN=CENTER")
  190.  
  191.  
  192.    htmlTable = .html_Table ~ new( "BORDER CELLPAD=3 ALIGN=CENTER WIDTH=100%" )     /* a table with no borders */
  193.    htmlTable ~~ putColumn( "Dependency tree, imposed by ::REQUIRES directives:") ~~ newRow( 8 )
  194.  
  195.  
  196.    CALL show_requires_tree htmlTable, tmpFile
  197.  
  198.    html ~ lineout( htmlTable ~ htmlText )               /* write table to HTML-file */
  199.    html ~ hr( , "WIDTH=75%" )
  200.  
  201.    RETURN
  202.  
  203. SHOW_REQUIRES_TREE: PROCEDURE
  204.    USE ARG htmlTable, tmpFile, level
  205.  
  206.    IF \VAR( "level" ) THEN              /* initial call ! */
  207.       level = 0
  208.  
  209.    tmpString = a_href( tmpFile ~ User_Slot ~ entry( "HTMLFileName") ,,
  210.                        "Start" ,,               /* anchor in HTMLFileName */
  211.                        tmpFile ~ name )
  212.  
  213.  
  214.  
  215. /* rgf was here -------- */
  216.    do i = 1 to level
  217.        htmlTable ~~ putColumn( " ", "WIDTH=5%" )
  218.    end
  219.    htmlTable ~~ putColumn( pp( tmpString )) ~~ newRow( MAX( 8, level ) )
  220. /* rgf was here -------- */
  221.  
  222.  
  223. /*
  224.    htmlTable ~~ skipColumn( level ) ~~ putColumn( pp( tmpString ) ) ~~ newRow( MAX( 8, level ) )
  225. */
  226.  
  227.    DO item OVER tmpFile ~ requires_files
  228.       CALL show_requires_tree htmlTable, item, ( level + 1 )
  229.    END
  230.    RETURN
  231. /* ------------------------------------------------------------------------- */
  232.  
  233.  
  234.  
  235. /* ---------------------------------------------------------------------------------------- */
  236. BUILD_STATS : PROCEDURE EXPOSE stats. ctl.
  237.    stats.         = 0
  238.  
  239.    stats.eLines.1.eText = "Total lines of code         " pp( format( 100, , 2 ) "%" )
  240.    stats.eLines.2.eText = "LOCs (lines of code, edited)"
  241.    stats.eLines.0      = 2
  242.  
  243.    i = 1
  244.  
  245.    stats.eFile.i.eText  = "procedure(s) found"           /* 1 */
  246.    i = i + 1
  247.    stats.eFile.i.eText  = "label(s)     found"           /* 2 */
  248.    i = i + 1
  249.  
  250.    stats.eFile.i.eText  = "::REQUIRES   found"           /* 3 */
  251.    i = i + 1
  252.  
  253.    stats.eFile.i.eText  = "::ROUTINE(s) found"           /* 4 */
  254.    i = i + 1
  255.  
  256.    stats.eFile.i.eText  = "::CLASS(es)  found"           /* 5 */
  257.    i = i + 1
  258.  
  259.    stats.eFile.i.eText  = "::METHOD(s)  found"           /* 6 */
  260.    i = i + 1
  261.  
  262.    stats.eFile.0       = i - 1
  263.    RETURN
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270. /* ---------------------------------------------------------------------------------------- */
  271. /* show statistical data of analyzed files (in alphabetical order ) */
  272. FILE_STATISTICS: PROCEDURE EXPOSE ctl. stats.
  273.    USE ARG html
  274.  
  275.    CALL time "Reset"
  276.    startFile = ctl.eFileStart                           /* determine file to start */
  277.    CALL require_structure html, ctl.eFileStart          /* start with file which we had to analyze */
  278.  
  279.    sortedFiles = sort( ctl.eFiles )     /* returns array with sorted indices of .directory */
  280.  
  281.    html ~ h2( A_NAME( "Start", smartCap( "Summary results of analyzing:" pp( ctl.eFileStart ~ name ) ) ), "ALIGN=CENTER")
  282.  
  283.    htmlList = .html_List ~ new( "OL" )
  284.    DO item OVER sortedFiles
  285.       tmpFile = ctl.eFiles ~ entry( item )              /* get file object */
  286.       tmpString = smartCap( pp( tmpFile ~ Name ) )
  287.  
  288.       IF tmpFile = startFile THEN
  289.          tmpString = tmpString .Yel.Dot x2bare( "<--- (started the analysis !)" )
  290.  
  291.       tmpString = a_href( tmpFile ~ User_Slot ~ entry( "HTMLFileName") ,,
  292.                           "Start" ,,               /* anchor in HTMLFileName */
  293.                           tmpString )
  294.  
  295.       htmlList ~ item( tmpString )
  296.    END
  297.    html ~ LINEOUT( htmlList ~ htmlText )
  298.    html ~ hr( , "size=3" )
  299.  
  300.  
  301.    DO i = 1 TO sortedFiles ~ items
  302.       html ~ hr( , "SIZE=5" )
  303.  
  304.       tmpFile = ctl.eFiles ~ entry( sortedFiles[ i ] )  /* get file object */
  305.  
  306.       /* if this is the file which got analyzed, indicate this fact and show accessible routines and classes */
  307.  
  308.       tmpString = "File" smartCap( pp( tmpFile ~ name ) )
  309.  
  310.       tmpString = a_href( tmpFile ~ User_Slot ~ entry( "HTMLFileName") ,,
  311.                           "Start" ,,               /* anchor in HTMLFileName */
  312.                           tmpString )
  313.  
  314.       IF tmpFile = startFile THEN
  315.       DO
  316.          html ~ h2( www_tag( tmpString ) .Yel.Dot x2bare( "<--- (started the analysis !)" ) )
  317.       END
  318.       ELSE
  319.          html ~ h2( tmpString )
  320.  
  321.       html ~ hr
  322.  
  323.       /* indicate which files REQUIRE this one */
  324.       htmlTable = .html_Table ~ new( "ALIGN=CENTER WIDTH=100%" )
  325.       tmpString = "According to the analysis the following file(s) require(s) this one:"
  326.       html ~ h4( tmpString )
  327.  
  328.       IF tmpFile ~ required_by ~ items > 0 THEN
  329.       DO
  330.          CALL sort_def_list htmlTable, tmpFile ~ required_by
  331.       END
  332.       ELSE
  333.          htmlTable ~ putColumn( "--- none ---", "ALIGN=CENTER" )
  334.  
  335.       html ~ LINEOUT( htmlTable ~ htmlText )
  336.       html ~ hr( , "WIDTH=75%" )
  337.  
  338.       /* indicate which files are REQUIRED by this one */
  339.       htmlTable = .html_Table ~ new( "ALIGN=CENTER WIDTH=100%" )
  340.       tmpString = "According to the analysis this file requires the following file(s):"
  341.       html ~ h4( tmpString )
  342.  
  343.       IF tmpFile ~ requires_files ~ items > 0 THEN
  344.       DO
  345.          CALL sort_def_list htmlTable, tmpFile ~ requires_files
  346.       END
  347.       ELSE
  348.          htmlTable ~ putColumn( "--- none ---", "ALIGN=CENTER" )
  349.  
  350.       html ~ LINEOUT( htmlTable ~ htmlText )
  351.       html ~ hr( , "WIDTH=75%" )
  352.  
  353.  
  354.   /* indicate whether file may be called as a procedure / function */
  355.   /* if so, show signatures and returns                            */
  356.  
  357.       IF tmpFile ~ IsProcedure | tmpFile ~ IsFunction THEN
  358.       DO
  359.          tmpString = "This file may be called as a procedure"
  360.          IF tmpFile ~ IsFunction THEN tmpString = tmpString www_tag("and", "EM") "as a function (it returns values)"
  361.  
  362.          html ~ h4( tmpString )
  363.          htmlTable = .html_Table ~ new( "ALIGN=CENTER WIDTH=100%" )
  364.  
  365.          /* show signatures */
  366.          IF tmpFile ~ signatures ~ items > 0 THEN
  367.          DO
  368.             title_string = ""
  369.             CALL dump_detail_dir2string htmlTable, tmpFile ~ signatures, title_string
  370.          END
  371.  
  372.          /* show return expressions */
  373.          IF tmpFile ~ returns ~ items > 0 THEN
  374.          DO
  375.             title_string = ""
  376.             CALL dump_detail_dir2string htmlTable, tmpFile ~ returns, title_string
  377.          END
  378.  
  379.          /* show exit expressions */
  380.          IF tmpFile ~ returns ~ items > 0 THEN
  381.          DO
  382.             title_string = ""
  383.             CALL dump_detail_dir2string htmlTable, tmpFile ~ exits, title_string
  384.          END
  385.          html ~ LINEOUT( htmlTable ~ htmlText )
  386.          html ~ hr( , "WIDTH=75%" )
  387.  
  388.       END
  389.  
  390.  
  391. /* show statistics */
  392.  
  393.       /* total number of lines */
  394.       stats.eLines.1      = pp( RIGHT( pp_number( tmpFile ~ total_loc ), 7) ) stats.eLines.1.eText
  395.       stats.eLines.1.eSum = stats.eLines.1.eSum + tmpFile ~ total_loc    /* grand total */
  396.  
  397.       stats.eLines.2      = pp( RIGHT( pp_number( tmpFile ~ loc ), 7) ) stats.eLines.2.eText,
  398.                             pp( RIGHT( format( (tmpFile ~ loc * 100 / MAX( tmpFile ~ total_loc, 1 )) , , 2), 6) "%" )
  399.       stats.eLines.2.eSum = stats.eLines.2.eSum + tmpFile ~ loc          /* grand total */
  400.  
  401.       htmlTable = .html_Table ~ new( "BORDER ALIGN=CENTER CELLPADDING=3 WIDTH=60%" )
  402.       htmlTable ~ setcaption( "Statistics", "ALIGN=TOP" )
  403.  
  404.       PARSE VAR stats.eLines.1 "[" tot_loc "]" tot_text "[" tot_perc "]"
  405.       PARSE VAR stats.eLines.2 "[" net_loc "]" net_text "[" net_perc "]"
  406.  
  407.       htmlTable ~~ ,
  408.                putColumn( tot_loc, "ALIGN=RIGHT WIDTH=15%"  ) ~~ ,
  409.                putColumn( tot_text ) ~~ ,
  410.                putColumn( tot_perc, "ALIGN=RIGHT WIDTH=15%") ~~,
  411.                newRow
  412.  
  413.       htmlTable ~~ ,
  414.                putColumn( net_loc, "ALIGN=RIGHT") ~~,
  415.                putColumn( net_text ) ~~,
  416.                putColumn( net_perc, "ALIGN=RIGHT") ~~,
  417.                newRow
  418.  
  419.       htmlTable ~~ putColumn( " ", "COLSPAN=3" ) ~~ newRow
  420.  
  421.       j = 1
  422.       stats.eFile.j = ctl.eProcedures2Files ~ allat( tmpFile ) ~ items
  423.       j = j + 1
  424.       stats.eFile.j = ctl.eLabels2Files     ~ allat( tmpFile ) ~ items
  425.       j = j + 1
  426.       stats.eFile.j = ctl.eRequires2Files   ~ allat( tmpFile ) ~ items
  427.       j = j + 1
  428.       stats.eFile.j = ctl.eRoutines2Files   ~ allat( tmpFile ) ~ items
  429.       j = j + 1
  430.       stats.eFile.j = ctl.eClasses2Files    ~ allat( tmpFile ) ~ items
  431.       j = j + 1
  432.       stats.eFile.j = ctl.eMethods2Files    ~ allat( tmpFile ) ~ items
  433.  
  434.       DO j = 1 TO stats.eFile.0
  435.          htmlTable ~~,
  436.                putColumn( pp_number( stats.eFile.j ), "ALIGN=RIGHT" ) ~~,
  437.                putColumn( stats.eFile.j.eText, "COLSPAN=2" ) ~~ newRow
  438.  
  439.          stats.eFile.j.eSum = stats.eFile.j.eSum + stats.eFile.j
  440.       END
  441.  
  442.       htmlTable ~~ putColumn( " ", "COLSPAN=3" ) ~~ newRow
  443.  
  444.       tmpHint = ""
  445.       IF tmpFile ~ errors ~ items > 0 THEN tmpHint = .Red.Dot
  446.  
  447.       htmlTable ~~,
  448.                putColumn( pp_number( tmpFile ~ errors ~ items ), "ALIGN=RIGHT" ) ~~,
  449.                putColumn( "Error(s) found" tmpHint, "COLSPAN=2" ) ~~,
  450.                newRow
  451.  
  452.       html ~ LINEOUT( "<CENTER>" )
  453.       html ~ LINEOUT( htmlTable ~ htmlText )
  454.       html ~ LINEOUT( "</CENTER>" )
  455.       html ~ hr( , "WIDTH=75%" )
  456.  
  457.  
  458.  /* show available ROUTINES ( all local and all public defined via requires ) */
  459.       tmpDir = tmpFile ~ local_Routines ~ union( tmpFile ~ visible_routines )
  460.       title_String = "The following routine(s) is (are) accessible for this file:"
  461.       CALL dump_directory html, tmpDir, .nil, ctl.eRoutines2Files, title_string
  462.  
  463.  
  464.  /* show available CLASSES ( all local and all public defined via requires ) */
  465.       tmpDir = tmpFile ~ local_classes ~ union( tmpFile ~ visible_classes )
  466.       title_String = "The following class(es) is (are) accessible for this file:"
  467.  
  468.       CALL dump_directory html, tmpDir, .nil, ctl.eClasses2Files, title_string, , .true /* with hyperlinks */
  469.  
  470.  /* show available classes as tree(s), indicate metaclass trees */
  471.       CALL dump_roots html, tmpFile
  472.  
  473.  /* show usage of metaclasses (display metaclasses and their classes) */
  474.       CALL dump_classes_using_metaclasses html, tmpFile
  475.  
  476.  /* show order of tiled classes for every leaf class */
  477.       CALL dump_tiled_classes html, tmpFile, tmpFile ~ Local_Leaf_Classes, .false
  478.  
  479.  /* show found errors */
  480.       htmlTable = .html_Table ~ new( "ALIGN=CENTER WIDTH=100%" )
  481.       tmpString = "The following error(s) was (were) found during parsing:"
  482.       html ~ h4( tmpString )
  483.  
  484.       IF tmpFile ~ errors ~ items > 0 THEN
  485.       DO
  486.          stats.eFile.eError.eSum = stats.eFile.eError.eSum + tmpFile ~ errors ~ items
  487.          CALL show_sorted_errors htmlTable, tmpFile ~ errors
  488.       END
  489.       ELSE
  490.         htmlTable ~ putColumn( "--- none ---", "ALIGN=CENTER" )
  491.  
  492.       html ~ lineout( htmlTable ~ htmlText )
  493.    END
  494.  
  495.    html ~ hr( , "SIZE=5" )
  496.  
  497.    html ~ hr( , "WIDTH=75%" )
  498.  
  499.  
  500. /* --------------------------- grand totals ----------------------------- */
  501. /* total number of lines */
  502.    tmp1 = pp( RIGHT( pp_number( stats.eLines.1.eSum ), 7) ) stats.eLines.1.eText
  503.  
  504.    tmp2 = pp( RIGHT( pp_number( stats.eLines.2.eSum ), 7) ) stats.eLines.2.eText,
  505.           pp( RIGHT( format( ( stats.eLines.2.eSum * 100 / MAX( stats.eLines.1.eSum, 1) ) , , 2), 6) "%" )
  506.  
  507.    htmlTable = .html_Table ~ new( "BORDER ALIGN=CENTER CELLPADDING=3 WIDTH=60%" )
  508.    htmlTable ~ setcaption( "Grand Totals - Statistics", "ALIGN=TOP" )
  509.  
  510.    PARSE VAR tmp1 "[" tot_loc "]" tot_text "[" tot_perc "]"
  511.    PARSE VAR tmp2 "[" net_loc "]" net_text "[" net_perc "]"
  512.  
  513.    htmlTable ~~,
  514.             putColumn( pp_number( sortedFiles ~ items ), "ALIGN=RIGHT" ) ~~,
  515.             putColumn( "File(s) (including 1x environment) processed:", "COLSPAN=2" ) ~~,
  516.             newRow
  517.  
  518.    htmlTable ~~ putColumn( " ", "COLSPAN=3" ) ~~ newRow
  519.  
  520.    htmlTable ~~ ,
  521.             putColumn( tot_loc, "ALIGN=RIGHT WIDTH=15%"  ) ~~ ,
  522.             putColumn( tot_text ) ~~ ,
  523.             putColumn( tot_perc, "ALIGN=RIGHT WIDTH=15%") ~~,
  524.             newRow
  525.  
  526.    htmlTable ~~ ,
  527.             putColumn( net_loc, "ALIGN=RIGHT") ~~,
  528.             putColumn( net_text ) ~~,
  529.             putColumn( net_perc, "ALIGN=RIGHT") ~~,
  530.             newRow
  531.  
  532.    htmlTable ~~ putColumn( " ", "COLSPAN=3" ) ~~ newRow
  533.  
  534.    DO j = 1 TO stats.eFile.0
  535.       htmlTable ~~,
  536.             putColumn( pp_number( stats.eFile.j.eSum ), "ALIGN=RIGHT" ) ~~,
  537.             putColumn( stats.eFile.j.eText, "COLSPAN=2" ) ~~ newRow
  538.    END
  539.  
  540.    htmlTable ~~ putColumn( " ", "COLSPAN=3" ) ~~ newRow
  541.  
  542.  
  543.    tmpHint = ""
  544.    IF stats.eFile.eError.eSum > 0 THEN tmpHint = .Red.Dot
  545.  
  546.    htmlTable ~~,
  547.             putColumn( pp_number( stats.eFile.eError.eSum ), "ALIGN=RIGHT" ) ~~,
  548.             putColumn( "Error(s) found" tmpHint, "COLSPAN=2" ) ~~,
  549.             newRow
  550.  
  551.  
  552.    html ~ LINEOUT( "<CENTER>" )
  553.    html ~ LINEOUT( htmlTable ~ htmlText )
  554.    html ~ LINEOUT( "</CENTER>" )
  555.    html ~ hr
  556.    PARSE VALUE TIME("Elapsed") WITH formatTime
  557.    CALL leadin html, , formatTime, "Summary document"
  558.  
  559.    html ~ hr( ,"SIZE=5" )
  560.    RETURN
  561.  
  562. /* ------------------------------------------------------------------------- */
  563.  
  564.  
  565.  
  566.  
  567.  
  568.  
  569. /* ========================================================================== */
  570.  
  571.  
  572.  
  573.  
  574.  
  575.  
  576. /* ---------------------------------------------------------------------------------------- */
  577. /* show details of analyzed files (in alphabetical order ) */
  578. FILE_DETAILS: PROCEDURE EXPOSE ctl. stats.
  579.  
  580.    startFile = ctl.eFileStart           /* determine file to start with */
  581.    sortedFiles = sort( ctl.eFiles )     /* returns array with sorted indices of .directory */
  582.  
  583.    DO i = 1 TO sortedFiles ~ items
  584.       CALL TIME "Reset"                 /* reset clock */
  585.  
  586.       tmpFile = ctl.eFiles ~ entry( sortedFiles[ i ] )  /* get file object */
  587.       CALL sayError "   details for" pp( tmpFile ~ Name ) "..."
  588.  
  589.       htmlFName = tmpFile ~ User_Slot ~ entry( "HTMLFileName" ) /* get HTML-file name */
  590.  
  591.       html = .html_doc ~ new(  htmlFName , ,                    /* create HTML-file */
  592.                                "Results of analyzing:" pp( tmpFile ~ name ), ,
  593.                                .true )     /* replace file, if it exists */
  594.  
  595.       html ~ LINEOUT( a_href( .html.Summary, "Start", "Back to Summary" ) )
  596.       html ~ hr
  597. /*----------------------------------- */
  598. /* if this is the file which got analyzed, indicate this fact and show accessible routines and classes */
  599.       tmpString = "File" smartCap( pp( tmpFile ~ name ) )
  600.  
  601.       IF tmpFile = startFile THEN
  602.          tmpString = tmpString .Yel.Dot x2bare( "<--- (started the analysis !)" )
  603.  
  604.       html ~ h2( A_NAME( "Start", tmpString ) )         /* define anchor name with title */
  605.  
  606.       html ~ hr
  607.  
  608. /*----------------------------------- */
  609. /* indicate which files REQUIRE this one */
  610.       htmlTable = .html_Table ~ new( "ALIGN=CENTER WIDTH=100%" )
  611.       tmpString = "According to the analysis the following file(s) require(s) this one:"
  612.       html ~ h4( tmpString )
  613.  
  614.       IF tmpFile ~ required_by ~ items > 0 THEN
  615.       DO
  616.          CALL sort_def_list htmlTable, tmpFile ~ required_by
  617.       END
  618.       ELSE
  619.          htmlTable ~ putColumn( "--- none ---", "ALIGN=CENTER" )
  620.  
  621.       html ~ LINEOUT( htmlTable ~ htmlText )
  622.       html ~ hr( , "WIDTH=75%" )
  623.  
  624.  
  625.  
  626. /*----------------------------------- */
  627. /* indicate which files are REQUIRED by this one */
  628.       htmlTable = .html_Table ~ new( "ALIGN=CENTER WIDTH=100%" )
  629.       tmpString = "According to the analysis this file requires the following file(s):"
  630.       html ~ h4( tmpString )
  631.  
  632.       IF tmpFile ~ requires_files ~ items > 0 THEN
  633.       DO
  634.          CALL sort_def_list htmlTable, tmpFile ~ requires_files
  635.       END
  636.       ELSE
  637.          htmlTable ~ putColumn( "--- none ---", "ALIGN=CENTER" )
  638.  
  639.       html ~ LINEOUT( htmlTable ~ htmlText )
  640.       html ~ hr( , "WIDTH=75%" )
  641.  
  642.  
  643.  
  644.  
  645. /*----------------------------------- */
  646. /* show statistics */
  647.  
  648.       /* total number of lines */
  649.       tmpTotLines         = pp( RIGHT( pp_number( tmpFile ~ total_loc ), 7) ) stats.eLines.1.eText
  650.  
  651.       tmpRealLines        = pp( RIGHT( pp_number( tmpFile ~ loc ), 7) ) stats.eLines.2.eText,
  652.                             pp( RIGHT( format( (tmpFile ~ loc * 100 / MAX( tmpFile ~ total_loc, 1 ) ) , , 2), 6) "%" )
  653.  
  654.       htmlTable = .html_Table ~ new( "BORDER ALIGN=CENTER CELLPADDING=3 WIDTH=60%" )
  655.       htmlTable ~ setcaption( "Statistics", "ALIGN=TOP" )
  656.  
  657.       PARSE VAR tmpTotLines  "[" tot_loc "]" tot_text "[" tot_perc "]"
  658.       PARSE VAR tmpRealLines "[" net_loc "]" net_text "[" net_perc "]"
  659.  
  660.       htmlTable ~~ ,
  661.                putColumn( tot_loc, "ALIGN=RIGHT WIDTH=15%"  ) ~~ ,
  662.                putColumn( tot_text ) ~~ ,
  663.                putColumn( tot_perc, "ALIGN=RIGHT WIDTH=15%") ~~,
  664.                newRow
  665.  
  666.       htmlTable ~~ ,
  667.                putColumn( net_loc, "ALIGN=RIGHT") ~~,
  668.                putColumn( net_text ) ~~,
  669.                putColumn( net_perc, "ALIGN=RIGHT") ~~,
  670.                newRow
  671.  
  672.       htmlTable ~~ putColumn( " ", "COLSPAN=3" ) ~~ newRow
  673.  
  674.  
  675.       nrProcedures         = pp_number( ctl.eProcedures2Files ~ allat( tmpFile ) ~ items )
  676.       htmlTable ~~ putColumn( nrProcedures, "ALIGN=RIGHT" ) ~~,
  677.                    putColumn( stats.eFile.1.eText, "COLSPAN=2" ) ~~ newRow
  678.  
  679.       nrLabels             = pp_number( ctl.eLabels2Files     ~ allat( tmpFile ) ~ items )
  680.       htmlTable ~~ putColumn( nrLabels, "ALIGN=RIGHT" ) ~~,
  681.                    putColumn( stats.eFile.2.eText, "COLSPAN=2" ) ~~ newRow
  682.  
  683.       nrRequires           = pp_number( ctl.eRequires2Files   ~ allat( tmpFile ) ~ items )
  684.       htmlTable ~~ putColumn( nrRequires, "ALIGN=RIGHT" ) ~~,
  685.                    putColumn( stats.eFile.3.eText, "COLSPAN=2" ) ~~ newRow
  686.  
  687.       nrRoutines           = pp_number( ctl.eRoutines2Files   ~ allat( tmpFile ) ~ items )
  688.       htmlTable ~~ putColumn( nrRoutines, "ALIGN=RIGHT" ) ~~,
  689.                    putColumn( stats.eFile.4.eText, "COLSPAN=2" ) ~~ newRow
  690.  
  691.       nrClasses            = pp_number( ctl.eClasses2Files    ~ allat( tmpFile ) ~ items )
  692.       htmlTable ~~ putColumn( nrClasses, "ALIGN=RIGHT" ) ~~,
  693.                    putColumn( stats.eFile.5.eText, "COLSPAN=2" ) ~~ newRow
  694.  
  695.       nrMethods            = pp_number( ctl.eMethods2Files    ~ allat( tmpFile ) ~ items )
  696.       htmlTable ~~ putColumn( nrMethods, "ALIGN=RIGHT" ) ~~,
  697.                    putColumn( stats.eFile.6.eText, "COLSPAN=2" ) ~~ newRow
  698.  
  699.       htmlTable ~~ putColumn( " ", "COLSPAN=3" ) ~~ newRow
  700.  
  701.       tmpHint = ""
  702.       IF tmpFile ~ errors ~ items > 0 THEN tmpHint = .Red.Dot
  703.  
  704.       htmlTable ~~,
  705.                putColumn( pp_number( tmpFile ~ errors ~ items ), "ALIGN=RIGHT" ) ~~,
  706.                putColumn( "Error(s) found" tmpHint, "COLSPAN=2" ) ~~,
  707.                newRow
  708.  
  709.       html ~ lineout( "<CENTER>" )
  710.       html ~ LINEOUT( htmlTable ~ htmlText )
  711.       html ~ lineout( "</CENTER>" )
  712.       html ~ hr( , "WIDTH=75%" )
  713.  
  714.  
  715. /*----------------------------------- */
  716. /* indicate whether file may be called as a procedure / function */
  717. /* if so, show signatures and returns                            */
  718.  
  719.       IF tmpFile ~ IsProcedure | tmpFile ~ IsFunction THEN
  720.       DO
  721.          tmpString = "This file may be called as a procedure"
  722.          IF tmpFile ~ IsFunction THEN tmpString = tmpString www_tag("and", "EM") "as a function (it returns values)"
  723.  
  724.          html ~ h4( tmpString )
  725.  
  726.          htmlTable = .html_Table ~ new( "ALIGN=CENTER WIDTH=100%" )
  727.  
  728.          /* show signatures */
  729.          IF tmpFile ~ signatures ~ items > 0 THEN
  730.          DO
  731.             title_string = "The following attempt(s) for argument parsing was (were) found:"
  732.             CALL dump_detail_dir2string htmlTable, tmpFile ~ signatures, title_string
  733.          END
  734.  
  735.          /* show return expressions */
  736.          IF tmpFile ~ returns ~ items > 0 THEN
  737.          DO
  738.             title_string = "The following RETURN statements was (were) found:"
  739.             CALL dump_detail_dir2string htmlTable, tmpFile ~ returns, title_string
  740.          END
  741.  
  742.          /* show exit expressions */
  743.          IF tmpFile ~ returns ~ items > 0 THEN
  744.          DO
  745.             title_string = "The following EXIT statement(s) was (were) found:"
  746.             CALL dump_detail_dir2string htmlTable, tmpFile ~ exits, title_string
  747.          END
  748.  
  749.          /* show labels within main body */
  750.          title_string = "This file contains the following label(s) in its main body:"
  751.          CALL dump_detail_dir2proclikes htmlTable, tmpFile ~ local_labels, title_string, .true
  752.  
  753.          html ~ LINEOUT( htmlTable ~ htmlText )
  754.          html ~ hr( , "WIDTH=75%" )
  755.       END
  756.  
  757.  
  758. /*----------------------------------- */
  759.  /* show available ROUTINES ( all local and all public defined via requires ) */
  760.       tmpDir = tmpFile ~ local_Routines ~ union( tmpFile ~ visible_routines )
  761.       title_String = "The following routine(s) is (are) accessible for this file:"
  762.       CALL dump_directory html, tmpDir, tmpFile, ctl.eRoutines2Files, title_string
  763.  
  764.  
  765. /*----------------------------------- */
  766.  /* show available CLASSES ( all local and all public defined via requires ) */
  767.       tmpDir = tmpFile ~ local_classes ~ union( tmpFile ~ visible_classes )
  768.       title_String = "The following class(es) is (are) accessible for this file:"
  769.       CALL dump_directory html, tmpDir, tmpFile, ctl.eClasses2Files, title_string, , .true /* with hyperlinks */
  770.  
  771.  
  772. /*----------------------------------- */
  773.  /* show available classes as tree(s), indicate metaclass trees */
  774.       CALL dump_roots html, tmpFile
  775.  
  776.  
  777. /*----------------------------------- */
  778. /* show usage of metaclasses (display metaclasses and their classes) */
  779.       CALL dump_classes_using_metaclasses html, tmpFile
  780.  
  781.  
  782. /*----------------------------------- */
  783. /* show procedures for file, including labels */
  784.       htmlTable = .html_Table ~ new( "BORDER ALIGN=CENTER WIDTH=100%" )
  785.       html ~ h4( "Procedures defined for file" )
  786.       title_string = ""
  787.       CALL dump_detail_dir2proclikes htmlTable, tmpFile ~ local_procedures, title_string, .true
  788.       html ~ LINEOUT( htmlTable ~ htmlText )
  789.  
  790. /*----------------------------------- */
  791. /* show routines for file, including labels, procedures */
  792.       htmlTable = .html_Table ~ new( "BORDER ALIGN=CENTER WIDTH=100%" )
  793.       html ~ h4( "::ROUTINE(s) defined within file" )
  794.       title_string = ""
  795.       CALL dump_detail_dir2proclikes htmlTable, tmpFile ~ local_routines, title_string, .true
  796.       html ~ LINEOUT( htmlTable ~ htmlText )
  797.  
  798.  
  799. /*----------------------------------- */
  800. /* show floating methods for file including labels & procedures */
  801.       IF tmpFile ~ local_methods ~ items > 0 THEN
  802.       DO
  803.          html ~ h4( "::METHOD(s) *not* attached to a specific class (floating)" )
  804.          htmlTable = .html_Table ~ new( "BORDER ALIGN=CENTER WIDTH=100%" )
  805.          title_string = ""
  806.          CALL dump_detail_dir2methods htmlTable, tmpFile ~ local_methods, title_string, .true
  807.          html ~ LINEOUT( htmlTable ~ htmlText )
  808.       END
  809.  
  810.  
  811.  
  812. /*----------------------------------- */
  813. /* show classes for file, including methods, which:
  814.         show class & instance methods including labels & procedures */
  815.  
  816.       title_string = "::CLASS(es) defined, detail view"
  817.       CALL dump_detail_dir2classes html, tmpFile ~ local_classes, title_string, .true
  818.  
  819.  
  820. /*------------------------------------------------------------------------------ */
  821.       /* show order of tiled classes for *every* class, including methods (!) */
  822.       tmp = tmpFile ~ Local_Classes ~ supplier
  823.  
  824.       tmpList = .list ~ new                     /* produce list containing def_classes only */
  825.       DO WHILE tmp ~ available
  826.          tmpList ~ insert( tmp ~ item )
  827.          tmp ~ next
  828.       END
  829.       CALL dump_tiled_classes html, tmpFile, tmpList, .true
  830.  
  831.  
  832.  
  833.  
  834. /*----------------------------------- */
  835. /* show found errors */
  836.       htmlTable = .html_Table ~ new( "ALIGN=CENTER WIDTH=100%" )
  837.       tmpString = "The following error(s) was (were) found during parsing:"
  838.       html ~ h4( tmpString )
  839.  
  840.       IF tmpFile ~ errors ~ items > 0 THEN
  841.       DO
  842.          stats.eFile.eError.eSum = stats.eFile.eError.eSum + tmpFile ~ errors ~ items
  843.          CALL show_sorted_errors htmlTable, tmpFile ~ errors
  844.       END
  845.       ELSE
  846.         htmlTable ~ putColumn( "--- none ---", "ALIGN=CENTER" )
  847.  
  848.       html ~ lineout( htmlTable ~ htmlText )
  849.       html ~ hr( , "SIZE=3" )
  850.  
  851.       PARSE VALUE TIME("Elapsed") WITH formatTime
  852.       CALL leadin html, , formatTime, tmpFile ~ name
  853.  
  854.       html ~ LINEOUT( a_href( .html.Summary, "Start", "Back to Summary" ) )
  855.       html ~ hr
  856.  
  857.       html ~ close                              /* close html-file */
  858.       CALL CPFile2SGMLEntity htmlFName          /* use SGML-entities for chars > x7F    */
  859.  
  860.    END
  861.  
  862.    RETURN
  863.  
  864.  
  865.  
  866.  
  867.  
  868. /* ========================================================================== */
  869.  
  870.  
  871.  
  872.  
  873.  
  874.  
  875.  
  876.  
  877. /* ---------------------------------------------------------------------------------------- */
  878.  
  879. /* show all metaclasses and classes using it */
  880.  
  881. DUMP_CLASSES_USING_METACLASSES: PROCEDURE EXPOSE ctl.
  882.     USE ARG html, tmpFile, line_nr
  883.  
  884.     IF \VAR( "line_nr" ) THEN line_nr = .false   /* default to not show line numbers */
  885.  
  886.     tmpDir = tmpFile ~ Local_MetaClasses                /* show metaclass usage */
  887.  
  888.     IF tmpDir ~ items = 0 THEN RETURN                   /* no metaclasses used in this file */
  889.  
  890.     tmpArr = sort( tmpDir )
  891.  
  892.     htmlTable = .html_Table ~ new( "BORDER CELLPADDING=1 ALIGN=CENTER WIDTH=100%" )
  893.     tmpString = "Metaclass(es) being explicitly used by:"
  894.     skipLevel = 4
  895.     html ~ h4( tmpString )
  896.  
  897.     DO i = 1 TO tmpArr ~ items                  /* display metaclasses */
  898.        tmpObject = tmpDir ~ entry( tmpArr[ i ] )
  899.  
  900.        tmpName        = "Metaclass" smartCap( pp( tmpObject ~ name) )
  901.        tmpErrorString = ""
  902.  
  903.  
  904.        IF tmpObject ~ IsMetaClass THEN
  905.           tmpName   = tmpName   "is used by:"
  906.        ELSE
  907.           tmpErrorString = .Red.Dot "** error ** (" || www_tag( "not", "EM" ) || "a metaclass!)"   /* show name */
  908.  
  909.        tmpLine = ""
  910.        IF line_nr THEN
  911.           tmpLine = tmpLine smartCap( pp_lineNr( tmpObject ~ LineNr ) )
  912.  
  913.        htmlTable ~~ putColumn( tmpName, "COLSPAN=" || skipLevel + 1 ) ~~ putColumn( tmpErrorString )
  914.        htmlTable ~~ putColumn( tmpLine ) ~~ newRow
  915.  
  916.        bNone = .true
  917.        nrItems = tmpObject ~ MetaUsedBySet ~ items
  918.        IF  nrItems > 0 THEN                             /* show classes using this metaclass */
  919.        DO
  920.           bNone = .false
  921.           tmpUseDir = .directory ~ new                  /* build a directory of classes using this metaclass */
  922.           DO item OVER tmpObject ~ MetaUsedBySet
  923.              tmpUseDir ~ setentry( item ~ name, item )
  924.           END
  925.  
  926.           tmpUseArr = sort( tmpUseDir )                 /* sort entries */
  927.           DO j = 1 TO tmpUseArr ~ items
  928.              aClass = tmpUseDir ~ entry( tmpUseArr[ j ] )       /* get class */
  929.              tmpString = smartCap( pp( aClass ~ name) )
  930.              tmpHint = ""
  931.              tmpMetaClassObject = aClass ~ MetaClassObject
  932.  
  933.              IF aClass <> tmpMetaClassObject THEN       /* don't show a metaclass defined by itself */
  934.              DO
  935.                 IF aClass ~ IsMetaClass THEN            /* ha, a metaclass is using a metaclass as its metaclass ? */
  936.                 DO
  937.                    tmpHint = "(metaclass)"
  938.                 END
  939.  
  940.                 htmlTable ~~ putColumn(" ", "ALIGN=RIGHT" ) ~~ putColumn( tmpString, "COLSPAN=" || skipLevel )
  941.                 htmlTable ~~ putColumn( tmpHint, "ALIGN=CENTER" ) ~~ newRow
  942.              END
  943.              ELSE
  944.                bNone = nrItems = 1                      /* indicate no other classes, if only class itself exists */
  945.           END
  946.        END
  947.  
  948.        IF bNone THEN                                    /* no class usages given */
  949.        DO
  950.           IF tmpObject ~ IsMetaClass THEN
  951.           DO
  952.              htmlTable ~~ putColumn(" ", "ALIGN=RIGHT" ) ~~ putColumn( "--- no class ! ---" , "COLSPAN=" || skipLevel )
  953.           END
  954.        END
  955.        htmlTable ~~ newRow ~~ putColumn ~~ putColumn ~~ putColumn ~~ newRow
  956.  
  957.     END
  958.  
  959.     html ~ lineout( htmlTable ~ htmlText )
  960.     html ~ hr( , "WIDTH=75%" )
  961.  
  962.     RETURN
  963.  
  964.  
  965.  
  966.  
  967.  
  968. /* ---------------------------------------------------------------------------------------- */
  969. /* show order of tiled classes for classes, passed in via every a collection
  970.  
  971.      tmpFile  - File (local classes being shown)
  972.      collObj  - Collection of local [leaf] classes
  973.      bDetail  - indicate whether methods should be shown (and aligned)
  974.      bBottomUp - indicate whether tiling should show class first and .object last (.true) or
  975.                                                show .object first and class last (.false)
  976.  
  977.      Remarks: while building the class-tree for a a leaf-class the starting class has a "level" of
  978.               0, a meta-class, a level of "-1", a meta-class for a meta-class, a level of "-2", etc.
  979. */
  980. DUMP_TILED_CLASSES : PROCEDURE EXPOSE ctl.
  981.    USE ARG html, tmpFile, collObject, bDetail, bObjectClassAtTop
  982.  
  983.    IF collObject ~ items = 0 THEN RETURN        /* nothing to show */
  984.  
  985.    IF \ VAR( bObjectClassAtTop) THEN bObjectClassAtTop = .false   /* default, determines order of shown "tiling" */
  986.  
  987.    IF \ .bShowEnvTilingWithMethodsEnv THEN      /* do a detailed tiling on .environment classes ? */
  988.    DO
  989.       /* too large ! 800KB with environment tiling !!! */
  990.       IF bDetail & tmpFile = ctl.eFileEnvironment THEN
  991.          RETURN
  992.    END
  993.  
  994.    /* build a list of superclasses, starting with leaves, remember top of every */
  995.    tmpLeafDir  = .directory ~ new
  996.  
  997.    /* turn set into directory, store class leaves, i.e. every class ---> a leaf, its superclasses in list */
  998.    DO aClass OVER collObject
  999.       IF tmpFile = .Env.FileObj THEN            /* if dumping environment, don't show classes given in .ignoreClasses */
  1000.       DO
  1001.         IF WORDPOS( SUBSTR( aClass ~ name, 2 ), .ignoreClasses ) > 0 THEN       /* remove leading dot */
  1002.            ITERATE
  1003.       END
  1004.  
  1005.       tmpList = .list ~ new
  1006.       tmpLeafDir ~ setentry( aClass ~ name, tmpList )
  1007.  
  1008.       /* build list of superclasses (last entry is root class) */
  1009.       tmpList ~ insert( aClass )                        /* store starting class  */
  1010.  
  1011.    END
  1012.  
  1013.    def_Class = aClass ~ class                           /* save class-object for def_class */
  1014.    max_length = def_Class ~ max_name_length + 2         /* get maximum classname length, account for brackets */
  1015.  
  1016.    /* sort directory of lists */
  1017.    tmpArr = sort( tmpLeafDir )
  1018.  
  1019. /* -------------------------------------------- */
  1020.    DO i = 1 TO tmpArr ~ items                           /* produce and display tiled classes */
  1021.       htmlTable = .html_Table ~ new( "BORDER CELLPADDING=1 ALIGN=CENTER WIDTH=100%" )
  1022.  
  1023.       tmpSetDir = .directory ~ new                      /* directory to contain sets for different class/metaclass levels */
  1024.       tmpSetDir ~ setentry( "1", .set ~ new )           /* set to contain classes already processed */
  1025.  
  1026.       HighestLevel = 0
  1027.  
  1028.       tmpList = tmpLeafDir ~ entry( tmpArr[ i ] )       /* process list, setup tiling, print it */
  1029.       tmpHierarchyList = .list ~ new
  1030.  
  1031.  
  1032.       next  = tmpList ~ first                           /* get first list entry */
  1033. /**/
  1034.       aClass = tmpList ~ at( next )                  /* get class-def */
  1035.       last = tmpHierarchyList ~ last                 /* get last entry, everything has to be inserted right after it */
  1036.       /* "HighestLevel" gets set in routine */
  1037.       CALL get_hierarchy_up aClass, tmpSetDir, tmpHierarchyList, last, 1 /* create tiled tree */
  1038. /**/
  1039.  
  1040.  
  1041.  
  1042.  
  1043.       /* now dump tiling */
  1044.       firstItem = tmpList ~ firstItem                   /* get first list item */
  1045.       tmpClass  = tmpList ~ firstItem                   /* get def_class object */
  1046.  
  1047.       tmpString = pp( tmpClass ~ name )
  1048.       tmpAttrString = tmpClass ~ dumpAttributes( .false )
  1049.       IF tmpAttrString <> "" THEN tmpString = tmpString pp( tmpAttrString )
  1050.  
  1051. /* -------------------------------------------- */
  1052.       IF \bDetail THEN                                  /* show summary */
  1053.       DO
  1054.          tmpClass = "Summary view of the tiling of leaf class:" www_tag( smartCap( pp( tmpClass ~ name) ), "EM" )
  1055.          html ~ h4( tmpClass )
  1056.  
  1057.          IF bObjectClassAtTop THEN next = tmpHierarchyList ~ last
  1058.                      ELSE next = tmpHierarchyList ~ first
  1059.  
  1060.          tmp_length = max_length + 25
  1061.          DO WHILE next <> .nil
  1062.             tmpItem = tmpHierarchyList ~ at( next )
  1063.             list_Item = tmpItem[ 1 ]                    /* get def_class object */
  1064.             tmpLevel  = HighestLevel - tmpItem[ 2 ]     /* level this class was found at, calculate indention */
  1065.  
  1066.             tmpClassString = smartCap( pp( list_item ~ name ) )
  1067.             tmpHint   = ""
  1068.             sourceFileName = ""
  1069.  
  1070.             IF      list_item = .missing.class THEN tmpHint = x2bare( "<-- MISSING" )
  1071.             ELSE IF list_item ~ IsMetaClass    THEN tmpHint = "(metaclass)"
  1072.  
  1073.             /* check whether defined in a different file, if so, display it ! */
  1074.             sourceFile = ctl.eClasses2Files ~ index( list_item )
  1075.             IF tmpFile <> sourceFile THEN sourceFileName = smartCap( pp( sourceFile ~ name ) )
  1076.  
  1077.             IF list_item ~ errors ~ items > 0 THEN tmpHint = tmpHint .Red.Dot "in error !"
  1078.  
  1079.             additionalCols = 3                  /* -3rd: hint, -2nd: "defined in:", -1st: file */
  1080.  
  1081.             /* rgf was here */
  1082.             DO tmpLevel
  1083.                htmlTable ~~ putColumn(" ", "WIDTH=20%" )
  1084.             END
  1085.             /*
  1086.             htmlTable ~~ skipColumn( tmpLevel )
  1087.             */
  1088.             /* rgf was here */
  1089.  
  1090.             htmlTable ~~ putColumn( tmpClassString, "WIDTH=20%" )
  1091.  
  1092.             /* rgf was here */
  1093.             DO ( highestLevel - tmpLevel - 1)       /* if a gap, then skip */
  1094.                htmlTable ~ putColumn( " ", "WIDTH=20%" )
  1095.             END
  1096.             /*
  1097.             htmlTable ~~ SkipColumn( highestLevel - tmpLevel - 1)       /* if a gap, then skip */
  1098.             */
  1099.             /* rgf was here */
  1100.  
  1101.             htmlTable ~~ putColumn( tmpHint, "WIDTH=10%" )
  1102.  
  1103.             IF sourceFileName <> "" THEN
  1104.             DO
  1105.                htmlTable ~~ putColumn( "from:", "ALIGN=RIGHT WIDTH=10%" )
  1106.                htmlTable ~~ putColumn( sourceFileName, "WIDTH=15%" )
  1107.             END
  1108.             htmlTable ~~ newRow( HighestLevel + additionalCols )
  1109.  
  1110.             IF bObjectClassAtTop THEN next = tmpHierarchyList ~ previous( next )
  1111.                         ELSE next = tmpHierarchyList ~ next( next )
  1112.          END
  1113.       END
  1114.  
  1115.  
  1116.  
  1117.  
  1118. /* -------------------------------------------- */
  1119.       ELSE                                              /* show detail (aligned methods) */
  1120.       DO                                                /* per level 2 columns (class/instance methods) */
  1121.          tmpClass = pp( i ) "Details view of the tiling of class:" www_tag( smartCap( pp( tmpClass ~ name) ), "EM" )
  1122.          html ~ h4( tmpClass )
  1123.  
  1124.  
  1125.          /* create temporary set to save methods already directly accessible */
  1126.          tmpClassMethDir     = .directory ~ new     /* save seen class methods */
  1127.          tmpInstanceMethDir  = .directory ~ new     /* save seen instance methods */
  1128.  
  1129.          IF bObjectClassAtTop THEN next = tmpHierarchyList ~ last
  1130.                      ELSE next = tmpHierarchyList ~ first
  1131.  
  1132.          tmpRootClass = tmpHierarchyList ~ at( next )[1]/* save root class */
  1133.          IsRootClassMeta = tmpRootClass ~ IsMetaClass   /* get metaclass indicator */
  1134.  
  1135.          DO WHILE next <> .nil
  1136.             tmpItem = tmpHierarchyList ~ at( next )
  1137.             list_Item = tmpItem[ 1 ]                    /* get def_class object */
  1138.             tmpLevel  = HighestLevel - tmpItem[ 2 ]     /* level this class was found at, calculate indentation */
  1139.             oriLevel  = tmpItem[ 2 ]                    /* original level */
  1140.  
  1141.             tmpClassString = smartCap( pp( list_item ~ name ) )
  1142.             tmpHint   = ""
  1143.             sourceFileName = ""
  1144.  
  1145.             IF      list_item = .missing.class THEN tmpHint = x2bare( "<-- MISSING" )
  1146.             ELSE IF list_item ~ IsMetaClass    THEN tmpHint = "(metaclass)"
  1147.             IF list_item ~ errors ~ items > 0  THEN tmpHint = tmpHint .Red.Dot "in error !"
  1148.  
  1149.             IF tmpHint <> "" THEN tmpHint = www_tag( tmpHint, "FONT SIZE=-1" )
  1150.  
  1151.  
  1152.             /* check whether defined in a different file, if so, display it ! */
  1153.             sourceFile = ctl.eClasses2Files ~ index( list_item )
  1154.  
  1155.             IF tmpFile <> sourceFile THEN
  1156.                sourceFileName = Capitalize( pp( sourceFile ~ shortName ), "FONT SIZE=-1", "FONT SIZE=-2" )
  1157.  
  1158.  
  1159.             bIsMetaClass = list_item ~ IsMetaClass
  1160.  
  1161.             additionalCols = 3                  /* -3rd: hint, -2nd: "defined in:", -1st: file */
  1162.  
  1163.  
  1164.             DO tmpLevel
  1165.                htmlTable ~~ putColumn( " ", "WIDTH=20%" )
  1166.             END
  1167.  
  1168.             htmlTable ~~ putColumn( www_tag( tmpClassString, "STRONG WIDTH=20%" ) )
  1169.             htmlTable ~~ SkipColumn( highestLevel - tmpLevel + ( highestLevel <> tmpLevel ) )
  1170.  
  1171.             htmlTable ~~ putColumn( tmpHint, "WIDTH=15%" )
  1172.  
  1173.             IF sourceFileName <> "" THEN
  1174.             DO
  1175.                htmlTable ~~ putColumn( www_tag( "from:", "FONT SIZE=-1"), "ALIGN=RIGHT WIDTH=10%" )
  1176.                htmlTable ~~ putColumn( sourceFileName, "WIDTH=15%" )
  1177.             END
  1178.             htmlTable ~~ newRow( HighestLevel * 2 + additionalCols )
  1179.  
  1180.  
  1181.             bShowMethods = ( list_item <> .missing.class )
  1182.  
  1183.             IF bShowMethods THEN
  1184.             DO
  1185.                IF \ .bShowEnvMethods THEN               /* show .environment class methods while tiling non .environment classes ? */
  1186.                DO       /* don't show methods, if they belong to an .environment class */
  1187.  
  1188.                   bShowMethods = \ ctl.eEnvClassSet ~ HASINDEX( list_item )
  1189.                END
  1190.             END
  1191.  
  1192.  
  1193.             /* now show methods */
  1194.             IF bShowMethods THEN
  1195.             DO
  1196.      /* dump *class* methods */
  1197.                tmpClassDir = list_item ~ Local_Class_Methods
  1198.                tmpClassArr = sort( tmpClassDir )
  1199.                classArray = .array ~ new( 0, 0 )                /* array to contain formatted methods */
  1200.  
  1201.                DO k = 1 TO tmpClassArr ~ items
  1202.                   tmpMethObj = tmpClassDir ~ entry( tmpClassArr[ k ] )
  1203.                   tmpString = tmpMethObj ~ name
  1204.                   tmpAttributes = STRIP( tmpMethObj ~ DumpAttributes( .false ) )
  1205.                   tmpString = smartCap( ( tmpString tmpAttributes ), "Cap", .false )
  1206.  
  1207.                   IF oriLevel = 1  THEN                 /* class methods only reachable if at level 1 */
  1208.                   DO
  1209.                         tmpName = tmpMethObj ~ name                            /* get method's name */
  1210.                         IF  tmpClassMethDir ~ entry( tmpName ) = .nil THEN     /* not recorded as of yet */
  1211.                         DO
  1212.                            IF \ bObjectClassAtTop THEN
  1213.                               tmpString = tmpString .Yel.Dot                       /* hint for direct access */
  1214.                            tmpClassMethDir ~ setentry( tmpName, tmpName )
  1215.                         END
  1216.                   END
  1217.                   classArray[ k, 1 ] = tmpLevel                 /* columns to skip */
  1218.                   classArray[ k, 2 ] = tmpString                /* string to show  */
  1219.  
  1220.                END
  1221.  
  1222.  
  1223.      /* dump *instance* methods */
  1224.                tmpClassDir = list_item ~ Local_Instance_Methods
  1225.                tmpClassArr = sort( tmpClassDir )
  1226.                instArray = .array ~ new( 0, 0 )                /* array to contain formatted methods */
  1227.  
  1228.                DO k = 1 TO tmpClassArr ~ items
  1229.                   tmpMethObj = tmpClassDir ~ entry( tmpClassArr[ k ] )
  1230.                   tmpString = tmpMethObj ~ name
  1231.                   tmpAttributes = STRIP( tmpMethObj ~ DumpAttributes( .false ) )
  1232.                   tmpString = smartCap( (tmpString tmpAttributes), "Cap", .false )
  1233.  
  1234.  
  1235.  
  1236.                   IF oriLevel <= 2 THEN
  1237.                   DO
  1238.                      /* indicate whether class method is directly accessible from starting class */
  1239.                      tmpName = tmpMethObj ~ name                   /* get method's name */
  1240.  
  1241.                      IF oriLevel = 1 THEN                               /* instance method in same column */
  1242.                      DO
  1243.                         IF  tmpInstanceMethDir ~ entry( tmpName ) = .nil THEN  /* not recorded as of yet */
  1244.                         DO
  1245.                            IF \ bObjectClassAtTop THEN
  1246.                               tmpString = tmpString .Yel.Dot                       /* hint for direct access */
  1247.                            tmpInstanceMethDir ~ setentry( tmpName, tmpName )
  1248.                         END
  1249.                      END
  1250.                      ELSE               /* oriLevel = 2: instance method is class method for class being tiled */
  1251.                      DO
  1252.                         IF tmpClassMethDir ~ entry( tmpName ) = .nil THEN      /* not recorded as of yet */
  1253.                         DO
  1254.                            IF \ bObjectClassAtTop THEN
  1255.                               tmpString = tmpString .Yel.Dot                       /* hint for direct access */
  1256.                            tmpClassMethDir ~ setentry( tmpName, tmpName )
  1257.                         END
  1258.                      END
  1259.                   END
  1260.  
  1261.                   instArray[ k, 1 ] = tmpLevel + 1             /* columns to skip */
  1262.                   instArray[ k, 2 ] = tmpString                /* string to show  */
  1263.                END
  1264.  
  1265.                /* write methods to table */
  1266.                DO k = 1 TO MAX( classArray ~ items, instArray ~ items ) / 2
  1267.                   bSkipped = .false
  1268.                   /* write class method */
  1269.                   IF classArray[ k, 1 ] <> .nil THEN
  1270.                   DO
  1271.                      /* rgf was here */
  1272.                      DO classArray[ k, 1 ]
  1273.                         htmlTable ~~ putColumn( " ", "WIDTH=10%" )
  1274.                      END
  1275.                      /*
  1276.                      htmlTable ~~ skipColumn( classArray[ k, 1 ] ),
  1277.                      */
  1278.                      /* rgf was here */
  1279.                      htmlTable ~~  putColumn( www_tag( classArray[ k, 2 ], "FONT SIZE=-1 WIDTH=25%" ) )
  1280.                      bSkipped = .true                              /* already skipped from the beginning */
  1281.                   END
  1282.  
  1283.                   IF instArray[ k, 1 ] <> .nil THEN
  1284.                   DO
  1285.                      IF \ bSkipped THEN
  1286.                      DO
  1287.                         /* rgf was here */
  1288.                         DO instArray[ k, 1 ]
  1289.                            htmlTable ~~ putColumn( " ", "WIDTH=20%" )
  1290.                         END
  1291.                         /*
  1292.                         htmlTable ~~ skipColumn( instArray[ k, 1 ] )
  1293.                         */
  1294.                         /* rgf was here */
  1295.                      END
  1296.  
  1297.                      htmlTable ~~  putColumn( www_tag( instArray[ k, 2 ], "FONT SIZE=-1 WIDTH=25%" ) )
  1298.                   END
  1299.                   htmlTable ~~ newRow
  1300.                END
  1301.  
  1302.                htmlTable ~~ putColumn() ~~ newRow
  1303.  
  1304.             END
  1305.  
  1306.             IF bObjectClassAtTop THEN next = tmpHierarchyList ~ previous( next )
  1307.                         ELSE next = tmpHierarchyList ~ next( next )
  1308.          END
  1309.       END
  1310. /* -------------------------------------------- */
  1311.  
  1312.       html ~ lineout( htmlTable ~ htmlText )
  1313.    END
  1314.    html ~ hr( , "WIDTH=75%" )
  1315.  
  1316.    RETURN
  1317.  
  1318.  
  1319.  
  1320.  
  1321. /* ---------------------------------------------------------------------------------------- */
  1322. /* produce a hierarchy list with starting class */
  1323. /* insert aCLASS into TMPHIERARCHYLIST, if it is not in TMPSET, position in list is
  1324.    indicated by POSITION_IN_LIST */
  1325. GET_HIERARCHY_UP: PROCEDURE EXPOSE ctl. HighestLevel
  1326.    USE ARG aClass, tmpSetDir, tmpHierarchyList, position_in_list, level
  1327.  
  1328.    IF aClass = .missing.class THEN                      /* leave missing class in list to indicate error */
  1329.    DO
  1330.       tmpHierarchyList ~ insert( .array~ of(aClass, level) , position_in_list )     /* insert class in front */
  1331.       RETURN
  1332.    END
  1333.  
  1334.    tmpSet = tmpSetDir ~ entry( level )                  /* get appropriate set to contain classes already processed at this level */
  1335.  
  1336.    IF tmpSet ~ hasindex( aClass ) THEN                  /* already handled */
  1337.    do
  1338.       RETURN
  1339.    end
  1340.  
  1341.  
  1342.    HighestLevel = MAX( level, HighestLevel )            /* store highest level (deepness w.r.t. metaclasses) */
  1343.    listIndex = tmpHierarchyList ~ insert( .array ~ of( aClass, level) , position_in_list) /* insert class in front, remember level */
  1344.    tmpSet ~ put( aClass )                               /* indicate that class has been handled at this level */
  1345.  
  1346.    tmpListOfSuperClasses = aClass ~ ListOfSuperClasses
  1347.    next = tmpListOfSuperClasses ~ last
  1348.    DO WHILE next <> .nil
  1349.       item = tmpListOfSuperClasses ~ at( next )
  1350.  
  1351.       IF \tmpSet ~ HASINDEX( item ) THEN      /* class not handled as of yet */
  1352.       DO
  1353.          CALL get_hierarchy_up item, tmpSetDir, tmpHierarchyList, listIndex, level
  1354.       END
  1355.  
  1356.       next = tmpListOfSuperClasses ~ previous( next )
  1357.    END
  1358.  
  1359.    aMetaClass = aClass ~ MetaClassObject                /* now resolve metaclass by putting it in front */
  1360.    IF aMetaClass <> .nil THEN
  1361.    DO
  1362.       IF \tmpSet ~ HASINDEX( aMetaClass) THEN           /* this class was not handled at this level as of yet */
  1363.       DO
  1364.          tmpSet ~ put( aMetaClass )                     /* indicate that class has been handled at this level */
  1365.          level = level + 1                              /* generate a new level */
  1366.  
  1367.          tmpSet = tmpSetDir ~ entry( level )            /* get the set of the next level and check whether metaclass was handled already */
  1368.  
  1369.          bRecurse = .false
  1370.          IF tmpSet = .nil THEN                          /* does a set for this metaclass level exist already ? */
  1371.          DO
  1372.             tmpSetDir ~ setentry( level, .set ~ new )   /* create an empty set for this new level */
  1373.             bRecurse = .true
  1374.          END
  1375.          ELSE
  1376.             bRecurse = \ tmpSet ~ HASINDEX( aMetaClass) /* only recurse if not handled at that level already ! */
  1377.  
  1378.  
  1379.  
  1380.          /* recurse, build a hierarchy for this metaclass at this new level */
  1381.          IF bRecurse THEN
  1382.          do
  1383.             CALL get_hierarchy_up aMetaClass, tmpSetDir, tmpHierarchyList, listIndex, level
  1384.          end
  1385.       END
  1386.    END
  1387.  
  1388.    RETURN
  1389.  
  1390.  
  1391.  
  1392. /* ---------------------------------------------------------------------------------------- */
  1393. DUMP_ROOTS: PROCEDURE   EXPOSE ctl.
  1394.    USE ARG html, tmpFile
  1395.  
  1396.    IF tmpFile ~ Local_Root_classes ~ items = 0 THEN RETURN      /* nothing to show */
  1397.  
  1398.    table1 = .html_table ~ new( "BORDER WIDTH=100% ALIGN=CENTER" )
  1399.    tmpString = "Show available root class(es) and founding metaclass(es) as tree(s):"
  1400.    html ~ h4( tmpString )
  1401.  
  1402.  
  1403.    tmpRootDir  = .directory ~ new
  1404.    /* turn set into directory */
  1405.    DO aClass OVER tmpFile ~ Local_Root_Classes
  1406.       tmpRootDir ~ setentry( aClass ~ name, aClass )
  1407.    END
  1408.  
  1409.    max_name_width =  aClass ~ class ~ max_name_length + 2 /* get maximum length of name, account for brackets */
  1410.  
  1411.    tmpArray = sort( tmpRootDir )                /* sort directory */
  1412.    DO i = 1 TO tmpArray ~ items                 /* dump classes in sorted root-order */
  1413.       tmpClass = tmpRootDir ~ entry( tmpArray[i] )
  1414.       CALL dump_sub_classes table1, tmpClass, 0, tmpClass ~ IsMetaClass
  1415.       table1 ~~ emptyColumn ~~ newRow
  1416.    END
  1417.    html ~ lineout( table1 ~ htmlText )
  1418.    html ~ hr( , "WIDTH=75%" )
  1419.    RETURN
  1420.  
  1421.  
  1422.  
  1423. /* ---------------------------------------------------------------------------------------- */
  1424. /* dump class tree recursively */
  1425. DUMP_SUB_CLASSES: PROCEDURE EXPOSE .ctl
  1426.   USE ARG htmlTable, class, level, IsMetaClass
  1427.  
  1428.   ClassName     = pp( class ~ name )
  1429.   MetaClassName = ""
  1430.  
  1431.   tmpHint = ""
  1432.   /* if this class has a metaclass defined with it, show it */
  1433.   IF ( level = 0 & IsMetaClass = .true ) | ( class ~ MetaClassObject <> .nil ) THEN
  1434.   DO
  1435.      IF class ~ MetaClassObject <> .nil THEN
  1436.      DO
  1437.          metaClassName = pp( class ~ MetaClassObject ~ name )
  1438.          tmpHint = "metaclass"
  1439.      END
  1440.      ELSE               /* no explicit metaclass, but subclassing .class ? */
  1441.      DO
  1442.         IF class ~ SuperClassObject ~ SuperClassObject <> .nil THEN     /* make sure .object is not shown */
  1443.         DO
  1444.            metaClassName = pp( class ~ SuperClassObject ~ name )
  1445.            tmpHint = "metaclass"
  1446.         END
  1447.      END
  1448.   END
  1449.  
  1450.   DO level
  1451.      htmlTable ~ putColumn( " ", "WIDTH=5%" )
  1452.   END
  1453.  
  1454.   htmlTable ~ putColumn( smartCap( ClassName ), "WIDTH=10%" )
  1455.   nextCol = MAX( level + 1, 10 )
  1456.  
  1457.   htmlTable ~ skipColumn( MAX( 0, nextCol - level - 1 ) )
  1458.  
  1459.   IF MetaClassName <> "" THEN
  1460.      htmlTable ~ putColumn( tmpHint smartCap( MetaClassName ), "WIDTH=25%" )
  1461.   ELSE
  1462.      htmlTable ~ putColumn
  1463.  
  1464.   htmlTable ~ newRow
  1465.  
  1466.   subClassSet = class ~ SetOfSubclasses
  1467.   tmpDir  = .directory ~ new
  1468.  
  1469.  
  1470.   /* turn set into directory */
  1471.   DO aClass OVER SubClassSet
  1472.      tmpDir ~ setentry( aClass ~ name, aClass )
  1473.   END
  1474.  
  1475.   tmpArray = sort( tmpDir )                    /* sort directory */
  1476.   DO i = 1 TO tmpArray ~ items                 /* dump in sorted root-order */
  1477.      tmpClass = tmpDir ~ entry( tmpArray[i] )
  1478.      CALL dump_sub_classes htmlTable, tmpClass, level + 1, IsMetaClass /* call recursively */
  1479.   END
  1480.  
  1481.   RETURN
  1482.  
  1483.  
  1484. /* ---------------------------------------------------------------------------------------- */
  1485. /* recursively dump proc-like data ( LABELS, PROCEDURES, ROUTINES )                */
  1486. /* dump detail of a directory pointing to strings ( LABELS, PROCEDURES, ROUTINES ) */
  1487. DUMP_DETAIL_DIR2PROCLIKES: PROCEDURE EXPOSE ctl.
  1488.    USE ARG htmlTable, tmpDir, title_string, line_nr
  1489.  
  1490.    IF \VAR( "line_nr" ) THEN line_nr = .false   /* default to not show line numbers */
  1491.  
  1492.    colSpan = 8
  1493.  
  1494.    /* show labels, procedures, routines stored with directory */
  1495.    IF tmpDir ~ items > 0 THEN
  1496.    DO
  1497.       htmlTable ~~ putColumn( www_tag( x2bare( title_string ),  "STRONG"), "COLSPAN=" || colSpan + 1 ) ~~ newRow
  1498.  
  1499.       tmpArr = sort( tmpDir )
  1500.  
  1501.       DO i = 1 TO tmpArr ~ items                        /* display entries */
  1502.          tmpObject = tmpDir ~ entry( tmpArr[ i ] )
  1503.  
  1504.          tmpString = ""
  1505.  
  1506.          tmpName = pp( tmpObject ~ name )
  1507.  
  1508.          IF      tmpObject ~ class ~ id = "DEF_PROCEDURE" THEN tmpName = tmpName ": PROCEDURE"
  1509.          ELSE IF tmpObject ~ class ~ id = "DEF_LABEL"     THEN tmpName = tmpName ":"
  1510.          ELSE IF tmpObject ~ class ~ id = "DEF_ROUTINE"   THEN tmpName = tmpObject ~ type tmpName
  1511.  
  1512.          tmpAttributes = tmpObject ~ dumpAttributes     /* show attributes (EXPOSE, PUBLIC) */
  1513.          extRange = \( tmpAttributes = "" )             /* account for missing attribute ? */
  1514.  
  1515.  
  1516.          tmpLine = ""
  1517.          IF line_nr THEN                                /* show line # */
  1518.             tmpLine = pp_lineNr( tmpObject ~ LineNr )
  1519.  
  1520.          htmlTable ~~ putColumn( i, "ALIGN=RIGHT WIDTH=5%" ) ~~,
  1521.                       putColumn( smartCap( tmpName ), "COLSPAN=" || colSpan / (extRange + 1) )
  1522.  
  1523.          IF tmpAttributes <> "" THEN
  1524.             htmlTable ~~ putColumn( smartCap( tmpAttributes ), "COLSPAN=" || colSpan / 2 )
  1525.  
  1526.          htmlTable ~~ putColumn( tmpLine, "ALIGN=RIGHT WIDTH=10%" ) ~~ newRow
  1527.  
  1528.  
  1529.          bDirty = .false
  1530.          htmlTable1 = .html_Table ~ new( "BORDER ALIGN=CENTER WIDTH=100%" )
  1531.  
  1532.          IF tmpObject ~ errors ~ items > 0 THEN
  1533.          DO
  1534.             htmlTable ~~ skipColumn( level )
  1535.             htmlTable ~~ putColumn( www_tag( "The following error(s) was (were) recorded:", "STRONG"),,
  1536.                                     "COLSPAN=" || MAX( 1, colSpan - level )  ) ~~ newRow
  1537.             CALL show_sorted_errors htmlTable1, tmpObject ~ errors, level, colSpan
  1538.             bDirty = .true
  1539.          END
  1540.  
  1541.  
  1542.          IF tmpObject ~ signatures ~ items > 0 THEN     /* show signatures */
  1543.          DO
  1544.             title_string = ""
  1545.             CALL dump_detail_dir2string htmlTable1, tmpObject ~ signatures, title_string
  1546.             bDirty = .true
  1547.          END
  1548.  
  1549.          IF tmpObject ~ returns    ~ items > 0 THEN     /* show return statements */
  1550.          DO
  1551.             title_string = "The following RETURN statements was (were) found:"
  1552.             title_string = ""
  1553.             CALL dump_detail_dir2string htmlTable1, tmpObject ~ returns, title_string
  1554.             bDirty = .true
  1555.          END
  1556.  
  1557.          IF tmpObject ~ exits      ~ items > 0 THEN     /* show exit-statements */
  1558.          DO
  1559.             title_string = "The following EXIT statement(s) was (were) found:"
  1560.             title_string = ""
  1561.             CALL dump_detail_dir2string htmlTable1, tmpObject ~ exits, title_string
  1562.             bDirty = .true
  1563.          END
  1564.  
  1565.  
  1566.          IF tmpObject ~ hasmethod( "local_labels" ) THEN
  1567.          DO
  1568.             IF tmpObject ~ local_labels ~ items > 0 THEN           /* show labels, but recurse */
  1569.             DO
  1570.                title_string = "Locally defined LABEL(s):"
  1571.                CALL dump_detail_dir2proclikes htmlTable1, tmpObject ~ local_labels, title_string, line_nr
  1572.  
  1573.                bDirty = .true
  1574.             END
  1575.          END
  1576.  
  1577.          IF tmpObject ~ hasmethod( "local_procedures" ) THEN
  1578.          DO
  1579.             IF tmpObject ~ local_procedures ~ items > 0 THEN       /* show procedures, but recurse */
  1580.             DO
  1581.                title_string = "Locally defined PROCEDURE(s):"
  1582.                CALL dump_detail_dir2proclikes htmlTable1, tmpObject ~ local_procedures, title_string, line_nr
  1583.  
  1584.                bDirty = .true
  1585.             END
  1586.          END
  1587.  
  1588.          IF bDirty THEN                                    /* was htmlTable1 written to ? */
  1589.             htmlTable ~~ skipColumn( 1 ) ~~ putColumn( htmlTable1 ~ htmlText, "COLSPAN=" || colSpan + 1 ) ~~ newRow
  1590.          ELSE
  1591.             htmlTable ~~ newRow
  1592.  
  1593.       END
  1594.     END
  1595.     RETURN
  1596.  
  1597.  
  1598.  
  1599. /* ---------------------------------------------------------------------------------------- */
  1600. /* dump detail of a directory pointing to strings ( METHOD ) */
  1601. DUMP_DETAIL_DIR2METHODS: PROCEDURE EXPOSE ctl.
  1602.    USE ARG htmlTable, tmpDir, title_string, line_nr
  1603.  
  1604.    IF tmpDir ~ items = 0 THEN RETURN            /* nothing to do */
  1605.    IF \VAR( "line_nr" ) THEN line_nr = .false   /* default to not show line numbers */
  1606.  
  1607.    /* show methods */
  1608.    methSpan = 8
  1609.    htmlTable ~~ putColumn( www_tag( x2bare( title_string ), "STRONG"), "COLSPAN=" || methSpan + 1 ) ~~ newRow
  1610.  
  1611.    tmpArr = sort( tmpDir )
  1612.  
  1613.    DO i = 1 TO tmpArr ~ items                        /* display entries */
  1614.       tmpObject = tmpDir ~ entry( tmpArr[ i ] )
  1615.  
  1616.       tmpName = "::method" pp( tmpObject ~ name )
  1617.  
  1618.       tmpAttributes = ( tmpObject ~ dumpAttributes )
  1619.  
  1620.       tmpLine = ""
  1621.  
  1622.       IF line_nr THEN                           /* show line numbers ? */
  1623.          tmpLine = smartCap( pp_lineNr( tmpObject ~ LineNr ) )
  1624.  
  1625.       htmlTable ~~ putColumn( i, "ALIGN=RIGHT WIDTH=5%" )
  1626.  
  1627.       IF tmpAttributes <> "" THEN
  1628.       DO
  1629.          htmlTable ~~ putColumn( smartCap( tmpName ), "COLSPAN=" || methspan / 2 )
  1630.          htmlTable ~~ putColumn( smartCap( tmpAttributes, "Cap", .false ), "COLSPAN=" || methspan / 2 )
  1631.       END
  1632.       ELSE
  1633.          htmlTable ~~ putColumn( smartCap( tmpName ), "COLSPAN=" || methspan )
  1634.  
  1635.       IF tmpLine <> "" THEN
  1636.          htmlTable ~~ putColumn( tmpLine, "ALIGN=RIGHT WIDTH=5%" )
  1637.  
  1638.       htmlTable ~~ newRow
  1639.  
  1640.       bDirty = .false
  1641.       htmlTable1 = .html_Table ~ new( "BORDER CELLPADDING=1 ALIGN=CENTER WIDTH=100%" )
  1642.  
  1643.       IF tmpObject ~ errors ~ items > 0 THEN
  1644.       DO
  1645.          CALL show_sorted_errors htmlTable1, tmpObject ~ errors, 1, methSpan
  1646.          bDirty = .true
  1647.       END
  1648.  
  1649.  
  1650.       IF tmpObject ~ expose ~ items > 0 THEN         /* show EXPOSE string */
  1651.       DO
  1652.          htmlTable1 ~~ putColumn( smartCap( pp( tmpObject ~ exposeAsString ) ), "COLSPAN=" || methSpan + 1) ~~ newRow
  1653.          htmlTable1 ~~ putColumn ~~ newRow
  1654.          bDirty = .true
  1655.       END
  1656.  
  1657.       IF tmpObject ~ signatures ~ items > 0 THEN     /* show signatures */
  1658.       DO
  1659.          title_string = ""
  1660.          CALL dump_detail_dir2string htmlTable1, tmpObject ~ signatures, title_string, 1
  1661.          htmlTable1 ~~ putColumn ~~ newRow
  1662.          bDirty = .true
  1663.       END
  1664.  
  1665.       IF tmpObject ~ returns    ~ items > 0 THEN     /* show return-statements */
  1666.       DO
  1667.          title_string = "Return Values"
  1668.          title_string = ""
  1669.          CALL dump_detail_dir2string htmlTable1, tmpObject ~ returns, title_string, 1
  1670.          htmlTable1 ~~ putColumn ~~ newRow
  1671.          bDirty = .true
  1672.       END
  1673.  
  1674.       IF tmpObject ~ exits      ~ items > 0 THEN     /* show exit-statements */
  1675.       DO
  1676.          title_string = ""
  1677.          CALL dump_detail_dir2string htmlTable1, tmpObject ~ exits, title_string, 1
  1678.          htmlTable1 ~~ putColumn ~~ newRow
  1679.          bDirty = .true
  1680.       END
  1681.  
  1682.       IF tmpObject ~ local_labels ~ items > 0 THEN           /* show labels */
  1683.       DO
  1684.          title_string = "Locally defined LABEL(s):"
  1685.          CALL dump_detail_dir2proclikes htmlTable1, tmpObject ~ local_labels, title_string, line_nr
  1686.          htmlTable1 ~~ putColumn ~~ newRow
  1687.          bDirty = .true
  1688.       END
  1689.  
  1690.       IF tmpObject ~ local_procedures ~ items > 0 THEN       /* show procedures */
  1691.       DO
  1692.          title_string = "Locally defined PROCEDURE(s):"
  1693.          CALL dump_detail_dir2proclikes htmlTable1, tmpObject ~ local_procedures, title_string, line_nr
  1694.          htmlTable1 ~~ putColumn ~~ newRow
  1695.          bDirty = .true
  1696.       END
  1697.  
  1698.       IF bDirty THEN                                    /* was htmlTable1 written to ? */
  1699.          htmlTable ~~ skipColumn( 1 ) ~~ putColumn( htmlTable1 ~ htmlText, "COLSPAN=" || methSpan + 1 ) ~~ newRow
  1700.       ELSE
  1701.          htmlTable ~~ newRow
  1702.  
  1703.       htmlTable ~~ putColumn ~~ newRow
  1704.     END
  1705.  
  1706.     RETURN
  1707.  
  1708.  
  1709.  
  1710.  
  1711. /* ---------------------------------------------------------------------------------------- */
  1712. /* dump detail of a directory pointing to strings ( CLASS ) */
  1713. DUMP_DETAIL_DIR2CLASSES: PROCEDURE EXPOSE ctl.
  1714.    USE ARG html, tmpDir, title_string, line_nr
  1715.  
  1716.    IF tmpDir ~ items = 0 THEN RETURN            /* nothing to do */
  1717.  
  1718.    IF \VAR( "line_nr" ) THEN line_nr = .false   /* default to not show line numbers */
  1719.  
  1720.    html ~ h4( title_string )
  1721.    classSpan = 8
  1722.  
  1723.    tmpArr = sort( tmpDir )
  1724.  
  1725.    DO i = 1 TO tmpArr ~ items                           /* display entries */
  1726.       level = 0
  1727.  
  1728.       htmlTable = .html_Table ~ new( "BORDER CELLPADDING=3 ALIGN=CENTER WIDTH=100%" )
  1729.  
  1730.       tmpObject = tmpDir ~ entry( tmpArr[ i ] )
  1731.       tmpName = smartCap( pp(tmpObject ~ name) )
  1732.  
  1733.       html ~ h4( .html.reference ~ A_Name( tmpObject, tmpName ) )
  1734.  
  1735.       tmpName = www_tag( tmpName, "STRONG" )
  1736.  
  1737.       tmpAttributes = tmpObject ~ dumpAttributes
  1738.  
  1739.       tmpLine = ""
  1740.       IF line_nr THEN
  1741.          tmpLine = smartCap( pp_lineNr( tmpObject ~ LineNr ) )
  1742.  
  1743.  
  1744.       htmlTable ~~ skipColumn( level ) ~~ putColumn( i, "ALIGN=RIGHT WIDTH=5%" )
  1745.  
  1746.       IF tmpAttributes = "" THEN
  1747.          htmlTable ~~ putColumn( tmpName , "COLSPAN=" || classSpan + 1 )
  1748.       ELSE
  1749.          htmlTable ~~ putColumn( tmpName, "COLSPAN=2" ) ~~ putColumn( smartCap( tmpAttributes ), "COLSPAN="||classSpan - 1 )
  1750.  
  1751.       IF tmpLine <> "" THEN
  1752.          htmlTable ~~ putColumn( tmpLine, "ALIGN=RIGHT WIDTH=10%" )
  1753.  
  1754.       htmlTable ~~ newRow
  1755.  
  1756.       IF tmpObject ~ errors ~ items > 0 THEN
  1757.       DO
  1758.          htmlTable ~~ skipColumn( level )
  1759.          htmlTable ~~ putColumn( "The following error(s) was (were) recorded:",,
  1760.                                  "COLSPAN=" || MAX( 1, classSpan - level )  ) ~~ newRow
  1761.          CALL show_sorted_errors htmlTable, tmpObject ~ errors, level, classSpan
  1762.       END
  1763.  
  1764.  
  1765. /* process methods */
  1766.       bDirty = .false
  1767.       htmlTable1 = .html_Table ~ new( "BORDER ALIGN=CENTER WIDTH=100%" )
  1768.    /* CLASS scope */
  1769.       IF tmpObject ~ ExposeClass ~ items > 0 THEN     /* show object variables at class scope */
  1770.       DO
  1771.          title_String = "CLASS-level object variable(s):"
  1772.          CALL dump_detail_dir2string2cols htmlTable1, tmpObject ~ ExposeClass, title_string, .false, 1
  1773.          htmlTable1 ~~ putColumn ~~ newRow
  1774.          bDirty = .true
  1775.       END
  1776.  
  1777.       IF tmpObject ~ local_Class_Methods ~ items > 0 THEN     /* show object variables at class scope */
  1778.       DO
  1779.          title_string = "CLASS METHOD(s):"
  1780.          CALL dump_detail_dir2methods htmlTable1, tmpObject ~ local_class_methods, title_string, .true
  1781.          htmlTable1 ~~ putColumn ~~ newRow
  1782.          bDirty = .true
  1783.       END
  1784.  
  1785.    /* INSTANCE scope */
  1786.       IF tmpObject ~ ExposeInstance ~ items > 0 THEN     /* show object variables at Instance scope */
  1787.       DO
  1788.          title_String = "INSTANCE-level object variable(s):"
  1789.          CALL dump_detail_dir2string2cols htmlTable1, tmpObject ~ ExposeInstance, title_string, .false, 1
  1790.          htmlTable1 ~~ putColumn ~~ newRow
  1791.          bDirty = .true
  1792.       END
  1793.  
  1794.       IF tmpObject ~ local_Instance_Methods ~ items > 0 THEN     /* show object variables at Instance scope */
  1795.       DO
  1796.          title_string = "INSTANCE METHOD(s):"
  1797.          CALL dump_detail_dir2methods htmlTable1, tmpObject ~ local_Instance_methods, title_string, .true
  1798.          htmlTable1 ~~ putColumn ~~ newRow
  1799.          bDirty = .true
  1800.       END
  1801.  
  1802.       IF bDirty THEN                                    /* was htmlTable1 written to ? */
  1803.          htmlTable ~~ skipColumn( 1 ) ~~ putColumn( htmlTable1 ~ htmlText, "COLSPAN=" || classSpan + 2 ) ~~ newRow
  1804.  
  1805.       htmlTable ~~ putColumn ~~ newRow
  1806.       html ~ lineout( htmlTable ~ htmlText )
  1807.    END
  1808.  
  1809.    RETURN
  1810.  
  1811.  
  1812.  
  1813.  
  1814. /* ---------------------------------------------------------------------------------------- */
  1815. /* dump detail of a directory pointing to strings ( SIGNATURES, RETURNS ) */
  1816. DUMP_DETAIL_DIR2STRING: PROCEDURE EXPOSE ctl.
  1817.    USE ARG htmlTable, tmpDir, title_string, skipLevel
  1818.  
  1819.     /* show strings stored with directory */
  1820.     IF tmpDir ~ items = 0 THEN RETURN
  1821.  
  1822.     IF \ VAR( "skipLevel" ) THEN skipLevel = 0
  1823.     dirSpan = 8
  1824.     skipLevel = 0
  1825.  
  1826.     IF title_string <> "" THEN
  1827.        htmlTable ~~ putColumn( www_tag( title_string, "STRONG"), "COLSPAN=" || dirSpan + 1 ) ~~ newRow
  1828.  
  1829.     tmpArr = sort( tmpDir )
  1830.  
  1831.     DO i = 1 TO tmpArr ~ items                        /* display entries */
  1832.        htmlTable ~~ putColumn( i, "ALIGN=RIGHT WIDTH=5%" ) ~~ ,
  1833.                     putColumn( smartCap( pp( tmpDir ~ entry( tmpArr[ i ] ) ), "Cap", .false ), "COLSPAN=" || dirSpan ) ~~ newRow
  1834.     END
  1835.     RETURN
  1836.  
  1837.  
  1838. /* ---------------------------------------------------------------------------------------- */
  1839. /* dump detail of a directory pointing to strings ( Object variables ), use two cols */
  1840. DUMP_DETAIL_DIR2STRING2COLS: PROCEDURE EXPOSE ctl.
  1841.    USE ARG htmlTable, tmpDir, title_string, skipLevel
  1842.  
  1843.     /* show strings stored with directory */
  1844.     IF tmpDir ~ items = 0 THEN RETURN
  1845.  
  1846.     IF \ VAR( "skipLevel" ) THEN skipLevel = 0
  1847.     dirSpan = 9
  1848.     cols = 3
  1849.     dirSpanCols = dirSpan / cols - 1            /* account for # col */
  1850.  
  1851.     IF title_string <> "" THEN
  1852.        htmlTable ~~ putColumn( www_tag( title_string, "STRONG"), "COLSPAN=" || dirSpan + 1 ) ~~ newRow
  1853.  
  1854.     tmpArr = sort( tmpDir )
  1855.     maxItems = tmpArr ~ items
  1856.  
  1857.     step = (maxItems - 1 ) % cols + 1
  1858.  
  1859.     DO i = 1 TO maxItems FOR step                       /* display entries */
  1860.        DO k = 0 TO cols - 1
  1861.           m = i + k * step
  1862.           IF m > maxItems THEN LEAVE
  1863.           htmlTable ~~ putColumn( m, "ALIGN=RIGHT WIDTH=5%" ) ~~ ,
  1864.                        putColumn( smartCap( pp( tmpDir ~ entry( tmpArr[ m ] ) ), "CAP", .false ), "COLSPAN=" || dirSpanCols )
  1865.        END
  1866.        htmlTable ~~ newRow
  1867.     END
  1868.  
  1869.     RETURN
  1870.  
  1871.  
  1872.  
  1873.  
  1874. /* ---------------------------------------------------------------------------------------- */
  1875. /* dump directory of same objects */
  1876. DUMP_DIRECTORY: PROCEDURE EXPOSE ctl.
  1877.    USE ARG html, tmpDir, tmpFile, Object2Files, title_string, with_line_nrs, bHyperLinks
  1878.  
  1879.    IF \var( "with_line_nrs" ) THEN with_line_nrs = .false
  1880.    IF \var( "bHyperLinks" ) THEN bHyperLinks = .false
  1881.  
  1882.    IF tmpDir ~ items = 0 THEN RETURN            /* nothing to do */
  1883.  
  1884.    tmpArray = sort( tmpDir )                 /* sort directory */
  1885.    maxArray    = tmpArray ~ items            /* get maximum array-elements */
  1886.  
  1887.    htmlTable = .html_Table ~ new( "ALIGN=CENTER WIDTH=100%" )
  1888.    html ~ h4( title_string )
  1889.  
  1890.    DO k = 1 TO maxArray
  1891.       tmpObject      = tmpDir ~ entry( tmpArray[ k ] )       /* get first token object accessible */
  1892.       tmpObjectFile  = Object2Files ~ index( tmpObject )     /* get file-object in which token is defined in */
  1893.  
  1894.       htmlTable ~ putColumn( k, "ALIGN=RIGHT WIDTH=5%" )              /* put nr. of item */
  1895.  
  1896.       IF tmpObject = ctl.eMissingClass THEN                  /* missing class in hand ? */
  1897.          tmpString = pp( k "->" tmpObject ~ name )           /* indicate missing class ! */
  1898.       ELSE
  1899.       DO
  1900.          tmpString = pp( tmpObject ~ name )                  /* get name of object */
  1901.       END
  1902.  
  1903.       tmpString = smartCap( tmpString )
  1904.  
  1905.       IF bHyperLinks THEN                                    /* get anchor name from object */
  1906.       DO
  1907.          IF tmpObjectFile <> tmpFile THEN                    /* in another file ! */
  1908.             tmpObjectFileHtml = tmpObjectFile ~ User_Slot ~ entry( "HTMLFileName" )     /* return HTML-file for file object */
  1909.          ELSE
  1910.             tmpObjectFileHtml = ""
  1911.  
  1912.          /* define a hyper link to tmpObject in question */
  1913.          tmpString = .html.reference ~ A_HREF( tmpObject,  tmpString, tmpObjectFileHTML )
  1914.       END
  1915.  
  1916.       htmlTable ~ putColumn( tmpString, "WIDTH=25%" )                     /* write name of tmpObject */
  1917.  
  1918.       IF tmpObjectFile <> tmpFile THEN                       /* if files differ, indicate source-file */
  1919.       DO
  1920.          IF tmpObjectFile <> .nil then                       /* e.g. def_class for missing-class has not file */
  1921.          DO
  1922.             htmlTable ~~ putColumn( "from:", "WIDTH=10%" )
  1923.  
  1924.             IF bHyperLinks THEN                              /* get anchor name from object */
  1925.                htmlTable ~~ putColumn( a_href( tmpObjectFileHTML, "Start", smartCap( pp( tmpObjectFile ~ shortName ) ) ), "WIDTH=25%" )
  1926.             ELSE
  1927.                htmlTable ~~ putColumn( smartCap( pp( tmpObjectFile ~ shortName ) ), "WIDTH=25%" )
  1928.          END
  1929.       END
  1930.       ELSE
  1931.          htmlTable ~ SkipColumn( 2 )
  1932.  
  1933.       IF with_line_nrs THEN
  1934.          htmlTable ~ putColumn( pp_lineNr( x2bare( tmpObject ~ LineNr ) ), "ALIGN=RIGHT WIDTH=25%" )
  1935.       ELSE
  1936.          htmlTable ~ SkipColumn
  1937.  
  1938.       htmlTable ~ newRow( 5 )                                /* total of 5 columns to fixup */
  1939.    END
  1940.    html ~ LINEOUT( htmlTable ~ htmlText )
  1941.    html ~ hr( , "WIDTH=75%" )
  1942.    RETURN
  1943.  
  1944.  
  1945.  
  1946. /* ---------------------------------------------------------------------------------------- */
  1947. SORT_DEF_LIST: PROCEDURE  EXPOSE ctl.
  1948.    USE ARG htmlTable, def_list
  1949.  
  1950.    tmpArray = .array ~ new                      /* create empty array */
  1951.  
  1952.    tmpSupp = def_list ~ supplier                /* get a supplier for list */
  1953.    delimiter = "ff"x
  1954.    i = 1
  1955.    DO WHILE tmpSupp ~ available
  1956.       tmpName = tmpSupp ~ item ~ name
  1957.                                                 /* store name in array */
  1958.       tmpArray[ i ] = tmpName || delimiter || FILESPEC( "Name", tmpName )
  1959.  
  1960.       tmpSupp ~ next
  1961.       i = i + 1
  1962.    END
  1963.  
  1964.    tmpArray = sort( tmpArray )                  /* sort by filename only */
  1965.  
  1966.    DO item OVER tmpArray
  1967.       PARSE VAR item fullName ( delimiter ) shortName
  1968.  
  1969.       /* define a hyperlink to file, pointing to anchor "Start" */
  1970.       HtmlFile = ctl.eFiles ~ entry( fullName ) ~ User_Slot ~ entry( "HTMLFileName" )
  1971.       tmpShortName  = a_href( HtmlFile, "Start", smartCap( shortName ) )
  1972.  
  1973.       htmlTable ~~ putColumn( tmpShortName, "WIDTH=25%" ) ~~,
  1974.                    putColumn( smartCap( fullName  ), "WIDTH=50%" ) ~~ newRow
  1975.    END
  1976.  
  1977.    RETURN
  1978.  
  1979. /* ---------------------------------------------------------------------------------------- */
  1980.  
  1981. /* return the line number in edited form */
  1982. pp_lineNr : PROCEDURE  EXPOSE ctl.
  1983.    USE ARG arg
  1984.    IF arg = .nil THEN RETURN ""         /* line number absent ? */
  1985.    RETURN "@ l#" pp( ARG(1) )
  1986.  
  1987.  
  1988.  
  1989. /* ---------------------------------------------------------------------------------------- */
  1990. SHOW_SORTED_ERRORS: PROCEDURE  EXPOSE ctl.
  1991.    USE ARG htmlTable, container, skipNrCols, spanCols
  1992.  
  1993.    IF \VAR( "skipNrCols" ) THEN skipNrCols = 0          /* no columns to skip for indentation   */
  1994.    IF \VAR( "spanCols"   ) THEN spanCols   = 1          /* span # of cols                       */
  1995.  
  1996.    sorted = sort( container )
  1997.  
  1998.    DO i = 1 TO sorted ~ items
  1999.       htmlTable ~~ skipColumn( skipNrCols ) ~~ putColumn( .Red.Dot x2bare( sorted[ i ] ),,
  2000.                                                "COLSPAN=" || MAX(1, spanCols - skipNrCols )  ) ~~ newRow
  2001.    END
  2002.  
  2003.    RETURN
  2004.  
  2005.  
  2006.  
  2007.  
  2008.  
  2009.  
  2010. /* ---------------------------------------------------------------------------------------- */
  2011. GET_HTML_FILE_NAME : PROCEDURE EXPOSE ctl.
  2012.    USE ARG object, presentFile
  2013.  
  2014.    IF \ VAR( "presentFile" ) THEN presentFile = .nil
  2015.  
  2016.    tmpFile = ctl.eToken2Files ~ allindex( object )[ 1 ]         /* get file object of object */
  2017.  
  2018.    IF presentFile = tmpFile THEN RETURN ""                      /* local reference */
  2019.  
  2020.    RETURN tmpFile ~ User_Slot ~ entry( "HTMLFileName" )         /* return HTML-file for file object */
  2021.  
  2022.  
  2023.  
  2024.  
  2025.  
  2026. /* ---------------------------------------------------------------------------------------- */
  2027.  
  2028. :: REQUIRES rgf_util.cmd
  2029. :: REQUIRES nls_util.cmd
  2030. :: REQUIRES html_util.cmd
  2031.  
  2032.  
  2033.