summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dive.h2
-rw-r--r--linux.c10
-rw-r--r--macos.c10
-rw-r--r--main.c2
-rw-r--r--windows.c54
5 files changed, 78 insertions, 0 deletions
diff --git a/dive.h b/dive.h
index d05f1d1b4..2c224a12d 100644
--- a/dive.h
+++ b/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))
diff --git a/linux.c b/linux.c
index 47a00a059..4e7e61c7c 100644
--- a/linux.c
+++ b/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 */
+}
diff --git a/macos.c b/macos.c
index d0d7a742b..17ae4a411 100644
--- a/macos.c
+++ b/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 */
+}
diff --git a/main.c b/main.c
index 7101b8b87..bc7bf7af1 100644
--- a/main.c
+++ b/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)
diff --git a/windows.c b/windows.c
index b6e10bb71..f2f06f9a0 100644
--- a/windows.c
+++ b/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);
+}