Menu

#1176 macro expansion does not work for system call within do loop

closed
nobody
None
1
2012-10-05
2012-10-01
No

I am running gnuplot 2.6 in ubuntu 12.04. I downloaded the .deb file from sourceforge on 13/9-2012.

It is normally possible to use macro expansion on string variables in system calls. e.g. variable = system (@macro) where macro can be a complicated command built up of several concatenated strings allowing flexible use of utilities like awk from within gnuplot scripts.

However this does not seem to work within the block structured do for ( ) { } loops.

See attached script and attached file with the standard result and standard error. NB this is a very simplified example but throws exactly the same error as the much much more complicated case I am trying to use.

Discussion

  • Anonymous

    Anonymous - 2012-10-01

    Correction I downloaded the .deb from the Ubuntu website - it was compiled for the development version of Ubuntu (12.1 quantal quetzal).

     
  • Andrew Rasmussen

    Are you sure it is version 2.6? When you type 'gnuplot' at the command line what version does it say it is?

     
  • Anonymous

    Anonymous - 2012-10-01

    example script

     
  • Anonymous

    Anonymous - 2012-10-01

    example error message

     
  • Anonymous

    Anonymous - 2012-10-01

    Yes I am sure. I did not use the package in the Ubuntu 12.04 repositories. I had been using 4.5 on windows before a switched to Ubuntu and some of the features added since 4.4 are too useful to be without (basically I'm saying that this is a great program that is getting better).

    When running in interactive mode I get...

    G N U P L O T
    Version 4.6 patchlevel 0    last modified 2012-03-04 
    Build System: Linux x86\_64
    
    Copyright \(C\) 1986-1993, 1998, 2004, 2007-2012
    Thomas Williams, Colin Kelley and many others
    
    gnuplot home:     http://www.gnuplot.info
    faq, bugs, etc:   type "help FAQ"
    immediate help:   type "help"  \(plot window: hit 'h'\)
    
     
  • Anonymous

    Anonymous - 2012-10-01

    I see what you mean... That was a typo by me. I really hope this doesn't mean that the bug report gets ignored.

     
  • Andrew Rasmussen

    OK, so it is 4.6, not 2.6 (that makes more sense!). This does look like a strange bug. When I delete one character from the end of the variable name I get different behavior (the following is command line input/output, not in a loop):

    gnuplot> Macro_expansion_for_print_statement_inside_do_loop = '"test"'
    gnuplot> print @Macro_expansion_for_print_statement_inside_do_loop
    warning: Macro_expansion_for_print_statement_inside_do_loop is not a string variable

    gnuplot> print
    ^
    constant expression required

    gnuplot> Macro_expansion_for_print_statement_inside_do_loo = '"test"'
    gnuplot> print @Macro_expansion_for_print_statement_inside_do_loo
    test

    Are you using very long macro names? I'm not sure what you are trying to do, but you may look into the 'eval' command also, e.g.:

    set macros
    whoo = '"test".ii'
    do for [ii=1:2] {
    print "gnuplot: ".@whoo
    eval "system(\"echo system: ".@whoo."\")"
    }

    That script works for me, giving this output:

    $ gnuplot ./min2.plt
    gnuplot: test1
    system: test1
    gnuplot: test2
    system: test2

     
  • Anonymous

    Anonymous - 2012-10-01

    If I run the commands you did at the command line I get exactly the same behaviour as you. Did you try running the example script with the do loop commented and uncommented? For me when the do loop is present it throws the error message I uploaded. When it isn't the script works fine.

    I don't think that eval does what I am trying to do. I need to call the shell. The system calls I have in the full version of the script (which works robustly if not within a do loop) are of the form:

    string_part_1_these_are_approx_35_characters = "awk -F, ' first part of awk command"
    string_part_3_these_are_approx_35_characters = "rest of awk command ' datafile"

    sample_name = "the sample name"
    systemcall = '"'.string_part_1_these_are_approx_35_characters.sample_name.string_part_3_these_are_approx_35_characters.'"' # this is a long statement that builds up the system call for the particular sample_name.

    Some_variable = system(@systemcall) # this is exactly the form used in the script.

    It looks ugly but it works perfectly outside of a do for () {} loop and after some initial set up allow lots of similar plots to be made with annotations specific the the individual samples.

     
  • Ethan Merritt

    Ethan Merritt - 2012-10-02

    It is possible to use macro expansion inside a {} loop, but it may not do what you expect. The entire bracketed clause is treated like one very long line of input. Any macros are expanded at the time the line is first read. This only happens once. If there is a loop, it is executed over and over using the same alread-processed string of commands that was originally read in. In other words, during repetitive looping the macros are not reevaluated, indeed they do not exist any more since they were expanded prior to looping.

    By the same token, macro _definitions_ (not expansions) inside a {} clause are not usable inside that same clause. At the time the clause is read in, the expansion will fail because the macro has not been previously defined. At the time the clause is executed, it's too late to do macro expansion.

    This is all consistent with the documented behavior of macros, once you understand that a bracketed clause acts as a single line.

    On the bright side, I don't see any need for macros at all in the example script you gave. You can just pass the constructed string directly to system() or print(). Nothing is gained by trying to make it a macro.

     
  • Anonymous

    Anonymous - 2012-10-03

    OK fair enough. I have downgraded the priority are there any other changes I should make so that this thread sinks quietly into nowhere?

    It is still slightly annoying behaviour -text macros are quite useful- but as you say it appears to still be possible do what I want in this case. Is this treatment for {} loops planned to continue or will they in future versions be treated as multiple lines?

    I apologise for misunderstanding the documentation. I was aware of both of those things but hadn't made the connection in my head for some reason.

    I would say that the strange behaviour noticed by andyras is a separate issue but may simply be that macro names have a limited length?

    Thank you for your response.

     
  • Anonymous

    Anonymous - 2012-10-03
    • priority: 5 --> 1
     
  • Ethan Merritt

    Ethan Merritt - 2012-10-05
    • status: open --> closed
     
  • Ethan Merritt

    Ethan Merritt - 2012-10-05

    The maximum length of an identifier (gnuplot variable name) is currently hard-coded as 50 bytes.

    gp_types.h:#define MAX_ID_LEN 50 /* max length of an identifier */

    It could be increased, but I would rather see a change to use dynamic strings everywhere. If anyone is looking for a project.....

     

Log in to post a comment.