aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-12-24 18:11:41 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-12-24 18:11:41 +0100
commit79587cb442d022bf8d9e388398834270785d2049 (patch)
tree6a2c1991d568fdfc32fb10c4e27d9e644dd00989
parent65b6fe09c4c6a25090b86ec4a6abcc6ab92f767e (diff)
downloadbusybox-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.c78
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
965static NOINLINE int bc_posix_error_fmt(const char *fmt, ...) 965static 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
1018static int bc_POSIX_requires(const char *msg) 1020static 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}
1022static int bc_POSIX_does_not_allow(const char *msg) 1024#define zbc_POSIX_requires(...) (zbc_POSIX_requires(__VA_ARGS__) COMMA_SUCCESS)
1025static 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}
1026static 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)
1030static 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}
1030static 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)
1035static 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
1036static void bc_vec_grow(BcVec *v, size_t n) 1042static 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) {