Ici, il est intéressant d'examiner la différence entre Pascal et C.
Les noms de fonctions sont différents de ceux donnés dans le programme
Pascal pour les files de caractères, car nous avons copié
textuellement ce code directement du noyau du système Unix. C'est
l'occasion de constater comment la programmation en C permet certaines
acrobaties, peu recommandables car on aurait pu suivre la technique
d'adressage des caractères dans les blocs de Pascal. La structure des
files est légèrement différente car on adresse directement les
caractères dans un bloc au lieu du système base et déplacement de
Pascal. Le débordement de bloc est testé en regardant si on est sur un
multiple de la taille d'un bloc, car on suppose le tableau des blocs
aligné sur un multiple de cette taille. Le fichier interface
files-de-caracteres.h est
#define NCLIST 80 /* - */
#define CBSIZE 12 /* - */
#define CROUND 0xf /* -*/
/*
* -
* -
* -
* -
* -
* -
*/
struct clist
{
int c_cc; /* - */
char *c_cf; /* - */
char *c_cl; /* - */
};
struct cblock {
struct cblock *c_next;
char c_info[CBSIZE];
};
typedef struct clist *FCtype;
int FCput(char c, FCtype p);
int FCget(FCtype p);
void FCinit(void);
Dans la partie implémentation qui suit, on remarque l'emploi
de la directive static qui permet de cacher à l'édition de
liens des variables, procédures ou fonctions privées qui ne seront pas
considérées comme externes. Contrairement à Pascal, il est possible en
C de cacher la représentation des files, en ne déclarant le type
FCtype que comme un pointeur vers une structure clist
non définie. Les fonctions retournent un résultat entier qui permet
de retourner des valeurs erronées comme
. Le fichier
files-de-caracteres.c est
#include <stdlib.h>
#include <files-de-caracteres.h>
static struct cblock cfree[NCLIST];
static struct cblock *cfreelist;
int FCput(char c, FCtype p)
{
struct cblock *bp;
char *cp;
register s;
if ((cp = p->c_cl) == NULL || p->c_cc < 0 ) {
if ((bp = cfreelist) == NULL)
return(-1);
cfreelist = bp->c_next;
bp->c_next = NULL;
p->c_cf = cp = bp->c_info;
} else if (((int)cp & CROUND) == 0) {
bp = (struct cblock *)cp - 1;
if ((bp->c_next = cfreelist) == NULL)
return(-1);
bp = bp->c_next;
cfreelist = bp->c_next;
bp->c_next = NULL;
cp = bp->c_info;
}
*cp++ = c;
p->c_cc++;
p->c_cl = cp;
return(0);
}
int FCget(FCtype p)
{
struct cblock *bp;
int c, s;
if (p->c_cc <= 0) {
c = -1;
p->c_cc = 0;
p->c_cf = p->c_cl = NULL;
} else {
c = *p->c_cf++ & 0xff;
if (--p->c_cc<=0) {
bp = (struct cblock *)(p->c_cf-1);
bp = (struct cblock *) ((int)bp & ~CROUND);
p->c_cf = p->c_cl = NULL;
bp->c_next = cfreelist;
cfreelist = bp;
} else if (((int)p->c_cf & CROUND) == 0){
bp = (struct cblock *)(p->c_cf-1);
p->c_cf = bp->c_next->c_info;
bp->c_next = cfreelist;
cfreelist = bp;
}
}
return(c);
}
void FCinit()
{
int ccp;
struct cblock *cp;
ccp = (int)cfree;
ccp = (ccp+CROUND) & ~CROUND;
for(cp=(struct cblock *)ccp; cp <= &cfree[NCLIST-1]; cp++) {
cp->c_next = cfreelist;
cfreelist = cp;
}
}