8 # define alloca __builtin_alloca
10 # define alloca __alloca
11 #elif defined _MSC_VER
13 # define alloca _alloca
31 # define gettext(x) (x)
32 # define dgettext(domain, x) (x)
35 #define _(x) dgettext("ecore", x)
46 #include "Ecore_Getopt.h"
48 static const char *prog = NULL;
49 static char **_argv = NULL;
52 static int helpcol = 80 / 3;
55 _ecore_getopt_help_print_replace_program(FILE *fp,
56 const Ecore_Getopt *parser __UNUSED__,
61 const char *d = strchr(text, '%');
69 if (fwrite(text, 1, d - text, fp) != (size_t)(d - text))
72 if (strncmp(d, "prog", sizeof("prog") - 1) == 0)
74 fputs(prog ? prog : "???", fp);
75 d += sizeof("prog") - 1;
86 while (text[0] != '\0');
92 _ecore_getopt_version(FILE *fp,
93 const Ecore_Getopt *parser)
95 fputs(_("Version:"), fp);
97 _ecore_getopt_help_print_replace_program(fp, parser, parser->version);
101 _ecore_getopt_help_usage(FILE *fp,
102 const Ecore_Getopt *parser)
104 fputs(_("Usage:"), fp);
109 fprintf(fp, _("%s [options]\n"), prog);
113 _ecore_getopt_help_print_replace_program(fp, parser, gettext(parser->usage));
117 _ecore_getopt_help_line(FILE *fp,
127 /* process line considering spaces (new line and tabs are spaces!) */
128 while ((used < total) && (len > 0))
130 const char *space = NULL;
137 for (i = 0; i < todo; i++)
138 if (isspace((unsigned char)text[i]))
146 i = fwrite(text, 1, i, fp);
158 if (space[0] == '\n')
160 else if (space[0] == '\t')
165 c = ((used / 8) + 1) * 8;
168 for (; used < c; used++)
178 else if (used < total)
183 i = fwrite(text, 1, i, fp);
194 for (used = 0; used < base; used++)
203 _ecore_getopt_help_description(FILE *fp,
204 const Ecore_Getopt *parser)
206 const char *p, *prg, *ver;
207 int used, prglen, verlen;
209 p = gettext(parser->description);
215 prg = prog ? prog : "???";
216 ver = parser->version ? parser->version : "???";
218 prglen = strlen(prg);
219 verlen = strlen(ver);
225 const char *d = strchr(p, '%');
229 _ecore_getopt_help_line(fp, 0, cols, used, p, strlen(p));
233 used = _ecore_getopt_help_line(fp, 0, cols, used, p, d - p);
235 if (strncmp(d, "prog", sizeof("prog") - 1) == 0)
237 used = _ecore_getopt_help_line(fp, 0, cols, used, prg, prglen);
238 d += sizeof("prog") - 1;
240 else if (strncmp(d, "version", sizeof("version") - 1) == 0)
242 used = _ecore_getopt_help_line(fp, 0, cols, used, ver, verlen);
243 d += sizeof("version") - 1;
249 used = _ecore_getopt_help_line(fp, 0, cols, used, "%", 1);
254 while (p[0] != '\0');
260 _ecore_getopt_copyright(FILE *fp,
261 const Ecore_Getopt *parser)
263 const char *txt = gettext(parser->copyright);
264 fputs(_("Copyright:"), fp);
266 _ecore_getopt_help_line
267 (fp, 3, cols, 3, txt, strlen(txt));
272 _ecore_getopt_license(FILE *fp,
273 const Ecore_Getopt *parser)
275 const char *txt = gettext(parser->license);
276 fputs(_("License:"), fp);
278 _ecore_getopt_help_line
279 (fp, 3, cols, 3, txt, strlen(txt));
283 static Ecore_Getopt_Desc_Arg_Requirement
284 _ecore_getopt_desc_arg_requirement(const Ecore_Getopt_Desc *desc)
286 switch (desc->action)
288 case ECORE_GETOPT_ACTION_STORE:
289 return desc->action_param.store.arg_req;
291 case ECORE_GETOPT_ACTION_STORE_CONST:
292 return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
294 case ECORE_GETOPT_ACTION_STORE_TRUE:
295 return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
297 case ECORE_GETOPT_ACTION_STORE_FALSE:
298 return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
300 case ECORE_GETOPT_ACTION_CHOICE:
301 return ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES;
303 case ECORE_GETOPT_ACTION_APPEND:
304 return ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES;
306 case ECORE_GETOPT_ACTION_COUNT:
307 return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
309 case ECORE_GETOPT_ACTION_CALLBACK:
310 return desc->action_param.callback.arg_req;
312 case ECORE_GETOPT_ACTION_HELP:
313 return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
315 case ECORE_GETOPT_ACTION_VERSION:
316 return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
319 return ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO;
324 _ecore_getopt_help_desc_setup_metavar(const Ecore_Getopt_Desc *desc,
331 const char *txt = gettext(desc->metavar);
332 *metavarlen = strlen(txt);
333 if (*metavarlen > maxsize - 1)
334 *metavarlen = maxsize - 1;
336 memcpy(metavar, txt, *metavarlen);
337 metavar[*metavarlen] = '\0';
339 else if (desc->longname)
343 *metavarlen = strlen(desc->longname);
344 if (*metavarlen > maxsize - 1)
345 *metavarlen = maxsize - 1;
347 for (i = 0; i < *metavarlen; i++)
348 metavar[i] = toupper((int) desc->longname[i]);
354 _ecore_getopt_help_desc_show_arg(FILE *fp,
355 Ecore_Getopt_Desc_Arg_Requirement requirement,
361 if (requirement == ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO)
366 if (requirement == ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL)
372 if (requirement != ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO)
376 used += metavarlen + 1;
379 if (requirement == ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL)
389 _ecore_getopt_help_desc_store(FILE *fp,
393 const Ecore_Getopt_Desc *desc)
395 const Ecore_Getopt_Desc_Store *store = &desc->action_param.store;
401 for (used = 0; used < base; used++)
406 case ECORE_GETOPT_TYPE_STR:
408 len = sizeof("STR") - 1;
411 case ECORE_GETOPT_TYPE_BOOL:
413 len = sizeof("BOOL") - 1;
416 case ECORE_GETOPT_TYPE_SHORT:
418 len = sizeof("SHORT") - 1;
421 case ECORE_GETOPT_TYPE_INT:
423 len = sizeof("INT") - 1;
426 case ECORE_GETOPT_TYPE_LONG:
428 len = sizeof("LONG") - 1;
431 case ECORE_GETOPT_TYPE_USHORT:
433 len = sizeof("USHORT") - 1;
436 case ECORE_GETOPT_TYPE_UINT:
438 len = sizeof("UINT") - 1;
441 case ECORE_GETOPT_TYPE_ULONG:
443 len = sizeof("ULONG") - 1;
446 case ECORE_GETOPT_TYPE_DOUBLE:
448 len = sizeof("DOUBLE") - 1;
453 len = sizeof("???") - 1;
456 used = _ecore_getopt_help_line
457 (fp, base, total, used, _("Type: "), strlen(_("Type: ")));
458 used = _ecore_getopt_help_line(fp, base, total, used, str, len);
460 if (store->arg_req == ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES)
463 used = _ecore_getopt_help_line
464 (fp, base, total, used, ". ", sizeof(". ") - 1);
468 case ECORE_GETOPT_TYPE_STR:
469 str = store->def.strv;
470 len = str ? strlen(str) : 0;
473 case ECORE_GETOPT_TYPE_BOOL:
474 str = store->def.boolv ? "true" : "false";
478 case ECORE_GETOPT_TYPE_SHORT:
480 len = snprintf(buf, sizeof(buf), "%hd", store->def.shortv);
481 if (len > sizeof(buf) - 1)
482 len = sizeof(buf) - 1;
485 case ECORE_GETOPT_TYPE_INT:
487 len = snprintf(buf, sizeof(buf), "%d", store->def.intv);
488 if (len > sizeof(buf) - 1)
489 len = sizeof(buf) - 1;
492 case ECORE_GETOPT_TYPE_LONG:
494 len = snprintf(buf, sizeof(buf), "%ld", store->def.longv);
495 if (len > sizeof(buf) - 1)
496 len = sizeof(buf) - 1;
499 case ECORE_GETOPT_TYPE_USHORT:
501 len = snprintf(buf, sizeof(buf), "%hu", store->def.ushortv);
502 if (len > sizeof(buf) - 1)
503 len = sizeof(buf) - 1;
506 case ECORE_GETOPT_TYPE_UINT:
508 len = snprintf(buf, sizeof(buf), "%u", store->def.uintv);
509 if (len > sizeof(buf) - 1)
510 len = sizeof(buf) - 1;
513 case ECORE_GETOPT_TYPE_ULONG:
515 len = snprintf(buf, sizeof(buf), "%lu", store->def.ulongv);
516 if (len > sizeof(buf) - 1)
517 len = sizeof(buf) - 1;
520 case ECORE_GETOPT_TYPE_DOUBLE:
522 len = snprintf(buf, sizeof(buf), "%f", store->def.doublev);
523 if (len > sizeof(buf) - 1)
524 len = sizeof(buf) - 1;
529 len = sizeof("???") - 1;
532 used = _ecore_getopt_help_line
533 (fp, base, total, used, _("Default: "), strlen(_("Default: ")));
534 used = _ecore_getopt_help_line(fp, base, total, used, str, len);
537 return _ecore_getopt_help_line(fp, base, total, used, ".", 1);
541 _ecore_getopt_help_desc_choices(FILE *fp,
545 const Ecore_Getopt_Desc *desc)
547 const char *const *itr;
548 const char sep[] = ", ";
549 const int seplen = sizeof(sep) - 1;
556 for (; used < base; used++)
559 used = _ecore_getopt_help_line
560 (fp, base, total, used, _("Choices: "), strlen(_("Choices: ")));
562 for (itr = desc->action_param.choices; *itr; itr++)
564 used = _ecore_getopt_help_line
565 (fp, base, total, used, *itr, strlen(*itr));
567 used = _ecore_getopt_help_line(fp, base, total, used, sep, seplen);
570 return _ecore_getopt_help_line(fp, base, total, used, ".", 1);
574 _ecore_getopt_help_desc(FILE *fp,
575 const Ecore_Getopt_Desc *desc)
577 Ecore_Getopt_Desc_Arg_Requirement arg_req;
578 char metavar[32] = "ARG";
582 arg_req = _ecore_getopt_desc_arg_requirement(desc);
583 if (arg_req != ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO)
584 _ecore_getopt_help_desc_setup_metavar
585 (desc, metavar, &metavarlen, sizeof(metavar));
593 fputc(desc->shortname, fp);
595 used += _ecore_getopt_help_desc_show_arg
596 (fp, arg_req, metavar, metavarlen);
599 if (desc->shortname && desc->longname)
607 int namelen = strlen(desc->longname);
610 fputs(desc->longname, fp);
612 used += _ecore_getopt_help_desc_show_arg
613 (fp, arg_req, metavar, metavarlen);
619 if (used + 3 >= helpcol)
625 for (; used < helpcol; used++)
628 used = _ecore_getopt_help_line
629 (fp, helpcol, cols, used, desc->help, strlen(desc->help));
631 switch (desc->action)
633 case ECORE_GETOPT_ACTION_STORE:
634 _ecore_getopt_help_desc_store(fp, helpcol, cols, used, desc);
637 case ECORE_GETOPT_ACTION_CHOICE:
638 _ecore_getopt_help_desc_choices(fp, helpcol, cols, used, desc);
650 _ecore_getopt_desc_is_sentinel(const Ecore_Getopt_Desc *desc)
652 return (desc->shortname == '\0') && (!desc->longname);
656 _ecore_getopt_help_options(FILE *fp,
657 const Ecore_Getopt *parser)
659 const Ecore_Getopt_Desc *desc;
661 fputs(_("Options:\n"), fp);
663 for (desc = parser->descs; !_ecore_getopt_desc_is_sentinel(desc); desc++)
664 _ecore_getopt_help_desc(fp, desc);
670 * Show nicely formatted help message for the given parser.
672 * @param fp The file the message will be printed on.
673 * @param parser The parser to be used.
676 ecore_getopt_help(FILE *fp,
677 const Ecore_Getopt *parser)
681 EINA_MAIN_LOOP_CHECK_RETURN;
686 ecore_app_args_get(&_argc, &_argv);
687 if ((_argc > 0) && (_argv[0]))
693 var = getenv("COLUMNS");
703 _ecore_getopt_help_usage(fp, parser);
704 _ecore_getopt_help_description(fp, parser);
705 _ecore_getopt_help_options(fp, parser);
708 static const Ecore_Getopt_Desc *
709 _ecore_getopt_parse_find_long(const Ecore_Getopt *parser,
712 const Ecore_Getopt_Desc *desc = parser->descs;
713 const char *p = strchr(name, '=');
719 for (; !_ecore_getopt_desc_is_sentinel(desc); desc++)
726 if ((strncmp(name, desc->longname, len) == 0) &&
727 (desc->longname[len] == '\0'))
732 if (strcmp(name, desc->longname) == 0)
740 static const Ecore_Getopt_Desc *
741 _ecore_getopt_parse_find_short(const Ecore_Getopt *parser,
744 const Ecore_Getopt_Desc *desc = parser->descs;
745 for (; !_ecore_getopt_desc_is_sentinel(desc); desc++)
746 if (name == desc->shortname)
752 _ecore_getopt_parse_find_nonargs_base(const Ecore_Getopt *parser,
757 int src, dst, used, base;
759 nonargs = alloca(sizeof(char *) * argc);
766 const Ecore_Getopt_Desc *desc;
767 Ecore_Getopt_Desc_Arg_Requirement arg_req;
768 char *arg = argv[src];
775 if (arg[2] == '\0') /* explicit end of options, "--" */
780 desc = _ecore_getopt_parse_find_long(parser, arg + 2);
783 desc = _ecore_getopt_parse_find_short(parser, arg[1]);
788 fprintf(stderr, _("ERROR: unknown option --%s.\n"), arg + 2);
790 fprintf(stderr, _("ERROR: unknown option -%c.\n"), arg[1]);
793 memmove(argv + dst, nonargs, used * sizeof(char *));
801 argv[dst] = argv[src];
805 arg_req = _ecore_getopt_desc_arg_requirement(desc);
806 if (arg_req == ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO)
809 if (strchr(arg, '='))
812 if ((src >= argc) || (argv[src][0] == '-'))
816 argv[dst] = argv[src];
827 if (!base) /* '--' not found */
833 argv[dst] = argv[src];
837 memmove(argv + dst, nonargs, used * sizeof(char *));
842 _ecore_getopt_desc_print_error(const Ecore_Getopt_Desc *desc,
848 fputs(_("ERROR: "), stderr);
853 fputc(desc->shortname, stderr);
856 if (desc->shortname && desc->longname)
862 fputs(desc->longname, stderr);
868 vfprintf(stderr, fmt, ap);
873 _ecore_getopt_parse_bool(const char *str,
876 if ((strcmp(str, "0") == 0) ||
877 (strcasecmp(str, "f") == 0) ||
878 (strcasecmp(str, "false") == 0) ||
879 (strcasecmp(str, "no") == 0) ||
880 (strcasecmp(str, "off") == 0)
886 else if ((strcmp(str, "1") == 0) ||
887 (strcasecmp(str, "t") == 0) ||
888 (strcasecmp(str, "true") == 0) ||
889 (strcasecmp(str, "yes") == 0) ||
890 (strcasecmp(str, "on") == 0)
901 _ecore_getopt_parse_long(const char *str,
905 *v = strtol(str, &endptr, 0);
910 _ecore_getopt_parse_double(const char *str,
914 *v = strtod(str, &endptr);
919 _ecore_getopt_parse_store(const Ecore_Getopt *parser __UNUSED__,
920 const Ecore_Getopt_Desc *desc,
921 Ecore_Getopt_Value *value,
924 const Ecore_Getopt_Desc_Store *store = &desc->action_param.store;
931 _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n"));
935 switch (store->arg_req)
937 case ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO:
940 case ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL:
944 case ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES:
950 case ECORE_GETOPT_TYPE_STR:
951 *value->strp = (char *)arg_val;
954 case ECORE_GETOPT_TYPE_BOOL:
955 if (_ecore_getopt_parse_bool(arg_val, &b))
962 _ecore_getopt_desc_print_error
963 (desc, _("unknown boolean value %s.\n"), arg_val);
967 case ECORE_GETOPT_TYPE_SHORT:
968 if (!_ecore_getopt_parse_long(arg_val, &v))
973 case ECORE_GETOPT_TYPE_INT:
974 if (!_ecore_getopt_parse_long(arg_val, &v))
979 case ECORE_GETOPT_TYPE_LONG:
980 if (!_ecore_getopt_parse_long(arg_val, &v))
985 case ECORE_GETOPT_TYPE_USHORT:
986 if (!_ecore_getopt_parse_long(arg_val, &v))
991 case ECORE_GETOPT_TYPE_UINT:
992 if (!_ecore_getopt_parse_long(arg_val, &v))
997 case ECORE_GETOPT_TYPE_ULONG:
998 if (!_ecore_getopt_parse_long(arg_val, &v))
1003 case ECORE_GETOPT_TYPE_DOUBLE:
1004 if (!_ecore_getopt_parse_double(arg_val, &d))
1006 *value->doublep = d;
1013 _ecore_getopt_desc_print_error
1014 (desc, _("invalid number format %s\n"), arg_val);
1018 switch (store->type)
1020 case ECORE_GETOPT_TYPE_STR:
1021 *value->strp = (char *)store->def.strv;
1024 case ECORE_GETOPT_TYPE_BOOL:
1025 *value->boolp = store->def.boolv;
1028 case ECORE_GETOPT_TYPE_SHORT:
1029 *value->shortp = store->def.shortv;
1032 case ECORE_GETOPT_TYPE_INT:
1033 *value->intp = store->def.intv;
1036 case ECORE_GETOPT_TYPE_LONG:
1037 *value->longp = store->def.longv;
1040 case ECORE_GETOPT_TYPE_USHORT:
1041 *value->ushortp = store->def.ushortv;
1044 case ECORE_GETOPT_TYPE_UINT:
1045 *value->uintp = store->def.uintv;
1048 case ECORE_GETOPT_TYPE_ULONG:
1049 *value->ulongp = store->def.ulongv;
1052 case ECORE_GETOPT_TYPE_DOUBLE:
1053 *value->doublep = store->def.doublev;
1061 _ecore_getopt_parse_store_const(const Ecore_Getopt *parser __UNUSED__,
1062 const Ecore_Getopt_Desc *desc,
1063 Ecore_Getopt_Value *val,
1064 const char *arg_val __UNUSED__)
1068 _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n"));
1072 *val->ptrp = (void *)desc->action_param.store_const;
1077 _ecore_getopt_parse_store_true(const Ecore_Getopt *parser __UNUSED__,
1078 const Ecore_Getopt_Desc *desc,
1079 Ecore_Getopt_Value *val,
1080 const char *arg_val __UNUSED__)
1084 _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n"));
1087 *val->boolp = EINA_TRUE;
1092 _ecore_getopt_parse_store_false(const Ecore_Getopt *parser __UNUSED__,
1093 const Ecore_Getopt_Desc *desc,
1094 Ecore_Getopt_Value *val,
1095 const char *arg_val __UNUSED__)
1099 _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n"));
1102 *val->boolp = EINA_FALSE;
1107 _ecore_getopt_parse_choice(const Ecore_Getopt *parser __UNUSED__,
1108 const Ecore_Getopt_Desc *desc,
1109 Ecore_Getopt_Value *val,
1110 const char *arg_val)
1112 const char *const *pchoice;
1116 _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n"));
1120 pchoice = desc->action_param.choices;
1121 for (; *pchoice; pchoice++)
1122 if (strcmp(*pchoice, arg_val) == 0)
1124 *val->strp = (char *)*pchoice;
1128 _ecore_getopt_desc_print_error
1129 (desc, _("invalid choice \"%s\". Valid values are: "), arg_val);
1131 pchoice = desc->action_param.choices;
1132 for (; *pchoice; pchoice++)
1134 fputs(*pchoice, stderr);
1136 fputs(", ", stderr);
1139 fputs(".\n", stderr);
1144 _ecore_getopt_parse_append(const Ecore_Getopt *parser __UNUSED__,
1145 const Ecore_Getopt_Desc *desc,
1146 Ecore_Getopt_Value *val,
1147 const char *arg_val)
1156 _ecore_getopt_desc_print_error
1157 (desc, _("missing parameter to append.\n"));
1163 _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n"));
1167 switch (desc->action_param.append_type)
1169 case ECORE_GETOPT_TYPE_STR:
1170 data = strdup(arg_val);
1173 case ECORE_GETOPT_TYPE_BOOL:
1175 if (_ecore_getopt_parse_bool(arg_val, &b))
1177 data = malloc(sizeof(Eina_Bool));
1179 *(Eina_Bool *)data = b;
1183 _ecore_getopt_desc_print_error(desc, _("unknown boolean value %s.\n"), arg_val);
1189 case ECORE_GETOPT_TYPE_SHORT:
1191 if (!_ecore_getopt_parse_long(arg_val, &v))
1193 data = malloc(sizeof(short));
1195 *(short *)data = (short)v;
1199 case ECORE_GETOPT_TYPE_INT:
1201 if (!_ecore_getopt_parse_long(arg_val, &v))
1203 data = malloc(sizeof(int));
1205 *(int *)data = (int)v;
1209 case ECORE_GETOPT_TYPE_LONG:
1211 if (!_ecore_getopt_parse_long(arg_val, &v))
1213 data = malloc(sizeof(long));
1219 case ECORE_GETOPT_TYPE_USHORT:
1221 if (!_ecore_getopt_parse_long(arg_val, &v))
1223 data = malloc(sizeof(unsigned short));
1225 *(unsigned short *)data = (unsigned short)v;
1229 case ECORE_GETOPT_TYPE_UINT:
1231 if (!_ecore_getopt_parse_long(arg_val, &v))
1233 data = malloc(sizeof(unsigned int));
1235 *(unsigned int *)data = (unsigned int)v;
1239 case ECORE_GETOPT_TYPE_ULONG:
1241 if (!_ecore_getopt_parse_long(arg_val, &v))
1243 data = malloc(sizeof(unsigned long));
1245 *(unsigned long *)data = v;
1249 case ECORE_GETOPT_TYPE_DOUBLE:
1251 if (!_ecore_getopt_parse_double(arg_val, &d))
1253 data = malloc(sizeof(double));
1255 *(double *)data = d;
1261 _ecore_getopt_desc_print_error(desc, _("could not parse value.\n"));
1266 *val->listp = eina_list_append(*val->listp, data);
1270 _ecore_getopt_desc_print_error
1271 (desc, _("invalid number format %s\n"), arg_val);
1276 _ecore_getopt_parse_count(const Ecore_Getopt *parser __UNUSED__,
1277 const Ecore_Getopt_Desc *desc,
1278 Ecore_Getopt_Value *val,
1279 const char *arg_val __UNUSED__)
1283 _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n"));
1292 _ecore_getopt_parse_callback(const Ecore_Getopt *parser,
1293 const Ecore_Getopt_Desc *desc,
1294 Ecore_Getopt_Value *val,
1295 const char *arg_val)
1297 const Ecore_Getopt_Desc_Callback *cb = &desc->action_param.callback;
1299 switch (cb->arg_req)
1301 case ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO:
1305 case ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL:
1310 case ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES:
1314 if (cb->arg_req != ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO)
1316 if ((!arg_val) || (arg_val[0] == '\0'))
1318 _ecore_getopt_desc_print_error(desc, _("missing parameter.\n"));
1324 _ecore_getopt_desc_print_error(desc, _("value has no pointer set.\n"));
1331 _ecore_getopt_desc_print_error(desc, _("missing callback function!\n"));
1335 return cb->func(parser, desc, arg_val, (void *)cb->data, val);
1339 _ecore_getopt_parse_help(const Ecore_Getopt *parser,
1340 const Ecore_Getopt_Desc *desc __UNUSED__,
1341 Ecore_Getopt_Value *val,
1342 const char *arg_val __UNUSED__)
1345 (*val->boolp) = EINA_TRUE;
1346 ecore_getopt_help(stdout, parser);
1351 _ecore_getopt_parse_version(const Ecore_Getopt *parser,
1352 const Ecore_Getopt_Desc *desc,
1353 Ecore_Getopt_Value *val,
1354 const char *arg_val __UNUSED__)
1357 (*val->boolp) = EINA_TRUE;
1358 if (!parser->version)
1360 _ecore_getopt_desc_print_error(desc, _("no version was defined.\n"));
1363 _ecore_getopt_version(stdout, parser);
1368 _ecore_getopt_parse_copyright(const Ecore_Getopt *parser,
1369 const Ecore_Getopt_Desc *desc,
1370 Ecore_Getopt_Value *val,
1371 const char *arg_val __UNUSED__)
1374 (*val->boolp) = EINA_TRUE;
1375 if (!parser->copyright)
1377 _ecore_getopt_desc_print_error(desc, _("no copyright was defined.\n"));
1380 _ecore_getopt_copyright(stdout, parser);
1385 _ecore_getopt_parse_license(const Ecore_Getopt *parser,
1386 const Ecore_Getopt_Desc *desc,
1387 Ecore_Getopt_Value *val,
1388 const char *arg_val __UNUSED__)
1391 (*val->boolp) = EINA_TRUE;
1392 if (!parser->license)
1394 _ecore_getopt_desc_print_error(desc, _("no license was defined.\n"));
1397 _ecore_getopt_license(stdout, parser);
1402 _ecore_getopt_desc_handle(const Ecore_Getopt *parser,
1403 const Ecore_Getopt_Desc *desc,
1404 Ecore_Getopt_Value *value,
1405 const char *arg_val)
1407 switch (desc->action)
1409 case ECORE_GETOPT_ACTION_STORE:
1410 return _ecore_getopt_parse_store(parser, desc, value, arg_val);
1412 case ECORE_GETOPT_ACTION_STORE_CONST:
1413 return _ecore_getopt_parse_store_const(parser, desc, value, arg_val);
1415 case ECORE_GETOPT_ACTION_STORE_TRUE:
1416 return _ecore_getopt_parse_store_true(parser, desc, value, arg_val);
1418 case ECORE_GETOPT_ACTION_STORE_FALSE:
1419 return _ecore_getopt_parse_store_false(parser, desc, value, arg_val);
1421 case ECORE_GETOPT_ACTION_CHOICE:
1422 return _ecore_getopt_parse_choice(parser, desc, value, arg_val);
1424 case ECORE_GETOPT_ACTION_APPEND:
1425 return _ecore_getopt_parse_append(parser, desc, value, arg_val);
1427 case ECORE_GETOPT_ACTION_COUNT:
1428 return _ecore_getopt_parse_count(parser, desc, value, arg_val);
1430 case ECORE_GETOPT_ACTION_CALLBACK:
1431 return _ecore_getopt_parse_callback(parser, desc, value, arg_val);
1433 case ECORE_GETOPT_ACTION_HELP:
1434 return _ecore_getopt_parse_help(parser, desc, value, arg_val);
1436 case ECORE_GETOPT_ACTION_VERSION:
1437 return _ecore_getopt_parse_version(parser, desc, value, arg_val);
1439 case ECORE_GETOPT_ACTION_COPYRIGHT:
1440 return _ecore_getopt_parse_copyright(parser, desc, value, arg_val);
1442 case ECORE_GETOPT_ACTION_LICENSE:
1443 return _ecore_getopt_parse_license(parser, desc, value, arg_val);
1451 _ecore_getopt_parse_arg_long(const Ecore_Getopt *parser,
1452 Ecore_Getopt_Value *values,
1453 int argc __UNUSED__,
1459 const Ecore_Getopt_Desc *desc;
1460 Ecore_Getopt_Desc_Arg_Requirement arg_req;
1461 const char *arg_val;
1463 Ecore_Getopt_Value *value;
1466 desc = _ecore_getopt_parse_find_long(parser, arg);
1469 fprintf(stderr, _("ERROR: unknown option --%s, ignored.\n"), arg);
1479 arg_req = _ecore_getopt_desc_arg_requirement(desc);
1480 if (arg_req != ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO)
1482 arg_val = strchr(arg, '=');
1487 if ((*idx < *nonargs) && (argv[*idx][0] != '-'))
1489 arg_val = argv[*idx];
1496 if (arg_val && arg_val[0] == '\0')
1499 if ((!arg_val) && (arg_req == ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES))
1502 (stderr, _("ERROR: option --%s requires an argument!\n"), arg);
1511 desc_idx = desc - parser->descs;
1512 value = values + desc_idx;
1513 ret = _ecore_getopt_desc_handle(parser, desc, value, arg_val);
1514 if ((!ret) && parser->strict)
1521 _ecore_getopt_parse_arg_short(const Ecore_Getopt *parser,
1522 Ecore_Getopt_Value *values,
1523 int argc __UNUSED__,
1530 while (run && (arg[0] != '\0'))
1533 const Ecore_Getopt_Desc *desc;
1534 Ecore_Getopt_Desc_Arg_Requirement arg_req;
1535 const char *arg_val;
1537 Ecore_Getopt_Value *value;
1540 desc = _ecore_getopt_parse_find_short(parser, arg[0]);
1544 (stderr, _("ERROR: unknown option -%c, ignored.\n"), arg[0]);
1554 arg_req = _ecore_getopt_desc_arg_requirement(desc);
1555 if (arg_req != ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO)
1562 else if (arg[0] != '\0')
1566 if ((*idx < *nonargs) && (argv[*idx][0] != '-'))
1568 arg_val = argv[*idx];
1575 if (arg_val && arg_val[0] == '\0')
1579 (arg_req == ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES))
1582 (stderr, _("ERROR: option -%c requires an argument!\n"),
1592 desc_idx = desc - parser->descs;
1593 value = values + desc_idx;
1594 ret = _ecore_getopt_desc_handle(parser, desc, value, arg_val);
1595 if ((!ret) && parser->strict)
1606 _ecore_getopt_parse_arg(const Ecore_Getopt *parser,
1607 Ecore_Getopt_Value *values,
1613 char *arg = argv[*idx];
1617 char **dst, **src, **src_end;
1621 src_end = src + *nonargs - *idx - 1;
1623 for (; src < src_end; src++, dst++)
1632 return _ecore_getopt_parse_arg_long(parser, values, argc, argv, idx, nonargs, arg + 2);
1634 return _ecore_getopt_parse_arg_short(parser, values, argc, argv, idx, nonargs, arg + 1);
1637 static const Ecore_Getopt_Desc *
1638 _ecore_getopt_parse_find_short_other(const Ecore_Getopt *parser,
1639 const Ecore_Getopt_Desc *orig)
1641 const Ecore_Getopt_Desc *desc = parser->descs;
1642 const char c = orig->shortname;
1644 for (; !_ecore_getopt_desc_is_sentinel(desc); desc++)
1649 if (c == desc->shortname)
1656 static const Ecore_Getopt_Desc *
1657 _ecore_getopt_parse_find_long_other(const Ecore_Getopt *parser,
1658 const Ecore_Getopt_Desc *orig)
1660 const Ecore_Getopt_Desc *desc = parser->descs;
1661 const char *name = orig->longname;
1663 for (; !_ecore_getopt_desc_is_sentinel(desc); desc++)
1668 if (desc->longname && (strcmp(name, desc->longname) == 0))
1676 * Check parser for duplicate entries, print them out.
1678 * @return @c EINA_TRUE if there are duplicates, @c EINA_FALSE otherwise.
1679 * @param parser The parser to be checked.
1682 ecore_getopt_parser_has_duplicates(const Ecore_Getopt *parser)
1684 const Ecore_Getopt_Desc *desc = parser->descs;
1685 for (; !_ecore_getopt_desc_is_sentinel(desc); desc++)
1687 if (desc->shortname)
1689 const Ecore_Getopt_Desc *other;
1690 other = _ecore_getopt_parse_find_short_other(parser, desc);
1693 _ecore_getopt_desc_print_error(desc, "short name -%c already exists.", desc->shortname);
1695 if (other->longname)
1696 fprintf(stderr, " Other is --%s.\n", other->longname);
1698 fputc('\n', stderr);
1705 const Ecore_Getopt_Desc *other;
1706 other = _ecore_getopt_parse_find_long_other(parser, desc);
1709 _ecore_getopt_desc_print_error(desc, "long name --%s already exists.", desc->longname);
1711 if (other->shortname)
1712 fprintf(stderr, " Other is -%c.\n", other->shortname);
1714 fputc('\n', stderr);
1722 static const Ecore_Getopt_Desc *
1723 _ecore_getopt_find_help(const Ecore_Getopt *parser)
1725 const Ecore_Getopt_Desc *desc = parser->descs;
1726 for (; !_ecore_getopt_desc_is_sentinel(desc); desc++)
1727 if (desc->action == ECORE_GETOPT_ACTION_HELP)
1733 * Parse command line parameters.
1735 * Walks the command line parameters and parse them based on @a parser
1736 * description, doing actions based on @c parser->descs->action, like
1737 * showing help text, license, copyright, storing values in values and
1740 * It is expected that values is of the same size than @c parser->descs,
1741 * options that do not need a value it will be left untouched.
1743 * All values are expected to be initialized before use. Options with
1744 * action @c ECORE_GETOPT_ACTION_STORE and non required arguments
1745 * (others than @c ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES), are expected
1746 * to provide a value in @c def to be used.
1748 * The following actions will store @c 1 on value as a boolean
1749 * (@c value->boolp) if it's not @c NULL to indicate these actions were
1751 * - @c ECORE_GETOPT_ACTION_HELP
1752 * - @c ECORE_GETOPT_ACTION_VERSION
1753 * - @c ECORE_GETOPT_ACTION_COPYRIGHT
1754 * - @c ECORE_GETOPT_ACTION_LICENSE
1756 * Just @c ECORE_GETOPT_ACTION_APPEND will allocate memory and thus
1757 * need to be freed. For consistency between all of appended subtypes,
1758 * @c eina_list->data will contain an allocated memory with the value,
1759 * that is, for @c ECORE_GETOPT_TYPE_STR it will contain a copy of the
1760 * argument, @c ECORE_GETOPT_TYPE_INT a pointer to an allocated
1761 * integer and so on.
1763 * If parser is in strict mode (see @c Ecore_Getopt->strict), then any
1764 * error will abort parsing and @c -1 is returned. Otherwise it will try
1765 * to continue as far as possible.
1767 * This function may reorder @a argv elements.
1769 * Translation of help strings (description), metavar, usage, license
1770 * and copyright may be translated, standard/global gettext() call
1771 * will be applied on them if ecore was compiled with such support.
1773 * @param parser description of how to work.
1774 * @param values where to store values, it is assumed that this is a vector
1775 * of the same size as @c parser->descs. Values should be previously
1777 * @param argc how many elements in @a argv. If not provided it will be
1778 * retrieved with ecore_app_args_get().
1779 * @param argv command line parameters.
1781 * @return index of first non-option parameter or -1 on error.
1784 ecore_getopt_parse(const Ecore_Getopt *parser,
1785 Ecore_Getopt_Value *values,
1793 fputs(_("ERROR: no parser provided.\n"), stderr);
1798 fputs(_("ERROR: no values provided.\n"), stderr);
1802 if ((argc < 1) || (!argv))
1803 ecore_app_args_get(&argc, &argv);
1807 fputs(_("ERROR: no arguments provided.\n"), stderr);
1814 prog = parser->prog;
1816 nonargs = _ecore_getopt_parse_find_nonargs_base(parser, argc, argv);
1825 if (!_ecore_getopt_parse_arg(parser, values, argc, argv, &i, &nonargs))
1832 const Ecore_Getopt_Desc *help;
1833 fputs(_("ERROR: invalid options found."), stderr);
1835 help = _ecore_getopt_find_help(parser);
1837 fputc('\n', stderr);
1838 else if (help->longname)
1839 fprintf(stderr, _(" See --%s.\n"), help->longname);
1841 fprintf(stderr, _(" See -%c.\n"), help->shortname);
1848 * Utility to free list and nodes allocated by @a ECORE_GETOPT_ACTION_APPEND.
1850 * @param list pointer to list to be freed.
1851 * @return always @c NULL, so you can easily make your list head @c NULL.
1854 ecore_getopt_list_free(Eina_List *list)
1858 EINA_LIST_FREE(list, data)
1864 * Helper ecore_getopt callback to parse geometry (x:y:w:h).
1866 * @param parser This parameter isn't in use.
1867 * @param desc This parameter isn't in use.
1868 * @param str Geometry value
1869 * @param data This parameter isn't in use.
1870 * @param storage must be a pointer to @c Eina_Rectangle and will be used to
1871 * store the four values passed in the given string.
1872 * @return @c EINA_TRUE on success, @c EINA_FALSE on incorrect geometry value.
1874 * @c callback_data value is ignored, you can safely use @c NULL.
1877 ecore_getopt_callback_geometry_parse(const Ecore_Getopt *parser __UNUSED__,
1878 const Ecore_Getopt_Desc *desc __UNUSED__,
1880 void *data __UNUSED__,
1881 Ecore_Getopt_Value *storage)
1883 Eina_Rectangle *v = (Eina_Rectangle *)storage->ptrp;
1885 if (sscanf(str, "%d:%d:%d:%d", &v->x, &v->y, &v->w, &v->h) != 4)
1887 fprintf(stderr, _("ERROR: incorrect geometry value '%s'\n"), str);
1895 * Helper ecore_getopt callback to parse geometry size (WxH).
1897 * @param parser This parameter isn't in use.
1898 * @param desc This parameter isn't in use.
1899 * @param str size value
1900 * @param data This parameter isn't in use.
1901 * @param storage must be a pointer to @c Eina_Rectangle and will be used to
1902 * store the two values passed in the given string and @c 0 in the x and y
1904 * @return @c EINA_TRUE on success, @c EINA_FALSE on incorrect size value.
1906 * @c callback_data value is ignored, you can safely use @c NULL.
1909 ecore_getopt_callback_size_parse(const Ecore_Getopt *parser __UNUSED__,
1910 const Ecore_Getopt_Desc *desc __UNUSED__,
1912 void *data __UNUSED__,
1913 Ecore_Getopt_Value *storage)
1915 Eina_Rectangle *v = (Eina_Rectangle *)storage->ptrp;
1917 if (sscanf(str, "%dx%d", &v->w, &v->h) != 2)
1919 fprintf(stderr, _("ERROR: incorrect size value '%s'\n"), str);