From: Richard on
On Jan 26, 10:51 am, "Pete Dashwood"
<dashw...(a)removethis.enternet.co.nz> wrote:
> Richard wrote:
> > On Jan 26, 2:39 am, "Pete Dashwood"
> > <dashw...(a)removethis.enternet.co.nz> wrote:
> >> Richard wrote:
> >>> 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.
>
> >> But then you wouldn't be using a library for your solution and yiour
> >> statement: "Recompile and relink as a set of _libraries _ " is not
> >> correct.
>
> > A libNAME.so _is_ a dynamic link library on Unix/Linux (so = shared
> > object) on Windows it would be named libNAME.DLL
>
> > It may be that my set of libraries has one module per library but that
> > was not excluded as a solution, it is just that you were unaware of
> > that option.
>
> What makes you think I was unaware of it? I was totally aware of it.  We
> opted for a single .DLL because it is a better solution.

If you were "totally aware" that my solution did not require an ENTRY
file then why did you claim that I "forgot" it and that it was
"important" ?

Anyway whether a bundled DLL/so is 'better' or not was not part of the
problem you specified.


> >>>> 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.
>
> >> Or several library files, which ios what you siuggested.
>
> > You had specified there were about 20 called routines, I suggested
> > about 20 dynamic load libraries with naming that reflected the
> > routine's call name so no ENTRY file needed.
>
> > How hard is that ?
>
> Not hard, just a poorer solution.

No, it isn't. Just because it is not the same as _YOUR_ solution does
not make it "poorer".

In particular you had "a couple of thousand programs" so 20 or so
separate dlls is not a burden but if unit testing is a requirement for
production release then if one routine changed, or another routine was
added, then before distributing the one bundled dll file, every
routine in that file would need to be tested and signed off.

> It means 20 different objects to be looked after when they can be in a
> single .DLL. (Library)

It is called modularity.

> Just to avoid the use of an Entry file which is generated by a tool anyway?
>

No, it is not to _avoid_ the use of an ENTRY file, it is to have a
_better_ system (IMHO), one that incidentally does not require an
ENTRY file.


> >>>>> 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.
>
> >> Perhaps...:-)
>
> >> You'd be amazed the number of sites that actually function without
> >> tools a "good" site would take for granted.
>
> >>> 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.
>
> >> It was suggested.
>
> >>> Your "doesn't HAVE grep or an equivalent" sounds exactly like like
> >>> "it couldn't be done".
>
> >> No, I didn't say that.
>
> > What you implied was that 'an equivalent couldn't be done'.
>
> Whatever inference you took is entirely a matter for you. There was no
> implication.
>
>
>
>
>
> >>>>> 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.
>
> >> Only if each subroutine is it's own module.
>
> > Each subroutine is in its own dynamic library, yes. Your point being ?
>
> >>>>> 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.
>
> >> Funny, the solution doesn't run wthout it. (All of the claaed stubs
> >> arein a single .DLL)
>
> > _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 ?


>
>
> >>>>>> 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
>
> >> That's a good point and I hadn't thought of it.
>
> >> As I mentioned in a different post, there is usually more than one
> >> solution...
>
> Pete.
> --
> "I used to write COBOL...now I can do anything."

From: Pete Dashwood on
docdwarf(a)panix.com wrote:
> In article <7s5m5eFc1bU1(a)mid.individual.net>,
> Pete Dashwood <dashwood(a)removethis.enternet.co.nz> wrote:
>> docdwarf(a)panix.com wrote:
>>> In article <7s420vFav7U1(a)mid.individual.net>,
>>> Pete Dashwood <dashwood(a)removethis.enternet.co.nz> wrote:
>>>
>>> [snip]
>>>
>>>> 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.
>>>
>>> [snip]
>>>
>>>
>>>
>>> We have different approaches, Mr Dashwood; after hearing 'You must
>>> have modified our software' my response would have been 'I have not
>>> done so and I find it insulting, unprofessional and unimaginative
>>> for you to blatantly misrepresent the facts demonstrated here in an
>>> effort to cover your lack of knowledge by impugning, belittling and
>>> attempting to dismiss my skills by asserting such a thing. I will
>>> be more than willing to supply sample code as soon as your check
>>> clears the bank.'
>>
>> Well, I DID tease them a little bit before revealing the solution.
>> :-)
>
> As I said, Mr Dashwood, we see it differently. As I see it you had a
> set of skills and experiences which could be combined in a manner
> which generated a solution which someone else - in this case IBM, an
> organisation which has a rather large profit-motive - could use to
> make money.
>
> No problem there... you want to make money from my abilities, *I*
> want to make money from my abilities. Works both ways, I'd say.
>
> (Note that this is for another party involved. IBM, I believe, was
> not collecting your timesheets nor paying for your invoices.

Nobody collected timesheets from me as I worked on a daily basis, and was
contracted direct to the client. However, the client did pay my invoices and
I did my very best to justify the not insignificant amounts on those
invoices, by ensuring that he got what he wanted rather than what IBM said
was possible. I went there on a 6 month contract to design a database and
ended up staying 2 years. My wife instigated it as she spoke a little
Spanish and she was tired of living in Germany. We could have stayed in
Madrid indefinitely but after 2 years she was ready to return to the U.K. I
never wanted to go there but I have to say they treated us very well and it
was a good place to live and work.

> If your
> Boss wants to give away trade secrets then that's his concern;

No, he just wanted to get his screens refreshed and was amused when we were
able to do it after IBM assured him it was not possible. I think if I had
refused to divulge the code, he would have supported me (we got on really
well), but then he would have been left with "reluctant" support from IBM
(or none at all), and having a hostile vendor is not something any site can
endure for long.



>under
> most contracts I've worked *anything* I've developed for the paying
> client is the paying client's property.)

I always crossed that clause out in the contract and gave them a
non-exclusive right to anything I did, retaining the Intellectual Property
myself..

Agent: "But it's a STANDARD clause...it's in ALL of our contracts."

Me: "Sorry, a contract is an AGREEMENT and I cannot AGREE to a restrictive
condition which affects my ability to make a living in the future."

Boss of Agency is fetched. I explain that if I am precluded from the use of
stuff I originated (which could be better ways to do things), then the next
contract I go to, I can't use that experience. Certainly, the client is
paying for it and should enjoy full and unhindered rights to it, but those
rights are non-exclusive and I would NEVER release Intellectual Property
rights unless a very large sum of money changed hands.

Boss of Agency thinks about the fact that the client will never see this
contract anyway, it will be filed in a draw and never looked at once it is
signed, then thinks about all the lovely money he is going to make if I am
placed on site, and initials the contract change.

I have never had a single Agency refuse to place me because I refused that
clause, and if they did, I'd go down the road to another agency. Why would
you make money for people who have no idea what's going on? There was one
occasion where the Agent wouldn't do it and couldn't get to his Boss, who
was out of town. I had already been interviewed by the client and we were
both quite keen to start. They phoned me and asked what the problem was. I
told them. Three hours later the Agent came back and said that his Boss had
authorised it by fax...

>
>>
>> My Boss was grinning ear to ear at their amazed gasps as terminals
>> around the room started pinging, without anybody touching them.
>>
>> I didn't want to alienate them too mch because I would be moving on
>> and the customer would need their support after I was gone.
>
> If 'playing by the same set of rules as you do' is seen as
> 'alienating' then a request for explanation - in as public a setting
> as possible - is a reasonable attempt to clarify the groundrules from
> which all members of the team are working. After all, We're All In
> This Together, right?
>
> (they absolutely *hate* it when their own buzzwords are thrown back at
> them, or so I've noticed)

Absolutely. :-)

It is a bit ironic and as a friend of mine once remarked: "That which you
resist, you often connect with." I spent years of my life as a contractor
"skirmishing" with IBM. The above is not an isolated instance :-)

Then, one day, I found myself working for them, on site at North Harbour in
Southampton (England) and later at the famous Hursley Park where CICS was
invented. It was an interesting experience which I could never have
anticipated. Like all large organizations they have good people (sometimes
actually outstanding people) and they have not-so-good people. They also
have their share of Corner Office Idiots and I was forced to work for one of
them for a while. The whole business was a growth experience and I don't
regret any of it.
>
> [snip]
>
>> And it wasn't really a lack of knowledge (they completely understood
>> the solution once it was revealed); rather, a lack of imagination...
>
> They may have had all the pieces, Mr Dashwood, but they did not know
> how you managed to put them together. If OCO (Object Code Only) is
> good enough for their programs them it is good enough for yours; give
> them the load modules and say 'it's all in there'.

In reality, I couldn't have them refusing to support the client because they
believed their standard code had been bent. There was really no option but
to show them what was done. Still, it was fun and I did enjoy it... :-)
>
> DD

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


From: Pete Dashwood on
Michael Wojcik wrote:
> Pete Dashwood wrote:
>>
>> 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).
>>
>> ...
>>
>> 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?
>
> In MF COBOL, I'd just repackage the called programs as dynamic-load
> modules (ie, as DLLs on Windows or CSOs on Unix). No source changes
> necessary.
>
> If source changes *were* necessary in the COBOL environment, this
> would seem to be a simple matter of shimming. (Rename called program
> "A" to "A-dynamic" or some such thing. Create a new "A" that does the
> dynamic call to "A-dynamic". Old caller calls the new "A" shim.) Am I
> missing something?

Thanks Michael. (Nice to see you back, BTW :-))

That is pretty much what we did. I'm glad it can work in a MF environment
too.

>
>> 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....
>>
>> 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?
>
> 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.
>
> In some environments the information might be available from the
> environment in some fashion. We don't know if that's the case here,
> since the problem doesn't specify it.
>
> Other metadata might be available in the buffer or the other
> parameters. Again, the problem doesn't specify.
>
> In short, this second problem reduces to "datum X may not be
> available; how do you acquire datum X?". Clearly underdetermined.
>
> The phrasing of the problem does open one possibility:
>
>> 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.
>
> I'll assume any other access idiom, such as reference modification,
> would be equivalent to "set a wrong length" here - that the key is an
> attempt to write past the end of the record.
>
> Then, *if* the environment provides a mechanism for detecting and
> handling exception conditions at the application level, your routine
> or code it invokes could probe the record to find the trap point.
> Again, this is not specified in the problem, so we can't rely on this
> as a general solution. But, for example:
>
> - In Windows, use the pointer-testing routines or SEH to probe
> locations in the buffer to see if they're writable
>
> - In Unix, use a SIGSEGV handler that sets a flag to detect when a
> probe fails. In some Unix implementations, you can also use the EFAULT
> trick - perform I/O from and to the buffer (saving the contents first
> in the latter case) against a descriptor for /dev/null, and look for
> an EFAULT error return. This behavior isn't guaranteed by SUS, though.
>
> - On the AS/400, call a subprogram that probes the buffer and handles
> the appropriate message.
>
> And so forth. It might be tempting to binary-search for the buffer
> length, but given the likely overhead of a faulting miss (ie, a probe
> that strikes past the end of the buffer), a linear probe from the
> beginning is likely to be faster. (With more information about the
> platform architecture, you might do better - for example, on a typical
> paged-memory system you only need to check each page - but the problem
> definition excludes that: it says any attempt to write past the end of
> the buffer will fail, so this must not be a paged system. Note that
> rules out Windows and Unix, so the strategies suggested for those
> platforms above are irrelevant.)

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


From: Pete Dashwood on

Sorry, my response was posted prematurely :-) more below...

> Pete Dashwood wrote:
>>
>> 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).
>>
>> ...
>>
>> 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?
>
> In MF COBOL, I'd just repackage the called programs as dynamic-load
> modules (ie, as DLLs on Windows or CSOs on Unix). No source changes
> necessary.
>
> If source changes *were* necessary in the COBOL environment, this
> would seem to be a simple matter of shimming. (Rename called program
> "A" to "A-dynamic" or some such thing. Create a new "A" that does the
> dynamic call to "A-dynamic". Old caller calls the new "A" shim.) Am I
> missing something?
>
>> 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....
>>
>> 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?
>
> 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. 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... :-( )

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.
>
> In some environments the information might be available from the
> environment in some fashion. We don't know if that's the case here,
> since the problem doesn't specify it.
>
> Other metadata might be available in the buffer or the other
> parameters. Again, the problem doesn't specify.
>
> In short, this second problem reduces to "datum X may not be
> available; how do you acquire datum X?". Clearly underdetermined.
>
> The phrasing of the problem does open one possibility:
>
>> 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.
>
> I'll assume any other access idiom, such as reference modification,
> would be equivalent to "set a wrong length" here - that the key is an
> attempt to write past the end of the record.
>
> Then, *if* the environment provides a mechanism for detecting and
> handling exception conditions at the application level, your routine
> or code it invokes could probe the record to find the trap point.
> Again, this is not specified in the problem, so we can't rely on this
> as a general solution. But, for example:
>
> - In Windows, use the pointer-testing routines or SEH to probe
> locations in the buffer to see if they're writable
>
> - In Unix, use a SIGSEGV handler that sets a flag to detect when a
> probe fails. In some Unix implementations, you can also use the EFAULT
> trick - perform I/O from and to the buffer (saving the contents first
> in the latter case) against a descriptor for /dev/null, and look for
> an EFAULT error return. This behavior isn't guaranteed by SUS, though.
>
> - On the AS/400, call a subprogram that probes the buffer and handles
> the appropriate message.
>
> And so forth. It might be tempting to binary-search for the buffer
> length, but given the likely overhead of a faulting miss (ie, a probe
> that strikes past the end of the buffer), a linear probe from the
> beginning is likely to be faster. (With more information about the
> platform architecture, you might do better - for example, on a typical
> paged-memory system you only need to check each page - but the problem
> definition excludes that: it says any attempt to write past the end of
> the buffer will fail, so this must not be a paged system. Note that
> rules out Windows and Unix, so the strategies suggested for those
> platforms above are irrelevant.)

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


From: Fred Mobach on
Pete Dashwood wrote:

> Fred Mobach wrote:
>> Pete Dashwood wrote:
>>
>>> Richard wrote:
>>>
>>>> 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.
>>
>> Minor change to the grep command :
>> grep -E -i "call *\"name\"" *.cbl
>> so more than 1 space between call and literal will fit.
>>
>>> As the site in question doesn't HAVE grep or an equivalent facility,
>>> for them, it is a nightmare.
>>
>> Then a download at http://www.cygwin.com/ of the Free Software Cygwin
>> might be your solution in case they're running a version of
>> MS-Windows.
>>
>> FYI, I've never used Cygwin because of lack of such an OS here.
>
> Thanks Fred. I think the lack of source management (or even
> versioning) in this place is a source of problems for them (it
> certainly would be for me:-)), but it is not something they are
> concerned about, especially as they will be replacing COBOL anyway.
>
> I believe they will move to full source management as part of the new
> environment. (It is likely they will standardise on Visual Studio for
> teams.)

Perhaps a recommendation to read
http://en.wikipedia.org/wiki/Comparison_of_revision_control_software
before actually spending time and money on a new software environment ?
--
Fred Mobach - fred(a)mobach.nl
website : https://fred.mobach.nl
.... In God we trust ....
.. The rest we monitor ..