選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

getopt.c 3.3 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /*
  2. * libcaca Colour ASCII-Art library
  3. * Copyright (c) 2002-2010 Sam Hocevar <sam@hocevar.net>
  4. * All Rights Reserved
  5. *
  6. * This program is free software. It comes without any warranty, to
  7. * the extent permitted by applicable law. You can redistribute it
  8. * and/or modify it under the terms of the Do What The Fuck You Want
  9. * To Public License, Version 2, as published by Sam Hocevar. See
  10. * http://sam.zoy.org/wtfpl/COPYING for more details.
  11. */
  12. /*
  13. * getopt.c: getopt_long reimplementation
  14. */
  15. #include "config.h"
  16. #if !defined __KERNEL__
  17. # include <stdio.h>
  18. # include <string.h>
  19. # if defined HAVE_GETOPT_H && defined HAVE_GETOPT_LONG
  20. # include <getopt.h>
  21. # endif
  22. #endif
  23. #include "caca.h"
  24. #include "caca_internals.h"
  25. int caca_optind = 1;
  26. char *caca_optarg = NULL;
  27. int caca_getopt(int argc, char * const _argv[], char const *optstring,
  28. struct caca_option const *longopts, int *longindex)
  29. {
  30. #if defined HAVE_GETOPT_LONG
  31. int ret;
  32. optind = caca_optind;
  33. optarg = caca_optarg;
  34. ret = getopt_long(argc, _argv, optstring,
  35. (struct option const *)longopts, longindex);
  36. caca_optind = optind;
  37. caca_optarg = optarg;
  38. return ret;
  39. #else
  40. /* XXX: this getopt_long implementation should not be trusted for other
  41. * applications without any serious peer reviewing. It “just works” with
  42. * zzuf and a few libcaca programs but may fail miserably in other
  43. * programs. */
  44. char **argv = (char **)(uintptr_t)_argv;
  45. char *flag;
  46. int i;
  47. if(caca_optind >= argc)
  48. return -1;
  49. flag = argv[caca_optind];
  50. if(flag[0] == '-' && flag[1] != '-')
  51. {
  52. char *tmp;
  53. int ret = flag[1];
  54. if(ret == '\0')
  55. return -1;
  56. tmp = strchr(optstring, ret);
  57. if(!tmp || ret == ':')
  58. return '?';
  59. caca_optind++;
  60. if(tmp[1] == ':')
  61. {
  62. if(flag[2] != '\0')
  63. caca_optarg = flag + 2;
  64. else
  65. caca_optarg = argv[caca_optind++];
  66. return ret;
  67. }
  68. if(flag[2] != '\0')
  69. {
  70. flag[1] = '-';
  71. caca_optind--;
  72. argv[caca_optind]++;
  73. }
  74. return ret;
  75. }
  76. if(flag[0] == '-' && flag[1] == '-')
  77. {
  78. if(flag[2] == '\0')
  79. return -1;
  80. for(i = 0; longopts[i].name; i++)
  81. {
  82. size_t l = strlen(longopts[i].name);
  83. if(strncmp(flag + 2, longopts[i].name, l))
  84. continue;
  85. switch(flag[2 + l])
  86. {
  87. case '=':
  88. if(!longopts[i].has_arg)
  89. goto bad_opt;
  90. if(longindex)
  91. *longindex = i;
  92. caca_optind++;
  93. caca_optarg = flag + 2 + l + 1;
  94. return longopts[i].val;
  95. case '\0':
  96. if(longindex)
  97. *longindex = i;
  98. caca_optind++;
  99. if(longopts[i].has_arg)
  100. caca_optarg = argv[caca_optind++];
  101. return longopts[i].val;
  102. default:
  103. break;
  104. }
  105. }
  106. bad_opt:
  107. fprintf(stderr, "%s: unrecognized option `%s'\n", argv[0], flag);
  108. return '?';
  109. }
  110. return -1;
  111. #endif
  112. }