C'est à peu de chose près, ce qui j'ai dit plus haut, sauf pour LANGUAGE_UNKNOWN pour lequel je ne suis pas d'accord.
En C, si l'enum est écrit LANGUAGE_UNKWOWN = 255, sa valeur vaut 255, pas 256 (voir l'énoncé de djibril).
C'est à peu de chose près, ce qui j'ai dit plus haut, sauf pour LANGUAGE_UNKNOWN pour lequel je ne suis pas d'accord.
En C, si l'enum est écrit LANGUAGE_UNKWOWN = 255, sa valeur vaut 255, pas 256 (voir l'énoncé de djibril).
Plus j'apprends, et plus je mesure mon ignorance (philou67430)
Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
Si c'est utile, say
hum autant pour moi j'ai fait une faute de frappe :p
Donc si tu reprends un peu mieux le patch que j'avais fourni, tu devrais obtenir ce résultat, sans oublier de corriger l'usage de %VariableDefine.
Plus j'apprends, et plus je mesure mon ignorance (philou67430)
Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
Si c'est utile, say
yes, sauf que je comprend pas pour l'inversion de l'increment
bon le C, ça fait des lustres que j'en ai pas fait.
L'idéal c'est de se mettre d'accord.
Pour ce fichier :
Voici ce que j'obtiens, j'espère que c'est OK pour vous
Code c : 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 typedef enum { NO_CARD = 1 , CARD_INSERTED , CARD_REMOVED , CARD_DETECTED , CARD_JAM , CARD_SCANNED } CARD_STATUS; #define TOP_CAD_PRIVATE_COMMAND 254 #define MAX_COMMAND_NUM 255 #define TOP_GENERIC_COMMAND 254 typedef enum { CARD_ON = TOP_GENERIC_COMMAND, CARD_OFF } CARD_STATUS; typedef enum { LANGUAGE_NONE = 0, LANGUAGE_DUTCH, LANGUAGE_ENGLISH, LANGUAGE_FRENCH, LANGUAGE_GERMAN, LANGUAGE_ITALIAN, LANGUAGE_SPANISH, LANGUAGE_UNKNOWN = 255 } LANGUAGE;
Par rapport à vous résultat, pourquoi CARD_OFF = 255 et non 0 vu qu'on commenceDefines:
TOP_GENERIC_COMMAND = 254
MAX_COMMAND_NUM = 255
TOP_CAD_PRIVATE_COMMAND = 254
============
Constantes definies dans les typedef:
LANGUAGE
- LANGUAGE_ENGLISH = 2
- LANGUAGE_DUTCH = 1
- LANGUAGE_UNKNOWN = 255
- LANGUAGE_ITALIAN = 5
- LANGUAGE_FRENCH = 3
- LANGUAGE_NONE = 0
- LANGUAGE_GERMAN = 4
- LANGUAGE_SPANISH = 6
CARD_STATUS
- CARD_OFF = 0
- CARD_ON = 254
l'incrémentation pour chaque enum à 0 ?
Voici le code
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 #!/usr/bin/perl # But : Parsing d'un fichier de type C use warnings; use strict; use Regexp::Common qw /comment/; use Perl6::Slurp; # Englobe le fichier .h my $CodeFichierC = slurp "pub_serv.h"; #ouverture du fichier *.txt en mode Ecriture open WRITER, '>', "decode2.txt" or die "Le fichier ne peut être édité !\n"; # Suppression des commentaires C my $RegexComment = $RE{comment}{'C++'}; #C++ pour supprimer /* */ ET // $CodeFichierC =~ s{$RegexComment}{}g; # Recupère tous les define du fichier my @define = $CodeFichierC =~ m{ ^\s* # La ligne commence par un espace ou non \#define # suivi de #define \s* # espace ou non ([^\n]+)\s* # contenu define \n # se termine par un retour chariot }mgix; # Dans le hash, la cle sera le nom d'un define et la valeur celle du define. my %VariableDefine; foreach my $Define (@define) { my ( $var, $value ) = split( /\s+/, $Define ); $VariableDefine{$var} = $value || ''; } print WRITER "Defines: \n\n"; foreach my $var ( keys %VariableDefine ) { print WRITER "$var = $VariableDefine{$var}\n"; } print WRITER "\n============\n\n"; # Recupère tous les bloc enum avec le nom de l'enum (le tout dans @typedef) # Si le bloc ne match pas avec la regex, il ne sera pas dans @BlocEnum my @BlocEnum = $CodeFichierC =~ m/ ( enum[^{]+{ # Ligne enum suivi de tous sauf une accolade + accolade [^}]+ # contenu tout sauf accolade fermante } # accolade fermante [^;]+; # suivi du nom de l'enum plus virgule ) /mgix; # On va maintenant traiter chaque bloc enum my %EnumData; foreach my $DonneeEnum (@BlocEnum) { my ( $ContenuBloc, $NomEnum ) = $DonneeEnum =~ m/ { ([^}]+) # contenu du bloc (tout sauf accolade) } ([^;]+);$ # Nom enum /mgix; # On enleve les retour chariot et espace $NomEnum =~ s{[\n\s]}{}g; $ContenuBloc =~ s{[\n\s]}{}g; # Recupération des constances dans $ContenuBloc my %Constante; my $Valeur = 0; foreach my $Enumerateur ( split( ',', $ContenuBloc ) ) { my ( $Nomvariable, $test ) = split( '=', $Enumerateur ); # si la valeur existe, on l'incremente, sinon on la met à 0 if ( defined $test) { # On vérifie qu'il est present dans define ou non if ( defined $VariableDefine{$test} ) { $test = $VariableDefine{$test}; } else { $Valeur++; } } else { $test = $Valeur; $Valeur++; } $Constante{$Nomvariable} = $test; } # A chaque enum, on associ un hash contenant ces constance $EnumData{$NomEnum} = \%Constante; } # Affichage des enum avec cnostances print WRITER "Constantes definies dans les typedef: \n\n"; while ( my ( $Enum, $RefConstances ) = each %EnumData ) { print WRITER "$Enum\n"; while ( my ( $constante, $valeur ) = each %{$RefConstances} ) { print WRITER "\t- $constante = $valeur \n"; } } close(WRITER);
- Les meilleurs cours et tutoriels Perl et Perl 6 pour vous former ;
- FAQ Perl, Perl 6 et Perl/Tk d'entraide ;
- Les news sur la rubrique Perl ;
- S'abonner au compte Twitter de la rubrique Perl ;
- Mes tutoriels developpez.com.
Pas de questions technique par messagerie privée (lisez les règles du forum Perl) et pour les nouveaux !
Djibril, dans un enum en C, lorsque tu commences à définir un énuméré, tous ceux qui suivent et qui ne sont pas définis avec une valeur sont simplement incrémentés par rapport au précédent.
Lorsque tu ne définis AUCUNE valeur dans l'énuméré, le premier énuméré commence à 0. C'est donc seulement dans ce cas qu'il faut initialiser $Valeur à 0. Dans tous les autres cas, soit on incrémente la valeur précédente, soit on prend la valeur spécifiée telle qu'elle.
Donc pour le cas de CARD_OFF, comme il est défini après CARD_ON et qu'il n'a pas de valeur définie, CARD_OFF vaudra CARD_ON + 1.
Plus j'apprends, et plus je mesure mon ignorance (philou67430)
Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
Si c'est utile, say
Ok, merci pour l'explication.
Donc ça change un peu la logique du code car pour le premier enum on obtient un bon résultat par chance l'initialisation de $valeur à 0 coincide avec le faite que LANGUAGE_NONE = 0, mais s'il était égal à 10, ce ne serait pas bon. D'ou l'importance d'avoir des exemples clairs sinon on tourne en rond et chacun perd son temps.
Exemple :
donne
Code c : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 typedef enum { LANGUAGE_NONE = 10, LANGUAGE_DUTCH, LANGUAGE_ENGLISH, LANGUAGE_FRENCH, LANGUAGE_GERMAN, LANGUAGE_ITALIAN, LANGUAGE_SPANISH, LANGUAGE_UNKNOWN = 255 } LANGUAGE;
au lieu deLANGUAGE
- LANGUAGE_ENGLISH = 2
- LANGUAGE_DUTCH = 1
- LANGUAGE_UNKNOWN = 255
- LANGUAGE_ITALIAN = 5
- LANGUAGE_FRENCH = 3
- LANGUAGE_NONE = 10
- LANGUAGE_GERMAN = 4
- LANGUAGE_SPANISH = 6
si j'ai bien comprisLANGUAGE
- LANGUAGE_ENGLISH = 12
- LANGUAGE_DUTCH = 11
- LANGUAGE_UNKNOWN = 255
- LANGUAGE_ITALIAN = 15
- LANGUAGE_FRENCH = 13
- LANGUAGE_NONE = 10
- LANGUAGE_GERMAN = 14
- LANGUAGE_SPANISH = 16
- Les meilleurs cours et tutoriels Perl et Perl 6 pour vous former ;
- FAQ Perl, Perl 6 et Perl/Tk d'entraide ;
- Les news sur la rubrique Perl ;
- S'abonner au compte Twitter de la rubrique Perl ;
- Mes tutoriels developpez.com.
Pas de questions technique par messagerie privée (lisez les règles du forum Perl) et pour les nouveaux !
bon modification
en rajoutant en début de script
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 foreach my $Enumerateur ( split( ',', $ContenuBloc ) ) { my ( $Nomvariable, $test ) = split( '=', $Enumerateur ); # si la valeur existe, on l'incremente, sinon on la met à 0 if ( defined $test) { # On vérifie qu'il est present dans define ou non if ( defined $VariableDefine{$test} ) { $test = $VariableDefine{$test}; $Valeur = List::Util::max($Valeur,$test) +1; } else { $Valeur ++; } } else { $Valeur = List::Util::max( values %Constante ) + 1 || $Valeur; $test = $Valeur; $Valeur++; } $Constante{$Nomvariable} = $test; }ainsi :
Code : Sélectionner tout - Visualiser dans une fenêtre à part use List::Util;
donne
Code c : 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 typedef enum { NO_CARD = 1 , CARD_INSERTED , CARD_REMOVED , CARD_DETECTED , CARD_JAM , CARD_SCANNED } CARD_STATUS; #define TOP_CAD_PRIVATE_COMMAND 254 #define MAX_COMMAND_NUM 255 #define TOP_GENERIC_COMMAND 254 typedef enum { CARD_ON = TOP_GENERIC_COMMAND, CARD_OFF } CARD_STATUS; typedef enum { LANGUAGE_NONE = 10, LANGUAGE_DUTCH, LANGUAGE_ENGLISH, LANGUAGE_FRENCH, LANGUAGE_GERMAN, LANGUAGE_ITALIAN, LANGUAGE_SPANISH, LANGUAGE_UNKNOWN = 255 } LANGUAGE;
Voilà, bon courage pour la suite.
Code c : 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 Defines: TOP_GENERIC_COMMAND = 254 MAX_COMMAND_NUM = 255 TOP_CAD_PRIVATE_COMMAND = 254 ============ Constantes definies dans les typedef: LANGUAGE - LANGUAGE_ENGLISH = 12 - LANGUAGE_DUTCH = 11 - LANGUAGE_UNKNOWN = 255 - LANGUAGE_ITALIAN = 15 - LANGUAGE_FRENCH = 13 - LANGUAGE_NONE = 10 - LANGUAGE_GERMAN = 14 - LANGUAGE_SPANISH = 16 CARD_STATUS - CARD_OFF = 255 - CARD_ON = 254
- Les meilleurs cours et tutoriels Perl et Perl 6 pour vous former ;
- FAQ Perl, Perl 6 et Perl/Tk d'entraide ;
- Les news sur la rubrique Perl ;
- S'abonner au compte Twitter de la rubrique Perl ;
- Mes tutoriels developpez.com.
Pas de questions technique par messagerie privée (lisez les règles du forum Perl) et pour les nouveaux !
Ton dernier résultat est effectivement ce qu'il faut obtenir (pas comme dans le message précédent, où je crois que tu as inversé).
Par contre, j'ai dit une bêtise plus tôt en parlant de l'usage de %VariableDefine : il est correctement utilisé.
Comme je l'ai fait remarquer plus haut, cela ne règle pas l'ensemble des formes grammaticales possibles en C pour la définition des énumérés, comme celle d'utiliser une valeur d'un énuméré comme base de calcul pour un autre... mais ceci est une autre histoire (CARD_ON = CARD_OFF + 10 par exemple).
Plus j'apprends, et plus je mesure mon ignorance (philou67430)
Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
Si c'est utile, say
- Les meilleurs cours et tutoriels Perl et Perl 6 pour vous former ;
- FAQ Perl, Perl 6 et Perl/Tk d'entraide ;
- Les news sur la rubrique Perl ;
- S'abonner au compte Twitter de la rubrique Perl ;
- Mes tutoriels developpez.com.
Pas de questions technique par messagerie privée (lisez les règles du forum Perl) et pour les nouveaux !
Rebonjour
Merci pour votre aide
Bon je tente quand même d'exposer une chose que je ne comprend pas:
Dans ton code Djibril, Eclipse me dit pour la ligne :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 $Valeur = List::Util::max(values %Constante) +1 || $Valeur;Et je ne comprend pas du tout ça en fait...
Code : Sélectionner tout - Visualiser dans une fenêtre à part Use of uninitialized value in addition (+)
Désolé si je n'ai pas été assez clair sur certains points, mais c'est pas évident de déceler toutes les particularité d'un header de plus de 2000 lignes (en tout cas moi j'y arrive pas :p )
ps: j'ai bien rajouté en début de script
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2use List::Util;
cela veut dire qu'à un moment où Perl est en train de faire
, il y a une valeur qui est non initialisée, probablement %Constante.
Code : Sélectionner tout - Visualiser dans une fenêtre à part $Valeur = List::Util::max(values %Constante) +1 || $Valeur;
Remplace
par
Code : Sélectionner tout - Visualiser dans une fenêtre à part $Valeur = List::Util::max( values %Constante ) + 1 || $Valeur;
Peux tu nous montrer ton fichier de 2000 lignes histoire qu'on le test si c pas discret
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 if ( my @Values = values %Constante ) { $Valeur = List::Util::max( @Values ) + 1; }
- Les meilleurs cours et tutoriels Perl et Perl 6 pour vous former ;
- FAQ Perl, Perl 6 et Perl/Tk d'entraide ;
- Les news sur la rubrique Perl ;
- S'abonner au compte Twitter de la rubrique Perl ;
- Mes tutoriels developpez.com.
Pas de questions technique par messagerie privée (lisez les règles du forum Perl) et pour les nouveaux !
Pour le header de 2000 lignes, je ne peux pas le distribuer comme ca, il est soumis à un copyright dsl
ok
- Les meilleurs cours et tutoriels Perl et Perl 6 pour vous former ;
- FAQ Perl, Perl 6 et Perl/Tk d'entraide ;
- Les news sur la rubrique Perl ;
- S'abonner au compte Twitter de la rubrique Perl ;
- Mes tutoriels developpez.com.
Pas de questions technique par messagerie privée (lisez les règles du forum Perl) et pour les nouveaux !
Je prefere pas prendre de risques...
Merci de ta compréhension
Mmmm... je me dis que cette ligne
étant exécutée inconditionnellement (donc y compris si $test est indéfini), il est possible que %Constante contienne des clés pour lesquelles les valeurs sont indéfinies.
Code : Sélectionner tout - Visualiser dans une fenêtre à part $Constante{$Nomvariable} = $test;
Ca n'a pas l'air d'avoir d'influence sur la fonction max, qui semble ignorer ces valeurs, mais il me semble qu'il sera sain pour éviter tout autre effet de bord que le hash %Constante ne contienne que des variables valides.
Plus j'apprends, et plus je mesure mon ignorance (philou67430)
Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
Si c'est utile, say
Salut!
Désolé pour cette période d'absence j'étais assez occupé.
De retour dans le perl je rajoute un nouveau problème au palamarès de mes problèmes que j'arrive pas à résoudre.
La ca me paraît assez simple à résoudre, mais j'ai beau essayer de chercher etc... je trouve pas du tout.
Donc voila:
J'ai des define de "forme normale" dans mon header.
Et j'en ai d'autres d'une autre forme:
Le problème est que dans la recherche du define, je fais ([^\n]*) donc il est censé prendre tout jusqu'a un retour chariot, hors après execution du script, j'obtiens seulement
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2#define ICCIS_CARD_STATUS_FLD ((DWORD)(1UL << 0))
Je ne comprend pas pourquoi il s'arrête là alors qu'il ne rencontre pas de retour chariot.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 ICCIS_CARD_STATUS_FLD = ((DWORD)(1UL
Une idée?
ps: si vous en avez marre aucun soucis, je comprend tout à fait, mais sachez juste que je ne fais pas ça pour un projet quelcquonque, c'est juste pour m'améliorer en Perl, et j'ai un peux de mal avec ce language. Libre à vous de continuer à m'aider
En tout cas merci déja pour votre aide
Si tu nous mettez ta vraie regex
- Les meilleurs cours et tutoriels Perl et Perl 6 pour vous former ;
- FAQ Perl, Perl 6 et Perl/Tk d'entraide ;
- Les news sur la rubrique Perl ;
- S'abonner au compte Twitter de la rubrique Perl ;
- Mes tutoriels developpez.com.
Pas de questions technique par messagerie privée (lisez les règles du forum Perl) et pour les nouveaux !
Alors je me suis dis si il va pas jusqu'au retour de chariot alors qu'il est censé le faire je me suis dit qu'il aille au moins jusqu'au 2 parenthèses fermantes donc à la place de ([^\n]*) j'ai tenté ([^\)\)]*) mais ca ne fonctionne pas.
Mais je comprend vraiment pas pourquoi il ne prend pas la fin du define. Il s'arrete alors qu'il n'y a pas de retour chariot et ca je comprend pas du tout :p
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 my @define = $CodeFichierC =~ m{ ^\s* # La ligne commence par un espace ou non \#define # suivi de #define \s* # espace ou non ([^\)\)]*) # contenu define jusqu'au parenthèses fermantes \n # se termine par un retour chariot }mgix;
Dans un groupe [ ], tu mets une liste de caractère admissible, mais il n'est pas possible d'y introduire des groupes de caractère.
Sinon, j'ai simplement utilisé ([^\n]*) et je peux capturer sans problème la fin du define :
Au lieu de matcher "\n", je préfère utiliser $.$ echo "#define ICCIS_CARD_STATUS_FLD ((DWORD)(1UL << 0))" | perl -e '$a = <STDIN>;@a = $a =~ /^\s*\#define\s*([^\n]*)\n/mgix;print join " : ", @a'
ICCIS_CARD_STATUS_FLD ((DWORD)(1UL << 0))
La regexp suivante fonctionne donc également
Code : Sélectionner tout - Visualiser dans une fenêtre à part /^\s*\#define\s*(.*)$/mgix
Plus j'apprends, et plus je mesure mon ignorance (philou67430)
Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
Si c'est utile, say
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager