test.c 4.0 KB

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