Author Topic: Pipe Console Output to QB64 program!  (Read 2131 times)

0 Members and 1 Guest are viewing this topic.

Offline SpriggsySpriggs

  • QB64 Developer
  • Forum Resident
  • Posts: 1089
  • If you're API and you know it clap your hands
    • My GitHub
Pipe Console Output to QB64 program!
« on: October 26, 2020, 01:16:52 PM »
So I have been keeping this code solely on the Discord server but since a new user needed help with something that my code deals directly with I have decided to go ahead and make a dedicated post. I have made a small header file called "pipecom.h" which allows you to run a command and pipe back the console output to your program. Credit for help goes to @luke for making a version that doesn't have memory issues. Here is an example of some code you can run:

Code: QB64: [Select]
  1. DECLARE LIBRARY "pipecom"
  2.     FUNCTION pipecom$ (cmd AS STRING)
  3.  
  4.  
  5. F = pipecom("dir /b *.BAS")
  6.  

 


It can be used just like SHELL and the library works in Mac, Windows, and Linux. No more having to write to a file and then read it back! Of course, with Windows, you might see a console window that appears for the duration of the SHELLed program. To avoid this, use "PowerShell -windowstyle hidden" before the rest of your command and escape any CHR$(34)s with a backslash. Windows now operates just as well as Linux and Mac with no console window.
« Last Edit: November 05, 2020, 10:35:57 AM by SpriggsySpriggs »
If you're API and you know it clap your hands
My GitHub

Offline bplus

  • Forum Resident
  • Posts: 7043
  • b = b + ...
Re: Pipe Console Output to QB64 program!
« Reply #1 on: October 26, 2020, 04:43:11 PM »
Yes! this looks to be a good replacement for DIR$(). I like that it comes in as string and you can get all the details or just file names.

@SpriggsySpriggs
Are there other switches? Probably have to leave it to Linux users to look up the ones they might need and I will ask you about the Windows ones ;-))

Also this doesn't seem to work if I add path to spec but that's OK, I guess. :)

Offline SpriggsySpriggs

  • QB64 Developer
  • Forum Resident
  • Posts: 1089
  • If you're API and you know it clap your hands
    • My GitHub
Re: Pipe Console Output to QB64 program!
« Reply #2 on: October 26, 2020, 05:01:34 PM »
Yes! this looks to be a good replacement for DIR$(). I like that it comes in as string and you can get all the details or just file names.

@SpriggsySpriggs
Are there other switches? Probably have to leave it to Linux users to look up the ones they might need and I will ask you about the Windows ones ;-))

Also this doesn't seem to work if I add path to spec but that's OK, I guess. :)

@bplus This simply runs a command/program. Any command/program. However you would do it for SHELL is how it would be done for this. I'm not doing anything with the command except passing it to the C++ library and getting the output. Let me see the code you say isn't working with a path spec.
If you're API and you know it clap your hands
My GitHub

Offline bplus

  • Forum Resident
  • Posts: 7043
  • b = b + ...
Re: Pipe Console Output to QB64 program!
« Reply #3 on: October 26, 2020, 06:04:40 PM »
I tried "C:\\*.*" and "..\*.*" the root and the directory just above current.

Offline SpriggsySpriggs

  • QB64 Developer
  • Forum Resident
  • Posts: 1089
  • If you're API and you know it clap your hands
    • My GitHub
Re: Pipe Console Output to QB64 program!
« Reply #4 on: October 26, 2020, 06:41:07 PM »
I tried "C:\\*.*" and "..\*.*" the root and the directory just above current.
Did you put "dir"?
If you're API and you know it clap your hands
My GitHub

Offline SpriggsySpriggs

  • QB64 Developer
  • Forum Resident
  • Posts: 1089
  • If you're API and you know it clap your hands
    • My GitHub
Re: Pipe Console Output to QB64 program!
« Reply #5 on: October 26, 2020, 07:28:50 PM »
I tried "C:\\*.*" and "..\*.*" the root and the directory just above current.

@bplus I'm confused, bro. I did this and it worked fine:

Code: QB64: [Select]
  1. DECLARE LIBRARY "pipecom"
  2.     FUNCTION pipecom$ (cmd AS STRING)
  3.  
  4.  
  5. F = pipecom("dir C:\")
  6. 'F = pipecom("dir /b C:\*.*") 'if you want just filenames
  7.  
  8.  
  9.  
  10. F = pipecom("dir ..\")
  11. 'F = pipecom("dir /b ..\") 'if you want just filenames
  12.  

 
 

 
 


P.S. Again, it isn't meant to just replace DIR$(). This is just a library that pipes ANY console command/program output back to the QB64 program. You just have to know the usage of the commands you are calling.
« Last Edit: October 26, 2020, 07:35:00 PM by SpriggsySpriggs »
If you're API and you know it clap your hands
My GitHub

Offline bplus

  • Forum Resident
  • Posts: 7043
  • b = b + ...
Re: Pipe Console Output to QB64 program!
« Reply #6 on: October 26, 2020, 09:12:45 PM »
OK thanks Spriggsy, I thought in Windows it didn't matter which way the slant leaned but in this case it does!

It does work fine leaning the integer division way \ but not regular division /

And it doesn't matter 1 or 2 slants to root drive.

 ;-))
« Last Edit: October 26, 2020, 09:14:07 PM by bplus »

Offline Jesterdev

  • Newbie
  • Posts: 3
Re: Pipe Console Output to QB64 program!
« Reply #7 on: October 27, 2020, 08:13:30 PM »
New to QB64, and this is exactly what I came here looking for. I'm attempting to create an interactive shell as a way of learning QB64 and teaching myself the the Linux shell. I've attempted a few things, but QB64 says it cannot find the library. I even tried pointing directly to it. Where exactly does the pipecom.h file need to be located?


Offline SpriggsySpriggs

  • QB64 Developer
  • Forum Resident
  • Posts: 1089
  • If you're API and you know it clap your hands
    • My GitHub
Re: Pipe Console Output to QB64 program!
« Reply #8 on: October 27, 2020, 08:17:00 PM »
@Jesterdev First off, welcome to the family! Second, glad you found something you find useful! Third, the pipecom.h file needs to be kept in the same folder as your source OR if you move it to a different folder, just change your DECLARE LIBRARY block to show the path where it is. Fourth, be sure to join our Discord server! Many of us are active there and since we all live in various timezones you are bound to receive an answer to any questions you have! https://discord.gg/7E4W9Pv
« Last Edit: October 27, 2020, 08:19:21 PM by SpriggsySpriggs »
If you're API and you know it clap your hands
My GitHub

Offline Jesterdev

  • Newbie
  • Posts: 3
Re: Pipe Console Output to QB64 program!
« Reply #9 on: October 27, 2020, 08:37:38 PM »
Thank you, appreciate the response. That's where I have it, in the same folder as my source. Still says it cannot find it. I'll try the discord also. Even copy and pasting the code from this post results in the same thing.
« Last Edit: October 27, 2020, 08:39:00 PM by Jesterdev »

Offline SpriggsySpriggs

  • QB64 Developer
  • Forum Resident
  • Posts: 1089
  • If you're API and you know it clap your hands
    • My GitHub
Re: Pipe Console Output to QB64 program!
« Reply #10 on: October 27, 2020, 08:41:24 PM »
@Jesterdev Ah, I'm now wondering if your QB64 executable is in the same folder as your source! If not, then you do need to change the DECLARE LIBRARY to show the path (without the extension)
If you're API and you know it clap your hands
My GitHub

Offline FellippeHeitor

  • QB64 Developer
  • Forum Resident
  • Posts: 3010
  • Let it go, this too shall pass.
    • QB64.org
Re: Pipe Console Output to QB64 program!
« Reply #11 on: October 27, 2020, 08:42:51 PM »
Either keep the .h file in QB64’s folder or with your source. If you choose to keep it with the source, declare it as "./pipecom".

Welcome aboard.

Offline luke

  • QB64 Developer
  • Seasoned Forum Regular
  • Posts: 284
Re: Pipe Console Output to QB64 program!
« Reply #12 on: October 27, 2020, 09:24:59 PM »
It's worth mentioning that this will leak memory on each call, because the string copy isn't freed.

Freeing that data turns out to be an absolute pain though because of how QB64 calls external functions. I tried to come up with a version that doesn't leak:
Code: [Select]
string pipecom_buffer;

const char* pipecom (char* cmd){
    FILE* stream;
    const int max_buffer = 256;
    char buffer[max_buffer];
    pipecom_buffer.clear();

    stream = popen(cmd, "r");
    if (stream) {
        while (!feof(stream)) {
            if (fgets(buffer, max_buffer, stream) != NULL) {
                pipecom_buffer.append(buffer);
            }
        }
        pclose(stream);
    }
return pipecom_buffer.c_str();
}
It appears to work, but it relies on QB64's behaviour of (usually) making a copy of string data. There are cases where it doesn't copy (like if you do `LEN(pipecom("foo"))`) because the string is read-only and that's okay, but I can't verify that it'll be fine in all cases.

Anyway, if you noticed your memory usage was steadily increasing over time, try this version instead.

Offline SpriggsySpriggs

  • QB64 Developer
  • Forum Resident
  • Posts: 1089
  • If you're API and you know it clap your hands
    • My GitHub
Re: Pipe Console Output to QB64 program!
« Reply #13 on: October 27, 2020, 09:26:47 PM »
@luke I noticed that if I only return a c_str then I lose data in Windows. Have you tried this in Windows? This is a common problem mentioned in Stack Overflow.
Never mind, your way works. People on Stack Overflow didn't have a good solution.
« Last Edit: October 27, 2020, 09:34:31 PM by SpriggsySpriggs »
If you're API and you know it clap your hands
My GitHub

Offline Jesterdev

  • Newbie
  • Posts: 3
Re: Pipe Console Output to QB64 program!
« Reply #14 on: October 27, 2020, 09:29:00 PM »
That was the trick! "./" worked. I also tried "/home/name/QB64/source/program/" and that didn't take either. The wiki was not exactly clear either, but I tried.

Thank so much, I really appreciate it. I'm jumping ahead a bit here. I'm working through Terry Ritchie's QB64 Game Programming tutorial, but I've been excited about this project for some time and can't help myself.