~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/scripts/get_feat.pl

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /scripts/get_feat.pl (Version linux-6.11.5) and /scripts/get_feat.pl (Version linux-6.8.12)


  1 #!/usr/bin/env perl                                 1 #!/usr/bin/env perl
  2 # SPDX-License-Identifier: GPL-2.0                  2 # SPDX-License-Identifier: GPL-2.0
  3                                                     3 
  4 use strict;                                         4 use strict;
  5 use Pod::Usage;                                     5 use Pod::Usage;
  6 use Getopt::Long;                                   6 use Getopt::Long;
  7 use File::Find;                                     7 use File::Find;
  8 use Fcntl ':mode';                                  8 use Fcntl ':mode';
  9 use Cwd 'abs_path';                                 9 use Cwd 'abs_path';
 10                                                    10 
 11 my $help;                                          11 my $help;
 12 my $man;                                           12 my $man;
 13 my $debug;                                         13 my $debug;
 14 my $arch;                                          14 my $arch;
 15 my $feat;                                          15 my $feat;
 16 my $enable_fname;                                  16 my $enable_fname;
 17                                                    17 
 18 my $basename = abs_path($0);                       18 my $basename = abs_path($0);
 19 $basename =~ s,/[^/]+$,/,;                         19 $basename =~ s,/[^/]+$,/,;
 20                                                    20 
 21 my $prefix=$basename . "../Documentation/featu     21 my $prefix=$basename . "../Documentation/features";
 22                                                    22 
 23 # Used only at for full features output. The s     23 # Used only at for full features output. The script will auto-adjust
 24 # such values for the minimal possible values      24 # such values for the minimal possible values
 25 my $status_size = 1;                               25 my $status_size = 1;
 26 my $description_size = 1;                          26 my $description_size = 1;
 27                                                    27 
 28 GetOptions(                                        28 GetOptions(
 29         "debug|d+" => \$debug,                     29         "debug|d+" => \$debug,
 30         "dir=s" => \$prefix,                       30         "dir=s" => \$prefix,
 31         'help|?' => \$help,                        31         'help|?' => \$help,
 32         'arch=s' => \$arch,                        32         'arch=s' => \$arch,
 33         'feat=s' => \$feat,                        33         'feat=s' => \$feat,
 34         'feature=s' => \$feat,                     34         'feature=s' => \$feat,
 35         "enable-fname" => \$enable_fname,          35         "enable-fname" => \$enable_fname,
 36         man => \$man                               36         man => \$man
 37 ) or pod2usage(2);                                 37 ) or pod2usage(2);
 38                                                    38 
 39 pod2usage(1) if $help;                             39 pod2usage(1) if $help;
 40 pod2usage(-exitstatus => 0, -verbose => 2) if      40 pod2usage(-exitstatus => 0, -verbose => 2) if $man;
 41                                                    41 
 42 pod2usage(1) if (scalar @ARGV < 1 || @ARGV > 2)     42 pod2usage(1) if (scalar @ARGV < 1 || @ARGV > 2);
 43                                                    43 
 44 my ($cmd, $arg) = @ARGV;                           44 my ($cmd, $arg) = @ARGV;
 45                                                    45 
 46 pod2usage(2) if ($cmd ne "current" && $cmd ne      46 pod2usage(2) if ($cmd ne "current" && $cmd ne "rest" && $cmd ne "validate"
 47                 && $cmd ne "ls" && $cmd ne "li     47                 && $cmd ne "ls" && $cmd ne "list");
 48                                                    48 
 49 require Data::Dumper if ($debug);                  49 require Data::Dumper if ($debug);
 50                                                    50 
 51 my %data;                                          51 my %data;
 52 my %archs;                                         52 my %archs;
 53                                                    53 
 54 #                                                  54 #
 55 # Displays an error message, printing file nam     55 # Displays an error message, printing file name and line
 56 #                                                  56 #
 57 sub parse_error($$$$) {                            57 sub parse_error($$$$) {
 58         my ($file, $ln, $msg, $data) = @_;         58         my ($file, $ln, $msg, $data) = @_;
 59                                                    59 
 60         $data =~ s/\s+$/\n/;                       60         $data =~ s/\s+$/\n/;
 61                                                    61 
 62         print STDERR "Warning: file $file#$ln:     62         print STDERR "Warning: file $file#$ln:\n\t$msg";
 63                                                    63 
 64         if ($data ne "") {                         64         if ($data ne "") {
 65                 print STDERR ". Line\n\t\t$dat     65                 print STDERR ". Line\n\t\t$data";
 66         } else {                                   66         } else {
 67             print STDERR "\n";                     67             print STDERR "\n";
 68         }                                          68         }
 69 }                                                  69 }
 70                                                    70 
 71 #                                                  71 #
 72 # Parse a features file, storing its contents      72 # Parse a features file, storing its contents at %data
 73 #                                                  73 #
 74                                                    74 
 75 my $h_name = "Feature";                            75 my $h_name = "Feature";
 76 my $h_kconfig = "Kconfig";                         76 my $h_kconfig = "Kconfig";
 77 my $h_description = "Description";                 77 my $h_description = "Description";
 78 my $h_subsys = "Subsystem";                        78 my $h_subsys = "Subsystem";
 79 my $h_status = "Status";                           79 my $h_status = "Status";
 80 my $h_arch = "Architecture";                       80 my $h_arch = "Architecture";
 81                                                    81 
 82 my $max_size_name = length($h_name);               82 my $max_size_name = length($h_name);
 83 my $max_size_kconfig = length($h_kconfig);         83 my $max_size_kconfig = length($h_kconfig);
 84 my $max_size_description = length($h_descripti     84 my $max_size_description = length($h_description);
 85 my $max_size_subsys = length($h_subsys);           85 my $max_size_subsys = length($h_subsys);
 86 my $max_size_status = length($h_status);           86 my $max_size_status = length($h_status);
 87                                                    87 
 88 my $max_size_arch = 0;                             88 my $max_size_arch = 0;
 89 my $max_size_arch_with_header;                     89 my $max_size_arch_with_header;
 90 my $max_description_word = 0;                      90 my $max_description_word = 0;
 91                                                    91 
 92 sub parse_feat {                                   92 sub parse_feat {
 93         my $file = $File::Find::name;              93         my $file = $File::Find::name;
 94                                                    94 
 95         my $mode = (stat($file))[2];               95         my $mode = (stat($file))[2];
 96         return if ($mode & S_IFDIR);               96         return if ($mode & S_IFDIR);
 97         return if ($file =~ m,($prefix)/arch-s     97         return if ($file =~ m,($prefix)/arch-support.txt,);
 98         return if (!($file =~ m,arch-support.t     98         return if (!($file =~ m,arch-support.txt$,));
 99                                                    99 
100         if ($enable_fname) {                      100         if ($enable_fname) {
101                 printf ".. FILE %s\n", abs_pat    101                 printf ".. FILE %s\n", abs_path($file);
102         }                                         102         }
103                                                   103 
104         my $subsys = "";                          104         my $subsys = "";
105         $subsys = $2 if ( m,.*($prefix)/([^/]+    105         $subsys = $2 if ( m,.*($prefix)/([^/]+).*,);
106                                                   106 
107         if (length($subsys) > $max_size_subsys    107         if (length($subsys) > $max_size_subsys) {
108                 $max_size_subsys = length($sub    108                 $max_size_subsys = length($subsys);
109         }                                         109         }
110                                                   110 
111         my $name;                                 111         my $name;
112         my $kconfig;                              112         my $kconfig;
113         my $description;                          113         my $description;
114         my $comments = "";                        114         my $comments = "";
115         my $last_status;                          115         my $last_status;
116         my $ln;                                   116         my $ln;
117         my %arch_table;                           117         my %arch_table;
118                                                   118 
119         print STDERR "Opening $file\n" if ($de    119         print STDERR "Opening $file\n" if ($debug > 1);
120         open IN, $file;                           120         open IN, $file;
121                                                   121 
122         while(<IN>) {                             122         while(<IN>) {
123                 $ln++;                            123                 $ln++;
124                                                   124 
125                 if (m/^\#\s+Feature\s+name:\s*    125                 if (m/^\#\s+Feature\s+name:\s*(.*\S)/) {
126                         $name = $1;               126                         $name = $1;
127                         if (length($name) > $m    127                         if (length($name) > $max_size_name) {
128                                 $max_size_name    128                                 $max_size_name = length($name);
129                         }                         129                         }
130                         next;                     130                         next;
131                 }                                 131                 }
132                 if (m/^\#\s+Kconfig:\s*(.*\S)/    132                 if (m/^\#\s+Kconfig:\s*(.*\S)/) {
133                         $kconfig = $1;            133                         $kconfig = $1;
134                         if (length($kconfig) >    134                         if (length($kconfig) > $max_size_kconfig) {
135                                 $max_size_kcon    135                                 $max_size_kconfig = length($kconfig);
136                         }                         136                         }
137                         next;                     137                         next;
138                 }                                 138                 }
139                 if (m/^\#\s+description:\s*(.*    139                 if (m/^\#\s+description:\s*(.*\S)/) {
140                         $description = $1;        140                         $description = $1;
141                         if (length($descriptio    141                         if (length($description) > $max_size_description) {
142                                 $max_size_desc    142                                 $max_size_description = length($description);
143                         }                         143                         }
144                                                   144 
145                         foreach my $word (spli    145                         foreach my $word (split /\s+/, $description) {
146                                 if (length($wo    146                                 if (length($word) > $max_description_word) {
147                                         $max_d    147                                         $max_description_word = length($word);
148                                 }                 148                                 }
149                         }                         149                         }
150                                                   150 
151                         next;                     151                         next;
152                 }                                 152                 }
153                 next if (m/^\\s*$/);              153                 next if (m/^\\s*$/);
154                 next if (m/^\s*\-+\s*$/);         154                 next if (m/^\s*\-+\s*$/);
155                 next if (m/^\s*\|\s*arch\s*\|\    155                 next if (m/^\s*\|\s*arch\s*\|\s*status\s*\|\s*$/);
156                                                   156 
157                 if (m/^\#\s*(.*)/) {              157                 if (m/^\#\s*(.*)/) {
158                         $comments .= "$1\n";      158                         $comments .= "$1\n";
159                         next;                     159                         next;
160                 }                                 160                 }
161                 if (m/^\s*\|\s*(\S+):\s*\|\s*(    161                 if (m/^\s*\|\s*(\S+):\s*\|\s*(\S+)\s*\|\s*$/) {
162                         my $a = $1;               162                         my $a = $1;
163                         my $status = $2;          163                         my $status = $2;
164                                                   164 
165                         if (length($status) >     165                         if (length($status) > $max_size_status) {
166                                 $max_size_stat    166                                 $max_size_status = length($status);
167                         }                         167                         }
168                         if (length($a) > $max_    168                         if (length($a) > $max_size_arch) {
169                                 $max_size_arch    169                                 $max_size_arch = length($a);
170                         }                         170                         }
171                                                   171 
172                         $status = "---" if ($s    172                         $status = "---" if ($status =~ m/^\.\.$/);
173                                                   173 
174                         $archs{$a} = 1;           174                         $archs{$a} = 1;
175                         $arch_table{$a} = $sta    175                         $arch_table{$a} = $status;
176                         next;                     176                         next;
177                 }                                 177                 }
178                                                   178 
179                 #Everything else is an error      179                 #Everything else is an error
180                 parse_error($file, $ln, "line     180                 parse_error($file, $ln, "line is invalid", $_);
181         }                                         181         }
182         close IN;                                 182         close IN;
183                                                   183 
184         if (!$name) {                             184         if (!$name) {
185                 parse_error($file, $ln, "Featu    185                 parse_error($file, $ln, "Feature name not found", "");
186                 return;                           186                 return;
187         }                                         187         }
188                                                   188 
189         parse_error($file, $ln, "Subsystem not    189         parse_error($file, $ln, "Subsystem not found", "") if (!$subsys);
190         parse_error($file, $ln, "Kconfig not f    190         parse_error($file, $ln, "Kconfig not found", "") if (!$kconfig);
191         parse_error($file, $ln, "Description n    191         parse_error($file, $ln, "Description not found", "") if (!$description);
192                                                   192 
193         if (!%arch_table) {                       193         if (!%arch_table) {
194                 parse_error($file, $ln, "Archi    194                 parse_error($file, $ln, "Architecture table not found", "");
195                 return;                           195                 return;
196         }                                         196         }
197                                                   197 
198         $data{$name}->{where} = $file;            198         $data{$name}->{where} = $file;
199         $data{$name}->{subsys} = $subsys;         199         $data{$name}->{subsys} = $subsys;
200         $data{$name}->{kconfig} = $kconfig;       200         $data{$name}->{kconfig} = $kconfig;
201         $data{$name}->{description} = $descrip    201         $data{$name}->{description} = $description;
202         $data{$name}->{comments} = $comments;     202         $data{$name}->{comments} = $comments;
203         $data{$name}->{table} = \%arch_table;     203         $data{$name}->{table} = \%arch_table;
204                                                   204 
205         $max_size_arch_with_header = $max_size    205         $max_size_arch_with_header = $max_size_arch + length($h_arch);
206 }                                                 206 }
207                                                   207 
208 #                                                 208 #
209 # Output feature(s) for a given architecture      209 # Output feature(s) for a given architecture
210 #                                                 210 #
211 sub output_arch_table {                           211 sub output_arch_table {
212         my $title = "Feature status on $arch a    212         my $title = "Feature status on $arch architecture";
213                                                   213 
214         print "=" x length($title) . "\n";        214         print "=" x length($title) . "\n";
215         print "$title\n";                         215         print "$title\n";
216         print "=" x length($title) . "\n\n";      216         print "=" x length($title) . "\n\n";
217                                                   217 
218         print "=" x $max_size_subsys;             218         print "=" x $max_size_subsys;
219         print "  ";                               219         print "  ";
220         print "=" x $max_size_name;               220         print "=" x $max_size_name;
221         print "  ";                               221         print "  ";
222         print "=" x $max_size_kconfig;            222         print "=" x $max_size_kconfig;
223         print "  ";                               223         print "  ";
224         print "=" x $max_size_status;             224         print "=" x $max_size_status;
225         print "  ";                               225         print "  ";
226         print "=" x $max_size_description;        226         print "=" x $max_size_description;
227         print "\n";                               227         print "\n";
228         printf "%-${max_size_subsys}s  ", $h_s    228         printf "%-${max_size_subsys}s  ", $h_subsys;
229         printf "%-${max_size_name}s  ", $h_nam    229         printf "%-${max_size_name}s  ", $h_name;
230         printf "%-${max_size_kconfig}s  ", $h_    230         printf "%-${max_size_kconfig}s  ", $h_kconfig;
231         printf "%-${max_size_status}s  ", $h_s    231         printf "%-${max_size_status}s  ", $h_status;
232         printf "%-${max_size_description}s\n",    232         printf "%-${max_size_description}s\n", $h_description;
233         print "=" x $max_size_subsys;             233         print "=" x $max_size_subsys;
234         print "  ";                               234         print "  ";
235         print "=" x $max_size_name;               235         print "=" x $max_size_name;
236         print "  ";                               236         print "  ";
237         print "=" x $max_size_kconfig;            237         print "=" x $max_size_kconfig;
238         print "  ";                               238         print "  ";
239         print "=" x $max_size_status;             239         print "=" x $max_size_status;
240         print "  ";                               240         print "  ";
241         print "=" x $max_size_description;        241         print "=" x $max_size_description;
242         print "\n";                               242         print "\n";
243                                                   243 
244         foreach my $name (sort {                  244         foreach my $name (sort {
245                                 ($data{$a}->{s    245                                 ($data{$a}->{subsys} cmp $data{$b}->{subsys}) ||
246                                 ("\L$a" cmp "\    246                                 ("\L$a" cmp "\L$b")
247                                } keys %data) {    247                                } keys %data) {
248                 next if ($feat && $name ne $fe    248                 next if ($feat && $name ne $feat);
249                                                   249 
250                 my %arch_table = %{$data{$name    250                 my %arch_table = %{$data{$name}->{table}};
251                 printf "%-${max_size_subsys}s     251                 printf "%-${max_size_subsys}s  ", $data{$name}->{subsys};
252                 printf "%-${max_size_name}s  "    252                 printf "%-${max_size_name}s  ", $name;
253                 printf "%-${max_size_kconfig}s    253                 printf "%-${max_size_kconfig}s  ", $data{$name}->{kconfig};
254                 printf "%-${max_size_status}s     254                 printf "%-${max_size_status}s  ", $arch_table{$arch};
255                 printf "%-s\n", $data{$name}->    255                 printf "%-s\n", $data{$name}->{description};
256         }                                         256         }
257                                                   257 
258         print "=" x $max_size_subsys;             258         print "=" x $max_size_subsys;
259         print "  ";                               259         print "  ";
260         print "=" x $max_size_name;               260         print "=" x $max_size_name;
261         print "  ";                               261         print "  ";
262         print "=" x $max_size_kconfig;            262         print "=" x $max_size_kconfig;
263         print "  ";                               263         print "  ";
264         print "=" x $max_size_status;             264         print "=" x $max_size_status;
265         print "  ";                               265         print "  ";
266         print "=" x $max_size_description;        266         print "=" x $max_size_description;
267         print "\n";                               267         print "\n";
268 }                                                 268 }
269                                                   269 
270 #                                                 270 #
271 # list feature(s) for a given architecture        271 # list feature(s) for a given architecture
272 #                                                 272 #
273 sub list_arch_features {                          273 sub list_arch_features {
274         print "#\n# Kernel feature support mat    274         print "#\n# Kernel feature support matrix of the '$arch' architecture:\n#\n";
275                                                   275 
276         foreach my $name (sort {                  276         foreach my $name (sort {
277                                 ($data{$a}->{s    277                                 ($data{$a}->{subsys} cmp $data{$b}->{subsys}) ||
278                                 ("\L$a" cmp "\    278                                 ("\L$a" cmp "\L$b")
279                                } keys %data) {    279                                } keys %data) {
280                 next if ($feat && $name ne $fe    280                 next if ($feat && $name ne $feat);
281                                                   281 
282                 my %arch_table = %{$data{$name    282                 my %arch_table = %{$data{$name}->{table}};
283                                                   283 
284                 my $status = $arch_table{$arch    284                 my $status = $arch_table{$arch};
285                 $status = " " x ((4 - length($    285                 $status = " " x ((4 - length($status)) / 2) . $status;
286                                                   286 
287                 printf " %${max_size_subsys}s/    287                 printf " %${max_size_subsys}s/ ", $data{$name}->{subsys};
288                 printf "%-${max_size_name}s: "    288                 printf "%-${max_size_name}s: ", $name;
289                 printf "%-5s|   ", $status;       289                 printf "%-5s|   ", $status;
290                 printf "%${max_size_kconfig}s     290                 printf "%${max_size_kconfig}s # ", $data{$name}->{kconfig};
291                 printf " %s\n", $data{$name}->    291                 printf " %s\n", $data{$name}->{description};
292         }                                         292         }
293 }                                                 293 }
294                                                   294 
295 #                                                 295 #
296 # Output a feature on all architectures           296 # Output a feature on all architectures
297 #                                                 297 #
298 sub output_feature {                              298 sub output_feature {
299         my $title = "Feature $feat";              299         my $title = "Feature $feat";
300                                                   300 
301         print "=" x length($title) . "\n";        301         print "=" x length($title) . "\n";
302         print "$title\n";                         302         print "$title\n";
303         print "=" x length($title) . "\n\n";      303         print "=" x length($title) . "\n\n";
304                                                   304 
305         print ":Subsystem: $data{$feat}->{subs    305         print ":Subsystem: $data{$feat}->{subsys} \n" if ($data{$feat}->{subsys});
306         print ":Kconfig: $data{$feat}->{kconfi    306         print ":Kconfig: $data{$feat}->{kconfig} \n" if ($data{$feat}->{kconfig});
307                                                   307 
308         my $desc = $data{$feat}->{description}    308         my $desc = $data{$feat}->{description};
309         $desc =~ s/^([a-z])/\U$1/;                309         $desc =~ s/^([a-z])/\U$1/;
310         $desc =~ s/\.?\s*//;                      310         $desc =~ s/\.?\s*//;
311         print "\n$desc.\n\n";                     311         print "\n$desc.\n\n";
312                                                   312 
313         my $com = $data{$feat}->{comments};       313         my $com = $data{$feat}->{comments};
314         $com =~ s/^\s+//;                         314         $com =~ s/^\s+//;
315         $com =~ s/\s+$//;                         315         $com =~ s/\s+$//;
316         if ($com) {                               316         if ($com) {
317                 print "Comments\n";               317                 print "Comments\n";
318                 print "--------\n\n";             318                 print "--------\n\n";
319                 print "$com\n\n";                 319                 print "$com\n\n";
320         }                                         320         }
321                                                   321 
322         print "=" x $max_size_arch_with_header    322         print "=" x $max_size_arch_with_header;
323         print "  ";                               323         print "  ";
324         print "=" x $max_size_status;             324         print "=" x $max_size_status;
325         print "\n";                               325         print "\n";
326                                                   326 
327         printf "%-${max_size_arch}s  ", $h_arc    327         printf "%-${max_size_arch}s  ", $h_arch;
328         printf "%-${max_size_status}s", $h_sta    328         printf "%-${max_size_status}s", $h_status . "\n";
329                                                   329 
330         print "=" x $max_size_arch_with_header    330         print "=" x $max_size_arch_with_header;
331         print "  ";                               331         print "  ";
332         print "=" x $max_size_status;             332         print "=" x $max_size_status;
333         print "\n";                               333         print "\n";
334                                                   334 
335         my %arch_table = %{$data{$feat}->{tabl    335         my %arch_table = %{$data{$feat}->{table}};
336         foreach my $arch (sort keys %arch_tabl    336         foreach my $arch (sort keys %arch_table) {
337                 printf "%-${max_size_arch}s  "    337                 printf "%-${max_size_arch}s  ", $arch;
338                 printf "%-${max_size_status}s\    338                 printf "%-${max_size_status}s\n", $arch_table{$arch};
339         }                                         339         }
340                                                   340 
341         print "=" x $max_size_arch_with_header    341         print "=" x $max_size_arch_with_header;
342         print "  ";                               342         print "  ";
343         print "=" x $max_size_status;             343         print "=" x $max_size_status;
344         print "\n";                               344         print "\n";
345 }                                                 345 }
346                                                   346 
347 #                                                 347 #
348 # Output all features for all architectures       348 # Output all features for all architectures
349 #                                                 349 #
350                                                   350 
351 sub matrix_lines($$$) {                           351 sub matrix_lines($$$) {
352         my $desc_size = shift;                    352         my $desc_size = shift;
353         my $status_size = shift;                  353         my $status_size = shift;
354         my $header = shift;                       354         my $header = shift;
355         my $fill;                                 355         my $fill;
356         my $ln_marker;                            356         my $ln_marker;
357                                                   357 
358         if ($header) {                            358         if ($header) {
359                 $ln_marker = "=";                 359                 $ln_marker = "=";
360         } else {                                  360         } else {
361                 $ln_marker = "-";                 361                 $ln_marker = "-";
362         }                                         362         }
363                                                   363 
364         $fill = $ln_marker;                       364         $fill = $ln_marker;
365                                                   365 
366         print "+";                                366         print "+";
367         print $fill x $max_size_name;             367         print $fill x $max_size_name;
368         print "+";                                368         print "+";
369         print $fill x $desc_size;                 369         print $fill x $desc_size;
370         print "+";                                370         print "+";
371         print $ln_marker x $status_size;          371         print $ln_marker x $status_size;
372         print "+\n";                              372         print "+\n";
373 }                                                 373 }
374                                                   374 
375 sub output_matrix {                               375 sub output_matrix {
376         my $title = "Feature status on all arc    376         my $title = "Feature status on all architectures";
377         my $notcompat = "Not compatible";         377         my $notcompat = "Not compatible";
378                                                   378 
379         print "=" x length($title) . "\n";        379         print "=" x length($title) . "\n";
380         print "$title\n";                         380         print "$title\n";
381         print "=" x length($title) . "\n\n";      381         print "=" x length($title) . "\n\n";
382                                                   382 
383         my $desc_title = "$h_kconfig / $h_desc    383         my $desc_title = "$h_kconfig / $h_description";
384                                                   384 
385         my $desc_size = $max_size_kconfig + 4;    385         my $desc_size = $max_size_kconfig + 4;
386         if (!$description_size) {                 386         if (!$description_size) {
387                 $desc_size = $max_size_descrip    387                 $desc_size = $max_size_description if ($max_size_description > $desc_size);
388         } else {                                  388         } else {
389                 $desc_size = $description_size    389                 $desc_size = $description_size if ($description_size > $desc_size);
390         }                                         390         }
391         $desc_size = $max_description_word if     391         $desc_size = $max_description_word if ($max_description_word > $desc_size);
392                                                   392 
393         $desc_size = length($desc_title) if (l    393         $desc_size = length($desc_title) if (length($desc_title) > $desc_size);
394                                                   394 
395         $max_size_status = length($notcompat)     395         $max_size_status = length($notcompat) if (length($notcompat) > $max_size_status);
396                                                   396 
397         # Ensure that the status will fit         397         # Ensure that the status will fit
398         my $min_status_size = $max_size_status    398         my $min_status_size = $max_size_status + $max_size_arch + 6;
399         $status_size = $min_status_size if ($s    399         $status_size = $min_status_size if ($status_size < $min_status_size);
400                                                   400 
401                                                   401 
402         my $cur_subsys = "";                      402         my $cur_subsys = "";
403         foreach my $name (sort {                  403         foreach my $name (sort {
404                                 ($data{$a}->{s    404                                 ($data{$a}->{subsys} cmp $data{$b}->{subsys}) or
405                                 ("\L$a" cmp "\    405                                 ("\L$a" cmp "\L$b")
406                                } keys %data) {    406                                } keys %data) {
407                                                   407 
408                 if ($cur_subsys ne $data{$name    408                 if ($cur_subsys ne $data{$name}->{subsys}) {
409                         if ($cur_subsys ne "")    409                         if ($cur_subsys ne "") {
410                                 printf "\n";      410                                 printf "\n";
411                         }                         411                         }
412                                                   412 
413                         $cur_subsys = $data{$n    413                         $cur_subsys = $data{$name}->{subsys};
414                                                   414 
415                         my $title = "Subsystem    415                         my $title = "Subsystem: $cur_subsys";
416                         print "$title\n";         416                         print "$title\n";
417                         print "=" x length($ti    417                         print "=" x length($title) . "\n\n";
418                                                   418 
419                                                   419 
420                         matrix_lines($desc_siz    420                         matrix_lines($desc_size, $status_size, 0);
421                                                   421 
422                         printf "|%-${max_size_    422                         printf "|%-${max_size_name}s", $h_name;
423                         printf "|%-${desc_size    423                         printf "|%-${desc_size}s", $desc_title;
424                                                   424 
425                         printf "|%-${status_si    425                         printf "|%-${status_size}s|\n", "Status per architecture";
426                         matrix_lines($desc_siz    426                         matrix_lines($desc_size, $status_size, 1);
427                 }                                 427                 }
428                                                   428 
429                 my %arch_table = %{$data{$name    429                 my %arch_table = %{$data{$name}->{table}};
430                 my $cur_status = "";              430                 my $cur_status = "";
431                                                   431 
432                 my (@lines, @descs);              432                 my (@lines, @descs);
433                 my $line = "";                    433                 my $line = "";
434                 foreach my $arch (sort {          434                 foreach my $arch (sort {
435                                         ($arch    435                                         ($arch_table{$b} cmp $arch_table{$a}) or
436                                         ("\L$a    436                                         ("\L$a" cmp "\L$b")
437                                        } keys     437                                        } keys %arch_table) {
438                                                   438 
439                         my $status = $arch_tab    439                         my $status = $arch_table{$arch};
440                                                   440 
441                         if ($status eq "---")     441                         if ($status eq "---") {
442                                 $status = $not    442                                 $status = $notcompat;
443                         }                         443                         }
444                                                   444 
445                         if ($status ne $cur_st    445                         if ($status ne $cur_status) {
446                                 if ($line ne "    446                                 if ($line ne "") {
447                                         push @    447                                         push @lines, $line;
448                                         $line     448                                         $line = "";
449                                 }                 449                                 }
450                                 $line = "- **"    450                                 $line = "- **" . $status . "**: " . $arch;
451                         } elsif (length($line)    451                         } elsif (length($line) + length ($arch) + 2 < $status_size) {
452                                 $line .= ", "     452                                 $line .= ", " . $arch;
453                         } else {                  453                         } else {
454                                 push @lines, $    454                                 push @lines, $line;
455                                 $line = "  " .    455                                 $line = "  " . $arch;
456                         }                         456                         }
457                         $cur_status = $status;    457                         $cur_status = $status;
458                 }                                 458                 }
459                 push @lines, $line if ($line n    459                 push @lines, $line if ($line ne "");
460                                                   460 
461                 my $description = $data{$name}    461                 my $description = $data{$name}->{description};
462                 while (length($description) >     462                 while (length($description) > $desc_size) {
463                         my $d = substr $descri    463                         my $d = substr $description, 0, $desc_size;
464                                                   464 
465                         # Ensure that it will     465                         # Ensure that it will end on a space
466                         # if it can't, it mean    466                         # if it can't, it means that the size is too small
467                         # Instead of aborting     467                         # Instead of aborting it, let's print what we have
468                         if (!($d =~ s/^(.*)\s+    468                         if (!($d =~ s/^(.*)\s+.*/$1/)) {
469                                 $d = substr $d    469                                 $d = substr $d, 0, -1;
470                                 push @descs, "    470                                 push @descs, "$d\\";
471                                 $description =    471                                 $description =~ s/^\Q$d\E//;
472                         } else {                  472                         } else {
473                                 push @descs, $    473                                 push @descs, $d;
474                                 $description =    474                                 $description =~ s/^\Q$d\E\s+//;
475                         }                         475                         }
476                 }                                 476                 }
477                 push @descs, $description;        477                 push @descs, $description;
478                                                   478 
479                 # Ensure that the full descrip    479                 # Ensure that the full description will be printed
480                 push @lines, "" while (scalar(    480                 push @lines, "" while (scalar(@lines) < 2 + scalar(@descs));
481                                                   481 
482                 my $ln = 0;                       482                 my $ln = 0;
483                 for my $line(@lines) {            483                 for my $line(@lines) {
484                         if (!$ln) {               484                         if (!$ln) {
485                                 printf "|%-${m    485                                 printf "|%-${max_size_name}s", $name;
486                                 printf "|%-${d    486                                 printf "|%-${desc_size}s", "``" . $data{$name}->{kconfig} . "``";
487                         } elsif ($ln >= 2 && s    487                         } elsif ($ln >= 2 && scalar(@descs)) {
488                                 printf "|%-${m    488                                 printf "|%-${max_size_name}s", "";
489                                 printf "|%-${d    489                                 printf "|%-${desc_size}s", shift @descs;
490                         } else {                  490                         } else {
491                                 printf "|%-${m    491                                 printf "|%-${max_size_name}s", "";
492                                 printf "|%-${d    492                                 printf "|%-${desc_size}s", "";
493                         }                         493                         }
494                                                   494 
495                         printf "|%-${status_si    495                         printf "|%-${status_size}s|\n", $line;
496                                                   496 
497                         $ln++;                    497                         $ln++;
498                 }                                 498                 }
499                 matrix_lines($desc_size, $stat    499                 matrix_lines($desc_size, $status_size, 0);
500         }                                         500         }
501 }                                                 501 }
502                                                   502 
503                                                   503 
504 #                                                 504 #
505 # Parses all feature files located at $prefix     505 # Parses all feature files located at $prefix dir
506 #                                                 506 #
507 find({wanted =>\&parse_feat, no_chdir => 1}, $    507 find({wanted =>\&parse_feat, no_chdir => 1}, $prefix);
508                                                   508 
509 print STDERR Data::Dumper->Dump([\%data], [qw(    509 print STDERR Data::Dumper->Dump([\%data], [qw(*data)]) if ($debug);
510                                                   510 
511 #                                                 511 #
512 # Handles the command                             512 # Handles the command
513 #                                                 513 #
514 if ($cmd eq "current") {                          514 if ($cmd eq "current") {
515         $arch = qx(uname -m | sed 's/x86_64/x8    515         $arch = qx(uname -m | sed 's/x86_64/x86/' | sed 's/i386/x86/');
516         $arch =~s/\s+$//;                         516         $arch =~s/\s+$//;
517 }                                                 517 }
518                                                   518 
519 if ($cmd eq "ls" or $cmd eq "list") {             519 if ($cmd eq "ls" or $cmd eq "list") {
520         if (!$arch) {                             520         if (!$arch) {
521                 $arch = qx(uname -m | sed 's/x    521                 $arch = qx(uname -m | sed 's/x86_64/x86/' | sed 's/i386/x86/');
522                 $arch =~s/\s+$//;                 522                 $arch =~s/\s+$//;
523         }                                         523         }
524                                                   524 
525         list_arch_features;                       525         list_arch_features;
526                                                   526 
527         exit;                                     527         exit;
528 }                                                 528 }
529                                                   529 
530 if ($cmd ne "validate") {                         530 if ($cmd ne "validate") {
531         if ($arch) {                              531         if ($arch) {
532                 output_arch_table;                532                 output_arch_table;
533         } elsif ($feat) {                         533         } elsif ($feat) {
534                 output_feature;                   534                 output_feature;
535         } else {                                  535         } else {
536                 output_matrix;                    536                 output_matrix;
537         }                                         537         }
538 }                                                 538 }
539                                                   539 
540 __END__                                           540 __END__
541                                                   541 
542 =head1 NAME                                       542 =head1 NAME
543                                                   543 
544 get_feat.pl - parse the Linux Feature files an    544 get_feat.pl - parse the Linux Feature files and produce a ReST book.
545                                                   545 
546 =head1 SYNOPSIS                                   546 =head1 SYNOPSIS
547                                                   547 
548 B<get_feat.pl> [--debug] [--man] [--help] [--d    548 B<get_feat.pl> [--debug] [--man] [--help] [--dir=<dir>] [--arch=<arch>]
549                [--feature=<feature>|--feat=<fe    549                [--feature=<feature>|--feat=<feature>] <COMAND> [<ARGUMENT>]
550                                                   550 
551 Where <COMMAND> can be:                           551 Where <COMMAND> can be:
552                                                   552 
553 =over 8                                           553 =over 8
554                                                   554 
555 B<current>               - output table in ReS    555 B<current>               - output table in ReST compatible ASCII format
556                            with features for t    556                            with features for this machine's architecture
557                                                   557 
558 B<rest>                  - output table(s)  in    558 B<rest>                  - output table(s)  in ReST compatible ASCII format
559                            with features in Re    559                            with features in ReST markup language. The output
560                            is affected by --ar    560                            is affected by --arch or --feat/--feature flags.
561                                                   561 
562 B<validate>              - validate the conten    562 B<validate>              - validate the contents of the files under
563                            Documentation/featu    563                            Documentation/features.
564                                                   564 
565 B<ls> or B<list>         - list features for t    565 B<ls> or B<list>         - list features for this machine's architecture,
566                            using an easier to     566                            using an easier to parse format.
567                            The output is affec    567                            The output is affected by --arch flag.
568                                                   568 
569 =back                                             569 =back
570                                                   570 
571 =head1 OPTIONS                                    571 =head1 OPTIONS
572                                                   572 
573 =over 8                                           573 =over 8
574                                                   574 
575 =item B<--arch>                                   575 =item B<--arch>
576                                                   576 
577 Output features for an specific architecture,     577 Output features for an specific architecture, optionally filtering for
578 a single specific feature.                        578 a single specific feature.
579                                                   579 
580 =item B<--feat> or B<--feature>                   580 =item B<--feat> or B<--feature>
581                                                   581 
582 Output features for a single specific feature.    582 Output features for a single specific feature.
583                                                   583 
584 =item B<--dir>                                    584 =item B<--dir>
585                                                   585 
586 Changes the location of the Feature files. By     586 Changes the location of the Feature files. By default, it uses
587 the Documentation/features directory.             587 the Documentation/features directory.
588                                                   588 
589 =item B<--enable-fname>                           589 =item B<--enable-fname>
590                                                   590 
591 Prints the file name of the feature files. Thi    591 Prints the file name of the feature files. This can be used in order to
592 track dependencies during documentation build.    592 track dependencies during documentation build.
593                                                   593 
594 =item B<--debug>                                  594 =item B<--debug>
595                                                   595 
596 Put the script in verbose mode, useful for deb    596 Put the script in verbose mode, useful for debugging. Can be called multiple
597 times, to increase verbosity.                     597 times, to increase verbosity.
598                                                   598 
599 =item B<--help>                                   599 =item B<--help>
600                                                   600 
601 Prints a brief help message and exits.            601 Prints a brief help message and exits.
602                                                   602 
603 =item B<--man>                                    603 =item B<--man>
604                                                   604 
605 Prints the manual page and exits.                 605 Prints the manual page and exits.
606                                                   606 
607 =back                                             607 =back
608                                                   608 
609 =head1 DESCRIPTION                                609 =head1 DESCRIPTION
610                                                   610 
611 Parse the Linux feature files from Documentati    611 Parse the Linux feature files from Documentation/features (by default),
612 optionally producing results at ReST format.      612 optionally producing results at ReST format.
613                                                   613 
614 It supports output data per architecture, per     614 It supports output data per architecture, per feature or a
615 feature x arch matrix.                            615 feature x arch matrix.
616                                                   616 
617 When used with B<rest> command, it will use ei    617 When used with B<rest> command, it will use either one of the tree formats:
618                                                   618 
619 If neither B<--arch> or B<--feature> arguments    619 If neither B<--arch> or B<--feature> arguments are used, it will output a
620 matrix with features per architecture.            620 matrix with features per architecture.
621                                                   621 
622 If B<--arch> argument is used, it will output     622 If B<--arch> argument is used, it will output the features availability for
623 a given architecture.                             623 a given architecture.
624                                                   624 
625 If B<--feat> argument is used, it will output     625 If B<--feat> argument is used, it will output the content of the feature
626 file using ReStructured Text markup.              626 file using ReStructured Text markup.
627                                                   627 
628 =head1 BUGS                                       628 =head1 BUGS
629                                                   629 
630 Report bugs to Mauro Carvalho Chehab <mchehab+s    630 Report bugs to Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
631                                                   631 
632 =head1 COPYRIGHT                                  632 =head1 COPYRIGHT
633                                                   633 
634 Copyright (c) 2019 by Mauro Carvalho Chehab <mc    634 Copyright (c) 2019 by Mauro Carvalho Chehab <mchehab+samsung@kernel.org>.
635                                                   635 
636 License GPLv2: GNU GPL version 2 <http://gnu.o    636 License GPLv2: GNU GPL version 2 <http://gnu.org/licenses/gpl.html>.
637                                                   637 
638 This is free software: you are free to change     638 This is free software: you are free to change and redistribute it.
639 There is NO WARRANTY, to the extent permitted     639 There is NO WARRANTY, to the extent permitted by law.
640                                                   640 
641 =cut                                              641 =cut
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php