Fix symbolic links
This commit is contained in:
parent
40d0fcff6f
commit
49f8bc7185
6 changed files with 1526 additions and 6 deletions
|
|
@ -1 +0,0 @@
|
|||
/home/zawz/code/c/tool/zFiledat/Filedat.hpp
|
||||
141
include/Filedat.hpp
Normal file
141
include/Filedat.hpp
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
#ifndef FILEDAT_H
|
||||
#define FILEDAT_H
|
||||
|
||||
#include "stringTools.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
//TESTS NEEDED
|
||||
|
||||
class AbstractChunk
|
||||
{
|
||||
public:
|
||||
enum typeEnum { none, val, chunk, list};
|
||||
|
||||
typeEnum type() { return m_type; }
|
||||
|
||||
AbstractChunk() { m_type=AbstractChunk::none; }
|
||||
virtual ~AbstractChunk() {}
|
||||
|
||||
protected:
|
||||
typeEnum m_type;
|
||||
};
|
||||
|
||||
class Chunk
|
||||
{
|
||||
public:
|
||||
Chunk() { m_achunk=nullptr; }
|
||||
Chunk(char* const in) { m_achunk=nullptr; set(std::string(in)); }
|
||||
Chunk(std::string const& in) { m_achunk=nullptr; set(in); }
|
||||
Chunk(Chunk const& in) { m_achunk=nullptr; set(in); }
|
||||
void clear() { if(m_achunk!=nullptr) delete m_achunk; m_achunk=nullptr; }
|
||||
~Chunk() { clear(); }
|
||||
|
||||
void set(std::string const& in);
|
||||
void set(Chunk const& in); //TO OPTIMIZE
|
||||
std::string strval(unsigned int alignment=0, std::string const& aligner="\t") const;
|
||||
|
||||
// bool concatenate(Chunk const& chk); //concatenates chunks
|
||||
bool addToChunk(std::string const& name, Chunk const& val); //adds if datachunk
|
||||
inline bool addToChunk(std::pair<std::string, Chunk> const& pair) { return add(pair.first, pair.second); } //adds if datachunk
|
||||
bool addToChunk(std::vector<std::pair<std::string, Chunk>> const& vec); //adds if datachunk
|
||||
bool addToList(Chunk const& val); //adds if list
|
||||
bool addToList(std::vector<Chunk> const& vec); //adds if list
|
||||
inline bool add(std::string const& name, Chunk const& val) { return addToChunk(name, val); } //adds if datachunk
|
||||
inline bool add(std::pair<std::string, Chunk> const& pair) { return add(pair.first, pair.second); } //adds if datachunk
|
||||
inline bool add(std::vector<std::pair<std::string, Chunk>> const& vec) { return addToChunk(vec); } //adds if datachunk
|
||||
inline bool add(Chunk const& val) { return addToList(val); } //adds if list
|
||||
inline bool add(std::vector<Chunk> const& vec) { return addToList(vec); } //adds if list
|
||||
|
||||
Chunk copy() const { return Chunk(*this); }
|
||||
Chunk* pcopy() const { return new Chunk(*this); }
|
||||
|
||||
AbstractChunk* getp() const { return m_achunk; }
|
||||
AbstractChunk::typeEnum type() const { if(m_achunk!=nullptr) return m_achunk->type(); else return AbstractChunk::none; }
|
||||
int listSize() const;
|
||||
|
||||
Chunk* subChunkPtr(std::string const& a) const; //datachunk
|
||||
Chunk* subChunkPtr(unsigned int a) const; //chunklist
|
||||
Chunk& subChunkRef(std::string const& a) const; //datachunk
|
||||
Chunk& subChunkRef(unsigned int a) const; //chunklist
|
||||
|
||||
Chunk& operator[](std::string const& a) const { return subChunkRef(a); }
|
||||
Chunk& operator[](unsigned int a) const { return subChunkRef(a); }
|
||||
Chunk& operator=(Chunk const& a) { set(a); return *this; }
|
||||
inline bool operator+=(std::pair<std::string, Chunk> const& a) { return addToChunk(a); }
|
||||
inline bool operator+=(std::vector<std::pair<std::string, Chunk>> const& a) { return addToChunk(a); }
|
||||
inline bool operator+=(Chunk const& a) { return addToList(a); }
|
||||
inline bool operator+=(std::vector<Chunk> const& a) { return addToList(a); }
|
||||
// inline bool operator*=(Chunk const& a) { concatenate(a); }
|
||||
|
||||
//add operator+ and operator*
|
||||
|
||||
protected:
|
||||
AbstractChunk* m_achunk;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, Chunk const& a);
|
||||
|
||||
class DataVal : public AbstractChunk
|
||||
{
|
||||
public:
|
||||
DataVal() { m_type=AbstractChunk::val; }
|
||||
virtual ~DataVal() {}
|
||||
|
||||
std::string val;
|
||||
};
|
||||
|
||||
class DataChunk : public AbstractChunk
|
||||
{
|
||||
public:
|
||||
DataChunk() { m_type=AbstractChunk::chunk; }
|
||||
virtual ~DataChunk();
|
||||
|
||||
std::map<std::string, Chunk*> values;
|
||||
|
||||
};
|
||||
|
||||
class ChunkList : public AbstractChunk
|
||||
{
|
||||
public:
|
||||
ChunkList() { m_type=AbstractChunk::list; }
|
||||
virtual ~ChunkList();
|
||||
|
||||
std::vector<Chunk*> list;
|
||||
};
|
||||
|
||||
class Filedat
|
||||
{
|
||||
public:
|
||||
Filedat();
|
||||
Filedat(std::string const& in);
|
||||
virtual ~Filedat();
|
||||
|
||||
bool readTest() const;
|
||||
|
||||
bool importFile();
|
||||
bool exportFile(std::string const& path="", std::string const& aligner="\t") const;
|
||||
|
||||
void clear();
|
||||
|
||||
std::string filePath() const { return m_filePath; }
|
||||
void setFilePath(std::string const& in) { m_filePath=in; }
|
||||
|
||||
std::string strval() const;
|
||||
|
||||
inline Chunk* pchunk() const { return m_dataChunk; }
|
||||
inline Chunk& chunk() const { return *m_dataChunk; }
|
||||
|
||||
inline Chunk* pdata() const { return m_dataChunk; }
|
||||
inline Chunk& data() const { return *m_dataChunk; }
|
||||
|
||||
private:
|
||||
std::string m_filePath;
|
||||
Chunk* m_dataChunk;
|
||||
};
|
||||
|
||||
#endif //FILEDAT_H
|
||||
|
|
@ -1 +0,0 @@
|
|||
/home/zawz/code/c/tool/zOptions/options.hpp
|
||||
55
include/options.hpp
Normal file
55
include/options.hpp
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#ifndef OPTIONS_H
|
||||
#define OPTIONS_H
|
||||
|
||||
//DUPLICATES NOT HANDLED: takes last one
|
||||
//NO ORDER: no way to know options order
|
||||
//RETURNS TRANSITIONAL STATE IF ERROR
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
std::vector<std::string> argVector(int argc, char** argv);
|
||||
|
||||
class Option
|
||||
{
|
||||
public:
|
||||
Option();
|
||||
Option(char c, bool arg);
|
||||
Option(std::string const& str, bool arg);
|
||||
Option(char c, std::string const& str, bool arg);
|
||||
virtual ~Option();
|
||||
|
||||
bool shortDef;
|
||||
char charName;
|
||||
|
||||
bool longDef;
|
||||
std::string strName;
|
||||
|
||||
bool activated;
|
||||
|
||||
bool takesArgument;
|
||||
std::string argument;
|
||||
};
|
||||
|
||||
class OptionSet
|
||||
{
|
||||
public:
|
||||
OptionSet();
|
||||
virtual ~OptionSet();
|
||||
|
||||
void addOption(Option opt) { m_options.push_back(opt); }
|
||||
|
||||
Option* findOption(char c);
|
||||
Option* findOption(std::string const& str);
|
||||
|
||||
std::ostream* errStream;
|
||||
|
||||
std::pair<std::vector<std::string>,bool> getOptions(std::vector<std::string> input);
|
||||
|
||||
private:
|
||||
std::vector<Option> m_options;
|
||||
|
||||
};
|
||||
|
||||
#endif //OPTIONS_H
|
||||
|
|
@ -1 +0,0 @@
|
|||
/home/zawz/code/c/tool/stringTools/stringTools.hpp
|
||||
131
include/stringTools.hpp
Normal file
131
include/stringTools.hpp
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
#ifndef READ_H
|
||||
#define READ_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include <stdint.h>
|
||||
|
||||
//NOTE: all functions here are probably not the most efficient
|
||||
|
||||
/*Translates string of 1 to 2 hex char into a byte
|
||||
returns 0 if an error occured
|
||||
*/
|
||||
uint8_t hexStringToByte(std::string const& in);
|
||||
|
||||
/*Translates an hex digit to its corresponding value
|
||||
*/
|
||||
int8_t hexDigitToNum(char car);
|
||||
|
||||
/*Translates a byte to a two char hex digit string
|
||||
*/
|
||||
std::string byteToHexString(uint8_t const& byte);
|
||||
|
||||
/*Translates a number into its hex char
|
||||
only answers correctly if 0<=num<16
|
||||
otherwise answers \0
|
||||
*/
|
||||
char toHexDigit(uint8_t const& num);
|
||||
|
||||
/*Reapeats n times string a
|
||||
*/
|
||||
std::string repeatString(std::string const& a, unsigned int n);
|
||||
|
||||
/*Repeats n times char a
|
||||
*/
|
||||
std::string repeatChar(char a, unsigned int n);
|
||||
|
||||
/*Returns true if it an alpha char
|
||||
*/
|
||||
bool isAlpha(char a);
|
||||
|
||||
/*Returns true if it a number char
|
||||
*/
|
||||
bool isNum(char a);
|
||||
|
||||
/*Returns true if it an hexadecimal char
|
||||
*/
|
||||
bool isHexdec(char a);
|
||||
|
||||
/*Checks if two strings are insensitively case equal
|
||||
*/
|
||||
bool equalNoCase(std::string const& st1, std::string const& st2);
|
||||
|
||||
/*Returns true if str1 and str2 have a common char
|
||||
*/
|
||||
bool hasCommonChar(std::string const& str1, std::string const& str2);
|
||||
|
||||
/*Fuses elements of a string vector, from [first] to [last] adding <separator> between each
|
||||
If separator = \0 , adds nothing
|
||||
if last < 0 , goes until the end
|
||||
*/
|
||||
std::string fuse(std::vector<std::string> const& vec, int first, int last=-1, char separator=' ');
|
||||
|
||||
/*Finds rank of char in string
|
||||
returns -1 if not found
|
||||
*/
|
||||
int findInString(std::string const& in, char const find);
|
||||
|
||||
/*Returns the number of times char has appeared in string
|
||||
*/
|
||||
unsigned int charCount(std::string const& in, char const find);
|
||||
|
||||
/*************************************/
|
||||
|
||||
bool isRead(char in); //Read characters (ascii-7bit) for following functions
|
||||
|
||||
/*Decapsulates the content of string
|
||||
If first read char is encapsulator, reads until decapsulator
|
||||
If not, just gets rid of unread char at beginning and end
|
||||
Encapsulators: "",{},[],<>
|
||||
*/
|
||||
std::string decapsulate(std::string const& in);
|
||||
|
||||
/*Removes unread chars at beggining and end of the string
|
||||
*/
|
||||
std::string ridUnread(std::string const& in);
|
||||
|
||||
/*Reads a variable of type string in a string.
|
||||
It's important to place the container characters right after the variable name
|
||||
ex: "variable={ text }"
|
||||
Smart reading, if another { is detected, it will wait for another } before ending
|
||||
Considers \n as the separator if there arent {}
|
||||
Reads only ascii-7bit
|
||||
*/
|
||||
std::string readInString(std::string const& in, std::string const& name, unsigned int occurence=0);
|
||||
|
||||
/*Same as above, but returns pair of value name and value itself of occurence given
|
||||
instead of value name
|
||||
puts beginning of value in rank if rank != nullptr
|
||||
*/
|
||||
std::pair<std::string, std::string> readValue(std::string const& in, unsigned int occurence=0, int* rank=nullptr);
|
||||
|
||||
/*Reads list in format [ , , ] and splits into vector
|
||||
*/
|
||||
std::vector<std::string> readList(std::string const& in);
|
||||
|
||||
/*Splits string using given delimiter. Uses space if not specified
|
||||
Between encapsulator and decapsulator: delims added
|
||||
INVALID DELIM: \ <encapsulator> <decapsulator>
|
||||
If delim is invalid, returns empty vector
|
||||
Does not include encapsulators in output
|
||||
\<char> adds \ and char, even if it is an encapsulator
|
||||
*/
|
||||
std::vector<std::string> splitString(std::string const& in, char const delim=' ', char encapsulator='\"', char decapsulator=0);
|
||||
|
||||
/*Replaces char f by r
|
||||
Returns number of char replaced
|
||||
*/
|
||||
int replaceChar(std::string& in, char const f,char const r);
|
||||
|
||||
/*Returns true if char c is in str
|
||||
*/
|
||||
bool isIn(char const c, std::string const& str);
|
||||
|
||||
/*Compacts suites of any chars from string chars, into char into
|
||||
note: equivalent to tr -s <chars> <into> in bash
|
||||
*/
|
||||
std::string encompact(std::string const& in, std::string const& chars=" \n\r\t\b", char const into=' ');
|
||||
|
||||
#endif // READ_H
|
||||
|
|
@ -1 +0,0 @@
|
|||
/home/zawz/code/c/tool/zFiledat/Filedat.cpp
|
||||
308
src/Filedat.cpp
Normal file
308
src/Filedat.cpp
Normal file
|
|
@ -0,0 +1,308 @@
|
|||
#include "Filedat.hpp"
|
||||
|
||||
#include <exception>
|
||||
|
||||
Filedat::Filedat()
|
||||
{
|
||||
m_dataChunk = nullptr;
|
||||
}
|
||||
|
||||
Filedat::Filedat(std::string const& in)
|
||||
{
|
||||
m_dataChunk = nullptr;
|
||||
m_filePath=in;
|
||||
}
|
||||
|
||||
Filedat::~Filedat()
|
||||
{
|
||||
if(m_dataChunk!=nullptr)
|
||||
{
|
||||
delete m_dataChunk;
|
||||
}
|
||||
}
|
||||
|
||||
void Filedat::clear()
|
||||
{
|
||||
if(m_dataChunk!=nullptr)
|
||||
{
|
||||
delete m_dataChunk;
|
||||
m_dataChunk = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool Filedat::readTest() const
|
||||
{
|
||||
std::ifstream stream(m_filePath);
|
||||
if(!stream)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Filedat::importFile()
|
||||
{
|
||||
std::ifstream stream(m_filePath);
|
||||
if(!stream)
|
||||
return false;
|
||||
|
||||
std::string str, line;
|
||||
while(stream)
|
||||
{
|
||||
getline(stream, line);
|
||||
str += (line + '\n');
|
||||
}
|
||||
this->clear();
|
||||
m_dataChunk = new Chunk(str);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Filedat::exportFile(std::string const& path, std::string const& aligner) const
|
||||
{
|
||||
std::ofstream stream;
|
||||
if(path=="")
|
||||
stream.open(m_filePath);
|
||||
else
|
||||
stream.open(path);
|
||||
if(!stream)
|
||||
return false;
|
||||
stream << this->strval();
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string Filedat::strval() const
|
||||
{
|
||||
if(m_dataChunk == nullptr)
|
||||
return "";
|
||||
else
|
||||
return m_dataChunk->strval();
|
||||
}
|
||||
|
||||
void Chunk::set(Chunk const& in)
|
||||
{
|
||||
this->set(in.strval());
|
||||
}
|
||||
|
||||
void Chunk::set(std::string const& in)
|
||||
{
|
||||
this->clear();
|
||||
std::string str=ridUnread(in);
|
||||
if(str[0]=='[')
|
||||
{
|
||||
std::vector<std::string> vstr = readList(in);
|
||||
ChunkList* cl = new ChunkList();
|
||||
for(auto it : vstr)
|
||||
{
|
||||
cl->list.push_back(new Chunk(it));
|
||||
}
|
||||
m_achunk=cl;
|
||||
}
|
||||
else if(str[0]=='{')
|
||||
{
|
||||
str=decapsulate(str);
|
||||
std::pair<std::string, std::string> pstr;
|
||||
int ti=0;
|
||||
DataChunk* dc = new DataChunk();
|
||||
while(str.size()>0 && ti>=0)
|
||||
{
|
||||
pstr = readValue(str,0,&ti);
|
||||
if(ti>=0)
|
||||
{
|
||||
dc->values.insert(std::make_pair(pstr.first , new Chunk(pstr.second)));
|
||||
if(ti > (int) str.size())
|
||||
throw std::runtime_error("Wrong file format at:\n" + str);
|
||||
str=str.substr(ti,str.size()-ti);
|
||||
}
|
||||
}
|
||||
m_achunk=dc;
|
||||
}
|
||||
else
|
||||
{
|
||||
DataVal* cv = new DataVal();
|
||||
cv->val = in;
|
||||
m_achunk=cv;
|
||||
}
|
||||
}
|
||||
|
||||
bool Chunk::addToChunk(std::string const& name, Chunk const& val)
|
||||
{
|
||||
if(this->type()==AbstractChunk::chunk)
|
||||
{
|
||||
DataChunk* cp = dynamic_cast<DataChunk*>(m_achunk);
|
||||
cp->values.insert(std::make_pair(name , new Chunk(val)));
|
||||
return true;
|
||||
}
|
||||
else if(this->type() == AbstractChunk::none)
|
||||
{
|
||||
DataChunk* cp = new DataChunk();
|
||||
cp->values.insert(std::make_pair(name , new Chunk(val)));
|
||||
m_achunk=cp;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Chunk::addToChunk(std::vector<std::pair<std::string, Chunk>> const& vec)
|
||||
{
|
||||
if(this->type()!=AbstractChunk::chunk && this->type()!=AbstractChunk::none)
|
||||
return false;
|
||||
for(auto it : vec)
|
||||
this->add(it.first, it.second);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Chunk::addToList(Chunk const& val)
|
||||
{
|
||||
if(this->type()==AbstractChunk::list)
|
||||
{
|
||||
ChunkList* lp = dynamic_cast<ChunkList*>(m_achunk);
|
||||
lp->list.push_back(new Chunk(val));
|
||||
return true;
|
||||
}
|
||||
else if(this->type() == AbstractChunk::none)
|
||||
{
|
||||
ChunkList* lp = new ChunkList();
|
||||
lp->list.push_back(new Chunk(val));
|
||||
m_achunk=lp;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Chunk::addToList(std::vector<Chunk> const& vec)
|
||||
{
|
||||
if(this->type()!=AbstractChunk::chunk && this->type()!=AbstractChunk::none)
|
||||
return false;
|
||||
for(auto it : vec)
|
||||
this->addToList(it);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string Chunk::strval(unsigned int alignment, std::string const& aligner) const
|
||||
{
|
||||
if(this->type()==AbstractChunk::val)
|
||||
{
|
||||
DataVal* vp = dynamic_cast<DataVal*>(m_achunk);
|
||||
return vp->val;
|
||||
}
|
||||
else if(this->type()==AbstractChunk::chunk)
|
||||
{
|
||||
DataChunk* cp = dynamic_cast<DataChunk*>(m_achunk);
|
||||
std::string ret="{\n";
|
||||
for(auto it : cp->values)
|
||||
{
|
||||
ret += repeatString(aligner,alignment+1);
|
||||
ret += it.first;
|
||||
ret += '=';
|
||||
if(it.second!=nullptr)
|
||||
ret += it.second->strval(alignment+1, aligner);
|
||||
ret += '\n';
|
||||
}
|
||||
ret += repeatString(aligner, alignment);
|
||||
ret += '}';
|
||||
return ret;
|
||||
}
|
||||
else if(this->type()==AbstractChunk::list)
|
||||
{
|
||||
ChunkList* lp = dynamic_cast<ChunkList*>(m_achunk);
|
||||
std::string ret="[\n";
|
||||
for(auto it : lp->list)
|
||||
{
|
||||
ret += repeatString(aligner, alignment+1);
|
||||
if(it!=nullptr)
|
||||
ret += it->strval(alignment+1, aligner);
|
||||
ret += ",\n";
|
||||
}
|
||||
ret.erase(ret.end()-2);
|
||||
ret += repeatString(aligner, alignment);
|
||||
ret += ']';
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
int Chunk::listSize() const
|
||||
{
|
||||
if(this->type() != AbstractChunk::list)
|
||||
return -1;
|
||||
ChunkList* cl = dynamic_cast<ChunkList*>(m_achunk);
|
||||
return cl->list.size();
|
||||
}
|
||||
|
||||
Chunk* Chunk::subChunkPtr(std::string const& in) const
|
||||
{
|
||||
if(this->type()==AbstractChunk::chunk)
|
||||
{
|
||||
DataChunk* dc = dynamic_cast<DataChunk*>(m_achunk);
|
||||
auto fi = dc->values.find(in);
|
||||
if(fi == dc->values.end()) //none found
|
||||
return nullptr;
|
||||
return fi->second;
|
||||
}
|
||||
else //not a chunk
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Chunk* Chunk::subChunkPtr(unsigned int a) const
|
||||
{
|
||||
if(this->type()==AbstractChunk::list)
|
||||
{
|
||||
ChunkList* cl = dynamic_cast<ChunkList*>(m_achunk);
|
||||
if(a >= cl->list.size()) //outside of range
|
||||
return nullptr;
|
||||
return cl->list[a];
|
||||
}
|
||||
else //not a list
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Chunk& Chunk::subChunkRef(std::string const& in) const
|
||||
{
|
||||
if(this->type()!=AbstractChunk::chunk)
|
||||
throw std::runtime_error("Chunk isn't a {}:" + this->strval());
|
||||
DataChunk* dc = dynamic_cast<DataChunk*>(m_achunk);
|
||||
auto fi = dc->values.find(in);
|
||||
if(fi == dc->values.end())
|
||||
throw std::runtime_error("Chunk doesn't have '" + in + "' flag:\n" + this->strval());
|
||||
return *fi->second;
|
||||
}
|
||||
|
||||
Chunk& Chunk::subChunkRef(unsigned int a) const
|
||||
{
|
||||
if(this->type()!=AbstractChunk::list)
|
||||
throw std::runtime_error("Chunk isn't a []:" + this->strval());
|
||||
ChunkList* cl = dynamic_cast<ChunkList*>(m_achunk);
|
||||
if(a >= cl->list.size())
|
||||
throw std::runtime_error("List size is below " + std::to_string(a) + ":\n" + this->strval());
|
||||
return *cl->list[a];
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, Chunk const& a)
|
||||
{
|
||||
stream << a.strval();
|
||||
return stream;
|
||||
}
|
||||
|
||||
DataChunk::~DataChunk()
|
||||
{
|
||||
for(auto it : values)
|
||||
{
|
||||
if(it.second != nullptr)
|
||||
delete it.second;
|
||||
}
|
||||
}
|
||||
|
||||
ChunkList::~ChunkList()
|
||||
{
|
||||
for(auto it : list)
|
||||
{
|
||||
if(it!=nullptr)
|
||||
delete it;
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
/home/zawz/code/c/tool/zOptions/options.cpp
|
||||
190
src/options.cpp
Normal file
190
src/options.cpp
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
#include "options.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
std::vector<std::string> argVector(int argc, char** argv)
|
||||
{
|
||||
std::vector<std::string> out;
|
||||
for(int i=1;i<argc; i++)
|
||||
{
|
||||
out.push_back(std::string(argv[i]));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
Option::Option()
|
||||
{
|
||||
shortDef=false;
|
||||
longDef=false;
|
||||
takesArgument=false;
|
||||
activated=false;
|
||||
charName=0;
|
||||
}
|
||||
Option::~Option()
|
||||
{
|
||||
}
|
||||
|
||||
Option::Option(char c, bool arg)
|
||||
{
|
||||
shortDef=true;
|
||||
longDef=false;
|
||||
takesArgument=arg;
|
||||
activated=false;
|
||||
charName=c;
|
||||
}
|
||||
|
||||
Option::Option(std::string const& str, bool arg)
|
||||
{
|
||||
shortDef=false;
|
||||
longDef=true;
|
||||
takesArgument=arg;
|
||||
activated=false;
|
||||
charName=0;
|
||||
strName=str;
|
||||
}
|
||||
Option::Option(char c, std::string const& str, bool arg)
|
||||
{
|
||||
shortDef=true;
|
||||
longDef=true;
|
||||
takesArgument=arg;
|
||||
activated=false;
|
||||
charName=c;
|
||||
strName=str;
|
||||
}
|
||||
|
||||
OptionSet::OptionSet()
|
||||
{
|
||||
errStream = &(std::cerr);
|
||||
}
|
||||
|
||||
OptionSet::~OptionSet()
|
||||
{
|
||||
}
|
||||
|
||||
Option* OptionSet::findOption(char c)
|
||||
{
|
||||
for( auto it=m_options.begin() ; it!=m_options.end() ; it++ )
|
||||
{
|
||||
if((*it).shortDef && (*it).charName == c)
|
||||
return &(*it);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
Option* OptionSet::findOption(std::string const& str)
|
||||
{
|
||||
for( auto it=m_options.begin() ; it!=m_options.end() ; it++ )
|
||||
{
|
||||
if((*it).longDef && (*it).strName == str)
|
||||
return &(*it);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::pair<std::vector<std::string>, bool> OptionSet::getOptions(std::vector<std::string> input)
|
||||
{
|
||||
std::vector<std::string> out;
|
||||
unsigned int i=0;
|
||||
for( auto it = input.begin(); it!=input.end() ; it++ )
|
||||
{
|
||||
if( (*it).size()>0 && (*it)[0]=='-' )
|
||||
{
|
||||
if((*it).size()>1 && (*it)[1]=='-')
|
||||
{
|
||||
std::size_t eqn=(*it).find('=');
|
||||
if(eqn == std::string::npos)
|
||||
{
|
||||
Option* popt = this->findOption( (*it).substr( 2,(*it).size()-2) );
|
||||
if(popt == nullptr)
|
||||
{
|
||||
(*errStream) << "Unknown option: " << (*it).substr(0,eqn) << std::endl;
|
||||
return std::make_pair(out, false);
|
||||
}
|
||||
if(popt->takesArgument)
|
||||
{
|
||||
if( ++it == input.end() ) //se termine ici
|
||||
{
|
||||
(*errStream) << "No argument given to option " << popt->strName << std::endl;
|
||||
return std::make_pair(out, false);
|
||||
}
|
||||
popt->activated = true;
|
||||
popt->argument = (*it);
|
||||
}
|
||||
else
|
||||
{
|
||||
popt->activated = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Option* popt = this->findOption( (*it).substr(2,eqn-2) );
|
||||
if(popt == nullptr)
|
||||
{
|
||||
(*errStream) << "Unknown option: " << (*it).substr(2,eqn-2) << std::endl;
|
||||
return std::make_pair(out, false);
|
||||
}
|
||||
if(!popt->takesArgument)
|
||||
{
|
||||
(*errStream) << "Option " << popt->strName << " doesn't take an argument" << std::endl;
|
||||
return std::make_pair(out, false);
|
||||
}
|
||||
popt->argument = (*it).substr(eqn+1,(*it).size()-eqn-1 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
i=1;
|
||||
Option* popt=nullptr;
|
||||
bool tstop=false;
|
||||
while( !tstop && it!=input.end() && (*it).size()>i )
|
||||
{
|
||||
popt=this->findOption((*it)[i]);
|
||||
if(popt==nullptr) //non trouvé: erreur
|
||||
{
|
||||
(*errStream) << "Unknown option: " << (*it)[i] << std::endl;
|
||||
return std::make_pair(out, false);
|
||||
}
|
||||
if(popt->takesArgument) //prends un argument
|
||||
{
|
||||
i++;
|
||||
if((*it).size()<=i) //se termine ici
|
||||
{
|
||||
if( ++it == input.end() ) //se termine ici
|
||||
{
|
||||
(*errStream) << "No argument given to option -" << popt->charName << std::endl;
|
||||
return std::make_pair(out, false);
|
||||
}
|
||||
popt->activated = true;
|
||||
popt->argument = (*it);
|
||||
tstop = true;
|
||||
}
|
||||
else //continue
|
||||
{
|
||||
if( (*it)[i] != '=') //incorrect
|
||||
{
|
||||
(*errStream) << "No argument given to option -" << popt->charName << std::endl;
|
||||
return std::make_pair(out, false);
|
||||
}
|
||||
i++;
|
||||
popt->argument = (*it).substr(i , (*it).size()-i );
|
||||
popt->activated = true;
|
||||
tstop=true;
|
||||
}
|
||||
}
|
||||
else // ne prends pas d'argument
|
||||
{
|
||||
popt->activated = true;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
out.push_back(*it);
|
||||
}
|
||||
if(it == input.end())
|
||||
break;
|
||||
}
|
||||
return std::make_pair(out, true);
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
/home/zawz/code/c/tool/stringTools/stringTools.cpp
|
||||
701
src/stringTools.cpp
Normal file
701
src/stringTools.cpp
Normal file
|
|
@ -0,0 +1,701 @@
|
|||
#include "stringTools.hpp"
|
||||
|
||||
uint8_t hexStringToByte(std::string const& in)
|
||||
{
|
||||
if(in.size() == 2)
|
||||
{
|
||||
return hexDigitToNum(in[0])*16 + hexDigitToNum(in[1]);
|
||||
}
|
||||
if(in.size() == 1)
|
||||
{
|
||||
return hexDigitToNum(in[0]);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t hexDigitToNum(char car)
|
||||
{
|
||||
if(isNum(car))
|
||||
return car - '0';
|
||||
else if(car>='a' && car<='f')
|
||||
return car - 'a' + 10;
|
||||
else if(car>='A' && car<='F')
|
||||
return car - 'A' + 10;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string byteToHexString(uint8_t const& byte)
|
||||
{
|
||||
std::string ret;
|
||||
ret += toHexDigit(byte/16);
|
||||
ret += toHexDigit(byte%16);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char toHexDigit(uint8_t const& num)
|
||||
{
|
||||
if(num>=0 && num<=9)
|
||||
{
|
||||
return '0' + num;
|
||||
}
|
||||
else if(num < 16)
|
||||
{
|
||||
return 'A' + num - 10;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string repeatString(std::string const& a, unsigned int n)
|
||||
{
|
||||
std::string ret;
|
||||
while(n>0)
|
||||
{
|
||||
ret += a;
|
||||
n--;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string repeatChar(char a, unsigned int n)
|
||||
{
|
||||
std::string ret;
|
||||
while(n>0)
|
||||
{
|
||||
ret.push_back(a);
|
||||
n--;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool isAlpha(char a)
|
||||
{
|
||||
return (a>='a' && a<='z') || (a>='A' && a<='Z');
|
||||
}
|
||||
|
||||
bool isNum(char a)
|
||||
{
|
||||
return (a>='0' && a<='9');
|
||||
}
|
||||
|
||||
bool isHexdec(char a)
|
||||
{
|
||||
return isNum(a) || (a>='a' && a<='f') || (a>='A' && a<='F');
|
||||
}
|
||||
|
||||
bool equalNoCase(char a, char b)
|
||||
{
|
||||
if(a==b)
|
||||
return true;
|
||||
if(!isAlpha(a) || !isAlpha(b))
|
||||
return false;
|
||||
return (a-b == 'a' - 'A') || (a-b == 'A' - 'a');
|
||||
}
|
||||
|
||||
bool equalNoCase(std::string const& st1, std::string const& st2)
|
||||
{
|
||||
if(st1.size()!=st2.size())
|
||||
return false;
|
||||
for(unsigned int i=0; i<st1.size(); i++)
|
||||
{
|
||||
if(!equalNoCase(st1[i],st2[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hasCommonChar(std::string const& str1, std::string const& str2)
|
||||
{
|
||||
if(str1.size() < str2.size())
|
||||
{
|
||||
for(std::string::const_iterator it = str1.begin(); it!= str1.end(); it++)
|
||||
if(str2.find(*it))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
for(std::string::const_iterator it = str2.begin(); it!= str2.end(); it++)
|
||||
if(str1.find(*it))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string fuse(std::vector<std::string> const& vec, int first, int last, char separator)
|
||||
{
|
||||
if(last<0 || last >= (int) vec.size())
|
||||
last=vec.size()-1;
|
||||
if(first<0)
|
||||
first=0;
|
||||
std::string ret;
|
||||
if(first <= last)
|
||||
{
|
||||
for(int i=first; i<=last-1; i++)
|
||||
{
|
||||
ret+=vec[i];
|
||||
if(separator != 0)
|
||||
ret+=separator;
|
||||
}
|
||||
ret += vec[last];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int findInString(std::string const& in, char const find)
|
||||
{
|
||||
for(unsigned int i=0; i<in.size(); i++)
|
||||
{
|
||||
if(in[i]==find)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned int charCount(std::string const& in, char const find)
|
||||
{
|
||||
return std::count(in.begin(), in.end(), find);
|
||||
}
|
||||
|
||||
bool isRead(char in)
|
||||
{
|
||||
bool out=false;
|
||||
if(in>=33 && in<=126)
|
||||
out=true;
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string decapsulate(std::string const& in)
|
||||
{
|
||||
unsigned int i=0,j;
|
||||
while(i<in.size() && !isRead(in[i]))
|
||||
i++;
|
||||
j=i;
|
||||
if(i<in.size() && in[i]=='\"')
|
||||
{
|
||||
i++;
|
||||
j++;
|
||||
while(i<in.size() && in[i]!='\"')
|
||||
{
|
||||
if(in[i]=='\\')
|
||||
i++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else if(i<in.size() && in[i]=='[')
|
||||
{
|
||||
unsigned int counter=0;
|
||||
i++;
|
||||
j++;
|
||||
while(i<in.size() && !(in[i]==']' && counter==0))
|
||||
{
|
||||
if(in[i]=='\\')
|
||||
i++;
|
||||
if(in[i]=='[')
|
||||
counter++;
|
||||
if(in[i]==']')
|
||||
counter--;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else if(i<in.size() && in[i]=='{')
|
||||
{
|
||||
unsigned int counter=0;
|
||||
i++;
|
||||
j++;
|
||||
while(i<in.size() && !(in[i]=='}' && counter==0))
|
||||
{
|
||||
if(in[i]=='\\')
|
||||
i++;
|
||||
if(in[i]=='{')
|
||||
counter++;
|
||||
if(in[i]=='}')
|
||||
counter--;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else if(i<in.size() && in[i]=='(')
|
||||
{
|
||||
unsigned int counter=0;
|
||||
i++;
|
||||
j++;
|
||||
while(i<in.size() && !(in[i]==')' && counter==0))
|
||||
{
|
||||
if(in[i]=='\\')
|
||||
i++;
|
||||
if(in[i]=='(')
|
||||
counter++;
|
||||
if(in[i]==')')
|
||||
counter--;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else if(i<in.size() && in[i]=='<')
|
||||
{
|
||||
unsigned int counter=0;
|
||||
i++;
|
||||
j++;
|
||||
while(i<in.size() && !(in[i]=='>' && counter==0))
|
||||
{
|
||||
if(in[i]=='\\')
|
||||
i++;
|
||||
if(in[i]=='<')
|
||||
counter++;
|
||||
if(in[i]=='>')
|
||||
counter--;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
i=in.size()-1;
|
||||
while(i<in.size() && i>0 && !isRead(in[i]))
|
||||
{
|
||||
i--;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return in.substr(j,i-j);
|
||||
}
|
||||
|
||||
std::string ridUnread(std::string const& in)
|
||||
{
|
||||
int i=0,j=in.size()-1;
|
||||
while( ((unsigned int) i)<in.size() && !isRead(in[i]))
|
||||
i++;
|
||||
while(j>=0 && !isRead(in[j]))
|
||||
j--;
|
||||
if(i<=j)
|
||||
return in.substr(i, j-i+1);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string readInString(std::string const& in, std::string const& name, unsigned int occurence)
|
||||
{
|
||||
bool found=false;
|
||||
std::string out="";
|
||||
unsigned int i=0,j=0,reading=0;
|
||||
while(i<in.size() && !found)
|
||||
{
|
||||
if(!isRead(in[i])) /*Lire jusqu'à un caractère lu (ingorer les espaces etc...)*/
|
||||
i++;
|
||||
else if(i<in.size()+name.size()+1 && (in.substr(i,name.size()+1)==name+"=" || (in.substr(i,name.size()+1)==name+":") ) ) /*La valeur qu'on veut*/
|
||||
{
|
||||
if(occurence==reading) /*Si c'est l'occurence que l'on veut*/
|
||||
{
|
||||
unsigned int counter=0;
|
||||
i+=name.size()+1;
|
||||
j=i;
|
||||
if(in[i]=='{') /*Valeur encapsulée*/
|
||||
{
|
||||
i++;
|
||||
j++;
|
||||
while(i<in.size() && !(in[i]=='}' && counter==0))
|
||||
{
|
||||
if(in[i]=='\\')
|
||||
i++;
|
||||
else if(in[i]=='{')
|
||||
counter++;
|
||||
else if(in[i]=='}')
|
||||
counter--;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else if(in[i]=='\"')
|
||||
{
|
||||
i++;
|
||||
j++;
|
||||
while(i<in.size() && in[i]!='\"')
|
||||
{
|
||||
if(in[i]=='\\')
|
||||
i++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else /*Valeur non encapsulée: jusqu'à \n*/
|
||||
{
|
||||
i++;
|
||||
while(i<in.size() && in[i]!='\n')
|
||||
i++;
|
||||
}
|
||||
found=true;
|
||||
out=in.substr(j,i-j);
|
||||
}
|
||||
else /*On veut une autre occurence: passer cette valeur là*/
|
||||
{
|
||||
reading++;
|
||||
i+=name.size()+1;
|
||||
unsigned int counter=0;
|
||||
if(i<in.size() && in[i]=='{') /*Encapsulée*/
|
||||
{
|
||||
i++;
|
||||
while(i<in.size() && !(in[i]=='}' && counter==0))
|
||||
{
|
||||
if(in[i]=='\\')
|
||||
i++;
|
||||
if(in[i]=='{')
|
||||
counter++;
|
||||
if(in[i]=='}')
|
||||
counter--;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else if(in[i]=='\"')
|
||||
{
|
||||
i++;
|
||||
while(i<in.size() && in[i]!='\"')
|
||||
{
|
||||
if(in[i]=='\\')
|
||||
i++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else /*Jusqu'à \n*/
|
||||
while(i<in.size() && in[i]!='\n')
|
||||
i++;
|
||||
|
||||
}
|
||||
}
|
||||
else /*Pas la valeur qu'on veut*/
|
||||
{
|
||||
while(i<in.size() && in[i]!='=' && in[i]!='\n' && in[i]!=' ' && in[i]!='\t' && in[i]!='\r')
|
||||
i++;
|
||||
if(i<in.size() && in[i]=='=')
|
||||
i++;
|
||||
if(i<in.size() && in[i]=='{')
|
||||
{
|
||||
unsigned int counter=0;
|
||||
i++;
|
||||
while(i<in.size() && !(in[i]=='}' && counter==0))
|
||||
{
|
||||
if(in[i]=='\\')
|
||||
i++;
|
||||
if(in[i]=='{')
|
||||
counter++;
|
||||
if(in[i]=='}')
|
||||
counter--;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else if(i<in.size() && in[i]=='\"')
|
||||
{
|
||||
i++;
|
||||
while(i<in.size() && in[i]!='\"')
|
||||
{
|
||||
if(in[i]=='\\')
|
||||
i++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
std::pair<std::string,std::string> readValue(std::string const& in, unsigned int occurence, int* rank)
|
||||
{
|
||||
std::string name="";
|
||||
unsigned int i=0,j=0,reading=0;
|
||||
while(i<in.size())
|
||||
{
|
||||
while(!isRead(in[i])) /*Lire jusqu'à un caractère lu (ingorer les espaces etc...)*/
|
||||
i++;
|
||||
if(i>=in.size())
|
||||
{
|
||||
if(rank != nullptr)
|
||||
*rank=-1;
|
||||
return std::make_pair("","");
|
||||
}
|
||||
while(in[i]!='=' && in[i]!=':') //lire le nom
|
||||
{
|
||||
name += in[i];
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
if(occurence==reading) /*Si c'est l'occurence que l'on veut*/
|
||||
{
|
||||
unsigned int counter=0;
|
||||
j=i;
|
||||
if(in[i]=='{') /*Valeur encapsulée*/
|
||||
{
|
||||
i++;
|
||||
while(i<in.size() && !(in[i]=='}' && counter==0))
|
||||
{
|
||||
if(in[i]=='\\')
|
||||
i++;
|
||||
else if(in[i]=='\"') //skip quotes
|
||||
{
|
||||
i++;
|
||||
while(i<in.size() && in[i]!='\"') i++;
|
||||
i++;
|
||||
}
|
||||
else if(in[i]=='{')
|
||||
counter++;
|
||||
else if(in[i]=='}')
|
||||
counter--;
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
if(rank!=nullptr)
|
||||
*rank=i;
|
||||
return std::make_pair(name, in.substr(j,i-j));
|
||||
}
|
||||
else if(in[i]=='[') /*Valeur encapsulée*/
|
||||
{
|
||||
i++;
|
||||
while(i<in.size() && !(in[i]==']' && counter==0))
|
||||
{
|
||||
if(in[i]=='\\')
|
||||
i++;
|
||||
else if(in[i]=='\"') //skip quotes
|
||||
{
|
||||
i++;
|
||||
while(i<in.size() && in[i]!='\"') i++;
|
||||
i++;
|
||||
}
|
||||
else if(in[i]=='[')
|
||||
counter++;
|
||||
else if(in[i]==']')
|
||||
counter--;
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
if(rank!=nullptr)
|
||||
*rank=i;
|
||||
return std::make_pair(name, in.substr(j,i-j));
|
||||
}
|
||||
else if(in[i]=='\"')
|
||||
{
|
||||
i++;
|
||||
j++;
|
||||
while(i<in.size() && in[i]!='\"')
|
||||
{
|
||||
if(in[i]=='\\')
|
||||
i++;
|
||||
i++;
|
||||
}
|
||||
if(rank!=nullptr)
|
||||
*rank=i+1;
|
||||
std::string ret;
|
||||
ret += '\"';
|
||||
ret += in.substr(j,i-j);
|
||||
ret += '\"';
|
||||
return std::make_pair(name, ret);
|
||||
}
|
||||
else /*Valeur non encapsulée: jusqu'à \n*/
|
||||
{
|
||||
i++;
|
||||
while(i<in.size() && in[i]!='\n')
|
||||
i++;
|
||||
if(rank!=nullptr)
|
||||
*rank=i;
|
||||
if(i>in.size())
|
||||
i=in.size();
|
||||
if(j>in.size())
|
||||
j=in.size();
|
||||
return std::make_pair(name, in.substr(j,i-j));
|
||||
}
|
||||
}
|
||||
else /*On veut une autre occurence: passer cette valeur là*/
|
||||
{
|
||||
reading++;
|
||||
i+=name.size()+1;
|
||||
unsigned int counter=0;
|
||||
if(i<in.size() && in[i]=='{') /*Encapsulée*/
|
||||
{
|
||||
i++;
|
||||
while(i<in.size() && !(in[i]=='}' && counter==0))
|
||||
{
|
||||
if(in[i]=='\\')
|
||||
i++;
|
||||
if(in[i]=='\"') //quote skip
|
||||
{
|
||||
i++;
|
||||
while(i<in.size() && in[i]!='\"') i++;
|
||||
}
|
||||
if(in[i]=='{')
|
||||
counter++;
|
||||
if(in[i]=='}')
|
||||
counter--;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else if(in[i]=='\"') //quote
|
||||
{
|
||||
i++;
|
||||
while(i<in.size() && in[i]!='\"')
|
||||
{
|
||||
if(in[i]=='\\')
|
||||
i++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else /*Jusqu'à \n*/
|
||||
while(i<in.size() && in[i]!='\n')
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if(rank!=nullptr)
|
||||
*rank=-1;
|
||||
return std::make_pair("","");
|
||||
}
|
||||
|
||||
std::vector<std::string> readList(std::string const& in)
|
||||
{
|
||||
unsigned int i=0,j=0,counter=0;
|
||||
std::vector<std::string> out;
|
||||
while(i<in.size() && in[i]!='[')
|
||||
i++;
|
||||
if(in[i]=='[')
|
||||
{
|
||||
i++;
|
||||
while(i<in.size() && in[i]!=']' && counter==0)
|
||||
{
|
||||
j=i;
|
||||
while(i<in.size() && !(in[i]==',' && counter==0) && !(in[i]==']' && counter==0) )
|
||||
{
|
||||
if(in[i]=='\\')
|
||||
i++;
|
||||
else if(in[i]=='{')
|
||||
{
|
||||
i++;
|
||||
unsigned int counter2=0;
|
||||
while( i<in.size() && (in[i]!='}' || counter2!=0) )
|
||||
{
|
||||
if(in[i]=='\\')
|
||||
i++;
|
||||
else if(in[i]=='{')
|
||||
counter2++;
|
||||
else if(in[i]=='}')
|
||||
counter2--;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else if(in[i]=='\"')
|
||||
{
|
||||
i++;
|
||||
while(in[i]!='\"')
|
||||
{
|
||||
if(in[i]=='\\')
|
||||
i++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(i<in.size() && in[i]=='[')
|
||||
counter++;
|
||||
if(i<in.size() && in[i]==']')
|
||||
counter--;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if((in[i]==',' || in[i]==']') && counter==0)
|
||||
out.push_back(ridUnread(in.substr(j,i-j)));
|
||||
else
|
||||
out.push_back(ridUnread(in.substr(j,i-j+1)));
|
||||
if(in[i]==',')
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if ( out.size() == 1 && out[0]=="" )
|
||||
return std::vector<std::string>();
|
||||
return out;
|
||||
}
|
||||
|
||||
std::vector<std::string> splitString(std::string const& in, char const delim, char encapsulator, char decapsulator)
|
||||
{
|
||||
std::vector<std::string> out;
|
||||
if(delim!='\\' && delim!=encapsulator && delim!=decapsulator)
|
||||
{
|
||||
if(decapsulator==0)
|
||||
decapsulator=encapsulator;
|
||||
unsigned int i=0;
|
||||
while(i<in.size())
|
||||
{
|
||||
std::string t="";
|
||||
while(i<in.size() && in[i]!=delim)
|
||||
{
|
||||
if(i<in.size() && in[i]==encapsulator)
|
||||
{
|
||||
i++;
|
||||
while(i<in.size() && in[i]!=decapsulator)
|
||||
{
|
||||
if(in[i]=='\\')
|
||||
{
|
||||
i++;
|
||||
t.push_back('\\');
|
||||
t.push_back(in[i]);
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
t.push_back(in[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
else if(in[i]=='\\')
|
||||
{
|
||||
i++;
|
||||
if(i<in.size() && in[i]=='n')
|
||||
{
|
||||
t.push_back(10);
|
||||
}
|
||||
else
|
||||
t.push_back(in[i]);
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
t.push_back(in[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
out.push_back(t);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
int replaceChar(std::string& in, char const f,char const r)
|
||||
{
|
||||
int j=0;
|
||||
for(unsigned int i=0;i<in.size();i++)
|
||||
if(in[i]==f)
|
||||
{
|
||||
in[i]=r;
|
||||
j++;
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
bool isIn(char const c, std::string const& str)
|
||||
{
|
||||
return str.find(c) != std::string::npos;
|
||||
}
|
||||
|
||||
std::string encompact(std::string const& in, std::string const& chars, char const into)
|
||||
{
|
||||
std::string out;
|
||||
unsigned int i=0,j=0;
|
||||
while(i<in.size())
|
||||
{
|
||||
j=i;
|
||||
while(isIn(in[i],chars))
|
||||
i++;
|
||||
if(j!=i)
|
||||
{
|
||||
out.push_back(into);
|
||||
}
|
||||
else
|
||||
{
|
||||
out.push_back(in[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
Loading…
Reference in a new issue