【问题标题】:tcl procedure not workingtcl 程序不工作
【发布时间】:2013-12-13 01:06:16
【问题描述】:

我正在编写一个程序来将错误/严重性/发生从文件格式转换为表格格式,但它不起作用。

文件片段:

error_name: xxxxxxxxxx
 Severity: Warning Occurrence: 2 
error_name2:xxxxxxxxxxx. 
Severity: Warning Occurrence: 16 
error_name3:xxxxxxxxxxxxx 
Severity: Warning Occurrence: 15

代码:

proc get_clp_summary { Infile } {
   set run_summary_file  [ glob $Infile/summary.rpt ]

   set fp [ open $run_summary_file   "r" ]

   while { [ gets $fp line ]!= -1 } {
      foreach {match label value} [regexp -inline -all {(\w+):\s*(\S*)} $line] {
         switch -exact -- $label {
            Severity   {set sev $value}
            Occurrence {set count $value}
            default    {set err $label}
         }
         lappend pack_stats [ list $err $sev $count] 
         puts $pack_stats              
      }

      return $pack_stats
   }


   ##################################################################

   set run_time_stats [ get_clp_summary [ lindex $argv 0 ]  ]

   puts ""
   puts ""
   puts ""

   table_styler
   puts " \<table id=\"customers\" style=\"margin-bottom:10px;\" \> "
   puts "\<th\>  Rule \<\/th\>"
   puts "\<th\>  Severity   \<\/th\>"
   puts "\<th\>  Occurrence  \<\/th\>"
   puts "\<\/tr\>"
   foreach k $run_time_stats {

      set st [ lindex $k 0 ]
      set st_type [ lindex $k 1 ]
      set st_count [lindex $k 2]
      set BGCOLOR #FFFFFF 
      puts " \<tr\> \<td\> $st \<\/\> \<td bgcolor=\"$BGCOLOR\" \> $st \<\/td\> "
      puts "\<td\> \<td bgcolor=\"$BGCOLOR\" \> $st_type \<\/td\>  \"                        
      puts "\<td\>  $st_count  \<\/td\> "
      puts "\<\/tr\>"
   }

   puts " \<\/table\> "
}

puts " \<\/body\> "
puts " \<\/html\> "

【问题讨论】:

  • 请定义“不工作”。它给了你什么?一个错误?没有输出?
  • 它不执行任何操作

标签: regex tcl


【解决方案1】:

这里有一些观察。

  • 您的代码确实输出了 bodyhtml 标签
  • 您编写了过程get_clp_summary,但没有调用它。这就是它不输出任何内容的原因。你需要这样称呼它:

    get_clp_summary filename
    
  • 请不要使用缩写/速记。我花了一段时间才弄清楚 o/p 表示输出。是的,我就是这么笨。

  • 作为风格问题,请为您的代码处理缩进。它应该对提高可读性有很大帮助。

【讨论】:

  • +1 表示“请不要使用缩写”。有些人是上限。用很多 abvr 写东西,所以 n/o 可以理解。
【解决方案2】:

您的主要问题是您的缩进不干净。一件微不足道的事情,但它会给你带来重大问题。

原因如下。当我重新缩进你的提交时,我发现过程get_clp_summary 实际上比我最初想象的要晚很多行!这意味着它永远不会被调用(在过程中存在一些无法访问的代码的递归调用,我认为你不希望这样做)。如果缩进正确,也许使用程序员编辑器的支持,那么您将更快地处理错位大括号等问题。

要修复代码,请在后面加上大括号:

puts " \<\/table\> "

把它放在之前

return $pack_stats

哦,该代码中还有 许多 其他问题。至少有一个反斜杠会导致该 HTML 打印部分完全混乱(而且 Tcl 在 &lt;&gt; 之前不需要 \)。更重要的是,您没有关闭正在读取的频道,并且您假设 glob 返回一个文件(它返回一个列表,即使它有时是一个包含一个元素的列表)。你可能想看看使用subst,像这样:

puts [subst {
<table id="customers" style="margin-bottom:10px;">
   <tr>
      <th> Rule </th>
      <th> Severity </th>
      <th> Occurrence </th>
   </tr>
}]
foreach k $run_time_stats {
   # Consider using:  lassign $k st st_type st_count
   set st [lindex $k 0]
   set st_type [lindex $k 1]
   set st_count [lindex $k 2]
   set BGCOLOR "#FFFFFF"
   puts [subst {
      <tr>
         <td bgcolor="$BGCOLOR"> $st </td>
         <td bgcolor="$BGCOLOR"> $st_type </td>
         <td> $st_count </td>
      </tr>
   }]
}
puts "</table>"

【讨论】:

  • 谢谢,我试过了,但它给出了错误 can't read "sev": no such variable while execution "list $err $sev $count" (procedure "get_clp_summary" line 13) 从内部调用从“set run_time_stats [get_clp_summary [lindex $argv 0]]”中调用“get_clp_summary [lindex $argv 0]”
  • 嗨,有人可以建议吗?它不返回任何东西
【解决方案3】:

问题在于foreach 循环逐行解析文件。读取第一行后,它没有严重性或计数信息,因此它会失败,因为变量 $sev$count 仍未设置。

一个相当粗略但有效的示例,并且不会偏离您的代码太远,就像这样。

while { [ gets $fp line ]!= -1 } {
    foreach {match label value} [regexp -inline -all {(\w+):\s*(\S*)} $line] {
        switch -exact -- $label {
            Severity   {set sev $value}
            Occurrence {set count $value}
            default    {set err $value}
        }
        if { [info exists err] && [info exists sev] && [info exists count] } {
            lappend pack_stats [ list $err $sev $count]
            unset err sev count
        }
  }

它检查直到所有三个变量都被收集和设置,然后附加返回列表,然后取消设置它们以便可以再次收集它们。还更正了default {set err $label} 部分,因为它认为它是一个值,而不是你想要的标签。如果我的假设是错误的,请回复。

【讨论】:

    最近更新 更多