|
|||||||
|
|
![]() |
|
|
Dr. Programmer, Private Eye by G. Wayne Hawks [The code for this article is available for download.] Does anyone out there write a whole program from scratch anymore? Maybe we should be called software surgeons. Always cutting pieces from this program and pasting into that one. Nah, "software surgeon" is too specialized. We are more like software doctors. Usually we divide our time between giving birth to new systems and trying to prolong the lives of the old. First diagnose the errors in a program and then fix them. The diagnosing often takes the skills of a detective. And, with documentation being what it is, sometimes we have to be really good detectives. So, then, how about Dr. Programmer, Private Eye? To help in your sleuthing endeavors, I'd like to take you through some techniques that should save you some time. Let's start with the search option in PDM (Program Development Manager) and end with a utility I wrote several years ago and use quite often. Suppose your company has been bought by another, and it's your job to find and change your old company's name with that of the new name, everywhere in your code. Option 25 in PDM has several choices to make. These are the ones I find the most interesting:
Of course, the first item, the text (string) you wish to find, is simply what you are searching for. In the scenario indicated above, you'd put in your company's old name. Items 2 and 3, the search from and to column numbers, limit the width of the search. So, say you were looking for what changed a particular field. You might want to only search in columns 50 to 64--the Result field (assuming you're using RPG IV and not changing it in an EVAL statement or free-form RPG). Anyway, you get the idea. If you don't find it with a limited search, you can always scan again, looking at all the columns. When I use item 4 above, I always set it to ignore the case of the text. I still type my code in uppercase, but I code my comments in as proper upper and lower case as I can. It sure makes it easier to read later if you make your comments as legible (and hey, while you're at it, as accurate!) as possible. But other programmers may use lowercase for their code as well so, it's best to ignore case. Obviously, option 25 in PDM (search) is a very powerful sleuthing tool. But how about making massive changes, like in our scenario? That brings us to option 5, the PDM option to take for each member that has matching text. Oh, the power, the power! Suppose you do a trial scan and discover that it does select all the members you want. Why not change item 5 above to do a PDM option 3, which is to copy the source members to a brand new source file? You can change your company's old name to the new one (or whatever mass change you need to make) in every member in that new file and, when ready, take an option 14 (compile)--or whatever user option you want to use--and then do an F-13 to copy that for every member of that source file. When done, just copy all (PDM option 3 for the first member and F-13 to copy that option for all members again) back to your original source file. You know, it took me a while to realize that source code is just data. In fact, it's some of the easiest data to work with. Every source file has three fields: SRCDAT, SRCDTA, and SRCSEQ. The date of last change is in SRCDAT, and the line number is in SRCSEQ. But the data is in SRCDTA. So why not write programs to change your program code? I know, it sounds a little bizarre. But, taking our scenario, you could use Display File Description (Member Info Only) of the new source file to an output file. You could then read that output file in a CL to "know" which members to override to and, using an RPG program created to scan through a member, looking for your old company name, it could change it to your new company name. And your CL could have the RPG change all the source file members. You would only have to write the CL and RPG programs to do so. So either go into each member and use search and replace umpteen times or write one CL and one RPG program to do the same thing. And since you're working with copies, go ahead and try it. Just be careful to really check that it does the right thing before you compile them or copy them back! Okay, that's great for mass changes, but what about when you know that somewhere in a program, a field is getting changed, but not where? Well, you can use option 25 for this, too, or F-16, when editing the source, but both ways position the source to the next occurrence of the field every time. That's fine if it's only in the source once; otherwise, you may have to hit F-16 time and again, until you're so used to hitting it, you fly right on by and have to start over. That used to happen to me a lot. Then I thought, wouldn't it be better to just look at a list (subfile) of source code lines that contain the field in question? Then, at a glance, I can see what line might be changing that field. So I created the program I call source member scan. And while I was at it, I built it as two subfiles I can toggle between. One of them has the source and line number, and the other contains the source and date last changed. After all, if the program has been working fine for years and a problem has just cropped up, was there a change in the program just recently or has something else in the data stream (or a user's memory) crumped? Then I used a PDM user option to call it. You can use whatever you want, but I used FS, which stands for "file scan," since you can only use two characters. By using the PDM user option, the library, source file, and member are passed along to the program. This allows the CL to do an override to the correct code. When you take option FS (or whatever you use for yours) you first get a screen that asks for up to four text strings to search for. I created it as an "or" search. So any one of these strings found in a line of code will add that line of code to the subfiles. And there's an option on the screen to indicate whether you want to include BEGSR, ENDSR, and format names. I find it very useful to have those, because it gives a hint to program flow to know which subroutines that field is getting changed in. I wrote this so it also works on display files, hence the "format names" portion of the question. After all, one of the biggest places a field can get changed is in a display file. What you enter as search strings, and whether you want to include BEGSR, ENDSR, and format names, is saved in a file by the user, so the next time any user uses it, its already populated for them. Since you may be using this over and over while searching, it's handy to not have to keep typing in the same stuff over and over. After you've filled in the strings you want to look for, and press Enter, you'll get a subfile display that only contains lines with one or more of the text strings you entered (and possibly BEGSR, ENDSR, or format-name lines). At the top is a count of how many lines it found. The first subfile to be displayed is the one with the line number on the left. Just press F-8 to toggle between this subfile and the one with the date last changed on the left. So whether you're making mass changes or just need to find what's happening to that one field, Dr. Programmer, Private Eye, I hope that these techniques and this utility help you in your endeavors. I hope that it frees up enough time for you that you can make more house calls to your own house! G. Wayne Hawks is a programmer/analyst with 14 years of experience in AS/400 programming. E-mail: donkey_hote@hotmail.com
|
Editors
Contact the Editors |
| Copyright © 1996-2008 Guild Companies, Inc. All Rights Reserved. |