Ajouter Documentation/base-guidee.md
This commit is contained in:
@@ -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**.
|
||||||
Reference in New Issue
Block a user