getopt_long-susv3.c 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  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. libc_hidden_proto(getopt)
  10. static int __getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly)
  11. {
  12. if (optind >= argc || !argv[optind] || argv[optind][0] != '-') return -1;
  13. if ((longonly && argv[optind][1]) ||
  14. (argv[optind][1] == '-' && argv[optind][2]))
  15. {
  16. int i;
  17. char *opt = argv[optind]+2;
  18. for (i=0; longopts[i].name; i++) {
  19. const char *name = longopts[i].name;
  20. while (*name && *name++ == *opt++);
  21. if (*name && *opt != '=') continue;
  22. if (*opt == '=') {
  23. if (!longopts[i].has_arg) continue;
  24. optarg = opt+1;
  25. } else {
  26. if (longopts[i].has_arg == required_argument) {
  27. if (!(optarg = argv[++optind]))
  28. return ':';
  29. } else optarg = NULL;
  30. }
  31. optind++;
  32. if (idx) *idx = i;
  33. if (longopts[i].flag) {
  34. *longopts[i].flag = longopts[i].val;
  35. return 0;
  36. }
  37. return longopts[i].val;
  38. }
  39. if (argv[optind][1] == '-') {
  40. optind++;
  41. return '?';
  42. }
  43. }
  44. return getopt(argc, argv, optstring);
  45. }
  46. int getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx)
  47. {
  48. return __getopt_long(argc, argv, optstring, longopts, idx, 0);
  49. }
  50. int getopt_long_only(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx)
  51. {
  52. return __getopt_long(argc, argv, optstring, longopts, idx, 1);
  53. }