test.c 4.0 KB

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