Main module for RCodeLeveler. requireLevel method is not part of it: it is in the global Module scope.
The default category (spaces have to be present to ensure users cannot use it)
The Ruby code category (spaces have to be present to ensure users cannot use it)
Get the leveled content of a specified file. This can be useful to convert files and require them then without RCodeLeveler. It can also be useful for debugging purposes.
iLibraryName (String): Name of the ruby file to require.
list<String>: The content of the file once levelized
Boolean: Is the content really different from original content ?
# File lib/rcodeleveler.rb, line 136 136: def RCodeLeveler.getLeveledFileContent(iLibraryName) 137: rSourceCode = nil 138: rDifferent = nil 139: 140: lExtension = File.extname(iLibraryName) 141: if (lExtension == '') 142: lFileNameWithExt = "#{iLibraryName}.rb" 143: else 144: lFileNameWithExt = iLibraryName 145: end 146: lRealFileName = RCodeLeveler::getRealLibraryPath(iLibraryName) 147: if (lRealFileName != nil) 148: rSourceCode, rDifferent = RCodeLeveler::getSourceFileContentLevelized(lRealFileName) 149: else 150: # Dump error 151: lDirList = $:.join(', ') 152: raise LoadError, "Unable to find file #{iLibraryName}. List of directories searched: #{lDirList}. Please use getLeveledFileContent with Ruby source files only." 153: end 154: 155: return rSourceCode, rDifferent 156: end
Reset all levels.
# File lib/rcodeleveler.rb, line 104 104: def RCodeLeveler.resetLevels 105: $RCLLevels = {K_Default_Category => 0} 106: end
Set a level for a category.
iLevel (Integer): The level
iCategory (String): The category name [optional = K_Default_Category]
# File lib/rcodeleveler.rb, line 113 113: def RCodeLeveler.setLevel(iLevel, iCategory = K_Default_Category) 114: $RCLLevels[iCategory] = iLevel 115: end
Set an optional output directory where all leveled files required using requireLevel will be written. Reset it by setting it to nil.
iDirectory (String): The directory to write files into [optional = nil]
# File lib/rcodeleveler.rb, line 123 123: def RCodeLeveler.setOutputDirectory(iDirectory = nil) 124: $RCLOutputDirectory = iDirectory 125: end
Set warning severity. 0: No warning. 1: Display them on stderr. 2: Throw an exception (default)
iWarningSeverity (Integer): Severity of warnings
# File lib/rcodeleveler.rb, line 99 99: def RCodeLeveler.setWarningSeverity(iWarningSeverity) 100: $RCLWarningSeverity = iWarningSeverity 101: end
Get the library file location. This method should search for the file EXACTLY the same way Ruby does. It has been coded bearing in mind the specifications of require and load methods of Kernel module as explained in “Programming Ruby - The Pragmatic Programmers’ Guide” Second Edition - by Dave Thomas (thanks Dave by the way for your excellent book !) It appears Ruby’s behaviour comes from the method “file.c:rb_find_file(path)” (Ruby 1.8.5).
iLibraryName (String): Name of the library to load, as given to require and load methods
String: The name of the real source file (or nil if none found)
# File lib/rcodeleveler.rb, line 203 203: def RCodeLeveler.getRealLibraryPath(iLibraryName) 204: lRealFileName = nil 205: 206: lExtension = File.extname(iLibraryName) 207: if (lExtension == '') 208: lFileNameWithExt = "#{iLibraryName}.rb" 209: else 210: lFileNameWithExt = iLibraryName 211: end 212: # Find the real file 213: if ((lExtension == '') or 214: (lExtension == '.rb')) 215: if (File.expand_path(iLibraryName) == iLibraryName) 216: # Absolute form 217: if (File.exist?(lFileNameWithExt)) 218: lRealFileName = lFileNameWithExt 219: end 220: else 221: # Relative form 222: # Find in each directory of $: 223: $:.each do |iDir| 224: lFilePathAttempt = "#{iDir}/#{lFileNameWithExt}" 225: if (File.exist?(lFilePathAttempt)) 226: # We found it 227: lRealFileName = lFilePathAttempt 228: break 229: end 230: end 231: end 232: # lRealFileName contains the real file name, or nil if none found 233: end 234: 235: return lRealFileName 236: end
Get the content of a file once levelized.
iFileName (String): Path to the source file to level
iOutputFileName (String): If set, specifies a file name to write the leveled file [optional = nil]
list<String>: The content of the file once levelized
Boolean: Is the content really different from original content ?
# File lib/rcodeleveler.rb, line 246 246: def RCodeLeveler.getSourceFileContentLevelized(iFileName, iOutputFileName = nil) 247: lNewFileContents = [] 248: lFoundUsefulLVLMacro = false 249: 250: # The stack of level sections 251: # list< [ String, Integer ] > 252: # Category Level 253: lLevelSections = [] 254: # The map of highest level sections 255: # map< String, Integer ] > 256: # Category HighestLevel 257: lHighestLevelSections = {} 258: #puts "----- $RCLLevels=#{$RCLLevels}" 259: # First read the source file 260: File.open(iFileName, 'r') do |iOrgFile| 261: lLineNumber = 1 262: # The section that currently disables our lines of code 263: # [ String, Integer ] 264: # Category Level 265: lLevelingSection = nil 266: iOrgFile.readlines.each do |iCodeLine| 267: # Here is the main algorithm of the leveler. 268: # It recognizes the following special comment lines: 269: # #__LVL__ <Number> <Code>: Activate the code <Code> for a default level >= <Number>. 270: # #__LVLCAT__ <Category> <Number> <Code>: Activate the code <Code> for a category level >= <Number>. 271: # #__LVLBEGIN__ <Number>: The following lines of the file are activated for a default level >= <Number>. It is a level section. 272: # #__LVLCATBEGIN__ <Category> <Number>: The following lines of the file are activated for a category level >= <Number>. It is a level section. 273: # #__LVLEND__: Terminate a level section of code that began with __LVLBEGIN__ or __LVLBEGINCAT__ comment (terminate the last opened one). 274: lLineStripped = iCodeLine.strip 275: # The line storing the output (by default it is the input if the last level section authorizes it) 276: # Check if we are in a context (from $RCLLevels) that filters our current level sections' stack 277: if (lLevelingSection == nil) 278: lOutputLine = iCodeLine 279: else 280: lFoundUsefulLVLMacro = true 281: lOutputLine = "# ! Level #{lLevelingSection[0]}.#{lLevelingSection[1]} ! #{iCodeLine}" 282: end 283: # Do we have to evaluate whether we have to evaluate the section or not after processing this line ? 284: lReevaluateLevelingSection = false 285: #puts "----- Line = #{iCodeLine}" 286: # Interpret it 287: if (lLineStripped[0..7] == '#__LVL__') 288: lLineArguments = lLineStripped.scan(/^#__LVL__ ([0-9]*) (.*)$/) 289: if (lLineArguments.size != 1) 290: warning("#{iFileName}:#{lLineNumber}: Malformed line: #{lLineStripped}") 291: lOutputLine = "# !!! Malformed line: #{lLineStripped}\n" 292: else 293: # Check that the level of this line is greater or equal to the current section's level 294: lLevel = lLineArguments[0][0].to_i 295: lLastLevel = lHighestLevelSections[K_Default_Category] 296: if (lLastLevel == nil) 297: lLastLevel = 0 298: end 299: if (lLevel <= lLastLevel) 300: warning("#{iFileName}:#{lLineNumber}: This line can never be activated as it is part of a level section of level #{lLastLevel}: #{lLineStripped}") 301: end 302: if ((lLevelingSection == nil) and 303: ($RCLLevels[K_Default_Category] >= lLevel)) 304: lFoundUsefulLVLMacro = true 305: lOutputLine = "#{lLineArguments[0][1]}\n" 306: end 307: end 308: elsif (lLineStripped[0..10] == '#__LVLCAT__') 309: #puts '----- Match LVLCAT' 310: lLineArguments = lLineStripped.scan(/^#__LVLCAT__ ([^ ]+) ([0-9]*) (.*)$/) 311: if (lLineArguments.size != 1) 312: warning("#{iFileName}:#{lLineNumber}: Malformed line: #{lLineStripped}") 313: lOutputLine = "# !!! Malformed line: #{lLineStripped}\n" 314: else 315: #puts "----- Matched: #{lLineArguments.inspect}" 316: # Check that the level of this line is greater or equal to the current section's level 317: lCategory = lLineArguments[0][0] 318: lLevel = lLineArguments[0][1].to_i 319: lLastLevel = lHighestLevelSections[lCategory] 320: if (lLastLevel == nil) 321: lLastLevel = 0 322: end 323: #puts "----- Last level of category #{lCategory}: #{lLastLevel}" 324: #puts "----- lLevelingSection=#{lLevelingSection.inspect}" 325: if (lLevel <= lLastLevel) 326: warning("#{iFileName}:#{lLineNumber}: This line can never be activated as it is part of a level section of level #{lLastLevel}: #{lLineStripped}") 327: end 328: if ((lLevelingSection == nil) and 329: ($RCLLevels[lCategory] != nil) and 330: ($RCLLevels[lCategory] >= lLevel)) 331: lFoundUsefulLVLMacro = true 332: lOutputLine = "#{lLineArguments[0][2]}\n" 333: end 334: end 335: elsif (lLineStripped[0..11] == '#__LVLRUBY__') 336: lLineArguments = lLineStripped.scan(/^#__LVLRUBY__ (.*) ### (.*)$/) 337: if (lLineArguments.size != 1) 338: warning("#{iFileName}:#{lLineNumber}: Malformed line: #{lLineStripped}") 339: lOutputLine = "# !!! Malformed line: #{lLineStripped}\n" 340: else 341: if ((lLevelingSection == nil) and 342: (eval(lLineArguments[0][0]))) 343: lFoundUsefulLVLMacro = true 344: lOutputLine = "#{lLineArguments[0][1]}\n" 345: end 346: end 347: elsif (lLineStripped[0..12] == '#__LVLBEGIN__') 348: lLineArguments = lLineStripped.scan(/^#__LVLBEGIN__ ([0-9]*)$/) 349: if (lLineArguments.size != 1) 350: warning("#{iFileName}:#{lLineNumber}: Malformed line: #{lLineStripped}") 351: lOutputLine = "# !!! Malformed line: #{lLineStripped}\n" 352: else 353: lLevel = lLineArguments[0][0].to_i 354: lLastLevel = lHighestLevelSections[K_Default_Category] 355: if (lLastLevel == nil) 356: lLastLevel = 0 357: end 358: if (lLevel <= lLastLevel) 359: warning("#{iFileName}:#{lLineNumber}: This level section can never be activated as it is part of a level section of level #{lLastLevel}: #{lLineStripped}") 360: lOutputLine = "# !!! This level section is useless as it is part of a level section of level #{lLastLevel}: #{lLineStripped}\n" 361: end 362: lLevelSections.push([K_Default_Category,lLevel]) 363: if ((lHighestLevelSections[K_Default_Category] == nil) or 364: (lHighestLevelSections[K_Default_Category] < lLevel)) 365: lHighestLevelSections[K_Default_Category] = lLevel 366: end 367: lReevaluateLevelingSection = true 368: end 369: elsif (lLineStripped[0..15] == '#__LVLCATBEGIN__') 370: lLineArguments = lLineStripped.scan(/^#__LVLCATBEGIN__ ([^ ]+) ([0-9]*)$/) 371: if (lLineArguments.size != 1) 372: warning("#{iFileName}:#{lLineNumber}: Malformed line: #{lLineStripped}") 373: lOutputLine = "# !!! Malformed line: #{lLineStripped}\n" 374: else 375: lCategory = lLineArguments[0][0] 376: lLevel = lLineArguments[0][1].to_i 377: lLastLevel = lHighestLevelSections[lCategory] 378: if (lLastLevel == nil) 379: lLastLevel = 0 380: end 381: if (lLevel <= lLastLevel) 382: warning("#{iFileName}:#{lLineNumber}: This level section can never be activated as it is part of a category level section of level #{lLastLevel}: #{lLineStripped}") 383: lOutputLine = "# !!! This level section is useless as it is part of a category level section of level #{lLastLevel}: #{lLineStripped}\n" 384: end 385: lLevelSections.push([lCategory,lLevel]) 386: if ((lHighestLevelSections[lCategory] == nil) or 387: (lHighestLevelSections[lCategory] < lLevel)) 388: lHighestLevelSections[lCategory] = lLevel 389: end 390: # Check if we can output following source code 391: if ($RCLLevels[lCategory] == nil) 392: $RCLLevels[lCategory] = 0 393: end 394: lReevaluateLevelingSection = true 395: end 396: elsif (lLineStripped[0..16] == '#__LVLRUBYBEGIN__') 397: lLineArguments = lLineStripped.scan(/^#__LVLRUBYBEGIN__ (.*)$/) 398: if (lLineArguments.size != 1) 399: warning("#{iFileName}:#{lLineNumber}: Malformed line: #{lLineStripped}") 400: lOutputLine = "# !!! Malformed line: #{lLineStripped}\n" 401: else 402: # Create a unique category for this section 403: lCategory = "#{K_Ruby_Category} #{lLineNumber}" 404: lRubyCode = lLineArguments[0][0] 405: # Set its level to 1 406: lLevelSections.push([lCategory,1]) 407: lHighestLevelSections[lCategory] = 1 408: # Check if we can output following source code 409: if (eval(lRubyCode)) 410: # Activate it 411: $RCLLevels[lCategory] = 1 412: else 413: # Do not activate it 414: $RCLLevels[lCategory] = 0 415: end 416: lReevaluateLevelingSection = true 417: end 418: elsif (lLineStripped == '#__LVLEND__') 419: if (lLevelSections.size > 0) 420: lCategory, lLevel = lLevelSections.pop 421: # Recompute the highest level for lCategory 422: lNewHighestLevel = 0 423: lLevelSections.each do |iLevelSectionInfo| 424: if ((iLevelSectionInfo[0] == lCategory) and 425: (iLevelSectionInfo[1] > lNewHighestLevel)) 426: lNewHighestLevel = iLevelSectionInfo[1] 427: end 428: end 429: if (lNewHighestLevel > 0) 430: lHighestLevelSections[lCategory] = lNewHighestLevel 431: else 432: lHighestLevelSections.delete(lCategory) 433: end 434: lReevaluateLevelingSection = true 435: else 436: warning("#{iFileName}:#{lLineNumber}: Closing level section that was not opened.") 437: lOutputLine = "# !!! Closing level section that was not opened: #{lLineStripped}\n" 438: end 439: end 440: if (lReevaluateLevelingSection) 441: # Check if we can output following source code 442: lLevelingSection = nil 443: $RCLLevels.each do |iCategory, iLevel| 444: lLastLevel = lHighestLevelSections[iCategory] 445: if (lLastLevel == nil) 446: lLastLevel = 0 447: end 448: if (iLevel < lLastLevel) 449: lLevelingSection = [ iCategory, lLastLevel ] 450: break 451: end 452: end 453: end 454: lNewFileContents << lOutputLine 455: lLineNumber += 1 456: end 457: end 458: # Test that level sections were all terminated correctly 459: if ((lFoundUsefulLVLMacro) and 460: (lLevelSections.size > 0)) 461: warning("#{iFileName}: Level sections were not closed properly: #{lLevelSections.size} sections are still opened. It is very unlikely that source code could run.") 462: lNewFileContents << "# !!! Level sections were not closed properly: #{lLevelSections.size} sections are still opened. It is very unlikely that source code could run: #{lLevelSections.join(', ')}\n" 463: end 464: if (iOutputFileName != nil) 465: # Create the directory if needed 466: FileUtils::mkdir_p(File.dirname(iOutputFileName)) 467: # Write the file 468: File.open(iOutputFileName, 'w+') do |iNewFile| 469: iNewFile.write(lNewFileContents) 470: end 471: end 472: 473: return lNewFileContents, lFoundUsefulLVLMacro 474: end
Issue a warning specific to RCodeLeveler Parameters:
iMessage (String): The message to output
# File lib/rcodeleveler.rb, line 184 184: def RCodeLeveler.warning(iMessage) 185: if ($RCLWarningSeverity == 1) 186: $stderr.puts "RCodeLeveler - warning: #{iMessage}" 187: elsif ($RCLWarningSeverity == 2) 188: raise ParseError, "RCodeLeveler - warning: #{iMessage}" 189: end 190: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.