Logs
Consultez les logs.
OK
Liste des données
Consultez la liste des données.
OK
Loading...
Formulaire
Saisissez vos données.
Enregistrer
Annuler

Programmation C

Vues
641

Introduction


C est un langage procédural impératif, prenant en charge la programmation structurée, la portée des variables lexicales et la récursivité, avec un système de type statique. Il a été conçu pour être compilé afin de fournir un accès de bas niveau à la mémoire et aux constructions de langage qui correspondent efficacement aux instructions machine, le tout avec une prise en charge minimale de l'exécution. Malgré ses capacités de bas niveau, le langage a été conçu pour encourager la programmation multiplateforme. Un programme C conforme aux standards écrit avec portabilité à l'esprit peut être compilé pour une grande variété de plates-formes informatiques et de systèmes d'exploitation avec peu de changements à son code source.

image.png


Recommandations techniques


Pour tester les extraits de code dans ce tutoriel, vous aurez besoin des éléments suivants:

Un compilateur C WinLibs sous Windows
Activer les standards c11
Installer GCC (GNU Compiler Collection) sous Linux.


Affichage d'un message



Affichage d'un message


Résultat:

image.png

Affichage d'un message:
 
//===============================================
// main.c
//===============================================
#include <stdio.h>
//===============================================
int main(int _argc, char** _argv) {
    printf("Bonjour tout le monde.\n");
    return 0;
}
//===============================================


Programmation par procédure



Affichage d'un message


Résultat:

image.png

Affichage d'un message:
 
//===============================================
// main.c
//===============================================
#include <stdio.h>
//===============================================
int main(int _argc, char** _argv) {
    printf("Bonjour tout le monde.\n");
    return 0;
}
//===============================================

Création d'une fonction


Résultat:

image.png

Création d'une fonction:

//===============================================
// main.c
//===============================================
#include <stdio.h>
//===============================================
void sayHello() {
    printf("Bonjour tout le monde.\n");
}
//===============================================
int main(int _argc, char** _argv) {
    sayHello();
    return 0;
}
//===============================================


Programmation par module



Affichage d'un message


Résultat:

image.png

Affichage d'un message:
 
//===============================================
// main.c
//===============================================
#include <stdio.h>
//===============================================
void sayHello() {
    printf("Bonjour tout le monde.\n");
}
//===============================================
int main(int _argc, char** _argv) {
    sayHello();
    return 0;
}
//===============================================

Création d'un module de fichiers headers


Résultat:

image.png

Création d'un module de fichiers headers:
 
//===============================================
// main.c
//===============================================
#include "GInclude.h"
//===============================================
void sayHello() {
    printf("Bonjour tout le monde.\n");
}
//===============================================
int main(int _argc, char** _argv) {
    sayHello();
    return 0;
}
//===============================================
// GInclude.h
//===============================================
#ifndef _GInclude_
#define _GInclude_
//===============================================
#include <stdio.h>
//===============================================
#endif
//===============================================

Création d'un module de salutation


Résultat:

image.png

Création d'un module de salutation:
 
//===============================================
// main.c
//===============================================
#include "GHello.h"
//===============================================
int main(int _argc, char** _argv) {
    GHello_sayHello();
    return 0;
}
//===============================================
// GHello.h
//===============================================
#ifndef _GHello_
#define _GHello_
//===============================================
#include "GInclude.h"
//===============================================
void GHello_sayHello();
//===============================================
#endif
//===============================================
// GHello.c
//===============================================
#include "GHello.h"
//===============================================
void GHello_sayHello() {
    printf("Bonjour tout le monde.\n");
}
//===============================================


Programmation par objet



Affichage d'un message


Résultat:

image.png

Affichage d'un message:
 
//===============================================
// main.c
//===============================================
int main(int _argc, char** _argv) {
    GHello_sayHello();
    return 0;
}
//===============================================
// GHello.h
//===============================================
void GHello_sayHello();
//===============================================
// GHello.c
//===============================================
#include "GHello.h"
//===============================================
void GHello_sayHello() {
    printf("Bonjour tout le monde.\n");
}
//===============================================

Utilisation de la notion d'objet


Résultat:

image.png

Utilisation de la notion d'objet:
 
//===============================================
// main.c
//===============================================
int main(int _argc, char** _argv) {
    GHello lHello;
    GHello_init(&lHello);
    lHello.sayHello();
    return 0;
}
//===============================================
// GHello.h
//===============================================
typedef struct _GHello GHello;
//===============================================
struct _GHello {
    void (*sayHello)();
};
//===============================================
void GHello_init(GHello* _this);
//===============================================
// GHello.c
//===============================================
#include "GHello.h"
//===============================================
static void GHello_sayHello();
//===============================================
void GHello_init(GHello* _this) {
    _this->sayHello = GHello_sayHello;
}
//===============================================
static void GHello_sayHello() {
    printf("Bonjour tout le monde.\n");
}
//===============================================

Utilisation d'une macro locale


Résultat:

image.png

Utilisation d'une macro local:
 
//===============================================
// main.c
//===============================================
int main(int _argc, char** _argv) {
    GHELLO_OBJ(lHello)
    lHello.sayHello();
    return 0;
}
//===============================================
// GHello.h
//===============================================
#define GHELLO_OBJ(_this) \
    GHello _this; \
    GHello_init(&_this);
//===============================================
typedef struct _GHello GHello;
//===============================================
struct _GHello {
    void (*sayHello)();
};
//===============================================
void GHello_init(GHello* _this);
//===============================================
static void GHello_sayHello();
//===============================================
// GHello.c
//===============================================
void GHello_init(GHello* _this) {
    _this->sayHello = GHello_sayHello;
}
//===============================================
static void GHello_sayHello() {
    printf("Bonjour tout le monde.\n");
}
//===============================================

Utilisation d'une macro globale


Résultat:

image.png

Utilisation d'une macro globale: 

//===============================================
// main.c
//===============================================
int main(int _argc, char** _argv) {
    GDEFINE_OBJ(GHello, lHello)
    lHello.sayHello();
    return 0;
}
//===============================================
// GInclude.h
//===============================================
#define GDEFINE_OBJ(_type, _this) \
    _type _this; \
    _type##_init(&_this);
//===============================================
// GHello.h
//===============================================
typedef struct _GHello GHello;
//===============================================
struct _GHello {
    void (*sayHello)();
};
//===============================================
void GHello_init(GHello* _this);
//===============================================
static void GHello_sayHello();
//===============================================
// GHello.c
//===============================================
void GHello_init(GHello* _this) {
    _this->sayHello = GHello_sayHello;
}
//===============================================
static void GHello_sayHello() {
    printf("Bonjour tout le monde.\n");
}
//===============================================

Utilisation de la mémoire dynamique


Résultat:

image.png

Utilisation de la mémoire dynamique: 

//===============================================
// main.c
//===============================================
int main(int _argc, char** _argv) {
    GHello* lHello = GHello_new();
    lHello->sayHello();
    free(lHello);
    return 0;
}
//===============================================
// GHello.h
//===============================================
typedef struct _GHello GHello;
//===============================================
struct _GHello {
    void (*sayHello)();
};
//===============================================
void GHello_init(GHello* _this);
GHello* GHello_new();
//===============================================
// GHello.h
//===============================================
GHello* GHello_new() {
    GHello* lObj = (GHello*)malloc(sizeof(GHello));
    GHello_init(lObj);
    return lObj;
}
//===============================================
void GHello_init(GHello* _this) {
    _this->sayHello = GHello_sayHello;
}
//===============================================
static void GHello_sayHello() {
    printf("Bonjour tout le monde.\n");
}
//===============================================

Intégration de la destruction d'un objet dynamique


Résultat:

image.png

Intégration de la destruction d'un objet dynamique: 

//===============================================
// main.c
//===============================================
int main(int _argc, char** _argv) {
    GHello* lHello = GHello_new();
    lHello->sayHello();
    lHello->delete(&lHello);
    return 0;
}
//===============================================
// GHello.h
//===============================================
typedef struct _GHello GHello;
//===============================================
struct _GHello {
    void (*delete)(GHello** _this);
    void (*sayHello)();
};
//===============================================
void GHello_init(GHello* _this);
GHello* GHello_new();
//===============================================
// GHello.h
//===============================================
GHello* GHello_new() {
    GHello* lObj = (GHello*)malloc(sizeof(GHello));
    GHello_init(lObj);
    return lObj;
}
//===============================================
static void GHello_delete(GHello** _this) {
    free(*_this);
    (*_this) = 0;
}
//===============================================
void GHello_init(GHello* _this) {
    _this->delete = GHello_delete;
    _this->sayHello = GHello_sayHello;
}
//===============================================
static void GHello_sayHello() {
    printf("Bonjour tout le monde.\n");
}
//===============================================

Création d'un objet dynamique via une macro locale


Résultat:

image.png

Création d'un objet dynamique via une macro local: 

//===============================================
// main.c
//===============================================
int main(int _argc, char** _argv) {
    GHELLO_OBJ(lHello)
    lHello->sayHello();
    lHello->delete(&lHello);
    return 0;
}
//===============================================
// GHello.h
//===============================================
#define GHELLO_OBJ(_this) \
    GHello* _this = GHello_new();
//===============================================
typedef struct _GHello GHello;
//===============================================
struct _GHello {
    void (*delete)(GHello** _this);
    void (*sayHello)();
};
//===============================================
void GHello_init(GHello* _this);
GHello* GHello_new();
//===============================================
// GHello.h
//===============================================
GHello* GHello_new() {
    GHello* lObj = (GHello*)malloc(sizeof(GHello));
    GHello_init(lObj);
    return lObj;
}
//===============================================
static void GHello_delete(GHello** _this) {
    free(*_this);
    (*_this) = 0;
}
//===============================================
void GHello_init(GHello* _this) {
    _this->delete = GHello_delete;
    _this->sayHello = GHello_sayHello;
}
//===============================================
static void GHello_sayHello() {
    printf("Bonjour tout le monde.\n");
}
//===============================================

Création d'un objet dynamique via une macro globale


Résultat:

image.png

Création d'un objet dynamique via une macro globale:
 
//===============================================
// main.c
//===============================================
int main(int _argc, char** _argv) {
    GDEFINE_OBJ_PTR(GHello, lHello)
    lHello->sayHello();
    lHello->delete(&lHello);
    return 0;
}
//===============================================
// GInclude.h
//===============================================
#define GDEFINE_OBJ(_type, _this) \
    _type _this; \
    _type##_init(&_this);
//===============================================
#define GDEFINE_OBJ_PTR(_type, _this) \
    _type* _this = _type##_new();
//===============================================
// GHello.h
//===============================================
typedef struct _GHello GHello;
//===============================================
struct _GHello {
    void (*delete)(GHello** _this);
    void (*sayHello)();
};
//===============================================
void GHello_init(GHello* _this);
GHello* GHello_new();
//===============================================
// GHello.h
//===============================================
GHello* GHello_new() {
    GHello* lObj = (GHello*)malloc(sizeof(GHello));
    GHello_init(lObj);
    return lObj;
}
//===============================================
static void GHello_delete(GHello** _this) {
    free(*_this);
    (*_this) = 0;
}
//===============================================
void GHello_init(GHello* _this) {
    _this->delete = GHello_delete;
    _this->sayHello = GHello_sayHello;
}
//===============================================
static void GHello_sayHello() {
    printf("Bonjour tout le monde.\n");
}
//===============================================


Programmation par sélection de projet



Affichage d'un message


Résultat:

image.png

Affichage d'un message:
 
//===============================================
// main.c
//===============================================
int main(int _argc, char** _argv) {
    GDEFINE_OBJ_PTR(GHello, lHello)
    lHello->sayHello();
    lHello->delete(&lHello);
    return 0;
}
//===============================================

Création d'un module de sélection de processus


Résultat:

image.png

Création d'un module de sélection de processus:
 
//===============================================
// main.c
//===============================================
int main(int _argc, char** _argv) {
    GDEFINE_OBJ(GProcess, lProcess)
    lProcess.run(_argc, _argv);
    return 0;
}
//===============================================
// GProcess.c
//===============================================
GProcess* GProcess_new() {
    GProcess* lObj = (GProcess*)malloc(sizeof(GProcess));
    GProcess_init(lObj);
    return lObj;
}
//===============================================
static void GProcess_delete(GProcess** _this) {
    free(*_this);
    (*_this) = 0;
}
//===============================================
void GProcess_init(GProcess* _this) {
    _this->delete = GProcess_delete;
    _this->run = GProcess_run;
}
//===============================================
static void GProcess_run(int _argc, char** _argv) {
    GDEFINE_OBJ(GHello, lHello)
    lHello.sayHello();
}
//===============================================

Utilisation des arguments passés en ligne de commande


Résultat:

image.png

Passage des arguments en ligne de commande:

::===============================================
:: Terminal
::===============================================
readyapp.exe hello
::===============================================

Utilisation des arguments passés en ligne de commande:
 
//===============================================
// main.c
//===============================================
int main(int _argc, char** _argv) {
    GDEFINE_OBJ(GProcess, lProcess)
    lProcess.run(_argc, _argv);
    return 0;
}
//===============================================
// GProcess.c
//===============================================
GProcess* GProcess_new() {
    GProcess* lObj = (GProcess*)malloc(sizeof(GProcess));
    GProcess_init(lObj);
    return lObj;
}
//===============================================
static void GProcess_delete(GProcess** _this) {
    free(*_this);
    (*_this) = 0;
}
//===============================================
void GProcess_init(GProcess* _this) {
    _this->delete = GProcess_delete;
    _this->run = GProcess_run;
}
//===============================================
static void GProcess_run(int _argc, char** _argv) {
    char* lModule = "";
    if(_argc > 1) lModule = _argv[1];
    if(!strcmp(lModule, "hello")) {
        GProcess_runHello(_argc, _argv);
    }
}
//===============================================
static void GProcess_runHello(int _argc, char** _argv) {
    GDEFINE_OBJ(GHello, lHello)
    lHello.sayHello();
}
//===============================================

Intégration d'un module de test


Résultat:

image.png

Exécution d'un module de test 

::===============================================
:: Terminal
::===============================================
readyapp.exe test
::===============================================

Intégration d'un module de test:
 
//===============================================
// main.c
//===============================================
int main(int _argc, char** _argv) {
    GDEFINE_OBJ(GProcess, lProcess)
    lProcess.run(_argc, _argv);
    return 0;
}
//===============================================
// GProcess.c
//===============================================
GProcess* GProcess_new() {
    GProcess* lObj = (GProcess*)malloc(sizeof(GProcess));
    GProcess_init(lObj);
    return lObj;
}
//===============================================
static void GProcess_delete(GProcess** _this) {
    free(*_this);
    (*_this) = 0;
}
//===============================================
void GProcess_init(GProcess* _this) {
    _this->delete = GProcess_delete;
    _this->run = GProcess_run;
}
//===============================================
static void GProcess_run(int _argc, char** _argv) {
    char* lModule = "";
    if(_argc > 1) lModule = _argv[1];
    if(!strcmp(lModule, "hello")) {
        GProcess_runHello(_argc, _argv);
    }
    else if(!strcmp(lModule, "test")) {
        GProcess_runTest(_argc, _argv);
    }
}
//===============================================
static void GProcess_runHello(int _argc, char** _argv) {
    GDEFINE_OBJ(GHello, lHello)
    lHello.sayHello();
}
//===============================================
static void GProcess_runTest(int _argc, char** _argv) {
    GDEFINE_OBJ(GTest, lObj)
    lObj.run(_argc, _argv);
}
//===============================================
// GTest.c
//===============================================
GTest* GTest_new() {
    GTest* lObj = (GTest*)malloc(sizeof(GTest));
    GTest_init(lObj);
    return lObj;
}
//===============================================
static void GTest_delete(GTest** _this) {
    free(*_this);
    (*_this) = 0;
}
//===============================================
void GTest_init(GTest* _this) {
    _this->delete = GTest_delete;
    _this->run = GTest_run;
}
//===============================================
static void GTest_run(int _argc, char** _argv) {
    printf("Je suis le module de test.\n");
}
//===============================================

Prise en compte des accents dans un terminal sous Windows


Résultat:

image.png

Prise en compte des accents dans un terminal sous Windows:

//===============================================
// main.c
//===============================================
int main(int _argc, char** _argv) {
    GDEFINE_OBJ(GProcess, lProcess)
    lProcess.inits(&lProcess);
    lProcess.run(&lProcess, _argc, _argv);
    lProcess.m_obj->m_logs->print(lProcess.m_obj->m_logs);
    lProcess.clean(&lProcess);
    return 0;
}
//===============================================
// GProcess.c
//===============================================
static void GProcess_inits(GProcess* _this) {
    assert(_this);
    SetConsoleOutputCP(CP_UTF8);
}
//===============================================
// GTest.c
//===============================================
static void GTest_runString(GTest* _this, int _argc, char** _argv) {
    assert(_this);
    printf("%s...\n",  __PRETTY_FUNCTION__);

    GString* lString = GString_new();

    lString->create(lString, "Voici mon premier message.\n");

    lString->add(lString, "Voici mon deuxième message.\n");
    lString->add(lString, "Voici mon troisième message.\n");
    lString->add(lString, "Voici mon quatrième message.\n");

    lString->print(lString);

    lString->delete(&lString);
}
//===============================================
// GString.c
//===============================================
static void GString_print(GString* _this) {
    assert(_this);
    printf("%s\n", _this->m_data);
}
//===============================================


Création d'une liste de données



Création d'une liste de données


Résultat:

image.png

Création d'une liste de données:
 
//===============================================
// GTest.c
//===============================================
static void GTest_runVector(int _argc, char** _argv) {
    printf("%s...\n",  __PRETTY_FUNCTION__);
    GVector* lVector = GVector_new();

    // size - add - get - clear - delete
    printf("size: %d\n", lVector->size(lVector));

    lVector->add(lVector, "un");
    lVector->add(lVector, "deux");
    lVector->add(lVector, "trois");
    printf("size: %d\n", lVector->size(lVector));

    printf("get: %s\n", (char*)lVector->get(lVector, 1));

    lVector->clear(lVector);
    printf("size: %d\n", lVector->size(lVector));

    lVector->delete(&lVector);
}
//===============================================
// GVector.h
//===============================================
typedef struct _GVector GVector;
//===============================================
struct _GVector {
    void (*delete)(GVector** _this);
    void (*clear)(GVector* _this);
    void (*add)(GVector* _this, void* _data);
    int (*size)(GVector* _this);
    void* (*get)(GVector* _this, int i);
    GVector* m_next;
    void* m_data;
};
//===============================================
void GVector_init(GVector* _this);
GVector* GVector_new();
//===============================================
// GVector.c
//===============================================
GVector* GVector_new() {
    GVector* lObj = (GVector*)malloc(sizeof(GVector));
    GVector_init(lObj);
    return lObj;
}
//===============================================
void GVector_init(GVector* _this) {
    _this->delete = GVector_delete;
    _this->clear = GVector_clear;
    _this->add = GVector_add;
    _this->size = GVector_size;
    _this->get = GVector_get;
    _this->m_next = 0;
    _this->m_data = 0;
}
//===============================================
static void GVector_delete(GVector** _this) {
    assert(*_this);
    (*_this)->clear(*_this);
    free(*_this);
    (*_this) = 0;
}
//===============================================
static void GVector_clear(GVector* _this) {
    assert(_this);
    GVector* lNode = _this->m_next;
    while(lNode) {
        GVector* lPrevious = lNode;
        lNode = lNode->m_next;
        free(lPrevious);
    }
    _this->m_next = 0;
}
//===============================================
static void GVector_add(GVector* _this, void* _data) {
    assert(_this);
    GVector* lNode = _this;
    while(lNode->m_next) lNode = lNode->m_next;
    GVector* lObj = GVector_new();
    lObj->m_data = _data;
    lNode->m_next = lObj;
}
//===============================================
static int GVector_size(GVector* _this) {
    assert(_this);
    int lCount = 0;
    GVector* lNode = _this;
    while(lNode->m_next) {
        lCount++;
        lNode = lNode->m_next;
    }
    return lCount;
}
//===============================================
static void* GVector_get(GVector* _this, int i) {
    assert(_this);
    int lSize = _this->size(_this);
    assert(i >= 0 && i < lSize);
    int lCount = 0;
    GVector* lNode = _this->m_next;
    while(lNode) {
        if(lCount == i) break;
        lNode = lNode->m_next;
        lCount++;
    }
    return lNode->m_data;
}
//===============================================


Création d'un gestionnaire de logs



Création d'un gestionnaire de logs 


Résultat:

image.png

Création d'un gestionnaire de logs: 

//===============================================
// GTest.c
//===============================================
static void GTest_runLog(int _argc, char** _argv) {
    printf("%s...\n",  __PRETTY_FUNCTION__);

    // addError - addLog - addData - addLogs - print - clear - delete
    GLog* lLog = GLog_new();
    GLog* lLog2 = GLog_new();

    lLog->addError(lLog, "Je suis une erreur.");
    lLog->addLog(lLog, "Je suis une information.");
    lLog->addData(lLog, "Je suis une donnée.");

    // lLog->clear(lLog);

    lLog->print(lLog);

    lLog->loadFromMap(lLog, 2);
    lLog->m_msg = "Je suis une information (2).";
    lLog->loadToMap(lLog, 2);

    lLog2->addLogs(lLog2, lLog);
    lLog2->print(lLog2);

    lLog->delete(&lLog);
    lLog2->delete(&lLog2);
}
//===============================================
// GLog.h
//===============================================
typedef struct _GLog GLog;
typedef struct _GVector GVector;
//===============================================
struct _GLog {
    void (*delete)(GLog** _this);
    void (*clear)(GLog* _this);
    void (*loadToMap)(GLog* _this, int _index);
    void (*loadFromMap)(GLog* _this, int _index);
    void (*addError)(GLog* _this, const char* _msg);
    void (*addLog)(GLog* _this, const char* _msg);
    void (*addData)(GLog* _this, const char* _msg);
    void (*addLogs)(GLog* _this, GLog* _obj);
    void (*print)(GLog* _this);

    GVector* m_map;
    const char* m_type;
    const char* m_side;
    const char* m_msg;
};
//===============================================
void GLog_init(GLog* _this);
GLog* GLog_new();
//===============================================
// GLog.c
//===============================================
GLog* GLog_new() {
    GLog* lObj = (GLog*)malloc(sizeof(GLog));
    GLog_init(lObj);
    return lObj;
}
//===============================================
void GLog_init(GLog* _this) {
    assert(_this);
    _this->delete = GLog_delete;
    _this->clear = GLog_clear;
    _this->loadToMap = GLog_loadToMap;
    _this->loadFromMap = GLog_loadFromMap;
    _this->addError = GLog_addError;
    _this->addLog = GLog_addLog;
    _this->addData = GLog_addData;
    _this->addLogs = GLog_addLogs;
    _this->print = GLog_print;

    _this->m_map = GVector_new();
    _this->m_type = 0;
    _this->m_side = 0;
    _this->m_msg = 0;
}
//===============================================
static void GLog_delete(GLog** _this) {
    assert(*_this);
    GVector* lMap = (*_this)->m_map;
    (*_this)->clear(*_this);
    lMap->delete(&lMap);
    free(*_this);
    (*_this) = 0;
}
//===============================================
static void GLog_clear(GLog* _this) {
    assert(_this);
    GVector* lMap = _this->m_map;
    for(int i = 0; i < lMap->size(lMap); i++) {
        GLog* lObj = lMap->get(lMap, i);
        lObj->delete(&lObj);
    }
    lMap->clear(lMap);
}
//===============================================
static GLog* GLog_clone(GLog* _this) {
    assert(_this);
    GLog* lObj = GLog_new();
    GLog_setObj(lObj, _this);
    return lObj;
}
//===============================================
static void GLog_setObj(GLog* _this, GLog* _obj) {
    assert(_this);
    _this->m_type = _obj->m_type;
    _this->m_side = _obj->m_side;
    _this->m_msg = _obj->m_msg;
}
//===============================================
static void GLog_loadToMap(GLog* _this, int _index) {
    assert(_this);
    assert(_index >= 1);
    GVector* lMap = _this->m_map;
    int lSize = lMap->size(lMap);
    assert(_index <= lSize);
    GLog* lObj = lMap->get(lMap, _index - 1);
    GLog_setObj(lObj, _this);
}
//===============================================
static void GLog_loadFromMap(GLog* _this, int _index) {
    assert(_this);
    assert(_index >= 1);
    GVector* lMap = _this->m_map;
    int lSize = lMap->size(lMap);
    assert(_index <= lSize);
    GLog* lObj = lMap->get(lMap, _index - 1);
    GLog_setObj(_this, lObj);
}
//===============================================
static void GLog_addError(GLog* _this, const char* _msg) {
    assert(_this);
    GVector* lMap = _this->m_map;
    GLog* lObj = GLog_new();
    lObj->m_type = "error";
    lObj->m_side = "server";
    lObj->m_msg = _msg;
    lMap->add(lMap, lObj);
}
//===============================================
static void GLog_addLog(GLog* _this, const char* _msg) {
    assert(_this);
    GVector* lMap = _this->m_map;
    GLog* lObj = GLog_new();
    lObj->m_type = "log";
    lObj->m_side = "server";
    lObj->m_msg = _msg;
    lMap->add(lMap, lObj);
}
//===============================================
static void GLog_addData(GLog* _this, const char* _msg) {
    assert(_this);
    GVector* lMap = _this->m_map;
    GLog* lObj = GLog_new();
    lObj->m_type = "data";
    lObj->m_side = "server";
    lObj->m_msg = _msg;
    lMap->add(lMap, lObj);
}
//===============================================
static void GLog_addLogs(GLog* _this, GLog* _obj) {
    assert(_this);
    GVector* lMap = _this->m_map;
    GVector* lMap2 = _obj->m_map;
    for(int i = 0; i < lMap2->size(lMap2); i++) {
        GLog* lObj = lMap2->get(lMap2, i);
        GLog* lObj2 = GLog_clone(lObj);
        lMap->add(lMap, lObj2);
    }
}
//===============================================
static void GLog_print(GLog* _this) {
    assert(_this);
    GVector* lMap = _this->m_map;
    for(int i = 0; i < lMap->size(lMap); i++) {
        GLog* lObj = lMap->get(lMap, i);
        printf("[%-6s] : %s\n", lObj->m_type, lObj->m_msg);
    }
}
//===============================================


Création d'un objet parent



Création d'un objet parent 


Création d'un objet parent:

//===============================================
// GObject.h
//===============================================
typedef struct _GObject GObject;
//===============================================
struct _GObject {
    void (*delete)(GObject** _this);
};
//===============================================
void GObject_init(GObject* _this);
GObject* GObject_new();
//===============================================
// GObject.c
//===============================================
GObject* GObject_new() {
    GObject* lObj = (GObject*)malloc(sizeof(GObject));
    GObject_init(lObj);
    return lObj;
}
//===============================================
void GObject_init(GObject* _this) {
    assert(_this);
    _this->delete = GObject_delete;
}
//===============================================
static void GObject_delete(GObject** _this) {
    assert(*_this);
    free(*_this);
    (*_this) = 0;
}
//===============================================

Intégration d'un gestionnaire de logs


Intégration d'un gestionnaire de logs: 

//===============================================
// GObject.h
//===============================================
typedef struct _GObject GObject;
//===============================================
struct _GObject {
    void (*delete)(GObject** _this);

    GLog* m_logs;
};
//===============================================
void GObject_init(GObject* _this);
GObject* GObject_new();
//===============================================
// GObject.c
//===============================================
GObject* GObject_new() {
    GObject* lObj = (GObject*)malloc(sizeof(GObject));
    GObject_init(lObj);
    return lObj;
}
//===============================================
void GObject_init(GObject* _this) {
    assert(_this);
    _this->delete = GObject_delete;

    _this->m_logs = GLog_new();
}
//===============================================
static void GObject_delete(GObject** _this) {
    assert(*_this);
    GLog* lLog = (*_this)->m_logs;
    lLog->delete(&lLog);
    free(*_this);
    (*_this) = 0;
}
//===============================================

Utilisation d'un objet parent


Utilisation d'un objet parent:
 
//===============================================
// GProcess.h
//===============================================
typedef struct _GProcess GProcess;
//===============================================
struct _GProcess {
    void (*delete)(GProcess** _this);
    void (*run)(GProcess* _this, int _argc, char** _argv);

    GObject* m_obj;
};
//===============================================
void GProcess_init(GProcess* _this);
GProcess* GProcess_new();
//===============================================
// GProcess.c
//===============================================
GProcess* GProcess_new() {
    GProcess* lObj = (GProcess*)malloc(sizeof(GProcess));
    GProcess_init(lObj);
    return lObj;
}
//===============================================
void GProcess_init(GProcess* _this) {
    assert(_this);
    _this->delete = GProcess_delete;
    _this->run = GProcess_run;

    _this->m_obj = GObject_new();
}
//===============================================
static void GProcess_delete(GProcess** _this) {
    assert(*_this);
    GObject* lObj = (*_this)->m_obj;
    lObj->delete(&lObj);
    free(*_this);
    (*_this) = 0;
}
//===============================================

Utilisation d'un gestionnaire de logs


Résultat:

image.png

Utilisation d'un gestionnaire de logs:

//===============================================
// main.c
//===============================================
int main(int _argc, char** _argv) {
    GDEFINE_OBJ(GProcess, lProcess)
    lProcess.run(&lProcess, _argc, _argv);
    lProcess.m_obj->m_logs->print(lProcess.m_obj->m_logs);
    return 0;
}
//===============================================
// GProcess.h
//===============================================
typedef struct _GProcess GProcess;
//===============================================
struct _GProcess {
    void (*delete)(GProcess** _this);
    void (*run)(GProcess* _this, int _argc, char** _argv);

    GObject* m_obj;
};
//===============================================
void GProcess_init(GProcess* _this);
GProcess* GProcess_new();
//===============================================
// GProcess.c
//===============================================
GProcess* GProcess_new() {
    GProcess* lObj = (GProcess*)malloc(sizeof(GProcess));
    GProcess_init(lObj);
    return lObj;
}
//===============================================
void GProcess_init(GProcess* _this) {
    assert(_this);
    _this->delete = GProcess_delete;
    _this->run = GProcess_run;

    _this->m_obj = GObject_new();
}
//===============================================
static void GProcess_delete(GProcess** _this) {
    assert(*_this);
    GObject* lObj = (*_this)->m_obj;
    lObj->delete(&lObj);
    free(*_this);
    (*_this) = 0;
}
//===============================================
static void GProcess_run(GProcess* _this, int _argc, char** _argv) {
    assert(_this);
    char* lModule = "";
    if(_argc > 1) lModule = _argv[1];
    GLog* lLog = _this->m_obj->m_logs;

    if(!strcmp(lModule, "")) {
        lLog->addError(lLog, "Le module est obligatoire.");
    }
    else if(!strcmp(lModule, "test")) {
        GProcess_runTest(_this, _argc, _argv);
    }
    else {
        lLog->addError(lLog, "Le module est inconnu.");
    }
}
//===============================================
static void GProcess_runTest(GProcess* _this, int _argc, char** _argv) {
    assert(_this);
    GDEFINE_OBJ(GTest, lObj)
    lObj.run(&lObj, _argc, _argv);
    _this->m_obj->m_logs->addLogs(_this->m_obj->m_logs, lObj.m_obj->m_logs);
}
//===============================================


Création d'un gestionnaire de chaînes de caractères



Création d'un gestionnaire de chaînes de caractères


Résultat:

image.png

Création d'un gestionnaire de chaînes de caractères:

//===============================================
// GTest.c
//===============================================
static void GTest_runString(GTest* _this, int _argc, char** _argv) {
    assert(_this);
    printf("%s...\n",  __PRETTY_FUNCTION__);

    GString* lString = GString_new();
    GString* lString2 = GString_new();
    GString* lString3 = GString_new();
    GVector* lMap = GVector_new();

    lString->create(lString, "Voici mon premier message.\n");

    lString->add(lString, "Voici mon deuxième message.\n");
    lString->add(lString, "Voici mon troisième message.\n");
    lString->add(lString, "Voici mon quatrième message.\n");
    lString->add(lString, "Voici mon cinquième message.");

    lString->print(lString);

    lString->split(lString, lMap, "\n");
    printf("split: %d\n", lMap->size(lMap));

    lString2->assign(lString2, lMap->get(lMap, 1));
    printf("get map: %s\n", lString2->m_data);

    printf("indexOf: %d\n", lString2->indexOf(lString2, "deuxième", 0));
    printf("startsWith: %d\n", lString2->startsWith(lString2, "Voici"));
    printf("endsWith: %d\n", lString2->endsWith(lString2, "message"));

    lString2->substr(lString2, lString3, 0, 3);
    printf("substr: %s\n", lString3->m_data);

    lString2->extract(lString2, lString3, " ", " ");
    printf("extract: %s\n", lString3->m_data);

    lString->get(lString, lString3, "\n", 3);
    printf("get sep: %s\n", lString3->m_data);

    lString->from(lString, lString3, "\n", 3);
    printf("from sep: %s\n", lString3->m_data);

    smdelete(lMap);
    lString->delete(&lString);
    lString2->delete(&lString2);
    lString3->delete(&lString3);
    lMap->delete(&lMap);
}
//===============================================
// GString.h
//===============================================
typedef struct _GString GString;
//===============================================
struct _GString {
    void (*delete)(GString** _this);
    void (*clear)(GString* _this);
    void (*allocate)(GString* _this, int _size);
    void (*create)(GString* _this, const char* _data);
    void (*assign)(GString* _this, GString* _data);
    void (*add)(GString* _this, const char* _data);
    void (*format)(GString* _this, const char* _format, ...);
    void (*split)(GString* _this, GVector* _map, const char* _sep);
    void (*get)(GString* _this, GString* _data, const char* _sep, int _index);
    void (*from)(GString* _this, GString* _data, const char* _sep, int _index);
    int (*isEmpty)(GString* _this);
    int (*startsWith)(GString* _this, const char* _data);
    int (*endsWith)(GString* _this, const char* _data);
    int (*indexOf)(GString* _this, const char* _data, int _pos);
    void (*substr)(GString* _this, GString* _data, int _pos, int _size);
    void (*extract)(GString* _this, GString* _data, const char* _start, const char* _end);
    void (*print)(GString* _this);

    char* m_data;
    int m_size;
};
//===============================================
// GString.c
//===============================================
void GString_init(GString* _this);
GString* GString_new();
//===============================================
GString* GString_new() {
    GString* lObj = (GString*)malloc(sizeof(GString));
    GString_init(lObj);
    return lObj;
}
//===============================================
void GString_init(GString* _this) {
    assert(_this);
    _this->delete = GString_delete;
    _this->clear = GString_clear;
    _this->allocate = GString_allocate;
    _this->create = GString_create;
    _this->assign = GString_assign;
    _this->add = GString_add;
    _this->format = GString_format;
    _this->split = GString_split;
    _this->get = GString_get;
    _this->from = GString_from;
    _this->isEmpty = GString_isEmpty;
    _this->startsWith = GString_startsWith;
    _this->endsWith = GString_endsWith;
    _this->indexOf = GString_indexOf;
    _this->substr = GString_substr;
    _this->extract = GString_extract;
    _this->print = GString_print;

    _this->m_data = 0;
    _this->m_size = 0;
}
//===============================================
static void GString_delete(GString** _this) {
    assert(*_this);
    (*_this)->clear(*_this);
    free(*_this);
    (*_this) = 0;
}
//===============================================
static void GString_clear(GString* _this) {
    assert(_this);
    free(_this->m_data);
    _this->m_data = 0;
    _this->m_size = 0;
}
//===============================================
static void GString_allocate(GString* _this, int _size) {
    assert(_this);
    assert(_size >= 0);
    _this->clear(_this);
    _this->m_data = (char*)malloc(sizeof(char)*(_size + 1));
    _this->m_data[_size] = '\0';
    _this->m_size = _size;
}
//===============================================
static void GString_create(GString* _this, const char* _data) {
    assert(_this);
    assert(_data);
    int lSize = strlen(_data);
    _this->allocate(_this, lSize);
    memcpy(_this->m_data, _data, _this->m_size);
}
//===============================================
static void GString_assign(GString* _this, GString* _data) {
    assert(_this);
    assert(_data);
    _this->allocate(_this, _data->m_size);
    memcpy(_this->m_data, _data->m_data, _this->m_size);
}
//===============================================
static void GString_add(GString* _this, const char* _data) {
    assert(_this);
    assert(_data);
    int lSize = strlen(_data);
    int lSizeT = _this->m_size + lSize;
    char* lDataT = (char*)malloc(sizeof(char)*(lSizeT + 1));
    memcpy(&lDataT[0], _this->m_data, _this->m_size);
    memcpy(&lDataT[_this->m_size], _data, lSize);
    lDataT[lSizeT] = '\0';
    _this->clear(_this);
    _this->m_data = lDataT;
    _this->m_size = lSizeT;
}
//===============================================
static void GString_format(GString* _this, const char* _format, ...) {
    assert(_this);
    assert(_format);
    va_list lArgs;
    va_start(lArgs, _format);
    int lSize = vsnprintf(0, 0, _format, lArgs);
    char* lData = (char*)malloc(sizeof(char)*(lSize + 1));
    vsnprintf(lData, lSize + 1, _format, lArgs);
    va_end(lArgs);
    _this->clear(_this);
    _this->m_data = lData;
    _this->m_size = lSize;
}
//===============================================
static void GString_split(GString* _this, GVector* _map, const char* _sep) {
    assert(_this);

    smdelete(_map);
    _map->clear(_map);

    GString* lData = GString_new();
    lData->assign(lData, _this);

    char* lToken = strtok(lData->m_data, _sep);

    while(lToken) {
        GString* lValue = GString_new();
        lValue->create(lValue, lToken);
        _map->add(_map, lValue);
        lToken = strtok(0, _sep);
    }

    lData->delete(&lData);
}
//===============================================
static void GString_get(GString* _this, GString* _data, const char* _sep, int _index) {
    assert(_this);
    _data->clear(_data);
    if(_this->isEmpty(_this)) return;
    int lStart = 0;
    int lEnd = 0;
    int lCount = 0;

    while(1) {
        lEnd = _this->indexOf(_this, _sep, lStart);
        if(lEnd == -1) {
            lEnd = _this->m_size;
            break;
        }
        int lSize = lEnd - lStart;

        if(lCount == _index) {
            _this->substr(_this, _data, lStart, lSize);
            return;
        }
        lCount++;

        lStart += lSize + strlen(_sep);
    }

    if(lCount == _index) {
        int lSize = lEnd - lStart;
        if(lSize > 0) {
            _this->substr(_this, _data, lStart, lSize);
        }
    }
}
//===============================================
static void GString_from(GString* _this, GString* _data, const char* _sep, int _index) {
    assert(_this);
    _data->clear(_data);
    if(_this->isEmpty(_this)) return;
    int lStart = 0;
    int lEnd = 0;
    int lCount = 0;

    while(1) {
        lEnd = _this->indexOf(_this, _sep, lStart);
        if(lEnd == -1) {
            lEnd = _this->m_size;
            break;
        }
        int lSize = lEnd - lStart;

        if(lCount == _index) {
            int lFrom = _this->m_size - lStart;
            _this->substr(_this, _data, lStart, lFrom);
            return;
        }
        lCount++;

        lStart += lSize + strlen(_sep);
    }

    if(lCount == _index) {
        int lSize = lEnd - lStart;
        if(lSize > 0) {
            int lFrom = _this->m_size - lStart;
            _this->substr(_this, _data, lStart, lFrom);
        }
    }
}
//===============================================
static int GString_isEmpty(GString* _this) {
    assert(_this);
    if(!_this->m_data || !_this->m_size) return 1;
    return 0;
}
//===============================================
static int GString_startsWith(GString* _this, const char* _data) {
    assert(_this);
    if(_this->isEmpty(_this)) return 0;
    int lSize = _this->m_size;
    int lSize2 = strlen(_data);
    if(lSize < lSize2) return 0;
    int lOk = memcmp(_this->m_data, _data, lSize2) == 0;
    return lOk;
}
//===============================================
static int GString_endsWith(GString* _this, const char* _data) {
    assert(_this);
    if(_this->isEmpty(_this)) return 0;
    int lSize = _this->m_size;
    int lSize2 = strlen(_data);
    if(lSize < lSize2) return 0;
    int lPos = lSize - lSize2 - 1;
    int lOk = memcmp(&_this->m_data[lPos], _data, lSize2) == 0;
    return lOk;
}
//===============================================
static int GString_indexOf(GString* _this, const char* _data, int _pos) {
    assert(_this);
    assert(_pos >= 0);
    if(_this->isEmpty(_this)) return -1;
    char* lFound = strstr(&_this->m_data[_pos], _data);
    if(!lFound) return -1;
    int lIndex = lFound - _this->m_data;
    return lIndex;
}
//===============================================
static void GString_substr(GString* _this, GString* _data, int _pos, int _size) {
    assert(_this);
    _data->clear(_data);
    if(_this->isEmpty(_this)) return;
    int lSize = _this->m_size;
    assert(_size >= 0 && _size <= lSize);
    assert(abs(_pos) < lSize);
    if(_pos < 0) {
        if(_size > abs(_pos)) _size = abs(_pos);
        _pos += lSize;
    }
    _data->allocate(_data, _size);
    memcpy(_data->m_data, &_this->m_data[_pos], _size);
}
//===============================================
static void GString_extract(GString* _this, GString* _data, const char* _start, const char* _end) {
    assert(_this);
    _data->clear(_data);
    if(_this->isEmpty(_this)) return;
    int lStart = _this->indexOf(_this, _start, 0);
    if(lStart == -1) return;
    int lPos = lStart + strlen(_start);
    int lEnd = _this->indexOf(_this, _end, lPos);
    if(lEnd == -1) return;
    int lSize = lEnd - lPos;
    _this->substr(_this, _data, lPos, lSize);
}
//===============================================
static void GString_print(GString* _this) {
    assert(_this);
    printf("%s\n", _this->m_data);
}
//===============================================
// GFunctions.c
//===============================================
void smdelete(GVector* _map) {
    for(int i = 0; i < _map->size(_map); i++) {
        GString* lData = _map->get(_map, i);
        lData->delete(&lData);
    }
}
//===============================================


Création d'un gestionnaire de fichiers



Création d'un gestionnaire de chaînes de caractères


Résultat:

image.png

Création d'un gestionnaire de chaînes de caractères:

//===============================================
// GTest.c
//===============================================
static void GTest_runFile(GTest* _this, int _argc, char** _argv) {
    assert(_this);
    printf("%s...\n",  __PRETTY_FUNCTION__);

    GString* lFile = GString_new();

    lFile->loadFile(lFile, "index.html");

    printf("loadFile:\n%s\n", lFile->m_data);
    printf("existFile: %d\n", lFile->existFile(lFile, "index.html"));
    printf("existFile: %d\n", lFile->existFile(lFile, "index.php"));

    lFile->delete(&lFile);
}
//===============================================
// GString.c
//===============================================
static int GString_loadFile(GString* _this, const char* _filename) {
    assert(_this);
    FILE* lFile = fopen(_filename, "rb");
    if(!lFile) return 0;
    fseek(lFile, 0, SEEK_END);
    long lSize = ftell(lFile);
    fseek(lFile, 0, SEEK_SET);
    _this->allocate(_this, lSize);
    fread(_this->m_data, lSize, 1, lFile);
    fclose(lFile);
    return 1;
}
//===============================================
static int GString_existFile(GString* _this, const char* _filename) {
    assert(_this);
    FILE* lFile = fopen(_filename, "r");
    if(lFile) {
        fclose(lFile);
        return 1;
    }
    return 0;
}
//===============================================


Création d'une interface web



Récupération d'une requête d'un client web


Résultat:

image.png

Envoi de la requête:

image.png

Récupération d'une requête d'un client web:

//===============================================
// GTest.c
//===============================================
static void GTest_runSocket(GTest* _this, int _argc, char** _argv) {
    assert(_this);
    printf("%s...\n",  __PRETTY_FUNCTION__);

    GSocket* lSocket = GSocket_new();

    lSocket->run(lSocket);

    lSocket->delete(&lSocket);
}
//===============================================
// GSocket.h
//===============================================
typedef struct _GSocket GSocket;
//===============================================
struct _GSocket {
    void (*delete)(GSocket** _this);
    void (*run)(GSocket* _this);
    void (*read)(GSocket* _this, GString* _data);

    GObject* m_obj;
    SOCKET m_socket;
};
//===============================================
void GSocket_init(GSocket* _this);
GSocket* GSocket_new();
//===============================================
// GSocket.c
//===============================================
static void GSocket_run(GSocket* _this) {
    assert(_this);
    GLog* lLog = _this->m_obj->m_logs;

    int lMajor = 2;
    int lMinor = 2;
    int lPort = 8010;
    int lBacklog = 10;

    WSADATA wsaData;

    if(WSAStartup(MAKEWORD(lMajor, lMinor), &wsaData) == SOCKET_ERROR) {
        lLog->addError(lLog, "L'initialisation du server a échoué.");
        return;
    }

    struct sockaddr_in lAddress;
    lAddress.sin_family = AF_INET;
    lAddress.sin_addr.s_addr = INADDR_ANY;
    lAddress.sin_port = htons(lPort);

    SOCKET lServer = socket(AF_INET, SOCK_STREAM, 0);

    if(lServer == INVALID_SOCKET) {
        lLog->addError(lLog, "La création du socket server a échoué.");
        return;
    }

    if(bind(lServer, (struct sockaddr *)&lAddress, sizeof(lAddress)) == SOCKET_ERROR) {
        lLog->addError(lLog, "La liaison du socket server a échoué.");
        return;
    }

    if(listen(lServer, lBacklog) == SOCKET_ERROR) {
        lLog->addError(lLog, "L'initialisation du nombre de connexions autorisées a échoué.");
        return;
    }

    printf("Démarrage du serveur...\n");

    struct sockaddr_in lAddressC;
    int lAddressCL = sizeof(lAddressC);

    while(1) {
        GSocket* lClient = GSocket_new();
        lClient->m_socket = accept(lServer, (struct sockaddr*)&lAddressC, &lAddressCL);

        DWORD lThreadId;
        HANDLE lThreadH = CreateThread(
                NULL,
                0,
                GSocket_onThread,
                lClient,
                0,
                &lThreadId
        );

        if(!lThreadH) {
            printf("La création du thread a échoué\n");
        }
    }

    closesocket(lServer);
    WSACleanup();
}
//===============================================
static DWORD WINAPI GSocket_onThread(LPVOID _params) {
    GSocket* lClient = (GSocket*)_params;
    GString* lRequest = GString_new();

    lClient->read(lClient, lRequest);
    lRequest->print(lRequest);

    closesocket(lClient->m_socket);
    lRequest->delete(&lRequest);
    return 0;
}
//===============================================
static void GSocket_read(GSocket* _this, GString* _data) {
    assert(_this);
    SOCKET lSocket = _this->m_socket;
    _data->clear(_data);

    while(1) {
        char lBuffer[GSOCKET_BUFFER_SIZE];
        int lBytes = recv(lSocket, lBuffer, GSOCKET_BUFFER_SIZE - 1, 0);
        if(lBytes == SOCKET_ERROR) break;
        lBuffer[lBytes] = '\0';

        _data->add(_data, lBuffer);

        u_long lBytesIO;
        int lOk = ioctlsocket(lSocket, FIONREAD, &lBytesIO);

        if(lOk == SOCKET_ERROR) break;
        if(lBytesIO <= 0) break;
    }
}
//===============================================

Préparation d'une réponse web


Résultat:

image.png

Préparation d'une réponse web: 

//===============================================
// GTest.c
//===============================================
static void GTest_runSocket(GTest* _this, int _argc, char** _argv) {
    assert(_this);
    printf("%s...\n",  __PRETTY_FUNCTION__);

    GSocket* lSocket = GSocket_new();

    lSocket->run(lSocket);

    lSocket->delete(&lSocket);
}
//===============================================
// GSocket.c
//===============================================
static DWORD WINAPI GSocket_onThread(LPVOID _params) {
    GSocket* lClient = (GSocket*)_params;
    GString* lRequest = GString_new();

    lClient->read(lClient, lRequest);
    lRequest->print(lRequest);

    const char* lResponse = ""
            "HTTP/1.1 200 OK\r\n"
            "Content-Length: 22\r\n"
            "\r\n"
            "Bonjour tout le monde."
            "";

    lClient->send(lClient, lResponse);

    closesocket(lClient->m_socket);
    lRequest->delete(&lRequest);
    return 0;
}
//===============================================
static void GSocket_send(GSocket* _this, const char* _data) {
    assert(_this);
    SOCKET lSocket = _this->m_socket;
    int lIndex = 0;
    const char* lBuffer = _data;
    int lSize = strlen(_data);
    while(1) {
        int lBytes = send(lSocket, &lBuffer[lIndex], lSize - lIndex, 0);
        if(lBytes == SOCKET_ERROR) break;
        lIndex += lBytes;
        if(lIndex >= lSize) break;
    }
}
//===============================================

Création d'un gestionnaire de requêtes HTTP


Résultat:

image.png

Création d'un gestionnaire de requêtes HTTP: 

//===============================================
// GTest.c
//===============================================
static void GTest_runSocket(GTest* _this, int _argc, char** _argv) {
    assert(_this);
    printf("%s...\n",  __PRETTY_FUNCTION__);

    GSocket* lSocket = GSocket_new();

    lSocket->run(lSocket);

    lSocket->delete(&lSocket);
}
//===============================================
// GSocket.c
//===============================================
static DWORD WINAPI GSocket_onThread(LPVOID _params) {
    GSocket* lClient = (GSocket*)_params;
    GString* lRequest = GString_new();
    GString* lResponse = GString_new();
    GHttp* lHttp = GHttp_new();

    lClient->read(lClient, lRequest);
    lRequest->print(lRequest);

    lHttp->toResponse(lHttp, lResponse, "Bonjour tout le monde.");
    lClient->send(lClient, lResponse->m_data);

    closesocket(lClient->m_socket);
    lRequest->delete(&lRequest);
    lClient->delete(&lClient);
    return 0;
}
//===============================================
// GHttp.h
//===============================================
typedef struct _GHttp GHttp;
//===============================================
struct _GHttp {
    void (*delete)(GHttp** _this);
    void (*toResponse)(GHttp* _this, GString* _data, const char* _msg);
};
//===============================================
void GHttp_init(GHttp* _this);
GHttp* GHttp_new();
//===============================================
// GHttp.c
//===============================================
GHttp* GHttp_new() {
    GHttp* lObj = (GHttp*)malloc(sizeof(GHttp));
    GHttp_init(lObj);
    return lObj;
}
//===============================================
void GHttp_init(GHttp* _this) {
    assert(_this);
    _this->delete = GHttp_delete;
    _this->toResponse = GHttp_toResponse;
}
//===============================================
static void GHttp_delete(GHttp** _this) {
    assert(*_this);
    free(*_this);
    (*_this) = 0;
}
//===============================================
static void GHttp_toResponse(GHttp* _this, GString* _data, const char* _msg) {
    assert(_this);
    int lSize = strlen(_msg);
    _data->format(_data, ""
            "HTTP/1.1 200 OK\r\n"
            "Content-Length: %d\r\n"
            "\r\n"
            "%s"
            "", lSize, _msg);
}
//===============================================

Chargement d'une réponse web à partir d'un fichier


Résultat:

image.png

Réponse web:

<!-- ============================================ -->
<!-- index.html -->
<!-- ============================================ -->
<!DOCTYPE html>
<html>
    <head>
        <title>ReadyApp</title>
    </head>
    <body>
        <p>Bonjour tout le monde.</p>
    </body>
</html>
<!-- ============================================ -->

Chargement d'une réponse web à partir d'un fichier: 

//===============================================
// GTest.c
//===============================================
static void GTest_runSocket(GTest* _this, int _argc, char** _argv) {
    assert(_this);
    printf("%s...\n",  __PRETTY_FUNCTION__);

    GSocket* lSocket = GSocket_new();

    lSocket->run(lSocket);

    lSocket->delete(&lSocket);
}
//===============================================
// GSocket.c
//===============================================
static DWORD WINAPI GSocket_onThread(LPVOID _params) {
    GSocket* lClient = (GSocket*)_params;
    GString* lRequest = GString_new();
    GString* lResponse = GString_new();
    GHttp* lHttp = GHttp_new();

    lClient->read(lClient, lRequest);
    lRequest->print(lRequest);

    FILE* lFile = fopen("index.html", "rb");
    fseek(lFile, 0, SEEK_END);
    long lSize = ftell(lFile);
    fseek(lFile, 0, SEEK_SET);

    char* lData = (char*)malloc(sizeof(char)*(lSize + 1));
    fread(lData, lSize, 1, lFile);
    fclose(lFile);
    lData[lSize] = '\0';

    lHttp->toResponse(lHttp, lResponse, lData);
    lClient->send(lClient, lResponse->m_data);

    closesocket(lClient->m_socket);
    lRequest->delete(&lRequest);
    lClient->delete(&lClient);
    free(lData);
    return 0;
}
//===============================================

Création d'un gestionnaire de chargement d'un fichier


Résultat:

image.png

Création d'un gestionnaire de chargement d'un fichier: 

//===============================================
// GTest.c
//===============================================
static void GTest_runSocket(GTest* _this, int _argc, char** _argv) {
    assert(_this);
    printf("%s...\n",  __PRETTY_FUNCTION__);

    GSocket* lSocket = GSocket_new();

    lSocket->run(lSocket);

    lSocket->delete(&lSocket);
}
//===============================================
// GSocket.c
//===============================================
static DWORD WINAPI GSocket_onThread(LPVOID _params) {
    GSocket* lClient = (GSocket*)_params;
    GString* lRequest = GString_new();
    GString* lResponse = GString_new();
    GString* lFile = GString_new();
    GHttp* lHttp = GHttp_new();

    lClient->read(lClient, lRequest);
    lRequest->print(lRequest);

    lFile->loadFile(lFile, "index.html");
    lHttp->toResponse(lHttp, lResponse, lFile->m_data);
    lClient->send(lClient, lResponse->m_data);

    closesocket(lClient->m_socket);
    lRequest->delete(&lRequest);
    lFile->delete(&lFile);
    lClient->delete(&lClient);
    return 0;
}
//===============================================
// GString.c
//===============================================
static void GString_loadFile(GString* _this, const char* _filename) {
    assert(_this);
    FILE* lFile = fopen(_filename, "rb");
    fseek(lFile, 0, SEEK_END);
    long lSize = ftell(lFile);
    fseek(lFile, 0, SEEK_SET);
    _this->allocate(_this, lSize);
    fread(_this->m_data, lSize, 1, lFile);
    fclose(lFile);
}
//===============================================


Compilation d'un projet C



Affichage d'un message


Résultat:

image.png

Structure du dossier avant compilation:

src
|--- main.c
|--- compile.bat

Affichage d'un message:
 
//===============================================
// main.c
//===============================================
#include <stdio.h>
//===============================================
int main(int _argc, char** _argv) {
    printf("Bonjour tout le monde.\n");
    return 0;
}
//===============================================

Compilation du projet:

::===============================================
:: compile.bat
::===============================================
@echo off
::===============================================
set "PATH="
set "PATH=winlibs\mingw64\bin"
::===============================================
gcc -c main.c -o main.o
gcc -o readyapp.exe main.o
readyapp.exe
::===============================================

Lancement de la compilation du projet:

::===============================================
:: Terminal
::===============================================
compile.bat
::===============================================

Structure du dossier après compilation: 

src
|--- main.c
|--- compile.bat
|--- main.o
|--- readyapp.exe

Génération des fichiers objet dans un répertoire build


Résultat:

image.png

Structure du dossier avant compilation:
 
src
|--- main.c
|--- compile.bat
|--- build/

Affichage d'un message:

//===============================================
// main.c
//===============================================
#include <stdio.h>
//===============================================
int main(int _argc, char** _argv) {
    printf("Bonjour tout le monde.\n");
    return 0;
}
//===============================================

Compilation du projet:

::===============================================
:: compile.bat
::===============================================
@echo off
::===============================================
set "PATH="
set "PATH=winlibs\mingw64\bin"
::===============================================
gcc -c main.c -o build/main.o
gcc -o readyapp.exe build/main.o
readyapp.exe
::===============================================

Structure du dossier après compilation:  

src
|--- main.c
|--- compile.bat
|--- readyapp.exe
|--- build/
     |--- main.o

Génération du fichier exécutable dans un répertoire bin


Résultat:

image.png

Structure du dossier avant compilation:

src
|--- main.c
|--- compile.bat
|--- build/
|--- bin/

Affichage d'un message:

//===============================================
// main.c
//===============================================
#include <stdio.h>
//===============================================
int main(int _argc, char** _argv) {
    printf("Bonjour tout le monde.\n");
    return 0;
}
//===============================================

Compilation du projet:

::===============================================
:: compile.bat
::===============================================
@echo off
::===============================================
set "PATH="
set "PATH=winlibs\mingw64\bin"
::===============================================
gcc -c main.c -o build/main.o
gcc -o bin/readyapp.exe build/main.o
bin\readyapp.exe
::===============================================

Compilation du projet:

src
|--- main.c
|--- compile.bat
|--- build/
     |--- main.o
|--- bin/
     |--- readyapp.exe


Utilisation d'un Makefile



Définition d'une règle par défaut (all)


Structure du dossier avant compilation:

src
|--- main.c
|--- Makefile
|--- envs.bat

Définition d'une règle par défaut (all):
 
#================================================
# Makefile
#================================================
all: compile run
#================================================

Définition d'une règle de compilation (compile)


Définition d'une règle de compilation (compile):
 
#================================================
# Makefile
#================================================
all: compile run

compile: main.o
	gcc -o readyapp.exe main.o
#================================================

Définition d'une règle de compilation (main.o)


Définition d'une règle de compilation (main.o):
 
#================================================
# Makefile
#================================================
all: compile run

compile: main.o
	gcc -o readyapp.exe main.o
main.o: main.c
	gcc -c main.c -o main.o
#================================================

Définition d'une règle d'exécution (run)


Définition d'une règle d'exécution (run):
 
#================================================
# Makefile
#================================================
all: compile run

compile: main.o
	gcc -o readyapp.exe main.o
main.o: main.c
	gcc -c main.c -o main.o
run:
	readyapp.exe
#================================================

Définition d'une règle de nettoyage (clean)


Définition d'une règle de nettoyage (clean):
 
#================================================
# Makefile
#================================================
all: compile run

compile: main.o
	gcc -o readyapp.exe main.o
main.o: main.c
	gcc -c main.c -o main.o
run:
	readyapp.exe
clean:
	del /q /s readyapp.exe main.o
#================================================

Affichage d'un message


Résultat:

image.png

Affichage d'un message:

//===============================================
// main.c
//===============================================
#include <stdio.h>
//===============================================
int main(int _argc, char** _argv) {
    printf("Bonjour tout le monde.\n");
    return 0;
}
//===============================================

Fichier Makefile: 

#================================================
# Makefile
#================================================
all: compile run

compile: main.o
	gcc -o readyapp.exe main.o
main.o: main.c
	gcc -c main.c -o main.o
run:
	readyapp.exe
clean:
	del /q /s readyapp.exe main.o
#================================================

Initialisation des variables d'environnement:

::===============================================
:: envs.bat
::===============================================
@echo off
::===============================================
set "PATH="
set "PATH=winlibs\mingw64\bin"
::===============================================

Lancement de l'initialisation des variables d'environnement:

::===============================================
:: Terminal
::===============================================
envs.bat
::===============================================

Lancement du nettoyage du projet: 

::===============================================
:: Terminal
::===============================================
mingw32-make clean
::===============================================

Lancement de la compilation du projet:

::===============================================
:: Terminal
::===============================================
mingw32-make
::===============================================

Structure du dossier après compilation:  

src
|--- main.c
|--- Makefile
|--- envs.bat
|--- main.o
|--- readyapp.exe

Génération des fichiers objet dans des répertoires


Résultat:

image.png

Structure du dossier avant compilation: 

src
|--- main.c
|--- Makefile
|--- envs.bat
|--- build/
|--- bin/
Génération des fichiers objet dans des répertoires: 

#================================================
# Makefile
#================================================
all: compile run
#================================================
compile: build/main.o
	gcc -o bin\readyapp.exe build/main.o
build/main.o: main.c
	gcc -c main.c -o build/main.o
run:
	bin\readyapp.exe
clean:
	del /q /s bin\readyapp.exe build\main.o
#================================================

Structure du dossier après compilation:

src
|--- main.c
|--- Makefile
|--- envs.bat
|--- build/
     |--- main.o
|--- bin/
     |--- readyapp.exe

Utilisation d'une variable dans un fichier Makefile


Résultat:

image.png

Utilisation de variables dans un fichier Makefile:

#================================================
# Makefile
#================================================
GSRC = .
GBIN = bin
GBUILD = build
GTARGET = $(GBIN)\readyapp.exe
#================================================
GOBJS =\
	$(GBUILD)/main.o
#================================================
all: compile run
#================================================
compile: $(GOBJS)
	gcc -o $(GTARGET) $(GOBJS)
$(GBUILD)/main.o: $(GSRC)/main.c
	gcc -c $(GSRC)/main.c -o $(GBUILD)/main.o
run:
	$(GTARGET)
clean:
	del /q /s $(GTARGET) $(GBUILD)\main.o
#================================================

Utilisation d'une extension dans un Makefile


Résultat:

image.png

Utilisation d'une extension dans un Makefile:

#================================================
# Makefile
#================================================
GSRC = .
GBIN = bin
GBUILD = build
GTARGET = $(GBIN)\readyapp.exe
#================================================
GOBJS =\
	$(GBUILD)/main.o
#================================================
all: compile run
#================================================
compile: $(GOBJS)
	gcc -o $(GTARGET) $(GOBJS)
$(GBUILD)/%.o: $(GSRC)/%.c
	gcc -c $< -o $@
run:
	$(GTARGET)
clean:
	del /q /s $(GTARGET) $(GBUILD)\*.o
#================================================

Génération automatique des fichiers objet dans un Makefile


Résultat:

image.png

Génération automatique des fichiers objet dans un Makefile: 

#================================================
# Makefile
#================================================
GSRC = .
GBIN = bin
GBUILD = build
GTARGET = $(GBIN)\readyapp.exe
#================================================
GOBJS =\
    $(patsubst $(GSRC)/%.c, $(GBUILD)/%.o, $(wildcard $(GSRC)/*.c)) \
#================================================
all: compile run
#================================================
compile: $(GOBJS)
	gcc -o $(GTARGET) $(GOBJS)
$(GBUILD)/%.o: $(GSRC)/%.c
	gcc -c $< -o $@
run:
	$(GTARGET)
clean:
	del /q /s $(GTARGET) $(GBUILD)\*.o
#================================================

Passage des arguments en ligne de commande dans un Makefile


Passage des arguments en ligne de commande à un Makefile: 

::===============================================
:: Terminal
::===============================================
mingw32-make args="arg1 arg2 arg3"
::===============================================

Utilisation des arguments passés en ligne de commande dans un Makefile:
  
#================================================
# Makefile
#================================================
GSRC = .
GBIN = bin
GBUILD = build
GTARGET = $(GBIN)\readyapp.exe
#================================================
GOBJS =\
    $(patsubst $(GSRC)/%.c, $(GBUILD)/%.o, $(wildcard $(GSRC)/*.c)) \
#================================================
all: compile run
#================================================
compile: $(GOBJS)
	gcc -o $(GTARGET) $(GOBJS)
$(GBUILD)/%.o: $(GSRC)/%.c
	gcc -c $< -o $@
run:
	$(GTARGET) $(args)
clean:
	del /q /s $(GTARGET) $(GBUILD)\*.o
#================================================

Utilisation des variables d'environnement dans un Makefile


Utilisation des variables d'environnement dans un Makefile:

#================================================
# Makefile
#================================================
GSRC = .
GBIN = bin
GBUILD = build
GTARGET = $(GBIN)\readyapp.exe
#================================================
GOBJS =\
    $(patsubst $(GSRC)/%.c, $(GBUILD)/%.o, $(wildcard $(GSRC)/*.c)) \
#================================================
all: compile run
#================================================
compile: $(GOBJS)
	gcc -o $(GTARGET) $(GOBJS)
$(GBUILD)/%.o: $(GSRC)/%.c
	gcc -c $< -o $@
run:
	envs.bat && $(GTARGET) $(args)
clean:
	del /q /s $(GTARGET) $(GBUILD)\*.o
#================================================

Utilisation d'une librairie dynamique dans un Makefile


Utilisation d'une librairie dynamique dans un Makefile: 

#================================================
GSRC = .
GBIN = bin
GBUILD = build
GTARGET = $(GBIN)\readyapp.exe
#================================================
GLIBS =\
	-lws2_32 \
	
GOBJS =\
    $(patsubst $(GSRC)/%.c, $(GBUILD)/%.o, $(wildcard $(GSRC)/*.c)) \
#================================================
GCFLAGS =\
    --std=gnu11 \
#================================================
all: compile run
#================================================
compile: $(GOBJS)
	gcc $(GCFLAGS) -o $(GTARGET) $(GOBJS)  $(GLIBS) 
$(GBUILD)/%.o: $(GSRC)/%.c
	gcc $(GCFLAGS) -c $< -o $@
run:
	$(GTARGET) $(args)
clean:
	del /q /s $(GTARGET) $(GBUILD)\*.o
#================================================


Utilisation des standards C



Affichage d'un message


Résultat:

image.png

Affichage d'un message: 

//===============================================
// main.c
//===============================================
#include <stdio.h>
//===============================================
int main(int _argc, char** _argv) {
    printf("Bonjour tout le monde.\n");
    return 0;
}
//===============================================

Fichier Makefile:

#================================================
# Makefile
#================================================
GSRC = .
GBIN = bin
GBUILD = build
GTARGET = $(GBIN)\readyapp.exe
#================================================
GOBJS =\
    $(patsubst $(GSRC)/%.c, $(GBUILD)/%.o, $(wildcard $(GSRC)/*.c)) \
#================================================
all: compile run
#================================================
compile: $(GOBJS)
	gcc -o $(GTARGET) $(GOBJS)
$(GBUILD)/%.o: $(GSRC)/%.c
	gcc -c $< -o $@
run:
	$(GTARGET)
clean:
	del /q /s $(GTARGET) $(GBUILD)\*.o
#================================================

Utilisation du standard c11


Résultat:

image.png

Fichier Makefile:

#================================================
GSRC = .
GBIN = bin
GBUILD = build
GTARGET = $(GBIN)\readyapp.exe
#================================================
GOBJS =\
    $(patsubst $(GSRC)/%.c, $(GBUILD)/%.o, $(wildcard $(GSRC)/*.c)) \
#================================================
GCFLAGS =\
    --std=gnu11 \
#================================================
all: compile run
#================================================
compile: $(GOBJS)
	gcc $(GCFLAGS) -o $(GTARGET) $(GOBJS)
$(GBUILD)/%.o: $(GSRC)/%.c
	gcc $(GCFLAGS) -c $< -o $@
run:
	$(GTARGET)
clean:
	del /q /s $(GTARGET) $(GBUILD)\*.o
#================================================


Utilisation du débogueur GDB



Affichage d'un message


Résultat:

Affichage d'un message:

//===============================================
// main.c
//===============================================
#include <stdio.h>
//===============================================
int main(int _argc, char** _argv) {
    printf("Bonjour tout le monde.\n");
    return 0;
}
//===============================================

Fichier Makefile:

#================================================
# Makefile
#================================================
GSRC = .
GBIN = bin
GBUILD = build
GTARGET = $(GBIN)\readyapp.exe
#================================================
GOBJS =\
    $(patsubst $(GSRC)/%.c, $(GBUILD)/%.o, $(wildcard $(GSRC)/*.c)) \
#================================================
GCFLAGS =\
    --std=gnu11 \
#================================================
all: compile run
#================================================
compile: $(GOBJS)
	gcc $(GCFLAGS) -o $(GTARGET) $(GOBJS)
$(GBUILD)/%.o: $(GSRC)/%.c
	gcc $(GCFLAGS) -c $< -o $@
run:
	$(GTARGET) $(args)
clean:
	del /q /s $(GTARGET) $(GBUILD)\*.o
#================================================

Utilisation du débogueur GDB


Résultat:

image.png

Fichier Makefile:

#================================================
# Makefile
#================================================
GSRC = .
GBIN = bin
GBUILD = build
GTARGET = $(GBIN)\readyapp.exe
#================================================
GOBJS =\
    $(patsubst $(GSRC)/%.c, $(GBUILD)/%.o, $(wildcard $(GSRC)/*.c)) \
#================================================
GCFLAGS =\
    --std=gnu11 \
#================================================
all: compile run
#================================================
compile: $(GOBJS)
	gcc $(GCFLAGS) -o $(GTARGET) $(GOBJS)
$(GBUILD)/%.o: $(GSRC)/%.c
	gcc $(GCFLAGS) -c $< -o $@
run:
	$(GTARGET) $(args)
run_g:
	gdb -ex run --args $(GTARGET) $(args)
clean:
	del /q /s $(GTARGET) $(GBUILD)\*.o
#================================================

Utilisation du débogueur GDB:

::===============================================
:: Terminal
::===============================================
mingw32-make run_g
::===============================================