wikid

[discontinued] A quick and simple CLI-program for downloading and rendering wikipedia pages in the terminal.
git clone https://noxz.tech/git/wikid.git
Log | Files | README | LICENSE

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}