コード例 #1
0
ファイル: substitute.c プロジェクト: porres/pd-cyclone
static void substitute_anything(t_substitute *x,
				t_symbol *s, int ac, t_atom *av)
{
    int matchndx = substitute_check(x, s, ac, av);
    if (matchndx < -1)
        //if replace type is null or no match found
	substitute_dooutput(x, s, ac, av, 1);
    else
    {
        int replaceonce = x->x_replaceonce;
        int replaced = 0; //if we've replaced something, useful for replaceonce

	int reentered = x->x_entered;
	int prealloc = !reentered;
	int ntotal = ac;
	t_atom *buf;
	t_substitute_proxy *proxy = (t_substitute_proxy *)x->x_proxy;
	x->x_entered = 1;
        //while method is working, point to aux versions so if they change, won't effect
        //currently undergoing replacement scheme
	proxy->p_match = &x->x_auxmatch;
	proxy->p_repl = &x->x_auxrepl;
	if (s == &s_) s = 0;
	if (matchndx == -1)
	{
            //if match type is a symbol AND is the selector 
	    if (x->x_repl.a_type == A_FLOAT)
	    {
                //since we're replacing the selector and it can't be a float,
                //need to add it to the list
		ntotal++;
                //if there's a rest to it, the selector needs to be a list selector
		if (ac) s = &s_list;
                //else there's no "rest of it", can be a float selector
		else s = &s_float;

                replaced = 1;
	    }
	    else if (x->x_repl.a_type == A_SYMBOL)
	    {
                //just replace the selector if the replace type is the symbol
                //set matchndx to 0 to avoid the if in the message contructor clause below
		s = x->x_repl.a_w.w_symbol;
		matchndx = 0;

                replaced = 1;
	    }
	}
	else if (matchndx == 0
		 && (!s || s == &s_list || s == &s_float)
		 && av->a_type == A_FLOAT
		 && x->x_repl.a_type == A_SYMBOL)
	{
            //match index is at the beginning of a list (or singleton)
            //incoming list[0] is a float, being replaced by a symbol
            //just make the selector the replacement
	    s = x->x_repl.a_w.w_symbol;
	    ac--;
	    av++;
	    ntotal = ac;
	}
	if (prealloc && ac > x->x_size)
	{
            //if bigger that maximum size, don't bother allocating to x_message
	    if (ntotal > SUBSTITUTE_MAXSIZE)
		prealloc = 0;
	    else
		x->x_message = grow_nodata(&ntotal, &x->x_size, x->x_message,
					   SUBSTITUTE_INISIZE, x->x_messini,
					   sizeof(*x->x_message));
	}

        //if allocated, just point stack pointer to struct's x_message
        //else just point stack pointer to new allocated memory
	if (prealloc) buf = x->x_message;
	else
	    /* LATER consider using the stack if ntotal <= MAXSTACK */
	    buf = getbytes(ntotal * sizeof(*buf));
	if (buf)
	{
	    int ncopy = ntotal;
	    t_atom *bp = buf;
	    if (matchndx == -1)
	    {
                //only hit if x_repl is a float because of the earlier clause
		SETFLOAT(bp++, x->x_repl.a_w.w_float);
		ncopy--;
	    }
            //copy over incoming list to allocated buf (or x message), do the substitution
	    if (ncopy)
		memcpy(bp, av, ncopy * sizeof(*buf));
	    substitute_doit(x, s, ntotal, buf, matchndx, replaceonce, replaced);
            
            //free newly allocated memory if using it
	    if (buf != x->x_message)
		freebytes(buf, ntotal * sizeof(*buf));
	}
	if (!reentered)
	{
	    x->x_entered = 0;
	    if (x->x_auxmatch.a_type != A_NULL)
	    {
		x->x_match = x->x_auxmatch;
		x->x_auxmatch.a_type = A_NULL;
	    }
	    if (x->x_auxrepl.a_type != A_NULL)
	    {
		x->x_repl = x->x_auxrepl;
		x->x_auxrepl.a_type = A_NULL;
	    }
	    proxy->p_match = &x->x_match;
	    proxy->p_repl = &x->x_repl;
	}
    }
}
コード例 #2
0
ファイル: substitute.c プロジェクト: EQ4/Pd-for-LibPd
static void substitute_anything(t_substitute *x,
				t_symbol *s, int ac, t_atom *av)
{
    int matchndx = substitute_check(x, s, ac, av);
    if (matchndx < -1)
	substitute_dooutput(x, s, ac, av, 1);
    else
    {
	int reentered = x->x_entered;
	int prealloc = !reentered;
	int ntotal = ac;
	t_atom *buf;
	t_substitute_proxy *proxy = (t_substitute_proxy *)x->x_proxy;
	x->x_entered = 1;
	proxy->p_match = &x->x_auxmatch;
	proxy->p_repl = &x->x_auxrepl;
	if (s == &s_) s = 0;
	if (matchndx == -1)
	{
	    if (x->x_repl.a_type == A_FLOAT)
	    {
		ntotal++;
		if (ac) s = &s_list;
		else s = &s_float;
	    }
	    else if (x->x_repl.a_type == A_SYMBOL)
	    {
		s = x->x_repl.a_w.w_symbol;
		matchndx = 0;
	    }
	}
	else if (matchndx == 0
		 && (!s || s == &s_list || s == &s_float)
		 && av->a_type == A_FLOAT
		 && x->x_repl.a_type == A_SYMBOL)
	{
	    s = x->x_repl.a_w.w_symbol;
	    ac--;
	    av++;
	    ntotal = ac;
	}
	if (prealloc && ac > x->x_size)
	{
	    if (ntotal > SUBSTITUTE_MAXSIZE)
		prealloc = 0;
	    else
		x->x_message = grow_nodata(&ntotal, &x->x_size, x->x_message,
					   SUBSTITUTE_INISIZE, x->x_messini,
					   sizeof(*x->x_message));
	}
	if (prealloc) buf = x->x_message;
	else
	    /* LATER consider using the stack if ntotal <= MAXSTACK */
	    buf = getbytes(ntotal * sizeof(*buf));
	if (buf)
	{
	    int ncopy = ntotal;
	    t_atom *bp = buf;
	    if (matchndx == -1)
	    {
		SETFLOAT(bp++, x->x_repl.a_w.w_float);
		ncopy--;
	    }
	    if (ncopy)
		memcpy(bp, av, ncopy * sizeof(*buf));
	    substitute_doit(x, s, ntotal, buf, matchndx);
	    if (buf != x->x_message)
		freebytes(buf, ntotal * sizeof(*buf));
	}
	if (!reentered)
	{
	    x->x_entered = 0;
	    if (x->x_auxmatch.a_type != A_NULL)
	    {
		x->x_match = x->x_auxmatch;
		x->x_auxmatch.a_type = A_NULL;
	    }
	    if (x->x_auxrepl.a_type != A_NULL)
	    {
		x->x_repl = x->x_auxrepl;
		x->x_auxrepl.a_type = A_NULL;
	    }
	    proxy->p_match = &x->x_match;
	    proxy->p_repl = &x->x_repl;
	}
    }
}