Welcome

Wheresoever you go, go with all your heart. (Confucius)

6/03/2011

libconfig - C/C++ Configuration File Library

Libconfig is a great library which can process configuration files base on structured format such as XML.
According tohttp://www.hyperrealm.com/libconfig/, this file format is more compact and more readable than XML. Advantages are the follows:

  1. type-aware: by parser, it is automatically bound to the appropriate type such as int, float, array, and string.
  2. support both the C and C++
  3. works on various operating systems: GNU/Linux, Mac OS X, Solaris, FreeBSD, and Windows (2000, XP, and later)


I tested whether or not it works on Windows 7 and Visual studio 2005. The result is very successful.
Here is a sample configuration file.
#----------------------------
# Example Configuration File
#---------------------------
#

application:
{

 /* This section defines some settings for our
  * main application window, such as size and
  * position.
  */

  window:
  {
    title = "My Application";
    size = { /* width */ w = 640; /* height */ h = 480; };
    pos = { x = 350; y = 250; };
  };

  a = 5;
  b = 6;
  ff = 1E6;
  test-comment = "/* hello\n \"there\"*/";

  test-long-string = "A very long string that spans multiple lines. "
  /* but wait, there's more... */ "Adjacent strings are automatically"
  " concatenated.";

  test-escaped-string = "\"This is\n a test.\"";

  group1:
  {
    x = 5;  y = 10;
    my_array = [ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22 ];
    flag = TRUE;

    group2: { zzz = "this is a test"; };

    states = [ "CT", // Connecticut
  "CA", // California
  "TX", // Texas
  "NV", // Nevada
  "FL"  // Florida
    ];
  };

  /* this would cause an error */
  // a = "hi!";
};

binary = [ 0xAA, 0xBB, 0xCC ];

list = ( ( "abc", 123, true ), 1.234, ( /* an empty list */ ) ,[ 1, 2, 3 ],
    { a = (1, 2, true); } );

books = ( "inventory",
          { title  = "Treasure Island";
            author = "Robert Louis Stevenson";
            price  = 29.99;
            qty    = 5; },
          { title  = "Snow Crash";
            author = "Neal Stephenson";
            price  = 9.99;
            qty    = 8; },
          { } );

# miscellaneous stuff

misc:
{
  port = 5000;
  pi = 3.14159265;
  enabled = FALSE;
  mask = 0xAABBCCDD;
  unicode = "STARGΛ̊TE SG-1"; // UTF-8 string
  bigint = 9223372036854775807L;
  bighex = 0x1122334455667788L;
};


### eof

As shown in the sample configuration above, this is so very powerful that I love the libconfig library.
Finally, I provide a sample code to read a configuration file.


#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <libconfig.h++>
using namespace std;
using namespace libconfig;
// This example reads the configuration file 'example.cfg' and displays
// some of its contents.
int main(int argc, char **argv)
{
  Config cfg;
  // Read the file. If there is an error, report it and exit.
  try
  {
    cfg.readFile("example.cfg");
  }
  catch(const FileIOException &fioex)
  {
    std::cerr << "I/O error while reading file." << std::endl;
    return(EXIT_FAILURE);
  }
  catch(const ParseException &pex)
  {
    std::cerr << "Parse error at " << pex.getFile() << ":" << pex.getLine()
              << " - " << pex.getError() << std::endl;
    return(EXIT_FAILURE);
  }
  // Get the store name.
  try
  {
    string name = cfg.lookup("name");
    cout << "Store name: " << name << endl << endl;
  }
  catch(const SettingNotFoundException &nfex)
  {
    cerr << "No 'name' setting in configuration file." << endl;
  }
  const Setting& root = cfg.getRoot();
  // Output a list of all books in the inventory.
  try
  {
    const Setting &books = root["inventory"]["books"];
    int count = books.getLength();
    cout << setw(30) << left << "TITLE" << "  "
         << setw(30) << left << "AUTHOR" << "   "
         << setw(6) << left << "PRICE" << "  "
         << "QTY"
         << endl;
    for(int i = 0; i < count; ++i)
    {
      const Setting &book = books[i];
      // Only output the record if all of the expected fields are present.
      string title, author;
      double price;
      int qty;
      if(!(book.lookupValue("title", title)
           && book.lookupValue("author", author)
           && book.lookupValue("price", price)
           && book.lookupValue("qty", qty)))
        continue;
      cout << setw(30) << left << title << "  "
           << setw(30) << left << author << "  "
           << '$' << setw(6) << right << price << "  "
           << qty
           << endl;
    }
    cout << endl;
  }
  catch(const SettingNotFoundException &nfex)
  {
    // Ignore.
  }
  // Output a list of all books in the inventory.
  try
  {
    const Setting &movies = root["inventory"]["movies"];
    int count = movies.getLength();
    cout << setw(30) << left << "TITLE" << "  "
         << setw(10) << left << "MEDIA" << "   "
         << setw(6) << left << "PRICE" << "  "
         << "QTY"
         << endl;
    for(int i = 0; i < count; ++i)
    {
      const Setting &movie = movies[i];
      // Only output the record if all of the expected fields are present.
      string title, media;
      double price;
      int qty;
      if(!(movie.lookupValue("title", title)
           && movie.lookupValue("media", media)
           && movie.lookupValue("price", price)
           && movie.lookupValue("qty", qty)))
        continue;
      cout << setw(30) << left << title << "  "
           << setw(10) << left << media << "  "
           << '$' << setw(6) << right << price << "  "
           << qty
           << endl;
    }
    cout << endl;
  }
  catch(const SettingNotFoundException &nfex)
  {
    // Ignore.
  }
  return(EXIT_SUCCESS);
}

libconfig - C/C++ Configuration File Library

Libconfig is a great library which can process configuration files base on structured format such as XML.
According tohttp://www.hyperrealm.com/libconfig/, this file format is more compact and more readable than XML. Advantages are the follows:

  1. type-aware: by parser, it is automatically bound to the appropriate type such as int, float, array, and string.
  2. support both the C and C++
  3. works on various operating systems: GNU/Linux, Mac OS X, Solaris, FreeBSD, and Windows (2000, XP, and later)


I tested whether or not it works on Windows 7 and Visual studio 2005. The result is very successful.
Here is a sample configuration file.
#----------------------------
# Example Configuration File
#---------------------------
#

application:
{

 /* This section defines some settings for our
  * main application window, such as size and
  * position.
  */

  window:
  {
    title = "My Application";
    size = { /* width */ w = 640; /* height */ h = 480; };
    pos = { x = 350; y = 250; };
  };

  a = 5;
  b = 6;
  ff = 1E6;
  test-comment = "/* hello\n \"there\"*/";

  test-long-string = "A very long string that spans multiple lines. "
  /* but wait, there's more... */ "Adjacent strings are automatically"
  " concatenated.";

  test-escaped-string = "\"This is\n a test.\"";

  group1:
  {
    x = 5;  y = 10;
    my_array = [ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22 ];
    flag = TRUE;

    group2: { zzz = "this is a test"; };

    states = [ "CT", // Connecticut
  "CA", // California
  "TX", // Texas
  "NV", // Nevada
  "FL"  // Florida
    ];
  };

  /* this would cause an error */
  // a = "hi!";
};

binary = [ 0xAA, 0xBB, 0xCC ];

list = ( ( "abc", 123, true ), 1.234, ( /* an empty list */ ) ,[ 1, 2, 3 ],
    { a = (1, 2, true); } );

books = ( "inventory",
          { title  = "Treasure Island";
            author = "Robert Louis Stevenson";
            price  = 29.99;
            qty    = 5; },
          { title  = "Snow Crash";
            author = "Neal Stephenson";
            price  = 9.99;
            qty    = 8; },
          { } );

# miscellaneous stuff

misc:
{
  port = 5000;
  pi = 3.14159265;
  enabled = FALSE;
  mask = 0xAABBCCDD;
  unicode = "STARGΛ̊TE SG-1"; // UTF-8 string
  bigint = 9223372036854775807L;
  bighex = 0x1122334455667788L;
};


### eof

As shown in the sample configuration above, this is so very powerful that I love the libconfig library.
Finally, I provide a sample code to read a configuration file.


#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <libconfig.h++>
using namespace std;
using namespace libconfig;
// This example reads the configuration file 'example.cfg' and displays
// some of its contents.
int main(int argc, char **argv)
{
  Config cfg;
  // Read the file. If there is an error, report it and exit.
  try
  {
    cfg.readFile("example.cfg");
  }
  catch(const FileIOException &fioex)
  {
    std::cerr << "I/O error while reading file." << std::endl;
    return(EXIT_FAILURE);
  }
  catch(const ParseException &pex)
  {
    std::cerr << "Parse error at " << pex.getFile() << ":" << pex.getLine()
              << " - " << pex.getError() << std::endl;
    return(EXIT_FAILURE);
  }
  // Get the store name.
  try
  {
    string name = cfg.lookup("name");
    cout << "Store name: " << name << endl << endl;
  }
  catch(const SettingNotFoundException &nfex)
  {
    cerr << "No 'name' setting in configuration file." << endl;
  }
  const Setting& root = cfg.getRoot();
  // Output a list of all books in the inventory.
  try
  {
    const Setting &books = root["inventory"]["books"];
    int count = books.getLength();
    cout << setw(30) << left << "TITLE" << "  "
         << setw(30) << left << "AUTHOR" << "   "
         << setw(6) << left << "PRICE" << "  "
         << "QTY"
         << endl;
    for(int i = 0; i < count; ++i)
    {
      const Setting &book = books[i];
      // Only output the record if all of the expected fields are present.
      string title, author;
      double price;
      int qty;
      if(!(book.lookupValue("title", title)
           && book.lookupValue("author", author)
           && book.lookupValue("price", price)
           && book.lookupValue("qty", qty)))
        continue;
      cout << setw(30) << left << title << "  "
           << setw(30) << left << author << "  "
           << '$' << setw(6) << right << price << "  "
           << qty
           << endl;
    }
    cout << endl;
  }
  catch(const SettingNotFoundException &nfex)
  {
    // Ignore.
  }
  // Output a list of all books in the inventory.
  try
  {
    const Setting &movies = root["inventory"]["movies"];
    int count = movies.getLength();
    cout << setw(30) << left << "TITLE" << "  "
         << setw(10) << left << "MEDIA" << "   "
         << setw(6) << left << "PRICE" << "  "
         << "QTY"
         << endl;
    for(int i = 0; i < count; ++i)
    {
      const Setting &movie = movies[i];
      // Only output the record if all of the expected fields are present.
      string title, media;
      double price;
      int qty;
      if(!(movie.lookupValue("title", title)
           && movie.lookupValue("media", media)
           && movie.lookupValue("price", price)
           && movie.lookupValue("qty", qty)))
        continue;
      cout << setw(30) << left << title << "  "
           << setw(10) << left << media << "  "
           << '$' << setw(6) << right << price << "  "
           << qty
           << endl;
    }
    cout << endl;
  }
  catch(const SettingNotFoundException &nfex)
  {
    // Ignore.
  }
  return(EXIT_SUCCESS);
}

6/02/2011

Windows 8: Building Video

Microsoft revealed a new operating system, windows 8.
The below movie shows the working by Touch Screen.
Maybe, it is optimized for Tablet PC.


6/01/2011

Automatically Scheduling of SyncToy

SyncToy doesn't have the feature to allow user to schedule folders to run synchronization process.
But, we can use Task Scheduler of Windows 7.

[Procedure]

  1. Click Task Scheduler, Location: Start menu - All Programs - Accessories - System Tools - Task Scheduler
  2. Click Create Basic Task in the Actions
  3. Type in a Name and Description
  4. Click Next button
  5. Select the frequency of when you want the task to start
  6. Click Next button
  7. Input date and times
  8. Click Next button
  9. Select Start a program
  10. Click Next button
  11. In Program/script, Locate the SyncToyCmd.exe
  12. In Add arguments, Type -R which run all folder pairs that are active for run all. If you want to run just a single folder pair, add -R"Folder pair name" to the end of the command line
  13. Click Next button

log4cplus - Logging library to C++ such as log4j

log4cplus is the excellent logging library to C++ such as log4j.
You can see at log4cplus.sourceforge.net.
Current version is 1.0.4, released on January 2011.

I tested this library on Visual studio 2005.
It is based on Win32 platform, so you can easily build it.
The following example is to save logging information into a specified log file.


 <Code Example>

#include <log4cplus/logger.h>
#include <log4cplus/configurator.h>
#include <log4cplus/fileappender.h>
using namespace log4cplus;
int main()
{
    SharedAppenderPtr myAppender(new FileAppender("LogFile.log"));
    BasicConfigurator config;
    config.configure();
    logger = Logger::getInstance("main");
    logger.addAppender(myAppender);
    logger.setLogLevel(ALL_LOG_LEVEL);
    LOG4CPLUS_WARN(logger, "Warning Test");
    return 0;
}

Centos - Sudoers file

In Centos, to use the command "sudo", you add a user information to /etc/sudoers.

For example, Basically root is "root ALL=(ALL) ALL"

You can modify this file for new sudo user.
username ALL=(ALL)ALL