2024-09-13 08:38:39 +00:00
|
|
|
/* $Id$ */
|
2024-09-13 09:06:44 +00:00
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
2024-09-13 10:08:00 +00:00
|
|
|
#include <stdbool.h>
|
2024-09-14 09:59:15 +00:00
|
|
|
#include <stdio.h>
|
2024-09-13 10:08:00 +00:00
|
|
|
#include <ctype.h>
|
2024-09-13 09:06:44 +00:00
|
|
|
|
|
|
|
char* cm_strcat(const char* a, const char* b) {
|
2024-09-19 09:23:45 +00:00
|
|
|
if(a == NULL) a = "";
|
|
|
|
if(b == NULL) b = "";
|
2024-09-13 09:06:44 +00:00
|
|
|
char* str = malloc(strlen(a) + strlen(b) + 1);
|
|
|
|
memcpy(str, a, strlen(a));
|
|
|
|
memcpy(str + strlen(a), b, strlen(b));
|
|
|
|
str[strlen(a) + strlen(b)] = 0;
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2024-09-13 15:09:52 +00:00
|
|
|
char* cm_strcat3(const char* a, const char* b, const char* c) {
|
|
|
|
char* tmp = cm_strcat(a, b);
|
|
|
|
char* str = cm_strcat(tmp, c);
|
|
|
|
free(tmp);
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2024-09-13 09:06:44 +00:00
|
|
|
char* cm_strdup(const char* str) { return cm_strcat(str, ""); }
|
2024-09-13 09:39:33 +00:00
|
|
|
|
2024-09-19 09:23:45 +00:00
|
|
|
bool cm_endswith(const char* str, const char* end) {
|
|
|
|
if(strlen(str) < strlen(end)) return false;
|
|
|
|
int i;
|
|
|
|
for(i = strlen(str) - strlen(end); i < strlen(str); i++) {
|
|
|
|
if(str[i] != end[i - strlen(str) + strlen(end)]) return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool cm_nocase_endswith(const char* str, const char* end) {
|
|
|
|
if(strlen(str) < strlen(end)) return false;
|
|
|
|
int i;
|
|
|
|
for(i = strlen(str) - strlen(end); i < strlen(str); i++) {
|
|
|
|
if(tolower(str[i]) != tolower(end[i - strlen(str) + strlen(end)])) return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2024-09-13 10:28:20 +00:00
|
|
|
char* cm_trimstart(const char* str) {
|
2024-09-13 09:39:33 +00:00
|
|
|
int i;
|
2024-09-13 10:28:20 +00:00
|
|
|
for(i = 0; str[i] != 0; i++) {
|
|
|
|
if(str[i] != ' ' && str[i] != '\t') {
|
2024-09-13 09:39:33 +00:00
|
|
|
return cm_strdup(str + i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return cm_strdup("");
|
|
|
|
}
|
|
|
|
|
2024-09-13 10:28:20 +00:00
|
|
|
char* cm_trimend(const char* str) {
|
2024-09-13 09:39:33 +00:00
|
|
|
char* s = cm_strdup(str);
|
|
|
|
int i;
|
2024-09-13 10:28:20 +00:00
|
|
|
for(i = strlen(s) - 1; i >= 0; i--) {
|
|
|
|
if(s[i] != '\t' && s[i] != ' ') {
|
2024-09-13 09:39:33 +00:00
|
|
|
s[i + 1] = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2024-09-13 10:28:20 +00:00
|
|
|
char* cm_trim(const char* str) {
|
2024-09-13 09:39:33 +00:00
|
|
|
char* tmp = cm_trimstart(str);
|
|
|
|
char* s = cm_trimend(tmp);
|
|
|
|
free(tmp);
|
|
|
|
return s;
|
|
|
|
}
|
2024-09-13 10:08:00 +00:00
|
|
|
|
2024-09-13 10:28:20 +00:00
|
|
|
char** cm_split(const char* str, const char* by) {
|
2024-09-13 10:08:00 +00:00
|
|
|
int i;
|
|
|
|
char** r = malloc(sizeof(*r));
|
|
|
|
r[0] = NULL;
|
|
|
|
char* b = malloc(1);
|
|
|
|
b[0] = 0;
|
|
|
|
char cbuf[2];
|
|
|
|
cbuf[1] = 0;
|
|
|
|
bool dq = false;
|
|
|
|
bool sq = false;
|
2024-09-13 10:28:20 +00:00
|
|
|
for(i = 0;; i++) {
|
2024-09-13 10:08:00 +00:00
|
|
|
int j;
|
|
|
|
bool has = false;
|
2024-09-13 10:28:20 +00:00
|
|
|
for(j = 0; by[j] != 0; j++) {
|
|
|
|
if(by[j] == str[i]) {
|
2024-09-13 10:08:00 +00:00
|
|
|
has = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2024-09-13 10:28:20 +00:00
|
|
|
if(!(dq || sq) && (has || str[i] == 0)) {
|
|
|
|
if(strlen(b) > 0) {
|
2024-09-13 10:08:00 +00:00
|
|
|
char** old = r;
|
|
|
|
int j;
|
2024-09-13 10:28:20 +00:00
|
|
|
for(j = 0; old[j] != NULL; j++)
|
|
|
|
;
|
2024-09-13 10:08:00 +00:00
|
|
|
r = malloc(sizeof(*r) * (j + 2));
|
|
|
|
for(j = 0; old[j] != NULL; j++) r[j] = old[j];
|
|
|
|
r[j] = b;
|
|
|
|
r[j + 1] = NULL;
|
|
|
|
free(old);
|
|
|
|
}
|
|
|
|
b = malloc(1);
|
|
|
|
b[0] = 0;
|
|
|
|
if(str[i] == 0) break;
|
2024-09-13 10:28:20 +00:00
|
|
|
} else {
|
|
|
|
if(str[i] == '"' && !sq) {
|
2024-09-13 10:08:00 +00:00
|
|
|
dq = !dq;
|
2024-09-13 10:28:20 +00:00
|
|
|
} else if(str[i] == '\'' && !dq) {
|
2024-09-13 10:08:00 +00:00
|
|
|
sq = !sq;
|
2024-09-13 10:28:20 +00:00
|
|
|
} else {
|
2024-09-13 10:08:00 +00:00
|
|
|
cbuf[0] = str[i];
|
|
|
|
char* tmp = b;
|
|
|
|
b = cm_strcat(tmp, cbuf);
|
|
|
|
free(tmp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free(b);
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2024-09-13 10:28:20 +00:00
|
|
|
bool cm_strcaseequ(const char* a, const char* b) {
|
2024-09-13 10:08:00 +00:00
|
|
|
if(a == NULL) return false;
|
|
|
|
if(b == NULL) return false;
|
|
|
|
if(strlen(a) != strlen(b)) return false;
|
|
|
|
int i;
|
2024-09-13 10:28:20 +00:00
|
|
|
for(i = 0; a[i] != 0; i++) {
|
2024-09-13 10:08:00 +00:00
|
|
|
if(tolower(a[i]) != tolower(b[i])) return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2024-09-14 09:59:15 +00:00
|
|
|
|
|
|
|
int cm_hex(const char* str, int len) {
|
|
|
|
int n = 0;
|
|
|
|
int i;
|
|
|
|
for(i = 0; i < len; i++) {
|
|
|
|
char c = str[i];
|
|
|
|
n *= 16;
|
|
|
|
if('0' <= c && c <= '9') {
|
|
|
|
n += c - '0';
|
|
|
|
} else if('a' <= c && c <= 'f') {
|
|
|
|
n += c - 'a' + 10;
|
|
|
|
} else if('A' <= c && c <= 'F') {
|
|
|
|
n += c - 'A' + 10;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
char* cm_html_escape(const char* str) {
|
|
|
|
int i;
|
|
|
|
char* result = malloc(1);
|
|
|
|
result[0] = 0;
|
|
|
|
char cbuf[2];
|
|
|
|
cbuf[1] = 0;
|
|
|
|
for(i = 0; str[i] != 0; i++) {
|
|
|
|
cbuf[0] = str[i];
|
|
|
|
if(str[i] == '&') {
|
|
|
|
char* tmp = result;
|
|
|
|
result = cm_strcat(tmp, "&");
|
|
|
|
free(tmp);
|
|
|
|
} else if(str[i] == '<') {
|
|
|
|
char* tmp = result;
|
|
|
|
result = cm_strcat(tmp, "<");
|
|
|
|
free(tmp);
|
|
|
|
} else if(str[i] == '>') {
|
|
|
|
char* tmp = result;
|
|
|
|
result = cm_strcat(tmp, ">");
|
|
|
|
free(tmp);
|
|
|
|
} else {
|
|
|
|
char* tmp = result;
|
|
|
|
result = cm_strcat(tmp, cbuf);
|
|
|
|
free(tmp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
2024-09-14 12:39:39 +00:00
|
|
|
|
|
|
|
char* cm_url_escape(const char* str) {
|
|
|
|
int i;
|
|
|
|
char* result = malloc(1);
|
|
|
|
result[0] = 0;
|
|
|
|
char cbuf[2];
|
|
|
|
cbuf[1] = 0;
|
|
|
|
for(i = 0; str[i] != 0; i++) {
|
|
|
|
cbuf[0] = str[i];
|
|
|
|
if('!' <= str[i] && str[i] <= '@' && str[i] != '.' && str[i] != '-' && str[i] != '/' && !('0' <= str[i] && str[i] <= '9')) {
|
|
|
|
char code[4];
|
|
|
|
sprintf(code, "%%%02X", str[i]);
|
|
|
|
char* tmp = result;
|
|
|
|
result = cm_strcat(tmp, code);
|
|
|
|
free(tmp);
|
|
|
|
} else {
|
|
|
|
char* tmp = result;
|
|
|
|
result = cm_strcat(tmp, cbuf);
|
|
|
|
free(tmp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|