source: rtems-libbsd/builder.py @ a6a6d54

5-freebsd-12
Last change on this file since a6a6d54 was a6a6d54, checked in by Christian Mauderer <christian.mauderer@…>, on Mar 27, 2018 at 7:31:49 AM

waf: Fix freebsd-to-rtems.py.

Update #3351

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