Skip to content

Instantly share code, notes, and snippets.

@d
Created December 4, 2018 21:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save d/de025c1ac9cdf0361012cf1649a88a39 to your computer and use it in GitHub Desktop.
Save d/de025c1ac9cdf0361012cf1649a88a39 to your computer and use it in GitHub Desktop.
Sort Clang / GCC warnings
#!/usr/bin/env ruby
require 'forwardable'
FLIP_PATTERN = /^(?:(?<file>\w+\.c(?:pp)?):\d+:\d+: warning: )|(?:In file included from (?<file>\w+\.c(?:pp)?):\d+:)/
FLOP_PATTERN = /^\d+ warnings? generated\.$/
class Warnings
include Enumerable
def initialize(lines)
@lines = lines
end
def each
builder = WarningBuilder.new
lines.each_with_index do |line, i|
builder.read(line)
if builder.flipped?
if builder.flopped?
yield builder.build
builder = WarningBuilder.new
end
else
yield NotWarning.new(line: line, line_number: i)
builder = WarningBuilder.new
end
end
end
private
attr_reader :lines
end
class NotWarning
def initialize(line:, line_number:)
@line = line
@line_number = line_number
end
def <=>(other)
if other.is_a?(self.class)
return line_number <=> other.line_number
else
1
end
end
def to_s
line
end
protected
attr_reader :line, :line_number
end
class WarningBuilder
extend Forwardable
def initialize
@data = []
@flipflop = FlipFlop.new
end
def build
CompilerWarning.new(file: flipflop.file, data: data)
end
def read(line)
flipflop.read(line)
if flipped?
data.push(line)
else
end
end
def_delegators :flipflop, :flipped?, :flopped?
def_delegator :data, :push
private
attr_reader :flipflop, :data
end
class CompilerWarning
def initialize(file:, data:)
@file = file
@data = data
end
def <=>(other)
if other.is_a?(CompilerWarning)
return file <=> other.file
else
return -1
end
end
def to_s
data.join
end
protected
attr_reader :file
private
attr_reader :data
end
class FlipFlop
def initialize
@flipped = false
@flopped = false
end
def read(line)
if flipped?
m = FLOP_PATTERN.match(line)
if m
@flopped = true
end
else
m = FLIP_PATTERN.match(line)
if m
@flipped = true
@file = m[:file]
end
end
end
def flipped?
return @flipped
end
def flopped?
return @flopped
end
attr_reader :file
end
def main
warnings = Warnings.new(ARGF.each_line)
warnings.sort.each &method(:print)
end
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment