Friday, September 27, 2013

Embedding C++ code analysis into Visual Studio

Once needed to perform C++ code analysis in order to find multibyte-unfriendly code. Perl with regular expressions helped me a much. Then I've realized that asking everybody in my team to work from DOS console would be inconvenient, thus I've started thinking how to embed this stuff into my lovely IDE (*)

I even asked the community a question: How do I modify View.FindResults1 contents in Visual Studio? 
and got am advice to my own version of the "Find Results" window by creating a Visual Studio extension myself. We can start by having a look at Extending Visual Studio > Tool Windows


Probably writing VisualStudio extensions is a deal of my future self-development. For now I've stopped on calling the script from Post-Build process:
perl $(SolutionDir)\Localization\test_resource_funs.pl  $(InputDir)
thus having its output in Compile Output window. No additional efforts are needed. I can even use "Errors List" to sort and observe all of script warnings.

"Output" window:

"Error List" window:


* - I bet Visual Studio is the best one IDE.

PS see: Formatting the Output of a Custom Build Step or Build Event 

Wednesday, September 25, 2013

Line count with .bat

When it comes to routine, some can think of wasted hours, yearning, many cups of cofee trying to to fall asleep during your work. In that case it's better to think about robots. Let robots do their staff.

I have a perl script which has to be called 100 times for each of VS solution subdirectory. I don't want to write another Perl script to automate it, so let's use .BAT file:
@echo off

if "%1" == "" GOTO HELP

for /D %%D in (%1*) do perl the_script.pl %%D > %%D.txt

goto END

:HELP
echo test_resource_funs_loop.bat - calls test_resource_funs.pl with each subdirectory
echo Usage example: test_resource_funs_loop.bat C:\Dev-9.1\hyp_src\

:END
Thanks to Brett Batie I've written Linux wc command analogue to count # of lines in the archived 100 .txt files:
@echo off
findstr /R /N "^" %1  |find /C ":"

Tuesday, September 17, 2013

Suggest using of Visual Assist X



I’d highly recommend using of the subject since it significantly improves code traversing, understanding of code written by others, code refactoring, etc.
Visual Assist is a Productivity and code refactoring plugin an is much more effective than Visual Studio Intellisence. You can switch off Intellisence and use Visual Assist X instead.

Sweets:

  • Its “Go to definition” never fails and works even if you have compile errors;

  • Find references finds much more precisely then of Intellisence
    For example, it can find all usages of CString::operator+() rather than searching for ‘+’ with “Find-In-Files”, which might be very useful;

  • “Call tree” and “Caller tree” gives you opportunity to investigate without running the code. Sometimes you even don’t have idea how to run/debug this particular function.

  • “Rename” and “Extract function” speeds up any rewriting.

  • It highlights the same variables/words on a screen that cursor is currently staying on. Helps a lot finding all ‘i’-s in a function.

  • It speeds up navigation among tons of sources an classes/function names. To look for a function named either “FillDirectory” or “DirectoryFill”, just type “Directory” and choose from the list.

 Read more about Visual Assist Features, try its 30-days trial, if interested

This is my proposal, it’s up to you whether to ask for purchasing it. But it has good discount policy: 5 copies costs as 4 separate purchases.

PS Note that it is not a static analysis tool like Klockwork or Coverity. Static analysis tools goal is to warn you about potential errors, thus code is written not according to Code Complete

Thursday, September 12, 2013

Dual personality of while

At a first glance nothing special. Then you see dual personality
   while(1)
   {
      ch = ::CharPrev(m_str1, ch);
      TestString s(ch);
   } while (ch!=m_str1);

Friday, September 6, 2013

Cure for broken TEXTINCLUDE section of VC++ resource files


Today I've configured VC++ project to allow editing Chinese resources from Visual Studio, which ended up in SVN Commit error “Inconsistent line ending style”.

Pic 1.  After each resource modification Visual Studio was writing incorrect end of line sequence to “Read-Only Symbol Directives” area

Thursday, September 5, 2013

Why is UTF-8 treated as not multibyte?



It’s a long discussion and object of terminology. Multibyte is a slippery term and is not the best one.
Visual Studio has 3 options for characters sets:

a) No characters set, which means it works OK with single byte characters sets (SBCS) like CP1251 (ru-RU) or CP1252 (en-US)
characters take 1 byte

b) MBCS, which means it works OK with multibyte Character sets like CP936,
characters take 1 or 2 bytes, GUI accepts such characters if appropriate locale is selected in Control Panel

c) Unicode, which means working with UTF-16BE,
characters take 2 bytes, selected locale doesn’t make any sense

Note that there is no option to work with utf-8.
There are conversion functions utf8 <-> MBCS.
In Microsoft documentation term “multibyte” is related to MBCS. It was hard for me to achieve, and I suppose there could be misunderstanding among the team regarding this term.

Even having the same way of coding and having floating amount of bytes, utf8 is a way of encoding Unicode characters, it is not related to MBCS at all.

In order to have our virare and maina (it.) we’ve agreed to call MBCS multibyte

Friday, August 9, 2013

A tool for searching for memory leaks



1. Download and install utility from http://vld.codeplex.com  (it's free).
2. In VS invoke dialog Tools -> Options..., select page Projects and Solutions -> VC++ Directories and add 
C:\Program Files (x86)\Visual Leak Detector\include 
to the list of Include files, and 
C:\Program Files (x86)\Visual Leak Detector\lib\Win32
to Library files.
3. Restart Visual Studio.
4. In any project file, add line 
#include "vld.h".
5. Build the project and run from the debugger.
6. After exiting the program, Output window will contain additional information about some (but unfortunately not all) of memory leaks, which makes it easy to locate them.
7. Please don't forget to remove #include "vld.h" before committing :)

by Oleg.B

Convenient way to place TODO into Visual Studio C++ project

Any ideas on the subject?

a. You can write a note on a sticker, put sticker on a wall in your office, then work from home for a couple of days and forget about your TODO.

b. You can write a note in your notebook, then add a couple of pages with other notes and forget your TODO.

c. You can file a Defect Request in ClearQuest (or other project management system) and be buried under bureaucracy process instead of coding. Probably your request would go to other developer and then he or she would do what your don't intend to do.

d. You can add a comment in code like with a small type (extra space or char):
//TODO:   mickhael, replace ch++ with  _tcsinc
then search for "TODO" with "Find-In-Files" and obtain tons of TODO's of the whole team.
Your may search "TODO: mikhael" and find nothing due to typo in the comment.

c. I'd recommend using of #pragma message:
#pragma message("//TODO:   mickhael, replace ch++ with  _tcsinc")  

Wednesday, August 7, 2013

MultiByte, UTF-8 and Chinese Character Set



This is a result of long discussion and research of MultiByte encoding with Olga L. this morning. Keep in mind the following information when processing strings when performing localization to Chinese:
  • Multibyte is used in HyperLynx for localized strings.
  • Multibyte is not related to wide chars (wchar_t, Utf-16) at all, even having 2 bytes per character.
  • Multibyte is not related to Utf-8.
  • In Visual Studio debugger you always see Multibyte characters in case Chinese Simplified locale is selected in Control Panel
  • Multibyte (MBCS, DBCS) is the same as CodePage 936 or GB2312 in case Chinese Simplified locale is selected in Control Panel
  • getchar's _(“Two beer or not to be”) returns Multibyte string.
  • “tchar.h” routines like _tcsclen, _tcsncpy,  etc. deal with Multibyte strings
  • .po files are written in UTF-8 and converted to Multibyte on loading
  • .rc files resources are written in Win1251
  • Chinese .zh-CN.rc resources are written in CP936
  • Some of MFC Windows GUI accepts  Multibyte, some only accept ANSI or wchar_t *
Use this site to understand different encodings better, note that on Chinese locale we deal with CP936 Encoding: http://www.kreativekorp.com/charset/encoding.php

Thursday, July 25, 2013

regexp в C++

К своей радости узнал, что в VS2008 появились регулярные выражения TR1 в STL
Подробности тут: A TR1 Tutorial: Regular Expressions

А мне как раз понадобилось на С++ парсить исходники С++ на предмет поиска параметров printf() , имеющих следующий прототип:
%[flags][width][.precision][length]specifier
После долгой возни вокруг \t \n вот что у меня получилось:

#include <string>
#include <regex>

// text - printf format input, for instance:
//        "Unable to create %s!/nUnsufficient RAM: %3d."
//
// arr  - output array of printf format parameters, in this case:

//        {"%s", "\n", "%3d"}
int GetPrintfParameter(CString text,CStringArray & arr)
{
    text.TrimLeft();
    text.TrimRight();
    if(text.IsEmpty() )return 0;

    std::string prinfFormat = text;
    const std::tr1::regex pattern("((%(\\+|-|0|\\#)?(\\d+|\\*)?(.\\d+|.\\*)?(\\d)?(d|i|u|o|x|f|e|g|a|c|s|p|n|\\%))|(\\\\n|\\\\t|\\|))");
    const std::tr1::sregex_token_iterator end;
     for ( std::tr1::sregex_token_iterator i(prinfFormat.begin(),  prinfFormat.end(), pattern);
              i != end;
            ++i )
     {
       CString sep = (*i).str().c_str();
       arr.SetSize(arr.GetSize()+1);
       arr[arr.GetSize()-1] = sep;
     }

    return arr.GetSize();
}

Thursday, June 20, 2013

Короткое замыкание в С++

Инициализация ссылки
Как известно, в С++ ссылки, являющиеся переменными класса, нужно инициализировать в списке инициализации конструктора:
class A() {
   std::vector<int> & m_refData; // ссылка на массив
}
См. короткое замыкание...

Трассировка лёгкая как printf


Разобрался наконец как работать с переменным количеством аргументов, а точнее конструкцией ... в Си-шных функциях. Заодно написал полезняшку для отладки с помощью WinAPI-шной функции OutputDebugString, которая неудобна, т.к. принимает только строки, что заставляло меня писать громоздские конструкции для отладки.

Исходники void TraceString(const char *msg, ...) см. ниже


Непроходимые горы, Dependency Walker, sxstrace.exe и другие

Иногда перед программистом во время отладки, а особенно 64-битных приложений, на ровном месте вырастают непроходимые горы, как например эти:


(нарисовано в thisissand.com)

"...И горы встают перед ним на пути,
И он по горам начинает ползти,
А горы всё выше, а горы всё круче,
А горы уходят под самые тучи!...

И сейчас же с высокой скалы к Айболиту спустились орлы..." (с)

Monday, June 17, 2013

Welcome, gettext, this is VBasic script

Task description
There is a project containing thousands of CPP sources that have to be localized into Chinese ASAP. We're using gettext technique for localization and strings to be translated have to be wrapped with _(), for example:
::MessageBox( _("Translate me please"), _("Warning"), MB_OK)
We can run Visual Studio Find In Files->Current File for each file with the following regexp:
\".*\" 
in order to search all strings, а then insert _('s and )'s.
But this is dull and boring, so let's switch on the brains and write a VisualBasic script in VBasic IDE (Alt-F11) which can be invoked by pressing F5 (or whatever you like, use Tools->Customize-Keyboard to setup hotkey).
Now just you have to traverse "Find Results" window by pressing F4 and optionally pressing F5 on each string that should be wrapped with _(). You can even avoid watching into .cpp source in simple cases with MessageBoxes (90% of strings). This way you reduce summary time  of processing all the .cpp sources for at least thrice, and even five times.

Here is VBasic Script. Note that it even handles multiline strings!

Wednesday, April 3, 2013

Amount of emotions when moving

There is a blog one could probably find it interesting http://www.englishdadinmoscow.com/

Also I heard about a book called "America, What a Life?" from Nikolai Zlobin
it's like the complement of that, in russian, about the US

"It seems strange that ordinary Russians would still be hungry for details about how ordinary Americans eat, pay mortgages and hire teenage baby sitters"
Too many Russian have moved for better life to America that's why it's a point of interest
I have 1 friend mine, 3 colleagues and ~ 10 students of the same year who moved abroad
I understand their point, they've got all ranges of perspectives (maybe) and twice - 5 times higher salary
This is why I'm shocked about Americans and Europeans who're moving to Russia without even speaking Russian
The key thing here is that all dull and boring daily stuff becomes very interesting to foreigners because all things are different
Do you remember the Third Newton law

"When a first body exerts a force F1 on a second body, the second body simultaneously exerts a force F2 = −F1 on the first body."

Let's state a new theorem:

"amount of emotions when moving from RU to US would be the same as when moving from US to RU"
It would be nice to prove it somehow

Self-made simple C++ profiler

In order to measure routine time and find bottle neck in С++ sources (do profiling), and especially if we have enough time, we can try some of existing profilers: http://stackoverflow.com/questions/67554/whats-the-best-free-c-profiler-for-windows-if-there-are

But simple and quite powerful decision could be using of self-written profiler (for non-thread-safe application). Let's create a C++ class that you just insert at the begining of tested functions or even {} scopes, for example:

f()
{
    Profile me;
    f1();
    f2();
}
f1()
{
   Profile me;
...
}
f2()
{
   Profile me;
...
}


What does it do?

Class Profile:
  1. measures time intervals between its constructor and destructor calls,
    at desctructor saving result to some place: to  memory stream or via OutputDebugString, not  to file!!.
  2. counts its instances in order to support indenting in reports
class Profile{
   static st_profile_indent_count;
   LARGE_INTEGER start;
   Profile() {
      st_profile_indent_count++;
      QueryPerformanceCounter(&start)
   }
   ~Profile()
   {
       st_profile_indent_count--;
       LARGE_INTEGER stop;
       ::QueryPerformanceCounter(&stop);
       OutputIndent(st_profile_indent_count);
       OutputTimeSpan(stop.QuadPart - start.QuadPart);
   }
}


Here is is. Then we can improve it somehow, add comments or scope name:
f()
{
    Profile me("f()");
    f1();
    f2();
}


We can learn Profile to report % of total time load, for example:
f()
{
    Profile me("f()"); // Текст для трассировки
    for (int i = 0; i< 10000000; i ++)
    {
         f1();
    }
    f2();
}

It's clear that f1 is a critical one function here.

PS Here are just practical ideas, not instructions. I've used such a technique in KLA-Tencor project when optimizing 3D engine.