#include #include #include #include "combinatoire.h" typedef unsigned long (*fun) (unsigned int,...); struct fonction { char *nom; int arite; fun f; }; struct fonction les_fonctions[] = { {"factorielle", 1, (fun) cmb_factorielle}, {"combinaison", 2, (fun) cmb_combinaison}, {"arrangement", 2, (fun) cmb_arrangement}, {"catalan", 1, (fun) cmb_catalan} }; static jmp_buf traitant_debordement; static jmp_buf traitant_parametre; static jmp_buf traitant_fun_inconnue; void usage (char *commande, char *msg, char *nomfonction); void cherche_fonction (struct fonction **f, char *nom_fonction, int arite); int main (int argc, char *argv[]) { struct fonction *volatile f; /* traitement des exceptions (obligatoirement dans le main) */ cmb_associer_exception (debordement, &traitant_debordement); cmb_associer_exception (parametre_invalide, &traitant_parametre); if (argc < 2) usage (argv[0], "nombre d'arguments insuffisant", ""); if (setjmp (traitant_fun_inconnue)) usage (argv[0], argv[1], " est une fonction inconnue "); if (setjmp (traitant_debordement)) usage (argv[0], "débordement de capacité dans ", f->nom); if (setjmp (traitant_parametre)) usage (argv[0], "paramètres invalides", f->nom); cherche_fonction ((struct fonction **) &f, argv[1], argc - 2); printf ("%ld", (argc == 3) ? f->f (strtoul (argv[2], NULL, 10)) : f->f (strtoul (argv[2], NULL, 10), strtoul (argv[3], NULL, 10))); return EXIT_SUCCESS; } void usage (char *commande, char *msg, char *nomfonction) { int i; printf ("\n %s : %s %s \n\n", commande, msg, nomfonction); printf ("usage %s opération argument(s) \n" "opérations disponibles :\n", commande); for (i = 0; i < sizeof (les_fonctions) / sizeof (struct fonction); i++) printf ("\t%s \t arité : %d\n", les_fonctions[i].nom, les_fonctions[i].arite); exit (EXIT_FAILURE); } void cherche_fonction (struct fonction **f, char *nom_fonction, int arite) { int i; for (i = 0; i < sizeof (les_fonctions) / sizeof (struct fonction); i++) if (!strcmp (les_fonctions[i].nom, nom_fonction)) { *f = &les_fonctions[i]; if (arite == (*f)->arite) return; longjmp (traitant_parametre, 1); } longjmp (traitant_fun_inconnue, 1); }