📄 general.pm
字号:
# autoconf -- create `configure' using m4 macros# Copyright (C) 2001, 2002 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 2, 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, write to the Free Software# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA# 02111-1307, USA.package Autom4te::General;use 5.005_03;use Exporter;use File::Basename;use File::Spec;use File::stat;use IO::File;use Carp;use strict;use vars qw (@ISA @EXPORT);@ISA = qw (Exporter);# Variables we define and export.my @export_vars = qw ($debug $force $help $me $tmp $verbose $version);# Functions we define and export.my @export_subs = qw (&backname &catfile &canonpath &debug &error &file_name_is_absolute &find_configure_ac &find_file &getopt &mktmpdir &mtime &uniq &update_file &up_to_date_p &verbose &xsystem &xqx);# Functions we forward (coming from modules we use).my @export_forward_subs = qw (&basename &dirname &fileparse);@EXPORT = (@export_vars, @export_subs, @export_forward_subs);# Variable we share with the main package. Be sure to have a single# copy of them: using `my' together with multiple inclusion of this# package would introduce several copies.use vars qw ($debug);$debug = 0;# Recreate all the files, or consider all the output files are obsolete.use vars qw ($force);$force = undef;use vars qw ($help);$help = undef;use vars qw ($me);$me = basename ($0);# Our tmp dir.use vars qw ($tmp);$tmp = undef;use vars qw ($verbose);$verbose = 0;use vars qw ($version);$version = undef;## ------------ #### Prototypes. #### ------------ ##sub verbose (@);## ----- #### END. #### ----- ### END# ---# Exit nonzero whenever closing STDOUT fails.# Ideally we should `exit ($? >> 8)', unfortunately, for some reason# I don't understand, whenever we `exit (1)' somewhere in the code,# we arrive here with `$? = 29'. I suspect some low level END routine# might be responsible. In this case, be sure to exit 1, not 29.sub END{ my $exit_status = $? ? 1 : 0; use POSIX qw (_exit); if (!$debug && defined $tmp && -d $tmp) { if (<$tmp/*>) { unlink <$tmp/*> or carp ("$me: cannot empty $tmp: $!\n"), _exit (1); } rmdir $tmp or carp ("$me: cannot remove $tmp: $!\n"), _exit (1); } # This is required if the code might send any output to stdout # E.g., even --version or --help. So it's best to do it unconditionally. close STDOUT or (carp "$me: closing standard output: $!\n"), _exit (1); _exit ($exit_status);}## ----------- #### Functions. #### ----------- ### $BACKPATH# &backname ($REL-DIR)# --------------------# If I `cd $REL-DIR', then to come back, I should `cd $BACKPATH'.# For instance `src/foo' => `../..'.# Works with non strictly increasing paths, i.e., `src/../lib' => `..'.sub backname ($){ my ($file) = @_; my $underscore = $_; my @res; foreach (split (/\//, $file)) { next if $_ eq '.' || $_ eq ''; if ($_ eq '..') { pop @res; } else { push (@res, '..'); } } $_ = $underscore; return canonpath (catfile (@res))}# $FILE# &catfile (@COMPONENT)# ---------------------sub catfile (@){ my (@component) = @_; return File::Spec->catfile (@component);}# $FILE# &canonpath ($FILE)# ------------------sub canonpath ($){ my ($file) = @_; return File::Spec->canonpath ($file);}# &debug(@MESSAGE)# ----------------# Messages displayed only if $DEBUG and $VERBOSE.sub debug (@){ print STDERR "$me: ", @_, "\n" if $verbose && $debug;}# &error (@MESSAGE)# -----------------# Same as die or confess, depending on $debug.sub error (@){ if ($debug) { confess "$me: ", @_, "\n"; } else { die "$me: ", @_, "\n"; }}# $BOOLEAN# &file_name_is_absolute ($FILE)# ------------------------------sub file_name_is_absolute ($){ my ($file) = @_; return File::Spec->file_name_is_absolute ($file);}# $CONFIGURE_AC# &find_configure_ac ([$DIRECTORY = `.'])# ---------------------------------------sub find_configure_ac (;$){ my ($directory) = @_; $directory ||= '.'; my $configure_ac = canonpath (catfile ($directory, 'configure.ac')); my $configure_in = canonpath (catfile ($directory, 'configure.in')); if (-f $configure_ac) { if (-f $configure_in) { carp "$me: warning: `$configure_ac' and `$configure_in' both present.\n"; carp "$me: warning: proceeding with `$configure_ac'.\n"; } return $configure_ac; } elsif (-f $configure_in) { return $configure_in; } return;}# $FILENAME# find_file ($FILENAME, @INCLUDE)# -------------------------------# We match exactly the behavior of GNU M4: first look in the current# directory (which includes the case of absolute file names), and, if# the file is not absolute, just fail. Otherwise, look in @INCLUDE.## If the file is flagged as optional (ends with `?'), then return undef# if absent.sub find_file ($@){ my ($filename, @include) = @_; my $optional = 0; $optional = 1 if $filename =~ s/\?$//; return canonpath ($filename) if -e $filename; if (file_name_is_absolute ($filename)) { error "no such file or directory: $filename" unless $optional; return undef; } foreach my $path (@include) { return canonpath (catfile ($path, $filename)) if -e catfile ($path, $filename); } error "no such file or directory: $filename" unless $optional; return undef;}# getopt (%OPTION)# ----------------# Handle the %OPTION, plus all the common options.# Work around Getopt bugs wrt `-'.sub getopt (%){ my (%option) = @_; use Getopt::Long; # F*k. Getopt seems bogus and dies when given `-' with `bundling'. # If fixed some day, use this: '' => sub { push @ARGV, "-" } my $stdin = grep /^-$/, @ARGV; @ARGV = grep !/^-$/, @ARGV; %option = ("h|help" => sub { print $help; exit 0 }, "V|version" => sub { print $version; exit 0 }, "v|verbose" => \$verbose, "d|debug" => \$debug, 'f|force' => \$force, # User options last, so that they have precedence. %option); Getopt::Long::Configure ("bundling", "pass_through"); GetOptions (%option) or exit 1; foreach (grep { /^-./ } @ARGV) { print STDERR "$0: unrecognized option `$_'\n"; print STDERR "Try `$0 --help' for more information.\n"; exit (1); } push @ARGV, '-' if $stdin;}# mktmpdir ($SIGNATURE)# ---------------------# Create a temporary directory which name is based on $SIGNATURE.sub mktmpdir ($){ my ($signature) = @_; my $TMPDIR = $ENV{'TMPDIR'} || '/tmp'; # If mktemp supports dirs, use it. $tmp = `(umask 077 && mktemp -d -q "$TMPDIR/${signature}XXXXXX") 2>/dev/null`; chomp $tmp; if (!$tmp || ! -d $tmp) { $tmp = "$TMPDIR/$signature" . int (rand 10000) . ".$$"; mkdir $tmp, 0700 or croak "$me: cannot create $tmp: $!\n"; } print STDERR "$me:$$: working in $tmp\n" if $debug;}# $MTIME# MTIME ($FILE)# -------------# Return the mtime of $FILE. Missing files, or `-' standing for STDIN# or STDOUT are ``obsolete'', i.e., as old as possible.sub mtime ($){ my ($file) = @_; return 0 if $file eq '-' || ! -f $file; my $stat = stat ($file) or croak "$me: cannot stat $file: $!\n"; return $stat->mtime;}# @RES# uniq (@LIST)# ------------# Return LIST with no duplicates.sub uniq (@){ my @res = (); my %seen = (); foreach my $item (@_) { if (! exists $seen{$item}) { $seen{$item} = 1; push (@res, $item); } } return wantarray ? @res : "@res";}# $BOOLEAN# &up_to_date_p ($FILE, @DEPS)# ----------------------------# Is $FILE more recent than @DEPS?sub up_to_date_p ($@){ my ($file, @dep) = @_; my $mtime = mtime ($file); foreach my $dep (@dep) { if ($mtime < mtime ($dep)) { debug "up_to_date ($file): outdated: $dep"; return 0; } } debug "up_to_date ($file): up to date"; return 1;}# &update_file ($FROM, $TO)# -------------------------# Rename $FROM as $TO, preserving $TO timestamp if it has not changed.# Recognize `$TO = -' standing for stdin. $FROM is always removed/renamed.sub update_file ($$){ my ($from, $to) = @_; my $SIMPLE_BACKUP_SUFFIX = $ENV{'SIMPLE_BACKUP_SUFFIX'} || '~'; use File::Compare; use File::Copy; if ($to eq '-') { my $in = new IO::File ("$from"); my $out = new IO::File (">-"); while ($_ = $in->getline) { print $out $_; } $in->close; unlink ($from) or error "cannot not remove $from: $!"; return; } if (-f "$to" && compare ("$from", "$to") == 0) { # File didn't change, so don't update its mod time. verbose "`$to' is unchanged"; unlink ($from) or error "cannot not remove $from: $!"; return } if (-f "$to") { # Back up and install the new one. move ("$to", "$to$SIMPLE_BACKUP_SUFFIX") or error "cannot not backup $to: $!"; move ("$from", "$to") or error "cannot not rename $from as $to: $!"; verbose "`$to' is updated"; } else { move ("$from", "$to") or error "cannot not rename $from as $to: $!"; verbose "`$to' is created"; }}# verbose(@MESSAGE)# -----------------sub verbose (@){ print STDERR "$me: ", @_, "\n" if $verbose;}# xqx ($COMMAND)# --------------# Same as `qx' (but in scalar context), but fails on errors.sub xqx ($){ use POSIX qw (WIFEXITED WEXITSTATUS); my ($command) = @_; verbose "running: $command"; my $res = `$command`; error ((split (' ', $command))[0] . " failed with exit status: " . WEXITSTATUS ($?)) if WIFEXITED ($?) && WEXITSTATUS ($?) != 0; return $res;}# xsystem ($COMMAND)# ------------------sub xsystem ($){ use POSIX qw (WEXITSTATUS); my ($command) = @_; verbose "running: $command"; (system $command) == 0 or error ((split (' ', $command))[0] . " failed with exit status: " . WEXITSTATUS ($?));}1; # for require### Setup "GNU" style for perl-mode and cperl-mode.## Local Variables:## perl-indent-level: 2## perl-continued-statement-offset: 2## perl-continued-brace-offset: 0## perl-brace-offset: 0## perl-brace-imaginary-offset: 0## perl-label-offset: -2## cperl-indent-level: 2## cperl-brace-offset: 0## cperl-continued-brace-offset: 0## cperl-label-offset: -2## cperl-extra-newline-before-brace: t## cperl-merge-trailing-else: nil## cperl-continued-statement-offset: 2## End:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -