From deb62aec9c7fab7c40e009bf9c60ffaf7907b4dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delabre=20=E2=9C=8F?= Date: Wed, 30 Nov 2016 11:55:20 +0100 Subject: [PATCH] =?UTF-8?q?S=C3=A9paration=20des=20fonctions=20d'interpr?= =?UTF-8?q?=C3=A9tation=20des=20arguments?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 35 +++++++++++-------- inc/arguments.h | 48 ++++++++++++++++++++++++++ src/arguments.c | 65 +++++++++++++++++++++++++++++++++++ src/main.c | 90 ++++--------------------------------------------- 4 files changed, 140 insertions(+), 98 deletions(-) create mode 100644 inc/arguments.h create mode 100644 src/arguments.c diff --git a/Makefile b/Makefile index 7cf4ea7..d4295e2 100644 --- a/Makefile +++ b/Makefile @@ -15,29 +15,36 @@ OBJECTS=$(patsubst $(SRC)%.c,$(OUT)%.o,$(SOURCES)) ##################################################### -all: $(OUT) $(OUT)$(PROG) +all: $(OUT) $(OUT)$(PROG) docs -# Créer le dossier de sortie si nécessaire +# Création du dossier de sortie $(OUT): mkdir -p $(OUT) -# Lier les différents fichiers objets générés en un exécutable -$(OUT)$(PROG): $(OBJECTS) - $(CC) $^ $(CFLAGS) -o $@ +# Génération de la documentation +docs: $(OUT) + doxygen + $(MAKE) -C $(OUT)doxygen/latex -# Générer les fichiers objets pour chaque source +# Génération du programme ./huffman +$(OUT)$(PROG): $(OUT) $(OBJECTS) + $(CC) $(OBJECTS) $(CFLAGS) -o $(OUT)$(PROG) + +$(OUT)arguments.o: $(SRC)arguments.c $(INC)arguments.h $(INC)common.h $(OUT)buffer.o: $(SRC)buffer.c $(INC)buffer.h -$(OUT)compress.o: $(SRC)compress.c $(INC)compress.h $(INC)common.h \ - $(INC)display.h -$(OUT)decompress.o: $(SRC)decompress.c $(INC)decompress.h $(INC)buffer.h \ - $(INC)display.h $(INC)huftree.h -$(OUT)display.o: $(SRC)display.c $(INC)display.h $(INC)common.h -$(OUT)huftree.o: $(SRC)huftree.c $(INC)huftree.h $(INC)common.h -$(OUT)main.o: $(SRC)main.c $(INC)compress.h $(INC)common.h +$(OUT)compress.o: $(SRC)compress.c $(INC)common.h $(INC)compress.h \ + $(INC)buffer.h $(INC)huftree.h $(INC)display.h +$(OUT)decompress.o: $(SRC)decompress.c $(INC)huftree.h $(INC)buffer.h \ + $(INC)display.h $(INC)decompress.h +$(OUT)display.o: $(SRC)display.c $(INC)common.h $(INC)display.h \ + $(INC)huftree.h +$(OUT)huftree.o: $(SRC)huftree.c $(INC)common.h $(INC)huftree.h $(INC)buffer.h +$(OUT)main.o: $(SRC)main.c $(INC)common.h $(INC)display.h $(INC)compress.h \ + $(INC)decompress.h $(INC)arguments.h $(OBJECTS): $(CC) $(CFLAGS) -o $@ -c $< -# Nettoyer le dossier de sortie +# Nettoyage du dossier de sortie clean: rm -rf out diff --git a/inc/arguments.h b/inc/arguments.h new file mode 100644 index 0000000..7cd6a3e --- /dev/null +++ b/inc/arguments.h @@ -0,0 +1,48 @@ +/** + * @file + * @brief Interprétation des arguments (options et opérandes) passés + * au programme + */ + +#ifndef __HUFFMAN_ARGUMENTS_H_INCLUDED__ +#define __HUFFMAN_ARGUMENTS_H_INCLUDED__ + +#include +#include + +/** + * @brief Valeurs des arguments (options et opérandes) passés au programme. + */ +typedef struct Args { + /** + * Lance-t-on le programme en mode verbeux ? (informations de débogage) + */ + int verbose; + + /** + * Compresse-t-on la source ou bien la décompresse-t-on ? + */ + int compress; + + /** + * Fichier source de l'opération à effectuer + */ + FILE* source; + + /** + * Fichier de sortie de l'opération effectuée + */ + FILE* dest; +} Args; + +/** + * @brief Interpréter l'argument @p key de valeur @p arg dans + * la structure argp d'état @p state + * + * @param key Clé de l'option, ou clé spéciale pour indiquer une opérande + * @param arg Valeur de l'option ou de l'opérande + * @param state État actuel de argp + */ +error_t parseArgument(int key, char* arg, struct argp_state* state); + +#endif // __HUFFMAN_ARGUMENTS_H_INCLUDED__ diff --git a/src/arguments.c b/src/arguments.c new file mode 100644 index 0000000..6f2d0bb --- /dev/null +++ b/src/arguments.c @@ -0,0 +1,65 @@ +#include "arguments.h" +#include "common.h" + +#include +#include + +error_t parseArgument(int key, char* arg, struct argp_state* state) { + Args* args = state->input; + + switch (key) { + case 'v': + args->verbose = TRUE; + break; + + case 'd': + args->compress = FALSE; + break; + + case ARGP_KEY_ARG: + switch (state->arg_num) { + case 0: + // Premier argument : fichier d'entrée + args->source = fopen(arg, "rb"); + + if (args->source == NULL) { + argp_error( + state, "%s: %s", + arg, strerror(errno) + ); + } + break; + + case 1: + // Second argument : fichier de sortie. Si omis, + // utilisation de la sortie standard + args->dest = fopen(arg, "wb"); + + if (args->dest == NULL) { + argp_error( + state, "%s: %s", + arg, strerror(errno) + ); + } + break; + + default: + argp_error( + state, "trop d'arguments (l'argument %s, numéro %d " + "est superflu)", arg, state->arg_num + 1 + ); + } + break; + + case ARGP_KEY_END: + if (state->arg_num < 1) { + argp_error(state, "fichier d'entrée manquant"); + } + break; + + default: + return ARGP_ERR_UNKNOWN; + } + + return 0; +} diff --git a/src/main.c b/src/main.c index c7bdb8d..922236c 100644 --- a/src/main.c +++ b/src/main.c @@ -2,6 +2,7 @@ #include "display.h" #include "compress.h" #include "decompress.h" +#include "arguments.h" #include #include @@ -9,93 +10,14 @@ #include #include -/** - * Contient les valeurs des arguments (options et opérandes) - * passées au programme et interprétées via Argp - */ -typedef struct Args { - int verbose; - int compress; - FILE* source; - FILE* dest; -} Args; - -/** - * Fonction de rappel pour interpréter les arguments - * passés au programme - */ -static error_t parse_opt(int key, char* arg, struct argp_state* state) { - Args* args = state->input; - - switch (key) { - case 'v': - args->verbose = TRUE; - break; - - case 'd': - args->compress = FALSE; - break; - - case ARGP_KEY_ARG: - switch (state->arg_num) { - case 0: - // Premier argument : fichier d'entrée - args->source = fopen(arg, "rb"); - - if (args->source == NULL) { - argp_error( - state, "%s: %s", - arg, strerror(errno) - ); - } - break; - - case 1: - // Second argument : fichier de sortie. Si omis, - // utilisation de la sortie standard - args->dest = fopen(arg, "wb"); - - if (args->dest == NULL) { - argp_error( - state, "%s: %s", - arg, strerror(errno) - ); - } - break; - - default: - argp_error( - state, "trop d'arguments (l'argument %s, numéro %d " - "est superflu)", arg, state->arg_num + 1 - ); - } - break; - - case ARGP_KEY_END: - if (state->arg_num < 1) { - argp_error(state, "fichier d'entrée manquant"); - } - break; - - default: - return ARGP_ERR_UNKNOWN; - } - - return 0; -} - -/** - * Nom, version du programme et adresse pour les bugs - * (ces informations sont affichées dans l'aide) - */ +// Nom, version du programme et adresse pour les bugs +// (ces informations sont affichées dans l'aide) const char *argp_program_version = "huffman 0.1"; const char *argp_program_bug_address = ""; -/** - * Définition de la configuration de Argp, qui affichera - * ces informations dans la page d'aide entre autres - */ +// Définition de la configuration de Argp, qui affichera +// ces informations dans la page d'aide entre autres static struct argp_option options[] = { { .name = "decompress", @@ -112,7 +34,7 @@ static struct argp_option options[] = { static struct argp argp = { .options = options, - .parser = parse_opt, + .parser = parseArgument, .args_doc = "SOURCE [DEST]", .doc = "Compresse SOURCE vers DEST (par défaut, vers la sortie standard) " "en utilisant l'algorithme de Huffman"