Fix typo in r428 (csdlib -> cstdlib)
[synfig.git] / ETL / trunk / ETL / _stringf.h
index 21a7190..5c3642a 100644 (file)
@@ -1,7 +1,7 @@
 /* =========================================================================
 ** Extended Template and Library
 ** stringf Prodecure Implementation
-** $Id: _stringf.h,v 1.1.1.1 2005/01/04 01:31:48 darco Exp $
+** $Id$
 **
 ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
 **
@@ -31,6 +31,7 @@
 
 #include <string>
 #include <cstdarg>
+#include <cstdlib>
 
 /* === M A C R O S ========================================================= */
 
@@ -53,11 +54,7 @@ _ETL_BEGIN_CDECLS
 #else
 
 # ifdef HAVE_VSNPRINTF // This is the secondary method
-#  if defined(__CYGWIN__)  || defined(_WIN32)
-extern int vsnprintf(char *,unsigned int,const char*,va_list)ETL_NO_THROW;
-#  else
-extern int vsnprintf(char *,int,const char*,va_list)ETL_NO_THROW;
-#  endif
+ extern int vsnprintf(char *,size_t,const char*,va_list)ETL_NO_THROW;
 # endif
 
 #endif
@@ -197,14 +194,12 @@ inline bool
 is_absolute_path(const std::string &path)
 {
 #ifdef WIN32
-       if(path.size()>=3 && path[1]==':' && path[2]=='\\')
+       if(path.size()>=3 && path[1]==':' && (path[2]=='\\' || path[2]=='/'))
                return true;
-       return false;
-#else
+#endif
        if(!path.empty() && path[0]==ETL_DIRECTORY_SEPERATOR)
                return true;
        return false;
-#endif 
 }
 
 inline std::string
@@ -241,14 +236,14 @@ get_root_from_path(std::string path)
 {
        std::string ret;
        std::string::const_iterator iter;
-       
+
        for(iter=path.begin();iter!=path.end();++iter)
        {
                if(*iter==ETL_DIRECTORY_SEPERATOR)
                        break;
                ret+=*iter;
        }
-       if(iter!=path.end())
+       //if(iter!=path.end())
                ret+=ETL_DIRECTORY_SEPERATOR;
        return ret;
 }
@@ -274,21 +269,22 @@ cleanup_path(std::string path)
        std::string ret;
 
        while(basename(path)==".")path=dirname(path);
-       
+
        while(!path.empty())
        {
                std::string dir(get_root_from_path(path));
-               if(dir=="../" && ret.size())
+               if((dir=="../" || dir=="..\\") && ret.size())
                {
                        ret=dirname(ret)+ETL_DIRECTORY_SEPERATOR;
                }
-               else if(dir!="./" && dir!=".")
+               else if((dir!="./" && dir!=".\\") && dir!=".")
                {
                        ret+=dir;
                }
                path=remove_root_from_path(path);
        }
-       
+
+       // Remove any trailing directory seperators
        if(ret.size() && ret[ret.size()-1]==ETL_DIRECTORY_SEPERATOR)
        {
                ret.erase(ret.begin()+ret.size()-1);
@@ -300,7 +296,7 @@ inline std::string
 absolute_path(std::string path)
 {
        std::string ret(current_working_directory());
-       
+
        if(path.empty())
                return cleanup_path(ret);
        if(is_absolute_path(path))
@@ -311,19 +307,33 @@ absolute_path(std::string path)
 
 inline std::string
 relative_path(std::string curr_path,std::string dest_path)
-{      
+{
        // If dest_path is already a relative path,
        // then there is no need to do anything.
        if(!is_absolute_path(dest_path))
                dest_path=absolute_path(dest_path);
        else
                dest_path=cleanup_path(dest_path);
-       
+
        if(!is_absolute_path(curr_path))
                curr_path=absolute_path(curr_path);
        else
                curr_path=cleanup_path(curr_path);
-       
+
+#ifdef WIN32
+       // If we are on windows and the dest path is on a different drive,
+       // then there is no way to make a relative path to it.
+       if(dest_path.size()>=3 && dest_path[1]==':' && dest_path[0]!=curr_path[0])
+       {
+               return dest_path;
+       }
+#endif
+
+       if(curr_path==dirname(dest_path))
+       {
+               return basename(dest_path);
+       }
+
        while(!dest_path.empty() && !curr_path.empty() && get_root_from_path(dest_path)==get_root_from_path(curr_path))
        {
                dest_path=remove_root_from_path(dest_path);
@@ -332,10 +342,10 @@ relative_path(std::string curr_path,std::string dest_path)
 
        while(!curr_path.empty())
        {
-               dest_path="../"+dest_path;
+               dest_path=std::string("..")+ETL_DIRECTORY_SEPERATOR+dest_path;
                curr_path=remove_root_from_path(curr_path);
        }
-       
+
        return dest_path;
 }