test.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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(struct cmd_tbl *cmdtp, int flag, int argc,
  50. char *const argv[])
  51. {
  52. char * const *ap;
  53. int i, op, left, adv, expr, last_expr, last_unop, last_binop;
  54. /* args? */
  55. if (argc < 3)
  56. return 1;
  57. #ifdef DEBUG
  58. {
  59. debug("test(%d):", argc);
  60. left = 1;
  61. while (argv[left])
  62. debug(" '%s'", argv[left++]);
  63. }
  64. #endif
  65. left = argc - 1;
  66. ap = argv + 1;
  67. expr = 0;
  68. last_unop = OP_INVALID;
  69. last_binop = OP_INVALID;
  70. last_expr = -1;
  71. while (left > 0) {
  72. for (i = 0; i < ARRAY_SIZE(op_adv); i++) {
  73. if (left <= op_adv[i].arg)
  74. continue;
  75. if (!strcmp(ap[op_adv[i].arg], op_adv[i].str)) {
  76. op = op_adv[i].op;
  77. adv = op_adv[i].adv;
  78. break;
  79. }
  80. }
  81. if (i == ARRAY_SIZE(op_adv)) {
  82. expr = 1;
  83. break;
  84. }
  85. if (left < adv) {
  86. expr = 1;
  87. break;
  88. }
  89. switch (op) {
  90. case OP_STR_EMPTY:
  91. expr = strlen(ap[1]) == 0 ? 1 : 0;
  92. break;
  93. case OP_STR_NEMPTY:
  94. expr = strlen(ap[1]) == 0 ? 0 : 1;
  95. break;
  96. case OP_STR_EQ:
  97. expr = strcmp(ap[0], ap[2]) == 0;
  98. break;
  99. case OP_STR_NEQ:
  100. expr = strcmp(ap[0], ap[2]) != 0;
  101. break;
  102. case OP_STR_LT:
  103. expr = strcmp(ap[0], ap[2]) < 0;
  104. break;
  105. case OP_STR_GT:
  106. expr = strcmp(ap[0], ap[2]) > 0;
  107. break;
  108. case OP_INT_EQ:
  109. expr = simple_strtol(ap[0], NULL, 0) ==
  110. simple_strtol(ap[2], NULL, 0);
  111. break;
  112. case OP_INT_NEQ:
  113. expr = simple_strtol(ap[0], NULL, 0) !=
  114. simple_strtol(ap[2], NULL, 0);
  115. break;
  116. case OP_INT_LT:
  117. expr = simple_strtol(ap[0], NULL, 0) <
  118. simple_strtol(ap[2], NULL, 0);
  119. break;
  120. case OP_INT_LE:
  121. expr = simple_strtol(ap[0], NULL, 0) <=
  122. simple_strtol(ap[2], NULL, 0);
  123. break;
  124. case OP_INT_GT:
  125. expr = simple_strtol(ap[0], NULL, 0) >
  126. simple_strtol(ap[2], NULL, 0);
  127. break;
  128. case OP_INT_GE:
  129. expr = simple_strtol(ap[0], NULL, 0) >=
  130. simple_strtol(ap[2], NULL, 0);
  131. break;
  132. case OP_FILE_EXISTS:
  133. expr = file_exists(ap[1], ap[2], ap[3], FS_TYPE_ANY);
  134. break;
  135. }
  136. switch (op) {
  137. case OP_OR:
  138. last_expr = expr;
  139. last_binop = OP_OR;
  140. break;
  141. case OP_AND:
  142. last_expr = expr;
  143. last_binop = OP_AND;
  144. break;
  145. case OP_NOT:
  146. if (last_unop == OP_NOT)
  147. last_unop = OP_INVALID;
  148. else
  149. last_unop = OP_NOT;
  150. break;
  151. default:
  152. if (last_unop == OP_NOT) {
  153. expr = !expr;
  154. last_unop = OP_INVALID;
  155. }
  156. if (last_binop == OP_OR)
  157. expr = last_expr || expr;
  158. else if (last_binop == OP_AND)
  159. expr = last_expr && expr;
  160. last_binop = OP_INVALID;
  161. break;
  162. }
  163. ap += adv; left -= adv;
  164. }
  165. expr = !expr;
  166. debug (": returns %d\n", expr);
  167. return expr;
  168. }
  169. #undef true
  170. #undef false
  171. U_BOOT_CMD(
  172. test, CONFIG_SYS_MAXARGS, 1, do_test,
  173. "minimal test like /bin/sh",
  174. "[args..]"
  175. );
  176. static int do_false(struct cmd_tbl *cmdtp, int flag, int argc,
  177. char *const argv[])
  178. {
  179. return 1;
  180. }
  181. U_BOOT_CMD(
  182. false, CONFIG_SYS_MAXARGS, 1, do_false,
  183. "do nothing, unsuccessfully",
  184. NULL
  185. );
  186. static int do_true(struct cmd_tbl *cmdtp, int flag, int argc,
  187. char *const argv[])
  188. {
  189. return 0;
  190. }
  191. U_BOOT_CMD(
  192. true, CONFIG_SYS_MAXARGS, 1, do_true,
  193. "do nothing, successfully",
  194. NULL
  195. );