From pgilbert@bank-banque-canada.ca  Mon Nov  5 15:07:42 2001
From: pgilbert@bank-banque-canada.ca (pgilbert@bank-banque-canada.ca)
Date: Mon, 5 Nov 2001 16:07:42 +0100 (MET)
Subject: [Rd] bug.report()sends empty message (PR#1158)
Message-ID: <200111051507.QAA03967@pubhealth.ku.dk>

This is a multi-part message in MIME format.
--------------FAC78F7B6BFECAD9BD873458
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

On Mon, 22 Oct 2001, David Brahm wrote:
>    I swear, bug.report() ate my message!  Apologies to all, esp. Peter who
> will once again have to clean up after my mess...

With some editors on Unix bug.report() does this. The problem is that
some editors (like Nedit) fork a separate process and return. The Unix
version of bug.report sends an empty message in this case. The fix is to
make the Unix version the same as the Windows version, with an optional
argument "wait".

Attached are four small files bug.report.R, bug.report.Rd, Sys.mail.R,
and Sys.mail.Rd, which attempt to fix the problem and the documentation.
They also separate out the mail mechanism as a utility that can be used
elsewhere. Unfortunately, I have only been able to test these on a
limited number of platforms.

Paul Gilbert

--------------FAC78F7B6BFECAD9BD873458
Content-Type: text/plain; charset=us-ascii;
 name="bug.report.R"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="bug.report.R"

bug.report <- function(subject = "", ccaddress = Sys.getenv("USER"),
                       method = getOption("mailer"),
                       address = "gilp",  #"r-bugs@r-project.org",
                       file = "R.bug.report",
		       wait=TRUE)
{
    methods <- c("mailx", "gnudoit", "none", "ess")

    method <-
	if(is.null(method)) "none"
	else methods[pmatch(method, methods)]

    body <- paste("\\n<<insert bug report here>>\\n\\n\\n\\n",
		  "--please do not edit the information below--\\n\\n",
		  "Version:\\n ",
		  paste(names(R.version),R.version, sep=" = ",collapse="\\n "),
		  "\\n\\n",
		  "Search Path:\\n ",
		  paste(search(), collapse=", "),
		  "\\n", sep="", collapse="")

    if(method == "gnudoit") {
	cmd <- paste("gnudoit -q '",
		     "(mail nil \"", address, "\")",
		     "(insert \"", body, "\")",
		     "(search-backward \"Subject:\")",
		     "(end-of-line)'",
		     sep="")
	system(cmd)
        if (wait) {
	  cat("Hit Return to continue in R. ")
	  answer <- readline()
        }
    }
    else if(method=="none"){

        disclaimer <-
            paste("# Your mailer is set to \"none\" (default on Windows),\n",
                  "# hence we cannot send the bug report directly from R.\n",
                  "# Please copy the bug report (after finishing it) to\n",
                  "# your favorite email program and send it to\n#\n",
                  "#       ", address, "\n#\n",
                  "######################################################\n",
                  "\n\n", sep = "")

        cat(disclaimer, file=file)
	body <- gsub("\\\\n", "\n", body)
	cat(body, file=file, append=TRUE)
	system(paste(getOption("editor"), file))
        cat("The unsent bug report can be found in file", file, "\n")
        if (wait) {
	  cat("Hit Return to continue in R. ")
	  answer <- readline()
        }
    }
    else if(method == "mailx"){

        if(missing(subject)) stop("Subject missing")

	body <- gsub("\\\\n", "\n", body)
	cat(body, file=file, append=FALSE)
	system(paste(getOption("editor"), file))
	
	if (wait) {
	  cat("Submit the bug report? (finish editing and save the file before responding) ")
	  answer <- readline()
	  answer <- grep("y", answer, ignore.case=TRUE)
	  if(length(answer)>0){
 	     body <- scan(file, what="char", sep="\n")
             cat("Sending email ...\n")
             status <- Sys.mail(address=address, ccaddress=ccaddress,
	                       subject=subject, body=body, method="mailx")
             if(!status) status <- Sys.mail(address=address, ccaddress=ccaddress,
	                       subject=subject, body=body, method="mail")
             if(!status) status <- Sys.mail(address=address, ccaddress=ccaddress,
	                       subject=subject, body=body, method="Mail")
             if(!status) {
                cat("Sending email failed!\n")
                cat("The unsent bug report can be found in file", file, "\n")
            }
	  }
        }
        else cat("The unsent bug report can be found in file", file, "\n")
    }
    else if(method=="ess"){
	body <- gsub("\\\\n", "\n", body)
	cat(body)
        if (wait) {
	  cat("Hit Return to continue in R. ")
	  answer <- readline()
        }
    }
}

--------------FAC78F7B6BFECAD9BD873458
Content-Type: text/plain; charset=us-ascii;
 name="bug.report.Rd"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="bug.report.Rd"

\name{bug.report}
\alias{bug.report}
\title{Send a Bug Report}
\usage{
bug.report(subject = "", ccaddress = Sys.getenv("USER"),
           method = getOption("mailer"), 
	   address = "r-bugs@r-project.org",
           file = "R.bug.report",
	   wait = TRUE)

}
\arguments{
  \item{subject}{Subject of the email. Please do not use single quotes
    (\code{'}) in the subject!}
  \item{ccaddress}{Optional email address for copies (default is current
    user).  Use \code{ccaddress = NULL} for no copies.}
  \item{method}{Submission method, one of \code{"mailx"},
    \code{"gnuclient"}, \code{"none"}, or \code{"ess"}.}
  \item{address}{Recipient's email address.}
  \item{file}{File to use for setting up the email (or storing it when
    method is \code{"none"} or sending mail fails).}
  \item{wait}{logical. Should \R wait for the editor to return?}
}
\description{
  Invokes an editor to write a bug report and optionally mail it to the
  r-bugs list at \email{r-bugs@r-project.org}.  Some standard
  information on the current version and configuration of \R are 
  included automatically.
}
\details{
  Currently direct submission of bug reports works only on Unix systems.
  If the submission method is \code{"mailx"}, then the default editor is
  used to write the bug report. Which editor is used can be controlled
  using \code{\link{options}}, type \code{getOption("editor")} to see what
  editor is currently defined. Please use the help pages of the
  respective editor for details of usage. After saving the bug report
  (in the temporary file opened) and exiting the editor
  the report is mailed using a Unix command line mail utility such as
  \code{mailx}.  A copy of the mail is sent to the current user.

  If method is \code{"gnuclient"}, then an emacs mail buffer is opened
  and used for sending the email.

  If method is \code{"none"} or \code{NULL} (which is the default on
  Windows systems), then only an editor is opened to help writing the
  bug report.  The report can then be copied to your favorite email
  program and be sent to the r-bugs list.

  If method is \code{"ess"} the body of the mail is simply sent to
  stdout.
  
  If wait is \code{"TRUE"} then \R issues a prompt after the editor is started
  and waits for input. If \R is sending the mail (e.g. with method
  code{"mailx"}) then wait should be \code{"TRUE"}. In this case the edited file
  must be saved before responding to the question.
}
\value{Nothing useful.}
\section{When is there a bug?}{
  If \R executes an illegal instruction, or dies with an operating
  system error message that indicates a problem in the program (as
  opposed to something like ``disk full''), then it is certainly a bug.

  Taking forever to complete a command can be a bug, but you must make
  certain that it was really \R's fault.  Some commands simply take a
  long time.  If the input was such that you KNOW it should have been
  processed quickly, report a bug.  If you don't know whether the
  command should take a long time, find out by looking in the manual or
  by asking for assistance.

  If a command you are familiar with causes an \R error message in a
  case where its usual definition ought to be reasonable, it is probably
  a bug.  If a command does the wrong thing, that is a bug.  But be sure
  you know for certain what it ought to have done.  If you aren't
  familiar with the command, or don't know for certain how the command
  is supposed to work, then it might actually be working right.  Rather
  than jumping to conclusions, show the problem to someone who knows for
  certain.

   Finally, a command's intended definition may not be best for
   statistical analysis.  This is a very important sort of problem, but
   it is also a matter of judgment.  Also, it is easy to come to such a
   conclusion out of ignorance of some of the existing features.  It is
   probably best not to complain about such a problem until you have
   checked the documentation in the usual ways, feel confident that you
   understand it, and know for certain that what you want is not
   available.  If you are not sure what the command is supposed to do
   after a careful reading of the manual this indicates a bug in the
   manual.  The manual's job is to make everything clear.  It is just as
   important to report documentation bugs as program bugs.

   If the online argument list of a function disagrees with the manual,
   one of them must be wrong, so report the bug.
}
\section{How to report a bug}{
  When you decide that there is a bug, it is important to report it and
  to report it in a way which is useful.  What is most useful is an
  exact description of what commands you type, from when you start \R
  until the problem happens.  Always include the version of \R, machine,
  and operating system that you are using; type `version' in \R to print
  this. 

  The most important principle in reporting a bug is to report FACTS,
  not hypotheses or categorizations.  It is always easier to report the
  facts, but people seem to prefer to strain to posit explanations and
  report them instead.  If the explanations are based on guesses about
  how \R is implemented, they will be useless; we will have to try to 
  figure out what the facts must have been to lead to such
  speculations.  Sometimes this is impossible.  But in any case, it is
  unnecessary work for us.

  For example, suppose that on a data set which you know to be quite
  large the command \code{data.frame(x, y, z, monday, tuesday)} never
  returns.  Do not report that \code{data.frame()} fails for large data
  sets.  Perhaps it fails when a variable name is a day of the week.  If
  this is so then when we got your report we would try out the
  \code{data.frame()} command on a large data set, probably with no day
  of the week variable name, and not see any problem. There is no way in
  the world that we could guess that we should try a day of the week
  variable name.

  Or perhaps the command fails because the last command you used was a
  \code{[} method that had a bug causing \R's internal data structures
  to be corrupted and making the \code{data.frame()} command fail from
  then on.  This is why we need to know what other commands you have
  typed (or read from your startup file).

  It is very useful to try and find simple examples that produce
  apparently the same bug, and somewhat useful to find simple examples
  that might be expected to produce the bug but actually do not.  If you
  want to debug the problem and find exactly what caused it, that is
  wonderful.  You should still report the facts as well as any
  explanations or solutions.

  Invoking \R with the \code{--vanilla} option may help in isolating a
  bug.  This ensures that the site profile and saved data files are not
  read.

  On some systems a bug report can be generated using the
  \code{bug.report()} function.  This automatically includes the version
  information and sends the bug to the correct address.  Alternatively
  the bug report can be emailed to \email{r-bugs@r-project.org} or
  submitted to the Web page at \url{http://bugs.r-project.org}.
}
\seealso{R FAQ, \code{link{Sys.mail}} }
\author{This help page is adapted from the Emacs manual}
\keyword{utilities}
\keyword{error}

--------------FAC78F7B6BFECAD9BD873458
Content-Type: text/plain; charset=us-ascii;
 name="Sys.mail.R"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="Sys.mail.R"

Sys.mail <- function(address = Sys.info()$user,
                     ccaddress  = NULL,
                     bccaddress = NULL,
		     subject    = NULL,
		     body= "no body",
                     method = getOption("mailer")) {
   if(!(is.character(address) && nchar(address)>0))
      stop("A character string address must be specified.")

   # The arguments to mail, mailx, and Mail are all the same, but a different
   # mailer will require that this first part be re-organized under the
   # specific method.
   file <- tempfile()
   on.exit(unlink(file))
   cat(body, file=file, append=FALSE, sep="\n")
   cmdargs <- paste(address, "<", file, "2>/dev/null")
	
   if(is.character(ccaddress) && nchar(ccaddress)>0) 
            cmdargs <- paste(" -c '", ccaddress, "' ",  cmdargs)

   if(is.character(bccaddress) && nchar(bccaddress)>0) 
            cmdargs <- paste(" -b '", bccaddress, "' ",  cmdargs)

   if(is.character(subject) && nchar(subject)>0) 
            cmdargs <- paste(" -s '", subject, "' ",  cmdargs)

   status <- 1
   if(method == "mailx") status <- system(paste("mailx", cmdargs)) else
   if(method == "mail")  status <- system(paste("mail", cmdargs))  else 
   if(method == "Mail")  status <- system(paste("Mail", cmdargs))  else {
	warning(paste("mail method ", method, " not supported.\n"))
	return(F)
	}
   if(status > 0) {
	warning(paste("sending email with ", method, " failed.\n"))
	return(F)
	}
   T
   }

--------------FAC78F7B6BFECAD9BD873458
Content-Type: text/plain; charset=us-ascii;
 name="Sys.mail.Rd"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="Sys.mail.Rd"

\name{Sys.mail}
\alias{Sys.mail}
\title{Send Mail}
\usage{
Sys.mail(address= Sys.info()$user, ccaddress = NULL, bccaddress = NULL,
           subject = NULL, body= "no body", method = getOption("mailer"))
}
\arguments{
  \item{address}{Recipient's email address. The default is the user name as
     indicated by \code{Sys.info()$user}, which will correspond to your 
     own email address on many systems.}
  \item{ccaddress}{Optional email address for copies. 
    Use \code{ccaddress = NULL} for no copies.}
  \item{bccaddress}{Optional email address for blind copies.
    Use \code{bccaddress = NULL} for no copies.}
  \item{subject}{Subject of the email. Please do not use single quotes
     in the subject!}
  \item{method}{Submission method, one of \code{"mailx"},
    \code{"mail"}, or \code{"Mail"}.}
  \item{body}{A vector of character, one line per element to place in the body
     of the email.}
}
\description{
  Use a system mail tool to send a message. Multiple recipients can be
  specified in any of the addresses by enclosing them in double (\code{"}) 
  quotes. Please do not use single (\code{'}) quotes.
  
  The body is a vector of character. Each element of body is written 
  as a line of the message body.
}
\details{
  Currently works only on Unix systems using "mailx", "mail" or "Mail". The mail
  tool needs to be found on your Unix search path.
}
\value{TRUE or FALSE indicating success or failure as returned by the operating
    system. (This does not indicate that the message was received at the 
    address.)}

\examples{
    \dontrun{Sys.mail(address="friends", subject="R", body="R is great")}
}
\seealso{\code{link{options}} }
\author{Paul Gilbert}
\keyword{utilities}


--------------FAC78F7B6BFECAD9BD873458--


-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-devel-request@stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._


[Rd] bug.report()sends empty message (PR#1158)
pgilbert@bank-banque-canada.ca