source: rtems-libbsd/builder.py @ 9a583a9

55-freebsd-126-freebsd-12
Last change on this file since 9a583a9 was 79ec6b9, checked in by Sebastian Huber <sebastian.huber@…>, on 10/16/17 at 07:49:09

Install libpcap header files

  • Property mode set to 100755
File size: 29.6 KB
Line 
1#
2#  Copyright (c) 2015-2016 Chris Johns <chrisj@rtems.org>. All rights reserved.
3#
4#  Copyright (c) 2009-2015 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#
51RTEMS_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            '-Irtemsbsd/sys',
191            '-ImDNSResponder/mDNSCore',
192            '-ImDNSResponder/mDNSShared',
193            '-ImDNSResponder/mDNSPosix',
194            '-Itestsuite/include']
195
196def buildInclude():
197    """ Returns the path where headers will be copied during build. """
198    return 'build-include'
199
200def cpuIncludes():
201    return ['-Irtemsbsd/@CPU@/include',
202            '-Ifreebsd/sys/@CPU@/include']
203
204def cflags():
205    return []
206
207def cxxflags():
208    return []
209
210def headerPaths():
211    """ Returns a list of information about what header files should be
212    installed.
213
214    The list is also used to find headers with a local path that doesn't match
215    it's dest path. Due to the difference in the path name such files are
216    problematic during the build if they are included using their later
217    installation path (dest path) name. Therefore they are copied into a
218    sub-directory of the build path so that they can be included with their
219    normal installation path. """
220
221    #         local path                      wildcard             dest path
222    return [('rtemsbsd/include',              '**/*.h',            ''),
223            ('rtemsbsd/mghttpd',              'mongoose.h',        'mghttpd'),
224            ('freebsd/include',               '**/*.h',            ''),
225            ('freebsd/sys/bsm',               '**/*.h',            'bsm'),
226            ('freebsd/sys/cam',               '**/*.h',            'cam'),
227            ('freebsd/sys/net',               '**/*.h',            'net'),
228            ('freebsd/sys/net80211',          '**/*.h',            'net80211'),
229            ('freebsd/sys/netinet',           '**/*.h',            'netinet'),
230            ('freebsd/sys/netinet6',          '**/*.h',            'netinet6'),
231            ('freebsd/sys/netipsec',          '**/*.h',            'netipsec'),
232            ('freebsd/contrib/libpcap',       '*.h',               ''),
233            ('freebsd/contrib/libpcap/pcap',  '*.h',               'pcap'),
234            ('freebsd/crypto/openssl',        '*.h',               'openssl'),
235            ('freebsd/crypto/openssl/crypto', '*.h',               'openssl'),
236            ('freebsd/crypto/openssl/ssl',    '(ssl|kssl|ssl2).h', 'openssl'),
237            ('freebsd/crypto/openssl/crypto/aes', 'aes.h',         'openssl'),
238            ('freebsd/crypto/openssl/crypto/err', 'err.h',         'openssl'),
239            ('freebsd/crypto/openssl/crypto/bio', '*.h',           'openssl'),
240            ('freebsd/crypto/openssl/crypto/dsa', '*.h',           'openssl'),
241            ('freebsd/crypto/openssl/ssl',        '*.h',           'openssl'),
242            ('freebsd/crypto/openssl/crypto/bn',  'bn.h',          'openssl'),
243            ('freebsd/crypto/openssl/crypto/x509',  'x509.h',      'openssl'),
244            ('freebsd/crypto/openssl/crypto/cast',  'cast.h',      'openssl'),
245            ('freebsd/crypto/openssl/crypto/lhash', 'lhash.h',     'openssl'),
246            ('freebsd/crypto/openssl/crypto/ecdh',  'ecdh.h',      'openssl'),
247            ('freebsd/crypto/openssl/crypto/ecdsa', 'ecdsa.h',     'openssl'),
248            ('freebsd/crypto/openssl/crypto/idea',  'idea.h',      'openssl'),
249            ('freebsd/crypto/openssl/crypto/mdc2',  'mdc2.h',      'openssl'),
250            ('freebsd/crypto/openssl/crypto/md4',   'md4.h',       'openssl'),
251            ('freebsd/crypto/openssl/crypto/md5',   'md5.h',       'openssl'),
252            ('freebsd/crypto/openssl/crypto/rc2',   'rc2.h',       'openssl'),
253            ('freebsd/crypto/openssl/crypto/rc4',   'rc4.h',       'openssl'),
254            ('freebsd/crypto/openssl/crypto/ripemd','ripemd.h',    'openssl'),
255            ('freebsd/crypto/openssl/crypto/seed',  'seed.h',      'openssl'),
256            ('freebsd/crypto/openssl/crypto/sha',   'sha.h',       'openssl'),
257            ('freebsd/crypto/openssl/crypto/x509v3','x509v3.h',    'openssl'),
258            ('freebsd/crypto/openssl/crypto/x509',  'x509_vfy.h',  'openssl'),
259            ('freebsd/crypto/openssl/crypto/buffer','buffer.h',    'openssl'),
260            ('freebsd/crypto/openssl/crypto/comp',  'comp.h',      'openssl'),
261            ('freebsd/crypto/openssl/crypto/asn1',  'asn1_mac.h',  'openssl'),
262            ('freebsd/crypto/openssl/crypto/pem',  '(pem|pem2).h', 'openssl'),
263            ('freebsd/crypto/openssl/crypto/rsa',   'rsa.h',       'openssl'),
264            ('freebsd/crypto/openssl/crypto/evp',   'evp.h',       'openssl'),
265            ('freebsd/crypto/openssl/crypto/ec',    'ec.h',        'openssl'),
266            ('freebsd/crypto/openssl/crypto/engine', 'engine.h',   'openssl'),
267            ('freebsd/crypto/openssl/crypto/pkcs7', 'pkcs7.h',     'openssl'),
268            ('freebsd/crypto/openssl/crypto/hmac',  'hmac.h',      'openssl'),
269            ('freebsd/crypto/openssl/crypto/pqueue', 'pqueue.h',   'openssl'),
270            ('freebsd/crypto/openssl/crypto/ocsp',  'ocsp.h',      'openssl'),
271            ('freebsd/crypto/openssl/crypto/rand',  'rand.h',      'openssl'),
272            ('freebsd/crypto/openssl/crypto/srp',   'srp.h',       'openssl'),
273            ('freebsd/crypto/openssl/crypto/dh',    'dh.h',        'openssl'),
274            ('freebsd/crypto/openssl/crypto/dso',   'dso.h',       'openssl'),
275            ('freebsd/crypto/openssl/crypto/krb5',  'krb5_asn.h',  'openssl'),
276            ('freebsd/crypto/openssl/crypto/cms',   'cms.h',       'openssl'),
277            ('freebsd/crypto/openssl/crypto/txt_db', 'txt_db.h',   'openssl'),
278            ('freebsd/crypto/openssl/crypto/ts',    'ts.h',        'openssl'),
279            ('freebsd/crypto/openssl/crypto/modes', 'modes.h',     'openssl'),
280            ('freebsd/crypto/openssl/crypto/pkcs12', 'pkcs12.h',   'openssl'),
281            ('freebsd/crypto/openssl/crypto/bf',    'blowfish.h',  'openssl'),
282            ('freebsd/crypto/openssl/crypto/cmac',  'cmac.h',      'openssl'),
283            ('freebsd/crypto/openssl/crypto/asn1',  '(asn1|asn1t).h',            'openssl'),
284            ('freebsd/crypto/openssl/crypto/camellia', 'camellia.h',             'openssl'),
285            ('freebsd/crypto/openssl/crypto/objects',  '(objects|obj_mac).h',    'openssl'),
286            ('freebsd/crypto/openssl/crypto/conf',     '(conf|conf_api).h',      'openssl'),
287            ('freebsd/crypto/openssl/crypto/des',      '(des|des_old).h',        'openssl'),
288            ('freebsd/crypto/openssl/crypto/ui',       '(ui_compat|ui).h',       'openssl'),
289            ('freebsd/crypto/openssl/crypto/whrlpool', 'whrlpool.h',             'openssl'),
290            ('freebsd/crypto/openssl/crypto/stack',    '(stack|safestack).h',    'openssl'),
291            ('freebsd/crypto/openssl/crypto', '(opensslconf|opensslv|crypto).h', 'openssl'),
292            ('freebsd/sys/rpc',               '**/*.h',            'rpc'),
293            ('freebsd/sys/sys',               '**/*.h',            'sys'),
294            ('freebsd/sys/vm',                '**/*.h',            'vm'),
295            ('freebsd/sys/dev/mii',           '**/*.h',            'dev/mii'),
296            ('mDNSResponder/mDNSCore',        'mDNSDebug.h',       ''),
297            ('mDNSResponder/mDNSCore',        'mDNSEmbeddedAPI.h', ''),
298            ('mDNSResponder/mDNSShared',      'dns_sd.h',          ''),
299            ('mDNSResponder/mDNSPosix',       'mDNSPosix.h',       '')]
300
301# Move target dependent files under a machine directory
302def mapCPUDependentPath(path):
303  return path.replace("include/", "include/machine/")
304
305def fixIncludes(data):
306    data = re.sub('#include <sys/resource.h>', '#include <rtems/bsd/sys/resource.h>', data)
307    data = re.sub('#include <sys/unistd.h>',   '#include <rtems/bsd/sys/unistd.h>', data)
308    return data
309
310# revert fixing the include paths inside a C or .h file
311def revertFixIncludes(data):
312    data = re.sub('#include <rtems/bsd/',  '#include <', data)
313    data = re.sub('#include <util.h>',     '#include <rtems/bsd/util.h>', data)
314    data = re.sub('#include <bsd.h>',      '#include <rtems/bsd/bsd.h>', data)
315    data = re.sub('#include <zerocopy.h>', '#include <rtems/bsd/zerocopy.h>', data)
316    return data
317
318# fix include paths inside a C or .h file
319def fixLocalIncludes(data):
320    data = re.sub('#include "opt_([^"]*)"',    '#include <rtems/bsd/local/opt_\\1>', data)
321    data = re.sub('#include "([^"]*)_if.h"',   '#include <rtems/bsd/local/\\1_if.h>', data)
322    data = re.sub('#include "miidevs([^"]*)"', '#include <rtems/bsd/local/miidevs\\1>', data)
323    data = re.sub('#include "usbdevs([^"]*)"', '#include <rtems/bsd/local/usbdevs\\1>', data)
324    return data
325
326# revert fixing the include paths inside a C or .h file
327def revertFixLocalIncludes(data):
328    data = re.sub('#include <rtems/bsd/local/([^>]*)>', '#include "\\1"', data)
329    return data
330
331def assertHeaderFile(path):
332    if path[-2] != '.' or path[-1] != 'h':
333        print("*** " + path + " does not end in .h")
334        print("*** Move it to a C source file list")
335        sys.exit(2)
336
337def assertSourceFile(path):
338    if path[-2] != '.' or (path[-1] != 'c' and path[-1] != 'S'):
339        print("*** " + path + " does not end in .c")
340        print("*** Move it to a header file list")
341        sys.exit(2)
342
343def diffSource(dstLines, srcLines, src, dst):
344    global filesTotal, filesTotalLines, filesTotalInserts, filesTotalDeletes
345    #
346    # Diff, note there is no line termination on each string.  Expand the
347    # generator to list because the generator is not reusable.
348    #
349    diff = list(difflib.unified_diff(dstLines,
350                                     srcLines,
351                                     fromfile = src,
352                                     tofile = dst,
353                                     n = 5,
354                                     lineterm = ''))
355    inserts = 0
356    deletes = 0
357    if len(diff) > 0:
358        if src in diffDetails and \
359           diffDetails[src].dst != dst and diffDetails[src].diff != diff:
360            raise error('repeated diff of file different: src:%s dst:%s' % (src, dst))
361        for l in diff:
362            if l[0] == '-':
363                deletes += 1
364            elif l[0] == '+':
365                inserts += 1
366        diffDetails[src] = diffRecord(src, dst, srcLines, diff, inserts, deletes)
367
368    #
369    # Count the total files, lines and the level of changes.
370    #
371    filesTotal += 1
372    filesTotalLines += len(srcLines)
373    filesTotalInserts += inserts
374    filesTotalDeletes += deletes
375
376    return diff
377
378#
379# Converters provide a way to alter the various types of code. The conversion
380# process filters a file as it is copies from the source path to the
381# destination path. Specialised versions are provided for different types of
382# source.
383#
384class Converter(object):
385
386    def convert(self, src, dst, hasSource = True, sourceFilter = None, srcContents = None):
387
388        global filesProcessed, filesProcessedCount
389
390        if verbose(verboseDebug):
391            print("convert: filter:%s: %s -> %s" % \
392                  (['yes', 'no'][sourceFilter is None], src, dst))
393
394        #
395        # If there is no source raise an error if we expect source else print a
396        # warning and do not try and convert.
397        #
398        if srcContents is None:
399            if not os.path.exists(src):
400                if hasSource:
401                    raise error('source not found: %s' % (src))
402                else:
403                    print('warning: no source: %s' % (src))
404                    return
405
406            #
407            # Files read as a single string if not passed in.
408            #
409            srcContents = readFile(src)
410
411        if os.path.exists(dst):
412            dstContents = readFile(dst)
413        else:
414            print('warning: no destination: %s' % (dst))
415            dstContents = ''
416
417        #
418        # Filter the source.
419        #
420        if sourceFilter is not None:
421            srcContents = sourceFilter(srcContents)
422
423        #
424        # Split into a list of lines.
425        #
426        srcLines = srcContents.split(os.linesep)
427        dstLines = dstContents.split(os.linesep)
428
429        if verbose(verboseDebug):
430            print('Unified diff: %s (lines:%d)' % (src, len(srcLines)))
431
432        #
433        # Diff, note there is no line termination on each string.
434        #
435        diff = diffSource(dstLines, srcLines, src, dst)
436
437        #
438        # The diff list is empty if the files are the same.
439        #
440        if len(diff) > 0:
441
442            if verbose(verboseDebug):
443                print('Unified diff length: %d' % len(diff))
444
445            filesProcessed += [dst]
446            filesProcessedCount += 1
447            if isDiffMode == False:
448                if verbose(verboseDetail):
449                    print("UPDATE: %s -> %s" % (src, dst))
450                if isDryRun == False:
451                    writeFile(dst, srcContents)
452            else:
453                print("diff -u %s %s" % (src, dst))
454                for l in diff:
455                    print(l)
456
457class NoConverter(Converter):
458    def convert(self, src, dst, hasSource = True, sourceFilter = None):
459        return '/* EMPTY */\n'
460
461class FromFreeBSDToRTEMSHeaderConverter(Converter):
462    def sourceFilter(self, data):
463        data = fixLocalIncludes(data)
464        data = fixIncludes(data)
465        return data
466
467    def convert(self, src, dst):
468        sconverter = super(FromFreeBSDToRTEMSHeaderConverter, self)
469        sconverter.convert(src, dst, sourceFilter = self.sourceFilter)
470
471class FromFreeBSDToRTEMSUserSpaceHeaderConverter(Converter):
472    def sourceFilter(self, data):
473        data = fixIncludes(data)
474        return data
475
476    def convert(self, src, dst):
477        sconverter = super(FromFreeBSDToRTEMSUserSpaceHeaderConverter, self)
478        sconverter.convert(src, dst, sourceFilter = self.sourceFilter)
479
480class FromFreeBSDToRTEMSSourceConverter(Converter):
481    def sourceFilter(self, data):
482        data = fixLocalIncludes(data)
483        data = fixIncludes(data)
484        data = '#include <machine/rtems-bsd-kernel-space.h>\n\n' + data
485        return data
486
487    def convert(self, src, dst):
488        sconverter = super(FromFreeBSDToRTEMSSourceConverter, self)
489        sconverter.convert(src, dst, sourceFilter = self.sourceFilter)
490
491class FromFreeBSDToRTEMSUserSpaceSourceConverter(Converter):
492    def sourceFilter(self, data):
493        data = fixIncludes(data)
494        data = '#include <machine/rtems-bsd-user-space.h>\n\n' + data
495        return data
496
497    def convert(self, src, dst):
498        sconverter = super(FromFreeBSDToRTEMSUserSpaceSourceConverter, self)
499        sconverter.convert(src, dst, sourceFilter = self.sourceFilter)
500
501class FromRTEMSToFreeBSDHeaderConverter(Converter):
502    def sourceFilter(self, data):
503        data = revertFixLocalIncludes(data)
504        data = revertFixIncludes(data)
505        return data
506
507    def convert(self, src, dst):
508        sconverter = super(FromRTEMSToFreeBSDHeaderConverter, self)
509        sconverter.convert(src, dst, hasSource = False,  sourceFilter = self.sourceFilter)
510
511class FromRTEMSToFreeBSDSourceConverter(Converter):
512    def sourceFilter(self, data):
513        data = re.sub('#include <machine/rtems-bsd-kernel-space.h>\n\n', '', data)
514        data = re.sub('#include <machine/rtems-bsd-user-space.h>\n\n', '', data)
515        data = revertFixLocalIncludes(data)
516        data = revertFixIncludes(data)
517        return data
518
519    def convert(self, src, dst):
520        sconverter = super(FromRTEMSToFreeBSDSourceConverter, self)
521        sconverter.convert(src, dst, hasSource = False, sourceFilter = self.sourceFilter)
522
523#
524# Compose a path based for the various parts of the source tree.
525#
526class PathComposer(object):
527    def composeFreeBSDPath(self, path):
528        return path
529
530    def composeRTEMSPath(self, path, prefix):
531        return os.path.join(prefix, path)
532
533class FreeBSDPathComposer(PathComposer):
534    def composeFreeBSDPath(self, path):
535        return os.path.join(FreeBSD_DIR, path)
536
537    def composeRTEMSPath(self, path, prefix):
538        return os.path.join(prefix, 'freebsd', path)
539
540class RTEMSPathComposer(PathComposer):
541    def composeFreeBSDPath(self, path):
542        return path
543
544    def composeRTEMSPath(self, path, prefix):
545        return os.path.join(prefix, 'rtemsbsd', path)
546
547class CPUDependentPathComposer(FreeBSDPathComposer):
548    def composeRTEMSPath(self, path, prefix):
549        path = super(CPUDependentPathComposer, self).composeRTEMSPath(path, prefix)
550        path = mapCPUDependentPath(path)
551        return path
552
553class TargetSourceCPUDependentPathComposer(CPUDependentPathComposer):
554    def __init__(self, targetCPU, sourceCPU):
555        self.targetCPU = targetCPU
556        self.sourceCPU = sourceCPU
557
558    def composeRTEMSPath(self, path, prefix):
559        path = super(TargetSourceCPUDependentPathComposer, self).composeRTEMSPath(path, prefix)
560        path = path.replace(self.sourceCPU, self.targetCPU)
561        return path
562
563class BuildSystemFragmentComposer(object):
564    def __init__(self, includes = None):
565        if type(includes) is not list:
566            self.includes = [includes]
567        else:
568            self.includes = includes
569
570    def compose(self, path):
571        return ''
572
573#
574# File - a file in the source we move backwards and forwards.
575#
576class File(object):
577    def __init__(self, path, pathComposer,
578                 forwardConverter, reverseConverter, buildSystemComposer):
579        if verbose(verboseMoreDetail):
580            print("FILE: %-50s F:%-45s R:%-45s" % \
581                  (path,
582                   forwardConverter.__class__.__name__,
583                   reverseConverter.__class__.__name__))
584        self.path = path
585        self.pathComposer = pathComposer
586        self.freebsdPath = self.pathComposer.composeFreeBSDPath(self.path)
587        self.rtemsPath = self.pathComposer.composeRTEMSPath(self.path, RTEMS_DIR)
588        self.forwardConverter = forwardConverter
589        self.reverseConverter = reverseConverter
590        self.buildSystemComposer = buildSystemComposer
591
592    def processSource(self, forward):
593        if forward:
594            if verbose(verboseDetail):
595                print("process source: %s => %s" % (self.freebsdPath, self.rtemsPath))
596            self.forwardConverter.convert(self.freebsdPath, self.rtemsPath)
597        else:
598            if verbose(verboseDetail):
599                print("process source: %s => %s converter:%s" % \
600                      (self.rtemsPath, self.freebsdPath, self.reverseConverter.__class__.__name__))
601            self.reverseConverter.convert(self.rtemsPath, self.freebsdPath)
602
603    def getFragment(self):
604        return self.buildSystemComposer.compose(self.pathComposer.composeRTEMSPath(self.path, ''))
605
606#
607# Module - logical group of related files we can perform actions on
608#
609class Module:
610    def __init__(self, name):
611        self.name = name
612        self.conditionalOn = "none"
613        self.files = []
614        self.cpuDependentSourceFiles = {}
615        self.dependencies = []
616
617    def initCPUDependencies(self, cpu):
618        if cpu not in self.cpuDependentSourceFiles:
619            self.cpuDependentSourceFiles[cpu] = []
620
621    def processSource(self, direction):
622        if verbose(verboseDetail):
623            print("process module: %s" % (self.name))
624        for f in self.files:
625            f.processSource(direction)
626        for cpu, files in self.cpuDependentSourceFiles.items():
627            for f in files:
628                f.processSource(direction)
629
630    def addFiles(self, newFiles, buildSystemComposer = BuildSystemFragmentComposer()):
631        files = []
632        for newFile in newFiles:
633            assertFile(newFile)
634            files += [File(newFile, composers, buildSystemComposer)]
635        return files
636
637    def addFile(self, f):
638        self.files += [f]
639
640    def addFiles(self, newFiles,
641                 pathComposer, fromFreeBSDToRTEMSConverter, fromRTEMSToFreeBSDConverter,
642                 assertFile, buildSystemComposer = BuildSystemFragmentComposer()):
643        files = []
644        for newFile in newFiles:
645            assertFile(newFile)
646            files += [File(newFile, pathComposer, fromFreeBSDToRTEMSConverter,
647                           fromRTEMSToFreeBSDConverter, buildSystemComposer)]
648        return files
649
650    def addKernelSpaceHeaderFiles(self, files):
651        self.files += self.addFiles(files,
652                                    FreeBSDPathComposer(), FromFreeBSDToRTEMSHeaderConverter(),
653                                    FromRTEMSToFreeBSDHeaderConverter(), assertHeaderFile)
654
655    def addUserSpaceHeaderFiles(self, files):
656        self.files += self.addFiles(files,
657                                    FreeBSDPathComposer(), FromFreeBSDToRTEMSUserSpaceHeaderConverter(),
658                                    FromRTEMSToFreeBSDHeaderConverter(), assertHeaderFile)
659
660    def addRTEMSHeaderFiles(self, files):
661        self.files += self.addFiles(files, RTEMSPathComposer(),
662                                    NoConverter(), NoConverter(), assertHeaderFile)
663
664    def addCPUDependentHeaderFiles(self, files):
665        self.files += self.addFiles(files,
666                                    CPUDependentPathComposer(), FromFreeBSDToRTEMSHeaderConverter(),
667                                    FromRTEMSToFreeBSDHeaderConverter(), assertHeaderFile)
668
669    def addTargetSourceCPUDependentHeaderFiles(self, targetCPUs, sourceCPU, files):
670        for cpu in targetCPUs:
671            self.files += self.addFiles(files,
672                                        TargetSourceCPUDependentPathComposer(cpu, sourceCPU),
673                                        FromFreeBSDToRTEMSHeaderConverter(),
674                                        NoConverter(), assertHeaderFile)
675
676    def addSourceFiles(self, files, sourceFileFragmentComposer):
677        self.files += self.addFiles(files,
678                                    PathComposer(), NoConverter(), NoConverter(), assertSourceFile,
679                                    sourceFileFragmentComposer)
680
681    def addKernelSpaceSourceFiles(self, files, sourceFileFragmentComposer):
682        self.files += self.addFiles(files,
683                                    FreeBSDPathComposer(), FromFreeBSDToRTEMSSourceConverter(),
684                                    FromRTEMSToFreeBSDSourceConverter(), assertSourceFile,
685                                    sourceFileFragmentComposer)
686
687    def addUserSpaceSourceFiles(self, files, sourceFileFragmentComposer):
688        self.files += self.addFiles(files,
689                                    FreeBSDPathComposer(),
690                                    FromFreeBSDToRTEMSUserSpaceSourceConverter(),
691                                    FromRTEMSToFreeBSDSourceConverter(), assertSourceFile,
692                                    sourceFileFragmentComposer)
693
694    def addRTEMSSourceFiles(self, files, sourceFileFragmentComposer):
695        self.files += self.addFiles(files,
696                                    RTEMSPathComposer(), NoConverter(), NoConverter(),
697                                    assertSourceFile, sourceFileFragmentComposer)
698
699    def addCPUDependentSourceFiles(self, cpus, files, sourceFileFragmentComposer):
700        for cpu in cpus:
701            self.initCPUDependencies(cpu)
702            self.cpuDependentSourceFiles[cpu] += \
703                self.addFiles(files,
704                              CPUDependentPathComposer(), FromFreeBSDToRTEMSSourceConverter(),
705                              FromRTEMSToFreeBSDSourceConverter(), assertSourceFile,
706                              sourceFileFragmentComposer)
707
708    def addTest(self, testFragementComposer):
709        self.files += [File(testFragementComposer.testName,
710                            PathComposer(), NoConverter(), NoConverter(),
711                            testFragementComposer)]
712
713    def addDependency(self, dep):
714        self.dependencies += [dep]
715
716#
717# Manager - a collection of modules.
718#
719class ModuleManager:
720    def __init__(self):
721        self.modules = {}
722        self.generator = {}
723        self.setGenerators()
724
725    def __getitem__(self, key):
726        if key not in self.modules:
727            raise KeyError('module %s not found' % (key))
728        return self.modules[key]
729
730    def getModules(self):
731        return sorted(self.modules.keys())
732
733    def addModule(self, module):
734        self.modules[module.name] = module
735
736    def processSource(self, direction):
737        if verbose(verboseDetail):
738            print("process modules:")
739        for m in sorted(self.modules):
740            self.modules[m].processSource(direction)
Note: See TracBrowser for help on using the repository browser.