General.pm 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. # autoconf -- create `configure' using m4 macros
  2. # Copyright (C) 2001-2004, 2006-2007, 2009-2012 Free Software
  3. # Foundation, Inc.
  4. # This program is free software: you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation, either version 3 of the License, or
  7. # (at your option) any later version.
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. # You should have received a copy of the GNU General Public License
  13. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. package Autom4te::General;
  15. =head1 NAME
  16. Autom4te::General - general support functions for Autoconf
  17. =head1 SYNOPSIS
  18. use Autom4te::General
  19. =head1 DESCRIPTION
  20. This perl module provides various general purpose support functions
  21. used in several executables of the Autoconf package.
  22. =cut
  23. use 5.006;
  24. use Exporter;
  25. use Autom4te::ChannelDefs;
  26. use Autom4te::Channels;
  27. use Autom4te::Getopt ();
  28. use File::Basename;
  29. use File::Path ();
  30. use File::stat;
  31. use IO::File;
  32. use Carp;
  33. use strict;
  34. use vars qw (@ISA @EXPORT);
  35. @ISA = qw (Exporter);
  36. # Variables we define and export.
  37. my @export_vars =
  38. qw ($debug $force $help $me $tmp $verbose $version);
  39. # Functions we define and export.
  40. my @export_subs =
  41. qw (&debug
  42. &getopt &shell_quote &mktmpdir
  43. &uniq);
  44. # Functions we forward (coming from modules we use).
  45. my @export_forward_subs =
  46. qw (&basename &dirname &fileparse);
  47. @EXPORT = (@export_vars, @export_subs, @export_forward_subs);
  48. # Variable we share with the main package. Be sure to have a single
  49. # copy of them: using `my' together with multiple inclusion of this
  50. # package would introduce several copies.
  51. =head2 Global Variables
  52. =over 4
  53. =item C<$debug>
  54. Set this variable to 1 if debug messages should be enabled. Debug
  55. messages are meant for developers only, or when tracking down an
  56. incorrect execution.
  57. =cut
  58. use vars qw ($debug);
  59. $debug = 0;
  60. =item C<$force>
  61. Set this variable to 1 to recreate all the files, or to consider all
  62. the output files are obsolete.
  63. =cut
  64. use vars qw ($force);
  65. $force = undef;
  66. =item C<$help>
  67. Set to the help message associated with the option C<--help>.
  68. =cut
  69. use vars qw ($help);
  70. $help = undef;
  71. =item C<$me>
  72. The name of this application, for diagnostic messages.
  73. =cut
  74. use vars qw ($me);
  75. $me = basename ($0);
  76. =item C<$tmp>
  77. The name of the temporary directory created by C<mktmpdir>. Left
  78. C<undef> otherwise.
  79. =cut
  80. # Our tmp dir.
  81. use vars qw ($tmp);
  82. $tmp = undef;
  83. =item C<$verbose>
  84. Enable verbosity messages. These messages are meant for ordinary
  85. users, and typically make explicit the steps being performed.
  86. =cut
  87. use vars qw ($verbose);
  88. $verbose = 0;
  89. =item C<$version>
  90. Set to the version message associated to the option C<--version>.
  91. =cut
  92. use vars qw ($version);
  93. $version = undef;
  94. =back
  95. =cut
  96. ## ----- ##
  97. ## END. ##
  98. ## ----- ##
  99. =head2 Functions
  100. =over 4
  101. =item C<END>
  102. Filter Perl's exit codes, delete any temporary directory (unless
  103. C<$debug>), and exit nonzero whenever closing C<STDOUT> fails.
  104. =cut
  105. # END
  106. # ---
  107. sub END
  108. {
  109. # $? contains the exit status we will return.
  110. # It was set using one of the following ways:
  111. #
  112. # 1) normal termination
  113. # this sets $? = 0
  114. # 2) calling `exit (n)'
  115. # this sets $? = n
  116. # 3) calling die or friends (croak, confess...):
  117. # a) when $! is non-0
  118. # this set $? = $!
  119. # b) when $! is 0 but $? is not
  120. # this sets $? = ($? >> 8) (i.e., the exit code of the
  121. # last program executed)
  122. # c) when both $! and $? are 0
  123. # this sets $? = 255
  124. #
  125. # Cases 1), 2), and 3b) are fine, but we prefer $? = 1 for 3a) and 3c).
  126. my $status = $?;
  127. $status = 1 if ($! && $! == $?) || $? == 255;
  128. # (Note that we cannot safely distinguish calls to `exit (n)'
  129. # from calls to die when `$! = n'. It's not big deal because
  130. # we only call `exit (0)' or `exit (1)'.)
  131. if (!$debug && defined $tmp && -d $tmp)
  132. {
  133. local $SIG{__WARN__} = sub { $status = 1; warn $_[0] };
  134. File::Path::rmtree $tmp;
  135. }
  136. # This is required if the code might send any output to stdout
  137. # E.g., even --version or --help. So it's best to do it unconditionally.
  138. if (! close STDOUT)
  139. {
  140. print STDERR "$me: closing standard output: $!\n";
  141. $? = 1;
  142. return;
  143. }
  144. $? = $status;
  145. }
  146. ## ----------- ##
  147. ## Functions. ##
  148. ## ----------- ##
  149. =item C<debug (@message)>
  150. If the debug mode is enabled (C<$debug> and C<$verbose>), report the
  151. C<@message> on C<STDERR>, signed with the name of the program.
  152. =cut
  153. # &debug(@MESSAGE)
  154. # ----------------
  155. # Messages displayed only if $DEBUG and $VERBOSE.
  156. sub debug (@)
  157. {
  158. print STDERR "$me: ", @_, "\n"
  159. if $verbose && $debug;
  160. }
  161. =item C<getopt (%option)>
  162. Wrapper around C<Autom4te::Getopt::parse_options>. In addition to
  163. the user C<option>s, support C<-h>/C<--help>, C<-V>/C<--version>,
  164. C<-v>/C<--verbose>, C<-d>/C<--debug>, C<-f>/C<--force>. Conform to
  165. the GNU Coding Standards for error messages.
  166. =cut
  167. # getopt (%OPTION)
  168. # ----------------
  169. # Handle the %OPTION, plus all the common options.
  170. sub getopt (%)
  171. {
  172. my (%option) = @_;
  173. %option = ("h|help" => sub { print $help; exit 0 },
  174. "V|version" => sub { print $version; exit 0 },
  175. "v|verbose" => sub { ++$verbose },
  176. "d|debug" => sub { ++$debug },
  177. 'f|force' => \$force,
  178. # User options last, so that they have precedence.
  179. %option);
  180. Autom4te::Getopt::parse_options (%option);
  181. setup_channel 'note', silent => !$verbose;
  182. setup_channel 'verb', silent => !$verbose;
  183. }
  184. =item C<shell_quote ($file_name)>
  185. Quote C<$file_name> for the shell.
  186. =cut
  187. # $FILE_NAME
  188. # shell_quote ($FILE_NAME)
  189. # ------------------------
  190. # If the string $S is a well-behaved file name, simply return it.
  191. # If it contains white space, quotes, etc., quote it, and return
  192. # the new string.
  193. sub shell_quote($)
  194. {
  195. my ($s) = @_;
  196. if ($s =~ m![^\w+/.,-]!)
  197. {
  198. # Convert each single quote to '\''
  199. $s =~ s/\'/\'\\\'\'/g;
  200. # Then single quote the string.
  201. $s = "'$s'";
  202. }
  203. return $s;
  204. }
  205. =item C<mktmpdir ($signature)>
  206. Create a temporary directory which name is based on C<$signature>.
  207. Store its name in C<$tmp>. C<END> is in charge of removing it, unless
  208. C<$debug>.
  209. =cut
  210. # mktmpdir ($SIGNATURE)
  211. # ---------------------
  212. sub mktmpdir ($)
  213. {
  214. my ($signature) = @_;
  215. my $TMPDIR = $ENV{'TMPDIR'} || '/tmp';
  216. my $quoted_tmpdir = shell_quote ($TMPDIR);
  217. # If mktemp supports dirs, use it.
  218. $tmp = `(umask 077 &&
  219. mktemp -d $quoted_tmpdir/"${signature}XXXXXX") 2>/dev/null`;
  220. chomp $tmp;
  221. if (!$tmp || ! -d $tmp)
  222. {
  223. $tmp = "$TMPDIR/$signature" . int (rand 10000) . ".$$";
  224. mkdir $tmp, 0700
  225. or croak "$me: cannot create $tmp: $!\n";
  226. }
  227. print STDERR "$me:$$: working in $tmp\n"
  228. if $debug;
  229. }
  230. =item C<uniq (@list)>
  231. Return C<@list> with no duplicates, keeping only the first
  232. occurrences.
  233. =cut
  234. # @RES
  235. # uniq (@LIST)
  236. # ------------
  237. sub uniq (@)
  238. {
  239. my @res = ();
  240. my %seen = ();
  241. foreach my $item (@_)
  242. {
  243. if (! exists $seen{$item})
  244. {
  245. $seen{$item} = 1;
  246. push (@res, $item);
  247. }
  248. }
  249. return wantarray ? @res : "@res";
  250. }
  251. =item C<handle_exec_errors ($command)>
  252. Display an error message for C<$command>, based on the content of
  253. C<$?> and C<$!>.
  254. =cut
  255. # handle_exec_errors ($COMMAND)
  256. # -----------------------------
  257. sub handle_exec_errors ($)
  258. {
  259. my ($command) = @_;
  260. $command = (split (' ', $command))[0];
  261. if ($!)
  262. {
  263. error "failed to run $command: $!";
  264. }
  265. else
  266. {
  267. use POSIX qw (WIFEXITED WEXITSTATUS WIFSIGNALED WTERMSIG);
  268. if (WIFEXITED ($?))
  269. {
  270. my $status = WEXITSTATUS ($?);
  271. # WIFEXITED and WEXITSTATUS can alter $!, reset it so that
  272. # error() actually propagates the command's exit status, not $!.
  273. $! = 0;
  274. error "$command failed with exit status: $status";
  275. }
  276. elsif (WIFSIGNALED ($?))
  277. {
  278. my $signal = WTERMSIG ($?);
  279. # In this case we prefer to exit with status 1.
  280. $! = 1;
  281. error "$command terminated by signal: $signal";
  282. }
  283. else
  284. {
  285. error "$command exited abnormally";
  286. }
  287. }
  288. }
  289. =back
  290. =head1 SEE ALSO
  291. L<Autom4te::XFile>
  292. =head1 HISTORY
  293. Written by Alexandre Duret-Lutz E<lt>F<adl@gnu.org>E<gt> and Akim
  294. Demaille E<lt>F<akim@freefriends.org>E<gt>.
  295. =cut
  296. 1; # for require
  297. ### Setup "GNU" style for perl-mode and cperl-mode.
  298. ## Local Variables:
  299. ## perl-indent-level: 2
  300. ## perl-continued-statement-offset: 2
  301. ## perl-continued-brace-offset: 0
  302. ## perl-brace-offset: 0
  303. ## perl-brace-imaginary-offset: 0
  304. ## perl-label-offset: -2
  305. ## cperl-indent-level: 2
  306. ## cperl-brace-offset: 0
  307. ## cperl-continued-brace-offset: 0
  308. ## cperl-label-offset: -2
  309. ## cperl-extra-newline-before-brace: t
  310. ## cperl-merge-trailing-else: nil
  311. ## cperl-continued-statement-offset: 2
  312. ## End: