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