Projet 2 • TR
| Champ | Valeur |
|---|---|
| Auteur·e | Élise |
| Édition | 2023-12-12 |
| Durée | 1,5 semaine |
| Taille des équipes | 1 personne |
| Rendu | via git, dépôt $YEAR_tr, droits en lecture à delivery_collector |
Barème
| Critères | Points |
|---|---|
| Fonctionnalité : remplacement CHAINE_1 CHAINE_2 | 4 |
| Fonctionnalité : suppression -d CHARS | 3 |
| Fonctionnalité : suppression inversée -c -d CHARS | 3 |
| Fonctionnalité : helper -h | 2 |
| Allocation juste de la mémoire | 3 |
| Libération de la mémoire | 2 |
| Absence d’erreurs mémoires (valgrind/memcheck) | 3 |
| Points accessibles | 20 |
| Malus par ligne contenant une faute de norme | -0,5 |
| Malus dépôt sale | -5 |
| Note maximale | 20 |
Règlement de projet
La réalisation de cet exercice est assujettie aux règles en vigueur dans l’école en matière de triche et de normalisation. Tricher vous expose à de graves sanctions.
Vous devez respecter les règles de normalisation suivantes : https://git.ecole-89.com/eriizu/coding_style/src/branch/main/norm.md
Le non-respect de la norme vous fera perdre une partie ou la totalité des points qui auraient pu être acquis, sur l’ensemble du rendu.
Fichiers à rendre
La structure de votre dépôt doit être la suivante :
- fichiers
*.cdanssrc/ - fichiers
*.hdansinclude/
Comme vous devez rendre un programme, vous devez rendre une fonction main. Son fichier, devra s’appeler main.c, être dans le dossier src/ et respecter les règles de normalisation (il ne s’agit pas d’un fichier de test.)
Votre projet sera compilé avec la commande suivante :
gcc -Wall -Wextra -Werror -Iinclude ./src/*.c -o tr
Fonctions autorisées et interdites
Pour tout le sujet, les fonctions autorisées sont :
writereadmallocfree
Tests
Vous pouvez inclure des main de test dans votre rendu. Ces main doivent être rendus dans un dossier test/. Vous pouvez organiser ce dépôt comme vous le souhaitez.
Préambule
Contexte : systèmes UNIX
Sur un système Linux et sur les systèmes UNIX en général, il y a tout plein de petits outils sous forme de programmes qui nous permettent de faire des opérations quotidiennes depuis un terminal. Vous avez implémenté cat qui est l’un d’entre eux, et probablement l’un des plus utilisés. Vous en avez manipulé plein d’autres comme head, tail, echo, ls, rm, etc. notamment lors de gameshell.
Ces commandes sont requises par une norme qui s’appelle POSIX (et une autre qui s’appelle SUS et qui aujourd’hui est fonctionnellement identique à POSIX) que GNU/Linux respecte en grande partie.
POSIX décrit également comment doivent se comporter les appels systèmes (comme read, write, open et close). Si vous allez sur le man de read.2, vous pouvez constater qu’il y a une section “STANDARDS” avec la norme à laquelle cette fonction se conforme. Il existe même une page read.3p qui correspond au manuel de la fonction telle que POSIX l’imagine.
Ces standards ont plusieurs intérêts.
- Si vous devez utiliser une machine qui tourne sur NetBSD, FreeBSD, OpenBDS ou sur MacOS, vous ne serez pas complètements perdus. Les commandes de base sont les mêmes. Elles peuvent avoir des variations mineures comme majeures mais elles ne vous seront pas complètement étrangères.
- Un programme écrit pour Linux (faisant usage d’appels systèmes directement), peut être porté facilement sur un autre système UNIX. Parfois sans avoir à changer une seule ligne de code.
Ces choses là étant possible sans que MacOS et Linux (par exemple) n’aient d’ancêtres communs.
Introduction
Dans le cadre de ce sujet, vous allez implémenter un clone partiel de la commande tr. Il s’agit d’un utilitaire qui peut remplacer ou supprimer des caractères lus sur son entrée standard. Il affiche le résultat sur sa sortie standard.
tr est un outil nécessaire pour qu’un système soit considéré POSIX. Il a fait sa première apparition sur la version 4 d’UNIX en 1973, avant même la première version de Windows (1985) ou de MS-DOS (1981). Il a donc fêté ses 50 ans cette année.
Consignes
Implémentez un clone de tr avec ces trois modes de fonctionnement :
- remplacement de caractères ;
- suppression de caractères faisant partie d’un ensemble ; et
- suppression de caractères ne faisant pas partie d’un ensemble.
Il peut y avoir n’importe quelle quantité d’octets sur l’entrée standard, vous devez donc lire en boucle.
Après avoir lu des caractères depuis l’entrée standard, vous devez les traiter et les afficher immédiatement. Vous êtes autorisés à appeler read seulement après avoir affiché le résultat de la dernière lecture.
Fonctionnalité : traduction simple
Le comportement de TR est différent en fonction des arguments reçus. Sans options, TR est en mode traduction. Il admet deux chaînes en argument appelons-les to_replace et substitutes.
TR restitue ce qu’il lit depuis l’entrée standard sur la sortie standard sauf pour les caractères qui sont présents dans to_replace. Chacun de ces caractères doit être remplacé par un caractère tiré de substitutes à la même position.
Exemple :
[sh] $ echo "tata" | ./tr a i
titi
[sh] $ echo "tata" | ./tr at if
fifi
Dans le premier exemple les “a” sont remplacés par des “i”.
Dans le second exemple :
- les “a” sont remplacés par des “i” ; et
- les “t” sont remplacés par des “f”.
Et ce peut importe le nombre de caractères dans to_replace et substitutes.
Erreurs possibles :
to_replaceetsubstitutesne font pas la même taille ; et- il n’y a pas assez d’arguments.
Fonctionnalité : suppression
Avec l’option d TR admet une chaîne en argument que l’on va appeler to_delete.
TR va restituer les caractères lus depuis l’entrée standard sauf ceux qui apparaissent dans to_delete.
[sh] $ echo zabcdef | ./tr -d zcdb
aef
Erreur possible :
- s’il n’y a pas assez d’arguments.
Fonctionnalité : conservation
Avec les options d et c TR admet une chaîne en argument que l’on va appeler to_keep.
TR va restituer les caractères lus depuis l’entrée standard SEULEMENT SI ils figurent dans la chaîne to_keep.
Cela concerne aussi les retours à la ligne, ce qui signifie que TR risque de ne rien afficher jusqu’à ce qu’il reçoive EOF s’il n’y a pas de \n dans to_keep.
[sh] $ echo lmqskdjfqmssldtakjfqmslkdmf | ./tr -cd ta
ta[sh] $ echo lmqskdjfqmssldtakjfqmslkdmf | ./tr -cd ta\\n
ta
[sh] $
Le \n sera reçu comme deux caractères séparés par votre programme. Il faudra le considérer comme un retour à la ligne quand même.
Fonctionnalité : helper
Lorsque vous recevez l’option h, affichez l’aide de votre programme. Elle doit avoir le même style que tr --help et elle doit inclure seulement les fonctionnalités que vous avec implémenté.
Elle doit aussi être en anglais.