getopt_long-simple.c 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. /*
  2. * Copyright (C) 2006 Rich Felker <dalias@aerifal.cx>
  3. *
  4. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  5. */
  6. #include <stddef.h>
  7. #include <getopt.h>
  8. #include <stdio.h>
  9. static int __getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly)
  10. {
  11. if (optind >= argc || !argv[optind] || argv[optind][0] != '-') return -1;
  12. if ((longonly && argv[optind][1]) ||
  13. (argv[optind][1] == '-' && argv[optind][2]))
  14. {
  15. int i;
  16. for (i=0; longopts[i].name; i++) {
  17. const char *name = longopts[i].name;
  18. char *opt = argv[optind]+2;
  19. while (*name && *name++ == *opt++);
  20. if (*name || (*opt && *opt != '=')) continue;
  21. if (*opt == '=') {
  22. if (!longopts[i].has_arg) continue;
  23. optarg = opt+1;
  24. } else {
  25. if (longopts[i].has_arg == required_argument) {
  26. if (!(optarg = argv[++optind]))
  27. return ':';
  28. } else optarg = NULL;
  29. }
  30. optind++;
  31. if (idx) *idx = i;
  32. if (longopts[i].flag) {
  33. *longopts[i].flag = longopts[i].val;
  34. return 0;
  35. }
  36. return longopts[i].val;
  37. }
  38. if (argv[optind][1] == '-') {
  39. optind++;
  40. return '?';
  41. }
  42. }
  43. return getopt(argc, argv, optstring);
  44. }
  45. int getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx)
  46. {
  47. return __getopt_long(argc, argv, optstring, longopts, idx, 0);
  48. }
  49. int getopt_long_only(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx)
  50. {
  51. return __getopt_long(argc, argv, optstring, longopts, idx, 1);
  52. }