From 1278a2f259bc8e4436c89c19f6f2e9294a906a5b Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Tue, 28 Aug 2012 22:50:46 +0200 Subject: [PATCH] bin/print-constant.pl: Add, print values of C constants. --- bin/print-constant.pl | 258 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100755 bin/print-constant.pl diff --git a/bin/print-constant.pl b/bin/print-constant.pl new file mode 100755 index 0000000..f0205db --- /dev/null +++ b/bin/print-constant.pl @@ -0,0 +1,258 @@ +#!/usr/bin/perl + +# Print values of C constants. + +# Copyright (C) 2012 Simon Ruderich +# +# 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 . + + +use strict; +use warnings; + +use Getopt::Long (); +use File::Temp (); + +our $VERSION = '0.01'; + + +my $option_help = 0; +my $option_version = 0; +my @option_include = (); +my $option_pathconf = undef; +my $option_quiet = 0; +my $option_sysconf = 0; +my $option_type = 'd'; +if (not Getopt::Long::GetOptions( + 'help|h|?' => \$option_help, + 'version|v' => \$option_version, + # + 'include|i=s' => \@option_include, + 'pathconf|p=s' => \$option_pathconf, + 'quiet|q' => \$option_quiet, + 'sysconf|s' => \$option_sysconf, + 'type|t=s' => \$option_type, + )) { + require Pod::Usage; + Pod::Usage::pod2usage(2); +} +if ($option_help) { + require Pod::Usage; + Pod::Usage::pod2usage(1); +} +if ($option_version) { + print <. +EOF + exit 0; +} + +# We need the constant name as argument. +if (scalar @ARGV != 1) { + require Pod::Usage; + Pod::Usage::pod2usage(2); +} + + +my $constant = $ARGV[0]; +# Check for non-constant name inputs - also prevents running arbitrary code on +# the machine. +if (not $constant =~ /^[a-zA-Z0-9_]+$/) { + print STDERR "Invalid constant name: '$constant'!\n"; + exit 1; +} + +# Some sanity checks. +if (not $option_type =~ /^[a-zA-Z]+$/) { + print STDERR "Invalid type: '$option_type'!\n"; + exit 1; +} +if ($option_sysconf and defined $option_pathconf) { + print STDERR "--sysconf and --pathconf can't be used together!\n"; + exit 1; +} +foreach my $include (@option_include) { + if (not $include =~ m{^[a-zA-Z0-9./_-]+$}) { + print STDERR "Invalid include: '$include'!\n"; + exit 1; + } +} + +my $constant_display = $constant; +# Pass the constant to sysconf()/pathconf() instead of using it directly. +if ($option_sysconf) { + $constant = "sysconf($constant)"; + $constant_display = $constant; +} elsif (defined $option_pathconf) { + $constant_display = "pathconf(\"$option_pathconf\", $constant)"; + # Use the current directory to prevent escape problems for the path, see + # below. + $constant = "pathconf(\".\", $constant)"; +} + + +# Use "limits.h" and "unistd.h" as default include - but only if the user +# specified no other includes, in case it conflicts with "limits.h". +if (scalar @option_include == 0) { + push @option_include, 'limits.h'; + push @option_include, 'unistd.h'; +} + + +# Temporary directory where the following C program which prints the constant +# is built. +my $tempdir = File::Temp::tempdir(CLEANUP => 1) or die $!; +chdir $tempdir or die $!; + +# Write the C file which prints the constant value. +my $c_template = <<'EOF'; +#include +#include +%s + +int main(int argc, char **argv) { + printf("%s\n", %s); + + return EXIT_SUCCESS; +} +EOF +open my $fh, '>', 'constant.c' or die $!; +printf $fh $c_template, + join("\n", map { "#include <$_>" } @option_include), + '%' . $option_type, + $constant; +close $fh or die $!; + +# Compile the constant C file. +my @args = ('cc', '-o', 'constant', 'constant.c'); +if (system(@args) != 0) { + print STDERR "Compilation failure (message above).\n"; + + chdir; # see below + exit 1; +} + +# pathconf() needs a path, we use the current directory - therefore we have to +# chdir to the given path. This prevents escape problems with the path. +if (defined $option_pathconf) { + chdir $option_pathconf; +} + +my $value = `$tempdir/constant`; + +if ($option_quiet) { + print $value; +} else { + print "$constant_display: $value"; +} + +# Change the working directory or File::Temp can't remove our temporary +# directory. +chdir; + + +__END__ + +=head1 NAME + +print-constant - print values of C constants + +=head1 SYNOPSIS + +B [I] I + +=head1 DESCRIPTION + +print-constant prints the values of C constants. Useful to find out certain +system constants without having to write a small C program to print them. + +=head1 OPTIONS + +=over 8 + +=item B<-i> I, B<--include> I + +Use I as include file. Adds C<#include EincludeE> to the +beginning of the C file used to print the constant. By default C and +C are used as headers. If this option is specified I default +includes are used. Can be specified multiple times. + +=item B<-p> I, B<--pathconf> I + +Pass the constant to pathconf(3) and print the result. I is the first +argument for pathconf(3). Conflicts with B<--sysconf>. + +=item B<-q>, B<--quiet> + +Display only the constant's value. + +=item B<-s>, B<--sysconf> + +Pass the constant to sysconf(3) and print the result. Conflicts with +B<--pathconf>. + +=item B<-t> I, B<--type> I + +Use I as type of the constant, used in printf(3). By default C is +used. + +=item B<-h>, B<-?>, B<--help> + +Print available options. + +=item B<-v>, B<--version> + +Print version number and license. + +=back + +=head1 AUTHOR + +Simon Ruderich, Esimon@ruderich.orgE + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2012 by Simon Ruderich + +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 . + +=head1 SEE ALSO + +L, L + +=cut -- 2.45.2