parsing. Added a test for the FILE HANDLE command.
msgstr ""
"Project-Id-Version: PSPP 0.3.1\n"
"Report-Msgid-Bugs-To: pspp-dev@gnu.org\n"
-"POT-Creation-Date: 2005-10-25 17:56+0800\n"
+"POT-Creation-Date: 2005-10-27 10:56+0800\n"
"PO-Revision-Date: 2004-01-23 13:04+0800\n"
"Last-Translator: John Darrington <john@darrington.wattle.id.au>\n"
"Language-Team: John Darrington <john@darrington.wattle.id.au>\n"
msgstr ""
#: src/autorecode.c:143 src/command.c:797 src/compute.c:280 src/do-if.c:256
-#: src/file-handle.q:142 src/lexer.c:438 src/loop.c:244 src/matrix-data.c:532
+#: src/file-handle.q:83 src/lexer.c:438 src/loop.c:244 src/matrix-data.c:532
#: src/print.c:338 src/print.c:1049 src/recode.c:410 src/sel-if.c:57
#: src/sel-if.c:134 src/vector.c:197
msgid "expecting end of command"
#: src/crosstabs.q:1109 src/crosstabs.q:1136 src/crosstabs.q:1156
#: src/crosstabs.q:1178 src/examine.q:1134 src/frequencies.q:1143
-#: src/frequencies.q:1264 src/sysfile-info.c:517 src/vfm.c:812
+#: src/frequencies.q:1264 src/sysfile-info.c:518 src/vfm.c:812
msgid "Value"
msgstr ""
msgstr ""
#: src/data-list.c:788 src/data-list.c:912 src/descript.c:886 src/print.c:800
-#: src/sysfile-info.c:138 src/sysfile-info.c:372 src/vfm.c:811
+#: src/sysfile-info.c:139 src/sysfile-info.c:373 src/vfm.c:811
msgid "Variable"
msgstr ""
msgid "%s is a PSPP extension."
msgstr ""
-#: src/file-handle.q:127
+#: src/file-handle.q:68
#, c-format
msgid ""
"File handle %s already refers to file %s. File handles cannot be redefined "
"within a session."
msgstr ""
-#: src/file-handle.q:148
+#: src/file-handle.q:89
msgid "The FILE HANDLE required subcommand NAME is not present."
msgstr ""
-#: src/file-handle.q:167
+#: src/file-handle.q:113
msgid ""
"Fixed-length records were specified on /RECFORM, but record length was not "
"specified on /LRECL. Assuming 1024-character records."
msgstr ""
-#: src/file-handle.q:174
+#: src/file-handle.q:120
#, c-format
msgid ""
"Record length (%ld) must be at least one byte. 1-character records will be "
"assumed."
msgstr ""
-#: src/file-handle.q:274
-#, c-format
-msgid "Can't open %s as a %s because it is already open as a %s"
-msgstr ""
-
-#: src/file-handle.q:281
-#, c-format
-msgid "Can't open %s as a %s for %s because it is already open for %s"
-msgstr ""
-
-#: src/file-handle.q:289
-#, c-format
-msgid "Can't re-open %s as a %s for %s"
-msgstr ""
-
-#: src/file-handle.q:342
+#: src/file-handle.q:157
msgid "expecting a file name or handle name"
msgstr ""
msgid "HTML output driver: %s: %s"
msgstr ""
-#: src/html.c:421 src/list.q:257
+#: src/html.c:421 src/list.q:256
#, c-format
msgid "Cannot open first page on HTML device %s."
msgstr ""
msgid "The step value %ld is less than 1. The value is being reset to 1."
msgstr ""
-#: src/list.q:202
+#: src/list.q:201
msgid "`/FORMAT WEIGHT' specified, but weighting is not on."
msgstr ""
-#: src/list.q:445
+#: src/list.q:444
msgid "Line"
msgstr ""
msgid "Residual"
msgstr ""
+#: src/regression.q:322
+msgid "Model"
+msgstr ""
+
+#: src/regression.q:323
+msgid "Covariances"
+msgstr ""
+
+#: src/regression.q:339
+msgid "Coefficient Correlations"
+msgstr ""
+
#: src/rename-vars.c:49
msgid ""
"RENAME VARS may not be used after TEMPORARY. Temporary transformations will "
msgid "DEC Kanji"
msgstr ""
-#: src/sfm-read.c:556 src/sysfile-info.c:118
+#: src/sfm-read.c:556 src/sysfile-info.c:119
msgid "Unknown"
msgstr ""
msgid "Buffer limit must be at least 2."
msgstr ""
-#: src/sort.c:461
+#: src/sort.c:462
#, c-format
msgid ""
"Out of memory. Could not allocate room for minimum of %d cases of %d bytes "
msgid "`)' expected."
msgstr ""
-#: src/sysfile-info.c:99
+#: src/sysfile-info.c:100
msgid "File:"
msgstr ""
-#: src/sysfile-info.c:101
+#: src/sysfile-info.c:102
msgid "Label:"
msgstr ""
-#: src/sysfile-info.c:105
+#: src/sysfile-info.c:106
msgid "No label."
msgstr ""
-#: src/sysfile-info.c:108
+#: src/sysfile-info.c:109
msgid "Created:"
msgstr ""
-#: src/sysfile-info.c:111
+#: src/sysfile-info.c:112
msgid "Endian:"
msgstr ""
-#: src/sysfile-info.c:112
+#: src/sysfile-info.c:113
msgid "Big."
msgstr ""
-#: src/sysfile-info.c:112
+#: src/sysfile-info.c:113
msgid "Little."
msgstr ""
-#: src/sysfile-info.c:113
+#: src/sysfile-info.c:114
msgid "Variables:"
msgstr ""
-#: src/sysfile-info.c:116
+#: src/sysfile-info.c:117
msgid "Cases:"
msgstr ""
-#: src/sysfile-info.c:119
+#: src/sysfile-info.c:120
msgid "Type:"
msgstr ""
-#: src/sysfile-info.c:120
+#: src/sysfile-info.c:121
msgid "System File."
msgstr ""
-#: src/sysfile-info.c:121
+#: src/sysfile-info.c:122
msgid "Weight:"
msgstr ""
-#: src/sysfile-info.c:125
+#: src/sysfile-info.c:126
msgid "Not weighted."
msgstr ""
-#: src/sysfile-info.c:127
+#: src/sysfile-info.c:128
msgid "Mode:"
msgstr ""
-#: src/sysfile-info.c:129
+#: src/sysfile-info.c:130
#, c-format
msgid "Compression %s."
msgstr ""
-#: src/sysfile-info.c:129
+#: src/sysfile-info.c:130
msgid "on"
msgstr ""
-#: src/sysfile-info.c:129
+#: src/sysfile-info.c:130
msgid "off"
msgstr ""
-#: src/sysfile-info.c:139 src/sysfile-info.c:377
+#: src/sysfile-info.c:140 src/sysfile-info.c:378
msgid "Description"
msgstr ""
-#: src/sysfile-info.c:140 src/sysfile-info.c:375
+#: src/sysfile-info.c:141 src/sysfile-info.c:376
msgid "Position"
msgstr ""
-#: src/sysfile-info.c:198
+#: src/sysfile-info.c:199
msgid "The active file does not have a file label."
msgstr ""
-#: src/sysfile-info.c:201
+#: src/sysfile-info.c:202
msgid "File label:"
msgstr ""
-#: src/sysfile-info.c:263
+#: src/sysfile-info.c:264
msgid "No variables to display."
msgstr ""
-#: src/sysfile-info.c:282
+#: src/sysfile-info.c:283
msgid "Macros not supported."
msgstr ""
-#: src/sysfile-info.c:292
+#: src/sysfile-info.c:293
msgid "The active file dictionary does not contain any documents."
msgstr ""
-#: src/sysfile-info.c:301
+#: src/sysfile-info.c:302
msgid "Documents in the active file:"
msgstr ""
-#: src/sysfile-info.c:379 src/sysfile-info.c:518 src/vfm.c:813
+#: src/sysfile-info.c:380 src/sysfile-info.c:519 src/vfm.c:813
msgid "Label"
msgstr ""
-#: src/sysfile-info.c:451
+#: src/sysfile-info.c:452
#, c-format
msgid "Format: %s"
msgstr ""
-#: src/sysfile-info.c:458
+#: src/sysfile-info.c:459
#, c-format
msgid "Print Format: %s"
msgstr ""
-#: src/sysfile-info.c:461
+#: src/sysfile-info.c:462
#, c-format
msgid "Write Format: %s"
msgstr ""
-#: src/sysfile-info.c:473
+#: src/sysfile-info.c:474
msgid "Missing Values: "
msgstr ""
-#: src/sysfile-info.c:574
+#: src/sysfile-info.c:575
msgid "No vectors defined."
msgstr ""
-#: src/sysfile-info.c:589
+#: src/sysfile-info.c:590
msgid "Vector"
msgstr ""
msgid "Truncating variable label to 255 characters."
msgstr ""
-#: src/vars-atr.c:132
+#: src/vars-atr.c:126
msgid "Variable name cannot be empty string."
msgstr ""
-#: src/vars-atr.c:138
+#: src/vars-atr.c:132
#, c-format
msgid "Variable name %s exceeds %d-character limit."
msgstr ""
-#: src/vars-atr.c:147
+#: src/vars-atr.c:141
#, c-format
msgid "Character `%c' (in %s) may not appear in a variable name."
msgstr ""
-#: src/vars-atr.c:156
+#: src/vars-atr.c:150
#, c-format
msgid ""
"Character `%c' (in %s), may not appear as the first character in a variable "
"name."
msgstr ""
-#: src/vars-atr.c:165
+#: src/vars-atr.c:159
#, c-format
msgid "%s may not be used as a variable name because it is a reserved word."
msgstr ""
-#: src/vars-atr.c:260
+#: src/vars-atr.c:254
msgid "Variable suffix too large."
msgstr ""
-#: src/vars-atr.c:301
+#: src/vars-atr.c:295
msgid "ordinary"
msgstr ""
-#: src/vars-atr.c:303
+#: src/vars-atr.c:297
msgid "system"
msgstr ""
-#: src/vars-atr.c:305
+#: src/vars-atr.c:299
msgid "scratch"
msgstr ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: pspp-dev@gnu.org\n"
-"POT-Creation-Date: 2005-10-25 17:56+0800\n"
+"POT-Creation-Date: 2005-10-27 10:56+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
msgstr ""
#: src/autorecode.c:143 src/command.c:797 src/compute.c:280 src/do-if.c:256
-#: src/file-handle.q:142 src/lexer.c:438 src/loop.c:244 src/matrix-data.c:532
+#: src/file-handle.q:83 src/lexer.c:438 src/loop.c:244 src/matrix-data.c:532
#: src/print.c:338 src/print.c:1049 src/recode.c:410 src/sel-if.c:57
#: src/sel-if.c:134 src/vector.c:197
msgid "expecting end of command"
#: src/crosstabs.q:1109 src/crosstabs.q:1136 src/crosstabs.q:1156
#: src/crosstabs.q:1178 src/examine.q:1134 src/frequencies.q:1143
-#: src/frequencies.q:1264 src/sysfile-info.c:517 src/vfm.c:812
+#: src/frequencies.q:1264 src/sysfile-info.c:518 src/vfm.c:812
msgid "Value"
msgstr ""
msgstr ""
#: src/data-list.c:788 src/data-list.c:912 src/descript.c:886 src/print.c:800
-#: src/sysfile-info.c:138 src/sysfile-info.c:372 src/vfm.c:811
+#: src/sysfile-info.c:139 src/sysfile-info.c:373 src/vfm.c:811
msgid "Variable"
msgstr ""
msgid "%s is a PSPP extension."
msgstr ""
-#: src/file-handle.q:127
+#: src/file-handle.q:68
#, c-format
msgid ""
"File handle %s already refers to file %s. File handles cannot be redefined "
"within a session."
msgstr ""
-#: src/file-handle.q:148
+#: src/file-handle.q:89
msgid "The FILE HANDLE required subcommand NAME is not present."
msgstr ""
-#: src/file-handle.q:167
+#: src/file-handle.q:113
msgid ""
"Fixed-length records were specified on /RECFORM, but record length was not "
"specified on /LRECL. Assuming 1024-character records."
msgstr ""
-#: src/file-handle.q:174
+#: src/file-handle.q:120
#, c-format
msgid ""
"Record length (%ld) must be at least one byte. 1-character records will be "
"assumed."
msgstr ""
-#: src/file-handle.q:274
-#, c-format
-msgid "Can't open %s as a %s because it is already open as a %s"
-msgstr ""
-
-#: src/file-handle.q:281
-#, c-format
-msgid "Can't open %s as a %s for %s because it is already open for %s"
-msgstr ""
-
-#: src/file-handle.q:289
-#, c-format
-msgid "Can't re-open %s as a %s for %s"
-msgstr ""
-
-#: src/file-handle.q:342
+#: src/file-handle.q:157
msgid "expecting a file name or handle name"
msgstr ""
msgid "HTML output driver: %s: %s"
msgstr ""
-#: src/html.c:421 src/list.q:257
+#: src/html.c:421 src/list.q:256
#, c-format
msgid "Cannot open first page on HTML device %s."
msgstr ""
msgid "The step value %ld is less than 1. The value is being reset to 1."
msgstr ""
-#: src/list.q:202
+#: src/list.q:201
msgid "`/FORMAT WEIGHT' specified, but weighting is not on."
msgstr ""
-#: src/list.q:445
+#: src/list.q:444
msgid "Line"
msgstr ""
msgid "Residual"
msgstr ""
+#: src/regression.q:322
+msgid "Model"
+msgstr ""
+
+#: src/regression.q:323
+msgid "Covariances"
+msgstr ""
+
+#: src/regression.q:339
+msgid "Coefficient Correlations"
+msgstr ""
+
#: src/rename-vars.c:49
msgid ""
"RENAME VARS may not be used after TEMPORARY. Temporary transformations will "
msgid "DEC Kanji"
msgstr ""
-#: src/sfm-read.c:556 src/sysfile-info.c:118
+#: src/sfm-read.c:556 src/sysfile-info.c:119
msgid "Unknown"
msgstr ""
msgid "Buffer limit must be at least 2."
msgstr ""
-#: src/sort.c:461
+#: src/sort.c:462
#, c-format
msgid ""
"Out of memory. Could not allocate room for minimum of %d cases of %d bytes "
msgid "`)' expected."
msgstr ""
-#: src/sysfile-info.c:99
+#: src/sysfile-info.c:100
msgid "File:"
msgstr ""
-#: src/sysfile-info.c:101
+#: src/sysfile-info.c:102
msgid "Label:"
msgstr ""
-#: src/sysfile-info.c:105
+#: src/sysfile-info.c:106
msgid "No label."
msgstr ""
-#: src/sysfile-info.c:108
+#: src/sysfile-info.c:109
msgid "Created:"
msgstr ""
-#: src/sysfile-info.c:111
+#: src/sysfile-info.c:112
msgid "Endian:"
msgstr ""
-#: src/sysfile-info.c:112
+#: src/sysfile-info.c:113
msgid "Big."
msgstr ""
-#: src/sysfile-info.c:112
+#: src/sysfile-info.c:113
msgid "Little."
msgstr ""
-#: src/sysfile-info.c:113
+#: src/sysfile-info.c:114
msgid "Variables:"
msgstr ""
-#: src/sysfile-info.c:116
+#: src/sysfile-info.c:117
msgid "Cases:"
msgstr ""
-#: src/sysfile-info.c:119
+#: src/sysfile-info.c:120
msgid "Type:"
msgstr ""
-#: src/sysfile-info.c:120
+#: src/sysfile-info.c:121
msgid "System File."
msgstr ""
-#: src/sysfile-info.c:121
+#: src/sysfile-info.c:122
msgid "Weight:"
msgstr ""
-#: src/sysfile-info.c:125
+#: src/sysfile-info.c:126
msgid "Not weighted."
msgstr ""
-#: src/sysfile-info.c:127
+#: src/sysfile-info.c:128
msgid "Mode:"
msgstr ""
-#: src/sysfile-info.c:129
+#: src/sysfile-info.c:130
#, c-format
msgid "Compression %s."
msgstr ""
-#: src/sysfile-info.c:129
+#: src/sysfile-info.c:130
msgid "on"
msgstr ""
-#: src/sysfile-info.c:129
+#: src/sysfile-info.c:130
msgid "off"
msgstr ""
-#: src/sysfile-info.c:139 src/sysfile-info.c:377
+#: src/sysfile-info.c:140 src/sysfile-info.c:378
msgid "Description"
msgstr ""
-#: src/sysfile-info.c:140 src/sysfile-info.c:375
+#: src/sysfile-info.c:141 src/sysfile-info.c:376
msgid "Position"
msgstr ""
-#: src/sysfile-info.c:198
+#: src/sysfile-info.c:199
msgid "The active file does not have a file label."
msgstr ""
-#: src/sysfile-info.c:201
+#: src/sysfile-info.c:202
msgid "File label:"
msgstr ""
-#: src/sysfile-info.c:263
+#: src/sysfile-info.c:264
msgid "No variables to display."
msgstr ""
-#: src/sysfile-info.c:282
+#: src/sysfile-info.c:283
msgid "Macros not supported."
msgstr ""
-#: src/sysfile-info.c:292
+#: src/sysfile-info.c:293
msgid "The active file dictionary does not contain any documents."
msgstr ""
-#: src/sysfile-info.c:301
+#: src/sysfile-info.c:302
msgid "Documents in the active file:"
msgstr ""
-#: src/sysfile-info.c:379 src/sysfile-info.c:518 src/vfm.c:813
+#: src/sysfile-info.c:380 src/sysfile-info.c:519 src/vfm.c:813
msgid "Label"
msgstr ""
-#: src/sysfile-info.c:451
+#: src/sysfile-info.c:452
#, c-format
msgid "Format: %s"
msgstr ""
-#: src/sysfile-info.c:458
+#: src/sysfile-info.c:459
#, c-format
msgid "Print Format: %s"
msgstr ""
-#: src/sysfile-info.c:461
+#: src/sysfile-info.c:462
#, c-format
msgid "Write Format: %s"
msgstr ""
-#: src/sysfile-info.c:473
+#: src/sysfile-info.c:474
msgid "Missing Values: "
msgstr ""
-#: src/sysfile-info.c:574
+#: src/sysfile-info.c:575
msgid "No vectors defined."
msgstr ""
-#: src/sysfile-info.c:589
+#: src/sysfile-info.c:590
msgid "Vector"
msgstr ""
msgid "Truncating variable label to 255 characters."
msgstr ""
-#: src/vars-atr.c:132
+#: src/vars-atr.c:126
msgid "Variable name cannot be empty string."
msgstr ""
-#: src/vars-atr.c:138
+#: src/vars-atr.c:132
#, c-format
msgid "Variable name %s exceeds %d-character limit."
msgstr ""
-#: src/vars-atr.c:147
+#: src/vars-atr.c:141
#, c-format
msgid "Character `%c' (in %s) may not appear in a variable name."
msgstr ""
-#: src/vars-atr.c:156
+#: src/vars-atr.c:150
#, c-format
msgid ""
"Character `%c' (in %s), may not appear as the first character in a variable "
"name."
msgstr ""
-#: src/vars-atr.c:165
+#: src/vars-atr.c:159
#, c-format
msgid "%s may not be used as a variable name because it is a reserved word."
msgstr ""
-#: src/vars-atr.c:260
+#: src/vars-atr.c:254
msgid "Variable suffix too large."
msgstr ""
-#: src/vars-atr.c:301
+#: src/vars-atr.c:295
msgid "ordinary"
msgstr ""
-#: src/vars-atr.c:303
+#: src/vars-atr.c:297
msgid "system"
msgstr ""
-#: src/vars-atr.c:305
+#: src/vars-atr.c:299
msgid "scratch"
msgstr ""
+Thu Oct 27 11:16:53 WST 2005 John Darrington <john@darrington.wattle.id.au>
+
+ Separated the definition of a file handle object from the stuff
+ pertaining to the FILE HANDLE command.
+
+ * file-handle-def.[ch]: New files.
+
+ * dfm-read.c file-handle.h file-handle.q
+
Tue Oct 25 21:56:23 2005 Ben Pfaff <blp@gnu.org>
Fix up potential overflows in size calculations by replacing
data-list.c data-list.h data-out.c date.c debug-print.h descript.c \
devind.c devind.h dfm-read.c dfm-read.h dfm-write.c dfm-write.h \
dictionary.c dictionary.h do-if.c do-ifP.h echo.c error.c error.h \
-factor_stats.c factor_stats.h file-handle.h file-type.c filename.c \
-filename.h flip.c font.h format.c format-prs.c format.def format.h formats.c get.c \
+factor_stats.c factor_stats.h file-handle-def.c file-handle-def.h \
+file-handle.h file-type.c filename.c filename.h flip.c font.h format.c \
+format-prs.c format.def format.h formats.c get.c \
getl.c getl.h glob.c glob.h groff-font.c group.c group.h group_proc.h \
hash.c hash.h histogram.c histogram.h html.c htmlP.h include.c \
-inpt-pgm.c lexer.c lexer.h lex-def.h lex-def.c levene.c levene.h linked-list.c \
+inpt-pgm.c lexer.c lexer.h lex-def.h lex-def.c levene.c levene.h linked-list.c \
linked-list.h log.h loop.c magic.c magic.h main.c main.h matrix-data.c \
mis-val.c misc.c misc.h missing-values.c missing-values.h \
modify-vars.c moments.c moments.h numeric.c output.c output.h \
#include "alloc.h"
#include "command.h"
#include "error.h"
-#include "file-handle.h"
+#include "file-handle-def.h"
#include "filename.h"
#include "getl.h"
#include "lexer.h"
--- /dev/null
+/* PSPP - computes sample statistics.
+ Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
+ Written by Ben Pfaff <blp@gnu.org>.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include <config.h>
+#include "file-handle.h"
+#include "error.h"
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include "alloc.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 "gettext.h"
+
+#define _(msgid) gettext (msgid)
+
+/* (headers) */
+
+/* File handle. */
+struct file_handle
+ {
+ struct file_handle *next; /* Next in global list. */
+ char *name; /* File handle identifier. */
+ 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 file_handle_mode mode; /* File mode. */
+ size_t length; /* 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. */
+ };
+
+
+static struct file_handle *file_handles;
+
+
+struct file_handle *
+get_handle_with_name (const char *handle_name)
+{
+ struct file_handle *iter;
+
+ for (iter = file_handles; iter != NULL; iter = iter->next)
+ if (!strcasecmp (handle_name, iter->name))
+ return iter;
+ return NULL;
+}
+
+struct file_handle *
+get_handle_for_filename (const char *filename)
+{
+ struct file_identity *identity;
+ struct file_handle *iter;
+
+ /* First check for a file with the same identity. */
+ identity = fn_get_identity (filename);
+ if (identity != NULL)
+ {
+ for (iter = file_handles; iter != NULL; iter = iter->next)
+ if (iter->identity != NULL
+ && !fn_compare_file_identities (identity, iter->identity))
+ {
+ fn_free_identity (identity);
+ return iter;
+ }
+ fn_free_identity (identity);
+ }
+
+ /* Then check for a file with the same name. */
+ for (iter = file_handles; iter != NULL; iter = iter->next)
+ if (!strcmp (filename, iter->filename))
+ return iter;
+
+ return NULL;
+}
+
+
+/* File handle functions. */
+
+struct file_handle *
+create_file_handle_with_defaults (const char *handle_name,
+ const char *filename)
+{
+ return create_file_handle (handle_name, filename,
+ MODE_TEXT,1024, 4);
+}
+
+
+/* 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 *
+create_file_handle (const char *handle_name, const char *filename,
+ enum file_handle_mode mode,
+ size_t length,
+ size_t tab_width
+ )
+{
+ struct file_handle *handle;
+
+ /* Create and initialize file handle. */
+ handle = xmalloc (sizeof *handle);
+ handle->next = file_handles;
+ handle->name = xstrdup (handle_name);
+ handle->filename = xstrdup (filename);
+ handle->identity = fn_get_identity (filename);
+ handle->where.filename = handle->filename;
+ handle->where.line_number = 0;
+ handle->mode = mode;
+ handle->length = length;
+ handle->tab_width = tab_width;
+ handle->open_cnt = 0;
+ handle->type = NULL;
+ handle->aux = NULL;
+ file_handles = handle;
+
+ return handle;
+}
+
+void
+destroy_file_handle(void *fh_, void *aux UNUSED)
+{
+ struct file_handle *fh = fh_;
+ free (fh->name);
+ free (fh->filename);
+ fn_free_identity (fh->identity);
+ free (fh);
+}
+
+static const char *
+mode_name (const char *mode)
+{
+ assert (mode != NULL);
+ assert (mode[0] == 'r' || mode[0] == 'w');
+
+ return mode[0] == 'r' ? "reading" : "writing";
+}
+
+
+/* Tries to open handle H with the given TYPE and MODE.
+
+ 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.
+
+ MODE combines the read or write mode with the sharing mode.
+ The first character is 'r' for read, 'w' for write. The
+ second character is 's' to permit sharing, 'e' to require
+ exclusive access.
+
+ Returns the address of a void * that the caller can use for
+ data specific to the file handle if successful, or a null
+ pointer on failure. For exclusive access modes the void *
+ will always be a null pointer at return. In shared access
+ modes the void * will necessarily be null only if no other
+ sharers are active.
+
+ If successful, a reference to type is retained, so it should
+ probably be a string literal. */
+void **
+fh_open (struct file_handle *h, const char *type, const char *mode)
+{
+ assert (h != NULL);
+ assert (type != NULL);
+ assert (mode != NULL);
+ assert (mode[0] == 'r' || mode[0] == 'w');
+ assert (mode[1] == 's' || mode[1] == 'e');
+ assert (mode[2] == '\0');
+
+ if (h->open_cnt != 0)
+ {
+ if (strcmp (h->type, type))
+ {
+ msg (SE, _("Can't open %s as a %s because it is "
+ "already open as a %s"),
+ handle_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"),
+ handle_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"),
+ handle_get_name (h), type, mode_name (mode));
+ return NULL;
+ }
+ }
+ else
+ {
+ h->type = type;
+ strcpy (h->open_mode, mode);
+ assert (h->aux == NULL);
+ }
+ h->open_cnt++;
+
+ return &h->aux;
+}
+
+/* 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. */
+int
+fh_close (struct file_handle *h, const char *type, const char *mode)
+{
+ assert (h != NULL);
+ assert (h->open_cnt > 0);
+ assert (type != NULL);
+ assert (!strcmp (type, h->type));
+ assert (mode != NULL);
+ assert (!strcmp (mode, h->open_mode));
+
+ h->open_cnt--;
+ if (h->open_cnt == 0)
+ {
+ h->type = NULL;
+ h->aux = NULL;
+ }
+ return h->open_cnt;
+}
+
+
+
+
+/* Returns the identifier of file HANDLE. If HANDLE was created
+ by referring to a filename instead of a handle name, returns
+ the filename, enclosed in double quotes. Return value is
+ owned by the file handle.
+
+ Useful for printing error messages about use of file handles. */
+const char *
+handle_get_name (const struct file_handle *handle)
+{
+ assert (handle != NULL);
+ return handle->name;
+}
+
+/* Returns the name of the file associated with HANDLE. */
+const char *
+handle_get_filename (const struct file_handle *handle)
+{
+ assert (handle != NULL);
+ return handle->filename;
+}
+
+/* Returns the mode of HANDLE. */
+enum file_handle_mode
+handle_get_mode (const struct file_handle *handle)
+{
+ assert (handle != NULL);
+ return handle->mode;
+}
+
+/* Returns the width of a logical record on HANDLE. */
+size_t
+handle_get_record_width (const struct file_handle *handle)
+{
+ assert (handle != NULL);
+ return handle->length;
+}
+
+/* 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. */
+size_t
+handle_get_tab_width (const struct file_handle *handle)
+{
+ assert (handle != NULL);
+ return handle->tab_width;
+}
+
--- /dev/null
+/* PSPP - computes sample statistics.
+ Copyright (C) 1997-9, 2000,2005 Free Software Foundation, Inc.
+ Written by Ben Pfaff <blp@gnu.org>.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#ifndef FILE_HANDLE_DEF_H
+#define FILE_HANDLE_DEF_H
+
+#include <config.h>
+
+/* File modes. */
+enum file_handle_mode
+ {
+ MODE_TEXT, /* New-line delimited lines. */
+ MODE_BINARY /* Fixed-length records. */
+ };
+
+struct file_handle *create_file_handle_with_defaults (const char *handle_name,
+ const char *filename);
+
+struct file_handle *create_file_handle (const char *handle_name,
+ const char *filename,
+ enum file_handle_mode mode,
+ size_t length,
+ size_t tab_width
+ );
+
+
+
+struct file_handle *
+get_handle_with_name (const char *handle_name) ;
+
+struct file_handle *
+get_handle_for_filename (const char *filename);
+
+const char *handle_get_name (const struct file_handle *handle);
+
+/* Returns the name of the file associated with HANDLE. */
+const char *handle_get_filename (const struct file_handle *handle) ;
+
+
+
+/* Returns the mode of HANDLE. */
+enum file_handle_mode handle_get_mode (const struct file_handle *handle) ;
+
+/* Returns the width of a logical record on HANDLE. */
+size_t handle_get_record_width (const struct file_handle *handle);
+
+
+/* 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. */
+size_t handle_get_tab_width (const struct file_handle *handle);
+
+
+
+void destroy_file_handle(void *fh_, void *aux UNUSED);
+
+
+/* Tries to open handle H with the given TYPE and MODE.
+
+ 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.
+
+ MODE combines the read or write mode with the sharing mode.
+ The first character is 'r' for read, 'w' for write. The
+ second character is 's' to permit sharing, 'e' to require
+ exclusive access.
+
+ Returns the address of a void * that the caller can use for
+ data specific to the file handle if successful, or a null
+ pointer on failure. For exclusive access modes the void *
+ will always be a null pointer at return. In shared access
+ modes the void * will necessarily be null only if no other
+ sharers are active.
+
+ If successful, a reference to type is retained, so it should
+ probably be a string literal. */
+
+void ** fh_open (struct file_handle *h, const char *type, const char *mode) ;
+
+
+#endif
/* File handles. */
#include <stddef.h>
-
-/* File modes. */
-enum file_handle_mode
- {
- MODE_TEXT, /* New-line delimited lines. */
- MODE_BINARY /* Fixed-length records. */
- };
+#include "file-handle-def.h"
void fh_init(void);
void fh_done(void);
+
/* Parsing handles. */
struct file_handle *fh_parse (void);
void **fh_open (struct file_handle *, const char *type, const char *mode);
int fh_close (struct file_handle *, const char *type, const char *mode);
-/* Handle info. */
-const char *handle_get_name (const struct file_handle *);
-const char *handle_get_filename (const struct file_handle *);
-enum file_handle_mode handle_get_mode (const struct file_handle *);
-size_t handle_get_record_width (const struct file_handle *);
-size_t handle_get_tab_width (const struct file_handle *);
#endif /* !file_handle.h */
#include "magic.h"
#include "var.h"
#include "linked-list.h"
+#include "file-handle-def.h"
#include "gettext.h"
#define _(msgid) gettext (msgid)
/* (headers) */
-/* File handle. */
-struct file_handle
- {
- struct file_handle *next; /* Next in global list. */
- char *name; /* File handle identifier. */
- 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 file_handle_mode mode; /* File mode. */
- size_t length; /* 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. */
- };
-
-static struct file_handle *file_handles;
-
-static struct file_handle *create_file_handle (const char *handle_name,
- const char *filename);
/* (specification)
"FILE HANDLE" (fh_):
/* (declarations) */
/* (functions) */
-static struct file_handle *
-get_handle_with_name (const char *handle_name)
-{
- struct file_handle *iter;
-
- for (iter = file_handles; iter != NULL; iter = iter->next)
- if (!strcasecmp (handle_name, iter->name))
- return iter;
- return NULL;
-}
-
-static struct file_handle *
-get_handle_for_filename (const char *filename)
-{
- struct file_identity *identity;
- struct file_handle *iter;
-
- /* First check for a file with the same identity. */
- identity = fn_get_identity (filename);
- if (identity != NULL)
- {
- for (iter = file_handles; iter != NULL; iter = iter->next)
- if (iter->identity != NULL
- && !fn_compare_file_identities (identity, iter->identity))
- {
- fn_free_identity (identity);
- return iter;
- }
- fn_free_identity (identity);
- }
-
- /* Then check for a file with the same name. */
- for (iter = file_handles; iter != NULL; iter = iter->next)
- if (!strcmp (filename, iter->filename))
- return iter;
-
- return NULL;
-}
int
cmd_file_handle (void)
{
msg (SE, _("File handle %s already refers to file %s. "
"File handles cannot be redefined within a session."),
- handle_name, handle->filename);
+ handle_name, handle_get_filename(handle));
return CMD_FAILURE;
}
goto lossage;
}
- handle = create_file_handle (handle_name, cmd.s_name);
+
+ enum file_handle_mode mode = MODE_TEXT;
+ size_t length = 1024;
+ size_t tab_width = 4;
+
+
switch (cmd.mode)
{
case FH_CHARACTER:
- handle->mode = MODE_TEXT;
+ mode = MODE_TEXT;
if (cmd.sbc_tabwidth)
- handle->tab_width = cmd.n_tabwidth[0];
+ tab_width = cmd.n_tabwidth[0];
else
- handle->tab_width = 4;
+ tab_width = 4;
break;
case FH_IMAGE:
- handle->mode = MODE_BINARY;
+ mode = 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. "
"Assuming 1024-character records."));
- handle->length = 1024;
+ length = 1024;
}
else if (cmd.n_lrecl[0] < 1)
{
msg (SE, _("Record length (%ld) must be at least one byte. "
"1-character records will be assumed."), cmd.n_lrecl[0]);
- handle->length = 1;
+ length = 1;
}
else
- handle->length = cmd.n_lrecl[0];
+ length = cmd.n_lrecl[0];
break;
default:
assert (0);
}
+ handle = create_file_handle (handle_name, cmd.s_name,
+ mode, length, tab_width);
+
+
return CMD_SUCCESS;
lossage:
free_file_handle (&cmd);
return CMD_FAILURE;
}
-\f
-/* File handle functions. */
-
-/* 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. */
-static struct file_handle *
-create_file_handle (const char *handle_name, const char *filename)
-{
- struct file_handle *handle;
-
- /* Create and initialize file handle. */
- handle = xmalloc (sizeof *handle);
- handle->next = file_handles;
- handle->name = xstrdup (handle_name);
- handle->filename = xstrdup (filename);
- handle->identity = fn_get_identity (filename);
- handle->where.filename = handle->filename;
- handle->where.line_number = 0;
- handle->mode = MODE_TEXT;
- handle->length = 1024;
- handle->tab_width = 4;
- handle->open_cnt = 0;
- handle->type = NULL;
- handle->aux = NULL;
- file_handles = handle;
-
- return handle;
-}
-
-static void
-destroy_file_handle(void *fh_, void *aux UNUSED)
-{
- struct file_handle *fh = fh_;
- free (fh->name);
- free (fh->filename);
- fn_free_identity (fh->identity);
- free (fh);
-}
-
-static const char *
-mode_name (const char *mode)
-{
- assert (mode != NULL);
- assert (mode[0] == 'r' || mode[0] == 'w');
-
- return mode[0] == 'r' ? "reading" : "writing";
-}
-
-
-/* Tries to open handle H with the given TYPE and MODE.
-
- 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.
-
- MODE combines the read or write mode with the sharing mode.
- The first character is 'r' for read, 'w' for write. The
- second character is 's' to permit sharing, 'e' to require
- exclusive access.
-
- Returns the address of a void * that the caller can use for
- data specific to the file handle if successful, or a null
- pointer on failure. For exclusive access modes the void *
- will always be a null pointer at return. In shared access
- modes the void * will necessarily be null only if no other
- sharers are active.
-
- If successful, a reference to type is retained, so it should
- probably be a string literal. */
-void **
-fh_open (struct file_handle *h, const char *type, const char *mode)
-{
- assert (h != NULL);
- assert (type != NULL);
- assert (mode != NULL);
- assert (mode[0] == 'r' || mode[0] == 'w');
- assert (mode[1] == 's' || mode[1] == 'e');
- assert (mode[2] == '\0');
-
- if (h->open_cnt != 0)
- {
- if (strcmp (h->type, type))
- {
- msg (SE, _("Can't open %s as a %s because it is "
- "already open as a %s"),
- handle_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"),
- handle_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"),
- handle_get_name (h), type, mode_name (mode));
- return NULL;
- }
- }
- else
- {
- h->type = type;
- strcpy (h->open_mode, mode);
- assert (h->aux == NULL);
- }
- h->open_cnt++;
-
- return &h->aux;
-}
-/* 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. */
-int
-fh_close (struct file_handle *h, const char *type, const char *mode)
-{
- assert (h != NULL);
- assert (h->open_cnt > 0);
- assert (type != NULL);
- assert (!strcmp (type, h->type));
- assert (mode != NULL);
- assert (!strcmp (mode, h->open_mode));
-
- h->open_cnt--;
- if (h->open_cnt == 0)
- {
- h->type = NULL;
- h->aux = NULL;
- }
- return h->open_cnt;
-}
static struct linked_list *handle_list;
char *filename = ds_c_str (&tokstr);
char *handle_name = xmalloc (strlen (filename) + 3);
sprintf (handle_name, "\"%s\"", filename);
- handle = create_file_handle (handle_name, filename);
+ handle = create_file_handle_with_defaults (handle_name, filename);
ll_push_front(handle_list, handle);
free (handle_name);
}
return handle;
}
-/* Returns the identifier of file HANDLE. If HANDLE was created
- by referring to a filename instead of a handle name, returns
- the filename, enclosed in double quotes. Return value is
- owned by the file handle.
-
- Useful for printing error messages about use of file handles. */
-const char *
-handle_get_name (const struct file_handle *handle)
-{
- assert (handle != NULL);
- return handle->name;
-}
-
-/* Returns the name of the file associated with HANDLE. */
-const char *
-handle_get_filename (const struct file_handle *handle)
-{
- assert (handle != NULL);
- return handle->filename;
-}
-
-/* Returns the mode of HANDLE. */
-enum file_handle_mode
-handle_get_mode (const struct file_handle *handle)
-{
- assert (handle != NULL);
- return handle->mode;
-}
-
-/* Returns the width of a logical record on HANDLE. */
-size_t
-handle_get_record_width (const struct file_handle *handle)
-{
- assert (handle != NULL);
- return handle->length;
-}
-
-/* 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. */
-size_t
-handle_get_tab_width (const struct file_handle *handle)
-{
- assert (handle != NULL);
- return handle->tab_width;
-}
void
command/examine-extremes.sh \
command/examine-percentiles.sh \
command/file-label.sh \
+ command/file-handle.sh \
command/filter.sh \
command/flip.sh \
command/import-export.sh \
--- /dev/null
+#!/bin/sh
+
+# This program's primary purpose is to test the FILE HANDLE command
+
+TEMPDIR=/tmp/pspp-tst-$$
+TESTFILE=$TEMPDIR/`basename $0`.sps
+
+here=`pwd`;
+
+# ensure that top_srcdir is absolute
+cd $top_srcdir; top_srcdir=`pwd`
+
+STAT_CONFIG_PATH=$top_srcdir/config
+export STAT_CONFIG_PATH
+
+
+cleanup()
+{
+ cd /
+ rm -rf $TEMPDIR
+}
+
+
+fail()
+{
+ echo $activity
+ echo FAILED
+ cleanup;
+ exit 1;
+}
+
+
+no_result()
+{
+ echo $activity
+ echo NO RESULT;
+ cleanup;
+ exit 2;
+}
+
+pass()
+{
+ cleanup;
+ exit 0;
+}
+
+mkdir -p $TEMPDIR
+
+cd $TEMPDIR
+
+activity="create file"
+cat > $TEMPDIR/wiggle.txt << EOF
+1
+2
+5
+109
+EOF
+if [ $? -ne 0 ] ; then no_result ; fi
+
+
+
+activity="create program"
+cat > $TESTFILE << EOF
+FILE HANDLE myhandle /NAME='$TEMPDIR/wiggle.txt'.
+DATA LIST LIST FILE=myhandle /x *.
+LIST.
+EOF
+if [ $? -ne 0 ] ; then no_result ; fi
+
+activity="run program"
+$SUPERVISOR $here/../src/pspp --testing-mode -o raw-ascii $TESTFILE
+if [ $? -ne 0 ] ; then no_result ; fi
+
+
+activity="compare output"
+diff -b $TEMPDIR/pspp.list - << EOF
+1.1 DATA LIST. Reading free-form data from file $TEMPDIR/wiggle.txt.
++--------+------+
+|Variable|Format|
+#========#======#
+|x |F8.0 |
++--------+------+
+
+ x
+--------
+ 1.00
+ 2.00
+ 5.00
+ 109.00
+
+EOF
+if [ $? -ne 0 ] ; then fail ; fi
+
+
+pass;