ptypes.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /*
  2. * Implementation of standard PTYPEs
  3. */
  4. #include <assert.h>
  5. #include <stdio.h>
  6. #include <unistd.h>
  7. #include <string.h>
  8. #include <stdlib.h>
  9. #include <errno.h>
  10. #include <faux/str.h>
  11. #include <faux/list.h>
  12. #include <faux/conv.h>
  13. #include <faux/argv.h>
  14. #include <klish/kcontext.h>
  15. #include <klish/kentry.h>
  16. /** @brief PTYPE: Consider ENTRY's name (or "value" field) as a command
  17. */
  18. int klish_ptype_COMMAND(kcontext_t *context)
  19. {
  20. const kentry_t *entry = NULL;
  21. const char *value = NULL;
  22. const char *command_name = NULL;
  23. entry = kcontext_candidate_entry(context);
  24. value = kcontext_candidate_value(context);
  25. command_name = kentry_value(entry);
  26. if (!command_name)
  27. command_name = kentry_name(entry);
  28. if (!command_name)
  29. return -1;
  30. return faux_str_casecmp(value, command_name);
  31. }
  32. /** @brief PTYPE: ENTRY's name (or "value" field) as a case sensitive command
  33. */
  34. int klish_ptype_COMMAND_CASE(kcontext_t *context)
  35. {
  36. const kentry_t *entry = NULL;
  37. const char *value = NULL;
  38. const char *command_name = NULL;
  39. entry = kcontext_candidate_entry(context);
  40. value = kcontext_candidate_value(context);
  41. command_name = kentry_value(entry);
  42. if (!command_name)
  43. command_name = kentry_name(entry);
  44. if (!command_name)
  45. return -1;
  46. return strcmp(value, command_name);
  47. }
  48. /** @brief PTYPE: Signed int with optional range
  49. *
  50. * Use long long int for conversion from text.
  51. *
  52. * <ACTION sym="INT">-30 80</ACTION>
  53. * Means range from "-30" to "80"
  54. */
  55. int klish_ptype_INT(kcontext_t *context)
  56. {
  57. const char *script = NULL;
  58. const char *value_str = NULL;
  59. long long int value = 0;
  60. script = kcontext_script(context);
  61. value_str = kcontext_candidate_value(context);
  62. if (!faux_conv_atoll(value_str, &value, 0))
  63. return -1;
  64. // Range is specified
  65. if (!faux_str_is_empty(script)) {
  66. faux_argv_t *argv = faux_argv_new();
  67. const char *str = NULL;
  68. faux_argv_parse(argv, script);
  69. // Min
  70. str = faux_argv_index(argv, 0);
  71. if (str) {
  72. long long int min = 0;
  73. if (!faux_conv_atoll(str, &min, 0) || (value < min)) {
  74. faux_argv_free(argv);
  75. return -1;
  76. }
  77. }
  78. // Max
  79. str = faux_argv_index(argv, 1);
  80. if (str) {
  81. long long int max = 0;
  82. if (!faux_conv_atoll(str, &max, 0) || (value > max)) {
  83. faux_argv_free(argv);
  84. return -1;
  85. }
  86. }
  87. faux_argv_free(argv);
  88. }
  89. return 0;
  90. }
  91. /** @brief PTYPE: Unsigned int with optional range
  92. *
  93. * Use unsigned long long int for conversion from text.
  94. *
  95. * <ACTION sym="UINT">30 80</ACTION>
  96. * Means range from "30" to "80"
  97. */
  98. int klish_ptype_UINT(kcontext_t *context)
  99. {
  100. const char *script = NULL;
  101. const char *value_str = NULL;
  102. unsigned long long int value = 0;
  103. script = kcontext_script(context);
  104. value_str = kcontext_candidate_value(context);
  105. if (!faux_conv_atoull(value_str, &value, 0))
  106. return -1;
  107. // Range is specified
  108. if (!faux_str_is_empty(script)) {
  109. faux_argv_t *argv = faux_argv_new();
  110. const char *str = NULL;
  111. faux_argv_parse(argv, script);
  112. // Min
  113. str = faux_argv_index(argv, 0);
  114. if (str) {
  115. unsigned long long int min = 0;
  116. if (!faux_conv_atoull(str, &min, 0) || (value < min)) {
  117. faux_argv_free(argv);
  118. return -1;
  119. }
  120. }
  121. // Max
  122. str = faux_argv_index(argv, 1);
  123. if (str) {
  124. unsigned long long int max = 0;
  125. if (!faux_conv_atoull(str, &max, 0) || (value > max)) {
  126. faux_argv_free(argv);
  127. return -1;
  128. }
  129. }
  130. faux_argv_free(argv);
  131. }
  132. return 0;
  133. }
  134. /** @brief PTYPE: Arbitrary string
  135. */
  136. int klish_ptype_STRING(kcontext_t *context)
  137. {
  138. // Really any string is a ... (surprise!) string
  139. context = context; // Happy compiler
  140. return 0;
  141. }