ucx/string.c

changeset 233
bd58fdde142d
parent 231
35490eb48214
child 234
7a63b4986b5b
     1.1 --- a/ucx/string.c	Mon Feb 20 16:04:14 2017 +0100
     1.2 +++ b/ucx/string.c	Mon Feb 20 16:57:09 2017 +0100
     1.3 @@ -212,62 +212,58 @@
     1.4          } else /* no match possible */ {
     1.5              *n = 1;
     1.6              sstr_t *result = (sstr_t*) almalloc(allocator, sizeof(sstr_t));
     1.7 -            result->ptr = (char*) almalloc(allocator, 1+s.length);
     1.8 -            memcpy(result->ptr, s.ptr, s.length);
     1.9 -            result->ptr[s.length] = '\0';
    1.10 -            result->length = s.length;
    1.11 +            *result = sstrdup_a(allocator, s);
    1.12              return result;
    1.13          }
    1.14      }
    1.15      
    1.16 -    sstr_t* result;
    1.17      ssize_t nmax = *n;
    1.18 -    *n = 1;
    1.19 -    
    1.20 -    sstr_t sv = sstrdup(s);
    1.21 -    if (sv.length == 0) {
    1.22 -        *n = -2;
    1.23 -        return NULL;
    1.24 -    }
    1.25 -
    1.26 -    for (size_t i = 0 ; i < s.length ; i++) {
    1.27 -        sstr_t substr = sstrsubs(sv, i);
    1.28 -        if (sstrprefix(substr, d)) {
    1.29 -            (*n)++;
    1.30 -            for (size_t j = 0 ; j < d.length ; j++) {
    1.31 -                sv.ptr[i+j] = 0;
    1.32 -            }
    1.33 -            i += d.length - 1; // -1, because the loop will do a i++
    1.34 -        }
    1.35 -        if ((*n) == nmax) break;
    1.36 -    }
    1.37 -    result = (sstr_t*) almalloc(allocator, sizeof(sstr_t)*(*n));
    1.38 +    sstr_t* result = (sstr_t*) almalloc(allocator, sizeof(sstr_t));
    1.39  
    1.40      if (result) {
    1.41 -        char *pptr = sv.ptr;
    1.42 -        for (ssize_t i = 0 ; i < *n ; i++) {
    1.43 -            size_t l = strlen(pptr);
    1.44 -            char* ptr = (char*) almalloc(allocator, l + 1);
    1.45 -            if (ptr) {
    1.46 -                memcpy(ptr, pptr, l);
    1.47 -                ptr[l] = '\0';
    1.48 +        sstr_t curpos = s;
    1.49 +        ssize_t j = 1;
    1.50 +        while (1) {
    1.51 +            sstr_t match = sstrstr(curpos, d);
    1.52 +            if (match.length > 0) {
    1.53 +                /* is this our last try? */
    1.54 +                if (nmax == 0 || j < nmax) {
    1.55 +                    /* copy the current string to the array */
    1.56 +                    sstr_t item = sstrn(curpos.ptr, match.ptr - curpos.ptr);
    1.57 +                    result[j-1] = sstrdup_a(allocator, item);
    1.58 +                    size_t processed = item.length + d.length;
    1.59 +                    curpos.ptr += processed;
    1.60 +                    curpos.length -= processed;
    1.61  
    1.62 -                result[i] = sstrn(ptr, l);
    1.63 -                pptr += l + d.length;
    1.64 +                    /* allocate memory for the next string */
    1.65 +                    j++;
    1.66 +                    sstr_t* reallocated = (sstr_t*)
    1.67 +                            alrealloc(allocator, result, j*sizeof(sstr_t));
    1.68 +                    if (reallocated) {
    1.69 +                        result = reallocated;
    1.70 +                    } else {
    1.71 +                        for (ssize_t i = 0 ; i < j-1 ; i++) {
    1.72 +                            alfree(allocator, result[i].ptr);
    1.73 +                        }
    1.74 +                        alfree(allocator, result);
    1.75 +                        *n = -2;
    1.76 +                        return NULL;
    1.77 +                    }
    1.78 +                } else {
    1.79 +                    /* nmax reached, copy the _full_ remaining string */
    1.80 +                    result[j-1] = sstrdup_a(allocator, curpos);
    1.81 +                    break;
    1.82 +                }
    1.83              } else {
    1.84 -                for (ssize_t j = i-1 ; j >= 0 ; j--) {
    1.85 -                    alfree(allocator, result[j].ptr);
    1.86 -                }
    1.87 -                alfree(allocator, result);
    1.88 -                *n = -2;
    1.89 +                /* no more matches, copy last string */
    1.90 +                result[j-1] = sstrdup_a(allocator, curpos);
    1.91                  break;
    1.92              }
    1.93          }
    1.94 +        *n = j;
    1.95      } else {
    1.96          *n = -2;
    1.97      }
    1.98 -    
    1.99 -    free(sv.ptr);
   1.100  
   1.101      return result;
   1.102  }

mercurial