Orb/Doxygen/src/portable.cpp
changeset 3 d8fccb2cd802
parent 0 42188c7ea2d9
child 4 468f4c8d3d5b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Orb/Doxygen/src/portable.cpp	Fri Apr 23 20:47:58 2010 +0100
@@ -0,0 +1,375 @@
+#include <stdlib.h>
+#include <ctype.h>
+#if defined(_WIN32) && !defined(__CYGWIN__)
+#undef UNICODE
+#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 <qglobal.h>
+#include <qdatetime.h>
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+#define popen _popen
+#define pclose _pclose
+#endif
+
+#include "portable.h"
+#ifndef NODEBUG
+#include "debug.h"
+#endif
+//#include "doxygen.h"
+
+static double  sysElapsedTime;
+
+int  portable_system(const char *command,const char *args,bool commandHasConsole)
+{
+  QTime time;
+  time.start();
+
+  if (command==0) return 1;
+
+  QCString fullCmd=command;
+  fullCmd=fullCmd.stripWhiteSpace();
+  if (fullCmd.at(0)!='"' && fullCmd.find(' ')!=-1)
+  {
+    // add quotes around command as it contains spaces and is not quoted already
+    fullCmd="\""+fullCmd+"\"";
+  }
+  fullCmd += " ";
+  fullCmd += args;
+#ifndef NODEBUG
+  Debug::print(Debug::ExtCmd,0,"Executing external command `%s`\n",fullCmd.data());
+#endif
+
+#if !defined(_WIN32) || defined(__CYGWIN__)
+  commandHasConsole=commandHasConsole;
+  /*! taken from the system() manpage on my Linux box */
+  int pid,status=0;
+
+#ifdef _OS_SOLARIS // for Solaris we use vfork since it is more memory efficient
+
+  // on Solaris fork() duplicates the memory usage
+  // so we use vfork instead
+  
+  // spawn shell
+  if ((pid=vfork())<0)
+  {
+    status=-1;
+  }
+  else if (pid==0)
+  {
+     execl("/bin/sh","sh","-c",fullCmd.data(),(char*)0);
+     _exit(127);
+  }
+  else
+  {
+    while (waitpid(pid,&status,0 )<0)
+    {
+      if (errno!=EINTR)
+      {
+        status=-1;
+        break;
+      }
+    }
+  }
+  sysElapsedTime+=((double)time.elapsed())/1000.0;
+  return status;
+
+#else  // Other Unices just use fork
+
+  pid = fork();
+  if (pid==-1) return -1;
+  if (pid==0)
+  {
+    const char * argv[4];
+    argv[0] = "sh";
+    argv[1] = "-c";
+    argv[2] = fullCmd.data();
+    argv[3] = 0;
+    execve("/bin/sh",(char * const *)argv,environ);
+    exit(127);
+  }
+  for (;;)
+  {
+    if (waitpid(pid,&status,0)==-1)
+    {
+      if (errno!=EINTR) return -1;
+    }
+    else
+    {
+      sysElapsedTime+=((double)time.elapsed())/1000.0;
+      if (WIFEXITED(status))
+      {
+        return WEXITSTATUS(status);
+      }
+      else
+      {
+        return status;
+      }
+    }
+  }
+#endif // !_OS_SOLARIS
+
+#else // Win32 specific
+  if (commandHasConsole)
+  {
+    return system(fullCmd);
+  }
+  else
+  {
+    // gswin32 is a GUI api which will pop up a window and run
+    // asynchronously. To prevent both, we use ShellExecuteEx and
+    // WaitForSingleObject (thanks to Robert Golias for the code)
+
+    SHELLEXECUTEINFO sInfo = {
+      sizeof(SHELLEXECUTEINFO),   /* structure size */
+      SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI,  /* tell us the process
+                                                       *  handle so we can wait till it's done | 
+                                                       *  do not display msg box if error 
+                                                       */
+      NULL,                       /* window handle */
+      NULL,                       /* action to perform: open */
+      command,                    /* file to execute */
+      args,                       /* argument list */ 
+      NULL,                       /* use current working dir */
+      SW_HIDE,                    /* minimize on start-up */
+      0,                          /* application instance handle */
+      NULL,                       /* ignored: id list */
+      NULL,                       /* ignored: class name */
+      NULL,                       /* ignored: key class */
+      0,                          /* ignored: hot key */
+      NULL,                       /* ignored: icon */
+      NULL                        /* resulting application handle */
+    };
+    if (!ShellExecuteEx(&sInfo))
+    {
+      return -1;
+    }
+    else if (sInfo.hProcess)      /* executable was launched, wait for it to finish */
+    {
+      WaitForSingleObject(sInfo.hProcess,INFINITE); 
+      CloseHandle(sInfo.hProcess);
+    }
+  }
+  sysElapsedTime+=((double)time.elapsed())/1000.0;
+  return 0;
+#endif
+
+}
+
+uint portable_pid()
+{
+  uint pid;
+#if !defined(_WIN32) || defined(__CYGWIN__)
+  pid = (uint)getpid();
+#else
+  pid = (uint)GetCurrentProcessId();
+#endif
+  return pid;
+}
+
+static char **last_environ;
+
+void portable_setenv(const char *name,const char *value)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+    SetEnvironmentVariable(name,value);
+#else
+    register char **ep = 0;
+    register size_t size;
+    const size_t namelen=strlen(name);
+    const size_t vallen=strlen(value) + 1;
+
+    size = 0;
+    if (environ!=0)
+    {
+      for (ep = environ; *ep; ++ep)
+      {
+        if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=')
+          break;
+        else
+          ++size;
+      }
+    }
+
+    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 *));
+      }
+
+      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 = strlen (*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);
+    }
+
+#endif
+}
+
+void portable_unsetenv(const char *variable)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+    SetEnvironmentVariable(variable,0);
+#else
+    /* Some systems don't have unsetenv(), so we do it ourselves */
+    size_t len;
+    char **ep;
+
+    if (variable == NULL || *variable == '\0' || strchr (variable, '=') != NULL)
+    {
+      return; // not properly formatted
+    }
+
+    len = strlen(variable);
+
+    ep = environ;
+    while (*ep != NULL)
+    {
+      if (!strncmp(*ep, variable, 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;
+      }
+    }
+#endif
+}
+
+const char *portable_getenv(const char *variable)
+{
+  return getenv(variable);
+}
+
+portable_off_t portable_fseek(FILE *f,portable_off_t offset, int whence)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+  return _fseeki64(f,offset,whence);
+#else
+  return fseeko(f,offset,whence);
+#endif
+}
+
+portable_off_t portable_ftell(FILE *f)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+  return _ftelli64(f);
+#else
+  return ftello(f);
+#endif
+}
+
+char  portable_pathSeparator()
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+  return '\\';
+#else
+  return '/';
+#endif
+}
+
+char  portable_pathListSeparator()
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+  return ';';
+#else
+  return ':';
+#endif
+}
+
+const char *portable_ghostScriptCommand()
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+    return "gswin32c.exe";
+#else
+    return "gs";
+#endif
+}
+
+const char *portable_commandExtension()
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+    return ".exe";
+#else
+    return "";
+#endif
+}
+
+bool portable_fileSystemIsCaseSensitive()
+{
+#if defined(_WIN32) || defined(macintosh) || defined(__MACOSX__) || defined(__APPLE__)
+  return FALSE;
+#else
+  return TRUE;
+#endif
+}
+
+FILE * portable_popen(const char *name,const char *type)
+{
+  return popen(name,type);
+}
+
+int portable_pclose(FILE *stream)
+{
+  return pclose(stream);
+}
+
+double portable_getSysElapsedTime()
+{
+  return sysElapsedTime;
+}
+