🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Holy Tool Batman!

Published August 08, 2006
Advertisement
I know this probably isn't very impressive, but I have some source to a little utility I'd like to share. I've been itching a little bit for a nice automated way to do line counts for an entire VS solution. Sure, line counts are silly, and it's hard to determine what's an actual line of code (as opposed to line of comment or whitespace)... but I don't care about that. I'm just looking for something to do that I can do and get done. If it helps me better half-assedly judge my progress, great. ~90 minutes later and it's done-ish.

Anyway, here you are. Specify a VS2005 solution file as the argument via CLI.
using System;using System.Collections.Generic;using System.Text;using System.IO;using System.Xml;class Program {    static string Usage = "Usage:    LineCountTool <-v|-verbose> SolutionFile.sln";    static bool Verbose = false;    static IEnumerable<string> ProjectPaths(string SolutionPath) {        if (!File.Exists(SolutionPath)) { Console.WriteLine("File not found: \"{0}\"", SolutionPath); return (new string[0]); }        string[] Lines = File.ReadAllLines(SolutionPath);        string DirPath = Path.GetDirectoryName(SolutionPath);        if (Lines.GetLength(0) <= 1) { Console.WriteLine("File empty: \"{0}\"", SolutionPath); return (new string[0]); }        if (Lines[1] != "Microsoft Visual Studio Solution File, Format Version 9.00") { Console.WriteLine("File does not appear to be Solution file (v 9.0)."); return (new string[0]); }        string buf = "";        List<string> rtn = new List<string>();        foreach (string Line in Lines) {            if (Line.StartsWith("Project")) {                buf = Line;                buf = buf.Remove(0, buf.IndexOf(',') + 1);                buf = buf.Remove(buf.IndexOf(','));                buf = buf.Replace("\"", "");                buf = buf.Trim();                buf = DirPath + Path.DirectorySeparatorChar + buf;                rtn.Add(buf);                if (Verbose) {                    Console.WriteLine("Project: {0}", buf);                }            }        }        return (rtn);    }    static IEnumerable<string> CodePaths(string ProjectPath) {        if (!File.Exists(ProjectPath)) { Console.WriteLine("File not found: \"{0}\"", ProjectPath); return (new string[0]); }        XmlDocument csproj = new XmlDocument();        csproj.Load(ProjectPath);        string DirName = Path.GetDirectoryName(ProjectPath);        List<string> rtn = new List<string>();        if (Verbose) {            Console.WriteLine();            Console.WriteLine("Files From {0}:", ProjectPath);        }        foreach (XmlNode node in csproj.GetElementsByTagName("Compile")) {            foreach (XmlAttribute attrib in node.Attributes) {                if (attrib.Name == "Include") {                    rtn.Add(DirName + Path.DirectorySeparatorChar + attrib.Value);                    if (Verbose) {                        Console.WriteLine(rtn[rtn.Count - 1]);                    }                }            }        }        if (Verbose) {            Console.WriteLine();        }        return (rtn);    }    static UInt64 LinesOfCode(string CodeFile) {        if (!File.Exists(CodeFile)) { Console.WriteLine("File not found: \"{0}\"", CodeFile); return (0); }        UInt64 rtn = (UInt64)File.ReadAllLines(CodeFile).GetLength(0);        if (Verbose) {            Console.WriteLine("Processing {0} ...   {1} lines.", CodeFile, rtn);        }        return (rtn);    }    static void Main(string[] args) {        UInt64 loc = 0;        //Verbose = true;        //string file = @"C:\src\Csharp-Barrier\Csharp-Barrier.sln";        #region Arg Parsing        string file = "";        if (args.GetLength(0) == 0) {            Console.WriteLine(Usage);            return;        }        foreach (string arg in args) {            if (arg == "-v" || arg == "-verbose") {                Verbose = true;            }            file = args[args.GetLength(0) - 1];        }                #endregion        foreach (string project in ProjectPaths(file)) {            foreach (string code in CodePaths(project)) {                loc += LinesOfCode(code);            }        }        if (Verbose) {            Console.WriteLine();        }        Console.WriteLine("Solution {0} ...   {1} lines.", file, loc);    }}


and sample verbose output for the current incarnation of moe:
// *snip*Processing c:\src\Csharp-moeClient2\..\Csharp-BaseSound\Csharp-BaseSound\BaseSound.cs ...   410 lines.Processing c:\src\Csharp-moeClient2\..\Csharp-BaseSound\Csharp-BaseSound\Properties\AssemblyInfo.cs ...   35 lines.Files From c:\src\Csharp-moeClient2\..\Csharp-SoundSceneObject\Csharp-SoundSceneObject\Csharp-SoundSceneObject.csproj:c:\src\Csharp-moeClient2\..\Csharp-SoundSceneObject\Csharp-SoundSceneObject\SoundSceneObject.csc:\src\Csharp-moeClient2\..\Csharp-SoundSceneObject\Csharp-SoundSceneObject\Properties\AssemblyInfo.csProcessing c:\src\Csharp-moeClient2\..\Csharp-SoundSceneObject\Csharp-SoundSceneObject\SoundSceneObject.cs ...   75 lines.Processing c:\src\Csharp-moeClient2\..\Csharp-SoundSceneObject\Csharp-SoundSceneObject\Properties\AssemblyInfo.cs ...   35 lines.Solution c:\src\Csharp-moeClient2\Csharp-moeClient2.sln ...   17501 lines.


(17500 lines? and ~5000 of those are fmod and a good percentage of the rest are comments/includes/whitespace? Pitiful!)

[edit: oh, and it's my first time ever dealing with xml, so you'll forgive me if there's a quicker/cleaner way to pickout the Compile Include="" bits...]
Previous Entry Ugh.
Next Entry Le Font.
0 likes 0 comments

Comments

Nobody has left a comment. You can be the first!
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement