/*     
      LIBUSER.H . Magma 1.0 . 1996 . Sylvain HUET

         definitions pour l'utilisateur de la machine SCOL
*/

/* DEFINITIONS DE TYPES ET DE CONSTANTES
  ---------------------------------------
*/
// Modification history:
//$ FA(06/06/2001): Add conditional definition of Mmachine struct
//$ FA(10/07/2001): Add conditional inclusion macros #ifndef _KERNEL_H_/#endif
//$ FA(03/08/2001): Add declaration of MMputs() function
//

#ifndef _KERNEL_H_
#define _KERNEL_H_

#define NIL -1

/* masque pour MMmalloc : tableau d'objets ou buffer quelconque */
#define TYPETAB 1
#define TYPEBUF 0

#ifndef SCOL_MMACHINE_DEFINED
struct Mmachine
{
  int *tape;     /* pointeur vers la bande       */
  int sizetape;  /* taille de la bande (en mots) */
  int pp;        /* pointeur de pile             */
  int maxpp;     /* valeur max de pp             */
  int topheap;   /* sommet du tas                */
  int sigGC;     /* distance declenchant le GC   */
  int h;         /* position header courant      */
  int err;
  int *top;		/* top of tape */
  //$BLG - v5.22: Add
  int lckdGC;			// Locked GC flag
};
typedef struct Mmachine *mmachine;
#define SCOL_MMACHINE_DEFINED
#endif

extern struct Mmachine mscol;

/* definitions des erreurs */
#define MERREND     1
#define MERROK      0
#define MERRMEM    -1
//#define MERRTYP    -2
#define MERRTYP    (merrlog(__LINE__,__FILE__,-2))
#define MERRRET    -3
#define MERRNUL    -4
#define MERRNF     -5
#define MERRLINK   -6
#define MERRFULL   -7
#define MERRUNKNOWN -8
#define MERRTOOLARGE -9
//$BLG - v5.22: Add (Already existing but missing in this file)
#define MERREP        -10
#define MERRFILE      -11
#define MERRCLOSE     -12
//$BLG - v5.22: Add
#define MERRCHNLDWN   -13

/* definition des offsets objets */
#define OFFOBJMAG   0
#define OFFOBJCHN   1
#define OFFOBJTYP   2
#define OFFOBJHAND  3
#define OFFOBJTPERE 4
#define OFFOBJHPERE 5
#define OFFOBJREF0  6
#define OFFOBJUSER0 7


/* GESTION DE LA BANDE MEMOIRE SCOL
  ----------------------------------
*/

/*
   Empilement d'un nouvel objet
        retourne -1 si erreur, 0 si succes.
*/
int MMpush(mmachine m, int val);

/*
   Empilement d'un nouvel objet sans GC : a utiliser avec precaution
        retourne 0
*/
int MMpushNoGC(mmachine m, int val);

/*
   Depile un objet
*/
int MMpull(mmachine m);

/* Lit la valeur du pointeur de pile */
int MMgetPP(mmachine m);

/* Ecrit la valeur du pointeur de pile */
void MMsetPP(mmachine m,int i);

/*
   Lit un etage de la pile, sans le depiler
*/
int MMget(mmachine m,int i);

/*
   Ecrit un etage de la pile, sans le depiler
*/
void MMset(mmachine m,int i,int v);

/*
   Lit une variable globale
*/
int MMgetglobal(mmachine m,int i);

/*
   Ecrit une variable globale
*/
void MMsetglobal(mmachine m,int i,int v);

/*
   Lit un champ de la pile, a partir d'une base donee
*/
int MMgetbase(mmachine m,int b,int i);

/*
   Ecrit un champ de la pile, a partir d'une base donnee
*/
void MMsetbase(mmachine m,int b,int i,int v);

/*
   Lit un champ d'un bloc TAB
*/
int MMfetch(mmachine m,int s,int i);

/*
   Ecrit un champ d'un bloc TAB
*/
void MMstore(mmachine m,int s,int i,int v);

/*
   Recupere un pointeur vers le debut d'un bloc BUF
*/
int* MMstart(mmachine m,int s);

/*
   Donne la taille en "int" d'un bloc BUF ou TAB
*/
int MMsize(mmachine m,int s);

/*
   Donne le type d'un bloc BUF ou TAB -> TYPEBUF ou TYPETAB
*/
int MMtype(mmachine m,int s);

/*
   Recupere un pointeur vers le debut d'une chaine de caracteres
*/
char* MMstartstr(mmachine m,int s);

/*
   Recupere la taille d'une chaine de caracteres
*/
int MMsizestr(mmachine m,int s);

/*
   Regle la taille d'une chaine de caracteres
*/
void MMsetsizestr(mmachine m,int s,int size);

/*
   Fonctions de transfert Objet <-> Int ou Pointer
*/
int ITOO(int i);
int PTOO(int p);
int OTOI(int i);
int OTOP(int p);

/*
   Alloue un bloc dans le tas : la taille est donnee en mots
    le bloc est initialise selon type
    retourne -1 si echec, sinon retourne le pointeur
*/
int MMmalloc(mmachine m, int size, int type);

/*
   Idem Malloc, avec mise a zero du bloc
    retourne -1 si echec, sinon retourne le pointeur
*/
int MMmallocCLR(mmachine m, int size, int type);

/* empilement d'une chaine sous forme de bloc (la chaine ne doit pas etre dans la bande memoire scol */
int Mpushstrbloc(mmachine m,char *buf);

/* empilement d'une chaine sous forme de bloc */
int Mpushstrblocn(mmachine m,char *buf,int l);

/* BYTECODE : creation d'un bloc de type TAB en recuperant la taille et les elements dans la pile
 niv 2 : objet A
 niv 1 : objet B
 niv 0 : entier 2
 -> depile les trois arguments et empile le tuple [A B]
*/
int MBdeftab(mmachine m);

/* BYTECODE : concatenation de deux chaines de caracteres en memoire scol
 niv 1 : chaine "xyz"
 niv 0 : chaine "abc"
 -> depile les deux arguments et empile la chaine "xyzabc"
*/
int MBstrcat(mmachine m);
int MBstrcatn(mmachine m);

/* INITIALISATION DE LA MACHINE SCOL
  ------------------------------------
*/

#define TYPVAR    -1
#define TYPCONS   -2
#define TYPTYPE   -3
#define TYPFIELD  -4
#define TYPSTRUC  -5
#define TYPCONS0  -6
#define TYPCOM    -7
#define TYPCOMV   -8

/* lecture d'un package en dur
  en 0: liste des packages deja charges
 retourne en 0: nouvelle liste
*/ 
int PKhardpak(mmachine m, char *name,
              int n, char **namefun, int (**fun)(mmachine z)
              , int *nargfun, char **typfun);

/* lecture et linkage d'un package en Magma
  en 0: liste des packages deja charges
 retourne en 0: nouvelle liste
*/ 
int PKloader(mmachine m,char *name,char *simplename);

/* taille de la bande memoire reservee par la machine SCOL
 (donnee en nombre de mots de 4 octets : 16384 -> 64Ko)
*/
extern int ScolMemoryLength;



/* GESTION DES FICHIERS EN SCOL
  ------------------------------
*/
#define SIZESIGN 1024

struct Packdir
{
  char path[SIZESIGN];  /* se termine par '/' */
  int quota;   /* -1: read only, 0: unlimited */
  struct Packdir *next;
};
typedef struct Packdir *packdir;

#define TYPESNONE  0
#define TYPESLOGIC 1

extern packdir Firstpack;

/* trouve un package dans la liste des packdir */
int SPfindfile(packdir p,char *sign,int *size,char *path);

/* ajout d'un fichier : trouve le chemin complet a partir du nom complet et 
  de la taille */
int SPaddfile(packdir p,char *sign,int size,char *path);


/* ACCES AUX NUMEROS DE SOCKET
  ------------------------------
*/

/* lecture du numero de socket associe a un serveur
   (server est un pointeur vers le serveur, avec bit 0 a 1) */
int SCgetsrvsocket(mmachine m, int server);

/* lecture du numero de socket associe a un canal
   (channel est un pointeur vers le canal, avec bit 0 a 1) */
int SCgetsocket(mmachine m, int channel);


/* FONCTIONS UTILES
  ------------------------------
*/

/* decoupage d'une chaine en mots (retourne le nombre de mots) */  
int Mcutting(char *comm, char **argv);


/* DEBUGGAGE
  -----------
*/

/* affichage d'un message dans le log, l'entier est un masque d'affichage, (0 pour non masquable) */
void MMechostr(int i,char *buf,...);
//$ FA(03/08/2001): Echo a string (length is unrestricted)
void MMputs(int i, const char* text);
//
/* definitions des masques de message console */
#define MSKFOO     1
#define MSKRUNTIME 2
#define MSKWARNING 4
#define MSKTRACE   8
#define MSKDEBUG   16



void* SCgetExtra(char *funcname);

/* enregistrement d'un nouveau type d'objet */
int OBJregister(int nbrefl,int recrefl,
				int (*destroy)(mmachine m,int handsys,int objm),char *name);

/* determine un numero de type en fonction du nom */
int OBJtypebyname(char *name);


/* obtention d'un nouvel evenement utilisateur */
int OBJgetUserEvent();

/* trouve un objet en fonction du handler systeme (notation int) et du typ (notation int)
 retourne le pointeur ou -1 si introuvable */
int OBJfindTH(mmachine m,int typ,int handsys);

/* trouve un objet en fonction de l'objet magma (notation obj) et du typ (notation int)
 retourne le pointeur ou -1 si introuvable */
int OBJfindTM(mmachine m,int typ,int objm);

/* creation d'un nouvel objet
en 1 : canal
en 0 : objet magma
retourne : 
en 0 : objet inchange
*/
int OBJcreate(mmachine m,int typ,int handsys,int typpere,int handsyspere);

/* definition d'un reflexe
en 2 : objet magma
en 1 : fonction magma
en 0 : argument user
retourne :
en 0 : objet
*/
int OBJaddreflex(mmachine m,int typ, int num);

/* commence le traitement d'un reflexe d'un certain type, avec un certain handler
et un certain numero de reflexe.
retourne :
 0 si OK
 1 si objet non trouve
 autre si erreur RUNTIME
 */
int OBJbeginreflex(mmachine m,int typ,int handsys,int num);

/* appel du reflexe
  nbarg est le nombre d'arguments ajoutes par l'utilisateur */
int OBJcallreflex(mmachine m,int nbarg);

/* destruction d'un objet en fonction de son type et du handler systeme */
int OBJdelTH(mmachine m,int typ,int handsys);

/* destruction d'un objet en fonction de son type et de l'objet magma */
int OBJdelTM(mmachine m,int typ,int q);

/* destruction de tous les objets lies a un canal (notation obj) */
int OBJdelChn(mmachine m,int canal);

/* donne a un canal tous les objets d'un autre */
int OBJchgchannel(mmachine m,int oldchn, int newchn);

/* destruction d'un objet */
int OBJdel(mmachine m,int p,int flag);

int OBJdestroy(mmachine m, int typ,int handsys,int objm,int flag);

/* compte le nombre d'objets d'un certain type */
int OBJcountT(mmachine m,int typ);
/* initialisation de la gestion des objets */
int OBJinit();

#endif // kernel.h