Reshuffle some functions between gutils and gfileutils

Move filename-related functions to gfileutils, and move
size formatting functions to gutils.
This commit is contained in:
Matthias Clasen 2011-10-17 01:30:31 -04:00
parent 23afdb119e
commit 67bf0083db
4 changed files with 780 additions and 771 deletions

View File

@ -2048,263 +2048,6 @@ g_build_filename (const gchar *first_element,
return str;
}
#define KILOBYTE_FACTOR (G_GOFFSET_CONSTANT (1000))
#define MEGABYTE_FACTOR (KILOBYTE_FACTOR * KILOBYTE_FACTOR)
#define GIGABYTE_FACTOR (MEGABYTE_FACTOR * KILOBYTE_FACTOR)
#define TERABYTE_FACTOR (GIGABYTE_FACTOR * KILOBYTE_FACTOR)
#define PETABYTE_FACTOR (TERABYTE_FACTOR * KILOBYTE_FACTOR)
#define EXABYTE_FACTOR (PETABYTE_FACTOR * KILOBYTE_FACTOR)
#define KIBIBYTE_FACTOR (G_GOFFSET_CONSTANT (1024))
#define MEBIBYTE_FACTOR (KIBIBYTE_FACTOR * KIBIBYTE_FACTOR)
#define GIBIBYTE_FACTOR (MEBIBYTE_FACTOR * KIBIBYTE_FACTOR)
#define TEBIBYTE_FACTOR (GIBIBYTE_FACTOR * KIBIBYTE_FACTOR)
#define PEBIBYTE_FACTOR (TEBIBYTE_FACTOR * KIBIBYTE_FACTOR)
#define EXBIBYTE_FACTOR (PEBIBYTE_FACTOR * KIBIBYTE_FACTOR)
/**
* g_format_size:
* @size: a size in bytes
*
* Formats a size (for example the size of a file) into a human readable
* string. Sizes are rounded to the nearest size prefix (kB, MB, GB)
* and are displayed rounded to the nearest tenth. E.g. the file size
* 3292528 bytes will be converted into the string "3.2 MB".
*
* The prefix units base is 1000 (i.e. 1 kB is 1000 bytes).
*
* This string should be freed with g_free() when not needed any longer.
*
* See g_format_size_full() for more options about how the size might be
* formatted.
*
* Returns: a newly-allocated formatted string containing a human readable
* file size.
*
* Since: 2.30
**/
gchar *
g_format_size (guint64 size)
{
return g_format_size_full (size, G_FORMAT_SIZE_DEFAULT);
}
/**
* g_format_size_full:
* @size: a size in bytes
* @flags: #GFormatSizeFlags to modify the output
*
* Formats a size.
*
* This function is similar to g_format_size() but allows for flags that
* modify the output. See #GFormatSizeFlags.
*
* Returns: a newly-allocated formatted string containing a human
* readable file size.
*
* Since: 2.30
**/
/**
* GFormatSizeFlags:
* @G_FORMAT_SIZE_DEFAULT: behave the same as g_format_size()
* @G_FORMAT_SIZE_LONG_FORMAT: include the exact number of bytes as part
* of the returned string. For example,
* "45.6 kB (45,612 bytes)".
* @G_FORMAT_SIZE_IEC_UNITS: use IEC (base 1024) units with "KiB"-style
* suffixes. IEC units should only be used
* for reporting things with a strong "power
* of 2" basis, like RAM sizes or RAID stripe
* sizes. Network and storage sizes should
* be reported in the normal SI units.
*
* Flags to modify the format of the string returned by
* g_format_size_full().
**/
gchar *
g_format_size_full (guint64 size,
GFormatSizeFlags flags)
{
GString *string;
string = g_string_new (NULL);
if (flags & G_FORMAT_SIZE_IEC_UNITS)
{
if (size < KIBIBYTE_FACTOR)
{
g_string_printf (string,
g_dngettext(GETTEXT_PACKAGE, "%u byte", "%u bytes", (guint) size),
(guint) size);
flags &= ~G_FORMAT_SIZE_LONG_FORMAT;
}
else if (size < MEBIBYTE_FACTOR)
g_string_printf (string, _("%.1f KiB"), (gdouble) size / (gdouble) KIBIBYTE_FACTOR);
else if (size < GIBIBYTE_FACTOR)
g_string_printf (string, _("%.1f MiB"), (gdouble) size / (gdouble) MEBIBYTE_FACTOR);
else if (size < TEBIBYTE_FACTOR)
g_string_printf (string, _("%.1f GiB"), (gdouble) size / (gdouble) GIBIBYTE_FACTOR);
else if (size < PEBIBYTE_FACTOR)
g_string_printf (string, _("%.1f TiB"), (gdouble) size / (gdouble) TEBIBYTE_FACTOR);
else if (size < EXBIBYTE_FACTOR)
g_string_printf (string, _("%.1f PiB"), (gdouble) size / (gdouble) PEBIBYTE_FACTOR);
else
g_string_printf (string, _("%.1f EiB"), (gdouble) size / (gdouble) EXBIBYTE_FACTOR);
}
else
{
if (size < KILOBYTE_FACTOR)
{
g_string_printf (string,
g_dngettext(GETTEXT_PACKAGE, "%u byte", "%u bytes", (guint) size),
(guint) size);
flags &= ~G_FORMAT_SIZE_LONG_FORMAT;
}
else if (size < MEGABYTE_FACTOR)
g_string_printf (string, _("%.1f kB"), (gdouble) size / (gdouble) KILOBYTE_FACTOR);
else if (size < GIGABYTE_FACTOR)
g_string_printf (string, _("%.1f MB"), (gdouble) size / (gdouble) MEGABYTE_FACTOR);
else if (size < TERABYTE_FACTOR)
g_string_printf (string, _("%.1f GB"), (gdouble) size / (gdouble) GIGABYTE_FACTOR);
else if (size < PETABYTE_FACTOR)
g_string_printf (string, _("%.1f TB"), (gdouble) size / (gdouble) TERABYTE_FACTOR);
else if (size < EXABYTE_FACTOR)
g_string_printf (string, _("%.1f PB"), (gdouble) size / (gdouble) PETABYTE_FACTOR);
else
g_string_printf (string, _("%.1f EB"), (gdouble) size / (gdouble) EXABYTE_FACTOR);
}
if (flags & G_FORMAT_SIZE_LONG_FORMAT)
{
/* First problem: we need to use the number of bytes to decide on
* the plural form that is used for display, but the number of
* bytes potentially exceeds the size of a guint (which is what
* ngettext() takes).
*
* From a pragmatic standpoint, it seems that all known languages
* base plural forms on one or both of the following:
*
* - the lowest digits of the number
*
* - if the number if greater than some small value
*
* Here's how we fake it: Draw an arbitrary line at one thousand.
* If the number is below that, then fine. If it is above it,
* then we take the modulus of the number by one thousand (in
* order to keep the lowest digits) and add one thousand to that
* (in order to ensure that 1001 is not treated the same as 1).
*/
guint plural_form = size < 1000 ? size : size % 1000 + 1000;
/* Second problem: we need to translate the string "%u byte" and
* "%u bytes" for pluralisation, but the correct number format to
* use for a gsize is different depending on which architecture
* we're on.
*
* Solution: format the number separately and use "%s bytes" on
* all platforms.
*/
const gchar *translated_format;
gchar *formatted_number;
/* Translators: the %s in "%s bytes" will always be replaced by a number. */
translated_format = g_dngettext(GETTEXT_PACKAGE, "%s byte", "%s bytes", plural_form);
/* XXX: Windows doesn't support the "'" format modifier, so we
* must not use it there. Instead, just display the number
* without separation. Bug #655336 is open until a solution is
* found.
*/
#ifndef G_OS_WIN32
formatted_number = g_strdup_printf ("%'"G_GUINT64_FORMAT, size);
#else
formatted_number = g_strdup_printf ("%"G_GUINT64_FORMAT, size);
#endif
g_string_append (string, " (");
g_string_append_printf (string, translated_format, formatted_number);
g_free (formatted_number);
g_string_append (string, ")");
}
return g_string_free (string, FALSE);
}
/**
* g_format_size_for_display:
* @size: a size in bytes.
*
* Formats a size (for example the size of a file) into a human readable string.
* Sizes are rounded to the nearest size prefix (KB, MB, GB) and are displayed
* rounded to the nearest tenth. E.g. the file size 3292528 bytes will be
* converted into the string "3.1 MB".
*
* The prefix units base is 1024 (i.e. 1 KB is 1024 bytes).
*
* This string should be freed with g_free() when not needed any longer.
*
* Returns: a newly-allocated formatted string containing a human readable
* file size.
*
* Deprecated:2.30: This function is broken due to its use of SI
* suffixes to denote IEC units. Use g_format_size()
* instead.
* Since: 2.16
**/
char *
g_format_size_for_display (goffset size)
{
if (size < (goffset) KIBIBYTE_FACTOR)
return g_strdup_printf (g_dngettext(GETTEXT_PACKAGE, "%u byte", "%u bytes",(guint) size), (guint) size);
else
{
gdouble displayed_size;
if (size < (goffset) MEBIBYTE_FACTOR)
{
displayed_size = (gdouble) size / (gdouble) KIBIBYTE_FACTOR;
return g_strdup_printf (_("%.1f KB"), displayed_size);
}
else if (size < (goffset) GIBIBYTE_FACTOR)
{
displayed_size = (gdouble) size / (gdouble) MEBIBYTE_FACTOR;
return g_strdup_printf (_("%.1f MB"), displayed_size);
}
else if (size < (goffset) TEBIBYTE_FACTOR)
{
displayed_size = (gdouble) size / (gdouble) GIBIBYTE_FACTOR;
return g_strdup_printf (_("%.1f GB"), displayed_size);
}
else if (size < (goffset) PEBIBYTE_FACTOR)
{
displayed_size = (gdouble) size / (gdouble) TEBIBYTE_FACTOR;
return g_strdup_printf (_("%.1f TB"), displayed_size);
}
else if (size < (goffset) EXBIBYTE_FACTOR)
{
displayed_size = (gdouble) size / (gdouble) PEBIBYTE_FACTOR;
return g_strdup_printf (_("%.1f PB"), displayed_size);
}
else
{
displayed_size = (gdouble) size / (gdouble) EXBIBYTE_FACTOR;
return g_strdup_printf (_("%.1f EB"), displayed_size);
}
}
}
/**
* g_file_read_link:
* @filename: the symbolic link
@ -2369,7 +2112,445 @@ g_file_read_link (const gchar *filename,
#endif
}
/* NOTE : Keep this part last to ensure nothing in this file uses the
/**
* g_path_is_absolute:
* @file_name: a file name
*
* Returns %TRUE if the given @file_name is an absolute file name.
* Note that this is a somewhat vague concept on Windows.
*
* On POSIX systems, an absolute file name is well-defined. It always
* starts from the single root directory. For example "/usr/local".
*
* On Windows, the concepts of current drive and drive-specific
* current directory introduce vagueness. This function interprets as
* an absolute file name one that either begins with a directory
* separator such as "\Users\tml" or begins with the root on a drive,
* for example "C:\Windows". The first case also includes UNC paths
* such as "\\myserver\docs\foo". In all cases, either slashes or
* backslashes are accepted.
*
* Note that a file name relative to the current drive root does not
* truly specify a file uniquely over time and across processes, as
* the current drive is a per-process value and can be changed.
*
* File names relative the current directory on some specific drive,
* such as "D:foo/bar", are not interpreted as absolute by this
* function, but they obviously are not relative to the normal current
* directory as returned by getcwd() or g_get_current_dir()
* either. Such paths should be avoided, or need to be handled using
* Windows-specific code.
*
* Returns: %TRUE if @file_name is absolute
*/
gboolean
g_path_is_absolute (const gchar *file_name)
{
g_return_val_if_fail (file_name != NULL, FALSE);
if (G_IS_DIR_SEPARATOR (file_name[0]))
return TRUE;
#ifdef G_OS_WIN32
/* Recognize drive letter on native Windows */
if (g_ascii_isalpha (file_name[0]) &&
file_name[1] == ':' && G_IS_DIR_SEPARATOR (file_name[2]))
return TRUE;
#endif
return FALSE;
}
/**
* g_path_skip_root:
* @file_name: a file name
*
* Returns a pointer into @file_name after the root component,
* i.e. after the "/" in UNIX or "C:\" under Windows. If @file_name
* is not an absolute path it returns %NULL.
*
* Returns: a pointer into @file_name after the root component
*/
const gchar *
g_path_skip_root (const gchar *file_name)
{
g_return_val_if_fail (file_name != NULL, NULL);
#ifdef G_PLATFORM_WIN32
/* Skip \\server\share or //server/share */
if (G_IS_DIR_SEPARATOR (file_name[0]) &&
G_IS_DIR_SEPARATOR (file_name[1]) &&
file_name[2] &&
!G_IS_DIR_SEPARATOR (file_name[2]))
{
gchar *p;
p = strchr (file_name + 2, G_DIR_SEPARATOR);
#ifdef G_OS_WIN32
{
gchar *q;
q = strchr (file_name + 2, '/');
if (p == NULL || (q != NULL && q < p))
p = q;
}
#endif
if (p && p > file_name + 2 && p[1])
{
file_name = p + 1;
while (file_name[0] && !G_IS_DIR_SEPARATOR (file_name[0]))
file_name++;
/* Possibly skip a backslash after the share name */
if (G_IS_DIR_SEPARATOR (file_name[0]))
file_name++;
return (gchar *)file_name;
}
}
#endif
/* Skip initial slashes */
if (G_IS_DIR_SEPARATOR (file_name[0]))
{
while (G_IS_DIR_SEPARATOR (file_name[0]))
file_name++;
return (gchar *)file_name;
}
#ifdef G_OS_WIN32
/* Skip X:\ */
if (g_ascii_isalpha (file_name[0]) &&
file_name[1] == ':' &&
G_IS_DIR_SEPARATOR (file_name[2]))
return (gchar *)file_name + 3;
#endif
return NULL;
}
/**
* g_basename:
* @file_name: the name of the file
*
* Gets the name of the file without any leading directory
* components. It returns a pointer into the given file name
* string.
*
* Return value: the name of the file without any leading
* directory components
*
* Deprecated:2.2: Use g_path_get_basename() instead, but notice
* that g_path_get_basename() allocates new memory for the
* returned string, unlike this function which returns a pointer
* into the argument.
*/
const gchar *
g_basename (const gchar *file_name)
{
gchar *base;
g_return_val_if_fail (file_name != NULL, NULL);
base = strrchr (file_name, G_DIR_SEPARATOR);
#ifdef G_OS_WIN32
{
gchar *q;
q = strrchr (file_name, '/');
if (base == NULL || (q != NULL && q > base))
base = q;
}
#endif
if (base)
return base + 1;
#ifdef G_OS_WIN32
if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
return (gchar*) file_name + 2;
#endif
return (gchar*) file_name;
}
/**
* g_path_get_basename:
* @file_name: the name of the file
*
* Gets the last component of the filename.
*
* If @file_name ends with a directory separator it gets the component
* before the last slash. If @file_name consists only of directory
* separators (and on Windows, possibly a drive letter), a single
* separator is returned. If @file_name is empty, it gets ".".
*
* Return value: a newly allocated string containing the last
* component of the filename
*/
gchar *
g_path_get_basename (const gchar *file_name)
{
gssize base;
gssize last_nonslash;
gsize len;
gchar *retval;
g_return_val_if_fail (file_name != NULL, NULL);
if (file_name[0] == '\0')
return g_strdup (".");
last_nonslash = strlen (file_name) - 1;
while (last_nonslash >= 0 && G_IS_DIR_SEPARATOR (file_name [last_nonslash]))
last_nonslash--;
if (last_nonslash == -1)
/* string only containing slashes */
return g_strdup (G_DIR_SEPARATOR_S);
#ifdef G_OS_WIN32
if (last_nonslash == 1 &&
g_ascii_isalpha (file_name[0]) &&
file_name[1] == ':')
/* string only containing slashes and a drive */
return g_strdup (G_DIR_SEPARATOR_S);
#endif
base = last_nonslash;
while (base >=0 && !G_IS_DIR_SEPARATOR (file_name [base]))
base--;
#ifdef G_OS_WIN32
if (base == -1 &&
g_ascii_isalpha (file_name[0]) &&
file_name[1] == ':')
base = 1;
#endif /* G_OS_WIN32 */
len = last_nonslash - base;
retval = g_malloc (len + 1);
memcpy (retval, file_name + base + 1, len);
retval [len] = '\0';
return retval;
}
/**
* g_dirname:
* @file_name: the name of the file
*
* Gets the directory components of a file name.
*
* If the file name has no directory components "." is returned.
* The returned string should be freed when no longer needed.
*
* Returns: the directory components of the file
*
* Deprecated: use g_path_get_dirname() instead
*/
/**
* g_path_get_dirname:
* @file_name: the name of the file
*
* Gets the directory components of a file name.
*
* If the file name has no directory components "." is returned.
* The returned string should be freed when no longer needed.
*
* Returns: the directory components of the file
*/
gchar *
g_path_get_dirname (const gchar *file_name)
{
gchar *base;
gsize len;
g_return_val_if_fail (file_name != NULL, NULL);
base = strrchr (file_name, G_DIR_SEPARATOR);
#ifdef G_OS_WIN32
{
gchar *q;
q = strrchr (file_name, '/');
if (base == NULL || (q != NULL && q > base))
base = q;
}
#endif
if (!base)
{
#ifdef G_OS_WIN32
if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
{
gchar drive_colon_dot[4];
drive_colon_dot[0] = file_name[0];
drive_colon_dot[1] = ':';
drive_colon_dot[2] = '.';
drive_colon_dot[3] = '\0';
return g_strdup (drive_colon_dot);
}
#endif
return g_strdup (".");
}
while (base > file_name && G_IS_DIR_SEPARATOR (*base))
base--;
#ifdef G_OS_WIN32
/* base points to the char before the last slash.
*
* In case file_name is the root of a drive (X:\) or a child of the
* root of a drive (X:\foo), include the slash.
*
* In case file_name is the root share of an UNC path
* (\\server\share), add a slash, returning \\server\share\ .
*
* In case file_name is a direct child of a share in an UNC path
* (\\server\share\foo), include the slash after the share name,
* returning \\server\share\ .
*/
if (base == file_name + 1 &&
g_ascii_isalpha (file_name[0]) &&
file_name[1] == ':')
base++;
else if (G_IS_DIR_SEPARATOR (file_name[0]) &&
G_IS_DIR_SEPARATOR (file_name[1]) &&
file_name[2] &&
!G_IS_DIR_SEPARATOR (file_name[2]) &&
base >= file_name + 2)
{
const gchar *p = file_name + 2;
while (*p && !G_IS_DIR_SEPARATOR (*p))
p++;
if (p == base + 1)
{
len = (guint) strlen (file_name) + 1;
base = g_new (gchar, len + 1);
strcpy (base, file_name);
base[len-1] = G_DIR_SEPARATOR;
base[len] = 0;
return base;
}
if (G_IS_DIR_SEPARATOR (*p))
{
p++;
while (*p && !G_IS_DIR_SEPARATOR (*p))
p++;
if (p == base + 1)
base++;
}
}
#endif
len = (guint) 1 + base - file_name;
base = g_new (gchar, len + 1);
g_memmove (base, file_name, len);
base[len] = 0;
return base;
}
#if defined(MAXPATHLEN)
#define G_PATH_LENGTH MAXPATHLEN
#elif defined(PATH_MAX)
#define G_PATH_LENGTH PATH_MAX
#elif defined(_PC_PATH_MAX)
#define G_PATH_LENGTH sysconf(_PC_PATH_MAX)
#else
#define G_PATH_LENGTH 2048
#endif
/**
* g_get_current_dir:
*
* Gets the current directory.
*
* The returned string should be freed when no longer needed.
* The encoding of the returned string is system defined.
* On Windows, it is always UTF-8.
*
* Returns: the current directory
*/
gchar *
g_get_current_dir (void)
{
#ifdef G_OS_WIN32
gchar *dir = NULL;
wchar_t dummy[2], *wdir;
int len;
len = GetCurrentDirectoryW (2, dummy);
wdir = g_new (wchar_t, len);
if (GetCurrentDirectoryW (len, wdir) == len - 1)
dir = g_utf16_to_utf8 (wdir, -1, NULL, NULL, NULL);
g_free (wdir);
if (dir == NULL)
dir = g_strdup ("\\");
return dir;
#else
gchar *buffer = NULL;
gchar *dir = NULL;
static gulong max_len = 0;
if (max_len == 0)
max_len = (G_PATH_LENGTH == -1) ? 2048 : G_PATH_LENGTH;
/* We don't use getcwd(3) on SUNOS, because, it does a popen("pwd")
* and, if that wasn't bad enough, hangs in doing so.
*/
#if (defined (sun) && !defined (__SVR4)) || !defined(HAVE_GETCWD)
buffer = g_new (gchar, max_len + 1);
*buffer = 0;
dir = getwd (buffer);
#else
while (max_len < G_MAXULONG / 2)
{
g_free (buffer);
buffer = g_new (gchar, max_len + 1);
*buffer = 0;
dir = getcwd (buffer, max_len);
if (dir || errno != ERANGE)
break;
max_len *= 2;
}
#endif /* !sun || !HAVE_GETCWD */
if (!dir || !*buffer)
{
/* hm, should we g_error() out here?
* this can happen if e.g. "./" has mode \0000
*/
buffer[0] = G_DIR_SEPARATOR;
buffer[1] = 0;
}
dir = g_strdup (buffer);
g_free (buffer);
return dir;
#endif /* !G_OS_WIN32 */
}
/* NOTE : Keep this part last to ensure nothing in this file uses thn
* below binary compatibility versions.
*/
#if defined (G_OS_WIN32) && !defined (_WIN64)
@ -2458,4 +2639,16 @@ g_file_open_tmp (const gchar *tmpl,
return retval;
}
#undef g_get_current_dir
gchar *
g_get_current_dir (void)
{
gchar *utf8_dir = g_get_current_dir_utf8 ();
gchar *dir = g_locale_from_utf8 (utf8_dir, -1, NULL, NULL, NULL);
g_free (utf8_dir);
return dir;
}
#endif

View File

@ -60,7 +60,7 @@ typedef enum
G_FILE_ERROR_FAILED
} GFileError;
/* For backward-compat reasons, these are synced to an old
/* For backward-compat reasons, these are synced to an old
* anonymous enum in libgnome. But don't use that enum
* in new code.
*/
@ -90,14 +90,14 @@ gboolean g_file_test (const gchar *filename,
GFileTest test);
gboolean g_file_get_contents (const gchar *filename,
gchar **contents,
gsize *length,
gsize *length,
GError **error);
gboolean g_file_set_contents (const gchar *filename,
const gchar *contents,
gssize length,
GError **error);
const gchar *contents,
gssize length,
GError **error);
gchar *g_file_read_link (const gchar *filename,
GError **error);
GError **error);
/* Wrapper / workalike for mkdtemp() */
gchar *g_mkdtemp (gchar *tmpl);
@ -105,46 +105,73 @@ gchar *g_mkdtemp_full (gchar *tmpl,
gint mode);
/* Wrapper / workalike for mkstemp() */
gint g_mkstemp (gchar *tmpl);
gint g_mkstemp_full (gchar *tmpl,
gint flags,
gint mode);
gint g_mkstemp (gchar *tmpl);
gint g_mkstemp_full (gchar *tmpl,
gint flags,
gint mode);
/* Wrappers for g_mkstemp and g_mkdtemp() */
gint g_file_open_tmp (const gchar *tmpl,
gchar **name_used,
GError **error);
gchar *g_dir_make_tmp (const gchar *tmpl,
GError **error);
gint g_file_open_tmp (const gchar *tmpl,
gchar **name_used,
GError **error);
gchar *g_dir_make_tmp (const gchar *tmpl,
GError **error);
typedef enum
{
G_FORMAT_SIZE_DEFAULT = 0,
G_FORMAT_SIZE_LONG_FORMAT = 1 << 0,
G_FORMAT_SIZE_IEC_UNITS = 1 << 1
} GFormatSizeFlags;
gchar *g_build_path (const gchar *separator,
const gchar *first_element,
...) G_GNUC_MALLOC G_GNUC_NULL_TERMINATED;
gchar *g_build_pathv (const gchar *separator,
gchar **args) G_GNUC_MALLOC;
gchar * g_format_size_full (guint64 size,
GFormatSizeFlags flags);
gchar * g_format_size (guint64 size);
gchar *g_build_filename (const gchar *first_element,
...) G_GNUC_MALLOC G_GNUC_NULL_TERMINATED;
gchar *g_build_filenamev (gchar **args) G_GNUC_MALLOC;
gint g_mkdir_with_parents (const gchar *pathname,
gint mode);
#ifdef G_OS_WIN32
/* On Win32, the canonical directory separator is the backslash, and
* the search path separator is the semicolon. Note that also the
* (forward) slash works as directory separator.
*/
#define G_DIR_SEPARATOR '\\'
#define G_DIR_SEPARATOR_S "\\"
#define G_IS_DIR_SEPARATOR(c) ((c) == G_DIR_SEPARATOR || (c) == '/')
#define G_SEARCHPATH_SEPARATOR ';'
#define G_SEARCHPATH_SEPARATOR_S ";"
#else /* !G_OS_WIN32 */
#define G_DIR_SEPARATOR '/'
#define G_DIR_SEPARATOR_S "/"
#define G_IS_DIR_SEPARATOR(c) ((c) == G_DIR_SEPARATOR)
#define G_SEARCHPATH_SEPARATOR ':'
#define G_SEARCHPATH_SEPARATOR_S ":"
#endif /* !G_OS_WIN32 */
gboolean g_path_is_absolute (const gchar *file_name);
const gchar *g_path_skip_root (const gchar *file_name);
#ifndef G_DISABLE_DEPRECATED
GLIB_DEPRECATED_FOR(g_format_size)
char *g_format_size_for_display (goffset size);
GLIB_DEPRECATED_FOR(g_path_get_basename)
const gchar *g_basename (const gchar *file_name);
#define g_dirname g_path_get_dirname
#endif /* G_DISABLE_DEPRECATED */
#ifndef __GTK_DOC_IGNORE__
#ifdef G_OS_WIN32
#define g_get_current_dir g_get_current_dir_utf8
#endif
#endif
gchar *g_build_path (const gchar *separator,
const gchar *first_element,
...) G_GNUC_MALLOC G_GNUC_NULL_TERMINATED;
gchar *g_build_pathv (const gchar *separator,
gchar **args) G_GNUC_MALLOC;
gchar *g_build_filename (const gchar *first_element,
...) G_GNUC_MALLOC G_GNUC_NULL_TERMINATED;
gchar *g_build_filenamev (gchar **args) G_GNUC_MALLOC;
int g_mkdir_with_parents (const gchar *pathname,
int mode);
gchar *g_get_current_dir (void);
gchar *g_path_get_basename (const gchar *file_name) G_GNUC_MALLOC;
gchar *g_path_get_dirname (const gchar *file_name) G_GNUC_MALLOC;
G_END_DECLS

View File

@ -88,16 +88,6 @@
* These are portable utility functions.
*/
#ifdef MAXPATHLEN
#define G_PATH_LENGTH MAXPATHLEN
#elif defined (PATH_MAX)
#define G_PATH_LENGTH PATH_MAX
#elif defined (_PC_PATH_MAX)
#define G_PATH_LENGTH sysconf(_PC_PATH_MAX)
#else
#define G_PATH_LENGTH 2048
#endif
#ifdef G_PLATFORM_WIN32
# include <windows.h>
# ifndef GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
@ -548,222 +538,6 @@ g_find_program_in_path (const gchar *program)
return NULL;
}
/**
* g_basename:
* @file_name: the name of the file.
*
* Gets the name of the file without any leading directory components.
* It returns a pointer into the given file name string.
*
* Return value: the name of the file without any leading directory components.
*
* Deprecated:2.2: Use g_path_get_basename() instead, but notice that
* g_path_get_basename() allocates new memory for the returned string, unlike
* this function which returns a pointer into the argument.
**/
const gchar *
g_basename (const gchar *file_name)
{
register gchar *base;
g_return_val_if_fail (file_name != NULL, NULL);
base = strrchr (file_name, G_DIR_SEPARATOR);
#ifdef G_OS_WIN32
{
gchar *q = strrchr (file_name, '/');
if (base == NULL || (q != NULL && q > base))
base = q;
}
#endif
if (base)
return base + 1;
#ifdef G_OS_WIN32
if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
return (gchar*) file_name + 2;
#endif /* G_OS_WIN32 */
return (gchar*) file_name;
}
/**
* g_path_get_basename:
* @file_name: the name of the file.
*
* Gets the last component of the filename. If @file_name ends with a
* directory separator it gets the component before the last slash. If
* @file_name consists only of directory separators (and on Windows,
* possibly a drive letter), a single separator is returned. If
* @file_name is empty, it gets ".".
*
* Return value: a newly allocated string containing the last component of
* the filename.
*/
gchar*
g_path_get_basename (const gchar *file_name)
{
register gssize base;
register gssize last_nonslash;
gsize len;
gchar *retval;
g_return_val_if_fail (file_name != NULL, NULL);
if (file_name[0] == '\0')
/* empty string */
return g_strdup (".");
last_nonslash = strlen (file_name) - 1;
while (last_nonslash >= 0 && G_IS_DIR_SEPARATOR (file_name [last_nonslash]))
last_nonslash--;
if (last_nonslash == -1)
/* string only containing slashes */
return g_strdup (G_DIR_SEPARATOR_S);
#ifdef G_OS_WIN32
if (last_nonslash == 1 && g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
/* string only containing slashes and a drive */
return g_strdup (G_DIR_SEPARATOR_S);
#endif /* G_OS_WIN32 */
base = last_nonslash;
while (base >=0 && !G_IS_DIR_SEPARATOR (file_name [base]))
base--;
#ifdef G_OS_WIN32
if (base == -1 && g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
base = 1;
#endif /* G_OS_WIN32 */
len = last_nonslash - base;
retval = g_malloc (len + 1);
memcpy (retval, file_name + base + 1, len);
retval [len] = '\0';
return retval;
}
/**
* g_path_is_absolute:
* @file_name: a file name.
*
* Returns %TRUE if the given @file_name is an absolute file name.
* Note that this is a somewhat vague concept on Windows.
*
* On POSIX systems, an absolute file name is well-defined. It always
* starts from the single root directory. For example "/usr/local".
*
* On Windows, the concepts of current drive and drive-specific
* current directory introduce vagueness. This function interprets as
* an absolute file name one that either begins with a directory
* separator such as "\Users\tml" or begins with the root on a drive,
* for example "C:\Windows". The first case also includes UNC paths
* such as "\\myserver\docs\foo". In all cases, either slashes or
* backslashes are accepted.
*
* Note that a file name relative to the current drive root does not
* truly specify a file uniquely over time and across processes, as
* the current drive is a per-process value and can be changed.
*
* File names relative the current directory on some specific drive,
* such as "D:foo/bar", are not interpreted as absolute by this
* function, but they obviously are not relative to the normal current
* directory as returned by getcwd() or g_get_current_dir()
* either. Such paths should be avoided, or need to be handled using
* Windows-specific code.
*
* Returns: %TRUE if @file_name is absolute.
*/
gboolean
g_path_is_absolute (const gchar *file_name)
{
g_return_val_if_fail (file_name != NULL, FALSE);
if (G_IS_DIR_SEPARATOR (file_name[0]))
return TRUE;
#ifdef G_OS_WIN32
/* Recognize drive letter on native Windows */
if (g_ascii_isalpha (file_name[0]) &&
file_name[1] == ':' && G_IS_DIR_SEPARATOR (file_name[2]))
return TRUE;
#endif /* G_OS_WIN32 */
return FALSE;
}
/**
* g_path_skip_root:
* @file_name: a file name.
*
* Returns a pointer into @file_name after the root component, i.e. after
* the "/" in UNIX or "C:\" under Windows. If @file_name is not an absolute
* path it returns %NULL.
*
* Returns: a pointer into @file_name after the root component.
*/
const gchar *
g_path_skip_root (const gchar *file_name)
{
g_return_val_if_fail (file_name != NULL, NULL);
#ifdef G_PLATFORM_WIN32
/* Skip \\server\share or //server/share */
if (G_IS_DIR_SEPARATOR (file_name[0]) &&
G_IS_DIR_SEPARATOR (file_name[1]) &&
file_name[2] &&
!G_IS_DIR_SEPARATOR (file_name[2]))
{
gchar *p;
p = strchr (file_name + 2, G_DIR_SEPARATOR);
#ifdef G_OS_WIN32
{
gchar *q = strchr (file_name + 2, '/');
if (p == NULL || (q != NULL && q < p))
p = q;
}
#endif
if (p &&
p > file_name + 2 &&
p[1])
{
file_name = p + 1;
while (file_name[0] && !G_IS_DIR_SEPARATOR (file_name[0]))
file_name++;
/* Possibly skip a backslash after the share name */
if (G_IS_DIR_SEPARATOR (file_name[0]))
file_name++;
return (gchar *)file_name;
}
}
#endif
/* Skip initial slashes */
if (G_IS_DIR_SEPARATOR (file_name[0]))
{
while (G_IS_DIR_SEPARATOR (file_name[0]))
file_name++;
return (gchar *)file_name;
}
#ifdef G_OS_WIN32
/* Skip X:\ */
if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':' && G_IS_DIR_SEPARATOR (file_name[2]))
return (gchar *)file_name + 3;
#endif
return NULL;
}
/**
* g_bit_nth_lsf:
* @mask: a #gulong containing flags
@ -801,197 +575,6 @@ g_path_skip_root (const gchar *file_name)
* Returns: the number of bits used to hold @number
*/
/**
* g_dirname:
* @file_name: the name of the file
*
* Gets the directory components of a file name.
* If the file name has no directory components "." is returned.
* The returned string should be freed when no longer needed.
*
* Returns: the directory components of the file
*
* Deprecated: use g_path_get_dirname() instead
*/
/**
* g_path_get_dirname:
* @file_name: the name of the file.
*
* Gets the directory components of a file name. If the file name has no
* directory components "." is returned. The returned string should be
* freed when no longer needed.
*
* Returns: the directory components of the file.
*/
gchar*
g_path_get_dirname (const gchar *file_name)
{
register gchar *base;
register gsize len;
g_return_val_if_fail (file_name != NULL, NULL);
base = strrchr (file_name, G_DIR_SEPARATOR);
#ifdef G_OS_WIN32
{
gchar *q = strrchr (file_name, '/');
if (base == NULL || (q != NULL && q > base))
base = q;
}
#endif
if (!base)
{
#ifdef G_OS_WIN32
if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
{
gchar drive_colon_dot[4];
drive_colon_dot[0] = file_name[0];
drive_colon_dot[1] = ':';
drive_colon_dot[2] = '.';
drive_colon_dot[3] = '\0';
return g_strdup (drive_colon_dot);
}
#endif
return g_strdup (".");
}
while (base > file_name && G_IS_DIR_SEPARATOR (*base))
base--;
#ifdef G_OS_WIN32
/* base points to the char before the last slash.
*
* In case file_name is the root of a drive (X:\) or a child of the
* root of a drive (X:\foo), include the slash.
*
* In case file_name is the root share of an UNC path
* (\\server\share), add a slash, returning \\server\share\ .
*
* In case file_name is a direct child of a share in an UNC path
* (\\server\share\foo), include the slash after the share name,
* returning \\server\share\ .
*/
if (base == file_name + 1 && g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
base++;
else if (G_IS_DIR_SEPARATOR (file_name[0]) &&
G_IS_DIR_SEPARATOR (file_name[1]) &&
file_name[2] &&
!G_IS_DIR_SEPARATOR (file_name[2]) &&
base >= file_name + 2)
{
const gchar *p = file_name + 2;
while (*p && !G_IS_DIR_SEPARATOR (*p))
p++;
if (p == base + 1)
{
len = (guint) strlen (file_name) + 1;
base = g_new (gchar, len + 1);
strcpy (base, file_name);
base[len-1] = G_DIR_SEPARATOR;
base[len] = 0;
return base;
}
if (G_IS_DIR_SEPARATOR (*p))
{
p++;
while (*p && !G_IS_DIR_SEPARATOR (*p))
p++;
if (p == base + 1)
base++;
}
}
#endif
len = (guint) 1 + base - file_name;
base = g_new (gchar, len + 1);
g_memmove (base, file_name, len);
base[len] = 0;
return base;
}
/**
* g_get_current_dir:
*
* Gets the current directory.
* The returned string should be freed when no longer needed. The encoding
* of the returned string is system defined. On Windows, it is always UTF-8.
*
* Returns: the current directory.
*/
gchar*
g_get_current_dir (void)
{
#ifdef G_OS_WIN32
gchar *dir = NULL;
wchar_t dummy[2], *wdir;
int len;
len = GetCurrentDirectoryW (2, dummy);
wdir = g_new (wchar_t, len);
if (GetCurrentDirectoryW (len, wdir) == len - 1)
dir = g_utf16_to_utf8 (wdir, -1, NULL, NULL, NULL);
g_free (wdir);
if (dir == NULL)
dir = g_strdup ("\\");
return dir;
#else
gchar *buffer = NULL;
gchar *dir = NULL;
static gulong max_len = 0;
if (max_len == 0)
max_len = (G_PATH_LENGTH == -1) ? 2048 : G_PATH_LENGTH;
/* We don't use getcwd(3) on SUNOS, because, it does a popen("pwd")
* and, if that wasn't bad enough, hangs in doing so.
*/
#if (defined (sun) && !defined (__SVR4)) || !defined(HAVE_GETCWD)
buffer = g_new (gchar, max_len + 1);
*buffer = 0;
dir = getwd (buffer);
#else /* !sun || !HAVE_GETCWD */
while (max_len < G_MAXULONG / 2)
{
g_free (buffer);
buffer = g_new (gchar, max_len + 1);
*buffer = 0;
dir = getcwd (buffer, max_len);
if (dir || errno != ERANGE)
break;
max_len *= 2;
}
#endif /* !sun || !HAVE_GETCWD */
if (!dir || !*buffer)
{
/* hm, should we g_error() out here?
* this can happen if e.g. "./" has mode \0000
*/
buffer[0] = G_DIR_SEPARATOR;
buffer[1] = 0;
}
dir = g_strdup (buffer);
g_free (buffer);
return dir;
#endif /* !Win32 */
}
G_LOCK_DEFINE_STATIC (g_utils_global);
static gchar *g_tmp_dir = NULL;
@ -2499,6 +2082,257 @@ g_nullify_pointer (gpointer *nullify_location)
*nullify_location = NULL;
}
#define KILOBYTE_FACTOR (G_GOFFSET_CONSTANT (1000))
#define MEGABYTE_FACTOR (KILOBYTE_FACTOR * KILOBYTE_FACTOR)
#define GIGABYTE_FACTOR (MEGABYTE_FACTOR * KILOBYTE_FACTOR)
#define TERABYTE_FACTOR (GIGABYTE_FACTOR * KILOBYTE_FACTOR)
#define PETABYTE_FACTOR (TERABYTE_FACTOR * KILOBYTE_FACTOR)
#define EXABYTE_FACTOR (PETABYTE_FACTOR * KILOBYTE_FACTOR)
#define KIBIBYTE_FACTOR (G_GOFFSET_CONSTANT (1024))
#define MEBIBYTE_FACTOR (KIBIBYTE_FACTOR * KIBIBYTE_FACTOR)
#define GIBIBYTE_FACTOR (MEBIBYTE_FACTOR * KIBIBYTE_FACTOR)
#define TEBIBYTE_FACTOR (GIBIBYTE_FACTOR * KIBIBYTE_FACTOR)
#define PEBIBYTE_FACTOR (TEBIBYTE_FACTOR * KIBIBYTE_FACTOR)
#define EXBIBYTE_FACTOR (PEBIBYTE_FACTOR * KIBIBYTE_FACTOR)
/**
* g_format_size:
* @size: a size in bytes
*
* Formats a size (for example the size of a file) into a human readable
* string. Sizes are rounded to the nearest size prefix (kB, MB, GB)
* and are displayed rounded to the nearest tenth. E.g. the file size
* 3292528 bytes will be converted into the string "3.2 MB".
*
* The prefix units base is 1000 (i.e. 1 kB is 1000 bytes).
*
* This string should be freed with g_free() when not needed any longer.
*
* See g_format_size_full() for more options about how the size might be
* formatted.
*
* Returns: a newly-allocated formatted string containing a human readable
* file size
*
* Since: 2.30
*/
gchar *
g_format_size (guint64 size)
{
return g_format_size_full (size, G_FORMAT_SIZE_DEFAULT);
}
/**
* GFormatSizeFlags:
* @G_FORMAT_SIZE_DEFAULT: behave the same as g_format_size()
* @G_FORMAT_SIZE_LONG_FORMAT: include the exact number of bytes as part
* of the returned string. For example, "45.6 kB (45,612 bytes)".
* @G_FORMAT_SIZE_IEC_UNITS: use IEC (base 1024) units with "KiB"-style
* suffixes. IEC units should only be used for reporting things with
* a strong "power of 2" basis, like RAM sizes or RAID stripe sizes.
* Network and storage sizes should be reported in the normal SI units.
*
* Flags to modify the format of the string returned by g_format_size_full().
*/
/**
* g_format_size_full:
* @size: a size in bytes
* @flags: #GFormatSizeFlags to modify the output
*
* Formats a size.
*
* This function is similar to g_format_size() but allows for flags
* that modify the output. See #GFormatSizeFlags.
*
* Returns: a newly-allocated formatted string containing a human
* readable file size
*
* Since: 2.30
*/
gchar *
g_format_size_full (guint64 size,
GFormatSizeFlags flags)
{
GString *string;
string = g_string_new (NULL);
if (flags & G_FORMAT_SIZE_IEC_UNITS)
{
if (size < KIBIBYTE_FACTOR)
{
g_string_printf (string,
g_dngettext(GETTEXT_PACKAGE, "%u byte", "%u bytes", (guint) size),
(guint) size);
flags &= ~G_FORMAT_SIZE_LONG_FORMAT;
}
else if (size < MEBIBYTE_FACTOR)
g_string_printf (string, _("%.1f KiB"), (gdouble) size / (gdouble) KIBIBYTE_FACTOR);
else if (size < GIBIBYTE_FACTOR)
g_string_printf (string, _("%.1f MiB"), (gdouble) size / (gdouble) MEBIBYTE_FACTOR);
else if (size < TEBIBYTE_FACTOR)
g_string_printf (string, _("%.1f GiB"), (gdouble) size / (gdouble) GIBIBYTE_FACTOR);
else if (size < PEBIBYTE_FACTOR)
g_string_printf (string, _("%.1f TiB"), (gdouble) size / (gdouble) TEBIBYTE_FACTOR);
else if (size < EXBIBYTE_FACTOR)
g_string_printf (string, _("%.1f PiB"), (gdouble) size / (gdouble) PEBIBYTE_FACTOR);
else
g_string_printf (string, _("%.1f EiB"), (gdouble) size / (gdouble) EXBIBYTE_FACTOR);
}
else
{
if (size < KILOBYTE_FACTOR)
{
g_string_printf (string,
g_dngettext(GETTEXT_PACKAGE, "%u byte", "%u bytes", (guint) size),
(guint) size);
flags &= ~G_FORMAT_SIZE_LONG_FORMAT;
}
else if (size < MEGABYTE_FACTOR)
g_string_printf (string, _("%.1f kB"), (gdouble) size / (gdouble) KILOBYTE_FACTOR);
else if (size < GIGABYTE_FACTOR)
g_string_printf (string, _("%.1f MB"), (gdouble) size / (gdouble) MEGABYTE_FACTOR);
else if (size < TERABYTE_FACTOR)
g_string_printf (string, _("%.1f GB"), (gdouble) size / (gdouble) GIGABYTE_FACTOR);
else if (size < PETABYTE_FACTOR)
g_string_printf (string, _("%.1f TB"), (gdouble) size / (gdouble) TERABYTE_FACTOR);
else if (size < EXABYTE_FACTOR)
g_string_printf (string, _("%.1f PB"), (gdouble) size / (gdouble) PETABYTE_FACTOR);
else
g_string_printf (string, _("%.1f EB"), (gdouble) size / (gdouble) EXABYTE_FACTOR);
}
if (flags & G_FORMAT_SIZE_LONG_FORMAT)
{
/* First problem: we need to use the number of bytes to decide on
* the plural form that is used for display, but the number of
* bytes potentially exceeds the size of a guint (which is what
* ngettext() takes).
*
* From a pragmatic standpoint, it seems that all known languages
* base plural forms on one or both of the following:
*
* - the lowest digits of the number
*
* - if the number if greater than some small value
*
* Here's how we fake it: Draw an arbitrary line at one thousand.
* If the number is below that, then fine. If it is above it,
* then we take the modulus of the number by one thousand (in
* order to keep the lowest digits) and add one thousand to that
* (in order to ensure that 1001 is not treated the same as 1).
*/
guint plural_form = size < 1000 ? size : size % 1000 + 1000;
/* Second problem: we need to translate the string "%u byte" and
* "%u bytes" for pluralisation, but the correct number format to
* use for a gsize is different depending on which architecture
* we're on.
*
* Solution: format the number separately and use "%s bytes" on
* all platforms.
*/
const gchar *translated_format;
gchar *formatted_number;
/* Translators: the %s in "%s bytes" will always be replaced by a number. */
translated_format = g_dngettext(GETTEXT_PACKAGE, "%s byte", "%s bytes", plural_form);
/* XXX: Windows doesn't support the "'" format modifier, so we
* must not use it there. Instead, just display the number
* without separation. Bug #655336 is open until a solution is
* found.
*/
#ifndef G_OS_WIN32
formatted_number = g_strdup_printf ("%'"G_GUINT64_FORMAT, size);
#else
formatted_number = g_strdup_printf ("%"G_GUINT64_FORMAT, size);
#endif
g_string_append (string, " (");
g_string_append_printf (string, translated_format, formatted_number);
g_free (formatted_number);
g_string_append (string, ")");
}
return g_string_free (string, FALSE);
}
/**
* g_format_size_for_display:
* @size: a size in bytes
*
* Formats a size (for example the size of a file) into a human
* readable string. Sizes are rounded to the nearest size prefix
* (KB, MB, GB) and are displayed rounded to the nearest tenth.
* E.g. the file size 3292528 bytes will be converted into the
* string "3.1 MB".
*
* The prefix units base is 1024 (i.e. 1 KB is 1024 bytes).
*
* This string should be freed with g_free() when not needed any longer.
*
* Returns: a newly-allocated formatted string containing a human
* readable file size
*
* Since: 2.16
*
* Deprecated:2.30: This function is broken due to its use of SI
* suffixes to denote IEC units. Use g_format_size() instead.
*/
gchar *
g_format_size_for_display (goffset size)
{
if (size < (goffset) KIBIBYTE_FACTOR)
return g_strdup_printf (g_dngettext(GETTEXT_PACKAGE, "%u byte", "%u bytes",(guint) size), (guint) size);
else
{
gdouble displayed_size;
if (size < (goffset) MEBIBYTE_FACTOR)
{
displayed_size = (gdouble) size / (gdouble) KIBIBYTE_FACTOR;
return g_strdup_printf (_("%.1f KB"), displayed_size);
}
else if (size < (goffset) GIBIBYTE_FACTOR)
{
displayed_size = (gdouble) size / (gdouble) MEBIBYTE_FACTOR;
return g_strdup_printf (_("%.1f MB"), displayed_size);
}
else if (size < (goffset) TEBIBYTE_FACTOR)
{
displayed_size = (gdouble) size / (gdouble) GIBIBYTE_FACTOR;
return g_strdup_printf (_("%.1f GB"), displayed_size);
}
else if (size < (goffset) PEBIBYTE_FACTOR)
{
displayed_size = (gdouble) size / (gdouble) TEBIBYTE_FACTOR;
return g_strdup_printf (_("%.1f TB"), displayed_size);
}
else if (size < (goffset) EXBIBYTE_FACTOR)
{
displayed_size = (gdouble) size / (gdouble) PEBIBYTE_FACTOR;
return g_strdup_printf (_("%.1f PB"), displayed_size);
}
else
{
displayed_size = (gdouble) size / (gdouble) EXBIBYTE_FACTOR;
return g_strdup_printf (_("%.1f EB"), displayed_size);
}
}
}
#ifdef G_OS_WIN32
/**
@ -2633,17 +2467,6 @@ g_find_program_in_path (const gchar *program)
return retval;
}
#undef g_get_current_dir
gchar*
g_get_current_dir (void)
{
gchar *utf8_dir = g_get_current_dir_utf8 ();
gchar *dir = g_locale_from_utf8 (utf8_dir, -1, NULL, NULL, NULL);
g_free (utf8_dir);
return dir;
}
#undef g_get_user_name
const gchar *

View File

@ -36,30 +36,6 @@
G_BEGIN_DECLS
#ifdef G_OS_WIN32
/* On Win32, the canonical directory separator is the backslash, and
* the search path separator is the semicolon. Note that also the
* (forward) slash works as directory separator.
*/
#define G_DIR_SEPARATOR '\\'
#define G_DIR_SEPARATOR_S "\\"
#define G_IS_DIR_SEPARATOR(c) ((c) == G_DIR_SEPARATOR || (c) == '/')
#define G_SEARCHPATH_SEPARATOR ';'
#define G_SEARCHPATH_SEPARATOR_S ";"
#else /* !G_OS_WIN32 */
/* Unix */
#define G_DIR_SEPARATOR '/'
#define G_DIR_SEPARATOR_S "/"
#define G_IS_DIR_SEPARATOR(c) ((c) == G_DIR_SEPARATOR)
#define G_SEARCHPATH_SEPARATOR ':'
#define G_SEARCHPATH_SEPARATOR_S ":"
#endif /* !G_OS_WIN32 */
/* Define G_VA_COPY() to do the right thing for copying va_list variables.
* glibconfig.h may have already defined G_VA_COPY as va_copy or __va_copy.
*/
@ -222,33 +198,23 @@ gint g_vsnprintf (gchar *string,
gchar const *format,
va_list args);
/* Check if a file name is an absolute path */
gboolean g_path_is_absolute (const gchar *file_name);
void g_nullify_pointer (gpointer *nullify_location);
/* In case of absolute paths, skip the root part */
const gchar * g_path_skip_root (const gchar *file_name);
typedef enum
{
G_FORMAT_SIZE_DEFAULT = 0,
G_FORMAT_SIZE_LONG_FORMAT = 1 << 0,
G_FORMAT_SIZE_IEC_UNITS = 1 << 1
} GFormatSizeFlags;
gchar *g_format_size_full (guint64 size,
GFormatSizeFlags flags);
gchar *g_format_size (guint64 size);
#ifndef G_DISABLE_DEPRECATED
GLIB_DEPRECATED_FOR(g_path_get_basename)
const gchar * g_basename (const gchar *file_name);
#define g_dirname g_path_get_dirname
#endif /* G_DISABLE_DEPRECATED */
#ifndef __GTK_DOC_IGNORE__
#ifdef G_OS_WIN32
#define g_get_current_dir g_get_current_dir_utf8
GLIB_DEPRECATED_FOR(g_format_size)
gchar *g_format_size_for_display (goffset size);
#endif
#endif
/* The returned strings are newly allocated with g_malloc() */
gchar* g_get_current_dir (void);
gchar* g_path_get_basename (const gchar *file_name) G_GNUC_MALLOC;
gchar* g_path_get_dirname (const gchar *file_name) G_GNUC_MALLOC;
/* Set the pointer at the specified location to NULL */
void g_nullify_pointer (gpointer *nullify_location);
/**
* GVoidFunc: