Blame source/uds/stringUtils.c

Packit Service 310c69
/*
Packit Service 310c69
 * Copyright (c) 2020 Red Hat, Inc.
Packit Service 310c69
 *
Packit Service 310c69
 * This program is free software; you can redistribute it and/or
Packit Service 310c69
 * modify it under the terms of the GNU General Public License
Packit Service 310c69
 * as published by the Free Software Foundation; either version 2
Packit Service 310c69
 * of the License, or (at your option) any later version.
Packit Service 310c69
 * 
Packit Service 310c69
 * This program is distributed in the hope that it will be useful,
Packit Service 310c69
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 310c69
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 310c69
 * GNU General Public License for more details.
Packit Service 310c69
 * 
Packit Service 310c69
 * You should have received a copy of the GNU General Public License
Packit Service 310c69
 * along with this program; if not, write to the Free Software
Packit Service 310c69
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit Service 310c69
 * 02110-1301, USA. 
Packit Service 310c69
 *
Packit Service 310c69
 * $Id: //eng/uds-releases/jasper/src/uds/stringUtils.c#2 $
Packit Service 310c69
 */
Packit Service 310c69
Packit Service 310c69
#include "stringUtils.h"
Packit Service 310c69
Packit Service 310c69
#include "errors.h"
Packit Service 310c69
#include "logger.h"
Packit Service 310c69
#include "memoryAlloc.h"
Packit Service 310c69
#include "permassert.h"
Packit Service 310c69
#include "uds.h"
Packit Service 310c69
Packit Service 310c69
/*****************************************************************************/
Packit Service 310c69
int allocSprintf(const char *what, char **strp, const char *fmt, ...)
Packit Service 310c69
{
Packit Service 310c69
  if (strp == NULL) {
Packit Service 310c69
    return UDS_INVALID_ARGUMENT;
Packit Service 310c69
  }
Packit Service 310c69
  va_list args;
Packit Service 310c69
#ifdef __KERNEL__
Packit Service 310c69
  // We want the memory allocation to use our own ALLOCATE/FREE wrappers.
Packit Service 310c69
  va_start(args, fmt);
Packit Service 310c69
  int count = vsnprintf(NULL, 0, fmt, args) + 1;
Packit Service 310c69
  va_end(args);
Packit Service 310c69
  int result = ALLOCATE(count, char, what, strp);
Packit Service 310c69
  if (result == UDS_SUCCESS) {
Packit Service 310c69
    va_start(args, fmt);
Packit Service 310c69
    vsnprintf(*strp, count, fmt, args);
Packit Service 310c69
    va_end(args);
Packit Service 310c69
  }
Packit Service 310c69
#else
Packit Service 310c69
  va_start(args, fmt);
Packit Service 310c69
  int result = vasprintf(strp, fmt, args) == -1 ? ENOMEM : UDS_SUCCESS;
Packit Service 310c69
  va_end(args);
Packit Service 310c69
#endif
Packit Service 310c69
  if ((result != UDS_SUCCESS) && (what != NULL)) {
Packit Service 310c69
    logError("cannot allocate %s", what);
Packit Service 310c69
  }
Packit Service 310c69
  return result;
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/*****************************************************************************/
Packit Service 310c69
int wrapVsnprintf(const char *what, char *buf, size_t bufSize,
Packit Service 310c69
                  int error, const char *fmt, va_list ap, size_t *needed)
Packit Service 310c69
{
Packit Service 310c69
  if (buf == NULL) {
Packit Service 310c69
    static char nobuf[1];
Packit Service 310c69
    buf = nobuf;
Packit Service 310c69
    bufSize = 0;
Packit Service 310c69
  }
Packit Service 310c69
  int n = vsnprintf(buf, bufSize, fmt, ap);
Packit Service 310c69
  if (n < 0) {
Packit Service 310c69
    return logErrorWithStringError(UDS_UNEXPECTED_RESULT,
Packit Service 310c69
                                   "%s: vsnprintf failed", what);
Packit Service 310c69
  }
Packit Service 310c69
  if (needed) {
Packit Service 310c69
    *needed = n;
Packit Service 310c69
  }
Packit Service 310c69
  if (((size_t) n >= bufSize) && (buf != NULL) && (error != UDS_SUCCESS)) {
Packit Service 310c69
    return logErrorWithStringError(error, "%s: string too long", what);
Packit Service 310c69
  }
Packit Service 310c69
  return UDS_SUCCESS;
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/*****************************************************************************/
Packit Service 310c69
int fixedSprintf(const char *what,
Packit Service 310c69
                 char       *buf,
Packit Service 310c69
                 size_t      bufSize,
Packit Service 310c69
                 int         error,
Packit Service 310c69
                 const char *fmt,
Packit Service 310c69
                 ...)
Packit Service 310c69
{
Packit Service 310c69
  if (buf == NULL) {
Packit Service 310c69
    return UDS_INVALID_ARGUMENT;
Packit Service 310c69
  }
Packit Service 310c69
  va_list args;
Packit Service 310c69
  va_start(args, fmt);
Packit Service 310c69
  int result = wrapVsnprintf(what, buf, bufSize, error, fmt, args, NULL);
Packit Service 310c69
  va_end(args);
Packit Service 310c69
  return result;
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/*****************************************************************************/
Packit Service 310c69
char *vAppendToBuffer(char       *buffer,
Packit Service 310c69
                      char       *bufEnd,
Packit Service 310c69
                      const char *fmt,
Packit Service 310c69
                      va_list     args)
Packit Service 310c69
{
Packit Service 310c69
  size_t n = vsnprintf(buffer, bufEnd - buffer, fmt, args);
Packit Service 310c69
  if (n >= (size_t) (bufEnd - buffer)) {
Packit Service 310c69
    buffer = bufEnd;
Packit Service 310c69
  } else {
Packit Service 310c69
    buffer += n;
Packit Service 310c69
  }
Packit Service 310c69
  return buffer;
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/*****************************************************************************/
Packit Service 310c69
char *appendToBuffer(char *buffer, char *bufEnd, const char *fmt, ...)
Packit Service 310c69
{
Packit Service 310c69
  va_list ap;
Packit Service 310c69
Packit Service 310c69
  va_start(ap, fmt);
Packit Service 310c69
  char *pos = vAppendToBuffer(buffer, bufEnd, fmt, ap);
Packit Service 310c69
  va_end(ap);
Packit Service 310c69
  return pos;
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/*****************************************************************************/
Packit Service 310c69
int stringToSignedInt(const char *nptr, int *num)
Packit Service 310c69
{
Packit Service 310c69
  long value;
Packit Service 310c69
  int result = stringToSignedLong(nptr, &value);
Packit Service 310c69
  if (result != UDS_SUCCESS) {
Packit Service 310c69
    return result;
Packit Service 310c69
  }
Packit Service 310c69
  if ((value < INT_MIN) || (value > INT_MAX)) {
Packit Service 310c69
    return ERANGE;
Packit Service 310c69
  }
Packit Service 310c69
  *num = (int) value;
Packit Service 310c69
  return UDS_SUCCESS;
Packit Service 310c69
}
Packit Service 310c69
Packit Service 310c69
/*****************************************************************************/
Packit Service 310c69
int stringToUnsignedInt(const char *nptr, unsigned int *num)
Packit Service 310c69
{
Packit Service 310c69
  unsigned long value;
Packit Service 310c69
  int result = stringToUnsignedLong(nptr, &value);
Packit Service 310c69
  if (result != UDS_SUCCESS) {
Packit Service 310c69
    return result;
Packit Service 310c69
  }
Packit Service 310c69
  if (value > UINT_MAX) {
Packit Service 310c69
    return ERANGE;
Packit Service 310c69
  }
Packit Service 310c69
  *num = (unsigned int) value;
Packit Service 310c69
  return UDS_SUCCESS;
Packit Service 310c69
}