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

Last change on this file since 118 was 70, checked in by Nishi, on Sep 19, 2024 at 6:23:45 PM

patch for windows xp

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