A Developer's Diary

Aug 31, 2010

zthreads - building zthread dll using visual studio 2008

ZThreads is a cross platform object oriented library written in C++ which provides a clean and simple interface to both POSIX threads and Windows API threads.

Building ZThread shared library using Visual Studio 2008

1. Download ZThread source tar ball and extract it.
2. Create a new Win32Project using the Visual Studio installed templates
3. Go to Application Settings of Win32 Application Wizard
4. Select dll as the Application type and Empty project in the Additional options.
5. Add all the cxx files inside ZThread src folder into your project Source Files excluding the sub directories
6. Go to C/C++ tab in the Project Properties. Specify ZThread include directory in the Additional Include Directories
7. Change the default Character Set used by your Visual Studio project from Use Unicode Character Set to Not Set
8. Build the project

Read more ...

Aug 29, 2010

Mercurial - A short tutorial

Why Mercurial?

Mercurial can boast of really unique set of properties that make it a particular good choice as a distributed revision control system.
1. Easy to learn and safe to use
2. Lightweight
3. Delightful extensions and customization
4. Scalable
Download and install the Windows shell extension for Mercurial (TortoiseHg) from here

Creating a Repository

hg init main
where
main is the repository name

Mercurial reads configuration data from several files, if they exist. On Windows, it normally looks for %USERPROFILE%/mercurial.ini file or %USERPROFILE%/.hgrc file and in Unix based machines it looks for $HOME/.hgrc file. For detailed information type hg help config in the command line window or the terminal
Configuring Mercurial

Open %USERPROFILE%/mercurial.ini or %USERPROFILE%/.hgrc file and add following lines to it.

[ui]
username = Firstname Lastname <firstname.lastname@example.net>

This sets the username for the mercurial and this information is for reading by other users

Mercurial has inbuilt lightweight HTTP server that can be used to share the repository.
Serving the Repository

hg serve -p 80 -d
where
-p is used to specify a different port (default port 8000)
-d is used to run the server in the background

Creating a local copy of the Repository

hg clone http://host-name/
This creates a clone of the repository on the local machine

Read more ...

Jul 19, 2010

C++ Idioms - Non Copyable Objects

The Non Copyable idiom in C++ allows us to create classes whose objects cannot be constructed using a copy constructor or assigned to another. Some of the classes using this idiom provide mutually exclusive access to the resources e.g. Mutex, Semaphores, Document, Memory, File etc

Key Idea
To prevent objects of a class from being copy constructed or assigned to each other, declare the copy constructor and the assignment operator as private and do not provide implementations
//File: NonCopyable.h
#include <iostream>

class NonCopyable
{
protected:
    NonCopyable(){}
    ~NonCopyable(){}

private:
    //Restrict the copy constructor
    NonCopyable(const NonCopyable&);
    //Restrict the assignment operator
    NonCopyable& operator=(const NonCopyable&);
};

Read more ...

Jul 18, 2010

Static Member Functions

A static member function can be accessed using an instance variable or using the class name. It is better to use class name to access a static method as it is more readable and speaks by itself that the method being called is a static member

//File: static_example.h
#include <iostream>
using namespace std;

class StaticExample
{
    public:
        StaticExample();
       ~StaticExample();

        //static member function
        static int StaticMethod();

    private:
        StaticExample(const StaticExample&);
        StaticExample& operator=(const StaticExample&);

        std::string m_str;
};

//File: static_example.cpp
#include "static_example.h"

StaticExample::StaticExample()
{
}

StaticExample::~StaticExample()
{
}

int StaticExample::StaticMethod()
{
    cout << "static method called";
    cout << endl;
    return 0;
}

Read more ...

Jul 17, 2010

Conditional execution in ant

An ant target can be configured to execute conditionally using if and unless attributes available.
A simple ant target without any attributes

<project name="examples" default="simple_target_example">

  <target name="simple_target_example">
    <echo message="a simple target example"/>
  </target>

</project>
Output
$ ant
Buildfile: build.xml

simple_target_example:
     [echo] a simple target example

BUILD SUCCESSFUL
Total time: 0 seconds

Ant target with an if attribute
<project name="examples" default="example_if_target">

  <target name="property_target">
    <property name="greetings" value="1"/>
  </target>

  <target name="example_if_target" depends="property_target" if="greetings">
    <echo message="Greetings"/>
  </target>

</project>
Output
$ ant
Buildfile: build.xml

property_target:

example_if_target:
[echo] Greetings

BUILD SUCCESSFUL
Total time: 0 seconds

The if="greetings" attribute causes the target to be executed if greetings property is set and the unless="greetings" attribute causes the target to be executed only if the property greetings is not set

Ant target with an unless attribute
<project name="examples" default="example_unless_target">

  <target name="example_unless_target" unless="greetings">
    <echo message="Greetings"/>
  </target>

</project>
Output
$ ant
Buildfile: build.xml

example_unless_target:
[echo] Greetings

BUILD SUCCESSFUL
Total time: 0 seconds


//setting the greetings property
Output
$ ant -Dgreetings=1
Buildfile: build.xml
 

example_unless_target:
BUILD SUCCESSFUL
Total time: 0 seconds

Read more ...

Jul 10, 2010

Standard Template Library - pair

The pair class template declared in <utility> is provided to treat two values as a single unit. STL container classes map and multimap use pairs to manage their elements which are key/value pairs

The example code below demonstrates some of the ways of using a pair class and the convenience function make_pair()

#include <utility>
#include <iostream>
#include <string>
#include <map>

using namespace std;

void print_pair(pair<long, string> pr)
{
    cout << "[";
    cout << pr.first;
    cout << "]";
    cout << "=";
    cout << pr.second;
    cout << endl;
}


// Example: simple pair example
void simple_pair_example()
{
    pair<long, string> pr(1, "Simple Pair");
    print_pair(pr);
    cout << endl;
}

// Example: pointer to a pair
void pair_pointer_example()
{
    pair<long, string> *pr = new pair<long, string>(1, "Pointer Pair");
    print_pair(*pr);
    cout << endl;
    delete pr;
    pr = NULL;
}


// Example: pair and a map
void pair_map_example()
{
    map<long, string>   employees;

    employees[1] = "Employee1";
    employees[2] = "Employee2";
    employees[3] = "Employee3";
    employees[4] = "Employee4";

    map<long, string>::const_iterator it;
    for(it = employees.begin(); it != employees.end(); ++it)
    {
        print_pair(*it);
    }
    cout << endl;
}


// Example: pair and map find function
void pair_map_search()
{
    string user = "george";
    map<string, pair<string, string> >   employees;

    employees["pankaj"] = make_pair("Pankaj", "Tiwari");
    employees["paresh"] = make_pair("Paresh", "Tiwari");
    employees["george"] = make_pair("George", "Bush");

    map<string, pair<string, string> >::const_iterator it;
    if((it = employees.find(user)) == employees.end())
    {
        cerr << "Unknown User: " << user;
    }
    else
    {
        const pair<string, string> user = it->second;
        cout << user.first << user.second;
    }
    cout << endl;
}

int main()
{
    simple_pair_example();
    pair_pointer_example();
    pair_map_example();
    pair_map_search();
}


Read more ...

Jul 5, 2010

Integer to Binary Representation

Binary representation is a number written using base 2. Each digit can have only one of the two possible values (0 or 1) e.g. 255 is written as 00000000 00000000 00000000 11111111, 500 as 00000000 00000000 00000001 11110100 and 1024 as 00000000 00000000 00000100 00000000

The following program converts an entered integer to it's equivalent binary representation

#include <stdio.h>
#define SIZE 8*sizeof(int)

int int2bin(int, char*);
int print_bstr(const char*);
int error();

int main()
{
    int number;
    char bstr[SIZE];
    while(1){
        printf("\nEnter the number ");
        scanf("%d", &number) ? int2bin(number, bstr) : error();
        print_bstr(bstr);
    }
}

int int2bin(int num, char* bstr)
{
    int i;
    for(i = SIZE - 1; i >= 0 ; --i, num >>= 1)
    {
        bstr[i] = (0x1 & num) + '0';
    }

    bstr[SIZE] = '\0';
}

int print_bstr(const char* bstr)
{
    int i = 0;
    while(bstr[i])
    {
        putchar(bstr[i++]);
        if(i % 8 == 0  && bstr[i])
            putchar(' ');
    }
}

int error()
{
    printf("Error: non-numeric data entered. Exiting");
    exit(-1);
}


Read more ...

Jul 1, 2010

Extended ASCII Character Set


The following is a simple program which prints the characters of an extended ASCII character set

Read more ...

Jun 28, 2010

Bit Operations

There are six bitwise operators used in the C programming language.

AND Operator &

Truth Table
0 & 0 = 0
1 & 0 = 0
0 & 1 = 0
1 & 1 = 1

OR Operator |

Truth Table
0 | 0 = 0
1 | 0 = 1
0 | 1 = 1
1 | 1 = 1

XOR Operator ^

Truth Table
0 ^ 0 = 0
1 ^ 0 = 1
0 ^ 1 = 1
1 ^ 1 = 0

NOT Operator ~

Truth Table
~0 = 1
~1 = 0

Right Shift Operator >>

Left Shift Operator <<

Note:
A unary operator is one which operates on a single operand where as a binary operator is one which operates on two operands


Mask
A mask is a bit pattern with some bits set to on (1) and some bits set to off (0)

Turning Bits On

number = number | MASK;
OR
number |= MASK;

This sets on all the bits that are 1 in the MASK

Turning Bits Off

number = number & ~MASK;
OR
number &= ~MASK;

This sets off all the bits that are 1 in the MASK

Toggling Bits

number = number ^ MASK;
OR
number ^= MASK;

This toggles values corresponding to 1s in the MASK

Comparing a Bit value

Checking if the value of bit at position p is set or not

number = 9
binary = 1 0 0 1
position = 1
mask = 1 0 0 0

if( ( number & mask ) == mask ) printf(" bit is set ");


Read more ...

May 30, 2010

Knuth Morris Pratt Algorithm

The KMP algorithm compares the pattern string to the text in left to right direction as compared to Boyer Moore Algorithm. The algorithm shifts the pattern more intelligently than the brute-force algorithm.

Key Idea
Whenever a mismatch occurs, what is the most we can shift the pattern so as to avoid redundant comparisons?
Answer: The largest prefix of P[0..j] that is a suffix of [1..j]

The KMP algorithm pre-processes the pattern string to find matches of the prefixes of the pattern with the pattern itself. The information thus calculated is used to shift the pattern appropriately whenever a mismatch occurs or a comparison fails. The compuatation is performed by the function called KMP prefix function
KMP Prefix Function
The prefix function F(j) is defined as the size of the largest prefix in P[0..j] that is also a suffix of P[1..j]


Code for computing the KMP Prefix Function
computeKmpPrefix(const std::string &pattern){
    int patternSize = pattern.size();
    vector<int> kmpPrefix(patternSize);
    size_t prefixPos = 0;
    size_t suffixPos = 1;

    while(suffixPos < patternSize){
        if(pattern[prefixPos] == pattern[suffixPos]){
            kmpPrefix[suffixPos] = prefixPos + 1;
            prefixPos++;
            suffixPos++;
        }
        else if(prefixPos > 0){//found some match
            prefixPos = kmpPrefix[prefixPos -1];//backtrack for matching prefix   e.g. aaaaabaaaaaa
        }
        else{
            kmpPrefix[suffixPos] = 0;
            suffixPos++;
        }
    }
    return kmpPrefix;
}

The algorithm in picture

Example

The Complete Code
#ifndef _PatternMatcher_H_
#define _PatternMatcher_H_

#include <iostream>

#include <string>
#include <vector>

using namespace std;

class PatternMatcher{
public:
    static int kmpSearch(const string& text, const string& pattern);

private:
    static vector<int> computeKmpPrefix(const string& pattern);

    PatternMatcher();
    PatternMatcher(const PatternMatcher&);
    const PatternMatcher& operator=(const PatternMatcher&);
};

#endif //_PatternMatcher_H_

#include "PatternMatcher.h"

vector<int> PatternMatcher::computeKmpPrefix(const std::string &pattern){
    int patternSize = pattern.size();
    vector<int> kmpPrefix(patternSize);
    size_t prefixPos = 0;
    size_t suffixPos = 1;

    while(suffixPos < patternSize){
        if(pattern[prefixPos] == pattern[suffixPos]){
            kmpPrefix[suffixPos] = prefixPos + 1;
            prefixPos++;
            suffixPos++;
        }
        else if(prefixPos > 0){//found some match
            prefixPos = kmpPrefix[prefixPos -1];//backtrack for matching prefix e.g. aaaaabaaaaaa
        }
        else{
            kmpPrefix[suffixPos] = 0;
            suffixPos++;
        }
    }
    return kmpPrefix;
}

int PatternMatcher::kmpSearch(const std::string &text, const std::string &pattern){

    size_t textSize = text.size();
    size_t patternSize = pattern.size();

    if(patternSize > textSize)
        return -1;

    vector<int> kmpNext = computeKmpPrefix(pattern);
    int tIdx = 0;
    int pIdx = 0;

    while(tIdx < textSize){
        if(pattern[pIdx] == text[tIdx]){
            if(pIdx == patternSize - 1) 
                return tIdx - (patternSize - 1);
            tIdx++;
            pIdx++;
        }
        else if(pIdx > 0){
            pIdx = kmpNext[pIdx - 1];
        }
        else{
            tIdx++;
        }
    }
    return -1;
}

#include "PatternMatcher.h"

int main(){
    cout << PatternMatcher::kmpSearch
        ("abacaabaccabacabaabb", "abacab")
        << endl;
    cout << PatternMatcher::kmpSearch
        ("abacaabaccabacabaabb", "baabb")
        << endl;
    cout << PatternMatcher::kmpSearch
        ("abacaabaccabacabaabb", "abacad")
        << endl;
    cout << PatternMatcher::kmpSearch
        ("abacaabaccabacabaabb", "abacaab")
        << endl;
    cout << PatternMatcher::kmpSearch
        ("abacaabaccabacabaabb", "abacab")
        << endl;
    cout << PatternMatcher::kmpSearch
        ("abacaabaccabacabaabb", "aabaccaba")
        << endl;
    cout << PatternMatcher::kmpSearch
        ("abacaabaccabacabaabb", "abacaabaccabacabaabb")
        << endl;
    cout << PatternMatcher::kmpSearch
        ("abacaabaccabacabaabb", "")
        << endl;
    cout << PatternMatcher::kmpSearch
        ("", "abacaabaccabacabaabb")
        << endl;
    cout << PatternMatcher::kmpSearch
        ("abacaabaccabacabaabb", "bacaabaccabacabaab")
        << endl;
    cout << PatternMatcher::kmpSearch
        ("abacaabaccabacabaabb", "abacaabac")
        << endl;
    cout << PatternMatcher::kmpSearch
        ("abacaabaccabacabaabb", "ccabacabaabb")
        << endl;
    cout << PatternMatcher::kmpSearch
        ("abacaabaccabacabaabb", "bacaabaccabacabaabb")
        << endl;
    return 0;
}

Read more ...

May 29, 2010

Boyer Moore Algorithm

Boyer Moore Algorithm is one of the fastest pattern searching algorithm based on two techniques:

Techniques Used
1. The looking glass technique where you find a pattern P in text T by moving backwards through P, starting at it's end.
2. The character jump heuristic when a mismatch occurs between the characters at position Text[t] = c
Three cases are checked in the order for calculating the character jump. Before moving on to understand the individual cases, let us understand the computation of last occurrence position in the pattern string

Computing last occurrence
The compute last occurrence method assumes that all the characters under the consideration are ASCII characters. The function computes last occurrences of all the characters present in the Pattern P starting from the left. The rest of the ASCII chars return -1


Consider the ASCII character set {a, b, c, d, ..., y, z} then the last occurrence function would be computed as shown in the figure below

The function f(x) points to the last occurrence of character in the pattern P

computeBmpLast(const std::string &pattern){
    const size_t NUM_ASCII_CHARS = 128;
    vector<int> bmpLast(NUM_ASCII_CHARS);

    for(size_t i = 0; i < NUM_ASCII_CHARS; i++){
        bmpLast[i] = -1;
    }

    for(size_t i = 0; i < pattern.size(); i++){
        bmpLast[pattern[i]] = i;
    }
    return bmpLast;
}



Character Jump Heuristics

Case 1:
The character mismatch occurs at the location T[t] = 'x' and the character 'x' is found to the left of the character P[p] = 'c' OR 1 + f(T[t]) <= p. In this case move pattern P to the right to align last occurrence of x in P with x in T

tnew = t + length of pattern - ( 1 + last occurrence of 'x' in pattern)
pnew = length of pattern - 1

Case 2:
The character mismatch occurs at the location T[t] = 'x' and the character 'x' is found to the right of the character P[p] = 'c' OR 1 + f(T[t]) > p. In this scenario alignment is not possible by moving the pattern to the right on the basis of last occurrence. Here we shift the pattern by 1 so that P[p] = c aligns with T[t+1] = a
tnew = t + length of pattern - p
pnew = length of pattern - 1

Case 3:
If the case 1 and case 2 cannot be applied, that means the character T[t] is not found in the pattern P. In this case, we move the pattern P so that P[0] = x aligns itself with T[t+1] = a

tnew = t + length of pattern
pnew = length of pattern - 1

//Character Jump Heuristics
int lastOccur = bmpLast[text[tIdx]];
if(lastOccur != -1){
    if(pIdx > lastOccur){// Case 1: last occurrence of char is to left or equal to the mismatch point 
        tIdx = tIdx + patternSize - (1 + lastOccur);
        pIdx = patternSize - 1;
    }
    else{// Case 2: last occurrence of char is to right of the mismatch point
        tIdx = tIdx + patternSize - (pIdx);
        pIdx = patternSize - 1;
    }
}
else{// Case 3: character is not found in the pattern string
    tIdx = tIdx + patternSize;
    pIdx = patternSize - 1;
}

Merging Case 1 and Case 2 in the above code
//Character Jump Heuristics
int lastOccur = bmpLast[text[tIdx]];
if(lastOccur != -1){
    tIdx = tIdx + patternSize - min<int>(pIdx, 1 + lastOccur);
}
else{// Case 3: character is not found in the pattern string
    tIdx = tIdx + patternSize;
}
pIdx = patternSize - 1;

In our case as computeBmpLast() function stores -1 for characters not found in the search pattern. We can safely merge the Case 3 in the above code to look as
//Character Jump Heuristics
int lastOccur = bmpLast[text[tIdx]];
tIdx = tIdx + patternSize - min<int>(pIdx, 1 + lastOccur);
pIdx = patternSize - 1;

Example:




Complete Code Example
#ifndef _PatternMatcher_H_
#define _PatternMatcher_H_
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class PatternMatcher{
public:
    static int bmpSearch(const string& text, const string& pattern);

private:
    static vector<int> computeBmpLast(const string& pattern);

    PatternMatcher();
    PatternMatcher(const PatternMatcher&);
    const PatternMatcher& operator=(const PatternMatcher&);
};
#endif //_PatternMatcher_H_

#include "PatternMatcher.h"
#include <algorithm>

using namespace std;

int PatternMatcher::bmpSearch(const std::string &text, const std::string &pattern){
    size_t textSize = text.size();
    size_t patternSize = pattern.size();
    if(textSize == 0 || patternSize == 0){
        return -1;
    }
    if(patternSize > textSize){
        return -1;
    }

    vector<int> bmpLast = computeBmpLast(pattern);
    size_t tIdx = patternSize - 1;
    size_t pIdx = patternSize - 1;
    while(tIdx < textSize){
        if(pattern[pIdx] == text[tIdx]){
            if(pIdx == 0){   //found a match
                return tIdx;
            }
            tIdx--;
            pIdx--;
        }
        else {
            //Character Jump Heuristics
            int lastOccur = bmpLast[text[tIdx]];
            tIdx = tIdx + patternSize - min<int>(pIdx, 1 + lastOccur);
            pIdx = patternSize - 1;
        }
    }
    return - 1;
}

vector<int> PatternMatcher::computeBmpLast(const std::string &pattern){
    const size_t NUM_ASCII_CHARS = 128;
    vector<int> bmpLast(NUM_ASCII_CHARS);
    for(size_t i = 0; i < NUM_ASCII_CHARS; i++){
        bmpLast[i] = -1;
    }
    for(size_t i = 0; i < pattern.size(); i++){
        bmpLast[pattern[i]] = i;
    }
    return bmpLast;
}

#include "PatternMatcher.h"

int main(){
    cout << PatternMatcher::bmpSearch
        ("abacaabaccabacabaabb", "abacab")
        << endl;
    cout << PatternMatcher::bmpSearch
        ("abacaabaccabacabaabb", "baabb")
        << endl;
    cout << PatternMatcher::bmpSearch
        ("abacaabaccabacabaabb", "abacad")
        << endl;
    cout << PatternMatcher::bmpSearch
        ("abacaabaccabacabaabb", "abacaab")
        << endl;
    cout << PatternMatcher::bmpSearch
        ("abacaabaccabacabaabb", "abacab")
        << endl;
    cout << PatternMatcher::bmpSearch
        ("abacaabaccabacabaabb", "aabaccaba")
        << endl;
    cout << PatternMatcher::bmpSearch
        ("abacaabaccabacabaabb", "abacaabaccabacabaabb")
        << endl;
    cout << PatternMatcher::bmpSearch
        ("abacaabaccabacabaabb", "")
        << endl;
    cout << PatternMatcher::bmpSearch
        ("", "abacaabaccabacabaabb")
        << endl;
    cout << PatternMatcher::bmpSearch
        ("abacaabaccabacabaabb", "bacaabaccabacabaab")
        << endl;
    cout << PatternMatcher::bmpSearch
        ("abacaabaccabacabaabb", "abacaabac")
        << endl;
    cout << PatternMatcher::bmpSearch
        ("abacaabaccabacabaabb", "ccabacabaabb")
        << endl;
    cout << PatternMatcher::bmpSearch
        ("abacaabaccabacabaabb", "bacaabaccabacabaabb")
        << endl;

    return 0;
}


Read more ...

Apr 3, 2010

Visual Studio - Auto formatting your code

Whenever you paste any code from other applications into a source file within Visual Studio, the formatting gets messed up. You can use the following tip to format the code if written in C++, C# and VB

Steps

1. Select the text portion to format OR (Ctrl + a)
2. Hold Ctrl and hit k followed by f (Ctrl + k + f)


Read more ...

Apr 1, 2010

Internet Explorer vs Firefox Keystroke detection

The DOM Level 2 Event specification does not provide a key event module. An event module designed for use with keyboard input devices will be included in a later version of the DOM specification.

With the lack of a specification and browser vendors coming out with their own implementation of Key Events, the compatibility issues between the browsers is bound to appear


#1. Code for handling keyboard event in Internet Explorer
<html>
<head>
<script type="text/javascript">

function keyDownListener()
{
    var key;
    key = window.event.keyCode;
    alert('Key Code ' + key);
    document.keyForm.textBox.value = "";
    return false;
}

</script>
</head>
<body>
<form name="keyForm" id="keyform">
<input type="text" name="textBox" id="textBox" size="20" oncontextmenu="return false" onkeydown="return keyDownListener()" />
</form>
</body>
</html>



#2. Code for handling keyboard event in the case of firefox
<html>
<head>
<script type="text/javascript">

function keyPressListener(myEvent)
{
    var key;
    key = myEvent.keyCode;
    alert('Key Code ' + key);
    document.keyForm.textBox.value = "";
    return false;
}

</script>
</head>
<body>
<form name="keyForm" id="keyform">
<input type="text" name="textBox" id="textBox" size="20" oncontextmenu="return false" onkeypress="return keyPressListener(event)" />
</form>
</body>
</html>



#3. Compatibility issues between firefox and internet explorer for key press event
<html>
<head>
<script type="text/javascript">

function IsIE()
{
    if (navigator.userAgent.indexOf("Firefox")!=-1)
        return false;
    if (navigator.userAgent.indexOf("MSIE")!=-1)
        return true;
}

function keyDownListener(e)
{
    var key, browser;
    alert('Key Down Listener');

    if ( IsIE() ){
        key = window.event.keyCode;
        browser = "Internet Explorer";
    }
    else{
        key = e.keyCode;
        browser = "Firefox";
    }
    alert("Browser: [" + browser + "] Key Code: [" + key + "]");
    document.keyForm.textBox.value = browser;
    return false;
}

function keyPressListener(e)
{
   var key, browser;
   alert('Key Press Listener');

if ( IsIE() ){
        key = window.event.keyCode;
        browser = "Internet Explorer";
    }
    else{
        key = e.keyCode;
        browser = "Firefox";
    }

alert("Browser: [" + browser + "] Key Code: [" + key + "]");
    document.keyForm.textBox.value = browser;
    return false;
}

function detectBrowser()
{
    if(IsIE())
        document.keyForm.textBox.value="Internet Explorer";
    else
        document.keyForm.textBox.value="Firefox";
}

</script>
</head>
<body onload="return detectBrowser()">
<form name="keyForm" id="keyform">
<input type="text" name="textBox" id="textBox" size="20" oncontextmenu="return false" onkeydown="return keyDownListener(event)" onkeypress="return keyPressListener(event)" />
</form>
</body>
</html>


References:
Detecting Keystrokes
Key Events

Read more ...

Mar 28, 2010

A const Reference and a Reference to const object

A reference serves as an alternative name or alias to an object. We cannot define reference to a reference type, but can make a reference to any other data type. C++ imposes several limitations on references. In particular, C++ does not allow you to change which memory a reference points to. Thus, all references are effectively 'const' references. Like normal constant objects, references must be given a value upon declaration.

What should we use then?

MyString& const ref = obj;
OR
MyString const &ref = obj;



Read more ...

Mar 27, 2010

vimrc explained

VIM editor is one of the most popular text editor amongst the developers. At first look, it appears to be a daunting task to get used to it but once you get the hang of the unlimited functionality it offers at your hand, there is no going back and you will fell in love with the tool

A customized ~/.vimrc file

:syntax on        "Turn on syntax highlighting
:set laststatus=2 "Always show status line

:set autowrite    "Automatically write a file when leaving a modified buffer
:set confirm      "Start a dialog when a command fails (here when quit command fails)
:set tabstop=4    "Number of spaces a TAB in the text stands for

:set shiftwidth=4 "Number of spaces used for each step of (auto)indent
:set hlsearch     "Have vim highlight the target of a search
:set incsearch    "Do incremental searching

:set ruler        "Show the cursor position all the time
:set number       "Show line numbers
:set ignorecase   "Ignore case when searching

:set title        "Show info in the window title
:set titlestring=PANKAJ:\ %F   
    "Automatically set screen title

:set noautoindent
:set nosmartindent
:set nocindent


"Indent only if the file is of type cpp,c,java,sh,pl,php,asp
:au FileType cpp,c,java,sh,pl,php,asp  set autoindent
:au FileType cpp,c,java,sh,pl,php,asp  set smartindent
:au FileType cpp,c,java,sh,pl,php,asp  set cindent

"Wrapping long lines
:set wrapmargin=4   "Margin from the right in which to break a line. Set this value to 4 or 5

:set textwidth=70   "Line length above which to break a line

"Defining abbreviations
:ab #d #define
:ab #i #include


"Defining abbreviations to draw comments
:ab #b /********************************************************
:ab #e ********************************************************/
:ab #l /*------------------------------------------------------*/

"Converting tabs to spaces
:set expandtab

VIM Editor Tips

Navigating through VIM

Down (j), Up (k), left (h), right (l)
w (word forward), b (word backward)
W (word forward skip punctuation), B (word backward skip punctuation)
Page Down (Ctrl-f)
Page Up (Ctrl-b)
End of Line ($)
Start of Line (0)
Start of document (gg)
End of Document (G)
Jump to last place that you made an edit (g;)


Copy Pasting Contents

Surprisingly VIM inserts a lot of extra spaces when code is pasted from other applications. This can be corrected by executing the following in VIM mode

:set paste
OR
gg=G

Indentations can be corrected by running the following command in the system

indent -kr filename


Working with Visual Blocks

It is a feature that allows you to mark a block of text and perform editing operations on them. To enter visual blocks mode, press Ctrl+v, then use hjkl or arrow keys to highlight a block of text. Now operate on the first highlighted line as if you were in normal mode

Visual mode (v)
Visual line mode (V)
Visual block mode (Ctrl-v)


Converting tabs to spaces

Make sure you have :set expandtab set in your .vimrc file or otherwise execute set expandtab in normal mode and then run the following command to convert all tabs to spaces

:retab


Wrap a long line

Use (gq) to wrap the highlighted peice of text


Auto-Complete

Start typing the variable/function names and then (Ctrl-n) or (Ctrl-p) next and previous


Delete

delete character (x)
delete word (dw)
delete line (dd)


Auto-Indent

line (==)
entire document (gg=G)


Find/Replace

%s/oldword/newword/g OR %s#oldword#newword#g
%s/oldword/newword/gc OR %s#oldword#newword#gc


Split Windows

Horizontal Windows :split
Vertical Windows :vs
Shifting between Windows (Ctrl-shift-ww)


Map Commands

If you find yourself re-typing the same command over and over, map it to one of the function keys as follows:

:map <fx> cmd

This maps the command cmd to function key Fx. For example, to map F5 to the command :!gcc -c % (compiles the current file) in normal mode


Code Folding

For large code blocks, you might want to fold/hide away certain functions temporarily. To fold a selection, select it in visual then (zf). To open a fold (zo)


Changing the Line Number Background and Foreground color

:highlight LineNr guibg=grey
:highlight LineNr guifg=blue
:highlight LineNr ctermfg=white ctermbg=grey


Read more ...