### 8.9 INPUT PROGRAM

         INPUT PROGRAM.
         ... input commands ...
         END INPUT PROGRAM.

`INPUT PROGRAM`...`END INPUT PROGRAM` specifies a complex input program. By placing data input commands within `INPUT PROGRAM`, pspp programs can take advantage of more complex file structures than available with only `DATA LIST`.

The first sort of extended input program is to simply put multiple `DATA LIST` commands within the `INPUT PROGRAM`. This will cause all of the data files to be read in parallel. Input will stop when end of file is reached on any of the data files.

Transformations, such as conditional and looping constructs, can also be included within `INPUT PROGRAM`. These can be used to combine input from several data files in more complex ways. However, input will still stop when end of file is reached on any of the data files.

To prevent `INPUT PROGRAM` from terminating at the first end of file, use the `END` subcommand on `DATA LIST`. This subcommand takes a variable name, which should be a numeric scratch variable (see Scratch Variables). (It need not be a scratch variable but otherwise the results can be surprising.) The value of this variable is set to 0 when reading the data file, or 1 when end of file is encountered.

Two additional commands are useful in conjunction with `INPUT PROGRAM`. `END CASE` is the first. Normally each loop through the `INPUT PROGRAM` structure produces one case. `END CASE` controls exactly when cases are output. When `END CASE` is used, looping from the end of `INPUT PROGRAM` to the beginning does not cause a case to be output.

`END FILE` is the second. When the `END` subcommand is used on `DATA LIST`, there is no way for the `INPUT PROGRAM` construct to stop looping, so an infinite loop results. `END FILE`, when executed, stops the flow of input data and passes out of the `INPUT PROGRAM` structure.

All this is very confusing. A few examples should help to clarify.

         INPUT PROGRAM.
                 DATA LIST NOTABLE FILE='a.data'/X 1-10.
                 DATA LIST NOTABLE FILE='b.data'/Y 1-10.
         END INPUT PROGRAM.
         LIST.

The example above reads variable X from file `a.data` and variable Y from file `b.data`. If one file is shorter than the other then the extra data in the longer file is ignored.

         INPUT PROGRAM.
                 NUMERIC #A #B.

                 DO IF NOT #A.
                         DATA LIST NOTABLE END=#A FILE='a.data'/X 1-10.
                 END IF.
                 DO IF NOT #B.
                         DATA LIST NOTABLE END=#B FILE='b.data'/Y 1-10.
                 END IF.
                 DO IF #A AND #B.
                         END FILE.
                 END IF.
                 END CASE.
         END INPUT PROGRAM.
         LIST.

The above example reads variable X from `a.data` and variable Y from `b.data`. If one file is shorter than the other then the missing field is set to the system-missing value alongside the present value for the remaining length of the longer file.

         INPUT PROGRAM.
                 NUMERIC #A #B.

                 DO IF #A.
                         DATA LIST NOTABLE END=#B FILE='b.data'/X 1-10.
                         DO IF #B.
                                 END FILE.
                         ELSE.
                                 END CASE.
                         END IF.
                 ELSE.
                         DATA LIST NOTABLE END=#A FILE='a.data'/X 1-10.
                         DO IF NOT #A.
                                 END CASE.
                         END IF.
                 END IF.
         END INPUT PROGRAM.
         LIST.

The above example reads data from file `a.data`, then from `b.data`, and concatenates them into a single active dataset.

         INPUT PROGRAM.
                 NUMERIC #EOF.

                 LOOP IF NOT #EOF.
                         DATA LIST NOTABLE END=#EOF FILE='a.data'/X 1-10.
                         DO IF NOT #EOF.
                                 END CASE.
                         END IF.
                 END LOOP.

                 COMPUTE #EOF = 0.
                 LOOP IF NOT #EOF.
                         DATA LIST NOTABLE END=#EOF FILE='b.data'/X 1-10.
                         DO IF NOT #EOF.
                                 END CASE.
                         END IF.
                 END LOOP.

                 END FILE.
         END INPUT PROGRAM.
         LIST.

The above example does the same thing as the previous example, in a different way.

         INPUT PROGRAM.
                 LOOP #I=1 TO 50.
                         COMPUTE X=UNIFORM(10).
                         END CASE.
                 END LOOP.
                 END FILE.
         END INPUT PROGRAM.
         LIST/FORMAT=NUMBERED.

The above example causes an active dataset to be created consisting of 50 random variates between 0 and 10.