IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Eclipse Modeling Discussion :

Générer du code C++ grâce à Acceleo


Sujet :

Eclipse Modeling

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Juin 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2014
    Messages : 7
    Points : 1
    Points
    1
    Par défaut Générer du code C++ grâce à Acceleo
    Bonjour à tous,

    Je souhaiterais sérialiser un fichier issu de Papyrus (.uml) en code C++ grâce à Acceleo.

    J'ai créé un template que voici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    [comment encoding = UTF-8 /]
    [module le_projet('http://www.eclipse.org/uml2/4.0.0/UML')]
     
    [template public le_projet(aClass : Class)]
    [comment @main /]
     [file (aClass.name.concat('.cpp'), false)]
       public class [aClass.name.toUpperFirst()/] {
       [for (p: Property | aClass.attribute) separator('\n')]
         private [p.type.name/] [p.name/];
       [/for]
     
       [for (p: Property | aClass.attribute) separator('\n')]
         public [p.type.name/] get[p.name.toUpperFirst()/]() {
           return this.[p.name/];
         }
       [/for]
     
       [for (o: Operation | aClass.ownedOperation) separator('\n')]
         public [o.type.name/] [o.name/]([for(p:Parameter | o.ownedParameter)separator(',')] [p.type.name/] [p.name/] [/for]) {
           // TODO should be implemented
         }
       [/for]
       }
     [/file]
     [/template]
    C'est censé gérer les classes, leurs attributs et méthodes.
    Appliqué à cette classe...
    Nom : extrait_diagramme_classe_mdrl.jpg
Affichages : 861
Taille : 10,7 Ko
    cela donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
       public class Recherche_de_fichier {
     
         public String recherche_fichier_dans_arbo( String Nom_fichier ) {
           // TODO should be implemented
         }
     
         public String Essai( String Essai_sortie , Bool Essai1 , String Essai2 ) {
           // TODO should be implemented
         }
       }
    Pas si mal, mais il y a un problème puisque le paramètre de retour se retrouve également dans les paramètres d'entrée de la méthode!

    J'ai bien trouvé une opération s'appelant in_and_out(EDiagnosticChain,EMap) : Boolean mais je ne sais pas du tout m'en servir et de plus, je ne suis pas sûr qu'elle résoudrait mon problème.

    Quelqu'un saurait-il m'indiquer comment faire pour résoudre ce problème ?

    Je débute dans ce domaine et j'ai quelques difficultés à obtenir de la documentation sur cette fonction.

    D'avance, merci pour vos conseils / idées.

  2. #2
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Juin 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2014
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    Bonjour à tous,

    Bon voila, du code c++ généré qui ressemble à quelque chose. ;-)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    [comment encoding = UTF-8 /]
    [module the_project('http://www.eclipse.org/uml2/4.0.0/UML')]
     
    [template public main_header(la_classe : Class)]
    [comment @main /]
    [file ('main.h', false)]
    #include la_classe.name.toLowerCase().prefix(la_classe.name.toLowerCase().concat('/')).concat('.h')/][/file]
    [/template]
    [template public other_header(aClass : Class)]
    [comment @main /]
     [file (aClass.name.toLowerCase().prefix(aClass.name.toLowerCase().concat('/')).concat('.h'), false)]
    #ifndef [aClass.name.toUpper().concat('_H')/]
    #define [aClass.name.toUpper().concat('_H')/]
     
    #include <string>
     
    using namespace std ;
     
    class [aClass.name/] {
    private :
    [for (p: Property | aClass.attribute) separator('\n')]
          [p.type.name.toLowerCase()/] [p.name.toLowerCase()/];
          [/for]
     
    public :
    [aClass.name/]() ;
    [aClass.name/](const [aClass.name/] &) ;
    virtual ~[aClass.name/]() ;
     
       [for (p: Property | aClass.attribute) separator('\n')]
         [p.type.name.toLowerCase()/] get_[p.name.toLowerCase()/]() {
           return this -> [p.name.toLowerCase()/] ;
         }
       [/for]
     
     
       [for (o: Operation | aClass.ownedOperation) separator('\n')]
         [o.type.name.toLowerCase()/] [o.name.toLowerCase()/]([for(p:Parameter | o.ownedParameter)separator(',')] [p.type.name.toLowerCase()/] [p.name.toLowerCase()/] [/for]) {
         }
       [/for]
       } ;
    #endif
     [/file]
     [/template]
     
    [template public other_src(la_classe : Class)]
    [comment @main /]
    [file (la_classe.name.toLowerCase().prefix(la_classe.name.toLowerCase().concat('/')).concat('.cpp'), false)]
    #include la_classe.name/]
     
       [for (o: Operation | la_classe.ownedOperation) separator('\n')]
         [o.type.name.toLowerCase()/] [o.name.toLowerCase()/]([for(p:Parameter | o.ownedParameter)separator(',')] [p.type.name.toLowerCase()/] [p.name.toLowerCase()/] [/for]) {
         }
     
       [/for]
     
       [/file]
    [/template]
    [template public main(generation_main : Class)]
    [comment @main /]
    [file ('main.cpp', false)]
    extern {
    #include <unistd.h>
    #include <getopt.h>
    }
    # include ain.h# include <iostream>
    # include <string>
     
    using namespace std ;
     
    int main(int argc, char **argv)
    {
      int opt ;
      static char optstring[ '[' /][ ']' /] = ;
      while ((opt = getopt(argc, argv, optstring)) != -1)
        {
          switch (opt)
            {
            case 'h' :
              cout << argv['[' /]optind - 1[ ']' /] << : Aide indisponible<< endl ;
              break ;
            case '?':
              cout << argv[ '[' /]optind - 1[ ']' /] << : Option inconnue.<< endl ;
              break;
            }
        }
     
     
      return 0 ;
    }
    [/file]
    [/template]
    [template public makefile(la_classe : Class)]
    [comment @main /]
    [file ('Makefile', false)]
    DEBUG=yes
    CC=g++
    COMMON_CFLAGS= -W -Wall -ansi -pedantic
    ifeq ($(DEBUG),yes)
            CFLAGS=$(COMMON_CFLAGS) -g
    else
            CFLAGS=$(COMMON_CFLAGS)
    endif
     
    LDFLAGS=
    EXEC=a
    SRC= $(wildcard *.cpp)
    OBJ= $(SRC:.cpp=.o)
     
    all: $(EXEC)
    ifeq ($(DEBUG),yes)
    @echo énération en mode debugelse
    @echo énération en mode releaseendif
     
    loogle: $(OBJ)
    @$(CC) -o $@ $^ $(LDFLAGS)
     
    %.o: %.cpp
    @$(CC) -o $@ -c $< $(CFLAGS)
     
    include .depend
     
    depend :
    g++ -MM *.cpp > .depend
     
    .PHONY: clean mrproper
     
    clean:
    @rm -rf *.o
     
    mrproper: clean
    @rm -rf $(EXEC)
    [/file]
    [/template]
    Cela génère un fichier main.cpp, un main.h, un makefile, ainsi qu'un répertoire par classe avec ses fichiers de déclaration (.h) et d'implémentation (.cpp).

    Moyennant quelques déclarations de bibliothèques en manuel, c'est compilable... Ouf!

    Mais j'ai toujours le même problème : le paramètre de retour des méthodes se retrouve toujours dans les paramètres d'entrée de celles-ci!

    Je peux le résoudre avec des sed, mais ce n'est pas une solution élégante.

    De plus, les fichiers main.c, main.h, makefile sont réécrits pour chaque classe. Pas très optimisé, mais plus grave, puisque la classe suivante écrase la classe précédente, le fichier main.h n'inclut que la dernière classe traitée.

    Pour finir, il faudra certainement que je factorise le code du template parce que j'ai fait beaucoup de copier-coller.

    Toutes critiques et suggestions sont les bien venues. :-)

  3. #3
    Membre expérimenté Avatar de yann2
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2004
    Messages
    897
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2004
    Messages : 897
    Points : 1 635
    Points
    1 635
    Par défaut
    Bonjour

    Effectivement, dans le méta-modèle UML, le type de retour est un paramètre de l'Operation, ce qui n'aide pas...

    Dans la boucle [for(p : Parameter | o.ownedParameter)separator(',')] il faut donc enlever le(s) Parameter(s) qui représentent ce type de retour :

    La propriété direction d'un objet Parameter permet de savoir si celui-ci est un 'retour'

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    [for(p:Parameter | o.ownedParameter->reject(direction = uml::ParameterDirectionKind::return)) separator(',')]
    Ou une autre solution, l'opération returnResult() sur un objet Operation retourne tous les paramètres de direction 'retour' :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    [for(p:Parameter | o.ownedParameter->removeAll(self.returnResult()) separator(',')]

    Je n'ai pas regardé le code en détail mais, factoriser est rarement une mauvaise idée


    Pour main.h et main.c, je vous conseille de changer le type de votre template par le model UML

    donc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [template public main(generation_main : Class)]
    devient

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [template public main(generation_main : Model)]
    Il faut ensuite itérer sur les classes à inclure avec un for

    Je complèterai certainement en fin de journée pour la structure qui est effectivement à revoir.


    Yann

  4. #4
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Juin 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2014
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    Super!

    Je vais essayer ces suggestions de ce pas.

    De mon coté j'étais arrivé à ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    class [aClass.name/] {
    private :
    [for (p: Property | aClass.attribute) separator('\n')]
          [p.type.name.toLowerCase()/] [p.name.toLowerCase()/];
          [/for]
     
    public :
    [aClass.name/]() ;
    [aClass.name/](const [aClass.name/] &) ;
    virtual ~[aClass.name/]() ;
     
       [for (p: Property | aClass.attribute) separator('\n')]
         [p.type.name.toLowerCase()/] get_[p.name.toLowerCase()/]() {
           return this -> [p.name.toLowerCase()/] ;
         }
       [/for]
     
     
       [for (o: Operation | aClass.ownedOperation) separator('\n')]
         [o.type.name.toLowerCase()/] [o.name.toLowerCase()/]([for(p:Parameter | o.ownedParameter) separator(', ')][if(p.direction.toString() = 'in')][p.type.name.toLowerCase()/] [p.n$
         }
         [for (p : Parameter | o.ownedParameter)]                                                                                ^
         [if (p.direction.toString() = 'return')]  <-- Ça marche inpec :-)                                                       |
         return [p.name.toLowerCase()/] ;                                                                                        ----- Ça ne marche pas (bien), j'ai une virgule de tro$
         [/if]
         [/for]
     [/for]
       } ;
    Cela ne fonctionne pas bien au niveau des arguments de la méthode, car
    même pour un paramètre de retour, il y a une itération : résultat une
    virgule de trop!

    Merci pour votre aide et je vous tiens au courant de mon avancement
    dans mes travaux.

    Ah! Une dernière question : Même s'il est toujours utile de savoir ce
    qu'il y à sous le capot en construisant from scratch, existe-t-il un
    (ou des) patron tout fait? J'ai fait quelques recherches et j'ai
    l'impression que l'on défriche.

    Encore merci et bonne journée.

  5. #5
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Juin 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2014
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    En exploitant correctement la propriété ParameterDirectionKind, on obtient le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
     
    [template public other_header(aClass : Class)]
    [comment @main /]
     [file (aClass.name.toLowerCase().prefix(aClass.name.toLowerCase().concat('/')).concat('.h'), false)]
    #ifndef [aClass.name.toUpper().concat('_H')/]
    #define [aClass.name.toUpper().concat('_H')/]
     
    #include <string>
     
    using namespace std ;
     
    class [aClass.name/] {
    private :
    [for (p: Property | aClass.attribute) separator('\n')]
          [p.type.name.toLowerCase()/] [p.name.toLowerCase()/];
          [/for]
     
    public :
    [aClass.name/]() ;
    [aClass.name/](const [aClass.name/] &) ;
    virtual ~[aClass.name/]() ;
       [for (p: Property | aClass.attribute) separator('\n')]
         [p.type.name.toLowerCase()/] get_[p.name.toLowerCase()/]() {
           return this -> [p.name.toLowerCase()/] ;
         }
       [/for]
     
     
       [for (o: Operation | aClass.ownedOperation) separator('\n')]
         [o.type.name.toLowerCase()/] [o.name.toLowerCase()/]([for(p:Parameter | o.ownedParameter->reject(direction = uml::ParameterDirectionKind::return)) separator(', ')][if(p.direc$
         }
         [for (p : Parameter | o.ownedParameter->reject(direction = uml::ParameterDirectionKind::_in))]
         return [p.name.toLowerCase()/] ;
         [/for]
         [/for]
       } ;
    #endif
     [/file]
     [/template]
    Effectivement, cela paraît bien plus simple maintenant : les
    structures if ont disparu.

    Et cela fonctionne impéccablement! :-))

    Maintenant, le problème du main.h écrit plusieurs fois...

  6. #6
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Juin 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2014
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    Bonjour à tous,

    Donc le problème d'écrasement du main.h est résolu (ligne 5) . Cela donne le code (presque) définitif :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
     
    [comment encoding = UTF-8 /]
    [module cpp('http://www.eclipse.org/uml2/4.0.0/UML')]
     
    [template public main_header(le_modele : Model)]
        [comment @main /]
        [file ('main.h', false)]
     
        [for (un_element:String|le_modele.ownedElement->selectByType(Class).name)]
    #include "[un_element.toLower().prefix(un_element.toLower().concat('/')).concat('.h')/]"
        [/for]
     
     
        [/file]
    [/template]
    [template public other_header(aClass : Class)]
    [comment @main /]
     [file (aClass.name.toLowerCase().prefix(aClass.name.toLowerCase().concat('/')).concat('.h'), false)]
    #ifndef [aClass.name.toUpper().concat('_H')/]
    #define [aClass.name.toUpper().concat('_H')/]
     
    #include <string>
     
    using namespace std ;
     
    class [aClass.name/] {
    private :   
        [for (p: Property | aClass.attribute) separator('\n')]
          [p.type.name.toLowerCase()/] [p.name.toLowerCase()/];
           [/for]
     
    public :
        [aClass.name/]() ;
        [aClass.name/](const [aClass.name/] &) ;
        virtual ~[aClass.name/]() ;
       [for (p: Property | aClass.attribute) separator('\n')]
         [p.type.name.toLowerCase()/] get_[p.name.toLowerCase()/]() {
           return this -> [p.name.toLowerCase()/] ;
         }
       [/for]
     
     
       [for (o: Operation | aClass.ownedOperation) separator('\n')]
         [o.type.name.toLowerCase()/] [o.name.toLowerCase()/]([for(p:Parameter | o.ownedParameter->reject(direction = uml::ParameterDirectionKind::return)) separator(', ')][if(p.direction.toString() = 'in')][p.type.name.toLowerCase()/] [p.name.toLowerCase()/][/if][/for]) {
            [for (p : Parameter | o.ownedParameter->reject(direction = uml::ParameterDirectionKind::_in))]
        [p.type.name.toLowerCase()/] [p.name.toLowerCase()/] ;
        return [p.name.toLowerCase()/] ;
            [/for]
        }
        [/for]
       } ;
    #endif
     [/file]
     [/template]
     
    [template public other_src(la_classe : Class)]
    [comment @main /]
        [file (la_classe.name.toLowerCase().prefix(la_classe.name.toLowerCase().concat('/')).concat('.cpp'), false)]
        #include "[la_classe.name/]"
     
     
       [for (o: Operation | la_classe.ownedOperation) separator('\n')]
         [o.type.name.toLowerCase()/] [o.name.toLowerCase()/]([for(p:Parameter | o.ownedParameter)separator(',')] [p.type.name.toLowerCase()/] [p.name.toLowerCase()/] [/for]) {
         }
       [/for]
     
        [/file]
    [/template]
    [template public main(generation_main : Model)]
    [comment @main /]
        [file ('main.cpp', false)]
    extern "C" {
    #include <unistd.h>
    #include <getopt.h>
    }
    # include "main.h"
    # include <iostream>
    # include <string>
     
    using namespace std ;
     
    int main(int argc, char **argv)
    {
      int opt ;
      static char optstring[ '[' /][ ']' /] = "h" ;
      while ((opt = getopt(argc, argv, optstring)) != -1)
        {
          switch (opt)
            {
            case 'h' :
              cout << argv['[' /]optind - 1[ ']' /] << " : Aide indisponible" << endl ;
              break ;
            case '?':
              cout << argv[ '[' /]optind - 1[ ']' /] << " : Option inconnue." << endl ;
              break;
            }
        }
     
     
      return 0 ;
    }
        [/file]
    [/template]
    [template public makefile(la_classe : Class)]
    [comment @main /]
    [file ('Makefile', false)]
    DEBUG=yes
    CC=g++
    COMMON_CFLAGS= -W -Wall -ansi -pedantic  -I /usr/include/boost/
    ifeq ($(DEBUG),yes)
            CFLAGS=$(COMMON_CFLAGS) -g
    else
            CFLAGS=$(COMMON_CFLAGS)
    endif
     
    LDFLAGS=-lboost_regex-mt -licuuc -lboost_filesystem-mt -lboost_system-mt -lboost_locale-mt -lsqlite3
    EXEC=loogle
    SRC= $(wildcard *.cpp)
    OBJ= $(SRC:.cpp=.o)
     
    all: $(EXEC)
    ifeq ($(DEBUG),yes)
        @echo "Génération en mode debug"
    else
        @echo "Génération en mode release"
    endif
     
    loogle: $(OBJ)
        @$(CC) -o $@ $^ $(LDFLAGS)
     
    %.o: %.cpp
        @$(CC) -o $@ -c $< $(CFLAGS)
     
    include .depend
     
    depend :
        g++ -MM *.cpp > .depend
     
    .PHONY: clean mrproper
     
    clean:
        @rm -rf *.o
     
    mrproper: clean
        @rm -rf $(EXEC)
    [/file]
    [/template]
    Par la même occasion, j'en ai profité pour améliorer le code concernant la valeur de retour des méthodes (lignes 46-47). En effet, le compilateur ne comprenait pas qu'une variable ne soit pas déclarée précédemment. Les lecteurs les plus attentifs auront néanmoins remarqué que cette variable est déclarée sans tester son existence parmi les paramètres de la méthode... Il faut donc que nous résolvions ce problème.

  7. #7
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Juin 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2014
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    C'est en exploitant son code que l'on s'aperçoit qu'il est... inexploitable!

    En voulant instancier un objet à partir d'une classe, le compilateur n'était pas du tout content.

    Tout d'abord, ce sont les fichiers d'implémentation (.cpp) qui incluent les fichiers d'entêtes (.h), et pas le contraire! ;-)

    Ensuite, il y avait des problèmes d'espace de noms.

    Tout ceci semble résolu avec cette nouvelle version.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
     
    [comment encoding = UTF-8 /]
    [module cpp('http://www.eclipse.org/uml2/4.0.0/UML')]
     
    [template public main_header(le_modele : Model)]
    	[comment @main /]
    	[file ('main.h', false)]
     
    	[for (un_element:String|le_modele.ownedElement->selectByType(Class).name)]
    #include "[un_element.toLower().prefix(un_element.toLower().concat('/')).concat('.cpp')/]"
        [/for]
     
     
    	[/file]
    [/template]
    [template public other_header(aClass : Class)]
    [comment @main /]
     [file (aClass.name.toLowerCase().prefix(aClass.name.toLowerCase().concat('/')).concat('.h'), false)]
    #ifndef [aClass.name.toUpper().concat('_H')/]
    #define [aClass.name.toUpper().concat('_H')/]
     
    #include <string>
     
    using namespace std ;
     
    class [aClass.name/] {
    private :   
    	[for (p: Property | aClass.attribute) separator('\n')]
          [p.type.name.toLowerCase()/] [p.name.toLowerCase()/];
       	[/for]
     
    public :
    	[aClass.name/]() ;
    	[aClass.name/](const [aClass.name/] &) ;
    	virtual ~[aClass.name/]() ;
       [for (p: Property | aClass.attribute) separator('\n')]
         [p.type.name.toLowerCase()/] get_[p.name.toLowerCase()/]() {
           return this -> [p.name.toLowerCase()/] ;
         }
       [/for]
     
     
       [for (o: Operation | aClass.ownedOperation) separator('\n')]
         [o.type.name.toLowerCase()/] [o.name.toLowerCase()/]([for(p:Parameter | o.ownedParameter->reject(direction = uml::ParameterDirectionKind::return)) separator(', ')][if(p.direction.toString() = 'in')][p.type.name.toLowerCase()/] [p.name.toLowerCase()/][/if][/for]) ;
    	[/for]
       } ;
    #endif
     [/file]
     [/template]
     
    [template public other_src(la_classe : Class)]
    [comment @main /]
    	[file (la_classe.name.toLowerCase().prefix(la_classe.name.toLowerCase().concat('/')).concat('.cpp'), false)]
    	#include "[la_classe.name.toLowerCase().concat('.h')/]"
     
    [la_classe.name/]::[la_classe.name/](){}
    [la_classe.name/]::~[la_classe.name/](){}
     
       [for (o: Operation | la_classe.ownedOperation) separator('\n')]
    		[o.type.name.toLowerCase()/] [la_classe.name/]::[o.name.toLowerCase()/]([for(p:Parameter | o.ownedParameter->reject(direction = uml::ParameterDirectionKind::return)) separator(', ')][if(p.direction.toString() = 'in')][p.type.name.toLowerCase()/] [p.name.toLowerCase()/][/if][/for]) {
    		[for (p : Parameter | o.ownedParameter->reject(direction = uml::ParameterDirectionKind::_in))]
    	[p.type.name.toLowerCase()/] [p.name.toLowerCase()/] ;
     
    	return [p.name.toLowerCase()/] ;
    		[/for]
         }
       [/for]
     
    	[/file]
    [/template]
    [template public main(generation_main : Model)]
    [comment @main /]
    	[file ('main.cpp', false)]
    extern "C" {
    #include <unistd.h>
    #include <getopt.h>
    }
    # include "main.h"
    # include <iostream>
    # include <string>
     
    using namespace std ;
     
    int main(int argc, char **argv)
    {
      int opt ;
      static char optstring[ '[' /][ ']' /] = "h" ;
      while ((opt = getopt(argc, argv, optstring)) != -1)
        {
          switch (opt)
            {
            case 'h' :
              cout << argv['[' /]optind - 1[ ']' /] << " : Aide indisponible" << endl ;
              break ;
            case '?':
              cout << argv[ '[' /]optind - 1[ ']' /] << " : Option inconnue." << endl ;
              break;
            }
        }
     
     
      return 0 ;
    }
    	[/file]
    [/template]
    [template public makefile(la_classe : Class)]
    [comment @main /]
    [file ('Makefile', false)]
    DEBUG=yes
    CC=g++
    COMMON_CFLAGS= -W -Wall -ansi -pedantic  -I /usr/include/boost/
    ifeq ($(DEBUG),yes)
            CFLAGS=$(COMMON_CFLAGS) -g
    else
            CFLAGS=$(COMMON_CFLAGS)
    endif
     
    LDFLAGS=-lboost_regex-mt -licuuc -lboost_filesystem-mt -lboost_system-mt -lboost_locale-mt -lsqlite3
    EXEC=loogle
    SRC= $(wildcard *.cpp)
    OBJ= $(SRC:.cpp=.o)
     
    all: $(EXEC)
    ifeq ($(DEBUG),yes)
    	@echo "Génération en mode debug"
    else
    	@echo "Génération en mode release"
    endif
     
    loogle: $(OBJ)
    	@$(CC) -o $@ $^ $(LDFLAGS)
     
    %.o: %.cpp
    	@$(CC) -o $@ -c $< $(CFLAGS)
     
    include .depend
     
    depend :
    	g++ -MM *.cpp > .depend
     
    .PHONY: clean mrproper
     
    clean:
    	@rm -rf *.o
     
    mrproper: clean
    	@rm -rf $(EXEC)
    [/file]
    [/template]
    Reste le problème évoqué dans le dernier poste...

  8. #8
    Nouveau Candidat au Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Juin 2014
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2014
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    Bonjour,
    Jusqu'à présent la visibilité des opérations n'était pas gérée, et bien ce matin c'est chose faite! (lignes 33 et 47)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
     
    [comment encoding = UTF-8 /]
    [module cpp('http://www.eclipse.org/uml2/4.0.0/UML')]
     
    [template public main_header(le_modele : Model)]
    	[comment @main /]
    	[file ('main.h', false)]
     
    	[for (un_element:String|le_modele.ownedElement->selectByType(Class).name)]
    #include "[un_element.toLower().prefix(un_element.toLower().concat('/')).concat('.cpp')/]"
        [/for]
     
     
    	[/file]
    [/template]
    [template public other_header(aClass : Class)]
    [comment @main /]
     [file (aClass.name.toLowerCase().prefix(aClass.name.toLowerCase().concat('/')).concat('.h'), false)]
    #ifndef [aClass.name.toUpper().concat('_H')/]
    #define [aClass.name.toUpper().concat('_H')/]
     
    #include <string>
     
    using namespace std ;
     
    class [aClass.name/] {
    Classe = [aClass.ownedOperation.visibility/]
    private :   
    	[for (p: Property | aClass.attribute) separator('\n')]
          [p.type.name.toLowerCase()/] [p.name.toLowerCase()/];
       	[/for]
     
       [for (o: Operation | aClass.ownedOperation->select(visibility = VisibilityKind::private)) separator('\n')]
         [o.type.name.toLowerCase()/] [o.name.toLowerCase()/]([for(p:Parameter | o.ownedParameter->reject(direction = uml::ParameterDirectionKind::return)) separator(', ')][if(p.direction.toString() = 'in')][p.type.name.toLowerCase()/] [p.name.toLowerCase()/][/if][/for]) ;
    	[/for]
     
    public :
    	[aClass.name/]() ;
    	[aClass.name/](const [aClass.name/] &) ;
    	virtual ~[aClass.name/]() ;
       [for (p: Property | aClass.attribute) separator('\n')]
         [p.type.name.toLowerCase()/] get_[p.name.toLowerCase()/]() {
           return this -> [p.name.toLowerCase()/] ;
         }
       [/for]
     
       [for (o: Operation | aClass.ownedOperation->select(visibility = VisibilityKind::public)) separator('\n')]
         [o.type.name.toLowerCase()/] [o.name.toLowerCase()/]([for(p:Parameter | o.ownedParameter->reject(direction = uml::ParameterDirectionKind::return)) separator(', ')][if(p.direction.toString() = 'in')][p.type.name.toLowerCase()/] [p.name.toLowerCase()/][/if][/for]) ;
    	[/for]
       } ;
    #endif
     [/file]
     [/template]
     
    [template public other_src(la_classe : Class)]
    [comment @main /]
    	[file (la_classe.name.toLowerCase().prefix(la_classe.name.toLowerCase().concat('/')).concat('.cpp'), false)]
    	#include "[la_classe.name.toLowerCase().concat('.h')/]"
     
    [la_classe.name/]::[la_classe.name/](){}
    [la_classe.name/]::~[la_classe.name/](){}
     
       [for (o: Operation | la_classe.ownedOperation) separator('\n')]
    		[o.type.name.toLowerCase()/] [la_classe.name/]::[o.name.toLowerCase()/]([for(p:Parameter | o.ownedParameter->reject(direction = uml::ParameterDirectionKind::return)) separator(', ')][if(p.direction.toString() = 'in')][p.type.name.toLowerCase()/] [p.name.toLowerCase()/][/if][/for]) {
    		[for (p : Parameter | o.ownedParameter->reject(direction = uml::ParameterDirectionKind::_in))]
    	[p.type.name.toLowerCase()/] [p.name.toLowerCase()/] ;
     
    	return [p.name.toLowerCase()/] ;
    		[/for]
         }
       [/for]
     
    	[/file]
    [/template]
    [template public main(generation_main : Model)]
    [comment @main /]
    	[file ('main.cpp', false)]
    extern "C" {
    #include <unistd.h>
    #include <getopt.h>
    }
    # include "main.h"
    # include <iostream>
    # include <string>
     
    using namespace std ;
     
    int main(int argc, char **argv)
    {
      int opt ;
      static char optstring[ '[' /][ ']' /] = "h" ;
      while ((opt = getopt(argc, argv, optstring)) != -1)
        {
          switch (opt)
            {
            case 'h' :
              cout << argv['[' /]optind - 1[ ']' /] << " : Aide indisponible" << endl ;
              break ;
            case '?':
              cout << argv[ '[' /]optind - 1[ ']' /] << " : Option inconnue." << endl ;
              break;
            }
        }
     
     
      return 0 ;
    }
    	[/file]
    [/template]
    [template public makefile(la_classe : Class)]
    [comment @main /]
    [file ('Makefile', false)]
    DEBUG=yes
    CC=g++
    COMMON_CFLAGS= -W -Wall -ansi -pedantic  -I /usr/include/boost/
    ifeq ($(DEBUG),yes)
            CFLAGS=$(COMMON_CFLAGS) -g
    else
            CFLAGS=$(COMMON_CFLAGS)
    endif
     
    LDFLAGS=-lboost_regex-mt -licuuc -lboost_filesystem-mt -lboost_system-mt -lboost_locale-mt -lsqlite3
    EXEC=loogle
    SRC= $(wildcard *.cpp)
    OBJ= $(SRC:.cpp=.o)
     
    all: $(EXEC)
    ifeq ($(DEBUG),yes)
    	@echo "Génération en mode debug"
    else
    	@echo "Génération en mode release"
    endif
     
    loogle: $(OBJ)
    	@$(CC) -o $@ $^ $(LDFLAGS)
     
    %.o: %.cpp
    	@$(CC) -o $@ -c $< $(CFLAGS)
     
    include .depend
     
    depend :
    	g++ -MM *.cpp > .depend
     
    .PHONY: clean mrproper
     
    clean:
    	@rm -rf *.o
     
    mrproper: clean
    	@rm -rf $(EXEC)
    [/file]
    [/template]
    Reste que le code devient de plus en plus sale. Quelques idées peut-être?

Discussions similaires

  1. Générer du code grâce aux annotations
    Par yous_han dans le forum Eclipse Platform
    Réponses: 0
    Dernier message: 11/12/2010, 18h16
  2. [Debutant(e)]Générer du code JSP dynamiquement
    Par Gibier dans le forum Servlets/JSP
    Réponses: 6
    Dernier message: 16/01/2004, 11h54
  3. [EclipseUml] Peut-on générer le code ?
    Par Dof dans le forum Eclipse Java
    Réponses: 3
    Dernier message: 05/06/2003, 15h21
  4. Générer du code HTML
    Par patpst dans le forum C++Builder
    Réponses: 4
    Dernier message: 27/11/2002, 10h27

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo