source: cpp/frams/util/sstringutils.cpp @ 257

Last change on this file since 257 was 257, checked in by Maciej Komosinski, 10 years ago
  • added strmove(): strcpy() for overlapping strings
  • ExtObject? operator== can handle NULL arguments
  • source formatting and improved genetic operator messages
  • Property svn:eol-style set to native
File size: 6.4 KB
Line 
1// This file is a part of the Framsticks GDK.
2// Copyright (C) 1999-2014  Maciej Komosinski and Szymon Ulatowski.  See LICENSE.txt for details.
3// Refer to http://www.framsticks.com/ for further information.
4
5#include "sstringutils.h"
6#include <frams/virtfile/virtfile.h>
7#include <common/framsg.h>
8#include <common/nonstd.h>
9
10int loadSString(const char* filename, SString& s, const char* framsgmodule, const char* error)
11{
12        VirtFILE *f;
13        int ret = 0;
14        if (f = Vfopen(filename, FOPEN_READ_BINARY))
15        {
16                loadSString(f, s);
17                ret = 1;
18                fclose(f);
19        }
20        else if (framsgmodule)
21                FMprintf(framsgmodule, "loadSString", FMLV_WARN, error ? error : "can't open file \"%s\"", filename);
22        return ret;
23}
24
25void loadSString(VirtFILE *f, SString& s)
26{
27        char buf[1024];
28        int len;
29        while (!f->Veof())
30        {
31                len = fread(buf, 1, sizeof(buf), f);
32                s.append(buf, len);
33        }
34        removeCR(s);
35}
36
37//load single line, discarding any \r or \n found at the end, return false if nothing could be loaded (error or eof)
38bool loadSStringLine(VirtFILE* f, SString& s)
39{
40        char buf[100];
41        bool eolfound = false;
42        bool ret = false;
43        s = SString::empty();
44        while (!eolfound)
45        {
46                char *r = fgets(buf, sizeof(buf), f);
47                if (r == NULL) break;
48                ret = true;
49                int d = strlen(r);
50                if (d > 0)
51                {
52                        if (r[d - 1] == '\n') { d--; eolfound = true; }
53                        if (d > 0) if (r[d - 1] == '\r') d--;
54                        s += SString(r, d);
55                }
56        }
57        return ret;
58}
59
60//////////////////////////
61
62/** "x~xx~xxx" -> "x\~xx\~xxx"  */
63int quoteTilde(SString &target)
64{
65        const char* x = target;
66        SString tmp;
67        char *f;
68        while (1)
69        {
70                f = strchr((char*)x, '~');
71                if (f)
72                {
73                        tmp.append(x, f - x);
74                        tmp += "\\~";
75                        x = f + 1;
76                }
77                else
78                {
79                        if (tmp.len() == 0) return 0; // nothing was changed!
80                        tmp += x;
81                        target = tmp;
82                        return 1;
83                }
84        }
85}
86
87/** "x\~xx\~xxx" -> "x~xx~xxx"  */
88int unquoteTilde(SString &target)
89{
90        const char* x = target;
91        SString tmp;
92        char *f;
93        while (1)
94        {
95                f = strchr((char*)x, '\\');
96                if (f)
97                {
98                        tmp.append(x, f - x);
99                        if (f[1] == '~')
100                        {
101                                tmp += '~';
102                                x = f + 2;
103                        }
104                        else
105                        {
106                                tmp += "\\";
107                                x = f + 1;
108                        }
109                }
110                else
111                {
112                        if (tmp.len() == 0) return 0; // nothing was changed!
113                        tmp += x;
114                        target = tmp;
115                        return 1;
116                }
117        }
118}
119
120/////////////////
121
122bool strContainsOneOf(const char* str, const char* chars)
123{
124        while (*str)
125        {
126                if (strchr(chars, *str)) return 1;
127                str++;
128        }
129        return 0;
130}
131
132//////////////
133
134bool sstringQuote(SString& target)
135{
136        const char* x = target;
137        bool changed = 0;
138        SString tmp;
139        tmp.memoryHint(target.len());
140        while (*x)
141        {
142                switch (*x)
143                {
144                case '\n': tmp += "\\n"; changed = 1; break;
145                case '\r': tmp += "\\r"; changed = 1; break;
146                case '\t': tmp += "\\t"; changed = 1; break;
147                case '\"': tmp += "\\\""; changed = 1; break;
148                case '\\': tmp += "\\\\"; changed = 1; break;
149                default: tmp += *x;
150                }
151                x++;
152        }
153        if (changed) target = tmp;
154        return changed;
155}
156
157const char* skipQuoteString(const char* txt, const char* limit)
158{
159        while (*txt)
160        {
161                if (*txt == '\"') return txt;
162                if (*txt == '\\') txt++;
163                txt++;
164                if (txt == limit) break;
165        }
166        return txt;
167}
168
169int sstringUnquote(SString &target)
170{
171        const char* x = target;
172        SString tmp;
173        char *f;
174        while (1)
175        {
176                f = strchr((char*)x, '\\');
177                if (f)
178                {
179                        tmp.append(x, f - x);
180                        switch (f[1])
181                        {
182                        case 'n': tmp += '\n'; break;
183                        case 'r': tmp += '\r'; break;
184                        case 't': tmp += '\t'; break;
185                        case '\"': tmp += '\"'; break;
186                        default: tmp += f[1];
187                        }
188                        x = f + 2;
189                }
190                else
191                {
192                        if (tmp.len() == 0) return 0; // nothing was changed!
193                        tmp += x;
194                        target = tmp;
195                        return 1;
196                }
197        }
198}
199
200int strFindField(const SString& txt, const SString& name, int &end)
201{
202        const char* t = txt, *n;
203        int pos = 0;
204        while (1)
205        {
206                n = strchr(t + pos, ',');
207                if ((!strncmp(t + pos, name, name.len())) && (t[pos + name.len()] == '='))
208                {
209                        if (n) end = n - t; else end = txt.len();
210                        return pos;
211                }
212                if (n) pos = n - t + 1; else break;
213        }
214        return -1;
215}
216
217SString strGetField(const SString& txt, const SString& name)
218{
219        int p, e;
220        p = strFindField(txt, name, e);
221        if (p < 0) return SString();
222        p += name.len() + 1;
223        return SString(txt.substr(p, e - p));
224}
225
226void strSetField(SString& txt, const SString& name, const SString& value)
227{
228        int p, e;
229        p = strFindField(txt, name, e);
230        if (p < 0)
231        {
232                if (!value.len()) return;
233                char *t = txt.directAppend(1 + name.len() + value.len());
234                char *b = t;
235                if (txt.len()) *(t++) = ',';
236                strcpy(t, name); t += name.len();
237                *(t++) = '=';
238                strcpy(t, value); t += value.len();
239                txt.endAppend(t - b);
240        }
241        else
242        {
243                if (!value.len())
244                {
245                        if (p > 0) p--; else if (e < txt.len()) e++;
246                        char *t = txt.directWrite(0);
247                        memmove(t + p, t + e, txt.len() - e);
248                        txt.endWrite(txt.len() + value.len() - (e - p));
249                }
250                else
251                {
252                        p += name.len() + 1;
253                        char *t = txt.directWrite(txt.len() + value.len() - (e - p));
254                        memmove(t + p + value.len(), t + e, txt.len() - e);
255                        memmove(t + p, value, value.len());
256                        txt.endWrite(txt.len() + value.len() - (e - p));
257                }
258        }
259}
260
261SString trim(SString& s)
262{
263        const unsigned char*b = (const unsigned char*)(const char*)s;
264        const unsigned char*e = b + s.len();
265        while ((b < e) && (*b <= ' ')) b++;
266        while ((b < e) && (e[-1] <= ' ')) e--;
267        if ((e - b) == s.len()) return s;
268        SString newstring;
269        char* t = newstring.directWrite(e - b);
270        memmove(t, b, e - b);
271        newstring.endWrite(e - b);
272        return newstring;
273}
274
275bool removeCR(SString& s)
276{
277        const char* p = (const char*)s;
278        const char* cr = strchr(p, '\r');
279        if (!cr) return false;
280        char* begin = s.directWrite();
281        char* src = begin + (cr - p), *dst = src;
282        while (*src)
283                if (*src == '\r')
284                        src++;
285                else
286                        *(dst++) = *(src++);
287        s.endWrite(dst - begin);
288        return true;
289}
290
291bool matchWildcard(const SString& word, const SString& pattern)
292{
293        if (pattern.len() == 0)
294                return word.len() == 0;
295        int aster = pattern.indexOf('*');
296        if (aster >= 0)
297        {
298                SString before = pattern.substr(0, aster);
299                SString after = pattern.substr(aster + 1);
300                int pos = 0;
301                if (!word.len()) return false;
302                if (before.len()) if (!word.startsWith(before)) return false;
303                if (after.len())
304                        if ((word.len() < after.len())
305                                || (strcmp((const char*)after, ((const char*)word) + word.len() - after.len())))
306                                return false;
307                return true;
308        }
309        else
310                return word == pattern;
311}
312
313bool matchWildcardList(const SString& word, const SString& patterns)
314{
315        if (patterns.len() == 0)
316                return word.len() == 0;
317        int pos = 0;
318        SString pattern;
319        while (patterns.getNextToken(pos, pattern, ','))
320                if (matchWildcard(word, pattern))
321                        return true;
322        return false;
323}
324
Note: See TracBrowser for help on using the repository browser.