From 8acca2de53c1852f38726f70fc6516b34732a79f Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sun, 5 Nov 2006 05:20:52 +0000 Subject: [PATCH] Rewrite and improve formatted output routines. Add lots of regression tests. Revise documentation. Thanks to John Darrington for review--see patch #5522. --- ChangeLog | 4 + configure.ac | 2 +- doc/data-io.texi | 6 +- doc/language.texi | 868 +- doc/transformation.texi | 2 +- doc/utilities.texi | 121 +- doc/variables.texi | 6 +- src/data/ChangeLog | 24 + src/data/calendar.c | 17 +- src/data/calendar.h | 2 +- src/data/data-out.c | 1889 ++-- src/data/data-out.h | 37 + src/data/format.c | 23 +- src/data/format.h | 4 - src/data/value-labels.c | 3 +- src/language/data-io/list.q | 13 +- src/language/data-io/print.c | 4 +- src/language/dictionary/ChangeLog | 5 + src/language/dictionary/numeric.c | 12 +- src/language/dictionary/split-file.c | 3 +- src/language/expressions/helpers.h | 1 + src/language/expressions/operations.def | 2 +- src/language/lexer/format-parser.h | 2 - src/language/stats/crosstabs.q | 7 +- src/language/utilities/ChangeLog | 13 + src/language/utilities/set.q | 131 + src/libpspp/str.c | 25 + src/libpspp/str.h | 3 + src/output/table.c | 5 +- src/ui/gui/helper.c | 6 +- src/ui/gui/psppire-data-store.c | 3 +- tests/ChangeLog | 23 + tests/automake.mk | 11 +- tests/command/no_case_size.sh | 10 +- tests/expressions/expressions.sh | 2 +- tests/formats/binhex-out.expected.gz | Bin 0 -> 4106 bytes tests/formats/binhex-out.sh | 168 + tests/formats/date-out.sh | 578 + tests/formats/inexactify.c | 65 + tests/formats/month-out.sh | 996 ++ tests/formats/num-out-cmp.pl | 74 + tests/formats/num-out-compare.pl | 122 + tests/formats/num-out-decmp.pl | 28 + tests/formats/num-out.expected.cmp.gz | Bin 0 -> 206727 bytes tests/formats/num-out.pl | 41 + tests/formats/num-out.sh | 78 + tests/formats/time-out.sh | 13124 ++++++++++++++++++++++ tests/formats/wkday-out.sh | 821 ++ 48 files changed, 18003 insertions(+), 1381 deletions(-) create mode 100644 src/data/data-out.h create mode 100644 tests/formats/binhex-out.expected.gz create mode 100755 tests/formats/binhex-out.sh create mode 100755 tests/formats/date-out.sh create mode 100644 tests/formats/inexactify.c create mode 100755 tests/formats/month-out.sh create mode 100644 tests/formats/num-out-cmp.pl create mode 100644 tests/formats/num-out-compare.pl create mode 100644 tests/formats/num-out-decmp.pl create mode 100644 tests/formats/num-out.expected.cmp.gz create mode 100644 tests/formats/num-out.pl create mode 100755 tests/formats/num-out.sh create mode 100755 tests/formats/time-out.sh create mode 100755 tests/formats/wkday-out.sh diff --git a/ChangeLog b/ChangeLog index ddf1d6cf..e50320c4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Sat Nov 4 15:59:31 2006 Ben Pfaff + + * configure.ac: Check for the "round" function added in C99. + Tue Oct 31 19:55:52 2006 Ben Pfaff * Smake (GNULIB_MODULES): Add `mempcpy' module. diff --git a/configure.ac b/configure.ac index dddfc564..0295d7fa 100644 --- a/configure.ac +++ b/configure.ac @@ -73,7 +73,7 @@ AC_DEFINE(FPREP_IEEE754, 1, AC_C_BIGENDIAN AC_FUNC_VPRINTF -AC_CHECK_FUNCS([__setfpucw isinf isnan finite getpid feholdexcept]) +AC_CHECK_FUNCS([__setfpucw isinf isnan finite getpid feholdexcept round]) AC_PROG_LN_S diff --git a/doc/data-io.texi b/doc/data-io.texi index d7e18ae8..efff25ea 100644 --- a/doc/data-io.texi +++ b/doc/data-io.texi @@ -186,7 +186,7 @@ In columnar style, the starting column and ending column for the field are specified after the variable name, separated by a dash (@samp{-}). For instance, the third through fifth columns on a line would be specified @samp{3-5}. By default, variables are considered to be in -@samp{F} format (@pxref{Input/Output Formats}). (This default can be +@samp{F} format (@pxref{Input and Output Formats}). (This default can be changed; see @ref{SET} for more information.) In columnar style, to use a variable format other than the default, @@ -218,7 +218,7 @@ Implied decimal places also exist in FORTRAN style. A format specification with @var{d} decimal places also has @var{d} implied decimal places. -In addition to the standard format specifiers (@pxref{Input/Output +In addition to the standard format specifiers (@pxref{Input and Output Formats}), FORTRAN style defines some extensions: @table @asis @@ -381,7 +381,7 @@ The FILE and END subcommands are as in @cmd{DATA LIST FIXED} above. The variables to be parsed are given as a single list of variable names. This list must be introduced by a single slash (@samp{/}). The set of variable names may contain format specifications in parentheses -(@pxref{Input/Output Formats}). Format specifications apply to all +(@pxref{Input and Output Formats}). Format specifications apply to all variables back to the previous parenthesized format specification. In addition, an asterisk may be used to indicate that all variables diff --git a/doc/language.texi b/doc/language.texi index 66e5ba36..3b667618 100644 --- a/doc/language.texi +++ b/doc/language.texi @@ -383,7 +383,7 @@ Some details of variables are described in the sections below. * Attributes:: Attributes of variables. * System Variables:: Variables automatically defined by PSPP. * Sets of Variables:: Lists of variable names. -* Input/Output Formats:: Input and output formats. +* Input and Output Formats:: Input and output formats. * Scratch Variables:: Variables deleted by procedures. @end menu @@ -470,12 +470,12 @@ string. @xref{VALUE LABELS}. Display width, format, and (for numeric variables) number of decimal places. This attribute does not affect how data are stored, just how they are displayed. Example: a width of 8, with 2 decimal places. -@xref{PRINT FORMATS}. +@xref{Input and Output Formats}. @cindex write format @item Write format -Similar to print format, but used by certain commands that are -designed to write to binary files. @xref{WRITE FORMATS}. +Similar to print format, but used by the @cmd{WRITE} command +(@pxref{WRITE}). @end table @node System Variables, Sets of Variables, Attributes, Variables @@ -522,7 +522,7 @@ was read, in format F20. Page width, in characters, in format F3. @end table -@node Sets of Variables, Input/Output Formats, System Variables, Variables +@node Sets of Variables, Input and Output Formats, System Variables, Variables @subsection Lists of variable names @cindex TO convention @cindex convention, TO @@ -551,326 +551,680 @@ After a set of variables has been defined with @cmd{DATA LIST} or another command with this method, the same set can be referenced on later commands using the same syntax. -@node Input/Output Formats, Scratch Variables, Sets of Variables, Variables +@node Input and Output Formats, Scratch Variables, Sets of Variables, Variables @subsection Input and Output Formats -Data that PSPP inputs and outputs must have one of a number of formats. -These formats are described, in general, by a format specification of -the form @code{NAMEw.d}, where @var{name} is the -format name and @var{w} is a field width. @var{d} is the optional -desired number of decimal places, if appropriate. If @var{d} is not -included then it is assumed to be 0. Some formats do not allow @var{d} -to be specified. +An @dfn{input format} describes how to interpret the contents of an +input field as a number or a string. It might specify that the field +contains an ordinary decimal number, a time or date, a number in binary +or hexadecimal notation, or one of several other notations. Input +formats are used by commands such as @cmd{DATA LIST} that read data or +syntax files into the PSPP active file. + +Every input format corresponds to a default @dfn{output format} that +specifies the formatting used when the value is output later. It is +always possible to explicitly specify an output format that resembles +the input format. Usually, this is the default, but in cases where the +input format is unfriendly to human readability, such as binary or +hexadecimal formats, the default output format is an easier-to-read +decimal format. + +Every variable has two output formats, called its @dfn{print format} and +@dfn{write format}. Print formats are used in most output contexts; +write formats are used only by @cmd{WRITE} (@pxref{WRITE}). Newly +created variables have identical print and write formats, and +@cmd{FORMATS}, the most commonly used command for changing formats +(@pxref{FORMATS}), sets both of them to the same value as well. Thus, +most of the time, the distinction between print and write formats is +unimportant. + +Input and output formats are specified to PSPP with a @dfn{format +specification} of the form @code{TYPEw} or @code{TYPEw.d}, where +@code{TYPE} is one of the format types described later, @code{w} is a +field width measured in columns, and @code{d} is an optional number of +decimal places. If @code{d} is omitted, a value of 0 is assumed. Some +formats do not allow a nonzero @code{d} to be specified. + +The following sections describe the input and output formats supported +by PSPP. -When @cmd{DATA LIST} or another command specifies an input format, -that format is converted to an output format for the purposes of -@cmd{PRINT} and other data output commands. For most purposes, input -and output formats are the same; the salient differences are described -below. +@menu +* Basic Numeric Formats:: +* Custom Currency Formats:: +* Legacy Numeric Formats:: +* Binary and Hexadecimal Numeric Formats:: +* Time and Date Formats:: +* Date Component Formats:: +* String Formats:: +@end menu -Below are listed the input and output formats supported by PSPP. If an -input format is mapped to a different output format by default, then -that mapping is indicated with @result{}. Each format has the listed -bounds on input width (iw) and output width (ow). +@node Basic Numeric Formats +@subsubsection Basic Numeric Formats + +The basic numeric formats are used for input and output of real numbers +in standard or scientific notation. The following table shows an +example of how each format displays positive and negative numbers with +the default decimal point setting: + +@float +@multitable {DOLLAR10.2} {@code{@tie{}$3,141.59}} {@code{-$3,141.59}} +@headitem Format @tab @code{@tie{}}3141.59 @tab -3141.59 +@item F8.2 @tab @code{@tie{}3141.59} @tab @code{-3141.59} +@item COMMA9.2 @tab @code{@tie{}3,141.59} @tab @code{-3,141.59} +@item DOT9.2 @tab @code{@tie{}3.141,59} @tab @code{-3.141,59} +@item DOLLAR10.2 @tab @code{@tie{}$3,141.59} @tab @code{-$3,141.59} +@item PCT9.2 @tab @code{@tie{}3141.59%} @tab @code{-3141.59%} +@item E8.1 @tab @code{@tie{}3.1E+003} @tab @code{-3.1E+003} +@end multitable +@end float + +On output, numbers in F format are expressed in standard decimal +notation with the requested number of decimal places. The other formats +output some variation on this style: -The standard numeric input and output formats are given in the following -table: +@itemize @bullet +@item +Numbers in COMMA format are additionally grouped every three digits by +inserting a grouping character. The grouping character is ordinarily a +comma, but it can be changed to a period (@pxref{SET DECIMAL}). -@table @asis -@item Fw.d: 1 <= iw,ow <= 40 -Standard decimal format with @var{d} decimal places. If the number is -too large to fit within the field width, it is expressed in scientific -notation (@code{1.2+34}) if w >= 6, with always at least two digits in -the exponent. When used as an input format, scientific notation is -allowed but an E or an F must be used to introduce the exponent. - -The default output format is the same as the input format, except if -@var{d} > 1. In that case the output @var{w} is always made to be at -least 2 + @var{d}. +@item +DOT format is like COMMA format, but it interchanges the role of the +decimal point and grouping characters. That is, the current grouping +character is used as a decimal point and vice versa. -@item Ew.d: 1 <= iw <= 40; 6 <= ow <= 40 -For input this is equivalent to F format except that no E or F is -require to introduce the exponent. For output, produces scientific -notation in the form @code{1.2+34}. There are always at least two -digits given in the exponent. +@item +DOLLAR format is like COMMA format, but it prefixes the number with +@samp{$}. -The default output @var{w} is the largest of the input @var{w}, the -input @var{d} + 7, and 10. The default output @var{d} is the input -@var{d}, but at least 3. +@item +PCT format is like F format, but adds @samp{%} after the number. -@item COMMAw.d: 1 <= iw,ow <= 40 -Equivalent to F format, except that groups of three digits are -comma-separated on output. If the number is too large to express in the -field width, then first commas are eliminated, then if there is still -not enough space the number is expressed in scientific notation given -that w >= 6. Commas are allowed and ignored when this is used as an -input format. +@item +The E format always produces output in scientific notation. +@end itemize -@item DOTw.d: 1 <= iw,ow <= 40 -Equivalent to COMMA format except that the roles of comma and decimal -point are interchanged. However: If SET /DECIMAL=DOT is in effect, then -COMMA uses @samp{,} for a decimal point and DOT uses @samp{.} for a -decimal point. +On input, the basic numeric formats accept positive and numbers in +standard decimal notation or scientific notation. Leading and trailing +spaces are allowed. An empty or all-spaces field, or one that contains +only a single period, is treated as the system missing value. -@item DOLLARw.d: 1 <= iw <= 40; 2 <= ow <= 40 -Equivalent to COMMA format, except that the number is prefixed by a -dollar sign (@samp{$}) if there is room. On input the value is allowed -to be prefixed by a dollar sign, which is ignored. +In scientific notation, the exponent may be introduced by a sign +(@samp{+} or @samp{-}), or by one of the letters @samp{e} or @samp{d} +(in uppercase or lowercase), or by a letter followed by a sign. A +single space may follow the letter or the sign or both. -The default output @var{w} is the input @var{w}, but at least 2. +On fixed-format @cmd{DATA LIST} (@pxref{DATA LIST FIXED}) and in a few +other contexts, decimals are implied when the field does not contain a +decimal point. In F6.5 format, for example, the field @code{314159} is +taken as the value 3.14159 with implied decimals. Decimals are never +implied if an explicit decimal point is present or if scientific +notation is used. -@item PCTw.d: 2 <= iw,ow <= 40 -Equivalent to F format, except that the number is suffixed by a percent -sign (@samp{%}) if there is room. On input the value is allowed to be -suffixed by a percent sign, which is ignored. +E and F formats accept the basic syntax already described. The other +formats allow some additional variations: -The default output @var{w} is the input @var{w}, but at least 2. +@itemize @bullet +@item +COMMA, DOLLAR, and DOT formats ignore grouping characters within the +integer part of the input field. The identity of the grouping +character depends on the format. -@item Nw.d: 1 <= iw,ow <= 40 -Only digits are allowed within the field width. The decimal point is -assumed to be @var{d} digits from the right margin. +@item +DOLLAR format allows a dollar sign to precede the number. In a negative +number, the dollar sign may precede or follow the minus sign. -The default output format is F with the same @var{w} and @var{d}, except -if @var{d} > 1. In that case the output @var{w} is always made to be at -least 2 + @var{d}. +@item +PCT format allows a percent sign to follow the number. +@end itemize -@item Zw.d @result{} F: 1 <= iw,ow <= 40 -Zoned decimal input. If you need to use this then you know how. +All of the basic number formats have a maximum field width of 40 and +accept no more than 16 decimal places, on both input and output. Some +additional restrictions apply: -@item IBw.d @result{} F: 1 <= iw,ow <= 8 -Integer binary format. The field is interpreted as a fixed-point -positive or negative binary number in two's-complement notation. The -location of the decimal point is implied. Endianness is the same as the -host machine. +@itemize @bullet +@item +As input formats, the basic numeric formats allow no more decimal places +than the field width. As output formats, the field width must be +greater than the number of decimal places; that is, large enough to +allow for a decimal point and the number of requested decimal places. +DOLLAR and PCT formats must allow an additional column for @samp{$} or +@samp{%}. -The default output format is F8.2 if @var{d} is 0. Otherwise it is F, -with output @var{w} as 9 + input @var{d} and output @var{d} as input -@var{d}. +@item +The default output format for a given input format increases the field +width enough to make room for optional input characters. If an input +format calls for decimal places, the width is increased by 1 to make +room for an implied decimal point. COMMA, DOT, and DOLLAR formats also +increase the output width to make room for grouping characters. DOLLAR +and PCT further increase the output field width by 1 to make room for +@samp{$} or @samp{%}. The increased output width is capped at 40, the +maximum field width. -@item PIB @result{} F: 1 <= iw,ow <= 8 -Positive integer binary format. The field is interpreted as a -fixed-point positive binary number. The location of the decimal point -is implied. Endianness is the same as the host machine. +@item +The E format is exceptional. For output, E format has a minimum width +of 7 plus the number of decimal places. The default output format for +an E input format is an E format with at least 3 decimal places and +thus a minimum width of 10. +@end itemize -The default output format follows the rules for IB format. +More details of basic numeric output formatting are given below: -@item Pw.d @result{} F: 1 <= iw,ow <= 16 -Binary coded decimal format. Each byte from left to right, except the -rightmost, represents two digits. The upper nibble of each byte is more -significant. The upper nibble of the final byte is the least -significant digit. The lower nibble of the final byte is the sign; a -value of D represents a negative sign and all other values are -considered positive. The decimal point is implied. +@itemize @bullet +@item +Output rounds to nearest, with ties rounded away from zero. Thus, 2.5 +is output as @code{3} in F1.0 format, and -1.125 as @code{-1.13} in F5.1 +format. -The default output format follows the rules for IB format. +@item +The system-missing value is output as a period in a field of spaces, +placed in the decimal point's position, or in the rightmost column if no +decimal places are requested. A period is used even if the decimal +point character is a comma. -@item PKw.d @result{} F: 1 <= iw,ow <= 16 -Positive binary code decimal format. Same as P but the last byte is the -same as the others. +@item +A number that does not fill its field is right-justified within the +field. -The default output format follows the rules for IB format. +@item +A number is too large for its field causes decimal places to be dropped +to make room. If dropping decimals does not make enough room, +scientific notation is used if the field is wide enough. If a number +does not fit in the field, even in scientific notation, the overflow is +indicated by filling the field with asterisks (@samp{*}). -@item RBw @result{} F: 2 <= iw,ow <= 8 +@item +COMMA, DOT, and DOLLAR formats insert grouping characters only if space +is available for all of them. Grouping characters are never inserted +when all decimal places must be dropped. Thus, 1234.56 in COMMA5.2 +format is output as @samp{@tie{}1235} without a comma, even though there +is room for one, because all decimal places were dropped. -Binary C architecture-dependent ``double'' format. For a standard -IEEE754 implementation @var{w} should be 8. +@item +DOLLAR or PCT format drop the @samp{$} or @samp{%} only if the number +would not fit at all without it. Scientific notation with @samp{$} or +@samp{%} is preferred to ordinary decimal notation without it. -The default output format follows the rules for IB format. +@item +Except in scientific notation, a decimal point is included only when +it is followed by a digit. If the integer part of the number being +output is 0, and a decimal point is included, then the zero before the +decimal point is dropped. -@item PIBHEXw.d @result{} F: 2 <= iw,ow <= 16 -PIB format encoded as textual hex digit pairs. @var{w} must be even. +In scientific notation, the number always includes a decimal point, +even if it is not followed by a digit. -The input width is mapped to a default output width as follows: -2@result{}4, 4@result{}6, 6@result{}9, 8@result{}11, 10@result{}14, -12@result{}16, 14@result{}18, 16@result{}21. No allowances are made for -decimal places. +@item +A negative number includes a minus sign only in the presence of a +nonzero digit: -0.01 is output as @samp{-.01} in F4.2 format but as +@samp{@tie{}@tie{}.0} in F4.1 format. Thus, a ``negative zero'' never +includes a minus sign. -@item RBHEXw @result{} F: 4 <= iw,ow <= 16 +@item +In negative numbers output in DOLLAR format, the dollar sign follows the +negative sign. Thus, -9.99 in DOLLAR6.2 format is output as +@code{-$9.99}. -RB format encoded as textual hex digits pairs. @var{w} must be even. +@item +In scientific notation, the exponent is output as @samp{E} followed by +@samp{+} or @samp{-} and exactly three digits. Numbers with magnitude +less than 10**-999 or larger than 10**999 are not supported by most +computers, but if they are supported then their output is considered +to overflow the field and will be output as asterisks. -The default output format is F8.2. +@item +On most computers, no more than 15 decimal digits are significant in +output, even if more are printed. In any case, output precision cannot +be any higher than input precision; few data sets are accurate to 15 +digits of precision. Unavoidable loss of precision in intermediate +calculations may also reduce precision of output. -@item CCAw.d: 1 <= ow <= 40 -@itemx CCBw.d: 1 <= ow <= 40 -@itemx CCCw.d: 1 <= ow <= 40 -@itemx CCDw.d: 1 <= ow <= 40 -@itemx CCEw.d: 1 <= ow <= 40 +@item +Special values such as infinities and ``not a number'' values are +usually converted to the system-missing value before printing. In a few +circumstances, these values are output directly. In fields of width 3 +or greater, special values are output as however many characters will +fit from @code{+Infinity} or @code{-Infinity} for infinities, from +@code{NaN} for ``not a number,'' or from @code{Unknown} for other values +(if any are supported by the system). In fields under 3 columns wide, +special values are output as asterisks. +@end itemize -User-defined custom currency formats. May not be used as an input -format. @xref{SET}, for more details. -@end table +@node Custom Currency Formats +@subsubsection Custom Currency Formats + +The custom currency formats are closely related to the basic numeric +formats, but they allow users to customize the output format. The +SET command configures custom currency formats, using the syntax +@display +SET CC@var{x}=@t{"}@var{string}@t{"}. +@end display +@noindent +where @var{x} is A, B, C, D, or E, and @var{string} is no more than 16 +characters long. + +@var{string} must contain exactly three commas or exactly three periods +(but not both), except that a single quote character may be used to +``escape'' a following comma, period, or single quote. If three commas +are used, commas will be used for grouping in output, and a period will +be used as the decimal point. Uses of periods reverses these roles. + +The commas or periods divide @var{string} into four fields, called the +@dfn{negative prefix}, @dfn{prefix}, @dfn{suffix}, and @dfn{negative +suffix}, respectively. The prefix and suffix are added to output +whenever space is available. The negative prefix and negative suffix +are always added to a negative number when the output includes a nonzero +digit. + +The following syntax shows how custom currency formats could be used to +reproduce basic numeric formats: -The date and time numeric input and output formats accept a number of -possible formats. Before describing the formats themselves, some -definitions of the elements that make up their formats will be helpful: +@example +@group +SET CCA="-,,,". /* Same as COMMA. +SET CCB="-...". /* Same as DOT. +SET CCC="-,$,,". /* Same as DOLLAR. +SET CCD="-,,%,". /* Like PCT, but groups with commas. +@end group +@end example -@table @dfn -@item leader -All formats accept an optional white space leader. +Here are some more examples of custom currency formats. The final +example shows how to use a single quote to escape a delimiter: -@item day -An integer between 1 and 31 representing the day of month. +@example +@group +SET CCA=",EUR,,-". /* Euro. +SET CCB="(,USD ,,)". /* US dollar. +SET CCC="-.R$..". /* Brazilian real. +SET CCD="-,, NIS,". /* Israel shekel. +SET CCE="-.Rp'. ..". /* Indonesia Rupiah. +@end group +@end example -@item day-count -An integer representing a number of days. +@noindent These formats would yield the following output: -@item date-delimiter -One or more characters of white space or the following characters: -@code{- / . ,} +@float +@multitable {CCD13.2} {@code{@tie{}@tie{}USD 3,145.59}} {@code{(USD 3,145.59)}} +@headitem Format @tab @code{@tie{}}3145.59 @tab -3145.59 +@item CCA12.2 @tab @code{@tie{}EUR3,145.59} @tab @code{EUR3,145.59-} +@item CCB14.2 @tab @code{@tie{}@tie{}USD 3,145.59} @tab @code{(USD 3,145.59)} +@item CCC11.2 @tab @code{@tie{}R$3.145,59} @tab @code{-R$3.145,59} +@item CCD13.2 @tab @code{@tie{}3,145.59 NIS} @tab @code{-3,145.59 NIS} +@item CCE10.0 @tab @code{@tie{}Rp. 3.146} @tab @code{-Rp. 3.146} +@end multitable +@end float + +The default for all the custom currency formats is @samp{-,,,}, +equivalent to COMMA format. + +@node Legacy Numeric Formats +@subsubsection Legacy Numeric Formats + +The N and Z numeric formats provide compatibility with legacy file +formats. They have much in common: -@item month -A month name in one of the following forms: @itemize @bullet @item -An integer between 1 and 12. +Output is rounded to the nearest representable value, with ties rounded +away from zero. + +@item +Numbers too large to display are output as a field filled with asterisks +(@samp{*}). + +@item +The decimal point is always implicitly the specified number of digits +from the right edge of the field, except that Z format input allows an +explicit decimal point. + +@item +Scientific notation may not be used. + +@item +The system-missing value is output as a period in a field of spaces. +The period is placed just to the right of the implied decimal point in +Z format, or at the right end in N format or in Z format if no decimal +places are requested. A period is used even if the decimal point +character is a comma. + @item -Roman numerals representing an integer between 1 and 12. +Field width may range from 1 to 40. Decimal places may range from 0 up +to the field width, to a maximum of 16. + @item -At least the first three characters of an English month name (January, -February, @dots{}). +When a legacy numeric format used for input is converted to an output +format, it is changed into the equivalent F format. The field width is +increased by 1 if any decimal places are specified, to make room for a +decimal point. For Z format, the field width is increased by 1 more +column, to make room for a negative sign. The output field width is +capped at 40 columns. @end itemize -@item year -An integer year number between 1582 and 19999, or between 1 and 199. -Years between 1 and 199 will have 1900 added. +@subsubheading N Format -@item julian -A single number with a year number in the first 2, 3, or 4 digits (as -above) and the day number within the year in the last 3 digits. +The N format supports input and output of fields that contain only +digits. On input, leading or trailing spaces, a decimal point, or any +other non-digit character causes the field to be read as the +system-missing value. As a special exception, an N format used on +@cmd{DATA LIST FREE} or @cmd{DATA LIST LIST} is treated as the +equivalent F format. -@item quarter -An integer between 1 and 4 representing a quarter. +On output, N pads the field on the left with zeros. Negative numbers +are output like the system-missing value. -@item q-delimiter -The letter @samp{Q} or @samp{q}. +@subsubheading Z Format -@item week -An integer between 1 and 53 representing a week within a year. +The Z format is a ``zoned decimal'' format used on IBM mainframes. Z +format encodes the sign as part of the final digit, which must be one of +the following: +@example +0123456789 +@{ABCDEFGHI +@}JKLMNOPQR +@end example +@noindent +where the characters in each row represent digits 0 through 9 in order. +Characters in the first two rows indicate a positive sign; those in the +third indicate a negative sign. + +On output, Z fields are padded on the left with spaces. On input, +leading and trailing spaces are ignored. Any character in an input +field other than spaces, the digit characters above, and @samp{.} causes +the field to be read as system-missing. + +The decimal point character for input and output is always @samp{.}, +even if the decimal point character is a comma (@pxref{SET DECIMAL}). + +Nonzero, negative values output in Z format are marked as negative even +when no nonzero digits are output. For example, -0.2 is output in Z1.0 +format as @samp{J}. The ``negative zero'' value supported by most +machines is output as positive. + +@node Binary and Hexadecimal Numeric Formats +@subsubsection Binary and Hexadecimal Numeric Formats + +The binary and hexadecimal formats are primarily designed for +compatibility with existing machine formats, not for human readability. +All of them therefore have a F format as default output format. Some of +these formats are only portable between machines with compatible byte +ordering (endianness) or floating-point format. + +Binary formats use byte values that in text files are interpreted as +special control functions, such as carriage return and line feed. Thus, +data in binary formats should not be included in syntax files or read +from data files with variable-length records, such as ordinary text +files. They may be read from or written to data files with fixed-length +records. @xref{FILE HANDLE}, for information on working with +fixed-length records. + +@subsubheading P and PK Formats + +These are binary-coded decimal formats, in which every byte (except the +last, in P format) represents two decimal digits. The most-significant +4 bits of the first byte is the most-significant decimal digit, the +least-significant 4 bits of the first byte is the next decimal digit, +and so on. + +In P format, the most-significant 4 bits of the last byte are the +least-significant decimal digit. The least-significant 4 bits represent +the sign: decimal 15 indicates a negative value, decimal 13 indicates a +positive value. + +Numbers are rounded downward on output. The system-missing value and +numbers outside representable range are output as zero. + +The maximum field width is 16. Decimal places may range from 0 up to +the number of decimal digits represented by the field. + +The default output format is an F format with twice the input field +width, plus one column for a decimal point (if decimal places were +requested). + +@subsubheading IB and PIB Formats + +These are integer binary formats. IB reads and writes 2's complement +binary integers, and PIB reads and writes unsigned binary integers. The +byte ordering is by default the host machine's, but SET RIB may be used +to select a specific byte ordering for reading (@pxref{SET RIB}) and +SET WIB, similarly, for writing (@pxref{SET WIB}). + +The maximum field width is 8. Decimal places may range from 0 up to the +number of decimal digits in the largest value representable in the field +width. + +The default output format is an F format whose width is the number of +decimal digits in the largest value representable in the field width, +plus 1 if the format has decimal places. + +@subsubheading RB Format + +This is a binary format for real numbers. By default it reads and +writes the host machine's floating-point format, but SET RRB may be +used to select an alternate floating-point format for reading +(@pxref{SET RRB}) and SET WRB, similarly, for writing (@pxref{SET +WRB}). + +The recommended field width depends on the floating-point format. +NATIVE (the default format), IDL, IDB, VD, VG, and ZL formats should use +a field width of 8. ISL, ISB, VF, and ZS formats should use a field +width of 4. Other field widths will not produce useful results. The +maximum field width is 8. No decimal places may be specified. -@item wk-delimiter -The letters @samp{wk} in any case. +The default output format is F8.2. -@item time-delimiter -At least one characters of white space or @samp{:} or @samp{.}. +@subsubheading PIBHEX and RBHEX Formats + +These are hexadecimal formats, for reading and writing binary formats +where each byte has been recoded as a pair of hexadecimal digits. + +A hexadecimal field consists solely of hexadecimal digits +@samp{0}@dots{}@samp{9} and @samp{A}@dots{}@samp{F}. Uppercase and +lowercase are accepted on input; output is in uppercase. + +Other than the hexadecimal representation, these formats are equivalent +to PIB and RB formats, respectively. However, bytes in PIBHEX format +are always ordered with the most-significant byte first (big-endian +order), regardless of the host machine's native byte order or PSPP +settings. + +Field widths must be even and between 2 and 16. RBHEX format allows no +decimal places; PIBHEX allows as many decimal places as a PIB format +with half the given width. + +@node Time and Date Formats +@subsubsection Time and Date Formats + +In PSPP, a @dfn{time} is an interval. The time formats translate +between human-friendly descriptions of time intervals and PSPP's +internal representation of time intervals, which is simply the number of +seconds in the interval. PSPP has two time formats: + +@float +@multitable {Time Format} {@code{dd-mmm-yyyy HH:MM:SS.ss}} {@code{01-OCT-1978 04:31:17.01}} +@headitem Time Format @tab Template @tab Example +@item TIME @tab @code{hh:MM:SS.ss} @tab @code{04:31:17.01} +@item DTIME @tab @code{DD HH:MM:SS.ss} @tab @code{00 04:31:17.01} +@end multitable +@end float + +A @dfn{date} is a moment in the past or the future. Internally, PSPP +represents a date as the number of seconds since the @dfn{epoch}, +midnight, Oct. 14, 1582. The date formats translate between +human-readable dates and PSPP's numeric representation of dates and +times. PSPP has several date formats: + +@float +@multitable {Date Format} {@code{dd-mmm-yyyy HH:MM:SS.ss}} {@code{01-OCT-1978 04:31:17.01}} +@headitem Date Format @tab Template @tab Example +@item DATE @tab @code{dd-mmm-yyyy} @tab @code{01-OCT-1978} +@item ADATE @tab @code{mm/dd/yyyy} @tab @code{10/01/1978} +@item EDATE @tab @code{dd.mm.yyyy} @tab @code{01.10.1978} +@item JDATE @tab @code{yyyyjjj} @tab @code{1978274} +@item SDATE @tab @code{yyyy/mm/dd} @tab @code{1978/10/01} +@item QYR @tab @code{q Q yyyy} @tab @code{3 Q 1978} +@item MOYR @tab @code{mmm yyyy} @tab @code{OCT 1978} +@item WKYR @tab @code{ww WK yyyy} @tab @code{40 WK 1978} +@item DATETIME @tab @code{dd-mmm-yyyy HH:MM:SS.ss} @tab @code{01-OCT-1978 04:31:17.01} +@end multitable +@end float + +The templates in the preceding tables describe how the time and date +formats are input and output: -@item hour -An integer greater than 0 representing an hour. +@table @code +@item dd +Day of month, from 1 to 31. Always output as two digits. + +@item mm +@itemx mmm +Month. In output, @code{mm} is output as two digits, @code{mmm} as the +first three letters of an English month name (January, February, +@dots{}). In input, both of these formats, plus Roman numerals, are +accepted. + +@item yyyy +Year. In output, DATETIME always produces a 4-digit year; other +formats can produce a 2- or 4-digit year. The century assumed for +2-digit years depends on the EPOCH setting (@pxref{SET EPOCH}). In +output, a year outside the epoch causes the whole field to be filled +with asterisks (@samp{*}). + +@item jjj +Day of year (Julian day), from 1 to 366. This is exactly three digits +giving the count of days from the start of the year. January 1 is +considered day 1. + +@item q +Quarter of year, from 1 to 4. Quarters start on January 1, April 1, +July 1, and October 1. + +@item ww +Week of year, from 1 to 53. Output as exactly two digits. January 1 is +the first day of week 1. + +@item DD +Count of days, which may be positive or negative. Output as at least +two digits. + +@item hh +Count of hours, which may be positive or negative. Output as at least +two digits. + +@item HH +Hour of day, from 0 to 23. Output as exactly two digits. + +@item MM +Minute of hour, from 0 to 59. Output as exactly two digits. + +@item SS.ss +Seconds within minute, from 0 to 59. The integer part is output as +exactly two digits. On output, seconds and fractional seconds may or +may not be included, depending on field width and decimal places. On +input, seconds and fractional seconds are optional. The DECIMAL setting +controls the character accepted and displayed as the decimal point +(@pxref{SET DECIMAL}). +@end table -@item minute -An integer between 0 and 59 representing a minute within an hour. +For output, the date and time formats use the delimiters indicated in +the table. For input, date components may be separated by spaces or by +one of the characters @samp{-}, @samp{/}, @samp{.}, or @samp{,}, and +time components may be separated by spaces, @samp{:}, or @samp{.}. On +input, the @samp{Q} separating quarter from year and the @samp{WK} +separating week from year may be uppercase or lowercase, and the spaces +around them are optional. + +On input, all time and date formats accept any amount of leading and +trailing white space. + +The maximum width for time and date formats is 40 columns. Minimum +input and output width for each of the time and date formats is shown +below: +@float +@multitable {DATETIME} {Min. Input Width} {Min. Output Width} {4-digit year} +@headitem Format @tab Min. Input Width @tab Min. Output Width @tab Option +@item DATE @tab 8 @tab 9 @tab 4-digit year +@item ADATE @tab 8 @tab 8 @tab 4-digit year +@item EDATE @tab 8 @tab 8 @tab 4-digit year +@item JDATE @tab 5 @tab 5 @tab 4-digit year +@item SDATE @tab 8 @tab 8 @tab 4-digit year +@item QYR @tab 4 @tab 6 @tab 4-digit year +@item MOYR @tab 6 @tab 6 @tab 4-digit year +@item WKYR @tab 6 @tab 8 @tab 4-digit year +@item DATETIME @tab 17 @tab 17 @tab seconds +@item TIME @tab 5 @tab 5 @tab seconds +@item DTIME @tab 8 @tab 8 @tab seconds +@end multitable +@end float +@noindent +In the table, ``Option'' describes what increased output width enables: -@item opt-second -Optionally, a time-delimiter followed by a real number representing a -number of seconds. +@table @asis +@item 4-digit year +A field 2 columns wider than minimum will include a 4-digit year. +(DATETIME format always includes a 4-digit year.) + +@item seconds +A field 3 columns wider than minimum will include seconds as well as +minutes. A field 5 columns wider than minimum, or more, can also +include a decimal point and fractional seconds (but no more than allowed +by the format's decimal places). +@end table -@item hour24 -An integer between 0 and 23 representing an hour within a day. +For the time and date formats, the default output format is the same as +the input format, except that PSPP increases the field width, if +necessary, to the minimum allowed for output. -@item weekday -At least the first two characters of an English day word. +Time or dates narrower than the field width are right-justified within +the field. -@item spaces -Any amount or no amount of white space. +When a time or date exceeds the field width, characters are trimmed from +the end until it fits. This can occur in an unusual situation, e.g.@: +with a year greater than 9999 (which adds an extra digit), or for a +negative value on TIME or DTIME (which adds a leading minus sign). -@item sign -An optional positive or negative sign. +@c What about out-of-range values? -@item trailer -All formats accept an optional white space trailer. -@end table +The system-missing value is output as a period at the right end of the +field. -The date input formats are strung together from the above pieces. On -output, the date formats are always printed in a single canonical -manner, based on field width. The date input and output formats are -described below: +@node Date Component Formats +@subsubsection Date Component Formats -@table @asis -@item DATEw: 9 <= iw,ow <= 40 -Date format. Input format: leader + day + date-delimiter + -month + date-delimiter + year + trailer. Output format: DD-MMM-YY for -@var{w} < 11, DD-MMM-YYYY otherwise. - -@item EDATEw: 8 <= iw,ow <= 40 -European date format. Input format same as DATE. Output format: -DD.MM.YY for @var{w} < 10, DD.MM.YYYY otherwise. - -@item SDATEw: 8 <= iw,ow <= 40 -Standard date format. Input format: leader + year + date-delimiter + -month + date-delimiter + day + trailer. Output format: YY/MM/DD for -@var{w} < 10, YYYY/MM/DD otherwise. - -@item ADATEw: 8 <= iw,ow <= 40 -American date format. Input format: leader + month + date-delimiter + -day + date-delimiter + year + trailer. Output format: MM/DD/YY for -@var{w} < 10, MM/DD/YYYY otherwise. - -@item JDATEw: 5 <= iw,ow <= 40 -Julian date format. Input format: leader + julian + trailer. Output -format: YYDDD for @var{w} < 7, YYYYDDD otherwise. - -@item QYRw: 4 <= iw <= 40, 6 <= ow <= 40 -Quarter/year format. Input format: leader + quarter + q-delimiter + -year + trailer. Output format: @samp{Q Q YY}, where the first -@samp{Q} is one of the digits 1, 2, 3, 4, if @var{w} < 8, @code{Q Q -YYYY} otherwise. - -@item MOYRw: 6 <= iw,ow <= 40 -Month/year format. Input format: leader + month + date-delimiter + year -+ trailer. Output format: @samp{MMM YY} for @var{w} < 8, @samp{MMM -YYYY} otherwise. - -@item WKYRw: 6 <= iw <= 40, 8 <= ow <= 40 -Week/year format. Input format: leader + week + wk-delimiter + year + -trailer. Output format: @samp{WW WK YY} for @var{w} < 10, @samp{WW WK -YYYY} otherwise. - -@item DATETIMEw.d: 17 <= iw,ow <= 40 -Date and time format. Input format: leader + day + date-delimiter + -month + date-delimiter + year + time-delimiter + hour24 + time-delimiter -+ minute + opt-second. Output format: @samp{DD-MMM-YYYY HH:MM}. If -@var{w} > 19 then seconds @samp{:SS} is added. If @var{w} > 22 and -@var{d} > 0 then fractional seconds @samp{.SS} are added. - -@item TIMEw.d: 5 <= iw,ow <= 40 -Time format. Input format: leader + sign + spaces + hour + -time-delimiter + minute + opt-second. Output format: @samp{HH:MM}. -Seconds and fractional seconds are available with @var{w} of at least 8 -and 10, respectively. - -@item DTIMEw.d: 1 <= iw <= 40, 8 <= ow <= 40 -Time format with day count. Input format: leader + sign + spaces + -day-count + time-delimiter + hour + time-delimiter + minute + -opt-second. Output format: @samp{DD HH:MM}. Seconds and fractional -seconds are available with @var{w} of at least 8 and 10, respectively. - -@item WKDAYw: 2 <= iw,ow <= 40 -A weekday as a number between 1 and 7, where 1 is Sunday. Input format: -leader + weekday + trailer. Output format: as many characters, in all -capital letters, of the English name of the weekday as will fit in the -field width. - -@item MONTHw: 3 <= iw,ow <= 40 -A month as a number between 1 and 12, where 1 is January. Input format: -leader + month + trailer. Output format: as many character, in all -capital letters, of the English name of the month as will fit in the -field width. -@end table +The WKDAY and MONTH formats provide input and output for the names of +weekdays and months, respectively. -There are only two formats that may be used with string variables: +On output, these formats convert a number between 1 and 7, for WKDAY, or +between 1 and 12, for MONTH, into the English name of a day or month, +respectively. If the name is longer than the field, it is trimmed to +fit. If the name is shorter than the field, it is padded on the right +with spaces. Values outside the valid range, and the system-missing +value, are output as all spaces. -@table @asis -@item Aw: 1 <= iw <= 255, 1 <= ow <= 254 -The entire field is treated as a string value. +On input, English weekday or month names (in uppercase or lowercase) are +converted back to their corresponding numbers. Weekday and month names +may be abbreviated to their first 2 or 3 letters, respectively. -@item AHEXw @result{} A: 2 <= iw <= 254; 2 <= ow <= 510 -The field is composed of characters in a string encoded as textual hex -digit pairs. +The field width may range from 2 to 40, for WKDAY, or from 3 to 40, for +MONTH. No decimal places are allowed. -The default output @var{w} is half the input @var{w}. -@end table +The default output format is the same as the input format. + +@node String Formats +@subsubsection String Formats + +The A and AHEX formats are the only ones that may be assigned to string +variables. Neither format allows any decimal places. + +In A format, the entire field is treated as a string value. The field +width may range from 1 to 32,767, the maximum string width. The default +output format is the same as the input format. + +In AHEX format, the field is composed of characters in a string encoded +as hex digit pairs. On output, hex digits are output in uppercase; on +input, uppercase and lowercase are both accepted. The default output +format is A format with half the input width. -@node Scratch Variables, , Input/Output Formats, Variables +@node Scratch Variables, , Input and Output Formats, Variables @subsection Scratch Variables Most of the time, variables don't retain their values between cases. diff --git a/doc/transformation.texi b/doc/transformation.texi index 327f6739..d8b08a45 100644 --- a/doc/transformation.texi +++ b/doc/transformation.texi @@ -287,7 +287,7 @@ one or more @dfn{test} variables for each case. The target variable values are always nonnegative integers. They are never missing. The target variable is assigned an F8.2 output format. -@xref{Input/Output Formats}. Any variables, including long and short +@xref{Input and Output Formats}. Any variables, including long and short string variables, may be test variables. User-missing values of test variables are treated just like any other diff --git a/doc/utilities.texi b/doc/utilities.texi index 54ae7b3b..31966849 100644 --- a/doc/utilities.texi +++ b/doc/utilities.texi @@ -88,6 +88,8 @@ DISPLAY FILE LABEL. active file, if any. @xref{FILE LABEL}. +This command is a PSPP extension. + @node DROP DOCUMENTS, ECHO, DISPLAY FILE LABEL, Utilities @section DROP DOCUMENTS @vindex DROP DOCUMENTS @@ -232,6 +234,8 @@ SET /DECIMAL=@{DOT,COMMA@} /FORMAT=fmt_spec /EPOCH=@{AUTOMATIC,year@} + /RIB=@{NATIVE,MSBFIRST,LSBFIRST,VAX@} + /RRB=@{NATIVE,ISL,ISB,IDL,IDB,VF,VD,VG,ZS,ZL@} (program input) /ENDCMD='.' @@ -258,6 +262,8 @@ SET /CC@{A,B,C,D,E@}=@{'npre,pre,suf,nsuf','npre.pre.suf.nsuf'@} /DECIMAL=@{DOT,COMMA@} /FORMAT=fmt_spec + /WIB=@{NATIVE,MSBFIRST,LSBFIRST,VAX@} + /WRB=@{NATIVE,ISL,ISB,IDL,IDB,VF,VD,VG,ZS,ZL@} (output routing) /ECHO=@{ON,OFF@} @@ -320,22 +326,86 @@ system-missing value to be assigned to null items. This is the default. Any real value may be assigned. @item DECIMAL +@anchor{SET DECIMAL} The default DOT setting causes the decimal point character to be -@samp{.}. A setting of COMMA causes the decimal point character to be -@samp{,}. +@samp{.} and the grouping character to be @samp{,}. A setting of COMMA +causes the decimal point character to be @samp{,} and the grouping +character to be @samp{.}. @item FORMAT Allows the default numeric input/output format to be specified. The -default is F8.2. @xref{Input/Output Formats}. +default is F8.2. @xref{Input and Output Formats}. @item EPOCH @anchor{SET EPOCH} Specifies the range of years used when a 2-digit year is read from a data file or used in a date construction expression (@pxref{Date -Construction}). If a 4-digit year is specified, then 2-digit years -are interpreted starting from that year, known as the epoch. If -AUTOMATIC (the default) is specified, then the epoch begins 69 years -before the current date. +Construction}). If a 4-digit year is specified for the epoch, then +2-digit years are interpreted starting from that year, known as the +epoch. If AUTOMATIC (the default) is specified, then the epoch begins +69 years before the current date. + +@item RIB +@anchor{SET RIB} + +PSPP extension to set the byte ordering (endianness) used for reading +data in IB or PIB format (@pxref{Binary and Hexadecimal Numeric +Formats}). In MSBFIRST ordering, the most-significant byte appears at +the left end of a IB or PIB field. In LSBFIRST ordering, the +least-significant byte appears at the left end. VAX ordering is like +MSBFIRST, except that each pair of bytes is in reverse order. NATIVE, +the default, is equivalent to MSBFIRST or LSBFIRST depending on the +native format of the machine running PSPP. + +@item RRB +@anchor{SET RRB} + +PSPP extension to set the floating-point format used for reading data in +RB format (@pxref{Binary and Hexadecimal Numeric Formats}). The +possibilities are: + +@table @asis +@item NATIVE +The native format of the machine running PSPP. Equivalent to either IDL +or IDB. + +@item ISL +32-bit IEEE 754 single-precision floating point, in little-endian byte +order. + +@item ISB +32-bit IEEE 754 single-precision floating point, in big-endian byte +order. + +@item IDL +64-bit IEEE 754 double-precision floating point, in little-endian byte +order. + +@item IDB +64-bit IEEE 754 double-precision floating point, in big-endian byte +order. + +@item VF +32-bit VAX F format, in VAX-endian byte order. + +@item VD +64-bit VAX D format, in VAX-endian byte order. + +@item VG +64-bit VAX G format, in VAX-endian byte order. + +@item ZS +32-bit IBM Z architecture short format hexadecimal floating point, in +big-endian byte order. + +@item ZL +64-bit IBM Z architecture long format hexadecimal floating point, in +big-endian byte order. + +Z architecture also supports IEEE 754 floating point. The ZS and ZL +formats are only for use with very old input files. +@end table +The default is NATIVE. @end table Program input subcommands affect the way that programs are parsed when @@ -408,18 +478,10 @@ subcommands are @itemx CCC @itemx CCD @itemx CCE -Set up custom currency formats. The argument is a string which must -contain exactly three commas or exactly three periods. If commas, then -the grouping character for the currency format is @samp{,}, and the -decimal point character is @samp{.}; if periods, then the situation is -reversed. - -The commas or periods divide the string into four fields, which are, in -order, the negative prefix, prefix, suffix, and negative suffix. When a -value is formatted using the custom currency format, the prefix precedes -the value formatted and the suffix follows it. In addition, if the -value is negative, the negative prefix precedes the prefix and the -negative suffix follows the suffix. +@anchor{CCx Settings} + +Set up custom currency formats. @xref{Custom Currency Formats}, for +details. @item DECIMAL The default DOT setting causes the decimal point character to be @@ -428,7 +490,26 @@ The default DOT setting causes the decimal point character to be @item FORMAT Allows the default numeric input/output format to be specified. The -default is F8.2. @xref{Input/Output Formats}. +default is F8.2. @xref{Input and Output Formats}. + +@item WIB +@anchor{SET WIB} + +PSPP extension to set the byte ordering (endianness) used for writing +data in IB or PIB format (@pxref{Binary and Hexadecimal Numeric +Formats}). In MSBFIRST ordering, the most-significant byte appears at +the left end of a IB or PIB field. In LSBFIRST ordering, the +least-significant byte appears at the left end. VAX ordering is like +MSBFIRST, except that each pair of bytes is in reverse order. NATIVE, +the default, is equivalent to MSBFIRST or LSBFIRST depending on the +native format of the machine running PSPP. + +@item WRB +@anchor{SET WRB} + +PSPP extension to set the floating-point format used for writing data in +RB format (@pxref{Binary and Hexadecimal Numeric Formats}). The choices +are the same as SET RIB. The default is NATIVE. @end table Output routing subcommands affect where the output of transformations diff --git a/doc/variables.texi b/doc/variables.texi index 525c7094..91b07112 100644 --- a/doc/variables.texi +++ b/doc/variables.texi @@ -101,7 +101,7 @@ FORMATS var_list (fmt_spec). @cmd{FORMATS} set both print and write formats for the specified numeric variables to the specified format specification. -@xref{Input/Output Formats}. +@xref{Input and Output Formats}. Specify a list of variables followed by a format specification in parentheses. The print and write formats of the specified variables @@ -256,7 +256,7 @@ setting their output formats. Specify a slash (@samp{/}), followed by the names of the new numeric variables. If you wish to set their output formats, follow their names -by an output format specification in parentheses (@pxref{Input/Output +by an output format specification in parentheses (@pxref{Input and Output Formats}); otherwise, the default is F8.2. Variables created with @cmd{NUMERIC} are initialized to the @@ -333,7 +333,7 @@ transformations. Specify a slash (@samp{/}), followed by the names of the string variables to create and the desired output format specification in -parentheses (@pxref{Input/Output Formats}). Variable widths are +parentheses (@pxref{Input and Output Formats}). Variable widths are implicitly derived from the specified output formats. Created variables are initialized to spaces. diff --git a/src/data/ChangeLog b/src/data/ChangeLog index 60076a0f..4be64ea9 100644 --- a/src/data/ChangeLog +++ b/src/data/ChangeLog @@ -1,3 +1,27 @@ +Sat Nov 4 15:59:56 2006 Ben Pfaff + + * calendar.c (calendar_offset_to_gregorian) Also return the + year-of-day. Change callers to new interface. + + * data-out.c: Completely rewrite internals to conform to SPSS + output formats as completely as possible. + (data_out) Change interface to put input parameters before output + parameters, for consistency with the style I now prefer. Update + all callers. + (data_out_get_integer_format) New public function. + (data_out_set_integer_format) New public function. + (data_out_get_float_format) New public function. + (data_out_set_float_format) New public function. + + * data-out.h: New file. Move prototype for data_out here, from + format.h. + + * format.c: (fmt_step_width) Use equality comparison instead of + bitwise and, for clarity. + (fmt_is_string) Ditto. + (fmt_input_to_output) Fix categories that are translated to F + format. + Sun Nov 5 08:29:34 WST 2006 John Darrington * casefilter.c casefilter.h (new files), casefile.c casefile.h diff --git a/src/data/calendar.c b/src/data/calendar.c index 0a6498dd..3a38f126 100644 --- a/src/data/calendar.c +++ b/src/data/calendar.c @@ -153,14 +153,15 @@ calendar_offset_to_year (int ofs) } /* Takes a count of days from 14 Oct 1582 and translates it into - a Gregorian calendar date in (*Y,*M,*D). Dates both before - and after the epoch are supported. */ + a Gregorian calendar date in (*Y,*M,*D). Also stores the + year-relative day number into *YD. Dates both before and + after the epoch are supported. */ void -calendar_offset_to_gregorian (int ofs, int *y, int *m, int *d) +calendar_offset_to_gregorian (int ofs, int *y, int *m, int *d, int *yd) { int year = *y = calendar_offset_to_year (ofs); int january1 = raw_gregorian_to_offset (year, 1, 1); - int yday = ofs - january1 + 1; + int yday = *yd = ofs - january1 + 1; int march1 = january1 + cum_month_days (year, 3); int correction = ofs < march1 ? 0 : (is_leap_year (year) ? 1 : 2); int month = *m = (12 * (yday - 1 + correction) + 373) / 367; @@ -195,8 +196,8 @@ calendar_offset_to_wday (int ofs) int calendar_offset_to_month (int ofs) { - int y, m, d; - calendar_offset_to_gregorian (ofs, &y, &m, &d); + int y, m, d, yd; + calendar_offset_to_gregorian (ofs, &y, &m, &d, &yd); return m; } @@ -205,7 +206,7 @@ calendar_offset_to_month (int ofs) int calendar_offset_to_mday (int ofs) { - int y, m, d; - calendar_offset_to_gregorian (ofs, &y, &m, &d); + int y, m, d, yd; + calendar_offset_to_gregorian (ofs, &y, &m, &d, &yd); return d; } diff --git a/src/data/calendar.h b/src/data/calendar.h index 1a70592b..f46e71fe 100644 --- a/src/data/calendar.h +++ b/src/data/calendar.h @@ -5,7 +5,7 @@ typedef void calendar_error_func (void *aux, const char *, ...); double calendar_gregorian_to_offset (int y, int m, int d, calendar_error_func *, void *aux); -void calendar_offset_to_gregorian (int ofs, int *y, int *m, int *d); +void calendar_offset_to_gregorian (int ofs, int *y, int *m, int *d, int *yd); int calendar_offset_to_year (int ofs); int calendar_offset_to_month (int ofs); int calendar_offset_to_mday (int ofs); diff --git a/src/data/data-out.c b/src/data/data-out.c index 74f97188..ffc79ecc 100644 --- a/src/data/data-out.c +++ b/src/data/data-out.c @@ -18,1215 +18,941 @@ 02110-1301, USA. */ #include -#include + +#include "data-out.h" + #include -#include #include +#include +#include #include #include + #include "calendar.h" -#include -#include #include "format.h" +#include "settings.h" +#include "variable.h" + +#include +#include +#include #include +#include #include #include -#include "settings.h" #include -#include "variable.h" + +#include "minmax.h" #include "gettext.h" #define _(msgid) gettext (msgid) -/* Public functions. */ - -typedef int numeric_converter (char *, const struct fmt_spec *, double); -static numeric_converter convert_F, convert_N, convert_E, convert_F_plus; -static numeric_converter convert_Z, convert_IB, convert_P, convert_PIB; -static numeric_converter convert_PIBHEX, convert_PK, convert_RB; -static numeric_converter convert_RBHEX, convert_CCx, convert_date; -static numeric_converter convert_time, convert_WKDAY, convert_MONTH; - -static numeric_converter try_F, convert_infinite; - -typedef int string_converter (char *, const struct fmt_spec *, const char *); -static string_converter convert_A, convert_AHEX; +/* A representation of a number that can be quickly rounded to + any desired number of decimal places (up to a specified + maximum). */ +struct rounder + { + char string[64]; /* Magnitude of number with excess precision. */ + int integer_digits; /* Number of digits before decimal point. */ + int leading_nines; /* Number of `9's or `.'s at start of string. */ + int leading_zeros; /* Number of `0's or `.'s at start of string. */ + bool negative; /* Is the number negative? */ + }; -/* Converts binary value V into printable form in the exactly - FP->W character in buffer S according to format specification - FP. No null terminator is appended to the buffer. */ -bool -data_out (char *s, const struct fmt_spec *fp, const union value *v) +static void rounder_init (struct rounder *, double number, int max_decimals); +static int rounder_width (const struct rounder *, int decimals, + int *integer_digits, bool *negative); +static void rounder_format (const struct rounder *, int decimals, + char *output); + +/* Format of integers in output (SET WIB). */ +static enum integer_format output_integer_format = INTEGER_NATIVE; + +/* Format of reals in output (SET WRB). */ +static enum float_format output_float_format = FLOAT_NATIVE_DOUBLE; + +typedef void data_out_converter_func (const union value *, + const struct fmt_spec *, + char *); +#define FMT(NAME, METHOD, IMIN, OMIN, IO, CATEGORY) \ + static data_out_converter_func output_##METHOD; +#include "format.def" + +static bool output_decimal (const struct rounder *, const struct fmt_spec *, + bool require_affixes, char *); +static bool output_scientific (double, const struct fmt_spec *, + bool require_affixes, char *); + +static double power10 (int) PURE_FUNCTION; +static double power256 (int) PURE_FUNCTION; + +static void output_infinite (double, const struct fmt_spec *, char *); +static void output_missing (const struct fmt_spec *, char *); +static void output_overflow (const struct fmt_spec *, char *); +static bool output_bcd_integer (double, int digits, char *); +static void output_binary_integer (uint64_t, int bytes, enum integer_format, + char *); +static void output_hex (const void *, size_t bytes, char *); + +/* Converts the INPUT value into printable form in the exactly + FORMAT->W characters in OUTPUT according to format + specification FORMAT. No null terminator is appended to the + buffer. */ +void +data_out (const union value *input, const struct fmt_spec *format, + char *output) { - int ok; - - assert (fmt_check_output (fp)); - if (fmt_is_numeric (fp->type)) + static data_out_converter_func *const converters[FMT_NUMBER_OF_FORMATS] = { - enum fmt_category category = fmt_get_category (fp->type); - double number = v->f; - - /* Handle SYSMIS turning into blanks. */ - if (!(category & (FMT_CAT_CUSTOM | FMT_CAT_BINARY | FMT_CAT_HEXADECIMAL)) - && number == SYSMIS) - { - memset (s, ' ', fp->w); - s[fp->w - fp->d - 1] = '.'; - return true; - } - - /* Handle decimal shift. */ - if ((category & (FMT_CAT_LEGACY | FMT_CAT_BINARY)) - && number != SYSMIS - && fp->d) - number *= pow (10.0, fp->d); - - switch (fp->type) - { - case FMT_F: - ok = convert_F (s, fp, number); - break; - - case FMT_N: - ok = convert_N (s, fp, number); - break; - - case FMT_E: - ok = convert_E (s, fp, number); - break; - - case FMT_COMMA: case FMT_DOT: case FMT_DOLLAR: case FMT_PCT: - ok = convert_F_plus (s, fp, number); - break; - - case FMT_Z: - ok = convert_Z (s, fp, number); - break; - - case FMT_A: - NOT_REACHED (); - - case FMT_AHEX: - NOT_REACHED (); - - case FMT_IB: - ok = convert_IB (s, fp, number); - break; - - case FMT_P: - ok = convert_P (s, fp, number); - break; - - case FMT_PIB: - ok = convert_PIB (s, fp, number); - break; - - case FMT_PIBHEX: - ok = convert_PIBHEX (s, fp, number); - break; - - case FMT_PK: - ok = convert_PK (s, fp, number); - break; +#define FMT(NAME, METHOD, IMIN, OMIN, IO, CATEGORY) output_##METHOD, +#include "format.def" + }; - case FMT_RB: - ok = convert_RB (s, fp, number); - break; + assert (fmt_check_output (format)); - case FMT_RBHEX: - ok = convert_RBHEX (s, fp, number); - break; + converters[format->type] (input, format, output); +} - case FMT_CCA: case FMT_CCB: case FMT_CCC: case FMT_CCD: case FMT_CCE: - ok = convert_CCx (s, fp, number); - break; +/* Returns the current output integer format. */ +enum integer_format +data_out_get_integer_format (void) +{ + return output_integer_format; +} - case FMT_DATE: case FMT_EDATE: case FMT_SDATE: case FMT_ADATE: - case FMT_JDATE: case FMT_QYR: case FMT_MOYR: case FMT_WKYR: - case FMT_DATETIME: - ok = convert_date (s, fp, number); - break; +/* Sets the output integer format to INTEGER_FORMAT. */ +void +data_out_set_integer_format (enum integer_format integer_format) +{ + output_integer_format = integer_format; +} - case FMT_TIME: case FMT_DTIME: - ok = convert_time (s, fp, number); - break; +/* Returns the current output float format. */ +enum float_format +data_out_get_float_format (void) +{ + return output_float_format; +} - case FMT_WKDAY: - ok = convert_WKDAY (s, fp, number); - break; +/* Sets the output float format to FLOAT_FORMAT. */ +void +data_out_set_float_format (enum float_format float_format) +{ + output_float_format = float_format; +} + +/* Main conversion functions. */ - case FMT_MONTH: - ok = convert_MONTH (s, fp, number); - break; +/* Outputs F, COMMA, DOT, DOLLAR, PCT, E, CCA, CCB, CCC, CCD, and + CCE formats. */ +static void +output_number (const union value *input, const struct fmt_spec *format, + char *output) +{ + double number = input->f; - default: - NOT_REACHED (); - } - } + if (number == SYSMIS) + output_missing (format, output); + else if (!isfinite (number)) + output_infinite (number, format, output); else { - /* String formatting. */ - const char *string = v->s; - - switch (fp->type) + if (format->type != FMT_E && fabs (number) < 1.5 * power10 (format->w)) { - case FMT_A: - ok = convert_A (s, fp, string); - break; - - case FMT_AHEX: - ok = convert_AHEX (s, fp, string); - break; + struct rounder r; + rounder_init (&r, number, format->d); - default: - NOT_REACHED (); + if (output_decimal (&r, format, true, output) + || output_scientific (number, format, true, output) + || output_decimal (&r, format, false, output)) + return; } - } - - /* Error handling. */ - if (!ok) - strncpy (s, "ERROR", fp->w); - - return ok; -} - -/* Main conversion functions. */ - -static void insert_commas (char *dst, const char *src, - const struct fmt_spec *fp); -static int year4 (int year); -static int try_CCx (char *s, const struct fmt_spec *fp, double v); - -#if FLT_RADIX!=2 -#error Write your own floating-point output routines. -#endif - -/* Converts a number between 0 and 15 inclusive to a `hexit' - [0-9A-F]. */ -#define MAKE_HEXIT(X) ("0123456789ABCDEF"[X]) - -/* Table of powers of 10. */ -static const double power10[] = - { - 0, /* Not used. */ - 1e01, 1e02, 1e03, 1e04, 1e05, 1e06, 1e07, 1e08, 1e09, 1e10, - 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, - 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29, 1e30, - 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39, 1e40, - }; -/* Handles F format. */ -static int -convert_F (char *dst, const struct fmt_spec *fp, double number) -{ - if (!try_F (dst, fp, number)) - convert_E (dst, fp, number); - return 1; + if (!output_scientific (number, format, false, output)) + output_overflow (format, output); + } } -/* Handles N format. */ -static int -convert_N (char *dst, const struct fmt_spec *fp, double number) +/* Outputs N format. */ +static void +output_N (const union value *input, const struct fmt_spec *format, + char *output) { - double d = floor (number); - - if (d < 0 || d == SYSMIS) - { - msg (ME, _("The N output format cannot be used to output a " - "negative number or the system-missing value.")); - return 0; - } - - if (d < power10[fp->w]) + double number = input->f * power10 (format->d); + if (input->f == SYSMIS || number < 0) + output_missing (format, output); + else { char buf[128]; - sprintf (buf, "%0*.0f", fp->w, number); - memcpy (dst, buf, fp->w); + number = fabs (round (number)); + if (number < power10 (format->w) + && sprintf (buf, "%0*.0f", format->w, number) == format->w) + memcpy (output, buf, format->w); + else + output_overflow (format, output); } - else - memset (dst, '*', fp->w); - - return 1; } -/* Handles E format. Also operates as fallback for some other - formats. */ -static int -convert_E (char *dst, const struct fmt_spec *fp, double number) +/* Outputs Z format. */ +static void +output_Z (const union value *input, const struct fmt_spec *format, + char *output) { - /* Temporary buffer. */ + double number = input->f * power10 (format->d); char buf[128]; - - /* Ranged number of decimal places. */ - int d; - - if (!finite (number)) - return convert_infinite (dst, fp, number); - - /* Check that the format is wide enough. - Although PSPP generally checks this, convert_E() can be called as - a fallback from other formats which do not check. */ - if (fp->w < 6) - { - memset (dst, '*', fp->w); - return 1; - } - - /* Put decimal places in usable range. */ - d = min (fp->d, fp->w - 6); - if (number < 0) - d--; - if (d < 0) - d = 0; - sprintf (buf, "%*.*E", fp->w, d, number); - - /* What we do here is force the exponent part to have four - characters whenever possible. That is, 1.00E+99 is okay (`E+99') - but 1.00E+100 (`E+100') must be coerced to 1.00+100 (`+100'). On - the other hand, 1.00E1000 (`E+100') cannot be canonicalized. - Note that ANSI C guarantees at least two digits in the - exponent. */ - if (fabs (number) > 1e99) - { - /* Pointer to the `E' in buf. */ - char *cp; - - cp = strchr (buf, 'E'); - if (cp) - { - /* Exponent better not be bigger than an int. */ - int exp = atoi (cp + 1); - - if (abs (exp) > 99 && abs (exp) < 1000) - { - /* Shift everything left one place: 1.00e+100 -> 1.00+100. */ - cp[0] = cp[1]; - cp[1] = cp[2]; - cp[2] = cp[3]; - cp[3] = cp[4]; - } - else if (abs (exp) >= 1000) - memset (buf, '*', fp->w); - } - } - - /* The C locale always uses a period `.' as a decimal point. - Translate to comma if necessary. */ - if (fmt_decimal_char (fp->type) != '.') + if (input->f == SYSMIS) + output_missing (format, output); + else if (fabs (number) >= power10 (format->w) + || sprintf (buf, "%0*.0f", format->w, + fabs (round (number))) != format->w) + output_overflow (format, output); + else { - char *cp = strchr (buf, '.'); - if (cp) - *cp = fmt_decimal_char (fp->type); + if (number < 0 && strspn (buf, "0") < format->w) + { + char *p = &buf[format->w - 1]; + *p = "}JKLMNOPQR"[*p - '0']; + } + memcpy (output, buf, format->w); } - - memcpy (dst, buf, fp->w); - return 1; } -/* Handles COMMA, DOT, DOLLAR, and PCT formats. */ -static int -convert_F_plus (char *dst, const struct fmt_spec *fp, double number) +/* Outputs P format. */ +static void +output_P (const union value *input, const struct fmt_spec *format, + char *output) { - char buf[40]; - - if (try_F (buf, fp, number)) - insert_commas (dst, buf, fp); + if (output_bcd_integer (fabs (input->f * power10 (format->d)), + format->w * 2 - 1, output) + && input->f < 0.0) + output[format->w - 1] |= 0xd; else - convert_E (dst, fp, number); - - return 1; + output[format->w - 1] |= 0xf; } -static int -convert_Z (char *dst, const struct fmt_spec *fp, double number) +/* Outputs PK format. */ +static void +output_PK (const union value *input, const struct fmt_spec *format, + char *output) { - static bool warned = false; - - if (!warned) - { - msg (MW, - _("Quality of zoned decimal (Z) output format code is " - "suspect. Check your results. Report bugs to %s."), - PACKAGE_BUGREPORT); - warned = 1; - } + output_bcd_integer (input->f * power10 (format->d), format->w * 2, output); +} - if (number == SYSMIS) +/* Outputs IB format. */ +static void +output_IB (const union value *input, const struct fmt_spec *format, + char *output) +{ + double number = round (input->f * power10 (format->d)); + if (input->f == SYSMIS + || number >= power256 (format->w) / 2 - 1 + || number < -power256 (format->w) / 2) + memset (output, 0, format->w); + else { - msg (ME, _("The system-missing value cannot be output as a zoned " - "decimal number.")); - return 0; + uint64_t integer = fabs (number); + if (number < 0) + integer = -integer; + output_binary_integer (integer, format->w, output_integer_format, + output); } - - { - char buf[41]; - double d; - int i; - - d = fabs (floor (number)); - if (d >= power10[fp->w]) - { - msg (ME, _("Number %g too big to fit in field with format Z%d.%d."), - number, fp->w, fp->d); - return 0; - } - - sprintf (buf, "%*.0f", fp->w, number); - for (i = 0; i < fp->w; i++) - dst[i] = (buf[i] - '0') | 0xf0; - if (number < 0) - dst[fp->w - 1] &= 0xdf; - } - - return 1; } -static int -convert_A (char *dst, const struct fmt_spec *fp, const char *string) +/* Outputs PIB format. */ +static void +output_PIB (const union value *input, const struct fmt_spec *format, + char *output) { - memcpy(dst, string, fp->w); - return 1; + double number = round (input->f * power10 (format->d)); + if (input->f == SYSMIS + || number < 0 || number >= power256 (format->w)) + memset (output, 0, format->w); + else + output_binary_integer (number, format->w, output_integer_format, output); } -static int -convert_AHEX (char *dst, const struct fmt_spec *fp, const char *string) +/* Outputs PIBHEX format. */ +static void +output_PIBHEX (const union value *input, const struct fmt_spec *format, + char *output) { - int i; - - for (i = 0; i < fp->w / 2; i++) + double number = round (input->f); + if (input->f == SYSMIS) + output_missing (format, output); + else if (input->f < 0 || number >= power256 (format->w / 2)) + output_overflow (format, output); + else { - *dst++ = MAKE_HEXIT ((string[i]) >> 4); - *dst++ = MAKE_HEXIT ((string[i]) & 0xf); + char tmp[8]; + output_binary_integer (number, format->w / 2, INTEGER_MSB_FIRST, tmp); + output_hex (tmp, format->w / 2, output); } - - return 1; } -static int -convert_IB (char *dst, const struct fmt_spec *fp, double number) +/* Outputs RB format. */ +static void +output_RB (const union value *input, const struct fmt_spec *format, + char *output) { - /* Strategy: Basically the same as convert_PIBHEX() but with - base 256. Then negate the two's-complement result if number - is negative. */ - - /* Used for constructing the two's-complement result. */ - unsigned temp[8]; + double d = input->f; + memcpy (output, &d, format->w); +} - /* Fraction (mantissa). */ - double frac; +/* Outputs RBHEX format. */ +static void +output_RBHEX (const union value *input, const struct fmt_spec *format, + char *output) +{ + double d = input->f; + output_hex (&d, format->w / 2, output); +} - /* Exponent. */ - int exp; +/* Outputs DATE, ADATE, EDATE, JDATE, SDATE, QYR, MOYR, WKYR, + DATETIME, TIME, and DTIME formats. */ +static void +output_date (const union value *input, const struct fmt_spec *format, + char *output) +{ + double number = input->f; + double magnitude = fabs (number); + int year, month, day, yday; - /* Difference between exponent and (-8*fp->w-1). */ - int diff; + const char *template = fmt_date_template (format->type); + size_t template_width = strlen (template); + int excess_width = format->w - template_width; - /* Counter. */ - int i; + char tmp[64]; + char *p = tmp; - /* Make the exponent (-8*fp->w-1). */ - frac = frexp (fabs (number), &exp); - diff = exp - (-8 * fp->w - 1); - exp -= diff; - frac *= ldexp (1.0, diff); + assert (format->w >= template_width); + if (number == SYSMIS) + goto missing; - /* Extract each base-256 digit. */ - for (i = 0; i < fp->w; i++) + if (fmt_get_category (format->type) == FMT_CAT_DATE) { - modf (frac, &frac); - frac *= 256.0; - temp[i] = floor (frac); + if (number <= 0) + goto missing; + calendar_offset_to_gregorian (number / 60. / 60. / 24., + &year, &month, &day, &yday); } + else + year = month = day = yday = 0; - /* Perform two's-complement negation if number is negative. */ - if (number < 0) + while (*template != '\0') { - /* Perform NOT operation. */ - for (i = 0; i < fp->w; i++) - temp[i] = ~temp[i]; - /* Add 1 to the whole number. */ - for (i = fp->w - 1; i >= 0; i--) - { - temp[i]++; - if (temp[i]) - break; - } + int ch = *template; + int count = 1; + while (template[count] == ch) + count++; + template += count; + + switch (ch) + { + case 'd': + if (count < 3) + p += sprintf (p, "%02d", day); + else + p += sprintf (p, "%03d", yday); + break; + case 'm': + if (count < 3) + p += sprintf (p, "%02d", month); + else + { + static const char *months[12] = + { + "JAN", "FEB", "MAR", "APR", "MAY", "JUN", + "JUL", "AUG", "SEP", "OCT", "NOV", "DEC", + }; + p = stpcpy (p, months[month - 1]); + } + break; + case 'y': + if (count >= 4 || excess_width >= 2) + { + if (year <= 9999) + p += sprintf (p, "%04d", year); + else if (format->type == FMT_DATETIME) + p = stpcpy (p, "****"); + else + goto overflow; + } + else + { + int offset = year - get_epoch (); + if (offset < 0 || offset > 99) + goto overflow; + p += sprintf (p, "%02d", abs (year) % 100); + } + break; + case 'q': + p += sprintf (p, "%d", (month - 1) / 3 + 1); + break; + case 'w': + p += sprintf (p, "%2d", (yday - 1) / 7 + 1); + break; + case 'D': + if (number < 0) + *p++ = '-'; + p += sprintf (p, "%.0f", floor (magnitude / 60. / 60. / 24.)); + break; + case 'h': + if (number < 0) + *p++ = '-'; + p += sprintf (p, "%.0f", floor (magnitude / 60. / 60.)); + break; + case 'H': + p += sprintf (p, "%02d", + (int) fmod (floor (magnitude / 60. / 60.), 24.)); + break; + case 'M': + p += sprintf (p, "%02d", + (int) fmod (floor (magnitude / 60.), 60.)); + excess_width = format->w - (p - tmp); + if (excess_width < 0) + goto overflow; + if (excess_width == 3 || excess_width == 4 + || (excess_width >= 5 && format->d == 0)) + p += sprintf (p, ":%02d", (int) fmod (magnitude, 60.)); + else if (excess_width >= 5) + { + int d = MIN (format->d, excess_width - 4); + int w = d + 3; + sprintf (p, ":%0*.*f", w, d, fmod (magnitude, 60.)); + if (fmt_decimal_char (FMT_F) != '.') + { + char *cp = strchr (p, '.'); + if (cp != NULL) + *cp = fmt_decimal_char (FMT_F); + } + p += strlen (p); + } + break; + default: + assert (count == 1); + *p++ = ch; + break; + } } - memcpy (dst, temp, fp->w); -#ifndef WORDS_BIGENDIAN - buf_reverse (dst, fp->w); -#endif - - return 1; -} - -static int -convert_P (char *dst, const struct fmt_spec *fp, double number) -{ - /* Buffer for fp->w*2-1 characters + a decimal point if library is - not quite compliant + a null. */ - char buf[17]; - - /* Counter. */ - int i; - - /* Main extraction. */ - sprintf (buf, "%0*.0f", fp->w * 2 - 1, floor (fabs (number))); - for (i = 0; i < fp->w; i++) - ((unsigned char *) dst)[i] - = ((buf[i * 2] - '0') << 4) + buf[i * 2 + 1] - '0'; + buf_copy_lpad (output, format->w, tmp, p - tmp); + return; - /* Set sign. */ - dst[fp->w - 1] &= 0xf0; - if (number >= 0.0) - dst[fp->w - 1] |= 0xf; - else - dst[fp->w - 1] |= 0xd; + overflow: + output_overflow (format, output); + return; - return 1; + missing: + output_missing (format, output); + return; } -static int -convert_PIB (char *dst, const struct fmt_spec *fp, double number) +/* Outputs WKDAY format. */ +static void +output_WKDAY (const union value *input, const struct fmt_spec *format, + char *output) { - /* Strategy: Basically the same as convert_IB(). */ - - /* Fraction (mantissa). */ - double frac; - - /* Exponent. */ - int exp; - - /* Difference between exponent and (-8*fp->w). */ - int diff; - - /* Counter. */ - int i; - - /* Make the exponent (-8*fp->w). */ - frac = frexp (fabs (number), &exp); - diff = exp - (-8 * fp->w); - exp -= diff; - frac *= ldexp (1.0, diff); + static const char *weekdays[7] = + { + "SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY", + "THURSDAY", "FRIDAY", "SATURDAY", + }; - /* Extract each base-256 digit. */ - for (i = 0; i < fp->w; i++) + if (input->f >= 1 && input->f < 8) + buf_copy_str_rpad (output, format->w, weekdays[(int) input->f - 1]); + else { - modf (frac, &frac); - frac *= 256.0; - ((unsigned char *) dst)[i] = floor (frac); + if (input->f != SYSMIS) + msg (ME, _("Weekday number %f is not between 1 and 7."), input->f); + output_missing (format, output); } -#ifndef WORDS_BIGENDIAN - buf_reverse (dst, fp->w); -#endif - - return 1; } -static int -convert_PIBHEX (char *dst, const struct fmt_spec *fp, double number) +/* Outputs MONTH format. */ +static void +output_MONTH (const union value *input, const struct fmt_spec *format, + char *output) { - /* Strategy: Use frexp() to create a normalized result (but mostly - to find the base-2 exponent), then change the base-2 exponent to - (-4*fp->w) using multiplication and division by powers of two. - Extract each hexit by multiplying by 16. */ - - /* Fraction (mantissa). */ - double frac; - - /* Exponent. */ - int exp; - - /* Difference between exponent and (-4*fp->w). */ - int diff; - - /* Counter. */ - int i; - - /* Make the exponent (-4*fp->w). */ - frac = frexp (fabs (number), &exp); - diff = exp - (-4 * fp->w); - exp -= diff; - frac *= ldexp (1.0, diff); + static const char *months[12] = + { + "JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE", + "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER", + }; - /* Extract each hexit. */ - for (i = 0; i < fp->w; i++) + if (input->f >= 1 && input->f < 13) + buf_copy_str_rpad (output, format->w, months[(int) input->f - 1]); + else { - modf (frac, &frac); - frac *= 16.0; - *dst++ = MAKE_HEXIT ((int) floor (frac)); + if (input->f != SYSMIS) + msg (ME, _("Month number %f is not between 1 and 12."), input->f); + output_missing (format, output); } - - return 1; } -static int -convert_PK (char *dst, const struct fmt_spec *fp, double number) +/* Outputs A format. */ +static void +output_A (const union value *input, const struct fmt_spec *format, + char *output) { - /* Buffer for fp->w*2 characters + a decimal point if library is not - quite compliant + a null. */ - char buf[18]; - - /* Counter. */ - int i; - - /* Main extraction. */ - sprintf (buf, "%0*.0f", fp->w * 2, floor (fabs (number))); - - for (i = 0; i < fp->w; i++) - ((unsigned char *) dst)[i] - = ((buf[i * 2] - '0') << 4) + buf[i * 2 + 1] - '0'; - - return 1; + memcpy (output, input->s, format->w); } -static int -convert_RB (char *dst, const struct fmt_spec *fp, double number) +/* Outputs AHEX format. */ +static void +output_AHEX (const union value *input, const struct fmt_spec *format, + char *output) { - union - { - double d; - char c[8]; - } - u; - - u.d = number; - memcpy (dst, u.c, fp->w); - - return 1; + output_hex (input->s, format->w, output); } + +/* Decimal and scientific formatting. */ -static int -convert_RBHEX (char *dst, const struct fmt_spec *fp, double number) +/* If REQUEST plus the current *WIDTH fits within MAX_WIDTH, + increments *WIDTH by REQUEST and return true. + Otherwise returns false without changing *WIDTH. */ +static bool +allocate_space (int request, int max_width, int *width) { - union - { - double d; - char c[8]; - } - u; - - int i; - - u.d = number; - for (i = 0; i < fp->w / 2; i++) + assert (*width <= max_width); + if (request + *width <= max_width) { - *dst++ = MAKE_HEXIT (u.c[i] >> 4); - *dst++ = MAKE_HEXIT (u.c[i] & 15); + *width += request; + return true; } - - return 1; -} - -static int -convert_CCx (char *dst, const struct fmt_spec *fp, double number) -{ - if (try_CCx (dst, fp, number)) - return 1; else - { - struct fmt_spec f; - - f.type = FMT_COMMA; - f.w = fp->w; - f.d = fp->d; - - return convert_F_plus (dst, &f, number); - } + return false; } -static int -convert_date (char *dst, const struct fmt_spec *fp, double number) +/* Tries to compose the number represented by R, in the style of + FORMAT, into OUTPUT. Returns true if successful, false on + failure, which occurs if FORMAT's width is too narrow. If + REQUIRE_AFFIXES is true, then the prefix and suffix specified + by FORMAT's style must be included; otherwise, they may be + omitted to make the number fit. */ +static bool +output_decimal (const struct rounder *r, const struct fmt_spec *format, + bool require_affixes, char *output) { - static const char *months[12] = - { - "JAN", "FEB", "MAR", "APR", "MAY", "JUN", - "JUL", "AUG", "SEP", "OCT", "NOV", "DEC", - }; + const struct fmt_number_style *style = fmt_get_style (format->type); + int decimals; - char buf[64] = {0}; - int ofs = number / 86400.; - int month, day, year; - - if (ofs < 1) - return 0; - - calendar_offset_to_gregorian (ofs, &year, &month, &day); - switch (fp->type) + for (decimals = format->d; decimals >= 0; decimals--) { - case FMT_DATE: - if (fp->w >= 11) - sprintf (buf, "%02d-%s-%04d", day, months[month - 1], year); - else - sprintf (buf, "%02d-%s-%02d", day, months[month - 1], year % 100); - break; - case FMT_EDATE: - if (fp->w >= 10) - sprintf (buf, "%02d.%02d.%04d", day, month, year); - else - sprintf (buf, "%02d.%02d.%02d", day, month, year % 100); - break; - case FMT_SDATE: - if (fp->w >= 10) - sprintf (buf, "%04d/%02d/%02d", year, month, day); - else - sprintf (buf, "%02d/%02d/%02d", year % 100, month, day); - break; - case FMT_ADATE: - if (fp->w >= 10) - sprintf (buf, "%02d/%02d/%04d", month, day, year); - else - sprintf (buf, "%02d/%02d/%02d", month, day, year % 100); - break; - case FMT_JDATE: - { - int yday = calendar_offset_to_yday (ofs); - - if (fp->w < 7) - sprintf (buf, "%02d%03d", year % 100, yday); - else if (year4 (year)) - sprintf (buf, "%04d%03d", year, yday); - else - break; - } - case FMT_QYR: - if (fp->w >= 8) - sprintf (buf, "%d Q% 04d", (month - 1) / 3 + 1, year); + /* Formatted version of magnitude of NUMBER. */ + char magnitude[64]; + + /* Number of digits in MAGNITUDE's integer and fractional parts. */ + int integer_digits; + + /* Amount of space within the field width already claimed. + Initially this is the width of MAGNITUDE, then it is reduced + in stages as space is allocated to prefixes and suffixes and + grouping characters. */ + int width; + + /* Include various decorations? */ + bool add_neg_prefix; + bool add_affixes; + bool add_grouping; + + /* Position in output. */ + char *p; + + /* Make sure there's room for the number's magnitude, plus + the negative suffix, plus (if negative) the negative + prefix. */ + width = rounder_width (r, decimals, &integer_digits, &add_neg_prefix); + width += ss_length (style->neg_suffix); + if (add_neg_prefix) + width += ss_length (style->neg_prefix); + if (width > format->w) + continue; + + /* If there's room for the prefix and suffix, allocate + space. If the affixes are required, but there's no + space, give up. */ + add_affixes = allocate_space (fmt_affix_width (style), + format->w, &width); + if (!add_affixes && require_affixes) + continue; + + /* Check whether we should include grouping characters. + We need room for a complete set or we don't insert any at all. + We don't include grouping characters if decimal places were + requested but they were all dropped. */ + add_grouping = (style->grouping != 0 + && integer_digits > 3 + && (format->d == 0 || decimals > 0) + && allocate_space ((integer_digits - 1) / 3, + format->w, &width)); + + /* Format the number's magnitude. */ + rounder_format (r, decimals, magnitude); + + /* Assemble number. */ + p = output; + if (format->w > width) + p = mempset (p, ' ', format->w - width); + if (add_neg_prefix) + p = mempcpy (p, ss_data (style->neg_prefix), + ss_length (style->neg_prefix)); + if (add_affixes) + p = mempcpy (p, ss_data (style->prefix), ss_length (style->prefix)); + if (!add_grouping) + p = mempcpy (p, magnitude, integer_digits); else - sprintf (buf, "%d Q% 02d", (month - 1) / 3 + 1, year % 100); - break; - case FMT_MOYR: - if (fp->w >= 8) - sprintf (buf, "%s% 04d", months[month - 1], year); + { + int i; + for (i = 0; i < integer_digits; i++) + { + if (i > 0 && (integer_digits - i) % 3 == 0) + *p++ = style->grouping; + *p++ = magnitude[i]; + } + } + if (decimals > 0) + { + *p++ = style->decimal; + p = mempcpy (p, &magnitude[integer_digits + 1], decimals); + } + if (add_affixes) + p = mempcpy (p, ss_data (style->suffix), ss_length (style->suffix)); + if (add_neg_prefix) + p = mempcpy (p, ss_data (style->neg_suffix), + ss_length (style->neg_suffix)); else - sprintf (buf, "%s% 02d", months[month - 1], year % 100); - break; - case FMT_WKYR: - { - int yday = calendar_offset_to_yday (ofs); - - if (fp->w >= 10) - sprintf (buf, "%02d WK% 04d", (yday - 1) / 7 + 1, year); - else - sprintf (buf, "%02d WK% 02d", (yday - 1) / 7 + 1, year % 100); - } - break; - case FMT_DATETIME: - { - char *cp; - - cp = spprintf (buf, "%02d-%s-%04d %02d:%02d", - day, months[month - 1], year, - (int) fmod (floor (number / 60. / 60.), 24.), - (int) fmod (floor (number / 60.), 60.)); - if (fp->w >= 20) - { - int w, d; - - if (fp->w >= 22 && fp->d > 0) - { - d = min (fp->d, fp->w - 21); - w = 3 + d; - } - else - { - w = 2; - d = 0; - } - - cp = spprintf (cp, ":%0*.*f", w, d, fmod (number, 60.)); - } - } - break; - default: - NOT_REACHED (); - } + p = mempset (p, ' ', ss_length (style->neg_suffix)); + assert (p == output + format->w); - if (buf[0] == 0) - return 0; - buf_copy_str_rpad (dst, fp->w, buf); - return 1; + return true; + } + return false; } -static int -convert_time (char *dst, const struct fmt_spec *fp, double number) +/* Formats NUMBER into OUTPUT in scientific notation according to + the style of the format specified in FORMAT. */ +static bool +output_scientific (double number, const struct fmt_spec *format, + bool require_affixes, char *output) { - char temp_buf[40]; - char *cp; - - double time; + const struct fmt_number_style *style = fmt_get_style (format->type); int width; + int fraction_width; + bool add_affixes; + char buf[64], *p; - if (fabs (number) > 1e20) - { - msg (ME, _("Time value %g too large in magnitude to convert to " - "alphanumeric time."), number); - return 0; - } + /* Allocate minimum required space. */ + width = 6 + ss_length (style->neg_suffix); + if (number < 0) + width += ss_length (style->neg_prefix); + if (width > format->w) + return false; + + /* Check for room for prefix and suffix. */ + add_affixes = allocate_space (fmt_affix_width (style), format->w, &width); + if (require_affixes && !add_affixes) + return false; + + /* Figure out number of characters we can use for the fraction, + if any. (If that turns out to be 1, then we'll output a + decimal point without any digits following; that's what the + # flag does in the call to sprintf, below.) */ + fraction_width = MIN (MIN (format->d + 1, format->w - width), 16); + if (format->type != FMT_E + && (fraction_width == 1 + || format->w - width + (style->grouping == 0 && number < 0) <= 2)) + fraction_width = 0; + width += fraction_width; + + /* Format (except suffix). */ + p = buf; + if (width < format->w) + p = mempset (p, ' ', format->w - width); + if (number < 0) + p = mempcpy (p, ss_data (style->neg_prefix), + ss_length (style->neg_prefix)); + if (add_affixes) + p = mempcpy (p, ss_data (style->prefix), ss_length (style->prefix)); + if (fraction_width > 0) + sprintf (p, "%#.*E", fraction_width - 1, fabs (number)); + else + sprintf (p, "%.0E", fabs (number)); - time = number; - width = fp->w; - cp = temp_buf; - if (time < 0) - *cp++ = '-', time = -time; - if (fp->type == FMT_DTIME) + /* The C locale always uses a period `.' as a decimal point. + Translate to comma if necessary. */ + if (style->decimal != '.') { - double days = floor (time / 60. / 60. / 24.); - cp = spprintf (temp_buf, "%02.0f ", days); - time = time - days * 60. * 60. * 24.; - width -= 3; + char *cp = strchr (p, '.'); + if (cp != NULL) + *cp = style->decimal; } - else - cp = temp_buf; - - cp = spprintf (cp, "%02.0f:%02.0f", - fmod (floor (time / 60. / 60.), 24.), - fmod (floor (time / 60.), 60.)); - if (width >= 8) - { - int w, d; + /* Make exponent have exactly three digits, plus sign. */ + { + char *cp = strchr (p, 'E') + 1; + long int exponent = strtol (cp, NULL, 10); + if (abs (exponent) > 999) + return false; + sprintf (cp, "%+04ld", exponent); + } - if (width >= 10 && fp->d >= 0 && fp->d != 0) - d = min (fp->d, width - 9), w = 3 + d; - else - w = 2, d = 0; + /* Add suffixes. */ + p = strchr (p, '\0'); + if (add_affixes) + p = mempcpy (p, ss_data (style->suffix), ss_length (style->suffix)); + if (number < 0) + p = mempcpy (p, ss_data (style->neg_suffix), + ss_length (style->neg_suffix)); + else + p = mempset (p, ' ', ss_length (style->neg_suffix)); - cp = spprintf (cp, ":%0*.*f", w, d, fmod (time, 60.)); - } - buf_copy_str_rpad (dst, fp->w, temp_buf); + assert (p == buf + format->w); - return 1; + buf_copy_str_lpad (output, format->w, buf); + return true; } - -static int -convert_WKDAY (char *dst, const struct fmt_spec *fp, double wkday) + +#ifndef HAVE_ROUND +/* Return X rounded to the nearest integer, + rounding ties away from zero. */ +static double +round (double x) { - static const char *weekdays[7] = - { - "SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY", - "THURSDAY", "FRIDAY", "SATURDAY", - }; - - if (wkday < 1 || wkday > 7) - { - msg (ME, _("Weekday index %f does not lie between 1 and 7."), - (double) wkday); - return 0; - } - buf_copy_str_rpad (dst, fp->w, weekdays[(int) wkday - 1]); - - return 1; + return x >= 0.0 ? floor (x + .5) : ceil (x - .5); } +#endif /* !HAVE_ROUND */ -static int -convert_MONTH (char *dst, const struct fmt_spec *fp, double month) +/* Returns true if the magnitude represented by R should be + rounded up when chopped off at DECIMALS decimal places, false + if it should be rounded down. */ +static bool +should_round_up (const struct rounder *r, int decimals) { - static const char *months[12] = - { - "JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE", - "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER", - }; - - if (month < 1 || month > 12) - { - msg (ME, _("Month index %f does not lie between 1 and 12."), - month); - return 0; - } - - buf_copy_str_rpad (dst, fp->w, months[(int) month - 1]); - - return 1; + int digit = r->string[r->integer_digits + decimals + 1]; + assert (digit >= '0' && digit <= '9'); + return digit >= '5'; } - -/* Helper functions. */ -/* Copies SRC to DST, inserting commas and dollar signs as appropriate - for format spec *FP. */ +/* Initializes R for formatting the magnitude of NUMBER to no + more than MAX_DECIMAL decimal places. */ static void -insert_commas (char *dst, const char *src, const struct fmt_spec *fp) +rounder_init (struct rounder *r, double number, int max_decimals) { - /* Number of leading spaces in the number. This is the amount of - room we have for inserting commas and dollar signs. */ - int n_spaces; - - /* Number of digits before the decimal point. This is used to - determine the Number of commas to insert. */ - int n_digits; - - /* Number of commas to insert. */ - int n_commas; - - /* Number of items ,%$ to insert. */ - int n_items; - - /* Number of n_items items not to use for commas. */ - int n_reserved; - - /* Digit iterator. */ - int i; - - /* Source pointer. */ - const char *sp; - - /* Count spaces and digits. */ - sp = src; - while (sp < src + fp->w && *sp == ' ') - sp++; - n_spaces = sp - src; - sp = src + n_spaces; - if (*sp == '-') - sp++; - n_digits = 0; - while (sp + n_digits < src + fp->w && isdigit ((unsigned char) sp[n_digits])) - n_digits++; - n_commas = (n_digits - 1) / 3; - n_items = n_commas + (fp->type == FMT_DOLLAR || fp->type == FMT_PCT); - - /* Check whether we have enough space to do insertions. */ - if (!n_spaces || !n_items) + assert (fabs (number) < 1e41); + assert (max_decimals >= 0 && max_decimals <= 16); + if (max_decimals == 0) { - memcpy (dst, src, fp->w); - return; - } - if (n_items > n_spaces) - { - n_items -= n_commas; - if (!n_items) - { - memcpy (dst, src, fp->w); - return; - } - } + /* Fast path. No rounding needed. - /* Put spaces at the beginning if there's extra room. */ - if (n_spaces > n_items) - { - memset (dst, ' ', n_spaces - n_items); - dst += n_spaces - n_items; - } - - /* Insert $ and reserve space for %. */ - n_reserved = 0; - if (fp->type == FMT_DOLLAR) - { - *dst++ = '$'; - n_items--; + We append ".00" to the integer representation because + round_up assumes that fractional digits are present. */ + sprintf (r->string, "%.0f.00", fabs (round (number))); } - else if (fp->type == FMT_PCT) - n_reserved = 1; - - /* Copy negative sign and digits, inserting commas. */ - if (sp - src > n_spaces) - *dst++ = '-'; - for (i = n_digits; i; i--) + else { - if (i % 3 == 0 && n_digits > i && n_items > n_reserved) - { - n_items--; - *dst++ = fmt_grouping_char (fp->type); - } - *dst++ = *sp++; + /* Slow path. + + This is more difficult than it really should be because + we have to make sure that numbers that are exactly + halfway between two representations are always rounded + away from zero. This is not what sprintf normally does + (usually it rounds to even), so we have to fake it as + best we can, by formatting with extra precision and then + doing the rounding ourselves. + + We take up to two rounds to format numbers. In the + first round, we obtain 2 digits of precision beyond + those requested by the user. If those digits are + exactly "50", then in a second round we format with as + many digits as are significant in a "double". + + It might be better to directly implement our own + floating-point formatting routine instead of relying on + the system's sprintf implementation. But the classic + Steele and White paper on printing floating-point + numbers does not hint how to do what we want, and it's + not obvious how to change their algorithms to do so. It + would also be a lot of work. */ + sprintf (r->string, "%.*f", max_decimals + 2, fabs (number)); + if (!strcmp (r->string + strlen (r->string) - 2, "50")) + { + int binary_exponent, decimal_exponent, format_decimals; + frexp (number, &binary_exponent); + decimal_exponent = binary_exponent * 3 / 10; + format_decimals = (DBL_DIG + 1) - decimal_exponent; + if (format_decimals > max_decimals + 2) + sprintf (r->string, "%.*f", format_decimals, fabs (number)); + } } + + if (r->string[0] == '0') + memmove (r->string, &r->string[1], strlen (r->string)); - /* Copy decimal places and insert % if necessary. */ - memcpy (dst, sp, fp->w - (sp - src)); - if (fp->type == FMT_PCT && n_items > 0) - dst[fp->w - (sp - src)] = '%'; + r->leading_zeros = strspn (r->string, "0."); + r->leading_nines = strspn (r->string, "9."); + r->integer_digits = strchr (r->string, '.') - r->string; + r->negative = number < 0; } -/* Returns 1 if YEAR (i.e., 1987) can be represented in four digits, 0 - otherwise. */ -static int -year4 (int year) -{ - if (year >= 1 && year <= 9999) - return 1; - msg (ME, _("Year %d cannot be represented in four digits for " - "output formatting purposes."), year); - return 0; -} +/* Returns the number of characters required to format the + magnitude represented by R to DECIMALS decimal places. + The return value includes integer digits and a decimal point + and fractional digits, if any, but it does not include any + negative prefix or suffix or other affixes. + + *INTEGER_DIGITS is set to the number of digits before the + decimal point in the output, between 0 and 40. + If R represents a negative number and its rounded + representation would include at least one nonzero digit, + *NEGATIVE is set to true; otherwise, it is set to false. */ static int -try_CCx (char *dst, const struct fmt_spec *fp, double number) +rounder_width (const struct rounder *r, int decimals, + int *integer_digits, bool *negative) { - const struct fmt_number_style *style = fmt_get_style (fp->type); - - struct fmt_spec f; - - char buf[64]; - char buf2[64]; - char *cp; - - /* Determine length available, decimal character for number - proper. */ - f.type = style->decimal == fmt_decimal_char (FMT_COMMA) ? FMT_COMMA : FMT_DOT; - f.w = fp->w - fmt_affix_width (style); - if (number < 0) - f.w -= fmt_neg_affix_width (style) - 1; - else - /* Convert -0 to +0. */ - number = fabs (number); - f.d = fp->d; - - if (f.w <= 0) - return 0; - - /* There's room for all that currency crap. Let's do the F - conversion first. */ - if (!convert_F (buf, &f, number) || *buf == '*') - return 0; - insert_commas (buf2, buf, &f); - - /* Postprocess back into buf. */ - cp = buf; - if (number < 0) - cp = mempcpy (cp, ss_data (style->neg_prefix), - ss_length (style->neg_prefix)); - cp = mempcpy (cp, ss_data (style->prefix), ss_length (style->prefix)); - { - char *bp = buf2; - while (*bp == ' ') - bp++; - - assert ((number >= 0) ^ (*bp == '-')); - if (number < 0) - bp++; - - memcpy (cp, bp, f.w - (bp - buf2)); - cp += f.w - (bp - buf2); - } - cp = mempcpy (cp, ss_data (style->suffix), ss_length (style->suffix)); - if (number < 0) - cp = mempcpy (cp, ss_data (style->neg_suffix), - ss_length (style->neg_suffix)); - - /* Copy into dst. */ - assert (cp - buf <= fp->w); - if (cp - buf < fp->w) + /* Calculate base measures. */ + int width = r->integer_digits; + if (decimals > 0) + width += decimals + 1; + *integer_digits = r->integer_digits; + *negative = r->negative; + + /* Rounding can cause adjustments. */ + if (should_round_up (r, decimals)) { - memcpy (&dst[fp->w - (cp - buf)], buf, cp - buf); - memset (dst, ' ', fp->w - (cp - buf)); + /* Rounding up leading 9s adds a new digit (a 1). */ + if (r->leading_nines >= width) + { + width++; + ++*integer_digits; + } } else - memcpy (dst, buf, fp->w); - - return 1; + { + /* Rounding down. */ + if (r->leading_zeros >= width) + { + /* All digits that remain after rounding are zeros. + Therefore we drop the negative sign. */ + *negative = false; + if (r->integer_digits == 0 && decimals == 0) + { + /* No digits at all are left. We need to display + at least a single digit (a zero). */ + assert (width == 0); + width++; + *integer_digits = 1; + } + } + } + return width; } -static int -format_and_round (char *dst, double number, const struct fmt_spec *fp, - int decimals); - -/* Tries to format NUMBER into DST as the F format specified in - *FP. Return true if successful, false on failure. */ -static int -try_F (char *dst, const struct fmt_spec *fp, double number) +/* Formats the magnitude represented by R into OUTPUT, rounding + to DECIMALS decimal places. Exactly as many characters as + indicated by rounder_width are written. No terminating null + is appended. */ +static void +rounder_format (const struct rounder *r, int decimals, char *output) { - assert (fp->w <= 40); - if (finite (number)) + int base_width = r->integer_digits + (decimals > 0 ? decimals + 1 : 0); + if (should_round_up (r, decimals)) { - if (fabs (number) < power10[fp->w]) + if (r->leading_nines < base_width) { - /* The value may fit in the field. */ - if (fp->d == 0) + /* Rounding up. This is the common case where rounding + up doesn't add an extra digit. */ + char *p; + memcpy (output, r->string, base_width); + for (p = output + base_width - 1; ; p--) { - /* There are no decimal places, so there's no way - that the value can be shortened. Either it fits - or it doesn't. */ - char buf[41]; - sprintf (buf, "%*.0f", fp->w, number); - if (strlen (buf) <= fp->w) + assert (p >= output); + if (*p == '9') + *p = '0'; + else if (*p >= '0' && *p <= '8') { - buf_copy_str_lpad (dst, fp->w, buf); - return true; + (*p)++; + break; } - else - return false; - } - else - { - /* First try to format it with 2 extra decimal - places. This gives us a good chance of not - needing even more decimal places, but it also - avoids wasting too much time formatting more - decimal places on the first try. */ - int result = format_and_round (dst, number, fp, fp->d + 2); - - if (result >= 0) - return result; - - /* 2 extra decimal places weren't enough to - correctly round. Try again with the maximum - number of places. */ - return format_and_round (dst, number, fp, LDBL_DIG + 1); + else + assert (*p == '.'); } } else { - /* The value is too big to fit in the field. */ - return false; + /* Rounding up leading 9s causes the result to be a 1 + followed by a number of 0s, plus a decimal point. */ + char *p = output; + *p++ = '1'; + p = mempset (p, '0', r->integer_digits); + if (decimals > 0) + { + *p++ = '.'; + p = mempset (p, '0', decimals); + } + assert (p == output + base_width + 1); } } - else - return convert_infinite (dst, fp, number); -} - -/* Tries to compose NUMBER into DST in format FP by first - formatting it with DECIMALS decimal places, then rounding off - to as many decimal places will fit or the number specified in - FP, whichever is fewer. - - Returns 1 if conversion succeeds, 0 if this try at conversion - failed and so will any other tries (because the integer part - of the number is too long), or -1 if this try failed but - another with higher DECIMALS might succeed (because we'd be - able to properly round). */ -static int -format_and_round (char *dst, double number, const struct fmt_spec *fp, - int decimals) -{ - /* Number of characters before the decimal point, - which includes digits and possibly a minus sign. */ - int predot_chars; - - /* Number of digits in the output fraction, - which may be smaller than fp->d if there's not enough room. */ - int fraction_digits; - - /* Points to last digit that will remain in the fraction after - rounding. */ - char *final_frac_dig; - - /* Round up? */ - bool round_up; - - char buf[128]; - - assert (decimals > fp->d); - if (decimals > LDBL_DIG) - decimals = LDBL_DIG + 1; - - sprintf (buf, "%.*f", decimals, number); - - /* Omit integer part if it's 0. */ - if (!memcmp (buf, "0.", 2)) - memmove (buf, buf + 1, strlen (buf)); - else if (!memcmp (buf, "-0.", 3)) - memmove (buf + 1, buf + 2, strlen (buf + 1)); - - predot_chars = strcspn (buf, "."); - if (predot_chars > fp->w) - { - /* Can't possibly fit. */ - return 0; - } - else if (predot_chars == fp->w) - { - /* Exact fit for integer part and sign. */ - memcpy (dst, buf, fp->w); - return 1; - } - else if (predot_chars + 1 == fp->w) - { - /* There's room for the decimal point, but not for any - digits of the fraction. - Right-justify the integer part and sign. */ - dst[0] = ' '; - memcpy (dst + 1, buf, fp->w - 1); - return 1; - } - - /* It looks like we have room for at least one digit of the - fraction. Figure out how many. */ - fraction_digits = fp->w - predot_chars - 1; - if (fraction_digits > fp->d) - fraction_digits = fp->d; - final_frac_dig = buf + predot_chars + fraction_digits; - - /* Decide rounding direction and truncate string. */ - if (final_frac_dig[1] == '5' - && strspn (final_frac_dig + 2, "0") == strlen (final_frac_dig + 2)) + else { - /* Exactly 1/2. */ - if (decimals <= LDBL_DIG) + /* Rounding down. */ + if (r->integer_digits != 0 || decimals != 0) { - /* Don't have enough fractional digits to know which way to - round. We can format with more decimal places, so go - around again. */ - return -1; + /* Common case: just copy the digits. */ + memcpy (output, r->string, base_width); } else { - /* We used up all our fractional digits and still don't - know. Round to even. */ - round_up = (final_frac_dig[0] - '0') % 2 != 0; + /* No digits remain. The output is just a zero. */ + output[0] = '0'; } } - else - round_up = final_frac_dig[1] >= '5'; - final_frac_dig[1] = '\0'; +} + +/* Helper functions. */ - /* Do rounding. */ - if (round_up) +/* Returns 10**X. */ +static double PURE_FUNCTION +power10 (int x) +{ + static const double p[] = { - char *cp = final_frac_dig; - for (;;) - { - if (*cp >= '0' && *cp <= '8') - { - (*cp)++; - break; - } - else if (*cp == '9') - *cp = '0'; - else - assert (*cp == '.'); - - if (cp == buf || *--cp == '-') - { - size_t length; - - /* Tried to go past the leftmost digit. Insert a 1. */ - memmove (cp + 1, cp, strlen (cp) + 1); - *cp = '1'; - - length = strlen (buf); - if (length > fp->w) - { - /* Inserting the `1' overflowed our space. - Drop a decimal place. */ - buf[--length] = '\0'; - - /* If that was the last decimal place, drop the - decimal point too. */ - if (buf[length - 1] == '.') - buf[length - 1] = '\0'; - } - - break; - } - } - } - - /* Omit `-' if value output is zero. */ - if (buf[0] == '-' && buf[strspn (buf, "-.0")] == '\0') - memmove (buf, buf + 1, strlen (buf)); + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29, + 1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39, + 1e40, + }; + return x >= 0 && x < sizeof p / sizeof *p ? p[x] : pow (10.0, x); +} - buf_copy_str_lpad (dst, fp->w, buf); - return 1; +/* Returns 256**X. */ +static double PURE_FUNCTION +power256 (int x) +{ + static const double p[] = + { + 1.0, + 256.0, + 65536.0, + 16777216.0, + 4294967296.0, + 1099511627776.0, + 281474976710656.0, + 72057594037927936.0, + 18446744073709551616.0 + }; + return x >= 0 && x < sizeof p / sizeof *p ? p[x] : pow (256.0, x); } -/* Formats non-finite NUMBER into DST according to the width - given in FP. */ -static int -convert_infinite (char *dst, const struct fmt_spec *fp, double number) +/* Formats non-finite NUMBER into OUTPUT according to the width + given in FORMAT. */ +static void +output_infinite (double number, const struct fmt_spec *format, char *output) { - assert (!finite (number)); + assert (!isfinite (number)); - if (fp->w >= 3) + if (format->w >= 3) { const char *s; @@ -1237,10 +963,95 @@ convert_infinite (char *dst, const struct fmt_spec *fp, double number) else s = "Unknown"; - buf_copy_str_lpad (dst, fp->w, s); + buf_copy_str_lpad (output, format->w, s); } else - memset (dst, '*', fp->w); + output_overflow (format, output); +} - return true; +/* Formats OUTPUT as a missing value for the given FORMAT. */ +static void +output_missing (const struct fmt_spec *format, char *output) +{ + memset (output, ' ', format->w); + + if (format->type != FMT_N) + { + int dot_ofs = (format->type == FMT_PCT ? 2 + : format->type == FMT_E ? 5 + : 1); + output[MAX (0, format->w - format->d - dot_ofs)] = '.'; + } + else + output[format->w - 1] = '.'; +} + +/* Formats OUTPUT for overflow given FORMAT. */ +static void +output_overflow (const struct fmt_spec *format, char *output) +{ + memset (output, '*', format->w); +} + +/* Converts the integer part of NUMBER to a packed BCD number + with the given number of DIGITS in OUTPUT. If DIGITS is odd, + the least significant nibble of the final byte in OUTPUT is + set to 0. Returns true if successful, false if NUMBER is not + representable. On failure, OUTPUT is cleared to all zero + bytes. */ +static bool +output_bcd_integer (double number, int digits, char *output) +{ + char decimal[64]; + + assert (digits < sizeof decimal); + if (number != SYSMIS + && number >= 0. + && number < power10 (digits) + && sprintf (decimal, "%0*.0f", digits, round (number)) == digits) + { + const char *src = decimal; + int i; + + for (i = 0; i < digits / 2; i++) + { + int d0 = *src++ - '0'; + int d1 = *src++ - '0'; + *output++ = (d0 << 4) + d1; + } + if (digits % 2) + *output = (*src - '0') << 4; + + return true; + } + else + { + memset (output, 0, digits); + return false; + } +} + +/* Writes VALUE to OUTPUT as a BYTES-byte binary integer of the + given INTEGER_FORMAT. */ +static void +output_binary_integer (uint64_t value, int bytes, + enum integer_format integer_format, char *output) +{ + integer_put (value, integer_format, output, bytes); +} + +/* Converts the BYTES bytes in DATA to twice as many hexadecimal + digits in OUTPUT. */ +static void +output_hex (const void *data_, size_t bytes, char *output) +{ + const uint8_t *data = data_; + size_t i; + + for (i = 0; i < bytes; i++) + { + static const char hex_digits[] = "0123456789ABCDEF"; + *output++ = hex_digits[data[i] >> 4]; + *output++ = hex_digits[data[i] & 15]; + } } diff --git a/src/data/data-out.h b/src/data/data-out.h new file mode 100644 index 00000000..bf949c8b --- /dev/null +++ b/src/data/data-out.h @@ -0,0 +1,37 @@ +/* PSPP - computes sample statistics. + Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc. + Written by Ben Pfaff . + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#ifndef DATA_OUT_H +#define DATA_OUT_H 1 + +#include +#include + +struct fmt_spec; +union value; + +void data_out (const union value *, const struct fmt_spec *, char *); + +enum integer_format data_out_get_integer_format (void); +void data_out_set_integer_format (enum integer_format); + +enum float_format data_out_get_float_format (void); +void data_out_set_float_format (enum float_format); + +#endif /* data-out.h */ diff --git a/src/data/format.c b/src/data/format.c index 3ce41ee0..06042d0e 100644 --- a/src/data/format.c +++ b/src/data/format.c @@ -456,7 +456,7 @@ fmt_max_output_decimals (enum fmt_type type, int width) int fmt_step_width (enum fmt_type type) { - return fmt_get_category (type) & FMT_CAT_HEXADECIMAL ? 2 : 1; + return fmt_get_category (type) == FMT_CAT_HEXADECIMAL ? 2 : 1; } /* Returns true if TYPE is used for string fields, @@ -464,7 +464,7 @@ fmt_step_width (enum fmt_type type) bool fmt_is_string (enum fmt_type type) { - return fmt_get_category (type) & FMT_CAT_STRING; + return fmt_get_category (type) == FMT_CAT_STRING; } /* Returns true if TYPE is used for numeric fields, @@ -491,10 +491,19 @@ fmt_get_category (enum fmt_type type) enum fmt_type fmt_input_to_output (enum fmt_type type) { - enum fmt_category category = fmt_get_category (type); - return (category & FMT_CAT_STRING ? FMT_A - : category & (FMT_CAT_BASIC | FMT_CAT_HEXADECIMAL) ? FMT_F - : type); + switch (fmt_get_category (type)) + { + case FMT_CAT_STRING: + return FMT_A; + + case FMT_CAT_LEGACY: + case FMT_CAT_BINARY: + case FMT_CAT_HEXADECIMAL: + return FMT_F; + + default: + return type; + } } /* Returns the SPSS format type corresponding to the given PSPP @@ -503,7 +512,7 @@ int fmt_to_io (enum fmt_type type) { return get_fmt_desc (type)->io; -}; +} /* Determines the PSPP format corresponding to the given SPSS format type. If successful, sets *FMT_TYPE to the PSPP format diff --git a/src/data/format.h b/src/data/format.h index 3678632e..919f1c69 100644 --- a/src/data/format.h +++ b/src/data/format.h @@ -163,9 +163,5 @@ enum measure bool measure_is_valid(enum measure m); bool alignment_is_valid(enum alignment a); - -#include - -bool data_out (char *s, const struct fmt_spec *fp, const union value *v); #endif /* format.h */ diff --git a/src/data/value-labels.c b/src/data/value-labels.c index ad7f3b81..96d3dd75 100644 --- a/src/data/value-labels.c +++ b/src/data/value-labels.c @@ -23,6 +23,7 @@ #include +#include #include #include #include @@ -545,7 +546,7 @@ value_to_string (const union value *val, const struct variable *var) if (s == NULL) { static char buf[MAX_STRING + 1]; - data_out (buf, &var->print, val); + data_out (val, &var->print, buf); buf[var->print.w] = '\0'; s = buf; } diff --git a/src/language/data-io/list.q b/src/language/data-io/list.q index b099a270..d8256e32 100644 --- a/src/language/data-io/list.q +++ b/src/language/data-io/list.q @@ -26,6 +26,7 @@ #include "size_max.h" #include #include +#include #include #include #include @@ -666,15 +667,15 @@ list_cases (const struct ccase *c, void *aux UNUSED, const struct dataset *ds UN if (fmt_is_string (v->print.type) || v->fv != -1) { - data_out (ds_put_uninit(&line_buffer, v->print.w), - &v->print, case_data (c, v->fv)); + data_out (case_data (c, v->fv), &v->print, + ds_put_uninit (&line_buffer, v->print.w)); } else { union value case_idx_value; case_idx_value.f = case_idx; - data_out (ds_put_uninit(&line_buffer,v->print.w), - &v->print, &case_idx_value); + data_out (&case_idx_value, &v->print, + ds_put_uninit (&line_buffer,v->print.w)); } ds_put_char(&line_buffer, ' '); @@ -702,12 +703,12 @@ list_cases (const struct ccase *c, void *aux UNUSED, const struct dataset *ds UN char buf[256]; if (fmt_is_string (v->print.type) || v->fv != -1) - data_out (buf, &v->print, case_data (c, v->fv)); + data_out (case_data (c, v->fv), &v->print, buf); else { union value case_idx_value; case_idx_value.f = case_idx; - data_out (buf, &v->print, &case_idx_value); + data_out (&case_idx_value, &v->print, buf); } fputs (" ", x->file); diff --git a/src/language/data-io/print.c b/src/language/data-io/print.c index 2bc28a5d..262d5397 100644 --- a/src/language/data-io/print.c +++ b/src/language/data-io/print.c @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include #include @@ -460,7 +460,7 @@ print_trns_proc (void *trns_, struct ccase *c, casenumber case_num UNUSED) const union value *input = case_data (c, spec->var->fv); char *output = ds_put_uninit (&trns->line, spec->format.w); if (!spec->sysmis_as_spaces || input->f != SYSMIS) - data_out (output, &spec->format, input); + data_out (input, &spec->format, output); else memset (output, ' ', spec->format.w); if (spec->add_space) diff --git a/src/language/dictionary/ChangeLog b/src/language/dictionary/ChangeLog index 726c6547..c0b714fc 100644 --- a/src/language/dictionary/ChangeLog +++ b/src/language/dictionary/ChangeLog @@ -1,3 +1,8 @@ +Sat Nov 4 16:04:19 2006 Ben Pfaff + + * numeric.c: (cmd_string) Check that output format is valid. + Simplify parsing. + Wed Nov 1 20:50:54 2006 Ben Pfaff * sys-file-info.c: (cmd_display) Use compare_var_ptr_names to diff --git a/src/language/dictionary/numeric.c b/src/language/dictionary/numeric.c index b7a23315..ae961963 100644 --- a/src/language/dictionary/numeric.c +++ b/src/language/dictionary/numeric.c @@ -128,7 +128,9 @@ cmd_string (struct dataset *ds) if (!parse_DATA_LIST_vars (&v, &nv, PV_NONE)) return CMD_FAILURE; - if (!lex_force_match ('(') || !parse_format_specifier (&f)) + if (!lex_force_match ('(') + || !parse_format_specifier (&f) + || !lex_force_match (')')) goto fail; if (!fmt_is_string (f.type)) { @@ -137,12 +139,8 @@ cmd_string (struct dataset *ds) "variable."), fmt_to_string (&f, str)); goto fail; } - - if (!lex_match (')')) - { - msg (SE, _("`)' expected after output format.")); - goto fail; - } + if (!fmt_check_output (&f)) + goto fail; width = fmt_var_width (&f); diff --git a/src/language/dictionary/split-file.c b/src/language/dictionary/split-file.c index ef34d7e9..8c5a9555 100644 --- a/src/language/dictionary/split-file.c +++ b/src/language/dictionary/split-file.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -95,7 +96,7 @@ output_split_file_values (const struct dataset *ds, const struct ccase *c) assert (v->type == NUMERIC || v->type == ALPHA); tab_text (t, 0, i + 1, TAB_LEFT | TAT_PRINTF, "%s", v->name); - data_out (temp_buf, &v->print, case_data (c, v->fv)); + data_out (case_data (c, v->fv), &v->print, temp_buf); temp_buf[v->print.w] = 0; tab_text (t, 1, i + 1, TAT_PRINTF, "%.*s", v->print.w, temp_buf); diff --git a/src/language/expressions/helpers.h b/src/language/expressions/helpers.h index 0f44b35f..124868cc 100644 --- a/src/language/expressions/helpers.h +++ b/src/language/expressions/helpers.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/src/language/expressions/operations.def b/src/language/expressions/operations.def index 303c1d5c..6b4d5221 100644 --- a/src/language/expressions/operations.def +++ b/src/language/expressions/operations.def @@ -587,7 +587,7 @@ absorb_miss string function STRING (x, no_format f) v.f = x; dst = alloc_string (e, f->w); assert (!fmt_is_string (f->type)); - data_out (dst.string, f, &v); + data_out (&v, f, dst.string); return dst; } diff --git a/src/language/lexer/format-parser.h b/src/language/lexer/format-parser.h index 046f57ab..d16b2f5b 100644 --- a/src/language/lexer/format-parser.h +++ b/src/language/lexer/format-parser.h @@ -24,8 +24,6 @@ #include -struct fmt_spec; - bool parse_abstract_format_specifier (char type[FMT_TYPE_LEN_MAX + 1], int *width, int *decimals); bool parse_format_specifier (struct fmt_spec *); diff --git a/src/language/stats/crosstabs.q b/src/language/stats/crosstabs.q index cf76b35b..67ee5aab 100644 --- a/src/language/stats/crosstabs.q +++ b/src/language/stats/crosstabs.q @@ -37,6 +37,7 @@ #include #include +#include #include #include #include @@ -1718,7 +1719,7 @@ format_cell_entry (struct tab_table *table, int c, int r, double value, s.length = 10; s.string = tab_alloc (table, 16); v.f = value; - data_out (s.string, &f, &v); + data_out (&v, &f, s.string); while (*s.string == ' ') { s.length--; @@ -3200,8 +3201,8 @@ format_short (char *s, const struct fmt_spec *fp, const union value *v) } /* Format. */ - data_out (s, fp, v); - + data_out (v, fp, s); + /* Null terminate. */ s[fp->w] = '\0'; } diff --git a/src/language/utilities/ChangeLog b/src/language/utilities/ChangeLog index bcae1ebd..e05deb42 100644 --- a/src/language/utilities/ChangeLog +++ b/src/language/utilities/ChangeLog @@ -1,3 +1,16 @@ +Sat Nov 4 16:05:47 2006 Ben Pfaff + + * set.q: Add WIB, WRB settings to control binary formats used by + data_out. + (cmd_set) Implement SET WIB, WRB. + (stc_to_integer_format) New function. + (stc_to_float_format) New function. + (show_integer_format) New function. + (show_float_format) New function. + (show_wib) New function. + (show_wrb) New function. + (static var show_table[]) Add SHOW WIB, WRB. + Sat Nov 4 11:48:23 2006 Ben Pfaff * set.q: Update ERRORS, MESSAGES, RESULTS command syntax. diff --git a/src/language/utilities/set.q b/src/language/utilities/set.q index d55511e0..a05878a3 100644 --- a/src/language/utilities/set.q +++ b/src/language/utilities/set.q @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -36,6 +37,8 @@ #include #include #include +#include +#include #include #include #include @@ -106,6 +109,8 @@ int tgetnum (const char *); tb1=string "x==3 || x==11" "3 or 11 characters long"; tbfonts=string; undefined=undef:warn/nowarn; + wib=wib:msbfirst/lsbfirst/vax/native; + wrb=wrb:native/isl/isb/idl/idb/vf/vd/vg/zs/zl; width=custom; workspace=integer "x>=1024" "%s must be at least 1 MB"; xsort=xsort:yes/no. @@ -118,6 +123,8 @@ int tgetnum (const char *); /* (functions) */ static bool do_cc (const char *cc_string, enum fmt_type); +static enum integer_format stc_to_integer_format (int stc); +static enum float_format stc_to_float_format (int stc); int cmd_set (struct dataset *ds) @@ -173,6 +180,10 @@ cmd_set (struct dataset *ds) set_scompression (cmd.scompress == STC_ON); if (cmd.sbc_undefined) set_undefined (cmd.undef == STC_WARN); + if (cmd.sbc_wib) + data_out_set_integer_format (stc_to_integer_format (cmd.wib)); + if (cmd.sbc_wrb) + data_out_set_float_format (stc_to_float_format (cmd.wrb)); if (cmd.sbc_workspace) set_workspace (cmd.n_workspace[0] * 1024L); @@ -204,6 +215,52 @@ cmd_set (struct dataset *ds) return CMD_SUCCESS; } +/* Returns the integer_format value corresponding to STC, + which should be the value of cmd.rib or cmd.wib. */ +static enum integer_format +stc_to_integer_format (int stc) +{ + return (stc == STC_MSBFIRST ? INTEGER_MSB_FIRST + : stc == STC_LSBFIRST ? INTEGER_LSB_FIRST + : stc == STC_VAX ? INTEGER_VAX + : INTEGER_NATIVE); +} + +/* Returns the float_format value corresponding to STC, + which should be the value of cmd.rrb or cmd.wrb. */ +static enum float_format +stc_to_float_format (int stc) +{ + switch (stc) + { + case STC_NATIVE: + return FLOAT_NATIVE_DOUBLE; + + case STC_ISL: + return FLOAT_IEEE_SINGLE_LE; + case STC_ISB: + return FLOAT_IEEE_SINGLE_BE; + case STC_IDL: + return FLOAT_IEEE_DOUBLE_LE; + case STC_IDB: + return FLOAT_IEEE_DOUBLE_BE; + + case STC_VF: + return FLOAT_VAX_F; + case STC_VD: + return FLOAT_VAX_D; + case STC_VG: + return FLOAT_VAX_G; + + case STC_ZS: + return FLOAT_Z_SHORT; + case STC_ZL: + return FLOAT_Z_LONG; + } + + NOT_REACHED (); +} + /* Find the grouping characters in CC_STRING and set CC's grouping and decimal members appropriately. Returns true if successful, false otherwise. */ @@ -604,6 +661,66 @@ show_mxwarns (const struct dataset *ds UNUSED) msg (SN, _("MXWARNS is %d."), get_mxwarns ()); } +/* Outputs that SETTING has the given INTEGER_FORMAT value. */ +static void +show_integer_format (const char *setting, enum integer_format integer_format) +{ + msg (SN, _("%s is %s (%s)."), + setting, + (integer_format == INTEGER_MSB_FIRST ? "MSBFIRST" + : integer_format == INTEGER_LSB_FIRST ? "LSBFIRST" + : "VAX"), + integer_format == INTEGER_NATIVE ? "NATIVE" : "nonnative"); +} + +/* Outputs that SETTING has the given FLOAT_FORMAT value. */ +static void +show_float_format (const char *setting, enum float_format float_format) +{ + const char *format_name = ""; + + switch (float_format) + { + case FLOAT_IEEE_SINGLE_LE: + format_name = "ISL (32-bit IEEE 754 single, little-endian)"; + break; + case FLOAT_IEEE_SINGLE_BE: + format_name = "ISB (32-bit IEEE 754 single, big-endian)"; + break; + case FLOAT_IEEE_DOUBLE_LE: + format_name = "IDL (64-bit IEEE 754 double, little-endian)"; + break; + case FLOAT_IEEE_DOUBLE_BE: + format_name = "IDB (64-bit IEEE 754 double, big-endian)"; + break; + + case FLOAT_VAX_F: + format_name = "VF (32-bit VAX F, VAX-endian)"; + break; + case FLOAT_VAX_D: + format_name = "VD (64-bit VAX D, VAX-endian)"; + break; + case FLOAT_VAX_G: + format_name = "VG (64-bit VAX G, VAX-endian)"; + break; + + case FLOAT_Z_SHORT: + format_name = "ZS (32-bit IBM Z hexadecimal short, big-endian)"; + break; + case FLOAT_Z_LONG: + format_name = "ZL (64-bit IBM Z hexadecimal long, big-endian)"; + break; + + case FLOAT_FP: + case FLOAT_HEX: + NOT_REACHED (); + } + + msg (SN, _("%s is %s (%s)."), + setting, format_name, + float_format == FLOAT_NATIVE_DOUBLE ? "NATIVE" : "nonnative"); +} + static void show_scompression (const struct dataset *ds UNUSED) { @@ -632,6 +749,18 @@ show_weight (const struct dataset *ds) msg (SN, _("WEIGHT is variable %s."), var->name); } +static void +show_wib (const struct dataset *ds UNUSED) +{ + show_integer_format ("WIB", data_out_get_integer_format ()); +} + +static void +show_wrb (const struct dataset *ds UNUSED) +{ + show_float_format ("WRB", data_out_get_float_format ()); +} + static void show_width (const struct dataset *ds UNUSED) { @@ -663,6 +792,8 @@ const struct show_sbc show_table[] = {"SCOMPRESSION", show_scompression}, {"UNDEFINED", show_undefined}, {"WEIGHT", show_weight}, + {"WIB", show_wib}, + {"WRB", show_wrb}, {"WIDTH", show_width}, }; diff --git a/src/libpspp/str.c b/src/libpspp/str.c index cf0069dd..965e3b30 100644 --- a/src/libpspp/str.c +++ b/src/libpspp/str.c @@ -158,6 +158,22 @@ buf_copy_str_lpad (char *dst, size_t dst_size, const char *src) } } +/* Copies buffer SRC, of SRC_SIZE bytes, to DST, of DST_SIZE bytes. + DST is truncated to DST_SIZE bytes or padded on the left with + spaces as needed. */ +void +buf_copy_lpad (char *dst, size_t dst_size, + const char *src, size_t src_size) +{ + if (src_size >= dst_size) + memmove (dst, src, dst_size); + else + { + memset (dst, ' ', dst_size - src_size); + memmove (&dst[dst_size - src_size], src, src_size); + } +} + /* Copies buffer SRC, of SRC_SIZE bytes, to DST, of DST_SIZE bytes. DST is truncated to DST_SIZE bytes or padded on the right with spaces as needed. */ @@ -253,6 +269,15 @@ spprintf (char *dst, const char *format, ...) return dst + count; } + +/* Sets the SIZE bytes starting at BLOCK to C, + and returns the byte following BLOCK. */ +void * +mempset (void *block, int c, size_t size) +{ + memset (block, c, size); + return (char *) block + size; +} /* Substrings. */ diff --git a/src/libpspp/str.h b/src/libpspp/str.h index d8698ba4..eaf12c3b 100644 --- a/src/libpspp/str.h +++ b/src/libpspp/str.h @@ -44,6 +44,7 @@ void buf_reverse (char *, size_t); char *buf_find_reverse (const char *, size_t, const char *, size_t); int buf_compare_case (const char *, const char *, size_t); int buf_compare_rpad (const char *, size_t, const char *, size_t); +void buf_copy_lpad (char *, size_t, const char *, size_t); void buf_copy_rpad (char *, size_t, const char *, size_t); void buf_copy_str_lpad (char *, size_t, const char *); void buf_copy_str_rpad (char *, size_t, const char *); @@ -56,6 +57,8 @@ void str_uppercase (char *); void str_lowercase (char *); char *spprintf (char *dst, const char *format, ...); + +void *mempset (void *, int, size_t); /* Common character classes for use with substring and string functions. */ diff --git a/src/output/table.c b/src/output/table.c index 029fd5d0..ca3e467c 100644 --- a/src/output/table.c +++ b/src/output/table.c @@ -29,6 +29,7 @@ #include "output.h" #include "manager.h" +#include #include #include #include @@ -541,7 +542,7 @@ tab_value (struct tab_table *table, int c, int r, unsigned char opt, table->cc[c + r * table->cf] = ss_buffer (contents, f->w); table->ct[c + r * table->cf] = opt; - data_out (contents, f, v); + data_out (v, f, contents); } /* Sets cell (C,R) in TABLE, with options OPT, to have value VAL @@ -580,7 +581,7 @@ tab_float (struct tab_table *table, int c, int r, unsigned char opt, #endif double_value.f = val; - data_out (buf, &f, &double_value); + data_out (&double_value, &f, buf); cp = buf; while (isspace ((unsigned char) *cp) && cp < &buf[w]) diff --git a/src/ui/gui/helper.c b/src/ui/gui/helper.c index 841bda5a..dea14d54 100644 --- a/src/ui/gui/helper.c +++ b/src/ui/gui/helper.c @@ -1,5 +1,6 @@ #include "helper.h" #include +#include #include #include @@ -16,10 +17,7 @@ value_to_text(union value v, struct fmt_spec format) gchar *s = 0; s = g_new(gchar, format.w + 1); - if ( ! data_out(s, &format, &v) ) - { - g_warning("Can't format missing discrete value \n"); - } + data_out(&v, &format, s); s[format.w]='\0'; g_strchug(s); diff --git a/src/ui/gui/psppire-data-store.c b/src/ui/gui/psppire-data-store.c index eeaf31d6..0cb8ef91 100644 --- a/src/ui/gui/psppire-data-store.c +++ b/src/ui/gui/psppire-data-store.c @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -506,7 +507,7 @@ psppire_data_store_get_string (const GSheetModel *model, gint row, gint column) /* Converts binary value V into printable form in the exactly FP->W character in buffer S according to format specification FP. No null terminator is appended to the buffer. */ - data_out (s->str, fp, v); + data_out (v, fp, s->str); text = pspp_locale_to_utf8 (s->str, fp->w, 0); g_string_free (s, TRUE); diff --git a/tests/ChangeLog b/tests/ChangeLog index 8cc076d6..790a3316 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,26 @@ +Sat Nov 4 16:08:58 2006 Ben Pfaff + + * automake.mk: Add binhex-out.sh, date-out.sh, month-out.sh, + num-out.sh, time-out.sh, wkday-out.sh from formats directory. Add + formats/inexactify as a program needed by tests. + + * command/no_case_size.sh: Update output to conform with updated + formatted output code. + + * expressions/expressions.sh: Ditto. + + * formats/binhex-out.sh: New test. + + * formats/date-out.sh: New test. + + * formats/month-out.sh: New test. + + * formats/num-out.sh: New test. + + * formats/time-out.sh: New test. + + * formats/wkday-out.sh: New test. + Thu Oct 26 20:20:39 2006 Ben Pfaff * automake.mk: Add tests/formats/float-format.sh. diff --git a/tests/automake.mk b/tests/automake.mk index 2527c836..dde7b09c 100644 --- a/tests/automake.mk +++ b/tests/automake.mk @@ -57,7 +57,13 @@ TESTS = \ tests/command/use.sh \ tests/command/very-long-strings.sh \ tests/command/weight.sh \ + tests/formats/binhex-out.sh \ + tests/formats/date-out.sh \ tests/formats/float-format.sh \ + tests/formats/month-out.sh \ + tests/formats/num-out.sh \ + tests/formats/time-out.sh \ + tests/formats/wkday-out.sh \ tests/bugs/agg_crash.sh \ tests/bugs/agg-crash-2.sh \ tests/bugs/alpha-freq.sh \ @@ -112,7 +118,8 @@ TESTS = \ tests/libpspp/ll-test \ tests/libpspp/llx-test -check_PROGRAMS += tests/libpspp/ll-test tests/libpspp/llx-test +check_PROGRAMS += tests/libpspp/ll-test tests/libpspp/llx-test \ + tests/formats/inexactify tests_libpspp_ll_test_SOURCES = \ src/libpspp/ll.c \ @@ -126,6 +133,8 @@ tests_libpspp_llx_test_SOURCES = \ src/libpspp/llx.h \ tests/libpspp/llx-test.c +tests_formats_inexactify_SOURCES = tests/formats/inexactify.c + EXTRA_DIST += $(TESTS) tests/weighting.data tests/data-list.data tests/list.data \ tests/no_case_size.sav \ tests/coverage.sh tests/test_template \ diff --git a/tests/command/no_case_size.sh b/tests/command/no_case_size.sh index 25744bdc..3d6f2867 100755 --- a/tests/command/no_case_size.sh +++ b/tests/command/no_case_size.sh @@ -92,12 +92,12 @@ diff -b -w pspp.list - < "123.6" string($sysmis, f5.1) => " . " string("abc", A5) => error string(123, e1) => error # E has a minimum width of 6 on output. -string(123, e6.0) => " 1E+02" +string(123, e6.0) => "1E+002" substr('abcdefgh', -5) => "" substr('abcdefgh', 0) => "" diff --git a/tests/formats/binhex-out.expected.gz b/tests/formats/binhex-out.expected.gz new file mode 100644 index 0000000000000000000000000000000000000000..f8fc6e98670b30a3c8439503e29dc47bb318bce7 GIT binary patch literal 4106 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 uL~QUmL binhex-out.pspp < expected.out +if [ $? -ne 0 ] ; then no_result ; fi + +activity="compare output" +cmp expected.out binhex.out +if [ $? -ne 0 ] ; then fail ; fi + +pass diff --git a/tests/formats/date-out.sh b/tests/formats/date-out.sh new file mode 100755 index 00000000..6e28083c --- /dev/null +++ b/tests/formats/date-out.sh @@ -0,0 +1,578 @@ +#! /bin/sh + +TEMPDIR=/tmp/pspp-tst-$$ +mkdir -p $TEMPDIR +trap 'cd /; rm -rf $TEMPDIR' 0 + +# ensure that top_builddir are absolute +if [ -z "$top_builddir" ] ; then top_builddir=. ; fi +if [ -z "$top_srcdir" ] ; then top_srcdir=. ; fi +top_builddir=`cd $top_builddir; pwd` +PSPP=$top_builddir/src/ui/terminal/pspp + +# ensure that top_srcdir is absolute +top_srcdir=`cd $top_srcdir; pwd` + +STAT_CONFIG_PATH=$top_srcdir/config +export STAT_CONFIG_PATH + +fail() +{ + echo $activity + echo FAILED + exit 1; +} + + +no_result() +{ + echo $activity + echo NO RESULT; + exit 2; +} + +pass() +{ + exit 0; +} + +cd $TEMPDIR + +activity="write pspp syntax" +cat > date-out.pspp < bad-date-out.pspp <. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include +#include +#include +#include +#include + +/* Replaces insignificant digits by # to facilitate textual + comparisons. Not a perfect solution to the general-purpose + comparison problem, because rounding that affects earlier + digits can still cause differences. */ +int +main (void) +{ + bool in_quotes = false; + bool in_exponent = false; + int digits = 0; + + for (;;) + { + int c = getchar (); + if (c == EOF) + break; + else if (c == '\n') + in_quotes = false; + else if (c == '"') + { + in_quotes = !in_quotes; + in_exponent = false; + digits = 0; + } + else if (in_quotes && !in_exponent) + { + if (strchr ("+dDeE", c) != NULL || (c == '-' && digits)) + in_exponent = true; + else if (strchr ("0123456789}JKLMNOPQR", c) != NULL) + { + if (digits || c >= '1') + digits++; + if (digits > 13) + c = isdigit (c) ? '#' : '@'; + } + } + putchar (c); + } + return EXIT_SUCCESS; +} diff --git a/tests/formats/month-out.sh b/tests/formats/month-out.sh new file mode 100755 index 00000000..65d0a42e --- /dev/null +++ b/tests/formats/month-out.sh @@ -0,0 +1,996 @@ +#! /bin/sh + +TEMPDIR=/tmp/pspp-tst-$$ +mkdir -p $TEMPDIR +trap 'cd /; rm -rf $TEMPDIR' 0 + +# ensure that top_builddir are absolute +if [ -z "$top_builddir" ] ; then top_builddir=. ; fi +if [ -z "$top_srcdir" ] ; then top_srcdir=. ; fi +top_builddir=`cd $top_builddir; pwd` +PSPP=$top_builddir/src/ui/terminal/pspp + +# ensure that top_srcdir is absolute +top_srcdir=`cd $top_srcdir; pwd` + +STAT_CONFIG_PATH=$top_srcdir/config +export STAT_CONFIG_PATH + +fail() +{ + echo $activity + echo FAILED + exit 1; +} + + +no_result() +{ + echo $activity + echo NO RESULT; + exit 2; +} + +pass() +{ + exit 0; +} + +cd $TEMPDIR + +activity="write pspp syntax" +cat > month-out.pspp <) { + s/^ //; + if (scalar (my (@line) = /^([A-Z]+)(\d+)([^"]+")( *)([^%"]*)(%?")$/) == 6) { + if (defined ($prev[0]) + && $line[0] eq $prev[0] + && $line[1] == $prev[1] + 1 + && $line[2] eq $prev[2] + && $line[5] eq $prev[5]) { + if ($line[3] eq " $prev[3]" + && $line[4] eq $prev[4]) { + flush_prefix (); + flush_suffix (); + $n++; + } elsif ($line[3] eq $prev[3] + && length ($line[4]) == length ($prev[4]) + 1 + && $prev[4] eq substr ($line[4], 0, length ($line[4]) - 1)) { + flush_n (); + flush_prefix (); + $suffix .= substr ($line[4], -1); + } elsif ($line[3] eq $prev[3] + && $prev[4] eq substr ($line[4], 1)) { + flush_n (); + flush_suffix (); + $prefix .= substr ($line[4], 0, 1); + } else { + flush (); + print $_; + } + } else { + flush (); + print $_; + } + @prev = @line; + } else { + flush (); + print $_; + @prev = (); + } +} +flush (); + +sub flush_suffix { + if ($suffix ne '') { + print "\$$suffix\n"; + $suffix = ''; + } +} + +sub flush_prefix { + if ($prefix ne '') { + print "^$prefix\n"; + $prefix = ''; + } +} + +sub flush_n { + if ($n) { + print "*$n\n"; + $n = 0; + } +} + +sub flush { + flush_prefix (); + flush_suffix (); + flush_n (); +} diff --git a/tests/formats/num-out-compare.pl b/tests/formats/num-out-compare.pl new file mode 100644 index 00000000..6bf0cb79 --- /dev/null +++ b/tests/formats/num-out-compare.pl @@ -0,0 +1,122 @@ +#! /usr/bin/perl -w + +use strict; +use Getopt::Long; + +my $exact = 0; +my $spss = 0; +my $verbose = 0; +Getopt::Long::Configure ("bundling"); +GetOptions ("e|exact!" => \$exact, + "s|spss!" => \$spss, + "v|verbose+" => \$verbose, + "h|help" => sub { usage (0) }) + or usage (1); + +sub usage { + print "$0: compare expected and actual numeric formatting output\n"; + print "usage: $0 [OPTION...] EXPECTED ACTUAL\n"; + print "where EXPECTED is the file containing expected output\n"; + print "and ACTUAL is the file containing actual output.\n"; + print "Options:\n"; + print " -e, --exact: Require numbers to be exactly equal.\n"; + print " (By default, small differences are permitted.)\n"; + print " -s, --spss: Ignore most SPSS formatting bugs in EXPECTED.\n"; + print " (A few differences are not compensated)\n"; + print " -v, --verbose: Use once to summarize errors and differences.\n"; + print " Use twice for details of differences.\n"; + exit (@_); +} + +open (EXPECTED, '<', $ARGV[0]) or die "$ARGV[0]: open: $!\n"; +open (ACTUAL, '<', $ARGV[1]) or die "$ARGV[1]: open: $!\n"; +my ($expr); +my ($bad_round) = 0; +my ($approximate) = 0; +my ($spss_wtf1) = 0; +my ($spss_wtf2) = 0; +my ($lost_sign) = 0; +my ($errors) = 0; +while (defined (my $a = ) && defined (my $b = )) { + chomp $a; + chomp $b; + if ($a eq $b) { + if ($a !~ /^\s*$/ && $a !~ /:/) { + $expr = $a; + $expr =~ s/\s*$//; + $expr =~ s/^\s*//; + } + } else { + my ($fmt, $a_out) = $a =~ /^ (.*): "(.*)"$/ or die; + my ($b_fmt, $b_out) = $b =~ /^ (.*): "(.*)"$/ or die; + die if $fmt ne $b_fmt; + die if $a_out eq $b_out; + + if (!$exact) { + if (increment ($a_out) eq $b_out || increment ($b_out) eq $a_out) { + $approximate++; + next; + } + } + if ($spss) { + if ($a_out =~ /0.*0/ && $a_out !~ /[1-9]/) { + $bad_round++; + next; + } elsif ($a_out =~ /\*/ && $a_out !~ /^\*+$/) { + $spss_wtf1++; + next; + } elsif ($expr =~ /^-/ + && $a_out =~ /^\*+$/ + && $b_out =~ /-\d(\.\d*#*)?E[-+]\d\d\d/ + && $fmt =~ /^E/) { + $spss_wtf2++; + next; + } elsif ($expr =~ /^-/ + && (($a_out !~ /-/ && $a_out =~ /[1-9]/ && $b_out =~ /-/) + || ($a_out =~ /^[0-9]+$/ && $b_out =~ /^\*+$/))) { + $lost_sign++; + next; + } + } + print "$.: $expr in $fmt: expected \"$a_out\", got \"$b_out\"\n" + if $verbose > 1; + $errors++; + } +} +if ($verbose) { + print "$errors errors\n"; + if (!$exact) { + print "$approximate approximate matches\n"; + } + if ($spss) { + print "$bad_round bad rounds\n"; + print "$spss_wtf1 SPSS WTF 1\n"; + print "$spss_wtf2 SPSS WTF 2\n"; + print "$lost_sign lost signs\n"; + } +} +exit ($errors > 0); + +# Returns the argument value incremented by one unit in its final +# decimal place. +sub increment { + local ($_) = @_; + my ($last_digit, $i); + for ($i = 0; $i < length $_; $i++) { + my ($c) = substr ($_, $i, 1); + last if ($c eq 'E'); + $last_digit = $i if $c =~ /[0-9]/; + } + return $_ if !defined $last_digit; + for ($i = $last_digit; $i >= 0; $i--) { + my ($c) = substr ($_, $i, 1); + if ($c eq '9') { + substr ($_, $i, 1) = '0'; + } elsif ($c =~ /[0-8]/) { + substr ($_, $i, 1) = chr (ord ($c) + 1); + last; + } + } + $_ = "1$_" if $i < 0; + return $_; +} diff --git a/tests/formats/num-out-decmp.pl b/tests/formats/num-out-decmp.pl new file mode 100644 index 00000000..3c066fee --- /dev/null +++ b/tests/formats/num-out-decmp.pl @@ -0,0 +1,28 @@ +use warnings; +use strict; + +my (@line); +while (<>) { + if (my ($n) = /^\*(\d+)$/) { + for (1...$n) { + $line[1]++; + $line[3] = " $line[3]"; + print ' ', join ('', @line), "\n"; + } + } elsif (my ($suffix) = /^\$(.*)$/) { + for my $c (split ('', $suffix)) { + $line[1]++; + $line[4] .= $c; + print ' ', join ('', @line), "\n"; + } + } elsif (my ($prefix) = /^\^(.*)$/) { + for my $c (split ('', $prefix)) { + $line[1]++; + $line[4] = "$c$line[4]"; + print ' ', join ('', @line), "\n"; + } + } else { + @line = /^([A-Z]+)(\d+)([^"]+")( *)([^%"]*)(%?")$/; + print " $_"; + } +} diff --git a/tests/formats/num-out.expected.cmp.gz b/tests/formats/num-out.expected.cmp.gz new file mode 100644 index 0000000000000000000000000000000000000000..f1f55b1591e63f12af95b445cd9035da2511a7d9 GIT binary patch literal 206727 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

d7kSp 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 VX|BEIv+wRd`-8S_%{KgE3; num-out.pspp +if [ $? -ne 0 ] ; then no_result ; fi +echo -n . + +activity="run program" +$SUPERVISOR $PSPP --testing-mode num-out.pspp +if [ $? -ne 0 ] ; then no_result ; fi +echo -n . + +activity="inexactify results" +$top_builddir/tests/formats/inexactify < output.txt > output.inexact +if [ $? -ne 0 ] ; then no_result ; fi +echo -n . + +activity="gunzip expected results" +gzip -cd < $top_srcdir/tests/formats/num-out.expected.cmp.gz > expected.txt.cmp +if [ $? -ne 0 ] ; then no_result ; fi +echo -n . + +activity="decompress expected results" +$PERL $top_srcdir/tests/formats/num-out-decmp.pl < expected.txt.cmp > expected.txt +if [ $? -ne 0 ] ; then no_result ; fi +echo -n . + +activity="inexactify expected results" +$top_builddir/tests/formats/inexactify < expected.txt > expected.inexact +if [ $? -ne 0 ] ; then no_result ; fi +echo -n . + +activity="compare output" +$PERL $top_srcdir/tests/formats/num-out-compare.pl \ + $PSPP_NUM_OUT_COMPARE_FLAGS expected.inexact output.inexact +if [ $? -ne 0 ] ; then fail ; fi + +echo . + +pass diff --git a/tests/formats/time-out.sh b/tests/formats/time-out.sh new file mode 100755 index 00000000..c110b966 --- /dev/null +++ b/tests/formats/time-out.sh @@ -0,0 +1,13124 @@ +#! /bin/sh + +TEMPDIR=/tmp/pspp-tst-$$ +mkdir -p $TEMPDIR +trap 'cd /; rm -rf $TEMPDIR' 0 + +# ensure that top_builddir are absolute +if [ -z "$top_builddir" ] ; then top_builddir=. ; fi +if [ -z "$top_srcdir" ] ; then top_srcdir=. ; fi +top_builddir=`cd $top_builddir; pwd` +PSPP=$top_builddir/src/ui/terminal/pspp + +# ensure that top_srcdir is absolute +top_srcdir=`cd $top_srcdir; pwd` + +STAT_CONFIG_PATH=$top_srcdir/config +export STAT_CONFIG_PATH + +fail() +{ + echo $activity + echo FAILED + exit 1; +} + + +no_result() +{ + echo $activity + echo NO RESULT; + exit 2; +} + +pass() +{ + exit 0; +} + +cd $TEMPDIR + +activity="write pspp syntax" +cat > time-out.pspp < wkday-out.pspp <