#ifndef JTOOLS_H
#define JTOOLS_H

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stddef.h>
#include <string.h>


/* CLASSE */
#define CLASSE(c_ident) typedef struct c_ident *c_ident

/* ERREURS */
extern char *err_malloc;
extern char *err_calloc;
extern char *err_realloc;


/* EXIT_IF */
#define EXIT_IF(expression, message) \
  exit_if(__FILE__, __LINE__, expression, #expression, message)

#define PERROR_AND_EXIT() \
  perror_and_exit(__FILE__ ":" PERROR__STRING(__LINE__) ":")
#define PERROR__STRING(n) PERROR___STRING(n)
#define PERROR___STRING(n) #n

extern void exit_if(char *fichier, int ligne, int condition,
                    char *code, char *message);
extern char *exit_message;
extern void perror_and_exit(char *localisation);


/* INSTANCIER */
#define INSTANCIER(c_ident)   \
  c_ident recv = malloc(sizeof(struct c_ident));\
  EXIT_IF(recv==NULL, "erreur instanciation: " #c_ident)


/* PIL_H */
typedef struct pil *pil;
extern pil pil_new(size_t);
                  // instancier une pile d'objets de taille donnée
extern void pil_free(pil);
                  // libérer mémoire
extern void pil_emp(pil, void*);
                 // empiler
extern void pil_dep(pil, void*);
                 // dépiler
extern void pil_top(pil recv, void* valeur);
                 // valeur du sommet
extern int pil_pro(pil recv);
                 // retourne la profondeur de la pile
extern void pil_vrb(pil recv, int mode);


/* VEC_H */
CLASSE(vec);

extern vec vec_new(size_t);            // constructeur
extern void vec_free(vec);             // destructeur
extern void vec_mt(vec recv);          // raz
extern void vec_aff(vec, int, void*);  // affectation
extern void vec_elm(vec, int, void*);  // extraction
extern int vec_nbr(vec);               // nombre d'éléments
extern void vec_vrb(vec, int);         // alloc. prolyxe


/* SET_H */
CLASSE(set);

typedef unsigned short card;
typedef char bool;

extern set set_new(card);             // construct set de card p1+1
extern void set_free(set);            // destruct. de p1
extern void set_mt(set);              // vide l'ensemble !
extern void set_add(set, card);       // ajoute element p2 dans l'ensemble p1
extern void set_union(set, set, set); // p3 = union de p1 et p2
extern void set_inter(set, set, set); // p3 = intersection de p1 et p2
extern bool set_egal(set, set);       //
extern bool set_incl(set, set);       // p2 inclu dans p1
extern bool set_app(set, card);       // p2 appartient à p1
extern void set_dump(set recv);       //
extern void set_print(char *,set);    //
extern void set_2vec(set, vec);       // -> vect. des éléments du set

/* ARG... */
#define GETARG(nom) \
        getarg(argc,argv,nom)
#define ARGSTR(nom, def) \
        argstr(argc,argv,nom,def)
#define ARGINT(nom, def) \
        argint(argc,argv,nom,def)
#define ARGFLT(nom, def) \
        argflt(argc,argv,nom,def)
extern char
  *getarg(int Argc, char **Argv, char *nom);
extern char
  *argstr(int argc, char **argv, char *nom, char *def);
extern int
  argint(int argc, char **argv, char *nom, int def);
extern float
  argflt(int argc, char **argv, char *nom, float def);
extern void
  avant(char *dst, char *src, char sep);
extern void
  apres(char *dst, char *src, char sep);
extern void
  before(char *dst, char *src, char *sep);
extern void
  after(char *dst, char *src, char *sep);
extern int
  scan(char *mot, char **src);

#define STRSIZE 255
extern int
  ReadLn (FILE* fd, char *s);

#endif /* JTOOLS_H */

