#!/usr/bin/env ruby # This script reads in a file and annotates it with # line number directives. Existing line annotations are updated. require 'optparse' @options = {} OptionParser.new do |opts| opts.on("-o", "--out FILENAME", "Output FILENAME to write to.") do | v | @options[:out_file] = v end opts.on("-i", "--in FILENAME", "Input FILENAME to read.") do | v | @options[:in_file] = v end opts.on("-a", "--annotate REGEXP", "REGEXP, if matched, marker is written.") do | v | @options[:annotate_re] = Regexp.new(v) end opts.on("-f", "--format FORMAT", "printf FORMAT of marker, must contain %s and %d of.") do | v | @options[:marker_format] = v end opts.on("-m", "--marker REGEXP", "REGEXP, if matched, marker is updated.") do | v | @options[:marker_re] = Regexp.new(v) end opts.on("-s", "--skip", "If set skipsthe markers in the line count") do | v | @options[:skip] = true end end.parse! file_name = @options[:in_file] || ARGV[0] if file_name == nil puts "liner: liner [options] file_to_annotate" exit 1 end annotate_re = @options[:annotate_re] || %r{^(func|type|const)} marker_format = @options[:marker_format] || "//line %s:%d\n" marker_re = @options[:marker_re] || %r{^//line [^:]+:[0-9]+$} out_name = @options[:out_file] lines = nil File.open(file_name) do |file| lines = file.readlines end marker_before = false out = $stdout if out_name out = File.open(out_name, "w+") if out == nil puts "liner: cannot open output file #{out_name}" exit 2 end end line_number = 0 lines.each do |line| line_number += 1 marker_match = marker_re.match(line) if marker_match != nil # Update existing marker out.printf(marker_format, file_name, line_number) marker_before = true # Skip read line in output next end if marker_before marker_before = false else annotate_match = annotate_re.match(line) if annotate_match out.printf(marker_format, file_name, line_number) line_number += 1 unless @options[:skip] end end out.puts(line) end if out != $stdout out.close end