Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
grealpath.h
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2013-2014, 2016 Tobias Ellinghaus.
4 Copyright (C) 2014 Roman Lebedev.
5 Copyright (C) 2020 Andreas Schneider.
6 Copyright (C) 2020 David-Tillmann Schaefer.
7 Copyright (C) 2021 Pascal Obry.
8 Copyright (C) 2022 Martin Baƙinka.
9
10 darktable is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
14
15 darktable is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with darktable. If not, see <http://www.gnu.org/licenses/>.
22*/
23/*
24 This code is taken from http://git.gnome.org/browse/gobject-introspection/tree/giscanner/grealpath.h .
25 According to http://git.gnome.org/browse/gobject-introspection/tree/COPYING it's licensed under the LGPLv2+.
26*/
27
28#ifndef DT_COMMON_GREALPATH_H
29#define DT_COMMON_GREALPATH_H
30
31#include <stdlib.h>
32#include <stdio.h>
33#include <string.h>
34#include <errno.h>
35#include <glib.h>
36
37#include "system/macros.h" // IS_NULL_PTR
38
39#ifdef _WIN32
40#include <fileapi.h>
41#endif
42
49static inline gchar *g_realpath(const char *path)
50{
51#ifndef _WIN32
52 /* POSIX.1-2008: a NULL second argument makes realpath() allocate a buffer of exactly
53 * the size it needs. The alternative form wants a caller buffer of at least the system
54 * PATH_MAX, which is the one place in this tree that genuinely needs that macro -- so
55 * this form removes the last reason to name it. */
56 char *resolved = realpath(path, NULL);
57
58 if(IS_NULL_PTR(resolved))
59 {
60 fprintf(stderr, "path lookup '%s' fails with: '%s'\n", path, strerror(errno));
61 exit(EXIT_FAILURE);
62 }
63
64 gchar *result = g_strdup(resolved);
65 free(resolved);
66 return result;
67#else
68 /* GetFullPathNameA caps at MAX_PATH and mangles any path the active ANSI code page
69 * cannot spell, which is most user names outside us-ascii. The wide entry point has
70 * neither problem; glib owns the UTF-8 <-> UTF-16 conversion. */
71 wchar_t *wpath = g_utf8_to_utf16(path, -1, NULL, NULL, NULL);
72 if(IS_NULL_PTR(wpath)) return g_strdup(path);
73
74 /* Called with a zero-length buffer, it returns the length it wants, terminator
75 * included. Anything else is a failure we answer by handing the input back. */
76 const DWORD needed = GetFullPathNameW(wpath, 0, NULL, NULL);
77 if(needed == 0)
78 {
79 g_free(wpath);
80 return g_strdup(path);
81 }
82
83 wchar_t *wbuffer = g_new(wchar_t, needed);
84 const DWORD written = GetFullPathNameW(wpath, needed, wbuffer, NULL);
85 g_free(wpath);
86
87 if(written == 0 || written >= needed)
88 {
89 g_free(wbuffer);
90 return g_strdup(path);
91 }
92
93 gchar *result = g_utf16_to_utf8(wbuffer, -1, NULL, NULL, NULL);
94 g_free(wbuffer);
95 return IS_NULL_PTR(result) ? g_strdup(path) : result;
96#endif
97}
98
99#endif // DT_COMMON_GREALPATH_H
100
101// clang-format off
102// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
103// vim: shiftwidth=2 expandtab tabstop=2 cindent
104// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
105// clang-format on
static gchar * g_realpath(const char *path)
Definition grealpath.h:49
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
Definition macros.h:96