beremiz

Parents 97d73990053d
Children 56bae4ff53c4
Added stdout/stderr separation limitation and coloration
  • +73 -15
    Beremiz.py
  • --- a/Beremiz.py Thu Aug 09 18:05:09 2007 +0200
    +++ b/Beremiz.py Mon Aug 13 17:22:39 2007 +0200
    @@ -32,6 +32,9 @@
    sys.path.append(os.path.join(base_folder, "plcopeneditor"))
    sys.path.append(os.path.join(base_folder, "CanFestival-3", "objdictgen"))
    +iec2cc_path = os.path.join(base_folder, "matiec", "iec2cc")
    +ieclib_path = os.path.join(base_folder, "matiec", "lib")
    +
    from PLCOpenEditor import PLCOpenEditor, ProjectDialog
    from PLCControler import PLCControler
    @@ -78,13 +81,32 @@
    class LogPseudoFile:
    """ Base class for file like objects to facilitate StdOut for the Shell."""
    def __init__(self, output = None):
    + self.red_white = wx.TextAttr("RED", "WHITE")
    + self.red_yellow = wx.TextAttr("RED", "YELLOW")
    + self.black_white = wx.TextAttr("BLACK", "WHITE")
    + self.default_style = None
    self.output = output
    def writelines(self, l):
    map(self.write, l)
    def write(self, s):
    - self.output.SetValue(self.output.GetValue() + s)
    + if self.default_style != self.black_white:
    + self.output.SetDefaultStyle(self.black_white)
    + self.default_style = self.black_white
    + self.output.AppendText(s)
    +
    + def write_warning(self, s):
    + if self.default_style != self.red_white:
    + self.output.SetDefaultStyle(self.red_white)
    + self.default_style = self.red_white
    + self.output.AppendText(s)
    +
    + def write_error(self, s):
    + if self.default_style != self.red_yellow:
    + self.output.SetDefaultStyle(self.red_yellow)
    + self.default_style = self.red_yellow
    + self.output.AppendText(s)
    def flush(self):
    self.output.SetValue("")
    @@ -261,7 +283,7 @@
    self.LogConsole = wx.TextCtrl(id=ID_BEREMIZLOGCONSOLE, value='',
    name='LogConsole', parent=self, pos=wx.Point(0, 0),
    - size=wx.Size(0, 0), style=wx.TE_MULTILINE)
    + size=wx.Size(0, 0), style=wx.TE_MULTILINE|wx.TE_RICH2)
    self.EditPLCButton = wx.Button(id=ID_BEREMIZEDITPLCBUTTON, label='Edit\nPLC',
    name='EditPLCButton', parent=self, pos=wx.Point(0, 0),
    @@ -617,25 +639,59 @@
    self.PLCEditor.RefreshToolBar()
    self.PLCEditor.Show()
    + def LogCommand(self, Command, sz_limit = 100):
    +
    + import os, popen2, fcntl, select, signal
    +
    + child = popen2.Popen3(Command, 1) # capture stdout and stderr from command
    + child.tochild.close() # don't need to talk to child
    + outfile = child.fromchild
    + outfd = outfile.fileno()
    + errfile = child.childerr
    + errfd = errfile.fileno()
    + outdata = errdata = ''
    + outeof = erreof = 0
    + outlen = errlen = 0
    + while 1:
    + ready = select.select([outfd,errfd],[],[]) # wait for input
    + if outfd in ready[0]:
    + outchunk = outfile.readline()
    + if outchunk == '': outeof = 1
    + outdata += outchunk
    + outlen += 1
    + self.Log.write(outchunk)
    + if errfd in ready[0]:
    + errchunk = errfile.readline()
    + if errchunk == '': erreof = 1
    + errdata += errchunk
    + errlen += 1
    + self.Log.write_warning(errchunk)
    + if outeof and erreof : break
    + if errlen > sz_limit or outlen > sz_limit :
    + os.kill(child.pid, signal.SIGTERM)
    + self.Log.write_error("Output size reached limit -- killed\n")
    + break
    + err = child.wait()
    + return (err, outdata, errdata)
    +
    def BuildAutom(self):
    if self.PLCManager:
    self.TargetDir = os.path.join(self.CurrentProjectPath, "build")
    if not os.path.exists(self.TargetDir):
    os.mkdir(self.TargetDir)
    self.Log.flush()
    - sys.stdout = self.Log
    + #sys.stdout = self.Log
    try:
    - print "Building ST Program..."
    + self.Log.write("Building ST Program...\n")
    plc_file = os.path.join(self.TargetDir, "plc.st")
    result = self.PLCManager.GenerateProgram(plc_file)
    if not result:
    - raise Exception
    - print "Compiling ST Program in to C Program..."
    - status, result = commands.getstatusoutput("../matiec/iec2cc %s -I ../matiec/lib %s"%(plc_file, self.TargetDir))
    + raise Exception, "ST/IL/SFC code generator returned %d"%result
    + self.Log.write("Compiling ST Program in to C Program...\n")
    + status, result, err_result = self.LogCommand("%s %s -I %s %s"%(iec2cc_path, plc_file, ieclib_path, self.TargetDir))
    if status:
    - print result
    - raise Exception
    - print "Extracting Located Variables..."
    + raise Exception, "IEC2C compiler returned %d"%status
    + self.Log.write("Extracting Located Variables...\n")
    location_file = open(os.path.join(self.TargetDir,"LOCATED_VARIABLES.h"))
    locations = []
    lines = [line.strip() for line in location_file.readlines()]
    @@ -643,21 +699,23 @@
    result = LOCATED_MODEL.match(line)
    if result:
    locations.append(result.groups())
    - print "Generating Network Configurations..."
    + self.Log.write("Generating Network Configurations...\n")
    for bus_id, bus_infos in self.BusManagers.items():
    if bus_infos["Type"] == "CanFestival":
    master = config_utils.GenerateConciseDCF(locations, bus_id, bus_infos["NodeList"])
    result = gen_cfile.GenerateFile("%s.c"%os.path.join(self.TargetDir, gen_cfile.FormatName(bus_infos["Name"])), master)
    if result:
    raise Exception
    - print "Generating Makefiles..."
    + self.Log.write("Generating Makefiles...\n")
    - print "Compiling Project..."
    + self.Log.write("Compiling Project...\n")
    - print "\nBuild Project completed"
    + self.Log.write("\nBuild Project completed\n")
    except Exception, message:
    + self.Log.write_error("\nBuild Failed\n")
    + self.Log.write(str(message))
    pass
    - sys.stdout = sys.__stdout__
    + #sys.stdout = sys.__stdout__
    #-------------------------------------------------------------------------------
    # Add Bus Dialog