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