Solution to Exercise 3

This was the assignment...

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.

General comments

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'
   !      ...

Our solution.

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.