cmd_test.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /*
  2. * Copyright 2000-2009
  3. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4. *
  5. * SPDX-License-Identifier: GPL-2.0+
  6. */
  7. /*
  8. * Define _STDBOOL_H here to avoid macro expansion of true and false.
  9. * If the future code requires macro true or false, remove this define
  10. * and undef true and false before U_BOOT_CMD. This define and comment
  11. * shall be removed if change to U_BOOT_CMD is made to take string
  12. * instead of stringifying it.
  13. */
  14. #define _STDBOOL_H
  15. #include <common.h>
  16. #include <command.h>
  17. #include <fs.h>
  18. #define OP_INVALID 0
  19. #define OP_NOT 1
  20. #define OP_OR 2
  21. #define OP_AND 3
  22. #define OP_STR_EMPTY 4
  23. #define OP_STR_NEMPTY 5
  24. #define OP_STR_EQ 6
  25. #define OP_STR_NEQ 7
  26. #define OP_STR_LT 8
  27. #define OP_STR_GT 9
  28. #define OP_INT_EQ 10
  29. #define OP_INT_NEQ 11
  30. #define OP_INT_LT 12
  31. #define OP_INT_LE 13
  32. #define OP_INT_GT 14
  33. #define OP_INT_GE 15
  34. #define OP_FILE_EXISTS 16
  35. const struct {
  36. int arg;
  37. const char *str;
  38. int op;
  39. int adv;
  40. } op_adv[] = {
  41. {1, "=", OP_STR_EQ, 3},
  42. {1, "!=", OP_STR_NEQ, 3},
  43. {1, "<", OP_STR_LT, 3},
  44. {1, ">", OP_STR_GT, 3},
  45. {1, "-eq", OP_INT_EQ, 3},
  46. {1, "-ne", OP_INT_NEQ, 3},
  47. {1, "-lt", OP_INT_LT, 3},
  48. {1, "-le", OP_INT_LE, 3},
  49. {1, "-gt", OP_INT_GT, 3},
  50. {1, "-ge", OP_INT_GE, 3},
  51. {0, "!", OP_NOT, 1},
  52. {0, "-o", OP_OR, 1},
  53. {0, "-a", OP_AND, 1},
  54. {0, "-z", OP_STR_EMPTY, 2},
  55. {0, "-n", OP_STR_NEMPTY, 2},
  56. {0, "-e", OP_FILE_EXISTS, 4},
  57. };
  58. static int do_test(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  59. {
  60. char * const *ap;
  61. int i, op, left, adv, expr, last_expr, last_unop, last_binop;
  62. /* args? */
  63. if (argc < 3)
  64. return 1;
  65. #ifdef DEBUG
  66. {
  67. debug("test(%d):", argc);
  68. left = 1;
  69. while (argv[left])
  70. debug(" '%s'", argv[left++]);
  71. }
  72. #endif
  73. left = argc - 1;
  74. ap = argv + 1;
  75. expr = 0;
  76. last_unop = OP_INVALID;
  77. last_binop = OP_INVALID;
  78. last_expr = -1;
  79. while (left > 0) {
  80. for (i = 0; i < ARRAY_SIZE(op_adv); i++) {
  81. if (left <= op_adv[i].arg)
  82. continue;
  83. if (!strcmp(ap[op_adv[i].arg], op_adv[i].str)) {
  84. op = op_adv[i].op;
  85. adv = op_adv[i].adv;
  86. break;
  87. }
  88. }
  89. if (i == ARRAY_SIZE(op_adv)) {
  90. expr = 1;
  91. break;
  92. }
  93. if (left < adv) {
  94. expr = 1;
  95. break;
  96. }
  97. switch (op) {
  98. case OP_STR_EMPTY:
  99. expr = strlen(ap[1]) == 0 ? 1 : 0;
  100. break;
  101. case OP_STR_NEMPTY:
  102. expr = strlen(ap[1]) == 0 ? 0 : 1;
  103. break;
  104. case OP_STR_EQ:
  105. expr = strcmp(ap[0], ap[2]) == 0;
  106. break;
  107. case OP_STR_NEQ:
  108. expr = strcmp(ap[0], ap[2]) != 0;
  109. break;
  110. case OP_STR_LT:
  111. expr = strcmp(ap[0], ap[2]) < 0;
  112. break;
  113. case OP_STR_GT:
  114. expr = strcmp(ap[0], ap[2]) > 0;
  115. break;
  116. case OP_INT_EQ:
  117. expr = simple_strtol(ap[0], NULL, 10) ==
  118. simple_strtol(ap[2], NULL, 10);
  119. break;
  120. case OP_INT_NEQ:
  121. expr = simple_strtol(ap[0], NULL, 10) !=
  122. simple_strtol(ap[2], NULL, 10);
  123. break;
  124. case OP_INT_LT:
  125. expr = simple_strtol(ap[0], NULL, 10) <
  126. simple_strtol(ap[2], NULL, 10);
  127. break;
  128. case OP_INT_LE:
  129. expr = simple_strtol(ap[0], NULL, 10) <=
  130. simple_strtol(ap[2], NULL, 10);
  131. break;
  132. case OP_INT_GT:
  133. expr = simple_strtol(ap[0], NULL, 10) >
  134. simple_strtol(ap[2], NULL, 10);
  135. break;
  136. case OP_INT_GE:
  137. expr = simple_strtol(ap[0], NULL, 10) >=
  138. simple_strtol(ap[2], NULL, 10);
  139. break;
  140. case OP_FILE_EXISTS:
  141. expr = file_exists(ap[1], ap[2], ap[3], FS_TYPE_ANY);
  142. break;
  143. }
  144. switch (op) {
  145. case OP_OR:
  146. last_expr = expr;
  147. last_binop = OP_OR;
  148. break;
  149. case OP_AND:
  150. last_expr = expr;
  151. last_binop = OP_AND;
  152. break;
  153. case OP_NOT:
  154. if (last_unop == OP_NOT)
  155. last_unop = OP_INVALID;
  156. else
  157. last_unop = OP_NOT;
  158. break;
  159. default:
  160. if (last_unop == OP_NOT) {
  161. expr = !expr;
  162. last_unop = OP_INVALID;
  163. }
  164. if (last_binop == OP_OR)
  165. expr = last_expr || expr;
  166. else if (last_binop == OP_AND)
  167. expr = last_expr && expr;
  168. last_binop = OP_INVALID;
  169. break;
  170. }
  171. ap += adv; left -= adv;
  172. }
  173. expr = !expr;
  174. debug (": returns %d\n", expr);
  175. return expr;
  176. }
  177. U_BOOT_CMD(
  178. test, CONFIG_SYS_MAXARGS, 1, do_test,
  179. "minimal test like /bin/sh",
  180. "[args..]"
  181. );
  182. static int do_false(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  183. {
  184. return 1;
  185. }
  186. U_BOOT_CMD(
  187. false, CONFIG_SYS_MAXARGS, 1, do_false,
  188. "do nothing, unsuccessfully",
  189. NULL
  190. );
  191. static int do_true(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  192. {
  193. return 0;
  194. }
  195. U_BOOT_CMD(
  196. true, CONFIG_SYS_MAXARGS, 1, do_true,
  197. "do nothing, successfully",
  198. NULL
  199. );