bool GlobDirs(String::Vector& out, const String& pattern, const bool emptyListBefore) { if (emptyListBefore) out.clear(); gResourcesMutex.lock(); for (ResourcesFoldersList::const_iterator i = pResourcesFolders.begin(); i != pResourcesFolders.end(); ++i) Paths::GlobDirs(out, *i + pattern, false); gResourcesMutex.unlock(); return !out.empty(); }
static inline void ParseCommandLine(int argc, char** argv, Settings& settings) { GetOpt::Parser options; String::Vector optFilenames; ShortString16 format; options.add(optFilenames, 'i', "input", "The input grammar"); options.add(settings.namespaceName, 'n', "namespace", "The target namespace (mandatory)"); options.add(format, 'f', "format", "Output format [cpp]"); options.remainingArguments(optFilenames); if (not options(argc, argv)) { if (options.errors()) { std::cout << "Abort due to error" << std::endl; exit(EXIT_FAILURE); } exit(0); } if (optFilenames.empty()) { logs.error() << "please provide a grammar file"; exit(EXIT_FAILURE); } settings.namespaceName.trim(" \t\r\n.:"); if (settings.namespaceName.empty()) { logs.error() << "no namespace provided"; exit(EXIT_FAILURE); } format.trim(); format.toLower(); if (format == "cpp") { settings.format = Settings::sfCPP; } else { logs.error() << "invalid output format"; exit(EXIT_FAILURE); } settings.filenames.resize((uint) optFilenames.size()); for (uint i = 0; i != (uint) optFilenames.size(); ++i) IO::Canonicalize(settings.filenames[i], optFilenames[i]); }
/*! * \brief Obtain a backtrace and print it to stdout. * * If GDB can be used to get a backtrace then we use it, otherwise and only * if TA3D_BUILTIN_BACKTRACE_SUPPORT is defined, a backtrace is obtained * then writen into a log file. It will be displayed in stdout when gdb is missing. * After this call, the program will exit with a exit status code equals * to `-1`. * * \param signum Which signal was received */ void backtrace_handler (int signum) { // Some functions called at exit may crash, so we must disable signals in order // to prevent overwriting a useful log clear_signals(); // Get TA3D's PID pid_t mypid = getpid(); // Try to get a stack trace from GDB String::Vector threads; TA3D::System::run_command(String("gdb --pid=") << mypid << " -ex \"info threads\" --batch").split(threads, "\n"); if (!threads.empty()) { String cmd; cmd << "gdb --pid=" << mypid << " -ex \"info threads\""; for(size_t i = 0 ; i < threads.size() ; ++i) { String &line = threads[i]; if (line.startsWith('[') || line.startsWith("0x") || line.startsWith('#')) continue; if (line.startsWith('*')) { line[0] = ' '; line.trimLeft(' '); } const int id = line.to<int>(); if (id <= 0) continue; cmd << " -ex \"thread " << id << "\" -ex bt"; } cmd << " --batch"; const String trace = TA3D::System::run_command(cmd); if (!trace.empty()) { bug_reporter(trace); exit(-1); } } // If GDB is not available or returned an error we must find another way ... this is now platform dependent # ifdef TA3D_BUILTIN_BACKTRACE_SUPPORT // Retrieving a backtrace void *array[400]; int size = backtrace (array, 400); char** strings = backtrace_symbols(array, size); // Try to log it Yuni::Core::IO::File::Stream m_File(String(TA3D::Paths::Logs) << "backtrace.txt", Yuni::Core::IO::OpenMode::write); if(m_File.opened()) { m_File << "received signal " << strsignal( signum ) << "\n"; m_File << "Obtained " << size << " stack frames.\n"; for (int i = 0; i < size; ++i) m_File << strings[i] << "\n"; m_File.flush(); m_File.close(); printf("received signal %s\n", strsignal( signum )); printf ("Obtained %d stack frames.\n", static_cast<int>(size)); for (int i = 0; i < size; ++i) printf ("%s\n", strings[i]); String szErrReport; szErrReport << "An error has occured.\nDebugging information have been logged to:\n" << TA3D::Paths::Logs << "backtrace.txt\nPlease report to our forums (http://www.ta3d.org/)\nand keep this file, it'll help us debugging.\n"; criticalMessage(szErrReport); } else { // The file is not opened // The backtrace will be directly to stdout instead. printf("received signal %s\n", strsignal(signum)); printf("couldn't open file for writing!!\n"); printf ("Obtained %d stack frames.\n", static_cast<int>(size)); for (int i = 0; i < size; ++i) printf ("%s\n", strings[i]); } free(strings); # else // ifdef TA3D_BUILTIN_BACKTRACE_SUPPORT // The backtrace support is disabled: warns the user String szErrReport = "An error has occured.\nDebugging information could not be logged.\nPlease report to our forums (http://www.ta3d.org/) so we can fix it."; criticalMessage(szErrReport); # endif // ifdef TA3D_BUILTIN_BACKTRACE_SUPPORT exit(-1); }
void MeshOBJ::load(File *file, const String &filename) { destroy3DM(); MeshOBJ *cur = this; name = "default"; bool firstObject = true; vector<Vector3D> lVertex; vector<Vector2D> lTcoord; vector<int> face; HashMap<Material>::Dense mtllib; Material currentMtl; while (!file->eof()) // Reads the whole file { String line; file->readLine(line); line.trim(); String::Vector args; line.explode(args, ' ', false, false, true); if (!args.empty()) { if ( (args[0] == "o" || args[0] == "g") && args.size() > 1) // Creates a new object { if (!face.empty()) { if (firstObject && cur->name.empty()) cur->name = "default"; cur->obj_finalize( filename, face, lVertex, lTcoord, ¤tMtl ); face.clear(); cur->child = new MeshOBJ(); cur = static_cast<MeshOBJ*>(cur->child); } firstObject = false; cur->name = args[1]; } else if (args[0] == "mtllib" && args.size() > 1) // Read given material libraries { for(String::Vector::iterator s = args.begin() + 1 ; s != args.end() ; ++s) { File *src_mtl = VFS::Instance()->readFile(String("objects3d/") << *s); if (!src_mtl) continue; Material mtl; while (!src_mtl->eof()) { String line0; src_mtl->readLine(line0); line0.trim(); String::Vector args0; line0.explode(args0, ' ', false, false, true); if (!args0.empty()) { if (args0[0] == "newmtl") mtl.name = args0[1]; else { if (args0[0] == "map_Kd") { mtl.textureName = String("textures/") << args0[1]; mtllib[mtl.name] = mtl; } } } } delete src_mtl; } } else { if (args[0] == "usemtl" && args.size() > 1) // Change current material { if (mtllib.count(args[1])) currentMtl = mtllib[args[1]]; else currentMtl.textureName.clear(); } else if (args[0] == "v" && args.size() > 3) // Add a vertex to current object lVertex.push_back( Vector3D(args[1].to<float>(), args[2].to<float>(), args[3].to<float>())); else if (args[0] == "vn" && args.size() > 3) // Add a normal vector to current object {} else if (args[0] == "vt" && args.size() > 2) // Add a texture coordinate vector to current object lTcoord.push_back( Vector2D( args[1].to<float>(), args[2].to<float>())); else if (args[0] == "f" && args.size() > 1) // Add a face to current object { vector<int> vertex_idx; vector<int> tcoord_idx; bool first_string = true; for(String::Vector::iterator s = args.begin() ; s != args.end() ; ++s) { // The first string is crap if we read it as vertex data !! if (first_string) { first_string = false; continue; } String::Vector data; s->trim(); s->explode(data, '/', false, false, true); if (!data.empty()) { vertex_idx.push_back( data[0].to<int>() - 1); if (vertex_idx.back() < 0) { LOG_DEBUG(LOG_PREFIX_OBJ << "parser : " << line << " -> " << *s << " -> " << vertex_idx.back()); } if (data.size() >= 2) tcoord_idx.push_back(data[1].to<int>() - 1); else tcoord_idx.push_back(-1); } } for (uint32 i = 2; i < vertex_idx.size(); ++i) // Make triangles (FAN method) { face.push_back(vertex_idx[0]); face.push_back(tcoord_idx[0]); face.push_back(vertex_idx[i-1]); face.push_back(tcoord_idx[i-1]); face.push_back(vertex_idx[i]); face.push_back(tcoord_idx[i]); } } } } } cur->obj_finalize(filename, face, lVertex, lTcoord, ¤tMtl); }