importing messaging-2008 branch to trunk.
[mono.git] / mcs / tools / mdoc / Mono.Documentation / mdoc.cs
1 // Part of the mdoc(7) suite of tools.
2 using System;
3 using System.Collections.Generic;
4 using System.Diagnostics;
5 using System.Linq;
6 using Mono.Options;
7
8 namespace Mono.Documentation {
9
10         class MDoc {
11
12                 private static bool debug;
13
14                 private static void Main (string[] args)
15                 {
16                         MDoc d = new MDoc ();
17                         try {
18                                 d.Run (args);
19                         }
20                         catch (Exception e) {
21                                 if (debug) {
22                                         Console.Error.WriteLine ("mdoc: {0}", e.ToString ());
23                                 }
24                                 else {
25                                         Console.Error.WriteLine ("mdoc: {0}", e.Message);
26                                 }
27                                 Console.Error.WriteLine ("See `mdoc help' for more information.");
28                         }
29                 }
30
31                 int verbosity = 2;
32
33                 internal Dictionary<string, MDocCommand> subcommands;
34
35                 private void Run (string[] args)
36                 {
37                         subcommands = new Dictionary<string, MDocCommand> () {
38                                 { "assemble",         new MDocAssembler () },
39                                 { "dump-tree",        new MDocTreeDumper () },
40                                 { "export-html",      new MDocToHtmlConverter () },
41                                 { "export-msxdoc",    new MDocToMSXDocConverter () },
42                                 { "help",             new MDocHelpCommand (this) },
43                                 { "update",           new MDocUpdater () },
44                                 { "validate",         new MDocValidator () },
45                         };
46
47                         bool showVersion = false;
48                         bool showHelp    = false;
49                         var p = new OptionSet () {
50                                 { "version",  v => showVersion = v != null },
51                                 { "v:",       (int? v) => verbosity = v.HasValue ? v.Value : verbosity+1 },
52                                 { "debug",    v => debug = v != null },
53                                 { "h|?|help", v => showHelp = v != null },
54                         };
55
56                         List<string> extra = p.Parse (args);
57
58                         if (showVersion) {
59                                 Console.WriteLine ("mdoc 0.1.0");
60                                 return;
61                         }
62                         if (extra.Count == 0) {
63                                 new MDocHelpCommand (this).Run (null);
64                         }
65                         if (showHelp) {
66                                 extra.Add ("--help");
67                         }
68                         GetCommand (extra [0]).Run (extra);
69                 }
70
71                 internal MDocCommand GetCommand (string command)
72                 {
73                         MDocCommand h;
74                         if (!subcommands.TryGetValue (command, out h)) {
75                                 Error ("Unknown command: {0}.", command);
76                         }
77                         h.TraceLevel  = (TraceLevel) verbosity;
78                         h.DebugOutput = debug;
79                         return h;
80                 }
81
82                 private static void Error (string format, params object[] args)
83                 {
84                         throw new Exception (string.Format (format, args));
85                 }
86         }
87
88         public abstract class MDocCommand {
89
90                 public TraceLevel TraceLevel { get; set; }
91                 public bool DebugOutput { get; set; }
92
93                 public abstract void Run (IEnumerable<string> args);
94
95                 protected List<string> Parse (OptionSet p, IEnumerable<string> args, 
96                                 string command, string prototype, string description)
97                 {
98                         bool showHelp = false;
99                         p.Add ("h|?|help", 
100                                         "Show this message and exit.", 
101                                         v => showHelp = v != null );
102
103                         List<string> extra = null;
104                         if (args != null) {
105                                 extra = p.Parse (args.Skip (1));
106                         }
107                         if (args == null || showHelp) {
108                                 Console.WriteLine ("usage: mdoc {0} {1}", 
109                                                 args == null ? command : args.First(), prototype);
110                                 Console.WriteLine ();
111                                 Console.WriteLine (description);
112                                 Console.WriteLine ();
113                                 Console.WriteLine ("Available Options:");
114                                 p.WriteOptionDescriptions (Console.Out);
115                                 return null;
116                         }
117                         return extra;
118                 }
119
120                 public void Error (string format, params object[] args)
121                 {
122                         throw new Exception (string.Format (format, args));
123                 }
124
125                 public void Message (TraceLevel level, string format, params object[] args)
126                 {
127                         if ((int) level > (int) TraceLevel)
128                                 return;
129                         if (level == TraceLevel.Error)
130                                 Console.Error.WriteLine (format, args);
131                         else
132                                 Console.WriteLine (format, args);
133                 }
134         }
135
136         class MDocHelpCommand : MDocCommand {
137
138                 MDoc instance;
139
140                 public MDocHelpCommand (MDoc instance)
141                 {
142                         this.instance = instance;
143                 }
144
145                 public override void Run (IEnumerable<string> args)
146                 {
147                         if (args != null && args.Count() > 1) {
148                                 foreach (var arg in args.Skip (1)) {
149                                         instance.GetCommand (arg).Run (new string[]{arg, "--help"});
150                                 }
151                                 return;
152                         }
153                         Message (TraceLevel.Warning, 
154                                 "usage: mdoc COMMAND [OPTIONS]\n" +
155                                 "Use `mdoc help COMMAND' for help on a specific command.\n" +
156                                 "\n" + 
157                                 "Available commands:\n\n   " +
158                                 string.Join ("\n   ", instance.subcommands.Keys.OrderBy (v => v).ToArray()) +
159                                 "\n\n" + 
160                                 "mdoc is a tool for documentation management.\n" +
161                                 "For additional information, see http://www.mono-project.com/"
162                         );
163                 }
164         }
165 }
166