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
Line 
1/* $Id: string.c 212 2024-10-02 17:44:55Z nishi $ */
2
3#include <string.h>
4#include <stdlib.h>
5#include <stdbool.h>
6#include <stdio.h>
7#include <ctype.h>
8
9char* cm_strcat(const char* a, const char* b) {
10 char* str;
11 if(a == NULL) a = "";
12 if(b == NULL) b = "";
13 str = malloc(strlen(a) + strlen(b) + 1);
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
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
27char* cm_strdup(const char* str) { return cm_strcat(str, ""); }
28
29bool cm_endswith(const char* str, const char* end) {
30 int i;
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) {
39 int i;
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
47char* cm_trimstart(const char* str) {
48 int i;
49 for(i = 0; str[i] != 0; i++) {
50 if(str[i] != ' ' && str[i] != '\t') {
51 return cm_strdup(str + i);
52 }
53 }
54 return cm_strdup("");
55}
56
57char* cm_trimend(const char* str) {
58 char* s = cm_strdup(str);
59 int i;
60 for(i = strlen(s) - 1; i >= 0; i--) {
61 if(s[i] != '\t' && s[i] != ' ') {
62 s[i + 1] = 0;
63 break;
64 }
65 }
66 return s;
67}
68
69char* cm_trim(const char* str) {
70 char* tmp = cm_trimstart(str);
71 char* s = cm_trimend(tmp);
72 free(tmp);
73 return s;
74}
75
76char** cm_split(const char* str, const char* by) {
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;
83 r[0] = NULL;
84 b[0] = 0;
85 cbuf[1] = 0;
86 for(i = 0;; i++) {
87 int j;
88 bool has = false;
89 for(j = 0; by[j] != 0; j++) {
90 if(by[j] == str[i]) {
91 has = true;
92 break;
93 }
94 }
95 if(!(dq || sq) && (has || str[i] == 0)) {
96 if(strlen(b) > 0) {
97 char** old = r;
98 int j;
99 for(j = 0; old[j] != NULL; j++)
100 ;
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;
110 } else {
111 if(str[i] == '"' && !sq) {
112 dq = !dq;
113 } else if(str[i] == '\'' && !dq) {
114 sq = !sq;
115 } else {
116 char* tmp = b;
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
127bool cm_strcaseequ(const char* a, const char* b) {
128 int i;
129 if(a == NULL) return false;
130 if(b == NULL) return false;
131 if(strlen(a) != strlen(b)) return false;
132 for(i = 0; a[i] != 0; i++) {
133 if(tolower(a[i]) != tolower(b[i])) return false;
134 }
135 return true;
136}
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);
158 char cbuf[2];
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}
183
184char* cm_url_escape(const char* str) {
185 int i;
186 char* result = malloc(1);
187 char cbuf[2];
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];
194 char* tmp = result;
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.