encore

Répétitions espacées dans le terminal
git clone git://git.asteride.xyz/~ldp/encore.git
Journaux | Fichiers | Références

paquet.c (13863B)


      1 #include <assert.h>
      2 #include <fcntl.h>
      3 #include <stdint.h>
      4 #include <sys/stat.h>
      5 #include <time.h>
      6 #include <unistd.h>
      7 
      8 #include <stdio.h>
      9 #include <stdlib.h>
     10 
     11 #include "paquet.h"
     12 #include "sm2.h"
     13 
     14 #define PQ_VERSION         0
     15 
     16 #define PQ_ENTETE_LG       32
     17 #define PQ_FICHE_LG        12
     18 
     19 #define DEC_ENTETE_VERSION 0
     20 #define DEC_ENTETE_DRAPS   1
     21 #define DEC_ENTETE_DEB_S   2
     22 #define DEC_ENTETE_DEB_N   5
     23 #define DEC_ENTETE_NB      8
     24 #define DEC_ENTETE_PINS    11
     25 #define DEC_ENTETE_PIPI    12
     26 #define DEC_ENTETE_PNPI    14
     27 #define DEC_ENTETE_FI      16
     28 #define DEC_ENTETE_DATE    17
     29 #define DEC_ENTETE_NFS     24
     30 
     31 #define DEC_FICHE_PRCH     0
     32 #define DEC_FICHE_DERN     3
     33 #define DEC_FICHE_ID       6
     34 #define DEC_FICHE_FAC      9
     35 #define DEC_FICHE_NSUCC    10
     36 
     37 #define PQ_PINS_DEF        3
     38 #define PQ_PIPI_DEF        1
     39 #define PQ_PNPI_DEF        377
     40 #define PQ_FI_DEF          120
     41 #define PQ_NFS_DEF         20
     42 
     43 #define TAMPON_TLL    (4096 - (4096 % PQ_FICHE_LG))
     44 #define TAMPON_FICHES (TAMPON_TLL / PQ_FICHE_LG)
     45 
     46 #define LIRE_1(tp) \
     47 		(((uint8_t) *(tp)))
     48 #define LIRE_2(tp) \
     49 		(((uint16_t) *(tp) << 8) \
     50 			+ ((uint16_t) *((tp) + 1)))
     51 #define LIRE_3(tp) \
     52 		(((uint32_t) *(tp) << 16) \
     53 			+ ((uint32_t) *((tp) + 1) << 8) \
     54 			+ ((uint32_t) *((tp) + 2)))
     55 #define LIRE_7(tp) \
     56 		(((uint64_t) *(tp) << 48) \
     57 			+ ((uint64_t) *((tp) + 1) << 40) \
     58 			+ ((uint64_t) *((tp) + 2) << 32) \
     59 			+ ((uint64_t) *((tp) + 3) << 24) \
     60 			+ ((uint64_t) *((tp) + 4) << 16) \
     61 			+ ((uint64_t) *((tp) + 5) << 8) \
     62 			+ ((uint64_t) *((tp) + 6)))
     63 
     64 #define PARENT(pos)  ((pos) / 2)
     65 #define ENFANT1(pos) ((pos) * 2 + 1)
     66 #define ENFANT2(pos) ((pos) * 2 + 2)
     67 
     68 static int pq_fiche_copier(struct paquet *, uint32_t, uint8_t *);
     69 static int pq_fiche_coller(struct paquet *, uint32_t, uint8_t *);
     70 static int pq_fiches_echanger(struct paquet *, uint32_t, uint32_t);
     71 static int pq_fiche_monter(struct paquet *, uint32_t, uint8_t *);
     72 static int pq_fiche_descendre(struct paquet *, uint32_t, uint8_t *);
     73 
     74 extern char *nom_prog;
     75 
     76 /* Créer la base de données au chemin et écrire les valeurs par défaut.
     77  * Ne créer la base de données que s'il n'y a pas de paquet à chemin */
     78 int
     79 pq_init(char *chemin)
     80 {
     81 	struct paquet pq;
     82 
     83 	assert(chemin != NULL);
     84 	assert(PQ_ENTETE_LG + 1 < (1 << 8));
     85 
     86 	if ((pq.fd = open(chemin, O_WRONLY | O_CREAT | O_EXCL,
     87 			S_IRUSR | S_IWUSR)) < 0) {
     88 		perror(chemin);
     89 		return -1;
     90 	}
     91 
     92 	pq.nom            = chemin;
     93 	pq.entete.version = 0;
     94 	pq.entete.draps   = 0;
     95 	pq.entete.deb_s   = 0;
     96 	pq.entete.deb_n   = 0;
     97 	pq.entete.nb      = 0;
     98 	pq.entete.pins    = PQ_PINS_DEF;
     99 	pq.entete.pipi    = PQ_PIPI_DEF;
    100 	pq.entete.pnpi    = PQ_PNPI_DEF;
    101 	pq.entete.fi      = PQ_FI_DEF;
    102 	pq.entete.date    = (uint64_t) time(NULL) >> 8;
    103 	pq.entete.nfs     = PQ_NFS_DEF;
    104 
    105 	if (pq_entete_maj(&pq) < 0)
    106 		return -1;
    107 
    108 	if (close(pq.fd) < 0) {
    109 		perror(chemin);
    110 		return -1;
    111 	}
    112 
    113 	return 0;
    114 }
    115 
    116 /* ouvrir le paquet pointé par chemin, en lire l'entête et remplir un struct
    117  * paquet */
    118 int
    119 pq_ouvrir(char *chemin, struct paquet *pq)
    120 {
    121 	uint8_t tp[PQ_ENTETE_LG];
    122 
    123 	assert(chemin != NULL);
    124 	assert(pq != NULL);
    125 
    126 	if ((pq->fd = open(chemin, O_RDWR)) < 0) {
    127 		perror(chemin);
    128 		return -1;
    129 	}
    130 
    131 	if (read(pq->fd, tp, PQ_ENTETE_LG) != PQ_ENTETE_LG) {
    132 		fprintf(stderr, "%s: paquet corrompu\n", chemin);
    133 		return -1;
    134 	}
    135 
    136 	pq->nom = chemin;
    137 
    138 	if ((pq->entete.version = LIRE_1(tp + DEC_ENTETE_VERSION)) != 0) {
    139 		fprintf(stderr, "%d: version incompatible\n",
    140 			pq->entete.version);
    141 		return -1;
    142 	}
    143 
    144 	pq->entete.draps = LIRE_1(tp + DEC_ENTETE_DRAPS);
    145 	pq->entete.deb_s = LIRE_3(tp + DEC_ENTETE_DEB_S);
    146 	pq->entete.deb_n = LIRE_3(tp + DEC_ENTETE_DEB_N);
    147 	pq->entete.nb    = LIRE_3(tp + DEC_ENTETE_NB);
    148 	pq->entete.pins  = LIRE_1(tp + DEC_ENTETE_PINS);
    149 	pq->entete.pipi  = LIRE_2(tp + DEC_ENTETE_PIPI);
    150 	pq->entete.pnpi  = LIRE_2(tp + DEC_ENTETE_PNPI);
    151 	pq->entete.fi    = LIRE_1(tp + DEC_ENTETE_FI);
    152 	pq->entete.date  = LIRE_7(tp + DEC_ENTETE_DATE);
    153 	pq->entete.nfs   = LIRE_2(tp + DEC_ENTETE_NFS);
    154 
    155 	return 0;
    156 }
    157 
    158 /* ajouter n entrées à la base de données
    159  * les entrées sont ajoutées dans la section « nouveaux » */
    160 int
    161 pq_ajouter(struct paquet *pq, unsigned int n)
    162 {
    163 	uint32_t id;
    164 	uint8_t  tp[TAMPON_TLL] = { 0 };
    165 	uint8_t *ptr;
    166 	int      min;
    167 	int      reste;
    168 
    169 	assert(pq != NULL);
    170 
    171 	id = pq->entete.nb ;
    172 
    173 	if (lseek(pq->fd, PQ_ENTETE_LG + id * PQ_FICHE_LG, SEEK_SET) < 0) {
    174 		perror(pq->nom);
    175 		return -1;
    176 	}
    177 
    178 	while (n != 0) {
    179 		assert(n > 0);
    180 		reste = min = n < TAMPON_FICHES ? n : TAMPON_FICHES;
    181 		for (ptr = tp; reste > 0; reste--, ptr += PQ_FICHE_LG) {
    182 			ptr[6] = (uint8_t) (id >> 16);
    183 			ptr[7] = (uint8_t) (id >> 8);
    184 			ptr[8] = (uint8_t) (id);
    185 			ptr[9] = (uint8_t) (pq->entete.fi);
    186 			id++;
    187 		}
    188 		reste = min * PQ_FICHE_LG;
    189 		if (write(pq->fd, tp, reste) != reste) {
    190 			perror(pq->nom);
    191 			return -1;
    192 		}
    193 		pq->entete.nb += min;
    194 		n -= min;
    195 	}
    196 
    197 	if (pq_entete_maj(pq) < 0)
    198 		return -1;
    199 
    200 	return 0;
    201 }
    202 
    203 /* retourner l'identifiant de la prochaine fiche à réviser */
    204 int
    205 pq_prochain(struct paquet *pq, int opts)
    206 {
    207 	uint8_t  fiche[PQ_FICHE_LG];
    208 	uint32_t indice;
    209 
    210 	assert(pq != NULL);
    211 
    212 	if (pq->entete.draps & PQ_DRAP_QST) {
    213 		if (pq->entete.draps & PQ_DRAP_MNC)
    214 			indice = 0;
    215 		else
    216 			indice = pq->entete.deb_n;
    217 	} else {
    218 		if (pq->entete.nb - pq->entete.deb_n > 0
    219 				&& (pq->entete.nfs > 0
    220 					|| !(pq->entete.draps & PQ_DRAP_NOUV)
    221 					|| opts & PQ_OPT_PRCH_NOUV)
    222 				&& !(opts & PQ_OPT_PRCH_VIEU)) {
    223 			pq->entete.draps &= ~PQ_DRAP_MNC;
    224 			if (pq->entete.draps & PQ_DRAP_ALEA) {
    225 				srand(time(NULL));
    226 				indice = rand()
    227 					% (pq->entete.nb - pq->entete.deb_n)
    228 					+ pq->entete.deb_n;
    229 				if (pq_fiches_echanger(pq, indice, pq->entete.deb_n) < 0)
    230 					return -1;
    231 			}
    232 			indice = pq->entete.deb_n;
    233 		} else if (pq->entete.deb_s > 0) {
    234 			pq->entete.draps |= PQ_DRAP_MNC;
    235 			indice = 0;
    236 		} else {
    237 			fprintf(stderr,
    238 				"%s: le paquet %s ne contient aucune fiche\n",
    239 				nom_prog, pq->nom);
    240 			return -1;
    241 		}
    242 	}
    243 
    244 	if (pq_fiche_copier(pq, indice, fiche) < 0)
    245 		return -1;
    246 
    247 	indice = LIRE_3(fiche + DEC_FICHE_PRCH);
    248 	if (pq->entete.draps & PQ_DRAP_GRAC
    249 			&& indice - LIRE_3(fiche + DEC_FICHE_DERN) < pq->entete.pnpi)
    250 		;
    251 	else if (((uint64_t) time(NULL) >> 8) < indice + pq->entete.date)
    252 		goto rien;
    253 
    254 	if (!(pq->entete.draps & PQ_DRAP_QST)) {
    255 		pq->entete.draps |= PQ_DRAP_QST;
    256 		if (pq_entete_maj(pq) < 0)
    257 			return -1;
    258 	}
    259 
    260 	return LIRE_3(fiche + DEC_FICHE_ID);
    261 
    262 rien:
    263 	fprintf(stderr, "%s: aucune fiche à réviser\n", nom_prog);
    264 	return -1;
    265 }
    266 
    267 static int
    268 pq_fiches_echanger(struct paquet *pq, uint32_t pos1, uint32_t pos2) {
    269 	if (pos1 != pos2) {
    270 		uint8_t fiche1[PQ_FICHE_LG];
    271 		uint8_t fiche2[PQ_FICHE_LG];
    272 		if (pq_fiche_copier(pq, pos1, fiche1) < 0)
    273 			return -1;
    274 		if (pq_fiche_copier(pq, pos2, fiche2) < 0)
    275 			return -1;
    276 		if (pq_fiche_coller(pq, pos1, fiche2) < 0)
    277 			return -1;
    278 		if (pq_fiche_coller(pq, pos2, fiche1) < 0)
    279 			return -1;
    280 	}
    281 
    282 	return 0;
    283 }
    284 
    285 int
    286 pq_reponse(struct paquet *pq, int rep)
    287 {
    288 	struct fiche f;
    289 	int          pos;
    290 	uint8_t      fiche[PQ_FICHE_LG];
    291 
    292 	assert(rep >= 0 && rep <= 5);
    293 
    294 	if (!(pq->entete.draps & PQ_DRAP_QST)) {
    295 		fprintf(stderr, "%s: veuillez d'abord exécuter la commande q\n",
    296 			nom_prog);
    297 		return -1;
    298 	}
    299 
    300 	if (pq->entete.draps & PQ_DRAP_MNC)
    301 		pos = 0;
    302 	else
    303 		pos = pq->entete.deb_n;
    304 
    305 	pq->entete.draps &= ~PQ_DRAP_QST;
    306 
    307 	if (pq_fiche_copier(pq, pos, fiche) < 0)
    308 		return -1;
    309 
    310 	f.prch  = LIRE_3(fiche + DEC_FICHE_PRCH);
    311 	f.dern  = LIRE_3(fiche + DEC_FICHE_DERN);
    312 	f.id    = LIRE_3(fiche + DEC_FICHE_ID);
    313 	f.fac   = LIRE_1(fiche + DEC_FICHE_FAC);
    314 	f.nsucc = LIRE_2(fiche + DEC_FICHE_NSUCC);
    315 
    316 	sm2(&f, rep, pq->entete.pins, pq->entete.pipi, pq->entete.pnpi, pq->entete.date);
    317 
    318 	fiche[0]  = (uint8_t) (f.prch >> 16);
    319 	fiche[1]  = (uint8_t) (f.prch >> 8);
    320 	fiche[2]  = (uint8_t) (f.prch);
    321 	fiche[3]  = (uint8_t) (f.dern >> 16);
    322 	fiche[4]  = (uint8_t) (f.dern >> 8);
    323 	fiche[5]  = (uint8_t) (f.dern);
    324 	fiche[6]  = (uint8_t) (f.id >> 16);
    325 	fiche[7]  = (uint8_t) (f.id >> 8);
    326 	fiche[8]  = (uint8_t) (f.id);
    327 	fiche[9]  = (uint8_t) (f.fac);
    328 	fiche[10] = (uint8_t) (f.nsucc >> 8);
    329 	fiche[11] = (uint8_t) (f.nsucc);
    330 
    331 	if (pos == 0 && pq->entete.deb_s > 0) {
    332 		if (pq_fiche_coller(pq, 0, fiche) < 0)
    333 			return -1;
    334 		if (pq_fiche_descendre(pq, 0, fiche) < 0)
    335 			return -1;
    336 	} else {
    337 		if (pq->entete.deb_n != pq->entete.deb_s) {
    338 			uint8_t fiche2[PQ_FICHE_LG];
    339 			if (pq_fiche_copier(pq, pq->entete.deb_s, fiche2) < 0)
    340 				return -1;
    341 			if (pq_fiche_coller(pq, pq->entete.deb_n, fiche2) < 0)
    342 				return -1;
    343 		}
    344 		if (pq_fiche_coller(pq, pq->entete.deb_s, fiche) < 0)
    345 			return -1;
    346 		pq->entete.deb_s++;
    347 		pq->entete.deb_n++;
    348 		if (pq->entete.draps & PQ_DRAP_NOUV)
    349 			pq->entete.nfs--;
    350 		assert(pq->entete.nfs >= 0);
    351 		if (pq_fiche_monter(pq, pos, fiche) < 0)
    352 			return -1;
    353 	}
    354 
    355 	if (pq_entete_maj(pq) < 0)
    356 		return -1;
    357 
    358 	return 0;
    359 }
    360 
    361 int
    362 pq_entete_maj(struct paquet *pq)
    363 {
    364 	uint8_t        texte[] = {
    365 		pq->entete.version,
    366 		pq->entete.draps,
    367 		(uint8_t) (pq->entete.deb_s >> 16),
    368 		(uint8_t) (pq->entete.deb_s >> 8),
    369 		(uint8_t) (pq->entete.deb_s),
    370 		(uint8_t) (pq->entete.deb_n >> 16),
    371 		(uint8_t) (pq->entete.deb_n >> 8),
    372 		(uint8_t) (pq->entete.deb_n),
    373 		(uint8_t) (pq->entete.nb >> 16),
    374 		(uint8_t) (pq->entete.nb >> 8),
    375 		(uint8_t) (pq->entete.nb),
    376 		pq->entete.pins,
    377 		(uint8_t) (pq->entete.pipi >> 8),
    378 		(uint8_t) (pq->entete.pipi),
    379 		(uint8_t) (pq->entete.pnpi >> 8),
    380 		(uint8_t) (pq->entete.pnpi),
    381 		pq->entete.fi,
    382 		(uint8_t) (pq->entete.date >> 48),
    383 		(uint8_t) (pq->entete.date >> 40),
    384 		(uint8_t) (pq->entete.date >> 32),
    385 		(uint8_t) (pq->entete.date >> 24),
    386 		(uint8_t) (pq->entete.date >> 16),
    387 		(uint8_t) (pq->entete.date >> 8),
    388 		(uint8_t) (pq->entete.date),
    389 		(uint8_t) (pq->entete.nfs >> 8),
    390 		(uint8_t) (pq->entete.nfs),
    391 		(uint8_t) (0),
    392 		(uint8_t) (0),
    393 		(uint8_t) (0),
    394 		(uint8_t) (0),
    395 		(uint8_t) (0),
    396 		(uint8_t) (0) };
    397 
    398 	assert(pq != NULL);
    399 	assert(sizeof(texte) == PQ_ENTETE_LG);
    400 
    401 	if (lseek(pq->fd, 0, SEEK_SET) < 0) {
    402 		perror(pq->nom);
    403 		return -1;
    404 	}
    405 
    406 	if (write(pq->fd, texte, PQ_ENTETE_LG) != PQ_ENTETE_LG) {
    407 		perror(pq->nom);
    408 		return -1;
    409 	}
    410 
    411 	return 0;
    412 }
    413 
    414 static int
    415 pq_fiche_copier(struct paquet *pq, uint32_t pos, uint8_t *tp)
    416 {
    417 	if (lseek(pq->fd, PQ_ENTETE_LG + pos * PQ_FICHE_LG, SEEK_SET) < 0) {
    418 		perror(pq->nom);
    419 		return -1;
    420 	}
    421 
    422 	if (read(pq->fd, tp, PQ_FICHE_LG) != PQ_FICHE_LG) {
    423 		perror(pq->nom);
    424 		return -1;
    425 	}
    426 
    427 	return 0;
    428 }
    429 
    430 static int
    431 pq_fiche_coller(struct paquet *pq, uint32_t pos, uint8_t *tp)
    432 {
    433 	if (lseek(pq->fd, PQ_ENTETE_LG + pos * PQ_FICHE_LG, SEEK_SET) < 0) {
    434 		perror(pq->nom);
    435 	}
    436 
    437 	if (write(pq->fd, tp, PQ_FICHE_LG) != PQ_FICHE_LG) {
    438 		perror(pq->nom);
    439 		return -1;
    440 	}
    441 
    442 	return 0;
    443 }
    444 
    445 /* faire monter une fiche dans le monceau */
    446 static int
    447 pq_fiche_monter(struct paquet *pq, uint32_t pos, uint8_t *tp)
    448 {
    449 	uint8_t  tp_parent[PQ_FICHE_LG];
    450 	uint32_t date;
    451 	uint32_t pos_orig;
    452 
    453 	assert(pq != NULL);
    454 	assert(tp != NULL);
    455 	assert(pq->entete.deb_s > pos); /* l'entrée doit être dans le monceau */
    456 
    457 	date = LIRE_3(tp + DEC_FICHE_PRCH);
    458 	for (pos_orig = pos; pos != 0; pos = PARENT(pos)) {
    459 		/* copier le parent */
    460 		if (pq_fiche_copier(pq, PARENT(pos), tp_parent) < 0)
    461 			return -1;
    462 
    463 		if (date >= LIRE_3(tp_parent + DEC_FICHE_PRCH))
    464 			break;
    465 
    466 		/* descendre le parent */
    467 		if (pq_fiche_coller(pq, pos, tp_parent) < 0)
    468 			return -1;
    469 	}
    470 
    471 	/* ne coller l'entrée que si l'enfant doit être déplacé */
    472 	if (pos != pos_orig)
    473 		if (pq_fiche_coller(pq, pos, tp) < 0)
    474 			return -1;
    475 
    476 	return 0;
    477 }
    478 
    479 /* faire descendre une entrée dans le monceau */
    480 static int
    481 pq_fiche_descendre(struct paquet *pq, uint32_t pos, uint8_t *tp)
    482 {
    483 	uint8_t  tp_enfants[PQ_FICHE_LG * 2];
    484 	uint32_t date_parent;
    485 	uint32_t date_enfants[2];
    486 	int      inf; /* sert à sélectionner l'enfant inférieur */
    487 	uint32_t pos_orig;
    488 
    489 	assert(pq != NULL);
    490 	assert(pq->entete.deb_s > pos); /* l'entrée doit être dans le monceau */
    491 
    492 	date_parent = LIRE_3(tp + DEC_FICHE_PRCH);
    493 	for (pos_orig = pos; ENFANT1(pos) < pq->entete.deb_s; pos = ENFANT1(pos) + inf) {
    494 		if (pq_fiche_copier(pq, ENFANT1(pos), tp_enfants) < 0)
    495 			return -1;
    496 
    497 		date_enfants[0] = LIRE_3(tp_enfants + DEC_FICHE_PRCH);
    498 		inf = 0;
    499 
    500 		if (ENFANT2(pos) < pq->entete.deb_s) {
    501 			if (pq_fiche_copier(pq, ENFANT2(pos),
    502 					tp_enfants + PQ_FICHE_LG) < 0)
    503 				return -1;
    504 			date_enfants[1] = LIRE_3(tp_enfants
    505 						+ PQ_FICHE_LG
    506 						+ DEC_FICHE_PRCH);
    507 			if (date_enfants[1] < date_enfants[0]) {
    508 				date_enfants[0] = date_enfants[1];
    509 				inf = 1;
    510 			}
    511 		}
    512 
    513 		/* monter l'enfant */
    514 		if (date_enfants[inf] <= date_parent) {
    515 			if (pq_fiche_coller(pq, pos, tp_enfants
    516 					+ PQ_FICHE_LG * inf) < 0)
    517 				return -1;
    518 		} else {
    519 			break;
    520 		}
    521 	}
    522 
    523 
    524 	/* ne coller l'entrée que si le parent doit être déplacé */
    525 	if (pos != pos_orig)
    526 		if (pq_fiche_coller(pq, pos, tp) < 0)
    527 			return -1;
    528 
    529 	return 0;
    530 }
    531 
    532 int
    533 pq_fiches_afficher(struct paquet *pq)
    534 {
    535 	uint8_t *tp;
    536 	int      n;
    537 	int      ncar;
    538 
    539 	ncar = pq->entete.nb * PQ_FICHE_LG;
    540 
    541 	if ((tp = malloc(ncar)) == NULL) {
    542 		perror(NULL);
    543 		return -1;
    544 	}
    545 
    546 	if (read(pq->fd, tp, ncar) != ncar) {
    547 		perror(pq->nom);
    548 		return -1;
    549 	}
    550 
    551 	printf("# MONCEAU\n");
    552 	for (n = pq->entete.deb_s; n > 0; n--, tp += PQ_FICHE_LG)
    553 		printf("%u\t%u\t%u\t%u\t%u\n",
    554 			LIRE_3(tp + DEC_FICHE_PRCH),
    555 			LIRE_3(tp + DEC_FICHE_DERN),
    556 			LIRE_3(tp + DEC_FICHE_ID),
    557 			LIRE_1(tp + DEC_FICHE_FAC),
    558 			LIRE_2(tp + DEC_FICHE_NSUCC));
    559 
    560 	printf("# CIMETIÈRE\n");
    561 	for (n = pq->entete.deb_n - pq->entete.deb_s; n > 0; n--, tp += PQ_FICHE_LG)
    562 		printf("%u\t%u\t%u\t%u\t%u\n",
    563 			LIRE_3(tp + DEC_FICHE_PRCH),
    564 			LIRE_3(tp + DEC_FICHE_DERN),
    565 			LIRE_3(tp + DEC_FICHE_ID),
    566 			LIRE_1(tp + DEC_FICHE_FAC),
    567 			LIRE_2(tp + DEC_FICHE_NSUCC));
    568 
    569 	printf("# NOUVEAUX\n");
    570 	for (n = pq->entete.nb - pq->entete.deb_n; n > 0; n--, tp += PQ_FICHE_LG)
    571 		printf("%u\t%u\t%u\t%u\t%u\n",
    572 			LIRE_3(tp + DEC_FICHE_PRCH),
    573 			LIRE_3(tp + DEC_FICHE_DERN),
    574 			LIRE_3(tp + DEC_FICHE_ID),
    575 			LIRE_1(tp + DEC_FICHE_FAC),
    576 			LIRE_2(tp + DEC_FICHE_NSUCC));
    577 
    578 	return 0;
    579 }