@@ -169,6 +169,7 @@ static void f_pyeval(typval_T *argvars, typval_T *rettv);
169169#if defined(FEAT_PYTHON ) || defined(FEAT_PYTHON3 )
170170static void f_pyxeval (typval_T * argvars , typval_T * rettv );
171171#endif
172+ static void f_rand (typval_T * argvars , typval_T * rettv );
172173static void f_range (typval_T * argvars , typval_T * rettv );
173174static void f_reg_executing (typval_T * argvars , typval_T * rettv );
174175static void f_reg_recording (typval_T * argvars , typval_T * rettv );
@@ -225,6 +226,7 @@ static void f_spellsuggest(typval_T *argvars, typval_T *rettv);
225226static void f_split (typval_T * argvars , typval_T * rettv );
226227#ifdef FEAT_FLOAT
227228static void f_sqrt (typval_T * argvars , typval_T * rettv );
229+ static void f_srand (typval_T * argvars , typval_T * rettv );
228230static void f_str2float (typval_T * argvars , typval_T * rettv );
229231#endif
230232static void f_str2list (typval_T * argvars , typval_T * rettv );
@@ -634,6 +636,7 @@ static funcentry_T global_functions[] =
634636#if defined(FEAT_PYTHON ) || defined (FEAT_PYTHON3 )
635637 {"pyxeval" , 1 , 1 , FEARG_1 , f_pyxeval },
636638#endif
639+ {"rand" , 0 , 1 , FEARG_1 , f_rand },
637640 {"range" , 1 , 3 , FEARG_1 , f_range },
638641 {"readdir" , 1 , 2 , FEARG_1 , f_readdir },
639642 {"readfile" , 1 , 3 , FEARG_1 , f_readfile },
@@ -725,6 +728,7 @@ static funcentry_T global_functions[] =
725728 {"split" , 1 , 3 , FEARG_1 , f_split },
726729#ifdef FEAT_FLOAT
727730 {"sqrt" , 1 , 1 , FEARG_1 , f_sqrt },
731+ {"srand" , 0 , 1 , FEARG_1 , f_srand },
728732#endif
729733 {"state" , 0 , 1 , FEARG_1 , f_state },
730734#ifdef FEAT_FLOAT
@@ -5128,6 +5132,79 @@ f_pyxeval(typval_T *argvars, typval_T *rettv)
51285132}
51295133#endif
51305134
5135+ /*
5136+ * "rand()" function
5137+ */
5138+ static void
5139+ f_rand (typval_T * argvars , typval_T * rettv )
5140+ {
5141+ list_T * l = NULL ;
5142+ UINT32_T x , y , z , w , t ;
5143+ static int rand_seed_initialized = FALSE;
5144+ static UINT32_T xyzw [4 ] = {123456789 , 362436069 , 521288629 , 88675123 };
5145+
5146+ #define SHUFFLE_XORSHIFT128 \
5147+ t = x ^ (x << 11); \
5148+ x = y; y = z; z = w; \
5149+ w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
5150+
5151+ if (argvars [0 ].v_type == VAR_UNKNOWN )
5152+ {
5153+ // When argument is not given, return random number initialized
5154+ // statically.
5155+ if (!rand_seed_initialized )
5156+ {
5157+ xyzw [0 ] = (varnumber_T )time (NULL );
5158+ rand_seed_initialized = TRUE;
5159+ }
5160+
5161+ x = xyzw [0 ];
5162+ y = xyzw [1 ];
5163+ z = xyzw [2 ];
5164+ w = xyzw [3 ];
5165+ SHUFFLE_XORSHIFT128 ;
5166+ xyzw [0 ] = x ;
5167+ xyzw [1 ] = y ;
5168+ xyzw [2 ] = z ;
5169+ xyzw [3 ] = w ;
5170+ }
5171+ else if (argvars [0 ].v_type == VAR_LIST )
5172+ {
5173+ listitem_T * lx , * ly , * lz , * lw ;
5174+
5175+ l = argvars [0 ].vval .v_list ;
5176+ if (list_len (l ) != 4 )
5177+ goto theend ;
5178+
5179+ lx = list_find (l , 0L );
5180+ ly = list_find (l , 1L );
5181+ lz = list_find (l , 2L );
5182+ lw = list_find (l , 3L );
5183+ if (lx -> li_tv .v_type != VAR_NUMBER ) goto theend ;
5184+ if (ly -> li_tv .v_type != VAR_NUMBER ) goto theend ;
5185+ if (lz -> li_tv .v_type != VAR_NUMBER ) goto theend ;
5186+ if (lw -> li_tv .v_type != VAR_NUMBER ) goto theend ;
5187+ x = (UINT32_T )lx -> li_tv .vval .v_number ;
5188+ y = (UINT32_T )ly -> li_tv .vval .v_number ;
5189+ z = (UINT32_T )lz -> li_tv .vval .v_number ;
5190+ w = (UINT32_T )lw -> li_tv .vval .v_number ;
5191+ SHUFFLE_XORSHIFT128 ;
5192+ lx -> li_tv .vval .v_number = (varnumber_T )x ;
5193+ ly -> li_tv .vval .v_number = (varnumber_T )y ;
5194+ lz -> li_tv .vval .v_number = (varnumber_T )z ;
5195+ lw -> li_tv .vval .v_number = (varnumber_T )w ;
5196+ }
5197+ else
5198+ goto theend ;
5199+
5200+ rettv -> v_type = VAR_NUMBER ;
5201+ rettv -> vval .v_number = (varnumber_T )w ;
5202+ return ;
5203+
5204+ theend :
5205+ semsg (_ (e_invarg2 ), tv_get_string (& argvars [0 ]));
5206+ }
5207+
51315208/*
51325209 * "range()" function
51335210 */
@@ -7012,6 +7089,31 @@ f_sqrt(typval_T *argvars, typval_T *rettv)
70127089 rettv -> vval .v_float = 0.0 ;
70137090}
70147091
7092+ /*
7093+ * "srand()" function
7094+ */
7095+ static void
7096+ f_srand (typval_T * argvars , typval_T * rettv )
7097+ {
7098+ if (rettv_list_alloc (rettv ) == FAIL )
7099+ return ;
7100+ if (argvars [0 ].v_type == VAR_UNKNOWN )
7101+ list_append_number (rettv -> vval .v_list , (varnumber_T )vim_time ());
7102+ else
7103+ {
7104+ int error = FALSE;
7105+ UINT32_T x = (UINT32_T )tv_get_number_chk (& argvars [0 ], & error );
7106+
7107+ if (error )
7108+ return ;
7109+
7110+ list_append_number (rettv -> vval .v_list , x );
7111+ }
7112+ list_append_number (rettv -> vval .v_list , 362436069 );
7113+ list_append_number (rettv -> vval .v_list , 521288629 );
7114+ list_append_number (rettv -> vval .v_list , 88675123 );
7115+ }
7116+
70157117/*
70167118 * "str2float()" function
70177119 */
0 commit comments