Skip to content

Commit 8e1a387

Browse files
Add a model of String.format
This uses CProverString.format which is builtin in the string solver.
1 parent b9aaf22 commit 8e1a387

File tree

1 file changed

+57
-2
lines changed

1 file changed

+57
-2
lines changed

src/main/java/java/lang/String.java

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3884,6 +3884,47 @@ 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+
{
3894+
if(obj == null)
3895+
return "";
3896+
if(obj instanceof String)
3897+
return (String)obj;
3898+
3899+
// All primitive types are cast to a long
3900+
long longValue = 0;
3901+
if(obj instanceof Integer) {
3902+
longValue = (Integer) obj;
3903+
} else if(obj instanceof Long) {
3904+
longValue = (Long) obj;
3905+
} else if(obj instanceof Float) {
3906+
longValue = (long) ((Float)obj).doubleValue();
3907+
} else if (obj instanceof Double) {
3908+
longValue = (long) ((Double)obj).doubleValue();
3909+
} else if (obj instanceof Character) {
3910+
char charValue = (Character)obj;
3911+
longValue = (long) charValue;
3912+
} else if(obj instanceof Byte) {
3913+
byte byteValue = ((Byte)obj);
3914+
longValue = (long) byteValue;
3915+
} else if(obj instanceof Boolean) {
3916+
longValue = ((Boolean) obj) ? 1 : 0;
3917+
}
3918+
3919+
// The long value is encoded using a string of 4 characters
3920+
StringBuilder builder = new StringBuilder();
3921+
builder.append((char) (longValue >> 48 & 0xFFFF));
3922+
builder.append((char) (longValue >> 32 & 0xFFFF));
3923+
builder.append((char) (longValue >> 16 & 0xFFFF));
3924+
builder.append((char) (longValue & 0xFFFF));
3925+
return builder.toString();
3926+
}
3927+
38873928
/**
38883929
* Returns a formatted string using the specified format string and
38893930
* arguments.
@@ -3946,9 +3987,23 @@ public char[] toCharArray() {
39463987
* @diffblue.untested
39473988
*/
39483989
public static String format(String format, Object... args) {
3949-
// DIFFBLUE MODEL LIBRARY This is treated internally in CBMC
3950-
return CProver.nondetWithoutNullForNotModelled();
3990+
// DIFFBLUE MODEL LIBRARY
39513991
// return new Formatter().format(format, args).toString();
3992+
if(args.length > 10) {
3993+
return CProver.nondetWithoutNull("");
3994+
}
3995+
String arg1 = args.length > 0 ? cproverFormatArgument(args[0]) : "";
3996+
String arg2 = args.length > 1 ? cproverFormatArgument(args[1]) : "";
3997+
String arg3 = args.length > 2 ? cproverFormatArgument(args[2]) : "";
3998+
String arg4 = args.length > 3 ? cproverFormatArgument(args[3]) : "";
3999+
String arg5 = args.length > 4 ? cproverFormatArgument(args[4]) : "";
4000+
String arg6 = args.length > 5 ? cproverFormatArgument(args[5]) : "";
4001+
String arg7 = args.length > 6 ? cproverFormatArgument(args[6]) : "";
4002+
String arg8 = args.length > 7 ? cproverFormatArgument(args[7]) : "";
4003+
String arg9 = args.length > 8 ? cproverFormatArgument(args[8]) : "";
4004+
String arg10 = args.length > 9 ? cproverFormatArgument(args[9]) : "";
4005+
return CProverString.format(format, arg1, arg2, arg3, arg4, arg5, arg6,
4006+
arg7, arg8, arg9, arg10);
39524007
}
39534008

39544009
/**

0 commit comments

Comments
 (0)