⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 metrules.c

📁 这是一个C程序分析工具
💻 C
📖 第 1 页 / 共 4 页
字号:
         length = function.operator_length + function.operand_length;         vocabulary = unique_operators + unique_operands;         intelligence = level * volume + ROUND;         lang_level = level * level * volume;         is_logic = FALSE;      }      is_within_function = FALSE;      update_module_stats(do_halstead, volume, level, effort, length,            vocabulary, intelligence, lang_level);      /*         Do not just print summaries and there is at least one metric to         print for a function.      */      if (!summaries_only && print_fcn)         print_function_summary(csv, do_halstead, volume, level, effort,               length, vocabulary, intelligence, lang_level);      if (function.gotos > 0)         warn(W_GOTO, function.gotos, NUMBER(function.gotos));      if (function.continues > 0)         warn(W_CONTINUE, function.continues, NUMBER(function.continues));      if (function.returns > 1)         warn(W_RETURNS, function.returns);   }   /* Only apply these rules if calculating Halstead metrics. */   if (do_halstead)   {      /* Before an initializer in a function? */      if (is_within_function && stm.before_initializer)      {         ++function.operand_length;         add_term(&operand_vocabulary, last_declarator());         is_logic = TRUE;      }      /* Past the declarations in a compound statement? */      if (stm.after_compound_declarations)         is_logic = TRUE;      /* End of an initializer or beginning of a compound block? */      if ((is_within_function && stm.after_initializer) ||            stm.before_compound_declarations)         is_logic = FALSE;      /* Count and record terms for Halstead metrics. */      if (is_logic)      {         if (grm.is_identifier || grm.is_type_name ||               grm.is_constant || grm.is_string)         {            ++function.operand_length;            add_term(&operand_vocabulary, token());         }         else if (keyword("break") || keyword("case") ||               keyword("continue") || keyword("default") || keyword("do") ||               keyword("else") || keyword("for") || keyword("goto") ||               keyword("if") || keyword("return") || keyword("sizeof") ||               keyword("switch") || keyword("while") ||               (grm.is_operator && !(oper("}") || oper(")") || oper("]"))))         {            ++function.operator_length;            add_term(&operator_vocabulary, token());         }      }      /*         Halstead says that labels are just to be considered comments, so         "uncount" them.      */      if (is_logic && stm.is_label)      {         /* Decrement length for both the label's identifier and colon. */         --function.operand_length;         --function.operator_length;         /*            Decrement term count. If these were the only instances of the            label's identifier and colon, remove them from the vocabulary            table.         */         if (--lookup_term(operand_vocabulary, last_identifier())->count == 0)            remove_term(&operand_vocabulary, last_identifier());         if (--lookup_term(operator_vocabulary, ":")->count == 0)            remove_term(&operator_vocabulary, ":");      }   }   /* At the end of each executable statement, record depth statistics. */   if (stm.end && !stm.is_decl)      record_stat(&function.max_depth, stm.depth);   /* Remember if line found with mixed indention (spaces and tabs). */   if (lin.is_mixed_indent)      mixed_indent_lines = TRUE;   /* Print warning if a line contains more than one statement. */   if (lin.statements > 0)      warn(W_MULT_STATEMENTS, lin.statements + 1);   /*      Count compound statements to later subtract from high-statement      total. This is because compound statements are counted as      high-level statements in fcn.high, but SPR code-counting rules do      not consider them to be statements, so they have to be subtracted      back out when reporting executable statements.   */   if (stm.is_comp)      ++function.comp;   /*      Count (goto) labels because the SPR code-counting rules consider      them to be executable statements.  (Curiously, Halstead considers      labels to be merely comments.)   */   if (stm.is_label)      ++function.label;   /*      Count empty statements, i.e., ";". According to Capers Jones, SPR      does not consider this C anomoly to be a "statement" in its      code-counting rules. Subtract from total later because fcn.low      includes empty expressions.   */   if (stm.is_empty_expr)      ++function.empty_expr;   /* Count gotos, continues, and returns. */   if (keyword("goto"))      ++function.gotos;   if (keyword("continue"))      ++function.continues;   if (keyword("return"))      ++function.returns;   /* Record identifier statistics at the function and module level. */   if (grm.is_identifier) {      unsigned str_len = strlen(this_identifier());      record_stat(&function.idents, str_len);      record_stat(&module.idents, str_len);   }   /*      If character encountered that is not in Standard C's source      character set, print warning.   */   if (lex.nonstandard)      warn(W_NONSTANDARD, lex.nonstandard);}/* Tell user how to use Metre and interpret its output. */static void print_help(void){   int i;   unsigned column;   out("-%c          Summaries only             "          "-%c          Halstead metrics\n",          SUMMARY_OPT_CHAR, HALSTEAD_OPT_CHAR);   out("-%c          Adjust function points     "          "-%cN         Stroud number [%d]\n",          ADJUST_FP_OPT_CHAR, STROUD_OPT_CHAR, DEFAULT_STROUD_NUMBER);   out("-%c          Comma-separated-value      "          "-%cxxx       Select specific metric\n",          CSV_OPT_CHAR, SELECT_METRIC_OPT_CHAR);   out("\nNotation and Abbreviations:\n");   out("<           Minimum                    ");   out("Cyclomatic  Cyclomatic Complexity\n");   out(">           Maximum                    ");   out("Max Depth   Max control-structure depth\n");   out("~           Average                    ");   out("Exec        Executable\n");   out("(nothing)   Total                      ");   out("Decl        Declaration\n");   out("Lang        Language                   ");   out("PP          Preprocessor\n");   column = out("\nFor -%c option: ", SELECT_METRIC_OPT_CHAR);   for (i = 0; i < DIM_OF(metric); ++i)   {      if (column + strlen(metric[i].name) + 1 >= OUTPUT_WIDTH)      {         out("\n");         column = 0;      }      column += out("%s ", metric[i].name);   }   out("\n");}/* Mark which metrics to print in the metric[] array. */static BOOLEAN mark_metrics_to_print(void){   static BOOLEAN metric_selected_to_print = FALSE;   int i, j;   int arg_count = argc();   char **arg_values = argv();   /* Start off assuming that no metrics are to be printed. */   for (j = 0; j < DIM_OF(metric); ++j)      metric[j].print = FALSE;   for (i = 1; i < arg_count; ++i)      if (strchr(OPT_INTRO_CHARS, arg_values[i][0]) != NULL &&            arg_values[i][OPTION_START] == SELECT_METRIC_OPT_CHAR)      {         for (j = 0; j < DIM_OF(metric); ++j)            if (strcmp(metric[j].name,                  &arg_values[i][OPTION_STRING_START]) == 0)            {               metric[j].print = TRUE;               metric_selected_to_print = TRUE;               break;            }         if (j == DIM_OF(metric))            warn(W_BAD_METRIC, &arg_values[i][OPTION_STRING_START]);      }   /* If no metrics explicitly selected to print, print all metrics. */   if (!metric_selected_to_print)      for (j = 0; j < DIM_OF(metric); ++j)         metric[j].print = TRUE;   return metric_selected_to_print;}/* Determine whether whole sections are to be printed. */static void mark_sections_to_print(BOOLEAN *print_fcn, BOOLEAN *print_mod_fcn,      BOOLEAN *print_mod, BOOLEAN *print_prj_fcn, BOOLEAN *print_prj_mod,      BOOLEAN *print_prj){   int i;   /* Function metrics. */   *print_fcn = FALSE;   for (i = 0; i < DIM_OF(metric); ++i)      if (metric[i].print && metric[i].fcn)      {         *print_fcn = TRUE;         break;      }   /* Function-related module metrics. */   *print_mod_fcn = FALSE;   for (i = 0; i < DIM_OF(metric); ++i)      if (metric[i].print && metric[i].mod_fcn)      {         *print_mod_fcn = TRUE;         break;      }   /* Module-related module metrics. */   *print_mod = FALSE;   for (i = 0; i < DIM_OF(metric); ++i)      if (metric[i].print && metric[i].mod)      {         *print_mod = TRUE;         break;      }   /* Function-related project metrics. */   *print_prj_fcn = FALSE;   for (i = 0; i < DIM_OF(metric); ++i)      if (metric[i].print && metric[i].prj_fcn)      {         *print_prj_fcn = TRUE;         break;      }   /* Module-related project metrics. */   *print_prj_mod = FALSE;   for (i = 0; i < DIM_OF(metric); ++i)      if (metric[i].print && metric[i].prj_mod)      {         *print_prj_mod = TRUE;         break;      }   /* Project-related project metrics. */   *print_prj = FALSE;   for (i = 0; i < DIM_OF(metric); ++i)      if (metric[i].print && metric[i].prj)      {         *print_prj = TRUE;         break;      }}/* Return whether to print the indicated metric. */static BOOLEAN print_metric(enum metric_type type){   BOOLEAN print_it = TRUE;   int i;   for (i = 0; i < DIM_OF(metric); ++i)      if (metric[i].type == type)         print_it = metric[i].print;   return print_it;}/* Initialize project-level statistics. */static void init_project_stats(BOOLEAN do_halstead){   init_stat(&project.function.decisions);   init_stat(&project.function.conditions);   if (do_halstead)   {      init_stat(&project.function.length);      init_stat(&project.function.vocabulary);      init_stat(&project.function.volume);      init_stat(&project.function.level);      init_stat(&project.function.effort);      init_stat(&project.function.intelligence);      init_stat(&project.function.lang_level);   }   init_stat(&project.function.lines);   init_stat(&project.function.code_lines);   init_stat(&project.function.comment_lines);   init_stat(&project.function.white_lines);   init_stat(&project.function.decls);   init_stat(&project.function.stmnts);   init_stat(&project.function.max_depth);   init_stat(&project.module.lines);   init_stat(&project.module.code_lines);   init_stat(&project.module.comment_lines);   init_stat(&project.module.white_lines);   init_stat(&project.module.decls);   init_stat(&project.module.stmnts);   init_stat(&project.module.pp);   init_stat(&project.module.funcs);   init_stat(&project.idents);   project.modules = 0;}/* Print project summary. */static void print_project_summary(BOOLEAN csv,      BOOLEAN print_prj_fcn, BOOLEAN print_prj_mod, BOOLEAN print_prj,      BOOLEAN do_halstead, BOOLEAN adjust_function_points){   /*      Executable + declaration + preprocessor statements.  For      function-point backfiring.   */   float total_statements;   /* Backfired function points. */   float function_points;   out(csv ? "" : "\n****************************************************");   out(csv ? "prj" : "\n\nProject Summary\n");   /*      Only print function-related stats if at least one function and      there is at least one function-related metric to print for the      project.   */   if (tot_stat(&project.module.funcs) != 0 && print_prj_fcn)   {      out(csv ? "" : "   -Function-\n");      if (print_metric(cyc))         out(csv ? ",%lu,%lu,%lu" : "   Cyclomatic:      <%lu >%lu ~%lu\n",               min_stat(&project.function.decisions) + 1,               max_stat(&project.function.decisions) + 1,               avg_stat(&project.function.decisions) + 1);      if (print_metric(exc))         out(csv ? ",%lu,%lu,%lu" : "     Extended:      <%lu >%lu ~%lu\n",               min_stat(&project.function.conditions) + 1,               max_stat(&project.function.conditions) + 1,               avg_stat(&project.function.conditions) + 1);      if (do_halstead)      {         if (print_metric(pln))            out(csv ? ",%lu,%lu,%lu" : "   Halstead Length: <%lu >%lu ~%lu\n",                  min_stat(&project.function.length),                  max_stat(&project.function.length),                  avg_stat(&project.function.length));         if (print_metric(pvc))            out(csv ? ",%lu,%lu,%lu" : "     Vocabulary:    <%lu >%lu ~%lu\n",                  min_stat(&project.function.vocabulary),                  max_stat(&project.function.vocabulary),                  avg_stat(&project.function.vocabulary));         if (print_metric(pvl))            out(csv ? ",%lu,%lu,%lu" : "     Volume:        <%lu >%lu ~%lu\n",                  min_stat(&project.function.volume),                  max_stat(&project.function.volume),                  avg_stat(&project.function.volume));         if (print_metric(plv))            out(csv ? ",%.3f,%.3f,%.3f" :                  "     Level:         <%.3f >%.3f ~%.3f\n",                  min_stat(&project.function.level) / 1000.0,                  max_stat(&project.function.level) / 1000.0,                  avg_stat(&project.function.level) / 1000.0);         if (print_metric(pef))            out(csv ? ",%lu,%lu,%lu" : "     Effort:        <%lu >%lu ~%lu\n",                  min_stat(&project.function.effort),                  max_stat(&project.function.effort),                  avg_stat(&project.function.effort));         if (print_metric(inc))            out(csv ? ",%lu,%lu,%lu" : "     Intelligence:  <%lu >%lu ~%lu\n",                  min_stat(&project.function.intelligence),                  max_stat(&project.function.intelligence),                  avg_stat(&project.function.intelligence));         if (print_metric(ptm))            out(csv ? ",%.1f,%.1f,%.1f,%.1f" :                  "     Time (hours):  <%.1f >%.1f ~%.1f %.1f\n",                  min_stat(&project.function.effort) / moments_per_hour,                  max_stat(&project.function.effort) / moments_per_hour,                  avg_stat(&project.function.effort) / moments_per_hour,                  tot_stat(&project.function.effort) / moments_per_hour);         if (print_metric(llv))            out(csv ? ",%.2f,%.2f,%.2f" :                  "     Lang Level:    <%.2f >%.2f ~%.2f\n",                  min_stat(&project.function.lang_level) / 100.0,                  max_stat(&project.function.lang_level) / 100.0,                  avg_stat(&project.function.lang_level) / 100.0);      }      if (print_metric(scl))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -