Ejemplo n.º 1
0
/* Look for an iterate-over-plot construct, of the form
 *    {s}plot  for [<var> = <start> : <end> { : <increment>}] ...
 */
void
check_for_iteration()
{
    char *errormsg = "Expecting iterator \tfor [<var> = <start> : <end>]\n\t\t\tor\tfor [<var> in \"string of words\"]";

    iteration_udv = NULL;
    free(iteration_string);
    iteration_string = NULL;
    iteration_increment = 1;
    iteration = 0;

    if (!equals(c_token, "for"))
	return;

    c_token++;
    if (!equals(c_token++, "[") || !isletter(c_token))
	int_error(c_token-1, errormsg);
    iteration_udv = add_udv(c_token++);

    if (equals(c_token, "=")) {
	c_token++;
	iteration_start = int_expression();
	if (!equals(c_token++, ":"))
	    int_error(c_token-1, errormsg);
	iteration_end = int_expression();
	if (equals(c_token,":")) {
	    c_token++;
	    iteration_increment = int_expression();
	}
	if (!equals(c_token++, "]"))
	    int_error(c_token-1, errormsg);
	if (iteration_udv->udv_undef == FALSE)
	    gpfree_string(&iteration_udv->udv_value);
	Ginteger(&(iteration_udv->udv_value), iteration_start);
	iteration_udv->udv_undef = FALSE;
    }

    else if (equals(c_token++, "in")) {
	iteration_string = try_to_get_string();
	if (!iteration_string)
	    int_error(c_token-1, errormsg);
	if (!equals(c_token++, "]"))
	    int_error(c_token-1, errormsg);
	iteration_start = 1;
	iteration_end = gp_words(iteration_string);
	if (iteration_udv->udv_undef == FALSE)
	    gpfree_string(&iteration_udv->udv_value);
	Gstring(&(iteration_udv->udv_value), gp_word(iteration_string, 1));
	iteration_udv->udv_undef = FALSE;
    }

    else /* Neither [i=B:E] or [s in "foo"] */
 	int_error(c_token-1, errormsg);

    iteration_current = iteration_start;

}
Ejemplo n.º 2
0
/* Set up next iteration.
 * Return TRUE if there is one, FALSE if we're done
 */
TBOOLEAN
next_iteration()
{
    if (!iteration_udv) {
	iteration = 0;
	return FALSE;
    }
    iteration++;
    iteration_current += iteration_increment;
    if (iteration_string) {
	free(iteration_udv->udv_value.v.string_val);
	iteration_udv->udv_value.v.string_val = gp_word(iteration_string,iteration_current);
    } else
	iteration_udv->udv_value.v.int_val = iteration_current;
    return iteration_increment && /* no infinite loops! */
      ((iteration_end - iteration_current)*iteration_increment >= 0);
}
Ejemplo n.º 3
0
Archivo: parse.c Proyecto: Reen/gnuplot
/* Set up next iteration.
 * Return TRUE if there is one, FALSE if we're done
 */
TBOOLEAN
next_iteration(t_iterator *iter)
{
    t_iterator *this_iter;
    TBOOLEAN condition = FALSE;
    
    if (!iter || iter->empty_iteration)
	return FALSE;

    /* Support for nested iteration:
     * we start with the innermost loop. */
    this_iter = iter->prev; /* linked to the last element of the list */
    
    if (!this_iter)
	return FALSE;
    
    while (!iter->really_done && this_iter != iter && this_iter->done) {
	this_iter->iteration_current = this_iter->iteration_start;
	this_iter->done = FALSE;
	if (this_iter->iteration_string) {
	    gpfree_string(&(this_iter->iteration_udv->udv_value));
	    Gstring(&(this_iter->iteration_udv->udv_value), 
		    gp_word(this_iter->iteration_string, this_iter->iteration_current));
    } else
	    this_iter->iteration_udv->udv_value.v.int_val = this_iter->iteration_current;	
	
	this_iter = this_iter->prev;
    }
   
    if (!this_iter->iteration_udv) {
	this_iter->iteration = 0;
	return FALSE;
    }
    iter->iteration++;
    /* don't increment if we're at the last iteration */
    if (!iter->really_done)
	this_iter->iteration_current += this_iter->iteration_increment;
    if (this_iter->iteration_string) {
	gpfree_string(&(this_iter->iteration_udv->udv_value));
	Gstring(&(this_iter->iteration_udv->udv_value), 
		gp_word(this_iter->iteration_string, this_iter->iteration_current));
    } else
	this_iter->iteration_udv->udv_value.v.int_val = this_iter->iteration_current;
    
    /* Mar 2014 revised to avoid integer overflow */
    if (this_iter->iteration_increment > 0
    &&  this_iter->iteration_end - this_iter->iteration_current < this_iter->iteration_increment)
	this_iter->done = TRUE;
    else if (this_iter->iteration_increment < 0
    &&  this_iter->iteration_end - this_iter->iteration_current > this_iter->iteration_increment)
	this_iter->done = TRUE;
    else
	this_iter->done = FALSE;
    
    /* We return false only if we're, um, really done */
    this_iter = iter;
    while (this_iter) {
	condition = condition || (!this_iter->done);
	this_iter = this_iter->next;
    }
    if (!condition) {
	if (!iter->really_done) {
	    iter->really_done = TRUE;
	    condition = TRUE;
	} else 
	    condition = FALSE;
    }
    return condition;
}
Ejemplo n.º 4
0
Archivo: parse.c Proyecto: Reen/gnuplot
/* Look for iterate-over-plot constructs, of the form
 *    for [<var> = <start> : <end> { : <increment>}] ...
 * If one (or more) is found, an iterator structure is allocated and filled
 * and a pointer to that structure is returned.
 * The pointer is NULL if no "for" statements are found.
 */
t_iterator *
check_for_iteration()
{
    char *errormsg = "Expecting iterator \tfor [<var> = <start> : <end> {: <incr>}]\n\t\t\tor\tfor [<var> in \"string of words\"]";
    int nesting_depth = 0;
    t_iterator *iter = NULL;
    t_iterator *this_iter = NULL;

    /* Now checking for iteration parameters */
    /* Nested "for" statements are supported, each one corresponds to a node of the linked list */
    while (equals(c_token, "for")) {
	struct udvt_entry *iteration_udv = NULL;
	char *iteration_string = NULL;
	int iteration_start;
	int iteration_end;
	int iteration_increment = 1;
	int iteration_current;
	int iteration = 0;
	TBOOLEAN empty_iteration;
	TBOOLEAN just_once = FALSE;

	c_token++;
	if (!equals(c_token++, "[") || !isletter(c_token))
	    int_error(c_token-1, errormsg);
	iteration_udv = add_udv(c_token++);

	if (equals(c_token, "=")) {
	    c_token++;
	    iteration_start = int_expression();
	    if (!equals(c_token++, ":"))
	    	int_error(c_token-1, errormsg);
	    iteration_end = int_expression();
	    if (equals(c_token,":")) {
	    	c_token++;
	    	iteration_increment = int_expression();
		if (iteration_increment == 0)
		    int_error(c_token-1, errormsg);
	    }
	    if (!equals(c_token++, "]"))
	    	int_error(c_token-1, errormsg);
	    if (iteration_udv->udv_undef == FALSE)
		gpfree_string(&(iteration_udv->udv_value));
	    Ginteger(&(iteration_udv->udv_value), iteration_start);
	    iteration_udv->udv_undef = FALSE;
	}
	else if (equals(c_token++, "in")) {
	    iteration_string = try_to_get_string();
	    if (!iteration_string)
	    	int_error(c_token-1, errormsg);
	    if (!equals(c_token++, "]"))
	    	int_error(c_token-1, errormsg);
	    iteration_start = 1;
	    iteration_end = gp_words(iteration_string);
	    if (iteration_udv->udv_undef == FALSE)
	    	gpfree_string(&(iteration_udv->udv_value));
	    Gstring(&(iteration_udv->udv_value), gp_word(iteration_string, 1));
	    iteration_udv->udv_undef = FALSE;
	}
	else /* Neither [i=B:E] or [s in "foo"] */
	    int_error(c_token-1, errormsg);

	iteration_current = iteration_start;

	empty_iteration = FALSE;	
	if ( (iteration_udv != NULL)
	&&   ((iteration_end > iteration_start && iteration_increment < 0)
	   || (iteration_end < iteration_start && iteration_increment > 0))) {
		empty_iteration = TRUE;
		FPRINTF((stderr,"Empty iteration\n"));
	}

	/* Allocating a node of the linked list nested iterations. */
	/* Iterating just once is the same as not iterating at all */
	/* so we skip building the node in that case.		   */
	if (iteration_start == iteration_end)
	    just_once = TRUE;
	if (iteration_start < iteration_end && iteration_end < iteration_start + iteration_increment)
	    just_once = TRUE;
	if (iteration_start > iteration_end && iteration_end > iteration_start + iteration_increment)
	    just_once = TRUE;

	if (!just_once) {
	    this_iter = gp_alloc(sizeof(t_iterator), "iteration linked list");
	    this_iter->iteration_udv = iteration_udv; 
	    this_iter->iteration_string = iteration_string;
	    this_iter->iteration_start = iteration_start;
	    this_iter->iteration_end = iteration_end;
	    this_iter->iteration_increment = iteration_increment;
	    this_iter->iteration_current = iteration_current;
	    this_iter->iteration = iteration;
	    this_iter->done = FALSE;
	    this_iter->really_done = FALSE;
	    this_iter->empty_iteration = empty_iteration;
	    this_iter->next = NULL;
	    this_iter->prev = NULL;
	    if (nesting_depth == 0) {
		/* first "for" statement: this will be the listhead */
		iter = this_iter;
	    }
	    else {
		/* not the first "for" statement: attach the newly created node to the end of the list */
		iter->prev->next = this_iter;  /* iter->prev points to the last node of the list */
		this_iter->prev = iter->prev;
	    }
	    iter->prev = this_iter; /* a shortcut: making the list circular */

	    /* if one iteration in the chain is empty, the subchain of nested iterations is too */
	    if (!iter->empty_iteration) 
		iter->empty_iteration = empty_iteration;

	    nesting_depth++;
	}
    }

    return iter;
}
Ejemplo n.º 5
0
/* Set up next iteration.
 * Return TRUE if there is one, FALSE if we're done
 */
TBOOLEAN
next_iteration(t_iterator *iter)
{
    t_iterator *this_iter;
    TBOOLEAN condition = FALSE;
    
    if (!iter || iter->empty_iteration)
	return FALSE;

    /* Support for nested iteration:
     * we start with the innermost loop. */
    this_iter = iter->prev; /* linked to the last element of the list */
    
    if (!this_iter)
	return FALSE;
    
    while (!iter->really_done && this_iter != iter && this_iter->done) {
	this_iter->iteration_current = this_iter->iteration_start;
	this_iter->done = FALSE;
	if (this_iter->iteration_string) {
	    free(this_iter->iteration_udv->udv_value.v.string_val);
	    this_iter->iteration_udv->udv_value.v.string_val
	         = gp_word(this_iter->iteration_string, this_iter->iteration_current);
    } else
	    this_iter->iteration_udv->udv_value.v.int_val = this_iter->iteration_current;	
	
	this_iter = this_iter->prev;
    }
   
    if (!this_iter->iteration_udv) {
	this_iter->iteration = 0;
	return FALSE;
    }
    iter->iteration++;
    /* don't increment if we're at the last iteration */
    if (!iter->really_done)
	this_iter->iteration_current += this_iter->iteration_increment;
    if (this_iter->iteration_string) {
	free(this_iter->iteration_udv->udv_value.v.string_val);
	this_iter->iteration_udv->udv_value.v.string_val
	    = gp_word(this_iter->iteration_string, this_iter->iteration_current);
    } else
	this_iter->iteration_udv->udv_value.v.int_val = this_iter->iteration_current;
    
    /* no need to check for increment <> 0 here, 
     * because that case was already caught in check_for_iteration */
    this_iter->done = 
	!((this_iter->iteration_end - this_iter->iteration_current - this_iter->iteration_increment)
	   * this_iter->iteration_increment >= 0);
    
    /* We return false only if we're, erm, really done */
    this_iter = iter;
    while (this_iter) {
	condition = condition || (!this_iter->done);
	this_iter = this_iter->next;
    }
    if (!condition) {
	if (!iter->really_done) {
	    iter->really_done = TRUE;
	    condition = TRUE;
	} else 
	    condition = FALSE;
    }
    return condition;
}