diff options
| -rw-r--r-- | doc/info/mds.texinfo | 24 | ||||
| -rw-r--r-- | src/libmdsserver/util.c | 95 | ||||
| -rw-r--r-- | src/libmdsserver/util.h | 24 | 
3 files changed, 141 insertions, 2 deletions
diff --git a/doc/info/mds.texinfo b/doc/info/mds.texinfo index 8d44bdb..7835753 100644 --- a/doc/info/mds.texinfo +++ b/doc/info/mds.texinfo @@ -6535,6 +6535,30 @@ string is not a 10-radix integer or has a value  outside [@code{min}, @code{max}], @code{-1} is  returned, otherwise zero is returned. +@item @code{strict_atoj} [(@code{const char* str, intmax_t* value, intmax_t min, intmax_t max}) @arrow{} @code{int}] +@fnindex @code{strict_atoj} +@fnindex @code{atoj} +@cpindex Integer parsing +@cpindex Error management +A version of @code{atoj} that is strict about the +syntax and bounds. Parses the string @code{str} into +an @code{int} and stores it in @code{*value}. If the +string is not a 10-radix integer or has a value +outside [@code{min}, @code{max}], @code{-1} is +returned, otherwise zero is returned. + +@item @code{strict_atouj} [(@code{const char* str, uintmax_t* value, uintmax_t min, uintmax_t max}) @arrow{} @code{int}] +@fnindex @code{strict_atouj} +@fnindex @code{atouj} +@cpindex Integer parsing +@cpindex Error management +A version of @code{atouj} that is strict about the +syntax and bounds. Parses the string @code{str} into +an @code{int} and stores it in @code{*value}. If the +string is not a 10-radix integer or has a value +outside [@code{min}, @code{max}], @code{-1} is +returned, otherwise zero is returned. +  @item @code{full_write} [(@code{int fd, const char* buffer, size_t length}) @arrow{} @code{int}]  @fnindex @code{full_write}  @cpindex File writing diff --git a/src/libmdsserver/util.c b/src/libmdsserver/util.c index eb79bff..f62abd2 100644 --- a/src/libmdsserver/util.c +++ b/src/libmdsserver/util.c @@ -241,6 +241,101 @@ int strict_atoi(const char* str, int* value, int min, int max)  /** + * A version of `atoj` that is strict about the syntax and bounds + *  + * @param   str    The text to parse + * @param   value  Slot in which to store the value + * @param   min    The minimum accepted value + * @param   max    The maximum accepted value + * @return         Zero on success, -1 on syntax error + */ +int strict_atoj(const char* str, intmax_t* value, intmax_t min, intmax_t max) +{ +  static char minstr[3 * sizeof(intmax_t) + 2] = { '\0' }; +  intmax_t r = 0; +  char c; +  int neg = 0; +   +  if (*str == '-') +    { +      if (*minstr == '\0') +	sprintf(minstr, "%j", INTMAX_MIN); +      if (!strcmp(str, minstr)) +	{ +	  r = INTMAX_MIN; +	  goto done; +	} +      neg = 1, str++; +    } +   +  if (*str == '\0') +    return -1; +   +  while ((c = *str)) +    if (('0' <= c) && (c <= '9')) +      { +	if (r > INTMAX_MAX / 10) +	  return -1; +	else if (r == INTMAX_MAX / 10) +	  if ((c & 15) > INTMAX_MAX % 10) +	    return -1; +	r = r * 10 + (c & 15); +      } +    else +      return -1; +   +  if (neg) +    r = -r; +   + done: +   +  if ((r < min) || (r > max)) +    return -1; +   +  *value = r; +  return 0; +} + + +/** + * A version of `atouj` that is strict about the syntax and bounds + *  + * @param   str    The text to parse + * @param   value  Slot in which to store the value + * @param   min    The minimum accepted value + * @param   max    The maximum accepted value + * @return         Zero on success, -1 on syntax error + */ +int strict_atouj(const char* str, uintmax_t* value, uintmax_t min, uintmax_t max) +{ +  uintmax_t r = 0; +  char c; +   +  if (*str == '\0') +    return -1; +   +  while ((c = *str)) +    if (('0' <= c) && (c <= '9')) +      { +	if (r > INTMAX_MAX / 10) +	  return -1; +	else if (r == INTMAX_MAX / 10) +	  if ((c & 15) > INTMAX_MAX % 10) +	    return -1; +	r = r * 10 + (c & 15); +      } +    else +      return -1; +   +  if ((r < min) || (r > max)) +    return -1; +   +  *value = r; +  return 0; +} + + +/**   * Send a buffer into a file and ignore interruptions   *    * @param   fd      The file descriptor diff --git a/src/libmdsserver/util.h b/src/libmdsserver/util.h index accf038..c84156d 100644 --- a/src/libmdsserver/util.h +++ b/src/libmdsserver/util.h @@ -110,6 +110,28 @@ size_t send_message(int socket, const char* message, size_t length);  int strict_atoi(const char* str, int* value, int min, int max);  /** + * A version of `atoj` that is strict about the syntax and bounds + *  + * @param   str    The text to parse + * @param   value  Slot in which to store the value + * @param   min    The minimum accepted value + * @param   max    The maximum accepted value + * @return         Zero on success, -1 on syntax error + */ +int strict_atoj(const char* str, intmax_t* value, intmax_t min, intmax_t max); + +/** + * A version of `atouj` that is strict about the syntax and bounds + *  + * @param   str    The text to parse + * @param   value  Slot in which to store the value + * @param   min    The minimum accepted value + * @param   max    The maximum accepted value + * @return         Zero on success, -1 on syntax error + */ +int strict_atouj(const char* str, uintmax_t* value, uintmax_t min, uintmax_t max); + +/**   * Send a buffer into a file and ignore interruptions   *    * @param   fd      The file descriptor @@ -128,7 +150,6 @@ int full_write(int fd, const char* buffer, size_t length);   */  char* full_read(int fd, size_t* length); -  /**   * Send a full message even if interrupted   *  @@ -139,7 +160,6 @@ char* full_read(int fd, size_t* length);   */  int full_send(int socket, const char* message, size_t length); -  /**   * Check whether a string begins with a specific string,   * where neither of the strings are necessarily NUL-terminated  | 
