Added new functions to escape non-printable characters. (epicsString)
This commit is contained in:
+129
-98
@@ -1,4 +1,5 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2009 Helmholtz-Zentrum Berlin fuer Materialien und Energie.
|
||||
* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
@@ -9,7 +10,7 @@
|
||||
/* $Id$ */
|
||||
|
||||
/* Authors: Jun-ichi Odagiri, Marty Kraimer, Eric Norum,
|
||||
* Mark Rivers, Andrew Johnson
|
||||
* Mark Rivers, Andrew Johnson, Ralph Lange
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -24,76 +25,149 @@
|
||||
#include "cantProceed.h"
|
||||
#include "epicsString.h"
|
||||
|
||||
/* Deprecated: This may be insecure; use epicsStrnRawFromEscaped instead */
|
||||
int dbTranslateEscape(char *to, const char *from)
|
||||
{
|
||||
size_t big_enough = strlen(from)+1;
|
||||
return epicsStrnRawFromEscaped(to, big_enough, from, big_enough);
|
||||
}
|
||||
|
||||
int epicsStrnRawFromEscaped(char *to, size_t outsize, const char *from, size_t inlen)
|
||||
{
|
||||
const char *pfrom = from;
|
||||
char *pto = to;
|
||||
char c;
|
||||
int nto=0;
|
||||
int nto=0, nfrom=0;
|
||||
|
||||
while( (c = *pfrom++ ) ){
|
||||
if(c=='\\') {
|
||||
switch( *pfrom ){
|
||||
case 'a': pfrom++; *pto++ = '\a' ; nto++; break;
|
||||
case 'b': pfrom++; *pto++ = '\b' ; nto++; break;
|
||||
case 'f': pfrom++; *pto++ = '\f' ; nto++; break;
|
||||
case 'n': pfrom++; *pto++ = '\n' ; nto++; break;
|
||||
case 'r': pfrom++; *pto++ = '\r' ; nto++; break;
|
||||
case 't': pfrom++; *pto++ = '\t' ; nto++; break;
|
||||
case 'v': pfrom++; *pto++ = '\v' ; nto++; break;
|
||||
case '\\': pfrom++; *pto++ = '\\' ; nto++; break;
|
||||
case '\?': pfrom++; *pto++ = '\?' ; nto++; break;
|
||||
case '\'': pfrom++; *pto++ = '\'' ; nto++; break;
|
||||
case '\"': pfrom++; *pto++ = '\"' ; nto++; break;
|
||||
case '0' :case '1' :case '2' :case '3' :
|
||||
case '4' :case '5' :case '6' :case '7' :
|
||||
{
|
||||
int i;
|
||||
char strval[4] = {0,0,0,0};
|
||||
unsigned int ival;
|
||||
unsigned char *pchar;
|
||||
while( (c = *pfrom++) && nto < outsize && nfrom < inlen){
|
||||
nfrom++;
|
||||
if(c == '\\') {
|
||||
if( nfrom >= inlen || *pfrom == '\0' ) break;
|
||||
switch( *pfrom ){
|
||||
case 'a': pfrom++; nfrom++; *pto++ = '\a' ; nto++; break;
|
||||
case 'b': pfrom++; nfrom++; *pto++ = '\b' ; nto++; break;
|
||||
case 'f': pfrom++; nfrom++; *pto++ = '\f' ; nto++; break;
|
||||
case 'n': pfrom++; nfrom++; *pto++ = '\n' ; nto++; break;
|
||||
case 'r': pfrom++; nfrom++; *pto++ = '\r' ; nto++; break;
|
||||
case 't': pfrom++; nfrom++; *pto++ = '\t' ; nto++; break;
|
||||
case 'v': pfrom++; nfrom++; *pto++ = '\v' ; nto++; break;
|
||||
case '\\': pfrom++; nfrom++; *pto++ = '\\' ; nto++; break;
|
||||
case '\?': pfrom++; nfrom++; *pto++ = '\?' ; nto++; break;
|
||||
case '\'': pfrom++; nfrom++; *pto++ = '\'' ; nto++; break;
|
||||
case '\"': pfrom++; nfrom++; *pto++ = '\"' ; nto++; break;
|
||||
case '0' :case '1' :case '2' :case '3' :
|
||||
case '4' :case '5' :case '6' :case '7' :
|
||||
{
|
||||
int i;
|
||||
char strval[4] = {0,0,0,0};
|
||||
unsigned int ival;
|
||||
unsigned char *pchar;
|
||||
|
||||
for(i=0; i<3; i++) {
|
||||
if((*pfrom < '0') || (*pfrom > '7')) break;
|
||||
strval[i] = *pfrom++;
|
||||
}
|
||||
sscanf(strval,"%o",&ival);
|
||||
pchar = (unsigned char *)(pto++); nto++;
|
||||
*pchar = (unsigned char)(ival);
|
||||
for(i=0; i<3; i++) {
|
||||
if((*pfrom < '0') || (*pfrom > '7')) break;
|
||||
strval[i] = *pfrom++; nfrom++;
|
||||
}
|
||||
sscanf(strval,"%o",&ival);
|
||||
pchar = (unsigned char *)(pto++); nto++;
|
||||
*pchar = (unsigned char)(ival);
|
||||
}
|
||||
break;
|
||||
case 'x' :
|
||||
{
|
||||
int i;
|
||||
char strval[3] = {0,0,0};
|
||||
unsigned int ival;
|
||||
unsigned char *pchar;
|
||||
|
||||
pfrom++; /*skip the x*/
|
||||
for(i=0; i<2; i++) {
|
||||
if(!isxdigit((int)*pfrom)) break;
|
||||
strval[i] = *pfrom++; nfrom++;
|
||||
}
|
||||
sscanf(strval,"%x",&ival);
|
||||
pchar = (unsigned char *)(pto++); nto++;
|
||||
*pchar = (unsigned char)(ival);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
*pto++ = *pfrom++; nfrom++; nto++;
|
||||
}
|
||||
break;
|
||||
case 'x' :
|
||||
{
|
||||
int i;
|
||||
char strval[3] = {0,0,0};
|
||||
unsigned int ival;
|
||||
unsigned char *pchar;
|
||||
|
||||
pfrom++; /*skip the x*/
|
||||
for(i=0; i<2; i++) {
|
||||
if(!isxdigit((int)*pfrom)) break;
|
||||
strval[i] = *pfrom++;
|
||||
}
|
||||
sscanf(strval,"%x",&ival);
|
||||
pchar = (unsigned char *)(pto++); nto++;
|
||||
*pchar = (unsigned char)(ival);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
*pto++ = *pfrom++;
|
||||
}
|
||||
} else {
|
||||
*pto++ = c; nto++;
|
||||
*pto++ = c; nto++;
|
||||
}
|
||||
}
|
||||
*pto = '\0'; /*NOTE that nto does not have to be incremented*/
|
||||
*pto = '\0'; /* NOTE that nto does not have to be incremented */
|
||||
return(nto);
|
||||
}
|
||||
|
||||
int epicsStrnEscapedFromRaw(char *outbuf, size_t outsize, const char *inbuf, size_t inlen)
|
||||
{
|
||||
int maxout = outsize;
|
||||
int nout = 0;
|
||||
int len;
|
||||
char *outpos = outbuf;
|
||||
|
||||
while (inlen--) {
|
||||
char c = *inbuf++;
|
||||
switch (c) {
|
||||
case '\a': len = epicsSnprintf(outpos, maxout, "\\a"); break;
|
||||
case '\b': len = epicsSnprintf(outpos, maxout, "\\b"); break;
|
||||
case '\f': len = epicsSnprintf(outpos, maxout, "\\f"); break;
|
||||
case '\n': len = epicsSnprintf(outpos, maxout, "\\n"); break;
|
||||
case '\r': len = epicsSnprintf(outpos, maxout, "\\r"); break;
|
||||
case '\t': len = epicsSnprintf(outpos, maxout, "\\t"); break;
|
||||
case '\v': len = epicsSnprintf(outpos, maxout, "\\v"); break;
|
||||
case '\\': len = epicsSnprintf(outpos, maxout, "\\\\"); ; break;
|
||||
/*? does not follow C convention because trigraphs no longer important*/
|
||||
case '\?': len = epicsSnprintf(outpos, maxout, "?"); break;
|
||||
case '\'': len = epicsSnprintf(outpos, maxout, "\\'"); break;
|
||||
case '\"': len = epicsSnprintf(outpos, maxout, "\\\""); break;
|
||||
default:
|
||||
if (isprint((int)c))
|
||||
len = epicsSnprintf(outpos, maxout, "%c", c);
|
||||
else
|
||||
len = epicsSnprintf(outpos, maxout, "\\%03o", (unsigned char)c);
|
||||
break;
|
||||
}
|
||||
if(len<0) return -1;
|
||||
nout += len;
|
||||
if(nout < outsize) {
|
||||
maxout -= len;
|
||||
outpos += len;
|
||||
} else {
|
||||
outpos = outpos + maxout -1;
|
||||
maxout = 1;
|
||||
}
|
||||
}
|
||||
*outpos = '\0';
|
||||
return nout;
|
||||
}
|
||||
|
||||
size_t epicsStrnEscapedFromRawSize(const char *inbuf, size_t inlen)
|
||||
{
|
||||
size_t nout = inlen;
|
||||
|
||||
while (inlen--) {
|
||||
char c = *inbuf++;
|
||||
switch (c) {
|
||||
case '\a': case '\b': case '\f': case '\n':
|
||||
case '\r': case '\t': case '\v': case '\\':
|
||||
case '\?': case '\'': case '\"':
|
||||
inlen++;
|
||||
break;
|
||||
default:
|
||||
if (!isprint((int)c))
|
||||
nout += 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return nout;
|
||||
}
|
||||
|
||||
int epicsStrCaseCmp(const char *s1, const char *s2)
|
||||
{
|
||||
int nexts1,nexts2;
|
||||
|
||||
|
||||
while(1) {
|
||||
/* vxWorks implementation expands argument more than once!!! */
|
||||
nexts1 = toupper(*s1);
|
||||
@@ -111,7 +185,7 @@ int epicsStrnCaseCmp(const char *s1, const char *s2, int n)
|
||||
{
|
||||
size_t ind = 0;
|
||||
int nexts1,nexts2;
|
||||
|
||||
|
||||
while(1) {
|
||||
if(ind++ >= (size_t)n) break;
|
||||
/* vxWorks implementation expands argument more than once!!! */
|
||||
@@ -161,49 +235,6 @@ int epicsStrPrintEscaped(FILE *fp, const char *s, int n)
|
||||
return nout;
|
||||
}
|
||||
|
||||
int epicsStrSnPrintEscaped(char *outbuf, int outsize, const char *inbuf,
|
||||
int inlen)
|
||||
{
|
||||
int maxout = outsize;
|
||||
int nout = 0;
|
||||
int len;
|
||||
char *outpos = outbuf;
|
||||
|
||||
while (inlen--) {
|
||||
char c = *inbuf++;
|
||||
switch (c) {
|
||||
case '\a': len = epicsSnprintf(outpos, maxout, "\\a"); break;
|
||||
case '\b': len = epicsSnprintf(outpos, maxout, "\\b"); break;
|
||||
case '\f': len = epicsSnprintf(outpos, maxout, "\\f"); break;
|
||||
case '\n': len = epicsSnprintf(outpos, maxout, "\\n"); break;
|
||||
case '\r': len = epicsSnprintf(outpos, maxout, "\\r"); break;
|
||||
case '\t': len = epicsSnprintf(outpos, maxout, "\\t"); break;
|
||||
case '\v': len = epicsSnprintf(outpos, maxout, "\\v"); break;
|
||||
case '\\': len = epicsSnprintf(outpos, maxout, "\\\\"); ; break;
|
||||
/*? does not follow C convention because trigraphs no longer important*/
|
||||
case '\?': len = epicsSnprintf(outpos, maxout, "?"); break;
|
||||
case '\'': len = epicsSnprintf(outpos, maxout, "\\'"); break;
|
||||
case '\"': len = epicsSnprintf(outpos, maxout, "\\\""); break;
|
||||
default:
|
||||
if (isprint((int)c))
|
||||
len = epicsSnprintf(outpos, maxout, "%c", c);
|
||||
else
|
||||
len = epicsSnprintf(outpos, maxout, "\\%03o", (unsigned char)c);
|
||||
break;
|
||||
}
|
||||
if(len<0) return -1;
|
||||
nout += len;
|
||||
if(nout < outsize) {
|
||||
maxout -= len;
|
||||
outpos += len;
|
||||
} else {
|
||||
outpos = outpos + maxout -1;
|
||||
maxout = 1;
|
||||
}
|
||||
}
|
||||
return nout;
|
||||
}
|
||||
|
||||
int epicsStrGlobMatch(const char *str, const char *pattern)
|
||||
{
|
||||
const char *cp=NULL, *mp=NULL;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2009 Helmholtz-Zentrum Berlin fuer Materialien und Energie.
|
||||
* Copyright (c) 2009 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
@@ -9,7 +10,7 @@
|
||||
/* $Id$ */
|
||||
|
||||
/* Authors: Jun-ichi Odagiri, Marty Kraimer, Eric Norum,
|
||||
* Mark Rivers, Andrew Johnson
|
||||
* Mark Rivers, Andrew Johnson, Ralph Lange
|
||||
*/
|
||||
|
||||
#ifndef INC_epicsString_H
|
||||
@@ -23,18 +24,23 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
epicsShareFunc int dbTranslateEscape(char *s,const char *ct);
|
||||
epicsShareFunc int epicsStrCaseCmp(const char *s1,const char *s2);
|
||||
epicsShareFunc int epicsStrnCaseCmp(const char *s1,const char *s2, int n);
|
||||
epicsShareFunc int epicsStrnRawFromEscaped(char *outbuf, size_t outsize,
|
||||
const char *inbuf, size_t inlen);
|
||||
epicsShareFunc int epicsStrnEscapedFromRaw(char *outbuf, size_t outsize,
|
||||
const char *inbuf, size_t inlen);
|
||||
epicsShareFunc size_t epicsStrnEscapedFromRawSize(const char *inbuf, size_t inlen);
|
||||
epicsShareFunc int epicsStrCaseCmp(const char *s1, const char *s2);
|
||||
epicsShareFunc int epicsStrnCaseCmp(const char *s1, const char *s2, int n);
|
||||
epicsShareFunc char * epicsStrDup(const char *s);
|
||||
epicsShareFunc int epicsStrPrintEscaped(FILE *fp, const char *s, int n);
|
||||
epicsShareFunc int epicsStrSnPrintEscaped(char *outbuf, int outsize,
|
||||
const char *inbuf, int inlen);
|
||||
#define epicsStrSnPrintEscaped epicsStrnEscapedFromRaw
|
||||
epicsShareFunc int epicsStrGlobMatch(const char *str, const char *pattern);
|
||||
epicsShareFunc char * epicsStrtok_r(char *s, const char *delim, char **lasts);
|
||||
epicsShareFunc unsigned int epicsStrHash(const char *str, unsigned int seed);
|
||||
epicsShareFunc unsigned int epicsMemHash(const char *str, size_t length,
|
||||
unsigned int seed);
|
||||
unsigned int seed);
|
||||
/* dbTranslateEscape is deprecated, use epicsStrnRawFromEscaped instead */
|
||||
epicsShareFunc int dbTranslateEscape(char *s, const char *ct);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user