Last active
May 10, 2021 02:36
-
-
Save TellowKrinkle/e00ddfb0c64a6012f57609a10452813b to your computer and use it in GitHub Desktop.
Script for PCSX2 to rename files to match a `.vcxproj.filters` file and update includes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require "fileutils" | |
require "nokogiri" | |
require "optparse" | |
require "pathname" | |
$absolutes = [] | |
parser = OptionParser.new do |opts| | |
opts.banner = "Usage: #{$PROGRAM_NAME} file.vcxproj.filters [options]" | |
opts.on("--absolute INCLUDE", "Force an include to always use absolute paths") do |absolute| | |
$absolutes << absolute | |
end | |
end | |
parser.parse! | |
if ARGV.count == 1 then | |
$filename = Pathname::new(ARGV[0]).expand_path | |
else | |
abort(parser.help) | |
end | |
$cwd = Pathname::new(".").expand_path | |
$absolutes = $absolutes.map { |file| Pathname::new(file).expand_path($cwd).relative_path_from($cwd) } | |
xml = File.open($filename) { |f| Nokogiri::XML(f) } | |
Filter = Struct::new(:file, :loc) | |
def find_filters(node, filters=[]) | |
file = node.attribute "Include" | |
filter = node.element_children.find { |child| child.name == "Filter" } | |
if !file.nil? && !filter.nil? then | |
filters << Filter::new(file, filter.child) | |
else | |
node.element_children.each { |child| find_filters(child, filters) } | |
end | |
return filters | |
end | |
class RenameList | |
def initialize(filters) | |
@renames = {} | |
filters.each do |filter| | |
old = Pathname::new(filter.file.value.gsub("\\", "/")).expand_path($filename.parent).relative_path_from($cwd) | |
new = Pathname::new(filter.loc.to_s.gsub("\\", "/")).join(old.basename) | |
@renames[old] = new | |
end | |
end | |
def new_name(file) | |
if @renames.has_key? file then | |
return @renames[file] | |
else | |
return file | |
end | |
end | |
def fixup_includes(file) | |
file = Pathname::new(file).expand_path($cwd).relative_path_from($cwd) | |
new_file = new_name(file) | |
content = File.read(file, :encoding => 'iso-8859-1') | |
begin | |
newcontent = content.gsub(/#include "([^"]+)"/) do |full_include| | |
old_include = Pathname::new($1).expand_path(file.parent).relative_path_from($cwd) | |
[".", "gui", "x86"].each do |dir| | |
if !old_include.exist? then | |
old_include = Pathname::new($1).expand_path(Pathname::new(dir).expand_path).relative_path_from($cwd) | |
end | |
end | |
if !old_include.exist? then | |
next full_include | |
end | |
new_include = new_name(old_include) | |
relative = new_include.relative_path_from(new_file.parent) | |
absolute = new_include.relative_path_from(".") | |
if $absolutes.include? old_include then | |
# puts "Forcing absolute for #{new_include}" | |
choice = absolute | |
elsif relative.to_s.count("/") <= absolute.to_s.count("/") then | |
choice = relative | |
else | |
choice = absolute | |
end | |
next "\#include \"#{choice}\"" | |
end | |
if content != newcontent then | |
File.write(file, newcontent, :encoding => 'iso-8859-1') | |
end | |
rescue ArgumentError => err | |
STDERR.puts "Unable to update #{file}: #{err}" | |
end | |
end | |
def fixup_cmake(file) | |
content = File.read(file) | |
content.gsub!(/[^\s\(\)]+/) do |word| | |
if @renames.has_key? Pathname::new(word) then | |
next @renames[Pathname::new(word)] | |
else | |
next word | |
end | |
end | |
File.write(file, content) | |
end | |
def to_s | |
@renames.map { |from, to| "#{from} => #{to}" }.join "\n" | |
end | |
end | |
filters = find_filters xml.root | |
renames = RenameList::new(filters) | |
Dir.glob("**/*.cpp") { |file| renames.fixup_includes file } | |
Dir.glob("**/*.h") { |file| renames.fixup_includes file } | |
Dir.glob("**/*.inl") { |file| renames.fixup_includes file } | |
renames.fixup_cmake "CMakeLists.txt" | |
filters.each do |filter| | |
file = Pathname::new(filter.file.value.gsub("\\", "/")).expand_path($filename.parent).relative_path_from($cwd) | |
new_file = renames.new_name file | |
filter.file.value = new_file.expand_path($cwd).relative_path_from($filename.parent).to_s.gsub("/", "\\") | |
begin | |
FileUtils.mkdir_p(new_file.parent) | |
File.rename(file, new_file) | |
rescue | |
STDERR.puts "Failed to rename #{file} to #{new_file}" | |
end | |
end | |
File.write($filename, xml.to_s) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment