options.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /* This file is part of the software similarity tester SIM.
  2. Written by Dick Grune, Vrije Universiteit, Amsterdam.
  3. $Id: options.c,v 1.3 2001/11/13 12:55:53 dick Exp $
  4. */
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include "options.h"
  8. static char options[128];
  9. static void bad_option(
  10. const char *progname, const struct option *optlist, char *msg, int c
  11. );
  12. static int opt_value(const struct option *op, const char *arg, char *argv[]);
  13. static int do_arg(
  14. const char *progname, const struct option *optlist,
  15. const char *arg, char *argv[]
  16. );
  17. int
  18. do_options(
  19. const char *progname, const struct option *optlist,
  20. int argc, char *argv[]
  21. ) {
  22. int skips = 0;
  23. while (argc > 0 && argv[0][0] == '-' && argv[0][1] != '\0') {
  24. int consumed = do_arg(progname, optlist, &argv[0][1], argv);
  25. argc -= consumed, argv += consumed, skips += consumed;
  26. }
  27. return skips;
  28. }
  29. int
  30. option_set(char ch) {
  31. return options[(int)ch];
  32. }
  33. static int
  34. do_arg(
  35. const char *progname, const struct option *optlist,
  36. const char *arg, char *argv[]
  37. ) {
  38. int consumed = 0;
  39. while (*arg) {
  40. /* treat argument character */
  41. register char opc = *arg++;
  42. register const struct option *op;
  43. for (op = optlist; op->op_char; op++) {
  44. /* for every allowed option */
  45. if (opc == op->op_char) {
  46. options[(int)opc]++;
  47. if (op->op_indicator != ' ') {
  48. consumed = opt_value(op, arg, argv);
  49. if (consumed < 0) {
  50. bad_option(progname, (struct option *)0,
  51. " option -%c requires another argument",
  52. op->op_char
  53. );
  54. /*NOTREACHED*/
  55. }
  56. }
  57. break;
  58. }
  59. }
  60. if (!op->op_char) {
  61. bad_option(progname, optlist,
  62. "*option -%c unknown", opc
  63. );
  64. /*NOTREACHED*/
  65. }
  66. if (consumed) break;
  67. }
  68. if (!consumed) {
  69. consumed = 1;
  70. }
  71. return consumed;
  72. }
  73. static int
  74. opt_value(const struct option *op, const char *arg, char *argv[]) {
  75. /* locate the option value */
  76. if (*arg) {
  77. /* argument is continuation of option */
  78. *op->op_stringp = arg;
  79. return 1;
  80. }
  81. else {
  82. /* argument follows option */
  83. if (!argv[1]) return -1;
  84. *op->op_stringp = argv[1];
  85. return 2;
  86. }
  87. }
  88. static void
  89. bad_option(
  90. const char *progname, const struct option *optlist, char *msg, int c
  91. ) {
  92. fprintf(stderr, "%s: ", progname);
  93. fprintf(stderr, &msg[1], c);
  94. fprintf(stderr, "\n");
  95. if (msg[0] != ' ') {
  96. register const struct option *op;
  97. fprintf(stderr, "Possible options are:\n");
  98. for (op = optlist; op->op_char; op++) {
  99. fprintf(stderr, "\t-%c%c\t%s\n",
  100. op->op_char, op->op_indicator, op->op_text
  101. );
  102. }
  103. }
  104. exit(1);
  105. }