// This file is a part of the Framsticks GDK. // Copyright (C) 1999-2014 Maciej Komosinski and Szymon Ulatowski. See LICENSE.txt for details. // Refer to http://www.framsticks.com/ for further information. #include "sstringutils.h" #include #include #include int loadSString(const char* filename,SString& s,const char* framsgmodule,const char* error) { VirtFILE *f; int ret=0; if (f=Vfopen(filename,FOPEN_READ_BINARY)) { loadSString(f,s); ret=1; fclose(f); } else if (framsgmodule) FMprintf(framsgmodule,"loadSString",FMLV_WARN,error?error:"can't open file \"%s\"",filename); return ret; } void loadSString(VirtFILE *f,SString& s) { char buf[1024]; int len; while(!f->Veof()) { len=fread(buf,1,sizeof(buf),f); s.append(buf,len); } removeCR(s); } //load single line, discarding any \r or \n found at the end, return false if nothing could be loaded (error or eof) bool loadSStringLine(VirtFILE* f,SString& s) { char buf[100]; bool eolfound=false; bool ret=false; s=SString::empty(); while(!eolfound) { char *r=fgets(buf,sizeof(buf),f); if (r==NULL) break; ret=true; int d=strlen(r); if (d>0) { if (r[d-1]=='\n') {d--; eolfound=true;} if (d>0) if (r[d-1]=='\r') d--; s+=SString(r,d); } } return ret; } ////////////////////////// /** "x~xx~xxx" -> "x\~xx\~xxx" */ int quoteTilde(SString &target) { const char* x=target; SString tmp; char *f; while(1) { f=strchr((char*)x,'~'); if (f) { tmp.append(x,f-x); tmp+="\\~"; x=f+1; } else { if (tmp.len()==0) return 0; // nothing was changed! tmp+=x; target=tmp; return 1; } } } /** "x\~xx\~xxx" -> "x~xx~xxx" */ int unquoteTilde(SString &target) { const char* x=target; SString tmp; char *f; while(1) { f=strchr((char*)x,'\\'); if (f) { tmp.append(x,f-x); if (f[1]=='~') { tmp+='~'; x=f+2; } else { tmp+="\\"; x=f+1; } } else { if (tmp.len()==0) return 0; // nothing was changed! tmp+=x; target=tmp; return 1; } } } ///////////////// bool strContainsOneOf(const char* str,const char* chars) { while(*str) { if (strchr(chars,*str)) return 1; str++; } return 0; } ////////////// bool sstringQuote(SString& target) { const char* x=target; bool changed=0; SString tmp; tmp.memoryHint(target.len()); while(*x) { switch(*x) { case '\n': tmp+="\\n"; changed=1; break; case '\r': tmp+="\\r"; changed=1; break; case '\t': tmp+="\\t"; changed=1; break; case '\"': tmp+="\\\""; changed=1; break; case '\\': tmp+="\\\\"; changed=1; break; default: tmp+=*x; } x++; } if (changed) target=tmp; return changed; } const char* skipQuoteString(const char* txt, const char* limit) { while(*txt) { if (*txt=='\"') return txt; if (*txt=='\\') txt++; txt++; if (txt==limit) break; } return txt; } int sstringUnquote(SString &target) { const char* x=target; SString tmp; char *f; while(1) { f=strchr((char*)x,'\\'); if (f) { tmp.append(x,f-x); switch(f[1]) { case 'n': tmp+='\n'; break; case 'r': tmp+='\r'; break; case 't': tmp+='\t'; break; case '\"': tmp+='\"'; break; default: tmp+=f[1]; } x=f+2; } else { if (tmp.len()==0) return 0; // nothing was changed! tmp+=x; target=tmp; return 1; } } } int strFindField(const SString& txt,const SString& name,int &end) { const char* t=txt,*n; int pos=0; while(1) { n=strchr(t+pos,','); if ((!strncmp(t+pos,name,name.len()))&&(t[pos+name.len()]=='=')) { if (n) end=n-t; else end=txt.len(); return pos; } if (n) pos=n-t+1; else break; } return -1; } SString strGetField(const SString& txt,const SString& name) { int p,e; p=strFindField(txt,name,e); if (p<0) return SString(); p+=name.len()+1; return SString(txt.substr(p,e-p)); } void strSetField(SString& txt,const SString& name,const SString& value) { int p,e; p=strFindField(txt,name,e); if (p<0) { if (!value.len()) return; char *t=txt.directAppend(1+name.len()+value.len()); char *b=t; if (txt.len()) *(t++)=','; strcpy(t,name); t+=name.len(); *(t++)='='; strcpy(t,value); t+=value.len(); txt.endAppend(t-b); } else { if (!value.len()) { if (p>0) p--; else if (e