]> git.mxchange.org Git - simgear.git/blobdiff - simgear/nasal/string.c
Olaf Flebbe:
[simgear.git] / simgear / nasal / string.c
index fc0acb0408cefde5c64bbf239074b94257ee597a..5f44a1cd29911ab49ddbd8f09a5b01df6fcca3ed 100644 (file)
@@ -8,11 +8,6 @@
 // double.
 #define DIGITS 16
 
-// The minimum size we'll allocate for a string.  Since a string
-// structure is already 12 bytes, and each naRef that points to it is
-// 8, there isn't much point in being stingy.
-#define MINLEN 16
-
 static int tonum(unsigned char* s, int len, double* result);
 static int fromnum(double val, unsigned char* s);
 
@@ -25,21 +20,22 @@ int naStr_len(naRef s)
 char* naStr_data(naRef s)
 {
     if(!IS_STR(s)) return 0;
-    return s.ref.ptr.str->data;
+    return (char*)s.ref.ptr.str->data;
 }
 
 static void setlen(struct naStr* s, int sz)
 {
-    int currSz, waste;
-    sz += 1; // Allow for an extra nul terminator
-    currSz = s->len+1 < MINLEN ? MINLEN : s->len+1;
-    waste = currSz - sz; // how much extra if we don't reallocate?
-    if(s->data == 0 || waste < 0 || waste > MINLEN) {
-        naFree(s->data);
-        s->data = naAlloc(sz < MINLEN ? MINLEN : sz);
-    }
-    s->len = sz - 1;
-    s->data[s->len] = 0; // nul terminate
+    if(s->data) naFree(s->data);
+    s->len = sz;
+    s->data = naAlloc(sz+1);
+    s->data[sz] = 0; // nul terminate
+}
+
+naRef naStr_buf(naRef dst, int len)
+{
+    setlen(dst.ref.ptr.str, len);
+    naBZero(dst.ref.ptr.str->data, len);
+    return dst;
 }
 
 naRef naStr_fromdata(naRef dst, char* data, int len)
@@ -94,7 +90,7 @@ naRef naStr_fromnum(naRef dest, double num)
 
 int naStr_parsenum(char* str, int len, double* result)
 {
-    return tonum(str, len, result);
+    return tonum((unsigned char*)str, len, result);
 }
 
 int naStr_tonum(naRef str, double* out)
@@ -110,10 +106,8 @@ int naStr_numeric(naRef str)
 
 void naStr_gcclean(struct naStr* str)
 {
-    if(str->len > MINLEN) {
-        naFree(str->data);
-        str->data = 0;
-    }
+    naFree(str->data);
+    str->data = 0;
     str->len = 0;
 }
 
@@ -188,6 +182,13 @@ static int tonum(unsigned char* s, int len, double* result)
     if(len == 1 && s[0] == '.')
         return 0;
 
+    // Strip off the leading negative sign first, so we can correctly
+    // parse things like -.xxx which would otherwise confuse
+    // readsigned.
+    if(len > 1 && s[0] == '-' && s[1] != '-') {
+        sgn = -1; s++; len--;
+    }
+
     // Read the integer part
     i = readsigned(s, len, i, &val);
     if(val < 0) { sgn = -1; val = -val; }
@@ -199,9 +200,15 @@ static int tonum(unsigned char* s, int len, double* result)
         i += fraclen;
     }
 
+    // Nothing so far?  Then the parse failed.
+    if(i == 0) return 0;
+
     // Read the exponent, if any
-    if(i < len && (s[i] == 'e' || s[i] == 'E'))
+    if(i < len && (s[i] == 'e' || s[i] == 'E')) {
+        int i0 = i+1;
         i = readsigned(s, len, i+1, &exp);
+        if(i == i0) return 0; // Must have a number after the "e"
+    }
     
     // compute the result
     *result = sgn * (val + frac * decpow(-fraclen)) * decpow(exp);
@@ -219,7 +226,7 @@ static int decprint(int val, unsigned char* s)
 {
     int p=1, i=0;
     if(val == 0) { *s = '0'; return 1; }
-    while(p < 1000000000 && p*10 < val) p *= 10;
+    while(p <= 999999999 && p*10 <= val) p *= 10;
     while(p > 0) {
         int count = 0;
         while(val >= p) { val -= p; count++; }
@@ -278,7 +285,7 @@ static int fromnum(double val, unsigned char* s)
         if(raw[i] != '0') break;
     digs = i+1;
 
-    if(exp > 0 || exp < -(DIGITS+2)) {
+    if(exp > 0 || exp < -(DIGITS+3)) {
         // Standard scientific notation
         exp += DIGITS-1;
         *ptr++ = raw[0];