ptypes.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  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. */
  19. int klish_ptype_COMMAND(kcontext_t *context)
  20. {
  21. const kentry_t *entry = NULL;
  22. const char *value = NULL;
  23. const char *command_name = NULL;
  24. entry = kcontext_candidate_entry(context);
  25. value = kcontext_candidate_value(context);
  26. command_name = kentry_value(entry);
  27. if (!command_name)
  28. command_name = kentry_name(entry);
  29. if (!command_name)
  30. return -1;
  31. return faux_str_casecmp(value, command_name);
  32. }
  33. /** @brief PTYPE: ENTRY's name (or "value" field) as a case sensitive command
  34. *
  35. */
  36. int klish_ptype_COMMAND_CASE(kcontext_t *context)
  37. {
  38. const kentry_t *entry = NULL;
  39. const char *value = NULL;
  40. const char *command_name = NULL;
  41. entry = kcontext_candidate_entry(context);
  42. value = kcontext_candidate_value(context);
  43. command_name = kentry_value(entry);
  44. if (!command_name)
  45. command_name = kentry_name(entry);
  46. if (!command_name)
  47. return -1;
  48. return strcmp(value, command_name);
  49. }
  50. /** @brief Signed int with optional range
  51. *
  52. * Use long long int for conversion from text.
  53. *
  54. * <ACTION sym="INT">-30 80</ACTION>
  55. * Means range from "-30" to "80"
  56. */
  57. int klish_ptype_INT(kcontext_t *context)
  58. {
  59. const char *script = NULL;
  60. const char *value_str = NULL;
  61. long long int value = 0;
  62. script = kcontext_script(context);
  63. value_str = kcontext_candidate_value(context);
  64. if (!faux_conv_atoll(value_str, &value, 0))
  65. return -1;
  66. // Range is specified
  67. if (!faux_str_is_empty(script)) {
  68. faux_argv_t *argv = faux_argv_new();
  69. const char *str = NULL;
  70. faux_argv_parse(argv, script);
  71. // Min
  72. str = faux_argv_index(argv, 0);
  73. if (str) {
  74. long long int min = 0;
  75. if (!faux_conv_atoll(str, &min, 0) || (value < min)) {
  76. faux_argv_free(argv);
  77. return -1;
  78. }
  79. }
  80. // Max
  81. str = faux_argv_index(argv, 1);
  82. if (str) {
  83. long long int max = 0;
  84. if (!faux_conv_atoll(str, &max, 0) || (value > max)) {
  85. faux_argv_free(argv);
  86. return -1;
  87. }
  88. }
  89. faux_argv_free(argv);
  90. }
  91. return 0;
  92. }
  93. /** @brief Unsigned int with optional range
  94. *
  95. * Use unsigned long long int for conversion from text.
  96. *
  97. * <ACTION sym="UINT">30 80</ACTION>
  98. * Means range from "30" to "80"
  99. */
  100. int klish_ptype_UINT(kcontext_t *context)
  101. {
  102. const char *script = NULL;
  103. const char *value_str = NULL;
  104. unsigned long long int value = 0;
  105. script = kcontext_script(context);
  106. value_str = kcontext_candidate_value(context);
  107. if (!faux_conv_atoull(value_str, &value, 0))
  108. return -1;
  109. // Range is specified
  110. if (!faux_str_is_empty(script)) {
  111. faux_argv_t *argv = faux_argv_new();
  112. const char *str = NULL;
  113. faux_argv_parse(argv, script);
  114. // Min
  115. str = faux_argv_index(argv, 0);
  116. if (str) {
  117. unsigned long long int min = 0;
  118. if (!faux_conv_atoull(str, &min, 0) || (value < min)) {
  119. faux_argv_free(argv);
  120. return -1;
  121. }
  122. }
  123. // Max
  124. str = faux_argv_index(argv, 1);
  125. if (str) {
  126. unsigned long long int max = 0;
  127. if (!faux_conv_atoull(str, &max, 0) || (value > max)) {
  128. faux_argv_free(argv);
  129. return -1;
  130. }
  131. }
  132. faux_argv_free(argv);
  133. }
  134. return 0;
  135. }