changeset 348:442fb043d149

Added log option to zcc
author Windel Bouwman
date Sat, 08 Mar 2014 15:32:33 +0100
parents 3bb7dcfe5529
children 13a6e73b448f
files python/ppci/buildtasks.py python/ppci/codegen/codegen.py python/ppci/linker.py python/ppci/outstream.py python/zcc.py test/testarmasm.py test/testasm.py test/testmsp430asm.py test/testthumbasm.py
diffstat 9 files changed, 64 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/python/ppci/buildtasks.py	Fri Mar 07 17:05:32 2014 +0100
+++ b/python/ppci/buildtasks.py	Sat Mar 08 15:32:33 2014 +0100
@@ -15,7 +15,7 @@
 from .assembler import Assembler
 from .objectfile import ObjectFile
 from .linker import Linker
-from .outstream import BinaryOutputStream
+from .outstream import BinaryOutputStream, MasterOutputStream, LoggerOutputStream
 
 
 class BuildTask(Task):
@@ -36,7 +36,7 @@
         self.assembler = Assembler(target)
 
     def run(self):
-        self.ostream.selectSection('code')
+        self.ostream.select_section('code')
         self.assembler.assemble(self.source, self.ostream)
 
 
@@ -74,7 +74,12 @@
             # Code generation:
             d = {'ircode':ircode}
             self.logger.debug('Starting code generation for {}'.format(ircode), extra=d)
-            o = BinaryOutputStream(self.output)
+
+            o2 = BinaryOutputStream(self.output)
+            o1 = LoggerOutputStream()
+            o = MasterOutputStream()
+            o.add_substream(o1)
+            o.add_substream(o2)
             cg.generate(ircode, o)
 
         if not c3b.ok:
--- a/python/ppci/codegen/codegen.py	Fri Mar 07 17:05:32 2014 +0100
+++ b/python/ppci/codegen/codegen.py	Sat Mar 08 15:32:33 2014 +0100
@@ -49,7 +49,7 @@
     def generate(self, ircode, outs):
         """ Generate code into output stream """
         assert isinstance(ircode, ir.Module)
-        outs.selectSection('code')
+        outs.select_section('code')
 
         # Munch program into a bunch of frames. One frame per function.
         # Each frame has a flat list of abstract instructions.
--- a/python/ppci/linker.py	Fri Mar 07 17:05:32 2014 +0100
+++ b/python/ppci/linker.py	Sat Mar 08 15:32:33 2014 +0100
@@ -1,4 +1,4 @@
-
+import logging
 import struct
 from .objectfile import ObjectFile
 from . import CompilerError
@@ -92,6 +92,9 @@
 class Linker:
     """ Merges the sections of several object files and 
         performs relocation """
+    def __init__(self):
+        self.logger = logging.getLogger('Linker')
+
     def link(self, objs, layout={}):
         # Create new object file to store output:
         self.dst = ObjectFile()
@@ -113,7 +116,7 @@
                 # Add new section:
                 offsets[in_s.name] = out_s.Size
                 out_s.add_data(in_s.data)
-
+                self.logger.debug('{} {}({})'.format(offsets[in_s.name], iobj, in_s.name))
 
             # Merge symbols:
             for sym in iobj.symbols.values():
--- a/python/ppci/outstream.py	Fri Mar 07 17:05:32 2014 +0100
+++ b/python/ppci/outstream.py	Sat Mar 08 15:32:33 2014 +0100
@@ -1,3 +1,4 @@
+import logging
 import binascii
 from ppci.target import Instruction, Alignment
 from ppci.objectfile import ObjectFile
@@ -12,7 +13,7 @@
     def emit(self, item):
         raise NotImplementedError('Abstract base class')
 
-    def selectSection(self, sname):
+    def select_section(self, sname):
         raise NotImplementedError('Abstract base class')
 
 
@@ -63,13 +64,43 @@
             while section.Size % item.align != 0:
                 section.add_data(bytes([0]))
 
-    def selectSection(self, sname):
+    def select_section(self, sname):
         self.currentSection = self.obj_file.get_section(sname)
 
 
 class DummyOutputStream(OutputStream):
+    """ Stream that implements the bare minimum and does nothing """
     def emit(self, item):
         pass
 
-    def selectSection(self, sname):
+    def select_section(self, sname):
         pass
+
+
+class LoggerOutputStream(OutputStream):
+    """ Stream that emits instructions as text in the log """
+    def __init__(self):
+        self.logger = logging.getLogger('LoggerOutputStream')
+
+    def emit(self, item):
+        self.logger.debug(str(item))
+
+    def select_section(self, sname):
+        self.logger.debug('.section {}'.format(sname))
+
+
+class MasterOutputStream(OutputStream):
+    """ Stream that emits to multiple sub streams """
+    def __init__(self):
+        self.substreams = []
+
+    def add_substream(self, output_stream):
+        self.substreams.append(output_stream)
+
+    def emit(self, item):
+        for output_stream in self.substreams:
+            output_stream.emit(item)
+
+    def select_section(self, sname):
+        for output_stream in self.substreams:
+            output_stream.select_section(sname)
--- a/python/zcc.py	Fri Mar 07 17:05:32 2014 +0100
+++ b/python/zcc.py	Sat Mar 08 15:32:33 2014 +0100
@@ -31,6 +31,9 @@
     parser.add_argument('--log', help='Log level (INFO,DEBUG,[WARN])',
                         type=logLevel, default='INFO')
     parser.add_argument('--display-build-steps', action='store_true')
+    parser.add_argument('--report',
+                help='Specify a file to write the compile report to',
+                type=argparse.FileType('w'))
     sub_parsers = parser.add_subparsers(title='commands',
          description='possible commands', dest='command')
     recipe_parser = sub_parsers.add_parser('recipe', help="Bake recipe")
@@ -45,13 +48,9 @@
         choices=targetnames, required=True)
     compile_parser.add_argument('-o', '--output', help='Output file',
         metavar='filename')
-    compile_parser.add_argument('--report',
-                help='Specify a file to write the compile report to',
-                type=argparse.FileType('w'))
     return parser
 
 
-
 def main(args):
     # Configure some logging:
     logging.getLogger().setLevel(logging.DEBUG)
@@ -60,6 +59,11 @@
     ch.setLevel(args.log)
     logging.getLogger().addHandler(ch)
 
+    if args.report:
+        fh = logging.StreamHandler(args.report)
+        fh.setFormatter(RstFormatter())
+        logging.getLogger().addHandler(fh)
+
     runner = TaskRunner()
     if args.command == 'compile':
         tg = targets[args.target]
@@ -77,6 +81,10 @@
     else:
         res = runner.run_tasks()
 
+    if args.report:
+        logging.getLogger().removeHandler(fh)
+        args.report.close()
+
     logging.getLogger().removeHandler(ch)
     return res
 
--- a/test/testarmasm.py	Fri Mar 07 17:05:32 2014 +0100
+++ b/test/testarmasm.py	Sat Mar 08 15:32:33 2014 +0100
@@ -14,7 +14,7 @@
         self.t = arm_target
         self.obj = ObjectFile()
         self.ostream = BinaryOutputStream(self.obj)
-        self.ostream.selectSection('.text')
+        self.ostream.select_section('.text')
         self.a = a #Assembler(target=self.t)
 
     def testMovImm(self):
--- a/test/testasm.py	Fri Mar 07 17:05:32 2014 +0100
+++ b/test/testasm.py	Sat Mar 08 15:32:33 2014 +0100
@@ -96,7 +96,7 @@
     def test1(self):
         obj = ObjectFile()
         o = BinaryOutputStream(obj)
-        o.selectSection('.text')
+        o.select_section('.text')
         o.emit(Label('a'))
         self.assertSequenceEqual(bytes(), obj.get_section('.text').data)
 
--- a/test/testmsp430asm.py	Fri Mar 07 17:05:32 2014 +0100
+++ b/test/testmsp430asm.py	Sat Mar 08 15:32:33 2014 +0100
@@ -14,7 +14,7 @@
         self.t = msp430target
         self.obj = ObjectFile()
         self.ostream = BinaryOutputStream(self.obj)
-        self.ostream.selectSection('.text')
+        self.ostream.select_section('.text')
         self.a = a
 
     def testMov(self):
--- a/test/testthumbasm.py	Fri Mar 07 17:05:32 2014 +0100
+++ b/test/testthumbasm.py	Sat Mar 08 15:32:33 2014 +0100
@@ -12,7 +12,7 @@
         self.t = thumb_target
         self.obj = ObjectFile()
         self.ostream = BinaryOutputStream(self.obj)
-        self.ostream.selectSection('.text')
+        self.ostream.select_section('.text')
         self.a = a #
 
     def testMovImm8(self):