[xbuild] Fix bug #671700, resource naming in presence of "Link".
[mono.git] / eglib / src / gpath.c
index 3991d08e47cceca1744c84fd478670b334411305..39c6aa150be3fc94d6b141351947a006637ae8d9 100644 (file)
  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
+#include <config.h>
 #include <stdio.h>
 #include <glib.h>
-#include <unistd.h>
 #include <errno.h>
-#include <sys/types.h>
-#include <pwd.h>
-#include <pthread.h>
+
+#ifdef G_OS_WIN32
+#include <direct.h> 
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
 
 gchar *
 g_build_path (const gchar *separator, const gchar *first_element, ...)
 {
        GString *result;
        const char *s, *p, *next;
-       int slen;
+       size_t slen;
        va_list args;
        
        g_return_val_if_fail (separator != NULL, NULL);
-       g_return_val_if_fail (first_element != NULL, NULL);
+
+       if (first_element == NULL)
+               return g_strdup ("");
 
        result = g_string_sized_new (48);
 
@@ -61,7 +68,8 @@ g_build_path (const gchar *separator, const gchar *first_element, ...)
                g_string_append_len (result, s, p - s);
 
                if (next && *next){
-                       g_string_append (result, separator);
+                       if (strncmp (separator, result->str + strlen (result->str) - slen, slen))
+                               g_string_append (result, separator);
 
                        for (; strncmp (next, separator, slen) == 0; )
                                next += slen;
@@ -77,7 +85,7 @@ gchar *
 g_path_get_dirname (const gchar *filename)
 {
        char *p, *r;
-       int count;
+       size_t count;
        g_return_val_if_fail (filename != NULL, NULL);
 
        p = strrchr (filename, G_DIR_SEPARATOR);
@@ -126,20 +134,73 @@ g_path_get_basename (const char *filename)
        return g_strdup (&r[1]);
 }
 
-gboolean
-g_path_is_absolute (const char *filename)
+#ifndef HAVE_STRTOK_R
+// This is from BSD's strtok_r
+
+char *
+strtok_r(char *s, const char *delim, char **last)
 {
-       g_return_val_if_fail (filename != NULL, FALSE);
-       return (*filename == '/');
+       char *spanp;
+       int c, sc;
+       char *tok;
+       
+       if (s == NULL && (s = *last) == NULL)
+               return NULL;
+       
+       /*
+        * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
+        */
+cont:
+       c = *s++;
+       for (spanp = (char *)delim; (sc = *spanp++) != 0; ){
+               if (c == sc)
+                       goto cont;
+       }
+
+       if (c == 0){         /* no non-delimiter characters */
+               *last = NULL;
+               return NULL;
+       }
+       tok = s - 1;
+
+       /*
+        * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
+        * Note that delim must have one NUL; we stop if we see that, too.
+        */
+       for (;;){
+               c = *s++;
+               spanp = (char *)delim;
+               do {
+                       if ((sc = *spanp++) == c) {
+                               if (c == 0)
+                                       s = NULL;
+                               else {
+                                       char *w = s - 1;
+                                       *w = '\0';
+                               }
+                               *last = s;
+                               return tok;
+                       }
+               }
+               while (sc != 0);
+       }
+       /* NOTREACHED */
 }
+#endif
 
 gchar *
 g_find_program_in_path (const gchar *program)
 {
-       char *p = g_strdup (getenv ("PATH"));
+       char *p = g_strdup (g_getenv ("PATH"));
        char *x = p, *l;
        gchar *curdir = NULL;
        char *save;
+#ifdef G_OS_WIN32
+       char *program_exe;
+       char *suffix_list[5] = {".exe",".cmd",".bat",".com",NULL};
+       int listx;
+       gboolean hasSuffix;
+#endif
 
        g_return_val_if_fail (program != NULL, NULL);
 
@@ -148,104 +209,50 @@ g_find_program_in_path (const gchar *program)
                x = curdir;
        }
 
+#ifdef G_OS_WIN32
+       /* see if program already has a suffix */
+       listx = 0;
+       hasSuffix = FALSE;
+       while (!hasSuffix && suffix_list[listx]) {
+               hasSuffix = g_str_has_suffix(program,suffix_list[listx++]);
+       }
+#endif
+
        while ((l = strtok_r (x, G_SEARCHPATH_SEPARATOR_S, &save)) != NULL){
                char *probe_path; 
                
                x = NULL;
                probe_path = g_build_path (G_DIR_SEPARATOR_S, l, program, NULL);
-               if (access (probe_path, X_OK) == 0){
+               if (access (probe_path, X_OK) == 0){ /* FIXME: on windows this is just a read permissions test */
                        g_free (curdir);
                        g_free (p);
                        return probe_path;
                }
                g_free (probe_path);
-       }
-       g_free (curdir);
-       g_free (p);
-       return NULL;
-}
-
-gchar *
-g_get_current_dir (void)
-{
-       int s = 32;
-       char *buffer = NULL, *r;
-       gboolean fail;
-       
-       do {
-               buffer = g_realloc (buffer, s);
-               r = getcwd  (buffer, s);
-               fail = (r == NULL && errno == ERANGE);
-               if (fail) {
-                       s <<= 1;
-               }
-       } while (fail);
-
-       return r;
-}
-
-static pthread_mutex_t home_lock = PTHREAD_MUTEX_INITIALIZER;
-static char *home_dir;
 
-/* Give preference to /etc/passwd than HOME */
-const gchar *
-g_get_home_dir (void)
-{
-       if (home_dir == NULL){
-               uid_t uid;
-
-               pthread_mutex_lock (&home_lock);
-               if (home_dir == NULL){
-                       struct passwd pwbuf, *track;
-                       char buf [4096];
-                       
-                       uid = getuid ();
-
-                       setpwent ();
-                       
-                       while (getpwent_r (&pwbuf, buf, sizeof (buf), &track) == 0){
-                               if (pwbuf.pw_uid == uid){
-                                       home_dir = g_strdup (pwbuf.pw_dir);
-                                       break;
+#ifdef G_OS_WIN32
+               /* check for program with a suffix attached */
+               if (!hasSuffix) {
+                       listx = 0;
+                       while (suffix_list[listx]) {
+                               program_exe = g_strjoin(NULL,program,suffix_list[listx],NULL);
+                               probe_path = g_build_path (G_DIR_SEPARATOR_S, l, program_exe, NULL);
+                               if (access (probe_path, X_OK) == 0){ /* FIXME: on windows this is just a read permissions test */
+                                       g_free (curdir);
+                                       g_free (p);
+                                       g_free (program_exe);
+                                       return probe_path;
                                }
+                               listx++;
+                               g_free (probe_path);
+                               g_free (program_exe);
                        }
-                       endpwent ();
-                       if (home_dir == NULL)
-                               home_dir = getenv ("HOME");
-                       pthread_mutex_unlock (&home_lock);
                }
+#endif
        }
-       return home_dir;
-}
-
-static char *tmp_dir;
-static pthread_mutex_t tmp_lock = PTHREAD_MUTEX_INITIALIZER;
-
-const gchar *
-g_get_tmp_dir (void)
-{
-       if (tmp_dir == NULL){
-               pthread_mutex_lock (&tmp_lock);
-               if (tmp_dir == NULL){
-                       tmp_dir = getenv ("TMPDIR");
-                       if (tmp_dir == NULL){
-                               tmp_dir = getenv ("TMP");
-                               if (tmp_dir == NULL){
-                                       tmp_dir = getenv ("TEMP");
-                                       if (tmp_dir == NULL)
-                                               tmp_dir = "/tmp";
-                               }
-                       }
-               }
-               pthread_mutex_unlock (&tmp_lock);
-       }
-       return tmp_dir;
-}
-
-const char *
-g_get_user_name (void)
-{
-       return getenv ("USER");
+       g_free (curdir);
+       g_free (p);
+       return NULL;
 }
 
 static char *name;