Y-lib
Loadrunner libraries
y_core.c
Go to the documentation of this file.
1 /*
2  * Ylib Loadrunner function library.
3  * Copyright (C) 2005-2014 Floris Kraak <randakar@gmail.com> | <fkraak@ymor.nl>
4  * Copyright (C) 2009 Raymond de Jongh <ferretproof@gmail.com> | <rdjongh@ymor.nl>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  */
20 
29 #ifndef _Y_CORE_C_
30 #define _Y_CORE_C_
32 
34 #include "vugen.h"
35 
39 int y_virtual_user_id = 0;
42 char* y_virtual_user_group = NULL;
44 int y_scid;
47 
48 #ifndef RAND_MAX
49 
57 #define RAND_MAX 32767
58 #endif
59 
67 #ifdef WINNT
68  #define Y_RAND_MAX 2147483647
69 #else
70  #define Y_RAND_MAX 1073741823
71 #endif
72 
85 void y_setup()
86 {
87  // if this is filled y_setup() has already been called.
88  if( y_virtual_user_group != NULL )
89  {
90  return;
91  }
92 
93  // Loadrunner sets the locale to "", causing scripts running in locales other than en_US to misbehave.
94  // Let's set it to something sensible, that actually works for people who don't want to mess with this stuff.
95  setlocale(LC_ALL, "C");
96 
97  // Global variables, handle with care
100 
101  // srand() no longer required on Windows but rand() may still be used in user code so we leave it in.
102  srand(time(NULL) + y_virtual_user_id + ((int)y_virtual_user_group) & 1023);
103 }
104 
106 #define vuser_init() vuser_init() { y_setup(); return y_vuser_init(); } y_vuser_init()
107 
142 #define y_is_vugen_run() y_is_vugen_run_bool
143 
156 long y_rand(void)
157 {
158  // Because rand() does not return numbers above 32767 and we want to get at least 30 of the 31 bits
159  // of randomness that a long affords us we are going to roll multiple numbers and basically
160  // concatenate them together using bit shifts.
161  //
162  // (If we were to go to 32 bits this function would return negative numbers, which would be undesirable
163  // because it will break people's expectations of what rand() does.)
164 #ifdef WINNT
165  // On Windows we can use rand_s which returns a truly 32 bit random number. But we strip off the sign bit.
166  unsigned int randomValue;
167  rand_s(&randomValue);
168  return randomValue & Y_RAND_MAX;
169 #else
170  return rand() << 15 | rand();
171 #endif
172 }
173 
189 double y_drand(void)
190 {
191 #ifdef WINNT
192  // On Windows we can use rand_s which returns a truly 32 bit random number.
193  unsigned int randomValue;
194  rand_s(&randomValue);
195  return (double)randomValue / 4294967296.;
196 #else
197  return (rand() << 15 | rand())/1073741824.;
198 #endif
199 }
200 
201 
221 char *y_mem_alloc(size_t size)
222 {
223  char *buff;
224  buff = malloc(size);
225  if (!buff)
226  {
227  lr_error_message("Insufficient memory available, requested %u bytes", size);
228  // If this happens you're pretty much screwed anyway.
229  lr_abort();
230  }
231  return buff;
232 }
233 
234 
245 char *y_array_alloc(size_t length, size_t size)
246 {
247  char *buff;
248  buff = calloc(length, size);
249  if (!buff)
250  {
251  lr_error_message("Insufficient memory available, requested %u * %u bytes", length, size);
252  // If this happens you're pretty much screwed anyway.
253  lr_abort();
254  }
255  return buff;
256 }
257 
258 
268 char* y_strdup(char* source)
269 {
270  char* result = strdup(source);
271  if (!result)
272  {
273  lr_error_message("Out of memory while calling strdup()");
274  lr_abort();
275  }
276  return result;
277 }
278 
287 char* y_get_parameter_eval_string(const char *param_name)
288 {
289  size_t size = strlen(param_name) +3; // parameter name + "{}" + '\0' (end of string)
290  char *result = y_mem_alloc( size );
291 
292  snprintf(result, size, "{%s}", param_name );
293  return result;
294 }
295 
305 int y_is_empty_parameter(const char *param_name)
306 {
307  char* param_eval_string = y_get_parameter_eval_string(param_name);
308  char* param = lr_eval_string(param_eval_string);
309 
310  int result = *param == 0 || strcmp(param, param_eval_string) == 0;
311  free(param_eval_string);
312 
313  return result;
314 }
315 
336 char* y_get_parameter(const char* param_name)
337 {
338  char* tmp = y_get_parameter_eval_string(param_name);
339  char* parameter = lr_eval_string(tmp);
340  free(tmp);
341 
342  return parameter;
343 }
344 
345 
373 char* y_get_parameter_or_null(const char* param_name)
374 {
375  char* param_eval_string = y_get_parameter_eval_string(param_name);
376  char* param = lr_eval_string(param_eval_string);
377 
378  int exists = strcmp(param, param_eval_string) != 0; // Result doesn't match the param eval string (eg: '{param}')
379  //lr_log_message("y_get_parameter_or_null for param_name %s, pre-eval string is %s, lr_eval_string result is %s, exists: %d", param_name, param_eval_string, param, exists);
380  free(param_eval_string);
381  //lr_abort();
382 
383  return exists ? param: NULL;
384 }
385 
386 
406 char* y_get_parameter_with_malloc_or_null(const char *src_param)
407 {
408  char *src = y_get_parameter_or_null(src_param);
409  //lr_log_message("Copying source data: %s", src);
410  return src ? y_strdup(src): NULL;
411 }
412 
414 #define y_get_parameter_malloc_string 0_please_use_y_get_parameter_with_malloc_or_null
415 
441 char* y_get_parameter_ext(const char *source_param)
442 {
443  char* buffer;
444  unsigned long size;
445  char* source = y_get_parameter_eval_string(source_param); // Puts the parameter name into parameter seperators { }.
446  lr_eval_string_ext(source, strlen(source), &buffer, &size, 0, 0, -1); // Evaluates the result and copy the data into buffer.
447  free(source); // Free the intermediate parameter name.
448  return buffer;
449 }
450 
452 
453 #endif // _Y_CORE_C_
void y_setup()
Ylib setup - determines and stores the identity of the virtual user.
Definition: y_core.c:85
int srand(unsigned int seed)
Documented at http://www.cplusplus.com/reference/cstdlib/srand/.
double y_drand(void)
Generate a random number between 0 <= y_drand() < 1. This supersedes y_rand(). Equal to Math...
Definition: y_core.c:189
Standard C function headers.
char * strdup(const char *string)
Documented at http://pubs.opengroup.org/onlinepubs/007904975/functions/strdup.html ...
void * malloc(size_t num_bytes)
Documented at http://www.cplusplus.com/reference/cstdlib/malloc/.
void * calloc(size_t num_elems, size_t elem_size)
Documented at http://www.cplusplus.com/reference/cstdlib/calloc/.
int y_scid
The virtual user scid, as reported by lr_whoami().
Definition: y_core.c:44
char * y_mem_alloc(size_t size)
Ylib wrapper for malloc()
Definition: y_core.c:221
char * y_array_alloc(size_t length, size_t size)
Allocates a character array and initializes all elements to zero As y_mem_alloc(), but using the &#39;calloc&#39; function, rather than &#39;malloc()&#39;.
Definition: y_core.c:245
int strcmp(const char *string1, const char *string2)
Documented at http://www.cplusplus.com/reference/cstring/strcmp/.
int y_virtual_user_id
The virtual user id, as reported by lr_whoami().
Definition: y_core.c:40
#define Y_RAND_MAX
Alternate RAND_MAX constant for use with y_rand.
Definition: y_core.c:70
char * setlocale(int category, const char *locale)
Documented at http://www.cplusplus.com/reference/clocale/setlocale/.
char * y_get_parameter_eval_string(const char *param_name)
Obtain the string required to fetch the contents of a parameter through lr_eval_string().
Definition: y_core.c:287
int y_is_vugen_run_bool
Boolean, true when running in Vugen. Not able to do this in pre-compile phase.
Definition: y_core.c:46
char * y_strdup(char *source)
Copy a string into a malloc&#39;d piece of memory using strdup(), and lr_abort() if the allocation fails...
Definition: y_core.c:268
size_t strlen(const char *string)
Documented at http://www.cplusplus.com/reference/cstring/strlen/.
int y_is_empty_parameter(const char *param_name)
Test if the given parameter is empty or not yet set. (These are two different things..) It would be nice if loadrunner had a builtin for this.
Definition: y_core.c:305
char * y_get_parameter_with_malloc_or_null(const char *src_param)
Get the content of a parameter and return it as a char * (malloc version)
Definition: y_core.c:406
#define LC_ALL
Definition: vugen.h:365
int snprintf(char *buffer, size_t n, const char *format_string,...)
Documented at http://www.cplusplus.com/reference/cstdio/snprintf/. This function was introduced by t...
long y_rand(void)
Generate a random (integer) number between 0 and Y_RAND_MAX (30 bit maxint).
Definition: y_core.c:156
char * y_virtual_user_group
The virtual user group, as reported by lr_whoami().
Definition: y_core.c:42
int rand(void)
Documented at http://www.cplusplus.com/reference/cstdlib/rand/.
char * y_get_parameter(const char *param_name)
Get the content of a parameter and return it as a char *.
Definition: y_core.c:336
char * y_get_parameter_or_null(const char *param_name)
Get the content of a parameter and return it as a char *, or return NULL if it wasn&#39;t set...
Definition: y_core.c:373
char * y_get_parameter_ext(const char *source_param)
Get the content of a parameter and return it as a char * (lr_eval_string_ext() version) ...
Definition: y_core.c:441
time_t time(time_t *timeptr)
Documented at http://www.cplusplus.com/reference/ctime/time/.
void free(void *mem_address)
Documented at http://www.cplusplus.com/reference/cstdlib/free/.