File indexing completed on 2025-04-20 05:11:08
0001 /*************************************************************************** 0002 * Copyright (C) 2005 by David Saxton * 0003 * david@bluehaze.org * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 ***************************************************************************/ 0010 0011 #include "language.h" 0012 #include "asmparser.h" 0013 #include "ktechlab.h" 0014 #include "languagemanager.h" 0015 #include "logview.h" 0016 #include "outputmethoddlg.h" 0017 #include "processchain.h" 0018 #include "projectmanager.h" 0019 0020 //#include <kio/netaccess.h> 0021 #include <KMessageBox> 0022 #include <KProcess> 0023 0024 #include <QRegExp> 0025 #include <QTimer> 0026 0027 #include <ktlconfig.h> 0028 #include <ktechlab_debug.h> 0029 0030 // BEGIN class Language 0031 Language::Language(ProcessChain *processChain, const QString &name) 0032 : QObject(KTechlab::self() /*, name */) 0033 { 0034 setObjectName(name); 0035 p_processChain = processChain; 0036 } 0037 0038 Language::~Language() 0039 { 0040 } 0041 0042 void Language::outputMessage(const QString &message) 0043 { 0044 LanguageManager::self()->slotMessage(message, extractMessageInfo(message)); 0045 } 0046 0047 void Language::outputWarning(const QString &message) 0048 { 0049 LanguageManager::self()->slotWarning(message, extractMessageInfo(message)); 0050 } 0051 0052 void Language::outputError(const QString &message) 0053 { 0054 LanguageManager::self()->slotError(message, extractMessageInfo(message)); 0055 m_errorCount++; 0056 } 0057 0058 void Language::finish(bool successful) 0059 { 0060 if (successful) { 0061 outputMessage(m_successfulMessage + "\n"); 0062 KTechlab::self()->slotChangeStatusbar(m_successfulMessage); 0063 0064 ProcessOptions::ProcessPath::Path newPath = outputPath(m_processOptions.processPath()); 0065 0066 if (newPath == ProcessOptions::ProcessPath::None) 0067 emit processSucceeded(this); 0068 0069 else if (p_processChain) { 0070 m_processOptions.setInputFiles(QStringList(m_processOptions.intermediaryOutput())); 0071 m_processOptions.setIntermediaryOutput(m_processOptions.targetFile()); 0072 m_processOptions.setProcessPath(newPath); 0073 // p_processChain->compile(m_processOptions); 0074 p_processChain->setProcessOptions(m_processOptions); 0075 p_processChain->compile(); 0076 } 0077 } else { 0078 outputError(m_failedMessage + "\n"); 0079 KTechlab::self()->slotChangeStatusbar(m_failedMessage); 0080 emit processFailed(this); 0081 return; 0082 } 0083 } 0084 0085 void Language::reset() 0086 { 0087 m_errorCount = 0; 0088 } 0089 0090 MessageInfo Language::extractMessageInfo(const QString &text) 0091 { 0092 if (!text.startsWith("/")) 0093 return MessageInfo(); 0094 0095 const int index = text.indexOf(":", 0, Qt::CaseInsensitive); 0096 if (index == -1) 0097 return MessageInfo(); 0098 const QString fileName = text.left(index); 0099 0100 // Extra line number 0101 const QString message = text.right(text.length() - index); 0102 const int linePos = message.indexOf(QRegExp(":[\\d]+")); 0103 int line = -1; 0104 if (linePos != -1) { 0105 const int linePosEnd = message.indexOf(':', linePos + 1); 0106 if (linePosEnd != -1) { 0107 const QString number = message.mid(linePos + 1, linePosEnd - linePos - 1).trimmed(); 0108 bool ok; 0109 line = number.toInt(&ok) - 1; 0110 if (!ok) 0111 line = -1; 0112 } 0113 } 0114 return MessageInfo(fileName, line); 0115 } 0116 // END class Language 0117 0118 // BEGIN class ProcessOptionsSpecial 0119 ProcessOptionsSpecial::ProcessOptionsSpecial() 0120 { 0121 m_bOutputMapFile = true; 0122 b_forceList = true; 0123 b_addToProject = ProjectManager::self()->currentProject(); 0124 0125 p_flowCodeDocument = nullptr; 0126 0127 switch (KTLConfig::hexFormat()) { 0128 case KTLConfig::EnumHexFormat::inhx8m: 0129 m_hexFormat = "inhx8m"; 0130 break; 0131 0132 case KTLConfig::EnumHexFormat::inhx8s: 0133 m_hexFormat = "inhx8s"; 0134 break; 0135 0136 case KTLConfig::EnumHexFormat::inhx16: 0137 m_hexFormat = "inhx16"; 0138 break; 0139 0140 case KTLConfig::EnumHexFormat::inhx32: 0141 default: 0142 m_hexFormat = "inhx32"; 0143 break; 0144 } 0145 } 0146 // END class ProcessOptionsSpecial 0147 0148 // BEGIN class ProcessOptions 0149 ProcessOptions::ProcessOptions() 0150 { 0151 m_pHelper = new ProcessOptionsHelper; 0152 0153 b_targetFileSet = false; 0154 m_pTextOutputTarget = nullptr; 0155 } 0156 0157 ProcessOptions::ProcessOptions(OutputMethodInfo info) 0158 { 0159 m_pHelper = new ProcessOptionsHelper; 0160 0161 b_addToProject = info.addToProject(); 0162 m_picID = info.picID(); 0163 b_targetFileSet = false; 0164 0165 setTargetFile(info.outputFile().toLocalFile()); 0166 0167 switch (info.method()) { 0168 case OutputMethodInfo::Method::Direct: 0169 m_method = Method::LoadAsNew; 0170 break; 0171 0172 case OutputMethodInfo::Method::SaveAndForget: 0173 m_method = Method::Forget; 0174 break; 0175 0176 case OutputMethodInfo::Method::SaveAndLoad: 0177 m_method = Method::Load; 0178 break; 0179 } 0180 } 0181 0182 void ProcessOptions::setTextOutputTarget(TextDocument *target, QObject *receiver, const char *slot) 0183 { 0184 m_pTextOutputTarget = target; 0185 QObject::connect(m_pHelper, SIGNAL(textOutputtedTo(TextDocument *)), receiver, slot); 0186 } 0187 0188 void ProcessOptions::setTextOutputtedTo(TextDocument *outputtedTo) 0189 { 0190 m_pTextOutputTarget = outputtedTo; 0191 emit m_pHelper->textOutputtedTo(m_pTextOutputTarget); 0192 } 0193 0194 void ProcessOptions::setTargetFile(const QString &file) 0195 { 0196 if (b_targetFileSet) { 0197 qCWarning(KTL_LOG) << "Trying to reset target file!"; 0198 return; 0199 } 0200 m_targetFile = file; 0201 m_intermediaryFile = file; 0202 b_targetFileSet = true; 0203 } 0204 0205 ProcessOptions::ProcessPath::MediaType ProcessOptions::guessMediaType(const QString &url) 0206 { 0207 QString extension = url.right(url.length() - url.lastIndexOf('.') - 1); 0208 extension = extension.toLower(); 0209 0210 if (extension == "asm") { 0211 // We'll have to look at the file contents to determine its type... 0212 AsmParser p(url); 0213 p.parse(); 0214 switch (p.type()) { 0215 case AsmParser::Relocatable: 0216 return ProcessPath::AssemblyRelocatable; 0217 0218 case AsmParser::Absolute: 0219 return ProcessPath::AssemblyAbsolute; 0220 } 0221 } 0222 0223 if (extension == "c") 0224 return ProcessPath::C; 0225 0226 if (extension == "flowcode") 0227 return ProcessPath::FlowCode; 0228 0229 if (extension == "a" || extension == "lib") 0230 return ProcessPath::Library; 0231 0232 if (extension == "microbe" || extension == "basic") 0233 return ProcessPath::Microbe; 0234 0235 if (extension == "o") 0236 return ProcessPath::Object; 0237 0238 if (extension == "hex") 0239 return ProcessPath::Program; 0240 0241 return ProcessPath::Unknown; 0242 } 0243 0244 ProcessOptions::ProcessPath::Path ProcessOptions::ProcessPath::path(MediaType from, MediaType to) 0245 { 0246 switch (from) { 0247 case AssemblyAbsolute: 0248 switch (to) { 0249 case AssemblyAbsolute: 0250 return None; 0251 case Pic: 0252 return AssemblyAbsolute_PIC; 0253 case Program: 0254 return AssemblyAbsolute_Program; 0255 0256 case AssemblyRelocatable: 0257 case C: 0258 case Disassembly: 0259 case FlowCode: 0260 case Library: 0261 case Microbe: 0262 case Object: 0263 case Unknown: 0264 default: 0265 return Invalid; 0266 } 0267 0268 case AssemblyRelocatable: 0269 switch (to) { 0270 case Library: 0271 return AssemblyRelocatable_Library; 0272 case Object: 0273 return AssemblyRelocatable_Object; 0274 case Pic: 0275 return AssemblyRelocatable_PIC; 0276 case Program: 0277 return AssemblyRelocatable_Program; 0278 0279 case AssemblyAbsolute: 0280 case AssemblyRelocatable: 0281 case C: 0282 case Disassembly: 0283 case FlowCode: 0284 case Microbe: 0285 case Unknown: 0286 default: 0287 return Invalid; 0288 } 0289 0290 case C: 0291 switch (to) { 0292 case AssemblyRelocatable: 0293 return C_AssemblyRelocatable; 0294 case Library: 0295 return C_Library; 0296 case Object: 0297 return C_Object; 0298 case Pic: 0299 return C_PIC; 0300 case Program: 0301 return C_Program; 0302 0303 case AssemblyAbsolute: 0304 case C: 0305 case Disassembly: 0306 case FlowCode: 0307 case Microbe: 0308 case Unknown: 0309 default: 0310 return Invalid; 0311 } 0312 0313 case Disassembly: 0314 return Invalid; 0315 0316 case FlowCode: 0317 switch (to) { 0318 case AssemblyAbsolute: 0319 return FlowCode_AssemblyAbsolute; 0320 case Microbe: 0321 return FlowCode_Microbe; 0322 case Pic: 0323 return FlowCode_PIC; 0324 case Program: 0325 return FlowCode_Program; 0326 0327 case AssemblyRelocatable: 0328 case C: 0329 case Disassembly: 0330 case FlowCode: 0331 case Library: 0332 case Object: 0333 case Unknown: 0334 default: 0335 return Invalid; 0336 } 0337 0338 case Library: 0339 return Invalid; 0340 0341 case Microbe: 0342 switch (to) { 0343 case AssemblyAbsolute: 0344 return Microbe_AssemblyAbsolute; 0345 case Pic: 0346 return Microbe_PIC; 0347 case Program: 0348 return Microbe_Program; 0349 0350 case AssemblyRelocatable: 0351 case C: 0352 case Disassembly: 0353 case FlowCode: 0354 case Library: 0355 case Microbe: 0356 case Object: 0357 case Unknown: 0358 default: 0359 return Invalid; 0360 } 0361 0362 case Object: 0363 switch (to) { 0364 case Disassembly: 0365 return Object_Disassembly; 0366 case Library: 0367 return Object_Library; 0368 case Pic: 0369 return Object_PIC; 0370 case Program: 0371 return Object_Program; 0372 0373 case AssemblyAbsolute: 0374 case AssemblyRelocatable: 0375 case C: 0376 case FlowCode: 0377 case Microbe: 0378 case Object: 0379 case Unknown: 0380 default: 0381 return Invalid; 0382 } 0383 0384 case Pic: 0385 return Invalid; 0386 0387 case Program: 0388 switch (to) { 0389 case Disassembly: 0390 return Program_Disassembly; 0391 case Pic: 0392 return Program_PIC; 0393 0394 case AssemblyAbsolute: 0395 case AssemblyRelocatable: 0396 case C: 0397 case FlowCode: 0398 case Library: 0399 case Microbe: 0400 case Object: 0401 case Program: 0402 case Unknown: 0403 default: 0404 return Invalid; 0405 } 0406 0407 case Unknown: 0408 return Invalid; 0409 } 0410 0411 return Invalid; 0412 } 0413 0414 ProcessOptions::ProcessPath::MediaType ProcessOptions::ProcessPath::from(Path path) 0415 { 0416 switch (path) { 0417 case ProcessPath::AssemblyAbsolute_PIC: 0418 case ProcessPath::AssemblyAbsolute_Program: 0419 return AssemblyAbsolute; 0420 0421 case ProcessPath::AssemblyRelocatable_Library: 0422 case ProcessPath::AssemblyRelocatable_Object: 0423 case ProcessPath::AssemblyRelocatable_PIC: 0424 case ProcessPath::AssemblyRelocatable_Program: 0425 return AssemblyRelocatable; 0426 0427 case ProcessPath::C_AssemblyRelocatable: 0428 case ProcessPath::C_Library: 0429 case ProcessPath::C_Object: 0430 case ProcessPath::C_PIC: 0431 case ProcessPath::C_Program: 0432 return C; 0433 0434 case ProcessPath::FlowCode_AssemblyAbsolute: 0435 case ProcessPath::FlowCode_Microbe: 0436 case ProcessPath::FlowCode_PIC: 0437 case ProcessPath::FlowCode_Program: 0438 return FlowCode; 0439 0440 case ProcessPath::Microbe_AssemblyAbsolute: 0441 case ProcessPath::Microbe_PIC: 0442 case ProcessPath::Microbe_Program: 0443 return Microbe; 0444 0445 case ProcessPath::Object_Disassembly: 0446 case ProcessPath::Object_Library: 0447 case ProcessPath::Object_PIC: 0448 case ProcessPath::Object_Program: 0449 return Object; 0450 0451 case ProcessPath::PIC_AssemblyAbsolute: 0452 return Pic; 0453 0454 case ProcessPath::Program_Disassembly: 0455 case ProcessPath::Program_PIC: 0456 return Program; 0457 0458 case ProcessPath::Invalid: 0459 case ProcessPath::None: 0460 return Unknown; 0461 } 0462 0463 return Unknown; 0464 } 0465 0466 ProcessOptions::ProcessPath::MediaType ProcessOptions::ProcessPath::to(Path path) 0467 { 0468 switch (path) { 0469 case ProcessPath::FlowCode_AssemblyAbsolute: 0470 case ProcessPath::Microbe_AssemblyAbsolute: 0471 case ProcessPath::PIC_AssemblyAbsolute: 0472 return AssemblyAbsolute; 0473 0474 case ProcessPath::C_AssemblyRelocatable: 0475 return AssemblyRelocatable; 0476 0477 case ProcessPath::Object_Disassembly: 0478 case ProcessPath::Program_Disassembly: 0479 return Disassembly; 0480 0481 case ProcessPath::AssemblyRelocatable_Library: 0482 case ProcessPath::C_Library: 0483 case ProcessPath::Object_Library: 0484 return Library; 0485 0486 case ProcessPath::FlowCode_Microbe: 0487 return Microbe; 0488 0489 case ProcessPath::AssemblyRelocatable_Object: 0490 case ProcessPath::C_Object: 0491 return Object; 0492 0493 case ProcessPath::AssemblyAbsolute_PIC: 0494 case ProcessPath::AssemblyRelocatable_PIC: 0495 case ProcessPath::C_PIC: 0496 case ProcessPath::FlowCode_PIC: 0497 case ProcessPath::Microbe_PIC: 0498 case ProcessPath::Object_PIC: 0499 case ProcessPath::Program_PIC: 0500 return Pic; 0501 0502 case ProcessPath::AssemblyAbsolute_Program: 0503 case ProcessPath::AssemblyRelocatable_Program: 0504 case ProcessPath::C_Program: 0505 case ProcessPath::FlowCode_Program: 0506 case ProcessPath::Microbe_Program: 0507 case ProcessPath::Object_Program: 0508 return Program; 0509 0510 case ProcessPath::Invalid: 0511 case ProcessPath::None: 0512 return Unknown; 0513 } 0514 0515 return Unknown; 0516 } 0517 // END class ProcessOptions 0518 0519 #include "moc_language.cpp"