Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suppressor.jl don't capture all stdout from CBindinged function #46

Open
Suavesito-Olimpiada opened this issue Sep 22, 2022 · 3 comments · May be fixed by #47
Open

Suppressor.jl don't capture all stdout from CBindinged function #46

Suavesito-Olimpiada opened this issue Sep 22, 2022 · 3 comments · May be fixed by #47

Comments

@Suavesito-Olimpiada
Copy link

I'm making a package called LibTeXPrintf.jl in which I need to capture stdout to define some variables.

But @capture_out doesn't capture all the output unless I had run already a printing operation without capturing it. I'll upload a MWE and an asciinema once I have both.

@Suavesito-Olimpiada
Copy link
Author

Here is the asciinema https://asciinema.org/a/523250.

@marcom
Copy link

marcom commented Jul 11, 2023

Here is a little testing script, similar to JuliaDocs/IOCapture.jl#16 (comment):

Test script
using Suppressor, Test

nbytes = [10^0, 10^1, 10^2, 10^3, 10^4, 10^5, 10^6]

function test_print(str)
    out = @capture_out begin
        print(str)
    end
    # save in a bool to avoid printing long strings when test fails
    cap_output_equals_str = out == str
    @test cap_output_equals_str
end

function test_puts(str)
    retval = 0
    out = @capture_out begin
        retval = @ccall puts(str::Cstring)::Cint
    end
    @test retval == length(str) + 1
    # save in a bool to avoid printing long strings when test fails
    cap_output_equals_str = out == str * "\n"
    @test cap_output_equals_str
end

function test_puts_flush(str)
    retval = 0
    out = @capture_out begin
        retval = @ccall puts(str::Cstring)::Cint
        Libc.flush_cstdio()
    end
    @test retval == length(str) + 1
    # save in a bool to avoid printing long strings when test fails
    cap_output_equals_str = out == str * "\n"
    @test cap_output_equals_str
end

function run_testset(fn::Function)
    @testset verbose=true "$fn" begin
        for (i, n) in enumerate(nbytes)
            # print different letters for each test
            c = collect('A':'Z')[i]
            @testset "$n" begin
                fn(c^n)
            end
        end
    end
end

@testset "Suppressor cstdio" verbose=true begin
    run_testset(test_print)
    run_testset(test_puts)
    run_testset(test_puts_flush)
end
Test script output
Test Summary:     | Pass  Fail  Total  Time
Suppressor cstdio |   22    13     35  3.1s
  test_print      |    7            7  0.1s
    1             |    1            1  0.1s
    10            |    1            1  0.0s
    100           |    1            1  0.0s
    1000          |    1            1  0.0s
    10000         |    1            1  0.0s
    100000        |    1            1  0.0s
    1000000       |    1            1  0.0s
  test_puts       |    5     9     14  2.1s
    1             |    1     1      2  2.0s
    10            |    1     1      2  0.0s
    100           |    1     1      2  0.0s
    1000          |    1     1      2  0.0s
    10000         |    1     1      2  0.0s
    100000        |          2      2  0.0s
    1000000       |          2      2  0.0s
  test_puts_flush |   10     4     14  0.0s
    1             |    2            2  0.0s
    10            |    2            2  0.0s
    100           |    2            2  0.0s
    1000          |    2            2  0.0s
    10000         |    2            2  0.0s
    100000        |          2      2  0.0s
    1000000       |          2      2  0.0s

If you look at the errors, you can see that with Libc.flush_cstdio() it works for sizes 10k bytes and below, but fails for larger outputs.

From these results it seems to me that just adding a single Libc.flush_cstdio() as is done in #47 would help and work correctly for short cstdio outputs, but for longer outputs one would have to additionally keep on reading from the pipe so it doesn't fill up.

@Suavesito-Olimpiada
Copy link
Author

Interesting, I need to look at it to know how to correct it for good. Thanks for the test script.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants