// Also allocates the vertex render buffers void FurMeshGeometry::SetVertexCount (uint n) { vertexCount = n; vertexBuffer = csRenderBuffer::CreateRenderBuffer (n, CS_BUF_STREAM, CS_BUFCOMP_FLOAT, 3); if (!vertexBuffer) csPrintfErr("Could not create vertex buffer!\n"); texcoordBuffer = csRenderBuffer::CreateRenderBuffer (n, CS_BUF_STREAM, CS_BUFCOMP_FLOAT, 2); if (!texcoordBuffer) csPrintfErr("Could not create texcoord buffer!\n"); normalBuffer = csRenderBuffer::CreateRenderBuffer (n, CS_BUF_STREAM, CS_BUFCOMP_FLOAT, 3); if (!normalBuffer) csPrintfErr("Could not create normal buffer!\n"); binormalBuffer = csRenderBuffer::CreateRenderBuffer (n, CS_BUF_STREAM, CS_BUFCOMP_FLOAT, 3); if (!binormalBuffer) csPrintfErr("Could not create binormal buffer!\n"); tangentBuffer = csRenderBuffer::CreateRenderBuffer (n, CS_BUF_STREAM, CS_BUFCOMP_FLOAT, 3); if (!tangentBuffer) csPrintfErr("Could not create tangent buffer!\n"); }
static void cmd_time (char *args) { if (!args) { csPrintfErr ("time: expected filename\n"); return; } csFileTime flmt; if (!VFS->GetFileTime (args, flmt)) { csPrintfErr ("time: can not query file time (no such file maybe)\n"); return; } struct tm time; memset (&time, 0, sizeof (time)); time.tm_sec = flmt.sec; time.tm_min = flmt.min; time.tm_hour = flmt.hour; time.tm_mday = flmt.day; time.tm_mon = flmt.mon; time.tm_year = flmt.year - 1900; // No newline needed; asctime() adds it for us. csPrintf ("Last file modification time: %s", asctime (&time)); }
static void cmd_rm (char *args) { if (!args) csPrintfErr ("rm: empty argument\n"); else if (!VFS->DeleteFile (args)) csPrintfErr ("rm: cannot remove file \"%s\"\n", args); }
static bool get2args (const char *command, char *args, char *&arg1, char *&arg2, bool req2nd = true) { if (!args) { csPrintfErr ("%s: arguments required\n", command); return false; } arg1 = args; while (*args && !isspace(*args)) args++; if (!*args && req2nd) { nodest: csPrintfErr ("%s: no second argument\n", command); return false; } arg2 = args; if (*args) arg2++; *args = 0; while (isspace(*arg2)) arg2++; if (!*arg2 && req2nd) goto nodest; return true; }
static void cmd_create (char *args) { csRef<iFile> F (VFS->Open (args, VFS_FILE_WRITE)); if (!F) { csPrintfErr ("create: cannot create or open for writing file \"%s\"\n", args); return; } csPrintf ("Copying from stdin to file \"%s\", enter EOF to finish\n", args); for (;;) { char buff [160]; if (!fgets (buff, sizeof (buff), stdin)) break; size_t len = F->Write (buff, strlen (buff)); if (len < strlen (buff)) { csPrintfErr ("create: error writing to file \"%s\"\n", args); break; } } csPrintf ("done, closing file\n"); }
void csSCF::RegisterClasses (char const* pluginPath, iDocument* doc, const char* context) { if (doc) { csRef<iDocumentNode> rootnode = doc->GetRoot(); if (rootnode != 0) { csRef<iDocumentNode> pluginnode = rootnode->GetNode("plugin"); if (pluginnode) { csRef<iDocumentNode> scfnode = pluginnode->GetNode("scf"); if (scfnode.IsValid()) RegisterClassesInt (pluginPath, scfnode, context); else csPrintfErr("SCF_ERROR: missing <scf> node in metadata for %s " "in context `%s'\n", pluginPath != 0 ? pluginPath : "{unknown}", GetContextName(context)); } else csPrintfErr("SCF_ERROR: missing root <plugin> node in metadata " "for %s in context `%s'\n", pluginPath != 0 ? pluginPath : "{unknown}", GetContextName(context)); } } }
bool csSCF::RegisterClass (const char *iClassID, const char *iLibraryName, const char *iFactoryClass, const char *iDesc, const char *Dependencies, const char* context) { CS::Threading::RecursiveMutexScopedLock lock (mutex); size_t idx; csStringID contextID = context ? contexts.Request (context) : csInvalidStringID; if (IsVerbose(SCF_VERBOSE_CLASS_REGISTER)) csPrintfErr("SCF_NOTIFY: registering class %s in context %s (from %s)\n", iClassID, CS::Quote::Single (GetContextName(context)), iLibraryName); if ((idx = ClassRegistry->FindClass(iClassID)) != (size_t)-1) { scfFactory *cf = (scfFactory *)ClassRegistry->Get (idx); if (ContextClash (cf->classContext, contextID)) { csPrintfErr("SCF_WARNING: class %s (from %s) has already been " "registered in the same context %s (in %s)\n", iClassID, iLibraryName, CS::Quote::Single (GetContextName(context)), get_library_name(cf->LibraryName)); } else { /* The user may want to override a standard CS plugin by putting a plugin exhibiting the same class ID into the e.g. app directory. In this case a warning is probably not desired. But for debugging purposes we emit something. */ #ifdef CS_DEBUG // Don't report when the already registered class is static. if (cf->classContext != staticContextID) { // @@@ some way to have this warning in non-debug builds would be nice. csPrintfErr("SCF_NOTIFY: class %s (from %s) has already been " "registered in a different context: %s vs. %s (from %s); this " "message appears only in debug builds\n", iClassID, iLibraryName, CS::Quote::Single (GetContextName(context)), CS::Quote::Single (GetContextName(cf->classContext)), get_library_name(cf->LibraryName)); } #endif } return false; } scfFactory* factory = new scfFactory (iClassID, iLibraryName, iFactoryClass, 0, iDesc, Dependencies, contextID); ClassRegistry->Push (factory); SortClassRegistry = true; return true; }
void csSCF::RegisterClassesInt(char const* pluginPath, iDocumentNode* scfnode, const char* context) { bool const seen = pluginPath != 0 && libraryNames->Contains(pluginPath); if (IsVerbose(SCF_VERBOSE_PLUGIN_REGISTER)) { char const* s = pluginPath != 0 ? pluginPath : "{unknown}"; char const* c = GetContextName(context); if (!seen) csPrintfErr("SCF_NOTIFY: registering plugin %s in context `%s'\n", s, c); else csPrintfErr("SCF_NOTIFY: ignoring duplicate plugin registration %s " "in context `%s'\n", s, c); } if (seen) return; // *** RETURN: Do not re-register *** csRef<iDocumentNode> classesnode = scfnode->GetNode("classes"); if (classesnode) { csRef<iDocumentNodeIterator> classiter = classesnode->GetNodes("class"); csRef<iDocumentNode> classnode; while ((classnode = classiter->Next())) { csString classname = get_node_value(classnode, "name"); csString imp = get_node_value(classnode, "implementation"); csString desc = get_node_value(classnode, "description"); // For backward compatibility, we build a comma-delimited dependency // string from the individual dependency nodes. In the future, // iSCF::GetClassDependencies() should be updated to return an // iStringArray, rather than a simple comma-delimited string. csString depend; csRef<iDocumentNode> depnode = classnode->GetNode("requires"); if (depnode) { csRef<iDocumentNodeIterator> depiter = depnode->GetNodes("class"); csRef<iDocumentNode> depclassnode; while ((depclassnode = depiter->Next())) { if (!depend.IsEmpty()) depend << ", "; depend << depclassnode->GetContentsValue(); } } char const* pdepend = (depend.IsEmpty() ? 0 : depend.GetData()); RegisterClass(classname, pluginPath, imp, desc, pdepend, context); } } }
scfFactory::~scfFactory () { #ifdef CS_DEBUG // Warn user about unreleased instances of this class if (scfRefCount) csPrintfErr("SCF WARNING: %d unreleased instances of class %s!\n", scfRefCount, ClassID); #endif if (scfWeakRefOwners) { for (size_t i = 0; i < scfWeakRefOwners->GetSize (); i++) { void** p = (*scfWeakRefOwners)[i]; *p = 0; } delete scfWeakRefOwners; scfWeakRefOwners = 0; } if (Library) Library->DecRef (); cs_free (FactoryClass); cs_free (Dependencies); cs_free (Description); #ifndef CS_REF_TRACKER cs_free (const_cast<char*> (ClassID)); #endif csRefTrackerAccess::TrackDestruction (this, scfRefCount); }
csPtr<iConfigFile> csGetPlatformConfig (const char* key) { csString fname = csGetPlatformConfigPath (key); fname << ".cfg"; csString dir (fname); size_t slash = dir.FindLast (CS_PATH_SEPARATOR); if (slash != (size_t)-1) dir.Truncate (slash); // Try to create the directory (we assume that $HOME is already created) struct stat stats; if (stat (dir, &stats) != 0) { mode_t const m = S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH; if (mkdir (dir, m) != 0) { csPrintfErr ("Failed to create %s for configuration files (errno %d).\n", CS::Quote::Single (dir.GetData()), errno); return 0; } } return new csConfigFile (fname); }
iBase *csSCF::CreateInstance (const char *iClassID) { CS::Threading::RecursiveMutexScopedLock lock (mutex); // Pre-sort class registry for doing binary searches if (SortClassRegistry) { ClassRegistry->Sort(); SortClassRegistry = false; } size_t idx = ClassRegistry->FindClass(iClassID, true); iBase *object = 0; if (idx != (size_t)-1) { iFactory *cf = (iFactory *)ClassRegistry->Get (idx); object = cf->CreateInstance (); if (!object) csPrintfErr("SCF_WARNING: factory returned a null instance for %s\n" "\tif error messages are not self explanatory, recompile CS with " "CS_DEBUG\n", iClassID); } /* endif */ UnloadUnusedModules (); return object; }
static void cmd_rpath (char *args) { if (!args) { csPrintfErr ("rpath: expected filename\n"); return; } csRef<iDataBuffer> db (VFS->GetRealPath (args)); if (!db) { csPrintfErr ("rpath: no real-world path corresponding to `%s'\n", args); return; } puts ((char *)db->GetData ()); }
bool csSCF::RegisterPlugin (const char* path) { csRef<iDocument> metadata; csRef<iString> msg; if (IsVerbose(SCF_VERBOSE_PLUGIN_REGISTER)) csPrintfErr("SCF_NOTIFY: registering plugin %s (no context)\n", path); if ((msg = csGetPluginMetadata (path, metadata)) != 0) { csPrintfErr("SCF_ERROR: couldn't retrieve metadata for '%s': %s\n", path, msg->GetData ()); return false; } RegisterClasses (path, metadata); return true; }
static void cmd_mount (char *args) { char *vpath, *rpath; if (!get2args ("mount", args, vpath, rpath)) return; if (!VFS->Mount (vpath, rpath)) csPrintfErr ("mount: cannot mount \"%s\" to \"%s\"\n", rpath, vpath); }
bool getcwdcheck (char* path, size_t size) { if (getcwd (path, size) == 0) { csPrintfErr ("csPathUtilities: getcwd() error for '%s' (errno = %d)!\n", path, errno); return false; } return true; }
bool getcwdcheck (char* path, size_t size) { if (getcwd (path, size) == 0) { csPrintfErr ("csPathUtilities: getcwd() error for %s (errno = %d)!\n", CS::Quote::Single (path), errno); return false; } return true; }
void csPrintLibraryError (const char* /*iModule*/) { char *str; while (ErrorMessages.GetSize () > 0) { str = (char*)ErrorMessages.Pop(); if (str != 0) csPrintfErr (" %s\n", str); delete[] str; } }
static void cmd_config (char *args) { bool real_fs; get_option (args, real_fs); iVFS *CfgVFS = real_fs ? (iVFS*)0 : (iVFS*)VFS; iConfigFile *config = Cfg->AddDomain (args, CfgVFS, iConfigManager::ConfigPriorityCmdLine); if (!config) { csPrintfErr ("config: cannot load config file \"%s\" in %s\n", args, real_fs ? "real filesystem" : "VFS"); return; } if (!VFS->LoadMountsFromFile (config)) csPrintfErr ( "config: mount: cannot mount all directories found in config file.\n"); }
void csTextureRGBA::SaveImage (iObjectRegistry* object_reg, const char* texname) const { csRef<iImageIO> imageio = csQueryRegistry<iImageIO> (object_reg); csRef<iVFS> VFS = csQueryRegistry<iVFS> (object_reg); if(!data) { csPrintfErr ("Bad data buffer!\n"); return; } csRef<iImage> image; image.AttachNew(new csImageMemory (width, height, data, false, CS_IMGFMT_TRUECOLOR | CS_IMGFMT_ALPHA)); if(!image.IsValid()) { csPrintfErr ("Error creating image\n"); return; } csPrintf ("Saving %zu KB of data.\n", csImageTools::ComputeDataSize (image) / 1024); csRef<iDataBuffer> db = imageio->Save (image, "image/png", "progressive"); if (db) { if (!VFS->WriteFile (texname, (const char*)db->GetData (), db->GetSize ())) { csPrintfErr ("Failed to write file %s!", CS::Quote::Single (texname)); return; } } else { csPrintfErr ("Failed to save png image for basemap!"); return; } }
static void cmd_exists (char *args) { if (!args) { csPrintfErr ("exists: empty argument\n"); return; } bool IsDir = args [strlen (args) - 1] == '/'; csPrintf ("%s \"%s\" %s\n", IsDir ? "Directory" : "File", args, VFS->Exists (args) ? "exists" : "does not exist"); }
scfSharedLibrary::scfSharedLibrary (csStringID libraryName, const char *core) { LibraryRegistry->Push (this); RefCount = 0; LibraryName = libraryName; const char* lib = get_library_name(LibraryName); if (PrivateSCF->IsVerbose(SCF_VERBOSE_PLUGIN_LOAD)) csPrintfErr("SCF_NOTIFY: loading plugin %s to satisfy request for %s\n", lib, core); LibraryHandle = csLoadLibrary (lib); if (LibraryHandle != 0) { csString sym; sym << core << "_scfInitialize"; initFunc = (scfInitFunc)csGetLibrarySymbol(LibraryHandle, sym); if (!initFunc) { csPrintfErr("SCF_ERROR: %s doesn't export %s\n", CS::Quote::Single (lib), CS::Quote::Single (sym.GetData())); csPrintLibraryError (sym); } sym.Clear (); sym << core << "_scfFinalize"; finisFunc = (scfFinisFunc)csGetLibrarySymbol(LibraryHandle, sym); if (!finisFunc) { csPrintfErr("SCF_ERROR: %s doesn't export %s\n", CS::Quote::Single (lib), CS::Quote::Single (sym.GetData())); csPrintLibraryError (sym); } if (initFunc && finisFunc) initFunc (PrivateSCF); } else csPrintLibraryError (lib); }
static void cmd_unmount (char *args) { char *vpath, *rpath; if (!get2args ("unmount", args, vpath, rpath, false)) return; if (!*rpath) rpath = 0; if (!VFS->Unmount (vpath, rpath)) csPrintfErr ("unmount: cannot unmount \"%s\" from \"%s\"\n", rpath, vpath); }
// Also allocates the index render buffer // The index buffer will be 3 * n, set triangle count not index count void FurMeshGeometry::SetTriangleCount (uint n) { if (!vertexCount) return; indexCount = n; indexBuffer = csRenderBuffer::CreateIndexRenderBuffer (3 * n, CS_BUF_STATIC, CS_BUFCOMP_UNSIGNED_INT, 0, vertexCount - 1); if (!indexBuffer) csPrintfErr("Could not create index buffer!\n"); }
bool chdircheck (const char* path) { if (chdir (path) != 0) { const int errcode = errno; // some "file not found" errors are to be expected, so filter them out. if (errcode != ENOENT) csPrintfErr ("csPathUtilities: chdir() error for %s (errno = %d)!\n", path, errcode); return false; } return true; }
static void cmd_cat (char *args) { bool onepass; get_option (args, onepass); if (onepass) { csRef<iDataBuffer> data (VFS->ReadFile (args)); if (!data) { csPrintfErr ("cat: cannot read file \"%s\"\n", args); return; } const size_t size = data->GetSize (); const size_t res = fwrite (**data, size, 1, stdout); if (res != size) csPrintfErr ("cat: could only write %zu of %zu bytes (errno = %d)!\n", res, size, errno); } else { csRef<iFile> F (VFS->Open (args, VFS_FILE_READ)); if (!F) { csPrintfErr ("cat: cannot open file \"%s\" for reading\n", args); return; } while (!F->AtEOF ()) { char buff [16]; size_t len = F->Read (buff, sizeof (buff) - 1); buff [len] = 0; csPrintf ("%s", buff); } } }
scfSharedLibrary::~scfSharedLibrary () { if (LibraryHandle) { if (initFunc && finisFunc) finisFunc(); if (PrivateSCF->IsVerbose(SCF_VERBOSE_PLUGIN_LOAD)) csPrintfErr("SCF_NOTIFY: unloading plugin %s\n", get_library_name(LibraryName)); #ifndef LAZY_UNLOAD csUnloadLibrary (LibraryHandle); #else PrivateSCF->lazyUnloadLibs.Push (LibraryHandle); #endif } }
static void cmd_rmounts (char *args) { if (!args) { csPrintfErr ("rmounts: expected virtual mount path\n"); return; } csRef<iStringArray> rpaths = VFS->GetRealMountPaths (args); if (rpaths->GetSize ()) { for (size_t i=0; i<rpaths->GetSize () ; i++) { csPrintf ("%s\n", rpaths->Get (i)); } } else csPrintf ("rmounts: no virtual mount at path `%s'\n", args); }
void scfFactory::DecRef () { csRefTrackerAccess::TrackDecRef (this, scfRefCount); #ifdef CS_DEBUG if (scfRefCount == 0) { csPrintfErr("SCF WARNING: extra invocations of scfFactory::DecRef() " "for class %s\n", ClassID); return; } #endif scfRefCount--; if (scfRefCount == 0) { // now we no longer need the library either if (Library) { Library->DecRef (); Library = 0; } } }
int main (int argc, char *argv []) { iObjectRegistry* object_reg = csInitializer::CreateEnvironment (argc, argv); if (!object_reg) return -1; if (!csInitializer::SetupConfigManager (object_reg, 0)) { csPrintfErr ("couldn't setup config!\n"); return 1; } if (!csInitializer::RequestPlugins (object_reg, CS_REQUEST_VFS, CS_REQUEST_END)) return -1; VFS = csQueryRegistry<iVFS> (object_reg); if (!VFS) { csPrintfErr ("Cannot load iVFS plugin\n"); return -1; } Cfg = csQueryRegistry<iConfigManager> (object_reg); if (!Cfg) { csPrintfErr ("Cannot load iConfigManager plugin\n"); return -1; } VFS->MountRoot ("native"); csPrintf ("Welcome to Virtual Shell\n" "Type \"help\" to get a short description of commands\n" "\n"); while (!ShutDown) { char command [999]; csPrintf (CS_ANSI_TEXT_BOLD_ON CS_ANSI_FM "%s " CS_ANSI_TEXT_BOLD_OFF CS_ANSI_FG "#" CS_ANSI_RST " ", VFS->GetCwd ()); fflush (stdout); if (!fgets (command, sizeof(command), stdin)) { csPrintf ("\r\n"); ShutDown = true; } else { char* s = command; trimwhite(s); if (s != 0 && !execute (s)) csPrintfErr ("vsh: unknown command: [%s]\n", s); } } Cfg = 0; VFS = 0; csInitializer::DestroyApplication (object_reg); return 0; }
void csSCF::ScanPluginsInt (csPathsList const* pluginPaths, const char* context) { if (pluginPaths) { // Search plugins in pluginpaths csRef<iStringArray> plugins; size_t i, j; for (i = 0; i < pluginPaths->Length(); i++) { csPathsList::Entry const& pathrec = (*pluginPaths)[i]; if (IsVerbose(SCF_VERBOSE_PLUGIN_SCAN)) { char const* x = scannedDirs.Contains(pathrec.path) ? "re-" : ""; csPrintfErr("SCF_NOTIFY: %sscanning plugin directory: %s " "(context `%s'; recursive %s)\n", x, pathrec.path.GetData(), GetContextName(pathrec.type), pathrec.scanRecursive ? "yes" : "no"); } if (plugins) plugins->Empty(); csRef<iStringArray> messages = csScanPluginDir (pathrec.path, plugins, pathrec.scanRecursive); scannedDirs.Request(pathrec.path); if ((messages != 0) && (messages->GetSize () > 0)) { csPrintfErr("SCF_WARNING: the following issue(s) arose while " "scanning '%s':", pathrec.path.GetData()); for (j = 0; j < messages->GetSize (); j++) csPrintfErr(" %s\n", messages->Get (j)); } csRef<iDocument> metadata; csRef<iString> msg; for (j = 0; j < plugins->GetSize (); j++) { char const* plugin = plugins->Get(j); msg = csGetPluginMetadata (plugin, metadata); if (msg != 0) { csPrintfErr("SCF_ERROR: metadata retrieval error for %s: %s\n", plugin, msg->GetData ()); } // It is possible for an error or warning message to be generated even // when metadata is also obtained. Likewise, it is possible for no // metadata to be obtained yet also to have no error message. The // latter case is indicative of csScanPluginDir() returning "potential" // plugins which turn out to not be Crystal Space plugins after all. // For instance, on Windows, the scan might find a DLL which is not a // Crystal Space DLL; that is, which does not contain embedded // metadata. This is a valid case, which we simply ignore since it is // legal for non-CS libraries to exist alongside CS plugins in the // scanned directories. if (metadata) RegisterClasses(plugin, metadata, context ? context : pathrec.type.GetData()); } } } }