Make Mine MAPPER #5 -------------------- by Rob Haeuser The amazing OA, BRK, and how Runs get run --------------------------------------------------------------- What's faster than a looping WRL, more powerful than a bunch of functions, and able to leap tall rids in a single pass? It's your humble, ever-ready Output Area (OA). The OA, along with Break (BRK), IF, and the various read functions (RDC, RDL, and RLN), comprise one of, if not the most, flexible means of manipulating data in all of MAPPER. But what is the OA? Why is it so much faster than a WRL loop? What does BRK do? How does it work with the OA? In my mind, the OA is a programmer's dream. Having come from a world where you absolutely had to use a 'write' verb to output data, the OA was a pleasant surprise. It's like the difference between a manual transmission and an automatic. On one hand you have to control every gear shift, which can get tedious, while on the other you let the machine do the work. Think of the OA as an enormous data sponge, absorbing any data line MAPPER 'spills' into it as it executes a run. Before we discuss this in detail, let's review how runs get executed, starting from the moment you transmit a command from the control line. MAPPER goes through a series of decisions, though not necessarily in this order. Was the first character 0 through 9? If so, you are asking to display a rid, so scan the input for the form type. If the form type is invalid, or the number preceding it exceeds the limit, usually 2,000, you get an error message. This is why no run name can start with a number. If not requesting to display a rid the old-fashioned way, is it in the Data Directory? If so, display it. A run cannot share a name with a Data Directory entry in the same department. Was a manual function entered? If so, execute it. If a manual function is available to a user, it takes precedence. However, it is possible to have a run called 'PR' if the manual print function has been disabled. If it's not a rid, and it's not a manual function, it should be a run, so MAPPER performs a 'pre-run'. This function checks the department's run registration rid to verify the run's name, physical location, and execution restrictions, such as time- slotting, IO and LLP limits, user-id, and/or station number. If the run registration points to an RCR that doesn't exist, you get the error message 'Invalid run control report - try to display it'. This can also happen if your run stops on the last line of the RCR with a non-interim display and is then resumed, so that MAPPER immediately hits the '..... END REPORT .....'. That's why every run should be terminated with a REL, GTO END, XIT, etc. Don't worry, I didn't forget about the output area. Ok, so everything checks out, and MAPPER begins execution of the RCR at line THREE. Raise your hands if your RCR has more than two lines of headers. I thought so. Some of the ancient runs in the system have only two header lines, a '.DATE' line and a period type line for a very brief statement of the run's name and purpose. Most RCRs have three to five header lines, usually more than enough space to clearly state what the run is about to do. However, those extra lines go into the OA, and will probably need to be cleared out. As far as MAPPER is concerned, there are only two meaningful line types. Either the line starts with the master space (@), a colon, or something else. If it starts with the '@', then either a numeric label, a valid function, a period/space, or a semi- colon/period/space should follow. If a colon, then a Label Table entry or a variable definition must follow. In Figure 1 we see some of the combinations possible. ---------------------------------------------------------------- FIGURE 1 -------- .DATE etc. .NAME=TEST1 Documentation starts at label 99 (at the BOTTOM!) :L5=7,10=13,15=14 @1:LDV variables SRH... Use LDV to load variables, not a ':' @5 TOT... @CAL..... @. These line formats are used to put imbedded comments in @:. the run. Only use them when the code is so thick that @10 . it absolutely requires an immediate explanation and @15:. you can't wait to put it at the bottom. MAPPER terminates @. the line scan at the space/period, but it counts as 1 LLP. @. @99. ... Documentation starts here, or maybe in another rid ... --------------------------------------------------------------- For lines starting with '@': if a number is present, a label check is performed. Is it greater than the highest allowed, usually either 199 or 399? Is it on the line indicated by a label table? Has it already been used on another line? Following the label will usually be a command to execute, and MAPPER checks against all the available run functions for validity. If the function is valid, the function syntax is checked, and executed if correct. The colon is a special case. In ancient times, the colon was used to load variables, prior to the existence of LDV. And yes, believe it or not, some runs still use it. These days, the colon is used to indicate a label table entry. Every run should have a label table, saving MAPPER the effort of physically locating labels by reading the RCR, increasing IO in the process. Do not attempt to enter a label table by hand. Why bother? BLT (Build Label Table) does it for you. The complimentary function CLT (Clear Label Table) removes it for you. Write a little utility to grab the displayed run, do a CLT, a BLT, and then REP it back. Very handy. Run it after you've initially written a run, and if you've added or deleted lines or labels. Otherwise, the run will probably abort with the error message 'This label number has already been used'. Not always the case, but close enough. But what about the output area!!!??? That amazing data sponge, the OA, will absorb any line not deemed executable, determined by the lack of a '@' or ':' in column one. Even though MAPPER has encountered a data line and doesn't attempt to execute it, the line is still scanned for variables and 'tics' (apostrophes) before the OA gets it. As MAPPER encounters tics, it will strip them off in pairs, considering anything between them to be literal data. This is how the literal 'V1' or '' can be placed into the OA. Without tics, any variable encountered will be converted to it's contained value. WARNING! Tics must occur on a data line in pairs! An odd number will abort the run. Functions can format data lines and place them in the OA, constructing a report up to the maximum number of lines allowed for a result (over 262,000!). Enter that humble function, BRK. The Mode and Type (MT) of the OA, among other things, are determined by BRK. It is a simple function, yet often misunderstood and overused. BRK actually does a number of things: 1) It turns the OA into the current -0 result; 2) It creates a new OA; 3) It establishes the Mode and Type (MT) of the OA, and therefore the NEXT result created by a BRK, with type determining the width; 4) It allocates space for the new OA. It is the third capability listed that seems to cause the confusion. Figure 2 is an example of how this occurs. This display at label 3 will abort. The result is in Mode 10, Type I, not H. The code starting at label 9 demonstrates how BRKs relate to one another. ---------------------------------------------------------------- FIGURE 2 -------- @BRK . (default to the MT of the RCR, in this case 10,I) data @3:BRK,10,H DSP,10,H,-0 . (This display will fail) data @9:BRK,10,I . (Mode/Type of the RCR) data @BRK,10,H DSP,10,I,-0 . data @BRK,20,B DSP,10,H,-0 . data @BRK,50,F DSP,20,B,-0 . data @BRK DSP,50,F,-0 . data @BRK DSP,50,F,-0 . ---------------------------------------------------------------- Notice the relationship between the MT, the BRK, and what is displayed by the DSP. I think I just confused myself. No wonder it's so easy to loose track of where the result is. Actually, Unisys (was it way back on level 33?) reduced this problem tremendously when they eliminated the need to state the MT, such as: @DSP,-0 . However, it still helps to know where in the heck that result really is! The next area of confusion is: when to use BRK? This is where over-use comes in. Quite often a BRK is unnecessary, since one had previously been performed. In Figure 3, we break, load a screen into the OA, break again, and then display the screen. After receiving input, we proceed to create a report in the OA via a RDL/RLN/IF loop, and finally display the report. ---------------------------------------------------------------- FIGURE 3 -------- .DATE .NAME=TEST4 *DESC=demonstration of too many BRKs * *=============================================================== @1:BRK . ..................... screen goes here ......................... @BRK CHG INVAR$ V1,V2,... SC,-0... @5:IF CURV$ = 23 REL ;. @10:BRK RDL... @15:IF V1... INC... LDV... etc. dump data into the OA @RLN,,20.... IF... GTO 15 ;. @20:BRK DSP,-0 . @REL . ---------------------------------------------------------------- The first BRK is required because the RCR contains more than two header lines. Remember, MAPPER begins looking for code at line three, usually encounters headers (data lines), and dumps them into the OA. The first BRK clears the OA, preventing the headers from becoming part of the screen. Following the screen definition, a second BRK does all the wonderful things that it does, especially creating a result of the screen to be displayed. At label 5 we check for an exit request. Then comes the BRK we could do without. Totally unnecessary, but it does what it's supposed to, including creating another result and clearing the OA, which was already cleared by the previous BRK. Finally, we loop through the data, selectively placing what we want in the OA. When all data has been read and processed, we end up at label 20, BRK again, and display the report. Finally a word about the quantity field. If left blank, a small area of space is allocated, enough for about 36 80-column lines. If the OA exceeds this default minimum, a larger block of space is allocated and whatever is in the OA is copied to the new area. Another threshold occurs at 498 lines and again at 5,498. As each threshold is exceeded, the OA is copied to yet a larger area, increasing the IO in the process. It seems as though thresholds occur every 5,000 lines thereafter. Without stating a quantity, creating a 1,000 line report could actually shuffle over 1,500 lines through the OA, which, after all, is really just disk space in MAPPER's work file, MAPER0. Why use more IO than you have to? If you don't know how big the result is going to be, estimate! It is more efficient to over- estimate than to under-estimate, so add 5 or 10% to be sure. This mentality also applies to the 'E' option for a SRH. In a large application, where efficiency is of the utmost importance, a 'sentinel' rid can be maintained with the last actual count (obtained by various means, including LLN). Subsequent executions can then read it, use it for the current estimate, and then write it back for future use. The OA and BRK are a powerful combination that can be used to create non-standard reports without the classic MAPPER look (header lines, the *= line, terse field descriptions, etc). Entire databases can be constructed by pulling data from various sources, re-assembling it in the OA, and then REPing dozens, hundreds, or even thousands of reports! There is still much more to be said about the OA, and I'm sure many questions remain unanswered. Hang in there! Next month we'll look at some IO statistics, and OA tricks that may surprise you!