Séparation des fonctions d'interprétation des arguments
This commit is contained in:
parent
67542a87c2
commit
deb62aec9c
35
Makefile
35
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):
|
$(OUT):
|
||||||
mkdir -p $(OUT)
|
mkdir -p $(OUT)
|
||||||
|
|
||||||
# Lier les différents fichiers objets générés en un exécutable
|
# Génération de la documentation
|
||||||
$(OUT)$(PROG): $(OBJECTS)
|
docs: $(OUT)
|
||||||
$(CC) $^ $(CFLAGS) -o $@
|
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)buffer.o: $(SRC)buffer.c $(INC)buffer.h
|
||||||
$(OUT)compress.o: $(SRC)compress.c $(INC)compress.h $(INC)common.h \
|
$(OUT)compress.o: $(SRC)compress.c $(INC)common.h $(INC)compress.h \
|
||||||
$(INC)display.h
|
$(INC)buffer.h $(INC)huftree.h $(INC)display.h
|
||||||
$(OUT)decompress.o: $(SRC)decompress.c $(INC)decompress.h $(INC)buffer.h \
|
$(OUT)decompress.o: $(SRC)decompress.c $(INC)huftree.h $(INC)buffer.h \
|
||||||
$(INC)display.h $(INC)huftree.h
|
$(INC)display.h $(INC)decompress.h
|
||||||
$(OUT)display.o: $(SRC)display.c $(INC)display.h $(INC)common.h
|
$(OUT)display.o: $(SRC)display.c $(INC)common.h $(INC)display.h \
|
||||||
$(OUT)huftree.o: $(SRC)huftree.c $(INC)huftree.h $(INC)common.h
|
$(INC)huftree.h
|
||||||
$(OUT)main.o: $(SRC)main.c $(INC)compress.h $(INC)common.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):
|
$(OBJECTS):
|
||||||
$(CC) $(CFLAGS) -o $@ -c $<
|
$(CC) $(CFLAGS) -o $@ -c $<
|
||||||
|
|
||||||
# Nettoyer le dossier de sortie
|
# Nettoyage du dossier de sortie
|
||||||
clean:
|
clean:
|
||||||
rm -rf out
|
rm -rf out
|
||||||
|
|
|
@ -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 <stdio.h>
|
||||||
|
#include <argp.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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__
|
|
@ -0,0 +1,65 @@
|
||||||
|
#include "arguments.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#include <argp.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
90
src/main.c
90
src/main.c
|
@ -2,6 +2,7 @@
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "compress.h"
|
#include "compress.h"
|
||||||
#include "decompress.h"
|
#include "decompress.h"
|
||||||
|
#include "arguments.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <argp.h>
|
#include <argp.h>
|
||||||
|
@ -9,93 +10,14 @@
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/**
|
// Nom, version du programme et adresse pour les bugs
|
||||||
* Contient les valeurs des arguments (options et opérandes)
|
// (ces informations sont affichées dans l'aide)
|
||||||
* 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)
|
|
||||||
*/
|
|
||||||
const char *argp_program_version = "huffman 0.1";
|
const char *argp_program_version = "huffman 0.1";
|
||||||
const char *argp_program_bug_address =
|
const char *argp_program_bug_address =
|
||||||
"<matteo.delabre@etu.umontpellier.fr>";
|
"<matteo.delabre@etu.umontpellier.fr>";
|
||||||
|
|
||||||
/**
|
// Définition de la configuration de Argp, qui affichera
|
||||||
* Définition de la configuration de Argp, qui affichera
|
// ces informations dans la page d'aide entre autres
|
||||||
* ces informations dans la page d'aide entre autres
|
|
||||||
*/
|
|
||||||
static struct argp_option options[] = {
|
static struct argp_option options[] = {
|
||||||
{
|
{
|
||||||
.name = "decompress",
|
.name = "decompress",
|
||||||
|
@ -112,7 +34,7 @@ static struct argp_option options[] = {
|
||||||
|
|
||||||
static struct argp argp = {
|
static struct argp argp = {
|
||||||
.options = options,
|
.options = options,
|
||||||
.parser = parse_opt,
|
.parser = parseArgument,
|
||||||
.args_doc = "SOURCE [DEST]",
|
.args_doc = "SOURCE [DEST]",
|
||||||
.doc = "Compresse SOURCE vers DEST (par défaut, vers la sortie standard) "
|
.doc = "Compresse SOURCE vers DEST (par défaut, vers la sortie standard) "
|
||||||
"en utilisant l'algorithme de Huffman"
|
"en utilisant l'algorithme de Huffman"
|
||||||
|
|
Loading…
Reference in New Issue