src/Pure/System/options.scala
changeset 74827 c1b5d6e6ff74
parent 74144 f9f6a31cc99c
child 75393 87ebf5a50283
equal deleted inserted replaced
74826:0e4d8aa61ad7 74827:c1b5d6e6ff74
    31     pos: Position.T,
    31     pos: Position.T,
    32     name: String,
    32     name: String,
    33     typ: Type,
    33     typ: Type,
    34     value: String,
    34     value: String,
    35     default_value: String,
    35     default_value: String,
       
    36     standard_value: Option[String],
    36     description: String,
    37     description: String,
    37     section: String)
    38     section: String)
    38   {
    39   {
       
    40     private def print_value(x: String): String = if (typ == Options.String) quote(x) else x
       
    41     private def print_standard: String =
       
    42       standard_value match {
       
    43         case None => ""
       
    44         case Some(s) if s == default_value => " (standard)"
       
    45         case Some(s) => " (standard " + print_value(s) + ")"
       
    46       }
    39     private def print(default: Boolean): String =
    47     private def print(default: Boolean): String =
    40     {
    48     {
    41       val x = if (default) default_value else value
    49       val x = if (default) default_value else value
    42       "option " + name + " : " + typ.print + " = " +
    50       "option " + name + " : " + typ.print + " = " + print_value(x) + print_standard +
    43         (if (typ == Options.String) quote(x) else x) +
       
    44         (if (description == "") "" else "\n  -- " + quote(description))
    51         (if (description == "") "" else "\n  -- " + quote(description))
    45     }
    52     }
    46 
    53 
    47     def print: String = print(false)
    54     def print: String = print(false)
    48     def print_default: String = print(true)
    55     def print_default: String = print(true)
    65   /* parsing */
    72   /* parsing */
    66 
    73 
    67   private val SECTION = "section"
    74   private val SECTION = "section"
    68   private val PUBLIC = "public"
    75   private val PUBLIC = "public"
    69   private val OPTION = "option"
    76   private val OPTION = "option"
       
    77   private val STANDARD = "standard"
    70   private val OPTIONS = Path.explode("etc/options")
    78   private val OPTIONS = Path.explode("etc/options")
    71   private val PREFS = Path.explode("$ISABELLE_HOME_USER/etc/preferences")
    79   private val PREFS = Path.explode("$ISABELLE_HOME_USER/etc/preferences")
    72 
    80 
    73   val options_syntax: Outer_Syntax =
    81   val options_syntax: Outer_Syntax =
    74     Outer_Syntax.empty + ":" + "=" + "--" + Symbol.comment + Symbol.comment_decoded +
    82     Outer_Syntax.empty + ":" + "=" + "--" + "(" + ")" +
       
    83       Symbol.comment + Symbol.comment_decoded +
    75       (SECTION, Keyword.DOCUMENT_HEADING) +
    84       (SECTION, Keyword.DOCUMENT_HEADING) +
    76       (PUBLIC, Keyword.BEFORE_COMMAND) +
    85       (PUBLIC, Keyword.BEFORE_COMMAND) +
    77       (OPTION, Keyword.THY_DECL)
    86       (OPTION, Keyword.THY_DECL) +
       
    87       STANDARD
    78 
    88 
    79   val prefs_syntax: Outer_Syntax = Outer_Syntax.empty + "="
    89   val prefs_syntax: Outer_Syntax = Outer_Syntax.empty + "="
    80 
    90 
    81   trait Parser extends Parse.Parser
    91   trait Parser extends Parse.Parser
    82   {
    92   {
    84     val option_type: Parser[String] = atom("option type", _.is_name)
    94     val option_type: Parser[String] = atom("option type", _.is_name)
    85     val option_value: Parser[String] =
    95     val option_value: Parser[String] =
    86       opt(token("-", tok => tok.is_sym_ident && tok.content == "-")) ~ atom("nat", _.is_nat) ^^
    96       opt(token("-", tok => tok.is_sym_ident && tok.content == "-")) ~ atom("nat", _.is_nat) ^^
    87         { case s ~ n => if (s.isDefined) "-" + n else n } |
    97         { case s ~ n => if (s.isDefined) "-" + n else n } |
    88       atom("option value", tok => tok.is_name || tok.is_float)
    98       atom("option value", tok => tok.is_name || tok.is_float)
       
    99     val option_standard: Parser[Option[String]] =
       
   100       $$$("(") ~! $$$(STANDARD) ~ opt(option_value) ~ $$$(")") ^^ { case _ ~ _ ~ a ~ _ => a }
    89   }
   101   }
    90 
   102 
    91   private object Parser extends Parser
   103   private object Parser extends Parser
    92   {
   104   {
    93     def comment_marker: Parser[String] =
   105     def comment_marker: Parser[String] =
    96     val option_entry: Parser[Options => Options] =
   108     val option_entry: Parser[Options => Options] =
    97     {
   109     {
    98       command(SECTION) ~! text ^^
   110       command(SECTION) ~! text ^^
    99         { case _ ~ a => (options: Options) => options.set_section(a) } |
   111         { case _ ~ a => (options: Options) => options.set_section(a) } |
   100       opt($$$(PUBLIC)) ~ command(OPTION) ~! (position(option_name) ~ $$$(":") ~ option_type ~
   112       opt($$$(PUBLIC)) ~ command(OPTION) ~! (position(option_name) ~ $$$(":") ~ option_type ~
   101       $$$("=") ~ option_value ~ (comment_marker ~! text ^^ { case _ ~ x => x } | success(""))) ^^
   113       $$$("=") ~ option_value ~ opt(option_standard) ~
   102         { case a ~ _ ~ ((b, pos) ~ _ ~ c ~ _ ~ d ~ e) =>
   114         (comment_marker ~! text ^^ { case _ ~ x => x } | success(""))) ^^
   103             (options: Options) => options.declare(a.isDefined, pos, b, c, d, e) }
   115         { case a ~ _ ~ ((b, pos) ~ _ ~ c ~ _ ~ d ~ e ~ f) =>
       
   116             (options: Options) => options.declare(a.isDefined, pos, b, c, d, e, f) }
   104     }
   117     }
   105 
   118 
   106     val prefs_entry: Parser[Options => Options] =
   119     val prefs_entry: Parser[Options => Options] =
   107     {
   120     {
   108       option_name ~ ($$$("=") ~! option_value) ^^
   121       option_name ~ ($$$("=") ~! option_value) ^^
   300     public: Boolean,
   313     public: Boolean,
   301     pos: Position.T,
   314     pos: Position.T,
   302     name: String,
   315     name: String,
   303     typ_name: String,
   316     typ_name: String,
   304     value: String,
   317     value: String,
       
   318     standard: Option[Option[String]],
   305     description: String): Options =
   319     description: String): Options =
   306   {
   320   {
   307     options.get(name) match {
   321     options.get(name) match {
   308       case Some(other) =>
   322       case Some(other) =>
   309         error("Duplicate declaration of option " + quote(name) + Position.here(pos) +
   323         error("Duplicate declaration of option " + quote(name) + Position.here(pos) +
   317             case "string" => Options.String
   331             case "string" => Options.String
   318             case _ =>
   332             case _ =>
   319               error("Unknown type for option " + quote(name) + " : " + quote(typ_name) +
   333               error("Unknown type for option " + quote(name) + " : " + quote(typ_name) +
   320                 Position.here(pos))
   334                 Position.here(pos))
   321           }
   335           }
   322         val opt = Options.Opt(public, pos, name, typ, value, value, description, section)
   336         val standard_value =
       
   337           standard match {
       
   338             case None => None
       
   339             case Some(_) if typ == Options.Bool =>
       
   340               error("Illegal standard value for option " + quote(name) + " : " + typ_name +
       
   341                 Position.here)
       
   342             case Some(s) => Some(s.getOrElse(value))
       
   343           }
       
   344         val opt =
       
   345           Options.Opt(public, pos, name, typ, value, value, standard_value, description, section)
   323         (new Options(options + (name -> opt), section)).check_value(name)
   346         (new Options(options + (name -> opt), section)).check_value(name)
   324     }
   347     }
   325   }
   348   }
   326 
   349 
   327   def add_permissive(name: String, value: String): Options =
   350   def add_permissive(name: String, value: String): Options =
   328   {
   351   {
   329     if (options.isDefinedAt(name)) this + (name, value)
   352     if (options.isDefinedAt(name)) this + (name, value)
   330     else {
   353     else {
   331       val opt = Options.Opt(false, Position.none, name, Options.Unknown, value, value, "", "")
   354       val opt = Options.Opt(false, Position.none, name, Options.Unknown, value, value, None, "", "")
   332       new Options(options + (name -> opt), section)
   355       new Options(options + (name -> opt), section)
   333     }
   356     }
   334   }
   357   }
   335 
   358 
   336   def + (name: String, value: String): Options =
   359   def + (name: String, value: String): Options =
   340   }
   363   }
   341 
   364 
   342   def + (name: String, opt_value: Option[String]): Options =
   365   def + (name: String, opt_value: Option[String]): Options =
   343   {
   366   {
   344     val opt = check_name(name)
   367     val opt = check_name(name)
   345     opt_value match {
   368     opt_value orElse opt.standard_value match {
   346       case Some(value) => this + (name, value)
   369       case Some(value) => this + (name, value)
   347       case None if opt.typ == Options.Bool | opt.typ == Options.String => this + (name, "true")
   370       case None if opt.typ == Options.Bool => this + (name, "true")
   348       case None => error("Missing value for option " + quote(name) + " : " + opt.typ.print)
   371       case None => error("Missing value for option " + quote(name) + " : " + opt.typ.print)
   349     }
   372     }
   350   }
   373   }
   351 
   374 
   352   def + (str: String): Options =
   375   def + (str: String): Options =