From: Pete Dashwood on
Richard wrote:
> On Jan 25, 12:19 am, "Pete Dashwood"
> <dashw...(a)removethis.enternet.co.nz> wrote:
>> Here's a couple of intellectual exercises if anyone is bored or
>> wants to think about something else for a break...
>>
>> Two problems relating to COBOL... (Assume Fujitsu NetCOBOL for both
>> solutions, or whatever version of COBOL you use if you can solve
>> them with your current compiler.)
>>
>> 1. Imagine you have a couple of thousand COBOL programs, all written
>> in ANSI 74 procedural COBOL. Almost every one of these programs
>> makes static calls to a number of subroutines (say there are around
>> 20 of these subroutines).
>>
>> sample call : CALL "X1" using p1, p2, p3, p4.
>>
>> Obviously, because of the static linkage, there is HUGE duplication
>> of these subroutines throughout the environment. (Every other
>> program has the same subroutines statically linked into it, and some
>> of these "subroutines" are "large"...) Changing any of the called
>> routines means a nightmare of identifying and recompiling every
>> program that uses it.
>>
>> For reasons connected with a new environment, you need these
>> routines to be dynamically called, but you cannot change all the
>> calling programs. (In fact, the client has insisted that the calling
>> program code must remain EXACTLY as it is.)
>>
>> Can you get to a dynamic environment WITHOUT recoding or amending the
>> calling programs?
>
> That is not a COBOL problem but is an implementation issue. Given that
> all CALLs would have to be using a literal to get static linkage then
> it is a matter of specifying the compiler and linking options
> applicable to the particular system being used. For Fujitsu it is
> DLOAD. Recompile and relink as a set of libraries and main program(s).

Yes, that is good. But you forgot to mention the ENTRY file that equates the
entry point to a .DLL at run time.

DLOAD implements "dynamic program linkage" (as opposed to "dynamic linkage")
and is a Fujitsu facility that allows the static calls to be processed
dynamically at run time, via an ENTRY file which equates the entry points ot
the respective libraries.

>
> Anyway, identifying the calling programs is not a 'nightmare', a
> simple 'grep -i "call \"name\"" *.cbl' will pick them up because with
> static linking the CALL must be of a literal.

As the site in question doesn't HAVE grep or an equivalent facility, for
them, it is a nightmare.

>
> With dynamic linking there may be a problem because the CALL can be a
> variable and the name may come from anywhere:

That's why the ENTRY file is important.


> in the case of most of
> my systems they can come from a system file that holds the menus and
> options, or can even be typed in directly.

The Fujitsu ENTRY file is a text file that can be managed externally in a
similar way. The PRIMA Toolset analyses any .DLL you specify and generates
this file for you.

>
>
>> 2. You are replacing a service routine (a called program, not in
>> COBOL) with a new routine, in COBOL. The new routine has the same
>> signature as the old one and receives several parameters from the
>> calling programs. Here is its signature:
>>
>> procedure division using
>> p1, p2, p3, p4.
>>
>> p1, p3, and p4 are always the same type and length.
>>
>> But, p2 can vary in length (it is a record buffer). It could be
>> defined in the working storage of each calling program as anything
>> from 20 to 8000 bytes. (Not with OCCURS... DEPENDING, just different
>> fixed length records.)
>>
>> Your called routine has to update this buffer; if you set a wrong
>> length in the Linkage section you will immediately crash on a
>> storage violation as soon as you try to write the record back.
>>
>> You might think it is pretty easy to pass a record length or some
>> other clue) as another parameter. Nope. The same rules as above; you
>> cannot modify the existing code, and it doesn't have a "p2-length"
>> in its parameter list.
>>
>> Clue: You MIGHT be able to derive the p2 length from an existing
>> "dictionary", accessible by your new program.
>>
>> Any thoughts on how the called program could be coded to accommodate
>> these requirements?
>
> You do it exactly the same way as the original (non-COBOL) program
> does currently.

No. The existing (non-COBOL program) has facilities that COBOL doesn't have,
so you CAN'T do that.

No more clues... :-)

Pete.
--
"I used to write COBOL...now I can do anything."


From: Pete Dashwood on
Charles Hottel wrote:
> "Pete Dashwood" <dashwood(a)removethis.enternet.co.nz> wrote in message
> news:7s2om7Fmu2U1(a)mid.individual.net...
>> Here's a couple of intellectual exercises if anyone is bored or
>> wants to think about something else for a break...
>>
>> Two problems relating to COBOL... (Assume Fujitsu NetCOBOL for both
>> solutions, or whatever version of COBOL you use if you can solve
>> them with your current compiler.)
>>
>> 1. Imagine you have a couple of thousand COBOL programs, all written
>> in ANSI 74 procedural COBOL. Almost every one of these programs
>> makes static calls to a number of subroutines (say there are around
>> 20 of these subroutines).
>>
>> sample call : CALL "X1" using p1, p2, p3, p4.
>>
>> Obviously, because of the static linkage, there is HUGE duplication
>> of these subroutines throughout the environment. (Every other
>> program has the same subroutines statically linked into it, and some
>> of these "subroutines" are "large"...) Changing any of the called
>> routines means a nightmare of identifying and recompiling every
>> program that uses it. For reasons connected with a new environment, you
>> need these
>> routines to be dynamically called, but you cannot change all the
>> calling programs. (In fact, the client has insisted that the calling
>> program code must remain EXACTLY as it is.)
>>
>> Can you get to a dynamic environment WITHOUT recoding or amending the
>> calling programs?
>>
>> 2. You are replacing a service routine (a called program, not in
>> COBOL) with a new routine, in COBOL. The new routine has the same
>> signature as the old one and receives several parameters from the
>> calling programs. Here is its signature:
>>
>> procedure division using
>> p1, p2, p3, p4.
>>
>> p1, p3, and p4 are always the same type and length.
>>
>> But, p2 can vary in length (it is a record buffer). It could be
>> defined in the working storage of each calling program as anything
>> from 20 to 8000 bytes. (Not with OCCURS... DEPENDING, just different
>> fixed length records.)
>>
>> Your called routine has to update this buffer; if you set a wrong
>> length in the Linkage section you will immediately crash on a
>> storage violation as soon as you try to write the record back.
>>
>> You might think it is pretty easy to pass a record length or some
>> other clue) as another parameter. Nope. The same rules as above;
>> you cannot modify the existing code, and it doesn't have a
>> "p2-length" in its parameter list.
>>
>> Clue: You MIGHT be able to derive the p2 length from an existing
>> "dictionary", accessible by your new program.
>>
>> Any thoughts on how the called program could be coded to accommodate
>> these requirements?
>>
>> FINALLY, as inspiration, some poetry...
>>
>> "They said it couldn't be done
>> But he, with a smile, denied it
>> He said:'How do you know that it cannot be done?'
>> Until you, at least, have tried it.
>>
>> So he rolled up his sleeves
>> And he gritted his teeth
>> And where there was doubt
>> He hid it.
>>
>> And he tackled that job that
>> 'Couldn't be done'....
>> And, Whaddya know?!!
>> He couldn't bloody do it..."
>>
> I remember two times when I was able to do something that "couldn't"
> be done. Afterwards the people who had said that (they were users)
> were very unhappy because they had previously be receiving large
> amounts of overtime for doing this manually.

My experience, garnered over many installations and cultures, has been that
when tech guys say: "You can't do that." what they really mean is: "I don't
know how to do that."

The most memorable case of this in my experience was in Spain when IBM told
a client that 3270 screens in conversational mode cannnot be automatically
refreshed. (The client wanted a chief dealer's screen to be automatically
updated when other dealers did a deal.). They were right; it says so in the
manual...

I provided a solution and 2 weeks later IBM were invited to a demo where
screens were automatically updated without Enter needing to be pressed,
exactly as the client required.

The IBM guys were shocked and claimed I must have modified their software
and it could no longer be supported by them. I hadn't. The solution was
implemented, in standard IBM COBOL at the time (I think it was MVS/OS),
using the standard IBM software without modification. I showed them how I
did it and they said: "Awww...Well, of course... if you do it like THAT..."
:-)

The point here is that because a company like IBM has huge credibility,
clients have little option but to believe what they say.

Management in most companies is similarly dependent on the advice they
receive from their tech leads. But sometimes those tech leads are not
imaginative. They have found a way of doing things and it works. Anything
outside that "cannot be done".

Some people have a major problem admitting that they don't know something,
or they can't imagine a solution.

The actual number of things you would want to do that actually "can't be
done" is very tiny. Most tech people get constrained by working in a given
environment with given tools and come to believe there is only one effective
approach and, if that can't be applied, then the problem is insoluble.

I learned many years ago to say: "I can't see a solution to that, but there
might be one. Maybe we should get someone else to take a look."

Sometimes the results have been amazing and a very good learning experience
for all concerned.

Sometimes a completely different approach can provide a solution. Setting
technology aside and looking only at what is needed can be fruitful.

All too often solutions are tailored to the technology currently in place,
simply because that is the technology currently in place. (Like, it isn't
possible to buy additional tools or expertise (or depart from the current
norm, because the benefits justify the departure...); that's not a tech.
decision.)

The bottom line is that, at least in my opinion, it is completely
unprofessional to say: "That can't be done." unless you qualify the
statement.

("That can't be done within the constraints of the toolset we have
available, BECAUSE...")

Much safer to simply say:"I don't know how to do that."

Pete.

--
"I used to write COBOL...now I can do anything."


From: Pete Dashwood on
Alistair wrote:
> On Jan 24, 11:19 am, "Pete Dashwood"
> <dashw...(a)removethis.enternet.co.nz> wrote:
>> Here's a couple of intellectual exercises if anyone is bored or
>> wants to think about something else for a break...
>>
>> Two problems relating to COBOL... (Assume Fujitsu NetCOBOL for both
>> solutions, or whatever version of COBOL you use if you can solve
>> them with your current compiler.)
>>
>> 1. Imagine you have a couple of thousand COBOL programs, all written
>> in ANSI 74 procedural COBOL. Almost every one of these programs
>> makes static calls to a number of subroutines (say there are around
>> 20 of these subroutines).
>>
>> sample call : CALL "X1" using p1, p2, p3, p4.
>>
>> Obviously, because of the static linkage, there is HUGE duplication
>> of these subroutines throughout the environment. (Every other
>> program has the same subroutines statically linked into it, and some
>> of these "subroutines" are "large"...) Changing any of the called
>> routines means a nightmare of identifying and recompiling every
>> program that uses it.
>>
>> For reasons connected with a new environment, you need these
>> routines to be dynamically called, but you cannot change all the
>> calling programs. (In fact, the client has insisted that the calling
>> program code must remain EXACTLY as it is.)
>>
>> Can you get to a dynamic environment WITHOUT recoding or amending the
>> calling programs?
>>
>
> How about renaming the called programs and replacing the original
> called program with a stub program to dynamically call the renamed
> program. I don't know if that would work under MVS as I don't know if
> a static recompile can call a program which executes a dynamic call.
>
That would certainly be one solution. Maybe not elegant, but it would
definitely reduce all the staticaly linked code.

I can't see any reason why a statically linked program shouldn't call a
program that makes dynamic calls, but it is many years since I worked in
that environment.

>
> But don't tease, give us solutions not problems (as a really shite
> manager of mine used to say).

Like many classes of problem, there is more than ONE way to do this. It
isn't a tease; these are real life examples taken from actual work I am
currently doing. The actual solutions implemented will be posted in a few
days after people who want to have a go at it have done so.

It is interesting to see how different environments would provide for a
solution, also.

Pete.

--
"I used to write COBOL...now I can do anything."


From: Pete Dashwood on
Arnold Trembley wrote:
> On 1/24/2010 1:26 PM, Alistair wrote:
>> On Jan 24, 11:19 am, "Pete Dashwood"
>> <dashw...(a)removethis.enternet.co.nz> wrote:
>>> Here's a couple of intellectual exercises if anyone is bored or
>>> wants to think about something else for a break...
>>> (snip)
>> How about renaming the called programs and replacing the original
>> called program with a stub program to dynamically call the renamed
>> program. I don't know if that would work under MVS as I don't know if
>> a static recompile can call a program which executes a dynamic call.
>>
>>
>> But don't tease, give us solutions not problems (as a really shite
>> manager of mine used to say).
>
> It should be possible to do this under MVS (now z/OS). The
> Binder/Linkage editor has a feature that allows you to relink an
> existing program, removing a statically bound subprogram and replacing
> it with a new statically bound subprogram. If that program is COBOL
> it can turn around and call any subprogram dynamically.
>
> You don't need to recompile the main calling program. But you would
> need to write two programs to replace each static subprogram, the
> first would be a stub with the same name, to call the second
> dynamically with whatever name you choose.
>
> It would help quite a bit if the main COBOL program uses COBOL or
> Language Environment runtime libraries.

Interesting post, Arnold. That is along the lines of what we actually did in
the end. We wrote a single .DLL that contained the stubs, and these called
the new subroutines dynamically.

The Fujitsu "Dynamic Program Linkage" model (implemented via the DLOAD
compiler option and with a suitable ENTRY file containing all the stub names
and equating them to the stub .DLL) , means there were no changes required
to the existing source, but it had to be batch recompiled with the DLOAD
option.

Only difference I can see from your solution is that we collected all the
stubs under one "umbrella" .DLL, rather than as separate called modules.

Pete.
--
"I used to write COBOL...now I can do anything."


From: Richard on
On Jan 25, 11:28 am, "Pete Dashwood"
<dashw...(a)removethis.enternet.co.nz> wrote:
> Richard wrote:
> > On Jan 25, 12:19 am, "Pete Dashwood"
> > <dashw...(a)removethis.enternet.co.nz> wrote:
> >> Here's a couple of intellectual exercises if anyone is bored or
> >> wants to think about something else for a break...
>
> >> Two problems relating to COBOL... (Assume Fujitsu NetCOBOL for both
> >> solutions, or whatever version of COBOL you use if you can solve
> >> them with your current compiler.)
>
> >> 1. Imagine you have a couple of thousand COBOL programs, all written
> >> in ANSI 74 procedural COBOL. Almost every one of these programs
> >> makes static calls to a number of subroutines (say there are around
> >> 20 of these subroutines).
>
> >> sample call : CALL "X1" using p1, p2, p3, p4.
>
> >> Obviously, because of the static linkage, there is HUGE duplication
> >> of these subroutines throughout the environment. (Every other
> >> program has the same subroutines statically linked into it, and some
> >> of these "subroutines" are "large"...) Changing any of the called
> >> routines means a nightmare of identifying and recompiling every
> >> program that uses it.
>
> >> For reasons connected with a new environment, you need these
> >> routines to be dynamically called, but you cannot change all the
> >> calling programs. (In fact, the client has insisted that the calling
> >> program code must remain EXACTLY as it is.)
>
> >> Can you get to a dynamic environment WITHOUT recoding or amending the
> >> calling programs?
>
> > That is not a COBOL problem but is an implementation issue. Given that
> > all CALLs would have to be using a literal to get static linkage then
> > it is a matter of specifying the compiler and linking options
> > applicable to the particular system being used. For Fujitsu it is
> > DLOAD. Recompile and relink as a set of libraries and main program(s).
>
> Yes, that is good. But you forgot to mention the ENTRY file that equates the
> entry point to a .DLL at run time.

I didn't 'forget' it, it is not needed. The CALLs are literals so if
each called routine is named as, say, libX1.so then CALL "X1" will
find it without an ENTRY file.

> DLOAD implements "dynamic program linkage" (as opposed to "dynamic linkage")
> and is a Fujitsu facility that allows the static calls to be processed
> dynamically at run time, via an ENTRY file which equates the entry points ot
> the respective libraries.

It only needs the ENTRY file if you have bundled the routines into one
library file that needs to be identified.


>
> > Anyway, identifying the calling programs is not a 'nightmare', a
> > simple 'grep -i "call \"name\"" *.cbl' will pick them up because with
> > static linking the CALL must be of a literal.
>
> As the site in question doesn't HAVE grep or an equivalent facility, for
> them, it is a nightmare.

If it doen't have grep or equivalent then _everything_ is a nightmare.

If they have Rexx or PERL or even AWK then they do have an equivalent
to grep. Writing a simple COBOL program to search source code for
CALLs should not be beyond them.

Your "doesn't HAVE grep or an equivalent" sounds exactly like like "it
couldn't be done".

> > With dynamic linking there may be a problem because the CALL can be a
> > variable and the name may come from anywhere:
>
> That's why the ENTRY file is important.

The problem as given was that currently the CALLs were static. This
means that it was CALL literal, thus no problem. But even with CALL
variable the system finds libNAME.so without any ENTRY file being
required.


> > in the case of most of
> > my systems they can come from a system file that holds the menus and
> > options, or can even be typed in directly.
>
> The Fujitsu ENTRY file is a text file that can be managed externally in a
> similar way. The PRIMA Toolset analyses any .DLL you specify and generates
> this file for you.

Not needed.

> >> 2. You are replacing a service routine (a called program, not in
> >> COBOL) with a new routine, in COBOL. The new routine has the same
> >> signature as the old one and receives several parameters from the
> >> calling programs. Here is its signature:
>
> >> procedure division using
> >> p1, p2, p3, p4.
>
> >> p1, p3, and p4 are always the same type and length.
>
> >> But, p2 can vary in length (it is a record buffer). It could be
> >> defined in the working storage of each calling program as anything
> >> from 20 to 8000 bytes. (Not with OCCURS... DEPENDING, just different
> >> fixed length records.)
>
> >> Your called routine has to update this buffer; if you set a wrong
> >> length in the Linkage section you will immediately crash on a
> >> storage violation as soon as you try to write the record back.
>
> >> You might think it is pretty easy to pass a record length or some
> >> other clue) as another parameter. Nope. The same rules as above; you
> >> cannot modify the existing code, and it doesn't have a "p2-length"
> >> in its parameter list.
>
> >> Clue: You MIGHT be able to derive the p2 length from an existing
> >> "dictionary", accessible by your new program.
>
> >> Any thoughts on how the called program could be coded to accommodate
> >> these requirements?
>
> > You do it exactly the same way as the original (non-COBOL) program
> > does currently.
>
> No. The existing (non-COBOL program) has facilities that COBOL doesn't have,
> so you CAN'T do that.
>
> No more clues... :-)

Fujitsu has ANY LENGTH