From DONOTREPLY at icculus.org Fri Jan 11 18:44:38 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 11 Jan 2008 18:44:38 -0500 Subject: r392 - trunk Message-ID: <20080111234438.1363.qmail@icculus.org> Author: icculus Date: 2008-01-11 18:44:37 -0500 (Fri, 11 Jan 2008) New Revision: 392 Modified: trunk/universal.h Log: Minor comment added. Modified: trunk/universal.h =================================================================== --- trunk/universal.h 2007-12-18 14:49:09 UTC (rev 391) +++ trunk/universal.h 2008-01-11 23:44:37 UTC (rev 392) @@ -125,6 +125,8 @@ void warn(const char *fmt, ...) ISPRINTF(1,2); // Malloc replacements that blow up on allocation failure. +// Please note that xmalloc() will zero the newly-allocated memory buffer, +// like calloc() would, but xrealloc() makes no such promise! void *xmalloc(size_t bytes); void *xrealloc(void *ptr, size_t bytes); char *xstrdup(const char *str); From DONOTREPLY at icculus.org Fri Jan 11 18:48:24 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 11 Jan 2008 18:48:24 -0500 Subject: r393 - in trunk: . scripts Message-ID: <20080111234824.8120.qmail@icculus.org> Author: icculus Date: 2008-01-11 18:48:24 -0500 (Fri, 11 Jan 2008) New Revision: 393 Modified: trunk/gui.h trunk/gui_gtkplus2.c trunk/lua_glue.c trunk/scripts/mojosetup_init.lua Log: Tooltip support for options page in GTK+ ui (thanks, Nemo!) Modified: trunk/gui.h =================================================================== --- trunk/gui.h 2008-01-11 23:44:37 UTC (rev 392) +++ trunk/gui.h 2008-01-11 23:48:24 UTC (rev 393) @@ -45,6 +45,7 @@ struct MojoGuiSetupOptions { const char *description; + const char *tooltip; boolean value; boolean is_group_parent; uint64 size; Modified: trunk/gui_gtkplus2.c =================================================================== --- trunk/gui_gtkplus2.c 2008-01-11 23:44:37 UTC (rev 392) +++ trunk/gui_gtkplus2.c 2008-01-11 23:48:24 UTC (rev 393) @@ -611,6 +611,7 @@ if (opts != NULL) { GtkWidget *widget; + if (opts->is_group_parent) { MojoGuiSetupOptions *kids = opts->child; @@ -661,6 +662,13 @@ gtk_box_pack_start(GTK_BOX(box), widget, FALSE, TRUE, 0); gtk_signal_connect(GTK_OBJECT(widget), "toggled", GTK_SIGNAL_FUNC(signal_option_toggled), opts); + + if (opts->tooltip != NULL) + { + GtkTooltips *tip = gtk_tooltips_new(); + gtk_tooltips_set_tip(tip, widget, opts->tooltip, NULL); + } // if + if (opts->child != NULL) { build_options(opts->child, new_option_level(box), Modified: trunk/lua_glue.c =================================================================== --- trunk/lua_glue.c 2008-01-11 23:44:37 UTC (rev 392) +++ trunk/lua_glue.c 2008-01-11 23:48:24 UTC (rev 393) @@ -1115,6 +1115,11 @@ lua_getfield(L, -1, "description"); newopt->description = xstrdup(lua_tostring(L, -1)); lua_pop(L, 1); + + lua_getfield(L, -1, "tooltip"); + if (!lua_isnil(L, -1)) + newopt->tooltip = xstrdup(lua_tostring(L, -1)); + lua_pop(L, 1); if (!is_option_group) { @@ -1134,6 +1139,7 @@ if ((is_option_group) && (!newopt->child)) // skip empty groups. { free((void *) newopt->description); + free((void *) newopt->tooltip); free(newopt); newopt = NULL; } // if @@ -1249,6 +1255,7 @@ } // if free((void *) opts->description); + free((void *) opts->tooltip); free(opts); } // if } // done_gui_options Modified: trunk/scripts/mojosetup_init.lua =================================================================== --- trunk/scripts/mojosetup_init.lua 2008-01-11 23:44:37 UTC (rev 392) +++ trunk/scripts/mojosetup_init.lua 2008-01-11 23:48:24 UTC (rev 393) @@ -431,6 +431,7 @@ { "disabled", false, mustBeBool }, { "bytes", nil, mustExist, mustBeNumber }, { "description", nil, mustExist, mustBeString, cantBeEmpty }, + { "tooltip", nil, mustBeString, cantBeEmpty }, }) end From DONOTREPLY at icculus.org Fri Jan 11 20:20:54 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 11 Jan 2008 20:20:54 -0500 Subject: r394 - in trunk: . examples/duke3d/scripts scripts Message-ID: <20080112012054.27262.qmail@icculus.org> Author: icculus Date: 2008-01-11 20:20:54 -0500 (Fri, 11 Jan 2008) New Revision: 394 Modified: trunk/examples/duke3d/scripts/config.lua trunk/gui_gtkplus2.c trunk/scripts/mojosetup_init.lua Log: More work on option tooltips. Modified: trunk/examples/duke3d/scripts/config.lua =================================================================== --- trunk/examples/duke3d/scripts/config.lua 2008-01-11 23:48:24 UTC (rev 393) +++ trunk/examples/duke3d/scripts/config.lua 2008-01-12 01:20:54 UTC (rev 394) @@ -50,6 +50,9 @@ { description = _("Installation type"), + -- This is a kind of useless tooltip; I'm just using it for testing. + tooltip = _("Pick your installation type"), + Setup.Option { value = true, @@ -57,6 +60,7 @@ disabled = false, bytes = 31102768, description = _("Install Shareware version"), + tooltip = _("This does not need a retail copy of the game. It's free!"), Setup.File { @@ -83,6 +87,7 @@ disabled = false, bytes = 64525364, description = _("Install full game from Atomic Edition disc"), + tooltip = _("Pick this if you have a retail game disc from 3DRealms."), Setup.File { Modified: trunk/gui_gtkplus2.c =================================================================== --- trunk/gui_gtkplus2.c 2008-01-11 23:48:24 UTC (rev 393) +++ trunk/gui_gtkplus2.c 2008-01-12 01:20:54 UTC (rev 394) @@ -605,12 +605,27 @@ } // new_option_level +// use this to generate a tooltip only as needed. +static GtkTooltips *get_tip(GtkTooltips **_tip) +{ + if (*_tip == NULL) + { + GtkTooltips *tip = gtk_tooltips_new(); + gtk_tooltips_enable(tip); + *_tip = tip; + } // if + + return *_tip; +} // get_tip + + static void build_options(MojoGuiSetupOptions *opts, GtkWidget *box, gboolean sensitive) { if (opts != NULL) { - GtkWidget *widget; + GtkTooltips *tip = NULL; + GtkWidget *widget = NULL; if (opts->is_group_parent) { @@ -627,6 +642,9 @@ gtk_container_add(GTK_CONTAINER(alignment), widget); gtk_box_pack_start(GTK_BOX(box), alignment, FALSE, TRUE, 0); + if (opts->tooltip != NULL) + gtk_tooltips_set_tip(get_tip(&tip), widget, opts->tooltip, 0); + widget = NULL; childbox = new_option_level(box); while (kids) @@ -642,6 +660,10 @@ gtk_box_pack_start(GTK_BOX(childbox), widget, FALSE, TRUE, 0); gtk_signal_connect(GTK_OBJECT(widget), "toggled", GTK_SIGNAL_FUNC(signal_option_toggled), kids); + + if (kids->tooltip != NULL) + gtk_tooltips_set_tip(get_tip(&tip),widget,kids->tooltip,0); + if (kids->child != NULL) { build_options(kids->child, new_option_level(childbox), @@ -664,10 +686,7 @@ GTK_SIGNAL_FUNC(signal_option_toggled), opts); if (opts->tooltip != NULL) - { - GtkTooltips *tip = gtk_tooltips_new(); - gtk_tooltips_set_tip(tip, widget, opts->tooltip, NULL); - } // if + gtk_tooltips_set_tip(get_tip(&tip), widget, opts->tooltip, 0); if (opts->child != NULL) { Modified: trunk/scripts/mojosetup_init.lua =================================================================== --- trunk/scripts/mojosetup_init.lua 2008-01-11 23:48:24 UTC (rev 393) +++ trunk/scripts/mojosetup_init.lua 2008-01-12 01:20:54 UTC (rev 394) @@ -440,6 +440,7 @@ { { "disabled", nil, mustBeBool }, { "description", nil, mustExist, mustBeString, cantBeEmpty }, + { "tooltip", nil, mustBeString, cantBeEmpty }, }) end From DONOTREPLY at icculus.org Fri Jan 11 20:47:16 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 11 Jan 2008 20:47:16 -0500 Subject: r395 - trunk Message-ID: <20080112014716.2444.qmail@icculus.org> Author: icculus Date: 2008-01-11 20:47:15 -0500 (Fri, 11 Jan 2008) New Revision: 395 Modified: trunk/docs.txt Log: Documentation on tooltip attribute. Modified: trunk/docs.txt =================================================================== --- trunk/docs.txt 2008-01-12 01:20:54 UTC (rev 394) +++ trunk/docs.txt 2008-01-12 01:47:15 UTC (rev 395) @@ -454,6 +454,13 @@ checkbox. + tooltip (no default, mustBeString, cantBeEmpty) + + This string will be used in mouseover "tooltips" in GUI environments for + this option's UI widget. There is no guarantee that they will be shown to + a user in any GUI target, so don't rely on them! + + Setup.OptionGroup: This element can be the parent or child of Setup.Option, or a child of @@ -485,6 +492,13 @@ radio button group. + tooltip (no default, mustBeString, cantBeEmpty) + + This string will be used in mouseover "tooltips" in GUI environments for + this option's UI widget. There is no guarantee that they will be shown to + a user in any GUI target, so don't rely on them! + + Setup.File: This element specifies a fileset, a collection of files, to install. These From DONOTREPLY at icculus.org Fri Jan 11 21:42:21 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 11 Jan 2008 21:42:21 -0500 Subject: r396 - trunk Message-ID: <20080112024221.23478.qmail@icculus.org> Author: icculus Date: 2008-01-11 21:42:21 -0500 (Fri, 11 Jan 2008) New Revision: 396 Modified: trunk/gui_gtkplus2.c Log: Removed placeholder text, since this actually doesn't suck. Modified: trunk/gui_gtkplus2.c =================================================================== --- trunk/gui_gtkplus2.c 2008-01-12 01:47:15 UTC (rev 395) +++ trunk/gui_gtkplus2.c 2008-01-12 02:42:21 UTC (rev 396) @@ -704,7 +704,6 @@ boolean can_back, boolean can_fwd) { int retval; - GtkWidget *widget; GtkWidget *box; GtkWidget *page; // this is a vbox. @@ -713,12 +712,6 @@ gtk_widget_show(box); gtk_box_pack_start(GTK_BOX(page), box, FALSE, FALSE, 0); - widget = gtk_label_new("!!! FIXME: this GUI stage is a placeholder"); - gtk_widget_show(widget); - gtk_box_pack_start(GTK_BOX(box), widget, FALSE, TRUE, 0); - gtk_label_set_justify(GTK_LABEL(widget), GTK_JUSTIFY_CENTER); - gtk_label_set_line_wrap(GTK_LABEL(widget), TRUE); - build_options(opts, box, TRUE); // !!! FIXME: better text. From DONOTREPLY at icculus.org Fri Jan 11 23:58:17 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 11 Jan 2008 23:58:17 -0500 Subject: r397 - in trunk: . scripts Message-ID: <20080112045817.30847.qmail@icculus.org> Author: icculus Date: 2008-01-11 23:58:16 -0500 (Fri, 11 Jan 2008) New Revision: 397 Modified: trunk/gui_gtkplus2.c trunk/lua_glue.c trunk/mojosetup.c trunk/scripts/mojosetup_mainline.lua Log: Changed fatal() so it only puts up an error box if the message isn't NULL, and other cleanups to reduce the amount of chatter when the user hits cancel. Modified: trunk/gui_gtkplus2.c =================================================================== --- trunk/gui_gtkplus2.c 2008-01-12 02:42:21 UTC (rev 396) +++ trunk/gui_gtkplus2.c 2008-01-12 04:58:16 UTC (rev 397) @@ -521,7 +521,7 @@ gtk_widget_show(finallabel); gtk_box_pack_start(GTK_BOX(widget), finallabel, FALSE, TRUE, 0); gtk_label_set_justify(GTK_LABEL(finallabel), GTK_JUSTIFY_LEFT); - gtk_label_set_line_wrap(GTK_LABEL(finallabel), FALSE); + gtk_label_set_line_wrap(GTK_LABEL(finallabel), TRUE); gtk_signal_connect(GTK_OBJECT(window), "delete-event", GTK_SIGNAL_FUNC(signal_delete), NULL); Modified: trunk/lua_glue.c =================================================================== --- trunk/lua_glue.c 2008-01-12 02:42:21 UTC (rev 396) +++ trunk/lua_glue.c 2008-01-12 04:58:16 UTC (rev 397) @@ -507,8 +507,6 @@ static int luahook_fatal(lua_State *L) { const char *errstr = lua_tostring(L, 1); - if (errstr == NULL) - errstr = _("Unknown error"); return fatal(errstr); // doesn't actually return. } // luahook_fatal Modified: trunk/mojosetup.c =================================================================== --- trunk/mojosetup.c 2008-01-12 02:42:21 UTC (rev 396) +++ trunk/mojosetup.c 2008-01-12 04:58:16 UTC (rev 397) @@ -449,39 +449,44 @@ int fatal(const char *fmt, ...) { static boolean in_fatal = false; - int len = 128; - char *buf = NULL; - int rc = 0; - va_list ap; if (in_fatal) return panic("BUG: fatal() called more than once!"); in_fatal = true; - buf = xmalloc(len); - va_start(ap, fmt); - rc = vsnprintf(buf, len, fmt, ap); - va_end(ap); - if (rc >= len) + // may not want to show a message, since we displayed one elsewhere, etc. + if (fmt != NULL) { - len = rc; - buf = xrealloc(buf, len); + va_list ap; + int rc = 0; + int len = 128; + char *buf = xmalloc(len); + va_start(ap, fmt); - vsnprintf(buf, len, fmt, ap); + rc = vsnprintf(buf, len, fmt, ap); va_end(ap); + if (rc >= len) + { + len = rc; + buf = xrealloc(buf, len); + va_start(ap, fmt); + vsnprintf(buf, len, fmt, ap); + va_end(ap); + } // if + + logError("FATAL: %s", buf); + + if (GGui != NULL) + GGui->msgbox(_("Fatal error"), buf); + + free(buf); } // if - logError("FATAL: %s", buf); + // Shouldn't call fatal() before app is initialized! if ( (GGui == NULL) || (!MojoLua_initialized()) ) - { - logError("fatal() called before app is initialized! Panicking..."); - panic(buf); // Shouldn't call fatal() before app is initialized! - } // if + panic("fatal() called before app is initialized! Panicking..."); - GGui->msgbox(_("Fatal error"), buf); - free(buf); - MojoLua_callProcedure("revertinstall"); deinitEverything(); Modified: trunk/scripts/mojosetup_mainline.lua =================================================================== --- trunk/scripts/mojosetup_mainline.lua 2008-01-12 02:42:21 UTC (rev 396) +++ trunk/scripts/mojosetup_mainline.lua 2008-01-12 04:58:16 UTC (rev 397) @@ -92,7 +92,7 @@ function MojoSetup.revertinstall() -- !!! FIXME: language. if MojoSetup.gui_started then - MojoSetup.gui.final(_("There were errors. We will now put things back how we found them and exit.")); + MojoSetup.gui.final(_("Incomplete installation. We will revert any changes we made.")); end MojoSetup.loginfo("Cleaning up half-finished installation..."); @@ -257,7 +257,7 @@ -- !!! FIXME: formatting! if not keepgoing then MojoSetup.logerror("User cancelled install during file write.") - MojoSetup.fatal(_("User cancelled installation.")) + MojoSetup.fatal() else MojoSetup.logerror("Failed to create file '" .. dest .. "'") MojoSetup.fatal(_("File creation failed!")) @@ -1027,7 +1027,7 @@ i = i - 1 end elseif rc == 0 then - MojoSetup.fatal(_("User cancelled installation.")) + MojoSetup.fatal() else MojoSetup.fatal(_("BUG: stage returned wrong value.")) end From DONOTREPLY at icculus.org Sat Jan 12 00:44:29 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 12 Jan 2008 00:44:29 -0500 Subject: r398 - trunk Message-ID: <20080112054429.22024.qmail@icculus.org> Author: icculus Date: 2008-01-12 00:44:29 -0500 (Sat, 12 Jan 2008) New Revision: 398 Modified: trunk/gui_gtkplus2.c Log: Disable the "next" button on the destination page when the text entry is blank. Modified: trunk/gui_gtkplus2.c =================================================================== --- trunk/gui_gtkplus2.c 2008-01-12 04:58:16 UTC (rev 397) +++ trunk/gui_gtkplus2.c 2008-01-12 05:44:29 UTC (rev 398) @@ -39,6 +39,8 @@ PAGE_FINAL } WizardPages; +static WizardPages currentpage = PAGE_INTRO; +static gboolean canfwd = TRUE; static GtkWidget *gtkwindow = NULL; static GtkWidget *pagetitle = NULL; static GtkWidget *notebook = NULL; @@ -64,19 +66,22 @@ } click_value = CLICK_NONE; -static void prepare_wizard(const char *name, gint page, +static void prepare_wizard(const char *name, WizardPages page, boolean can_back, boolean can_fwd) { char *markup = g_markup_printf_escaped( "%s", name); + currentpage = page; + canfwd = can_fwd; + gtk_label_set_markup(GTK_LABEL(pagetitle), markup); g_free(markup); gtk_widget_set_sensitive(back, can_back); gtk_widget_set_sensitive(next, can_fwd); - gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), page); + gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), (gint) page); assert(click_value == CLICK_NONE); assert(gtkwindow != NULL); @@ -117,7 +122,7 @@ } // pump_events -static int run_wizard(const char *name, gint page, +static int run_wizard(const char *name, WizardPages page, boolean can_back, boolean can_fwd) { int retval = CLICK_NONE; @@ -152,6 +157,7 @@ } // else } // signal_clicked + static void signal_browse_clicked(GtkButton *_button, gpointer data) { GtkWidget *dialog = gtk_file_chooser_dialog_new ( @@ -185,9 +191,22 @@ // !!! FIXME: Could warn when the target directory already contains files? gtk_widget_destroy(dialog); -} +} // signal_browse_clicked +static void signal_dest_changed(GtkComboBox *combo, gpointer user_data) +{ + // Disable the forward button when the destination entry is blank. + if ((currentpage == PAGE_DESTINATION) && (canfwd)) + { + gchar *str = gtk_combo_box_get_active_text(combo); + const gboolean filled_in = ((str != NULL) && (*str != '\0')); + g_free(str); + gtk_widget_set_sensitive(next, filled_in); + } // if +} // signal_dest_changed + + static uint8 MojoGui_gtkplus2_priority(boolean istty) { // gnome-session exports this environment variable since 2002. @@ -373,6 +392,9 @@ GtkWidget *alignment; GtkWidget *hbox; + currentpage = PAGE_INTRO; + canfwd = TRUE; + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), title); gtk_container_set_border_width(GTK_CONTAINER(window), 8); @@ -489,6 +511,8 @@ gtk_label_set_line_wrap(GTK_LABEL(widget), FALSE); alignment = gtk_alignment_new(0.5, 0.5, 1, 0); destination = gtk_combo_box_entry_new_text(); + gtk_signal_connect(GTK_OBJECT(destination), "changed", + GTK_SIGNAL_FUNC(signal_dest_changed), NULL); gtk_container_add(GTK_CONTAINER(alignment), destination); gtk_box_pack_start(GTK_BOX(hbox), alignment, TRUE, TRUE, 0); browse = create_button(hbox, "gtk-open", @@ -738,14 +762,13 @@ can_back, can_fwd); str = gtk_combo_box_get_active_text(combo); - if ((str == NULL) || (*str == '\0')) - *command = 0; - else - { - retval = entry->xstrdup(str); - g_free(str); - } // else + // shouldn't ever be empty ("next" should be disabled in that case). + assert( (*command <= 0) || ((str != NULL) && (*str != '\0')) ); + + retval = entry->xstrdup(str); + g_free(str); + for (i = recnum-1; i >= 0; i--) gtk_combo_box_remove_text(combo, i); From DONOTREPLY at icculus.org Sat Jan 12 05:16:05 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 12 Jan 2008 05:16:05 -0500 Subject: r399 - trunk Message-ID: <20080112101605.9083.qmail@icculus.org> Author: icculus Date: 2008-01-12 05:16:04 -0500 (Sat, 12 Jan 2008) New Revision: 399 Modified: trunk/stb_image.c Log: Fixed GCC compiler warning. Modified: trunk/stb_image.c =================================================================== --- trunk/stb_image.c 2008-01-12 05:44:29 UTC (rev 398) +++ trunk/stb_image.c 2008-01-12 10:16:04 UTC (rev 399) @@ -3022,8 +3022,12 @@ unsigned char *tga_data; unsigned char *tga_palette = NULL; int i, j; - unsigned char raw_data[4]; - unsigned char trans_data[4]; +#if __MOJOSETUP__ // gcc whining fixes. --ryan. + //unsigned char raw_data[4]; + //unsigned char trans_data[4]; + unsigned char raw_data[4] = { 0, 0, 0, 0 }; + unsigned char trans_data[4] = { 0, 0, 0, 0 }; +#endif int RLE_count = 0; int RLE_repeating = 0; int read_next_pixel = 1; From DONOTREPLY at icculus.org Sat Jan 12 05:48:34 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 12 Jan 2008 05:48:34 -0500 Subject: r400 - in trunk: . scripts Message-ID: <20080112104834.4755.qmail@icculus.org> Author: icculus Date: 2008-01-12 05:48:34 -0500 (Sat, 12 Jan 2008) New Revision: 400 Modified: trunk/docs.txt trunk/fileio.c trunk/gui.c trunk/gui_gtkplus2.c trunk/gui_ncurses.c trunk/gui_stdio.c trunk/gui_www.c trunk/lua_glue.c trunk/mojosetup.c trunk/platform_unix.c trunk/scripts/localization.lua trunk/universal.h Log: Reworked string formatting, so you can reorder formatting args by localization, dynamically allocate the formatted string, and not depend so much on the C runtime. Modified: trunk/docs.txt =================================================================== --- trunk/docs.txt 2008-01-12 10:16:04 UTC (rev 399) +++ trunk/docs.txt 2008-01-12 10:48:34 UTC (rev 400) @@ -740,7 +740,16 @@ the basic config schema. Everything else is free game. Here are the globals that MojoSetup provides: + MojoSetup.format(fmt, ...) + Format a string, sort of (but not exactly!) like sprintf(). + The only formatters accepted are %0 through %9 (and %%), which do not + have to appear in order in the string, but match the varargs in the + order they are passed to the function. + + format('%1 %0 %1 %%', 'X', 'Y', 'Z') will return the string: 'Y X Y %' + + MojoSetup.fatal(errstr) Display (errstr) to the end user and stop the installation. The installer Modified: trunk/fileio.c =================================================================== --- trunk/fileio.c 2008-01-12 10:16:04 UTC (rev 399) +++ trunk/fileio.c 2008-01-12 10:48:34 UTC (rev 400) @@ -570,7 +570,6 @@ #if !SUPPORT_URL_HTTP && !SUPPORT_URL_FTP MojoInput *MojoInput_fromURL(const char *url) { - // !!! FIXME: localization. logError(_("No networking support in this build.")); return NULL; } // MojoInput_fromURL Modified: trunk/gui.c =================================================================== --- trunk/gui.c 2008-01-12 10:16:04 UTC (rev 399) +++ trunk/gui.c 2008-01-12 10:48:34 UTC (rev 400) @@ -73,7 +73,7 @@ { if ( (i->priority == p) && (i->gui->init()) ) { - logInfo("Selected '%s' UI.", i->gui->name()); + logInfo("Selected '%0' UI.", i->gui->name()); return i; } // if } // for Modified: trunk/gui_gtkplus2.c =================================================================== --- trunk/gui_gtkplus2.c 2008-01-12 10:16:04 UTC (rev 399) +++ trunk/gui_gtkplus2.c 2008-01-12 10:48:34 UTC (rev 400) @@ -781,14 +781,15 @@ gint rc = 0; // !!! FIXME: Use stock GTK icon for "media"? // !!! FIXME: better text. - const char *title = entry->_("Media change"); + const char *title = entry->xstrdup(entry->_("Media change")); // !!! FIXME: better text. - const char *fmt = entry->_("Please insert '%s'"); - size_t len = strlen(fmt) + strlen(medianame) + 1; - char *text = (char *) entry->xmalloc(len); - snprintf(text, len, fmt, medianame); + const char *fmt = entry->xstrdup(entry->_("Please insert '%0'")); + const char *text = entry->format(fmt, medianame); rc = do_msgbox(title, text, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK_CANCEL, GTK_RESPONSE_OK, NULL); + free((void *) text); + free((void *) fmt); + free((void *) title); return (rc == GTK_RESPONSE_OK); } // MojoGui_gtkplus2_insertmedia Modified: trunk/gui_ncurses.c =================================================================== --- trunk/gui_ncurses.c 2008-01-12 10:16:04 UTC (rev 399) +++ trunk/gui_ncurses.c 2008-01-12 10:48:34 UTC (rev 400) @@ -1285,25 +1285,22 @@ static boolean MojoGui_ncurses_insertmedia(const char *medianame) { - char *fmt = entry->xstrdup(entry->_("Please insert '%s'")); - const size_t len = strlen(fmt) + strlen(medianame) + 1; - char *text = (char *) entry->xmalloc(len); + char *fmt = entry->xstrdup(entry->_("Please insert '%0'")); + char *text = entry->format(fmt, medianame); char *localized_ok = entry->xstrdup(entry->_("Ok")); char *localized_cancel = entry->xstrdup(entry->_("Cancel")); char *buttons[] = { localized_ok, localized_cancel }; MojoBox *mojobox = NULL; int rc = 0; - snprintf(text, len, fmt, medianame); - free(fmt); - mojobox = makeBox(entry->_("Media change"), text, buttons, 2, false, true); while ((rc = upkeepBox(&mojobox, wgetch(mojobox->mainwin))) == -1) {} freeBox(mojobox, true); - free(text); free(localized_cancel); free(localized_ok); + free(text); + free(fmt); return (rc == 0); } // MojoGui_ncurses_insertmedia Modified: trunk/gui_stdio.c =================================================================== --- trunk/gui_stdio.c 2008-01-12 10:16:04 UTC (rev 399) +++ trunk/gui_stdio.c 2008-01-12 10:48:34 UTC (rev 400) @@ -46,16 +46,18 @@ // !!! FIXME: abort in read_stdin() if i/o fails? int retval = 0; - const char *backstr = NULL; + char *backstr = (back) ? entry->xstrdup(entry->_("back")) : NULL; if (prompt != NULL) printf("%s\n", prompt); if (back) { - backstr = entry->xstrdup(entry->_("back")); - printf(entry->_("Type '%s' to go back."), backstr); - printf("\n"); + char *fmt = entry->xstrdup(entry->_("Type '%0' to go back.")); + char *msg = entry->format(fmt, backstr); + printf("%s\n", msg); + free(msg); + free(fmt); } // if if (fwd) @@ -73,7 +75,7 @@ retval = -1; } // if - free((void *) backstr); + free(backstr); return retval; } // readstr @@ -111,7 +113,11 @@ static void MojoGui_stdio_msgbox(const char *title, const char *text) { char buf[128]; - printf(entry->_("NOTICE: %s\n[hit enter]"), text); + char *fmt = entry->xstrdup(entry->_("NOTICE: %0\n[hit enter]")); + char *msg = entry->format(fmt, text); + printf("%s\n", msg); + free(msg); + free(fmt); fflush(stdout); read_stdin(buf, sizeof (buf)); } // MojoGui_stdio_msgbox @@ -123,10 +129,11 @@ boolean retval = false; if (!feof(stdin)) { - const char *fmt = ((defval) ? "%s\n[Y/n]: " : "%s\n[y/N]: "); - const char *localized_fmt = entry->xstrdup(entry->_(fmt)); - const char *localized_no = entry->xstrdup(entry->_("N")); - const char *localized_yes = entry->xstrdup(entry->_("Y")); + const char *_fmt = ((defval) ? "%1\n[Y/n]: " : "%1\n[y/N]: "); + char *fmt = entry->xstrdup(entry->_(_fmt)); + char *msg = entry->format(fmt, text); + char *localized_no = entry->xstrdup(entry->_("N")); + char *localized_yes = entry->xstrdup(entry->_("Y")); boolean getout = false; char buf[128]; @@ -135,7 +142,7 @@ int rc = 0; getout = true; // we may reset this later. - printf(localized_fmt, text); + printf("%s\n", msg); fflush(stdout); rc = read_stdin(buf, sizeof (buf)); @@ -151,9 +158,10 @@ getout = false; // try again. } // while - free((void *) localized_yes); - free((void *) localized_no); - free((void *) localized_fmt); + free(localized_yes); + free(localized_no); + free(msg); + free(fmt); } // if return retval; @@ -166,11 +174,12 @@ MojoGuiYNAN retval = MOJOGUI_NO; if (!feof(stdin)) { - const char *localized_fmt = entry->_("%s\n[y/n/Always/Never]: "); - const char *localized_no = entry->xstrdup(entry->_("N")); - const char *localized_yes = entry->xstrdup(entry->_("Y")); - const char *localized_always = entry->xstrdup(entry->_("Always")); - const char *localized_never = entry->xstrdup(entry->_("Never")); + char *fmt = entry->xstrdup(_("%0\n[y/n/Always/Never]: ")); + char *msg = entry->format(fmt, txt); + char *localized_no = entry->xstrdup(entry->_("N")); + char *localized_yes = entry->xstrdup(entry->_("Y")); + char *localized_always = entry->xstrdup(entry->_("Always")); + char *localized_never = entry->xstrdup(entry->_("Never")); boolean getout = false; char buf[128]; @@ -179,7 +188,7 @@ int rc = 0; getout = true; // we may reset this later. - printf(localized_fmt, txt); + printf("%s\n", msg); fflush(stdout); rc = read_stdin(buf, sizeof (buf)); @@ -199,11 +208,12 @@ getout = false; // try again. } // while - free((void *) localized_never); - free((void *) localized_always); - free((void *) localized_yes); - free((void *) localized_no); - free((void *) localized_fmt); + free(localized_never); + free(localized_always); + free(localized_yes); + free(localized_no); + free(msg); + free(fmt); } // if return retval; @@ -303,9 +313,7 @@ static void dumb_pager(const char *name, const char *data, size_t datalen) { const int MAX_PAGE_LINES = 21; - char buf[256]; - const char *_fmt = entry->_("(%d-%d of %d lines, see more?)"); // !!! FIXME: localization - char *fmt = entry->xstrdup(_fmt); + char *fmt = entry->xstrdup(entry->_("(%0-%1 of %2 lines, see more?)")); int i = 0; int w = 0; int linecount = 0; @@ -330,10 +338,13 @@ getout = true; else { + char *msg = NULL; printf("\n"); - snprintf(buf, sizeof (buf), fmt, - (printed-i)+1, printed, linecount); - getout = !MojoGui_stdio_promptyn("", buf, true); + msg = entry->format(fmt, entry->numstr((printed-i)+1), + entry->numstr(printed), + entry->numstr(linecount)); + getout = !MojoGui_stdio_promptyn("", msg, true); + free(msg); printf("\n"); } // else } while (!getout); @@ -575,8 +586,11 @@ static boolean MojoGui_stdio_insertmedia(const char *medianame) { char buf[32]; - printf(entry->_("Please insert '%s'"), medianame); - printf("\n"); + char *fmt = entry->xstrdup(entry->_("Please insert '%0'")); + char *msg = entry->format(fmt, medianame); + printf("%s\n", msg); + free(msg); + free(fmt); return (readstr(NULL, buf, sizeof (buf), false, true) >= 0); } // MojoGui_stdio_insertmedia @@ -601,12 +615,20 @@ // limit update spam... will only write every one second, tops. if (percentTicks <= now) { + char *fmt = NULL; + char *msg = NULL; percentTicks = now + 1000; // !!! FIXME: localization. if (percent < 0) - printf(entry->_("%s\n"), item); + printf("%s\n", item); else - printf(entry->_("%s (total progress: %d%%)\n"), item, percent); + { + fmt = entry->xstrdup(entry->_("%0 (total progress: %1%%)\n")); + msg = entry->format(fmt, item, entry->numstr(percent)); + printf("%s\n", msg); + free(msg); + free(fmt); + } // else } // if return true; Modified: trunk/gui_www.c =================================================================== --- trunk/gui_www.c 2008-01-12 10:16:04 UTC (rev 399) +++ trunk/gui_www.c 2008-01-12 10:48:34 UTC (rev 400) @@ -52,18 +52,19 @@ int rc = WSAStartup(MAKEWORD(1, 1), &data); if (rc != 0) { - entry->logError("www: WSAStartup() failed: %s", sockStrErrVal(rc)); + entry->logError("www: WSAStartup() failed: %0", sockStrErrVal(rc)); return false; } // if - entry->logInfo("www: WinSock initialized (want %d.%d, got %d.%d).", - (int) (LOBYTE(data.wVersion)), - (int) (HIBYTE(data.wVersion)), - (int) (LOBYTE(data.wHighVersion)), - (int) (HIBYTE(data.wHighVersion))); - entry->logInfo("www: WinSock description: %s", data.szDescription); - entry->logInfo("www: WinSock system status: %s", data.szSystemStatus); - entry->logInfo("www: WinSock max sockets: %s", (int) data.iMaxSockets); + entry->logInfo("www: WinSock initialized (want %0.%1, got %2.%3).", + entry->numstr((int) (LOBYTE(data.wVersion))), + entry->numstr((int) (HIBYTE(data.wVersion))), + entry->numstr((int) (LOBYTE(data.wHighVersion))), + entry->numstr((int) (HIBYTE(data.wHighVersion)))); + entry->logInfo("www: WinSock description: %0", data.szDescription); + entry->logInfo("www: WinSock system status: %0", data.szSystemStatus); + entry->logInfo("www: WinSock max sockets: %0", + entry->numstr((int) data.iMaxSockets)); return true; } // initSocketSupport @@ -158,7 +159,7 @@ req->value = entry->xstrdup(val); req->next = webRequest; webRequest = req; - entry->logDebug("www: request element '%s' = '%s'", key, val); + entry->logDebug("www: request element '%0' = '%1'", key, val); } // if } // addWebRequest @@ -308,7 +309,7 @@ const int err = sockErrno(); if (!intrError(err)) { - entry->logError("www: send() failed: %s", sockStrErrVal(err)); + entry->logError("www: send() failed: %0", sockStrErrVal(err)); break; } // if } // else @@ -456,7 +457,7 @@ assert(!blocking); else { - entry->logError("www: accept() failed: %s", sockStrErrVal(err)); + entry->logError("www: accept() failed: %0", sockStrErrVal(err)); closesocket(listenSocket); // make all future i/o fail too. listenSocket = INVALID_SOCKET; } // else @@ -474,7 +475,7 @@ const int err = sockErrno(); if (!intrError(err)) // just try again on interrupt. { - entry->logError("www: recv() failed: %s", sockStrErrVal(err)); + entry->logError("www: recv() failed: %0", sockStrErrVal(err)); FREE_AND_NULL(reqstr); closesocket(s); s = INVALID_SOCKET; @@ -519,7 +520,7 @@ memmove(reqstr, ptr, len+1); } // else - entry->logDebug("www: request '%s'", get); + entry->logDebug("www: request '%0'", get); // okay, now (get) and (reqptr) are separate strings. // These parse*() functions update (webRequest). @@ -554,7 +555,7 @@ s = socket(PF_INET, SOCK_STREAM, protocol); if (s == INVALID_SOCKET) - entry->logInfo("www: socket() failed ('%s')", sockStrError()); + entry->logInfo("www: socket() failed ('%0')", sockStrError()); else { boolean success = false; @@ -572,12 +573,13 @@ #endif if (bind(s, (struct sockaddr *) &addr, sizeof (addr)) == SOCKET_ERROR) - entry->logError("www: bind() failed ('%s')", sockStrError()); + entry->logError("www: bind() failed ('%0')", sockStrError()); else if (listen(s, 5) == SOCKET_ERROR) - entry->logError("www: listen() failed ('%s')", sockStrError()); + entry->logError("www: listen() failed ('%0')", sockStrError()); else { - entry->logInfo("www: socket created on port %d", (int) portnum); + entry->logInfo("www: socket created on port %0", + entry->numstr(portnum)); success = true; } // else @@ -987,10 +989,12 @@ htmlescape(entry->_("OK")), }; - // !!! FIXME: better text. char *title = entry->xstrdup(entry->_("Media change")); - // !!! FIXME: better text. - strAdd(&text, &len, &alloc, entry->_("Please insert '%s'"), medianame); + char *fmt = entry->xstrdup(entry->_("Please insert '%0'")); + char *msg = entry->format(fmt, medianame); + strAdd(&text, &len, &alloc, msg); + free(msg); + free(fmt); htmltext = htmlescape(text); free(text); Modified: trunk/lua_glue.c =================================================================== --- trunk/lua_glue.c 2008-01-12 10:16:04 UTC (rev 399) +++ trunk/lua_glue.c 2008-01-12 10:48:34 UTC (rev 400) @@ -215,7 +215,7 @@ int i = 0; if (errstr != NULL) - logDebug("%s\n", errstr); + logDebug("%0", errstr); logDebug("Lua stack backtrace:"); @@ -233,7 +233,7 @@ if (!lua_getinfo(L, "nSl", &ldbg)) { snprintfcat(&ptr, &len, "???\n"); - logDebug((const char *) scratchbuf_128k); + logDebug("%0", (const char *) scratchbuf_128k); continue; } // if @@ -252,7 +252,7 @@ snprintfcat(&ptr, &len, "unidentifiable function"); } // if - logDebug((const char *) scratchbuf_128k); + logDebug("%0", (const char *) scratchbuf_128k); ptr = (char *) scratchbuf_128k; len = sizeof (scratchbuf_128k); @@ -271,7 +271,7 @@ if (ldbg.currentline != -1) snprintfcat(&ptr, &len, ":%d", ldbg.currentline); } // else - logDebug((const char *) scratchbuf_128k); + logDebug("%0", (const char *) scratchbuf_128k); } // for return retvalString(L, errstr ? errstr : ""); @@ -446,12 +446,13 @@ int post = 0; pre = (lua_gc(L, LUA_GCCOUNT, 0) * 1024) + lua_gc(L, LUA_GCCOUNTB, 0); - logDebug("Collecting garbage (currently using %d bytes).", pre); + logDebug("Collecting garbage (currently using %0 bytes).", numstr(pre)); ticks = MojoPlatform_ticks(); lua_gc (L, LUA_GCCOLLECT, 0); profile("Garbage collection", ticks); post = (lua_gc(L, LUA_GCCOUNT, 0) * 1024) + lua_gc(L, LUA_GCCOUNTB, 0); - logDebug("Now using %d bytes (%d bytes savings).\n", post, pre - post); + logDebug("Now using %0 bytes (%1 bytes savings).", + numstr(post), numstr(pre - post)); } // MojoLua_collectGarbage @@ -499,6 +500,37 @@ } // translate +// Lua interface to format(). +static int luahook_format(lua_State *L) +{ + const int argc = lua_gettop(L); + const char *fmt = luaL_checkstring(L, 1); + char *formatted = NULL; + char *s[10]; + int i; + + assert(argc <= 11); // fmt, plus %0 through %9. + + for (i = 0; i < STATICARRAYLEN(s); i++) + { + const char *str = NULL; + if ((i+2) <= argc) + str = lua_tostring(L, i+2); + s[i] = (str == NULL) ? NULL : xstrdup(str); + } // for + + // I think this is legal (but probably not moral) C code. + formatted = format(fmt,s[0],s[1],s[2],s[3],s[4],s[5],s[6],s[7],s[8],s[9]); + + for (i = 0; i < STATICARRAYLEN(s); i++) + free(s[i]); + + lua_pushstring(L, formatted); + free(formatted); + return 1; +} // luahook_format + + // Use this instead of Lua's error() function if you don't have a // programatic error, so you don't get stack callback stuff: // MojoSetup.fatal("You need the base game to install this expansion pack.") @@ -507,7 +539,9 @@ static int luahook_fatal(lua_State *L) { const char *errstr = lua_tostring(L, 1); - return fatal(errstr); // doesn't actually return. + if (errstr == NULL) + return fatal(NULL); // doesn't actually return. + return fatal("%0", errstr); // doesn't actually return. } // luahook_fatal @@ -589,28 +623,28 @@ static int luahook_logwarning(lua_State *L) { - logWarning(luaL_checkstring(L, 1)); + logWarning("%0", luaL_checkstring(L, 1)); return 0; } // luahook_logwarning static int luahook_logerror(lua_State *L) { - logError(luaL_checkstring(L, 1)); + logError("%0", luaL_checkstring(L, 1)); return 0; } // luahook_logerror static int luahook_loginfo(lua_State *L) { - logInfo(luaL_checkstring(L, 1)); + logInfo("%0", luaL_checkstring(L, 1)); return 0; } // luahook_loginfo static int luahook_logdebug(lua_State *L) { - logDebug(luaL_checkstring(L, 1)); + logDebug("%0", luaL_checkstring(L, 1)); return 0; } // luahook_logdebug @@ -729,7 +763,7 @@ const char *permstr = luaL_checkstring(L, 3); perms = MojoPlatform_makePermissions(permstr, &valid); if (!valid) - fatal(_("BUG: '%s' is not a valid permission string"), permstr); + fatal(_("BUG: '%0' is not a valid permission string"), permstr); } // if rc = MojoInput_toPhysicalFile(in, path, perms, &sums, writeCallback, L); @@ -912,7 +946,7 @@ const char *permstr = luaL_checkstring(L, 2); perms = MojoPlatform_makePermissions(permstr, &valid); if (!valid) - fatal(_("BUG: '%s' is not a valid permission string"), permstr); + fatal(_("BUG: '%0' is not a valid permission string"), permstr); } // if return retvalBoolean(L, MojoPlatform_mkdir(dir, perms)); } // luahook_platform_mkdir @@ -1041,7 +1075,7 @@ const boolean can_go_fwd = canGoForward(thisstage, maxstage); if (data == NULL) - fatal(_("failed to load file '%s'"), fname); + fatal(_("failed to load file '%0'"), fname); lua_pushnumber(L, GGui->readme(name, data, len, can_go_back, can_go_fwd)); free((void *) data); @@ -1088,7 +1122,7 @@ if (required) { lua_getfield(L, -2, "description"); - logWarning("Option '%s' is both required and disabled!", + logWarning("Option '%0' is both required and disabled!", lua_tostring(L, -1)); lua_pop(L, 1); } // if @@ -1166,7 +1200,7 @@ // !!! FIXME: schema should check? if ((is_group) && (opts->is_group_parent)) { - fatal("OptionGroup '%s' inside OptionGroup '%s'.", + fatal("OptionGroup '%0' inside OptionGroup '%1'.", opts->description, parent->description); } // if @@ -1174,7 +1208,7 @@ { if (seen_enabled) { - logWarning("Options '%s' and '%s' are both enabled in group '%s'.", + logWarning("Options '%0' and '%1' are both enabled in group '%2'.", seen_enabled->description, opts->description, parent->description); seen_enabled->value = false; @@ -1191,7 +1225,7 @@ if ((prev) && (is_group) && (!seen_enabled)) { - logWarning("Option group '%s' has no enabled items, choosing first ('%s').", + logWarning("Option group '%0' has no enabled items, choosing first ('%1').", parent->description, prev->description); prev->value = true; } // if @@ -1460,6 +1494,7 @@ set_cfunc(luaState, luahook_runfile, "runfile"); set_cfunc(luaState, luahook_translate, "translate"); set_cfunc(luaState, luahook_ticks, "ticks"); + set_cfunc(luaState, luahook_format, "format"); set_cfunc(luaState, luahook_fatal, "fatal"); set_cfunc(luaState, luahook_msgbox, "msgbox"); set_cfunc(luaState, luahook_promptyn, "promptyn"); Modified: trunk/mojosetup.c =================================================================== --- trunk/mojosetup.c 2008-01-12 10:16:04 UTC (rev 399) +++ trunk/mojosetup.c 2008-01-12 10:48:34 UTC (rev 400) @@ -33,6 +33,8 @@ logError, logInfo, logDebug, + format, + numstr, MojoPlatform_ticks, }; @@ -74,7 +76,7 @@ io->close(io); if (br == imglen) { - logInfo("Switching binary with '%s'...", ar->prevEnum.filename); + logInfo("Switching binary with '%0'...", ar->prevEnum.filename); MojoPlatform_switchBin(img, imglen); // no return on success. logError("...Switch binary failed."); } // if @@ -329,6 +331,104 @@ } // wildcardMatch +const char *numstr(int val) +{ + static int pos = 0; + char *ptr = ((char *) scratchbuf_128k) + (pos * 128); + snprintf(ptr, 128, "%d", val); + pos = (pos + 1) % 1000; + return ptr; +} // numstr + + +static char *format_internal(const char *fmt, va_list ap) +{ + // This is kinda nasty. String manipulation in C always is. + char *retval = NULL; + const char *strs[10]; // 0 through 9. + const char *ptr = NULL; + char *wptr = NULL; + size_t len = 0; + int maxfmtid = -2; + int i; + + // figure out what this format string contains... + for (ptr = fmt; *ptr; ptr++) + { + if (*ptr == '%') + { + const char ch = *(++ptr); + if (ch == '%') // a literal '%' + maxfmtid = (maxfmtid == -2) ? -1 : maxfmtid; + else if ((ch >= '0') && (ch <= '9')) + maxfmtid = ((maxfmtid > (ch - '0')) ? maxfmtid : (ch - '0')); + else + fatal(_("BUG: Invalid format() string")); + } // if + } // while + + if (maxfmtid == -2) // no formatters present at all. + return xstrdup(fmt); // just copy it, we're done. + + for (i = 0; i <= maxfmtid; i++) // referenced varargs --> linear array. + { + strs[i] = va_arg(ap, const char *); + if (strs[i] == NULL) + strs[i] = "(null)"; // just to match sprintf() behaviour... + } // for + + // allocate the string we'll need in one shot, so we don't have to resize. + for (ptr = fmt; *ptr; ptr++) + { + if (*ptr != '%') + len++; + else + { + const char ch = *(++ptr); + if (ch == '%') // a literal '%' + len++; // just want '%' char. + else //if ((ch >= '0') && (ch <= '9')) + len += strlen(strs[ch - '0']); + } // else + } // while + + // Now write the formatted string... + wptr = retval = (char *) xmalloc(len+1); + for (ptr = fmt; *ptr; ptr++) + { + const char strch = *ptr; + if (strch != '%') + *(wptr++) = strch; + else + { + const char ch = *(++ptr); + if (ch == '%') // a literal '%' + *(wptr++) = '%'; + else //if ((ch >= '0') && (ch <= '9')) + { + const char *str = strs[ch - '0']; + strcpy(wptr, str); + wptr += strlen(str); + } // else + } // else + } // while + *wptr = '\0'; + + return retval; +} // format_internal + + +char *format(const char *fmt, ...) +{ + char *retval = NULL; + va_list ap; + va_start(ap, fmt); + retval = format_internal(fmt, ap); + va_end(ap); + return retval; +} // format + + #if ((defined _NDEBUG) || (defined NDEBUG)) #define DEFLOGLEV "info" #else @@ -380,21 +480,22 @@ { if (level <= MojoLog_logLevel) { - char buf[1024]; + char *str = format_internal(fmt, ap); //int len = vsnprintf(buf + 2, sizeof (buf) - 2, fmt, ap) + 2; //buf[0] = levelchar; //buf[1] = ' '; - int len = vsnprintf(buf, sizeof (buf), fmt, ap); - while ( (--len >= 0) && ((buf[len] == '\n') || (buf[len] == '\r')) ) {} - buf[len+1] = '\0'; // delete trailing newline crap. - MojoPlatform_log(buf); + int len = strlen(str); + while ( (--len >= 0) && ((str[len] == '\n') || (str[len] == '\r')) ) {} + str[len+1] = '\0'; // delete trailing newline crap. + MojoPlatform_log(str); if (logFile != NULL) { const char *endl = MOJOPLATFORM_ENDLINE; - MojoPlatform_write(logFile, buf, strlen(buf)); + MojoPlatform_write(logFile, str, strlen(str)); MojoPlatform_write(logFile, endl, strlen(endl)); MojoPlatform_flush(logFile); } // if + free(str); } // if } // addLog @@ -439,9 +540,7 @@ { uint32 retval = MojoPlatform_ticks() - start_time; if (what != NULL) - { - logDebug("%s took %lu ms.", what, (unsigned long) retval); - } // if + logDebug("%0 took %1 ms.", what, numstr((int) retval)); return retval; } // profile_start @@ -458,24 +557,13 @@ // may not want to show a message, since we displayed one elsewhere, etc. if (fmt != NULL) { + char *buf = NULL; va_list ap; - int rc = 0; - int len = 128; - char *buf = xmalloc(len); - va_start(ap, fmt); - rc = vsnprintf(buf, len, fmt, ap); + buf = format_internal(fmt, ap); va_end(ap); - if (rc >= len) - { - len = rc; - buf = xrealloc(buf, len); - va_start(ap, fmt); - vsnprintf(buf, len, fmt, ap); - va_end(ap); - } // if - logError("FATAL: %s", buf); + logError("FATAL: %0", buf); if (GGui != NULL) GGui->msgbox(_("Fatal error"), buf); @@ -502,7 +590,7 @@ panic_runs++; if (panic_runs == 1) { - logError("PANIC: %s", err); + logError("PANIC: %0", err); panic(err); } // if @@ -583,7 +671,7 @@ #if MOJOSETUP_INTERNAL_BZLIB && BZ_NO_STDIO void bz_internal_error(int errcode) { - fatal(_("bzlib triggered an internal error: %d"), errcode); + fatal(_("bzlib triggered an internal error: %0"), numstr(numbuf)); } // bz_internal_error #endif Modified: trunk/platform_unix.c =================================================================== --- trunk/platform_unix.c 2008-01-12 10:16:04 UTC (rev 399) +++ trunk/platform_unix.c 2008-01-12 10:48:34 UTC (rev 400) @@ -1031,7 +1031,7 @@ if (first_shot) { first_shot = false; - logError("Caught signal #%d", sig); + logError("Caught signal #%0", numstr(sig)); } // if } // signal_catcher Modified: trunk/scripts/localization.lua =================================================================== --- trunk/scripts/localization.lua 2008-01-12 10:16:04 UTC (rev 399) +++ trunk/scripts/localization.lua 2008-01-12 10:48:34 UTC (rev 400) @@ -17,6 +17,17 @@ -- You should leave the existing strings here. They aren't hurting anything, -- and most are used by MojoSetup itself. Add your own, though. -- +-- Whenever you see a %x sequence, that is replaced with a string at runtime. +-- So if you see, ["Hello, %0, my name is %1."], then this might become +-- "Hello, Alice, my name is Bob." at runtime. If your culture would find +-- introducing yourself second to be rude, you might translate this to: +-- "My name is %1, hello %0." If you need a literal '%' char, write "%%": +-- "Operation is %0%% complete" might give "Operation is 3% complete." +-- All strings, from your locale or otherwise, are checked for formatter +-- correctness at startup. This is to prevent the installer working fine +-- in all reasonable tests, then finding out that one guy in Ghana has a +-- crashing installer because his localization forgot to add a %1 somewhere. +-- -- The table you create here goes away shortly after creation, as the relevant -- parts of it get moved somewhere else. You should call MojoSetup.translate() -- to get the proper translation for a given string. @@ -42,19 +53,19 @@ }; -- stdio GUI plugin says this for msgboxes (printf format string). - ["NOTICE: %s\n[hit enter]"] = { + ["NOTICE: %1\n[hit enter]"] = { }; -- stdio GUI plugin says this for yes/no prompts that default to yes (printf format string). - ["%s\n[Y/n]: "] = { + ["%1\n[Y/n]: "] = { }; -- stdio GUI plugin says this for yes/no prompts that default to no (printf format string). - ["%s\n[y/N]: "] = { + ["%1\n[y/N]: "] = { }; -- stdio GUI plugin says this for yes/no/always/never prompts (printf format string). - ["%s\n[y/n/Always/Never]: "] = { + ["%1\n[y/n/Always/Never]: "] = { }; -- This is utf8casecmp()'d for "yes" answers in stdio GUI's promptyn(). @@ -66,7 +77,7 @@ }; -- This is shown when using stdio GUI's built-in README pager (printf format). - ["(Viewing %d-%d of %d lines, see more?)"] = { + ["(Viewing %1-%2 of %3 lines, see more?)"] = { }; -- This is utf8casecmp()'d for "always" answers in stdio GUI's promptyn(). @@ -95,10 +106,10 @@ ["Choose number to change."] = { }; - ["Type '%s' to go back."] = { + ["Type '%1' to go back."] = { }; - -- This is the string used for the '%s' in the above string. + -- This is the string used for the '%1' in the above string. ["back"] = { }; @@ -142,10 +153,10 @@ ["You must accept the license before you may install"] = { }; - ["failed to load file '%s'"] = { + ["failed to load file '%1'"] = { }; - ["Please insert '%s'"] = { + ["Please insert '%1'"] = { }; ["(I want to specify a path.)"] = { @@ -161,6 +172,9 @@ ["Setup program is shutting down. You can close this browser now."] = { }; + + ["No networking support in this build."] = { + }; }; -- end of localization.lua ... Modified: trunk/universal.h =================================================================== --- trunk/universal.h 2008-01-12 10:16:04 UTC (rev 399) +++ trunk/universal.h 2008-01-12 10:48:34 UTC (rev 400) @@ -96,6 +96,23 @@ // Static, non-stack memory for scratch work...not thread safe! extern uint8 scratchbuf_128k[128 * 1024]; +// Format a string, sort of (but not exactly!) like sprintf(). +// The only formatters accepted are %0 through %9 (and %%), which do not +// have to appear in order in the string, but match the varargs passed to the +// function. Only strings are accepted for varargs. This function allocates +// memory as necessary, so you need to free() the result, but don't need to +// preallocate a buffer and be concerned about overflowing it. +// This does not use scratchbuf_128k. +char *format(const char *fmt, ...); + +// Convert an int to a string. This uses incremental pieces of +// scratchbuf_128k for a buffer to store the results, and +// will overwrite itself after some number of calls when the memory +// is all used, but note that other things use scratchbuf_128k too, +// so this is only good for printf() things: +// fmtfunc("mission took %0 seconds, %1 points", numstr(secs), numstr(pts)); +const char *numstr(int val); + // Call this for fatal errors that require immediate app termination. // Does not clean up, or translate the error string. Try to avoid this. // These are for crucial lowlevel issues that preclude any meaningful @@ -112,7 +129,9 @@ // If there's no GUI or Lua isn't initialized, this calls panic(). That's bad. // Doesn't return, but if it did, you can assume it returns zero, so you can // do: 'return fatal("missing config file");' or whatnot. -int fatal(const char *fmt, ...) ISPRINTF(1,2); +// THIS DOES NOT USE PRINTF-STYLE FORMAT CODES. Please see the comments for +// format() for details. +int fatal(const char *fmt, ...); // The platform layer should set up signal/exception handlers before calling // MojoSetup_main(), that will call these functions. "crashed" for bug @@ -121,9 +140,6 @@ void MojoSetup_crashed(void); void MojoSetup_terminated(void); -// Call this to pop up a warning dialog box and block until user hits OK. -void warn(const char *fmt, ...) ISPRINTF(1,2); - // Malloc replacements that blow up on allocation failure. // Please note that xmalloc() will zero the newly-allocated memory buffer, // like calloc() would, but xrealloc() makes no such promise! @@ -253,12 +269,16 @@ extern MojoSetupLogLevel MojoLog_logLevel; void MojoLog_initLogging(void); void MojoLog_deinitLogging(void); -void logWarning(const char *fmt, ...) ISPRINTF(1,2); -void logError(const char *fmt, ...) ISPRINTF(1,2); -void logInfo(const char *fmt, ...) ISPRINTF(1,2); -void logDebug(const char *fmt, ...) ISPRINTF(1,2); +// Logging facilities. +// THESE DO NOT USE PRINTF-STYLE FORMAT CODES. Please see the comments for +// format() for details. +void logWarning(const char *fmt, ...); +void logError(const char *fmt, ...); +void logInfo(const char *fmt, ...); +void logDebug(const char *fmt, ...); + // Checksums. typedef uint32 MojoCrc32; @@ -320,10 +340,12 @@ char *(*xstrdup)(const char *str); char *(*xstrncpy)(char *dst, const char *src, size_t len); const char *(*translate)(const char *str); - void (*logWarning)(const char *fmt, ...) ISPRINTF(1,2); - void (*logError)(const char *fmt, ...) ISPRINTF(1,2); - void (*logInfo)(const char *fmt, ...) ISPRINTF(1,2); - void (*logDebug)(const char *fmt, ...) ISPRINTF(1,2); + void (*logWarning)(const char *fmt, ...); + void (*logError)(const char *fmt, ...); + void (*logInfo)(const char *fmt, ...); + void (*logDebug)(const char *fmt, ...); + char *(*format)(const char *fmt, ...); + const char *(*numstr)(int val); uint32 (*ticks)(void); } MojoSetupEntryPoints; extern MojoSetupEntryPoints GEntryPoints; @@ -339,6 +361,9 @@ #endif #endif // DOXYGEN_SHOULD_IGNORE_THIS +#define DEFINE_TO_STR2(x) #x +#define DEFINE_TO_STR(x) DEFINE_TO_STR2(x) + #ifndef DOXYGEN_SHOULD_IGNORE_THIS #define STUBBED(x) \ do { \ @@ -346,17 +371,14 @@ if (!seen_this) \ { \ seen_this = true; \ - logDebug("STUBBED: %s at %s (%s:%d)\n", x, __FUNCTION__, \ - __FILE__, __LINE__); \ + logDebug("STUBBED: %0 at %1 (%2:%3)\n", x, __FUNCTION__, \ + __FILE__, DEFINE_TO_STR(__LINE__)); \ } \ } while (false) #endif #define STATICARRAYLEN(x) ( (sizeof ((x))) / (sizeof ((x)[0])) ) -#define DEFINE_TO_STR2(x) #x -#define DEFINE_TO_STR(x) DEFINE_TO_STR2(x) - #ifdef __cplusplus } #endif From DONOTREPLY at icculus.org Sat Jan 12 06:21:28 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 12 Jan 2008 06:21:28 -0500 Subject: r401 - trunk/scripts Message-ID: <20080112112128.30573.qmail@icculus.org> Author: icculus Date: 2008-01-12 06:21:28 -0500 (Sat, 12 Jan 2008) New Revision: 401 Modified: trunk/scripts/localization.lua Log: Updated localization table. Modified: trunk/scripts/localization.lua =================================================================== --- trunk/scripts/localization.lua 2008-01-12 10:48:34 UTC (rev 400) +++ trunk/scripts/localization.lua 2008-01-12 11:21:28 UTC (rev 401) @@ -33,39 +33,44 @@ -- to get the proper translation for a given string. MojoSetup.localization = { - -- zlib errors + -- zlib error message ["need dictionary"] = { }; + -- zlib error message ["data error"] = { }; + -- zlib error message ["memory error"] = { }; + -- zlib error message ["buffer error"] = { }; + -- zlib error message ["version error"] = { }; + -- zlib error message ["unknown error"] = { }; - -- stdio GUI plugin says this for msgboxes (printf format string). - ["NOTICE: %1\n[hit enter]"] = { + -- stdio GUI plugin says this for msgboxes. + ["NOTICE: %0\n[hit enter]"] = { }; - -- stdio GUI plugin says this for yes/no prompts that default to yes (printf format string). - ["%1\n[Y/n]: "] = { + -- stdio GUI plugin says this for yes/no prompts that default to yes. + ["%0\n[Y/n]: "] = { }; - -- stdio GUI plugin says this for yes/no prompts that default to no (printf format string). - ["%1\n[y/N]: "] = { + -- stdio GUI plugin says this for yes/no prompts that default to no. + ["%0\n[y/N]: "] = { }; - -- stdio GUI plugin says this for yes/no/always/never prompts (printf format string). - ["%1\n[y/n/Always/Never]: "] = { + -- stdio GUI plugin says this for yes/no/always/never prompts. + ["%0\n[y/n/Always/Never]: "] = { }; -- This is utf8casecmp()'d for "yes" answers in stdio GUI's promptyn(). @@ -77,7 +82,7 @@ }; -- This is shown when using stdio GUI's built-in README pager (printf format). - ["(Viewing %1-%2 of %3 lines, see more?)"] = { + ["(%0-%1 of %2 lines, see more?)"] = { }; -- This is utf8casecmp()'d for "always" answers in stdio GUI's promptyn(). @@ -88,93 +93,237 @@ ["Never"] = { }; - ["Yes"] = { + ["Type '%0' to go back."] = { }; - ["No"] = { + -- This is the string used for the '%0' in the above string. + ["back"] = { }; - ["OK"] = { + -- This is the prompt in the stdio driver when user input is expected. + ["> "] = { }; + ["NOTICE: %0\n[hit enter]"] = { + }; + + ["%0 (total progress: %1%%)\n"] = { + }; + + ["Accept this license?"] = { + }; + + -- This is a GTK+ button label. The '_' comes after the hotkey character. + ["_Always"] = { + }; + + ["Archive not found."] = { + }; + + ["Are you sure you want to cancel installation?"] = { + }; + + ["Back"] = { + }; + + -- This is a GTK+ button label. The '_' comes after the hotkey character. + ["B_rowse..."] = { + }; + + -- "bytes per second" + ["B/s"] = { + }; + + ["BUG: '%0' is not a valid permission string"] = { + }; + + ["BUG: Invalid format() string"] = { + }; + + ["BUG: stage returned wrong type."] = { + }; + + ["BUG: stage returned wrong value."] = { + }; + + ["BUG: stepped back over start of stages"] = { + }; + + ["bzlib triggered an internal error: %0"] = { + }; + ["Cancel"] = { }; - ["Press enter to continue."] = { + ["Cancel installation"] = { }; + ["cannot open archive."] = { + }; + + ["Can't enumerate archive"] = { + }; + + ["Choose install destination by number (hit enter for #1), or enter your own."] = { + }; + ["Choose number to change."] = { }; - ["Type '%1' to go back."] = { + ["Config bug: duplicate media id"] = { }; - -- This is the string used for the '%1' in the above string. - ["back"] = { + ["Config bug: no options"] = { }; - -- This is the prompt in the stdio driver when user input is expected. - ["> "] = { + -- As in "two different files want to use the same name" + ["Conflict!"] = { }; - ["Options"] = { + ["Couldn't backup file for rollback"] = { }; + ["Couldn't create manifest"] = { + }; + + ["Couldn't enumerate archive."] = { + }; + + ["Couldn't open archive."] = { + }; + + ["Couldn't restore some files. Your existing installation is likely damaged."] = { + }; + + ["Deletion failed!"] = { + }; + ["Destination"] = { }; - ["Choose install destination by number (hit enter for #1), or enter your own."] = { + ["Downloading"] = { }; ["Enter path where files will be installed."] = { }; - ["Nothing to do!"] = { + ["failed to load file '%0'"] = { }; - ["Unknown error"] = { + ["Fatal error"] = { }; - ["Internal error"] = { + ["File creation failed!"] = { }; - ["PANIC"] = { + ["file download failed!"] = { }; - ["Fatal error"] = { + ["Finish"] = { }; ["GUI failed to start"] = { }; - ["Accept this license?"] = { + ["Incomplete installation. We will revert any changes we made."] = { }; - ["You must accept the license before you may install"] = { + ["Installation location"] = { }; - ["failed to load file '%1'"] = { + ["Installation was successful."] = { }; - ["Please insert '%1'"] = { + ["Installing"] = { }; + ["Install options:"] = { + }; + ["(I want to specify a path.)"] = { }; - -- as in "404 Not Found" in a web browser. + -- "kilobytes per second" + ["KB/s"] = { + }; + + ["Media change"] = { + }; + + ["mkdir failed"] = { + }; + + ["need dictionary"] = { + }; + + -- This is a GTK+ button label. The '_' comes after the hotkey character. + ["N_ever"] = { + }; + + ["Never"] = { + }; + + ["Next"] = { + }; + + ["No"] = { + }; + + ["No networking support in this build."] = { + }; + ["Not Found"] = { }; - -- title bar in browser page, used with next item for page's text. + ["Nothing to do!"] = { + }; + + ["OK"] = { + }; + + ["Options"] = { + }; + + ["PANIC"] = { + }; + + ["Please insert '%0'"] = { + }; + + ["Press enter to continue."] = { + }; + + ["Serious problem"] = { + }; + ["Shutting down..."] = { }; - ["Setup program is shutting down. You can close this browser now."] = { + -- printed instead of kilobytes per second when download isn't progressing. + ["(stalled)"] = { }; - ["No networking support in this build."] = { + ["symlink creation failed!"] = { }; + + ["The installer has been stopped by the system."] = { + }; + + ["The installer has crashed due to a bug."] = { + }; + + -- This is a button label in the ncurses ui. + ["Toggle"] = { + }; + + ["Unknown file type in archive"] = { + }; + + ["Yes"] = { + }; + + ["You must accept the license before you may install"] = { + }; }; -- end of localization.lua ... From DONOTREPLY at icculus.org Sat Jan 12 06:22:50 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 12 Jan 2008 06:22:50 -0500 Subject: r402 - trunk/scripts Message-ID: <20080112112250.32229.qmail@icculus.org> Author: icculus Date: 2008-01-12 06:22:50 -0500 (Sat, 12 Jan 2008) New Revision: 402 Modified: trunk/scripts/loki_setup_compat.lua trunk/scripts/mojosetup_init.lua trunk/scripts/mojosetup_mainline.lua Log: Removed some errant semicolons from the Lua scripts... Modified: trunk/scripts/loki_setup_compat.lua =================================================================== --- trunk/scripts/loki_setup_compat.lua 2008-01-12 11:21:28 UTC (rev 401) +++ trunk/scripts/loki_setup_compat.lua 2008-01-12 11:22:50 UTC (rev 402) @@ -47,7 +47,7 @@ f:write('\n') f:write('\n'); + .. MojoSetup.destination .. '" ' .. update_url .. '>\n') f:write(' \n') Modified: trunk/scripts/mojosetup_init.lua =================================================================== --- trunk/scripts/mojosetup_init.lua 2008-01-12 11:21:28 UTC (rev 401) +++ trunk/scripts/mojosetup_init.lua 2008-01-12 11:22:50 UTC (rev 402) @@ -29,7 +29,7 @@ MojoSetup.loginfo("ui: " .. MojoSetup.info.ui) MojoSetup.loginfo("loglevel: " .. MojoSetup.info.loglevel) -MojoSetup.loginfo("command line:"); +MojoSetup.loginfo("command line:") for i,v in ipairs(MojoSetup.info.argv) do MojoSetup.loginfo(" " .. i .. ": " .. v) end @@ -96,7 +96,7 @@ end if MojoSetup.localization ~= nil then - local at_least_one = false; + local at_least_one = false local locale = MojoSetup.info.locale local lang = string.gsub(locale, "_%w+", "", 1) -- make "en_US" into "en" MojoSetup.translations = {} @@ -146,15 +146,15 @@ end local function mustBeString(fnname, elem, val) - mustBeSomething(fnname, elem, val, "string"); + mustBeSomething(fnname, elem, val, "string") end local function mustBeBool(fnname, elem, val) - mustBeSomething(fnname, elem, val, "boolean"); + mustBeSomething(fnname, elem, val, "boolean") end local function mustBeNumber(fnname, elem, val) - mustBeSomething(fnname, elem, val, "number"); + mustBeSomething(fnname, elem, val, "number") end local function mustBeFunction(fnname, elem, val) @@ -218,7 +218,7 @@ local function sanitize(fnname, tab, elems) mustBeTable(fnname, "", tab) - tab._type_ = string.lower(fnname) .. "s"; -- "Eula" becomes "eulas". + tab._type_ = string.lower(fnname) .. "s" -- "Eula" becomes "eulas". for i,elem in ipairs(elems) do local child = elem[1] local defval = elem[2] @@ -228,7 +228,7 @@ end local j = 3 while elem[j] do - elem[j](fnname, child, tab[child]); -- will assert on problem. + elem[j](fnname, child, tab[child]) -- will assert on problem. j = j + 1 end end @@ -270,7 +270,7 @@ table.insert(tab[typestr], v) end -- can't just set tab[k] to nil here, since it screws up pairs()... - killlist[#killlist+1] = k; + killlist[#killlist+1] = k elseif vtype == "table" then tab[k] = reform_schema_table(v) end Modified: trunk/scripts/mojosetup_mainline.lua =================================================================== --- trunk/scripts/mojosetup_mainline.lua 2008-01-12 11:21:28 UTC (rev 401) +++ trunk/scripts/mojosetup_mainline.lua 2008-01-12 11:22:50 UTC (rev 402) @@ -92,16 +92,16 @@ function MojoSetup.revertinstall() -- !!! FIXME: language. if MojoSetup.gui_started then - MojoSetup.gui.final(_("Incomplete installation. We will revert any changes we made.")); + MojoSetup.gui.final(_("Incomplete installation. We will revert any changes we made.")) end - MojoSetup.loginfo("Cleaning up half-finished installation..."); + MojoSetup.loginfo("Cleaning up half-finished installation...") -- !!! FIXME: callbacks here. delete_files(MojoSetup.downloads) delete_files(MojoSetup.installed_files) do_rollbacks() - delete_scratchdirs(); + delete_scratchdirs() end @@ -138,7 +138,7 @@ minsleft = string.sub("00" .. (minsleft - (hoursleft * 60)), -2) if hoursleft < 10 then - hoursleft = "0" .. hoursleft; + hoursleft = "0" .. hoursleft else hoursleft = tostring(hoursleft) end @@ -547,7 +547,7 @@ path = path .. "/" .. v if not MojoSetup.platform.exists(path) then if knowngood == "" then -- !!! FIXME: error message. - MojoSetup.fatal(_("archive not found")) + MojoSetup.fatal(_("Archive not found")) end local archive = create_basepath_archive(knowngood) local arclist = { archive } From DONOTREPLY at icculus.org Sat Jan 12 07:46:51 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 12 Jan 2008 07:46:51 -0500 Subject: r403 - trunk/scripts Message-ID: <20080112124651.21716.qmail@icculus.org> Author: icculus Date: 2008-01-12 07:46:51 -0500 (Sat, 12 Jan 2008) New Revision: 403 Modified: trunk/scripts/localization.lua Log: Whoops, dupe entry. Modified: trunk/scripts/localization.lua =================================================================== --- trunk/scripts/localization.lua 2008-01-12 11:22:50 UTC (rev 402) +++ trunk/scripts/localization.lua 2008-01-12 12:46:51 UTC (rev 403) @@ -260,9 +260,6 @@ ["N_ever"] = { }; - ["Never"] = { - }; - ["Next"] = { }; From DONOTREPLY at icculus.org Sat Jan 12 07:47:19 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 12 Jan 2008 07:47:19 -0500 Subject: r404 - trunk/scripts Message-ID: <20080112124719.23375.qmail@icculus.org> Author: icculus Date: 2008-01-12 07:47:19 -0500 (Sat, 12 Jan 2008) New Revision: 404 Modified: trunk/scripts/mojosetup_init.lua Log: Make sure all translation formatting strings are sane at startup. Modified: trunk/scripts/mojosetup_init.lua =================================================================== --- trunk/scripts/mojosetup_init.lua 2008-01-12 12:46:51 UTC (rev 403) +++ trunk/scripts/mojosetup_init.lua 2008-01-12 12:47:19 UTC (rev 404) @@ -89,6 +89,39 @@ -- This table gets filled by the config file. Just create an empty one for now. MojoSetup.installs = {} + +local function sanity_check_localization_entry(str, translations) + local maxval = -1; + + for val in string.gmatch(str, "%%.") do + val = string.sub(val, 2) + if string.match(val, "^[^%%0-9]$") ~= nil then + MojoSetup.fatal("BUG: localization key ['" .. str .. "'] has invalid escape sequence.") + end + if val ~= "%" then + local num = tonumber(val) + if num > maxval then + maxval = num + end + end + end + + for k,v in pairs(translations) do + for val in string.gmatch(v, "%%.") do + val = string.sub(val, 2) + if string.match(val, "^[^%%0-9]$") ~= nil then + MojoSetup.fatal("BUG: '" .. k .. "' localization ['" .. v .. "'] has invalid escape sequence.") + end + if val ~= "%" then + if tonumber(val) > maxval then + MojoSetup.fatal("BUG: '" .. k .. "' localization ['" .. v .. "'] has escape sequence > max for translation.") + end + end + end + end +end + + -- Build the translations table from the localizations table supplied in -- localizations.lua... if type(MojoSetup.localization) ~= "table" then @@ -102,6 +135,7 @@ MojoSetup.translations = {} for k,v in pairs(MojoSetup.localization) do if type(v) == "table" then + sanity_check_localization_entry(k, v) if v[locale] ~= nil then MojoSetup.translations[k] = v[locale] at_least_one = true From DONOTREPLY at icculus.org Sat Jan 12 07:49:47 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 12 Jan 2008 07:49:47 -0500 Subject: r405 - trunk Message-ID: <20080112124947.30078.qmail@icculus.org> Author: icculus Date: 2008-01-12 07:49:47 -0500 (Sat, 12 Jan 2008) New Revision: 405 Modified: trunk/gui_ncurses.c trunk/gui_stdio.c Log: More localization fixes. Modified: trunk/gui_ncurses.c =================================================================== --- trunk/gui_ncurses.c 2008-01-12 12:47:19 UTC (rev 404) +++ trunk/gui_ncurses.c 2008-01-12 12:49:47 UTC (rev 405) @@ -1287,7 +1287,7 @@ { char *fmt = entry->xstrdup(entry->_("Please insert '%0'")); char *text = entry->format(fmt, medianame); - char *localized_ok = entry->xstrdup(entry->_("Ok")); + char *localized_ok = entry->xstrdup(entry->_("OK")); char *localized_cancel = entry->xstrdup(entry->_("Cancel")); char *buttons[] = { localized_ok, localized_cancel }; MojoBox *mojobox = NULL; Modified: trunk/gui_stdio.c =================================================================== --- trunk/gui_stdio.c 2008-01-12 12:47:19 UTC (rev 404) +++ trunk/gui_stdio.c 2008-01-12 12:49:47 UTC (rev 405) @@ -129,7 +129,10 @@ boolean retval = false; if (!feof(stdin)) { - const char *_fmt = ((defval) ? "%1\n[Y/n]: " : "%1\n[y/N]: "); + const char *_fmt = ((defval) ? + entry->_("%1\n[Y/n]: ") : + entry->_("%1\n[y/N]: ")); + char *fmt = entry->xstrdup(entry->_(_fmt)); char *msg = entry->format(fmt, text); char *localized_no = entry->xstrdup(entry->_("N")); From DONOTREPLY at icculus.org Sun Jan 13 01:49:48 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 13 Jan 2008 01:49:48 -0500 Subject: r406 - trunk Message-ID: <20080113064948.5760.qmail@icculus.org> Author: icculus Date: 2008-01-13 01:49:48 -0500 (Sun, 13 Jan 2008) New Revision: 406 Modified: trunk/fileio.c trunk/fileio.h trunk/lua_glue.c Log: Added MojoInput that reads from a memory buffer, and lua glue that uses it to dumping a string to a file. This will eventually remove the need to use the Lua "io" package in the loki_setup bridge. Modified: trunk/fileio.c =================================================================== --- trunk/fileio.c 2008-01-12 12:49:47 UTC (rev 405) +++ trunk/fileio.c 2008-01-13 06:49:48 UTC (rev 406) @@ -281,6 +281,128 @@ } // MojoInput_newFromFile + +// MojoInputs from blocks of memory. + +typedef struct +{ + void *ptr; // original pointer from xmalloc() + uint32 *refcount; // address in xmalloc()'d block for reference count. + const uint8 *data; // base of actual "file" data in xmalloc()'d block. + uint32 len; // size, in bytes, of "file" data. + uint32 pos; // current read position. +} MojoInputMemInstance; + +static boolean MojoInput_memory_ready(MojoInput *io) +{ + return true; // always ready! +} // MojoInput_memory_ready + +static int64 MojoInput_memory_read(MojoInput *io, void *buf, uint32 bufsize) +{ + MojoInputMemInstance *inst = (MojoInputMemInstance *) io->opaque; + const uint32 avail = inst->len - inst->pos; + if (bufsize > avail) + bufsize = avail; + memcpy(buf, inst->data + inst->pos, bufsize); + inst->pos += bufsize; + return bufsize; +} // MojoInput_memory_read + +static boolean MojoInput_memory_seek(MojoInput *io, uint64 pos) +{ + MojoInputMemInstance *inst = (MojoInputMemInstance *) io->opaque; + if (pos > (uint64) inst->len) + return false; + inst->pos = (uint32) pos; + return true; +} // MojoInput_memory_seek + +static int64 MojoInput_memory_tell(MojoInput *io) +{ + MojoInputMemInstance *inst = (MojoInputMemInstance *) io->opaque; + return (int64) inst->pos; +} // MojoInput_memory_tell + +static int64 MojoInput_memory_length(MojoInput *io) +{ + MojoInputMemInstance *inst = (MojoInputMemInstance *) io->opaque; + return (int64) inst->len; +} // MojoInput_memory_length + +static MojoInput *MojoInput_memory_duplicate(MojoInput *io) +{ + MojoInputMemInstance *srcinst = (MojoInputMemInstance *) io->opaque; + MojoInput *retval = NULL; + MojoInputMemInstance *inst = NULL; + + if (srcinst->refcount != NULL) + { + // we don't copy the data for each duplicate; we just bump a reference + // counter. We free the data when all referencers are closed. + (*srcinst->refcount)++; // !!! FIXME: not thread safe! + } // if + + inst = (MojoInputMemInstance*) xmalloc(sizeof (MojoInputMemInstance)); + memcpy(inst, srcinst, sizeof (MojoInputMemInstance)); + inst->pos = 0; + + retval = (MojoInput *) xmalloc(sizeof (MojoInput)); + memcpy(retval, io, sizeof (MojoInput)); + retval->opaque = inst; + + return retval; +} // MojoInput_memory_duplicate + +static void MojoInput_memory_close(MojoInput *io) +{ + MojoInputMemInstance *inst = (MojoInputMemInstance *) io->opaque; + + if (inst->refcount != NULL) // memory we have to free? + { + assert(*inst->refcount > 0); + if (--(*inst->refcount) == 0) // !!! FIXME: not thread safe! + free(inst->ptr); + } // if + + free(inst); + free(io); +} // MojoInput_memory_close + +MojoInput *MojoInput_newFromMemory(const uint8 *ptr, uint32 len, int constant) +{ + MojoInput *io = (MojoInput *) xmalloc(sizeof (MojoInput)); + MojoInputMemInstance *inst = (MojoInputMemInstance*) + xmalloc(sizeof (MojoInputMemInstance)); + + if (constant) + inst->data = ptr; + else + { + inst->ptr = xmalloc(len + sizeof (uint32)); + inst->refcount = (uint32 *) inst->ptr; + inst->data = ((const uint8 *) inst->ptr) + sizeof (uint32); + *inst->refcount = 1; + memcpy((void *) inst->data, ptr, len); + } // else + + inst->len = len; + + io->ready = MojoInput_memory_ready; + io->read = MojoInput_memory_read; + io->seek = MojoInput_memory_seek; + io->tell = MojoInput_memory_tell; + io->length = MojoInput_memory_length; + io->duplicate = MojoInput_memory_duplicate; + io->close = MojoInput_memory_close; + io->opaque = inst; + + return io; +} // MojoInput_newFromMemory + + + + // MojoArchives from directories on the OS filesystem. typedef struct DirStack Modified: trunk/fileio.h =================================================================== --- trunk/fileio.h 2008-01-12 12:49:47 UTC (rev 405) +++ trunk/fileio.h 2008-01-13 06:49:48 UTC (rev 406) @@ -44,8 +44,11 @@ void *opaque; }; +// This copies the memory, so you may free (ptr) after this function returns. +MojoInput *MojoInput_newFromMemory(const uint8 *ptr, uint32 len, int constant); MojoInput *MojoInput_newFromFile(const char *fname); + typedef enum { MOJOARCHIVE_ENTRY_UNKNOWN = 0, Modified: trunk/lua_glue.c =================================================================== --- trunk/lua_glue.c 2008-01-12 12:49:47 UTC (rev 405) +++ trunk/lua_glue.c 2008-01-13 06:49:48 UTC (rev 406) @@ -979,6 +979,38 @@ } // luahook_movefile +// !!! FIXME: this is a lot of duplication from luahook_writefile +static int luahook_stringtofile(lua_State *L) +{ + const char *str = luaL_checkstring(L, 1); + const char *path = luaL_checkstring(L, 2); + MojoInput *in = NULL; + size_t len = 0; + int retval = 0; + boolean rc = false; + uint16 perms = 0600; // !!! FIXME + MojoChecksums sums; + + str = lua_tolstring(L, 1, &len); + in = MojoInput_newFromMemory((const uint8 *) str, (uint32) len, 1); + assert(in != NULL); // xmalloc() would fatal(), should not return NULL. + if (!lua_isnil(L, 3)) + { + boolean valid = false; + const char *permstr = luaL_checkstring(L, 3); + perms = MojoPlatform_makePermissions(permstr, &valid); + if (!valid) + fatal(_("BUG: '%0' is not a valid permission string"), permstr); + } // if + rc = MojoInput_toPhysicalFile(in, path, perms, &sums, writeCallback, L); + + retval += retvalBoolean(L, rc); + if (rc) + retval += retvalChecksums(L, &sums); + return retval; +} // luahook_stringtofile + + static void prepareSplash(MojoGuiSplash *splash, const char *fname) { MojoInput *io = NULL; @@ -1510,6 +1542,7 @@ set_cfunc(luaState, luahook_debugger, "debugger"); set_cfunc(luaState, luahook_findmedia, "findmedia"); set_cfunc(luaState, luahook_writefile, "writefile"); + set_cfunc(luaState, luahook_stringtofile, "stringtofile"); set_cfunc(luaState, luahook_download, "download"); set_cfunc(luaState, luahook_movefile, "movefile"); set_cfunc(luaState, luahook_wildcardmatch, "wildcardmatch"); From DONOTREPLY at icculus.org Sun Jan 13 06:14:36 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 13 Jan 2008 06:14:36 -0500 Subject: r407 - trunk/examples/duke3d Message-ID: <20080113111436.31823.qmail@icculus.org> Author: icculus Date: 2008-01-13 06:14:32 -0500 (Sun, 13 Jan 2008) New Revision: 407 Modified: trunk/examples/duke3d/make.sh Log: Try to do the right thing with different CPU counts. Modified: trunk/examples/duke3d/make.sh =================================================================== --- trunk/examples/duke3d/make.sh 2008-01-13 06:49:48 UTC (rev 406) +++ trunk/examples/duke3d/make.sh 2008-01-13 11:14:32 UTC (rev 407) @@ -13,6 +13,18 @@ DEBUG=1 fi +OSTYPE=`uname -s` +if [ "$OSTYPE" = "Linux" ]; then + NCPU=`cat /proc/cpuinfo |grep vendor_id |wc -l` + let NCPU=$NCPU+1 +elif [ "$OSTYPE" = "Darwin" ]; then + NCPU=`sysctl -n hw.ncpu` +else + NCPU=1 +fi + +echo "Will use make -j$NCPU. If this is wrong, check NCPU at top of script." + # Show everything that we do here on stdout. set -x @@ -55,7 +67,7 @@ -DMOJOSETUP_IMAGE_PNG=FALSE \ -DMOJOSETUP_URL_FTP=FALSE \ . -make -j5 +make -j$NCPU # Strip the binaries and GUI plugins, put them somewhere useful. if [ "$DEBUG" != "1" ]; then From DONOTREPLY at icculus.org Sun Jan 13 06:15:38 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 13 Jan 2008 06:15:38 -0500 Subject: r408 - trunk/examples/ut3-dedicated Message-ID: <20080113111538.1375.qmail@icculus.org> Author: icculus Date: 2008-01-13 06:15:38 -0500 (Sun, 13 Jan 2008) New Revision: 408 Modified: trunk/examples/ut3-dedicated/make.sh Log: Added NCPU patch to ut3-dedicated example. Modified: trunk/examples/ut3-dedicated/make.sh =================================================================== --- trunk/examples/ut3-dedicated/make.sh 2008-01-13 11:14:32 UTC (rev 407) +++ trunk/examples/ut3-dedicated/make.sh 2008-01-13 11:15:38 UTC (rev 408) @@ -21,6 +21,18 @@ DEBUG=1 fi +OSTYPE=`uname -s` +if [ "$OSTYPE" = "Linux" ]; then + NCPU=`cat /proc/cpuinfo |grep vendor_id |wc -l` + let NCPU=$NCPU+1 +elif [ "$OSTYPE" = "Darwin" ]; then + NCPU=`sysctl -n hw.ncpu` +else + NCPU=1 +fi + +echo "Will use make -j$NCPU. If this is wrong, check NCPU at top of script." + # Show everything that we do here on stdout. set -x @@ -80,7 +92,7 @@ . #make -j5 VERBOSE=1 -make -j5 +make -j$NCPU # Strip the binaries and GUI plugins, put them somewhere useful. if [ "$DEBUG" != "1" ]; then From DONOTREPLY at icculus.org Sun Jan 13 07:33:00 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 13 Jan 2008 07:33:00 -0500 Subject: r409 - trunk/scripts Message-ID: <20080113123300.18068.qmail@icculus.org> Author: icculus Date: 2008-01-13 07:32:59 -0500 (Sun, 13 Jan 2008) New Revision: 409 Modified: trunk/scripts/localization.lua Log: More text, and more documentation. Modified: trunk/scripts/localization.lua =================================================================== --- trunk/scripts/localization.lua 2008-01-13 11:15:38 UTC (rev 408) +++ trunk/scripts/localization.lua 2008-01-13 12:32:59 UTC (rev 409) @@ -4,7 +4,8 @@ -- -- This file written by Ryan C. Gordon. - +-- Lines starting with "--" are comments in this file. +-- -- NOTE: If you care about Unicode or ASCII chars above 127, this file _MUST_ -- be UTF-8 encoded! If you think you're using a certain high-ascii codepage, -- you're wrong! @@ -14,9 +15,24 @@ -- file more like a data description language and less like a turing-complete -- scripting language. -- --- You should leave the existing strings here. They aren't hurting anything, --- and most are used by MojoSetup itself. Add your own, though. +-- The format of an entry looks like this: -- +-- ["Hello"] = { +-- es = "Hola", +-- de = "Hallo", +-- fr = "Bonjour", +-- }; +-- +-- So you just fill in the translation of the English for your language code. +-- Note that locales work, too: +-- +-- ["Color"] = { +-- en_GB = "Colour", +-- }; +-- +-- Specific locales are favored, falling back to specific languages, eventually +-- ending up on the untranslated version (which is technically en_US). +-- -- Whenever you see a %x sequence, that is replaced with a string at runtime. -- So if you see, ["Hello, %0, my name is %1."], then this might become -- "Hello, Alice, my name is Bob." at runtime. If your culture would find @@ -28,6 +44,9 @@ -- in all reasonable tests, then finding out that one guy in Ghana has a -- crashing installer because his localization forgot to add a %1 somewhere. -- +-- You should leave the existing strings here. They aren't hurting anything, +-- and most are used by MojoSetup itself. Add your own, if needed, though. +-- -- The table you create here goes away shortly after creation, as the relevant -- parts of it get moved somewhere else. You should call MojoSetup.translate() -- to get the proper translation for a given string. @@ -149,6 +168,9 @@ ["BUG: stepped back over start of stages"] = { }; + ["BUG: Unhandled data type"] = { + }; + ["bzlib triggered an internal error: %0"] = { }; @@ -321,6 +343,9 @@ ["You must accept the license before you may install"] = { }; + + ["Metadata"] = { + }; }; -- end of localization.lua ... From DONOTREPLY at icculus.org Sun Jan 13 07:48:19 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 13 Jan 2008 07:48:19 -0500 Subject: r410 - trunk Message-ID: <20080113124819.15664.qmail@icculus.org> Author: icculus Date: 2008-01-13 07:48:19 -0500 (Sun, 13 Jan 2008) New Revision: 410 Modified: trunk/docs.txt Log: Updated documentation. Modified: trunk/docs.txt =================================================================== --- trunk/docs.txt 2008-01-13 12:32:59 UTC (rev 409) +++ trunk/docs.txt 2008-01-13 12:48:19 UTC (rev 410) @@ -267,6 +267,12 @@ Setup.Package table as a parameter. + updateurl (no default, mustBeUrl) + + This is written to the manifest files for the aid of external tools, but + isn't currently used by MojoSetup itself. + + splash (no default, mustBeString, cantBeEmpty) (!!! FIXME) This attribute is for future expansion. @@ -298,11 +304,6 @@ (!!! FIXME) This attribute is for future expansion. - update_url (no default, mustBeString, mustBeUrl) - - (!!! FIXME) This attribute is for future expansion. - - superuser (default false, mustBeBool) (!!! FIXME) This attribute is for future expansion. @@ -958,7 +959,7 @@ MojoSetup.info.ui This is a string (not a function!) of the UI plugin that MojoSetup chose. - system. This is currently one of "stdio", "ncurses", "macosx", "gtkplus2", + This is currently one of "stdio", "ncurses", "macosx", "gtkplus2", "www", or one of several others, depending on your build and target platform. It's best to not rely on this being within a specific set of values. @@ -1035,7 +1036,11 @@ a change to the filesystem. Each of these elements is an array of tables. for option,items in pairs(MojoSetup.manifest) do - print("Option: " .. option.description) + local desc = option + if type(desc) == "table" then -- could be a string in some cases! + desc = desc.description + end + print("Option: " .. desc) for i,item in ipairs(items) do -- ... do stuff with "item" here ... end @@ -1052,8 +1057,10 @@ -- Checksums may or may not exist in this table, depending on how -- MojoSetup was compiled. You can iterate to find out what's there: print("checksums:") - for k,v in pairs(item.checksums) do - print(" " .. k .. ": " .. v) -- "crc32: 92FAB211E", etc. + if item.checksums ~= nil then + for k,v in pairs(item.checksums) do + print(" " .. k .. ": " .. v) -- "crc32: 92FAB211E", etc. + end end end From DONOTREPLY at icculus.org Sun Jan 13 07:50:39 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 13 Jan 2008 07:50:39 -0500 Subject: r411 - trunk/scripts Message-ID: <20080113125039.19408.qmail@icculus.org> Author: icculus Date: 2008-01-13 07:50:39 -0500 (Sun, 13 Jan 2008) New Revision: 411 Removed: trunk/scripts/loki_setup_compat.lua Modified: trunk/scripts/config.lua trunk/scripts/mojosetup_init.lua trunk/scripts/mojosetup_mainline.lua Log: Generate manifests for installs in various formats, and other cleanups related to that effort. Modified: trunk/scripts/config.lua =================================================================== --- trunk/scripts/config.lua 2008-01-13 12:48:19 UTC (rev 410) +++ trunk/scripts/config.lua 2008-01-13 12:50:39 UTC (rev 411) @@ -42,6 +42,7 @@ superuser = false, destination = "/usr/local/bin", recommended_destinations = { "/opt/games", "/usr/local/games" }, + updateurl = "http://localhost/updates/", -- Things named Setup.Something are internal functions we supply. -- Generally these return the table you pass to them, but they Deleted: trunk/scripts/loki_setup_compat.lua =================================================================== --- trunk/scripts/loki_setup_compat.lua 2008-01-13 12:48:19 UTC (rev 410) +++ trunk/scripts/loki_setup_compat.lua 2008-01-13 12:50:39 UTC (rev 411) @@ -1,100 +0,0 @@ --- MojoSetup; a portable, flexible installation application. --- --- Please see the file LICENSE.txt in the source's root directory. --- --- This file written by Ryan C. Gordon. - - --- Compatibility with loki_setup and related tools. --- --- You can cut-and-paste this file into your config script, or call this at --- the start of it: MojoSetup.runfile("loki_setup_compat") --- This code is optional, and not otherwise referenced by MojoSetup. It could --- be useful for those that need to integrate with loki_update, etc. --- --- Using this code requires you to build with the Lua "io" runtime library. --- (for now, at least). - -MojoSetup.Loki = {} - - --- !!! FIXME: some of these are currently-undocumented MojoSetup.* methods... - -function MojoSetup.Loki.manifest(install, update_url) - local manifestdir = MojoSetup.destination .. "/.manifest" - MojoSetup.installed_files[#MojoSetup.installed_files+1] = manifestdir - if not MojoSetup.platform.mkdir(manifestdir) then - -- !!! FIXME: formatting - MojoSetup.logerror("Failed to create dir '" .. manifestdir .. "'") - MojoSetup.fatal(_("mkdir failed")) - end - - local manifestfile = manifestdir .. "/" .. install.id .. ".xml" - MojoSetup.installed_files[#MojoSetup.installed_files+1] = manifestfile - local f, err = io.open(manifestfile, "a") - if f == nil then - MojoSetup.logerror("Couldn't create manifest: " .. err) - MojoSetup.fatal(_("Couldn't create manifest")) - end - - if update_url ~= nil then - update_url = 'update_url="' .. update_url .. '"' - else - update_url = '' - end - - -- !!! FIXME: check i/o errors - f:write('\n') - f:write('\n') - f:write(' \n') - - local destlen = string.len(MojoSetup.destination) + 2 - for option,items in pairs(MojoSetup.manifest) do - f:write(' \n') - end - - f:write(' \n') - f:write('\n\n') - - -- !!! FIXME: check i/o errors - f:close() -end - --- end of loki_setup_compat.lua ... - Modified: trunk/scripts/mojosetup_init.lua =================================================================== --- trunk/scripts/mojosetup_init.lua 2008-01-13 12:48:19 UTC (rev 410) +++ trunk/scripts/mojosetup_init.lua 2008-01-13 12:50:39 UTC (rev 411) @@ -339,7 +339,7 @@ { "category", "Games", mustBeString, cantBeEmpty }, { "promptoverwrite", true, mustBeBool }, { "binarypath", nil, mustBeString, cantBeEmpty }, - { "update_url", nil, mustBeString, mustBeUrl }, + { "updateurl", nil, mustBeString, mustBeUrl }, { "superuser", false, mustBeBool }, }) Modified: trunk/scripts/mojosetup_mainline.lua =================================================================== --- trunk/scripts/mojosetup_mainline.lua 2008-01-13 12:48:19 UTC (rev 410) +++ trunk/scripts/mojosetup_mainline.lua 2008-01-13 12:50:39 UTC (rev 411) @@ -88,6 +88,26 @@ end +-- get a linear array of filenames in the manifest. +local function flatten_manifest() + local man = MojoSetup.manifest + local files = {} + + if man ~= nil then + for key,items in pairs(man) do + for i,item in ipairs(items) do + local path = item.path + if path ~= nil then + files[#files+1] = path + end + end + end + end + + return files +end + + -- This gets called by fatal()...must be a global function. function MojoSetup.revertinstall() -- !!! FIXME: language. @@ -99,7 +119,7 @@ -- !!! FIXME: callbacks here. delete_files(MojoSetup.downloads) - delete_files(MojoSetup.installed_files) + delete_files(flatten_manifest()) do_rollbacks() delete_scratchdirs() end @@ -233,11 +253,11 @@ end -local function install_file(dest, archive, file, perms, option) +local function install_file(dest, perms, writefn, desc, manifestkey) -- Upvalued so we don't look these up each time... local fname = string.gsub(dest, "^.*/", "", 1) -- chop the dirs off... local ptype = _("Installing") -- !!! FIXME: localization. - local component = option.description + local component = desc local keepgoing = true local callback = function(ticks, justwrote, bw, total) local percent = -1 @@ -251,8 +271,22 @@ return keepgoing end - MojoSetup.installed_files[#MojoSetup.installed_files+1] = dest - local written, sums = MojoSetup.writefile(archive, dest, perms, callback) + -- Add to manifest first, so we can delete it during rollback if i/o fails. + local manifestentry = + { + type = "file", + path = dest, + mode = perms, -- !!! FIXME: perms may be nil...we need a MojoSetup.defaultPermsString()... + } + if manifestkey ~= nil then + if MojoSetup.manifest[manifestkey] == nil then + MojoSetup.manifest[manifestkey] = {} + end + local manifest = MojoSetup.manifest[manifestkey] + manifest[#manifest+1] = manifestentry + end + + local written, sums = writefn(callback) if not written then -- !!! FIXME: formatting! if not keepgoing then @@ -264,39 +298,42 @@ end end - -- !!! FIXME: perms may be null...we need a MojoSetup.defaultPermsString()... + manifestentry.checksums = sums - if option ~= nil then - if MojoSetup.manifest[option] == nil then - MojoSetup.manifest[option] = {} - end - local manifest = MojoSetup.manifest[option] - manifest[#manifest+1] = - { - type = "file", - path = dest, - checksums = sums, - mode = perms, - } + MojoSetup.loginfo("Created file '" .. dest .. "'") +end + + +local function install_file_from_archive(dest, archive, perms, desc, manifestkey) + local fn = function(callback) + return MojoSetup.writefile(archive, dest, perms, callback) end + return install_file(dest, perms, fn, desc, manifestkey) +end - MojoSetup.loginfo("Created file '" .. dest .. "'") + +local function install_file_from_string(dest, string, perms, desc, manifestkey) + local fn = function(callback) + return MojoSetup.stringtofile(string, dest, perms, callback) + end + return install_file(dest, perms, fn, desc, manifestkey) end -local function install_symlink(dest, lndest, option) - MojoSetup.installed_files[#MojoSetup.installed_files+1] = dest +-- !!! FIXME: we should probably pump the GUI queue here, in case there are +-- !!! FIXME: thousands of symlinks in a row or something. +local function install_symlink(dest, lndest, manifestkey) if not MojoSetup.platform.symlink(dest, lndest) then -- !!! FIXME: formatting! MojoSetup.logerror("Failed to create symlink '" .. dest .. "'") MojoSetup.fatal(_("symlink creation failed!")) end - if option ~= nil then - if MojoSetup.manifest[option] == nil then - MojoSetup.manifest[option] = {} + if manifestkey ~= nil then + if MojoSetup.manifest[manifestkey] == nil then + MojoSetup.manifest[manifestkey] = {} end - local manifest = MojoSetup.manifest[option] + local manifest = MojoSetup.manifest[manifestkey] manifest[#manifest+1] = { type = "symlink", @@ -309,19 +346,20 @@ end -local function install_directory(dest, perms, option) - MojoSetup.installed_files[#MojoSetup.installed_files+1] = dest +-- !!! FIXME: we should probably pump the GUI queue here, in case there are +-- !!! FIXME: thousands of dirs in a row or something. +local function install_directory(dest, perms, manifestkey) if not MojoSetup.platform.mkdir(dest, perms) then -- !!! FIXME: formatting MojoSetup.logerror("Failed to create dir '" .. dest .. "'") MojoSetup.fatal(_("mkdir failed")) end - if option ~= nil then - if MojoSetup.manifest[option] == nil then - MojoSetup.manifest[option] = {} + if manifestkey ~= nil then + if MojoSetup.manifest[manifestkey] == nil then + MojoSetup.manifest[manifestkey] = {} end - local manifest = MojoSetup.manifest[option] + local manifest = MojoSetup.manifest[manifestkey] manifest[#manifest+1] = { type = "dir", @@ -334,7 +372,7 @@ end -local function install_parent_dirs(path, option) +local function install_parent_dirs(path, manifestkey) -- Chop any '/' chars from the end of the string... path = string.gsub(path, "/+$", "") @@ -344,7 +382,7 @@ if item ~= "" then fullpath = fullpath .. "/" .. item if not MojoSetup.platform.exists(fullpath) then - install_directory(fullpath, nil, option) + install_directory(fullpath, nil, manifestkey) end end end @@ -386,7 +424,6 @@ if allowoverwrite then local id = #MojoSetup.rollbacks + 1 local f = MojoSetup.rollbackdir .. "/" .. id - -- !!! FIXME: don't add (f) to the installed_files table... install_parent_dirs(f, nil) MojoSetup.rollbacks[id] = dest if not MojoSetup.movefile(dest, f) then @@ -401,7 +438,6 @@ return allowoverwrite end - local function install_archive_entry(archive, ent, file, option) local entdest = ent.filename if entdest == nil then return end -- probably can't happen... @@ -429,7 +465,8 @@ if permit_write(dest, ent, file) then install_parent_dirs(dest, option) if ent.type == "file" then - install_file(dest, archive, file, perms, option) + local desc = option.description + install_file_from_archive(dest, archive, perms, desc, option) elseif ent.type == "dir" then install_directory(dest, perms, option) elseif ent.type == "symlink" then @@ -569,6 +606,7 @@ -- !!! FIXME: ".mojosetup_tmp" dirname may clash with install...? MojoSetup.loginfo("Install dest: '" .. dest .. "'") MojoSetup.destination = dest + MojoSetup.manifestdir = MojoSetup.destination .. "/.mojosetup_manifest" MojoSetup.scratchdir = MojoSetup.destination .. "/.mojosetup_tmp" MojoSetup.rollbackdir = MojoSetup.scratchdir .. "/rollbacks" MojoSetup.downloaddir = MojoSetup.scratchdir .. "/downloads" @@ -585,6 +623,191 @@ end +-- The XML manifest is compatible with the loki_setup manifest schema, since +-- it has a reasonable set of data, and allows you to use loki_update or +-- loki_patch with a MojoSetup installation. Please note that we never ever +-- look at this data! You are responsible for updating the other files if +-- you think it'll be important. The Unix MojoSetup uninstaller uses the +-- plain text manifest, for example (but loki_uninstall can use the xml one, +-- so if you want, you can just drop in MojoSetup to replace loki_setup and +-- use the Loki tools for everything else. +local function build_xml_manifest() + local install = MojoSetup.install + local updateurl = install.updateurl + if updateurl ~= nil then + updateurl = 'update_url="' .. updateurl .. '"' + else + updateurl = '' + end + + local retval = + '\n' .. + '\n' .. + '\t\n' + + local destlen = string.len(MojoSetup.destination) + 2 + for option,items in pairs(MojoSetup.manifest) do + local desc = option + if type(desc) == "table" then -- "meta" etc, or an option table. + desc = option.description + end + + retval = retval .. '\t\t\n' + end + + retval = retval .. '\t\n' + retval = retval .. '\n\n' + + return retval +end + + +local function build_lua_manifest() + local indentation = 0 -- upvalue for serialize() + local function serialize(obj) + local retval = '' + + indentation = indentation + 1 + + local objtype = type(obj) + if objtype == "number" then + retval = tostring(obj) + elseif objtype == "string" then + retval = string.format("%q", obj) + elseif objtype == "table" then + retval = "{\n" + local tab = string.rep("\t", indentation) + for k,v in pairs(obj) do + local key = k + if type(key) == "number" then + key = '[' .. key .. ']' + elseif not string.match(key, "^[_a-zA-Z][_a-zA-Z0-9]*$") then + key = '[' .. string.format("%q", key) .. ']' + end + retval = retval .. tab .. key .. " = " .. serialize(v) .. ",\n" + end + retval = retval .. string.rep("\t", indentation-1) .. "}" + else + MojoSetup.fatal(_("BUG: Unhandled data type")) + end + + indentation = indentation - 1 + return retval + end + + local man = {} + for option,items in pairs(MojoSetup.manifest) do + local desc = option + if type(desc) == "table" then -- "meta" etc, or an option table. + desc = option.description + end + man[desc] = items; + end + + local install = MojoSetup.install + return 'package = ' .. serialize { + id = install.id, + description = install.description, + root = MojoSetup.destination, + update_url = install.updateurl, + version = install.version, + manifest = man, + } .. "\n\n" +end + + +local function build_txt_manifest() + local retval = '' + local destlen = string.len(MojoSetup.destination) + 2 + local files = flatten_manifest() + for i,item in ipairs(files) do + local path = item + if path ~= nil then + path = string.sub(path, destlen) -- make it relative. + retval = retval .. path .. "\n" + end + end + return retval +end + + +local function install_manifests() + -- We write out a Lua script as a data definition language, a + -- loki_setup-compatible XML manifest, and a straight text file of + -- all the filenames. Take your pick. + local key = ".mojosetup_metadata." + + -- We have to cheat and just plug these into the manifest directly, since + -- they won't show up until after we write them out, otherwise. + -- Obviously, we don't have checksums for them, either, as we haven't + -- assembled the data yet! + local perms = "0644" -- !!! FIXME + local basefname = MojoSetup.manifestdir .. "/" .. MojoSetup.install.id + local lua_fname = basefname .. ".lua" + local xml_fname = basefname .. ".xml" + local txt_fname = basefname .. ".txt" + if MojoSetup.manifest[key] == nil then + MojoSetup.manifest[key] = {} + end + local manifest = MojoSetup.manifest[key] + manifest[#manifest+1] = { type = "file", path = lua_fname, mode = perms } + manifest[#manifest+1] = { type = "file", path = xml_fname, mode = perms } + manifest[#manifest+1] = { type = "file", path = txt_fname, mode = perms } + + -- These are probably all duplicated effort, but just in case... + install_parent_dirs(lua_fname, key) + install_parent_dirs(xml_fname, key) + install_parent_dirs(txt_fname, key) + + -- now build these things... + local desc = _("Metadata") + install_file_from_string(lua_fname, build_lua_manifest(), perms, desc, nil) + install_file_from_string(xml_fname, build_xml_manifest(), perms, desc, nil) + install_file_from_string(txt_fname, build_txt_manifest(), perms, desc, nil) +end + + local function do_install(install) MojoSetup.forceoverwrite = nil MojoSetup.written = 0 @@ -864,7 +1087,6 @@ local id = 0 for file,option in pairs(MojoSetup.files.downloads) do local f = MojoSetup.downloaddir .. "/" .. id - -- !!! FIXME: don't add (f) to the installed_files table... install_parent_dirs(f, nil) id = id + 1 @@ -976,6 +1198,9 @@ end run_config_defined_hook(install.postinstall, install) + + install_manifests() -- write out manifest. + return 1 -- go to next stage. end @@ -1004,7 +1229,6 @@ MojoSetup.stages = stages MojoSetup.manifest = {} - MojoSetup.installed_files = {} MojoSetup.rollbacks = {} MojoSetup.downloads = {} @@ -1033,15 +1257,12 @@ end end - -- !!! FIXME: write out manifest. - -- Successful install, so delete conflicts we no longer need to rollback. delete_rollbacks() delete_files(MojoSetup.downloads) delete_scratchdirs() -- Don't let future errors delete files from successful installs... - MojoSetup.installed_files = nil MojoSetup.downloads = nil MojoSetup.rollbacks = nil @@ -1052,6 +1273,7 @@ stages = nil MojoSetup.manifest = nil MojoSetup.destination = nil + MojoSetup.manifestdir = nil MojoSetup.scratchdir = nil MojoSetup.rollbackdir = nil MojoSetup.downloaddir = nil From DONOTREPLY at icculus.org Sun Jan 13 20:01:24 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 13 Jan 2008 20:01:24 -0500 Subject: r412 - trunk Message-ID: <20080114010124.6945.qmail@icculus.org> Author: icculus Date: 2008-01-13 20:01:23 -0500 (Sun, 13 Jan 2008) New Revision: 412 Modified: trunk/archive_tar.c Log: Fixed a FIXME: leaking MojoInputs from the tar archiver in corner cases. Modified: trunk/archive_tar.c =================================================================== --- trunk/archive_tar.c 2008-01-13 12:50:39 UTC (rev 411) +++ trunk/archive_tar.c 2008-01-14 01:01:23 UTC (rev 412) @@ -166,15 +166,21 @@ return retval; } // MojoInput_gzip_duplicate -static void MojoInput_gzip_close(MojoInput *io) +static void free_gzip_input(MojoInput *io) { GZIPinfo *info = (GZIPinfo *) io->opaque; - if (info->origio != NULL) - info->origio->close(info->origio); inflateEnd(&info->stream); free(info->buffer); free(info); free(io); +} // free_gzip_input + +static void MojoInput_gzip_close(MojoInput *io) +{ + GZIPinfo *info = (GZIPinfo *) io->opaque; + if (info->origio != NULL) + info->origio->close(info->origio); + free_gzip_input(io); } // MojoInput_gzip_close static MojoInput *make_gzip_input(MojoInput *origio) @@ -374,15 +380,21 @@ return retval; } // MojoInput_bzip2_duplicate -static void MojoInput_bzip2_close(MojoInput *io) +static void free_bzip2_input(MojoInput *io) { BZIP2info *info = (BZIP2info *) io->opaque; - if (info->origio != NULL) - info->origio->close(info->origio); BZ2_bzDecompressEnd(&info->stream); free(info->buffer); free(info); free(io); +} // free_bzip2_input + +static void MojoInput_bzip2_close(MojoInput *io) +{ + BZIP2info *info = (BZIP2info *) io->opaque; + if (info->origio != NULL) + info->origio->close(info->origio); + free_bzip2_input(io); } // MojoInput_bzip2_close static MojoInput *make_bzip2_input(MojoInput *origio) @@ -471,7 +483,7 @@ static MojoInput *MojoInput_tar_duplicate(MojoInput *io) { MojoInput *retval = NULL; - fatal("BUG: Can't duplicate tar inputs"); + fatal("BUG: Can't duplicate tar inputs"); // !!! FIXME: why not? #if 0 TARinput *input = (TARinput *) io->opaque; MojoInput *origio = (MojoInput *) io->opaque; @@ -711,11 +723,14 @@ } // MojoArchive_tar_close +static void free_wrapper_noop(MojoInput *io) {} + MojoArchive *MojoArchive_createTAR(MojoInput *io) { MojoArchive *ar = NULL; uint8 sig[512]; int64 br = io->read(io, sig, 4); + void (*free_wrapper)(MojoInput *io) = free_wrapper_noop; if ((!io->seek(io, 0)) || (br != 4)) return NULL; @@ -727,13 +742,19 @@ #if SUPPORT_TAR_GZ // gzip compressed? if ((sig[0] == 0x1F) && (sig[1] == 0x8B) && (sig[2] == 0x08)) + { + free_wrapper = free_gzip_input; io = make_gzip_input(io); + } // if #endif // BZ2 compressed? #if SUPPORT_TAR_BZ2 // bzip2 compressed? if ((sig[0] == 0x42) && (sig[1] == 0x5A)) + { + free_wrapper = free_bzip2_input; io = make_bzip2_input(io); + } // if #endif } // if @@ -743,11 +764,17 @@ // these for years, so it's okay to ignore other ones, I guess. br = io->read(io, sig, sizeof (sig)); // potentially compressed. if ((!io->seek(io, 0)) || (br != sizeof (sig))) - return NULL; // !!! FIXME: leaking MojoInput wrapper... + { + free_wrapper(io); + return NULL; + } // if if (!is_ustar(sig)) - return NULL; // !!! FIXME: leaking MojoInput wrapper... - + { + free_wrapper(io); + return NULL; + } // if + // okay, it's a tarball, we're good to go. ar = (MojoArchive *) xmalloc(sizeof (MojoArchive)); From DONOTREPLY at icculus.org Sun Jan 13 20:50:21 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 13 Jan 2008 20:50:21 -0500 Subject: r413 - in trunk: . scripts Message-ID: <20080114015021.26311.qmail@icculus.org> Author: icculus Date: 2008-01-13 20:50:21 -0500 (Sun, 13 Jan 2008) New Revision: 413 Modified: trunk/gui_gtkplus2.c trunk/gui_stdio.c trunk/lua_glue.c trunk/mojosetup.c trunk/platform.h trunk/platform_unix.c trunk/platform_windows.c trunk/scripts/localization.lua trunk/scripts/mojosetup_mainline.lua Log: Lots of FIXME removals, clenaups, and tweaks. Modified: trunk/gui_gtkplus2.c =================================================================== --- trunk/gui_gtkplus2.c 2008-01-14 01:01:23 UTC (rev 412) +++ trunk/gui_gtkplus2.c 2008-01-14 01:50:21 UTC (rev 413) @@ -97,7 +97,6 @@ gtk_main_iteration(); if (click_value == CLICK_CANCEL) { - // !!! FIXME: language. char *title = entry->xstrdup(entry->_("Cancel installation")); char *text = entry->xstrdup(entry->_("Are you sure you want to cancel installation?")); if (!MojoGui_gtkplus2_promptyn(title, text, false)) @@ -280,7 +279,6 @@ static boolean MojoGui_gtkplus2_promptyn(const char *title, const char *text, boolean defval) { - // !!! FIXME: support defval. gint rc = do_msgbox(title, text, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, defval ? GTK_RESPONSE_YES : GTK_RESPONSE_NO, @@ -310,7 +308,6 @@ const char *text, boolean defval) { - // !!! FIXME: support defval. const gint rc = do_msgbox(title, text, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, defval ? GTK_RESPONSE_YES : GTK_RESPONSE_NO, Modified: trunk/gui_stdio.c =================================================================== --- trunk/gui_stdio.c 2008-01-14 01:01:23 UTC (rev 412) +++ trunk/gui_stdio.c 2008-01-14 01:50:21 UTC (rev 413) @@ -621,7 +621,6 @@ char *fmt = NULL; char *msg = NULL; percentTicks = now + 1000; - // !!! FIXME: localization. if (percent < 0) printf("%s\n", item); else Modified: trunk/lua_glue.c =================================================================== --- trunk/lua_glue.c 2008-01-14 01:01:23 UTC (rev 412) +++ trunk/lua_glue.c 2008-01-14 01:50:21 UTC (rev 413) @@ -988,7 +988,7 @@ size_t len = 0; int retval = 0; boolean rc = false; - uint16 perms = 0600; // !!! FIXME + uint16 perms = MojoPlatform_defaultFilePerms(); MojoChecksums sums; str = lua_tolstring(L, 1, &len); @@ -1365,21 +1365,17 @@ size_t reccount = 0; char *rc = NULL; int command = 0; + size_t i = 0; if (lua_istable(L, 1)) { - size_t i; - reccount = lua_objlen(L, 1); - recommend = (char **) alloca(reccount * sizeof (char *)); + recommend = (char **) xmalloc(reccount * sizeof (char *)); for (i = 0; i < reccount; i++) { - const char *str = NULL; lua_pushinteger(L, i+1); lua_gettable(L, 1); - str = lua_tostring(L, -1); // !!! FIXME: alloca in a loop... - recommend[i] = (char *) alloca(strlen(str) + 1); - strcpy(recommend[i], str); + recommend[i] = xstrdup(lua_tostring(L, -1)); lua_pop(L, 1); } // for } // if @@ -1387,6 +1383,13 @@ rc = GGui->destination((const char **) recommend, reccount, &command, can_go_back, can_go_fwd); + if (recommend != NULL) + { + for (i = 0; i < reccount; i++) + free(recommend[i]); + free(recommend); + } // if + retvalNumber(L, command); retvalString(L, rc); // may push nil. free(rc); Modified: trunk/mojosetup.c =================================================================== --- trunk/mojosetup.c 2008-01-14 01:01:23 UTC (rev 412) +++ trunk/mojosetup.c 2008-01-14 01:50:21 UTC (rev 413) @@ -455,8 +455,9 @@ else // Unknown string gets everything...that'll teach you. MojoLog_logLevel = MOJOSETUP_LOG_EVERYTHING; - // !!! FIXME: allow logging to stdout on Unix. - if (fname != NULL) + if ((fname != NULL) && (strcmp(fname, "-") == 0)) + logFile = MojoPlatform_stdout(); + else if (fname != NULL) { const uint32 flags = MOJOFILE_WRITE|MOJOFILE_CREATE|MOJOFILE_TRUNCATE; const uint16 mode = MojoPlatform_defaultFilePerms(); Modified: trunk/platform.h =================================================================== --- trunk/platform.h 2008-01-14 01:01:23 UTC (rev 412) +++ trunk/platform.h 2008-01-14 01:50:21 UTC (rev 413) @@ -147,6 +147,12 @@ // handle with MojoPlatform_close() when done with it. void *MojoPlatform_open(const char *fname, uint32 flags, uint16 mode); +// Return a handle that's compatible with MojoPlatform_open()'s return values +// that represents stdout. May return NULL for platforms that don't support +// this concept. You need to make sure that stdout itself doesn't really +// close in MojoPlatform_close(), at least for now. +void *MojoPlatform_stdout(void); + // Read (bytes) bytes from (fd) into (buf). This wraps the Unix read() syscall. // Returns number of bytes read, -1 on error. int64 MojoPlatform_read(void *fd, void *buf, uint32 bytes); Modified: trunk/platform_unix.c =================================================================== --- trunk/platform_unix.c 2008-01-14 01:01:23 UTC (rev 412) +++ trunk/platform_unix.c 2008-01-14 01:50:21 UTC (rev 413) @@ -591,6 +591,14 @@ } // MojoPlatform_isfile +void *MojoPlatform_stdout(void) +{ + int *retval = (int *) xmalloc(sizeof (int)); + *retval = 1; // stdout. + return retval; +} // MojoPlatform_stdout + + void *MojoPlatform_open(const char *fname, uint32 flags, uint16 mode) { void *retval = NULL; @@ -678,8 +686,17 @@ boolean MojoPlatform_close(void *fd) { boolean retval = false; - if (close(*((int *) fd)) == 0) + int handle = *((int *) fd); + + // don't close stdin, stdout, or stderr. + if ((handle == 0) || (handle == 1) || (handle == 2)) + { free(fd); + return true; + } // if + + if (close(handle) == 0) + free(fd); return retval; } // MojoPlatform_close Modified: trunk/platform_windows.c =================================================================== --- trunk/platform_windows.c 2008-01-14 01:01:23 UTC (rev 412) +++ trunk/platform_windows.c 2008-01-14 01:50:21 UTC (rev 413) @@ -1132,6 +1132,12 @@ } // MojoPlatform_isfile +void *MojoPlatform_stdout(void) +{ + return NULL; // unsupported on Windows. +} // MojoPlatform_stdout + + void *MojoPlatform_open(const char *fname, uint32 flags, uint16 mode) { HANDLE *retval = NULL; Modified: trunk/scripts/localization.lua =================================================================== --- trunk/scripts/localization.lua 2008-01-14 01:01:23 UTC (rev 412) +++ trunk/scripts/localization.lua 2008-01-14 01:50:21 UTC (rev 413) @@ -126,6 +126,10 @@ ["NOTICE: %0\n[hit enter]"] = { }; + -- That's meant to be the name of an item (%0) and the percent done (%1). + ["%0: %1%%"] = { + }; + ["%0 (total progress: %1%%)\n"] = { }; @@ -180,10 +184,10 @@ ["Cancel installation"] = { }; - ["cannot open archive."] = { + ["Can't enumerate archive"] = { }; - ["Can't enumerate archive"] = { + ["Can't open archive."] = { }; ["Choose install destination by number (hit enter for #1), or enter your own."] = { @@ -238,9 +242,12 @@ ["File creation failed!"] = { }; - ["file download failed!"] = { + ["File download failed!"] = { }; + ["File '$0' already exists! Replace?"] = { + }; + ["Finish"] = { }; @@ -272,7 +279,7 @@ ["Media change"] = { }; - ["mkdir failed"] = { + ["Directory creation failed"] = { }; ["need dictionary"] = { @@ -322,7 +329,7 @@ ["(stalled)"] = { }; - ["symlink creation failed!"] = { + ["Symlink creation failed!"] = { }; ["The installer has been stopped by the system."] = { Modified: trunk/scripts/mojosetup_mainline.lua =================================================================== --- trunk/scripts/mojosetup_mainline.lua 2008-01-14 01:01:23 UTC (rev 412) +++ trunk/scripts/mojosetup_mainline.lua 2008-01-14 01:50:21 UTC (rev 413) @@ -35,7 +35,6 @@ for i = max,1,-1 do local fname = filelist[i] if not do_delete(fname) and error_is_fatal then - -- !!! FIXME: formatting MojoSetup.fatal(_("Deletion failed!")) end @@ -77,7 +76,6 @@ local dest = MojoSetup.rollbacks[id] if not MojoSetup.movefile(src, dest) then -- we're already in fatal(), so we can only throw up a msgbox... - -- !!! FIXME: formatting MojoSetup.msgbox(_("Serious problem"), _("Couldn't restore some files. Your existing installation is likely damaged.")) end @@ -110,7 +108,6 @@ -- This gets called by fatal()...must be a global function. function MojoSetup.revertinstall() - -- !!! FIXME: language. if MojoSetup.gui_started then MojoSetup.gui.final(_("Incomplete installation. We will revert any changes we made.")) end @@ -219,7 +216,7 @@ -- This code's a little nasty... local function drill_for_archive(archive, path, arclist) if not MojoSetup.archive.enumerate(archive) then - MojoSetup.fatal(_("Couldn't enumerate archive.")) -- !!! FIXME: error message + MojoSetup.fatal(_("Couldn't enumerate archive.")) end local pathtab = split_path(path) @@ -237,7 +234,7 @@ -- open it as an archive and keep drilling... local arc = MojoSetup.archive.fromentry(archive) if arc == nil then - MojoSetup.fatal(_("Couldn't open archive.")) -- !!! FIXME: error message. + MojoSetup.fatal(_("Couldn't open archive.")) end arclist[#arclist+1] = arc if pathtab[i] == nil then @@ -249,14 +246,14 @@ ent = MojoSetup.archive.enumnext(archive) end - MojoSetup.fatal(_("Archive not found.")) -- !!! FIXME: error message. + MojoSetup.fatal(_("Archive not found.")) end local function install_file(dest, perms, writefn, desc, manifestkey) -- Upvalued so we don't look these up each time... local fname = string.gsub(dest, "^.*/", "", 1) -- chop the dirs off... - local ptype = _("Installing") -- !!! FIXME: localization. + local ptype = _("Installing") local component = desc local keepgoing = true local callback = function(ticks, justwrote, bw, total) @@ -265,7 +262,7 @@ if total >= 0 then MojoSetup.written = MojoSetup.written + justwrote percent = calc_percent(MojoSetup.written, MojoSetup.totalwrite) - item = fname .. ": " .. calc_percent(bw, total) .. "%" -- !!! FIXME: localization + item = MojoSetup.format(_("%0: %1%%"), fname, calc_percent(bw, total)) end keepgoing = MojoSetup.gui.progress(ptype, component, percent, item) return keepgoing @@ -288,7 +285,6 @@ local written, sums = writefn(callback) if not written then - -- !!! FIXME: formatting! if not keepgoing then MojoSetup.logerror("User cancelled install during file write.") MojoSetup.fatal() @@ -324,9 +320,8 @@ -- !!! FIXME: thousands of symlinks in a row or something. local function install_symlink(dest, lndest, manifestkey) if not MojoSetup.platform.symlink(dest, lndest) then - -- !!! FIXME: formatting! MojoSetup.logerror("Failed to create symlink '" .. dest .. "'") - MojoSetup.fatal(_("symlink creation failed!")) + MojoSetup.fatal(_("Symlink creation failed!")) end if manifestkey ~= nil then @@ -350,9 +345,8 @@ -- !!! FIXME: thousands of dirs in a row or something. local function install_directory(dest, perms, manifestkey) if not MojoSetup.platform.mkdir(dest, perms) then - -- !!! FIXME: formatting MojoSetup.logerror("Failed to create dir '" .. dest .. "'") - MojoSetup.fatal(_("mkdir failed")) + MojoSetup.fatal(_("Directory creation failed")) end if manifestkey ~= nil then @@ -404,7 +398,8 @@ if not allowoverwrite then -- !!! FIXME: language and formatting. MojoSetup.loginfo("File '" .. dest .. "' already exists.") - local ynan = MojoSetup.promptynan(_("Conflict!"), _("File already exists! Replace?"), true) + local text = MojoSetup.format(_("File '$0' already exists! Replace?"), dest); + local ynan = MojoSetup.promptynan(_("Conflict!"), text, true) if ynan == "always" then MojoSetup.forceoverwrite = true allowoverwrite = true @@ -427,7 +422,6 @@ install_parent_dirs(f, nil) MojoSetup.rollbacks[id] = dest if not MojoSetup.movefile(dest, f) then - -- !!! FIXME: formatting MojoSetup.fatal(_("Couldn't backup file for rollback")) end MojoSetup.loginfo("Moved rollback #" .. id .. ": '" .. dest .. "' -> '" .. f .. "'") @@ -472,7 +466,6 @@ elseif ent.type == "symlink" then install_symlink(dest, ent.linkdest, option) else -- !!! FIXME: device nodes, etc... - -- !!! FIXME: formatting! -- !!! FIXME: should this be fatal? MojoSetup.fatal(_("Unknown file type in archive")) end @@ -483,7 +476,6 @@ local function install_archive(archive, file, option) if not MojoSetup.archive.enumerate(archive) then - -- !!! FIXME: need formatting function. MojoSetup.fatal(_("Can't enumerate archive")) end @@ -562,8 +554,8 @@ local archive = MojoSetup.archive.fromdir(path) if archive == nil then archive = MojoSetup.archive.fromfile(path) - if archive == nil then -- !!! FIXME: error message. - MojoSetup.fatal(_("cannot open archive.")) + if archive == nil then + MojoSetup.fatal(_("Can't open archive.")) end end return archive @@ -583,7 +575,7 @@ local knowngood = path path = path .. "/" .. v if not MojoSetup.platform.exists(path) then - if knowngood == "" then -- !!! FIXME: error message. + if knowngood == "" then MojoSetup.fatal(_("Archive not found")) end local archive = create_basepath_archive(knowngood) @@ -1093,7 +1085,7 @@ -- Upvalued so we don't look these up each time... local url = file.source local fname = string.gsub(url, "^.*/", "", 1) -- chop the dirs off... - local ptype = _("Downloading") -- !!! FIXME: localization. + local ptype = _("Downloading") local component = option.description local bps = 0 local bpsticks = 0 @@ -1123,8 +1115,7 @@ MojoSetup.loginfo("Download '" .. url .. "' to '" .. f .. "'") local downloaded, sums = MojoSetup.download(url, f, callback) if not downloaded then - -- !!! FIXME: formatting! - MojoSetup.fatal(_("file download failed!")) + MojoSetup.fatal(_("File download failed!")) end MojoSetup.downloads[#MojoSetup.downloads+1] = f end @@ -1206,7 +1197,6 @@ -- Next stage: show results gui stages[#stages+1] = function(thisstage, maxstage) - -- !!! FIXME: language. MojoSetup.gui.final(_("Installation was successful.")) return 1 -- go forward. end From DONOTREPLY at icculus.org Mon Jan 14 03:38:21 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 14 Jan 2008 03:38:21 -0500 Subject: r414 - trunk/scripts Message-ID: <20080114083821.14778.qmail@icculus.org> Author: icculus Date: 2008-01-14 03:38:19 -0500 (Mon, 14 Jan 2008) New Revision: 414 Modified: trunk/scripts/mojosetup_init.lua Log: Crash out if there's a duplicate localization key, to catch subtle bugs. Modified: trunk/scripts/mojosetup_init.lua =================================================================== --- trunk/scripts/mojosetup_init.lua 2008-01-14 01:50:21 UTC (rev 413) +++ trunk/scripts/mojosetup_init.lua 2008-01-14 08:38:19 UTC (rev 414) @@ -134,6 +134,9 @@ local lang = string.gsub(locale, "_%w+", "", 1) -- make "en_US" into "en" MojoSetup.translations = {} for k,v in pairs(MojoSetup.localization) do + if MojoSetup.translations[k] ~= nil then + MojoSetup.fatal("BUG: Duplicate localization key ['" .. k .. "']") + end if type(v) == "table" then sanity_check_localization_entry(k, v) if v[locale] ~= nil then From DONOTREPLY at icculus.org Mon Jan 14 03:38:53 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 14 Jan 2008 03:38:53 -0500 Subject: r415 - trunk/scripts Message-ID: <20080114083853.15705.qmail@icculus.org> Author: icculus Date: 2008-01-14 03:38:53 -0500 (Mon, 14 Jan 2008) New Revision: 415 Modified: trunk/scripts/localization.lua trunk/scripts/mojosetup_mainline.lua Log: Cleaned up localization for download progress text. Modified: trunk/scripts/localization.lua =================================================================== --- trunk/scripts/localization.lua 2008-01-14 08:38:19 UTC (rev 414) +++ trunk/scripts/localization.lua 2008-01-14 08:38:53 UTC (rev 415) @@ -276,6 +276,26 @@ ["KB/s"] = { }; + -- Download rate when we don't know the goal (can't report time left). + -- This is a number ($0) followed by the localized "KB/s" or "B/s" ($1). + ["$0 $1"] = { + }; + + -- Download rate when we know the goal (can report time left). + -- This is a number ($0) followed by the localized "KB/s" or "B/s" ($1), + -- then the hours ($2), minutes ($3), and seconds ($4) remaining + ["$0 $1, $2:$3:$4 remaining"] = { + }; + + -- download rate when download isn't progressing at all. + ["stalled"] = { + }; + + -- Download progress string: filename ($0), percent downloaded ($1), + -- download rate determined in one of the above strings ($2). + ["$0: $1%% ($2)"] = { + }; + ["Media change"] = { }; @@ -325,10 +345,6 @@ ["Shutting down..."] = { }; - -- printed instead of kilobytes per second when download isn't progressing. - ["(stalled)"] = { - }; - ["Symlink creation failed!"] = { }; Modified: trunk/scripts/mojosetup_mainline.lua =================================================================== --- trunk/scripts/mojosetup_mainline.lua 2008-01-14 08:38:19 UTC (rev 414) +++ trunk/scripts/mojosetup_mainline.lua 2008-01-14 08:38:53 UTC (rev 415) @@ -139,44 +139,42 @@ end -local function make_bps_string(bps, bw, total) - -- !!! FIXME: localization on all this. - local bpsstr = nil +local function make_rate_string(rate, bw, total) + local retval = nil - if bps <= 0 then - bpsstr = _("(stalled)") + if rate <= 0 then + retval = _("stalled") else - local bytesleft = total - bw - local secsleft = MojoSetup.truncatenum(bytesleft / bps) - local minsleft = MojoSetup.truncatenum(secsleft / 60) - local hoursleft = MojoSetup.truncatenum(minsleft / 60) + local ratetype = _("B/s") + if rate > 1024 then + rate = MojoSetup.truncatenum(rate / 1024) + ratetype = _("KB/s") + end - secsleft = string.sub("00" .. (secsleft - (minsleft * 60)), -2) - minsleft = string.sub("00" .. (minsleft - (hoursleft * 60)), -2) + if total > 0 then -- can approximate time left if we know the goal. + local bytesleft = total - bw + local secsleft = MojoSetup.truncatenum(bytesleft / rate) + local minsleft = MojoSetup.truncatenum(secsleft / 60) + local hoursleft = MojoSetup.truncatenum(minsleft / 60) - if hoursleft < 10 then - hoursleft = "0" .. hoursleft - else - hoursleft = tostring(hoursleft) - end + secsleft = string.sub("00" .. (secsleft - (minsleft * 60)), -2) + minsleft = string.sub("00" .. (minsleft - (hoursleft * 60)), -2) - local timeleft = hoursleft .. ":" .. minsleft .. ":" .. secsleft - if bps > 1024 then - local kps = MojoSetup.truncatenum(bps / 1024) - if total > 0 then - bpsstr = " (" .. kps .. _("Kb/s") .. ", " .. timeleft .. " remaining)" + if hoursleft < 10 then + hoursleft = "0" .. hoursleft else - bpsstr = " (" .. kps .. _("Kb/s") .. ")" + hoursleft = tostring(hoursleft) end + + retval = MojoSetup.format(_("$0 $1, $2:$3:$4 remaining"), + rate, ratetype, + hoursleft, minsleft, secsleft) else - if total > 0 then - bpsstr = " (" .. bps .. _("b/s") .. ", " .. timeleft .. " remaining)" - else - bpsstr = " (" .. bps .. _("b/s") .. ")" - end + retval = MojoSetup.format(_("$0 $1"), rate, ratetype) end end - return bpsstr + + return retval end @@ -1089,7 +1087,7 @@ local component = option.description local bps = 0 local bpsticks = 0 - local bpsstr = '' + local ratestr = '' local item = fname local percent = -1 local callback = function(ticks, justwrote, bw, total) @@ -1098,7 +1096,7 @@ bpsticks = ticks + 1000 else if ticks >= bpsticks then - bpsstr = make_bps_string(bps, bw, total) + ratestr = make_rate_string(bps, bw, total) bpsticks = ticks + 1000 bps = 0 end @@ -1107,7 +1105,10 @@ percent = calc_percent(MojoSetup.downloaded, MojoSetup.totaldownload) - item = fname .. ": " .. calc_percent(bw, total) .. "%" .. bpsstr -- !!! FIXME: localization + item = MojoSetup.format(_("$0: $1%% ($2)"), + fname, + calc_percent(bw, total), + ratestr); end return MojoSetup.gui.progress(ptype, component, percent, item) end From DONOTREPLY at icculus.org Mon Jan 14 04:09:15 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 14 Jan 2008 04:09:15 -0500 Subject: r416 - trunk/scripts Message-ID: <20080114090915.28543.qmail@icculus.org> Author: icculus Date: 2008-01-14 04:08:47 -0500 (Mon, 14 Jan 2008) New Revision: 416 Modified: trunk/scripts/localization.lua trunk/scripts/mojosetup_init.lua trunk/scripts/mojosetup_mainline.lua Log: Cleaned up localization for config schema verification. Modified: trunk/scripts/localization.lua =================================================================== --- trunk/scripts/localization.lua 2008-01-14 08:38:53 UTC (rev 415) +++ trunk/scripts/localization.lua 2008-01-14 09:08:47 UTC (rev 416) @@ -50,6 +50,9 @@ -- The table you create here goes away shortly after creation, as the relevant -- parts of it get moved somewhere else. You should call MojoSetup.translate() -- to get the proper translation for a given string. +-- +-- Questions about the intent of a specific string can go to Ryan C. Gordon +-- (icculus at icculus.org). MojoSetup.localization = { -- zlib error message @@ -175,6 +178,77 @@ ["BUG: Unhandled data type"] = { }; + -- Buggy config elements: + -- This is supposed to be a config element ($0) and something that's wrong + -- with it ($1), such as "BUG: Config Package::description not a string" + -- The grammar can be imperfect here; this is a developer error, not an + -- end-user error, so we haven't made this very flexible. + ["BUG: Config $0 $1."] = { + }; + + -- This is an error string for a buggy config element. See notes above. + ["must be explicitly specified"] = { + }; + + -- This is an error string for a buggy config element. See notes above. + ["must be string or table of strings"] = { + }; + + -- This is an error string for a buggy config element. See notes above. + ["must be a string or number"] = { + }; + + -- This is an error string for a buggy config element. See notes above. + ["can't be empty string"] = { + }; + + -- This is an error string for a buggy config element. See notes above. + ["URL doesn't have protocol"] = { + }; + + -- This is an error string for a buggy config element. See notes above. + ["URL doesn't have host"] = { + }; + + -- This is an error string for a buggy config element. See notes above. + ["URL doesn't have path"] = { + }; + + -- This is an error string for a buggy config element. See notes above. + ["URL protocol is unsupported"] = { + }; + + -- This is an error string for a buggy config element. See notes above. + ["Permission string is invalid"] = { + }; + + -- This is an error string for a buggy config element. See notes above. + ["is not a valid property"] = { + }; + + -- This is an error string for a buggy config element. See notes above. + -- $0 is a data type name (string, number, table, etc). + ["must be $0"] = { + }; + + -- Data types for "must be $0" above... + ["string"] = { + }; + + ["boolean"] = { + }; + + ["number"] = { + }; + + ["function"] = { + }; + + ["table"] = { + }; + + + ["bzlib triggered an internal error: %0"] = { }; Modified: trunk/scripts/mojosetup_init.lua =================================================================== --- trunk/scripts/mojosetup_init.lua 2008-01-14 08:38:53 UTC (rev 415) +++ trunk/scripts/mojosetup_init.lua 2008-01-14 09:08:47 UTC (rev 416) @@ -19,6 +19,8 @@ -- then this code executes to do the heavy lifting. All Lua state should be -- sane for the rest of the app once this script successfully completes. +local _ = MojoSetup.translate + MojoSetup.loginfo("MojoSetup Lua initialization at " .. MojoSetup.date()) MojoSetup.loginfo("buildver: " .. MojoSetup.info.buildver) MojoSetup.loginfo("locale: " .. MojoSetup.info.locale) @@ -159,26 +161,29 @@ end - -- Our namespace for this API...this is filled in with the rest of this file. Setup = {} local function schema_assert(test, fnname, elem, errstr) if not test then - -- !!! FIXME: error()? localization? - error(fnname .. "::" .. elem .. " " .. errstr .. ".", 0) + local msg = MojoSetup.format(_("BUG: Config $0 $1."), + fnname .. "::" .. elem, errstr) + MojoSetup.fatal(msg) end end local function mustExist(fnname, elem, val) - schema_assert(val ~= nil, fnname, elem, "must be explicitly specified") + schema_assert(val ~= nil, fnname, elem, _("must be explicitly specified")) end local function mustBeSomething(fnname, elem, val, elemtype) -- Can be nil...please use mustExist if this is a problem! if val ~= nil then - schema_assert(type(val) == elemtype, fnname, elem, - "must be a " .. elemtype) + if type(val) ~= elemtype then + local msg = MojoSetup.format(_("must be $0"), + MojoSetup.translate(elemtype)) + schema_assert(false, fnname, elem, msg) + end end end @@ -205,21 +210,20 @@ local function cantBeEmpty(fnname, elem, val) -- Can be nil...please use mustExist if this is a problem! if val ~= nil then - schema_assert(val ~= "", fnname, elem, "can't be empty string") + schema_assert(val ~= "", fnname, elem, _("can't be empty string")) end end local function mustBeStringOrTableOfStrings(fnname, elem, val) -- Can be nil...please use mustExist if this is a problem! if val ~= nil then + local err = _("must be string or table of strings") if type(val) == "string" then val = { val } end - schema_assert(type(val) == "table", fnname, elem, - "must be string or table of strings") + schema_assert(type(val) == "table", fnname, elem, err) for k,v in pairs(val) do - schema_assert(type(v) == "string", fnname, elem, - "must be string or table of strings") + schema_assert(type(v) == "string", fnname, elem, err) end end end @@ -229,7 +233,7 @@ if val ~= nil then local t = type(val) schema_assert((t == "string") or (t == "number"), fnname, elem, - "must be a string or number") + _("must be a string or number")) end end @@ -238,19 +242,19 @@ cantBeEmpty(fnname, elem, val) if (val ~= nil) then local prot,host,path = MojoSetup.spliturl(val) - schema_assert(prot ~= nil, fnname, elem, "URL doesn't have protocol") - schema_assert(host ~= nil, fnname, elem, "URL doesn't have host") - schema_assert(path ~= nil, fnname, elem, "URL doesn't have path") + schema_assert(prot ~= nil,fnname,elem,_("URL doesn't have protocol")) + schema_assert(host ~= nil,fnname,elem,_("URL doesn't have host")) + schema_assert(path ~= nil,fnname,elem,_("URL doesn't have path")) prot = string.gsub(prot, "://$", "") local supported = MojoSetup.info.supportedurls[prot] - schema_assert(supported, fnname, elem, "URL protocol is unsupported") + schema_assert(supported,fnname,elem,_("URL protocol is unsupported")) end end local function mustBePerms(fnname, elem, val) mustBeString(fnname, elem, val) local valid = MojoSetup.isvalidperms(val) - schema_assert(valid, fnname, elem, "Permission string is invalid") + schema_assert(valid, fnname, elem, _("Permission string is invalid")) end local function sanitize(fnname, tab, elems) @@ -270,6 +274,7 @@ end end + local notvaliderr = _("is not a valid property") for k,v in pairs(tab) do local found = false if k == "_type_" then @@ -285,7 +290,7 @@ end end end - schema_assert(found, fnname, k, "is not a valid property") + schema_assert(found, fnname, k, notvaliderr) end return tab Modified: trunk/scripts/mojosetup_mainline.lua =================================================================== --- trunk/scripts/mojosetup_mainline.lua 2008-01-14 08:38:53 UTC (rev 415) +++ trunk/scripts/mojosetup_mainline.lua 2008-01-14 09:08:47 UTC (rev 416) @@ -11,7 +11,6 @@ -- !!! FIXME: add a --dryrun option. --- This is just for convenience. local _ = MojoSetup.translate local function do_delete(fname) From DONOTREPLY at icculus.org Mon Jan 14 04:27:00 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 14 Jan 2008 04:27:00 -0500 Subject: r417 - in trunk: . scripts Message-ID: <20080114092700.17742.qmail@icculus.org> Author: icculus Date: 2008-01-14 04:26:46 -0500 (Mon, 14 Jan 2008) New Revision: 417 Modified: trunk/archive_tar.c trunk/scripts/localization.lua trunk/scripts/mojosetup_mainline.lua Log: A few more minor localization tweaks and FIXME fixes. Modified: trunk/archive_tar.c =================================================================== --- trunk/archive_tar.c 2008-01-14 09:08:47 UTC (rev 416) +++ trunk/archive_tar.c 2008-01-14 09:26:46 UTC (rev 417) @@ -483,7 +483,7 @@ static MojoInput *MojoInput_tar_duplicate(MojoInput *io) { MojoInput *retval = NULL; - fatal("BUG: Can't duplicate tar inputs"); // !!! FIXME: why not? + fatal(_("BUG: Can't duplicate tar inputs")); // !!! FIXME: why not? #if 0 TARinput *input = (TARinput *) io->opaque; MojoInput *origio = (MojoInput *) io->opaque; Modified: trunk/scripts/localization.lua =================================================================== --- trunk/scripts/localization.lua 2008-01-14 09:08:47 UTC (rev 416) +++ trunk/scripts/localization.lua 2008-01-14 09:26:46 UTC (rev 417) @@ -178,6 +178,10 @@ ["BUG: Unhandled data type"] = { }; + -- "tar" is a proper name in this case. + ["BUG: Can't duplicate tar inputs"] = { + }; + -- Buggy config elements: -- This is supposed to be a config element ($0) and something that's wrong -- with it ($1), such as "BUG: Config Package::description not a string" Modified: trunk/scripts/mojosetup_mainline.lua =================================================================== --- trunk/scripts/mojosetup_mainline.lua 2008-01-14 09:08:47 UTC (rev 416) +++ trunk/scripts/mojosetup_mainline.lua 2008-01-14 09:26:46 UTC (rev 417) @@ -393,7 +393,6 @@ -- !!! FIXME: option/package-wide overwrite? allowoverwrite = file.allowoverwrite if not allowoverwrite then - -- !!! FIXME: language and formatting. MojoSetup.loginfo("File '" .. dest .. "' already exists.") local text = MojoSetup.format(_("File '$0' already exists! Replace?"), dest); local ynan = MojoSetup.promptynan(_("Conflict!"), text, true) From DONOTREPLY at icculus.org Mon Jan 14 16:26:12 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 14 Jan 2008 16:26:12 -0500 Subject: r418 - trunk Message-ID: <20080114212612.19852.qmail@icculus.org> Author: icculus Date: 2008-01-14 16:26:12 -0500 (Mon, 14 Jan 2008) New Revision: 418 Modified: trunk/platform_unix.c Log: Added a FIXME comment. Modified: trunk/platform_unix.c =================================================================== --- trunk/platform_unix.c 2008-01-14 09:26:46 UTC (rev 417) +++ trunk/platform_unix.c 2008-01-14 21:26:12 UTC (rev 418) @@ -447,6 +447,10 @@ boolean MojoPlatform_osVersion(char *buf, size_t len) { #if PLATFORM_MACOSX + // !!! FIXME: this is wrong...it doesn't with with 10.y.xx, where 'xx' + // !!! FIXME: is more than one digit (it appears to clamp to 9 in these + // !!! FIXME: cases inside Gestalt(), for obvious reasons). + // !!! FIXME: This is a legacy--and incorrect--way to get this information. long ver = 0x0000; if (Gestalt(gestaltSystemVersion, &ver) == noErr) { From DONOTREPLY at icculus.org Mon Jan 14 16:29:01 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 14 Jan 2008 16:29:01 -0500 Subject: r419 - trunk/scripts Message-ID: <20080114212901.26527.qmail@icculus.org> Author: icculus Date: 2008-01-14 16:29:01 -0500 (Mon, 14 Jan 2008) New Revision: 419 Modified: trunk/scripts/localization.lua Log: Norwegian/Bokmal translation (thanks, Gerry JJ!). Modified: trunk/scripts/localization.lua =================================================================== --- trunk/scripts/localization.lua 2008-01-14 21:26:12 UTC (rev 418) +++ trunk/scripts/localization.lua 2008-01-14 21:29:01 UTC (rev 419) @@ -57,69 +57,86 @@ MojoSetup.localization = { -- zlib error message ["need dictionary"] = { + nb = "trenger ordbok", }; -- zlib error message ["data error"] = { + nb = "datafeil", }; -- zlib error message ["memory error"] = { + nb = "minnefeil", }; -- zlib error message ["buffer error"] = { + nb = "bufferfeil", }; -- zlib error message ["version error"] = { + nb = "versjonsfeil", }; -- zlib error message ["unknown error"] = { + nb = "ukjent feil", }; -- stdio GUI plugin says this for msgboxes. ["NOTICE: %0\n[hit enter]"] = { + nb = "NB: %0\n[trykk enter]", }; -- stdio GUI plugin says this for yes/no prompts that default to yes. ["%0\n[Y/n]: "] = { + nb = "%0\n[J/n]: ", }; -- stdio GUI plugin says this for yes/no prompts that default to no. ["%0\n[y/N]: "] = { + nb = "%0\n[j/N]: ", }; -- stdio GUI plugin says this for yes/no/always/never prompts. ["%0\n[y/n/Always/Never]: "] = { + nb = "%0\n[j/n/Alltid/Aldri]: ", }; -- This is utf8casecmp()'d for "yes" answers in stdio GUI's promptyn(). ["Y"] = { + nb = "J", }; -- This is utf8casecmp()'d for "no" answers in stdio GUI's promptyn(). ["N"] = { + nb = "N", }; -- This is shown when using stdio GUI's built-in README pager (printf format). ["(%0-%1 of %2 lines, see more?)"] = { + nb = "(%0-%1 av %2 linjer, se mer?)", }; -- This is utf8casecmp()'d for "always" answers in stdio GUI's promptyn(). ["Always"] = { + nb = "Alltid", }; -- This is utf8casecmp()'d for "never" answers in stdio GUI's promptyn(). ["Never"] = { + nb = "Aldri", }; ["Type '%0' to go back."] = { + nb = "Skriv '%0' for ? g? tilbake.", }; -- This is the string used for the '%0' in the above string. ["back"] = { + nb = "tilbake", }; -- This is the prompt in the stdio driver when user input is expected. @@ -127,33 +144,42 @@ }; ["NOTICE: %0\n[hit enter]"] = { + nb = "NB: %0\n[trykk enter]", --DUP? }; -- That's meant to be the name of an item (%0) and the percent done (%1). ["%0: %1%%"] = { + nb = "%0: %1%%", }; ["%0 (total progress: %1%%)\n"] = { + nb = "%0 (totalt: %1%%)\n", }; ["Accept this license?"] = { + nb = "Akseptere denne lisensen?", }; -- This is a GTK+ button label. The '_' comes after the hotkey character. ["_Always"] = { + nb = "_Alltid", }; ["Archive not found."] = { + nb = "Fant ikke arkiv.", }; ["Are you sure you want to cancel installation?"] = { + nb = "Er du sikker p? at du vil avbryte installasjonen?", }; ["Back"] = { + nb = "Tilbake", }; -- This is a GTK+ button label. The '_' comes after the hotkey character. ["B_rowse..."] = { + nb = "B_la gjennom...", }; -- "bytes per second" @@ -161,25 +187,32 @@ }; ["BUG: '%0' is not a valid permission string"] = { + nb = "FEIL: '%0' er ikke en gyldig rettighetsstreng", }; ["BUG: Invalid format() string"] = { + nb = "FEIL: Ugyldig format()-streng", }; ["BUG: stage returned wrong type."] = { + nb = "FEIL: niv? returnerte feil type.", }; ["BUG: stage returned wrong value."] = { + nb = "FEIL: niv? returnerte feil verdi.", }; ["BUG: stepped back over start of stages"] = { + nb = "FEIL: Gikk tilbake forbi startniv?", }; ["BUG: Unhandled data type"] = { + nb = "FEIL: Uh?ndtert datatype", }; -- "tar" is a proper name in this case. ["BUG: Can't duplicate tar inputs"] = { + nb = "FEIL: Kan ikke duplisere innfiler for tar", }; -- Buggy config elements: @@ -188,166 +221,215 @@ -- The grammar can be imperfect here; this is a developer error, not an -- end-user error, so we haven't made this very flexible. ["BUG: Config $0 $1."] = { + nb = "FEIL: Konfigurasjon $0 $1.", }; -- This is an error string for a buggy config element. See notes above. ["must be explicitly specified"] = { + nb = "m? gis eksplisitt", }; -- This is an error string for a buggy config element. See notes above. ["must be string or table of strings"] = { + nb = "m? v?re streng eller tabell av strenger", }; -- This is an error string for a buggy config element. See notes above. ["must be a string or number"] = { + nb = "m? v?re streng eller nummer", }; -- This is an error string for a buggy config element. See notes above. ["can't be empty string"] = { + nb = "kan ikke v?re tom streng", }; -- This is an error string for a buggy config element. See notes above. ["URL doesn't have protocol"] = { + nb = "URL har ikke protokoll", }; -- This is an error string for a buggy config element. See notes above. ["URL doesn't have host"] = { + nb = "URL har ikke vert", }; -- This is an error string for a buggy config element. See notes above. ["URL doesn't have path"] = { + nb = "URL har ikke sti", }; -- This is an error string for a buggy config element. See notes above. ["URL protocol is unsupported"] = { + nb = "URL-protokoll er ikke st?ttet", }; -- This is an error string for a buggy config element. See notes above. ["Permission string is invalid"] = { + nb = "Rettighetsstreng er ugyldig", }; -- This is an error string for a buggy config element. See notes above. ["is not a valid property"] = { + nb = "er ikke en gyldig egenskap", }; -- This is an error string for a buggy config element. See notes above. -- $0 is a data type name (string, number, table, etc). ["must be $0"] = { + nb = "m? v?re $0", }; -- Data types for "must be $0" above... ["string"] = { + nb = "streng", }; ["boolean"] = { + nb = "boolsk verdi", }; ["number"] = { + nb = "nummer", }; ["function"] = { + nb = "funksjon", }; ["table"] = { + nb = "tabell", }; ["bzlib triggered an internal error: %0"] = { + nb = "intern feil i bzlib: %0", }; ["Cancel"] = { + nb = "Avbryt", }; ["Cancel installation"] = { + nb = "Avbryt installasjonen", }; ["Can't enumerate archive"] = { + nb = "Kan ikke enumerere arkiv", }; ["Can't open archive."] = { + nb = "Kan ikke ?pne arkiv.", }; ["Choose install destination by number (hit enter for #1), or enter your own."] = { + nb = "Velg installasjonssti etter nummer (trykk enter for #1), eller skriv din egen.", }; ["Choose number to change."] = { + nb = "Velg nummer som skal endres.", }; ["Config bug: duplicate media id"] = { + nb = "Konfigurasjonsfeil: duplisert media-id", }; ["Config bug: no options"] = { + nb = "Konfigurasjonsfeil: ingen valg", }; -- As in "two different files want to use the same name" ["Conflict!"] = { + nb = "Konflikt!", }; ["Couldn't backup file for rollback"] = { + nb = "Kunne ikke sikkerhetskopiere fil for tilbakerulling", }; ["Couldn't create manifest"] = { + nb = "Kunne ikke lage manifest", }; ["Couldn't enumerate archive."] = { + nb = "Kunne ikke enumerere arkiv.", }; ["Couldn't open archive."] = { + nb = "Kunne ikke ?pne arkiv.", }; ["Couldn't restore some files. Your existing installation is likely damaged."] = { + nb = "Noen filer kunne ikke tilbakestilles. Den eksisterende installasjonen er sannsynligvis skadet.", }; ["Deletion failed!"] = { + nb = "Kunne ikke slette!", }; ["Destination"] = { + nb = "Destinasjon", }; ["Downloading"] = { + nb = "Laster ned", }; ["Enter path where files will be installed."] = { + nb = "Skriv inn destinasjonssti for installasjonen.", }; ["failed to load file '%0'"] = { + nb = "kunne ikke laste fil '%0'", }; ["Fatal error"] = { + nb = "Fatal feil", }; ["File creation failed!"] = { + nb = "Kunne ikke lage fil!", }; ["File download failed!"] = { + nb = "Kunne ikke laste ned fil!", }; ["File '$0' already exists! Replace?"] = { + nb = "Filen '$0' eksisterer allerede! Skrive over?", }; ["Finish"] = { + nb = "Ferdig", }; ["GUI failed to start"] = { + nb = "Kunne ikke starte grafisk grensesnitt", }; ["Incomplete installation. We will revert any changes we made."] = { + nb = "Installasjonen ble ikke ferdig. Vi vil tilbakestille alle endringer som ble gjort.", }; ["Installation location"] = { + nb = "Installasjonssti", }; ["Installation was successful."] = { + nb = "Installasjonen var en suksess.", }; ["Installing"] = { + nb = "Installerer", }; ["Install options:"] = { + nb = "Installasjonsvalg:", }; ["(I want to specify a path.)"] = { + nb = "(Jeg vil skrive min egen sti.)", }; -- "kilobytes per second" @@ -363,10 +445,12 @@ -- This is a number ($0) followed by the localized "KB/s" or "B/s" ($1), -- then the hours ($2), minutes ($3), and seconds ($4) remaining ["$0 $1, $2:$3:$4 remaining"] = { + nb = "$0 $1, $2:$3:$4 igjen", }; -- download rate when download isn't progressing at all. ["stalled"] = { + nb = "st?r fast", }; -- Download progress string: filename ($0), percent downloaded ($1), @@ -375,77 +459,101 @@ }; ["Media change"] = { + nb = "Mediaendring", }; ["Directory creation failed"] = { + nb = "Kunne ikke lage katalog", }; ["need dictionary"] = { + nb = "trenger ordbok", }; -- This is a GTK+ button label. The '_' comes after the hotkey character. ["N_ever"] = { + nb = "Al_dri", }; ["Next"] = { + nb = "Neste", }; ["No"] = { + nb = "Nei", }; ["No networking support in this build."] = { + nb = "Nettverksst?tte er ikke aktivert i denne versjonen.", }; ["Not Found"] = { + nb = "Ikke funnet", }; ["Nothing to do!"] = { + nb = "Ingenting ? gj?re!", }; ["OK"] = { + nb = "OK", }; ["Options"] = { + nb = "Valg", }; ["PANIC"] = { + nb = "PANIKK", }; ["Please insert '%0'"] = { + nb = "Sett inn '%0'", }; ["Press enter to continue."] = { + nb = "Trykk enter for ? fortsette.", }; ["Serious problem"] = { + nb = "Alvorlig problem", }; ["Shutting down..."] = { + nb = "Avslutter...", }; ["Symlink creation failed!"] = { + nb = "Kunne likke lage symbolsk lenke!", }; ["The installer has been stopped by the system."] = { + nb = "Installasjonsprogrammet ble stoppet av systemet.", }; ["The installer has crashed due to a bug."] = { + nb = "Installasjonsprogrammet kr?sjet pga. en feil.", }; -- This is a button label in the ncurses ui. ["Toggle"] = { + nb = "Inverter valg", }; ["Unknown file type in archive"] = { + nb = "Ukjent filtype i arkivet", }; ["Yes"] = { + nb = "Ja", }; ["You must accept the license before you may install"] = { + nb = "Lisensen m? godkjennes f?r du kan installere", }; ["Metadata"] = { + nb ="Metadata", }; }; From DONOTREPLY at icculus.org Mon Jan 14 16:34:20 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 14 Jan 2008 16:34:20 -0500 Subject: r420 - trunk/scripts Message-ID: <20080114213420.4077.qmail@icculus.org> Author: icculus Date: 2008-01-14 16:34:19 -0500 (Mon, 14 Jan 2008) New Revision: 420 Modified: trunk/scripts/mojosetup_init.lua Log: Remap some legacy language strings. Modified: trunk/scripts/mojosetup_init.lua =================================================================== --- trunk/scripts/mojosetup_init.lua 2008-01-14 21:29:01 UTC (rev 419) +++ trunk/scripts/mojosetup_init.lua 2008-01-14 21:34:19 UTC (rev 420) @@ -130,10 +130,21 @@ MojoSetup.localization = nil end +-- Map some legacy language identifiers into updated equivalents. +local lang_remap = +{ + no = "nb", -- "Norwegian" split into "Bokmal" (nb) and "Nynorsk" (nn) +} + if MojoSetup.localization ~= nil then local at_least_one = false local locale = MojoSetup.info.locale local lang = string.gsub(locale, "_%w+", "", 1) -- make "en_US" into "en" + + if lang_remap[lang] ~= nil then + lang = lang_remap[lang] + end + MojoSetup.translations = {} for k,v in pairs(MojoSetup.localization) do if MojoSetup.translations[k] ~= nil then From DONOTREPLY at icculus.org Mon Jan 14 20:16:32 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 14 Jan 2008 20:16:32 -0500 Subject: r421 - in trunk: . scripts Message-ID: <20080115011632.23561.qmail@icculus.org> Author: icculus Date: 2008-01-14 20:16:32 -0500 (Mon, 14 Jan 2008) New Revision: 421 Modified: trunk/fileio.c trunk/gui_gtkplus2.c trunk/gui_stdio.c trunk/gui_www.c trunk/scripts/localization.lua trunk/scripts/mojosetup_init.lua trunk/scripts/mojosetup_mainline.lua Log: Added German translation (thanks, Dennis Schridde!), improved comments in localization.lua, and cleaned up some more localization mistakes and inconsistencies that Dennis pointed out. Modified: trunk/fileio.c =================================================================== --- trunk/fileio.c 2008-01-14 21:34:19 UTC (rev 420) +++ trunk/fileio.c 2008-01-15 01:16:32 UTC (rev 421) @@ -692,7 +692,7 @@ #if !SUPPORT_URL_HTTP && !SUPPORT_URL_FTP MojoInput *MojoInput_fromURL(const char *url) { - logError(_("No networking support in this build.")); + logError("No networking support in this build."); return NULL; } // MojoInput_fromURL #endif Modified: trunk/gui_gtkplus2.c =================================================================== --- trunk/gui_gtkplus2.c 2008-01-14 21:34:19 UTC (rev 420) +++ trunk/gui_gtkplus2.c 2008-01-15 01:16:32 UTC (rev 421) @@ -160,7 +160,7 @@ static void signal_browse_clicked(GtkButton *_button, gpointer data) { GtkWidget *dialog = gtk_file_chooser_dialog_new ( - entry->_("Installation location"), + entry->_("Destination"), NULL, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, @@ -735,7 +735,6 @@ build_options(opts, box, TRUE); - // !!! FIXME: better text. retval = run_wizard(entry->_("Options"), PAGE_OPTIONS, can_back, can_fwd); gtk_widget_destroy(box); return retval; Modified: trunk/gui_stdio.c =================================================================== --- trunk/gui_stdio.c 2008-01-14 21:34:19 UTC (rev 420) +++ trunk/gui_stdio.c 2008-01-15 01:16:32 UTC (rev 421) @@ -485,8 +485,8 @@ static int MojoGui_stdio_options(MojoGuiSetupOptions *opts, boolean can_back, boolean can_fwd) { + const char *inst_opts_str = entry->xstrdup(entry->_("Options")); const char *prompt = entry->xstrdup(entry->_("Choose number to change.")); - const char *inst_opts_str = entry->xstrdup(entry->_("Install options:")); int retval = -1; boolean getout = false; char buf[128]; @@ -591,6 +591,7 @@ char buf[32]; char *fmt = entry->xstrdup(entry->_("Please insert '%0'")); char *msg = entry->format(fmt, medianame); + printf("%s\n", entry->_("Media change")); printf("%s\n", msg); free(msg); free(fmt); @@ -625,7 +626,7 @@ printf("%s\n", item); else { - fmt = entry->xstrdup(entry->_("%0 (total progress: %1%%)\n")); + fmt = entry->xstrdup(entry->_("%0 (total progress: %1%%)")); msg = entry->format(fmt, item, entry->numstr(percent)); printf("%s\n", msg); free(msg); Modified: trunk/gui_www.c =================================================================== --- trunk/gui_www.c 2008-01-14 21:34:19 UTC (rev 420) +++ trunk/gui_www.c 2008-01-15 01:16:32 UTC (rev 421) @@ -624,8 +624,7 @@ { // Catch any waiting browser connections...and tell them to buzz off! :) char *donetitle = htmlescape(entry->_("Shutting down...")); - char *donetext = htmlescape(entry->_( - "Setup program is shutting down. You can close this browser now.")); + char *donetext = htmlescape(entry->_("You can close this browser now.")); size_t len = 0, alloc = 0; char *html = NULL; @@ -862,6 +861,8 @@ static int MojoGui_www_options(MojoGuiSetupOptions *opts, boolean can_back, boolean can_fwd) { + // !!! FIXME: write me. + STUBBED("www options"); return 1; } // MojoGui_www_options Modified: trunk/scripts/localization.lua =================================================================== --- trunk/scripts/localization.lua 2008-01-14 21:34:19 UTC (rev 420) +++ trunk/scripts/localization.lua 2008-01-15 01:16:32 UTC (rev 421) @@ -44,6 +44,9 @@ -- in all reasonable tests, then finding out that one guy in Ghana has a -- crashing installer because his localization forgot to add a %1 somewhere. -- +-- Occasionally you might see a "\n" ... that's a newline character. "\t" is +-- a tab character, and "\\" turns into a single "\" character. +-- -- You should leave the existing strings here. They aren't hurting anything, -- and most are used by MojoSetup itself. Add your own, if needed, though. -- @@ -57,503 +60,756 @@ MojoSetup.localization = { -- zlib error message ["need dictionary"] = { - nb = "trenger ordbok", + de = "W?rterbuch ben?tigt", + nb = "trenger ordbok", }; -- zlib error message ["data error"] = { - nb = "datafeil", + de = "Datenfehler", + nb = "datafeil", }; -- zlib error message ["memory error"] = { - nb = "minnefeil", + de = "Speicherfehler", + nb = "minnefeil", }; -- zlib error message ["buffer error"] = { - nb = "bufferfeil", + de = "Pufferfehler", + nb = "bufferfeil", }; -- zlib error message ["version error"] = { - nb = "versjonsfeil", + de = "Versionsfehler", + nb = "versjonsfeil", }; -- zlib error message ["unknown error"] = { - nb = "ukjent feil", + de = "Unbekannter Fehler", + nb = "ukjent feil", }; - -- stdio GUI plugin says this for msgboxes. + -- stdio UI plugin says this for "OK"-only msgboxes. "%0" is the message + -- box's text content. ["NOTICE: %0\n[hit enter]"] = { - nb = "NB: %0\n[trykk enter]", + de = "HINWEIS: %0\n[Dr?cken Sie Enter]", + nb = "NB: %0\n[trykk enter]", }; - -- stdio GUI plugin says this for yes/no prompts that default to yes. + -- stdio UI plugin says this for yes/no prompts that default to yes. + -- "%0" is the question the user is being asked to respond to. ["%0\n[Y/n]: "] = { - nb = "%0\n[J/n]: ", + de = "%0\n[J/n]", + nb = "%0\n[J/n]: ", }; - -- stdio GUI plugin says this for yes/no prompts that default to no. + -- stdio UI plugin says this for yes/no prompts that default to no. + -- "%0" is the question the user is being asked to respond to. ["%0\n[y/N]: "] = { - nb = "%0\n[j/N]: ", + de = "%0\n[j/N]", + nb = "%0\n[j/N]: ", }; - -- stdio GUI plugin says this for yes/no/always/never prompts. + -- stdio UI plugin says this for yes/no/always/never prompts. + -- "%0" is the question the user is being asked to respond to. ["%0\n[y/n/Always/Never]: "] = { - nb = "%0\n[j/n/Alltid/Aldri]: ", + de = "%0\n[j/n/Immer/Niemals]", + nb = "%0\n[j/n/Alltid/Aldri]: ", }; - -- This is utf8casecmp()'d for "yes" answers in stdio GUI's promptyn(). + -- This is used for "yes" in stdio UI's yes/no prompts (case insensitive). ["Y"] = { - nb = "J", + de = "J", + nb = "J", }; - -- This is utf8casecmp()'d for "no" answers in stdio GUI's promptyn(). + -- This is used for "no" in stdio UI's yes/no prompts (case insensitive). ["N"] = { - nb = "N", + de = "N", + nb = "N", }; - -- This is shown when using stdio GUI's built-in README pager (printf format). - ["(%0-%1 of %2 lines, see more?)"] = { - nb = "(%0-%1 av %2 linjer, se mer?)", - }; - - -- This is utf8casecmp()'d for "always" answers in stdio GUI's promptyn(). + -- This is used for "always" in stdio UI's yes/no/always/never prompts + -- (case insensitive). ["Always"] = { - nb = "Alltid", + de = "Immer", + nb = "Alltid", }; - -- This is utf8casecmp()'d for "never" answers in stdio GUI's promptyn(). + -- This is used for "never" in stdio UI's yes/no/always/never prompts + -- (case insensitive). ["Never"] = { - nb = "Aldri", + de = "Niemals", + nb = "Aldri", }; + -- This is shown when using stdio UI's built-in README pager, to + -- show what range of lines of text are being displayed (%0 is first + -- line, %1 is last line, %2 is the total number of lines of text). + ["(%0-%1 of %2 lines, see more?)"] = { + de = "(%0-%1 von %2 Zeilen, mehr anschauen?)", + nb = "(%0-%1 av %2 linjer, se mer?)", + }; + + -- The stdio UI uses this sentence in the prompt if the user is able + -- to return to a previous stage of installation (from the options + -- section to the "choose installation destination" section, etc). ["Type '%0' to go back."] = { - nb = "Skriv '%0' for ? g? tilbake.", + de = "Dr?cken Sie '%0' um zur?ckzugehen.", + nb = "Skriv '%0' for ? g? tilbake.", }; -- This is the string used for the '%0' in the above string. + -- This is only for the stdio UI, so choose something easy and + -- reasonable for the user to manually type. The UIs use a different + -- string for their button ("Back" vs "back" specifically). ["back"] = { - nb = "tilbake", + de = "zur?ck", -- FIXME Does this name a button? Which one??? + nb = "tilbake", }; -- This is the prompt in the stdio driver when user input is expected. ["> "] = { + de = "> ", + nb = "> ", }; - ["NOTICE: %0\n[hit enter]"] = { - nb = "NB: %0\n[trykk enter]", --DUP? - }; - -- That's meant to be the name of an item (%0) and the percent done (%1). ["%0: %1%%"] = { - nb = "%0: %1%%", + de = "%0: %1%%", + nb = "%0: %1%%", }; - ["%0 (total progress: %1%%)\n"] = { - nb = "%0 (totalt: %1%%)\n", + -- The stdio UI uses this to show current status (%0), + -- and overall progress as percentage of work complete (%1). + ["%0 (total progress: %1%%)"] = { + de = "%0 (Gesamtfortschritt: %1%%)", + nb = "%0 (totalt: %1%%)", }; + -- This prompt is shown to the end-user after an End User License Agreement + -- has been displayed, asking them if the license text is acceptable to + -- them. It's a yes/no question. ["Accept this license?"] = { - nb = "Akseptere denne lisensen?", + de = "Nehmen Sie die Lizenzbedingungen an?", + nb = "Akseptere denne lisensen?", }; - -- This is a GTK+ button label. The '_' comes after the hotkey character. + -- This is a GTK+ button label for yes/no/always/never questions. + -- The '_' comes before the hotkey character. ["_Always"] = { - nb = "_Alltid", + de = "_Immer", + nb = "_Alltid", }; - ["Archive not found."] = { - nb = "Fant ikke arkiv.", + -- This is an error message reported when a .zip file (or whatever) that + -- we need can't be located. + ["Archive not found"] = { + de = "Archiv nicht gefunden", + nb = "Fant ikke arkiv", }; + -- This prompt is shown to the user when they click the "Cancel" button, + -- to confirm they really want to stop. It's a yes/no question. ["Are you sure you want to cancel installation?"] = { - nb = "Er du sikker p? at du vil avbryte installasjonen?", + de = "Sind Sie sicher, dass Sie die Installation abbrechen wollen?", + nb = "Er du sikker p? at du vil avbryte installasjonen?", }; + -- The opposite of "next", used as a UI button label. ["Back"] = { - nb = "Tilbake", + de = "Zur?ck", + nb = "Tilbake", }; - -- This is a GTK+ button label. The '_' comes after the hotkey character. + -- This is a GTK+ button label. The '_' comes before the hotkey character. + -- "Back" might be using 'B' in English. This button brings up a file + -- dialog where the end-user can navigate to and select files. ["B_rowse..."] = { - nb = "B_la gjennom...", + de = "D_urchsuchen", + nb = "B_la gjennom...", }; - -- "bytes per second" - ["B/s"] = { + + -- All the "BUG:" strings are generally meant to be seen by developers, + -- not end users. They represent programming errors and configuration + -- file problems. + + -- This is shown if the configuration file has specified two cd-roms (or + -- whatever) with the same media id, which is a bug the developer must + -- fix before shipping her installer. + -- "media id" refers to Setup.Media.id in the config file. It's not meant + -- to be a proper name, in this case. + ["BUG: duplicate media id"] = { + de = "FEHLER: Doppelte Medien ID", + nb = "FEIL: duplisert media-id", }; + -- This is shown if the configuration file has no installable options, + -- either because none are listed or they've all become disabled, which + -- is a bug the developer must fix before shipping her installer. + ["BUG: no options"] = { + de = "FEHLER: Keine Optionen", + nb = "FEIL: ingen valg", + }; + + -- This is a file's permissions. Programmers give these as strings, and + -- if one isn't valid, the program will report this. So, on Unix, they + -- might specify "0600" as a valid string, but "sdfksjdfk" wouldn't be + -- and cause this error. ["BUG: '%0' is not a valid permission string"] = { - nb = "FEIL: '%0' er ikke en gyldig rettighetsstreng", + de = "FEHLER: '%0' ist keine zul?ssige Berechtigungs-Zeichenkette", -- FIXME Better word for "Berechtigungs-Zeichenkette" needed + nb = "FEIL: '%0' er ikke en gyldig rettighetsstreng", }; + -- If there's a string in the program that needs be formatted with + -- %0, %1, etc, and it specifies an invalid sequence like "%'", this + -- error pops up to inform the programmer/translator. + -- "format()" is a proper name in this case (program function name) ["BUG: Invalid format() string"] = { - nb = "FEIL: Ugyldig format()-streng", + de = "FEHLER: Unzul?ssige format() Zeichenkette", + nb = "FEIL: Ugyldig format()-streng", }; - ["BUG: stage returned wrong type."] = { - nb = "FEIL: niv? returnerte feil type.", + -- The program runs in "stages" and as it transitions from one stage to + -- another, it has to report some data about what happened during the + -- stage. A programming bug may cause unexpected type of data to be + -- reported, causing this error to pop up. + ["BUG: stage returned wrong type"] = { + de = "FEHLER: Phase gab falschen Typ zur?ck", -- FIXME "stage"? + nb = "FEIL: niv? returnerte feil type", }; - ["BUG: stage returned wrong value."] = { - nb = "FEIL: niv? returnerte feil verdi.", + -- The program runs in "stages" and as it transitions from one stage to + -- another, it has to report some data about what happened during the + -- stage. A programming bug may cause unexpected information to be + -- reported, causing this error to pop up. + ["BUG: stage returned wrong value"] = { + de = "FEHLER: Phase gab falschen Wert zur?ck", -- FIXME "stage"? + nb = "FEIL: niv? returnerte feil verdi", }; + -- The program runs in "stages", which can in many cases be revisited + -- by the user clicking the "Back" button. If the program has a bug + -- that allows the user to click "Back" on the initial stage, this + -- error pops up. ["BUG: stepped back over start of stages"] = { - nb = "FEIL: Gikk tilbake forbi startniv?", + de = "FEHLER: ?ber die Startphase hinaus zur?ckgegangen", -- FIXME "stage"? + nb = "FEIL: Gikk tilbake forbi startniv?", }; + -- This happens if there's an unusual case when writing out Lua scripts + -- to disk. This should never be seen by an end-user. ["BUG: Unhandled data type"] = { - nb = "FEIL: Uh?ndtert datatype", + de = "FEHLER: Unbehandelter Datentyp", + nb = "FEIL: Uh?ndtert datatype", }; - -- "tar" is a proper name in this case. + -- This is triggered by a logic bug in the i/o subsystem. + -- This should never be seen by an end-user. + -- "tar" is a proper name in this case (it's a file format). ["BUG: Can't duplicate tar inputs"] = { - nb = "FEIL: Kan ikke duplisere innfiler for tar", + de = "FEHLER: Tar-Eingaben k?nnen nicht dupliziert werden", + nb = "FEIL: Kan ikke duplisere innfiler for tar", }; -- Buggy config elements: - -- This is supposed to be a config element ($0) and something that's wrong - -- with it ($1), such as "BUG: Config Package::description not a string" + -- This is supposed to be a config element (%0) and something that's wrong + -- with it (%1), such as "BUG: Config Package::description not a string" -- The grammar can be imperfect here; this is a developer error, not an -- end-user error, so we haven't made this very flexible. - ["BUG: Config $0 $1."] = { - nb = "FEIL: Konfigurasjon $0 $1.", + ["BUG: Config %0 %1"] = { + de = "FEHLER: Konfiguration %0 %1", + nb = "FEIL: Konfigurasjon %0 %1", }; -- This is an error string for a buggy config element. See notes above. ["must be explicitly specified"] = { - nb = "m? gis eksplisitt", + de = "muss explizit angegeben werden", + nb = "m? gis eksplisitt", }; -- This is an error string for a buggy config element. See notes above. ["must be string or table of strings"] = { - nb = "m? v?re streng eller tabell av strenger", + de = "muss ein String oder eine Tabelle von Strings sein", + nb = "m? v?re streng eller tabell av strenger", }; -- This is an error string for a buggy config element. See notes above. ["must be a string or number"] = { - nb = "m? v?re streng eller nummer", + de = "muss ein String oder eine Zahl sein", + nb = "m? v?re streng eller nummer", }; -- This is an error string for a buggy config element. See notes above. ["can't be empty string"] = { - nb = "kan ikke v?re tom streng", + de = "darf kein leerer String sein", + nb = "kan ikke v?re tom streng", }; -- This is an error string for a buggy config element. See notes above. ["URL doesn't have protocol"] = { - nb = "URL har ikke protokoll", + de = "URL hat kein Protokoll", + nb = "URL har ikke protokoll", }; -- This is an error string for a buggy config element. See notes above. ["URL doesn't have host"] = { - nb = "URL har ikke vert", + de = "URL hat keinen Host", + nb = "URL har ikke vert", }; -- This is an error string for a buggy config element. See notes above. ["URL doesn't have path"] = { - nb = "URL har ikke sti", + de = "URL hat keinen Pfad", + nb = "URL har ikke sti", }; -- This is an error string for a buggy config element. See notes above. ["URL protocol is unsupported"] = { - nb = "URL-protokoll er ikke st?ttet", + de = "URL Protokoll wird nicht unterst?tzt", + nb = "URL-protokoll er ikke st?ttet", }; -- This is an error string for a buggy config element. See notes above. + -- "Permission string" is text representing a file's permissions, + -- such as "0644" on Unix. ["Permission string is invalid"] = { - nb = "Rettighetsstreng er ugyldig", + de = "Berechtigungs-String ist ung?ltig", -- FIXME "Berechtigungs-Zeichenkette"... s.a. + nb = "Rettighetsstreng er ugyldig", }; -- This is an error string for a buggy config element. See notes above. + -- "property" means attribute, not something owned, in this case. ["is not a valid property"] = { - nb = "er ikke en gyldig egenskap", + de = "ist keine g?ltige Eigenschaft", + nb = "er ikke en gyldig egenskap", }; -- This is an error string for a buggy config element. See notes above. - -- $0 is a data type name (string, number, table, etc). - ["must be $0"] = { - nb = "m? v?re $0", + -- %0 is a data type name (string, number, table, etc). + ["must be %0"] = { + de = "muss vom Typ %0 sein", + nb = "m? v?re %0", }; - -- Data types for "must be $0" above... + -- Data type for "must be %0" above... ["string"] = { - nb = "streng", + de = "String", + nb = "streng", }; + -- Data type for "must be %0" above... ["boolean"] = { - nb = "boolsk verdi", + de = "Bool", + nb = "boolsk verdi", }; + -- Data type for "must be %0" above... ["number"] = { - nb = "nummer", + de = "Zahl", + nb = "nummer", }; + -- Data type for "must be %0" above... ["function"] = { - nb = "funksjon", + de = "Funktion", + nb = "funksjon", }; + -- Data type for "must be %0" above... ["table"] = { - nb = "tabell", + de = "Tabelle", + nb = "tabell", }; - + -- bzlib is a proper name. The error message (%0) may not be localized, + -- it's meant to be a developer error and not an end-user message. ["bzlib triggered an internal error: %0"] = { - nb = "intern feil i bzlib: %0", + de = "bzlib hat einen internen Fehler ausgel?st: %0", + nb = "intern feil i bzlib: %0", }; + -- This is a UI button label, usually paired with "OK", but also usually + -- present as a generic "stop the program" button. ["Cancel"] = { - nb = "Avbryt", + de = "Abbrechen", + nb = "Avbryt", }; + -- This is a message box title when prompting for confirmation when the + -- the user clicks the Cancel button. ["Cancel installation"] = { - nb = "Avbryt installasjonen", + de = "Installation abbrechen", + nb = "Avbryt installasjonen", }; - ["Can't enumerate archive"] = { - nb = "Kan ikke enumerere arkiv", + -- This error is reported for i/o failures while listing files contained + -- in a .zip (or whatever) file. + ["Couldn't enumerate archive"] = { + de = "Konnte Archiv nicht auflisten.", + nb = "Kunne ikke enumerere arkiv.", }; - ["Can't open archive."] = { - nb = "Kan ikke ?pne arkiv.", + -- This error is reported for i/o failures while opening a .zip + -- (or whatever) file. + ["Couldn't open archive."] = { + de = "Konnte Archiv nicht ?ffnen", + nb = "Kunne ikke ?pne arkiv.", }; + -- This is used by the stdio UI to choose a location to write files. + -- A numbered list of options is printed, and the user may choose one by + -- its number (default is number one), or enter their own text instead of + -- choosing a default. This string is the instructions printed for the + -- user before the prompt. ["Choose install destination by number (hit enter for #1), or enter your own."] = { - nb = "Velg installasjonssti etter nummer (trykk enter for #1), eller skriv din egen.", + de = "W?hlen Sie eine Nummer f?r das Installationsziel (dr?cken Sie Enter f?r #1), oder geben Sie ein eigenes an.", + nb = "Velg installasjonssti etter nummer (trykk enter for #1), eller skriv din egen.", }; + -- This is used by the stdio UI to toggle options. A numbered list is + -- printed, and the user can enter one of those numbers to toggle that + -- option on or off. This string is the instructions printed for the + -- user before the prompt. ["Choose number to change."] = { - nb = "Velg nummer som skal endres.", + de = "W?hlen Sie eine Nummer zum ?ndern.", + nb = "Velg nummer som skal endres.", }; - ["Config bug: duplicate media id"] = { - nb = "Konfigurasjonsfeil: duplisert media-id", - }; - - ["Config bug: no options"] = { - nb = "Konfigurasjonsfeil: ingen valg", - }; - - -- As in "two different files want to use the same name" + -- As in "two different files want to use the same name." This is a title + -- on a message box. ["Conflict!"] = { - nb = "Konflikt!", + de = "Namenskonflikt!", -- FIXME Translated as "Name conflict!" + nb = "Konflikt!", }; + -- This is an error message shown to the user. When a file is to be + -- overwritten, we move it out of the way instead, so we can restore it + -- ("roll the file back") in case of problems, with the goal of having + -- an installation that fails halfway through reverse any changes it made. + -- This error is shown if we can't move a file out of the way. ["Couldn't backup file for rollback"] = { - nb = "Kunne ikke sikkerhetskopiere fil for tilbakerulling", + de = "Konnte Datei nicht zum Zur?cknehmen sichern", + nb = "Kunne ikke sikkerhetskopiere fil for tilbakerulling", }; + -- This error is shown if we aren't able to write the list of files + -- that were installed (the "manifest") to disk. ["Couldn't create manifest"] = { - nb = "Kunne ikke lage manifest", + de = "Konnte Manifest nicht erstellen", + nb = "Kunne ikke lage manifest", }; - ["Couldn't enumerate archive."] = { - nb = "Kunne ikke enumerere arkiv.", - }; - - ["Couldn't open archive."] = { - nb = "Kunne ikke ?pne arkiv.", - }; - + -- This is an error message. It speaks for itself. :) ["Couldn't restore some files. Your existing installation is likely damaged."] = { - nb = "Noen filer kunne ikke tilbakestilles. Den eksisterende installasjonen er sannsynligvis skadet.", + de = "Konnte einige Dateien nicht widerherstellen. Ihre Installation ist wahrscheinlich besch?digt.", + nb = "Noen filer kunne ikke tilbakestilles. Den eksisterende installasjonen er sannsynligvis skadet.", }; + -- Error message when deleting a file fails. ["Deletion failed!"] = { - nb = "Kunne ikke slette!", + de = "L?schung fehlgeschlagen!", + nb = "Kunne ikke slette!", }; + -- This is a window title when user is selecting a path to install files. ["Destination"] = { - nb = "Destinasjon", + de = "Ziel", + nb = "Destinasjon", }; + -- This is a window title while the program is downloading external files + -- it needs from the network. ["Downloading"] = { - nb = "Laster ned", + de = "Herunterladen", + nb = "Laster ned", }; + -- Several UIs use this string as a prompt to the end-user when selecting + -- a destination for newly-installed files. ["Enter path where files will be installed."] = { - nb = "Skriv inn destinasjonssti for installasjonen.", + de = "Geben Sie den Pfad an, wo Dateien installiert werden sollen.", + nb = "Skriv inn destinasjonssti for installasjonen.", }; + -- Error message when a file we expect to load can't be read from disk. ["failed to load file '%0'"] = { - nb = "kunne ikke laste fil '%0'", + de = "Laden von Datei '%0' fehlgeschlagen", + nb = "kunne ikke laste fil '%0'", }; + -- This is a window title when something goes very wrong. ["Fatal error"] = { - nb = "Fatal feil", + de = "Schwerer Fehler", + nb = "Fatal feil", }; + -- This is an error message when failing to write a file to disk. ["File creation failed!"] = { - nb = "Kunne ikke lage fil!", + de = "Dateierstellung fehlgeschlagen!", + nb = "Kunne ikke lage fil!", }; + -- This is an error message when failing to get a file from the network. ["File download failed!"] = { - nb = "Kunne ikke laste ned fil!", + de = "Dateidownload fehlgeschlagen!", + nb = "Kunne ikke laste ned fil!", }; - ["File '$0' already exists! Replace?"] = { - nb = "Filen '$0' eksisterer allerede! Skrive over?", + -- This prompt is shown to users when we may overwrite an existing file. + -- "%0" is the filename. + ["File '%0' already exists! Replace?"] = { + de = "Datei '%0' existiert bereits! Ersetzen?", + nb = "Filen '%0' eksisterer allerede! Skrive over?", }; + -- This is a button in the UI. It replaces "Next" when there are no more + -- stages to move forward to. ["Finish"] = { - nb = "Ferdig", + de = "Fertigstellen", + nb = "Ferdig", }; + -- This error message is (hopefully) shown to the user if the UI + -- subsystem can't create the main application window. ["GUI failed to start"] = { - nb = "Kunne ikke starte grafisk grensesnitt", + de = "GUI konnte nicht gestartet werden", + nb = "Kunne ikke starte grafisk grensesnitt", }; + -- This message is shown to the user if an installation encounters a fatal + -- problem (or the user clicked "cancel"), telling them that we'll try + -- to put everything back how it was before we started. ["Incomplete installation. We will revert any changes we made."] = { - nb = "Installasjonen ble ikke ferdig. Vi vil tilbakestille alle endringer som ble gjort.", + de = "Unvollst?ndige Installation. Vollzogene Ver?nderungen werden zur?ckgenommen.", + nb = "Installasjonen ble ikke ferdig. Vi vil tilbakestille alle endringer som ble gjort.", }; - ["Installation location"] = { - nb = "Installasjonssti", - }; - + -- Reported to the user if everything worked out. ["Installation was successful."] = { - nb = "Installasjonen var en suksess.", + de = "Installation war erfolgreich.", + nb = "Installasjonen var en suksess.", }; + -- This is a window title, shown while the actual installation to disk + -- is in process and a progress meter is being shown. ["Installing"] = { - nb = "Installerer", + de = "Installieren", + nb = "Installerer", }; - ["Install options:"] = { - nb = "Installasjonsvalg:", + -- This is a window title, shown while the user is choosing + -- installation-specific options. + ["Options"] = { + de = "Optionen", + nb = "Valg", }; + -- Shown as an option in the ncurses UI as the final element in a list of + -- default filesystem paths where a user may install files. They can + -- choose this to enter a filesystem path manually. ["(I want to specify a path.)"] = { - nb = "(Jeg vil skrive min egen sti.)", + de = "(Ich m?chte einen Pfad angeben.)", + nb = "(Jeg vil skrive min egen sti.)", }; - -- "kilobytes per second" + -- "kilobytes per second" ... download rate. ["KB/s"] = { + de = "KB/s", + nb = "KB/s", }; + -- "bytes per second" ... download rate. + ["B/s"] = { + de = "B/s", + nb = "B/s", + }; + -- Download rate when we don't know the goal (can't report time left). - -- This is a number ($0) followed by the localized "KB/s" or "B/s" ($1). - ["$0 $1"] = { + -- This is a number (%0) followed by the localized "KB/s" or "B/s" (%1). + ["%0 %1"] = { + de = "%0 %1", + nb = "%0 %1", }; -- Download rate when we know the goal (can report time left). - -- This is a number ($0) followed by the localized "KB/s" or "B/s" ($1), - -- then the hours ($2), minutes ($3), and seconds ($4) remaining - ["$0 $1, $2:$3:$4 remaining"] = { - nb = "$0 $1, $2:$3:$4 igjen", + -- This is a number (%0) followed by the localized "KB/s" or "B/s" (%1), + -- then the hours (%2), minutes (%3), and seconds (%4) remaining + ["%0 %1, %2:%3:%4 remaining"] = { + de = "%0 %1, %2:%3:%4 verbleibend", + nb = "%0 %1, %2:%3:%4 igjen", }; -- download rate when download isn't progressing at all. ["stalled"] = { - nb = "st?r fast", + de = "Stillstand", -- FIXME Translated as "halt" or "standstill" + nb = "st?r fast", }; - -- Download progress string: filename ($0), percent downloaded ($1), - -- download rate determined in one of the above strings ($2). - ["$0: $1%% ($2)"] = { + -- Download progress string: filename (%0), percent downloaded (%1), + -- download rate determined in one of the above strings (%2). + ["%0: %1%% (%2)"] = { + de = "%0: %1%% (%2)", + nb = "%0: %1%% (%2)", }; + -- This is a window title when prompting the user to insert a new disc. ["Media change"] = { - nb = "Mediaendring", + de = "Medienwechsel", + nb = "Mediaendring", }; + -- This error message is shown to the end-user when we can't make a new + -- folder/directory in the filesystem. ["Directory creation failed"] = { - nb = "Kunne ikke lage katalog", + de = "Erstellung eines Verzeichnisses fehlgeschlagen", + nb = "Kunne ikke lage katalog", }; - ["need dictionary"] = { - nb = "trenger ordbok", - }; - - -- This is a GTK+ button label. The '_' comes after the hotkey character. + -- This is a GTK+ button label. The '_' comes before the hotkey character. + -- "No" would take the 'N' hotkey in English. ["N_ever"] = { - nb = "Al_dri", + de = "N_iemals", + nb = "Al_dri", }; + -- This is a GUI button label, to move forward to the next stage of + -- installation. It's opposite is "Back" in this case. ["Next"] = { - nb = "Neste", + de = "Weiter", + nb = "Neste", }; + -- This is a GUI button label, indicating a negative response. ["No"] = { - nb = "Nei", + de = "Nein", + nb = "Nei", }; - ["No networking support in this build."] = { - nb = "Nettverksst?tte er ikke aktivert i denne versjonen.", + -- This is a GUI button label, indicating a positive response. + ["Yes"] = { + de = "Ja", + nb = "Ja", }; + -- HTTP error message in the www UI, as in "404 Not Found" ... requested + -- file is missing. ["Not Found"] = { - nb = "Ikke funnet", + de = "Nicht gefunden", + nb = "Ikke funnet", }; + -- This is reported to the user when there are no files to install, and + -- thus no installation to go forward. ["Nothing to do!"] = { - nb = "Ingenting ? gj?re!", + de = "Nichts zu tun!", + nb = "Ingenting ? gj?re!", }; + -- This is a GUI button label, sometimes paired with "Cancel" ["OK"] = { - nb = "OK", + de = "OK", + nb = "OK", }; - ["Options"] = { - nb = "Valg", - }; - + -- This is displayed when the application has a serious problem, such as + -- crashing again in the crash handler, or being unable to find basic + -- files it needs to get started. It may be a window title, or written + -- to stdout, or whatever, but it's basically meant to be a title or + -- header, with more information to follow later. ["PANIC"] = { - nb = "PANIKK", + de = "PANIK", + nb = "PANIKK", }; + -- Prompt shown to user when we need her to insert a new disc. ["Please insert '%0'"] = { - nb = "Sett inn '%0'", + de = "Bitte f?gen Sie '%0' ein", + nb = "Sett inn '%0'", }; + -- Prompt shown to user in the stdio UI when we need to pause before + -- continuing, usually to let them read the outputted text that is + -- scrolling by. ["Press enter to continue."] = { - nb = "Trykk enter for ? fortsette.", + de = "Dr?cken Sie Enter um fortzufahren", + nb = "Trykk enter for ? fortsette.", }; + -- This is a window title when informing the user that something + -- important has gone wrong (such as being unable to revert changes + -- during a rollback). ["Serious problem"] = { - nb = "Alvorlig problem", + de = "Ernstes Problem", + nb = "Alvorlig problem", }; + -- The www UI uses this as a page title when the program is terminating. ["Shutting down..."] = { - nb = "Avslutter...", + de = "Schlie?e...", + nb = "Avslutter...", }; + -- The www UI uses this as page text when the program is terminating. + ["You can close this browser now."] = { + }; + + -- Error message shown to end-user when we can't write a symbolic link + -- to the filesystem. ["Symlink creation failed!"] = { - nb = "Kunne likke lage symbolsk lenke!", + de = "Erzeugung einer Verkn?pfung fehlgeschlagen!", + nb = "Kunne likke lage symbolsk lenke!", }; + -- Error message shown to the end-user when the OS has requested + -- termination of the program (SIGINT/ctrl-c on Unix, etc). ["The installer has been stopped by the system."] = { - nb = "Installasjonsprogrammet ble stoppet av systemet.", + de = "Das Installationsprogramm wurde vom System gestoppt.", + nb = "Installasjonsprogrammet ble stoppet av systemet.", }; + -- Error message shown to the end-user when the program crashes with a + -- bad memory access (segfault on Unix, GPF on Windows, etc). ["The installer has crashed due to a bug."] = { - nb = "Installasjonsprogrammet kr?sjet pga. en feil.", + de = "Das Installationsprogramm ist aufgrund eines Fehlers abgest?rzt.", + nb = "Installasjonsprogrammet kr?sjet pga. en feil.", }; - -- This is a button label in the ncurses ui. + -- This is a button label in the ncurses ui to flip an option on/off. ["Toggle"] = { - nb = "Inverter valg", + de = "Umschalten", + nb = "Inverter valg", }; + -- This is an error message shown to the end-user when there is an + -- unexpected entry in a .zip (or whatever) file that we didn't know + -- how to handle. ["Unknown file type in archive"] = { - nb = "Ukjent filtype i arkivet", + de = "Unbekannter Dateityp im Archiv", + nb = "Ukjent filtype i arkivet", }; - ["Yes"] = { - nb = "Ja", - }; - + -- This is an error message shown to the end-user if they refuse to + -- agree to the license of the software they are try to install. ["You must accept the license before you may install"] = { - nb = "Lisensen m? godkjennes f?r du kan installere", + de = "Sie m?ssen den Lizenzbedingungen zustimmen, bevor sie installieren k?nnen", + nb = "Lisensen m? godkjennes f?r du kan installere", }; + -- Installations display the currently-installing component, such as + -- "Base game" or "Bonus pack content" or whatnot. The installer lists + -- the current component as "Metadata" when writing out its own + -- information, such as file manifests, uninstall support, etc. ["Metadata"] = { - nb ="Metadata", + de = "Metadaten", + nb ="Metadata", }; }; Modified: trunk/scripts/mojosetup_init.lua =================================================================== --- trunk/scripts/mojosetup_init.lua 2008-01-14 21:34:19 UTC (rev 420) +++ trunk/scripts/mojosetup_init.lua 2008-01-15 01:16:32 UTC (rev 421) @@ -177,7 +177,7 @@ local function schema_assert(test, fnname, elem, errstr) if not test then - local msg = MojoSetup.format(_("BUG: Config $0 $1."), + local msg = MojoSetup.format(_("BUG: Config %0 %1"), fnname .. "::" .. elem, errstr) MojoSetup.fatal(msg) end @@ -191,7 +191,7 @@ -- Can be nil...please use mustExist if this is a problem! if val ~= nil then if type(val) ~= elemtype then - local msg = MojoSetup.format(_("must be $0"), + local msg = MojoSetup.format(_("must be %0"), MojoSetup.translate(elemtype)) schema_assert(false, fnname, elem, msg) end Modified: trunk/scripts/mojosetup_mainline.lua =================================================================== --- trunk/scripts/mojosetup_mainline.lua 2008-01-14 21:34:19 UTC (rev 420) +++ trunk/scripts/mojosetup_mainline.lua 2008-01-15 01:16:32 UTC (rev 421) @@ -165,11 +165,11 @@ hoursleft = tostring(hoursleft) end - retval = MojoSetup.format(_("$0 $1, $2:$3:$4 remaining"), + retval = MojoSetup.format(_("%0 %1, %2:%3:%4 remaining"), rate, ratetype, hoursleft, minsleft, secsleft) else - retval = MojoSetup.format(_("$0 $1"), rate, ratetype) + retval = MojoSetup.format(_("%0 %1"), rate, ratetype) end end @@ -243,7 +243,7 @@ ent = MojoSetup.archive.enumnext(archive) end - MojoSetup.fatal(_("Archive not found.")) + MojoSetup.fatal(_("Archive not found")) end @@ -394,7 +394,7 @@ allowoverwrite = file.allowoverwrite if not allowoverwrite then MojoSetup.loginfo("File '" .. dest .. "' already exists.") - local text = MojoSetup.format(_("File '$0' already exists! Replace?"), dest); + local text = MojoSetup.format(_("File '%0' already exists! Replace?"), dest); local ynan = MojoSetup.promptynan(_("Conflict!"), text, true) if ynan == "always" then MojoSetup.forceoverwrite = true @@ -472,7 +472,7 @@ local function install_archive(archive, file, option) if not MojoSetup.archive.enumerate(archive) then - MojoSetup.fatal(_("Can't enumerate archive")) + MojoSetup.fatal(_("Couldn't enumerate archive")) end local isbase = (archive == MojoSetup.archive.base) @@ -551,7 +551,7 @@ if archive == nil then archive = MojoSetup.archive.fromfile(path) if archive == nil then - MojoSetup.fatal(_("Can't open archive.")) + MojoSetup.fatal(_("Couldn't open archive")) end end return archive @@ -1103,7 +1103,7 @@ percent = calc_percent(MojoSetup.downloaded, MojoSetup.totaldownload) - item = MojoSetup.format(_("$0: $1%% ($2)"), + item = MojoSetup.format(_("%0: %1%% (%2)"), fname, calc_percent(bw, total), ratestr); @@ -1228,7 +1228,7 @@ -- Too many times I forgot to return something. :) if type(rc) ~= "number" then - MojoSetup.fatal(_("BUG: stage returned wrong type.")) + MojoSetup.fatal(_("BUG: stage returned wrong type")) end if rc == 1 then @@ -1242,7 +1242,7 @@ elseif rc == 0 then MojoSetup.fatal() else - MojoSetup.fatal(_("BUG: stage returned wrong value.")) + MojoSetup.fatal(_("BUG: stage returned wrong value")) end end From DONOTREPLY at icculus.org Mon Jan 14 21:11:58 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 14 Jan 2008 21:11:58 -0500 Subject: r422 - in trunk: . scripts Message-ID: <20080115021158.8325.qmail@icculus.org> Author: icculus Date: 2008-01-14 21:11:58 -0500 (Mon, 14 Jan 2008) New Revision: 422 Modified: trunk/gui_gtkplus2.c trunk/scripts/localization.lua Log: Fixed some missing localizations. Modified: trunk/gui_gtkplus2.c =================================================================== --- trunk/gui_gtkplus2.c 2008-01-15 01:16:32 UTC (rev 421) +++ trunk/gui_gtkplus2.c 2008-01-15 02:11:58 UTC (rev 422) @@ -501,7 +501,7 @@ gtk_widget_show(box); hbox = gtk_hbox_new (FALSE, 6); - widget = gtk_label_new("Folder:"); + widget = gtk_label_new(entry->_("Folder:")); gtk_widget_show(widget); gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 0); gtk_label_set_justify(GTK_LABEL(widget), GTK_JUSTIFY_CENTER); @@ -754,7 +754,7 @@ gtk_combo_box_prepend_text(combo, recommends[i]); gtk_combo_box_set_active (combo, 0); - *command = run_wizard(entry->_("Installation location"), PAGE_DESTINATION, + *command = run_wizard(entry->_("Destination"), PAGE_DESTINATION, can_back, can_fwd); str = gtk_combo_box_get_active_text(combo); Modified: trunk/scripts/localization.lua =================================================================== --- trunk/scripts/localization.lua 2008-01-15 01:16:32 UTC (rev 421) +++ trunk/scripts/localization.lua 2008-01-15 02:11:58 UTC (rev 422) @@ -519,6 +519,12 @@ nb = "Kunne ikke slette!", }; + -- This is a label displayed next to the text entry in the GTK+ UI where + -- the user specifies the installation destination (folder/directory) in + -- the filesystem. + ["Folder:"] = { + }; + -- This is a window title when user is selecting a path to install files. ["Destination"] = { de = "Ziel", From DONOTREPLY at icculus.org Mon Jan 14 22:50:44 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 14 Jan 2008 22:50:44 -0500 Subject: r423 - trunk/scripts Message-ID: <20080115035044.25590.qmail@icculus.org> Author: icculus Date: 2008-01-14 22:50:43 -0500 (Mon, 14 Jan 2008) New Revision: 423 Modified: trunk/scripts/localization.lua trunk/scripts/mojosetup_mainline.lua Log: A few more localization tweaks from Dennis. Modified: trunk/scripts/localization.lua =================================================================== --- trunk/scripts/localization.lua 2008-01-15 02:11:58 UTC (rev 422) +++ trunk/scripts/localization.lua 2008-01-15 03:50:43 UTC (rev 423) @@ -169,7 +169,7 @@ -- reasonable for the user to manually type. The UIs use a different -- string for their button ("Back" vs "back" specifically). ["back"] = { - de = "zur?ck", -- FIXME Does this name a button? Which one??? + de = "zur?ck", nb = "tilbake", }; @@ -246,7 +246,7 @@ -- "media id" refers to Setup.Media.id in the config file. It's not meant -- to be a proper name, in this case. ["BUG: duplicate media id"] = { - de = "FEHLER: Doppelte Medien ID", + de = "FEHLER: Doppelte Medien-ID", nb = "FEIL: duplisert media-id", }; @@ -263,7 +263,7 @@ -- might specify "0600" as a valid string, but "sdfksjdfk" wouldn't be -- and cause this error. ["BUG: '%0' is not a valid permission string"] = { - de = "FEHLER: '%0' ist keine zul?ssige Berechtigungs-Zeichenkette", -- FIXME Better word for "Berechtigungs-Zeichenkette" needed + de = "FEHLER: '%0' ist keine zul?ssiger Berechtigungs-String", nb = "FEIL: '%0' er ikke en gyldig rettighetsstreng", }; @@ -272,7 +272,7 @@ -- error pops up to inform the programmer/translator. -- "format()" is a proper name in this case (program function name) ["BUG: Invalid format() string"] = { - de = "FEHLER: Unzul?ssige format() Zeichenkette", + de = "FEHLER: Unzul?ssiger format() String", nb = "FEIL: Ugyldig format()-streng", }; @@ -281,7 +281,7 @@ -- stage. A programming bug may cause unexpected type of data to be -- reported, causing this error to pop up. ["BUG: stage returned wrong type"] = { - de = "FEHLER: Phase gab falschen Typ zur?ck", -- FIXME "stage"? + de = "FEHLER: Abschnitt gab falschen Typ zur?ck", nb = "FEIL: niv? returnerte feil type", }; @@ -290,7 +290,7 @@ -- stage. A programming bug may cause unexpected information to be -- reported, causing this error to pop up. ["BUG: stage returned wrong value"] = { - de = "FEHLER: Phase gab falschen Wert zur?ck", -- FIXME "stage"? + de = "FEHLER: Abschnitt gab falschen Wert zur?ck", nb = "FEIL: niv? returnerte feil verdi", }; @@ -299,7 +299,7 @@ -- that allows the user to click "Back" on the initial stage, this -- error pops up. ["BUG: stepped back over start of stages"] = { - de = "FEHLER: ?ber die Startphase hinaus zur?ckgegangen", -- FIXME "stage"? + de = "FEHLER: ?ber den Startabschnitt hinaus zur?ckgegangen", nb = "FEIL: Gikk tilbake forbi startniv?", }; @@ -380,7 +380,7 @@ -- "Permission string" is text representing a file's permissions, -- such as "0644" on Unix. ["Permission string is invalid"] = { - de = "Berechtigungs-String ist ung?ltig", -- FIXME "Berechtigungs-Zeichenkette"... s.a. + de = "Berechtigungs-String ist ung?ltig", nb = "Rettighetsstreng er ugyldig", }; @@ -453,15 +453,15 @@ -- This error is reported for i/o failures while listing files contained -- in a .zip (or whatever) file. ["Couldn't enumerate archive"] = { - de = "Konnte Archiv nicht auflisten.", - nb = "Kunne ikke enumerere arkiv.", + de = "Archiv kann nicht aufgelistet werden", + nb = "Kunne ikke enumerere arkiv", }; -- This error is reported for i/o failures while opening a .zip -- (or whatever) file. - ["Couldn't open archive."] = { - de = "Konnte Archiv nicht ?ffnen", - nb = "Kunne ikke ?pne arkiv.", + ["Couldn't open archive"] = { + de = "Archiv kann nicht ge?ffnet werden", + nb = "Kunne ikke ?pne arkiv", }; -- This is used by the stdio UI to choose a location to write files. @@ -486,7 +486,7 @@ -- As in "two different files want to use the same name." This is a title -- on a message box. ["Conflict!"] = { - de = "Namenskonflikt!", -- FIXME Translated as "Name conflict!" + de = "Konflikt!", nb = "Konflikt!", }; @@ -515,7 +515,7 @@ -- Error message when deleting a file fails. ["Deletion failed!"] = { - de = "L?schung fehlgeschlagen!", + de = "L?schen fehlgeschlagen!", nb = "Kunne ikke slette!", }; @@ -579,7 +579,7 @@ -- This is a button in the UI. It replaces "Next" when there are no more -- stages to move forward to. ["Finish"] = { - de = "Fertigstellen", + de = "Fertig", nb = "Ferdig", }; @@ -737,7 +737,7 @@ -- Prompt shown to user when we need her to insert a new disc. ["Please insert '%0'"] = { - de = "Bitte f?gen Sie '%0' ein", + de = "Bitte legen Sie '%0' ein", nb = "Sett inn '%0'", }; @@ -765,6 +765,7 @@ -- The www UI uses this as page text when the program is terminating. ["You can close this browser now."] = { + de = "Sie k?nnen diesen Browser nun schlie?en.", }; -- Error message shown to end-user when we can't write a symbolic link @@ -815,7 +816,7 @@ -- information, such as file manifests, uninstall support, etc. ["Metadata"] = { de = "Metadaten", - nb ="Metadata", + nb = "Metadata", }; }; Modified: trunk/scripts/mojosetup_mainline.lua =================================================================== --- trunk/scripts/mojosetup_mainline.lua 2008-01-15 02:11:58 UTC (rev 422) +++ trunk/scripts/mojosetup_mainline.lua 2008-01-15 03:50:43 UTC (rev 423) @@ -213,7 +213,7 @@ -- This code's a little nasty... local function drill_for_archive(archive, path, arclist) if not MojoSetup.archive.enumerate(archive) then - MojoSetup.fatal(_("Couldn't enumerate archive.")) + MojoSetup.fatal(_("Couldn't enumerate archive")) end local pathtab = split_path(path) @@ -231,7 +231,7 @@ -- open it as an archive and keep drilling... local arc = MojoSetup.archive.fromentry(archive) if arc == nil then - MojoSetup.fatal(_("Couldn't open archive.")) + MojoSetup.fatal(_("Couldn't open archive")) end arclist[#arclist+1] = arc if pathtab[i] == nil then From DONOTREPLY at icculus.org Wed Jan 16 05:10:49 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 16 Jan 2008 05:10:49 -0500 Subject: r424 - trunk Message-ID: <20080116101049.14703.qmail@icculus.org> Author: icculus Date: 2008-01-16 05:10:34 -0500 (Wed, 16 Jan 2008) New Revision: 424 Modified: trunk/stb_image.c Log: Patched to compile on Mac OS X. Modified: trunk/stb_image.c =================================================================== --- trunk/stb_image.c 2008-01-15 03:50:43 UTC (rev 423) +++ trunk/stb_image.c 2008-01-16 10:10:34 UTC (rev 424) @@ -782,7 +782,10 @@ static unsigned char *convert_format(unsigned char *data, int img_n, int req_comp) { - uint i,j; +#if __MOJOSETUP__ + //uint i,j; + uint32 i,j; +#endif unsigned char *good; if (req_comp == img_n) return data; From DONOTREPLY at icculus.org Wed Jan 16 05:12:29 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 16 Jan 2008 05:12:29 -0500 Subject: r425 - trunk Message-ID: <20080116101229.17118.qmail@icculus.org> Author: icculus Date: 2008-01-16 05:12:18 -0500 (Wed, 16 Jan 2008) New Revision: 425 Modified: trunk/archive_zip.c trunk/fileio.c trunk/fileio.h Log: Let archives report the byte offset in a MojoInput where they start, so we know, for example, exactly where an executable ends and an appended .zip file starts. Modified: trunk/archive_zip.c =================================================================== --- trunk/archive_zip.c 2008-01-16 10:10:34 UTC (rev 424) +++ trunk/archive_zip.c 2008-01-16 10:12:18 UTC (rev 425) @@ -252,6 +252,7 @@ #if __MOJOSETUP__ void *io; /* a MojoInput pointer */ int32 enumIndex; /* index of last entry enumerated. */ + int64 offset; /* byte offset from start of MojoInput where zip starts. */ #endif PHYSFS_uint16 entryCount; /* Number of files in ZIP. */ ZIPentry *entries; /* info on all files in ZIP. */ @@ -1307,6 +1308,10 @@ if (!zip_parse_end_of_central_dir(in, info, &data_start, ¢_dir_ofs)) goto zip_openarchive_failed; +#if __MOJOSETUP__ + info->offset = (int64) data_start; +#endif + if (!zip_load_entries(in, info, data_start, cent_dir_ofs)) goto zip_openarchive_failed; @@ -1823,6 +1828,7 @@ ar->enumNext = MojoArchive_zip_enumNext; ar->openCurrentEntry = MojoArchive_zip_openCurrentEntry; ar->close = MojoArchive_zip_close; + ar->offsetOfStart = ((const ZIPinfo *) opaque)->offset; ar->opaque = opaque; ar->io = io; return ar; Modified: trunk/fileio.c =================================================================== --- trunk/fileio.c 2008-01-16 10:10:34 UTC (rev 424) +++ trunk/fileio.c 2008-01-16 10:12:18 UTC (rev 425) @@ -598,6 +598,7 @@ ar->enumNext = MojoArchive_dir_enumNext; ar->openCurrentEntry = MojoArchive_dir_openCurrentEntry; ar->close = MojoArchive_dir_close; + ar->offsetOfStart = -1; // doesn't mean anything here. ar->opaque = inst; return ar; } // MojoArchive_newFromDirectory Modified: trunk/fileio.h =================================================================== --- trunk/fileio.h 2008-01-16 10:10:34 UTC (rev 424) +++ trunk/fileio.h 2008-01-16 10:12:18 UTC (rev 425) @@ -82,6 +82,7 @@ // private MojoInput *io; MojoArchiveEntry prevEnum; + int64 offsetOfStart; // byte offset in MojoInput where archive starts. void *opaque; }; From DONOTREPLY at icculus.org Wed Jan 16 06:48:06 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 16 Jan 2008 06:48:06 -0500 Subject: r426 - in trunk: . scripts Message-ID: <20080116114806.26481.qmail@icculus.org> Author: icculus Date: 2008-01-16 06:48:05 -0500 (Wed, 16 Jan 2008) New Revision: 426 Modified: trunk/fileio.c trunk/fileio.h trunk/lua_glue.c trunk/scripts/mojosetup_mainline.lua Log: MojoInput_toPhysicalFile() and MojoSetup.writefile() can now take a maximum byte size, so you can write only the first X bytes of a MojoInput (or pass -1 or nil to write everything). Modified: trunk/fileio.c =================================================================== --- trunk/fileio.c 2008-01-16 10:12:18 UTC (rev 425) +++ trunk/fileio.c 2008-01-16 11:48:05 UTC (rev 426) @@ -81,7 +81,7 @@ // !!! FIXME: I'd rather not use a callback here, but I can't see a cleaner // !!! FIXME: way right now... boolean MojoInput_toPhysicalFile(MojoInput *in, const char *fname, uint16 perms, - MojoChecksums *checksums, + MojoChecksums *checksums, int64 maxbytes, MojoInput_FileCopyCallback cb, void *data) { boolean retval = false; @@ -113,6 +113,8 @@ } // while flen = in->length(in); + if ((maxbytes >= 0) && (flen > maxbytes)) + flen = maxbytes; MojoPlatform_unlink(fname); if (!iofailure) @@ -127,14 +129,27 @@ while (!iofailure) { int64 br = 0; + int64 maxread = sizeof (scratchbuf_128k); + // see if we need to clamp to eof or maxbytes... + if (flen >= 0) + { + const int64 avail = flen - bw; + if (avail < maxread) + { + maxread = avail; + if (maxread == 0) + break; // nothing left to do, break out. + } // if + } // if + // If there's a callback, then poll. Otherwise, just block on // the reads from the MojoInput. if ((cb != NULL) && (!in->ready(in))) MojoPlatform_sleep(100); else { - br = in->read(in, scratchbuf_128k, sizeof (scratchbuf_128k)); + br = in->read(in, scratchbuf_128k, maxread); if (br == 0) // we're done! break; else if (br < 0) @@ -161,6 +176,8 @@ if (MojoPlatform_close(out) != 0) iofailure = true; + else if (bw != flen) + iofailure = true; if (iofailure) MojoPlatform_unlink(fname); Modified: trunk/fileio.h =================================================================== --- trunk/fileio.h 2008-01-16 10:12:18 UTC (rev 425) +++ trunk/fileio.h 2008-01-16 11:48:05 UTC (rev 426) @@ -104,7 +104,7 @@ typedef boolean (*MojoInput_FileCopyCallback)(uint32 ticks, int64 justwrote, int64 bw, int64 total, void *data); boolean MojoInput_toPhysicalFile(MojoInput *in, const char *fname, uint16 perms, - MojoChecksums *checksums, + MojoChecksums *checksums, int64 maxbytes, MojoInput_FileCopyCallback cb, void *data); MojoInput *MojoInput_fromURL(const char *url); Modified: trunk/lua_glue.c =================================================================== --- trunk/lua_glue.c 2008-01-16 10:12:18 UTC (rev 425) +++ trunk/lua_glue.c 2008-01-16 11:48:05 UTC (rev 426) @@ -755,6 +755,8 @@ uint16 perms = archive->prevEnum.perms; MojoChecksums sums; MojoInput *in = archive->openCurrentEntry(archive); + int64 maxbytes = -1; + if (in != NULL) { if (!lua_isnil(L, 3)) @@ -765,8 +767,12 @@ if (!valid) fatal(_("BUG: '%0' is not a valid permission string"), permstr); } // if - rc = MojoInput_toPhysicalFile(in, path, perms, &sums, - writeCallback, L); + + if (!lua_isnil(L, 4)) + maxbytes = luaL_checkinteger(L, 4); + + rc = MojoInput_toPhysicalFile(in, path, perms, &sums, maxbytes, + writeCallback, L); } // if retval += retvalBoolean(L, rc); @@ -798,7 +804,7 @@ if (in != NULL) { // !!! FIXME: Unix-specific permissions thing here. - rc = MojoInput_toPhysicalFile(in, dst, 0644, &sums, + rc = MojoInput_toPhysicalFile(in, dst, 0644, &sums, -1, writeCallback, L); } // if @@ -965,7 +971,7 @@ { uint16 perms = 0; MojoPlatform_perms(src, &perms); - retval = MojoInput_toPhysicalFile(in, dst, perms, NULL, NULL, NULL); + retval = MojoInput_toPhysicalFile(in,dst,perms,NULL,-1,NULL,NULL); if (retval) { retval = MojoPlatform_unlink(src); @@ -1002,7 +1008,7 @@ if (!valid) fatal(_("BUG: '%0' is not a valid permission string"), permstr); } // if - rc = MojoInput_toPhysicalFile(in, path, perms, &sums, writeCallback, L); + rc = MojoInput_toPhysicalFile(in, path, perms, &sums, -1, writeCallback, L); retval += retvalBoolean(L, rc); if (rc) Modified: trunk/scripts/mojosetup_mainline.lua =================================================================== --- trunk/scripts/mojosetup_mainline.lua 2008-01-16 10:12:18 UTC (rev 425) +++ trunk/scripts/mojosetup_mainline.lua 2008-01-16 11:48:05 UTC (rev 426) @@ -299,7 +299,7 @@ local function install_file_from_archive(dest, archive, perms, desc, manifestkey) local fn = function(callback) - return MojoSetup.writefile(archive, dest, perms, callback) + return MojoSetup.writefile(archive, dest, perms, nil, callback) end return install_file(dest, perms, fn, desc, manifestkey) end From DONOTREPLY at icculus.org Wed Jan 16 06:50:02 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 16 Jan 2008 06:50:02 -0500 Subject: r427 - trunk Message-ID: <20080116115002.29098.qmail@icculus.org> Author: icculus Date: 2008-01-16 06:50:02 -0500 (Wed, 16 Jan 2008) New Revision: 427 Modified: trunk/lua_glue.c Log: Minor FIXME cleanup. Modified: trunk/lua_glue.c =================================================================== --- trunk/lua_glue.c 2008-01-16 11:48:05 UTC (rev 426) +++ trunk/lua_glue.c 2008-01-16 11:50:02 UTC (rev 427) @@ -803,9 +803,8 @@ MojoInput *in = MojoInput_fromURL(url); if (in != NULL) { - // !!! FIXME: Unix-specific permissions thing here. - rc = MojoInput_toPhysicalFile(in, dst, 0644, &sums, -1, - writeCallback, L); + rc = MojoInput_toPhysicalFile(in, dst, MojoPlatform_defaultFilePerms(), + &sums, -1, writeCallback, L); } // if retval += retvalBoolean(L, rc); From DONOTREPLY at icculus.org Wed Jan 16 07:23:36 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 16 Jan 2008 07:23:36 -0500 Subject: r428 - trunk Message-ID: <20080116122336.4059.qmail@icculus.org> Author: icculus Date: 2008-01-16 07:23:36 -0500 (Wed, 16 Jan 2008) New Revision: 428 Modified: trunk/lua_glue.c Log: Export the base archive's path and the app binary path to Lua. Modified: trunk/lua_glue.c =================================================================== --- trunk/lua_glue.c 2008-01-16 11:50:02 UTC (rev 427) +++ trunk/lua_glue.c 2008-01-16 12:23:36 UTC (rev 428) @@ -1493,6 +1493,7 @@ { const char *envr = cmdlinestr("locale", "MOJOSETUP_LOCALE", NULL); char *homedir = NULL; + char *binarypath = NULL; char locale[16]; char ostype[64]; char osversion[64]; @@ -1525,6 +1526,7 @@ registerLuaLibs(luaState); homedir = MojoPlatform_homedir(); + binarypath = MojoPlatform_appBinaryPath(); // !!! FIXME: I'd like to change the function name case for the lua hooks. @@ -1571,6 +1573,8 @@ set_string(luaState, GLuaLicense, "lualicense"); set_string(luaState, logLevelString(), "loglevel"); set_string(luaState, homedir, "homedir"); + set_string(luaState, binarypath, "binarypath"); + set_string(luaState, GBaseArchivePath, "basearchivepath"); set_string_array(luaState, GArgc, GArgv, "argv"); lua_newtable(luaState); set_string(luaState, "base", "base"); @@ -1623,6 +1627,7 @@ lua_setfield(luaState, -2, "archive"); lua_setglobal(luaState, MOJOSETUP_NAMESPACE); + free(binarypath); free(homedir); // Set up localization table, if possible. From DONOTREPLY at icculus.org Wed Jan 16 07:37:09 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 16 Jan 2008 07:37:09 -0500 Subject: r429 - trunk/scripts Message-ID: <20080116123709.3648.qmail@icculus.org> Author: icculus Date: 2008-01-16 07:37:07 -0500 (Wed, 16 Jan 2008) New Revision: 429 Modified: trunk/scripts/mojosetup_mainline.lua Log: Changed metadata directory structure. Modified: trunk/scripts/mojosetup_mainline.lua =================================================================== --- trunk/scripts/mojosetup_mainline.lua 2008-01-16 12:23:36 UTC (rev 428) +++ trunk/scripts/mojosetup_mainline.lua 2008-01-16 12:37:07 UTC (rev 429) @@ -591,11 +591,11 @@ local function set_destination(dest) - -- !!! FIXME: ".mojosetup_tmp" dirname may clash with install...? MojoSetup.loginfo("Install dest: '" .. dest .. "'") MojoSetup.destination = dest - MojoSetup.manifestdir = MojoSetup.destination .. "/.mojosetup_manifest" - MojoSetup.scratchdir = MojoSetup.destination .. "/.mojosetup_tmp" + MojoSetup.metadatadir = MojoSetup.destination .. "/.mojosetup" + MojoSetup.manifestdir = MojoSetup.metadatadir .. "/manifest" + MojoSetup.scratchdir = MojoSetup.metadatadir .. "/tmp" MojoSetup.rollbackdir = MojoSetup.scratchdir .. "/rollbacks" MojoSetup.downloaddir = MojoSetup.scratchdir .. "/downloads" end @@ -1263,6 +1263,7 @@ MojoSetup.manifest = nil MojoSetup.destination = nil MojoSetup.manifestdir = nil + MojoSetup.metadatadir = nil MojoSetup.scratchdir = nil MojoSetup.rollbackdir = nil MojoSetup.downloaddir = nil From DONOTREPLY at icculus.org Thu Jan 17 05:09:46 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 17 Jan 2008 05:09:46 -0500 Subject: r430 - trunk Message-ID: <20080117100946.30842.qmail@icculus.org> Author: icculus Date: 2008-01-17 05:09:43 -0500 (Thu, 17 Jan 2008) New Revision: 430 Modified: trunk/platform_unix.c Log: Implemented Mac OS X version of MojoPlatform_spawnTerminal(). Modified: trunk/platform_unix.c =================================================================== --- trunk/platform_unix.c 2008-01-16 12:37:07 UTC (rev 429) +++ trunk/platform_unix.c 2008-01-17 10:09:43 UTC (rev 430) @@ -973,9 +973,78 @@ #if PLATFORM_BEOS #error write me. // "/boot/apps/Terminal" + #elif PLATFORM_MACOSX - #error write me. - // "/Applications/Utilities/Terminal.app" + // this is nasty...it'd be nice if Terminal.app just took command lines. + boolean failed = false; + FILE *io = NULL; + char *cmd = NULL; + char *ptr = NULL; + char *binpath = MojoPlatform_appBinaryPath(); + size_t len = (strlen(binpath) * 5) + 3; + int i = 0; + for (i = 1; i < GArgc; i++) + len += (strlen(GArgv[i]) * 5) + 3; + + ptr = cmd = (char *) xmalloc(len+1); + for (i = 0; i < GArgc; i++) + { + const char *str = (i == 0) ? binpath : GArgv[i]; + if (i != 0) + *(ptr++) = ' '; + *(ptr++) = '\''; + while (*str) + { + const char ch = *(str++); + if (ch == '\'') + { + // have to escape for both AppleScript and /bin/sh. :/ + *(ptr++) = '\''; + *(ptr++) = '\\'; + *(ptr++) = '\\'; + *(ptr++) = '\''; + *(ptr++) = '\''; + } // if + else + { + *(ptr++) = ch; + } // else + } // while + *(ptr++) = '\''; + } // for + + free(binpath); + + *ptr = '\0'; + ptr = format( + "ignoring application responses\n" + "tell application \"Terminal\" to do script \"clear ; echo %0 -notermspawn=1 ; exit\"\n" + "tell application \"Terminal\" to tell its front window to set its custom title to \"MojoSetup\"\n" + "tell application \"Terminal\" to tell its front window to set its title displays device name to false\n" + "tell application \"Terminal\" to tell its front window to set its title displays shell path to false\n" + "tell application \"Terminal\" to tell its front window to set its title displays window size to false\n" + "tell application \"Terminal\" to tell its front window to set its title displays file name to false\n" + "tell application \"Terminal\" to tell its front window to set its title displays custom title to true\n" + "tell application \"Terminal\" to activate\n" + "end ignoring\n", cmd); + + free(cmd); + + io = popen("osascript -", "w"); + if (io == NULL) + failed = true; + else + { + failed |= (fwrite(ptr, strlen(ptr), 1, io) != 1); + failed |= (pclose(io) != 0); + } // else + + free(ptr); + + if (!failed) + exit(0); + + // otherwise, returning at all says we failed. #else // urgh From DONOTREPLY at icculus.org Thu Jan 17 05:11:31 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 17 Jan 2008 05:11:31 -0500 Subject: r431 - trunk Message-ID: <20080117101131.3368.qmail@icculus.org> Author: icculus Date: 2008-01-17 05:11:29 -0500 (Thu, 17 Jan 2008) New Revision: 431 Modified: trunk/platform_unix.c Log: Fixed terminal spawning on Unix to work no matter what cwd the new terminal shell starts in. Modified: trunk/platform_unix.c =================================================================== --- trunk/platform_unix.c 2008-01-17 10:09:43 UTC (rev 430) +++ trunk/platform_unix.c 2008-01-17 10:11:29 UTC (rev 431) @@ -1053,6 +1053,7 @@ "dtterm", "eterm", "Eterm", "aterm" }; + char *binpath = MojoPlatform_appBinaryPath(); const char *tryfirst = NULL; const int max_added_args = 5; const unsigned int argc = GArgc + max_added_args; @@ -1086,7 +1087,7 @@ argv[argi++] = is_gnome_term ? "--title" : "-title"; argv[argi++] = "MojoSetup"; argv[argi++] = is_gnome_term ? "-x" : "-e"; - argv[argi++] = GArgv[0]; + argv[argi++] = binpath; argv[argi++] = "-notermspawn=1"; assert(argi-1 <= max_added_args); @@ -1103,6 +1104,7 @@ // Still here? We failed. Mankind is wiped out in the Robot Wars. free(argv); + free(binpath); #endif } // MojoPlatform_spawnTerminal From DONOTREPLY at icculus.org Thu Jan 17 05:13:11 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 17 Jan 2008 05:13:11 -0500 Subject: r432 - trunk Message-ID: <20080117101311.7613.qmail@icculus.org> Author: icculus Date: 2008-01-17 05:13:06 -0500 (Thu, 17 Jan 2008) New Revision: 432 Modified: trunk/lua_glue.c Log: Added MojoSetup.archive.offsetofstart(), MojoSetup.copyfile(), and moved the bulk of writefile/copyfile/stringtofile into a generic backend. Modified: trunk/lua_glue.c =================================================================== --- trunk/lua_glue.c 2008-01-17 10:11:29 UTC (rev 431) +++ trunk/lua_glue.c 2008-01-17 10:13:06 UTC (rev 432) @@ -746,15 +746,12 @@ // !!! FIXME: push this into Lua, make things fatal. -static int luahook_writefile(lua_State *L) +static int do_writefile(lua_State *L, MojoInput *in, uint16 perms) { - MojoArchive *archive = (MojoArchive *) lua_touserdata(L, 1); const char *path = luaL_checkstring(L, 2); int retval = 0; boolean rc = false; - uint16 perms = archive->prevEnum.perms; MojoChecksums sums; - MojoInput *in = archive->openCurrentEntry(archive); int64 maxbytes = -1; if (in != NULL) @@ -779,9 +776,38 @@ if (rc) retval += retvalChecksums(L, &sums); return retval; +} // do_writefile + + +static int luahook_writefile(lua_State *L) +{ + MojoArchive *archive = (MojoArchive *) lua_touserdata(L, 1); + uint16 perms = archive->prevEnum.perms; + MojoInput *in = archive->openCurrentEntry(archive); + return do_writefile(L, in, perms); } // luahook_writefile +static int luahook_copyfile(lua_State *L) +{ + const char *src = luaL_checkstring(L, 1); + MojoInput *in = MojoInput_newFromFile(src); + return do_writefile(L, in, MojoPlatform_defaultFilePerms()); +} // luahook_copyfile + + +static int luahook_stringtofile(lua_State *L) +{ + const char *str = luaL_checkstring(L, 1); + MojoInput *in = NULL; + size_t len = 0; + str = lua_tolstring(L, 1, &len); + in = MojoInput_newFromMemory((const uint8 *) str, (uint32) len, 1); + assert(in != NULL); // xmalloc() would fatal(), should not return NULL. + return do_writefile(L, in, MojoPlatform_defaultFilePerms()); +} // luahook_stringtofile + + static int luahook_isvalidperms(lua_State *L) { boolean valid = false; @@ -887,6 +913,13 @@ } // luahook_archive_close +static int luahook_archive_offsetofstart(lua_State *L) +{ + MojoArchive *archive = (MojoArchive *) lua_touserdata(L, 1); + return retvalNumber(L, (lua_Number) archive->offsetOfStart); +} // luahook_archive_offsetofstart + + static int luahook_platform_unlink(lua_State *L) { const char *path = luaL_checkstring(L, 1); @@ -984,38 +1017,6 @@ } // luahook_movefile -// !!! FIXME: this is a lot of duplication from luahook_writefile -static int luahook_stringtofile(lua_State *L) -{ - const char *str = luaL_checkstring(L, 1); - const char *path = luaL_checkstring(L, 2); - MojoInput *in = NULL; - size_t len = 0; - int retval = 0; - boolean rc = false; - uint16 perms = MojoPlatform_defaultFilePerms(); - MojoChecksums sums; - - str = lua_tolstring(L, 1, &len); - in = MojoInput_newFromMemory((const uint8 *) str, (uint32) len, 1); - assert(in != NULL); // xmalloc() would fatal(), should not return NULL. - if (!lua_isnil(L, 3)) - { - boolean valid = false; - const char *permstr = luaL_checkstring(L, 3); - perms = MojoPlatform_makePermissions(permstr, &valid); - if (!valid) - fatal(_("BUG: '%0' is not a valid permission string"), permstr); - } // if - rc = MojoInput_toPhysicalFile(in, path, perms, &sums, -1, writeCallback, L); - - retval += retvalBoolean(L, rc); - if (rc) - retval += retvalChecksums(L, &sums); - return retval; -} // luahook_stringtofile - - static void prepareSplash(MojoGuiSplash *splash, const char *fname) { MojoInput *io = NULL; @@ -1552,6 +1553,7 @@ set_cfunc(luaState, luahook_debugger, "debugger"); set_cfunc(luaState, luahook_findmedia, "findmedia"); set_cfunc(luaState, luahook_writefile, "writefile"); + set_cfunc(luaState, luahook_copyfile, "copyfile"); set_cfunc(luaState, luahook_stringtofile, "stringtofile"); set_cfunc(luaState, luahook_download, "download"); set_cfunc(luaState, luahook_movefile, "movefile"); @@ -1623,6 +1625,7 @@ set_cfunc(luaState, luahook_archive_enumerate, "enumerate"); set_cfunc(luaState, luahook_archive_enumnext, "enumnext"); set_cfunc(luaState, luahook_archive_close, "close"); + set_cfunc(luaState, luahook_archive_offsetofstart, "offsetofstart"); set_cptr(luaState, GBaseArchive, "base"); lua_setfield(luaState, -2, "archive"); lua_setglobal(luaState, MOJOSETUP_NAMESPACE); From DONOTREPLY at icculus.org Thu Jan 17 05:16:17 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 17 Jan 2008 05:16:17 -0500 Subject: r433 - trunk Message-ID: <20080117101617.15417.qmail@icculus.org> Author: icculus Date: 2008-01-17 05:16:06 -0500 (Thu, 17 Jan 2008) New Revision: 433 Modified: trunk/lua_glue.c Log: Generalized MojoSetup.download(), too. Modified: trunk/lua_glue.c =================================================================== --- trunk/lua_glue.c 2008-01-17 10:13:06 UTC (rev 432) +++ trunk/lua_glue.c 2008-01-17 10:16:06 UTC (rev 433) @@ -788,6 +788,14 @@ } // luahook_writefile +static int luahook_download(lua_State *L) +{ + const char *src = luaL_checkstring(L, 1); + MojoInput *in = MojoInput_fromURL(src); + return do_writefile(L, in, MojoPlatform_defaultFilePerms()); +} // luahook_download + + static int luahook_copyfile(lua_State *L) { const char *src = luaL_checkstring(L, 1); @@ -819,27 +827,6 @@ } // luahook_isvalidperms -static int luahook_download(lua_State *L) -{ - const char *url = luaL_checkstring(L, 1); - const char *dst = luaL_checkstring(L, 2); - int retval = 0; - boolean rc = false; - MojoChecksums sums; - MojoInput *in = MojoInput_fromURL(url); - if (in != NULL) - { - rc = MojoInput_toPhysicalFile(in, dst, MojoPlatform_defaultFilePerms(), - &sums, -1, writeCallback, L); - } // if - - retval += retvalBoolean(L, rc); - if (rc) - retval += retvalChecksums(L, &sums); - return retval; -} // luahook_download - - static int luahook_archive_fromdir(lua_State *L) { const char *path = luaL_checkstring(L, 1); From DONOTREPLY at icculus.org Thu Jan 17 05:18:36 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 17 Jan 2008 05:18:36 -0500 Subject: r434 - trunk/scripts Message-ID: <20080117101836.20228.qmail@icculus.org> Author: icculus Date: 2008-01-17 05:18:30 -0500 (Thu, 17 Jan 2008) New Revision: 434 Modified: trunk/scripts/localization.lua trunk/scripts/mojosetup_mainline.lua Log: Attempt to install control binary and other work. Modified: trunk/scripts/localization.lua =================================================================== --- trunk/scripts/localization.lua 2008-01-17 10:16:06 UTC (rev 433) +++ trunk/scripts/localization.lua 2008-01-17 10:18:30 UTC (rev 434) @@ -318,6 +318,12 @@ nb = "FEIL: Kan ikke duplisere innfiler for tar", }; + -- This is a generic error message when a programming bug produced a + -- result we weren't expecting (a negative number when we expected + -- positive, etc...) + ["BUG: Unexpected value"] = { + }; + -- Buggy config elements: -- This is supposed to be a config element (%0) and something that's wrong -- with it (%1), such as "BUG: Config Package::description not a string" Modified: trunk/scripts/mojosetup_mainline.lua =================================================================== --- trunk/scripts/mojosetup_mainline.lua 2008-01-17 10:16:06 UTC (rev 433) +++ trunk/scripts/mojosetup_mainline.lua 2008-01-17 10:18:30 UTC (rev 434) @@ -313,6 +313,14 @@ end +local function install_file_from_filesystem(dest, src, perms, desc, manifestkey, maxbytes) + local fn = function(callback) + return MojoSetup.copyfile(src, dest, perms, maxbytes, callback) + end + return install_file(dest, perms, fn, desc, manifestkey) +end + + -- !!! FIXME: we should probably pump the GUI queue here, in case there are -- !!! FIXME: thousands of symlinks in a row or something. local function install_symlink(dest, lndest, manifestkey) @@ -394,7 +402,7 @@ allowoverwrite = file.allowoverwrite if not allowoverwrite then MojoSetup.loginfo("File '" .. dest .. "' already exists.") - local text = MojoSetup.format(_("File '%0' already exists! Replace?"), dest); + local text = MojoSetup.format(_("File '%0' already exists! Replace?"), dest) local ynan = MojoSetup.promptynan(_("Conflict!"), text, true) if ynan == "always" then MojoSetup.forceoverwrite = true @@ -428,6 +436,22 @@ return allowoverwrite end + +local function install_archive_entity(dest, ent, archive, desc, manifestkey) + install_parent_dirs(dest, manifestkey) + if ent.type == "file" then + install_file_from_archive(dest, archive, perms, desc, manifestkey) + elseif ent.type == "dir" then + install_directory(dest, perms, manifestkey) + elseif ent.type == "symlink" then + install_symlink(dest, ent.linkdest, manifestkey) + else -- !!! FIXME: device nodes, etc... + -- !!! FIXME: should this be fatal? + MojoSetup.fatal(_("Unknown file type in archive")) + end +end + + local function install_archive_entry(archive, ent, file, option) local entdest = ent.filename if entdest == nil then return end -- probably can't happen... @@ -453,18 +477,8 @@ if dest ~= nil then -- Only install if file wasn't filtered out dest = MojoSetup.destination .. "/" .. dest if permit_write(dest, ent, file) then - install_parent_dirs(dest, option) - if ent.type == "file" then - local desc = option.description - install_file_from_archive(dest, archive, perms, desc, option) - elseif ent.type == "dir" then - install_directory(dest, perms, option) - elseif ent.type == "symlink" then - install_symlink(dest, ent.linkdest, option) - else -- !!! FIXME: device nodes, etc... - -- !!! FIXME: should this be fatal? - MojoSetup.fatal(_("Unknown file type in archive")) - end + local desc = option.description + install_archive_entity(dest, ent, archive, desc, option) end end end @@ -594,6 +608,7 @@ MojoSetup.loginfo("Install dest: '" .. dest .. "'") MojoSetup.destination = dest MojoSetup.metadatadir = MojoSetup.destination .. "/.mojosetup" + MojoSetup.controldir = MojoSetup.metadatadir .. "/control" MojoSetup.manifestdir = MojoSetup.metadatadir .. "/manifest" MojoSetup.scratchdir = MojoSetup.metadatadir .. "/tmp" MojoSetup.rollbackdir = MojoSetup.scratchdir .. "/rollbacks" @@ -730,7 +745,7 @@ if type(desc) == "table" then -- "meta" etc, or an option table. desc = option.description end - man[desc] = items; + man[desc] = items end local install = MojoSetup.install @@ -760,11 +775,71 @@ end -local function install_manifests() +local function install_control_app(desc, key) + local dst, src + + -- We copy the installer binary itself, and any auxillary files it needs, + -- like this Lua script, to a metadata directory in the installation. + -- Unfortunately, the binary might be a self-extracting installer that + -- has gigabytes of now-unnecessary data appended to it, so we need to + -- decide if that's the case and, if so, extract just the program itself + -- from the start of the file. + local maxbytes = -1 -- copy whole thing by default. + local base = MojoSetup.archive.base + + -- !!! FIXME: This needs an ".exe" appended on Windows. + dst = MojoSetup.controldir .. "/mojosetup" + src = MojoSetup.info.binarypath + if src == MojoSetup.info.basearchivepath then + local base = MojoSetup.archive.base + maxbytes = MojoSetup.archive.offsetofstart(base) + if maxbytes <= 0 then + MojoSetup.fatal(_("BUG: Unexpected value")) + end + end + + local perms = "0755" -- !!! FIXME + install_parent_dirs(dst, key); + install_file_from_filesystem(dst, src, perms, desc, key, maxbytes) + + -- Okay, now we need all the support files. + if not MojoSetup.archive.enumerate(base) then + MojoSetup.fatal(_("Couldn't enumerate archive")) + end + + local needdirs = { "scripts", "gui", "meta" } + + local ent = MojoSetup.archive.enumnext(base) + while ent ~= nil do + -- Make sure this is in a directory we want to write out... + local should_write = false + if (ent.filename ~= nil) and (ent.filename ~= "") then + for i,dir in ipairs(needdirs) do + local clipdir = "^" .. dir .. "/" + if string.find(ent.filename, clipdir) ~= nil then + should_write = true + break + end + end + end + + if should_write then + dst = MojoSetup.controldir .. "/" .. ent.filename + install_archive_entity(dst, ent, base, desc, key) + end + + -- and check the next entry in the archive... + ent = MojoSetup.archive.enumnext(archive) + end + + -- okay, we're written out. +end + + +local function install_manifests(desc, key) -- We write out a Lua script as a data definition language, a -- loki_setup-compatible XML manifest, and a straight text file of -- all the filenames. Take your pick. - local key = ".mojosetup_metadata." -- We have to cheat and just plug these into the manifest directly, since -- they won't show up until after we write them out, otherwise. @@ -789,7 +864,6 @@ install_parent_dirs(txt_fname, key) -- now build these things... - local desc = _("Metadata") install_file_from_string(lua_fname, build_lua_manifest(), perms, desc, nil) install_file_from_string(xml_fname, build_xml_manifest(), perms, desc, nil) install_file_from_string(txt_fname, build_txt_manifest(), perms, desc, nil) @@ -1106,7 +1180,7 @@ item = MojoSetup.format(_("%0: %1%% (%2)"), fname, calc_percent(bw, total), - ratestr); + ratestr) end return MojoSetup.gui.progress(ptype, component, percent, item) end @@ -1187,9 +1261,14 @@ end end + local metadatakey = ".mojosetup_metadata." + local metadatadesc = _("Metadata") + + install_control_app(metadatadesc, metadatakey) + run_config_defined_hook(install.postinstall, install) - install_manifests() -- write out manifest. + install_manifests(metadatadesc, metadatakey) -- write out manifest. return 1 -- go to next stage. end @@ -1264,6 +1343,7 @@ MojoSetup.destination = nil MojoSetup.manifestdir = nil MojoSetup.metadatadir = nil + MojoSetup.controldir = nil MojoSetup.scratchdir = nil MojoSetup.rollbackdir = nil MojoSetup.downloaddir = nil From DONOTREPLY at icculus.org Thu Jan 17 05:19:17 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 17 Jan 2008 05:19:17 -0500 Subject: r435 - in trunk: . libfetch Message-ID: <20080117101917.22170.qmail@icculus.org> Author: icculus Date: 2008-01-17 05:19:16 -0500 (Thu, 17 Jan 2008) New Revision: 435 Modified: trunk/fileio.c trunk/fileio.h trunk/libfetch/common.c trunk/lua_glue.c trunk/mojosetup.c Log: ...not sure why MojoInput_fromURL() was named differently from all the other MojoInput_newFromXXX() functions... Modified: trunk/fileio.c =================================================================== --- trunk/fileio.c 2008-01-17 10:18:30 UTC (rev 434) +++ trunk/fileio.c 2008-01-17 10:19:16 UTC (rev 435) @@ -708,11 +708,11 @@ // This stub is here if we didn't compile in libfetch... #if !SUPPORT_URL_HTTP && !SUPPORT_URL_FTP -MojoInput *MojoInput_fromURL(const char *url) +MojoInput *MojoInput_newFromURL(const char *url) { logError("No networking support in this build."); return NULL; -} // MojoInput_fromURL +} // MojoInput_newFromURL #endif // end of fileio.c ... Modified: trunk/fileio.h =================================================================== --- trunk/fileio.h 2008-01-17 10:18:30 UTC (rev 434) +++ trunk/fileio.h 2008-01-17 10:19:16 UTC (rev 435) @@ -107,7 +107,7 @@ MojoChecksums *checksums, int64 maxbytes, MojoInput_FileCopyCallback cb, void *data); -MojoInput *MojoInput_fromURL(const char *url); +MojoInput *MojoInput_newFromURL(const char *url); #ifdef __cplusplus } Modified: trunk/libfetch/common.c =================================================================== --- trunk/libfetch/common.c 2008-01-17 10:18:30 UTC (rev 434) +++ trunk/libfetch/common.c 2008-01-17 10:19:16 UTC (rev 435) @@ -1060,7 +1060,7 @@ -MojoInput *MojoInput_fromURL(const char *url) +MojoInput *MojoInput_newFromURL(const char *url) { MojoInput *retval = NULL; if (url != NULL) @@ -1087,6 +1087,6 @@ } // if } // if return retval; -} // MojoInput_fromURL +} // MojoInput_newFromURL #endif Modified: trunk/lua_glue.c =================================================================== --- trunk/lua_glue.c 2008-01-17 10:18:30 UTC (rev 434) +++ trunk/lua_glue.c 2008-01-17 10:19:16 UTC (rev 435) @@ -791,7 +791,7 @@ static int luahook_download(lua_State *L) { const char *src = luaL_checkstring(L, 1); - MojoInput *in = MojoInput_fromURL(src); + MojoInput *in = MojoInput_newFromURL(src); return do_writefile(L, in, MojoPlatform_defaultFilePerms()); } // luahook_download Modified: trunk/mojosetup.c =================================================================== --- trunk/mojosetup.c 2008-01-17 10:18:30 UTC (rev 434) +++ trunk/mojosetup.c 2008-01-17 10:19:16 UTC (rev 435) @@ -814,7 +814,7 @@ int64 total_br = 0; int64 br = 0; printf("\n\nFetching '%s' ...\n", url); - MojoInput *io = MojoInput_fromURL(url); + MojoInput *io = MojoInput_newFromURL(url); if (io == NULL) { fprintf(stderr, "failed!\n"); From DONOTREPLY at icculus.org Thu Jan 17 05:33:24 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 17 Jan 2008 05:33:24 -0500 Subject: r436 - trunk/scripts Message-ID: <20080117103324.3783.qmail@icculus.org> Author: icculus Date: 2008-01-17 05:33:22 -0500 (Thu, 17 Jan 2008) New Revision: 436 Modified: trunk/scripts/mojosetup_mainline.lua Log: Bunch of fixes for last few checkins. Modified: trunk/scripts/mojosetup_mainline.lua =================================================================== --- trunk/scripts/mojosetup_mainline.lua 2008-01-17 10:19:16 UTC (rev 435) +++ trunk/scripts/mojosetup_mainline.lua 2008-01-17 10:33:22 UTC (rev 436) @@ -307,7 +307,7 @@ local function install_file_from_string(dest, string, perms, desc, manifestkey) local fn = function(callback) - return MojoSetup.stringtofile(string, dest, perms, callback) + return MojoSetup.stringtofile(string, dest, perms, nil, callback) end return install_file(dest, perms, fn, desc, manifestkey) end @@ -791,7 +791,6 @@ dst = MojoSetup.controldir .. "/mojosetup" src = MojoSetup.info.binarypath if src == MojoSetup.info.basearchivepath then - local base = MojoSetup.archive.base maxbytes = MojoSetup.archive.offsetofstart(base) if maxbytes <= 0 then MojoSetup.fatal(_("BUG: Unexpected value")) @@ -807,7 +806,7 @@ MojoSetup.fatal(_("Couldn't enumerate archive")) end - local needdirs = { "scripts", "gui", "meta" } + local needdirs = { "scripts", "guis", "meta" } local ent = MojoSetup.archive.enumnext(base) while ent ~= nil do @@ -829,7 +828,7 @@ end -- and check the next entry in the archive... - ent = MojoSetup.archive.enumnext(archive) + ent = MojoSetup.archive.enumnext(base) end -- okay, we're written out. @@ -1186,7 +1185,7 @@ end MojoSetup.loginfo("Download '" .. url .. "' to '" .. f .. "'") - local downloaded, sums = MojoSetup.download(url, f, callback) + local downloaded, sums = MojoSetup.download(url, f, nil, nil, callback) if not downloaded then MojoSetup.fatal(_("File download failed!")) end From DONOTREPLY at icculus.org Sat Jan 19 17:19:15 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 19 Jan 2008 17:19:15 -0500 Subject: r437 - trunk/scripts Message-ID: <20080119221915.23396.qmail@icculus.org> Author: icculus Date: 2008-01-19 17:19:14 -0500 (Sat, 19 Jan 2008) New Revision: 437 Modified: trunk/scripts/localization.lua Log: Swedish translation (thanks, Ulrik!) Modified: trunk/scripts/localization.lua =================================================================== --- trunk/scripts/localization.lua 2008-01-17 10:33:22 UTC (rev 436) +++ trunk/scripts/localization.lua 2008-01-19 22:19:14 UTC (rev 437) @@ -62,36 +62,42 @@ ["need dictionary"] = { de = "W?rterbuch ben?tigt", nb = "trenger ordbok", + se = "beh?ver ordbok", }; -- zlib error message ["data error"] = { de = "Datenfehler", nb = "datafeil", + se = "datafel", }; -- zlib error message ["memory error"] = { de = "Speicherfehler", nb = "minnefeil", + se = "minnesfel", }; -- zlib error message ["buffer error"] = { de = "Pufferfehler", nb = "bufferfeil", + se = "bufferfel", }; -- zlib error message ["version error"] = { de = "Versionsfehler", nb = "versjonsfeil", + se = "versionsfel", }; -- zlib error message ["unknown error"] = { de = "Unbekannter Fehler", nb = "ukjent feil", + se = "ok?nt fel", }; -- stdio UI plugin says this for "OK"-only msgboxes. "%0" is the message @@ -99,6 +105,7 @@ ["NOTICE: %0\n[hit enter]"] = { de = "HINWEIS: %0\n[Dr?cken Sie Enter]", nb = "NB: %0\n[trykk enter]", + se = "NB: %0\n[tryck enter]", }; -- stdio UI plugin says this for yes/no prompts that default to yes. @@ -106,6 +113,7 @@ ["%0\n[Y/n]: "] = { de = "%0\n[J/n]", nb = "%0\n[J/n]: ", + se = "%0\n[J/n]: ", }; -- stdio UI plugin says this for yes/no prompts that default to no. @@ -113,6 +121,7 @@ ["%0\n[y/N]: "] = { de = "%0\n[j/N]", nb = "%0\n[j/N]: ", + se = "%0\n[j/N]: ", }; -- stdio UI plugin says this for yes/no/always/never prompts. @@ -120,18 +129,21 @@ ["%0\n[y/n/Always/Never]: "] = { de = "%0\n[j/n/Immer/Niemals]", nb = "%0\n[j/n/Alltid/Aldri]: ", + se = "%0\n[j/n/Alltid/Aldrig]: ", }; -- This is used for "yes" in stdio UI's yes/no prompts (case insensitive). ["Y"] = { de = "J", nb = "J", + se = "J", }; -- This is used for "no" in stdio UI's yes/no prompts (case insensitive). ["N"] = { de = "N", nb = "N", + se = "N", }; -- This is used for "always" in stdio UI's yes/no/always/never prompts @@ -139,6 +151,7 @@ ["Always"] = { de = "Immer", nb = "Alltid", + se = "Alltid", }; -- This is used for "never" in stdio UI's yes/no/always/never prompts @@ -146,6 +159,7 @@ ["Never"] = { de = "Niemals", nb = "Aldri", + se = "Aldrig", }; -- This is shown when using stdio UI's built-in README pager, to @@ -154,6 +168,7 @@ ["(%0-%1 of %2 lines, see more?)"] = { de = "(%0-%1 von %2 Zeilen, mehr anschauen?)", nb = "(%0-%1 av %2 linjer, se mer?)", + se = "(%0-%1 av %2 linjer, se mer?)", }; -- The stdio UI uses this sentence in the prompt if the user is able @@ -162,6 +177,7 @@ ["Type '%0' to go back."] = { de = "Dr?cken Sie '%0' um zur?ckzugehen.", nb = "Skriv '%0' for ? g? tilbake.", + se = "Skriv '%0' f?r att g? tillbaka.", }; -- This is the string used for the '%0' in the above string. @@ -171,18 +187,21 @@ ["back"] = { de = "zur?ck", nb = "tilbake", + se = "tillbaka", }; -- This is the prompt in the stdio driver when user input is expected. ["> "] = { de = "> ", nb = "> ", + se = "> ", }; -- That's meant to be the name of an item (%0) and the percent done (%1). ["%0: %1%%"] = { de = "%0: %1%%", nb = "%0: %1%%", + se = "%0: %1%%", }; -- The stdio UI uses this to show current status (%0), @@ -190,6 +209,7 @@ ["%0 (total progress: %1%%)"] = { de = "%0 (Gesamtfortschritt: %1%%)", nb = "%0 (totalt: %1%%)", + se = "%0 (totalt: %1%%)", }; -- This prompt is shown to the end-user after an End User License Agreement @@ -198,6 +218,7 @@ ["Accept this license?"] = { de = "Nehmen Sie die Lizenzbedingungen an?", nb = "Akseptere denne lisensen?", + se = "Acceptera licensen?", }; -- This is a GTK+ button label for yes/no/always/never questions. @@ -205,6 +226,7 @@ ["_Always"] = { de = "_Immer", nb = "_Alltid", + se = "_Alltid", }; -- This is an error message reported when a .zip file (or whatever) that @@ -212,6 +234,7 @@ ["Archive not found"] = { de = "Archiv nicht gefunden", nb = "Fant ikke arkiv", + se = "Hittade inte arkivet", }; -- This prompt is shown to the user when they click the "Cancel" button, @@ -219,12 +242,14 @@ ["Are you sure you want to cancel installation?"] = { de = "Sind Sie sicher, dass Sie die Installation abbrechen wollen?", nb = "Er du sikker p? at du vil avbryte installasjonen?", + se = "?r du s?ker p? att du vill avbryta installationen?", }; -- The opposite of "next", used as a UI button label. ["Back"] = { de = "Zur?ck", nb = "Tilbake", + se = "Tillbaka", }; -- This is a GTK+ button label. The '_' comes before the hotkey character. @@ -233,6 +258,7 @@ ["B_rowse..."] = { de = "D_urchsuchen", nb = "B_la gjennom...", + se = "B_l?ddra", }; @@ -248,6 +274,7 @@ ["BUG: duplicate media id"] = { de = "FEHLER: Doppelte Medien-ID", nb = "FEIL: duplisert media-id", + se = "FEL: dupliserat media id", }; -- This is shown if the configuration file has no installable options, @@ -256,6 +283,7 @@ ["BUG: no options"] = { de = "FEHLER: Keine Optionen", nb = "FEIL: ingen valg", + se = "FEL: inget option", }; -- This is a file's permissions. Programmers give these as strings, and @@ -265,6 +293,7 @@ ["BUG: '%0' is not a valid permission string"] = { de = "FEHLER: '%0' ist keine zul?ssiger Berechtigungs-String", nb = "FEIL: '%0' er ikke en gyldig rettighetsstreng", + se = "FEL: '%0' ?r inte en giltig r?ttighetsstr?ng", }; -- If there's a string in the program that needs be formatted with @@ -274,6 +303,7 @@ ["BUG: Invalid format() string"] = { de = "FEHLER: Unzul?ssiger format() String", nb = "FEIL: Ugyldig format()-streng", + se = "FEL: Ogiltig format() str?ng", }; -- The program runs in "stages" and as it transitions from one stage to @@ -283,6 +313,7 @@ ["BUG: stage returned wrong type"] = { de = "FEHLER: Abschnitt gab falschen Typ zur?ck", nb = "FEIL: niv? returnerte feil type", + se = "FEL: niv? returnerade fel type", }; -- The program runs in "stages" and as it transitions from one stage to @@ -292,6 +323,7 @@ ["BUG: stage returned wrong value"] = { de = "FEHLER: Abschnitt gab falschen Wert zur?ck", nb = "FEIL: niv? returnerte feil verdi", + se = "FEL: niv? returnerade fel v?rde", }; -- The program runs in "stages", which can in many cases be revisited @@ -301,6 +333,7 @@ ["BUG: stepped back over start of stages"] = { de = "FEHLER: ?ber den Startabschnitt hinaus zur?ckgegangen", nb = "FEIL: Gikk tilbake forbi startniv?", + se = "FEL: Gick tillbaka f?rbi startniv?", }; -- This happens if there's an unusual case when writing out Lua scripts @@ -308,6 +341,7 @@ ["BUG: Unhandled data type"] = { de = "FEHLER: Unbehandelter Datentyp", nb = "FEIL: Uh?ndtert datatype", + se = "FEL: Ohanterad datatyp", }; -- This is triggered by a logic bug in the i/o subsystem. @@ -316,12 +350,14 @@ ["BUG: Can't duplicate tar inputs"] = { de = "FEHLER: Tar-Eingaben k?nnen nicht dupliziert werden", nb = "FEIL: Kan ikke duplisere innfiler for tar", + se = "FEL: Kan inte duplicera infiler f?r tar", }; -- This is a generic error message when a programming bug produced a -- result we weren't expecting (a negative number when we expected -- positive, etc...) ["BUG: Unexpected value"] = { + se = "FEL: Ov?ntat v?rde", }; -- Buggy config elements: @@ -332,54 +368,63 @@ ["BUG: Config %0 %1"] = { de = "FEHLER: Konfiguration %0 %1", nb = "FEIL: Konfigurasjon %0 %1", + se = "FEL: Konfiguration %0 %1", }; -- This is an error string for a buggy config element. See notes above. ["must be explicitly specified"] = { de = "muss explizit angegeben werden", nb = "m? gis eksplisitt", + se = "m?ste vara explicit specifierad", }; -- This is an error string for a buggy config element. See notes above. ["must be string or table of strings"] = { de = "muss ein String oder eine Tabelle von Strings sein", nb = "m? v?re streng eller tabell av strenger", + se = "m?ste vara str?ng eller tabell av str?ngar", }; -- This is an error string for a buggy config element. See notes above. ["must be a string or number"] = { de = "muss ein String oder eine Zahl sein", nb = "m? v?re streng eller nummer", + se = "m?ste vara str?ng eller nummer", }; -- This is an error string for a buggy config element. See notes above. ["can't be empty string"] = { de = "darf kein leerer String sein", nb = "kan ikke v?re tom streng", + se = "kan inte vara tom str?ng", }; -- This is an error string for a buggy config element. See notes above. ["URL doesn't have protocol"] = { de = "URL hat kein Protokoll", nb = "URL har ikke protokoll", + se = "URL saknar protokoll", }; -- This is an error string for a buggy config element. See notes above. ["URL doesn't have host"] = { de = "URL hat keinen Host", nb = "URL har ikke vert", + se = "URL saknar v?rd", }; -- This is an error string for a buggy config element. See notes above. ["URL doesn't have path"] = { de = "URL hat keinen Pfad", nb = "URL har ikke sti", + se = "URL saknar s?kv?g", }; -- This is an error string for a buggy config element. See notes above. ["URL protocol is unsupported"] = { de = "URL Protokoll wird nicht unterst?tzt", nb = "URL-protokoll er ikke st?ttet", + se = "URL protokollet har inget st?d", }; -- This is an error string for a buggy config element. See notes above. @@ -388,6 +433,7 @@ ["Permission string is invalid"] = { de = "Berechtigungs-String ist ung?ltig", nb = "Rettighetsstreng er ugyldig", + se = "R?ttighetsstr?ngen ?r ogiltig", }; -- This is an error string for a buggy config element. See notes above. @@ -395,6 +441,7 @@ ["is not a valid property"] = { de = "ist keine g?ltige Eigenschaft", nb = "er ikke en gyldig egenskap", + se = "?r inte ett giltigt attribut", }; -- This is an error string for a buggy config element. See notes above. @@ -402,36 +449,42 @@ ["must be %0"] = { de = "muss vom Typ %0 sein", nb = "m? v?re %0", + se = "m?ste vara %0", }; -- Data type for "must be %0" above... ["string"] = { de = "String", nb = "streng", + se = "str?ng", }; -- Data type for "must be %0" above... ["boolean"] = { de = "Bool", nb = "boolsk verdi", + se = "boolskt v?rde", }; -- Data type for "must be %0" above... ["number"] = { de = "Zahl", nb = "nummer", + se = "nummer", }; -- Data type for "must be %0" above... ["function"] = { de = "Funktion", nb = "funksjon", + se = "funktion", }; -- Data type for "must be %0" above... ["table"] = { de = "Tabelle", nb = "tabell", + se = "tabell", }; @@ -440,6 +493,7 @@ ["bzlib triggered an internal error: %0"] = { de = "bzlib hat einen internen Fehler ausgel?st: %0", nb = "intern feil i bzlib: %0", + se = "internt fel i bzlib: %0", }; -- This is a UI button label, usually paired with "OK", but also usually @@ -447,6 +501,7 @@ ["Cancel"] = { de = "Abbrechen", nb = "Avbryt", + se = "Avbryt", }; -- This is a message box title when prompting for confirmation when the @@ -454,6 +509,7 @@ ["Cancel installation"] = { de = "Installation abbrechen", nb = "Avbryt installasjonen", + se = "Avbryt installationen", }; -- This error is reported for i/o failures while listing files contained @@ -461,6 +517,7 @@ ["Couldn't enumerate archive"] = { de = "Archiv kann nicht aufgelistet werden", nb = "Kunne ikke enumerere arkiv", + se = "Kunde inte lista filen", }; -- This error is reported for i/o failures while opening a .zip @@ -468,6 +525,7 @@ ["Couldn't open archive"] = { de = "Archiv kann nicht ge?ffnet werden", nb = "Kunne ikke ?pne arkiv", + se = "Kunde inte ?ppna filen", }; -- This is used by the stdio UI to choose a location to write files. @@ -478,6 +536,7 @@ ["Choose install destination by number (hit enter for #1), or enter your own."] = { de = "W?hlen Sie eine Nummer f?r das Installationsziel (dr?cken Sie Enter f?r #1), oder geben Sie ein eigenes an.", nb = "Velg installasjonssti etter nummer (trykk enter for #1), eller skriv din egen.", + se = "V?lg s?kv?g f?r installationen efter nummer (tryck enter f?r #1), eller skriv in din egen.", }; -- This is used by the stdio UI to toggle options. A numbered list is @@ -487,6 +546,7 @@ ["Choose number to change."] = { de = "W?hlen Sie eine Nummer zum ?ndern.", nb = "Velg nummer som skal endres.", + se = "V?lg nummer som skall ?ndras.", }; -- As in "two different files want to use the same name." This is a title @@ -494,6 +554,7 @@ ["Conflict!"] = { de = "Konflikt!", nb = "Konflikt!", + se = "Konflikt!", }; -- This is an error message shown to the user. When a file is to be @@ -504,6 +565,7 @@ ["Couldn't backup file for rollback"] = { de = "Konnte Datei nicht zum Zur?cknehmen sichern", nb = "Kunne ikke sikkerhetskopiere fil for tilbakerulling", + se = "Kunde inte s?kerhetskopiera filen f?r ?terst?llning", }; -- This error is shown if we aren't able to write the list of files @@ -511,30 +573,35 @@ ["Couldn't create manifest"] = { de = "Konnte Manifest nicht erstellen", nb = "Kunne ikke lage manifest", + se = "Kunde inte skapa manifest", }; -- This is an error message. It speaks for itself. :) ["Couldn't restore some files. Your existing installation is likely damaged."] = { de = "Konnte einige Dateien nicht widerherstellen. Ihre Installation ist wahrscheinlich besch?digt.", nb = "Noen filer kunne ikke tilbakestilles. Den eksisterende installasjonen er sannsynligvis skadet.", + se = "N?gra filer kunde inte ?terskapas. Den existerande installationen ?r troligtvis skadad.", }; -- Error message when deleting a file fails. ["Deletion failed!"] = { de = "L?schen fehlgeschlagen!", nb = "Kunne ikke slette!", + se = "Kunde inte radera!", }; -- This is a label displayed next to the text entry in the GTK+ UI where -- the user specifies the installation destination (folder/directory) in -- the filesystem. ["Folder:"] = { + se = "Katalog:", }; -- This is a window title when user is selecting a path to install files. ["Destination"] = { de = "Ziel", nb = "Destinasjon", + se = "Destination", }; -- This is a window title while the program is downloading external files @@ -542,6 +609,7 @@ ["Downloading"] = { de = "Herunterladen", nb = "Laster ned", + se = "Laddar ner", }; -- Several UIs use this string as a prompt to the end-user when selecting @@ -549,30 +617,35 @@ ["Enter path where files will be installed."] = { de = "Geben Sie den Pfad an, wo Dateien installiert werden sollen.", nb = "Skriv inn destinasjonssti for installasjonen.", + se = "Skriv in s?kv?gen f?r installationen.", }; -- Error message when a file we expect to load can't be read from disk. ["failed to load file '%0'"] = { de = "Laden von Datei '%0' fehlgeschlagen", nb = "kunne ikke laste fil '%0'", + se = "kunde inte ladda filen '%0'", }; -- This is a window title when something goes very wrong. ["Fatal error"] = { de = "Schwerer Fehler", nb = "Fatal feil", + se = "Fatalt fel", }; -- This is an error message when failing to write a file to disk. ["File creation failed!"] = { de = "Dateierstellung fehlgeschlagen!", nb = "Kunne ikke lage fil!", + se = "Kunde inte skapa filen!", }; -- This is an error message when failing to get a file from the network. ["File download failed!"] = { de = "Dateidownload fehlgeschlagen!", nb = "Kunne ikke laste ned fil!", + se = "Kunde inte ladda ner filen!", }; -- This prompt is shown to users when we may overwrite an existing file. @@ -580,6 +653,7 @@ ["File '%0' already exists! Replace?"] = { de = "Datei '%0' existiert bereits! Ersetzen?", nb = "Filen '%0' eksisterer allerede! Skrive over?", + se = "Filen '%0' existerer redan! Skriv ?ver?", }; -- This is a button in the UI. It replaces "Next" when there are no more @@ -587,6 +661,7 @@ ["Finish"] = { de = "Fertig", nb = "Ferdig", + se = "F?rdig", }; -- This error message is (hopefully) shown to the user if the UI @@ -594,6 +669,7 @@ ["GUI failed to start"] = { de = "GUI konnte nicht gestartet werden", nb = "Kunne ikke starte grafisk grensesnitt", + se = "Kunde inte starta grafisk gr?nssnitt", }; -- This message is shown to the user if an installation encounters a fatal @@ -602,12 +678,14 @@ ["Incomplete installation. We will revert any changes we made."] = { de = "Unvollst?ndige Installation. Vollzogene Ver?nderungen werden zur?ckgenommen.", nb = "Installasjonen ble ikke ferdig. Vi vil tilbakestille alle endringer som ble gjort.", + se = "Ofullst?ndig installation. ?terst?llning av alla gjorda ?ndringar utf?rs.", }; -- Reported to the user if everything worked out. ["Installation was successful."] = { de = "Installation war erfolgreich.", nb = "Installasjonen var en suksess.", + se = "Installationen blev lyckad.", }; -- This is a window title, shown while the actual installation to disk @@ -615,6 +693,7 @@ ["Installing"] = { de = "Installieren", nb = "Installerer", + se = "Installerar", }; -- This is a window title, shown while the user is choosing @@ -622,6 +701,7 @@ ["Options"] = { de = "Optionen", nb = "Valg", + se = "V?lg", }; -- Shown as an option in the ncurses UI as the final element in a list of @@ -630,18 +710,21 @@ ["(I want to specify a path.)"] = { de = "(Ich m?chte einen Pfad angeben.)", nb = "(Jeg vil skrive min egen sti.)", + se = "(Jag vill skriva in en egen s?kv?g.)", }; -- "kilobytes per second" ... download rate. ["KB/s"] = { de = "KB/s", nb = "KB/s", + se = "KB/s", }; -- "bytes per second" ... download rate. ["B/s"] = { de = "B/s", nb = "B/s", + se = "B/s", }; -- Download rate when we don't know the goal (can't report time left). @@ -649,6 +732,7 @@ ["%0 %1"] = { de = "%0 %1", nb = "%0 %1", + se = "%0 %1", }; -- Download rate when we know the goal (can report time left). @@ -657,12 +741,14 @@ ["%0 %1, %2:%3:%4 remaining"] = { de = "%0 %1, %2:%3:%4 verbleibend", nb = "%0 %1, %2:%3:%4 igjen", + se = "%0 %1, %2:%3:%4 ?terst?r", }; -- download rate when download isn't progressing at all. ["stalled"] = { de = "Stillstand", -- FIXME Translated as "halt" or "standstill" nb = "st?r fast", + se = "avstannad", }; -- Download progress string: filename (%0), percent downloaded (%1), @@ -670,12 +756,14 @@ ["%0: %1%% (%2)"] = { de = "%0: %1%% (%2)", nb = "%0: %1%% (%2)", + se = "%0: %1%% (%2)", }; -- This is a window title when prompting the user to insert a new disc. ["Media change"] = { de = "Medienwechsel", nb = "Mediaendring", + se = "Mediabyte", }; -- This error message is shown to the end-user when we can't make a new @@ -683,6 +771,7 @@ ["Directory creation failed"] = { de = "Erstellung eines Verzeichnisses fehlgeschlagen", nb = "Kunne ikke lage katalog", + se = "Kunde inte skapa katalog", }; -- This is a GTK+ button label. The '_' comes before the hotkey character. @@ -690,6 +779,7 @@ ["N_ever"] = { de = "N_iemals", nb = "Al_dri", + se = "Al_drig", }; -- This is a GUI button label, to move forward to the next stage of @@ -697,18 +787,21 @@ ["Next"] = { de = "Weiter", nb = "Neste", + se = "N?sta", }; -- This is a GUI button label, indicating a negative response. ["No"] = { de = "Nein", nb = "Nei", + se = "Nej", }; -- This is a GUI button label, indicating a positive response. ["Yes"] = { de = "Ja", nb = "Ja", + se = "Ja", }; -- HTTP error message in the www UI, as in "404 Not Found" ... requested @@ -716,6 +809,7 @@ ["Not Found"] = { de = "Nicht gefunden", nb = "Ikke funnet", + se = "Inte funnen", }; -- This is reported to the user when there are no files to install, and @@ -723,12 +817,14 @@ ["Nothing to do!"] = { de = "Nichts zu tun!", nb = "Ingenting ? gj?re!", + se = "Ingenting att g?ra!", }; -- This is a GUI button label, sometimes paired with "Cancel" ["OK"] = { de = "OK", nb = "OK", + se = "OK", }; -- This is displayed when the application has a serious problem, such as @@ -739,12 +835,14 @@ ["PANIC"] = { de = "PANIK", nb = "PANIKK", + se = "PANIK", }; -- Prompt shown to user when we need her to insert a new disc. ["Please insert '%0'"] = { de = "Bitte legen Sie '%0' ein", nb = "Sett inn '%0'", + se = "S?tt in '%0'", }; -- Prompt shown to user in the stdio UI when we need to pause before @@ -753,6 +851,7 @@ ["Press enter to continue."] = { de = "Dr?cken Sie Enter um fortzufahren", nb = "Trykk enter for ? fortsette.", + se = "Tryck enter f?r att forts?tta.", }; -- This is a window title when informing the user that something @@ -761,17 +860,20 @@ ["Serious problem"] = { de = "Ernstes Problem", nb = "Alvorlig problem", + se = "Allvarligt problem", }; -- The www UI uses this as a page title when the program is terminating. ["Shutting down..."] = { de = "Schlie?e...", nb = "Avslutter...", + se = "Avslutar...", }; -- The www UI uses this as page text when the program is terminating. ["You can close this browser now."] = { de = "Sie k?nnen diesen Browser nun schlie?en.", + se = "Du kan st?nga denna browser nu.", }; -- Error message shown to end-user when we can't write a symbolic link @@ -779,6 +881,7 @@ ["Symlink creation failed!"] = { de = "Erzeugung einer Verkn?pfung fehlgeschlagen!", nb = "Kunne likke lage symbolsk lenke!", + se = "Kunde inte skapa symbolisk l?nk!", }; -- Error message shown to the end-user when the OS has requested @@ -786,6 +889,7 @@ ["The installer has been stopped by the system."] = { de = "Das Installationsprogramm wurde vom System gestoppt.", nb = "Installasjonsprogrammet ble stoppet av systemet.", + se = "Installationsprogrammet blev stoppat av systemet.", }; -- Error message shown to the end-user when the program crashes with a @@ -793,12 +897,14 @@ ["The installer has crashed due to a bug."] = { de = "Das Installationsprogramm ist aufgrund eines Fehlers abgest?rzt.", nb = "Installasjonsprogrammet kr?sjet pga. en feil.", + se = "Installationsprogrammet kraschade pga. ett fel.", }; -- This is a button label in the ncurses ui to flip an option on/off. ["Toggle"] = { de = "Umschalten", nb = "Inverter valg", + se = "Invertera", }; -- This is an error message shown to the end-user when there is an @@ -807,6 +913,7 @@ ["Unknown file type in archive"] = { de = "Unbekannter Dateityp im Archiv", nb = "Ukjent filtype i arkivet", + se = "Ok?nd filtyp i arkivet", }; -- This is an error message shown to the end-user if they refuse to @@ -814,6 +921,7 @@ ["You must accept the license before you may install"] = { de = "Sie m?ssen den Lizenzbedingungen zustimmen, bevor sie installieren k?nnen", nb = "Lisensen m? godkjennes f?r du kan installere", + se = "Licensen m?ste godk?nnas f?r att installationen skall forts?tta", }; -- Installations display the currently-installing component, such as @@ -823,6 +931,7 @@ ["Metadata"] = { de = "Metadaten", nb = "Metadata", + se = "Metadata", }; }; From DONOTREPLY at icculus.org Sat Jan 19 21:11:01 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 19 Jan 2008 21:11:01 -0500 Subject: r438 - in trunk: . scripts Message-ID: <20080120021101.16894.qmail@icculus.org> Author: icculus Date: 2008-01-19 21:11:01 -0500 (Sat, 19 Jan 2008) New Revision: 438 Modified: trunk/lua_glue.c trunk/scripts/localization.lua trunk/scripts/mojosetup_init.lua Log: Split out internal strings and app-specific strings, so package developers don't have to track our changes to keep their localizations up to date. Modified: trunk/lua_glue.c =================================================================== --- trunk/lua_glue.c 2008-01-19 22:19:14 UTC (rev 437) +++ trunk/lua_glue.c 2008-01-20 02:11:01 UTC (rev 438) @@ -1620,8 +1620,9 @@ free(binarypath); free(homedir); - // Set up localization table, if possible. + // Set up localization tables, if possible. MojoLua_runFile("localization"); + MojoLua_runFile("app_localization"); // Transfer control to Lua to setup some APIs and state... if (!MojoLua_runFile("mojosetup_init")) Modified: trunk/scripts/localization.lua =================================================================== --- trunk/scripts/localization.lua 2008-01-19 22:19:14 UTC (rev 437) +++ trunk/scripts/localization.lua 2008-01-20 02:11:01 UTC (rev 438) @@ -6,6 +6,10 @@ -- Lines starting with "--" are comments in this file. -- +-- You should add your installer's strings to app_localization.lua, not this +-- file. This file is for strings internal to MojoSetup, and we change it all +-- the time. Your app can override any individual string in this file, though. +-- -- NOTE: If you care about Unicode or ASCII chars above 127, this file _MUST_ -- be UTF-8 encoded! If you think you're using a certain high-ascii codepage, -- you're wrong! Modified: trunk/scripts/mojosetup_init.lua =================================================================== --- trunk/scripts/mojosetup_init.lua 2008-01-19 22:19:14 UTC (rev 437) +++ trunk/scripts/mojosetup_init.lua 2008-01-20 02:11:01 UTC (rev 438) @@ -130,6 +130,21 @@ MojoSetup.localization = nil end +-- Merge the applocalization table into localization. +if type(MojoSetup.applocalization) == "table" then + for k,v in pairs(MojoSetup.applocalization) do + if MojoSetup.localization[k] == nil then + MojoSetup.localization[k] = v -- just take the whole table as-is. + else + -- This can add or overwrite entries... + for lang,str in pairs(MojoSetup.applocalization) do + MojoSetup.localization[k][lang] = str + end + end + end +end +MojoSetup.applocalization = nil -- done with this; garbage collect it. + -- Map some legacy language identifiers into updated equivalents. local lang_remap = { From DONOTREPLY at icculus.org Sat Jan 19 21:11:21 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 19 Jan 2008 21:11:21 -0500 Subject: r439 - trunk/scripts Message-ID: <20080120021121.17580.qmail@icculus.org> Author: icculus Date: 2008-01-19 21:11:21 -0500 (Sat, 19 Jan 2008) New Revision: 439 Added: trunk/scripts/app_localization.lua Log: Forgot to add this. Added: trunk/scripts/app_localization.lua =================================================================== --- trunk/scripts/app_localization.lua (rev 0) +++ trunk/scripts/app_localization.lua 2008-01-20 02:11:21 UTC (rev 439) @@ -0,0 +1,11 @@ +-- Lines starting with "--" are comments in this file. +-- You should add your installer's strings here, instead of localization.lua, +-- but localization.lua has instructions on how this file is formatted. + +MojoSetup.applocalization = { +}; + +-- end of app_localization.lua ... + + + From DONOTREPLY at icculus.org Sun Jan 20 01:12:05 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 20 Jan 2008 01:12:05 -0500 Subject: r440 - trunk/scripts Message-ID: <20080120061205.4719.qmail@icculus.org> Author: icculus Date: 2008-01-20 01:12:03 -0500 (Sun, 20 Jan 2008) New Revision: 440 Modified: trunk/scripts/localization.lua Log: Removed incorrect comment. Modified: trunk/scripts/localization.lua =================================================================== --- trunk/scripts/localization.lua 2008-01-20 02:11:21 UTC (rev 439) +++ trunk/scripts/localization.lua 2008-01-20 06:12:03 UTC (rev 440) @@ -51,9 +51,6 @@ -- Occasionally you might see a "\n" ... that's a newline character. "\t" is -- a tab character, and "\\" turns into a single "\" character. -- --- You should leave the existing strings here. They aren't hurting anything, --- and most are used by MojoSetup itself. Add your own, if needed, though. --- -- The table you create here goes away shortly after creation, as the relevant -- parts of it get moved somewhere else. You should call MojoSetup.translate() -- to get the proper translation for a given string. From DONOTREPLY at icculus.org Sun Jan 20 03:49:54 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 20 Jan 2008 03:49:54 -0500 Subject: r441 - in trunk/examples/duke3d: . scripts Message-ID: <20080120084954.3097.qmail@icculus.org> Author: icculus Date: 2008-01-20 03:49:53 -0500 (Sun, 20 Jan 2008) New Revision: 441 Added: trunk/examples/duke3d/scripts/app_localization.lua Modified: trunk/examples/duke3d/make.sh Log: Added app_localization for duke3d example. Modified: trunk/examples/duke3d/make.sh =================================================================== --- trunk/examples/duke3d/make.sh 2008-01-20 06:12:03 UTC (rev 440) +++ trunk/examples/duke3d/make.sh 2008-01-20 08:49:53 UTC (rev 441) @@ -93,6 +93,10 @@ rm -f examples/duke3d/image/scripts/config.luac ./mojoluac $LUASTRIPOPT -o examples/duke3d/image/scripts/config.luac examples/duke3d/scripts/config.lua +# Don't want the example app_localization...use our's instead. +rm -f examples/duke3d/image/scripts/app_localization.luac +./mojoluac $LUASTRIPOPT -o examples/duke3d/image/scripts/app_localization.luac examples/duke3d/scripts/app_localization.lua + # Fill in the rest of the Base Archive... cd examples/duke3d cp data/* image/data/ Added: trunk/examples/duke3d/scripts/app_localization.lua =================================================================== --- trunk/examples/duke3d/scripts/app_localization.lua (rev 0) +++ trunk/examples/duke3d/scripts/app_localization.lua 2008-01-20 08:49:53 UTC (rev 441) @@ -0,0 +1,74 @@ +-- Lines starting with "--" are comments in this file. +-- You should add your installer's strings here, instead of localization.lua, +-- but localization.lua has instructions on how this file is formatted. + +MojoSetup.applocalization = { + -- Window title when showing the GPL. + ["GNU General Public License"] = { + }; + + -- As you add GPL translations, change the filename here. + ["gpl.txt"] = { + en = "gpl.txt", + }; + + -- Window title when showing game's README file. + ["Duke Nukem 3D README"] = { + }; + + -- As you add README translations, change the filename here. + ["duke3d_readme.txt"] = { + }; + + -- Window title when showing MojoSetup README file. + ["Duke Nukem 3D README"] = { + }; + + -- As you add README translations, change the filename here. + ["mojosetup_readme.txt"] = { + }; + + -- Name of disc published by MacSoft (as in "Please insert 'Disc Name'") + ["MacSoft Duke3D CD-ROM"] = { + }; + + -- Name of disc published for DOS (as in "Please insert 'Disc Name'") + ["PC Atomic Edition CD-ROM"] = { + }; + + -- Name of option section. + ["Installation type"] = { + }; + + -- This is a kind of useless tooltip; I'm just using it for testing. + -- This is a command to the user. + ["Pick your installation type"] = { + }; + + -- One possible installation option that user can click. + ["Install Shareware version"] = { + }; + + -- Tooltip text for "Install Shareware version". + ["This does not need a retail copy of the game. It's free!"] = { + } + + -- One possible installation option that user can click. + ["Install full game from Atomic Edition disc"] = { + }; + + -- Tooltip text for "Install full game from Atomic Edition disc". + ["Pick this if you have a retail game disc from 3DRealms."] = { + }; + + -- One possible installation option that user can click. + ["Install full game from MacSoft disc"] = { + }; + + -- Tooltip text for "Install full game from MacSoft disc". + ["Pick this if you have a retail game disc from MacSoft."] = { + }; +}; + +-- end of app_localization.lua ... + From DONOTREPLY at icculus.org Sun Jan 20 03:53:39 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 20 Jan 2008 03:53:39 -0500 Subject: r442 - trunk Message-ID: <20080120085339.9067.qmail@icculus.org> Author: icculus Date: 2008-01-20 03:53:39 -0500 (Sun, 20 Jan 2008) New Revision: 442 Modified: trunk/lua_glue.c Log: Made MojoLua_runFile() not use static filename buffers. Modified: trunk/lua_glue.c =================================================================== --- trunk/lua_glue.c 2008-01-20 08:49:53 UTC (rev 441) +++ trunk/lua_glue.c 2008-01-20 08:53:39 UTC (rev 442) @@ -381,17 +381,11 @@ MojoArchive *ar = GBaseArchive; // in case we want to generalize later. const MojoArchiveEntry *entinfo; boolean retval = false; - char clua[128]; // compiled filename. - char ulua[128]; // uncompiled filename. + char *clua = format("scripts/%0.luac", name); // compiled filename. + char *ulua = format("scripts/%0.lua", name); // uncompiled filename. int rc = 0; MojoInput *io = NULL; - if (snprintf(clua, sizeof(clua), "scripts/%s.luac", name) >= sizeof (clua)) - return false; - - if (snprintf(ulua, sizeof(ulua), "scripts/%s.lua", name) >= sizeof (ulua)) - return false; - if (ar->enumerate(ar)) { while ((io == NULL) && ((entinfo = ar->enumNext(ar)) != NULL)) @@ -412,6 +406,9 @@ } // while } // if + free(ulua); + free(clua); + if (io != NULL) { char *realfname = (char *) xmalloc(strlen(entinfo->filename) + 2); From DONOTREPLY at icculus.org Sun Jan 20 03:59:43 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 20 Jan 2008 03:59:43 -0500 Subject: r443 - trunk Message-ID: <20080120085943.17138.qmail@icculus.org> Author: icculus Date: 2008-01-20 03:59:43 -0500 (Sun, 20 Jan 2008) New Revision: 443 Modified: trunk/lua_glue.c trunk/lua_glue.h Log: Let you run Lua scripts from specific directories... Modified: trunk/lua_glue.c =================================================================== --- trunk/lua_glue.c 2008-01-20 08:53:39 UTC (rev 442) +++ trunk/lua_glue.c 2008-01-20 08:59:43 UTC (rev 443) @@ -376,13 +376,13 @@ } // MojoLua_callProcedure -boolean MojoLua_runFile(const char *name) +boolean MojoLua_runFileFromDir(const char *dir, const char *name) { MojoArchive *ar = GBaseArchive; // in case we want to generalize later. const MojoArchiveEntry *entinfo; boolean retval = false; - char *clua = format("scripts/%0.luac", name); // compiled filename. - char *ulua = format("scripts/%0.lua", name); // uncompiled filename. + char *clua = format("%0/%1.luac", dir, name); // compiled filename. + char *ulua = format("%0/%1.lua", dir, name); // uncompiled filename. int rc = 0; MojoInput *io = NULL; @@ -432,6 +432,12 @@ } // if return retval; +} // MojoLua_runFileFromDir + + +boolean MojoLua_runFile(const char *name) +{ + return MojoLua_runFileFromDir("scripts", name); } // MojoLua_runFile Modified: trunk/lua_glue.h =================================================================== --- trunk/lua_glue.h 2008-01-20 08:53:39 UTC (rev 442) +++ trunk/lua_glue.h 2008-01-20 08:59:43 UTC (rev 443) @@ -27,13 +27,16 @@ boolean MojoLua_initialized(void); // Run the code in a given Lua file. This is JUST the base filename. -// We will look for it in GBaseArchive in the scripts/ directory, both as +// We will look for it in GBaseArchive in the (dir) directory, both as // fname.luac and fname.lua. This code chunk will accept no arguments, and // return no results, but it can change the global state and alter tables, // etc, so it can have lasting side effects. // Will return false if the file couldn't be loaded, or true if the chunk // successfully ran. Will not return if there's a runtime error in the // chunk, as it will call fatal() instead. +boolean MojoLua_runFileFromDir(const char *dir, const char *name) + +// This is shorthand for MojoLua_runFileFromDir("scripts", fname); boolean MojoLua_runFile(const char *fname); // Call a function in Lua. This calls MojoSetup.funcname, if it exists and From DONOTREPLY at icculus.org Sun Jan 20 04:05:05 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 20 Jan 2008 04:05:05 -0500 Subject: r444 - in trunk: . scripts Message-ID: <20080120090505.23717.qmail@icculus.org> Author: icculus Date: 2008-01-20 04:04:50 -0500 (Sun, 20 Jan 2008) New Revision: 444 Modified: trunk/lua_glue.c trunk/scripts/mojosetup_init.lua trunk/scripts/mojosetup_mainline.lua Log: Reworked and cleaned up some scripting code and glue. Modified: trunk/lua_glue.c =================================================================== --- trunk/lua_glue.c 2008-01-20 08:59:43 UTC (rev 443) +++ trunk/lua_glue.c 2008-01-20 09:04:50 UTC (rev 444) @@ -1623,23 +1623,10 @@ free(binarypath); free(homedir); - // Set up localization tables, if possible. - MojoLua_runFile("localization"); - MojoLua_runFile("app_localization"); - // Transfer control to Lua to setup some APIs and state... if (!MojoLua_runFile("mojosetup_init")) return false; - // ...and run the installer-specific config file. - if (!MojoLua_runFile("config")) - return false; - - // We don't need the "Setup" namespace anymore. Make it - // eligible for garbage collection. - lua_pushnil(luaState); - lua_setglobal(luaState, "Setup"); - MojoLua_collectGarbage(); // get rid of old init crap we don't need. return true; Modified: trunk/scripts/mojosetup_init.lua =================================================================== --- trunk/scripts/mojosetup_init.lua 2008-01-20 08:59:43 UTC (rev 443) +++ trunk/scripts/mojosetup_init.lua 2008-01-20 09:04:50 UTC (rev 444) @@ -21,25 +21,6 @@ local _ = MojoSetup.translate -MojoSetup.loginfo("MojoSetup Lua initialization at " .. MojoSetup.date()) -MojoSetup.loginfo("buildver: " .. MojoSetup.info.buildver) -MojoSetup.loginfo("locale: " .. MojoSetup.info.locale) -MojoSetup.loginfo("platform: " .. MojoSetup.info.platform) -MojoSetup.loginfo("arch: " .. MojoSetup.info.arch) -MojoSetup.loginfo("ostype: " .. MojoSetup.info.ostype) -MojoSetup.loginfo("osversion: " .. MojoSetup.info.osversion) -MojoSetup.loginfo("ui: " .. MojoSetup.info.ui) -MojoSetup.loginfo("loglevel: " .. MojoSetup.info.loglevel) - -MojoSetup.loginfo("command line:") -for i,v in ipairs(MojoSetup.info.argv) do - MojoSetup.loginfo(" " .. i .. ": " .. v) -end - ---MojoSetup.loginfo(MojoSetup.info.license) ---MojoSetup.loginfo(MojoSetup.info.lualicense) - - -- Returns three elements: protocol, host, path function MojoSetup.spliturl(url) return string.match(url, "^(.+://)(.-)/(.*)") @@ -88,106 +69,8 @@ end end --- This table gets filled by the config file. Just create an empty one for now. -MojoSetup.installs = {} - -local function sanity_check_localization_entry(str, translations) - local maxval = -1; - - for val in string.gmatch(str, "%%.") do - val = string.sub(val, 2) - if string.match(val, "^[^%%0-9]$") ~= nil then - MojoSetup.fatal("BUG: localization key ['" .. str .. "'] has invalid escape sequence.") - end - if val ~= "%" then - local num = tonumber(val) - if num > maxval then - maxval = num - end - end - end - - for k,v in pairs(translations) do - for val in string.gmatch(v, "%%.") do - val = string.sub(val, 2) - if string.match(val, "^[^%%0-9]$") ~= nil then - MojoSetup.fatal("BUG: '" .. k .. "' localization ['" .. v .. "'] has invalid escape sequence.") - end - if val ~= "%" then - if tonumber(val) > maxval then - MojoSetup.fatal("BUG: '" .. k .. "' localization ['" .. v .. "'] has escape sequence > max for translation.") - end - end - end - end -end - - --- Build the translations table from the localizations table supplied in --- localizations.lua... -if type(MojoSetup.localization) ~= "table" then - MojoSetup.localization = nil -end - --- Merge the applocalization table into localization. -if type(MojoSetup.applocalization) == "table" then - for k,v in pairs(MojoSetup.applocalization) do - if MojoSetup.localization[k] == nil then - MojoSetup.localization[k] = v -- just take the whole table as-is. - else - -- This can add or overwrite entries... - for lang,str in pairs(MojoSetup.applocalization) do - MojoSetup.localization[k][lang] = str - end - end - end -end -MojoSetup.applocalization = nil -- done with this; garbage collect it. - --- Map some legacy language identifiers into updated equivalents. -local lang_remap = -{ - no = "nb", -- "Norwegian" split into "Bokmal" (nb) and "Nynorsk" (nn) -} - -if MojoSetup.localization ~= nil then - local at_least_one = false - local locale = MojoSetup.info.locale - local lang = string.gsub(locale, "_%w+", "", 1) -- make "en_US" into "en" - - if lang_remap[lang] ~= nil then - lang = lang_remap[lang] - end - - MojoSetup.translations = {} - for k,v in pairs(MojoSetup.localization) do - if MojoSetup.translations[k] ~= nil then - MojoSetup.fatal("BUG: Duplicate localization key ['" .. k .. "']") - end - if type(v) == "table" then - sanity_check_localization_entry(k, v) - if v[locale] ~= nil then - MojoSetup.translations[k] = v[locale] - at_least_one = true - elseif v[lang] ~= nil then - MojoSetup.translations[k] = v[lang] - at_least_one = true - end - end - end - - -- Delete the table if there's no actual useful translations for this run. - if (not at_least_one) then - MojoSetup.translations = nil - end - - -- This is eligible for garbage collection now. We're done with it. - MojoSetup.localization = nil -end - - --- Our namespace for this API...this is filled in with the rest of this file. +-- Our namespace for config API... Setup = {} local function schema_assert(test, fnname, elem, errstr) @@ -377,6 +260,10 @@ { "superuser", false, mustBeBool }, }) + if MojoSetup.installs == nil then + MojoSetup.installs = {} + end + tab._type_ = nil tab = reform_schema_table(tab) table.insert(MojoSetup.installs, tab) @@ -512,5 +399,132 @@ }) end + +local function prepare_localization() + -- Map some legacy language identifiers into updated equivalents. + local lang_remap = + { + no = "nb", -- "Norwegian" split into "Bokmal" (nb) and "Nynorsk" (nn) + } + + local function sanity_check_localization_entry(str, translations) + local maxval = -1; + + for val in string.gmatch(str, "%%.") do + val = string.sub(val, 2) + if string.match(val, "^[^%%0-9]$") ~= nil then + MojoSetup.fatal("BUG: localization key ['" .. str .. "'] has invalid escape sequence.") + end + if val ~= "%" then + local num = tonumber(val) + if num > maxval then + maxval = num + end + end + end + + for k,v in pairs(translations) do + for val in string.gmatch(v, "%%.") do + val = string.sub(val, 2) + if string.match(val, "^[^%%0-9]$") ~= nil then + MojoSetup.fatal("BUG: '" .. k .. "' localization ['" .. v .. "'] has invalid escape sequence.") + end + if val ~= "%" then + if tonumber(val) > maxval then + MojoSetup.fatal("BUG: '" .. k .. "' localization ['" .. v .. "'] has escape sequence > max for translation.") + end + end + end + end + end + + -- Build the translations table from the localizations table supplied in + -- localizations.lua... + if type(MojoSetup.localization) ~= "table" then + MojoSetup.localization = nil + end + + -- Merge the applocalization table into localization. + if type(MojoSetup.applocalization) == "table" then + if MojoSetup.localization == nil then + MojoSetup.localization = {} + end + for k,v in pairs(MojoSetup.applocalization) do + if MojoSetup.localization[k] == nil then + MojoSetup.localization[k] = v -- just take the whole table as-is. + else + -- This can add or overwrite entries... + for lang,str in pairs(MojoSetup.applocalization) do + MojoSetup.localization[k][lang] = str + end + end + end + end + MojoSetup.applocalization = nil -- done with this; garbage collect it. + + if MojoSetup.localization == nil then + local at_least_one = false + local locale = MojoSetup.info.locale + local lang = string.gsub(locale, "_%w+", "", 1) -- make "en_US" into "en" + + if lang_remap[lang] ~= nil then + lang = lang_remap[lang] + end + + MojoSetup.translations = {} + for k,v in pairs(MojoSetup.localization) do + if MojoSetup.translations[k] ~= nil then + MojoSetup.fatal("BUG: Duplicate localization key ['" .. k .. "']") + end + if type(v) == "table" then + sanity_check_localization_entry(k, v) + if v[locale] ~= nil then + MojoSetup.translations[k] = v[locale] + at_least_one = true + elseif v[lang] ~= nil then + MojoSetup.translations[k] = v[lang] + at_least_one = true + end + end + end + + -- Delete the table if there's no actual useful translations for this run. + if (not at_least_one) then + MojoSetup.translations = nil + end + + -- This is eligible for garbage collection now. We're done with it. + MojoSetup.localization = nil + end +end + + +-- Mainline... + +MojoSetup.loginfo("MojoSetup Lua initialization at " .. MojoSetup.date()) +MojoSetup.loginfo("buildver: " .. MojoSetup.info.buildver) +MojoSetup.loginfo("locale: " .. MojoSetup.info.locale) +MojoSetup.loginfo("platform: " .. MojoSetup.info.platform) +MojoSetup.loginfo("arch: " .. MojoSetup.info.arch) +MojoSetup.loginfo("ostype: " .. MojoSetup.info.ostype) +MojoSetup.loginfo("osversion: " .. MojoSetup.info.osversion) +MojoSetup.loginfo("ui: " .. MojoSetup.info.ui) +MojoSetup.loginfo("loglevel: " .. MojoSetup.info.loglevel) + +MojoSetup.loginfo("command line:") +for i,v in ipairs(MojoSetup.info.argv) do + MojoSetup.loginfo(" " .. i .. ": " .. v) +end + +--MojoSetup.loginfo(MojoSetup.info.license) +--MojoSetup.loginfo(MojoSetup.info.lualicense) + +-- These scripts are optional, but hopefully exist... +MojoSetup.runFile("localization") +MojoSetup.runFile("app_localization") +prepare_localization() + +-- okay, we're initialized! + -- end of mojosetup_init.lua ... Modified: trunk/scripts/mojosetup_mainline.lua =================================================================== --- trunk/scripts/mojosetup_mainline.lua 2008-01-20 08:59:43 UTC (rev 443) +++ trunk/scripts/mojosetup_mainline.lua 2008-01-20 09:04:50 UTC (rev 444) @@ -1357,26 +1357,43 @@ MojoSetup.totaldownload = 0 end +local function installer() + -- This builds the MojoSetup.installs table. + MojoSetup.runFile("config") + -- We don't need the "Setup" namespace anymore. Make it eligible + -- for garbage collection. + Setup = nil --- Mainline. + -- This dumps the table built from the user's config script using logdebug, + -- so it only spits out crap if debug-level logging is enabled. + MojoSetup.dumptable("MojoSetup.installs", MojoSetup.installs) + local saw_an_installer = false + for installkey,install in pairs(MojoSetup.installs) do + if not install.disabled then + saw_an_installer = true + do_install(install) + MojoSetup.collectgarbage() -- nuke all the tables we threw around... + end + end --- This dumps the table built from the user's config script using logdebug, --- so it only spits out crap if debug-level logging is enabled. -MojoSetup.dumptable("MojoSetup.installs", MojoSetup.installs) - -local saw_an_installer = false -for installkey,install in pairs(MojoSetup.installs) do - if not install.disabled then - saw_an_installer = true - do_install(install) - MojoSetup.collectgarbage() -- nuke all the tables we threw around... + if not saw_an_installer then + MojoSetup.fatal(_("Nothing to do!")) end end -if not saw_an_installer then - MojoSetup.fatal(_("Nothing to do!")) + +-- Mainline. + +if MojoSetup.cmdline("manifest") then + Setup = nil -- don't need this after all. + MojoSetup.fatal("Not implemented yet.") +elseif MojoSetup.cmdline("uninstall") then + Setup = nil -- don't need this after all. + MojoSetup.fatal("Not implemented yet.") +else + installer() end -- end of mojosetup_mainline.lua ... From DONOTREPLY at icculus.org Sun Jan 20 05:03:18 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 20 Jan 2008 05:03:18 -0500 Subject: r445 - trunk Message-ID: <20080120100318.26224.qmail@icculus.org> Author: icculus Date: 2008-01-20 05:03:16 -0500 (Sun, 20 Jan 2008) New Revision: 445 Modified: trunk/lua_glue.c trunk/platform.h trunk/platform_unix.c trunk/platform_windows.c Log: Another attempt to stop being a game developer; some more MojoPlatform_* functions now returned a malloc()'d string that the caller must free(), instead of counting on the caller to pass in a (maybe!) large enough buffer. Modified: trunk/lua_glue.c =================================================================== --- trunk/lua_glue.c 2008-01-20 09:04:50 UTC (rev 444) +++ trunk/lua_glue.c 2008-01-20 10:03:16 UTC (rev 445) @@ -1485,20 +1485,21 @@ const char *envr = cmdlinestr("locale", "MOJOSETUP_LOCALE", NULL); char *homedir = NULL; char *binarypath = NULL; - char locale[16]; - char ostype[64]; - char osversion[64]; + char *locale = NULL + char *ostype = NULL; + char *osversion = NULL; if (envr != NULL) - xstrncpy(locale, envr, sizeof (locale)); - else if (!MojoPlatform_locale(locale, sizeof (locale))) - xstrncpy(locale, "???", sizeof (locale)); + locale = xstrdup(envr); + else if ((locale = MojoPlatform_locale()) == NULL) + locale = xstrdup("???"); - if (!MojoPlatform_osType(ostype, sizeof (ostype))) - xstrncpy(ostype, "???", sizeof (ostype)); - if (!MojoPlatform_osVersion(osversion, sizeof (osversion))) - xstrncpy(osversion, "???", sizeof (osversion)); + if ((ostype = MojoPlatform_osType()) == NULL) + ostype = xstrdup("???"); + if ((osversion = MojoPlatform_osVersion()) == NULL) + osversion = xstrdup("???"); + assert(luaState == NULL); luaState = lua_newstate(MojoLua_alloc, NULL); @@ -1622,6 +1623,9 @@ free(binarypath); free(homedir); + free(osversion); + free(ostype); + free(locale); // Transfer control to Lua to setup some APIs and state... if (!MojoLua_runFile("mojosetup_init")) Modified: trunk/platform.h =================================================================== --- trunk/platform.h 2008-01-20 09:04:50 UTC (rev 444) +++ trunk/platform.h 2008-01-20 10:03:16 UTC (rev 445) @@ -262,12 +262,19 @@ // Get the current locale, in the format "xx_YY" where "xx" is the language // (en, fr, de...) and "_YY" is the country. (_US, _CA, etc). The country // can be omitted. Don't include encoding, it's always UTF-8 at this time. -// Return true if locale is known, false otherwise. -boolean MojoPlatform_locale(char *buf, size_t len); +// Returns locale string, or NULL if it couldn't be determined. +// Caller must free() the returned pointer! +char *MojoPlatform_locale(void); -boolean MojoPlatform_osType(char *buf, size_t len); -boolean MojoPlatform_osVersion(char *buf, size_t len); +// !!! FIXME: document me. +// Caller must free() the returned pointer! +char *MojoPlatform_osType(void); +// !!! FIXME: document me. +// Caller must free() the returned pointer! +char *MojoPlatform_osVersion(void); + + // Basic platform detection. #if PLATFORM_WINDOWS #define PLATFORM_NAME "windows" Modified: trunk/platform_unix.c =================================================================== --- trunk/platform_unix.c 2008-01-20 09:04:50 UTC (rev 444) +++ trunk/platform_unix.c 2008-01-20 10:03:16 UTC (rev 445) @@ -367,23 +367,21 @@ // This implementation is a bit naive. -boolean MojoPlatform_locale(char *buf, size_t len) +char *MojoPlatform_locale(void) { - boolean retval = false; + char *retval = NULL; const char *envr = getenv("LANG"); if (envr != NULL) { - char *ptr = NULL; - xstrncpy(buf, envr, len); - ptr = strchr(buf, '.'); // chop off encoding if explicitly listed. + retval = xstrdup(envr); + ptr = strchr(retval, '.'); // chop off encoding if explicitly listed. if (ptr != NULL) *ptr = '\0'; - retval = true; } // if #if PLATFORM_MACOSX else if (CFLocaleCreateCanonicalLocaleIdentifierFromString == NULL) - retval = false; // !!! FIXME: 10.2 compatibility? + retval = NULL; // !!! FIXME: 10.2 compatibility? else if (CFLocaleCreateCanonicalLocaleIdentifierFromString != NULL) { @@ -400,9 +398,11 @@ kCFAllocatorDefault, primary); if (locale != NULL) if (locale != NULL) { - CFStringGetCString(locale, buf, len, kCFStringEncodingUTF8); + const CFIndex len = (CFStringGetLength(locale) + 1) * 6; + char *ptr = (char*) xmalloc(len); + CFStringGetCString(locale, ptr, len, kCFStringEncodingUTF8); CFRelease(locale); - retval = true; + retval = xrealloc(ptr, strlen(ptr) + 1); } // if } // if CFRelease(languages); @@ -414,37 +414,37 @@ } // MojoPlatform_locale -boolean MojoPlatform_osType(char *buf, size_t len) +char *MojoPlatform_osType(void) { #if PLATFORM_MACOSX - xstrncpy(buf, "macosx", len); + return xstrdup("macosx"); #elif PLATFORM_BEOS - xstrncpy(buf, "beos", len); // !!! FIXME: zeta? haiku? + return xstrdup("beos"); // !!! FIXME: zeta? haiku? #elif defined(linux) || defined(__linux) || defined(__linux__) - xstrncpy(buf, "linux", len); + return xstrdup("linux"); #elif defined(__FreeBSD__) || defined(__DragonFly__) - xstrncpy(buf, "freebsd", len); + return xstrdup("freebsd"); #elif defined(__NetBSD__) - xstrncpy(buf, "netbsd", len); + return xstrdup("netbsd"); #elif defined(__OpenBSD__) - xstrncpy(buf, "openbsd", len); + return xstrdup("openbsd"); #elif defined(bsdi) || defined(__bsdi) || defined(__bsdi__) - xstrncpy(buf, "bsdi", len); + return xstrdup("bsdi"); #elif defined(_AIX) - xstrncpy(buf, "aix", len); + return xstrdup("aix"); #elif defined(hpux) || defined(__hpux) || defined(__hpux__) - xstrncpy(buf, "hpux", len); + return xstrdup("hpux"); #elif defined(sgi) || defined(__sgi) || defined(__sgi__) || defined(_SGI_SOURCE) - xstrncpy(buf, "irix", len); + return xstrdup("irix"); #else # error Please define your platform. #endif - return true; + return NULL; } // MojoPlatform_ostype -boolean MojoPlatform_osVersion(char *buf, size_t len) +char *MojoPlatform_osVersion() { #if PLATFORM_MACOSX // !!! FIXME: this is wrong...it doesn't with with 10.y.xx, where 'xx' @@ -454,10 +454,10 @@ long ver = 0x0000; if (Gestalt(gestaltSystemVersion, &ver) == noErr) { - char str[16]; + char *retval = (char *) xmalloc(16); snprintf(str, sizeof (str), "%X", (int) ver); snprintf(buf, len, "%c%c.%c.%c", str[0], str[1], str[2], str[3]); - return true; + return retval; } // if #else // This information may or may not actually MEAN anything. On BeOS, it's @@ -465,13 +465,10 @@ // version, which doesn't necessarily help. struct utsname un; if (uname(&un) == 0) - { - xstrncpy(buf, un.release, len); - return true; - } // if + return xstrdup(un.release); #endif - return false; + return NULL; } // MojoPlatform_osversion Modified: trunk/platform_windows.c =================================================================== --- trunk/platform_windows.c 2008-01-20 09:04:50 UTC (rev 444) +++ trunk/platform_windows.c 2008-01-20 10:03:16 UTC (rev 445) @@ -924,9 +924,8 @@ // This implementation is a bit naive. -boolean MojoPlatform_locale(char *buf, size_t len) +char *MojoPlatform_locale(void) { - boolean retval = false; char lang[16]; char country[16]; @@ -940,33 +939,29 @@ // Win95 systems will fail, because they don't have LOCALE_SISO*NAME ... if ((langrc != 0) && (ctryrc != 0)) - { - snprintf(buf, len, "%s_%s", lang, country); - retval = true; - } // if + return format("%0_%1", lang, country); - return retval; + return NULL; } // MojoPlatform_locale -boolean MojoPlatform_osType(char *buf, size_t len) +char *MojoPlatform_osType(void) { if (osIsWin9x) - xstrncpy(buf, "win9x", len); + return xstrdup("win9x"); else - xstrncpy(buf, "winnt", len); + return xstrdup("winnt"); - return true; + return NULL; } // MojoPlatform_ostype -boolean MojoPlatform_osVersion(char *buf, size_t len) +char *MojoPlatform_osVersion(void) { - snprintf(buf, len, "%u.%u.%u", - (unsigned int) osMajorVer, - (unsigned int) osMinorVer, - (unsigned int) osBuildVer); - return true; + return format("%0.%1.%2", + numStr(osMajorVer), + numStr(osMinorVer), + numStr(osBuildVer)); } // MojoPlatform_osversion From DONOTREPLY at icculus.org Sun Jan 20 05:26:06 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 20 Jan 2008 05:26:06 -0500 Subject: r446 - trunk Message-ID: <20080120102606.24902.qmail@icculus.org> Author: icculus Date: 2008-01-20 05:26:06 -0500 (Sun, 20 Jan 2008) New Revision: 446 Modified: trunk/lua_glue.c trunk/lua_glue.h trunk/platform.h trunk/platform_unix.c trunk/platform_windows.c Log: A couple things cleaned up and patched to compile, and uid/euid/gid supplied to Lua scripts. Modified: trunk/lua_glue.c =================================================================== --- trunk/lua_glue.c 2008-01-20 10:03:16 UTC (rev 445) +++ trunk/lua_glue.c 2008-01-20 10:26:06 UTC (rev 446) @@ -86,7 +86,16 @@ lua_setfield(L, -2, sym); } // set_string + +// Sets t[sym]=f, where t is on the top of the Lua stack. // !!! FIXME: why is this a different naming convention? +static inline void set_integer(lua_State *L, lua_Integer x, const char *sym) +{ + lua_pushinteger(L, x); + lua_setfield(L, -2, sym); +} // set_string + +// !!! FIXME: why is this a different naming convention? static inline void set_string_array(lua_State *L, int argc, const char **argv, const char *sym) { @@ -1483,43 +1492,25 @@ boolean MojoLua_initLua(void) { const char *envr = cmdlinestr("locale", "MOJOSETUP_LOCALE", NULL); - char *homedir = NULL; - char *binarypath = NULL; - char *locale = NULL - char *ostype = NULL; - char *osversion = NULL; + char *homedir = MojoPlatform_homedir(); + char *binarypath = MojoPlatform_appBinaryPath(); + char *locale = (envr != NULL) ? xstrdup(envr) : MojoPlatform_locale(); + char *ostype = MojoPlatform_osType(); + char *osversion = MojoPlatform_osVersion(); + lua_Integer uid = MojoPlatform_getuid(); + lua_Integer euid = MojoPlatform_geteuid(); + lua_Integer gid = MojoPlatform_getgid(); - if (envr != NULL) - locale = xstrdup(envr); - else if ((locale = MojoPlatform_locale()) == NULL) - locale = xstrdup("???"); + if (locale == NULL) locale = xstrdup("???"); + if (ostype == NULL) ostype = xstrdup("???"); + if (osversion == NULL) osversion = xstrdup("???"); - if ((ostype = MojoPlatform_osType()) == NULL) - ostype = xstrdup("???"); - - if ((osversion = MojoPlatform_osVersion()) == NULL) - osversion = xstrdup("???"); - assert(luaState == NULL); - - luaState = lua_newstate(MojoLua_alloc, NULL); - if (luaState == NULL) - return false; - + luaState = lua_newstate(MojoLua_alloc, NULL); // calls fatal() on failure. lua_atpanic(luaState, luahook_fatal); - - if (!lua_checkstack(luaState, 20)) // Just in case. - { - lua_close(luaState); - luaState = NULL; - return false; - } // if - + assert(lua_checkstack(luaState, 20)); // Just in case. registerLuaLibs(luaState); - homedir = MojoPlatform_homedir(); - binarypath = MojoPlatform_appBinaryPath(); - // !!! FIXME: I'd like to change the function name case for the lua hooks. // Build MojoSetup namespace for Lua to access and fill in C bridges... @@ -1568,6 +1559,9 @@ set_string(luaState, homedir, "homedir"); set_string(luaState, binarypath, "binarypath"); set_string(luaState, GBaseArchivePath, "basearchivepath"); + set_integer(luaState, uid, "uid"); + set_integer(luaState, euid, "euid"); + set_integer(luaState, gid, "gid"); set_string_array(luaState, GArgc, GArgv, "argv"); lua_newtable(luaState); set_string(luaState, "base", "base"); @@ -1621,11 +1615,11 @@ lua_setfield(luaState, -2, "archive"); lua_setglobal(luaState, MOJOSETUP_NAMESPACE); - free(binarypath); - free(homedir); free(osversion); free(ostype); free(locale); + free(binarypath); + free(homedir); // Transfer control to Lua to setup some APIs and state... if (!MojoLua_runFile("mojosetup_init")) Modified: trunk/lua_glue.h =================================================================== --- trunk/lua_glue.h 2008-01-20 10:03:16 UTC (rev 445) +++ trunk/lua_glue.h 2008-01-20 10:26:06 UTC (rev 446) @@ -34,7 +34,7 @@ // Will return false if the file couldn't be loaded, or true if the chunk // successfully ran. Will not return if there's a runtime error in the // chunk, as it will call fatal() instead. -boolean MojoLua_runFileFromDir(const char *dir, const char *name) +boolean MojoLua_runFileFromDir(const char *dir, const char *name); // This is shorthand for MojoLua_runFileFromDir("scripts", fname); boolean MojoLua_runFile(const char *fname); Modified: trunk/platform.h =================================================================== --- trunk/platform.h 2008-01-20 10:03:16 UTC (rev 445) +++ trunk/platform.h 2008-01-20 10:26:06 UTC (rev 446) @@ -274,7 +274,16 @@ // Caller must free() the returned pointer! char *MojoPlatform_osVersion(void); +// !!! FIXME: document me. +uint64 MojoPlatform_getuid(void); +// !!! FIXME: document me. +uint64 MojoPlatform_geteuid(void); + +// !!! FIXME: document me. +uint64 MojoPlatform_getgid(void); + + // Basic platform detection. #if PLATFORM_WINDOWS #define PLATFORM_NAME "windows" Modified: trunk/platform_unix.c =================================================================== --- trunk/platform_unix.c 2008-01-20 10:03:16 UTC (rev 445) +++ trunk/platform_unix.c 2008-01-20 10:26:06 UTC (rev 446) @@ -370,6 +370,7 @@ char *MojoPlatform_locale(void) { char *retval = NULL; + char *ptr = NULL; const char *envr = getenv("LANG"); if (envr != NULL) { @@ -399,7 +400,7 @@ if (locale != NULL) { const CFIndex len = (CFStringGetLength(locale) + 1) * 6; - char *ptr = (char*) xmalloc(len); + ptr = (char*) xmalloc(len); CFStringGetCString(locale, ptr, len, kCFStringEncodingUTF8); CFRelease(locale); retval = xrealloc(ptr, strlen(ptr) + 1); @@ -454,10 +455,12 @@ long ver = 0x0000; if (Gestalt(gestaltSystemVersion, &ver) == noErr) { - char *retval = (char *) xmalloc(16); + const size_t len = 8; + char *buf = (char *) xmalloc(len); + char str[16]; snprintf(str, sizeof (str), "%X", (int) ver); snprintf(buf, len, "%c%c.%c.%c", str[0], str[1], str[2], str[3]); - return retval; + return buf; } // if #else // This information may or may not actually MEAN anything. On BeOS, it's @@ -1114,6 +1117,24 @@ } // MojoPlatform_decodeImage +uint64 MojoPlatform_getuid(void) +{ + return (uint64) getuid(); +} // MojoPlatform_getuid + + +uint64 MojoPlatform_geteuid(void) +{ + return (uint64) geteuid(); +} // MojoPlatform_geteuid + + +uint64 MojoPlatform_getgid(void) +{ + return (uint64) getgid(); +} // MojoPlatform_getgid + + static void signal_catcher(int sig) { static boolean first_shot = true; Modified: trunk/platform_windows.c =================================================================== --- trunk/platform_windows.c 2008-01-20 10:03:16 UTC (rev 445) +++ trunk/platform_windows.c 2008-01-20 10:26:06 UTC (rev 446) @@ -1586,6 +1586,25 @@ } // MojoPlatform_dlclose +uint64 MojoPlatform_getuid(void) +{ + return 0; // !!! FIXME +} // MojoPlatform_getuid + + +uint64 MojoPlatform_geteuid(void) +{ + return 0; // !!! FIXME +} // MojoPlatform_geteuid + + +uint64 MojoPlatform_getgid(void) +{ + return 0; // !!! FIXME +} // MojoPlatform_getgid + + + // Get OS info and save the important parts. // Returns non-zero if successful, otherwise it returns zero on failure. static boolean getOSInfo(void) From DONOTREPLY at icculus.org Sun Jan 20 07:12:31 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 20 Jan 2008 07:12:31 -0500 Subject: r447 - trunk Message-ID: <20080120121231.12476.qmail@icculus.org> Author: icculus Date: 2008-01-20 07:12:30 -0500 (Sun, 20 Jan 2008) New Revision: 447 Modified: trunk/docs.txt Log: Added notes on uid/euid/gid fields. Modified: trunk/docs.txt =================================================================== --- trunk/docs.txt 2008-01-20 10:26:06 UTC (rev 446) +++ trunk/docs.txt 2008-01-20 12:12:30 UTC (rev 447) @@ -881,6 +881,26 @@ dependencies just to write this string into the log. + MojoSetup.info.uid + + This is a number (not a function!) that lists the user id of the person + running the installer. On Unix, this is what getuid() reports (and zero + would be the root user). + + + MojoSetup.info.euid + + This is a number (not a function!) that lists the EFFECTIVE user id of the + person running the installer. On Unix, this is what geteuid() reports (and + zero would be the root user). + + + MojoSetup.info.gid + + This is a number (not a function!) that lists the group id of the person + running the installer. On Unix, this is what getgid() reports. + + MojoSetup.info.locale This is a string (not a function!) of the current locale, in the format From DONOTREPLY at icculus.org Sun Jan 20 08:30:43 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 20 Jan 2008 08:30:43 -0500 Subject: r448 - trunk Message-ID: <20080120133043.11043.qmail@icculus.org> Author: icculus Date: 2008-01-20 08:30:43 -0500 (Sun, 20 Jan 2008) New Revision: 448 Modified: trunk/lua_glue.c Log: Added Lua hooks for checksumming a MojoInput and running scripts in other directories. Modified: trunk/lua_glue.c =================================================================== --- trunk/lua_glue.c 2008-01-20 12:12:30 UTC (rev 447) +++ trunk/lua_glue.c 2008-01-20 13:30:43 UTC (rev 448) @@ -566,6 +566,16 @@ } // luahook_runfile +// Lua interface to MojoLua_runFileFromDir(). This is needed instead of Lua's +// require(), since it can access scripts inside an archive. +static int luahook_runfilefromdir(lua_State *L) +{ + const char *dir = luaL_checkstring(L, 1); + const char *fname = luaL_checkstring(L, 2); + return retvalBoolean(L, MojoLua_runFileFromDir(dir, fname)); +} // luahook_runfile + + // Lua interface to translate(). static int luahook_translate(lua_State *L) { @@ -839,6 +849,38 @@ } // luahook_isvalidperms +static int do_checksum(lua_State *L, MojoInput *in) +{ + MojoChecksumContext ctx; + MojoChecksums sums; + int64 br = 0; + + MojoChecksum_init(&ctx); + + while (1) + { + br = in->read(in, scratchbuf_128k, sizeof (scratchbuf_128k)); + if (br <= 0) + break; + MojoChecksum_append(&ctx, scratchbuf_128k, (uint32) br); + } // while + + MojoChecksum_finish(&ctx, &sums); + + in->close(in); + + return (br < 0) ? 0 : retvalChecksums(L, &sums); +} // do_checksum + + +static int luahook_checksum(lua_State *L) +{ + const char *fname = luaL_checkstring(L, 1); + MojoInput *in = MojoInput_newFromFile(fname); + return do_checksum(L, in); +} // luahook_checksum + + static int luahook_archive_fromdir(lua_State *L) { const char *path = luaL_checkstring(L, 1); @@ -1517,6 +1559,7 @@ lua_newtable(luaState); // Set up initial C functions, etc we want to expose to Lua code... set_cfunc(luaState, luahook_runfile, "runfile"); + set_cfunc(luaState, luahook_runfilefromdir, "runfilefromdir"); set_cfunc(luaState, luahook_translate, "translate"); set_cfunc(luaState, luahook_ticks, "ticks"); set_cfunc(luaState, luahook_format, "format"); @@ -1543,6 +1586,7 @@ set_cfunc(luaState, luahook_truncatenum, "truncatenum"); set_cfunc(luaState, luahook_date, "date"); set_cfunc(luaState, luahook_isvalidperms, "isvalidperms"); + set_cfunc(luaState, luahook_checksum, "checksum"); // Set some information strings... lua_newtable(luaState); From DONOTREPLY at icculus.org Sun Jan 20 18:04:45 2008 From: DONOTREPLY at icculus.org (DONOTREPLY at icculus.org) Date: 20 Jan 2008 18:04:45 -0500 Subject: r449 - trunk/scripts Message-ID: <20080120230445.20428.qmail@icculus.org> Author: icculus Date: 2008-01-20 18:04:44 -0500 (Sun, 20 Jan 2008) New Revision: 449 Modified: trunk/scripts/mojosetup_mainline.lua Log: Reworked MojoSetup.manifest table to be hashed by filename first, since we're almost always iterating the whole thing to find a specific file, and concerned about dupes. Modified: trunk/scripts/mojosetup_mainline.lua =================================================================== --- trunk/scripts/mojosetup_mainline.lua 2008-01-20 13:30:43 UTC (rev 448) +++ trunk/scripts/mojosetup_mainline.lua 2008-01-20 23:04:44 UTC (rev 449) @@ -86,18 +86,12 @@ -- get a linear array of filenames in the manifest. -local function flatten_manifest() - local man = MojoSetup.manifest +local function flatten_manifest(man) local files = {} if man ~= nil then - for key,items in pairs(man) do - for i,item in ipairs(items) do - local path = item.path - if path ~= nil then - files[#files+1] = path - end - end + for fname,items in pairs(man) do + files[#files+1] = path end end @@ -115,7 +109,7 @@ -- !!! FIXME: callbacks here. delete_files(MojoSetup.downloads) - delete_files(flatten_manifest()) + delete_files(flatten_manifest(MojoSetup.manifest)) do_rollbacks() delete_scratchdirs() end @@ -268,16 +262,12 @@ -- Add to manifest first, so we can delete it during rollback if i/o fails. local manifestentry = { + option = manifestkey, type = "file", - path = dest, mode = perms, -- !!! FIXME: perms may be nil...we need a MojoSetup.defaultPermsString()... } if manifestkey ~= nil then - if MojoSetup.manifest[manifestkey] == nil then - MojoSetup.manifest[manifestkey] = {} - end - local manifest = MojoSetup.manifest[manifestkey] - manifest[#manifest+1] = manifestentry + MojoSetup.manifest[dest] = manifestentry end local written, sums = writefn(callback) @@ -330,12 +320,9 @@ end if manifestkey ~= nil then - if MojoSetup.manifest[manifestkey] == nil then - MojoSetup.manifest[manifestkey] = {} - end - local manifest = MojoSetup.manifest[manifestkey] - manifest[#manifest+1] = + MojoSetup.manifest[dest] = { + option = manifestkey, type = "symlink", path = dest, linkdest = lndest, @@ -355,13 +342,10 @@ end if manifestkey ~= nil then - if MojoSetup.manifest[manifestkey] == nil then - MojoSetup.manifest[manifestkey] = {} - end - local manifest = MojoSetup.manifest[manifestkey] - manifest[#manifest+1] = + MojoSetup.manifest[dest] = { - type = "dir", + option = manifestkey, + type = "directory", path = dest, mode = perms, } @@ -631,7 +615,7 @@ -- loki_patch with a MojoSetup installation. Please note that we never ever -- look at this data! You are responsible for updating the other files if -- you think it'll be important. The Unix MojoSetup uninstaller uses the --- plain text manifest, for example (but loki_uninstall can use the xml one, +-- lua manifest, for example (but loki_uninstall can use the xml one, -- so if you want, you can just drop in MojoSetup to replace loki_setup and -- use the Loki tools for everything else. local function build_xml_manifest() @@ -652,18 +636,23 @@ '" default="yes">\n' local destlen = string.len(MojoSetup.destination) + 2 - for option,items in pairs(MojoSetup.manifest) do - local desc = option - if type(desc) == "table" then -- "meta" etc, or an option table. - desc = option.description + + -- Need to group these by options. + local grouped = {} + for fname,entity in pairs(MojoSetup.manifest) do + local key = entity.option + if grouped[key] == nil then + if grouped[key] = {} end + entity.path = fname + local list = grouped[key] + list[#list+1] = entity + end + for desc,items in pairs(grouped) do retval = retval .. '\t\t