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) ^^ |
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 = |