xref: /netbsd-src/external/gpl3/binutils/dist/ar-lib (revision c1a20988198909a4dd9874492f62747781a99381)
1*c1a20988Schristos#! /bin/sh
2*c1a20988Schristos# Wrapper for Microsoft lib.exe
3*c1a20988Schristos
4*c1a20988Schristosme=ar-lib
5*c1a20988Schristosscriptversion=2012-03-01.08; # UTC
6*c1a20988Schristos
7*c1a20988Schristos# Copyright (C) 2010-2017 Free Software Foundation, Inc.
8*c1a20988Schristos# Written by Peter Rosin <peda@lysator.liu.se>.
9*c1a20988Schristos#
10*c1a20988Schristos# This program is free software; you can redistribute it and/or modify
11*c1a20988Schristos# it under the terms of the GNU General Public License as published by
12*c1a20988Schristos# the Free Software Foundation; either version 2, or (at your option)
13*c1a20988Schristos# any later version.
14*c1a20988Schristos#
15*c1a20988Schristos# This program is distributed in the hope that it will be useful,
16*c1a20988Schristos# but WITHOUT ANY WARRANTY; without even the implied warranty of
17*c1a20988Schristos# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*c1a20988Schristos# GNU General Public License for more details.
19*c1a20988Schristos#
20*c1a20988Schristos# You should have received a copy of the GNU General Public License
21*c1a20988Schristos# along with this program.  If not, see <http://www.gnu.org/licenses/>.
22*c1a20988Schristos
23*c1a20988Schristos# As a special exception to the GNU General Public License, if you
24*c1a20988Schristos# distribute this file as part of a program that contains a
25*c1a20988Schristos# configuration script generated by Autoconf, you may include it under
26*c1a20988Schristos# the same distribution terms that you use for the rest of that program.
27*c1a20988Schristos
28*c1a20988Schristos# This file is maintained in Automake, please report
29*c1a20988Schristos# bugs to <bug-automake@gnu.org> or send patches to
30*c1a20988Schristos# <automake-patches@gnu.org>.
31*c1a20988Schristos
32*c1a20988Schristos
33*c1a20988Schristos# func_error message
34*c1a20988Schristosfunc_error ()
35*c1a20988Schristos{
36*c1a20988Schristos  echo "$me: $1" 1>&2
37*c1a20988Schristos  exit 1
38*c1a20988Schristos}
39*c1a20988Schristos
40*c1a20988Schristosfile_conv=
41*c1a20988Schristos
42*c1a20988Schristos# func_file_conv build_file
43*c1a20988Schristos# Convert a $build file to $host form and store it in $file
44*c1a20988Schristos# Currently only supports Windows hosts.
45*c1a20988Schristosfunc_file_conv ()
46*c1a20988Schristos{
47*c1a20988Schristos  file=$1
48*c1a20988Schristos  case $file in
49*c1a20988Schristos    / | /[!/]*) # absolute file, and not a UNC file
50*c1a20988Schristos      if test -z "$file_conv"; then
51*c1a20988Schristos	# lazily determine how to convert abs files
52*c1a20988Schristos	case `uname -s` in
53*c1a20988Schristos	  MINGW*)
54*c1a20988Schristos	    file_conv=mingw
55*c1a20988Schristos	    ;;
56*c1a20988Schristos	  CYGWIN*)
57*c1a20988Schristos	    file_conv=cygwin
58*c1a20988Schristos	    ;;
59*c1a20988Schristos	  *)
60*c1a20988Schristos	    file_conv=wine
61*c1a20988Schristos	    ;;
62*c1a20988Schristos	esac
63*c1a20988Schristos      fi
64*c1a20988Schristos      case $file_conv in
65*c1a20988Schristos	mingw)
66*c1a20988Schristos	  file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
67*c1a20988Schristos	  ;;
68*c1a20988Schristos	cygwin)
69*c1a20988Schristos	  file=`cygpath -m "$file" || echo "$file"`
70*c1a20988Schristos	  ;;
71*c1a20988Schristos	wine)
72*c1a20988Schristos	  file=`winepath -w "$file" || echo "$file"`
73*c1a20988Schristos	  ;;
74*c1a20988Schristos      esac
75*c1a20988Schristos      ;;
76*c1a20988Schristos  esac
77*c1a20988Schristos}
78*c1a20988Schristos
79*c1a20988Schristos# func_at_file at_file operation archive
80*c1a20988Schristos# Iterate over all members in AT_FILE performing OPERATION on ARCHIVE
81*c1a20988Schristos# for each of them.
82*c1a20988Schristos# When interpreting the content of the @FILE, do NOT use func_file_conv,
83*c1a20988Schristos# since the user would need to supply preconverted file names to
84*c1a20988Schristos# binutils ar, at least for MinGW.
85*c1a20988Schristosfunc_at_file ()
86*c1a20988Schristos{
87*c1a20988Schristos  operation=$2
88*c1a20988Schristos  archive=$3
89*c1a20988Schristos  at_file_contents=`cat "$1"`
90*c1a20988Schristos  eval set x "$at_file_contents"
91*c1a20988Schristos  shift
92*c1a20988Schristos
93*c1a20988Schristos  for member
94*c1a20988Schristos  do
95*c1a20988Schristos    $AR -NOLOGO $operation:"$member" "$archive" || exit $?
96*c1a20988Schristos  done
97*c1a20988Schristos}
98*c1a20988Schristos
99*c1a20988Schristoscase $1 in
100*c1a20988Schristos  '')
101*c1a20988Schristos     func_error "no command.  Try '$0 --help' for more information."
102*c1a20988Schristos     ;;
103*c1a20988Schristos  -h | --h*)
104*c1a20988Schristos    cat <<EOF
105*c1a20988SchristosUsage: $me [--help] [--version] PROGRAM ACTION ARCHIVE [MEMBER...]
106*c1a20988Schristos
107*c1a20988SchristosMembers may be specified in a file named with @FILE.
108*c1a20988SchristosEOF
109*c1a20988Schristos    exit $?
110*c1a20988Schristos    ;;
111*c1a20988Schristos  -v | --v*)
112*c1a20988Schristos    echo "$me, version $scriptversion"
113*c1a20988Schristos    exit $?
114*c1a20988Schristos    ;;
115*c1a20988Schristosesac
116*c1a20988Schristos
117*c1a20988Schristosif test $# -lt 3; then
118*c1a20988Schristos  func_error "you must specify a program, an action and an archive"
119*c1a20988Schristosfi
120*c1a20988Schristos
121*c1a20988SchristosAR=$1
122*c1a20988Schristosshift
123*c1a20988Schristoswhile :
124*c1a20988Schristosdo
125*c1a20988Schristos  if test $# -lt 2; then
126*c1a20988Schristos    func_error "you must specify a program, an action and an archive"
127*c1a20988Schristos  fi
128*c1a20988Schristos  case $1 in
129*c1a20988Schristos    -lib | -LIB \
130*c1a20988Schristos    | -ltcg | -LTCG \
131*c1a20988Schristos    | -machine* | -MACHINE* \
132*c1a20988Schristos    | -subsystem* | -SUBSYSTEM* \
133*c1a20988Schristos    | -verbose | -VERBOSE \
134*c1a20988Schristos    | -wx* | -WX* )
135*c1a20988Schristos      AR="$AR $1"
136*c1a20988Schristos      shift
137*c1a20988Schristos      ;;
138*c1a20988Schristos    *)
139*c1a20988Schristos      action=$1
140*c1a20988Schristos      shift
141*c1a20988Schristos      break
142*c1a20988Schristos      ;;
143*c1a20988Schristos  esac
144*c1a20988Schristosdone
145*c1a20988Schristosorig_archive=$1
146*c1a20988Schristosshift
147*c1a20988Schristosfunc_file_conv "$orig_archive"
148*c1a20988Schristosarchive=$file
149*c1a20988Schristos
150*c1a20988Schristos# strip leading dash in $action
151*c1a20988Schristosaction=${action#-}
152*c1a20988Schristos
153*c1a20988Schristosdelete=
154*c1a20988Schristosextract=
155*c1a20988Schristoslist=
156*c1a20988Schristosquick=
157*c1a20988Schristosreplace=
158*c1a20988Schristosindex=
159*c1a20988Schristoscreate=
160*c1a20988Schristos
161*c1a20988Schristoswhile test -n "$action"
162*c1a20988Schristosdo
163*c1a20988Schristos  case $action in
164*c1a20988Schristos    d*) delete=yes  ;;
165*c1a20988Schristos    x*) extract=yes ;;
166*c1a20988Schristos    t*) list=yes    ;;
167*c1a20988Schristos    q*) quick=yes   ;;
168*c1a20988Schristos    r*) replace=yes ;;
169*c1a20988Schristos    s*) index=yes   ;;
170*c1a20988Schristos    S*)             ;; # the index is always updated implicitly
171*c1a20988Schristos    c*) create=yes  ;;
172*c1a20988Schristos    u*)             ;; # TODO: don't ignore the update modifier
173*c1a20988Schristos    v*)             ;; # TODO: don't ignore the verbose modifier
174*c1a20988Schristos    *)
175*c1a20988Schristos      func_error "unknown action specified"
176*c1a20988Schristos      ;;
177*c1a20988Schristos  esac
178*c1a20988Schristos  action=${action#?}
179*c1a20988Schristosdone
180*c1a20988Schristos
181*c1a20988Schristoscase $delete$extract$list$quick$replace,$index in
182*c1a20988Schristos  yes,* | ,yes)
183*c1a20988Schristos    ;;
184*c1a20988Schristos  yesyes*)
185*c1a20988Schristos    func_error "more than one action specified"
186*c1a20988Schristos    ;;
187*c1a20988Schristos  *)
188*c1a20988Schristos    func_error "no action specified"
189*c1a20988Schristos    ;;
190*c1a20988Schristosesac
191*c1a20988Schristos
192*c1a20988Schristosif test -n "$delete"; then
193*c1a20988Schristos  if test ! -f "$orig_archive"; then
194*c1a20988Schristos    func_error "archive not found"
195*c1a20988Schristos  fi
196*c1a20988Schristos  for member
197*c1a20988Schristos  do
198*c1a20988Schristos    case $1 in
199*c1a20988Schristos      @*)
200*c1a20988Schristos        func_at_file "${1#@}" -REMOVE "$archive"
201*c1a20988Schristos        ;;
202*c1a20988Schristos      *)
203*c1a20988Schristos        func_file_conv "$1"
204*c1a20988Schristos        $AR -NOLOGO -REMOVE:"$file" "$archive" || exit $?
205*c1a20988Schristos        ;;
206*c1a20988Schristos    esac
207*c1a20988Schristos  done
208*c1a20988Schristos
209*c1a20988Schristoselif test -n "$extract"; then
210*c1a20988Schristos  if test ! -f "$orig_archive"; then
211*c1a20988Schristos    func_error "archive not found"
212*c1a20988Schristos  fi
213*c1a20988Schristos  if test $# -gt 0; then
214*c1a20988Schristos    for member
215*c1a20988Schristos    do
216*c1a20988Schristos      case $1 in
217*c1a20988Schristos        @*)
218*c1a20988Schristos          func_at_file "${1#@}" -EXTRACT "$archive"
219*c1a20988Schristos          ;;
220*c1a20988Schristos        *)
221*c1a20988Schristos          func_file_conv "$1"
222*c1a20988Schristos          $AR -NOLOGO -EXTRACT:"$file" "$archive" || exit $?
223*c1a20988Schristos          ;;
224*c1a20988Schristos      esac
225*c1a20988Schristos    done
226*c1a20988Schristos  else
227*c1a20988Schristos    $AR -NOLOGO -LIST "$archive" | sed -e 's/\\/\\\\/g' | while read member
228*c1a20988Schristos    do
229*c1a20988Schristos      $AR -NOLOGO -EXTRACT:"$member" "$archive" || exit $?
230*c1a20988Schristos    done
231*c1a20988Schristos  fi
232*c1a20988Schristos
233*c1a20988Schristoselif test -n "$quick$replace"; then
234*c1a20988Schristos  if test ! -f "$orig_archive"; then
235*c1a20988Schristos    if test -z "$create"; then
236*c1a20988Schristos      echo "$me: creating $orig_archive"
237*c1a20988Schristos    fi
238*c1a20988Schristos    orig_archive=
239*c1a20988Schristos  else
240*c1a20988Schristos    orig_archive=$archive
241*c1a20988Schristos  fi
242*c1a20988Schristos
243*c1a20988Schristos  for member
244*c1a20988Schristos  do
245*c1a20988Schristos    case $1 in
246*c1a20988Schristos    @*)
247*c1a20988Schristos      func_file_conv "${1#@}"
248*c1a20988Schristos      set x "$@" "@$file"
249*c1a20988Schristos      ;;
250*c1a20988Schristos    *)
251*c1a20988Schristos      func_file_conv "$1"
252*c1a20988Schristos      set x "$@" "$file"
253*c1a20988Schristos      ;;
254*c1a20988Schristos    esac
255*c1a20988Schristos    shift
256*c1a20988Schristos    shift
257*c1a20988Schristos  done
258*c1a20988Schristos
259*c1a20988Schristos  if test -n "$orig_archive"; then
260*c1a20988Schristos    $AR -NOLOGO -OUT:"$archive" "$orig_archive" "$@" || exit $?
261*c1a20988Schristos  else
262*c1a20988Schristos    $AR -NOLOGO -OUT:"$archive" "$@" || exit $?
263*c1a20988Schristos  fi
264*c1a20988Schristos
265*c1a20988Schristoselif test -n "$list"; then
266*c1a20988Schristos  if test ! -f "$orig_archive"; then
267*c1a20988Schristos    func_error "archive not found"
268*c1a20988Schristos  fi
269*c1a20988Schristos  $AR -NOLOGO -LIST "$archive" || exit $?
270*c1a20988Schristosfi
271