Ejemplo n.º 1
0
int _RTLENTRY _EXPFUNC _mbsnicmp(const unsigned char *s1, const unsigned char *s2, size_t n)
{
    unsigned int c1, c2;

    for ( ; n > 0; n--)
    {
        c1 = *s1++;
        if (_ismbblead(c1))
        {
            if (*s1 == '\0')
                c1 = 0;
            else
                c1 = (c1 << 8) | *s1++;
        }
        else
            c1 = _ltoupper(c1);
        c2 = *s2++;
        if (_ismbblead(c2))
        {
            if (*s2 == '\0')
                c2 = 0;
            else
                c2 = (c2 << 8) | *s2++;
        }
        else
            c2 = _ltoupper(c2);
        if (c1 != c2)
            return (c1 < c2) ? -1 : 1;
        if (c1 == 0)
            break;
    }
    return 0;
}
Ejemplo n.º 2
0
LPSTR GetFnameTop(LPCTSTR pszPath, LPCTSTR lpDelim)
{
	LPSTR pTop = (LPSTR)pszPath;
	if (lpDelim) {
		int nLen = strlen(lpDelim);
		if (lpDelim[0] != '\0') {
			char c;
			while((c = *pszPath++) != '\0') {
				if (_ismbblead(c)) {
					pszPath++;
				} else if (c == lpDelim[0]) {
					if (strncmp(pszPath-1, lpDelim, nLen) == 0) {
						if (pszPath[nLen-1] == '\0') return pTop;
						pTop = (LPSTR)(pszPath -1 + nLen);
					}
				}
			}
		}
	} else {
		char c;
		while((c = *pszPath++) != '\0') {
			if (_ismbblead(c)) {
				pszPath++;
			} else if (c == '\\') {
				if (*pszPath == '\0') {
					return pTop;
				}
				pTop = (LPSTR)pszPath;
			}
		}
	}
	return pTop;
}
Ejemplo n.º 3
0
int _RTLENTRY _EXPFUNC _mbsicmp(const unsigned char *s1, const unsigned char *s2)
{
    unsigned int c1, c2;

    do {
        c1 = *s1++;
        if (_ismbblead(c1))
        {
            if (*s1 == '\0')
                c1 = 0;
            else
                c1 = (c1 << 8) | *s1++;
        }
        else
            c1 = _ltoupper(c1);
        c2 = *s2++;
        if (_ismbblead(c2))
        {
            if (*s2 == '\0')
                c2 = 0;
            else
                c2 = (c2 << 8) | *s2++;
        }
        else
            c2 = _ltoupper(c2);
        if (c1 != c2)
            return (c1 < c2) ? -1 : 1;
    } while (c1 != 0) ;
    return 0;
}
Ejemplo n.º 4
0
/*
 * @implemented
 */
int _mbsbtype( const unsigned char *str, size_t n )
{
  int lead = 0;
  const unsigned char *end = str + n;

  /* Lead bytes can also be trail bytes so we need to analyse the string.
   * Also we must return _MBC_ILLEGAL for chars past the end of the string
   */
  while (str < end) /* Note: we skip the last byte - will check after the loop */
  {
    if (!*str)
      return _MBC_ILLEGAL;
    lead = !lead && _ismbblead(*str);
    str++;
  }

  if (lead)
    if (_ismbbtrail(*str))
      return _MBC_TRAIL;
    else
      return _MBC_ILLEGAL;
  else
    if (_ismbblead(*str))
      return _MBC_LEAD;
    else
      return _MBC_SINGLE;
}
Ejemplo n.º 5
0
/*
 * @implemented
 */
int _mbsicmp(const unsigned char *str1, const unsigned char *str2)
{
	unsigned char *s1 = (unsigned char *)str1;
	unsigned char *s2 = (unsigned char *)str2;

	unsigned short *short_s1, *short_s2;

	int l1, l2;

	do {

		if (*s1 == 0)
			break;

		l1 = _ismbblead(*s1);
		l2 = _ismbblead(*s2);
		if ( !l1 &&  !l2  ) {

			if (toupper(*s1) != toupper(*s2))
				return toupper(*s1) - toupper(*s2);
			else {
				s1 += 1;
				s2 += 1;
			}
		}
		else if ( l1 && l2 ){
			short_s1 = (unsigned short *)s1;
			short_s2 = (unsigned short *)s2;
			if ( _mbctoupper(*short_s1) != _mbctoupper(*short_s2 ))
				return _mbctoupper(*short_s1) - _mbctoupper(*short_s2);
			else {
				s1 += 2;
				s2 += 2;
			}
		}
		else
			return *s1 - *s2;
	} while (*s1 != 0);
	return 0;

  while (toupper(*s1) == toupper(*s2))
  {
    if (*s1 == 0)
      return 0;
    s1++;
    s2++;
  }
  return toupper(*(unsigned const char *)s1) - toupper(*(unsigned const char *)(s2));
}
Ejemplo n.º 6
0
static int __read_wide_char( FILE *fp, wchar_t *wc )
/**************************************************/
{
    if( fp->_flag & _BINARY ) {
        /*** Read a wide character ***/
        return( fread( wc, sizeof( wchar_t ), 1, fp ) );
    } else {
        char            mbc[MB_CUR_MAX];
        wchar_t         wcTemp;
        int             rc;

        /*** Read the multibyte character ***/
        if( !fread( &mbc[0], 1, 1, fp ) )
            return( 0 );

        if( _ismbblead( (unsigned char)mbc[0] ) ) {
            if( !fread( &mbc[1], 1, 1, fp ) )
                return( 0 );
        }

        /*** Convert it to wide form ***/
        rc = mbtowc( &wcTemp, mbc, MB_CUR_MAX );
        if( rc >= 0 ) {
            *wc = wcTemp;
            return( 1 );
        } else {
            _RWD_errno = EILSEQ;
            return( 0 );
        }
    }
}
Ejemplo n.º 7
0
/*
 * @implemented
 */
void _mbccpy(unsigned char *dst, const unsigned char *src)
{
  if (!_ismbblead(*src) )
    return;

  memcpy(dst,src,_mbclen2(*src));
}
Ejemplo n.º 8
0
unsigned int _mbbtoupper(unsigned int c)
{
	if (!_ismbblead(c) )
		return toupper(c);

	return c;
}
Ejemplo n.º 9
0
void wc(wc_info& wci) {

	char mbc[2];
	bool lead_byte = false;

	char* p = (char*)wci.m_p;

	for (size_t i = 0; i < wci.m_size; i++) {

		if (!lead_byte) {
			if (_ismbblead(p[i])) {
				// 2バイトコードの可能性があるので、フラグを立てて保留
				mbc[0] = p[i];
				lead_byte = true;
			} else {
				// 1バイトコードなので、カウント+1
				++wci.m_count_byte;
				++wci.m_count_char;
			}
		} else {
			if (_ismbbtrail(p[i])) {
				// 2バイトコード確定。フラグを落としてカウントアップ
				mbc[1] = p[i];
				lead_byte = false;
				wci.m_count_byte += 2;
				++wci.m_count_char;
			} else {
				// 異常な文字。カウントせずにフラグだけ戻す
				lead_byte = false;
			}
		}
	}
}
Ejemplo n.º 10
0
Archivo: File.cpp Proyecto: yagi/satori
inline T*	FindFinalChar(T* start, T c) {
    T* last=NULL;
    for (T* p=start; *p ; p+=_ismbblead(*p)?2:1)
        if (*p==c)
            last=p;
    return	last;
}
Ejemplo n.º 11
0
/*********************************************************************
 *              _mbsnbcpy(MSVCRT.@)
 * REMARKS
 *  Like strncpy this function doesn't enforce the string to be
 *  NUL-terminated
 */
unsigned char* CDECL _mbsnbcpy(unsigned char* dst, const unsigned char* src, size_t n)
{
  unsigned char* ret = dst;
  if(!n)
    return dst;
  if(get_mbcinfo()->ismbcodepage)
  {
    int is_lead = 0;
    while (*src && n)
    {
      is_lead = (!is_lead && _ismbblead(*src));
      n--;
      *dst++ = *src++;
    }

    if (is_lead) /* if string ends with a lead, remove it */
	*(dst - 1) = 0;
  }
  else
  {
    while (n)
    {
        n--;
        if (!(*dst++ = *src++)) break;
    }
  }
  while (n--) *dst++ = 0;
  return ret;
}
Ejemplo n.º 12
0
/*
 * @implemented
 */
unsigned char * _mbsrev(unsigned char *s)
{
	unsigned char  *e;
	unsigned char  a;
	unsigned char  *e2;
	e=s;
	while (*e) {
		if ( _ismbblead(*e) ) {
			a = *e;
			e2 = e;
			*e2 = *++e;
			if ( *e == 0 )
				break;
			*e = a;
		}
		e++;
	}
	while (s<e) {
		a=*s;
		*s=*e;
		*e=a;
		s++;
		e--;
	}


	return s;
}
Ejemplo n.º 13
0
LPSTR TokenAddr(LPSTR lpAddr)
{
	static LPSTR lpOrg = NULL;
	if (lpAddr) lpOrg = lpAddr;
	LPSTR lpEnd, lpRet;
	BOOL bQ = FALSE;
	if (lpOrg) {
		while (*lpOrg &&
			(*(LPBYTE)lpOrg <= (BYTE)'\x20' || *lpOrg == ',' || *lpOrg == ';')) lpOrg++;
		if (*lpOrg == '(') {
			while (*lpOrg != ')') {
				if (*lpOrg == '\0') return NULL;
				lpOrg++;
			}
			lpOrg++;
			while (*lpOrg &&
				(*(LPBYTE)lpOrg <= (BYTE)'\x20' || *lpOrg == ',' || *lpOrg == ';')) lpOrg++;
		}
		lpEnd = lpOrg;
		while (*lpEnd) {
			char ch = *lpEnd;
			if (_ismbblead(ch)) {
				lpEnd += 2;
			} else {
				while (ch == '(') {
					while (*lpEnd != ')' && *lpEnd) {
						lpEnd++;
					}
					ch = *lpEnd;
				}
				if (ch == '\"') bQ ^= TRUE;
				else if ((ch == ',' || ch == ';') && !bQ) {
					*lpEnd = '\0';
					LPSTR lpBack = lpEnd;
					while (*(LPBYTE)(lpBack-1) <= (BYTE)'\x20' && lpBack > lpOrg) {
						lpBack--;
						*lpBack = '\0';
					}
					lpRet = lpOrg;
					lpOrg = lpEnd + 1;
					return lpRet;
				}
				lpEnd++;
			}
		}
		LPSTR lpRet = lpOrg;
		lpOrg = NULL;
		if (lpRet[0] == '\0') {
			return NULL;
		} else {
			LPSTR lpBack = lpEnd;
			while (*(LPBYTE)(lpBack-1) <= (BYTE)'\x20' && lpBack > lpRet) {
				lpBack--;
				*lpBack = '\0';
			}
			return lpRet;
		}
	} else return NULL;
}
Ejemplo n.º 14
0
unsigned char * _RTLENTRY _EXPFUNC _mbsdec(const unsigned char *s, const unsigned char *p)
{
    unsigned char *q;

    if (!s || !p || p <= s)
        return NULL;
    q = (unsigned char *)(p - 1);
    if (_ismbblead(*q))
        return (q - 1);
    q--;
    while ((const unsigned char *)q >= s)
    {
        if (!(_ismbblead(*q))) break;
        q--;
    }
    return (unsigned char *)(p - ((int)((unsigned char *)p - q) & 1) - 1);
}
Ejemplo n.º 15
0
/*********************************************************************
 *              _mbsnbcpy_s(MSVCRT.@)
 * REMARKS
 * Unlike _mbsnbcpy this function does not pad the rest of the dest
 * string with 0
 */
int CDECL _mbsnbcpy_s(unsigned char* dst, size_t size, const unsigned char* src, size_t n)
{
    size_t pos = 0;

    if(!dst || size == 0)
        return EINVAL;
    if(!src)
    {
        dst[0] = '\0';
        return EINVAL;
    }
    if(!n)
        return 0;

    if(get_mbcinfo()->ismbcodepage)
    {
        int is_lead = 0;
        while (*src && n)
        {
            if(pos == size)
            {
                dst[0] = '\0';
                return ERANGE;
            }
            is_lead = (!is_lead && _ismbblead(*src));
            n--;
            dst[pos++] = *src++;
        }

        if (is_lead) /* if string ends with a lead, remove it */
            dst[pos - 1] = 0;
    }
    else
    {
        while (n)
        {
            n--;
            if(pos == size)
            {
                dst[0] = '\0';
                return ERANGE;
            }

            if(!(*src)) break;
            dst[pos++] = *src++;
        }
    }

    if(pos < size)
        dst[pos] = '\0';
    else
    {
        dst[0] = '\0';
        return ERANGE;
    }

    return 0;
}
Ejemplo n.º 16
0
_WCRTLINK int _NEARFAR(mbtowc,_fmbtowc)( wchar_t _FFAR *pwc, const char _FFAR *ch, size_t n )
{
#ifdef __NT__
    int                 rc;
    int                 len;
    wchar_t             wch;
#endif

    /*** Catch special cases ***/
    if( ch == NULL )  return( 0 );
    if( n == 0 )  return( -1 );
    if( *ch == '\0' ) {
        if( pwc != NULL )  *pwc = L'\0';
        return( 0 );
    }
    if( _ismbblead( ch[0] )  &&  ch[1] == '\0' )  return( -1 ); /* invalid */

    /*** Convert the character ***/
    #ifdef __NT__
        len = _NEARFAR(_mbclen,_fmbclen)( (unsigned char _FFAR *)ch );
        rc = MultiByteToWideChar( __MBCodePage, MB_ERR_INVALID_CHARS,
                                  (LPCSTR)ch, min(n,len), (LPWSTR)&wch, 1 );
        if( rc != 0 ) {
            if( pwc != NULL )  *pwc = wch;
            return( len );                      /* return mbchar size */
        } else {
            return( -1 );                       /* cannot convert */
        }
    #else
        if( _ismbblead(*ch) && n>=2 ) {         /* lead byte present? */
            if( pwc != NULL ) {
                *pwc = (((wchar_t)ch[0])<<8) |  /* convert to lead:trail */
                        (wchar_t)ch[1];
            }
            return( 2 );                        /* return char size */
        } else if( !_ismbblead(*ch) ) {
            if( pwc != NULL ) {
                *pwc = (wchar_t)ch[0];          /* convert to 00:byte */
            }
            return( 1 );                        /* return char size */
        } else {
            return( -1 );                       /* n==1, but char 2 bytes */
        }
    #endif
}
Ejemplo n.º 17
0
/*
 * @implemented
 */
int _mbsnbcoll(const unsigned char *str1, const unsigned char *str2, size_t n)
{
	unsigned char *s1 = (unsigned char *)str1;
	unsigned char *s2 = (unsigned char *)str2;

	unsigned short *short_s1, *short_s2;

	int l1, l2;

	if (n == 0)
		return 0;
	do {

		if (*s1 == 0)
			break;

		l1 = _ismbblead(*s1);
		l2 = _ismbblead(*s2);
		if ( !l1 &&  !l2  ) {

			if (*s1 != *s2)
				return colldif(*s1, *s2);
			else {
				s1 += 1;
				s2 += 1;
				n--;
			}
		}
		else if ( l1 && l2 ){
			short_s1 = (unsigned short *)s1;
			short_s2 = (unsigned short *)s2;
			if ( *short_s1 != *short_s2 )
				return colldif(*short_s1, *short_s2);
			else {
				s1 += 2;
				s2 += 2;
				n-=2;

			}
		}
		else
			return colldif(*s1, *s2);
	} while (n > 0);
	return 0;
}
Ejemplo n.º 18
0
/*
 * @implemented
 */
int _mbsicoll(const unsigned char *str1, const unsigned char *str2)
{
	unsigned char *s1 = (unsigned char *)str1;
	unsigned char *s2 = (unsigned char *)str2;

	unsigned short *short_s1, *short_s2;

	int l1, l2;

	while ( *s1 != 0 ) {

		if (*s1 == 0)
			break;

		l1 = _ismbblead(*s1);
		l2 = _ismbblead(*s2);
		if ( !l1 &&  !l2  ) {

			if (toupper(*s1) != toupper(*s2))
				return colldif(*s1, *s2);
			else {
				s1 += 1;
				s2 += 1;
			}
		}
		else if ( l1 && l2 ){
			short_s1 = (unsigned short *)s1;
			short_s2 = (unsigned short *)s2;
			if ( _mbctoupper(*short_s1) != _mbctoupper(*short_s2 ))
				return colldif(*short_s1, *short_s2);
			else {
				s1 += 2;
				s2 += 2;

			}
		}
		else
			return colldif(*s1, *s2);
	} ;
	return 0;
}
Ejemplo n.º 19
0
void GetLegalFileName(LPCTSTR lpName, LPSTR lpBuf, int nBuf)
{
	LPSTR lpPtr = lpBuf;
	LPCTSTR lpSub = lpName;
	int nLen = 0;
	while (*(LPBYTE)lpSub <= (BYTE)'\x20') lpSub++;
	while (*lpSub) {
		char c = *lpSub++;
		nLen++;
		if ((lpPtr - lpBuf) >= nBuf-3) {
			break;
		}
		if (_ismbblead(c)) {
			*lpPtr++ = c;
			*lpPtr++ = *lpSub;
			nLen++;
			if (*lpSub == '\0') break;
			else lpSub++;
		} else if ((BYTE)c < (BYTE)'\x20') {
			c = ' ';
			*lpPtr++ = c;
		} else {
			switch (c) {
			case '*':
			case '<':
			case '>':
			case '?':
			case '\\':
			case '|':
			case '/':
				c = '=';
				break;
			case ':':
				c = ';';
				break;
			case '\"':
				c = '\'';
				break;
			default:
				break;
			}
			*lpPtr++ = c;
		}
	}
	while (nLen && (*(lpPtr-1) == '.' || *(lpPtr-1) == ' ')) {
		lpPtr--;
		nLen--;
	}
	*lpPtr++ = '\0';
	if (*lpBuf == '\0') {
		strcpy(lpBuf, "(noname)");
	}
}
Ejemplo n.º 20
0
/*
 * @implemented
 */
unsigned char * _mbsdec(const unsigned char *str, const unsigned char *cur)
{
	unsigned char *s = (unsigned char *)cur;
	if ( str >= cur )
		return NULL;

	s--;
	if (_ismbblead(*(s-1)) )
		s--;

	return s; 
}
Ejemplo n.º 21
0
/* added by H.Banno for Windows & Mac */
static char *
fgets_jconf(char *buf, int size, FILE *fp)
{
  int c, prev_c;
  int pos;

  if (fp == NULL) return NULL;
    
  pos = 0;
  c = '\0';
  prev_c = '\0';
  while (1) {
    if (pos >= size) {
      pos--;
      break;
    }

    c = fgetc(fp);
    if (c == EOF) {
      buf[pos] = '\0';
      if (pos <= 0) {
	return NULL;
      } else {
	return buf;
      }
    } else if (c == '\n' || c == '\r') {
      if (c == '\r' && (c = fgetc(fp)) != '\n') { /* for Mac */
	ungetc(c, fp);
      }
      if (prev_c == '\\') {
	pos--;
      } else {
	break;
      }
    } else {
      buf[pos] = c;
      pos++;

#if defined(_WIN32) && !defined(__CYGWIN32__)
      if (c == '\\' && (_ismbblead(prev_c) && _ismbbtrail(c))) {
      c = '\0';
      }
#endif
    }
    prev_c = c;
  }
  buf[pos] = '\0';

  return buf;
}
Ejemplo n.º 22
0
_WCRTLINK size_t _NEARFAR(__mbslen,__fmbslen)( unsigned char const _FFAR *s )
{
    size_t              count = 0;

    if( __IsDBCS ) {
        while( *s != '\0' ) {
            s += _ismbblead(*s) ? 2 : 1;/* point to next char */
            count++;                    /* update count */
        }
        return( count );
    } else {
        return( _NEARFAR(strlen,_fstrlen)( s ) );
    }
}
Ejemplo n.º 23
0
size_t _RTLENTRY _EXPFUNC _mbsnbcnt(const unsigned char *s, size_t n)
{
    const unsigned char *p;

    for (p = s; n > 0 && *p; n--, p++)
    {
        if (_ismbblead(*p))
        {
            if (p[1] == '\0')
                break;
            p++;
        }
    }
    return (size_t)(p - s);
}
Ejemplo n.º 24
0
/*
 * @implemented
 */
size_t _mbslen(const unsigned char *str)
{
  size_t len = 0;
  while(*str)
  {
    if (_ismbblead(*str))
    {
      str++;
      if (!*str)  /* count only full chars */
        break;
    }
    str++;
    len++;
  }
  return len;
}
Ejemplo n.º 25
0
/*
 * @implemented
 */
int _ismbslead( const unsigned char *start, const unsigned char *str)
{
  int lead = 0;

  /* Lead bytes can also be trail bytes so we need to analyse the string
   */
  while (start <= str)
  {
    if (!*start)
      return 0;
    lead = !lead && _ismbblead(*start);
    start++;
  }

  return lead ? -1 : 0;
}
Ejemplo n.º 26
0
unsigned int __cdecl _mbctoupper(
    unsigned int c
    )
{
	unsigned char val[2];
#if defined(_WIN32) && !defined(_POSIX_)
        unsigned char ret[4];
#endif /* _WIN32 */

	if (c > 0x00FF)
        {
            val[0] = (c >> 8) & 0xFF;
            val[1] = c & 0xFF;

            if (!_ismbblead(val[0]))
                return c;

#if defined( _WIN32 ) && !defined(_POSIX_)

            if (__crtLCMapStringA(  __mblcid,
                                    LCMAP_UPPERCASE,
                                    val,
                                    2,
                                    ret,
                                    2,
                                    __mbcodepage) == 0)
                return c;

            c = ret[1];
            c += ret[0] << 8;

            return c;

#else /* _WIN32 */

            if      (c >= _MBLOWERLOW1 && c <= _MBLOWERHIGH1)
                c -= _MBCASEDIFF1;

            else if (c >= _MBLOWERLOW2 && c <= _MBLOWERHIGH2)
                c -= _MBCASEDIFF2;

            return c;

#endif /* _WIN32 */

	} else
Ejemplo n.º 27
0
/*
 * @implemented
 */
int _mbsnicmp(const unsigned char *s1, const unsigned char *s2, size_t n)
{
  if (n == 0)
    return 0;
  do {
    if (_mbbtoupper(*s1) != _mbbtoupper(*s2))
      return _mbbtoupper(*(unsigned const char *)s1) - _mbbtoupper(*(unsigned const char *)s2);
    s1 += _mbclen2(*s1);
    s2 += _mbclen2(*s2);

    if (*s1 == 0)
      break;
    if (!_ismbblead(*s1))
      n--;
  } while (n > 0);
  return 0;
}
Ejemplo n.º 28
0
/*
 * @implemented
 */
unsigned char * _mbsninc(const unsigned char *str, size_t n)
{
  if(!str)
    return NULL;

  while (n > 0 && *str)
  {
    if (_ismbblead(*str))
    {
      if (!*(str+1))
         break;
      str++;
    }
    str++;
    n--;
  }

  return (unsigned char*)str;
}
Ejemplo n.º 29
0
_WCRTLINK int _NEARFAR(mbrtowc,_fmbrtowc)( wchar_t _FFAR *pwc, const char _FFAR *s, size_t n, mbstate_t _FFAR *ps )
{
    int                 rc;

    /*** Check the simple cases ***/
    if( s == NULL )  return( 0 );           /* always in initial state */
    if( n == 0 )  return( -2 );             /* can't process nothing */

    /*** Check for a valid multibyte character ***/
    rc = _NEARFAR(mbtowc,_fmbtowc)( pwc, s, n );
    if( rc != -1 ) {
        return( rc );
    } else if( n < MB_LEN_MAX && _ismbblead( (unsigned char)*s ) ) {
        return( -2 );                       /* incomplete, possibly valid */
    } else {
        _RWD_errno = EILSEQ;                /* encoding error */
        return( -1 );
    }
}
Ejemplo n.º 30
0
/*********************************************************************
 *		_mbsncpy(MSVCRT.@)
 * REMARKS
 *  The parameter n is the number or characters to copy, not the size of
 *  the buffer. Use _mbsnbcpy for a function analogical to strncpy
 */
unsigned char* CDECL _mbsncpy(unsigned char* dst, const unsigned char* src, size_t n)
{
  unsigned char* ret = dst;
  if(!n)
    return dst;
  if (get_mbcinfo()->ismbcodepage)
  {
    while (*src && n)
    {
      n--;
      if (_ismbblead(*src))
      {
        if (!*(src+1))
        {
            *dst++ = 0;
            *dst++ = 0;
            break;
        }

        *dst++ = *src++;
      }

      *dst++ = *src++;
    }
  }
  else
  {
    while (n)
    {
        n--;
        if (!(*dst++ = *src++)) break;
    }
  }
  while (n--) *dst++ = 0;
  return ret;
}