rulururu

post CompareNoCase does not work as expected

July 30th, 2008

Filed under: C++, MFC — Kai @ 11:18 am

Recently I found a program of mine doing all kind of unexpected things because of CString::CompareNoCase() not returning what I expected it to return.

My application usered names containing the characters: é, è, à. Somewhere in my app I used the given name to search the corresponding object in a list. Since the given names had to be (case insensitive) unique I stored those names in uppercase format.

Afterwards I compared (in a case insensitive way) the given name with the uppercase name of each object in the list.
And that went unexpectedly wrong! Look at the following code snippet:

CString strText("élève - à la façon - château");
CString strTextUpper(strText);
strTextUpper.MakeUpper(); // Upper case the original 
 
int match = strTextUpper.CompareNoCase(strText); //does not match

For CString::CompareNoCase I read:

Compares this CString object with another string using the generic-text function _tcsicmp. The generic-text function _tcsicmp, which is defined in TCHAR.H, maps to either _stricmp, _wcsicmp, _mbsicmp depending on the character set that is defined at compile time. Each of these functions performs a case-insensitive comparison of the strings, and is not affected by locale.

While digging deeper in MSDN I discovered the existence of CString::CollateNoCase for which I read:

Compares this CString object with another string using the generic-text function _tcscoll. The generic-text function _tcscoll, which is defined in TCHAR.H, maps to either stricoll, wcsicoll, or _mbsicoll depending on the character set that is defined at compile time. Each of these functions performs a case-insensitive comparison of the strings, according to the code page currently in use.

This knowledge led me to two workarounds:

  • Use CString::CollateNoCase instead of CompareNoCase.
  • Although the help says it works independent of the locale, before calling CString::CompareNoCase set (the LC_CTYPE part of the) the locale. e.g.:
    setlocale(LC_CTYPE, "french-belgian");

Finally my confidence in MFC’s CString comparison functions isn’t great after I discovered this. And that’s why I wrote my own ever-working workaround:

int MyCompareNoCase(LPCTSTR str1, LPCTSTR str2)
{
  CString strTmp1(str1);
  CString strTmp2(str2);
  strTmp1.MakeUpper();
  strTmp2.MakeUpper();
  return strTmp1.Compare(strTmp2);
}

post Getting back the root password

July 25th, 2008

Filed under: Linux — Kai @ 2:12 am

Let’s imagine you forgot your root password. Now you’ll just have to reinstall the entire machine. But it’s surprisingly easy to get on the machine and change the password. This doesn’t work in all cases (like if you made a GRUB password and forgot that too), but here’s how you do it in a normal case.

  • First reboot the system. When it reboots you’ll come to the GRUB screen. Move the arrow key so that you stay on this screen instead of proceeding all the way to a normal boot.
  • Next, select the kernel that will boot with the arrow keys, and type E to edit the kernel line.
  • Use the arrow key again to highlight the line that begins with kernel, and press E to edit the kernel parameters. Simply append the number 1 to the arguments.
  • Then press Enter, B, and the kernel will boot up to single-user mode. Once here you can run the passwd command, changing password for user root…
machine# passwd
New UNIX password:
Retype new UNIX password:
passwd: all authentication tokens updated successfully

Now you can reboot, and the machine will boot up with your new password.

It’s also possible to do something similar with lilo, too. If I’m not wrong typing linux single at the lilo prompt should work.

post Single Instance managed by GUID

July 22nd, 2008

Filed under: C++ — Kai @ 3:29 pm

Some of the applications need to be restricted to run as a single instance. This can be achieved very easily in C++ applications.

When the application is started, it has to be checked if there is another instance running. If there is one already running, a message should be displayed and the application quit from the environment.

By default MFC provide no APIs or methods to satisfy this. But, by using mutex, the work is so simple.
For this we need a GUID (Globally Unique Identifier). You can create this by using the MFC application

A small tool called guidgen.exe generates a GUID.
First of all you have to start guidgen.exe. All you have to do is to click the New GUID button in the Create GUID dialog box.

After that you need to create a named mutex semaphore when you start your application. When the second one starts it tries to get access to the mutex but will fail…

Implement one method:

BOOL CThreadTestApp::SingleTest (LPSTR szName)
{
        HANDLE hMutex = CreateMutex (NULL, TRUE, szName);
        if (GetLastError() == ERROR_ALREADY_EXISTS)
        {
           CloseHandle(hMutex);
           return FALSE;
        }
return TRUE;
}

Call the method in InitInstance() like:

if (SingleTest (_T("SingleTest_48C56927-A0DB-4e31-8C32-FE15FBA45043")))
{
 
}
else
{
   AfxMessageBox(_T("Error: application is already running!"));
   return FALSE;
}

This check is performed inside the CWinApp derived classes in MFC. The CWinApp::InitInstance function is the ideal place for performing such initial check-ups.

post New Domain Endings

July 18th, 2008

Filed under: Internet — Kai @ 1:32 pm

Domains ending in anything from .nyc to .travel may be possible after ICANN modifies its process for approving new names.

If your domain name of choice has been already been soaked up in every ending from .com to .tk, fear not: a new move by the organization responsible for registering domains may soon open up a limitless supply of new endings. The Internet Corporation for Assigned Names and Numbers (ICANN) decided that it will create new guidelines to streamline the addition of new domains in the coming years.

Allowed will be common words like .love or even proper names like .bob. However, endings that violate the law of trade marks or are agains morals and decency will not be permitted.

ICANN announced its decision at the conclusion of a week of meetings held in Paris. Although the plan still needs approval from a board before new domains can begin to crop up, ICANN foresees a slew of specialized new endings, from .travel to .nyc, growing from the new guidelines.

To foot the cost of introducing new domain endings, they will most likely have to be sponsored by the introducing party. The Associated Press speculates that fees could begin around $100,000, cutting the market for “vanity” domain names.

Although the full approval for a new domain has no set timeline, ICANN hopes to begin accepting applications in the second quarter of 2009.

I’ll think the question I ask myself the next several days will be how I can take advantage of that. What domain names may be available due to this?

Unfortunately I guess that www.bka.bonn won’t be allowed?

post Google Open Sources C++ Testing Framework

July 15th, 2008

Filed under: C++, General Programming, Internet, Software — Kai @ 3:22 pm

The Google C++ Testing Framework known also as Google Test, based on xUnit has been used by many of the Google C++ developers to help in unit testing their C++ applications. It is portable and works on Linux, Windows, Mac etc with GCC and MSVC compilers and even embedded systems. You can even use it to kill your Linux applications so that they die as you expect them to. Or have it continue testing after non-fatal errors. Now they have made it available as an open source library.

Google doesn’t claim that their test framework is better than others but they have made it easy to extend it by adding new test macros. You can read more in the primer and faq.

Link: Google C++ Testing Framework

post Love or Hate Extension Methods?

July 14th, 2008

Filed under: .NET — Kai @ 12:39 pm

In C#, there is no String.Left() function. Fair enough; we can roll up our sleeves and write our own function lickety-split:

public static string Left(string s, int len)
{
    if (len == 0 || s.Length == 0)
        return "";
    else if (s.Length <= len)
        return s;
    else
        return s.Substring(0, len);
}

And call it like so:

var s = "superlongstring";
s = Left(s, 5);

But with the advent of C# 3.0, there’s an even better way — extension methods. With an extension method, we “extend” the String to add the missing function. The code is fairly similar:

public static string Left(this string s, int len)
{
    if (len == 0 || s.Length == 0)
        return "";
    else if (s.Length <= len)
        return s;
    else
        return s.Substring(0, len);
}

And now we can call it as if this very method existed on the String class as shipped:

var s = "superlongstring";
s = s.Left(5);

Pretty slick. It’s difficult not to fall in love with extension methods, as they allow you to mold classes into exactly what you think they should be. This is fairly innocuous in C#, as extension methods only allow you to add new functionality to classes, not override, remove, or replace anything.

ruldrurd
Next Page »
Powered by WordPress, Content and Design by Kai Bellmann
Entries (RSS) and Comments (RSS)