text: #!/usr/bin/env python
  
  import sys, re, os.path, cgi, stat, math
  from optparse import OptionParser
  from color import getColorizer
  
  class tblCell(object):
      def __init__(self, text, value = None, props = None):
          self.text = text
          self.value = value
          self.props = props
  
  class tblColumn(object):
      def __init__(self, caption, title = None, props = None):
          self.text = caption
          self.title = title
          self.props = props
  
  class tblRow(object):
      def __init__(self, colsNum, props = None):
          self.cells = [None] * colsNum
          self.props = props
  
  def htmlEncode(str):
      return '<br/>'.join([cgi.escape(s) for s in str])
  
  class table(object):
      def_align = "left"
      def_valign = "middle"
      def_color = None
      def_colspan = 1
      def_rowspan = 1
      def_bold = False
      def_italic = False
      def_text="-"
  
      def __init__(self, caption = None):
          self.columns = {}
          self.rows = []
          self.ridx = -1;
          self.caption = caption
          pass
  
      def newRow(self, **properties):
          if len(self.rows) - 1 == self.ridx:
              self.rows.append(tblRow(len(self.columns), properties))
          else:
              self.rows[ridx + 1].props = properties
          self.ridx += 1
          return self.rows[self.ridx]
  
      def trimLastRow(self):
          if self.rows:
              self.rows.pop()
          if self.ridx >= len(self.rows):
              self.ridx = len(self.rows) - 1
  
      def newColumn(self, name, caption, title = None, **properties):
          if name in self.columns:
              index = self.columns[name].index
          else:
              index = len(self.columns)
          if isinstance(caption, tblColumn):
              caption.index = index
              self.columns[name] = caption
              return caption
          else:
              col = tblColumn(caption, title, properties)
              col.index = index
              self.columns[name] = col
              return col
  
      def getColumn(self, name):
          if isinstance(name, str):
              return self.columns.get(name, None)
          else:
              vals = [v for v in self.columns.values() if v.index == name]
              if vals:
                  return vals[0]
          return None
  
      def newCell(self, col_name, text, value = None, **properties):
          if self.ridx < 0:
              self.newRow()
          col = self.getColumn(col_name)
          row = self.rows[self.ridx]
          if not col:
              return None
          if isinstance(text, tblCell):
              cl = text
          else:
              cl = tblCell(text, value, properties)
          row.cells[col.index] = cl
          return cl
  
      def layoutTable(self):
          columns = self.columns.values()
          columns.sort(key=lambda c: c.index)
  
          colspanned = []
          rowspanned = []
  
          self.headerHeight = 1
          rowsToAppend = 0
  
          for col in columns:
              self.measureCell(col)
              if col.height > self.headerHeight:
                  self.headerHeight = col.height
              col.minwidth = col.width
              col.line = None
  
          for r in range(len(self.rows)):
              row = self.rows[r]
              row.minheight = 1
              for i in range(len(row.cells)):
                  cell = row.cells[i]
                  if row.cells[i] is None:
                      continue
                  cell.line = None
                  self.measureCell(cell)
                  colspan = int(self.getValue("colspan", cell))
                  rowspan = int(self.getValue("rowspan", cell))
                  if colspan > 1:
                      colspanned.append((r,i))
                      if i + colspan > len(columns):
                          colspan = len(columns) - i
                      cell.colspan = colspan
                      #clear spanned cells
                      for j in range(i+1, min(len(row.cells), i + colspan)):
                          row.cells[j] = None
                  elif columns[i].minwidth < cell.width:
                      columns[i].minwidth = cell.width
                  if rowspan > 1:
                      rowspanned.append((r,i))
                      rowsToAppend2 = r + colspan - len(self.rows)
                      if rowsToAppend2 > rowsToAppend:
                          rowsToAppend = rowsToAppend2
                      cell.rowspan = rowspan
                      #clear spanned cells
                      for j in range(r+1, min(len(self.rows), r + rowspan)):
                          if len(self.rows[j].cells) > i:
                              self.rows[j].cells[i] = None
                  elif row.minheight < cell.height:
                      row.minheight = cell.height
  
          self.ridx = len(self.rows) - 1
          for r in range(rowsToAppend):
              self.newRow()
              self.rows[len(self.rows) - 1].minheight = 1
  
          while colspanned:
              colspanned_new = []
              for r, c in colspanned:
                  cell = self.rows[r].cells[c]
                  sum([col.minwidth for col in columns[c:c + cell.colspan]])
                  cell.awailable = sum([col.minwidth for col in columns[c:c + cell.colspan]]) + cell.colspan - 1
                  if cell.awailable < cell.width:
                      colspanned_new.append((r,c))
              colspanned = colspanned_new
              if colspanned:
                  r,c = colspanned[0]
                  cell = self.rows[r].cells[c]
                  cols = columns[c:c + cell.colspan]
                  total = cell.awailable - cell.colspan + 1
                  budget = cell.width - cell.awailable
                  spent = 0
                  s = 0
                  for col in cols:
                      s += col.minwidth
                      addition = s * budget / total - spent
                      spent += addition
                      col.minwidth += addition
  
          while rowspanned:
              rowspanned_new = []
              for r, c in rowspanned:
                  cell = self.rows[r].cells[c]
                  cell.awailable = sum([row.minheight for row in self.rows[r:r + cell.rowspan]])
                  if cell.awailable < cell.height:
                      rowspanned_new.append((r,c))
              rowspanned = rowspanned_new
              if rowspanned:
                  r,c = rowspanned[0]
                  cell = self.rows[r].cells[c]
                  rows = self.rows[r:r + cell.rowspan]
                  total = cell.awailable
                  budget = cell.height - cell.awailable
                  spent = 0
                  s = 0
                  for row in rows:
                      s += row.minheight
                      addition = s * budget / total - spent
                      spent += addition
                      row.minheight += addition
  
          return columns
  
      def measureCell(self, cell):
          text = self.getValue("text", cell)
          cell.text = self.reformatTextValue(text)
          cell.height = len(cell.text)
          cell.width = len(max(cell.text, key = lambda line: len(line)))
  
      def reformatTextValue(self, value):
          if isinstance(value, str):
              vstr = value
          elif isinstance(value, unicode):
              vstr = str(value)
          else:
              try:
                  vstr = '\n'.join([str(v) for v in value])
              except TypeError:
                  vstr = str(value)
          return vstr.splitlines()
  
      def adjustColWidth(self, cols, width):
          total = sum([c.minWidth for c in cols])
          if total + len(cols) - 1 >= width:
              return
          budget = width - len(cols) + 1 - total
          spent = 0
          s = 0
          for col in cols:
              s += col.minWidth
              addition = s * budget / total - spent
              spent += addition
              col.minWidth += addition
  
      def getValue(self, name, *elements):
          for el in elements:
              try:
                  return getattr(el, name)
              except AttributeError:
                  pass
              try:
                  val = el.props[name]
                  if val:
                      return val
              except AttributeError:
                  pass
              except KeyError:
                  pass
          try:
              return getattr(self.__class__, "def_" + name)
          except AttributeError:
              return None
  
      def consolePrintTable(self, out):
          columns = self.layoutTable()
          colrizer = getColorizer(out)
  
          if self.caption:
              out.write("%s%s%s" % ( os.linesep,  os.linesep.join(self.reformatTextValue(self.caption)), os.linesep * 2))
  
          headerRow = tblRow(len(columns), {"align": "center", "valign": "top", "bold": True, "header": True})
          headerRow.cells = columns
          headerRow.minheight = self.headerHeight
  
          self.consolePrintRow2(colrizer, headerRow, columns)
  
          for i in range(0, len(self.rows)):
              self.consolePrintRow2(colrizer, i, columns)
  
      def consolePrintRow2(self, out, r, columns):
          if isinstance(r, tblRow):
              row = r
              r = -1
          else:
              row = self.rows[r]
  
          #evaluate initial values for line numbers
          i = 0
          while i < len(row.cells):
              cell = row.cells[i]
              colspan = self.getValue("colspan", cell)
              if cell is not None:
                  cell.wspace = sum([col.minwidth for col in columns[i:i + colspan]]) + colspan - 1
                  if cell.line is None:
                      if r < 0:
                          rows = [row]
                      else:
                          rows = self.rows[r:r + self.getValue("rowspan", cell)]
                      cell.line = self.evalLine(cell, rows, columns[i])
                      if len(rows) > 1:
                          for rw in rows:
                              rw.cells[i] = cell
              i += colspan
  
          #print content
          for ln in range(row.minheight):
              i = 0
              while i < len(row.cells):
                  if i > 0:
                      out.write(" ")
                  cell = row.cells[i]
                  column = columns[i]
                  if cell is None:
                      out.write(" " * column.minwidth)
                      i += 1
                  else:
                      self.consolePrintLine(cell, row, column, out)
                      i += self.getValue("colspan", cell)
              out.write(os.linesep)
  
      def consolePrintLine(self, cell, row, column, out):
          if cell.line < 0 or cell.line >= cell.height:
              line = ""
          else:
              line = cell.text[cell.line]
          width = cell.wspace
          align = self.getValue("align", ((None, cell)[isinstance(cell, tblCell)]), row, column)
  
          if align == "right":
              pattern = "%" + str(width) + "s"
          elif align == "center":
              pattern = "%" + str((width - len(line)) / 2 + len(line)) + "s" + " " * (width - len(line) - (width - len(line)) / 2)
          else:
              pattern = "%-" + str(width) + "s"
  
          out.write(pattern % line, color = self.getValue("color", cell, row, column))
          cell.line += 1
  
      def evalLine(self, cell, rows, column):
          height = cell.height
          valign = self.getValue("valign", cell, rows[0], column)
          space = sum([row.minheight for row in rows])
          if valign == "bottom":
              return height - space
          if valign == "middle":
              return (height - space + 1) / 2
          return 0
  
      def htmlPrintTable(self, out, embeedcss = False):
          columns = self.layoutTable()
  
          if embeedcss:
              out.write("<div style=\"font-family: Lucida Console, Courier New, Courier;font-size: 16px;color:#3e4758;\">\n<table style=\"background:none repeat scroll 0 0 #FFFFFF;border-collapse:collapse;font-family:'Lucida Sans Unicode','Lucida Grande',Sans-Serif;font-size:14px;margin:20px;text-align:left;width:480px;margin-left: auto;margin-right: auto;white-space:nowrap;\">\n")
          else:
              out.write("<div class=\"tableFormatter\">\n<table class=\"tbl\">\n")
          if self.caption:
              if embeedcss:
                  out.write(" <caption style=\"font:italic 16px 'Trebuchet MS',Verdana,Arial,Helvetica,sans-serif;padding:0 0 5px;text-align:right;white-space:normal;\">%s</caption>\n" % htmlEncode(self.reformatTextValue(self.caption)))
              else:
                  out.write(" <caption>%s</caption>\n" % htmlEncode(self.reformatTextValue(self.caption)))
          out.write(" <thead>\n")
  
          headerRow = tblRow(len(columns), {"align": "center", "valign": "top", "bold": True, "header": True})
          headerRow.cells = columns
  
          header_rows = [headerRow]
          header_rows.extend([row for row in self.rows if self.getValue("header")])
          last_row = header_rows[len(header_rows) - 1]
  
          for row in header_rows:
              out.write("  <tr>\n")
              for th in row.cells:
                  align = self.getValue("align", ((None, th)[isinstance(th, tblCell)]), row, row)
                  valign = self.getValue("valign", th, row)
                  cssclass = self.getValue("cssclass", th)
                  attr = ""
                  if align:
                      attr += " align=\"%s\"" % align
                  if valign:
                      attr += " valign=\"%s\"" % valign
                  if cssclass:
                      attr += " class=\"%s\"" % cssclass
                  css = ""
                  if embeedcss:
                      css = " style=\"border:none;color:#003399;font-size:16px;font-weight:normal;white-space:nowrap;padding:3px 10px;\""
                      if row == last_row:
                          css = css[:-1] + "padding-bottom:5px;\""
                  out.write("   <th%s%s>\n" % (attr, css))
                  if th is not None:
                      out.write("    %s\n" % htmlEncode(th.text))
                  out.write("   </th>\n")
              out.write("  </tr>\n")
  
          out.write(" </thead>\n <tbody>\n")
  
          rows = [row for row in self.rows if not self.getValue("header")]
          for r in range(len(rows)):
              row = rows[r]
              rowattr = ""
              cssclass = self.getValue("cssclass", row)
              if cssclass:
                  rowattr += " class=\"%s\"" % cssclass
              out.write("  <tr%s>\n" % (rowattr))
              i = 0
              while i < len(row.cells):
                  column = columns[i]
                  td = row.cells[i]
                  if isinstance(td, int):
                      i += td
                      continue
                  colspan = self.getValue("colspan", td)
                  rowspan = self.getValue("rowspan", td)
                  align = self.getValue("align", td, row, column)
                  valign = self.getValue("valign", td, row, column)
                  color = self.getValue("color", td, row, column)
                  bold = self.getValue("bold", td, row, column)
                  italic = self.getValue("italic", td, row, column)
                  style = ""
                  attr = ""
                  if color:
                      style += "color:%s;" % color
                  if bold:
                      style += "font-weight: bold;"
                  if italic:
                      style += "font-style: italic;"
                  if align and align != "left":
                      attr += " align=\"%s\"" % align
                  if valign and valign != "middle":
                      attr += " valign=\"%s\"" % valign
                  if colspan > 1:
                      attr += " colspan=\"%s\"" % colspan
                  if rowspan > 1:
                      attr += " rowspan=\"%s\"" % rowspan
                      for q in range(r+1, min(r+rowspan, len(rows))):
                          rows[q].cells[i] = colspan
                  if style:
                      attr += " style=\"%s\"" % style
                  css = ""
                  if embeedcss:
                      css = " style=\"border:none;border-bottom:1px solid #CCCCCC;color:#666699;padding:6px 8px;white-space:nowrap;\""
                      if r == 0:
                          css = css[:-1] + "border-top:2px solid #6678B1;\""
                  out.write("   <td%s%s>\n" % (attr, css))
                  if td is not None:
                      out.write("    %s\n" % htmlEncode(td.text))
                  out.write("   </td>\n")
                  i += colspan
              out.write("  </tr>\n")
  
          out.write(" </tbody>\n</table>\n</div>\n")
  
  def htmlPrintHeader(out, title = None):
      if title:
          titletag = "<title>%s</title>\n" % htmlEncode([str(title)])
      else:
          titletag = ""
      out.write("""<!DOCTYPE HTML>
  <html>
  <head>
  <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
  %s<style type="text/css">
  html, body {font-family: Lucida Console, Courier New, Courier;font-size: 16px;color:#3e4758;}
  .tbl{background:none repeat scroll 0 0 #FFFFFF;border-collapse:collapse;font-family:"Lucida Sans Unicode","Lucida Grande",Sans-Serif;font-size:14px;margin:20px;text-align:left;width:480px;margin-left: auto;margin-right: auto;white-space:nowrap;}
  .tbl span{display:block;white-space:nowrap;}
  .tbl thead tr:last-child th {padding-bottom:5px;}
  .tbl tbody tr:first-child td {border-top:3px solid #6678B1;}
  .tbl th{border:none;color:#003399;font-size:16px;font-weight:normal;white-space:nowrap;padding:3px 10px;}
  .tbl td{border:none;border-bottom:1px solid #CCCCCC;color:#666699;padding:6px 8px;white-space:nowrap;}
  .tbl tbody tr:hover td{color:#000099;}
  .tbl caption{font:italic 16px "Trebuchet MS",Verdana,Arial,Helvetica,sans-serif;padding:0 0 5px;text-align:right;white-space:normal;}
  .firstingroup {border-top:2px solid #6678B1;}
  </style>
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
  <script type="text/javascript">
  function abs(val) { return val < 0 ? -val : val }
  $(function(){
    //generate filter rows
    $("div.tableFormatter table.tbl").each(function(tblIdx, tbl) {
      var head = $("thead", tbl)
      var filters = $("<tr></tr>")
      var hasAny = false
      $("tr:first th", head).each(function(colIdx, col) {
        col = $(col)
        var cell
        var id = "t" + tblIdx + "r" + colIdx
        if (col.hasClass("col_name")){
          cell = $("<th><input id='" + id + "' name='" + id + "' type='text' style='width:100%%' class='filter_col_name' title='Regular expression for name filtering (&quot;resize.*640x480&quot; - resize tests on VGA resolution)'></input></th>")
          hasAny = true
        }
        else if (col.hasClass("col_rel")){
          cell = $("<th><input id='" + id + "' name='" + id + "' type='text' style='width:100%%' class='filter_col_rel' title='Filter out lines with a x-factor of acceleration less than Nx'></input></th>")
          hasAny = true
        }
        else if (col.hasClass("col_cr")){
          cell = $("<th><input id='" + id + "' name='" + id + "' type='text' style='width:100%%' class='filter_col_cr' title='Filter out lines with a percentage of acceleration less than N%%'></input></th>")
          hasAny = true
        }
        else
          cell = $("<th></th>")
        cell.appendTo(filters)
      })
  
     if (hasAny){
       $(tbl).wrap("<form id='form_t" + tblIdx + "' method='get' action=''></form>")
       $("<input it='test' type='submit' value='Apply Filters' style='margin-left:10px;'></input>")
         .appendTo($("th:last", filters.appendTo(head)))
     }
    })
  
    //get filter values
    var vars = []
    var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&')
    for(var i = 0; i < hashes.length; ++i)
    {
       hash = hashes[i].split('=')
       vars.push(decodeURIComponent(hash[0]))
       vars[decodeURIComponent(hash[0])] = decodeURIComponent(hash[1]);
    }
  
    //set filter values
    for(var i = 0; i < vars.length; ++i)
       $("#" + vars[i]).val(vars[vars[i]])
  
    //apply filters
    $("div.tableFormatter table.tbl").each(function(tblIdx, tbl) {
        filters = $("input:text", tbl)
        var predicate = function(row) {return true;}
        var empty = true
        $.each($("input:text", tbl), function(i, flt) {
           flt = $(flt)
           var val = flt.val()
           var pred = predicate;
           if(val) {
             empty = false
             var colIdx = parseInt(flt.attr("id").slice(flt.attr("id").indexOf('r') + 1))
             if(flt.hasClass("filter_col_name")) {
                var re = new RegExp(val);
                predicate = function(row) {
                  if (re.exec($(row.get(colIdx)).text()) == null)
                    return false
                  return pred(row)
            }
             } else if(flt.hasClass("filter_col_rel")) {
                var percent = parseFloat(val)
                if (percent < 0) {
                  predicate = function(row) {
                    var val = parseFloat($(row.get(colIdx)).text())
                    if (!val || val >= 1 || val > 1+percent)
                      return false
                    return pred(row)
              }
                } else {
                  predicate = function(row) {
                    var val = parseFloat($(row.get(colIdx)).text())
                    if (!val || val < percent)
                      return false
                    return pred(row)
              }
                }
             } else if(flt.hasClass("filter_col_cr")) {
                var percent = parseFloat(val)
                predicate = function(row) {
                  var val = parseFloat($(row.get(colIdx)).text())
                  if (!val || val < percent)
                    return false
                  return pred(row)
            }
             }
           }
        });
        if (!empty){
           $("tbody tr", tbl).each(function (i, tbl_row) {
              if(!predicate($("td", tbl_row)))
                 $(tbl_row).remove()
           })
           if($("tbody tr", tbl).length == 0) {
             $("<tr><td colspan='"+$("thead tr:first th", tbl).length+"'>No results mathing your search criteria</td></tr>")
               .appendTo($("tbody", tbl))
           }
        }
    })
  })
  </script>
  </head>
  <body>
  """ % titletag)
  
  def htmlPrintFooter(out):
      out.write("</body>\n</html>")
  
  def getStdoutFilename():
      try:
          if os.name == "nt":
              import msvcrt, ctypes
              handle = msvcrt.get_osfhandle(sys.stdout.fileno())
              size = ctypes.c_ulong(1024)
              nameBuffer = ctypes.create_string_buffer(size.value)
              ctypes.windll.kernel32.GetFinalPathNameByHandleA(handle, nameBuffer, size, 4)
              return nameBuffer.value
          else:
              return os.readlink('/proc/self/fd/1')
      except:
          return ""
  
  def detectHtmlOutputType(requestedType):
      if requestedType == "txt":
          return False
      elif requestedType in ["html", "moinwiki"]:
          return True
      else:
          if sys.stdout.isatty():
              return False
          else:
              outname = getStdoutFilename()
              if outname:
                  if outname.endswith(".htm") or outname.endswith(".html"):
                      return True
                  else:
                      return False
              else:
                  return False
  
  def getRelativeVal(test, test0, metric):
      if not test or not test0:
          return None
      val0 = test0.get(metric, "s")
      if not val0:
          return None
      val =  test.get(metric, "s")
      if not val or val == 0:
          return None
      return float(val0)/val
  
  def getCycleReduction(test, test0, metric):
      if not test or not test0:
          return None
      val0 = test0.get(metric, "s")
      if not val0 or val0 == 0:
          return None
      val =  test.get(metric, "s")
      if not val:
          return None
      return (1.0-float(val)/val0)*100
  
  def getScore(test, test0, metric):
      if not test or not test0:
          return None
      m0 = float(test.get("gmean", None))
      m1 = float(test0.get("gmean", None))
      if m0 == 0 or m1 == 0:
          return None
      s0 = float(test.get("gstddev", None))
      s1 = float(test0.get("gstddev", None))
      s = math.sqrt(s0*s0 + s1*s1)
      m0 = math.log(m0)
      m1 = math.log(m1)
      if s == 0:
          return None
      return (m0-m1)/s
  
  metrix_table = \
  {
      "name": ("Name of Test", lambda test,test0,units: str(test)),
  
      "samples": ("Number of\ncollected samples", lambda test,test0,units: test.get("samples", units)),
      "outliers": ("Number of\noutliers", lambda test,test0,units: test.get("outliers", units)),
  
      "gmean": ("Geometric mean", lambda test,test0,units: test.get("gmean", units)),
      "mean": ("Mean", lambda test,test0,units: test.get("mean", units)),
      "min": ("Min", lambda test,test0,units: test.get("min", units)),
      "median": ("Median", lambda test,test0,units: test.get("median", units)),
      "stddev": ("Standard deviation", lambda test,test0,units: test.get("stddev", units)),
      "gstddev": ("Standard deviation of Ln(time)", lambda test,test0,units: test.get("gstddev")),
  
      "gmean%": ("Geometric mean (relative)", lambda test,test0,units: getRelativeVal(test, test0, "gmean")),
      "mean%": ("Mean (relative)", lambda test,test0,units: getRelativeVal(test, test0, "mean")),
      "min%": ("Min (relative)", lambda test,test0,units: getRelativeVal(test, test0, "min")),
      "median%": ("Median (relative)", lambda test,test0,units: getRelativeVal(test, test0, "median")),
      "stddev%": ("Standard deviation (relative)", lambda test,test0,units: getRelativeVal(test, test0, "stddev")),
      "gstddev%": ("Standard deviation of Ln(time) (relative)", lambda test,test0,units: getRelativeVal(test, test0, "gstddev")),
  
      "gmean$": ("Geometric mean (cycle reduction)", lambda test,test0,units: getCycleReduction(test, test0, "gmean")),
      "mean$": ("Mean (cycle reduction)", lambda test,test0,units: getCycleReduction(test, test0, "mean")),
      "min$": ("Min (cycle reduction)", lambda test,test0,units: getCycleReduction(test, test0, "min")),
      "median$": ("Median (cycle reduction)", lambda test,test0,units: getCycleReduction(test, test0, "median")),
      "stddev$": ("Standard deviation (cycle reduction)", lambda test,test0,units: getCycleReduction(test, test0, "stddev")),
      "gstddev$": ("Standard deviation of Ln(time) (cycle reduction)", lambda test,test0,units: getCycleReduction(test, test0, "gstddev")),
  
      "score": ("SCORE", lambda test,test0,units: getScore(test, test0, "gstddev")),
  }
  
  def formatValue(val, metric, units = None):
      if val is None:
          return "-"
      if metric.endswith("%"):
          return "%.2f" % val
      if metric.endswith("$"):
          return "%.2f%%" % val
      if metric.endswith("S"):
          if val > 3.5:
              return "SLOWER"
          if val < -3.5:
              return "FASTER"
          if val > -1.5 and val < 1.5:
              return " "
          if val < 0:
              return "faster"
          if val > 0:
              return "slower"
          #return "%.4f" % val
      return "%.3f %s" % (val, units)
  
  if __name__ == "__main__":
      if len(sys.argv) < 2:
          print "Usage:\n", os.path.basename(sys.argv[0]), "<log_name>.xml"
          exit(0)
  
      parser = OptionParser()
      parser.add_option("-o", "--output", dest="format", help="output results in text format (can be 'txt', 'html' or 'auto' - default)", metavar="FMT", default="auto")
      parser.add_option("-m", "--metric", dest="metric", help="output metric", metavar="NAME", default="gmean")
      parser.add_option("-u", "--units", dest="units", help="units for output values (s, ms (default), mks, ns or ticks)", metavar="UNITS", default="ms")
      (options, args) = parser.parse_args()
  
      options.generateHtml = detectHtmlOutputType(options.format)
      if options.metric not in metrix_table:
          options.metric = "gmean"
  
      #print options
      #print args
  
  #    tbl = table()
  #    tbl.newColumn("first", "qqqq", align = "left")
  #    tbl.newColumn("second", "wwww\nz\nx\n")
  #    tbl.newColumn("third", "wwasdas")
  #
  #    tbl.newCell(0, "ccc111", align = "right")
  #    tbl.newCell(1, "dddd1")
  #    tbl.newCell(2, "8768756754")
  #    tbl.newRow()
  #    tbl.newCell(0, "1\n2\n3\n4\n5\n6\n7", align = "center", colspan = 2, rowspan = 2)
  #    tbl.newCell(2, "xxx\nqqq", align = "center", colspan = 1, valign = "middle")
  #    tbl.newRow()
  #    tbl.newCell(2, "+", align = "center", colspan = 1, valign = "middle")
  #    tbl.newRow()
  #    tbl.newCell(0, "vcvvbasdsadassdasdasv", align = "right", colspan = 2)
  #    tbl.newCell(2, "dddd1")
  #    tbl.newRow()
  #    tbl.newCell(0, "vcvvbv")
  #    tbl.newCell(1, "3445324", align = "right")
  #    tbl.newCell(2, None)
  #    tbl.newCell(1, "0000")
  #    if sys.stdout.isatty():
  #        tbl.consolePrintTable(sys.stdout)
  #    else:
  #        htmlPrintHeader(sys.stdout)
  #        tbl.htmlPrintTable(sys.stdout)
  #        htmlPrintFooter(sys.stdout)
  
      import testlog_parser
  
      if options.generateHtml:
          htmlPrintHeader(sys.stdout, "Tables demo")
  
      getter = metrix_table[options.metric][1]
  
      for arg in args:
          tests = testlog_parser.parseLogFile(arg)
          tbl = table(arg)
          tbl.newColumn("name", "Name of Test", align = "left")
          tbl.newColumn("value", metrix_table[options.metric][0], align = "center", bold = "true")
  
          for t in sorted(tests):
              tbl.newRow()
              tbl.newCell("name", str(t))
  
              status = t.get("status")
              if status != "run":
                  tbl.newCell("value", status)
              else:
                  val = getter(t, None, options.units)
                  if val:
                      if options.metric.endswith("%"):
                          tbl.newCell("value", "%.2f" % val, val)
                      else:
                          tbl.newCell("value", "%.3f %s" % (val, options.units), val)
                  else:
                      tbl.newCell("value", "-")
  
          if options.generateHtml:
              tbl.htmlPrintTable(sys.stdout)
          else:
              tbl.consolePrintTable(sys.stdout)
  
      if options.generateHtml:
          htmlPrintFooter(sys.stdout)
  