@@ -1048,12 +1048,50 @@ void ConverterRefCount::ConvertPrintf(clang::CallExpr *expr) {
10481048 StrCat (' )' );
10491049}
10501050
1051+ void ConverterRefCount::ConvertSnprintf (clang::CallExpr *expr) {
1052+ std::string format;
1053+ if (auto *str = clang::dyn_cast<clang::StringLiteral>(
1054+ expr->getArg (2 )->IgnoreImplicit ())) {
1055+ format = GetEscapedStringLiteral (str);
1056+ } else {
1057+ llvm::errs () << " Unknown snprintf format: " ;
1058+ expr->getArg (2 )->dump ();
1059+ llvm::errs () << ' \n ' ;
1060+ exit (1 );
1061+ }
1062+ auto types = printf2fmt (format);
1063+
1064+ StrCat (" ({ let __s = format!(" , format);
1065+ unsigned j = 0 ;
1066+ for (unsigned i = 3 , e = expr->getNumArgs (); i < e; ++i) {
1067+ StrCat (token::kComma );
1068+ Convert (expr->getArg (i));
1069+ if (types[j]) {
1070+ StrCat (keyword::kAs , types[j]);
1071+ }
1072+ ++j;
1073+ }
1074+ StrCat (" ); let __b = __s.as_bytes(); let __size = (" );
1075+ Convert (expr->getArg (1 ));
1076+ StrCat (" ) as usize; if __size > 0 {" ,
1077+ " let __n = ::std::cmp::min(__b.len(), __size - 1); (" );
1078+ Convert (expr->getArg (0 ));
1079+ StrCat (" ).with_slice_mut(__n + 1, |__dst| {" ,
1080+ " __dst[..__n].copy_from_slice(&__b[..__n]); __dst[__n] = 0; }); }" ,
1081+ " __b.len() as i32 })" );
1082+ }
1083+
10511084bool ConverterRefCount::VisitCallExpr (clang::CallExpr *expr) {
10521085 if (IsBuiltinVaStart (expr) || IsBuiltinVaEnd (expr) || IsBuiltinVaCopy (expr)) {
10531086 ConvertVAArgCall (expr);
10541087 return false ;
10551088 }
10561089
1090+ if (Mapper::ToString (expr->getCallee ()).starts_with (" int snprintf" )) {
1091+ ConvertSnprintf (expr);
1092+ return false ;
1093+ }
1094+
10571095 if (expr->isCallToStdMove ()) {
10581096 if (IsUniquePtr (expr->getArg (0 )->getType ())) {
10591097 StrCat (std::format (" {}.take()" , ConvertLValue (expr->getArg (0 ))));
0 commit comments