getopt.c 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. #include <unistd.h>
  2. #include <wchar.h>
  3. #include <string.h>
  4. #include <limits.h>
  5. #include <stdlib.h>
  6. #include "libc.h"
  7. char *optarg;
  8. int optind=1, opterr=1, optopt, __optpos, __optreset=0;
  9. #define optpos __optpos
  10. weak_alias(__optreset, optreset);
  11. int getopt(int argc, char * const argv[], const char *optstring)
  12. {
  13. int i;
  14. wchar_t c, d;
  15. int k, l;
  16. char *optchar;
  17. if (!optind || __optreset) {
  18. __optreset = 0;
  19. __optpos = 0;
  20. optind = 1;
  21. }
  22. if (optind >= argc || !argv[optind] || argv[optind][0] != '-' || !argv[optind][1])
  23. return -1;
  24. if (argv[optind][1] == '-' && !argv[optind][2])
  25. return optind++, -1;
  26. if (!optpos) optpos++;
  27. if ((k = mbtowc(&c, argv[optind]+optpos, MB_LEN_MAX)) < 0) {
  28. k = 1;
  29. c = 0xfffd; /* replacement char */
  30. }
  31. optchar = argv[optind]+optpos;
  32. optopt = c;
  33. optpos += k;
  34. if (!argv[optind][optpos]) {
  35. optind++;
  36. optpos = 0;
  37. }
  38. for (i=0; (l = mbtowc(&d, optstring+i, MB_LEN_MAX)) && d!=c; i+=l>0?l:1);
  39. if (d != c) {
  40. if (optstring[0] != ':' && opterr) {
  41. write(2, argv[0], strlen(argv[0]));
  42. write(2, ": illegal option: ", 18);
  43. write(2, optchar, k);
  44. write(2, "\n", 1);
  45. }
  46. return '?';
  47. }
  48. if (optstring[i+1] == ':') {
  49. if (optind >= argc) {
  50. if (optstring[0] == ':') return ':';
  51. if (opterr) {
  52. write(2, argv[0], strlen(argv[0]));
  53. write(2, ": option requires an argument: ", 31);
  54. write(2, optchar, k);
  55. write(2, "\n", 1);
  56. }
  57. return '?';
  58. }
  59. optarg = argv[optind++] + optpos;
  60. optpos = 0;
  61. }
  62. return c;
  63. }