Wednesday, December 28, 2005

Session saving and Firefox 1.5

I use mainly Firefox 1.5 as internet browser, and my friends call me "the thousand tabs man" for joke because I often have many tabs open. So, it's important for me to keep these tabs even when I close my pc or when I experience a firefox crash.

So I tried to look for an extension that provides this feature, and I installed SessionSaver 2. All ok with old Firefox < 1.5, but with the latest version I get some problems: the worst one is the "unresponsive script" warning that I get during operation such as file uploads, even when the file is small. It seems as the SessionSaver script computes some operations that stick it in an infinite loop or something similar, because if I click on "stop script" button the upload completes correctly.

I removed SessionSaver extension, and asked in the official forum (it's not properly a forum, is a post on mozillazine forum with actual 122 pages, not very well organized in my opinion), and found there a link to another extension: TabMixPlus.

The image on the left shows you part of session saving options you can choose. It has also a lot of other useful features, such as multi level undo close tab - I used to install a separate extension for this, called UndoCloseTab - and page loading progress bar on the tab and, if you want, in statusbar too. I still have to explore all its features, but the only one I really needed works perfectly, and I have my tab session always present even in case of system crash.

You can download TabMixPlus here:
http://tmp.garyr.net/beta%200.3/

Official MozillaZine thread about TabMixPlus is here:
http://forums.mozillazine.org/viewtopic.php?t=327222

It's still a beta version, but it seems to work well. Many thanks to the author(s).

Monday, December 12, 2005

Forcing postgreSQL 8.0 default encoding

If anyone knows a better way to set the default encoding please let me know it.
I also tried the -E option to specify SQL_ASCII encoding when running initdb, but it gave me error messages, complaining about compatibility with my locale (ISO8859-1).

So I logged in as root, switched to postgres user, then launched psql console connected to template1 database.

# su - postgres
$ psql template1
Welcome to psql 8.0.3, the PostgreSQL interactive terminal.

Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit


then I performed the following command to see which encoding is set for the template database:

template1=# select datname, encoding from pg_database;
datname | encoding
-----------+----------
template1 | 6
template0 | 6
(2 rows)


I discovered that 6 stands for UNICODE. Don't tell me why, cause I don't know, the encoding attribute is shown here as an integer but everywhere its type is a varchar.

So, let's set it as SQL_ASCII (integer 0):

template1=# update pg_database set encoding = 0;
UPDATE 2
template1=# select datname, encoding from pg_database;
datname | encoding
-----------+----------
template1 | 0
template0 | 0
(2 rows)


Then I created a new database:

template1=# create database pippo;
CREATE DATABASE
template1=# select datname, encoding from pg_database;
datname | encoding
-----------+----------
template1 | 0
template0 | 0
pippo | 0
(3 rows)


Hoorray! I got it. Party time now.

Wednesday, December 07, 2005

Writing a program plugin in C++

Today I found myself trying to imagine how to call a function (or more in general to load a library) at runtime. I know shared object, also called DLL on windows world, can be useful for this, but I never wrote a program that uses dynamic linking.

To do so, I read something about dlfcn.h, a standard library for loading shared object at runtime. Let's see how to use it.

At first, create the shared object:

----hello.cpp----

#include <iostream>

using namespace std;

extern "C" void hello()
{
    cout << "hello world!" << endl;
}


compile it as a shared object:

$ g++ hello.cpp -o hello.so -shared


now create the main program file:

----main.cpp----

#include <iostream>
#include <dlfcn.h>

using namespace std;

int main( int argc, char *argv[] )
{
    void * handle = dlopen( "./hello.so", RTLD_LAZY );

    if( !handle )
    {
        cerr << "Cannot open library: " << dlerror() << endl;
        return 1;
    }

    typedef void (*hello_t)();

    hello_t hello = (hello_t) dlsym(handle, "hello");

    if( !hello )
    {
        cerr << "Cannot load symbol 'hello': " << dlerror() << endl;
        dlclose(handle);
        return 1;
    }

    hello();

    dlclose( handle );

    return 0;
}


compile it as usual:

$ g++ main.cpp -o main -ldl


now we have a shared object, hello.so with hello() function compiled inside it. We also have the main program.
The (almost) obvious output will be:

$ ./main
hello world!


source:
http://www.tldp.org/HOWTO/C++-dlopen/index.html

more informations:
http://www.faqs.org/docs/Linux-HOWTO/Program-Library-HOWTO.html