surfaces-unies/src/main.c

151 lines
5.1 KiB
C
Raw Normal View History

2018-11-06 23:45:25 +00:00
/**
* \file main.c
* \brief Fichier principal du programme
*
* Ce fichier contient les fonctions principales du logiciel qui ne sont pas
* directement liées à la logique et au traitement des données du logiciel,
* mais plutôt au traitement des arguments passés au processus et au lancement
* des fonctions cœures du programme.
*/
#include "compress.h"
#include "uncompress.h"
2018-10-31 10:40:47 +00:00
#include <getopt.h>
#include <string.h>
2018-10-19 18:03:06 +00:00
/**
* \brief Affiche un message d'aide
*
* Affiche un message d'aide pour le logiciel ainsi que son utilisation, puis
* termine le processus avec le code de sortie indiqué par l'argument de la
* fonction.
*
* \param[in] t_exit_code Code de sortie du processus
*/
void help(int t_exit_code) {
2018-11-24 21:51:25 +00:00
puts("Usage:\n"
"surfaces-unies -i path [-o path] [--options] [-t 0-100]\n\n"
2018-11-24 21:51:25 +00:00
"The default action is to compress the mandatory input image to a .su\n"
"file saved in the current directory.\n"
"The input image MUST be saved in the ppm format.\n"
"Options available:\n"
"-h --help\n\tDisplay the current message\n"
"-i --input\n\tPath to the input file (MANDATORY)\n"
2018-11-24 21:51:25 +00:00
"-o --output\n"
"\tPath to the output file (if the file already exists, it will be\n"
2018-11-24 21:51:25 +00:00
"\toverwritten)\n"
"-t --tolerance\n"
"\tColor tolerance for lossy compression. By default at 0 for lossless\n"
"\tcompression, at 100 will consider every color to be the same.\n"
"-c --compress\n\tCompress the input file\n"
"-u --uncompress\n\tUncompresses the input file to the output file.");
exit(t_exit_code);
2018-10-31 10:40:47 +00:00
}
/**
* \struct Argres
* \brief Résultats du traitement des arguments du processus
*
* Cette structure est utilisée pour consolider ensemble les résultats du
* traitement des arguments et les renvoyer en une fois au lieu d'avoir à
* utiliser des variables globales ou des pointeurs en arguments
* supplémentaires aux fonctions.
*/
2018-10-31 10:40:47 +00:00
struct Argres {
char *input; /*!< Nom du fichier d'entrée */
char *output; /*!< Nom du fichier de sortie */
char compress; /*!< Le fichier d'entrée doit-il être compressé ? */
int32_t tolerance; /*!< Tolérance en pourcentage des différences de couleur */
2018-10-31 10:40:47 +00:00
};
typedef struct Argres Argres;
/**
* \brief Processes independently the arguments of the process
*
* Each option and switch will be processed here and will modify appropriately
* the parameter `args`
*
* \param[out] t_args Result of the arguments processing
* \param[in] t_c Switch or option passed
*/
2018-11-24 20:58:55 +00:00
void get_args(Argres *t_args, const int *const t_c) {
switch (*t_c) {
2018-10-31 10:40:47 +00:00
case 0: break;
case 'h': help(NOERROR); break;
case 'i': (*t_args).input = optarg; break;
case 'o': (*t_args).output = optarg; break;
case 'c': (*t_args).compress = 1; break;
case 'u': (*t_args).compress = 0; break;
case 't':
(*t_args).tolerance = atoi(optarg);
if(t_args->tolerance < 0 || t_args->tolerance > 100) {
help(ARGERROR);
}
break;
2018-10-31 10:40:47 +00:00
case '?':
default: help(ARGERROR);
}
}
/**
* \brief Traite les arguments passés au processus
*
* Les arguments passés au processus seront traités ici. Les arguments passés
* dans cette fonction ne subiront aucune modification. La fonction renvoie une
* structure \ref Argres contenant le nom de fichier dentrée et de sortie
* ainsi quun booléen indiquant si le fichier dentrée doit être compressé ou
* décompressé.
*
* \param[in] t_argc Nombre darguments reçus
* \param[in] t_argv Arguments reçus par le processus
* \return structure \ref Argres
*/
Argres process_args(const int t_argc, char *t_argv[]) {
2018-10-31 10:40:47 +00:00
Argres res;
res.input = NULL;
res.compress = 1;
res.output = NULL;
res.tolerance = 0;
while (1) {
2018-10-31 10:40:47 +00:00
int option_index = 0;
static struct option long_options[] = {
2018-11-24 20:58:55 +00:00
{"help", no_argument, NULL, 'h'},
{"input", required_argument, NULL, 'i'},
{"output", required_argument, NULL, 'o'},
{"tolerance", required_argument, NULL, 't'},
2018-11-24 20:58:55 +00:00
{"compress", no_argument, NULL, 'c'},
{"uncompress", no_argument, NULL, 'u'},
{NULL, 0, NULL, 0}};
int c = getopt_long(t_argc, t_argv, "hi:o:t:cu", long_options, &option_index);
2018-11-24 20:58:55 +00:00
if (c == -1)
break;
2018-10-31 10:40:47 +00:00
get_args(&res, &c);
}
return res;
}
/**
* \brief Fonction `main` lancée avec le processus
*
* This function is launched with the process. It will analyze the arguments it
* received, and depending on them will either compress or uncompress the input
* file, or will throw an error and stop in case of incorrect arguments.
*
* \param[in] argc Nombre darguments reçus par le processus
* \param[in] argv Tableau des arguments reçus par le processus
* \return Code de status du processus
*/
2018-10-31 10:40:47 +00:00
int main(int argc, char **argv) {
Argres argresults = process_args(argc, argv);
if (NULL == argresults.input) {
2018-10-31 10:40:47 +00:00
fprintf(stderr, "ERROR: no input file.");
help(ARGERROR);
}
if (argresults.compress) {
compress(argresults.input, argresults.output, argresults.tolerance);
} else {
uncompress(argresults.input, argresults.output);
}
2018-10-31 08:56:44 +00:00
return 0;
2018-10-19 18:03:06 +00:00
}