2 * Portable Utility Functions
5 * Miguel de Icaza (miguel@novell.com)
7 * (C) 2006 Novell, Inc.
9 * Permission is hereby granted, free of charge, to any person obtaining
10 * a copy of this software and associated documentation files (the
11 * "Software"), to deal in the Software without restriction, including
12 * without limitation the rights to use, copy, modify, merge, publish,
13 * distribute, sublicense, and/or sell copies of the Software, and to
14 * permit persons to whom the Software is furnished to do so, subject to
15 * the following conditions:
17 * The above copyright notice and this permission notice shall be
18 * included in all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
42 g_build_path (const gchar
*separator
, const gchar
*first_element
, ...)
45 const char *s
, *p
, *next
;
49 g_return_val_if_fail (separator
!= NULL
, NULL
);
51 if (first_element
== NULL
)
54 result
= g_string_sized_new (48);
56 slen
= strlen (separator
);
58 va_start (args
, first_element
);
59 for (s
= first_element
; s
!= NULL
; s
= next
){
60 next
= va_arg (args
, char *);
63 if (next
&& p
- slen
> s
){
64 for (; strncmp (p
-slen
, separator
, slen
) == 0; ){
68 g_string_append_len (result
, s
, p
- s
);
71 if (strncmp (separator
, result
->str
+ strlen (result
->str
) - slen
, slen
))
72 g_string_append (result
, separator
);
74 for (; strncmp (next
, separator
, slen
) == 0; )
78 g_string_append_c (result
, 0);
81 return g_string_free (result
, FALSE
);
85 g_path_get_dirname (const gchar
*filename
)
89 g_return_val_if_fail (filename
!= NULL
, NULL
);
91 p
= strrchr (filename
, G_DIR_SEPARATOR
);
93 return g_strdup (".");
95 return g_strdup ("/");
97 r
= g_malloc (count
+ 1);
98 strncpy (r
, filename
, count
);
105 g_path_get_basename (const char *filename
)
108 g_return_val_if_fail (filename
!= NULL
, NULL
);
110 /* Empty filename -> . */
112 return g_strdup (".");
114 /* No separator -> filename */
115 r
= strrchr (filename
, G_DIR_SEPARATOR
);
117 return g_strdup (filename
);
119 /* Trailing slash, remove component */
121 char *copy
= g_strdup (filename
);
122 copy
[r
-filename
] = 0;
123 r
= strrchr (copy
, G_DIR_SEPARATOR
);
127 return g_strdup ("/");
129 r
= g_strdup (&r
[1]);
134 return g_strdup (&r
[1]);
137 #ifndef HAVE_STRTOK_R
138 // This is from BSD's strtok_r
141 strtok_r(char *s
, const char *delim
, char **last
)
147 if (s
== NULL
&& (s
= *last
) == NULL
)
151 * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
155 for (spanp
= (char *)delim
; (sc
= *spanp
++) != 0; ){
160 if (c
== 0){ /* no non-delimiter characters */
167 * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
168 * Note that delim must have one NUL; we stop if we see that, too.
172 spanp
= (char *)delim
;
174 if ((sc
= *spanp
++) == c
) {
192 g_find_program_in_path (const gchar
*program
)
194 char *p
= g_strdup (g_getenv ("PATH"));
196 gchar
*curdir
= NULL
;
199 g_return_val_if_fail (program
!= NULL
, NULL
);
201 if (x
== NULL
|| *x
== '\0') {
202 curdir
= g_get_current_dir ();
206 while ((l
= strtok_r (x
, G_SEARCHPATH_SEPARATOR_S
, &save
)) != NULL
){
210 probe_path
= g_build_path (G_DIR_SEPARATOR_S
, l
, program
, NULL
);
211 if (access (probe_path
, X_OK
) == 0){ /* FIXME: on windows this is just a read permissions test */
226 g_set_prgname (const gchar
*prgname
)
228 name
= g_strdup (prgname
);