Journal Rajouter automatiquement une ligne dans chaque void d'un source C

Posté par  (site web personnel) .
Étiquettes : aucune
0
25
mai
2004
Mon cher journal, je fait pas mal de progrès en Sed, mais là ce que je cherche à faire est au dessus de mes capacités.
Cela dit, les vertus de l'imitation sont grandes...


Voilà mon problème : j'ai un source en C avec plein de void (c'est un source généré par un compilateur donc c'est le bordel, mais à peine plus qu'un gros fichier, non en fait c'est assez propre).

Je voudrait faire un script qui ajoute automatiquement une ligne après les 3 lignes d'entêtes de fonctions, de commentaires puis la { une ligne du type
fprint(stderr,Nomde la fonction démarée)

Vous avez bien compris, je voudrais tracer sur la sortie err chaque appel de chaque fonction.

Pour exemple j'ai ça :
static void draw__to__UYHC(void *self__VYHC,signed long x0__WYHC,signed long y0__XYHC,signed long x1__YYHC,signed long y1__ZYHC)
// TETRIS draw__to(TETRIS,INTEGER,INTEGER,INTEGER,INTEGER)
{

et après l' { je voudrai ajouter fprintf(stderr,"draw__to__UYHC\n")

j'imagine quelques bouts, mais je ne vois pas comment faire, si vous avez des idées....

Merci !
  • # En perl ?

    Posté par  . Évalué à 5.

    Je ne suis pas sûr de traiter les cas particuliers mais si ton code sort d'un générateur ça doit pouvoir le faire avec ça :
    #!/usr/bin/perl
    
    use strict;
    
    my $currentFunction;
    my $pos = 0;
    
    while (my $line = ) {
      print $line;
      if ($pos == 0 and $line =~ m/^\s*static\s+void\s+([^\s]+)\s*\(/ ) {
        $currentFunction = $1;
        $pos = 1;
      }
      if ($pos == 1 and $line =~ m/\)/) {
        $pos = 2;
      }
      if ($pos == 2 and $line =~ m/^\s*\/\// ) {
        $pos = 3;
      }
      if ($pos == 3 and $line =~ m/^\s*\{/ ) {
        print 'fprintf(stderr,"', $currentFunction, '\n")', "\n";
        $pos = 0;
      }
    }
    
    • [^] # Re: En perl ?

      Posté par  . Évalué à 1.

      Perl me semble un excellent outil pour ce que tu veux faire.

      #!/usr/bin/perl

      open (IN, "tonfichier.c") or die("argghhh !");
      open (OUT, ">fichierDeSortie.c") or die ("ou la la !");

      while ($ligne = ) {
      print OUT $ligne;
      chomp $ligne;
      if ($ligne =~/^void /) {
      ($void, $nomFonction, @toutLeReste) = split ' ', $ligne;
      print OUT 'fprint(stderr,';
      print OUT $nomFonction;
      print OUT ')';
      }
      }

      close IN;
      close OUT;

      Maintenant, vu le temps qui s'est ecoule entre aujourd'hui et la derniere fois ou j'ai touche a Perl, il est clair que quelque debugging s'impose et que mon code est loin d'etre executable tel quel, mais l'algo est la.

      Bon courage.
      • [^] # Re: En perl ?

        Posté par  . Évalué à 0.

        C'est pas du joli Perl ça !

        Perso, je fous toujours tout ce qui est en IN dans un tableau et je ferme le handle.

        Le if... n'est pas très beau non plus

        Le while n'est pas très joli, les print non plus

        Bref c'est pas du joli Perl comme j'aime :)

        Ca devrait être un bon one-line ça :p

        Ceci dit je critique mais je propose pas de solution non plus :)
    • [^] # Re: En perl ?

      Posté par  . Évalué à 2.

      Il y a une ligne qui s'est fait bouffée :

      while (my $line = <STDIN>) {

      Et la première regexp est peut-être mieux comme ça :

      $line =~ m/^\s*static\s+void\s+([^\s\(]+)\s*\(/
      • [^] # Re: En perl ?

        Posté par  (site web personnel) . Évalué à 0.

        Merci beaucoup, ça fonctionne ! :)

        Dans la série "je voudrai en profiter pour apprendre"

        le seul truc que je comprend pas c'est $line =~ m/^\s*static\s+void\s+([^\s\(]+)\s*\(/

        si tu pouvais expliquer un peu, ça me permettrai d'aider à mon tour ;)

        « Il n’y a pas de choix démocratiques contre les Traités européens » - Jean-Claude Junker

  • # euh...

    Posté par  (site web personnel) . Évalué à 2.

    tu peux ajouter un commentaire spécial devant chaque fonction histoire de retrouver facilement les endroits où insérer du code automatiquement, après un petit script dans ton langage préférer devrait pouvoir te faire celà... (il te suffit de rechercher le premier '{' après ton commentaire spécial)

    Sinon je suppose que tu ne veux pas rajouter de truc dans ton code, auquel cas, en C, tu vas bien t'amuser (c'est possible dans des langages qui permettent l'auto-description comme ceux basé sur le CLR de Mono par exemple)... y'a surement dans le résultat de la compilation la table des entrées de ton module, tu peux peut être rajouter du code assembleur à ce niveau là mais alors là tu vas vraiment t'amuser, et tout dépendra du compilateur que tu utilises...

    Dernière solution : tu te fait ton propre parseur qui va retrouver comme un grand les fonctions et donc tu pourras y ajouter ce que tu veux... Il te suffit de récupérer un parser C dans ton langage préféré, basé sur la grammaire du langage C... Si tu n'as que la grammaire, tu peux utiliser l'utilitaire yacc qui te générera l'analyseur en C, tu pourras alors rajouter dans ta grammaire un morceau de code qui "intègre" tes fonctions d'affichages...

    Une dernière piste : man gdb ? (je dis ça mais j'en sais rien) en tout cas les debuggueur y arrivent très bien à faire ce que tu veux...
  • # et en C ? :-)

    Posté par  . Évalué à 1.

    Bon jme suis amusé a le faire en C, si jamais ca t'interesse...

    une fois compilé : $ ./mon_programme ton_fichier.c et zou il créé ton_fichier.c.new comme tu le veux :-)

    enjoy !

    /*********************************************************/

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>

    int main(int argc, char *argv[])
    {
    FILE *fic;
    FILE *fic1;
    char buffer[512];
    char temp[512];
    char nom[512];
    char *pos;
    int i;

    strcpy(temp,"fprintf(stderr,\"");
    if ((fic=fopen(argv[1],"r"))==NULL)
    {
    printf("Impossible d'ouvrir le fichier specifie.\n");
    return 1;
    }

    strcpy(nom,argv[1]);
    strcat(nom,".new");
    fic1=fopen(nom,"w");
    while(fgets(buffer,512,fic),!feof(fic))
    {
    pos=strstr(buffer,"void ");

    if (pos!=NULL) /* la ligne contient un nom de fonction ? */
    {
    pos=pos+5;
    temp[16]='\0';
    while (*pos!='(')
    {
    i=strlen(temp);
    temp[i]=*pos;
    temp[i+1]='\0';
    pos++;
    }
    fprintf(fic1,"%s",buffer);
    fgets(buffer,512,fic);
    fprintf(fic1,"%s",buffer);
    fgets(buffer,512,fic);
    fprintf(fic1,"%s",buffer);
    fprintf(fic1,"%s\");\n",temp);


    }
    else
    fprintf(fic1,"%s",buffer);
    }/* fin while */
    fclose(fic1);

    printf("Fichier %s cree avec succes !\n",nom);
    return 0;
    }
    • [^] # Re: et en C ? :-)

      Posté par  . Évalué à 0.

      euh ca gène pas le fonctionnement du programme, mais un ptit fclose(fic); a la fin serait le bienvenue, jlai oublié :-/

      Mais bon, ca marche quand meme sans, vu que fic etait en accès Lecture seule, mais c'est plus propre avec..
      • [^] # Re: et en C ? :-)

        Posté par  (site web personnel) . Évalué à 1.

        ca marche pas ;)
        Ca transforme

        // BITMAP
        struct __BITMAP {
        signed long height__E9F;
        signed long width__F9F;
        signed long clip_x0__G9F;
        signed long clip_y0__H9F;
        signed long clip_x1__I9F;
        signed long clip_y1__J9F;
        signed long spot_x__K9F;
        signed long spot_y__L9F;
        unsigned long rgbcolor__M9F;
        void *edges__HBG;
        signed long edges_upper__IBG;
        signed long poly_ymax__JBG;
        void *poly_list_y__KBG;
        void *begin_y__LBG;
        signed long begin_idx__MBG;
        void *last_y__NBG;
        signed long last_idx__OBG;
        signed long x_origin__PBG;
        signed long y_origin__QBG;
        };

        en

        // BITMAP
        struct __BITMAP {
        signed long height__E9F;
        signed long width__F9F;
        signed long clip_x0__G9F;
        signed long clip_y0__H9F;
        signed long clip_x1__I9F;
        signed long clip_y1__J9F;
        signed long spot_x__K9F;
        signed long spot_y__L9F;
        unsigned long rgbcolor__M9F;
        void *edges__HBG;
        signed long edges_upper__IBG;
        signed long poly_ymax__JBG;
        fprintf(stderr,"*edges__HBG;
        lor__M9F;
        t_abstract_string__RH;
        e.";


        DFGHJKLM% µWXCVBN?./§";
        L^C@à?^C@@Ž^B@H^A@^C K^A@^T=^A@4J^A@`^C@,õÿ¿ék@`^C@^C^C^Põÿ¿bz@^C@õ^^Pii^M^Pii^Mu^ pK^A@^BSep 18 12:^A¹
        lõÿ¿H^A@ë^B@L^C@à?^C@@Ž^B@H^A@^C K^A@^T=^A@ô@^A@Ã^Àõÿ¿ék@Ã^ÿw^Aô^põÿ¿š@^A@^APK^A@^A^Apõÿ¿ÿw^Aöÿ¿X?^A@`^C@ë^B@Ð1^C@H^A@Töÿ¿Žõÿ¿ðš@^?^C^A^L
        @Ñ÷ÿ¿Töÿ¿þ @ I^U@I^U@Žõÿ¿¥Ú^C@ I^U@}k@^T=^A@X?^A@ô@^A@^Pöÿ¿£§@ô@^A@PK^A@l^èõÿ¿Á^Töÿ¿\öÿöÿ¿Ü^ ¯@Töÿ¿p^�^8^A@Töÿ¿");
        void *poly_list_y__KBG;


        et ça fait ça sur tout les struct qui contiennent des void. le pire c ke les vrai void ne sont pas touchés. Cela dit merci bcp, c'est une bonne base :)

        « Il n’y a pas de choix démocratiques contre les Traités européens » - Jean-Claude Junker

        • [^] # Re: et en C ? :-)

          Posté par  . Évalué à 0.

          Ah oué j'ai pas testé, moi j'ai considéré que dès que yavé un void, c'etait un corps de fonction. Auquel cas ca marchais, j'avais pris soin de tester lol
          Je vais faire un patch :-)
        • [^] # Hop patché !

          Posté par  . Évalué à 1.

          ayé c patché :-)
          J'ai modifié une seule ligne lol...

          /****************************************************/

          #include <stdlib.h>
          #include <stdio.h>
          #include <string.h>

          int main(int argc, char *argv[])
          {
          FILE *fic;
          FILE *fic1;
          char buffer[512];
          char temp[512];
          char nom[512];
          char *pos;
          int i;

          strcpy(temp,"fprintf(stderr,\"");
          if ((fic=fopen(argv[1],"r"))==NULL)
          {
          printf("Impossible d'ouvrir le fichier specifie.\n");
          return 1;
          }

          strcpy(nom,argv[1]);
          strcat(nom,".new");
          fic1=fopen(nom,"w");
          while(fgets(buffer,512,fic),!feof(fic))
          {
          pos=strstr(buffer,"void ");

          if ((pos!=NULL)&&(strchr(buffer,';')==NULL)) /* la ligne contient un nom de fonction ? */
          {
          pos=pos+5;
          temp[16]='\0';
          while (*pos!='(')
          {
          i=strlen(temp);
          temp[i]=*pos;
          temp[i+1]='\0';
          pos++;
          }
          fprintf(fic1,"%s",buffer);
          fgets(buffer,512,fic);
          fprintf(fic1,"%s",buffer);
          fgets(buffer,512,fic);
          fprintf(fic1,"%s",buffer);
          fprintf(fic1,"%s\");\n",temp);


          }
          else
          fprintf(fic1,"%s",buffer);
          }/* fin while */
          fclose(fic1);

          printf("Fichier %s cree avec succes !\n",nom);
          return 0;
          }
          • [^] # Re: Hop patché !

            Posté par  . Évalué à 0.

            Ah et j'ai oublié un ptit '\n' vers la fin :
            fprintf(fic1,"%s\");\n",temp);
            devient :
            fprintf(fic1,"%s\\n\");\n",temp);

            Voilà c'est mieux, sinon tout s'affichait a la suite dans stderr...
    • [^] # Re: et en C ? :-)

      Posté par  (site web personnel) . Évalué à 4.

      T'as pas pensé à le faire en assembleur directement ?
      • [^] # Re: et en C ? :-)

        Posté par  . Évalué à 0.

        C'est une phrase ironique d'informaticien ou c'est serieux ? Car j'suis une huitre en assembleur, et mes a prioris sur le langage me laisse penser que ce serait assez technique à réaliser...
  • # ne re-inventons pas la roue carrée

    Posté par  . Évalué à 0.

    moi pour mettre en forme mes sources apres avoir tapé au kilometre j'utilise un petit soft tres bien qui connait toutes les regles de presentation (et tu peut definir les tiennes si tu veux)
    c'est indent (un petit google et tu le trouveras)
    • [^] # Re: ne re-inventons pas la roue carrée

      Posté par  . Évalué à -1.

      euh moi j'ai répondu pour le fun, c'est pas que j'aime réinventer la roue, mais le monsieur a posé une question et c'est toujours plaisant de pondre une ptit bout de code qui marche, ca entretient les neurones ^^

      Bon après que ce qu'il veule ait déjà été fait ou non on s'en fiche un peu, mais c'est toujours bien de le dire effectivement

      Mais il vient d'apprendre grosso modo comment faire ce qu'il voulait en perl, en C ,et maintenant avec indent, c'est comme ca qu'on progresse :-)

      Voilou

      - cho7, qui aime participer a la re-invention de la roue carrée, parce que ca le fait *un peu* reflechir -
  • # Personne ne connaît __FUNCTION__ ?

    Posté par  . Évalué à 2.

    Il suffit de rajouter ça après chaque accolade :
    fprintf(stderr, __FUNCTION__ "\n");

    Pas besoin de se casser la tête, le préprocesseur fait tout le boulot à notre place :)
    • [^] # Re: Personne ne connaît __FUNCTION__ ?

      Posté par  (site web personnel) . Évalué à 2.

      le plus intéressant c'est pour les messages de debug:

      #define debug(str, args...) printf(__FUNCTION__":"__LINE__ str, ##args)

      et plus loin dans le code on peut appeler debug() comme printf(), et les messages seront préfixés du nom de la fonction et du numéro de ligne.

      Indispensable pour moi, c'est l'un des premiers define que je tape dans un .h de projet.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.