Asm-C

 view release on metacpan or  search on metacpan

lib/Asm/C.pm  view on Meta::CPAN

use Data::Dump qw(dump);
use Data::Table::Text qw(:all);
use feature qw(say current_sub);

#D1 Asm::C                                                                      # Extract macro values and structure details from C programs.

#D2 Structures                                                                  # Extract structure details from C programs.

my %extractCStructure;                                                          # Structured extracted from C files

sub extractCStructure($)                                                        # Extract the details of a structure
 {my ($input) = @_;                                                             # Input C file - a temporary one is ok

  return $extractCStructure{$input} if exists $extractCStructure{$input};       # Return cached value if it exists
  return undef unless confirmHasCommandLineCommand(q(gcc));                     # Check that we have gcc

  my $inputFile = -f $input ? $input : writeTempFile($input);                   # Make sure input is in a file

  my $e = qq(gcc -c -x c -fno-eliminate-unused-debug-symbols -fno-eliminate-unused-debug-types -gdwarf $inputFile -o a.out; readelf -w a.out; rm a.out);
  my @e = qx($e);                                                               # Structure details via dwarf debugging info
  my @s;                                                                        # Structure

lib/Asm/C.pm  view on Meta::CPAN

       }
      else
       {say STDERR "No base for offset: $type";
       }
     }
   }

  $extractCStructure{$input} = \%s                                              # Structure details
 } # extractCStructure

sub extractCField($$$)                                                          # Extract the details of a field in a structure in a C file
 {my ($input, $structure, $field) = @_;                                         # Input file, structure name,  field within structure
  if     (my $s = extractCStructure $input)                                     # Structures in file
   {if   (my $S = $$s{$structure})                                              # Found structure
     {if (my $F = $S->fields)                                                   # Structure has fields
       {return $$F{$field};                                                     # Field detail
       }
     }
   }
  undef                                                                         # Parse failed or no such structure
 } # extractCField

sub extractCFieldLoc($$$)                                                       # Extract the offset to the location of a field in a structure in a C file
 {my ($input, $structure, $field) = @_;                                         # Input file, structure name,  field within structure
  if (my $f = extractCField($input, $structure, $field))                        # Structures in file
   {return $f->loc;                                                             # Offset to field location
   }
  undef                                                                         # Parse failed or no such structure or no such field
 } # extractCFieldLoc

sub extractCFieldSize($$$)                                                      # Extract the size of a field in a structure in a C file
 {my ($input, $structure, $field) = @_;                                         # Input file, structure name,  field within structure
  if (my $f = extractCField($input, $structure, $field))                        # Structures in file
   {return $f->size;                                                            # Size of field
   }
  undef                                                                         # Parse failed or no such structure or no such field
 } # extractCFieldSize

sub extractCFieldType($$$)                                                      # Extract the type of a field in a structure in a C file
 {my ($input, $structure, $field) = @_;                                         # Input file, structure name,  field within structure
  if (my $f = extractCField($input, $structure, $field))                        # Structures in file
   {return $f->type;                                                            # Type of field
   }
  undef                                                                         # Parse failed or no such structure or no such field
 } # extractCFieldType

sub extractCStructureFields($$)                                                 # Extract the names of the fields in a C structure
 {my ($input, $structure) = @_;                                                 # Input file, structure name
  if (my $s = extractCStructure $input)                                         # Structures in file
   {if (my $S = $$s{$structure})                                                # Found structure
     {if (my $F = $S->fields)                                                   # Structure has fields
       {return sort keys %$F;                                                   # Return names of fields in structure in ascending order
       }
     }
   }
  ()                                                                            # Parse failed or no such structure
 } # extractCStructureSize

sub extractCStructureSize($$)                                                   # Extract the size of a C structure
 {my ($input, $structure) = @_;                                                 # Input file, structure name
  if (my $s = extractCStructure $input)                                         # Structures in file
   {if (my $S = $$s{$structure})                                                # Found structure
     {return $S->size;                                                          # Return structure size
     }
   }
  undef                                                                         # Parse failed or no such structure
 } # extractCStructureSize

#D2 Macros                                                                      # Extract macro values from C header files

my %extractMacroDefinitionsFromCHeaderFile;                                     # Cache macro definitions

sub extractMacroDefinitionsFromCHeaderFile($)                                   # Extract the macro definitions found in a C header file using gcc
 {my ($includeFile) = @_;                                                       # C Header file name as it would be entered in a C program
  my $d = $extractMacroDefinitionsFromCHeaderFile{$includeFile};                # Cached macro definitions
  return $d if $d;                                                              # Return cached value

  confirmHasCommandLineCommand("gcc");                                          # Check gcc
  my @l = qx(gcc -E -dM -include "$includeFile" - < /dev/null);                 # Use gcc to extract macro definitions

  my %d;
  for my $l(@l)                                                                 # Extract macro definitions
   {if ($l =~ m(\A#define\s+(\S+)\s+(\S+)(.*)))
     {$d{$1} = $2;
     }
   }

  $extractMacroDefinitionsFromCHeaderFile{$includeFile} = \%d;                  # Return definitions
 }

sub extractMacroDefinitionFromCHeaderFile($$)                                   # Extract a macro definitions found in a C header file using gcc
 {my ($includeFile, $macro) = @_;                                               # C Header file name as it would be entered in a C program, macro name
  if (my $d = extractMacroDefinitionsFromCHeaderFile($includeFile))             # Get macro definitions
   {return $$d{$macro};
   }
  undef
 }

#d
#-------------------------------------------------------------------------------
# Export - eeee



( run in 0.763 second using v1.01-cache-2.11-cpan-65fba6d93b7 )