Write a procedure that converts a one-lined exec into a multi-line exec. To that purpose, we provide the MULTILIN SKELETON © that you have to complete. This procedure uses EXECIO to read and write the files. Review the comments in the procedure to see what you have to do.
You could test your procedure on ONELINED XEDIT ©. but this file is rather large and if you have to trace your procedure, it would take you too long. We therefore also provide ONELINED EXEC © that contains only a few statements.
Several points covered in previous exercise apply here too.
If you used the provided skeleton, then this exercise is not too difficult.
The important parts of the skeleton are reproduced here:
/* Skeleton MULTILIN */ address command parse source . . myname mytype . parse upper arg fileid '(' opt /***********************************************************************/ /* You should complete here in order to : */ /* - test if fileid is not missing */ /* - complete the fileid if only name is given and verify if it exists */ /* In case conditions are not fulfilled, use the general ERREXIT exit. */ /***********************************************************************/ ... /***********************************************************************/ /* Now we read the input file via EXECIO and put all records in array. */ 'EXECIO * DISKR 'fileid' (FINIS STEM REC.' if rc<>0 then call errexit rc,'Problems with EXECIO read statement' /***********************************************************************/ /* All records are in array REC. and REC.0 contains number of records. */ /* The splitted records should be collected in array OUT. */ /* OUT.0 must indicate the number of records so produced. */ /***********************************************************************/ nr = 0 /* number of single records */ do i=1 to rec.0 ... end /***********************************************************************/ /* We can write the file now... */ outfile=word(fileid,1) 'MULTILIN A' address command 'ERASE' outfile /* erase old file */ address command 'EXECIO' out.0 'DISKW' outfile '(FINIS STEM OUT.' if rc<>0 then call errexit rc,'Problems with EXECIO output' call exit 0,'File' fileid 'successfully multi-lined in' outfile /********************** General Exit Routine ***************************/ EXIT: ERREXIT: parse arg retc,errmsg if errmsg<>'' then say myname':' errmsg exit retc
You had only to code some statements to complete the DO-loop. Let's review a typical solution provided by one of our former students:
! /***********************************************************************/ ! /* Procedure MULTILIN skeleton completed by Rudi */ ! /***********************************************************************/ ! address command ! parse source . . myname mytype . 1 ! parse upper arg fileid filetype '(' opt 2 ! if fileid=' ' then call errexit rc,'File name missing' 3 ! if fileid<>' ' then do 4 ! if filetype=' ' then filetype='EXEC' 5 ! address '' 'ESTATE' fileid filetype '*' 6 ! if RC^=0 then call errexit rc,fileid' 'filetype' does not exists' 7 ! end ! 'EXECIO * DISKR 'fileid filetype' (FINIS STEM REC.' ! if rc<>0 then call errexit rc,'Problems with EXECIO read statement' ! /***********************************************************************/ ! /* main routine... */ ! /***********************************************************************/ 8 ! nr = 1;dos=0 /* number of single records */ 9 ! do i=1 to rec.0 10 ! nomorefound=0 11 ! do until nomorefound=1 12 ! foundone=pos(';',rec.i,1) 13 ! if foundone>0 then do 14 ! out.nr=substr(rec.i,1,foundone-1) 15 ! rec.i=substr(rec.i,foundone+1) 16 ! if opt=indent then do 17 ! if pos(':',out.nr,1)>0 then dos=0 18 ! if word(out.nr,1)='end' then dos=dos-1 19 ! if word(out.nr,1)='else' then dos=dos-1 20 ! if dos<0 then dos=0 21 ! out.nr=copies(' ',(dos*3))''out.nr 22 ! if word(out.nr,1)='do' then dos=dos+1 23 ! if word(out.nr,1)='if' then dos=dos+1 24 ! if word(out.nr,1)='select' then dos=dos+1 25 ! end 26 ! end 27 ! else do 28 ! out.nr=rec.i 29 ! nomorefound=1 30 ! end 31 ! nr=nr+1 32 ! end 33 ! out.0=nr-1 ! /***********************************************************************/ ! /* All separate statements in array OUT. and OUT.0 is number of ele- */ ! /* ments. We use EXECIO to write the output file. */ ! /***********************************************************************/ ! outfile=word(fileid,1) 'MULTILIN A' ! address command 'ERASE' outfile /* erase old file */ ! address command 'EXECIO' out.0 'DISKW' outfile '(FINIS STEM OUT.' ! if rc<>0 then call errexit rc,'Problems with EXECIO output' ! ...
We tried your procedure on some one-lined procedures, but it didn't work perfectly as:
We think such a feature would be rather difficult to implement, but we have to praise this student for the work !
We leave you with two other possible solutions (they are a bit more tricky).
In the first one, pay special attention at the second do statement:
nr = 1 /* number of single records */ do i=1 to rec.0 do nr=nr by 1 while rec.i<>'' parse var rec.i out.nr ';' rec.i end end i out.0=nr-1
This second one uses all the whistles of parse. These techniques are covered in extenso in next lesson.
nr = 0 /* number of single records */ do i=1 to rec.0 do while rec.i<>'' parse value nr+1 rec.i with nr . 0 out.0 out.nr ';' rec.i end end
We let you analyze these solutions by yourself. We'll come back on the details when we discuss the exercises of Lesson 3.
You are ready now to read chapter 9.