diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-24 18:11:41 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-24 18:11:41 +0100 |
commit | 79587cb442d022bf8d9e388398834270785d2049 (patch) | |
tree | 6a2c1991d568fdfc32fb10c4e27d9e644dd00989 | |
parent | 65b6fe09c4c6a25090b86ec4a6abcc6ab92f767e (diff) | |
download | busybox-w32-79587cb442d022bf8d9e388398834270785d2049.tar.gz busybox-w32-79587cb442d022bf8d9e388398834270785d2049.tar.bz2 busybox-w32-79587cb442d022bf8d9e388398834270785d2049.zip |
bc: POSIX error/warn functions can be 'z' functions too
In non-interactive config, they either return 'success', or do not return.
function old new delta
zbc_posix_error_fmt 41 39 -2
bc_parse_expr_empty_ok 1751 1744 -7
zbc_parse_stmt_possibly_auto 1322 1314 -8
------------------------------------------------------------------------------
(add/remove: 5/5 grow/shrink: 0/2 up/down: 118/-135) Total: -17 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | miscutils/bc.c | 78 |
1 files changed, 42 insertions, 36 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index 4fac2c99a..12bc80b3e 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
@@ -962,13 +962,13 @@ static NOINLINE ERRORFUNC int bc_error_fmt(const char *fmt, ...) | |||
962 | } | 962 | } |
963 | 963 | ||
964 | #if ENABLE_BC | 964 | #if ENABLE_BC |
965 | static NOINLINE int bc_posix_error_fmt(const char *fmt, ...) | 965 | static NOINLINE BC_STATUS zbc_posix_error_fmt(const char *fmt, ...) |
966 | { | 966 | { |
967 | va_list p; | 967 | va_list p; |
968 | 968 | ||
969 | // Are non-POSIX constructs totally ok? | 969 | // Are non-POSIX constructs totally ok? |
970 | if (!(option_mask32 & (BC_FLAG_S|BC_FLAG_W))) | 970 | if (!(option_mask32 & (BC_FLAG_S|BC_FLAG_W))) |
971 | return BC_STATUS_SUCCESS; // yes | 971 | RETURN_STATUS(BC_STATUS_SUCCESS); // yes |
972 | 972 | ||
973 | va_start(p, fmt); | 973 | va_start(p, fmt); |
974 | bc_verror_msg(fmt, p); | 974 | bc_verror_msg(fmt, p); |
@@ -976,11 +976,13 @@ static NOINLINE int bc_posix_error_fmt(const char *fmt, ...) | |||
976 | 976 | ||
977 | // Do we treat non-POSIX constructs as errors? | 977 | // Do we treat non-POSIX constructs as errors? |
978 | if (!(option_mask32 & BC_FLAG_S)) | 978 | if (!(option_mask32 & BC_FLAG_S)) |
979 | return BC_STATUS_SUCCESS; // no, it's a warning | 979 | RETURN_STATUS(BC_STATUS_SUCCESS); // no, it's a warning |
980 | |||
980 | if (ENABLE_FEATURE_CLEAN_UP || G_ttyin) | 981 | if (ENABLE_FEATURE_CLEAN_UP || G_ttyin) |
981 | return BC_STATUS_FAILURE; | 982 | RETURN_STATUS(BC_STATUS_FAILURE); |
982 | exit(1); | 983 | exit(1); |
983 | } | 984 | } |
985 | #define zbc_posix_error_fmt(...) (zbc_posix_error_fmt(__VA_ARGS__) COMMA_SUCCESS) | ||
984 | #endif | 986 | #endif |
985 | 987 | ||
986 | // We use error functions with "return bc_error(FMT[, PARAMS])" idiom. | 988 | // We use error functions with "return bc_error(FMT[, PARAMS])" idiom. |
@@ -1015,22 +1017,26 @@ static ERRORFUNC int bc_error_variable_is_wrong_type(void) | |||
1015 | IF_ERROR_RETURN_POSSIBLE(return) bc_error("variable is wrong type"); | 1017 | IF_ERROR_RETURN_POSSIBLE(return) bc_error("variable is wrong type"); |
1016 | } | 1018 | } |
1017 | #if ENABLE_BC | 1019 | #if ENABLE_BC |
1018 | static int bc_POSIX_requires(const char *msg) | 1020 | static BC_STATUS zbc_POSIX_requires(const char *msg) |
1019 | { | 1021 | { |
1020 | return bc_posix_error_fmt("POSIX requires %s", msg); | 1022 | RETURN_STATUS(zbc_posix_error_fmt("POSIX requires %s", msg)); |
1021 | } | 1023 | } |
1022 | static int bc_POSIX_does_not_allow(const char *msg) | 1024 | #define zbc_POSIX_requires(...) (zbc_POSIX_requires(__VA_ARGS__) COMMA_SUCCESS) |
1025 | static BC_STATUS zbc_POSIX_does_not_allow(const char *msg) | ||
1023 | { | 1026 | { |
1024 | return bc_posix_error_fmt("%s%s", "POSIX does not allow ", msg); | 1027 | RETURN_STATUS(zbc_posix_error_fmt("%s%s", "POSIX does not allow ", msg)); |
1025 | } | 1028 | } |
1026 | static int bc_POSIX_does_not_allow_bool_ops_this_is_bad(const char *msg) | 1029 | #define zbc_POSIX_does_not_allow(...) (zbc_POSIX_does_not_allow(__VA_ARGS__) COMMA_SUCCESS) |
1030 | static BC_STATUS zbc_POSIX_does_not_allow_bool_ops_this_is_bad(const char *msg) | ||
1027 | { | 1031 | { |
1028 | return bc_posix_error_fmt("%s%s %s", "POSIX does not allow ", "boolean operators; the following is bad:", msg); | 1032 | RETURN_STATUS(zbc_posix_error_fmt("%s%s %s", "POSIX does not allow ", "boolean operators; the following is bad:", msg)); |
1029 | } | 1033 | } |
1030 | static int bc_POSIX_does_not_allow_empty_X_expression_in_for(const char *msg) | 1034 | #define zbc_POSIX_does_not_allow_bool_ops_this_is_bad(...) (zbc_POSIX_does_not_allow_bool_ops_this_is_bad(__VA_ARGS__) COMMA_SUCCESS) |
1035 | static BC_STATUS zbc_POSIX_does_not_allow_empty_X_expression_in_for(const char *msg) | ||
1031 | { | 1036 | { |
1032 | return bc_posix_error_fmt("%san empty %s expression in a for loop", "POSIX does not allow ", msg); | 1037 | RETURN_STATUS(zbc_posix_error_fmt("%san empty %s expression in a for loop", "POSIX does not allow ", msg)); |
1033 | } | 1038 | } |
1039 | #define zbc_POSIX_does_not_allow_empty_X_expression_in_for(...) (zbc_POSIX_does_not_allow_empty_X_expression_in_for(__VA_ARGS__) COMMA_SUCCESS) | ||
1034 | #endif | 1040 | #endif |
1035 | 1041 | ||
1036 | static void bc_vec_grow(BcVec *v, size_t n) | 1042 | static void bc_vec_grow(BcVec *v, size_t n) |
@@ -3054,8 +3060,8 @@ static BC_STATUS zbc_lex_identifier(BcLex *l) | |||
3054 | continue; // "ifz" does not match "if" keyword, "if." does | 3060 | continue; // "ifz" does not match "if" keyword, "if." does |
3055 | l->t.t = BC_LEX_KEY_1st_keyword + i; | 3061 | l->t.t = BC_LEX_KEY_1st_keyword + i; |
3056 | if (!bc_lex_kws_POSIX(i)) { | 3062 | if (!bc_lex_kws_POSIX(i)) { |
3057 | s = bc_posix_error_fmt("%sthe '%.8s' keyword", "POSIX does not allow ", bc_lex_kws[i].name8); | 3063 | s = zbc_posix_error_fmt("%sthe '%.8s' keyword", "POSIX does not allow ", bc_lex_kws[i].name8); |
3058 | IF_ERROR_RETURN_POSSIBLE(if (s) RETURN_STATUS(s)); | 3064 | if (s) RETURN_STATUS(s); |
3059 | } | 3065 | } |
3060 | 3066 | ||
3061 | // We minus 1 because the index has already been incremented. | 3067 | // We minus 1 because the index has already been incremented. |
@@ -3072,7 +3078,7 @@ static BC_STATUS zbc_lex_identifier(BcLex *l) | |||
3072 | // bc: POSIX only allows one character names; the following is bad: 'qwe=1 | 3078 | // bc: POSIX only allows one character names; the following is bad: 'qwe=1 |
3073 | // ' | 3079 | // ' |
3074 | unsigned len = strchrnul(buf, '\n') - buf; | 3080 | unsigned len = strchrnul(buf, '\n') - buf; |
3075 | s = bc_posix_error_fmt("POSIX only allows one character names; the following is bad: '%.*s'", len, buf); | 3081 | s = zbc_posix_error_fmt("POSIX only allows one character names; the following is bad: '%.*s'", len, buf); |
3076 | } | 3082 | } |
3077 | 3083 | ||
3078 | RETURN_STATUS(s); | 3084 | RETURN_STATUS(s); |
@@ -3184,16 +3190,16 @@ static BC_STATUS zbc_lex_token(BcLex *l) | |||
3184 | case '!': | 3190 | case '!': |
3185 | bc_lex_assign(l, XC_LEX_OP_REL_NE, BC_LEX_OP_BOOL_NOT); | 3191 | bc_lex_assign(l, XC_LEX_OP_REL_NE, BC_LEX_OP_BOOL_NOT); |
3186 | if (l->t.t == BC_LEX_OP_BOOL_NOT) { | 3192 | if (l->t.t == BC_LEX_OP_BOOL_NOT) { |
3187 | s = bc_POSIX_does_not_allow_bool_ops_this_is_bad("!"); | 3193 | s = zbc_POSIX_does_not_allow_bool_ops_this_is_bad("!"); |
3188 | IF_ERROR_RETURN_POSSIBLE(if (s) RETURN_STATUS(s)); | 3194 | if (s) RETURN_STATUS(s); |
3189 | } | 3195 | } |
3190 | break; | 3196 | break; |
3191 | case '"': | 3197 | case '"': |
3192 | s = zbc_lex_string(l); | 3198 | s = zbc_lex_string(l); |
3193 | break; | 3199 | break; |
3194 | case '#': | 3200 | case '#': |
3195 | s = bc_POSIX_does_not_allow("'#' script comments"); | 3201 | s = zbc_POSIX_does_not_allow("'#' script comments"); |
3196 | IF_ERROR_RETURN_POSSIBLE(if (s) RETURN_STATUS(s)); | 3202 | if (s) RETURN_STATUS(s); |
3197 | bc_lex_lineComment(l); | 3203 | bc_lex_lineComment(l); |
3198 | break; | 3204 | break; |
3199 | case '%': | 3205 | case '%': |
@@ -3202,8 +3208,8 @@ static BC_STATUS zbc_lex_token(BcLex *l) | |||
3202 | case '&': | 3208 | case '&': |
3203 | c2 = l->buf[l->i]; | 3209 | c2 = l->buf[l->i]; |
3204 | if (c2 == '&') { | 3210 | if (c2 == '&') { |
3205 | s = bc_POSIX_does_not_allow_bool_ops_this_is_bad("&&"); | 3211 | s = zbc_POSIX_does_not_allow_bool_ops_this_is_bad("&&"); |
3206 | IF_ERROR_RETURN_POSSIBLE(if (s) RETURN_STATUS(s)); | 3212 | if (s) RETURN_STATUS(s); |
3207 | ++l->i; | 3213 | ++l->i; |
3208 | l->t.t = BC_LEX_OP_BOOL_AND; | 3214 | l->t.t = BC_LEX_OP_BOOL_AND; |
3209 | } else { | 3215 | } else { |
@@ -3242,7 +3248,7 @@ static BC_STATUS zbc_lex_token(BcLex *l) | |||
3242 | s = zbc_lex_number(l, c); | 3248 | s = zbc_lex_number(l, c); |
3243 | else { | 3249 | else { |
3244 | l->t.t = BC_LEX_KEY_LAST; | 3250 | l->t.t = BC_LEX_KEY_LAST; |
3245 | s = bc_POSIX_does_not_allow("a period ('.') as a shortcut for the last result"); | 3251 | s = zbc_POSIX_does_not_allow("a period ('.') as a shortcut for the last result"); |
3246 | } | 3252 | } |
3247 | break; | 3253 | break; |
3248 | case '/': | 3254 | case '/': |
@@ -3331,8 +3337,8 @@ static BC_STATUS zbc_lex_token(BcLex *l) | |||
3331 | case '|': | 3337 | case '|': |
3332 | c2 = l->buf[l->i]; | 3338 | c2 = l->buf[l->i]; |
3333 | if (c2 == '|') { | 3339 | if (c2 == '|') { |
3334 | s = bc_POSIX_does_not_allow_bool_ops_this_is_bad("||"); | 3340 | s = zbc_POSIX_does_not_allow_bool_ops_this_is_bad("||"); |
3335 | IF_ERROR_RETURN_POSSIBLE(if (s) RETURN_STATUS(s)); | 3341 | if (s) RETURN_STATUS(s); |
3336 | ++l->i; | 3342 | ++l->i; |
3337 | l->t.t = BC_LEX_OP_BOOL_OR; | 3343 | l->t.t = BC_LEX_OP_BOOL_OR; |
3338 | } else { | 3344 | } else { |
@@ -4116,8 +4122,8 @@ static BC_STATUS zbc_parse_return(BcParse *p) | |||
4116 | if (s) RETURN_STATUS(s); | 4122 | if (s) RETURN_STATUS(s); |
4117 | 4123 | ||
4118 | if (!paren || p->l.t.last != BC_LEX_RPAREN) { | 4124 | if (!paren || p->l.t.last != BC_LEX_RPAREN) { |
4119 | s = bc_POSIX_requires("parentheses around return expressions"); | 4125 | s = zbc_POSIX_requires("parentheses around return expressions"); |
4120 | IF_ERROR_RETURN_POSSIBLE(if (s) RETURN_STATUS(s)); | 4126 | if (s) RETURN_STATUS(s); |
4121 | } | 4127 | } |
4122 | 4128 | ||
4123 | bc_parse_push(p, XC_INST_RET); | 4129 | bc_parse_push(p, XC_INST_RET); |
@@ -4243,8 +4249,8 @@ static BC_STATUS zbc_parse_for(BcParse *p) | |||
4243 | bc_parse_push(p, XC_INST_POP); | 4249 | bc_parse_push(p, XC_INST_POP); |
4244 | if (s) RETURN_STATUS(s); | 4250 | if (s) RETURN_STATUS(s); |
4245 | } else { | 4251 | } else { |
4246 | s = bc_POSIX_does_not_allow_empty_X_expression_in_for("init"); | 4252 | s = zbc_POSIX_does_not_allow_empty_X_expression_in_for("init"); |
4247 | IF_ERROR_RETURN_POSSIBLE(if (s) RETURN_STATUS(s);) | 4253 | if (s) RETURN_STATUS(s); |
4248 | } | 4254 | } |
4249 | 4255 | ||
4250 | if (p->l.t.t != BC_LEX_SCOLON) RETURN_STATUS(bc_error_bad_token()); | 4256 | if (p->l.t.t != BC_LEX_SCOLON) RETURN_STATUS(bc_error_bad_token()); |
@@ -4264,7 +4270,7 @@ static BC_STATUS zbc_parse_for(BcParse *p) | |||
4264 | // which has no string requirement. | 4270 | // which has no string requirement. |
4265 | bc_vec_string(&p->l.t.v, 1, "1"); | 4271 | bc_vec_string(&p->l.t.v, 1, "1"); |
4266 | bc_parse_pushNUM(p); | 4272 | bc_parse_pushNUM(p); |
4267 | s = bc_POSIX_does_not_allow_empty_X_expression_in_for("condition"); | 4273 | s = zbc_POSIX_does_not_allow_empty_X_expression_in_for("condition"); |
4268 | } | 4274 | } |
4269 | if (s) RETURN_STATUS(s); | 4275 | if (s) RETURN_STATUS(s); |
4270 | 4276 | ||
@@ -4285,8 +4291,8 @@ static BC_STATUS zbc_parse_for(BcParse *p) | |||
4285 | if (p->l.t.t != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token()); | 4291 | if (p->l.t.t != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token()); |
4286 | bc_parse_push(p, XC_INST_POP); | 4292 | bc_parse_push(p, XC_INST_POP); |
4287 | } else { | 4293 | } else { |
4288 | s = bc_POSIX_does_not_allow_empty_X_expression_in_for("update"); | 4294 | s = zbc_POSIX_does_not_allow_empty_X_expression_in_for("update"); |
4289 | IF_ERROR_RETURN_POSSIBLE(if (s) RETURN_STATUS(s);) | 4295 | if (s) RETURN_STATUS(s); |
4290 | } | 4296 | } |
4291 | 4297 | ||
4292 | bc_parse_pushJUMP(p, cond_idx); | 4298 | bc_parse_pushJUMP(p, cond_idx); |
@@ -4421,7 +4427,7 @@ static BC_STATUS zbc_parse_funcdef(BcParse *p) | |||
4421 | if (s) RETURN_STATUS(s); | 4427 | if (s) RETURN_STATUS(s); |
4422 | 4428 | ||
4423 | if (p->l.t.t != BC_LEX_LBRACE) | 4429 | if (p->l.t.t != BC_LEX_LBRACE) |
4424 | s = bc_POSIX_requires("the left brace be on the same line as the function header"); | 4430 | s = zbc_POSIX_requires("the left brace be on the same line as the function header"); |
4425 | 4431 | ||
4426 | // Prevent "define z()<newline>" from being interpreted as function with empty stmt as body | 4432 | // Prevent "define z()<newline>" from being interpreted as function with empty stmt as body |
4427 | s = zbc_lex_skip_if_at_NLINE(&p->l); | 4433 | s = zbc_lex_skip_if_at_NLINE(&p->l); |
@@ -4824,11 +4830,11 @@ static BcStatus bc_parse_expr_empty_ok(BcParse *p, uint8_t flags) | |||
4824 | return bc_error_bad_expression(); | 4830 | return bc_error_bad_expression(); |
4825 | 4831 | ||
4826 | if (!(flags & BC_PARSE_REL) && nrelops) { | 4832 | if (!(flags & BC_PARSE_REL) && nrelops) { |
4827 | s = bc_POSIX_does_not_allow("comparison operators outside if or loops"); | 4833 | s = zbc_POSIX_does_not_allow("comparison operators outside if or loops"); |
4828 | IF_ERROR_RETURN_POSSIBLE(if (s) return s); | 4834 | if (s) return s; |
4829 | } else if ((flags & BC_PARSE_REL) && nrelops > 1) { | 4835 | } else if ((flags & BC_PARSE_REL) && nrelops > 1) { |
4830 | s = bc_POSIX_requires("exactly one comparison operator per condition"); | 4836 | s = zbc_POSIX_requires("exactly one comparison operator per condition"); |
4831 | IF_ERROR_RETURN_POSSIBLE(if (s) return s); | 4837 | if (s) return s; |
4832 | } | 4838 | } |
4833 | 4839 | ||
4834 | if (flags & BC_PARSE_PRINT) { | 4840 | if (flags & BC_PARSE_PRINT) { |