File: Struct.pm

package info (click to toggle)
icheck 0.9.7-9
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,352 kB
  • sloc: perl: 12,152; makefile: 202; ansic: 100
file content (110 lines) | stat: -rw-r--r-- 2,468 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package CParse::Struct;

use 5.6.0;
use strict;
use warnings;

use File::Spec;
use CType::Struct;
use CType::Ref;

sub new
  {
    my $this = shift;
    my $class = ref($this) || $this;
    my $tag = shift;
    my $declarations = shift;
    my $attributes1 = shift;
    my $attributes2 = shift;
    my $self = {tag => $tag,
                declarations => $declarations,
                attributes1 => $attributes1,
                attributes2 => $attributes2,
               };
    bless $self, $class;
    return $self;
  }

sub dump_c
  {
    my $self = shift;

    my $str = '';

    $str .= "struct";
    if ($self->{attributes1})
      {
        $str .= " " . $self->{attributes1}->dump_c;
      }
    if ($self->{tag})
      {
        $str .= " $self->{tag}";
      }
    $str .= "\n{\n";
    foreach my $declaration (@{$self->{declarations}})
      {
        my @dump = split /\n/, $declaration->dump_c;
        $str .= join('', map {"  $_\n"} @dump);
      }
    $str .= "}";
    if ($self->{attributes2})
      {
        $str .= " " . $self->{attributes2}->dump_c;
      }

    return $str;
  }

sub construct_type
  {
    my $self = shift;
    my $namespace = shift;

    my @attributes;
    push @attributes, $self->{attributes1}->attributes if $self->{attributes1};
    push @attributes, $self->{attributes2}->attributes if $self->{attributes2};

    my @members = map {$_->get_members($namespace)} @{$self->{declarations}};

    return new CType::Struct \@members, \@attributes, $CParse::current_location;
  }

sub process
  {
    my $self = shift;

    my $namespace = shift;

    if ($self->{tag})
      {
        # Heuristic: we'll ignore redefinitions that occur at the same file:line
        my $old = $namespace->get('struct', $self->{tag});
        if ($old and
            (File::Spec->canonpath($old->{file}) ne File::Spec->canonpath($CParse::current_location->{file})
             or $old->{line} ne $CParse::current_location->{line}))
          {
            die "Redefinition of struct $self->{tag}\n (old definition at $old->{file}:$old->{line})\n";
          }

        my $type = $self->construct_type($namespace);
        $namespace->set('struct', $self->{tag}, $type);
      }
  }

sub get_type
  {
    my $self = shift;

    my $namespace = shift;

    if ($self->{tag})
      {
        return new CType::Ref 'struct', $self->{tag}, $namespace;
      }
    else
      {
        return $self->construct_type($namespace);
      }
  }

1;