ClangCompiler::ClangCompiler() : invocation_(new CompilerInvocation()), compiler_(new CompilerInstance()), keep_temporaries_(false), debug_mode_(false), log_stream_(&cerr) { // Set-up the clang compiler #if CLANG_VERSION_MAJOR == 3 # if CLANG_VERSION_MINOR == 0 TextDiagnosticPrinter *diag_client = new TextDiagnosticPrinter(errs(), DiagnosticOptions()); # elif CLANG_VERSION_MINOR == 5 TextDiagnosticPrinter *diag_client = new TextDiagnosticPrinter(errs(), new DiagnosticOptions()); # endif #endif IntrusiveRefCntPtr<DiagnosticIDs> diag_id(new DiagnosticIDs()); #if CLANG_VERSION_MAJOR == 3 # if CLANG_VERSION_MINOR == 0 DiagnosticsEngine diags(diag_id, diag_client); # elif CLANG_VERSION_MINOR == 5 DiagnosticsEngine diags(diag_id, 0, diag_client); # endif #endif // Create a dummy invocation of the compiler, so as to set it up // and we will replace the source file afterwards const char *const dummy_argv[] = { "" }; CompilerInvocation::CreateFromArgs(*invocation_, dummy_argv, dummy_argv, diags); // Compile C99 #if CLANG_VERSION_MAJOR == 3 # if CLANG_VERSION_MINOR == 0 invocation_->setLangDefaults(IK_C, LangStandard::lang_c99); # elif CLANG_VERSION_MINOR == 5 invocation_->setLangDefaults(*(invocation_->getLangOpts()), IK_C, LangStandard::lang_c99); # endif #endif // Add a user-defined include path first, if specified char *user_inc_path = getenv("SPX_JIT_INC_PATH"); if (user_inc_path) AddIncludeSearchPath(user_inc_path, IncludePathSystem); // Setup the include path AddIncludeSearchPath(CLANG_INC_SEARCH_PATH, IncludePathSystem); // Setup diagnostic options DiagnosticOptions &diag_options = invocation_->getDiagnosticOpts(); // FIXME: The following option crashes Clang 3.0 on certain systems! // diag_options.Warnings.push_back("all"); // -Wall diag_options.Pedantic = 1; // -pedantic diag_options.ShowColors = 1; // be fancy ;) // Setup code generation options SetCodeGenOptions(); }
NABoolean CmpStatement::error(Lng32 no, const char* s) { if ( diags()->getNumber() ) return TRUE; // means the underlying routines have put the errors into // diags. *diags() << DgSqlCode(no) << DgString0(s); return TRUE; }
//-------------------------------------------------- void f0r_set_param_value(f0r_instance_t instance, f0r_param_t param, int param_index) { tp_inst_t* inst = (tp_inst_t*)instance; f0r_param_double* p = (f0r_param_double*) param; int chg,tmpi; float tmpf; chg=0; switch (param_index) { case 0: //type tmpf=*((double*)p); if (tmpf>=1.0) tmpi=(int)tmpf; else tmpi = map_value_forward(tmpf, 0.0, 9.9999); if ((tmpi<0)||(tmpi>9.0)) break; if (inst->type != tmpi) chg=1; inst->type = tmpi; break; case 1: //channel tmpf=*((double*)p); if (tmpf>=1.0) tmpi=(int)tmpf; else tmpi = map_value_forward(tmpf, 0.0, 7.9999); if ((tmpi<0)||(tmpi>7.0)) break; if (inst->chan != tmpi) chg=1; inst->chan = tmpi; case 2: //amplitude tmpf = map_value_forward(*((double*)p), 0.0, 1.0); if (inst->amp != tmpf) chg=1; inst->amp = tmpf; break; case 3: //linear period sweep tmpi = map_value_forward(*((double*)p), 0.0, 1.0); if (inst->linp != tmpi) chg=1; inst->linp = tmpi; break; case 4: //frequency 1 tmpf = map_value_forward(*((double*)p), 0.0, 1.0); if (inst->f1 != tmpf) chg=1; inst->f1 = tmpf; break; case 5: //frequency 2 tmpf = map_value_forward(*((double*)p), 0.0, 1.0); if (inst->f2 != tmpf) chg=1; inst->f2 = tmpf; break; case 6: //aspect type tmpf=*((double*)p); if (tmpf>=1.0) tmpi=(int)tmpf; else tmpi = map_value_forward(tmpf, 0.0, 6.9999); if ((tmpi<0)||(tmpi>6.0)) break; if (inst->aspt != tmpi) chg=1; inst->aspt = tmpi; switch (inst->aspt) //pixel aspect ratio { case 0: inst->par=1.000; break; //square pixels case 1: inst->par=1.067; break; //PAL DV case 2: inst->par=1.455; break; //PAL wide case 3: inst->par=0.889; break; //NTSC DV case 4: inst->par=1.212; break; //NTSC wide case 5: inst->par=1.333; break; //HDV case 6: inst->par=inst->mpar; break; //manual } break; case 7: //manual aspect tmpf = map_value_forward_log(*((double*)p), 0.5, 2.0); if (inst->mpar != tmpf) chg=1; inst->mpar = tmpf; if (inst->aspt==6) inst->par=inst->mpar; break; } if (chg==0) return; switch (inst->type) { case 0: //hor freq ver sweep sweep_v(inst->sl, inst->w, inst->h, 0, inst->amp, inst->linp, inst->par, 0.05, 0.7); break; case 1: //hor freq hor sweep sweep_h(inst->sl, inst->w, inst->h, 0, inst->amp, inst->linp, inst->par, 0.05, 0.7); break; case 2: //ver freq ver sweep sweep_v(inst->sl, inst->w, inst->h, 1, inst->amp, inst->linp, inst->par, 0.05, 0.7); //ver f ver sw break; case 3: //ver freq hor sweep sweep_h(inst->sl, inst->w, inst->h, 1, inst->amp, inst->linp, inst->par, 0.05, 0.7); break; case 4: // "Siemens star" radials(inst->sl, inst->w, inst->h, inst->amp, inst->par, 60.0); break; case 5: //rings outwards rings(inst->sl, inst->w, inst->h, inst->amp, inst->par, inst->linp, 0.05, 0.7); break; case 6: //rings inwards rings(inst->sl, inst->w, inst->h, inst->amp, inst->par, inst->linp, 0.7, 0.05); break; case 7: //uniform 2D spatial frequency diags(inst->sl, inst->w, inst->h, inst->amp, inst->par, inst->f1, inst->f2); break; case 8: // "Nyquist blocks" nblocks(inst->sl, inst->w, inst->h, inst->amp); break; case 9: //square bars at integer Nyquist fractions sqbars(inst->sl, inst->w, inst->h, inst->amp); break; default: break; } }
void CmpCommon::dumpDiags(ostream& outStream, NABoolean newline) { NADumpDiags(outStream, diags(), newline); }
int main(int argc, char* argv[]) { llvm::llvm_shutdown_obj llvm_manager(false); cl::SetVersionPrinter(&PrintVersion); cl::ParseCommandLineOptions(argc, argv); if (show_help) cl::PrintHelpMessage(); if (show_license) { for (std::size_t i=0; i<sizeof(license_msg)/sizeof(license_msg[0]); i++) llvm::outs() << license_msg[i] << '\n'; return EXIT_SUCCESS; } if (show_info) { llvm::outs() << full_version << '\n'; list_module<yasm::ObjectFormatModule>(); return EXIT_SUCCESS; } yasm::OffsetDiagnosticPrinter diag_printer(llvm::errs()); yasm::Diagnostic diags(&diag_printer); yasm::SourceManager source_mgr(diags); diags.setSourceManager(&source_mgr); diag_printer.setPrefix("yobjdump"); // Load standard modules if (!yasm::LoadStandardPlugins()) { diags.Report(yasm::diag::fatal_standard_modules); return EXIT_FAILURE; } if (show_all_headers) { show_file_headers = true; show_section_headers = true; show_private_headers = true; show_relocs = true; show_symbols = true; } // Determine input filename and open input file. if (in_filenames.empty()) { diags.Report(yasm::diag::fatal_no_input_files); return EXIT_FAILURE; } int retval = EXIT_SUCCESS; for (std::vector<std::string>::const_iterator i=in_filenames.begin(), end=in_filenames.end(); i != end; ++i) { try { if (DoDump(*i, source_mgr, diags) != EXIT_SUCCESS) retval = EXIT_FAILURE; } catch (std::out_of_range& err) { llvm::errs() << *i << ": " << "out of range error while reading (corrupt file?)\n"; retval = EXIT_FAILURE; } } return retval; }
CmpStatement::ReturnStatus CmpStatement::process (const CmpMessageDDL& statement) { CmpMain cmpmain; CMPASSERT(statement.getCmpCompileInfo()); char * sqlStr = NULL; Int32 sqlStrLen = 0; Lng32 inputCS = 0; NAString currCatName; NAString currSchName; char * recompControlInfo = NULL; NABoolean isSchNameRecvd; NABoolean nametypeNsk; NABoolean odbcProcess; NABoolean noTextCache; NABoolean aqrPrepare; NABoolean standaloneQuery; isDDL_ = TRUE; if (processRecvdCmpCompileInfo(this, statement, statement.getCmpCompileInfo(), context_, sqlStr, sqlStrLen, // out - long & inputCS, isSchNameRecvd, currCatName, currSchName, recompControlInfo, nametypeNsk, odbcProcess, noTextCache, aqrPrepare, standaloneQuery)) return CmpStatement_ERROR; CmpCommon::context()->sqlSession()->setParentQid( statement.getParentQid()); // process recompControlInfo, if received if (recompControlInfo) setupRecompControlInfo(recompControlInfo, &cmpmain); cmpmain.setSqlParserFlags(statement.getFlags()); // set the current catalog and schema names. InitSchemaDB(); // C control character embedded in sqlStr is not handled. Now replace // control characters tabs, line feeds, spaces with spaces. (no longer // substitute for \n so we can recognized embedded comments) for (Int32 i = 0; sqlStr[i]; i++) if (sqlStr[i] != '\n' && isSpace8859_1((unsigned char)sqlStr[i])) sqlStr[i] = ' '; // skip leading blanks NAString ns(sqlStr); ns = ns.strip(NAString::leading, ' '); // if this is an "update statistics..." request, // then do not send it catalog manager. Int32 foundUpdStat = 0; // check if the first token is UPDATE size_t position = ns.index("UPDATE", 0, NAString::ignoreCase); if (position == 0) { // found UPDATE. See if the next token is STATISTICS. ns = ns(6, ns.length()-6); // skip over UPDATE ns = ns.strip(NAString::leading, ' '); position = ns.index("STATISTICS", 0, NAString::ignoreCase); if (position == 0) foundUpdStat = -1; } if (foundUpdStat) { // TODO, should be removed later // A pointer to user SQL query is stored in CmpStatement; if an exception // is thrown the user query is copied from here. It is reset upon return // from the UpdateStats() method. char *userStr= new (heap()) char[2000]; #pragma nowarn(1506) // warning elimination Int32 len=strlen(sqlStr); #pragma warn(1506) // warning elimination if (len > 1999) len=1999; strncpy(userStr, sqlStr, len); userStr[len]='\0'; sqlTextStr_ = userStr; sqlTextLen_ = len; if (UpdateStats(sqlStr)) { sqlTextStr_ = NULL; sqlTextLen_ = 0; if (recompControlInfo) restoreRecompControlInfo(recompControlInfo); return CmpStatement_ERROR; } sqlTextStr_ = NULL; sqlTextLen_ = 0; if (recompControlInfo) restoreRecompControlInfo(recompControlInfo); return CmpStatement_SUCCESS; } ReturnStatus status = CmpStatement_SUCCESS; if (statement.getCmpCompileInfo()->isHbaseDDL()) { CmpMain::ReturnStatus rs = CmpMain::SUCCESS; QueryText qText(sqlStr, inputCS); CmpMessageReplyCode *bound = new(outHeap_) CmpMessageReplyCode(outHeap_, statement.id(), 0, 0, outHeap_); // CmpMain cmpmain; Set_SqlParser_Flags(DELAYED_RESET); // sqlcompCleanup resets for us Parser parser(CmpCommon::context()); BindWA bindWA(ActiveSchemaDB(), CmpCommon::context(), TRUE); // save parser flags Int32 savedParserFlags = Get_SqlParser_Flags (0xFFFFFFFF); ExprNode * exprNode = NULL; if (parser.parseDML(qText, &exprNode, NULL)) { error(arkcmpErrorNoDiags, statement.data()); sqlTextStr_=NULL; return CmpStatement_ERROR; } RelExpr * rRoot = NULL; if (exprNode->getOperatorType() EQU STM_QUERY) { rRoot = (RelRoot*)exprNode->getChild(0); } else if (exprNode->getOperatorType() EQU REL_ROOT) { rRoot = (RelRoot*)exprNode; } CMPASSERT(rRoot); ExprNode *boundDDL = rRoot->bindNode(&bindWA); CMPASSERT(boundDDL); if (CmpCommon::diags()->getNumber(DgSqlCode::ERROR_)) { return CmpStatement_ERROR; } ExprNode * ddlNode = NULL; DDLExpr * ddlExpr = NULL; ddlExpr = (DDLExpr*)rRoot->getChild(0); ddlNode = ddlExpr->getDDLNode(); if (ddlNode) { boundDDL = ddlNode->castToStmtDDLNode()->bindNode(&bindWA); CMPASSERT(boundDDL); if (CmpCommon::diags()->getNumber(DgSqlCode::ERROR_)) { return CmpStatement_ERROR; } ddlNode = boundDDL; } // reset saved flags Set_SqlParser_Flags (savedParserFlags); CmpSeabaseDDL cmpSBD(heap_); if (cmpSBD.executeSeabaseDDL(ddlExpr, ddlNode, currCatName, currSchName)) { Set_SqlParser_Flags(0); return CmpStatement_ERROR; } Set_SqlParser_Flags (0); // TEMPTEMP. // Until support for metadata invalidation is in, clear up query cache for // this process. That way statements issued later from this session will // not see stale definitions. // This also helps in running tests where tables are modified and accessed from // the same session. // This does not solve the issue of stale definition seen by other processes, // that will be fixed once we have metadata invalidation. CURRENTQCACHE->makeEmpty(); return CmpStatement_SUCCESS; } // hbaseDDL // This is a normal DDL request, call Catalog manager *diags() << DgSqlCode(-4222) << DgString0("SQL Compiler DDL"); return CmpStatement_ERROR; }
void NasmInsnRunner::TestInsn(yasm::Insn* insn, std::size_t golden_len, const unsigned char* golden, const llvm::StringRef& ew_msg) { // // Turn the instruction into bytes // BytecodeContainer container(0); ::testing::StrictMock<MockDiagnosticString> mock_consumer; llvm::IntrusiveRefCntPtr<DiagnosticIDs> diagids(new DiagnosticIDs); DiagnosticsEngine diags(diagids, &mock_consumer, false); FileSystemOptions opts; FileManager fmgr(opts); SourceManager smgr(diags, fmgr); diags.setSourceManager(&smgr); if (!ew_msg.empty()) { EXPECT_CALL(mock_consumer, DiagString(ew_msg)) .Times(1); } else { // expect no diagnostic calls EXPECT_CALL(mock_consumer, DiagString(::testing::_)) .Times(0); } insn->Append(container, SourceLocation(), diags); container.Finalize(diags); if (diags.hasErrorOccurred()) return; container.bytecodes_front().CalcLen(AddSpanTest, diags); ASSERT_EQ(golden_len, container.bytecodes_front().getTotalLen()); if (diags.hasErrorOccurred()) return; container.UpdateOffsets(diags); if (diags.hasErrorOccurred()) return; llvm::SmallString<64> outbytes; llvm::raw_svector_ostream outstream(outbytes); RawOutput outputter(outstream, *m_arch, diags); container.bytecodes_front().Output(outputter); outstream.flush(); // // Compare the result against the golden result // if (golden_len != outbytes.size()) goto bad; for (std::size_t i=0; i<golden_len; ++i) { if ((int)(golden[i] & 0xff) != (int)(outbytes[i] & 0xff)) goto bad; } return; bad: std::string golden_str, outbytes_str; llvm::raw_string_ostream golden_ss(golden_str), outbytes_ss(outbytes_str); for (std::size_t i=0; i<golden_len; ++i) golden_ss << llvm::format("%02x ", (int)(golden[i] & 0xff)); golden_ss.flush(); for (std::size_t i=0; i<outbytes.size(); ++i) outbytes_ss << llvm::format("%02x ", (int)(outbytes[i] & 0xff)); outbytes_ss.flush(); ASSERT_EQ(golden_str, outbytes_str); }
void NasmInsnRunner::ParseAndTestLine(const char* filename, const llvm::StringRef& line, int linenum) { SCOPED_TRACE(llvm::format("%s:%d", filename, linenum)); llvm::StringRef insn_in, golden_in; llvm::tie(insn_in, golden_in) = line.split(';'); insn_in = strip(insn_in); golden_in = strip(golden_in); // Handle bits directive if (golden_in.empty() && insn_in.startswith("[bits ")) { int bits = atoi(insn_in.substr(6, 2).str().c_str()); if (bits == 64) m_arch->setMachine("amd64"); else m_arch->setMachine("x86"); m_arch->setVar("mode_bits", bits); return; } if (insn_in.empty() || golden_in.empty()) return; // skip lines that don't have both text and a comment // // parse the golden result // llvm::SmallVector<unsigned char, 64> golden; llvm::StringRef golden_errwarn; for (;;) { // strip whitespace golden_in = strip(golden_in); if (golden_in.empty() || !isxdigit(golden_in[0])) break; unsigned int byte_val = 0x100; llvm::StringRef byte_str; llvm::tie(byte_str, golden_in) = golden_in.split(' '); if (byte_str.size() == 2) // assume hex byte_val = (fromhexdigit(byte_str[0]) << 4) | fromhexdigit(byte_str[1]); else if (byte_str.size() == 3) // assume octal byte_val = (fromoctdigit(byte_str[0]) << 6) | (fromoctdigit(byte_str[1]) << 3) | fromoctdigit(byte_str[2]); ASSERT_LE(byte_val, 0xffU) << "invalid golden value"; golden.push_back(byte_val); } // interpret string in [] as error/warning if (!golden_in.empty() && golden_in[0] == '[') llvm::tie(golden_errwarn, golden_in) = golden_in.substr(1).split(']'); // // parse the instruction // ::testing::StrictMock<MockDiagnosticString> mock_consumer; llvm::IntrusiveRefCntPtr<DiagnosticIDs> diagids(new DiagnosticIDs); DiagnosticsEngine diags(diagids, &mock_consumer, false); FileSystemOptions opts; FileManager fmgr(opts); SourceManager smgr(diags, fmgr); diags.setSourceManager(&smgr); // instruction name is the first thing on the line llvm::StringRef insn_name; llvm::tie(insn_name, insn_in) = insn_in.split(' '); Arch::InsnPrefix insnprefix = m_arch->ParseCheckInsnPrefix(insn_name, SourceLocation(), diags); ASSERT_TRUE(insnprefix.isType(Arch::InsnPrefix::INSN)); std::auto_ptr<Insn> insn = m_arch->CreateInsn(insnprefix.getInsn()); ASSERT_TRUE(insn.get() != 0) << "unrecognized instruction '" << insn_name.str() << "'"; // parse insn arguments unsigned int wsize = m_arch_module->getWordSize(); // strip whitespace from arguments insn_in = strip(insn_in); while (!insn_in.empty()) { llvm::StringRef arg_str; llvm::tie(arg_str, insn_in) = insn_in.split(','); // strip whitespace from arg arg_str = strip(arg_str); unsigned int size = 0; bool strict = false; for (;;) { int next; int nsize = 0; // operand overrides (size and strict) if (arg_str.startswith("byte ")) { nsize = 8; next = 5; } else if (arg_str.startswith("hword ")) { nsize = wsize/2; next = 6; } else if (arg_str.startswith("word ")) { nsize = wsize; next = 5; } else if (arg_str.startswith("dword ")) { nsize = wsize*2; next = 6; } else if (arg_str.startswith("qword ")) { nsize = wsize*4; next = 6; } else if (arg_str.startswith("tword ")) { nsize = 80; next = 6; } else if (arg_str.startswith("dqword ")) { nsize = wsize*8; next = 7; } else if (arg_str.startswith("oword ")) { nsize = wsize*8; next = 6; } else if (arg_str.startswith("yword ")) { nsize = 256; next = 6; } else if (arg_str.startswith("strict ")) { strict = true; next = 7; } else break; if (size == 0) size = nsize; arg_str = arg_str.substr(next); } if (arg_str[0] == '[') { // Very simple int/reg expression parser. Does not handle parens or // order of operations; simply builds expr from left to right. // This means r8*4+r9 will have a different result than r9+r8*4! // Also only handles binary operators * and +. llvm::StringRef estr = arg_str.slice(1, arg_str.find(']')+1); std::auto_ptr<Expr> e(new Expr); char pendingop = '\0'; std::size_t tokstart = 0; for (std::size_t pos = 0; pos < estr.size(); ++pos) { if (estr[pos] == '*' || estr[pos] == '+' || estr[pos] == ']') { // figure out this token llvm::StringRef tok = strip(estr.slice(tokstart, pos)); if (isdigit(estr[tokstart])) e->Append(strtoint(tok)); else { Arch::RegTmod regtmod = m_arch->ParseCheckRegTmod(tok, SourceLocation(), diags); ASSERT_TRUE(regtmod.isType(Arch::RegTmod::REG)) << "cannot handle label '" << tok.str() << "'"; e->Append(*regtmod.getReg()); } // append pending operator if (pendingop == '*') e->AppendOp(Op::MUL, 2); else if (pendingop == '+') e->AppendOp(Op::ADD, 2); // store new operator pendingop = estr[pos]; tokstart = pos+1; } } Operand operand(m_arch->CreateEffAddr(e)); operand.setSize(size); operand.setStrict(strict); insn->AddOperand(operand); continue; } // TODO: split by space to allow target modifiers // Test for registers Arch::RegTmod regtmod = m_arch->ParseCheckRegTmod(arg_str, SourceLocation(), diags); if (const Register* reg = regtmod.getReg()) { Operand operand(reg); operand.setSize(size); operand.setStrict(strict); insn->AddOperand(operand); continue; } else if (const SegmentRegister* segreg = regtmod.getSegReg()) { Operand operand(segreg); operand.setSize(size); operand.setStrict(strict); insn->AddOperand(operand); continue; } else if (regtmod.getTargetMod()) { FAIL() << "cannot handle target modifier"; } else if (regtmod.getRegGroup()) { FAIL() << "cannot handle register group"; } // Can't handle labels ASSERT_TRUE(isdigit(arg_str[0]) || arg_str[0] == '-') << "cannot handle label '" << arg_str.str() << "'"; // Convert to integer expression Operand intop(Expr::Ptr(new Expr(strtoint(arg_str)))); intop.setSize(size); intop.setStrict(strict); insn->AddOperand(intop); } TestInsn(insn.get(), golden.size(), golden.data(), golden_errwarn); }
void MainWindow::load() { QString fileName = QFileDialog::getOpenFileName(this, tr("Open KD Chart 2 File"), QDir::currentPath(), tr("KDC2 Files (*.kdc2 *.xml)")); if (fileName.isEmpty()) return; QFile file(fileName); if (!file.open(QFile::ReadOnly | QFile::Text)) { QMessageBox::warning(this, tr("KD Chart Serializer"), tr("Cannot read file %1:\n%2.") .arg(fileName) .arg(file.errorString())); return; } // note: We do NOT set any default data-model for the serializer here // because we assign the data-models by another way, see below. KDChart::Serializer serializer( 0, 0 ); if( serializer.read( &file ) ){ if( serializer.chart() && serializer.chart()->coordinatePlane() && serializer.chart()->coordinatePlane()->diagram() ) { // Retrieve the chart read from file: KDChart::Chart* newChart = serializer.chart(); // Remove the current chart and delete it: removeTheChart(); KDChart::CoordinatePlaneList planes( newChart->coordinatePlanes() ); for( int iPlane=0; iPlane<planes.count(); ++iPlane){ KDChart::AbstractDiagramList diags( planes.at(iPlane)->diagrams() ); for( int iDiag=0; iDiag<diags.count(); ++iDiag){ KDChart::AbstractDiagram* diagram = diags.at( iDiag ); if( dynamic_cast<KDChart::BarDiagram*>( diagram ) || dynamic_cast<KDChart::LineDiagram*>( diagram ) ) diagram->setModel( m_model ); } } // From now on use the chart read from file: m_chart = newChart; m_chartLayout->addWidget( m_chart ); m_chart->update(); }else{ QMessageBox::warning( this, tr("KD Chart Serializer"), tr("ERROR: Parsed chart in file %1 has no diagram.") .arg(fileName) ); } }else{ QMessageBox::warning( this, tr("KD Chart Serializer"), tr("ERROR: Cannot read file %1.") .arg(fileName) ); } file.close(); }