+sub parse_devices {
+ my ($target_dir, $subtarget) = @_;
+
+ if (open M, "make -C '$target_dir' --no-print-directory DUMP=1 TARGET_BUILD=1 SUBTARGET='$subtarget' V=s |") {
+ my ($device_profile, $device_name, @device_alt_names, $device_is_alt);
+ while (defined(my $line = readline M)) {
+ chomp $line;
+
+ if ($line =~ /^Target-Profile-Name: (.+)$/) {
+ $device_name = $1;
+ }
+ elsif ($line =~ /^Target-Profile: DEVICE_(.+)$/) {
+ $device_profile = $1;
+ }
+ # Logic behind this.
+ # DUMP duplicate info for each alternative device name and
+ # the alternative device name are printed first before the
+ # primary device name
+ # Alternative device titles always have the full list of
+ # all the alternative device name.
+ # The device name pattern for an alternative device name is
+ # Target-Profile-Name: ALT_NAME (PRIMARY_NAME)
+ # We compare the detected device name and check if it does
+ # match the alternative device name pattern with one of
+ # the alternative device name in Alternative device titles:
+ # If an alternative device name is detected,
+ # alternative device is skipped.
+ elsif ($line =~ /^Alternative device titles:$/) {
+ while (defined($line = readline M)) {
+ if ($line =~ /^- (.+)$/) {
+ if ($device_name =~ /^\Q$1\E \((.+)\)$/) {
+ $device_is_alt = 1;
+ last;
+ }
+ push @device_alt_names, $1;
+ }
+ else {
+ last;
+ }
+ }
+ }
+ if ($line =~ /^@\@$/) {
+ if ($device_name && $device_profile && ! $device_is_alt) {
+ push @{$devices{$device_profile}}, $device_name;
+
+ if (scalar @device_alt_names) {
+ foreach my $device_alt_name (sort values @device_alt_names) {
+ push @{$devices{$device_profile}}, $device_alt_name;
+ }
+ }
+ }
+
+ undef $device_name;
+ undef $device_profile;
+ undef $device_is_alt;
+ @device_alt_names = ();
+ }
+ }
+ close M;
+ }
+}
+