Expertise (5/5)
Je développe en C depuis 14 ans. Je m’oriente de plus en plus vers des langages qui possèdent des trousses à outils plus riches et qui sont plus demandés sur le marché du travail (PHP, Java, C#, en particulier).
Descrition
Ce code est extrait d'un logiciel que j'ai développé et dont la fonction tait d'assurer la répartition de charge entre plusieurs serveurs.
Le fichier de configuration du logiciel contient, entre autres choses, des lignes qui ressemblent à ça :
Remarque: Veuillez noter que cet exemple de fichier de configuration ne contient pas de caractère "espace". Il n'y a que des tabulations.
L'analyseur syntaxique - loadb.lex
Remarque: Notez l'utilisation des contextes.
Note: Pour accepter les fins de lignes sous UNIX ou sous Windows:
Intégration de l'analyseur au code du logiciel - loadb.c
Makefile
Sources
Veuillez cliquer sur le lien pour télécharger les sources de l'analyseur.
Descrition
Cet exemple crée un petit serveur sur lequel il est possible de se connecter via Telnet. Ce serveur reçoit des chaînes de caractères, censées contenir des tags "${TAG}" (exemples "${NAME}", "${ADDRESS}",...). Ce serveur extrait les noms des tags envoyés et il les affiche simplement.
Remarque: Ce code est inspiré d'un serveur beaucoup plus complexe que j'ai développé.
L'analyseur syntaxique - fdscan.lex
Intégration de l'analyseur au code du logiciel - fdscan.c
Instructions de compilation
Sources
Veuillez cliquer sur le lien pour télécharger les sources de l'analyseur.
Descrition
Cet exemple illustre les points suivants :
- Anayse syntaxique de tampons stockés en mémoire.
- Utilisation de deux analyseurs syntaxiques au sein d'un même logiciel.
Premier analyseur syntaxique - hasher.lex
Second analyseur syntaxique - hasher1.lex
Intégration des deux analyseurs au logiciel - test_hasher.c
Instructions de compilation
Sources
Veuillez cliquer sur le lien pour télécharger les sources de l'analyseur.
- If a start condition is inclusive, then rules with no start conditions at all will also be active.
- If a start condition is exclusive, then only rules qualified with the start condition will be active.
- Exclusive start conditions are not executed at startup. They are executed when you call BEGIN(condition).
- A BEGIN(COMMAND) at the begining of all rules says that we start the parser in the COMMAND start condition. But BEGIN is executed whenever you call yylex() ! Not only first time.
- If the parser finds more than one match, it takes the one matching the most text.
- If the finds two or more matches of the same length, the rule listed first in the flex input file is chosen.
Cet exemple est tiré du code d'un serveur SMTP très spécifique (pour une utilisation spécialisée) que j'ai développé. Ce serveur simple affiche le contenu des sections "DATA" des emails envoyés par les clients.
L'analyseur syntaxique - smtpd.lex
Intégration de l'analyseur au code du logiciel - smtpd.c et smtpd.h
Makefile
Les analyseurs Flex "en C" utilisent des variables globales. Ces variables sont utilisées pour stocker des états internes à la fonction yylex(). Par conséquent, il est impossible d'utiliser un analyseur Flex "en C" pour analyser deux flux en même temps.
Pour générer un analyseur Flex qui soit capable d'analyser plusieurs flux simultanément, il faut passer par l'utilisation du C++. Les variables utilisées pour stocker les états de l'analyseur sont "encapsulées" dans des classes.
L'analyseur syntaxique - file.lex
Intégration de l'analyseur dans un outil destiné à lire des fichiers - file.cc
Intégration de l'analyseur dans un outil destiné à lire des tampons (en mémoire) - string.cc
Makefile
Ce serveur DHCP a été développé pour répondre aux besoins spécifiques d’un gros fournisseur d’accès Internet.
- Il utilise une base MySql dans laquelle sont stockées toutes les adresses IP de tous les clients.
- Un cliet se voit associer deux adresses IP: une adresse IP pour son routeur ADSL et une adresse IP pour son décodeur TV.
- Une adresse IP est associée à un ensemble de 5 valeurs : 4 valeurs issues de l’option 82 du paquet DHCP, et le numéro de VLAN.
- Ce serveur s’intègre à des systèmes d’information qu’il met à jour en temps réel.
- Le serveur intègre des greffons («.so») fonctionnels. Ces greffons permettent d’étendre les fonctions du serveur, sans toucher au code de ce dernier.
Remarque: Ce serveur a supporté environ 1 500 000 clients DHCP pendant 3 trois, sans interruption. Aucun problème n’a été constaté.
Les fichiers d'entête
ack_codes.h
config.h
conversion.h
dhcp.h
find_ip_and_reply.h
flock.h
libhttp.h
libip.h
logging.h
logistic.h
modem.h
mysql_header.h
mysql_interface.h
packets.h
packets_data.h
packets_operations.h
server_config.h
sockets.h
tables.h
Les fichiers C et Flex
config.c
config.lex
configuration.c
conversion.c
dhcp.c
find_ip_and_reply.c
flock.c
hitachi.c
libhttp.c
libip.c
logging.c
logistic.c
modem.c
mysql.c
mysql_interface.c
packets.c
packets_operations.c
read_conf.c
sockets.c
vci_surf.c
vci_tv.c
Configuration Doxygen
Documentation du code
Cliquez sur ce lien pour accéder à la documentation du serveur DHCP. Cette documentation a été générée avec Doxygen.
Makefile
Les codes ci-après sont extraits d’une petite librairie que j’ai développée au fil du temps. Veuillez cliquer sur ce lien pour télécharger l’archive de la librairie.
Les entêtes
array.h
bitmanip.h
buffers.h
cgi.h
chtbl.h
config.h
cyclic_buffer.h
date.h
deamon.h
dmalloc.h
double_list.h
dstring.h
files.h
flock.h
hashfunc.h
list.h
my_dir.h
my_endian.h
my_math.h
my_sem.h
my_shm.h
my_smtp.h
my_sockets.h
option.h
replacer.h
sha.h
signals.h
sort.h
stack.h
strings_utils.h
timing.h
Les sources
array.c
cgi.c
char2hex.c
chtbl.c
config.c
config.lex
cyclic_buffer.c
date.c
date.lex
dates.c
deamon.c
dir.c
dmalloc.c
dstring.c
endian.c
files.c
flock.c
hashfunc.c
issort.c
list.c
make_char2hex.c
make_char2int.c
make_dates.c
make_hexa_codes.c
my_math.c
option.c
os_specific.c
qksort.c
rand_dates.c
replacer.c
replacer.lex
sem.c
sha.c
shm.c
signals.c
smtp.c
smtp.lex
sockets.c
stack.c
strings_utils.c
timing.c
ttref.lex
Makefile
Le code suivant est extrait d’un moteur de Workflow que j’ai développé pour un opérateur télécom. L’analyseur grammatical implémente les fonctions suivantes :
- Opérateur OR, AND, XOR, NOT.
- Gestion des priorités entre les opérateurs.
- Gestion des parenthèses (niveau arbitraire d’imbrication).
- Détection de toutes les erreurs.
L’analyseur transforme une expression arithmétique en expression RPN (Revers Polish Notation).
Exemple:
INPUT BOOLEAN EXPRESSION: "b1 OR b2 AND b3 OR (b4 AND b5) XOR NOT b6"
OUTPUT (RPN representation):
b1
b2
b3
and()
or()
b4
b5
and()
b6
not()
xor()
or()
L'analyseur grammatical: bool.y
L'analyseur lexical: bool.lex
Gestion de chaînes dynamiques: linked_list.c
Programme de test: test_bool.c
boolean_analyzer.h
grammar_types.h
linked_list.h
Makefile
Code source
Le code est disponible sur
ce lien.
Les outils de compilation
Tool
| GNU
| Microsoft Visual C++ |
The compiler
| g++ (alias gcc)
| cl.exe |
The linker
| ld
| link.exe |
The make utility
| gmake (alias make)
| nmake.exe |
Dumping binary content
| objdump
| dumpbin.exe |
Library dumping
| nm
| dumpbin.exe |
Building a library
| ar (and optionally ranlib)
| lib.exe
|
Les Makefiles
The text below is my first Visual C++ "Makefile":
It looks pretty much like a standard UNIX Makefile. The following "Makefile" illustrates the GNU version of a Makefile.
Configuration de compilation
The following table illustrates common compiler's configuration options.
What to do
| GCC
| Visual C++ |
Where to look for extra header files
| -Iinclude_path
| Tools => Options => "show directories for" => "include files"
/Iinclude_path |
Where to look for extra libraries
| -Llibrary_path
| Tools => Options => "show directories for" => "library files"
/link /LIBPATH:library_path |
Linking a library:
| -lname
This will link the library libname.a
| Project => settings => link
Just add the library name to the compiler's command line. Any files with
name extension other than .C, .CXX, .CPP, or .DEF are passed to the linker. |
Specify an output file name
| -ofile_name
| Project => settings => link
- /Fefile_name (to create an executable).
- /Fofile_name.obj (to create an onject file).
|
Compile only, produce an object file.
| -c
This will create a ".o" file.
| /c /Fofile_name.obj
This will create a ".obj" file. |
Produce full warning output
| -Wall
| Project => settings => C/C++ => category => General
/W4 |
Define a macro
| -Dmacro[=...]
| Project => settings => C/C++ => category => preprocessor
/Dmacro[=...] |
Undefine a macro
| -Umacro
| Project => settings => C/C++ => category => preprocessor
/Umacro |
Building a static library
| ar rcs library_name.a file1.o file2.o file3.o ...
| lib.exe file1.obj file2.obj ... /OUT:library_name.lib |
Building a dynamic library
| gcc -shared -fPIC -ldl -o library_name.so file1.o file2.o ...
| link.exe /DLL file1.obj file2.obj ... /OUT:library_name.dll
|
Cet exemple illustre les opérations de base:
- Création d'une base de donnée.
- Insertion d’enregistrements.
- Recherche.
- Suppression.
- Fermeture de la base.
Création de deux bases au sein d'un même fichier.
Cet exemple illustre les opérations de base:
- Ajout d’un enregistrement à la fin d’une base de type RECNO.
- Utilisation de curseurs.