Archive | Castalia for Delphi RSS feed for this section

Bug Dissection: Comparing Filenames

I think it’s good to confess the errors you made when you created bugs in your software. It makes you a better programmer to write out the process of creating and fixing the bug, and might help someone else at the same time. This is one of those confessions.

Castalia often has a need to determine whether two filenames are the same. For example, the code that maintains internal data about the code you’re working on very frequently checks to see if you’re still working on the same file you were last time. It does this by comparing the name of the file you’re working on with the name of the file you were working on last time it checked. If they’re the same, it’s the same file. If they’re different, then you’re working on a different file.

Easy enough, right? Filenames are just strings, so it’s a simple string comparison.

Of course, there has to be a complication. The complication is that the Delphi ToolsAPI doesn’t always give you the filename in the same format. It’s usually the full path to the file, but occasionally, it will be just the extracted filename.

For example, when Castalia gets the name of the current file from the ToolsAPI, it will probably get a string like ‘c:\users\jacob\documents\project1\MainForm.pas’, but it might just get ‘MainForm.pas.’

So, I wrote an IsSameFile routine that would take two filenames as strings, and compare them in both cases (full path, or just filename), to determine if they are, in fact, the same file:

function IsSameFile(N1, N2: string): Boolean;
begin
  Result := CompareText(N1, N2) = 0; //Usually this works, for full paths
  if not Result then //If it's false, maybe we have a simple filename. Check that
    Result := CompareText(ExtractFileName(N1), ExtractFileName(N2)) = 0;
end;

This worked great, until someone came across an edge case that proved to be a bug in this function.

See if you can spot it. I’ll wait…

OK, did you find it?

Here’s the problem: What if the “short” filenames are the same, but are, in fact, different files? For example:

N1 is ‘c:\users\jacob\documents\project1\MainForm.pas’

N2 is ‘d:\projects\project2\MainForm.pas’

The function above will first try to compare N1 and N2, and then when that’s false, will compare the “short” file names, which happen to match, even though it’s painfully obvious that these are not, in fact, the same file.

There are two fundamental errors in logic here. One is thinking there only two cases: 2 full paths, or 2 “short” names. The second is thinking that the second case is always triggered by the first case being false.

The fixes:

First, realizing that there are actually three distinct cases for comparing the two filenames:

  1. Compare two filenames with full paths
  2. Compare two “short” filenames, with no path
  3. Compare one “short” filename with one full path

Second, these cases need to be detected independently. Just because the first case is false doesn’t mean that wasn’t the right case. There needs to be a mechanism to determine which case to use, and then compare the appropriate strings.

Here’s the fixed IsSameFile function:

function IsSameFile(N1, N2: string): Boolean;
var
  S1, S2: string; //Short filenames
begin
  S1 := ExtractFileName(N1);
  S2 := ExtractFileName(N2);

  if (S1 <> N1) and (S2 <> N2) then
  begin
    //2 full path
    Result := CompareText(N1, N2) = 0;
  end else
  if (S1 = N1) and (S2 = N2) then
  begin
    //2 filename only
    Result := CompareText(N1, N2) = 0;
  end else
  begin
    //1 short, 1 path
    Result := CompareText(S1, S2) = 0;
  end;
end;

This handles all three cases correctly, and more importantly, determines which case to use the right way.

This addressed a bug where Castalia’s navigation toolbar would get confused if you opened two files with the same filename, either at the same time, or in sequence (for example, working on MainForm.pas in one project, then closing that project and immediately opening MainForm.pas from another project). That bug is fixed, thanks to the fixed IsSameFile() function, as of Castalia 2014.5.

Read full story · Comments { 14 }

Castalia 2014.5 is now available

I’ve just released Castalia 2014.5, the latest update to my smart code editor for Delphi programmers. This is primarily a bugfix release, addressing the following issues:

  • Fixed: Navigation toolbar keyboard shortcuts stop working in Delphi XE5 or XE6
  • Fixed: Navigation toolbar can get confused by two units with the same filename

Castalia users with a current maintenance subscription can download Castalia 2014.5 right now at subscribe.twodesk.com.

Everyone else can learn more about Castalia and download a free trial at twodesk.com/castalia.

Read full story · Comments { 2 }

Announcing Castalia 2014.4 with Delphi XE6 support

I’ve just released Castalia 2014.4, my newest collection of Delphi IDE plugins.

The biggest news in Castalia 2014.4 is the addition of support for Delphi XE6.

Here’s what’s new:

  • All Castalia editions are now available for Delphi XE6.
  • Fixed: Can’t change structural highlighting line width
  • Fixed: “Open Used Units” from Navigation Toolbar doesn’t work in Delphi XE5.
  • Several small performance enhancements and tweaks.

Castalia users with a current maintenance subscription can download Castalia 2014.4 at subscribe.twodesk.com.

Everyone else can learn more and try Castalia free at www.twodesk.com/castalia

Read full story · Comments { 0 }

Castalia 2014.3 is now available

I’ve just released Castalia 2014.3, the latest update to my smart code editor for Delphi programmers. This is primarily a bugfix release, addressing the following issues:

  • Fixed: Access violation when performing certain refactorings on classes with overloaded methods
  • Fixed: Castalia incorrectly identifies the following syntax as invalid: try … except else; end;
  • Fixed: Text search toolbar can become disabled when switching editor tabs, and can’t be re-enabled without restarting Delphi

Customers with a current subscription can download Castalia 2014.3 right now at https://subscribe.twodesk.com.

Everyone else can learn more about Castalia and download a free trial at twodesk.com/castalia.

Read full story · Comments { 0 }

Castalia 2014.2 is now available

I’ve just released a new version of my smart code editor for Delphi programmers: Castalia 2014.2.

Castalia 2014.2 is a bugfix release that addresses two issues:

  • Fixed: “Synchronize Prototypes” doesn’t handle constructors or destructors well
  • Fixed: Syntax error highlighting can get “behind” by a keystroke under some circumstances

Users with a current maintenance subscription can download Castalia 2014.2 at the customer download site.

Everyone else can try Castalia for free at twodesk.com/castalia/freetrial.html.

Read full story · Comments { 0 }

For programmers, by a programmer

Hi. My name is Jacob, and I'm the creator of Castalia.

I starting programming in 1986, learning Lightspeed Pascal on a Mac Classic. Today, I'm a professional programmer, teacher, and entrepreneur.

I have a Master's Degree in Computer Science, and I still love Pascal and Delphi.

I believe that writing code is the heart and soul of software development, and I love helping programmers write code more effectively.