#include "common.h" #include "display.h" #include "compress.h" #include #include #include #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. Si omis, // utilisation de l'entrée standard args->source = fopen(arg, "r"); 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, "w"); if (args->dest == NULL) { argp_error( state, "%s: %s", arg, strerror(errno) ); } break; default: argp_error( state, "Trop d'arguments - L'argument %s est superflu", arg ); } 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 v0.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 */ static struct argp_option options[] = { { .name = "decompress", .key = 'd', .doc = "Décompresse SOURCE vers DEST" }, { .name = "verbose", .key = 'v', .doc = "Affiche des informations de débogage" }, {0} }; static struct argp argp = { .options = options, .parser = parse_opt, .args_doc = "[SOURCE [DEST]]", .doc = "Compresse ou décompresse SOURCE vers DEST en utilisant " "l'algorithme de Huffman (par défaut, compresse SOURCE vers DEST)." }; int main(int argc, char** argv) { // Paramètres de langue. Utilisation de la locale de l'utilisateur, // et des messages traduits dans libc (pour pallier à un bug de argp) setlocale(LC_ALL, ""); textdomain("libc"); // Valeurs par défaut des arguments optionnels Args args = { .verbose = FALSE, .compress = TRUE, .source = stdin, .dest = stdout }; // Interprétation des arguments passés au programme, résultat // dans `args`. Arrêt en cas d'erreur if (argp_parse(&argp, argc, argv, 0, 0, &args)) { return EXIT_FAILURE; } // Passage en mode verbeux si demandé setVerbose(args.verbose); // Compression ou décompression du flux d'entrée vers le flux de sortie if (args.compress) { compress(args.source, args.dest); } else { fprintf(stderr, "Décompression non-implémentée.\n"); return EXIT_FAILURE; } // Fermeture des flux et sortie fclose(args.source); fclose(args.dest); return EXIT_SUCCESS; }