source: rtems-libbsd/builder.py @ 7c68f4e

55-freebsd-126-freebsd-12
Last change on this file since 7c68f4e was 445d59e, checked in by Sebastian Huber <sebastian.huber@…>, on 10/24/17 at 06:15:06

Remove ability to synchronize with Linux

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