# 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;
    }