AmiTimeKeeper/string.c

391 lines
7.2 KiB
C

/*-
* Copyright (c) 2017-2018 Carsten Sonne Larsen <cs@innolan.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "config.h"
static const char *alphaNumerics = "0123456789";
static const int base = 10;
struct RawDoFmtStream
{
char *buf;
int size;
};
/*
* Get the length of a null terminated string.
*/
int StrLen(const char *string)
{
char *i = (char *)string;
char *s = i;
while (*i)
i++;
return (int)(i - s);
}
/*
* Copies the string pointed to by src to dest.
*/
char *StrCopy(char *dest, const char *src)
{
char *q = (char *)src;
char *p = dest;
while ((*p++ = *q++))
;
*p = '\0';
return dest;
}
char *AppendText(char *start, const char *text)
{
char *p = start;
char *q = (char *)text;
while (*q != '\0')
*p++ = *q++;
*p = '\0';
return p;
}
int TrimRight(char *string)
{
char *i = string;
char *s = i;
while (*i)
i++;
if (i == s)
return 0;
i--;
while (*i == ' ' || *i == '\r' || *i == '\n' || *i == '\t')
*i-- = '\0';
return (int)(i - s + 1);
}
/*
* Find the first occurrence of a character.
*/
char *StrChr(const char *start, const char c, int len)
{
char *i = (char *)start;
int j = 0;
if (i == NULL)
return NULL;
do
{
if (*i == c)
return i;
i++;
j++;
} while (j < len);
return NULL;
}
/*
* Find the last occurrence of a character.
*/
char *StrRChr(const char *start, const char c, int len)
{
char *i = (char *)start;
char *l = NULL;
int j = 0;
if (i == NULL)
return NULL;
do
{
if (*i == c)
l = i;
i++;
j++;
} while (j < len);
return l;
}
/*
* Convert a long to a null terminated string.
*/
int LongToStr(signed long value, char *string)
{
unsigned int len, count = 0;
unsigned long current = value;
char chars[12];
char *p = chars;
char *q = string;
bool negative = false;
if (value < 0)
{
current = -value;
negative = true;
}
do
{
unsigned long remainder = current % base;
*p++ = alphaNumerics[remainder];
current /= base;
count++;
} while (current >= 1);
p--;
len = count;
if (negative)
{
*q++ = '-';
len++;
}
while (count-- != 0)
*q++ = *p--;
*q = '\0';
return len;
}
/*
* Convert a long long to a null terminated string.
*/
int LongLongToStr(signed long long value, char *string)
{
unsigned int len, count = 0;
unsigned long long current = value;
char chars[MAXLONGLONGCHARSIZE];
char *p = chars;
char *q = string;
bool negative = false;
if (value < 0)
{
current = -value;
negative = true;
}
do
{
unsigned long long remainder = current % base;
*p++ = alphaNumerics[remainder];
current /= base;
count++;
} while (current >= 1);
p--;
len = count;
if (negative)
{
*q++ = '-';
len++;
}
while (count-- != 0)
*q++ = *p--;
*q = '\0';
return len;
}
/*
* Convert a null terminated string to a long long.
*/
int StrToLongLong(char *string, unsigned long long *value)
{
signed long long result = 0;
bool negative = false;
char *p = string;
int count = 0;
if (*p == '-')
{
negative = true;
p++;
}
while (*p != '\0')
{
if (*p < '0' || *p > '9' || count > 20)
{
return -1;
}
result *= 10;
result += (*p++) - '0';
}
*value = negative ? -result : result;
return count;
}
/*
* Try to parse a null terminated string to a long.
*/
bool TryParseLong(char *string, long *value)
{
LONG characters, parsedValue;
characters = StrToLong((STRPTR)string, &parsedValue);
if (characters != -1)
{
*value = parsedValue;
return true;
}
*value = 0;
return false;
}
/*
* Try to parse a null terminated string to a long.
*/
bool TryParseLongLong(char *string, long long *value)
{
unsigned long long parsedValue;
long characters;
characters = StrToLongLong(string, &parsedValue);
if (characters != -1)
{
*value = parsedValue;
return true;
}
*value = 0;
return false;
}
#ifdef AOS3
static void RawDoFmtChar(REG(d0, UBYTE c), REG(a3, struct RawDoFmtStream *s))
{
if (s->size > 0)
{
*(s->buf)++ = c;
(s->size)--;
if (s->size == 1)
{
*(s->buf) = '\0';
s->size = 0;
}
}
}
/*
* Formats and stores a series of characters and values.
*/
int VSNPrintf(char *str, size_t size, const char *format, va_list ap)
{
int result = 0;
if (str != NULL)
{
struct RawDoFmtStream s;
s.buf = str;
s.size = size;
RawDoFmt(format, (void *)ap, (void (*)())RawDoFmtChar, (void *)&s);
if ((result = (size - s.size)) != size)
--result;
}
return result;
}
/*
* Formats and stores a series of characters and values in the array buffer.
*/
int SNPrintf(char *str, size_t size, const char *format, ...)
{
va_list args;
int result;
va_start(args, format);
result = VSNPrintf(str, size, format, args);
va_end(args);
return result;
}
#endif
/*
* Split filename in path and filename.
*/
void SplitFileName(const char *s, char *path, char *name)
{
int len, x, y;
char *c;
if (s == NULL || *s == '\0')
{
*path = '\0';
*name = '\0';
return;
}
len = StrLen(s);
c = StrRChr(s, '/', len);
if (c == NULL)
{
c = StrChr(s, ':', len);
if (c == NULL)
{
*path = '\0';
CopyMem((char *)s, name, len);
return;
}
else
{
// Include :
x = (c - s + 1);
}
}
else
{
x = (c - s);
}
y = len - (c - s);
*(char *)(path + x) = '\0';
CopyMem((char *)s, path, x);
CopyMem(++c, name, y);
}