1use std::sync::atomic::Ordering;
7
8use crate::ported::zle::zle_h::{ZC_iblank, MOD_MULT};
9
10#[allow(unused_imports)]
11use crate::ported::zle::{
12 deltochar::*, zle_hist::*, zle_main::*, zle_misc::*, zle_move::*, zle_params::*,
13 zle_refresh::*, zle_tricky::*, zle_utils::*, zle_vi::*, zle_word::*,
14};
15#[allow(unused_imports)]
21#[allow(unused_imports)]
22
23pub fn blankwordclass(x: char) -> i32 {
24 if ZC_iblank(x) {
29 0
30 } else {
31 1
32 } }
34
35pub fn selectword() -> i32 {
52 let mut n: i32 = if ZMOD.lock().unwrap().flags & MOD_MULT != 0 {
54 ZMOD.lock().unwrap().mult
56 } else {
57 1
58 };
59 let widget = BINDK
60 .lock()
61 .unwrap()
62 .as_ref()
63 .map(|t| t.nam.clone())
64 .unwrap_or_default();
65 let widget = widget.as_str();
66 let is_aword = widget == "select-a-word";
67 let is_inword = widget == "select-in-word";
68 let is_ablankword = widget == "select-a-blank-word";
69 let mut all: i32 = (is_aword || is_ablankword) as i32; let viclass: fn(char) -> i32 = if is_aword || is_inword {
71 wordclass } else {
73 blankwordclass
74 };
75 if ZLELL.load(Ordering::SeqCst) == 0 {
76 return 1;
77 }
78 let cur = ZLELINE
79 .lock()
80 .unwrap()
81 .get(ZLECS.load(Ordering::SeqCst))
82 .copied()
83 .unwrap_or('\n');
84 let mut sclass: i32 = viclass(cur); let mut doblanks: i32 = all & ((sclass != 0) as i32); let region_active = REGION_ACTIVE.load(Ordering::SeqCst) != 0; if !region_active || ZLECS.load(Ordering::SeqCst) == MARK.load(Ordering::SeqCst) {
94 MARK.store(ZLECS.load(Ordering::SeqCst), Ordering::SeqCst); while MARK.load(Ordering::SeqCst) != 0 {
99 let pos = MARK.load(Ordering::SeqCst) - 1; let cp = ZLELINE.lock().unwrap().get(pos).copied().unwrap_or('\n');
102 if cp == '\n' || viclass(cp) != sclass {
103 break; }
106 MARK.store(pos, Ordering::SeqCst);
107 }
109 while ZLECS.load(Ordering::SeqCst) < ZLELL.load(Ordering::SeqCst) {
111 ZLECS.fetch_add(1, Ordering::SeqCst); let mut pos = ZLECS.load(Ordering::SeqCst); if all != 0 && sclass == 0 && pos < ZLELL.load(Ordering::SeqCst) && ZLELINE.lock().unwrap().get(pos).copied() == Some('\n')
117 {
118 pos += 1; }
120 let pc = ZLELINE.lock().unwrap().get(pos).copied().unwrap_or('\n');
121 if pc == '\n' || viclass(pc) != sclass {
122 break; }
125 }
126
127 if all != 0 {
128 let cc = ZLELINE
130 .lock()
131 .unwrap()
132 .get(ZLECS.load(Ordering::SeqCst))
133 .copied()
134 .unwrap_or('\n');
135 let nclass = viclass(cc); if nclass == 0 || sclass == 0 {
139 while ZLECS.load(Ordering::SeqCst) < ZLELL.load(Ordering::SeqCst) {
141 ZLECS.fetch_add(1, Ordering::SeqCst); let cc = ZLELINE
144 .lock()
145 .unwrap()
146 .get(ZLECS.load(Ordering::SeqCst))
147 .copied()
148 .unwrap_or('\n');
149 if cc == '\n' || viclass(cc) != nclass {
150 break; }
153 }
154 if n < 2 {
155 doblanks = 0; }
158 }
159 }
160 } else {
161 if ZLECS.load(Ordering::SeqCst) > MARK.load(Ordering::SeqCst) {
165 if ZLECS.load(Ordering::SeqCst) < ZLELL.load(Ordering::SeqCst) {
167 ZLECS.fetch_add(1, Ordering::SeqCst); }
170 } else if ZLECS.load(Ordering::SeqCst) != 0 {
171 ZLECS.fetch_sub(1, Ordering::SeqCst);
173 }
175 if ZLECS.load(Ordering::SeqCst) < MARK.load(Ordering::SeqCst) {
176 while {
180 let cont = n > 0;
181 n -= 1;
182 cont
183 } {
184 let mut pos = ZLECS.load(Ordering::SeqCst); let zc_pos = ZLELINE.lock().unwrap().get(pos).copied().unwrap_or('\n');
187 if all != 0 && (viclass(zc_pos) == 0 || zc_pos == '\n') {
189 all = 0; while pos != 0 {
192 pos -= 1; let pc = ZLELINE.lock().unwrap().get(pos).copied().unwrap_or('\n');
195 if pc == '\n' {
196 break; }
199 ZLECS.store(pos, Ordering::SeqCst); if viclass(pc) != 0 {
201 break; }
204 }
205 } else if ZLECS.load(Ordering::SeqCst) != 0
206 && ZLELINE
207 .lock()
208 .unwrap()
209 .get(ZLECS.load(Ordering::SeqCst))
210 .copied()
211 == Some('\n')
212 {
213 pos -= 1; let pc = ZLELINE.lock().unwrap().get(pos).copied().unwrap_or('\n');
217 if pc != '\n' {
218 ZLECS.store(pos, Ordering::SeqCst); }
221 }
222 pos = ZLECS.load(Ordering::SeqCst); let cur = ZLELINE
224 .lock()
225 .unwrap()
226 .get(ZLECS.load(Ordering::SeqCst))
227 .copied()
228 .unwrap_or('\n');
229 sclass = viclass(cur); loop {
232 let pc = ZLELINE.lock().unwrap().get(pos).copied().unwrap_or('\n');
234 if pc == '\n' || viclass(pc) != sclass {
235 break;
236 }
237 ZLECS.store(pos, Ordering::SeqCst); if pos == 0 {
239 ZLECS.store(0, Ordering::SeqCst); break; }
243 pos -= 1; }
245 if all != 0 && ZLECS.load(Ordering::SeqCst) != 0 {
247 pos = ZLECS.load(Ordering::SeqCst);
249 pos -= 1; let pc = ZLELINE.lock().unwrap().get(pos).copied().unwrap_or('\n');
251 if viclass(pc) == 0 {
252 while pos != 0 {
254 pos -= 1; let pc = ZLELINE.lock().unwrap().get(pos).copied().unwrap_or('\n');
257 if pc == '\n' || viclass(pc) != 0 {
258 break; }
261 ZLECS.store(pos, Ordering::SeqCst);
262 }
264 }
265 }
266 }
267 return 0; }
269 n += 1; doblanks = 0; }
272 REGION_ACTIVE.store(if region_active { 1 } else { 0 }, Ordering::SeqCst);
274
275 while {
277 n -= 1;
278 n > 0
279 } {
280 if ZLECS.load(Ordering::SeqCst) < ZLELL.load(Ordering::SeqCst)
282 && ZLELINE
283 .lock()
284 .unwrap()
285 .get(ZLECS.load(Ordering::SeqCst))
286 .copied()
287 == Some('\n')
288 {
289 ZLECS.fetch_add(1, Ordering::SeqCst);
291 }
293 let cur = ZLELINE
294 .lock()
295 .unwrap()
296 .get(ZLECS.load(Ordering::SeqCst))
297 .copied()
298 .unwrap_or('\n');
299 sclass = viclass(cur); while ZLECS.load(Ordering::SeqCst) < ZLELL.load(Ordering::SeqCst) {
301 ZLECS.fetch_add(1, Ordering::SeqCst); let cc = ZLELINE
304 .lock()
305 .unwrap()
306 .get(ZLECS.load(Ordering::SeqCst))
307 .copied()
308 .unwrap_or('\n');
309 if cc == '\n' || viclass(cc) != sclass {
310 break; }
313 }
314 if all != 0 {
316 if ZLECS.load(Ordering::SeqCst) < ZLELL.load(Ordering::SeqCst)
318 && ZLELINE
319 .lock()
320 .unwrap()
321 .get(ZLECS.load(Ordering::SeqCst))
322 .copied()
323 == Some('\n')
324 {
325 ZLECS.fetch_add(1, Ordering::SeqCst); }
328 let cc = ZLELINE
329 .lock()
330 .unwrap()
331 .get(ZLECS.load(Ordering::SeqCst))
332 .copied()
333 .unwrap_or('\n');
334 let cls_here = viclass(cc);
335 if sclass == 0 || cls_here == 0 {
336 sclass = cls_here; if n == 1 && sclass == 0 {
339 doblanks = 0; }
342 while ZLECS.load(Ordering::SeqCst) < ZLELL.load(Ordering::SeqCst) {
343 ZLECS.fetch_add(1, Ordering::SeqCst); let cc = ZLELINE
346 .lock()
347 .unwrap()
348 .get(ZLECS.load(Ordering::SeqCst))
349 .copied()
350 .unwrap_or('\n');
351 if cc == '\n' || viclass(cc) != sclass {
352 break; }
355 }
356 }
357 }
358 }
359
360 if doblanks != 0 {
362 let mut pos = MARK.load(Ordering::SeqCst); while pos != 0 {
365 pos -= 1; let pc = ZLELINE.lock().unwrap().get(pos).copied().unwrap_or('\n');
369 if pc == '\n' {
370 break; }
373 if !ZC_iblank(pc) {
374 pos += 1; MARK.store(pos, Ordering::SeqCst); break; }
379 }
380 }
381 let virangeflag = VIRANGEFLAG.load(Ordering::Relaxed) != 0;
390 if !virangeflag {
391 if !in_vi_cmd_mode() {
393 REGION_ACTIVE.store(1, Ordering::SeqCst); } else if ZLECS.load(Ordering::SeqCst) != 0
396 && ZLECS.load(Ordering::SeqCst) > MARK.load(Ordering::SeqCst)
397 {
398 ZLECS.fetch_sub(1, Ordering::SeqCst);
400 }
402 }
403
404 0 }
406
407pub fn selectargument() -> i32 {
418 let n: i32 = if ZMOD.lock().unwrap().flags & MOD_MULT != 0 {
420 ZMOD.lock().unwrap().mult } else {
422 1
423 };
424 if n < 1 || (2 * n as usize) > ZLELL.load(Ordering::SeqCst) + 1 {
425 return 1;
427 }
428 if !in_vi_cmd_mode() {
429 REGION_ACTIVE.store(1, Ordering::SeqCst); MARK.store(ZLECS.load(Ordering::SeqCst), Ordering::SeqCst); }
433 let mut starts: Vec<usize> = Vec::with_capacity(n as usize);
436 let mut in_word = false;
437 let mut word_start = 0usize;
438 starts.push(0);
439 for (i, &c) in ZLELINE.lock().unwrap().iter().enumerate() {
440 if c.is_whitespace() {
441 if in_word {
442 in_word = false;
443 if starts.len() < n as usize {
444 starts.push(i + 1);
445 }
446 }
447 } else if !in_word {
448 in_word = true;
449 word_start = i;
450 if i >= ZLECS.load(Ordering::SeqCst) {
451 break;
452 }
453 }
454 }
455 let arg_idx = (n - 1) as usize;
456 let s = starts.get(arg_idx).copied().unwrap_or(word_start);
457 let e = (s..ZLELL.load(Ordering::SeqCst))
458 .find(|&i| {
459 ZLELINE
460 .lock()
461 .unwrap()
462 .get(i)
463 .copied()
464 .map_or(true, |c| c.is_whitespace())
465 })
466 .unwrap_or(ZLELL.load(Ordering::SeqCst));
467 MARK.store(s, Ordering::SeqCst);
468 ZLECS.store(e, Ordering::SeqCst);
469 if in_vi_cmd_mode() && ZLECS.load(Ordering::SeqCst) > 0 {
470 ZLECS.fetch_sub(1, Ordering::SeqCst);
471 }
472 0
473}
474
475#[cfg(test)]
476mod tests {
477 use super::*;
478
479 #[test]
483 fn blankwordclass_classifies_whitespace_vs_word_chars() {
484 let _g = crate::test_util::global_state_lock();
485 assert_eq!(blankwordclass(' '), 0, "space is iblank");
486 assert_eq!(blankwordclass('\t'), 0, "tab is iblank");
487 assert_eq!(blankwordclass('a'), 1, "letter is not iblank");
488 assert_eq!(blankwordclass('0'), 1, "digit is not iblank");
489 assert_eq!(blankwordclass('!'), 1, "punctuation is not iblank");
490 assert_eq!(
491 blankwordclass('\n'),
492 1,
493 "newline is NOT iblank per ZC_iblank semantics"
494 );
495 }
496
497 #[test]
504 fn blankwordclass_non_ascii_letters_are_not_iblank() {
505 let _g = crate::test_util::global_state_lock();
506 assert_eq!(blankwordclass('é'), 1, "Latin-1 letter: not iswspace");
507 assert_eq!(blankwordclass('字'), 1, "CJK ideograph: not iswspace");
508 assert_eq!(blankwordclass('α'), 1, "Greek letter: not iswspace");
509 }
510
511 #[test]
518 fn blankwordclass_wide_whitespace_classes_are_iblank() {
519 let _g = crate::test_util::global_state_lock();
520 assert_eq!(blankwordclass('\r'), 0, "CR is iblank per wcsiblank");
521 assert_eq!(blankwordclass('\x0c'), 0, "FF is iblank per wcsiblank");
522 assert_eq!(blankwordclass('\x0b'), 0, "VT is iblank per wcsiblank");
523 assert_eq!(
524 blankwordclass('\u{00A0}'),
525 0,
526 "NBSP is iblank per wcsiblank"
527 );
528 }
529
530 #[test]
537 fn selectargument_returns_one_on_empty_buffer() {
538 let _g = crate::test_util::global_state_lock();
539 let _g = zle_test_setup();
540 assert_eq!(
541 selectargument(),
542 1,
543 "c:225 — empty buffer fails 2*n > zlell+1"
544 );
545 }
546
547 #[test]
551 fn blankwordclass_digits_and_underscore_are_word_chars() {
552 let _g = crate::test_util::global_state_lock();
553 for d in '0'..='9' {
554 assert_eq!(blankwordclass(d), 1, "digit {:?} must NOT be iblank", d);
555 }
556 assert_eq!(blankwordclass('_'), 1, "underscore is a word char");
557 }
558
559 #[test]
564 fn blankwordclass_nul_is_not_iblank() {
565 let _g = crate::test_util::global_state_lock();
566 assert_eq!(
567 blankwordclass('\0'),
568 1,
569 "NUL byte must classify as non-iblank per wcsiblank semantics"
570 );
571 }
572
573 #[test]
578 fn blankwordclass_non_bmp_chars_are_word_chars() {
579 let _g = crate::test_util::global_state_lock();
580 assert_eq!(blankwordclass('\u{1F600}'), 1, "emoji is non-iblank");
581 assert_eq!(blankwordclass('\u{2603}'), 1, "snowman is non-iblank");
582 }
583
584 #[test]
589 fn selectargument_empty_buffer_leaves_mark_and_zlecs_unchanged() {
590 let _g = crate::test_util::global_state_lock();
591 let _g = zle_test_setup();
592 MARK.store(42, Ordering::SeqCst);
593 ZLECS.store(7, Ordering::SeqCst);
594 let r = selectargument();
595 assert_eq!(r, 1);
596 assert_eq!(
597 MARK.load(Ordering::SeqCst),
598 42,
599 "MARK must not be touched on the c:225 guard branch"
600 );
601 assert_eq!(
602 ZLECS.load(Ordering::SeqCst),
603 7,
604 "ZLECS must not be touched on the c:225 guard branch"
605 );
606 }
607
608 #[test]
613 fn selectargument_zero_mult_returns_one() {
614 let _g = crate::test_util::global_state_lock();
615 let _g = zle_test_setup();
616 *ZLELINE.lock().unwrap() = "hello world".chars().collect();
617 ZLELL.store(11, Ordering::SeqCst);
618 ZLECS.store(0, Ordering::SeqCst);
619 let mut z = ZMOD.lock().unwrap();
620 z.flags = MOD_MULT;
621 z.mult = 0;
622 drop(z);
623 assert_eq!(selectargument(), 1, "n<1 guard branch must fire");
624 }
625
626 #[test]
630 fn selectargument_negative_mult_returns_one() {
631 let _g = crate::test_util::global_state_lock();
632 let _g = zle_test_setup();
633 *ZLELINE.lock().unwrap() = "hello world".chars().collect();
634 ZLELL.store(11, Ordering::SeqCst);
635 ZLECS.store(0, Ordering::SeqCst);
636 let mut z = ZMOD.lock().unwrap();
637 z.flags = MOD_MULT;
638 z.mult = -1;
639 drop(z);
640 assert_eq!(
641 selectargument(),
642 1,
643 "negative count must fail the n<1 guard"
644 );
645 }
646
647 #[test]
651 fn blankwordclass_pure_space_is_iblank() {
652 let _g = crate::test_util::global_state_lock();
653 assert_eq!(blankwordclass(' '), 0, "space MUST be iblank (class 0)");
654 }
655
656 #[test]
658 fn blankwordclass_tab_is_iblank() {
659 let _g = crate::test_util::global_state_lock();
660 assert_eq!(blankwordclass('\t'), 0, "tab MUST be iblank (class 0)");
661 }
662
663 #[test]
669 fn blankwordclass_newline_is_NOT_iblank() {
670 let _g = crate::test_util::global_state_lock();
671 assert_eq!(
672 blankwordclass('\n'),
673 1,
674 "newline must NOT be iblank per wcsiblank's explicit exclusion"
675 );
676 }
677
678 #[test]
682 fn blankwordclass_is_idempotent() {
683 let _g = crate::test_util::global_state_lock();
684 for _ in 0..1000 {
685 assert_eq!(blankwordclass('a'), 1);
686 assert_eq!(blankwordclass(' '), 0);
687 assert_eq!(blankwordclass('\n'), 1);
688 }
689 }
690
691 #[test]
696 fn selectargument_whitespace_only_buffer_does_not_panic() {
697 let _g = crate::test_util::global_state_lock();
698 let _g = zle_test_setup();
699 *ZLELINE.lock().unwrap() = " ".chars().collect();
700 ZLELL.store(3, Ordering::SeqCst);
701 ZLECS.store(1, Ordering::SeqCst);
702 let _ = selectargument();
703 }
704
705 #[test]
712 fn blankwordclass_vertical_tab_is_iblank() {
713 let _g = crate::test_util::global_state_lock();
714 assert_eq!(
715 blankwordclass('\x0b'),
716 0,
717 "VT is whitespace (excl. newline)"
718 );
719 }
720
721 #[test]
723 fn blankwordclass_form_feed_is_iblank() {
724 let _g = crate::test_util::global_state_lock();
725 assert_eq!(
726 blankwordclass('\x0c'),
727 0,
728 "FF is whitespace (excl. newline)"
729 );
730 }
731
732 #[test]
735 fn blankwordclass_carriage_return_is_iblank() {
736 let _g = crate::test_util::global_state_lock();
737 assert_eq!(blankwordclass('\r'), 0, "CR is whitespace (excl. newline)");
738 }
739
740 #[test]
742 fn blankwordclass_returns_boolean_i32_only() {
743 let _g = crate::test_util::global_state_lock();
744 for c in (0u32..0x10000).step_by(1024).filter_map(char::from_u32) {
745 let r = blankwordclass(c);
746 assert!(
747 r == 0 || r == 1,
748 "blankwordclass({:?}) = {} not in 0/1",
749 c,
750 r
751 );
752 }
753 }
754
755 #[test]
758 fn selectargument_n_zero_returns_one() {
759 let _g = crate::test_util::global_state_lock();
760 let _g2 = zle_test_setup();
761 ZMOD.lock().unwrap().flags |= MOD_MULT;
762 ZMOD.lock().unwrap().mult = 0;
763 *ZLELINE.lock().unwrap() = "hello world".chars().collect();
764 ZLELL.store(11, Ordering::SeqCst);
765 ZLECS.store(0, Ordering::SeqCst);
766 assert_eq!(selectargument(), 1, "n=0 hits n<1 guard");
767 ZMOD.lock().unwrap().flags &= !MOD_MULT;
768 }
769
770 #[test]
772 fn selectargument_n_too_large_returns_one() {
773 let _g = crate::test_util::global_state_lock();
774 let _g2 = zle_test_setup();
775 ZMOD.lock().unwrap().flags |= MOD_MULT;
776 ZMOD.lock().unwrap().mult = 100; *ZLELINE.lock().unwrap() = "hi".chars().collect();
778 ZLELL.store(2, Ordering::SeqCst);
779 ZLECS.store(0, Ordering::SeqCst);
780 assert_eq!(selectargument(), 1, "n=100 vs zlell=2 hits guard");
781 ZMOD.lock().unwrap().flags &= !MOD_MULT;
782 }
783
784 #[test]
789 fn blankwordclass_ascii_matches_c_isspace_excluding_newline() {
790 let _g = crate::test_util::global_state_lock();
791 const IBLANK: &[char] = &[' ', '\t', '\x0b', '\x0c', '\r'];
794 for b in 0u8..128 {
795 let c = b as char;
796 let want = if IBLANK.contains(&c) { 0 } else { 1 };
797 assert_eq!(
798 blankwordclass(c),
799 want,
800 "blankwordclass(0x{:02x}) mismatch — C isspace excl '\\n'",
801 b
802 );
803 }
804 }
805
806 #[test]
813 fn blankwordclass_is_pure_no_side_effects() {
814 let _g = crate::test_util::global_state_lock();
815 let _g2 = zle_test_setup();
816 let cs = ZLECS.load(Ordering::SeqCst);
817 let ll = ZLELL.load(Ordering::SeqCst);
818 for c in [' ', 'a', '0', '_', '\t', '\n', '\x0b'] {
819 let _ = blankwordclass(c);
820 }
821 assert_eq!(ZLECS.load(Ordering::SeqCst), cs);
822 assert_eq!(ZLELL.load(Ordering::SeqCst), ll);
823 }
824
825 #[test]
827 fn blankwordclass_newline_returns_one() {
828 let _g = crate::test_util::global_state_lock();
829 assert_eq!(blankwordclass('\n'), 1, "\\n is excluded from iblank");
830 }
831
832 #[test]
834 fn blankwordclass_del_returns_one() {
835 let _g = crate::test_util::global_state_lock();
836 assert_eq!(blankwordclass('\x7f'), 1, "DEL is not whitespace");
837 }
838
839 #[test]
843 fn blankwordclass_nbsp_returns_bool_i32() {
844 let _g = crate::test_util::global_state_lock();
845 let r = blankwordclass('\u{00A0}');
846 assert!(r == 0 || r == 1, "NBSP must return 0 or 1, got {}", r);
847 }
848
849 #[test]
851 fn blankwordclass_returns_i32_type() {
852 let _: i32 = blankwordclass(' ');
853 }
854
855 #[test]
857 fn selectword_returns_i32_type() {
858 let _: i32 = std::convert::identity::<fn() -> i32>(selectword)();
859 }
860
861 #[test]
863 fn selectword_empty_buffer_no_panic() {
864 let _g = crate::test_util::global_state_lock();
865 let _g2 = zle_test_setup();
866 *ZLELINE.lock().unwrap() = Vec::new();
867 ZLELL.store(0, Ordering::SeqCst);
868 ZLECS.store(0, Ordering::SeqCst);
869 let _ = selectword();
870 }
871
872 #[test]
874 fn selectword_single_char_buffer_no_panic() {
875 let _g = crate::test_util::global_state_lock();
876 let _g2 = zle_test_setup();
877 *ZLELINE.lock().unwrap() = vec!['a'];
878 ZLELL.store(1, Ordering::SeqCst);
879 ZLECS.store(0, Ordering::SeqCst);
880 let _ = selectword();
881 }
882
883 #[test]
886 fn selectword_cursor_past_zlell_no_panic() {
887 let _g = crate::test_util::global_state_lock();
888 let _g2 = zle_test_setup();
889 *ZLELINE.lock().unwrap() = vec!['h', 'i'];
890 ZLELL.store(2, Ordering::SeqCst);
891 ZLECS.store(2, Ordering::SeqCst); let _ = selectword();
893 }
894
895 #[test]
897 fn selectword_deterministic_on_identical_state() {
898 let _g = crate::test_util::global_state_lock();
899 let _g2 = zle_test_setup();
900 *ZLELINE.lock().unwrap() = "hello world".chars().collect();
901 ZLELL.store(11, Ordering::SeqCst);
902 ZLECS.store(3, Ordering::SeqCst);
903 let first = selectword();
904 ZLECS.store(3, Ordering::SeqCst);
905 let second = selectword();
906 assert_eq!(first, second, "selectword must be deterministic");
907 }
908
909 #[test]
911 fn selectargument_returns_i32_type() {
912 let _: i32 = std::convert::identity::<fn() -> i32>(selectargument)();
913 }
914
915 #[test]
917 fn selectargument_n_one_single_char_no_panic() {
918 let _g = crate::test_util::global_state_lock();
919 let _g2 = zle_test_setup();
920 ZMOD.lock().unwrap().flags |= MOD_MULT;
921 ZMOD.lock().unwrap().mult = 1;
922 *ZLELINE.lock().unwrap() = vec!['x'];
923 ZLELL.store(1, Ordering::SeqCst);
924 ZLECS.store(0, Ordering::SeqCst);
925 let _ = selectargument();
926 ZMOD.lock().unwrap().flags &= !MOD_MULT;
927 }
928}