/*************************************************************************** * Copyright (C) 2007 Nicolas Hadacek * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include "generator_check.h" #include "devices/base/device_group.h" #include "devices/pic/pic/pic_memory.h" #include "tools/gputils/gputils.h" #include "tools/gputils/gputils_generator.h" #include "tools/sdcc/sdcc.h" #include "tools/sdcc/sdcc_generator.h" #include "devices/list/device_list.h" //---------------------------------------------------------------------------- GeneratorCheckHelper::GeneratorCheckHelper() : _cprocess(0), _lprocess(0), _generator(0) {} GeneratorCheckHelper::~GeneratorCheckHelper() { delete _generator; } void GeneratorCheckHelper::cleanup() { delete _lprocess; _lprocess = 0; delete _cprocess; _cprocess = 0; } //---------------------------------------------------------------------------- GeneratorCheck::GeneratorCheck(GeneratorCheckHelper *helper) : _helper(helper), _fdest(0), _fhex(0), _memory1(0) { _view = new CLI::View; } GeneratorCheck::~GeneratorCheck() { delete _view; delete _helper; } void GeneratorCheck::runTest() { _helper->initSupported(); DeviceTest::runTest(); } bool GeneratorCheck::init(const Device::Data &data) { PURL::Url dest(PURL::Directory::current(), "test.xxx"); dest = dest.toFileType(_helper->sourceFileType()); _fdest = new PURL::File(dest, *_view); _helper->init(data); PURL::Url hex(PURL::Directory::current(), "test.hex"); _fhex = new PURL::File(hex, *_view); _memory1 = static_cast(data.group().createMemory(data)); return true; } bool GeneratorCheck::skip(const Device::Data &data) const { return !_helper->isSupported(data); } void GeneratorCheck::cleanup(const Device::Data &) { delete _memory1; _memory1 = 0; delete _fhex; _fhex = 0; // _fdest->remove(); delete _fdest; _fdest = 0; _helper->cleanup(); } bool GeneratorCheck::execute(const Device::Data &data) { // create asm file from template source code if ( !_fdest->openForWrite() ) TEST_FAILED_RETURN(""); _fdest->appendText(_source); _fdest->close(); // run compiler Process::State state = Process::runSynchronously(*_helper->_cprocess, Process::Start, 2000); // 2s timeout if ( state!=Process::Exited ) TEST_FAILED_RETURN("Error while running compilation") if ( _helper->_cprocess->exitCode()!=0 ) TEST_FAILED_RETURN(TQString("Error in compilation for %1:\n%2%3").tqarg(data.name()).tqarg(_helper->_cprocess->sout()+_helper->_cprocess->serr()).tqarg(TQString())) // run linker if (_helper->_lprocess) { state = Process::runSynchronously(*_helper->_lprocess, Process::Start, 2000); // 2s timeout if ( state!=Process::Exited ) TEST_FAILED_RETURN("Error while running linking") if ( _helper->_lprocess->exitCode()!=0 ) TEST_FAILED_RETURN(TQString("Error in linking for %1:\n%2%3").tqarg(data.name()).tqarg(_helper->_lprocess->sout()+_helper->_lprocess->serr()).tqarg(TQString())) } // load hex file if ( !_fhex->openForRead() ) TEST_FAILED_RETURN("") TQStringList errors, warnings; Device::Memory::WarningTypes warningTypes; if ( !_memory1->load(_fhex->stream(), errors, warningTypes, warnings) ) TEST_FAILED_RETURN(TQString("Error loading hex into memory: %1").tqarg(errors.join(" "))) //if ( warningTypes!=Device::Memory::NoWarning ) TEST_FAILED(TQString("Warning loading hex into memory: %1").tqarg(warnings.join(" "))) TEST_PASSED return true; } //---------------------------------------------------------------------------- bool ConfigGeneratorCheck::init(const Device::Data &data) { if ( !GeneratorCheck::init(data) ) return false; _memory2 = static_cast(data.group().createMemory(data)); return true; } bool ConfigGeneratorCheck::execute(const Device::Data &data) { // create configuration const Pic::Config &config = static_cast(data).config(); for (uint l=0; ; l++) { // set config bits bool ok = false; for (uint i=0; isetConfigValue(ctqmask.name, ctqmask.values[l].name); } } } if ( !ok ) break; // create source code PURL::SourceFamily sfamily = _helper->sourceFileType().data().sourceFamily; PURL::ToolType ttype = sfamily.data().toolType; SourceLine::List lines = _helper->generator()->includeLines(ttype, data); lines += _helper->generator()->configLines(ttype, *_memory2, ok); lines += _helper->configEndLines(); _source = SourceLine::text(sfamily, lines, 2); if (!ok) TEST_FAILED_RETURN("Config lines generation incomplete") if ( !GeneratorCheck::execute(data) ) return false; // check that config bits are the same uint nbChars = static_cast(data).nbCharsWord(Pic::MemoryRangeType::Config); for (uint i=0; iword(Pic::MemoryRangeType::Config, i); BitValue word2 = _memory2->word(Pic::MemoryRangeType::Config, i); if ( word1==word2 ) continue; for (uint k=0; ksourceFileType().data().sourceFamily; PURL::ToolType ttype = sfamily.data().toolType; SourceLine::List lines = _helper->generator()->templateSourceFile(ttype, data, ok); _source = SourceLine::text(sfamily, lines, 2); if (!ok) TEST_FAILED_RETURN(TQString("Incomplete template generator for %1").tqarg(data.name())) return true; } //---------------------------------------------------------------------------- GPUtilsGeneratorCheckHelper::GPUtilsGeneratorCheckHelper() { _generator = new GPUtils::SourceGenerator; } void GPUtilsGeneratorCheckHelper::initSupported() { Process::StringOutput p; TQStringList options; options += "-l"; p.setup("gpasm", options, false); Process::runSynchronously(p, Process::Start, 2000); // 2s timeout _supported = GPUtils::getSupportedDevices(p.sout()); } bool GPUtilsGeneratorCheckHelper::init(const Device::Data &data) { _cprocess = new Process::StringOutput; TQStringList options; options = "-c"; options += "-p" + GPUtils::toDeviceName(data.name()); options += "test.asm"; _cprocess->setup("gpasm", options, false); _lprocess = new Process::StringOutput; options = "-o"; options += "test.hex"; options += "test.o"; _lprocess->setup("gplink", options, false); return true; } SourceLine::List GPUtilsGeneratorCheckHelper::configEndLines() const { SourceLine::List lines; lines.appendIndentedCode("end"); return lines; } //---------------------------------------------------------------------------- SDCCGeneratorCheckHelper::SDCCGeneratorCheckHelper() { _generator = new SDCC::SourceGenerator; } void SDCCGeneratorCheckHelper::initSupported() { PURL::Url url(PURL::Directory::current(), "test.c"); Log::StringView view; PURL::File file(url, view); if ( file.openForWrite() ) file.appendText("void main(void) {}\n"); file.close(); _supported.clear(); for (uint i=0; isetup("sdcc", options, false); return true; } SourceLine::List SDCCGeneratorCheckHelper::configEndLines() const { SourceLine::List lines; lines.appendIndentedCode("void main() {}"); return lines; }