cOMS/Utils/StringUtils.h

276 lines
7.5 KiB
C++
Executable File

/**
* Karaka
*
* @package Utils
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef UTILS_STRING_UTILS_H
#define UTILS_STRING_UTILS_H
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "MathUtils.h"
#include "ArraySort.h"
namespace Utils
{
namespace StringUtils
{
inline
char *search_replace(const char *haystack, const char *needle, const char *replace)
{
const char *haystackT = haystack;
size_t i;
size_t match = 0;
size_t oldLength = strlen(needle);
size_t newLength = strlen(replace);
for (i = 0; haystack[i] != '\0'; ++i) {
if (strstr(&haystack[i], needle) == &haystack[i]) {
++match;
i += oldLength - 1;
}
}
char *result = (char *) malloc(i + match * (newLength - oldLength) + 1);
if (!result) {
return NULL;
}
size_t c = 0;
while (*haystack && c < i + match * (newLength - oldLength)) {
if (strstr(haystack, needle) == haystack) {
strcpy(&result[c], replace);
c += newLength;
haystack += oldLength;
} else {
result[c++] = *haystack++;
}
}
if (c > i + match * (newLength - oldLength)) {
c = i + match * (newLength - oldLength);
}
result[c] = '\0';
return result;
}
inline
bool is_number(const char *s)
{
while (*s != '\0') {
if (!isdigit(*s)) {
return false;
}
++s;
}
return true;
}
inline
size_t str_count(char *str, char *substr)
{
int l1 = strlen(str);
int l2 = strlen(substr);
if (l2 == 0 || l1 < l2) {
return 0;
}
int count = 0;
for (str = strstr(str, substr); str; str = strstr(str + l2, substr)) {
++count;
}
return count;
}
char *strsep(char **sp, char *sep)
{
char *p, *s;
if (sp == NULL || *sp == NULL || **sp == '\0') {
return(NULL);
}
s = *sp;
p = s + strcspn(s, sep);
if (*p != '\0') {
*p++ = '\0';
}
*sp = p;
return(s);
}
int str_split(char **list, char *str, const char delim)
{
size_t splits = str_count(str, (char *) &delim) + 1;
list = (char **) malloc(splits * sizeof(char *));
char *token;
int i = 0;
while ((token = strsep(&str, (char *) &delim)) != NULL) {
list[i] = (char *) malloc(strlen(token + 1) * sizeof(char));
memcpy(list[i], token, (strlen(token) + 1) * sizeof(char));
++i;
}
return i;
}
typedef struct {
char **values;
int *masks;
int size;
} text_diff;
text_diff computeLCSDiff(char **from, int fromSize, char **to, int toSize)
{
char **diffValues = (char **) malloc(fromSize * toSize * sizeof(char *));
int *diffMasks = (int *) calloc(fromSize * toSize, sizeof(int));
int *dm = (int *) calloc((fromSize + 1) * (toSize + 1), sizeof(int));
if (!diffValues || !diffMasks || !dm) {
fprintf(stderr, "CRITICAL: malloc failed");
}
int i = 0;
int j = 0;
/* Handled with calloc
for (j = 0; j <= toSize; ++j) {
dm[0 + j] = 0;
}
for (i = 1; i <= fromSize; ++i) {
dm[i * fromSize + 0] = 0;
}
*/
for (i = 1; i <= fromSize; ++i) {
for (j = 1; j <= toSize; ++j) {
dm[i * fromSize + j] = strcmp(from[i - 1], to[j - 1]) == 0
? dm[(i - 1) * fromSize + (j - 1)] + 1
: oms_max(dm[(i - 1) * fromSize + j], dm[i * fromSize + (j - 1)]);
}
}
int diffIndex = 0;
i = fromSize;
j = toSize;
while ((i > 0 || j > 0) && diffIndex < fromSize * toSize) {
if (j > 0 && dm[i * fromSize + (j - 1)] == dm[i * fromSize + j]) {
diffValues[diffIndex] = (char *) malloc((strlen(to[j - 1]) + 1) * sizeof(char));
if (!diffValues[diffIndex]) {
fprintf(stderr, "CRITICAL: malloc failed");
continue;
}
#ifdef _WIN32
strcpy_s(diffValues[diffIndex], (strlen(to[j - 1]) + 1) * sizeof(char), to[j - 1]);
#else
strcpy(diffValues[diffIndex], to[j - 1]);
#endif
diffMasks[diffIndex] = 1;
--j;
++diffIndex;
continue;
}
if (i > 0 && dm[(i - 1) * fromSize + j] == dm[i * fromSize + j]) {
diffValues[diffIndex] = (char *) malloc((strlen(from[i - 1]) + 1) * sizeof(char));
if (!diffValues[diffIndex]) {
fprintf(stderr, "CRITICAL: malloc failed");
continue;
}
#ifdef _WIN32
strcpy_s(diffValues[diffIndex], (strlen(from[i - 1]) + 1) * sizeof(char), from[i - 1]);
#else
strcpy(diffValues[diffIndex], from[i - 1]);
#endif
diffMasks[diffIndex] = -1;
--i;
++diffIndex;
continue;
}
diffValues[diffIndex] = (char *) malloc((strlen(from[i - 1]) + 1) * sizeof(char));
if (!diffValues[diffIndex]) {
fprintf(stderr, "CRITICAL: malloc failed");
continue;
}
#ifdef _WIN32
strcpy_s(diffValues[diffIndex], (strlen(from[i - 1]) + 1) * sizeof(char), from[i - 1]);
#else
strcpy(diffValues[diffIndex], from[i - 1]);
#endif
/* Handled with calloc
diffMasks[diffIndex] = 0;
*/
--i;
--j;
++diffIndex;
}
free(dm);
char **diffValuesT = (char **) realloc(diffValues, diffIndex * sizeof(char *));
if (!diffValuesT) {
free(diffValues);
}
diffValues = diffValuesT;
int *diffMasksT = (int *) realloc(diffMasks, diffIndex * sizeof(int));
if (!diffMasksT) {
free(diffMasks);
}
diffMasks = diffMasksT;
if (!diffValues || !diffMasks) {
fprintf(stderr, "CRITICAL: malloc failed");
return text_diff{};
}
ArraySort::reverse_char(diffValues, diffIndex);
ArraySort::reverse_int(diffMasks, diffIndex);
return text_diff{diffValues, diffMasks, diffIndex};
}
}
}
#endif