encore

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

encore.c (8362B)


      1 #include <assert.h>
      2 #include <stdint.h>
      3 #include <stdio.h>
      4 #include <string.h>
      5 #include <unistd.h>
      6 
      7 #include "paquet.h"
      8 #include "cve.h"
      9 
     10 #define CMD   '\0' /* commande racine */
     11 #define CMD_Q 'q'  /* questionner */
     12 #define CMD_R 'r'  /* répondre */
     13 #define CMD_S 's'  /* statistiquer */
     14 #define CMD_A 'a'  /* ajouter */
     15 #define CMD_E 'e'  /* enlever */
     16 #define CMD_I 'i'  /* initiliser */
     17 #define CMD_M 'm'  /* modifier */
     18 
     19 static int cmd_q(int, char **);
     20 static int cmd_r(int, char **);
     21 static int cmd_s(int, char **);
     22 static int cmd_a(int, char **);
     23 static int cmd_e(int, char **);
     24 static int cmd_i(int, char **);
     25 static int cmd_m(int, char **);
     26 
     27 static void utilisation(FILE *, int);
     28 
     29 char *nom_prog;
     30 
     31 int
     32 main(int argc, char **argv)
     33 {
     34 	char  opt;
     35 	int (*cmd)(int, char **);
     36 
     37 	if ((nom_prog = argv[0]) == NULL || nom_prog[0] == '\0')
     38 		nom_prog = "encore";
     39 
     40 	opterr = 0;
     41 	while ((opt = getopt(argc, argv, "h")) != -1) {
     42 		switch (opt) {
     43 		case 'h':
     44 			utilisation(stdout, CMD);
     45 			return 0;
     46 		default:
     47 			goto err_util;
     48 		}
     49 	}
     50 	argc    -= optind;
     51 	argv    += optind;
     52 	optind   = 1;
     53 	optreset = 1;
     54 
     55 	if (argc == 0)
     56 		goto err_util;
     57 
     58 	if (argv[0][1] != '\0')
     59 		goto err_util;
     60 
     61 	switch (argv[0][0]) {
     62 	case CMD_Q: cmd = &cmd_q; break;
     63 	case CMD_R: cmd = &cmd_r; break;
     64 	case CMD_S: cmd = &cmd_s; break;
     65 	case CMD_A: cmd = &cmd_a; break;
     66 	case CMD_E: cmd = &cmd_e; break;
     67 	case CMD_I: cmd = &cmd_i; break;
     68 	case CMD_M: cmd = &cmd_m; break;
     69 	default:    goto err_util;
     70 	}
     71 
     72 	return (*cmd)(argc, argv);
     73 
     74 err_util:
     75 	utilisation(stderr, CMD);
     76 	return 1;
     77 }
     78 
     79 static int
     80 cmd_q(int argc, char **argv)
     81 {
     82 	struct paquet pq;
     83 	int           opts_prch;
     84 	char          opt;
     85 	int           id;
     86 
     87 	assert(argc >= 1);
     88 	assert(argv != NULL);
     89 
     90 	opts_prch = 0;
     91 
     92 	while ((opt = getopt(argc, argv, "NVh")) != -1) {
     93 		switch (opt) {
     94 		case 'N':
     95 			opts_prch |= PQ_OPT_PRCH_NOUV;
     96 			continue;
     97 		case 'V':
     98 			opts_prch |= PQ_OPT_PRCH_VIEU;
     99 			continue;
    100 		case 'h':
    101 			utilisation(stdout, CMD_Q);
    102 			return 0;
    103 		default:
    104 			goto err_util;
    105 		}
    106 	}
    107 	argc -= optind;
    108 	argv += optind;
    109 
    110 	if (argc != 1)
    111 		goto err_util;
    112 
    113 	if (pq_ouvrir(argv[0], &pq) < 0)
    114 		return 1;
    115 
    116 	if ((id = pq_prochain(&pq, opts_prch)) < 0)
    117 		return 1;
    118 
    119 	printf("%u\n", id);
    120 
    121 	return 0;
    122 
    123 err_util:
    124 	utilisation(stderr, CMD_Q);
    125 	return 1;
    126 }
    127 
    128 static int
    129 cmd_r(int argc, char **argv)
    130 {
    131 	struct paquet pq;
    132 	char          opt;
    133 	unsigned int  qual;
    134 
    135 	assert(argc >= 1);
    136 	assert(argv != NULL);
    137 
    138 	qual = 4;
    139 
    140 	while ((opt = getopt(argc, argv, "q:h")) != -1) {
    141 		switch (opt) {
    142 		case 'q':
    143 			if (cve(optarg, &qual) < 0)
    144 				goto err_val;
    145 			if (qual < 0 || qual > 5)
    146 				goto err_val;
    147 			continue;
    148 		case 'h':
    149 			utilisation(stdout, CMD_R);
    150 			return 0;
    151 		default:
    152 			goto err_util;
    153 		}
    154 	}
    155 	argc -= optind;
    156 	argv += optind;
    157 
    158 	if (argc != 1)
    159 		goto err_util;
    160 
    161 	if (pq_ouvrir(argv[0], &pq) < 0)
    162 		return 1;
    163 
    164 	if (pq_reponse(&pq, qual) < 0)
    165 		return 1;
    166 
    167 	return 0;
    168 
    169 err_util:
    170 	utilisation(stderr, CMD_R);
    171 	return 1;
    172 err_val:
    173 	utilisation(stderr, CMD_R);
    174 	fprintf(stderr, "%s n'est pas un entier entre 0 et 5\n", optarg);
    175 	return 1;
    176 }
    177 
    178 static int
    179 cmd_s(int argc, char **argv)
    180 {
    181 	struct paquet pq;
    182 	char          opt;
    183 
    184 	assert(argc >= 1);
    185 	assert(argv != NULL);
    186 
    187 	while ((opt = getopt(argc, argv, "h")) != -1) {
    188 		switch (opt) {
    189 		case 'h':
    190 			utilisation(stdout, CMD_S);
    191 			return 0;
    192 		default:
    193 			goto err_util;
    194 		}
    195 	}
    196 	argc -= optind;
    197 	argv += optind;
    198 
    199 	if (argc != 1)
    200 		goto err_util;
    201 
    202 	if (pq_ouvrir(argv[0], &pq) < 0)
    203 		return 1;
    204 
    205 	printf("version: %d\n"
    206 		"drapeaux: %d\n"
    207 		"début du cimetière: %u\n"
    208 		"début de l'incubateur: %u\n"
    209 		"nombre d'entrées: %u\n"
    210 		"pins: %d\n"
    211 		"pipi: %u\n"
    212 		"pnpi: %u\n"
    213 		"fi: %u\n"
    214 		"date: %llu\n"
    215 		"nfs: %u\n",
    216 		pq.entete.version,
    217 		pq.entete.draps,
    218 		pq.entete.deb_s,
    219 		pq.entete.deb_n,
    220 		pq.entete.nb,
    221 		pq.entete.pins,
    222 		pq.entete.pipi,
    223 		pq.entete.pnpi,
    224 		pq.entete.fi,
    225 		pq.entete.date << 8,
    226 		pq.entete.nfs);
    227 
    228 	if (pq_fiches_afficher(&pq) < 0)
    229 		return 1;
    230 
    231 	return 0;
    232 
    233 err_util:
    234 	utilisation(stderr, CMD_S);
    235 	return 1;
    236 }
    237 
    238 static int
    239 cmd_a(int argc, char **argv)
    240 {
    241 	struct paquet pq;
    242 	unsigned int  n;
    243 	char          opt;
    244 	int           abs;
    245 
    246 	assert(argc >= 1);
    247 	assert(argv != NULL);
    248 
    249 	n   = 1;
    250 	abs = 0;
    251 
    252 	while ((opt = getopt(argc, argv, "n:ah")) != -1) {
    253 		switch (opt) {
    254 		case 'n':
    255 			if (cve(optarg, &n) < 0) {
    256 				utilisation(stderr, CMD_A);
    257 				fprintf(stderr,
    258 					"%s doit être un entier positif\n",
    259 					optarg);
    260 				return 0;
    261 			}
    262 			continue;
    263 		case 'a':
    264 			abs = 1;
    265 			continue;
    266 		case 'h':
    267 			utilisation(stdout, CMD_A);
    268 			return 0;
    269 		default:
    270 			goto err_util;
    271 		}
    272 	}
    273 	argc -= optind;
    274 	argv += optind;
    275 
    276 	if (argc != 1)
    277 		goto err_util;
    278 
    279 	if (pq_ouvrir(argv[0], &pq) < 0)
    280 		return 1;
    281 
    282 	if (abs) {
    283 		if (n < pq.entete.nb)
    284 			goto err_abs;
    285 		n = n - pq.entete.nb;
    286 	}
    287 
    288 	if (pq_ajouter(&pq, n) < 0)
    289 		return 1;
    290 
    291 	return 0;
    292 
    293 err_util:
    294 	utilisation(stderr, CMD_A);
    295 	return 1;
    296 err_abs:
    297 	fprintf(stderr, "il y a déjà plus de %d fiches dans %s\n",
    298 		pq.entete.nb, pq.nom);
    299 	return 1;
    300 }
    301 
    302 static int
    303 cmd_e(int argc, char **argv)
    304 {
    305 	assert(argc >= 1);
    306 	assert(argv != NULL);
    307 	assert(argv[0] != NULL);
    308 
    309 	(void)argc;
    310 	(void)argv;
    311 
    312 	utilisation(stdout, CMD_E);
    313 
    314 	return 0;
    315 }
    316 
    317 static int
    318 cmd_i(int argc, char **argv)
    319 {
    320 	int opt;
    321 
    322 	assert(argc >= 1);
    323 	assert(argv != NULL);
    324 
    325 	while ((opt = getopt(argc, argv, "h")) != -1) {
    326 		switch (opt) {
    327 		case 'h':
    328 			utilisation(stdout, CMD_I);
    329 			return 0;
    330 		default:
    331 			goto err_util;
    332 		}
    333 	}
    334 	argc -= optind;
    335 	argv += optind;
    336 
    337 	if (argc != 1)
    338 		goto err_util;
    339 
    340 	if (pq_init(argv[0]) < 0)
    341 		return 1;
    342 
    343 	return 0;
    344 
    345 err_util:
    346 	utilisation(stderr, CMD_I);
    347 	return 1;
    348 }
    349 
    350 static int
    351 cmd_m(int argc, char **argv)
    352 {
    353 	struct paquet pq;
    354 	unsigned int  n;
    355 	char          opt;
    356 	char         *opts = "s:i:n:f:q:c:a:g:h";
    357 
    358 	assert(argc >= 0);
    359 	assert(argv != NULL);
    360 
    361 	while (getopt(argc, argv, opts) != -1)
    362 		;
    363 
    364 	if (argc - optind == 0)
    365 		goto err_util;
    366 
    367 	if (pq_ouvrir(argv[optind], &pq) < 0)
    368 		return 1;
    369 
    370 	optind   = 1;
    371 	optreset = 1;
    372 
    373 	while ((opt = getopt(argc, argv, opts)) != -1) {
    374 		switch (opt) {
    375 		case 's':
    376 			if (cve(optarg, &n) < 0 || n > (uint8_t) ~0)
    377 				goto invalide;
    378 			pq.entete.pins = n;
    379 			continue;
    380 		case 'i':
    381 			if (cve(optarg, &n) < 0 || n > (uint16_t) ~0)
    382 				goto invalide;
    383 			pq.entete.pipi = n;
    384 			continue;
    385 		case 'n':
    386 			if (cve(optarg, &n) < 0 || n > (uint16_t) ~0)
    387 				goto invalide;
    388 			pq.entete.pnpi = n;
    389 			continue;
    390 		case 'f':
    391 			if (cve(optarg, &n) < 0 || n > (uint8_t) ~0)
    392 				goto invalide;
    393 			pq.entete.fi = n;
    394 			continue;
    395 		case 'q':
    396 			if (cve(optarg, &n) < 0 || n > (uint8_t) ~0)
    397 				goto invalide;
    398 			pq.entete.nfs = n;
    399 			continue;
    400 		case 'c':
    401 			if (optarg[1] != '\0')
    402 				goto err_util;
    403 			if (optarg[0] == '0')
    404 				pq.entete.draps &= ~PQ_DRAP_NOUV;
    405 			else if (optarg[0] == '1')
    406 				pq.entete.draps |= PQ_DRAP_NOUV;
    407 			continue;
    408 		case 'a':
    409 			if (optarg[1] != '\0')
    410 				goto err_util;
    411 			if (optarg[0] == '0')
    412 				pq.entete.draps &= ~PQ_DRAP_ALEA;
    413 			else if (optarg[0] == '1')
    414 				pq.entete.draps |= PQ_DRAP_ALEA;
    415 			continue;
    416 		case 'g':
    417 			if (optarg[1] != '\0')
    418 				goto err_util;
    419 			if (optarg[0] == '0')
    420 				pq.entete.draps &= ~PQ_DRAP_GRAC;
    421 			else if (optarg[0] == '1')
    422 				pq.entete.draps |= PQ_DRAP_GRAC;
    423 			continue;
    424 		case 'h':
    425 			utilisation(stdout, CMD_M);
    426 			return 0;
    427 		default:
    428 			goto err_util;
    429 		}
    430 	}
    431 
    432 	if (pq_entete_maj(&pq) < 0)
    433 		return 1;
    434 
    435 	return 0;
    436 
    437 invalide:
    438 	utilisation(stderr, CMD_M);
    439 	fprintf(stderr, "%s n'est pas un nombre valide\n", optarg);
    440 	return 1;
    441 err_util:
    442 	utilisation(stderr, CMD_M);
    443 	return 1;
    444 }
    445 
    446 static void
    447 utilisation(FILE *f, int cmd)
    448 {
    449 	char        *util;
    450 	unsigned int i;
    451 	char        *msgs[] = {
    452 		"[-h]",
    453 		"q [-hNV] paquet",
    454 		"r [-h] [-q qualité] paquet",
    455 		"s [-h] paquet",
    456 		"a [-h] [-n nb] paquet",
    457 		"e ??? paquet",
    458 		"i [-h] paquet",
    459 		("m [-h] [-s pins] [-i pipi] [-n pnpi] [-f fi] [-q nfs] "
    460 			"[-c dn] [-a aléa] [-g grâce] paquet") };
    461 
    462 	assert(f != NULL);
    463 
    464 	util = "Utilisation:";
    465 	fprintf(f, "%s", util);
    466 
    467 	switch (cmd) {
    468 	case CMD:
    469 		fputc('\n', f);
    470 		for (i = 0; i < sizeof(msgs) / sizeof(char *); i++)
    471 			fprintf(f, "  %s %s\n", nom_prog, msgs[i]);
    472 		return;
    473 	case CMD_Q: i = 1; break;
    474 	case CMD_R: i = 2; break;
    475 	case CMD_S: i = 3; break;
    476 	case CMD_A: i = 4; break;
    477 	case CMD_E: i = 5; break;
    478 	case CMD_I: i = 6; break;
    479 	case CMD_M: i = 7; break;
    480 	default:    assert(0); return;
    481 	}
    482 
    483 	fprintf(f, " %s %s\n", nom_prog, msgs[i]);
    484 }