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 }