source: Main/trunk/Common/string.c@ 408

Last change on this file since 408 was 212, checked in by Nishi, on Oct 3, 2024 at 2:44:55 AM

compiles on vc6

  • Property svn:keywords set to Id
File size: 4.1 KB
RevLine 
[2]1/* $Id: string.c 212 2024-10-02 17:44:55Z nishi $ */
[3]2
3#include <string.h>
4#include <stdlib.h>
[5]5#include <stdbool.h>
[20]6#include <stdio.h>
[5]7#include <ctype.h>
[3]8
9char* cm_strcat(const char* a, const char* b) {
[212]10 char* str;
[70]11 if(a == NULL) a = "";
12 if(b == NULL) b = "";
[212]13 str = malloc(strlen(a) + strlen(b) + 1);
[3]14 memcpy(str, a, strlen(a));
15 memcpy(str + strlen(a), b, strlen(b));
16 str[strlen(a) + strlen(b)] = 0;
17 return str;
18}
19
[16]20char* cm_strcat3(const char* a, const char* b, const char* c) {
21 char* tmp = cm_strcat(a, b);
22 char* str = cm_strcat(tmp, c);
23 free(tmp);
24 return str;
25}
26
[3]27char* cm_strdup(const char* str) { return cm_strcat(str, ""); }
[4]28
[70]29bool cm_endswith(const char* str, const char* end) {
[212]30 int i;
[70]31 if(strlen(str) < strlen(end)) return false;
32 for(i = strlen(str) - strlen(end); i < strlen(str); i++) {
33 if(str[i] != end[i - strlen(str) + strlen(end)]) return false;
34 }
35 return true;
36}
37
38bool cm_nocase_endswith(const char* str, const char* end) {
[212]39 int i;
[70]40 if(strlen(str) < strlen(end)) return false;
41 for(i = strlen(str) - strlen(end); i < strlen(str); i++) {
42 if(tolower(str[i]) != tolower(end[i - strlen(str) + strlen(end)])) return false;
43 }
44 return true;
45}
46
[6]47char* cm_trimstart(const char* str) {
[4]48 int i;
[6]49 for(i = 0; str[i] != 0; i++) {
50 if(str[i] != ' ' && str[i] != '\t') {
[4]51 return cm_strdup(str + i);
52 }
53 }
54 return cm_strdup("");
55}
56
[6]57char* cm_trimend(const char* str) {
[4]58 char* s = cm_strdup(str);
59 int i;
[6]60 for(i = strlen(s) - 1; i >= 0; i--) {
61 if(s[i] != '\t' && s[i] != ' ') {
[4]62 s[i + 1] = 0;
63 break;
64 }
65 }
66 return s;
67}
68
[6]69char* cm_trim(const char* str) {
[4]70 char* tmp = cm_trimstart(str);
71 char* s = cm_trimend(tmp);
72 free(tmp);
73 return s;
74}
[5]75
[6]76char** cm_split(const char* str, const char* by) {
[5]77 int i;
78 char** r = malloc(sizeof(*r));
79 char* b = malloc(1);
80 char cbuf[2];
81 bool dq = false;
82 bool sq = false;
[212]83 r[0] = NULL;
84 b[0] = 0;
85 cbuf[1] = 0;
[6]86 for(i = 0;; i++) {
[5]87 int j;
88 bool has = false;
[6]89 for(j = 0; by[j] != 0; j++) {
90 if(by[j] == str[i]) {
[5]91 has = true;
92 break;
93 }
94 }
[6]95 if(!(dq || sq) && (has || str[i] == 0)) {
96 if(strlen(b) > 0) {
[5]97 char** old = r;
98 int j;
[6]99 for(j = 0; old[j] != NULL; j++)
100 ;
[5]101 r = malloc(sizeof(*r) * (j + 2));
102 for(j = 0; old[j] != NULL; j++) r[j] = old[j];
103 r[j] = b;
104 r[j + 1] = NULL;
105 free(old);
106 }
107 b = malloc(1);
108 b[0] = 0;
109 if(str[i] == 0) break;
[6]110 } else {
111 if(str[i] == '"' && !sq) {
[5]112 dq = !dq;
[6]113 } else if(str[i] == '\'' && !dq) {
[5]114 sq = !sq;
[6]115 } else {
[212]116 char* tmp = b;
[5]117 cbuf[0] = str[i];
118 b = cm_strcat(tmp, cbuf);
119 free(tmp);
120 }
121 }
122 }
123 free(b);
124 return r;
125}
126
[6]127bool cm_strcaseequ(const char* a, const char* b) {
[212]128 int i;
[5]129 if(a == NULL) return false;
130 if(b == NULL) return false;
131 if(strlen(a) != strlen(b)) return false;
[6]132 for(i = 0; a[i] != 0; i++) {
[5]133 if(tolower(a[i]) != tolower(b[i])) return false;
134 }
135 return true;
136}
[20]137
138int cm_hex(const char* str, int len) {
139 int n = 0;
140 int i;
141 for(i = 0; i < len; i++) {
142 char c = str[i];
143 n *= 16;
144 if('0' <= c && c <= '9') {
145 n += c - '0';
146 } else if('a' <= c && c <= 'f') {
147 n += c - 'a' + 10;
148 } else if('A' <= c && c <= 'F') {
149 n += c - 'A' + 10;
150 }
151 }
152 return n;
153}
154
155char* cm_html_escape(const char* str) {
156 int i;
157 char* result = malloc(1);
[212]158 char cbuf[2];
[20]159 result[0] = 0;
160 cbuf[1] = 0;
161 for(i = 0; str[i] != 0; i++) {
162 cbuf[0] = str[i];
163 if(str[i] == '&') {
164 char* tmp = result;
165 result = cm_strcat(tmp, "&amp;");
166 free(tmp);
167 } else if(str[i] == '<') {
168 char* tmp = result;
169 result = cm_strcat(tmp, "&lt;");
170 free(tmp);
171 } else if(str[i] == '>') {
172 char* tmp = result;
173 result = cm_strcat(tmp, "&gt;");
174 free(tmp);
175 } else {
176 char* tmp = result;
177 result = cm_strcat(tmp, cbuf);
178 free(tmp);
179 }
180 }
181 return result;
182}
[21]183
184char* cm_url_escape(const char* str) {
185 int i;
186 char* result = malloc(1);
[212]187 char cbuf[2];
[21]188 result[0] = 0;
189 cbuf[1] = 0;
190 for(i = 0; str[i] != 0; i++) {
191 cbuf[0] = str[i];
192 if('!' <= str[i] && str[i] <= '@' && str[i] != '.' && str[i] != '-' && str[i] != '/' && !('0' <= str[i] && str[i] <= '9')) {
193 char code[4];
[212]194 char* tmp = result;
[21]195 sprintf(code, "%%%02X", str[i]);
196 result = cm_strcat(tmp, code);
197 free(tmp);
198 } else {
199 char* tmp = result;
200 result = cm_strcat(tmp, cbuf);
201 free(tmp);
202 }
203 }
204 return result;
205}
Note: See TracBrowser for help on using the repository browser.