static awlval* awlval_slice_step_str(awlval* x, int start, int end, int step) { char* sliced = strsubstr(x->str, start, end); if (step > 1 && strlen(sliced)) { char* stepped = strstep(sliced, step); free(sliced); sliced = stepped; } free(x->str); x->str = sliced; return x; }
/** * Make sub-string replacing by regular compiled expression matching * * @param __re - compiled regular expression * @param __s - source string * @param __mask - mask of replacement * @return replaced string * @sideeffect allocate memory for return value */ char* regexp_replace (const regexp_t *__re, const char *__s, const char *__mask) { char *shift = (char*)__s; char *dummy, *prefix = NULL, *buf = NULL; size_t l, r, len, buf_len = 0, prefix_len = 0; for (;;) { dummy = regexp_replace_iterator (__re, shift, __mask, &l, &r); len = 0; if (dummy) { len = strlen (dummy); } if (l > 0) { /* There is non-empty prefix */ if (prefix_len < l) { prefix_len = l; prefix = realloc (prefix, prefix_len + 1); } strsubstr (shift, 0, l, prefix); } else { if (!prefix) { prefix = strdup (""); prefix_len = 0; } else { prefix[0] = 0; } } if (l + len > 0) { BOOL zerolize = 0; /* It there is something to append */ buf_len += l + len; if (!buf) { zerolize = TRUE; } buf = realloc (buf, buf_len + 1); if (zerolize) { buf[0] = 0; } /* Append new prefix to buffer */ strcat (buf, prefix); if (dummy) { /* Append replaced string and free it */ strcat (buf, dummy); free (dummy); } } shift += r; if (!dummy || !r || !TEST_FLAG (__re->modifiers, REGEXP_REPLACE_GLOBAL)) { /* FINITO */ break; } } SAFE_FREE (prefix); /* Append suffix */ buf_len += strlen (shift); if (buf) { buf = realloc (buf, buf_len + 1); strcat (buf, shift); } else { buf = malloc (buf_len + 1); strcpy (buf, shift); } return buf; }
/** * Iterator for regexp_replace() * * @param __re - compiled regular expression * @param __s - source string * @param __mask - mask of replacement * @param __l - left offset of replaced sub-string * @param __r - right offset of replaced sub-string * @return replaced string * @sideeffect allocate memory for return value */ static char* regexp_replace_iterator (const regexp_t *__re, const char *__s, const char *__mask, size_t *__l, size_t *__r) { int i, vector_count; char *token, *shift, *append; char *out = NULL; char **substrings = NULL; size_t len, cur_size = 0; int ovector_size = (strlen (__s) + 1) * 2; int *ovector = malloc (sizeof (int) * ovector_size); int flags, errno; (*__l) = (*__r) = 0; /* Get the vector of matches */ vector_count = regexp_get_vector (__re, __s, ovector, ovector_size); if (vector_count <= 0) { /* No matched sub-strings */ return 0; } /* Get named sub-strings */ substrings = malloc (vector_count * sizeof (char*)); for (i = 0; i < vector_count; i++) { len = ovector[i * 2 + 1] - ovector[i * 2]; substrings[i] = malloc (len + 1); strsubstr (__s, ovector[i * 2], len, substrings[i]); } shift = (char*)__mask; len = strlen (__mask); cur_size = len + 1; MALLOC_ZERO (out, cur_size); /* Token can't be longer than mask string */ token = malloc (len + 1); while ((shift = replace_parser_iterator (shift, &token, &flags, &errno))) { if (errno == REGEXP_OK) { if (flags & PF_NAMED_STRING) { /* Numbered string */ int index = atoi (token); if (index >= vector_count) { /* If index is out of range, append empty string */ append = ""; } else { append = substrings[index]; } } else { /* Just append token */ append = token; } len = strlen (append); cur_size += len; out = realloc (out, cur_size); strcat (out, append); } else { SAFE_FREE (out); break; } } free (token); (*__l) = ovector[0]; (*__r) = ovector[1]; for (i = 0; i < vector_count; ++i) { free (substrings[i]); } free (substrings); free (ovector); return out; }