<commit_before>/*                     __                                               *\
**     ________ ___   / /  ___     Scala API                            **
**    / __/ __// _ | / /  / _ |    (c) 2003-2009, LAMP/EPFL             **
**  __\ \/ /__/ __ |/ /__/ __ |    http://scala-lang.org/               **
** /____/\___/_/ |_/____/_/ | |                                         **
**                          |/                                          **
\*                                                                      */

package scala.io

import annotation.experimental
import concurrent.ThreadRunner
import util.Properties.{ isWin, isMac }
import util.control.Exception.catching
import java.lang.{ Process => JProcess, ProcessBuilder => JProcessBuilder }
import java.io.{ IOException, InputStream, OutputStream, BufferedReader, InputStreamReader, File => JFile }
import java.util.concurrent.LinkedBlockingQueue

/** The <code>Process</code> object contains convenience functions
 *  for running external processes.
 *
 *  An example usage:
 *  <pre>
 *    io.Process("ls", cwd = io.File("/")) foreach println
 *  </pre>
 *
 *  See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4109888
 *  for a dated list of the many obstacles to a clean interface.
 *
|*  This is not finished!! Do not rely upon it yet.
 *
 *  @author   <NAME>
 *  @since    2.8
 */

@experimental
object Process
{
  lazy val runtime = Runtime.getRuntime()

  @experimental
  private[Process] class ProcessBuilder(val pb: JProcessBuilder)
  {
    def this(cmd: String*) = this(new JProcessBuilder(cmd.toArray: _*))
    def start() = new Process(() => pb.start())

    def withOnlyEnv(env: Map[String, String]): this.type = {
      pb.environment.clear()
      withEnv(env)
    }

    def withEnv(env: Map[String,String]): this.type = {
      if (env != null) {
        val jmap = pb.environment()
        for ((k, v) <- env) jmap.put(k, v)
      }
      this
    }

    def withCwd(cwd: File): this.type = {
      if (cwd != null)
        pb directory cwd.file

      this
    }
    def withRedirectedErrorStream(merged: Boolean): this.type = {
      pb redirectErrorStream merged
      this
    }

    override def toString() = "ProcessBuilder(%s)" format pb.command()
  }

  // This can be fleshed out if more variations come up
  private val shell: String => Array[String] =
    if (isWin) Array("cmd.exe", "/C", _)
    else Array("sh", "-c", _)

  /** Executes the given command line in a shell.
   *
   *  @param    command   the command line
   *  @return             a Process object
   */
  def apply(
    command: String,
    env: Map[String, String] = null,
    cwd: File = null,
    redirect: Boolean = false
  ): Process =
      exec(shell(command), env, cwd)

  /** Executes the given command line.
   *
   *  @param    command   the command line
   *  @return             a Process object
   */
  def exec(
    command: Seq[String],
    env: Map[String, String] = null,
    cwd: File = null,
    redirect: Boolean = false
  ): Process =
      new ProcessBuilder(command: _*) withEnv env withCwd cwd start
}
import Process._

@experimental
class Process(processCreator: () => JProcess) extends Iterable[String]
{
  lazy val process = processCreator()

  def exitValue(): Option[Int] =
    catching(classOf[IllegalThreadStateException]) opt process.exitValue()

  def waitFor() = process.waitFor()
  def destroy() = process.destroy()
  def rerun() = new Process(processCreator)

  def iterator = _out.iterator
  def err = _err.iterator

  class StreamedConsumer(in: InputStream) extends Thread with Iterable[String] {
    private val queue = new LinkedBlockingQueue[String]
    private val reader = new BufferedReader(new InputStreamReader(in))

    def iterator = {
      join()  // make sure this thread is complete
      new Iterator[String] {
        val it = queue.iterator()
        def hasNext = it.hasNext
        def next = it.next
      }
    }
    override def run() {
      reader.readLine match {
        case null =>
        case x    =>
          queue put x
          run()
      }
    }
  }

  private val _err = createConsumer(process.getErrorStream)
  private val _out = createConsumer(process.getInputStream)
  private def createConsumer(in: InputStream) = {
    val t = new StreamedConsumer(in)
    t.start()
    t
  }

  override def toString() = "Process(%s)" format process.toString()
}

<commit_msg>Exposed stdin as a PrintWriter.<commit_after>/*                     __                                               *\
**     ________ ___   / /  ___     Scala API                            **
**    / __/ __// _ | / /  / _ |    (c) 2003-2009, LAMP/EPFL             **
**  __\ \/ /__/ __ |/ /__/ __ |    http://scala-lang.org/               **
** /____/\___/_/ |_/____/_/ | |                                         **
**                          |/                                          **
\*                                                                      */

package scala.io

import annotation.experimental
import concurrent.ThreadRunner
import util.Properties.{ isWin, isMac }
import util.control.Exception.catching
import java.lang.{ Process => JProcess, ProcessBuilder => JProcessBuilder }
import java.io.{ IOException, InputStream, OutputStream, BufferedReader, InputStreamReader, PrintWriter, File => JFile }
import java.util.concurrent.LinkedBlockingQueue

/** The <code>Process</code> object contains convenience functions
 *  for running external processes.
 *
 *  An example usage:
 *  <pre>
 *    io.Process("ls", cwd = io.File("/")) foreach println
 *  </pre>
 *
 *  See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4109888
 *  for a dated list of the many obstacles to a clean interface.
 *
|*  This is not finished!! Do not rely upon it yet.
 *
 *  @author   <NAME>
 *  @since    2.8
 */

@experimental
object Process
{
  lazy val runtime = Runtime.getRuntime()

  @experimental
  private[Process] class ProcessBuilder(val pb: JProcessBuilder)
  {
    def this(cmd: String*) = this(new JProcessBuilder(cmd.toArray: _*))
    def start() = new Process(() => pb.start())

    def withOnlyEnv(env: Map[String, String]): this.type = {
      pb.environment.clear()
      withEnv(env)
    }

    def withEnv(env: Map[String,String]): this.type = {
      if (env != null) {
        val jmap = pb.environment()
        for ((k, v) <- env) jmap.put(k, v)
      }
      this
    }

    def withCwd(cwd: File): this.type = {
      if (cwd != null)
        pb directory cwd.file

      this
    }
    def withRedirectedErrorStream(merged: Boolean): this.type = {
      pb redirectErrorStream merged
      this
    }

    override def toString() = "ProcessBuilder(%s)" format pb.command()
  }

  // This can be fleshed out if more variations come up
  private val shell: String => Array[String] =
    if (isWin) Array("cmd.exe", "/C", _)
    else Array("sh", "-c", _)

  /** Executes the given command line in a shell.
   *
   *  @param    command   the command line
   *  @return             a Process object
   */
  def apply(
    command: String,
    env: Map[String, String] = null,
    cwd: File = null,
    redirect: Boolean = false
  ): Process =
      exec(shell(command), env, cwd)

  /** Executes the given command line.
   *
   *  @param    command   the command line
   *  @return             a Process object
   */
  def exec(
    command: Seq[String],
    env: Map[String, String] = null,
    cwd: File = null,
    redirect: Boolean = false
  ): Process =
      new ProcessBuilder(command: _*) withEnv env withCwd cwd start
}
import Process._

@experimental
class Process(processCreator: () => JProcess) extends Iterable[String]
{
  lazy val process = processCreator()

  def exitValue(): Option[Int] =
    catching(classOf[IllegalThreadStateException]) opt process.exitValue()

  def waitFor() = process.waitFor()
  def destroy() = process.destroy()
  def rerun() = new Process(processCreator)

  def stdout    = iterator
  def iterator  = _out.iterator
  def stderr    = _err.iterator
  lazy val stdin = new PrintWriter(_in, true)

  class StreamedConsumer(in: InputStream) extends Thread with Iterable[String] {
    private val queue = new LinkedBlockingQueue[String]
    private val reader = new BufferedReader(new InputStreamReader(in))

    def iterator = {
      join()  // make sure this thread is complete
      new Iterator[String] {
        val it = queue.iterator()
        def hasNext = it.hasNext
        def next = it.next
      }
    }
    override def run() {
      reader.readLine match {
        case null =>
        case x    =>
          queue put x
          run()
      }
    }
  }

  private val _err = createConsumer(process.getErrorStream)
  private val _out = createConsumer(process.getInputStream)
  private val _in  = process.getOutputStream()

  private def createConsumer(in: InputStream) = {
    val t = new StreamedConsumer(in)
    t.start()
    t
  }

  override def toString() = "Process(%s)" format process.toString()
}


{'fraction_non_alphanumeric': 0.1163100121964741, 'fraction_numerical': 0.0037698192704290943, 'mean_word_length': 2.137391304347826, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 22, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4872945', 'n_tokens_mistral': 2707, 'n_tokens_neox': 2631, 'n_words': 734}