mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
Provide a method to use unicode command line arguments on Windows
For unicode command line characters Windows uses UTF-16, while Glib and GTK use UTF-8. To solve that we retrieve the command line via __wgetmainargs() and use g_utf16_to_utf8() to convert each argument. The used method should support wildcards passed as arguments (e.g. *.xml). Two new, OS abstracted functions appear in linux.c (NOP), macos.c (NOP), windows.c: subsurface_command_line_init(...) subsurface_command_line_exit(...) which are being called in main() Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
3917e7b2f7
commit
f928be5061
5 changed files with 78 additions and 0 deletions
2
dive.h
2
dive.h
|
@ -434,6 +434,8 @@ extern const char *star_strings[];
|
|||
extern const char *default_filename;
|
||||
extern const char *existing_filename;
|
||||
extern const char *subsurface_default_filename(void);
|
||||
extern void subsurface_command_line_init(gint *, gchar ***);
|
||||
extern void subsurface_command_line_exit(gint *, gchar ***);
|
||||
#define AIR_PERMILLE 209
|
||||
|
||||
#define FRACTION(n,x) ((unsigned)(n)/(x)),((unsigned)(n)%(x))
|
||||
|
|
10
linux.c
10
linux.c
|
@ -91,3 +91,13 @@ void subsurface_ui_setup(GtkSettings *settings, GtkWidget *menubar,
|
|||
divelist_font = DIVELIST_DEFAULT_FONT;
|
||||
gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
|
||||
}
|
||||
|
||||
void subsurface_command_line_init(gint *argc, gchar ***argv)
|
||||
{
|
||||
/* this is a no-op */
|
||||
}
|
||||
|
||||
void subsurface_command_line_exit(gint *argc, gchar ***argv)
|
||||
{
|
||||
/* this is a no-op */
|
||||
}
|
||||
|
|
10
macos.c
10
macos.c
|
@ -149,3 +149,13 @@ void subsurface_ui_setup(GtkSettings *settings, GtkWidget *menubar,
|
|||
|
||||
gtk_osxapplication_ready(osx_app);
|
||||
}
|
||||
|
||||
void subsurface_command_line_init(gint *argc, gchar ***argv)
|
||||
{
|
||||
/* this is a no-op */
|
||||
}
|
||||
|
||||
void subsurface_command_line_exit(gint *argc, gchar ***argv)
|
||||
{
|
||||
/* this is a no-op */
|
||||
}
|
||||
|
|
2
main.c
2
main.c
|
@ -223,6 +223,7 @@ int main(int argc, char **argv)
|
|||
|
||||
output_units = SI_units;
|
||||
|
||||
subsurface_command_line_init(&argc, &argv);
|
||||
parse_xml_init();
|
||||
|
||||
init_ui(&argc, &argv);
|
||||
|
@ -268,6 +269,7 @@ int main(int argc, char **argv)
|
|||
exit_ui();
|
||||
|
||||
parse_xml_exit();
|
||||
subsurface_command_line_exit(&argc, &argv);
|
||||
|
||||
#ifdef DEBUGFILE
|
||||
if (debugfile)
|
||||
|
|
54
windows.c
54
windows.c
|
@ -124,3 +124,57 @@ void subsurface_ui_setup(GtkSettings *settings, GtkWidget *menubar,
|
|||
divelist_font = DIVELIST_DEFAULT_FONT;
|
||||
gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
|
||||
}
|
||||
|
||||
/* barely documented API */
|
||||
extern int __wgetmainargs(int *, wchar_t ***, wchar_t ***, int, int *);
|
||||
|
||||
/* expand-convert the UTF-16 argument list to a list of UTF-8 strings */
|
||||
void subsurface_command_line_init(gint *argc, gchar ***argv)
|
||||
{
|
||||
wchar_t **wargv, **wenviron;
|
||||
gchar **argv_new;
|
||||
gchar *s;
|
||||
/* for si we assume that a struct address will equal the address
|
||||
* of its first and only int member */
|
||||
gint i, n, ret, si;
|
||||
|
||||
/* memory leak tools may reports a potential issue here at a call
|
||||
* to strcpy_s in msvcrt, wich should be a false positive. but even if there
|
||||
* is some kind of a leak, it should be unique and have the same
|
||||
* lifespan as the process heap. */
|
||||
ret = __wgetmainargs(&n, &wargv, &wenviron, TRUE, &si);
|
||||
if (ret < 0) {
|
||||
g_warning("Cannot convert command line");
|
||||
return;
|
||||
}
|
||||
argv_new = g_malloc(sizeof(gchar *) * (n + 1));
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
s = g_utf16_to_utf8((gunichar2 *)wargv[i], -1, NULL, NULL, NULL);
|
||||
if (!s) {
|
||||
g_warning("Cannot convert command line argument (%d) to UTF-8", (i + 1));
|
||||
s = "\0";
|
||||
} else if (!g_utf8_validate(s, -1, NULL)) {
|
||||
g_warning("Cannot validate command line argument '%s' (%d)", s, (i + 1));
|
||||
g_free(s);
|
||||
s = "\0";
|
||||
}
|
||||
argv_new[i] = s;
|
||||
}
|
||||
argv_new[n] = NULL;
|
||||
|
||||
/* update the argument list and count */
|
||||
if (argv && argc) {
|
||||
*argv = argv_new;
|
||||
*argc = n;
|
||||
}
|
||||
}
|
||||
|
||||
/* once done, free the argument list */
|
||||
void subsurface_command_line_exit(gint *argc, gchar ***argv)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < *argc; i++)
|
||||
g_free((*argv)[i]);
|
||||
g_free(*argv);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue