From: Michael Wojcik on
Richard wrote:
> On Jan 26, 1:48 am, Fred Mobach <f...(a)> wrote:
>> Pete Dashwood wrote:
>>> As the site in question doesn't HAVE grep or an equivalent facility,
>>> for them, it is a nightmare.

What *are* they running on? A 1401?

>> Then a download at the Free Software Cygwin
>> might be your solution in case they're running a version of MS-Windows.
> grep has available for decades on almost all systems including Windows
> and IBM mainframes. For example

For that matter, Windows has included findstr.exe as part of the core
OS for many years, and it includes regular-expression support. findstr
is somewhat more awkward than grep, lacks the egrep-mode EREs, and has
some odd limitations (mostly due to the brain-dead parser in cmd.exe),
but for most purposes it's a usable grep substitute on Windows systems.

I have multiple Unix emulators on my Windows dev machines (typically
Microsoft's SFU / SUA, Cygwin, and MinGW), but I don't bother
switching to a bash or ksh window just for things like file searching.
The Windows commandline tools still aren't great (though Powershell is
coming along), but they're often adequate.

Michael Wojcik
Micro Focus
Rhetoric & Writing, Michigan State University
From: Michael Wojcik on
Pete Dashwood wrote:
> Michael Wojcik wrote:
>> Pete Dashwood wrote:
>>> 2. You are replacing a service routine (a called program, not in
>>> COBOL) with a new routine, in COBOL. ...
>>> 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....
>> There isn't enough information in the problem.
>> Either the length of the buffer is available out-of-band, or it isn't.
>> The problem says it "MIGHT" be available from a dictionary. That's not
>> a useful statement. It might be available from magic computer elves,
>> too; but either we don't have to accommodate the case where it is not
>> available from that source, in which case the problem is solved, or we
>> do, in which case we are no closer to a general solution.
> Yes, that is fair comment. I used MIGHT because there was some doubt about
> whether the "dictionary" would actualy be built and accessible.

OK, but we still don't know whether we can use it in our solution...

> Also, this
> is meant to be a fun exercise and not to be taken too literally (I should
> have known that posting it here would preclude any element of fun... :-( )

I didn't say I wasn't having fun with it! Just that there wasn't
enough information to solve the problem. (Clearly, there was enough to
speculate at some length... :-)

> Take it, for the sake of the exercise that a it IS possible to derive the
> length of the buffer in the calling program, from a dictionary.

OK. In that case I'd probably use reference modification to operate on
the buffer using the correct length, assuming standard procedural COBOL.

In our comms code, it's pretty common to have linkage like:

01 incoming-record.
03 rec-length pic x(4) comp-x.
03 rec-data pic x.

Then "rec-data" is actually processed with refmod, for example:

move rec-data(1:rec-length) ...

Obviously that's a highly simplified version - with no length
validation, you'd have a nifty stack-smashing opportunity here - but
you get the idea.

(In .NET managed code, I could declare a working-storage "binary-char
unsigned occurs any" item, then set its length and contents from the
linkage item. Then I'd have an Array object with the correct length
and all the other Array methods available, which would make the
subsequent code safer and cleaner.)

Michael Wojcik
Micro Focus
Rhetoric & Writing, Michigan State University
From: Michael Wojcik on
Pete Dashwood wrote:
> Michael Wojcik wrote:
>> Pete Dashwood wrote:
>> - In Windows, use the pointer-testing routines or SEH to probe
>> locations in the buffer to see if they're writable
> I hadn't thought of that one. Not elegant but a possibility.

Yes, it's rather a hack. And the Windows IsBadReadPtr / IsBadWritePtr
functions are deprecated (and particularly dangerous in a
multithreaded process), so SEH would be the way to go - but it's
difficult to use in a language that doesn't have built-in support.

> I did consider trying to detect the end of the buffer by checking characters
> and trapping a storage violation, but it is pretty awful isn't it? (As the
> buffer could be 8000 characters this approach was ruled out fairly early on
> in the piece.)

Agreed. It's inelegant and the overhead is bad. It can be improved by
only testing each page, on a paged-memory system - with a maximum
length of 8000 bytes, you'd only have to test three addresses on the
typical 4KB-page OS. (8000 bytes could begin partway through one page,
contain all of a second, and stretch into a third.)

But deliberately trapping, however popular with the "use exceptions
for control flow" crowd, really isn't something you want to do on
every call.

> Another possibility would be to drop into Assembler and get the parameter
> length from the stack (this is Windows), assuming COBOL puts it there. (I
> have a feeling the calling program pushes each parameter and its length onto
> the stack (the calling mode determines who cleans up the stack afterwards
> if I remember rightly),but it is ages since I worked at that level and I
> simply don't have time for the experiments I would need to do to confirm it.

Depends on the implementation, and in many cases on compiler options
or language extensions. The standard Windows calling conventions don't
put parameter lengths on the stack, but compilers can implement other
calling conventions. They can even be interoperable (ie, a COBOL
implementation could include length info without breaking calls to C,
for example), if the length information doesn't change the layout of
the normal parameter values. For example, a COBOL implementation could
put length info after the last parameter, effectively making it a
"hidden" parameter, as long as it's using a convention where the
caller cleans up the stack.

Michael Wojcik
Micro Focus
Rhetoric & Writing, Michigan State University
From: Richard on
On Jan 27, 12:56 am, "Pete Dashwood"
<dashw...(a)> wrote:
> Richard wrote:
> > On Jan 26, 10:51 am, "Pete Dashwood"
> > <dashw...(a)> wrote:
> >> Richard wrote:
> >>> On Jan 26, 2:39 am, "Pete Dashwood"
> >>> <dashw...(a)> wrote:
> >>>> Richard wrote:
> >>>>> On Jan 25, 11:28 am, "Pete Dashwood"
> >>>>> <dashw...(a)> wrote:
> >>>>>> Richard wrote:
> >>>>>>> On Jan 25, 12:19 am, "Pete Dashwood"
> >>>>>>> <dashw...(a)> wrote:
> <snipped>
> >>> _YOUR_ solution may not run without it. _MY_ solution does not need
> >>> it. The problem as stated was to get "_a_ dynamic environment", and
> >>> did not require it to be identical to yours.
> >> No, of course not and there are a number of possible solutions.
> >> If you like yours, that's fine. I don't care.
> >> But be aware that I chose the solution I did in full awareness of
> >> the facts surrounding Fujitsu's Dynamic Program Linkage model both
> >> with and without the use of an Entry file.
> > So, why did you claim that I "forgot" it ?
> Because you stated:
>  "For Fujitsu it is DLOAD. Recompile and relink as a set of
>  libraries and main program(s).
> "
> "Libraries" in this environment requires an Entry file.
> Individual, separately called modules do not.

The Fujitsu Cobol systems that I use can only produce and use two
types of files through the mechanism of '(re)compile and (re)link':
executables for main programs and shared object libraries (or DLLs). A
'module' is not a file type that can be created or loaded by a call.

It happens that a library can contain multiple programs (subroutines)
or just one. If each library contains a single program then, as I
stated, a _set_ of libraries is required, one for each program. If I
had said "_A_ library" then an entry file would be required but,
according to the manual:

"""The entry information may be omitted if the shared object file name
is """".

From: Clark F Morris on
On Mon, 25 Jan 2010 12:20:41 +1300, "Pete Dashwood"
<dashwood(a)> wrote:

>Arnold Trembley wrote:
>> On 1/24/2010 1:26 PM, Alistair wrote:
>>> On Jan 24, 11:19 am, "Pete Dashwood"
>>> <dashw...(a)> 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
>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.

Unless none of the components change, I don't see the advantage of the
single DLL but then I'm used to the IBM MVS environment. For that
environment, assuming that the subroutines were all separately
compiled, the change would be re-compile the calling programs changing
the compile option from NODYNAM to DYNAM. This would not work for
CICS programs. The second part means that the length of parameter 2
must have been determinable based on data passed in the other
parameters and action could then be taken based on that data. If the
field had a prefix, there are cute tricks to allow getting at that