| author | wenzelm | 
| Sun, 02 Sep 2012 19:26:05 +0200 | |
| changeset 49065 | 8ead9e8b15fb | 
| parent 48992 | 0518bf89c777 | 
| child 49245 | cb70157293c0 | 
| permissions | -rw-r--r-- | 
| 
48365
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
1  | 
/* Title: Pure/System/options.scala  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
2  | 
Author: Makarius  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
3  | 
|
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
4  | 
Stand-alone options with external string representation.  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
5  | 
*/  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
6  | 
|
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
7  | 
package isabelle  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
8  | 
|
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
9  | 
|
| 48807 | 10  | 
import java.util.Calendar  | 
11  | 
||
12  | 
||
| 
48365
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
13  | 
object Options  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
14  | 
{
 | 
| 48421 | 15  | 
type Spec = (String, Option[String])  | 
16  | 
||
17  | 
val empty: Options = new Options()  | 
|
18  | 
||
19  | 
||
20  | 
/* representation */  | 
|
21  | 
||
22  | 
sealed abstract class Type  | 
|
| 
48365
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
23  | 
  {
 | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
24  | 
def print: String = toString.toLowerCase  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
25  | 
}  | 
| 48421 | 26  | 
private case object Bool extends Type  | 
27  | 
private case object Int extends Type  | 
|
28  | 
private case object Real extends Type  | 
|
29  | 
private case object String extends Type  | 
|
| 48860 | 30  | 
private case object Unknown extends Type  | 
| 
48365
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
31  | 
|
| 48370 | 32  | 
case class Opt(typ: Type, value: String, description: String)  | 
| 48860 | 33  | 
  {
 | 
34  | 
def unknown: Boolean = typ == Unknown  | 
|
35  | 
}  | 
|
| 
48365
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
36  | 
|
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
37  | 
|
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
38  | 
/* parsing */  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
39  | 
|
| 
48795
 
bece259ee055
clarified format of etc/options: only declarations, not re-definitions;
 
wenzelm 
parents: 
48718 
diff
changeset
 | 
40  | 
private val OPTION = "option"  | 
| 48807 | 41  | 
  private val OPTIONS = Path.explode("etc/options")
 | 
42  | 
  private val PREFS = Path.explode("$ISABELLE_HOME_USER/etc/preferences")
 | 
|
43  | 
  private val PREFS_BACKUP = Path.explode("$ISABELLE_HOME_USER/etc/preferences~")
 | 
|
| 
48713
 
de26cf3191a3
more token markers, based on actual outer syntax;
 
wenzelm 
parents: 
48693 
diff
changeset
 | 
44  | 
|
| 48807 | 45  | 
lazy val options_syntax = Outer_Syntax.init() + ":" + "=" + "--" + (OPTION, Keyword.THY_DECL)  | 
46  | 
lazy val prefs_syntax = Outer_Syntax.init() + "="  | 
|
| 
48713
 
de26cf3191a3
more token markers, based on actual outer syntax;
 
wenzelm 
parents: 
48693 
diff
changeset
 | 
47  | 
|
| 48807 | 48  | 
object Parser extends Parse.Parser  | 
| 
48365
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
49  | 
  {
 | 
| 48807 | 50  | 
    val option_name = atom("option name", _.is_xname)
 | 
51  | 
    val option_type = atom("option type", _.is_ident)
 | 
|
52  | 
val option_value =  | 
|
53  | 
      opt(token("-", tok => tok.is_sym_ident && tok.content == "-")) ~ atom("nat", _.is_nat) ^^
 | 
|
54  | 
        { case s ~ n => if (s.isDefined) "-" + n else n } |
 | 
|
55  | 
      atom("option value", tok => tok.is_name || tok.is_float)
 | 
|
56  | 
||
57  | 
val option_entry: Parser[Options => Options] =  | 
|
| 
48365
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
58  | 
    {
 | 
| 
48795
 
bece259ee055
clarified format of etc/options: only declarations, not re-definitions;
 
wenzelm 
parents: 
48718 
diff
changeset
 | 
59  | 
      command(OPTION) ~! (option_name ~ keyword(":") ~ option_type ~
 | 
| 48580 | 60  | 
      keyword("=") ~ option_value ~ (keyword("--") ~! text ^^ { case _ ~ x => x } | success(""))) ^^
 | 
| 
48795
 
bece259ee055
clarified format of etc/options: only declarations, not re-definitions;
 
wenzelm 
parents: 
48718 
diff
changeset
 | 
61  | 
        { case _ ~ (a ~ _ ~ b ~ _ ~ c ~ d) => (options: Options) => options.declare(a, b, c, d) }
 | 
| 
48365
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
62  | 
}  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
63  | 
|
| 48807 | 64  | 
val prefs_entry: Parser[Options => Options] =  | 
65  | 
    {
 | 
|
66  | 
      option_name ~ (keyword("=") ~! option_value) ^^
 | 
|
| 48860 | 67  | 
      { case a ~ (_ ~ b) => (options: Options) => options.add_permissive(a, b) }
 | 
| 48807 | 68  | 
}  | 
69  | 
||
70  | 
def parse_file(syntax: Outer_Syntax, parser: Parser[Options => Options],  | 
|
71  | 
options: Options, file: Path): Options =  | 
|
| 
48365
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
72  | 
    {
 | 
| 48807 | 73  | 
val toks = syntax.scan(File.read(file))  | 
74  | 
val ops =  | 
|
75  | 
        parse_all(rep(parser), Token.reader(toks, file.implode)) match {
 | 
|
76  | 
case Success(result, _) => result  | 
|
77  | 
case bad => error(bad.toString)  | 
|
78  | 
}  | 
|
79  | 
      try { (options /: ops) { case (opts, op) => op(opts) } }
 | 
|
| 48992 | 80  | 
      catch { case ERROR(msg) => error(msg + Position.here(file.position)) }
 | 
| 
48365
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
81  | 
}  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
82  | 
}  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
83  | 
|
| 48807 | 84  | 
def init_defaults(): Options =  | 
| 
48365
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
85  | 
  {
 | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
86  | 
var options = empty  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
87  | 
    for {
 | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
88  | 
dir <- Isabelle_System.components()  | 
| 48548 | 89  | 
file = dir + OPTIONS if file.is_file  | 
| 48807 | 90  | 
    } { options = Parser.parse_file(options_syntax, Parser.option_entry, options, file) }
 | 
| 
48365
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
91  | 
options  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
92  | 
}  | 
| 48457 | 93  | 
|
| 48807 | 94  | 
def init(): Options = init_defaults().load_prefs()  | 
95  | 
||
| 48457 | 96  | 
|
97  | 
/* encode */  | 
|
98  | 
||
99  | 
val encode: XML.Encode.T[Options] = (options => options.encode)  | 
|
| 
48693
 
ceeea46bdeba
"isabelle options" prints Isabelle system options;
 
wenzelm 
parents: 
48605 
diff
changeset
 | 
100  | 
|
| 
 
ceeea46bdeba
"isabelle options" prints Isabelle system options;
 
wenzelm 
parents: 
48605 
diff
changeset
 | 
101  | 
|
| 
 
ceeea46bdeba
"isabelle options" prints Isabelle system options;
 
wenzelm 
parents: 
48605 
diff
changeset
 | 
102  | 
/* command line entry point */  | 
| 
 
ceeea46bdeba
"isabelle options" prints Isabelle system options;
 
wenzelm 
parents: 
48605 
diff
changeset
 | 
103  | 
|
| 
 
ceeea46bdeba
"isabelle options" prints Isabelle system options;
 
wenzelm 
parents: 
48605 
diff
changeset
 | 
104  | 
def main(args: Array[String])  | 
| 
 
ceeea46bdeba
"isabelle options" prints Isabelle system options;
 
wenzelm 
parents: 
48605 
diff
changeset
 | 
105  | 
  {
 | 
| 
 
ceeea46bdeba
"isabelle options" prints Isabelle system options;
 
wenzelm 
parents: 
48605 
diff
changeset
 | 
106  | 
    Command_Line.tool {
 | 
| 
 
ceeea46bdeba
"isabelle options" prints Isabelle system options;
 
wenzelm 
parents: 
48605 
diff
changeset
 | 
107  | 
      args.toList match {
 | 
| 
 
ceeea46bdeba
"isabelle options" prints Isabelle system options;
 
wenzelm 
parents: 
48605 
diff
changeset
 | 
108  | 
case export_file :: more_options =>  | 
| 48807 | 109  | 
val options = (Options.init() /: more_options)(_ + _)  | 
| 
48693
 
ceeea46bdeba
"isabelle options" prints Isabelle system options;
 
wenzelm 
parents: 
48605 
diff
changeset
 | 
110  | 
|
| 
 
ceeea46bdeba
"isabelle options" prints Isabelle system options;
 
wenzelm 
parents: 
48605 
diff
changeset
 | 
111  | 
if (export_file == "") java.lang.System.out.println(options.print)  | 
| 
 
ceeea46bdeba
"isabelle options" prints Isabelle system options;
 
wenzelm 
parents: 
48605 
diff
changeset
 | 
112  | 
else File.write(Path.explode(export_file), YXML.string_of_body(options.encode))  | 
| 
 
ceeea46bdeba
"isabelle options" prints Isabelle system options;
 
wenzelm 
parents: 
48605 
diff
changeset
 | 
113  | 
|
| 
 
ceeea46bdeba
"isabelle options" prints Isabelle system options;
 
wenzelm 
parents: 
48605 
diff
changeset
 | 
114  | 
0  | 
| 
 
ceeea46bdeba
"isabelle options" prints Isabelle system options;
 
wenzelm 
parents: 
48605 
diff
changeset
 | 
115  | 
        case _ => error("Bad arguments:\n" + cat_lines(args))
 | 
| 
 
ceeea46bdeba
"isabelle options" prints Isabelle system options;
 
wenzelm 
parents: 
48605 
diff
changeset
 | 
116  | 
}  | 
| 
 
ceeea46bdeba
"isabelle options" prints Isabelle system options;
 
wenzelm 
parents: 
48605 
diff
changeset
 | 
117  | 
}  | 
| 
 
ceeea46bdeba
"isabelle options" prints Isabelle system options;
 
wenzelm 
parents: 
48605 
diff
changeset
 | 
118  | 
}  | 
| 
48365
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
119  | 
}  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
120  | 
|
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
121  | 
|
| 48807 | 122  | 
final class Options private(protected val options: Map[String, Options.Opt] = Map.empty)  | 
| 
48365
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
123  | 
{
 | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
124  | 
  override def toString: String = options.iterator.mkString("Options (", ",", ")")
 | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
125  | 
|
| 
48693
 
ceeea46bdeba
"isabelle options" prints Isabelle system options;
 
wenzelm 
parents: 
48605 
diff
changeset
 | 
126  | 
def print: String =  | 
| 
 
ceeea46bdeba
"isabelle options" prints Isabelle system options;
 
wenzelm 
parents: 
48605 
diff
changeset
 | 
127  | 
    cat_lines(options.toList.sortBy(_._1).map({ case (name, opt) =>
 | 
| 
48795
 
bece259ee055
clarified format of etc/options: only declarations, not re-definitions;
 
wenzelm 
parents: 
48718 
diff
changeset
 | 
128  | 
"option " + name + " : " + opt.typ.print + " = " +  | 
| 
48693
 
ceeea46bdeba
"isabelle options" prints Isabelle system options;
 
wenzelm 
parents: 
48605 
diff
changeset
 | 
129  | 
(if (opt.typ == Options.String) quote(opt.value) else opt.value) +  | 
| 48860 | 130  | 
(if (opt.description == "") "" else "\n -- " + quote(opt.description)) }))  | 
| 
48693
 
ceeea46bdeba
"isabelle options" prints Isabelle system options;
 
wenzelm 
parents: 
48605 
diff
changeset
 | 
131  | 
|
| 
48365
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
132  | 
|
| 48370 | 133  | 
/* check */  | 
| 
48365
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
134  | 
|
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
135  | 
private def check_name(name: String): Options.Opt =  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
136  | 
    options.get(name) match {
 | 
| 48860 | 137  | 
case Some(opt) if !opt.unknown => opt  | 
138  | 
      case _ => error("Unknown option " + quote(name))
 | 
|
| 
48365
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
139  | 
}  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
140  | 
|
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
141  | 
private def check_type(name: String, typ: Options.Type): Options.Opt =  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
142  | 
  {
 | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
143  | 
val opt = check_name(name)  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
144  | 
if (opt.typ == typ) opt  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
145  | 
    else error("Ill-typed option " + quote(name) + " : " + opt.typ.print + " vs. " + typ.print)
 | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
146  | 
}  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
147  | 
|
| 48370 | 148  | 
|
149  | 
/* basic operations */  | 
|
150  | 
||
151  | 
private def put[A](name: String, typ: Options.Type, value: String): Options =  | 
|
152  | 
  {
 | 
|
153  | 
val opt = check_type(name, typ)  | 
|
154  | 
new Options(options + (name -> opt.copy(value = value)))  | 
|
155  | 
}  | 
|
156  | 
||
| 
48365
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
157  | 
private def get[A](name: String, typ: Options.Type, parse: String => Option[A]): A =  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
158  | 
  {
 | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
159  | 
val opt = check_type(name, typ)  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
160  | 
    parse(opt.value) match {
 | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
161  | 
case Some(x) => x  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
162  | 
case None =>  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
163  | 
        error("Malformed value for option " + quote(name) +
 | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
164  | 
" : " + typ.print + " =\n" + quote(opt.value))  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
165  | 
}  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
166  | 
}  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
167  | 
|
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
168  | 
|
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
169  | 
/* internal lookup and update */  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
170  | 
|
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
171  | 
val bool = new Object  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
172  | 
  {
 | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
173  | 
def apply(name: String): Boolean = get(name, Options.Bool, Properties.Value.Boolean.unapply)  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
174  | 
def update(name: String, x: Boolean): Options =  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
175  | 
put(name, Options.Bool, Properties.Value.Boolean(x))  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
176  | 
}  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
177  | 
|
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
178  | 
val int = new Object  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
179  | 
  {
 | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
180  | 
def apply(name: String): Int = get(name, Options.Int, Properties.Value.Int.unapply)  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
181  | 
def update(name: String, x: Int): Options =  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
182  | 
put(name, Options.Int, Properties.Value.Int(x))  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
183  | 
}  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
184  | 
|
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
185  | 
val real = new Object  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
186  | 
  {
 | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
187  | 
def apply(name: String): Double = get(name, Options.Real, Properties.Value.Double.unapply)  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
188  | 
def update(name: String, x: Double): Options =  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
189  | 
put(name, Options.Real, Properties.Value.Double(x))  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
190  | 
}  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
191  | 
|
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
192  | 
val string = new Object  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
193  | 
  {
 | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
194  | 
def apply(name: String): String = get(name, Options.String, s => Some(s))  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
195  | 
def update(name: String, x: String): Options = put(name, Options.String, x)  | 
| 
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
196  | 
}  | 
| 48370 | 197  | 
|
198  | 
||
| 48807 | 199  | 
/* external updates */  | 
| 48370 | 200  | 
|
201  | 
private def check_value(name: String): Options =  | 
|
202  | 
  {
 | 
|
203  | 
val opt = check_name(name)  | 
|
204  | 
    opt.typ match {
 | 
|
205  | 
case Options.Bool => bool(name); this  | 
|
206  | 
case Options.Int => int(name); this  | 
|
207  | 
case Options.Real => real(name); this  | 
|
208  | 
case Options.String => string(name); this  | 
|
| 48860 | 209  | 
case Options.Unknown => this  | 
| 48370 | 210  | 
}  | 
211  | 
}  | 
|
212  | 
||
213  | 
def declare(name: String, typ_name: String, value: String, description: String = ""): Options =  | 
|
214  | 
  {
 | 
|
215  | 
    options.get(name) match {
 | 
|
216  | 
      case Some(_) => error("Duplicate declaration of option " + quote(name))
 | 
|
217  | 
case None =>  | 
|
218  | 
val typ =  | 
|
219  | 
          typ_name match {
 | 
|
220  | 
case "bool" => Options.Bool  | 
|
221  | 
case "int" => Options.Int  | 
|
222  | 
case "real" => Options.Real  | 
|
223  | 
case "string" => Options.String  | 
|
| 
48456
 
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
 
wenzelm 
parents: 
48421 
diff
changeset
 | 
224  | 
            case _ => error("Unknown type for option " + quote(name) + " : " + quote(typ_name))
 | 
| 48370 | 225  | 
}  | 
| 48807 | 226  | 
val opt = Options.Opt(typ, value, description)  | 
227  | 
(new Options(options + (name -> opt))).check_value(name)  | 
|
| 48370 | 228  | 
}  | 
229  | 
}  | 
|
230  | 
||
| 48860 | 231  | 
def add_permissive(name: String, value: String): Options =  | 
232  | 
  {
 | 
|
233  | 
if (options.isDefinedAt(name)) this + (name, value)  | 
|
234  | 
else new Options(options + (name -> Options.Opt(Options.Unknown, value, "")))  | 
|
235  | 
}  | 
|
236  | 
||
| 48807 | 237  | 
def + (name: String, value: String): Options =  | 
| 48370 | 238  | 
  {
 | 
239  | 
val opt = check_name(name)  | 
|
240  | 
(new Options(options + (name -> opt.copy(value = value)))).check_value(name)  | 
|
241  | 
}  | 
|
242  | 
||
| 48807 | 243  | 
def + (name: String, opt_value: Option[String]): Options =  | 
| 48370 | 244  | 
  {
 | 
245  | 
val opt = check_name(name)  | 
|
246  | 
    opt_value match {
 | 
|
| 48807 | 247  | 
case Some(value) => this + (name, value)  | 
248  | 
case None if opt.typ == Options.Bool => this + (name, "true")  | 
|
| 48370 | 249  | 
      case None => error("Missing value for option " + quote(name) + " : " + opt.typ.print)
 | 
250  | 
}  | 
|
251  | 
}  | 
|
252  | 
||
| 48807 | 253  | 
def + (str: String): Options =  | 
| 48370 | 254  | 
  {
 | 
255  | 
    str.indexOf('=') match {
 | 
|
| 48807 | 256  | 
case -1 => this + (str, None)  | 
257  | 
case i => this + (str.substring(0, i), str.substring(i + 1))  | 
|
| 48370 | 258  | 
}  | 
259  | 
}  | 
|
| 
48456
 
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
 
wenzelm 
parents: 
48421 
diff
changeset
 | 
260  | 
|
| 48807 | 261  | 
def ++ (specs: List[Options.Spec]): Options =  | 
262  | 
    (this /: specs)({ case (x, (y, z)) => x + (y, z) })
 | 
|
263  | 
||
| 
48456
 
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
 
wenzelm 
parents: 
48421 
diff
changeset
 | 
264  | 
|
| 
 
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
 
wenzelm 
parents: 
48421 
diff
changeset
 | 
265  | 
/* encode */  | 
| 
 
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
 
wenzelm 
parents: 
48421 
diff
changeset
 | 
266  | 
|
| 
 
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
 
wenzelm 
parents: 
48421 
diff
changeset
 | 
267  | 
def encode: XML.Body =  | 
| 
 
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
 
wenzelm 
parents: 
48421 
diff
changeset
 | 
268  | 
  {
 | 
| 48860 | 269  | 
val opts =  | 
270  | 
for ((name, opt) <- options.toList; if !opt.unknown)  | 
|
271  | 
yield (name, opt.typ.print, opt.value)  | 
|
272  | 
||
| 
48456
 
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
 
wenzelm 
parents: 
48421 
diff
changeset
 | 
273  | 
    import XML.Encode.{string => str, _}
 | 
| 48860 | 274  | 
list(triple(str, str, str))(opts)  | 
| 
48456
 
d8ff14f44a40
added ML version of stand-alone options, with XML.encode/decode operations (unidirectional from Scala to ML);
 
wenzelm 
parents: 
48421 
diff
changeset
 | 
275  | 
}  | 
| 48807 | 276  | 
|
277  | 
||
278  | 
/* user preferences */  | 
|
279  | 
||
280  | 
def load_prefs(): Options =  | 
|
281  | 
if (Options.PREFS.is_file)  | 
|
282  | 
Options.Parser.parse_file(  | 
|
283  | 
Options.prefs_syntax, Options.Parser.prefs_entry, this, Options.PREFS)  | 
|
284  | 
else this  | 
|
285  | 
||
286  | 
def save_prefs()  | 
|
287  | 
  {
 | 
|
| 48860 | 288  | 
val defaults = Options.init_defaults()  | 
| 48807 | 289  | 
val changed =  | 
290  | 
      (for {
 | 
|
| 48860 | 291  | 
(name, opt2) <- options.iterator  | 
292  | 
opt1 = defaults.options.get(name)  | 
|
293  | 
if (opt1.isEmpty || opt1.get.value != opt2.value)  | 
|
294  | 
} yield (name, opt2.value, if (opt1.isEmpty) " (* unknown *)" else "")).toList  | 
|
295  | 
||
| 48807 | 296  | 
val prefs =  | 
297  | 
changed.sortBy(_._1)  | 
|
| 48860 | 298  | 
        .map({ case (x, y, z) => x + " = " + Outer_Syntax.quote_string(y) + z + "\n" }).mkString
 | 
| 48807 | 299  | 
|
300  | 
Options.PREFS.file renameTo Options.PREFS_BACKUP.file  | 
|
301  | 
File.write(Options.PREFS,  | 
|
302  | 
"(* generated by Isabelle " + Calendar.getInstance.getTime + " *)\n\n" + prefs)  | 
|
303  | 
}  | 
|
| 
48365
 
d88aefda01c4
basic support for stand-alone options with external string representation;
 
wenzelm 
parents:  
diff
changeset
 | 
304  | 
}  |