Menu

#2653 Windows: plot command line continuation using "\" within function block does not work

None
closed-fixed
nobody
None
2023-12-30
2023-09-26
najevi
No

The same piece of demo script is submitted for 4 separately reported bugs.

I would have expected that using the backslash, "\", to break a very long command (illustrated here with just a short plot command) so as to make the command more easily human-readable would be supported within a function block.

## Some bugs related to function blocks and/or data blocks 
##  (gnuplot v6 rc1  on Windows 11)
##
## Given that function blocks are still experiemental I hesitate to call these "bugs" however,
## they are definitely not intuitive/expeceted behaviour. 
## To experience each bug uncomment that/those script line(s) that has/have just a single hash '#'.
##
##(1) using the backslash "\" to break a (very long) plot command across multiple lines (within a function block) throws an error: "invalid character \"
##(2) datablock definition within an if or else compound statement throws error: "attempt to define data block from invalid context"
##(3) "function block" usage of the special string variables, ARGC, ARG0, ARG1..ARG9 is not consistent with "call" usage
##(3a) cannot access ARGV[1] as the string, ARG1; 
##(3b) cannot access function block name as ARG0; (script filename is returned instead)
##(3c) ... but _can_ access argument count for function block as ARGC
##(4) inline data "plot '-'" may not be used within a function block (somewhat akin to the ban on defining a data block within a function block)
##

function $myPlot(strSource,strFont) << _EOFD
    set title strSource." - variable color and orientation in plotstyle 'with labels'" offset 0,-2

    ## within a function block, a backslash throws the error: "invalid character \" .. but not within main script block
    #plot @strSource \
    #   using 1:1:2:3:0 \
    #   with labels rotate variable tc variable font @strFont
    plot @strSource using 1:1:2:3:0 with labels rotate variable tc variable font @strFont

    ## ARG0 returns script filename (not function block name) ..  but ARGC correctly returns a count of arguments passed to function
    ##return sprintf("function, %s, completed; with %d arguments", "$myPlot", ARGC)
    return sprintf("function, %s, completed; with %d arguments", ARG0, ARGC)
_EOFD

function $myInlinePlot << _EOFD
    set title "function block INLINE - variable color and orientation in plotstyle 'with labels'" offset 0,-2
    ## within a function block, attempting to use inline data as the data source causes script execution to hang without any error message
    ## ... Ctrl+C will not terminate script execution from this point
    ## ... the only remedy I have found is to locate the hung gnuplot.exe process and terminate it 
    plot '-' using 1:1:2:3:0 with labels rotate variable tc variable font ",8"
1 one -30
2 two -60
3 three -90
4 four -120
5 five -150
6 six -180
7 seven -210
8 eight -240
9 nine -270
10 ten -300
11 eleven -330
12 twelve -360
EOD
    ## it seems that inline data may not be used within a function block 
    ## (somewhat akin to the ban on defining a data block within a function block)
    ## however, the script hangs without any error message
    return sprintf("function, %s, completed; with %d arguments", "$myInlinePlot", ARGC)
_EOFD

##
## Additional data columns can be used to hold text rotation or color
## for plot style "with labels"
##

debug = 1

#if (debug) {   ## defining a datablock inside an if/else throws: "attempt to define data block from invalid context"
    $Data1 <<EOD
    1 one -30
    2 two -60
    3 three -90
    4 four -120
    5 five -150
    6 six -180
    7 seven -210
    8 eight -240
    9 nine -270
    10 ten -300
    11 eleven -330
    12 twelve -360
EOD
## leading whitespace before the above EOD _does_ throw an error: "no datablock named $Data2"
##  ... fair enough since $Data1 definition never correctly ends if EOD not found at start of line.
#   }
#else {
$Data2 <<EOD
1 one -30
2 two -60
3 three -90
4 four -120
5 five -150
6 six -180
7 seven -210
8 eight -240
9 nine -270
10 ten -300
11 eleven -330
12 twelve -360
EOD
#   }

$Data3 <<EOD
1 one -30
2 two -60
3 three -90
4 four -120
5 five -150
6 six -180
7 seven -210
8 eight -240
9 nine -270
10 ten -300
11 eleven -330
12 twelve -360
EOD

set angle degrees
unset key
set title "variable color and orientation in plotstyle 'with labels'" offset 0,-2

set xrange [0:13]
set yrange [0:13]
set xtics 1,1,12 nomirror
set ytics 1,1,12 nomirror
set border 3

stringFont = "\"Times,10\""     ## exercising care to escape double quotes is necessary (and appropriate)
##plot $Data3 using 1:1:2:3:0 with labels rotate variable tc variable font ",20"
## no error from using backslash to break the above plot command over multiple lines
plot $Data3 \
    using 1:1:2:3:0 \
    with labels rotate variable tc variable font @stringFont
pause mouse close

printerr $myPlot("$Data1","\"Times,12\"")
pause mouse close

printerr $myPlot("$Data2","\"Times,16\"")
pause mouse close

printerr $myPlot("$Data3","\"Times,20\"")
pause mouse close

set title "INLINE - variable color and orientation in plotstyle 'with labels'" offset 0,-2
plot '-' using 1:1:2:3:0 with labels rotate variable tc variable font ",24"
    1 one -30
    2 two -60
    3 three -90
    4 four -120
    5 five -150
    6 six -180
    7 seven -210
    8 eight -240
    9 nine -270
    10 ten -300
    11 eleven -330
    12 twelve -360
EOD
#   EOD
    ## leading whitespace before EOD, above, does not _seem_ to matter however,
    ## for the inline data example within a function block this leading whitspace was avoided just to remove any possible doubt
pause mouse close

## to demonstrate bug (4) (and this script hanging without any error message) uncomment the following function call
#printerr $myInlinePlot()
#pause mouse close

Discussion

  • najevi

    najevi - 2023-09-26

    The above demo used only a short plot command so perhaps the impact of forcing a user to put the plot command on one, unbroken, line is lost. Please compare the following two sections of a block function definition.

    The interpreter friendly version first:

    plot @inFile using ($f($1)[3]) : ($f($1)[4]) : ($f($1)[5]) : ($f($1)[6]) : ($f($1)[7]) with sectors linecolor @varColor , @inFile using ($f($1)[3]+$f($1)[5]/2) : ($f($1)[4]-0.4) : 1 : (-fixT*( ($f($1)[3]+$f($1)[5]/3) + pi/2 ) ) : ($f($1)[7]) with labels nopoint center rotate variable textcolor @varColor font @labelFont , $ConeOutline using 1:2:3:4:5 with sectors linecolor variable
    

    and, second, the more human-friendly version:

    plot @inFile \
        using ($f($1)[3]) : ($f($1)[4]) : ($f($1)[5]) : ($f($1)[6]) : ($f($1)[7]) \
        with sectors linecolor @varColor \
        , @inFile \
        using ($f($1)[3]+$f($1)[5]/2) : ($f($1)[4]-0.4) : 1 : (-fixT*( ($f($1)[3]+$f($1)[5]/3) + pi/2 ) ) : ($f($1)[7]) \
        with labels nopoint center rotate variable textcolor @varColor font @withLabels \
        , $ConeOutline using 1:2:3:4:5 with sectors linecolor variable
    
     
  • Ethan Merritt

    Ethan Merritt - 2023-09-27

    I am not able to reproduce any problems with having the "user-friendly" version of your plot command inside a function block. Both the single line and the 3-line version of the plot command work without error.

    Tested using 6.0rc1 under linux
    Tested using the gp60rc1-win64-mingw.zip binary under Wine

    Could this be an error specific to a particular native Windows platform?
    It seems odd to me that handling the trailing backslash would behave any differently inside a function block definition than it does in other contexts. Can you simplify the test case to a minimal reproducer? The following script words for me. Does it fail for you?

    function $testplot() << EOF
    plot \
          sin(x)
    EOF
    evaluate $testplot()
    
     
  • najevi

    najevi - 2023-09-28

    Could this be an error specific to a particular native Windows platform?

    Yes, you may be on to something there.
    The small test case you sent throws an error for me. Just not the line continuation error I had seen previously.

    Do you see anything in my compile options (below) that might hint at a difference between the gnuplot.exe I am running and what is standard?

    gnuplot> show version long
    
            G N U P L O T
            Version 6.0 patchlevel rc1    last modified 2023-07-08
    
            Copyright (C) 1986-1993, 1998, 2004, 2007-2023
            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')
    
    Compile options:
        +READLINE  -LIBREADLINE  +HISTORY
        +UNICODE  +OBJECTS  +STATS  +WATCHPOINTS  +EXTERNAL_FUNCTIONS +POLARGRID
        +COMPLEX_FUNCS  +LIBCERF  +AMOS
        +GD_PNG  +GD_JPEG  +GD_TTF  +GD_GIF  +ANIMATION
        -USE_CWDRC  +USE_MOUSE  +HIDDEN3D_QUADTREE
        +FUNCTIONBLOCKS +CHI_SHAPES
        64-bit integer arithmetic
        sizeof(struct coordinate) = 64 with extra coordinate
    GNUPLOT_DRIVER_DIR = ""
    GNUPLOT_PS_DIR     = "share/PostScript"
    HELPFILE           = "C:\Program Files\gnuplot\bin\wgnuplot.chm"
    
    gnuplot>
    

    I've modified the small test case you provided in 4 progressively different ways to see what does (and does not!) cause it to throw an error on my Windows 11 installation of gnuplot v6 rc1.
    There is clearly a problem with handling of both:
    1. parentheses and
    2. backslash
    at my instalation.

    function $testplot() << EOF
    plot \
          sin(x)
    EOF
    evaluate $testplot()
    
    # output #
    > gnuplot -persist '.\testplot.txt'
    
    function $testplot() << EOF
                         ^
    ".\testplot.txt" line 1: expecting ')'
    
    function $testNoPARENplot << EOF
    plot \
          sin(x)
    EOF
    evaluate $testNoPARENplot()
    
    # output #
    > gnuplot -persist '.\testNoPARENplot.txt'
    
    plot \
         ^
    "$testNoPARENplot" line 1: invalid character \
    
    function $testNoLB_NoPARENplot << EOF
    plot sin(x)
    EOF
    evaluate $testNoLB_NoPARENplot()
    
    # no errors; plot output as expected
    
    function $testNoLBplot() << EOF
    plot sin(x)
    EOF
    evaluate $testNoLBplot()
    
    # output #
    > gnuplot -persist '.\testNoLBplot.txt'
    
    function $testNoLBplot() << EOF
                             ^
    ".\testNoLBplot.txt" line 1: expecting ')'
    
    function $testNoLB_DummyARGplot(a) << EOF
    plot sin(a*x)
    EOF
    evaluate $testNoLB_DummyARGplot(1.0)
    
    # no errors; plot output as expected
    

    These next four variations involve an IF statement however, the only new light it sheds (for me) is a reminder as to how the interpreter treats a { }-block attached to an IF as a one-line-statement so that when an error is reported for a line within that { }-block, the correct line number for the error cannot be displayed. (Nor can the offending line of code be displayed.) This is a digression.

    function $testNoLB_NoPAREN_IFplot << EOF
    if (1) {
    plot sin(x)
    }
    EOF
    evaluate $testNoLB_NoPAREN_IFplot()
    
    # no errors; plot output as expected
    
    function $testNoLB_DummyARG_IFplot(a) << EOF
    if (1) {
    plot sin(a*x)
    }
    EOF
    evaluate $testNoLB_DummyARG_IFplot(1.0)
    
    # no errors; plot output as expected
    
    function $testNoLB_IFplot() << EOF
    if (1) {
    plot sin(x)
    }
    EOF
    evaluate $testNoLB_IFplot()
    
    # output #
    > gnuplot -persist '.\testNoLB_IFplot.txt'
    
    function $testNoLB_IFplot() << EOF
                                ^
    ".\testNoLB_IFplot.txt" line 1: expecting ')'
    
    function $testDummyARG_IFplot(a) << EOF
    if (1) {
    plot \
        sin(a*x)
    }
    EOF
    evaluate $testDummyARG_IFplot(1.0)
    
    # output #
    > gnuplot -persist '.\testDummyARG_IFplot.txt'
    "$testDummyARG_IFplot" line 2: invalid character \
    
     
    • Ethan Merritt

      Ethan Merritt - 2023-09-28

      Sorry, sorry. My bad.
      There was a typo in the test case. That's what I get for re-typing into the box rather than cut-and-paste from the actual test file.
      The test should be

      function $testplot << EOF
      plot \
            sin(x)
      EOF
      evaluate $testplot()
      

      Note the lack of parentheses in the function definition. That was your 2nd test run and is correct. I think the program actually ought to accept empty parentheses if there are no arguments but apparently that isn't working. However that's a separate issue from your problem with backslashes. Let's put that aside for now.

      I may have missed it, but it is unclear to me whether you get this same error when a backslash is used outside a function block. Does it work directly from the command line or in a script to split the plot command? What about commands other than plot? At this point I don't know whether I should be looking for something added by the function block code or whether this is come totally general problem about input lines.

      plot \
         sin(x)
      

      Your listed compile options seem to match those in the binary from Tatsuro Matsuoka. I'm afraid I can't offer any guidance on compiling under Windows. I have never worked with Windows as either a developer or a user. There are some suggestions written by other people in the INSTALL file distributed with the gnuplot source package. It might also be instructive to try Matsuoka's binary to see if you get the same error there, which I think would indicate there is something different about your machine (or Windows 11?) setup rather than being a problem with your compiled binary per se.

       
  • najevi

    najevi - 2023-09-28

    Correct, testNoLB_NoPARENplot resembles what you intended to send me and that caused no errors and the plot output was as expected. Only after inserting the \ to continue the plot command over two lines did an error get generated. (see testNoPARENplot above)

    I may have missed it, but it is unclear to me whether you get this same error when a backslash is used outside a function block. Does it work directly from the command line or in a script to split the plot command?

    Easy enough to miss when my demo script is as long as it is.
    I can confirm that no error is thrown when \ is used to continue a command line over two lines within the main script block. Refer to this snippet (from my original, non-minimal, test case) and also see the test case (later on) which uses the humble print command.

    plot $Data3 \
        using 1:1:2:3:0 \
        with labels rotate variable tc variable font @stringFont
    pause mouse close
    

    That was parsed by the interpreter with no error and the plot output was as expected.

    Also, I can confirm that at the gnuplot command line the following session throws no error:

    gnuplot> function $testplot << EOF
    plot \
            sin(x)
    EOF
    gnuplot> evaluate $testplot()
    gnuplot>
    

    Testing a command other than plot ...

    print \
        sprintf("some command other than plot - in main script block")
    
    function $testprint << EOF
    print \
        sprintf("some command other than plot - within function block")
    EOF
    evaluate $testprint()
    
    # output #
    > gnuplot .\testprint.txt
    some command other than plot - in main script block
    
    print \
          ^
    "$testprint" line 1: invalid character \
    

    The print statement line continuation \ is interpreted fine in the main script "block" but throws an error in the subsequent function block.

    It looks to me as though Tatsuro Matsuoka's binary is the win64-mingw compiled binary found at the Files section of this Sourceforge site, correct?
    viz.

    gp60rc1-win64-mingw.zip     2023-07-23  62.9 MB 
    SHA1: 4b538d6bb2d0cde7677970786f1d25496e0f04ca
    MD5: 2a0c144c0efaf611f268f3c7e49a4d91
    

    If so, then this is the gnuplot v6 rc1 binary that I am currently using.

    I will see if I can test/contrast all of this under linux today.

     
  • najevi

    najevi - 2023-09-28

    Unfortunately the only linux command line that I can readily access is an ubuntu installation under WSL. (Windows Subsystem for Linux)

    It has gnuplot v5.4.2 and of course, 5.x.x does not support function blocks.
    Upon extracting the tarball (gnuplot-6.0.rc1.tar.gz) and then running ./configure
    ... there were just too many no's and then the kicker:
    "no acceptable C compiler found in $PATH"

    So I am afraid I cannot contrast the behavior of "v6 rc1" under linux against what I see running under Windows 11.

     
    • Ethan Merritt

      Ethan Merritt - 2023-09-28

      I have tested the linux behavior extensively, using both gcc and clang and several alternative input paths (readline / editline / gnuplot-builtin-nanoemacs).
      I have also tested the behavior of the Windows binary from SourceForge, although I am running it under Wine (version wine-8.0) on linux rather than natively on a Windows box.

      I believe you that you are seeing a problem under native Windows 11, but until you or someone else can pin it down more specifically I don't even know what code to look at.

      Is it possible that the problem is in the file properties (specifically the line termination settings) of your input script? Do you get the same error if you type the commands in the console window rather than reading them from a file?

       
      • najevi

        najevi - 2023-09-29

        With reference to

        Also, I can confirm that at the gnuplot command line the following session throws no error:

        above, I have previously confirmed that the problem does not appear when one of these backslashes are typed into the command line of a gnuplot console session.

        I can confirm that the end of line style is the CRLF typical of windows ASCII files.
        Ought that be a contributing factor?

         
        • Ethan Merritt

          Ethan Merritt - 2023-09-29

          Can you attach here a script that shows the problem when run? I will try executing that script here directly from your file. Up until now I have been using test files created here, which contain unix-style line termination.

           
          • najevi

            najevi - 2023-09-29

            Oh, brilliant thought!!

            Prompted by this I tweaked Notepad++ settings to allow me to create Unix-style (LF) end-of-line sequences. This tweak does not change files that already have Windows-CRLF EOLs but any new files created do adopt Unix-LF EOLs.

            So attached you will find four files.

            The two files using Windows style (CRLF) both throw the error.
            The two files using Unix style (LF) do not throw the error!

            Actual output from running each script at the PS (Windows PowerShell) command line is shown as comment at the end of each file.

            1. I now have a solution to move forward with and
            2. You now have some insight as to what might need tweaking to accommodate the Windows environment.
             
  • Ethan Merritt

    Ethan Merritt - 2023-09-29
    • summary: plot command line continuation using "\" within function block is not supported --> Windows: plot command line continuation using "\" within function block does not work
    • Group: -->
    • Priority: -->
     
  • Ethan Merritt

    Ethan Merritt - 2023-09-30

    In the end it was so easy.
    Now fixed in 6.1 and will be in 6.0 -rc3

     
  • Ethan Merritt

    Ethan Merritt - 2023-09-30
    • status: open --> pending-fixed
     
  • Ethan Merritt

    Ethan Merritt - 2023-12-30
    • Status: pending-fixed --> closed-fixed
     

Log in to post a comment.