Category Archives: Tools and Utilities

Programming tools and various software utilities.

Random Character Name Generator

I wrote a random character name generator in Python today. It’s HERE at Xangis.com.

The system used is:
1. Roll a d6. 1-3 = consonant (1d20). 4-5 = vowel (1d6 with ‘y’ counting as a vowel), 6 = end name.
2. Names must be at least 3 characters long, ignore a roll of 6 if the name is too short.
3. If you get three consonants in a row, end the name.

I used to use that method to generate horrible character names for AD&D a decade and a half ago.

Visual Studio Refactoring And Encapsulation

I love the refactoring support in MS Visual Studio.  It makes certain things like field encapsulation incredibly easy.

For instance, thanks to its origins in C, most of the Basternae 3 codebase doesn’t have encapsulation yet.  This means that there are tons of class member variables declared like this:

public string _keyword;

Setting the _keyword member variable to private and creating a property named Keyword with getters and setters that reference the _keyword variable would take about 30 seconds.

With Visual Studio it’s easier:  Just right-click on the variable and select “Encapsulate Field”.  It will come up with a reasonable property name and automatically generate the code and set the variable to private.

Pretty nice, but nothing to write home about.

But, here’s the magic:

All references to that variable in code are AUTOMATICALLY changed to refer to the property.  If that member variable was used in 50 different places, Visual Studio just saved you the trouble of making 50 different changes or doing a search-and-replace that may or may not get everything on the first try.

Of course, this doesn’t automatically update any XML files that have been saved using the old variable name.  To take care of that you can do one of two things.

1. Do a search and replace in every XML file that your class would have been serialized to and hope you didn’t miss one.
2. Use the XmlElementAttribute on your property to map the saved attributes to your new type:
[XmlElement(“_keyword”)]
public string Keyword
{

#2 is obviously safer and easier, especially since it doesn’t require changes to existing data.  Of course, your data files might be clearer to read if they used the exact property names, but do you want to go through the trouble?  Likely not.

Resharper 4.0

Last year I tried the Resharper 3 plugin for Visual Studio, and posted my thoughts on it:

http://basternae.org/blog/2007/07/26/jetbrains-resharper/

It was OK, but not all that special. It had potential, but wasn’t quite “there” yet.

I just finished trying out Resharper 4.0 and you could paste the Resharper 3.0 review in its place. It’s neat, but not so neat that it’s a ‘must have’ utility. The features added in the latest version really aren’t anything I find useful — I don’t refactor Visual Basic, don’t use LINQ, etc.

It does, however, appear to run a little faster than version 3.  That might just be the system I’m using it with, but the slowness is no longer an annoyance.

I’ll keep my eye on it. Maybe they’ll add something I can’t live without in a later version.

Taking The Visual Studio 2008 Plunge

Since VS2008 somewhat rudely decided that it would become the default application for all projects, including projects that were VS2005 projects (what exactly *is* the Visual Studio Version Selector good for, anyway?), I decided to try building Basternae with 2008.

It was actually a pretty painless process.

Something changes in every version of a compiler and 99% of the time something breaks, either due to deprecation, changes in the way warnings and errors are treated, or most often due to changes in dependencies and the way they are handled. In any project of significantly large size, you can expect errors when converting to a new version of Visual Studio.

It was no surprise when the project didn’t build. It was, however, a pleasant surprise. It found three bad cast operations that shouldn’t have been written in the first place, the sort of thing that VS2005 should have complained about but didn’t. After spending a few seconds fixing those, everything built fine with no problems.

Visual C++ projects are a different story. You see, I’m convinced that Microsoft hates Visual C++ and just wants it to shrivel up and die. As long as Visual Basic and Visual C# projects are healthy, it’s safe to release a new version of Visual Studio. This time it was a bit of DLL hell along the lines of missing MSVCP90D.DLL and MSVCP90.DLL errors when trying to run a newly-built executable. WTF? Weren’t those installed with Visual Studio? You mean we can build C++ projects but aren’t allowed to run them?

OK, OK, so maybe it was a missing runtime redistributable. That’s fair enough and something I could live with since that’s the way .NET works. So I download the Microsoft Visual C++ 2008 Redistributable and install it. Fail. Epic fail.

After an unsuccessful Google search (plenty of people with the problem but no clear solution) I went playing with some of the project settings. The final fix was setting “Generate Manifest” to “Yes” instead of “No” in the Linker->Manifest File section.

Free Copy of Vista Ultimate and Visual Studio 2008

Today was the Microsoft “launch event” for Visual Studio and Server 2008. I attended the local presentation and walked away with a free copy of Vista Ultimate and Visual Studio 2008. It was free to attend and I got $600 worth of software out of the deal. How can you beat that? Sure the presentations weren’t very relevant to the types of development I do (all they talked about were database-driven development, MS Office add-in development, and ASP.NET web development, all of which I don’t have any involvement in.)

I may or may not switch development of Basternae 3 to VS2008 right away and probably won’t start using Vista until my next PC upgrade, but it still feels nice to get free stuff.

Current Line Counts

Lately it’s just been a bit more work on the editor (which is now at version 0.25). Here’s an updated line count:

Main Codebase:
99,360 lines total
77,693 lines of code (78%)
8,417 lines of comments (8%)
1,258 mixed (code + comment) lines (1%)
11,987 blank lines (12%)

Editor:
9,597 lines total
7,491 lines of code (78%)
1,654 lines of comments (17%)
9 mixed (code + comment) lines (0%)
443 blank lines (4%)

MUD Screen Editor:
1,147 Lines Total
887 Lines of code (77%)
184 lines of comments (16%)
0 mixed (code + comment) lines (0%)
76 blank lines (6%)

Help Editor:
696 Lines Total
512 Lines of code (73%)
142 lines of comments (20%)
0 mixed (code + comment) lines (0%)
42 blank lines (6%)

Client:
5,312 Lines Total
3,940 Lines of code (74%)
781 lines of comments (14%)
29 mixed (code + comment) lines (0%)
562 blank lines (10%)

Since we last checked in, the editor has added about 1100 lines of code, the engine has added about 450, and the help editor and client are new to the list. It’s not that the client is new, this is just the first time we’ve counted it.

This really is a fairly large project.

HTML Help Workshop = Epic Fail.

Anyone who has wondered why the help systems in Windows applications are typically so abysmal has to look no further than Microsoft’s HTML Help Workshop. Not only is rotting tripe more pleasant to deal with, it’s more likely to help you get the job done.

You’d think that maybe an application designed for editing help files would have a decent help system. Not so.

After trying to figure out the interface to HTML Help Workshop and failing (after getting screens full of incomprehensible errors) I went in search of an application with a less counterintuitive interface. I found HelpNDoc. It looks a lot prettier, but it’s also completely incomprehensible. It might not be all that bad, but after my HHW-induced brain meltdown I just didn’t have the patience to decrypt the interface.

I guess if you were meant to be able to get useful information out of the help files for an application they would have made it easy. Failures like Microsoft HHW are why the software training industry is a massive cash cow.

I ended up falling back on the manual method — creating the index, table of contents, and individual topic files by hand. This is the same method I used when creating the help files for PixelSwapper. To put it in perspective, having to do so is just as retarded as writing a letter to your congresscritter using a hex editor because your word processing program is too terrible to use.

Luckily the file formats are well-documented. Not so much by Microsoft, but by the folks who made the Win32 API usable — wxWidgets. I’ve used wxWidgets extensively, and if you’re going to write an app for Windows without using .NET it’s the only sane way to go. Down the path of pure Win32 lies madness. Yes, the Windows API was designed by Cthulhu. Luckily he has since moved on to the world of embedded design and development (cellphones mostly), so post-Win32 Windows programming is no longer painful.

A Day Of Bugfixes

I spent today working through a handful of bugs in the new communication code in the MUD engine and fixing a few problems in the Basternae version 2-to-3 zone converter.  Some of the text formatting still needs some work, but things are a *LOT* better now than they were before, especially with the network portions running smoothly and reliably now.

Now would probably be a fine time for a line count on the project:

Main Codebase:
98,868 lines total
77,254 lines of code (78%)
8,375 lines of comments (8%)
1,261 mixed (code + comment) lines (1%)
11,978 blank lines (12%)

Editor:
8,191 lines total
6,350 lines of code (77%)
1,446 lines of comments (17%)
8 mixed (code + comment) lines (0%)
387 blank lines (4%)

MUD Screen Editor:
1,137 Lines Total
876 Lines of code (77%)
185 lines of comments (16%)
0 mixed (code + comment) lines (0%)
76 blank lines (6%)

Since we last checked in, the editor has just shy of doubled its lines of code while the core codebase has shrunk a little thanks to a bit of recent code cleanup.

Project Line Counter Revisited

When I decided to switch development efforts to C# I assumed that Project Line Counter didn’t support counting non-C++ code. It turns out I was wrong, so here’s an update on the codebase line counts:

Main Codebase:
99,482 lines total
77,947 lines of code (78%)
8,252 lines of comments (8%)
1,285 mixed (code + comment) lines (1%)
11,976 blank lines (12%)

Editor:
4,402 lines total
3,281 lines of code (74%)
927 lines of comments (21%)
1 mixed (code + comment) lines (0%)
193 blank lines (4%)

If you saw my line count post from last May, you’ll notice that there are about 16,000 fewer lines of code.  It’s not because features have been been removed from the MUD engine.  Just about all of the reduction in code is from converting the save/load code to .NET XML serialization.  Letting go of the old, buggy, hacked-together text file formats has done wonders for reducing code-spam.

Visual SourceSafe 2005 Is The Worst Application Ever

First off, don’t think I’m using VSS2005 for Basternae because I’m not – I’m using Subversion. However, I am using it at work. If I had a choice what source control application we used I’d be using Subversion there too.Over the years there have been many deeply flawed software applications. Luckily market Darwinism has weeded out most of the unbearably bad programs. If nobody wants to use an application, it fails to sell and ends up perishing.

The problem is that Visual SourceSafe 2005 seems to be immune to this force. That might be primarily due to the fact that each release has about fifteen minutes worth of code updates added to the previous release.

Here are some of the problems with VSS:

1. Unbearably slow. I’m on a gigabit network and have a very fast server and it still takes ten minutes to check for code updates.
2. The interface is completely counterintuitive. It’s as if the design team studied up on good design principles, high-quality user interfaces, and even performed user testing studies just so they could do the exact opposite of what would make using their software a pleasant experience.
3. Don’t try to fork or branch your code. You’ll never understand it and you’ll completely screw it up, no matter how many times you have done it before.
4. When your code differs from that on the server, you get a dialog box asking you whether you’d like to keep your changes or replace them with the code in the repository. Nevermind that they managed to word the dialog in such a way that it’s hard to tell what you’re actually doing — the “Apply to all items” checkbox does absolutely nothing.
5. VSS is far too opaque. Unlike Subversion, which tells you exactly what it’s going to do before it does it so you can make changes or cancel, SourceSafe will just do whatever it wants, whenever it wants, without your permission. It’s incredibly easy to screw up a directory structure, check out things you had no intention of checking out, or perform all sorts of spooky voodoo that you never even gave the app permission to do.
6. It’s so terrible even Microsoft won’t use it.
7. It doesn’t encourage you to leave comments when you check in code. In fact, the comment window is disabled by default in Visual Studio 2005.
8. It’s hard to figure out who broke something when you want to revert, mainly via a combination of #7 and #2.
9. It slows down Visual Studio and sometimes even causes it to crash. VS.NET is already a resource hog, so adding an unstable plugin isn’t the best idea.
10. Don’t ever try to work offline/disconnected. VSS will screw everything up in very creative ways. For instance, I modified a single line of code in a single file while offline and it somehow managed to check out 500 code files when I reconnected. None of these files had been modified.

I’m not the only one who hates VSS. For further reading:
http://www.codinghorror.com/blog/archives/000660.html
http://www.codinghorror.com/blog/archives/000079.html
http://www.highprogrammer.com/alan/windev/sourcesafe.html
http://www.developsense.com/testing/VSSDefects.html

JetBrains ReSharper

I just finished a trial of JetBrains ReSharper 3.0, an add-on for Visual Studio 2005 designed for code analysis and refactoring.

ReSharper’s main feature is automatic code analysis. When you open a code file, it will scan for and higlight errors in your code and show an error count and error locations on the sidebar. It also goes a step further than the compiler by highlighting warnings and making suggestions for improving code.

For many errors, it will pop up a lightbulb icon if it knows how to fix the problem. If you click this icon, it will give you a menu that will let you perform a quick-fix.

ReSharper is smart enough to warn about places where a NullReferenceException could occur and overrides intellisense with its own, more thorough version. It gives more parameter information, shows more class info, and takes intellisense to the next level in general.

Visual Studio’s refactoring options are a neat addition, but not overwhelmingly useful. ReSharper extends them quite a bit to add a lot more functionality. I never really made much use of ReSharper’s refactorings since I prefer to change things by hand.

ReSharper has quite a few features that I couldn’t imagine ever using, such as code generation, code templates, and build script editing.

Although it add a lot of features and functionality to Visual Studio, in a project of any significant size (such as the 116k-line Basternae codebase) it causes a drastic slowdown, rendering my development machine nearly unusable at times, especially when code analysis is grinding away on a large code file. It’s true that the codebase I’m working on isn’t optimal (huge classes, bloated files, plenty of errors, etc), but that’s why I’m working on it in the first place — to fix all of that.

It’s an ambitious tool, but perhaps it’s trying to do too much. Maybe future versions will be faster, but right now it doesn’t add enough value to the development process to justify the $149 price tag.

If JetBrains removed everything but the code analysis functions for a “lite” version that sold for $49 I’d buy it in a heartbeat, but as it is now ReSharper doesn’t speed up my development process more than it slows it down. I’ll look at the 4.0 version when it comes out, but 3.0 isn’t for me.

Visual Studio Becomes More Responsive

I mentioned in an earlier post that Visual Studio 2005 was gradually becoming more responsive as the error count decreased.

On my system, which is a Pentium D 2.66 GHz with 1GB of RAM, it starts becoming usable again at about 22,000 errors (we’re at 22,267 now).  That’s where the “type-a-character-and-wait” transitions into using the application in realtime.

One thing to keep in mind is that I have a trial installation of ReSharper (which I’ll post about once I’ve had more chance to evaluate), which slows things down considerably due to constant recompiling to find errors in realtime and excessive intellisense-ing above and beyond that which Visual Studio does.  Without Resharper I think I would have noticed responsiveness a bit earlier, but for now I have to say that 22,000 errors should be considered the upper limit of usability in a system like mine.

With more RAM it would probably be a bit better, and at this point it probably makes sense to upgrade to 2GB (RAM’s gone down quite a bit recently, probably due to Vista finally starting to sell).  I’ll have to add that to my grocery list.

VS2005 Regular Expression Search Rules!

One of the things I had to do to eliminate a few thousand bugs as part of this C++ to C# conversion is replace the text transmission functions.

Nevermind how they work internally, the important thing for the sake of the current conversion is that they look completely different.

The old functions looked something like:

send_to_char( “Words.\n\r”, ch );

While the new functions are supposed to look like:

ch.SendText( “Words.” );

With around 4000 or so calls to that function, it would be a dauntingly huge project to retype every reference to send_to_char. Because it’s a bit more complicated than a simple word replace, we would be hosed if not for Visual Studio 2005’s regular expression search and replace.

If you Google regular expression search-and-replace, most likely you’ll come up with a lot of people complaining about it. Ignore them — those people are whiny idiots. It is easily one of the most useful things ever added to Visual Studio and it takes about 10-15 minutes to get the hang of.

To make the above change, all I had to do was do a search for:

send_to_char[(] {:q}, {:i} [)];

And replace it with:

\2.SendText( \1 );

As a basic explanation:

1. Anything in [] brackets means “any of these characters”. I had to bracket the parenthesis to keep the parser from evaluating them as an expression.
2. Anything in {} brackets means that it’s assigned an “expression tag”. It’s the equivalent of the scripting language act of assigning it to %0, %1, etc and they’re numbered in the order they are found.
3. :q means match a “quoted expression”.
4. :i means match a C++/C# identifier (i.e. a variable name).
5. \1 means “insert the first tagged expression”. \2 inserts the second, etc.

This is enough to get the basic idea going, and it works like a charm, provided the functions are spaced EXACTLY as indicated. If you have something like (notice spaces):

send_to_char(“Something” , ch );

It will not work. In any codebase that has had more than one person’s fingers in it, you’ll have inconsistent spacing. Some people will put spaces before/after every variable, some won’t, and some will be mixed. That’s why we have to set it to ignore spaces anywhere they will be a concern. We do this by inserting [ ]* which means “match anywhere from 0 to infinity spaces”. The search expression now looks like:

send_to_char[(][ ]*{:q},[ ]*{:i}[ ]*[)];

And now that I’ve figured out how to use regular expressions, all of the references to the Diku send_to_char function have been replaced with our shiny new code.

The error count is now down to 24,414.

Visual Studio 2005

I’ve been using Visual Studio .Net 2003 for a long time. I’ve finally upgraded to 2005, and some of the changes are interesting.

One of the things I’ve been doing is converting a lot of the c-string functions to STL std::string. It turns out that the old string functions I’m gradually eliminating have been deprecated:

_snprintf: “This function or variable may be unsafe. Consider using _snprintf_s instead.”
strncat: “This function or variable may be unsafe. Consider using strncat_s instead.”
stricmp: “The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _stricmp”
fopen: “This function or variable may be unsafe. Consider using fopen_s instead.”
strncpy: “This function or variable may be unsafe. Considre using strncpy_s instead.”

I will gladly avoid using those functions. I hate them.

SourceMonitor Update

Ahh, the joy of code metrics.

Files: 132
Lines: 113,584
Statements: 58,853
% Branches: 29.2
% Comments: 8.8
Class Definitions: 52
Methods/Class: 6.86
Average Statements/Method: 14.7
Max Complexity: 477
Max Depth: 8
Average Depth: 1.86
Average Complexity: 11.47

For the first time, the number of lines of code has gone down.  This is because MobProgs were removed.  We also lost about another 400 or so lines because the change to saving objects using XML allowed us to eliminate some duplicate code (repeat after me kids: Duplicate code is BAAAD!)   The average complexity also seems to be gradually decreasing a little.  In general that’s a good thing, since maintainability of code is generally thought to be the inverse of its complexity.

SourceMonitor Update

I just love these statistics tools…

Files: 127
Lines: 116,320
Statements: 60,630
% Branches: 29.5
% Comments: 8.5
Class Definitions: 50
Methods/Class: 7.04
Average Statements/Method: 10.8
Max Complexity: 477
Max Depth: 8
Average Depth: 1.87
Average Complexity: 11.71

The number of files, class definitions, and methods per class has increased, while the statements per method and average complexity has decreased.

Project Line Counter Update

I’ve done a lot of writing, rewriting, replacing, and rearranging lately. Here are the current totals:

115,384 lines total
93,783 lines of code
9,859 lines of comments
2,071 mixed (code + comment) lines
13,813 blank lines

I guess you could call that a small but not quite negligible increase.

WinMerge

One of my biggest complaints when booting into Linux is that I don’t have access to a merge tool quite as nice as WinMerge. The current version of WinMerge doesn’t run under Wine, but apparently an older version, 2.0.2, will.

Some things are optional when writing code, but a good merge tool is not one of them. WinMerge is the perfect example of what a merge tool should be.

The Meld diff viewer is the best merge tool that I’ve seen on Linux, but it’s just a bit less usable than WinMerge.

SourceMonitor

I found a code analysis and metrics program called SourceMonitor today. I downloaded version 2.3.6.1 and fed it the source files for Basternae. Here’s what it came up with:

Files: 120
Lines: 114,121
Statements: 59,490
% Branches: 29.2
% Comments: 8.6
Class Definitions: 43
Methods/Class: 4.41
Average Statements/Method: 14.2
Max Complexity: 477
Max Depth: 8
Average Depth: 1.87
Average Complexity: 12.41

The check_command() function in the command interpreter is the most complex function. The complexity rating of 477 comes from the fact that it has 477 different branches of execution – essentially 1 for each different command the MUD understands.

Since this code is hybrid C and C++, the average number of statements per method metric doesn’t giev a full picture of things. It’s still pretty interesting to see the statistics on things.

SourceMonitor keeps track of “checkpoints” and lets you look at how code evolves over time, so it’ll be interesting to fire it up and post statistics now and then.

Lines and Lines of Code

One of my favorite free little toys for Microsoft Visual Studio is the Project Line Counter (http://www.codeproject.com/macro/linecount.asp). A count of the current Basternae codebase shows:

110,815 lines total
89,446 lines of code
9,880 lines of comments
2,003 mixed (code + comment) lines
13,492 blank lines

Progress continues on changing to std::string, constructors and destructors, and converting manually-handled lists (direct pointer-setting) to std::list.