示例#1
0
    // 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");
    }
示例#2
0
文件: vsh.cpp 项目: garinh/cs
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));
}
示例#3
0
文件: vsh.cpp 项目: garinh/cs
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);
}
示例#4
0
文件: vsh.cpp 项目: garinh/cs
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;
}
示例#5
0
文件: vsh.cpp 项目: garinh/cs
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");
}
示例#6
0
文件: scf.cpp 项目: garinh/cs
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));
    }
  }
}
示例#7
0
文件: scf.cpp 项目: Tank-D/Shards
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;
}
示例#8
0
文件: scf.cpp 项目: garinh/cs
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);
    }
  }
}
示例#9
0
文件: scf.cpp 项目: garinh/cs
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);
}
示例#10
0
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);
}
示例#11
0
文件: scf.cpp 项目: garinh/cs
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;
}
示例#12
0
文件: vsh.cpp 项目: garinh/cs
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 ());
}
示例#13
0
文件: scf.cpp 项目: garinh/cs
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;
}
示例#14
0
文件: vsh.cpp 项目: garinh/cs
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);
}
示例#15
0
文件: pathutil.cpp 项目: garinh/cs
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;
}
示例#16
0
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;
}
示例#17
0
文件: loadlib.cpp 项目: garinh/cs
void csPrintLibraryError (const char* /*iModule*/)
{
  char *str;
  while (ErrorMessages.GetSize () > 0)
  {
    str = (char*)ErrorMessages.Pop();
    if (str != 0) csPrintfErr ("  %s\n", str);
    delete[] str;
  }
}
示例#18
0
文件: vsh.cpp 项目: garinh/cs
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");
}
示例#19
0
  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;
    }	    
  }
示例#20
0
文件: vsh.cpp 项目: garinh/cs
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");
}
示例#21
0
文件: scf.cpp 项目: Tank-D/Shards
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);
}
示例#22
0
文件: vsh.cpp 项目: garinh/cs
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);
}
示例#23
0
    // 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");
    }
示例#24
0
文件: pathutil.cpp 项目: garinh/cs
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;
}
示例#25
0
文件: vsh.cpp 项目: garinh/cs
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);
    }
  }
}
示例#26
0
文件: scf.cpp 项目: garinh/cs
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
  }
}
示例#27
0
文件: vsh.cpp 项目: garinh/cs
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);
}
示例#28
0
文件: scf.cpp 项目: garinh/cs
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;
    }
  }
}
示例#29
0
文件: vsh.cpp 项目: garinh/cs
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;
}
示例#30
0
文件: scf.cpp 项目: garinh/cs
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());
      }
    }
  }
}