Re: Best (or any) practices to rewrite spaghetti or METAL/C
Original Message Subject:Re: Best (or any) practices to rewrite spaghetti or METAL/C Date: Thu, 10 Feb 2011 08:58:28 +0100 From: Miklos Szigetvari miklos.szigetv...@isis-papyrus.com To: IBM Mainframe Discussion List ibm-m...@bama.ua.edu Hi If we can consider METAL/C as alternative to rewrite assembler code ?
Re: Best (or any) practices to rewrite spaghetti
Miklos, all Good question. I'm not sure the following is a best practice, but I've found it useful in developing z390 in Java and zcobol in z390 assembler. I have used several callable routines to handle all error messages and aborts. One routine called log_error(error_number,error_msg) logs error message and returns to caller which allows caller to continue on or handle error. The other routine named abort_error(error_number,error_message) logs error and then issues abort. This approach minimizes insertion of GOTO's (one abort call), and allows user to maintain the shared routines which handle error logs, console logs, maximum return codes, etc. Don Higgins d...@higgins.net On Thu, 3 Feb 2011 18:16:57 +0100, Miklos Szigetvari miklos.szigetv...@isis-papyrus.com wrote: Hi Asking here for the best practices to rewrite spaghetti assembler code to use structured programming macros I think I red a number of SHARE presentations My concern is currently the error handling Till now, if an error occurred, there was a JUMP/BRANCH to an error block, with all the possible error messages , and after a JUMP/BRANCH to the module RETURN. Seems to me , instead of this, some DOEXIT or ASMLEAVE would be more complicated Mikos, all
Re: Best (or any) practices to rewrite spaghetti
On Feb 3, 2011, at 12:57, Edward Jaffe wrote: On 2/3/2011 10:41 AM, Johanson, Adam wrote: Then, I told myself that the whole point of the exercise was to make the code more readable, so a branch to a return-to-caller label every now and then didn't really defeat the purpose and actually _did_ help things. IMHO, rather than seeing a big nested IF statement and chasing down the end point just to figure out that you're gonna return to the caller is a bit more involved than realizing, Oh, I'm just getting out of Dodge. Yup. You can find analogs in other languages. For example SIGNAL and EXIT in REXX. Programs can become unnecessarily complex if you require every condition to be surfaced back up through a deeply-nested logic hierarchy. Rexx SIGNAL sucks. One one hand, it trashes the DO...END structure; OTOH it leaves the subroutine return stack hanging (a naive colleague once authored a Rexx program that used SIGNAL to get out of Dodge. He tested it, apparently successfully. It crashed on a large input data set when the stack overflowed. PITA to refactor.) Absence of a construct to exit a nest of procedures impels Rexx programmers to eschew subroutines in contexts where they'd otherwise be preferable. I'd cherish an extension to support LEAVE control-variable where control-variable belongs to a loop in an outer procedure exposed in the inner procedure containing the LEAVE. But Rexx does support LEAVE and ITERATE for outer DOs. I habitually code: do OuterLoop = 1 for 1 ... do ... do ... leave OuterLoop ... end ... end ... end OuterLoop Depending on your program design, an signal/exit jump from anywhere can be problematic when using a stack for (at least) saving/restoring registers. If you signal/exit with the stack pushed several levels deep, your current registers might not be appropriate for the signal/exit routine and, if the stack is needed for any processing after that, you'll need a way to unwind the stack to the appropriate level or else things might go horribly wrong--for example when the signal/exit routine itself tries to return to the original caller. The easiest way to avoid this is to never branch to a signal/exit label from an inner routine. Or put another way, each stack level has its own signal/exit routine. Another way we've handled the signal/exit jump from anywhere is to save the appropriate stack control and registers in some easily addressable non-stack storage from which they are loaded/copied as one of the very first things the signal/exit routine does. FWIW, when writing code from scratch it is often possible to avoid signal/exit branches entirely by enclosing the logic within two nested simple DOs as shown. We have used this technique quite effectively in some very large and complex programs. (This is only an example. Many other variants of this approach are possible.) | DO LABEL=MainLineDo for MainLine routine | | | * Process MainLine Logic Here * | | DO LABEL=MainLineLogic Do for MainLine logic | . | .(some deeply nested code here discovers an error) | LHI R15,ErrorCode1 Load error code | LEAVE MainLineLogic Go perform error processing | . | .(another error is discovered) | LHI R15,ErrorCode2 Load error code | LEAVE MainLineLogic Go perform error processing | . | .(this can be a very large and complex routine) | . | XRR15,R15Set return code = 0 | LEAVE MainLine Exit the routine | ENDDO , MainLineLogicEndDo for MainLine error trap | | | * Process MainLine Errors Here * | | SELECT CHI,R15,EQSelect error code | WHEN ErrorCode1 ErrorCode1 | (whatever) Issue msg, set retcode/rsn, etc. | WHEN ErrorCode2 ErrorCode2 | (whatever) Issue msg, set retcode/rsn, etc. | OTHRWISE , Unknown Error Code | J *+2Logic error. Force abend here. | ENDSEL , EndSel error code | ENDDO , MainLine EndDo for MainLine routine And you've probably come across it in the SHARE presentations that you've seen, but if you're going to do this, download Ed Jaffe's FLOWASM exit. It makes life easier. I'm glad you found it useful. 8-) -- Edward E Jaffe Phoenix Software International, Inc 831 Parkview Drive North El Segundo, CA 90245 310-338-0400 x318 edja...@phoenixsoftware.com http://www.phoenixsoftware.com/
Re: Best (or any) practices to rewrite spaghetti
Hi Thank you. Try to consider this, i.e if I can make some common error routine set. Currently every error label does something special . On 2/4/2011 3:31 PM, Don Higgins wrote: Miklos, all Good question. I'm not sure the following is a best practice, but I've found it useful in developing z390 in Java and zcobol in z390 assembler. I have used several callable routines to handle all error messages and aborts. One routine called log_error(error_number,error_msg) logs error message and returns to caller which allows caller to continue on or handle error. The other routine named abort_error(error_number,error_message) logs error and then issues abort. This approach minimizes insertion of GOTO's (one abort call), and allows user to maintain the shared routines which handle error logs, console logs, maximum return codes, etc. Don Higgins d...@higgins.net On Thu, 3 Feb 2011 18:16:57 +0100, Miklos Szigetvari miklos.szigetv...@isis-papyrus.com wrote: Hi Asking here for the best practices to rewrite spaghetti assembler code to use structured programming macros I think I red a number of SHARE presentations My concern is currently the error handling Till now, if an error occurred, there was a JUMP/BRANCH to an error block, with all the possible error messages , and after a JUMP/BRANCH to the module RETURN. Seems to me , instead of this, some DOEXIT or ASMLEAVE would be more complicated Mikos, all
SV: Best (or any) practices to rewrite spaghetti
-Ursprungligt meddelande- Från: IBM Mainframe Assembler List [mailto:ASSEMBLER- l...@listserv.uga.edu] För Paul Gilmartin Skickat: den 4 februari 2011 16:09 Till: ASSEMBLER-LIST@LISTSERV.UGA.EDU Ämne: Re: Best (or any) practices to rewrite spaghetti On Feb 3, 2011, at 12:57, Edward Jaffe wrote: snip Yup. You can find analogs in other languages. For example SIGNAL and EXIT in REXX. Programs can become unnecessarily complex if you require every condition to be surfaced back up through a deeply-nested logic hierarchy. Rexx SIGNAL sucks. One one hand, it trashes the DO...END structure; OTOH it leaves the subroutine return stack hanging (a naive colleague once authored a Rexx program that used SIGNAL to get out of Dodge. He tested it, apparently successfully. It crashed on a large input data set when the stack overflowed. PITA to refactor.) Absence of a construct to exit a nest of procedures impels Rexx programmers to eschew subroutines in contexts where they'd otherwise be preferable. I'd cherish an extension to support LEAVE control-variable where control-variable belongs to a loop in an outer procedure exposed in the inner procedure containing the LEAVE. But Rexx does support LEAVE and ITERATE for outer DOs. I habitually code: do OuterLoop = 1 for 1 ... do ... do ... leave OuterLoop ... end ... end ... end OuterLoop I don't quite understand Your problems with SIGNAL. AFAICS, You use SIGNAL when the situation is such that You can't handle it within Your REXX routine logic/context. That's is, You must abort all processing and (normally) give a comprehensive error message, maybe also log it. You describe a situation where a large input file was handled. If that were the reason for the crash it means that too much data was stored in memory (instead of reading smaller amounts at a time from the file or storing temporary data in a disk dataset). (BTW, I use in these kinds of error situations a CALL errorroutine where I do necessary messaging etc, and then in that routine SIGNAL exitroutine.) Regards, Thomas Berg _ Thomas Berg Specialist A M SWEDBANK
Re: Best (or any) practices to rewrite spaghetti
On Fri, Feb 4, 2011 at 4:40 PM, Thomas Berg thomas.b...@swedbank.se wrote: I don't quite understand Your problems with SIGNAL. AFAICS, You use SIGNAL when the situation is such that You can't handle it within Your REXX routine logic/context. That's is, You must abort all processing and (normally) give a comprehensive error message, maybe also log it. The abort all processing is the magic. At best show some diagnostic information to diagnose the problem. But not everyone can resist the temptation... I found some code where a bright soul had put a restart: somewhere in the REXX program and then a signal restart in the error: handler. Unfortunately the trapped error was in a procedure so once the program went though that path, it continued with part of the REXX variables hidden outside the scope (but filling up memory). | Rob
Re: SV: Best (or any) practices to rewrite spaghetti
On Feb 4, 2011, at 08:40, Thomas Berg wrote: I don't quite understand Your problems with SIGNAL. AFAICS, You use SIGNAL when the situation is such that You can't handle it within Your REXX routine logic/context. That's is, You must abort all processing and (normally) give a comprehensive error message, maybe also log it. For that, CALL and EXIT suffice; no need for SIGNAL. You describe a situation where a large input file was handled. If that were the reason for the crash it means that too much data was stored in memory It does not mean that. (instead of reading smaller amounts at a time from the file or storing temporary data in a disk dataset). I was not the author. It became my problem only when I was called on to analyze it. Something such as: /* Rexx */ signal on novalue; /* Doc: signal considered harmful. */ I = 0 A: I = I + 1 call P say I 'was processed by P' signal A P: if right( I, 1 ) == 0 then do say Ignoring I signal A; end /* whatever */ return Much surrounding spaghetti redacted. When I succeeded, after several tries, in explaining the problem to the author, I believe he replaced the CALL and the RETURN with two more SIGNALs. I never have a problem with SIGNAL because I have _never_ (except in demonstrations such as above) coded a SIGNAL to a label. I always code SIGNAL ON NOVALUE. There is one larger EXEC of which I was not the author, but have become the maintainer, which is permeated with SIGNAL spaghetti. It reads commands from the terminal with a hierarchy of recognized subcommands. But many of the subcommand processors recognize top-level commands and SIGNAL directly to their processors. Necessarily, all the loops are implemented by SIGNAL, not DO, and all the subcommand processors are invoked by SIGNAL, not CALL. I hate it. But, following the spaghetti metaphor, once it's cooked it can't be untangled; it merely breaks. Someday I'll try setting a switch variable and RETURN to a SELECT within a DO. Or adding a unified lexical analyzer. -- gil
SV: SV: Best (or any) practices to rewrite spaghetti
-Ursprungligt meddelande- Från: IBM Mainframe Assembler List [mailto:ASSEMBLER- l...@listserv.uga.edu] För Paul Gilmartin Skickat: den 4 februari 2011 17:54 Till: ASSEMBLER-LIST@LISTSERV.UGA.EDU Ämne: Re: SV: Best (or any) practices to rewrite spaghetti On Feb 4, 2011, at 08:40, Thomas Berg wrote: I don't quite understand Your problems with SIGNAL. AFAICS, You use SIGNAL when the situation is such that You can't handle it within Your REXX routine logic/context. That's is, You must abort all processing and (normally) give a comprehensive error message, maybe also log it. For that, CALL and EXIT suffice; no need for SIGNAL. I had some cases where CALL didn't work as expected but SIGNAL did. Maybe the problem was when the exit was a RETURN (external function). You describe a situation where a large input file was handled. If that were the reason for the crash it means that too much data was stored in memory It does not mean that. (instead of reading smaller amounts at a time from the file or storing temporary data in a disk dataset). I was not the author. It became my problem only when I was called on to analyze it. Something such as: /* Rexx */ signal on novalue; /* Doc: signal considered harmful. */ I = 0 A: I = I + 1 call P say I 'was processed by P' signal A P: if right( I, 1 ) == 0 then do say Ignoring I signal A; end /* whatever */ return OMG, I didn't foresee such a usage of SIGNAL... 8-o That is calling (or maybe rather signaling) for problems. Much surrounding spaghetti redacted. When I succeeded, after several tries, in explaining the problem to the author, I believe he replaced the CALL and the RETURN with two more SIGNALs. I never have a problem with SIGNAL because I have _never_ (except in demonstrations such as above) coded a SIGNAL to a label. I always code SIGNAL ON NOVALUE. There is one larger EXEC of which I was not the author, but have become the maintainer, which is permeated with SIGNAL spaghetti. It reads commands from the terminal with a hierarchy of recognized subcommands. But many of the subcommand processors recognize top-level commands and SIGNAL directly to their processors. Necessarily, all the loops are implemented by SIGNAL, not DO, and all the subcommand processors are invoked by SIGNAL, not CALL. I hate it. But, following the spaghetti metaphor, once it's cooked it can't be untangled; it merely breaks. Someday I'll try setting a switch variable and RETURN to a SELECT within a DO. Or adding a unified lexical analyzer. -- gil Regards, Thomas Berg _ Thomas Berg Specialist A M SWEDBANK
Re: Best (or any) practices to rewrite spaghetti
Sorry, REXX SIGNAL does not suck; you just don't know how to use it. It only trashes the current DO...END structure. It works just fine if you code something like: DO Outerloop = 1 to n Call processes_item End Process_item: Signal ... Return Any errors encountered in 'Process_item' will not stop Outerloop. John -Original Message- From: IBM Mainframe Assembler List [mailto:ASSEMBLER-LIST@LISTSERV.UGA.EDU] On Behalf Of Paul Gilmartin Sent: Friday, February 04, 2011 10:09 AM To: ASSEMBLER-LIST@LISTSERV.UGA.EDU Subject: Re: Best (or any) practices to rewrite spaghetti On Feb 3, 2011, at 12:57, Edward Jaffe wrote: On 2/3/2011 10:41 AM, Johanson, Adam wrote: Then, I told myself that the whole point of the exercise was to make the code more readable, so a branch to a return-to-caller label every now and then didn't really defeat the purpose and actually _did_ help things. IMHO, rather than seeing a big nested IF statement and chasing down the end point just to figure out that you're gonna return to the caller is a bit more involved than realizing, Oh, I'm just getting out of Dodge. Yup. You can find analogs in other languages. For example SIGNAL and EXIT in REXX. Programs can become unnecessarily complex if you require every condition to be surfaced back up through a deeply-nested logic hierarchy. Rexx SIGNAL sucks. One one hand, it trashes the DO...END structure; OTOH it leaves the subroutine return stack hanging (a naive colleague once authored a Rexx program that used SIGNAL to get out of Dodge. He tested it, apparently successfully. It crashed on a large input data set when the stack overflowed. PITA to refactor.) Absence of a construct to exit a nest of procedures impels Rexx programmers to eschew subroutines in contexts where they'd otherwise be preferable. I'd cherish an extension to support LEAVE control-variable where control-variable belongs to a loop in an outer procedure exposed in the inner procedure containing the LEAVE. But Rexx does support LEAVE and ITERATE for outer DOs. I habitually code: do OuterLoop = 1 for 1 ... do ... do ... leave OuterLoop ... end ... end ... end OuterLoop Depending on your program design, an signal/exit jump from anywhere can be problematic when using a stack for (at least) saving/restoring registers. If you signal/exit with the stack pushed several levels deep, your current registers might not be appropriate for the signal/exit routine and, if the stack is needed for any processing after that, you'll need a way to unwind the stack to the appropriate level or else things might go horribly wrong--for example when the signal/exit routine itself tries to return to the original caller. The easiest way to avoid this is to never branch to a signal/exit label from an inner routine. Or put another way, each stack level has its own signal/exit routine. Another way we've handled the signal/exit jump from anywhere is to save the appropriate stack control and registers in some easily addressable non-stack storage from which they are loaded/copied as one of the very first things the signal/exit routine does. FWIW, when writing code from scratch it is often possible to avoid signal/exit branches entirely by enclosing the logic within two nested simple DOs as shown. We have used this technique quite effectively in some very large and complex programs. (This is only an example. Many other variants of this approach are possible.) | DO LABEL=MainLineDo for MainLine routine | | | * Process MainLine Logic Here * | | DO LABEL=MainLineLogic Do for MainLine logic | . | .(some deeply nested code here discovers an error) | LHI R15,ErrorCode1 Load error code | LEAVE MainLineLogic Go perform error processing | . | .(another error is discovered) | LHI R15,ErrorCode2 Load error code | LEAVE MainLineLogic Go perform error processing | . | .(this can be a very large and complex routine) | . | XRR15,R15Set return code = 0 | LEAVE MainLine Exit the routine | ENDDO , MainLineLogicEndDo for MainLine error trap | | | * Process MainLine Errors Here * | | SELECT CHI,R15,EQSelect error code | WHEN ErrorCode1 ErrorCode1 | (whatever) Issue msg, set retcode/rsn, etc. | WHEN ErrorCode2 ErrorCode2 | (whatever) Issue msg, set retcode/rsn, etc. | OTHRWISE , Unknown Error Code | J *+2Logic error. Force abend here. | ENDSEL
SV: Best (or any) practices to rewrite spaghetti
-Ursprungligt meddelande- Från: IBM Mainframe Assembler List [mailto:ASSEMBLER- l...@listserv.uga.edu] För Rob van der Heij Skickat: den 4 februari 2011 17:56 Till: ASSEMBLER-LIST@LISTSERV.UGA.EDU Ämne: Re: Best (or any) practices to rewrite spaghetti On Fri, Feb 4, 2011 at 4:40 PM, Thomas Berg thomas.b...@swedbank.se wrote: I don't quite understand Your problems with SIGNAL. AFAICS, You use SIGNAL when the situation is such that You can't handle it within Your REXX routine logic/context. That's is, You must abort all processing and (normally) give a comprehensive error message, maybe also log it. The abort all processing is the magic. At best show some diagnostic information to diagnose the problem. But not everyone can resist the temptation... I found some code where a bright soul had put a restart: somewhere in the REXX program and then a signal restart in the error: handler. Unfortunately the trapped error was in a procedure so once the program went though that path, it continued with part of the REXX variables hidden outside the scope (but filling up memory). I don't understand how anyone can have any decent confidence in a routine that continue processing after a SIGNAL. It's more or less like continue driving after taking LSD. :) Regards, Thomas Berg _ Thomas Berg Specialist A M SWEDBANK
REXX SIGNAL (Was: Best (or any) practices to rewrite spaghetti)
On 2/4/2011 7:08 AM, Paul Gilmartin wrote: Rexx SIGNAL sucks. One one hand, it trashes the DO...END structure; OTOH it leaves the subroutine return stack hanging (a naive colleague once authored a Rexx program that used SIGNAL to get out of Dodge. He tested it, apparently successfully. It crashed on a large input data set when the stack overflowed. PITA to refactor.) Absence of a construct to exit a nest of procedures impels Rexx programmers to eschew subroutines in contexts where they'd otherwise be preferable. I didn't know that about REXX SIGNAL. The issues you describe are similar to those I described in my post to this thread. At least an HLASM programmer can design his/her program to deal with these issues. Apparently, a REXX programmer is just screwed. :-( -- Edward E Jaffe Phoenix Software International, Inc 831 Parkview Drive North El Segundo, CA 90245 310-338-0400 x318 edja...@phoenixsoftware.com http://www.phoenixsoftware.com/
Re: Best (or any) practices to rewrite spaghetti
Personally, I consider a 'branch to abnormal exit' much better than trying to unwind all the 'perform' levels, be it COBOL or Assembler. I have seen programs where they attempted to unwind everything during an error and ended up processing code unintentionally. Tony Thigpen -Original Message - From: Miklos Szigetvari Sent: 02/03/2011 12:16 PM Hi Asking here for the best practices to rewrite spaghetti assembler code to use structured programming macros I think I red a number of SHARE presentations My concern is currently the error handling Till now, if an error occurred, there was a JUMP/BRANCH to an error block, with all the possible error messages , and after a JUMP/BRANCH to the module RETURN. Seems to me , instead of this, some DOEXIT or ASMLEAVE would be more complicated
Re: Best (or any) practices to rewrite spaghetti
There's no reason your SP macro code can't include a jump to an error handler when an error occurs. Donald Knuth once wrote a scholarly article called Structured Programming with GOTO Statements where he showed that attempts to be purely structured were often more obscure than using a GOTO when it was simplest. Miklos Szigetvari asked: Asking here for the best practices to rewrite spaghetti assembler code to use structured programming macros I think I red a number of SHARE presentations My concern is currently the error handling Till now, if an error occurred, there was a JUMP/BRANCH to an error block, with all the possible error messages , and after a JUMP/BRANCH to the module RETURN. Seems to me, instead of this, some DOEXIT or ASMLEAVE would be more complicated
Re: Best (or any) practices to rewrite spaghetti
One of the ways I avoid too many nested IF statements is to use straddling DO/ENDDO around code that may require several let's get outta here now moments. For example : DO, Some code DOEXIT (TM,flag,bit,NO) ... Some more code DOEXIT (CLC,field,NE,value) ... Call some subroutine DOEXIT (LTR,R15,R15,NZ) ...etc ENDDO You could also label the DO (eg MAIN) and then use something like ASMLEAVE MAIN from anywhere later in the logic. Rob Scott Lead Developer Rocket Software 275 Grove Street * Newton, MA 02466-2272 * USA Tel: +1.617.614.2305 Email: rsc...@rs.com Web: www.rocketsoftware.com -Original Message- From: IBM Mainframe Assembler List [mailto:ASSEMBLER-LIST@LISTSERV.UGA.EDU] On Behalf Of Johanson, Adam Sent: 03 February 2011 18:42 To: ASSEMBLER-LIST@LISTSERV.UGA.EDU Subject: Re: Best (or any) practices to rewrite spaghetti John Ehrman wrote: There's no reason your SP macro code can't include a jump to an error handler when an error occurs. Donald Knuth once wrote a scholarly article called Structured Programming with GOTO Statements where he showed that attempts to be purely structured were often more obscure than using a GOTO when it was simplest. Yeah, what they said. I recently changed a couple of multi-thousand-line programs to use SPMs and my first thought was that I was going to eliminate all of the branches in them. But as I got going, it became pretty apparent that to do so would require things that made the code a little bit less readable, like lengthening IF-blocks and adding a couple of more indentation spacings to blocks that already had a fair amount of indentation to them. Then, I told myself that the whole point of the exercise was to make the code more readable, so a branch to a return-to-caller label every now and then didn't really defeat the purpose and actually _did_ help things. IMHO, rather than seeing a big nested IF statement and chasing down the end point just to figure out that you're gonna return to the caller is a bit more involved than realizing, Oh, I'm just getting out of Dodge. And you've probably come across it in the SHARE presentations that you've seen, but if you're going to do this, download Ed Jaffe's FLOWASM exit. It makes life easier. Adam Johanson IMS Systems Programming USAA
Re: Best (or any) practices to rewrite spaghetti
On 2/3/2011 10:41 AM, Johanson, Adam wrote: Then, I told myself that the whole point of the exercise was to make the code more readable, so a branch to a return-to-caller label every now and then didn't really defeat the purpose and actually _did_ help things. IMHO, rather than seeing a big nested IF statement and chasing down the end point just to figure out that you're gonna return to the caller is a bit more involved than realizing, Oh, I'm just getting out of Dodge. Yup. You can find analogs in other languages. For example SIGNAL and EXIT in REXX. Programs can become unnecessarily complex if you require every condition to be surfaced back up through a deeply-nested logic hierarchy. Depending on your program design, an signal/exit jump from anywhere can be problematic when using a stack for (at least) saving/restoring registers. If you signal/exit with the stack pushed several levels deep, your current registers might not be appropriate for the signal/exit routine and, if the stack is needed for any processing after that, you'll need a way to unwind the stack to the appropriate level or else things might go horribly wrong--for example when the signal/exit routine itself tries to return to the original caller. The easiest way to avoid this is to never branch to a signal/exit label from an inner routine. Or put another way, each stack level has its own signal/exit routine. Another way we've handled the signal/exit jump from anywhere is to save the appropriate stack control and registers in some easily addressable non-stack storage from which they are loaded/copied as one of the very first things the signal/exit routine does. FWIW, when writing code from scratch it is often possible to avoid signal/exit branches entirely by enclosing the logic within two nested simple DOs as shown. We have used this technique quite effectively in some very large and complex programs. (This is only an example. Many other variants of this approach are possible.) | DO LABEL=MainLineDo for MainLine routine | | | * Process MainLine Logic Here * | | DO LABEL=MainLineLogic Do for MainLine logic | . | .(some deeply nested code here discovers an error) | LHI R15,ErrorCode1 Load error code | LEAVE MainLineLogic Go perform error processing | . | .(another error is discovered) | LHI R15,ErrorCode2 Load error code | LEAVE MainLineLogic Go perform error processing | . | .(this can be a very large and complex routine) | . | XRR15,R15Set return code = 0 | LEAVE MainLine Exit the routine | ENDDO , MainLineLogicEndDo for MainLine error trap | | | * Process MainLine Errors Here * | | SELECT CHI,R15,EQSelect error code | WHEN ErrorCode1 ErrorCode1 | (whatever) Issue msg, set retcode/rsn, etc. | WHEN ErrorCode2 ErrorCode2 | (whatever) Issue msg, set retcode/rsn, etc. | OTHRWISE , Unknown Error Code | J *+2Logic error. Force abend here. | ENDSEL , EndSel error code | ENDDO , MainLine EndDo for MainLine routine And you've probably come across it in the SHARE presentations that you've seen, but if you're going to do this, download Ed Jaffe's FLOWASM exit. It makes life easier. I'm glad you found it useful. 8-) -- Edward E Jaffe Phoenix Software International, Inc 831 Parkview Drive North El Segundo, CA 90245 310-338-0400 x318 edja...@phoenixsoftware.com http://www.phoenixsoftware.com/
Re: Best (or any) practices to rewrite spaghetti
I'm sure others will tell you about coding techniques and structured macros etc. My advice when improving old spaghetti assembler code is this: Make sure you have a regression test library ready to insure that the behavior of the new code matches the old code. Spaghetti code can hide a lot of little subtleties and you need to make sure that the more structured, more readable code doesn't change or miss anything. You also need to compare performance. On more than one occasion we found the performance of the old spaghetti code module hard to beat or match. --Roger On Thu, Feb 3, 2011 at 10:16 AM, Miklos Szigetvari miklos.szigetv...@isis-papyrus.com wrote: Hi Asking here for the best practices to rewrite spaghetti assembler code to use structured programming macros I think I red a number of SHARE presentations My concern is currently the error handling Till now, if an error occurred, there was a JUMP/BRANCH to an error block, with all the possible error messages , and after a JUMP/BRANCH to the module RETURN. Seems to me , instead of this, some DOEXIT or ASMLEAVE would be more complicated
Re: Best (or any) practices to rewrite spaghetti
On Thu, Feb 3, 2011 at 6:29 PM, Tony Thigpen t...@vse2pdf.com wrote: Personally, I consider a 'branch to abnormal exit' much better than trying to unwind all the 'perform' levels, be it COBOL or Assembler. I have seen programs where they attempted to unwind everything during an error and ended up processing code unintentionally. My father used to say that 'anything with too in it is bad' and I had to think of that when I was recently trying to untange some ancient code. I allow myself premature exit to the end of the routine as well, but it's a glippery slope. At least I find that when you don't give it enough thought, it's easy to end up with a lot of them and make following the flow much harder. My dialect of Structured Assembler does a combined call with automatic exit on nonzero return code Though this is the same as coding that extra branch, the simplification to me is that it's always the same NZ that does the exit. If necessary, I will put a number of those diverse tests in a subroutine and let that conclude Z or NZ. That avoids things like this: CLC DEVADDR,RANGELO BL EXIT CLC DEVADDR,RANGEHI BH EXIT | Rob
Re: Best (or any) practices to rewrite spaghetti
Hi Thank you very much for everybody. The answers has confirmed my view , to overuse a good technique can lead to obscure results. On 2/3/2011 9:15 PM, Roger Bolan wrote: I'm sure others will tell you about coding techniques and structured macros etc. My advice when improving old spaghetti assembler code is this: Make sure you have a regression test library ready to insure that the behavior of the new code matches the old code. Spaghetti code can hide a lot of little subtleties and you need to make sure that the more structured, more readable code doesn't change or miss anything. You also need to compare performance. On more than one occasion we found the performance of the old spaghetti code module hard to beat or match. --Roger On Thu, Feb 3, 2011 at 10:16 AM, Miklos Szigetvari miklos.szigetv...@isis-papyrus.com wrote: Hi Asking here for the best practices to rewrite spaghetti assembler code to use structured programming macros I think I red a number of SHARE presentations My concern is currently the error handling Till now, if an error occurred, there was a JUMP/BRANCH to an error block, with all the possible error messages , and after a JUMP/BRANCH to the module RETURN. Seems to me , instead of this, some DOEXIT or ASMLEAVE would be more complicated