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