Global Metrics

path: .metrics.halstead.difficulty
old: 5.555555555555555
new: 35.857142857142854

path: .metrics.halstead.level
old: 0.18
new: 0.027888446215139445

path: .metrics.halstead.purity_ratio
old: 1.027798125448147
new: 1.2067917988678205

path: .metrics.halstead.N2
old: 50.0
new: 251.0

path: .metrics.halstead.length
old: 140.0
new: 592.0

path: .metrics.halstead.n2
old: 27.0
new: 91.0

path: .metrics.halstead.effort
old: 3923.417648389908
new: 145840.1763446196

path: .metrics.halstead.n1
old: 6.0
new: 26.0

path: .metrics.halstead.estimated_program_length
old: 143.8917375627406
new: 714.4207449297497

path: .metrics.halstead.volume
old: 706.2151767101835
new: 4067.255913993375

path: .metrics.halstead.bugs
old: 0.08291920052627293
new: 0.9235566344847896

path: .metrics.halstead.vocabulary
old: 33.0
new: 117.0

path: .metrics.halstead.N1
old: 90.0
new: 341.0

path: .metrics.halstead.time
old: 217.96764713277267
new: 8102.232019145533

path: .metrics.loc.lloc
old: 0.0
new: 41.0

path: .metrics.loc.cloc
old: 49.0
new: 10.0

path: .metrics.loc.sloc
old: 83.0
new: 128.0

path: .metrics.loc.ploc
old: 24.0
new: 107.0

path: .metrics.loc.blank
old: 10.0
new: 11.0

path: .metrics.nom.total
old: 0.0
new: 1.0

path: .metrics.nom.functions
old: 0.0
new: 1.0

path: .metrics.mi.mi_sei
old: 64.24618586185468
new: 10.713199186096729

path: .metrics.mi.mi_original
old: 64.61319828924877
new: 43.66134581661258

path: .metrics.mi.mi_visual_studio
old: 37.78549607558408
new: 25.53295076994888

path: .metrics.cognitive.sum
old: 0.0
new: 36.0

path: .metrics.cognitive.average
old: null
new: 36.0

path: .metrics.nexits.average
old: null
new: 0.0

path: .metrics.nargs.sum
old: 0.0
new: 1.0

path: .metrics.nargs.average
old: null
new: 1.0

path: .metrics.cyclomatic.sum
old: 3.0
new: 24.0

path: .metrics.cyclomatic.average
old: 1.0
new: 12.0

Spaces Data

Minimal test - lines (17, 126)

path: .spaces[0].metrics.halstead.bugs
old: 0.07370327030700347
new: 0.9244753205073072

path: .spaces[0].metrics.halstead.estimated_program_length
old: 96.22039775975506
new: 698.5517080276778

path: .spaces[0].metrics.halstead.n1
old: 6.0
new: 26.0

path: .spaces[0].metrics.halstead.vocabulary
old: 25.0
new: 115.0

path: .spaces[0].metrics.halstead.effort
old: 3287.8501823605047
new: 146057.83702674278

path: .spaces[0].metrics.halstead.level
old: 0.16666666666666666
new: 0.02760545905707196

path: .spaces[0].metrics.halstead.volume
old: 547.9750303934175
new: 4031.993640006237

path: .spaces[0].metrics.halstead.length
old: 118.0
new: 589.0

path: .spaces[0].metrics.halstead.time
old: 182.6583434644725
new: 8114.324279263488

path: .spaces[0].metrics.halstead.difficulty
old: 6.0
new: 36.2247191011236

path: .spaces[0].metrics.halstead.n2
old: 19.0
new: 89.0

path: .spaces[0].metrics.halstead.N1
old: 80.0
new: 341.0

path: .spaces[0].metrics.halstead.purity_ratio
old: 0.8154270996589412
new: 1.185996108705735

path: .spaces[0].metrics.halstead.N2
old: 38.0
new: 248.0

path: .spaces[0].metrics.nargs.average
old: null
new: 1.0

path: .spaces[0].metrics.nargs.sum
old: 0.0
new: 1.0

path: .spaces[0].metrics.nom.functions
old: 0.0
new: 1.0

path: .spaces[0].metrics.nom.total
old: 0.0
new: 1.0

path: .spaces[0].metrics.cyclomatic.sum
old: 1.0
new: 23.0

path: .spaces[0].metrics.cyclomatic.average
old: 1.0
new: 23.0

path: .spaces[0].metrics.loc.lloc
old: 0.0
new: 41.0

path: .spaces[0].metrics.loc.sloc
old: 32.0
new: 110.0

path: .spaces[0].metrics.loc.ploc
old: 10.0
new: 97.0

path: .spaces[0].metrics.loc.blank
old: 6.0
new: 7.0

path: .spaces[0].metrics.loc.cloc
old: 16.0
new: 6.0

path: .spaces[0].metrics.nexits.average
old: null
new: 0.0

path: .spaces[0].metrics.mi.mi_original
old: 81.83268382578565
new: 46.39173366583596

path: .spaces[0].metrics.mi.mi_visual_studio
old: 47.85537065835418
new: 27.12966881043038

path: .spaces[0].metrics.mi.mi_sei
old: 86.91717721185134
new: 11.268679277403216

path: .spaces[0].metrics.cognitive.sum
old: 0.0
new: 36.0

path: .spaces[0].metrics.cognitive.average
old: null
new: 36.0

Code

void leaky::readSymbols(const char* fileName) {
  int fd = ::open(fileName, O_RDONLY);
  if (fd < 0) {
    fprintf(stderr, "%s: unable to open \"%s\"\n", applicationName, fileName);
    exit(-1);
  }

  elf_version(EV_CURRENT);
  Elf* elf = elf_begin(fd, ELF_C_READ, 0);
  if (!elf) {
    fprintf(stderr, "%s: \"%s\": has no symbol table\n", applicationName,
            fileName);
    exit(-1);
  }

  long alloced = 10000;
  Symbol* syms = (Symbol*)malloc(sizeof(Symbol) * 10000);
  Symbol* sp = syms;
  Symbol* last = syms + alloced;

  // Get each of the relevant sections and add them to the list of
  // symbols.
  Elf32_Ehdr* ehdr = elf32_getehdr(elf);
  if (!ehdr) {
    fprintf(stderr, "%s: elf library lossage\n", applicationName);
    exit(-1);
  }
#  if 0
    Elf32_Half ndx = ehdr->e_shstrndx;
#  endif

  Elf_Scn* scn = 0;
  int strtabndx = -1;
  for (int i = 1; (scn = elf_nextscn(elf, scn)) != 0; i++) {
    Elf32_Shdr* shdr = elf32_getshdr(scn);
#  if 0
	char *name = elf_strptr(elf, ndx, (size_t) shdr->sh_name);
	printf("Section %s (%d 0x%x)\n", name ? name : "(null)",
	       shdr->sh_type, shdr->sh_type);
#  endif
    if (shdr->sh_type == SHT_STRTAB) {
      /* We assume here that string tables preceed symbol tables... */
      strtabndx = i;
      continue;
    }
#  if 0
	if (shdr->sh_type == SHT_DYNAMIC) {
	    /* Dynamic */
	    Elf_Data *data = elf_getdata(scn, 0);
	    if (!data || !data->d_size) {
		printf("No data...");
		continue;
	    }

	    Elf32_Dyn *dyn = (Elf32_Dyn*) data->d_buf;
	    Elf32_Dyn *lastdyn =
		(Elf32_Dyn*) ((char*) data->d_buf + data->d_size);
	    for (; dyn < lastdyn; dyn++) {
		printf("tag=%d value=0x%x\n", dyn->d_tag, dyn->d_un.d_val);
	    }
	} else
#  endif
    if ((shdr->sh_type == SHT_SYMTAB) || (shdr->sh_type == SHT_DYNSYM)) {
      /* Symbol table */
      Elf_Data* data = elf_getdata(scn, 0);
      if (!data || !data->d_size) {
        printf("No data...");
        continue;
      }

      /* In theory we now have the symbols... */
      Elf32_Sym* esym = (Elf32_Sym*)data->d_buf;
      Elf32_Sym* lastsym = (Elf32_Sym*)((char*)data->d_buf + data->d_size);
      for (; esym < lastsym; esym++) {
#  if 0
		char *nm = elf_strptr(elf, strtabndx, (size_t)esym->st_name);
		printf("%20s 0x%08x %02x %02x\n",
		       nm, esym->st_value, ELF32_ST_BIND(esym->st_info),
		       ELF32_ST_TYPE(esym->st_info));
#  endif
        if ((esym->st_value == 0) ||
            (ELF32_ST_BIND(esym->st_info) == STB_WEAK) ||
            (ELF32_ST_BIND(esym->st_info) == STB_NUM) ||
            (ELF32_ST_TYPE(esym->st_info) != STT_FUNC)) {
          continue;
        }
#  if 1
        char* nm = elf_strptr(elf, strtabndx, (size_t)esym->st_name);
#  endif
        sp->name = nm ? strdup(nm) : "(no name)";
        sp->address = esym->st_value;
        sp++;
        if (sp >= last) {
          long n = alloced + 10000;
          syms = (Symbol*)realloc(syms, (size_t)(sizeof(Symbol) * n));
          last = syms + n;
          sp = syms + alloced;
          alloced = n;
        }
      }
    }
  }

  int interesting = sp - syms;
  if (!quiet) {
    printf("Total of %d symbols\n", interesting);
  }
  usefulSymbols = interesting;
  externalSymbols = syms;
}