pspp-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Pspp-cvs] pspp ./Smake doc/data-io.texi doc/files.texi do...


From: Ben Pfaff
Subject: [Pspp-cvs] pspp ./Smake doc/data-io.texi doc/files.texi do...
Date: Sun, 29 Jan 2006 02:41:12 +0000

CVSROOT:        /cvsroot/pspp
Module name:    pspp
Branch:         
Changes by:     Ben Pfaff <address@hidden>      06/01/29 02:41:12

Modified files:
        .              : Smake 
        doc            : data-io.texi files.texi language.texi 
                         transformation.texi 
        po             : en_GB.po pspp.pot 
        src            : ChangeLog Makefile.am aggregate.c apply-dict.c 
                         cat.h command.def correlations.q data-list.c 
                         dfm-read.c dfm-write.c dictionary.c 
                         dictionary.h error.c file-handle-def.c 
                         file-handle-def.h file-handle.h file-handle.q 
                         file-type.c filename.c filename.h get.c glob.c 
                         inpt-pgm.c matrix-data.c pfm-read.c pfm-read.h 
                         pfm-write.c pfm-write.h print.c regression.q 
                         sfm-read.c sfm-read.h sfm-write.c str.c str.h 
                         sysfile-info.c var.h vfm.c vfm.h 
        tests/bugs     : agg-crash-2.sh compute-lv.sh computebug.out 
                         crosstabs-crash.sh match-files-scratch.sh 
                         multipass.sh recode-copy-bug-1.out 
                         recode-copy-bug-2.out t-test-alpha.sh 
                         temp-freq.sh 
        tests/command  : aggregate.sh autorecod.sh beg-data.sh count.sh 
                         data-list.sh examine-percentiles.sh examine.sh 
                         file-handle.sh file-label.sh flip.sh lag.sh 
                         list.sh longvars.sh loop.sh 
                         oneway-with-splits.sh oneway.sh print.sh 
                         rename.sh sysfile-info.sh t-test-1-indep-val.sh 
                         t-test-1s.sh t-test-groups.sh t-test-pairs.sh 
                         tabs.sh trimmed-mean.sh weight.sh 
        tests/expressions: variables.sh vectors.sh 
        tests/stats    : descript-basic.sh descript-missing.sh 
Added files:
        src            : any-reader.c any-reader.h any-writer.c 
                         any-writer.h scratch-handle.c scratch-handle.h 
                         scratch-reader.c scratch-reader.h 
                         scratch-writer.c scratch-writer.h 

Log message:
        Add scratch file handles.
        
        Now a file handle can refer to a disk file, to an in-memory
        structure, or to the "inline" file, instead of just to a disk
        file.  The introduction of new categories means that special cases
        for the inline file in a few places could be eliminated, but it
        also means that code that assumed that a handle refers to a file
        has to check for that.
        
        Also, now file handles can be freed, so code now must be sure not
        to access a handle after closing it (with fh_close()).
        
        Plus some cleanups.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/Smake.diff?tr1=1.18&tr2=1.19&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/doc/data-io.texi.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/doc/files.texi.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/doc/language.texi.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/doc/transformation.texi.diff?tr1=1.9&tr2=1.10&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/po/en_GB.po.diff?tr1=1.66&tr2=1.67&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/po/pspp.pot.diff?tr1=1.69&tr2=1.70&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/ChangeLog.diff?tr1=1.259&tr2=1.260&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/Makefile.am.diff?tr1=1.62&tr2=1.63&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/aggregate.c.diff?tr1=1.43&tr2=1.44&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/any-reader.c?rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/any-reader.h?rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/any-writer.c?rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/any-writer.h?rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/apply-dict.c.diff?tr1=1.9&tr2=1.10&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/cat.h.diff?tr1=1.6&tr2=1.7&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/command.def.diff?tr1=1.24&tr2=1.25&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/correlations.q.diff?tr1=1.8&tr2=1.9&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/data-list.c.diff?tr1=1.44&tr2=1.45&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/dfm-read.c.diff?tr1=1.9&tr2=1.10&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/dfm-write.c.diff?tr1=1.4&tr2=1.5&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/dictionary.c.diff?tr1=1.32&tr2=1.33&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/dictionary.h.diff?tr1=1.8&tr2=1.9&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/error.c.diff?tr1=1.22&tr2=1.23&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/file-handle-def.c.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/file-handle-def.h.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/file-handle.h.diff?tr1=1.11&tr2=1.12&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/file-handle.q.diff?tr1=1.25&tr2=1.26&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/file-type.c.diff?tr1=1.24&tr2=1.25&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/filename.c.diff?tr1=1.15&tr2=1.16&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/filename.h.diff?tr1=1.3&tr2=1.4&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/get.c.diff?tr1=1.42&tr2=1.43&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/glob.c.diff?tr1=1.33&tr2=1.34&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/inpt-pgm.c.diff?tr1=1.22&tr2=1.23&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/matrix-data.c.diff?tr1=1.34&tr2=1.35&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/pfm-read.c.diff?tr1=1.30&tr2=1.31&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/pfm-read.h.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/pfm-write.c.diff?tr1=1.20&tr2=1.21&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/pfm-write.h.diff?tr1=1.4&tr2=1.5&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/print.c.diff?tr1=1.24&tr2=1.25&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/regression.q.diff?tr1=1.36&tr2=1.37&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/scratch-handle.c?rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/scratch-handle.h?rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/scratch-reader.c?rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/scratch-reader.h?rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/scratch-writer.c?rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/scratch-writer.h?rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/sfm-read.c.diff?tr1=1.28&tr2=1.29&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/sfm-read.h.diff?tr1=1.2&tr2=1.3&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/sfm-write.c.diff?tr1=1.24&tr2=1.25&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/str.c.diff?tr1=1.18&tr2=1.19&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/str.h.diff?tr1=1.13&tr2=1.14&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/sysfile-info.c.diff?tr1=1.20&tr2=1.21&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/var.h.diff?tr1=1.41&tr2=1.42&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/vfm.c.diff?tr1=1.44&tr2=1.45&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/src/vfm.h.diff?tr1=1.12&tr2=1.13&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/bugs/agg-crash-2.sh.diff?tr1=1.8&tr2=1.9&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/bugs/compute-lv.sh.diff?tr1=1.6&tr2=1.7&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/bugs/computebug.out.diff?tr1=1.2&tr2=1.3&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/bugs/crosstabs-crash.sh.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/bugs/match-files-scratch.sh.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/bugs/multipass.sh.diff?tr1=1.7&tr2=1.8&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/bugs/recode-copy-bug-1.out.diff?tr1=1.2&tr2=1.3&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/bugs/recode-copy-bug-2.out.diff?tr1=1.2&tr2=1.3&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/bugs/t-test-alpha.sh.diff?tr1=1.8&tr2=1.9&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/bugs/temp-freq.sh.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/aggregate.sh.diff?tr1=1.12&tr2=1.13&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/autorecod.sh.diff?tr1=1.10&tr2=1.11&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/beg-data.sh.diff?tr1=1.9&tr2=1.10&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/count.sh.diff?tr1=1.8&tr2=1.9&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/data-list.sh.diff?tr1=1.7&tr2=1.8&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/examine-percentiles.sh.diff?tr1=1.8&tr2=1.9&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/examine.sh.diff?tr1=1.11&tr2=1.12&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/file-handle.sh.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/file-label.sh.diff?tr1=1.10&tr2=1.11&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/flip.sh.diff?tr1=1.8&tr2=1.9&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/lag.sh.diff?tr1=1.8&tr2=1.9&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/list.sh.diff?tr1=1.13&tr2=1.14&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/longvars.sh.diff?tr1=1.6&tr2=1.7&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/loop.sh.diff?tr1=1.11&tr2=1.12&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/oneway-with-splits.sh.diff?tr1=1.11&tr2=1.12&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/oneway.sh.diff?tr1=1.13&tr2=1.14&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/print.sh.diff?tr1=1.20&tr2=1.21&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/rename.sh.diff?tr1=1.6&tr2=1.7&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/sysfile-info.sh.diff?tr1=1.7&tr2=1.8&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/t-test-1-indep-val.sh.diff?tr1=1.8&tr2=1.9&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/t-test-1s.sh.diff?tr1=1.9&tr2=1.10&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/t-test-groups.sh.diff?tr1=1.10&tr2=1.11&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/t-test-pairs.sh.diff?tr1=1.9&tr2=1.10&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/tabs.sh.diff?tr1=1.9&tr2=1.10&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/trimmed-mean.sh.diff?tr1=1.10&tr2=1.11&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/command/weight.sh.diff?tr1=1.14&tr2=1.15&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/expressions/variables.sh.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/expressions/vectors.sh.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/stats/descript-basic.sh.diff?tr1=1.7&tr2=1.8&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/pspp/pspp/tests/stats/descript-missing.sh.diff?tr1=1.7&tr2=1.8&r1=text&r2=text

Patches:
Index: pspp/Smake
diff -u pspp/Smake:1.18 pspp/Smake:1.19
--- pspp/Smake:1.18     Thu Jan 26 05:49:47 2006
+++ pspp/Smake  Sun Jan 29 02:41:11 2006
@@ -7,7 +7,7 @@
 gethostname getline getlogin_r getopt gettext memchr memcmp memmem     \
 memmove memset progname readlink restrict snprintf stat-macros stdbool \
 stpcpy strcase strcspn strerror strftime strstr strtod strtok_r strtol \
-strtoul vsnprintf xalloc xalloc-die xreadlink
+strtoul vsnprintf xalloc xalloc-die xreadlink xvasprintf
 
 all: po/POTFILES.in
        test -d m4 || mkdir m4
Index: pspp/doc/data-io.texi
diff -u pspp/doc/data-io.texi:1.5 pspp/doc/data-io.texi:1.6
--- pspp/doc/data-io.texi:1.5   Sat Dec 17 20:06:59 2005
+++ pspp/doc/data-io.texi       Sun Jan 29 02:41:11 2006
@@ -8,26 +8,26 @@
 
 Data are the focus of the PSPP language.  
 Each datum  belongs to a @dfn{case} (also called an @dfn{observation}).
-Each case represents an individual or `experimental unit'.
+Each case represents an individual or ``experimental unit''.
 For example, in the results of a survey, the names of the respondents,
-their sex, age @i{etc}. and their responses are all data and the data
+their sex, age, etc.@: and their responses are all data and the data
 pertaining to single respondent is a case.
 This chapter examines
 the PSPP commands for defining variables and reading and writing data.
 
address@hidden
address@hidden note:} Data is not actually read until a procedure is
-executed.  These commands tell PSPP how to read data, but they
-do not @emph{cause} PSPP to read data.
address@hidden Note
+These commands tell PSPP how to read data, but the data will not
+actually be read until a procedure is executed.
 @end quotation
 
 @menu
 * BEGIN DATA::                  Embed data within a syntax file.
 * CLEAR TRANSFORMATIONS::       Clear pending transformations.
+* CLOSE FILE HANDLE::           Close a file handle.
 * DATA LIST::                   Fundamental data reading command.
 * END CASE::                    Output the current case.
 * END FILE::                    Terminate the current input program.
-* FILE HANDLE::                 Support for fixed-length records.
+* FILE HANDLE::                 Support for special file formats.
 * INPUT PROGRAM::               Support for complex input programs.
 * LIST::                        List cases in the active file.
 * MATRIX DATA::                 Read matrices in text format.
@@ -40,7 +40,7 @@
 * WRITE::                       Display values in write formats.
 @end menu
 
address@hidden BEGIN DATA, CLEAR TRANSFORMATIONS, Data Input and Output, Data 
Input and Output
address@hidden BEGIN DATA
 @section BEGIN DATA
 @vindex BEGIN DATA
 @vindex END DATA
@@ -65,7 +65,7 @@
 END DATA.
 @end example
 
address@hidden CLEAR TRANSFORMATIONS, DATA LIST, BEGIN DATA, Data Input and 
Output
address@hidden CLEAR TRANSFORMATIONS
 @section CLEAR TRANSFORMATIONS
 @vindex CLEAR TRANSFORMATIONS
 
@@ -77,7 +77,31 @@
 transformations.  It does not cancel the current input program.  It is
 valid only when PSPP is interactive, not in syntax files.
 
address@hidden DATA LIST, END CASE, CLEAR TRANSFORMATIONS, Data Input and Output
address@hidden CLOSE FILE HANDLE
address@hidden CLOSE FILE HANDLE
+
address@hidden
+CLOSE FILE HANDLE handle_name.
address@hidden display
+
address@hidden FILE HANDLE} disassociates the name of a file handle with a
+given file.  The only specification is the name of the handle to close.
+Afterward
address@hidden HANDLE}.
+
+If the file handle name refers to a scratch file, then the storage
+associated with the scratch file in memory or on disk will be freed.
+If the scratch file is in use, e.g.@: it has been specified on a
address@hidden command whose execution has not completed, then freeing is
+delayed until it is no longer in use.
+
+The file named INLINE, which represents data entered between @cmd{BEGIN
+DATA} and @cmd{END DATA}, cannot be closed.  Attempts to close it with
address@hidden FILE HANDLE} have no effect.
+
address@hidden FILE HANDLE} is a PSPP extension.
+
address@hidden DATA LIST
 @section DATA LIST
 @vindex DATA LIST
 @cindex reading data from a file
@@ -104,7 +128,7 @@
 * DATA LIST LIST::              Each case must be on a single line.
 @end menu
 
address@hidden DATA LIST FIXED, DATA LIST FREE, DATA LIST, DATA LIST
address@hidden DATA LIST FIXED
 @subsection DATA LIST FIXED
 @vindex DATA LIST FIXED
 @cindex reading fixed-format data
@@ -131,7 +155,7 @@
 
 The FILE subcommand must be used if input is to be taken from an
 external file.  It may be used to specify a filename as a string or a
-file handle (@pxref{FILE HANDLE}).  If the FILE subcommand is not used,
+file handle (@pxref{File Handles}).  If the FILE subcommand is not used,
 then input is assumed to be specified within the command file using
 @cmd{BEGIN address@hidden@cmd{END DATA} (@pxref{BEGIN DATA}).
 
@@ -229,7 +253,7 @@
 * DATA LIST FIXED Examples::    Examples of DATA LIST FIXED.
 @end menu
 
address@hidden DATA LIST FIXED Examples,  , DATA LIST FIXED, DATA LIST FIXED
address@hidden DATA LIST FIXED Examples
 @unnumberedsubsubsec Examples
 
 @enumerate
@@ -315,7 +339,7 @@
 
 @end enumerate
 
address@hidden DATA LIST FREE, DATA LIST LIST, DATA LIST FIXED, DATA LIST
address@hidden DATA LIST FREE
 @subsection DATA LIST FREE
 @vindex DATA LIST FREE
 
@@ -367,7 +391,7 @@
 Specified field widths are ignored on input, although all normal limits
 on field width apply, but they are honored on output.
 
address@hidden DATA LIST LIST,  , DATA LIST FREE, DATA LIST
address@hidden DATA LIST LIST
 @subsection DATA LIST LIST
 @vindex DATA LIST LIST
 
@@ -390,7 +414,7 @@
 record.  If more or fewer fields are found on an input line than
 expected, an appropriate diagnostic is issued.
 
address@hidden END CASE, END FILE, DATA LIST, Data Input and Output
address@hidden END CASE
 @section END CASE
 @vindex END CASE
 
@@ -401,7 +425,7 @@
 @cmd{END CASE} is used only within @cmd{INPUT PROGRAM} to output the
 current case.  @xref{INPUT PROGRAM}, for details.
 
address@hidden END FILE, FILE HANDLE, END CASE, Data Input and Output
address@hidden END FILE
 @section END FILE
 @vindex END FILE
 
@@ -412,50 +436,67 @@
 @cmd{END FILE} is used only within @cmd{INPUT PROGRAM} to terminate
 the current input program.  @xref{INPUT PROGRAM}.
 
address@hidden FILE HANDLE, INPUT PROGRAM, END FILE, Data Input and Output
address@hidden FILE HANDLE
 @section FILE HANDLE
 @vindex FILE HANDLE
 
 @display
-FILE HANDLE handle_name
-        /NAME='filename'
-        /address@hidden,address@hidden
-        /LRECL=rec_len
-        /TABWIDTH=tab_width
+For text files:
+        FILE HANDLE handle_name
+                /NAME='filename'
+                [/MODE=CHARACTER]
+                /TABWIDTH=tab_width
+
+For binary files with fixed-length records:
+        FILE HANDLE handle_name
+                /NAME='filename'
+                /MODE=IMAGE
+                [/LRECL=rec_len]
+
+To explicitly declare a scratch handle:
+        FILE HANDLE handle_name
+                /MODE=SCRATCH
 @end display
 
 Use @cmd{FILE HANDLE} to associate a file handle name with a file and
 its attributes, so that later commands can refer to the file by its
-handle name.  Because names of text files can be specified directly on
-commands that access files, @cmd{FILE HANDLE} is only needed when a
+handle name.  Names of text files can be specified directly on
+commands that access files, so that @cmd{FILE HANDLE} is only needed when a
 file is not an ordinary file containing lines of text.  However,
 @cmd{FILE HANDLE} may be used even for text files, and it may be
 easier to specify a file's name once and later refer to it by an
 abstract handle.
 
-Specify the file handle name as an identifier.  Any given identifier may
-only appear once in a PSPP run.  File handles may not be reassigned to a
-different file.  The file handle name must immediately follow the @cmd{FILE
-HANDLE} command name.
-
-The NAME subcommand specifies the name of the file associated with the
-handle.  It is the only required subcommand.
+Specify the file handle name as the identifier immediately following the
address@hidden HANDLE} command name.  The identifier INLINE is reserved for
+representing data embedded in the syntax file (@pxref{BEGIN DATA}) The
+file handle name must not already have been used in a previous
+invocation of @cmd{FILE HANDLE}, unless it has been closed by an
+intervening command (@pxref{CLOSE FILE HANDLE}).
 
 MODE specifies a file mode.  In CHARACTER mode, the default, the data
-file is opened in ANSI C text mode, so that local end of line
-conventions are followed, and each text line is read as one record.
+file is read as a text file, according to the local system's 
+conventions, and each text line is read as one record.
 In CHARACTER mode, most input programs will expand tabs to spaces
 (@cmd{DATA LIST FREE} with explicitly specified delimiters is an
 exception).  By default, each tab is 4 characters wide, but an
 alternate width may be specified on TABWIDTH.  A tab width of 0
 suppresses tab expansion entirely.
 
-By contrast, in IMAGE mode, the data file is opened in ANSI C binary
-mode and records are a fixed length.  In IMAGE mode, LRECL specifies
-the record length in bytes, with a default of 1024.  Tab characters
-are never expanded to spaces in binary mode.
+In IMAGE mode, the data file is opened in ANSI C binary mode and records
+are fixed in length.  In IMAGE mode, LRECL specifies the record length in
+bytes, with a default of 1024.  Tab characters are never expanded to
+spaces in binary mode.
+
+The NAME subcommand specifies the name of the file associated with the
+handle.  It is required in CHARACTER and IMAGE modes.
+
+The SCRATCH mode designates the file handle as a scratch file handle.
+Its use is usually unnecessary because file handle names that begin with
address@hidden are assumed to refer to scratch files.  @pxref{File Handles},
+for more information.
 
address@hidden INPUT PROGRAM, LIST, FILE HANDLE, Data Input and Output
address@hidden INPUT PROGRAM
 @section INPUT PROGRAM
 @vindex INPUT PROGRAM
 
@@ -606,7 +647,7 @@
 The above example causes an active file to be created consisting of 50
 random variates between 0 and 10.
 
address@hidden LIST, MATRIX DATA, INPUT PROGRAM, Data Input and Output
address@hidden LIST
 @section LIST
 @vindex LIST
 
@@ -647,7 +688,7 @@
 
 @cmd{LIST} is a procedure.  It causes the data to be read.
 
address@hidden MATRIX DATA, NEW FILE, LIST, Data Input and Output
address@hidden MATRIX DATA
 @section MATRIX DATA
 @vindex MATRIX DATA
 
@@ -674,7 +715,7 @@
 should specify VARIABLES first.
 
 Specify the file to read on FILE, either as a file name string or a file
-handle (@pxref{FILE HANDLE}).  If FILE is not specified then matrix data
+handle (@pxref{File Handles}).  If FILE is not specified then matrix data
 must immediately follow @cmd{MATRIX DATA} with a @cmd{BEGIN
 address@hidden@cmd{END DATA}
 construct (@pxref{BEGIN DATA}).
@@ -749,7 +790,7 @@
 accepting or producing related data, so these semantics aren't
 documented.  Later, they'll be described here in detail.
 
address@hidden NEW FILE, PRINT, MATRIX DATA, Data Input and Output
address@hidden NEW FILE
 @section NEW FILE
 @vindex NEW FILE
 
@@ -759,7 +800,7 @@
 
 @cmd{NEW FILE} command clears the current active file.
 
address@hidden PRINT, PRINT EJECT, NEW FILE, Data Input and Output
address@hidden PRINT
 @section PRINT
 @vindex PRINT
 
@@ -785,8 +826,8 @@
 All @cmd{PRINT} subcommands are optional.
 
 The OUTFILE subcommand specifies the file to receive the output.  The
-file may be a file name as a string or a file handle (@pxref{FILE
-HANDLE}).  If OUTFILE is not present then output will be sent to PSPP's
+file may be a file name as a string or a file handle (@pxref{File
+Handles}).  If OUTFILE is not present then output will be sent to PSPP's
 output listing file.
 
 The RECORDS subcommand specifies the number of lines to be output.  The
@@ -822,7 +863,7 @@
 truncated to that length, although additional text being added will
 again extend the line to that length.
 
address@hidden PRINT EJECT, PRINT SPACE, PRINT, Data Input and Output
address@hidden PRINT EJECT
 @section PRINT EJECT
 @vindex PRINT EJECT
 
@@ -845,7 +886,7 @@
 
 @xref{PRINT}, for more information on syntax and usage.
 
address@hidden PRINT SPACE, REREAD, PRINT EJECT, Data Input and Output
address@hidden PRINT SPACE
 @section PRINT SPACE
 @vindex PRINT SPACE
 
@@ -856,15 +897,15 @@
 @cmd{PRINT SPACE} prints one or more blank lines to an output file.
 
 The OUTFILE subcommand is optional.  It may be used to direct output to
-a file specified by file name as a string or file handle (@pxref{FILE
-HANDLE}).  If OUTFILE is not specified then output will be directed to
+a file specified by file name as a string or file handle (@pxref{File
+Handles}).  If OUTFILE is not specified then output will be directed to
 the listing file.
 
 n_lines is also optional.  If present, it is an expression
 (@pxref{Expressions}) specifying the number of blank lines to be
 printed.  The expression must evaluate to a nonnegative value.
 
address@hidden REREAD, REPEATING DATA, PRINT SPACE, Data Input and Output
address@hidden REREAD
 @section REREAD
 @vindex REREAD
 
@@ -878,8 +919,8 @@
 for further processing.
 
 The FILE subcommand, which is optional, is used to specify the file to
-have its line re-read.  The file must be specified in the form of a file
-handle (@pxref{FILE HANDLE}).  If FILE is not specified then the last
+have its line re-read.  The file must be specified as the name of a file
+handle (@pxref{File Handles}).  If FILE is not specified then the last
 file specified on @cmd{DATA LIST} will be assumed (last file specified
 lexically, not in terms of flow-of-control).
 
@@ -892,7 +933,7 @@
 Issuing @code{REREAD} multiple times will not back up in the data
 file.  Instead, it will re-read the same line multiple times.
 
address@hidden REPEATING DATA, WRITE, REREAD, Data Input and Output
address@hidden REPEATING DATA
 @section REPEATING DATA
 @vindex REPEATING DATA
 
@@ -941,7 +982,7 @@
 All other subcommands are optional.
 
 FILE specifies the file to read, either a file name as a string or a
-file handle (@pxref{FILE HANDLE}).  If FILE is not present then the
+file handle (@pxref{File Handles}).  If FILE is not present then the
 default is the last file handle used on @cmd{DATA LIST} (lexically, not in
 terms of flow of control).
 
@@ -974,7 +1015,7 @@
 structure (@pxref{LOOP}).  Use @cmd{DATA LIST} before, not after,
 @cmd{REPEATING DATA}.
 
address@hidden WRITE,  , REPEATING DATA, Data Input and Output
address@hidden WRITE
 @section WRITE
 @vindex WRITE
 
Index: pspp/doc/files.texi
diff -u pspp/doc/files.texi:1.5 pspp/doc/files.texi:1.6
--- pspp/doc/files.texi:1.5     Sun Aug 21 07:21:06 2005
+++ pspp/doc/files.texi Sun Jan 29 02:41:11 2006
@@ -21,18 +21,18 @@
 @vindex APPLY DICTIONARY
 
 @display
-APPLY DICTIONARY FROM='filename'.
+APPLY DICTIONARY address@hidden'filename',address@hidden
 @end display
 
 @cmd{APPLY DICTIONARY} applies the variable labels, value labels,
-and missing values from variables in a system file to corresponding
+and missing values taken from a file to corresponding
 variables in the active file.  In some cases it also updates the
 weighting variable.
 
-Specify a system file with a file name string or as a file handle
-(@pxref{FILE HANDLE}).  The dictionary in the system file will be read,
-but it will not replace the active file dictionary.  The system file's
-data will not be read.
+Specify a system file, portable file, or scratch file with a file name
+string or as a file handle (@pxref{File Handles}).  The dictionary in the
+file will be read, but it will not replace the active file dictionary.
+The file's data will not be read.
 
 Only variables with names that exist in both the active file and the
 system file are considered.  Variables with the same name but different
@@ -79,9 +79,9 @@
 @end display
 
 The @cmd{EXPORT} procedure writes the active file dictionary and data to a
-specified portable file.
+specified portable file or scratch file.
 
-By default, cases excluded with FILTER are written to the portable
+By default, cases excluded with FILTER are written to the
 file.  These can be excluded by specifying DELETE on the UNSELECTED
 subcommand.  Specifying RETAIN makes the default explicit.
 
@@ -95,8 +95,8 @@
 precision to write.  DIGITS applies only to non-integers.
 
 The OUTFILE subcommand, which is the only required subcommand, specifies
-the portable file to be written as a file name string or a file handle
-(@pxref{FILE HANDLE}).
+the portable file or scratch file to be written as a file name string or
+a file handle (@pxref{File Handles}).
 
 DROP, KEEP, and RENAME follow the same format as the SAVE procedure
 (@pxref{SAVE}).
@@ -114,25 +114,25 @@
 
 @display
 GET
-        /FILE='filename'
+        /address@hidden'filename',address@hidden
         /DROP=var_list
         /KEEP=var_list
         /RENAME=(src_names=target_names)@dots{}
 @end display
 
 @cmd{GET} clears the current dictionary and active file and
-replaces them with the dictionary and data from a specified system file.
+replaces them with the dictionary and data from a specified file.
 
 The FILE subcommand is the only required subcommand.  Specify the system
-file to be read as a string file name or a file handle (@pxref{FILE
-HANDLE}).
+file, portable file, or scratch file to be read as a string file name or
+a file handle (@pxref{File Handles}).
 
-By default, all the variables in a system file are read.  The DROP
+By default, all the variables in a file are read.  The DROP
 subcommand can be used to specify a list of variables that are not to be
 read.  By contrast, the KEEP subcommand can be used to specify variable
 that are to be read, with all other variables not read.
 
-Normally variables in a system file retain the names that they were
+Normally variables in a file retain the names that they were
 saved under.  Use the RENAME subcommand to change these names.  Specify,
 within parentheses, a list of variable names followed by an equals sign
 (@samp{=}) and the names that they should be renamed to.  Multiple
@@ -145,14 +145,17 @@
 once.  For instance, @samp{/RENAME=A=B}.  This alternate syntax is
 deprecated.
 
-DROP, KEEP, and RENAME are performed in left-to-right order.  They
-each may be present any number of times.  @cmd{GET} never modifies a
-system file on disk.  Only the active file read from the system file
+DROP, KEEP, and RENAME are executed in left-to-right order.  
+Each may be present any number of times.  @cmd{GET} never modifies a
+file on disk.  Only the active file read from the file
 is affected by these subcommands.
 
 @cmd{GET} does not cause the data to be read, only the dictionary.  The data
 is read later, when a procedure is executed.
 
+Use of @cmd{GET} to read a portable file or scratch file is a PSPP
+extension.
+
 @node IMPORT
 @section IMPORT
 @vindex IMPORT
@@ -168,11 +171,12 @@
 
 The @cmd{IMPORT} transformation clears the active file dictionary and
 data and
-replaces them with a dictionary and data from a portable file on disk.
+replaces them with a dictionary and data from a system, portable file,
+or scratch file.
 
 The FILE subcommand, which is the only required subcommand, specifies
 the portable file to be read as a file name string or a file handle
-(@pxref{FILE HANDLE}).
+(@pxref{File Handles}).
 
 The TYPE subcommand is currently not used.
 
@@ -181,6 +185,9 @@
 @cmd{IMPORT} does not cause the data to be read, only the dictionary.  The
 data is read later, when a procedure is executed.
 
+Use of @cmd{IMPORT} to read a system file or scratch file is a PSPP
+extension.
+
 @node MATCH FILES
 @section MATCH FILES
 @vindex MATCH FILES
@@ -199,26 +206,28 @@
         /MAP
 @end display
 
address@hidden FILES} merges one or more system files, optionally
address@hidden FILES} merges one or more system, portable, or scratch files,
+optionally
 including the active file.  Records with the same values for BY
 variables are combined into a single record.  Records with different
-values are output in order.  Thus, multiple sorted system files are
-combined into a single sorted system file based on the value of the BY
+values are output in order.  Thus, multiple sorted files are
+combined into a single sorted file based on the value of the BY
 variables.  The results of the merge become the new active file.
 
 The BY subcommand specifies a list of variables that are used to match
-records from each of the system files.  Variables specified must exist
+records from each of the files.  Variables specified must exist
 in all the files specified on FILE and TABLE.  BY should usually be
 specified.  If TABLE or IN is used then BY is required.
 
-Specify FILE with a system file as a file name string or file handle
-(@pxref{FILE HANDLE}), or with an asterisk (@samp{*}) to
+Specify FILE with a system, portable, or scratch file as a file name
+string or file handle
+(@pxref{File Handles}), or with an asterisk (@samp{*}) to
 indicate the current active file.  The files specified on FILE are
 merged together based on the BY variables, or combined case-by-case if
 BY is not specified.  Normally at least two FILE subcommands should be
 specified.
 
-Specify TABLE with a system file to use it as a @dfn{table
+Specify TABLE with a file to use it as a @dfn{table
 lookup file}.  Records in table lookup files are not used up after
 they've been used once.  This means that data in table lookup files can
 correspond to any number of records in FILE files.  Table lookup files
@@ -247,13 +256,16 @@
 @cmd{MATCH FILES} may not be specified following @cmd{TEMPORARY}
 (@pxref{TEMPORARY}) if the active file is used as an input source.
 
+Use of portable or scratch files on @cmd{MATCH FILES} is a PSPP
+extension.
+
 @node SAVE
 @section SAVE
 @vindex SAVE
 
 @display
 SAVE
-        /OUTFILE='filename'
+        /address@hidden'filename',address@hidden
         /address@hidden,address@hidden
         /@{COMPRESSED,address@hidden
         /address@hidden,address@hidden
@@ -267,11 +279,11 @@
 
 The @cmd{SAVE} procedure causes the dictionary and data in the active
 file to
-be written to a system file.
+be written to a system file or scratch file.
 
-OUTFILE is the only required subcommand.  Specify the system
-file to be written as a string file name or a file handle (@pxref{FILE
-HANDLE}).
+OUTFILE is the only required subcommand.  Specify the system file or
+scratch file to be written as a string file name or a file handle
+(@pxref{File Handles}).
 
 By default, cases excluded with FILTER are written to the system file.
 These can be excluded by specifying DELETE on the UNSELECTED
@@ -384,7 +396,7 @@
 @end display
 
 The @cmd{XSAVE} transformation writes the active file dictionary and
-data to a system file stored on disk.  It is similar to the @cmd{SAVE}
+data to a system file or scratch file.  It is similar to the @cmd{SAVE}
 procedure, with two differences:
 
 @itemize
Index: pspp/doc/language.texi
diff -u pspp/doc/language.texi:1.5 pspp/doc/language.texi:1.6
--- pspp/doc/language.texi:1.5  Wed May  4 15:36:56 2005
+++ pspp/doc/language.texi      Sun Jan 29 02:41:11 2006
@@ -20,6 +20,7 @@
 * Missing Observations::        Handling missing observations.
 * Variables::                   The unit of data storage.
 * Files::                       Files used by PSPP.
+* File Handles::                How files are named.
 * BNF::                         How command syntax is described.
 @end menu
 
@@ -898,7 +899,7 @@
 to copy its value into an ordinary variable, then use that ordinary
 variable in the analysis.
 
address@hidden Files, BNF, Variables, Language
address@hidden Files
 @section Files Used by PSPP
 
 PSPP makes use of many files each time it runs.  Some of these it
@@ -914,16 +915,14 @@
 @itemx syntax file
 These names (synonyms) refer to the file that contains instructions
 that tell PSPP what to do.  The syntax file's name is specified on
-the PSPP command line.  Syntax files can also be pulled in with
+the PSPP command line.  Syntax files can also be read with
 @cmd{INCLUDE} (@pxref{INCLUDE}).
 
 @cindex file, data
 @cindex data file
 @item data file
-Data files contain raw data in ASCII format suitable for being read in
-by @cmd{DATA LIST}.  Data can be embedded in the syntax
-file with @cmd{BEGIN DATA} and @cmd{END DATA}: this makes the
-syntax file a data file too.
+Data files contain raw data in text or binary format.  Data can also
+be embedded in a syntax file with @cmd{BEGIN DATA} and @cmd{END DATA}.
 
 @cindex file, output
 @cindex output file
@@ -936,13 +935,82 @@
 @cindex active file
 @cindex file, active
 @item active file
-The active file is the ``file'' on which all PSPP procedures
-are performed.  The active file contains variable definitions and
-cases.  The active file is not necessarily a disk file: it is stored
-in memory if there is room.
+The active file is the ``file'' on which all PSPP procedures are
+performed.  The active file consists of a dictionary and a set of cases.
+The active file is not necessarily a disk file: it is stored in memory
+if there is room.
+
address@hidden system file
address@hidden file, system
address@hidden system file
+System files are binary files that store a dictionary and a set of
+cases.  @cmd{GET} and @cmd{SAVE} read and write system files.
+
address@hidden portable file
address@hidden file, portable
address@hidden portable file
+Portable files are files in a text-based format that store a dictionary
+and a set of cases.  @cmd{IMPORT} and @cmd{EXPORT} read and write
+portable files.
+
address@hidden scratch file
address@hidden file, scratch
address@hidden scratch file
+Scratch files consist of a dictionary and cases and may be stored in
+memory or on disk.  Most procedures that act on a system file or
+portable file can use a scratch file instead.  The contents of scratch
+files persist within a single PSPP session only.  @cmd{GET} and
address@hidden can be used to read and write scratch files.  Scratch files
+are a PSPP extension.
 @end table
 
address@hidden BNF,  , Files, Language
address@hidden File Handles
address@hidden File Handles
address@hidden file handles
+
+A @dfn{file handle} is a reference to a data file, system file, portable
+file, or scratch file.  Most often, a file handle is specified as the
+name of a file as a string, that is, enclosed within @samp{'} or
address@hidden"}.
+
+PSPP also supports declaring named file handles with the @cmd{FILE
+HANDLE} command.  This command associates an identifier of your choice
+(the file handle's name) with a file.  Later, the file handle name can
+be substituted for the name of the file.  When PSPP syntax accesses a
+file multiple times, declaring a named file handle simplifies updating
+the syntax later to use a different file.  Use of @cmd{FILE HANDLE} is
+also required to read data files in binary formats.  @xref{FILE HANDLE},
+for more information.
+
+PSPP assumes that a file handle name that begins with @samp{#} refers to
+a scratch file, unless the name has already been declared on @cmd{FILE
+HANDLE} to refer to another kind of file.  A scratch file is similar to
+a system file, except that it persists only for the duration of a given
+PSPP session.  Most commands that read or write a system or portable
+file, such as @cmd{GET} and @cmd{SAVE}, also accept scratch file
+handles.  Scratch file handles may also be declared explicitly with
address@hidden HANDLE}.  Scratch files are a PSPP extension.
+
+In some circumstances, PSPP must distinguish whether a file handle
+refers to a system file or a portable file.  When this is necessary to
+read a file, e.g.@: as an input file for @cmd{GET} or @cmd{MATCH FILES},
+PSPP uses the file's contents to decide.  In the context of writing a
+file, e.g.@: as an output file for @cmd{SAVE} or @cmd{AGGREGATE}, PSPP
+decides based on the file's name: if it ends in @samp{.por} (with any
+capitalization), then PSPP writes a portable file; otherwise, PSPP
+writes a system file.
+
+INLINE is reserved as a file handle name.  It refers to the ``data
+file'' embedded into the syntax file between @cmd{BEGIN DATA} and
address@hidden DATA}.  @xref{BEGIN DATA}, for more information.
+
+The file to which a file handle refers may be reassigned on a later
address@hidden HANDLE} command if it is first closed using @cmd{CLOSE FILE
+HANDLE}.  The @cmd{CLOSE FILE HANDLE} command is also useful to free the
+storage associated with a scratch file.  @xref{CLOSE FILE HANDLE}, for
+more information.
+
address@hidden BNF
 @section Backus-Naur Form
 @cindex BNF
 @cindex Backus-Naur Form
Index: pspp/doc/transformation.texi
diff -u pspp/doc/transformation.texi:1.9 pspp/doc/transformation.texi:1.10
--- pspp/doc/transformation.texi:1.9    Mon May  2 06:21:20 2005
+++ pspp/doc/transformation.texi        Sun Jan 29 02:41:11 2006
@@ -23,7 +23,7 @@
 
 @display
 AGGREGATE 
-        address@hidden,'filename'@}          
+        address@hidden,'filename',address@hidden          
         /PRESORTED
         /DOCUMENT
         /MISSING=COLUMNWISE
@@ -37,9 +37,11 @@
 for summarizing case contents.
 
 The OUTFILE subcommand is required and must appear first.  Specify a
-system file by file name string or file handle (@pxref{FILE HANDLE}).
+system file, portable file, or scratch file by file name or file
+handle (@pxref{File Handles}).
 The aggregated cases are written to this file.  If @samp{*} is
-specified, then the aggregated cases replace the active file.
+specified, then the aggregated cases replace the active file.  Use of
+OUTFILE to write a portable file or scratch file is a PSPP extension.
 
 By default, the active file will be sorted based on the break variables
 before aggregation takes place.  If the active file is already sorted
Index: pspp/po/en_GB.po
diff -u pspp/po/en_GB.po:1.66 pspp/po/en_GB.po:1.67
--- pspp/po/en_GB.po:1.66       Tue Jan 24 09:58:18 2006
+++ pspp/po/en_GB.po    Sun Jan 29 02:41:11 2006
@@ -7,7 +7,7 @@
 msgstr ""
 "Project-Id-Version: PSPP 0.3.1\n"
 "Report-Msgid-Bugs-To: address@hidden"
-"POT-Creation-Date: 2006-01-24 17:40+0800\n"
+"POT-Creation-Date: 2006-01-28 17:20-0800\n"
 "PO-Revision-Date: 2004-01-23 13:04+0800\n"
 "Last-Translator: John Darrington <address@hidden>\n"
 "Language-Team: John Darrington <address@hidden>\n"
@@ -16,15 +16,15 @@
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n!=1);\n"
 
-#: src/aggregate.c:199
+#: src/aggregate.c:200
 msgid "while expecting COLUMNWISE"
 msgstr ""
 
-#: src/aggregate.c:228
+#: src/aggregate.c:229
 msgid "expecting BREAK"
 msgstr ""
 
-#: src/aggregate.c:233
+#: src/aggregate.c:234
 msgid ""
 "When PRESORTED is specified, specifying sorting directions with (A) or (D) "
 "has no effect.  Output data will be sorted the same way as the input data."
@@ -78,20 +78,34 @@
 "contains the aggregate variables and the break variables."
 msgstr ""
 
+#: src/any-reader.c:74
+#, c-format
+msgid "An error occurred while opening \"%s\": %s."
+msgstr ""
+
+#: src/any-reader.c:129
+#, c-format
+msgid "\"%s\" is not a system or portable file."
+msgstr ""
+
+#: src/any-reader.c:135 src/any-writer.c:80
+msgid "The inline file is not allowed here."
+msgstr ""
+
 #: src/apply-dict.c:71
 #, c-format
 msgid "Variable %s is %s in target file, but %s in source file."
 msgstr ""
 
 #: src/apply-dict.c:74 src/apply-dict.c:75 src/format.c:198 src/recode.c:464
-#: src/recode.c:465 src/sfm-read.c:1014 src/sfm-read.c:1159
-#: src/sfm-read.c:1160 src/vars-atr.c:40 src/vars-atr.c:48
+#: src/recode.c:465 src/sfm-read.c:1016 src/sfm-read.c:1161
+#: src/sfm-read.c:1162 src/vars-atr.c:40 src/vars-atr.c:48
 msgid "string"
 msgstr ""
 
 #: src/apply-dict.c:74 src/apply-dict.c:75 src/format.c:198 src/recode.c:464
-#: src/recode.c:465 src/sfm-read.c:1014 src/sfm-read.c:1159
-#: src/sfm-read.c:1160 src/vars-atr.c:40
+#: src/recode.c:465 src/sfm-read.c:1016 src/sfm-read.c:1161
+#: src/sfm-read.c:1162 src/vars-atr.c:40
 msgid "numeric"
 msgstr ""
 
@@ -234,8 +248,8 @@
 msgid "Source variable count (%u) does not match target variable count (%u)."
 msgstr ""
 
-#: src/autorecode.c:142 src/command.c:797 src/file-handle.q:83 src/lexer.c:440
-#: src/matrix-data.c:532 src/print.c:335 src/print.c:1044 src/sel-if.c:57
+#: src/autorecode.c:142 src/command.c:797 src/lexer.c:440
+#: src/matrix-data.c:532 src/print.c:335 src/print.c:1046 src/sel-if.c:57
 #: src/sel-if.c:134 src/vector.c:197
 msgid "expecting end of command"
 msgstr ""
@@ -560,7 +574,7 @@
 
 #: src/crosstabs.q:1109 src/crosstabs.q:1136 src/crosstabs.q:1156
 #: src/crosstabs.q:1178 src/examine.q:1131 src/frequencies.q:1142
-#: src/frequencies.q:1263 src/sysfile-info.c:518 src/vfm.c:840
+#: src/frequencies.q:1263 src/sysfile-info.c:518 src/vfm.c:845
 msgid "Value"
 msgstr ""
 
@@ -934,288 +948,275 @@
 msgid "Field too long (%d characters).  Truncated after character %d."
 msgstr ""
 
-#: src/data-list.c:142
-msgid ""
-"DATA LIST may not use a different file from that specified on its "
-"surrounding FILE TYPE."
+#: src/data-list.c:144
+msgid "DATA LIST must use the same file as the enclosing FILE TYPE."
 msgstr ""
 
-#: src/data-list.c:161
+#: src/data-list.c:163
 msgid "The END subcommand may only be specified once."
 msgstr ""
 
-#: src/data-list.c:196
+#: src/data-list.c:198
 msgid "Only one of FIXED, FREE, or LIST may be specified."
 msgstr ""
 
-#: src/data-list.c:346 src/print.c:296
+#: src/data-list.c:348 src/print.c:296
 #, c-format
 msgid ""
 "The record number specified, %ld, is before the previous record, %d.  Data "
 "fields must be listed in order of increasing record number."
 msgstr ""
 
-#: src/data-list.c:375 src/data-list.c:1735
+#: src/data-list.c:377 src/data-list.c:1727
 msgid ""
 "SPSS-like or FORTRAN-like format specification expected after variable names."
 msgstr ""
 
-#: src/data-list.c:386
+#: src/data-list.c:388
 msgid "At least one variable must be specified."
 msgstr ""
 
-#: src/data-list.c:391 src/print.c:328
+#: src/data-list.c:393 src/print.c:328
 msgid ""
 "Variables are specified on records that should not exist according to "
 "RECORDS subcommand."
 msgstr ""
 
-#: src/data-list.c:424 src/data-list.c:438 src/print.c:520 src/print.c:533
+#: src/data-list.c:426 src/data-list.c:440 src/print.c:520 src/print.c:533
 msgid "Column positions for fields must be positive."
 msgstr ""
 
-#: src/data-list.c:443
+#: src/data-list.c:445
 msgid "The ending column for a field must be greater than the starting column."
 msgstr ""
 
-#: src/data-list.c:457
+#: src/data-list.c:459
 #, c-format
 msgid "The %d columns %d-%d can't be evenly divided into %d fields."
 msgstr ""
 
-#: src/data-list.c:477 src/print.c:561
+#: src/data-list.c:479 src/print.c:561
 msgid "A format specifier on this line has extra characters on the end."
 msgstr ""
 
-#: src/data-list.c:492 src/print.c:577
+#: src/data-list.c:494 src/print.c:577
 msgid "The value for number of decimal places must be at least 1."
 msgstr ""
 
-#: src/data-list.c:506 src/print.c:590
+#: src/data-list.c:508 src/print.c:590
 #, c-format
 msgid "Input format %s doesn't accept decimal places."
 msgstr ""
 
-#: src/data-list.c:553 src/data-list.c:649 src/data-list.c:863
+#: src/data-list.c:555 src/data-list.c:651 src/data-list.c:859
 #, c-format
 msgid "%s is a duplicate variable name."
 msgstr ""
 
-#: src/data-list.c:558
+#: src/data-list.c:560
 #, c-format
 msgid "There is already a variable %s of a different type."
 msgstr ""
 
-#: src/data-list.c:565
+#: src/data-list.c:567
 #, c-format
 msgid "There is already a string variable %s of a different width."
 msgstr ""
 
-#: src/data-list.c:640
+#: src/data-list.c:642
 msgid ""
 "The number of format specifications exceeds the given number of variable "
 "names."
 msgstr ""
 
-#: src/data-list.c:753 src/print.c:766
+#: src/data-list.c:755 src/print.c:766
 msgid ""
 "There aren't enough format specifications to match the number of variable "
 "names given."
 msgstr ""
 
-#: src/data-list.c:780 src/data-list.c:904 src/descript.c:882 src/print.c:797
-#: src/sysfile-info.c:139 src/sysfile-info.c:373 src/vfm.c:839
+#: src/data-list.c:782 src/data-list.c:900 src/descript.c:882 src/print.c:797
+#: src/sysfile-info.c:139 src/sysfile-info.c:373 src/vfm.c:844
 msgid "Variable"
 msgstr ""
 
-#: src/data-list.c:781 src/print.c:798
+#: src/data-list.c:783 src/print.c:798
 msgid "Record"
 msgstr ""
 
-#: src/data-list.c:782 src/print.c:799
+#: src/data-list.c:784 src/print.c:799
 msgid "Columns"
 msgstr ""
 
-#: src/data-list.c:783 src/data-list.c:905 src/print.c:800
+#: src/data-list.c:785 src/data-list.c:901 src/print.c:800
 msgid "Format"
 msgstr ""
 
-#: src/data-list.c:799
+#: src/data-list.c:800
 #, c-format
-msgid "Reading %d record from file %s."
-msgid_plural "Reading %d records from file %s."
+msgid "Reading %d record from %s."
+msgid_plural "Reading %d records from %s."
 msgstr[0] ""
 msgstr[1] ""
 
-#: src/data-list.c:803
+#: src/data-list.c:916
 #, c-format
-msgid "Reading %d record from the command file."
-msgid_plural "Reading %d records from the command file."
-msgstr[0] ""
-msgstr[1] ""
-
-#: src/data-list.c:921
-#, c-format
-msgid "Reading free-form data from file %s."
-msgstr ""
-
-#: src/data-list.c:924
-msgid "Reading free-form data from the command file."
+msgid "Reading free-form data from %s."
 msgstr ""
 
-#: src/data-list.c:975
+#: src/data-list.c:967
 #, c-format
 msgid "Quoted string missing terminating `%c'."
 msgstr ""
 
-#: src/data-list.c:1084
+#: src/data-list.c:1076
 #, c-format
 msgid "Partial case of %d of %d records discarded."
 msgstr ""
 
-#: src/data-list.c:1138
+#: src/data-list.c:1130
 #, c-format
 msgid "Partial case discarded.  The first variable missing was %s."
 msgstr ""
 
-#: src/data-list.c:1182
+#: src/data-list.c:1174
 #, c-format
 msgid ""
 "Missing value(s) for all variables from %s onward.  These will be filled "
 "with the system-missing value or blanks, as appropriate."
 msgstr ""
 
-#: src/data-list.c:1259
+#: src/data-list.c:1251
 msgid "Attempt to read past end of file."
 msgstr ""
 
-#: src/data-list.c:1398
+#: src/data-list.c:1390
 msgid ""
 "REPEATING DATA must use the same file as its corresponding DATA LIST or FILE "
 "TYPE."
 msgstr ""
 
-#: src/data-list.c:1408 src/data-list.c:1442 src/data-list.c:1455
-#: src/data-list.c:1468 src/data-list.c:1502
+#: src/data-list.c:1400 src/data-list.c:1434 src/data-list.c:1447
+#: src/data-list.c:1460 src/data-list.c:1494
 #, c-format
 msgid "%s subcommand given multiple times."
 msgstr ""
 
-#: src/data-list.c:1431
+#: src/data-list.c:1423
 #, c-format
 msgid "STARTS beginning column (%d) exceeds STARTS ending column (%d)."
 msgstr ""
 
-#: src/data-list.c:1488
+#: src/data-list.c:1480
 #, c-format
 msgid "CONTINUED beginning column (%d) exceeds CONTINUED ending column (%d)."
 msgstr ""
 
-#: src/data-list.c:1511
+#: src/data-list.c:1503
 #, c-format
 msgid "ID beginning column (%ld) must be positive."
 msgstr ""
 
-#: src/data-list.c:1526
+#: src/data-list.c:1518
 #, c-format
 msgid "ID ending column (%ld) must be positive."
 msgstr ""
 
-#: src/data-list.c:1532
+#: src/data-list.c:1524
 #, c-format
 msgid "ID ending column (%ld) cannot be less than ID beginning column (%d)."
 msgstr ""
 
-#: src/data-list.c:1572
+#: src/data-list.c:1564
 msgid "Missing required specification STARTS."
 msgstr ""
 
-#: src/data-list.c:1574
+#: src/data-list.c:1566
 msgid "Missing required specification OCCURS."
 msgstr ""
 
-#: src/data-list.c:1581
+#: src/data-list.c:1573
 msgid "ID specified without CONTINUED."
 msgstr ""
 
-#: src/data-list.c:1592
+#: src/data-list.c:1584
 #, c-format
 msgid ""
 "STARTS beginning column (%d) exceeds default STARTS ending column taken from "
 "file's record width (%d)."
 msgstr ""
 
-#: src/data-list.c:1605
+#: src/data-list.c:1597
 #, c-format
 msgid ""
 "CONTINUED beginning column (%d) exceeds default CONTINUED ending column "
 "taken from file's record width (%d)."
 msgstr ""
 
-#: src/data-list.c:1684
+#: src/data-list.c:1676
 msgid "String variable not allowed here."
 msgstr ""
 
-#: src/data-list.c:1694
+#: src/data-list.c:1686
 #, c-format
 msgid "%s (%d) must be at least 1."
 msgstr ""
 
-#: src/data-list.c:1700
+#: src/data-list.c:1692
 #, c-format
 msgid "Variable or integer expected for %s."
 msgstr ""
 
-#: src/data-list.c:1825
+#: src/data-list.c:1817
 #, c-format
 msgid "Encountered mismatched record ID \"%s\" expecting \"%s\"."
 msgstr ""
 
-#: src/data-list.c:1857
+#: src/data-list.c:1849
 #, c-format
 msgid ""
 "Variable %s starting in column %d extends beyond physical record length of %"
 "d."
 msgstr ""
 
-#: src/data-list.c:1924
+#: src/data-list.c:1916
 #, c-format
 msgid "Invalid value %d for OCCURS."
 msgstr ""
 
-#: src/data-list.c:1930
+#: src/data-list.c:1922
 #, c-format
 msgid "Beginning column for STARTS (%d) must be at least 1."
 msgstr ""
 
-#: src/data-list.c:1938
+#: src/data-list.c:1930
 #, c-format
 msgid "Ending column for STARTS (%d) is less than beginning column (%d)."
 msgstr ""
 
-#: src/data-list.c:1946
+#: src/data-list.c:1938
 #, c-format
 msgid "Invalid value %d for LENGTH."
 msgstr ""
 
-#: src/data-list.c:1953
+#: src/data-list.c:1945
 #, c-format
 msgid "Beginning column for CONTINUED (%d) must be at least 1."
 msgstr ""
 
-#: src/data-list.c:1961
+#: src/data-list.c:1953
 #, c-format
 msgid "Ending column for CONTINUED (%d) is less than beginning column (%d)."
 msgstr ""
 
-#: src/data-list.c:1993
+#: src/data-list.c:1985
 #, c-format
 msgid ""
 "Number of repetitions specified on OCCURS (%d) exceed number of repetitions "
 "available in space on STARTS (%d), and CONTINUED not specified."
 msgstr ""
 
-#: src/data-list.c:2011
+#: src/data-list.c:2003
 #, c-format
 msgid "Unexpected end of file with %d repetitions remaining out of %d."
 msgstr ""
@@ -1367,42 +1368,42 @@
 msgid "Valid cases = %g; cases with missing value(s) = %g."
 msgstr ""
 
-#: src/dfm-read.c:158
+#: src/dfm-read.c:136
 #, c-format
 msgid "Could not open \"%s\" for reading as a data file: %s."
 msgstr ""
 
-#: src/dfm-read.c:191 src/dfm-read.c:209
+#: src/dfm-read.c:168 src/dfm-read.c:186
 msgid "BEGIN DATA expected."
 msgstr ""
 
-#: src/dfm-read.c:218
+#: src/dfm-read.c:195
 msgid ""
 "Unexpected end-of-file while reading data in BEGIN DATA.  This probably "
 "indicates a missing or misformatted END DATA command.  END DATA must appear "
 "by itself on a single line with exactly one space between words."
 msgstr ""
 
-#: src/dfm-read.c:251 src/dfm-read.c:271
+#: src/dfm-read.c:227 src/dfm-read.c:247
 #, c-format
 msgid "Error reading file %s: %s."
 msgstr ""
 
-#: src/dfm-read.c:274
+#: src/dfm-read.c:250
 #, c-format
 msgid "%s: Partial record at end of file."
 msgstr ""
 
-#: src/dfm-read.c:317
+#: src/dfm-read.c:299
 #, c-format
 msgid "Attempt to read beyond end-of-file on file %s."
 msgstr ""
 
-#: src/dfm-read.c:320
+#: src/dfm-read.c:302
 msgid "Attempt to read beyond END DATA."
 msgstr ""
 
-#: src/dfm-read.c:467
+#: src/dfm-read.c:446
 msgid ""
 "This command is not valid here since the current input program does not "
 "access the inline file."
@@ -1720,67 +1721,61 @@
 msgid "%s is a PSPP extension."
 msgstr ""
 
-#: src/file-handle-def.c:229
+#: src/file-handle-def.c:303
 #, c-format
-msgid "Can't open %s as a %s because it is already open as a %s"
+msgid "Can't open %s as a %s because it is already open as a %s."
 msgstr ""
 
-#: src/file-handle-def.c:236
+#: src/file-handle-def.c:310
 #, c-format
-msgid "Can't open %s as a %s for %s because it is already open for %s"
+msgid "Can't open %s as a %s for %s because it is already open for %s."
 msgstr ""
 
-#: src/file-handle-def.c:244
+#: src/file-handle-def.c:318
 #, c-format
-msgid "Can't re-open %s as a %s for %s"
+msgid "Can't re-open %s as a %s for %s."
 msgstr ""
 
-#: src/file-handle.q:68
+#: src/file-handle.q:69
 #, c-format
 msgid ""
-"File handle %s already refers to file %s.  File handles cannot be redefined "
-"within a session."
+"File handle %s is already defined.  Use CLOSE FILE HANDLE before redefining "
+"a file handle."
 msgstr ""
 
-#: src/file-handle.q:89
-msgid "The FILE HANDLE required subcommand NAME is not present."
-msgstr ""
-
-#: src/file-handle.q:104
+#: src/file-handle.q:101
 #, c-format
 msgid ""
 "Fixed-length records were specified on /RECFORM, but record length was not "
 "specified on /LRECL.  Assuming %d-character records."
 msgstr ""
 
-#: src/file-handle.q:109
+#: src/file-handle.q:106
 #, c-format
 msgid ""
 "Record length (%ld) must be at least one byte.  Assuming %d-character "
 "records."
 msgstr ""
 
-#: src/file-handle.q:139
-msgid "expecting a file name or handle name"
+#: src/file-handle.q:152
+msgid "file"
 msgstr ""
 
-#: src/filename.c:227
-#, c-format
-msgid "Searching for `%s'..."
+#: src/file-handle.q:154
+msgid "inline file"
 msgstr ""
 
-#: src/filename.c:235 src/filename.c:267
-msgid "Search unsuccessful!"
+#: src/file-handle.q:156
+msgid "scratch file"
 msgstr ""
 
-#: src/filename.c:260
-#, c-format
-msgid "Found `%s'."
+#: src/file-handle.q:177
+msgid "expecting a file name or handle name"
 msgstr ""
 
-#: src/filename.c:665
+#: src/file-handle.q:204
 #, c-format
-msgid "Not opening pipe file `%s' because SAFER option set."
+msgid "Handle for %s not allowed here."
 msgstr ""
 
 #: src/file-type.c:133
@@ -1921,6 +1916,25 @@
 msgid "Unknown record type %g."
 msgstr ""
 
+#: src/filename.c:227
+#, c-format
+msgid "Searching for `%s'..."
+msgstr ""
+
+#: src/filename.c:235 src/filename.c:267
+msgid "Search unsuccessful!"
+msgstr ""
+
+#: src/filename.c:260
+#, c-format
+msgid "Found `%s'."
+msgstr ""
+
+#: src/filename.c:677
+#, c-format
+msgid "Not opening pipe file `%s' because SAFER option set."
+msgstr ""
+
 #: src/flip.c:88
 msgid ""
 "FLIP ignores TEMPORARY.  Temporary transformations will be made permanent."
@@ -1982,6 +1996,29 @@
 msgid "Unexpected end of file reading FLIP temporary file."
 msgstr ""
 
+#: src/format-prs.c:66
+msgid "X and T format specifiers not allowed here."
+msgstr ""
+
+#: src/format-prs.c:74
+#, c-format
+msgid "%.*s is not a valid data format."
+msgstr ""
+
+#: src/format-prs.c:115
+msgid "Format specifier expected."
+msgstr ""
+
+#: src/format-prs.c:127
+#, c-format
+msgid "Data format %s does not specify a width."
+msgstr ""
+
+#: src/format-prs.c:145
+#, c-format
+msgid "Data format %s is not valid."
+msgstr ""
+
 #: src/format.c:73
 #, c-format
 msgid "Format specifies a bad type (%d)"
@@ -2038,11 +2075,11 @@
 msgid "%s variables are not compatible with %s format %s."
 msgstr ""
 
-#: src/format.c:197 src/pfm-read.c:476 src/sfm-read.c:1012 src/sfm-read.c:1021
+#: src/format.c:197 src/pfm-read.c:476 src/sfm-read.c:1014 src/sfm-read.c:1023
 msgid "String"
 msgstr ""
 
-#: src/format.c:197 src/pfm-read.c:476 src/sfm-read.c:1012 src/sfm-read.c:1021
+#: src/format.c:197 src/pfm-read.c:476 src/sfm-read.c:1014 src/sfm-read.c:1023
 msgid "Numeric"
 msgstr ""
 
@@ -2051,29 +2088,6 @@
 msgid "String variable with width %d not compatible with format %s."
 msgstr ""
 
-#: src/format-prs.c:66
-msgid "X and T format specifiers not allowed here."
-msgstr ""
-
-#: src/format-prs.c:74
-#, c-format
-msgid "%.*s is not a valid data format."
-msgstr ""
-
-#: src/format-prs.c:115
-msgid "Format specifier expected."
-msgstr ""
-
-#: src/format-prs.c:127
-#, c-format
-msgid "Data format %s does not specify a width."
-msgstr ""
-
-#: src/format-prs.c:145
-#, c-format
-msgid "Data format %s is not valid."
-msgstr ""
-
 #: src/formats.c:89
 msgid "`(' expected after variable list"
 msgstr ""
@@ -2167,16 +2181,20 @@
 msgid "No valid data for variable %s; statistics not displayed."
 msgstr ""
 
-#: src/get.c:306 src/get.c:320 src/get.c:345
+#: src/get.c:108
+msgid "expecting COMM or TAPE"
+msgstr ""
+
+#: src/get.c:343 src/get.c:357 src/get.c:382
 #, c-format
 msgid "expecting %s or %s"
 msgstr ""
 
-#: src/get.c:552 src/print.c:179
+#: src/get.c:586 src/print.c:179
 msgid "expecting a valid subcommand"
 msgstr ""
 
-#: src/get.c:585
+#: src/get.c:619
 #, c-format
 msgid ""
 "Cannot rename %s as %s because there already exists a variable named %s.  To "
@@ -2184,85 +2202,81 @@
 "as \"/RENAME (A=B)(B=C)(C=A)\", or equivalently, \"/RENAME (A B C=B C A)\"."
 msgstr ""
 
-#: src/get.c:610
+#: src/get.c:644
 msgid "`=' expected after variable list."
 msgstr ""
 
-#: src/get.c:617
+#: src/get.c:651
 #, c-format
 msgid ""
 "Number of variables on left side of `=' (%d) does not match number of "
 "variables on right side (%d), in parenthesized group %d of RENAME subcommand."
 msgstr ""
 
-#: src/get.c:630
+#: src/get.c:664
 #, c-format
 msgid "Requested renaming duplicates variable name %s."
 msgstr ""
 
-#: src/get.c:660
+#: src/get.c:694
 msgid "Cannot DROP all variables from dictionary."
 msgstr ""
 
-#: src/get.c:835
+#: src/get.c:869
 msgid "The active file may not be specified more than once."
 msgstr ""
 
-#: src/get.c:844
+#: src/get.c:878
 msgid "Cannot specify the active file since no active file has been defined."
 msgstr ""
 
-#: src/get.c:852
+#: src/get.c:886
 msgid ""
 "MATCH FILES may not be used after TEMPORARY when the active file is an input "
 "source.  Temporary transformations will be made permanent."
 msgstr ""
 
-#: src/get.c:890
+#: src/get.c:924
 msgid "Multiple IN subcommands for a single FILE or TABLE."
 msgstr ""
 
-#: src/get.c:910
+#: src/get.c:944
 msgid "BY may appear at most once."
 msgstr ""
 
-#: src/get.c:930
+#: src/get.c:964
 #, c-format
 msgid "File %s lacks BY variable %s."
 msgstr ""
 
-#: src/get.c:944
+#: src/get.c:978
 msgid "FIRST may appear at most once."
 msgstr ""
 
-#: src/get.c:958
+#: src/get.c:992
 msgid "LAST may appear at most once."
 msgstr ""
 
-#: src/get.c:999
+#: src/get.c:1033
 msgid "BY is required when TABLE is specified."
 msgstr ""
 
-#: src/get.c:1004
+#: src/get.c:1038
 msgid "BY is required when IN is specified."
 msgstr ""
 
-#: src/get.c:1032
+#: src/get.c:1066
 #, c-format
 msgid "IN variable name %s duplicates an existing variable name."
 msgstr ""
 
-#: src/get.c:1461
+#: src/get.c:1495
 #, c-format
 msgid ""
 "Variable %s in file %s (%s) has different type or width from the same "
 "variable in earlier file (%s)."
 msgstr ""
 
-#: src/get.c:1545
-msgid "expecting COMM or TAPE"
-msgstr ""
-
 #: src/getl.c:139
 #, c-format
 msgid "Can't find `%s' in include file search path."
@@ -3269,34 +3283,34 @@
 msgid "Cannot change mode of %s: %s"
 msgstr ""
 
-#: src/pfm-read.c:87
+#: src/pfm-read.c:97
 #, c-format
 msgid "portable file %s corrupt at offset %ld: "
 msgstr ""
 
-#: src/pfm-read.c:114
+#: src/pfm-read.c:124
 msgid "unexpected end of file"
 msgstr ""
 
-#: src/pfm-read.c:172
+#: src/pfm-read.c:182
 #, c-format
 msgid ""
 "An error occurred while opening \"%s\" for reading as a portable file: %s."
 msgstr ""
 
-#: src/pfm-read.c:190
+#: src/pfm-read.c:200
 msgid "Data record expected."
 msgstr ""
 
-#: src/pfm-read.c:298
+#: src/pfm-read.c:308
 msgid "Missing numeric terminator."
 msgstr ""
 
-#: src/pfm-read.c:321
+#: src/pfm-read.c:331
 msgid "Invalid integer."
 msgstr ""
 
-#: src/pfm-read.c:332
+#: src/pfm-read.c:342
 #, c-format
 msgid "Bad string length %d."
 msgstr ""
@@ -3316,12 +3330,12 @@
 msgid "Bad time string length %d."
 msgstr ""
 
-#: src/pfm-read.c:468 src/sfm-read.c:1004
+#: src/pfm-read.c:468 src/sfm-read.c:1006
 #, c-format
 msgid "%s: Bad format specifier byte (%d)."
 msgstr ""
 
-#: src/pfm-read.c:475 src/sfm-read.c:1020
+#: src/pfm-read.c:475 src/sfm-read.c:1022
 #, c-format
 msgid "%s variable %s has invalid format specifier %s."
 msgstr ""
@@ -3397,7 +3411,7 @@
 msgid "%s: Writing portable file: %s."
 msgstr ""
 
-#: src/pfm-write.c:468
+#: src/pfm-write.c:466
 #, c-format
 msgid "%s: Closing portable file: %s."
 msgstr ""
@@ -3584,19 +3598,23 @@
 
 #: src/print.c:839
 #, c-format
-msgid "Writing %d record(s) to file %s."
-msgstr ""
+msgid "Writing %d record to %s."
+msgid_plural "Writing %d records to %s."
+msgstr[0] ""
+msgstr[1] ""
 
-#: src/print.c:842
+#: src/print.c:843
 #, c-format
-msgid "Writing %d record(s) to the listing file."
-msgstr ""
+msgid "Writing %d record."
+msgid_plural "Writing %d records."
+msgstr[0] ""
+msgstr[1] ""
 
-#: src/print.c:1082
+#: src/print.c:1084
 msgid "The expression on PRINT SPACE evaluated to the system-missing value."
 msgstr ""
 
-#: src/print.c:1085
+#: src/print.c:1087
 #, c-format
 msgid "The expression on PRINT SPACE evaluated to %g."
 msgstr ""
@@ -3806,6 +3824,13 @@
 msgid "Cannot sample %d observations from a population of %d."
 msgstr ""
 
+#: src/scratch-reader.c:59
+#, c-format
+msgid ""
+"Scratch file handle %s has not yet been written, using SAVE or another "
+"procedure, so it cannot yet be used for reading."
+msgstr ""
+
 #: src/sel-if.c:103
 msgid "The filter variable must be numeric."
 msgstr ""
@@ -3951,131 +3976,131 @@
 msgid "corrupt system file: "
 msgstr ""
 
-#: src/sfm-read.c:151 src/sfm-write.c:931
+#: src/sfm-read.c:149 src/sfm-write.c:929
 #, c-format
 msgid "%s: Closing system file: %s."
 msgstr ""
 
-#: src/sfm-read.c:237
+#: src/sfm-read.c:239
 #, c-format
 msgid ""
 "An error occurred while opening \"%s\" for reading as a system file: %s."
 msgstr ""
 
-#: src/sfm-read.c:255
+#: src/sfm-read.c:257
 #, c-format
 msgid ""
 "%s: Index of weighting variable (%d) is not between 0 and number of elements "
 "per case (%d)."
 msgstr ""
 
-#: src/sfm-read.c:264
+#: src/sfm-read.c:266
 #, c-format
 msgid ""
 "%s: Weighting variable may not be a continuation of a long string variable."
 msgstr ""
 
-#: src/sfm-read.c:267
+#: src/sfm-read.c:269
 #, c-format
 msgid "%s: Weighting variable may not be a string variable."
 msgstr ""
 
-#: src/sfm-read.c:292
+#: src/sfm-read.c:294
 #, c-format
 msgid ""
 "%s: Orphaned variable index record (type 4).  Type 4 records must always "
 "immediately follow type 3 records."
 msgstr ""
 
-#: src/sfm-read.c:350
+#: src/sfm-read.c:352
 #, c-format
 msgid "%s: Invalid subrecord length. Record: 7; Subrecord: 11"
 msgstr ""
 
-#: src/sfm-read.c:404
+#: src/sfm-read.c:406
 #, c-format
 msgid "%s: Trailing garbage in long variable name map."
 msgstr ""
 
-#: src/sfm-read.c:411
+#: src/sfm-read.c:413
 #, c-format
 msgid "%s: Long variable mapping to invalid variable name `%s'."
 msgstr ""
 
-#: src/sfm-read.c:421
+#: src/sfm-read.c:423
 #, c-format
 msgid "%s: Long variable mapping for nonexistent variable %s."
 msgstr ""
 
-#: src/sfm-read.c:431
+#: src/sfm-read.c:433
 #, c-format
 msgid "%s: Duplicate long variable name `%s' within system file."
 msgstr ""
 
-#: src/sfm-read.c:459
+#: src/sfm-read.c:461
 #, c-format
 msgid "%s: Unrecognized record type 7, subtype %d encountered in system file."
 msgstr ""
 
-#: src/sfm-read.c:484
+#: src/sfm-read.c:486
 #, c-format
 msgid "%s: Unrecognized record type %d."
 msgstr ""
 
-#: src/sfm-read.c:516
+#: src/sfm-read.c:518
 #, c-format
 msgid ""
 "%s: Bad size (%d) or count (%d) field on record type 7, subtype 3.\tExpected "
 "size %d, count 8."
 msgstr ""
 
-#: src/sfm-read.c:527
+#: src/sfm-read.c:529
 #, c-format
 msgid ""
 "%s: Floating-point representation in system file is not IEEE-754.  PSPP "
 "cannot convert between floating-point formats."
 msgstr ""
 
-#: src/sfm-read.c:543
+#: src/sfm-read.c:545
 #, c-format
 msgid ""
 "%s: File-indicated endianness (%s) does not match endianness intuited from "
 "file header (%s)."
 msgstr ""
 
-#: src/sfm-read.c:546 src/sfm-read.c:547
+#: src/sfm-read.c:548 src/sfm-read.c:549
 msgid "big-endian"
 msgstr ""
 
-#: src/sfm-read.c:546 src/sfm-read.c:547
+#: src/sfm-read.c:548 src/sfm-read.c:549
 msgid "little-endian"
 msgstr ""
 
-#: src/sfm-read.c:548
+#: src/sfm-read.c:550
 msgid "unknown"
 msgstr ""
 
-#: src/sfm-read.c:552
+#: src/sfm-read.c:554
 #, c-format
 msgid "%s: File-indicated character representation code (%s) is not ASCII."
 msgstr ""
 
-#: src/sfm-read.c:556
+#: src/sfm-read.c:558
 msgid "DEC Kanji"
 msgstr ""
 
-#: src/sfm-read.c:556 src/sysfile-info.c:119
+#: src/sfm-read.c:558 src/sysfile-info.c:119
 msgid "Unknown"
 msgstr ""
 
-#: src/sfm-read.c:572
+#: src/sfm-read.c:574
 #, c-format
 msgid ""
 "%s: Bad size (%d) or count (%d) field on record type 7, subtype 4.\tExpected "
 "size %d, count 8."
 msgstr ""
 
-#: src/sfm-read.c:587
+#: src/sfm-read.c:589
 #, c-format
 msgid ""
 "%s: File-indicated value is different from internal value for at least one "
@@ -4083,220 +4108,220 @@
 "%g; LOWEST: %g, %g."
 msgstr ""
 
-#: src/sfm-read.c:614
+#: src/sfm-read.c:616
 #, c-format
 msgid ""
 "%s: Bad magic.  Proper system files begin with the four characters `$FL2'. "
 "This file will not be read."
 msgstr ""
 
-#: src/sfm-read.c:656
+#: src/sfm-read.c:658
 #, c-format
 msgid ""
 "%s: File layout code has unexpected value %d.  Value should be 2, in big-"
 "endian or little-endian format."
 msgstr ""
 
-#: src/sfm-read.c:684
+#: src/sfm-read.c:686
 #, c-format
 msgid "%s: Number of cases in file (%ld) is not between -1 and %d."
 msgstr ""
 
-#: src/sfm-read.c:689
+#: src/sfm-read.c:691
 #, c-format
 msgid "%s: Compression bias (%g) is not the usual value of 100."
 msgstr ""
 
-#: src/sfm-read.c:812
+#: src/sfm-read.c:814
 #, c-format
 msgid ""
 "%s: position %d: String variable does not have proper number of continuation "
 "records."
 msgstr ""
 
-#: src/sfm-read.c:823
+#: src/sfm-read.c:825
 #, c-format
 msgid "%s: position %d: Superfluous long string continuation record."
 msgstr ""
 
-#: src/sfm-read.c:829
+#: src/sfm-read.c:831
 #, c-format
 msgid "%s: position %d: Bad variable type code %d."
 msgstr ""
 
-#: src/sfm-read.c:832
+#: src/sfm-read.c:834
 #, c-format
 msgid "%s: position %d: Variable label indicator field is not 0 or 1."
 msgstr ""
 
-#: src/sfm-read.c:836
+#: src/sfm-read.c:838
 #, c-format
 msgid ""
 "%s: position %d: Missing value indicator field is not -3, -2, 0, 1, 2, or 3."
 msgstr ""
 
-#: src/sfm-read.c:842
+#: src/sfm-read.c:844
 #, c-format
 msgid "%s: position %d: Variable name begins with invalid character."
 msgstr ""
 
-#: src/sfm-read.c:846
+#: src/sfm-read.c:848
 #, c-format
 msgid "%s: position %d: Variable name begins with lowercase letter %c."
 msgstr ""
 
-#: src/sfm-read.c:850
+#: src/sfm-read.c:852
 #, c-format
 msgid ""
 "%s: position %d: Variable name begins with octothorpe (`#').  Scratch "
 "variables should not appear in system files."
 msgstr ""
 
-#: src/sfm-read.c:865
+#: src/sfm-read.c:867
 #, c-format
 msgid "%s: position %d: Variable name character %d is lowercase letter %c."
 msgstr ""
 
-#: src/sfm-read.c:874
+#: src/sfm-read.c:876
 #, c-format
 msgid ""
 "%s: position %d: character `\\%03o' (%c) is not valid in a variable name."
 msgstr ""
 
-#: src/sfm-read.c:881
+#: src/sfm-read.c:883
 #, c-format
 msgid "%s: Invalid variable name `%s' within system file."
 msgstr ""
 
-#: src/sfm-read.c:888
+#: src/sfm-read.c:890
 #, c-format
 msgid "%s: Duplicate variable name `%s' within system file."
 msgstr ""
 
-#: src/sfm-read.c:911
+#: src/sfm-read.c:913
 #, c-format
 msgid "%s: Variable %s indicates variable label of invalid length %d."
 msgstr ""
 
-#: src/sfm-read.c:932
+#: src/sfm-read.c:934
 #, c-format
 msgid "%s: Long string variable %s may not have missing values."
 msgstr ""
 
-#: src/sfm-read.c:953
+#: src/sfm-read.c:955
 #, c-format
 msgid ""
 "%s: String variable %s may not have missing values specified as a range."
 msgstr ""
 
-#: src/sfm-read.c:980
+#: src/sfm-read.c:982
 #, c-format
 msgid "%s: Long string continuation records omitted at end of dictionary."
 msgstr ""
 
-#: src/sfm-read.c:985
+#: src/sfm-read.c:987
 #, c-format
 msgid ""
 "%s: System file header indicates %d variable positions but %d were read from "
 "file."
 msgstr ""
 
-#: src/sfm-read.c:1010
+#: src/sfm-read.c:1012
 #, c-format
 msgid "%s: %s variable %s has %s format specifier %s."
 msgstr ""
 
-#: src/sfm-read.c:1063
+#: src/sfm-read.c:1065
 #, c-format
 msgid "%s: Invalid number of labels: %d.  Ignoring labels."
 msgstr ""
 
-#: src/sfm-read.c:1105
+#: src/sfm-read.c:1107
 #, c-format
 msgid ""
 "%s: Variable index record (type 4) does not immediately follow value label "
 "record (type 3) as it should."
 msgstr ""
 
-#: src/sfm-read.c:1116
+#: src/sfm-read.c:1118
 #, c-format
 msgid ""
 "%s: Number of variables associated with a value label (%d) is not between 1 "
 "and the number of variables (%d)."
 msgstr ""
 
-#: src/sfm-read.c:1132
+#: src/sfm-read.c:1134
 #, c-format
 msgid ""
 "%s: Variable index associated with value label (%d) is not between 1 and the "
 "number of values (%d)."
 msgstr ""
 
-#: src/sfm-read.c:1139
+#: src/sfm-read.c:1141
 #, c-format
 msgid ""
 "%s: Variable index associated with value label (%d) refers to a continuation "
 "of a string variable, not to an actual variable."
 msgstr ""
 
-#: src/sfm-read.c:1144
+#: src/sfm-read.c:1146
 #, c-format
 msgid "%s: Value labels are not allowed on long string variables (%s)."
 msgstr ""
 
-#: src/sfm-read.c:1155
+#: src/sfm-read.c:1157
 #, c-format
 msgid ""
 "%s: Variables associated with value label are not all of identical type.  "
 "Variable %s has %s type, but variable %s has %s type."
 msgstr ""
 
-#: src/sfm-read.c:1196
+#: src/sfm-read.c:1198
 #, c-format
 msgid "%s: File contains duplicate label for value %g for variable %s."
 msgstr ""
 
-#: src/sfm-read.c:1200
+#: src/sfm-read.c:1202
 #, c-format
 msgid "%s: File contains duplicate label for value `%.*s' for variable %s."
 msgstr ""
 
-#: src/sfm-read.c:1242 src/sfm-read.c:1519
+#: src/sfm-read.c:1244 src/sfm-read.c:1521
 #, c-format
 msgid "%s: Reading system file: %s."
 msgstr ""
 
-#: src/sfm-read.c:1245 src/sfm-read.c:1360 src/sfm-read.c:1402
+#: src/sfm-read.c:1247 src/sfm-read.c:1362 src/sfm-read.c:1404
 #, c-format
 msgid "%s: Unexpected end of file."
 msgstr ""
 
-#: src/sfm-read.c:1260
+#: src/sfm-read.c:1262
 #, c-format
 msgid "%s: Seeking system file: %s."
 msgstr ""
 
-#: src/sfm-read.c:1275
+#: src/sfm-read.c:1277
 #, c-format
 msgid "%s: System file contains multiple type 6 (document) records."
 msgstr ""
 
-#: src/sfm-read.c:1281
+#: src/sfm-read.c:1283
 #, c-format
 msgid "%s: Number of document lines (%ld) must be greater than 0."
 msgstr ""
 
-#: src/sfm-read.c:1313
+#: src/sfm-read.c:1315
 #, c-format
 msgid "%s: Error reading file: %s."
 msgstr ""
 
-#: src/sfm-read.c:1350
+#: src/sfm-read.c:1352
 #, c-format
 msgid "%s: Compressed data is corrupted.  Data ends in partial case."
 msgstr ""
 
-#: src/sfm-read.c:1522
+#: src/sfm-read.c:1524
 #, c-format
 msgid "%s: Partial record at end of system file."
 msgstr ""
@@ -4316,6 +4341,14 @@
 msgid "%s: Writing system file: %s."
 msgstr ""
 
+#: src/sort-prs.c:94
+msgid "`A' or `D' expected inside parentheses."
+msgstr ""
+
+#: src/sort-prs.c:99
+msgid "`)' expected."
+msgstr ""
+
 #: src/sort.c:85
 msgid "Buffer limit must be at least 2."
 msgstr ""
@@ -4327,14 +4360,6 @@
 "each.  (PSPP workspace is currently restricted to a maximum of %d KB.)"
 msgstr ""
 
-#: src/sort-prs.c:94
-msgid "`A' or `D' expected inside parentheses."
-msgstr ""
-
-#: src/sort-prs.c:99
-msgid "`)' expected."
-msgstr ""
-
 #: src/sysfile-info.c:100
 msgid "File:"
 msgstr ""
@@ -4436,7 +4461,7 @@
 msgid "Documents in the active file:"
 msgstr ""
 
-#: src/sysfile-info.c:380 src/sysfile-info.c:519 src/vfm.c:841
+#: src/sysfile-info.c:380 src/sysfile-info.c:519 src/vfm.c:846
 msgid "Label"
 msgstr ""
 
@@ -4467,51 +4492,6 @@
 msgid "Vector"
 msgstr ""
 
-#: src/tab.c:258
-#, c-format
-msgid "bad vline: x=%d+%d=%d y=(%d+%d=%d,%d+%d=%d) in table size (%d,%d)\n"
-msgstr ""
-
-#: src/tab.c:333
-#, c-format
-msgid ""
-"bad box: (%d+%d=%d,%d+%d=%d)-(%d+%d=%d,%d+%d=%d) in table size (%d,%d)\n"
-msgstr ""
-
-#: src/temporary.c:49
-msgid "This command is not valid inside DO IF or LOOP."
-msgstr ""
-
-#: src/temporary.c:56
-msgid ""
-"This command may only appear once between procedures and procedure-like "
-"commands."
-msgstr ""
-
-#: src/title.c:60
-#, c-format
-msgid "%s before: %s\n"
-msgstr ""
-
-#: src/title.c:60
-msgid "<none>"
-msgstr ""
-
-#: src/title.c:72
-#, c-format
-msgid "%s: `.' expected after string."
-msgstr ""
-
-#: src/title.c:88
-#, c-format
-msgid "%s after: %s\n"
-msgstr ""
-
-#: src/title.c:143
-#, c-format
-msgid "Document entered %s by %s:"
-msgstr ""
-
 #: src/t-test.q:270
 msgid "TESTVAL, GROUPS and PAIRS subcommands are mutually exclusive."
 msgstr ""
@@ -4637,6 +4617,51 @@
 msgid "%s & %s"
 msgstr ""
 
+#: src/tab.c:258
+#, c-format
+msgid "bad vline: x=%d+%d=%d y=(%d+%d=%d,%d+%d=%d) in table size (%d,%d)\n"
+msgstr ""
+
+#: src/tab.c:333
+#, c-format
+msgid ""
+"bad box: (%d+%d=%d,%d+%d=%d)-(%d+%d=%d,%d+%d=%d) in table size (%d,%d)\n"
+msgstr ""
+
+#: src/temporary.c:49
+msgid "This command is not valid inside DO IF or LOOP."
+msgstr ""
+
+#: src/temporary.c:56
+msgid ""
+"This command may only appear once between procedures and procedure-like "
+"commands."
+msgstr ""
+
+#: src/title.c:60
+#, c-format
+msgid "%s before: %s\n"
+msgstr ""
+
+#: src/title.c:60
+msgid "<none>"
+msgstr ""
+
+#: src/title.c:72
+#, c-format
+msgid "%s: `.' expected after string."
+msgstr ""
+
+#: src/title.c:88
+#, c-format
+msgid "%s after: %s\n"
+msgstr ""
+
+#: src/title.c:143
+#, c-format
+msgid "Document entered %s by %s:"
+msgstr ""
+
 #: src/val-labs.c:121
 #, c-format
 msgid ""
Index: pspp/po/pspp.pot
diff -u pspp/po/pspp.pot:1.69 pspp/po/pspp.pot:1.70
--- pspp/po/pspp.pot:1.69       Tue Jan 24 09:58:18 2006
+++ pspp/po/pspp.pot    Sun Jan 29 02:41:11 2006
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: address@hidden"
-"POT-Creation-Date: 2006-01-24 17:40+0800\n"
+"POT-Creation-Date: 2006-01-28 17:20-0800\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <address@hidden>\n"
 "Language-Team: LANGUAGE <address@hidden>\n"
@@ -17,15 +17,15 @@
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
 
-#: src/aggregate.c:199
+#: src/aggregate.c:200
 msgid "while expecting COLUMNWISE"
 msgstr ""
 
-#: src/aggregate.c:228
+#: src/aggregate.c:229
 msgid "expecting BREAK"
 msgstr ""
 
-#: src/aggregate.c:233
+#: src/aggregate.c:234
 msgid ""
 "When PRESORTED is specified, specifying sorting directions with (A) or (D) "
 "has no effect.  Output data will be sorted the same way as the input data."
@@ -79,20 +79,34 @@
 "contains the aggregate variables and the break variables."
 msgstr ""
 
+#: src/any-reader.c:74
+#, c-format
+msgid "An error occurred while opening \"%s\": %s."
+msgstr ""
+
+#: src/any-reader.c:129
+#, c-format
+msgid "\"%s\" is not a system or portable file."
+msgstr ""
+
+#: src/any-reader.c:135 src/any-writer.c:80
+msgid "The inline file is not allowed here."
+msgstr ""
+
 #: src/apply-dict.c:71
 #, c-format
 msgid "Variable %s is %s in target file, but %s in source file."
 msgstr ""
 
 #: src/apply-dict.c:74 src/apply-dict.c:75 src/format.c:198 src/recode.c:464
-#: src/recode.c:465 src/sfm-read.c:1014 src/sfm-read.c:1159
-#: src/sfm-read.c:1160 src/vars-atr.c:40 src/vars-atr.c:48
+#: src/recode.c:465 src/sfm-read.c:1016 src/sfm-read.c:1161
+#: src/sfm-read.c:1162 src/vars-atr.c:40 src/vars-atr.c:48
 msgid "string"
 msgstr ""
 
 #: src/apply-dict.c:74 src/apply-dict.c:75 src/format.c:198 src/recode.c:464
-#: src/recode.c:465 src/sfm-read.c:1014 src/sfm-read.c:1159
-#: src/sfm-read.c:1160 src/vars-atr.c:40
+#: src/recode.c:465 src/sfm-read.c:1016 src/sfm-read.c:1161
+#: src/sfm-read.c:1162 src/vars-atr.c:40
 msgid "numeric"
 msgstr ""
 
@@ -235,8 +249,8 @@
 msgid "Source variable count (%u) does not match target variable count (%u)."
 msgstr ""
 
-#: src/autorecode.c:142 src/command.c:797 src/file-handle.q:83 src/lexer.c:440
-#: src/matrix-data.c:532 src/print.c:335 src/print.c:1044 src/sel-if.c:57
+#: src/autorecode.c:142 src/command.c:797 src/lexer.c:440
+#: src/matrix-data.c:532 src/print.c:335 src/print.c:1046 src/sel-if.c:57
 #: src/sel-if.c:134 src/vector.c:197
 msgid "expecting end of command"
 msgstr ""
@@ -561,7 +575,7 @@
 
 #: src/crosstabs.q:1109 src/crosstabs.q:1136 src/crosstabs.q:1156
 #: src/crosstabs.q:1178 src/examine.q:1131 src/frequencies.q:1142
-#: src/frequencies.q:1263 src/sysfile-info.c:518 src/vfm.c:840
+#: src/frequencies.q:1263 src/sysfile-info.c:518 src/vfm.c:845
 msgid "Value"
 msgstr ""
 
@@ -935,288 +949,275 @@
 msgid "Field too long (%d characters).  Truncated after character %d."
 msgstr ""
 
-#: src/data-list.c:142
-msgid ""
-"DATA LIST may not use a different file from that specified on its "
-"surrounding FILE TYPE."
+#: src/data-list.c:144
+msgid "DATA LIST must use the same file as the enclosing FILE TYPE."
 msgstr ""
 
-#: src/data-list.c:161
+#: src/data-list.c:163
 msgid "The END subcommand may only be specified once."
 msgstr ""
 
-#: src/data-list.c:196
+#: src/data-list.c:198
 msgid "Only one of FIXED, FREE, or LIST may be specified."
 msgstr ""
 
-#: src/data-list.c:346 src/print.c:296
+#: src/data-list.c:348 src/print.c:296
 #, c-format
 msgid ""
 "The record number specified, %ld, is before the previous record, %d.  Data "
 "fields must be listed in order of increasing record number."
 msgstr ""
 
-#: src/data-list.c:375 src/data-list.c:1735
+#: src/data-list.c:377 src/data-list.c:1727
 msgid ""
 "SPSS-like or FORTRAN-like format specification expected after variable names."
 msgstr ""
 
-#: src/data-list.c:386
+#: src/data-list.c:388
 msgid "At least one variable must be specified."
 msgstr ""
 
-#: src/data-list.c:391 src/print.c:328
+#: src/data-list.c:393 src/print.c:328
 msgid ""
 "Variables are specified on records that should not exist according to "
 "RECORDS subcommand."
 msgstr ""
 
-#: src/data-list.c:424 src/data-list.c:438 src/print.c:520 src/print.c:533
+#: src/data-list.c:426 src/data-list.c:440 src/print.c:520 src/print.c:533
 msgid "Column positions for fields must be positive."
 msgstr ""
 
-#: src/data-list.c:443
+#: src/data-list.c:445
 msgid "The ending column for a field must be greater than the starting column."
 msgstr ""
 
-#: src/data-list.c:457
+#: src/data-list.c:459
 #, c-format
 msgid "The %d columns %d-%d can't be evenly divided into %d fields."
 msgstr ""
 
-#: src/data-list.c:477 src/print.c:561
+#: src/data-list.c:479 src/print.c:561
 msgid "A format specifier on this line has extra characters on the end."
 msgstr ""
 
-#: src/data-list.c:492 src/print.c:577
+#: src/data-list.c:494 src/print.c:577
 msgid "The value for number of decimal places must be at least 1."
 msgstr ""
 
-#: src/data-list.c:506 src/print.c:590
+#: src/data-list.c:508 src/print.c:590
 #, c-format
 msgid "Input format %s doesn't accept decimal places."
 msgstr ""
 
-#: src/data-list.c:553 src/data-list.c:649 src/data-list.c:863
+#: src/data-list.c:555 src/data-list.c:651 src/data-list.c:859
 #, c-format
 msgid "%s is a duplicate variable name."
 msgstr ""
 
-#: src/data-list.c:558
+#: src/data-list.c:560
 #, c-format
 msgid "There is already a variable %s of a different type."
 msgstr ""
 
-#: src/data-list.c:565
+#: src/data-list.c:567
 #, c-format
 msgid "There is already a string variable %s of a different width."
 msgstr ""
 
-#: src/data-list.c:640
+#: src/data-list.c:642
 msgid ""
 "The number of format specifications exceeds the given number of variable "
 "names."
 msgstr ""
 
-#: src/data-list.c:753 src/print.c:766
+#: src/data-list.c:755 src/print.c:766
 msgid ""
 "There aren't enough format specifications to match the number of variable "
 "names given."
 msgstr ""
 
-#: src/data-list.c:780 src/data-list.c:904 src/descript.c:882 src/print.c:797
-#: src/sysfile-info.c:139 src/sysfile-info.c:373 src/vfm.c:839
+#: src/data-list.c:782 src/data-list.c:900 src/descript.c:882 src/print.c:797
+#: src/sysfile-info.c:139 src/sysfile-info.c:373 src/vfm.c:844
 msgid "Variable"
 msgstr ""
 
-#: src/data-list.c:781 src/print.c:798
+#: src/data-list.c:783 src/print.c:798
 msgid "Record"
 msgstr ""
 
-#: src/data-list.c:782 src/print.c:799
+#: src/data-list.c:784 src/print.c:799
 msgid "Columns"
 msgstr ""
 
-#: src/data-list.c:783 src/data-list.c:905 src/print.c:800
+#: src/data-list.c:785 src/data-list.c:901 src/print.c:800
 msgid "Format"
 msgstr ""
 
-#: src/data-list.c:799
+#: src/data-list.c:800
 #, c-format
-msgid "Reading %d record from file %s."
-msgid_plural "Reading %d records from file %s."
+msgid "Reading %d record from %s."
+msgid_plural "Reading %d records from %s."
 msgstr[0] ""
 msgstr[1] ""
 
-#: src/data-list.c:803
+#: src/data-list.c:916
 #, c-format
-msgid "Reading %d record from the command file."
-msgid_plural "Reading %d records from the command file."
-msgstr[0] ""
-msgstr[1] ""
-
-#: src/data-list.c:921
-#, c-format
-msgid "Reading free-form data from file %s."
-msgstr ""
-
-#: src/data-list.c:924
-msgid "Reading free-form data from the command file."
+msgid "Reading free-form data from %s."
 msgstr ""
 
-#: src/data-list.c:975
+#: src/data-list.c:967
 #, c-format
 msgid "Quoted string missing terminating `%c'."
 msgstr ""
 
-#: src/data-list.c:1084
+#: src/data-list.c:1076
 #, c-format
 msgid "Partial case of %d of %d records discarded."
 msgstr ""
 
-#: src/data-list.c:1138
+#: src/data-list.c:1130
 #, c-format
 msgid "Partial case discarded.  The first variable missing was %s."
 msgstr ""
 
-#: src/data-list.c:1182
+#: src/data-list.c:1174
 #, c-format
 msgid ""
 "Missing value(s) for all variables from %s onward.  These will be filled "
 "with the system-missing value or blanks, as appropriate."
 msgstr ""
 
-#: src/data-list.c:1259
+#: src/data-list.c:1251
 msgid "Attempt to read past end of file."
 msgstr ""
 
-#: src/data-list.c:1398
+#: src/data-list.c:1390
 msgid ""
 "REPEATING DATA must use the same file as its corresponding DATA LIST or FILE "
 "TYPE."
 msgstr ""
 
-#: src/data-list.c:1408 src/data-list.c:1442 src/data-list.c:1455
-#: src/data-list.c:1468 src/data-list.c:1502
+#: src/data-list.c:1400 src/data-list.c:1434 src/data-list.c:1447
+#: src/data-list.c:1460 src/data-list.c:1494
 #, c-format
 msgid "%s subcommand given multiple times."
 msgstr ""
 
-#: src/data-list.c:1431
+#: src/data-list.c:1423
 #, c-format
 msgid "STARTS beginning column (%d) exceeds STARTS ending column (%d)."
 msgstr ""
 
-#: src/data-list.c:1488
+#: src/data-list.c:1480
 #, c-format
 msgid "CONTINUED beginning column (%d) exceeds CONTINUED ending column (%d)."
 msgstr ""
 
-#: src/data-list.c:1511
+#: src/data-list.c:1503
 #, c-format
 msgid "ID beginning column (%ld) must be positive."
 msgstr ""
 
-#: src/data-list.c:1526
+#: src/data-list.c:1518
 #, c-format
 msgid "ID ending column (%ld) must be positive."
 msgstr ""
 
-#: src/data-list.c:1532
+#: src/data-list.c:1524
 #, c-format
 msgid "ID ending column (%ld) cannot be less than ID beginning column (%d)."
 msgstr ""
 
-#: src/data-list.c:1572
+#: src/data-list.c:1564
 msgid "Missing required specification STARTS."
 msgstr ""
 
-#: src/data-list.c:1574
+#: src/data-list.c:1566
 msgid "Missing required specification OCCURS."
 msgstr ""
 
-#: src/data-list.c:1581
+#: src/data-list.c:1573
 msgid "ID specified without CONTINUED."
 msgstr ""
 
-#: src/data-list.c:1592
+#: src/data-list.c:1584
 #, c-format
 msgid ""
 "STARTS beginning column (%d) exceeds default STARTS ending column taken from "
 "file's record width (%d)."
 msgstr ""
 
-#: src/data-list.c:1605
+#: src/data-list.c:1597
 #, c-format
 msgid ""
 "CONTINUED beginning column (%d) exceeds default CONTINUED ending column "
 "taken from file's record width (%d)."
 msgstr ""
 
-#: src/data-list.c:1684
+#: src/data-list.c:1676
 msgid "String variable not allowed here."
 msgstr ""
 
-#: src/data-list.c:1694
+#: src/data-list.c:1686
 #, c-format
 msgid "%s (%d) must be at least 1."
 msgstr ""
 
-#: src/data-list.c:1700
+#: src/data-list.c:1692
 #, c-format
 msgid "Variable or integer expected for %s."
 msgstr ""
 
-#: src/data-list.c:1825
+#: src/data-list.c:1817
 #, c-format
 msgid "Encountered mismatched record ID \"%s\" expecting \"%s\"."
 msgstr ""
 
-#: src/data-list.c:1857
+#: src/data-list.c:1849
 #, c-format
 msgid ""
 "Variable %s starting in column %d extends beyond physical record length of %"
 "d."
 msgstr ""
 
-#: src/data-list.c:1924
+#: src/data-list.c:1916
 #, c-format
 msgid "Invalid value %d for OCCURS."
 msgstr ""
 
-#: src/data-list.c:1930
+#: src/data-list.c:1922
 #, c-format
 msgid "Beginning column for STARTS (%d) must be at least 1."
 msgstr ""
 
-#: src/data-list.c:1938
+#: src/data-list.c:1930
 #, c-format
 msgid "Ending column for STARTS (%d) is less than beginning column (%d)."
 msgstr ""
 
-#: src/data-list.c:1946
+#: src/data-list.c:1938
 #, c-format
 msgid "Invalid value %d for LENGTH."
 msgstr ""
 
-#: src/data-list.c:1953
+#: src/data-list.c:1945
 #, c-format
 msgid "Beginning column for CONTINUED (%d) must be at least 1."
 msgstr ""
 
-#: src/data-list.c:1961
+#: src/data-list.c:1953
 #, c-format
 msgid "Ending column for CONTINUED (%d) is less than beginning column (%d)."
 msgstr ""
 
-#: src/data-list.c:1993
+#: src/data-list.c:1985
 #, c-format
 msgid ""
 "Number of repetitions specified on OCCURS (%d) exceed number of repetitions "
 "available in space on STARTS (%d), and CONTINUED not specified."
 msgstr ""
 
-#: src/data-list.c:2011
+#: src/data-list.c:2003
 #, c-format
 msgid "Unexpected end of file with %d repetitions remaining out of %d."
 msgstr ""
@@ -1368,42 +1369,42 @@
 msgid "Valid cases = %g; cases with missing value(s) = %g."
 msgstr ""
 
-#: src/dfm-read.c:158
+#: src/dfm-read.c:136
 #, c-format
 msgid "Could not open \"%s\" for reading as a data file: %s."
 msgstr ""
 
-#: src/dfm-read.c:191 src/dfm-read.c:209
+#: src/dfm-read.c:168 src/dfm-read.c:186
 msgid "BEGIN DATA expected."
 msgstr ""
 
-#: src/dfm-read.c:218
+#: src/dfm-read.c:195
 msgid ""
 "Unexpected end-of-file while reading data in BEGIN DATA.  This probably "
 "indicates a missing or misformatted END DATA command.  END DATA must appear "
 "by itself on a single line with exactly one space between words."
 msgstr ""
 
-#: src/dfm-read.c:251 src/dfm-read.c:271
+#: src/dfm-read.c:227 src/dfm-read.c:247
 #, c-format
 msgid "Error reading file %s: %s."
 msgstr ""
 
-#: src/dfm-read.c:274
+#: src/dfm-read.c:250
 #, c-format
 msgid "%s: Partial record at end of file."
 msgstr ""
 
-#: src/dfm-read.c:317
+#: src/dfm-read.c:299
 #, c-format
 msgid "Attempt to read beyond end-of-file on file %s."
 msgstr ""
 
-#: src/dfm-read.c:320
+#: src/dfm-read.c:302
 msgid "Attempt to read beyond END DATA."
 msgstr ""
 
-#: src/dfm-read.c:467
+#: src/dfm-read.c:446
 msgid ""
 "This command is not valid here since the current input program does not "
 "access the inline file."
@@ -1721,67 +1722,61 @@
 msgid "%s is a PSPP extension."
 msgstr ""
 
-#: src/file-handle-def.c:229
+#: src/file-handle-def.c:303
 #, c-format
-msgid "Can't open %s as a %s because it is already open as a %s"
+msgid "Can't open %s as a %s because it is already open as a %s."
 msgstr ""
 
-#: src/file-handle-def.c:236
+#: src/file-handle-def.c:310
 #, c-format
-msgid "Can't open %s as a %s for %s because it is already open for %s"
+msgid "Can't open %s as a %s for %s because it is already open for %s."
 msgstr ""
 
-#: src/file-handle-def.c:244
+#: src/file-handle-def.c:318
 #, c-format
-msgid "Can't re-open %s as a %s for %s"
+msgid "Can't re-open %s as a %s for %s."
 msgstr ""
 
-#: src/file-handle.q:68
+#: src/file-handle.q:69
 #, c-format
 msgid ""
-"File handle %s already refers to file %s.  File handles cannot be redefined "
-"within a session."
+"File handle %s is already defined.  Use CLOSE FILE HANDLE before redefining "
+"a file handle."
 msgstr ""
 
-#: src/file-handle.q:89
-msgid "The FILE HANDLE required subcommand NAME is not present."
-msgstr ""
-
-#: src/file-handle.q:104
+#: src/file-handle.q:101
 #, c-format
 msgid ""
 "Fixed-length records were specified on /RECFORM, but record length was not "
 "specified on /LRECL.  Assuming %d-character records."
 msgstr ""
 
-#: src/file-handle.q:109
+#: src/file-handle.q:106
 #, c-format
 msgid ""
 "Record length (%ld) must be at least one byte.  Assuming %d-character "
 "records."
 msgstr ""
 
-#: src/file-handle.q:139
-msgid "expecting a file name or handle name"
+#: src/file-handle.q:152
+msgid "file"
 msgstr ""
 
-#: src/filename.c:227
-#, c-format
-msgid "Searching for `%s'..."
+#: src/file-handle.q:154
+msgid "inline file"
 msgstr ""
 
-#: src/filename.c:235 src/filename.c:267
-msgid "Search unsuccessful!"
+#: src/file-handle.q:156
+msgid "scratch file"
 msgstr ""
 
-#: src/filename.c:260
-#, c-format
-msgid "Found `%s'."
+#: src/file-handle.q:177
+msgid "expecting a file name or handle name"
 msgstr ""
 
-#: src/filename.c:665
+#: src/file-handle.q:204
 #, c-format
-msgid "Not opening pipe file `%s' because SAFER option set."
+msgid "Handle for %s not allowed here."
 msgstr ""
 
 #: src/file-type.c:133
@@ -1922,6 +1917,25 @@
 msgid "Unknown record type %g."
 msgstr ""
 
+#: src/filename.c:227
+#, c-format
+msgid "Searching for `%s'..."
+msgstr ""
+
+#: src/filename.c:235 src/filename.c:267
+msgid "Search unsuccessful!"
+msgstr ""
+
+#: src/filename.c:260
+#, c-format
+msgid "Found `%s'."
+msgstr ""
+
+#: src/filename.c:677
+#, c-format
+msgid "Not opening pipe file `%s' because SAFER option set."
+msgstr ""
+
 #: src/flip.c:88
 msgid ""
 "FLIP ignores TEMPORARY.  Temporary transformations will be made permanent."
@@ -1983,6 +1997,29 @@
 msgid "Unexpected end of file reading FLIP temporary file."
 msgstr ""
 
+#: src/format-prs.c:66
+msgid "X and T format specifiers not allowed here."
+msgstr ""
+
+#: src/format-prs.c:74
+#, c-format
+msgid "%.*s is not a valid data format."
+msgstr ""
+
+#: src/format-prs.c:115
+msgid "Format specifier expected."
+msgstr ""
+
+#: src/format-prs.c:127
+#, c-format
+msgid "Data format %s does not specify a width."
+msgstr ""
+
+#: src/format-prs.c:145
+#, c-format
+msgid "Data format %s is not valid."
+msgstr ""
+
 #: src/format.c:73
 #, c-format
 msgid "Format specifies a bad type (%d)"
@@ -2039,11 +2076,11 @@
 msgid "%s variables are not compatible with %s format %s."
 msgstr ""
 
-#: src/format.c:197 src/pfm-read.c:476 src/sfm-read.c:1012 src/sfm-read.c:1021
+#: src/format.c:197 src/pfm-read.c:476 src/sfm-read.c:1014 src/sfm-read.c:1023
 msgid "String"
 msgstr ""
 
-#: src/format.c:197 src/pfm-read.c:476 src/sfm-read.c:1012 src/sfm-read.c:1021
+#: src/format.c:197 src/pfm-read.c:476 src/sfm-read.c:1014 src/sfm-read.c:1023
 msgid "Numeric"
 msgstr ""
 
@@ -2052,29 +2089,6 @@
 msgid "String variable with width %d not compatible with format %s."
 msgstr ""
 
-#: src/format-prs.c:66
-msgid "X and T format specifiers not allowed here."
-msgstr ""
-
-#: src/format-prs.c:74
-#, c-format
-msgid "%.*s is not a valid data format."
-msgstr ""
-
-#: src/format-prs.c:115
-msgid "Format specifier expected."
-msgstr ""
-
-#: src/format-prs.c:127
-#, c-format
-msgid "Data format %s does not specify a width."
-msgstr ""
-
-#: src/format-prs.c:145
-#, c-format
-msgid "Data format %s is not valid."
-msgstr ""
-
 #: src/formats.c:89
 msgid "`(' expected after variable list"
 msgstr ""
@@ -2168,16 +2182,20 @@
 msgid "No valid data for variable %s; statistics not displayed."
 msgstr ""
 
-#: src/get.c:306 src/get.c:320 src/get.c:345
+#: src/get.c:108
+msgid "expecting COMM or TAPE"
+msgstr ""
+
+#: src/get.c:343 src/get.c:357 src/get.c:382
 #, c-format
 msgid "expecting %s or %s"
 msgstr ""
 
-#: src/get.c:552 src/print.c:179
+#: src/get.c:586 src/print.c:179
 msgid "expecting a valid subcommand"
 msgstr ""
 
-#: src/get.c:585
+#: src/get.c:619
 #, c-format
 msgid ""
 "Cannot rename %s as %s because there already exists a variable named %s.  To "
@@ -2185,85 +2203,81 @@
 "as \"/RENAME (A=B)(B=C)(C=A)\", or equivalently, \"/RENAME (A B C=B C A)\"."
 msgstr ""
 
-#: src/get.c:610
+#: src/get.c:644
 msgid "`=' expected after variable list."
 msgstr ""
 
-#: src/get.c:617
+#: src/get.c:651
 #, c-format
 msgid ""
 "Number of variables on left side of `=' (%d) does not match number of "
 "variables on right side (%d), in parenthesized group %d of RENAME subcommand."
 msgstr ""
 
-#: src/get.c:630
+#: src/get.c:664
 #, c-format
 msgid "Requested renaming duplicates variable name %s."
 msgstr ""
 
-#: src/get.c:660
+#: src/get.c:694
 msgid "Cannot DROP all variables from dictionary."
 msgstr ""
 
-#: src/get.c:835
+#: src/get.c:869
 msgid "The active file may not be specified more than once."
 msgstr ""
 
-#: src/get.c:844
+#: src/get.c:878
 msgid "Cannot specify the active file since no active file has been defined."
 msgstr ""
 
-#: src/get.c:852
+#: src/get.c:886
 msgid ""
 "MATCH FILES may not be used after TEMPORARY when the active file is an input "
 "source.  Temporary transformations will be made permanent."
 msgstr ""
 
-#: src/get.c:890
+#: src/get.c:924
 msgid "Multiple IN subcommands for a single FILE or TABLE."
 msgstr ""
 
-#: src/get.c:910
+#: src/get.c:944
 msgid "BY may appear at most once."
 msgstr ""
 
-#: src/get.c:930
+#: src/get.c:964
 #, c-format
 msgid "File %s lacks BY variable %s."
 msgstr ""
 
-#: src/get.c:944
+#: src/get.c:978
 msgid "FIRST may appear at most once."
 msgstr ""
 
-#: src/get.c:958
+#: src/get.c:992
 msgid "LAST may appear at most once."
 msgstr ""
 
-#: src/get.c:999
+#: src/get.c:1033
 msgid "BY is required when TABLE is specified."
 msgstr ""
 
-#: src/get.c:1004
+#: src/get.c:1038
 msgid "BY is required when IN is specified."
 msgstr ""
 
-#: src/get.c:1032
+#: src/get.c:1066
 #, c-format
 msgid "IN variable name %s duplicates an existing variable name."
 msgstr ""
 
-#: src/get.c:1461
+#: src/get.c:1495
 #, c-format
 msgid ""
 "Variable %s in file %s (%s) has different type or width from the same "
 "variable in earlier file (%s)."
 msgstr ""
 
-#: src/get.c:1545
-msgid "expecting COMM or TAPE"
-msgstr ""
-
 #: src/getl.c:139
 #, c-format
 msgid "Can't find `%s' in include file search path."
@@ -3270,34 +3284,34 @@
 msgid "Cannot change mode of %s: %s"
 msgstr ""
 
-#: src/pfm-read.c:87
+#: src/pfm-read.c:97
 #, c-format
 msgid "portable file %s corrupt at offset %ld: "
 msgstr ""
 
-#: src/pfm-read.c:114
+#: src/pfm-read.c:124
 msgid "unexpected end of file"
 msgstr ""
 
-#: src/pfm-read.c:172
+#: src/pfm-read.c:182
 #, c-format
 msgid ""
 "An error occurred while opening \"%s\" for reading as a portable file: %s."
 msgstr ""
 
-#: src/pfm-read.c:190
+#: src/pfm-read.c:200
 msgid "Data record expected."
 msgstr ""
 
-#: src/pfm-read.c:298
+#: src/pfm-read.c:308
 msgid "Missing numeric terminator."
 msgstr ""
 
-#: src/pfm-read.c:321
+#: src/pfm-read.c:331
 msgid "Invalid integer."
 msgstr ""
 
-#: src/pfm-read.c:332
+#: src/pfm-read.c:342
 #, c-format
 msgid "Bad string length %d."
 msgstr ""
@@ -3317,12 +3331,12 @@
 msgid "Bad time string length %d."
 msgstr ""
 
-#: src/pfm-read.c:468 src/sfm-read.c:1004
+#: src/pfm-read.c:468 src/sfm-read.c:1006
 #, c-format
 msgid "%s: Bad format specifier byte (%d)."
 msgstr ""
 
-#: src/pfm-read.c:475 src/sfm-read.c:1020
+#: src/pfm-read.c:475 src/sfm-read.c:1022
 #, c-format
 msgid "%s variable %s has invalid format specifier %s."
 msgstr ""
@@ -3398,7 +3412,7 @@
 msgid "%s: Writing portable file: %s."
 msgstr ""
 
-#: src/pfm-write.c:468
+#: src/pfm-write.c:466
 #, c-format
 msgid "%s: Closing portable file: %s."
 msgstr ""
@@ -3585,19 +3599,23 @@
 
 #: src/print.c:839
 #, c-format
-msgid "Writing %d record(s) to file %s."
-msgstr ""
+msgid "Writing %d record to %s."
+msgid_plural "Writing %d records to %s."
+msgstr[0] ""
+msgstr[1] ""
 
-#: src/print.c:842
+#: src/print.c:843
 #, c-format
-msgid "Writing %d record(s) to the listing file."
-msgstr ""
+msgid "Writing %d record."
+msgid_plural "Writing %d records."
+msgstr[0] ""
+msgstr[1] ""
 
-#: src/print.c:1082
+#: src/print.c:1084
 msgid "The expression on PRINT SPACE evaluated to the system-missing value."
 msgstr ""
 
-#: src/print.c:1085
+#: src/print.c:1087
 #, c-format
 msgid "The expression on PRINT SPACE evaluated to %g."
 msgstr ""
@@ -3807,6 +3825,13 @@
 msgid "Cannot sample %d observations from a population of %d."
 msgstr ""
 
+#: src/scratch-reader.c:59
+#, c-format
+msgid ""
+"Scratch file handle %s has not yet been written, using SAVE or another "
+"procedure, so it cannot yet be used for reading."
+msgstr ""
+
 #: src/sel-if.c:103
 msgid "The filter variable must be numeric."
 msgstr ""
@@ -3952,131 +3977,131 @@
 msgid "corrupt system file: "
 msgstr ""
 
-#: src/sfm-read.c:151 src/sfm-write.c:931
+#: src/sfm-read.c:149 src/sfm-write.c:929
 #, c-format
 msgid "%s: Closing system file: %s."
 msgstr ""
 
-#: src/sfm-read.c:237
+#: src/sfm-read.c:239
 #, c-format
 msgid ""
 "An error occurred while opening \"%s\" for reading as a system file: %s."
 msgstr ""
 
-#: src/sfm-read.c:255
+#: src/sfm-read.c:257
 #, c-format
 msgid ""
 "%s: Index of weighting variable (%d) is not between 0 and number of elements "
 "per case (%d)."
 msgstr ""
 
-#: src/sfm-read.c:264
+#: src/sfm-read.c:266
 #, c-format
 msgid ""
 "%s: Weighting variable may not be a continuation of a long string variable."
 msgstr ""
 
-#: src/sfm-read.c:267
+#: src/sfm-read.c:269
 #, c-format
 msgid "%s: Weighting variable may not be a string variable."
 msgstr ""
 
-#: src/sfm-read.c:292
+#: src/sfm-read.c:294
 #, c-format
 msgid ""
 "%s: Orphaned variable index record (type 4).  Type 4 records must always "
 "immediately follow type 3 records."
 msgstr ""
 
-#: src/sfm-read.c:350
+#: src/sfm-read.c:352
 #, c-format
 msgid "%s: Invalid subrecord length. Record: 7; Subrecord: 11"
 msgstr ""
 
-#: src/sfm-read.c:404
+#: src/sfm-read.c:406
 #, c-format
 msgid "%s: Trailing garbage in long variable name map."
 msgstr ""
 
-#: src/sfm-read.c:411
+#: src/sfm-read.c:413
 #, c-format
 msgid "%s: Long variable mapping to invalid variable name `%s'."
 msgstr ""
 
-#: src/sfm-read.c:421
+#: src/sfm-read.c:423
 #, c-format
 msgid "%s: Long variable mapping for nonexistent variable %s."
 msgstr ""
 
-#: src/sfm-read.c:431
+#: src/sfm-read.c:433
 #, c-format
 msgid "%s: Duplicate long variable name `%s' within system file."
 msgstr ""
 
-#: src/sfm-read.c:459
+#: src/sfm-read.c:461
 #, c-format
 msgid "%s: Unrecognized record type 7, subtype %d encountered in system file."
 msgstr ""
 
-#: src/sfm-read.c:484
+#: src/sfm-read.c:486
 #, c-format
 msgid "%s: Unrecognized record type %d."
 msgstr ""
 
-#: src/sfm-read.c:516
+#: src/sfm-read.c:518
 #, c-format
 msgid ""
 "%s: Bad size (%d) or count (%d) field on record type 7, subtype 3.\tExpected "
 "size %d, count 8."
 msgstr ""
 
-#: src/sfm-read.c:527
+#: src/sfm-read.c:529
 #, c-format
 msgid ""
 "%s: Floating-point representation in system file is not IEEE-754.  PSPP "
 "cannot convert between floating-point formats."
 msgstr ""
 
-#: src/sfm-read.c:543
+#: src/sfm-read.c:545
 #, c-format
 msgid ""
 "%s: File-indicated endianness (%s) does not match endianness intuited from "
 "file header (%s)."
 msgstr ""
 
-#: src/sfm-read.c:546 src/sfm-read.c:547
+#: src/sfm-read.c:548 src/sfm-read.c:549
 msgid "big-endian"
 msgstr ""
 
-#: src/sfm-read.c:546 src/sfm-read.c:547
+#: src/sfm-read.c:548 src/sfm-read.c:549
 msgid "little-endian"
 msgstr ""
 
-#: src/sfm-read.c:548
+#: src/sfm-read.c:550
 msgid "unknown"
 msgstr ""
 
-#: src/sfm-read.c:552
+#: src/sfm-read.c:554
 #, c-format
 msgid "%s: File-indicated character representation code (%s) is not ASCII."
 msgstr ""
 
-#: src/sfm-read.c:556
+#: src/sfm-read.c:558
 msgid "DEC Kanji"
 msgstr ""
 
-#: src/sfm-read.c:556 src/sysfile-info.c:119
+#: src/sfm-read.c:558 src/sysfile-info.c:119
 msgid "Unknown"
 msgstr ""
 
-#: src/sfm-read.c:572
+#: src/sfm-read.c:574
 #, c-format
 msgid ""
 "%s: Bad size (%d) or count (%d) field on record type 7, subtype 4.\tExpected "
 "size %d, count 8."
 msgstr ""
 
-#: src/sfm-read.c:587
+#: src/sfm-read.c:589
 #, c-format
 msgid ""
 "%s: File-indicated value is different from internal value for at least one "
@@ -4084,220 +4109,220 @@
 "%g; LOWEST: %g, %g."
 msgstr ""
 
-#: src/sfm-read.c:614
+#: src/sfm-read.c:616
 #, c-format
 msgid ""
 "%s: Bad magic.  Proper system files begin with the four characters `$FL2'. "
 "This file will not be read."
 msgstr ""
 
-#: src/sfm-read.c:656
+#: src/sfm-read.c:658
 #, c-format
 msgid ""
 "%s: File layout code has unexpected value %d.  Value should be 2, in big-"
 "endian or little-endian format."
 msgstr ""
 
-#: src/sfm-read.c:684
+#: src/sfm-read.c:686
 #, c-format
 msgid "%s: Number of cases in file (%ld) is not between -1 and %d."
 msgstr ""
 
-#: src/sfm-read.c:689
+#: src/sfm-read.c:691
 #, c-format
 msgid "%s: Compression bias (%g) is not the usual value of 100."
 msgstr ""
 
-#: src/sfm-read.c:812
+#: src/sfm-read.c:814
 #, c-format
 msgid ""
 "%s: position %d: String variable does not have proper number of continuation "
 "records."
 msgstr ""
 
-#: src/sfm-read.c:823
+#: src/sfm-read.c:825
 #, c-format
 msgid "%s: position %d: Superfluous long string continuation record."
 msgstr ""
 
-#: src/sfm-read.c:829
+#: src/sfm-read.c:831
 #, c-format
 msgid "%s: position %d: Bad variable type code %d."
 msgstr ""
 
-#: src/sfm-read.c:832
+#: src/sfm-read.c:834
 #, c-format
 msgid "%s: position %d: Variable label indicator field is not 0 or 1."
 msgstr ""
 
-#: src/sfm-read.c:836
+#: src/sfm-read.c:838
 #, c-format
 msgid ""
 "%s: position %d: Missing value indicator field is not -3, -2, 0, 1, 2, or 3."
 msgstr ""
 
-#: src/sfm-read.c:842
+#: src/sfm-read.c:844
 #, c-format
 msgid "%s: position %d: Variable name begins with invalid character."
 msgstr ""
 
-#: src/sfm-read.c:846
+#: src/sfm-read.c:848
 #, c-format
 msgid "%s: position %d: Variable name begins with lowercase letter %c."
 msgstr ""
 
-#: src/sfm-read.c:850
+#: src/sfm-read.c:852
 #, c-format
 msgid ""
 "%s: position %d: Variable name begins with octothorpe (`#').  Scratch "
 "variables should not appear in system files."
 msgstr ""
 
-#: src/sfm-read.c:865
+#: src/sfm-read.c:867
 #, c-format
 msgid "%s: position %d: Variable name character %d is lowercase letter %c."
 msgstr ""
 
-#: src/sfm-read.c:874
+#: src/sfm-read.c:876
 #, c-format
 msgid ""
 "%s: position %d: character `\\%03o' (%c) is not valid in a variable name."
 msgstr ""
 
-#: src/sfm-read.c:881
+#: src/sfm-read.c:883
 #, c-format
 msgid "%s: Invalid variable name `%s' within system file."
 msgstr ""
 
-#: src/sfm-read.c:888
+#: src/sfm-read.c:890
 #, c-format
 msgid "%s: Duplicate variable name `%s' within system file."
 msgstr ""
 
-#: src/sfm-read.c:911
+#: src/sfm-read.c:913
 #, c-format
 msgid "%s: Variable %s indicates variable label of invalid length %d."
 msgstr ""
 
-#: src/sfm-read.c:932
+#: src/sfm-read.c:934
 #, c-format
 msgid "%s: Long string variable %s may not have missing values."
 msgstr ""
 
-#: src/sfm-read.c:953
+#: src/sfm-read.c:955
 #, c-format
 msgid ""
 "%s: String variable %s may not have missing values specified as a range."
 msgstr ""
 
-#: src/sfm-read.c:980
+#: src/sfm-read.c:982
 #, c-format
 msgid "%s: Long string continuation records omitted at end of dictionary."
 msgstr ""
 
-#: src/sfm-read.c:985
+#: src/sfm-read.c:987
 #, c-format
 msgid ""
 "%s: System file header indicates %d variable positions but %d were read from "
 "file."
 msgstr ""
 
-#: src/sfm-read.c:1010
+#: src/sfm-read.c:1012
 #, c-format
 msgid "%s: %s variable %s has %s format specifier %s."
 msgstr ""
 
-#: src/sfm-read.c:1063
+#: src/sfm-read.c:1065
 #, c-format
 msgid "%s: Invalid number of labels: %d.  Ignoring labels."
 msgstr ""
 
-#: src/sfm-read.c:1105
+#: src/sfm-read.c:1107
 #, c-format
 msgid ""
 "%s: Variable index record (type 4) does not immediately follow value label "
 "record (type 3) as it should."
 msgstr ""
 
-#: src/sfm-read.c:1116
+#: src/sfm-read.c:1118
 #, c-format
 msgid ""
 "%s: Number of variables associated with a value label (%d) is not between 1 "
 "and the number of variables (%d)."
 msgstr ""
 
-#: src/sfm-read.c:1132
+#: src/sfm-read.c:1134
 #, c-format
 msgid ""
 "%s: Variable index associated with value label (%d) is not between 1 and the "
 "number of values (%d)."
 msgstr ""
 
-#: src/sfm-read.c:1139
+#: src/sfm-read.c:1141
 #, c-format
 msgid ""
 "%s: Variable index associated with value label (%d) refers to a continuation "
 "of a string variable, not to an actual variable."
 msgstr ""
 
-#: src/sfm-read.c:1144
+#: src/sfm-read.c:1146
 #, c-format
 msgid "%s: Value labels are not allowed on long string variables (%s)."
 msgstr ""
 
-#: src/sfm-read.c:1155
+#: src/sfm-read.c:1157
 #, c-format
 msgid ""
 "%s: Variables associated with value label are not all of identical type.  "
 "Variable %s has %s type, but variable %s has %s type."
 msgstr ""
 
-#: src/sfm-read.c:1196
+#: src/sfm-read.c:1198
 #, c-format
 msgid "%s: File contains duplicate label for value %g for variable %s."
 msgstr ""
 
-#: src/sfm-read.c:1200
+#: src/sfm-read.c:1202
 #, c-format
 msgid "%s: File contains duplicate label for value `%.*s' for variable %s."
 msgstr ""
 
-#: src/sfm-read.c:1242 src/sfm-read.c:1519
+#: src/sfm-read.c:1244 src/sfm-read.c:1521
 #, c-format
 msgid "%s: Reading system file: %s."
 msgstr ""
 
-#: src/sfm-read.c:1245 src/sfm-read.c:1360 src/sfm-read.c:1402
+#: src/sfm-read.c:1247 src/sfm-read.c:1362 src/sfm-read.c:1404
 #, c-format
 msgid "%s: Unexpected end of file."
 msgstr ""
 
-#: src/sfm-read.c:1260
+#: src/sfm-read.c:1262
 #, c-format
 msgid "%s: Seeking system file: %s."
 msgstr ""
 
-#: src/sfm-read.c:1275
+#: src/sfm-read.c:1277
 #, c-format
 msgid "%s: System file contains multiple type 6 (document) records."
 msgstr ""
 
-#: src/sfm-read.c:1281
+#: src/sfm-read.c:1283
 #, c-format
 msgid "%s: Number of document lines (%ld) must be greater than 0."
 msgstr ""
 
-#: src/sfm-read.c:1313
+#: src/sfm-read.c:1315
 #, c-format
 msgid "%s: Error reading file: %s."
 msgstr ""
 
-#: src/sfm-read.c:1350
+#: src/sfm-read.c:1352
 #, c-format
 msgid "%s: Compressed data is corrupted.  Data ends in partial case."
 msgstr ""
 
-#: src/sfm-read.c:1522
+#: src/sfm-read.c:1524
 #, c-format
 msgid "%s: Partial record at end of system file."
 msgstr ""
@@ -4317,6 +4342,14 @@
 msgid "%s: Writing system file: %s."
 msgstr ""
 
+#: src/sort-prs.c:94
+msgid "`A' or `D' expected inside parentheses."
+msgstr ""
+
+#: src/sort-prs.c:99
+msgid "`)' expected."
+msgstr ""
+
 #: src/sort.c:85
 msgid "Buffer limit must be at least 2."
 msgstr ""
@@ -4328,14 +4361,6 @@
 "each.  (PSPP workspace is currently restricted to a maximum of %d KB.)"
 msgstr ""
 
-#: src/sort-prs.c:94
-msgid "`A' or `D' expected inside parentheses."
-msgstr ""
-
-#: src/sort-prs.c:99
-msgid "`)' expected."
-msgstr ""
-
 #: src/sysfile-info.c:100
 msgid "File:"
 msgstr ""
@@ -4437,7 +4462,7 @@
 msgid "Documents in the active file:"
 msgstr ""
 
-#: src/sysfile-info.c:380 src/sysfile-info.c:519 src/vfm.c:841
+#: src/sysfile-info.c:380 src/sysfile-info.c:519 src/vfm.c:846
 msgid "Label"
 msgstr ""
 
@@ -4468,51 +4493,6 @@
 msgid "Vector"
 msgstr ""
 
-#: src/tab.c:258
-#, c-format
-msgid "bad vline: x=%d+%d=%d y=(%d+%d=%d,%d+%d=%d) in table size (%d,%d)\n"
-msgstr ""
-
-#: src/tab.c:333
-#, c-format
-msgid ""
-"bad box: (%d+%d=%d,%d+%d=%d)-(%d+%d=%d,%d+%d=%d) in table size (%d,%d)\n"
-msgstr ""
-
-#: src/temporary.c:49
-msgid "This command is not valid inside DO IF or LOOP."
-msgstr ""
-
-#: src/temporary.c:56
-msgid ""
-"This command may only appear once between procedures and procedure-like "
-"commands."
-msgstr ""
-
-#: src/title.c:60
-#, c-format
-msgid "%s before: %s\n"
-msgstr ""
-
-#: src/title.c:60
-msgid "<none>"
-msgstr ""
-
-#: src/title.c:72
-#, c-format
-msgid "%s: `.' expected after string."
-msgstr ""
-
-#: src/title.c:88
-#, c-format
-msgid "%s after: %s\n"
-msgstr ""
-
-#: src/title.c:143
-#, c-format
-msgid "Document entered %s by %s:"
-msgstr ""
-
 #: src/t-test.q:270
 msgid "TESTVAL, GROUPS and PAIRS subcommands are mutually exclusive."
 msgstr ""
@@ -4638,6 +4618,51 @@
 msgid "%s & %s"
 msgstr ""
 
+#: src/tab.c:258
+#, c-format
+msgid "bad vline: x=%d+%d=%d y=(%d+%d=%d,%d+%d=%d) in table size (%d,%d)\n"
+msgstr ""
+
+#: src/tab.c:333
+#, c-format
+msgid ""
+"bad box: (%d+%d=%d,%d+%d=%d)-(%d+%d=%d,%d+%d=%d) in table size (%d,%d)\n"
+msgstr ""
+
+#: src/temporary.c:49
+msgid "This command is not valid inside DO IF or LOOP."
+msgstr ""
+
+#: src/temporary.c:56
+msgid ""
+"This command may only appear once between procedures and procedure-like "
+"commands."
+msgstr ""
+
+#: src/title.c:60
+#, c-format
+msgid "%s before: %s\n"
+msgstr ""
+
+#: src/title.c:60
+msgid "<none>"
+msgstr ""
+
+#: src/title.c:72
+#, c-format
+msgid "%s: `.' expected after string."
+msgstr ""
+
+#: src/title.c:88
+#, c-format
+msgid "%s after: %s\n"
+msgstr ""
+
+#: src/title.c:143
+#, c-format
+msgid "Document entered %s by %s:"
+msgstr ""
+
 #: src/val-labs.c:121
 #, c-format
 msgid ""
Index: pspp/src/ChangeLog
diff -u pspp/src/ChangeLog:1.259 pspp/src/ChangeLog:1.260
--- pspp/src/ChangeLog:1.259    Thu Jan 12 03:39:01 2006
+++ pspp/src/ChangeLog  Sun Jan 29 02:41:11 2006
@@ -1,6 +1,207 @@
+Sat Jan 28 17:45:36 2006  Ben Pfaff  <address@hidden>
+
+       Cleaner (faster?) way to compact cases.
+
+       * dictionary.c: (dict_compact_case) Removed.
+       (dict_needs_compaction) New function.
+       (struct copy_map) New structure.
+       (struct dict_compactor) New structure.
+       (dict_make_compactor) New function.
+       (dict_compactor_compact) New function.
+       (dict_compactor_destroy) New function.
+       
+Sat Jan 28 17:24:22 2006  Ben Pfaff  <address@hidden>
+
+       Cleanups.
+
+       * data-list.c: Make data_list_source_class static.
+       (dump_fixed_table) Use fh_get_name() to describe source of data.
+       (dump_free_table) Ditto.
+       (cmd_repeating_data) Eliminate special cases for inline file.
+
+       * dictionary.c: (dict_contains_var) Change return value from int to
+       bool.
+       (dict_rename_vars) Ditto.
+       (dict_create_vector) Ditto.
+
+Sat Jan 28 17:20:50 2006  Ben Pfaff  <address@hidden>
+
+       Add scratch file handles.
+
+       Now a file handle can refer to a disk file, to an in-memory
+       structure, or to the "inline" file, instead of just to a disk
+       file.  The introduction of new categories means that special cases
+       for the inline file in a few places could be eliminated, but it
+       also means that code that assumed that a handle refers to a file
+       has to check for that.
+
+       Also, now file handles can be freed, so code now must be sure not
+       to access a handle after closing it (with fh_close()).
+
+       * Makefile.am: Add any-reader.c, any-reader.h, any-writer.c,
+       any-writer.h, scratch-handle.c, scratch-handle.h,
+       scratch-reader.c, scratch-reader.h, scratch-writer.c,
+       scratch-writer.h to pspp_SOURCES.
+
+       * any-reader.c: New file.
+       
+       * any-reader.h: New file.
+       
+       * any-writer.c: New file.
+       
+       * any-writer.h: New file.
+
+       * scratch-handle.c: New file.
+       
+       * scratch-handle.h: New file.
+
+       * scratch-reader.c: New file.
+       
+       * scratch-reader.h: New file.
+
+       * scratch-writer.c: New file.
+       
+       * scratch-writer.h: New file.
+
+       * aggregate.c: Use an any_writer instead of an sfm_writer, to add
+       flexibility.
+
+       * apply-dict.c: Use an any_reader instead of an sfm_reader, to add
+       flexibility.
+
+       * command.def: Add CLOSE FILE HANDLE command.
+
+       * dfm-reader.c: Now fewer special cases for inline file.
+       (static var inline_open_cnt) Removed.
+       (static var inline_file) Removed.
+       (dfm_close_reader) Eliminate a special case for inline file.
+       Reorganize to avoid access-after-free.
+       (dfm_open_reader) Eliminate a special case for inline file.
+       (read_inline_record) Use bool instead of int.  No need to
+       increment line number.
+       (read_file_record) Use bool instead of int.
+       (read_record) Check whether file handle is inline file, instead of
+       for null pointer.
+       (dfm_eof) Ditto.
+       (dfm_expand_tabs) Ditto.
+       (dfm_push) Ditto.
+       (dfm_pop) Ditto.
+       (cmd_begin_data) Fix inaccurate check for whether the inline file
+       is in use--now we can tell by checking whether the inline file's
+       open count is positive.
+       
+       * file-handle-def.c: (struct file_handle) Reorder members.  Add
+       `deleted' member.  Add `referent' member.  Add `sh' member.
+       (static var default_handle) New variable.
+       (static var inline_file) New variable.
+       (fh_init) Initialize inline file.
+       (free_handle) New function.
+       (fh_done) Rewrite.
+       (fh_from_name) Don't return deleted handles.
+       (fh_from_filename) Ditto.
+       (fh_create) Removed.
+       (create_handle) New function.
+       (fh_create_file) New function.
+       (fh_create_scratch) New function.
+       (fh_inline_file) New function.
+       (fh_free) Rewrite.
+       (fh_open) Now requires a referent type mask and verifies it.  All
+       references updated.
+       (fh_close) If open_cnt goes to 0 on a deleted handle, free it.
+       (fh_is_open) New function.
+       (fh_get_referent) New function.
+       (fh_get_filename) Limit to handles that refer to files.
+       (fh_get_mode) Ditto.
+       (fh_get_record_width) Limit to handles that refer to files or the
+       inline file.
+       (fh_get_tab_width) Ditto.
+       (fh_get_scratch_handle) New function.
+       (fh_set_scratch_handle) New function.
+       (fh_get_default_handle) New function.
+       (fh_set_default_handle) New function.
+
+       * file-handle.h: (enum fh_referent) New type.
+       (enum fh_mode) Rename MODE_TEXT to FH_MODE_TEXT, MODE_BINARY to
+       FH_MODE_BINARY, and update all usages.
+
+       * file-handle.q: Add "scratch" as a possible mode.
+       (cmd_file_handle) Mention CLOSE FILE HANDLE in error message.
+       Use lex_end_of_command(), lex_sbc_missing().  Support creating
+       scratch handles.
+       (cmd_close_file_handle) New function.
+       (referent_name) New function.
+       (fh_parse) Now takes a referent type mask to specify handles that
+       can be accepted.  Updated all references.
+       
+       * filename.c: (fn_extension) New function.
+
+       * get.c: Use any_reader and any_writer and thereby merge code that
+       has been duplicated for each kind of file.  Also, we had something
+       here called `any_writer' before, so its name had to be changed to
+       `case_writer'.
+       (enum operation) Removed, because unused.
+       (struct get_pgm) Removed.
+       (get_pgm_free) Removed.
+       (get_source_destroy) Removed.
+       (get_source_read) Removed.
+       (global var get_source_class) Removed.
+       (static var case_reader_source_class) Removed.
+       (enum reader_command) New enum.
+       (struct case_reader_pgm) New struct.
+       (parse_read_command) New function.
+       (case_reader_pgm_free) New function.
+       (case_reader_source_destroy) New function.
+       (case_Reader_source_Read) New function.
+       (cmd_get) Rewrote as a call to parse_read_command().
+       (cmd_import) Ditto.
+       (struct any_writer) Rename to case_writer.  Drop `writer_type',
+       `writer' members in favor of an `any_writer' member named
+       `writer'.
+       (any_writer_destroy) Rename case_writer_destroy.  Use
+       any_writer_close().
+       (parse_write_command) Allow scratch files.  Use any_writer.
+       (any_writer_write_case) Rename case_writer_write_case().  Use
+       any_writer_write().
+`      (struct mtf_file) Use any_reader.
+       (cmd_match_files) Allow scratch files.  Use any_reader.
+       (mtf_free_file) Use any_reader_close().
+       (mtf_read_nonactive_records) Use any_reader_read().
+       (mtf_processing) Use any_reader_read().
+       (struct import_pgm) Removed.
+       (import_pgm_free) Removed.
+       (import_source_destroy) Removed.
+       (import_source_read) Removed.
+       (global var import_source_class) Removed.
+
+       * glob.c: (global var default_handle) Removed.  Replaced all
+       references by fh_get_default_handle() or fh_set_default_handle().
+
+       * pfm-read.c: (static var portable_to_local) Moved from inside
+       read_header() to top level.
+       (pfm_detect) New function.
+
+       * pfm-write.c: (pfm_write_case) Make case argument const.
+       Reorganize to avoid access-after-free.
+
+       * print.c: (dump_table) Use fh_get_name() to describe source of
+       data.
+
+       * sfm-read.c: (sfm_close_reader) Reorganize to avoid
+       access-after-free.
+       (sfm_detect) New function.
+
+       * str.c: (str_lowercase) New function.
+
+       * vfm.c: Use new compaction interface.
+       (static var compaction_necessary) Removed.
+       (static var compactor) New variable.
+       (open_active_file) Initialize compactor.
+       (write_case) Use compactor.
+       (close_active_file) Free compactor.
+       
 Wed Jan 11 19:28:39 2006  Ben Pfaff  <address@hidden>
 
-       Clean up file handle code in preparation to add temporary file
+       Clean up file handle code in preparation to add scratch file
        handles.
        
        * file-handle-def.c: Lots of formatting cleanup.  Added function
Index: pspp/src/Makefile.am
diff -u pspp/src/Makefile.am:1.62 pspp/src/Makefile.am:1.63
--- pspp/src/Makefile.am:1.62   Thu Jan 19 03:31:35 2006
+++ pspp/src/Makefile.am        Sun Jan 29 02:41:11 2006
@@ -72,6 +72,10 @@
        algorithm.h                             \
        alloc.c                                 \
        alloc.h                                 \
+       any-reader.c                            \
+       any-reader.h                            \
+       any-writer.c                            \
+       any-writer.h                            \
        apply-dict.c                            \
        ascii.c                                 \
        autorecode.c                            \
@@ -221,6 +225,12 @@
        tab.c                                   \
        tab.h                                   \
        temporary.c                             \
+       scratch-handle.c                        \
+       scratch-handle.h                        \
+       scratch-reader.c                        \
+       scratch-reader.h                        \
+       scratch-writer.c                        \
+       scratch-writer.h                        \
        mkfile.c                                \
        mkfile.h                                \
        title.c                                 \
Index: pspp/src/aggregate.c
diff -u pspp/src/aggregate.c:1.43 pspp/src/aggregate.c:1.44
--- pspp/src/aggregate.c:1.43   Wed Oct 26 05:06:14 2005
+++ pspp/src/aggregate.c        Sun Jan 29 02:41:11 2006
@@ -21,6 +21,7 @@
 #include "error.h"
 #include <stdlib.h>
 #include "alloc.h"
+#include "any-writer.h"
 #include "case.h"
 #include "casefile.h"
 #include "command.h"
@@ -121,7 +122,7 @@
 struct agr_proc 
   {
     /* We have either an output file or a sink. */
-    struct sfm_writer *writer;          /* Output file, or null if none. */
+    struct any_writer *writer;          /* Output file, or null if none. */
     struct case_sink *sink;             /* Sink, or null if none. */
 
     /* Break variables. */
@@ -181,7 +182,7 @@
   lex_match ('=');
   if (!lex_match ('*'))
     {
-      out_file = fh_parse ();
+      out_file = fh_parse (FH_REF_FILE | FH_REF_SCRATCH);
       if (out_file == NULL)
         goto error;
     }
@@ -278,8 +279,7 @@
     }
   else
     {
-      agr.writer = sfm_open_writer (out_file, agr.dict,
-                                    sfm_writer_default_options ());
+      agr.writer = any_writer_open (out_file, agr.dict);
       if (agr.writer == NULL)
         goto error;
       
@@ -297,7 +297,7 @@
           while (casereader_read_xfer (reader, &c)) 
             {
               if (aggregate_single_case (&agr, &c, &agr.agr_case)) 
-                sfm_write_case (agr.writer, &agr.agr_case);
+                any_writer_write (agr.writer, &agr.agr_case);
               case_destroy (&c);
             }
           casereader_destroy (reader);
@@ -312,7 +312,7 @@
       if (agr.case_cnt > 0) 
         {
           dump_aggregate_info (&agr, &agr.agr_case);
-          sfm_write_case (agr.writer, &agr.agr_case);
+          any_writer_write (agr.writer, &agr.agr_case);
         }
     }
   
@@ -652,7 +652,7 @@
 {
   struct agr_var *iter, *next;
 
-  sfm_close_writer (agr->writer);
+  any_writer_close (agr->writer);
   if (agr->sort != NULL)
     sort_destroy_criteria (agr->sort);
   free (agr->break_vars);
@@ -1075,7 +1075,7 @@
   struct agr_proc *agr = agr_;
 
   if (aggregate_single_case (agr, c, &agr->agr_case)) 
-    sfm_write_case (agr->writer, &agr->agr_case);
+    any_writer_write (agr->writer, &agr->agr_case);
 
   return 1;
 }
Index: pspp/src/apply-dict.c
diff -u pspp/src/apply-dict.c:1.9 pspp/src/apply-dict.c:1.10
--- pspp/src/apply-dict.c:1.9   Sun Aug  7 04:39:28 2005
+++ pspp/src/apply-dict.c       Sun Jan 29 02:41:11 2006
@@ -19,13 +19,13 @@
 
 #include <config.h>
 #include <stdlib.h>
+#include "any-reader.h"
 #include "command.h"
 #include "dictionary.h"
 #include "error.h"
 #include "file-handle.h"
 #include "hash.h"
 #include "lexer.h"
-#include "sfm-read.h"
 #include "str.h"
 #include "value-labels.h"
 #include "var.h"
@@ -40,7 +40,7 @@
 cmd_apply_dictionary (void)
 {
   struct file_handle *handle;
-  struct sfm_reader *reader;
+  struct any_reader *reader;
   struct dictionary *dict;
 
   int n_matched = 0;
@@ -49,14 +49,14 @@
   
   lex_match_id ("FROM");
   lex_match ('=');
-  handle = fh_parse ();
+  handle = fh_parse (FH_REF_FILE | FH_REF_SCRATCH);
   if (!handle)
     return CMD_FAILURE;
 
-  reader = sfm_open_reader (handle, &dict, NULL);
+  reader = any_reader_open (handle, &dict);
   if (dict == NULL)
     return CMD_FAILURE;
-  sfm_close_reader (reader);
+  any_reader_close (reader);
 
   for (i = 0; i < dict_get_var_cnt (dict); i++)
     {
@@ -163,7 +163,7 @@
         dict_set_weight (default_dict, new_weight);
     }
   
-  sfm_close_reader (reader);
+  any_reader_close (reader);
 
   return lex_end_of_command ();
 }
Index: pspp/src/cat.h
diff -u pspp/src/cat.h:1.6 pspp/src/cat.h:1.7
--- pspp/src/cat.h:1.6  Sun Nov 27 20:25:51 2005
+++ pspp/src/cat.h      Sun Jan 29 02:41:11 2006
@@ -53,4 +53,5 @@
                                           values stored.
                                         */
 };
+
 #endif
Index: pspp/src/command.def
diff -u pspp/src/command.def:1.24 pspp/src/command.def:1.25
--- pspp/src/command.def:1.24   Fri Oct 14 14:50:07 2005
+++ pspp/src/command.def        Sun Jan 29 02:41:11 2006
@@ -38,6 +38,7 @@
 UNIMPL ("CASESTOVARS",           ERRO, ERRO, ERRO, ERRO, "Restructure complex 
data")
 UNIMPL ("CCF",                   ERRO, ERRO, ERRO, ERRO, "Time series cross 
correlation")
 DEFCMD ("CLEAR TRANSFORMATIONS",  ERRO, INPU, TRAN, TRAN, 
cmd_clear_transformations)
+DEFCMD ("CLOSE FILE HANDLE",      INIT, INPU, TRAN, PROC, 
cmd_close_file_handle)
 UNIMPL ("CLUSTER",               ERRO, ERRO, ERRO, ERRO, "Hierachial 
clustering")
 DEFCMD ("COMPUTE",                ERRO, INPU, TRAN, TRAN, cmd_compute)
 UNIMPL ("CONJOINT",              ERRO, ERRO, ERRO, ERRO, "Analyse full concept 
data")
Index: pspp/src/correlations.q
diff -u pspp/src/correlations.q:1.8 pspp/src/correlations.q:1.9
--- pspp/src/correlations.q:1.8 Mon Oct 24 02:51:32 2005
+++ pspp/src/correlations.q     Sun Jan 29 02:41:11 2006
@@ -137,7 +137,7 @@
     matrix_file = NULL;
   else 
     {
-      matrix_file = fh_parse ();
+      matrix_file = fh_parse (FH_REF_FILE);
       if (matrix_file == NULL)
         return 0; 
     }
Index: pspp/src/data-list.c
diff -u pspp/src/data-list.c:1.44 pspp/src/data-list.c:1.45
--- pspp/src/data-list.c:1.44   Thu Jan 12 03:39:01 2006
+++ pspp/src/data-list.c        Sun Jan 29 02:41:11 2006
@@ -1,5 +1,5 @@
 /* PSPP - computes sample statistics.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
    Written by Ben Pfaff <address@hidden>.
 
    This program is free software; you can redistribute it and/or
@@ -95,6 +95,8 @@
     size_t delim_cnt;           /* Number of delimiter, or 0 for spaces. */
   };
 
+static const struct case_source_class data_list_source_class;
+
 static int parse_fixed (struct data_list_pgm *);
 static int parse_free (struct dls_var_spec **, struct dls_var_spec **);
 static void dump_fixed_table (const struct dls_var_spec *,
@@ -111,9 +113,9 @@
 int
 cmd_data_list (void)
 {
-  struct data_list_pgm *dls;     /* DATA LIST program under construction. */
+  struct data_list_pgm *dls;
   int table = -1;                /* Print table if nonzero, -1=undecided. */
-  struct file_handle *fh = NULL; /* File handle of source, NULL=inline file. */
+  struct file_handle *fh = fh_inline_file ();
 
   if (!case_source_is_complex (vfm_source))
     discard_variables ();
@@ -133,14 +135,14 @@
       if (lex_match_id ("FILE"))
        {
          lex_match ('=');
-         fh = fh_parse ();
+         fh = fh_parse (FH_REF_FILE | FH_REF_INLINE);
          if (fh == NULL)
            goto error;
          if (case_source_is_class (vfm_source, &file_type_source_class)
-              && fh != default_handle)
+              && fh != fh_get_default_handle ())
            {
-             msg (SE, _("DATA LIST may not use a different file from "
-                        "that specified on its surrounding FILE TYPE."));
+             msg (SE, _("DATA LIST must use the same file "
+                        "as the enclosing FILE TYPE."));
              goto error;
            }
        }
@@ -235,7 +237,7 @@
     }
 
   dls->case_size = dict_get_case_size (default_dict);
-  default_handle = fh;
+  fh_set_default_handle (fh);
 
   if (dls->type == -1)
     dls->type = DLS_FIXED;
@@ -795,15 +797,9 @@
                    fmt_to_string (&spec->input));
     }
 
-  if (fh != NULL)
-    tab_title (t, 1, ngettext ("Reading %d record from file %s.",
-                               "Reading %d records from file %s.", rec_cnt),
-               rec_cnt, fh_get_filename (fh));
-  else
-    tab_title (t, 1, ngettext ("Reading %d record from the command file.",
-                               "Reading %d records from the command file.",
-                               rec_cnt),
-               rec_cnt);
+  tab_title (t, 1, ngettext ("Reading %d record from %s.",
+                             "Reading %d records from %s.", rec_cnt),
+             rec_cnt, fh_get_name (fh));
   tab_submit (t);
 }
 
@@ -917,11 +913,7 @@
       }
   }
 
-  if (fh != NULL)
-    tab_title (t, 1, _("Reading free-form data from file %s."),
-               fh_get_filename (fh));
-  else
-    tab_title (t, 1, _("Reading free-form data from the command file."));
+  tab_title (t, 1, _("Reading free-form data from %s."), fh_get_name (fh));
   
   tab_submit (t);
 }
@@ -1309,7 +1301,7 @@
   data_list_trns_free (source->aux);
 }
 
-const struct case_source_class data_list_source_class = 
+static const struct case_source_class data_list_source_class = 
   {
     "DATA LIST",
     NULL,
@@ -1367,12 +1359,12 @@
   bool saw_length = false;      /* Saw LENGTH subcommand? */
   bool saw_continued = false;   /* Saw CONTINUED subcommand? */
   bool saw_id = false;          /* Saw ID subcommand? */
-  struct file_handle *const fh = default_handle;
+  struct file_handle *const fh = fh_get_default_handle ();
   
   assert (case_source_is_complex (vfm_source));
 
   rpd = xmalloc (sizeof *rpd);
-  rpd->reader = dfm_open_reader (default_handle);
+  rpd->reader = dfm_open_reader (fh);
   rpd->first = rpd->last = NULL;
   rpd->starts_beg.num = 0;
   rpd->starts_beg.var = NULL;
@@ -1390,7 +1382,7 @@
        {
           struct file_handle *file;
          lex_match ('=');
-         file = fh_parse ();
+         file = fh_parse (FH_REF_FILE | FH_REF_INLINE);
          if (file == NULL)
            goto error;
          if (file != fh)
@@ -1585,7 +1577,7 @@
   /* Calculate and check starts_end, cont_end if necessary. */
   if (rpd->starts_end.num == 0 && rpd->starts_end.var == NULL) 
     {
-      rpd->starts_end.num = fh != NULL ? fh_get_record_width (fh) : 80;
+      rpd->starts_end.num = fh_get_record_width (fh);
       if (rpd->starts_beg.num != 0 
           && rpd->starts_beg.num > rpd->starts_end.num)
         {
@@ -1598,7 +1590,7 @@
     }
   if (rpd->cont_end.num == 0 && rpd->cont_end.var == NULL) 
     {
-      rpd->cont_end.num = fh != NULL ? fh_get_record_width (fh) : 80;
+      rpd->cont_end.num = fh_get_record_width (fh);
       if (rpd->cont_beg.num != 0
           && rpd->cont_beg.num > rpd->cont_end.num)
         {
Index: pspp/src/dfm-read.c
diff -u pspp/src/dfm-read.c:1.9 pspp/src/dfm-read.c:1.10
--- pspp/src/dfm-read.c:1.9     Thu Jan 12 03:39:01 2006
+++ pspp/src/dfm-read.c Sun Jan 29 02:41:11 2006
@@ -1,5 +1,5 @@
 /* PSPP - computes sample statistics.
-   Copyright (C) 1997-2004 Free Software Foundation, Inc.
+   Copyright (C) 1997-2004, 2006 Free Software Foundation, Inc.
    Written by Ben Pfaff <address@hidden>.
 
    This program is free software; you can redistribute it and/or
@@ -53,17 +53,14 @@
 struct dfm_reader
   {
     struct file_handle *fh;     /* File handle. */
-    struct file_ext file;      /* Associated file. */
     struct file_locator where;  /* Current location in data file. */
     struct string line;         /* Current line. */
-    size_t pos;                 /* Offset in line of current character. */
     struct string scratch;      /* Extra line buffer. */
     enum dfm_reader_flags flags; /* Zero or more of DFM_*. */
+    struct file_ext file;      /* Associated file. */
+    size_t pos;                 /* Offset in line of current character. */
   };
 
-static int inline_open_cnt;
-static struct dfm_reader *inline_file;
-
 static void read_record (struct dfm_reader *r);
 
 /* Closes reader R opened by dfm_open_reader(). */
@@ -71,81 +68,62 @@
 dfm_close_reader (struct dfm_reader *r)
 {
   int still_open;
+  bool is_inline;
 
   if (r == NULL)
     return;
 
-  if (r->fh != NULL) 
-    still_open = fh_close (r->fh, "data file", "rs");
-  else
-    {
-      assert (inline_open_cnt > 0);
-      still_open = --inline_open_cnt;
-
-      if (!still_open) 
-        {
-          /* Skip any remaining data on the inline file. */
-          if (r->flags & DFM_SAW_BEGIN_DATA)
-            while ((r->flags & DFM_EOF) == 0)
-              read_record (r);
-          inline_file = NULL;
-        }
-    }
+  is_inline = r->fh == fh_inline_file ();
+  still_open = fh_close (r->fh, "data file", "rs");
   if (still_open)
     return;
 
-  if (r->fh != NULL && r->file.file)
+  if (!is_inline)
     {
       fn_close_ext (&r->file);
       free (r->file.filename);
       r->file.filename = NULL;
     }
+  else
+    {
+      /* Skip any remaining data on the inline file. */
+      if (r->flags & DFM_SAW_BEGIN_DATA)
+        while ((r->flags & DFM_EOF) == 0)
+          read_record (r);
+    }
+
   ds_destroy (&r->line);
   ds_destroy (&r->scratch);
   free (r);
 }
 
 /* Opens the file designated by file handle FH for reading as a
-   data file.  Providing a null pointer for FH designates the
+   data file.  Providing fh_inline_file() for FH designates the
    "inline file", that is, data included inline in the command
-   file between BEGIN FILE and END FILE.  Returns nonzero only if
-   successful. */
+   file between BEGIN FILE and END FILE.  Returns a reader if
+   successful, or a null pointer otherwise. */
 struct dfm_reader *
 dfm_open_reader (struct file_handle *fh)
 {
   struct dfm_reader *r;
   void **rp;
 
-  if (fh != NULL) 
-    {
-      rp = fh_open (fh, "data file", "rs");
-      if (rp == NULL)
-        return NULL;
-      if (*rp != NULL)
-        return *rp; 
-    }
-  else 
-    {
-      assert (inline_open_cnt >= 0);
-      if (inline_open_cnt++ > 0)
-        return inline_file;
-      rp = NULL;
-    }
+  rp = fh_open (fh, FH_REF_FILE | FH_REF_INLINE, "data file", "rs");
+  if (rp == NULL)
+    return NULL;
+  if (*rp != NULL)
+    return *rp; 
   
   r = xmalloc (sizeof *r);
   r->fh = fh;
-  if (fh != NULL) 
-    {
-      r->where.filename = fh_get_filename (fh);
-      r->where.line_number = 0; 
-    }
-  r->file.file = NULL;
   ds_init (&r->line, 64);
   ds_init (&r->scratch, 0);
   r->flags = DFM_ADVANCE;
-
-  if (fh != NULL)
+  if (fh != fh_inline_file ()) 
     {
+      r->where.filename = fh_get_filename (fh);
+      r->where.line_number = 0; 
+      r->file.file = NULL;
       r->file.filename = xstrdup (fh_get_filename (r->fh));
       r->file.mode = "rb";
       r->file.file = NULL;
@@ -154,24 +132,23 @@
       r->file.postopen = NULL;
       r->file.preclose = NULL;
       if (!fn_open_ext (&r->file))
-       {
-         msg (ME, _("Could not open \"%s\" for reading "
-                     "as a data file: %s."),
+        {
+          msg (ME, _("Could not open \"%s\" for reading as a data file: %s."),
                fh_get_filename (r->fh), strerror (errno));
           err_cond_fail ();
           fh_close (fh,"data file", "rs");
           free (r);
           return NULL;
-       }
-      *rp = r;
+        }
     }
-  else
-    inline_file = r;
+  *rp = r;
 
   return r;
 }
 
-static int
+/* Reads a record from the inline file into R.
+   Returns true if successful, false on failure. */
+static bool
 read_inline_record (struct dfm_reader *r)
 {
   if ((r->flags & DFM_SAW_BEGIN_DATA) == 0)
@@ -208,7 +185,7 @@
         {
           msg (SE, _("BEGIN DATA expected."));
           lex_preprocess_line ();
-          return 0;
+          return false;
         }
       getl_prompt = GETL_PRPT_DATA;
     }
@@ -223,25 +200,24 @@
       err_failure ();
     }
 
-  if (r->fh != NULL)
-    r->where.line_number++;
-
   if (ds_length (&getl_buf) >= 8
       && !strncasecmp (ds_c_str (&getl_buf), "end data", 8))
     {
       lex_set_prog (ds_c_str (&getl_buf) + ds_length (&getl_buf));
-      return 0;
+      return false;
     }
 
   ds_replace (&r->line, ds_c_str (&getl_buf));
-  return 1;
+  return true;
 }
 
-static int
+/* Reads a record from a disk file into R.
+   Returns true if successful, false on failure. */
+static bool
 read_file_record (struct dfm_reader *r)
 {
-  assert (r->fh != NULL);
-  if (fh_get_mode (r->fh) == MODE_TEXT)
+  assert (r->fh != fh_inline_file ());
+  if (fh_get_mode (r->fh) == FH_MODE_TEXT)
     {
       ds_clear (&r->line);
       if (!ds_gets (&r->line, r->file.file)) 
@@ -252,10 +228,10 @@
                    fh_get_name (r->fh), strerror (errno));
               err_cond_fail ();
             }
-          return 0;
+          return false;
         }
     }
-  else if (fh_get_mode (r->fh) == MODE_BINARY)
+  else if (fh_get_mode (r->fh) == FH_MODE_BINARY)
     {
       size_t record_width = fh_get_record_width (r->fh);
       size_t amt;
@@ -274,10 +250,10 @@
             msg (ME, _("%s: Partial record at end of file."),
                  fh_get_name (r->fh));
           else
-            return 0;
+            return false;
 
           err_cond_fail ();
-          return 0;
+          return false;
         }
     }
   else
@@ -285,7 +261,7 @@
 
   r->where.line_number++;
 
-  return 1;
+  return true;
 }
 
 /* Reads a record from R, setting the current position to the
@@ -294,7 +270,13 @@
 static void
 read_record (struct dfm_reader *r)
 {
-  int success = r->fh != NULL ? read_file_record (r) : read_inline_record (r);
+  bool success;
+
+  if (fh_get_referent (r->fh) == FH_REF_FILE)
+    success = read_file_record (r);
+  else
+    success = read_inline_record (r);
+  
   if (success)
     r->pos = 0;
   else
@@ -313,7 +295,7 @@
         read_record (r);
       else
         {
-          if (r->fh != NULL)
+          if (r->fh != fh_inline_file ())
             msg (SE, _("Attempt to read beyond end-of-file on file %s."),
                  fh_get_name (r->fh));
           else
@@ -359,15 +341,15 @@
     return;
   r->flags |= DFM_TABS_EXPANDED;
 
-  if (r->fh != NULL
-      && (fh_get_mode (r->fh) == MODE_BINARY
+  if (r->fh != fh_inline_file ()
+      && (fh_get_mode (r->fh) == FH_MODE_BINARY
           || fh_get_tab_width (r->fh) == 0
           || memchr (ds_c_str (&r->line), '\t', ds_length (&r->line)) == NULL))
     return;
 
   /* Expand tabs from r->line into r->scratch, and figure out
      new value for r->pos. */
-  tab_width = r->fh != NULL ? fh_get_tab_width (r->fh) : 8;
+  tab_width = fh_get_tab_width (r->fh);
   ds_clear (&r->scratch);
   new_pos = 0;
   for (ofs = 0; ofs < ds_length (&r->line); ofs++)
@@ -439,7 +421,7 @@
 void
 dfm_push (struct dfm_reader *r)
 {
-  if (r->fh != NULL)
+  if (r->fh != fh_inline_file ())
     err_push_file_locator (&r->where);
 }
 
@@ -447,7 +429,7 @@
 void
 dfm_pop (struct dfm_reader *r)
 {
-  if (r->fh != NULL)
+  if (r->fh != fh_inline_file ())
     err_pop_file_locator (&r->where);
 }
 
@@ -459,10 +441,7 @@
 {
   struct dfm_reader *r;
 
-  /* FIXME: figure out the *exact* conditions, not these really
-     lenient conditions. */
-  if (vfm_source == NULL
-      || case_source_is_class (vfm_source, &storage_source_class))
+  if (!fh_is_open (fh_inline_file ()))
     {
       msg (SE, _("This command is not valid here since the current "
                  "input program does not access the inline file."));
@@ -471,7 +450,7 @@
     }
 
   /* Open inline file. */
-  r = dfm_open_reader (NULL);
+  r = dfm_open_reader (fh_inline_file ());
   r->flags |= DFM_SAW_BEGIN_DATA;
 
   /* Input procedure reads from inline file. */
Index: pspp/src/dfm-write.c
diff -u pspp/src/dfm-write.c:1.4 pspp/src/dfm-write.c:1.5
--- pspp/src/dfm-write.c:1.4    Thu Jan 12 03:39:01 2006
+++ pspp/src/dfm-write.c        Sun Jan 29 02:41:11 2006
@@ -46,7 +46,7 @@
   struct dfm_writer *w;
   void **aux;
   
-  aux = fh_open (fh, "data file", "ws");
+  aux = fh_open (fh, FH_REF_FILE, "data file", "ws");
   if (aux == NULL)
     return NULL;
   if (*aux != NULL)
@@ -89,7 +89,7 @@
 {
   assert (w != NULL);
 
-  if (fh_get_mode (w->fh) == MODE_BINARY
+  if (fh_get_mode (w->fh) == FH_MODE_BINARY
       && len < fh_get_record_width (w->fh))
     {
       size_t rec_width = fh_get_record_width (w->fh);
Index: pspp/src/dictionary.c
diff -u pspp/src/dictionary.c:1.32 pspp/src/dictionary.c:1.33
--- pspp/src/dictionary.c:1.32  Tue Nov 22 22:10:25 2005
+++ pspp/src/dictionary.c       Sun Jan 29 02:41:11 2006
@@ -1,5 +1,5 @@
 /* PSPP - computes sample statistics.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
    Written by Ben Pfaff <address@hidden>.
 
    This program is free software; you can redistribute it and/or
@@ -25,6 +25,7 @@
 #include "alloc.h"
 #include "case.h"
 #include "cat.h"
+#include "cat-routines.h"
 #include "error.h"
 #include "hash.h"
 #include "misc.h"
@@ -406,8 +407,9 @@
   return v;
 }
 
-/* Returns nonzero if variable V is in dictionary D. */
-int
+/* Returns true if variable V is in dictionary D,
+   false otherwise. */
+bool
 dict_contains_var (const struct dictionary *d, const struct variable *v)
 {
   assert (d != NULL);
@@ -593,18 +595,18 @@
 
 /* Renames COUNT variables specified in VARS to the names given
    in NEW_NAMES within dictionary D.  If the renaming would
-   result in a duplicate variable name, returns zero and stores a
+   result in a duplicate variable name, returns false and stores a
    name that would be duplicated into *ERR_NAME (if ERR_NAME is
-   non-null).  Otherwise, the renaming is successful, and nonzero
+   non-null).  Otherwise, the renaming is successful, and true
    is returned. */
-int
+bool
 dict_rename_vars (struct dictionary *d,
                   struct variable **vars, char **new_names,
                   size_t count, char **err_name) 
 {
   char **old_names;
   size_t i;
-  int success = 1;
+  bool success = true;
 
   assert (d != NULL);
   assert (count == 0 || vars != NULL);
@@ -649,7 +651,7 @@
               hsh_force_insert (d->name_tab, vars[i]);
             }
 
-          success = 0;
+          success = false;
           goto done;
         }
     }
@@ -807,30 +809,6 @@
     }
 }
 
-/* Copies values from SRC, which represents a case arranged
-   according to dictionary D, to DST, which represents a case
-   arranged according to the dictionary that will be produced by
-   dict_compact_values(D). */
-void
-dict_compact_case (const struct dictionary *d,
-                   struct ccase *dst, const struct ccase *src)
-{
-  size_t i;
-  size_t value_idx;
-
-  value_idx = 0;
-  for (i = 0; i < d->var_cnt; i++) 
-    {
-      struct variable *v = d->var[i];
-
-      if (dict_class_from_id (v->name) != DC_SCRATCH)
-        {
-          case_copy (dst, value_idx, src, v->fv, v->nv);
-          value_idx += v->nv;
-        }
-    }
-}
-
 /* Returns the number of values that would be used by a case if
    dict_compact_values() were called. */
 size_t
@@ -874,6 +852,112 @@
   return idx_to_fv;
 }
 
+/* Returns true if a case for dictionary D would be smaller after
+   compaction, false otherwise.  Compacting a case eliminates
+   "holes" between values and after the last value.  Holes are
+   created by deleting variables (or by scratch variables).
+
+   The return value may differ from whether compacting a case
+   from dictionary D would *change* the case: compaction could
+   rearrange values even if it didn't reduce space
+   requirements. */
+bool
+dict_needs_compaction (const struct dictionary *d) 
+{
+  return dict_get_compacted_value_cnt (d) < dict_get_next_value_idx (d);
+}
+
+/* How to copy a contiguous range of values between cases. */
+struct copy_map
+  {
+    size_t src_idx;             /* Starting value index in source case. */
+    size_t dst_idx;             /* Starting value index in target case. */
+    size_t cnt;                 /* Number of values. */
+  };
+
+/* How to compact a case. */
+struct dict_compactor 
+  {
+    struct copy_map *maps;      /* Array of mappings. */
+    size_t map_cnt;             /* Number of mappings. */
+  };
+
+/* Creates and returns a dict_compactor that can be used to
+   compact cases for dictionary D.
+
+   Compacting a case eliminates "holes" between values and after
+   the last value.  Holes are created by deleting variables (or
+   by scratch variables). */
+struct dict_compactor *
+dict_make_compactor (const struct dictionary *d)
+{
+  struct dict_compactor *compactor;
+  struct copy_map *map;
+  size_t map_allocated;
+  size_t value_idx;
+  size_t i;
+
+  compactor = xmalloc (sizeof *compactor);
+  compactor->maps = NULL;
+  compactor->map_cnt = 0;
+  map_allocated = 0;
+
+  value_idx = 0;
+  map = NULL;
+  for (i = 0; i < d->var_cnt; i++) 
+    {
+      struct variable *v = d->var[i];
+
+      if (dict_class_from_id (v->name) == DC_SCRATCH)
+        continue;
+      if (map != NULL && map->src_idx + map->cnt == v->fv) 
+        map->cnt += v->nv;
+      else 
+        {
+          if (compactor->map_cnt == map_allocated)
+            compactor->maps = x2nrealloc (compactor->maps, &map_allocated,
+                                          sizeof *compactor->maps);
+          map = &compactor->maps[compactor->map_cnt++];
+          map->src_idx = v->fv;
+          map->dst_idx = value_idx;
+          map->cnt = v->nv;
+        }
+      value_idx += v->nv;
+    }
+
+  return compactor;
+}
+
+/* Compacts SRC by copying it to DST according to the scheme in
+   COMPACTOR.
+
+   Compacting a case eliminates "holes" between values and after
+   the last value.  Holes are created by deleting variables (or
+   by scratch variables). */
+void
+dict_compactor_compact (const struct dict_compactor *compactor,
+                        struct ccase *dst, const struct ccase *src) 
+{
+  size_t i;
+
+  for (i = 0; i < compactor->map_cnt; i++) 
+    {
+      const struct copy_map *map = &compactor->maps[i];
+      case_copy (dst, map->dst_idx, src, map->src_idx, map->cnt);
+    }
+}
+
+/* Destroys COMPACTOR. */
+void
+dict_compactor_destroy (struct dict_compactor *compactor) 
+{
+  if (compactor != NULL) 
+    {
+      free (compactor->maps);
+      free (compactor);
+    }
+}
+
 /* Returns the SPLIT FILE vars (see cmd_split_file()).  Call
    dict_get_split_cnt() to determine how many SPLIT FILE vars
    there are.  Returns a null pointer if and only if there are no
@@ -963,9 +1047,9 @@
 }
 
 /* Creates in D a vector named NAME that contains CNT variables
-   VAR (see cmd_vector()).  Returns nonzero if successful, or
-   zero if a vector named NAME already exists in D. */
-int
+   VAR (see cmd_vector()).  Returns true if successful, or
+   false if a vector named NAME already exists in D. */
+bool
 dict_create_vector (struct dictionary *d,
                     const char *name,
                     struct variable **var, size_t cnt) 
@@ -980,7 +1064,7 @@
   assert (cnt > 0);
   
   if (dict_lookup_vector (d, name) != NULL)
-    return 0;
+    return false;
 
   d->vector = xnrealloc (d->vector, d->vector_cnt + 1, sizeof *d->vector);
   vector = d->vector[d->vector_cnt] = xmalloc (sizeof *vector);
@@ -994,7 +1078,7 @@
     }
   vector->cnt = cnt;
   
-  return 1;
+  return true;
 }
 
 /* Returns the vector in D with index IDX, which must be less
Index: pspp/src/dictionary.h
diff -u pspp/src/dictionary.h:1.8 pspp/src/dictionary.h:1.9
--- pspp/src/dictionary.h:1.8   Mon Oct 24 02:51:32 2005
+++ pspp/src/dictionary.h       Sun Jan 29 02:41:11 2006
@@ -20,6 +20,7 @@
 #ifndef DICTIONARY_H
 #define DICTIONARY_H
 
+#include <stdbool.h>
 #include <stddef.h>
 
 /* Dictionary. */ 
@@ -50,7 +51,7 @@
 struct variable *dict_lookup_var (const struct dictionary *, const char *);
 struct variable *dict_lookup_var_assert (const struct dictionary *,
                                          const char *);
-int dict_contains_var (const struct dictionary *, const struct variable *);
+bool dict_contains_var (const struct dictionary *, const struct variable *);
 void dict_delete_var (struct dictionary *, struct variable *);
 void dict_delete_vars (struct dictionary *,
                        struct variable *const *, size_t count);
@@ -60,9 +61,9 @@
 void dict_reorder_vars (struct dictionary *,
                         struct variable *const *, size_t count);
 void dict_rename_var (struct dictionary *, struct variable *, const char *);
-int dict_rename_vars (struct dictionary *,
-                      struct variable **, char **new_names,
-                      size_t count, char **err_name);
+bool dict_rename_vars (struct dictionary *,
+                       struct variable **, char **new_names,
+                       size_t count, char **err_name);
 
 struct ccase;
 struct variable *dict_get_weight (const struct dictionary *);
@@ -80,10 +81,14 @@
 size_t dict_get_case_size (const struct dictionary *);
 
 void dict_compact_values (struct dictionary *);
-void dict_compact_case (const struct dictionary *,
-                        struct ccase *, const struct ccase *);
 size_t dict_get_compacted_value_cnt (const struct dictionary *);
 int *dict_get_compacted_idx_to_fv (const struct dictionary *);
+bool dict_needs_compaction (const struct dictionary *);
+
+struct dict_compactor *dict_make_compactor (const struct dictionary *);
+void dict_compactor_compact (const struct dict_compactor *,
+                             struct ccase *, const struct ccase *);
+void dict_compactor_destroy (struct dict_compactor *);
 
 struct variable *const *dict_get_split_vars (const struct dictionary *);
 size_t dict_get_split_cnt (const struct dictionary *);
@@ -96,9 +101,9 @@
 const char *dict_get_documents (const struct dictionary *);
 void dict_set_documents (struct dictionary *, const char *);
 
-int dict_create_vector (struct dictionary *,
-                        const char *name,
-                        struct variable **, size_t cnt);
+bool dict_create_vector (struct dictionary *,
+                         const char *name,
+                         struct variable **, size_t cnt);
 const struct vector *dict_get_vector (const struct dictionary *,
                                       size_t idx);
 size_t dict_get_vector_cnt (const struct dictionary *);
Index: pspp/src/error.c
diff -u pspp/src/error.c:1.22 pspp/src/error.c:1.23
--- pspp/src/error.c:1.22       Thu Jan 26 05:24:02 2006
+++ pspp/src/error.c    Sun Jan 29 02:41:11 2006
@@ -31,6 +31,7 @@
 #include "main.h"
 #include "output.h"
 #include "progname.h"
+#include "readln.h"
 #include "settings.h"
 #include "str.h"
 #include "var.h"
Index: pspp/src/file-handle-def.c
diff -u pspp/src/file-handle-def.c:1.5 pspp/src/file-handle-def.c:1.6
--- pspp/src/file-handle-def.c:1.5      Tue Jan 24 09:58:18 2006
+++ pspp/src/file-handle-def.c  Sun Jan 29 02:41:11 2006
@@ -1,5 +1,5 @@
 /* PSPP - computes sample statistics.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
    Written by Ben Pfaff <address@hidden>.
 
    This program is free software; you can redistribute it and/or
@@ -18,23 +18,22 @@
    02110-1301, USA. */
 
 #include <config.h>
-#include "file-handle.h"
 #include "file-handle-def.h"
 #include "error.h"
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
 #include "alloc.h"
+#include "file-handle.h"
 #include "filename.h"
 #include "command.h"
 #include "getl.h"
 #include "error.h"
 #include "magic.h"
 #include "var.h"
-#include "file-handle-def.h"
+#include "scratch-handle.h"
 
 #include "gettext.h"
-
 #define _(msgid) gettext (msgid)
 
 /* (headers) */
@@ -43,60 +42,78 @@
 struct file_handle 
   {
     struct file_handle *next;   /* Next in global list. */
+    int open_cnt;               /* 0=not open, otherwise # of openers. */
+    bool deleted;               /* Destroy handle when open_cnt goes to 0? */
+
     char *name;                 /* File handle identifier. */
+    const char *type;           /* If open, type of file. */
+    char open_mode[3];          /* "[rw][se]". */
+    void *aux;                  /* Aux data pointer for owner if any. */
+    enum fh_referent referent;  /* What the file handle refers to. */
+
+    /* FH_REF_FILE only. */
     char *filename;            /* Filename as provided by user. */
     struct file_identity *identity; /* For checking file identity. */
-    struct file_locator where; /* Used for reporting error messages. */
     enum fh_mode mode;         /* File mode. */
+
+    /* FH_REF_FILE and FH_REF_INLINE only. */
     size_t record_width;        /* Length of fixed-format records. */
     size_t tab_width;           /* Tab width, 0=do not expand tabs. */
 
-    int open_cnt;               /* 0=not open, otherwise # of openers. */
-    const char *type;           /* If open, type of file. */
-    char open_mode[3];          /* "[rw][se]". */
-    void *aux;                  /* Aux data pointer for owner if any. */
+    /* FH_REF_SCRATCH only. */
+    struct scratch_handle *sh;  /* Scratch file data. */
   };
 
+/* List of all handles. */
 static struct file_handle *file_handles;
 
+/* Default file handle for DATA LIST, REREAD, REPEATING DATA
+   commands. */
+static struct file_handle *default_handle;
+
+/* The "file" that reads from BEGIN DATA...END DATA. */
+static struct file_handle *inline_file;
+
+static struct file_handle *create_handle (const char *name, enum fh_referent);
+
 /* File handle initialization routine. */
 void 
 fh_init (void)
 {
-  /* Currently nothing to do. */
+  inline_file = create_handle ("INLINE", FH_REF_INLINE);
+  inline_file->record_width = 80;
+  inline_file->tab_width = 8;
 }
 
+/* Free HANDLE and remove it from the global list. */
+static void
+free_handle (struct file_handle *handle) 
+{
+  /* Remove handle from global list. */
+  if (file_handles == handle)
+    file_handles = handle->next;
+  else 
+    {
+      struct file_handle *iter = file_handles;
+      while (iter->next != handle)
+        iter = iter->next;
+      iter->next = handle->next;
+    }
 
-/* Destroy file handle.
-   Normally needed only if a file_handle needs to be re-assigned.
-   Otherwise, just let fh_done clean destroy the handle.
- */
-void 
-fh_free(struct file_handle *fh)
-{
-  if ( !fh->name ) 
-    return ;
-
-  free (fh->name);
-  fh->name = 0;
-  free (fh->filename);
-  fn_free_identity (fh->identity);
-  free (fh);
+  /* Free data. */
+  free (handle->name);
+  free (handle->filename);
+  fn_free_identity (handle->identity);
+  scratch_handle_destroy (handle->sh);
+  free (handle);
 }
 
-
 /* Frees all the file handles. */
 void 
 fh_done (void)
 {
-  struct file_handle *fh, *next;
-  
-  for (fh = file_handles; fh != NULL; fh = next)
-    {
-      next = fh->next;
-      fh_free(fh);
-    }
-  file_handles = NULL;
+  while (file_handles != NULL) 
+    free_handle (file_handles);
 }
 
 /* Returns the handle named HANDLE_NAME, or a null pointer if
@@ -107,7 +124,7 @@
   struct file_handle *iter;
 
   for (iter = file_handles; iter != NULL; iter = iter->next)
-    if (!strcasecmp (handle_name, iter->name))
+    if (!iter->deleted && !strcasecmp (handle_name, iter->name))
       return iter;
   return NULL;
 }
@@ -127,7 +144,9 @@
   if (identity != NULL) 
     {
       for (iter = file_handles; iter != NULL; iter = iter->next)
-        if (iter->identity != NULL
+        if (!iter->deleted
+            && iter->referent == FH_REF_FILE
+            && iter->identity != NULL
             && !fn_compare_file_identities (identity, iter->identity))
           {
             fn_free_identity (identity);
@@ -138,40 +157,69 @@
 
   /* Then check for a file with the same name. */
   for (iter = file_handles; iter != NULL; iter = iter->next)
-    if (!strcmp (filename, iter->filename))
+    if (!iter->deleted
+        && iter->referent == FH_REF_FILE && !strcmp (filename, iter->filename))
       return iter; 
 
   return NULL;
 }
 
-/* Creates and returns a new file handle with the given values
-   and defaults for other values.  Adds the created file handle
-   to the global list. */
-struct file_handle *
-fh_create (const char *handle_name, const char *filename,
-           const struct fh_properties *properties)
+/* Creates a new handle with name HANDLE_NAME that refers to
+   REFERENT.  Links the new handle into the global list.  Returns
+   the new handle.
+
+   The new handle is not fully initialized.  The caller is
+   responsible for completing its initialization. */
+static struct file_handle *
+create_handle (const char *handle_name, enum fh_referent referent) 
 {
-  struct file_handle *handle;
-
-  assert(filename);
-  assert(handle_name);
-
-  /* Create and initialize file handle. */
-  handle = xmalloc (sizeof *handle);
+  struct file_handle *handle = xzalloc (sizeof *handle);
   handle->next = file_handles;
+  handle->open_cnt = 0;
+  handle->deleted = false;
   handle->name = xstrdup (handle_name);
+  handle->type = NULL;
+  handle->aux = NULL;
+  handle->referent = referent;
+  file_handles = handle;
+  return handle;
+}
+
+/* Returns the unique handle of referent type FH_REF_INLINE,
+   which refers to the "inline file" that represents character
+   data in the command file between BEGIN DATA and END DATA. */
+struct file_handle *
+fh_inline_file (void) 
+{
+  return inline_file;
+}
+
+/* Creates a new file handle named HANDLE_NAME, which must not be
+   the name of an existing file handle.  The new handle is
+   associated with file FILENAME and the given PROPERTIES. */
+struct file_handle *
+fh_create_file (const char *handle_name, const char *filename,
+                const struct fh_properties *properties)
+{
+  struct file_handle *handle;
+  assert (fh_from_name (handle_name) == NULL);
+  handle = create_handle (handle_name, FH_REF_FILE);
   handle->filename = xstrdup (filename);
   handle->identity = fn_get_identity (filename);
-  handle->where.filename = handle->filename;
-  handle->where.line_number = 0;
   handle->mode = properties->mode;
   handle->record_width = properties->record_width;
   handle->tab_width = properties->tab_width;
-  handle->open_cnt = 0;
-  handle->type = NULL;
-  handle->aux = NULL;
-  file_handles = handle;
+  return handle;
+}
 
+/* Creates a new file handle named HANDLE_NAME, which must not be
+   the name of an existing file handle.  The new handle is
+   associated with a scratch file (initially empty). */
+struct file_handle *
+fh_create_scratch (const char *handle_name) 
+{
+  struct file_handle *handle = create_handle (handle_name, FH_REF_SCRATCH);
+  handle->sh = NULL;
   return handle;
 }
 
@@ -179,10 +227,31 @@
 const struct fh_properties *
 fh_default_properties (void)
 {
-  static const struct fh_properties default_properties = {MODE_TEXT, 1024, 4};
+  static const struct fh_properties default_properties
+    = {FH_MODE_TEXT, 1024, 4};
   return &default_properties;
 }
 
+/* Deletes FH from the global list of file handles.  Afterward,
+   attempts to search for it will fail.  Unless the file handle
+   is currently open, it will be destroyed; otherwise, it will be
+   destroyed later when it is closed.
+   Normally needed only if a file_handle needs to be re-assigned.
+   Otherwise, just let fh_done() destroy the handle. */
+void 
+fh_free (struct file_handle *handle)
+{
+  if (handle == fh_inline_file () || handle == NULL || handle->deleted)
+    return;
+  handle->deleted = true;
+
+  if (handle == default_handle)
+    default_handle = fh_inline_file ();
+
+  if (handle->open_cnt == 0)
+    free_handle (handle);
+}
+
 /* Returns an English description of MODE,
    which is in the format of the MODE argument to fh_open(). */
 static const char *
@@ -196,6 +265,9 @@
 
 /* Tries to open handle H with the given TYPE and MODE.
 
+   H's referent type must be one of the bits in MASK.  The caller
+   must verify this ahead of time; we simply assert it here.
+
    TYPE is the sort of file, e.g. "system file".  Only one given
    type of access is allowed on a given file handle at once.
    If successful, a reference to TYPE is retained, so it should
@@ -213,9 +285,11 @@
    modes the void * will necessarily be null only if no other
    sharers are active. */
 void **
-fh_open (struct file_handle *h, const char *type, const char *mode) 
+fh_open (struct file_handle *h, enum fh_referent mask UNUSED,
+         const char *type, const char *mode) 
 {
   assert (h != NULL);
+  assert ((fh_get_referent (h) & mask) != 0);
   assert (type != NULL);
   assert (mode != NULL);
   assert (mode[0] == 'r' || mode[0] == 'w');
@@ -227,21 +301,21 @@
       if (strcmp (h->type, type)) 
         {
           msg (SE, _("Can't open %s as a %s because it is "
-                     "already open as a %s"),
+                     "already open as a %s."),
                fh_get_name (h), type, h->type);
           return NULL; 
         }
       else if (strcmp (h->open_mode, mode)) 
         {
           msg (SE, _("Can't open %s as a %s for %s because it is "
-                     "already open for %s"),
+                     "already open for %s."),
                fh_get_name (h), type, mode_name (mode),
                mode_name (h->open_mode));
           return NULL;
         }
       else if (h->open_mode[1] == 'e')
         {
-          msg (SE, _("Can't re-open %s as a %s for %s"),
+          msg (SE, _("Can't re-open %s as a %s for %s."),
                fh_get_name (h), type, mode_name (mode));
           return NULL;
         }
@@ -260,7 +334,11 @@
 /* Closes file handle H, which must have been open for the
    specified TYPE and MODE of access provided to fh_open().
    Returns zero if the file is now closed, nonzero if it is still
-   open due to another reference. */
+   open due to another reference.
+
+   After fh_close() returns zero for a handle, it is unsafe to
+   reference that file handle again in any way, because its
+   storage may have been freed. */
 int
 fh_close (struct file_handle *h, const char *type, const char *mode)
 {
@@ -271,13 +349,23 @@
   assert (mode != NULL);
   assert (!strcmp (mode, h->open_mode));
 
-  h->open_cnt--;
-  if (h->open_cnt == 0) 
+  if (--h->open_cnt == 0) 
     {
       h->type = NULL;
       h->aux = NULL;
+      if (h->deleted)
+        free_handle (h);
+      return 0;
     }
-  return h->open_cnt;
+  return 1;
+}
+
+/* Is the file open?  BEGIN DATA...END DATA uses this to detect
+   whether the inline file is actually in use. */
+bool
+fh_is_open (const struct file_handle *handle) 
+{
+  return handle->open_cnt > 0;
 }
 
 /* Returns the identifier of file HANDLE.  If HANDLE was created
@@ -289,15 +377,21 @@
 const char *
 fh_get_name (const struct file_handle *handle)
 {
-  assert (handle != NULL);
   return handle->name;
 }
 
+/* Returns the type of object that HANDLE refers to. */
+enum fh_referent
+fh_get_referent (const struct file_handle *handle) 
+{
+  return handle->referent;
+}
+
 /* Returns the name of the file associated with HANDLE. */
 const char *
 fh_get_filename (const struct file_handle *handle) 
 {
-  assert (handle != NULL);
+  assert (handle->referent == FH_REF_FILE);
   return handle->filename;
 }
 
@@ -305,7 +399,7 @@
 enum fh_mode
 fh_get_mode (const struct file_handle *handle) 
 {
-  assert (handle != NULL);
+  assert (handle->referent == FH_REF_FILE);
   return handle->mode;
 }
 
@@ -313,16 +407,50 @@
 size_t
 fh_get_record_width (const struct file_handle *handle)
 {
-  assert (handle != NULL);
+  assert (handle->referent & (FH_REF_FILE | FH_REF_INLINE));
   return handle->record_width;
 }
 
 /* Returns the number of characters per tab stop for HANDLE, or
    zero if tabs are not to be expanded.  Applicable only to
-   MODE_TEXT files. */
+   FH_MODE_TEXT files. */
 size_t
 fh_get_tab_width (const struct file_handle *handle) 
 {
-  assert (handle != NULL);
+  assert (handle->referent & (FH_REF_FILE | FH_REF_INLINE));
   return handle->tab_width;
 }
+
+/* Returns the scratch file handle associated with HANDLE.
+   Applicable to only FH_REF_SCRATCH files. */
+struct scratch_handle *
+fh_get_scratch_handle (struct file_handle *handle) 
+{
+  assert (handle->referent == FH_REF_SCRATCH);
+  return handle->sh;
+}
+
+/* Sets SH to be the scratch file handle associated with HANDLE.
+   Applicable to only FH_REF_SCRATCH files. */
+void
+fh_set_scratch_handle (struct file_handle *handle, struct scratch_handle *sh)
+{
+  assert (handle->referent == FH_REF_SCRATCH);
+  handle->sh = sh;
+}
+
+/* Returns the current default handle. */
+struct file_handle *
+fh_get_default_handle (void) 
+{
+  return default_handle ? default_handle : fh_inline_file ();
+}
+
+/* Sets NEW_DEFAULT_HANDLE as the default handle. */
+void
+fh_set_default_handle (struct file_handle *new_default_handle) 
+{
+  assert (new_default_handle == NULL
+          || (new_default_handle->referent & (FH_REF_INLINE | FH_REF_FILE)));
+  default_handle = new_default_handle;
+}
Index: pspp/src/file-handle-def.h
diff -u pspp/src/file-handle-def.h:1.3 pspp/src/file-handle-def.h:1.4
--- pspp/src/file-handle-def.h:1.3      Tue Jan 24 09:58:18 2006
+++ pspp/src/file-handle-def.h  Sun Jan 29 02:41:11 2006
@@ -1,5 +1,5 @@
 /* PSPP - computes sample statistics.
-   Copyright (C) 1997-9, 2000,2005 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2005, 2006 Free Software Foundation, Inc.
    Written by Ben Pfaff <address@hidden>.
 
    This program is free software; you can redistribute it and/or
@@ -20,13 +20,24 @@
 #ifndef FILE_HANDLE_DEF_H
 #define FILE_HANDLE_DEF_H
 
-#include <config.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+/* What a file handle refers to.
+   (Ordinarily only a single value is allowed, but fh_open()
+   and fh_parse() take a mask.) */
+enum fh_referent
+  {
+    FH_REF_FILE = 001,          /* Ordinary file (the most common case). */
+    FH_REF_INLINE = 002,        /* The inline file. */
+    FH_REF_SCRATCH = 004        /* Temporary dataset. */
+  };
 
 /* File modes. */
 enum fh_mode
   {
-    MODE_TEXT,                  /* New-line delimited lines. */
-    MODE_BINARY                 /* Fixed-length records. */
+    FH_MODE_TEXT,               /* New-line delimited lines. */
+    FH_MODE_BINARY              /* Fixed-length records. */
   };
 
 /* Properties of a file handle. */
@@ -41,27 +52,45 @@
 void fh_done (void);
 
 /* Creating file handles. */
-struct file_handle *fh_create (const char *handle_name, 
-                               const char *filename,
-                               const struct fh_properties *);
-/* Destroy file handle */
-void fh_free(struct file_handle *);
-
+struct file_handle *fh_create_file (const char *handle_name,
+                                    const char *filename,
+                                    const struct fh_properties *);
+struct file_handle *fh_create_scratch (const char *handle_name);
 const struct fh_properties *fh_default_properties (void);
 
-/* Finding file handles, based on handle name or filename. */
+/* Delete file handle from global list. */
+void fh_free (struct file_handle *);
+
+/* Finding file handles. */
 struct file_handle *fh_from_name (const char *handle_name);
 struct file_handle *fh_from_filename (const char *filename);
+struct file_handle *fh_inline_file (void);
 
-/* Querying properties of file handles. */
+/* Generic properties of file handles. */
 const char *fh_get_name (const struct file_handle *);
+enum fh_referent fh_get_referent (const struct file_handle *);
+
+/* Properties of FH_REF_FILE file handles. */
 const char *fh_get_filename (const struct file_handle *);
 enum fh_mode fh_get_mode (const struct file_handle *) ;
+
+/* Properties of FH_REF_FILE and FH_REF_INLINE file handles. */
 size_t fh_get_record_width (const struct file_handle *);
 size_t fh_get_tab_width (const struct file_handle *);
 
+/* Properties of FH_REF_SCRATCH file handles. */
+struct scratch_handle *fh_get_scratch_handle (struct file_handle *);
+void fh_set_scratch_handle (struct file_handle *, struct scratch_handle *);
+
 /* Opening and closing file handles. */
-void **fh_open (struct file_handle *, const char *type, const char *mode);
+void **fh_open (struct file_handle *, enum fh_referent mask,
+                const char *type, const char *mode);
 int fh_close (struct file_handle *, const char *type, const char *mode);
+bool fh_is_open (const struct file_handle *);
+
+/* Default file handle for DATA LIST, REREAD, REPEATING DATA
+   commands. */
+struct file_handle *fh_get_default_handle (void);
+void fh_set_default_handle (struct file_handle *);
 
 #endif
Index: pspp/src/file-handle.h
diff -u pspp/src/file-handle.h:1.11 pspp/src/file-handle.h:1.12
--- pspp/src/file-handle.h:1.11 Thu Jan 12 03:39:01 2006
+++ pspp/src/file-handle.h      Sun Jan 29 02:41:11 2006
@@ -22,9 +22,10 @@
 
 /* File handles. */
 
+#include <stdbool.h>
 #include <stddef.h>
 #include "file-handle-def.h"
 
-struct file_handle *fh_parse (void);
+struct file_handle *fh_parse (enum fh_referent);
 
 #endif /* !file_handle.h */
Index: pspp/src/file-handle.q
diff -u pspp/src/file-handle.q:1.25 pspp/src/file-handle.q:1.26
--- pspp/src/file-handle.q:1.25 Thu Jan 12 03:39:01 2006
+++ pspp/src/file-handle.q      Sun Jan 29 02:41:11 2006
@@ -1,5 +1,5 @@
 /* PSPP - computes sample statistics.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
    Written by Ben Pfaff <address@hidden>.
 
    This program is free software; you can redistribute it and/or
@@ -29,6 +29,7 @@
 #include "getl.h"
 #include "error.h"
 #include "magic.h"
+#include "str.h"
 #include "var.h"
 #include "linked-list.h"
 #include "file-handle-def.h"
@@ -44,7 +45,7 @@
      name=string;
      lrecl=integer;
      tabwidth=integer "x>=0" "%s must be nonnegative";
-     mode=mode:!character/image.
+     mode=mode:!character/image/scratch.
 */
 /* (declarations) */
 /* (functions) */
@@ -65,9 +66,9 @@
   handle = fh_from_name (handle_name);
   if (handle != NULL)
     {
-      msg (SE, _("File handle %s already refers to file %s.  "
-                 "File handles cannot be redefined within a session."),
-          handle_name, fh_get_filename(handle));
+      msg (SE, _("File handle %s is already defined.  "
+                 "Use CLOSE FILE HANDLE before redefining a file handle."),
+          handle_name);
       return CMD_FAILURE;
     }
 
@@ -78,28 +79,24 @@
   if (!parse_file_handle (&cmd))
     return CMD_FAILURE;
 
-  if (token != '.')
-    {
-      lex_error (_("expecting end of command"));
-      goto lossage;
-    }
+  if (lex_end_of_command () != CMD_SUCCESS)
+    goto lossage;
 
-  if (cmd.s_name == NULL)
+  if (cmd.s_name == NULL && cmd.mode != FH_SCRATCH)
     {
-      msg (SE, _("The FILE HANDLE required subcommand NAME "
-                "is not present."));
+      lex_sbc_missing ("NAME");
       goto lossage;
     }
 
   switch (cmd.mode)
     {
     case FH_CHARACTER:
-      properties.mode = MODE_TEXT;
+      properties.mode = FH_MODE_TEXT;
       if (cmd.sbc_tabwidth)
         properties.tab_width = cmd.n_tabwidth[0];
       break;
     case FH_IMAGE:
-      properties.mode = MODE_BINARY;
+      properties.mode = FH_MODE_BINARY;
       if (cmd.n_lrecl[0] == NOT_LONG)
         msg (SE, _("Fixed-length records were specified on /RECFORM, but "
                    "record length was not specified on /LRECL.  "
@@ -116,7 +113,10 @@
       assert (0);
     }
 
-  handle = fh_create (handle_name, cmd.s_name, &properties);
+  if (cmd.mode != FH_SCRATCH)
+    fh_create_file (handle_name, cmd.s_name, &properties);
+  else
+    fh_create_scratch (handle_name);
 
   free_file_handle (&cmd);
   return CMD_SUCCESS;
@@ -126,36 +126,85 @@
   return CMD_FAILURE;
 }
 
-/* Parses a file handle name, which may be a filename as a string or
-   a file handle name as an identifier.  Returns the file handle or
-   NULL on failure. */
-struct file_handle *
-fh_parse (void)
+int
+cmd_close_file_handle (void) 
 {
   struct file_handle *handle;
 
-  if (token != T_ID && token != T_STRING)
+  if (!lex_force_id ())
+    return CMD_FAILURE;
+  handle = fh_from_name (tokid);
+  if (handle == NULL)
+    return CMD_FAILURE;
+
+  fh_free (handle);
+
+  return CMD_SUCCESS;
+}
+
+/* Returns the name for REFERENT. */
+static const char *
+referent_name (enum fh_referent referent) 
+{
+  switch (referent) 
     {
-      lex_error (_("expecting a file name or handle name"));
-      return NULL;
+    case FH_REF_FILE:
+      return _("file");
+    case FH_REF_INLINE:
+      return _("inline file");
+    case FH_REF_SCRATCH:
+      return _("scratch file");
+    default:
+      abort ();
     }
+}
 
-  /* Check for named handles first, then go by filename. */
-  handle = NULL;
-  if (token == T_ID) 
-    handle = fh_from_name (tokid);
-  if (handle == NULL)
-    handle = fh_from_filename (ds_c_str (&tokstr));
-  if (handle == NULL) 
-    {
-      char *filename = ds_c_str (&tokstr);
-      char *handle_name = xmalloc (strlen (filename) + 3);
-      sprintf (handle_name, "\"%s\"", filename);
-      handle = fh_create (handle_name, filename, fh_default_properties ());
-      free (handle_name);
+/* Parses a file handle name, which may be a filename as a string
+   or a file handle name as an identifier.  The allowed types of
+   file handle are restricted to those in REFERENT_MASK.  Returns
+   the file handle when successful, a null pointer on failure. */
+struct file_handle *
+fh_parse (enum fh_referent referent_mask)
+{
+  struct file_handle *handle;
+
+  if (lex_match_id ("INLINE")) 
+    handle = fh_inline_file ();
+  else 
+    {
+      if (token != T_ID && token != T_STRING)
+        {
+          lex_error (_("expecting a file name or handle name"));
+          return NULL;
+        }
+
+      handle = NULL;
+      if (token == T_ID) 
+        handle = fh_from_name (tokid);
+      if (handle == NULL) 
+        handle = fh_from_filename (ds_c_str (&tokstr)); 
+      if (handle == NULL)
+        {
+          if (token != T_ID || tokid[0] != '#' || get_syntax () != ENHANCED) 
+            {
+              char *filename = ds_c_str (&tokstr);
+              char *handle_name = xasprintf ("\"%s\"", filename);
+              handle = fh_create_file (handle_name, filename,
+                                       fh_default_properties ());
+              free (handle_name);
+            }
+          else
+            handle = fh_create_scratch (tokid);
+        }
+      lex_get ();
     }
 
-  lex_get ();
+  if (!(fh_get_referent (handle) & referent_mask)) 
+    {
+      msg (SE, _("Handle for %s not allowed here."),
+           referent_name (fh_get_referent (handle)));
+      return NULL;
+    }
 
   return handle;
 }
Index: pspp/src/file-type.c
diff -u pspp/src/file-type.c:1.24 pspp/src/file-type.c:1.25
--- pspp/src/file-type.c:1.24   Thu Nov  3 06:21:46 2005
+++ pspp/src/file-type.c        Sun Jan 29 02:41:11 2006
@@ -103,7 +103,7 @@
 cmd_file_type (void)
 {
   static struct file_type_pgm *fty;     /* FIXME: static? WTF? */
-  struct file_handle *fh = NULL;
+  struct file_handle *fh = fh_inline_file ();
 
   /* Initialize. */
   discard_variables ();
@@ -139,7 +139,7 @@
       if (lex_match_id ("FILE"))
        {
          lex_match ('=');
-         fh = fh_parse ();
+         fh = fh_parse (FH_REF_FILE | FH_REF_INLINE);
          if (fh == NULL)
            goto error;
        }
@@ -279,7 +279,7 @@
   fty->reader = dfm_open_reader (fh);
   if (fty->reader == NULL)
     goto error;
-  default_handle = fh;
+  fh_set_default_handle (fh);
 
   create_col_var (&fty->record);
   if (fty->case_sbc.name[0])
Index: pspp/src/filename.c
diff -u pspp/src/filename.c:1.15 pspp/src/filename.c:1.16
--- pspp/src/filename.c:1.15    Sun Dec 11 02:48:45 2005
+++ pspp/src/filename.c Sun Jan 29 02:41:11 2006
@@ -1,5 +1,5 @@
 /* PSPP - computes sample statistics.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
    Written by Ben Pfaff <address@hidden>.
 
    This program is free software; you can redistribute it and/or
@@ -530,6 +530,18 @@
   abort ();
 }
 #endif
+
+/* Returns the extension part of FILENAME as a malloc()'d string.
+   If FILENAME does not have an extension, returns an empty
+   string. */
+char *
+fn_extension (const char *filename) 
+{
+  const char *extension = strrchr (filename, '.');
+  if (extension == NULL)
+    extension = "";
+  return xstrdup (extension);
+}
 
 #if unix
 /* Returns the current working directory, as a malloc()'d string.
Index: pspp/src/filename.h
diff -u pspp/src/filename.h:1.3 pspp/src/filename.h:1.4
--- pspp/src/filename.h:1.3     Fri Apr 29 01:02:14 2005
+++ pspp/src/filename.h Sun Jan 29 02:41:11 2006
@@ -35,6 +35,7 @@
 char *fn_normalize (const char *fn);
 char *fn_dirname (const char *fn);
 char *fn_basename (const char *fn);
+char *fn_extension (const char *fn);
 
 char *fn_get_cwd (void);
 
Index: pspp/src/get.c
diff -u pspp/src/get.c:1.42 pspp/src/get.c:1.43
--- pspp/src/get.c:1.42 Thu Jan 12 03:39:01 2006
+++ pspp/src/get.c      Sun Jan 29 02:41:11 2006
@@ -1,5 +1,5 @@
 /* PSPP - computes sample statistics.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
    Written by Ben Pfaff <address@hidden>.
 
    This program is free software; you can redistribute it and/or
@@ -21,6 +21,8 @@
 #include "error.h"
 #include <stdlib.h>
 #include "alloc.h"
+#include "any-reader.h"
+#include "any-writer.h"
 #include "case.h"
 #include "command.h"
 #include "dictionary.h"
@@ -29,10 +31,8 @@
 #include "hash.h"
 #include "lexer.h"
 #include "misc.h"
-#include "pfm-read.h"
 #include "pfm-write.h"
 #include "settings.h"
-#include "sfm-read.h"
 #include "sfm-write.h"
 #include "str.h"
 #include "value-labels.h"
@@ -52,116 +52,147 @@
                       const struct ccase *, struct ccase *);
 static void destroy_case_map (struct case_map *);
 
-/* Operation type. */
-enum operation 
+static bool parse_dict_trim (struct dictionary *);
+
+/* Reading system and portable files. */
+
+/* Type of command. */
+enum reader_command 
   {
-    OP_READ,    /* GET or IMPORT. */
-    OP_SAVE,    /* SAVE or XSAVE. */
-    OP_EXPORT   /* EXPORT. */
+    GET_CMD,
+    IMPORT_CMD
   };
 
-static bool parse_dict_trim (struct dictionary *);
-
-/* GET input program. */
-struct get_pgm 
+/* Case reader input program. */
+struct case_reader_pgm 
   {
-    struct sfm_reader *reader;  /* System file reader. */
-    struct case_map *map;       /* Map from system file to active file dict. */
+    struct any_reader *reader;  /* File reader. */
+    struct case_map *map;       /* Map from file dict to active file dict. */
     struct ccase bounce;        /* Bounce buffer. */
   };
 
-static void get_pgm_free (struct get_pgm *);
+static const struct case_source_class case_reader_source_class;
 
-/* Parses the GET command. */
-int
-cmd_get (void)
+static void case_reader_pgm_free (struct case_reader_pgm *);
+
+/* Parses a GET or IMPORT command. */
+static int
+parse_read_command (enum reader_command type)
 {
-  struct get_pgm *pgm = NULL;
-  struct file_handle *fh;
+  struct case_reader_pgm *pgm = NULL;
+  struct file_handle *fh = NULL;
   struct dictionary *dict = NULL;
 
-  pgm = xmalloc (sizeof *pgm);
-  pgm->reader = NULL;
-  pgm->map = NULL;
-  case_nullify (&pgm->bounce);
+  for (;;)
+    {
+      lex_match ('/');
 
-  discard_variables ();
+      if (lex_match_id ("FILE") || token == T_STRING)
+       {
+         lex_match ('=');
 
-  lex_match ('/');
-  if (lex_match_id ("FILE"))
-    lex_match ('=');
-  fh = fh_parse ();
-  if (fh == NULL)
-    goto error;
+         fh = fh_parse (FH_REF_FILE | FH_REF_SCRATCH);
+         if (fh == NULL)
+            goto error;
+       }
+      else if (type == IMPORT_CMD && lex_match_id ("TYPE"))
+       {
+         lex_match ('=');
 
-  pgm->reader = sfm_open_reader (fh, &dict, NULL);
+         if (lex_match_id ("COMM"))
+           type = PFM_COMM;
+         else if (lex_match_id ("TAPE"))
+           type = PFM_TAPE;
+         else
+           {
+             lex_error (_("expecting COMM or TAPE"));
+              goto error;
+           }
+       }
+      else
+        break; 
+    }
+  
+  if (fh == NULL) 
+    {
+      lex_sbc_missing ("FILE");
+      goto error;
+    }
+              
+  discard_variables ();
+
+  pgm = xmalloc (sizeof *pgm);
+  pgm->reader = any_reader_open (fh, &dict);
+  pgm->map = NULL;
+  case_nullify (&pgm->bounce);
   if (pgm->reader == NULL)
     goto error;
-  case_create (&pgm->bounce, dict_get_next_value_idx (dict));
 
+  case_create (&pgm->bounce, dict_get_next_value_idx (dict));
+  
   start_case_map (dict);
-  while (lex_match ('/'))
-    if (!parse_dict_trim (dict))
-      goto error;
 
-  if (!lex_end_of_command ())
-    return false;
+  while (token != '.')
+    {
+      lex_match ('/');
+      if (!parse_dict_trim (dict))
+        goto error;
+    }
 
-  dict_compact_values (dict);
   pgm->map = finish_case_map (dict);
-
+  
   dict_destroy (default_dict);
   default_dict = dict;
 
-  vfm_source = create_case_source (&get_source_class, pgm);
+  vfm_source = create_case_source (&case_reader_source_class, pgm);
 
   return CMD_SUCCESS;
 
  error:
-  get_pgm_free (pgm);
-  if (dict != NULL) 
+  case_reader_pgm_free (pgm);
+  if (dict != NULL)
     dict_destroy (dict);
   return CMD_FAILURE;
 }
 
-/* Frees a struct get_pgm. */
+/* Frees a struct case_reader_pgm. */
 static void
-get_pgm_free (struct get_pgm *pgm) 
+case_reader_pgm_free (struct case_reader_pgm *pgm) 
 {
   if (pgm != NULL) 
     {
-      sfm_close_reader (pgm->reader);
+      any_reader_close (pgm->reader);
       destroy_case_map (pgm->map);
       case_destroy (&pgm->bounce);
       free (pgm);
     }
 }
 
-/* Clears internal state related to GET input procedure. */
+/* Clears internal state related to case reader input procedure. */
 static void
-get_source_destroy (struct case_source *source)
+case_reader_source_destroy (struct case_source *source)
 {
-  struct get_pgm *pgm = source->aux;
-  get_pgm_free (pgm);
+  struct case_reader_pgm *pgm = source->aux;
+  case_reader_pgm_free (pgm);
 }
 
 /* Reads all the cases from the data file into C and passes them
    to WRITE_CASE one by one, passing WC_DATA. */
 static void
-get_source_read (struct case_source *source,
-                 struct ccase *c,
-                 write_case_func *write_case, write_case_data wc_data)
+case_reader_source_read (struct case_source *source,
+                    struct ccase *c,
+                    write_case_func *write_case, write_case_data wc_data)
 {
-  struct get_pgm *pgm = source->aux;
+  struct case_reader_pgm *pgm = source->aux;
   int ok;
 
   do
     {
       if (pgm->map == NULL)
-        ok = sfm_read_case (pgm->reader, c);
+        ok = any_reader_read (pgm->reader, c);
       else
         {
-          ok = sfm_read_case (pgm->reader, &pgm->bounce);
+          ok = any_reader_read (pgm->reader, &pgm->bounce);
           if (ok)
             map_case (pgm->map, &pgm->bounce, c);
         }
@@ -172,14 +203,30 @@
   while (ok);
 }
 
-const struct case_source_class get_source_class =
+static const struct case_source_class case_reader_source_class =
   {
-    "GET",
+    "case reader",
     NULL,
-    get_source_read,
-    get_source_destroy,
+    case_reader_source_read,
+    case_reader_source_destroy,
   };
 
+/* GET. */
+int
+cmd_get (void) 
+{
+  return parse_read_command (GET_CMD);
+}
+
+/* IMPORT. */
+int
+cmd_import (void) 
+{
+  return parse_read_command (IMPORT_CMD);
+}
+
+/* Writing system and portable files. */ 
+
 /* Type of output file. */
 enum writer_type
   {
@@ -194,11 +241,10 @@
     PROC_CMD            /* Procedure. */
   };
 
-/* Portable or system file writer plus a case map. */
-struct any_writer
+/* File writer plus a case map. */
+struct case_writer
   {
-    enum writer_type writer_type;
-    void *writer;
+    struct any_writer *writer;  /* File writer. */
     struct case_map *map;       /* Map to output file dictionary
                                    (null pointer for identity mapping). */
     struct ccase bounce;        /* Bounce buffer for mapping (if needed). */
@@ -206,19 +252,11 @@
 
 /* Destroys AW. */
 static void
-any_writer_destroy (struct any_writer *aw)
+case_writer_destroy (struct case_writer *aw)
 {
   if (aw != NULL) 
     {
-      switch (aw->writer_type) 
-        {
-        case PORFILE_WRITER:
-          pfm_close_writer (aw->writer);
-          break;
-        case SYSFILE_WRITER:
-          sfm_close_writer (aw->writer);
-          break;
-        }
+      any_writer_close (aw->writer);
       destroy_case_map (aw->map);
       case_destroy (&aw->bounce);
       free (aw);
@@ -235,7 +273,7 @@
    included.
 
    On failure, returns a null pointer. */
-static struct any_writer *
+static struct case_writer *
 parse_write_command (enum writer_type writer_type,
                      enum command_type command_type,
                      bool *retain_unselected)
@@ -243,7 +281,7 @@
   /* Common data. */
   struct file_handle *handle; /* Output file. */
   struct dictionary *dict;    /* Dictionary for output file. */
-  struct any_writer *aw;      /* Writer. */  
+  struct case_writer *aw;      /* Writer. */  
 
   /* Common options. */
   bool print_map;             /* Print map?  TODO. */
@@ -261,7 +299,6 @@
   handle = NULL;
   dict = dict_clone (default_dict);
   aw = xmalloc (sizeof *aw);
-  aw->writer_type = writer_type;
   aw->writer = NULL;
   aw->map = NULL;
   case_nullify (&aw->bounce);
@@ -286,7 +323,7 @@
           
          lex_match ('=');
       
-         handle = fh_parse ();
+         handle = fh_parse (FH_REF_FILE | FH_REF_SCRATCH);
          if (handle == NULL)
            goto error;
        }
@@ -374,45 +411,42 @@
   if (aw->map != NULL)
     case_create (&aw->bounce, dict_get_next_value_idx (dict));
 
-  switch (writer_type) 
+  if (fh_get_referent (handle) == FH_REF_FILE) 
     {
-    case SYSFILE_WRITER:
-      aw->writer = sfm_open_writer (handle, dict, sysfile_opts);
-      break;
-    case PORFILE_WRITER:
-      aw->writer = pfm_open_writer (handle, dict, porfile_opts);
-      break;
+      switch (writer_type) 
+        {
+        case SYSFILE_WRITER:
+          aw->writer = any_writer_from_sfm_writer (
+            sfm_open_writer (handle, dict, sysfile_opts));
+          break;
+        case PORFILE_WRITER:
+          aw->writer = any_writer_from_pfm_writer (
+            pfm_open_writer (handle, dict, porfile_opts));
+          break;
+        }
     }
-
+  else
+    aw->writer = any_writer_open (handle, dict);
   dict_destroy (dict);
   
   return aw;
 
  error:
-  any_writer_destroy (aw);
+  case_writer_destroy (aw);
   dict_destroy (dict);
   return NULL;
 }
 
 /* Writes case C to writer AW. */
 static void
-any_writer_write_case (struct any_writer *aw, struct ccase *c) 
+case_writer_write_case (struct case_writer *aw, struct ccase *c) 
 {
   if (aw->map != NULL) 
     {
       map_case (aw->map, c, &aw->bounce);
       c = &aw->bounce; 
     }
-  
-  switch (aw->writer_type) 
-    {
-    case SYSFILE_WRITER:
-      sfm_write_case (aw->writer, c);
-      break;
-    case PORFILE_WRITER:
-      pfm_write_case (aw->writer, c);
-      break;
-    }
+  any_writer_write (aw->writer, c);
 }
 
 /* SAVE and EXPORT. */
@@ -425,7 +459,7 @@
 {
   bool retain_unselected;
   struct variable *saved_filter_variable;
-  struct any_writer *aw;
+  struct case_writer *aw;
 
   aw = parse_write_command (writer_type, PROC_CMD, &retain_unselected);
   if (aw == NULL) 
@@ -437,7 +471,7 @@
   procedure (output_proc, aw);
   dict_set_filter (default_dict, saved_filter_variable);
 
-  any_writer_destroy (aw);
+  case_writer_destroy (aw);
   return CMD_SUCCESS;
 }
 
@@ -445,8 +479,8 @@
 static int
 output_proc (struct ccase *c, void *aw_) 
 {
-  struct any_writer *aw = aw_;
-  any_writer_write_case (aw, c);
+  struct case_writer *aw = aw_;
+  case_writer_write_case (aw, c);
   return 0;
 }
 
@@ -467,7 +501,7 @@
 /* Transformation. */
 struct output_trns 
   {
-    struct any_writer *aw;      /* Writer. */
+    struct case_writer *aw;      /* Writer. */
   };
 
 static trns_proc_func output_trns_proc;
@@ -494,7 +528,7 @@
 output_trns_proc (void *trns_, struct ccase *c, int case_num UNUSED)
 {
   struct output_trns *t = trns_;
-  any_writer_write_case (t->aw, c);
+  case_writer_write_case (t->aw, c);
   return -1;
 }
 
@@ -506,7 +540,7 @@
 
   if (t != NULL)
     {
-      any_writer_destroy (t->aw);
+      case_writer_destroy (t->aw);
       free (t);
     }
 }
@@ -709,7 +743,7 @@
     int type;                  /* One of MTF_*. */
     struct variable **by;      /* List of BY variables for this file. */
     struct file_handle *handle; /* File handle. */
-    struct sfm_reader *reader;  /* System file reader. */
+    struct any_reader *reader;  /* File reader. */
     struct dictionary *dict;   /* Dictionary from system file. */
 
     /* IN subcommand. */
@@ -859,11 +893,11 @@
         }
       else
         {
-          file->handle = fh_parse ();
+          file->handle = fh_parse (FH_REF_FILE | FH_REF_SCRATCH);
           if (file->handle == NULL)
             goto error;
 
-          file->reader = sfm_open_reader (file->handle, &file->dict, NULL);
+          file->reader = any_reader_open (file->handle, &file->dict);
           if (file->reader == NULL)
             goto error;
 
@@ -1151,7 +1185,7 @@
 mtf_free_file (struct mtf_file *file)
 {
   free (file->by);
-  sfm_close_reader (file->reader);
+  any_reader_close (file->reader);
   if (file->dict != default_dict)
     dict_destroy (file->dict);
   case_destroy (&file->input);
@@ -1225,7 +1259,7 @@
   for (iter = mtf->head; iter != NULL; iter = next)
     {
       next = iter->next;
-      if (iter->handle && !sfm_read_case (iter->reader, &iter->input))
+      if (iter->handle && !any_reader_read (iter->reader, &iter->input))
         mtf_delete_file_in_place (mtf, &iter);
     }
 }
@@ -1323,7 +1357,7 @@
                 {
                   if (iter->handle == NULL)
                     return 1;
-                  if (sfm_read_case (iter->reader, &iter->input))
+                  if (any_reader_read (iter->reader, &iter->input))
                     continue;
                   mtf_delete_file_in_place (mtf, &iter);
                 }
@@ -1405,7 +1439,7 @@
        {
          next = iter->next_min;
          if (iter->reader != NULL
-              && !sfm_read_case (iter->reader, &iter->input))
+              && !any_reader_read (iter->reader, &iter->input))
             mtf_delete_file_in_place (mtf, &iter);
        }
     }
@@ -1500,162 +1534,6 @@
   return v->aux;
 }
 
-/* IMPORT command. */
-
-/* IMPORT input program. */
-struct import_pgm 
-  {
-    struct pfm_reader *reader;  /* Portable file reader. */
-    struct case_map *map;       /* Map from system file to active file dict. */
-    struct ccase bounce;        /* Bounce buffer. */
-  };
-
-static void import_pgm_free (struct import_pgm *);
-
-/* Parses the IMPORT command. */
-int
-cmd_import (void)
-{
-  struct import_pgm *pgm = NULL;
-  struct file_handle *fh = NULL;
-  struct dictionary *dict = NULL;
-  enum pfm_type type;
-
-  lex_match ('/');
-  for (;;)
-    {
-      if (pgm == NULL && (lex_match_id ("FILE") || token == T_STRING))
-       {
-         lex_match ('=');
-
-         fh = fh_parse ();
-         if (fh == NULL)
-            goto error;
-       }
-      else if (pgm == NULL && lex_match_id ("TYPE"))
-       {
-         lex_match ('=');
-
-         if (lex_match_id ("COMM"))
-           type = PFM_COMM;
-         else if (lex_match_id ("TAPE"))
-           type = PFM_TAPE;
-         else
-           {
-             lex_error (_("expecting COMM or TAPE"));
-              goto error;
-           }
-       }
-      else 
-        {
-          if (pgm == NULL) 
-            {
-              if (fh == NULL) 
-                {
-                  lex_sbc_missing ("FILE");
-                  goto error;
-                }
-              
-              discard_variables ();
-
-              pgm = xmalloc (sizeof *pgm);
-              pgm->reader = pfm_open_reader (fh, &dict, NULL);
-              pgm->map = NULL;
-              case_nullify (&pgm->bounce);
-              if (pgm->reader == NULL)
-                goto error;
-
-              case_create (&pgm->bounce, dict_get_next_value_idx (dict));
-  
-              start_case_map (dict);
-            }
-
-          if (token == '.')
-            break;
-          
-          if (!parse_dict_trim (dict))
-            goto error;
-        }
-
-      lex_match ('/');
-    }
-  if (pgm == NULL) 
-    {
-      lex_error (NULL);
-      goto error;
-    }
-
-  pgm->map = finish_case_map (dict);
-  
-  dict_destroy (default_dict);
-  default_dict = dict;
-
-  vfm_source = create_case_source (&import_source_class, pgm);
-
-  return CMD_SUCCESS;
-
- error:
-  import_pgm_free (pgm);
-  if (dict != NULL)
-    dict_destroy (dict);
-  return CMD_FAILURE;
-}
-
-/* Frees a struct import_pgm. */
-static void
-import_pgm_free (struct import_pgm *pgm) 
-{
-  if (pgm != NULL) 
-    {
-      pfm_close_reader (pgm->reader);
-      destroy_case_map (pgm->map);
-      case_destroy (&pgm->bounce);
-      free (pgm);
-    }
-}
-
-/* Clears internal state related to IMPORT input procedure. */
-static void
-import_source_destroy (struct case_source *source)
-{
-  struct import_pgm *pgm = source->aux;
-  import_pgm_free (pgm);
-}
-
-/* Reads all the cases from the data file into C and passes them
-   to WRITE_CASE one by one, passing WC_DATA. */
-static void
-import_source_read (struct case_source *source,
-                 struct ccase *c,
-                 write_case_func *write_case, write_case_data wc_data)
-{
-  struct import_pgm *pgm = source->aux;
-  int ok;
-
-  do
-    {
-      if (pgm->map == NULL)
-        ok = pfm_read_case (pgm->reader, c);
-      else
-        {
-          ok = pfm_read_case (pgm->reader, &pgm->bounce);
-          if (ok)
-            map_case (pgm->map, &pgm->bounce, c);
-        }
-
-      if (ok)
-        ok = write_case (wc_data);
-    }
-  while (ok);
-}
-
-const struct case_source_class import_source_class =
-  {
-    "IMPORT",
-    NULL,
-    import_source_read,
-    import_source_destroy,
-  };
 
 
 /* Case map.
Index: pspp/src/glob.c
diff -u pspp/src/glob.c:1.33 pspp/src/glob.c:1.34
--- pspp/src/glob.c:1.33        Wed Dec 14 06:59:06 2005
+++ pspp/src/glob.c     Sun Jan 29 02:41:11 2006
@@ -31,8 +31,6 @@
 size_t n_trns, m_trns, f_trns;
 
 int FILTER_before_TEMPORARY;
-
-struct file_handle *default_handle;
 
 /* Functions. */
 
Index: pspp/src/inpt-pgm.c
diff -u pspp/src/inpt-pgm.c:1.22 pspp/src/inpt-pgm.c:1.23
--- pspp/src/inpt-pgm.c:1.22    Thu Nov  3 06:21:46 2005
+++ pspp/src/inpt-pgm.c Sun Jan 29 02:41:11 2006
@@ -317,7 +317,7 @@
   struct expression *e;         /* Expression for column to set. */
   struct reread_trns *t;        /* Created transformation. */
 
-  fh = default_handle;
+  fh = fh_get_default_handle ();
   e = NULL;
   while (token != '.')
     {
@@ -339,7 +339,7 @@
       else if (lex_match_id ("FILE"))
        {
          lex_match ('=');
-          fh = fh_parse ();
+          fh = fh_parse (FH_REF_FILE | FH_REF_INLINE);
          if (fh == NULL)
            {
              expr_free (e);
Index: pspp/src/matrix-data.c
diff -u pspp/src/matrix-data.c:1.34 pspp/src/matrix-data.c:1.35
--- pspp/src/matrix-data.c:1.34 Sat Oct 29 05:50:06 2005
+++ pspp/src/matrix-data.c      Sun Jan 29 02:41:11 2006
@@ -172,7 +172,7 @@
 {
   struct pool *pool;
   struct matrix_data_pgm *mx;
-  struct file_handle *fh = NULL;
+  struct file_handle *fh = fh_inline_file ();
     
   unsigned seen = 0;
   
@@ -258,7 +258,7 @@
       else if (lex_match_id ("FILE"))
        {
          lex_match ('=');
-         fh = fh_parse ();
+         fh = fh_parse (FH_REF_FILE | FH_REF_INLINE);
          if (fh == NULL)
            goto lossage;
        }
Index: pspp/src/pfm-read.c
diff -u pspp/src/pfm-read.c:1.30 pspp/src/pfm-read.c:1.31
--- pspp/src/pfm-read.c:1.30    Thu Jan 12 03:39:01 2006
+++ pspp/src/pfm-read.c Sun Jan 29 02:41:11 2006
@@ -1,5 +1,5 @@
 /* PSPP - computes sample statistics.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
    Written by Ben Pfaff <address@hidden>.
    Code for parsing floating-point numbers adapted from GNU C
    library.
@@ -49,6 +49,16 @@
 
 #include "debug-print.h"
 
+/* portable_to_local[PORTABLE] translates the given portable
+   character into the local character set. */
+static const char portable_to_local[256] =
+  {
+    "                                                                "
+    "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ."
+    "<(+|&[]!$*);^-/|,%_>?`:$@'=\"      ~-   0123456789   -() {}\\     "
+    "                                                                "
+  };
+
 /* Portable file reader. */
 struct pfm_reader
   {
@@ -149,7 +159,7 @@
   struct pfm_reader *volatile r = NULL;
 
   *dict = dict_create ();
-  if (!fh_open (fh, "portable file", "rs"))
+  if (!fh_open (fh, FH_REF_FILE, "portable file", "rs"))
     goto error;
 
   /* Create and initialize reader. */
@@ -353,16 +363,6 @@
 static void
 read_header (struct pfm_reader *r)
 {
-  /* portable_to_local[PORTABLE] translates the given portable
-     character into the local character set. */
-  static const char portable_to_local[256] =
-    {
-      "                                                                "
-      "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ."
-      "<(+|&[]!$*);^-/|,%_>?`:$@'=\"      ~-   0123456789   -() {}\\     "
-      "                                                                "
-    };
-
   char *trans;
   int i;
 
@@ -687,3 +687,38 @@
   
   return true;
 }
+
+/* Returns true if FILE is an SPSS portable file,
+   false otherwise. */
+bool
+pfm_detect (FILE *file) 
+{
+  unsigned char header[464];
+  char trans[256];
+  int cooked_cnt, raw_cnt;
+  int i;
+
+  cooked_cnt = raw_cnt = 0;
+  while (cooked_cnt < sizeof header)
+    {
+      int c = getc (file);
+      if (c == EOF || raw_cnt++ > 512)
+        return false;
+      else if (c != '\n' && c != '\r') 
+        header[cooked_cnt++] = c;
+    }
+
+  memset (trans, 0, 256);
+  for (i = 64; i < 256; i++) 
+    {
+      unsigned char c = header[i + 200];
+      if (trans[c] == 0)
+        trans[c] = portable_to_local[i];
+    }
+
+  for (i = 0; i < 8; i++) 
+    if (trans[header[i + 456]] != "SPSSPORT"[i]) 
+      return false; 
+
+  return true;
+}
Index: pspp/src/pfm-read.h
diff -u pspp/src/pfm-read.h:1.5 pspp/src/pfm-read.h:1.6
--- pspp/src/pfm-read.h:1.5     Sun Aug 21 07:21:06 2005
+++ pspp/src/pfm-read.h Sun Jan 29 02:41:11 2006
@@ -23,6 +23,7 @@
 /* Portable file reading. */
 
 #include <stdbool.h>
+#include <stdio.h>
 
 /* Information produced by pfm_read_dictionary() that doesn't fit into
    a dictionary struct. */
@@ -42,5 +43,6 @@
                                     struct pfm_read_info *);
 bool pfm_read_case (struct pfm_reader *, struct ccase *);
 void pfm_close_reader (struct pfm_reader *);
+bool pfm_detect (FILE *);
 
 #endif /* pfm-read.h */
Index: pspp/src/pfm-write.c
diff -u pspp/src/pfm-write.c:1.20 pspp/src/pfm-write.c:1.21
--- pspp/src/pfm-write.c:1.20   Thu Jan 12 03:39:01 2006
+++ pspp/src/pfm-write.c        Sun Jan 29 02:41:11 2006
@@ -111,7 +111,7 @@
     goto open_error;
 
   /* Open file handle. */
-  if (!fh_open (fh, "portable file", "we"))
+  if (!fh_open (fh, FH_REF_FILE, "portable file", "we"))
     goto error;
 
   /* Initialize data structures. */
@@ -420,7 +420,7 @@
 /* Writes case ELEM to the portable file represented by H.  Returns
    success. */
 int 
-pfm_write_case (struct pfm_writer *w, struct ccase *c)
+pfm_write_case (struct pfm_writer *w, const struct ccase *c)
 {
   int i;
   
@@ -451,8 +451,6 @@
   if (w == NULL)
     return;
 
-  fh_close (w->fh, "portable file", "we");
-  
   if (w->file != NULL)
     {
       char buf[80];
@@ -469,6 +467,8 @@
              fh_get_filename (w->fh), strerror (errno));
     }
 
+  fh_close (w->fh, "portable file", "we");
+  
   free (w->vars);
   free (w);
 }
Index: pspp/src/pfm-write.h
diff -u pspp/src/pfm-write.h:1.4 pspp/src/pfm-write.h:1.5
--- pspp/src/pfm-write.h:1.4    Sun Aug 21 07:21:06 2005
+++ pspp/src/pfm-write.h        Sun Jan 29 02:41:11 2006
@@ -46,7 +46,7 @@
                                     struct pfm_write_options);
 struct pfm_write_options pfm_writer_default_options (void);
 
-int pfm_write_case (struct pfm_writer *, struct ccase *);
+int pfm_write_case (struct pfm_writer *, const struct ccase *);
 void pfm_close_writer (struct pfm_writer *);
 
 #endif /* pfm-write.h */
Index: pspp/src/print.c
diff -u pspp/src/print.c:1.24 pspp/src/print.c:1.25
--- pspp/src/print.c:1.24       Thu Jan 12 03:39:01 2006
+++ pspp/src/print.c    Sun Jan 29 02:41:11 2006
@@ -156,7 +156,7 @@
        {
          lex_match ('=');
 
-         fh = fh_parse ();
+         fh = fh_parse (FH_REF_FILE);
          if (fh == NULL)
            goto error;
        }
@@ -191,7 +191,7 @@
       if (prt.writer == NULL)
         goto error;
 
-      if (fh_get_mode (fh) == MODE_BINARY)
+      if (fh_get_mode (fh) == FH_MODE_BINARY)
         prt.options |= PRT_BINARY;
     }
 
@@ -836,10 +836,12 @@
       }
 
   if (fh != NULL)
-    tab_title (t, 1, _("Writing %d record(s) to file %s."),
-               recno, fh_get_filename (fh));
+    tab_title (t, 1, ngettext ("Writing %d record to %s.",
+                               "Writing %d records to %s.", recno),
+               recno, fh_get_name (fh));
   else
-    tab_title (t, 1, _("Writing %d record(s) to the listing file."), recno);
+    tab_title (t, 1, ngettext ("Writing %d record.",
+                               "Writing %d records.", recno), recno);
   tab_submit (t);
 }
 
@@ -1027,7 +1029,7 @@
     {
       lex_match ('=');
 
-      fh = fh_parse ();
+      fh = fh_parse (FH_REF_FILE);
       if (fh == NULL)
        return CMD_FAILURE;
       lex_get ();
Index: pspp/src/regression.q
diff -u pspp/src/regression.q:1.36 pspp/src/regression.q:1.37
--- pspp/src/regression.q:1.36  Thu Jan 12 03:39:01 2006
+++ pspp/src/regression.q       Sun Jan 29 02:41:11 2006
@@ -687,7 +687,7 @@
     model_file = NULL;
   else
     {
-      model_file = fh_parse ();
+      model_file = fh_parse (FH_REF_FILE);
       if (model_file == NULL)
        return 0;
     }
Index: pspp/src/sfm-read.c
diff -u pspp/src/sfm-read.c:1.28 pspp/src/sfm-read.c:1.29
--- pspp/src/sfm-read.c:1.28    Thu Jan 12 03:39:01 2006
+++ pspp/src/sfm-read.c Sun Jan 29 02:41:11 2006
@@ -1,5 +1,5 @@
 /* PSPP - computes sample statistics.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
    Written by Ben Pfaff <address@hidden>.
 
    This program is free software; you can redistribute it and/or
@@ -143,15 +143,17 @@
   if (r == NULL)
     return;
 
+  if (r->file)
+    {
+      if (fn_close (fh_get_filename (r->fh), r->file) == EOF)
+        msg (ME, _("%s: Closing system file: %s."),
+             fh_get_filename (r->fh), strerror (errno));
+      r->file = NULL;
+    }
+
   if (r->fh != NULL)
     fh_close (r->fh, "system file", "rs");
   
-  if ( r->file ) {
-    if (fn_close (fh_get_filename (r->fh), r->file) == EOF)
-      msg (ME, _("%s: Closing system file: %s."),
-          fh_get_filename (r->fh), strerror (errno));
-    r->file = NULL;
-  }
   free (r->vars);
   free (r->buf);
   free (r);
@@ -206,7 +208,7 @@
   struct variable **var_by_idx = NULL;
 
   *dict = dict_create ();
-  if (!fh_open (fh, "system file", "rs"))
+  if (!fh_open (fh, FH_REF_FILE, "system file", "rs"))
     goto error;
 
   /* Create and initialize reader. */
@@ -1524,3 +1526,17 @@
       return 0;
     }
 }
+
+/* Returns true if FILE is an SPSS system file,
+   false otherwise. */
+bool
+sfm_detect (FILE *file) 
+{
+  struct sysfile_header hdr;
+
+  if (fread (&hdr, sizeof hdr, 1, file) != 1)
+    return false;
+  if (strncmp ("$FL2", hdr.rec_type, 4))
+    return false;
+  return true; 
+}
Index: pspp/src/sfm-read.h
diff -u pspp/src/sfm-read.h:1.2 pspp/src/sfm-read.h:1.3
--- pspp/src/sfm-read.h:1.2     Fri Apr 29 01:02:15 2005
+++ pspp/src/sfm-read.h Sun Jan 29 02:41:11 2006
@@ -20,6 +20,9 @@
 #ifndef SFM_READ_H
 #define SFM_READ_H 1
 
+#include <stdbool.h>
+#include <stdio.h>
+
 /* Reading system files. */
 
 /* System file info that doesn't fit in struct dictionary. */
@@ -41,5 +44,6 @@
                                     struct sfm_read_info *);
 int sfm_read_case (struct sfm_reader *, struct ccase *);
 void sfm_close_reader (struct sfm_reader *);
+bool sfm_detect (FILE *);
 
 #endif /* sfm-read.h */
Index: pspp/src/sfm-write.c
diff -u pspp/src/sfm-write.c:1.24 pspp/src/sfm-write.c:1.25
--- pspp/src/sfm-write.c:1.24   Tue Jan 24 09:58:18 2006
+++ pspp/src/sfm-write.c        Sun Jan 29 02:41:11 2006
@@ -156,7 +156,7 @@
     goto open_error;
 
   /* Open file handle. */
-  if (!fh_open (fh, "system file", "we"))
+  if (!fh_open (fh, FH_REF_FILE, "system file", "we"))
     goto error;
 
   /* Create and initialize writer. */
@@ -904,8 +904,6 @@
   if (w == NULL)
     return;
 
-  fh_close (w->fh, "system file", "we");
-  
   if (w->file != NULL) 
     {
       /* Flush buffer. */
@@ -932,6 +930,8 @@
              fh_get_filename (w->fh), strerror (errno));
     }
 
+  fh_close (w->fh, "system file", "we");
+  
   free (w->buf);
   free (w->vars);
   free (w);
Index: pspp/src/str.c
diff -u pspp/src/str.c:1.18 pspp/src/str.c:1.19
--- pspp/src/str.c:1.18 Wed Oct 26 00:50:44 2005
+++ pspp/src/str.c      Sun Jan 29 02:41:11 2006
@@ -1,5 +1,5 @@
 /* PSPP - computes sample statistics.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
    Written by Ben Pfaff <address@hidden>.
 
    This program is free software; you can redistribute it and/or
@@ -270,6 +270,14 @@
   for (; *s != '\0'; s++)
     *s = toupper ((unsigned char) *s);
 }
+
+/* Converts each character in S to lowercase. */
+void
+str_lowercase (char *s) 
+{
+  for (; *s != '\0'; s++)
+    *s = tolower ((unsigned char) *s);
+}
 
 /* Initializes ST with initial contents S. */
 void
Index: pspp/src/str.h
diff -u pspp/src/str.h:1.13 pspp/src/str.h:1.14
--- pspp/src/str.h:1.13 Tue Oct 25 04:28:17 2005
+++ pspp/src/str.h      Sun Jan 29 02:41:11 2006
@@ -34,6 +34,7 @@
 #include "strstr.h"
 #include "strtok_r.h"
 #include "vsnprintf.h"
+#include "xvasprintf.h"
 
 #ifndef HAVE_STRCHR
 #define strchr index
@@ -108,6 +109,7 @@
 void str_copy_trunc (char *, size_t, const char *);
 void str_copy_buf_trunc (char *, size_t, const char *, size_t);
 void str_uppercase (char *);
+void str_lowercase (char *);
 
 /* Fixed-length strings. */
 struct fixed_string 
Index: pspp/src/sysfile-info.c
diff -u pspp/src/sysfile-info.c:1.20 pspp/src/sysfile-info.c:1.21
--- pspp/src/sysfile-info.c:1.20        Thu Jan 12 03:39:01 2006
+++ pspp/src/sysfile-info.c     Sun Jan 29 02:41:11 2006
@@ -86,7 +86,7 @@
   lex_match_id ("FILE");
   lex_match ('=');
 
-  h = fh_parse ();
+  h = fh_parse (FH_REF_FILE);
   if (!h)
     return CMD_FAILURE;
 
Index: pspp/src/var.h
diff -u pspp/src/var.h:1.41 pspp/src/var.h:1.42
--- pspp/src/var.h:1.41 Wed Nov 23 13:52:47 2005
+++ pspp/src/var.h      Sun Jan 29 02:41:11 2006
@@ -129,10 +129,6 @@
 
 /* Transformation state. */
 
-/* Default file handle for DATA LIST, REREAD, REPEATING DATA
-   commands. */
-extern struct file_handle *default_handle;
-
 /* PROCESS IF expression. */
 extern struct expression *process_if_expr;
 
Index: pspp/src/vfm.c
diff -u pspp/src/vfm.c:1.44 pspp/src/vfm.c:1.45
--- pspp/src/vfm.c:1.44 Wed Dec 14 06:59:06 2005
+++ pspp/src/vfm.c      Sun Jan 29 02:41:11 2006
@@ -1,5 +1,5 @@
 /* PSPP - computes sample statistics.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
    Written by Ben Pfaff <address@hidden>.
 
    This program is free software; you can redistribute it and/or
@@ -35,6 +35,7 @@
 #include "ctl-stack.h"
 #include "error.h"
 #include "expressions/public.h"
+#include "file-handle-def.h"
 #include "misc.h"
 #include "settings.h"
 #include "som.h"
@@ -75,9 +76,9 @@
 /* The replacement active file, to which cases are written. */
 struct case_sink *vfm_sink;
 
-/* Nonzero if the case needs to have values deleted before being
-   stored, zero otherwise. */
-static int compaction_necessary;
+/* The compactor used to compact a compact, if necessary;
+   otherwise a null pointer. */
+static struct dict_compactor *compactor;
 
 /* Time at which vfm was last invoked. */
 static time_t last_vfm_invocation;
@@ -229,8 +230,9 @@
     }
 
   /* Figure out compaction. */
-  compaction_necessary = (dict_get_next_value_idx (temp_dict)
-                          != dict_get_compacted_value_cnt (temp_dict));
+  compactor = (dict_needs_compaction (temp_dict)
+               ? dict_make_compactor (temp_dict)
+               : NULL);
 
   /* Prepare sink. */
   if (vfm_sink == NULL)
@@ -279,10 +281,10 @@
   /* Write case to replacement active file. */
   if (vfm_sink->class->write != NULL) 
     {
-      if (compaction_necessary) 
+      if (compactor != NULL) 
         {
-          dict_compact_case (temp_dict, &wc_data->sink_case,
-                             &wc_data->trns_case);
+          dict_compactor_compact (compactor, &wc_data->sink_case,
+                                  &wc_data->trns_case);
           vfm_sink->class->write (vfm_sink, &wc_data->sink_case);
         }
       else
@@ -425,8 +427,11 @@
     }
 
   /* Finish compaction. */
-  if (compaction_necessary)
-    dict_compact_values (default_dict);
+  if (compactor != NULL) 
+    {
+      dict_compactor_destroy (compactor);
+      dict_compact_values (default_dict); 
+    }
     
   /* Free data source. */
   free_case_source (vfm_source);
@@ -944,7 +949,7 @@
 discard_variables (void)
 {
   dict_clear (default_dict);
-  default_handle = NULL;
+  fh_set_default_handle (NULL);
 
   n_lag = 0;
   
Index: pspp/src/vfm.h
diff -u pspp/src/vfm.h:1.12 pspp/src/vfm.h:1.13
--- pspp/src/vfm.h:1.12 Wed Dec 14 06:59:06 2005
+++ pspp/src/vfm.h      Sun Jan 29 02:41:11 2006
@@ -56,12 +56,8 @@
   };
 
 extern const struct case_source_class storage_source_class;
-extern const struct case_source_class data_list_source_class;
 extern const struct case_source_class file_type_source_class;
 extern const struct case_source_class input_program_source_class;
-extern const struct case_source_class get_source_class;
-extern const struct case_source_class import_source_class;
-extern const struct case_source_class sort_source_class;
 
 struct dictionary;
 struct case_source *create_case_source (const struct case_source_class *,
Index: pspp/tests/bugs/agg-crash-2.sh
diff -u pspp/tests/bugs/agg-crash-2.sh:1.8 pspp/tests/bugs/agg-crash-2.sh:1.9
--- pspp/tests/bugs/agg-crash-2.sh:1.8  Thu Oct 27 19:32:56 2005
+++ pspp/tests/bugs/agg-crash-2.sh      Sun Jan 29 02:41:11 2006
@@ -71,7 +71,7 @@
 
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff -b  -w $TEMPDIR/pspp.list - << EOF
-1.1 DATA LIST.  Reading free-form data from the command file.
+1.1 DATA LIST.  Reading free-form data from INLINE.
 +--------+------+
 |Variable|Format|
 #========#======#
Index: pspp/tests/bugs/compute-lv.sh
diff -u pspp/tests/bugs/compute-lv.sh:1.6 pspp/tests/bugs/compute-lv.sh:1.7
--- pspp/tests/bugs/compute-lv.sh:1.6   Thu Oct 27 19:32:56 2005
+++ pspp/tests/bugs/compute-lv.sh       Sun Jan 29 02:41:12 2006
@@ -73,7 +73,7 @@
 activity="compare output"
 perl -pi -e 's/^\s*$//g' pspp.list
 diff -b pspp.list - << EOF
-1.1 DATA LIST.  Reading free-form data from the command file.
+1.1 DATA LIST.  Reading free-form data from INLINE.
 +----------------+------+
 |    Variable    |Format|
 #================#======#
Index: pspp/tests/bugs/computebug.out
diff -u pspp/tests/bugs/computebug.out:1.2 pspp/tests/bugs/computebug.out:1.3
--- pspp/tests/bugs/computebug.out:1.2  Mon Oct 10 22:18:06 2005
+++ pspp/tests/bugs/computebug.out      Sun Jan 29 02:41:12 2006
@@ -1,4 +1,4 @@
-1.1 DATA LIST.  Reading free-form data from the command file.
+1.1 DATA LIST.  Reading free-form data from INLINE.
 +--------+------+
 |Variable|Format|
 #========#======#
Index: pspp/tests/bugs/crosstabs-crash.sh
diff -u pspp/tests/bugs/crosstabs-crash.sh:1.5 
pspp/tests/bugs/crosstabs-crash.sh:1.6
--- pspp/tests/bugs/crosstabs-crash.sh:1.5      Thu Oct 27 19:32:56 2005
+++ pspp/tests/bugs/crosstabs-crash.sh  Sun Jan 29 02:41:12 2006
@@ -66,7 +66,7 @@
 
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff -b  -w $TEMPDIR/pspp.list - << EOF
-1.1 DATA LIST.  Reading free-form data from the command file.
+1.1 DATA LIST.  Reading free-form data from INLINE.
 +--------+------+
 |Variable|Format|
 #========#======#
Index: pspp/tests/bugs/match-files-scratch.sh
diff -u pspp/tests/bugs/match-files-scratch.sh:1.5 
pspp/tests/bugs/match-files-scratch.sh:1.6
--- pspp/tests/bugs/match-files-scratch.sh:1.5  Thu Oct 27 19:32:56 2005
+++ pspp/tests/bugs/match-files-scratch.sh      Sun Jan 29 02:41:12 2006
@@ -76,7 +76,7 @@
 
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff -b  -w $TEMPDIR/pspp.list - << EOF
-1.1 DATA LIST.  Reading free-form data from the command file.
+1.1 DATA LIST.  Reading free-form data from INLINE.
 +--------+------+
 |Variable|Format|
 #========#======#
Index: pspp/tests/bugs/multipass.sh
diff -u pspp/tests/bugs/multipass.sh:1.7 pspp/tests/bugs/multipass.sh:1.8
--- pspp/tests/bugs/multipass.sh:1.7    Thu Oct 27 19:32:56 2005
+++ pspp/tests/bugs/multipass.sh        Sun Jan 29 02:41:12 2006
@@ -76,7 +76,7 @@
 
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff -b  -w $TEMPDIR/pspp.list - << EOF
-1.1 DATA LIST.  Reading free-form data from the command file.
+1.1 DATA LIST.  Reading free-form data from INLINE.
 +--------+------+
 |Variable|Format|
 #========#======#
Index: pspp/tests/bugs/recode-copy-bug-1.out
diff -u pspp/tests/bugs/recode-copy-bug-1.out:1.2 
pspp/tests/bugs/recode-copy-bug-1.out:1.3
--- pspp/tests/bugs/recode-copy-bug-1.out:1.2   Mon Oct 10 22:18:06 2005
+++ pspp/tests/bugs/recode-copy-bug-1.out       Sun Jan 29 02:41:12 2006
@@ -1,4 +1,4 @@
-1.1 DATA LIST.  Reading free-form data from the command file.
+1.1 DATA LIST.  Reading free-form data from INLINE.
 +--------+------+
 |Variable|Format|
 #========#======#
Index: pspp/tests/bugs/recode-copy-bug-2.out
diff -u pspp/tests/bugs/recode-copy-bug-2.out:1.2 
pspp/tests/bugs/recode-copy-bug-2.out:1.3
--- pspp/tests/bugs/recode-copy-bug-2.out:1.2   Mon Oct 10 22:18:06 2005
+++ pspp/tests/bugs/recode-copy-bug-2.out       Sun Jan 29 02:41:12 2006
@@ -1,4 +1,4 @@
-1.1 DATA LIST.  Reading free-form data from the command file.
+1.1 DATA LIST.  Reading free-form data from INLINE.
 +--------+------+
 |Variable|Format|
 #========#======#
Index: pspp/tests/bugs/t-test-alpha.sh
diff -u pspp/tests/bugs/t-test-alpha.sh:1.8 pspp/tests/bugs/t-test-alpha.sh:1.9
--- pspp/tests/bugs/t-test-alpha.sh:1.8 Thu Oct 27 19:32:56 2005
+++ pspp/tests/bugs/t-test-alpha.sh     Sun Jan 29 02:41:12 2006
@@ -80,7 +80,7 @@
 activity="compare output"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff  -b $TEMPDIR/pspp.list - <<EOF
-1.1 DATA LIST.  Reading free-form data from the command file.
+1.1 DATA LIST.  Reading free-form data from INLINE.
 +--------+------+
 |Variable|Format|
 #========#======#
Index: pspp/tests/bugs/temp-freq.sh
diff -u pspp/tests/bugs/temp-freq.sh:1.5 pspp/tests/bugs/temp-freq.sh:1.6
--- pspp/tests/bugs/temp-freq.sh:1.5    Thu Oct 27 19:32:56 2005
+++ pspp/tests/bugs/temp-freq.sh        Sun Jan 29 02:41:12 2006
@@ -77,7 +77,7 @@
 
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff -b  -w $TEMPDIR/pspp.list - << EOF
-1.1 DATA LIST.  Reading free-form data from the command file.
+1.1 DATA LIST.  Reading free-form data from INLINE.
 +--------+------+
 |Variable|Format|
 #========#======#
Index: pspp/tests/command/aggregate.sh
diff -u pspp/tests/command/aggregate.sh:1.12 
pspp/tests/command/aggregate.sh:1.13
--- pspp/tests/command/aggregate.sh:1.12        Mon Oct 10 22:18:06 2005
+++ pspp/tests/command/aggregate.sh     Sun Jan 29 02:41:12 2006
@@ -166,7 +166,7 @@
 4     1.00     1.00       1       1  .      .     .     1.000   .       .      
.       .000  .      .     .      .000      .       .              4    .       
 .       .       1.000     .      .            4    .     .          4      .   
     .      .     .          4      .00      .00      .00     1.00     1.00     
1.00     1.00      .00       0       0       0       1       1        1       1 
       0    .      .     .   100.0     .       .      .       .0    .      .    
 .      .0      .        .       .     100.0      .        .        .        .  
 
 EOF
 
-for outfile in active external; do
+for outfile in temporary active external; do
     for sort in presorted unsorted; do
        for missing in itemwise columnwise; do
            name=$outfile-$sort-$missing
@@ -182,8 +182,10 @@
                echo "aggregate"
                if [ "$outfile" = "active" ]; then
                    echo "      outfile=*"
-               else
+               elif [ "$outfile" = "external" ]; then
                    echo "      outfile='aggregate.sys'"
+               else
+                   echo "      outfile=#AGGREGATE"
                fi
                if [ "$sort" = "presorted" ]; then
                    echo "      /presorted"
@@ -194,6 +196,8 @@
                cat agg-skel.pspp
                if [ "$outfile" = "external" ]; then
                    echo "get file='aggregate.sys'."
+               elif [ "$outfile" = "temporary" ]; then
+                   echo "get file=#AGGREGATE."
                fi
                echo "list."
            } > $name.pspp
Index: pspp/tests/command/autorecod.sh
diff -u pspp/tests/command/autorecod.sh:1.10 
pspp/tests/command/autorecod.sh:1.11
--- pspp/tests/command/autorecod.sh:1.10        Thu Oct 27 18:57:39 2005
+++ pspp/tests/command/autorecod.sh     Sun Jan 29 02:41:12 2006
@@ -83,7 +83,7 @@
 activity="test output"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff -b $TEMPDIR/pspp.list - <<EOF
-1.1 DATA LIST.  Reading 1 record from the command file.
+1.1 DATA LIST.  Reading 1 record from INLINE.
 +--------+------+-------+------+
 |Variable|Record|Columns|Format|
 #========#======#=======#======#
Index: pspp/tests/command/beg-data.sh
diff -u pspp/tests/command/beg-data.sh:1.9 pspp/tests/command/beg-data.sh:1.10
--- pspp/tests/command/beg-data.sh:1.9  Thu Oct 27 18:57:39 2005
+++ pspp/tests/command/beg-data.sh      Sun Jan 29 02:41:12 2006
@@ -82,7 +82,7 @@
 activity="compare data"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff -b $TEMPDIR/pspp.list - << foobar
-1.1 DATA LIST.  Reading 1 record from the command file.
+1.1 DATA LIST.  Reading 1 record from INLINE.
 +--------+------+-------+------+
 |Variable|Record|Columns|Format|
 #========#======#=======#======#
@@ -96,7 +96,7 @@
 5 6 
 7 8 
 9 0 
-2.1 DATA LIST.  Reading 1 record from the command file.
+2.1 DATA LIST.  Reading 1 record from INLINE.
 +--------+------+-------+------+
 |Variable|Record|Columns|Format|
 #========#======#=======#======#
Index: pspp/tests/command/count.sh
diff -u pspp/tests/command/count.sh:1.8 pspp/tests/command/count.sh:1.9
--- pspp/tests/command/count.sh:1.8     Thu Oct 27 18:57:39 2005
+++ pspp/tests/command/count.sh Sun Jan 29 02:41:12 2006
@@ -75,7 +75,7 @@
 activity="compare results"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff -b  $TEMPDIR/pspp.list - <<EOF
-1.1 DATA LIST.  Reading 1 record from the command file.
+1.1 DATA LIST.  Reading 1 record from INLINE.
 +--------+------+-------+------+
 |Variable|Record|Columns|Format|
 #========#======#=======#======#
Index: pspp/tests/command/data-list.sh
diff -u pspp/tests/command/data-list.sh:1.7 pspp/tests/command/data-list.sh:1.8
--- pspp/tests/command/data-list.sh:1.7 Thu Oct 27 18:57:39 2005
+++ pspp/tests/command/data-list.sh     Sun Jan 29 02:41:12 2006
@@ -108,7 +108,7 @@
 activity="compare output"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff -b  $TEMPDIR/pspp.list - << EOF
-1.1 DATA LIST.  Reading free-form data from the command file.
+1.1 DATA LIST.  Reading free-form data from INLINE.
 +--------+------+
 |Variable|Format|
 #========#======#
Index: pspp/tests/command/examine-percentiles.sh
diff -u pspp/tests/command/examine-percentiles.sh:1.8 
pspp/tests/command/examine-percentiles.sh:1.9
--- pspp/tests/command/examine-percentiles.sh:1.8       Thu Oct 27 18:57:39 2005
+++ pspp/tests/command/examine-percentiles.sh   Sun Jan 29 02:41:12 2006
@@ -84,7 +84,7 @@
 activity="compare results"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff -b  $TEMPDIR/pspp.list - << EOF
-1.1 DATA LIST.  Reading free-form data from the command file.
+1.1 DATA LIST.  Reading free-form data from INLINE.
 +--------+------+
 |Variable|Format|
 #========#======#
Index: pspp/tests/command/examine.sh
diff -u pspp/tests/command/examine.sh:1.11 pspp/tests/command/examine.sh:1.12
--- pspp/tests/command/examine.sh:1.11  Thu Oct 27 18:57:39 2005
+++ pspp/tests/command/examine.sh       Sun Jan 29 02:41:12 2006
@@ -96,7 +96,7 @@
 activity="compare results"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff -b  $TEMPDIR/pspp.list - << EOF
-1.1 DATA LIST.  Reading free-form data from the command file.
+1.1 DATA LIST.  Reading free-form data from INLINE.
 +--------+------+
 |Variable|Format|
 #========#======#
Index: pspp/tests/command/file-handle.sh
diff -u pspp/tests/command/file-handle.sh:1.1 
pspp/tests/command/file-handle.sh:1.2
--- pspp/tests/command/file-handle.sh:1.1       Thu Oct 27 03:19:07 2005
+++ pspp/tests/command/file-handle.sh   Sun Jan 29 02:41:12 2006
@@ -74,7 +74,7 @@
 
 activity="compare output"
 diff  -b  $TEMPDIR/pspp.list - << EOF 
-1.1 DATA LIST.  Reading free-form data from file $TEMPDIR/wiggle.txt.
+1.1 DATA LIST.  Reading free-form data from myhandle.
 +--------+------+
 |Variable|Format|
 #========#======#
Index: pspp/tests/command/file-label.sh
diff -u pspp/tests/command/file-label.sh:1.10 
pspp/tests/command/file-label.sh:1.11
--- pspp/tests/command/file-label.sh:1.10       Thu Oct 27 18:57:39 2005
+++ pspp/tests/command/file-label.sh    Sun Jan 29 02:41:12 2006
@@ -118,7 +118,7 @@
 activity="compare results"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.filtered
 diff -b  $TEMPDIR/pspp.filtered - <<EOF
-1.1 DATA LIST.  Reading 1 record from the command file.
+1.1 DATA LIST.  Reading 1 record from INLINE.
 +--------+------+-------+------+
 |Variable|Record|Columns|Format|
 #========#======#=======#======#
Index: pspp/tests/command/flip.sh
diff -u pspp/tests/command/flip.sh:1.8 pspp/tests/command/flip.sh:1.9
--- pspp/tests/command/flip.sh:1.8      Thu Oct 27 18:57:39 2005
+++ pspp/tests/command/flip.sh  Sun Jan 29 02:41:12 2006
@@ -74,7 +74,7 @@
 activity="compare output"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff  -b  $TEMPDIR/pspp.list - << EOF
-1.1 DATA LIST.  Reading 1 record from the command file.
+1.1 DATA LIST.  Reading 1 record from INLINE.
 +--------+------+-------+------+
 |Variable|Record|Columns|Format|
 #========#======#=======#======#
Index: pspp/tests/command/lag.sh
diff -u pspp/tests/command/lag.sh:1.8 pspp/tests/command/lag.sh:1.9
--- pspp/tests/command/lag.sh:1.8       Thu Oct 27 18:57:39 2005
+++ pspp/tests/command/lag.sh   Sun Jan 29 02:41:12 2006
@@ -73,7 +73,7 @@
 activity="compare result"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff -b  $TEMPDIR/pspp.list - <<EOF
-1.1 DATA LIST.  Reading 1 record from the command file.
+1.1 DATA LIST.  Reading 1 record from INLINE.
 +--------+------+-------+------+
 |Variable|Record|Columns|Format|
 #========#======#=======#======#
Index: pspp/tests/command/list.sh
diff -u pspp/tests/command/list.sh:1.13 pspp/tests/command/list.sh:1.14
--- pspp/tests/command/list.sh:1.13     Thu Oct 27 18:57:39 2005
+++ pspp/tests/command/list.sh  Sun Jan 29 02:41:12 2006
@@ -75,7 +75,7 @@
 activity="compare results"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff -b  $TEMPDIR/pspp.list - <<EOF
-1.1 DATA LIST.  Reading 1 record from file $top_srcdir/tests/weighting.data.
+1.1 DATA LIST.  Reading 1 record from "$top_srcdir/tests/weighting.data".
 +--------+------+-------+------+
 |Variable|Record|Columns|Format|
 #========#======#=======#======#
Index: pspp/tests/command/longvars.sh
diff -u pspp/tests/command/longvars.sh:1.6 pspp/tests/command/longvars.sh:1.7
--- pspp/tests/command/longvars.sh:1.6  Thu Oct 27 18:57:39 2005
+++ pspp/tests/command/longvars.sh      Sun Jan 29 02:41:12 2006
@@ -73,7 +73,7 @@
 activity="compare output"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff  -b $TEMPDIR/pspp.list - <<EOF
-1.1 DATA LIST.  Reading free-form data from the command file.
+1.1 DATA LIST.  Reading free-form data from INLINE.
 +--------------+------+
 |   Variable   |Format|
 #==============#======#
Index: pspp/tests/command/loop.sh
diff -u pspp/tests/command/loop.sh:1.11 pspp/tests/command/loop.sh:1.12
--- pspp/tests/command/loop.sh:1.11     Thu Nov  3 06:21:47 2005
+++ pspp/tests/command/loop.sh  Sun Jan 29 02:41:12 2006
@@ -78,7 +78,7 @@
 activity="compare results"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff  -b $TEMPDIR/pspp.list  - <<EOF
-1.1 DATA LIST.  Reading 1 record from the command file.
+1.1 DATA LIST.  Reading 1 record from INLINE.
 +----------+------+-------+------+
 | Variable |Record|Columns|Format|
 #==========#======#=======#======#
Index: pspp/tests/command/oneway-with-splits.sh
diff -u pspp/tests/command/oneway-with-splits.sh:1.11 
pspp/tests/command/oneway-with-splits.sh:1.12
--- pspp/tests/command/oneway-with-splits.sh:1.11       Mon Oct 10 20:49:13 2005
+++ pspp/tests/command/oneway-with-splits.sh    Sun Jan 29 02:41:12 2006
@@ -97,7 +97,7 @@
 
 perl -pi -e s/^\s*\$//g $TEMPDIR/pspp.list
 diff -b  $TEMPDIR/pspp.list - << EOF | perl -e 's/^\s*$//g'
-1.1 DATA LIST.  Reading free-form data from the command file.
+1.1 DATA LIST.  Reading free-form data from INLINE.
 +--------+------+
 |Variable|Format|
 #========#======#
Index: pspp/tests/command/oneway.sh
diff -u pspp/tests/command/oneway.sh:1.13 pspp/tests/command/oneway.sh:1.14
--- pspp/tests/command/oneway.sh:1.13   Thu Oct 27 18:57:39 2005
+++ pspp/tests/command/oneway.sh        Sun Jan 29 02:41:12 2006
@@ -94,7 +94,7 @@
 
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff -b  $TEMPDIR/pspp.list - << EOF
-1.1 DATA LIST.  Reading free-form data from the command file.
+1.1 DATA LIST.  Reading free-form data from INLINE.
 +--------+------+
 |Variable|Format|
 #========#======#
Index: pspp/tests/command/print.sh
diff -u pspp/tests/command/print.sh:1.20 pspp/tests/command/print.sh:1.21
--- pspp/tests/command/print.sh:1.20    Thu Oct 27 18:57:39 2005
+++ pspp/tests/command/print.sh Sun Jan 29 02:41:12 2006
@@ -100,7 +100,7 @@
 activity="compare output"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff -b  $TEMPDIR/pspp.list - << EOF
-1.1 DATA LIST.  Reading free-form data from file $TEMPDIR/data-list.data.
+1.1 DATA LIST.  Reading free-form data from "$TEMPDIR/data-list.data".
 +--------+------+
 |Variable|Format|
 #========#======#
@@ -109,7 +109,7 @@
 |C       |F8.0  |
 |D       |F8.0  |
 +--------+------+
-2.1 PRINT.  Writing 1 record(s) to file foo.
+2.1 PRINT.  Writing 1 record to "foo".
 +--------+------+-------+------+
 |Variable|Record|Columns|Format|
 #========#======#=======#======#
@@ -125,7 +125,7 @@
      .       2.00     3.00     4.00 
      .       6.00     7.00     8.00 
      .      10.00    11.00    12.00 
-3.1 DATA LIST.  Reading free-form data from file $TEMPDIR/data-list.data.
+3.1 DATA LIST.  Reading free-form data from "$TEMPDIR/data-list.data".
 +--------+------+
 |Variable|Format|
 #========#======#
@@ -134,7 +134,7 @@
 |C       |F8.0  |
 |D       |F8.0  |
 +--------+------+
-4.1 PRINT.  Writing 1 record(s) to the listing file.
+4.1 PRINT.  Writing 1 record.
 +--------+------+-------+------+
 |Variable|Record|Columns|Format|
 #========#======#=======#======#
Index: pspp/tests/command/rename.sh
diff -u pspp/tests/command/rename.sh:1.6 pspp/tests/command/rename.sh:1.7
--- pspp/tests/command/rename.sh:1.6    Thu Oct 27 18:57:39 2005
+++ pspp/tests/command/rename.sh        Sun Jan 29 02:41:12 2006
@@ -80,7 +80,7 @@
 activity="compare output"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff  -b $TEMPDIR/pspp.list - <<EOF
-1.1 DATA LIST.  Reading free-form data from the command file.
+1.1 DATA LIST.  Reading free-form data from INLINE.
 +----------+------+
 | Variable |Format|
 #==========#======#
Index: pspp/tests/command/sysfile-info.sh
diff -u pspp/tests/command/sysfile-info.sh:1.7 
pspp/tests/command/sysfile-info.sh:1.8
--- pspp/tests/command/sysfile-info.sh:1.7      Thu Oct 27 18:57:39 2005
+++ pspp/tests/command/sysfile-info.sh  Sun Jan 29 02:41:12 2006
@@ -78,7 +78,7 @@
 activity="compare output"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/out-filtered
 diff -b -w $TEMPDIR/out-filtered - << EOF
-1.1 DATA LIST.  Reading free-form data from the command file.
+1.1 DATA LIST.  Reading free-form data from INLINE.
 +--------+------+
 |Variable|Format|
 #========#======#
Index: pspp/tests/command/t-test-1-indep-val.sh
diff -u pspp/tests/command/t-test-1-indep-val.sh:1.8 
pspp/tests/command/t-test-1-indep-val.sh:1.9
--- pspp/tests/command/t-test-1-indep-val.sh:1.8        Thu Oct 27 18:57:39 2005
+++ pspp/tests/command/t-test-1-indep-val.sh    Sun Jan 29 02:41:12 2006
@@ -89,7 +89,7 @@
 activity="compare output"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff  -b $TEMPDIR/pspp.list - <<EOF
-1.1 DATA LIST.  Reading free-form data from the command file.
+1.1 DATA LIST.  Reading free-form data from INLINE.
 +--------+------+
 |Variable|Format|
 #========#======#
Index: pspp/tests/command/t-test-1s.sh
diff -u pspp/tests/command/t-test-1s.sh:1.9 pspp/tests/command/t-test-1s.sh:1.10
--- pspp/tests/command/t-test-1s.sh:1.9 Thu Oct 27 18:57:39 2005
+++ pspp/tests/command/t-test-1s.sh     Sun Jan 29 02:41:12 2006
@@ -72,7 +72,7 @@
 activity="compare output"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff  -b $TEMPDIR/pspp.list - <<EOF
-1.1 DATA LIST.  Reading free-form data from the command file.
+1.1 DATA LIST.  Reading free-form data from INLINE.
 +--------+------+
 |Variable|Format|
 #========#======#
Index: pspp/tests/command/t-test-groups.sh
diff -u pspp/tests/command/t-test-groups.sh:1.10 
pspp/tests/command/t-test-groups.sh:1.11
--- pspp/tests/command/t-test-groups.sh:1.10    Mon Oct 10 20:49:13 2005
+++ pspp/tests/command/t-test-groups.sh Sun Jan 29 02:41:12 2006
@@ -79,7 +79,7 @@
 activity="compare output"
 perl -pi -e s/^\s*\$//g $TEMPDIR/pspp.list
 diff  -b $TEMPDIR/pspp.list - <<EOF | perl -e 's/^\s*$//g'
-1.1 DATA LIST.  Reading free-form data from the command file.
+1.1 DATA LIST.  Reading free-form data from INLINE.
 +--------+------+
 |Variable|Format|
 #========#======#
Index: pspp/tests/command/t-test-pairs.sh
diff -u pspp/tests/command/t-test-pairs.sh:1.9 
pspp/tests/command/t-test-pairs.sh:1.10
--- pspp/tests/command/t-test-pairs.sh:1.9      Thu Oct 27 18:57:39 2005
+++ pspp/tests/command/t-test-pairs.sh  Sun Jan 29 02:41:12 2006
@@ -71,7 +71,7 @@
 activity="compare output"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff  -b $TEMPDIR/pspp.list - <<EOF
-1.1 DATA LIST.  Reading free-form data from the command file.
+1.1 DATA LIST.  Reading free-form data from INLINE.
 +--------+------+
 |Variable|Format|
 #========#======#
Index: pspp/tests/command/tabs.sh
diff -u pspp/tests/command/tabs.sh:1.9 pspp/tests/command/tabs.sh:1.10
--- pspp/tests/command/tabs.sh:1.9      Mon Oct 10 20:49:13 2005
+++ pspp/tests/command/tabs.sh  Sun Jan 29 02:41:12 2006
@@ -76,7 +76,7 @@
 
 perl -pi -e s/^\s*\$//g $TEMPDIR/pspp.list
 diff  -b $TEMPDIR/pspp.list - << EOF | perl -e 's/^\s*$//g'
-1.1 DATA LIST.  Reading 1 record from the command file.
+1.1 DATA LIST.  Reading 1 record from INLINE.
 +--------+------+-------+------+
 |Variable|Record|Columns|Format|
 #========#======#=======#======#
Index: pspp/tests/command/trimmed-mean.sh
diff -u pspp/tests/command/trimmed-mean.sh:1.10 
pspp/tests/command/trimmed-mean.sh:1.11
--- pspp/tests/command/trimmed-mean.sh:1.10     Thu Oct 27 18:57:39 2005
+++ pspp/tests/command/trimmed-mean.sh  Sun Jan 29 02:41:12 2006
@@ -77,7 +77,7 @@
 activity="compare results"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff -b  $TEMPDIR/pspp.list - << EOF
-1.1 DATA LIST.  Reading free-form data from the command file.
+1.1 DATA LIST.  Reading free-form data from INLINE.
 +--------+------+
 |Variable|Format|
 #========#======#
Index: pspp/tests/command/weight.sh
diff -u pspp/tests/command/weight.sh:1.14 pspp/tests/command/weight.sh:1.15
--- pspp/tests/command/weight.sh:1.14   Thu Oct 27 18:57:39 2005
+++ pspp/tests/command/weight.sh        Sun Jan 29 02:41:12 2006
@@ -68,7 +68,7 @@
 activity="compare results"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff  -b $TEMPDIR/pspp.list - <<EOF
-1.1 DATA LIST.  Reading 1 record from file $top_srcdir/tests/weighting.data.
+1.1 DATA LIST.  Reading 1 record from "$top_srcdir/tests/weighting.data".
 +--------+------+-------+------+
 |Variable|Record|Columns|Format|
 #========#======#=======#======#
Index: pspp/tests/expressions/variables.sh
diff -u pspp/tests/expressions/variables.sh:1.5 
pspp/tests/expressions/variables.sh:1.6
--- pspp/tests/expressions/variables.sh:1.5     Thu Oct 27 19:25:23 2005
+++ pspp/tests/expressions/variables.sh Sun Jan 29 02:41:12 2006
@@ -99,7 +99,7 @@
 activity="compare results"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff -b  $TEMPDIR/pspp.list - <<EOF
-1.1 DATA LIST.  Reading 1 record from the command file.
+1.1 DATA LIST.  Reading 1 record from INLINE.
 +--------+------+-------+------+
 |Variable|Record|Columns|Format|
 #========#======#=======#======#
Index: pspp/tests/expressions/vectors.sh
diff -u pspp/tests/expressions/vectors.sh:1.5 
pspp/tests/expressions/vectors.sh:1.6
--- pspp/tests/expressions/vectors.sh:1.5       Thu Oct 27 19:25:23 2005
+++ pspp/tests/expressions/vectors.sh   Sun Jan 29 02:41:12 2006
@@ -75,7 +75,7 @@
 activity="compare results"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff -b  $TEMPDIR/pspp.list - <<EOF
-1.1 DATA LIST.  Reading 1 record from the command file.
+1.1 DATA LIST.  Reading 1 record from INLINE.
 +--------+------+-------+------+
 |Variable|Record|Columns|Format|
 #========#======#=======#======#
Index: pspp/tests/stats/descript-basic.sh
diff -u pspp/tests/stats/descript-basic.sh:1.7 
pspp/tests/stats/descript-basic.sh:1.8
--- pspp/tests/stats/descript-basic.sh:1.7      Thu Oct 27 17:24:35 2005
+++ pspp/tests/stats/descript-basic.sh  Sun Jan 29 02:41:12 2006
@@ -78,7 +78,7 @@
 activity="compare output"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff -b $TEMPDIR/pspp.list - <<EOF
-1.1 DATA LIST.  Reading 1 record from the command file.
+1.1 DATA LIST.  Reading 1 record from INLINE.
 +--------+------+-------+------+
 |Variable|Record|Columns|Format|
 #========#======#=======#======#
Index: pspp/tests/stats/descript-missing.sh
diff -u pspp/tests/stats/descript-missing.sh:1.7 
pspp/tests/stats/descript-missing.sh:1.8
--- pspp/tests/stats/descript-missing.sh:1.7    Thu Oct 27 18:51:52 2005
+++ pspp/tests/stats/descript-missing.sh        Sun Jan 29 02:41:12 2006
@@ -79,7 +79,7 @@
 activity="compare output"
 perl -pi -e 's/^\s*$//g' $TEMPDIR/pspp.list
 diff -b $TEMPDIR/pspp.list - <<EOF
-1.1 DATA LIST.  Reading 1 record from the command file.
+1.1 DATA LIST.  Reading 1 record from INLINE.
 +--------+------+-------+------+
 |Variable|Record|Columns|Format|
 #========#======#=======#======#




reply via email to

[Prev in Thread] Current Thread [Next in Thread]