mirrored from git://git.sv.gnu.org/gnulib.git
-
Notifications
You must be signed in to change notification settings - Fork 112
/
gnulib-tool.sh
executable file
·7793 lines (7486 loc) · 278 KB
/
gnulib-tool.sh
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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#! /bin/sh
#
# Copyright (C) 2002-2024 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/>.
#
# This program is meant for authors or maintainers which want to import
# modules from gnulib into their packages.
# CODING STYLE for this file:
# * Indentation: Indent by 2 spaces. Indent case clauses by 2 spaces as well.
# * Shell variable references: Use double-quote around shell variable
# references always (except when word splitting is explicitly desired),
# even when you know the double-quote are not needed. This style tends to
# avoid undesired word splitting caused by omitted double-quotes (the
# number one mistake in shell scripts).
# When the referenced variable can only have a finite number of possible
# values and these values are all simple words (e.g. true and false), it's
# OK to omit the double-quotes.
# * Backquotes:
# - Use backquotes like in `command`, not $(command).
# - Don't use `command` inside double-quotes. Instead assign the result of
# `command` to a variable, and use the value of the variable afterwards.
# * Functions:
# - All functions that don't emulate a program or shell built-in have a name
# that starts with 'func_'.
# - Document the implicit and explicit arguments of all functions, as well
# as their output variables and side effects.
# * Use test condition instead of [ condition ].
# * Minimize the use of eval; when you need it, make sure the string to be
# evaluated has a very simple syntactic structure.
progname=$0
package=gnulib
nl='
'
IFS=" "" $nl"
# You can set AUTOCONFPATH to empty if autoconf ≥ 2.64 is already in your PATH.
AUTOCONFPATH=
#case $USER in
# bruno )
# AUTOCONFBINDIR=/arch/x86-linux/gnu-inst-autoconf/2.64/bin
# AUTOCONFPATH="eval env PATH=${AUTOCONFBINDIR}:\$PATH "
# ;;
#esac
# You can set AUTOMAKEPATH to empty if automake ≥ 1.14 is already in your PATH.
AUTOMAKEPATH=
# You can set GETTEXTPATH to empty if autopoint ≥ 0.15 is already in your PATH.
GETTEXTPATH=
# You can set LIBTOOLPATH to empty if libtoolize 2.x is already in your PATH.
LIBTOOLPATH=
# If you didn't set AUTOCONFPATH and AUTOMAKEPATH, you can also set the
# variables AUTOCONF, AUTOHEADER, ACLOCAL, AUTOMAKE, AUTORECONF individually.
if test -z "${AUTOCONF}" || test -n "${AUTOCONFPATH}"; then
AUTOCONF="${AUTOCONFPATH}autoconf"
fi
if test -z "${AUTOHEADER}" || test -n "${AUTOCONFPATH}"; then
AUTOHEADER="${AUTOCONFPATH}autoheader"
fi
if test -z "${ACLOCAL}" || test -n "${AUTOMAKEPATH}"; then
ACLOCAL="${AUTOMAKEPATH}aclocal"
fi
if test -z "${AUTOMAKE}" || test -n "${AUTOMAKEPATH}"; then
AUTOMAKE="${AUTOMAKEPATH}automake"
fi
if test -z "${AUTORECONF}" || test -n "${AUTOCONFPATH}"; then
AUTORECONF="${AUTOCONFPATH}autoreconf"
fi
# If you didn't set GETTEXTPATH, you can also set the variable AUTOPOINT.
if test -z "${AUTOPOINT}" || test -n "${GETTEXTPATH}"; then
AUTOPOINT="${GETTEXTPATH}autopoint"
fi
# If you didn't set LIBTOOLPATH, you can also set the variable LIBTOOLIZE.
if test -z "${LIBTOOLIZE}" || test -n "${LIBTOOLPATH}"; then
LIBTOOLIZE="${LIBTOOLPATH}libtoolize"
fi
# You can set MAKE.
if test -z "${MAKE}"; then
MAKE=make
fi
# When using GNU sed, turn off as many GNU extensions as possible,
# to minimize the risk of accidentally using non-portable features.
# However, do this only for gnulib-tool itself, not for the code that
# gnulib-tool generates, since we don't want "sed --posix" to leak
# into makefiles. And do it only for sed versions 4.2 or newer,
# because "sed --posix" is buggy in GNU sed 4.1.5, see
# <https://lists.gnu.org/r/bug-gnulib/2009-02/msg00225.html>.
if (alias) > /dev/null 2>&1 \
&& echo | sed --posix -e d >/dev/null 2>&1 \
&& case `sed --version | sed -e 's/^[^0-9]*//' -e 1q` in \
[1-3]* | 4.[01]*) false;; \
*) true;; \
esac \
; then
# Define sed as an alias.
# It is not always possible to use aliases. Aliases are guaranteed to work
# if the executing shell is bash and either it is invoked as /bin/sh or
# is a version >= 2.0, supporting shopt. This is the common case.
# Two other approaches (use of a variable $sed or of a function func_sed
# instead of an alias) require massive, fragile code changes.
# An other approach (use of function sed) requires `which sed` - but
# 'which' is hard to emulate, due to missing "test -x" on some platforms.
if test -n "$BASH_VERSION"; then
shopt -s expand_aliases >/dev/null 2>&1
fi
alias sed='sed --posix'
fi
# sed_noop is a sed expression that does nothing.
# An empty expression does not work with the native 'sed' on AIX 6.1.
sed_noop='s,x,x,'
# sed_comments is true or false, depending whether 'sed' supports comments.
# AIX 5.3 sed barfs over indented comments.
if echo fo | sed -e 's/f/g/
# s/o/u/
# indented comment
s/o/e/' 2>/dev/null | grep ge > /dev/null; then
sed_comments=true
else
sed_comments=false
fi
# func_usage
# outputs to stdout the --help usage message.
func_usage ()
{
echo "\
Usage: gnulib-tool --list
gnulib-tool --find filename
gnulib-tool --import [module1 ... moduleN]
gnulib-tool --add-import [module1 ... moduleN]
gnulib-tool --remove-import [module1 ... moduleN]
gnulib-tool --update
gnulib-tool --create-testdir --dir=directory [module1 ... moduleN]
gnulib-tool --create-megatestdir --dir=directory [module1 ... moduleN]
gnulib-tool --test --dir=directory [module1 ... moduleN]
gnulib-tool --megatest --dir=directory [module1 ... moduleN]
gnulib-tool --extract-description module
gnulib-tool --extract-comment module
gnulib-tool --extract-status module
gnulib-tool --extract-notice module
gnulib-tool --extract-applicability module
gnulib-tool --extract-filelist module
gnulib-tool --extract-dependencies module
gnulib-tool --extract-recursive-dependencies module
gnulib-tool --extract-autoconf-snippet module
gnulib-tool --extract-automake-snippet module
gnulib-tool --extract-include-directive module
gnulib-tool --extract-link-directive module
gnulib-tool --extract-recursive-link-directive module
gnulib-tool --extract-license module
gnulib-tool --extract-maintainer module
gnulib-tool --extract-tests-module module
gnulib-tool --copy-file file [destination]
Operation modes:
--list print the available module names
--find find the modules which contain the specified file
--import import the given modules into the current package
--add-import augment the list of imports from gnulib into the
current package, by adding the given modules;
if no modules are specified, update the current
package from the current gnulib
--remove-import reduce the list of imports from gnulib into the
current package, by removing the given modules
--update update the current package, restore files omitted
from version control
--create-testdir create a scratch package with the given modules
--create-megatestdir create a mega scratch package with the given modules
one by one and all together
--test test the combination of the given modules
(recommended to use CC=\"gcc -Wall\" here)
--megatest test the given modules one by one and all together
(recommended to use CC=\"gcc -Wall\" here)
--extract-description extract the description
--extract-comment extract the comment
--extract-status extract the status (obsolete etc.)
--extract-notice extract the notice or banner
--extract-applicability extract the applicability
--extract-filelist extract the list of files
--extract-dependencies extract the dependencies
--extract-recursive-dependencies extract the dependencies of the module
and its dependencies, recursively, all
together, but without the conditions
--extract-autoconf-snippet extract the snippet for configure.ac
--extract-automake-snippet extract the snippet for library makefile
--extract-include-directive extract the #include directive
--extract-link-directive extract the linker directive
--extract-recursive-link-directive extract the linker directive of the
module and its dependencies,
recursively, all together
--extract-license report the license terms of the source files
under lib/
--extract-maintainer report the maintainer(s) inside gnulib
--extract-tests-module report the unit test module, if it exists
--copy-file copy a file that is not part of any module
--help Show this help text.
--version Show version and authorship information.
General options:
--dir=DIRECTORY Specify the target directory.
For --import, this specifies where your
configure.ac can be found. Defaults to current
directory.
--local-dir=DIRECTORY Specify a local override directory where to look
up files before looking in gnulib's directory.
--verbose Increase verbosity. May be repeated.
--quiet Decrease verbosity. May be repeated.
Options for --import, --add/remove-import, --update:
--dry-run Only print what would have been done.
Options for --import, --add/remove-import:
--with-tests Include unit tests for the included modules.
Options for --create-[mega]testdir, --[mega]test:
--without-tests Don't include unit tests for the included modules.
Options for --import, --add/remove-import,
--create-[mega]testdir, --[mega]test:
--with-obsolete Include obsolete modules when they occur among the
dependencies. By default, dependencies to obsolete
modules are ignored.
--with-c++-tests Include even unit tests for C++ interoperability.
--without-c++-tests Exclude unit tests for C++ interoperability.
--with-longrunning-tests
Include even unit tests that are long-runners.
--without-longrunning-tests
Exclude unit tests that are long-runners.
--with-privileged-tests
Include even unit tests that require root
privileges.
--without-privileged-tests
Exclude unit tests that require root privileges.
--with-unportable-tests
Include even unit tests that fail on some platforms.
--without-unportable-tests
Exclude unit tests that fail on some platforms.
--with-all-tests Include all kinds of problematic unit tests.
--avoid=MODULE Avoid including the given MODULE. Useful if you
have code that provides equivalent functionality.
This option can be repeated.
--conditional-dependencies
Support conditional dependencies (may save configure
time and object code).
--no-conditional-dependencies
Don't use conditional dependencies.
--libtool Use libtool rules.
--no-libtool Don't use libtool rules.
Options for --import, --add/remove-import:
--lib=LIBRARY Specify the library name. Defaults to 'libgnu'.
--source-base=DIRECTORY
Directory relative to --dir where source code is
placed (default \"lib\").
--m4-base=DIRECTORY Directory relative to --dir where *.m4 macros are
placed (default \"m4\").
--po-base=DIRECTORY Directory relative to --dir where *.po files are
placed (default \"po\"). Deprecated.
--doc-base=DIRECTORY Directory relative to --dir where doc files are
placed (default \"doc\").
--tests-base=DIRECTORY
Directory relative to --dir where unit tests are
placed (default \"tests\").
--aux-dir=DIRECTORY Directory relative to --dir where auxiliary build
tools are placed (default comes from configure.ac).
--gnu-make Output for GNU Make instead of for the default
Automake
--lgpl[=2|=3orGPLv2|=3]
Abort if modules aren't available under the LGPL.
The version number of the LGPL can be specified;
the default is currently LGPLv3.
--makefile-name=NAME Name of makefile in the source-base and tests-base
directories (default \"Makefile.am\", or
\"Makefile.in\" if --gnu-make).
--tests-makefile-name=NAME
Name of makefile in the tests-base directory
(default as specified through --makefile-name).
--automake-subdir Specify that the makefile in the source-base
directory be generated in such a way that it can
be 'include'd from the toplevel Makefile.am.
--automake-subdir-tests
Likewise, but for the tests directory.
--macro-prefix=PREFIX Specify the prefix of the macros 'gl_EARLY' and
'gl_INIT'. Default is 'gl'.
--po-domain=NAME Specify the prefix of the i18n domain. Usually use
the package name. A suffix '-gnulib' is appended.
Deprecated.
--witness-c-macro=NAME Specify the C macro that is defined when the
sources in this directory are compiled or used.
--vc-files Update version control related files.
--no-vc-files Don't update version control related files
(.gitignore and/or .cvsignore).
Options for --create-[mega]testdir, --[mega]test:
--single-configure Generate a single configure file, not a separate
configure file for the tests directory.
Options for --import, --add/remove-import, --update,
--create-[mega]testdir, --[mega]test:
-s, --symbolic, --symlink Make symbolic links instead of copying files.
--local-symlink Make symbolic links instead of copying files, only
for files from the local override directory.
-h, --hardlink Make hard links instead of copying files.
--local-hardlink Make hard links instead of copying files, only
for files from the local override directory.
Options for --import, --add/remove-import, --update:
-S, --more-symlinks Deprecated; equivalent to --symlink.
-H, --more-hardlinks Deprecated; equivalent to --hardlink.
Report bugs to <[email protected]>."
}
# func_version
# outputs to stdout the --version message.
func_version ()
{
func_gnulib_dir
if test -d "$gnulib_dir"/.git \
&& (git --version) >/dev/null 2>/dev/null \
&& (date --version) >/dev/null 2>/dev/null; then
# gnulib checked out from git.
sed_extract_first_date='/^Date/{
s/^Date:[ ]*//p
q
}'
date=`cd "$gnulib_dir" && git log -n 1 --format=medium --date=iso ChangeLog | sed -n -e "$sed_extract_first_date"`
# Use GNU date to compute the time in GMT.
date=`date -d "$date" -u +"%Y-%m-%d %H:%M:%S"`
version=' '`cd "$gnulib_dir" && ./build-aux/git-version-gen /dev/null | sed -e 's/-dirty/-modified/'`
else
# gnulib copy without versioning information.
date=`sed -e 's/ .*//;q' "$gnulib_dir"/ChangeLog`
version=
fi
year=`"$gnulib_dir"/build-aux/mdate-sh "$self_abspathname" | sed -e 's,^.* ,,'`
echo "\
gnulib-tool (GNU $package $date)$version
Copyright (C) $year Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
"
printf "Written by %s, %s, and %s.\n" "Bruno Haible" "Paul Eggert" "Simon Josefsson"
}
# func_emit_copyright_notice
# outputs to stdout a header for a generated file.
func_emit_copyright_notice ()
{
sed -n -e '/Copyright/ {
p
q
}' < "$self_abspathname"
echo "#"
echo "# This file is free software; you can redistribute it and/or modify"
echo "# it under the terms of the GNU General Public License as published by"
echo "# the Free Software Foundation, either version 3 of the License, or"
echo "# (at your option) any later version."
echo "#"
echo "# This file is distributed in the hope that it will be useful,"
echo "# but WITHOUT ANY WARRANTY; without even the implied warranty of"
echo "# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the"
echo "# GNU General Public License for more details."
echo "#"
echo "# You should have received a copy of the GNU General Public License"
echo "# along with this file. If not, see <https://www.gnu.org/licenses/>."
echo "#"
echo "# As a special exception to the GNU General Public License,"
echo "# this file may be distributed as part of a program that"
echo "# contains a configuration script generated by Autoconf, under"
echo "# the same distribution terms as the rest of that program."
echo "#"
echo "# Generated by gnulib-tool."
}
# func_exit STATUS
# exits with a given status.
# This function needs to be used, rather than 'exit', when a 'trap' handler is
# in effect that refers to $?.
func_exit ()
{
(exit $1); exit $1
}
# func_fatal_error message
# outputs to stderr a fatal error message, and terminates the program.
# Input:
# - progname name of this program
func_fatal_error ()
{
echo "$progname: *** $1" 1>&2
echo "$progname: *** Stop." 1>&2
func_exit 1
}
# func_warning message
# Outputs to stderr a warning message,
func_warning ()
{
echo "gnulib-tool: warning: $1" 1>&2
}
# func_readlink SYMLINK
# outputs the target of the given symlink.
if (type readlink) > /dev/null 2>&1; then
func_readlink ()
{
# Use the readlink program from GNU coreutils.
readlink "$1"
}
else
func_readlink ()
{
# Use two sed invocations. A single sed -n -e 's,^.* -> \(.*\)$,\1,p'
# would do the wrong thing if the link target contains " -> ".
LC_ALL=C ls -l "$1" | sed -e 's, -> ,#%%#,' | sed -n -e 's,^.*#%%#\(.*\)$,\1,p'
}
fi
# func_gnulib_dir
# locates the directory where the gnulib repository lives
# Input:
# - progname name of this program
# Sets variables
# - self_abspathname absolute pathname of gnulib-tool
# - gnulib_dir absolute pathname of gnulib repository
func_gnulib_dir ()
{
case "$progname" in
/* | ?:*) self_abspathname="$progname" ;;
*/*) self_abspathname=`pwd`/"$progname" ;;
*)
# Look in $PATH.
# Iterate through the elements of $PATH.
# We use IFS=: instead of
# for d in `echo ":$PATH:" | sed -e 's/:::*/:.:/g' | sed -e 's/:/ /g'`
# because the latter does not work when some PATH element contains spaces.
# We use a canonicalized $pathx instead of $PATH, because empty PATH
# elements are by definition equivalent to '.', however field splitting
# according to IFS=: loses empty fields in many shells:
# - /bin/sh on OSF/1 and Solaris loses all empty fields (at the
# beginning, at the end, and in the middle),
# - /bin/sh on IRIX and /bin/ksh on IRIX and OSF/1 lose empty fields
# at the beginning and at the end,
# - GNU bash, /bin/sh on AIX and HP-UX, and /bin/ksh on AIX, HP-UX,
# Solaris lose empty fields at the end.
# The 'case' statement is an optimization, to avoid evaluating the
# explicit canonicalization command when $PATH contains no empty fields.
self_abspathname=
if test "$PATH_SEPARATOR" = ";"; then
# On Windows, programs are searched in "." before $PATH.
pathx=".;$PATH"
else
# On Unix, we have to convert empty PATH elements to ".".
pathx="$PATH"
case :$PATH: in
*::*)
pathx=`echo ":$PATH:" | sed -e 's/:::*/:.:/g' -e 's/^://' -e 's/:\$//'`
;;
esac
fi
saved_IFS="$IFS"
IFS="$PATH_SEPARATOR"
for d in $pathx; do
IFS="$saved_IFS"
test -z "$d" && d=.
if test -x "$d/$progname" && test ! -d "$d/$progname"; then
self_abspathname="$d/$progname"
break
fi
done
IFS="$saved_IFS"
if test -z "$self_abspathname"; then
func_fatal_error "could not locate the gnulib-tool program - how did you invoke it?"
fi
;;
esac
while test -h "$self_abspathname"; do
# Resolve symbolic link.
linkval=`func_readlink "$self_abspathname"`
test -n "$linkval" || break
case "$linkval" in
/* | ?:* ) self_abspathname="$linkval" ;;
* ) self_abspathname=`echo "$self_abspathname" | sed -e 's,/[^/]*$,,'`/"$linkval" ;;
esac
done
gnulib_dir=`echo "$self_abspathname" | sed -e 's,/[^/]*$,,'`
}
# func_tmpdir
# creates a temporary directory.
# Input:
# - progname name of this program
# Sets variable
# - tmp pathname of freshly created temporary directory
func_tmpdir ()
{
# Use the environment variable TMPDIR, falling back to /tmp. This allows
# users to specify a different temporary directory, for example, if their
# /tmp is filled up or too small.
: "${TMPDIR=/tmp}"
{
# Use the mktemp program if available. If not available, hide the error
# message.
tmp=`(umask 077 && mktemp -d "$TMPDIR/glXXXXXX") 2>/dev/null` &&
test -n "$tmp" && test -d "$tmp"
} ||
{
# Use a simple mkdir command. It is guaranteed to fail if the directory
# already exists. $RANDOM is bash specific and expands to empty in shells
# other than bash, ksh and zsh. Its use does not increase security;
# rather, it minimizes the probability of failure in a very cluttered /tmp
# directory.
tmp=$TMPDIR/gl$$-$RANDOM
(umask 077 && mkdir "$tmp")
} ||
{
echo "$progname: cannot create a temporary directory in $TMPDIR" >&2
func_exit 1
}
}
# func_append var value
# appends the given value to the shell variable var.
if ( foo=bar; foo+=baz && test "$foo" = barbaz ) >/dev/null 2>&1; then
# Use bash's += operator. It reduces complexity of appending repeatedly to
# a single variable from O(n^2) to O(n).
func_append ()
{
eval "$1+=\"\$2\""
}
fast_func_append=true
else
func_append ()
{
eval "$1=\"\$$1\$2\""
}
fast_func_append=false
fi
# func_remove_prefix var prefix
# removes the given prefix from the value of the shell variable var.
# var should be the name of a shell variable.
# Its value should not contain a newline and not start or end with whitespace.
# prefix should not contain the characters "$`\{}[]^|.
if ( foo=bar; eval 'test "${foo#b}" = ar' ) >/dev/null 2>&1; then
func_remove_prefix ()
{
eval "$1=\${$1#\$2}"
}
fast_func_remove_prefix=true
else
func_remove_prefix ()
{
eval "value=\"\$$1\""
prefix="$2"
case "$prefix" in
*.*)
sed_escape_dots='s/\([.]\)/\\\1/g'
prefix=`echo "$prefix" | sed -e "$sed_escape_dots"`
;;
esac
value=`echo "$value" | sed -e "s|^${prefix}||"`
eval "$1=\"\$value\""
}
fast_func_remove_prefix=false
fi
# Determine whether we should use ':' or ';' as PATH_SEPARATOR.
func_determine_path_separator ()
{
if test "${PATH_SEPARATOR+set}" != set; then
# Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which
# contains only /bin. Note that ksh looks also at the FPATH variable,
# so we have to set that as well for the test.
PATH_SEPARATOR=:
(PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \
&& { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \
|| PATH_SEPARATOR=';'
}
fi
}
# func_path_append pathvar directory
# appends directory to pathvar, delimiting directories by PATH_SEPARATOR.
func_path_append ()
{
if eval "test -n \"\$$1\""; then
func_append "$1" "$PATH_SEPARATOR$2"
else
eval "$1=\$2"
fi
}
# func_path_foreach_inner
# helper for func_path_foreach because we need new 'args' array
# Input:
# - fpf_dir directory from local_gnulib_path
# - fpf_cb callback to be run for fpf_dir
func_path_foreach_inner ()
{
set %start% "$@"
for _fpf_arg
do
case "$_fpf_arg" in
%start%)
set dummy
;;
%dir%)
set "$@" "$fpf_dir"
;;
*)
set "$@" "$_fpf_arg"
;;
esac
done
shift
"$fpf_cb" "$@"
}
# func_path_foreach path method args
# Execute method for each directory in path. The method will be called
# like `method args` while any argument '%dir%' within args will be replaced
# with processed directory from path.
func_path_foreach ()
{
fpf_dirs="$1"; shift
fpf_cb="$1"; shift
fpf_rc=false
fpf_saved_IFS="$IFS"
IFS="$PATH_SEPARATOR"
for fpf_dir in $fpf_dirs
do
IFS="$fpf_saved_IFS"
func_path_foreach_inner "$@" && fpf_rc=:
done
IFS="$fpf_saved_IFS"
$fpf_rc
}
# func_remove_suffix var suffix
# removes the given suffix from the value of the shell variable var.
# var should be the name of a shell variable.
# Its value should not contain a newline and not start or end with whitespace.
# suffix should not contain the characters "$`\{}[]^|.
if ( foo=bar; eval 'test "${foo%r}" = ba' ) >/dev/null 2>&1; then
func_remove_suffix ()
{
eval "$1=\${$1%\$2}"
}
fast_func_remove_suffix=true
else
func_remove_suffix ()
{
eval "value=\"\$$1\""
suffix="$2"
case "$suffix" in
*.*)
sed_escape_dots='s/\([.]\)/\\\1/g'
suffix=`echo "$suffix" | sed -e "$sed_escape_dots"`
;;
esac
value=`echo "$value" | sed -e "s|${suffix}\$||"`
eval "$1=\"\$value\""
}
fast_func_remove_suffix=false
fi
# func_relativize DIR1 DIR2
# computes a relative pathname RELDIR such that DIR1/RELDIR = DIR2.
# Input:
# - DIR1 relative pathname, relative to the current directory
# - DIR2 relative pathname, relative to the current directory
# Output:
# - reldir relative pathname of DIR2, relative to DIR1
func_relativize ()
{
dir0=`pwd`
dir1="$1"
dir2="$2"
sed_first='s,^\([^/]*\)/.*$,\1,'
sed_rest='s,^[^/]*/*,,'
sed_last='s,^.*/\([^/]*\)$,\1,'
sed_butlast='s,/*[^/]*$,,'
while test -n "$dir1"; do
first=`echo "$dir1" | sed -e "$sed_first"`
if test "$first" != "."; then
if test "$first" = ".."; then
dir2=`echo "$dir0" | sed -e "$sed_last"`/"$dir2"
dir0=`echo "$dir0" | sed -e "$sed_butlast"`
else
first2=`echo "$dir2" | sed -e "$sed_first"`
if test "$first2" = "$first"; then
dir2=`echo "$dir2" | sed -e "$sed_rest"`
else
dir2="../$dir2"
fi
dir0="$dir0"/"$first"
fi
fi
dir1=`echo "$dir1" | sed -e "$sed_rest"`
done
reldir="$dir2"
}
# func_relconcat DIR1 DIR2
# computes a relative pathname DIR1/DIR2, with obvious simplifications.
# Input:
# - DIR1 relative pathname, relative to the current directory
# - DIR2 relative pathname, relative to DIR1
# Output:
# - relconcat DIR1/DIR2, relative to the current directory
func_relconcat ()
{
dir1="$1"
dir2="$2"
sed_first='s,^\([^/]*\)/.*$,\1,'
sed_rest='s,^[^/]*/*,,'
sed_last='s,^.*/\([^/]*\)$,\1,'
sed_butlast='s,/*[^/]*$,,'
while true; do
first=`echo "$dir2" | sed -e "$sed_first"`
if test "$first" = "."; then
dir2=`echo "$dir2" | sed -e "$sed_rest"`
if test -z "$dir2"; then
relconcat="$dir1"
break
fi
else
last=`echo "$dir1" | sed -e "$sed_last"`
while test "$last" = "."; do
dir1=`echo "$dir1" | sed -e "$sed_butlast"`
last=`echo "$dir1" | sed -e "$sed_last"`
done
if test -z "$dir1"; then
relconcat="$dir2"
break
fi
if test "$first" = ".."; then
if test "$last" = ".."; then
relconcat="$dir1/$dir2"
break
fi
dir1=`echo "$dir1" | sed -e "$sed_butlast"`
dir2=`echo "$dir2" | sed -e "$sed_rest"`
if test -z "$dir1"; then
relconcat="$dir2"
break
fi
if test -z "$dir2"; then
relconcat="$dir1"
break
fi
else
relconcat="$dir1/$dir2"
break
fi
fi
done
}
# func_ensure_writable DEST
# Ensures the file DEST is writable.
func_ensure_writable ()
{
test -w "$1" || chmod u+w "$1"
}
# func_ln_s SRC DEST
# Like ln -s, except use cp -p if ln -s fails.
func_ln_s ()
{
ln -s "$1" "$2" || {
echo "$progname: ln -s failed; falling back on cp -p" >&2
case "$1" in
/* | ?:*) # SRC is absolute.
cp_src="$1" ;;
*) # SRC is relative to the directory of DEST.
case "$2" in
*/*) cp_src="${2%/*}/$1" ;;
*) cp_src="$1" ;;
esac
;;
esac
cp -p "$cp_src" "$2"
func_ensure_writable "$2"
}
}
# func_symlink_target SRC DEST
# Determines LINK_TARGET such that "ln -s LINK_TARGET DEST" will create a
# symbolic link DEST that points to SRC.
# Output:
# - link_target link target, relative to the directory of DEST
func_symlink_target ()
{
case "$1" in
/* | ?:*)
link_target="$1" ;;
*) # SRC is relative.
case "$2" in
/* | ?:*)
link_target="`pwd`/$1" ;;
*) # DEST is relative too.
ln_destdir=`echo "$2" | sed -e 's,[^/]*$,,'`
test -n "$ln_destdir" || ln_destdir="."
func_relativize "$ln_destdir" "$1"
link_target="$reldir"
;;
esac
;;
esac
}
# func_symlink SRC DEST
# Like func_ln_s, except that SRC is given relative to the current directory (or
# absolute), not given relative to the directory of DEST.
func_symlink ()
{
func_symlink_target "$1" "$2"
func_ln_s "$link_target" "$2"
}
# func_symlink_if_changed SRC DEST
# Like func_symlink, but avoids munging timestamps if the link is correct.
# SRC is given relative to the current directory (or absolute).
func_symlink_if_changed ()
{
if test $# -ne 2; then
echo "usage: func_symlink_if_changed SRC DEST" >&2
fi
func_symlink_target "$1" "$2"
ln_target=`func_readlink "$2"`
if test -h "$2" && test "$link_target" = "$ln_target"; then
:
else
rm -f "$2"
func_ln_s "$link_target" "$2"
fi
}
# func_hardlink SRC DEST
# Like ln, except use cp -p if ln fails.
# SRC is given relative to the current directory (or absolute).
func_hardlink ()
{
ln "$1" "$2" || {
echo "$progname: ln failed; falling back on cp -p" >&2
cp -p "$1" "$2"
func_ensure_writable "$2"
}
}
# Ensure an 'echo' command that
# 1. does not interpret backslashes and
# 2. does not print an error message "broken pipe" when writing into a pipe
# with no writers.
#
# Test cases for problem 1:
# echo '\n' | wc -l prints 1 when OK, 2 when KO
# echo '\t' | grep t > /dev/null has return code 0 when OK, 1 when KO
# Test cases for problem 2:
# echo hi | true frequently prints
# "bash: echo: write error: Broken pipe"
# to standard error in bash 3.2.
#
# Problem 1 is a weird heritage from SVR4. BSD got it right (except that
# BSD echo interprets '-n' as an option, which is also not desirable).
# Nowadays the problem occurs in 4 situations:
# - in bash, when the shell option xpg_echo is set (bash >= 2.04)
# or when it was built with --enable-usg-echo-default (bash >= 2.0)
# or when it was built with DEFAULT_ECHO_TO_USG (bash < 2.0),
# - in zsh, when sh-emulation is not set,
# - in ksh (e.g. AIX /bin/sh and Solaris /usr/xpg4/bin/sh are ksh instances,
# and HP-UX /bin/sh and IRIX /bin/sh behave similarly),
# - in Solaris /bin/sh and OSF/1 /bin/sh.
# We try the following workarounds:
# - for all: respawn using $CONFIG_SHELL if that is set and works.
# - for bash >= 2.04: unset the shell option xpg_echo.
# - for bash >= 2.0: define echo to a function that uses the printf built-in.
# - for bash < 2.0: define echo to a function that uses cat of a here document.
# - for zsh: turn sh-emulation on.
# - for ksh: alias echo to 'print -r'.
# - for ksh: alias echo to a function that uses cat of a here document.
# - for Solaris /bin/sh and OSF/1 /bin/sh: respawn using /bin/ksh and rely on
# the ksh workaround.
# - otherwise: respawn using /bin/sh and rely on the workarounds.
# When respawning, we pass --no-reexec as first argument, so as to avoid
# turning this script into a fork bomb in unlucky situations.
#
# Problem 2 is specific to bash 3.2 and affects the 'echo' built-in, but not
# the 'printf' built-in. See
# <https://lists.gnu.org/r/bug-bash/2008-12/msg00050.html>
# <https://lists.gnu.org/r/bug-gnulib/2010-02/msg00154.html>
# The workaround is: define echo to a function that uses the printf built-in.
have_echo=
if echo '\t' | grep t > /dev/null; then
have_echo=yes # Lucky!
fi
# Try the workarounds.
# Respawn using $CONFIG_SHELL if that is set and works.
if test -z "$have_echo" \
&& test "X$1" != "X--no-reexec" \
&& test -n "$CONFIG_SHELL" \
&& test -f "$CONFIG_SHELL" \
&& $CONFIG_SHELL -c "echo '\\t' | grep t > /dev/null"; then
exec $CONFIG_SHELL "$0" --no-reexec "$@"
exit 127
fi
# For bash >= 2.04: unset the shell option xpg_echo.
if test -z "$have_echo" \
&& test -n "$BASH_VERSION" \
&& (shopt -o xpg_echo; echo '\t' | grep t > /dev/null) 2>/dev/null; then
shopt -o xpg_echo
have_echo=yes
fi
# For bash >= 2.0: define echo to a function that uses the printf built-in.
# For bash < 2.0: define echo to a function that uses cat of a here document.
# (There is no win in using 'printf' over 'cat' if it is not a shell built-in.)
# Also handle problem 2, specific to bash 3.2, here.
if { test -z "$have_echo" \
|| case "$BASH_VERSION" in 3.2*) true;; *) false;; esac; \
} \
&& test -n "$BASH_VERSION"; then \
if type printf 2>/dev/null | grep / > /dev/null; then
# 'printf' is not a shell built-in.
echo ()
{
cat <<EOF
$*
EOF
}
else
# 'printf' is a shell built-in.
echo ()
{
printf '%s\n' "$*"
}
fi
if echo '\t' | grep t > /dev/null; then
have_echo=yes
fi
fi
# For zsh: turn sh-emulation on.
if test -z "$have_echo" \
&& test -n "$ZSH_VERSION" \
&& (emulate sh) >/dev/null 2>&1; then
emulate sh
fi
# For ksh: alias echo to 'print -r'.
if test -z "$have_echo" \
&& (type print) >/dev/null 2>&1; then
# A 'print' command exists.
if type print 2>/dev/null | grep / > /dev/null; then
:
else
# 'print' is a shell built-in.
if (print -r '\told' | grep told > /dev/null) 2>/dev/null; then
# 'print' is the ksh shell built-in.
alias echo='print -r'
fi
fi