ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/tewi/Common/string.c
Revision: 1.1
Committed: Thu Oct 17 09:53:38 2024 UTC (4 weeks, 1 day ago) by nishi
Content type: text/x-c
Branch: MAIN
CVS Tags: v2_05A, v2_05, HEAD
Log Message:
update

File Contents

# User Rev Content
1 nishi 1.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    
9     char* 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    
20     char* 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    
27     char* cm_strdup(const char* str) { return cm_strcat(str, ""); }
28    
29     bool 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    
38     bool 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    
47     char* 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    
57     char* 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    
69     char* 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    
76     char** 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    
127     bool 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    
138     int 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    
155     char* 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    
184     char* 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     }