Achille Fouilleul a écrit 74 commentaires

  • # Correction

    Posté par  (site web personnel) . En réponse à la dépêche C++17 fixe l’ordre d’évaluation des expressions. Évalué à 2.

    s/assignement/affectation/

  • # Une solution en F#

    Posté par  (site web personnel) . En réponse au message Paradigme fonctionnel : juste un habillage ?. Évalué à 3.

    Je n'ai pas de compilateur OCaml sous la main, mais voici une proposition en F#. La traduction en OCaml devrait être simple.

    open System
    
    let split (s : String) =
     let rec loop i j xs =
      if i = 0 then
       if j > 0 then
        s.[0 .. j - 1] :: xs
       else
        xs
      else
       if s.[i - 1] = ' ' then
        loop (i - 1) (i - 1) (s.[i .. j - 1] :: xs)
       else
        loop (i - 1) j xs
     let n = String.length s
     loop n n []
    
    let format width xs =
     let rec loop rs line rems =
      match rems with
      | [] -> List.rev (line :: rs)
      | hd :: tl ->
       match line with
       | "" ->
        loop rs hd tl // problème si un mot est plus long que width
       | _ ->
        let line' = line + " " + hd
        if String.length line' <= width then
         loop rs line' tl
        else
         loop (line :: rs) hd tl
     loop [] "" xs
    
    let s =
     [
      "Ceci"
      " est un"
      "e chaine assez "
      "longue, voir"
      "e même trop lo"
      "ngue ! Tellement longue que l'on peut se demander si elle va tenir !"
      " sur une seule ligne"
     ]
     |> String.concat ""
    
    Console.WriteLine("Original string: " + s)
    Console.WriteLine()
    
    let xs = split s
    
    Console.WriteLine("Split string:")
    for x in xs do
     Console.WriteLine("[" + x + "]")
    Console.WriteLine()
    
    let lines = format 20 xs
    
    Console.WriteLine("After formatting:")
    for line in lines do
     Console.WriteLine(line)
    
    

    La fonction split découpe la chaîne passée en paramètre et renvoie une liste de chaînes. La fonction format prend une liste de chaines et renvoie une liste de chaînes (une par ligne) en s'assurant qu'aucune ligne ne dépasse la largeur maxi spécifiée (sauf si un élément de la liste d'entrée est lui-même plus long que ladite largeur maxi).

  • [^] # Re: Solution Qt

    Posté par  (site web personnel) . En réponse au message Affichage de caractères grecques UTF-8 dans Xorg. Évalué à 1.

    La doc de Xlib laisse à désirer, en effet, mais ce n'est pas aussi compliqué que ça en a l'air.
    J'ai modifié ton programme comme suit, en ajoutant pas mal de code de diagnostic, et ça a l'air de marcher. (À compiler avec -std=c99)

    #include <X11/Xlib.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <locale.h>
    
    int main(void) {
     printf("setlocale() -> %s\n", setlocale(LC_ALL, ""));
    
     Display *d = XOpenDisplay(NULL);
     if (d == NULL) {
      fprintf(stderr, "Cannot open display\n");
      exit(1);
     }
    
     char **missing_charset_list = NULL;
     int missing_charset_count = 0;
     char *def_string = NULL;
     XFontSet fs = XCreateFontSet(d, "*", &missing_charset_list, &missing_charset_count, &def_string);
     printf("fs = %p, def_string = %s\n", fs, def_string);
     for (int i = 0; i < missing_charset_count; ++i)
      printf("missing_charset_list[%d] = %s\n", i, missing_charset_list[i]);
     XFreeStringList(missing_charset_list);
     if (fs == NULL)
      exit(1);
    
     int s = DefaultScreen(d);
    
     char msg[] = "ΟΑΣΔΦΖΧΨΩΒzeΒ";
     Window w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 200, 200, 1, BlackPixel(d, s), WhitePixel(d, s));
    
     XMapWindow(d, w);
    
     XSelectInput(d, w, ExposureMask);
    
     while (1) {
      XEvent e;
      XNextEvent(d, &e);
      if (e.type == Expose) {
       XmbDrawString(d, w, fs, DefaultGC(d, s), 10, 20, msg, strlen(msg));
      }
     }
    
     XFreeFontSet(d, fs);
    
     XCloseDisplay(d);
     return 0;
    
    }
    
    
  • # XDrawString -> Xutf8DrawString

    Posté par  (site web personnel) . En réponse au message Affichage de caractères grecques UTF-8 dans Xorg. Évalué à 2.

    Si le code source est en UTF-8, les constantes chaînes de caractères le seront aussi. Dans ce cas, il vaudrait mieux utiliser Xutf8DrawString(), en passant comme XFontSet la valeur renvoyée par XCreateFontSet(d, "*", ...).

  • [^] # Re: Merci à vous qui m'avez répondu

    Posté par  (site web personnel) . En réponse au message Problème de compilation du noyau 2.6.30. Évalué à 1.

    Le manuel de make est ici: http://www.gnu.org/s/make/manual/. Il peut aider un peu, mais la compilation d'un noyau Linux requiert souvent le passage de paramètres via la ligne de commande ou bien la modification du Makefile ; ARCH=arm par exemple. Ces paramètres sont spécifiques au projet et n'ont aucune raison d'apparaître dans le manuel de make.

    Notez que si vous cherchez à compiler un noyau pour ARM sur une machine de type x86, il s'agit d'une compilation croisée, et le compilateur hôte ne sera d'aucune utilité. Vérifiez que vous disposez d'une chaîne de compilation croisée ou compilez-la au besoin. Chaque outil de la chaîne commence par un préfixe, par exemple: arm-linux- dans votre cas. Le compilateur C sera alors appelé via arm-linux-gcc, l'assembleur via arm-linux-as, etc. Passez donc le paramètre CROSS_COMPILE=arm-linux- à make.
    Si vous voulez configurer et compiler le noyau hors de l'arbre des sources, utilisez O=.
    En outre, j'utilise souvent les variables INSTALL_MOD_PATH et V.

  • # Autres pistes

    Posté par  (site web personnel) . En réponse au message Ecritures disques non bloquants. Évalué à 1.

    Non testé:
    - Essaie plutôt mount -o async.
    - ./prog | tee log > /dev/null
    - Si tee est lui-aussi bloquant, tu peux réécrire une variante avec un tampon d'entrée plus grand, mais ça revient un peu au même que la solution à 2 threads.
    Tu ne dis rien sur le débit des données produites par ton programme ; s'il dépasse les capacités de la carte SD mais que tu as du temps CPU de disponible, la solution est peut-être de compresser la sortie de ton programme (ex: ./prog | gzip -9 > log.gz).

  • # Décomposer exécutable en lanceur + bibliothèque

    Posté par  (site web personnel) . En réponse au message POSIX capabilities / ouvrir port tcp <=1024. Évalué à 2.

    Une idée que je n'ai pas testée.

    Le lanceur pourrait ressembler à ça: (à compiler avec -std=c99 -ldl -o run-with-cap-net-bind-service)

    #include <dlfcn.h>
    
    typedef int (*FuncPtr)(/* ... */);
    
    int main(int argc, char *argv[])
    {
        const char *libpath = ...; /* à récupérer dans argv */
        void *lib = dlopen(libpath);
        if (lib == NULL)
            abort();
        FuncPtr libmain = (FuncPtr)dlsym(lib, "libmain");
        if (libmain == NULL)
            abort();
        return libmain(/* ... *);
    }
    
    

    Ce programme reçoit la capability cap_net_bind_service et éventuellement quelques restrictions (chgrp, chmod g+x, ...).
    L'utilisateur crée son code et le compile avec l'option -shared.
    Ex: gcc -shared ... -o libmain.so
    NB: le point d'entrée devient:

    int libmain(/* même signature que ci-dessus, cf. FuncPtr */)
    {
    }
    
    

    Pour lancer le tout: ./run-with-cap-net-bind-service libmain.so ...

  • [^] # Re: Précisions

    Posté par  (site web personnel) . En réponse au message Écrire en russe facilement sous GNOME via la translittération. Évalué à 2.

    Faute de meilleur endroit, j'ai mis mon antisèche ici:
    http://achille.fouilleul.free.fr/cyrtable.xhtml
  • # Précisions

    Posté par  (site web personnel) . En réponse au message Écrire en russe facilement sous GNOME via la translittération. Évalué à 1.

    Je vais pinailler un peu : la méthode de saisie est fournie par GTK+ et non GNOME ; c'est ainsi qu'on peut l'employer avec les applis GTK+ portées sous Windows (ex. GIMP, Inkscape). D'un autre côté, elle n'est pas disponible sur d'autres applis courantes comme Firefox, OpenOffice.org, etc. car non-GTK+. Dommage, car dans ce cas, je suis régulièrement amené à saisir mes textes en cyrillique sous gedit pour ensuite faire des copier-coller...

    Par ailleurs, je suis surpris qu'aucune documentation soit aisément disponible sur le sujet. Il y a quelques années, il m'a fallu plonger dans le code source pour comprendre précisément comment elle fonctionnait et constituer un aide-mémoire.

    Добрый вечер
  • [^] # Re: Une solution

    Posté par  (site web personnel) . En réponse au message PyGTK et les threads.. Évalué à 1.

    Je préfère malgré tout l'approche gobject.idle_add(). C'est une question de préférence personnelle, peut-être, mais la plupart des bibliothèques graphiques n'autorisent pas les appels cross-thread, même avec des verrous. D'ailleurs, que se passe-t-il si une exception est levée entre threads_enter() et threads_leave() ?
    Pour préserver les espaces dans le code, utilise des balises <pre>. Lis la doc ;-)
  • [^] # Re: Une solution

    Posté par  (site web personnel) . En réponse au message PyGTK et les threads.. Évalué à 1.

    Quelques notes, puisque j'y suis:
    - les tests "if x == True" et "while y == False" peuvent être réécrits "if x" et "while not y"
    - la classe MyThread pose des problèmes de synchronisation ("race conditions"): il se peut que la valeur de is_running soit fausse si un autre thread intervient par ex.
    - j'ai oublié "self.th.join()" avant "self.th = None", pour attendre que le thread ait terminé avant de revenir.
  • # Une solution

    Posté par  (site web personnel) . En réponse au message PyGTK et les threads.. Évalué à 1.

    j'ai réécrit la classe MyThread comme ceci:
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    import threading, time
    import gobject
    import gtk
    
    class MyThread:
        def __init__(self, main, nb):
            self.main = main
            self.nb = nb
            self.is_running = False
    
        def start(self):
            print 'start thread', self.nb
            self.is_running = True
            self.th = threading.Thread(target = self.loop)
            self.th.start()
    
        def stop(self):
            print 'stop thread', self.nb
            self.is_running = False
            self.th = None
    
        def loop(self):
            while self.is_running == True:
                gobject.idle_add(self.update_label)
                time.sleep(0.1) 
    
        def update_label(self):
            # Le but de cette fonction est de montrer comment modifier
            # un objet gtk dans la boucle principale depuis un thread.
            self.main.labels[self.nb-1].set_text(str(time.time()))
    
  • [^] # Re: En France aussi, depuis 2004

    Posté par  (site web personnel) . En réponse au journal vous en reprendrez bien une petite dose. Évalué à 1.

    Je me souviens de cette inscription, et aussi d'avoir été sceptique. Après tout, puisque elle a été ajouté à la constitution, elle peut aussi en être retirée. Que se passerait-il si un référendum sur cette question était organisé juste après une affaire criminelle sordide ?
  • [^] # En France aussi, depuis 2004

    Posté par  (site web personnel) . En réponse au journal vous en reprendrez bien une petite dose. Évalué à 5.

    Voir [http://www.assemblee-nationale.fr/12/propositions/pion1521.a(...)]:

    "PROPOSITION DE LOI
    tendant à rétablir la peine de mort
    pour les auteurs d’actes de terrorisme"

    Ce texte mentionne les protocoles n°6 et 13 additionnels à la Convention européenne de sauvegarde des droits de l’homme et des libertés fondamentales comme étant les seuls "verrous juridiques" empêchant le rétablissement de la peine de mort.
  • # «Néo» libéralisme?

    Posté par  (site web personnel) . En réponse au journal La prise de conscience. Évalué à 2.

    Qu'est-ce que la définition de WP a de mauvais? (si ce n'est qu'elle ne cadre pas vraiment avec ce que tu dis).

    Le vrai problème avec les termes «néolibéral» et «ultralibéral», c'est que personne ne se revendique comme tel. Ils servent d'hommes de paille bien commode pour attaquer les idées libérales en les mélangeant avec des choses qui n'ont rien à voir (consumérisme, productivisme, ...) voire lui sont opposées (protectionnisme, mercantilisme, esclavage, ...).

    Ainsi, Reagan, Thatcher, etc. ne se sont jamais définis ainsi et leurs politiques de réduction de l'intervention étatique − avec lesquelles on peut ne pas être d'accord, la question n'est pas là − sont en partie d'inspiration libérale (pas «néo» ni «ultra»).
    Je t'invite, pour compléter ta culture sur le sujet, à consulter plus attentivement les articles sur le sujet de wikipédia et du wiki des liberaux [http://www.wikiberal.org]. Il est toujours utile de connaître les idées autrement que par ceux qui les critiques.

    Voir aussi [http://bastiat.net] et l'excellent [http://dantou.fr/liberalisme.htm].
  • [^] # Re: Et les liens ?

    Posté par  (site web personnel) . En réponse au journal Microsoft réécrit Hurd ?. Évalué à 2.

    Singularity est sur le codeplex de MS depuis quelques semaines (voire même mois...), avec une iso que tu peux tester, le code source y est (bon pas sous GPL ni BSD, faut pas rêver).

    http://www.codeplex.com/singularity

    Dans ces conditions, je crois que nous n'avons pas la même définition de vaporware.
  • [^] # Re: Dommages-intérêts

    Posté par  (site web personnel) . En réponse à la dépêche Free assigné pour violation de la GPL. Évalué à -1.

    OK, j'avais mal compris. C'était d'ailleurs bien pratique il y a quelques années, quand les connexions à Internet n'étaient pas ce qu'elles sont, quoique dans mon coin il fallait chercher un moment avant de trouver un magazine+CD Linux.
  • [^] # Re: Dommages-intérêts

    Posté par  (site web personnel) . En réponse à la dépêche Free assigné pour violation de la GPL. Évalué à -3.

    Je suis au courant, c'est pour cela que j'ai dit "dans ce cadre" (sous-entendu "de la GPL"). Voir par exemple FreeRTOS, disponible sous d'autres licences que la GPL. Mais à ma connaissance, ce n'est pas possible avec Linux, ni avec BusyBox.

    Je ne reproche pas aux plaignants de chercher à faire valoir leurs droits. Seulement, le fait qu'un succès de leur démarche pourrait leur bénéficier personnellement n'apparait nulle part sur le site [http://freebox.flouzo.net/]. Au contraire, on peut lire: This software was developed in the best interest of all, and unlike developers of proprietary software, we do not ask for much in exchange for our work: we simply request to receive recognition and that any modification and additions to our work be available to all.

    Ils incitent les défenseurs du LL à soutenir leur action par des dons, donc le risque d'échec est réparti entre tous les contributeurs. En revanche, en cas de succès, seuls eux en profiteront. C'est cette ambigüité qui me chiffonne.
  • [^] # Re: Dommages-intérêts

    Posté par  (site web personnel) . En réponse à la dépêche Free assigné pour violation de la GPL. Évalué à -2.

    Ils ne sont pas obligés, bien sûr, mais ils pourraient. Certains le font parfois. Leur action en justice pourrait ainsi paraître "désinterressée."

    Après tout, ils ont fait le choix de mettre leur code sous GPL, c'est bien qu'ils ne comptaient pas recevoir de rétribution financière en cas d'utilisation de ce code dans ce cadre. Je trouve donc un peu bancale d'affirmer que Free leur cause un préjudice moral et surtout patrimonial.
  • # Dommages-intérêts

    Posté par  (site web personnel) . En réponse à la dépêche Free assigné pour violation de la GPL. Évalué à 0.

    Un truc me turlupine: MM. Welte, Landley et Andersen exigent chacun 1€ par Freebox mise à disposition par Free à ses abonnés (cf. l'assignation pp. 21-22). Il y en a plusieurs millions ! Ont-ils dit ce qu'ils feraient de ces sous si le tribunal leur donne raison ? D'autant qu'ils demandent 10000€ d'article 700 en sus.
  • [^] # Re: C# n'est pas un langage à typage fort !

    Posté par  (site web personnel) . En réponse à la dépêche Mono 2.0 : le singe continue ses grimaces. Évalué à 10.

    C# est bien un langage à typage fort. C'est la magie de l'inférence de type qui permet de se passer dans ce genre de cas de déclarations superflues.

    Le bout de code d'exemple m'a l'air correct, il se compose bien de trois instructions:
    1. charge le document.
    2. récupère les éléments du flux, ne garde que ceux dont le titre contient le mot "Mono", ordonne par date de publication, et renvoie un IEnumerable d'un type anonyme qui contient le titre, un lien, et la description de chacun des items retenus.
    3. vérifie si la balise "description" d'un item au moins contient la chaîne recherchée et affiche un message le cas échéant.

    À noter: C++0x devrait faire un pas dans cette direction en "recyclant" le mot-clé "auto". Ainsi, les
    for (ContainerType::const_iterator p = list.begin(); p != list.end(); ++p)
        Action(*p, otherArgument);

    ressembleraient plutôt à
    for (auto p = list.begin(); p != list.end(); ++p)
        Action(*p, otherArgument);

    Une bénédiction...
  • [^] # Re: bon ben c' est simple....

    Posté par  (site web personnel) . En réponse au journal G'MIC : Un nouvel outil libre de manipulation d'images. Évalué à 2.

    Si on ne veut vraiment pas de fonctions membres dans les classes, alors on fait des structures C et c'etait pas la peine de faire du C++.

    Ce n'est pas ce que je veux dire. L'idée de la programmation objet (quel que soit le langague) est justement de séparer les concepts, d'avoir des classes minimalistes qui représentent un invariant. Il ne me semble pas judicieux, par exemple de mêler dans une même classe gestion des fichiers, des options de ligne de commande, l'interface utilisateur, etc.

    J'ai bien vu que tu utilises des traits -- trop peu à mon goût, mais je découvre ta bibliothèque, alors je suis prudent dans mes commentaires :-).

    En ce qui concerne les policies, tu pourrais bien, par exemple avoir une classe par algo (blur pour reprendre ton exemple) et t'en servir comme paramètre de template. Il s'agit là de métaprogrammation: la classe n'est jamais instanciée, elle sert de paramètre à une autre classe (cf. Policy-based design sur wikipédia, ou la bibliothèque Loki d'Andrei Alexandrescu). J'insiste, va voir Anti-Grain c'est aussi une bibliothèque graphique, indépendante du type de pixel, couleur, etc., statiquement polymorphe et (à mon avis) lisible.

    En ce qui concerne de "faire du C++" je note que tu utilises pas mal de fonctions stdio/stdlib (fopen, sprintf, memcpy, etc.), alors que de meilleurs équivalents C++ sont disponibles (std::fstream, std::ostringstream, std::copy, etc.).


    * Les macros peuvent faire peur, mais elles sont très peu utilisées dans CImg, et je pense qu'elles le sont à bon escient. Ca fait peur parce que elles se trouvent en début de fichier, et que c'est vrai que ca prend de la place... Mais bon, c'est des macros, je vais pas les mettre à la fin du fichier...

    Pour les macros, c'est un peu pareil, c'est du C. Je suis sûr qu'il est possible de les réécrire sous forme de templates, elles seraient certainement plus courtes, "type-safe", et le compilateur devrait être capable de produire de meilleures optimisations.
  • [^] # Re: bon ben c' est simple....

    Posté par  (site web personnel) . En réponse au journal G'MIC : Un nouvel outil libre de manipulation d'images. Évalué à 3.

    En résumé, la modularité n'a rien à voir la dedans, G'MIC utilise un tas de fonctions différentes avec des types d'images différents (et de la généricité statique) et donc de toute façon, le compilo doit les compiler pour tous les types que l'on a prévu.

    Mais c'est bien ce qu'il dit, il y a à mon avis aussi un gros problème de conception. Il ne s'agit pas de saucissonner le code en fichiers .h, bien sûr que ça ne règlerait pas le problème.
    * Pourquoi tout mettre dans une seule classe (CImg)? À la fois du code dépendant de la plateforme, du code de traitement d'image, de tracé de formes. Tout cela pourrait avantageusement séparé.
    * As-tu considéré les traits/policies? Tu conserves ainsi le polymorphisme statique (lorsqu'il est vraiment nécessaire). Il faudrait des benchmarks pour arbitrer avec le polymorphisme dynamique.
    * Pourquoi toutes ces données codées en dur (polices, chemins, tableaux de constantes, etc.)?
    * Des fonctions/macros qui prennent une dizaine de paramètres?!

    Comme le post parent le suggère, jette un coup d'oeil à Boost, la STL, etc. Tu verras qu'il est possible de conserver de la généricité tout en gardant des tailles de fichier et des temps de compilation raisonnables.

    Ne le prends pas mal, c'est du bon et gros boulot, les algos de traitement d'image sont certainement bons et ta bibliothèque utile, mais elle gagnerait à une conception utilisant mieux le langage C++.

    Vois également la bibliothèque AGG (antigrain). Elle est très polymorphe (y compris statiquement), les headers et classes sont clairement décomposés.
  • # Ailleurs...

    Posté par  (site web personnel) . En réponse au journal Linux sur les mini-laptop : pas un réel succès ?. Évalué à 4.

    ...on signale que c'est encore pire: certains achètent un netbook Linux et installent Windows par-dessus [http://osnews.com/story/20182/Will_Netbooks_Pave_the_Way_for(...)]. Sont-ils nombreux? Difficile de savoir.

    Cet article: [http://linuxdevices.com/news/NS3729146740.html] semble indiquer que les machines sous Linux représentent près de la moitié des ventes d'appareils de ce format.
    Quoi qu'il arrive, le moment est intéressant.
  • [^] # Re: Présomption de culpabilité...

    Posté par  (site web personnel) . En réponse au journal Hans Reiser déclaré coupable. Évalué à 6.

    Ci-dessous un monsieur qui sait de quoi il parle donne plus d'explications:

    http://www.maitre-eolas.fr/2005/12/16/252-pourquoi-on-peut-c(...)