Stowing programs using Natural command line

Hello, I’m using Natural V 6.1.1 Pl 15 on Linux. I know this is long post, so if you want to answer only one of my questions, I would be very happy :).

I had this idea of creating Natural programs from outside the editor to do simple tasks as reading some Adabas fields. Simple as:

000090 1 PRO_TABLES VIEW OF PRO_TABLES
000100 2 COMP
000110 2 TAB_NO
000120 2 TAB_KEY
000130 2 TAB_DATA(1:1)
000140 END-DEFINE
000360 READ PRO_TABLES BY TAB_SUP1 EQ ‘X124’
000410 WRITE WORK FILE 1 TAB_NO ‘,’ TAB_KEY ‘,’ TAB_DATA(*)
000430 END-READ

Let say i generate that source as ‘read.nsp’. then i want to call something like:

natural parm=PRODIS bp=nat31 etid=$i “stack=(logon PRODIS;READ;FIN)”

[b]

  1. I need a way to save the file under Natural database and stow it programmaticaly, can it be achieved?

  2. Is there any way to save the workfile under other name? how can i change the file output without messing with the Natural configuration?

  3. Is there a way to output to the stdout without having those “MORE” prompts? Then, i could capture the stdout without having to store all my data on disk.

  4. Is there a way of READING a file that has not the name of a workfile?

  5. Is there any Natural language construct that could let me store data (as in a linked list) whitout having to store it on disk? If this could be done, it would be very helpfull.
    [/b]

Thank you very much!

  1. you can use the parameter CMSYNIN for Natural command and input data (see http://techcommunity.softwareag.com/ecosystem/documentation/natural/nat622unx/ops/ops-batchmode.htm#ops-batch-sample and process this data in your script calling natural. You can omit the STACK parameter then. Your file could contain the following:
logon PRODIS1
EDIT
PRO_TABLES VIEW OF PRO_TABLES 
2 COMP 
2 TAB_NO 
2 TAB_KEY 
2 TAB_DATA(1:1) 
END-DEFINE 
READ PRO_TABLES BY TAB_SUP1 EQ 'X124' 
WRITE WORK FILE 1 TAB_NO ',' TAB_KEY ',' TAB_DATA(*) 
END-READ 
END
.
RUN
FIN

2)DEFINE WORK FILE 1 “myfilename”

3)FORMAT PS=0

4)same as 2)

5)???

I got a question to point 5) …
Do you mean something like this?

natural ... "stack=(logon PRODIS;READ;FIN)" | do_some_things_in_linux.bash 

Here’s a link to an older discussion. It’s not exactly your problem, but maybe you can find some good tips.

http://natural.forums.softwareag.com/viewtopic.php?t=136

  1. About number five, i don’t know if you ever used C++, what i’m talking about is something like:

std::vector vecInt;

vecInt.push_back(1);
vecInt.push_back(2);
vecInt.push_back(3);
etc…

I think the only way to do something “like that” in Natural (ie storing data in a place with dinamical storage capacity) is using work files. I’m right?

Perhaps X-ARRAYs will help you (from NAT6.2.2. OS on). See http://techcommunity.softwareag.com/ecosystem/documentation/natural/nat622unx/pg/pg_defi_xarry_0230.htm for more details.

Thank you for that info. i’m using Natural V 6.1.1 Pl 15 and it seems to work in that version too. i’ll try it.

THIS DOES NOT WORK!!! Why why why is so difficult to do something as easy as printing without pagebreaks in Natural!!! Oh - My - God !!!

Ok, i just had to scream for a second… :oops: please help

This should print the whole thing without “MORE” prompts, but those “MORE” keep appearing:

000010 * PROGRAMA ABM_T94P ( ABM DE USUARIOS EN LA TABLA DE AUTORIZACIONES
000020 *                     DE VENDEDORES --TABLA 094 )
000030 ************************************************************************
000040 DEFINE DATA
000050 LOCAL
000060 *
000070 1 I (N10)
000080 *
000090 1 PRO_TABLES VIEW OF PRO_TABLES
000100   2 COMP
000110   2 TAB_NO
000120   2 TAB_KEY
000130   2 TAB_DATA(1:1)
000140 *
000150 1 CUSTOMER VIEW OF PRO_CUSTOMER
000160   2 CUSTOMER_NO
000170   2 SALES_MAN
000180 *
000190 1 #SP_CUST (A9)
000200 1 REDEFINE #SP_CUST
000210   2 #SP_CUST_NO (A8)
000220   2 #SP_CUST_REC(L)
000230 *
000240 1 #CLAVE  (A4)
000250 1 #USER   (A8)
000260 *
000270 1 USER VIEW OF PRO_USER
000280   2 COMP
000290   2 USER_ID
000300   2 USER_GROUP
000310   2 USER_PASSW
000320   2 USER_NAME
000330   2 USER_STATUS
000340 END-DEFINE
000350 *
000360 define printer (1) output 'video'
000370 format (1) PS=0
000380 *
000390 READ PRO_TABLES BY TAB_SUP1 EQ 'X130'
000400     IF TAB_NO GT 130
000410       ESCAPE BOTTOM
000420     END-IF
000430
000440   MOVE TAB_KEY TO #USER
000450   WRITE(1) notitle  #USER / #user /* ',' TAB_DATA(*)
000460 *
000470 END-READ
000480 *
000490 END

:oops: :oops:

The mistake is: video is not equal to stdout!
format PS=0 uses the page size of the physical device. If you output to video, you use the number of lines on your display. Output to another unix device (except video!) and it will work.

But why do you print the data you want to capture? Why do you not write it to a work file?

Because of the unix way of doing things.

How many times have you done, for example,
ls | grep -e ‘myfile’, or
who | grep ‘user’, or
ps | grep ‘something’

and things like that?

I have a multiuser enviroment and sometimes it’s really a pain to use workfiles, because i don’t really know if i’m breaking the workfile another user is using.

if i had the posibility of using the pipe (|) to redirect natural output, i wouldn’t need to use workfiles.

Then you can define a printer script LPTnn that echoes all input from STDIN to STDOUT. That’s the normal NATURAL way to do things in UNIX.

The reason for your problems is: Natural normally uses block oriented devices and UNIX uses character oriented devices. So Natural emulates block oriented devices in UNIX and that’s a real problem for UNIX people.

One method is to redirect a work- or printfile to /dev/stdout. But Natural uses STDOUT for displaying the Natural version etc. But Natural doesn’t use STDERR. So please try the follwing:
Write a little program to produce some lines of output on STDERR. For example:

define data local
01 #n3 (N3)
end-define
define work file 1 "/dev/stderr" type "ASCII"
for #n3 = 1 to 100
  write work file 1 #n3
end-for
close work file 1
end

Save it and type in the following on the linux command line

natural batch bp=xxxxx parm=xxxxx stack="(logon mylib;run 100LINES;fin)" 2>&1 1>/dev/null | grep 2

The trick is:
You redirect STDOUT (with the Natural-Version etc.) into /dev/null
You redirect STDERR to STDOUT
So you can pipe STDOUT

Another solution is to use the “real batch mode” in Natural. There you are able to redirect all output to STDOUT without defining a workfile. Here’s a sample program again:

define data local
01 #n3 (N3)
end-define
for #n3 = 1 to 100
  write notitle #n3
end-for
end

And the command line on Linux/Unix looks like this:

natural batchmode cmprint="/dev/stdout" bp=xxxxx parm=xxxxx stack="(logon mylib;run 100LINES;fin)"

The output on STDOUT is then:

Logon accepted to library MYLIB.
   1
   2
   3
   4
...
  97
  98
  99
 100
NAT9995 Natural session terminated normally.
Used CPU time:   0 00:00:00.02
Elapsed time:    0 00:00:00.04

With the natural-parameters bmtime=off endmsg=off you can supress the last three lines of the output. But I don’t know a way to suppress the logon-Message at the beginning. Of course | tail +2 would work, but a natural-paramter would be better …