support.cpp revision 78b6828f1420a266e02687685bc2ab993a54eadd
192a07003b2ce449b22709fbd9b4f1e49b3a2fd3eHoward Hinnant// -*- C++ -*-
2efbe4067f225856814465913bf51e87ec8f17bdbHoward Hinnant//===----------------------- support/win32/support.h ----------------------===//
392a07003b2ce449b22709fbd9b4f1e49b3a2fd3eHoward Hinnant//
492a07003b2ce449b22709fbd9b4f1e49b3a2fd3eHoward Hinnant//                     The LLVM Compiler Infrastructure
592a07003b2ce449b22709fbd9b4f1e49b3a2fd3eHoward Hinnant//
692a07003b2ce449b22709fbd9b4f1e49b3a2fd3eHoward Hinnant// This file is dual licensed under the MIT and the University of Illinois Open
792a07003b2ce449b22709fbd9b4f1e49b3a2fd3eHoward Hinnant// Source Licenses. See LICENSE.TXT for details.
892a07003b2ce449b22709fbd9b4f1e49b3a2fd3eHoward Hinnant//
992a07003b2ce449b22709fbd9b4f1e49b3a2fd3eHoward Hinnant//===----------------------------------------------------------------------===//
1092a07003b2ce449b22709fbd9b4f1e49b3a2fd3eHoward Hinnant
11efbe4067f225856814465913bf51e87ec8f17bdbHoward Hinnant#include <support/win32/support.h>
12efbe4067f225856814465913bf51e87ec8f17bdbHoward Hinnant#include <stdarg.h> // va_start, va_end
136cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant#include <stddef.h> // size_t
146cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant#include <stdlib.h> // malloc
156cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant#include <stdio.h>  // vsprintf, vsnprintf
166cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant#include <string.h> // strcpy, wcsncpy
176cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant
1878b6828f1420a266e02687685bc2ab993a54eaddHoward Hinnantint asprintf(char **sptr, const char *__restrict fmt, ...)
19efbe4067f225856814465913bf51e87ec8f17bdbHoward Hinnant{
20efbe4067f225856814465913bf51e87ec8f17bdbHoward Hinnant    va_list ap;
21efbe4067f225856814465913bf51e87ec8f17bdbHoward Hinnant    va_start(ap, fmt);
22efbe4067f225856814465913bf51e87ec8f17bdbHoward Hinnant    int result = vasprintf(sptr, fmt, ap);
23efbe4067f225856814465913bf51e87ec8f17bdbHoward Hinnant    va_end(ap);
248db4acad3b67808114c495fc21d4db6e7e277087Howard Hinnant    return result;
25efbe4067f225856814465913bf51e87ec8f17bdbHoward Hinnant}
2678b6828f1420a266e02687685bc2ab993a54eaddHoward Hinnantint vasprintf( char **sptr, const char *__restrict fmt, va_list ap )
2792a07003b2ce449b22709fbd9b4f1e49b3a2fd3eHoward Hinnant{
286cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant    *sptr = NULL;
2992a07003b2ce449b22709fbd9b4f1e49b3a2fd3eHoward Hinnant    int count = vsnprintf( *sptr, 0, fmt, ap );
306cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant    if( (count >= 0) && ((*sptr = (char*)malloc(count+1)) != NULL) )
3192a07003b2ce449b22709fbd9b4f1e49b3a2fd3eHoward Hinnant    {
3292a07003b2ce449b22709fbd9b4f1e49b3a2fd3eHoward Hinnant        vsprintf( *sptr, fmt, ap );
3392a07003b2ce449b22709fbd9b4f1e49b3a2fd3eHoward Hinnant        sptr[count] = '\0';
3492a07003b2ce449b22709fbd9b4f1e49b3a2fd3eHoward Hinnant    }
3592a07003b2ce449b22709fbd9b4f1e49b3a2fd3eHoward Hinnant
3692a07003b2ce449b22709fbd9b4f1e49b3a2fd3eHoward Hinnant    return count;
3792a07003b2ce449b22709fbd9b4f1e49b3a2fd3eHoward Hinnant}
386cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant
396cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant// FIXME: use wcrtomb and avoid copy
406cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant// use mbsrtowcs which is available, first copy first nwc elements of src
4178b6828f1420a266e02687685bc2ab993a54eaddHoward Hinnantsize_t mbsnrtowcs( wchar_t *__restrict dst, const char **__restrict src,
4278b6828f1420a266e02687685bc2ab993a54eaddHoward Hinnant                   size_t nmc, size_t len, mbstate_t *__restrict ps )
436cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant{
446cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant    char* local_src = new char[nmc+1];
456cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant    char* nmcsrc = local_src;
466cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant    strncpy( nmcsrc, *src, nmc );
476cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant    nmcsrc[nmc] = '\0';
486cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant    const size_t result = mbsrtowcs( dst, const_cast<const char **>(&nmcsrc), len, ps );
496cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant    // propagate error
506cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant    if( nmcsrc == NULL )
516cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant        *src = NULL;
526cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant    delete[] local_src;
536cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant    return result;
546cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant}
556cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant// FIXME: use wcrtomb and avoid copy
566cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant// use wcsrtombs which is available, first copy first nwc elements of src
5778b6828f1420a266e02687685bc2ab993a54eaddHoward Hinnantsize_t wcsnrtombs( char *__restrict dst, const wchar_t **__restrict src,
5878b6828f1420a266e02687685bc2ab993a54eaddHoward Hinnant                   size_t nwc, size_t len, mbstate_t *__restrict ps )
596cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant{
606cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant    wchar_t* local_src = new wchar_t[nwc];
616cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant    wchar_t* nwcsrc = local_src;
626cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant    wcsncpy(nwcsrc, *src, nwc);
636cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant    nwcsrc[nwc] = '\0';
646cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant    const size_t result = wcsrtombs( dst, const_cast<const wchar_t **>(&nwcsrc), len, ps );
656cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant    // propogate error
666cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant    if( nwcsrc == NULL )
676cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant        *src = NULL;
686cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant    delete[] nwcsrc;
696cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant    return result;
706cd05eeb35636c33a5cd951a7b5501f51611b469Howard Hinnant}
71