Catégorie : développement

Tout ce qui concerne le développement en général, que ce soit des choses générales, ou des choses bien précises. Cela va de la gestion de projet à la recherche du fonctionnement de pointeurs en C.

Windows Vista : Apache : quand php ne charge pas le fichier php.ini

Votre fichier « php.ini » n’est pas chargé au démarrage d’Apache sous Windows Vista ?

Pas de problème. C’est très simple. Éditez votre fichier Apache de configuration, habituellement httpd.conf.
Juste avant la ligne de directive qui dit de charger le module Apache, il faut ajouter la directive PHPIniDir "C:/PHP" qui précise où doit se situer le fichier php.ini.

Exemple :

PHPIniDir "C:/PHP"
LoadModule php5_module "C:/PHP/php5apache2_2.dll"

Je ne vous parle pas de l’autre méthode moins efficace : lancer Notepad en tant qu’administrateur, ouvrir le fichier php.ini puis le sauver sous le répertoire C:\Windows (c’est le répertoire de configuration par défaut de php).
Je viens de passer plus de deux heures complètes avant de réussir ce qui me prend en temps normal, sur Linux et Windows XP, 5 minutes. Décidément, Vista est vraiment de la daube sous tous les points de vue.

Linux : changer les droits que sur des répertoires et sous répertoires

Voilà le problème :

Vous voulez mettre des droits en lecture uniquement sur tous les fichiers mais laisser le droit "x" sur les répertoires.

Voilà la solution la plus simple que j’ai décomposée volontairement pour être plus clair :

  1. Supprimer toutes les autorisations :
    chmod -R 0 ./*
  2. Ajouter les autorisations en lecture pour tout le monde :
    chmod -R ugo+r ./*
  3. Ajouter les autorisations en écriture uniquement pour le possesseur des fichiers :
    chmod -R u+w ./*
  4. Et la petite astuce pour que les autres puissent lire les répertoires et sous-répertoires :
    Appliquer le "x" uniquement sur les répertoires et sous répertoires (et pas sur les fichiers) :
    find . -type d | xargs chmod ugo+x

En résumé, copiez collez cette ligne :
chmod -R 0 ./* && chmod -R ugo+r ./* && chmod -R u+w ./* && find . -type d | xargs chmod ugo+x

Et vous aurez pour tout le monde le droit en lecture des répertoire et sous répertoires et le droit en écriture uniquement donné à l’utilisateur courant.
Attention : il n’y aura pas de fichier exécutable, car les autorisations "x" seront enlevées.

The Gimp : mémo de la syntaxe Script-Fu

Script-Fu est le langage de script pour automatiser The Gimp. Voici un mémo pour ceux qui veulent faire rapidement du Script-Fu.

Résumé Script-Fu

  • Style d’écriture : notation Polonaise inversée : (+ 1 2) donnera 3
  • Tout est entre parenthèses. Même une fonction qui n’a pas de paramètres.
    Exemple de fonction qu’on appelle sans passer de paramètres : (gimp-image-list)
  • Tout s’écrit sous la forme :
    (f x1 . . . xn)
    Et f est une fonction, ou un mot-clé.
    Exemples de mots-clé : if, and, or, let, define, car
  • Le code (define <symbole> <expression>)
    sert à définir un <symbole> qui devient une variable globale.
    Un <symbole> peut être une fonction ;
  • Définition d’une fonction :
    (define (myfunc param1 . . . paramn) (corps de la fonction))
    Sachant que param1 . . . paramn sont les paramètres à passer à la fonction ;
  • Les constantes booléennes vrai / faux sont notées #t (=true) et #f (=false).
    Exemples :
    > (integer? (sqrt 2))
    #f
    > (integer? 4)
    #t
  • Exemple : (gimp-image-list)

NB : ce mémo est destiné à faire rapidement du Script-Fu. Rien de plus !

The Gimp : exemple simple Script-Fu

Detail pas à pas de la création d’un listing :

  • Decription de la fonction gimp-image-list :
    Cette fonction renvoie une liste :

    • premier élément = nombre d’images
    • ce qui suit = pointeurs sur les images
  • Code classique d’appel de la fonction :
    (gimp-image-list)
  • Assigner à imgs le tableau résultat de (gimp-image-list) :
    let (imgs (gimp-image-list) )
  • Si on veut immédiatement se resservir de la valeur de imgs, il faut utiliser let *
    Donc :
    let* (
    (imgs (gimp-image-list))
    )
  • Mettre le nombre d’images dans la variable nb-imgs :
    let* (
    (imgs (gimp-image-list))
    (nb-imgs (car imgs))
    )
  • Mettre le reste du tableau dans la variable img-array :
    let* (
    (imgs (gimp-image-list))
    (nb-imgs (car imgs))
    (img-array (cadr imgs))
    )

The Gimp et Script-fu : afficher tous les ordres disponibles

L’une des fonctions les plus intéressantes de The Gimp est la possibilité d’écrire des scripts afin d’automatiser les manipulations. Ces scripts sont écrit en langage « Script-Fu« .
Si vous avez un peu fait de Script-Fu, voilà une astuce pour afficher rapidement tous les ordres disponibles en Script-Fu pour The Gimp version 2.6.3.

  1. Allez dans le menu Script, choisissez « Script-Fu », et dans le sous-menu, choisissez : « console » : Script-Fu 01
  2. Une fenêtre de console s’ouvre. Cliquez sur le bouton « parcourir » : Script-Fu 02
  3. Et là vous avez le navigateur qui affiche tous les Script-Fu disponibles, vous pouvez en voir les sources et faire ce que vous voulez avec : Script-Fu 03
  4. Mais vous pouvez faire mieux : tapez « new » et ainsi vous aurez pratiquement tous les ordres « Script-Fu » qui servent à créer un nouvel objet : ainsi vous saurez quels sont tous les objets qu’il est possible de créer sous The Gimp :
    Script-Fu 04

Delphi : TClientDataSet, TDataSetProvider et TTable

Je développe en Delphi depuis plusieurs années et je me suis remis à la base de données il y a peu.

Donc je fais un petit mémo expliquant ce que j’ai compris, en espérant que cela fera gagner du temps à ceux qui n’y arrivent pas, et en sautant les étapes de l’aide Delphi, qui, quoique très précise et détaillée, aurait tendance dans un premier temps à plus nous embrouiller qu’autre chose.

Dans une application « orientée base de données », il faut tout d’abord afficher les données. Il y a les composants de données, qui commencent tous par TDB (TDBGrid, TDBEdit, TDBMemo etc.). On prend le composant, on le dépose sur la fiche. On a une « DBGrid1 » qui s’affiche.

Ensuite, il faut aller chercher les données qu’on veut afficher. Une « source de données ». En Anglais, un composant « TDataSource ». On prend le composant, on le pose sur la fiche, on initialise la propriété « DataSource » de notre « DBGrid1 » à « DataSource1 ».

Ensuite, ce composant « source de données » doit aller chercher les données quelque part. Mais où ? Eh bien chez un « serveur de données ». Pour cela il nous faut un objet appelé le client. Ça peut paraitre bizarre, mais on l’appelle « client » parce que c’est lui qui ira demander des informations à un serveur de données. C’est le client de données du serveur de données. Donc un client d’ensemble de données, en Anglais : « TClientDataSet ». On prend un composant « TClientDataSet », on le pose sur la fiche, et on initialise la propriété « DataSet » de « DataSource1 » à « ClientDataSet1 ».

Ce fameux Client, lui, doit donc se connecter à un serveur de données. C’est intéréssant dans la mesure ou ce fameux serveur peut être « hors » de l’application, sur un autre ordinateur, mais faisons simple : on va supposer que ce serveur est directement intégré à l’application. On utilise donc un composant fournisseur de données, en Anglais : « TDataSetProvider ». On prend un composant « TDataSetProvider », on le pose sur la fiche, et on initialise la propriété « ProviderName » de « ClientDataSet1 » à « DataSetProvider1 ».

On y est presque !

Il reste le côté purement physique, c’est à dire l’objet réel qui ira lire les informations. Nous allons prendre un objet TTable. (Il y a les objet TIBTable pour Interbase, TMyTable pour MySQL, TSQLTable pour dbExpress, bref, plein de tables dont on se sert de la même manière que TTable). On prend un composant « TTable, on le pose sur la fiche, et on initialise la propriété « DataSet » de « DataSetProvider1 » à « Table1 ».

Voilà l’image résultat :
Résultat Delphi TClientDataSet, TDataSetProvider, et TTable

Voilà le trajet des informations :

Lorsque la grille de données voudra lire des informations pour les afficher, la demande suivra ce trajet :

DBGrid1 => DataSource1 => ClientDataSet1 => DataSetProvider1 => Table1

et la Table ira lire les bonnes informations, et créera une réponse. La réponse fera le trajet inverse :

Table1 => DataSetProvider1 => ClientDataSet1 => DataSource1 => DBGrid1

L’intérêt d’avoir autant de composants c’est qu’on peut faire deux applications : le client qui affiche les données, et le serveur, qu’on peut mettre sur un autre ordinateur.

Il est possible de « couper » directement la route et de ne faire qu’un lien direct entre DataSource1 et Table1. (Le propriété DataSource1.DataSet = « Table1 »). Mais ce ne sera pas du tout évolutif. A éviter donc.

JavaFX : résoudre des problèmes sous NetBeans

Si jamais vous essayez de faire fonctionner l’exemple fourni ici et que rien ne marche, avec une erreur ressemblant à :

pakage javafx.ui does not exist

ou encore :

package javafx.ext.swing does not exist

C’est que vous n’avez probablement pas installé la dernière version de JavaFX.

Voici comment faire :

  1. vous allez chercher la toute dernière version ici ;
  2. vous dézippez le fichier archive ;
  3. dans Netbeans, vous désinstallez les plugins JavaFX (menu Tools/Plugins, onglet « Installed ») ;
  4. vous ré-installez la nouvelle version que vous venez d’unzipper : menu Tools/Plugins, onglet « Downloaded », cliquez sur le bouton « Add plugins ».

Librairie Apr : tutoriel 12

12. DSO (Dynamic Symbol Object)

Vous connaissez peut-être les objets partagés (so = shared object) ou les dlls (dll=dynamic link library). Grossièrement on peut dire que DSO est né du principe des so/dll. Mais on parle de dso (Dynamic Symbol Object) pour les différencier des librairies dynamiques so/dll.

Pour comprendre le fonctionnement des dso, il faut savoir comment fonctionne le link et le chargement. En général, lorsqu’on utilise des librairies dynamiques, on les « link » avec le programme principal lors de la compilation. ld(1) s’occupe de cela sur Unix. ld(1) est connu en tant qu’éditeur de lien. Comme ld(1) est habituellement appelé par le compilateur lui-même gcc(1) de façon implicite, peut-être n’avez-vous jamais entendu parler de ld(1). Au mieux avez-vous vu des messages problème de « link » lors de la compilation. Cela signifie que ld(1) n’arrive pas à résoudre certains symboles que vous utilisez dans votre programme. En cours d’exécution, ld.so(8) charge les librairies dynamiques. S’il n’y arrive pas, vous verrez des messages d’erreur de chargement. En résumé, le « link » est fait lors de la compilation, et le chargement est fait lors de l’exécution. Si vous voulez en savoir plus, il vous suffit de lire les manuels ld(1) et ld.so(8).

Grâce à dso, le link et le chargement sont faits lors de l’exécution. Quel est l’intérêt d’un tel mécanisme ? La raison se résume en deux mots : architecture plugin. La seule chose que nous ayons à faire lors de la compilation est de définir les interfaces (« noms symboliques » et la manière les appeler, les paramètres à leur donner, donc) des modules qu’il devra être possible de charger. Le programme charge les modules pendant son exécution, et s’en sert au travers d’interfaces. Les modules dynamiquement « téléchargeables » peuvent ainsi être développés par des programmeurs indépendants. Vous pourrez ainsi rendre votre programme très flexible et extensible.

Voyons voir dso-sample.c. Vous pouvez y voir deux chaines : « libm.so » et « pow ». En réalité, pow(3) est une fonction basique et, en temps normal, n’a pas besoin d’être appelée sous forme de dso, mais c’est simplement pour l’exemple.

Au début, on appelle apr_dso_load() et on lui donne le nom de la librairie : « libm.so ».

/* extrait de dso-sample.c, vérif. des erreurs omise */
const char fname[] = "libm.so";
    apr_dso_handle_t *dso_h;
    apr_dso_load(&dso_h, fname, mp);

Comme vous pouvez l’imaginer, si vous voulez programmer en donnant la possibilité aux autres de faire des plugins pour votre programme, vous devez faire en sorte d’avroi un fichier dans lequel il y a tous les noms des plugins à télécharger. On a déjà quelque chose qui tourne plutôt bien : les modules apache. Leurs noms sont spécifiés, en général, dans le fichier de configuration principal : le fichier « httpd.conf ».

Lorsque apr_dso_load() renvoie une erreur, c’est, la plupart du temps, parce qu’il ne trouve pas le fichier de la librairie dynamique. Le chemin de recherche pour les librairies dépend du système d’exploitation. Sur GNU/Linux, il dépend de la variable d’environnement LD_LIBRARY_PATH. Sur MS-Windows, il dépend de la variable d’environnement PATH. Après avoir un résultat de retour de apr_dso_load() réussi, on peut appeler apr_dso_sym().

Voici le prototype :

/* extrait de apr_dso.h */
APR_DECLARE(apr_status_t) apr_dso_sym(
    apr_dso_handle_sym_t *ressym,
    apr_dso_handle_t *handle,
    const char *symname);

On peut récupérer un objet par son nom via apr_dso_sym(). Le premier argument est un argument résultat. Le second argument est un handle dso, qu’on a avec apr_dso_open() expliqué précédemment. Le troisième argument est le nom du symbole.

Le code suivant est un extrait de dso-sample.c. Le nom du symbole est « pow » et on récupère un pointeur de fontion en tant qu’objet. Comme on connait l’interface de pow(3), il nous suffit de définir la fonction en tant que type : pow_fn_t.

/* extrait de dso-sample.c, vérif. des erreurs omise */
typedef double (*pow_fn_t)(double x, double y);
pow_fn_t pow_fn;

/* récupérer la fonction pow(3) de libm.so */
apr_dso_sym(
    (apr_dso_handle_sym_t*)&pow_fn,
    dso_h, "pow");

/* appeler pow(3) */
printf("%d ^ %d = %f\n", 2, 2, pow_fn(2, 2));

Si votre programme a des plugins, vous devrez définir des noms symboliques ainsi que leurs interfaces. Par la suite, les développeurs devront s’appuyer sur ces déclarations. Enfin, on appelle apr_dso_unload() pour libérer le module. Cela diminue ainsi la consommation mémoire.

Statistiques : de la pub de manière incroyable

C’est absolument impossible que quelqu’un soit tombé sur ma page en tapant l’un de ces termes :

  • (microsoft) and (idees or ideas or start-up)
  • (microsoft or windows or msn) and drm
  • bessemer venture partner shasta ventures catamount ventures

Voici, à mon avis, l’explication : plusieurs mecs ont fait des « faux » aspirateurs de site qui mettent un referer qui fait croire que leur origine vient d’un résultat d’une recherche sur google. Ainsi ils font passer leur pub sur les statistiques Internet. Aussi ingénieux que geek, non ?

Top 16 sur un total de 16 groupes de mots-clés
# Hits Mots-clés
1 4 15.38% faire le gros malin
2 4 15.38% olivier pons
3 2 7.69% %i64d unix
4 2 7.69% (microsoft) and (idees or ideas or start-up)
5 2 7.69% blog olivier pons immobilier
6 2 7.69% http://.olivier.pons.free.fr
7 1 3.85% (microsoft or windows or msn) and drm
8 1 3.85% bessemer venture partner shasta ventures catamount ventures
9 1 3.85% http://olivier.pons.free.fr/blog/geek/
10 1 3.85% php 5 tutorial
11 1 3.85% pons
12 1 3.85% pons olivier myspace
13 1 3.85% produit démonstrateur
14 1 3.85% site:.olivier.pons.free.fr
15 1 3.85% utimaco or bitlocker or ((efs or rms or drm or gestion de droit
16 1 3.85% zeemoz