사용자 도구

사이트 도구


kb:rubysnippets


Ruby Snippets

Ruby 코드 조각들

C++ 소스 코드 include 정리

Perforce 처리도 같이 했다.

def sort_includes(source_name, dest_name)
    basename = "#include \"" + File.basename(source_name, File.extname(source_name)) + ".h\""
 
    locals = []
    remotes = []
    systems = []
    source_lines = []
    dest_lines = []
 
    for line in IO.readlines(source_name) 
        source_lines.push(line)
 
        if line =~ /\#include .+PCH\.h.+/ or line.strip == basename then
            dest_lines.push(line)
        elsif line =~ /\#include .+/ then
            if line =~ /\#include \"[^\/]+\".*/ then
                locals.push(line) if not locals.include?(line)
            elsif line =~ /\#include \".+\".*/ then
                remotes.push(line) if not remotes.include?(line)
            else
                systems.push(line) if not systems.include?(line)
            end
        else
            if locals.size + remotes.size + systems.size > 0 then
                dest_lines.concat(locals.sort) if locals.size > 0
                dest_lines.concat(remotes.sort) if remotes.size > 0
                dest_lines.concat(systems.sort) if systems.size > 0
 
                locals.clear
                remotes.clear
                systems.clear
            end
 
            dest_lines.push(line)
        end
    end
 
    dest_lines.concat(locals.sort) if locals.size > 0
    dest_lines.concat(remotes.sort) if remotes.size > 0
    dest_lines.concat(systems.sort) if systems.size > 0
 
    if source_lines != dest_lines then
        dest = File.open(dest_name, "w")
        for line in dest_lines 
            dest.write(line)
        end
        print(source_name + " changed\n")
    end
end
 
def traverse(path, excludes)
    Dir.foreach(path) { |name|
        next if name == '.' or name == '..' or excludes.has_key?(name.downcase)
        full_name = File.join(path, name)
        case File.ftype(full_name)
            when "file"
                extname = File.extname(full_name)
                if extname == ".h" or extname == ".cpp" then
                    #system("p4 edit " + full_name)
                    print(".\n")
                    sort_includes(full_name, full_name)
                end
            when "directory"
                traverse(full_name, excludes)
        end
    }
end
 
excludes = 
{
    "packetid.cpp" => 1,
    "typescommon.h" => 1,
    "pch.h" => 1,
    "resource.h" => 1
}
 
system("p4 edit D:\\Project\\Anima\\Shared\\...")
system("p4 edit D:\\Project\\Anima\\Server\\...")
traverse("D:\\Project\\Anima\\Shared\\", excludes)
traverse("D:\\Project\\Anima\\Server\\", excludes)
system("p4 revert -a")

FTP

지정된 디렉토리 및 그 하위 디렉토리에 있는 파일들을 모두 업로드하기.

require 'net/ftp'
 
def is_new_file(ftp, file_name)
    begin
        if ftp.mtime(file_name) < File.mtime(file_name) then
            return true
        else
            return false
        end
    rescue Net::FTPPermError
    end
    return true
end
 
def upload(ftp, path, spec, recursive)
    begin
        ftp.mkdir(path)
    rescue Net::FTPPermError
    end
 
    Dir.foreach(path) { |name|
        next if name == '.' or name == '..'
        full_name = File.join(path, name)
 
        case File.ftype(full_name)
            when "file"
                if full_name =~ spec then
                    print("#{full_name} ==> ")
                    if is_new_file(ftp, full_name) then
                        ftp.putbinaryfile(full_name, full_name, 102400) {|data| print(".") }
                        print("\n")
                    else
                        print("skipped\n")
                    end
                end
            when "directory"
                if recursive then
                    upload(ftp, full_name, spec, recursive)
                end
        end
    }
end
 
ftp = Net::FTP.new('somewhere.com')
ftp.login('user', 'password')
#upload(ftp, ".", /^.+\.exe/, true)
upload(ftp, ".", /.+/, true)
ftp.close

파일이 많을 경우, 스레드 기능이 절실히 필요하다.

CSV dump

어버버버…

require 'csv'
 
def generate_csv(file_name, collection)
    force_delete(file_name)
 
    file = File.open(file_name, "w")
    for row in collection do
        line = CSV.generate_line(row)
        file.write(line)
        file.write("\r")
    end
    file.close
end

YAML dump

Ruby에 기본적으로 있는 YAML 덤프 함수가 마음에 들지 않아 따로 만든 함수. (사실 이 함수가 만들어내는 파일을 YamlParserForCpp가 읽어들이지를 못해서…)

#-------------------------------------------------------------------------------
# Ruby에 기본적으로 있는 YAML 덤프 기능이 마음에 들지 않아 따로 만든 덤프 함수
# 이 함수를 직접 호출할 일은 없다. generate_yaml 함수를 이용하도록.
#-------------------------------------------------------------------------------
def dump_to_yaml(file, collection, indent, parent_type_is_sequence)
    if collection.class.to_s == "Hash" then
        first_time = true
 
        for key, value in collection do
            if parent_type_is_sequence then
                if first_time then
                    file.write(("  " * (indent - 1)) + "- " + key.to_s + ": ")
                    first_time = false
                else
                    file.write(("  " * indent) + key.to_s + ": ")
                end
            else
                file.write(("  " * indent) + key.to_s + ": ")
            end
 
            if value.class.to_s == "Hash" or value.class.to_s == "Array" then
                file.write("\n")
                dump_to_yaml(file, value, indent + 2, false)
            else
                file.write(value.to_s + "\n")
            end
        end
    elsif collection.class.to_s == "Array" then
        for child in collection do
            dump_to_yaml(file, child, indent + 1, true)
        end
    end
end
 
#-------------------------------------------------------------------------------
# dump_to_yaml 함수를 호출하기 위한 엔트리 함수
#-------------------------------------------------------------------------------
def generate_yaml(file_name, collection)
    force_delete(file_name)
 
    file = File.open(file_name, "w")
    if collection.class.to_s == "Hash" then
        dump_to_yaml(file, collection, 0, false)
    else
        dump_to_yaml(file, collection, 0, true)
    end
    file.close
end

읽기 전용 파일 삭제하기

def force_delete(file_name)
    if File.exists? file_name
        File.chmod(0777, file_name)
        File.delete(file_name)
    end
end

어익후, chmod로 할 줄은 꿈에도 몰랐네 그려.

Cpp 소스 파일 라인 카운트

from C++ Line Counting in Ruby

#
# $Id: cpplinecount.html,v 1.2 2002/11/19 00:49:37 erngui Exp $
#
# CppLineCount by ErnestoGuisado (erngui@acm.org)
# Count Lines of code in C++ sources.
# Doesn't handle complicated stuff like keywords appearing inside string literals, etc.
#
keywords = %w(case do else enum for if public private protected
  class struct union switch while try catch)
 
# Humphrey prefers to count '};' too.
#punct = /(;|,|\{|\};*)/
 
# this regexp catches statements and declarations. 
# The comma catches 'int x,y;' type declarations.
punct = /(;|,)/
 
lines = 0
empty = 0
comments = 0
prepro = 0
kwd = 0
statements = 0
while line = gets()
  lines += 1
  if line =~ /^$/
    empty += 1
    next
  end
  if line =~ /^\s*\/\//
    comments += 1
    next
  end
  if line =~ /^#/
    prepro += 1
    next
  end
  line.scan(/\w+/) do |word|
    kwd += 1 if keywords.include?(word)
  end
  line.scan(punct) do |p|
    statements += 1
  end
end 
 
puts "Lines:               #{lines}"
puts "Blank lines:         #{empty}"
puts "Comments(C++ style): #{comments}"
puts "Preprocessor:        #{prepro}"
puts "Keywords:            #{kwd}"
puts "Statements:          #{statements}"
sloc = statements + kwd + prepro # omit blanks and comments
puts "SLOC:                #{sloc}"

kb/rubysnippets.txt · 마지막으로 수정됨: 2014/11/10 16:23 (바깥 편집)