6

The new gnuplot (5.x) has new syntax for logic, but I cannot get the 'else if' statement to work. For example:

if(flag==1){
plot sin(x)
}
else{
plot cos(x)
}

does work, but:

if(flag==1){
plot sin(x)
}
else if(flag==2){
plot cos(x)
}
else if(flag==3){
plot tan(x)
}

does not. I have tried many combinations of {} and placement of 'if' and 'else' to no avail. Does anyone know how to correctly implement 'else if' in gnuplot 5.x?

The gnuplot guide (http://www.bersch.net/gnuplot-doc/if.html) has no examples of the new logic syntax using 'else if' but does have examples using the old syntax, but I would rather avoid the old.

1
  • You can avoid using else in your second example and get what you need. Commented Sep 30, 2017 at 16:30

1 Answer 1

7

Based on a brief inspection of the source code of command.c in the latest version of Gnuplot, I would say that this feature is not supported. To be more specific, the relevant part can be found on line 1163 (see below). The parser first makes sure that the if is followed by a condition enclosed in parentheses. If the following token is a {, it activates the new syntax, isolates the entire if block enclosed in a pair of matching {} and optionally looks for an else which is however permitted to be followed also only with a {}-enclosed clause. Because of this, a simple script such as:

if(flag == 1){
    print 1;
}else if(flag == 2){
    print 2;
}

indeed produces the error message expected {else-clause}. One workaround would be to nest the if statements as:

if(flag == 1){

}else{
    if(flag == 2){

    }else{
        if(flag == 3){

        }
    }
}

which is admittedly slightly more verbose...

void
if_command()
{
    double exprval;
    int end_token;

    if (!equals(++c_token, "("))    /* no expression */
    int_error(c_token, "expecting (expression)");
    exprval = real_expression();

    /*
     * EAM May 2011
     * New if {...} else {...} syntax can span multiple lines.
     * Isolate the active clause and execute it recursively.
     */
    if (equals(c_token,"{")) {
    /* Identify start and end position of the clause substring */
    char *clause = NULL;
    int if_start, if_end, else_start=0, else_end=0;
    int clause_start, clause_end;

    c_token = find_clause(&if_start, &if_end);

    if (equals(c_token,"else")) {
        if (!equals(++c_token,"{"))
        int_error(c_token,"expected {else-clause}");
        c_token = find_clause(&else_start, &else_end);
    }
    end_token = c_token;

    if (exprval != 0) {
        clause_start = if_start;
        clause_end = if_end;
        if_condition = TRUE;
    } else {
        clause_start = else_start;
        clause_end = else_end;
        if_condition = FALSE;
    }
    if_open_for_else = (else_start) ? FALSE : TRUE;

    if (if_condition || else_start != 0) {
        clause = new_clause(clause_start, clause_end);
        begin_clause();
        do_string_and_free(clause);
        end_clause();
    }
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for looking into this. What a shame that support for 'else if' has been dropped. I guess your workaround is the best that can be done in such circumstances.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.