void c_expand_varargs(int where) { svalue_t *s, *t; array_t *arr; int n; s = sp - where; if (s->type != T_ARRAY) error("Item being expanded with ... is not an array\n"); arr = s->u.arr; n = arr->size; num_varargs += n - 1; if (!n) { t = s; while (t < sp) { *t = *(t + 1); t++; } sp--; } else if (n == 1) { assign_svalue_no_free(s, &arr->item[0]); } else { t = sp; CHECK_STACK_OVERFLOW(n - 1); sp += n - 1; while (t > s) { *(t + n - 1) = *t; t--; } t = s + n - 1; if (arr->ref == 1) { memcpy(s, arr->item, n * sizeof(svalue_t)); free_empty_array(arr); return; } else { while (n--) assign_svalue_no_free(t--, &arr->item[n]); } } free_array(arr); }
/* This is mostly copy/paste from reg_assoc, some parts are changed * TODO: rewrite with new logic */ static array_t *pcre_assoc(svalue_t *str, array_t *pat, array_t *tok, svalue_t *def) { int i, size; const char *tmp; array_t *ret; if ((size = pat->size) != tok->size) error("Pattern and token array size must be identical.\n"); for (i = 0; i < size; i++) if (pat->item[i].type != T_STRING) error("Non-string found in pattern array.\n"); ret = allocate_empty_array(2); if (size) { pcre_t **rgpp; struct reg_match { int tok_i; const char *begin, *end; struct reg_match *next; } *rmp = (struct reg_match *) 0, *rmph = (struct reg_match *) 0; int num_match = 0, length; svalue_t *sv1, *sv2, *sv; int regindex; pcre_t *tmpreg; int laststart; rgpp = CALLOCATE(size, pcre_t *, TAG_TEMPORARY, "pcre_assoc : rgpp"); for (i = 0; i < size; i++) { rgpp[i] = CALLOCATE(1, pcre_t, TAG_TEMPORARY, "pcre_assoc : rgpp[i]"); rgpp[i]->ovector = NULL; rgpp[i]->ovecsize = 0; assign_svalue_no_free(&rgpp[i]->pattern, &pat->item[i]); rgpp[i]->re = pcre_get_cached_pattern(&pcre_cache, &rgpp[i]->pattern); if (rgpp[i]->re == NULL) { if (pcre_local_compile(rgpp[i]) == NULL) { const char *rerror = rgpp[i]->error; int offset = rgpp[i]->erroffset; while (i--) pcre_free_memory(rgpp[i]); FREE(rgpp); free_empty_array(ret); error("PCRE compilation failed at offset %d: %s\n", offset, rerror); } else pcre_cache_pattern(&pcre_cache, rgpp[i]->re, &rgpp[i]->pattern); } } tmp = str->u.string; int totalsize = SVALUE_STRLEN(str); int used = 0; while (*tmp) { laststart = 0; regindex = -1; for (i = 0; i < size; i++) { rgpp[i]->subject = tmp; rgpp[i]->s_length = totalsize-used; pcre_local_exec(tmpreg = rgpp[i]); if (pcre_query_match(tmpreg)) { char *curr_temp; size_t curr_temp_sz; curr_temp_sz = totalsize - used - tmpreg->ovector[0]; if(!tmpreg->ovector[0]){ regindex = i; break; } if (laststart < curr_temp_sz) { laststart = curr_temp_sz; regindex = i; } } } if (regindex >= 0) { const char *rmpb_tmp, *rmpe_tmp; size_t rmpb_tmp_sz, rmpe_tmp_sz; num_match++; if (rmp) { rmp->next = ALLOCATE(struct reg_match, TAG_TEMPORARY, "pcre_assoc : rmp->next"); rmp = rmp->next; } else rmph = rmp = ALLOCATE(struct reg_match, TAG_TEMPORARY, "pcre_assoc : rmp"); tmpreg = rgpp[regindex]; rmpb_tmp = tmp + tmpreg->ovector[0]; rmpe_tmp = tmp + tmpreg->ovector[1]; rmp->begin = rmpb_tmp; rmp->end = tmp = rmpe_tmp; used+=tmpreg->ovector[1]; rmp->tok_i = regindex; rmp->next = (struct reg_match *) 0; } else break; if (rmp->begin == tmp && (!*++tmp)) break; }