$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r64159 - trunk/tools/build/v2/engine/src
From: ghost_at_[hidden]
Date: 2010-07-19 10:50:18
Author: vladimir_prus
Date: 2010-07-19 10:50:16 EDT (Mon, 19 Jul 2010)
New Revision: 64159
URL: http://svn.boost.org/trac/boost/changeset/64159
Log:
New builtin SELF_PATH
Text files modified: 
   trunk/tools/build/v2/engine/src/builtins.c |    21 ++++++++++++++                          
   trunk/tools/build/v2/engine/src/builtins.h |     1                                         
   trunk/tools/build/v2/engine/src/jam.c      |    59 ++++++++++++++++++++++++++++++++++++++++
   trunk/tools/build/v2/engine/src/pathsys.h  |     9 ++++++                                  
   4 files changed, 90 insertions(+), 0 deletions(-)
Modified: trunk/tools/build/v2/engine/src/builtins.c
==============================================================================
--- trunk/tools/build/v2/engine/src/builtins.c	(original)
+++ trunk/tools/build/v2/engine/src/builtins.c	2010-07-19 10:50:16 EDT (Mon, 19 Jul 2010)
@@ -381,6 +381,11 @@
                         builtin_precious, 0, args );
       }
 
+      {
+          char * args [] = { 0 };
+          bind_builtin( "SELF_PATH", builtin_self_path, 0, args );
+      }
+
       /* Initialize builtin modules. */
       init_set();
       init_path();
@@ -1707,6 +1712,22 @@
     return L0;
 }
 
+LIST *builtin_self_path( PARSE *parse, FRAME *frame )
+{
+    extern char *saved_argv0;
+    char *p = executable_path (saved_argv0);
+    if (p)
+    {
+        LIST* result = list_new (0, newstr (p));
+        free(p);
+        return result;
+    }
+    else
+    {
+        return L0;
+    }
+}
+
 
 #ifdef HAVE_PYTHON
 
Modified: trunk/tools/build/v2/engine/src/builtins.h
==============================================================================
--- trunk/tools/build/v2/engine/src/builtins.h	(original)
+++ trunk/tools/build/v2/engine/src/builtins.h	2010-07-19 10:50:16 EDT (Mon, 19 Jul 2010)
@@ -60,6 +60,7 @@
 LIST *builtin_file_open( PARSE *parse, FRAME *frame );
 LIST *builtin_pad( PARSE *parse, FRAME *frame );
 LIST *builtin_precious( PARSE *parse, FRAME *frame );
+LIST *builtin_self_path( PARSE *parse, FRAME *frame );
 
 void backtrace( FRAME *frame );
 extern int last_update_now_status;
Modified: trunk/tools/build/v2/engine/src/jam.c
==============================================================================
--- trunk/tools/build/v2/engine/src/jam.c	(original)
+++ trunk/tools/build/v2/engine/src/jam.c	2010-07-19 10:50:16 EDT (Mon, 19 Jul 2010)
@@ -210,6 +210,8 @@
     extern PyObject * bjam_backtrace    ( PyObject * self, PyObject * args );
 #endif
 
+char *saved_argv0;
+
 int main( int argc, char * * argv, char * * arg_environ )
 {
     int                     n;
@@ -221,6 +223,8 @@
     char          *       * arg_v = argv;
     char            const * progname = argv[0];
 
+    saved_argv0 = argv[0];
+
     BJAM_MEM_INIT();
 
 # ifdef OS_MAC
@@ -562,3 +566,58 @@
 
     return status ? EXITBAD : EXITOK;
 }
+
+#if defined(_WIN32)
+#include <windows.h>
+char *executable_path(char *arvg0) {
+    char buf[1024];
+    DWORD ret = GetModuleFileName(NULL, buf, sizeof(buf));
+    if (ret == 0 || ret == sizeof(buf)) return NULL;
+    return strdup (buf);
+}
+#elif defined(__APPLE__)  // Not tested
+#include <mach-o/dyld.h>
+char *executable_path(char *arvg0) {
+    char buf[1024];
+    uint32_t size = sizeof(buf);
+    int ret = _NSGetExecutablePath(buf, &size);
+    if (ret != 0) return NULL;
+    return strdup(buf);
+}
+#elif defined(sun) || defined(__sun) // Not tested
+#include <stdlib.h>
+
+char *executable_path(char *arvg0) {
+    return stdrup(getexecname());
+}
+#elif defined(__FreeBSD__)
+#include <sys/sysctl.h>
+char *executable_path(char *arvg0) {
+    int mib[4];
+    mib[0] = CTL_KERN;
+    mib[1] = KERN_PROC;
+    mib[2] = KERN_PROC_PATHNAME;
+    mib[3] = -1;
+    char buf[1024];
+    size_t size = sizeof(buf);
+    sysctl(mib, 4, buf, &size, NULL, 0);
+    if (size == 0 || size == sizeof(buf)) return NULL;
+    return strndup(buf, size);
+}
+#elif defined(__linux__)
+#include <unistd.h>
+char *executable_path(char *arvg0) {
+    char buf[1024];
+    ssize_t ret = readlink("/proc/self/exe", buf, sizeof(buf));
+    if (ret == 0 || ret == sizeof(buf)) return NULL;
+    return strndup(buf, ret);
+}
+#else
+char *executable_path(char *arvg0) {
+    // If argv0 is absolute path, assume it's the right
+    // absolute path.
+    if (argv0[0] == "/")
+        return strdup(argv0);
+    return NULL;
+}
+#endif
Modified: trunk/tools/build/v2/engine/src/pathsys.h
==============================================================================
--- trunk/tools/build/v2/engine/src/pathsys.h	(original)
+++ trunk/tools/build/v2/engine/src/pathsys.h	2010-07-19 10:50:16 EDT (Mon, 19 Jul 2010)
@@ -79,4 +79,13 @@
 const char * path_tmpfile( void );
 #endif
 
+/** Give the first argument to 'main', return a full path to
+    our executable.  Returns null in the unlikely case it
+    cannot be determined. Caller is responsible for freeing
+    the string.
+
+    Implemented in jam.c
+*/
+char * executable_path (char *argv0);
+
 #endif