msgstr ""
"Project-Id-Version: PSPP 0.3.1\n"
"Report-Msgid-Bugs-To: pspp-dev@gnu.org\n"
-"POT-Creation-Date: 2004-11-09 08:18+0800\n"
+"POT-Creation-Date: 2004-11-15 00:28-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"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n!=1);\n"
-#: src/aggregate.c:188 src/aggregate.c:223 src/data-list.c:1437
-#: src/data-list.c:1472 src/data-list.c:1485 src/data-list.c:1498
-#: src/data-list.c:1531
+#: src/aggregate.c:187 src/aggregate.c:220 src/data-list.c:1421
+#: src/data-list.c:1456 src/data-list.c:1469 src/data-list.c:1482
+#: src/data-list.c:1515
#, c-format
msgid "%s subcommand given multiple times."
msgstr ""
-#: src/aggregate.c:208
+#: src/aggregate.c:205
msgid "while expecting COLUMNWISE"
msgstr ""
-#: src/aggregate.c:246
+#: src/aggregate.c:243
msgid "BREAK subcommand not specified."
msgstr ""
-#: src/aggregate.c:416
+#: src/aggregate.c:397
msgid "expecting aggregation function"
msgstr ""
-#: src/aggregate.c:432
+#: src/aggregate.c:413
#, c-format
msgid "Unknown aggregation function %s."
msgstr ""
-#: src/aggregate.c:447
+#: src/aggregate.c:428
msgid "expecting `('"
msgstr ""
-#: src/aggregate.c:482
+#: src/aggregate.c:463
#, c-format
msgid "Missing argument %d to %s."
msgstr ""
-#: src/aggregate.c:490
+#: src/aggregate.c:471
#, c-format
msgid "Arguments to %s must be of same type as source variables."
msgstr ""
-#: src/aggregate.c:500 src/expr-prs.c:626
+#: src/aggregate.c:481 src/expr-prs.c:627
msgid "expecting `)'"
msgstr ""
-#: src/aggregate.c:512
+#: src/aggregate.c:493
#, c-format
msgid ""
"Number of source variables (%d) does not match number of target variables (%"
"d)."
msgstr ""
-#: src/aggregate.c:581
+#: src/aggregate.c:562
#, c-format
msgid ""
"Variable name %s is not unique within the aggregate file dictionary, which "
"contains the aggregate variables and the break variables."
msgstr ""
-#: src/apply-dict.c:65
+#: src/apply-dict.c:68
#, c-format
msgid "Variable %s is %s in target file, but %s in source file."
msgstr ""
-#: src/apply-dict.c:68 src/apply-dict.c:69 src/expr-prs.c:1288
-#: src/expr-prs.c:1304 src/formats.c:96 src/pfm-read.c:636 src/print.c:689
-#: src/sfm-read.c:927 src/sfm-read.c:1057 src/sfm-read.c:1058
+#: src/apply-dict.c:71 src/apply-dict.c:72 src/expr-prs.c:1289
+#: src/expr-prs.c:1305 src/formats.c:96 src/pfm-read.c:604 src/print.c:695
+#: src/sfm-read.c:888 src/sfm-read.c:1017 src/sfm-read.c:1018
msgid "string"
msgstr ""
-#: src/apply-dict.c:68 src/apply-dict.c:69 src/expr-prs.c:1285
-#: src/expr-prs.c:1302 src/formats.c:96 src/pfm-read.c:636 src/print.c:689
-#: src/sfm-read.c:927 src/sfm-read.c:1057 src/sfm-read.c:1058
+#: src/apply-dict.c:71 src/apply-dict.c:72 src/expr-prs.c:1286
+#: src/expr-prs.c:1303 src/formats.c:96 src/pfm-read.c:604 src/print.c:695
+#: src/sfm-read.c:888 src/sfm-read.c:1017 src/sfm-read.c:1018
msgid "numeric"
msgstr ""
-#: src/apply-dict.c:81
+#: src/apply-dict.c:84
#, c-format
msgid "Cannot add value labels from source file to long string variable %s."
msgstr ""
-#: src/apply-dict.c:127
+#: src/apply-dict.c:130
#, c-format
msgid ""
"Cannot apply missing values from source file to long string variable %s."
msgstr ""
-#: src/apply-dict.c:160
+#: src/apply-dict.c:163
msgid "No matching variables found between the source and target files."
msgstr ""
msgid "%s - Page %d"
msgstr ""
-#: src/autorecode.c:121
+#: src/autorecode.c:122
#, c-format
msgid "Source variable count (%d) does not match target variable count (%d)."
msgstr ""
-#: src/autorecode.c:138 src/command.c:738 src/compute.c:293
-#: src/data-list.c:406 src/data-list.c:903 src/data-list.c:1764
-#: src/do-if.c:253 src/get.c:351 src/lexer.c:412 src/loop.c:240
-#: src/matrix-data.c:504 src/print.c:329 src/print.c:1039 src/recode.c:404
-#: src/sel-if.c:53 src/sel-if.c:130 src/vector.c:192 src/file-handle.q:141
+#: src/autorecode.c:139 src/command.c:739 src/compute.c:294
+#: src/data-list.c:407 src/data-list.c:897 src/data-list.c:1748
+#: src/do-if.c:253 src/get.c:405 src/lexer.c:412 src/loop.c:241
+#: src/matrix-data.c:527 src/print.c:335 src/print.c:1045 src/recode.c:405
+#: src/sel-if.c:54 src/sel-if.c:131 src/vector.c:193 src/file-handle.q:138
msgid "expecting end of command"
msgstr ""
-#: src/autorecode.c:148
+#: src/autorecode.c:149
#, c-format
msgid "Target variable %s duplicates existing variable %s."
msgstr ""
-#: src/autorecode.c:155
+#: src/autorecode.c:156
#, c-format
msgid "Duplicate variable name %s among target variables."
msgstr ""
-#: src/casefile.c:184
+#: src/casefile.c:182
#, c-format
msgid "%s: Removing temporary file: %s."
msgstr ""
-#: src/casefile.c:329
+#: src/casefile.c:328
#, c-format
msgid "Error writing temporary file: %s."
msgstr ""
-#: src/casefile.c:356
+#: src/casefile.c:355
#, c-format
msgid "%s: Creating temporary file: %s."
msgstr ""
-#: src/casefile.c:500
+#: src/casefile.c:498
#, c-format
msgid "%s: Opening temporary file: %s."
msgstr ""
-#: src/casefile.c:526
+#: src/casefile.c:524
#, c-format
msgid "%s: Seeking temporary file: %s."
msgstr ""
-#: src/casefile.c:541
+#: src/casefile.c:540
#, c-format
msgid "%s: Reading temporary file: %s."
msgstr ""
-#: src/casefile.c:544
+#: src/casefile.c:543
#, c-format
msgid "%s: Temporary file ended unexpectedly."
msgstr ""
-#: src/cmdline.c:141 src/cmdline.c:160 src/cmdline.c:172 src/command.c:160
+#: src/cmdline.c:141 src/cmdline.c:160 src/cmdline.c:172 src/command.c:161
#: src/set.q:414 src/set.q:416 src/set.q:956
#, c-format
msgid "%s is not yet implemented."
"Report bugs to <%s>.\n"
msgstr ""
-#: src/command.c:98
+#: src/command.c:99
#, c-format
msgid "%s not allowed inside FILE TYPE/END FILE TYPE."
msgstr ""
-#: src/command.c:102
+#: src/command.c:103
#, c-format
msgid "%s not allowed inside FILE TYPE GROUPED/END FILE TYPE."
msgstr ""
-#: src/command.c:105
+#: src/command.c:106
msgid "RECORD TYPE must be the first command inside a FILE TYPE structure."
msgstr ""
-#: src/command.c:150
+#: src/command.c:151
msgid "expecting command name"
msgstr ""
-#: src/command.c:179
+#: src/command.c:180
#, c-format
msgid ""
"%s is not allowed (1) before a command to specify the input program, such as "
"PROGRAM and END INPUT PROGRAM."
msgstr ""
-#: src/command.c:183
+#: src/command.c:184
#, c-format
msgid "%s is not allowed within an input program."
msgstr ""
-#: src/command.c:184 src/command.c:185
+#: src/command.c:185 src/command.c:186
#, c-format
msgid "%s is only allowed within an input program."
msgstr ""
-#: src/command.c:464
+#: src/command.c:465
#, c-format
msgid "Unknown command %s."
msgstr ""
-#: src/command.c:564
+#: src/command.c:565
msgid ""
"This command is not accepted in a syntax file. Instead, use FINISH to "
"terminate a syntax file."
msgstr ""
-#: src/command.c:582
+#: src/command.c:583
msgid ""
"This command is not executed in interactive mode. Instead, PSPP drops down "
"to the command prompt. Use EXIT if you really want to quit."
msgstr ""
-#: src/command.c:625 src/command.c:756
+#: src/command.c:626 src/command.c:757
msgid "This command not allowed when the SAFER option is set."
msgstr ""
-#: src/command.c:637
+#: src/command.c:638
#, c-format
msgid "Error removing `%s': %s."
msgstr ""
-#: src/command.c:687
+#: src/command.c:688
#, c-format
msgid "Couldn't fork: %s."
msgstr ""
-#: src/command.c:729
+#: src/command.c:730
#, c-format
msgid "Error executing command: %s."
msgstr ""
-#: src/command.c:777
+#: src/command.c:778
msgid "No operating system support for this command."
msgstr ""
-#: src/command.c:800
+#: src/command.c:801
msgid "This command is not valid in a syntax file."
msgstr ""
-#: src/compute.c:145 src/compute.c:209
+#: src/compute.c:146 src/compute.c:210
#, c-format
msgid ""
"When executing COMPUTE: SYSMIS is not a valid value as an index into vector %"
"s."
msgstr ""
-#: src/compute.c:148 src/compute.c:213
+#: src/compute.c:149 src/compute.c:214
#, c-format
msgid ""
"When executing COMPUTE: %g is not a valid value as an index into vector %s."
msgstr ""
-#: src/compute.c:355
+#: src/compute.c:356
#, c-format
msgid "There is no vector named %s."
msgstr ""
-#: src/count.c:155
+#: src/count.c:156
msgid "Destination cannot be a string variable."
msgstr ""
-#: src/count.c:262
+#: src/count.c:263
#, c-format
msgid ""
"%g THRU %g is not a valid range. The number following THRU must be at least "
msgid "Only one of FIXED, FREE, or LIST may be specified."
msgstr ""
-#: src/data-list.c:353 src/print.c:290
+#: src/data-list.c:354 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:382 src/data-list.c:1753
+#: src/data-list.c:383 src/data-list.c:1737
msgid ""
"SPSS-like or FORTRAN-like format specification expected after variable names."
msgstr ""
-#: src/data-list.c:393
+#: src/data-list.c:394
msgid "At least one variable must be specified."
msgstr ""
-#: src/data-list.c:398 src/print.c:322
+#: src/data-list.c:399 src/print.c:328
msgid ""
"Variables are specified on records that should not exist according to "
"RECORDS subcommand."
msgstr ""
-#: src/data-list.c:436 src/data-list.c:450 src/print.c:499 src/print.c:512
+#: src/data-list.c:437 src/data-list.c:451 src/print.c:505 src/print.c:518
msgid "Column positions for fields must be positive."
msgstr ""
-#: src/data-list.c:455
+#: src/data-list.c:456
msgid "The ending column for a field must be greater than the starting column."
msgstr ""
-#: src/data-list.c:469 src/print.c:589
+#: src/data-list.c:470 src/print.c:595
#, c-format
msgid "The %d columns %d-%d can't be evenly divided into %d fields."
msgstr ""
-#: src/data-list.c:489 src/print.c:540
+#: src/data-list.c:490 src/print.c:546
msgid "A format specifier on this line has extra characters on the end."
msgstr ""
-#: src/data-list.c:504 src/print.c:556
+#: src/data-list.c:505 src/print.c:562
msgid "The value for number of decimal places must be at least 1."
msgstr ""
-#: src/data-list.c:518 src/print.c:569
+#: src/data-list.c:519 src/print.c:575
#, c-format
msgid "Input format %s doesn't accept decimal places."
msgstr ""
-#: src/data-list.c:565 src/data-list.c:661 src/data-list.c:882
+#: src/data-list.c:566 src/data-list.c:662 src/data-list.c:876
#, c-format
msgid "%s is a duplicate variable name."
msgstr ""
-#: src/data-list.c:570
+#: src/data-list.c:571
#, c-format
msgid "There is already a variable %s of a different type."
msgstr ""
-#: src/data-list.c:577
+#: src/data-list.c:578
#, c-format
msgid "There is already a string variable %s of a different width."
msgstr ""
-#: src/data-list.c:652
+#: src/data-list.c:653
msgid ""
"The number of format specifications exceeds the given number of variable "
"names."
msgstr ""
-#: src/data-list.c:765 src/print.c:762
+#: src/data-list.c:766 src/print.c:768
msgid ""
"There aren't enough format specifications to match the number of variable "
"names given."
msgstr ""
-#: src/data-list.c:794 src/data-list.c:924 src/descript.c:879 src/print.c:793
-#: src/sysfile-info.c:132 src/sysfile-info.c:365 src/vfm.c:874
+#: src/data-list.c:793 src/data-list.c:919 src/descript.c:880 src/print.c:799
+#: src/sysfile-info.c:134 src/sysfile-info.c:367 src/vfm.c:875
msgid "Variable"
msgstr ""
-#: src/data-list.c:795 src/print.c:794
+#: src/data-list.c:794 src/print.c:800
msgid "Record"
msgstr ""
-#: src/data-list.c:796 src/print.c:795
+#: src/data-list.c:795 src/print.c:801
msgid "Columns"
msgstr ""
-#: src/data-list.c:797 src/data-list.c:925 src/print.c:796
+#: src/data-list.c:796 src/data-list.c:920 src/print.c:802
msgid "Format"
msgstr ""
-#: src/data-list.c:817
+#: src/data-list.c:812
#, c-format
msgid "Reading %d record from file %s."
msgid_plural "Reading %d records from file %s."
msgstr[0] ""
msgstr[1] ""
-#: src/data-list.c:819
+#: src/data-list.c:816
#, 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:948
+#: src/data-list.c:936
#, c-format
msgid "Reading free-form data from file %s."
msgstr ""
-#: src/data-list.c:949
+#: src/data-list.c:939
msgid "Reading free-form data from the command file."
msgstr ""
-#: src/data-list.c:1002
+#: src/data-list.c:990
#, c-format
msgid "Quoted string missing terminating `%c'."
msgstr ""
-#: src/data-list.c:1111
+#: src/data-list.c:1099
#, c-format
msgid "Partial case of %d of %d records discarded."
msgstr ""
-#: src/data-list.c:1165
+#: src/data-list.c:1153
#, c-format
msgid "Partial case discarded. The first variable missing was %s."
msgstr ""
-#: src/data-list.c:1209
+#: src/data-list.c:1197
#, 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:1287
+#: src/data-list.c:1275
msgid "Attempt to read past end of file."
msgstr ""
-#: src/data-list.c:1427
+#: src/data-list.c:1411
msgid ""
"REPEATING DATA must use the same file as its corresponding DATA LIST or FILE "
"TYPE."
msgstr ""
-#: src/data-list.c:1461
+#: src/data-list.c:1445
#, c-format
msgid "STARTS beginning column (%d) exceeds STARTS ending column (%d)."
msgstr ""
-#: src/data-list.c:1517
+#: src/data-list.c:1501
#, c-format
msgid "CONTINUED beginning column (%d) exceeds CONTINUED ending column (%d)."
msgstr ""
-#: src/data-list.c:1540
+#: src/data-list.c:1524
#, c-format
msgid "ID beginning column (%ld) must be positive."
msgstr ""
-#: src/data-list.c:1555
+#: src/data-list.c:1539
#, c-format
msgid "ID ending column (%ld) must be positive."
msgstr ""
-#: src/data-list.c:1561
+#: src/data-list.c:1545
#, c-format
msgid "ID ending column (%ld) cannot be less than ID beginning column (%d)."
msgstr ""
-#: src/data-list.c:1601
+#: src/data-list.c:1585
msgid "Missing required specification STARTS."
msgstr ""
-#: src/data-list.c:1603
+#: src/data-list.c:1587
msgid "Missing required specification OCCURS."
msgstr ""
-#: src/data-list.c:1610
+#: src/data-list.c:1594
msgid "ID specified without CONTINUED."
msgstr ""
-#: src/data-list.c:1702
+#: src/data-list.c:1686
msgid "String variable not allowed here."
msgstr ""
-#: src/data-list.c:1712
+#: src/data-list.c:1696
#, c-format
msgid "%s (%d) must be at least 1."
msgstr ""
-#: src/data-list.c:1718
+#: src/data-list.c:1702
#, c-format
msgid "Variable or integer expected for %s."
msgstr ""
-#: src/data-list.c:1856
+#: src/data-list.c:1840
#, c-format
msgid "Encountered mismatched record ID \"%s\" expecting \"%s\"."
msgstr ""
-#: src/data-list.c:1888
+#: src/data-list.c:1872
#, c-format
msgid ""
"Variable %s starting in column %d extends beyond physical record length of %"
"d."
msgstr ""
-#: src/data-list.c:1956
+#: src/data-list.c:1940
#, c-format
msgid "Invalid value %d for OCCURS."
msgstr ""
-#: src/data-list.c:1962
+#: src/data-list.c:1946
#, c-format
msgid "Beginning column for STARTS (%d) must be at least 1."
msgstr ""
-#: src/data-list.c:1970
+#: src/data-list.c:1954
#, c-format
msgid "Ending column for STARTS (%d) is less than beginning column (%d)."
msgstr ""
-#: src/data-list.c:1978
+#: src/data-list.c:1962
#, c-format
msgid "Invalid value %d for LENGTH."
msgstr ""
-#: src/data-list.c:1985
+#: src/data-list.c:1969
#, c-format
msgid "Beginning column for CONTINUED (%d) must be at least 1."
msgstr ""
-#: src/data-list.c:1993
+#: src/data-list.c:1977
#, c-format
msgid "Ending column for CONTINUED (%d) is less than beginning column (%d)."
msgstr ""
-#: src/data-list.c:2025
+#: src/data-list.c:2009
#, 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:2043
+#: src/data-list.c:2027
#, c-format
msgid "Unexpected end of file with %d repetitions remaining out of %d."
msgstr ""
-#: src/data-out.c:235 src/sfm-read.c:466 src/sysfile-info.c:113
+#: src/data-out.c:235 src/sfm-read.c:432 src/sysfile-info.c:115
msgid "Unknown"
msgstr ""
msgid "Only USE ALL is currently implemented."
msgstr ""
-#: src/descript.c:98 src/examine.q:584 src/frequencies.q:100 src/oneway.q:394
-#: src/t-test.q:681 src/t-test.q:704 src/t-test.q:827 src/t-test.q:1165
+#: src/descript.c:99 src/examine.q:631 src/frequencies.q:110 src/oneway.q:396
+#: src/t-test.q:683 src/t-test.q:706 src/t-test.q:829 src/t-test.q:1166
msgid "Mean"
msgstr ""
-#: src/descript.c:99
+#: src/descript.c:100
msgid "S E Mean"
msgstr ""
-#: src/descript.c:100 src/frequencies.q:104
+#: src/descript.c:101 src/frequencies.q:114
msgid "Std Dev"
msgstr ""
-#: src/descript.c:101 src/examine.q:641 src/frequencies.q:105
+#: src/descript.c:102 src/examine.q:694 src/frequencies.q:115
msgid "Variance"
msgstr ""
-#: src/descript.c:102 src/examine.q:711 src/frequencies.q:106
+#: src/descript.c:103 src/examine.q:764 src/frequencies.q:116
msgid "Kurtosis"
msgstr ""
-#: src/descript.c:103
+#: src/descript.c:104
msgid "S E Kurt"
msgstr ""
-#: src/descript.c:104 src/examine.q:706 src/frequencies.q:108
+#: src/descript.c:105 src/examine.q:759 src/frequencies.q:118
msgid "Skewness"
msgstr ""
-#: src/descript.c:105
+#: src/descript.c:106
msgid "S E Skew"
msgstr ""
-#: src/descript.c:106 src/examine.q:689 src/frequencies.q:110
+#: src/descript.c:107 src/examine.q:742 src/frequencies.q:120
msgid "Range"
msgstr ""
-#: src/descript.c:107 src/examine.q:666 src/frequencies.q:111 src/oneway.q:406
+#: src/descript.c:108 src/examine.q:719 src/frequencies.q:121 src/oneway.q:408
msgid "Minimum"
msgstr ""
-#: src/descript.c:108 src/examine.q:677 src/frequencies.q:112 src/oneway.q:407
+#: src/descript.c:109 src/examine.q:730 src/frequencies.q:122 src/oneway.q:409
msgid "Maximum"
msgstr ""
-#: src/descript.c:109 src/frequencies.q:113
+#: src/descript.c:110 src/frequencies.q:123
msgid "Sum"
msgstr ""
-#: src/descript.c:332
+#: src/descript.c:333
#, c-format
msgid "Z-score variable name %s would be a duplicate variable name."
msgstr ""
-#: src/descript.c:350 src/list.q:140
+#: src/descript.c:351 src/list.q:142
msgid "No variables specified."
msgstr ""
-#: src/descript.c:434
+#: src/descript.c:435
msgid "expecting statistic name: reverting to default"
msgstr ""
-#: src/descript.c:507
+#: src/descript.c:508
msgid ""
"Ran out of generic names for Z-score variables. There are only 126 generic "
"names: ZSC001-ZSC0999, STDZ01-STDZ09, ZZZZ01-ZZZZ09, ZQZQ01-ZQZQ09."
msgstr ""
-#: src/descript.c:538
+#: src/descript.c:539
msgid "Mapping of variables to corresponding Z-scores."
msgstr ""
-#: src/descript.c:543
+#: src/descript.c:544
msgid "Source"
msgstr ""
-#: src/descript.c:544
+#: src/descript.c:545
msgid "Target"
msgstr ""
-#: src/descript.c:663 src/descript.c:669
+#: src/descript.c:664 src/descript.c:670
msgid "Z-score of "
msgstr ""
-#: src/descript.c:882
+#: src/descript.c:883
msgid "Valid N"
msgstr ""
-#: src/descript.c:883
+#: src/descript.c:884
msgid "Missing N"
msgstr ""
-#: src/descript.c:909
+#: src/descript.c:910
#, c-format
msgid "Valid cases = %g; cases with missing value(s) = %g."
msgstr ""
msgid "Cannot open first page on DEVIND device %s."
msgstr ""
-#: src/dfm.c:88 src/dfm.c:565
-#, c-format
-msgid "%s: Closing data-file handle %s."
-msgstr ""
-
-#: src/dfm.c:115
-#, c-format
-msgid "Cannot read from file %s already opened for %s."
-msgstr ""
-
-#: src/dfm.c:129
-#, c-format
-msgid "%s: Opening data-file handle %s for reading."
-msgstr ""
-
-#: src/dfm.c:144
+#: src/dfm-read.c:153
#, c-format
msgid "Could not open \"%s\" for reading as a data file: %s."
msgstr ""
-#: src/dfm.c:186 src/dfm.c:204
+#: src/dfm-read.c:186 src/dfm-read.c:204
msgid "BEGIN DATA expected."
msgstr ""
-#: src/dfm.c:213
+#: src/dfm-read.c:213
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.c:241 src/dfm.c:261
+#: src/dfm-read.c:246 src/dfm-read.c:266
#, c-format
msgid "Error reading file %s: %s."
msgstr ""
-#: src/dfm.c:264
+#: src/dfm-read.c:269
#, c-format
msgid "%s: Partial record at end of file."
msgstr ""
-#: src/dfm.c:300
+#: src/dfm-read.c:312
#, c-format
msgid "Attempt to read beyond end-of-file on file %s."
msgstr ""
-#: src/dfm.c:446
-msgid "reading as a data file"
-msgstr ""
-
-#: src/dfm.c:472
-#, c-format
-msgid "Cannot write to file %s already opened for %s."
-msgstr ""
-
-#: src/dfm.c:485
-#, c-format
-msgid "%s: Opening data-file handle %s for writing."
+#: src/dfm-read.c:315
+msgid "Attempt to read beyond END DATA."
msgstr ""
-#: src/dfm.c:491
-msgid "Cannot open the inline file for writing."
+#: src/dfm-read.c:462
+msgid ""
+"This command is not valid here since the current input program does not "
+"access the inline file."
msgstr ""
-#: src/dfm.c:505
+#: src/dfm-write.c:67
#, c-format
msgid "An error occurred while opening \"%s\" for writing as a data file: %s."
msgstr ""
-#: src/dfm.c:547
+#: src/dfm-write.c:103
#, c-format
msgid "Error writing file %s: %s."
msgstr ""
-#: src/dfm.c:581
-msgid "writing as a data file"
-msgstr ""
-
-#: src/dfm.c:598
-msgid ""
-"This command is not valid here since the current input program does not "
-"access the inline file."
-msgstr ""
-
-#: src/dfm.c:605
-msgid "inline file: Opening for reading."
-msgstr ""
-
-#: src/dfm.c:618
-msgid "Skipping remaining inline data."
-msgstr ""
-
-#: src/dictionary.c:583
+#: src/dictionary.c:603
msgid ""
"At least one case in the data file had a weight value that was user-missing, "
"system-missing, zero, or negative. These case(s) were ignored."
msgid "fatal"
msgstr ""
-#: src/error.c:259 src/error.c:266 src/error.c:269 src/expr-prs.c:1279
+#: src/error.c:259 src/error.c:266 src/error.c:269 src/expr-prs.c:1280
msgid "error"
msgstr ""
msgid "installation error"
msgstr ""
-#: src/expr-evl.c:633
+#: src/expr-evl.c:634
msgid "TIME.HMS cannot mix positive and negative in its arguments."
msgstr ""
-#: src/expr-evl.c:697
+#: src/expr-evl.c:698
#, fuzzy
msgid "Week argument to WKYR must be in range 0 to 53."
msgstr "Text colour must be in range 0-15."
-#: src/expr-evl.c:848 src/expr-evl.c:904
+#: src/expr-evl.c:849 src/expr-evl.c:905
msgid "Argument 3 of RINDEX may not be system-missing."
msgstr ""
-#: src/expr-evl.c:858 src/expr-evl.c:914
+#: src/expr-evl.c:859 src/expr-evl.c:915
msgid ""
"Argument 3 of RINDEX must be between 1 and the length of argument 2, and it "
"must evenly divide the length of argument 2."
msgstr ""
-#: src/expr-evl.c:1100
+#: src/expr-evl.c:1101
msgid ""
"A number being treated as a Boolean in an expression was found to have a "
"value other than 0 (false), 1 (true), or the system-missing value. The "
"result was forced to 0."
msgstr ""
-#: src/expr-evl.c:1141
+#: src/expr-evl.c:1142
#, c-format
msgid ""
"SYSMIS is not a valid index value for vector %s. The result will be set to "
"SYSMIS."
msgstr ""
-#: src/expr-evl.c:1145
+#: src/expr-evl.c:1146
#, c-format
msgid ""
"%g is not a valid index value for vector %s. The result will be set to "
"SYSMIS."
msgstr ""
-#: src/expr-evl.c:1164
+#: src/expr-evl.c:1165
#, c-format
msgid ""
"SYSMIS is not a valid index value for vector %s. The result will be set to "
"the empty string."
msgstr ""
-#: src/expr-evl.c:1169
+#: src/expr-evl.c:1170
#, c-format
msgid ""
"%g is not a valid index value for vector %s. The result will be set to the "
"Boolean value was found to have a constant value other than 0, 1, or SYSMIS."
msgstr ""
-#: src/expr-prs.c:137
+#: src/expr-prs.c:138
msgid ""
"Type mismatch: expression has string type, but a numeric value is required "
"here."
msgstr ""
-#: src/expr-prs.c:148
+#: src/expr-prs.c:149
msgid ""
"Type mismatch: expression has numeric type, but a string value is required "
"here."
msgstr ""
-#: src/expr-prs.c:207
+#: src/expr-prs.c:208
#, c-format
msgid "Type mismatch: operands of %s operator must be strings."
msgstr ""
-#: src/expr-prs.c:210
+#: src/expr-prs.c:211
#, c-format
msgid "Type mismatch: operands of %s operator must be numeric."
msgstr ""
-#: src/expr-prs.c:391
+#: src/expr-prs.c:392
msgid ""
"Chaining relational operators (e.g. \"a < b < c\") will not produce the "
"mathematically expected result. Use the AND logical operator to fix the "
"parentheses will disable this warning (e.g. \"(a < b) < c\".)"
msgstr ""
-#: src/expr-prs.c:471
+#: src/expr-prs.c:472
msgid ""
"The exponentiation operator (\"**\") is left-associative, even though right-"
"associative semantics are more useful. That is, \"a**b**c\" equals \"(a**b)"
"**c\", not as \"a**(b**c)\". To disable this warning, insert parentheses."
msgstr ""
-#: src/expr-prs.c:552
+#: src/expr-prs.c:553
#, c-format
msgid "Unknown system variable %s."
msgstr ""
-#: src/expr-prs.c:591
+#: src/expr-prs.c:592
msgid "expecting variable name"
msgstr ""
-#: src/expr-prs.c:634
+#: src/expr-prs.c:635
msgid "in expression"
msgstr ""
-#: src/expr-prs.c:730
+#: src/expr-prs.c:731
msgid "Argument 2 to LAG must be a small positive integer constant."
msgstr ""
-#: src/expr-prs.c:811 src/expr-prs.c:850
+#: src/expr-prs.c:812 src/expr-prs.c:851
#, c-format
msgid ""
"Type mismatch in argument %d of %s, which was expected to be of %s type. It "
"was actually of %s type. "
msgstr ""
-#: src/expr-prs.c:837
+#: src/expr-prs.c:838
#, c-format
msgid "%s cannot take Boolean operands."
msgstr ""
-#: src/expr-prs.c:869
+#: src/expr-prs.c:870
msgid "in function call"
msgstr ""
-#: src/expr-prs.c:883
+#: src/expr-prs.c:884
msgid "RANGE requires an odd number of arguments, but at least three."
msgstr ""
-#: src/expr-prs.c:893
+#: src/expr-prs.c:894
#, c-format
msgid "%s requires at least two arguments."
msgstr ""
-#: src/expr-prs.c:908
+#: src/expr-prs.c:909
#, c-format
msgid "%s.%d requires at least %d arguments."
msgstr ""
-#: src/expr-prs.c:973
+#: src/expr-prs.c:974
#, c-format
msgid ""
"Argument %d to CONCAT is type %s. All arguments to CONCAT must be strings."
msgstr ""
-#: src/expr-prs.c:1070
+#: src/expr-prs.c:1071
#, c-format
msgid ""
"Argument %d to %s was expected to be of %s type. It was actually of type %s."
msgstr ""
-#: src/expr-prs.c:1087
+#: src/expr-prs.c:1088
#, c-format
msgid "%s is not a numeric format."
msgstr ""
-#: src/expr-prs.c:1125
+#: src/expr-prs.c:1126
#, c-format
msgid "Too few arguments to function %s."
msgstr ""
-#: src/expr-prs.c:1158
+#: src/expr-prs.c:1159
#, c-format
msgid ""
"Type mismatch in argument %d of %s. A string expression was supplied where "
"only a numeric expression is allowed."
msgstr ""
-#: src/expr-prs.c:1168
+#: src/expr-prs.c:1169
#, c-format
msgid "Missing comma following argument %d of %s."
msgstr ""
-#: src/expr-prs.c:1206
+#: src/expr-prs.c:1207
msgid "The index value after a vector name must be numeric."
msgstr ""
-#: src/expr-prs.c:1213
+#: src/expr-prs.c:1214
msgid "`)' expected after a vector index value."
msgstr ""
-#: src/expr-prs.c:1246
+#: src/expr-prs.c:1247
#, c-format
msgid "There is no function named %s."
msgstr ""
-#: src/expr-prs.c:1251
+#: src/expr-prs.c:1252
#, c-format
msgid "Function %s may not be given a minimum number of arguments."
msgstr ""
-#: src/expr-prs.c:1260
+#: src/expr-prs.c:1261
#, c-format
msgid "expecting `)' after %s function"
msgstr ""
-#: src/expr-prs.c:1282
+#: src/expr-prs.c:1283
msgid "Boolean"
msgstr ""
-#: src/filename.c:221
-#, c-format
-msgid "Searching for `%s'..."
-msgstr ""
-
-#: src/filename.c:229 src/filename.c:261
-msgid "Search unsuccessful!"
-msgstr ""
-
-#: src/filename.c:254
-#, c-format
-msgid "Found `%s'."
-msgstr ""
-
-#: src/filename.c:686
-#, c-format
-msgid "Not opening pipe file `%s' because SAFER option set."
-msgstr ""
-
-#: src/file-type.c:127
+#: src/file-type.c:129
msgid "MIXED, GROUPED, or NESTED expected."
msgstr ""
-#: src/file-type.c:150
+#: src/file-type.c:152
msgid "The CASE subcommand is not valid on FILE TYPE MIXED."
msgstr ""
-#: src/file-type.c:168
+#: src/file-type.c:170
msgid "WARN or NOWARN expected after WILD."
msgstr ""
-#: src/file-type.c:176
+#: src/file-type.c:178
msgid "The DUPLICATE subcommand is not valid on FILE TYPE MIXED."
msgstr ""
-#: src/file-type.c:190
+#: src/file-type.c:192
msgid "DUPLICATE=CASE is only valid on FILE TYPE NESTED."
msgstr ""
-#: src/file-type.c:199
+#: src/file-type.c:201
#, c-format
msgid "WARN%s expected after DUPLICATE."
msgstr ""
-#: src/file-type.c:200
+#: src/file-type.c:202
msgid ", NOWARN, or CASE"
msgstr ""
-#: src/file-type.c:201
+#: src/file-type.c:203
msgid " or NOWARN"
msgstr ""
-#: src/file-type.c:209
+#: src/file-type.c:211
msgid "The MISSING subcommand is not valid on FILE TYPE MIXED."
msgstr ""
-#: src/file-type.c:221
+#: src/file-type.c:223
msgid "WARN or NOWARN after MISSING."
msgstr ""
-#: src/file-type.c:229
+#: src/file-type.c:231
msgid "ORDERED is only valid on FILE TYPE GROUPED."
msgstr ""
-#: src/file-type.c:240
+#: src/file-type.c:242
msgid "YES or NO expected after ORDERED."
msgstr ""
-#: src/file-type.c:246 src/file-type.c:540 src/get.c:335
+#: src/file-type.c:248 src/file-type.c:543 src/get.c:389
msgid "while expecting a valid subcommand"
msgstr ""
-#: src/file-type.c:253
+#: src/file-type.c:255
msgid "The required RECORD subcommand was not present."
msgstr ""
-#: src/file-type.c:261
+#: src/file-type.c:263
msgid "The required CASE subcommand was not present."
msgstr ""
-#: src/file-type.c:267
+#: src/file-type.c:269
msgid "CASE and RECORD must specify different variable names."
msgstr ""
-#: src/file-type.c:324
+#: src/file-type.c:327
msgid "Column value must be positive."
msgstr ""
-#: src/file-type.c:340
+#: src/file-type.c:343
msgid "Ending column precedes beginning column."
msgstr ""
-#: src/file-type.c:360
+#: src/file-type.c:363
msgid "Bad format specifier name."
msgstr ""
-#: src/file-type.c:389 src/file-type.c:577
+#: src/file-type.c:392 src/file-type.c:580
msgid ""
"This command may only appear within a FILE TYPE/END FILE TYPE structure."
msgstr ""
-#: src/file-type.c:412
+#: src/file-type.c:415
msgid "OTHER may appear only on the last RECORD TYPE command."
msgstr ""
-#: src/file-type.c:422
+#: src/file-type.c:425
msgid "No input commands (DATA LIST, REPEATING DATA) for above RECORD TYPE."
msgstr ""
-#: src/file-type.c:473
+#: src/file-type.c:476
msgid ""
"The CASE subcommand is not allowed on the RECORD TYPE command for FILE TYPE "
"MIXED."
msgstr ""
-#: src/file-type.c:483
+#: src/file-type.c:486
msgid ""
"No variable name may be specified for the CASE subcommand on RECORD TYPE."
msgstr ""
-#: src/file-type.c:491
+#: src/file-type.c:494
msgid ""
"The CASE column specification on RECORD TYPE must give a format specifier "
"that is the same type as that of the CASE column specification given on FILE "
"TYPE."
msgstr ""
-#: src/file-type.c:507
+#: src/file-type.c:510
msgid "WARN or NOWARN expected on DUPLICATE subcommand."
msgstr ""
-#: src/file-type.c:521
+#: src/file-type.c:524
msgid "WARN or NOWARN expected on MISSING subcommand."
msgstr ""
-#: src/file-type.c:534
+#: src/file-type.c:537
msgid "YES or NO expected on SPREAD subcommand."
msgstr ""
-#: src/file-type.c:590
+#: src/file-type.c:593
msgid "No input commands (DATA LIST, REPEATING DATA) on above RECORD TYPE."
msgstr ""
-#: src/file-type.c:597
+#: src/file-type.c:600
msgid "No commands between FILE TYPE and END FILE TYPE."
msgstr ""
-#: src/file-type.c:666
+#: src/file-type.c:669
#, c-format
msgid "Unknown record type \"%.*s\"."
msgstr ""
-#: src/file-type.c:690
+#: src/file-type.c:693
#, c-format
msgid "Unknown record type %g."
msgstr ""
-#: src/flip.c:77
+#: src/filename.c:221
+#, c-format
+msgid "Searching for `%s'..."
+msgstr ""
+
+#: src/filename.c:229 src/filename.c:261
+msgid "Search unsuccessful!"
+msgstr ""
+
+#: src/filename.c:254
+#, c-format
+msgid "Found `%s'."
+msgstr ""
+
+#: src/filename.c:686
+#, c-format
+msgid "Not opening pipe file `%s' because SAFER option set."
+msgstr ""
+
+#: src/flip.c:78
msgid ""
"FLIP ignores TEMPORARY. Temporary transformations will be made permanent."
msgstr ""
-#: src/flip.c:217
+#: src/flip.c:218
#, c-format
msgid "Could not create acceptable variant for variable %s."
msgstr ""
-#: src/flip.c:233
+#: src/flip.c:234
msgid "Cannot create more than 99999 variable names."
msgstr ""
-#: src/flip.c:277
+#: src/flip.c:278
msgid "Could not create temporary file for FLIP."
msgstr ""
-#: src/flip.c:284 src/flip.c:352
+#: src/flip.c:285 src/flip.c:353
#, c-format
msgid "Error writing FLIP file: %s."
msgstr ""
-#: src/flip.c:394
+#: src/flip.c:395
#, c-format
msgid "Error rewinding FLIP file: %s."
msgstr ""
-#: src/flip.c:398
+#: src/flip.c:399
msgid "Error creating FLIP source file."
msgstr ""
-#: src/flip.c:407
+#: src/flip.c:408
#, c-format
msgid "Error reading FLIP file: %s."
msgstr ""
-#: src/flip.c:424
+#: src/flip.c:425
#, c-format
msgid "Error seeking FLIP source file: %s."
msgstr ""
-#: src/flip.c:429
+#: src/flip.c:430
#, c-format
msgid "Error writing FLIP source file: %s."
msgstr ""
-#: src/flip.c:440
+#: src/flip.c:441
#, c-format
msgid "Error rewind FLIP source file: %s."
msgstr ""
-#: src/flip.c:492
+#: src/flip.c:493
#, c-format
msgid "Error reading FLIP temporary file: %s."
msgstr ""
-#: src/flip.c:495
+#: src/flip.c:496
msgid "Unexpected end of file reading FLIP temporary file."
msgstr ""
msgid "Format %s may not be assigned to a %s variable."
msgstr ""
-#: src/formats.c:116 src/numeric.c:64 src/numeric.c:135
+#: src/formats.c:116 src/numeric.c:65 src/numeric.c:136
msgid "`)' expected after output format."
msgstr ""
-#: src/get.c:341
+#: src/get.c:395
msgid "All variables deleted from system file dictionary."
msgstr ""
-#: src/get.c:388
+#: src/get.c:445
#, c-format
msgid ""
"Cannot rename %s as %s because there already exists a variable named %s. To "
"as \"/RENAME (A=B)(B=C)(C=A)\", or equivalently, \"/RENAME (A B C=B C A)\"."
msgstr ""
-#: src/get.c:413
+#: src/get.c:470
msgid "`=' expected after variable list."
msgstr ""
-#: src/get.c:420
+#: src/get.c:477
#, 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:433
+#: src/get.c:490
#, c-format
msgid "Requested renaming duplicates variable name %s."
msgstr ""
-#: src/get.c:564
+#: src/get.c:674
msgid "The BY subcommand may be given once at most."
msgstr ""
-#: src/get.c:631
+#: src/get.c:746
msgid "The active file may not be specified more than once."
msgstr ""
-#: src/get.c:640
+#: src/get.c:755
msgid "Cannot specify the active file since no active file has been defined."
msgstr ""
-#: src/get.c:648
+#: src/get.c:763
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:682
+#: src/get.c:793
msgid ""
"IN, FIRST, and LAST subcommands may not occur before the first FILE or TABLE."
msgstr ""
-#: src/get.c:717
+#: src/get.c:828
#, c-format
msgid "Multiple %s subcommands for a single FILE or TABLE."
msgstr ""
-#: src/get.c:727
+#: src/get.c:838
#, c-format
msgid "Duplicate variable name %s while creating %s variable."
msgstr ""
-#: src/get.c:741
+#: src/get.c:850
msgid ""
"RENAME, KEEP, and DROP subcommands may not occur before the first FILE or "
"TABLE."
msgstr ""
-#: src/get.c:765
+#: src/get.c:877
msgid "The BY subcommand is required when a TABLE subcommand is given."
msgstr ""
-#: src/get.c:786
+#: src/get.c:896
#, c-format
msgid "File %s lacks BY variable %s."
msgstr ""
-#: src/get.c:1282
+#: src/get.c:1390
#, 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:1330
+#: src/get.c:1468
msgid "expecting COMM or TAPE"
msgstr ""
msgid "HTML output driver: %s: %s"
msgstr ""
-#: src/html.c:403 src/list.q:250
+#: src/html.c:403 src/list.q:252
#, c-format
msgid "Cannot open first page on HTML device %s."
msgstr ""
msgid "expecting filename"
msgstr ""
-#: src/inpt-pgm.c:81
+#: src/inpt-pgm.c:82
msgid "No matching INPUT PROGRAM command."
msgstr ""
-#: src/inpt-pgm.c:86
+#: src/inpt-pgm.c:87
msgid ""
"No data-input or transformation commands specified between INPUT PROGRAM and "
"END INPUT PROGRAM."
msgstr ""
-#: src/inpt-pgm.c:287 src/inpt-pgm.c:420
+#: src/inpt-pgm.c:288 src/inpt-pgm.c:418
msgid ""
"This command may only be executed between INPUT PROGRAM and END INPUT "
"PROGRAM."
msgstr ""
-#: src/inpt-pgm.c:342
+#: src/inpt-pgm.c:338
msgid "COLUMN subcommand multiply specified."
msgstr ""
-#: src/inpt-pgm.c:395
+#: src/inpt-pgm.c:391
msgid ""
"REREAD: Column numbers must be positive finite numbers. Column set to 1."
msgstr ""
msgid "<ERROR>"
msgstr ""
-#: src/lexer.c:993 src/pfm-read.c:136 src/repeat.c:213
+#: src/lexer.c:993 src/pfm-read.c:134 src/repeat.c:214
msgid "Unexpected end of file."
msgstr ""
"spaces."
msgstr ""
-#: src/loop.c:193
+#: src/loop.c:194
msgid "The index variable may not be a string variable."
msgstr ""
-#: src/loop.c:299
+#: src/loop.c:300
msgid "There is no LOOP command that corresponds to this END LOOP."
msgstr ""
-#: src/loop.c:493
+#: src/loop.c:494
msgid ""
"This command may only appear enclosed in a LOOP/END LOOP control structure."
msgstr ""
-#: src/loop.c:499
+#: src/loop.c:500
msgid "BREAK not enclosed in DO IF structure."
msgstr ""
-#: src/loop.c:577
+#: src/loop.c:578
#, c-format
msgid "%s without %s."
msgstr ""
-#: src/main.c:74
+#: src/main.c:76
msgid "Error initializing output drivers."
msgstr ""
-#: src/main.c:140
+#: src/main.c:146
msgid "This command not executed."
msgstr ""
-#: src/main.c:144
+#: src/main.c:150
msgid ""
"Skipping the rest of this command. Part of this command may have been "
"executed."
msgstr ""
-#: src/main.c:149
+#: src/main.c:155
msgid ""
"Skipping the rest of this command. This command was fully executed up to "
"this point."
msgstr ""
-#: src/main.c:154
+#: src/main.c:160
msgid ""
"Trailing garbage was encountered following this command. The command was "
"fully executed to this point."
msgstr ""
-#: src/main.c:171
+#: src/main.c:177
msgid "The rest of this command has been discarded."
msgstr ""
-#: src/matrix-data.c:185
+#: src/matrix-data.c:208
msgid "VARIABLES subcommand multiply specified."
msgstr ""
-#: src/matrix-data.c:200
+#: src/matrix-data.c:223
msgid "VARNAME_ cannot be explicitly specified on VARIABLES."
msgstr ""
-#: src/matrix-data.c:265
+#: src/matrix-data.c:284
msgid "in FORMAT subcommand"
msgstr ""
-#: src/matrix-data.c:276
+#: src/matrix-data.c:295
msgid "SPLIT subcommand multiply specified."
msgstr ""
-#: src/matrix-data.c:283
+#: src/matrix-data.c:302
msgid "in SPLIT subcommand"
msgstr ""
-#: src/matrix-data.c:292
+#: src/matrix-data.c:311
msgid "Split variable may not be named ROWTYPE_ or VARNAME_."
msgstr ""
-#: src/matrix-data.c:325
+#: src/matrix-data.c:345
#, c-format
msgid "Split variable %s is already another type."
msgstr ""
-#: src/matrix-data.c:340
+#: src/matrix-data.c:360
msgid "FACTORS subcommand multiply specified."
msgstr ""
-#: src/matrix-data.c:355
+#: src/matrix-data.c:378
#, c-format
msgid "Factor variable %s is already another type."
msgstr ""
-#: src/matrix-data.c:370
+#: src/matrix-data.c:393
msgid "CELLS subcommand multiply specified."
msgstr ""
-#: src/matrix-data.c:376 src/matrix-data.c:395
+#: src/matrix-data.c:399 src/matrix-data.c:418
msgid "expecting positive integer"
msgstr ""
-#: src/matrix-data.c:389
+#: src/matrix-data.c:412
msgid "N subcommand multiply specified."
msgstr ""
-#: src/matrix-data.c:410
+#: src/matrix-data.c:433
msgid "CONTENTS subcommand multiply specified."
msgstr ""
-#: src/matrix-data.c:430
+#: src/matrix-data.c:453
msgid "Nested parentheses not allowed."
msgstr ""
-#: src/matrix-data.c:440
+#: src/matrix-data.c:463
msgid "Mismatched right parenthesis (`(')."
msgstr ""
-#: src/matrix-data.c:445
+#: src/matrix-data.c:468
msgid "Empty parentheses not allowed."
msgstr ""
-#: src/matrix-data.c:458 src/matrix-data.c:466
+#: src/matrix-data.c:481 src/matrix-data.c:489
msgid "in CONTENTS subcommand"
msgstr ""
-#: src/matrix-data.c:473
+#: src/matrix-data.c:496
#, c-format
msgid "Content multiply specified for %s."
msgstr ""
-#: src/matrix-data.c:490
+#: src/matrix-data.c:513
msgid "Missing right parenthesis."
msgstr ""
-#: src/matrix-data.c:510
+#: src/matrix-data.c:533
msgid "Missing VARIABLES subcommand."
msgstr ""
-#: src/matrix-data.c:516
+#: src/matrix-data.c:539
msgid ""
"CONTENTS subcommand not specified: assuming file contains only CORR matrix."
msgstr ""
-#: src/matrix-data.c:526
+#: src/matrix-data.c:549
msgid ""
"Missing CELLS subcommand. CELLS is required when ROWTYPE_ is not given in "
"the data and factors are present."
msgstr ""
-#: src/matrix-data.c:534
+#: src/matrix-data.c:557
msgid "Split file values must be present in the data when ROWTYPE_ is present."
msgstr ""
-#: src/matrix-data.c:589
+#: src/matrix-data.c:610
msgid "No continuous variables specified."
msgstr ""
-#: src/matrix-data.c:815
+#: src/matrix-data.c:853
msgid "Scope of string exceeds line."
msgstr ""
-#: src/matrix-data.c:882
+#: src/matrix-data.c:920
#, c-format
msgid "End of line expected %s while reading %s."
msgstr ""
-#: src/matrix-data.c:1070
+#: src/matrix-data.c:1106
#, c-format
msgid "expecting value for %s %s"
msgstr ""
-#: src/matrix-data.c:1232
+#: src/matrix-data.c:1270
#, c-format
msgid "Syntax error expecting SPLIT FILE value %s."
msgstr ""
-#: src/matrix-data.c:1241
+#: src/matrix-data.c:1279
#, c-format
msgid "Expecting value %g for %s."
msgstr ""
-#: src/matrix-data.c:1282 src/matrix-data.c:1750
+#: src/matrix-data.c:1320 src/matrix-data.c:1787
#, c-format
msgid "Syntax error expecting factor value %s."
msgstr ""
-#: src/matrix-data.c:1291
+#: src/matrix-data.c:1329
#, c-format
msgid "Syntax error expecting value %g for %s %s."
msgstr ""
-#: src/matrix-data.c:1527
+#: src/matrix-data.c:1564
#, c-format
msgid "Syntax error %s expecting SPLIT FILE value."
msgstr ""
-#: src/matrix-data.c:1657
+#: src/matrix-data.c:1694
#, c-format
msgid ""
"Expected %d lines of data for %s content; actually saw %d lines. No data "
"will be output for this content."
msgstr ""
-#: src/matrix-data.c:1692
+#: src/matrix-data.c:1729
#, c-format
msgid "Multiply specified ROWTYPE_ %s."
msgstr ""
-#: src/matrix-data.c:1697
+#: src/matrix-data.c:1734
#, c-format
msgid "Syntax error %s expecting ROWTYPE_ string."
msgstr ""
-#: src/matrix-data.c:1717
+#: src/matrix-data.c:1754
#, c-format
msgid "Syntax error %s."
msgstr ""
-#: src/matrix-data.c:1867
+#: src/matrix-data.c:1904
#, c-format
msgid "Duplicate specification for %s."
msgstr ""
-#: src/matrix-data.c:1879
+#: src/matrix-data.c:1916
#, c-format
msgid "Too many rows of matrix data for %s."
msgstr ""
-#: src/matrix-data.c:1927
+#: src/matrix-data.c:1964
#, c-format
msgid "Syntax error expecting value for %s %s."
msgstr ""
msgid "String is not of proper length."
msgstr ""
-#: src/mis-val.c:316 src/repeat.c:459
+#: src/mis-val.c:316 src/repeat.c:460
msgid "String expected."
msgstr ""
-#: src/modify-vars.c:88
+#: src/modify-vars.c:89
msgid ""
"MODIFY VARS may not be used after TEMPORARY. Temporary transformations will "
"be made permanent."
msgstr ""
-#: src/modify-vars.c:112
+#: src/modify-vars.c:113
msgid "REORDER subcommand may be given at most once."
msgstr ""
-#: src/modify-vars.c:135
+#: src/modify-vars.c:136
msgid "Cannot specify ALL after specifying a set of variables."
msgstr ""
-#: src/modify-vars.c:145
+#: src/modify-vars.c:146
msgid "`(' expected on REORDER subcommand."
msgstr ""
-#: src/modify-vars.c:157
+#: src/modify-vars.c:158
msgid "`)' expected following variable names on REORDER subcommand."
msgstr ""
-#: src/modify-vars.c:175
+#: src/modify-vars.c:176
msgid "RENAME subcommand may be given at most once."
msgstr ""
-#: src/modify-vars.c:188
+#: src/modify-vars.c:189
msgid "`(' expected on RENAME subcommand."
msgstr ""
-#: src/modify-vars.c:196
+#: src/modify-vars.c:197
msgid ""
"`=' expected between lists of new and old variable names on RENAME "
"subcommand."
msgstr ""
-#: src/modify-vars.c:204 src/rename-vars.c:74
+#: src/modify-vars.c:205 src/rename-vars.c:75
#, c-format
msgid ""
"Differing number of variables in old name list (%d) and in new name list (%"
"d)."
msgstr ""
-#: src/modify-vars.c:215
+#: src/modify-vars.c:216
msgid "`)' expected after variable lists on RENAME subcommand."
msgstr ""
-#: src/modify-vars.c:229
+#: src/modify-vars.c:230
msgid ""
"KEEP subcommand may be given at most once. It may notbe given in "
"conjunction with the DROP subcommand."
msgstr ""
-#: src/modify-vars.c:271
+#: src/modify-vars.c:272
msgid ""
"DROP subcommand may be given at most once. It may not be given in "
"conjunction with the KEEP subcommand."
msgstr ""
-#: src/modify-vars.c:297
+#: src/modify-vars.c:298
#, c-format
msgid "Unrecognized subcommand name `%s'."
msgstr ""
-#: src/modify-vars.c:299
+#: src/modify-vars.c:300
msgid "Subcommand name expected."
msgstr ""
-#: src/modify-vars.c:307
+#: src/modify-vars.c:308
msgid "`/' or `.' expected."
msgstr ""
msgid "expecting weight value"
msgstr ""
-#: src/numeric.c:57
+#: src/numeric.c:58
#, c-format
msgid "Format type %s may not be used with a numeric variable."
msgstr ""
-#: src/numeric.c:76 src/numeric.c:158 src/vector.c:155
+#: src/numeric.c:77 src/numeric.c:159 src/vector.c:156
#, c-format
msgid "There is already a variable named %s."
msgstr ""
-#: src/numeric.c:128
+#: src/numeric.c:129
#, c-format
msgid "Format type %s may not be used with a string variable."
msgstr ""
msgid "portable file %s corrupt at offset %ld: "
msgstr ""
-#: src/pfm-read.c:111 src/pfm-write.c:504
+#: src/pfm-read.c:114 src/pfm-write.c:490
#, c-format
msgid "%s: Closing portable file: %s."
msgstr ""
-#: src/pfm-read.c:144
+#: src/pfm-read.c:142
msgid "Bad line end."
msgstr ""
-#: src/pfm-read.c:225
-#, c-format
-msgid "Cannot read file %s as portable file: already opened for %s."
-msgstr ""
-
-#: src/pfm-read.c:231
-#, c-format
-msgid "%s: Opening portable-file handle %s for reading."
-msgstr ""
-
-#: src/pfm-read.c:239
+#: src/pfm-read.c:233
#, c-format
msgid ""
"An error occurred while opening \"%s\" for reading as a portable file: %s."
msgstr ""
-#: src/pfm-read.c:274
+#: src/pfm-read.c:256
msgid "Data record expected."
msgstr ""
-#: src/pfm-read.c:276
-msgid "Read portable-file dictionary successfully."
-msgstr ""
-
-#: src/pfm-read.c:282
-msgid "Error reading portable-file dictionary."
-msgstr ""
-
-#: src/pfm-read.c:380
+#: src/pfm-read.c:353
msgid "Missing numeric terminator."
msgstr ""
-#: src/pfm-read.c:417
+#: src/pfm-read.c:390
msgid "Bad integer format."
msgstr ""
-#: src/pfm-read.c:447
+#: src/pfm-read.c:419
#, c-format
msgid "Bad string length %d."
msgstr ""
-#: src/pfm-read.c:546
+#: src/pfm-read.c:514
#, c-format
msgid "Bad date string length %d."
msgstr ""
-#: src/pfm-read.c:550
+#: src/pfm-read.c:518
msgid "Bad character in date."
msgstr ""
-#: src/pfm-read.c:570
+#: src/pfm-read.c:538
#, c-format
msgid "Bad time string length %d."
msgstr ""
-#: src/pfm-read.c:574
+#: src/pfm-read.c:542
msgid "Bad character in time."
msgstr ""
-#: src/pfm-read.c:624 src/pfm-read.c:631 src/sfm-read.c:912 src/sfm-read.c:920
+#: src/pfm-read.c:592 src/pfm-read.c:599 src/sfm-read.c:873 src/sfm-read.c:881
#, c-format
msgid "%s: Bad format specifier byte (%d)."
msgstr ""
-#: src/pfm-read.c:633
+#: src/pfm-read.c:601
#, c-format
msgid "%s variable %s has %s format specifier %s."
msgstr ""
-#: src/pfm-read.c:634 src/print.c:601 src/sfm-read.c:925
+#: src/pfm-read.c:602 src/print.c:607 src/sfm-read.c:886
msgid "String"
msgstr ""
-#: src/pfm-read.c:634 src/print.c:601 src/sfm-read.c:925
+#: src/pfm-read.c:602 src/print.c:607 src/sfm-read.c:886
msgid "Numeric"
msgstr ""
-#: src/pfm-read.c:673
+#: src/pfm-read.c:640
msgid "Expected variable count record."
msgstr ""
-#: src/pfm-read.c:677
+#: src/pfm-read.c:644
#, c-format
msgid "Invalid number of variables %d."
msgstr ""
-#: src/pfm-read.c:687
+#: src/pfm-read.c:654
#, c-format
msgid "Unexpected flag value %d."
msgstr ""
-#: src/pfm-read.c:701
+#: src/pfm-read.c:666
#, c-format
msgid "Weight variable name (%s) truncated."
msgstr ""
-#: src/pfm-read.c:716
+#: src/pfm-read.c:681
msgid "Expected variable record."
msgstr ""
-#: src/pfm-read.c:722
+#: src/pfm-read.c:687
#, c-format
msgid "Invalid variable width %d."
msgstr ""
-#: src/pfm-read.c:740
+#: src/pfm-read.c:705
#, c-format
msgid "position %d: Variable name has %u characters."
msgstr ""
-#: src/pfm-read.c:744
+#: src/pfm-read.c:709
#, c-format
msgid "position %d: Variable name begins with invalid character."
msgstr ""
-#: src/pfm-read.c:748
+#: src/pfm-read.c:713
#, c-format
msgid "position %d: Variable name begins with lowercase letter %c."
msgstr ""
-#: src/pfm-read.c:761
+#: src/pfm-read.c:726
#, c-format
msgid "position %d: Variable name character %d is lowercase letter %c."
msgstr ""
-#: src/pfm-read.c:771
+#: src/pfm-read.c:736
#, c-format
msgid "position %d: character `\\%03o' is not valid in a variable name."
msgstr ""
-#: src/pfm-read.c:782
+#: src/pfm-read.c:748
#, c-format
msgid "Duplicate variable name %s."
msgstr ""
-#: src/pfm-read.c:826
+#: src/pfm-read.c:792
#, c-format
msgid "Bad missing values for %s."
msgstr ""
-#: src/pfm-read.c:849
+#: src/pfm-read.c:815
#, c-format
msgid "Weighting variable %s not present in dictionary."
msgstr ""
-#: src/pfm-read.c:922
+#: src/pfm-read.c:886
#, c-format
msgid "Unknown variable %s while parsing value labels."
msgstr ""
-#: src/pfm-read.c:925
+#: src/pfm-read.c:889
#, c-format
msgid ""
"Cannot assign value labels to %s and %s, which have different variable types "
"or widths."
msgstr ""
-#: src/pfm-read.c:958
+#: src/pfm-read.c:922
#, c-format
msgid "Duplicate label for value %g for variable %s."
msgstr ""
-#: src/pfm-read.c:961
+#: src/pfm-read.c:925
#, c-format
msgid "Duplicate label for value `%.*s' for variable %s."
msgstr ""
-#: src/pfm-read.c:1032
+#: src/pfm-read.c:978
msgid "End of file midway through case."
msgstr ""
-#: src/pfm-read.c:1042
-msgid "reading as a portable file"
-msgstr ""
-
-#: src/pfm-write.c:71
-#, c-format
-msgid "Cannot write file %s as portable file: already opened for %s."
-msgstr ""
-
-#: src/pfm-write.c:77
-#, c-format
-msgid "%s: Opening portable-file handle %s for writing."
-msgstr ""
-
-#: src/pfm-write.c:87
+#: src/pfm-write.c:92
#, c-format
msgid ""
"An error occurred while opening \"%s\" for writing as a portable file: %s."
msgstr ""
-#: src/pfm-write.c:124
-msgid "Wrote portable-file header successfully."
-msgstr ""
-
-#: src/pfm-write.c:129
-msgid "Error writing portable-file header."
-msgstr ""
-
-#: src/pfm-write.c:170
+#: src/pfm-write.c:154
#, c-format
msgid "%s: Writing portable file: %s."
msgstr ""
-#: src/pfm-write.c:514
-msgid "writing as a portable file"
-msgstr ""
-
#: src/postscript.c:323
#, c-format
msgid "PostScript driver initializing as `%s'..."
msgid "PostScript driver: Cannot find encoding `%s' for PostScript font `%s'."
msgstr ""
-#: src/print.c:180
+#: src/print.c:179
msgid "expecting a valid subcommand"
msgstr ""
-#: src/print.c:359 src/print.c:376
+#: src/print.c:365 src/print.c:382
#, c-format
msgid "%g is not a valid column location."
msgstr ""
-#: src/print.c:370
+#: src/print.c:376
#, c-format
msgid "Column location expected following `%d-'."
msgstr ""
-#: src/print.c:381
+#: src/print.c:387
#, c-format
msgid ""
"%d-%ld is not a valid column range. The second column must be greater than "
"or equal to the first."
msgstr ""
-#: src/print.c:487
+#: src/print.c:493
#, c-format
msgid ""
"%s is not of the same type as %s. To specify variables of different types "
"in the same variable list, use a FORTRAN-like format specifier."
msgstr ""
-#: src/print.c:517
+#: src/print.c:523
msgid ""
"The ending column for a field must not be less than the starting column."
msgstr ""
-#: src/print.c:600
+#: src/print.c:606
#, c-format
msgid "%s variables cannot be displayed with format %s."
msgstr ""
-#: src/print.c:678
+#: src/print.c:684
msgid ""
"The number of format specifications exceeds the number of variable names "
"given."
msgstr ""
-#: src/print.c:687
+#: src/print.c:693
#, c-format
msgid "Display format %s may not be used with a %s variable."
msgstr ""
-#: src/print.c:835
+#: src/print.c:841
#, c-format
msgid "Writing %d record(s) to file %s."
msgstr ""
-#: src/print.c:838
+#: src/print.c:844
#, c-format
msgid "Writing %d record(s) to the listing file."
msgstr ""
-#: src/print.c:1080
+#: src/print.c:1092
#, c-format
msgid ""
"The expression on PRINT SPACE evaluated to %d. It's not possible to PRINT "
"SPACE a negative number of lines."
msgstr ""
-#: src/recode.c:282
+#: src/recode.c:283
#, c-format
msgid ""
"%d variable(s) cannot be recoded into %d variable(s). Specify the same "
"number of variables as input and output variables."
msgstr ""
-#: src/recode.c:296
+#: src/recode.c:297
#, c-format
msgid ""
"There is no string variable named %s. (All string variables specified on "
"variable.)"
msgstr ""
-#: src/recode.c:305
+#: src/recode.c:306
#, c-format
msgid ""
"Type mismatch between input and output variables. Output variable %s is not "
"a string variable, but all the input variables are string variables."
msgstr ""
-#: src/recode.c:324
+#: src/recode.c:325
#, c-format
msgid "Type mismatch after INTO: %s is not a numeric variable."
msgstr ""
-#: src/recode.c:354
+#: src/recode.c:355
msgid ""
"INTO must be used when the input values are numeric and output values are "
"string."
msgstr ""
-#: src/recode.c:362
+#: src/recode.c:363
msgid ""
"INTO must be used when the input values are string and output values are "
"numeric."
msgstr ""
-#: src/recode.c:485
+#: src/recode.c:486
msgid "expecting output value"
msgstr ""
-#: src/recode.c:499
+#: src/recode.c:500
msgid ""
"Inconsistent output types. The output values must be all numeric or all "
"string."
msgstr ""
-#: src/recode.c:550
+#: src/recode.c:551
msgid "following LO THRU"
msgstr ""
-#: src/recode.c:566 src/recode.c:595
+#: src/recode.c:567 src/recode.c:596
msgid "in source value"
msgstr ""
-#: src/recode.c:608
+#: src/recode.c:609
msgid ""
"Keyword CONVERT may only be used with string input values and numeric output "
"values."
msgstr ""
-#: src/rename-vars.c:47
+#: src/rename-vars.c:48
msgid ""
"RENAME VARS may not be used after TEMPORARY. Temporary transformations will "
"be made permanent."
msgstr ""
-#: src/rename-vars.c:59
+#: src/rename-vars.c:60
msgid "`(' expected."
msgstr ""
-#: src/rename-vars.c:67
+#: src/rename-vars.c:68
msgid "`=' expected between lists of new and old variable names."
msgstr ""
-#: src/rename-vars.c:85
+#: src/rename-vars.c:86
msgid "`)' expected after variable names."
msgstr ""
-#: src/rename-vars.c:95
+#: src/rename-vars.c:96
#, c-format
msgid "Renaming would duplicate variable name %s."
msgstr ""
-#: src/repeat.c:150
+#: src/repeat.c:151
#, c-format
msgid "Identifier %s is given twice."
msgstr ""
-#: src/repeat.c:193
+#: src/repeat.c:194
#, c-format
msgid ""
"There must be the same number of substitutions for each dummy variable "
"s as well, but %d were specified."
msgstr ""
-#: src/repeat.c:298
+#: src/repeat.c:299
msgid "No commands in scope."
msgstr ""
-#: src/repeat.c:486
+#: src/repeat.c:487
msgid "No matching DO REPEAT."
msgstr ""
msgid "Cannot sample %d observations from a population of %d."
msgstr ""
-#: src/sel-if.c:99
+#: src/sel-if.c:100
msgid "The filter variable must be numeric."
msgstr ""
-#: src/sel-if.c:105
+#: src/sel-if.c:106
msgid "The filter variable may not be scratch."
msgstr ""
-#: src/sel-if.c:136
+#: src/sel-if.c:137
msgid "Only last instance of this command is in effect."
msgstr ""
-#: src/sfm-read.c:147
+#: src/sfm-read.c:140
msgid "corrupt system file: "
msgstr ""
-#: src/sfm-read.c:163 src/sfm-write.c:743
+#: src/sfm-read.c:157 src/sfm-write.c:808
#, c-format
msgid "%s: Closing system file: %s."
msgstr ""
-#: src/sfm-read.c:237
-#, c-format
-msgid "Cannot read file %s as system file: already opened for %s."
-msgstr ""
-
-#: src/sfm-read.c:242
-#, c-format
-msgid "%s: Opening system-file handle %s for reading."
-msgstr ""
-
-#: src/sfm-read.c:250
+#: src/sfm-read.c:240
#, c-format
msgid ""
"An error occurred while opening \"%s\" for reading as a system file: %s."
msgstr ""
-#: src/sfm-read.c:285
+#: src/sfm-read.c:258
#, c-format
msgid ""
"%s: Weighting variable may not be a continuation of a long string variable."
msgstr ""
-#: src/sfm-read.c:288
+#: src/sfm-read.c:261
#, c-format
msgid "%s: Weighting variable may not be a string variable."
msgstr ""
-#: src/sfm-read.c:313
+#: src/sfm-read.c:286
#, 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:362
+#: src/sfm-read.c:335
#, c-format
msgid "%s: Unrecognized record type 7, subtype %d encountered in system file."
msgstr ""
-#: src/sfm-read.c:387
+#: src/sfm-read.c:360
#, c-format
msgid "%s: Unrecognized record type %d."
msgstr ""
-#: src/sfm-read.c:394
-msgid "Read system-file dictionary successfully."
-msgstr ""
-
-#: src/sfm-read.c:401
-msgid "Error reading system-file header."
-msgstr ""
-
-#: src/sfm-read.c:425
+#: src/sfm-read.c:392
#, 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:437
+#: src/sfm-read.c:403
#, 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:453
+#: src/sfm-read.c:419
#, c-format
msgid ""
"%s: File-indicated endianness (%s) does not match endianness intuited from "
"file header (%s)."
msgstr ""
-#: src/sfm-read.c:456 src/sfm-read.c:457
+#: src/sfm-read.c:422 src/sfm-read.c:423
msgid "big-endian"
msgstr ""
-#: src/sfm-read.c:456 src/sfm-read.c:457
+#: src/sfm-read.c:422 src/sfm-read.c:423
msgid "little-endian"
msgstr ""
-#: src/sfm-read.c:458
+#: src/sfm-read.c:424
msgid "unknown"
msgstr ""
-#: src/sfm-read.c:462
+#: src/sfm-read.c:428
#, c-format
msgid "%s: File-indicated character representation code (%s) is not ASCII."
msgstr ""
-#: src/sfm-read.c:466
+#: src/sfm-read.c:432
msgid "DEC Kanji"
msgstr ""
-#: src/sfm-read.c:485
+#: src/sfm-read.c:448
#, 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:500
+#: src/sfm-read.c:463
#, c-format
msgid ""
"%s: File-indicated value is different from internal value for at least one "
"%g; LOWEST: %g, %g."
msgstr ""
-#: src/sfm-read.c:531
+#: src/sfm-read.c:490
#, 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:574
+#: src/sfm-read.c:532
#, 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:590
+#: src/sfm-read.c:548
#, c-format
msgid "%s: Number of elements per case (%d) is not between 1 and %d."
msgstr ""
-#: src/sfm-read.c:599
+#: src/sfm-read.c:557
#, 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:605
+#: src/sfm-read.c:564
#, c-format
msgid "%s: Number of cases in file (%ld) is not between -1 and %d."
msgstr ""
-#: src/sfm-read.c:610
+#: src/sfm-read.c:569
#, c-format
msgid "%s: Compression bias (%g) is not the usual value of 100."
msgstr ""
-#: src/sfm-read.c:704
+#: src/sfm-read.c:662
#, c-format
msgid "%s: position %d: Bad record type (%d); the expected value was 2."
msgstr ""
-#: src/sfm-read.c:714
+#: src/sfm-read.c:672
#, c-format
msgid ""
"%s: position %d: String variable does not have proper number of continuation "
"records."
msgstr ""
-#: src/sfm-read.c:723
+#: src/sfm-read.c:681
#, c-format
msgid "%s: position %d: Superfluous long string continuation record."
msgstr ""
-#: src/sfm-read.c:729
+#: src/sfm-read.c:687
#, c-format
msgid "%s: position %d: Bad variable type code %d."
msgstr ""
-#: src/sfm-read.c:732
+#: src/sfm-read.c:690
#, c-format
msgid "%s: position %d: Variable label indicator field is not 0 or 1."
msgstr ""
-#: src/sfm-read.c:736
+#: src/sfm-read.c:694
#, c-format
msgid ""
"%s: position %d: Missing value indicator field is not -3, -2, 0, 1, 2, or 3."
msgstr ""
-#: src/sfm-read.c:742
+#: src/sfm-read.c:700
#, c-format
msgid "%s: position %d: Variable name begins with invalid character."
msgstr ""
-#: src/sfm-read.c:746
+#: src/sfm-read.c:704
#, c-format
msgid "%s: position %d: Variable name begins with lowercase letter %c."
msgstr ""
-#: src/sfm-read.c:750
+#: src/sfm-read.c:708
#, c-format
msgid ""
"%s: position %d: Variable name begins with octothorpe (`#'). Scratch "
"variables should not appear in system files."
msgstr ""
-#: src/sfm-read.c:765
+#: src/sfm-read.c:723
#, c-format
msgid "%s: position %d: Variable name character %d is lowercase letter %c."
msgstr ""
-#: src/sfm-read.c:774
+#: src/sfm-read.c:732
#, c-format
msgid ""
"%s: position %d: character `\\%03o' (%c) is not valid in a variable name."
msgstr ""
-#: src/sfm-read.c:783
+#: src/sfm-read.c:741
#, c-format
msgid "%s: Duplicate variable name `%s' within system file."
msgstr ""
-#: src/sfm-read.c:808
+#: src/sfm-read.c:762
#, c-format
msgid "%s: Variable %s indicates variable label of invalid length %d."
msgstr ""
-#: src/sfm-read.c:825
+#: src/sfm-read.c:779
#, c-format
msgid "%s: Long string variable %s may not have missing values."
msgstr ""
-#: src/sfm-read.c:850
+#: src/sfm-read.c:804
#, c-format
msgid ""
"%s: String variable %s may not have missing values specified as a range."
msgstr ""
-#: src/sfm-read.c:888
+#: src/sfm-read.c:852
#, c-format
msgid "%s: Long string continuation records omitted at end of dictionary."
msgstr ""
-#: src/sfm-read.c:892
+#: src/sfm-read.c:856
#, c-format
msgid ""
"%s: System file header indicates %d variable positions but %d were read from "
"file."
msgstr ""
-#: src/sfm-read.c:923
+#: src/sfm-read.c:884
#, c-format
msgid "%s: %s variable %s has %s format specifier %s."
msgstr ""
-#: src/sfm-read.c:1003
+#: src/sfm-read.c:963
#, 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:1014
+#: src/sfm-read.c:974
#, 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:1030
+#: src/sfm-read.c:990
#, 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:1037
+#: src/sfm-read.c:997
#, 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:1042
+#: src/sfm-read.c:1002
#, c-format
msgid "%s: Value labels are not allowed on long string variables (%s)."
msgstr ""
-#: src/sfm-read.c:1053
+#: src/sfm-read.c:1013
#, 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:1094
+#: src/sfm-read.c:1054
#, c-format
msgid "%s: File contains duplicate label for value %g for variable %s."
msgstr ""
-#: src/sfm-read.c:1098
+#: src/sfm-read.c:1058
#, c-format
msgid "%s: File contains duplicate label for value `%.*s' for variable %s."
msgstr ""
-#: src/sfm-read.c:1135 src/sfm-read.c:1338
+#: src/sfm-read.c:1093 src/sfm-read.c:1357
#, c-format
msgid "%s: Reading system file: %s."
msgstr ""
-#: src/sfm-read.c:1138 src/sfm-read.c:1245 src/sfm-read.c:1287
+#: src/sfm-read.c:1096 src/sfm-read.c:1198 src/sfm-read.c:1240
#, c-format
msgid "%s: Unexpected end of file."
msgstr ""
-#: src/sfm-read.c:1157
+#: src/sfm-read.c:1113
#, c-format
msgid "%s: System file contains multiple type 6 (document) records."
msgstr ""
-#: src/sfm-read.c:1163
+#: src/sfm-read.c:1119
#, c-format
msgid "%s: Number of document lines (%ld) must be greater than 0."
msgstr ""
-#: src/sfm-read.c:1196
+#: src/sfm-read.c:1151
#, c-format
msgid "%s: Error reading file: %s."
msgstr ""
-#: src/sfm-read.c:1235
+#: src/sfm-read.c:1188
#, c-format
msgid "%s: Compressed data is corrupted. Data ends in partial case."
msgstr ""
-#: src/sfm-read.c:1341
+#: src/sfm-read.c:1360
#, c-format
msgid "%s: Partial record at end of system file."
msgstr ""
-#: src/sfm-read.c:1380
-msgid "reading as a system file"
-msgstr ""
-
-#: src/sfm-write.c:95
-#, c-format
-msgid "Cannot write file %s as system file: already opened for %s."
-msgstr ""
-
-#: src/sfm-write.c:101
-#, c-format
-msgid "%s: Opening system-file handle %s for writing."
-msgstr ""
-
-#: src/sfm-write.c:111
+#: src/sfm-write.c:143
#, c-format
-msgid ""
-"An error occurred while opening \"%s\" for writing as a system file: %s."
-msgstr ""
-
-#: src/sfm-write.c:165
-msgid "Wrote system-file header successfully."
+msgid "Error opening \"%s\" for writing as a system file: %s."
msgstr ""
-#: src/sfm-write.c:170
-msgid "Error writing system-file header."
-msgstr ""
-
-#: src/sfm-write.c:606
+#: src/sfm-write.c:628
#, c-format
msgid "%s: Writing system file: %s."
msgstr ""
-#: src/sfm-write.c:754
-msgid "writing as a system file"
-msgstr ""
-
#: src/sort.c:197
msgid "`A' or `D' expected inside parentheses."
msgstr ""
"each. (PSPP workspace is currently restricted to a maximum of %d KB.)"
msgstr ""
-#: src/sysfile-info.c:94
+#: src/sysfile-info.c:96
msgid "File:"
msgstr ""
-#: src/sysfile-info.c:96
+#: src/sysfile-info.c:98
msgid "Label:"
msgstr ""
-#: src/sysfile-info.c:100
+#: src/sysfile-info.c:102
msgid "No label."
msgstr ""
-#: src/sysfile-info.c:103
+#: src/sysfile-info.c:105
msgid "Created:"
msgstr ""
-#: src/sysfile-info.c:106
+#: src/sysfile-info.c:108
msgid "Endian:"
msgstr ""
-#: src/sysfile-info.c:107
+#: src/sysfile-info.c:109
msgid "Big."
msgstr ""
-#: src/sysfile-info.c:107
+#: src/sysfile-info.c:109
msgid "Little."
msgstr ""
-#: src/sysfile-info.c:108
+#: src/sysfile-info.c:110
msgid "Variables:"
msgstr ""
-#: src/sysfile-info.c:111
+#: src/sysfile-info.c:113
msgid "Cases:"
msgstr ""
-#: src/sysfile-info.c:114
+#: src/sysfile-info.c:116
msgid "Type:"
msgstr ""
-#: src/sysfile-info.c:115
+#: src/sysfile-info.c:117
msgid "System File."
msgstr ""
-#: src/sysfile-info.c:116
+#: src/sysfile-info.c:118
msgid "Weight:"
msgstr ""
-#: src/sysfile-info.c:120
+#: src/sysfile-info.c:122
msgid "Not weighted."
msgstr ""
-#: src/sysfile-info.c:122
+#: src/sysfile-info.c:124
msgid "Mode:"
msgstr ""
-#: src/sysfile-info.c:124
+#: src/sysfile-info.c:126
#, c-format
msgid "Compression %s."
msgstr ""
-#: src/sysfile-info.c:124
+#: src/sysfile-info.c:126
msgid "on"
msgstr ""
-#: src/sysfile-info.c:124
+#: src/sysfile-info.c:126
msgid "off"
msgstr ""
-#: src/sysfile-info.c:133 src/sysfile-info.c:370
+#: src/sysfile-info.c:135 src/sysfile-info.c:372
msgid "Description"
msgstr ""
-#: src/sysfile-info.c:134 src/sysfile-info.c:368
+#: src/sysfile-info.c:136 src/sysfile-info.c:370
msgid "Position"
msgstr ""
-#: src/sysfile-info.c:191
+#: src/sysfile-info.c:193
msgid "The active file does not have a file label."
msgstr ""
-#: src/sysfile-info.c:194
+#: src/sysfile-info.c:196
msgid "File label:"
msgstr ""
-#: src/sysfile-info.c:256
+#: src/sysfile-info.c:258
msgid "No variables to display."
msgstr ""
-#: src/sysfile-info.c:275
+#: src/sysfile-info.c:277
msgid "Macros not supported."
msgstr ""
-#: src/sysfile-info.c:285
+#: src/sysfile-info.c:287
msgid "The active file dictionary does not contain any documents."
msgstr ""
-#: src/sysfile-info.c:294
+#: src/sysfile-info.c:296
msgid "Documents in the active file:"
msgstr ""
-#: src/sysfile-info.c:372 src/sysfile-info.c:530 src/vfm.c:876
+#: src/sysfile-info.c:374 src/sysfile-info.c:532 src/vfm.c:877
msgid "Label"
msgstr ""
-#: src/sysfile-info.c:444
+#: src/sysfile-info.c:446
#, c-format
msgid "Format: %s"
msgstr ""
-#: src/sysfile-info.c:451
+#: src/sysfile-info.c:453
#, c-format
msgid "Print Format: %s"
msgstr ""
-#: src/sysfile-info.c:454
+#: src/sysfile-info.c:456
#, c-format
msgid "Write Format: %s"
msgstr ""
-#: src/sysfile-info.c:462
+#: src/sysfile-info.c:464
msgid "Missing Values: "
msgstr ""
-#: src/sysfile-info.c:529 src/vfm.c:875 src/crosstabs.q:1068
-#: src/crosstabs.q:1095 src/crosstabs.q:1115 src/crosstabs.q:1137
-#: src/examine.q:1125 src/frequencies.q:1056 src/frequencies.q:1174
+#: src/sysfile-info.c:531 src/vfm.c:876 src/crosstabs.q:1099
+#: src/crosstabs.q:1126 src/crosstabs.q:1146 src/crosstabs.q:1168
+#: src/examine.q:1179 src/frequencies.q:1083 src/frequencies.q:1204
msgid "Value"
msgstr ""
-#: src/sysfile-info.c:586
+#: src/sysfile-info.c:588
msgid "No vectors defined."
msgstr ""
-#: src/sysfile-info.c:601
+#: src/sysfile-info.c:603
msgid "Vector"
msgstr ""
"bad box: (%d+%d=%d,%d+%d=%d)-(%d+%d=%d,%d+%d=%d) in table size (%d,%d)\n"
msgstr ""
-#: src/temporary.c:45
+#: src/temporary.c:46
msgid "This command is not valid inside DO IF or LOOP."
msgstr ""
-#: src/temporary.c:52
+#: src/temporary.c:53
msgid ""
"This command may only appear once between procedures and procedure-like "
"commands."
msgstr ""
-#: src/title.c:55
+#: src/title.c:56
#, c-format
msgid "%s before: %s\n"
msgstr ""
-#: src/title.c:55
+#: src/title.c:56
msgid "<none>"
msgstr ""
-#: src/title.c:67
+#: src/title.c:68
#, c-format
msgid "%s: `.' expected after string."
msgstr ""
-#: src/title.c:83
+#: src/title.c:84
#, c-format
msgid "%s after: %s\n"
msgstr ""
-#: src/title.c:139
+#: src/title.c:140
#, c-format
msgid "Document entered %s %02d:%02d:%02d by %s (%s):"
msgstr ""
msgid "Truncating variable label to 255 characters."
msgstr ""
-#: src/vars-prs.c:48
+#: src/vars-prs.c:49
#, c-format
msgid "%s is not a variable name."
msgstr ""
-#: src/vars-prs.c:100
+#: src/vars-prs.c:101
msgid "ordinary"
msgstr ""
-#: src/vars-prs.c:102
+#: src/vars-prs.c:103
msgid "system"
msgstr ""
-#: src/vars-prs.c:104
+#: src/vars-prs.c:105
msgid "scratch"
msgstr ""
-#: src/vars-prs.c:209
+#: src/vars-prs.c:210
#, c-format
msgid "%s TO %s is not valid syntax since %s precedes %s in the dictionary."
msgstr ""
-#: src/vars-prs.c:219
+#: src/vars-prs.c:220
#, c-format
msgid ""
"When using the TO keyword to specify several variables, both variables must "
"system variables. %s is a %s variable, whereas %s is %s."
msgstr ""
-#: src/vars-prs.c:237
+#: src/vars-prs.c:238
#, c-format
msgid "Scratch variables (such as %s) are not allowed here."
msgstr ""
-#: src/vars-prs.c:260
+#: src/vars-prs.c:261
#, c-format
msgid ""
"%s is not a numeric variable. It will not be included in the variable list."
msgstr ""
-#: src/vars-prs.c:263
+#: src/vars-prs.c:264
#, c-format
msgid ""
"%s is not a string variable. It will not be included in the variable list."
msgstr ""
-#: src/vars-prs.c:267
+#: src/vars-prs.c:268
#, c-format
msgid ""
"%s and %s are not the same type. All variables in this variable list must "
"be of the same type. %s will be omitted from list."
msgstr ""
-#: src/vars-prs.c:272
+#: src/vars-prs.c:273
#, c-format
msgid "Variable %s appears twice in variable list."
msgstr ""
-#: src/vars-prs.c:352
+#: src/vars-prs.c:353
msgid "incorrect use of TO convention"
msgstr ""
-#: src/vars-prs.c:399
+#: src/vars-prs.c:400
msgid "Scratch variables not allowed here."
msgstr ""
-#: src/vars-prs.c:421
+#: src/vars-prs.c:422
msgid "Prefixes don't match in use of TO convention."
msgstr ""
-#: src/vars-prs.c:426
+#: src/vars-prs.c:427
msgid "Bad bounds in use of TO convention."
msgstr ""
-#: src/vector.c:66
+#: src/vector.c:67
#, c-format
msgid "Vector name %s is given twice."
msgstr ""
-#: src/vector.c:72
+#: src/vector.c:73
#, c-format
msgid "There is already a vector with name %s."
msgstr ""
-#: src/vector.c:93
+#: src/vector.c:94
msgid ""
"A slash must be used to separate each vector specification when using the "
"long form. Commands such as VECTOR A,B=Q1 TO Q20 are not supported."
msgstr ""
-#: src/vector.c:127
+#: src/vector.c:128
msgid "Vectors must have at least one element."
msgstr ""
-#: src/vector.c:141
+#: src/vector.c:142
#, c-format
msgid "%s%d is too long for a variable name."
msgstr ""
-#: src/vector.c:179
+#: src/vector.c:180
msgid ""
"The syntax for this command does not match the expected syntax for either "
"the long form or the short form of VECTOR."
msgstr ""
-#: src/weight.c:52
+#: src/weight.c:53
msgid "The weighting variable must be numeric."
msgstr ""
-#: src/weight.c:57
+#: src/weight.c:58
msgid "The weighting variable may not be scratch."
msgstr ""
-#: src/crosstabs.q:241
+#: src/crosstabs.q:261
msgid ""
"Missing mode REPORT not allowed in general mode. Assuming MISSING=TABLE."
msgstr ""
-#: src/crosstabs.q:251
+#: src/crosstabs.q:271
msgid "Write mode ALL not allowed in general mode. Assuming WRITE=CELLS."
msgstr ""
-#: src/crosstabs.q:312
+#: src/crosstabs.q:332
msgid "expecting BY"
msgstr ""
-#: src/crosstabs.q:379
+#: src/crosstabs.q:399
msgid "VARIABLES must be specified before TABLES."
msgstr ""
-#: src/crosstabs.q:416
+#: src/crosstabs.q:436
#, c-format
msgid "Maximum value (%ld) less than minimum value (%ld)."
msgstr ""
-#: src/crosstabs.q:769
+#: src/crosstabs.q:800
msgid "Summary."
msgstr ""
-#: src/crosstabs.q:771 src/examine.q:784
+#: src/crosstabs.q:802 src/examine.q:837
msgid "Cases"
msgstr ""
-#: src/crosstabs.q:772 src/examine.q:722 src/frequencies.q:1054
-#: src/frequencies.q:1421
+#: src/crosstabs.q:803 src/examine.q:775 src/frequencies.q:1081
+#: src/frequencies.q:1454
msgid "Valid"
msgstr ""
-#: src/crosstabs.q:773 src/examine.q:723 src/frequencies.q:1121
-#: src/frequencies.q:1422
+#: src/crosstabs.q:804 src/examine.q:776 src/frequencies.q:1149
+#: src/frequencies.q:1455
msgid "Missing"
msgstr ""
-#: src/crosstabs.q:774 src/crosstabs.q:977 src/crosstabs.q:1690
-#: src/examine.q:724 src/frequencies.q:1130 src/oneway.q:306 src/oneway.q:483
+#: src/crosstabs.q:805 src/crosstabs.q:1008 src/crosstabs.q:1722
+#: src/examine.q:777 src/frequencies.q:1158 src/oneway.q:307 src/oneway.q:486
msgid "Total"
msgstr ""
-#: src/crosstabs.q:784 src/examine.q:805 src/frequencies.q:1420
-#: src/oneway.q:393 src/t-test.q:680 src/t-test.q:703 src/t-test.q:828
+#: src/crosstabs.q:815 src/examine.q:858 src/frequencies.q:1453
+#: src/oneway.q:395 src/t-test.q:682 src/t-test.q:705 src/t-test.q:830
#: src/t-test.q:1365
msgid "N"
msgstr ""
-#: src/crosstabs.q:785 src/examine.q:807 src/frequencies.q:1058
-#: src/frequencies.q:1059 src/frequencies.q:1060
+#: src/crosstabs.q:816 src/examine.q:860 src/frequencies.q:1085
+#: src/frequencies.q:1086 src/frequencies.q:1087
msgid "Percent"
msgstr ""
-#: src/crosstabs.q:1027
+#: src/crosstabs.q:1058
msgid "count"
msgstr ""
-#: src/crosstabs.q:1028
+#: src/crosstabs.q:1059
msgid "row %"
msgstr ""
-#: src/crosstabs.q:1029
+#: src/crosstabs.q:1060
msgid "column %"
msgstr ""
-#: src/crosstabs.q:1030
+#: src/crosstabs.q:1061
msgid "total %"
msgstr ""
-#: src/crosstabs.q:1031
+#: src/crosstabs.q:1062
msgid "expected"
msgstr ""
-#: src/crosstabs.q:1032
+#: src/crosstabs.q:1063
msgid "residual"
msgstr ""
-#: src/crosstabs.q:1033
+#: src/crosstabs.q:1064
msgid "std. resid."
msgstr ""
-#: src/crosstabs.q:1034
+#: src/crosstabs.q:1065
msgid "adj. resid."
msgstr ""
-#: src/crosstabs.q:1067 src/crosstabs.q:1094 src/crosstabs.q:1114
-#: src/crosstabs.q:1135 src/examine.q:448
+#: src/crosstabs.q:1098 src/crosstabs.q:1125 src/crosstabs.q:1145
+#: src/crosstabs.q:1166 src/examine.q:495
msgid "Statistic"
msgstr ""
-#: src/crosstabs.q:1069 src/oneway.q:276 src/oneway.q:711 src/t-test.q:979
-#: src/t-test.q:1171 src/t-test.q:1263
+#: src/crosstabs.q:1100 src/oneway.q:278 src/oneway.q:707 src/t-test.q:980
+#: src/t-test.q:1172 src/t-test.q:1264
msgid "df"
msgstr ""
-#: src/crosstabs.q:1071
+#: src/crosstabs.q:1102
msgid "Asymp. Sig. (2-sided)"
msgstr ""
-#: src/crosstabs.q:1073
+#: src/crosstabs.q:1104
msgid "Exact. Sig. (2-sided)"
msgstr ""
-#: src/crosstabs.q:1075
+#: src/crosstabs.q:1106
msgid "Exact. Sig. (1-sided)"
msgstr ""
-#: src/crosstabs.q:1093 src/crosstabs.q:1134
+#: src/crosstabs.q:1124 src/crosstabs.q:1165
msgid "Category"
msgstr ""
-#: src/crosstabs.q:1096 src/crosstabs.q:1138
+#: src/crosstabs.q:1127 src/crosstabs.q:1169
msgid "Asymp. Std. Error"
msgstr ""
-#: src/crosstabs.q:1097 src/crosstabs.q:1139
+#: src/crosstabs.q:1128 src/crosstabs.q:1170
msgid "Approx. T"
msgstr ""
-#: src/crosstabs.q:1098 src/crosstabs.q:1140
+#: src/crosstabs.q:1129 src/crosstabs.q:1171
msgid "Approx. Sig."
msgstr ""
-#: src/crosstabs.q:1113
+#: src/crosstabs.q:1144
#, c-format
msgid " 95%% Confidence Interval"
msgstr ""
-#: src/crosstabs.q:1116 src/t-test.q:983 src/t-test.q:1168 src/t-test.q:1266
+#: src/crosstabs.q:1147 src/t-test.q:984 src/t-test.q:1169 src/t-test.q:1267
msgid "Lower"
msgstr ""
-#: src/crosstabs.q:1117 src/t-test.q:984 src/t-test.q:1169 src/t-test.q:1267
+#: src/crosstabs.q:1148 src/t-test.q:985 src/t-test.q:1170 src/t-test.q:1268
msgid "Upper"
msgstr ""
-#: src/crosstabs.q:1136
+#: src/crosstabs.q:1167
msgid "Type"
msgstr ""
-#: src/crosstabs.q:1884
+#: src/crosstabs.q:1916
msgid "Pearson Chi-Square"
msgstr ""
-#: src/crosstabs.q:1885
+#: src/crosstabs.q:1917
msgid "Likelihood Ratio"
msgstr ""
-#: src/crosstabs.q:1886
+#: src/crosstabs.q:1918
msgid "Fisher's Exact Test"
msgstr ""
-#: src/crosstabs.q:1887
+#: src/crosstabs.q:1919
msgid "Continuity Correction"
msgstr ""
-#: src/crosstabs.q:1888
+#: src/crosstabs.q:1920
msgid "Linear-by-Linear Association"
msgstr ""
-#: src/crosstabs.q:1925 src/crosstabs.q:1995 src/crosstabs.q:2054
+#: src/crosstabs.q:1957 src/crosstabs.q:2027 src/crosstabs.q:2086
msgid "N of Valid Cases"
msgstr ""
-#: src/crosstabs.q:1941 src/crosstabs.q:2070
+#: src/crosstabs.q:1973 src/crosstabs.q:2102
msgid "Nominal by Nominal"
msgstr ""
-#: src/crosstabs.q:1942 src/crosstabs.q:2071
+#: src/crosstabs.q:1974 src/crosstabs.q:2103
msgid "Ordinal by Ordinal"
msgstr ""
-#: src/crosstabs.q:1943
+#: src/crosstabs.q:1975
msgid "Interval by Interval"
msgstr ""
-#: src/crosstabs.q:1944
+#: src/crosstabs.q:1976
msgid "Measure of Agreement"
msgstr ""
-#: src/crosstabs.q:1949
+#: src/crosstabs.q:1981
msgid "Phi"
msgstr ""
-#: src/crosstabs.q:1950
+#: src/crosstabs.q:1982
msgid "Cramer's V"
msgstr ""
-#: src/crosstabs.q:1951
+#: src/crosstabs.q:1983
msgid "Contingency Coefficient"
msgstr ""
-#: src/crosstabs.q:1952
+#: src/crosstabs.q:1984
msgid "Kendall's tau-b"
msgstr ""
-#: src/crosstabs.q:1953
+#: src/crosstabs.q:1985
msgid "Kendall's tau-c"
msgstr ""
-#: src/crosstabs.q:1954
+#: src/crosstabs.q:1986
msgid "Gamma"
msgstr ""
-#: src/crosstabs.q:1955
+#: src/crosstabs.q:1987
msgid "Spearman Correlation"
msgstr ""
-#: src/crosstabs.q:1956
+#: src/crosstabs.q:1988
msgid "Pearson's R"
msgstr ""
-#: src/crosstabs.q:1957
+#: src/crosstabs.q:1989
msgid "Kappa"
msgstr ""
-#: src/crosstabs.q:2027
+#: src/crosstabs.q:2059
#, c-format
msgid "Odds Ratio for %s (%g / %g)"
msgstr ""
-#: src/crosstabs.q:2030
+#: src/crosstabs.q:2062
#, c-format
msgid "Odds Ratio for %s (%.*s / %.*s)"
msgstr ""
-#: src/crosstabs.q:2038
+#: src/crosstabs.q:2070
#, c-format
msgid "For cohort %s = %g"
msgstr ""
-#: src/crosstabs.q:2041
+#: src/crosstabs.q:2073
#, c-format
msgid "For cohort %s = %.*s"
msgstr ""
-#: src/crosstabs.q:2072
+#: src/crosstabs.q:2104
msgid "Nominal by Interval"
msgstr ""
-#: src/crosstabs.q:2077
+#: src/crosstabs.q:2109
msgid "Lambda"
msgstr ""
-#: src/crosstabs.q:2078
+#: src/crosstabs.q:2110
msgid "Goodman and Kruskal tau"
msgstr ""
-#: src/crosstabs.q:2079
+#: src/crosstabs.q:2111
msgid "Uncertainty Coefficient"
msgstr ""
-#: src/crosstabs.q:2080
+#: src/crosstabs.q:2112
msgid "Somers' d"
msgstr ""
-#: src/crosstabs.q:2081
+#: src/crosstabs.q:2113
msgid "Eta"
msgstr ""
-#: src/crosstabs.q:2086
+#: src/crosstabs.q:2118
msgid "Symmetric"
msgstr ""
-#: src/crosstabs.q:2087 src/crosstabs.q:2088
+#: src/crosstabs.q:2119 src/crosstabs.q:2120
#, c-format
msgid "%s Dependent"
msgstr ""
-#: src/examine.q:217 src/examine.q:229
+#: src/examine.q:264 src/examine.q:276
#, c-format
msgid "%s and %s are mutually exclusive"
msgstr ""
-#: src/examine.q:449 src/oneway.q:396 src/oneway.q:709
+#: src/examine.q:496 src/oneway.q:398 src/oneway.q:705
msgid "Std. Error"
msgstr ""
-#: src/examine.q:563 src/oneway.q:410
+#: src/examine.q:610 src/oneway.q:412
msgid "Descriptives"
msgstr ""
-#: src/examine.q:602 src/oneway.q:401
+#: src/examine.q:649 src/oneway.q:403
#, c-format
msgid "%g%% Confidence Interval for Mean"
msgstr ""
-#: src/examine.q:608 src/oneway.q:403
+#: src/examine.q:655 src/oneway.q:405
msgid "Lower Bound"
msgstr ""
-#: src/examine.q:619 src/oneway.q:404
+#: src/examine.q:666 src/oneway.q:406
msgid "Upper Bound"
msgstr ""
-#: src/examine.q:631
+#: src/examine.q:678
msgid "5% Trimmed Mean"
msgstr ""
-#: src/examine.q:636 src/frequencies.q:102
+#: src/examine.q:689 src/frequencies.q:112
msgid "Median"
msgstr ""
-#: src/examine.q:653 src/oneway.q:395 src/t-test.q:682 src/t-test.q:705
-#: src/t-test.q:829 src/t-test.q:1166
+#: src/examine.q:706 src/oneway.q:397 src/t-test.q:684 src/t-test.q:707
+#: src/t-test.q:831 src/t-test.q:1167
msgid "Std. Deviation"
msgstr ""
-#: src/examine.q:701
+#: src/examine.q:754
msgid "Interquartile Range"
msgstr ""
-#: src/examine.q:778
+#: src/examine.q:831
msgid "Case Processing Summary"
msgstr ""
-#: src/examine.q:1103
+#: src/examine.q:1157
msgid "Extreme Values"
msgstr ""
-#: src/examine.q:1126
+#: src/examine.q:1180
msgid "Case Number"
msgstr ""
-#: src/examine.q:1252
+#: src/examine.q:1306
msgid "Highest"
msgstr ""
-#: src/examine.q:1257
+#: src/examine.q:1311
msgid "Lowest"
msgstr ""
-#: src/file-handle.q:125
+#: src/examine.q:1350
+#, c-format
+msgid "Normal Q-Q Plot of %s"
+msgstr ""
+
+#: src/examine.q:1351 src/examine.q:1357
+msgid "Observed Value"
+msgstr ""
+
+#: src/examine.q:1352
+msgid "Expected Normal"
+msgstr ""
+
+#: src/examine.q:1355
+#, c-format
+msgid "Detrended Normal Q-Q Plot of %s"
+msgstr ""
+
+#: src/examine.q:1358
+msgid "Dev from Normal"
+msgstr ""
+
+#: src/file-handle.q:122
#, c-format
msgid ""
"File handle %s already refers to file %s. File handle cannot be redefined "
"within a session."
msgstr ""
-#: src/file-handle.q:147
+#: src/file-handle.q:144
msgid "The FILE HANDLE required subcommand NAME is not present."
msgstr ""
-#: src/file-handle.q:166
+#: src/file-handle.q:163
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:173
+#: src/file-handle.q:170
#, c-format
msgid ""
"Record length (%ld) must be at least one byte. 1-character records will be "
"assumed."
msgstr ""
-#: src/file-handle.q:247
-msgid "<Inline File>"
+#: src/file-handle.q:260
+#, c-format
+msgid "Can't open %s as a %s because it is already open as a %s"
+msgstr ""
+
+#: src/file-handle.q:264
+#, c-format
+msgid "Can't open %s as a %s for %s because it is already open for %s"
+msgstr ""
+
+#: src/file-handle.q:269
+#, c-format
+msgid "Can't re-open %s as a %s for %s"
msgstr ""
-#: src/file-handle.q:262
+#: src/file-handle.q:317
msgid "expecting a file name or handle name"
msgstr ""
-#: src/frequencies.q:101
+#: src/frequencies.q:111
msgid "S.E. Mean"
msgstr ""
-#: src/frequencies.q:103
+#: src/frequencies.q:113
msgid "Mode"
msgstr ""
-#: src/frequencies.q:107
+#: src/frequencies.q:117
msgid "S.E. Kurt"
msgstr ""
-#: src/frequencies.q:109
+#: src/frequencies.q:119
msgid "S.E. Skew"
msgstr ""
-#: src/frequencies.q:315
+#: src/frequencies.q:340
msgid ""
"At most one of BARCHART, HISTOGRAM, or HBAR should be given. HBAR will be "
"assumed. Argument values will be given precedence increasing along the "
"order given."
msgstr ""
-#: src/frequencies.q:398
+#: src/frequencies.q:423
#, c-format
msgid ""
"MAX must be greater than or equal to MIN, if both are specified. However, "
"MIN was specified as %g and MAX as %g. MIN and MAX will be ignored."
msgstr ""
-#: src/frequencies.q:722
+#: src/frequencies.q:747
msgid ""
"Upper limit of integer mode value range must be greater than lower limit."
msgstr ""
-#: src/frequencies.q:734
+#: src/frequencies.q:760
#, c-format
msgid "Variable %s specified multiple times on VARIABLES subcommand."
msgstr ""
-#: src/frequencies.q:747
+#: src/frequencies.q:766
#, c-format
msgid "Integer mode specified, but %s is not a numeric variable."
msgstr ""
-#: src/frequencies.q:809
+#: src/frequencies.q:832
msgid "`)' expected after GROUPED interval list."
msgstr ""
-#: src/frequencies.q:822
+#: src/frequencies.q:844
#, c-format
msgid "Variables %s specified on GROUPED but not on VARIABLES."
msgstr ""
-#: src/frequencies.q:825
+#: src/frequencies.q:851
#, c-format
msgid "Variables %s specified multiple times on GROUPED subcommand."
msgstr ""
-#: src/frequencies.q:1055 src/frequencies.q:1146 src/frequencies.q:1147
-#: src/frequencies.q:1177
+#: src/frequencies.q:1082 src/frequencies.q:1174 src/frequencies.q:1175
+#: src/frequencies.q:1207
msgid "Cum"
msgstr ""
-#: src/frequencies.q:1057
+#: src/frequencies.q:1084
msgid "Frequency"
msgstr ""
-#: src/frequencies.q:1076
+#: src/frequencies.q:1104
msgid "Value Label"
msgstr ""
-#: src/frequencies.q:1175
+#: src/frequencies.q:1205
msgid "Freq"
msgstr ""
-#: src/frequencies.q:1176 src/frequencies.q:1178
+#: src/frequencies.q:1206 src/frequencies.q:1208
msgid "Pct"
msgstr ""
-#: src/frequencies.q:1394
+#: src/frequencies.q:1427
#, c-format
msgid "No valid data for variable %s; statistics not displayed."
msgstr ""
-#: src/frequencies.q:1433
+#: src/frequencies.q:1465
msgid "Percentiles"
msgstr ""
-#: src/list.q:148
+#: src/list.q:150
#, c-format
msgid ""
"The first case (%ld) specified precedes the last case (%ld) specified. The "
"values will be swapped."
msgstr ""
-#: src/list.q:156
+#: src/list.q:158
#, c-format
msgid ""
"The first case (%ld) to list is less than 1. The value is being reset to 1."
msgstr ""
-#: src/list.q:162
+#: src/list.q:164
#, c-format
msgid ""
"The last case (%ld) to list is less than 1. The value is being reset to 1."
msgstr ""
-#: src/list.q:168
+#: src/list.q:170
#, c-format
msgid "The step value %ld is less than 1. The value is being reset to 1."
msgstr ""
-#: src/list.q:195
+#: src/list.q:197
msgid "`/FORMAT WEIGHT' specified, but weighting is not on."
msgstr ""
-#: src/list.q:436
+#: src/list.q:438
msgid "Line"
msgstr ""
-#: src/means.q:101
+#: src/means.q:100
msgid "Missing required subcommand TABLES."
msgstr ""
-#: src/means.q:135
-msgid "TABLES or CROSSBREAK subcommand may not appear more than once."
-msgstr ""
-
-#: src/means.q:172
-#, c-format
-msgid ""
-"Variable %s specified on TABLES or CROSSBREAK, but not specified on "
-"VARIABLES."
-msgstr ""
-
-#: src/means.q:186
-#, c-format
-msgid "LOWEST and HIGHEST may not be used for independent variables (%s)."
-msgstr ""
-
-#: src/means.q:194
-#, c-format
-msgid ""
-"Independent variables (%s) may not have noninteger endpoints in their ranges."
-msgstr ""
-
-#: src/means.q:227
-msgid "VARIABLES must precede TABLES."
-msgstr ""
-
-#: src/means.q:284
-#, c-format
-msgid "Upper value (%g) is less than lower value (%g) on VARIABLES subcommand."
+#: src/means.q:134
+msgid "TABLES subcommand may not appear more than once."
msgstr ""
-#: src/oneway.q:166
+#: src/oneway.q:168
msgid "Number of contrast coefficients must equal the number of groups"
msgstr ""
-#: src/oneway.q:175
+#: src/oneway.q:177
#, c-format
msgid "Coefficients for contrast %d do not total zero"
msgstr ""
-#: src/oneway.q:240 src/t-test.q:364 src/t-test.q:449
+#: src/oneway.q:242 src/t-test.q:366 src/t-test.q:451
#, c-format
msgid "`%s' is not a variable name"
msgstr ""
-#: src/oneway.q:275
+#: src/oneway.q:277
msgid "Sum of Squares"
msgstr ""
-#: src/oneway.q:277
+#: src/oneway.q:279
msgid "Mean Square"
msgstr ""
-#: src/oneway.q:278 src/t-test.q:976
+#: src/oneway.q:280 src/t-test.q:977
msgid "F"
msgstr ""
-#: src/oneway.q:279 src/oneway.q:549
+#: src/oneway.q:281 src/oneway.q:552
msgid "Significance"
msgstr ""
-#: src/oneway.q:304
+#: src/oneway.q:305
msgid "Between Groups"
msgstr ""
-#: src/oneway.q:305
+#: src/oneway.q:306
msgid "Within Groups"
msgstr ""
-#: src/oneway.q:351
+#: src/oneway.q:353
msgid "ANOVA"
msgstr ""
-#: src/oneway.q:546
+#: src/oneway.q:549
msgid "Levene Statistic"
msgstr ""
-#: src/oneway.q:547
+#: src/oneway.q:550
msgid "df1"
msgstr ""
-#: src/oneway.q:548
+#: src/oneway.q:551
msgid "df2"
msgstr ""
-#: src/oneway.q:552
+#: src/oneway.q:555
msgid "Test of Homogeneity of Variances"
msgstr ""
-#: src/oneway.q:628
+#: src/oneway.q:631
msgid "Contrast Coefficients"
msgstr ""
-#: src/oneway.q:630 src/oneway.q:707
+#: src/oneway.q:633 src/oneway.q:703
msgid "Contrast"
msgstr ""
-#: src/oneway.q:705
+#: src/oneway.q:701
msgid "Contrast Tests"
msgstr ""
-#: src/oneway.q:708
+#: src/oneway.q:704
msgid "Value of Contrast"
msgstr ""
-#: src/oneway.q:710 src/t-test.q:978 src/t-test.q:1170 src/t-test.q:1262
+#: src/oneway.q:706 src/t-test.q:979 src/t-test.q:1171 src/t-test.q:1263
msgid "t"
msgstr ""
-#: src/oneway.q:712 src/t-test.q:980 src/t-test.q:1172 src/t-test.q:1264
+#: src/oneway.q:708 src/t-test.q:981 src/t-test.q:1173 src/t-test.q:1265
msgid "Sig. (2-tailed)"
msgstr ""
-#: src/oneway.q:760
+#: src/oneway.q:754
msgid "Assume equal variances"
msgstr ""
-#: src/oneway.q:764
+#: src/oneway.q:758
msgid "Does not assume equal"
msgstr ""
msgid "data> "
msgstr ""
-#: src/t-test.q:266
+#: src/t-test.q:268
msgid "TESTVAL, GROUPS and PAIRS subcommands are mutually exclusive."
msgstr ""
-#: src/t-test.q:283
+#: src/t-test.q:285
msgid "VARIABLES subcommand is not appropriate with PAIRS"
msgstr ""
-#: src/t-test.q:320
+#: src/t-test.q:322
msgid "One or more VARIABLES must be specified."
msgstr ""
-#: src/t-test.q:377
+#: src/t-test.q:379
#, c-format
msgid "Long string variable %s is not valid here."
msgstr ""
-#: src/t-test.q:397
+#: src/t-test.q:399
msgid ""
"When applying GROUPS to a string variable, at least one value must be "
"specified."
msgstr ""
-#: src/t-test.q:484
+#: src/t-test.q:486
#, c-format
msgid ""
"PAIRED was specified but the number of variables preceding WITH (%d) did not "
"match the number following (%d)."
msgstr ""
-#: src/t-test.q:501
+#: src/t-test.q:503
msgid "At least two variables must be specified on PAIRS."
msgstr ""
-#: src/t-test.q:678
+#: src/t-test.q:680
msgid "One-Sample Statistics"
msgstr ""
-#: src/t-test.q:683 src/t-test.q:706 src/t-test.q:830
+#: src/t-test.q:685 src/t-test.q:708 src/t-test.q:832
msgid "SE. Mean"
msgstr ""
-#: src/t-test.q:700
+#: src/t-test.q:702
msgid "Group Statistics"
msgstr ""
-#: src/t-test.q:824
+#: src/t-test.q:826
msgid "Paired Sample Statistics"
msgstr ""
-#: src/t-test.q:846 src/t-test.q:1191 src/t-test.q:1382
+#: src/t-test.q:848 src/t-test.q:1192 src/t-test.q:1382
#, c-format
msgid "Pair %d"
msgstr ""
-#: src/t-test.q:964
+#: src/t-test.q:965
msgid "Independent Samples Test"
msgstr ""
-#: src/t-test.q:972
+#: src/t-test.q:973
msgid "Levene's Test for Equality of Variances"
msgstr ""
-#: src/t-test.q:974
+#: src/t-test.q:975
msgid "t-test for Equality of Means"
msgstr ""
-#: src/t-test.q:977 src/t-test.q:1367
+#: src/t-test.q:978 src/t-test.q:1367
msgid "Sig."
msgstr ""
-#: src/t-test.q:981 src/t-test.q:1265
+#: src/t-test.q:982 src/t-test.q:1266
msgid "Mean Difference"
msgstr ""
-#: src/t-test.q:982
+#: src/t-test.q:983
msgid "Std. Error Difference"
msgstr ""
-#: src/t-test.q:987 src/t-test.q:1162 src/t-test.q:1257
+#: src/t-test.q:988 src/t-test.q:1163 src/t-test.q:1258
#, c-format
msgid "%g%% Confidence Interval of the Difference"
msgstr ""
-#: src/t-test.q:1041
+#: src/t-test.q:1043
msgid "Equal variances assumed"
msgstr ""
-#: src/t-test.q:1094
+#: src/t-test.q:1095
msgid "Equal variances not assumed"
msgstr ""
-#: src/t-test.q:1152
+#: src/t-test.q:1153
msgid "Paired Samples Test"
msgstr ""
-#: src/t-test.q:1155
+#: src/t-test.q:1156
msgid "Paired Differences"
msgstr ""
-#: src/t-test.q:1167
+#: src/t-test.q:1168
msgid "Std. Error Mean"
msgstr ""
-#: src/t-test.q:1246
+#: src/t-test.q:1247
msgid "One-Sample Test"
msgstr ""
-#: src/t-test.q:1251
+#: src/t-test.q:1252
#, c-format
msgid "Test Value = %f"
msgstr ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: pspp-dev@gnu.org\n"
-"POT-Creation-Date: 2004-11-09 08:18+0800\n"
+"POT-Creation-Date: 2004-11-15 00:28-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"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
-#: src/aggregate.c:188 src/aggregate.c:223 src/data-list.c:1437
-#: src/data-list.c:1472 src/data-list.c:1485 src/data-list.c:1498
-#: src/data-list.c:1531
+#: src/aggregate.c:187 src/aggregate.c:220 src/data-list.c:1421
+#: src/data-list.c:1456 src/data-list.c:1469 src/data-list.c:1482
+#: src/data-list.c:1515
#, c-format
msgid "%s subcommand given multiple times."
msgstr ""
-#: src/aggregate.c:208
+#: src/aggregate.c:205
msgid "while expecting COLUMNWISE"
msgstr ""
-#: src/aggregate.c:246
+#: src/aggregate.c:243
msgid "BREAK subcommand not specified."
msgstr ""
-#: src/aggregate.c:416
+#: src/aggregate.c:397
msgid "expecting aggregation function"
msgstr ""
-#: src/aggregate.c:432
+#: src/aggregate.c:413
#, c-format
msgid "Unknown aggregation function %s."
msgstr ""
-#: src/aggregate.c:447
+#: src/aggregate.c:428
msgid "expecting `('"
msgstr ""
-#: src/aggregate.c:482
+#: src/aggregate.c:463
#, c-format
msgid "Missing argument %d to %s."
msgstr ""
-#: src/aggregate.c:490
+#: src/aggregate.c:471
#, c-format
msgid "Arguments to %s must be of same type as source variables."
msgstr ""
-#: src/aggregate.c:500 src/expr-prs.c:626
+#: src/aggregate.c:481 src/expr-prs.c:627
msgid "expecting `)'"
msgstr ""
-#: src/aggregate.c:512
+#: src/aggregate.c:493
#, c-format
msgid ""
"Number of source variables (%d) does not match number of target variables (%"
"d)."
msgstr ""
-#: src/aggregate.c:581
+#: src/aggregate.c:562
#, c-format
msgid ""
"Variable name %s is not unique within the aggregate file dictionary, which "
"contains the aggregate variables and the break variables."
msgstr ""
-#: src/apply-dict.c:65
+#: src/apply-dict.c:68
#, c-format
msgid "Variable %s is %s in target file, but %s in source file."
msgstr ""
-#: src/apply-dict.c:68 src/apply-dict.c:69 src/expr-prs.c:1288
-#: src/expr-prs.c:1304 src/formats.c:96 src/pfm-read.c:636 src/print.c:689
-#: src/sfm-read.c:927 src/sfm-read.c:1057 src/sfm-read.c:1058
+#: src/apply-dict.c:71 src/apply-dict.c:72 src/expr-prs.c:1289
+#: src/expr-prs.c:1305 src/formats.c:96 src/pfm-read.c:604 src/print.c:695
+#: src/sfm-read.c:888 src/sfm-read.c:1017 src/sfm-read.c:1018
msgid "string"
msgstr ""
-#: src/apply-dict.c:68 src/apply-dict.c:69 src/expr-prs.c:1285
-#: src/expr-prs.c:1302 src/formats.c:96 src/pfm-read.c:636 src/print.c:689
-#: src/sfm-read.c:927 src/sfm-read.c:1057 src/sfm-read.c:1058
+#: src/apply-dict.c:71 src/apply-dict.c:72 src/expr-prs.c:1286
+#: src/expr-prs.c:1303 src/formats.c:96 src/pfm-read.c:604 src/print.c:695
+#: src/sfm-read.c:888 src/sfm-read.c:1017 src/sfm-read.c:1018
msgid "numeric"
msgstr ""
-#: src/apply-dict.c:81
+#: src/apply-dict.c:84
#, c-format
msgid "Cannot add value labels from source file to long string variable %s."
msgstr ""
-#: src/apply-dict.c:127
+#: src/apply-dict.c:130
#, c-format
msgid ""
"Cannot apply missing values from source file to long string variable %s."
msgstr ""
-#: src/apply-dict.c:160
+#: src/apply-dict.c:163
msgid "No matching variables found between the source and target files."
msgstr ""
msgid "%s - Page %d"
msgstr ""
-#: src/autorecode.c:121
+#: src/autorecode.c:122
#, c-format
msgid "Source variable count (%d) does not match target variable count (%d)."
msgstr ""
-#: src/autorecode.c:138 src/command.c:738 src/compute.c:293
-#: src/data-list.c:406 src/data-list.c:903 src/data-list.c:1764
-#: src/do-if.c:253 src/get.c:351 src/lexer.c:412 src/loop.c:240
-#: src/matrix-data.c:504 src/print.c:329 src/print.c:1039 src/recode.c:404
-#: src/sel-if.c:53 src/sel-if.c:130 src/vector.c:192 src/file-handle.q:141
+#: src/autorecode.c:139 src/command.c:739 src/compute.c:294
+#: src/data-list.c:407 src/data-list.c:897 src/data-list.c:1748
+#: src/do-if.c:253 src/get.c:405 src/lexer.c:412 src/loop.c:241
+#: src/matrix-data.c:527 src/print.c:335 src/print.c:1045 src/recode.c:405
+#: src/sel-if.c:54 src/sel-if.c:131 src/vector.c:193 src/file-handle.q:138
msgid "expecting end of command"
msgstr ""
-#: src/autorecode.c:148
+#: src/autorecode.c:149
#, c-format
msgid "Target variable %s duplicates existing variable %s."
msgstr ""
-#: src/autorecode.c:155
+#: src/autorecode.c:156
#, c-format
msgid "Duplicate variable name %s among target variables."
msgstr ""
-#: src/casefile.c:184
+#: src/casefile.c:182
#, c-format
msgid "%s: Removing temporary file: %s."
msgstr ""
-#: src/casefile.c:329
+#: src/casefile.c:328
#, c-format
msgid "Error writing temporary file: %s."
msgstr ""
-#: src/casefile.c:356
+#: src/casefile.c:355
#, c-format
msgid "%s: Creating temporary file: %s."
msgstr ""
-#: src/casefile.c:500
+#: src/casefile.c:498
#, c-format
msgid "%s: Opening temporary file: %s."
msgstr ""
-#: src/casefile.c:526
+#: src/casefile.c:524
#, c-format
msgid "%s: Seeking temporary file: %s."
msgstr ""
-#: src/casefile.c:541
+#: src/casefile.c:540
#, c-format
msgid "%s: Reading temporary file: %s."
msgstr ""
-#: src/casefile.c:544
+#: src/casefile.c:543
#, c-format
msgid "%s: Temporary file ended unexpectedly."
msgstr ""
-#: src/cmdline.c:141 src/cmdline.c:160 src/cmdline.c:172 src/command.c:160
+#: src/cmdline.c:141 src/cmdline.c:160 src/cmdline.c:172 src/command.c:161
#: src/set.q:414 src/set.q:416 src/set.q:956
#, c-format
msgid "%s is not yet implemented."
"Report bugs to <%s>.\n"
msgstr ""
-#: src/command.c:98
+#: src/command.c:99
#, c-format
msgid "%s not allowed inside FILE TYPE/END FILE TYPE."
msgstr ""
-#: src/command.c:102
+#: src/command.c:103
#, c-format
msgid "%s not allowed inside FILE TYPE GROUPED/END FILE TYPE."
msgstr ""
-#: src/command.c:105
+#: src/command.c:106
msgid "RECORD TYPE must be the first command inside a FILE TYPE structure."
msgstr ""
-#: src/command.c:150
+#: src/command.c:151
msgid "expecting command name"
msgstr ""
-#: src/command.c:179
+#: src/command.c:180
#, c-format
msgid ""
"%s is not allowed (1) before a command to specify the input program, such as "
"PROGRAM and END INPUT PROGRAM."
msgstr ""
-#: src/command.c:183
+#: src/command.c:184
#, c-format
msgid "%s is not allowed within an input program."
msgstr ""
-#: src/command.c:184 src/command.c:185
+#: src/command.c:185 src/command.c:186
#, c-format
msgid "%s is only allowed within an input program."
msgstr ""
-#: src/command.c:464
+#: src/command.c:465
#, c-format
msgid "Unknown command %s."
msgstr ""
-#: src/command.c:564
+#: src/command.c:565
msgid ""
"This command is not accepted in a syntax file. Instead, use FINISH to "
"terminate a syntax file."
msgstr ""
-#: src/command.c:582
+#: src/command.c:583
msgid ""
"This command is not executed in interactive mode. Instead, PSPP drops down "
"to the command prompt. Use EXIT if you really want to quit."
msgstr ""
-#: src/command.c:625 src/command.c:756
+#: src/command.c:626 src/command.c:757
msgid "This command not allowed when the SAFER option is set."
msgstr ""
-#: src/command.c:637
+#: src/command.c:638
#, c-format
msgid "Error removing `%s': %s."
msgstr ""
-#: src/command.c:687
+#: src/command.c:688
#, c-format
msgid "Couldn't fork: %s."
msgstr ""
-#: src/command.c:729
+#: src/command.c:730
#, c-format
msgid "Error executing command: %s."
msgstr ""
-#: src/command.c:777
+#: src/command.c:778
msgid "No operating system support for this command."
msgstr ""
-#: src/command.c:800
+#: src/command.c:801
msgid "This command is not valid in a syntax file."
msgstr ""
-#: src/compute.c:145 src/compute.c:209
+#: src/compute.c:146 src/compute.c:210
#, c-format
msgid ""
"When executing COMPUTE: SYSMIS is not a valid value as an index into vector %"
"s."
msgstr ""
-#: src/compute.c:148 src/compute.c:213
+#: src/compute.c:149 src/compute.c:214
#, c-format
msgid ""
"When executing COMPUTE: %g is not a valid value as an index into vector %s."
msgstr ""
-#: src/compute.c:355
+#: src/compute.c:356
#, c-format
msgid "There is no vector named %s."
msgstr ""
-#: src/count.c:155
+#: src/count.c:156
msgid "Destination cannot be a string variable."
msgstr ""
-#: src/count.c:262
+#: src/count.c:263
#, c-format
msgid ""
"%g THRU %g is not a valid range. The number following THRU must be at least "
msgid "Only one of FIXED, FREE, or LIST may be specified."
msgstr ""
-#: src/data-list.c:353 src/print.c:290
+#: src/data-list.c:354 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:382 src/data-list.c:1753
+#: src/data-list.c:383 src/data-list.c:1737
msgid ""
"SPSS-like or FORTRAN-like format specification expected after variable names."
msgstr ""
-#: src/data-list.c:393
+#: src/data-list.c:394
msgid "At least one variable must be specified."
msgstr ""
-#: src/data-list.c:398 src/print.c:322
+#: src/data-list.c:399 src/print.c:328
msgid ""
"Variables are specified on records that should not exist according to "
"RECORDS subcommand."
msgstr ""
-#: src/data-list.c:436 src/data-list.c:450 src/print.c:499 src/print.c:512
+#: src/data-list.c:437 src/data-list.c:451 src/print.c:505 src/print.c:518
msgid "Column positions for fields must be positive."
msgstr ""
-#: src/data-list.c:455
+#: src/data-list.c:456
msgid "The ending column for a field must be greater than the starting column."
msgstr ""
-#: src/data-list.c:469 src/print.c:589
+#: src/data-list.c:470 src/print.c:595
#, c-format
msgid "The %d columns %d-%d can't be evenly divided into %d fields."
msgstr ""
-#: src/data-list.c:489 src/print.c:540
+#: src/data-list.c:490 src/print.c:546
msgid "A format specifier on this line has extra characters on the end."
msgstr ""
-#: src/data-list.c:504 src/print.c:556
+#: src/data-list.c:505 src/print.c:562
msgid "The value for number of decimal places must be at least 1."
msgstr ""
-#: src/data-list.c:518 src/print.c:569
+#: src/data-list.c:519 src/print.c:575
#, c-format
msgid "Input format %s doesn't accept decimal places."
msgstr ""
-#: src/data-list.c:565 src/data-list.c:661 src/data-list.c:882
+#: src/data-list.c:566 src/data-list.c:662 src/data-list.c:876
#, c-format
msgid "%s is a duplicate variable name."
msgstr ""
-#: src/data-list.c:570
+#: src/data-list.c:571
#, c-format
msgid "There is already a variable %s of a different type."
msgstr ""
-#: src/data-list.c:577
+#: src/data-list.c:578
#, c-format
msgid "There is already a string variable %s of a different width."
msgstr ""
-#: src/data-list.c:652
+#: src/data-list.c:653
msgid ""
"The number of format specifications exceeds the given number of variable "
"names."
msgstr ""
-#: src/data-list.c:765 src/print.c:762
+#: src/data-list.c:766 src/print.c:768
msgid ""
"There aren't enough format specifications to match the number of variable "
"names given."
msgstr ""
-#: src/data-list.c:794 src/data-list.c:924 src/descript.c:879 src/print.c:793
-#: src/sysfile-info.c:132 src/sysfile-info.c:365 src/vfm.c:874
+#: src/data-list.c:793 src/data-list.c:919 src/descript.c:880 src/print.c:799
+#: src/sysfile-info.c:134 src/sysfile-info.c:367 src/vfm.c:875
msgid "Variable"
msgstr ""
-#: src/data-list.c:795 src/print.c:794
+#: src/data-list.c:794 src/print.c:800
msgid "Record"
msgstr ""
-#: src/data-list.c:796 src/print.c:795
+#: src/data-list.c:795 src/print.c:801
msgid "Columns"
msgstr ""
-#: src/data-list.c:797 src/data-list.c:925 src/print.c:796
+#: src/data-list.c:796 src/data-list.c:920 src/print.c:802
msgid "Format"
msgstr ""
-#: src/data-list.c:817
+#: src/data-list.c:812
#, c-format
msgid "Reading %d record from file %s."
msgid_plural "Reading %d records from file %s."
msgstr[0] ""
msgstr[1] ""
-#: src/data-list.c:819
+#: src/data-list.c:816
#, 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:948
+#: src/data-list.c:936
#, c-format
msgid "Reading free-form data from file %s."
msgstr ""
-#: src/data-list.c:949
+#: src/data-list.c:939
msgid "Reading free-form data from the command file."
msgstr ""
-#: src/data-list.c:1002
+#: src/data-list.c:990
#, c-format
msgid "Quoted string missing terminating `%c'."
msgstr ""
-#: src/data-list.c:1111
+#: src/data-list.c:1099
#, c-format
msgid "Partial case of %d of %d records discarded."
msgstr ""
-#: src/data-list.c:1165
+#: src/data-list.c:1153
#, c-format
msgid "Partial case discarded. The first variable missing was %s."
msgstr ""
-#: src/data-list.c:1209
+#: src/data-list.c:1197
#, 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:1287
+#: src/data-list.c:1275
msgid "Attempt to read past end of file."
msgstr ""
-#: src/data-list.c:1427
+#: src/data-list.c:1411
msgid ""
"REPEATING DATA must use the same file as its corresponding DATA LIST or FILE "
"TYPE."
msgstr ""
-#: src/data-list.c:1461
+#: src/data-list.c:1445
#, c-format
msgid "STARTS beginning column (%d) exceeds STARTS ending column (%d)."
msgstr ""
-#: src/data-list.c:1517
+#: src/data-list.c:1501
#, c-format
msgid "CONTINUED beginning column (%d) exceeds CONTINUED ending column (%d)."
msgstr ""
-#: src/data-list.c:1540
+#: src/data-list.c:1524
#, c-format
msgid "ID beginning column (%ld) must be positive."
msgstr ""
-#: src/data-list.c:1555
+#: src/data-list.c:1539
#, c-format
msgid "ID ending column (%ld) must be positive."
msgstr ""
-#: src/data-list.c:1561
+#: src/data-list.c:1545
#, c-format
msgid "ID ending column (%ld) cannot be less than ID beginning column (%d)."
msgstr ""
-#: src/data-list.c:1601
+#: src/data-list.c:1585
msgid "Missing required specification STARTS."
msgstr ""
-#: src/data-list.c:1603
+#: src/data-list.c:1587
msgid "Missing required specification OCCURS."
msgstr ""
-#: src/data-list.c:1610
+#: src/data-list.c:1594
msgid "ID specified without CONTINUED."
msgstr ""
-#: src/data-list.c:1702
+#: src/data-list.c:1686
msgid "String variable not allowed here."
msgstr ""
-#: src/data-list.c:1712
+#: src/data-list.c:1696
#, c-format
msgid "%s (%d) must be at least 1."
msgstr ""
-#: src/data-list.c:1718
+#: src/data-list.c:1702
#, c-format
msgid "Variable or integer expected for %s."
msgstr ""
-#: src/data-list.c:1856
+#: src/data-list.c:1840
#, c-format
msgid "Encountered mismatched record ID \"%s\" expecting \"%s\"."
msgstr ""
-#: src/data-list.c:1888
+#: src/data-list.c:1872
#, c-format
msgid ""
"Variable %s starting in column %d extends beyond physical record length of %"
"d."
msgstr ""
-#: src/data-list.c:1956
+#: src/data-list.c:1940
#, c-format
msgid "Invalid value %d for OCCURS."
msgstr ""
-#: src/data-list.c:1962
+#: src/data-list.c:1946
#, c-format
msgid "Beginning column for STARTS (%d) must be at least 1."
msgstr ""
-#: src/data-list.c:1970
+#: src/data-list.c:1954
#, c-format
msgid "Ending column for STARTS (%d) is less than beginning column (%d)."
msgstr ""
-#: src/data-list.c:1978
+#: src/data-list.c:1962
#, c-format
msgid "Invalid value %d for LENGTH."
msgstr ""
-#: src/data-list.c:1985
+#: src/data-list.c:1969
#, c-format
msgid "Beginning column for CONTINUED (%d) must be at least 1."
msgstr ""
-#: src/data-list.c:1993
+#: src/data-list.c:1977
#, c-format
msgid "Ending column for CONTINUED (%d) is less than beginning column (%d)."
msgstr ""
-#: src/data-list.c:2025
+#: src/data-list.c:2009
#, 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:2043
+#: src/data-list.c:2027
#, c-format
msgid "Unexpected end of file with %d repetitions remaining out of %d."
msgstr ""
-#: src/data-out.c:235 src/sfm-read.c:466 src/sysfile-info.c:113
+#: src/data-out.c:235 src/sfm-read.c:432 src/sysfile-info.c:115
msgid "Unknown"
msgstr ""
msgid "Only USE ALL is currently implemented."
msgstr ""
-#: src/descript.c:98 src/examine.q:584 src/frequencies.q:100 src/oneway.q:394
-#: src/t-test.q:681 src/t-test.q:704 src/t-test.q:827 src/t-test.q:1165
+#: src/descript.c:99 src/examine.q:631 src/frequencies.q:110 src/oneway.q:396
+#: src/t-test.q:683 src/t-test.q:706 src/t-test.q:829 src/t-test.q:1166
msgid "Mean"
msgstr ""
-#: src/descript.c:99
+#: src/descript.c:100
msgid "S E Mean"
msgstr ""
-#: src/descript.c:100 src/frequencies.q:104
+#: src/descript.c:101 src/frequencies.q:114
msgid "Std Dev"
msgstr ""
-#: src/descript.c:101 src/examine.q:641 src/frequencies.q:105
+#: src/descript.c:102 src/examine.q:694 src/frequencies.q:115
msgid "Variance"
msgstr ""
-#: src/descript.c:102 src/examine.q:711 src/frequencies.q:106
+#: src/descript.c:103 src/examine.q:764 src/frequencies.q:116
msgid "Kurtosis"
msgstr ""
-#: src/descript.c:103
+#: src/descript.c:104
msgid "S E Kurt"
msgstr ""
-#: src/descript.c:104 src/examine.q:706 src/frequencies.q:108
+#: src/descript.c:105 src/examine.q:759 src/frequencies.q:118
msgid "Skewness"
msgstr ""
-#: src/descript.c:105
+#: src/descript.c:106
msgid "S E Skew"
msgstr ""
-#: src/descript.c:106 src/examine.q:689 src/frequencies.q:110
+#: src/descript.c:107 src/examine.q:742 src/frequencies.q:120
msgid "Range"
msgstr ""
-#: src/descript.c:107 src/examine.q:666 src/frequencies.q:111 src/oneway.q:406
+#: src/descript.c:108 src/examine.q:719 src/frequencies.q:121 src/oneway.q:408
msgid "Minimum"
msgstr ""
-#: src/descript.c:108 src/examine.q:677 src/frequencies.q:112 src/oneway.q:407
+#: src/descript.c:109 src/examine.q:730 src/frequencies.q:122 src/oneway.q:409
msgid "Maximum"
msgstr ""
-#: src/descript.c:109 src/frequencies.q:113
+#: src/descript.c:110 src/frequencies.q:123
msgid "Sum"
msgstr ""
-#: src/descript.c:332
+#: src/descript.c:333
#, c-format
msgid "Z-score variable name %s would be a duplicate variable name."
msgstr ""
-#: src/descript.c:350 src/list.q:140
+#: src/descript.c:351 src/list.q:142
msgid "No variables specified."
msgstr ""
-#: src/descript.c:434
+#: src/descript.c:435
msgid "expecting statistic name: reverting to default"
msgstr ""
-#: src/descript.c:507
+#: src/descript.c:508
msgid ""
"Ran out of generic names for Z-score variables. There are only 126 generic "
"names: ZSC001-ZSC0999, STDZ01-STDZ09, ZZZZ01-ZZZZ09, ZQZQ01-ZQZQ09."
msgstr ""
-#: src/descript.c:538
+#: src/descript.c:539
msgid "Mapping of variables to corresponding Z-scores."
msgstr ""
-#: src/descript.c:543
+#: src/descript.c:544
msgid "Source"
msgstr ""
-#: src/descript.c:544
+#: src/descript.c:545
msgid "Target"
msgstr ""
-#: src/descript.c:663 src/descript.c:669
+#: src/descript.c:664 src/descript.c:670
msgid "Z-score of "
msgstr ""
-#: src/descript.c:882
+#: src/descript.c:883
msgid "Valid N"
msgstr ""
-#: src/descript.c:883
+#: src/descript.c:884
msgid "Missing N"
msgstr ""
-#: src/descript.c:909
+#: src/descript.c:910
#, c-format
msgid "Valid cases = %g; cases with missing value(s) = %g."
msgstr ""
msgid "Cannot open first page on DEVIND device %s."
msgstr ""
-#: src/dfm.c:88 src/dfm.c:565
-#, c-format
-msgid "%s: Closing data-file handle %s."
-msgstr ""
-
-#: src/dfm.c:115
-#, c-format
-msgid "Cannot read from file %s already opened for %s."
-msgstr ""
-
-#: src/dfm.c:129
-#, c-format
-msgid "%s: Opening data-file handle %s for reading."
-msgstr ""
-
-#: src/dfm.c:144
+#: src/dfm-read.c:153
#, c-format
msgid "Could not open \"%s\" for reading as a data file: %s."
msgstr ""
-#: src/dfm.c:186 src/dfm.c:204
+#: src/dfm-read.c:186 src/dfm-read.c:204
msgid "BEGIN DATA expected."
msgstr ""
-#: src/dfm.c:213
+#: src/dfm-read.c:213
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.c:241 src/dfm.c:261
+#: src/dfm-read.c:246 src/dfm-read.c:266
#, c-format
msgid "Error reading file %s: %s."
msgstr ""
-#: src/dfm.c:264
+#: src/dfm-read.c:269
#, c-format
msgid "%s: Partial record at end of file."
msgstr ""
-#: src/dfm.c:300
+#: src/dfm-read.c:312
#, c-format
msgid "Attempt to read beyond end-of-file on file %s."
msgstr ""
-#: src/dfm.c:446
-msgid "reading as a data file"
-msgstr ""
-
-#: src/dfm.c:472
-#, c-format
-msgid "Cannot write to file %s already opened for %s."
-msgstr ""
-
-#: src/dfm.c:485
-#, c-format
-msgid "%s: Opening data-file handle %s for writing."
+#: src/dfm-read.c:315
+msgid "Attempt to read beyond END DATA."
msgstr ""
-#: src/dfm.c:491
-msgid "Cannot open the inline file for writing."
+#: src/dfm-read.c:462
+msgid ""
+"This command is not valid here since the current input program does not "
+"access the inline file."
msgstr ""
-#: src/dfm.c:505
+#: src/dfm-write.c:67
#, c-format
msgid "An error occurred while opening \"%s\" for writing as a data file: %s."
msgstr ""
-#: src/dfm.c:547
+#: src/dfm-write.c:103
#, c-format
msgid "Error writing file %s: %s."
msgstr ""
-#: src/dfm.c:581
-msgid "writing as a data file"
-msgstr ""
-
-#: src/dfm.c:598
-msgid ""
-"This command is not valid here since the current input program does not "
-"access the inline file."
-msgstr ""
-
-#: src/dfm.c:605
-msgid "inline file: Opening for reading."
-msgstr ""
-
-#: src/dfm.c:618
-msgid "Skipping remaining inline data."
-msgstr ""
-
-#: src/dictionary.c:583
+#: src/dictionary.c:603
msgid ""
"At least one case in the data file had a weight value that was user-missing, "
"system-missing, zero, or negative. These case(s) were ignored."
msgid "fatal"
msgstr ""
-#: src/error.c:259 src/error.c:266 src/error.c:269 src/expr-prs.c:1279
+#: src/error.c:259 src/error.c:266 src/error.c:269 src/expr-prs.c:1280
msgid "error"
msgstr ""
msgid "installation error"
msgstr ""
-#: src/expr-evl.c:633
+#: src/expr-evl.c:634
msgid "TIME.HMS cannot mix positive and negative in its arguments."
msgstr ""
-#: src/expr-evl.c:697
+#: src/expr-evl.c:698
msgid "Week argument to WKYR must be in range 0 to 53."
msgstr ""
-#: src/expr-evl.c:848 src/expr-evl.c:904
+#: src/expr-evl.c:849 src/expr-evl.c:905
msgid "Argument 3 of RINDEX may not be system-missing."
msgstr ""
-#: src/expr-evl.c:858 src/expr-evl.c:914
+#: src/expr-evl.c:859 src/expr-evl.c:915
msgid ""
"Argument 3 of RINDEX must be between 1 and the length of argument 2, and it "
"must evenly divide the length of argument 2."
msgstr ""
-#: src/expr-evl.c:1100
+#: src/expr-evl.c:1101
msgid ""
"A number being treated as a Boolean in an expression was found to have a "
"value other than 0 (false), 1 (true), or the system-missing value. The "
"result was forced to 0."
msgstr ""
-#: src/expr-evl.c:1141
+#: src/expr-evl.c:1142
#, c-format
msgid ""
"SYSMIS is not a valid index value for vector %s. The result will be set to "
"SYSMIS."
msgstr ""
-#: src/expr-evl.c:1145
+#: src/expr-evl.c:1146
#, c-format
msgid ""
"%g is not a valid index value for vector %s. The result will be set to "
"SYSMIS."
msgstr ""
-#: src/expr-evl.c:1164
+#: src/expr-evl.c:1165
#, c-format
msgid ""
"SYSMIS is not a valid index value for vector %s. The result will be set to "
"the empty string."
msgstr ""
-#: src/expr-evl.c:1169
+#: src/expr-evl.c:1170
#, c-format
msgid ""
"%g is not a valid index value for vector %s. The result will be set to the "
"Boolean value was found to have a constant value other than 0, 1, or SYSMIS."
msgstr ""
-#: src/expr-prs.c:137
+#: src/expr-prs.c:138
msgid ""
"Type mismatch: expression has string type, but a numeric value is required "
"here."
msgstr ""
-#: src/expr-prs.c:148
+#: src/expr-prs.c:149
msgid ""
"Type mismatch: expression has numeric type, but a string value is required "
"here."
msgstr ""
-#: src/expr-prs.c:207
+#: src/expr-prs.c:208
#, c-format
msgid "Type mismatch: operands of %s operator must be strings."
msgstr ""
-#: src/expr-prs.c:210
+#: src/expr-prs.c:211
#, c-format
msgid "Type mismatch: operands of %s operator must be numeric."
msgstr ""
-#: src/expr-prs.c:391
+#: src/expr-prs.c:392
msgid ""
"Chaining relational operators (e.g. \"a < b < c\") will not produce the "
"mathematically expected result. Use the AND logical operator to fix the "
"parentheses will disable this warning (e.g. \"(a < b) < c\".)"
msgstr ""
-#: src/expr-prs.c:471
+#: src/expr-prs.c:472
msgid ""
"The exponentiation operator (\"**\") is left-associative, even though right-"
"associative semantics are more useful. That is, \"a**b**c\" equals \"(a**b)"
"**c\", not as \"a**(b**c)\". To disable this warning, insert parentheses."
msgstr ""
-#: src/expr-prs.c:552
+#: src/expr-prs.c:553
#, c-format
msgid "Unknown system variable %s."
msgstr ""
-#: src/expr-prs.c:591
+#: src/expr-prs.c:592
msgid "expecting variable name"
msgstr ""
-#: src/expr-prs.c:634
+#: src/expr-prs.c:635
msgid "in expression"
msgstr ""
-#: src/expr-prs.c:730
+#: src/expr-prs.c:731
msgid "Argument 2 to LAG must be a small positive integer constant."
msgstr ""
-#: src/expr-prs.c:811 src/expr-prs.c:850
+#: src/expr-prs.c:812 src/expr-prs.c:851
#, c-format
msgid ""
"Type mismatch in argument %d of %s, which was expected to be of %s type. It "
"was actually of %s type. "
msgstr ""
-#: src/expr-prs.c:837
+#: src/expr-prs.c:838
#, c-format
msgid "%s cannot take Boolean operands."
msgstr ""
-#: src/expr-prs.c:869
+#: src/expr-prs.c:870
msgid "in function call"
msgstr ""
-#: src/expr-prs.c:883
+#: src/expr-prs.c:884
msgid "RANGE requires an odd number of arguments, but at least three."
msgstr ""
-#: src/expr-prs.c:893
+#: src/expr-prs.c:894
#, c-format
msgid "%s requires at least two arguments."
msgstr ""
-#: src/expr-prs.c:908
+#: src/expr-prs.c:909
#, c-format
msgid "%s.%d requires at least %d arguments."
msgstr ""
-#: src/expr-prs.c:973
+#: src/expr-prs.c:974
#, c-format
msgid ""
"Argument %d to CONCAT is type %s. All arguments to CONCAT must be strings."
msgstr ""
-#: src/expr-prs.c:1070
+#: src/expr-prs.c:1071
#, c-format
msgid ""
"Argument %d to %s was expected to be of %s type. It was actually of type %s."
msgstr ""
-#: src/expr-prs.c:1087
+#: src/expr-prs.c:1088
#, c-format
msgid "%s is not a numeric format."
msgstr ""
-#: src/expr-prs.c:1125
+#: src/expr-prs.c:1126
#, c-format
msgid "Too few arguments to function %s."
msgstr ""
-#: src/expr-prs.c:1158
+#: src/expr-prs.c:1159
#, c-format
msgid ""
"Type mismatch in argument %d of %s. A string expression was supplied where "
"only a numeric expression is allowed."
msgstr ""
-#: src/expr-prs.c:1168
+#: src/expr-prs.c:1169
#, c-format
msgid "Missing comma following argument %d of %s."
msgstr ""
-#: src/expr-prs.c:1206
+#: src/expr-prs.c:1207
msgid "The index value after a vector name must be numeric."
msgstr ""
-#: src/expr-prs.c:1213
+#: src/expr-prs.c:1214
msgid "`)' expected after a vector index value."
msgstr ""
-#: src/expr-prs.c:1246
+#: src/expr-prs.c:1247
#, c-format
msgid "There is no function named %s."
msgstr ""
-#: src/expr-prs.c:1251
+#: src/expr-prs.c:1252
#, c-format
msgid "Function %s may not be given a minimum number of arguments."
msgstr ""
-#: src/expr-prs.c:1260
+#: src/expr-prs.c:1261
#, c-format
msgid "expecting `)' after %s function"
msgstr ""
-#: src/expr-prs.c:1282
+#: src/expr-prs.c:1283
msgid "Boolean"
msgstr ""
-#: src/filename.c:221
-#, c-format
-msgid "Searching for `%s'..."
-msgstr ""
-
-#: src/filename.c:229 src/filename.c:261
-msgid "Search unsuccessful!"
-msgstr ""
-
-#: src/filename.c:254
-#, c-format
-msgid "Found `%s'."
-msgstr ""
-
-#: src/filename.c:686
-#, c-format
-msgid "Not opening pipe file `%s' because SAFER option set."
-msgstr ""
-
-#: src/file-type.c:127
+#: src/file-type.c:129
msgid "MIXED, GROUPED, or NESTED expected."
msgstr ""
-#: src/file-type.c:150
+#: src/file-type.c:152
msgid "The CASE subcommand is not valid on FILE TYPE MIXED."
msgstr ""
-#: src/file-type.c:168
+#: src/file-type.c:170
msgid "WARN or NOWARN expected after WILD."
msgstr ""
-#: src/file-type.c:176
+#: src/file-type.c:178
msgid "The DUPLICATE subcommand is not valid on FILE TYPE MIXED."
msgstr ""
-#: src/file-type.c:190
+#: src/file-type.c:192
msgid "DUPLICATE=CASE is only valid on FILE TYPE NESTED."
msgstr ""
-#: src/file-type.c:199
+#: src/file-type.c:201
#, c-format
msgid "WARN%s expected after DUPLICATE."
msgstr ""
-#: src/file-type.c:200
+#: src/file-type.c:202
msgid ", NOWARN, or CASE"
msgstr ""
-#: src/file-type.c:201
+#: src/file-type.c:203
msgid " or NOWARN"
msgstr ""
-#: src/file-type.c:209
+#: src/file-type.c:211
msgid "The MISSING subcommand is not valid on FILE TYPE MIXED."
msgstr ""
-#: src/file-type.c:221
+#: src/file-type.c:223
msgid "WARN or NOWARN after MISSING."
msgstr ""
-#: src/file-type.c:229
+#: src/file-type.c:231
msgid "ORDERED is only valid on FILE TYPE GROUPED."
msgstr ""
-#: src/file-type.c:240
+#: src/file-type.c:242
msgid "YES or NO expected after ORDERED."
msgstr ""
-#: src/file-type.c:246 src/file-type.c:540 src/get.c:335
+#: src/file-type.c:248 src/file-type.c:543 src/get.c:389
msgid "while expecting a valid subcommand"
msgstr ""
-#: src/file-type.c:253
+#: src/file-type.c:255
msgid "The required RECORD subcommand was not present."
msgstr ""
-#: src/file-type.c:261
+#: src/file-type.c:263
msgid "The required CASE subcommand was not present."
msgstr ""
-#: src/file-type.c:267
+#: src/file-type.c:269
msgid "CASE and RECORD must specify different variable names."
msgstr ""
-#: src/file-type.c:324
+#: src/file-type.c:327
msgid "Column value must be positive."
msgstr ""
-#: src/file-type.c:340
+#: src/file-type.c:343
msgid "Ending column precedes beginning column."
msgstr ""
-#: src/file-type.c:360
+#: src/file-type.c:363
msgid "Bad format specifier name."
msgstr ""
-#: src/file-type.c:389 src/file-type.c:577
+#: src/file-type.c:392 src/file-type.c:580
msgid ""
"This command may only appear within a FILE TYPE/END FILE TYPE structure."
msgstr ""
-#: src/file-type.c:412
+#: src/file-type.c:415
msgid "OTHER may appear only on the last RECORD TYPE command."
msgstr ""
-#: src/file-type.c:422
+#: src/file-type.c:425
msgid "No input commands (DATA LIST, REPEATING DATA) for above RECORD TYPE."
msgstr ""
-#: src/file-type.c:473
+#: src/file-type.c:476
msgid ""
"The CASE subcommand is not allowed on the RECORD TYPE command for FILE TYPE "
"MIXED."
msgstr ""
-#: src/file-type.c:483
+#: src/file-type.c:486
msgid ""
"No variable name may be specified for the CASE subcommand on RECORD TYPE."
msgstr ""
-#: src/file-type.c:491
+#: src/file-type.c:494
msgid ""
"The CASE column specification on RECORD TYPE must give a format specifier "
"that is the same type as that of the CASE column specification given on FILE "
"TYPE."
msgstr ""
-#: src/file-type.c:507
+#: src/file-type.c:510
msgid "WARN or NOWARN expected on DUPLICATE subcommand."
msgstr ""
-#: src/file-type.c:521
+#: src/file-type.c:524
msgid "WARN or NOWARN expected on MISSING subcommand."
msgstr ""
-#: src/file-type.c:534
+#: src/file-type.c:537
msgid "YES or NO expected on SPREAD subcommand."
msgstr ""
-#: src/file-type.c:590
+#: src/file-type.c:593
msgid "No input commands (DATA LIST, REPEATING DATA) on above RECORD TYPE."
msgstr ""
-#: src/file-type.c:597
+#: src/file-type.c:600
msgid "No commands between FILE TYPE and END FILE TYPE."
msgstr ""
-#: src/file-type.c:666
+#: src/file-type.c:669
#, c-format
msgid "Unknown record type \"%.*s\"."
msgstr ""
-#: src/file-type.c:690
+#: src/file-type.c:693
#, c-format
msgid "Unknown record type %g."
msgstr ""
-#: src/flip.c:77
+#: src/filename.c:221
+#, c-format
+msgid "Searching for `%s'..."
+msgstr ""
+
+#: src/filename.c:229 src/filename.c:261
+msgid "Search unsuccessful!"
+msgstr ""
+
+#: src/filename.c:254
+#, c-format
+msgid "Found `%s'."
+msgstr ""
+
+#: src/filename.c:686
+#, c-format
+msgid "Not opening pipe file `%s' because SAFER option set."
+msgstr ""
+
+#: src/flip.c:78
msgid ""
"FLIP ignores TEMPORARY. Temporary transformations will be made permanent."
msgstr ""
-#: src/flip.c:217
+#: src/flip.c:218
#, c-format
msgid "Could not create acceptable variant for variable %s."
msgstr ""
-#: src/flip.c:233
+#: src/flip.c:234
msgid "Cannot create more than 99999 variable names."
msgstr ""
-#: src/flip.c:277
+#: src/flip.c:278
msgid "Could not create temporary file for FLIP."
msgstr ""
-#: src/flip.c:284 src/flip.c:352
+#: src/flip.c:285 src/flip.c:353
#, c-format
msgid "Error writing FLIP file: %s."
msgstr ""
-#: src/flip.c:394
+#: src/flip.c:395
#, c-format
msgid "Error rewinding FLIP file: %s."
msgstr ""
-#: src/flip.c:398
+#: src/flip.c:399
msgid "Error creating FLIP source file."
msgstr ""
-#: src/flip.c:407
+#: src/flip.c:408
#, c-format
msgid "Error reading FLIP file: %s."
msgstr ""
-#: src/flip.c:424
+#: src/flip.c:425
#, c-format
msgid "Error seeking FLIP source file: %s."
msgstr ""
-#: src/flip.c:429
+#: src/flip.c:430
#, c-format
msgid "Error writing FLIP source file: %s."
msgstr ""
-#: src/flip.c:440
+#: src/flip.c:441
#, c-format
msgid "Error rewind FLIP source file: %s."
msgstr ""
-#: src/flip.c:492
+#: src/flip.c:493
#, c-format
msgid "Error reading FLIP temporary file: %s."
msgstr ""
-#: src/flip.c:495
+#: src/flip.c:496
msgid "Unexpected end of file reading FLIP temporary file."
msgstr ""
msgid "Format %s may not be assigned to a %s variable."
msgstr ""
-#: src/formats.c:116 src/numeric.c:64 src/numeric.c:135
+#: src/formats.c:116 src/numeric.c:65 src/numeric.c:136
msgid "`)' expected after output format."
msgstr ""
-#: src/get.c:341
+#: src/get.c:395
msgid "All variables deleted from system file dictionary."
msgstr ""
-#: src/get.c:388
+#: src/get.c:445
#, c-format
msgid ""
"Cannot rename %s as %s because there already exists a variable named %s. To "
"as \"/RENAME (A=B)(B=C)(C=A)\", or equivalently, \"/RENAME (A B C=B C A)\"."
msgstr ""
-#: src/get.c:413
+#: src/get.c:470
msgid "`=' expected after variable list."
msgstr ""
-#: src/get.c:420
+#: src/get.c:477
#, 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:433
+#: src/get.c:490
#, c-format
msgid "Requested renaming duplicates variable name %s."
msgstr ""
-#: src/get.c:564
+#: src/get.c:674
msgid "The BY subcommand may be given once at most."
msgstr ""
-#: src/get.c:631
+#: src/get.c:746
msgid "The active file may not be specified more than once."
msgstr ""
-#: src/get.c:640
+#: src/get.c:755
msgid "Cannot specify the active file since no active file has been defined."
msgstr ""
-#: src/get.c:648
+#: src/get.c:763
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:682
+#: src/get.c:793
msgid ""
"IN, FIRST, and LAST subcommands may not occur before the first FILE or TABLE."
msgstr ""
-#: src/get.c:717
+#: src/get.c:828
#, c-format
msgid "Multiple %s subcommands for a single FILE or TABLE."
msgstr ""
-#: src/get.c:727
+#: src/get.c:838
#, c-format
msgid "Duplicate variable name %s while creating %s variable."
msgstr ""
-#: src/get.c:741
+#: src/get.c:850
msgid ""
"RENAME, KEEP, and DROP subcommands may not occur before the first FILE or "
"TABLE."
msgstr ""
-#: src/get.c:765
+#: src/get.c:877
msgid "The BY subcommand is required when a TABLE subcommand is given."
msgstr ""
-#: src/get.c:786
+#: src/get.c:896
#, c-format
msgid "File %s lacks BY variable %s."
msgstr ""
-#: src/get.c:1282
+#: src/get.c:1390
#, 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:1330
+#: src/get.c:1468
msgid "expecting COMM or TAPE"
msgstr ""
msgid "HTML output driver: %s: %s"
msgstr ""
-#: src/html.c:403 src/list.q:250
+#: src/html.c:403 src/list.q:252
#, c-format
msgid "Cannot open first page on HTML device %s."
msgstr ""
msgid "expecting filename"
msgstr ""
-#: src/inpt-pgm.c:81
+#: src/inpt-pgm.c:82
msgid "No matching INPUT PROGRAM command."
msgstr ""
-#: src/inpt-pgm.c:86
+#: src/inpt-pgm.c:87
msgid ""
"No data-input or transformation commands specified between INPUT PROGRAM and "
"END INPUT PROGRAM."
msgstr ""
-#: src/inpt-pgm.c:287 src/inpt-pgm.c:420
+#: src/inpt-pgm.c:288 src/inpt-pgm.c:418
msgid ""
"This command may only be executed between INPUT PROGRAM and END INPUT "
"PROGRAM."
msgstr ""
-#: src/inpt-pgm.c:342
+#: src/inpt-pgm.c:338
msgid "COLUMN subcommand multiply specified."
msgstr ""
-#: src/inpt-pgm.c:395
+#: src/inpt-pgm.c:391
msgid ""
"REREAD: Column numbers must be positive finite numbers. Column set to 1."
msgstr ""
msgid "<ERROR>"
msgstr ""
-#: src/lexer.c:993 src/pfm-read.c:136 src/repeat.c:213
+#: src/lexer.c:993 src/pfm-read.c:134 src/repeat.c:214
msgid "Unexpected end of file."
msgstr ""
"spaces."
msgstr ""
-#: src/loop.c:193
+#: src/loop.c:194
msgid "The index variable may not be a string variable."
msgstr ""
-#: src/loop.c:299
+#: src/loop.c:300
msgid "There is no LOOP command that corresponds to this END LOOP."
msgstr ""
-#: src/loop.c:493
+#: src/loop.c:494
msgid ""
"This command may only appear enclosed in a LOOP/END LOOP control structure."
msgstr ""
-#: src/loop.c:499
+#: src/loop.c:500
msgid "BREAK not enclosed in DO IF structure."
msgstr ""
-#: src/loop.c:577
+#: src/loop.c:578
#, c-format
msgid "%s without %s."
msgstr ""
-#: src/main.c:74
+#: src/main.c:76
msgid "Error initializing output drivers."
msgstr ""
-#: src/main.c:140
+#: src/main.c:146
msgid "This command not executed."
msgstr ""
-#: src/main.c:144
+#: src/main.c:150
msgid ""
"Skipping the rest of this command. Part of this command may have been "
"executed."
msgstr ""
-#: src/main.c:149
+#: src/main.c:155
msgid ""
"Skipping the rest of this command. This command was fully executed up to "
"this point."
msgstr ""
-#: src/main.c:154
+#: src/main.c:160
msgid ""
"Trailing garbage was encountered following this command. The command was "
"fully executed to this point."
msgstr ""
-#: src/main.c:171
+#: src/main.c:177
msgid "The rest of this command has been discarded."
msgstr ""
-#: src/matrix-data.c:185
+#: src/matrix-data.c:208
msgid "VARIABLES subcommand multiply specified."
msgstr ""
-#: src/matrix-data.c:200
+#: src/matrix-data.c:223
msgid "VARNAME_ cannot be explicitly specified on VARIABLES."
msgstr ""
-#: src/matrix-data.c:265
+#: src/matrix-data.c:284
msgid "in FORMAT subcommand"
msgstr ""
-#: src/matrix-data.c:276
+#: src/matrix-data.c:295
msgid "SPLIT subcommand multiply specified."
msgstr ""
-#: src/matrix-data.c:283
+#: src/matrix-data.c:302
msgid "in SPLIT subcommand"
msgstr ""
-#: src/matrix-data.c:292
+#: src/matrix-data.c:311
msgid "Split variable may not be named ROWTYPE_ or VARNAME_."
msgstr ""
-#: src/matrix-data.c:325
+#: src/matrix-data.c:345
#, c-format
msgid "Split variable %s is already another type."
msgstr ""
-#: src/matrix-data.c:340
+#: src/matrix-data.c:360
msgid "FACTORS subcommand multiply specified."
msgstr ""
-#: src/matrix-data.c:355
+#: src/matrix-data.c:378
#, c-format
msgid "Factor variable %s is already another type."
msgstr ""
-#: src/matrix-data.c:370
+#: src/matrix-data.c:393
msgid "CELLS subcommand multiply specified."
msgstr ""
-#: src/matrix-data.c:376 src/matrix-data.c:395
+#: src/matrix-data.c:399 src/matrix-data.c:418
msgid "expecting positive integer"
msgstr ""
-#: src/matrix-data.c:389
+#: src/matrix-data.c:412
msgid "N subcommand multiply specified."
msgstr ""
-#: src/matrix-data.c:410
+#: src/matrix-data.c:433
msgid "CONTENTS subcommand multiply specified."
msgstr ""
-#: src/matrix-data.c:430
+#: src/matrix-data.c:453
msgid "Nested parentheses not allowed."
msgstr ""
-#: src/matrix-data.c:440
+#: src/matrix-data.c:463
msgid "Mismatched right parenthesis (`(')."
msgstr ""
-#: src/matrix-data.c:445
+#: src/matrix-data.c:468
msgid "Empty parentheses not allowed."
msgstr ""
-#: src/matrix-data.c:458 src/matrix-data.c:466
+#: src/matrix-data.c:481 src/matrix-data.c:489
msgid "in CONTENTS subcommand"
msgstr ""
-#: src/matrix-data.c:473
+#: src/matrix-data.c:496
#, c-format
msgid "Content multiply specified for %s."
msgstr ""
-#: src/matrix-data.c:490
+#: src/matrix-data.c:513
msgid "Missing right parenthesis."
msgstr ""
-#: src/matrix-data.c:510
+#: src/matrix-data.c:533
msgid "Missing VARIABLES subcommand."
msgstr ""
-#: src/matrix-data.c:516
+#: src/matrix-data.c:539
msgid ""
"CONTENTS subcommand not specified: assuming file contains only CORR matrix."
msgstr ""
-#: src/matrix-data.c:526
+#: src/matrix-data.c:549
msgid ""
"Missing CELLS subcommand. CELLS is required when ROWTYPE_ is not given in "
"the data and factors are present."
msgstr ""
-#: src/matrix-data.c:534
+#: src/matrix-data.c:557
msgid "Split file values must be present in the data when ROWTYPE_ is present."
msgstr ""
-#: src/matrix-data.c:589
+#: src/matrix-data.c:610
msgid "No continuous variables specified."
msgstr ""
-#: src/matrix-data.c:815
+#: src/matrix-data.c:853
msgid "Scope of string exceeds line."
msgstr ""
-#: src/matrix-data.c:882
+#: src/matrix-data.c:920
#, c-format
msgid "End of line expected %s while reading %s."
msgstr ""
-#: src/matrix-data.c:1070
+#: src/matrix-data.c:1106
#, c-format
msgid "expecting value for %s %s"
msgstr ""
-#: src/matrix-data.c:1232
+#: src/matrix-data.c:1270
#, c-format
msgid "Syntax error expecting SPLIT FILE value %s."
msgstr ""
-#: src/matrix-data.c:1241
+#: src/matrix-data.c:1279
#, c-format
msgid "Expecting value %g for %s."
msgstr ""
-#: src/matrix-data.c:1282 src/matrix-data.c:1750
+#: src/matrix-data.c:1320 src/matrix-data.c:1787
#, c-format
msgid "Syntax error expecting factor value %s."
msgstr ""
-#: src/matrix-data.c:1291
+#: src/matrix-data.c:1329
#, c-format
msgid "Syntax error expecting value %g for %s %s."
msgstr ""
-#: src/matrix-data.c:1527
+#: src/matrix-data.c:1564
#, c-format
msgid "Syntax error %s expecting SPLIT FILE value."
msgstr ""
-#: src/matrix-data.c:1657
+#: src/matrix-data.c:1694
#, c-format
msgid ""
"Expected %d lines of data for %s content; actually saw %d lines. No data "
"will be output for this content."
msgstr ""
-#: src/matrix-data.c:1692
+#: src/matrix-data.c:1729
#, c-format
msgid "Multiply specified ROWTYPE_ %s."
msgstr ""
-#: src/matrix-data.c:1697
+#: src/matrix-data.c:1734
#, c-format
msgid "Syntax error %s expecting ROWTYPE_ string."
msgstr ""
-#: src/matrix-data.c:1717
+#: src/matrix-data.c:1754
#, c-format
msgid "Syntax error %s."
msgstr ""
-#: src/matrix-data.c:1867
+#: src/matrix-data.c:1904
#, c-format
msgid "Duplicate specification for %s."
msgstr ""
-#: src/matrix-data.c:1879
+#: src/matrix-data.c:1916
#, c-format
msgid "Too many rows of matrix data for %s."
msgstr ""
-#: src/matrix-data.c:1927
+#: src/matrix-data.c:1964
#, c-format
msgid "Syntax error expecting value for %s %s."
msgstr ""
msgid "String is not of proper length."
msgstr ""
-#: src/mis-val.c:316 src/repeat.c:459
+#: src/mis-val.c:316 src/repeat.c:460
msgid "String expected."
msgstr ""
-#: src/modify-vars.c:88
+#: src/modify-vars.c:89
msgid ""
"MODIFY VARS may not be used after TEMPORARY. Temporary transformations will "
"be made permanent."
msgstr ""
-#: src/modify-vars.c:112
+#: src/modify-vars.c:113
msgid "REORDER subcommand may be given at most once."
msgstr ""
-#: src/modify-vars.c:135
+#: src/modify-vars.c:136
msgid "Cannot specify ALL after specifying a set of variables."
msgstr ""
-#: src/modify-vars.c:145
+#: src/modify-vars.c:146
msgid "`(' expected on REORDER subcommand."
msgstr ""
-#: src/modify-vars.c:157
+#: src/modify-vars.c:158
msgid "`)' expected following variable names on REORDER subcommand."
msgstr ""
-#: src/modify-vars.c:175
+#: src/modify-vars.c:176
msgid "RENAME subcommand may be given at most once."
msgstr ""
-#: src/modify-vars.c:188
+#: src/modify-vars.c:189
msgid "`(' expected on RENAME subcommand."
msgstr ""
-#: src/modify-vars.c:196
+#: src/modify-vars.c:197
msgid ""
"`=' expected between lists of new and old variable names on RENAME "
"subcommand."
msgstr ""
-#: src/modify-vars.c:204 src/rename-vars.c:74
+#: src/modify-vars.c:205 src/rename-vars.c:75
#, c-format
msgid ""
"Differing number of variables in old name list (%d) and in new name list (%"
"d)."
msgstr ""
-#: src/modify-vars.c:215
+#: src/modify-vars.c:216
msgid "`)' expected after variable lists on RENAME subcommand."
msgstr ""
-#: src/modify-vars.c:229
+#: src/modify-vars.c:230
msgid ""
"KEEP subcommand may be given at most once. It may notbe given in "
"conjunction with the DROP subcommand."
msgstr ""
-#: src/modify-vars.c:271
+#: src/modify-vars.c:272
msgid ""
"DROP subcommand may be given at most once. It may not be given in "
"conjunction with the KEEP subcommand."
msgstr ""
-#: src/modify-vars.c:297
+#: src/modify-vars.c:298
#, c-format
msgid "Unrecognized subcommand name `%s'."
msgstr ""
-#: src/modify-vars.c:299
+#: src/modify-vars.c:300
msgid "Subcommand name expected."
msgstr ""
-#: src/modify-vars.c:307
+#: src/modify-vars.c:308
msgid "`/' or `.' expected."
msgstr ""
msgid "expecting weight value"
msgstr ""
-#: src/numeric.c:57
+#: src/numeric.c:58
#, c-format
msgid "Format type %s may not be used with a numeric variable."
msgstr ""
-#: src/numeric.c:76 src/numeric.c:158 src/vector.c:155
+#: src/numeric.c:77 src/numeric.c:159 src/vector.c:156
#, c-format
msgid "There is already a variable named %s."
msgstr ""
-#: src/numeric.c:128
+#: src/numeric.c:129
#, c-format
msgid "Format type %s may not be used with a string variable."
msgstr ""
msgid "portable file %s corrupt at offset %ld: "
msgstr ""
-#: src/pfm-read.c:111 src/pfm-write.c:504
+#: src/pfm-read.c:114 src/pfm-write.c:490
#, c-format
msgid "%s: Closing portable file: %s."
msgstr ""
-#: src/pfm-read.c:144
+#: src/pfm-read.c:142
msgid "Bad line end."
msgstr ""
-#: src/pfm-read.c:225
-#, c-format
-msgid "Cannot read file %s as portable file: already opened for %s."
-msgstr ""
-
-#: src/pfm-read.c:231
-#, c-format
-msgid "%s: Opening portable-file handle %s for reading."
-msgstr ""
-
-#: src/pfm-read.c:239
+#: src/pfm-read.c:233
#, c-format
msgid ""
"An error occurred while opening \"%s\" for reading as a portable file: %s."
msgstr ""
-#: src/pfm-read.c:274
+#: src/pfm-read.c:256
msgid "Data record expected."
msgstr ""
-#: src/pfm-read.c:276
-msgid "Read portable-file dictionary successfully."
-msgstr ""
-
-#: src/pfm-read.c:282
-msgid "Error reading portable-file dictionary."
-msgstr ""
-
-#: src/pfm-read.c:380
+#: src/pfm-read.c:353
msgid "Missing numeric terminator."
msgstr ""
-#: src/pfm-read.c:417
+#: src/pfm-read.c:390
msgid "Bad integer format."
msgstr ""
-#: src/pfm-read.c:447
+#: src/pfm-read.c:419
#, c-format
msgid "Bad string length %d."
msgstr ""
-#: src/pfm-read.c:546
+#: src/pfm-read.c:514
#, c-format
msgid "Bad date string length %d."
msgstr ""
-#: src/pfm-read.c:550
+#: src/pfm-read.c:518
msgid "Bad character in date."
msgstr ""
-#: src/pfm-read.c:570
+#: src/pfm-read.c:538
#, c-format
msgid "Bad time string length %d."
msgstr ""
-#: src/pfm-read.c:574
+#: src/pfm-read.c:542
msgid "Bad character in time."
msgstr ""
-#: src/pfm-read.c:624 src/pfm-read.c:631 src/sfm-read.c:912 src/sfm-read.c:920
+#: src/pfm-read.c:592 src/pfm-read.c:599 src/sfm-read.c:873 src/sfm-read.c:881
#, c-format
msgid "%s: Bad format specifier byte (%d)."
msgstr ""
-#: src/pfm-read.c:633
+#: src/pfm-read.c:601
#, c-format
msgid "%s variable %s has %s format specifier %s."
msgstr ""
-#: src/pfm-read.c:634 src/print.c:601 src/sfm-read.c:925
+#: src/pfm-read.c:602 src/print.c:607 src/sfm-read.c:886
msgid "String"
msgstr ""
-#: src/pfm-read.c:634 src/print.c:601 src/sfm-read.c:925
+#: src/pfm-read.c:602 src/print.c:607 src/sfm-read.c:886
msgid "Numeric"
msgstr ""
-#: src/pfm-read.c:673
+#: src/pfm-read.c:640
msgid "Expected variable count record."
msgstr ""
-#: src/pfm-read.c:677
+#: src/pfm-read.c:644
#, c-format
msgid "Invalid number of variables %d."
msgstr ""
-#: src/pfm-read.c:687
+#: src/pfm-read.c:654
#, c-format
msgid "Unexpected flag value %d."
msgstr ""
-#: src/pfm-read.c:701
+#: src/pfm-read.c:666
#, c-format
msgid "Weight variable name (%s) truncated."
msgstr ""
-#: src/pfm-read.c:716
+#: src/pfm-read.c:681
msgid "Expected variable record."
msgstr ""
-#: src/pfm-read.c:722
+#: src/pfm-read.c:687
#, c-format
msgid "Invalid variable width %d."
msgstr ""
-#: src/pfm-read.c:740
+#: src/pfm-read.c:705
#, c-format
msgid "position %d: Variable name has %u characters."
msgstr ""
-#: src/pfm-read.c:744
+#: src/pfm-read.c:709
#, c-format
msgid "position %d: Variable name begins with invalid character."
msgstr ""
-#: src/pfm-read.c:748
+#: src/pfm-read.c:713
#, c-format
msgid "position %d: Variable name begins with lowercase letter %c."
msgstr ""
-#: src/pfm-read.c:761
+#: src/pfm-read.c:726
#, c-format
msgid "position %d: Variable name character %d is lowercase letter %c."
msgstr ""
-#: src/pfm-read.c:771
+#: src/pfm-read.c:736
#, c-format
msgid "position %d: character `\\%03o' is not valid in a variable name."
msgstr ""
-#: src/pfm-read.c:782
+#: src/pfm-read.c:748
#, c-format
msgid "Duplicate variable name %s."
msgstr ""
-#: src/pfm-read.c:826
+#: src/pfm-read.c:792
#, c-format
msgid "Bad missing values for %s."
msgstr ""
-#: src/pfm-read.c:849
+#: src/pfm-read.c:815
#, c-format
msgid "Weighting variable %s not present in dictionary."
msgstr ""
-#: src/pfm-read.c:922
+#: src/pfm-read.c:886
#, c-format
msgid "Unknown variable %s while parsing value labels."
msgstr ""
-#: src/pfm-read.c:925
+#: src/pfm-read.c:889
#, c-format
msgid ""
"Cannot assign value labels to %s and %s, which have different variable types "
"or widths."
msgstr ""
-#: src/pfm-read.c:958
+#: src/pfm-read.c:922
#, c-format
msgid "Duplicate label for value %g for variable %s."
msgstr ""
-#: src/pfm-read.c:961
+#: src/pfm-read.c:925
#, c-format
msgid "Duplicate label for value `%.*s' for variable %s."
msgstr ""
-#: src/pfm-read.c:1032
+#: src/pfm-read.c:978
msgid "End of file midway through case."
msgstr ""
-#: src/pfm-read.c:1042
-msgid "reading as a portable file"
-msgstr ""
-
-#: src/pfm-write.c:71
-#, c-format
-msgid "Cannot write file %s as portable file: already opened for %s."
-msgstr ""
-
-#: src/pfm-write.c:77
-#, c-format
-msgid "%s: Opening portable-file handle %s for writing."
-msgstr ""
-
-#: src/pfm-write.c:87
+#: src/pfm-write.c:92
#, c-format
msgid ""
"An error occurred while opening \"%s\" for writing as a portable file: %s."
msgstr ""
-#: src/pfm-write.c:124
-msgid "Wrote portable-file header successfully."
-msgstr ""
-
-#: src/pfm-write.c:129
-msgid "Error writing portable-file header."
-msgstr ""
-
-#: src/pfm-write.c:170
+#: src/pfm-write.c:154
#, c-format
msgid "%s: Writing portable file: %s."
msgstr ""
-#: src/pfm-write.c:514
-msgid "writing as a portable file"
-msgstr ""
-
#: src/postscript.c:323
#, c-format
msgid "PostScript driver initializing as `%s'..."
msgid "PostScript driver: Cannot find encoding `%s' for PostScript font `%s'."
msgstr ""
-#: src/print.c:180
+#: src/print.c:179
msgid "expecting a valid subcommand"
msgstr ""
-#: src/print.c:359 src/print.c:376
+#: src/print.c:365 src/print.c:382
#, c-format
msgid "%g is not a valid column location."
msgstr ""
-#: src/print.c:370
+#: src/print.c:376
#, c-format
msgid "Column location expected following `%d-'."
msgstr ""
-#: src/print.c:381
+#: src/print.c:387
#, c-format
msgid ""
"%d-%ld is not a valid column range. The second column must be greater than "
"or equal to the first."
msgstr ""
-#: src/print.c:487
+#: src/print.c:493
#, c-format
msgid ""
"%s is not of the same type as %s. To specify variables of different types "
"in the same variable list, use a FORTRAN-like format specifier."
msgstr ""
-#: src/print.c:517
+#: src/print.c:523
msgid ""
"The ending column for a field must not be less than the starting column."
msgstr ""
-#: src/print.c:600
+#: src/print.c:606
#, c-format
msgid "%s variables cannot be displayed with format %s."
msgstr ""
-#: src/print.c:678
+#: src/print.c:684
msgid ""
"The number of format specifications exceeds the number of variable names "
"given."
msgstr ""
-#: src/print.c:687
+#: src/print.c:693
#, c-format
msgid "Display format %s may not be used with a %s variable."
msgstr ""
-#: src/print.c:835
+#: src/print.c:841
#, c-format
msgid "Writing %d record(s) to file %s."
msgstr ""
-#: src/print.c:838
+#: src/print.c:844
#, c-format
msgid "Writing %d record(s) to the listing file."
msgstr ""
-#: src/print.c:1080
+#: src/print.c:1092
#, c-format
msgid ""
"The expression on PRINT SPACE evaluated to %d. It's not possible to PRINT "
"SPACE a negative number of lines."
msgstr ""
-#: src/recode.c:282
+#: src/recode.c:283
#, c-format
msgid ""
"%d variable(s) cannot be recoded into %d variable(s). Specify the same "
"number of variables as input and output variables."
msgstr ""
-#: src/recode.c:296
+#: src/recode.c:297
#, c-format
msgid ""
"There is no string variable named %s. (All string variables specified on "
"variable.)"
msgstr ""
-#: src/recode.c:305
+#: src/recode.c:306
#, c-format
msgid ""
"Type mismatch between input and output variables. Output variable %s is not "
"a string variable, but all the input variables are string variables."
msgstr ""
-#: src/recode.c:324
+#: src/recode.c:325
#, c-format
msgid "Type mismatch after INTO: %s is not a numeric variable."
msgstr ""
-#: src/recode.c:354
+#: src/recode.c:355
msgid ""
"INTO must be used when the input values are numeric and output values are "
"string."
msgstr ""
-#: src/recode.c:362
+#: src/recode.c:363
msgid ""
"INTO must be used when the input values are string and output values are "
"numeric."
msgstr ""
-#: src/recode.c:485
+#: src/recode.c:486
msgid "expecting output value"
msgstr ""
-#: src/recode.c:499
+#: src/recode.c:500
msgid ""
"Inconsistent output types. The output values must be all numeric or all "
"string."
msgstr ""
-#: src/recode.c:550
+#: src/recode.c:551
msgid "following LO THRU"
msgstr ""
-#: src/recode.c:566 src/recode.c:595
+#: src/recode.c:567 src/recode.c:596
msgid "in source value"
msgstr ""
-#: src/recode.c:608
+#: src/recode.c:609
msgid ""
"Keyword CONVERT may only be used with string input values and numeric output "
"values."
msgstr ""
-#: src/rename-vars.c:47
+#: src/rename-vars.c:48
msgid ""
"RENAME VARS may not be used after TEMPORARY. Temporary transformations will "
"be made permanent."
msgstr ""
-#: src/rename-vars.c:59
+#: src/rename-vars.c:60
msgid "`(' expected."
msgstr ""
-#: src/rename-vars.c:67
+#: src/rename-vars.c:68
msgid "`=' expected between lists of new and old variable names."
msgstr ""
-#: src/rename-vars.c:85
+#: src/rename-vars.c:86
msgid "`)' expected after variable names."
msgstr ""
-#: src/rename-vars.c:95
+#: src/rename-vars.c:96
#, c-format
msgid "Renaming would duplicate variable name %s."
msgstr ""
-#: src/repeat.c:150
+#: src/repeat.c:151
#, c-format
msgid "Identifier %s is given twice."
msgstr ""
-#: src/repeat.c:193
+#: src/repeat.c:194
#, c-format
msgid ""
"There must be the same number of substitutions for each dummy variable "
"s as well, but %d were specified."
msgstr ""
-#: src/repeat.c:298
+#: src/repeat.c:299
msgid "No commands in scope."
msgstr ""
-#: src/repeat.c:486
+#: src/repeat.c:487
msgid "No matching DO REPEAT."
msgstr ""
msgid "Cannot sample %d observations from a population of %d."
msgstr ""
-#: src/sel-if.c:99
+#: src/sel-if.c:100
msgid "The filter variable must be numeric."
msgstr ""
-#: src/sel-if.c:105
+#: src/sel-if.c:106
msgid "The filter variable may not be scratch."
msgstr ""
-#: src/sel-if.c:136
+#: src/sel-if.c:137
msgid "Only last instance of this command is in effect."
msgstr ""
-#: src/sfm-read.c:147
+#: src/sfm-read.c:140
msgid "corrupt system file: "
msgstr ""
-#: src/sfm-read.c:163 src/sfm-write.c:743
+#: src/sfm-read.c:157 src/sfm-write.c:808
#, c-format
msgid "%s: Closing system file: %s."
msgstr ""
-#: src/sfm-read.c:237
-#, c-format
-msgid "Cannot read file %s as system file: already opened for %s."
-msgstr ""
-
-#: src/sfm-read.c:242
-#, c-format
-msgid "%s: Opening system-file handle %s for reading."
-msgstr ""
-
-#: src/sfm-read.c:250
+#: src/sfm-read.c:240
#, c-format
msgid ""
"An error occurred while opening \"%s\" for reading as a system file: %s."
msgstr ""
-#: src/sfm-read.c:285
+#: src/sfm-read.c:258
#, c-format
msgid ""
"%s: Weighting variable may not be a continuation of a long string variable."
msgstr ""
-#: src/sfm-read.c:288
+#: src/sfm-read.c:261
#, c-format
msgid "%s: Weighting variable may not be a string variable."
msgstr ""
-#: src/sfm-read.c:313
+#: src/sfm-read.c:286
#, 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:362
+#: src/sfm-read.c:335
#, c-format
msgid "%s: Unrecognized record type 7, subtype %d encountered in system file."
msgstr ""
-#: src/sfm-read.c:387
+#: src/sfm-read.c:360
#, c-format
msgid "%s: Unrecognized record type %d."
msgstr ""
-#: src/sfm-read.c:394
-msgid "Read system-file dictionary successfully."
-msgstr ""
-
-#: src/sfm-read.c:401
-msgid "Error reading system-file header."
-msgstr ""
-
-#: src/sfm-read.c:425
+#: src/sfm-read.c:392
#, 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:437
+#: src/sfm-read.c:403
#, 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:453
+#: src/sfm-read.c:419
#, c-format
msgid ""
"%s: File-indicated endianness (%s) does not match endianness intuited from "
"file header (%s)."
msgstr ""
-#: src/sfm-read.c:456 src/sfm-read.c:457
+#: src/sfm-read.c:422 src/sfm-read.c:423
msgid "big-endian"
msgstr ""
-#: src/sfm-read.c:456 src/sfm-read.c:457
+#: src/sfm-read.c:422 src/sfm-read.c:423
msgid "little-endian"
msgstr ""
-#: src/sfm-read.c:458
+#: src/sfm-read.c:424
msgid "unknown"
msgstr ""
-#: src/sfm-read.c:462
+#: src/sfm-read.c:428
#, c-format
msgid "%s: File-indicated character representation code (%s) is not ASCII."
msgstr ""
-#: src/sfm-read.c:466
+#: src/sfm-read.c:432
msgid "DEC Kanji"
msgstr ""
-#: src/sfm-read.c:485
+#: src/sfm-read.c:448
#, 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:500
+#: src/sfm-read.c:463
#, c-format
msgid ""
"%s: File-indicated value is different from internal value for at least one "
"%g; LOWEST: %g, %g."
msgstr ""
-#: src/sfm-read.c:531
+#: src/sfm-read.c:490
#, 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:574
+#: src/sfm-read.c:532
#, 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:590
+#: src/sfm-read.c:548
#, c-format
msgid "%s: Number of elements per case (%d) is not between 1 and %d."
msgstr ""
-#: src/sfm-read.c:599
+#: src/sfm-read.c:557
#, 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:605
+#: src/sfm-read.c:564
#, c-format
msgid "%s: Number of cases in file (%ld) is not between -1 and %d."
msgstr ""
-#: src/sfm-read.c:610
+#: src/sfm-read.c:569
#, c-format
msgid "%s: Compression bias (%g) is not the usual value of 100."
msgstr ""
-#: src/sfm-read.c:704
+#: src/sfm-read.c:662
#, c-format
msgid "%s: position %d: Bad record type (%d); the expected value was 2."
msgstr ""
-#: src/sfm-read.c:714
+#: src/sfm-read.c:672
#, c-format
msgid ""
"%s: position %d: String variable does not have proper number of continuation "
"records."
msgstr ""
-#: src/sfm-read.c:723
+#: src/sfm-read.c:681
#, c-format
msgid "%s: position %d: Superfluous long string continuation record."
msgstr ""
-#: src/sfm-read.c:729
+#: src/sfm-read.c:687
#, c-format
msgid "%s: position %d: Bad variable type code %d."
msgstr ""
-#: src/sfm-read.c:732
+#: src/sfm-read.c:690
#, c-format
msgid "%s: position %d: Variable label indicator field is not 0 or 1."
msgstr ""
-#: src/sfm-read.c:736
+#: src/sfm-read.c:694
#, c-format
msgid ""
"%s: position %d: Missing value indicator field is not -3, -2, 0, 1, 2, or 3."
msgstr ""
-#: src/sfm-read.c:742
+#: src/sfm-read.c:700
#, c-format
msgid "%s: position %d: Variable name begins with invalid character."
msgstr ""
-#: src/sfm-read.c:746
+#: src/sfm-read.c:704
#, c-format
msgid "%s: position %d: Variable name begins with lowercase letter %c."
msgstr ""
-#: src/sfm-read.c:750
+#: src/sfm-read.c:708
#, c-format
msgid ""
"%s: position %d: Variable name begins with octothorpe (`#'). Scratch "
"variables should not appear in system files."
msgstr ""
-#: src/sfm-read.c:765
+#: src/sfm-read.c:723
#, c-format
msgid "%s: position %d: Variable name character %d is lowercase letter %c."
msgstr ""
-#: src/sfm-read.c:774
+#: src/sfm-read.c:732
#, c-format
msgid ""
"%s: position %d: character `\\%03o' (%c) is not valid in a variable name."
msgstr ""
-#: src/sfm-read.c:783
+#: src/sfm-read.c:741
#, c-format
msgid "%s: Duplicate variable name `%s' within system file."
msgstr ""
-#: src/sfm-read.c:808
+#: src/sfm-read.c:762
#, c-format
msgid "%s: Variable %s indicates variable label of invalid length %d."
msgstr ""
-#: src/sfm-read.c:825
+#: src/sfm-read.c:779
#, c-format
msgid "%s: Long string variable %s may not have missing values."
msgstr ""
-#: src/sfm-read.c:850
+#: src/sfm-read.c:804
#, c-format
msgid ""
"%s: String variable %s may not have missing values specified as a range."
msgstr ""
-#: src/sfm-read.c:888
+#: src/sfm-read.c:852
#, c-format
msgid "%s: Long string continuation records omitted at end of dictionary."
msgstr ""
-#: src/sfm-read.c:892
+#: src/sfm-read.c:856
#, c-format
msgid ""
"%s: System file header indicates %d variable positions but %d were read from "
"file."
msgstr ""
-#: src/sfm-read.c:923
+#: src/sfm-read.c:884
#, c-format
msgid "%s: %s variable %s has %s format specifier %s."
msgstr ""
-#: src/sfm-read.c:1003
+#: src/sfm-read.c:963
#, 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:1014
+#: src/sfm-read.c:974
#, 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:1030
+#: src/sfm-read.c:990
#, 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:1037
+#: src/sfm-read.c:997
#, 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:1042
+#: src/sfm-read.c:1002
#, c-format
msgid "%s: Value labels are not allowed on long string variables (%s)."
msgstr ""
-#: src/sfm-read.c:1053
+#: src/sfm-read.c:1013
#, 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:1094
+#: src/sfm-read.c:1054
#, c-format
msgid "%s: File contains duplicate label for value %g for variable %s."
msgstr ""
-#: src/sfm-read.c:1098
+#: src/sfm-read.c:1058
#, c-format
msgid "%s: File contains duplicate label for value `%.*s' for variable %s."
msgstr ""
-#: src/sfm-read.c:1135 src/sfm-read.c:1338
+#: src/sfm-read.c:1093 src/sfm-read.c:1357
#, c-format
msgid "%s: Reading system file: %s."
msgstr ""
-#: src/sfm-read.c:1138 src/sfm-read.c:1245 src/sfm-read.c:1287
+#: src/sfm-read.c:1096 src/sfm-read.c:1198 src/sfm-read.c:1240
#, c-format
msgid "%s: Unexpected end of file."
msgstr ""
-#: src/sfm-read.c:1157
+#: src/sfm-read.c:1113
#, c-format
msgid "%s: System file contains multiple type 6 (document) records."
msgstr ""
-#: src/sfm-read.c:1163
+#: src/sfm-read.c:1119
#, c-format
msgid "%s: Number of document lines (%ld) must be greater than 0."
msgstr ""
-#: src/sfm-read.c:1196
+#: src/sfm-read.c:1151
#, c-format
msgid "%s: Error reading file: %s."
msgstr ""
-#: src/sfm-read.c:1235
+#: src/sfm-read.c:1188
#, c-format
msgid "%s: Compressed data is corrupted. Data ends in partial case."
msgstr ""
-#: src/sfm-read.c:1341
+#: src/sfm-read.c:1360
#, c-format
msgid "%s: Partial record at end of system file."
msgstr ""
-#: src/sfm-read.c:1380
-msgid "reading as a system file"
-msgstr ""
-
-#: src/sfm-write.c:95
-#, c-format
-msgid "Cannot write file %s as system file: already opened for %s."
-msgstr ""
-
-#: src/sfm-write.c:101
-#, c-format
-msgid "%s: Opening system-file handle %s for writing."
-msgstr ""
-
-#: src/sfm-write.c:111
+#: src/sfm-write.c:143
#, c-format
-msgid ""
-"An error occurred while opening \"%s\" for writing as a system file: %s."
-msgstr ""
-
-#: src/sfm-write.c:165
-msgid "Wrote system-file header successfully."
+msgid "Error opening \"%s\" for writing as a system file: %s."
msgstr ""
-#: src/sfm-write.c:170
-msgid "Error writing system-file header."
-msgstr ""
-
-#: src/sfm-write.c:606
+#: src/sfm-write.c:628
#, c-format
msgid "%s: Writing system file: %s."
msgstr ""
-#: src/sfm-write.c:754
-msgid "writing as a system file"
-msgstr ""
-
#: src/sort.c:197
msgid "`A' or `D' expected inside parentheses."
msgstr ""
"each. (PSPP workspace is currently restricted to a maximum of %d KB.)"
msgstr ""
-#: src/sysfile-info.c:94
+#: src/sysfile-info.c:96
msgid "File:"
msgstr ""
-#: src/sysfile-info.c:96
+#: src/sysfile-info.c:98
msgid "Label:"
msgstr ""
-#: src/sysfile-info.c:100
+#: src/sysfile-info.c:102
msgid "No label."
msgstr ""
-#: src/sysfile-info.c:103
+#: src/sysfile-info.c:105
msgid "Created:"
msgstr ""
-#: src/sysfile-info.c:106
+#: src/sysfile-info.c:108
msgid "Endian:"
msgstr ""
-#: src/sysfile-info.c:107
+#: src/sysfile-info.c:109
msgid "Big."
msgstr ""
-#: src/sysfile-info.c:107
+#: src/sysfile-info.c:109
msgid "Little."
msgstr ""
-#: src/sysfile-info.c:108
+#: src/sysfile-info.c:110
msgid "Variables:"
msgstr ""
-#: src/sysfile-info.c:111
+#: src/sysfile-info.c:113
msgid "Cases:"
msgstr ""
-#: src/sysfile-info.c:114
+#: src/sysfile-info.c:116
msgid "Type:"
msgstr ""
-#: src/sysfile-info.c:115
+#: src/sysfile-info.c:117
msgid "System File."
msgstr ""
-#: src/sysfile-info.c:116
+#: src/sysfile-info.c:118
msgid "Weight:"
msgstr ""
-#: src/sysfile-info.c:120
+#: src/sysfile-info.c:122
msgid "Not weighted."
msgstr ""
-#: src/sysfile-info.c:122
+#: src/sysfile-info.c:124
msgid "Mode:"
msgstr ""
-#: src/sysfile-info.c:124
+#: src/sysfile-info.c:126
#, c-format
msgid "Compression %s."
msgstr ""
-#: src/sysfile-info.c:124
+#: src/sysfile-info.c:126
msgid "on"
msgstr ""
-#: src/sysfile-info.c:124
+#: src/sysfile-info.c:126
msgid "off"
msgstr ""
-#: src/sysfile-info.c:133 src/sysfile-info.c:370
+#: src/sysfile-info.c:135 src/sysfile-info.c:372
msgid "Description"
msgstr ""
-#: src/sysfile-info.c:134 src/sysfile-info.c:368
+#: src/sysfile-info.c:136 src/sysfile-info.c:370
msgid "Position"
msgstr ""
-#: src/sysfile-info.c:191
+#: src/sysfile-info.c:193
msgid "The active file does not have a file label."
msgstr ""
-#: src/sysfile-info.c:194
+#: src/sysfile-info.c:196
msgid "File label:"
msgstr ""
-#: src/sysfile-info.c:256
+#: src/sysfile-info.c:258
msgid "No variables to display."
msgstr ""
-#: src/sysfile-info.c:275
+#: src/sysfile-info.c:277
msgid "Macros not supported."
msgstr ""
-#: src/sysfile-info.c:285
+#: src/sysfile-info.c:287
msgid "The active file dictionary does not contain any documents."
msgstr ""
-#: src/sysfile-info.c:294
+#: src/sysfile-info.c:296
msgid "Documents in the active file:"
msgstr ""
-#: src/sysfile-info.c:372 src/sysfile-info.c:530 src/vfm.c:876
+#: src/sysfile-info.c:374 src/sysfile-info.c:532 src/vfm.c:877
msgid "Label"
msgstr ""
-#: src/sysfile-info.c:444
+#: src/sysfile-info.c:446
#, c-format
msgid "Format: %s"
msgstr ""
-#: src/sysfile-info.c:451
+#: src/sysfile-info.c:453
#, c-format
msgid "Print Format: %s"
msgstr ""
-#: src/sysfile-info.c:454
+#: src/sysfile-info.c:456
#, c-format
msgid "Write Format: %s"
msgstr ""
-#: src/sysfile-info.c:462
+#: src/sysfile-info.c:464
msgid "Missing Values: "
msgstr ""
-#: src/sysfile-info.c:529 src/vfm.c:875 src/crosstabs.q:1068
-#: src/crosstabs.q:1095 src/crosstabs.q:1115 src/crosstabs.q:1137
-#: src/examine.q:1125 src/frequencies.q:1056 src/frequencies.q:1174
+#: src/sysfile-info.c:531 src/vfm.c:876 src/crosstabs.q:1099
+#: src/crosstabs.q:1126 src/crosstabs.q:1146 src/crosstabs.q:1168
+#: src/examine.q:1179 src/frequencies.q:1083 src/frequencies.q:1204
msgid "Value"
msgstr ""
-#: src/sysfile-info.c:586
+#: src/sysfile-info.c:588
msgid "No vectors defined."
msgstr ""
-#: src/sysfile-info.c:601
+#: src/sysfile-info.c:603
msgid "Vector"
msgstr ""
"bad box: (%d+%d=%d,%d+%d=%d)-(%d+%d=%d,%d+%d=%d) in table size (%d,%d)\n"
msgstr ""
-#: src/temporary.c:45
+#: src/temporary.c:46
msgid "This command is not valid inside DO IF or LOOP."
msgstr ""
-#: src/temporary.c:52
+#: src/temporary.c:53
msgid ""
"This command may only appear once between procedures and procedure-like "
"commands."
msgstr ""
-#: src/title.c:55
+#: src/title.c:56
#, c-format
msgid "%s before: %s\n"
msgstr ""
-#: src/title.c:55
+#: src/title.c:56
msgid "<none>"
msgstr ""
-#: src/title.c:67
+#: src/title.c:68
#, c-format
msgid "%s: `.' expected after string."
msgstr ""
-#: src/title.c:83
+#: src/title.c:84
#, c-format
msgid "%s after: %s\n"
msgstr ""
-#: src/title.c:139
+#: src/title.c:140
#, c-format
msgid "Document entered %s %02d:%02d:%02d by %s (%s):"
msgstr ""
msgid "Truncating variable label to 255 characters."
msgstr ""
-#: src/vars-prs.c:48
+#: src/vars-prs.c:49
#, c-format
msgid "%s is not a variable name."
msgstr ""
-#: src/vars-prs.c:100
+#: src/vars-prs.c:101
msgid "ordinary"
msgstr ""
-#: src/vars-prs.c:102
+#: src/vars-prs.c:103
msgid "system"
msgstr ""
-#: src/vars-prs.c:104
+#: src/vars-prs.c:105
msgid "scratch"
msgstr ""
-#: src/vars-prs.c:209
+#: src/vars-prs.c:210
#, c-format
msgid "%s TO %s is not valid syntax since %s precedes %s in the dictionary."
msgstr ""
-#: src/vars-prs.c:219
+#: src/vars-prs.c:220
#, c-format
msgid ""
"When using the TO keyword to specify several variables, both variables must "
"system variables. %s is a %s variable, whereas %s is %s."
msgstr ""
-#: src/vars-prs.c:237
+#: src/vars-prs.c:238
#, c-format
msgid "Scratch variables (such as %s) are not allowed here."
msgstr ""
-#: src/vars-prs.c:260
+#: src/vars-prs.c:261
#, c-format
msgid ""
"%s is not a numeric variable. It will not be included in the variable list."
msgstr ""
-#: src/vars-prs.c:263
+#: src/vars-prs.c:264
#, c-format
msgid ""
"%s is not a string variable. It will not be included in the variable list."
msgstr ""
-#: src/vars-prs.c:267
+#: src/vars-prs.c:268
#, c-format
msgid ""
"%s and %s are not the same type. All variables in this variable list must "
"be of the same type. %s will be omitted from list."
msgstr ""
-#: src/vars-prs.c:272
+#: src/vars-prs.c:273
#, c-format
msgid "Variable %s appears twice in variable list."
msgstr ""
-#: src/vars-prs.c:352
+#: src/vars-prs.c:353
msgid "incorrect use of TO convention"
msgstr ""
-#: src/vars-prs.c:399
+#: src/vars-prs.c:400
msgid "Scratch variables not allowed here."
msgstr ""
-#: src/vars-prs.c:421
+#: src/vars-prs.c:422
msgid "Prefixes don't match in use of TO convention."
msgstr ""
-#: src/vars-prs.c:426
+#: src/vars-prs.c:427
msgid "Bad bounds in use of TO convention."
msgstr ""
-#: src/vector.c:66
+#: src/vector.c:67
#, c-format
msgid "Vector name %s is given twice."
msgstr ""
-#: src/vector.c:72
+#: src/vector.c:73
#, c-format
msgid "There is already a vector with name %s."
msgstr ""
-#: src/vector.c:93
+#: src/vector.c:94
msgid ""
"A slash must be used to separate each vector specification when using the "
"long form. Commands such as VECTOR A,B=Q1 TO Q20 are not supported."
msgstr ""
-#: src/vector.c:127
+#: src/vector.c:128
msgid "Vectors must have at least one element."
msgstr ""
-#: src/vector.c:141
+#: src/vector.c:142
#, c-format
msgid "%s%d is too long for a variable name."
msgstr ""
-#: src/vector.c:179
+#: src/vector.c:180
msgid ""
"The syntax for this command does not match the expected syntax for either "
"the long form or the short form of VECTOR."
msgstr ""
-#: src/weight.c:52
+#: src/weight.c:53
msgid "The weighting variable must be numeric."
msgstr ""
-#: src/weight.c:57
+#: src/weight.c:58
msgid "The weighting variable may not be scratch."
msgstr ""
-#: src/crosstabs.q:241
+#: src/crosstabs.q:261
msgid ""
"Missing mode REPORT not allowed in general mode. Assuming MISSING=TABLE."
msgstr ""
-#: src/crosstabs.q:251
+#: src/crosstabs.q:271
msgid "Write mode ALL not allowed in general mode. Assuming WRITE=CELLS."
msgstr ""
-#: src/crosstabs.q:312
+#: src/crosstabs.q:332
msgid "expecting BY"
msgstr ""
-#: src/crosstabs.q:379
+#: src/crosstabs.q:399
msgid "VARIABLES must be specified before TABLES."
msgstr ""
-#: src/crosstabs.q:416
+#: src/crosstabs.q:436
#, c-format
msgid "Maximum value (%ld) less than minimum value (%ld)."
msgstr ""
-#: src/crosstabs.q:769
+#: src/crosstabs.q:800
msgid "Summary."
msgstr ""
-#: src/crosstabs.q:771 src/examine.q:784
+#: src/crosstabs.q:802 src/examine.q:837
msgid "Cases"
msgstr ""
-#: src/crosstabs.q:772 src/examine.q:722 src/frequencies.q:1054
-#: src/frequencies.q:1421
+#: src/crosstabs.q:803 src/examine.q:775 src/frequencies.q:1081
+#: src/frequencies.q:1454
msgid "Valid"
msgstr ""
-#: src/crosstabs.q:773 src/examine.q:723 src/frequencies.q:1121
-#: src/frequencies.q:1422
+#: src/crosstabs.q:804 src/examine.q:776 src/frequencies.q:1149
+#: src/frequencies.q:1455
msgid "Missing"
msgstr ""
-#: src/crosstabs.q:774 src/crosstabs.q:977 src/crosstabs.q:1690
-#: src/examine.q:724 src/frequencies.q:1130 src/oneway.q:306 src/oneway.q:483
+#: src/crosstabs.q:805 src/crosstabs.q:1008 src/crosstabs.q:1722
+#: src/examine.q:777 src/frequencies.q:1158 src/oneway.q:307 src/oneway.q:486
msgid "Total"
msgstr ""
-#: src/crosstabs.q:784 src/examine.q:805 src/frequencies.q:1420
-#: src/oneway.q:393 src/t-test.q:680 src/t-test.q:703 src/t-test.q:828
+#: src/crosstabs.q:815 src/examine.q:858 src/frequencies.q:1453
+#: src/oneway.q:395 src/t-test.q:682 src/t-test.q:705 src/t-test.q:830
#: src/t-test.q:1365
msgid "N"
msgstr ""
-#: src/crosstabs.q:785 src/examine.q:807 src/frequencies.q:1058
-#: src/frequencies.q:1059 src/frequencies.q:1060
+#: src/crosstabs.q:816 src/examine.q:860 src/frequencies.q:1085
+#: src/frequencies.q:1086 src/frequencies.q:1087
msgid "Percent"
msgstr ""
-#: src/crosstabs.q:1027
+#: src/crosstabs.q:1058
msgid "count"
msgstr ""
-#: src/crosstabs.q:1028
+#: src/crosstabs.q:1059
msgid "row %"
msgstr ""
-#: src/crosstabs.q:1029
+#: src/crosstabs.q:1060
msgid "column %"
msgstr ""
-#: src/crosstabs.q:1030
+#: src/crosstabs.q:1061
msgid "total %"
msgstr ""
-#: src/crosstabs.q:1031
+#: src/crosstabs.q:1062
msgid "expected"
msgstr ""
-#: src/crosstabs.q:1032
+#: src/crosstabs.q:1063
msgid "residual"
msgstr ""
-#: src/crosstabs.q:1033
+#: src/crosstabs.q:1064
msgid "std. resid."
msgstr ""
-#: src/crosstabs.q:1034
+#: src/crosstabs.q:1065
msgid "adj. resid."
msgstr ""
-#: src/crosstabs.q:1067 src/crosstabs.q:1094 src/crosstabs.q:1114
-#: src/crosstabs.q:1135 src/examine.q:448
+#: src/crosstabs.q:1098 src/crosstabs.q:1125 src/crosstabs.q:1145
+#: src/crosstabs.q:1166 src/examine.q:495
msgid "Statistic"
msgstr ""
-#: src/crosstabs.q:1069 src/oneway.q:276 src/oneway.q:711 src/t-test.q:979
-#: src/t-test.q:1171 src/t-test.q:1263
+#: src/crosstabs.q:1100 src/oneway.q:278 src/oneway.q:707 src/t-test.q:980
+#: src/t-test.q:1172 src/t-test.q:1264
msgid "df"
msgstr ""
-#: src/crosstabs.q:1071
+#: src/crosstabs.q:1102
msgid "Asymp. Sig. (2-sided)"
msgstr ""
-#: src/crosstabs.q:1073
+#: src/crosstabs.q:1104
msgid "Exact. Sig. (2-sided)"
msgstr ""
-#: src/crosstabs.q:1075
+#: src/crosstabs.q:1106
msgid "Exact. Sig. (1-sided)"
msgstr ""
-#: src/crosstabs.q:1093 src/crosstabs.q:1134
+#: src/crosstabs.q:1124 src/crosstabs.q:1165
msgid "Category"
msgstr ""
-#: src/crosstabs.q:1096 src/crosstabs.q:1138
+#: src/crosstabs.q:1127 src/crosstabs.q:1169
msgid "Asymp. Std. Error"
msgstr ""
-#: src/crosstabs.q:1097 src/crosstabs.q:1139
+#: src/crosstabs.q:1128 src/crosstabs.q:1170
msgid "Approx. T"
msgstr ""
-#: src/crosstabs.q:1098 src/crosstabs.q:1140
+#: src/crosstabs.q:1129 src/crosstabs.q:1171
msgid "Approx. Sig."
msgstr ""
-#: src/crosstabs.q:1113
+#: src/crosstabs.q:1144
#, c-format
msgid " 95%% Confidence Interval"
msgstr ""
-#: src/crosstabs.q:1116 src/t-test.q:983 src/t-test.q:1168 src/t-test.q:1266
+#: src/crosstabs.q:1147 src/t-test.q:984 src/t-test.q:1169 src/t-test.q:1267
msgid "Lower"
msgstr ""
-#: src/crosstabs.q:1117 src/t-test.q:984 src/t-test.q:1169 src/t-test.q:1267
+#: src/crosstabs.q:1148 src/t-test.q:985 src/t-test.q:1170 src/t-test.q:1268
msgid "Upper"
msgstr ""
-#: src/crosstabs.q:1136
+#: src/crosstabs.q:1167
msgid "Type"
msgstr ""
-#: src/crosstabs.q:1884
+#: src/crosstabs.q:1916
msgid "Pearson Chi-Square"
msgstr ""
-#: src/crosstabs.q:1885
+#: src/crosstabs.q:1917
msgid "Likelihood Ratio"
msgstr ""
-#: src/crosstabs.q:1886
+#: src/crosstabs.q:1918
msgid "Fisher's Exact Test"
msgstr ""
-#: src/crosstabs.q:1887
+#: src/crosstabs.q:1919
msgid "Continuity Correction"
msgstr ""
-#: src/crosstabs.q:1888
+#: src/crosstabs.q:1920
msgid "Linear-by-Linear Association"
msgstr ""
-#: src/crosstabs.q:1925 src/crosstabs.q:1995 src/crosstabs.q:2054
+#: src/crosstabs.q:1957 src/crosstabs.q:2027 src/crosstabs.q:2086
msgid "N of Valid Cases"
msgstr ""
-#: src/crosstabs.q:1941 src/crosstabs.q:2070
+#: src/crosstabs.q:1973 src/crosstabs.q:2102
msgid "Nominal by Nominal"
msgstr ""
-#: src/crosstabs.q:1942 src/crosstabs.q:2071
+#: src/crosstabs.q:1974 src/crosstabs.q:2103
msgid "Ordinal by Ordinal"
msgstr ""
-#: src/crosstabs.q:1943
+#: src/crosstabs.q:1975
msgid "Interval by Interval"
msgstr ""
-#: src/crosstabs.q:1944
+#: src/crosstabs.q:1976
msgid "Measure of Agreement"
msgstr ""
-#: src/crosstabs.q:1949
+#: src/crosstabs.q:1981
msgid "Phi"
msgstr ""
-#: src/crosstabs.q:1950
+#: src/crosstabs.q:1982
msgid "Cramer's V"
msgstr ""
-#: src/crosstabs.q:1951
+#: src/crosstabs.q:1983
msgid "Contingency Coefficient"
msgstr ""
-#: src/crosstabs.q:1952
+#: src/crosstabs.q:1984
msgid "Kendall's tau-b"
msgstr ""
-#: src/crosstabs.q:1953
+#: src/crosstabs.q:1985
msgid "Kendall's tau-c"
msgstr ""
-#: src/crosstabs.q:1954
+#: src/crosstabs.q:1986
msgid "Gamma"
msgstr ""
-#: src/crosstabs.q:1955
+#: src/crosstabs.q:1987
msgid "Spearman Correlation"
msgstr ""
-#: src/crosstabs.q:1956
+#: src/crosstabs.q:1988
msgid "Pearson's R"
msgstr ""
-#: src/crosstabs.q:1957
+#: src/crosstabs.q:1989
msgid "Kappa"
msgstr ""
-#: src/crosstabs.q:2027
+#: src/crosstabs.q:2059
#, c-format
msgid "Odds Ratio for %s (%g / %g)"
msgstr ""
-#: src/crosstabs.q:2030
+#: src/crosstabs.q:2062
#, c-format
msgid "Odds Ratio for %s (%.*s / %.*s)"
msgstr ""
-#: src/crosstabs.q:2038
+#: src/crosstabs.q:2070
#, c-format
msgid "For cohort %s = %g"
msgstr ""
-#: src/crosstabs.q:2041
+#: src/crosstabs.q:2073
#, c-format
msgid "For cohort %s = %.*s"
msgstr ""
-#: src/crosstabs.q:2072
+#: src/crosstabs.q:2104
msgid "Nominal by Interval"
msgstr ""
-#: src/crosstabs.q:2077
+#: src/crosstabs.q:2109
msgid "Lambda"
msgstr ""
-#: src/crosstabs.q:2078
+#: src/crosstabs.q:2110
msgid "Goodman and Kruskal tau"
msgstr ""
-#: src/crosstabs.q:2079
+#: src/crosstabs.q:2111
msgid "Uncertainty Coefficient"
msgstr ""
-#: src/crosstabs.q:2080
+#: src/crosstabs.q:2112
msgid "Somers' d"
msgstr ""
-#: src/crosstabs.q:2081
+#: src/crosstabs.q:2113
msgid "Eta"
msgstr ""
-#: src/crosstabs.q:2086
+#: src/crosstabs.q:2118
msgid "Symmetric"
msgstr ""
-#: src/crosstabs.q:2087 src/crosstabs.q:2088
+#: src/crosstabs.q:2119 src/crosstabs.q:2120
#, c-format
msgid "%s Dependent"
msgstr ""
-#: src/examine.q:217 src/examine.q:229
+#: src/examine.q:264 src/examine.q:276
#, c-format
msgid "%s and %s are mutually exclusive"
msgstr ""
-#: src/examine.q:449 src/oneway.q:396 src/oneway.q:709
+#: src/examine.q:496 src/oneway.q:398 src/oneway.q:705
msgid "Std. Error"
msgstr ""
-#: src/examine.q:563 src/oneway.q:410
+#: src/examine.q:610 src/oneway.q:412
msgid "Descriptives"
msgstr ""
-#: src/examine.q:602 src/oneway.q:401
+#: src/examine.q:649 src/oneway.q:403
#, c-format
msgid "%g%% Confidence Interval for Mean"
msgstr ""
-#: src/examine.q:608 src/oneway.q:403
+#: src/examine.q:655 src/oneway.q:405
msgid "Lower Bound"
msgstr ""
-#: src/examine.q:619 src/oneway.q:404
+#: src/examine.q:666 src/oneway.q:406
msgid "Upper Bound"
msgstr ""
-#: src/examine.q:631
+#: src/examine.q:678
msgid "5% Trimmed Mean"
msgstr ""
-#: src/examine.q:636 src/frequencies.q:102
+#: src/examine.q:689 src/frequencies.q:112
msgid "Median"
msgstr ""
-#: src/examine.q:653 src/oneway.q:395 src/t-test.q:682 src/t-test.q:705
-#: src/t-test.q:829 src/t-test.q:1166
+#: src/examine.q:706 src/oneway.q:397 src/t-test.q:684 src/t-test.q:707
+#: src/t-test.q:831 src/t-test.q:1167
msgid "Std. Deviation"
msgstr ""
-#: src/examine.q:701
+#: src/examine.q:754
msgid "Interquartile Range"
msgstr ""
-#: src/examine.q:778
+#: src/examine.q:831
msgid "Case Processing Summary"
msgstr ""
-#: src/examine.q:1103
+#: src/examine.q:1157
msgid "Extreme Values"
msgstr ""
-#: src/examine.q:1126
+#: src/examine.q:1180
msgid "Case Number"
msgstr ""
-#: src/examine.q:1252
+#: src/examine.q:1306
msgid "Highest"
msgstr ""
-#: src/examine.q:1257
+#: src/examine.q:1311
msgid "Lowest"
msgstr ""
-#: src/file-handle.q:125
+#: src/examine.q:1350
+#, c-format
+msgid "Normal Q-Q Plot of %s"
+msgstr ""
+
+#: src/examine.q:1351 src/examine.q:1357
+msgid "Observed Value"
+msgstr ""
+
+#: src/examine.q:1352
+msgid "Expected Normal"
+msgstr ""
+
+#: src/examine.q:1355
+#, c-format
+msgid "Detrended Normal Q-Q Plot of %s"
+msgstr ""
+
+#: src/examine.q:1358
+msgid "Dev from Normal"
+msgstr ""
+
+#: src/file-handle.q:122
#, c-format
msgid ""
"File handle %s already refers to file %s. File handle cannot be redefined "
"within a session."
msgstr ""
-#: src/file-handle.q:147
+#: src/file-handle.q:144
msgid "The FILE HANDLE required subcommand NAME is not present."
msgstr ""
-#: src/file-handle.q:166
+#: src/file-handle.q:163
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:173
+#: src/file-handle.q:170
#, c-format
msgid ""
"Record length (%ld) must be at least one byte. 1-character records will be "
"assumed."
msgstr ""
-#: src/file-handle.q:247
-msgid "<Inline File>"
+#: src/file-handle.q:260
+#, c-format
+msgid "Can't open %s as a %s because it is already open as a %s"
+msgstr ""
+
+#: src/file-handle.q:264
+#, c-format
+msgid "Can't open %s as a %s for %s because it is already open for %s"
+msgstr ""
+
+#: src/file-handle.q:269
+#, c-format
+msgid "Can't re-open %s as a %s for %s"
msgstr ""
-#: src/file-handle.q:262
+#: src/file-handle.q:317
msgid "expecting a file name or handle name"
msgstr ""
-#: src/frequencies.q:101
+#: src/frequencies.q:111
msgid "S.E. Mean"
msgstr ""
-#: src/frequencies.q:103
+#: src/frequencies.q:113
msgid "Mode"
msgstr ""
-#: src/frequencies.q:107
+#: src/frequencies.q:117
msgid "S.E. Kurt"
msgstr ""
-#: src/frequencies.q:109
+#: src/frequencies.q:119
msgid "S.E. Skew"
msgstr ""
-#: src/frequencies.q:315
+#: src/frequencies.q:340
msgid ""
"At most one of BARCHART, HISTOGRAM, or HBAR should be given. HBAR will be "
"assumed. Argument values will be given precedence increasing along the "
"order given."
msgstr ""
-#: src/frequencies.q:398
+#: src/frequencies.q:423
#, c-format
msgid ""
"MAX must be greater than or equal to MIN, if both are specified. However, "
"MIN was specified as %g and MAX as %g. MIN and MAX will be ignored."
msgstr ""
-#: src/frequencies.q:722
+#: src/frequencies.q:747
msgid ""
"Upper limit of integer mode value range must be greater than lower limit."
msgstr ""
-#: src/frequencies.q:734
+#: src/frequencies.q:760
#, c-format
msgid "Variable %s specified multiple times on VARIABLES subcommand."
msgstr ""
-#: src/frequencies.q:747
+#: src/frequencies.q:766
#, c-format
msgid "Integer mode specified, but %s is not a numeric variable."
msgstr ""
-#: src/frequencies.q:809
+#: src/frequencies.q:832
msgid "`)' expected after GROUPED interval list."
msgstr ""
-#: src/frequencies.q:822
+#: src/frequencies.q:844
#, c-format
msgid "Variables %s specified on GROUPED but not on VARIABLES."
msgstr ""
-#: src/frequencies.q:825
+#: src/frequencies.q:851
#, c-format
msgid "Variables %s specified multiple times on GROUPED subcommand."
msgstr ""
-#: src/frequencies.q:1055 src/frequencies.q:1146 src/frequencies.q:1147
-#: src/frequencies.q:1177
+#: src/frequencies.q:1082 src/frequencies.q:1174 src/frequencies.q:1175
+#: src/frequencies.q:1207
msgid "Cum"
msgstr ""
-#: src/frequencies.q:1057
+#: src/frequencies.q:1084
msgid "Frequency"
msgstr ""
-#: src/frequencies.q:1076
+#: src/frequencies.q:1104
msgid "Value Label"
msgstr ""
-#: src/frequencies.q:1175
+#: src/frequencies.q:1205
msgid "Freq"
msgstr ""
-#: src/frequencies.q:1176 src/frequencies.q:1178
+#: src/frequencies.q:1206 src/frequencies.q:1208
msgid "Pct"
msgstr ""
-#: src/frequencies.q:1394
+#: src/frequencies.q:1427
#, c-format
msgid "No valid data for variable %s; statistics not displayed."
msgstr ""
-#: src/frequencies.q:1433
+#: src/frequencies.q:1465
msgid "Percentiles"
msgstr ""
-#: src/list.q:148
+#: src/list.q:150
#, c-format
msgid ""
"The first case (%ld) specified precedes the last case (%ld) specified. The "
"values will be swapped."
msgstr ""
-#: src/list.q:156
+#: src/list.q:158
#, c-format
msgid ""
"The first case (%ld) to list is less than 1. The value is being reset to 1."
msgstr ""
-#: src/list.q:162
+#: src/list.q:164
#, c-format
msgid ""
"The last case (%ld) to list is less than 1. The value is being reset to 1."
msgstr ""
-#: src/list.q:168
+#: src/list.q:170
#, c-format
msgid "The step value %ld is less than 1. The value is being reset to 1."
msgstr ""
-#: src/list.q:195
+#: src/list.q:197
msgid "`/FORMAT WEIGHT' specified, but weighting is not on."
msgstr ""
-#: src/list.q:436
+#: src/list.q:438
msgid "Line"
msgstr ""
-#: src/means.q:101
+#: src/means.q:100
msgid "Missing required subcommand TABLES."
msgstr ""
-#: src/means.q:135
-msgid "TABLES or CROSSBREAK subcommand may not appear more than once."
-msgstr ""
-
-#: src/means.q:172
-#, c-format
-msgid ""
-"Variable %s specified on TABLES or CROSSBREAK, but not specified on "
-"VARIABLES."
-msgstr ""
-
-#: src/means.q:186
-#, c-format
-msgid "LOWEST and HIGHEST may not be used for independent variables (%s)."
-msgstr ""
-
-#: src/means.q:194
-#, c-format
-msgid ""
-"Independent variables (%s) may not have noninteger endpoints in their ranges."
-msgstr ""
-
-#: src/means.q:227
-msgid "VARIABLES must precede TABLES."
-msgstr ""
-
-#: src/means.q:284
-#, c-format
-msgid "Upper value (%g) is less than lower value (%g) on VARIABLES subcommand."
+#: src/means.q:134
+msgid "TABLES subcommand may not appear more than once."
msgstr ""
-#: src/oneway.q:166
+#: src/oneway.q:168
msgid "Number of contrast coefficients must equal the number of groups"
msgstr ""
-#: src/oneway.q:175
+#: src/oneway.q:177
#, c-format
msgid "Coefficients for contrast %d do not total zero"
msgstr ""
-#: src/oneway.q:240 src/t-test.q:364 src/t-test.q:449
+#: src/oneway.q:242 src/t-test.q:366 src/t-test.q:451
#, c-format
msgid "`%s' is not a variable name"
msgstr ""
-#: src/oneway.q:275
+#: src/oneway.q:277
msgid "Sum of Squares"
msgstr ""
-#: src/oneway.q:277
+#: src/oneway.q:279
msgid "Mean Square"
msgstr ""
-#: src/oneway.q:278 src/t-test.q:976
+#: src/oneway.q:280 src/t-test.q:977
msgid "F"
msgstr ""
-#: src/oneway.q:279 src/oneway.q:549
+#: src/oneway.q:281 src/oneway.q:552
msgid "Significance"
msgstr ""
-#: src/oneway.q:304
+#: src/oneway.q:305
msgid "Between Groups"
msgstr ""
-#: src/oneway.q:305
+#: src/oneway.q:306
msgid "Within Groups"
msgstr ""
-#: src/oneway.q:351
+#: src/oneway.q:353
msgid "ANOVA"
msgstr ""
-#: src/oneway.q:546
+#: src/oneway.q:549
msgid "Levene Statistic"
msgstr ""
-#: src/oneway.q:547
+#: src/oneway.q:550
msgid "df1"
msgstr ""
-#: src/oneway.q:548
+#: src/oneway.q:551
msgid "df2"
msgstr ""
-#: src/oneway.q:552
+#: src/oneway.q:555
msgid "Test of Homogeneity of Variances"
msgstr ""
-#: src/oneway.q:628
+#: src/oneway.q:631
msgid "Contrast Coefficients"
msgstr ""
-#: src/oneway.q:630 src/oneway.q:707
+#: src/oneway.q:633 src/oneway.q:703
msgid "Contrast"
msgstr ""
-#: src/oneway.q:705
+#: src/oneway.q:701
msgid "Contrast Tests"
msgstr ""
-#: src/oneway.q:708
+#: src/oneway.q:704
msgid "Value of Contrast"
msgstr ""
-#: src/oneway.q:710 src/t-test.q:978 src/t-test.q:1170 src/t-test.q:1262
+#: src/oneway.q:706 src/t-test.q:979 src/t-test.q:1171 src/t-test.q:1263
msgid "t"
msgstr ""
-#: src/oneway.q:712 src/t-test.q:980 src/t-test.q:1172 src/t-test.q:1264
+#: src/oneway.q:708 src/t-test.q:981 src/t-test.q:1173 src/t-test.q:1265
msgid "Sig. (2-tailed)"
msgstr ""
-#: src/oneway.q:760
+#: src/oneway.q:754
msgid "Assume equal variances"
msgstr ""
-#: src/oneway.q:764
+#: src/oneway.q:758
msgid "Does not assume equal"
msgstr ""
msgid "data> "
msgstr ""
-#: src/t-test.q:266
+#: src/t-test.q:268
msgid "TESTVAL, GROUPS and PAIRS subcommands are mutually exclusive."
msgstr ""
-#: src/t-test.q:283
+#: src/t-test.q:285
msgid "VARIABLES subcommand is not appropriate with PAIRS"
msgstr ""
-#: src/t-test.q:320
+#: src/t-test.q:322
msgid "One or more VARIABLES must be specified."
msgstr ""
-#: src/t-test.q:377
+#: src/t-test.q:379
#, c-format
msgid "Long string variable %s is not valid here."
msgstr ""
-#: src/t-test.q:397
+#: src/t-test.q:399
msgid ""
"When applying GROUPS to a string variable, at least one value must be "
"specified."
msgstr ""
-#: src/t-test.q:484
+#: src/t-test.q:486
#, c-format
msgid ""
"PAIRED was specified but the number of variables preceding WITH (%d) did not "
"match the number following (%d)."
msgstr ""
-#: src/t-test.q:501
+#: src/t-test.q:503
msgid "At least two variables must be specified on PAIRS."
msgstr ""
-#: src/t-test.q:678
+#: src/t-test.q:680
msgid "One-Sample Statistics"
msgstr ""
-#: src/t-test.q:683 src/t-test.q:706 src/t-test.q:830
+#: src/t-test.q:685 src/t-test.q:708 src/t-test.q:832
msgid "SE. Mean"
msgstr ""
-#: src/t-test.q:700
+#: src/t-test.q:702
msgid "Group Statistics"
msgstr ""
-#: src/t-test.q:824
+#: src/t-test.q:826
msgid "Paired Sample Statistics"
msgstr ""
-#: src/t-test.q:846 src/t-test.q:1191 src/t-test.q:1382
+#: src/t-test.q:848 src/t-test.q:1192 src/t-test.q:1382
#, c-format
msgid "Pair %d"
msgstr ""
-#: src/t-test.q:964
+#: src/t-test.q:965
msgid "Independent Samples Test"
msgstr ""
-#: src/t-test.q:972
+#: src/t-test.q:973
msgid "Levene's Test for Equality of Variances"
msgstr ""
-#: src/t-test.q:974
+#: src/t-test.q:975
msgid "t-test for Equality of Means"
msgstr ""
-#: src/t-test.q:977 src/t-test.q:1367
+#: src/t-test.q:978 src/t-test.q:1367
msgid "Sig."
msgstr ""
-#: src/t-test.q:981 src/t-test.q:1265
+#: src/t-test.q:982 src/t-test.q:1266
msgid "Mean Difference"
msgstr ""
-#: src/t-test.q:982
+#: src/t-test.q:983
msgid "Std. Error Difference"
msgstr ""
-#: src/t-test.q:987 src/t-test.q:1162 src/t-test.q:1257
+#: src/t-test.q:988 src/t-test.q:1163 src/t-test.q:1258
#, c-format
msgid "%g%% Confidence Interval of the Difference"
msgstr ""
-#: src/t-test.q:1041
+#: src/t-test.q:1043
msgid "Equal variances assumed"
msgstr ""
-#: src/t-test.q:1094
+#: src/t-test.q:1095
msgid "Equal variances not assumed"
msgstr ""
-#: src/t-test.q:1152
+#: src/t-test.q:1153
msgid "Paired Samples Test"
msgstr ""
-#: src/t-test.q:1155
+#: src/t-test.q:1156
msgid "Paired Differences"
msgstr ""
-#: src/t-test.q:1167
+#: src/t-test.q:1168
msgid "Std. Error Mean"
msgstr ""
-#: src/t-test.q:1246
+#: src/t-test.q:1247
msgid "One-Sample Test"
msgstr ""
-#: src/t-test.q:1251
+#: src/t-test.q:1252
#, c-format
msgid "Test Value = %f"
msgstr ""
Makefile.in
correlations.c
crosstabs.c
+examine.c
file-handle.c
frequencies.c
list.c
means.c
+oneway.c
pspp
q2c
set.c
+Mon Nov 15 01:33:32 2004 Ben Pfaff <blp@gnu.org>
+
+ * q2c.c: (dump_header) Don't try to emit #includes at very top of
+ output file because that will precede #include <config.h>, which
+ is bad.
+ (main) Add needed headers to /* (header) */ code.
+
+Mon Nov 15 01:21:36 2004 Ben Pfaff <blp@gnu.org>
+
+ Instead of making system or portable file readers responsible for
+ dropping and reordering variables, make them read full cases and
+ let the caller take care of any changes.
+
+ * get.c: New "case map" structure to handle this. Use for GET,
+ IMPORT, MATCH FILES. Essentially rewrite the whole file.
+
+ * pfm-read.c: (pfm_read_case) Read into provided case. Signature
+ changed appropriately.
+
+ * sfm-read.c: (sfm_read_case) Ditto.
+
+Mon Nov 15 00:47:45 2004 Ben Pfaff <blp@gnu.org>
+
+ Decided that case_serialize() and case_unserialize() were too
+ abstract. Also we need a couple more functions to avoid excessive
+ copying for data in/out fast paths.
+
+ * case.c: (case_serial_size) Removed.
+ (case_serialize) Rename case_to_values() and make its argument
+ explicitly an array of union values.
+ (case_unserialize) Rename case_from_values() and make its argument
+ explicitly an array of union values.
+ (case_data_all) New function.
+ (case_data_all_rw) New function.
+
+ * casefile.c: (struct casefile) Change buffer from array of
+ unsigned char to array of union value for better accuracy.
+ Redefine buffer_used and buffer_size in terms of values, not
+ bytes. Remove case_size because it is now redundant with
+ value_cnt. Fix up all references to these members.
+
+Mon Nov 15 00:45:46 2004 Ben Pfaff <blp@gnu.org>
+
+ * barchart.c: (struct subcat) Make `label' member const to silence
+ GCC warning with -Wwrite-strings.
+
+ * cartesian.c: (struct dataset) Ditto.
+
+ * case.c: Don't re-define NDEBUG if already defined.
+ Add lots of comments.
+
+ * str.c: Fix includes.
+
+ * crosstabs.q: Fix includes.
+
+ * examine.q: Fix includes. Fix GCC warning about unused
+ variables.
+
+ * frequencies.q: (stat macro) Removed and replaced where used by
+ its expansion.
+
+ * list.q: Fix includes.
+
+ * oneway.q: Fix includes.
+
+ * piechart.c: Fix includes. Only define M_PI if not already
+ defined.
+
+ * sfm-read.c: (bswap) New function.
+ (bswap_int32) Write in terms of bswap.
+ (bswap_flt64) Ditto.
+
+ * str.c: (ds_data) Add external definition here, needed because
+ str.h has only an `extern inline' version.
+
+ * value-labels.c: Fix includes.
+
+Mon Nov 15 00:40:55 2004 Ben Pfaff <blp@gnu.org>
+
+ Instead of providing a system or portable file writer with a raw
+ case in the format needed for output, provide it with a regular
+ case. The writer takes care of any needed translation.
+
+ * aggregate.c: Adopt new scheme for AGGREGATE.
+ (struct agr_proc) sfm_agr_case member removed.
+ (write_case_to_sfm) Removed because the new interface is easier to
+ use.
+
+ * get.c: Adopt new scheme for SAVE, XSAVE, EXPORT.
+
+ * pfm-write.c: Implement new scheme.
+
+ * sfm-write.c: Ditto.
+
+Mon Nov 15 00:32:24 2004 Ben Pfaff <blp@gnu.org>
+
+ Instead of treating `struct file_handle' as a class to subclass
+ into data files, system files, and portable files, instead use it
+ as a helper that coordinates access. Now it is opaque, too.
+
+ This means that most references to a struct file_handle are now
+ changed into references to one of struct dfm_reader, struct
+ dfm_writer, struct sfm_reader, struct sfm_writer, struct
+ pfm_reader, or struct pfm_writer, according to what's being read
+ or written.
+
+ Most related changes are only worth summarizing briefly.
+
+ * dictionary.c: (dict_clear) Destroy aux data in deleted
+ variables.
+ (dict_clear_aux) New function.
+ (dict_create_var) Initialize aux, aux_dtor.
+ (dict_delete_var) Destroy aux data in deleted variable.
+
+ * file-handle.h: (struct fh_ext_class) Removed.
+ (struct file_handle) Removed.
+ (fh_init_files) Removed.
+
+ * file-handle.q: Changed references to a handle's `private' member
+ to direct references.
+ (struct private_file_handle) Renamed file_handle.
+ Add next, open_cnt, type, open_mode, aux members.
+ (struct file_handle_list) Removed.
+ (extern var inline_file) Removed.
+ (static var file_handles) Changed from file_handle_list * to
+ file_handle *.
+ (create_file_handle) Initialize new members.
+ (fh_close_handle) Removed.
+ (mode_name) New function.
+ (fh_open) New function.
+ (fh_close) New function.
+ (fh_parse_file_handle) Renamed fh_parse().
+
+ * glob.c: (init_glob) Remove fh_init_files() call.
+
+ * aggregate.c: use sfm_writer.
+ (create_sysfile) Removed because the new interface is simpler.
+
+ * apply-dict.c: Use sfm_reader.
+
+ * data-list.c: Use dfm_reader.
+
+ * file-type.c: Use dfm_reader.
+
+ * get.c: Use sfm_reader, sfm_writer, pfm_reader, pfm_writer.
+
+ * inpt-pgm.c: Use dfm_reader.
+
+ * print.c: Use dfm_writer.
+
+ * sysfile-info: Use sfm_reader.
+
+ * dfm-read.c: Adopt new file handle infrastructure.
+
+ * dfm-write.c: Ditto.
+
+ * pfm-read.c: Ditto.
+
+ * pfm-write.c: Ditto.
+
+ * sfm-read.c: Ditto.
+
+ * sfm-write.c: Ditto.
+
+Mon Nov 15 00:31:44 2004 Ben Pfaff <blp@gnu.org>
+
+ Break dictionary functions into separate header file.
+
+ * dictionary.h: New file.
+
+ * var.h: Moved dict_*() functions to dictionary.h.
+
+Mon Nov 15 00:30:33 2004 Ben Pfaff <blp@gnu.org>
+
+ Get rid of procedure-specific union in struct variable, using
+ instead a void * pointer and a destructor function.
+
+ Most related changes are only worth brief summaries.
+
+ * crosstabs.q: Fix includes. Use new struct var_range in lieu of
+ old p.crs member in struct variable.
+
+ * frequencies.q: Fix includes. Use new struct var_freqs in lieu
+ of old p.frq member in struct variable.
+
+ * histogram.c: (draw_histogram) Takes new freq_tab arg because
+ it's no longer possible to grab this from var->p.frq.
+
+ * piechart.c: (draw_piechart) Ditto.
+
+ * group.c: (group_proc_get) New function.
+
+ * levene.c: Use group_proc_get() in lieu of old p.grp_data member
+ in struct variable.
+
+ * oneway.q: Ditto.
+
+ * t-test.q: Ditto.
+
+ * main.c: (execute_command) Clear aux data in default_dict after
+ each command. (It's debatable whether this should be done.)
+
+ * matrix-data.c: Use new struct mxd_var in lieu of old p.mxd
+ member in struct variable.
+
+ * means.q: Get rid of integer mode, which is not included in
+ recent SPSS and was the only code that wanted per-variable private
+ data.
+
+ * var.h: (struct crosstab_proc) Removed.
+ (struct frequencies_proc) Removed.
+ (struct list_proc) Removed.
+ (struct get_proc) Removed.
+ (struct means_proc) Removed.
+ (struct matrix_data_proc) Removed.
+ (struct match_files_proc) Removed.
+ (lots of enums) Removed.
+ (struct variable) Removed members `p', `get'. Add member
+ `aux_dtor'.
+
+ * vars-atr.c: (var_attach_aux) New function.
+ (var_detach_aux) New function.
+ (var_clear_aux) New function.
+ (var_dtor_free) New function.
+ (discard_variables) Use NULL instead of inline_file.
+
Fri Nov 12 10:07:11 WST 2004 John Darrington <john@darrington.wattle.id.au>
* value-labs.c Fixed the implmentation of value_to_string, so
casefile.c casefile.h cmdline.c cmdline.h command.c command.def \
command.h compute.c copyleft.c copyleft.h count.c data-in.c data-in.h \
data-list.c data-list.h data-out.c date.c debug-print.h descript.c \
-devind.c devind.h dfm.c dfm.h dictionary.c do-if.c do-ifP.h error.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 error.c \
error.h expr-evl.c expr-opt.c expr-prs.c expr.h exprP.h expr.def \
factor_stats.c factor_stats.h file-handle.h \
file-type.c filename.c filename.h flip.c font.h format.c format.def \
hash.c hash.h html.c htmlP.h include.c inpt-pgm.c lexer.c \
lexer.h levene.c levene.h log.h loop.c magic.c magic.h main.c main.h \
matrix-data.c mis-val.c misc.c misc.h modify-vars.c \
-moments.c moments.h numeric.c output.c output.h pfm-read.c pfm-write.c \
-pfm.h pool.c pool.h postscript.c print.c random.c random.h recode.c \
+moments.c moments.h numeric.c output.c output.h pfm-read.c pfm-read.h \
+pfm-write.c pfm-write.h \
+pool.c pool.h postscript.c print.c random.c random.h recode.c \
rename-vars.c repeat.c repeat.h sample.c sel-if.c settings.h \
-sfm-read.c sfm-write.c sfm.h sfmP.h som.c som.h sort.c sort.h \
+sfm-read.c sfm-read.h sfm-write.c sfm-write.h sfmP.h som.c som.h \
+sort.c sort.h \
split-file.c str.c str.h subclist.c subclist.h \
sysfile-info.c tab.c tab.h temporary.c stat.h \
title.c val.h val-labs.c value-labels.c value-labels.h \
#include "case.h"
#include "casefile.h"
#include "command.h"
+#include "dictionary.h"
#include "error.h"
#include "file-handle.h"
#include "lexer.h"
#include "moments.h"
#include "pool.h"
#include "settings.h"
-#include "sfm.h"
+#include "sfm-write.h"
#include "sort.h"
#include "str.h"
#include "var.h"
struct agr_proc
{
/* We have either an output file or a sink. */
- struct file_handle *out_file; /* Output file, or null if none. */
+ struct sfm_writer *writer; /* Output file, or null if none. */
struct case_sink *sink; /* Sink, or null if none. */
/* Break variables. */
struct dictionary *dict; /* Aggregate dictionary. */
int case_cnt; /* Counts aggregated cases. */
struct ccase agr_case; /* Aggregate case for output. */
- flt64 *sfm_agr_case; /* Aggregate case in SFM format. */
};
static void initialize_aggregate_info (struct agr_proc *);
const struct ccase *input,
struct ccase *output);
static void dump_aggregate_info (struct agr_proc *agr, struct ccase *output);
-static int create_sysfile (struct agr_proc *);
/* Aggregating to the active file. */
static int agr_to_active_file (struct ccase *, void *aux);
/* Aggregating to a system file. */
-static void write_case_to_sfm (struct agr_proc *agr);
static int presorted_agr_to_sysfile (struct ccase *, void *aux);
\f
/* Parsing. */
cmd_aggregate (void)
{
struct agr_proc agr;
+ struct file_handle *out_file = NULL;
/* Have we seen these subcommands? */
unsigned seen = 0;
- agr.out_file = NULL;
+ agr.writer = NULL;
agr.sink = NULL;
agr.missing = ITEMWISE;
agr.sort = NULL;
if (seen & 1)
{
msg (SE, _("%s subcommand given multiple times."),"OUTFILE");
- goto lossage;
+ goto error;
}
seen |= 1;
lex_match ('=');
- if (lex_match ('*'))
- agr.out_file = NULL;
- else
+ if (!lex_match ('*'))
{
- agr.out_file = fh_parse_file_handle ();
- if (agr.out_file == NULL)
- goto lossage;
+ out_file = fh_parse ();
+ if (out_file == NULL)
+ goto error;
}
}
else if (lex_match_id ("MISSING"))
if (!lex_match_id ("COLUMNWISE"))
{
lex_error (_("while expecting COLUMNWISE"));
- goto lossage;
+ goto error;
}
agr.missing = COLUMNWISE;
}
if (seen & 8)
{
msg (SE, _("%s subcommand given multiple times."),"BREAK");
- goto lossage;
+ goto error;
}
seen |= 8;
agr.sort = sort_parse_criteria (default_dict,
&agr.break_vars, &agr.break_var_cnt);
if (agr.sort == NULL)
- goto lossage;
+ goto error;
for (i = 0; i < agr.break_var_cnt; i++)
{
/* Read in the aggregate functions. */
if (!parse_aggregate_functions (&agr))
- goto lossage;
+ goto error;
/* Delete documents. */
if (!(seen & 2))
initialize_aggregate_info (&agr);
/* Output to active file or external file? */
- if (agr.out_file == NULL)
+ if (out_file == NULL)
{
/* The active file will be replaced by the aggregated data,
so TEMPORARY is moot. */
}
else
{
- if (!create_sysfile (&agr))
- goto lossage;
-
+ agr.writer = sfm_open_writer (out_file, agr.dict, get_scompression ());
+ if (agr.writer == NULL)
+ goto error;
+
if (agr.sort != NULL && (seen & 4) == 0)
{
/* Sorting is needed. */
dst = sort_active_file_to_casefile (agr.sort);
if (dst == NULL)
- goto lossage;
+ goto error;
reader = casefile_get_destructive_reader (dst);
while (casereader_read_xfer (reader, &c))
{
if (aggregate_single_case (&agr, &c, &agr.agr_case))
- write_case_to_sfm (&agr);
+ sfm_write_case (agr.writer, &agr.agr_case);
case_destroy (&c);
}
casereader_destroy (reader);
if (agr.case_cnt > 0)
{
dump_aggregate_info (&agr, &agr.agr_case);
- write_case_to_sfm (&agr);
+ sfm_write_case (agr.writer, &agr.agr_case);
}
- fh_close_handle (agr.out_file);
}
agr_destroy (&agr);
return CMD_SUCCESS;
-lossage:
+error:
agr_destroy (&agr);
return CMD_FAILURE;
}
-/* Create a system file for use in aggregation to an external
- file. */
-static int
-create_sysfile (struct agr_proc *agr)
-{
- struct sfm_write_info w;
- w.h = agr->out_file;
- w.dict = agr->dict;
- w.compress = get_scompression();
- if (!sfm_write_dictionary (&w))
- return 0;
-
- agr->sfm_agr_case = xmalloc (sizeof *agr->sfm_agr_case * w.case_size);
-
- return 1;
-}
-
/* Parse all the aggregate functions. */
static int
parse_aggregate_functions (struct agr_proc *agr)
{
int n_dest_prev = n_dest;
- if (!parse_DATA_LIST_vars (&dest, &n_dest, PV_APPEND | PV_SINGLE | PV_NO_SCRATCH))
- goto lossage;
+ if (!parse_DATA_LIST_vars (&dest, &n_dest,
+ PV_APPEND | PV_SINGLE | PV_NO_SCRATCH))
+ goto error;
/* Assign empty labels. */
{
if (token != T_ID)
{
lex_error (_("expecting aggregation function"));
- goto lossage;
+ goto error;
}
include_missing = 0;
if (NULL == function->name)
{
msg (SE, _("Unknown aggregation function %s."), tokid);
- goto lossage;
+ goto error;
}
func_index = function - agr_func_tab;
lex_get ();
else
{
lex_error (_("expecting `('"));
- goto lossage;
+ goto error;
}
} else {
/* Parse list of source variables. */
pv_opts |= PV_SAME_TYPE;
if (!parse_variables (default_dict, &src, &n_src, pv_opts))
- goto lossage;
+ goto error;
}
/* Parse function arguments, for those functions that
type = NUMERIC;
} else {
msg (SE, _("Missing argument %d to %s."), i + 1, function->name);
- goto lossage;
+ goto error;
}
lex_get ();
msg (SE, _("Arguments to %s must be of same type as "
"source variables."),
function->name);
- goto lossage;
+ goto error;
}
}
if (!lex_match(')'))
{
lex_error (_("expecting `)'"));
- goto lossage;
+ goto error;
}
/* Now check that the number of source variables match the
msg (SE, _("Number of source variables (%d) does not match "
"number of target variables (%d)."),
n_src, n_dest);
- goto lossage;
+ goto error;
}
}
"variables."),
dest[i]);
free (dest[i]);
- goto lossage;
+ goto error;
}
free (dest[i]);
}
continue;
- lossage:
+ error:
for (i = 0; i < n_dest; i++)
{
free (dest[i]);
{
struct agr_var *iter, *next;
- if (agr->dict != NULL)
- dict_destroy (agr->dict);
+ sfm_close_writer (agr->writer);
if (agr->sort != NULL)
sort_destroy_criteria (agr->sort);
free (agr->break_vars);
+ free (agr->prev_break);
for (iter = agr->agr_vars; iter; iter = next)
{
next = iter->next;
moments1_destroy (iter->moments);
free (iter);
}
- free (agr->prev_break);
+ if (agr->dict != NULL)
+ dict_destroy (agr->dict);
case_destroy (&agr->agr_case);
}
\f
return 1;
}
-/* Writes AGR->agr_case to AGR->out_file. */
-static void
-write_case_to_sfm (struct agr_proc *agr)
-{
- flt64 *p;
- int i;
-
- p = agr->sfm_agr_case;
- for (i = 0; i < dict_get_var_cnt (agr->dict); i++)
- {
- struct variable *v = dict_get_var (agr->dict, i);
-
- if (v->type == NUMERIC)
- {
- double src = case_num (&agr->agr_case, v->fv);
- if (src == SYSMIS)
- *p++ = -FLT64_MAX;
- else
- *p++ = src;
- }
- else
- {
- memcpy (p, case_str (&agr->agr_case, v->fv), v->width);
- memset (&((char *) p)[v->width], ' ',
- REM_RND_UP (v->width, sizeof (flt64)));
- p += DIV_RND_UP (v->width, sizeof (flt64));
- }
- }
-
- sfm_write_case (agr->out_file, agr->sfm_agr_case, p - agr->sfm_agr_case);
-}
-
/* Aggregate the current case and output it if we passed a
breakpoint. */
static int
struct agr_proc *agr = agr_;
if (aggregate_single_case (agr, c, &agr->agr_case))
- write_case_to_sfm (agr);
+ sfm_write_case (agr->writer, &agr->agr_case);
return 1;
}
#include <config.h>
#include "alloc.h"
-#include "error.h"
#include <stdio.h>
#include <stdlib.h>
+#include "error.h"
#include "str.h"
\f
/* Public functions. */
#include <config.h>
#include <stdlib.h>
#include "command.h"
+#include "dictionary.h"
#include "error.h"
#include "file-handle.h"
#include "hash.h"
#include "lexer.h"
-#include "sfm.h"
+#include "sfm-read.h"
#include "str.h"
#include "value-labels.h"
#include "var.h"
cmd_apply_dictionary (void)
{
struct file_handle *handle;
+ struct sfm_reader *reader;
struct dictionary *dict;
int n_matched = 0;
lex_match_id ("FROM");
lex_match ('=');
- handle = fh_parse_file_handle ();
+ handle = fh_parse ();
if (!handle)
return CMD_FAILURE;
- dict = sfm_read_dictionary (handle, NULL);
+ reader = sfm_open_reader (handle, &dict, NULL);
if (dict == NULL)
return CMD_FAILURE;
+ sfm_close_reader (reader);
for (i = 0; i < dict_get_var_cnt (dict); i++)
{
dict_set_weight (default_dict, new_weight);
}
- sfm_maybe_close (handle);
+ sfm_close_reader (reader);
return lex_end_of_command ();
}
#include "alloc.h"
#include "case.h"
#include "command.h"
+#include "dictionary.h"
#include "error.h"
#include "hash.h"
#include "lexer.h"
struct subcat {
const double *data;
- char *label;
+ const char *label;
};
static const struct subcat sub_catagory[SUB_CATAGORIES] =
struct dataset
{
int n_data;
- char *label;
+ const char *label;
};
#ifdef GLOBAL_DEBUGGING
#undef NDEBUG
#else
+#ifndef NDEBUG
#define NDEBUG
#endif
+#endif
#include <assert.h>
+/* Changes C not to share data with any other case.
+ C must be a case with a reference count greater than 1.
+ There should be no reason for external code to call this
+ function explicitly. It will be called automatically when
+ needed. */
void
case_unshare (struct ccase *c)
{
sizeof *cd->values * cd->value_cnt);
}
+/* Returns the number of bytes needed by a case with VALUE_CNT
+ values. */
static inline size_t
case_size (size_t value_cnt)
{
}
#ifdef GLOBAL_DEBUGGING
+/* Initializes C as a null case. */
void
case_nullify (struct ccase *c)
{
#endif /* GLOBAL_DEBUGGING */
#ifdef GLOBAL_DEBUGGING
+/* Returns true iff C is a null case. */
int
case_is_null (const struct ccase *c)
{
}
#endif /* GLOBAL_DEBUGGING */
+/* Initializes C as a new case that can store VALUE_CNT values.
+ The values have indeterminate contents until explicitly
+ written. */
void
case_create (struct ccase *c, size_t value_cnt)
{
}
#ifdef GLOBAL_DEBUGGING
+/* Initializes CLONE as a copy of ORIG. */
void
case_clone (struct ccase *clone, const struct ccase *orig)
{
#endif /* GLOBAL_DEBUGGING */
#ifdef GLOBAL_DEBUGGING
+/* Replaces DST by SRC and nullifies SRC.
+ DST and SRC must be initialized cases at entry. */
void
case_move (struct ccase *dst, struct ccase *src)
{
#endif /* GLOBAL_DEBUGGING */
#ifdef GLOBAL_DEBUGGING
+/* Destroys case C. */
void
case_destroy (struct ccase *c)
{
}
#endif /* GLOBAL_DEBUGGING */
+/* Attempts to create C as a new case that holds VALUE_CNT
+ values. Returns nonzero if successful, zero if memory
+ allocation failed. */
int
case_try_create (struct ccase *c, size_t value_cnt)
{
}
}
+/* Tries to initialize CLONE as a copy of ORIG.
+ Returns nonzero if successful, zero if memory allocation
+ failed. */
int
case_try_clone (struct ccase *clone, const struct ccase *orig)
{
}
#ifdef GLOBAL_DEBUGGING
+/* Copies VALUE_CNT values from SRC (starting at SRC_IDX) to DST
+ (starting at DST_IDX). */
void
case_copy (struct ccase *dst, size_t dst_idx,
const struct ccase *src, size_t src_idx,
#endif /* GLOBAL_DEBUGGING */
#ifdef GLOBAL_DEBUGGING
-size_t
-case_serial_size (size_t value_cnt)
-{
- return value_cnt * sizeof (union value);
-}
-#endif /* GLOBAL_DEBUGGING */
-
-#ifdef GLOBAL_DEBUGGING
+/* Copies case C to OUTPUT.
+ OUTPUT_SIZE is the number of `union values' in OUTPUT,
+ which must match the number of `union values' in C. */
void
-case_serialize (const struct ccase *c, void *output,
+case_to_values (const struct ccase *c, union value *output,
size_t output_size UNUSED)
{
assert (c != NULL);
assert (c->this == c);
assert (c->case_data != NULL);
assert (c->case_data->ref_cnt > 0);
- assert (output_size == case_serial_size (c->case_data->value_cnt));
+ assert (output_size == c->case_data->value_cnt);
assert (output != NULL || output_size == 0);
memcpy (output, c->case_data->values,
- case_serial_size (c->case_data->value_cnt));
+ c->case_data->value_cnt * sizeof *output);
}
#endif /* GLOBAL_DEBUGGING */
#ifdef GLOBAL_DEBUGGING
+/* Copies INPUT into case C.
+ INPUT_SIZE is the number of `union values' in INPUT,
+ which must match the number of `union values' in C. */
void
-case_unserialize (struct ccase *c, const void *input,
+case_from_values (struct ccase *c, const union value *input,
size_t input_size UNUSED)
{
assert (c != NULL);
assert (c->this == c);
assert (c->case_data != NULL);
assert (c->case_data->ref_cnt > 0);
- assert (input_size == case_serial_size (c->case_data->value_cnt));
+ assert (input_size == c->case_data->value_cnt);
assert (input != NULL || input_size == 0);
if (c->case_data->ref_cnt > 1)
case_unshare (c);
memcpy (c->case_data->values, input,
- case_serial_size (c->case_data->value_cnt));
+ c->case_data->value_cnt * sizeof *input);
}
#endif /* GLOBAL_DEBUGGING */
#ifdef GLOBAL_DEBUGGING
+/* Returns a pointer to the `union value' used for the
+ element of C numbered IDX.
+ The caller must not modify the returned data. */
const union value *
case_data (const struct ccase *c, size_t idx)
{
#endif /* GLOBAL_DEBUGGING */
#ifdef GLOBAL_DEBUGGING
+/* Returns the numeric value of the `union value' in C numbered
+ IDX. */
double
case_num (const struct ccase *c, size_t idx)
{
#endif /* GLOBAL_DEBUGGING */
#ifdef GLOBAL_DEBUGGING
+/* Returns the string value of the `union value' in C numbered
+ IDX.
+ (Note that the value is not null-terminated.)
+ The caller must not modify the return value. */
const char *
case_str (const struct ccase *c, size_t idx)
{
#endif /* GLOBAL_DEBUGGING */
#ifdef GLOBAL_DEBUGGING
+/* Returns a pointer to the `union value' used for the
+ element of C numbered IDX.
+ The caller is allowed to modify the returned data. */
union value *
case_data_rw (struct ccase *c, size_t idx)
{
return &c->case_data->values[idx];
}
#endif /* GLOBAL_DEBUGGING */
+
+/* Returns a pointer to the array of `union value's used for C.
+ The caller must *not* modify the returned data.
+
+ NOTE: This function breaks the case abstraction. It should
+ *not* be used often. Prefer the other case functions. */
+const union value *
+case_data_all (const struct ccase *c)
+{
+ assert (c != NULL);
+ assert (c->this == c);
+ assert (c->case_data != NULL);
+ assert (c->case_data->ref_cnt > 0);
+
+ return c->case_data->values;
+}
+
+/* Returns a pointer to the array of `union value's used for C.
+ The caller is allowed to modify the returned data.
+
+ NOTE: This function breaks the case abstraction. It should
+ *not* be used often. Prefer the other case functions. */
+union value *
+case_data_all_rw (struct ccase *c)
+{
+ assert (c != NULL);
+ assert (c->this == c);
+ assert (c->case_data != NULL);
+ assert (c->case_data->ref_cnt > 0);
+
+ if (c->case_data->ref_cnt > 1)
+ case_unshare (c);
+ return c->case_data->values;
+}
case_move() or case_clone() instead of copying. */
struct ccase
{
- struct case_data *case_data;
+ struct case_data *case_data; /* Actual data. */
#if GLOBAL_DEBUGGING
- struct ccase *this;
+ struct ccase *this; /* Detects unauthorized move/copy. */
#endif
};
/* Invisible to user code. */
struct case_data
{
- size_t value_cnt;
- unsigned ref_cnt;
- union value values[1];
+ size_t value_cnt; /* Number of values. */
+ unsigned ref_cnt; /* Reference count. */
+ union value values[1]; /* Values. */
};
#ifdef GLOBAL_DEBUGGING
const struct ccase *src, size_t src_idx,
size_t cnt);
-CASE_INLINE size_t case_serial_size (size_t value_cnt);
-CASE_INLINE void case_serialize (const struct ccase *, void *, size_t);
-CASE_INLINE void case_unserialize (struct ccase *, const void *, size_t);
+CASE_INLINE void case_to_values (const struct ccase *, union value *, size_t);
+CASE_INLINE void case_from_values (struct ccase *,
+ const union value *, size_t);
CASE_INLINE const union value *case_data (const struct ccase *, size_t idx);
CASE_INLINE double case_num (const struct ccase *, size_t idx);
CASE_INLINE union value *case_data_rw (struct ccase *, size_t idx);
+const union value *case_data_all (const struct ccase *);
+union value *case_data_all_rw (struct ccase *);
+
void case_unshare (struct ccase *);
#ifndef GLOBAL_DEBUGGING
sizeof *dst->case_data->values * value_cnt);
}
-static inline size_t
-case_serial_size (size_t value_cnt)
-{
- return value_cnt * sizeof (union value);
-}
-
static inline void
-case_serialize (const struct ccase *c, void *output,
+case_to_values (const struct ccase *c, union value *output,
size_t output_size UNUSED)
{
memcpy (output, c->case_data->values,
- case_serial_size (c->case_data->value_cnt));
+ c->case_data->value_cnt * sizeof *output);
}
static inline void
-case_unserialize (struct ccase *c, const void *input,
+case_from_values (struct ccase *c, const union value *input,
size_t input_size UNUSED)
{
if (c->case_data->ref_cnt > 1)
case_unshare (c);
memcpy (c->case_data->values, input,
- case_serial_size (c->case_data->value_cnt));
+ c->case_data->value_cnt * sizeof *input);
}
static inline const union value *
#include <valgrind/valgrind.h>
#endif
-#define IO_BUF_SIZE 8192
+#define IO_BUF_SIZE (8192 / sizeof (union value))
/* A casefile is a sequentially accessible array of immutable
cases. It may be stored in memory or on disk as workspace
/* Basic data. */
struct casefile *next, *prev; /* Next, prev in global list. */
size_t value_cnt; /* Case size in `union value's. */
- size_t case_size; /* Case size in bytes. */
size_t case_acct_size; /* Case size for accounting. */
unsigned long case_cnt; /* Number of cases stored. */
enum { MEMORY, DISK } storage; /* Where cases are stored. */
/* Disk storage. */
int fd; /* File descriptor, -1 if none. */
char *filename; /* Filename. */
- unsigned char *buffer; /* I/O buffer, NULL if none. */
- size_t buffer_used; /* Number of bytes used in buffer. */
- size_t buffer_size; /* Buffer size in bytes. */
+ union value *buffer; /* I/O buffer, NULL if none. */
+ size_t buffer_used; /* Number of values used in buffer. */
+ size_t buffer_size; /* Buffer size in values. */
};
/* For reading out the cases in a casefile. */
/* Disk storage. */
int fd; /* File descriptor. */
- unsigned char *buffer; /* I/O buffer. */
- size_t buffer_pos; /* Byte offset of buffer position. */
+ union value *buffer; /* I/O buffer. */
+ size_t buffer_pos; /* Offset of buffer position. */
struct ccase c; /* Current case. */
};
static int safe_open (const char *filename, int flags);
static int safe_close (int fd);
-static int full_read (int fd, char *buffer, size_t size);
-static int full_write (int fd, const char *buffer, size_t size);
+static int full_read (int fd, void *buffer, size_t size);
+static int full_write (int fd, const void *buffer, size_t size);
/* Creates and returns a casefile to store cases of VALUE_CNT
`union value's each. */
cf->next->prev = cf;
casefiles = cf;
cf->value_cnt = value_cnt;
- cf->case_size = case_serial_size (value_cnt);
- cf->case_acct_size = cf->case_size + 4 * sizeof (void *);
+ cf->case_acct_size = (cf->value_cnt + 4) * sizeof *cf->buffer;
cf->case_cnt = 0;
cf->storage = MEMORY;
cf->mode = WRITE;
cf->fd = -1;
cf->filename = NULL;
cf->buffer = NULL;
- cf->buffer_size = ROUND_UP (cf->case_size, IO_BUF_SIZE);
- if (cf->case_size > 0 && cf->buffer_size % cf->case_size > 512)
- cf->buffer_size = cf->case_size;
+ cf->buffer_size = ROUND_UP (cf->value_cnt, IO_BUF_SIZE);
+ if (cf->value_cnt > 0 && cf->buffer_size % cf->value_cnt > 64)
+ cf->buffer_size = cf->value_cnt;
cf->buffer_used = 0;
register_atexit ();
return cf;
static void
write_case_to_disk (struct casefile *cf, const struct ccase *c)
{
- case_serialize (c, cf->buffer + cf->buffer_used, cf->case_size);
- cf->buffer_used += cf->case_size;
- if (cf->buffer_used + cf->case_size > cf->buffer_size)
+ case_to_values (c, cf->buffer + cf->buffer_used, cf->value_cnt);
+ cf->buffer_used += cf->value_cnt;
+ if (cf->buffer_used + cf->value_cnt > cf->buffer_size)
flush_buffer (cf);
}
{
if (cf->buffer_used > 0)
{
- if (!full_write (cf->fd, cf->buffer, cf->buffer_size))
+ if (!full_write (cf->fd, cf->buffer,
+ cf->buffer_size * sizeof *cf->buffer))
msg (FE, _("Error writing temporary file: %s."), strerror (errno));
cf->buffer_used = 0;
struct casereader *reader;
assert (cf != NULL);
-
+
if (cf->storage == MEMORY)
{
size_t idx, block_cnt;
cf->storage = DISK;
if (!make_temp_file (&cf->fd, &cf->filename))
err_failure ();
- cf->buffer = xmalloc (cf->buffer_size);
- memset (cf->buffer, 0, cf->buffer_size);
+ cf->buffer = xmalloc (cf->buffer_size * sizeof *cf->buffer);
+ memset (cf->buffer, 0, cf->buffer_size * sizeof *cf->buffer);
case_bytes -= cf->case_cnt * cf->case_acct_size;
for (idx = 0; idx < cf->case_cnt; idx++)
reader_open_file (struct casereader *reader)
{
struct casefile *cf = reader->cf;
- size_t buffer_case_cnt;
off_t file_ofs;
if (reader->case_idx >= cf->case_cnt)
}
else
{
- reader->buffer = xmalloc (cf->buffer_size);
- memset (reader->buffer, 0, cf->buffer_size);
+ reader->buffer = xmalloc (cf->buffer_size * sizeof *cf->buffer);
+ memset (reader->buffer, 0, cf->buffer_size * sizeof *cf->buffer);
}
- if (cf->case_size != 0)
+ if (cf->value_cnt != 0)
{
- buffer_case_cnt = cf->buffer_size / cf->case_size;
- file_ofs = ((off_t) reader->case_idx
- / buffer_case_cnt * cf->buffer_size);
+ size_t buffer_case_cnt = cf->buffer_size / cf->value_cnt;
+ file_ofs = ((off_t) reader->case_idx / buffer_case_cnt
+ * cf->buffer_size * sizeof *cf->buffer);
reader->buffer_pos = (reader->case_idx % buffer_case_cnt
- * cf->case_size);
+ * cf->value_cnt);
}
else
file_ofs = 0;
msg (FE, _("%s: Seeking temporary file: %s."),
cf->filename, strerror (errno));
- if (cf->case_cnt > 0 && cf->case_size > 0)
+ if (cf->case_cnt > 0 && cf->value_cnt > 0)
fill_buffer (reader);
case_create (&reader->c, cf->value_cnt);
static void
fill_buffer (struct casereader *reader)
{
- int retval = full_read (reader->fd, reader->buffer, reader->cf->buffer_size);
+ int retval = full_read (reader->fd, reader->buffer,
+ reader->cf->buffer_size * sizeof *reader->buffer);
if (retval < 0)
msg (FE, _("%s: Reading temporary file: %s."),
reader->cf->filename, strerror (errno));
- else if (retval != reader->cf->buffer_size)
+ else if (retval != reader->cf->buffer_size * sizeof *reader->buffer)
msg (FE, _("%s: Temporary file ended unexpectedly."),
reader->cf->filename);
}
}
else
{
- if (reader->buffer_pos + reader->cf->case_size > reader->cf->buffer_size)
+ if (reader->buffer_pos + reader->cf->value_cnt > reader->cf->buffer_size)
{
fill_buffer (reader);
reader->buffer_pos = 0;
}
- case_unserialize (&reader->c, reader->buffer + reader->buffer_pos,
- reader->cf->case_size);
- reader->buffer_pos += reader->cf->case_size;
+ case_from_values (&reader->c, reader->buffer + reader->buffer_pos,
+ reader->cf->value_cnt);
+ reader->buffer_pos += reader->cf->value_cnt;
reader->case_idx++;
case_clone (c, &reader->c);
/* Calls read(), passing FD, BUFFER, and SIZE, repeating as
necessary to deal with interrupted calls. */
static int
-full_read (int fd, char *buffer, size_t size)
+full_read (int fd, void *buffer_, size_t size)
{
+ char *buffer = buffer_;
size_t bytes_read = 0;
while (bytes_read < size)
/* Calls write(), passing FD, BUFFER, and SIZE, repeating as
necessary to deal with interrupted calls. */
static int
-full_write (int fd, const char *buffer, size_t size)
+full_write (int fd, const void *buffer_, size_t size)
{
+ const char *buffer = buffer_;
size_t bytes_written = 0;
while (bytes_written < size)
for (i = j = 0; i < case_cnt; i++)
{
read_and_verify_random_case (cf, r1, i);
- if (rng_get_int (rng) % pattern == 0)
- read_and_verify_random_case (cf, r2, j++);
+ if (rng_get_int (rng) % pattern == 0)
+ read_and_verify_random_case (cf, r2, j++);
if (i == case_cnt / 2)
casefile_to_disk (cf);
}
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-
+#include <config.h>
#include <stdio.h>
#include <plot.h>
#include <stdarg.h>
#include <math.h>
#include "chart.h"
+#include "str.h"
const char *data_colour[] = {
void draw_histogram(struct chart *ch,
const struct variable *v,
+ const struct freq_tab *frq_tab,
const char *title,
struct normal_curve *norm,
int show_normal);
double chart_rounded_tick(double tick);
-void draw_piechart(struct chart *ch, const struct variable *v);
+void draw_piechart(struct chart *ch, const struct variable *v,
+ const struct freq_tab *);
void draw_scatterplot(struct chart *ch);
#include <ctype.h>
#include <errno.h>
#include "alloc.h"
+#include "dictionary.h"
#include "error.h"
#include "getline.h"
#include "lexer.h"
#include "alloc.h"
#include "case.h"
#include "command.h"
+#include "dictionary.h"
#include "error.h"
#include "expr.h"
#include "lexer.h"
#include <config.h>
#include <stdlib.h>
#include "alloc.h"
+#include "dictionary.h"
#include "file-handle.h"
#include "command.h"
#include "lexer.h"
return 0;
if (lex_match ('*'))
- matrix_file = inline_file;
- else
- matrix_file = fh_parse_file_handle ();
-
- if (!matrix_file)
- return 0;
+ matrix_file = NULL;
+ else
+ {
+ matrix_file = fh_parse ();
+ if (matrix_file == NULL)
+ return 0;
+ }
if (!lex_force_match (')'))
return 0;
#include "alloc.h"
#include "case.h"
#include "command.h"
+#include "dictionary.h"
#include "error.h"
#include "lexer.h"
#include "str.h"
#include "algorithm.h"
#include "alloc.h"
#include "case.h"
+#include "dictionary.h"
#include "hash.h"
#include "pool.h"
#include "command.h"
#include "magic.h"
#include "misc.h"
#include "output.h"
+#include "str.h"
#include "tab.h"
#include "value-labels.h"
#include "var.h"
#include "vfm.h"
+/* (headers) */
+
#include "debug-print.h"
/* (specification)
larger indices first. */
};
+/* Integer mode variable info. */
+struct var_range
+ {
+ int min; /* Minimum value. */
+ int max; /* Maximum value + 1. */
+ int count; /* max - min. */
+ };
+
+static inline struct var_range *
+get_var_range (struct variable *v)
+{
+ assert (v != NULL);
+ assert (v->aux != NULL);
+ return v->aux;
+}
+
/* Indexes into crosstab.v. */
enum
{
}
lex_get ();
- for (i = orig_nv; i < variables_cnt; i++)
- {
- variables[i]->p.crs.min = min;
- variables[i]->p.crs.max = max + 1.;
- variables[i]->p.crs.count = max - min + 1;
+ for (i = orig_nv; i < variables_cnt; i++)
+ {
+ struct var_range *vr = xmalloc (sizeof *vr);
+ vr->min = min;
+ vr->max = max + 1.;
+ vr->count = max - min + 1;
+ var_attach_aux (variables[i], vr, var_dtor_free);
}
if (token == '/')
x->ofs = n_sorted_tab;
- for (j = 2; j < x->nvar; j++)
- count *= x->vars[j - 2]->p.crs.count;
-
+ for (j = 2; j < x->nvar; j++)
+ count *= get_var_range (x->vars[j - 2])->count;
+
sorted_tab = xrealloc (sorted_tab,
sizeof *sorted_tab * (n_sorted_tab + count));
v = local_alloc (sizeof *v * x->nvar);
- for (j = 2; j < x->nvar; j++)
- v[j] = x->vars[j]->p.crs.min;
+ for (j = 2; j < x->nvar; j++)
+ v[j] = get_var_range (x->vars[j])->min;
for (j = 0; j < count; j++)
{
struct table_entry *te;
te->table = i;
{
- const int mat_size = (x->vars[0]->p.crs.count
- * x->vars[1]->p.crs.count);
+ int row_cnt = get_var_range (x->vars[0])->count;
+ int col_cnt = get_var_range (x->vars[1])->count;
+ const int mat_size = row_cnt * col_cnt;
int m;
te->u.data = xmalloc (sizeof *te->u.data * mat_size);
for (k = 2; k < x->nvar; k++)
te->values[k].f = v[k];
- for (k = 2; k < x->nvar; k++)
- if (++v[k] >= x->vars[k]->p.crs.max)
- v[k] = x->vars[k]->p.crs.min;
- else
- break;
+ for (k = 2; k < x->nvar; k++)
+ {
+ struct var_range *vr = get_var_range (x->vars[k]);
+ if (++v[k] >= vr->max)
+ v[k] = vr->min;
+ else
+ break;
+ }
}
local_free (v);
}
for (i = 0; i < x->nvar; i++)
{
struct variable *const v = x->vars[i];
+ struct var_range *vr = get_var_range (v);
double value = case_num (c, v->fv);
/* Note that the first test also rules out SYSMIS. */
- if ((value < v->p.crs.min || value >= v->p.crs.max)
+ if ((value < vr->min || value >= vr->max)
|| (cmd.miss == CRS_TABLE && is_num_user_missing (value, v)))
{
x->missing += weight;
if (i > 1)
{
- ofs += fact * ((int) value - v->p.crs.min);
- fact *= v->p.crs.count;
+ ofs += fact * ((int) value - vr->min);
+ fact *= vr->count;
}
}
{
- const int row = case_num (c, x->vars[ROW_VAR]->fv) - x->vars[ROW_VAR]->p.crs.min;
- const int col = case_num (c, x->vars[COL_VAR]->fv) - x->vars[COL_VAR]->p.crs.min;
- const int col_dim = x->vars[COL_VAR]->p.crs.count;
+ struct variable *row_var = x->vars[ROW_VAR];
+ const int row = case_num (c, row_var->fv) - get_var_range (row_var)->min;
+
+ struct variable *col_var = x->vars[COL_VAR];
+ const int col = case_num (c, col_var->fv) - get_var_range (col_var)->min;
+
+ const int col_dim = get_var_range (col_var)->count;
sorted_tab[ofs]->u.data[col + row * col_dim] += weight;
}
else
{
const struct crosstab *const x = xtab[(*pb)->table];
- const int n_cols = x->vars[COL_VAR]->p.crs.count;
- const int n_rows = x->vars[ROW_VAR]->p.crs.count;
+ const int n_cols = get_var_range (x->vars[COL_VAR])->count;
+ const int n_rows = get_var_range (x->vars[ROW_VAR])->count;
const int count = n_cols * n_rows;
for (valid = 0.; pb < pe; pb++)
/* Given an array of ENTRY_CNT table_entry structures starting at
ENTRIES, creates a sorted list of the values that the variable
- with index VAR_INDEX takes on. The values are returned as a
+ with index VAR_IDX takes on. The values are returned as a
malloc()'darray stored in *VALUES, with the number of values
stored in *VALUE_CNT.
*/
enum_var_values (struct table_entry **entries, int entry_cnt, int var_idx,
union value **values, int *value_cnt)
{
+ struct variable *v = xtab[(*entries)->table]->vars[var_idx];
+
if (mode == GENERAL)
{
- int width = xtab[(*entries)->table]->vars[var_idx]->width;
+ int width = v->width;
int i;
*values = xmalloc (sizeof **values * entry_cnt);
}
else
{
- struct crosstab_proc *crs
- = &xtab[(*entries)->table]->vars[var_idx]->p.crs;
+ struct var_range *vr = get_var_range (v);
int i;
assert (mode == INTEGER);
- *values = xmalloc (sizeof **values * crs->count);
- for (i = 0; i < crs->count; i++)
- (*values)[i].f = i + crs->min;
- *value_cnt = crs->count;
+ *values = xmalloc (sizeof **values * vr->count);
+ for (i = 0; i < vr->count; i++)
+ (*values)[i].f = i + vr->min;
+ *value_cnt = vr->count;
}
}
#include "command.h"
#include "data-in.h"
#include "debug-print.h"
-#include "dfm.h"
+#include "dfm-read.h"
+#include "dictionary.h"
#include "error.h"
#include "file-handle.h"
#include "format.h"
struct trns_header h;
struct dls_var_spec *first, *last; /* Variable parsing specifications. */
- struct file_handle *handle; /* Input file, never NULL. */
+ struct dfm_reader *reader; /* Data file reader. */
int type; /* A DLS_* constant. */
struct variable *end; /* Variable specified on END subcommand. */
int eof; /* End of file encountered. */
- int nrec; /* Number of records. */
+ int rec_cnt; /* Number of records. */
size_t case_size; /* Case size in bytes. */
char *delims; /* Delimiters if any; not null-terminated. */
size_t delim_cnt; /* Number of delimiter, or 0 for spaces. */
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 *specs,
- const struct file_handle *handle, int nrec);
-static void dump_free_table (const struct data_list_pgm *);
+static void dump_fixed_table (const struct dls_var_spec *,
+ const struct file_handle *, int rec_cnt);
+static void dump_free_table (const struct data_list_pgm *,
+ const struct file_handle *);
static void destroy_dls_var_spec (struct dls_var_spec *);
static trns_free_func data_list_trns_free;
static trns_proc_func data_list_trns_proc;
int
cmd_data_list (void)
{
- /* DATA LIST program under construction. */
- struct data_list_pgm *dls;
-
- /* 0=print no table, 1=print table. (TABLE subcommand.) */
- int table = -1;
+ struct data_list_pgm *dls; /* DATA LIST program under construction. */
+ int table = -1; /* Print table if nonzero, -1=undecided. */
+ struct file_handle *fh = NULL; /* File handle of source, NULL=inline file. */
if (!case_source_is_complex (vfm_source))
discard_variables ();
dls = xmalloc (sizeof *dls);
- dls->handle = default_handle;
+ dls->reader = NULL;
dls->type = -1;
dls->end = NULL;
dls->eof = 0;
- dls->nrec = 0;
+ dls->rec_cnt = 0;
dls->delims = NULL;
dls->delim_cnt = 0;
dls->first = dls->last = NULL;
if (lex_match_id ("FILE"))
{
lex_match ('=');
- dls->handle = fh_parse_file_handle ();
- if (!dls->handle)
+ fh = fh_parse ();
+ if (fh == NULL)
goto error;
if (case_source_is_class (vfm_source, &file_type_source_class)
- && dls->handle != default_handle)
+ && fh != default_handle)
{
msg (SE, _("DATA LIST may not use a different file from "
"that specified on its surrounding FILE TYPE."));
lex_match ('(');
if (!lex_force_int ())
goto error;
- dls->nrec = lex_integer ();
+ dls->rec_cnt = lex_integer ();
lex_get ();
lex_match (')');
}
}
dls->case_size = dict_get_case_size (default_dict);
- default_handle = dls->handle;
+ default_handle = fh;
if (dls->type == -1)
dls->type = DLS_FIXED;
if (!parse_fixed (dls))
goto error;
if (table)
- dump_fixed_table (dls->first, dls->handle, dls->nrec);
+ dump_fixed_table (dls->first, fh, dls->rec_cnt);
}
else
{
if (!parse_free (&dls->first, &dls->last))
goto error;
if (table)
- dump_free_table (dls);
+ dump_free_table (dls, fh);
}
- if (!dfm_open_for_reading (dls->handle))
+ dls->reader = dfm_open_reader (fh);
+ if (dls->reader == NULL)
goto error;
if (vfm_source != NULL)
msg (SE, _("At least one variable must be specified."));
return 0;
}
- if (dls->nrec && dls->last->rec > dls->nrec)
+ if (dls->rec_cnt && dls->last->rec > dls->rec_cnt)
{
msg (SE, _("Variables are specified on records that "
"should not exist according to RECORDS subcommand."));
return 0;
}
- else if (!dls->nrec)
- dls->nrec = dls->last->rec;
+ else if (!dls->rec_cnt)
+ dls->rec_cnt = dls->last->rec;
if (token != '.')
{
lex_error (_("expecting end of command"));
ending column. */
static void
dump_fixed_table (const struct dls_var_spec *specs,
- const struct file_handle *handle, int nrec)
+ const struct file_handle *fh, int rec_cnt)
{
const struct dls_var_spec *spec;
struct tab_table *t;
- char *buf;
- const char *filename;
int i;
for (i = 0, spec = specs; spec; spec = spec->next)
fmt_to_string (&spec->input));
}
- filename = handle_get_filename (handle);
- if (filename == NULL)
- filename = "";
- buf = local_alloc (strlen (filename) + INT_DIGITS + 80);
- sprintf (buf, (handle != inline_file
- ? ngettext ("Reading %d record from file %s.",
- "Reading %d records from file %s.", nrec)
- : ngettext ("Reading %d record from the command file.",
- "Reading %d records from the command file.",
- nrec)),
- nrec, filename);
-
- tab_title (t, 0, buf);
+ if (fh != NULL)
+ tab_title (t, 1, ngettext ("Reading %d record from file %s.",
+ "Reading %d records from file %s.", rec_cnt),
+ rec_cnt, handle_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_submit (t);
- local_free (buf);
}
\f
/* Free-format parsing. */
/* Displays a table giving information on free-format variable parsing
on DATA LIST. */
static void
-dump_free_table (const struct data_list_pgm *dls)
+dump_free_table (const struct data_list_pgm *dls,
+ const struct file_handle *fh)
{
struct tab_table *t;
int i;
tab_text (t, 1, i, TAB_LEFT | TAT_FIX, fmt_to_string (&spec->input));
}
}
-
- {
- const char *filename;
-
- filename = handle_get_filename (dls->handle);
- if (filename == NULL)
- filename = "";
- tab_title (t, 1,
- (dls->handle != inline_file
- ? _("Reading free-form data from file %s.")
- : _("Reading free-form data from the command file.")),
- filename);
- }
+
+ if (fh != NULL)
+ tab_title (t, 1, _("Reading free-form data from file %s."),
+ handle_get_filename (fh));
+ else
+ tab_title (t, 1, _("Reading free-form data from the command file."));
tab_submit (t);
}
char *cp;
size_t column_start;
- if (dfm_eof (dls->handle))
+ if (dfm_eof (dls->reader))
return 0;
if (dls->delim_cnt == 0)
- dfm_expand_tabs (dls->handle);
- dfm_get_record (dls->handle, &line);
+ dfm_expand_tabs (dls->reader);
+ dfm_get_record (dls->reader, &line);
cp = ls_c_str (&line);
if (dls->delim_cnt == 0)
{
if (cp >= ls_end (&line))
{
- int column = dfm_column_start (dls->handle);
+ int column = dfm_column_start (dls->reader);
/* A blank line or a line that ends in \t has a
trailing blank field. */
if (column == 1 || (column > 1 && cp[-1] == '\t'))
*end_blank = 1;
field->string = ls_end (&line);
field->length = 0;
- dfm_forward_record (dls->handle);
+ dfm_forward_record (dls->reader);
return column;
}
else
}
}
- dfm_forward_columns (dls->handle, field->string - line.string);
- column_start = dfm_column_start (dls->handle);
+ dfm_forward_columns (dls->reader, field->string - line.string);
+ column_start = dfm_column_start (dls->reader);
- dfm_forward_columns (dls->handle, cp - field->string);
+ dfm_forward_columns (dls->reader, cp - field->string);
return column_start;
}
struct dls_var_spec *var_spec = dls->first;
int i;
- if (dfm_eof (dls->handle))
+ if (dfm_eof (dls->reader))
return -2;
- for (i = 1; i <= dls->nrec; i++)
+ for (i = 1; i <= dls->rec_cnt; i++)
{
struct len_string line;
- if (dfm_eof (dls->handle))
+ if (dfm_eof (dls->reader))
{
/* Note that this can't occur on the first record. */
msg (SW, _("Partial case of %d of %d records discarded."),
- i - 1, dls->nrec);
+ i - 1, dls->rec_cnt);
return -2;
}
- dfm_expand_tabs (dls->handle);
- dfm_get_record (dls->handle, &line);
+ dfm_expand_tabs (dls->reader);
+ dfm_get_record (dls->reader, &line);
for (; var_spec && i == var_spec->rec; var_spec = var_spec->next)
{
data_in (&di);
}
- dfm_forward_record (dls->handle);
+ dfm_forward_record (dls->reader);
}
return -1;
if (column != 0)
break;
- if (!dfm_eof (dls->handle))
- dfm_forward_record (dls->handle);
- if (dfm_eof (dls->handle))
+ if (!dfm_eof (dls->reader))
+ dfm_forward_record (dls->reader);
+ if (dfm_eof (dls->reader))
{
if (var_spec != dls->first)
msg (SW, _("Partial case discarded. The first variable "
struct dls_var_spec *var_spec;
int end_blank = 0;
- if (dfm_eof (dls->handle))
+ if (dfm_eof (dls->reader))
return -2;
for (var_spec = dls->first; var_spec; var_spec = var_spec->next)
}
}
- dfm_forward_record (dls->handle);
+ dfm_forward_record (dls->reader);
return -1;
}
struct data_list_pgm *dls = (struct data_list_pgm *) pgm;
free (dls->delims);
destroy_dls_var_spec (dls->first);
- fh_close_handle (dls->handle);
+ dfm_close_reader (dls->reader);
free (pgm);
}
data_list_read_func *read_func;
int retval;
- dfm_push (dls->handle);
+ dfm_push (dls->reader);
read_func = get_data_list_read_func (dls);
retval = read_func (dls, c);
{
msg (SE, _("Attempt to read past end of file."));
err_failure ();
- dfm_pop (dls->handle);
+ dfm_pop (dls->reader);
return -2;
}
case_data_rw (c, dls->end->fv)->f = 0.0;
}
- dfm_pop (dls->handle);
+ dfm_pop (dls->reader);
return retval;
}
struct data_list_pgm *dls = source->aux;
data_list_read_func *read_func = get_data_list_read_func (dls);
- dfm_push (dls->handle);
+ dfm_push (dls->reader);
while (read_func (dls, c) != -2)
if (!write_case (wc_data))
break;
- dfm_pop (dls->handle);
-
- fh_close_handle (dls->handle);
+ dfm_pop (dls->reader);
}
/* Destroys the source's internal data. */
{
struct trns_header h;
struct dls_var_spec *first, *last; /* Variable parsing specifications. */
- struct file_handle *handle; /* Input file, never NULL. */
+ struct dfm_reader *reader; /* Input file, never NULL. */
struct rpd_num_or_var starts_beg; /* STARTS=, before the dash. */
struct rpd_num_or_var starts_end; /* STARTS=, after the dash. */
cmd_repeating_data (void)
{
struct repeating_data_trns *rpd;
-
- /* 0=print no table, 1=print table. (TABLE subcommand.) */
- int table = 1;
-
- /* Bits are set when a particular subcommand has been seen. */
- unsigned seen = 0;
+ int table = 1; /* Print table? */
+ unsigned seen = 0; /* Mark subcommands as already seen. */
+ struct file_handle *const fh = default_handle;
assert (case_source_is_complex (vfm_source));
rpd = xmalloc (sizeof *rpd);
- rpd->handle = default_handle;
+ rpd->reader = dfm_open_reader (default_handle);
rpd->first = rpd->last = NULL;
rpd->starts_beg.num = 0;
rpd->starts_beg.var = NULL;
{
if (lex_match_id ("FILE"))
{
+ struct file_handle *file;
lex_match ('=');
- rpd->handle = fh_parse_file_handle ();
- if (!rpd->handle)
+ file = fh_parse ();
+ if (file == NULL)
goto error;
- if (rpd->handle != default_handle)
+ if (file != fh)
{
msg (SE, _("REPEATING DATA must use the same file as its "
"corresponding DATA LIST or FILE TYPE."));
/* Calculate starts_end, cont_end if necessary. */
if (rpd->starts_end.num == 0 && rpd->starts_end.var == NULL)
- rpd->starts_end.num = handle_get_record_width (rpd->handle);
+ rpd->starts_end.num = handle_get_record_width (fh);
if (rpd->cont_end.num == 0 && rpd->starts_end.var == NULL)
- rpd->cont_end.num = handle_get_record_width (rpd->handle);
+ rpd->cont_end.num = handle_get_record_width (fh);
/* Calculate length if possible. */
if ((seen & 4) == 0)
goto error;
if (table)
- dump_fixed_table (rpd->first, rpd->handle, rpd->last->rec);
+ dump_fixed_table (rpd->first, fh, rpd->last->rec);
{
struct repeating_data_trns *new_trns;
int skip_first_record = 0;
- dfm_push (t->handle);
+ dfm_push (t->reader);
/* Read the current record. */
- dfm_reread_record (t->handle, 1);
- dfm_expand_tabs (t->handle);
- if (dfm_eof (t->handle))
+ dfm_reread_record (t->reader, 1);
+ dfm_expand_tabs (t->reader);
+ if (dfm_eof (t->reader))
return -2;
- dfm_get_record (t->handle, &line);
- dfm_forward_record (t->handle);
+ dfm_get_record (t->reader, &line);
+ dfm_forward_record (t->reader);
/* Calculate occurs, length. */
occurs_left = occurs = realize_value (&t->occurs, c);
assert (occurs_left >= 0);
/* Read in another record. */
- if (dfm_eof (t->handle))
+ if (dfm_eof (t->reader))
{
tmsg (SE, RPD_ERR,
_("Unexpected end of file with %d repetitions "
occurs_left, occurs);
return -2;
}
- dfm_expand_tabs (t->handle);
- dfm_get_record (t->handle, &line);
- dfm_forward_record (t->handle);
+ dfm_expand_tabs (t->reader);
+ dfm_get_record (t->reader, &line);
+ dfm_forward_record (t->reader);
/* Parse this record. */
info.trns = t;
occurs_left -= code;
}
- dfm_pop (t->handle);
+ dfm_pop (t->reader);
/* FIXME: This is a kluge until we've implemented multiplexing of
transformations. */
struct repeating_data_trns *rpd = (struct repeating_data_trns *) rpd_;
destroy_dls_var_spec (rpd->first);
- fh_close_handle (rpd->handle);
+ dfm_close_reader (rpd->reader);
free (rpd->id_value);
}
#include "case.h"
#include "casefile.h"
#include "command.h"
+#include "dictionary.h"
#include "lexer.h"
#include "error.h"
#include "magic.h"
--- /dev/null
+/* PSPP - computes sample statistics.
+ Copyright (C) 1997-2004 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include <config.h>
+#include "dfm-read.h"
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "alloc.h"
+#include "command.h"
+#include "error.h"
+#include "file-handle.h"
+#include "filename.h"
+#include "getline.h"
+#include "lexer.h"
+#include "str.h"
+#include "vfm.h"
+
+#include "debug-print.h"
+
+/* Flags for DFM readers. */
+enum dfm_reader_flags
+ {
+ DFM_EOF = 001, /* At end-of-file? */
+ DFM_ADVANCE = 002, /* Read next line on dfm_get_record() call? */
+ DFM_SAW_BEGIN_DATA = 004, /* For inline_file only, whether we've
+ already read a BEGIN DATA line. */
+ DFM_TABS_EXPANDED = 010, /* Tabs have been expanded. */
+ };
+
+/* Data file reader. */
+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_*. */
+ };
+
+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(). */
+void
+dfm_close_reader (struct dfm_reader *r)
+{
+ int still_open;
+
+ 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. */
+ while ((r->flags & DFM_EOF) == 0)
+ read_record (r);
+ inline_file = NULL;
+ }
+ }
+ if (still_open)
+ return;
+
+ if (r->fh != NULL && r->file.file)
+ {
+ fn_close_ext (&r->file);
+ free (r->file.filename);
+ r->file.filename = NULL;
+ }
+ 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
+ "inline file", that is, data included inline in the command
+ file between BEGIN FILE and END FILE. Returns nonzero only if
+ successful. */
+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;
+ }
+
+ r = xmalloc (sizeof *r);
+ r->fh = fh;
+ if (fh != NULL)
+ {
+ r->where.filename = handle_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)
+ {
+ r->file.filename = xstrdup (handle_get_filename (r->fh));
+ r->file.mode = "rb";
+ r->file.file = NULL;
+ r->file.sequence_no = NULL;
+ r->file.param = NULL;
+ 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."),
+ handle_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;
+
+ return r;
+}
+
+static int
+read_inline_record (struct dfm_reader *r)
+{
+ if ((r->flags & DFM_SAW_BEGIN_DATA) == 0)
+ {
+ char *s;
+
+ r->flags |= DFM_SAW_BEGIN_DATA;
+
+ /* FIXME: WTF can't this just be done with tokens?
+ Is this really a special case? */
+ do
+ {
+ char *cp;
+
+ if (!getl_read_line ())
+ {
+ msg (SE, _("BEGIN DATA expected."));
+ err_failure ();
+ }
+
+ /* Skip leading whitespace, separate out first
+ word, so that S points to a single word reduced
+ to lowercase. */
+ s = ds_c_str (&getl_buf);
+ while (isspace ((unsigned char) *s))
+ s++;
+ for (cp = s; isalpha ((unsigned char) *cp); cp++)
+ *cp = tolower ((unsigned char) (*cp));
+ ds_truncate (&getl_buf, cp - s);
+ }
+ while (*s == '\0');
+
+ if (!lex_id_match_len ("begin", 5, s, strcspn (s, " \t\r\v\n")))
+ {
+ msg (SE, _("BEGIN DATA expected."));
+ lex_preprocess_line ();
+ return 0;
+ }
+ getl_prompt = GETL_PRPT_DATA;
+ }
+
+ if (!getl_read_line ())
+ {
+ msg (SE, _("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."));
+ 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;
+ }
+
+ ds_replace (&r->line, ds_c_str (&getl_buf));
+ return 1;
+}
+
+static int
+read_file_record (struct dfm_reader *r)
+{
+ assert (r->fh != NULL);
+ if (handle_get_mode (r->fh) == MODE_TEXT)
+ {
+ ds_clear (&r->line);
+ if (!ds_gets (&r->line, r->file.file))
+ {
+ if (ferror (r->file.file))
+ {
+ msg (ME, _("Error reading file %s: %s."),
+ handle_get_name (r->fh), strerror (errno));
+ err_cond_fail ();
+ }
+ return 0;
+ }
+ }
+ else if (handle_get_mode (r->fh) == MODE_BINARY)
+ {
+ size_t record_width = handle_get_record_width (r->fh);
+ size_t amt;
+
+ if (ds_length (&r->line) < record_width)
+ ds_rpad (&r->line, record_width, 0);
+
+ amt = fread (ds_c_str (&r->line), 1, record_width,
+ r->file.file);
+ if (record_width != amt)
+ {
+ if (ferror (r->file.file))
+ msg (ME, _("Error reading file %s: %s."),
+ handle_get_name (r->fh), strerror (errno));
+ else if (amt != 0)
+ msg (ME, _("%s: Partial record at end of file."),
+ handle_get_name (r->fh));
+ else
+ return 0;
+
+ err_cond_fail ();
+ return 0;
+ }
+ }
+ else
+ assert (0);
+
+ r->where.line_number++;
+
+ return 1;
+}
+
+/* Reads a record from R, setting the current position to the
+ start of the line. If an error occurs or end-of-file is
+ encountered, the current line is set to null. */
+static void
+read_record (struct dfm_reader *r)
+{
+ int success = r->fh != NULL ? read_file_record (r) : read_inline_record (r);
+ if (success)
+ r->pos = 0;
+ else
+ r->flags |= DFM_EOF;
+}
+
+/* Returns nonzero if end of file has been reached on HANDLE.
+ Reads forward in HANDLE's file, if necessary to tell. */
+int
+dfm_eof (struct dfm_reader *r)
+{
+ if (r->flags & DFM_ADVANCE)
+ {
+ r->flags &= ~DFM_ADVANCE;
+ if ((r->flags & DFM_EOF) == 0)
+ read_record (r);
+ else
+ {
+ if (r->fh != NULL)
+ msg (SE, _("Attempt to read beyond end-of-file on file %s."),
+ handle_get_name (r->fh));
+ else
+ msg (SE, _("Attempt to read beyond END DATA."));
+ err_cond_fail ();
+ }
+ }
+
+ return (r->flags & DFM_EOF) != 0;
+}
+
+/* Returns the current record in the file corresponding to
+ HANDLE. Aborts if reading from the file is necessary or at
+ end of file, so call dfm_eof() first. Sets *LINE to the line,
+ which is not null-terminated. The caller must not free or
+ modify the returned string. */
+void
+dfm_get_record (struct dfm_reader *r, struct len_string *line)
+{
+ assert ((r->flags & DFM_ADVANCE) == 0);
+ assert ((r->flags & DFM_EOF) == 0);
+ assert (r->pos <= ds_length (&r->line));
+
+ line->string = ds_data (&r->line) + r->pos;
+ line->length = ds_length (&r->line) - r->pos;
+}
+
+/* Expands tabs in the current line into the equivalent number of
+ spaces, if appropriate for this kind of file. Aborts if
+ reading from the file is necessary or at end of file, so call
+ dfm_eof() first.*/
+void
+dfm_expand_tabs (struct dfm_reader *r)
+{
+ struct string temp;
+ size_t ofs, new_pos, tab_width;
+
+ assert ((r->flags & DFM_ADVANCE) == 0);
+ assert ((r->flags & DFM_EOF) == 0);
+ assert (r->pos <= ds_length (&r->line));
+
+ if (r->flags & DFM_TABS_EXPANDED)
+ return;
+ r->flags |= DFM_TABS_EXPANDED;
+
+ if (r->fh != NULL
+ && (handle_get_mode (r->fh) == MODE_BINARY
+ || handle_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 ? handle_get_tab_width (r->fh) : 8;
+ ds_clear (&r->scratch);
+ new_pos = 0;
+ for (ofs = 0; ofs < ds_length (&r->line); ofs++)
+ {
+ unsigned char c;
+
+ if (ofs == r->pos)
+ new_pos = ds_length (&r->scratch);
+
+ c = ds_c_str (&r->line)[ofs];
+ if (c != '\t')
+ ds_putc (&r->scratch, c);
+ else
+ {
+ do
+ ds_putc (&r->scratch, ' ');
+ while (ds_length (&r->scratch) % tab_width != 0);
+ }
+ }
+
+ /* Swap r->line and r->scratch and set new r->pos. */
+ temp = r->line;
+ r->line = r->scratch;
+ r->scratch = temp;
+ r->pos = new_pos;
+}
+
+/* Causes dfm_get_record() to read in the next record the next time it
+ is executed on file HANDLE. */
+void
+dfm_forward_record (struct dfm_reader *r)
+{
+ r->flags |= DFM_ADVANCE;
+}
+
+/* Cancels the effect of any previous dfm_fwd_record() executed
+ on file HANDLE. Sets the current line to begin in the 1-based
+ column COLUMN. */
+void
+dfm_reread_record (struct dfm_reader *r, size_t column)
+{
+ r->flags &= ~DFM_ADVANCE;
+ if (column < 1)
+ r->pos = 0;
+ else if (column > ds_length (&r->line))
+ r->pos = ds_length (&r->line);
+ else
+ r->pos = column - 1;
+}
+
+/* Sets the current line to begin COLUMNS characters following
+ the current start. */
+void
+dfm_forward_columns (struct dfm_reader *r, size_t columns)
+{
+ dfm_reread_record (r, (r->pos + 1) + columns);
+}
+
+/* Returns the 1-based column to which the line pointer in HANDLE
+ is set. Unless dfm_reread_record() or dfm_forward_columns()
+ have been called, this is 1. */
+size_t
+dfm_column_start (struct dfm_reader *r)
+{
+ return r->pos + 1;
+}
+
+/* Pushes the filename and line number on the fn/ln stack. */
+void
+dfm_push (struct dfm_reader *r)
+{
+ if (r->fh != NULL)
+ err_push_file_locator (&r->where);
+}
+
+/* Pops the filename and line number from the fn/ln stack. */
+void
+dfm_pop (struct dfm_reader *r)
+{
+ if (r->fh != NULL)
+ err_pop_file_locator (&r->where);
+}
+\f
+/* BEGIN DATA...END DATA procedure. */
+
+/* Perform BEGIN DATA...END DATA as a procedure in itself. */
+int
+cmd_begin_data (void)
+{
+ 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))
+ {
+ msg (SE, _("This command is not valid here since the current "
+ "input program does not access the inline file."));
+ err_cond_fail ();
+ return CMD_FAILURE;
+ }
+
+ /* Open inline file. */
+ r = dfm_open_reader (NULL);
+ r->flags |= DFM_SAW_BEGIN_DATA;
+
+ /* Input procedure reads from inline file. */
+ getl_prompt = GETL_PRPT_DATA;
+ procedure (NULL, NULL);
+
+ dfm_close_reader (r);
+
+ return CMD_SUCCESS;
+}
--- /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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef DFM_READ_H
+#define DFM_READ_H
+
+/* Data file manager (dfm).
+
+ This module is in charge of reading and writing data files (other
+ than system files). dfm is an fhuser, so see file-handle.h for the
+ fhuser interface. */
+
+#include <stddef.h>
+
+struct file_handle;
+struct len_string;
+
+/* Input. */
+struct dfm_reader *dfm_open_reader (struct file_handle *);
+void dfm_close_reader (struct dfm_reader *);
+int dfm_eof (struct dfm_reader *);
+void dfm_get_record (struct dfm_reader *, struct len_string *);
+void dfm_expand_tabs (struct dfm_reader *);
+
+/* Line control. */
+void dfm_forward_record (struct dfm_reader *);
+void dfm_reread_record (struct dfm_reader *, size_t column);
+void dfm_forward_columns (struct dfm_reader *, size_t columns);
+size_t dfm_column_start (struct dfm_reader *);
+
+/* File stack. */
+void dfm_push (struct dfm_reader *);
+void dfm_pop (struct dfm_reader *);
+
+#endif /* dfm-read.h */
--- /dev/null
+/* PSPP - computes sample statistics.
+ Copyright (C) 1997-2004 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include <config.h>
+#include "dfm-write.h"
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include "alloc.h"
+#include "error.h"
+#include "file-handle.h"
+#include "filename.h"
+#include "str.h"
+
+/* Data file writer. */
+struct dfm_writer
+ {
+ struct file_handle *fh; /* File handle. */
+ struct file_ext file; /* Associated file. */
+ char *bounce; /* Bounce buffer for fixed-size fields. */
+ };
+
+/* Opens a file handle for writing as a data file. */
+struct dfm_writer *
+dfm_open_writer (struct file_handle *fh)
+{
+ struct dfm_writer *w;
+ void **aux;
+
+ aux = fh_open (fh, "data file", "ws");
+ if (aux == NULL)
+ return NULL;
+ if (*aux != NULL)
+ return *aux;
+
+ w = *aux = xmalloc (sizeof *w);
+ w->fh = fh;
+ w->file.file = NULL;
+ w->bounce = NULL;
+
+ w->file.filename = xstrdup (handle_get_filename (w->fh));
+ w->file.mode = "wb";
+ w->file.file = NULL;
+ w->file.sequence_no = NULL;
+ w->file.param = NULL;
+ w->file.postopen = NULL;
+ w->file.preclose = NULL;
+
+ if (!fn_open_ext (&w->file))
+ {
+ msg (ME, _("An error occurred while opening \"%s\" for writing "
+ "as a data file: %s."),
+ handle_get_filename (w->fh), strerror (errno));
+ goto error;
+ }
+
+ return w;
+
+ error:
+ err_cond_fail ();
+ dfm_close_writer (w);
+ return NULL;
+}
+
+/* Writes record REC having length LEN to the file corresponding to
+ HANDLE. REC is not null-terminated. Returns nonzero on success,
+ zero on failure. */
+int
+dfm_put_record (struct dfm_writer *w, const char *rec, size_t len)
+{
+ assert (w != NULL);
+
+ if (handle_get_mode (w->fh) == MODE_BINARY
+ && len < handle_get_record_width (w->fh))
+ {
+ size_t rec_width = handle_get_record_width (w->fh);
+ if (w->bounce == NULL)
+ w->bounce = xmalloc (rec_width);
+ memcpy (w->bounce, rec, len);
+ memset (&w->bounce[len], 0, rec_width - len);
+ rec = w->bounce;
+ len = rec_width;
+ }
+
+ if (fwrite (rec, len, 1, w->file.file) != 1)
+ {
+ msg (ME, _("Error writing file %s: %s."),
+ handle_get_name (w->fh), strerror (errno));
+ err_cond_fail ();
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Closes data file writer W. */
+void
+dfm_close_writer (struct dfm_writer *w)
+{
+ if (fh_close (w->fh, "data file", "ws"))
+ return;
+
+ if (w->file.file)
+ {
+ fn_close_ext (&w->file);
+ free (w->file.filename);
+ w->file.filename = NULL;
+ }
+ free (w->bounce);
+ free (w);
+}
--- /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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef DFM_WRITE_H
+#define DFM_WRITE_H
+
+/* Writing data files. */
+
+#include <stddef.h>
+
+struct file_handle;
+struct dfm_writer *dfm_open_writer (struct file_handle *);
+void dfm_close_writer (struct dfm_writer *);
+int dfm_put_record (struct dfm_writer *, const char *rec, size_t len);
+
+#endif /* dfm-write.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., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
-
-#include <config.h>
-#include "error.h"
-#include "dfm.h"
-#include <ctype.h>
-#include <errno.h>
-#include <stdlib.h>
-#include "alloc.h"
-#include "command.h"
-#include "error.h"
-#include "file-handle.h"
-#include "filename.h"
-#include "getline.h"
-#include "lexer.h"
-#include "misc.h"
-#include "str.h"
-#include "vfm.h"
-
-#include "debug-print.h"
-
-/* Flags for DFM readers. */
-enum dfm_reader_flags
- {
- DFM_EOF = 001, /* At end-of-file? */
- DFM_ADVANCE = 002, /* Read next line on dfm_get_record() call? */
- DFM_SAW_BEGIN_DATA = 004, /* For inline_file only, whether we've
- already read a BEGIN DATA line. */
- DFM_TABS_EXPANDED = 010, /* Tabs have been expanded. */
- };
-
-/* file_handle extension structure. */
-struct dfm_reader_ext
- {
- 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_*. */
- };
-
-static struct fh_ext_class dfm_r_class;
-
-static void read_record (struct file_handle *h);
-
-/* Asserts that H represents a DFM reader and returns H->ext
- converted to a struct dfm_reader_ext *. */
-static inline struct dfm_reader_ext *
-get_reader (struct file_handle *h)
-{
- assert (h != NULL);
- assert (h->class == &dfm_r_class);
- assert (h->ext != NULL);
-
- return h->ext;
-}
-
-/* Closes file handle H opened by dfm_open_for_reading(). */
-static void
-close_reader (struct file_handle *h)
-{
- struct dfm_reader_ext *ext = get_reader (h);
-
- /* Skip any remaining data on the inline file. */
- if (h == inline_file)
- while ((ext->flags & DFM_EOF) == 0)
- read_record (h);
-
- msg (VM (2), _("%s: Closing data-file handle %s."),
- handle_get_filename (h), handle_get_name (h));
- assert (h->class == &dfm_r_class);
- if (ext->file.file)
- {
- fn_close_ext (&ext->file);
- free (ext->file.filename);
- ext->file.filename = NULL;
- }
- ds_destroy (&ext->line);
- ds_destroy (&ext->scratch);
- free (ext);
-}
-
-/* Opens a file handle for reading as a data file. Returns
- nonzero only if successful. */
-int
-dfm_open_for_reading (struct file_handle *h)
-{
- struct dfm_reader_ext *ext;
-
- if (h->class != NULL)
- {
- if (h->class == &dfm_r_class)
- return 1;
- else
- {
- msg (ME, _("Cannot read from file %s already opened for %s."),
- handle_get_name (h), gettext (h->class->name));
- return 0;
- }
- }
-
- ext = xmalloc (sizeof *ext);
- ext->where.filename = handle_get_filename (h);
- ext->where.line_number = 0;
- ext->file.file = NULL;
- ds_init (&ext->line, 64);
- ds_init (&ext->scratch, 0);
- ext->flags = DFM_ADVANCE;
-
- msg (VM (1), _("%s: Opening data-file handle %s for reading."),
- handle_get_filename (h), handle_get_name (h));
-
- assert (h != NULL);
- if (h != inline_file)
- {
- ext->file.filename = xstrdup (handle_get_filename (h));
- ext->file.mode = "rb";
- ext->file.file = NULL;
- ext->file.sequence_no = NULL;
- ext->file.param = NULL;
- ext->file.postopen = NULL;
- ext->file.preclose = NULL;
- if (!fn_open_ext (&ext->file))
- {
- msg (ME, _("Could not open \"%s\" for reading "
- "as a data file: %s."),
- handle_get_filename (h), strerror (errno));
- goto error;
- }
- }
-
- h->class = &dfm_r_class;
- h->ext = ext;
- return 1;
-
- error:
- err_cond_fail ();
- free (ext);
- return 0;
-}
-
-/* Reads a record from H->EXT->FILE into H->EXT->LINE, setting
- H->EXT->PTR to H->EXT->LINE, and setting H->EXT-LEN to the length
- of the line. The line is not null-terminated. If an error occurs
- or end-of-file is encountered, H->EXT->LINE is set to NULL. */
-static void
-read_record (struct file_handle *h)
-{
- struct dfm_reader_ext *ext = get_reader (h);
-
- if (h == inline_file)
- {
- if ((ext->flags & DFM_SAW_BEGIN_DATA) == 0)
- {
- char *s;
-
- ext->flags |= DFM_SAW_BEGIN_DATA;
-
- /* FIXME: WTF can't this just be done with tokens?
- Is this really a special case? */
- do
- {
- char *cp;
-
- if (!getl_read_line ())
- {
- msg (SE, _("BEGIN DATA expected."));
- err_failure ();
- }
-
- /* Skip leading whitespace, separate out first
- word, so that S points to a single word reduced
- to lowercase. */
- s = ds_c_str (&getl_buf);
- while (isspace ((unsigned char) *s))
- s++;
- for (cp = s; isalpha ((unsigned char) *cp); cp++)
- *cp = tolower ((unsigned char) (*cp));
- ds_truncate (&getl_buf, cp - s);
- }
- while (*s == '\0');
-
- if (!lex_id_match_len ("begin", 5, s, strcspn (s, " \t\r\v\n")))
- {
- msg (SE, _("BEGIN DATA expected."));
- lex_preprocess_line ();
- goto eof;
- }
- getl_prompt = GETL_PRPT_DATA;
- }
-
- if (!getl_read_line ())
- {
- msg (SE, _("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."));
- err_failure ();
- }
-
- ext->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));
- goto eof;
- }
-
- ds_replace (&ext->line, ds_c_str (&getl_buf));
- }
- else
- {
- if (handle_get_mode (h) == MODE_TEXT)
- {
- ds_clear (&ext->line);
- if (!ds_gets (&ext->line, ext->file.file))
- {
- if (ferror (ext->file.file))
- {
- msg (ME, _("Error reading file %s: %s."),
- handle_get_name (h), strerror (errno));
- err_cond_fail ();
- }
- goto eof;
- }
- }
- else if (handle_get_mode (h) == MODE_BINARY)
- {
- size_t record_width = handle_get_record_width (h);
- size_t amt;
-
- if (ds_length (&ext->line) < record_width)
- ds_rpad (&ext->line, record_width, 0);
-
- amt = fread (ds_c_str (&ext->line), 1, record_width,
- ext->file.file);
- if (record_width != amt)
- {
- if (ferror (ext->file.file))
- msg (ME, _("Error reading file %s: %s."),
- handle_get_name (h), strerror (errno));
- else if (amt != 0)
- msg (ME, _("%s: Partial record at end of file."),
- handle_get_name (h));
- else
- goto eof;
-
- err_cond_fail ();
- goto eof;
- }
- }
- else
- assert (0);
-
- ext->where.line_number++;
- }
-
- ext->pos = 0;
- return;
-
-eof:
- /* Hit eof or an error, clean up everything. */
- ext->flags |= DFM_EOF;
-}
-
-/* Returns nonzero if end of file has been reached on HANDLE.
- Reads forward in HANDLE's file, if necessary to tell. */
-int
-dfm_eof (struct file_handle *h)
-{
- struct dfm_reader_ext *ext = get_reader (h);
- if (ext->flags & DFM_ADVANCE)
- {
- ext->flags &= ~DFM_ADVANCE;
- if ((ext->flags & DFM_EOF) == 0)
- read_record (h);
- else
- {
- msg (SE, _("Attempt to read beyond end-of-file on file %s."),
- handle_get_name (h));
- err_cond_fail ();
- }
- }
-
- return (ext->flags & DFM_EOF) != 0;
-}
-
-/* Returns the current record in the file corresponding to
- HANDLE. Aborts if reading from the file is necessary or at
- end of file, so call dfm_eof() first. Sets *LINE to the line,
- which is not null-terminated. The caller must not free or
- modify the returned string. */
-void
-dfm_get_record (struct file_handle *h, struct len_string *line)
-{
- struct dfm_reader_ext *ext = get_reader (h);
- assert ((ext->flags & DFM_ADVANCE) == 0);
- assert ((ext->flags & DFM_EOF) == 0);
- assert (ext->pos <= ds_length (&ext->line));
-
- line->string = ds_data (&ext->line) + ext->pos;
- line->length = ds_length (&ext->line) - ext->pos;
-}
-
-/* Expands tabs in the current line into the equivalent number of
- spaces, if appropriate for this kind of file. Aborts if
- reading from the file is necessary or at end of file, so call
- dfm_eof() first.*/
-void
-dfm_expand_tabs (struct file_handle *h)
-{
- struct dfm_reader_ext *ext = get_reader (h);
- struct string temp;
- size_t ofs, new_pos, tab_width;
-
- assert ((ext->flags & DFM_ADVANCE) == 0);
- assert ((ext->flags & DFM_EOF) == 0);
- assert (ext->pos <= ds_length (&ext->line));
-
- if (ext->flags & DFM_TABS_EXPANDED)
- return;
- ext->flags |= DFM_TABS_EXPANDED;
-
- if (handle_get_mode (h) == MODE_BINARY
- || handle_get_tab_width (h) == 0
- || memchr (ds_c_str (&ext->line), '\t', ds_length (&ext->line)) == NULL)
- return;
-
- /* Expand tabs from ext->line into ext->scratch, and figure out
- new value for ext->pos. */
- tab_width = handle_get_tab_width (h);
- ds_clear (&ext->scratch);
- new_pos = 0;
- for (ofs = 0; ofs < ds_length (&ext->line); ofs++)
- {
- unsigned char c;
-
- if (ofs == ext->pos)
- new_pos = ds_length (&ext->scratch);
-
- c = ds_c_str (&ext->line)[ofs];
- if (c != '\t')
- ds_putc (&ext->scratch, c);
- else
- {
- do
- ds_putc (&ext->scratch, ' ');
- while (ds_length (&ext->scratch) % tab_width != 0);
- }
- }
-
- /* Swap ext->line and ext->scratch and set new ext->pos. */
- temp = ext->line;
- ext->line = ext->scratch;
- ext->scratch = temp;
- ext->pos = new_pos;
-}
-
-/* Causes dfm_get_record() to read in the next record the next time it
- is executed on file HANDLE. */
-void
-dfm_forward_record (struct file_handle *h)
-{
- struct dfm_reader_ext *ext = get_reader (h);
- ext->flags |= DFM_ADVANCE;
-}
-
-/* Cancels the effect of any previous dfm_fwd_record() executed
- on file HANDLE. Sets the current line to begin in the 1-based
- column COLUMN. */
-void
-dfm_reread_record (struct file_handle *h, size_t column)
-{
- struct dfm_reader_ext *ext = get_reader (h);
- ext->flags &= ~DFM_ADVANCE;
- if (column < 1)
- ext->pos = 0;
- else if (column > ds_length (&ext->line))
- ext->pos = ds_length (&ext->line);
- else
- ext->pos = column - 1;
-}
-
-/* Sets the current line to begin COLUMNS characters following
- the current start. */
-void
-dfm_forward_columns (struct file_handle *h, size_t columns)
-{
- struct dfm_reader_ext *ext = get_reader (h);
- dfm_reread_record (h, (ext->pos + 1) + columns);
-}
-
-/* Returns the 1-based column to which the line pointer in HANDLE
- is set. Unless dfm_reread_record() or dfm_forward_columns()
- have been called, this is 1. */
-size_t
-dfm_column_start (struct file_handle *h)
-{
- struct dfm_reader_ext *ext = get_reader (h);
- return ext->pos + 1;
-}
-
-/* Pushes the filename and line number on the fn/ln stack. */
-void
-dfm_push (struct file_handle *h)
-{
- struct dfm_reader_ext *ext = get_reader (h);
- if (h != inline_file)
- err_push_file_locator (&ext->where);
-}
-
-/* Pops the filename and line number from the fn/ln stack. */
-void
-dfm_pop (struct file_handle *h)
-{
- struct dfm_reader_ext *ext = get_reader (h);
- if (h != inline_file)
- err_pop_file_locator (&ext->where);
-}
-
-/* DFM reader class. */
-static struct fh_ext_class dfm_r_class =
-{
- 1,
- N_("reading as a data file"),
- close_reader,
-};
-\f
-/* file_handle extension structure. */
-struct dfm_writer_ext
- {
- struct file_ext file; /* Associated file. */
- struct file_locator where; /* Current location in data file. */
- char *bounce; /* Bounce buffer for fixed-size fields. */
- };
-
-static struct fh_ext_class dfm_w_class;
-
-/* Opens a file handle for writing as a data file. */
-int
-dfm_open_for_writing (struct file_handle *h)
-{
- struct dfm_writer_ext *ext;
-
- if (h->class != NULL)
- {
- if (h->class == &dfm_w_class)
- return 1;
- else
- {
- msg (ME, _("Cannot write to file %s already opened for %s."),
- handle_get_name (h), gettext (h->class->name));
- err_cond_fail ();
- return 0;
- }
- }
-
- ext = xmalloc (sizeof *ext);
- ext->where.filename = handle_get_filename (h);
- ext->where.line_number = 0;
- ext->file.file = NULL;
- ext->bounce = NULL;
-
- msg (VM (1), _("%s: Opening data-file handle %s for writing."),
- handle_get_filename (h), handle_get_name (h));
-
- assert (h != NULL);
- if (h == inline_file)
- {
- msg (ME, _("Cannot open the inline file for writing."));
- goto error;
- }
-
- ext->file.filename = xstrdup (handle_get_filename (h));
- ext->file.mode = "wb";
- ext->file.file = NULL;
- ext->file.sequence_no = NULL;
- ext->file.param = NULL;
- ext->file.postopen = NULL;
- ext->file.preclose = NULL;
-
- if (!fn_open_ext (&ext->file))
- {
- msg (ME, _("An error occurred while opening \"%s\" for writing "
- "as a data file: %s."),
- handle_get_filename (h), strerror (errno));
- goto error;
- }
-
- h->class = &dfm_w_class;
- h->ext = ext;
- return 1;
-
- error:
- free (ext);
- err_cond_fail ();
- return 0;
-}
-
-/* Writes record REC having length LEN to the file corresponding to
- HANDLE. REC is not null-terminated. Returns nonzero on success,
- zero on failure. */
-int
-dfm_put_record (struct file_handle *h, const char *rec, size_t len)
-{
- struct dfm_writer_ext *ext;
-
- assert (h != NULL);
- assert (h->class == &dfm_w_class);
- assert (h->ext != NULL);
-
- ext = h->ext;
- if (handle_get_mode (h) == MODE_BINARY && len < handle_get_record_width (h))
- {
- size_t rec_width = handle_get_record_width (h);
- if (ext->bounce == NULL)
- ext->bounce = xmalloc (rec_width);
- memcpy (ext->bounce, rec, len);
- memset (&ext->bounce[len], 0, rec_width - len);
- rec = ext->bounce;
- len = rec_width;
- }
-
- if (fwrite (rec, len, 1, ext->file.file) != 1)
- {
- msg (ME, _("Error writing file %s: %s."),
- handle_get_name (h), strerror (errno));
- err_cond_fail ();
- return 0;
- }
-
- return 1;
-}
-
-/* Closes file handle H opened by dfm_open_for_writing(). */
-static void
-close_writer (struct file_handle *h)
-{
- struct dfm_writer_ext *ext;
-
- assert (h->class == &dfm_w_class);
- ext = h->ext;
-
- msg (VM (2), _("%s: Closing data-file handle %s."),
- handle_get_filename (h), handle_get_name (h));
- if (ext->file.file)
- {
- fn_close_ext (&ext->file);
- free (ext->file.filename);
- ext->file.filename = NULL;
- }
- free (ext->bounce);
- free (ext);
-}
-
-/* DFM writer class. */
-static struct fh_ext_class dfm_w_class =
-{
- 2,
- N_("writing as a data file"),
- close_writer,
-};
-\f
-/* BEGIN DATA...END DATA procedure. */
-
-/* Perform BEGIN DATA...END DATA as a procedure in itself. */
-int
-cmd_begin_data (void)
-{
- struct dfm_reader_ext *ext;
-
- /* FIXME: figure out the *exact* conditions, not these really
- lenient conditions. */
- if (vfm_source == NULL
- || case_source_is_class (vfm_source, &storage_source_class))
- {
- msg (SE, _("This command is not valid here since the current "
- "input program does not access the inline file."));
- err_cond_fail ();
- return CMD_FAILURE;
- }
-
- /* Initialize inline_file. */
- msg (VM (1), _("inline file: Opening for reading."));
- dfm_open_for_reading (inline_file);
- ext = inline_file->ext;
- ext->flags |= DFM_SAW_BEGIN_DATA;
-
- /* We don't actually read from the inline file. The input procedure
- is what reads from it. */
- getl_prompt = GETL_PRPT_DATA;
- procedure (NULL, NULL);
-
- ext = inline_file->ext;
- if (ext && (ext->flags & DFM_EOF) == 0)
- {
- msg (MW, _("Skipping remaining inline data."));
- while ((ext->flags & DFM_EOF) == 0)
- read_record (inline_file);
- }
- assert (inline_file->ext == NULL);
-
- return CMD_SUCCESS;
-}
+++ /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., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
-
-#if !dfm_h
-#define dfm_h 1
-
-/* Data file manager (dfm).
-
- This module is in charge of reading and writing data files (other
- than system files). dfm is an fhuser, so see file-handle.h for the
- fhuser interface. */
-
-#include <stddef.h>
-
-struct file_handle;
-struct len_string;
-
-/* Input. */
-int dfm_open_for_reading (struct file_handle *);
-int dfm_eof (struct file_handle *);
-void dfm_get_record (struct file_handle *, struct len_string *);
-void dfm_expand_tabs (struct file_handle *);
-
-void dfm_forward_record (struct file_handle *);
-void dfm_reread_record (struct file_handle *, size_t column);
-void dfm_forward_columns (struct file_handle *, size_t columns);
-size_t dfm_column_start (struct file_handle *);
-
-/* Output. */
-int dfm_open_for_writing (struct file_handle *);
-int dfm_put_record (struct file_handle *, const char *rec, size_t len);
-
-/* File stack. */
-void dfm_push (struct file_handle *);
-void dfm_pop (struct file_handle *);
-
-#endif /* dfm_h */
02111-1307, USA. */
#include <config.h>
-#include "error.h"
+#include "dictionary.h"
#include <stdlib.h>
#include "algorithm.h"
#include "alloc.h"
#include "case.h"
+#include "error.h"
#include "hash.h"
#include "misc.h"
#include "str.h"
for (i = 0; i < d->var_cnt; i++)
{
struct variable *v = d->var[i];
+ var_clear_aux (v);
val_labs_destroy (v->val_labs);
free (v->label);
free (v);
dict_clear_vectors (d);
}
+/* Destroys the aux data for every variable in D, by calling
+ var_clear_aux() for each variable. */
+void
+dict_clear_aux (struct dictionary *d)
+{
+ int i;
+
+ assert (d != NULL);
+
+ for (i = 0; i < d->var_cnt; i++)
+ var_clear_aux (d->var[i]);
+}
+
/* Clears a dictionary and destroys it. */
void
dict_destroy (struct dictionary *d)
v->write = v->print;
v->val_labs = val_labs_create (v->width);
v->label = NULL;
+ v->aux = NULL;
+ v->aux_dtor = NULL;
/* Update dictionary. */
if (d->var_cnt >= d->var_cap)
assert (dict_contains_var (d, v));
assert (d->var[v->index] == v);
- /* Remove v from splits, weight, filter variables. */
+ /* Delete aux data. */
+ var_clear_aux (v);
+
+ /* Remove V from splits, weight, filter variables. */
d->split_cnt = remove_equal (d->split, d->split_cnt, sizeof *d->split,
&v,
compare_variable_dblptrs, NULL);
d->filter = NULL;
dict_clear_vectors (d);
- /* Remove v from var array. */
+ /* Remove V from var array. */
d->var_cnt--;
memmove (d->var + v->index, d->var + v->index + 1,
(d->var_cnt - v->index) * sizeof *d->var);
--- /dev/null
+/* PSPP - computes sample statistics.
+ Copyright (C) 2004 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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef DICTIONARY_H
+#define DICTIONARY_H
+
+#include <stddef.h>
+
+/* Dictionary. */
+
+struct variable;
+struct dictionary *dict_create (void);
+struct dictionary *dict_clone (const struct dictionary *);
+void dict_clear (struct dictionary *);
+void dict_clear_aux (struct dictionary *);
+void dict_destroy (struct dictionary *);
+
+size_t dict_get_var_cnt (const struct dictionary *);
+struct variable *dict_get_var (const struct dictionary *, size_t idx);
+void dict_get_vars (const struct dictionary *,
+ struct variable ***vars, size_t *cnt,
+ unsigned exclude_classes);
+
+struct variable *dict_create_var (struct dictionary *, const char *,
+ int width);
+struct variable *dict_create_var_assert (struct dictionary *, const char *,
+ int width);
+struct variable *dict_clone_var (struct dictionary *, const struct variable *,
+ const char *);
+void dict_rename_var (struct dictionary *, struct variable *, const char *);
+
+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 *);
+void dict_delete_var (struct dictionary *, struct variable *);
+void dict_delete_vars (struct dictionary *,
+ struct variable *const *, size_t count);
+void dict_reorder_vars (struct dictionary *,
+ struct variable *const *, size_t count);
+int 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 *);
+double dict_get_case_weight (const struct dictionary *,
+ const struct ccase *, int *);
+void dict_set_weight (struct dictionary *, struct variable *);
+
+struct variable *dict_get_filter (const struct dictionary *);
+void dict_set_filter (struct dictionary *, struct variable *);
+
+int dict_get_case_limit (const struct dictionary *);
+void dict_set_case_limit (struct dictionary *, int);
+
+int dict_get_next_value_idx (const struct dictionary *);
+size_t dict_get_case_size (const struct dictionary *);
+
+void dict_compact_values (struct dictionary *);
+size_t dict_get_compacted_value_cnt (const struct dictionary *);
+int *dict_get_compacted_idx_to_fv (const struct dictionary *);
+
+struct variable *const *dict_get_split_vars (const struct dictionary *);
+size_t dict_get_split_cnt (const struct dictionary *);
+void dict_set_split_vars (struct dictionary *,
+ struct variable *const *, size_t cnt);
+
+const char *dict_get_label (const struct dictionary *);
+void dict_set_label (struct dictionary *, const char *);
+
+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);
+const struct vector *dict_get_vector (const struct dictionary *,
+ size_t idx);
+size_t dict_get_vector_cnt (const struct dictionary *);
+const struct vector *dict_lookup_vector (const struct dictionary *,
+ const char *name);
+void dict_clear_vectors (struct dictionary *);
+
+#endif /* dictionary.h */
#include "alloc.h"
#include "str.h"
#include "case.h"
+#include "dictionary.h"
#include "command.h"
#include "lexer.h"
#include "error.h"
#include "hash.h"
#include "casefile.h"
#include "factor_stats.h"
+/* (headers) */
#include "chart.h"
/* (specification)
/* Per Split function */
-static void run_examine(const struct casefile *cf, void *cmd_);
+static void run_examine(const struct casefile *cf, void *);
static void output_examine(void);
totals->stats = xmalloc(sizeof ( struct metrics ) * n_dependent_vars);
- multipass_procedure_with_splits (run_examine, &cmd);
+ multipass_procedure_with_splits (run_examine, NULL);
hsh_destroy(hash_table_factors);
static void
-run_examine(const struct casefile *cf, void *cmd_)
+run_examine(const struct casefile *cf, void *aux UNUSED)
{
struct hsh_iterator hi;
struct factor *fctr;
struct ccase c;
int v;
- const struct cmd_examine *cmd = (struct cmd_examine *) cmd_;
-
/* Make sure we haven't got rubbish left over from a
previous split */
if ( hash_table_factors )
#include <stdio.h>
#include "case.h"
#include "data-in.h"
+#include "dictionary.h"
#include "error.h"
#include "julcal/julcal.h"
#include "magic.h"
02111-1307, USA. */
#include <config.h>
+#include "dictionary.h"
#include "expr.h"
#include "exprP.h"
#include "error.h"
#if !file_handle_h
#define file_handle_h 1
-/* File handle provider (fhp).
-
- This module provides file handles in the form of file_handle
- structures to the dfm and sfm modules, which are known as file
- handle users (fhusers). fhp does not know anything about file
- contents. */
+/* File handles. */
#include <stddef.h>
-#include "error.h"
-
-struct file_handle;
-
-/* Services that fhusers provide to fhp. */
-struct fh_ext_class
- {
- int magic; /* Magic identifier for fhuser. */
- const char *name; /* String identifier for fhuser. */
-
- void (*close) (struct file_handle *); /* Closes the file. */
- };
-
-/* Mostly-opaque structure. */
-struct file_handle
- {
- struct private_file_handle *private;
- const struct fh_ext_class *class; /* Polymorphism support. */
- void *ext; /* Extension struct for fhuser use. */
- };
/* File modes. */
enum file_handle_mode
MODE_BINARY /* Fixed-length records. */
};
-/* Pointer to the file handle that corresponds to data in the command
- file entered via BEGIN DATA/END DATA. */
-extern struct file_handle *inline_file;
-
-/* Initialization. */
-void fh_init_files (void);
+/* Parsing handles. */
+struct file_handle *fh_parse (void);
/* Opening and closing handles. */
-struct file_handle *fh_parse_file_handle (void);
-void fh_close_handle (struct file_handle *handle);
+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 *handle);
-const char *handle_get_filename (const struct file_handle *handle);
+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 *);
#include "var.h"
/* (headers) */
-/* File handle private data. */
-struct private_file_handle
+/* 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. */
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. */
- };
-/* Linked list of file handles. */
-struct file_handle_list
- {
- struct file_handle *handle;
- struct file_handle_list *next;
+ int open_cnt; /* 0=not open, otherwise # of openers. */
+ const char *type; /* If open, type of file. */
+ const char *open_mode; /* "[rw][se]". */
+ void *aux; /* Aux data pointer for owner if any. */
};
-static struct file_handle_list *file_handles;
-struct file_handle *inline_file;
+static struct file_handle *file_handles;
static struct file_handle *create_file_handle (const char *handle_name,
const char *filename);
static struct file_handle *
get_handle_with_name (const char *handle_name)
{
- struct file_handle_list *iter;
+ struct file_handle *iter;
for (iter = file_handles; iter != NULL; iter = iter->next)
- if (!strcmp (handle_name, iter->handle->private->name))
- return iter->handle;
+ if (!strcmp (handle_name, iter->name))
+ return iter;
return NULL;
}
get_handle_for_filename (const char *filename)
{
struct file_identity *identity;
- struct file_handle_list *iter;
+ 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->handle->private->identity != NULL
- && !fn_compare_file_identities (identity,
- iter->handle->private->identity))
+ if (iter->identity != NULL
+ && !fn_compare_file_identities (identity, iter->identity))
{
fn_free_identity (identity);
- return iter->handle;
+ 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->handle->private->filename))
- return iter->handle;
+ if (!strcmp (filename, iter->filename))
+ return iter;
return NULL;
}
msg (SE, _("File handle %s already refers to "
"file %s. File handle cannot be redefined within a "
"session."),
- tokid, handle->private->filename);
+ tokid, handle->filename);
return CMD_FAILURE;
}
switch (cmd.mode)
{
case FH_CHARACTER:
- handle->private->mode = MODE_TEXT;
+ handle->mode = MODE_TEXT;
if (cmd.sbc_tabwidth)
- handle->private->tab_width = cmd.n_tabwidth;
+ handle->tab_width = cmd.n_tabwidth[0];
else
- handle->private->tab_width = 4;
+ handle->tab_width = 4;
break;
case FH_IMAGE:
- handle->private->mode = MODE_BINARY;
- if (cmd.n_lrecl == NOT_LONG)
+ handle->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->private->length = 1024;
+ handle->length = 1024;
}
- else if (cmd.n_lrecl < 1)
+ 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);
- handle->private->length = 1;
+ handle->length = 1;
}
else
- handle->private->length = cmd.n_lrecl;
+ handle->length = cmd.n_lrecl[0];
break;
default:
assert (0);
create_file_handle (const char *handle_name, const char *filename)
{
struct file_handle *handle;
- struct file_handle_list *list;
/* Create and initialize file handle. */
handle = xmalloc (sizeof *handle);
- handle->private = xmalloc (sizeof *handle->private);
- handle->private->name = xstrdup (handle_name);
- handle->private->filename = xstrdup (filename);
- handle->private->identity = fn_get_identity (filename);
- handle->private->where.filename = handle->private->filename;
- handle->private->where.line_number = 0;
- handle->private->mode = MODE_TEXT;
- handle->private->length = 1024;
- handle->private->tab_width = 4;
- handle->ext = NULL;
- handle->class = NULL;
-
- /* Add file handle to global list. */
- list = xmalloc (sizeof *list);
- list->handle = handle;
- list->next = file_handles;
- file_handles = list;
+ 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->open_mode = NULL;
+ handle->aux = NULL;
+ file_handles = handle;
return handle;
}
-/* Closes the stdio FILE associated with handle H. Frees internal
- buffers associated with that file. Does *not* destroy the file
- handle H. (File handles are permanent during a session.) */
-void
-fh_close_handle (struct file_handle *h)
+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 FILE 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, references to type and mode are retained, so
+ they should probably be string literals. */
+void **
+fh_open (struct file_handle *h, const char *type, const char *mode)
{
- if (h == NULL)
- return;
+ 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);
+ 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));
+ 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));
+ }
+ else
+ {
+ h->type = type;
+ h->open_mode = mode;
+ assert (h->aux == NULL);
+ }
+ h->open_cnt++;
- if (h->class != NULL)
- h->class->close (h);
- h->class = NULL;
- h->ext = NULL;
+ return &h->aux;
}
-/* Initialize the hash of file handles; inserts the "inline file"
- inline_file. */
-void
-fh_init_files (void)
+/* 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)
{
- if (inline_file == NULL)
+ 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)
{
- inline_file = create_file_handle ("INLINE", _("<Inline File>"));
- inline_file->private->length = 80;
+ h->type = NULL;
+ h->open_mode = NULL;
+ h->aux = NULL;
}
+ return h->open_cnt;
}
/* 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_file_handle (void)
+fh_parse (void)
{
struct file_handle *handle;
const char *
handle_get_name (const struct file_handle *handle)
{
- return handle->private->name;
+ 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)
{
- return handle->private->filename;
+ assert (handle != NULL);
+ return handle->filename;
}
/* Returns the mode of HANDLE. */
handle_get_mode (const struct file_handle *handle)
{
assert (handle != NULL);
- return handle->private->mode;
+ return handle->mode;
}
/* Returns the width of a logical record on HANDLE. Applicable
handle_get_record_width (const struct file_handle *handle)
{
assert (handle != NULL);
- return handle->private->length;
+ return handle->length;
}
/* Returns the number of characters per tab stop for HANDLE, or
handle_get_tab_width (const struct file_handle *handle)
{
assert (handle != NULL);
- return handle->private->tab_width;
+ return handle->tab_width;
}
/*
02111-1307, USA. */
#include <config.h>
-#include "error.h"
#include <stdlib.h>
#include "alloc.h"
#include "case.h"
#include "command.h"
#include "data-in.h"
-#include "dfm.h"
+#include "dfm-read.h"
+#include "dictionary.h"
+#include "error.h"
#include "file-handle.h"
#include "format.h"
#include "lexer.h"
struct file_type_pgm
{
int type; /* One of the FTY_* constants. */
- struct file_handle *handle; /* File handle of input file. */
+ struct dfm_reader *reader; /* Data file to read. */
struct col_spec record; /* RECORD subcommand. */
struct col_spec case_sbc; /* CASE subcommand. */
int wild; /* 0=NOWARN, 1=WARN. */
int
cmd_file_type (void)
{
- static struct file_type_pgm *fty;
+ static struct file_type_pgm *fty; /* FIXME: static? WTF? */
+ struct file_handle *fh = NULL;
/* Initialize. */
discard_variables ();
fty = xmalloc (sizeof *fty);
- fty->handle = inline_file;
+ fty->reader = NULL;
fty->record.name[0] = 0;
fty->case_sbc.name[0] = 0;
fty->wild = fty->duplicate = fty->missing = fty->ordered = 0;
if (lex_match_id ("FILE"))
{
lex_match ('=');
- fty->handle = fh_parse_file_handle ();
- if (!fty->handle)
+ fh = fh_parse ();
+ if (fh == NULL)
goto error;
}
else if (lex_match_id ("RECORD"))
}
}
- if (!dfm_open_for_reading (fty->handle))
+ fty->reader = dfm_open_reader (fh);
+ if (fty->reader == NULL)
goto error;
- default_handle = fty->handle;
+ default_handle = fh;
create_col_var (&fty->record);
if (fty->case_sbc.name[0])
struct file_type_pgm *fty = source->aux;
struct fmt_spec format;
- dfm_push (fty->handle);
+ dfm_push (fty->reader);
format.type = fty->record.fmt;
format.w = fty->record.nc;
format.d = 0;
- while (!dfm_eof (fty->handle))
+ while (!dfm_eof (fty->reader))
{
struct len_string line;
struct record_type *iter;
union value v;
int i;
- dfm_expand_tabs (fty->handle);
- dfm_get_record (fty->handle, &line);
+ dfm_expand_tabs (fty->reader);
+ dfm_get_record (fty->reader, &line);
if (formats[fty->record.fmt].cat & FCAT_STRING)
{
struct data_in di;
if (fty->wild)
msg (SW, _("Unknown record type %g."), v.f);
}
- dfm_forward_record (fty->handle);
+ dfm_forward_record (fty->reader);
continue;
found:
/* Arrive here if there is a matching record_type, which is in
iter. */
- dfm_forward_record (fty->handle);
+ dfm_forward_record (fty->reader);
}
/* switch(fty->type)
default: assert(0);
} */
- dfm_pop (fty->handle);
+ dfm_pop (fty->reader);
}
static void
struct record_type *iter, *next;
cancel_transformations ();
+ dfm_close_reader (fty->reader);
for (iter = fty->recs_head; iter; iter = next)
{
next = iter->next;
#include "alloc.h"
#include "case.h"
#include "command.h"
+#include "dictionary.h"
#include "error.h"
#include "lexer.h"
#include "misc.h"
#include "alloc.h"
#include "bitvector.h"
#include "case.h"
+#include "dictionary.h"
#include "hash.h"
#include "pool.h"
#include "command.h"
#include "vfm.h"
#include "settings.h"
#include "chart.h"
+/* (headers) */
#include "debug-print.h"
/* (declarations) */
/* (functions) */
+/* Statistics. */
+enum
+ {
+ frq_mean = 0, frq_semean, frq_median, frq_mode, frq_stddev, frq_variance,
+ frq_kurt, frq_sekurt, frq_skew, frq_seskew, frq_range, frq_min, frq_max,
+ frq_sum, frq_n_stats
+ };
+
/* Description of a statistic. */
struct frq_info
{
static void add_percentile (double x) ;
-
static struct percentile *percentiles;
static int n_percentiles;
static struct pool *int_pool; /* Integer mode. */
static struct pool *gen_pool; /* General mode. */
-/* Easier access to a_statistics. */
-#define stat cmd.a_statistics
+/* Per-variable frequency data. */
+struct var_freqs
+ {
+ /* Freqency table. */
+ struct freq_tab tab; /* Frequencies table to use. */
+
+ /* Percentiles. */
+ int n_groups; /* Number of groups. */
+ double *groups; /* Groups. */
+
+ /* Statistics. */
+ double stat[frq_n_stats];
+ };
+
+static inline struct var_freqs *
+get_var_freqs (struct variable *v)
+{
+ assert (v != NULL);
+ assert (v->aux != NULL);
+ return v->aux;
+}
static void determine_charts (void);
-static void calc_stats (struct variable * v, double d[frq_n_stats]);
+static void calc_stats (struct variable *v, double d[frq_n_stats]);
static void precalc (void *);
static int calc (struct ccase *, void *);
n_variables = 0;
v_variables = NULL;
- for (i = 0; i < dict_get_var_cnt (default_dict); i++)
- dict_get_var(default_dict, i)->p.frq.used = 0;
-
if (!parse_frequencies (&cmd))
return CMD_FAILURE;
/* Figure out statistics to calculate. */
stats = 0;
- if (stat[FRQ_ST_DEFAULT] || !cmd.sbc_statistics)
+ if (cmd.a_statistics[FRQ_ST_DEFAULT] || !cmd.sbc_statistics)
stats |= frq_default;
- if (stat[FRQ_ST_ALL])
+ if (cmd.a_statistics[FRQ_ST_ALL])
stats |= frq_all;
if (cmd.sort != FRQ_AVALUE && cmd.sort != FRQ_DVALUE)
stats &= ~frq_median;
for (i = 0; i < frq_n_stats; i++)
- if (stat[st_name[i].st_indx])
+ if (cmd.a_statistics[st_name[i].st_indx])
stats |= BIT_INDEX (i);
if (stats & frq_kurt)
stats |= frq_sekurt;
{
struct variable *v = v_variables[i];
const union value *val = case_data (c, v->fv);
- struct freq_tab *ft = &v->p.frq.tab;
+ struct freq_tab *ft = &get_var_freqs (v)->tab;
- switch (v->p.frq.tab.mode)
+ switch (ft->mode)
{
case FRQM_GENERAL:
{
case FRQM_INTEGER:
/* Integer mode. */
if (val->f == SYSMIS)
- v->p.frq.tab.sysmis += weight;
+ ft->sysmis += weight;
else if (val->f > INT_MIN+1 && val->f < INT_MAX-1)
{
int i = val->f;
- if (i >= v->p.frq.tab.min && i <= v->p.frq.tab.max)
- v->p.frq.tab.vector[i - v->p.frq.tab.min] += weight;
+ if (i >= ft->min && i <= ft->max)
+ ft->vector[i - ft->min] += weight;
}
else
- v->p.frq.tab.out_of_range += weight;
+ ft->out_of_range += weight;
break;
default:
assert (0);
for (i = 0; i < n_variables; i++)
{
struct variable *v = v_variables[i];
+ struct freq_tab *ft = &get_var_freqs (v)->tab;
- if (v->p.frq.tab.mode == FRQM_GENERAL)
+ if (ft->mode == FRQM_GENERAL)
{
hsh_hash_func *hash;
hsh_compare_func *compare;
hash = hash_value_alpha;
compare = compare_value_alpha_a;
}
- v->p.frq.tab.data = hsh_create (16, compare, hash, NULL, v);
+ ft->data = hsh_create (16, compare, hash, NULL, v);
}
else
{
int j;
- for (j = (v->p.frq.tab.max - v->p.frq.tab.min); j >= 0; j--)
- v->p.frq.tab.vector[j] = 0.0;
- v->p.frq.tab.out_of_range = 0.0;
- v->p.frq.tab.sysmis = 0.0;
+ for (j = (ft->max - ft->min); j >= 0; j--)
+ ft->vector[j] = 0.0;
+ ft->out_of_range = 0.0;
+ ft->sysmis = 0.0;
}
}
}
for (i = 0; i < n_variables; i++)
{
struct variable *v = v_variables[i];
+ struct var_freqs *vf = get_var_freqs (v);
+ struct freq_tab *ft = &vf->tab;
int n_categories;
int dumped_freq_tab = 1;
postprocess_freq_tab (v);
/* Frequencies tables. */
- n_categories = v->p.frq.tab.n_valid + v->p.frq.tab.n_missing;
+ n_categories = ft->n_valid + ft->n_missing;
if (cmd.table == FRQ_TABLE
|| (cmd.table == FRQ_LIMIT && n_categories <= cmd.limit))
switch (cmd.cond)
{
struct chart ch;
double d[frq_n_stats];
- struct frequencies_proc *frq = &v->p.frq;
struct normal_curve norm;
- norm.N = frq->tab.total_cases ;
+ norm.N = vf->tab.total_cases;
calc_stats(v,d);
norm.mean = d[frq_mean];
norm.stddev = d[frq_stddev];
chart_initialise(&ch);
- draw_histogram(&ch, v_variables[i], "HISTOGRAM",&norm,normal);
+ draw_histogram(&ch, v_variables[i], ft, "HISTOGRAM",&norm,normal);
chart_finalise(&ch);
}
chart_initialise(&ch);
- draw_piechart(&ch, v_variables[i]);
+ draw_piechart(&ch, v_variables[i], ft);
chart_finalise(&ch);
}
struct freq *freqs, *f;
size_t i;
- assert (v->p.frq.tab.mode == FRQM_GENERAL);
+ ft = &get_var_freqs (v)->tab;
+ assert (ft->mode == FRQM_GENERAL);
compare = get_freq_comparator (cmd.sort, v->type);
- ft = &v->p.frq.tab;
/* Extract data from hash table. */
count = hsh_count (ft->data);
static void
cleanup_freq_tab (struct variable *v)
{
- assert (v->p.frq.tab.mode == FRQM_GENERAL);
- free (v->p.frq.tab.valid);
- hsh_destroy (v->p.frq.tab.data);
+ struct freq_tab *ft = &get_var_freqs (v)->tab;
+ assert (ft->mode == FRQM_GENERAL);
+ free (ft->valid);
+ hsh_destroy (ft->data);
}
/* Parses the VARIABLES subcommand, adding to
PV_APPEND | PV_NO_SCRATCH))
return 0;
- for (i = old_n_variables; i < n_variables; i++)
- v_variables[i]->p.frq.tab.mode = FRQM_GENERAL;
-
if (!lex_match ('('))
mode = FRQM_GENERAL;
else
for (i = old_n_variables; i < n_variables; i++)
{
struct variable *v = v_variables[i];
+ struct var_freqs *vf;
- if (v->p.frq.used != 0)
+ if (v->aux != NULL)
{
msg (SE, _("Variable %s specified multiple times on VARIABLES "
"subcommand."), v->name);
return 0;
}
-
- v->p.frq.used = 1; /* Used simply as a marker. */
-
- v->p.frq.tab.valid = v->p.frq.tab.missing = NULL;
+ if (mode == FRQM_INTEGER && v->type != NUMERIC)
+ {
+ msg (SE, _("Integer mode specified, but %s is not a numeric "
+ "variable."), v->name);
+ return 0;
+ }
+ vf = var_attach_aux (v, xmalloc (sizeof *vf), var_dtor_free);
+ vf->tab.mode = mode;
+ vf->tab.valid = vf->tab.missing = NULL;
if (mode == FRQM_INTEGER)
{
- if (v->type != NUMERIC)
- {
- msg (SE, _("Integer mode specified, but %s is not a numeric "
- "variable."), v->name);
- return 0;
- }
-
- v->p.frq.tab.min = min;
- v->p.frq.tab.max = max;
- v->p.frq.tab.vector = pool_alloc (int_pool,
- sizeof (struct freq) * (max - min + 1));
+ vf->tab.min = min;
+ vf->tab.max = max;
+ vf->tab.vector = pool_alloc (int_pool,
+ sizeof (struct freq) * (max - min + 1));
}
else
- v->p.frq.tab.vector = NULL;
-
- v->p.frq.n_groups = 0;
- v->p.frq.groups = NULL;
+ vf->tab.vector = NULL;
+ vf->n_groups = 0;
+ vf->groups = NULL;
}
return 1;
}
-/* Parses the GROUPED subcommand, setting the frq.{n_grouped,grouped}
+/* Parses the GROUPED subcommand, setting the n_grouped, grouped
fields of specified variables. */
static int
frq_custom_grouped (struct cmd_frequencies *cmd UNUSED)
}
for (i = 0; i < n; i++)
- {
- if (v[i]->p.frq.used == 0)
- msg (SE, _("Variables %s specified on GROUPED but not on "
- "VARIABLES."), v[i]->name);
- if (v[i]->p.frq.groups != NULL)
- msg (SE, _("Variables %s specified multiple times on GROUPED "
- "subcommand."), v[i]->name);
- else
- {
- v[i]->p.frq.n_groups = nl;
- v[i]->p.frq.groups = dl;
- }
- }
+ if (v[i]->aux == NULL)
+ msg (SE, _("Variables %s specified on GROUPED but not on "
+ "VARIABLES."), v[i]->name);
+ else
+ {
+ struct var_freqs *vf = get_var_freqs (v[i]);
+
+ if (vf->groups != NULL)
+ msg (SE, _("Variables %s specified multiple times on GROUPED "
+ "subcommand."), v[i]->name);
+ else
+ {
+ vf->n_groups = nl;
+ vf->groups = dl;
+ }
+ }
free (v);
if (!lex_match ('/'))
break;
/* Displays a full frequency table for variable V. */
static void
-dump_full (struct variable * v)
+dump_full (struct variable *v)
{
int n_categories;
+ struct freq_tab *ft;
struct freq *f;
struct tab_table *t;
int r;
int lab = cmd.labels == FRQ_LABELS;
- n_categories = v->p.frq.tab.n_valid + v->p.frq.tab.n_missing;
+ ft = &get_var_freqs (v)->tab;
+ n_categories = ft->n_valid + ft->n_missing;
t = tab_create (5 + lab, n_categories + 3, 0);
tab_headers (t, 0, 0, 2, 0);
tab_dim (t, full_dim);
TAB_CENTER | TAT_TITLE, gettext (p->s));
r = 2;
- for (f = v->p.frq.tab.valid; f < v->p.frq.tab.missing; f++)
+ for (f = ft->valid; f < ft->missing; f++)
{
double percent, valid_percent;
cum_freq += f->c;
- percent = f->c / v->p.frq.tab.total_cases * 100.0;
- valid_percent = f->c / v->p.frq.tab.valid_cases * 100.0;
+ percent = f->c / ft->total_cases * 100.0;
+ valid_percent = f->c / ft->valid_cases * 100.0;
cum_total += valid_percent;
if (lab)
tab_float (t, 4 + lab, r, TAB_NONE, cum_total, 5, 1);
r++;
}
- for (; f < &v->p.frq.tab.valid[n_categories]; f++)
+ for (; f < &ft->valid[n_categories]; f++)
{
cum_freq += f->c;
tab_value (t, 0 + lab, r, TAB_NONE, &f->v, &v->print);
tab_float (t, 1 + lab, r, TAB_NONE, f->c, 8, 0);
tab_float (t, 2 + lab, r, TAB_NONE,
- f->c / v->p.frq.tab.total_cases * 100.0, 5, 1);
+ f->c / ft->total_cases * 100.0, 5, 1);
tab_text (t, 3 + lab, r, TAB_NONE, _("Missing"));
r++;
}
/* Display condensed frequency table for variable V. */
static void
-dump_condensed (struct variable * v)
+dump_condensed (struct variable *v)
{
int n_categories;
+ struct freq_tab *ft;
struct freq *f;
struct tab_table *t;
int r;
double cum_total = 0.0;
- n_categories = v->p.frq.tab.n_valid + v->p.frq.tab.n_missing;
+ ft = &get_var_freqs (v)->tab;
+ n_categories = ft->n_valid + ft->n_missing;
t = tab_create (4, n_categories + 2, 0);
tab_headers (t, 0, 0, 2, 0);
tab_dim (t, condensed_dim);
r = 2;
- for (f = v->p.frq.tab.valid; f < v->p.frq.tab.missing; f++)
+ for (f = ft->valid; f < ft->missing; f++)
{
double percent;
- percent = f->c / v->p.frq.tab.total_cases * 100.0;
- cum_total += f->c / v->p.frq.tab.valid_cases * 100.0;
+ percent = f->c / ft->total_cases * 100.0;
+ cum_total += f->c / ft->valid_cases * 100.0;
tab_value (t, 0, r, TAB_NONE, &f->v, &v->print);
tab_float (t, 1, r, TAB_NONE, f->c, 8, 0);
tab_float (t, 3, r, TAB_NONE, cum_total, 3, 0);
r++;
}
- for (; f < &v->p.frq.tab.valid[n_categories]; f++)
+ for (; f < &ft->valid[n_categories]; f++)
{
tab_value (t, 0, r, TAB_NONE, &f->v, &v->print);
tab_float (t, 1, r, TAB_NONE, f->c, 8, 0);
tab_float (t, 2, r, TAB_NONE,
- f->c / v->p.frq.tab.total_cases * 100.0, 3, 0);
+ f->c / ft->total_cases * 100.0, 3, 0);
r++;
}
/* Calculates all the pertinent statistics for variable V, putting
them in array D[]. FIXME: This could be made much more optimal. */
static void
-calc_stats (struct variable * v, double d[frq_n_stats])
+calc_stats (struct variable *v, double d[frq_n_stats])
{
- double W = v->p.frq.tab.valid_cases;
+ struct freq_tab *ft = &get_var_freqs (v)->tab;
+ double W = ft->valid_cases;
struct moments *m;
struct freq *f=0;
int most_often;
}
rank = 0;
- for (idx = 0; idx < v->p.frq.tab.n_valid; ++idx)
+ for (idx = 0; idx < ft->n_valid; ++idx)
{
static double prev_value = SYSMIS;
- f = &v->p.frq.tab.valid[idx];
+ f = &ft->valid[idx];
rank += f->c ;
for (i = 0; i < n_percentiles; i++)
{
if ( get_algorithm() != COMPATIBLE )
tp =
- (v->p.frq.tab.valid_cases - 1) * percentiles[i].p;
+ (ft->valid_cases - 1) * percentiles[i].p;
else
tp =
- (v->p.frq.tab.valid_cases + 1) * percentiles[i].p - 1;
+ (ft->valid_cases + 1) * percentiles[i].p - 1;
if ( percentiles[i].flag )
{
for (i = 0; i < n_percentiles; i++)
{
- struct freq_tab *ft = &v->p.frq.tab;
+ struct freq_tab *ft = &get_var_freqs (v)->tab;
double s;
double dummy;
if ( get_algorithm() != COMPATIBLE )
{
- s = modf((ft->valid_cases - 1) * percentiles[i].p , &dummy);
+ s = modf((ft->valid_cases - 1) * percentiles[i].p , &dummy);
}
else
{
- s = modf((ft->valid_cases + 1) * percentiles[i].p -1, &dummy);
+ s = modf((ft->valid_cases + 1) * percentiles[i].p -1, &dummy);
}
percentiles[i].value = percentiles[i].x1 +
/* Calculate the mode. */
most_often = -1;
X_mode = SYSMIS;
- for (f = v->p.frq.tab.valid; f < v->p.frq.tab.missing; f++)
+ for (f = ft->valid; f < ft->missing; f++)
{
if (most_often < f->c)
{
/* Calculate moments. */
m = moments_create (MOMENT_KURTOSIS);
- for (f = v->p.frq.tab.valid; f < v->p.frq.tab.missing; f++)
+ for (f = ft->valid; f < ft->missing; f++)
moments_pass_one (m, f->v.f, f->c);
- for (f = v->p.frq.tab.valid; f < v->p.frq.tab.missing; f++)
+ for (f = ft->valid; f < ft->missing; f++)
moments_pass_two (m, f->v.f, f->c);
moments_calculate (m, NULL, &d[frq_mean], &d[frq_variance],
&d[frq_skew], &d[frq_kurt]);
moments_destroy (m);
/* Formulas below are taken from _SPSS Statistical Algorithms_. */
- d[frq_min] = v->p.frq.tab.valid[0].v.f;
- d[frq_max] = v->p.frq.tab.valid[v->p.frq.tab.n_valid - 1].v.f;
+ d[frq_min] = ft->valid[0].v.f;
+ d[frq_max] = ft->valid[ft->n_valid - 1].v.f;
d[frq_mode] = X_mode;
d[frq_range] = d[frq_max] - d[frq_min];
d[frq_median] = *median_value;
/* Displays a table of all the statistics requested for variable V. */
static void
-dump_statistics (struct variable * v, int show_varname)
+dump_statistics (struct variable *v, int show_varname)
{
+ struct freq_tab *ft;
double stat_value[frq_n_stats];
struct tab_table *t;
int i, r;
if (v->type == ALPHA)
return;
- if (v->p.frq.tab.n_valid == 0)
+ ft = &get_var_freqs (v)->tab;
+ if (ft->n_valid == 0)
{
msg (SW, _("No valid data for variable %s; statistics not displayed."),
v->name);
tab_text (t, 1, 0, TAB_LEFT | TAT_TITLE, _("Valid"));
tab_text (t, 1, 1, TAB_LEFT | TAT_TITLE, _("Missing"));
- tab_float(t, 2, 0, TAB_NONE, v->p.frq.tab.valid_cases, 11, 0);
- tab_float(t, 2, 1, TAB_NONE,
- v->p.frq.tab.total_cases - v->p.frq.tab.valid_cases, 11, 0);
+ tab_float(t, 2, 0, TAB_NONE, ft->valid_cases, 11, 0);
+ tab_float(t, 2, 1, TAB_NONE, ft->total_cases - ft->valid_cases, 11, 0);
for (i = 0; i < n_explicit_percentiles; i++, r++)
#include "alloc.h"
#include "case.h"
#include "command.h"
+#include "dictionary.h"
#include "error.h"
#include "file-handle.h"
#include "hash.h"
#include "lexer.h"
#include "misc.h"
-#include "pfm.h"
+#include "pfm-read.h"
+#include "pfm-write.h"
#include "settings.h"
-#include "sfm.h"
+#include "sfm-read.h"
+#include "sfm-write.h"
#include "str.h"
#include "value-labels.h"
#include "var.h"
#include "debug-print.h"
-/* GET or IMPORT input program. */
-struct get_pgm
+/* Rearranging and reducing a dictionary. */
+static void start_case_map (struct dictionary *);
+static struct case_map *finish_case_map (struct dictionary *);
+static void map_case (const struct case_map *,
+ const struct ccase *, struct ccase *);
+static void destroy_case_map (struct case_map *);
+
+/* Operation type. */
+enum operation
{
- struct file_handle *handle; /* File to GET or IMPORT from. */
- size_t case_size; /* Case size in bytes. */
+ OP_READ, /* GET or IMPORT. */
+ OP_SAVE, /* SAVE or XSAVE. */
+ OP_EXPORT, /* EXPORT. */
+ OP_MATCH /* MATCH FILES. */
};
-/* XSAVE transformation (and related SAVE, EXPORT procedures). */
-struct save_trns
+static int trim_dictionary (struct dictionary *,
+ enum operation, int *compress);
+\f
+/* GET input program. */
+struct get_pgm
{
- struct trns_header h;
- struct file_handle *f; /* Associated system file. */
- int nvar; /* Number of variables. */
- struct variable **var; /* Variables. */
- flt64 *case_buf; /* Case transfer buffer. */
+ struct sfm_reader *reader; /* System file reader. */
+ struct case_map *map; /* Map from system file to active file dict. */
+ struct ccase bounce; /* Bounce buffer. */
};
-/* Options bits set by trim_dictionary(). */
-#define GTSV_OPT_COMPRESSED 001 /* Compression; (X)SAVE only. */
-#define GTSV_OPT_SAVE 002 /* The SAVE/XSAVE/EXPORT procedures. */
-#define GTSV_OPT_MATCH_FILES 004 /* The MATCH FILES procedure. */
-#define GTSV_OPT_NONE 0
-
-static int trim_dictionary (struct dictionary * dict, int *options);
-static int save_write_case_func (struct ccase *, void *);
-static trns_proc_func save_trns_proc;
-static trns_free_func save_trns_free;
+static void get_pgm_free (struct get_pgm *);
/* Parses the GET command. */
int
cmd_get (void)
{
- struct file_handle *handle;
- struct dictionary *dict;
- struct get_pgm *pgm;
- int options = GTSV_OPT_NONE;
+ struct get_pgm *pgm = NULL;
+ struct file_handle *fh;
+ struct dictionary *dict = NULL;
+
+ pgm = xmalloc (sizeof *pgm);
+ pgm->reader = NULL;
+ pgm->map = NULL;
+ case_nullify (&pgm->bounce);
discard_variables ();
lex_match ('/');
if (lex_match_id ("FILE"))
lex_match ('=');
+ fh = fh_parse ();
+ if (fh == NULL)
+ goto error;
- handle = fh_parse_file_handle ();
- if (handle == NULL)
- return CMD_FAILURE;
-
- dict = sfm_read_dictionary (handle, NULL);
- if (dict == NULL)
- return CMD_FAILURE;
-
- if (0 == trim_dictionary (dict, &options))
- {
- fh_close_handle (handle);
- return CMD_FAILURE;
- }
+ pgm->reader = sfm_open_reader (fh, &dict, NULL);
+ if (pgm->reader == NULL)
+ goto error;
+ case_create (&pgm->bounce, dict_get_next_value_idx (dict));
- dict_compact_values (dict);
+ start_case_map (dict);
+ if (!trim_dictionary (dict, OP_READ, NULL))
+ goto error;
+ pgm->map = finish_case_map (dict);
dict_destroy (default_dict);
default_dict = dict;
- pgm = xmalloc (sizeof *pgm);
- pgm->handle = handle;
- pgm->case_size = dict_get_case_size (default_dict);
vfm_source = create_case_source (&get_source_class, default_dict, pgm);
return CMD_SUCCESS;
+
+ error:
+ get_pgm_free (pgm);
+ if (dict != NULL)
+ dict_destroy (dict);
+ return CMD_FAILURE;
}
-/* SAVE or XSAVE command? */
-enum save_cmd
- {
- CMD_SAVE,
- CMD_XSAVE
- };
+/* Frees a struct get_pgm. */
+static void
+get_pgm_free (struct get_pgm *pgm)
+{
+ if (pgm != NULL)
+ {
+ sfm_close_reader (pgm->reader);
+ destroy_case_map (pgm->map);
+ case_destroy (&pgm->bounce);
+ free (pgm);
+ }
+}
-/* Parses the SAVE and XSAVE commands. */
-static int
-cmd_save_internal (enum save_cmd save_cmd)
+/* Clears internal state related to GET input procedure. */
+static void
+get_source_destroy (struct case_source *source)
{
- struct file_handle *handle;
- struct dictionary *dict;
- int options = GTSV_OPT_SAVE;
+ struct get_pgm *pgm = source->aux;
+ get_pgm_free (pgm);
+}
- struct save_trns *t;
- struct sfm_write_info inf;
+/* 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)
+{
+ struct get_pgm *pgm = source->aux;
+ int ok;
- int i;
+ do
+ {
+ if (pgm->map == NULL)
+ ok = sfm_read_case (pgm->reader, c);
+ else
+ {
+ ok = sfm_read_case (pgm->reader, &pgm->bounce);
+ if (ok)
+ map_case (pgm->map, &pgm->bounce, c);
+ }
- lex_match ('/');
- if (lex_match_id ("OUTFILE"))
- lex_match ('=');
+ if (ok)
+ ok = write_case (wc_data);
+ }
+ while (ok);
+}
- handle = fh_parse_file_handle ();
- if (handle == NULL)
- return CMD_FAILURE;
+const struct case_source_class get_source_class =
+ {
+ "GET",
+ NULL,
+ get_source_read,
+ get_source_destroy,
+ };
+\f
+/* XSAVE transformation and SAVE procedure. */
+struct save_trns
+ {
+ struct trns_header h;
+ struct sfm_writer *writer; /* System file writer. */
+ struct case_map *map; /* Map from active file to system file dict. */
+ struct ccase bounce; /* Bounce buffer. */
+ };
- dict = dict_clone (default_dict);
- for (i = 0; i < dict_get_var_cnt (dict); i++)
- dict_get_var (dict, i)->aux = dict_get_var (default_dict, i);
- if (0 == trim_dictionary (dict, &options))
- {
- fh_close_handle (handle);
- return CMD_FAILURE;
- }
+static int save_write_case_func (struct ccase *, void *);
+static trns_proc_func save_trns_proc;
+static trns_free_func save_trns_free;
- /* Write dictionary. */
- inf.h = handle;
- inf.dict = dict;
- inf.compress = !!(options & GTSV_OPT_COMPRESSED);
- if (!sfm_write_dictionary (&inf))
- {
- dict_destroy (dict);
- fh_close_handle (handle);
- return CMD_FAILURE;
- }
+/* Parses the SAVE or XSAVE command
+ and returns the parsed transformation. */
+static struct save_trns *
+cmd_save_internal (void)
+{
+ struct file_handle *fh;
+ struct dictionary *dict = NULL;
+ struct save_trns *t = NULL;
+ int compress = get_scompression ();
- /* Fill in transformation structure. */
t = xmalloc (sizeof *t);
t->h.proc = save_trns_proc;
t->h.free = save_trns_free;
- t->f = handle;
- t->nvar = dict_get_var_cnt (dict);
- t->var = xmalloc (sizeof *t->var * t->nvar);
- for (i = 0; i < t->nvar; i++)
- t->var[i] = dict_get_var (dict, i)->aux;
- t->case_buf = xmalloc (sizeof *t->case_buf * inf.case_size);
+ t->writer = NULL;
+ t->map = NULL;
+ case_nullify (&t->bounce);
+
+ lex_match ('/');
+ if (lex_match_id ("OUTFILE"))
+ lex_match ('=');
+ fh = fh_parse ();
+ if (fh == NULL)
+ goto error;
+
+ dict = dict_clone (default_dict);
+ start_case_map (dict);
+ if (!trim_dictionary (dict, OP_SAVE, &compress))
+ goto error;
+ t->map = finish_case_map (dict);
+ if (t->map != NULL)
+ case_create (&t->bounce, dict_get_next_value_idx (dict));
+
+ t->writer = sfm_open_writer (fh, dict, compress);
+ if (t->writer == NULL)
+ goto error;
+
dict_destroy (dict);
- if (save_cmd == CMD_SAVE)
- {
- procedure (save_write_case_func, t);
- save_trns_free (&t->h);
- }
- else
- {
- assert (save_cmd == CMD_XSAVE);
- add_transformation (&t->h);
- }
+ return t;
- return CMD_SUCCESS;
+ error:
+ assert (t != NULL);
+ dict_destroy (dict);
+ save_trns_free (&t->h);
+ return NULL;
}
/* Parses and performs the SAVE procedure. */
int
cmd_save (void)
{
- return cmd_save_internal (CMD_SAVE);
+ struct save_trns *t = cmd_save_internal ();
+ if (t != NULL)
+ {
+ procedure (save_write_case_func, t);
+ save_trns_free (&t->h);
+ return CMD_SUCCESS;
+ }
+ else
+ return CMD_FAILURE;
}
/* Parses the XSAVE transformation command. */
int
cmd_xsave (void)
{
- return cmd_save_internal (CMD_XSAVE);
+ struct save_trns *t = cmd_save_internal ();
+ if (t != NULL)
+ {
+ add_transformation (&t->h);
+ return CMD_SUCCESS;
+ }
+ else
+ return CMD_FAILURE;
}
/* Writes the given C to the file specified by T. */
static void
do_write_case (struct save_trns *t, struct ccase *c)
{
- flt64 *p = t->case_buf;
- int i;
-
- for (i = 0; i < t->nvar; i++)
+ if (t->map == NULL)
+ sfm_write_case (t->writer, c);
+ else
{
- struct variable *v = t->var[i];
- if (v->type == NUMERIC)
- {
- double src = case_num (c, v->fv);
- if (src == SYSMIS)
- *p++ = -FLT64_MAX;
- else
- *p++ = src;
- }
- else
- {
- memcpy (p, case_str (c, v->fv), v->width);
- memset (&((char *) p)[v->width], ' ',
- REM_RND_UP (v->width, sizeof *p));
- p += DIV_RND_UP (v->width, sizeof *p);
- }
+ map_case (t->map, c, &t->bounce);
+ sfm_write_case (t->writer, &t->bounce);
}
-
- sfm_write_case (t->f, t->case_buf, p - t->case_buf);
}
/* Writes case C to the system file specified on SAVE. */
/* Frees a SAVE transformation. */
static void
-save_trns_free (struct trns_header *pt)
+save_trns_free (struct trns_header *t_)
{
- struct save_trns *t = (struct save_trns *) pt;
+ struct save_trns *t = (struct save_trns *) t_;
- fh_close_handle (t->f);
- free (t->var);
- free (t->case_buf);
- free (t);
+ if (t != NULL)
+ {
+ sfm_close_writer (t->writer);
+ destroy_case_map (t->map);
+ case_destroy (&t->bounce);
+ }
}
-static int rename_variables (struct dictionary * dict);
+static int rename_variables (struct dictionary *dict);
+
+/* Commands that read and write system files share a great deal
+ of common syntactic structure for rearranging and dropping
+ variables. This function parses this syntax and modifies DICT
+ appropriately.
-/* The GET and SAVE commands have a common structure after the
- FILE/OUTFILE subcommand. This function parses this structure and
- returns nonzero on success, zero on failure. It both reads
- *OPTIONS, for the GTSV_OPT_SAVE bit, and writes it, for the
- GTSV_OPT_COMPRESSED bit. */
+ OP is the operation being performed. For operations that
+ write a system file, *COMPRESS is set to 1 if the system file
+ should be compressed, 0 otherwise.
+
+ Returns nonzero on success, zero on failure. */
/* FIXME: IN, FIRST, LAST, MAP. */
-/* FIXME? Should we call dict_compact_values() on dict as a
- final step? */
static int
-trim_dictionary (struct dictionary *dict, int *options)
+trim_dictionary (struct dictionary *dict, enum operation op, int *compress)
{
+ assert ((compress != NULL) == (op == OP_SAVE));
if (get_scompression())
- *options |= GTSV_OPT_COMPRESSED;
+ *compress = 1;
- if (*options & GTSV_OPT_SAVE)
+ if (op == OP_SAVE || op == OP_EXPORT)
{
/* Delete all the scratch variables. */
struct variable **v;
free (v);
}
- while ((*options & GTSV_OPT_MATCH_FILES) || lex_match ('/'))
+ while (op == OP_MATCH || lex_match ('/'))
{
- if (!(*options & GTSV_OPT_MATCH_FILES) && lex_match_id ("COMPRESSED"))
- *options |= GTSV_OPT_COMPRESSED;
- else if (!(*options & GTSV_OPT_MATCH_FILES) && lex_match_id ("UNCOMPRESSED"))
- *options &= ~GTSV_OPT_COMPRESSED;
+ if (op == OP_SAVE && lex_match_id ("COMPRESSED"))
+ *compress = 1;
+ else if (op == OP_SAVE && lex_match_id ("UNCOMPRESSED"))
+ *compress = 0;
else if (lex_match_id ("DROP"))
{
struct variable **v;
return 0;
}
- if (*options & GTSV_OPT_MATCH_FILES)
- return 1;
+ if (op == OP_MATCH)
+ goto success;
}
if (token != '.')
lex_error (_("expecting end of command"));
return 0;
}
-
+
+ success:
+ if (op != OP_MATCH)
+ dict_compact_values (dict);
return 1;
}
/* Parses and performs the RENAME subcommand of GET and SAVE. */
static int
-rename_variables (struct dictionary * dict)
+rename_variables (struct dictionary *dict)
{
int i;
return success;
}
\f
-/* Clears internal state related to GET input procedure. */
-static void
-get_source_destroy (struct case_source *source)
+/* EXPORT procedure. */
+struct export_proc
+ {
+ struct pfm_writer *writer; /* System file writer. */
+ struct case_map *map; /* Map from active file to system file dict. */
+ struct ccase bounce; /* Bounce buffer. */
+ };
+
+static int export_write_case_func (struct ccase *, void *);
+static void export_proc_free (struct export_proc *);
+
+/* Parses the EXPORT command. */
+/* FIXME: same as cmd_save_internal(). */
+int
+cmd_export (void)
{
- struct get_pgm *pgm = source->aux;
+ struct file_handle *fh;
+ struct dictionary *dict;
+ struct export_proc *proc;
- /* It is not necessary to destroy the dictionary because if we get
- to this point then the dictionary is default_dict. */
- fh_close_handle (pgm->handle);
- free (pgm);
-}
+ proc = xmalloc (sizeof *proc);
+ proc->writer = NULL;
+ proc->map = NULL;
+ case_nullify (&proc->bounce);
-/* 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)
-{
- struct get_pgm *pgm = source->aux;
+ lex_match ('/');
+ if (lex_match_id ("OUTFILE"))
+ lex_match ('=');
+ fh = fh_parse ();
+ if (fh == NULL)
+ return CMD_FAILURE;
- while (sfm_read_case (pgm->handle, c, default_dict)
- && write_case (wc_data))
- ;
+ dict = dict_clone (default_dict);
+ start_case_map (dict);
+ if (!trim_dictionary (dict, OP_EXPORT, NULL))
+ goto error;
+ proc->map = finish_case_map (dict);
+ if (proc->map != NULL)
+ case_create (&proc->bounce, dict_get_next_value_idx (dict));
+
+ proc->writer = pfm_open_writer (fh, dict);
+ if (proc->writer == NULL)
+ goto error;
+
+ dict_destroy (dict);
+
+ procedure (export_write_case_func, proc);
+ export_proc_free (proc);
+
+ return CMD_SUCCESS;
+
+ error:
+ dict_destroy (dict);
+ export_proc_free (proc);
+ return CMD_FAILURE;
}
-const struct case_source_class get_source_class =
- {
- "GET",
- NULL,
- get_source_read,
- get_source_destroy,
- };
+/* Writes case C to the EXPORT file. */
+static int
+export_write_case_func (struct ccase *c, void *aux)
+{
+ struct export_proc *proc = aux;
+ if (proc->map == NULL)
+ pfm_write_case (proc->writer, c);
+ else
+ {
+ map_case (proc->map, c, &proc->bounce);
+ pfm_write_case (proc->writer, &proc->bounce);
+ }
+ return 1;
+}
+static void
+export_proc_free (struct export_proc *proc)
+{
+ if (proc != NULL)
+ {
+ pfm_close_writer (proc->writer);
+ destroy_case_map (proc->map);
+ case_destroy (&proc->bounce);
+ }
+}
\f
/* MATCH FILES. */
int type; /* One of MTF_*. */
struct variable **by; /* List of BY variables for this file. */
- struct file_handle *handle; /* File handle for the file. */
+ struct file_handle *handle; /* File handle. */
+ struct sfm_reader *reader; /* System file reader. */
struct dictionary *dict; /* Dictionary from system file. */
char in[9]; /* Name of the variable from IN=. */
char first[9], last[9]; /* Name of the variables from FIRST=, LAST=. */
static char *var_type_description (struct variable *);
+static void set_master (struct variable *, struct variable *master);
+static struct variable *get_master (struct variable *);
+
/* Parse and execute the MATCH FILES command. */
int
cmd_match_files (void)
{
struct mtf_proc mtf;
struct mtf_file *first_table = NULL;
+ struct mtf_file *iter;
int seen = 0;
if (seen & 1)
{
msg (SE, _("The BY subcommand may be given once at most."));
- goto lossage;
+ goto error;
}
seen |= 1;
lex_match ('=');
if (!parse_variables (mtf.dict, &mtf.by, &mtf.by_cnt,
PV_NO_DUPLICATE | PV_NO_SCRATCH))
- goto lossage;
+ goto error;
}
else if (token != T_ID)
{
lex_error (NULL);
- goto lossage;
+ goto error;
}
else if (lex_id_match ("FILE", tokid) || lex_id_match ("TABLE", tokid))
{
struct mtf_file *file = xmalloc (sizeof *file);
- file->in[0] = file->first[0] = file->last[0] = '\0';
- file->dict = NULL;
- file->by = NULL;
- case_nullify (&file->input);
-
if (lex_match_id ("FILE"))
file->type = MTF_FILE;
else if (lex_match_id ("TABLE"))
else
assert (0);
+ file->by = NULL;
+ file->handle = NULL;
+ file->reader = NULL;
+ file->dict = NULL;
+ file->in[0] = '\0';
+ file->first[0] = '\0';
+ file->last[0] = '\0';
+ case_nullify (&file->input);
+
/* FILEs go first, then TABLEs. */
if (file->type == MTF_TABLE || first_table == NULL)
{
if (lex_match ('*'))
{
- file->handle = NULL;
-
+ file->handle = NULL;
+ file->reader = NULL;
+
if (seen & 2)
{
msg (SE, _("The active file may not be specified more "
"than once."));
- goto lossage;
+ goto error;
}
seen |= 2;
{
msg (SE, _("Cannot specify the active file since no active "
"file has been defined."));
- goto lossage;
+ goto error;
}
if (temporary != 0)
"Temporary transformations will be made permanent."));
cancel_temporary ();
}
+
+ file->dict = default_dict;
}
else
{
- file->handle = fh_parse_file_handle ();
- if (!file->handle)
- goto lossage;
- }
+ file->handle = fh_parse ();
+ if (file->handle == NULL)
+ goto error;
+
+ file->reader = sfm_open_reader (file->handle, &file->dict, NULL);
+ if (file->reader == NULL)
+ goto error;
- if (file->handle)
- {
- file->dict = sfm_read_dictionary (file->handle, NULL);
- if (!file->dict)
- goto lossage;
case_create (&file->input, dict_get_next_value_idx (file->dict));
}
- else
- file->dict = default_dict;
- if (!mtf_merge_dictionary (mtf.dict, file))
- goto lossage;
}
else if (lex_id_match ("IN", tokid)
|| lex_id_match ("FIRST", tokid)
{
msg (SE, _("IN, FIRST, and LAST subcommands may not occur "
"before the first FILE or TABLE."));
- goto lossage;
+ goto error;
}
if (lex_match_id ("IN"))
if (token != T_ID)
{
lex_error (NULL);
- goto lossage;
+ goto error;
}
if (*name)
msg (SE, _("Multiple %s subcommands for a single FILE or "
"TABLE."),
sbc);
- goto lossage;
+ goto error;
}
strcpy (name, tokid);
lex_get ();
msg (SE, _("Duplicate variable name %s while creating %s "
"variable."),
name, sbc);
- goto lossage;
+ goto error;
}
}
else if (lex_id_match ("RENAME", tokid)
|| lex_id_match ("KEEP", tokid)
|| lex_id_match ("DROP", tokid))
{
- int options = GTSV_OPT_MATCH_FILES;
-
if (mtf.tail == NULL)
{
msg (SE, _("RENAME, KEEP, and DROP subcommands may not occur "
"before the first FILE or TABLE."));
- goto lossage;
+ goto error;
}
- if (!trim_dictionary (mtf.tail->dict, &options))
- goto lossage;
+ if (!trim_dictionary (mtf.tail->dict, OP_MATCH, NULL))
+ goto error;
}
else if (lex_match_id ("MAP"))
{
else
{
lex_error (NULL);
- goto lossage;
+ goto error;
}
}
while (token != '.');
+ for (iter = mtf.head; iter != NULL; iter = iter->next)
+ mtf_merge_dictionary (mtf.dict, iter);
+
if (seen & 4)
{
if (!(seen & 1))
{
msg (SE, _("The BY subcommand is required when a TABLE subcommand "
"is given."));
- goto lossage;
+ goto error;
}
}
if (seen & 1)
{
- struct mtf_file *iter;
-
- for (iter = mtf.head; iter; iter = iter->next)
+ for (iter = mtf.head; iter != NULL; iter = iter->next)
{
int i;
msg (SE, _("File %s lacks BY variable %s."),
iter->handle ? handle_get_name (iter->handle) : "*",
mtf.by[i]->name);
- goto lossage;
+ goto error;
}
}
}
mtf_free (&mtf);
return CMD_SUCCESS;
-lossage:
+error:
mtf_free (&mtf);
return CMD_FAILURE;
}
static void
mtf_free_file (struct mtf_file *file)
{
- fh_close_handle (file->handle);
- if (file->dict != NULL && file->dict != default_dict)
- dict_destroy (file->dict);
free (file->by);
- if (file->handle)
- case_destroy (&file->input);
+ sfm_close_reader (file->reader);
+ if (file->dict != default_dict)
+ dict_destroy (file->dict);
+ case_destroy (&file->input);
free (file);
}
for (i = 0; i < dict_get_var_cnt (f->dict); i++)
{
struct variable *v = dict_get_var (f->dict, i);
- union value *out = case_data_rw (mtf->mtf_case, v->p.mtf.master->fv);
+ union value *out = case_data_rw (mtf->mtf_case, get_master (v)->fv);
if (v->type == NUMERIC)
out->f = SYSMIS;
{
if (iter->handle)
{
- if (!sfm_read_case (iter->handle, &iter->input, iter->dict))
+ if (!sfm_read_case (iter->reader, &iter->input))
mtf_delete_file_in_place (mtf, &iter);
else
iter = iter->next;
case 1:
if (iter->handle == NULL)
return 1;
- if (sfm_read_case (iter->handle, &iter->input, iter->dict))
+ if (sfm_read_case (iter->reader, &iter->input))
goto again;
mtf_delete_file_in_place (mtf, &iter);
break;
struct ccase *record;
union value *out;
- if (mtf->seq_nums[v->p.mtf.master->index] == mtf->seq_num)
+ if (mtf->seq_nums[get_master (v)->index] == mtf->seq_num)
continue;
- mtf->seq_nums[v->p.mtf.master->index] = mtf->seq_num;
+ mtf->seq_nums[get_master (v)->index] = mtf->seq_num;
record = case_is_null (&iter->input) ? c : &iter->input;
assert (v->type == NUMERIC || v->type == ALPHA);
- out = case_data_rw (mtf->mtf_case, v->p.mtf.master->fv);
+ out = case_data_rw (mtf->mtf_case, get_master (v)->fv);
if (v->type == NUMERIC)
out->f = case_num (record, v->fv);
else
struct variable *v = dict_get_var (iter->dict, i);
union value *out;
- if (mtf->seq_nums[v->p.mtf.master->index] == mtf->seq_num)
+ if (mtf->seq_nums[get_master (v)->index] == mtf->seq_num)
continue;
- mtf->seq_nums[v->p.mtf.master->index] = mtf->seq_num;
+ mtf->seq_nums[get_master (v)->index] = mtf->seq_num;
- out = case_data_rw (mtf->mtf_case, v->p.mtf.master->fv);
+ out = case_data_rw (mtf->mtf_case, get_master (v)->fv);
if (v->type == NUMERIC)
out->f = SYSMIS;
else
{
struct mtf_file *next = iter->next_min;
- if (iter->handle)
+ if (iter->reader != NULL)
{
- if (!sfm_read_case (iter->handle, &iter->input, iter->dict))
+ if (!sfm_read_case (iter->reader, &iter->input))
mtf_delete_file_in_place (mtf, &iter);
}
return (mtf->head && mtf->head->type != MTF_TABLE);
}
-/* Merge the dictionary for file F into the master dictionary
- mtf_dict. */
+/* Merge the dictionary for file F into master dictionary M. */
static int
mtf_merge_dictionary (struct dictionary *const m, struct mtf_file *f)
{
var_type_description (dv), var_type_description (mv));
return 0;
}
- dv->p.mtf.master = mv;
+ set_master (dv, mv);
}
}
return 1;
}
+
+/* Marks V's master variable as MASTER. */
+static void
+set_master (struct variable *v, struct variable *master)
+{
+ var_attach_aux (v, master, NULL);
+}
+
+/* Returns the master variable corresponding to V,
+ as set with set_master(). */
+static struct variable *
+get_master (struct variable *v)
+{
+ assert (v->aux != NULL);
+ return v->aux;
+}
\f
/* 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 file_handle *handle = NULL;
- struct dictionary *dict;
- struct get_pgm *pgm;
- int options = GTSV_OPT_NONE;
+ struct import_pgm *pgm = NULL;
+ struct file_handle *fh = NULL;
+ struct dictionary *dict = NULL;
int type;
+ pgm = xmalloc (sizeof *pgm);
+ pgm->reader = NULL;
+ pgm->map = NULL;
+ case_nullify (&pgm->bounce);
+
for (;;)
{
lex_match ('/');
{
lex_match ('=');
- handle = fh_parse_file_handle ();
- if (handle == NULL)
+ fh = fh_parse ();
+ if (fh == NULL)
return CMD_FAILURE;
}
else if (lex_match_id ("TYPE"))
discard_variables ();
- dict = pfm_read_dictionary (handle, NULL);
- if (dict == NULL)
+ pgm->reader = pfm_open_reader (fh, &dict, NULL);
+ if (pgm->reader == NULL)
return CMD_FAILURE;
-
- if (0 == trim_dictionary (dict, &options))
- {
- fh_close_handle (handle);
- return CMD_FAILURE;
- }
-
- dict_compact_values (dict);
-
+ case_create (&pgm->bounce, dict_get_next_value_idx (dict));
+
+ start_case_map (dict);
+ if (!trim_dictionary (dict, OP_READ, NULL))
+ goto error;
+ pgm->map = finish_case_map (dict);
+
dict_destroy (default_dict);
default_dict = dict;
- pgm = xmalloc (sizeof *pgm);
- pgm->handle = handle;
- pgm->case_size = dict_get_case_size (default_dict);
vfm_source = create_case_source (&import_source_class, default_dict, pgm);
return CMD_SUCCESS;
+
+ error:
+ import_pgm_free (pgm);
+ if (dict != NULL)
+ dict_destroy (dict);
+ return CMD_FAILURE;
}
-/* Reads all the cases from the data file and passes them to
- write_case(). */
+/* 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 ccase *c,
+ write_case_func *write_case, write_case_data wc_data)
{
- struct get_pgm *pgm = source->aux;
-
- while (pfm_read_case (pgm->handle, c, default_dict))
- if (!write_case (wc_data))
- break;
+ 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,
- get_source_destroy,
+ import_source_destroy,
};
+
\f
-static int export_write_case_func (struct ccase *c, void *);
-
-/* Parses the EXPORT command. */
-/* FIXME: same as cmd_save_internal(). */
-int
-cmd_export (void)
-{
- struct file_handle *handle;
- struct dictionary *dict;
- int options = GTSV_OPT_SAVE;
+/* Case map.
- struct save_trns *t;
+ A case map copies data from a case that corresponds for one
+ dictionary to a case that corresponds to a second dictionary
+ derived from the first by, optionally, deleting, reordering,
+ or renaming variables. (No new variables may be created.)
+ */
- int i;
+/* A case map. */
+struct case_map
+ {
+ size_t value_cnt; /* Number of values in map. */
+ int *map; /* For each destination index, the
+ corresponding source index. */
+ };
- lex_match ('/');
- if (lex_match_id ("OUTFILE"))
- lex_match ('=');
+/* Prepares dictionary D for producing a case map. Afterward,
+ the caller may delete, reorder, or rename variables within D
+ at will before using finish_case_map() to produce the case
+ map.
- handle = fh_parse_file_handle ();
- if (handle == NULL)
- return CMD_FAILURE;
-
- dict = dict_clone (default_dict);
- for (i = 0; i < dict_get_var_cnt (dict); i++)
- dict_get_var (dict, i)->aux = dict_get_var (default_dict, i);
- if (0 == trim_dictionary (dict, &options))
+ Uses D's aux members, which may not otherwise be in use. */
+static void
+start_case_map (struct dictionary *d)
+{
+ size_t var_cnt = dict_get_var_cnt (d);
+ size_t i;
+
+ for (i = 0; i < var_cnt; i++)
{
- fh_close_handle (handle);
- return CMD_FAILURE;
+ struct variable *v = dict_get_var (d, i);
+ int *src_fv = xmalloc (sizeof *src_fv);
+ *src_fv = v->fv;
+ var_attach_aux (v, src_fv, var_dtor_free);
}
+}
+
+/* Produces a case map from dictionary D, which must have been
+ previously prepared with start_case_map().
- /* Write dictionary. */
- if (!pfm_write_dictionary (handle, dict))
+ Does not retain any reference to D, and clears the aux members
+ set up by start_case_map().
+
+ Returns the new case map, or a null pointer if no mapping is
+ required (that is, no data has changed position). */
+static struct case_map *
+finish_case_map (struct dictionary *d)
+{
+ struct case_map *map;
+ size_t var_cnt = dict_get_var_cnt (d);
+ size_t i;
+ int identity_map;
+
+ map = xmalloc (sizeof *map);
+ map->value_cnt = dict_get_next_value_idx (d);
+ map->map = xmalloc (sizeof *map->map * map->value_cnt);
+ for (i = 0; i < map->value_cnt; i++)
+ map->map[i] = -1;
+
+ identity_map = 1;
+ for (i = 0; i < var_cnt; i++)
{
- dict_destroy (dict);
- fh_close_handle (handle);
- return CMD_FAILURE;
+ struct variable *v = dict_get_var (d, i);
+ int src_fv = *(int *) var_detach_aux (v);
+ size_t idx;
+
+ if (v->fv != src_fv)
+ identity_map = 0;
+
+ for (idx = 0; idx < v->nv; idx++)
+ {
+ int src_idx = src_fv + idx;
+ int dst_idx = v->fv + idx;
+
+ assert (map->map[dst_idx] == -1);
+ map->map[dst_idx] = src_idx;
+ }
}
- /* Fill in transformation structure. */
- t = xmalloc (sizeof *t);
- t->h.proc = save_trns_proc;
- t->h.free = save_trns_free;
- t->f = handle;
- t->nvar = dict_get_var_cnt (dict);
- t->var = xmalloc (sizeof *t->var * t->nvar);
- for (i = 0; i < t->nvar; i++)
- t->var[i] = dict_get_var (dict, i)->aux;
- t->case_buf = xmalloc (sizeof *t->case_buf * t->nvar);
- dict_destroy (dict);
+ if (identity_map)
+ {
+ destroy_case_map (map);
+ return NULL;
+ }
- procedure (export_write_case_func, t);
- save_trns_free (&t->h);
+ while (map->value_cnt > 0 && map->map[map->value_cnt - 1] == -1)
+ map->value_cnt--;
- return CMD_SUCCESS;
+ return map;
}
-/* Writes case C to the EXPORT file. */
-static int
-export_write_case_func (struct ccase *c, void *aux)
+/* Maps from SRC to DST, applying case map MAP. */
+static void
+map_case (const struct case_map *map,
+ const struct ccase *src, struct ccase *dst)
{
- struct save_trns *t = aux;
- union value *p = (union value *) t->case_buf;
- int i;
+ size_t dst_idx;
- for (i = 0; i < t->nvar; i++)
- {
- struct variable *v = t->var[i];
+ assert (map != NULL);
+ assert (src != NULL);
+ assert (dst != NULL);
+ assert (src != dst);
- if (v->type == NUMERIC)
- (*p++).f = case_num (c, v->fv);
- else
- (*p++).c = (char *) case_str (c, v->fv);
+ for (dst_idx = 0; dst_idx < map->value_cnt; dst_idx++)
+ {
+ int src_idx = map->map[dst_idx];
+ if (src_idx != -1)
+ *case_data_rw (dst, dst_idx) = *case_data (src, src_idx);
}
+}
- pfm_write_case (t->f, (union value *) t->case_buf);
- return 1;
+/* Destroys case map MAP. */
+static void
+destroy_case_map (struct case_map *map)
+{
+ if (map != NULL)
+ {
+ free (map->map);
+ free (map);
+ }
}
#include "alloc.h"
#include "command.h"
+#include "dictionary.h"
#include "do-ifP.h"
#include "error.h"
#include "expr.h"
logfn = xstrdup ("pspp.log");
logfile = NULL;
- /* file-handle.h */
- fh_init_files ();
-
get_date ();
}
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
+#include <config.h>
+#include <stdlib.h>
+#include "alloc.h"
#include "hash.h"
#include "group.h"
-#include <string.h>
+#include "group_proc.h"
+#include "str.h"
+#include "var.h"
/* Return -1 if the id of a is less than b; +1 if greater than and
void
-free_group(struct group_statistics *v, void *aux)
+free_group(struct group_statistics *v, void *aux UNUSED)
{
free(v);
}
+
+
+struct group_proc *
+group_proc_get (struct variable *v)
+{
+ /* This is not ideal, obviously. */
+ if (v->aux == NULL)
+ var_attach_aux (v, xmalloc (sizeof (struct group_proc)), var_dtor_free);
+ return v->aux;
+}
};
+struct variable;
+struct group_proc *group_proc_get (struct variable *);
+
#endif
void
draw_histogram(struct chart *ch,
const struct variable *var,
+ const struct freq_tab *frq_tab,
const char *title,
struct normal_curve *norm,
int show_normal)
double ordinate_values[BINS];
- const struct freq_tab *frq_tab = &var->p.frq.tab ;
-
struct hsh_iterator hi;
struct hsh_table *fh = frq_tab->data;
struct freq *frq;
#include "case.h"
#include "command.h"
#include "data-list.h"
-#include "dfm.h"
+#include "dfm-read.h"
+#include "dictionary.h"
#include "error.h"
#include "expr.h"
#include "file-handle.h"
{
struct trns_header h;
- struct file_handle *handle; /* File to move file pointer back on. */
+ struct dfm_reader *reader; /* File to move file pointer back on. */
struct expression *column; /* Column to reset file pointer to. */
};
int
cmd_reread (void)
{
- /* File to be re-read. */
- struct file_handle *h;
-
- /* Expression for column to set file pointer to. */
- struct expression *e;
-
- /* Created transformation. */
- struct reread_trns *t;
+ struct file_handle *fh; /* File to be re-read. */
+ struct expression *e; /* Expression for column to set. */
+ struct reread_trns *t; /* Created transformation. */
- h = default_handle;
+ fh = default_handle;
e = NULL;
while (token != '.')
{
else if (lex_match_id ("FILE"))
{
lex_match ('=');
- h = fh_parse_file_handle ();
- if (h == NULL)
+ fh = fh_parse ();
+ if (fh == NULL)
{
expr_free (e);
return CMD_FAILURE;
t = xmalloc (sizeof *t);
t->h.proc = reread_trns_proc;
t->h.free = reread_trns_free;
- t->handle = h;
+ t->reader = dfm_open_reader (fh);
t->column = e;
add_transformation ((struct trns_header *) t);
struct reread_trns *t = (struct reread_trns *) pt;
if (t->column == NULL)
- dfm_reread_record (t->handle, 1);
+ dfm_reread_record (t->reader, 1);
else
{
union value column;
{
msg (SE, _("REREAD: Column numbers must be positive finite "
"numbers. Column set to 1."));
- dfm_reread_record (t->handle, 1);
+ dfm_reread_record (t->reader, 1);
}
else
- dfm_reread_record (t->handle, column.f);
+ dfm_reread_record (t->reader, column.f);
}
return -1;
}
/* Frees a REREAD transformation. */
static void
-reread_trns_free (struct trns_header * t)
+reread_trns_free (struct trns_header *t_)
{
- expr_free (((struct reread_trns *) t)->column);
+ struct reread_trns *t = (struct reread_trns *) t_;
+ expr_free (t->column);
+ dfm_close_reader (t->reader);
}
/* Parses END FILE command. */
#include "error.h"
#include "case.h"
#include "casefile.h"
+#include "dictionary.h"
+#include "group_proc.h"
#include "hash.h"
#include "str.h"
#include "var.h"
for(i = 0; i < l->n_dep ; ++i )
{
struct variable *var = l->v_dep[i];
+ struct group_proc *gp = group_proc_get (var);
struct group_statistics *gs;
struct hsh_iterator hi;
lz[i].grand_total = 0;
lz[i].total_n = 0;
- lz[i].n_groups = var->p.grp_data.n_groups ;
+ lz[i].n_groups = gp->n_groups ;
- for ( gs = hsh_first(var->p.grp_data.group_hash, &hi);
+ for ( gs = hsh_first(gp->group_hash, &hi);
gs != 0;
- gs = hsh_next(var->p.grp_data.group_hash, &hi))
+ gs = hsh_next(gp->group_hash, &hi))
{
gs->lz_total = 0;
}
for (i = 0; i < l->n_dep; ++i)
{
struct variable *var = l->v_dep[i];
+ struct group_proc *gp = group_proc_get (var);
double levene_z;
const union value *v = case_data (c, var->fv);
struct group_statistics *gs;
- gs = hsh_find(var->p.grp_data.group_hash,(void *) &key );
+ gs = hsh_find(gp->group_hash,(void *) &key );
if ( 0 == gs )
continue ;
struct group_statistics *g;
struct variable *var = l->v_dep[v] ;
- struct hsh_table *hash = var->p.grp_data.group_hash;
+ struct hsh_table *hash = group_proc_get (var)->group_hash;
for(g = (struct group_statistics *) hsh_first(hash,&hi);
const union value *v = case_data (c, var->fv);
struct group_statistics *gs;
- gs = hsh_find(var->p.grp_data.group_hash,(void *) &key );
+ gs = hsh_find(group_proc_get (var)->group_hash,(void *) &key );
if ( 0 == gs )
continue;
struct group_statistics *g;
struct variable *var = l->v_dep[v] ;
- struct hsh_table *hash = var->p.grp_data.group_hash;
+ struct group_proc *gp = group_proc_get (var);
+ struct hsh_table *hash = gp->group_hash;
for(g = (struct group_statistics *) hsh_first(hash,&hi);
g != 0 ;
{
lz_numerator += g->n * pow2(g->lz_mean - lz[v].grand_mean );
}
- lz_numerator *= ( l->v_dep[v]->p.grp_data.ugs.n -
- l->v_dep[v]->p.grp_data.n_groups );
+ lz_numerator *= ( gp->ugs.n - gp->n_groups );
- lz_denominator[v] *= (l->v_dep[v]->p.grp_data.n_groups - 1);
+ lz_denominator[v] *= (gp->n_groups - 1);
- l->v_dep[v]->p.grp_data.levene = lz_numerator / lz_denominator[v] ;
+ gp->levene = lz_numerator / lz_denominator[v] ;
}
#include "case.h"
#include "command.h"
#include "devind.h"
+#include "dictionary.h"
#include "lexer.h"
#include "error.h"
#include "magic.h"
#include "var.h"
#include "vfm.h"
#include "format.h"
+/* (headers) */
#include "debug-print.h"
#include "alloc.h"
#include "case.h"
#include "command.h"
+#include "dictionary.h"
#include "do-ifP.h"
#include "error.h"
#include "expr.h"
#include "main.h"
#include "cmdline.h"
#include "command.h"
+#include "dictionary.h"
#include "error.h"
#include "getline.h"
#include "glob.h"
#include "lexer.h"
#include "output.h"
#include "settings.h"
+#include "var.h"
#include <signal.h>
#include <stdlib.h>
execute_command (void)
{
int result;
+
/* Read the command's first token.
We may hit end of file.
If so, give the line reader a chance to proceed to the next file.
/* Unset the /ALGORITHM subcommand if it was used */
unset_cmd_algorithm ();
+ /* Clear any auxiliary data from the dictionary. */
+ dict_clear_aux (default_dict);
+
return result;
}
#include "case.h"
#include "command.h"
#include "data-in.h"
-#include "dfm.h"
+#include "dfm-read.h"
+#include "dictionary.h"
#include "error.h"
#include "file-handle.h"
#include "lexer.h"
/* FIXME: /N subcommand not implemented. It should be pretty simple,
too. */
+/* Different types of variables for MATRIX DATA procedure. Order is
+ important: these are used for sort keys. */
+enum
+ {
+ MXD_SPLIT, /* SPLIT FILE variables. */
+ MXD_ROWTYPE, /* ROWTYPE_. */
+ MXD_FACTOR, /* Factor variables. */
+ MXD_VARNAME, /* VARNAME_. */
+ MXD_CONTINUOUS, /* Continuous variables. */
+
+ MXD_COUNT
+ };
+
/* Format type enums. */
enum format_type
{
struct matrix_data_pgm
{
struct pool *container; /* Arena used for all allocations. */
- struct file_handle *data_file; /* The data file to be read. */
+ struct dfm_reader *reader; /* Data file to read. */
/* Format. */
enum format_type fmt; /* LIST or FREE. */
first continuous variable. */
};
+/* Auxiliary data attached to MATRIX DATA variables. */
+struct mxd_var
+ {
+ int var_type; /* Variable type. */
+ int sub_type; /* Subtype. */
+ };
+
static const struct case_source_class matrix_data_with_rowtype_source_class;
static const struct case_source_class matrix_data_without_rowtype_source_class;
-static int compare_variables_by_mxd_vartype (const void *pa,
+static int compare_variables_by_mxd_var_type (const void *pa,
const void *pb);
static void read_matrices_without_rowtype (struct matrix_data_pgm *);
static void read_matrices_with_rowtype (struct matrix_data_pgm *);
static int string_to_content_type (char *, int *);
+static void attach_mxd_aux (struct variable *, int var_type, int sub_type);
int
cmd_matrix_data (void)
{
struct pool *pool;
struct matrix_data_pgm *mx;
-
+ struct file_handle *fh = NULL;
+
unsigned seen = 0;
discard_variables ();
pool = pool_create ();
mx = pool_alloc (pool, sizeof *mx);
mx->container = pool;
- mx->data_file = inline_file;
+ mx->reader = NULL;
mx->fmt = LIST;
mx->section = LOWER;
mx->diag = DIAGONAL;
if (strcmp (v[i], "ROWTYPE_"))
{
new_var = dict_create_var_assert (default_dict, v[i], 0);
- new_var->p.mxd.vartype = MXD_CONTINUOUS;
- new_var->p.mxd.subtype = i;
- }
+ attach_mxd_aux (new_var, MXD_CONTINUOUS, i);
+ }
else
mx->explicit_rowtype = 1;
free (v[i]);
free (v);
}
- {
- mx->rowtype_ = dict_create_var_assert (default_dict,
- "ROWTYPE_", 8);
- mx->rowtype_->p.mxd.vartype = MXD_ROWTYPE;
- mx->rowtype_->p.mxd.subtype = 0;
- }
+ mx->rowtype_ = dict_create_var_assert (default_dict,
+ "ROWTYPE_", 8);
+ attach_mxd_aux (mx->rowtype_, MXD_ROWTYPE, 0);
}
else if (lex_match_id ("FILE"))
{
lex_match ('=');
- mx->data_file = fh_parse_file_handle ();
- if (mx->data_file == NULL)
+ fh = fh_parse ();
+ if (fh == NULL)
goto lossage;
}
else if (lex_match_id ("FORMAT"))
mx->single_split = dict_create_var_assert (default_dict,
tokid, 0);
+ attach_mxd_aux (mx->single_split, MXD_CONTINUOUS, 0);
lex_get ();
- mx->single_split->p.mxd.vartype = MXD_CONTINUOUS;
-
dict_set_split_vars (default_dict, &mx->single_split, 1);
}
else
for (i = 0; i < split_cnt; i++)
{
- if (split[i]->p.mxd.vartype != MXD_CONTINUOUS)
+ struct mxd_var *mv = split[i]->aux;
+ assert (mv != NULL);
+ if (mv->var_type != MXD_CONTINUOUS)
{
msg (SE, _("Split variable %s is already another type."),
tokid);
goto lossage;
}
- split[i]->p.mxd.vartype = MXD_SPLIT;
- split[i]->p.mxd.subtype = i;
+ var_clear_aux (split[i]);
+ attach_mxd_aux (split[i], MXD_SPLIT, i);
}
}
}
for (i = 0; i < mx->n_factors; i++)
{
- if (mx->factors[i]->p.mxd.vartype != MXD_CONTINUOUS)
+ struct variable *v = mx->factors[i];
+ struct mxd_var *mv = v->aux;
+ assert (mv != NULL);
+ if (mv->var_type != MXD_CONTINUOUS)
{
msg (SE, _("Factor variable %s is already another type."),
tokid);
goto lossage;
}
- mx->factors[i]->p.mxd.vartype = MXD_FACTOR;
- mx->factors[i]->p.mxd.subtype = i;
+ var_clear_aux (v);
+ attach_mxd_aux (v, MXD_FACTOR, i);
}
}
}
}
/* Create VARNAME_. */
- {
- mx->varname_ = dict_create_var_assert (default_dict, "VARNAME_", 8);
- mx->varname_->p.mxd.vartype = MXD_VARNAME;
- mx->varname_->p.mxd.subtype = 0;
- }
+ mx->varname_ = dict_create_var_assert (default_dict, "VARNAME_", 8);
+ attach_mxd_aux (mx->varname_, MXD_VARNAME, 0);
/* Sort the dictionary variables into the desired order for the
system file output. */
size_t nv;
dict_get_vars (default_dict, &v, &nv, 0);
- qsort (v, nv, sizeof *v, compare_variables_by_mxd_vartype);
+ qsort (v, nv, sizeof *v, compare_variables_by_mxd_var_type);
dict_reorder_vars (default_dict, v, nv);
free (v);
}
for (i = 0; i < dict_get_var_cnt (default_dict); i++)
{
struct variable *v = dict_get_var (default_dict, i);
- int type = v->p.mxd.vartype;
+ struct mxd_var *mv = v->aux;
+ int type = mv->var_type;
assert (type >= 0 && type < MXD_COUNT);
v->print = v->write = fmt_tab[type];
goto lossage;
}
- if (!dfm_open_for_reading (mx->data_file))
+ mx->reader = dfm_open_reader (fh);
+ if (mx->reader == NULL)
goto lossage;
if (mx->explicit_rowtype)
else
read_matrices_without_rowtype (mx);
+ dfm_close_reader (mx->reader);
+
pool_destroy (mx->container);
return CMD_SUCCESS;
return -1;
}
-/* Compare two variables using p.mxd.vartype and p.mxd.subtype
+/* Compare two variables using p.mxd.var_type and p.mxd.sub_type
fields. */
static int
-compare_variables_by_mxd_vartype (const void *a_, const void *b_)
+compare_variables_by_mxd_var_type (const void *a_, const void *b_)
{
struct variable *const *pa = a_;
struct variable *const *pb = b_;
- const struct matrix_data_proc *a = &(*pa)->p.mxd;
- const struct matrix_data_proc *b = &(*pb)->p.mxd;
-
- if (a->vartype != b->vartype)
- return a->vartype > b->vartype ? 1 : -1;
+ const struct mxd_var *a = (*pa)->aux;
+ const struct mxd_var *b = (*pb)->aux;
+
+ if (a->var_type != b->var_type)
+ return a->var_type > b->var_type ? 1 : -1;
else
- return a->subtype < b->subtype ? -1 : a->subtype > b->subtype;
+ return a->sub_type < b->sub_type ? -1 : a->sub_type > b->sub_type;
+}
+
+/* Attaches a struct mxd_var with the specific member values to
+ V. */
+static void
+attach_mxd_aux (struct variable *v, int var_type, int sub_type)
+{
+ struct mxd_var *mv;
+
+ assert (v->aux == NULL);
+ mv = xmalloc (sizeof *mv);
+ mv->var_type = var_type;
+ mv->sub_type = sub_type;
+ var_attach_aux (v, mv, var_dtor_free);
}
\f
/* Matrix tokenizer. */
int length; /* MSTR: tokstr length. */
};
-static int mget_token (struct matrix_token *, struct file_handle *);
+static int mget_token (struct matrix_token *, struct dfm_reader *);
#if DEBUGGING
-#define mget_token(TOKEN, HANDLE) mget_token_dump(TOKEN, HANDLE)
+#define mget_token(TOKEN, READER) mget_token_dump(TOKEN, READER)
static void
mdump_token (const struct matrix_token *token)
}
static int
-mget_token_dump (struct matrix_token *token, struct file_handle *data_file)
+mget_token_dump (struct matrix_token *token, struct dfm_reader *reader)
{
- int result = (mget_token) (token, data_file);
+ int result = (mget_token) (token, reader);
mdump_token (token);
return result;
}
#endif
-/* Return the current position in DATA_FILE. */
+/* Return the current position in READER. */
static const char *
-context (struct file_handle *data_file)
+context (struct dfm_reader *reader)
{
static char buf[32];
- if (dfm_eof (data_file))
+ if (dfm_eof (reader))
strcpy (buf, "at end of file");
else
{
struct len_string line;
const char *sp;
- dfm_get_record (data_file, &line);
+ dfm_get_record (reader, &line);
sp = ls_c_str (&line);
while (sp < ls_end (&line) && isspace ((unsigned char) *sp))
sp++;
/* Is there at least one token left in the data file? */
static int
-another_token (struct file_handle *data_file)
+another_token (struct dfm_reader *reader)
{
for (;;)
{
struct len_string line;
const char *cp;
- if (dfm_eof (data_file))
+ if (dfm_eof (reader))
return 0;
- dfm_get_record (data_file, &line);
+ dfm_get_record (reader, &line);
cp = ls_c_str (&line);
while (isspace ((unsigned char) *cp) && cp < ls_end (&line))
if (cp < ls_end (&line))
{
- dfm_forward_columns (data_file, cp - ls_c_str (&line));
+ dfm_forward_columns (reader, cp - ls_c_str (&line));
return 1;
}
- dfm_forward_record (data_file);
+ dfm_forward_record (reader);
}
}
-/* Parse a MATRIX DATA token from mx->data_file into TOKEN. */
+/* Parse a MATRIX DATA token from READER into TOKEN. */
static int
-(mget_token) (struct matrix_token *token, struct file_handle *data_file)
+(mget_token) (struct matrix_token *token, struct dfm_reader *reader)
{
struct len_string line;
int first_column;
char *cp;
- if (!another_token (data_file))
+ if (!another_token (reader))
return 0;
- dfm_get_record (data_file, &line);
- first_column = dfm_column_start (data_file);
+ dfm_get_record (reader, &line);
+ first_column = dfm_column_start (reader);
/* Three types of fields: quoted with ', quoted with ", unquoted. */
cp = ls_c_str (&line);
token->type = MSTR;
}
- dfm_forward_columns (data_file, cp - ls_c_str (&line));
+ dfm_forward_columns (reader, cp - ls_c_str (&line));
return 1;
}
/* Forcibly skip the end of a line for content type CONTENT in
- DATA_FILE. */
+ READER. */
static int
-force_eol (struct file_handle *data_file, const char *content)
+force_eol (struct dfm_reader *reader, const char *content)
{
struct len_string line;
const char *cp;
- if (dfm_eof (data_file))
+ if (dfm_eof (reader))
return 0;
- dfm_get_record (data_file, &line);
+ dfm_get_record (reader, &line);
cp = ls_c_str (&line);
while (isspace ((unsigned char) *cp) && cp < ls_end (&line))
if (cp < ls_end (&line))
{
msg (SE, _("End of line expected %s while reading %s."),
- context (data_file), content);
+ context (reader), content);
return 0;
}
- dfm_forward_record (data_file);
+ dfm_forward_record (reader);
return 1;
}
\f
free (nr.split_values);
free (nr.factor_values);
-
- fh_close_handle (mx->data_file);
}
/* Mirror data across the diagonal of matrix CP which contains
for (j = 0; j < n_cols; j++)
{
struct matrix_token token;
- if (!mget_token (&token, mx->data_file))
+ if (!mget_token (&token, mx->reader))
return 0;
if (token.type != MNUM)
{
msg (SE, _("expecting value for %s %s"),
dict_get_var (default_dict, j)->name,
- context (mx->data_file));
+ context (mx->reader));
return 0;
}
*cp++ = token.number;
}
if (mx->fmt != FREE
- && !force_eol (mx->data_file, content_names[content]))
+ && !force_eol (mx->reader, content_names[content]))
return 0;
debug_printf (("\n"));
}
nr_output_data (nr, c, write_case, wc_data);
if (dict_get_split_cnt (default_dict) == 0
- || !another_token (mx->data_file))
+ || !another_token (mx->reader))
return;
}
}
if (mx->single_split)
{
- if (!compare)
- nr->split_values[0]
- = ++dict_get_split_vars (default_dict)[0]->p.mxd.subtype;
+ if (!compare)
+ {
+ struct mxd_var *mv = dict_get_split_vars (default_dict)[0]->aux;
+ nr->split_values[0] = ++mv->sub_type;
+ }
return 1;
}
for (i = 0; i < split_cnt; i++)
{
struct matrix_token token;
- if (!mget_token (&token, mx->data_file))
+ if (!mget_token (&token, mx->reader))
return 0;
if (token.type != MNUM)
{
msg (SE, _("Syntax error expecting SPLIT FILE value %s."),
- context (mx->data_file));
+ context (mx->reader));
return 0;
}
for (i = 0; i < mx->n_factors; i++)
{
struct matrix_token token;
- if (!mget_token (&token, mx->data_file))
+ if (!mget_token (&token, mx->reader))
return 0;
if (token.type != MNUM)
{
msg (SE, _("Syntax error expecting factor value %s."),
- context (mx->data_file));
+ context (mx->reader));
return 0;
}
{
msg (SE, _("Syntax error expecting value %g for %s %s."),
nr->factor_values[i + mx->n_factors * cell],
- mx->factors[i]->name, context (mx->data_file));
+ mx->factors[i]->name, context (mx->reader));
return 0;
}
}
static int wr_output_data (struct wr_aux_data *, struct ccase *,
write_case_func *, write_case_data);
static int wr_read_rowtype (struct wr_aux_data *,
- const struct matrix_token *, struct file_handle *);
+ const struct matrix_token *, struct dfm_reader *);
static int wr_read_factors (struct wr_aux_data *);
static int wr_read_indeps (struct wr_aux_data *);
static void matrix_data_read_with_rowtype (struct case_source *,
procedure (NULL, NULL);
free (wr.split_values);
- fh_close_handle (mx->data_file);
}
/* Read from the data file and write it to the active file. */
if (!wr_read_indeps (wr))
return;
}
- while (another_token (mx->data_file));
+ while (another_token (mx->reader));
wr_output_data (wr, c, write_case, wc_data);
}
for (i = 0; i < split_cnt; i++)
{
struct matrix_token token;
- if (!mget_token (&token, mx->data_file))
+ if (!mget_token (&token, mx->reader))
return 0;
if (token.type != MNUM)
{
msg (SE, _("Syntax error %s expecting SPLIT FILE value."),
- context (mx->data_file));
+ context (mx->reader));
return 0;
}
return 1;
}
-/* Sets ROWTYPE_ based on the given TOKEN read from DATA_FILE.
+/* Sets ROWTYPE_ based on the given TOKEN read from READER.
Return success. */
static int
wr_read_rowtype (struct wr_aux_data *wr,
const struct matrix_token *token,
- struct file_handle *data_file)
+ struct dfm_reader *reader)
{
if (wr->content != -1)
{
- msg (SE, _("Multiply specified ROWTYPE_ %s."), context (data_file));
+ msg (SE, _("Multiply specified ROWTYPE_ %s."), context (reader));
return 0;
}
if (token->type != MSTR)
{
msg (SE, _("Syntax error %s expecting ROWTYPE_ string."),
- context (data_file));
+ context (reader));
return 0;
}
if (wr->content == -1)
{
- msg (SE, _("Syntax error %s."), context (data_file));
+ msg (SE, _("Syntax error %s."), context (reader));
return 0;
}
for (i = 0; i < mx->n_factors; i++)
{
struct matrix_token token;
- if (!mget_token (&token, mx->data_file))
+ if (!mget_token (&token, mx->reader))
goto lossage;
if (token.type == MSTR)
{
- if (!wr_read_rowtype (wr, &token, mx->data_file))
+ if (!wr_read_rowtype (wr, &token, mx->reader))
goto lossage;
- if (!mget_token (&token, mx->data_file))
+ if (!mget_token (&token, mx->reader))
goto lossage;
}
if (token.type != MNUM)
{
msg (SE, _("Syntax error expecting factor value %s."),
- context (mx->data_file));
+ context (mx->reader));
goto lossage;
}
if (wr->content == -1)
{
struct matrix_token token;
- if (!mget_token (&token, mx->data_file))
+ if (!mget_token (&token, mx->reader))
goto lossage;
- if (!wr_read_rowtype (wr, &token, mx->data_file))
+ if (!wr_read_rowtype (wr, &token, mx->reader))
goto lossage;
}
for (j = 0; j < n_cols; j++)
{
struct matrix_token token;
- if (!mget_token (&token, mx->data_file))
+ if (!mget_token (&token, mx->reader))
return 0;
if (token.type != MNUM)
{
msg (SE, _("Syntax error expecting value for %s %s."),
dict_get_var (default_dict, mx->first_continuous + j)->name,
- context (mx->data_file));
+ context (mx->reader));
return 0;
}
*cp++ = token.number;
}
if (mx->fmt != FREE
- && !force_eol (mx->data_file, content_names[wr->content]))
+ && !force_eol (mx->reader, content_names[wr->content]))
return 0;
debug_printf (("\n"));
}
matrix_data_read_without_rowtype,
NULL,
};
+
#include <config.h>
#include <stdlib.h>
#include <stdio.h>
+#include "dictionary.h"
#include "error.h"
#include "alloc.h"
#include "command.h"
/* (specification)
means (mns_):
*tables=custom;
- +variables=custom;
- +crossbreak=custom;
+format=lab:!labels/nolabels/nocatlabs,
name:!names/nonames,
val:!values/novalues,
return 2;
lex_match ('=');
- if (cmd->sbc_tables || cmd->sbc_crossbreak)
+ if (cmd->sbc_tables)
{
- msg (SE, _("TABLES or CROSSBREAK subcommand may not appear more "
+ msg (SE, _("TABLES subcommand may not appear more "
"than once."));
return 0;
}
- if (cmd->sbc_variables)
- var_set = var_set_create_from_array (v_var, n_var);
- else
- var_set = var_set_create_from_dict (default_dict);
+ var_set = var_set_create_from_dict (default_dict);
assert (var_set != NULL);
do
nv_dim[n_dim - 1] = nvl;
v_dim[n_dim - 1] = vl;
-
- if (cmd->sbc_variables)
- {
- int i;
-
- for (i = 0; i < nv_dim[0]; i++)
- {
- struct means_proc *v_inf = &v_dim[0][i]->p.mns;
-
- if (v_inf->min == SYSMIS)
- {
- msg (SE, _("Variable %s specified on TABLES or "
- "CROSSBREAK, but not specified on "
- "VARIABLES."),
- v_dim[0][i]->name);
- goto lossage;
- }
-
- if (n_dim == 1)
- {
- v_inf->min = (int) v_inf->min;
- v_inf->max = (int) v_inf->max;
- } else {
- if (v_inf->min == LOWEST || v_inf->max == HIGHEST)
- {
- msg (SE, _("LOWEST and HIGHEST may not be used "
- "for independent variables (%s)."),
- v_dim[0][i]->name);
- goto lossage;
- }
- if (v_inf->min != (int) v_inf->min
- || v_inf->max != (int) v_inf->max)
- {
- msg (SE, _("Independent variables (%s) may not "
- "have noninteger endpoints in their "
- "ranges."),
- v_dim[0][i]->name);
- goto lossage;
- }
- }
- }
- }
}
while (lex_match (T_BY));
return 0;
}
-/* Parse CROSSBREAK subcommand. */
-static int
-mns_custom_crossbreak (struct cmd_means *cmd)
-{
- return mns_custom_tables (cmd);
-}
-
-/* Parses the VARIABLES subcommand. */
-static int
-mns_custom_variables (struct cmd_means *cmd)
-{
- if (cmd->sbc_tables)
- {
- msg (SE, _("VARIABLES must precede TABLES."));
- return 0;
- }
-
- if (cmd->sbc_variables == 1)
- {
- int i;
-
- for (i = 0; i < dict_get_var_cnt (default_dict); i++)
- dict_get_var (default_dict, i)->p.mns.min = SYSMIS;
- }
-
- do
- {
- int orig_n = n_var;
-
- double min, max;
-
- if (!parse_variables (default_dict, &v_var, &n_var,
- PV_APPEND | PV_NO_DUPLICATE | PV_NO_SCRATCH))
- return 0;
-
- if (!lex_force_match ('('))
- return 0;
-
- /* Lower value. */
- if (token == T_ID
- && (!strcmp (tokid, "LO") || lex_id_match ("LOWEST", tokid)))
- min = LOWEST;
- else
- {
- if (!lex_force_num ())
- return 0;
- min = tokval;
- }
- lex_get ();
-
- lex_match (',');
-
- /* Higher value. */
- if (token == T_ID
- && (!strcmp (tokid, "HI") || lex_id_match ("HIGHEST", tokid)))
- max = HIGHEST;
- else
- {
- if (!lex_force_num ())
- return 0;
- max = tokval;
- }
- lex_get ();
-
- if (!lex_force_match (')'))
- return 0;
-
- /* Range check. */
- if (max < min)
- {
- msg (SE, _("Upper value (%g) is less than lower value "
- "(%g) on VARIABLES subcommand."), max, min);
- return 0;
- }
-
- {
- int i;
-
- for (i = orig_n; i < n_var; i++)
- {
- struct means_proc *v_inf = &v_var[i]->p.mns;
-
- v_inf->min = min;
- v_inf->max = max;
- }
- }
- }
- while (token != '/' && token != '.');
-
- return 1;
-}
-
/*
Local Variables:
mode: c
#include "alloc.h"
#include "bitvector.h"
#include "command.h"
+#include "dictionary.h"
#include "error.h"
#include "hash.h"
#include "lexer.h"
#include "error.h"
#include <stdlib.h>
#include "command.h"
+#include "dictionary.h"
#include "error.h"
#include "lexer.h"
#include "str.h"
#include "alloc.h"
#include "str.h"
#include "case.h"
+#include "dictionary.h"
#include "command.h"
#include "lexer.h"
#include "error.h"
#include "group_proc.h"
#include "group.h"
#include "levene.h"
+/* (headers) */
/* (specification)
"ONEWAY" (oneway_):
/* Clean up */
for (i = 0 ; i < n_vars ; ++i )
{
- struct hsh_table *group_hash = vars[i]->p.grp_data.group_hash;
+ struct hsh_table *group_hash = group_proc_get (vars[i])->group_hash;
hsh_destroy(group_hash);
}
for ( i=0 ; i < n_vars ; ++i )
{
- struct group_statistics *totals = &vars[i]->p.grp_data.ugs;
- struct hsh_table *group_hash = vars[i]->p.grp_data.group_hash;
+ struct group_statistics *totals = &group_proc_get (vars[i])->ugs;
+ struct hsh_table *group_hash = group_proc_get (vars[i])->group_hash;
struct hsh_iterator g;
struct group_statistics *gs;
double ssa=0;
tab_hline(t, TAL_1, 0, n_cols - 1 , i * 3 + 1);
{
+ struct group_proc *gp = group_proc_get (vars[i]);
const double sst = totals->ssq - ( totals->sum * totals->sum) / totals->n ;
- const double df1 = vars[i]->p.grp_data.n_groups - 1;
- const double df2 = totals->n - vars[i]->p.grp_data.n_groups ;
+ const double df1 = gp->n_groups - 1;
+ const double df2 = totals->n - gp->n_groups ;
const double msa = ssa / df1;
- vars[i]->p.grp_data.mse = (sst - ssa) / df2;
+ gp->mse = (sst - ssa) / df2;
/* Sums of Squares */
/* Mean Squares */
tab_float (t, 4, i * 3 + 1, TAB_RIGHT, msa, 8, 3);
- tab_float (t, 4, i * 3 + 2, TAB_RIGHT, vars[i]->p.grp_data.mse, 8, 3);
+ tab_float (t, 4, i * 3 + 2, TAB_RIGHT, gp->mse, 8, 3);
{
- const double F = msa/vars[i]->p.grp_data.mse ;
+ const double F = msa/gp->mse ;
/* The F value */
tab_float (t, 5, i * 3 + 1, 0, F, 8, 3);
for ( v = 0 ; v < n_vars ; ++v )
- n_rows += vars[v]->p.grp_data.n_groups + 1;
+ n_rows += group_proc_get (vars[v])->n_groups + 1;
t = tab_create (n_cols,n_rows,0);
tab_headers (t, 2, 0, 2, 0);
{
double T;
double std_error;
-
+
+ struct group_proc *gp = group_proc_get (vars[v]);
struct hsh_iterator g;
struct group_statistics *gs;
- struct group_statistics *totals = &vars[v]->p.grp_data.ugs;
+ struct group_statistics *totals = &gp->ugs;
int count = 0 ;
const char *s = var_to_string(vars[v]);
- struct hsh_table *group_hash = vars[v]->p.grp_data.group_hash;
+ struct hsh_table *group_hash = gp->group_hash;
tab_text (t, 0, row, TAB_LEFT | TAT_TITLE, s);
tab_float(t, 8, row + count, 0, totals->minimum, 8, 2);
tab_float(t, 9, row + count, 0, totals->maximum, 8, 2);
- row += vars[v]->p.grp_data.n_groups + 1;
+ row += gp->n_groups + 1;
}
{
double F;
const struct variable *var = vars[v];
+ const struct group_proc *gp = group_proc_get (vars[v]);
const char *s = var_to_string(var);
- const struct group_statistics *totals = &var->p.grp_data.ugs;
+ const struct group_statistics *totals = &gp->ugs;
- const double df1 = var->p.grp_data.n_groups - 1;
- const double df2 = totals->n - var->p.grp_data.n_groups ;
+ const double df1 = gp->n_groups - 1;
+ const double df2 = totals->n - gp->n_groups ;
tab_text (t, 0, v + 1, TAB_LEFT | TAT_TITLE, s);
- F = var->p.grp_data.levene;
+ F = gp->levene;
tab_float (t, 1, v + 1, TAB_RIGHT, F, 8,3);
tab_float (t, 2, v + 1, TAB_RIGHT, df1 ,8,0);
tab_float (t, 3, v + 1, TAB_RIGHT, df2 ,8,0);
int ci;
double contrast_value = 0.0;
double coef_msq = 0.0;
- struct group_proc *grp_data = &vars[v]->p.grp_data ;
+ struct group_proc *grp_data = group_proc_get (vars[v]);
struct hsh_table *group_hash = grp_data->group_hash;
struct hsh_iterator g;
struct group_statistics *gs;
cmd.sbc_contrast,
TAB_RIGHT, contrast_value, 8,2);
- std_error_contrast = sqrt(vars[v]->p.grp_data.mse * coef_msq);
+ std_error_contrast = sqrt(grp_data->mse * coef_msq);
/* Std. Error */
tab_float (t, 4, (v * lines_per_variable) + i + 1,
for(i=0; i< n_vars ; ++i)
{
- struct group_statistics *totals = &vars[i]->p.grp_data.ugs;
+ struct group_proc *gp = group_proc_get (vars[i]);
+ struct group_statistics *totals = &gp->ugs;
/* Create a hash for each of the dependent variables.
The hash contains a group_statistics structure,
and is keyed by value of the independent variable */
- vars[i]->p.grp_data.group_hash =
+ gp->group_hash =
hsh_create(4,
(hsh_compare_func *) compare_group,
(hsh_hash_func *) hash_group,
const union value *val = case_data (&c, v->fv);
- struct hsh_table *group_hash = vars[i]->p.grp_data.group_hash;
+ struct group_proc *gp = group_proc_get (vars[i]);
+ struct hsh_table *group_hash = gp->group_hash;
struct group_statistics *gs;
if (! value_is_missing(val,v) )
{
- struct group_statistics *totals = &vars[i]->p.grp_data.ugs;
+ struct group_statistics *totals = &gp->ugs;
totals->n+=weight;
totals->sum+=weight * val->f;
gs->maximum = val->f * weight;
}
- vars[i]->p.grp_data.n_groups = hsh_count ( group_hash );
+ gp->n_groups = hsh_count ( group_hash );
}
}
for(i = 0; i < n_vars ; ++i)
{
- struct hsh_table *group_hash = vars[i]->p.grp_data.group_hash;
- struct group_statistics *totals = &vars[i]->p.grp_data.ugs;
+ struct group_proc *gp = group_proc_get (vars[i]);
+ struct hsh_table *group_hash = gp->group_hash;
+ struct group_statistics *totals = &gp->ugs;
struct hsh_iterator g;
struct group_statistics *gs;
/* PSPP - computes sample statistics.
Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
Written by Ben Pfaff <blp@gnu.org>.
+ Code for parsing floating-point numbers adapted from GNU C
+ library.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
02111-1307, USA. */
#include <config.h>
-#include "pfm.h"
+#include "pfm-read.h"
#include "error.h"
#include <stdarg.h>
#include <stdio.h>
#include <math.h>
#include "alloc.h"
#include "case.h"
+#include "dictionary.h"
#include "file-handle.h"
#include "format.h"
#include "getline.h"
#include "debug-print.h"
-/* pfm's file_handle extension. */
-struct pfm_fhuser_ext
+/* Portable file reader. */
+struct pfm_reader
{
- FILE *file; /* Actual file. */
+ struct file_handle *fh; /* File handle. */
+ FILE *file; /* File stream. */
- struct dictionary *dict; /* File's dictionary. */
int weight_index; /* 0-based index of weight variable, or -1. */
unsigned char *trans; /* 256-byte character set translation table. */
- int nvars; /* Number of variables. */
- int *vars; /* Variable widths, 0 for numeric. */
- int case_size; /* Number of `value's per case. */
+ int var_cnt; /* Number of variables. */
+ int *widths; /* Variable widths, 0 for numeric. */
+ int value_cnt; /* Number of `value's per case. */
unsigned char buf[83]; /* Input buffer. */
unsigned char *bp; /* Buffer pointer. */
int cc; /* Current character. */
};
-static struct fh_ext_class pfm_r_class;
-
static int
-corrupt_msg (struct file_handle *h, const char *format,...)
+corrupt_msg (struct pfm_reader *r, const char *format,...)
PRINTF_FORMAT (2, 3);
/* Displays a corruption error. */
static int
-corrupt_msg (struct file_handle *h, const char *format, ...)
+corrupt_msg (struct pfm_reader *r, const char *format, ...)
{
- struct pfm_fhuser_ext *ext = h->ext;
char buf[1024];
{
e.class = ME;
getl_location (&e.where.filename, &e.where.line_number);
- filename = handle_get_filename (h);
+ filename = handle_get_filename (r->fh);
e.title = title = local_alloc (strlen (filename) + 80);
sprintf (title, _("portable file %s corrupt at offset %ld: "),
- filename, ftell (ext->file) - (82 - (long) (ext->bp - ext->buf)));
+ filename, ftell (r->file) - (82 - (long) (r->bp - r->buf)));
e.text = buf;
err_vmsg (&e);
}
/* Closes a portable file after we're done with it. */
-static void
-pfm_close (struct file_handle *h)
+void
+pfm_close_reader (struct pfm_reader *r)
{
- struct pfm_fhuser_ext *ext = h->ext;
+ if (r == NULL)
+ return;
- if (EOF == fclose (ext->file))
+ if (r->fh != NULL)
+ fh_close (r->fh, "portable file", "rs");
+ if (fclose (r->file) == EOF)
msg (ME, _("%s: Closing portable file: %s."),
- handle_get_filename (h), strerror (errno));
- free (ext->vars);
- free (ext->trans);
- free (h->ext);
+ handle_get_filename (r->fh), strerror (errno));
+ free (r->trans);
+ free (r);
}
-/* Displays the message X with corrupt_msg, then jumps to the lossage
+/* Displays the message X with corrupt_msg, then jumps to the error
label. */
-#define lose(X) \
- do \
- { \
- corrupt_msg X; \
- goto lossage; \
- } \
- while (0)
+#define lose(X) \
+ do { \
+ corrupt_msg X; \
+ goto error; \
+ } while (0)
/* Read an 80-character line into handle H's buffer. Return
success. */
static int
-fill_buf (struct file_handle *h)
+fill_buf (struct pfm_reader *r)
{
- struct pfm_fhuser_ext *ext = h->ext;
-
- if (80 != fread (ext->buf, 1, 80, ext->file))
- lose ((h, _("Unexpected end of file.")));
+ if (80 != fread (r->buf, 1, 80, r->file))
+ lose ((r, _("Unexpected end of file.")));
/* PORTME: line ends. */
{
int c;
- c = getc (ext->file);
+ c = getc (r->file);
if (c != '\n' && c != '\r')
- lose ((h, _("Bad line end.")));
+ lose ((r, _("Bad line end.")));
- c = getc (ext->file);
+ c = getc (r->file);
if (c != '\n' && c != '\r')
- ungetc (c, ext->file);
+ ungetc (c, r->file);
}
- if (ext->trans)
+ if (r->trans)
{
int i;
for (i = 0; i < 80; i++)
- ext->buf[i] = ext->trans[ext->buf[i]];
+ r->buf[i] = r->trans[r->buf[i]];
}
- ext->bp = ext->buf;
+ r->bp = r->buf;
return 1;
- lossage:
+ error:
return 0;
}
/* Read a single character into cur_char. Return success; */
static int
-read_char (struct file_handle *h)
+read_char (struct pfm_reader *r)
{
- struct pfm_fhuser_ext *ext = h->ext;
-
- if (ext->bp >= &ext->buf[80] && !fill_buf (h))
+ if (r->bp >= &r->buf[80] && !fill_buf (r))
return 0;
- ext->cc = *ext->bp++;
+ r->cc = *r->bp++;
return 1;
}
/* Advance a single character. */
-#define advance() if (!read_char (h)) goto lossage
+#define advance() \
+ do { \
+ if (!read_char (r)) \
+ goto error; \
+ } while (0)
/* Skip a single character if present, and return whether it was
skipped. */
static inline int
-skip_char (struct file_handle *h, int c)
+skip_char (struct pfm_reader *r, int c)
{
- struct pfm_fhuser_ext *ext = h->ext;
-
- if (ext->cc == c)
+ if (r->cc == c)
{
advance ();
return 1;
}
- lossage:
+ error:
return 0;
}
/* Skip a single character if present, and return whether it was
skipped. */
-#define match(C) skip_char (h, C)
+#define match(C) skip_char (r, C)
-static int read_header (struct file_handle *h);
-static int read_version_data (struct file_handle *h, struct pfm_read_info *inf);
-static int read_variables (struct file_handle *h);
-static int read_value_label (struct file_handle *h);
-void dump_dictionary (struct dictionary *dict);
+static int read_header (struct pfm_reader *);
+static int read_version_data (struct pfm_reader *, struct pfm_read_info *);
+static int read_variables (struct pfm_reader *, struct dictionary *);
+static int read_value_label (struct pfm_reader *, struct dictionary *);
+void dump_dictionary (struct dictionary *);
/* Reads the dictionary from file with handle H, and returns it in a
dictionary structure. This dictionary may be modified in order to
rename, reorder, and delete variables, etc. */
-struct dictionary *
-pfm_read_dictionary (struct file_handle *h, struct pfm_read_info *inf)
+struct pfm_reader *
+pfm_open_reader (struct file_handle *fh, struct dictionary **dict,
+ struct pfm_read_info *info)
{
- /* The file handle extension record. */
- struct pfm_fhuser_ext *ext;
-
- /* Check whether the file is already open. */
- if (h->class == &pfm_r_class)
- {
- ext = h->ext;
- return ext->dict;
- }
- else if (h->class != NULL)
- {
- msg (ME, _("Cannot read file %s as portable file: already opened "
- "for %s."),
- handle_get_name (h), h->class->name);
- return NULL;
- }
-
- msg (VM (1), _("%s: Opening portable-file handle %s for reading."),
- handle_get_filename (h), handle_get_name (h));
-
- /* Open the physical disk file. */
- ext = xmalloc (sizeof (struct pfm_fhuser_ext));
- ext->file = fopen (handle_get_filename (h), "rb");
- if (ext->file == NULL)
+ struct pfm_reader *r = NULL;
+
+ *dict = dict_create ();
+ if (!fh_open (fh, "portable file", "rs"))
+ goto error;
+
+ /* Create and initialize reader. */
+ r = xmalloc (sizeof *r);
+ r->fh = fh;
+ r->file = fopen (handle_get_filename (r->fh), "rb");
+ r->weight_index = -1;
+ r->trans = NULL;
+ r->var_cnt = 0;
+ r->widths = NULL;
+ r->value_cnt = 0;
+ r->bp = NULL;
+
+ /* Check that file open succeeded, prime reading. */
+ if (r->file == NULL)
{
msg (ME, _("An error occurred while opening \"%s\" for reading "
"as a portable file: %s."),
- handle_get_filename (h), strerror (errno));
+ handle_get_filename (r->fh), strerror (errno));
err_cond_fail ();
- free (ext);
- return NULL;
+ goto error;
}
-
- /* Initialize the sfm_fhuser_ext structure. */
- h->class = &pfm_r_class;
- h->ext = ext;
- ext->dict = NULL;
- ext->trans = NULL;
- if (!fill_buf (h))
- goto lossage;
+ if (!fill_buf (r))
+ goto error;
advance ();
- /* Read the header. */
- if (!read_header (h))
- goto lossage;
-
- /* Read version, date info, product identification. */
- if (!read_version_data (h, inf))
- goto lossage;
-
- /* Read variables. */
- if (!read_variables (h))
- goto lossage;
+ /* Read header, version, date info, product id, variables. */
+ if (!read_header (r)
+ || !read_version_data (r, info)
+ || !read_variables (r, *dict))
+ goto error;
- /* Value labels. */
+ /* Read value labels. */
while (match (77 /* D */))
- if (!read_value_label (h))
- goto lossage;
+ if (!read_value_label (r, *dict))
+ goto error;
+ /* Check that we've made it to the data. */
if (!match (79 /* F */))
- lose ((h, _("Data record expected.")));
-
- msg (VM (2), _("Read portable-file dictionary successfully."));
+ lose ((r, _("Data record expected.")));
- return ext->dict;
+ return r;
- lossage:
- /* Come here on unsuccessful completion. */
- msg (VM (1), _("Error reading portable-file dictionary."));
-
- fclose (ext->file);
- if (ext && ext->dict)
- dict_destroy (ext->dict);
- free (ext);
- h->class = NULL;
- h->ext = NULL;
+ error:
+ pfm_close_reader (r);
+ dict_destroy (*dict);
+ *dict = NULL;
return NULL;
}
\f
/* Read a floating point value and return its value, or
second_lowest_value on error. */
static double
-read_float (struct file_handle *h)
+read_float (struct pfm_reader *r)
{
- struct pfm_fhuser_ext *ext = h->ext;
double num = 0.;
int got_dot = 0;
int got_digit = 0;
for (;;)
{
- if (ext->cc >= 64 /* 0 */ && ext->cc <= 93 /* T */)
+ if (r->cc >= 64 /* 0 */ && r->cc <= 93 /* T */)
{
got_digit++;
digit so that we can multiply by 10 later. */
++exponent;
else
- num = (num * 30.0) + (ext->cc - 64);
+ num = (num * 30.0) + (r->cc - 64);
/* Keep track of the number of digits after the decimal point.
If we just divided by 30 here, we would lose precision. */
if (got_dot)
--exponent;
}
- else if (!got_dot && ext->cc == 127 /* . */)
+ else if (!got_dot && r->cc == 127 /* . */)
/* Record that we have found the decimal point. */
got_dot = 1;
else
}
if (!got_digit)
- lose ((h, "Number expected."));
+ lose ((r, "Number expected."));
- if (ext->cc == 130 /* + */ || ext->cc == 141 /* - */)
+ if (r->cc == 130 /* + */ || r->cc == 141 /* - */)
{
/* Get the exponent. */
long int exp = 0;
- int neg_exp = ext->cc == 141 /* - */;
+ int neg_exp = r->cc == 141 /* - */;
for (;;)
{
advance ();
- if (ext->cc < 64 /* 0 */ || ext->cc > 93 /* T */)
+ if (r->cc < 64 /* 0 */ || r->cc > 93 /* T */)
break;
if (exp > LONG_MAX / 30)
goto overflow;
- exp = exp * 30 + (ext->cc - 64);
+ exp = exp * 30 + (r->cc - 64);
}
/* We don't check whether there were actually any digits, but we
}
if (!match (142 /* / */))
- lose ((h, _("Missing numeric terminator.")));
+ lose ((r, _("Missing numeric terminator.")));
/* Multiply NUM by 30 to the EXPONENT power, checking for overflow. */
else
return DBL_MAX / 10;
- lossage:
+ error:
return second_lowest_value;
}
/* Read an integer and return its value, or NOT_INT on failure. */
static int
-read_int (struct file_handle *h)
+read_int (struct pfm_reader *r)
{
- double f = read_float (h);
+ double f = read_float (r);
if (f == second_lowest_value)
- goto lossage;
+ goto error;
if (floor (f) != f || f >= INT_MAX || f <= INT_MIN)
- lose ((h, _("Bad integer format.")));
+ lose ((r, _("Bad integer format.")));
return f;
- lossage:
+ error:
return NOT_INT;
}
failure. The buffer can be deallocated by calling with a NULL
argument. */
static unsigned char *
-read_string (struct file_handle *h)
+read_string (struct pfm_reader *r)
{
- struct pfm_fhuser_ext *ext = h->ext;
static char *buf;
int n;
- if (h == NULL)
+ if (r == NULL)
{
free (buf);
buf = NULL;
else if (buf == NULL)
buf = xmalloc (256);
- n = read_int (h);
+ n = read_int (r);
if (n == NOT_INT)
return NULL;
if (n < 0 || n > 255)
- lose ((h, _("Bad string length %d."), n));
+ lose ((r, _("Bad string length %d."), n));
{
int i;
for (i = 0; i < n; i++)
{
- buf[i] = ext->cc;
+ buf[i] = r->cc;
advance ();
}
}
buf[n] = 0;
return buf;
- lossage:
+ error:
return NULL;
}
\f
/* Reads the 464-byte file header. */
int
-read_header (struct file_handle *h)
+read_header (struct pfm_reader *r)
{
- struct pfm_fhuser_ext *ext = h->ext;
-
/* For now at least, just ignore the vanity splash strings. */
{
int i;
for (i = 0; i < 256; i++)
{
- src[i] = (unsigned char) ext->cc;
+ src[i] = (unsigned char) r->cc;
advance ();
}
if (trans_temp[src[i]] == -1)
trans_temp[src[i]] = i;
- ext->trans = xmalloc (256);
+ r->trans = xmalloc (256);
for (i = 0; i < 256; i++)
- ext->trans[i] = trans_temp[i] == -1 ? 0 : trans_temp[i];
+ r->trans[i] = trans_temp[i] == -1 ? 0 : trans_temp[i];
/* Translate the input buffer. */
for (i = 0; i < 80; i++)
- ext->buf[i] = ext->trans[ext->buf[i]];
- ext->cc = ext->trans[ext->cc];
+ r->buf[i] = r->trans[r->buf[i]];
+ r->cc = r->trans[r->cc];
}
{
for (i = 0; i < 8; i++)
if (!match (sig[i]))
- lose ((h, "Missing SPSSPORT signature."));
+ lose ((r, "Missing SPSSPORT signature."));
}
return 1;
- lossage:
+ error:
return 0;
}
/* Reads the version and date info record, as well as product and
subproduct identification records if present. */
int
-read_version_data (struct file_handle *h, struct pfm_read_info *inf)
+read_version_data (struct pfm_reader *r, struct pfm_read_info *info)
{
- struct pfm_fhuser_ext *ext = h->ext;
-
/* Version. */
if (!match (74 /* A */))
- lose ((h, "Unrecognized version code %d.", ext->cc));
+ lose ((r, "Unrecognized version code %d.", r->cc));
/* Date. */
{
static const int map[] = {6, 7, 8, 9, 3, 4, 0, 1};
- char *date = read_string (h);
+ char *date = read_string (r);
int i;
if (!date)
return 0;
if (strlen (date) != 8)
- lose ((h, _("Bad date string length %d."), strlen (date)));
+ lose ((r, _("Bad date string length %d."), strlen (date)));
for (i = 0; i < 8; i++)
{
if (date[i] < 64 /* 0 */ || date[i] > 73 /* 9 */)
- lose ((h, _("Bad character in date.")));
- if (inf)
- inf->creation_date[map[i]] = date[i] - 64 /* 0 */ + '0';
+ lose ((r, _("Bad character in date.")));
+ if (info)
+ info->creation_date[map[i]] = date[i] - 64 /* 0 */ + '0';
}
- if (inf)
+ if (info)
{
- inf->creation_date[2] = inf->creation_date[5] = ' ';
- inf->creation_date[10] = 0;
+ info->creation_date[2] = info->creation_date[5] = ' ';
+ info->creation_date[10] = 0;
}
}
/* Time. */
{
static const int map[] = {0, 1, 3, 4, 6, 7};
- char *time = read_string (h);
+ char *time = read_string (r);
int i;
if (!time)
return 0;
if (strlen (time) != 6)
- lose ((h, _("Bad time string length %d."), strlen (time)));
+ lose ((r, _("Bad time string length %d."), strlen (time)));
for (i = 0; i < 6; i++)
{
if (time[i] < 64 /* 0 */ || time[i] > 73 /* 9 */)
- lose ((h, _("Bad character in time.")));
- if (inf)
- inf->creation_time[map[i]] = time[i] - 64 /* 0 */ + '0';
+ lose ((r, _("Bad character in time.")));
+ if (info)
+ info->creation_time[map[i]] = time[i] - 64 /* 0 */ + '0';
}
- if (inf)
+ if (info)
{
- inf->creation_time[2] = inf->creation_time[5] = ' ';
- inf->creation_time[8] = 0;
+ info->creation_time[2] = info->creation_time[5] = ' ';
+ info->creation_time[8] = 0;
}
}
{
char *product;
- product = read_string (h);
+ product = read_string (r);
if (product == NULL)
return 0;
- if (inf)
- strncpy (inf->product, product, 61);
+ if (info)
+ strncpy (info->product, product, 61);
}
- else if (inf)
- inf->product[0] = 0;
+ else if (info)
+ info->product[0] = 0;
/* Subproduct. */
if (match (67 /* 3 */))
{
char *subproduct;
- subproduct = read_string (h);
+ subproduct = read_string (r);
if (subproduct == NULL)
return 0;
- if (inf)
- strncpy (inf->subproduct, subproduct, 61);
+ if (info)
+ strncpy (info->subproduct, subproduct, 61);
}
- else if (inf)
- inf->subproduct[0] = 0;
+ else if (info)
+ info->subproduct[0] = 0;
return 1;
- lossage:
+ error:
return 0;
}
static int
-convert_format (struct file_handle *h, int fmt[3], struct fmt_spec *v,
+convert_format (struct pfm_reader *r, int fmt[3], struct fmt_spec *v,
struct variable *vv)
{
v->type = translate_fmt (fmt[0]);
if (v->type == -1)
- lose ((h, _("%s: Bad format specifier byte (%d)."), vv->name, fmt[0]));
+ lose ((r, _("%s: Bad format specifier byte (%d)."), vv->name, fmt[0]));
v->w = fmt[1];
v->d = fmt[2];
/* FIXME? Should verify the resulting specifier more thoroughly. */
if (v->type == -1)
- lose ((h, _("%s: Bad format specifier byte (%d)."), vv->name, fmt[0]));
+ lose ((r, _("%s: Bad format specifier byte (%d)."), vv->name, fmt[0]));
if ((vv->type == ALPHA) ^ ((formats[v->type].cat & FCAT_STRING) != 0))
- lose ((h, _("%s variable %s has %s format specifier %s."),
+ lose ((r, _("%s variable %s has %s format specifier %s."),
vv->type == ALPHA ? _("String") : _("Numeric"),
vv->name,
formats[v->type].cat & FCAT_STRING ? _("string") : _("numeric"),
formats[v->type].name));
return 1;
- lossage:
+ error:
return 0;
}
*s = spss2ascii[(unsigned char) *s];
}
-static int parse_value (struct file_handle *, union value *, struct variable *);
+static int parse_value (struct pfm_reader *, union value *, struct variable *);
/* Read information on all the variables. */
static int
-read_variables (struct file_handle *h)
+read_variables (struct pfm_reader *r, struct dictionary *dict)
{
- struct pfm_fhuser_ext *ext = h->ext;
char *weight_name = NULL;
int i;
if (!match (68 /* 4 */))
- lose ((h, _("Expected variable count record.")));
+ lose ((r, _("Expected variable count record.")));
- ext->nvars = read_int (h);
- if (ext->nvars <= 0 || ext->nvars == NOT_INT)
- lose ((h, _("Invalid number of variables %d."), ext->nvars));
- ext->vars = xmalloc (sizeof *ext->vars * ext->nvars);
+ r->var_cnt = read_int (r);
+ if (r->var_cnt <= 0 || r->var_cnt == NOT_INT)
+ lose ((r, _("Invalid number of variables %d."), r->var_cnt));
+ r->widths = xmalloc (sizeof *r->widths * r->var_cnt);
/* Purpose of this value is unknown. It is typically 161. */
{
- int x = read_int (h);
+ int x = read_int (r);
if (x == NOT_INT)
- goto lossage;
+ goto error;
if (x != 161)
- corrupt_msg (h, _("Unexpected flag value %d."), x);
+ corrupt_msg (r, _("Unexpected flag value %d."), x);
}
- ext->dict = dict_create ();
-
if (match (70 /* 6 */))
{
- weight_name = read_string (h);
+ weight_name = read_string (r);
if (!weight_name)
- goto lossage;
+ goto error;
asciify (weight_name);
if (strlen (weight_name) > 8)
{
- corrupt_msg (h, _("Weight variable name (%s) truncated."),
+ corrupt_msg (r, _("Weight variable name (%s) truncated."),
weight_name);
weight_name[8] = '\0';
}
}
- for (i = 0; i < ext->nvars; i++)
+ for (i = 0; i < r->var_cnt; i++)
{
int width;
unsigned char *name;
int j;
if (!match (71 /* 7 */))
- lose ((h, _("Expected variable record.")));
+ lose ((r, _("Expected variable record.")));
- width = read_int (h);
+ width = read_int (r);
if (width == NOT_INT)
- goto lossage;
+ goto error;
if (width < 0)
- lose ((h, _("Invalid variable width %d."), width));
- ext->vars[i] = width;
+ lose ((r, _("Invalid variable width %d."), width));
+ r->widths[i] = width;
- name = read_string (h);
+ name = read_string (r);
if (name == NULL)
- goto lossage;
+ goto error;
for (j = 0; j < 6; j++)
{
- fmt[j] = read_int (h);
+ fmt[j] = read_int (r);
if (fmt[j] == NOT_INT)
- goto lossage;
+ goto error;
}
/* Verify first character of variable name.
Weirdly enough, there is no # character in the SPSS portable
character set, so we can't check for it. */
if (strlen (name) > 8)
- lose ((h, _("position %d: Variable name has %u characters."),
+ lose ((r, _("position %d: Variable name has %u characters."),
i, strlen (name)));
if ((name[0] < 74 /* A */ || name[0] > 125 /* Z */)
&& name[0] != 152 /* @ */)
- lose ((h, _("position %d: Variable name begins with invalid "
+ lose ((r, _("position %d: Variable name begins with invalid "
"character."), i));
if (name[0] >= 100 /* a */ && name[0] <= 125 /* z */)
{
- corrupt_msg (h, _("position %d: Variable name begins with "
+ corrupt_msg (r, _("position %d: Variable name begins with "
"lowercase letter %c."),
i, name[0] - 100 + 'a');
name[0] -= 26 /* a - A */;
if (c >= 100 /* a */ && c <= 125 /* z */)
{
- corrupt_msg (h, _("position %d: Variable name character %d "
+ corrupt_msg (r, _("position %d: Variable name character %d "
"is lowercase letter %c."),
i, j + 1, c - 100 + 'a');
name[j] -= 26 /* z - Z */;
|| c == 136 /* $ */ || c == 146 /* _ */)
name[j] = c;
else
- lose ((h, _("position %d: character `\\%03o' is not "
+ lose ((r, _("position %d: character `\\%03o' is not "
"valid in a variable name."), i, c));
}
asciify (name);
if (width < 0 || width > 255)
- lose ((h, "Bad width %d for variable %s.", width, name));
+ lose ((r, "Bad width %d for variable %s.", width, name));
- v = dict_create_var (ext->dict, name, width);
- v->get.fv = v->fv;
+ v = dict_create_var (dict, name, width);
+ v->aux = xmalloc (sizeof (int));
+ *(int *) v->aux = v->fv;
if (v == NULL)
- lose ((h, _("Duplicate variable name %s."), name));
- if (!convert_format (h, &fmt[0], &v->print, v))
- goto lossage;
- if (!convert_format (h, &fmt[3], &v->write, v))
- goto lossage;
+ lose ((r, _("Duplicate variable name %s."), name));
+ if (!convert_format (r, &fmt[0], &v->print, v))
+ goto error;
+ if (!convert_format (r, &fmt[3], &v->write, v))
+ goto error;
/* Range missing values. */
if (match (75 /* B */))
{
v->miss_type = MISSING_RANGE;
- if (!parse_value (h, &v->missing[0], v)
- || !parse_value (h, &v->missing[1], v))
- goto lossage;
+ if (!parse_value (r, &v->missing[0], v)
+ || !parse_value (r, &v->missing[1], v))
+ goto error;
}
else if (match (74 /* A */))
{
v->miss_type = MISSING_HIGH;
- if (!parse_value (h, &v->missing[0], v))
- goto lossage;
+ if (!parse_value (r, &v->missing[0], v))
+ goto error;
}
else if (match (73 /* 9 */))
{
v->miss_type = MISSING_LOW;
- if (!parse_value (h, &v->missing[0], v))
- goto lossage;
+ if (!parse_value (r, &v->missing[0], v))
+ goto error;
}
/* Single missing values. */
v->miss_type = map_next[v->miss_type];
if (v->miss_type == -1)
- lose ((h, _("Bad missing values for %s."), v->name));
+ lose ((r, _("Bad missing values for %s."), v->name));
assert (map_ofs[v->miss_type] != -1);
- if (!parse_value (h, &v->missing[map_ofs[v->miss_type]], v))
- goto lossage;
+ if (!parse_value (r, &v->missing[map_ofs[v->miss_type]], v))
+ goto error;
}
if (match (76 /* C */))
{
- char *label = read_string (h);
+ char *label = read_string (r);
if (label == NULL)
- goto lossage;
+ goto error;
v->label = xstrdup (label);
asciify (v->label);
if (weight_name != NULL)
{
- struct variable *weight_var = dict_lookup_var (ext->dict, weight_name);
+ struct variable *weight_var = dict_lookup_var (dict, weight_name);
if (weight_var == NULL)
- lose ((h, _("Weighting variable %s not present in dictionary."),
+ lose ((r, _("Weighting variable %s not present in dictionary."),
weight_name));
free (weight_name);
- dict_set_weight (ext->dict, weight_var);
+ dict_set_weight (dict, weight_var);
}
return 1;
- lossage:
+ error:
free (weight_name);
return 0;
}
/* Parse a value for variable VV into value V. Returns success. */
static int
-parse_value (struct file_handle *h, union value *v, struct variable *vv)
+parse_value (struct pfm_reader *r, union value *v, struct variable *vv)
{
if (vv->type == ALPHA)
{
- char *mv = read_string (h);
+ char *mv = read_string (r);
int j;
if (mv == NULL)
}
else
{
- v->f = read_float (h);
+ v->f = read_float (r);
if (v->f == second_lowest_value)
return 0;
}
/* Parse a value label record and return success. */
static int
-read_value_label (struct file_handle *h)
+read_value_label (struct pfm_reader *r, struct dictionary *dict)
{
- struct pfm_fhuser_ext *ext = h->ext;
-
/* Variables. */
int nv;
struct variable **v;
int i;
- nv = read_int (h);
+ nv = read_int (r);
if (nv == NOT_INT)
return 0;
v = xmalloc (sizeof *v * nv);
for (i = 0; i < nv; i++)
{
- char *name = read_string (h);
+ char *name = read_string (r);
if (name == NULL)
- goto lossage;
+ goto error;
asciify (name);
- v[i] = dict_lookup_var (ext->dict, name);
+ v[i] = dict_lookup_var (dict, name);
if (v[i] == NULL)
- lose ((h, _("Unknown variable %s while parsing value labels."), name));
+ lose ((r, _("Unknown variable %s while parsing value labels."), name));
if (v[0]->width != v[i]->width)
- lose ((h, _("Cannot assign value labels to %s and %s, which "
+ lose ((r, _("Cannot assign value labels to %s and %s, which "
"have different variable types or widths."),
v[0]->name, v[i]->name));
}
- n_labels = read_int (h);
+ n_labels = read_int (r);
if (n_labels == NOT_INT)
- goto lossage;
+ goto error;
for (i = 0; i < n_labels; i++)
{
int j;
- if (!parse_value (h, &val, v[0]))
- goto lossage;
+ if (!parse_value (r, &val, v[0]))
+ goto error;
- label = read_string (h);
+ label = read_string (r);
if (label == NULL)
- goto lossage;
+ goto error;
asciify (label);
/* Assign the value_label's to each variable. */
continue;
if (var->type == NUMERIC)
- lose ((h, _("Duplicate label for value %g for variable %s."),
+ lose ((r, _("Duplicate label for value %g for variable %s."),
val.f, var->name));
else
- lose ((h, _("Duplicate label for value `%.*s' for variable %s."),
+ lose ((r, _("Duplicate label for value `%.*s' for variable %s."),
var->width, val.s, var->name));
}
}
free (v);
return 1;
- lossage:
+ error:
free (v);
return 0;
}
-/* Reads one case from portable file H into PERM
- according to the instuctions given in associated dictionary DICT,
- which must have the get.fv elements appropriately set. Returns
- nonzero only if successful. */
+/* Reads one case from portable file R into C. Returns nonzero
+ only if successful. */
int
-pfm_read_case (struct file_handle *h, struct ccase *perm,
- struct dictionary *dict)
+pfm_read_case (struct pfm_reader *r, struct ccase *c)
{
- struct pfm_fhuser_ext *ext = h->ext;
-
- union value *temp, *tp;
- int i;
+ size_t i;
+ size_t idx;
/* Check for end of file. */
- if (ext->cc == 99 /* Z */)
+ if (r->cc == 99 /* Z */)
return 0;
- /* The first concern is to obtain a full case relative to the data
- file. (Cases in the data file have no particular relationship to
- cases in the active file.) */
- tp = temp = local_alloc (sizeof *tp * ext->case_size);
- for (tp = temp, i = 0; i < ext->nvars; i++)
- if (ext->vars[i] == 0)
- {
- tp->f = read_float (h);
- if (tp->f == second_lowest_value)
- goto unexpected_eof;
- tp++;
- }
- else
- {
- char *s = read_string (h);
- if (s == NULL)
- goto unexpected_eof;
- asciify (s);
-
- st_bare_pad_copy (tp->s, s, ext->vars[i]);
- tp += DIV_RND_UP (ext->vars[i], MAX_SHORT_STRING);
- }
-
- /* Translate a case in data file format to a case in active file
- format. */
- for (i = 0; i < dict_get_var_cnt (dict); i++)
+ idx = 0;
+ for (i = 0; i < r->var_cnt; i++)
{
- struct variable *v = dict_get_var (dict, i);
-
- if (v->get.fv == -1)
- continue;
+ int width = r->widths[i];
- if (v->type == NUMERIC)
- case_data_rw (perm, v->fv)->f = temp[v->get.fv].f;
+ if (width == 0)
+ {
+ double f = read_float (r);
+ if (f == second_lowest_value)
+ goto unexpected_eof;
+
+ case_data_rw (c, idx)->f = f;
+ idx++;
+ }
else
- memcpy (case_data_rw (perm, v->fv)->s, &temp[v->get.fv], v->width);
- }
+ {
+ char *s = read_string (r);
+ if (s == NULL)
+ goto unexpected_eof;
+ asciify (s);
- local_free (temp);
+ st_bare_pad_copy (case_data_rw (c, idx)->s, s, width);
+ idx += DIV_RND_UP (width, MAX_SHORT_STRING);
+ }
+ }
+
return 1;
unexpected_eof:
- lose ((h, _("End of file midway through case.")));
+ lose ((r, _("End of file midway through case.")));
- lossage:
- local_free (temp);
+ error:
return 0;
}
-
-static struct fh_ext_class pfm_r_class =
-{
- 5,
- N_("reading as a portable file"),
- pfm_close,
-};
--- /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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef PFM_READ_H
+#define PFM_READ_H
+
+/* Portable file reading. */
+
+/* Portable file types. */
+enum pfm_type
+ {
+ PFM_COMM, /* Formatted for communication. */
+ PFM_TAPE /* Formatted for tape. */
+ };
+
+/* Information produced by pfm_read_dictionary() that doesn't fit into
+ a dictionary struct. */
+struct pfm_read_info
+ {
+ char creation_date[11]; /* `dd mm yyyy' plus a null. */
+ char creation_time[9]; /* `hh:mm:ss' plus a null. */
+ char product[61]; /* Product name plus a null. */
+ char subproduct[61]; /* Subproduct name plus a null. */
+ };
+
+struct dictionary;
+struct file_handle;
+struct ccase;
+struct pfm_reader *pfm_open_reader (struct file_handle *,
+ struct dictionary **,
+ struct pfm_read_info *);
+int pfm_read_case (struct pfm_reader *, struct ccase *);
+void pfm_close_reader (struct pfm_reader *);
+
+#endif /* pfm-read.h */
02111-1307, USA. */
#include <config.h>
-#include "pfm.h"
+#include "pfm-write.h"
#include "error.h"
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <time.h>
#include "alloc.h"
+#include "case.h"
+#include "dictionary.h"
#include "error.h"
#include "file-handle.h"
#include "gmp.h"
#include "debug-print.h"
-/* pfm writer file_handle extension. */
-struct pfm_fhuser_ext
+/* Portable file writer. */
+struct pfm_writer
{
- FILE *file; /* Actual file. */
+ struct file_handle *fh; /* File handle. */
+ FILE *file; /* File stream. */
int lc; /* Number of characters on this line so far. */
- int nvars; /* Number of variables. */
- int *vars; /* Variable widths. */
+ size_t var_cnt; /* Number of variables. */
+ struct pfm_var *vars; /* Variables. */
};
-static struct fh_ext_class pfm_w_class;
+/* A variable to write to the portable file. */
+struct pfm_var
+ {
+ int width; /* 0=numeric, otherwise string var width. */
+ int fv; /* Starting case index. */
+ };
-static int bufwrite (struct file_handle *h, const void *buf, size_t nbytes);
-static int write_header (struct file_handle *h);
-static int write_version_data (struct file_handle *h);
-static int write_variables (struct file_handle *h, struct dictionary *d);
-static int write_value_labels (struct file_handle *h, struct dictionary *d);
+static int buf_write (struct pfm_writer *, const void *, size_t);
+static int write_header (struct pfm_writer *);
+static int write_version_data (struct pfm_writer *);
+static int write_variables (struct pfm_writer *, const struct dictionary *);
+static int write_value_labels (struct pfm_writer *, const struct dictionary *);
/* Writes the dictionary DICT to portable file HANDLE. Returns
nonzero only if successful. */
-int
-pfm_write_dictionary (struct file_handle *handle, struct dictionary *dict)
+struct pfm_writer *
+pfm_open_writer (struct file_handle *fh, const struct dictionary *dict)
{
- struct pfm_fhuser_ext *ext;
-
- if (handle->class != NULL)
- {
- msg (ME, _("Cannot write file %s as portable file: already opened "
- "for %s."),
- handle_get_name (handle), handle->class->name);
- return 0;
- }
+ struct pfm_writer *w = NULL;
+ size_t i;
- msg (VM (1), _("%s: Opening portable-file handle %s for writing."),
- handle_get_filename (handle), handle_get_name (handle));
+ if (!fh_open (fh, "portable file", "we"))
+ goto error;
/* Open the physical disk file. */
- handle->class = &pfm_w_class;
- handle->ext = ext = xmalloc (sizeof (struct pfm_fhuser_ext));
- ext->file = fopen (handle_get_filename (handle), "wb");
- ext->lc = 0;
- if (ext->file == NULL)
+ w = xmalloc (sizeof *w);
+ w->fh = fh;
+ w->file = fopen (handle_get_filename (fh), "wb");
+ w->lc = 0;
+ w->var_cnt = 0;
+ w->vars = NULL;
+
+ /* Check that file create succeeded. */
+ if (w->file == NULL)
{
msg (ME, _("An error occurred while opening \"%s\" for writing "
"as a portable file: %s."),
- handle_get_filename (handle), strerror (errno));
+ handle_get_filename (fh), strerror (errno));
err_cond_fail ();
- free (ext);
- return 0;
+ goto error;
}
- {
- int i;
-
- ext->nvars = dict_get_var_cnt (dict);
- ext->vars = xmalloc (sizeof *ext->vars * ext->nvars);
- for (i = 0; i < ext->nvars; i++)
- ext->vars[i] = dict_get_var (dict, i)->width;
- }
-
- /* Write the file header. */
- if (!write_header (handle))
- goto lossage;
-
- /* Write version data. */
- if (!write_version_data (handle))
- goto lossage;
-
- /* Write variables. */
- if (!write_variables (handle, dict))
- goto lossage;
-
- /* Write value labels. */
- if (!write_value_labels (handle, dict))
- goto lossage;
+ w->var_cnt = dict_get_var_cnt (dict);
+ w->vars = xmalloc (sizeof *w->vars * w->var_cnt);
+ for (i = 0; i < w->var_cnt; i++)
+ {
+ const struct variable *dv = dict_get_var (dict, i);
+ struct pfm_var *pv = &w->vars[i];
+ pv->width = dv->width;
+ pv->fv = dv->fv;
+ }
- /* Write beginning of data marker. */
- if (!bufwrite (handle, "F", 1))
- goto lossage;
+ /* Write file header. */
+ if (!write_header (w)
+ || !write_version_data (w)
+ || !write_variables (w, dict)
+ || !write_value_labels (w, dict)
+ || !buf_write (w, "F", 1))
+ goto error;
- msg (VM (2), _("Wrote portable-file header successfully."));
+ return w;
- return 1;
-
-lossage:
- msg (VM (1), _("Error writing portable-file header."));
- fclose (ext->file);
- free (ext->vars);
- handle->class = NULL;
- handle->ext = NULL;
- return 0;
+error:
+ pfm_close_writer (w);
+ return NULL;
}
\f
/* Write NBYTES starting at BUF to the portable file represented by
H. Break lines properly every 80 characters. */
static int
-bufwrite (struct file_handle *h, const void *buf_, size_t nbytes)
+buf_write (struct pfm_writer *w, const void *buf_, size_t nbytes)
{
const char *buf = buf_;
- struct pfm_fhuser_ext *ext = h->ext;
assert (buf != NULL);
- while (nbytes + ext->lc >= 80)
+ while (nbytes + w->lc >= 80)
{
- size_t n = 80 - ext->lc;
+ size_t n = 80 - w->lc;
- if (n && 1 != fwrite (buf, n, 1, ext->file))
- goto lossage;
+ if (n && fwrite (buf, n, 1, w->file) != 1)
+ goto error;
- /* PORTME: line ends. */
- if (1 != fwrite ("\r\n", 2, 1, ext->file))
- goto lossage;
+ if (fwrite ("\r\n", 2, 1, w->file) != 1)
+ goto error;
nbytes -= n;
buf += n;
- ext->lc = 0;
+ w->lc = 0;
}
- if (nbytes && 1 != fwrite (buf, nbytes, 1, ext->file))
- goto lossage;
- ext->lc += nbytes;
+ if (nbytes && 1 != fwrite (buf, nbytes, 1, w->file))
+ goto error;
+ w->lc += nbytes;
return 1;
- lossage:
- abort ();
+ error:
msg (ME, _("%s: Writing portable file: %s."),
- handle_get_filename (h), strerror (errno));
+ handle_get_filename (w->fh), strerror (errno));
return 0;
}
/* Write D to the portable file as a floating-point field, and return
success. */
static int
-write_float (struct file_handle *h, double d)
+write_float (struct pfm_writer *w, double d)
{
int neg = 0;
char *mantissa;
}
if (d == fabs (SYSMIS) || d == HUGE_VAL)
- return bufwrite (h, "*.", 2);
+ return buf_write (w, "*.", 2);
/* Use GNU libgmp2 to convert D into base-30. */
{
}
*cp++ = '/';
- success = bufwrite (h, buf, cp - buf);
+ success = buf_write (w, buf, cp - buf);
local_free (buf);
free (mantissa);
return success;
/* Write N to the portable file as an integer field, and return success. */
static int
-write_int (struct file_handle *h, int n)
+write_int (struct pfm_writer *w, int n)
{
char buf[64];
char *bp = &buf[64];
if (neg)
*--bp = '-';
- return bufwrite (h, bp, &buf[64] - bp);
+ return buf_write (w, bp, &buf[64] - bp);
}
/* Write S to the portable file as a string field. */
static int
-write_string (struct file_handle *h, const char *s)
+write_string (struct pfm_writer *w, const char *s)
{
size_t n = strlen (s);
- return write_int (h, (int) n) && bufwrite (h, s, n);
+ return write_int (w, (int) n) && buf_write (w, s, n);
}
\f
/* Write file header. */
static int
-write_header (struct file_handle *h)
+write_header (struct pfm_writer *w)
{
/* PORTME. */
{
int i;
for (i = 0; i < 5; i++)
- if (!bufwrite (h, "ASCII SPSS PORT FILE ", 40))
+ if (!buf_write (w, "ASCII SPSS PORT FILE ", 40))
return 0;
}
"0000000000000000000000000000000000000000000000000000000000000000"
};
- if (!bufwrite (h, spss2ascii, 256))
+ if (!buf_write (w, spss2ascii, 256))
return 0;
}
- if (!bufwrite (h, "SPSSPORT", 8))
+ if (!buf_write (w, "SPSSPORT", 8))
return 0;
return 1;
/* Writes version, date, and identification records. */
static int
-write_version_data (struct file_handle *h)
+write_version_data (struct pfm_writer *w)
{
- if (!bufwrite (h, "A", 1))
+ if (!buf_write (w, "A", 1))
return 0;
{
sprintf (date_str, "%04d%02d%02d",
tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday);
sprintf (time_str, "%02d%02d%02d", tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
- if (!write_string (h, date_str) || !write_string (h, time_str))
+ if (!write_string (w, date_str) || !write_string (w, time_str))
return 0;
}
/* Product identification. */
- if (!bufwrite (h, "1", 1) || !write_string (h, version))
+ if (!buf_write (w, "1", 1) || !write_string (w, version))
return 0;
/* Subproduct identification. */
- if (!bufwrite (h, "3", 1) || !write_string (h, host_system))
+ if (!buf_write (w, "3", 1) || !write_string (w, host_system))
return 0;
return 1;
/* Write format F to file H, and return success. */
static int
-write_format (struct file_handle *h, struct fmt_spec *f)
+write_format (struct pfm_writer *w, struct fmt_spec *f)
{
- return (write_int (h, formats[f->type].spss)
- && write_int (h, f->w)
- && write_int (h, f->d));
+ return (write_int (w, formats[f->type].spss)
+ && write_int (w, f->w)
+ && write_int (w, f->d));
}
/* Write value V for variable VV to file H, and return success. */
static int
-write_value (struct file_handle *h, union value *v, struct variable *vv)
+write_value (struct pfm_writer *w, union value *v, struct variable *vv)
{
if (vv->type == NUMERIC)
- return write_float (h, v->f);
+ return write_float (w, v->f);
else
- return write_int (h, vv->width) && bufwrite (h, v->s, vv->width);
+ return write_int (w, vv->width) && buf_write (w, v->s, vv->width);
}
/* Write variable records, and return success. */
static int
-write_variables (struct file_handle *h, struct dictionary *dict)
+write_variables (struct pfm_writer *w, const struct dictionary *dict)
{
int i;
- if (!bufwrite (h, "4", 1) || !write_int (h, dict_get_var_cnt (dict))
- || !write_int (h, 161))
+ if (!buf_write (w, "4", 1) || !write_int (w, dict_get_var_cnt (dict))
+ || !write_int (w, 161))
return 0;
for (i = 0; i < dict_get_var_cnt (dict); i++)
struct variable *v = dict_get_var (dict, i);
- if (!bufwrite (h, "7", 1) || !write_int (h, v->width)
- || !write_string (h, v->name)
- || !write_format (h, &v->print) || !write_format (h, &v->write))
+ if (!buf_write (w, "7", 1) || !write_int (w, v->width)
+ || !write_string (w, v->name)
+ || !write_format (w, &v->print) || !write_format (w, &v->write))
return 0;
for (m = miss_types[v->miss_type], j = 0; j < (int) strlen (m); j++)
- if ((m[j] != ' ' && !bufwrite (h, &m[j], 1))
- || !write_value (h, &v->missing[j], v))
+ if ((m[j] != ' ' && !buf_write (w, &m[j], 1))
+ || !write_value (w, &v->missing[j], v))
return 0;
- if (v->label && (!bufwrite (h, "C", 1) || !write_string (h, v->label)))
+ if (v->label && (!buf_write (w, "C", 1) || !write_string (w, v->label)))
return 0;
}
/* Write value labels to disk. FIXME: Inefficient. */
static int
-write_value_labels (struct file_handle *h, struct dictionary *dict)
+write_value_labels (struct pfm_writer *w, const struct dictionary *dict)
{
int i;
if (!val_labs_count (v->val_labs))
continue;
- if (!bufwrite (h, "D", 1)
- || !write_int (h, 1)
- || !write_string (h, v->name)
- || !write_int (h, val_labs_count (v->val_labs)))
+ if (!buf_write (w, "D", 1)
+ || !write_int (w, 1)
+ || !write_string (w, v->name)
+ || !write_int (w, val_labs_count (v->val_labs)))
return 0;
for (vl = val_labs_first_sorted (v->val_labs, &j); vl != NULL;
vl = val_labs_next (v->val_labs, &j))
- if (!write_value (h, &vl->value, v)
- || !write_string (h, vl->label))
+ if (!write_value (w, &vl->value, v)
+ || !write_string (w, vl->label))
{
val_labs_done (&j);
return 0;
/* Writes case ELEM to the portable file represented by H. Returns
success. */
int
-pfm_write_case (struct file_handle *h, const union value *elem)
+pfm_write_case (struct pfm_writer *w, struct ccase *c)
{
- struct pfm_fhuser_ext *ext = h->ext;
-
int i;
- for (i = 0; i < ext->nvars; i++)
+ for (i = 0; i < w->var_cnt; i++)
{
- const int width = ext->vars[i];
+ struct pfm_var *v = &w->vars[i];
- if (width == 0)
+ if (v->width == 0)
{
- if (!write_float (h, elem[i].f))
+ if (!write_float (w, case_num (c, v->fv)))
return 0;
}
else
{
- if (!write_int (h, width) || !bufwrite (h, elem[i].c, width))
+ if (!write_int (w, v->width)
+ || !buf_write (w, case_str (c, v->fv), v->width))
return 0;
}
}
}
/* Closes a portable file after we're done with it. */
-static void
-pfm_close (struct file_handle *h)
+void
+pfm_close_writer (struct pfm_writer *w)
{
- struct pfm_fhuser_ext *ext = h->ext;
+ if (w == NULL)
+ return;
+
+ fh_close (w->fh, "portable file", "we");
- {
- char buf[80];
+ if (w->file != NULL)
+ {
+ char buf[80];
- int n = 80 - ext->lc;
- if (n == 0)
- n = 80;
+ int n = 80 - w->lc;
+ if (n == 0)
+ n = 80;
- memset (buf, 'Z', n);
- bufwrite (h, buf, n);
- }
+ memset (buf, 'Z', n);
+ buf_write (w, buf, n);
- if (EOF == fclose (ext->file))
- msg (ME, _("%s: Closing portable file: %s."),
- handle_get_filename (h), strerror (errno));
+ if (fclose (w->file) == EOF)
+ msg (ME, _("%s: Closing portable file: %s."),
+ handle_get_filename (w->fh), strerror (errno));
+ }
- free (ext->vars);
- free (ext);
+ free (w->vars);
+ free (w);
}
-
-static struct fh_ext_class pfm_w_class =
-{
- 6,
- N_("writing as a portable file"),
- pfm_close,
-};
--- /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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef PFM_WRITE_H
+#define PFM_WRITE_H
+
+/* Portable file writing. */
+
+struct file_handle;
+struct dictionary;
+struct ccase;
+struct pfm_writer *pfm_open_writer (struct file_handle *,
+ const struct dictionary *);
+int pfm_write_case (struct pfm_writer *, struct ccase *);
+void pfm_close_writer (struct pfm_writer *);
+
+#endif /* pfm-write.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., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
-
-#if !pfm_h
-#define pfm_h 1
-
-/* Portable file manager (pfm).
-
- This module is in charge of reading and writing portable files.
- pfm is an fhuser, so see file-handle.h for the fhuser interface. */
-
-/* Portable file types. */
-enum
- {
- PFM_COMM,
- PFM_TAPE
- };
-
-/* Information produced by pfm_read_dictionary() that doesn't fit into
- a dictionary struct. */
-struct pfm_read_info
- {
- char creation_date[11]; /* `dd mm yyyy' plus a null. */
- char creation_time[9]; /* `hh:mm:ss' plus a null. */
- char product[61]; /* Product name plus a null. */
- char subproduct[61]; /* Subproduct name plus a null. */
- };
-
-struct dictionary;
-struct file_handle;
-struct ccase;
-union value;
-
-struct dictionary *pfm_read_dictionary (struct file_handle *,
- struct pfm_read_info *);
-int pfm_read_case (struct file_handle *, struct ccase *, struct dictionary *);
-
-int pfm_write_dictionary (struct file_handle *, struct dictionary *);
-int pfm_write_case (struct file_handle *, const union value *elem);
-
-#endif /* !pfm_h */
02111-1307, USA. */
+#include <config.h>
#include "chart.h"
#include <float.h>
#include <assert.h>
#include <math.h>
#include <stdio.h>
+#include "str.h"
#include "value-labels.h"
/* Pie charts of course need to know Pi :) */
+#ifndef M_PI
#define M_PI ( 22.0 / 7.0 )
+#endif
#define min(A,B) ((A>B)?B:A)
/* Draw a pie chart */
void
-draw_piechart(struct chart *ch, const struct variable *var)
+draw_piechart(struct chart *ch, const struct variable *var,
+ const struct freq_tab *frq_tab)
{
int i;
- const struct freq_tab *frq_tab = &var->p.frq.tab ;
-
const int n_data = frq_tab->n_valid;
const double left_label = ch->data_left +
(ch->data_right - ch->data_left)/10.0;
#include "alloc.h"
#include "case.h"
#include "command.h"
-#include "dfm.h"
+#include "dfm-write.h"
#include "error.h"
#include "expr.h"
#include "file-handle.h"
PRT_CMD_MASK = 1, /* Command type mask. */
PRT_PRINT = 0, /* PRINT transformation identifier. */
PRT_WRITE = 1, /* WRITE transformation identifier. */
- PRT_EJECT = 002 /* Can be combined with CMD_PRINT only. */
+ PRT_EJECT = 002, /* Can be combined with CMD_PRINT only. */
+ PRT_BINARY = 004 /* File is binary, omit newlines. */
};
/* PRINT, PRINT EJECT, WRITE private data structure. */
struct print_trns
{
struct trns_header h;
- struct file_handle *handle; /* Output file, NULL=listing file. */
+ struct dfm_writer *writer; /* Output file, NULL=listing file. */
int options; /* PRT_* bitmapped field. */
struct prt_out_spec *spec; /* Output specifications. */
int max_width; /* Maximum line width including null. */
static trns_proc_func print_trns_proc;
static trns_free_func print_trns_free;
static int parse_specs (void);
-static void dump_table (void);
-static void append_var_spec (struct prt_out_spec *spec);
+static void dump_table (const struct file_handle *);
+static void append_var_spec (struct prt_out_spec *);
static void alloc_line (void);
\f
/* Basic parsing. */
static int
internal_cmd_print (int f)
{
- /* 0=print no table, 1=print table. (TABLE subcommand.) */
- int table = 0;
-
- /* malloc()'d transformation. */
- struct print_trns *trns;
+ int table = 0; /* Print table? */
+ struct print_trns *trns; /* malloc()'d transformation. */
+ struct file_handle *fh = NULL;
/* Fill in prt to facilitate error-handling. */
prt.h.proc = print_trns_proc;
prt.h.free = print_trns_free;
- prt.handle = NULL;
+ prt.writer = NULL;
prt.options = f;
prt.spec = NULL;
prt.line = NULL;
{
lex_match ('=');
- prt.handle = fh_parse_file_handle ();
- if (!prt.handle)
- goto lossage;
+ fh = fh_parse ();
+ if (fh == NULL)
+ goto error;
}
else if (lex_match_id ("RECORDS"))
{
lex_match ('=');
lex_match ('(');
if (!lex_force_int ())
- goto lossage;
+ goto error;
nrec = lex_integer ();
lex_get ();
lex_match (')');
else
{
lex_error (_("expecting a valid subcommand"));
- goto lossage;
+ goto error;
}
}
/* Parse variables and strings. */
if (!parse_specs ())
- goto lossage;
-
- if (prt.handle != NULL && !dfm_open_for_writing (prt.handle))
- goto lossage;
+ goto error;
+
+ if (fh != NULL)
+ {
+ prt.writer = dfm_open_writer (fh);
+ if (prt.writer == NULL)
+ goto error;
+
+ if (handle_get_mode (fh) == MODE_BINARY)
+ prt.options |= PRT_BINARY;
+ }
/* Output the variable table if requested. */
if (table)
- dump_table ();
+ dump_table (fh);
/* Count the maximum line width. Allocate linebuffer if
applicable. */
return CMD_SUCCESS;
- lossage:
+ error:
print_trns_free ((struct trns_header *) & prt);
return CMD_FAILURE;
}
/* Prints the table produced by the TABLE subcommand to the listing
file. */
static void
-dump_table (void)
+dump_table (const struct file_handle *fh)
{
struct prt_out_spec *spec;
struct tab_table *t;
assert (0);
}
- if (prt.handle != NULL)
+ if (fh != NULL)
tab_title (t, 1, _("Writing %d record(s) to file %s."),
- recno, handle_get_filename (prt.handle));
+ recno, handle_get_filename (fh));
else
tab_title (t, 1, _("Writing %d record(s) to the listing file."), recno);
tab_submit (t);
if (t->options & PRT_EJECT)
som_eject_page ();
- /* Note that a field written to a place where a field has already
- been written truncates the record. `PRINT /A B (T10,F8,T1,F8).'
- only outputs B. This is an example of bug-for-bug compatibility,
- in the author's opinion. */
+ /* Note that a field written to a place where a field has
+ already been written truncates the record. `PRINT /A B
+ (T10,F8,T1,F8).' only outputs B. */
for (i = t->spec; i; i = i->next)
switch (i->type)
{
case PRT_NEWLINE:
- if (t->handle == NULL)
+ if (t->writer == NULL)
{
buf[len] = 0;
tab_output_text (TAT_FIX | TAT_NOWRAP, buf);
else
{
if ((t->options & PRT_CMD_MASK) == PRT_PRINT
- || handle_get_mode (t->handle) != MODE_BINARY)
+ || !(t->options & PRT_BINARY))
{
/* PORTME: Line ends. */
#ifdef __MSDOS__
buf[len++] = '\n';
}
- dfm_put_record (t->handle, buf, len);
+ dfm_put_record (t->writer, buf, len);
}
memset (buf, ' ', t->max_width);
{
struct trns_header h;
- struct file_handle *handle; /* Output file, NULL=listing file. */
+ struct dfm_writer *writer; /* Output data file. */
struct expression *e; /* Number of lines; NULL=1. */
}
print_space_trns;
cmd_print_space (void)
{
struct print_space_trns *t;
- struct file_handle *handle;
+ struct file_handle *fh;
struct expression *e;
+ struct dfm_writer *writer;
if (lex_match_id ("OUTFILE"))
{
lex_match ('=');
- handle = fh_parse_file_handle ();
- if (handle == NULL)
+ fh = fh_parse ();
+ if (fh == NULL)
return CMD_FAILURE;
lex_get ();
}
else
- handle = NULL;
+ fh = NULL;
if (token != '.')
{
else
e = NULL;
- if (handle != NULL && !dfm_open_for_writing (handle))
+ if (fh != NULL)
{
- expr_free (e);
- return CMD_FAILURE;
+ writer = dfm_open_writer (fh);
+ if (writer == NULL)
+ {
+ expr_free (e);
+ return CMD_FAILURE;
+ }
}
-
+ else
+ writer = NULL;
+
t = xmalloc (sizeof *t);
t->h.proc = print_space_trns_proc;
if (e)
t->h.free = print_space_trns_free;
else
t->h.free = NULL;
- t->handle = handle;
+ t->writer = writer;
t->e = e;
add_transformation ((struct trns_header *) t);
else
n = 1;
- if (t->handle == NULL)
+ if (t->writer == NULL)
while (n--)
som_blank_line ();
else
buf[0] = '\n';
#endif
while (n--)
- dfm_put_record (t->handle, buf, LINE_END_WIDTH);
+ dfm_put_record (t->writer, buf, LINE_END_WIDTH);
}
return -1;
dump (0, " Generated by q2c from %s on %s.", ifn, timep);
dump (0, " Do not modify!");
dump (0, " */");
-
- dump (0, nullstr);
- dump (0, "#include \"settings.h\"");
- dump (0, "#include \"subclist.h\"");
- dump (0, nullstr);
}
/* Write out commands to free variable state. */
dump (0, "#include \"alloc.h\"");
dump (0, "#include \"error.h\"");
dump (0, "#include \"lexer.h\"");
+ dump (0, "#include \"settings.h\"");
dump (0, "#include \"str.h\"");
+ dump (0, "#include \"subclist.h\"");
dump (0, "#include \"var.h\"");
dump (0, nullstr);
#include "alloc.h"
#include "case.h"
#include "command.h"
+#include "dictionary.h"
#include "error.h"
#include "lexer.h"
#include "magic.h"
#include "error.h"
#include "alloc.h"
#include "command.h"
+#include "dictionary.h"
#include "error.h"
#include "hash.h"
#include "lexer.h"
#include <stdlib.h>
#include "alloc.h"
#include "command.h"
+#include "dictionary.h"
#include "error.h"
#include "getline.h"
#include "lexer.h"
#include <config.h>
#include "alloc.h"
#include "command.h"
+#include "dictionary.h"
#include "error.h"
#include "expr.h"
#include "lexer.h"
02111-1307, USA. */
#include <config.h>
-#include "sfm.h"
+#include "sfm-read.h"
#include "sfmP.h"
#include "error.h"
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <float.h>
+#include <setjmp.h>
#include "alloc.h"
#include "case.h"
+#include "dictionary.h"
#include "error.h"
#include "file-handle.h"
#include "filename.h"
#include "debug-print.h"
-/* PORTME: This file may require substantial revision for those
- systems that don't meet the typical 32-bit integer/64-bit double
- model. It's kinda hard to tell without having one of them on my
- desk. */
-
-/* sfm's file_handle extension. */
-struct sfm_fhuser_ext
+/* System file reader. */
+struct sfm_reader
{
- FILE *file; /* Actual file. */
- int opened; /* Reference count. */
-
- struct dictionary *dict; /* File's dictionary. */
+ struct file_handle *fh; /* File handle. */
+ FILE *file; /* File stream. */
int reverse_endian; /* 1=file has endianness opposite us. */
- int case_size; /* Number of `values's per case. */
- long ncases; /* Number of cases, -1 if unknown. */
+ int fix_specials; /* 1=SYSMIS/HIGHEST/LOWEST differs from us. */
+ int value_cnt; /* Number of `union values's per case. */
+ long case_cnt; /* Number of cases, -1 if unknown. */
int compressed; /* 1=compressed, 0=not compressed. */
double bias; /* Compression bias, usually 100.0. */
- int weight_index; /* 0-based index of weighting variable, or -1. */
+ int weight_idx; /* 0-based index of weighting variable, or -1. */
+
+ /* Variables. */
+ struct sfm_var *vars; /* Variables. */
+ size_t var_cnt; /* Number of variables. */
/* File's special constants. */
flt64 sysmis;
flt64 highest;
flt64 lowest;
- /* Uncompression buffer. */
+ /* Decompression buffer. */
flt64 *buf; /* Buffer data. */
flt64 *ptr; /* Current location in buffer. */
flt64 *end; /* End of buffer data. */
/* Compression instruction octet. */
- unsigned char x[sizeof (flt64)];
- /* Current instruction octet. */
+ unsigned char x[8]; /* Current instruction octet. */
unsigned char *y; /* Location in current instruction octet. */
};
-static struct fh_ext_class sfm_r_class;
+/* A variable in a system file. */
+struct sfm_var
+ {
+ int width; /* 0=numeric, otherwise string width. */
+ int fv; /* Index into case. */
+ };
\f
/* Utilities. */
-/* bswap_int32(): Reverse the byte order of 32-bit integer *X. */
+/* Swap bytes *A and *B. */
static inline void
-bswap_int32 (int32 *x)
+bswap (unsigned char *a, unsigned char *b)
{
- unsigned char *y = (unsigned char *) x;
- unsigned char t;
-
- t = y[0];
- y[0] = y[3];
- y[3] = t;
+ unsigned char t = *a;
+ *a = *b;
+ *b = t;
+}
- t = y[1];
- y[1] = y[2];
- y[2] = t;
+/* bswap_int32(): Reverse the byte order of 32-bit integer *X. */
+static inline void
+bswap_int32 (int32 *x_)
+{
+ unsigned char *x = (unsigned char *) x_;
+ bswap (x + 0, x + 3);
+ bswap (x + 1, x + 2);
}
/* Reverse the byte order of 64-bit floating point *X. */
static inline void
-bswap_flt64 (flt64 *x)
+bswap_flt64 (flt64 *x_)
{
- unsigned char *y = (unsigned char *) x;
- unsigned char t;
-
- t = y[0];
- y[0] = y[7];
- y[7] = t;
-
- t = y[1];
- y[1] = y[6];
- y[6] = t;
-
- t = y[2];
- y[2] = y[5];
- y[5] = t;
-
- t = y[3];
- y[3] = y[4];
- y[4] = t;
+ unsigned char *x = (unsigned char *) x_;
+ bswap (x + 0, x + 7);
+ bswap (x + 1, x + 6);
+ bswap (x + 2, x + 5);
+ bswap (x + 3, x + 4);
}
static void
}
/* Closes a system file after we're done with it. */
-static void
-sfm_close (struct file_handle *h)
-{
- struct sfm_fhuser_ext *ext = h->ext;
-
- ext->opened--;
- assert (ext->opened == 0);
- if (EOF == fn_close (handle_get_filename (h), ext->file))
- msg (ME, _("%s: Closing system file: %s."),
- handle_get_filename (h), strerror (errno));
- free (ext->buf);
- free (h->ext);
-}
-
-/* Closes a system file if we're done with it. */
void
-sfm_maybe_close (struct file_handle *h)
+sfm_close_reader (struct sfm_reader *r)
{
- struct sfm_fhuser_ext *ext = h->ext;
+ if (r == NULL)
+ return;
- if (ext->opened == 1)
- fh_close_handle (h);
- else
- ext->opened--;
+ if (r->fh != NULL)
+ fh_close (r->fh, "system file", "rs");
+ if (fn_close (handle_get_filename (r->fh), r->file) == EOF)
+ msg (ME, _("%s: Closing system file: %s."),
+ handle_get_filename (r->fh), strerror (errno));
+ free (r->vars);
+ free (r->buf);
+ free (r);
}
\f
/* Dictionary reader. */
-static void *bufread (struct file_handle *handle, void *buf, size_t nbytes,
- size_t minalloc);
+static void *buf_read (struct sfm_reader *, void *buf, size_t byte_cnt,
+ size_t min_alloc);
+
+static int read_header (struct sfm_reader *,
+ struct dictionary *, struct sfm_read_info *);
+static int parse_format_spec (struct sfm_reader *, int32,
+ struct fmt_spec *, struct variable *);
+static int read_value_labels (struct sfm_reader *, struct dictionary *,
+ struct variable **var_by_idx);
+static int read_variables (struct sfm_reader *,
+ struct dictionary *, struct variable ***var_by_idx);
+static int read_machine_int32_info (struct sfm_reader *, int size, int count);
+static int read_machine_flt64_info (struct sfm_reader *, int size, int count);
+static int read_documents (struct sfm_reader *, struct dictionary *);
-static int read_header (struct file_handle *h, struct sfm_read_info *inf);
-static int parse_format_spec (struct file_handle *h, int32 s,
- struct fmt_spec *v, struct variable *vv);
-static int read_value_labels (struct file_handle *h, struct variable **var_by_index);
-static int read_variables (struct file_handle *h, struct variable ***var_by_index);
-static int read_machine_int32_info (struct file_handle *h, int size, int count);
-static int read_machine_flt64_info (struct file_handle *h, int size, int count);
-static int read_documents (struct file_handle *h);
+static int fread_ok (struct sfm_reader *, void *, size_t);
-/* Displays the message X with corrupt_msg, then jumps to the lossage
+/* Displays the message X with corrupt_msg, then jumps to the error
label. */
-#define lose(X) \
- do \
- { \
- corrupt_msg X; \
- goto lossage; \
- } \
- while (0)
-
-/* Calls bufread with the specified arguments, and jumps to lossage if
- the read fails. */
-#define assertive_bufread(a,b,c,d) \
- do \
- { \
- if (!bufread (a,b,c,d)) \
- goto lossage; \
- } \
- while (0)
-
-/* Reads the dictionary from file with handle H, and returns it in a
- dictionary structure. This dictionary may be modified in order to
- rename, reorder, and delete variables, etc. */
-struct dictionary *
-sfm_read_dictionary (struct file_handle *h, struct sfm_read_info *inf)
+#define lose(X) \
+ do { \
+ corrupt_msg X; \
+ goto error; \
+ } while (0)
+
+/* Calls buf_read with the specified arguments, and jumps to
+ error if the read fails. */
+#define assertive_buf_read(a,b,c,d) \
+ do { \
+ if (!buf_read (a,b,c,d)) \
+ goto error; \
+ } while (0)
+
+/* Opens the system file designated by file handle FH for
+ reading. Reads the system file's dictionary into *DICT.
+ If INFO is non-null, then it receives additional info about the
+ system file. */
+struct sfm_reader *
+sfm_open_reader (struct file_handle *fh, struct dictionary **dict,
+ struct sfm_read_info *info)
{
- /* The file handle extension record. */
- struct sfm_fhuser_ext *ext;
-
- /* Allows for quick reference to variables according to indexes
- relative to position within a case. */
- struct variable **var_by_index = NULL;
-
- /* Check whether the file is already open. */
- if (h->class == &sfm_r_class)
- {
- ext = h->ext;
- ext->opened++;
- return ext->dict;
- }
- else if (h->class != NULL)
- {
- msg (ME, _("Cannot read file %s as system file: already opened for %s."),
- handle_get_name (h), h->class->name);
- return NULL;
- }
-
- msg (VM (1), _("%s: Opening system-file handle %s for reading."),
- handle_get_filename (h), handle_get_name (h));
-
- /* Open the physical disk file. */
- ext = xmalloc (sizeof (struct sfm_fhuser_ext));
- ext->file = fn_open (handle_get_filename (h), "rb");
- if (ext->file == NULL)
+ struct sfm_reader *r = NULL;
+ struct variable **var_by_idx = NULL;
+
+ *dict = dict_create ();
+ if (!fh_open (fh, "system file", "rs"))
+ goto error;
+
+ /* Create and initialize reader. */
+ r = xmalloc (sizeof *r);
+ r->fh = fh;
+ r->file = fn_open (handle_get_filename (fh), "rb");
+
+ r->reverse_endian = 0;
+ r->fix_specials = 0;
+ r->value_cnt = 0;
+ r->case_cnt = 0;
+ r->compressed = 0;
+ r->bias = 100.0;
+ r->weight_idx = -1;
+
+ r->vars = NULL;
+ r->var_cnt = 0;
+
+ r->sysmis = -FLT64_MAX;
+ r->highest = FLT64_MAX;
+ r->lowest = second_lowest_flt64;
+
+ r->buf = r->ptr = r->end = NULL;
+ r->y = r->x + sizeof r->x;
+
+ /* Check that file open succeeded. */
+ if (r->file == NULL)
{
msg (ME, _("An error occurred while opening \"%s\" for reading "
"as a system file: %s."),
- handle_get_filename (h), strerror (errno));
+ handle_get_filename (r->fh), strerror (errno));
err_cond_fail ();
- free (ext);
- return NULL;
+ goto error;
}
- /* Initialize the sfm_fhuser_ext structure. */
- h->class = &sfm_r_class;
- h->ext = ext;
- ext->dict = NULL;
- ext->buf = ext->ptr = ext->end = NULL;
- ext->y = ext->x + sizeof ext->x;
- ext->opened = 1;
-
- /* Default special constants. */
- ext->sysmis = -FLT64_MAX;
- ext->highest = FLT64_MAX;
- ext->lowest = second_lowest_flt64;
-
- /* Read the header. */
- if (!read_header (h, inf))
- goto lossage;
-
- /* Read about the variables. */
- if (!read_variables (h, &var_by_index))
- goto lossage;
+ /* Read header and variables. */
+ if (!read_header (r, *dict, info) || !read_variables (r, *dict, &var_by_idx))
+ goto error;
/* Handle weighting. */
- if (ext->weight_index != -1)
+ if (r->weight_idx != -1)
{
- struct variable *wv = var_by_index[ext->weight_index];
+ struct variable *weight_var = var_by_idx[r->weight_idx];
- if (wv == NULL)
- lose ((ME, _("%s: Weighting variable may not be a continuation of "
- "a long string variable."), handle_get_filename (h)));
- else if (wv->type == ALPHA)
+ if (weight_var == NULL)
+ lose ((ME,
+ _("%s: Weighting variable may not be a continuation of "
+ "a long string variable."), handle_get_filename (fh)));
+ else if (weight_var->type == ALPHA)
lose ((ME, _("%s: Weighting variable may not be a string variable."),
- handle_get_filename (h)));
+ handle_get_filename (fh)));
- dict_set_weight (ext->dict, wv);
+ dict_set_weight (*dict, weight_var);
}
else
- dict_set_weight (ext->dict, NULL);
+ dict_set_weight (*dict, NULL);
/* Read records of types 3, 4, 6, and 7. */
for (;;)
{
int32 rec_type;
- assertive_bufread (h, &rec_type, sizeof rec_type, 0);
- if (ext->reverse_endian)
+ assertive_buf_read (r, &rec_type, sizeof rec_type, 0);
+ if (r->reverse_endian)
bswap_int32 (&rec_type);
switch (rec_type)
{
case 3:
- if (!read_value_labels (h, var_by_index))
- goto lossage;
+ if (!read_value_labels (r, *dict, var_by_idx))
+ goto error;
break;
case 4:
lose ((ME, _("%s: Orphaned variable index record (type 4). Type 4 "
"records must always immediately follow type 3 "
"records."),
- handle_get_filename (h)));
+ handle_get_filename (r->fh)));
case 6:
- if (!read_documents (h))
- goto lossage;
+ if (!read_documents (r, *dict))
+ goto error;
break;
case 7:
int skip = 0;
- assertive_bufread (h, &data, sizeof data, 0);
- if (ext->reverse_endian)
+ assertive_buf_read (r, &data, sizeof data, 0);
+ if (r->reverse_endian)
{
bswap_int32 (&data.subtype);
bswap_int32 (&data.size);
switch (data.subtype)
{
case 3:
- if (!read_machine_int32_info (h, data.size, data.count))
- goto lossage;
+ if (!read_machine_int32_info (r, data.size, data.count))
+ goto error;
break;
case 4:
- if (!read_machine_flt64_info (h, data.size, data.count))
- goto lossage;
+ if (!read_machine_flt64_info (r, data.size, data.count))
+ goto error;
break;
case 5:
default:
msg (MW, _("%s: Unrecognized record type 7, subtype %d "
"encountered in system file."),
- handle_get_filename (h), data.subtype);
+ handle_get_filename (r->fh), data.subtype);
skip = 1;
}
if (skip)
{
- void *x = bufread (h, NULL, data.size * data.count, 0);
+ void *x = buf_read (r, NULL, data.size * data.count, 0);
if (x == NULL)
- goto lossage;
+ goto error;
free (x);
}
}
{
int32 filler;
- assertive_bufread (h, &filler, sizeof filler, 0);
- goto break_out_of_loop;
+ assertive_buf_read (r, &filler, sizeof filler, 0);
+ goto success;
}
default:
lose ((ME, _("%s: Unrecognized record type %d."),
- handle_get_filename (h), rec_type));
+ handle_get_filename (r->fh), rec_type));
}
}
-break_out_of_loop:
+success:
/* Come here on successful completion. */
- msg (VM (2), _("Read system-file dictionary successfully."));
-
- free (var_by_index);
- return ext->dict;
+ free (var_by_idx);
+ return r;
-lossage:
+error:
/* Come here on unsuccessful completion. */
- msg (VM (1), _("Error reading system-file header."));
-
- free (var_by_index);
- fn_close (handle_get_filename (h), ext->file);
- if (ext && ext->dict)
- dict_destroy (ext->dict);
- free (ext);
- h->class = NULL;
- h->ext = NULL;
+ sfm_close_reader (r);
+ free (var_by_idx);
+ if (*dict != NULL)
+ {
+ dict_destroy (*dict);
+ *dict = NULL;
+ }
return NULL;
}
/* Read record type 7, subtype 3. */
static int
-read_machine_int32_info (struct file_handle *h, int size, int count)
+read_machine_int32_info (struct sfm_reader *r, int size, int count)
{
- struct sfm_fhuser_ext *ext = h->ext;
-
int32 data[8];
int file_bigendian;
if (size != sizeof (int32) || count != 8)
lose ((ME, _("%s: Bad size (%d) or count (%d) field on record type 7, "
"subtype 3. Expected size %d, count 8."),
- handle_get_filename (h), size, count, sizeof (int32)));
+ handle_get_filename (r->fh), size, count, sizeof (int32)));
- assertive_bufread (h, data, sizeof data, 0);
- if (ext->reverse_endian)
+ assertive_buf_read (r, data, sizeof data, 0);
+ if (r->reverse_endian)
for (i = 0; i < 8; i++)
bswap_int32 (&data[i]);
- /* PORTME: Check floating-point representation. */
#ifdef FPREP_IEEE754
if (data[4] != 1)
lose ((ME, _("%s: Floating-point representation in system file is not "
"IEEE-754. PSPP cannot convert between floating-point "
"formats."),
- handle_get_filename (h)));
+ handle_get_filename (r->fh)));
+#else
+#error Add support for your floating-point format.
#endif
- /* PORTME: Check recorded file endianness against intuited file
- endianness. */
#ifdef WORDS_BIGENDIAN
file_bigendian = 1;
#else
file_bigendian = 0;
#endif
- if (ext->reverse_endian)
+ if (r->reverse_endian)
file_bigendian ^= 1;
if (file_bigendian ^ (data[6] == 1))
- lose ((ME, _("%s: File-indicated endianness (%s) does not match endianness "
- "intuited from file header (%s)."),
- handle_get_filename (h),
+ lose ((ME, _("%s: File-indicated endianness (%s) does not match "
+ "endianness intuited from file header (%s)."),
+ handle_get_filename (r->fh),
file_bigendian ? _("big-endian") : _("little-endian"),
data[6] == 1 ? _("big-endian") : (data[6] == 2 ? _("little-endian")
: _("unknown"))));
/* PORTME: Character representation code. */
- if (data[7] != 2 && data[7] != 3)
- lose ((ME, _("%s: File-indicated character representation code (%s) is not "
- "ASCII."),
- handle_get_filename (h),
+ if (data[7] != 2 && data[7] != 3)
+ lose ((ME, _("%s: File-indicated character representation code (%s) is "
+ "not ASCII."),
+ handle_get_filename (r->fh),
(data[7] == 1 ? "EBCDIC"
: (data[7] == 4 ? _("DEC Kanji") : _("Unknown")))));
return 1;
-lossage:
+error:
return 0;
}
/* Read record type 7, subtype 4. */
static int
-read_machine_flt64_info (struct file_handle *h, int size, int count)
+read_machine_flt64_info (struct sfm_reader *r, int size, int count)
{
- struct sfm_fhuser_ext *ext = h->ext;
-
flt64 data[3];
-
int i;
if (size != sizeof (flt64) || count != 3)
lose ((ME, _("%s: Bad size (%d) or count (%d) field on record type 7, "
"subtype 4. Expected size %d, count 8."),
- handle_get_filename (h), size, count, sizeof (flt64)));
+ handle_get_filename (r->fh), size, count, sizeof (flt64)));
- assertive_bufread (h, data, sizeof data, 0);
- if (ext->reverse_endian)
+ assertive_buf_read (r, data, sizeof data, 0);
+ if (r->reverse_endian)
for (i = 0; i < 3; i++)
bswap_flt64 (&data[i]);
if (data[0] != SYSMIS || data[1] != FLT64_MAX
|| data[2] != second_lowest_flt64)
{
- ext->sysmis = data[0];
- ext->highest = data[1];
- ext->lowest = data[2];
+ r->sysmis = data[0];
+ r->highest = data[1];
+ r->lowest = data[2];
msg (MW, _("%s: File-indicated value is different from internal value "
"for at least one of the three system values. SYSMIS: "
"indicated %g, expected %g; HIGHEST: %g, %g; LOWEST: "
"%g, %g."),
- handle_get_filename (h), (double) data[0], (double) SYSMIS,
+ handle_get_filename (r->fh), (double) data[0], (double) SYSMIS,
(double) data[1], (double) FLT64_MAX,
(double) data[2], (double) second_lowest_flt64);
}
return 1;
-lossage:
+error:
return 0;
}
static int
-read_header (struct file_handle *h, struct sfm_read_info *inf)
+read_header (struct sfm_reader *r,
+ struct dictionary *dict, struct sfm_read_info *info)
{
- struct sfm_fhuser_ext *ext = h->ext; /* File extension strcut. */
struct sysfile_header hdr; /* Disk buffer. */
- struct dictionary *dict; /* File dictionary. */
char prod_name[sizeof hdr.prod_name + 1]; /* Buffer for product name. */
int skip_amt = 0; /* Amount of product name to omit. */
int i;
- /* Create the dictionary. */
- dict = ext->dict = dict_create ();
-
/* Read header, check magic. */
- assertive_bufread (h, &hdr, sizeof hdr, 0);
- if (0 != strncmp ("$FL2", hdr.rec_type, 4))
+ assertive_buf_read (r, &hdr, sizeof hdr, 0);
+ if (strncmp ("$FL2", hdr.rec_type, 4) != 0)
lose ((ME, _("%s: Bad magic. Proper system files begin with "
"the four characters `$FL2'. This file will not be read."),
- handle_get_filename (h)));
+ handle_get_filename (r->fh)));
/* Check eye-catcher string. */
memcpy (prod_name, hdr.prod_name, sizeof hdr.prod_name);
}
/* Check endianness. */
- /* PORTME: endianness. */
if (hdr.layout_code == 2)
- ext->reverse_endian = 0;
+ r->reverse_endian = 0;
else
{
bswap_int32 (&hdr.layout_code);
if (hdr.layout_code != 2)
lose ((ME, _("%s: File layout code has unexpected value %d. Value "
"should be 2, in big-endian or little-endian format."),
- handle_get_filename (h), hdr.layout_code));
+ handle_get_filename (r->fh), hdr.layout_code));
- ext->reverse_endian = 1;
+ r->reverse_endian = 1;
bswap_int32 (&hdr.case_size);
- bswap_int32 (&hdr.compressed);
- bswap_int32 (&hdr.weight_index);
- bswap_int32 (&hdr.ncases);
+ bswap_int32 (&hdr.compress);
+ bswap_int32 (&hdr.weight_idx);
+ bswap_int32 (&hdr.case_cnt);
bswap_flt64 (&hdr.bias);
}
/* Copy basic info and verify correctness. */
- ext->case_size = hdr.case_size;
- if (hdr.case_size <= 0 || ext->case_size > (INT_MAX
- / (int) sizeof (union value) / 2))
+ r->value_cnt = hdr.case_size;
+ if (r->value_cnt <= 0
+ || r->value_cnt > (INT_MAX / (int) sizeof (union value) / 2))
lose ((ME, _("%s: Number of elements per case (%d) is not between 1 "
"and %d."),
- handle_get_filename (h), hdr.case_size,
+ handle_get_filename (r->fh), r->value_cnt,
INT_MAX / sizeof (union value) / 2));
- ext->compressed = hdr.compressed;
+ r->compressed = hdr.compress;
- ext->weight_index = hdr.weight_index - 1;
- if (hdr.weight_index < 0 || hdr.weight_index > hdr.case_size)
+ r->weight_idx = hdr.weight_idx - 1;
+ if (hdr.weight_idx < 0 || hdr.weight_idx > r->value_cnt)
lose ((ME, _("%s: Index of weighting variable (%d) is not between 0 "
"and number of elements per case (%d)."),
- handle_get_filename (h), hdr.weight_index, ext->case_size));
+ handle_get_filename (r->fh), hdr.weight_idx, r->value_cnt));
- ext->ncases = hdr.ncases;
- if (ext->ncases < -1 || ext->ncases > INT_MAX / 2)
- lose ((ME, _("%s: Number of cases in file (%ld) is not between -1 and "
- "%d."), handle_get_filename (h), (long) ext->ncases, INT_MAX / 2));
+ r->case_cnt = hdr.case_cnt;
+ if (r->case_cnt < -1 || r->case_cnt > INT_MAX / 2)
+ lose ((ME,
+ _("%s: Number of cases in file (%ld) is not between -1 and %d."),
+ handle_get_filename (r->fh), (long) r->case_cnt, INT_MAX / 2));
- ext->bias = hdr.bias;
- if (ext->bias != 100.0)
+ r->bias = hdr.bias;
+ if (r->bias != 100.0)
corrupt_msg (MW, _("%s: Compression bias (%g) is not the usual "
"value of 100."),
- handle_get_filename (h), ext->bias);
+ handle_get_filename (r->fh), r->bias);
/* Make a file label only on the condition that the given label is
not all spaces or nulls. */
}
}
- if (inf)
+ if (info)
{
char *cp;
- memcpy (inf->creation_date, hdr.creation_date, 9);
- inf->creation_date[9] = 0;
+ memcpy (info->creation_date, hdr.creation_date, 9);
+ info->creation_date[9] = 0;
- memcpy (inf->creation_time, hdr.creation_time, 8);
- inf->creation_time[8] = 0;
+ memcpy (info->creation_time, hdr.creation_time, 8);
+ info->creation_time[8] = 0;
#ifdef WORDS_BIGENDIAN
- inf->bigendian = !ext->reverse_endian;
+ info->big_endian = !r->reverse_endian;
#else
- inf->bigendian = ext->reverse_endian;
+ info->big_endian = r->reverse_endian;
#endif
- inf->compressed = hdr.compressed;
+ info->compressed = hdr.compress;
- inf->ncases = hdr.ncases;
+ info->case_cnt = hdr.case_cnt;
for (cp = &prod_name[skip_amt]; cp < &prod_name[60]; cp++)
if (isgraph ((unsigned char) *cp))
break;
- strcpy (inf->product, cp);
+ strcpy (info->product, cp);
}
return 1;
-lossage:
+error:
return 0;
}
/* Reads most of the dictionary from file H; also fills in the
- associated VAR_BY_INDEX array. The get.* elements in the
- created dictionary are set to appropriate values to allow the
- file to be read. */
+ associated VAR_BY_IDX array. */
static int
-read_variables (struct file_handle *h, struct variable ***var_by_index)
+read_variables (struct sfm_reader *r,
+ struct dictionary *dict, struct variable ***var_by_idx)
{
int i;
- struct sfm_fhuser_ext *ext = h->ext; /* File extension record. */
- struct dictionary *dict = ext->dict; /* Dictionary being constructed. */
struct sysfile_variable sv; /* Disk buffer. */
int long_string_count = 0; /* # of long string continuation
records still expected. */
int next_value = 0; /* Index to next `value' structure. */
+ size_t var_cap = 0;
/* Allocate variables. */
- *var_by_index = xmalloc (sizeof **var_by_index * ext->case_size);
+ *var_by_idx = xmalloc (sizeof **var_by_idx * r->value_cnt);
/* Read in the entry for each variable and use the info to
initialize the dictionary. */
- for (i = 0; i < ext->case_size; i++)
+ for (i = 0; i < r->value_cnt; i++)
{
struct variable *vv;
char name[9];
+ int nv;
int j;
- assertive_bufread (h, &sv, sizeof sv, 0);
+ assertive_buf_read (r, &sv, sizeof sv, 0);
- if (ext->reverse_endian)
+ if (r->reverse_endian)
{
bswap_int32 (&sv.rec_type);
bswap_int32 (&sv.type);
if (sv.rec_type != 2)
lose ((ME, _("%s: position %d: Bad record type (%d); "
"the expected value was 2."),
- handle_get_filename (h), i, sv.rec_type));
+ handle_get_filename (r->fh), i, sv.rec_type));
/* If there was a long string previously, make sure that the
continuations are present; otherwise make sure there aren't
if (sv.type != -1)
lose ((ME, _("%s: position %d: String variable does not have "
"proper number of continuation records."),
- handle_get_filename (h), i));
+ handle_get_filename (r->fh), i));
- (*var_by_index)[i] = NULL;
+ (*var_by_idx)[i] = NULL;
long_string_count--;
continue;
}
else if (sv.type == -1)
lose ((ME, _("%s: position %d: Superfluous long string continuation "
"record."),
- handle_get_filename (h), i));
+ handle_get_filename (r->fh), i));
/* Check fields for validity. */
if (sv.type < 0 || sv.type > 255)
lose ((ME, _("%s: position %d: Bad variable type code %d."),
- handle_get_filename (h), i, sv.type));
+ handle_get_filename (r->fh), i, sv.type));
if (sv.has_var_label != 0 && sv.has_var_label != 1)
lose ((ME, _("%s: position %d: Variable label indicator field is not "
- "0 or 1."), handle_get_filename (h), i));
+ "0 or 1."), handle_get_filename (r->fh), i));
if (sv.n_missing_values < -3 || sv.n_missing_values > 3
|| sv.n_missing_values == -1)
lose ((ME, _("%s: position %d: Missing value indicator field is not "
- "-3, -2, 0, 1, 2, or 3."), handle_get_filename (h), i));
+ "-3, -2, 0, 1, 2, or 3."), handle_get_filename (r->fh), i));
/* Copy first character of variable name. */
if (!isalpha ((unsigned char) sv.name[0])
&& sv.name[0] != '@' && sv.name[0] != '#')
lose ((ME, _("%s: position %d: Variable name begins with invalid "
"character."),
- handle_get_filename (h), i));
+ handle_get_filename (r->fh), i));
if (islower ((unsigned char) sv.name[0]))
msg (MW, _("%s: position %d: Variable name begins with lowercase letter "
"%c."),
- handle_get_filename (h), i, sv.name[0]);
+ handle_get_filename (r->fh), i, sv.name[0]);
if (sv.name[0] == '#')
msg (MW, _("%s: position %d: Variable name begins with octothorpe "
"(`#'). Scratch variables should not appear in system "
"files."),
- handle_get_filename (h), i);
+ handle_get_filename (r->fh), i);
name[0] = toupper ((unsigned char) (sv.name[0]));
/* Copy remaining characters of variable name. */
{
msg (MW, _("%s: position %d: Variable name character %d is "
"lowercase letter %c."),
- handle_get_filename (h), i, j + 1, sv.name[j]);
+ handle_get_filename (r->fh), i, j + 1, sv.name[j]);
name[j] = toupper ((unsigned char) (c));
}
else if (isalnum (c) || c == '.' || c == '@'
else
lose ((ME, _("%s: position %d: character `\\%03o' (%c) is not valid in a "
"variable name."),
- handle_get_filename (h), i, c, c));
+ handle_get_filename (r->fh), i, c, c));
}
name[j] = 0;
/* Create variable. */
- vv = (*var_by_index)[i] = dict_create_var (dict, name, sv.type);
+ vv = (*var_by_idx)[i] = dict_create_var (dict, name, sv.type);
if (vv == NULL)
lose ((ME, _("%s: Duplicate variable name `%s' within system file."),
- handle_get_filename (h), name));
+ handle_get_filename (r->fh), name));
/* Case reading data. */
- vv->get.fv = next_value;
- if (sv.type == 0)
- vv->get.nv = 1;
- else
- vv->get.nv = DIV_RND_UP (sv.type, sizeof (flt64));
- long_string_count = vv->get.nv - 1;
- next_value += vv->get.nv;
+ nv = sv.type == 0 ? 1 : DIV_RND_UP (sv.type, sizeof (flt64));
+ long_string_count = nv - 1;
+ next_value += nv;
/* Get variable label, if any. */
if (sv.has_var_label == 1)
int32 len;
/* Read length of label. */
- assertive_bufread (h, &len, sizeof len, 0);
- if (ext->reverse_endian)
+ assertive_buf_read (r, &len, sizeof len, 0);
+ if (r->reverse_endian)
bswap_int32 (&len);
/* Check len. */
if (len < 0 || len > 255)
lose ((ME, _("%s: Variable %s indicates variable label of invalid "
"length %d."),
- handle_get_filename (h), vv->name, len));
+ handle_get_filename (r->fh), vv->name, len));
/* Read label into variable structure. */
- vv->label = bufread (h, NULL, ROUND_UP (len, sizeof (int32)), len + 1);
+ vv->label = buf_read (r, NULL, ROUND_UP (len, sizeof (int32)), len + 1);
if (vv->label == NULL)
- goto lossage;
+ goto error;
vv->label[len] = '\0';
}
if (vv->width > MAX_SHORT_STRING)
lose ((ME, _("%s: Long string variable %s may not have missing "
"values."),
- handle_get_filename (h), vv->name));
+ handle_get_filename (r->fh), vv->name));
- assertive_bufread (h, mv, sizeof *mv * abs (sv.n_missing_values), 0);
+ assertive_buf_read (r, mv, sizeof *mv * abs (sv.n_missing_values), 0);
- if (ext->reverse_endian && vv->type == NUMERIC)
+ if (r->reverse_endian && vv->type == NUMERIC)
for (j = 0; j < abs (sv.n_missing_values); j++)
bswap_flt64 (&mv[j]);
if (vv->type == ALPHA)
lose ((ME, _("%s: String variable %s may not have missing "
"values specified as a range."),
- handle_get_filename (h), vv->name));
+ handle_get_filename (r->fh), vv->name));
- if (mv[0] == ext->lowest)
+ if (mv[0] == r->lowest)
{
vv->miss_type = MISSING_LOW;
vv->missing[x++].f = mv[1];
}
- else if (mv[1] == ext->highest)
+ else if (mv[1] == r->highest)
{
vv->miss_type = MISSING_HIGH;
vv->missing[x++].f = mv[0];
else
vv->miss_type = MISSING_NONE;
- if (!parse_format_spec (h, sv.print, &vv->print, vv)
- || !parse_format_spec (h, sv.write, &vv->write, vv))
- goto lossage;
+ if (!parse_format_spec (r, sv.print, &vv->print, vv)
+ || !parse_format_spec (r, sv.write, &vv->write, vv))
+ goto error;
+
+ /* Add variable to list. */
+ if (var_cap >= r->var_cnt)
+ {
+ var_cap = 2 + r->var_cnt * 2;
+ r->vars = xrealloc (r->vars, var_cap * sizeof *r->vars);
+ }
+ r->vars[r->var_cnt].width = vv->width;
+ r->vars[r->var_cnt].fv = vv->fv;
+ r->var_cnt++;
}
/* Some consistency checks. */
if (long_string_count != 0)
lose ((ME, _("%s: Long string continuation records omitted at end of "
"dictionary."),
- handle_get_filename (h)));
- if (next_value != ext->case_size)
+ handle_get_filename (r->fh)));
+ if (next_value != r->value_cnt)
lose ((ME, _("%s: System file header indicates %d variable positions but "
"%d were read from file."),
- handle_get_filename (h), ext->case_size, next_value));
+ handle_get_filename (r->fh), r->value_cnt, next_value));
return 1;
-lossage:
- dict_destroy (dict);
- ext->dict = NULL;
-
+error:
return 0;
}
/* Translates the format spec from sysfile format to internal
format. */
static int
-parse_format_spec (struct file_handle *h, int32 s, struct fmt_spec *v, struct variable *vv)
+parse_format_spec (struct sfm_reader *r, int32 s, struct fmt_spec *v, struct variable *vv)
{
v->type = translate_fmt ((s >> 16) & 0xff);
if (v->type == -1)
lose ((ME, _("%s: Bad format specifier byte (%d)."),
- handle_get_filename (h), (s >> 16) & 0xff));
+ handle_get_filename (r->fh), (s >> 16) & 0xff));
v->w = (s >> 8) & 0xff;
v->d = s & 0xff;
if (v->type == -1)
lose ((ME, _("%s: Bad format specifier byte (%d)."),
- handle_get_filename (h), (s >> 16) & 0xff));
+ handle_get_filename (r->fh), (s >> 16) & 0xff));
if ((vv->type == ALPHA) ^ ((formats[v->type].cat & FCAT_STRING) != 0))
lose ((ME, _("%s: %s variable %s has %s format specifier %s."),
- handle_get_filename (h),
+ handle_get_filename (r->fh),
vv->type == ALPHA ? _("String") : _("Numeric"),
vv->name,
formats[v->type].cat & FCAT_STRING ? _("string") : _("numeric"),
formats[v->type].name));
return 1;
-lossage:
+error:
return 0;
}
/* Reads value labels from sysfile H and inserts them into the
associated dictionary. */
int
-read_value_labels (struct file_handle *h, struct variable **var_by_index)
+read_value_labels (struct sfm_reader *r,
+ struct dictionary *dict, struct variable **var_by_idx)
{
- struct sfm_fhuser_ext *ext = h->ext; /* File extension record. */
-
struct label
{
unsigned char raw_value[8]; /* Value as uninterpreted bytes. */
don't know yet whether it is of numeric or string type. */
/* Read number of labels. */
- assertive_bufread (h, &n_labels, sizeof n_labels, 0);
- if (ext->reverse_endian)
+ assertive_buf_read (r, &n_labels, sizeof n_labels, 0);
+ if (r->reverse_endian)
bswap_int32 (&n_labels);
/* Allocate memory. */
size_t padded_len;
/* Read value. */
- assertive_bufread (h, label->raw_value, sizeof label->raw_value, 0);
+ assertive_buf_read (r, label->raw_value, sizeof label->raw_value, 0);
/* Read label length. */
- assertive_bufread (h, &label_len, sizeof label_len, 0);
+ assertive_buf_read (r, &label_len, sizeof label_len, 0);
padded_len = ROUND_UP (label_len + 1, sizeof (flt64));
/* Read label, padding. */
label->label = xmalloc (padded_len + 1);
- assertive_bufread (h, label->label, padded_len - 1, 0);
+ assertive_buf_read (r, label->label, padded_len - 1, 0);
label->label[label_len] = 0;
}
{
int32 rec_type;
- assertive_bufread (h, &rec_type, sizeof rec_type, 0);
- if (ext->reverse_endian)
+ assertive_buf_read (r, &rec_type, sizeof rec_type, 0);
+ if (r->reverse_endian)
bswap_int32 (&rec_type);
if (rec_type != 4)
lose ((ME, _("%s: Variable index record (type 4) does not immediately "
"follow value label record (type 3) as it should."),
- handle_get_filename (h)));
+ handle_get_filename (r->fh)));
}
/* Read number of variables associated with value label from type 4
record. */
- assertive_bufread (h, &n_vars, sizeof n_vars, 0);
- if (ext->reverse_endian)
+ assertive_buf_read (r, &n_vars, sizeof n_vars, 0);
+ if (r->reverse_endian)
bswap_int32 (&n_vars);
- if (n_vars < 1 || n_vars > dict_get_var_cnt (ext->dict))
+ if (n_vars < 1 || n_vars > dict_get_var_cnt (dict))
lose ((ME, _("%s: Number of variables associated with a value label (%d) "
"is not between 1 and the number of variables (%d)."),
- handle_get_filename (h), n_vars, dict_get_var_cnt (ext->dict)));
+ handle_get_filename (r->fh), n_vars, dict_get_var_cnt (dict)));
/* Read the list of variables. */
var = xmalloc (n_vars * sizeof *var);
for (i = 0; i < n_vars; i++)
{
- int32 var_index;
+ int32 var_idx;
struct variable *v;
/* Read variable index, check range. */
- assertive_bufread (h, &var_index, sizeof var_index, 0);
- if (ext->reverse_endian)
- bswap_int32 (&var_index);
- if (var_index < 1 || var_index > ext->case_size)
+ assertive_buf_read (r, &var_idx, sizeof var_idx, 0);
+ if (r->reverse_endian)
+ bswap_int32 (&var_idx);
+ if (var_idx < 1 || var_idx > r->value_cnt)
lose ((ME, _("%s: Variable index associated with value label (%d) is "
"not between 1 and the number of values (%d)."),
- handle_get_filename (h), var_index, ext->case_size));
+ handle_get_filename (r->fh), var_idx, r->value_cnt));
/* Make sure it's a real variable. */
- v = var_by_index[var_index - 1];
+ v = var_by_idx[var_idx - 1];
if (v == NULL)
lose ((ME, _("%s: Variable index associated with value label (%d) "
"refers to a continuation of a string variable, not to "
"an actual variable."),
- handle_get_filename (h), var_index));
+ handle_get_filename (r->fh), var_idx));
if (v->type == ALPHA && v->width > MAX_SHORT_STRING)
lose ((ME, _("%s: Value labels are not allowed on long string "
"variables (%s)."),
- handle_get_filename (h), v->name));
+ handle_get_filename (r->fh), v->name));
/* Add it to the list of variables. */
var[i] = v;
lose ((ME, _("%s: Variables associated with value label are not all of "
"identical type. Variable %s has %s type, but variable "
"%s has %s type."),
- handle_get_filename (h),
+ handle_get_filename (r->fh),
var[0]->name, var[0]->type == ALPHA ? _("string") : _("numeric"),
var[i]->name, var[i]->type == ALPHA ? _("string") : _("numeric")));
flt64 f;
assert (sizeof f == sizeof label->raw_value);
memcpy (&f, label->raw_value, sizeof f);
- if (ext->reverse_endian)
+ if (r->reverse_endian)
bswap_flt64 (&f);
label->value.f = f;
}
if (var[0]->type == NUMERIC)
msg (MW, _("%s: File contains duplicate label for value %g for "
"variable %s."),
- handle_get_filename (h), label->value.f, v->name);
+ handle_get_filename (r->fh), label->value.f, v->name);
else
msg (MW, _("%s: File contains duplicate label for value `%.*s' "
"for variable %s."),
- handle_get_filename (h), v->width, label->value.s, v->name);
+ handle_get_filename (r->fh), v->width, label->value.s, v->name);
}
}
free (var);
return 1;
-lossage:
+error:
if (labels)
{
for (i = 0; i < n_labels; i++)
return 0;
}
-/* Reads NBYTES bytes from the file represented by H. If BUF is
+/* Reads BYTE_CNT bytes from the file represented by H. If BUF is
non-NULL, uses that as the buffer; otherwise allocates at least
- MINALLOC bytes. Returns a pointer to the buffer on success, NULL
+ MIN_ALLOC bytes. Returns a pointer to the buffer on success, NULL
on failure. */
static void *
-bufread (struct file_handle *h, void *buf, size_t nbytes, size_t minalloc)
+buf_read (struct sfm_reader *r, void *buf, size_t byte_cnt, size_t min_alloc)
{
- struct sfm_fhuser_ext *ext = h->ext;
-
if (buf == NULL)
- buf = xmalloc (max (nbytes, minalloc));
- if (1 != fread (buf, nbytes, 1, ext->file))
+ buf = xmalloc (max (byte_cnt, min_alloc));
+ if (1 != fread (buf, byte_cnt, 1, r->file))
{
- if (ferror (ext->file))
+ if (ferror (r->file))
msg (ME, _("%s: Reading system file: %s."),
- handle_get_filename (h), strerror (errno));
+ handle_get_filename (r->fh), strerror (errno));
else
corrupt_msg (ME, _("%s: Unexpected end of file."),
- handle_get_filename (h));
+ handle_get_filename (r->fh));
return NULL;
}
return buf;
}
-/* Reads a document record, type 6, from system file H, and sets up
+/* Reads a document record, type 6, from system file R, and sets up
the documents and n_documents fields in the associated
dictionary. */
static int
-read_documents (struct file_handle *h)
+read_documents (struct sfm_reader *r, struct dictionary *dict)
{
- struct sfm_fhuser_ext *ext = h->ext;
- struct dictionary *dict = ext->dict;
- int32 n_lines;
+ int32 line_cnt;
char *documents;
if (dict_get_documents (dict) != NULL)
lose ((ME, _("%s: System file contains multiple "
"type 6 (document) records."),
- handle_get_filename (h)));
+ handle_get_filename (r->fh)));
- assertive_bufread (h, &n_lines, sizeof n_lines, 0);
- if (n_lines <= 0)
+ assertive_buf_read (r, &line_cnt, sizeof line_cnt, 0);
+ if (line_cnt <= 0)
lose ((ME, _("%s: Number of document lines (%ld) "
"must be greater than 0."),
- handle_get_filename (h), (long) n_lines));
+ handle_get_filename (r->fh), (long) line_cnt));
- documents = bufread (h, NULL, 80 * n_lines, n_lines * 80 + 1);
+ documents = buf_read (r, NULL, 80 * line_cnt, line_cnt * 80 + 1);
/* FIXME? Run through asciify. */
if (documents == NULL)
return 0;
- documents[80 * n_lines] = '\0';
+ documents[80 * line_cnt] = '\0';
dict_set_documents (dict, documents);
free (documents);
return 1;
-lossage:
+error:
return 0;
}
\f
appropriately. Returns nonzero only if both no errors occur and
data was read. */
static int
-buffer_input (struct file_handle *h)
+buffer_input (struct sfm_reader *r)
{
- struct sfm_fhuser_ext *ext = h->ext;
size_t amt;
- if (ext->buf == NULL)
- ext->buf = xmalloc (sizeof *ext->buf * 128);
- amt = fread (ext->buf, sizeof *ext->buf, 128, ext->file);
- if (ferror (ext->file))
+ if (r->buf == NULL)
+ r->buf = xmalloc (sizeof *r->buf * 128);
+ amt = fread (r->buf, sizeof *r->buf, 128, r->file);
+ if (ferror (r->file))
{
msg (ME, _("%s: Error reading file: %s."),
- handle_get_filename (h), strerror (errno));
+ handle_get_filename (r->fh), strerror (errno));
return 0;
}
- ext->ptr = ext->buf;
- ext->end = &ext->buf[amt];
+ r->ptr = r->buf;
+ r->end = &r->buf[amt];
return amt;
}
-/* Reads a single case consisting of compressed data from system file
- H into the array TEMP[] according to dictionary DICT, and returns
- nonzero only if successful. */
-/* Data in system files is compressed in the following manner:
- data values are grouped into sets of eight; each of the eight has
- one instruction byte, which are output together in an octet; each
- byte gives a value for that byte or indicates that the value can be
- found following the instructions. */
+/* Reads a single case consisting of compressed data from system
+ file H into the array BUF[] according to reader R, and
+ returns nonzero only if successful. */
+/* Data in system files is compressed in this manner. Data
+ values are grouped into sets of eight ("octets"). Each value
+ in an octet has one instruction byte that are output together.
+ Each instruction byte gives a value for that byte or indicates
+ that the value can be found following the instructions. */
static int
-read_compressed_data (struct file_handle *h, flt64 *temp)
+read_compressed_data (struct sfm_reader *r, flt64 *buf)
{
- struct sfm_fhuser_ext *ext = h->ext;
-
- const unsigned char *p_end = ext->x + sizeof (flt64);
- unsigned char *p = ext->y;
+ const unsigned char *p_end = r->x + sizeof (flt64);
+ unsigned char *p = r->y;
- const flt64 *temp_beg = temp;
- const flt64 *temp_end = &temp[ext->case_size];
+ const flt64 *buf_beg = buf;
+ const flt64 *buf_end = &buf[r->value_cnt];
for (;;)
{
continue;
case 252:
/* Code 252 is end of file. */
- if (temp_beg != temp)
+ if (buf_beg != buf)
lose ((ME, _("%s: Compressed data is corrupted. Data ends "
"in partial case."),
- handle_get_filename (h)));
- goto lossage;
+ handle_get_filename (r->fh)));
+ goto error;
case 253:
/* Code 253 indicates that the value is stored explicitly
following the instruction bytes. */
- if (ext->ptr == NULL || ext->ptr >= ext->end)
- if (!buffer_input (h))
+ if (r->ptr == NULL || r->ptr >= r->end)
+ if (!buffer_input (r))
{
lose ((ME, _("%s: Unexpected end of file."),
- handle_get_filename (h)));
- goto lossage;
+ handle_get_filename (r->fh)));
+ goto error;
}
- memcpy (temp++, ext->ptr++, sizeof *temp);
- if (temp >= temp_end)
- goto winnage;
+ memcpy (buf++, r->ptr++, sizeof *buf);
+ if (buf >= buf_end)
+ goto success;
break;
case 254:
/* Code 254 indicates a string that is all blanks. */
- memset (temp++, ' ', sizeof *temp);
- if (temp >= temp_end)
- goto winnage;
+ memset (buf++, ' ', sizeof *buf);
+ if (buf >= buf_end)
+ goto success;
break;
case 255:
/* Code 255 indicates the system-missing value. */
- *temp = ext->sysmis;
- if (ext->reverse_endian)
- bswap_flt64 (temp);
- temp++;
- if (temp >= temp_end)
- goto winnage;
+ *buf = r->sysmis;
+ if (r->reverse_endian)
+ bswap_flt64 (buf);
+ buf++;
+ if (buf >= buf_end)
+ goto success;
break;
default:
/* Codes 1 through 251 inclusive are taken to indicate a
value of (BYTE - BIAS), where BYTE is the byte's value
and BIAS is the compression bias (generally 100.0). */
- *temp = *p - ext->bias;
- if (ext->reverse_endian)
- bswap_flt64 (temp);
- temp++;
- if (temp >= temp_end)
- goto winnage;
+ *buf = *p - r->bias;
+ if (r->reverse_endian)
+ bswap_flt64 (buf);
+ buf++;
+ if (buf >= buf_end)
+ goto success;
break;
}
/* We have reached the end of this instruction octet. Read
another. */
- if (ext->ptr == NULL || ext->ptr >= ext->end)
- if (!buffer_input (h))
+ if (r->ptr == NULL || r->ptr >= r->end)
+ if (!buffer_input (r))
{
- if (temp_beg != temp)
+ if (buf_beg != buf)
lose ((ME, _("%s: Unexpected end of file."),
- handle_get_filename (h)));
- goto lossage;
+ handle_get_filename (r->fh)));
+ goto error;
}
- memcpy (ext->x, ext->ptr++, sizeof *temp);
- p = ext->x;
+ memcpy (r->x, r->ptr++, sizeof *buf);
+ p = r->x;
}
/* Not reached. */
assert (0);
-winnage:
+success:
/* We have filled up an entire record. Update state and return
successfully. */
- ext->y = ++p;
+ r->y = ++p;
return 1;
-lossage:
+error:
/* We have been unsuccessful at filling a record, either through i/o
error or through an end-of-file indication. Update state and
return unsuccessfully. */
return 0;
}
-/* Reads one case from system file H into PERM
- according to the instructions given in associated dictionary DICT,
- which must have the get.* elements appropriately set. Returns
- nonzero only if successful. */
+/* Reads one case from READER's file into C. Returns nonzero
+ only if successful. */
int
-sfm_read_case (struct file_handle *h, struct ccase *perm, struct dictionary *dict)
+sfm_read_case (struct sfm_reader *r, struct ccase *c)
{
- struct sfm_fhuser_ext *ext = h->ext;
-
- size_t nbytes;
- flt64 *temp;
-
- int i;
-
- /* The first concern is to obtain a full case relative to the data
- file. (Cases in the data file have no particular relationship to
- cases in the active file.) */
- nbytes = sizeof *temp * ext->case_size;
- temp = local_alloc (nbytes);
-
- if (ext->compressed == 0)
+ if (!r->compressed && sizeof (flt64) == sizeof (double))
{
- size_t amt = fread (temp, 1, nbytes, ext->file);
+ /* Fast path: external and internal representations are the
+ same, except possibly for endianness or SYSMIS. Read
+ directly into the case's buffer, then fix up any minor
+ details as needed. */
+ if (!fread_ok (r, case_data_all_rw (c),
+ sizeof (union value) * r->value_cnt))
+ return 0;
+
+ /* Fix up endianness if needed. */
+ if (r->reverse_endian)
+ {
+ int i;
+
+ for (i = 0; i < r->var_cnt; i++)
+ if (r->vars[i].width == 0)
+ bswap_flt64 (&case_data_rw (c, r->vars[i].fv)->f);
+ }
- if (amt != nbytes)
- {
- if (ferror (ext->file))
- msg (ME, _("%s: Reading system file: %s."),
- handle_get_filename (h), strerror (errno));
- else if (amt != 0)
- msg (ME, _("%s: Partial record at end of system file."),
- handle_get_filename (h));
- goto lossage;
- }
+ /* Fix up SYSMIS values if needed.
+ I don't think this will ever actually kick in, but it
+ can't hurt. */
+ if (r->sysmis != SYSMIS)
+ {
+ int i;
+
+ for (i = 0; i < r->var_cnt; i++)
+ if (r->vars[i].width == 0 && case_num (c, i) == r->sysmis)
+ case_data_rw (c, r->vars[i].fv)->f = SYSMIS;
+ }
}
- else if (!read_compressed_data (h, temp))
- goto lossage;
-
- /* Translate a case in data file format to a case in active file
- format. */
- for (i = 0; i < dict_get_var_cnt (dict); i++)
+ else
{
- struct variable *v = dict_get_var (dict, i);
-
- if (v->get.fv == -1)
- continue;
-
- if (v->type == NUMERIC)
- {
- flt64 src = temp[v->get.fv];
- if (ext->reverse_endian)
- bswap_flt64 (&src);
- case_data_rw (perm, v->fv)->f = src == ext->sysmis ? SYSMIS : src;
- }
+ /* Slow path: internal and external representations differ.
+ Read into a bounce buffer, then copy to C. */
+ flt64 *bounce;
+ flt64 *bounce_cur;
+ size_t bounce_size;
+ int read_ok;
+ int i;
+
+ bounce_size = sizeof *bounce * r->value_cnt;
+ bounce = bounce_cur = local_alloc (bounce_size);
+
+ if (!r->compressed)
+ read_ok = fread_ok (r, bounce, bounce_size);
else
- memcpy (case_data_rw (perm, v->fv)->s, &temp[v->get.fv], v->width);
- }
+ read_ok = read_compressed_data (r, bounce);
+ if (!read_ok)
+ {
+ local_free (bounce);
+ return 0;
+ }
- local_free (temp);
- return 1;
+ for (i = 0; i < r->var_cnt; i++)
+ {
+ struct sfm_var *v = &r->vars[i];
+
+ if (v->width == 0)
+ {
+ flt64 f = *bounce_cur++;
+ if (r->reverse_endian)
+ bswap_flt64 (&f);
+ case_data_rw (c, i)->f = f == r->sysmis ? SYSMIS : f;
+ }
+ else
+ {
+ memcpy (case_data_rw (c, v->fv)->s, bounce_cur, v->width);
+ bounce_cur += DIV_RND_UP (v->width, sizeof (flt64));
+ }
+ }
-lossage:
- local_free (temp);
- return 0;
+ local_free (bounce);
+ }
+ return 1;
}
-static struct fh_ext_class sfm_r_class =
+static int
+fread_ok (struct sfm_reader *r, void *buffer, size_t byte_cnt)
{
- 3,
- N_("reading as a system file"),
- sfm_close,
-};
+ size_t read_bytes = fread (buffer, 1, byte_cnt, r->file);
+
+ if (read_bytes == byte_cnt)
+ return 1;
+ else
+ {
+ if (ferror (r->file))
+ msg (ME, _("%s: Reading system file: %s."),
+ handle_get_filename (r->fh), strerror (errno));
+ else if (read_bytes != 0)
+ msg (ME, _("%s: Partial record at end of system file."),
+ handle_get_filename (r->fh));
+ return 0;
+ }
+}
--- /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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef SFM_READ_H
+#define SFM_READ_H 1
+
+/* Reading system files. */
+
+/* System file info that doesn't fit in struct dictionary. */
+struct sfm_read_info
+ {
+ char creation_date[10]; /* `dd mmm yy' plus a null. */
+ char creation_time[9]; /* `hh:mm:ss' plus a null. */
+ int big_endian; /* 1=big-endian, 0=little-endian. */
+ int compressed; /* 0=no, 1=yes. */
+ int case_cnt; /* -1 if unknown. */
+ char product[61]; /* Product name plus a null. */
+ };
+
+struct dictionary;
+struct file_handle;
+struct ccase;
+struct sfm_reader *sfm_open_reader (struct file_handle *,
+ struct dictionary **,
+ struct sfm_read_info *);
+int sfm_read_case (struct sfm_reader *, struct ccase *);
+void sfm_close_reader (struct sfm_reader *);
+
+#endif /* sfm-read.h */
02111-1307, USA. */
#include <config.h>
-#include "sfm.h"
+#include "sfm-write.h"
#include "sfmP.h"
#include "error.h"
#include <stdlib.h>
#include <unistd.h> /* Required by SunOS4. */
#endif
#include "alloc.h"
+#include "case.h"
+#include "dictionary.h"
#include "error.h"
#include "file-handle.h"
#include "getline.h"
#include "debug-print.h"
-/* PORTME: This file may require substantial revision for those
- systems that don't meet the typical 32-bit integer/64-bit double
- model. It's kinda hard to tell without having one of them on my
- desk. */
-
/* Compression bias used by PSPP. Values between (1 -
COMPRESSION_BIAS) and (251 - COMPRESSION_BIAS) inclusive can be
compressed. */
#define COMPRESSION_BIAS 100
-/* sfm writer file_handle extension. */
-struct sfm_fhuser_ext
+/* System file writer. */
+struct sfm_writer
{
- FILE *file; /* Actual file. */
+ struct file_handle *fh; /* File handle. */
+ FILE *file; /* File stream. */
+
+ int needs_translation; /* 0=use fast path, 1=translation needed. */
+ int compress; /* 1=compressed, 0=not compressed. */
+ int case_cnt; /* Number of cases written so far. */
+ size_t flt64_cnt; /* Number of flt64 elements in case. */
- int compressed; /* 1=compressed, 0=not compressed. */
+ /* Compression buffering. */
flt64 *buf; /* Buffered data. */
flt64 *end; /* Buffer end. */
flt64 *ptr; /* Current location in buffer. */
unsigned char *x; /* Location in current instruction octet. */
unsigned char *y; /* End of instruction octet. */
- int n_cases; /* Number of cases written so far. */
- char *elem_type; /* ALPHA or NUMERIC for each flt64 element. */
+ /* Variables. */
+ struct sfm_var *vars; /* Variables. */
+ size_t var_cnt; /* Number of variables. */
};
-static struct fh_ext_class sfm_w_class;
+/* A variable in a system file. */
+struct sfm_var
+ {
+ int width; /* 0=numeric, otherwise string width. */
+ int fv; /* Index into case. */
+ size_t flt64_cnt; /* Number of flt64 elements. */
+ };
static char *append_string_max (char *, const char *, const char *);
-static int write_header (struct sfm_write_info *inf);
-static int bufwrite (struct file_handle *h, const void *buf, size_t nbytes);
-static int write_variable (struct sfm_write_info *inf, struct variable *v);
-static int write_value_labels (struct sfm_write_info *inf, struct variable * s, int index);
-static int write_rec_7_34 (struct sfm_write_info *inf);
-static int write_documents (struct sfm_write_info *inf);
-
-/* Writes the dictionary INF->dict to system file INF->h. The system
- file is compressed if INF->compress is nonzero. INF->case_size is
- set to the number of flt64 elements in a single case. Returns
- nonzero only if successful. */
-int
-sfm_write_dictionary (struct sfm_write_info *inf)
+static int write_header (struct sfm_writer *, const struct dictionary *);
+static int buf_write (struct sfm_writer *, const void *, size_t);
+static int write_variable (struct sfm_writer *, struct variable *);
+static int write_value_labels (struct sfm_writer *,
+ struct variable *, int idx);
+static int write_rec_7_34 (struct sfm_writer *);
+static int write_documents (struct sfm_writer *, const struct dictionary *);
+static int does_dict_need_translation (const struct dictionary *);
+
+static inline int
+var_flt64_cnt (const struct variable *v)
+{
+ return v->type == NUMERIC ? 1 : DIV_RND_UP (v->width, sizeof (flt64));
+}
+
+/* Opens the system file designated by file handle FH for writing
+ cases from dictionary D. If COMPRESS is nonzero, the
+ system file will be compressed.
+
+ No reference to D is retained, so it may be modified or
+ destroyed at will after this function returns. */
+struct sfm_writer *
+sfm_open_writer (struct file_handle *fh,
+ const struct dictionary *d, int compress)
{
- struct dictionary *d = inf->dict;
- struct sfm_fhuser_ext *ext;
+ struct sfm_writer *w = NULL;
+ int idx;
int i;
- int index;
- if (inf->h->class != NULL)
+ if (!fh_open (fh, "system file", "we"))
+ goto error;
+
+ /* Create and initialize writer. */
+ w = xmalloc (sizeof *w);
+ w->fh = fh;
+ w->file = fopen (handle_get_filename (fh), "wb");
+
+ w->needs_translation = does_dict_need_translation (d);
+ w->compress = compress;
+ w->case_cnt = 0;
+ w->flt64_cnt = 0;
+
+ w->buf = w->end = w->ptr = NULL;
+ w->x = w->y = NULL;
+
+ w->var_cnt = dict_get_var_cnt (d);
+ w->vars = xmalloc (sizeof *w->vars * w->var_cnt);
+ for (i = 0; i < w->var_cnt; i++)
{
- msg (ME, _("Cannot write file %s as system file: "
- "already opened for %s."),
- handle_get_name (inf->h), inf->h->class->name);
- return 0;
+ const struct variable *dv = dict_get_var (d, i);
+ struct sfm_var *sv = &w->vars[i];
+ sv->width = dv->width;
+ sv->fv = dv->fv;
+ sv->flt64_cnt = var_flt64_cnt (dv);
}
- msg (VM (1), _("%s: Opening system-file handle %s for writing."),
- handle_get_filename (inf->h), handle_get_name (inf->h));
-
- /* Open the physical disk file. */
- inf->h->class = &sfm_w_class;
- inf->h->ext = ext = xmalloc (sizeof (struct sfm_fhuser_ext));
- ext->file = fopen (handle_get_filename (inf->h), "wb");
- ext->elem_type = NULL;
- if (ext->file == NULL)
+ /* Check that file create succeeded. */
+ if (w->file == NULL)
{
- msg (ME, _("An error occurred while opening \"%s\" for writing "
+ msg (ME, _("Error opening \"%s\" for writing "
"as a system file: %s."),
- handle_get_filename (inf->h), strerror (errno));
+ handle_get_filename (w->fh), strerror (errno));
err_cond_fail ();
- free (ext);
- return 0;
+ goto error;
}
- /* Initialize the sfm_fhuser_ext structure. */
- ext->compressed = inf->compress;
- ext->buf = ext->ptr = NULL;
- ext->x = ext->y = NULL;
- ext->n_cases = 0;
-
/* Write the file header. */
- if (!write_header (inf))
- goto lossage;
+ if (!write_header (w, d))
+ goto error;
/* Write basic variable info. */
for (i = 0; i < dict_get_var_cnt (d); i++)
- write_variable (inf, dict_get_var (d, i));
+ write_variable (w, dict_get_var (d, i));
/* Write out value labels. */
- for (index = i = 0; i < dict_get_var_cnt (d); i++)
+ for (idx = i = 0; i < dict_get_var_cnt (d); i++)
{
struct variable *v = dict_get_var (d, i);
- if (!write_value_labels (inf, v, index))
- goto lossage;
- index += (v->type == NUMERIC ? 1
- : DIV_RND_UP (v->width, sizeof (flt64)));
+ if (!write_value_labels (w, v, idx))
+ goto error;
+ idx += var_flt64_cnt (v);
}
- if (dict_get_documents (d) != NULL && !write_documents (inf))
- goto lossage;
- if (!write_rec_7_34 (inf))
- goto lossage;
+ if (dict_get_documents (d) != NULL && !write_documents (w, d))
+ goto error;
+ if (!write_rec_7_34 (w))
+ goto error;
/* Write record 999. */
{
rec_999.rec_type = 999;
rec_999.filler = 0;
- if (!bufwrite (inf->h, &rec_999, sizeof rec_999))
- goto lossage;
+ if (!buf_write (w, &rec_999, sizeof rec_999))
+ goto error;
}
- msg (VM (2), _("Wrote system-file header successfully."));
+ if (w->compress)
+ {
+ w->buf = xmalloc (sizeof *w->buf * 128);
+ w->ptr = w->buf;
+ w->end = &w->buf[128];
+ w->x = (unsigned char *) w->ptr++;
+ w->y = (unsigned char *) w->ptr;
+ }
- return 1;
+ return w;
-lossage:
- msg (VM (1), _("Error writing system-file header."));
- fclose (ext->file);
- inf->h->class = NULL;
- inf->h->ext = NULL;
- free (ext->elem_type);
- ext->elem_type = NULL;
- return 0;
+ error:
+ sfm_close_writer (w);
+ return NULL;
+}
+
+static int
+does_dict_need_translation (const struct dictionary *d)
+{
+ size_t case_idx;
+ size_t i;
+
+ case_idx = 0;
+ for (i = 0; i < dict_get_var_cnt (d); i++)
+ {
+ struct variable *v = dict_get_var (d, i);
+ if (v->fv != case_idx)
+ return 0;
+ case_idx += v->nv;
+ }
+ return 1;
}
/* Returns value of X truncated to two least-significant digits. */
return x;
}
-/* Write the sysfile_header header to the system file represented by
- INF. */
+/* Write the sysfile_header header to system file W. */
static int
-write_header (struct sfm_write_info *inf)
+write_header (struct sfm_writer *w, const struct dictionary *d)
{
- struct dictionary *d = inf->dict;
- struct sfm_fhuser_ext *ext = inf->h->ext;
struct sysfile_header hdr;
char *p;
int i;
hdr.layout_code = 2;
- hdr.case_size = 0;
+ w->flt64_cnt = 0;
for (i = 0; i < dict_get_var_cnt (d); i++)
- {
- struct variable *v = dict_get_var (d, i);
- hdr.case_size += (v->type == NUMERIC ? 1
- : DIV_RND_UP (v->width, sizeof (flt64)));
- }
- inf->case_size = hdr.case_size;
+ w->flt64_cnt += var_flt64_cnt (dict_get_var (d, i));
+ hdr.case_size = w->flt64_cnt;
- p = ext->elem_type = xmalloc (inf->case_size);
- for (i = 0; i < dict_get_var_cnt (d); i++)
- {
- struct variable *v = dict_get_var (d, i);
- int count = (v->type == NUMERIC ? 1
- : DIV_RND_UP (v->width, sizeof (flt64)));
- while (count--)
- *p++ = v->type;
- }
-
- hdr.compressed = inf->compress;
+ hdr.compress = w->compress;
if (dict_get_weight (d) != NULL)
{
struct variable *weight_var;
- int recalc_weight_index = 1;
+ int recalc_weight_idx = 1;
int i;
weight_var = dict_get_weight (d);
struct variable *v = dict_get_var (d, i);
if (v == weight_var)
break;
- recalc_weight_index += (v->type == NUMERIC ? 1
- : DIV_RND_UP (v->width, sizeof (flt64)));
+ recalc_weight_idx += var_flt64_cnt (v);
}
- hdr.weight_index = recalc_weight_index;
+ hdr.weight_idx = recalc_weight_idx;
}
else
- hdr.weight_index = 0;
+ hdr.weight_idx = 0;
- hdr.ncases = -1;
+ hdr.case_cnt = -1;
hdr.bias = COMPRESSION_BIAS;
- if ((time_t) - 1 == time (&t))
+ if (time (&t) == (time_t) -1)
{
memcpy (hdr.creation_date, "01 Jan 70", 9);
memcpy (hdr.creation_time, "00:00:00", 8);
else
{
static const char *month_name[12] =
- {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
- };
+ {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
+ };
struct tm *tmp = localtime (&t);
int day = rerange (tmp->tm_mday);
int mon = rerange (tmp->tm_mon + 1);
memset (hdr.padding, 0, sizeof hdr.padding);
- if (!bufwrite (inf->h, &hdr, sizeof hdr))
+ if (!buf_write (w, &hdr, sizeof hdr))
return 0;
return 1;
}
}
/* Write the variable record(s) for primary variable P and secondary
- variable S to the system file represented by INF. */
+ variable S to system file W. */
static int
-write_variable (struct sfm_write_info *inf, struct variable *v)
+write_variable (struct sfm_writer *w, struct variable *v)
{
struct sysfile_variable sv;
/* Missing values. */
- flt64 m[3]; /* Missing value values. */
- int nm; /* Number of missing values, possibly negative. */
+ flt64 m[3]; /* Missing value values. */
+ int nm; /* Number of missing values, possibly negative. */
sv.rec_type = 2;
- sv.type = (v->type == NUMERIC ? 0 : v->width);
+ sv.type = v->width;
sv.has_var_label = (v->label != NULL);
switch (v->miss_type)
write_format_spec (&v->write, &sv.write);
memcpy (sv.name, v->name, strlen (v->name));
memset (&sv.name[strlen (v->name)], ' ', 8 - strlen (v->name));
- if (!bufwrite (inf->h, &sv, sizeof sv))
+ if (!buf_write (w, &sv, sizeof sv))
return 0;
if (v->label)
memcpy (l.label, v->label, l.label_len);
memset (&l.label[l.label_len], ' ', ext_len - l.label_len);
- if (!bufwrite (inf->h, &l, offsetof (struct label, label) + ext_len))
- return 0;
+ if (!buf_write (w, &l, offsetof (struct label, label) + ext_len))
+ return 0;
}
- if (nm && !bufwrite (inf->h, m, sizeof *m * nm))
+ if (nm && !buf_write (w, m, sizeof *m * nm))
return 0;
if (v->type == ALPHA && v->width > (int) sizeof (flt64))
pad_count = DIV_RND_UP (v->width, (int) sizeof (flt64)) - 1;
for (i = 0; i < pad_count; i++)
- if (!bufwrite (inf->h, &sv, sizeof sv))
+ if (!buf_write (w, &sv, sizeof sv))
return 0;
}
}
/* Writes the value labels for variable V having system file variable
- index INDEX to the system file associated with INF. Returns
+ index IDX to system file W. Returns
nonzero only if successful. */
static int
-write_value_labels (struct sfm_write_info * inf, struct variable *v, int index)
+write_value_labels (struct sfm_writer *w, struct variable *v, int idx)
{
struct value_label_rec
{
flt64 labels[1] P;
};
- struct variable_index_rec
+ struct var_idx_rec
{
int32 rec_type P;
int32 n_vars P;
struct val_labs_iterator *i;
struct value_label_rec *vlr;
- struct variable_index_rec vir;
+ struct var_idx_rec vir;
struct val_lab *vl;
size_t vlr_size;
flt64 *loc;
loc += DIV_RND_UP (len + 1, sizeof (flt64));
}
- if (!bufwrite (inf->h, vlr, vlr_size))
+ if (!buf_write (w, vlr, vlr_size))
{
free (vlr);
return 0;
vir.rec_type = 4;
vir.n_vars = 1;
- vir.vars[0] = index + 1;
- if (!bufwrite (inf->h, &vir, sizeof vir))
+ vir.vars[0] = idx + 1;
+ if (!buf_write (w, &vir, sizeof vir))
return 0;
return 1;
/* Writes record type 6, document record. */
static int
-write_documents (struct sfm_write_info * inf)
+write_documents (struct sfm_writer *w, const struct dictionary *d)
{
- struct dictionary *d = inf->dict;
struct
- {
- int32 rec_type P; /* Always 6. */
- int32 n_lines P; /* Number of lines of documents. */
- }
+ {
+ int32 rec_type P; /* Always 6. */
+ int32 n_lines P; /* Number of lines of documents. */
+ }
rec_6;
const char *documents;
rec_6.rec_type = 6;
rec_6.n_lines = n_lines;
- if (!bufwrite (inf->h, &rec_6, sizeof rec_6))
+ if (!buf_write (w, &rec_6, sizeof rec_6))
return 0;
- if (!bufwrite (inf->h, documents, 80 * n_lines))
+ if (!buf_write (w, documents, 80 * n_lines))
return 0;
return 1;
/* Writes record type 7, subtypes 3 and 4. */
static int
-write_rec_7_34 (struct sfm_write_info * inf)
+write_rec_7_34 (struct sfm_writer *w)
{
struct
{
rec_7.elem_4[1] = FLT64_MAX;
rec_7.elem_4[2] = second_lowest_flt64;
- if (!bufwrite (inf->h, &rec_7, sizeof rec_7))
+ if (!buf_write (w, &rec_7, sizeof rec_7))
return 0;
return 1;
}
/* Write NBYTES starting at BUF to the system file represented by
H. */
static int
-bufwrite (struct file_handle * h, const void *buf, size_t nbytes)
+buf_write (struct sfm_writer *w, const void *buf, size_t nbytes)
{
- struct sfm_fhuser_ext *ext = h->ext;
-
- assert (buf);
- if (1 != fwrite (buf, nbytes, 1, ext->file))
+ assert (buf != NULL);
+ if (fwrite (buf, nbytes, 1, w->file) != 1)
{
msg (ME, _("%s: Writing system file: %s."),
- handle_get_filename (h), strerror (errno));
+ handle_get_filename (w->fh), strerror (errno));
return 0;
}
return 1;
element. If there's not room, pads out the current instruction
octet with zero and dumps out the buffer. */
static inline int
-ensure_buf_space (struct file_handle *h)
+ensure_buf_space (struct sfm_writer *w)
{
- struct sfm_fhuser_ext *ext = h->ext;
-
- if (ext->ptr >= ext->end)
+ if (w->ptr >= w->end)
{
- memset (ext->x, 0, ext->y - ext->x);
- ext->x = ext->y;
- ext->ptr = ext->buf;
- if (!bufwrite (h, ext->buf, sizeof *ext->buf * 128))
+ memset (w->x, 0, w->y - w->x);
+ w->x = w->y;
+ w->ptr = w->buf;
+ if (!buf_write (w, w->buf, sizeof *w->buf * 128))
return 0;
}
return 1;
}
-/* Writes case ELEM consisting of N_ELEM flt64 elements to the system
- file represented by H. Return success. */
+static void write_compressed_data (struct sfm_writer *w, const flt64 *elem);
+
+/* Writes case C to system file W.
+ Returns nonzero if successful. */
int
-sfm_write_case (struct file_handle * h, const flt64 *elem, int n_elem)
+sfm_write_case (struct sfm_writer *w, struct ccase *c)
{
- struct sfm_fhuser_ext *ext = h->ext;
- const flt64 *end_elem = &elem[n_elem];
- char *elem_type = ext->elem_type;
+ w->case_cnt++;
- ext->n_cases++;
+ if (!w->needs_translation && !w->compress
+ && sizeof (flt64) == sizeof (union value))
+ {
+ /* Fast path: external and internal representations are the
+ same and the dictionary is properly ordered. Write
+ directly to file. */
+ buf_write (w, case_data_all (c), sizeof (union value) * w->flt64_cnt);
+ }
+ else
+ {
+ /* Slow path: internal and external representations differ.
+ Write into a bounce buffer, then write to W. */
+ flt64 *bounce;
+ flt64 *bounce_cur;
+ size_t bounce_size;
+ size_t i;
+
+ bounce_size = sizeof *bounce * w->flt64_cnt;
+ bounce = bounce_cur = local_alloc (bounce_size);
+
+ for (i = 0; i < w->var_cnt; i++)
+ {
+ struct sfm_var *v = &w->vars[i];
+
+ if (v->width == 0)
+ *bounce_cur = case_num (c, v->fv);
+ else
+ memcpy (bounce_cur, case_data (c, v->fv)->s, v->width);
+ bounce_cur += v->flt64_cnt;
+ }
- if (ext->compressed == 0)
- return bufwrite (h, elem, sizeof *elem * n_elem);
+ if (!w->compress)
+ buf_write (w, bounce, bounce_size);
+ else
+ write_compressed_data (w, bounce);
+
+ local_free (bounce);
+ }
+
+ return 1;
+}
- if (ext->buf == NULL)
+static void
+put_instruction (struct sfm_writer *w, unsigned char instruction)
+{
+ if (w->x >= w->y)
{
- ext->buf = xmalloc (sizeof *ext->buf * 128);
- ext->ptr = ext->buf;
- ext->end = &ext->buf[128];
- ext->x = (unsigned char *) (ext->ptr++);
- ext->y = (unsigned char *) (ext->ptr);
+ if (!ensure_buf_space (w))
+ return;
+ w->x = (unsigned char *) w->ptr++;
+ w->y = (unsigned char *) w->ptr;
}
- for (; elem < end_elem; elem++, elem_type++)
+ *w->x++ = instruction;
+}
+
+static void
+put_element (struct sfm_writer *w, const flt64 *elem)
+{
+ if (!ensure_buf_space (w))
+ return;
+ memcpy (w->ptr++, elem, sizeof *elem);
+}
+
+static void
+write_compressed_data (struct sfm_writer *w, const flt64 *elem)
+{
+ size_t i;
+
+ for (i = 0; i < w->var_cnt; i++)
{
- if (ext->x >= ext->y)
- {
- if (!ensure_buf_space (h))
- return 0;
- ext->x = (unsigned char *) (ext->ptr++);
- ext->y = (unsigned char *) (ext->ptr);
- }
+ struct sfm_var *v = &w->vars[i];
- if (*elem_type == NUMERIC)
+ if (v->width == 0)
{
- if (*elem == -FLT64_MAX)
+ if (*elem == -FLT64_MAX)
+ put_instruction (w, 255);
+ else if (*elem >= 1 - COMPRESSION_BIAS
+ && *elem <= 251 - COMPRESSION_BIAS
+ && *elem == (int) *elem)
+ put_instruction (w, (int) *elem + COMPRESSION_BIAS);
+ else
{
- *ext->x++ = 255;
- continue;
- }
- else if (*elem > INT_MIN && *elem < INT_MAX)
- {
- int value = *elem;
-
- if (value >= 1 - COMPRESSION_BIAS
- && value <= 251 - COMPRESSION_BIAS
- && value == *elem)
- {
- *ext->x++ = value + COMPRESSION_BIAS;
- continue;
- }
+ put_instruction (w, 253);
+ put_element (w, elem);
}
+ elem++;
}
- else
- {
- if (0 == memcmp ((char *) elem,
- " ",
- sizeof (flt64)))
+ else
+ {
+ size_t j;
+
+ for (j = 0; j < v->flt64_cnt; j++, elem++)
{
- *ext->x++ = 254;
- continue;
+ if (!memcmp (elem, " ", sizeof (flt64)))
+ put_instruction (w, 254);
+ else
+ {
+ put_instruction (w, 253);
+ put_element (w, elem);
+ }
}
}
-
- *ext->x++ = 253;
- if (!ensure_buf_space (h))
- return 0;
- *ext->ptr++ = *elem;
}
-
- return 1;
}
/* Closes a system file after we're done with it. */
-static void
-sfm_close (struct file_handle * h)
+void
+sfm_close_writer (struct sfm_writer *w)
{
- struct sfm_fhuser_ext *ext = h->ext;
+ if (w == NULL)
+ return;
- if (ext->buf != NULL && ext->ptr > ext->buf)
+ fh_close (w->fh, "system file", "we");
+
+ if (w->file != NULL)
{
- memset (ext->x, 0, ext->y - ext->x);
- bufwrite (h, ext->buf, (ext->ptr - ext->buf) * sizeof *ext->buf);
- }
+ /* Flush buffer. */
+ if (w->buf != NULL && w->ptr > w->buf)
+ {
+ memset (w->x, 0, w->y - w->x);
+ buf_write (w, w->buf, (w->ptr - w->buf) * sizeof *w->buf);
+ }
- /* Attempt to seek back to the beginning in order to write the
- number of cases. If that's not possible (i.e., we're writing to
- a tty or a pipe), then it's not a big deal because we wrote the
- code that indicates an unknown number of cases. */
- if (0 == fseek (ext->file, offsetof (struct sysfile_header, ncases),
- SEEK_SET))
- {
- int32 n_cases = ext->n_cases;
+ /* Seek back to the beginning and update the number of cases.
+ This is just a courtesy to later readers, so there's no need
+ to check return values or report errors. */
+ if (!fseek (w->file, offsetof (struct sysfile_header, case_cnt), SEEK_SET))
+ {
+ int32 case_cnt = w->case_cnt;
- /* I don't really care about the return value: it doesn't matter
- whether this data is written. This is the only situation in
- which you will see me fail to check a return value. */
- fwrite (&n_cases, sizeof n_cases, 1, ext->file);
- }
+ /* I don't really care about the return value: it doesn't
+ matter whether this data is written. */
+ fwrite (&case_cnt, sizeof case_cnt, 1, w->file);
+ }
- if (EOF == fclose (ext->file))
- msg (ME, _("%s: Closing system file: %s."),
- handle_get_filename (h), strerror (errno));
- free (ext->buf);
+ if (fclose (w->file) == EOF)
+ msg (ME, _("%s: Closing system file: %s."),
+ handle_get_filename (w->fh), strerror (errno));
+ }
- free (ext->elem_type);
- free (ext);
+ free (w->buf);
+ free (w->vars);
+ free (w);
}
-
-static struct fh_ext_class sfm_w_class =
-{
- 4,
- N_("writing as a system file"),
- sfm_close,
-};
--- /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., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef SFM_WRITE_H
+#define SFM_WRITE_H 1
+
+/* Writing system files. */
+
+struct file_handle;
+struct dictionary;
+struct ccase;
+struct sfm_writer *sfm_open_writer (struct file_handle *,
+ const struct dictionary *, int compress);
+int sfm_write_case (struct sfm_writer *, struct ccase *);
+void sfm_close_writer (struct sfm_writer *);
+
+#endif /* sfm-write.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., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
-
-#if !sfm_h
-#define sfm_h 1
-
-/* System file manager (sfm).
-
- This module is in charge of reading and writing system files. For
- now, only ordinary system files are supported; in the future, PC+
- compatible system files should be supported, too. sfm is an
- fhuser, so see file-handle.h for the fhuser interface. */
-
-/* Information produced by sfm_read_dictionary() that doesn't fit into
- a dictionary struct. */
-struct sfm_read_info
- {
- char creation_date[10]; /* `dd mmm yy' plus a null. */
- char creation_time[9]; /* `hh:mm:ss' plus a null. */
- int bigendian; /* 1=big-endian, 0=little-endian. */
- int compressed; /* 0=no, 1=yes. */
- int ncases; /* -1 if unknown. */
- char product[61]; /* Product name plus a null. */
- };
-
-struct dictionary;
-struct file_handle;
-struct ccase;
-
-struct dictionary *sfm_read_dictionary (struct file_handle *,
- struct sfm_read_info *);
-int sfm_read_case (struct file_handle *, struct ccase *, struct dictionary *);
-void sfm_maybe_close (struct file_handle *);
-
-/* Information needed by sfm_write_dictionary(). */
-struct sfm_write_info
- {
- /* Read by sfm_write_dictionary(). */
- struct file_handle *h; /* File handle. */
- struct dictionary *dict; /* Primary dictionary. */
- int compress; /* 1=compress, 0=do not compress. */
-
- /* Written by sfm_write_dictionary(). */
- int case_size; /* Number of flt64 elements per case. */
- };
-
-int sfm_write_dictionary (struct sfm_write_info *);
-int sfm_write_case (struct file_handle *, const flt64* elem, int n_elem);
-
-#endif /* !sfm_h */
/* Record Type 1: General Information. */
struct sysfile_header
{
- char rec_type[4] P; /* Record-type code, "$FL2". */
- char prod_name[60] P; /* Product identification. */
- int32 layout_code P; /* 2. */
- int32 case_size P; /* Number of `value's per case. */
- int32 compressed P; /* 1=compressed, 0=not compressed. */
- int32 weight_index P; /* 1-based index of weighting var, or zero. */
- int32 ncases P; /* Number of cases, -1 if unknown. */
- flt64 bias P; /* Compression bias (100.0). */
- char creation_date[9] P; /* `dd mmm yy' creation date of file. */
- char creation_time[8] P; /* `hh:mm:ss' 24-hour creation time. */
- char file_label[64] P; /* File label. */
- char padding[3] P; /* Ignored padding. */
+ char rec_type[4] P; /* 00: Record-type code, "$FL2". */
+ char prod_name[60] P; /* 04: Product identification. */
+ int32 layout_code P; /* 40: 2. */
+ int32 case_size P; /* 44: Number of `value's per case. */
+ int32 compress P; /* 48: 1=compressed, 0=not compressed. */
+ int32 weight_idx P; /* 4c: 1-based index of weighting var, or 0. */
+ int32 case_cnt P; /* 50: Number of cases, -1 if unknown. */
+ flt64 bias P; /* 54: Compression bias (100.0). */
+ char creation_date[9] P; /* 5c: `dd mmm yy' creation date of file. */
+ char creation_time[8] P; /* 65: `hh:mm:ss' 24-hour creation time. */
+ char file_label[64] P; /* 6d: File label. */
+ char padding[3] P; /* ad: Ignored padding. */
};
/* Record Type 2: Variable. */
#include <stdlib.h>
#include "alloc.h"
#include "command.h"
+#include "dictionary.h"
#include "error.h"
#include "lexer.h"
#include "str.h"
return st->string;
}
+/* Returns the string data inside ST. */
+char *
+ds_data (const struct string *st)
+{
+ return st->string;
+}
+
/* Returns a pointer to the null terminator ST.
This might not be an actual null character unless ds_c_str() has
been called since the last modification to ST. */
char *strtok_r (char *, const char *, char **);
#endif
-#if !HAVE_STPCPY && !__linux__
+#if !HAVE_STPCPY
char *stpcpy (char *dest, const char *src);
#endif
#include "algorithm.h"
#include "alloc.h"
#include "command.h"
+#include "dictionary.h"
#include "error.h"
#include "file-handle.h"
#include "hash.h"
#include "lexer.h"
#include "misc.h"
#include "output.h"
-#include "sfm.h"
+#include "sfm-read.h"
#include "som.h"
#include "tab.h"
#include "value-labels.h"
struct file_handle *h;
struct dictionary *d;
struct tab_table *t;
- struct sfm_read_info inf;
+ struct sfm_reader *reader;
+ struct sfm_read_info info;
int r, nr;
int i;
lex_match_id ("FILE");
lex_match ('=');
- h = fh_parse_file_handle ();
+ h = fh_parse ();
if (!h)
return CMD_FAILURE;
- d = sfm_read_dictionary (h, &inf);
- fh_close_handle (h);
- if (!d)
+ reader = sfm_open_reader (h, &d, &info);
+ if (!reader)
return CMD_FAILURE;
+ sfm_close_reader (reader);
t = tab_create (2, 9, 0);
tab_vline (t, TAL_1 | TAL_SPACING, 1, 0, 8);
}
tab_text (t, 0, 2, TAB_LEFT, _("Created:"));
tab_text (t, 1, 2, TAB_LEFT | TAT_PRINTF, "%s %s by %s",
- inf.creation_date, inf.creation_time, inf.product);
+ info.creation_date, info.creation_time, info.product);
tab_text (t, 0, 3, TAB_LEFT, _("Endian:"));
- tab_text (t, 1, 3, TAB_LEFT, inf.bigendian ? _("Big.") : _("Little."));
+ tab_text (t, 1, 3, TAB_LEFT, info.big_endian ? _("Big.") : _("Little."));
tab_text (t, 0, 4, TAB_LEFT, _("Variables:"));
tab_text (t, 1, 4, TAB_LEFT | TAT_PRINTF, "%d",
dict_get_var_cnt (d));
tab_text (t, 0, 5, TAB_LEFT, _("Cases:"));
tab_text (t, 1, 5, TAB_LEFT | TAT_PRINTF,
- inf.ncases == -1 ? _("Unknown") : "%d", inf.ncases);
+ info.case_cnt == -1 ? _("Unknown") : "%d", info.case_cnt);
tab_text (t, 0, 6, TAB_LEFT, _("Type:"));
tab_text (t, 1, 6, TAB_LEFT, _("System File."));
tab_text (t, 0, 7, TAB_LEFT, _("Weight:"));
}
tab_text (t, 0, 8, TAB_LEFT, _("Mode:"));
tab_text (t, 1, 8, TAB_LEFT | TAT_PRINTF,
- _("Compression %s."), inf.compressed ? _("on") : _("off"));
+ _("Compression %s."), info.compressed ? _("on") : _("off"));
tab_dim (t, tab_natural_dimensions);
tab_submit (t);
#include "str.h"
#include "case.h"
#include "command.h"
+#include "dictionary.h"
#include "lexer.h"
#include "error.h"
#include "magic.h"
#include "group_proc.h"
#include "casefile.h"
#include "levene.h"
+/* (headers) */
/* (specification)
"T-TEST" (tts_):
/* Destroy any group statistics we created */
for (v = 0 ; v < cmd.n_variables ; ++v )
{
- struct group_proc *grpp = &cmd.v_variables[v]->p.grp_data;
+ struct group_proc *grpp = group_proc_get (cmd.v_variables[v]);
free(grpp->group_hash);
}
}
for (i=0; i < cmd->n_variables; ++i)
{
struct variable *var = cmd->v_variables[i];
- struct hsh_table *grp_hash = var->p.grp_data.group_hash;
+ struct hsh_table *grp_hash = group_proc_get (var)->group_hash;
int count=0;
tab_text (ssb->t, 0, i*2+1, TAB_LEFT, cmd->v_variables[i]->name);
{
struct group_statistics *gs;
- gs=&pairs[i].v[j]->p.grp_data.ugs;
+ gs = &group_proc_get (pairs[i].v[j])->ugs;
/* Titles */
for (i=0; i < cmd->n_variables; ++i)
{
- struct group_statistics *gs;
- gs= &cmd->v_variables[i]->p.grp_data.ugs;
+ struct group_statistics *gs = &group_proc_get (cmd->v_variables[i])->ugs;
tab_text (ssb->t, 0, i+1, TAB_LEFT, cmd->v_variables[i]->name);
tab_float (ssb->t,1, i+1, TAB_RIGHT, gs->n, 2, 0);
double mean_diff;
struct variable *var = cmd->v_variables[i];
+ struct group_proc *grp_data = group_proc_get (var);
- struct hsh_table *grp_hash = var->p.grp_data.group_hash;
+ struct hsh_table *grp_hash = grp_data->group_hash;
struct group_statistics *gs0 ;
struct group_statistics *gs1 ;
tab_text (self->t, 1, i*2+3, TAB_LEFT, _("Equal variances assumed"));
- tab_float(self->t, 2, i*2+3, TAB_CENTER,
- cmd->v_variables[i]->p.grp_data.levene, 8,3);
+ tab_float(self->t, 2, i*2+3, TAB_CENTER, grp_data->levene, 8,3);
/* Now work out the significance of the Levene test */
- df1 = 1; df2 = cmd->v_variables[i]->p.grp_data.ugs.n - 2;
- q = gsl_cdf_fdist_Q(cmd->v_variables[i]->p.grp_data.levene, df1, df2);
+ df1 = 1; df2 = grp_data->ugs.n - 2;
+ q = gsl_cdf_fdist_Q(grp_data->levene, df1, df2);
tab_float(self->t, 3, i*2+3, TAB_CENTER, q, 8,3 );
double t;
double p,q;
double df;
- struct group_statistics *gs;
- gs= &cmd->v_variables[i]->p.grp_data.ugs;
+ struct group_statistics *gs = &group_proc_get (cmd->v_variables[i])->ugs;
tab_text (trb->t, 0, i+3, TAB_LEFT, cmd->v_variables[i]->name);
struct variable *v = cmd->v_variables[i];
const union value *val = case_data (c, v->fv);
- gs= &cmd->v_variables[i]->p.grp_data.ugs;
+ gs= &group_proc_get (cmd->v_variables[i])->ugs;
if (! value_is_missing(val,v) )
{
for(i=0; i< cmd->n_variables ; ++i)
{
struct group_statistics *gs;
- gs= &cmd->v_variables[i]->p.grp_data.ugs;
+ gs= &group_proc_get (cmd->v_variables[i])->ugs;
gs->sum=0;
gs->n=0;
for(i=0; i< cmd->n_variables ; ++i)
{
struct group_statistics *gs;
- gs= &cmd->v_variables[i]->p.grp_data.ugs;
+ gs= &group_proc_get (cmd->v_variables[i])->ugs;
gs->mean=gs->sum / gs->n;
gs->s_std_dev= sqrt(
struct variable *v = cmd->v_variables[i];
const union value *val = case_data (c, v->fv);
- gs= &cmd->v_variables[i]->p.grp_data.ugs;
+ gs= &group_proc_get (cmd->v_variables[i])->ugs;
if ( ! value_is_missing(val,v))
gs->sum_diff += weight * (val->f - cmd->n_testval[0]);
for(i=0; i< cmd->n_variables ; ++i)
{
struct group_statistics *gs;
- gs= &cmd->v_variables[i]->p.grp_data.ugs;
+ gs= &group_proc_get (cmd->v_variables[i])->ugs;
gs->sum_diff=0;
}
for(i=0; i< cmd->n_variables ; ++i)
{
struct group_statistics *gs;
- gs= &cmd->v_variables[i]->p.grp_data.ugs;
+ gs= &group_proc_get (cmd->v_variables[i])->ugs;
gs->mean_diff = gs->sum_diff / gs->n ;
}
for(i=0; i< cmd->n_variables ; ++i)
{
- struct group_proc *ttpr = &cmd->v_variables[i]->p.grp_data;
+ struct group_proc *ttpr = group_proc_get (cmd->v_variables[i]);
/* There's always 2 groups for a T - TEST */
ttpr->n_groups = 2;
{
struct variable *var = cmd->v_variables[i];
const union value *val = case_data (c, var->fv);
- struct hsh_table *grp_hash = var->p.grp_data.group_hash;
+ struct hsh_table *grp_hash = group_proc_get (var)->group_hash;
struct group_statistics *gs;
gs = hsh_find(grp_hash, (void *) gv);
for(i=0; i< cmd->n_variables ; ++i)
{
struct variable *var = cmd->v_variables[i];
- struct hsh_table *grp_hash = var->p.grp_data.group_hash;
+ struct hsh_table *grp_hash = group_proc_get (var)->group_hash;
struct hsh_iterator g;
struct group_statistics *gs;
int count=0;
#include <stdlib.h>
#include "alloc.h"
#include "command.h"
+#include "dictionary.h"
#include "do-ifP.h"
#include "error.h"
#include "hash.h"
#include <stdlib.h>
#include "alloc.h"
#include "command.h"
+#include "dictionary.h"
#include "error.h"
#include "lexer.h"
#include "main.h"
#include "value-labels.h"
#include "error.h"
#include <stdlib.h>
-#include <string.h>
#include "alloc.h"
#include "hash.h"
+#include "str.h"
static hsh_compare_func compare_int_val_lab;
static hsh_hash_func hash_int_val_lab;
#include <stddef.h>
#include "format.h"
-#include "group_proc.h"
#include "val.h"
/* Frequency tables. */
double valid_cases; /* Sum of weights of valid cases. */
};
\f
-/* Procedures' private per-variable data. */
-
-/* Structure name suffixes for private data:
- _proc: for a procedure (i.e., LIST -> list_proc).
- _trns: for a transformation (i.e., COMPUTE -> compute_trns.
- _pgm: for an input program (i.e., DATA LIST -> data_list_pgm). */
-
-/* CROSSTABS private data. */
-struct crosstab_proc
- {
- /* Integer mode only. */
- int min; /* Minimum value. */
- int max; /* Maximum value + 1. */
- int count; /* max - min. */
- };
-
-
-/* FREQUENCIES private data. */
-enum
- {
- frq_mean = 0, frq_semean, frq_median, frq_mode, frq_stddev, frq_variance,
- frq_kurt, frq_sekurt, frq_skew, frq_seskew, frq_range, frq_min, frq_max,
- frq_sum, frq_n_stats
- };
-
-struct frequencies_proc
- {
- int used; /* 1=This variable already used. */
-
- /* Freqency table. */
- struct freq_tab tab; /* Frequencies table to use. */
-
- /* Percentiles. */
- int n_groups; /* Number of groups. */
- double *groups; /* Groups. */
-
- /* Statistics. */
- double stat[frq_n_stats];
- };
-
-/* LIST private data. */
-struct list_proc
- {
- int newline; /* Whether a new line begins here. */
- int width; /* Field width. */
- int vert; /* Whether to print the varname vertically. */
- };
-
-/* GET private data. */
-struct get_proc
- {
- int fv, nv; /* First, # of values. */
- };
-
-/* MEANS private data. */
-struct means_proc
- {
- double min, max; /* Range for integer mode. */
- };
-
-/* Different types of variables for MATRIX DATA procedure. Order is
- important: these are used for sort keys. */
-enum
- {
- MXD_SPLIT, /* SPLIT FILE variables. */
- MXD_ROWTYPE, /* ROWTYPE_. */
- MXD_FACTOR, /* Factor variables. */
- MXD_VARNAME, /* VARNAME_. */
- MXD_CONTINUOUS, /* Continuous variables. */
-
- MXD_COUNT
- };
-
-/* MATRIX DATA private data. */
-struct matrix_data_proc
- {
- int vartype; /* Variable type. */
- int subtype; /* Subtype. */
- };
-
-/* MATCH FILES private data. */
-struct match_files_proc
- {
- struct variable *master; /* Corresponding master file variable. */
- };
-
-\f
/* Script variables. */
/* Variable type. */
};
/* Types of missing values. Order is significant, see
- mis-val.c:parse_numeric(), sfm-read.c:sfm_read_dictionary()
- sfm-write.c:sfm_write_dictionary(),
+ mis-val.c:parse_numeric(), sfm-read.c, sfm-write.c,
sysfile-info.c:cmd_sysfile_info(), mis-val.c:copy_missing_values(),
pfm-read.c:read_variables(), pfm-write.c:write_variables(),
apply-dict.c:cmd_apply_dictionary(), and more (?). */
struct val_labs *val_labs; /* Value labels. */
char *label; /* Variable label. */
- /* Per-procedure info. */
+ /* Per-command info. */
void *aux;
- struct get_proc get;
- union
- {
- struct crosstab_proc crs;
- struct frequencies_proc frq;
- struct list_proc lst;
- struct means_proc mns;
- struct matrix_data_proc mxd;
- struct match_files_proc mtf;
- struct group_proc grp_data;
- }
- p;
+ void (*aux_dtor) (struct variable *);
};
int compare_variables (const void *, const void *, void *);
unsigned hash_variable (const void *, void *);
+void *var_attach_aux (struct variable *,
+ void *aux, void (*aux_dtor) (struct variable *));
+void var_clear_aux (struct variable *);
+void *var_detach_aux (struct variable *);
+void var_dtor_free (struct variable *);
+
/* Classes of variables. */
enum dict_class
{
int cnt; /* Number of variables. */
};
\f
-/* Dictionary. */
-
-/* Complete dictionary state. */
-struct dictionary;
-
-struct dictionary *dict_create (void);
-struct dictionary *dict_clone (const struct dictionary *);
-void dict_clear (struct dictionary *);
-void dict_destroy (struct dictionary *);
-
-size_t dict_get_var_cnt (const struct dictionary *);
-struct variable *dict_get_var (const struct dictionary *, size_t idx);
-void dict_get_vars (const struct dictionary *,
- struct variable ***vars, size_t *cnt,
- unsigned exclude_classes);
-
-struct variable *dict_create_var (struct dictionary *, const char *,
- int width);
-struct variable *dict_create_var_assert (struct dictionary *, const char *,
- int width);
-struct variable *dict_clone_var (struct dictionary *, const struct variable *,
- const char *);
-void dict_rename_var (struct dictionary *, struct variable *, const char *);
-
-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 *);
-void dict_delete_var (struct dictionary *, struct variable *);
-void dict_delete_vars (struct dictionary *,
- struct variable *const *, size_t count);
-void dict_reorder_vars (struct dictionary *,
- struct variable *const *, size_t count);
-int 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 *);
-double dict_get_case_weight (const struct dictionary *,
- const struct ccase *, int *);
-void dict_set_weight (struct dictionary *, struct variable *);
-
-struct variable *dict_get_filter (const struct dictionary *);
-void dict_set_filter (struct dictionary *, struct variable *);
-
-int dict_get_case_limit (const struct dictionary *);
-void dict_set_case_limit (struct dictionary *, int);
-
-int dict_get_next_value_idx (const struct dictionary *);
-size_t dict_get_case_size (const struct dictionary *);
-
-void dict_compact_values (struct dictionary *);
-size_t dict_get_compacted_value_cnt (const struct dictionary *);
-int *dict_get_compacted_idx_to_fv (const struct dictionary *);
-
-struct variable *const *dict_get_split_vars (const struct dictionary *);
-size_t dict_get_split_cnt (const struct dictionary *);
-void dict_set_split_vars (struct dictionary *,
- struct variable *const *, size_t cnt);
-
-const char *dict_get_label (const struct dictionary *);
-void dict_set_label (struct dictionary *, const char *);
-
-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);
-const struct vector *dict_get_vector (const struct dictionary *,
- size_t idx);
-size_t dict_get_vector_cnt (const struct dictionary *);
-const struct vector *dict_lookup_vector (const struct dictionary *,
- const char *name);
-void dict_clear_vectors (struct dictionary *);
\f
void discard_variables (void);
\f
/* Functions. */
+struct ccase;
void dump_split_vars (const struct ccase *);
typedef int (* is_missing_func )(const union value *, const struct variable *);
#include <stdlib.h>
#include "alloc.h"
#include "command.h"
+#include "dictionary.h"
#include "do-ifP.h"
#include "expr.h"
#include "file-handle.h"
#include "debug-print.h"
+void *
+var_attach_aux (struct variable *v,
+ void *aux, void (*aux_dtor) (struct variable *))
+{
+ assert (v->aux == NULL);
+ assert (aux != NULL);
+ v->aux = aux;
+ v->aux_dtor = aux_dtor;
+ return aux;
+}
+
+void *
+var_detach_aux (struct variable *v)
+{
+ void *aux = v->aux;
+ assert (aux != NULL);
+ v->aux = NULL;
+ return aux;
+}
+
+void
+var_clear_aux (struct variable *v)
+{
+ assert (v != NULL);
+ if (v->aux != NULL)
+ {
+ if (v->aux_dtor != NULL)
+ v->aux_dtor (v);
+ v->aux = NULL;
+ }
+}
+
+void
+var_dtor_free (struct variable *v)
+{
+ free (v->aux);
+}
+
/* Compares A and B, which both have the given WIDTH, and returns
a strcmp()-type result. */
int
discard_variables (void)
{
dict_clear (default_dict);
- default_handle = inline_file;
+ default_handle = NULL;
n_lag = 0;
#include <stdlib.h>
#include "alloc.h"
#include "bitvector.h"
+#include "dictionary.h"
#include "error.h"
#include "hash.h"
#include "lexer.h"
#include <stdlib.h>
#include "alloc.h"
#include "command.h"
+#include "dictionary.h"
#include "error.h"
#include "lexer.h"
#include "misc.h"
#include "alloc.h"
#include "case.h"
#include "casefile.h"
+#include "dictionary.h"
#include "do-ifP.h"
#include "error.h"
#include "expr.h"
#include "error.h"
#include <stdio.h>
#include "command.h"
+#include "dictionary.h"
#include "error.h"
#include "lexer.h"
#include "str.h"