⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 swiprintf.cpp

📁 OSB-PIK-OpenVXI-3.0.0源代码 “中国XML论坛 - 专业的XML技术讨论区--XML在语音技术中的应用”
💻 CPP
字号:
 /****************License************************************************  *  * Copyright 2000-2003.  ScanSoft, Inc.      *  * Use of this software is subject to notices and obligations set forth   * in the SpeechWorks Public License - Software Version 1.2 which is   * included with this software.   *  * ScanSoft is a registered trademark of ScanSoft, Inc., and OpenSpeech,   * SpeechWorks and the SpeechWorks logo are registered trademarks or   * trademarks of SpeechWorks International, Inc. in the United States   * and other countries.  *  ***********************************************************************/  // -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8  #include <stdio.h> #include <stdlib.h> #include <stddef.h> #include <string.h> #include <stdarg.h> #include <ctype.h> #include <malloc.h>  #include "SWIprintf.h" #include "misc_string.h"  static const char BAD_FORMAT_TEXT[] = " [bad format!]"; static const wchar_t BAD_FORMAT_TEXT_W[] = L" [bad format!]"; static const size_t BAD_FORMAT_TEXT_LEN = 14;  // Convert wide to narrow characters #define w2c(w) (((w) & 0xff00)?'\277':((unsigned char) ((w) & 0x00ff)))  #if !defined(_win32_) static wchar_t* ConvertFormatForWidePrintf(const wchar_t* format) {   int formatLen = wcslen(format);    // The maximum length of the new format string is 1 and 2/3 that   //    of the original.   wchar_t* newFormat = new wchar_t [2 * formatLen];   int nfIndex = 0;    for (int fIndex = 0; fIndex < formatLen; ++fIndex)   {     // We found %s in format.     if ((format[fIndex] == L'%') && (fIndex != (formatLen - 1)))     {       newFormat[nfIndex++] = L'%';       fIndex++;       while((SWIchar_iswdigit(format[fIndex]) || (format[fIndex] == L'+') ||             (format[fIndex] == L'-') || (format[fIndex] == L'.') ||             (format[fIndex] == L'*') || (format[fIndex] == L'#')) &&             (fIndex < formatLen - 1)) {         newFormat[nfIndex++] = format[fIndex++];       }        switch(format[fIndex]) {         case L's': {           newFormat[nfIndex++] = L'l';           newFormat[nfIndex++] = L's';           break;         }         case L'S': {           newFormat[nfIndex++] = L's';           break;         }         case L'c': {           newFormat[nfIndex++] = L'l';           newFormat[nfIndex++] = L'c';           break;         }         case L'C': {           newFormat[nfIndex++] = L'c';           break;         }         default: {           newFormat[nfIndex++] = format[fIndex];           break;         }       }     }     else     {       newFormat[nfIndex++] = format[fIndex];     }   }    newFormat[nfIndex] = 0;    return newFormat; }  static char* ConvertFormatForNarrowPrintf(const char* format) {   int formatLen = strlen(format);    // The maximum length of the new format string is 1 and 2/3 that   //    of the original.   char* newFormat = new char [2 * formatLen];   int nfIndex = 0;    for (int fIndex = 0; fIndex < formatLen; ++fIndex)   {     // We found %s in format.     if ((format[fIndex] == '%') && (fIndex != (formatLen - 1)))     {       newFormat[nfIndex++] = '%';       fIndex++;       while((SWIchar_isdigit(format[fIndex]) || (format[fIndex] == L'+') ||             (format[fIndex] == L'-') || (format[fIndex] == L'.') ||             (format[fIndex] == L'*') || (format[fIndex] == L'#')) &&             (fIndex < formatLen - 1)) {         newFormat[nfIndex++] = format[fIndex++];       }        if (format[fIndex] == 'S')       {         newFormat[nfIndex++] = 'l';         newFormat[nfIndex++] = 's';       }       else if (format[fIndex] == 'C')       {         newFormat[nfIndex++] = 'l';         newFormat[nfIndex++] = 'c';       }       else       {         newFormat[nfIndex++] = format[fIndex];       }     }     else     {       newFormat[nfIndex++] = format[fIndex];     }   }    newFormat[nfIndex] = 0;    return newFormat; }  static char* ConvertWideFormatForNarrowPrintf(const wchar_t* format) {   int formatLen = wcslen(format);    // The maximum length of the new format string is 1 and 2/3 that   //    of the original.   char* newFormat = new char [2 * formatLen];   int nfIndex = 0;    for (int fIndex = 0; fIndex < formatLen; ++fIndex)   {     // We found %s in format.     if ((format[fIndex] == L'%') && (fIndex != (formatLen - 1)))     {       newFormat[nfIndex++] = '%';       fIndex++;       while((SWIchar_iswdigit(format[fIndex]) || (format[fIndex] == L'+') ||             (format[fIndex] == L'-') || (format[fIndex] == L'.') ||             (format[fIndex] == L'*') || (format[fIndex] == L'#')) &&             (fIndex < formatLen - 1)) {         newFormat[nfIndex++] = w2c(format[fIndex++]);       }        switch(format[fIndex]) {         case L's': {           newFormat[nfIndex++] = 'l';           newFormat[nfIndex++] = 's';           break;         }         case L'S': {           newFormat[nfIndex++] = 's';           break;         }         case L'c': {           newFormat[nfIndex++] = 'l';           newFormat[nfIndex++] = 'c';           break;         }         case L'C': {           newFormat[nfIndex++] = 'c';           break;         }         default: {           newFormat[nfIndex++] = w2c(format[fIndex]);           break;         }       }     }     else     {       newFormat[nfIndex++] = w2c(format[fIndex]);     }   }    newFormat[nfIndex] = 0;    return newFormat; } #endif  /*  *  Common functions for all OSes  */  SWIPRINTF_API int SWIfprintf(FILE* file, const char* format, ...) {   va_list ap;   int rc;    va_start(ap, format);  #if 0   try { #endif #if !defined(_win32_)     char* newFormat = ConvertFormatForNarrowPrintf(format);     rc = vfprintf(file, newFormat, ap);     delete []newFormat; #else     rc = vfprintf(file, format, ap); #endif #if 0   } catch(...) {     rc = fputs(format, file);   } #endif   va_end(ap);    return rc; }   SWIPRINTF_API int SWIfwprintf(FILE* file, const wchar_t* format, ...) {   va_list ap;   int rc;    va_start(ap, format);  #if !defined(_win32_)   char* newFormat = ConvertWideFormatForNarrowPrintf(format);   rc = vfprintf(file, newFormat, ap);   delete [] newFormat; #else   rc = vfwprintf(file, format, ap); #endif    va_end(ap);    return rc; }   SWIPRINTF_API int SWIsprintf(char* str, size_t maxlen, const char* format, ...) {   va_list ap;   int rc;    va_start(ap, format);   rc = SWIvsprintf(str, maxlen, format, ap);   va_end(ap);    return rc; }     // if maxlen == 0, wcs is untouched, returns -1   // if there is overflow, returns -1 and maxlen-1 # of chars are written SWIPRINTF_API int SWIswprintf (wchar_t* wcs, size_t maxlen, 			       const wchar_t* format, ...) {   va_list ap;   int rc;   wchar_t strbuf[200]; // try to avoid malloc   wchar_t *tstr;    if (maxlen < 1)     return -1;    if ( maxlen >= 200 ) {     tstr = (wchar_t *)malloc( (maxlen+1)*sizeof(wchar_t) );     if (tstr == NULL) {       //FIXME-- can't log, how can we notify user?       return -1;     }   } else {     tstr = strbuf;   }    va_start(ap, format);   rc = SWIvswprintf(tstr, maxlen, format, ap);   va_end(ap);    wcscpy( wcs,tstr );    if ( tstr != strbuf ) free(tstr);    return rc; }   /*  *  OS specific functions below, UNIX variants start first  */  #ifndef _win32_ static int wcs2str(const wchar_t *wcs, char *str) {   int len, i;    len = wcslen(wcs);   for (i = 0; i < len; i++)     str[i] = w2c(wcs[i]);   str[i] = '\0';    return len; }  static int str2wcs(const char *str, wchar_t *wcs) {   int len, i;    len = strlen(str);   for (i = 0; i < len; i++)     wcs[i] = (wchar_t)str[i];   wcs[i] = L'\0';    return len; }  /* convert str to wcs */ static int buf_str2wcs(const char *str, wchar_t *wcs, int len) {   int i;    for (i = 0; i < len; i++)     wcs[i] = (wchar_t)str[i];    return len; }  static int buf_wcs2str(const wchar_t *wcs, char *str, int len) {   int i;    for (i = 0; i < len; i++)     str[i] = w2c(wcs[i]);    return len; }   static int format_wcs2str(const wchar_t *wformat, char *nformat) {   size_t len, i;   bool replacement = false;    len = wcslen(wformat);   for (i = 0; i <= len; i++) {     nformat[i] = w2c(wformat[i]);     if (nformat[i] == '%') {       if (replacement) 	replacement = false; // double %%       else 	replacement = true;     }     else if ((replacement == true) && (SWIchar_isalpha(nformat[i]))) {       switch (nformat[i]) {       case 'c': 	// wide insert for wide format -> wide insert for narrow format 	nformat[i] = 'C'; 	break;       case 's': 	// wide insert for wide format -> wide insert for narrow format 	nformat[i] = 'S'; 	break;       case 'C': 	// narrow insert for wide format -> narrow insert for narrow format 	nformat[i] = 'c'; 	break;       case 'S': 	// narrow insert for wide format -> narrow insert for narrow format 	nformat[i] = 's'; 	break;       default: 	break;       }       replacement = false;     }   }   nformat[i] = '\0';    return len; }   SWIPRINTF_API int SWIvsprintf(char* str, size_t maxlen, 			      const char* format, va_list args) {   char tmpbuf[BUFSIZE];   char *buf;   int rc;    if (maxlen < 1)     return -1;   str[0] = '\0';    /* allocate buffer, allow for overrun */   buf = BUFMALLOC(tmpbuf, maxlen + 1024);   if (!buf)     return -1;  #if 0   try { #endif     char* newFormat = ConvertFormatForNarrowPrintf(format);     rc = vsnprintf(buf, maxlen, newFormat, args);     delete []newFormat; #if 0   } catch(...) {     if (strlen(format) < maxlen) {       strcpy(buf, format);       rc = strlen(buf);       if (rc + BAD_FORMAT_TEXT_LEN < maxlen) { 	strcat(buf, BAD_FORMAT_TEXT); 	rc += BAD_FORMAT_TEXT_LEN;       }     }   } #endif    /* copy buffer back */   if (rc >= 0) {     size_t len = strlen(buf);     if (len < maxlen) {       strcpy(str, buf);     } else {       strncpy(str, buf, maxlen - 1);       str[maxlen - 1] = '\0';     }   }    BUFFREE(tmpbuf, buf);    return rc; }   SWIPRINTF_API int SWIvswprintf(wchar_t* wcs, size_t maxlen, 			       const wchar_t* format, va_list args) {   int rc;    if (maxlen < 1)     return -1;   wcs[0] = '\0';  #if defined(__GNUC__) && (__GNUC__ <= 2)    /* Some versions of the GNU C library do not provide the required      vswprintf( ) function, so we emulate it by converting the format      string to narrow characters, do a narrow sprintf( ), then convert      back */    /* Use a temporary buffer for output to protect against relatively      small overruns */   char *buf, tmpbuf[BUFSIZE];   if (BUFSIZE < maxlen + 1024)     buf = new char[maxlen + 1024];   else     buf = tmpbuf;   if (!buf)     return -1;    /* convert format to narrow, a bit generous compared to the ANSI/ISO      C specifications for the printf( ) family format strings but we're      not trying to do full validation here anyway */   char *fmt, tmpfmt[BUFSIZE];   size_t fmtlen = wcslen(format);   if (BUFSIZE < fmtlen + 1)     fmt = new char[fmtlen + 1];   else     fmt = tmpfmt;   if (!fmt)     return -1;    format_wcs2str(format, fmt);    /* generate the final string based on the narrow format and arguments */   rc = vsnprintf(buf, maxlen, fmt, args);    /* copy back to wide characters */   size_t finallen = strlen(buf);   if (finallen >= maxlen)     finallen = maxlen - 1;   for (size_t i = 0; i < finallen; i++)     wcs[i] = buf[i];   wcs[finallen] = L'\0';    /* clean up */   if (buf != tmpbuf)     delete [] buf;   if (fmt != tmpfmt)     delete [] fmt;  #else /* ! defined(__GNUC__) || (__GNUC__ > 2) */    wchar_t* newFormat = ConvertFormatForWidePrintf(format);   rc = vswprintf(wcs, maxlen, newFormat, args);   delete [] newFormat;    if ((size_t) rc >= maxlen - 1) /* overflow */     wcs[maxlen - 1] = L'\0';  #endif /* defined(__GNUC__) && (__GNUC__ <= 2) */    return rc; }   SWIPRINTF_API wchar_t *SWIfgetws(wchar_t *ws, int n, FILE *stream) {   char tmpbuf[BUFSIZE];   char *buf;   char *rs;    /* allocate local buffer */   buf = BUFMALLOC(tmpbuf, n);   if (!buf) {     return NULL;   }    rs = fgets(buf, n, stream);   if (rs == NULL) {     BUFFREE(tmpbuf, buf);     return NULL;   }    str2wcs(buf, ws);   BUFFREE(tmpbuf, buf);    return ws; }  /* Only for linux: Solaris has a swscanf but doesn't have vsscanf!! */ #if defined(_linux_) SWIPRINTF_API int SWIswscanf(const wchar_t *s, const wchar_t *format, ... ) {   char tmpbuf[BUFSIZE];   char *buf;   char tmpfmt[BUFSIZE];   char *fmt;   va_list ap;   int rc;    buf = BUFMALLOC(tmpbuf, wcslen(s) + 1);   if (!buf) {     return 0;   }    fmt = BUFMALLOC(tmpfmt, wcslen(format) + 1);   if (!fmt) {     BUFFREE(tmpbuf, buf);     return 0;   }    /* convert buffers */   wcs2str(s, buf);   format_wcs2str(format, fmt);    va_start(ap, format);   rc = vsscanf(buf, fmt, ap);   va_end(ap);    /* we do not need to convert anything back */   BUFFREE(tmpbuf, buf);   BUFFREE(tmpfmt, fmt);    return rc; } #endif  #elif defined(_win32_)  SWIPRINTF_API int SWIvsprintf(char* str, size_t maxlen, 			      const char* format, va_list args) {   int rc;    if (maxlen < 1)     return -1;   str[0] = '\0';  #if 0   try { #endif     rc = _vsnprintf(str, maxlen, format, args);     if ((size_t) rc >= maxlen - 1) /* overflow */       str[maxlen - 1] = '\0'; #if 0   } catch(...) {     if (strlen(format) < maxlen) {       strcpy(str, format);       rc = strlen(str);       if (rc + BAD_FORMAT_TEXT_LEN < maxlen) { 	strcat(str, BAD_FORMAT_TEXT); 	rc += BAD_FORMAT_TEXT_LEN;       }     }   } #endif    return rc; }   SWIPRINTF_API int SWIvswprintf(wchar_t* wcs, size_t maxlen, 			       const wchar_t* format, va_list args) {   int rc;    if (maxlen < 1)     return -1;   wcs[0] = '\0';  #if 0   try { #endif     rc = _vsnwprintf(wcs, maxlen, format, args);     if ((size_t) rc >= maxlen - 1) /* overflow */       wcs[maxlen - 1] = L'\0'; #if 0   } catch(...) {     if (wcslen(format) < maxlen) {       wcscpy(wcs, format);       rc = wcslen(wcs);       if (rc + BAD_FORMAT_TEXT_LEN < maxlen) { 	wcscat(wcs, BAD_FORMAT_TEXT_W); 	rc += BAD_FORMAT_TEXT_LEN;       }     }   } #endif    return rc; }    SWIPRINTF_API wchar_t *SWIfgetws(wchar_t *ws, int n, FILE *stream) {   return fgetws(ws, n, stream); }   /* SWSCANF on Win32 is just a #define to the real version */    #elif #error #endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -