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

Last change on this file since 224 was 210, checked in by Maciej Komosinski, 11 years ago

Added wildcard matching functions

  • Property svn:eol-style set to native
File size: 5.8 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{
12VirtFILE *f;
13int ret=0;
14if (f=Vfopen(filename,FOPEN_READ_BINARY))
15        {
16        loadSString(f,s);
17        ret=1;
18        fclose(f);
19        }
20else if (framsgmodule)
21        FMprintf(framsgmodule,"loadSString",FMLV_WARN,error?error:"can't open file \"%s\"",filename);
22return ret;
23}
24
25void loadSString(VirtFILE *f,SString& s)
26{
27char buf[1024];
28int len;
29while(!f->Veof())
30        {
31        len=fread(buf,1,sizeof(buf),f);
32        s.append(buf,len);
33        }
34removeCR(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{
40char buf[100];
41bool eolfound=false;
42bool ret=false;
43s=SString::empty();
44while(!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        }
57return ret;
58}
59
60//////////////////////////
61
62/** "x~xx~xxx" -> "x\~xx\~xxx"  */
63int quoteTilde(SString &target)
64{
65const char* x=target;
66SString tmp;
67char *f;
68while(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{
90const char* x=target;
91SString tmp;
92char *f;
93while(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{
124while(*str)
125        {
126        if (strchr(chars,*str)) return 1;
127        str++;
128        }
129return 0;
130}
131
132//////////////
133
134bool sstringQuote(SString& target)
135{
136const char* x=target;
137bool changed=0;
138SString tmp;
139tmp.memoryHint(target.len());
140while(*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        }
153if (changed) target=tmp;
154return changed;
155}
156
157const char* skipQuoteString(const char* txt, const char* limit)
158{
159while(*txt)
160        {
161        if (*txt=='\"') return txt;
162        if (*txt=='\\') txt++;
163        txt++;
164        if (txt==limit) break;
165        }
166return txt;
167}
168
169int sstringUnquote(SString &target)
170{
171const char* x=target;
172SString tmp;
173char *f;
174while(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{
202const char* t=txt,*n;
203int pos=0;
204while(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        }
214return -1;
215}
216
217SString strGetField(const SString& txt,const SString& name)
218{
219int p,e;
220p=strFindField(txt,name,e);
221if (p<0) return SString();
222p+=name.len()+1;
223return SString(txt.substr(p,e-p));
224}
225
226void strSetField(SString& txt,const SString& name,const SString& value)
227{
228int p,e;
229p=strFindField(txt,name,e);
230if (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        }
241else
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{
263const unsigned char*b=(const unsigned char*)(const char*)s;
264const unsigned char*e=b+s.len();
265while((b<e)&&(*b<=' ')) b++;
266while((b<e)&&(e[-1]<=' ')) e--;
267if ((e-b)==s.len()) return s;
268SString newstring;
269char* t=newstring.directWrite(e-b);
270memmove(t,b,e-b);
271newstring.endWrite(e-b);
272return newstring;
273}
274
275bool removeCR(SString& s)
276{
277const char* p=(const char*)s;
278const char* cr=strchr(p,'\r');
279if (!cr) return false;
280char* begin=s.directWrite();
281char* src=begin+(cr-p),*dst=src;
282while(*src)
283        if (*src=='\r')
284                src++;
285        else
286                *(dst++)=*(src++);
287s.endWrite(dst-begin);
288return true;
289}
290
291bool matchWildcard(const SString& word,const SString& pattern)
292{
293if (pattern.len()==0)
294        return word.len()==0;
295int aster=pattern.indexOf('*');
296if (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        }
309else
310        return word==pattern;
311}
312
313bool matchWildcardList(const SString& word,const SString& patterns)
314{
315if (patterns.len()==0)
316        return word.len()==0;
317int pos=0;
318SString pattern;
319while(patterns.getNextToken(pos,pattern,','))
320        if (matchWildcard(word,pattern))
321                return true;
322return false;
323}
324
Note: See TracBrowser for help on using the repository browser.