From 311ba451668565366b9657b91e8300c4905dd39b Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Fri, 9 Jan 2026 14:35:32 -0800 Subject: [PATCH] fixes --- rust/doc/src/spv/light-detail.md | 23 ++++++++++++++------- rust/pspp/src/spv/read/light.rs | 10 +++++---- rust/pspp/src/spv/read/tests.rs | 6 ++++++ rust/pspp/src/spv/testdata/light5.expected | 7 +++++++ rust/pspp/src/spv/testdata/light5.spv | Bin 0 -> 2145 bytes rust/pspp/src/spv/testdata/light6.expected | 5 +++++ rust/pspp/src/spv/testdata/light6.spv | Bin 0 -> 1901 bytes 7 files changed, 39 insertions(+), 12 deletions(-) create mode 100644 rust/pspp/src/spv/testdata/light5.expected create mode 100644 rust/pspp/src/spv/testdata/light5.spv create mode 100644 rust/pspp/src/spv/testdata/light6.expected create mode 100644 rust/pspp/src/spv/testdata/light6.spv diff --git a/rust/doc/src/spv/light-detail.md b/rust/doc/src/spv/light-detail.md index 2eadec547c..5797a045b7 100644 --- a/rust/doc/src/spv/light-detail.md +++ b/rust/doc/src/spv/light-detail.md @@ -805,14 +805,21 @@ Group => `name` is the name of the category (or group). -A `Leaf` represents a leaf category. The `Leaf`'s `leaf-index` is a -nonnegative integer unique within the `Dimension` and less than -`n-categories` in the Dimension. If the user does not sort or -rearrange the categories, then `leaf-index` starts at 0 for the first -`Leaf` in the dimension and increments by 1 with each successive -`Leaf`. If the user does sort or rearrange the categories, then the -order of categories in the file reflects that change and `leaf-index` -reflects the original order. +A `Leaf` represents a leaf category. The `Leaf`'s `leaf-index` is +ordinarily a integer unique within the `Dimension` in the range +`0..n-categories`: + +- If the user does not sort or rearrange the categories, then + `leaf-index` starts at 0 for the first `Leaf` in the dimension and + increments by 1 with each successive `Leaf`. + +- If the user does sort or rearrange the categories, then the order of + categories in the file reflects that change and `leaf-index` + reflects the original order. + +- A `leaf-index` of -1 indicates a deleted category. A reader can + ignore these categories. The remaining `n` categories have + `leaf-index` in the range `0..n`. A dimension can have no leaf categories at all. A table that contains such a dimension necessarily has no data at all. diff --git a/rust/pspp/src/spv/read/light.rs b/rust/pspp/src/spv/read/light.rs index b3b9f4526b..13598369eb 100644 --- a/rust/pspp/src/spv/read/light.rs +++ b/rust/pspp/src/spv/read/light.rs @@ -179,7 +179,7 @@ impl LightTable { .iter() .map(|cell| { ( - PrecomputedIndex(cell.index as usize), + PrecomputedIndex(dbg!(cell.index) as usize), cell.value.decode(encoding, &footnotes, warn), ) }) @@ -1718,8 +1718,10 @@ impl Category { let name = self.name.decode(encoding, footnotes, warn); match &self.child { Child::Leaf { leaf_index } => { - ptod.push(*leaf_index as usize); - group.push(pivot::Leaf::new(name)); + if *leaf_index >= 0 { + ptod.push(*leaf_index as usize); + group.push(pivot::Leaf::new(name)); + } } Child::Group { merge: true, @@ -1751,7 +1753,7 @@ enum Child { #[br(magic(0u16), parse_with(parse_bool), temp)] _x24: bool, #[br(magic(b"\x02\0\0\0"))] - leaf_index: u32, + leaf_index: i32, #[br(magic(0u32), temp)] _tail: (), }, diff --git a/rust/pspp/src/spv/read/tests.rs b/rust/pspp/src/spv/read/tests.rs index 9ab4e7b6ca..40fefc6f9b 100644 --- a/rust/pspp/src/spv/read/tests.rs +++ b/rust/pspp/src/spv/read/tests.rs @@ -44,6 +44,12 @@ fn light5() { test_raw_spvfile("light5", None); } +/// Test categories to be deleted due to negative `leaf-index`. +#[test] +fn light6() { + test_raw_spvfile("light6", None); +} + #[test] fn legacy1() { test_raw_spvfile("legacy1", None); diff --git a/rust/pspp/src/spv/testdata/light5.expected b/rust/pspp/src/spv/testdata/light5.expected new file mode 100644 index 0000000000..8acd5b12b8 --- /dev/null +++ b/rust/pspp/src/spv/testdata/light5.expected @@ -0,0 +1,7 @@ + Hypothesis Test Summary + Null Hypothesis │ Test │Sig.[a,b]│ Decision +─────────────────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────┼─────────┼─────────────────────────── +1 The distributions of Variable0000001, Variable0000002 and Variable0000003 are the same.│Related-Samples Friedman's Two-Way Analysis of Variance by Ranks│ .164│Retain the null hypothesis. +─────────────────────────────────────────────────────────────────────────────────────────┴────────────────────────────────────────────────────────────────┴─────────┴─────────────────────────── +a. The significance level is .050. +b. Asymptotic significance is displayed. diff --git a/rust/pspp/src/spv/testdata/light5.spv b/rust/pspp/src/spv/testdata/light5.spv new file mode 100644 index 0000000000000000000000000000000000000000..55951cd1f5efc305fae6b3c6ec442e13ff676aac GIT binary patch literal 2145 zcmaKtc|4SP7{FhQJL4MGEfMP&cdm$$Ge?%8Xr!4Evom9cW{{b(L$ugz2%%P!NjcZJ z?+9(KT-k({Esa5g)sE284((RETl;%I&+qel|9HR8^Z9+=@AG)M@qr)!00;q4H*G}P z$f|D&9{@Co0Dv-}1Q@kfKEa9uSNB z?ao%_*MC?V2FYi8xBg*&C3IO`G4oqSV55+bhCp%XOq_5^W0ERq+;i?eyLL`bwdJg# zO3Ok{isp(z^l#Hoss!!tb$1eed&WPNw|Ip%%=--U%fmc#{P|bEBf z`o}ieWs&8)ISyX2JLopYWUwJfTPEK6xxP75PJ9=c=5^yma=dijcbJPg?xhEzYzs-L z#DjE#vW3E`@&YeqcBOB6v3ZF(xr<}cw>-Az)h>V>mXlg_JIOtt$=dvCWlMSZqOjm- zj4CC)+51cWuD1S{o!>n1&(5|EK>GW1R^l-pH!yyJ6x{royv(OcY6j^wWe#8SwO*@` zicdnSF+rn=$EXt>Y-dYvaq}EVWZEDTAnaM~XeV9#j(L<0^_V6Kn_Cz=I7{_6XK++- zfHPR&3*iQmZMzOZk9s$-r9&GhHho|->~fRQ+AYO{YB8;2x7bFs^J^wd7jhf=V>_4332a&f{v5n zm`Mf27WtSa-l053D2r$z)of7R-q96F@i0k1;>;jug z!TNdE^idL1=8Y?3DjH z6Er1QPC_QzV^&j&tY014?+h4rW;zz1)C`fe9vEviOVDj%)ocVy0_L}v`y=U@g#k|% zo6)|rew?)^wnonjQH`$#kKTO1Au@vXo=4QN_E%n|+XpNpN3Af^B2tWNH-!wTZ+vY_ zkFPx}T+9s2g0{(9*1;+6x^=o$k7B!hvYt=#d}9FA$I^60M0rXFE}d(3;KLR;LOekXqYoI|g^2U$OVuuSvSU7jHTRQS{?gVT z#%eyad}$2m5y!EdqSr_%V-@3RHrQ%gFRtNSow(&Z^yrE{(w+App6jJx(b!zBDMqaF~S4p>FVU@1K0O(+M$K2f3i0qu~>YR7djG8 zM2Cgg5F<#z+x&M;Xq)dMC(taw3jiYg0HDC-<4HsUiRgz8jtY)=-;WISqjA{(%aVB| z2%l#t(RMfa#cUi^0~fb@lzwNtu(l-2eSG3n8-L0DTCB9a?Iw8mGBIFpkLc{H&4;fC zJj29m?8v9}ju>~*R8MrCDi_i3g}fbqde)87tSj@3l_toqb@b;h zSYNG^ij#aPpB~RMBmc!DNn7Pq=sV^7^9M!nE+qlLlRB20ZnK~N~gx>^uM*q7O* z&R%+5ke;g`asAhIJNsE|2HQ%kN!6k&boqBNOpg1+$UZ8fcvj) y?{GZaTItlippS6>aF0vgcJGsge$KOx$q8KY|5^7rKEJ^BErPfYmRsV~&fA~phF5d| literal 0 HcmV?d00001 diff --git a/rust/pspp/src/spv/testdata/light6.expected b/rust/pspp/src/spv/testdata/light6.expected new file mode 100644 index 0000000000..d0ceed0749 --- /dev/null +++ b/rust/pspp/src/spv/testdata/light6.expected @@ -0,0 +1,5 @@ +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Frequency│Percent +────────────────────────┼─────── +Missing System 21│ 100.0 +────────────────────────┴─────── diff --git a/rust/pspp/src/spv/testdata/light6.spv b/rust/pspp/src/spv/testdata/light6.spv new file mode 100644 index 0000000000000000000000000000000000000000..b48fd3780d52b49dbc5df654cc747b73541fe0f7 GIT binary patch literal 1901 zcmWIWW@Zs#U|`^2sLa-kx%ur!a1#>)!z~U523ZCf1_L;V&&f>BC<#eS%1L!eEJ@T$ z%FGK5;bdUGR+N}o2gIcn+zgB?FPIq^z{J+jvw4>t1nzB}ZMHC=PCHc8$s@+$RKM)Q z2?~lrTb-CzYMl_7Ir(*)Z|ap@s;}Liu&|$t+4+t2gmuAVL#4ighliFFMtz7dWr=m!yoSpZA*9+KQ*u7}Knt%WQpBT#%7LqUaZqV8Oho|TJ zbG2D^+%^8U-rSYro@Mu#uf&sU@w5Nk?>icQ1uZ<;;nqOtRf z6DcLTuDmQ1TYbThxn4a@eG&h{-&F=n%1nRc@+>{w7rgspnV4q1yFuA{?+%`4?;|gq z;oN=wbz-OJpROi+Y)c+_?FW{jAx+6=|aK ziynxJ)USG=v{1r3%iT_X(IPGpmfNgGQEAg6Pv5@H<-MP_{V`WcV_(a1sMl$E#pF_(CT+Xt zbsJvZVW_s=bayVVM!|9JzjGV3?OxS<6nQXl`)-?*+kCrnKk2b|?PS?oYhh>=5maK+ zU&g^$@xpv(v-@oI*y|>JeU~+KObjQ^3;vfC%U->9M|sMNh?Fy*Ewjxd1-j;xD@Qjz z)_gVFdurXRNmftt+-`;0ek{sp+PCgMYXC4|a{&`J1A{6sVS^b^f)kjqeO*Hwbv^yu z^udYP6qtZP7%dSajHt}ijA2)wp(_M50)$17jqr8!^K^3!4$<><1Dht6k2Omq=H%p; z2V|Dzmt^Lp+m;lSrh?3e<~^YKxeB%A(!ji@$;!YW1vEduw4|W4BrG$vJhcd(4Gr`v za&z$6GIfe~{%r%EhW}j)igS-cBq8F{M*HE7qS-bvG}U$cIaaplISD+{c9HIy@wPA|E{ z!a0*|+9$19Uh;lN#NS5A@<00H;-h|f=ZQ}`r|nZ8eRI2WZ|&2GUkf!u-%1Cx@@ge; zyt?#$&evVLOa#5m0$K~3OO0C0=6WX9{`@f4nekiEdfg@wnSFrz7*F z^i|HR>;(3YFQ*5zq^sS}dz6tUT)Kk&f{od?`!B8~tX^CBrrYF(`PCQAQt^$l2Mp{s zFEDR#$dyP~a?#+@!F^X+yFPxsay0vceP|``H(@-@n%J?Q!Cb%f{Q? zjSF_))w?@)nO)wM5~Gt>*3W*udsCa6`Z2}K@G{LsCpU)2{oa)SzCB4yeuM9(l3DLI zPFmf1mG#Ee?bDpRxl3boz219Bvj>)Ns@B{$lj&)#_UqGMpxI+u5^*Z-**BZrKO>uk zuPK!3M=AwtY+21BH_Kt)!@2-orGlad9M#?{iW;}}KVb;`Q5{%vev_Qj!`+j<%ZkqN zKYVWAtH&M<_PYIo%x^?)C)IMi-)j4Hro5ZcX|>I7O6;uXpHENUY@EmN{@a0%WqYlj z_9aCJNk3fiSaC_d<(#W2KkAANv!cq6P2V&7lTPFc^KHkUR+sC0O>1Y`{Kw>HSUqEa zHzSiAGp@p30-i;dG=i9jB!{)=XN45~7&!)H1+HudvqFI3t>aB#N=M3sK;y7xK!kCa zSrB3zBhal&8fAbL58ODE3<)$Dlp(P?6j$a$Hn|39GQO;c%Y0TgP$;qhVGhuVuYsAG GfdK%86VrnL literal 0 HcmV?d00001 -- 2.30.2