diff --git a/jerry-libc/include/stdlib.h b/jerry-libc/include/stdlib.h index dd802fa090..4682af8d55 100644 --- a/jerry-libc/include/stdlib.h +++ b/jerry-libc/include/stdlib.h @@ -33,6 +33,7 @@ void __attribute__ ((noreturn)) exit (int); void __attribute__ ((noreturn)) abort (void); int rand (void); void srand (unsigned int); +long int strtol (const char *, char **, int); #ifdef __cplusplus } diff --git a/jerry-libc/jerry-libc.c b/jerry-libc/jerry-libc.c index 20c947c5b7..6511950594 100644 --- a/jerry-libc/jerry-libc.c +++ b/jerry-libc/jerry-libc.c @@ -17,6 +17,7 @@ * Jerry libc's common functions implementation */ +#include #include #include #include @@ -280,3 +281,76 @@ srand (unsigned int seed) /**< new seed */ libc_random_gen_state[2] = libc_random_gen_state[3] = seed; } /* srand */ + +/** + * Convert a string to a long integer. + * + * The function first discards leading whitespace characters. Then takes an + * optional sign followed by as many digits as possible and interprets them as a + * numerical value. Additional characters after those that form the number are + * ignored. + * + * Note: + * If base is not 10, the behaviour is undefined. + * If the value read is out-of-range, the behaviour is undefined. + * The implementation never sets errno. + * + * @return the integer value of str. + */ +long int +strtol (const char *nptr, /**< string representation of an integer number */ + char **endptr, /**< [out] the address of the first non-number character */ + int base) /**< numerical base or radix (MUST be 10) */ +{ + assert (base == 10); + (void) base; /* Unused. */ + + const char *str = nptr; + + /* Skip leading whitespaces. */ + while (*str == ' ' || *str == '\t' || *str == '\r' || *str == '\n') + { + str++; + } + + bool digits = false; + bool positive = true; + long int num = 0; + + /* Process optional sign. */ + if (*str == '-') + { + positive = false; + str++; + } + else if (*str == '+') + { + str++; + } + + /* Process base-10 digits. */ + while (*str >= '0' && *str <= '9') + { + num = num * 10 + (*str - '0'); + digits = true; + str++; + } + + /* Set endptr and return result*/ + if (digits) + { + if (endptr) + { + *endptr = (char *) str; + } + return positive ? num : -num; + } + else + { + if (endptr) + { + *endptr = (char *) nptr; + } + return 0L; + } +} /* strtol */ diff --git a/jerry-main/main-unix.c b/jerry-main/main-unix.c index 7586a4eb58..5f8f7e5ac5 100644 --- a/jerry-main/main-unix.c +++ b/jerry-main/main-unix.c @@ -126,30 +126,6 @@ jerry_value_is_syntax_error (jerry_value_t error_value) /**< error value */ return false; } /* jerry_value_is_syntax_error */ -/** - * Convert string into unsigned integer - * - * @return converted number - */ -static uint32_t -str_to_uint (const char *num_str_p) /**< string to convert */ -{ - assert (jerry_is_feature_enabled (JERRY_FEATURE_ERROR_MESSAGES)); - - uint32_t result = 0; - - while (*num_str_p != '\0') - { - assert (*num_str_p >= '0' && *num_str_p <= '9'); - - result *= 10; - result += (uint32_t) (*num_str_p - '0'); - num_str_p++; - } - - return result; -} /* str_to_uint */ - /** * Print error value */ @@ -177,18 +153,18 @@ print_unhandled_exception (jerry_value_t error_value) /**< error value */ if (jerry_is_feature_enabled (JERRY_FEATURE_ERROR_MESSAGES) && jerry_value_is_syntax_error (error_value)) { - uint32_t err_line = 0; - uint32_t err_col = 0; + unsigned int err_line = 0; + unsigned int err_col = 0; /* 1. parse column and line information */ - for (uint32_t i = 0; i < sz; i++) + for (jerry_size_t i = 0; i < sz; i++) { if (!strncmp ((char *) (err_str_buf + i), "[line: ", 7)) { i += 7; char num_str[8]; - uint32_t j = 0; + unsigned int j = 0; while (i < sz && err_str_buf[i] != ',') { @@ -198,7 +174,7 @@ print_unhandled_exception (jerry_value_t error_value) /**< error value */ } num_str[j] = '\0'; - err_line = str_to_uint (num_str); + err_line = (unsigned int) strtol (num_str, NULL, 10); if (strncmp ((char *) (err_str_buf + i), ", column: ", 10)) { @@ -216,17 +192,17 @@ print_unhandled_exception (jerry_value_t error_value) /**< error value */ } num_str[j] = '\0'; - err_col = str_to_uint (num_str); + err_col = (unsigned int) strtol (num_str, NULL, 10); break; } } /* for */ if (err_line != 0 && err_col != 0) { - uint32_t curr_line = 1; + unsigned int curr_line = 1; bool is_printing_context = false; - uint32_t pos = 0; + unsigned int pos = 0; /* 2. seek and print */ while (buffer[pos] != '\0') @@ -519,10 +495,12 @@ main (int argc, } case OPT_LOG_LEVEL: { - check_usage (strlen (cli_state.arg[1]) == 1 && cli_state.arg[1][0] >= '0' && cli_state.arg[1][0] <= '3', + char *endptr; + long int log_level = strtol (cli_state.arg[1], &endptr, 10); + check_usage (log_level >= 0 && log_level <= 3 && !*endptr, argv[0], "Error: wrong format for ", cli_state.arg[0]); - jerry_port_default_set_log_level ((jerry_log_level_t) (cli_state.arg[1][0] - '0')); + jerry_port_default_set_log_level ((jerry_log_level_t) log_level); break; } case OPT_ABORT_ON_FAIL: