| 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