Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on Aug 30th, 2012  |  syntax: None  |  size: 5.55 KB  |  hits: 15  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. # Stats about a single log
  2. class Log
  3.   # Load a file and parse every line as a print.
  4.   def self.parse(file_path)
  5.     Log.new(file_path, File.readlines(file_path))
  6.   end
  7.  
  8.               # Number of lines in the file and number of lines that are valid CATS prints
  9.   attr_reader :linecount,     :cats_linecount,
  10.               # Number of characters that are in the file, part of CATS prints and part of CATS header overhead, respectively
  11.               :charcount,     :cats_charcount,  :cats_header_charcount,
  12.               # Hash of trace symbols and trace lines, by symbol name/line identifier, and list of TracePrints
  13.               :symbols,       :lines,           :prints,
  14.               # Name of the log
  15.               :name
  16.  
  17.   def initialize(log_name, log_lines = [])
  18.     @name       = log_name
  19.     @linecount  = @cats_linecount = @charcount = @cats_charcount = @cats_header_charcount = 0
  20.     @symbols    = {}
  21.     @lines      = {}
  22.     @prints     = []
  23.     log_lines.each { |line| self << line }
  24.   end
  25.  
  26.   # Add prints to this log, accepts either strings, TraceLines or TracePrints, or an array of these things
  27.   def <<(trace_line_or_print)
  28.     trace_print = nil
  29.  
  30.     if trace_line_or_print.is_a? TraceLine              # TraceLine
  31.       # Add all the prints
  32.       self << trace_line_or_print.trace_prints
  33.       return nil
  34.     elsif trace_line_or_print.is_a? Array               # Array
  35.       trace_line_or_print.each do |print|
  36.         self << print
  37.       end
  38.       rerturn nil
  39.     elsif trace_line_or_print.is_a? TracePrint          # TracePrint
  40.       trace_print = trace_line_or_print
  41.     else                                                # String or others
  42.       # It's not a TracePrint, trying making one
  43.       if TracePrint.cats? trace_line_or_print
  44.         trace_print = TracePrint.new(trace_line_or_print)
  45.       else # Not a CATS print or a corrupted print
  46.         @linecount += 1
  47.         @charcount += trace_line_or_print.to_s.length
  48.         return nil
  49.       end
  50.     end
  51.  
  52.     # Beyond this points, trace_print is certainly a TracePrint
  53.  
  54.     @linecount              += 1
  55.     @charcount              += trace_print.to_s.length
  56.     @cats_linecount         += 1
  57.     @cats_charcount         += trace_print.to_s.length
  58.     @cats_header_charcount  += trace_print.to_s.length - trace_print.payload.length
  59.  
  60.     @lines[trace_print.trace_line]     ||= TraceLine.new(trace_print.trace_symbol, trace_print.line)
  61.     @symbols[trace_print.trace_symbol] ||= TraceSymbol.new(trace_print.trace_symbol)
  62.     @symbols[trace_print.trace_symbol] << trace_print
  63.     @lines[trace_print.trace_line]     << trace_print
  64.     @prints                            << trace_print
  65.  
  66.     nil
  67.   end
  68.  
  69.   # Combine two logs
  70.   def +(log)
  71.     raise "TODO"
  72.   end
  73. end
  74.  
  75. # Stats about specific trace symbol
  76. class TraceSymbol
  77.   attr_reader :name, :lines, :prints, :charcount
  78.  
  79.   def initialize(trace_symbol)
  80.     @name       = trace_symbol
  81.     @charcount  = 0
  82.     @lines      = {}
  83.     @prints     = []
  84.   end
  85.  
  86.   def <<(trace_print)
  87.     @lines[trace_print.trace_line]     ||= TraceLine.new(trace_print.trace_symbol, trace_print.line)
  88.     @lines[trace_print.trace_line]     << trace_print
  89.     @prints                            << trace_print
  90.     @charcount                         += trace_print.to_s.length
  91.   end
  92.  
  93.   def +(trace_symbol)
  94.     raise "TODO"
  95.   end
  96. end
  97.  
  98. # Stats about specific TraceXxx calls
  99. class TraceLine
  100.   attr_reader :symbol, :line, :trace_line, :prints, :charcount
  101.  
  102.   alias :name :trace_line
  103.  
  104.   def initialize(symbol, line)
  105.     @symbol     = symbol
  106.     @line       = line
  107.     @charcount  = 0
  108.     @trace_line = "%s:%04d" % [@symbol, @line]
  109.     @prints     = []
  110.   end
  111.  
  112.   def <<(trace_print)
  113.     @prints     << trace_print
  114.     @charcount  += trace_print.to_s.length
  115.   end
  116.  
  117.   def +(trace_line)
  118.     raise "TODO"
  119.   end
  120. end
  121.  
  122. class TracePrint
  123.   # A5 00090.005.621    euApp:         382 /ceapsubtitle_m(01077) SUBTITLE:  type = Digital
  124.   LEGACY_CATS = %r{
  125.     (?<cpu>      [AP]){0}
  126.     (?<level>    \d){0}
  127.     (?<timestamp>\d{5}\.\d{3}.\d{3}){0}
  128.     (?<process>  [^:]+){0}
  129.     (?<thread_id>[^ ]+){0}
  130.     (?<symbol>   [^\(]+){0}
  131.     (?<line>     \d+){0}
  132.     (?<payload>  .*){0}
  133.  
  134.     \g<cpu>\g<level>\s\g<timestamp>\s+\g<process>:\s*\g<thread_id>\s+\g<symbol>\(\g<line>\)\s*\g<payload>
  135.   }x
  136.  
  137.   # 5P23.46451  plfapp:455  /legacy/printf:0000 ##papi_mute_smt_MuteOutputs ## outputs=0x00 OutputsMuted = 0x00
  138.   MODERN_CATS = %r{
  139.     (?<cpu>      [AP]){0}
  140.     (?<level>    \d){0}
  141.     (?<timestamp>\d+\.\d{5}){0}
  142.     (?<process>  [^:]+){0}
  143.     (?<thread_id>\d+){0}
  144.     (?<symbol>   [^:]+){0}
  145.     (?<line>     \d+){0}
  146.     (?<payload>  .*){0}
  147.  
  148.     \g<level>\g<cpu>\g<timestamp>\t+\g<process>:\g<thread_id>\t+\g<symbol>:\g<line>\t*\g<payload>
  149.   }x
  150.  
  151.   def self.cats?(cats_print)
  152.     cats_print && not(cats_print[LEGACY_CATS].nil? && cats_print[MODERN_CATS].nil?)
  153.   end
  154.  
  155.   def initialize(cats_print)
  156.     raise Error.new("#{cats_prints.inspect} is not a CATS prints.") unless TracePrint.cats?(cats_print)
  157.  
  158.     match = LEGACY_CATS.match(cats_print) || MODERN_CATS.match(cats_print)
  159.     # Filter out second dot from timestamp for legacy prints
  160.     @time         = match[:timestamp].sub(/\.(\d\d\d)$/, '\1')
  161.     @line         = match[:line].to_i
  162.     @trace_symbol = match[:symbol]
  163.     @trace_line   = "%s:%04d" % [@trace_symbol, @line]
  164.     @payload      = match[:payload]
  165.     @cpu          = match[:cpu]
  166.     @level        = match[:level]
  167.     @process      = match[:process]
  168.     @thread_id    = match[:thread_id]
  169.     @payload      = match[:payload]
  170.     @raw          = match.to_s
  171.   end
  172.  
  173.   attr_reader :time, :trace_line, :line, :trace_symbol, :payload, :thread_id, :process, :cpu, :level, :raw
  174.  
  175.   def to_s
  176.     @raw.clone
  177.   end
  178. end