Example #1
0
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);
}
Example #2
0
/* 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;
		}