#ifndef LINK_H
#define LINK_H

#include "../Version.h"
#define DEPMOD_RELEASE		MODULES_VERSION
#define ETC_CONF_MODULES	"/etc/conf.modules"
#define SHELL_WILD "\"\'\140$*?[]{}|\\"

#ifndef STDIO_H
	#include <stdio.h>
#endif

#define EXEC_PRE_INSTALL 0
#define EXEC_POST_INSTALL 1
#define EXEC_PRE_REMOVE 2
#define EXEC_POST_REMOVE 3
#define EXEC_INSTALL 4
#define EXEC_REMOVE 5

class MODULE;
struct SYMBOL{
	SYMBOL *next;	// Liste li‚ pour hashing
	MODULE *module;	// Module qui d‚clare ce symbole
	char *name;
	char requis;		// Requis par d'autre module
	char defini;		// La d‚finition a ‚t‚ vue
	char vue_avant;		// D‚finie avant d'etre vue
	char force;			// Chargement doit ˆtre forc‚ pour ‚viter
						// un link multi passe.
	char is_common;		// ???
	char is_dup;		// Ce symbole a d‚j… ‚t‚ charg‚ d'un autre module
};

enum SYM_STATUS {
	SYM_PASUTIL,	// Requis par un module qui n'est pas requis lui meme.
	SYM_DEFINI,		// On a trouve un module qui le connait
	SYM_REQUIS		// Requis par un autre module
};

struct LIST_SYMBOL{
	LIST_SYMBOL *next;
	SYMBOL alloc[1];
	// Structure alloue plus longue
};

struct LIST_TEXTE {
	LIST_TEXTE *next;
	char alloc[1];
	// Structure alloue plus longue
};
	
class MODULES;
class SYMBOLS{
	SYMBOL *hash[2048];
	struct {
		LIST_SYMBOL *cur;
		int nb;
		SYMBOL *ptacc;
		SYMBOL *lastacc;
	} sym;
	/*~PROTOBEG~ SYMBOLS */
public:
	SYMBOLS (void);
	SYMBOL *add (const char *name,
		 MODULE *module,
		 SYM_STATUS status,
		 int &module_requis,
		 int is_common);
protected:
	void allocsym (void);
public:
	void dump (FILE *fout);
	int findforce (char **tb, int maxtb);
	/*~PROTOEND~ SYMBOLS */
};

struct MODULE{
	char *name;
	struct {		// Symbole publique et externe de ce module
		SYMBOL **tb;
		int nb;
	} pub,ext;
	char is_load;	// Ce module doit ˆtre inclus dans le programme
	short lib;		// Num‚ro de la librairie de provenance
};

class MODULES{
	MODULE *tbmod;
	int nbmod;
	char **tblibs;
	int nblib;
	/*~PROTOBEG~ MODULES */
public:
	MODULES (void);
	int findundef (FILE *fout);
	int loadobj (SYMBOLS&syms, const char *objname);
	void prtdepend (FILE *fout,
		 const char *dontcare,
		 int verbose,
		 int showerror);
	MODULE *setdummy (const char *name);
private:
	void setmod (MODULE *mod,
		 SYMBOL *tbpub[],
		 int nbpub,
		 SYMBOL *tbext[],
		 int nbext,
		 int module_requis);
public:
	void showall (FILE *fout);
	int showload (FILE *fout);
	void showundef (SYMBOL *undef, FILE *fout);
	/*~PROTOEND~ MODULES */
};

extern int debugmode;
extern char *optlist[];
extern char depmod_syslog;
extern char *insmod_opt;

#include "link.p"

#endif

