사용자 도구

사이트 도구


kb:rubysnippets

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

kb:rubysnippets [2014/11/10 16:23] (현재)
줄 1: 줄 1:
 +{{INLINETOC}}
 +\\
 +
 +====== Ruby Snippets ======
 +[[Ruby]] 코드 조각들
 +
 +====== C++ 소스 코드 include 정리 ======
 +[[Perforce]] 처리도 같이 했다.
 +<code ruby>
 +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")
 +</​code>​
 +
 +====== FTP ======
 +지정된 디렉토리 및 그 하위 디렉토리에 있는 파일들을 모두 업로드하기.
 +<code ruby>
 +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
 +</​code>​ 파일이 많을 경우, 스레드 기능이 절실히 필요하다.
 +
 +====== CSV dump ======
 +어버버버...
 +<code ruby>
 +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
 +</​code>​
 +
 +====== YAML dump ======
 +[[Ruby]]에 기본적으로 있는 [[YAML]] 덤프 함수가 마음에 들지 않아 따로 만든 함수. (사실 이 함수가 만들어내는 파일을 [[YamlParserForCpp]]가 읽어들이지를 못해서...)
 +<code ruby>
 +#​-------------------------------------------------------------------------------
 +# 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
 +</​code>​
 +
 +====== 읽기 전용 파일 삭제하기 ======
 +<code ruby>
 +def force_delete(file_name)
 +    if File.exists?​ file_name
 +        File.chmod(0777,​ file_name)
 +        File.delete(file_name)
 +    end
 +end
 +</​code>​
 +어익후, chmod로 할 줄은 꿈에도 몰랐네 그려.
 +
 +
 +====== Cpp 소스 파일 라인 카운트 ======
 +from [[http://​triumvir.org/​prog/​cpp/​cpplinecount.html | C++ Line Counting in Ruby]]
 +<code 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}"​
 +</​code>​
 +
 +----
 +  * see also [[Ruby]]
  
kb/rubysnippets.txt · 마지막으로 수정됨: 2014/11/10 16:23 (바깥 편집)