+
+=item getmessage
+
+ getmessage($msgid);
+ getmessage($msgid, $variables);
+
+Gets a localized message (format string) with message id $msgid,
+and, if an array reference of variables $variables is given,
+substitutes variables in the format string with @$variables.
+Returns the found message string, with variable substitutions
+if specified.
+
+$msgid must be the message identifier corresponding to a defined
+message string (a valid key to the $messages hash in the Installer
+package). getmessage throws an exception if the message cannot be
+found.
+
+=cut
+
+sub getmessage {
+ my $messagename=shift;
+ my $variables=shift;
+ my $message=$messages->{$messagename}->{$language} || $messages->{$messagename}->{en} || RED.BOLD."Error: No message named $messagename in Install.pm\n";
+ if (defined($variables)) {
+ $message=sprintf $message, @$variables;
+ }
+ return $message;
+}
+
+
+=item showmessage
+
+ showmessage($message, 'none');
+ showmessage($message, 'none', undef, $noclear);
+
+ $result = showmessage($message, 'yn');
+ $result = showmessage($message, 'yn', $defaultresponse);
+ $result = showmessage($message, 'yn', $defaultresponse, $noclear);
+
+ $result = showmessage($message, 'restrictchar CHARS');
+ $result = showmessage($message, 'free');
+ $result = showmessage($message, 'silentfree');
+ $result = showmessage($message, 'numerical');
+ $result = showmessage($message, 'email');
+ $result = showmessage($message, 'PressEnter');
+
+Shows a message and optionally gets a response from the user.
+
+The first two arguments, the message and the response type,
+are mandatory. The message must be the actual string to
+display; the caller is responsible for calling getmessage if
+required.
+
+The response type must be one of "none", "yn", "free", "silentfree"
+"numerical", "email", "PressEnter", or a string consisting
+of "restrictchar " followed by a list of allowed characters
+(space can be specified). (Case is not significant, but case is
+significant in the list of allowed characters.) If a response
+type other than the above-listed is specified, the result is
+undefined.
+
+Note that the response type "yn" is equivalent to "restrictchar yn".
+Because "restrictchar" is case-sensitive, the user is expected
+to enter "y" or "n" in lowercase only.
+
+Note that the response type of "email" does not actually
+guarantee that the returned value is a well-formed RFC-822
+email address, nor does it accept all well-formed RFC-822 email
+addresses. What it does is to restrict the returned value to a
+string that is looks reasonably likely to be an email address
+in the "real world", given the premise that the user is trying
+to enter a real email address.
+
+If a response type other than "none" or "PressEnter" is
+specified, a third argument, specifying the default value, can
+be specified: If this default response is not specified, the
+default response is the first allowed character if the response
+type is "restrictchar", otherwise the default response is the
+empty string. This default response is used when the user does
+not specify a value (i.e., presses Enter without typing in
+anything), showmessage will assume that the default response is
+the user's response.
+
+Note that because the response type "yn" is equivalent to
+"restrictchar yn", the default value for response type "yn",
+if unspecified, is "y".
+
+The screen is normally cleared before the message is displayed;
+if a fourth argument is specified and is nonzero, this
+screen-clearing is not done.
+
+=cut
+#'
+
+sub showmessage {
+ #MJR: Maybe refactor to use anonymous functions that
+ # check the responses instead of RnP branching.
+ my $message=join('',fill('','',(shift)));
+ my $responsetype=shift;
+ my $defaultresponse=shift;
+ my $noclear=shift;
+ $noclear = 0 unless defined $noclear; # defaults to "clear"
+ ($noclear) || (print $clear_string);
+ if ($responsetype =~ /^yn$/) {
+ $responsetype='restrictchar ynYN';
+ }
+ print RESET.$message;
+ if ($responsetype =~/^restrictchar (.*)/i) {
+ my $response='\0';
+ my $options=$1;
+ until ($options=~/$response/) {
+ (defined($defaultresponse)) || ($defaultresponse=substr($options,0,1));
+ $response=<STDIN>;
+ chomp $response;
+ (length($response)) || ($response=$defaultresponse);
+ if ( $response=~/.*[\:\(\)\^\$\*\!\\].*/ ) {
+ ($noclear) || (print $clear_string);
+ print RED."Response contains invalid characters. Choose from [$options].\n\n";
+ print RESET.$message;
+ $response='\0';
+ } else {
+ unless ($options=~/$response/) {
+ ($noclear) || (print $clear_string);
+ print RED."Invalid Response. Choose from [$options].\n\n";
+ print RESET.$message;
+ }
+ }
+ }
+ return $response;
+ } elsif ($responsetype =~/^(silent)?free$/i) {
+ (defined($defaultresponse)) || ($defaultresponse='');
+ if ($responsetype =~/^(silent)/i) { setecho(0) };
+ my $response=<STDIN>;
+ if ($responsetype =~/^(silent)/i) { setecho(1) };
+ chomp $response;
+ ($response) || ($response=$defaultresponse);
+ return $response;
+ } elsif ($responsetype =~/^numerical$/i) {
+ (defined($defaultresponse)) || ($defaultresponse='');
+ my $response='';
+ until ($response=~/^\d+$/) {
+ $response=<STDIN>;
+ chomp $response;
+ ($response) || ($response=$defaultresponse);
+ unless ($response=~/^\d+$/) {
+ ($noclear) || (print $clear_string);
+ print RED."Invalid Response ($response). Response must be a number.\n\n";
+ print RESET.$message;
+ }
+ }
+ return $response;
+ } elsif ($responsetype =~/^email$/i) {
+ (defined($defaultresponse)) || ($defaultresponse='');
+ my $response='';
+ until ($response=~/.*\@.*\..*/) {
+ $response=<STDIN>;
+ chomp $response;
+ ($response) || ($response=$defaultresponse);
+ if ($response!~/.*\@.*\..*/) {
+ ($noclear) || (print $clear_string);
+ print RED."Invalid Response ($response). Response must be a valid email address.\n\n";
+ print RESET.$message;
+ }
+ }
+ return $response;
+ } elsif ($responsetype =~/^PressEnter$/i) {
+ <STDIN>;
+ return;
+ } elsif ($responsetype =~/^none$/i) {
+ return;
+ } else {
+ # FIXME: There are a few places where we will get an undef as the
+ # response type. Should we thrown an exception here, or should we
+ # legitimize this usage and say "none" is the default if not specified?
+ #die "Illegal response type \"$responsetype\"";
+ }
+}
+
+
+=back
+
+=item startsysout
+
+ startsysout;
+
+Changes the display to show system output until the next showmessage call.
+At the time of writing, this means using red text.
+
+=cut
+
+sub startsysout {
+ print RED."\n";
+}
+
+