util.c
1/* See LICENSE file for copyright and license details. */
2#include <string.h>
3#include "util.h"
4
5void string_replace(char *str, const char find, const char replace)
6{
7 char *pt = str;
8 while (*pt) {
9 if (*pt == find)
10 *pt = replace;
11 pt++;
12 }
13}
14
15void string_remove(char *str, const char *rem)
16{
17 char *pt = str;
18 const char *rpt = rem;
19 int length = strlen(rem);
20
21 while (*pt) {
22 if (*pt == *rpt) {
23 rpt++;
24 if (!*rpt) {
25 pt++;
26 memmove(pt - length, pt, 1 + strlen(pt));
27 rpt = rem;
28 pt -= length;
29 continue;
30 }
31 } else {
32 rpt = rem;
33 }
34 pt++;
35 }
36}
37
38void string_trim(char *str)
39{
40 char *pt = str;
41
42 while (*pt == ' ' || *pt == '\n')
43 pt++;
44
45 if (strlen(pt) == 0) {
46 str[0] = '\0';
47 } else {
48 memmove(str, pt, 1 + strlen(pt));
49 pt = str + strlen(str) - 1;
50
51 while (*pt == ' ' || *pt == '\n')
52 pt--;
53
54 memmove(pt + 1, str + strlen(str), strlen(pt + 1));
55 }
56}
57
58void string_remove_redundent_spaces(char *str)
59{
60 char *dest = str;
61
62 while (*str != '\0') {
63 while ((*str == ' ' && *(str + 1) == ' ')
64 || (*str == ' ' && *(str + 1) == '\n')
65 || (*str == ' ' && *(str - 1) == '\n'))
66 str++;
67 *dest++ = *str++;
68 }
69 *dest = '\0';
70}
71
72void dictionary_replace(char *str, const Dictionary *dict, int size)
73{
74 const Dictionary *entry = dict;
75 const Dictionary *end = dict + size;
76 const char *ent;
77 const char *rep;
78 char *ptr;
79 int ent_len;
80 int rep_len;
81
82 while (entry < end) {
83 ent = entry->entity;
84 rep = entry->replacement;
85 ent_len = strlen(ent);
86 rep_len = strlen(rep);
87
88 if (ent_len < rep_len) {
89 entry++;
90 continue;
91 }
92
93 ptr = str;
94 while (*ptr) {
95 if (*ptr == *ent++) {
96 if (*ent == '\0') {
97 ptr -= (ent_len - 1);
98
99 while (*rep)
100 *ptr++ = *rep++;
101
102 rep -= rep_len;
103 memmove(
104 ptr,
105 ptr + ent_len - rep_len,
106 1 + strlen(ptr + ent_len - rep_len)
107 );
108 continue;
109 }
110 } else if (*ptr == entry->entity[0]) {
111 ent = entry->entity + 1;
112 } else {
113 ent = entry->entity;
114 }
115 ptr++;
116 }
117 entry++;
118 }
119}
120
121int tiny_pow(int x, int y)
122{
123 int z = x;
124
125 if (y == 0)
126 return 1;
127
128 while (y-- > 1)
129 z *= x;
130
131 return z;
132}
133
134int hex_value(char c)
135{
136 if (c >= 0x30 && c <= 0x39)
137 return c - 0x30;
138 else if (c >= 0x41 && c <= 0x46)
139 return c - 0x37;
140 else if (c >= 0x61 && c <= 0x66)
141 return c - 0x57;
142 else
143 return -1;
144}
145
146void ucs_to_utf8(char *ucs)
147{
148 unsigned u = 0;
149 unsigned c = 0;
150 int length = strlen(ucs);
151 char *pt = ucs;
152
153 while (*pt)
154 u += hex_value(*pt++) * tiny_pow(16, length - 1 - c++);
155
156 pt = ucs;
157
158 if (u <= 0x7f) {
159 *pt++ = u;
160 } else if (u <= 0x7ff) {
161 *pt++ = 0xc0 | (u >> 6);
162 *pt++ = 0x80 | ((u >> 0) & 0x3f);
163 } else if (u <= 0xffff) {
164 *pt++ = 0xe0 | (u >> 12);
165 *pt++ = 0x80 | ((u >> 6) & 0x3f);
166 *pt++ = 0x80 | ((u >> 0) & 0x3f);
167 } else if (u <= 0x1fffff) {
168 *pt++ = 0xf0 | (u >> 18);
169 *pt++ = 0x80 | ((u >> 12) & 0x3f);
170 *pt++ = 0x80 | ((u >> 6) & 0x3f);
171 *pt++ = 0x80 | ((u >> 0) & 0x3f);
172 } else {
173 *pt++ = 0x3f;
174 }
175
176 *pt = '\0';
177}
178
179void unicode_decode(char *str)
180{
181 char buff[5];
182 char *pt = str;
183 char *bpt = buff;
184 const char indic[2] = { '\\', 'u' };
185 int c = 0;
186 int j = 0;
187
188 while (*pt) {
189 if (c < 2 && *pt == indic[c]) {
190 c++;
191 } else if (c >= 2 && c < 6 && hex_value(*pt) != -1) {
192 *bpt++ = *pt;
193 *bpt = '\0';
194 c++;
195 } else if (c == 6) {
196 ucs_to_utf8(buff);
197 bpt = buff;
198 pt -= c;
199 j = 0;
200
201 while (*bpt) {
202 *pt++ = *bpt++;
203 j++;
204 }
205
206 memmove(pt, pt + c - j, 1 + strlen(pt + c - j));
207
208 bpt = buff;
209 c = 0;
210 continue;
211 } else {
212 bpt = buff;
213 c = 0;
214 }
215 pt++;
216 }
217}