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 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
#!/usr/bin/perl -w
# Derive #define directives from specially formatted 'case ...:' statements.
# Copyright (C) 2003-2018 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
use strict;
use Getopt::Long;
(my $VERSION = '$Revision: 1.5 $ ') =~ tr/[0-9].//cd;
(my $ME = $0) =~ s|.*/||;
END
{
# Nobody ever checks the status of print()s. That's okay, because
# if any do fail, we're guaranteed to get an indicator when we close()
# the filehandle.
#
# Close stdout now, and if there were no errors, return happy status.
# If stdout has already been closed by the script, though, do nothing.
defined fileno STDOUT
or return;
close STDOUT
and return;
# Errors closing stdout. Indicate that, and hope stderr is OK.
warn "$ME: closing standard output: $!\n";
# Don't be so arrogant as to assume that we're the first END handler
# defined, and thus the last one invoked. There may be others yet
# to come. $? will be passed on to them, and to the final _exit().
#
# If it isn't already an error, make it one (and if it _is_ an error,
# preserve the value: it might be important).
$? ||= 1;
}
sub usage ($)
{
my ($exit_code) = @_;
my $STREAM = ($exit_code == 0 ? *STDOUT : *STDERR);
if ($exit_code != 0)
{
print $STREAM "Try '$ME --help' for more information.\n";
}
else
{
print $STREAM <<EOF;
Usage: $ME [OPTIONS] FILE
FIXME: describe
OPTIONS:
There are two modes of operation, the default, which is to emit
#define directives derived from specially formatted 'case' statements,
and that with --local, which is to emit a static inline function
mapping S_MAGIC_* values to 1, 0, -1, corresponding to known-local,
known-remote/distributed/network and unknown, respectively.
--local emit an is_local_fs_type function
--help display this help and exit
--version output version information and exit
EOF
}
exit $exit_code;
}
{
# The default is to print S_MAGIC_* definitions.
my $emit_magic = 1;
GetOptions
(
local => sub { $emit_magic = 0 },
help => sub { usage 0 },
version => sub { print "$ME version $VERSION\n"; exit },
) or usage 1;
my $fail = 0;
@ARGV < 1
and (warn "$ME: missing FILE arguments\n"), $fail = 1;
1 < @ARGV
and (warn "$ME: too many arguments\n"), $fail = 1;
$fail
and usage 1;
my $file = $ARGV[0];
open FH, $file
or die "$ME: can't open '$file' for reading: $!\n";
# For each line like this:
# case S_MAGIC_ROMFS: /* 0x7275 */
# emit one like this:
# # define S_MAGIC_ROMFS 0x7275
# Fail if there is a 'case S_MAGIC_.*' line without
# a properly formed comment.
my $map_comment = <<EOF;
/* Map each S_MAGIC_* value to 1, 0 or -1.
1 if it is known to be a remote file system type,
0 if it is known to be a local file system type, or -1 otherwise. */
EOF
my $magic_comment = <<EOF;
/* Define the magic numbers as given by statfs(2).
Please send additions to bug-coreutils\@gnu.org and meskes\@debian.org.
This file is generated automatically from $file. */
EOF
print $emit_magic ? $magic_comment : $map_comment;
$emit_magic
and print "\n#if defined __linux__\n";
$emit_magic
or print "static inline int\n"
. "is_local_fs_type (unsigned long int magic)\n"
. "{\n switch (magic)\n {\n";
while (defined (my $line = <FH>))
{
$line =~ /^[ \t]+case S_MAGIC_/
or next;
$line =~
m!^[ \t]+case (S_MAGIC_\w+): /\* (0x[0-9A-Fa-f]+) (local|remote) \*/!
or (warn "$ME:$file:$.: malformed case S_MAGIC_... line"),
$fail = 1, next;
my $name = $1;
my $magic = $2;
my $local = $3 eq 'local' ? 1 : 0;
print $emit_magic
? "# define $name $magic\n"
: " case $name: return $local;\n";
}
$emit_magic
and print <<\EOF;
#elif defined __GNU__
# include <hurd/hurd_types.h>
#endif
EOF
$emit_magic
or printf " default: return -1;\n }\n}\n";
close FH;
exit $fail;
}
|