opt.c (1688B)
1 #include <assert.h> 2 #include <string.h> 3 4 #include "rcx.h" 5 #include "opt.h" 6 7 void 8 opt_init(opt_ctx *opt, int *argc, char **argv) { 9 opt->arg_used = false; 10 opt->cluster = 0; 11 opt->argc = argc; 12 opt->o = &argv[1]; 13 opt->a = &argv[1]; 14 } 15 16 bool 17 opt_parse(opt_ctx *opt) { 18 if (opt->arg_used) { 19 if (opt->attached) { 20 opt->cluster = 0; 21 } else { 22 opt->o++; 23 (*opt->argc)--; 24 } 25 opt->arg_used = false; 26 } 27 28 if (opt->cluster) { 29 if ((opt->s = *++opt->cluster)) 30 goto found_opt; 31 opt->cluster = 0; 32 } 33 34 bool skip = false; 35 for (; *opt->o; opt->o++) { 36 if (skip || (*opt->o)[0] != '-' || (*opt->o)[1] == '\0') { 37 /* Got an argument */ 38 *opt->a++ = *opt->o; 39 continue; 40 } 41 (*opt->argc)--; 42 if ((*opt->o)[1] == '-' && (*opt->o)[2] == '\0') { 43 /* Got "--", so everything else is an argument */ 44 skip = true; 45 continue; 46 } 47 /* Got an option */ 48 if ((*opt->o)[1] == '-') { /* Long */ 49 opt->s = 0; 50 opt->l = &(*opt->o)[2]; 51 } else { /* Short */ 52 opt->cluster = &(*opt->o)[1]; 53 opt->s = *opt->cluster; 54 opt->l = ""; 55 } 56 opt->o++; 57 goto found_opt; 58 } 59 60 /* End of option parsing */ 61 *opt->a = 0; 62 return false; 63 64 found_opt: 65 /* Find argument for option */ 66 opt->arg = 0; 67 if ((opt->arg = strchr(opt->l, '='))) { /* "--opt=ARG" */ 68 *opt->arg++ = '\0'; /* Null-terminate opt->l */ 69 opt->attached = true; 70 } else if (opt->s && opt->cluster[1] != '\0') { /* "-oARG" */ 71 opt->arg = &opt->cluster[1]; 72 opt->attached = true; 73 } else { /* "-o ARG" or "--opt ARG" or nothing */ 74 opt->arg = *opt->o; 75 opt->attached = false; 76 } 77 opt->avail = !!opt->arg; 78 79 return true; 80 } 81 82 char * 83 opt_arg(opt_ctx *opt) { 84 assert(opt->avail); 85 opt->arg_used = true; 86 return opt->arg; 87 }