Advertisement
KoBeWi

StringName Finder

May 14th, 2024
473
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 3.65 KB | None | 0 0
  1. StringNameList = {}
  2. StringNameUsage = {}
  3.  
  4. $actionables = 0
  5. $maxlen = 0
  6.  
  7. def print_error(error, path = nil, line_index = nil, line_text = nil)
  8.     $actionables += 1
  9.     puts "\e[31mError: #{error}\e[0m"
  10.     puts "at #{File.basename(path)}:#{line_index}" if path
  11.     puts line_text if line_text
  12.     puts ""
  13. end
  14.  
  15. def extract_string(line, from = 0)
  16.     quote = line.index('"', from) + 1
  17.     line[quote...line.index('"', quote)]
  18. end
  19.  
  20. def extract_stringname(path, line, i)
  21.     name = ""
  22.     if line.include?("=")
  23.         name = line[0...line.index("=")]
  24.     else
  25.         name = line[0...line.index("(")]
  26.     end
  27.  
  28.     string = extract_string(line)
  29.     if StringNameList.include? string
  30.         print_error("Duplicate StringName: #{string}", path, i)
  31.     else
  32.         StringNameList[name.strip] = string
  33.         $maxlen = [$maxlen, string.length].max
  34.     end
  35. end
  36.  
  37. def scan_stringname_source(path)
  38.     File.readlines(path).each.with_index do |line, i|
  39.         if line.include?("StaticCString::create")
  40.             extract_stringname(path, line, i)
  41.         elsif line.include?('"') and not line.start_with?("#") and not line.start_with?("/*")
  42.             print_error("StringName created in unusual way", path, i, line)
  43.             extract_stringname(path, line, i)
  44.         end
  45.     end
  46. end
  47.  
  48. def check_string_name(line, prefix)
  49.     return if not line.include?(prefix)
  50.  
  51.     start = line.index(prefix) + prefix.length
  52.     string = line[start...line.index(")", start)]
  53.     StringNameUsage[string] += 1
  54. end
  55.  
  56. def scan_source_file(path)
  57.     File.readlines(path).each.with_index do |line, i|
  58.         next if line.start_with?("#") or line.start_with?("/*")
  59.  
  60.         if line.include?("StringNames::get_singleton()->")
  61.             print_error("Legacy StringName usage", path, i, line)
  62.         end
  63.  
  64.         check_string_name(line, "CoreStringName(")
  65.         check_string_name(line, "SceneStringName(")
  66.         check_string_name(line, "EditorStringName(")
  67.  
  68.         quote = line.index('"')
  69.         while quote
  70.             string = extract_string(line, quote)
  71.             if string.length < 2 or string.length > $maxlen or string.include?(" ") or string.include?("D_METHOD") or string.include?("PropertyInfo")
  72.                 quote = line.index('"', quote + string.length + 2)
  73.                 next
  74.             end
  75.  
  76.             key = StringNameList.key(string)
  77.             if key
  78.                 StringNameUsage[key] += 1
  79.                 print_error("Potential replacement: #{string}", path, i, line)
  80.                 break
  81.             end
  82.  
  83.             quote = line.index('"', quote + string.length + 2)
  84.         end
  85.     end
  86. end
  87.  
  88. def scan_directory(path)
  89.     path.delete_prefix!("./")
  90.  
  91.     (Dir.entries(path) - [".", ".."]).each do |entry|
  92.         next if entry.start_with?(".")
  93.  
  94.         entry_path = File.join(path, entry)
  95.         if File.exist?(entry_path) and File.extname(entry) == ".cpp" and not entry.include?(".gen")
  96.             scan_source_file(entry_path)
  97.             next
  98.         end
  99.  
  100.         if Dir.exist?(entry_path)
  101.             scan_directory(entry_path)
  102.         end
  103.     end
  104. end
  105.  
  106. scan_stringname_source("core/core_string_names.cpp")
  107. scan_stringname_source("scene/scene_string_names.cpp")
  108. scan_stringname_source("editor/editor_string_names.cpp")
  109.  
  110. StringNameList.each_key do |string|
  111.     StringNameUsage[string] = 0
  112. end
  113.  
  114. scan_directory(".")
  115.  
  116. StringNameUsage.each_pair do |string, usage|
  117.     if usage == 0
  118.         print_error("Unused StringName: #{string}")
  119.     elsif usage == 1
  120.         print_error("StringName used only once: #{string}")
  121.     end
  122. end
  123.  
  124. puts "Finished"
  125. puts "Found #{$actionables} actionable items." if $actionables > 0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement