helper to escape while printing strings
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
#include <unistd.h>
|
||||
#define HAVE_ISATTY
|
||||
@@ -13,6 +14,7 @@
|
||||
#include <deque>
|
||||
|
||||
#include <epicsTime.h>
|
||||
#include <epicsString.h>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/bitSet.h>
|
||||
@@ -436,4 +438,57 @@ std::ostream& operator<<(std::ostream& strm, const PVStructure::Formatter& forma
|
||||
return strm;
|
||||
}
|
||||
|
||||
static char hexdigit(char c) {
|
||||
c &= 0xf;
|
||||
if(c<9)
|
||||
return '0'+c;
|
||||
else
|
||||
return 'A'+c-10;
|
||||
}
|
||||
|
||||
escape::~escape() {}
|
||||
|
||||
std::string escape::str() const
|
||||
{
|
||||
std::ostringstream strm;
|
||||
strm<<(*this);
|
||||
return strm.str();
|
||||
}
|
||||
|
||||
epicsShareFunc
|
||||
std::ostream& operator<<(std::ostream& strm, const escape& Q)
|
||||
{
|
||||
for(size_t pos = 0, len = Q.orig.size(); pos < len; pos++) {
|
||||
const char C = Q.orig[pos];
|
||||
char quote = '\\', next;
|
||||
// compare me with epicsStrnEscapedFromRaw()
|
||||
switch(C) {
|
||||
case '\a': next = 'a'; break;
|
||||
case '\b': next = 'b'; break;
|
||||
case '\f': next = 'f'; break;
|
||||
case '\n': next = 'n'; break;
|
||||
case '\r': next = 'r'; break;
|
||||
case '\t': next = 't'; break;
|
||||
case '\v': next = 'v'; break;
|
||||
case '\\': next = '\\'; break;
|
||||
case '\'': next = '\''; break;
|
||||
case '\"': next = '\"'; if(Q.S==escape::CSV) quote = '"'; break;
|
||||
default:
|
||||
if(!isprint(C)) {
|
||||
// print three charator escape
|
||||
strm<<"\\x"<<hexdigit(C>>4)<<hexdigit(C);
|
||||
} else {
|
||||
// literal
|
||||
strm.put(C);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// print two charactor escape
|
||||
strm.put(quote);
|
||||
strm.put(next);
|
||||
}
|
||||
|
||||
return strm;
|
||||
}
|
||||
|
||||
}} //epics::pvData
|
||||
|
||||
@@ -208,6 +208,35 @@ static FORCE_INLINE
|
||||
typename detail::print_convolute<T>::return_t
|
||||
print_cast(const T& v) { return detail::print_convolute<T>::op(v); }
|
||||
|
||||
class escape;
|
||||
|
||||
epicsShareFunc
|
||||
std::ostream& operator<<(std::ostream& strm, const escape& Q);
|
||||
|
||||
//! Helper to print a string with escaping
|
||||
//! @code strm<<'"'<<escape(astring)<<'"' @endcode
|
||||
struct epicsShareClass escape
|
||||
{
|
||||
enum style_t {
|
||||
C, // default
|
||||
CSV, // a la RFC4180
|
||||
};
|
||||
private:
|
||||
const std::string& orig;
|
||||
style_t S;
|
||||
public:
|
||||
escape(const std::string& orig) :orig(orig), S(C) {}
|
||||
~escape();
|
||||
//! Change escaping style
|
||||
inline escape& style(style_t s) { S = s; return *this; }
|
||||
//! print to string and return. (alloc and copy)
|
||||
std::string str() const;
|
||||
|
||||
friend
|
||||
epicsShareFunc
|
||||
std::ostream& operator<<(std::ostream& strm, const escape& Q);
|
||||
};
|
||||
|
||||
}} // end namespace
|
||||
|
||||
#endif // PVTYPECAST_H
|
||||
|
||||
Reference in New Issue
Block a user