Refactoring and fixing jerry-libc
Refactor memory and string handling routines
* Potential code size improvements:
* Most loops don't really need a new incrementing index variable
running between 0..n-1 but can just loop `while (n--)`, and the
bodies don't need array indexing but can just use the `*p++`
idiom.
* Compare routines are not required to return -1, 0, and +1, but
any negative, zero, or positive result will do.
* `strncmp` may follow the other routines and does not have to have
defined behaviour if any of its args is NULL.
* Fix:
* `strncmp` did not work correctly if the strings were equal but
`n` was greater than their length (did not stop at the
terminating zero character).
Refactor printf
* Merging code duplications, removing dead initialization.
Refactor rand and srand
* Making sure that the type of the state variables is OK
(`uint32_t` instead of `unsigned int`).
* Getting type conversions OK.
* Fixing `srand` to write all state variables and thus indeed
generate the same random sequence.
JerryScript-DCO-1.0-Signed-off-by: Akos Kiss akiss@inf.u-szeged.hu
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
|
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||||
|
* Copyright 2016 University of Szeged
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -210,23 +211,13 @@ libc_printf_write_d_i (FILE *stream, /**< stream pointer */
|
|||||||
switch (length)
|
switch (length)
|
||||||
{
|
{
|
||||||
case LIBC_PRINTF_ARG_LENGTH_TYPE_NONE:
|
case LIBC_PRINTF_ARG_LENGTH_TYPE_NONE:
|
||||||
|
case LIBC_PRINTF_ARG_LENGTH_TYPE_HH: /* char is promoted to int */
|
||||||
|
case LIBC_PRINTF_ARG_LENGTH_TYPE_H: /* short int is promoted to int */
|
||||||
{
|
{
|
||||||
value = (uintmax_t) va_arg (*args_list_p, int);
|
value = (uintmax_t) va_arg (*args_list_p, int);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case LIBC_PRINTF_ARG_LENGTH_TYPE_HH:
|
|
||||||
{
|
|
||||||
value = (uintmax_t) va_arg (*args_list_p, int); /* char is promoted to int */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case LIBC_PRINTF_ARG_LENGTH_TYPE_H:
|
|
||||||
{
|
|
||||||
value = (uintmax_t) va_arg (*args_list_p, int); /* short int is promoted to int */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case LIBC_PRINTF_ARG_LENGTH_TYPE_L:
|
case LIBC_PRINTF_ARG_LENGTH_TYPE_L:
|
||||||
{
|
{
|
||||||
value = (uintmax_t) va_arg (*args_list_p, long int);
|
value = (uintmax_t) va_arg (*args_list_p, long int);
|
||||||
@@ -324,23 +315,13 @@ libc_printf_write_u_o_x_X (FILE *stream, /**< stream pointer */
|
|||||||
switch (length)
|
switch (length)
|
||||||
{
|
{
|
||||||
case LIBC_PRINTF_ARG_LENGTH_TYPE_NONE:
|
case LIBC_PRINTF_ARG_LENGTH_TYPE_NONE:
|
||||||
|
case LIBC_PRINTF_ARG_LENGTH_TYPE_HH: /* char is promoted to int */
|
||||||
|
case LIBC_PRINTF_ARG_LENGTH_TYPE_H: /* short int is promoted to int */
|
||||||
{
|
{
|
||||||
value = (uintmax_t) va_arg (*args_list_p, unsigned int);
|
value = (uintmax_t) va_arg (*args_list_p, unsigned int);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case LIBC_PRINTF_ARG_LENGTH_TYPE_HH:
|
|
||||||
{
|
|
||||||
value = (uintmax_t) va_arg (*args_list_p, unsigned int); /* char is promoted to int */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case LIBC_PRINTF_ARG_LENGTH_TYPE_H:
|
|
||||||
{
|
|
||||||
value = (uintmax_t) va_arg (*args_list_p, unsigned int); /* short int is promoted to int */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case LIBC_PRINTF_ARG_LENGTH_TYPE_L:
|
case LIBC_PRINTF_ARG_LENGTH_TYPE_L:
|
||||||
{
|
{
|
||||||
value = (uintmax_t) va_arg (*args_list_p, unsigned long int);
|
value = (uintmax_t) va_arg (*args_list_p, unsigned long int);
|
||||||
@@ -398,7 +379,7 @@ libc_printf_write_u_o_x_X (FILE *stream, /**< stream pointer */
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t radix = 10;
|
uint32_t radix;
|
||||||
const char *alphabet;
|
const char *alphabet;
|
||||||
|
|
||||||
switch (specifier)
|
switch (specifier)
|
||||||
|
|||||||
+53
-75
@@ -1,4 +1,5 @@
|
|||||||
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
|
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||||
|
* Copyright 2016 University of Szeged
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -27,7 +28,7 @@
|
|||||||
/**
|
/**
|
||||||
* State of pseudo-random number generator
|
* State of pseudo-random number generator
|
||||||
*/
|
*/
|
||||||
static unsigned int libc_random_gen_state[4] = { 1455997910, 1999515274, 1234451287, 1949149569 };
|
static uint32_t libc_random_gen_state[4] = { 1455997910, 1999515274, 1234451287, 1949149569 };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard file descriptors
|
* Standard file descriptors
|
||||||
@@ -62,9 +63,9 @@ memset (void *s, /**< area to set values in */
|
|||||||
size_t n) /**< area size */
|
size_t n) /**< area size */
|
||||||
{
|
{
|
||||||
uint8_t *area_p = (uint8_t *) s;
|
uint8_t *area_p = (uint8_t *) s;
|
||||||
for (size_t index = 0; index < n; index++)
|
while (n--)
|
||||||
{
|
{
|
||||||
area_p[ index ] = (uint8_t) c;
|
*area_p++ = (uint8_t) c;
|
||||||
}
|
}
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
@@ -74,8 +75,8 @@ memset (void *s, /**< area to set values in */
|
|||||||
* memcmp
|
* memcmp
|
||||||
*
|
*
|
||||||
* @return 0, if areas are equal;
|
* @return 0, if areas are equal;
|
||||||
* -1, if first area's content is lexicographically less, than second area's content;
|
* <0, if first area's content is lexicographically less, than second area's content;
|
||||||
* 1, otherwise
|
* >0, otherwise
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
memcmp (const void *s1, /**< first area */
|
memcmp (const void *s1, /**< first area */
|
||||||
@@ -83,15 +84,12 @@ memcmp (const void *s1, /**< first area */
|
|||||||
size_t n) /**< area size */
|
size_t n) /**< area size */
|
||||||
{
|
{
|
||||||
const uint8_t *area1_p = (uint8_t *) s1, *area2_p = (uint8_t *) s2;
|
const uint8_t *area1_p = (uint8_t *) s1, *area2_p = (uint8_t *) s2;
|
||||||
for (size_t index = 0; index < n; index++)
|
while (n--)
|
||||||
{
|
{
|
||||||
if (area1_p[ index ] < area2_p[ index ])
|
int diff = ((int) *area1_p++) - ((int) *area2_p++);
|
||||||
|
if (diff)
|
||||||
{
|
{
|
||||||
return -1;
|
return diff;
|
||||||
}
|
|
||||||
else if (area1_p[ index ] > area2_p[ index ])
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,9 +107,9 @@ memcpy (void *s1, /**< destination */
|
|||||||
uint8_t *area1_p = (uint8_t *) s1;
|
uint8_t *area1_p = (uint8_t *) s1;
|
||||||
const uint8_t *area2_p = (const uint8_t *) s2;
|
const uint8_t *area2_p = (const uint8_t *) s2;
|
||||||
|
|
||||||
for (size_t index = 0; index < n; index++)
|
while (n--)
|
||||||
{
|
{
|
||||||
area1_p[ index ] = area2_p[ index ];
|
*area1_p++ = *area2_p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return s1;
|
return s1;
|
||||||
@@ -127,21 +125,27 @@ memmove (void *s1, /**< destination */
|
|||||||
const void *s2, /**< source */
|
const void *s2, /**< source */
|
||||||
size_t n) /**< bytes number */
|
size_t n) /**< bytes number */
|
||||||
{
|
{
|
||||||
uint8_t *dest_p = (uint8_t *) s1;
|
uint8_t *dest_p;
|
||||||
const uint8_t *src_p = (const uint8_t *) s2;
|
const uint8_t *src_p;
|
||||||
|
|
||||||
if (dest_p < src_p)
|
if (s1 < s2)
|
||||||
{ /* from begin to end */
|
{ /* from begin to end */
|
||||||
for (size_t index = 0; index < n; index++)
|
dest_p = (uint8_t *) s1;
|
||||||
|
src_p = (const uint8_t *) s2;
|
||||||
|
|
||||||
|
while (n--)
|
||||||
{
|
{
|
||||||
dest_p[ index ] = src_p[ index ];
|
*dest_p++ = *src_p++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (dest_p > src_p)
|
else if (s1 > s2)
|
||||||
{ /* from end to begin */
|
{ /* from end to begin */
|
||||||
for (size_t index = 1; index <= n; index++)
|
dest_p = ((uint8_t *) s1) + n - 1;
|
||||||
|
src_p = ((const uint8_t *) s2) + n - 1;
|
||||||
|
|
||||||
|
while (n--)
|
||||||
{
|
{
|
||||||
dest_p[ n - index ] = src_p[ n - index ];
|
*dest_p-- = *src_p--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,23 +160,19 @@ CALL_PRAGMA (GCC diagnostic pop)
|
|||||||
/** Compare two strings. return an integer less than, equal to, or greater than zero
|
/** Compare two strings. return an integer less than, equal to, or greater than zero
|
||||||
if s1 is found, respectively, to be less than, to match, or be greater than s2. */
|
if s1 is found, respectively, to be less than, to match, or be greater than s2. */
|
||||||
int
|
int
|
||||||
strcmp (const char *str1, const char *str2)
|
strcmp (const char *s1, const char *s2)
|
||||||
{
|
{
|
||||||
int s1;
|
while (1)
|
||||||
int s2;
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
s1 = *str1++;
|
int c1 = (unsigned char) *s1++;
|
||||||
s2 = *str2++;
|
int c2 = (unsigned char) *s2++;
|
||||||
|
int diff = c1 - c2;
|
||||||
|
|
||||||
if (s1 == 0)
|
if (!c1 || diff)
|
||||||
{
|
{
|
||||||
break;
|
return diff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (s1 == s2);
|
|
||||||
|
|
||||||
return (s1 < s2) ? -1 : (s1 > s2 ? 1 : 0);
|
|
||||||
} /* strcmp */
|
} /* strcmp */
|
||||||
|
|
||||||
/** Compare two strings. return an integer less than, equal to, or greater than zero
|
/** Compare two strings. return an integer less than, equal to, or greater than zero
|
||||||
@@ -181,38 +181,15 @@ strcmp (const char *str1, const char *str2)
|
|||||||
int
|
int
|
||||||
strncmp (const char *s1, const char *s2, size_t n)
|
strncmp (const char *s1, const char *s2, size_t n)
|
||||||
{
|
{
|
||||||
size_t i;
|
while (n--)
|
||||||
|
{
|
||||||
|
int c1 = (unsigned char) *s1++;
|
||||||
|
int c2 = (unsigned char) *s2++;
|
||||||
|
int diff = c1 - c2;
|
||||||
|
|
||||||
if (n == 0)
|
if (!c1 || diff)
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s1 == NULL)
|
|
||||||
{
|
|
||||||
if (s2 != NULL)
|
|
||||||
{
|
{
|
||||||
return -1;
|
return diff;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (s2 == NULL)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < n; i++)
|
|
||||||
{
|
|
||||||
if (s1[i] > s2[i])
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else if (s1[i] < s2[i])
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,12 +202,12 @@ strncmp (const char *s1, const char *s2, size_t n)
|
|||||||
char * __attr_used___ // FIXME
|
char * __attr_used___ // FIXME
|
||||||
strncpy (char *dest, const char *src, size_t n)
|
strncpy (char *dest, const char *src, size_t n)
|
||||||
{
|
{
|
||||||
size_t i;
|
while (n--)
|
||||||
|
|
||||||
for (i = 0; i < n; i++)
|
|
||||||
{
|
{
|
||||||
dest[i] = src[i];
|
char c = *src++;
|
||||||
if (src[i] == '\0')
|
*dest++ = c;
|
||||||
|
|
||||||
|
if (!c)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -243,10 +220,10 @@ strncpy (char *dest, const char *src, size_t n)
|
|||||||
size_t
|
size_t
|
||||||
strlen (const char *s)
|
strlen (const char *s)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i = 0;
|
||||||
for (i = 0; s[i]; i++)
|
while (s[i])
|
||||||
{
|
{
|
||||||
;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
@@ -273,9 +250,7 @@ rand (void)
|
|||||||
libc_random_gen_state[3] ^= libc_random_gen_state[3] >> 19;
|
libc_random_gen_state[3] ^= libc_random_gen_state[3] >> 19;
|
||||||
libc_random_gen_state[3] ^= intermediate;
|
libc_random_gen_state[3] ^= intermediate;
|
||||||
|
|
||||||
uint32_t ret = libc_random_gen_state[3] % (RAND_MAX + 1u);
|
return libc_random_gen_state[3] % (RAND_MAX + 1u);
|
||||||
|
|
||||||
return (int32_t) ret;
|
|
||||||
} /* rand */
|
} /* rand */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -284,5 +259,8 @@ rand (void)
|
|||||||
void
|
void
|
||||||
srand (unsigned int seed) /**< new seed */
|
srand (unsigned int seed) /**< new seed */
|
||||||
{
|
{
|
||||||
|
libc_random_gen_state[0] =
|
||||||
|
libc_random_gen_state[1] =
|
||||||
|
libc_random_gen_state[2] =
|
||||||
libc_random_gen_state[3] = seed;
|
libc_random_gen_state[3] = seed;
|
||||||
} /* srand */
|
} /* srand */
|
||||||
|
|||||||
Reference in New Issue
Block a user