huffman/src/main.c

136 lines
3.4 KiB
C

#include "common.h"
#include "compress.h"
#include <argp.h>
#include <locale.h>
#include <string.h>
/**
* Définition de la configuration de Argp, qui affichera
* ces informations dans la page d'aide entre autres
*/
static char doc[] = "Compresse ou décompresse des fichiers en "
"utilisant l'algorithme de Huffman";
static char args_doc[] = "FICHIER...";
static struct argp_option options[] = {
{
"verbose", 'V', 0, 0,
"Afficher des informations de débogage sur la compression"
},
{0}
};
/**
* Contient les valeurs des arguments (options et opérandes)
* passées au programme et interprétées via Argp
*/
typedef struct Args {
int verbose;
char** files;
} 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 ARGP_KEY_ARG:
// Consommation de tous les fichiers en argument
// et arrêt du parsage
args->files = &state->argv[state->next - 1];
state->next = state->argc;
break;
case ARGP_KEY_NO_ARGS:
argp_usage(state);
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct argp argp = {options, parse_opt, args_doc, doc};
int main(int argc, char** argv) {
// Pour pouvoir afficher des caractères larges dans le terminal
setlocale(LC_CTYPE, "");
// Interprétation des arguments passés au programme par Argv,
// suivant la configuration définie au dessus
Args args;
args.verbose = FALSE;
args.files = NULL;
argp_parse(&argp, argc, argv, 0, 0, &args);
// Passage en mode verbeux si demandé
setVerbose(args.verbose);
// Compression des fichiers en argument
char** files = args.files;
while (*files != NULL) {
char* input = *files;
// Compression du fichier xx en xx.huf
// TODO: rendre le nom du fichier de sortie configurable
char* output = malloc((strlen(input) + 5) * sizeof(*output));
strcpy(output, input);
strcat(output, ".huf");
switch (compress(input, output)) {
case COMPRESS_READ_ERROR:
fprintf(
stderr,
"Erreur : impossible de lire le fichier '%s' - %s\n",
input, strerror(errno)
);
return COMPRESS_READ_ERROR;
case COMPRESS_WRITE_ERROR:
fprintf(
stderr,
"Erreur : impossible d'écrire dans le fichier '%s' - %s\n",
output, strerror(errno)
);
return COMPRESS_WRITE_ERROR;
case COMPRESS_OPEN_INPUT_ERROR:
fprintf(
stderr,
"Erreur : impossible d'ouvrir le fichier '%s' - %s\n",
input, strerror(errno)
);
return COMPRESS_OPEN_INPUT_ERROR;
case COMPRESS_OPEN_OUTPUT_ERROR:
fprintf(
stderr,
"Erreur : impossible d'ouvrir le fichier '%s' - %s\n",
output, strerror(errno)
);
return COMPRESS_OPEN_OUTPUT_ERROR;
}
free(output);
files++;
// Ligne de séparation entre les différents fichiers
if (*files != NULL) {
printVerbose("\n");
}
}
return EXIT_SUCCESS;
}