/*************************************************************************\ * Copyright (c) 2002 The University of Chicago, as Operator of Argonne * National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. * EPICS BASE Versions 3.13.7 * and higher are distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. \*************************************************************************/ /*epicsString.c*/ /*Authors: Jun-ichi Odagiri and Marty Kraimer*/ #include #include #include #include #include #include #define epicsExportSharedSymbols #include "epicsStdio.h" #include "cantProceed.h" #include "epicsString.h" epicsShareFunc int epicsShareAPI dbTranslateEscape(char *to, const char *from) { const char *pfrom = from; char *pto = to; char c; int nto=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}; 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); } break; case 'x' : { int i; char strval[3] = {0,0,0}; 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 = '\0'; /*NOTE that nto does not have to be incremented*/ return(nto); } epicsShareFunc int epicsShareAPI epicsStrCaseCmp( const char *s1, const char *s2) { int nexts1,nexts2; while(1) { /* vxWorks implementation expands argument more than once!!! */ nexts1 = toupper(*s1); nexts2 = toupper(*s2); if(nexts1==0) return( (nexts2==0) ? 0 : 1 ); if(nexts2==0) return(-1); if(nexts1nexts2) return(1); s1++; s2++; } } epicsShareFunc int epicsShareAPI epicsStrnCaseCmp( const char *s1, const char *s2, int n) { size_t ind = 0; int nexts1,nexts2; while(1) { if(ind++ >= n) break; /* vxWorks implementation expands argument more than once!!! */ nexts1 = toupper(*s1); nexts2 = toupper(*s2); if(nexts1==0) return( (nexts2==0) ? 0 : 1 ); if(nexts2==0) return(-1); if(nexts1nexts2) return(1); s1++; s2++; } return(0); } epicsShareFunc char * epicsShareAPI epicsStrDup(const char *s) { return strcpy(mallocMustSucceed(strlen(s)+1,"epicsStrDup"),s); } epicsShareFunc int epicsShareAPI epicsStrPrintEscaped( FILE *fp, const char *s, int n) { int nout=0; while (n--) { char c = *s++; switch (c) { case '\a': nout += fprintf(fp, "\\a"); break; case '\b': nout += fprintf(fp, "\\b"); break; case '\f': nout += fprintf(fp, "\\f"); break; case '\n': nout += fprintf(fp, "\\n"); break; case '\r': nout += fprintf(fp, "\\r"); break; case '\t': nout += fprintf(fp, "\\t"); break; case '\v': nout += fprintf(fp, "\\v"); break; case '\\': nout += fprintf(fp, "\\\\"); break; /*? does not follow C convention because trigraphs no longer important*/ case '\?': nout += fprintf(fp, "?"); break; case '\'': nout += fprintf(fp, "\\'"); break; case '\"': nout += fprintf(fp, "\\\""); break; default: if (isprint(c)) nout += fprintf(fp, "%c", c);/* putchar(c) doesn't work on vxWorks */ else nout += fprintf(fp, "\\%03o", (unsigned char)c); break; } } return nout; } epicsShareFunc int epicsShareAPI epicsStrSnPrintEscaped( char *outbuf, int outsize, const char *inbuf, int inlen) { int outCapacity = outsize; int len; while (inlen-- && (outsize > 0)) { char c = *inbuf++; switch (c) { case '\a': len = epicsSnprintf(outbuf, outsize, "\\a"); break; case '\b': len = epicsSnprintf(outbuf, outsize, "\\b"); break; case '\f': len = epicsSnprintf(outbuf, outsize, "\\f"); break; case '\n': len = epicsSnprintf(outbuf, outsize, "\\n"); break; case '\r': len = epicsSnprintf(outbuf, outsize, "\\r"); break; case '\t': len = epicsSnprintf(outbuf, outsize, "\\t"); break; case '\v': len = epicsSnprintf(outbuf, outsize, "\\v"); break; case '\\': len = epicsSnprintf(outbuf, outsize, "\\\\"); ; break; /*? does not follow C convention because trigraphs no longer important*/ case '\?': len = epicsSnprintf(outbuf, outsize, "?"); break; case '\'': len = epicsSnprintf(outbuf, outsize, "\\'"); break; case '\"': len = epicsSnprintf(outbuf, outsize, "\\\""); break; default: if (isprint(c)) len = epicsSnprintf(outbuf, outsize, "%c", c); else len = epicsSnprintf(outbuf, outsize, "\\%03o", (unsigned char)c); break; } outsize -= len; outbuf += len; } return(outCapacity - outsize); }