replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / build_common / tools / UnpackAll.py
1 # -*- coding: utf-8 -*-
2
3 # -- Dual Licence ----------------------------------------------------------
4
5 ############################################################################
6 # GPL License                                                              #
7 #                                                                          #
8 # This file is a SCons (http://www.scons.org/) builder                     #
9 # Copyright (c) 2012-14, Philipp Kraus, <philipp.kraus@flashpixx.de>       #
10 # This program is free software: you can redistribute it and/or modify     #
11 # it under the terms of the GNU General Public License as                  #
12 # published by the Free Software Foundation, either version 3 of the       #
13 # License, or (at your option) any later version.                          #
14 #                                                                          #
15 # This program is distributed in the hope that it will be useful,          #
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of           #
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            #
18 # GNU General Public License for more details.                             #
19 #                                                                          #
20 # You should have received a copy of the GNU General Public License        #
21 # along with this program. If not, see <http://www.gnu.org/licenses/>.     #
22 ############################################################################
23
24 # --------------------------------------------------------------------------
25
26 ############################################################################
27 # BSD 3-Clause License                                                     #
28 #                                                                          #
29 # This file is a SCons (http://www.scons.org/) builder                     #
30 # Copyright (c) 2012-14, Philipp Kraus, <philipp.kraus@flashpixx.de>       #
31 # All rights reserved.                                                     #
32 #                                                                          #
33 # Redistribution and use in source and binary forms, with or without       #
34 # modification, are permitted provided that the following conditions are   #
35 # met:                                                                     #
36 #                                                                          #
37 # 1. Redistributions of source code must retain the above copyright        #
38 # notice, this list of conditions and the following disclaimer.            #
39 #                                                                          #
40 # 2. Redistributions in binary form must reproduce the above copyright     #
41 # notice, this list of conditions and the following disclaimer in the      #
42 # documentation and/or other materials provided with the distribution.     #
43 #                                                                          #
44 # 3. Neither the name of the copyright holder nor the names of its         #
45 # contributors may be used to endorse or promote products derived from     #
46 # this software without specific prior written permission.                 #
47 #                                                                          #
48 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS      #
49 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT        #
50 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A  #
51 # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT       #
52 # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,   #
53 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED #
54 # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR   #
55 # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF   #
56 # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING     #
57 # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS       #
58 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.             #
59 ############################################################################
60
61
62
63 # The Unpack Builder can be used for unpacking archives (eg Zip, TGZ, BZ, ... ).
64 # The emitter of the Builder reads the archive data and creates a returning file list
65 # the builder extract the archive. The environment variable stores a dictionary "UNPACK"
66 # for set different extractions (subdict "EXTRACTOR"):
67 # {
68 #   PRIORITY         => a value for setting the extractor order (lower numbers = extractor is used earlier)
69 #   SUFFIX           => defines a list with file suffixes, which should be handled with this extractor
70 #   EXTRACTSUFFIX    => suffix of the extract command
71 #   EXTRACTFLAGS     => a string parameter for the RUN command for extracting the data
72 #   EXTRACTCMD       => full extract command of the builder
73 #   RUN              => the main program which will be started (if the parameter is empty, the extractor will be ignored)
74 #   LISTCMD          => the listing command for the emitter
75 #   LISTFLAGS        => the string options for the RUN command for showing a list of files
76 #   LISTSUFFIX       => suffix of the list command
77 #   LISTEXTRACTOR    => a optional Python function, that is called on each output line of the
78 #                       LISTCMD for extracting file & dir names, the function need two parameters (first line number,
79 #                       second line content) and must return a string with the file / dir path (other value types
80 #                       will be ignored)
81 # }
82 # Other options in the UNPACK dictionary are:
83 #   STOPONEMPTYFILE  => bool variable for stoping if the file has empty size (default True)
84 #   VIWEXTRACTOUTPUT => shows the output messages of the extraction command (default False)
85 #   EXTRACTDIR       => path in that the data will be extracted (default #)
86 #
87 # The file which is handled by the first suffix match of the extractor, the extractor list can be append for other files.
88 # The order of the extractor dictionary creates the listing & extractor command eg file extension .tar.gz should be
89 # before .gz, because the tar.gz is extract in one shoot.
90 #
91 # Under *nix system these tools are supported: tar, bzip2, gzip, unzip
92 # Under Windows only 7-Zip (http://www.7-zip.org/) is supported
93
94
95 import subprocess, os
96
97 import SCons.Errors, SCons.Warnings
98 import SCons.Util
99
100
101 # enables Scons warning for this builder
102 class UnpackWarning(SCons.Warnings.Warning) :
103     pass
104
105 SCons.Warnings.enableWarningClass(UnpackWarning)
106
107
108
109 # extractor function for Tar output
110 # @param env environment object
111 # @param count number of returning lines
112 # @param no number of the output line
113 # @param i line content
114 def __fileextractor_nix_tar( env, count, no, i ) :
115     return i.split()[-1]
116
117 # extractor function for GZip output,
118 # ignore the first line
119 # @param env environment object
120 # @param count number of returning lines
121 # @param no number of the output line
122 # @param i line content
123 def __fileextractor_nix_gzip( env, count, no, i ) :
124     if no == 0 :
125         return None
126     return i.split()[-1]
127
128 # extractor function for Unzip output,
129 # ignore the first & last two lines
130 # @param env environment object
131 # @param count number of returning lines
132 # @param no number of the output line
133 # @param i line content
134 def __fileextractor_nix_unzip( env, count, no, i ) :
135     if no < 3 or no >= count - 2 :
136         return None
137     return i.split()[-1]
138
139 # extractor function for 7-Zip
140 # @param env environment object
141 # @param count number of returning lines
142 # @param no number of the output line
143 # @param i line content
144 def __fileextractor_win_7zip( env, count, no, i ) :
145     item = i.split()
146     if no > 8 and no < count - 2 :
147         return item[-1]
148     return None
149
150
151
152 # returns the extractor item for handling the source file
153 # @param source input source file
154 # @param env environment object
155 # @return extractor entry or None on non existing
156 def __getExtractor( source, env ) :
157     # we check each unpacker and get the correc  list command first, run the command and
158     # replace the target filelist with the list values, we sorte the extractors by their priority
159     for unpackername, extractor in sorted(env["UNPACK"]["EXTRACTOR"].iteritems(), key = lambda (k,v) : (v["PRIORITY"],k)):
160
161         # if the run command not set, we continue the extractor search, otherwise we check the extractor parameters
162         if not SCons.Util.is_String(extractor["RUN"]) :
163             raise SCons.Errors.StopError("list command of the unpack builder for [%s] archives is not a string" % (unpackername))
164         if not len(extractor["RUN"]) :
165             raise SCons.Errors.StopError("run command of the unpack builder for [%s] archives is not set - can not extract files" % (unpackername))
166
167
168         if not SCons.Util.is_String(extractor["LISTFLAGS"]) :
169             raise SCons.Errors.StopError("list flags of the unpack builder for [%s] archives is not a string" % (unpackername))
170         if not SCons.Util.is_String(extractor["LISTCMD"]) :
171             raise SCons.Errors.StopError("list command of the unpack builder for [%s] archives is not a string" % (unpackername))
172
173         if not SCons.Util.is_String(extractor["EXTRACTFLAGS"]) :
174             raise SCons.Errors.StopError("extract flags of the unpack builder for [%s] archives is not a string" % (unpackername))
175         if not SCons.Util.is_String(extractor["EXTRACTCMD"]) :
176             raise SCons.Errors.StopError("extract command of the unpack builder for [%s] archives is not a string" % (unpackername))
177
178
179         # check the source file suffix and if the first is found, run the list command
180         if not SCons.Util.is_List(extractor["SUFFIX"]) :
181             raise SCons.Errors.StopError("suffix list of the unpack builder for [%s] archives is not a list" % (unpackername))
182
183         for suffix in extractor["SUFFIX"] :
184             if str(source[0]).lower()[-len(suffix):] == suffix.lower() :
185                 return extractor
186
187     return None
188
189
190 # creates the extracter output message
191 # @param s original message
192 # @param target target name
193 # @param source source name
194 # @param env environment object
195 def __message( s, target, source, env ) :
196     print "extract [%s] ..." % (source[0])
197
198
199 # action function for extracting of the data
200 # @param target target packed file
201 # @param source extracted files
202 # @env environment object
203 def __action( target, source, env ) :
204     extractor = __getExtractor([File(source)], env)
205     if not extractor :
206         raise SCons.Errors.StopError( "can not find any extractor value for the source file [%s]" % (source[0]) )
207
208
209     # if the extract command is empty, we create an error
210     if len(extractor["EXTRACTCMD"]) == 0 :
211         raise SCons.Errors.StopError( "the extractor command for the source file [%s] is empty" % (source[0]) )
212
213     # build it now (we need the shell, because some programs need it)
214     handle = None
215     cmd    = env.subst(extractor["EXTRACTCMD"], source=source, target=target)
216
217     if env["UNPACK"]["VIWEXTRACTOUTPUT"] :
218         handle  = subprocess.Popen( cmd, shell=True )
219     else :
220         devnull = open(os.devnull, "wb")
221         handle  = subprocess.Popen( cmd, shell=True, stdout=devnull )
222
223     if handle.wait() <> 0 :
224         raise SCons.Errors.BuildError( "error running extractor [%s] on the source [%s]" % (cmd, source[0])  )
225
226
227 # emitter function for getting the files
228 # within the archive
229 # @param target target packed file
230 # @param source extracted files
231 # @env environment object
232 def __emitter( target, source, env ) :
233     extractor = __getExtractor(source, env)
234     if not extractor :
235         raise SCons.Errors.StopError( "can not find any extractor value for the source file [%s]" % (source[0]) )
236
237     # we do a little trick, because in some cases we do not have got a physical
238     # file (eg we download a packed archive), so we don't get a list or knows
239     # the targets. On physical files we can do this with the LISTCMD, but on
240     # non-physical files we hope the user knows the target files, so we inject
241     # this knowledge into the return target.
242     if env.has_key("UNPACKLIST") :
243         if not SCons.Util.is_List(env["UNPACKLIST"]) and not SCons.Util.is_String(env["UNPACKLIST"]) :
244             raise SCons.Errors.StopError( "manual target list of [%s] must be a string or list" % (source[0]) )
245         if not env["UNPACKLIST"] :
246             raise SCons.Errors.StopError( "manual target list of [%s] need not be empty" % (source[0]) )
247         return env["UNPACKLIST"], source
248
249
250     # we check if the source file exists, because we would like to read the data
251     if not source[0].exists() :
252         raise SCons.Errors.StopError( "source file [%s] must be exist" % (source[0]) )
253
254     # create the list command and run it in a subprocess and pipes the output to a variable,
255     # we need the shell for reading data from the stdout
256     cmd    = env.subst(extractor["LISTCMD"], source=source, target=target)
257     handle = subprocess.Popen( cmd, shell=True, stdout=subprocess.PIPE )
258     target = handle.stdout.readlines()
259     handle.communicate()
260     if handle.returncode <> 0 :
261         raise SCons.Errors.StopError("error on running list command [%s] of the source file [%s]" % (cmd, source[0]) )
262
263     # if the returning output exists and the listseperator is a callable structure
264     # we run it for each line of the output and if the return of the callable is
265     # a string we push it back to the target list
266     try :
267         if callable(extractor["LISTEXTRACTOR"]) :
268             target = filter( lambda s : SCons.Util.is_String(s), [ extractor["LISTEXTRACTOR"]( env, len(target), no, i) for no, i in enumerate(target) ] )
269     except Exception, e :
270         raise SCons.Errors.StopError( "%s" % (e) )
271
272     # the line removes duplicated names - we need this line, otherwise an cyclic dependency error will occured,
273     # because the list process can create redundant data (an archive file can not store redundant content in a filepath)
274     target = [i.strip() for i in list(set(target))]
275     if not target :
276         SCons.Warnings.warn(UnpackWarning, "emitter file list on target [%s] is empty, please check your extractor list function [%s]" % (source[0], cmd) )
277
278     # we append the extractdir to each target if is not absolut
279     if env["UNPACK"]["EXTRACTDIR"] <> "." :
280         target = [i if os.path.isabs(i) else os.path.join(env["UNPACK"]["EXTRACTDIR"], i) for i in target]
281
282     return target, source
283
284 def __unpack_all(env, target, source) :
285     if os.path.exists(target):
286         return
287
288     print "Unpacking %s ..." % source
289     __action(target, source, env)
290
291 # generate function, that adds the builder to the environment
292 # @env environment object
293 def generate( env ) :
294     # setup environment variable
295     toolset = {
296         "STOPONEMPTYFILE"  : True,
297         "VIWEXTRACTOUTPUT" : False,
298         "EXTRACTDIR"       : os.curdir,
299         "EXTRACTOR" : {
300             "TARGZ" : {
301                 "PRIORITY"       : 0,
302                 "SUFFIX"         : [".tar.gz", ".tgz", ".tar.gzip"],
303                 "EXTRACTSUFFIX"  : "",
304                 "EXTRACTFLAGS"   : "",
305                 "EXTRACTCMD"     : "${UNPACK['EXTRACTOR']['TARGZ']['RUN']} ${UNPACK['EXTRACTOR']['TARGZ']['EXTRACTFLAGS']} $SOURCE ${UNPACK['EXTRACTOR']['TARGZ']['EXTRACTSUFFIX']}",
306                 "RUN"            : "",
307                 "LISTCMD"        : "${UNPACK['EXTRACTOR']['TARGZ']['RUN']} ${UNPACK['EXTRACTOR']['TARGZ']['LISTFLAGS']} $SOURCE ${UNPACK['EXTRACTOR']['TARGZ']['LISTSUFFIX']}",
308                 "LISTSUFFIX"     : "",
309                 "LISTFLAGS"      : "",
310                 "LISTEXTRACTOR"  : None
311             },
312
313             "TARBZ" : {
314                 "PRIORITY"       : 0,
315                 "SUFFIX"         : [".tar.bz", ".tbz", ".tar.bz2", ".tar.bzip2", ".tar.bzip"],
316                 "EXTRACTSUFFIX"  : "",
317                 "EXTRACTFLAGS"   : "",
318                 "EXTRACTCMD"     : "${UNPACK['EXTRACTOR']['TARBZ']['RUN']} ${UNPACK['EXTRACTOR']['TARBZ']['EXTRACTFLAGS']} $SOURCE ${UNPACK['EXTRACTOR']['TARBZ']['EXTRACTSUFFIX']}",
319                 "RUN"            : "",
320                 "LISTCMD"        : "${UNPACK['EXTRACTOR']['TARBZ']['RUN']} ${UNPACK['EXTRACTOR']['TARBZ']['LISTFLAGS']} $SOURCE ${UNPACK['EXTRACTOR']['TARBZ']['LISTSUFFIX']}",
321                 "LISTSUFFIX"     : "",
322                 "LISTFLAGS"      : "",
323                 "LISTEXTRACTOR"  : None
324             },
325
326             "BZIP" : {
327                 "PRIORITY"       : 1,
328                 "SUFFIX"         : [".bz", "bzip", ".bz2", ".bzip2"],
329                 "EXTRACTSUFFIX"  : "",
330                 "EXTRACTFLAGS"   : "",
331                 "EXTRACTCMD"     : "${UNPACK['EXTRACTOR']['BZIP']['RUN']} ${UNPACK['EXTRACTOR']['BZIP']['EXTRACTFLAGS']} $SOURCE ${UNPACK['EXTRACTOR']['BZIP']['EXTRACTSUFFIX']}",
332                 "RUN"            : "",
333                 "LISTCMD"        : "${UNPACK['EXTRACTOR']['BZIP']['RUN']} ${UNPACK['EXTRACTOR']['BZIP']['LISTFLAGS']} $SOURCE ${UNPACK['EXTRACTOR']['BZIP']['LISTSUFFIX']}",
334                 "LISTSUFFIX"     : "",
335                 "LISTFLAGS"      : "",
336                 "LISTEXTRACTOR"  : None
337             },
338
339             "GZIP" : {
340                 "PRIORITY"       : 1,
341                 "SUFFIX"         : [".gz", ".gzip"],
342                 "EXTRACTSUFFIX"  : "",
343                 "EXTRACTFLAGS"   : "",
344                 "EXTRACTCMD"     : "${UNPACK['EXTRACTOR']['GZIP']['RUN']} ${UNPACK['EXTRACTOR']['GZIP']['EXTRACTFLAGS']} $SOURCE ${UNPACK['EXTRACTOR']['GZIP']['EXTRACTSUFFIX']}",
345                 "RUN"            : "",
346                 "LISTCMD"        : "${UNPACK['EXTRACTOR']['GZIP']['RUN']} ${UNPACK['EXTRACTOR']['GZIP']['LISTFLAGS']} $SOURCE ${UNPACK['EXTRACTOR']['GZIP']['LISTSUFFIX']}",
347                 "LISTSUFFIX"     : "",
348                 "LISTFLAGS"      : "",
349                 "LISTEXTRACTOR"  : None
350             },
351
352             "TAR" : {
353                 "PRIORITY"       : 1,
354                 "SUFFIX"         : [".tar"],
355                 "EXTRACTSUFFIX"  : "",
356                 "EXTRACTFLAGS"   : "",
357                 "EXTRACTCMD"     : "${UNPACK['EXTRACTOR']['TAR']['RUN']} ${UNPACK['EXTRACTOR']['TAR']['EXTRACTFLAGS']} $SOURCE ${UNPACK['EXTRACTOR']['TAR']['EXTRACTSUFFIX']}",
358                 "RUN"            : "",
359                 "LISTCMD"        : "${UNPACK['EXTRACTOR']['TAR']['RUN']} ${UNPACK['EXTRACTOR']['TAR']['LISTFLAGS']} $SOURCE ${UNPACK['EXTRACTOR']['TAR']['LISTSUFFIX']}",
360                 "LISTSUFFIX"     : "",
361                 "LISTFLAGS"      : "",
362                 "LISTEXTRACTOR"  : None
363             },
364
365             "ZIP" : {
366                 "PRIORITY"       : 1,
367                 "SUFFIX"         : [".zip"],
368                 "EXTRACTSUFFIX"  : "",
369                 "EXTRACTFLAGS"   : "",
370                 "EXTRACTCMD"     : "${UNPACK['EXTRACTOR']['ZIP']['RUN']} ${UNPACK['EXTRACTOR']['ZIP']['EXTRACTFLAGS']} $SOURCE ${UNPACK['EXTRACTOR']['ZIP']['EXTRACTSUFFIX']}",
371                 "RUN"            : "",
372                 "LISTCMD"        : "${UNPACK['EXTRACTOR']['ZIP']['RUN']} ${UNPACK['EXTRACTOR']['ZIP']['LISTFLAGS']} $SOURCE ${UNPACK['EXTRACTOR']['ZIP']['LISTSUFFIX']}",
373                 "LISTSUFFIX"     : "",
374                 "LISTFLAGS"      : "",
375                 "LISTEXTRACTOR"  : None
376             }
377         }
378     }
379
380     # read tools for Windows system
381     if env["PLATFORM"] <> "darwin" and "win" in env["PLATFORM"] :
382
383         if env.WhereIs('7z', env.get('PATH')):
384             toolset["EXTRACTOR"]["TARGZ"]["RUN"]           = "7z"
385             toolset["EXTRACTOR"]["TARGZ"]["LISTEXTRACTOR"] = __fileextractor_win_7zip
386             toolset["EXTRACTOR"]["TARGZ"]["LISTFLAGS"]     = "x"
387             toolset["EXTRACTOR"]["TARGZ"]["LISTSUFFIX"]    = "-so -y | ${UNPACK['EXTRACTOR']['TARGZ']['RUN']} l -sii -ttar -y -so"
388             toolset["EXTRACTOR"]["TARGZ"]["EXTRACTFLAGS"]  = "x"
389             toolset["EXTRACTOR"]["TARGZ"]["EXTRACTSUFFIX"] = "-so -y | ${UNPACK['EXTRACTOR']['TARGZ']['RUN']} x -sii -ttar -y -o${UNPACK['EXTRACTDIR']}"
390
391             toolset["EXTRACTOR"]["TARBZ"]["RUN"]           = "7z"
392             toolset["EXTRACTOR"]["TARBZ"]["LISTEXTRACTOR"] = __fileextractor_win_7zip
393             toolset["EXTRACTOR"]["TARBZ"]["LISTFLAGS"]     = "x"
394             toolset["EXTRACTOR"]["TARBZ"]["LISTSUFFIX"]    = "-so -y | ${UNPACK['EXTRACTOR']['TARGZ']['RUN']} l -sii -ttar -y -so"
395             toolset["EXTRACTOR"]["TARBZ"]["EXTRACTFLAGS"]  = "x"
396             toolset["EXTRACTOR"]["TARBZ"]["EXTRACTSUFFIX"] = "-so -y | ${UNPACK['EXTRACTOR']['TARGZ']['RUN']} x -sii -ttar -y -o${UNPACK['EXTRACTDIR']}"
397
398             toolset["EXTRACTOR"]["BZIP"]["RUN"]            = "7z"
399             toolset["EXTRACTOR"]["BZIP"]["LISTEXTRACTOR"]  = __fileextractor_win_7zip
400             toolset["EXTRACTOR"]["BZIP"]["LISTFLAGS"]      = "l"
401             toolset["EXTRACTOR"]["BZIP"]["LISTSUFFIX"]     = "-y -so"
402             toolset["EXTRACTOR"]["BZIP"]["EXTRACTFLAGS"]   = "x"
403             toolset["EXTRACTOR"]["BZIP"]["EXTRACTSUFFIX"]  = "-y -o${UNPACK['EXTRACTDIR']}"
404
405             toolset["EXTRACTOR"]["GZIP"]["RUN"]            = "7z"
406             toolset["EXTRACTOR"]["GZIP"]["LISTEXTRACTOR"]  = __fileextractor_win_7zip
407             toolset["EXTRACTOR"]["GZIP"]["LISTFLAGS"]      = "l"
408             toolset["EXTRACTOR"]["GZIP"]["LISTSUFFIX"]     = "-y -so"
409             toolset["EXTRACTOR"]["GZIP"]["EXTRACTFLAGS"]   = "x"
410             toolset["EXTRACTOR"]["GZIP"]["EXTRACTSUFFIX"]  = "-y -o${UNPACK['EXTRACTDIR']}"
411
412             toolset["EXTRACTOR"]["ZIP"]["RUN"]             = "7z"
413             toolset["EXTRACTOR"]["ZIP"]["LISTEXTRACTOR"]   = __fileextractor_win_7zip
414             toolset["EXTRACTOR"]["ZIP"]["LISTFLAGS"]       = "l"
415             toolset["EXTRACTOR"]["ZIP"]["LISTSUFFIX"]      = "-y -so"
416             toolset["EXTRACTOR"]["ZIP"]["EXTRACTFLAGS"]    = "x"
417             toolset["EXTRACTOR"]["ZIP"]["EXTRACTSUFFIX"]   = "-y -o${UNPACK['EXTRACTDIR']}"
418
419             toolset["EXTRACTOR"]["TAR"]["RUN"]             = "7z"
420             toolset["EXTRACTOR"]["TAR"]["LISTEXTRACTOR"]   = __fileextractor_win_7zip
421             toolset["EXTRACTOR"]["TAR"]["LISTFLAGS"]       = "l"
422             toolset["EXTRACTOR"]["TAR"]["LISTSUFFIX"]      = "-y -ttar -so"
423             toolset["EXTRACTOR"]["TAR"]["EXTRACTFLAGS"]    = "x"
424             toolset["EXTRACTOR"]["TAR"]["EXTRACTSUFFIX"]   = "-y -ttar -o${UNPACK['EXTRACTDIR']}"
425         else:
426             print '''*********************** Error ************************
427 *                                                    *
428 * Please make sure that 7-zip is in your System PATH *
429 *                                                    *
430 ******************************************************
431 '''
432
433         # here can add some other Windows tools, that can handle the archive files
434         # but I don't know which ones can handle all file types
435
436
437
438     # read the tools on *nix systems and sets the default parameters
439     elif env["PLATFORM"] in ["darwin", "linux", "posix", "msys"] :
440
441         if env.WhereIs("unzip") :
442             toolset["EXTRACTOR"]["ZIP"]["RUN"]             = "unzip"
443             toolset["EXTRACTOR"]["ZIP"]["LISTEXTRACTOR"]   = __fileextractor_nix_unzip
444             toolset["EXTRACTOR"]["ZIP"]["LISTFLAGS"]       = "-l"
445             toolset["EXTRACTOR"]["ZIP"]["EXTRACTFLAGS"]    = "-oqq"
446             toolset["EXTRACTOR"]["ZIP"]["EXTRACTSUFFIX"]   = "-d ${UNPACK['EXTRACTDIR']}"
447
448         if env.WhereIs("tar") :
449             toolset["EXTRACTOR"]["TAR"]["RUN"]             = "tar"
450             toolset["EXTRACTOR"]["TAR"]["LISTEXTRACTOR"]   = __fileextractor_nix_tar
451             toolset["EXTRACTOR"]["TAR"]["LISTFLAGS"]       = "tvf"
452             toolset["EXTRACTOR"]["TAR"]["EXTRACTFLAGS"]    = "xf"
453             toolset["EXTRACTOR"]["TAR"]["EXTRACTSUFFIX"]   = "-C ${UNPACK['EXTRACTDIR']}"
454
455             toolset["EXTRACTOR"]["TARGZ"]["RUN"]           = "tar"
456             toolset["EXTRACTOR"]["TARGZ"]["LISTEXTRACTOR"] = __fileextractor_nix_tar
457             toolset["EXTRACTOR"]["TARGZ"]["EXTRACTFLAGS"]  = "xfz"
458             toolset["EXTRACTOR"]["TARGZ"]["LISTFLAGS"]     = "tvfz"
459             toolset["EXTRACTOR"]["TARGZ"]["EXTRACTSUFFIX"] = "-C ${UNPACK['EXTRACTDIR']}"
460
461             toolset["EXTRACTOR"]["TARBZ"]["RUN"]           = "tar"
462             toolset["EXTRACTOR"]["TARBZ"]["LISTEXTRACTOR"] = __fileextractor_nix_tar
463             toolset["EXTRACTOR"]["TARBZ"]["EXTRACTFLAGS"]  = "xfj"
464             toolset["EXTRACTOR"]["TARBZ"]["LISTFLAGS"]     = "tvfj"
465             toolset["EXTRACTOR"]["TARBZ"]["EXTRACTSUFFIX"] = "-C ${UNPACK['EXTRACTDIR']}"
466
467         if env.WhereIs("bzip2") :
468             toolset["EXTRACTOR"]["BZIP"]["RUN"]            = "bzip2"
469             toolset["EXTRACTOR"]["BZIP"]["EXTRACTFLAGS"]   = "-df"
470
471         if env.WhereIs("gzip") :
472             toolset["EXTRACTOR"]["GZIP"]["RUN"]            = "gzip"
473             toolset["EXTRACTOR"]["GZIP"]["LISTEXTRACTOR"]  = __fileextractor_nix_gzip
474             toolset["EXTRACTOR"]["GZIP"]["LISTFLAGS"]      = "-l"
475             toolset["EXTRACTOR"]["GZIP"]["EXTRACTFLAGS"]   = "-df"
476
477     else :
478         raise SCons.Errors.StopError("Unpack tool detection on this platform [%s] unkown" % (env["PLATFORM"]))
479
480     # the target_factory must be a "Entry", because the target list can be files and dirs, so we can not specified the targetfactory explicite
481     env.Replace(UNPACK = toolset)
482     env.AddMethod(__unpack_all, 'UnpackAll')
483
484 #    env["BUILDERS"]["UnpackAll"] = SCons.Builder.Builder( action = __action,  emitter = __emitter,  target_factory = SCons.Node.FS.Entry,  source_factory = SCons.Node.FS.File,  single_source = True,  PRINT_CMD_LINE_FUNC = __message )
485
486
487 # existing function of the builder
488 # @param env environment object
489 # @return true
490 def exists(env) :
491     return 1
492
493 Import('env')
494 generate(env)