summaryrefslogtreecommitdiffstats
path: root/src/portable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/portable.cpp')
-rw-r--r--src/portable.cpp292
1 files changed, 166 insertions, 126 deletions
diff --git a/src/portable.cpp b/src/portable.cpp
index 3d64638..3ee1081 100644
--- a/src/portable.cpp
+++ b/src/portable.cpp
@@ -1,36 +1,43 @@
+#include "portable.h"
+
#include <stdlib.h>
-#include <ctype.h>
+#include <stdio.h>
+
#if defined(_WIN32) && !defined(__CYGWIN__)
#undef UNICODE
#define _WIN32_DCOM
#include <windows.h>
#else
#include <unistd.h>
-#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
extern char **environ;
#endif
+#include <ctype.h>
#include <qglobal.h>
#include <qdatetime.h>
+#include <qglobal.h>
+#include <qdir.h>
+#include <map>
+#include <string>
-#if defined(_MSC_VER) || defined(__BORLANDC__)
-#define popen _popen
-#define pclose _pclose
-#endif
-
-#include "portable.h"
#include "util.h"
#ifndef NODEBUG
#include "debug.h"
#endif
+#if !defined(_WIN32) || defined(__CYGWIN__)
+static bool environmentLoaded = false;
+static std::map<std::string,std::string> proc_env = std::map<std::string,std::string>();
+#endif
+
static double g_sysElapsedTime;
static QTime g_time;
-int portable_system(const char *command,const char *args,bool commandHasConsole)
+
+int Portable::system(const char *command,const char *args,bool commandHasConsole)
{
if (command==0) return 1;
@@ -127,7 +134,7 @@ int portable_system(const char *command,const char *args,bool commandHasConsole)
#else // Win32 specific
if (commandHasConsole)
{
- return system(fullCmd);
+ return ::system(fullCmd);
}
else
{
@@ -189,13 +196,13 @@ int portable_system(const char *command,const char *args,bool commandHasConsole)
}
-uint portable_pid()
+unsigned int Portable::pid(void)
{
- uint pid;
+ unsigned int pid;
#if !defined(_WIN32) || defined(__CYGWIN__)
- pid = (uint)getpid();
+ pid = (unsigned int)getpid();
#else
- pid = (uint)GetCurrentProcessId();
+ pid = (unsigned int)GetCurrentProcessId();
#endif
return pid;
}
@@ -205,88 +212,50 @@ uint portable_pid()
static char **last_environ;
#endif
-void portable_setenv(const char *name,const char *value)
+#if !defined(_WIN32) || defined(__CYGWIN__)
+void loadEnvironment()
{
- if (value==0) value="";
-#if defined(_WIN32) && !defined(__CYGWIN__)
- SetEnvironmentVariable(name,value);
-#else
- char **ep = 0;
- size_t size;
- const size_t namelen=qstrlen(name);
- const size_t vallen=qstrlen(value) + 1;
+ if(environ != NULL)
+ {
+ unsigned int i = 0;
+ char* current = environ[i];
- size = 0;
- if (environ!=0)
+ while(current != NULL) // parse all strings contained by environ til the last element (NULL)
{
- for (ep = environ; *ep; ++ep)
- {
- if (!qstrncmp (*ep, name, (uint)namelen) &&
- (*ep)[namelen] == '=')
- break;
- else
- ++size;
+ std::string env_var(current); // load current environment variable string
+ size_t pos = env_var.find("=");
+ if(pos != std::string::npos) // only parse the variable, if it is a valid environment variable...
+ { // ...which has to contain an equal sign as delimiter by definition
+ std::string name = env_var.substr(0,pos); // the string til the equal sign contains the name
+ std::string value = env_var.substr(pos + 1); // the string from the equal sign contains the value
+
+ proc_env[name] = value; // save the value by the name as its key in the classes map
}
+ i++;
+ current = environ[i];
}
+ }
- if (environ==0 || *ep==0) /* add new string */
- {
- char **new_environ;
- if (environ == last_environ && environ!=0)
- {
- // We allocated this space; we can extend it.
- new_environ = (char **) realloc (last_environ, (size + 2) * sizeof (char *));
- }
- else
- {
- new_environ = (char **) malloc ((size + 2) * sizeof (char *));
- }
-
- if (new_environ==0) // no more memory
- {
- return;
- }
-
- new_environ[size] = (char *)malloc (namelen + 1 + vallen);
- if (new_environ[size]==0)
- {
- free (new_environ);
- return;
- }
-
- if (environ != last_environ)
- {
- memcpy ((char *) new_environ, environ, size * sizeof (char *));
- }
+ environmentLoaded = true;
+}
+#endif
- memcpy(new_environ[size], name, namelen);
- new_environ[size][namelen] = '=';
- memcpy(&new_environ[size][namelen + 1], value, vallen);
- new_environ[size + 1] = 0;
- last_environ = environ = new_environ;
- }
- else /* replace existing string */
- {
- size_t len = qstrlen (*ep);
- if (len + 1 < namelen + 1 + vallen)
- {
- /* The existing string is too short; malloc a new one. */
- char *newString = (char *)malloc(namelen + 1 + vallen);
- if (newString==0)
- {
- return;
- }
- *ep = newString;
- }
- memcpy(*ep, name, namelen);
- (*ep)[namelen] = '=';
- memcpy(&(*ep)[namelen + 1], value, vallen);
+void Portable::setenv(const char *name,const char *value)
+{
+ if (value==0) value="";
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ SetEnvironmentVariable(name,value);
+#else
+ if(!environmentLoaded) // if the environment variables are not loaded already...
+ { // ...call loadEnvironment to store them in class
+ loadEnvironment();
}
+ proc_env[name] = std::string(value); // create or replace exisiting value
#endif
}
-void portable_unsetenv(const char *variable)
+void Portable::unsetenv(const char *variable)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
SetEnvironmentVariable(variable,0);
@@ -300,32 +269,35 @@ void portable_unsetenv(const char *variable)
return; // not properly formatted
}
- len = qstrlen(variable);
-
- ep = environ;
- while (*ep != NULL)
+ if(proc_env.find(variable) != proc_env.end())
{
- if (!qstrncmp(*ep, variable, (uint)len) && (*ep)[len]=='=')
- {
- /* Found it. Remove this pointer by moving later ones back. */
- char **dp = ep;
- do dp[0] = dp[1]; while (*dp++);
- /* Continue the loop in case NAME appears again. */
- }
- else
- {
- ++ep;
- }
+ proc_env[variable].erase();
}
#endif
}
-const char *portable_getenv(const char *variable)
-{
- return getenv(variable);
+const char *Portable::getenv(const char *variable)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ return ::getenv(variable);
+#else
+ if(!environmentLoaded) // if the environment variables are not loaded already...
+ { // ...call loadEnvironment to store them in class
+ loadEnvironment();
+ }
+
+ if(proc_env.find(variable) != proc_env.end())
+ {
+ return proc_env[variable].c_str();
+ }
+ else
+ {
+ return NULL;
+ }
+#endif
}
-portable_off_t portable_fseek(FILE *f,portable_off_t offset, int whence)
+portable_off_t Portable::fseek(FILE *f,portable_off_t offset, int whence)
{
#if defined(__MINGW32__)
return fseeko64(f,offset,whence);
@@ -336,7 +308,7 @@ portable_off_t portable_fseek(FILE *f,portable_off_t offset, int whence)
#endif
}
-portable_off_t portable_ftell(FILE *f)
+portable_off_t Portable::ftell(FILE *f)
{
#if defined(__MINGW32__)
return ftello64(f);
@@ -347,18 +319,18 @@ portable_off_t portable_ftell(FILE *f)
#endif
}
-FILE *portable_fopen(const char *fileName,const char *mode)
+FILE *Portable::fopen(const char *fileName,const char *mode)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
QString fn(fileName);
QString m(mode);
return _wfopen((wchar_t*)fn.ucs2(),(wchar_t*)m.ucs2());
#else
- return fopen(fileName,mode);
+ return ::fopen(fileName,mode);
#endif
}
-char portable_pathSeparator()
+char Portable::pathSeparator(void)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
return '\\';
@@ -367,7 +339,7 @@ char portable_pathSeparator()
#endif
}
-char portable_pathListSeparator()
+char Portable::pathListSeparator(void)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
return ';';
@@ -376,7 +348,7 @@ char portable_pathListSeparator()
#endif
}
-const char *portable_ghostScriptCommand()
+const char *Portable::ghostScriptCommand(void)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
return "gswin32c.exe";
@@ -385,7 +357,7 @@ const char *portable_ghostScriptCommand()
#endif
}
-const char *portable_commandExtension()
+const char *Portable::commandExtension(void)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
return ".exe";
@@ -394,7 +366,7 @@ const char *portable_commandExtension()
#endif
}
-bool portable_fileSystemIsCaseSensitive()
+bool Portable::fileSystemIsCaseSensitive(void)
{
#if defined(_WIN32) || defined(macintosh) || defined(__MACOSX__) || defined(__APPLE__) || defined(__CYGWIN__)
return FALSE;
@@ -403,32 +375,40 @@ bool portable_fileSystemIsCaseSensitive()
#endif
}
-FILE * portable_popen(const char *name,const char *type)
+FILE * Portable::popen(const char *name,const char *type)
{
- return popen(name,type);
+ #if defined(_MSC_VER) || defined(__BORLANDC__)
+ return ::_popen(name,type);
+ #else
+ return ::popen(name,type);
+ #endif
}
-int portable_pclose(FILE *stream)
+int Portable::pclose(FILE *stream)
{
- return pclose(stream);
+ #if defined(_MSC_VER) || defined(__BORLANDC__)
+ return ::_pclose(stream);
+ #else
+ return ::pclose(stream);
+ #endif
}
-void portable_sysTimerStart()
+void Portable::sysTimerStart(void)
{
g_time.start();
}
-void portable_sysTimerStop()
+void Portable::sysTimerStop(void)
{
g_sysElapsedTime+=((double)g_time.elapsed())/1000.0;
}
-double portable_getSysElapsedTime()
+double Portable::getSysElapsedTime(void)
{
return g_sysElapsedTime;
}
-void portable_sleep(int ms)
+void Portable::sleep(int ms)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
Sleep(ms);
@@ -437,7 +417,7 @@ void portable_sleep(int ms)
#endif
}
-bool portable_isAbsolutePath(const char *fileName)
+bool Portable::isAbsolutePath(const char *fileName)
{
# ifdef _WIN32
if (isalpha (fileName [0]) && fileName[1] == ':')
@@ -457,24 +437,84 @@ bool portable_isAbsolutePath(const char *fileName)
/**
* Correct a possible wrong PATH variable
*
- * This routine was inspired by the cause for bug 766059 was that in the Windows path there were forward slahes.
+ * This routine was inspired by the cause for bug 766059 was that in the Windows path there were forward slashes.
*/
-void portable_correct_path(void)
+void Portable::correct_path(void)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
- const char *p = portable_getenv("PATH");
+ const char *p = Portable::getenv("PATH");
if (!p) return; // no path nothing to correct
QCString result = substitute(p,'/','\\');
- if (result!=p) portable_setenv("PATH",result.data());
+ if (result!=p) Portable::setenv("PATH",result.data());
#endif
}
-void portable_unlink(const char *fileName)
+void Portable::unlink(const char *fileName)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
_unlink(fileName);
#else
- unlink(fileName);
+ ::unlink(fileName);
#endif
}
+void Portable::setShortDir(void)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ long length = 0;
+ TCHAR* buffer = NULL;
+ // First obtain the size needed by passing NULL and 0.
+ length = GetShortPathName(QDir::currentDirPath().data(), NULL, 0);
+ // Dynamically allocate the correct size
+ // (terminating null char was included in length)
+ buffer = new TCHAR[length];
+ // Now simply call again using same (long) path.
+ length = GetShortPathName(QDir::currentDirPath().data(), buffer, length);
+ // Set the correct directory (short name)
+ QDir::setCurrent(buffer);
+ delete [] buffer;
+#endif
+}
+
+/* Return the first occurrence of NEEDLE in HAYSTACK. */
+static const char * portable_memmem (const char *haystack, size_t haystack_len,
+ const char *needle, size_t needle_len)
+{
+ const char *const last_possible = haystack + haystack_len - needle_len;
+
+ if (needle_len == 0)
+ // The first occurrence of the empty string should to occur at the beginning of the string.
+ {
+ return haystack;
+ }
+
+ // Sanity check
+ if (haystack_len < needle_len)
+ {
+ return 0;
+ }
+
+ for (const char *begin = haystack; begin <= last_possible; ++begin)
+ {
+ if (begin[0] == needle[0] && !memcmp(&begin[1], needle + 1, needle_len - 1))
+ {
+ return begin;
+ }
+ }
+
+ return 0;
+}
+
+const char *Portable::strnstr(const char *haystack, const char *needle, size_t haystack_len)
+{
+ size_t needle_len = strnlen(needle, haystack_len);
+ if (needle_len < haystack_len || !needle[needle_len])
+ {
+ const char *x = portable_memmem(haystack, haystack_len, needle, needle_len);
+ if (x && !memchr(haystack, 0, x - haystack))
+ {
+ return x;
+ }
+ }
+ return 0;
+}