**** Merged from MCS ****
[mono-project.git] / mcs / tools / monostyle.cs
blobcd72b86fc54a23c22a2ef6b153b6bb5d60bf7fe3
1 // monostyle.cs
2 //
3 // Adam Treat (manyoso@yahoo.com)
4 // Ben Maurer (bmaurer@users.sf.net)
5 // (C) 2002 Adam Treat
6 // (C) 2003 Ben Maurer
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
13 using System;
14 using System.IO;
15 using System.Text.RegularExpressions;
16 using System.Collections.Specialized;
18 namespace Mono.Util {
20 class MonoStyle {
22 string file;
23 StringCollection filebuffer;
24 bool linespace = true;
26 void Usage()
28 Console.Write (
29 "monostyle -f file.cs -l <true|false> > output.cs\n\n" +
30 " -f || /-f || --file file.cs The csharp source file to parse.\n\n" +
31 " -l || /-l || --line <true|false> Specifies wether to use line spacing.\n\n");
34 public static void Main (string[] args)
36 MonoStyle style = new MonoStyle(args);
39 public MonoStyle (string[] args)
41 int argc = args.Length;
42 for(int i = 0; i < argc; i++) {
43 string arg = args[i];
44 // The "/" switch is there for wine users, like me ;-)
45 if(arg.StartsWith("-") || arg.StartsWith("/")) {
46 switch(arg) {
47 case "-l": case "/-l": case "--line":
48 if((i + 1) >= argc) {
49 Usage();
50 return;
52 if (args[i++] == "false") {
53 linespace = false;
55 continue;
56 case "-f": case "/-f": case "--file":
57 if((i + 1) >= argc) {
58 Usage();
59 return;
61 file = args[++i];
62 continue;
63 default:
64 Usage();
65 return;
69 if(file == null) {
70 Usage();
71 return;
73 filebuffer = new StringCollection();
74 StreamReader sr = new StreamReader(file);
75 FillBuffer(sr);
76 FixMonoStyle();
77 PrintToConsole();
80 public void FillBuffer(StreamReader sr)
82 sr.BaseStream.Seek(0, SeekOrigin.Begin);
83 while (sr.Peek() > -1) {
84 filebuffer.Add(sr.ReadLine());
86 sr.Close();
89 public void FixMonoStyle()
91 for (int i=0; i < filebuffer.Count; i++) {
92 IsBadMonoStyle(filebuffer[i]);
96 public void PrintToConsole()
98 for (int i=0; i < filebuffer.Count; i++) {
99 Console.WriteLine(filebuffer[i]);
103 public void IsBadMonoStyle(String str)
105 if (IsBadMonoType(str)) {
106 FixHangingBrace(str);
107 } else if(IsBadMonoFlow(str)) {
108 FixHangingBrace(str);
109 } else if(IsBadMonoFunction(str)) {
110 FixEndBrace(str);
111 } else if(IsBadMonoProperty(str)) {
112 FixHangingBrace(str);
113 } else {
117 public void FixHangingBrace(String str)
119 int strloc = filebuffer.IndexOf(str);
120 int brcloc = FindHangingBrace(strloc);
121 int diff = brcloc - strloc;
122 if (brcloc > 0) {
123 for (int i = 0; i < diff+1; i++) {
124 filebuffer.RemoveAt(strloc);
126 filebuffer.Insert(strloc, str + " {");
127 if (linespace) {
128 filebuffer.Insert(strloc+1, "");
130 } else {}
133 public int FindHangingBrace(int strloc)
135 strloc++;
136 bool found = false;
137 while (!found) {
138 try {
139 string str = filebuffer[strloc++];
140 found = IsHangingBrace(str);
141 if (!found && !IsBlankLine(str)) {
142 return -1;
144 } catch (Exception) {
145 return -1;
148 return strloc -1;
151 public void FixEndBrace(String str)
153 int strloc = filebuffer.IndexOf(str);
154 filebuffer.RemoveAt(strloc);
155 filebuffer.Insert(strloc, RemoveEndBrace(str));
156 filebuffer.Insert(strloc+1, AddHangingBrace(str));
159 public static bool IsBadMonoType(String str)
161 if ( IsType(str) && !EndWithBrace(str)) {
162 return true;
163 } else {
164 return false;
168 public static bool IsBadMonoFlow(String str)
170 if (IsFlow(str) && !EndWithBrace(str)) {
171 return true;
172 } else {
173 return false;
177 public static bool IsBadMonoFunction(String str)
179 if (IsFunction(str) && EndWithBrace(str)) {
180 return true;
181 } else {
182 return false;
186 public static bool IsBadMonoProperty(String str)
188 if (IsProperty(str) && !EndWithBrace(str)) {
189 return true;
190 } else {
191 return false;
195 public static bool IsType(String str)
197 if ( !IsComment(str) && (
198 IsNameSpace(str) ||
199 IsClass(str) ||
200 IsStruct(str) ||
201 IsEnum(str) )) {
202 return true;
203 } else {
204 return false;
208 public static bool IsFlow(String str)
210 if ( !IsComment(str) && (
211 IsIf(str) ||
212 IsElse(str) ||
213 IsElseIf(str) ||
214 IsTry(str) ||
215 IsCatch(str) ||
216 IsFinally(str) ||
217 IsFor(str) ||
218 IsForEach(str) ||
219 IsWhile(str) ||
220 IsSwitch(str)
221 )) {
222 return true;
223 } else {
224 return false;
228 public static bool IsFunction(String str)
230 if ( Regex.IsMatch(str, @"^\s*(\w+)\s+(\w+).*\(+") &&
231 !IsDeclaration(str) &&
232 !IsComment(str) &&
233 !IsType(str) &&
234 !IsFlow(str) ) {
235 return true;
236 } else {
237 return false;
241 public static bool IsProperty(String str)
243 if ( Regex.IsMatch(str, @"^\s*(\w+)\s+(\w+).*") &&
244 !IsDeclaration(str) &&
245 !IsComment(str) &&
246 !IsType(str) &&
247 !IsFlow(str) &&
248 !IsFunction(str) ) {
249 return true;
250 } else {
251 return false;
255 public static string RemoveEndBrace(String str)
257 Regex rg = new Regex(@"\{\s*$");
258 return rg.Replace(str, "");
261 public static string AddHangingBrace(String str)
263 Regex rg = new Regex(@"\S+\s*");
264 string blank = rg.Replace(str,"");
265 return blank + "{";
268 public static bool IsDeclaration(String str)
270 return Regex.IsMatch(str, @"\;\s*$");
273 public static bool IsComment(String str)
275 return Regex.IsMatch(str, @"^(\s*\/+|\s*\*+|\s*\#+)");
278 public static bool EndWithBrace(String str)
280 return Regex.IsMatch(str, @"\{\s*$");
283 public static bool IsHangingBrace(String str)
285 return Regex.IsMatch(str, @"^\s*\{");
288 public static bool IsBlankLine(String str)
290 return Regex.IsMatch(str, @"^\s*$");
293 public static bool IsNameSpace(String str)
295 return Regex.IsMatch(str, @"(^|\s+)namespace\s+");
298 public static bool IsClass(String str)
300 return Regex.IsMatch(str, @"\s+class\s+");
303 public static bool IsStruct(String str)
305 return Regex.IsMatch(str, @"\s+struct\s+");
308 public static bool IsEnum(String str)
310 return Regex.IsMatch(str, @"\s+enum\s+");
313 public static bool IsIf(String str)
315 return Regex.IsMatch(str, @"(^|\s+|\}+)if(\s+|\(+|$)");
318 public static bool IsElse(String str)
320 return Regex.IsMatch(str, @"(^|\s+|\}+)else(\s+|\{+|$)");
323 public static bool IsElseIf(String str)
325 return Regex.IsMatch(str, @"(^|\s+|\}+)else if(\s+|\(+|$)");
328 public static bool IsTry(String str)
330 return Regex.IsMatch(str, @"(^|\s+|\}+)try(\s+|\(+|$)");
333 public static bool IsCatch(String str)
335 return Regex.IsMatch(str, @"(^|\s+|\}+)catch(\s+|\(+|$)");
338 public static bool IsFinally(String str)
340 return Regex.IsMatch(str, @"(^|\s+|\}+)finally(\s+|\{+|$)");
343 public static bool IsFor(String str)
345 return Regex.IsMatch(str, @"(^|\s+|\}+)for(\s+|\(+|$)");
348 public static bool IsForEach(String str)
350 return Regex.IsMatch(str, @"(^|\s+|\}+)foreach(\s+|\(+|$)");
353 public static bool IsWhile(String str)
355 return Regex.IsMatch(str, @"(^|\s+|\}+)while(\s+|\(+|$)");
358 public static bool IsSwitch(String str)
360 return Regex.IsMatch(str, @"(^|\s+|\}+)switch(\s+|\(+|$)");
363 public static bool IsCase(String str)
365 return Regex.IsMatch(str, @"(^|\s+|\}+)case(\s+|\(+|$)");