Ajouter Documentation/base-guidee.md

This commit is contained in:
2026-09-25 10:47:13 +02:00
parent 4128ff9bef
commit 6971d8289a
+170
View File
@@ -0,0 +1,170 @@
# Comprendre la base guidée
**Au TP1, lire les parties 1 à 5 pendant les temps de découverte déjà prévus.**
Les pointeurs de fonctions viennent au CM3/TP3 : voir
[APPELS-INDIRECTS.md](APPELS-INDIRECTS.md). Il n'est pas nécessaire de commencer par eux.
## 1. À quoi sert ce programme ?
Snapguard construit une sauvegarde consultable dans un répertoire. On appelle
**instantané** cette copie datée de l'arborescence. Le programme reçoit une source,
une nouvelle destination et, éventuellement, un instantané précédent.
Le nom de destination est choisi par l'appelant : le programme n'y ajoute pas
automatiquement une date.
```text
./snapguard SOURCE DESTINATION [PRECEDENT]
```
Les crochets signifient « argument facultatif » : on ne les tape pas. Sans
précédent, le programme copie les fichiers. Sinon, il décide pour chaque fichier
s'il peut réutiliser sa version précédente ou doit le copier.
La destination est d'abord construite sous un nom terminé par `.en-cours`.
**Publier** signifie ici renommer ce répertoire vers le nom définitif.
Ce n'est ni une mise en ligne ni un envoi sur Internet.
Le parcours, les opérations sur les fichiers et les tests sont fournis. Vous
faites évoluer quatre décisions en C, une par TP. Le programme contient les
défauts annoncés : on observe son comportement actuel avant de le comparer au
comportement attendu.
## 2. Où se trouve chaque responsabilité ?
| Fichier | Son rôle | Votre lecture |
|---|---|---|
| `src/sg.h` | Types, prototypes et contrats communs | Le type et le contrat du TP du jour |
| `src/main.c` | Lit les arguments, lance la sauvegarde, affiche le résultat | La fonction `main`, sans détailler d'abord les contrôles de chemins |
| `src/service.c` | Organise les étapes et parcourt les répertoires | Les points d'appel indiqués dans le sujet |
| `src/rapport.c` | Choisit l'étiquette du bilan | Chantier TP1 |
| `src/regles.c` | Décide si une version précédente est réutilisable | Chantier TP2 |
| `src/transfert.c` | Organise les tentatives de lien et de copie | Chantier TP3 |
| `src/finalisation.c` | Décide de publier et met à jour l'état | Chantier TP4 |
| `src/fs_posix.c` | Réalise les opérations sur de vrais fichiers sous Linux ou macOS | Fourni ; détails système à consulter au besoin |
| `tests/test_seances.c` | Prépare les cas R, D, E et A et vérifie leurs résultats | Les tests de votre séquence |
| `tests/mes_tests.c` | Accueille vos tests personnels | À compléter selon le sujet |
| `tests/doublure.h` et `.c` | Simulent des réponses et comptent les appels | À lire au TP3 |
| `tests/integration.py` | Lance le vrai programme sur des fichiers temporaires | À exécuter ; Python n'est pas un chantier du projet |
| `Makefile` | Donne les commandes de compilation et de test | Utiliser les cibles annoncées |
`sg_` est le préfixe des noms du projet ; `_t` est une convention pour les noms
de types. Ces morceaux de noms ne sont pas des instructions du langage C.
## 3. Quel chemin suit une sauvegarde ?
Voici les appels principaux d'une exécution qui atteint la fin du parcours.
L'indentation signifie « appelle » ; certaines erreurs peuvent arrêter plus tôt.
```text
main() [main.c]
sg_sauvegarder(...) [service.c]
initialise le rapport et l'état
vérifie la source et crée le répertoire de travail
parcourir(...) [service.c]
pour chaque fichier :
sg_reutilisable(...) [regles.c]
sg_transferer(...) [transfert.c]
pour chaque sous-répertoire : parcourir(...) à nouveau
sg_finaliser(...) [finalisation.c]
sg_bilan(&rapport) [rapport.c]
affiche les compteurs et l'état
```
Le service organise les tâches. Les quatre fonctions étudiées en TP répondent
chacune à une question locale. `sg_bilan` est appelée après le retour du service :
elle lit le rapport, elle ne déclenche pas la sauvegarde.
**Exemple sans incident ni précédent :** pour deux fichiers copiés, le rapport
contient `vus=2`, `copies=2`, `lies=0`, `erreurs=0`. Le renommage final réussit,
l'état devient `SG_COMPLET`, puis `main` affiche les résultats.
## 4. Quelles données circulent ?
| Type | Ce qu'il représente | À retenir |
|---|---|---|
| `sg_entree_t` | Nom, taille, date `mtime`, nature d'un fichier ou répertoire | Des métadonnées, pas le contenu. `off_t` représente une taille ; `time_t`, une date. |
| `sg_rapport_t` | Compteurs `vus`, `copies`, `lies`, `erreurs` | Le service et le transfert les remplissent ; le bilan les lit. `vus` compte les fichiers rencontrés, pas les répertoires. |
| `sg_etat_t` | État de la tentative : en cours, complet ou échec | Déclaré avec `enum` ; distinct des compteurs de traitement. |
| `sg_port_t` | Opérations utilisables pour accéder aux fichiers | Au TP1, retenir : une boîte à opérations déjà préparée. Les adresses de fonctions seront lues au TP3. |
Dans `main.c` :
```c
sg_rapport_t rapport;
sg_etat_t etat;
int code = sg_sauvegarder(sg_posix(), argv[1], precedent,
argv[2], &rapport, &etat);
```
`rapport` et `etat` sont des objets locaux à `main`. Leurs adresses sont
transmises pour que le service puisse les initialiser et les modifier.
Il ne reçoit pas une copie du rapport. Ces objets existent pendant l'appel.
```c
const char *sg_bilan(const sg_rapport_t *r);
```
`r` pointe vers le rapport. `r->erreurs` lit son champ `erreurs` ; c'est une
autre écriture de `(*r).erreurs`. Le `const` interdit de modifier le rapport
à travers `r`. Le résultat `const char *` désigne le texte de l'étiquette.
`sg_bilan` n'alloue pas un nouveau rapport.
Le retour `code`, les compteurs et l'état répondent à des questions différentes.
Zéro erreur de traitement ne prouve pas que le renommage final a réussi.
On approfondira cette distinction au TP4.
## 5. Pourquoi un `.h` et plusieurs `.c` ?
`sg.h` décrit ce qu'un fichier doit connaître pour utiliser une fonction définie
ailleurs : nom, paramètres et résultat. Il définit aussi les types partagés.
Les commentaires de contrat disent ce que la fonction doit garantir.
`#include "sg.h"` rend ces déclarations visibles au compilateur ; cela
**n'exécute aucune fonction**. La définition de `sg_bilan`, avec son corps,
est dans `rapport.c`. On inclut le `.h`, pas le `.c`. Les lignes `#ifndef`,
`#define` et `#endif` évitent de relire deux fois le même en-tête lors de la
compilation d'un fichier.
Le Makefile construit trois programmes séparés :
| Programme | Point de départ | Opérations utilisées |
|---|---|---|
| `snapguard` | `main` dans `src/main.c` | Vrais fichiers : `src/fs_posix.c` |
| `run_tests` | `main` dans `tests/test_seances.c` | Cas fournis ; opérations simulées si nécessaire |
| `tests_perso` | `main` dans `tests/mes_tests.c` | Vos cas ; même simulation disponible |
Les mêmes fichiers de décision sont compilés avec chacun des programmes.
Il y a plusieurs fonctions `main` dans le dossier, mais **une seule par
exécutable**. Les tests n'ont pas leur propre copie corrigée de vos fonctions.
Depuis le dossier `base-guidee/` :
```sh
make depart
make observer
make test-s1
```
`make depart` compile les trois programmes puis vérifie une copie sur des
données temporaires. `make observer` affiche deux rapports : dans la base
initiale, leur étiquette vaut `OK` malgré leurs compteurs différents.
`make test-s1` signale alors l'échec de R2. C'est le défaut à étudier, pas
une installation ratée. Une erreur de compilation, en revanche, empêche de
lancer les tests : il faut d'abord lire le message du compilateur.
**Avant de modifier :** retrouvez le prototype de `sg_bilan`, sa définition,
son appel et R2. Expliquez qui écrit le rapport et qui le lit. Vous avez ainsi
suivi une donnée entre plusieurs fichiers sans lire toute l'infrastructure.
## 6. Ce qui s'ajoute aux séances suivantes
- **TP2 :** dans `parcourir`, suivre `p`, initialement `NULL`, puis `&info` si
les métadonnées précédentes sont disponibles. `NULL` marque ici leur absence.
Un lien dur crée un autre nom pour le même fichier : il vise la version de
l'instantané précédent, jamais la source susceptible de changer.
- **TP3 :** lire [APPELS-INDIRECTS.md](APPELS-INDIRECTS.md), puis suivre un appel
de `transfert.c` jusqu'à la doublure : fonction choisie et contexte.
- **TP4 :** suivre l'adresse de l'état jusqu'à `sg_finaliser`, puis observer
l'appel de publication et les effets autorisés.
À chaque TP : **contrat → appel → résultat prédit → test → modification**.