Class | RDoc::Fortran95parser |
In: |
lib/rdoc/parsers/parse_f95.rb
|
Parent: | Object |
See rdoc/parsers/parse_f95.rb
COMMENTS_ARE_UPPER | = | false |
|
|||||
INTERNAL_ALIAS_MES | = | "Alias for" | Internal alias message | |||||
EXTERNAL_ALIAS_MES | = | "The entity is" | External alias message |
prepare to parse a Fortran 95 file
# File lib/rdoc/parsers/parse_f95.rb, line 195 195: def initialize(top_level, file_name, body, options, stats) 196: @body = body 197: @stats = stats 198: @file_name = file_name 199: @options = options 200: @top_level = top_level 201: @progress = $stderr unless options.quiet 202: end
define code constructs
# File lib/rdoc/parsers/parse_f95.rb, line 205 205: def scan 206: 207: # remove private comment 208: remaining_code = remove_private_comments(@body) 209: 210: # continuation lines are united to one line 211: remaining_code = united_to_one_line(remaining_code) 212: 213: # semicolons are replaced to line feed 214: remaining_code = semicolon_to_linefeed(remaining_code) 215: 216: # collect comment for file entity 217: whole_comment, remaining_code = collect_first_comment(remaining_code) 218: @top_level.comment = whole_comment 219: 220: # String "remaining_code" is converted to Array "remaining_lines" 221: remaining_lines = remaining_code.split("\n") 222: 223: # "module" or "program" parts are parsed (new) 224: # 225: level_depth = 0 226: block_searching_flag = nil 227: block_searching_lines = [] 228: pre_comment = [] 229: module_program_trailing = "" 230: module_program_name = "" 231: other_block_level_depth = 0 232: other_block_searching_flag = nil 233: remaining_lines.collect!{|line| 234: if !block_searching_flag && !other_block_searching_flag 235: if line =~ /^\s*?module\s+(\w+)\s*?(!.*?)?$/i 236: block_searching_flag = :module 237: block_searching_lines << line 238: module_program_name = $1 239: module_program_trailing = find_comments($2) 240: next false 241: elsif line =~ /^\s*?program\s+(\w+)\s*?(!.*?)?$/i || 242: line =~ /^\s*?\w/ && !block_start?(line) 243: block_searching_flag = :program 244: block_searching_lines << line 245: module_program_name = $1 || "" 246: module_program_trailing = find_comments($2) 247: next false 248: 249: elsif block_start?(line) 250: other_block_searching_flag = true 251: next line 252: 253: elsif line =~ /^\s*?!\s?(.*)/ 254: pre_comment << line 255: next line 256: else 257: pre_comment = [] 258: next line 259: end 260: elsif other_block_searching_flag 261: other_block_level_depth += 1 if block_start?(line) 262: other_block_level_depth -= 1 if block_end?(line) 263: if other_block_level_depth < 0 264: other_block_level_depth = 0 265: other_block_searching_flag = nil 266: end 267: next line 268: end 269: 270: block_searching_lines << line 271: level_depth += 1 if block_start?(line) 272: level_depth -= 1 if block_end?(line) 273: if level_depth >= 0 274: next false 275: end 276: 277: # "module_program_code" is formatted. 278: # ":nodoc:" flag is checked. 279: # 280: module_program_code = block_searching_lines.join("\n") 281: module_program_code = remove_empty_head_lines(module_program_code) 282: if module_program_trailing =~ /^:nodoc:/ 283: # next loop to search next block 284: level_depth = 0 285: block_searching_flag = false 286: block_searching_lines = [] 287: pre_comment = [] 288: next false 289: end 290: 291: # NormalClass is created, and added to @top_level 292: # 293: if block_searching_flag == :module 294: module_name = module_program_name 295: module_code = module_program_code 296: module_trailing = module_program_trailing 297: progress "m" 298: @stats.num_modules += 1 299: f9x_module = @top_level.add_module NormalClass, module_name 300: f9x_module.record_location @top_level 301: 302: f9x_comment = COMMENTS_ARE_UPPER ? 303: find_comments(pre_comment.join("\n")) + "\n" + module_trailing : 304: module_trailing + "\n" + find_comments(module_code.sub(/^.*$\n/i, '')) 305: f9x_module.comment = f9x_comment 306: parse_program_or_module(f9x_module, module_code) 307: 308: TopLevel.all_files.each do |name, toplevel| 309: if toplevel.include_includes?(module_name, @options.ignore_case) 310: if !toplevel.include_requires?(@file_name, @options.ignore_case) 311: toplevel.add_require(Require.new(@file_name, "")) 312: end 313: end 314: toplevel.each_classmodule{|m| 315: if m.include_includes?(module_name, @options.ignore_case) 316: if !m.include_requires?(@file_name, @options.ignore_case) 317: m.add_require(Require.new(@file_name, "")) 318: end 319: end 320: } 321: end 322: elsif block_searching_flag == :program 323: program_name = module_program_name 324: program_code = module_program_code 325: program_trailing = module_program_trailing 326: progress "p" 327: program_comment = COMMENTS_ARE_UPPER ? 328: find_comments(pre_comment.join("\n")) + "\n" + program_trailing : 329: program_trailing + "\n" + find_comments(program_code.sub(/^.*$\n/i, '')) 330: program_comment = "\n\n= <i>Program</i> <tt>#{program_name}</tt>\n\n" \ 331: + program_comment 332: @top_level.comment << program_comment 333: parse_program_or_module(@top_level, program_code, :private) 334: end 335: 336: # next loop to search next block 337: level_depth = 0 338: block_searching_flag = false 339: block_searching_lines = [] 340: pre_comment = [] 341: next false 342: } 343: 344: remaining_lines.delete_if{ |line| 345: line == false 346: } 347: 348: # External subprograms and functions are parsed 349: # 350: parse_program_or_module(@top_level, remaining_lines.join("\n"), 351: :public, true) 352: 353: @top_level 354: end
Which "line" is end of block (module, program, block data, subroutine, function) statement ?
# File lib/rdoc/parsers/parse_f95.rb, line 1582 1582: def block_end?(line) 1583: return nil if !line 1584: 1585: if line =~ /^\s*?end\s*?(!.*?)?$/i || 1586: line =~ /^\s*?end\s+module(\s+\w+)?\s*?(!.*?)?$/i || 1587: line =~ /^\s*?end\s+program(\s+\w+)?\s*?(!.*?)?$/i || 1588: line =~ /^\s*?end\s+block\s+data(\s+\w+)?\s*?(!.*?)?$/i || 1589: line =~ /^\s*?end\s+subroutine(\s+\w+)?\s*?(!.*?)?$/i || 1590: line =~ /^\s*?end\s+function(\s+\w+)?\s*?(!.*?)?$/i 1591: return true 1592: end 1593: 1594: return nil 1595: end
Which "line" is start of block (module, program, block data, subroutine, function) statement ?
# File lib/rdoc/parsers/parse_f95.rb, line 1546 1546: def block_start?(line) 1547: return nil if !line 1548: 1549: if line =~ /^\s*?module\s+(\w+)\s*?(!.*?)?$/i || 1550: line =~ /^\s*?program\s+(\w+)\s*?(!.*?)?$/i || 1551: line =~ /^\s*?block\s+data(\s+\w+)?\s*?(!.*?)?$/i || 1552: line =~ \ 1553: /^\s*? 1554: (recursive|pure|elemental)?\s*? 1555: subroutine\s+(\w+)\s*?(\(.*?\))?\s*?(!.*?)?$ 1556: /ix || 1557: line =~ \ 1558: /^\s*? 1559: (recursive|pure|elemental)?\s*? 1560: ( 1561: character\s*?(\([\w\s\=\(\)\*]+?\))?\s+ 1562: | type\s*?\([\w\s]+?\)\s+ 1563: | integer\s*?(\([\w\s\=\(\)\*]+?\))?\s+ 1564: | real\s*?(\([\w\s\=\(\)\*]+?\))?\s+ 1565: | double\s+precision\s+ 1566: | logical\s*?(\([\w\s\=\(\)\*]+?\))?\s+ 1567: | complex\s*?(\([\w\s\=\(\)\*]+?\))?\s+ 1568: )? 1569: function\s+(\w+)\s*? 1570: (\(.*?\))?(\s+result\((.*?)\))?\s*?(!.*?)?$ 1571: /ix 1572: return true 1573: end 1574: 1575: return nil 1576: end
Check external aliases
# File lib/rdoc/parsers/parse_f95.rb, line 1330 1330: def check_external_aliases(subname, params, comment, test=nil) 1331: @@external_aliases.each{ |alias_item| 1332: if subname == alias_item["old_name"] || 1333: subname.upcase == alias_item["old_name"].upcase && 1334: @options.ignore_case 1335: 1336: new_meth = initialize_external_method(alias_item["new_name"], 1337: subname, params, @file_name, 1338: comment) 1339: new_meth.visibility = alias_item["visibility"] 1340: 1341: progress "e" 1342: @stats.num_methods += 1 1343: alias_item["file_or_module"].add_method(new_meth) 1344: 1345: if !alias_item["file_or_module"].include_requires?(@file_name, @options.ignore_case) 1346: alias_item["file_or_module"].add_require(Require.new(@file_name, "")) 1347: end 1348: end 1349: } 1350: end
Check public_methods
# File lib/rdoc/parsers/parse_f95.rb, line 1355 1355: def check_public_methods(method, parent) 1356: return if !method || !parent 1357: @@public_methods.each{ |alias_item| 1358: parent_is_used_module = nil 1359: alias_item["used_modules"].each{ |used_module| 1360: if used_module == parent || 1361: used_module.upcase == parent.upcase && 1362: @options.ignore_case 1363: parent_is_used_module = true 1364: end 1365: } 1366: next if !parent_is_used_module 1367: 1368: if method.name == alias_item["name"] || 1369: method.name.upcase == alias_item["name"].upcase && 1370: @options.ignore_case 1371: 1372: new_meth = initialize_public_method(method, parent) 1373: if alias_item["local_name"] 1374: new_meth.name = alias_item["local_name"] 1375: end 1376: 1377: progress "e" 1378: @stats.num_methods += 1 1379: alias_item["file_or_module"].add_method new_meth 1380: end 1381: } 1382: end
Collect comment for file entity
# File lib/rdoc/parsers/parse_f95.rb, line 1039 1039: def collect_first_comment(body) 1040: comment = "" 1041: not_comment = "" 1042: comment_start = false 1043: comment_end = false 1044: body.split("\n").each{ |line| 1045: if comment_end 1046: not_comment << line 1047: not_comment << "\n" 1048: elsif /^\s*?!\s?(.*)$/i =~ line 1049: comment_start = true 1050: comment << $1 1051: comment << "\n" 1052: elsif /^\s*?$/i =~ line 1053: comment_end = true if comment_start && COMMENTS_ARE_UPPER 1054: else 1055: comment_end = true 1056: not_comment << line 1057: not_comment << "\n" 1058: end 1059: } 1060: return comment, not_comment 1061: end
Comment out checker
# File lib/rdoc/parsers/parse_f95.rb, line 1477 1477: def comment_out?(line) 1478: return nil unless line 1479: commentout = false 1480: squote = false ; dquote = false 1481: line.split("").each { |char| 1482: if !(squote) && !(dquote) 1483: case char 1484: when "!" ; commentout = true ; break 1485: when "\""; dquote = true 1486: when "\'"; squote = true 1487: else next 1488: end 1489: elsif squote 1490: case char 1491: when "\'"; squote = false 1492: else next 1493: end 1494: elsif dquote 1495: case char 1496: when "\""; dquote = false 1497: else next 1498: end 1499: end 1500: } 1501: return commentout 1502: end
Continuous line checker
# File lib/rdoc/parsers/parse_f95.rb, line 1463 1463: def continuous_line?(line) 1464: continuous = false 1465: if /&\s*?(!.*)?$/ =~ line 1466: continuous = true 1467: if comment_out?($~.pre_match) 1468: continuous = false 1469: end 1470: end 1471: return continuous 1472: end
Parse string argument "text", and Return Array of Fortran95Definition object
# File lib/rdoc/parsers/parse_f95.rb, line 1712 1712: def definition_info(text) 1713: return nil unless text 1714: lines = "#{text}" 1715: defs = Array.new 1716: comment = "" 1717: trailing_comment = "" 1718: under_comment_valid = false 1719: lines.split("\n").each{ |line| 1720: if /^\s*?!\s?(.*)/ =~ line 1721: if COMMENTS_ARE_UPPER 1722: comment << remove_header_marker($1) 1723: comment << "\n" 1724: elsif defs[-1] && under_comment_valid 1725: defs[-1].comment << "\n" 1726: defs[-1].comment << remove_header_marker($1) 1727: end 1728: next 1729: elsif /^\s*?$/ =~ line 1730: comment = "" 1731: under_comment_valid = false 1732: next 1733: end 1734: type = "" 1735: characters = "" 1736: if line =~ /^\s*? 1737: ( 1738: character\s*?(\([\w\s\=\(\)\*]+?\))?[\s\,]* 1739: | type\s*?\([\w\s]+?\)[\s\,]* 1740: | integer\s*?(\([\w\s\=\(\)\*]+?\))?[\s\,]* 1741: | real\s*?(\([\w\s\=\(\)\*]+?\))?[\s\,]* 1742: | double\s+precision[\s\,]* 1743: | logical\s*?(\([\w\s\=\(\)\*]+?\))?[\s\,]* 1744: | complex\s*?(\([\w\s\=\(\)\*]+?\))?[\s\,]* 1745: ) 1746: (.*?::)? 1747: (.+)$ 1748: /ix 1749: characters = $8 1750: type = $1 1751: type << $7.gsub(/::/, '').gsub(/^\s*?\,/, '') if $7 1752: else 1753: under_comment_valid = false 1754: next 1755: end 1756: squote = false ; dquote = false ; bracket = 0 1757: iniflag = false; commentflag = false 1758: varname = "" ; arraysuffix = "" ; inivalue = "" 1759: start_pos = defs.size 1760: characters.split("").each { |char| 1761: if !(squote) && !(dquote) && bracket <= 0 && !(iniflag) && !(commentflag) 1762: case char 1763: when "!" ; commentflag = true 1764: when "(" ; bracket += 1 ; arraysuffix = char 1765: when "\""; dquote = true 1766: when "\'"; squote = true 1767: when "=" ; iniflag = true ; inivalue << char 1768: when "," 1769: defs << Fortran95Definition.new(varname, type, inivalue, arraysuffix, comment) 1770: varname = "" ; arraysuffix = "" ; inivalue = "" 1771: under_comment_valid = true 1772: when " " ; next 1773: else ; varname << char 1774: end 1775: elsif commentflag 1776: comment << remove_header_marker(char) 1777: trailing_comment << remove_header_marker(char) 1778: elsif iniflag 1779: if dquote 1780: case char 1781: when "\"" ; dquote = false ; inivalue << char 1782: else ; inivalue << char 1783: end 1784: elsif squote 1785: case char 1786: when "\'" ; squote = false ; inivalue << char 1787: else ; inivalue << char 1788: end 1789: elsif bracket > 0 1790: case char 1791: when "(" ; bracket += 1 ; inivalue << char 1792: when ")" ; bracket -= 1 ; inivalue << char 1793: else ; inivalue << char 1794: end 1795: else 1796: case char 1797: when "," 1798: defs << Fortran95Definition.new(varname, type, inivalue, arraysuffix, comment) 1799: varname = "" ; arraysuffix = "" ; inivalue = "" 1800: iniflag = false 1801: under_comment_valid = true 1802: when "(" ; bracket += 1 ; inivalue << char 1803: when "\""; dquote = true ; inivalue << char 1804: when "\'"; squote = true ; inivalue << char 1805: when "!" ; commentflag = true 1806: else ; inivalue << char 1807: end 1808: end 1809: elsif !(squote) && !(dquote) && bracket > 0 1810: case char 1811: when "(" ; bracket += 1 ; arraysuffix << char 1812: when ")" ; bracket -= 1 ; arraysuffix << char 1813: else ; arraysuffix << char 1814: end 1815: elsif squote 1816: case char 1817: when "\'"; squote = false ; inivalue << char 1818: else ; inivalue << char 1819: end 1820: elsif dquote 1821: case char 1822: when "\""; dquote = false ; inivalue << char 1823: else ; inivalue << char 1824: end 1825: end 1826: } 1827: defs << Fortran95Definition.new(varname, type, inivalue, arraysuffix, comment) 1828: if trailing_comment =~ /^:nodoc:/ 1829: defs[start_pos..-1].collect!{ |defitem| 1830: defitem.nodoc = true 1831: } 1832: end 1833: varname = "" ; arraysuffix = "" ; inivalue = "" 1834: comment = "" 1835: under_comment_valid = true 1836: trailing_comment = "" 1837: } 1838: return defs 1839: end
Return comments of definitions of arguments
If "all" argument is true, information of all arguments are returned. If "modified_params" is true, list of arguments are decorated, for example, optional arguments are parenthetic as "[arg]".
# File lib/rdoc/parsers/parse_f95.rb, line 1070 1070: def find_arguments(args, text, all=nil, indent=nil, modified_params=nil) 1071: return unless args || all 1072: indent = "" unless indent 1073: args = ["all"] if all 1074: params = "" if modified_params 1075: comma = "" 1076: return unless text 1077: args_rdocforms = "\n" 1078: remaining_lines = "#{text}" 1079: definitions = definition_info(remaining_lines) 1080: args.each{ |arg| 1081: arg.strip! 1082: arg.chomp! 1083: definitions.each { |defitem| 1084: if arg == defitem.varname.strip.chomp || all 1085: args_rdocforms << "\n\#{indent}<tt><b>\#{defitem.varname.chomp.strip}\#{defitem.arraysuffix}</b> \#{defitem.inivalue}</tt> ::\n\#{indent} <tt>\#{defitem.types.chomp.strip}</tt>\n" 1086: if !defitem.comment.chomp.strip.empty? 1087: comment = "" 1088: defitem.comment.split("\n").each{ |line| 1089: comment << " " + line + "\n" 1090: } 1091: args_rdocforms << "\n\#{indent} <tt></tt> ::\n\#{indent} <tt></tt>\n\#{indent} \#{comment.chomp.strip}\n" 1092: end 1093: 1094: if modified_params 1095: if defitem.include_attr?("optional") 1096: params << "#{comma}[#{arg}]" 1097: else 1098: params << "#{comma}#{arg}" 1099: end 1100: comma = ", " 1101: end 1102: end 1103: } 1104: } 1105: if modified_params 1106: return args_rdocforms, params 1107: else 1108: return args_rdocforms 1109: end 1110: end
Comments just after module or subprogram, or arguments are returned. If "COMMENTS_ARE_UPPER" is true, comments just before modules or subprograms are returned
# File lib/rdoc/parsers/parse_f95.rb, line 1151 1151: def find_comments text 1152: return "" unless text 1153: lines = text.split("\n") 1154: lines.reverse! if COMMENTS_ARE_UPPER 1155: comment_block = Array.new 1156: lines.each do |line| 1157: break if line =~ /^\s*?\w/ || line =~ /^\s*?$/ 1158: if COMMENTS_ARE_UPPER 1159: comment_block.unshift line.sub(/^\s*?!\s?/,"") 1160: else 1161: comment_block.push line.sub(/^\s*?!\s?/,"") 1162: end 1163: end 1164: nice_lines = comment_block.join("\n").split "\n\s*?\n" 1165: nice_lines[0] ||= "" 1166: nice_lines.shift 1167: end
Return comments of definitions of namelists
# File lib/rdoc/parsers/parse_f95.rb, line 1125 1125: def find_namelists(text, before_contains=nil) 1126: return nil if !text 1127: result = "" 1128: lines = "#{text}" 1129: before_contains = "" if !before_contains 1130: while lines =~ /^\s*?namelist\s+\/\s*?(\w+)\s*?\/([\s\w\,]+)$/i 1131: lines = $~.post_match 1132: nml_comment = COMMENTS_ARE_UPPER ? 1133: find_comments($~.pre_match) : find_comments($~.post_match) 1134: nml_name = $1 1135: nml_args = $2.split(",") 1136: result << "\n\n=== NAMELIST <tt><b>" + nml_name + "</tt></b>\n\n" 1137: result << nml_comment + "\n" if nml_comment 1138: if lines.split("\n")[0] =~ /^\//i 1139: lines = "namelist " + lines 1140: end 1141: result << find_arguments(nml_args, "#{text}" + "\n" + before_contains) 1142: end 1143: return result 1144: end
Find visibility
# File lib/rdoc/parsers/parse_f95.rb, line 1314 1314: def find_visibility(container, subname, visibility_info) 1315: return nil if !subname || !visibility_info 1316: visibility_info.each{ |info| 1317: if info["name"] == subname || 1318: @options.ignore_case && info["name"].upcase == subname.upcase 1319: if info["parent"] == container.name 1320: return info["visibility"] 1321: end 1322: end 1323: } 1324: return nil 1325: end
Create method for external alias
If argument "internal" is true, file is ignored.
# File lib/rdoc/parsers/parse_f95.rb, line 1196 1196: def initialize_external_method(new, old, params, file, comment, token=nil, 1197: internal=nil, nolink=nil) 1198: return nil unless new || old 1199: 1200: if internal 1201: external_alias_header = "#{INTERNAL_ALIAS_MES} " 1202: external_alias_text = external_alias_header + old 1203: elsif file 1204: external_alias_header = "#{EXTERNAL_ALIAS_MES} " 1205: external_alias_text = external_alias_header + file + "#" + old 1206: else 1207: return nil 1208: end 1209: external_meth = AnyMethod.new(external_alias_text, new) 1210: external_meth.singleton = false 1211: external_meth.params = params 1212: external_comment = remove_trailing_alias(comment) + "\n\n" if comment 1213: external_meth.comment = external_comment || "" 1214: if nolink && token 1215: external_meth.start_collecting_tokens 1216: external_meth.add_token Token.new(1,1).set_text(token) 1217: else 1218: external_meth.comment << external_alias_text 1219: end 1220: 1221: return external_meth 1222: end
Create method for internal alias
# File lib/rdoc/parsers/parse_f95.rb, line 1179 1179: def initialize_public_method(method, parent) 1180: return if !method || !parent 1181: 1182: new_meth = AnyMethod.new("External Alias for module", method.name) 1183: new_meth.singleton = method.singleton 1184: new_meth.params = method.params.clone 1185: new_meth.comment = remove_trailing_alias(method.comment.clone) 1186: new_meth.comment << "\n\n#{EXTERNAL_ALIAS_MES} #{parent.strip.chomp}\##{method.name}" 1187: 1188: return new_meth 1189: end
# File lib/rdoc/parsers/parse_f95.rb, line 358 358: def parse_program_or_module(container, code, 359: visibility=:public, external=nil) 360: return unless container 361: return unless code 362: remaining_lines = code.split("\n") 363: remaining_code = "#{code}" 364: 365: # 366: # Parse variables before "contains" in module 367: # 368: level_depth = 0 369: before_contains_lines = [] 370: before_contains_code = nil 371: before_contains_flag = nil 372: remaining_lines.each{ |line| 373: if !before_contains_flag 374: if line =~ /^\s*?module\s+\w+\s*?(!.*?)?$/i 375: before_contains_flag = true 376: end 377: else 378: break if line =~ /^\s*?contains\s*?(!.*?)?$/i 379: level_depth += 1 if block_start?(line) 380: level_depth -= 1 if block_end?(line) 381: break if level_depth < 0 382: before_contains_lines << line 383: end 384: } 385: before_contains_code = before_contains_lines.join("\n") 386: if before_contains_code 387: before_contains_code.gsub!(/^\s*?interface\s+.*?\s+end\s+interface.*?$/im, "") 388: before_contains_code.gsub!(/^\s*?type[\s\,]+.*?\s+end\s+type.*?$/im, "") 389: end 390: 391: # 392: # Parse global "use" 393: # 394: use_check_code = "#{before_contains_code}" 395: cascaded_modules_list = [] 396: while use_check_code =~ /^\s*?use\s+(\w+)(.*?)(!.*?)?$/i 397: use_check_code = $~.pre_match 398: use_check_code << $~.post_match 399: used_mod_name = $1.strip.chomp 400: used_list = $2 || "" 401: used_trailing = $3 || "" 402: next if used_trailing =~ /!:nodoc:/ 403: if !container.include_includes?(used_mod_name, @options.ignore_case) 404: progress "." 405: container.add_include Include.new(used_mod_name, "") 406: end 407: if ! (used_list =~ /\,\s*?only\s*?:/i ) 408: cascaded_modules_list << "\#" + used_mod_name 409: end 410: end 411: 412: # 413: # Parse public and private, and store information. 414: # This information is used when "add_method" and 415: # "set_visibility_for" are called. 416: # 417: visibility_default, visibility_info = 418: parse_visibility(remaining_lines.join("\n"), visibility, container) 419: @@public_methods.concat visibility_info 420: if visibility_default == :public 421: if !cascaded_modules_list.empty? 422: cascaded_modules = 423: Attr.new("Cascaded Modules", 424: "Imported modules all of whose components are published again", 425: "", 426: cascaded_modules_list.join(", ")) 427: container.add_attribute(cascaded_modules) 428: end 429: end 430: 431: # 432: # Check rename elements 433: # 434: use_check_code = "#{before_contains_code}" 435: while use_check_code =~ /^\s*?use\s+(\w+)\s*?\,(.+)$/i 436: use_check_code = $~.pre_match 437: use_check_code << $~.post_match 438: used_mod_name = $1.strip.chomp 439: used_elements = $2.sub(/\s*?only\s*?:\s*?/i, '') 440: used_elements.split(",").each{ |used| 441: if /\s*?(\w+)\s*?=>\s*?(\w+)\s*?/ =~ used 442: local = $1 443: org = $2 444: @@public_methods.collect!{ |pub_meth| 445: if local == pub_meth["name"] || 446: local.upcase == pub_meth["name"].upcase && 447: @options.ignore_case 448: pub_meth["name"] = org 449: pub_meth["local_name"] = local 450: end 451: pub_meth 452: } 453: end 454: } 455: end 456: 457: # 458: # Parse private "use" 459: # 460: use_check_code = remaining_lines.join("\n") 461: while use_check_code =~ /^\s*?use\s+(\w+)(.*?)(!.*?)?$/i 462: use_check_code = $~.pre_match 463: use_check_code << $~.post_match 464: used_mod_name = $1.strip.chomp 465: used_trailing = $3 || "" 466: next if used_trailing =~ /!:nodoc:/ 467: if !container.include_includes?(used_mod_name, @options.ignore_case) 468: progress "." 469: container.add_include Include.new(used_mod_name, "") 470: end 471: end 472: 473: container.each_includes{ |inc| 474: TopLevel.all_files.each do |name, toplevel| 475: indicated_mod = toplevel.find_symbol(inc.name, 476: nil, @options.ignore_case) 477: if indicated_mod 478: indicated_name = indicated_mod.parent.file_relative_name 479: if !container.include_requires?(indicated_name, @options.ignore_case) 480: container.add_require(Require.new(indicated_name, "")) 481: end 482: break 483: end 484: end 485: } 486: 487: # 488: # Parse derived-types definitions 489: # 490: derived_types_comment = "" 491: remaining_code = remaining_lines.join("\n") 492: while remaining_code =~ /^\s*? 493: type[\s\,]+(public|private)?\s*?(::)?\s*? 494: (\w+)\s*?(!.*?)?$ 495: (.*?) 496: ^\s*?end\s+type.*?$ 497: /imx 498: remaining_code = $~.pre_match 499: remaining_code << $~.post_match 500: typename = $3.chomp.strip 501: type_elements = $5 || "" 502: type_code = remove_empty_head_lines($&) 503: type_trailing = find_comments($4) 504: next if type_trailing =~ /^:nodoc:/ 505: type_visibility = $1 506: type_comment = COMMENTS_ARE_UPPER ? 507: find_comments($~.pre_match) + "\n" + type_trailing : 508: type_trailing + "\n" + find_comments(type_code.sub(/^.*$\n/i, '')) 509: type_element_visibility_public = true 510: type_code.split("\n").each{ |line| 511: if /^\s*?private\s*?$/ =~ line 512: type_element_visibility_public = nil 513: break 514: end 515: } if type_code 516: 517: args_comment = "" 518: type_args_info = nil 519: 520: if @options.show_all 521: args_comment = find_arguments(nil, type_code, true) 522: else 523: type_public_args_list = [] 524: type_args_info = definition_info(type_code) 525: type_args_info.each{ |arg| 526: arg_is_public = type_element_visibility_public 527: arg_is_public = true if arg.include_attr?("public") 528: arg_is_public = nil if arg.include_attr?("private") 529: type_public_args_list << arg.varname if arg_is_public 530: } 531: args_comment = find_arguments(type_public_args_list, type_code) 532: end 533: 534: type = AnyMethod.new("type #{typename}", typename) 535: type.singleton = false 536: type.params = "" 537: type.comment = "<b><em> Derived Type </em></b> :: <tt></tt>\n" 538: type.comment << args_comment if args_comment 539: type.comment << type_comment if type_comment 540: progress "t" 541: @stats.num_methods += 1 542: container.add_method type 543: 544: set_visibility(container, typename, visibility_default, @@public_methods) 545: 546: if type_visibility 547: type_visibility.gsub!(/\s/,'') 548: type_visibility.gsub!(/\,/,'') 549: type_visibility.gsub!(/:/,'') 550: type_visibility.downcase! 551: if type_visibility == "public" 552: container.set_visibility_for([typename], :public) 553: elsif type_visibility == "private" 554: container.set_visibility_for([typename], :private) 555: end 556: end 557: 558: check_public_methods(type, container.name) 559: 560: if @options.show_all 561: derived_types_comment << ", " unless derived_types_comment.empty? 562: derived_types_comment << typename 563: else 564: if type.visibility == :public 565: derived_types_comment << ", " unless derived_types_comment.empty? 566: derived_types_comment << typename 567: end 568: end 569: 570: end 571: 572: if !derived_types_comment.empty? 573: derived_types_table = 574: Attr.new("Derived Types", "Derived_Types", "", 575: derived_types_comment) 576: container.add_attribute(derived_types_table) 577: end 578: 579: # 580: # move interface scope 581: # 582: interface_code = "" 583: while remaining_code =~ /^\s*? 584: interface( 585: \s+\w+ | 586: \s+operator\s*?\(.*?\) | 587: \s+assignment\s*?\(\s*?=\s*?\) 588: )?\s*?$ 589: (.*?) 590: ^\s*?end\s+interface.*?$ 591: /imx 592: interface_code << remove_empty_head_lines($&) + "\n" 593: remaining_code = $~.pre_match 594: remaining_code << $~.post_match 595: end 596: 597: # 598: # Parse global constants or variables in modules 599: # 600: const_var_defs = definition_info(before_contains_code) 601: const_var_defs.each{|defitem| 602: next if defitem.nodoc 603: const_or_var_type = "Variable" 604: const_or_var_progress = "v" 605: if defitem.include_attr?("parameter") 606: const_or_var_type = "Constant" 607: const_or_var_progress = "c" 608: end 609: const_or_var = AnyMethod.new(const_or_var_type, defitem.varname) 610: const_or_var.singleton = false 611: const_or_var.params = "" 612: self_comment = find_arguments([defitem.varname], before_contains_code) 613: const_or_var.comment = "<b><em>" + const_or_var_type + "</em></b> :: <tt></tt>\n" 614: const_or_var.comment << self_comment if self_comment 615: progress const_or_var_progress 616: @stats.num_methods += 1 617: container.add_method const_or_var 618: 619: set_visibility(container, defitem.varname, visibility_default, @@public_methods) 620: 621: if defitem.include_attr?("public") 622: container.set_visibility_for([defitem.varname], :public) 623: elsif defitem.include_attr?("private") 624: container.set_visibility_for([defitem.varname], :private) 625: end 626: 627: check_public_methods(const_or_var, container.name) 628: 629: } if const_var_defs 630: 631: remaining_lines = remaining_code.split("\n") 632: 633: # "subroutine" or "function" parts are parsed (new) 634: # 635: level_depth = 0 636: block_searching_flag = nil 637: block_searching_lines = [] 638: pre_comment = [] 639: procedure_trailing = "" 640: procedure_name = "" 641: procedure_params = "" 642: procedure_prefix = "" 643: procedure_result_arg = "" 644: procedure_type = "" 645: contains_lines = [] 646: contains_flag = nil 647: remaining_lines.collect!{|line| 648: if !block_searching_flag 649: # subroutine 650: if line =~ /^\s*? 651: (recursive|pure|elemental)?\s*? 652: subroutine\s+(\w+)\s*?(\(.*?\))?\s*?(!.*?)?$ 653: /ix 654: block_searching_flag = :subroutine 655: block_searching_lines << line 656: 657: procedure_name = $2.chomp.strip 658: procedure_params = $3 || "" 659: procedure_prefix = $1 || "" 660: procedure_trailing = $4 || "!" 661: next false 662: 663: # function 664: elsif line =~ /^\s*? 665: (recursive|pure|elemental)?\s*? 666: ( 667: character\s*?(\([\w\s\=\(\)\*]+?\))?\s+ 668: | type\s*?\([\w\s]+?\)\s+ 669: | integer\s*?(\([\w\s\=\(\)\*]+?\))?\s+ 670: | real\s*?(\([\w\s\=\(\)\*]+?\))?\s+ 671: | double\s+precision\s+ 672: | logical\s*?(\([\w\s\=\(\)\*]+?\))?\s+ 673: | complex\s*?(\([\w\s\=\(\)\*]+?\))?\s+ 674: )? 675: function\s+(\w+)\s*? 676: (\(.*?\))?(\s+result\((.*?)\))?\s*?(!.*?)?$ 677: /ix 678: block_searching_flag = :function 679: block_searching_lines << line 680: 681: procedure_prefix = $1 || "" 682: procedure_type = $2 ? $2.chomp.strip : nil 683: procedure_name = $8.chomp.strip 684: procedure_params = $9 || "" 685: procedure_result_arg = $11 ? $11.chomp.strip : procedure_name 686: procedure_trailing = $12 || "!" 687: next false 688: elsif line =~ /^\s*?!\s?(.*)/ 689: pre_comment << line 690: next line 691: else 692: pre_comment = [] 693: next line 694: end 695: end 696: contains_flag = true if line =~ /^\s*?contains\s*?(!.*?)?$/ 697: block_searching_lines << line 698: contains_lines << line if contains_flag 699: 700: level_depth += 1 if block_start?(line) 701: level_depth -= 1 if block_end?(line) 702: if level_depth >= 0 703: next false 704: end 705: 706: # "procedure_code" is formatted. 707: # ":nodoc:" flag is checked. 708: # 709: procedure_code = block_searching_lines.join("\n") 710: procedure_code = remove_empty_head_lines(procedure_code) 711: if procedure_trailing =~ /^!:nodoc:/ 712: # next loop to search next block 713: level_depth = 0 714: block_searching_flag = nil 715: block_searching_lines = [] 716: pre_comment = [] 717: procedure_trailing = "" 718: procedure_name = "" 719: procedure_params = "" 720: procedure_prefix = "" 721: procedure_result_arg = "" 722: procedure_type = "" 723: contains_lines = [] 724: contains_flag = nil 725: next false 726: end 727: 728: # AnyMethod is created, and added to container 729: # 730: subroutine_function = nil 731: if block_searching_flag == :subroutine 732: subroutine_prefix = procedure_prefix 733: subroutine_name = procedure_name 734: subroutine_params = procedure_params 735: subroutine_trailing = procedure_trailing 736: subroutine_code = procedure_code 737: 738: subroutine_comment = COMMENTS_ARE_UPPER ? 739: pre_comment.join("\n") + "\n" + subroutine_trailing : 740: subroutine_trailing + "\n" + subroutine_code.sub(/^.*$\n/i, '') 741: subroutine = AnyMethod.new("subroutine", subroutine_name) 742: parse_subprogram(subroutine, subroutine_params, 743: subroutine_comment, subroutine_code, 744: before_contains_code, nil, subroutine_prefix) 745: progress "s" 746: @stats.num_methods += 1 747: container.add_method subroutine 748: subroutine_function = subroutine 749: 750: elsif block_searching_flag == :function 751: function_prefix = procedure_prefix 752: function_type = procedure_type 753: function_name = procedure_name 754: function_params_org = procedure_params 755: function_result_arg = procedure_result_arg 756: function_trailing = procedure_trailing 757: function_code_org = procedure_code 758: 759: function_comment = COMMENTS_ARE_UPPER ? 760: pre_comment.join("\n") + "\n" + function_trailing : 761: function_trailing + "\n " + function_code_org.sub(/^.*$\n/i, '') 762: 763: function_code = "#{function_code_org}" 764: if function_type 765: function_code << "\n" + function_type + " :: " + function_result_arg 766: end 767: 768: function_params = 769: function_params_org.sub(/^\(/, "\(#{function_result_arg}, ") 770: 771: function = AnyMethod.new("function", function_name) 772: parse_subprogram(function, function_params, 773: function_comment, function_code, 774: before_contains_code, true, function_prefix) 775: 776: # Specific modification due to function 777: function.params.sub!(/\(\s*?#{function_result_arg}\s*?,\s*?/, "\( ") 778: function.params << " result(" + function_result_arg + ")" 779: function.start_collecting_tokens 780: function.add_token Token.new(1,1).set_text(function_code_org) 781: 782: progress "f" 783: @stats.num_methods += 1 784: container.add_method function 785: subroutine_function = function 786: 787: end 788: 789: # The visibility of procedure is specified 790: # 791: set_visibility(container, procedure_name, 792: visibility_default, @@public_methods) 793: 794: # The alias for this procedure from external modules 795: # 796: check_external_aliases(procedure_name, 797: subroutine_function.params, 798: subroutine_function.comment, subroutine_function) if external 799: check_public_methods(subroutine_function, container.name) 800: 801: 802: # contains_lines are parsed as private procedures 803: if contains_flag 804: parse_program_or_module(container, 805: contains_lines.join("\n"), :private) 806: end 807: 808: # next loop to search next block 809: level_depth = 0 810: block_searching_flag = nil 811: block_searching_lines = [] 812: pre_comment = [] 813: procedure_trailing = "" 814: procedure_name = "" 815: procedure_params = "" 816: procedure_prefix = "" 817: procedure_result_arg = "" 818: contains_lines = [] 819: contains_flag = nil 820: next false 821: } # End of remaining_lines.collect!{|line| 822: 823: # Array remains_lines is converted to String remains_code again 824: # 825: remaining_code = remaining_lines.join("\n") 826: 827: # 828: # Parse interface 829: # 830: interface_scope = false 831: generic_name = "" 832: interface_code.split("\n").each{ |line| 833: if /^\s*? 834: interface( 835: \s+\w+| 836: \s+operator\s*?\(.*?\)| 837: \s+assignment\s*?\(\s*?=\s*?\) 838: )? 839: \s*?(!.*?)?$ 840: /ix =~ line 841: generic_name = $1 ? $1.strip.chomp : nil 842: interface_trailing = $2 || "!" 843: interface_scope = true 844: interface_scope = false if interface_trailing =~ /!:nodoc:/ 845: # if generic_name =~ /operator\s*?\((.*?)\)/i 846: # operator_name = $1 847: # if operator_name && !operator_name.empty? 848: # generic_name = "#{operator_name}" 849: # end 850: # end 851: # if generic_name =~ /assignment\s*?\((.*?)\)/i 852: # assignment_name = $1 853: # if assignment_name && !assignment_name.empty? 854: # generic_name = "#{assignment_name}" 855: # end 856: # end 857: end 858: if /^\s*?end\s+interface/i =~ line 859: interface_scope = false 860: generic_name = nil 861: end 862: # internal alias 863: if interface_scope && /^\s*?module\s+procedure\s+(.*?)(!.*?)?$/i =~ line 864: procedures = $1.strip.chomp 865: procedures_trailing = $2 || "!" 866: next if procedures_trailing =~ /!:nodoc:/ 867: procedures.split(",").each{ |proc| 868: proc.strip! 869: proc.chomp! 870: next if generic_name == proc || !generic_name 871: old_meth = container.find_symbol(proc, nil, @options.ignore_case) 872: next if !old_meth 873: nolink = old_meth.visibility == :private ? true : nil 874: nolink = nil if @options.show_all 875: new_meth = 876: initialize_external_method(generic_name, proc, 877: old_meth.params, nil, 878: old_meth.comment, 879: old_meth.clone.token_stream[0].text, 880: true, nolink) 881: new_meth.singleton = old_meth.singleton 882: 883: progress "i" 884: @stats.num_methods += 1 885: container.add_method new_meth 886: 887: set_visibility(container, generic_name, visibility_default, @@public_methods) 888: 889: check_public_methods(new_meth, container.name) 890: 891: } 892: end 893: 894: # external aliases 895: if interface_scope 896: # subroutine 897: proc = nil 898: params = nil 899: procedures_trailing = nil 900: if line =~ /^\s*? 901: (recursive|pure|elemental)?\s*? 902: subroutine\s+(\w+)\s*?(\(.*?\))?\s*?(!.*?)?$ 903: /ix 904: proc = $2.chomp.strip 905: generic_name = proc unless generic_name 906: params = $3 || "" 907: procedures_trailing = $4 || "!" 908: 909: # function 910: elsif line =~ /^\s*? 911: (recursive|pure|elemental)?\s*? 912: ( 913: character\s*?(\([\w\s\=\(\)\*]+?\))?\s+ 914: | type\s*?\([\w\s]+?\)\s+ 915: | integer\s*?(\([\w\s\=\(\)\*]+?\))?\s+ 916: | real\s*?(\([\w\s\=\(\)\*]+?\))?\s+ 917: | double\s+precision\s+ 918: | logical\s*?(\([\w\s\=\(\)\*]+?\))?\s+ 919: | complex\s*?(\([\w\s\=\(\)\*]+?\))?\s+ 920: )? 921: function\s+(\w+)\s*? 922: (\(.*?\))?(\s+result\((.*?)\))?\s*?(!.*?)?$ 923: /ix 924: proc = $8.chomp.strip 925: generic_name = proc unless generic_name 926: params = $9 || "" 927: procedures_trailing = $12 || "!" 928: else 929: next 930: end 931: next if procedures_trailing =~ /!:nodoc:/ 932: indicated_method = nil 933: indicated_file = nil 934: TopLevel.all_files.each do |name, toplevel| 935: indicated_method = toplevel.find_local_symbol(proc, @options.ignore_case) 936: indicated_file = name 937: break if indicated_method 938: end 939: 940: if indicated_method 941: external_method = 942: initialize_external_method(generic_name, proc, 943: indicated_method.params, 944: indicated_file, 945: indicated_method.comment) 946: 947: progress "e" 948: @stats.num_methods += 1 949: container.add_method external_method 950: set_visibility(container, generic_name, visibility_default, @@public_methods) 951: if !container.include_requires?(indicated_file, @options.ignore_case) 952: container.add_require(Require.new(indicated_file, "")) 953: end 954: check_public_methods(external_method, container.name) 955: 956: else 957: @@external_aliases << { 958: "new_name" => generic_name, 959: "old_name" => proc, 960: "file_or_module" => container, 961: "visibility" => find_visibility(container, generic_name, @@public_methods) || visibility_default 962: } 963: end 964: end 965: 966: } if interface_code # End of interface_code.split("\n").each ... 967: 968: # 969: # Already imported methods are removed from @@public_methods. 970: # Remainders are assumed to be imported from other modules. 971: # 972: @@public_methods.delete_if{ |method| method["entity_is_discovered"]} 973: 974: @@public_methods.each{ |pub_meth| 975: next unless pub_meth["file_or_module"].name == container.name 976: pub_meth["used_modules"].each{ |used_mod| 977: TopLevel.all_classes_and_modules.each{ |modules| 978: if modules.name == used_mod || 979: modules.name.upcase == used_mod.upcase && 980: @options.ignore_case 981: modules.method_list.each{ |meth| 982: if meth.name == pub_meth["name"] || 983: meth.name.upcase == pub_meth["name"].upcase && 984: @options.ignore_case 985: new_meth = initialize_public_method(meth, 986: modules.name) 987: if pub_meth["local_name"] 988: new_meth.name = pub_meth["local_name"] 989: end 990: progress "e" 991: @stats.num_methods += 1 992: container.add_method new_meth 993: end 994: } 995: end 996: } 997: } 998: } 999: 1000: container 1001: end
Parse arguments, comment, code of subroutine and function. Return AnyMethod object.
# File lib/rdoc/parsers/parse_f95.rb, line 1007 1007: def parse_subprogram(subprogram, params, comment, code, 1008: before_contains=nil, function=nil, prefix=nil) 1009: subprogram.singleton = false 1010: prefix = "" if !prefix 1011: arguments = params.sub(/\(/, "").sub(/\)/, "").split(",") if params 1012: args_comment, params_opt = 1013: find_arguments(arguments, code.sub(/^s*?contains\s*?(!.*?)?$.*/im, ""), 1014: nil, nil, true) 1015: params_opt = "( " + params_opt + " ) " if params_opt 1016: subprogram.params = params_opt || "" 1017: namelist_comment = find_namelists(code, before_contains) 1018: 1019: block_comment = find_comments comment 1020: if function 1021: subprogram.comment = "<b><em> Function </em></b> :: <em>#{prefix}</em>\n" 1022: else 1023: subprogram.comment = "<b><em> Subroutine </em></b> :: <em>#{prefix}</em>\n" 1024: end 1025: subprogram.comment << args_comment if args_comment 1026: subprogram.comment << block_comment if block_comment 1027: subprogram.comment << namelist_comment if namelist_comment 1028: 1029: # For output source code 1030: subprogram.start_collecting_tokens 1031: subprogram.add_token Token.new(1,1).set_text(code) 1032: 1033: subprogram 1034: end
Parse visibility
# File lib/rdoc/parsers/parse_f95.rb, line 1229 1229: def parse_visibility(code, default, container) 1230: result = [] 1231: visibility_default = default || :public 1232: 1233: used_modules = [] 1234: container.includes.each{|i| used_modules << i.name} if container 1235: 1236: remaining_code = code.gsub(/^\s*?type[\s\,]+.*?\s+end\s+type.*?$/im, "") 1237: remaining_code.split("\n").each{ |line| 1238: if /^\s*?private\s*?$/ =~ line 1239: visibility_default = :private 1240: break 1241: end 1242: } if remaining_code 1243: 1244: remaining_code.split("\n").each{ |line| 1245: if /^\s*?private\s*?(::)?\s+(.*)\s*?(!.*?)?/i =~ line 1246: methods = $2.sub(/!.*$/, '') 1247: methods.split(",").each{ |meth| 1248: meth.sub!(/!.*$/, '') 1249: meth.gsub!(/:/, '') 1250: result << { 1251: "name" => meth.chomp.strip, 1252: "visibility" => :private, 1253: "used_modules" => used_modules.clone, 1254: "file_or_module" => container, 1255: "entity_is_discovered" => nil, 1256: "local_name" => nil 1257: } 1258: } 1259: elsif /^\s*?public\s*?(::)?\s+(.*)\s*?(!.*?)?/i =~ line 1260: methods = $2.sub(/!.*$/, '') 1261: methods.split(",").each{ |meth| 1262: meth.sub!(/!.*$/, '') 1263: meth.gsub!(/:/, '') 1264: result << { 1265: "name" => meth.chomp.strip, 1266: "visibility" => :public, 1267: "used_modules" => used_modules.clone, 1268: "file_or_module" => container, 1269: "entity_is_discovered" => nil, 1270: "local_name" => nil 1271: } 1272: } 1273: end 1274: } if remaining_code 1275: 1276: if container 1277: result.each{ |vis_info| 1278: vis_info["parent"] = container.name 1279: } 1280: end 1281: 1282: return visibility_default, result 1283: end
# File lib/rdoc/parsers/parse_f95.rb, line 1169 1169: def progress(char) 1170: unless @options.quiet 1171: @progress.print(char) 1172: @progress.flush 1173: end 1174: end
Empty lines in header are removed
# File lib/rdoc/parsers/parse_f95.rb, line 1621 1621: def remove_empty_head_lines(text) 1622: return "" unless text 1623: lines = text.split("\n") 1624: header = true 1625: lines.delete_if{ |line| 1626: header = false if /\S/ =~ line 1627: header && /^\s*?$/ =~ line 1628: } 1629: lines.join("\n") 1630: end
header marker "=", "==", … are removed
# File lib/rdoc/parsers/parse_f95.rb, line 1634 1634: def remove_header_marker(text) 1635: return text.gsub(/^\s?(=+)/, '<tt></tt>\1') 1636: end
# File lib/rdoc/parsers/parse_f95.rb, line 1638 1638: def remove_private_comments(body) 1639: body.gsub!(/^\s*!--\s*?$.*?^\s*!\+\+\s*?$/m, '') 1640: return body 1641: end
Remove "Alias for" in end of comments
# File lib/rdoc/parsers/parse_f95.rb, line 1600 1600: def remove_trailing_alias(text) 1601: return "" if !text 1602: lines = text.split("\n").reverse 1603: comment_block = Array.new 1604: checked = false 1605: lines.each do |line| 1606: if !checked 1607: if /^\s?#{INTERNAL_ALIAS_MES}/ =~ line || 1608: /^\s?#{EXTERNAL_ALIAS_MES}/ =~ line 1609: checked = true 1610: next 1611: end 1612: end 1613: comment_block.unshift line 1614: end 1615: nice_lines = comment_block.join("\n") 1616: nice_lines ||= "" 1617: return nice_lines 1618: end
Semicolons are replaced to line feed.
# File lib/rdoc/parsers/parse_f95.rb, line 1507 1507: def semicolon_to_linefeed(text) 1508: return "" unless text 1509: lines = text.split("\n") 1510: lines.collect!{ |line| 1511: words = line.split("") 1512: commentout = false 1513: squote = false ; dquote = false 1514: words.collect! { |char| 1515: if !(squote) && !(dquote) && !(commentout) 1516: case char 1517: when "!" ; commentout = true ; next char 1518: when "\""; dquote = true ; next char 1519: when "\'"; squote = true ; next char 1520: when ";" ; "\n" 1521: else next char 1522: end 1523: elsif commentout 1524: next char 1525: elsif squote 1526: case char 1527: when "\'"; squote = false ; next char 1528: else next char 1529: end 1530: elsif dquote 1531: case char 1532: when "\""; dquote = false ; next char 1533: else next char 1534: end 1535: end 1536: } 1537: words.join("") 1538: } 1539: return lines.join("\n") 1540: end
Set visibility
"subname" element of "visibility_info" is deleted.
# File lib/rdoc/parsers/parse_f95.rb, line 1290 1290: def set_visibility(container, subname, visibility_default, visibility_info) 1291: return unless container || subname || visibility_default || visibility_info 1292: not_found = true 1293: visibility_info.collect!{ |info| 1294: if info["name"] == subname || 1295: @options.ignore_case && info["name"].upcase == subname.upcase 1296: if info["file_or_module"].name == container.name 1297: container.set_visibility_for([subname], info["visibility"]) 1298: info["entity_is_discovered"] = true 1299: not_found = false 1300: end 1301: end 1302: info 1303: } 1304: if not_found 1305: return container.set_visibility_for([subname], visibility_default) 1306: else 1307: return container 1308: end 1309: end
Continuous lines are united.
Comments in continuous lines are removed.
# File lib/rdoc/parsers/parse_f95.rb, line 1389 1389: def united_to_one_line(f90src) 1390: return "" unless f90src 1391: lines = f90src.split("\n") 1392: previous_continuing = false 1393: now_continuing = false 1394: body = "" 1395: lines.each{ |line| 1396: words = line.split("") 1397: next if words.empty? && previous_continuing 1398: commentout = false 1399: brank_flag = true ; brank_char = "" 1400: squote = false ; dquote = false 1401: ignore = false 1402: words.collect! { |char| 1403: if previous_continuing && brank_flag 1404: now_continuing = true 1405: ignore = true 1406: case char 1407: when "!" ; break 1408: when " " ; brank_char << char ; next "" 1409: when "&" 1410: brank_flag = false 1411: now_continuing = false 1412: next "" 1413: else 1414: brank_flag = false 1415: now_continuing = false 1416: ignore = false 1417: next brank_char + char 1418: end 1419: end 1420: ignore = false 1421: 1422: if now_continuing 1423: next "" 1424: elsif !(squote) && !(dquote) && !(commentout) 1425: case char 1426: when "!" ; commentout = true ; next char 1427: when "\""; dquote = true ; next char 1428: when "\'"; squote = true ; next char 1429: when "&" ; now_continuing = true ; next "" 1430: else next char 1431: end 1432: elsif commentout 1433: next char 1434: elsif squote 1435: case char 1436: when "\'"; squote = false ; next char 1437: else next char 1438: end 1439: elsif dquote 1440: case char 1441: when "\""; dquote = false ; next char 1442: else next char 1443: end 1444: end 1445: } 1446: if !ignore && !previous_continuing || !brank_flag 1447: if previous_continuing 1448: body << words.join("") 1449: else 1450: body << "\n" + words.join("") 1451: end 1452: end 1453: previous_continuing = now_continuing ? true : nil 1454: now_continuing = nil 1455: } 1456: return body 1457: end