1 | package metadata; |
2 | use base 'Exporter'; |
3 | use strict; |
4 | use warnings; |
5 | our @EXPORT = qw(%package %srcpackage %category %subdir %preconfig %features clear_packages parse_package_metadata get_multiline); |
6 | |
7 | our %package; |
8 | our %preconfig; |
9 | our %srcpackage; |
10 | our %category; |
11 | our %subdir; |
12 | our %features; |
13 | |
14 | sub get_multiline { |
15 | my $fh = shift; |
16 | my $prefix = shift; |
17 | my $str; |
18 | while (<$fh>) { |
19 | last if /^@@/; |
20 | $str .= (($_ and $prefix) ? $prefix . $_ : $_); |
21 | } |
22 | |
23 | return $str ? $str : ""; |
24 | } |
25 | |
26 | sub clear_packages() { |
27 | %subdir = (); |
28 | %preconfig = (); |
29 | %package = (); |
30 | %srcpackage = (); |
31 | %category = (); |
32 | %features = (); |
33 | } |
34 | |
35 | sub parse_package_metadata($) { |
36 | my $file = shift; |
37 | my $pkg; |
38 | my $feature; |
39 | my $makefile; |
40 | my $preconfig; |
41 | my $subdir; |
42 | my $src; |
43 | |
44 | open FILE, "<$file" or do { |
45 | warn "Cannot open '$file': $!\n"; |
46 | return undef; |
47 | }; |
48 | while (<FILE>) { |
49 | chomp; |
50 | /^Source-Makefile: \s*((.+\/)([^\/]+)\/Makefile)\s*$/ and do { |
51 | $makefile = $1; |
52 | $subdir = $2; |
53 | $src = $3; |
54 | $subdir =~ s/^package\///; |
55 | $subdir{$src} = $subdir; |
56 | $srcpackage{$src} = []; |
57 | undef $pkg; |
58 | }; |
59 | next unless $src; |
60 | /^Package:\s*(.+?)\s*$/ and do { |
61 | undef $feature; |
62 | $pkg = {}; |
63 | $pkg->{src} = $src; |
64 | $pkg->{makefile} = $makefile; |
65 | $pkg->{name} = $1; |
66 | $pkg->{title} = ""; |
67 | $pkg->{default} = "m if ALL"; |
68 | $pkg->{depends} = []; |
69 | $pkg->{mdepends} = []; |
70 | $pkg->{builddepends} = []; |
71 | $pkg->{buildtypes} = []; |
72 | $pkg->{subdir} = $subdir; |
73 | $pkg->{tristate} = 1; |
74 | $package{$1} = $pkg; |
75 | push @{$srcpackage{$src}}, $pkg; |
76 | }; |
77 | /^Feature:\s*(.+?)\s*$/ and do { |
78 | undef $pkg; |
79 | $feature = {}; |
80 | $feature->{name} = $1; |
81 | $feature->{priority} = 0; |
82 | }; |
83 | $feature and do { |
84 | /^Target-Name:\s*(.+?)\s*$/ and do { |
85 | $features{$1} or $features{$1} = []; |
86 | push @{$features{$1}}, $feature; |
87 | }; |
88 | /^Target-Title:\s*(.+?)\s*$/ and $feature->{target_title} = $1; |
89 | /^Feature-Priority:\s*(\d+)\s*$/ and $feature->{priority} = $1; |
90 | /^Feature-Name:\s*(.+?)\s*$/ and $feature->{title} = $1; |
91 | /^Feature-Description:/ and $feature->{description} = get_multiline(\*FILE, "\t\t\t"); |
92 | next; |
93 | }; |
94 | next unless $pkg; |
95 | /^Version: \s*(.+)\s*$/ and $pkg->{version} = $1; |
96 | /^Title: \s*(.+)\s*$/ and $pkg->{title} = $1; |
97 | /^Menu: \s*(.+)\s*$/ and $pkg->{menu} = $1; |
98 | /^Submenu: \s*(.+)\s*$/ and $pkg->{submenu} = $1; |
99 | /^Submenu-Depends: \s*(.+)\s*$/ and $pkg->{submenudep} = $1; |
100 | /^Source: \s*(.+)\s*$/ and $pkg->{source} = $1; |
101 | /^Default: \s*(.+)\s*$/ and $pkg->{default} = $1; |
102 | /^Provides: \s*(.+)\s*$/ and do { |
103 | my @vpkg = split /\s+/, $1; |
104 | foreach my $vpkg (@vpkg) { |
105 | $package{$vpkg} or $package{$vpkg} = { |
106 | name => $vpkg, |
107 | vdepends => [], |
108 | src => $src, |
109 | subdir => $subdir, |
110 | makefile => $makefile |
111 | }; |
112 | push @{$package{$vpkg}->{vdepends}}, $pkg->{name}; |
113 | } |
114 | }; |
115 | /^Menu-Depends: \s*(.+)\s*$/ and $pkg->{mdepends} = [ split /\s+/, $1 ]; |
116 | /^Depends: \s*(.+)\s*$/ and $pkg->{depends} = [ split /\s+/, $1 ]; |
117 | /^Hidden: \s*(.+)\s*$/ and $pkg->{hidden} = 1; |
118 | /^Build-Variant: \s*([\w\-]+)\s*/ and $pkg->{variant} = $1; |
119 | /^Build-Only: \s*(.+)\s*$/ and $pkg->{buildonly} = 1; |
120 | /^Build-Depends: \s*(.+)\s*$/ and $pkg->{builddepends} = [ split /\s+/, $1 ]; |
121 | /^Build-Depends\/(\w+): \s*(.+)\s*$/ and $pkg->{"builddepends/$1"} = [ split /\s+/, $2 ]; |
122 | /^Build-Types:\s*(.+)\s*$/ and $pkg->{buildtypes} = [ split /\s+/, $1 ]; |
123 | /^Category: \s*(.+)\s*$/ and do { |
124 | $pkg->{category} = $1; |
125 | defined $category{$1} or $category{$1} = {}; |
126 | defined $category{$1}->{$src} or $category{$1}->{$src} = []; |
127 | push @{$category{$1}->{$src}}, $pkg; |
128 | }; |
129 | /^Description: \s*(.*)\s*$/ and $pkg->{description} = "\t\t $1\n". get_multiline(*FILE, "\t\t "); |
130 | /^Type: \s*(.+)\s*$/ and do { |
131 | $pkg->{type} = [ split /\s+/, $1 ]; |
132 | undef $pkg->{tristate}; |
133 | foreach my $type (@{$pkg->{type}}) { |
134 | $type =~ /ipkg/ and $pkg->{tristate} = 1; |
135 | } |
136 | }; |
137 | /^Config:\s*(.*)\s*$/ and $pkg->{config} = "$1\n".get_multiline(*FILE, "\t"); |
138 | /^Prereq-Check:/ and $pkg->{prereq} = 1; |
139 | /^Preconfig:\s*(.+)\s*$/ and do { |
140 | my $pkgname = $pkg->{name}; |
141 | $preconfig{$pkgname} or $preconfig{$pkgname} = {}; |
142 | if (exists $preconfig{$pkgname}->{$1}) { |
143 | $preconfig = $preconfig{$pkgname}->{$1}; |
144 | } else { |
145 | $preconfig = { |
146 | id => $1 |
147 | }; |
148 | $preconfig{$pkgname}->{$1} = $preconfig; |
149 | } |
150 | }; |
151 | /^Preconfig-Type:\s*(.*?)\s*$/ and $preconfig->{type} = $1; |
152 | /^Preconfig-Label:\s*(.*?)\s*$/ and $preconfig->{label} = $1; |
153 | /^Preconfig-Default:\s*(.*?)\s*$/ and $preconfig->{default} = $1; |
154 | } |
155 | close FILE; |
156 | return 1; |
157 | } |
158 | |
159 | 1; |
160 | |