source: rtems-libbsd/builder.py @ 23d6e50

5-freebsd-12
Last change on this file since 23d6e50 was 23d6e50, checked in by Sebastian Huber <sebastian.huber@…>, on Apr 3, 2017 at 1:18:09 PM

scripts: Support Linux import

  • Property mode set to 100755
File size: 31.5 KB
Line 
1#
2#  Copyright (c) 2015-2016 Chris Johns <chrisj@rtems.org>. All rights reserved.
3#
4#  Copyright (c) 2009, 2017 embedded brains GmbH.  All rights reserved.
5#
6#   embedded brains GmbH
7#   Dornierstr. 4
8#   82178 Puchheim
9#   Germany
10#   <info@embedded-brains.de>
11#
12#  Copyright (c) 2012 OAR Corporation. All rights reserved.
13#
14#  Redistribution and use in source and binary forms, with or without
15#  modification, are permitted provided that the following conditions
16#  are met:
17#  1. Redistributions of source code must retain the above copyright
18#     notice, this list of conditions and the following disclaimer.
19#  2. Redistributions in binary form must reproduce the above copyright
20#     notice, this list of conditions and the following disclaimer in the
21#     documentation and/or other materials provided with the distribution.
22#
23#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24#  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25#  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26#  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27#  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29#  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30#  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31#  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32#  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33#  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
35# FreeBSD: http://svn.freebsd.org/base/releng/8.2/sys (revision 222485)
36
37from __future__ import print_function
38
39import shutil
40import os
41import re
42import sys
43import getopt
44import filecmp
45import difflib
46import codecs
47
48#
49# Global controls.
50#
51LIBBSD_DIR = "."
52FreeBSD_DIR = "freebsd-org"
53Linux_DIR = "linux-org"
54verboseLevel = 0
55isDryRun = False
56isDiffMode = False
57filesProcessedCount = 0
58filesProcessed = []
59filesTotal = 0
60filesTotalLines = 0
61filesTotalInserts = 0
62filesTotalDeletes = 0
63diffDetails = { }
64
65verboseInfo = 1
66verboseDetail = 2
67verboseMoreDetail = 3
68verboseDebug = 4
69
70def verbose(level = verboseInfo):
71    return verboseLevel >= level
72
73def changedFileSummary(statsReport = False):
74
75    global filesTotal, filesTotalLines, filesTotalInserts, filesTotalDeletes
76
77    if isDiffMode == False:
78        if verbose():
79            print('%d file(s) were changed:' % (filesProcessedCount))
80            for f in sorted(filesProcessed):
81                print(' %s' % (f))
82        else:
83            print('%d file(s) were changed.' % (filesProcessedCount))
84    if statsReport:
85        print('Stats Report:')
86        transparent = filesTotal - len(diffDetails)
87        changes = filesTotalInserts + filesTotalDeletes
88        opacity = (float(changes) / (filesTotalLines + changes)) * 100.0
89        print(' Total File(s):%d  Unchanged:%d (%.1f%%)  Changed:%d' \
90              '   Opacity:%5.1f%% Lines:%d Edits:%d (+):%d (-):%d'  % \
91              (filesTotal, transparent, (float(transparent) / filesTotal) * 100.0, len(diffDetails), \
92               opacity, filesTotalLines, changes, filesTotalInserts, filesTotalDeletes))
93        #
94        # Sort by opacity.
95        #
96        ordered_diffs = sorted(diffDetails.items(), key = lambda diff: diff[1].opacity, reverse = True)
97        for f in ordered_diffs:
98            print(%s' % (diffDetails[f[0]].status()))
99
100def readFile(name):
101    try:
102        contents = codecs.open(name, mode = 'r', encoding = 'utf-8', errors = 'ignore').read()
103    except UnicodeDecodeError as ude:
104        print('error: reading: %s: %s' % (name, ude))
105        sys.exit(1)
106    return contents
107
108def writeFile(name, contents):
109    path = os.path.dirname(name)
110    if not os.path.exists(path):
111        try:
112            os.makedirs(path)
113        except OSError as oe:
114            print('error: cannot create directory: %s: %s' % (path, oe))
115            sys.exit(1)
116    try:
117        codecs.open(name, mode = 'w',  encoding = 'utf-8', errors = 'ignore').write(contents)
118    except UnicodeDecodeError as ude:
119        print('error: write: %s: %s' % (name, ude))
120        sys.exit(1)
121
122#
123# A builder error.
124#
125class error(Exception):
126    """Base class for exceptions."""
127    def __init__(self, msg):
128        self.msg = 'error: %s' % (msg)
129    def set_output(self, msg):
130        self.msg = msg
131    def __str__(self):
132        return self.msg
133
134#
135# Diff Record
136#
137class diffRecord:
138    def __init__(self, src, dst, orig, diff, inserts, deletes):
139        self.src = src
140        self.dst = dst
141        self.orig = orig
142        self.diff = diff
143        self.lines = len(orig)
144        self.inserts = inserts
145        self.deletes = deletes
146        self.changes = inserts + deletes
147        self.opacity = (float(self.changes) / (self.lines + self.changes)) * 100.0
148
149    def __repr__(self):
150        return self.src
151
152    def status(self):
153        return 'opacity:%5.1f%% edits:%4d (+):%-4d (-):%-4d %s' % \
154            (self.opacity, self.changes, self.inserts, self.deletes, self.src)
155
156#
157# This stuff needs to move to libbsd.py.
158#
159def commonFlags():
160    return ['-g',
161            '-fno-strict-aliasing',
162            '-ffreestanding',
163            '-fno-common']
164
165def commonWarnings():
166    return ['-Wall',
167            '-Wno-format',
168            '-Wno-pointer-sign']
169
170def commonNoWarnings():
171    return ['-w']
172
173def includes():
174    return ['-Irtemsbsd/include',
175            '-Ifreebsd/sys',
176            '-Ifreebsd/sys/contrib/pf',
177            '-Ifreebsd/sys/net',
178            '-Ifreebsd/include',
179            '-Ifreebsd/lib',
180            '-Ifreebsd/lib/libbsdstat',
181            '-Ifreebsd/lib/libc/include',
182            '-Ifreebsd/lib/libc/isc/include',
183            '-Ifreebsd/lib/libc/resolv',
184            '-Ifreebsd/lib/libutil',
185            '-Ifreebsd/lib/libkvm',
186            '-Ifreebsd/lib/libmemstat',
187            '-Ifreebsd/lib/libipsec',
188            '-Ifreebsd/contrib/expat/lib',
189            '-Ifreebsd/contrib/libpcap',
190            '-Ifreebsd/contrib/libxo',
191            '-Irtemsbsd/sys',
192            '-ImDNSResponder/mDNSCore',
193            '-ImDNSResponder/mDNSShared',
194            '-ImDNSResponder/mDNSPosix',
195            '-Itestsuite/include']
196
197def buildInclude():
198    """ Returns the path where headers will be copied during build. """
199    return 'build-include'
200
201def cpuIncludes():
202    return ['-Irtemsbsd/@CPU@/include',
203            '-Ifreebsd/sys/@CPU@/include']
204
205def cflags():
206    return []
207
208def cxxflags():
209    return []
210
211def headerPaths():
212    """ Returns a list of information about what header files should be
213    installed.
214
215    The list is also used to find headers with a local path that doesn't match
216    it's dest path. Due to the difference in the path name such files are
217    problematic during the build if they are included using their later
218    installation path (dest path) name. Therefore they are copied into a
219    sub-directory of the build path so that they can be included with their
220    normal installation path. """
221
222    #         local path                      wildcard             dest path
223    return [('rtemsbsd/include',              '**/*.h',            ''),
224            ('rtemsbsd/mghttpd',              'mongoose.h',        'mghttpd'),
225            ('freebsd/include',               '**/*.h',            ''),
226            ('freebsd/sys/bsm',               '**/*.h',            'bsm'),
227            ('freebsd/sys/cam',               '**/*.h',            'cam'),
228            ('freebsd/sys/net',               '**/*.h',            'net'),
229            ('freebsd/sys/net80211',          '**/*.h',            'net80211'),
230            ('freebsd/sys/netinet',           '**/*.h',            'netinet'),
231            ('freebsd/sys/netinet6',          '**/*.h',            'netinet6'),
232            ('freebsd/sys/netipsec',          '**/*.h',            'netipsec'),
233            ('freebsd/contrib/libpcap',       '*.h',               ''),
234            ('freebsd/contrib/libpcap/pcap',  '*.h',               'pcap'),
235            ('freebsd/crypto/openssl',        '*.h',               'openssl'),
236            ('freebsd/crypto/openssl/crypto', '*.h',               'openssl'),
237            ('freebsd/crypto/openssl/ssl',    '(ssl|kssl|ssl2).h', 'openssl'),
238            ('freebsd/crypto/openssl/crypto/aes', 'aes.h',         'openssl'),
239            ('freebsd/crypto/openssl/crypto/err', 'err.h',         'openssl'),
240            ('freebsd/crypto/openssl/crypto/bio', '*.h',           'openssl'),
241            ('freebsd/crypto/openssl/crypto/dsa', '*.h',           'openssl'),
242            ('freebsd/crypto/openssl/ssl',        '*.h',           'openssl'),
243            ('freebsd/crypto/openssl/crypto/bn',  'bn.h',          'openssl'),
244            ('freebsd/crypto/openssl/crypto/x509',  'x509.h',      'openssl'),
245            ('freebsd/crypto/openssl/crypto/cast',  'cast.h',      'openssl'),
246            ('freebsd/crypto/openssl/crypto/lhash', 'lhash.h',     'openssl'),
247            ('freebsd/crypto/openssl/crypto/ecdh',  'ecdh.h',      'openssl'),
248            ('freebsd/crypto/openssl/crypto/ecdsa', 'ecdsa.h',     'openssl'),
249            ('freebsd/crypto/openssl/crypto/idea',  'idea.h',      'openssl'),
250            ('freebsd/crypto/openssl/crypto/mdc2',  'mdc2.h',      'openssl'),
251            ('freebsd/crypto/openssl/crypto/md4',   'md4.h',       'openssl'),
252            ('freebsd/crypto/openssl/crypto/md5',   'md5.h',       'openssl'),
253            ('freebsd/crypto/openssl/crypto/rc2',   'rc2.h',       'openssl'),
254            ('freebsd/crypto/openssl/crypto/rc4',   'rc4.h',       'openssl'),
255            ('freebsd/crypto/openssl/crypto/ripemd','ripemd.h',    'openssl'),
256            ('freebsd/crypto/openssl/crypto/seed',  'seed.h',      'openssl'),
257            ('freebsd/crypto/openssl/crypto/sha',   'sha.h',       'openssl'),
258            ('freebsd/crypto/openssl/crypto/x509v3','x509v3.h',    'openssl'),
259            ('freebsd/crypto/openssl/crypto/x509',  'x509_vfy.h',  'openssl'),
260            ('freebsd/crypto/openssl/crypto/buffer','buffer.h',    'openssl'),
261            ('freebsd/crypto/openssl/crypto/comp',  'comp.h',      'openssl'),
262            ('freebsd/crypto/openssl/crypto/asn1',  'asn1_mac.h',  'openssl'),
263            ('freebsd/crypto/openssl/crypto/pem',  '(pem|pem2).h', 'openssl'),
264            ('freebsd/crypto/openssl/crypto/rsa',   'rsa.h',       'openssl'),
265            ('freebsd/crypto/openssl/crypto/evp',   'evp.h',       'openssl'),
266            ('freebsd/crypto/openssl/crypto/ec',    'ec.h',        'openssl'),
267            ('freebsd/crypto/openssl/crypto/engine', 'engine.h',   'openssl'),
268            ('freebsd/crypto/openssl/crypto/pkcs7', 'pkcs7.h',     'openssl'),
269            ('freebsd/crypto/openssl/crypto/hmac',  'hmac.h',      'openssl'),
270            ('freebsd/crypto/openssl/crypto/pqueue', 'pqueue.h',   'openssl'),
271            ('freebsd/crypto/openssl/crypto/ocsp',  'ocsp.h',      'openssl'),
272            ('freebsd/crypto/openssl/crypto/rand',  'rand.h',      'openssl'),
273            ('freebsd/crypto/openssl/crypto/srp',   'srp.h',       'openssl'),
274            ('freebsd/crypto/openssl/crypto/dh',    'dh.h',        'openssl'),
275            ('freebsd/crypto/openssl/crypto/dso',   'dso.h',       'openssl'),
276            ('freebsd/crypto/openssl/crypto/krb5',  'krb5_asn.h',  'openssl'),
277            ('freebsd/crypto/openssl/crypto/cms',   'cms.h',       'openssl'),
278            ('freebsd/crypto/openssl/crypto/txt_db', 'txt_db.h',   'openssl'),
279            ('freebsd/crypto/openssl/crypto/ts',    'ts.h',        'openssl'),
280            ('freebsd/crypto/openssl/crypto/modes', 'modes.h',     'openssl'),
281            ('freebsd/crypto/openssl/crypto/pkcs12', 'pkcs12.h',   'openssl'),
282            ('freebsd/crypto/openssl/crypto/bf',    'blowfish.h',  'openssl'),
283            ('freebsd/crypto/openssl/crypto/cmac',  'cmac.h',      'openssl'),
284            ('freebsd/crypto/openssl/crypto/asn1',  '(asn1|asn1t).h',            'openssl'),
285            ('freebsd/crypto/openssl/crypto/camellia', 'camellia.h',             'openssl'),
286            ('freebsd/crypto/openssl/crypto/objects',  '(objects|obj_mac).h',    'openssl'),
287            ('freebsd/crypto/openssl/crypto/conf',     '(conf|conf_api).h',      'openssl'),
288            ('freebsd/crypto/openssl/crypto/des',      '(des|des_old).h',        'openssl'),
289            ('freebsd/crypto/openssl/crypto/ui',       '(ui_compat|ui).h',       'openssl'),
290            ('freebsd/crypto/openssl/crypto/whrlpool', 'whrlpool.h',             'openssl'),
291            ('freebsd/crypto/openssl/crypto/stack',    '(stack|safestack).h',    'openssl'),
292            ('freebsd/crypto/openssl/crypto', '(opensslconf|opensslv|crypto).h', 'openssl'),
293            ('freebsd/sys/rpc',               '**/*.h',            'rpc'),
294            ('freebsd/sys/sys',               '**/*.h',            'sys'),
295            ('freebsd/sys/vm',                '**/*.h',            'vm'),
296            ('freebsd/sys/dev/mii',           '**/*.h',            'dev/mii'),
297            ('mDNSResponder/mDNSCore',        'mDNSDebug.h',       ''),
298            ('mDNSResponder/mDNSCore',        'mDNSEmbeddedAPI.h', ''),
299            ('mDNSResponder/mDNSShared',      'dns_sd.h',          ''),
300            ('mDNSResponder/mDNSPosix',       'mDNSPosix.h',       '')]
301
302# Move target dependent files under a machine directory
303def mapCPUDependentPath(path):
304  return path.replace("include/", "include/machine/")
305
306def fixIncludes(data):
307    data = re.sub('#include <sys/resource.h>', '#include <rtems/bsd/sys/resource.h>', data)
308    data = re.sub('#include <sys/unistd.h>',   '#include <rtems/bsd/sys/unistd.h>', data)
309    return data
310
311# revert fixing the include paths inside a C or .h file
312def revertFixIncludes(data):
313    data = re.sub('#include <rtems/bsd/',  '#include <', data)
314    data = re.sub('#include <util.h>',     '#include <rtems/bsd/util.h>', data)
315    data = re.sub('#include <bsd.h>',      '#include <rtems/bsd/bsd.h>', data)
316    data = re.sub('#include <zerocopy.h>', '#include <rtems/bsd/zerocopy.h>', data)
317    return data
318
319# fix include paths inside a C or .h file
320def fixLocalIncludes(data):
321    data = re.sub('#include "opt_([^"]*)"',    '#include <rtems/bsd/local/opt_\\1>', data)
322    data = re.sub('#include "([^"]*)_if.h"',   '#include <rtems/bsd/local/\\1_if.h>', data)
323    data = re.sub('#include "miidevs([^"]*)"', '#include <rtems/bsd/local/miidevs\\1>', data)
324    data = re.sub('#include "usbdevs([^"]*)"', '#include <rtems/bsd/local/usbdevs\\1>', data)
325    return data
326
327# revert fixing the include paths inside a C or .h file
328def revertFixLocalIncludes(data):
329    data = re.sub('#include <rtems/bsd/local/([^>]*)>', '#include "\\1"', data)
330    return data
331
332def assertHeaderFile(path):
333    if path[-2] != '.' or path[-1] != 'h':
334        print("*** " + path + " does not end in .h")
335        print("*** Move it to a C source file list")
336        sys.exit(2)
337
338def assertSourceFile(path):
339    if path[-2] != '.' or (path[-1] != 'c' and path[-1] != 'S'):
340        print("*** " + path + " does not end in .c")
341        print("*** Move it to a header file list")
342        sys.exit(2)
343
344def diffSource(dstLines, srcLines, src, dst):
345    global filesTotal, filesTotalLines, filesTotalInserts, filesTotalDeletes
346    #
347    # Diff, note there is no line termination on each string.  Expand the
348    # generator to list because the generator is not reusable.
349    #
350    diff = list(difflib.unified_diff(dstLines,
351                                     srcLines,
352                                     fromfile = src,
353                                     tofile = dst,
354                                     n = 5,
355                                     lineterm = ''))
356    inserts = 0
357    deletes = 0
358    if len(diff) > 0:
359        if src in diffDetails and \
360           diffDetails[src].dst != dst and diffDetails[src].diff != diff:
361            raise error('repeated diff of file different: src:%s dst:%s' % (src, dst))
362        for l in diff:
363            if l[0] == '-':
364                deletes += 1
365            elif l[0] == '+':
366                inserts += 1
367        diffDetails[src] = diffRecord(src, dst, srcLines, diff, inserts, deletes)
368
369    #
370    # Count the total files, lines and the level of changes.
371    #
372    filesTotal += 1
373    filesTotalLines += len(srcLines)
374    filesTotalInserts += inserts
375    filesTotalDeletes += deletes
376
377    return diff
378
379#
380# Converters provide a way to alter the various types of code. The conversion
381# process filters a file as it is copies from the source path to the
382# destination path. Specialised versions are provided for different types of
383# source.
384#
385class Converter(object):
386
387    def convert(self, src, dst, hasSource = True, sourceFilter = None, srcContents = None):
388
389        global filesProcessed, filesProcessedCount
390
391        if verbose(verboseDebug):
392            print("convert: filter:%s: %s -> %s" % \
393                  (['yes', 'no'][sourceFilter is None], src, dst))
394
395        #
396        # If there is no source raise an error if we expect source else print a
397        # warning and do not try and convert.
398        #
399        if srcContents is None:
400            if not os.path.exists(src):
401                if hasSource:
402                    raise error('source not found: %s' % (src))
403                else:
404                    print('warning: no source: %s' % (src))
405                    return
406
407            #
408            # Files read as a single string if not passed in.
409            #
410            srcContents = readFile(src)
411
412        if os.path.exists(dst):
413            dstContents = readFile(dst)
414        else:
415            print('warning: no destination: %s' % (dst))
416            dstContents = ''
417
418        #
419        # Filter the source.
420        #
421        if sourceFilter is not None:
422            srcContents = sourceFilter(srcContents)
423
424        #
425        # Split into a list of lines.
426        #
427        srcLines = srcContents.split(os.linesep)
428        dstLines = dstContents.split(os.linesep)
429
430        if verbose(verboseDebug):
431            print('Unified diff: %s (lines:%d)' % (src, len(srcLines)))
432
433        #
434        # Diff, note there is no line termination on each string.
435        #
436        diff = diffSource(dstLines, srcLines, src, dst)
437
438        #
439        # The diff list is empty if the files are the same.
440        #
441        if len(diff) > 0:
442
443            if verbose(verboseDebug):
444                print('Unified diff length: %d' % len(diff))
445
446            filesProcessed += [dst]
447            filesProcessedCount += 1
448            if isDiffMode == False:
449                if verbose(verboseDetail):
450                    print("UPDATE: %s -> %s" % (src, dst))
451                if isDryRun == False:
452                    writeFile(dst, srcContents)
453            else:
454                print("diff -u %s %s" % (src, dst))
455                for l in diff:
456                    print(l)
457
458class NoConverter(Converter):
459    def convert(self, src, dst, hasSource = True, sourceFilter = None):
460        return '/* EMPTY */\n'
461
462class FromFreeBSDToRTEMSHeaderConverter(Converter):
463    def sourceFilter(self, data):
464        data = fixLocalIncludes(data)
465        data = fixIncludes(data)
466        return data
467
468    def convert(self, src, dst):
469        sconverter = super(FromFreeBSDToRTEMSHeaderConverter, self)
470        sconverter.convert(src, dst, sourceFilter = self.sourceFilter)
471
472class FromFreeBSDToRTEMSUserSpaceHeaderConverter(Converter):
473    def sourceFilter(self, data):
474        data = fixIncludes(data)
475        return data
476
477    def convert(self, src, dst):
478        sconverter = super(FromFreeBSDToRTEMSUserSpaceHeaderConverter, self)
479        sconverter.convert(src, dst, sourceFilter = self.sourceFilter)
480
481class FromFreeBSDToRTEMSSourceConverter(Converter):
482    def sourceFilter(self, data):
483        data = fixLocalIncludes(data)
484        data = fixIncludes(data)
485        data = '#include <machine/rtems-bsd-kernel-space.h>\n\n' + data
486        return data
487
488    def convert(self, src, dst):
489        sconverter = super(FromFreeBSDToRTEMSSourceConverter, self)
490        sconverter.convert(src, dst, sourceFilter = self.sourceFilter)
491
492class FromFreeBSDToRTEMSUserSpaceSourceConverter(Converter):
493    def sourceFilter(self, data):
494        data = fixIncludes(data)
495        data = '#include <machine/rtems-bsd-user-space.h>\n\n' + data
496        return data
497
498    def convert(self, src, dst):
499        sconverter = super(FromFreeBSDToRTEMSUserSpaceSourceConverter, self)
500        sconverter.convert(src, dst, sourceFilter = self.sourceFilter)
501
502class FromRTEMSToFreeBSDHeaderConverter(Converter):
503    def sourceFilter(self, data):
504        data = revertFixLocalIncludes(data)
505        data = revertFixIncludes(data)
506        return data
507
508    def convert(self, src, dst):
509        sconverter = super(FromRTEMSToFreeBSDHeaderConverter, self)
510        sconverter.convert(src, dst, hasSource = False,  sourceFilter = self.sourceFilter)
511
512class FromRTEMSToFreeBSDSourceConverter(Converter):
513    def sourceFilter(self, data):
514        data = re.sub('#include <machine/rtems-bsd-kernel-space.h>\n\n', '', data)
515        data = re.sub('#include <machine/rtems-bsd-user-space.h>\n\n', '', data)
516        data = revertFixLocalIncludes(data)
517        data = revertFixIncludes(data)
518        return data
519
520    def convert(self, src, dst):
521        sconverter = super(FromRTEMSToFreeBSDSourceConverter, self)
522        sconverter.convert(src, dst, hasSource = False, sourceFilter = self.sourceFilter)
523
524#
525# Compose a path based for the various parts of the source tree.
526#
527class PathComposer(object):
528    def composeOriginPath(self, path):
529        return path
530
531    def composeLibBSDPath(self, path, prefix):
532        return os.path.join(prefix, path)
533
534class FreeBSDPathComposer(PathComposer):
535    def composeOriginPath(self, path):
536        return os.path.join(FreeBSD_DIR, path)
537
538    def composeLibBSDPath(self, path, prefix):
539        return os.path.join(prefix, 'freebsd', path)
540
541class RTEMSPathComposer(PathComposer):
542    def composeOriginPath(self, path):
543        return path
544
545    def composeLibBSDPath(self, path, prefix):
546        return os.path.join(prefix, 'rtemsbsd', path)
547
548class LinuxPathComposer(PathComposer):
549    def composeOriginPath(self, path):
550        return os.path.join(Linux_DIR, path)
551
552    def composeLibBSDPath(self, path, prefix):
553        return os.path.join(prefix, 'linux', path)
554
555class CPUDependentFreeBSDPathComposer(FreeBSDPathComposer):
556    def composeLibBSDPath(self, path, prefix):
557        path = super(CPUDependentFreeBSDPathComposer, self).composeLibBSDPath(path, prefix)
558        path = mapCPUDependentPath(path)
559        return path
560
561class CPUDependentLinuxPathComposer(LinuxPathComposer):
562    def composeLibBSDPath(self, path, prefix):
563        path = super(CPUDependentLinuxPathComposer, self).composeLibBSDPath(path, prefix)
564        path = mapCPUDependentPath(path)
565        return path
566
567class TargetSourceCPUDependentPathComposer(CPUDependentFreeBSDPathComposer):
568    def __init__(self, targetCPU, sourceCPU):
569        self.targetCPU = targetCPU
570        self.sourceCPU = sourceCPU
571
572    def composeLibBSDPath(self, path, prefix):
573        path = super(TargetSourceCPUDependentPathComposer, self).composeLibBSDPath(path, prefix)
574        path = path.replace(self.sourceCPU, self.targetCPU)
575        return path
576
577class BuildSystemFragmentComposer(object):
578    def __init__(self, includes = None):
579        if type(includes) is not list:
580            self.includes = [includes]
581        else:
582            self.includes = includes
583
584    def compose(self, path):
585        return ''
586
587#
588# File - a file in the source we move backwards and forwards.
589#
590class File(object):
591    def __init__(self, path, pathComposer,
592                 forwardConverter, reverseConverter, buildSystemComposer):
593        if verbose(verboseMoreDetail):
594            print("FILE: %-50s F:%-45s R:%-45s" % \
595                  (path,
596                   forwardConverter.__class__.__name__,
597                   reverseConverter.__class__.__name__))
598        self.path = path
599        self.pathComposer = pathComposer
600        self.originPath = self.pathComposer.composeOriginPath(self.path)
601        self.libbsdPath = self.pathComposer.composeLibBSDPath(self.path, LIBBSD_DIR)
602        self.forwardConverter = forwardConverter
603        self.reverseConverter = reverseConverter
604        self.buildSystemComposer = buildSystemComposer
605
606    def processSource(self, forward):
607        if forward:
608            if verbose(verboseDetail):
609                print("process source: %s => %s" % (self.originPath, self.libbsdPath))
610            self.forwardConverter.convert(self.originPath, self.libbsdPath)
611        else:
612            if verbose(verboseDetail):
613                print("process source: %s => %s converter:%s" % \
614                      (self.libbsdPath, self.originPath, self.reverseConverter.__class__.__name__))
615            self.reverseConverter.convert(self.libbsdPath, self.originPath)
616
617    def getFragment(self):
618        return self.buildSystemComposer.compose(self.pathComposer.composeLibBSDPath(self.path, ''))
619
620#
621# Module - logical group of related files we can perform actions on
622#
623class Module:
624    def __init__(self, name):
625        self.name = name
626        self.conditionalOn = "none"
627        self.files = []
628        self.cpuDependentSourceFiles = {}
629        self.dependencies = []
630
631    def initCPUDependencies(self, cpu):
632        if cpu not in self.cpuDependentSourceFiles:
633            self.cpuDependentSourceFiles[cpu] = []
634
635    def processSource(self, direction):
636        if verbose(verboseDetail):
637            print("process module: %s" % (self.name))
638        for f in self.files:
639            f.processSource(direction)
640        for cpu, files in self.cpuDependentSourceFiles.items():
641            for f in files:
642                f.processSource(direction)
643
644    def addFiles(self, newFiles, buildSystemComposer = BuildSystemFragmentComposer()):
645        files = []
646        for newFile in newFiles:
647            assertFile(newFile)
648            files += [File(newFile, composers, buildSystemComposer)]
649        return files
650
651    def addFile(self, f):
652        self.files += [f]
653
654    def addFiles(self, newFiles,
655                 pathComposer, forwardConverter, reverseConverter,
656                 assertFile, buildSystemComposer = BuildSystemFragmentComposer()):
657        files = []
658        for newFile in newFiles:
659            assertFile(newFile)
660            files += [File(newFile, pathComposer, forwardConverter,
661                           reverseConverter, buildSystemComposer)]
662        return files
663
664    def addKernelSpaceHeaderFiles(self, files):
665        self.files += self.addFiles(files,
666                                    FreeBSDPathComposer(), FromFreeBSDToRTEMSHeaderConverter(),
667                                    FromRTEMSToFreeBSDHeaderConverter(), assertHeaderFile)
668
669    def addUserSpaceHeaderFiles(self, files):
670        self.files += self.addFiles(files,
671                                    FreeBSDPathComposer(), FromFreeBSDToRTEMSUserSpaceHeaderConverter(),
672                                    FromRTEMSToFreeBSDHeaderConverter(), assertHeaderFile)
673
674    def addRTEMSHeaderFiles(self, files):
675        self.files += self.addFiles(files, RTEMSPathComposer(),
676                                    NoConverter(), NoConverter(), assertHeaderFile)
677
678    def addLinuxHeaderFiles(self, files):
679        self.files += self.addFiles(files,
680                                    LinuxPathComposer(), FromFreeBSDToRTEMSHeaderConverter(),
681                                    FromRTEMSToFreeBSDHeaderConverter(), assertHeaderFile)
682
683    def addCPUDependentFreeBSDHeaderFiles(self, files):
684        self.files += self.addFiles(files,
685                                    CPUDependentFreeBSDPathComposer(), FromFreeBSDToRTEMSHeaderConverter(),
686                                    FromRTEMSToFreeBSDHeaderConverter(), assertHeaderFile)
687
688    def addCPUDependentLinuxHeaderFiles(self, files):
689        self.files += self.addFiles(files,
690                                    CPUDependentLinuxPathComposer(), FromFreeBSDToRTEMSHeaderConverter(),
691                                    FromRTEMSToFreeBSDHeaderConverter(), assertHeaderFile)
692
693    def addTargetSourceCPUDependentHeaderFiles(self, targetCPUs, sourceCPU, files):
694        for cpu in targetCPUs:
695            self.files += self.addFiles(files,
696                                        TargetSourceCPUDependentPathComposer(cpu, sourceCPU),
697                                        FromFreeBSDToRTEMSHeaderConverter(),
698                                        NoConverter(), assertHeaderFile)
699
700    def addSourceFiles(self, files, sourceFileFragmentComposer):
701        self.files += self.addFiles(files,
702                                    PathComposer(), NoConverter(), NoConverter(), assertSourceFile,
703                                    sourceFileFragmentComposer)
704
705    def addKernelSpaceSourceFiles(self, files, sourceFileFragmentComposer):
706        self.files += self.addFiles(files,
707                                    FreeBSDPathComposer(), FromFreeBSDToRTEMSSourceConverter(),
708                                    FromRTEMSToFreeBSDSourceConverter(), assertSourceFile,
709                                    sourceFileFragmentComposer)
710
711    def addUserSpaceSourceFiles(self, files, sourceFileFragmentComposer):
712        self.files += self.addFiles(files,
713                                    FreeBSDPathComposer(),
714                                    FromFreeBSDToRTEMSUserSpaceSourceConverter(),
715                                    FromRTEMSToFreeBSDSourceConverter(), assertSourceFile,
716                                    sourceFileFragmentComposer)
717
718    def addRTEMSSourceFiles(self, files, sourceFileFragmentComposer):
719        self.files += self.addFiles(files,
720                                    RTEMSPathComposer(), NoConverter(), NoConverter(),
721                                    assertSourceFile, sourceFileFragmentComposer)
722
723    def addLinuxSourceFiles(self, files, sourceFileFragmentComposer):
724        self.files += self.addFiles(files,
725                                    LinuxPathComposer(), FromFreeBSDToRTEMSSourceConverter(),
726                                    FromRTEMSToFreeBSDSourceConverter(), assertSourceFile,
727                                    sourceFileFragmentComposer)
728
729    def addCPUDependentFreeBSDSourceFiles(self, cpus, files, sourceFileFragmentComposer):
730        for cpu in cpus:
731            self.initCPUDependencies(cpu)
732            self.cpuDependentSourceFiles[cpu] += \
733                self.addFiles(files,
734                              CPUDependentFreeBSDPathComposer(), FromFreeBSDToRTEMSSourceConverter(),
735                              FromRTEMSToFreeBSDSourceConverter(), assertSourceFile,
736                              sourceFileFragmentComposer)
737
738    def addCPUDependentLinuxSourceFiles(self, cpus, files, sourceFileFragmentComposer):
739        for cpu in cpus:
740            self.initCPUDependencies(cpu)
741            self.cpuDependentSourceFiles[cpu] += \
742                self.addFiles(files,
743                              CPUDependentLinuxPathComposer(), FromFreeBSDToRTEMSSourceConverter(),
744                              FromRTEMSToFreeBSDSourceConverter(), assertSourceFile,
745                              sourceFileFragmentComposer)
746
747    def addTest(self, testFragementComposer):
748        self.files += [File(testFragementComposer.testName,
749                            PathComposer(), NoConverter(), NoConverter(),
750                            testFragementComposer)]
751
752    def addDependency(self, dep):
753        self.dependencies += [dep]
754
755#
756# Manager - a collection of modules.
757#
758class ModuleManager:
759    def __init__(self):
760        self.modules = {}
761        self.generator = {}
762        self.setGenerators()
763
764    def __getitem__(self, key):
765        if key not in self.modules:
766            raise KeyError('module %s not found' % (key))
767        return self.modules[key]
768
769    def getModules(self):
770        return sorted(self.modules.keys())
771
772    def addModule(self, module):
773        self.modules[module.name] = module
774
775    def processSource(self, direction):
776        if verbose(verboseDetail):
777            print("process modules:")
778        for m in sorted(self.modules):
779            self.modules[m].processSource(direction)
Note: See TracBrowser for help on using the repository browser.