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

📄 metrules.c

📁 这是一个C程序分析工具
💻 C
📖 第 1 页 / 共 4 页
字号:
      total_statements = tot_stat(&module.function.stmnts) + mod.decl + mod.pp;      function_points = total_statements / STMNT_TO_FP_DIVISOR + ROUND;      /*         If function(s) and supposed to, adjust function points based on         average complexity.      */      if (mod.functions != 0 && adjust_function_points)      {         function_points /= fp_adjustment_factor(               avg_stat(&module.function.decisions) + 1);      }      if (print_metric(fnp))         out(csv ? ",%u" : "      Function Points: %u\n",               (unsigned)function_points);      if (print_metric(idc))         out(csv ? ",%lu" : "      Identifiers:     %lu\n",               tim_stat(&module.idents));      if (print_metric(idl))         out(csv ? ",%lu,%lu,%lu" : "        Length:        <%lu >%lu ~%lu\n",               tim_stat(&module.idents) == 0 ? 0 : min_stat(&module.idents),               tim_stat(&module.idents) == 0 ? 0 : max_stat(&module.idents),               tim_stat(&module.idents) == 0 ? 0 : avg_stat(&module.idents));      if (print_metric(fnc))         out(csv ? ",%u" : "      Functions:       %u\n", mod.functions);   }   out(csv ? "\n" : "");}/* Update module-level statistics. */static void update_module_stats(BOOLEAN do_halstead,      unsigned volume, float level, long unsigned effort,      long unsigned length, unsigned vocabulary, unsigned intelligence,      float lang_level){   record_stat(&module.function.decisions, fcn.decisions);   record_stat(&module.function.conditions, fcn.conditions);   if (do_halstead)   {      record_stat(&module.function.length, length);      record_stat(&module.function.vocabulary, vocabulary);      record_stat(&module.function.volume, volume);      /*         In order to maintain precision to the third decimal place while         holding in an unsigned long, multiply by 1000. Will be divided         by 1000 when extracted.      */      record_stat(&module.function.level,            (unsigned long)(level * 1000.0 + ROUND));      record_stat(&module.function.effort, effort);      record_stat(&module.function.intelligence, intelligence);      record_stat(&module.function.lang_level,            (unsigned long)(lang_level * 100.0 + ROUND));   }   record_stat(&module.function.lines, fcn.lines.total);   record_stat(&module.function.code_lines, fcn.lines.code);   record_stat(&module.function.comment_lines, fcn.lines.com);   record_stat(&module.function.white_lines, fcn.lines.white);   record_stat(&module.function.max_depth, max_stat(&function.max_depth));   record_stat(&module.function.decls, fcn.decl);   record_stat(&module.function.stmnts, executable_function_statements());}/* Initialize function-level statistics. */static void init_function_stats(void){   init_stat(&function.idents);   init_stat(&function.max_depth);   function.comp = 0;   function.empty_expr = 0;   function.label = 0;   function.gotos = 0;   function.continues = 0;   function.returns = 0;   function.operand_length = 0;   function.operator_length = 0;}/* Print function summary. */static void print_function_summary(BOOLEAN csv, BOOLEAN do_halstead,      unsigned volume, float level, long unsigned effort,      long unsigned length, unsigned vocabulary, unsigned intelligence,      float lang_level){   if (csv)      out("fcn,%s,%s", mod_name(), fcn_name());   else      out("\n   %s()\n", fcn_name());   if (print_metric(cyc))      out(csv ? ",%u" :            "      Cyclomatic:      %u\n", fcn.decisions + 1);   if (print_metric(exc))      out(csv ? ",%u" :            "        Extended:      %u\n", fcn.conditions + 1);   if (do_halstead)   {      if (print_metric(pln))         out(csv ? ",%lu" :               "      Halstead Length: %lu\n", length);      if (print_metric(pvc))         out(csv ? ",%u" :               "        Vocabulary:    %u\n", vocabulary);      if (print_metric(pvl))         out(csv ? ",%u" :               "        Volume:        %u\n", volume);      if (print_metric(plv))         out(csv ? ",%.3f" :               "        Level:         %.3f\n", level);      if (print_metric(pef))         out(csv ? ",%lu" :               "        Effort:        %lu\n", effort);      if (print_metric(inc))         out(csv ? ",%u" :               "        Intelligence:  %u\n", intelligence);      if (print_metric(ptm))         out(csv ? ",%.1f" :               "        Time (hours):  %.1f\n",               effort / moments_per_hour);      if (print_metric(llv))         out(csv ? ",%.2f" :               "        Lang Level:    %.2f\n", lang_level);   }   if (print_metric(scl))      out(csv ? ",%u" :            "      Lines:           %u\n", fcn.lines.total);   if (print_metric(cdl))      out(csv ? ",%u" :            "        Code:          %u\n", fcn.lines.code);   if (print_metric(cml))      out(csv ? ",%u" :            "        Comment:       %u\n", fcn.lines.com);   if (print_metric(bll))      out(csv ? ",%u" :            "        Blank:         %u\n", fcn.lines.white);   if (print_metric(exs))      out(csv ? ",%u" :            "      Exec Statements: %u\n",            executable_function_statements());   if (print_metric(dcs))      out(csv ? ",%u" :            "      Decl Statements: %u\n", fcn.decl);   if (print_metric(mcd))      out(csv ? ",%lu" :            "      Max Depth:       %lu\n", max_stat(&function.max_depth));   if (print_metric(idc))      out(csv ? ",%lu" :            "      Identifiers:     %lu\n", tim_stat(&function.idents));   if (print_metric(idl))      out(csv ? ",%lu,%lu,%lu" :            "        Length:        <%lu >%lu ~%lu\n",            tim_stat(&function.idents) == 0 ? 0 : min_stat(&function.idents),            tim_stat(&function.idents) == 0 ? 0 : max_stat(&function.idents),            tim_stat(&function.idents) == 0 ? 0 : avg_stat(&function.idents));   out(csv ? "\n" : "");}/*   Return factor that adjusts an initial function-point estimate based   on the average functional complexity of a program. This results in a   more accurate assessment of backfired function points. Divide the   initial function-point estimate by the returned factor to arrive at   the adjusted function-point estimate. Cyclomatic complexity is passed   into this function.   This function uses a table that is similar to the one in Capers Jones   book, _Applied Software Measurement_. Capers' table bases the   adjustment on the sum of these three subjective bounded complexity   metrics: program, data, and code complexity. The table in this   function bases the adjustment on McCabe's objective unbounded   cyclomatic complexity metric. I adapted ideas from Capers' book to   come up with this table but have no idea how well founded it is.*/static float fp_adjustment_factor(unsigned long cyclo){   static struct {      unsigned long min;      float factor;   } table[] = {      { 0,  0.70 },     /* 1 */      { 1,  0.80 },     /* 2 */      { 2,  0.85 },     /* 3 */      { 3,  0.90 },     /* 4-5 */      { 5,  0.95 },     /* 6-8 */      { 8,  1.00 },     /* 9-11 */      { 11, 1.05 },     /* 12-16 */      { 16, 1.10 },     /* 17-21 */      { 21, 1.15 },     /* 22-27 */      { 27, 1.20 },     /* 28-36 */      { 36, 1.25 },     /* 37-53 */      { 53, 1.30 },     /* 54- */   };   unsigned i;   if (cyclo == 0)      fatal(F_BAD_CYCLO);   for (i = 0; i < DIM_OF(table) && cyclo > table[i].min; ++i)      ;   return table[i - 1].factor;}/* Return the total number of executable statements in the current function. */static unsigned executable_function_statements(void){   /*      Subtract out compound statements from the total in fcn.high, then      add 1 back in for the outer-most compound statement that contains      the function itself.   */   return (fcn.low - function.empty_expr) + (fcn.high - function.comp + 1) +         function.label;}/* Common printf-like output function. */static int out(const char *format, ...){   va_list args;   int chars_written;   va_start(args, format);   chars_written = vfprintf(out_fp, format, args);   va_end(args);   return chars_written;}/*   The following *_stat() functions are accessor functions for STAT   structures.*//* Initialize statistic. */static void init_stat(STAT *stat){   stat->times = 0;   stat->total = 0;   TYPE_MAX(stat->min);   stat->max = 0;}/* Record a value for this statistic. */static void record_stat(STAT *stat, unsigned long value){   if (value > stat->max)         stat->max = value;   if (value < stat->min)         stat->min = value;   ++stat->times;   stat->total += value;}/* Absorb source statistic into destination statistic. */static void absorb_stat(STAT *stat_to, STAT *stat_from){   if (stat_from->max > stat_to->max)         stat_to->max = stat_from->max;   if (stat_from->min < stat_to->min)         stat_to->min = stat_from->min;   stat_to->times += stat_from->times;   stat_to->total += stat_from->total;}/* Return minimum value ever recorded for this statistic. */static unsigned long min_stat(STAT *stat){   unsigned long min;   if (stat->times == 0)      min = 0;   else      min = stat->min;   return min;}/* Return maximum value ever recorded for this statistic. */static unsigned long max_stat(STAT *stat){   return stat->max;}/* Return sum of all values ever recorded for this statistic. */static unsigned long tot_stat(STAT *stat){   return stat->total;}/* Return number of times a value was recorded for this statistic. */static unsigned long tim_stat(STAT *stat){   return stat->times;}/*   Return the average value of this statistic, rounding to the nearest   integer.*/static unsigned long avg_stat(STAT *stat){   unsigned long avg;   if (stat->times == 0)      avg = 0;   else      avg = (unsigned long)((float)tot_stat(stat) / stat->times + ROUND);   return avg;}/*   The following functions (clear_vocab(), add_term(), lookup_term(),   and remove_term()) manipulate the linked list whos head is pointed to   by the vocabulary. These functions are used for the Halstead metrics.*//* Remove all vocabulary-table entries and return the number of entries. */static unsigned clear_vocab(TERM **vocabulary){   TERM *term = *vocabulary;   unsigned entries = 0;   while (term != NULL)   {      TERM *next_term;      free(term->string);      next_term = term->next;      free(term);      term = next_term;      ++entries;   }   *vocabulary = NULL;   return entries;}/* Add string to vocabulary table. */static void add_term(TERM **vocabulary, char *string){   TERM *term;   /* If term not found, add a copy of it to the front of the vocabulary. */   if ((term = lookup_term(*vocabulary, string)) == NULL)   {      term = (TERM *)malloc(sizeof *term);      if (term == NULL)         fatal(F_MEMORY);      term->next = *vocabulary;      *vocabulary = term;      term->string = (char *)malloc(strlen(string) + 1);      if (term->string == NULL)         fatal(F_MEMORY);      strcpy(term->string, string);      term->count = 0;   }   ++term->count;}/*   Lookup term in vocabulary table. Return pointer to TERM entry or NULL   if not found.*/static TERM *lookup_term(TERM *vocabulary, char *string){   TERM *term;   /* Search through vocabulary for this term. */   for (term = vocabulary; term != NULL && strcmp(term->string, string) != 0;         term = term->next)      ;   return term;}/* Remove term from vocabulary table. */static void remove_term(TERM **vocabulary, char *string){   TERM *term, *prev_term;   /* Search through vocabulary for this term. */   for (prev_term = NULL, term = *vocabulary;         term != NULL && strcmp(term->string, string) != 0;         prev_term = term, term = term->next)      ;   if (term != NULL)   {      /* If prev_term is NULL, this is the first entry in the linked list. */      if (prev_term == NULL)         *vocabulary = term->next;      else         prev_term->next = term->next;      free(term->string);      free(term);   }   /* (Else if term was not found, do not do anything. */}

⌨️ 快捷键说明

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