All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.scalacheck.util.CmdLineParser.scala Maven / Gradle / Ivy

There is a newer version: 1.18.1
Show newest version
/*-------------------------------------------------------------------------*\
**  ScalaCheck                                                             **
**  Copyright (c) 2007-2021 Rickard Nilsson. All rights reserved.          **
**  http://www.scalacheck.org                                              **
**                                                                         **
**  This software is released under the terms of the Revised BSD License.  **
**  There is NO WARRANTY. See the file LICENSE for the full text.          **
\*------------------------------------------------------------------------ */

package org.scalacheck.util

import scala.collection.Set

private[scalacheck] trait CmdLineParser {

  trait Opt[+T] {
    val default: T
    val names: Set[String]
    val help: String
  }
  trait Flag extends Opt[Unit]
  trait IntOpt extends Opt[Int]
  trait FloatOpt extends Opt[Float]
  trait StrOpt extends Opt[String]
  trait OpStrOpt extends Opt[Option[String]]

  class OptMap(private val opts: Map[Opt[_],Any] = Map.empty) {
    def apply(flag: Flag): Boolean = opts.contains(flag)
    def apply[T](opt: Opt[T]): T = opts.get(opt) match {
      case None => opt.default
      case Some(v) => v.asInstanceOf[T]
    }
    def set[T](o: (Opt[T], T)) = new OptMap(opts + o)
  }

  val opts: Set[Opt[_]]

  private def getOpt(s: String) = {
    if(s == null || s.length == 0 || s.charAt(0) != '-') None
    else opts.find(_.names.contains(s.drop(1)))
  }

  private def getStr(s: String) = Some(s)

  private def getInt(s: String) =
    if (s != null && s.length > 0 && s.forall(_.isDigit)) Some(s.toInt)
    else None

  private def getFloat(s: String) =
    if (s != null && s.matches("[0987654321]+\\.?[0987654321]*")) Some(s.toFloat)
    else None

  def printHelp(): Unit = {
    Console.out.println("Available options:")
    opts.foreach { opt =>
      Console.out.println("  " + opt.names.map("-"+_).mkString(", ") + ": " + opt.help)
    }
  }

  /** Parses a command line and returns a tuple of the parsed options,
   *  and any unrecognized strings */
  def parseArgs[T](args: Array[String]): (OptMap, List[String]) = {

    def parse(
      as: List[String], om: OptMap, us: List[String]
    ): (OptMap, List[String]) =
      as match {
        case Nil => (om, us)
        case a::Nil =>
          getOpt(a) match {
            case Some(o: Flag) =>
              parse(Nil, om.set((o, ())), us)
            case _ =>
              (om, us :+ a)
          }
        case a1::a2::as => getOpt(a1) match {
          case Some(o: Flag) =>
            parse(a2 :: as, om.set((o, ())), us)
          case otherwise =>
            (otherwise match {
              case Some(o: IntOpt) => getInt(a2).map(v => parse(as, om.set(o -> v), us))
              case Some(o: FloatOpt) => getFloat(a2).map(v => parse(as, om.set(o -> v), us))
              case Some(o: StrOpt) => getStr(a2).map(v => parse(as, om.set(o -> v), us))
              case Some(o: OpStrOpt) => getStr(a2).map(v => parse(as, om.set(o -> Option(v)), us))
              case _ => None
            }).getOrElse(parse(a2::as, om, us :+ a1))
        }
      }

    parse(args.toList, new OptMap(), Nil)
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy