Revision: 22435
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=22435
Author:   campbellbarton
Date:     2009-08-13 19:05:27 +0200 (Thu, 13 Aug 2009)

Log Message:
-----------
added string max length option for unit functions bUnit_AsString and 
bUnit_ReplaceString

Modified Paths:
--------------
    branches/blender2.5/blender/source/blender/blenkernel/BKE_unit.h
    branches/blender2.5/blender/source/blender/blenkernel/intern/unit.c
    branches/blender2.5/blender/source/blender/editors/interface/interface.c
    branches/blender2.5/blender/source/blender/editors/transform/transform.c

Modified: branches/blender2.5/blender/source/blender/blenkernel/BKE_unit.h
===================================================================
--- branches/blender2.5/blender/source/blender/blenkernel/BKE_unit.h    
2009-08-13 16:59:52 UTC (rev 22434)
+++ branches/blender2.5/blender/source/blender/blenkernel/BKE_unit.h    
2009-08-13 17:05:27 UTC (rev 22435)
@@ -31,10 +31,10 @@
 /* in all cases the value is assumed to be scaled by the user preference */
 
 /* humanly readable representation of a value in units (used for button 
drawing) */
-void   bUnit_AsString(char *str, double value, int prec, int system, int type, 
int split, int pad);
+void   bUnit_AsString(char *str, int len_max, double value, int prec, int 
system, int type, int split, int pad);
 
 /* replace units with values, used before python button evaluation */
-int            bUnit_ReplaceString(char *str, char *str_orig, char *str_prev, 
double scale_pref, int system, int type);
+int            bUnit_ReplaceString(char *str, int len_max, char *str_prev, 
double scale_pref, int system, int type);
 
 /* the size of the unit used for this value (used for calculating the 
ckickstep) */
 double bUnit_ClosestScalar(double value, int system, int type);

Modified: branches/blender2.5/blender/source/blender/blenkernel/intern/unit.c
===================================================================
--- branches/blender2.5/blender/source/blender/blenkernel/intern/unit.c 
2009-08-13 16:59:52 UTC (rev 22434)
+++ branches/blender2.5/blender/source/blender/blenkernel/intern/unit.c 
2009-08-13 17:05:27 UTC (rev 22435)
@@ -27,6 +27,8 @@
 #include <string.h>
 #include <math.h>
 
+#define TEMP_STR_SIZE 256
+
 /* define a single unit */
 typedef struct bUnitDef {
        char *name;
@@ -89,7 +91,7 @@
        {"thou", "Thous",                               "mil", NULL,0.0000254, 
0.0,     B_UNIT_DEF_NONE},
        {NULL, NULL, NULL, NULL, 0.0, 0.0}
 };
-static struct bUnitCollection buImperialLenCollecton = {buImperialLenDef, 3, 
0, sizeof(buImperialLenDef)/sizeof(bUnitDef)};
+static struct bUnitCollection buImperialLenCollecton = {buImperialLenDef, 4, 
0, sizeof(buImperialLenDef)/sizeof(bUnitDef)};
 
 
 /* Time */
@@ -156,7 +158,7 @@
        *unit_b=        unit_best_fit(*value_b, usys, *unit_a, 1);
 }
 
-static int unit_as_string(char *str, double value, int prec, bUnitCollection 
*usys,
+static int unit_as_string(char *str, int len_max, double value, int prec, 
bUnitCollection *usys,
                /* non exposed options */
                bUnitDef *unit, char pad)
 {
@@ -178,32 +180,33 @@
 
        /* Convert to a string */
        {
-               char conv_str[5] = {'%', '.', '0'+prec, 'f', '\0'}; /* "%.2f" 
when prec is 2, must be under 10 */
-               len= sprintf(str, conv_str, (float)value_conv);
+               char conv_str[6] = {'%', '.', '0'+prec, 'l', 'f', '\0'}; /* 
"%.2lf" when prec is 2, must be under 10 */
+               len= snprintf(str, len_max, conv_str, (float)value_conv);
+
+               if(len >= len_max)
+                       len= len_max;
        }
        
-       
        /* Add unit prefix and strip zeros */
-       {
-               /* replace trailing zero's with spaces 
-                * so the number is less complicated but allignment in a button 
wont
-                * jump about while dragging */
-               int j;
-               i= len-1;
 
+       /* replace trailing zero's with spaces
+        * so the number is less complicated but allignment in a button wont
+        * jump about while dragging */
+       i= len-1;
+
+       while(i>0 && str[i]=='0') { /* 4.300 -> 4.3 */
+               str[i--]= pad;
+       }
+
+       if(i>0 && str[i]=='.') { /* 10. -> 10 */
+               str[i--]= pad;
+       }
        
-               while(i>0 && str[i]=='0') { /* 4.300 -> 4.3 */
-                       str[i--]= pad;
-               }
-               
-               if(i>0 && str[i]=='.') { /* 10. -> 10 */
-                       str[i--]= pad;
-               }
-               
-               /* Now add the suffix */
+       /* Now add the suffix */
+       if(i<len_max) {
+               int j=0;
                i++;
-               j=0;
-               while(unit->name_short[j]) {
+               while(unit->name_short[j] && (i < len_max)) {
                        str[i++]= unit->name_short[j++];
                }
 
@@ -212,21 +215,23 @@
                         * the unit name only used padded chars,
                         * In that case add padding for the name. */
 
-                       while(i<=len+j) {
+                       while(i<=len+j && (i < len_max)) {
                                str[i++]= pad;
                        }
                }
-               
-               /* terminate no matter whats done with padding above */
-               str[i] = '\0';
        }
 
+       /* terminate no matter whats done with padding above */
+       if(i >= len_max)
+               i= len_max-1;
+
+       str[i] = '\0';
        return i;
 }
 
 
 /* Used for drawing number buttons, try keep fast */
-void bUnit_AsString(char *str, double value, int prec, int system, int type, 
int split, int pad)
+void bUnit_AsString(char *str, int len_max, double value, int prec, int 
system, int type, int split, int pad)
 {
        bUnitCollection *usys = unit_get_system(system, type);
 
@@ -242,56 +247,111 @@
 
                /* check the 2 is a smaller unit */
                if(unit_b > unit_a) {
-                       i= unit_as_string(str, value_a, prec, usys,  unit_a, 
'\0');
-                       str[i++]= ',';
-                       str[i++]= ' ';
+                       i= unit_as_string(str, len_max, value_a, prec, usys,  
unit_a, '\0');
 
-                       /* use low precision since this is a smaller unit */
-                       unit_as_string(str+i, value_b, prec?1:0, usys,  unit_b, 
'\0');
+                       /* is there enough space for at least 1 char of the 
next unit? */
+                       if(i+3 < len_max) {
+                               str[i++]= ',';
+                               str[i++]= ' ';
+
+                               /* use low precision since this is a smaller 
unit */
+                               unit_as_string(str+i, len_max-i, value_b, 
prec?1:0, usys,  unit_b, '\0');
+                       }
                        return;
                }
        }
 
-       unit_as_string(str, value, prec, usys,    NULL, pad?' ':'\0');
+       unit_as_string(str, len_max, value, prec, usys,    NULL, pad?' ':'\0');
 }
 
 
-static int unit_scale_str(char *str, char *str_tmp, double scale_pref, 
bUnitDef *unit, char *replace_str)
+static char *unit_find_str(char *str, char *substr)
 {
        char *str_found;
-       int change= 0;
 
-       if(replace_str==NULL || replace_str[0] == '\0')
-               return 0;
+       if(substr && substr[0] != '\0') {
+               str_found= strstr(str, substr);
+               if(str_found) {
+                       /* previous char cannot be a letter */
+                       if (str_found == str || isalpha(*(str_found-1))==0) {
+                               /* next char cannot be alphanum */
+                               int len_name = strlen(substr);
 
-       if((str_found= strstr(str, replace_str))) {
-               /* previous char cannot be a letter */
-               if (str_found == str || isalpha(*(str_found-1))==0) {
-                       int len_name = strlen(replace_str);
-
-                       /* next char cannot be alphanum */
-                       if (!isalpha(*(str_found+len_name))) {
-                               int len= strlen(str);
-                               int len_num= sprintf(str_tmp, "*%g", 
unit->scalar/scale_pref);
-                               memmove(str_found+len_num, str_found+len_name, 
(len+1)-(int)((str_found+len_name)-str)); /* may grow or shrink the string, 1+ 
to copy the string terminator */
-                               memcpy(str_found, str_tmp, len_num); /* without 
the string terminator */
-                               change= 1;
+                               if (!isalpha(*(str_found+len_name))) {
+                                       return str_found;
+                               }
                        }
                }
+
        }
-       return change;
+       return NULL;
+
 }
 
-static int unit_replace(char *str, char *str_tmp, double scale_pref, bUnitDef 
*unit)
+static int unit_scale_str(char *str, int len_max, char *str_tmp, double 
scale_pref, bUnitDef *unit, char *replace_str)
+{
+       char *str_found= unit_find_str(str, replace_str);
+
+       if(str_found) { /* XXX - investigate, does not respect len_max properly 
 */
+               int len, len_num, len_name, len_move, found_ofs;
+
+               found_ofs = (int)(str_found-str);
+
+               len= strlen(str);
+
+               len_name = strlen(replace_str);
+               len_move= (len - (found_ofs+len_name)) + 1; /* 1+ to copy the 
string terminator */
+               len_num= snprintf(str_tmp, TEMP_STR_SIZE, "*%lg", 
unit->scalar/scale_pref);
+
+               if(len_num > len_max)
+                       len_num= len_max;
+
+               if(found_ofs+len_num+len_move > len_max) {
+                       /* can't move the whole string, move just as much as 
will fit */
+                       len_move -= (found_ofs+len_num+len_move) - len_max;
+               }
+
+               if(len_move>0) {
+                       /* resize the last part of the string */
+                       memmove(str_found+len_num, str_found+len_name, 
len_move); /* may grow or shrink the string */
+               }
+
+               if(found_ofs+len_num > len_max) {
+                       /* not even the number will fit into the string, only 
copy part of it */
+                       len_num -= (found_ofs+len_num) - len_max;
+               }
+
+               if(len_num > 0) {
+                       /* its possible none of the number could be copied in */
+                       memcpy(str_found, str_tmp, len_num); /* without the 
string terminator */
+               }
+
+               str[len_max-1]= '\0'; /* since the null terminator wont be 
moved */
+               return 1;
+       }
+       return 0;
+}
+
+static int unit_replace(char *str, int len_max, char *str_tmp, double 
scale_pref, bUnitDef *unit)
 {      
        int change= 0;
-       change |= unit_scale_str(str, str_tmp, scale_pref, unit, 
unit->name_short);
-       change |= unit_scale_str(str, str_tmp, scale_pref, unit, 
unit->name_plural);
-       change |= unit_scale_str(str, str_tmp, scale_pref, unit, 
unit->name_alt);
-       change |= unit_scale_str(str, str_tmp, scale_pref, unit, unit->name);
+       change |= unit_scale_str(str, len_max, str_tmp, scale_pref, unit, 
unit->name_short);
+       change |= unit_scale_str(str, len_max, str_tmp, scale_pref, unit, 
unit->name_plural);
+       change |= unit_scale_str(str, len_max, str_tmp, scale_pref, unit, 
unit->name_alt);
+       change |= unit_scale_str(str, len_max, str_tmp, scale_pref, unit, 
unit->name);
        return change;
 }
 
+static int unit_find(char *str, bUnitDef *unit)
+{
+       if (unit_find_str(str, unit->name_short))       return 1;
+       if (unit_find_str(str, unit->name_plural))      return 1;
+       if (unit_find_str(str, unit->name_alt))         return 1;
+       if (unit_find_str(str, unit->name))                     return 1;
+
+       return 0;
+}
+
 /* make a copy of the string that replaces the units with numbers
  * this is used before parsing
  * This is only used when evaluating user input and can afford to be a bit 
slower
@@ -304,15 +364,13 @@
  *
  * return true of a change was made.
  */
-int bUnit_ReplaceString(char *str, char *str_orig, char *str_prev, double 
scale_pref, int system, int type)
+int bUnit_ReplaceString(char *str, int len_max, char *str_prev, double 
scale_pref, int system, int type)
 {
        bUnitCollection *usys = unit_get_system(system, type);
 
        bUnitDef *unit;
-       char str_tmp[256];
+       char str_tmp[TEMP_STR_SIZE];
        int change= 0;
-       
-       strcpy(str, str_orig);
 
        if(usys==NULL || usys->units[0].name==NULL) {
                return 0;
@@ -324,7 +382,7 @@
                        continue;
 
                /* incase there are multiple instances */
-               while(unit_replace(str, str_tmp, scale_pref, unit))
+               while(unit_replace(str, len_max, str_tmp, scale_pref, unit))
                        change= 1;
        }
        unit= NULL;
@@ -343,7 +401,7 @@
                                                continue;
 
                                        /* incase there are multiple instances 
*/
-                                       while(unit_replace(str, str_tmp, 
scale_pref, unit))
+                                       while(unit_replace(str, len_max, 
str_tmp, scale_pref, unit))
                                                change= 1;
                                }
                        }
@@ -355,25 +413,24 @@
                /* no units given so infer a unit from the previous string or 
default */
                if(str_prev) {
                        /* see which units the original value had */

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to