How to run cobc without an input source file, but via a pipe?
Asked Answered
J

2

15

Is it possible to execute COBOL code without providing input files? I'm using cobc.

I tried to pipe the code to the cobc process:

$ cat my-input.cbl | cobc
cobc: No input files

To compile a file and run it, I do:

cobc -x di.cbl -o a && ./a

Supposing I don't have a file, I have just the code somewhere (maybe in a variable, as string), can I pass it to cobc? It would be better than creating the file and then compile it and run it.

In my case, the user inputs the source code of a COBOL program and that's a string variable. Currently, I save the code in a file, I compile it and then I execute it. It would be nice if cobc would support piping the code snippet in stdin or even as cli option, and generate a binary file or even showing the result directly (not sure if that's a good or bad idea). node, for example, has the -p option: node -p 'console.log(1)' -- this will output 1\nundefined. g++ has this feature –

Joinville answered 29/7, 2015 at 18:48 Comment(10)
You'd have to make it a feature-request to the GnuCOBOL project. Currently at SourceForge, probably moving on soon.Anacrusis
@BillWoodger Maybe could you do it and post an answer? :) I'm not really familiar with how SourceForge works...Jewfish
To not have the source code in a file carries a big implication of "generated code". Is that the type of thing you are thinking of? Have you got a couple of examples where it would be beneficial to pipe rather than use a file? If you can do that, I can post the actual request.Anacrusis
@BillWoodger In my case, the user inputs the source code of a COBOL program and that's a string variable. Currently, I save the code in a file, I compile it and then I execute it. It would be nice if cobc would support piping the code snippet in stdin or even as cli option, and generate a binary file or even showing the result directly (not sure if that's a good or bad idea). node, for example, has the -p option: node -p 'console.log(1)' -- this will output 1\nundefined. g++ has this featureJewfish
OK. That's good service from Brian :-) There's a branch for source-code contributions if you have something interesting (sounds like it) and you want to share it around.Anacrusis
Yes, a nice touch. And only the second COBOL bounty :-)Anacrusis
@BillWoodger And only the second COBOL bounty -- how can I know that? :)Jewfish
@BillWoodger Here is what I did. :) +100 points for Brian! He deserves them!Jewfish
Thanks very much. I thought it sounded interesting :-)Anacrusis
Ahh, more nerd cred. Yayys. Muchly appreciated @IonicăBizăuMinistrant
M
6

It was not possible yesterday, but it is today, and I'll get the changes into the source tree as soon as the lead approves the change.

Two small changes to the compiler source and - can be used to indicate stdin.

prompt$ echo 'program-id. test. display "hello".' | cobc -free -frelax -x -o thing -
-: 1: Warning: PROCEDURE DIVISION header missing - assumed
prompt$ ls -l
-rwxrwxr-x. 1 btiffin btiffin 13192 Jul 31 17:27 thing
prompt$ ./thing
hello

This will then work for any operating system, and not just those with /dev/stdin support (which, for now, as paxdiablo wrote, is a very valid option with GNU/Linux and the like).

And as an aside; cobc can already be used as a POSIX interpreter.

#!/usr/local/bin/cobc -xvg
       identification division.
       program-id. SAMPLE.

       procedure division.
       display "scripted" end-display
       goback.

       end program SAMPLE.

with

prompt$ chmod +x interp.cob
prompt$ ./interp.cob

giving

Command line:   /usr/local/bin/cobc -xvg ./interp.cob 
Preprocessing:  ./interp.cob -> interp.i
Return status:  0
Parsing:        interp.i (./interp.cob)
Return status:  0
Translating:    interp.i -> interp.c (./interp.cob)
Executing:      gcc -std=gnu99 -c -I/usr/local/include -pipe -Wno-unused
                -fsigned-char -Wno-pointer-sign -g -o "/tmp/cob25113_0.o"
                "interp.c"
Return status:  0
Executing:      gcc -std=gnu99 -Wl,--export-dynamic -o "interp"
                "/tmp/cob25113_0.o" -L/usr/local/lib -lcob -lm -lgmp
                -lncursesw -ldb -ldl
Return status:  0

Sadly, that is just for the build. Execution requires an extra step.

prompt$ ./interp
scripted

There is no compiler option for "run the code now", so a -J (fixed form) and -j (free form) option will be added. Run job, becomes a new form of -x (create executable) but will also execute the binary at end of processing. Then we'll have access to cobc "scripts" in POSIX. Currently all that is allowed is build, and the run has to be a separate command.

And the inherent limitations that POSIX hashbang lines are limited to a single argument, so -j -free wouldn't work, nor would -j -Xref etc, but within limits, it'll allow for cobc scripts.

That's another one line change to the compiler, and 400 lines of option parsing and documentation. ;-)

Should be ready for testing in a few hours. Again, these changes will require approval from all the other compiler maintainers, but I don't see any reason for not allowing the improvements. Two commits, one for - as stdin, and -J -j for run job at end of compile.

Ministrant answered 31/7, 2015 at 22:39 Comment(12)
Tested ok. cobc now supports -j, compile, link and go. So cobc shell scripting will be in the 2.0 pre-release, as well as being able to, well, compile, link and go, from a cobc command line.Ministrant
Thanks! :) Could you please provide some links to the source code where this was introduced (e.g. commit links or so)? This is great news!Jewfish
@IonicăBizău, cobc from stdin, went in with Rev 630. sourceforge.net/p/open-cobol/code/HEAD/tree Cheers.Ministrant
I'm using Ubuntu and I installed cobc using apt-get install open-cobol. When will the new version available? Thanks! I will open a bounty on this question and give you +50 points. :-)Jewfish
Oh, it may not be in repositories for a good long while. The current open-cobol is from 2009 maybe 2011. COBOL moves slow. gnucobol 2.0 may not be officially released for many more months, then it'll take time to be into the hands of package builders. Many many months away, and possibly years.Ministrant
But; I checked this in with all the maintainer mode scripts already run. So if you svn checkout svn://svn.code.sf.net/p/open-cobol/code/branches/gnu-cobol-2.0 gnucobol and then cd gnucobol and then ./configure ; make ; make check && sudo make install ; sudo ldconfig it should be good to go in /usr/local/binMinistrant
Check out the sources again, and the new -j switch is in. Full on POSIX scriptable ala #!/usr/local/bin/cobc -jxF followed by lines of free form COBOL. Skip the -F if you use fixed form in the script.Ministrant
Ha! It worked. :) The tests are failing, so I skipped the make check step. Compiling code from stdin works nice. :) One day I will give you another bunch of reputation points.Jewfish
Sweet! I'll try and get an entry for the FAQ written this weekend. (And thanks for the appreciation points @IonicăBizău). Nice.Ministrant
@IonicăBizău, you are now in the FAQ at opencobol.add1tocobol.com/gnucobol/… Thanks muchly.Ministrant
@IonicăBizău congratulations on the fame, Ionică. arstechnica.com/information-technology/2015/08/… That is awesome. Well done. Yayys.Ministrant
Yeah! Saw it yesterday. It's awesome. I really didn't expect such a feedback. :)Jewfish
A
3

With a bit of sneakiness, this can be done. First create a file we can use for testing:

000100 * HELLO.COB OpenCOBOL FAQ example
000200 IDENTIFICATION DIVISION.
000300 PROGRAM-ID. Hello.
000400 PROCEDURE DIVISION.
000500    DISPLAY "Hello world!".
000600    STOP RUN.

Now you already know we can compile and run this:

pax> cobc -x hello.cob ; hello
Hello world!

But, if you don't want it in a file, you can simply use the /dev/stdin "file" to get the information in, adjusting the output file so it gives you what you want:

pax> cat hello.cob | cobc -x /dev/stdin -o hello2 ; hello2
Hello world!

That's coming from a file but it's not cobc opening the file up to compile it, so you could replace cat hello.cob with any command that generated a COBOL source file to its standard output.

All you need to do in your program is to open up a process running cobc with the /dev/stdin file as input and a suitable output file, then pipe your COBOL program into it.

Anvers answered 31/7, 2015 at 9:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.