|
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 |
}
|