@@ -3884,6 +3884,50 @@ public char[] toCharArray() {
38843884 return result ;
38853885 }
38863886
3887+ /**
3888+ * Helper function for the {@code format} function.
3889+ * Serialize potential String.format argument to a String.
3890+ * The returned String is never null.
3891+ */
3892+ static String cproverFormatArgument (Object obj ) {
3893+ if (obj == null ) {
3894+ return "null" ;
3895+ }
3896+ if (obj instanceof String ) {
3897+ return (String ) obj ;
3898+ }
3899+
3900+ // All primitive types are cast to a long
3901+ long longValue = 0 ;
3902+ if (obj instanceof Integer ) {
3903+ longValue = (Integer ) obj ;
3904+ } else if (obj instanceof Long ) {
3905+ longValue = (Long ) obj ;
3906+ } else if (obj instanceof Float ) {
3907+ longValue = (long ) ((Float ) obj ).doubleValue ();
3908+ } else if (obj instanceof Double ) {
3909+ longValue = (long ) ((Double ) obj ).doubleValue ();
3910+ } else if (obj instanceof Character ) {
3911+ char charValue = (Character ) obj ;
3912+ longValue = (long ) charValue ;
3913+ } else if (obj instanceof Byte ) {
3914+ byte byteValue = ((Byte ) obj );
3915+ longValue = (long ) byteValue ;
3916+ } else if (obj instanceof Boolean ) {
3917+ longValue = ((Boolean ) obj ) ? 1 : 0 ;
3918+ } else {
3919+ return CProver .nondetWithoutNull ("" );
3920+ }
3921+
3922+ // The long value is encoded using a string of 4 characters
3923+ StringBuilder builder = new StringBuilder ();
3924+ builder .append ((char ) (longValue >> 48 & 0xFFFF ));
3925+ builder .append ((char ) (longValue >> 32 & 0xFFFF ));
3926+ builder .append ((char ) (longValue >> 16 & 0xFFFF ));
3927+ builder .append ((char ) (longValue & 0xFFFF ));
3928+ return builder .toString ();
3929+ }
3930+
38873931 /**
38883932 * Returns a formatted string using the specified format string and
38893933 * arguments.
@@ -3942,13 +3986,32 @@ public char[] toCharArray() {
39423986 * <li>
39433987 * having 5 arguments or more makes the solver slow
39443988 * </li>
3989+ * <li>
3990+ * the string "null" is interpreted the same way {@code null} would be by
3991+ * the JDK String.format function, which is correct for the %s format
3992+ * specifier but not %b for instance.
3993+ * </li>
39453994 * </ul>
39463995 * @diffblue.untested
39473996 */
39483997 public static String format (String format , Object ... args ) {
3949- // DIFFBLUE MODEL LIBRARY This is treated internally in CBMC
3950- return CProver .nondetWithoutNullForNotModelled ();
39513998 // return new Formatter().format(format, args).toString();
3999+ // DIFFBLUE MODEL LIBRARY
4000+ if (args .length > 10 ) {
4001+ return CProver .nondetWithoutNull ("" );
4002+ }
4003+ String arg0 = args .length > 0 ? cproverFormatArgument (args [0 ]) : "" ;
4004+ String arg1 = args .length > 1 ? cproverFormatArgument (args [1 ]) : "" ;
4005+ String arg2 = args .length > 2 ? cproverFormatArgument (args [2 ]) : "" ;
4006+ String arg3 = args .length > 3 ? cproverFormatArgument (args [3 ]) : "" ;
4007+ String arg4 = args .length > 4 ? cproverFormatArgument (args [4 ]) : "" ;
4008+ String arg5 = args .length > 5 ? cproverFormatArgument (args [5 ]) : "" ;
4009+ String arg6 = args .length > 6 ? cproverFormatArgument (args [6 ]) : "" ;
4010+ String arg7 = args .length > 7 ? cproverFormatArgument (args [7 ]) : "" ;
4011+ String arg8 = args .length > 8 ? cproverFormatArgument (args [8 ]) : "" ;
4012+ String arg9 = args .length > 9 ? cproverFormatArgument (args [9 ]) : "" ;
4013+ return CProverString .format (format , arg0 , arg1 , arg2 , arg3 , arg4 , arg5 ,
4014+ arg6 , arg7 , arg8 , arg9 );
39524015 }
39534016
39544017 /**
@@ -3988,12 +4051,12 @@ public static String format(String format, Object... args) {
39884051 * @see java.util.Formatter
39894052 * @since 1.5
39904053 *
3991- * @diffblue.noSupport
4054+ * @diffblue.limitedSupport The locale argument is ignored and it has the
4055+ * same limitations as {@link #format(String, Object...)}.
39924056 */
39934057 public static String format (Locale l , String format , Object ... args ) {
39944058 // return new Formatter(l).format(format, args).toString();
3995- CProver .notModelled ();
3996- return CProver .nondetWithoutNullForNotModelled ();
4059+ return format (format , args );
39974060 }
39984061
39994062 /**
0 commit comments