diff -pruN dillo-0.7.0/src/dillo.c dillo-0.7.0-fullwindow/src/dillo.c --- dillo-0.7.0/src/dillo.c Sat Aug 24 02:29:49 2002 +++ dillo-0.7.0-fullwindow/src/dillo.c Sat Nov 2 10:40:06 2002 @@ -49,11 +49,32 @@ /* + * Command line options structure + */ + +typedef struct { + char *sh_opt; /* must be non NULL */ + char *lg_opt; /* must be non NULL */ + int opt_argc; /* positive: mandatory, negative: optional */ + int opt_flg; /* 1 << n */ + char *help; /* can be NULL */ +} DilloCLIOptions; + +enum { + DILLO_CLI_FULLWINDOW = 1 << 1, + DILLO_CLI_HELP = 1 << 29, + DILLO_CLI_VERSION = 1 << 30, + DILLO_CLI_ERROR = 1 << 31 +}; + +/* * Forward declarations */ static void Dillo_check_home_dir(char *dir); - - +static guint32 Dillo_get_opt(DilloCLIOptions *dillo_options, int argc, + char **argv, char ***opt_arg, gint *cli_idx); +static void Dillo_print_help(DilloCLIOptions *dillo_options); +static void Dillo_print_version(void); /* * ******************************** MAIN ************************************* @@ -63,13 +84,60 @@ gint main(int argc, char *argv[]) gchar *file; DilloUrl *start_url; BrowserWindow *bw; + guint32 cli_options = 0; + gint cli_idx; + guint opt_flg; + gboolean gui_state; + gint i; + char **opt_argv = NULL; + DilloCLIOptions dillo_options[] = { + {"-f", "--fullwindow", 0, DILLO_CLI_FULLWINDOW, + " -f, --fullwindow Start in full window mode."}, + {"-v", "--version", 0, DILLO_CLI_VERSION, + " -v, --version Display version info and exit."}, + {"-h", "--help", 0, DILLO_CLI_HELP, + " -h, --help Display this help text and exit."}, + {NULL, NULL, 0, 0, NULL} + }; /* This lets threads in the file module end peacefully when aborted * todo: implement a cleaner mechanism (in file.c) */ signal(SIGPIPE, SIG_IGN); g_print("Setting locale to %s\n", gtk_set_locale()); - gtk_init(&argc, &argv); + + /* Initialize GUI when possible and parse GTK related args*/ + if (!(gui_state = gtk_init_check(&argc, &argv))) + /* GUI not initialized, args not parsed. Line from gtkmain.c */ + g_warning("cannot open display: %s", gdk_get_display()); + + /* Handle command line options */ + while ((opt_flg = Dillo_get_opt(dillo_options, argc, argv, &opt_argv, + &cli_idx))) + { + cli_options |= opt_flg; + switch (opt_flg) { + case DILLO_CLI_VERSION: + Dillo_print_version(); + return 0; + break; + case DILLO_CLI_HELP: + Dillo_print_help(dillo_options); + return 0; + break; + case DILLO_CLI_FULLWINDOW: + break; + default: + printf("Error in command line options.\n"); + return -1; + break; + } + } + + if (!gui_state) + /* Abort if GUI could not be initialized. */ + exit(1); + gdk_rgb_init(); /* check that ~/.dillo exists, create it if it doesn't */ @@ -91,6 +159,9 @@ gint main(int argc, char *argv[]) * initialized with the new browser_window structure */ bw = a_Interface_browser_window_new(prefs.width, prefs.height); + if (cli_options & DILLO_CLI_FULLWINDOW) + a_Interface_toggle_panel(bw); + a_Bookmarks_init(); /* Send dillo startup screen */ @@ -98,22 +169,25 @@ gint main(int argc, char *argv[]) a_Nav_push(bw, start_url); a_Url_free(start_url); - if (argc == 2) { - if (access(argv[1], F_OK) == 0) { - GString *UrlStr = g_string_sized_new(128); + for (i = cli_idx; i < argc; i++) { + /* If more than one URL/FILE, open in new window */ + if (i > cli_idx) + bw = a_Interface_browser_window_new(prefs.width, prefs.height); + if (access(argv[i], F_OK) == 0) { + GString *UrlStr = g_string_sized_new(128); - if (argv[1][0] == '/') { - g_string_sprintf(UrlStr, "file:%s", argv[1]); + if (argv[i][0] == '/') { + g_string_sprintf(UrlStr, "file:%s", argv[i]); } else { g_string_sprintf(UrlStr, "file:%s", g_get_current_dir()); if (UrlStr->str[UrlStr->len - 1] != '/') g_string_append(UrlStr, "/"); - g_string_append(UrlStr, argv[1]); + g_string_append(UrlStr, argv[i]); } start_url = a_Url_new(UrlStr->str, NULL, 0, 0); g_string_free(UrlStr, TRUE); } else { - start_url = a_Url_new(argv[1], NULL, 0, 0); + start_url = a_Url_new(argv[i], NULL, 0, 0); } a_Nav_push(bw, start_url); a_Url_free(start_url); @@ -157,3 +231,105 @@ static void Dillo_check_home_dir(char *d } } +/* + * Get next command line option. + * Return value: + * opt_flg of the option + * 0 if no more options found + * -1 if an unrecognised option is found or if a mandatory option + * argument is not found. + */ +static guint32 Dillo_get_opt(DilloCLIOptions *dillo_options, int argc, + char **argv, char ***opt_argv, gint *cli_idx) +{ + static int idx = 1; + int opt_flg; + int opt_argc; + int i = 0; + guint32 ret_val = 0; + + if (idx >= argc) + goto done; + + /* Create a sufficiently large array to hold the maximum possible number of + * option arguments */ + if (*opt_argv == NULL) { + int max_argc = 0; + for (i = 0; dillo_options[i].sh_opt; i++) + if (abs(dillo_options[i].opt_argc) > max_argc) + max_argc = abs(dillo_options[i].opt_argc); + if (max_argc) + *opt_argv = (char **) calloc(max_argc + 1, sizeof(char *)); + } + + /* Find the option */ + for (i = 0; dillo_options[i].sh_opt; i++) { + if (strcmp(dillo_options[i].sh_opt, argv[idx]) == 0 + || strcmp(dillo_options[i].lg_opt, argv[idx]) == 0) { + opt_flg = dillo_options[i].opt_flg; + opt_argc = dillo_options[i].opt_argc; + idx++; + + if (opt_argc) { + /* Find the required/optional arguments of the option */ + for (i = 0; idx < argc && i < abs(opt_argc) && argv[idx][0] != '-'; + i++) + (*opt_argv)[i] = argv[idx++]; + + (*opt_argv)[i] = NULL; + /* Optional arguments have opt_argc < 0 */ + if (i < opt_argc) { + printf("Option %s requires %d argument(s)\n", argv[idx - i - 1], + opt_argc); + goto error; + } + } + *cli_idx = idx; + return opt_flg; + } + } + /* No known options found. We're done if there are no more options + * -- means: consider the rest of arguments as non options */ + if (strcmp(argv[idx], "--") == 0) { + idx++; + goto done; + } + if (argv[idx][0] != '-') + goto done; + +error: + /* Unknown option or insufficient mandatory option arguments */ + ret_val = DILLO_CLI_ERROR; +done: + if (*opt_argv) + free(*opt_argv); + *cli_idx = idx; + return ret_val; +} + +/* + * Print a short help text automatically generated from the options structure + */ +static void Dillo_print_help(DilloCLIOptions *dillo_options) +{ + printf("Usage: dillo [OPTIONS] [URL|FILE]...\n" + "Options:\n"); + + for (; dillo_options && dillo_options->sh_opt; dillo_options++) + if (dillo_options->help) + printf("%s\n", dillo_options->help); + else + printf(" %s, %s *Undocumented*\n", dillo_options->sh_opt, + dillo_options->lg_opt); + + printf(" URL URL to browse.\n" + " FILE Local FILE to view.\n"); +} + +/* + * Print version (TODO: and maybe a copyright notice) + */ +static void Dillo_print_version(void) +{ + printf("Dillo %s\n", VERSION); +}