Fix #117783: Allow Multiple Negatives in Numerical Inputs with Units
Support multiple unary operators before a number where only a single negative value worked in the past. Ref !117827.
This commit is contained in:
parent
72d324bd81
commit
c527056f0c
|
@ -1844,6 +1844,18 @@ static bool ch_is_op(char op)
|
|||
}
|
||||
}
|
||||
|
||||
static bool ch_is_op_unary(char op)
|
||||
{
|
||||
switch (op) {
|
||||
case '+':
|
||||
case '-':
|
||||
case '~':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for #unit_distribute_negatives to find the next negative to distribute.
|
||||
*
|
||||
|
@ -1912,6 +1924,18 @@ static char *find_next_op(const char *str, char *remaining_str, int remaining_st
|
|||
return remaining_str + i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip over multiple successive unary operators (typically `-`), skipping spaces.
|
||||
* This allows for `--90d` to be handled properly, see: #117783.
|
||||
*/
|
||||
static char *skip_unary_op(char *str)
|
||||
{
|
||||
while (*str == ' ' || ch_is_op_unary(*str)) {
|
||||
str++;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Put parentheses around blocks of values after negative signs to get rid of an implied "+"
|
||||
* between numbers without an operation between them. For example:
|
||||
|
@ -1937,8 +1961,9 @@ static bool unit_distribute_negatives(char *str, const int str_maxncpy)
|
|||
memmove(remaining_str + 1, remaining_str, remaining_str_maxncpy - 2);
|
||||
*remaining_str = '(';
|
||||
|
||||
/* Add the ')' before the next operation or at the end. */
|
||||
remaining_str = find_next_op(str, remaining_str + 1, remaining_str_maxncpy);
|
||||
/* Add the ')' before the next operation or at the end.
|
||||
* Unary operators are skipped to allow `--` to be a supported prefix. */
|
||||
remaining_str = find_next_op(str, skip_unary_op(remaining_str + 1), remaining_str_maxncpy);
|
||||
remaining_str_maxncpy = str_maxncpy - int(remaining_str - str);
|
||||
memmove(remaining_str + 1, remaining_str, remaining_str_maxncpy - 2);
|
||||
*remaining_str = ')';
|
||||
|
|
|
@ -29,6 +29,24 @@ class UnitsTesting(unittest.TestCase):
|
|||
('METRIC', 'LENGTH', "", "1+1ft", 1.3048), # no metric units, we default to meters.
|
||||
('IMPERIAL', 'LENGTH', "", "3+1in+1ft", 0.3048 * 4 + 0.0254), # bigger unit becomes default one!
|
||||
('IMPERIAL', 'LENGTH', "", "(3+1)in+1ft", 0.3048 + 0.0254 * 4),
|
||||
|
||||
# Support successive leading unary operators.
|
||||
('IMPERIAL', 'LENGTH', "", "-1ft", -0.3048),
|
||||
('IMPERIAL', 'LENGTH', "", "--1ft", --0.3048),
|
||||
('IMPERIAL', 'LENGTH', "", "---1ft", ---0.3048),
|
||||
|
||||
('IMPERIAL', 'LENGTH', "", "- 1ft", -0.3048),
|
||||
('IMPERIAL', 'LENGTH', "", "- - 1ft", --0.3048),
|
||||
('IMPERIAL', 'LENGTH', "", "- - - 1ft", ---0.3048),
|
||||
|
||||
('IMPERIAL', 'LENGTH', "", "-+1ft", -+0.3048),
|
||||
('IMPERIAL', 'LENGTH', "", "+-1ft", +-0.3048),
|
||||
|
||||
('METRIC', 'LENGTH', "", "~+-32m", ~+-32),
|
||||
('METRIC', 'LENGTH', "", "-+~32m", -+~32),
|
||||
|
||||
('METRIC', 'LENGTH', "", "~ + - 32m", ~+-32),
|
||||
('METRIC', 'LENGTH', "", "- + ~ 32m", -+~32),
|
||||
)
|
||||
|
||||
# From 'internal' Blender value to user-friendly printing
|
||||
|
|
Loading…
Reference in New Issue