Fix T47661: cm (centimeter) unit breaks m (meter) unit in Metric.
authorBastien Montagne <montagne29@wanadoo.fr>
Wed, 2 Mar 2016 16:57:03 +0000 (17:57 +0100)
committerBastien Montagne <montagne29@wanadoo.fr>
Wed, 2 Mar 2016 17:02:19 +0000 (18:02 +0100)
`m` unit when used after `cm`/`mm`/etc. ones would get ignored, and the alt version of miles
would be used instead.

The root of the issue is that, in `unit_find_str`, once we get a 'hit' for a unit, we check
it's actual unit (since 'm' would also hit on 'cm', 'mm', etc.). In case that hit is not a
valid unit one, we would just return NULL, breaking the cycle of checks over that unit, and
hence missing all later usages of it.

So now, in case we have an 'invalid unit hit', we immediately retry to find it within remaining string.

source/blender/blenkernel/intern/unit.c

index e0f21201c786a7abffa67a9cf2a45c95b38bd053..e3ea5b9ba3f526697ad48597bf510c2e042a4faa 100644 (file)
@@ -460,29 +460,33 @@ BLI_INLINE bool isalpha_or_utf8(const int ch)
 
 static const char *unit_find_str(const char *str, const char *substr)
 {
-       const char *str_found;
-
        if (substr && substr[0] != '\0') {
-               str_found = strstr(str, substr);
-               if (str_found) {
-                       /* previous char cannot be a letter */
-                       if (str_found == str ||
-                           /* weak unicode support!, so "µm" won't match up be replaced by "m"
-                            * since non ascii utf8 values will NEVER return true */
-                           isalpha_or_utf8(*BLI_str_prev_char_utf8(str_found)) == 0)
-                       {
-                               /* next char cannot be alphanum */
-                               int len_name = strlen(substr);
-
-                               if (!isalpha_or_utf8(*(str_found + len_name))) {
-                                       return str_found;
+               while (true) {
+                       const char *str_found = strstr(str, substr);
+
+                       if (str_found) {
+                               /* Previous char cannot be a letter. */
+                               if (str_found == str ||
+                                       /* weak unicode support!, so "µm" won't match up be replaced by "m"
+                                        * since non ascii utf8 values will NEVER return true */
+                                       isalpha_or_utf8(*BLI_str_prev_char_utf8(str_found)) == 0)
+                               {
+                                       /* next char cannot be alphanum */
+                                       int len_name = strlen(substr);
+
+                                       if (!isalpha_or_utf8(*(str_found + len_name))) {
+                                               return str_found;
+                                       }
                                }
+                               /* If str_found is not a valid unit, we have to check further in the string... */
+                               str = str_found + 1;
+                       }
+                       else {
+                               break;
                        }
                }
-
        }
        return NULL;
-
 }
 
 /* Note that numbers are added within brackets