1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 #include <string.h> /* strlen() */
29 #define mkdir(s,a) _mkdir(s)
32 #include <sys/types.h>
35 /** Get the name of a subdirectory of our data directory.
36 * This function does not create the subdirectory, just make the correct name.
37 * @param subdir The name of the directory desired.
38 * @returns The full path to the directory. This string should be freed
42 dia_get_data_directory(const gchar
* subdir
)
46 * Calculate from executable path
48 gchar sLoc
[MAX_PATH
+1];
49 HINSTANCE hInst
= GetModuleHandle(NULL
);
51 if (0 != GetModuleFileName(hInst
, sLoc
, MAX_PATH
))
54 if (strrchr(sLoc
, G_DIR_SEPARATOR
))
55 strrchr(sLoc
, G_DIR_SEPARATOR
)[0] = 0;
56 /* and one dir (bin) */
57 if (strrchr(sLoc
, G_DIR_SEPARATOR
))
58 strrchr(sLoc
, G_DIR_SEPARATOR
)[1] = 0;
60 return g_strconcat (sLoc
, subdir
, NULL
);
63 if (strlen (subdir
) == 0)
64 return g_strconcat (DATADIR
, NULL
);
66 return g_strconcat (DATADIR
, G_DIR_SEPARATOR_S
, subdir
, NULL
);
70 /** Get a subdirectory of our lib directory. This does not create the
71 * directory, merely the name of the full path.
72 * @param subdir The name of the subdirectory wanted.
73 * @returns The full path of the named directory. The string should be
77 dia_get_lib_directory(const gchar
* subdir
)
81 * Calulate from executable path
83 gchar sLoc
[MAX_PATH
+1];
84 HINSTANCE hInst
= GetModuleHandle(NULL
);
86 if (0 != GetModuleFileName(hInst
, sLoc
, MAX_PATH
))
89 if (strrchr(sLoc
, G_DIR_SEPARATOR
))
90 strrchr(sLoc
, G_DIR_SEPARATOR
)[0] = 0;
91 /* and one dir (bin) */
92 if (strrchr(sLoc
, G_DIR_SEPARATOR
))
93 strrchr(sLoc
, G_DIR_SEPARATOR
)[1] = 0;
95 return g_strconcat (sLoc
, subdir
, NULL
);
98 return g_strconcat (LIBDIR
, G_DIR_SEPARATOR_S
, subdir
, NULL
);
102 /** Get the name of a file under the Dia config directory. If no home
103 * directory can be found, uses a temporary directory.
104 * @param subfile Name of the subfile.
105 * @returns A string with the full path of the desired file. This string
106 * should be freed after use.
109 dia_config_filename(const gchar
*subfile
)
111 const gchar
*homedir
;
113 homedir
= g_get_home_dir();
115 homedir
= g_get_tmp_dir(); /* put config stuff in /tmp -- not ideal, but
116 * we should not reach this state */
118 return g_strconcat(homedir
, G_DIR_SEPARATOR_S
".dia" G_DIR_SEPARATOR_S
,
122 /** Ensure that the directory part of `filename' exists.
123 * @param filename A file that we want the parent directory of to exist.
124 * @returns TRUE if the directory existed or has been created, FALSE if
125 * it cannot be created.
128 dia_config_ensure_dir(const gchar
*filename
)
130 gchar
*dir
= g_path_get_dirname(filename
);
132 if (dir
== NULL
) return FALSE
;
133 if (strcmp(dir
, ".")) {
134 if (g_file_test(dir
, G_FILE_TEST_IS_DIR
)) {
137 if (dia_config_ensure_dir(dir
)) {
138 exists
= (mkdir(dir
, 0755) == 0);
150 /** Remove all instances of . and .. from an absolute path.
151 * This is not a cheap function.
152 * @param path String to canonicalize.
153 * @returns A newly allocated string, or NULL if too many ..'s were found
156 dia_get_canonical_path(const gchar
*path
)
159 gchar
**list
= g_strsplit (path
, G_DIR_SEPARATOR_S
, -1);
162 while (list
[i
] != NULL
) {
163 if (0 == strcmp (list
[i
], ".")) {
164 /* simple, just remove it */
166 list
[i
] = g_strdup ("");
168 else if (0 == strcmp (list
[i
], "..")) {
169 /* need to 'remove' the previous non empty part too */
172 list
[i
] = g_strdup ("");
174 if (0 != strlen(list
[n
])) {
177 list
[n
] = g_strdup ("");
182 /* we haven't found an entry to remove for '..' */
189 /* cant use g_strjoinv () cause it would stumble about empty elements */
190 GString
*str
= g_string_new (NULL
);
193 while (list
[i
] != NULL
) {
194 if (strlen(list
[i
]) > 0) {
196 /* win32 filenames usually don't start with a dir separator but
199 if (i
!= 0 || list
[i
][1] != ':')
200 g_string_append (str
, G_DIR_SEPARATOR_S
);
201 g_string_append (str
, list
[i
]);
205 ret
= g_string_free (str
, FALSE
);
213 /** Returns an filename in UTF-8 encoding from filename in filesystem
214 * encoding. In GTK < 2.6, invalid sequences are not [???]
215 * @param filename A filename string as gotten from the filesystem.
216 * @returns UTF-8 encoded copy of the filename.
217 * The value returned is a pointer to static array.
218 * Note: The string can be used AFTER the next call to this function
219 * Written like glib/gstrfuncs.c#g_strerror()
222 dia_message_filename(const gchar
*filename
)
227 #if GLIB_CHECK_VERSION(2,6,0)
228 tmp
= g_filename_display_name(filename
);
231 tmp
= g_filename_to_utf8(filename
, -1, &num_read
, NULL
, NULL
);
234 /* Best effort at displaying filename: Display as must as is readable */
235 g_utf8_validate(filename
, -1, &ellipsis
);
236 tmp
= g_filename_to_utf8(filename
, ellipsis
-filename
, NULL
, NULL
, NULL
);
237 ellipsis
= g_strdup_printf(_("%s<illegal characters>..."), tmp
);
242 /* Stick in the quark table so that we can return a static result
244 msg_quark
= g_quark_from_string (tmp
);
246 tmp
= (gchar
*) g_quark_to_string (msg_quark
);
250 /** Return an absolute filename from an absolute or relative filename.
251 * @param filename A relative or absolute filename.
252 * @return Absolute and canonicalized filename as a newly allocated string.
255 dia_get_absolute_filename (const gchar
*filename
)
260 if (filename
== NULL
) return NULL
;
261 if (g_path_is_absolute(filename
)) return dia_get_canonical_path(filename
);
262 current_dir
= g_get_current_dir();
263 fullname
= g_build_filename(current_dir
, filename
, NULL
);
265 if (strchr(fullname
, '.') == NULL
) return fullname
;
266 canonical
= dia_get_canonical_path(fullname
);
267 if (canonical
== NULL
) {
268 message_warning(_("Too many ..'s in filename %s\n"),
269 dia_message_filename(filename
));
270 return g_strdup(filename
);