1 # Copyright (C) 2014 The Android Open Source Project 2 # 3 # Licensed under the Apache License, Version 2.0 (the "License"); 4 # you may not use this file except in compliance with the License. 5 # You may obtain a copy of the License at 6 # 7 # http://www.apache.org/licenses/LICENSE-2.0 8 # 9 # Unless required by applicable law or agreed to in writing, software 10 # distributed under the License is distributed on an "AS IS" BASIS, 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 # See the License for the specific language governing permissions and 13 # limitations under the License. 14 15 upper_bound_int_pow2 = 31 16 upper_bound_int_pow2_neg = 32 17 upper_bound_long_pow2 = 63 18 upper_bound_long_pow2_neg = 64 19 upper_bound_constant = 100 20 all_tests = [ 21 ({'@INT@': 'int', '@SUFFIX@':''}, 22 [('CheckDiv', 'idiv_by_pow2_', [2**i for i in range(upper_bound_int_pow2)]), 23 ('CheckDiv', 'idiv_by_pow2_neg_', [-2**i for i in range(upper_bound_int_pow2_neg)]), 24 ('CheckDiv', 'idiv_by_constant_', [i for i in range(1, upper_bound_constant)]), 25 ('CheckDiv', 'idiv_by_constant_neg_', [-i for i in range(1, upper_bound_constant)]), 26 ('CheckRem', 'irem_by_pow2_', [2**i for i in range(upper_bound_int_pow2)]), 27 ('CheckRem', 'irem_by_pow2_neg_', [-2**i for i in range(upper_bound_int_pow2_neg)]), 28 ('CheckRem', 'irem_by_constant_', [i for i in range(1, upper_bound_constant)]), 29 ('CheckRem', 'irem_by_constant_neg_', [-i for i in range(1, upper_bound_constant)])]), 30 ({'@INT@': 'long', '@SUFFIX@': 'l'}, 31 [('CheckDiv', 'ldiv_by_pow2_', [2**i for i in range(upper_bound_long_pow2)]), 32 ('CheckDiv', 'ldiv_by_pow2_neg_', [-2**i for i in range(upper_bound_long_pow2_neg)]), 33 ('CheckDiv', 'ldiv_by_constant_', [i for i in range(1, upper_bound_constant)]), 34 ('CheckDiv', 'ldiv_by_constant_neg_', [-i for i in range(1, upper_bound_constant)]), 35 ('CheckRem', 'lrem_by_pow2_', [2**i for i in range(upper_bound_long_pow2)]), 36 ('CheckRem', 'lrem_by_pow2_neg_', [-2**i for i in range(upper_bound_long_pow2_neg)]), 37 ('CheckRem', 'lrem_by_constant_', [i for i in range(1, upper_bound_constant)]), 38 ('CheckRem', 'lrem_by_constant_neg_', [-i for i in range(1, upper_bound_constant)])]) 39 ] 40 41 def subst_vars(variables, text): 42 '''Substitute variables in text.''' 43 for key, value in variables.iteritems(): 44 text = text.replace(str(key), str(value)) 45 return text 46 47 # Generate all the function bodies (in decls) and all the function calls (in calls). 48 decls, calls = '', {} 49 for default_vars, tests in all_tests: 50 local_vars = default_vars.copy() 51 int_type = local_vars['@INT@'] 52 for checker, name, values in tests: 53 local_vars['@CHECKER@'] = checker 54 for i, value in enumerate(values): 55 local_vars['@NAME@'] = name + str(i) 56 local_vars['@VALUE@'] = value 57 local_vars['@OP@'] = '/' if 'div' in name else '%' 58 59 # Function body. 60 decls += subst_vars(local_vars, ''' 61 public static @INT@ @NAME@(@INT@ x) {return x @OP@ @VALUE@@SUFFIX@;}''') 62 63 # Function call and test. 64 calls[int_type] = calls.get(int_type, '') + subst_vars(local_vars, ''' 65 @INT@@CHECKER@("@NAME@", @NAME@(x), x, @VALUE@@SUFFIX@);''') 66 67 # Generate the checkers. 68 checkers = '' 69 local_vars = {} 70 for int_type in ('int', 'long'): 71 local_vars['@INT@'] = int_type 72 for op, op_name in (('/', 'Div'), ('%', 'Rem')): 73 local_vars['@OP@'] = op 74 local_vars['@OP_NAME@'] = op_name 75 checkers += subst_vars(local_vars, ''' 76 public static void @INT@Check@OP_NAME@(String desc, @INT@ result, @INT@ dividend, @INT@ divisor) { 77 @INT@ correct_result = dividend @OP@ divisor; 78 if (result != correct_result) { 79 reportError(desc + "(" + dividend + ") == " + result + 80 " should be " + correct_result); 81 } 82 }''') 83 84 85 code = \ 86 '''/* 87 * Copyright (C) 2014 The Android Open Source Project 88 * 89 * Licensed under the Apache License, Version 2.0 (the "License"); 90 * you may not use this file except in compliance with the License. 91 * You may obtain a copy of the License at 92 * 93 * http://www.apache.org/licenses/LICENSE-2.0 94 * 95 * Unless required by applicable law or agreed to in writing, software 96 * distributed under the License is distributed on an "AS IS" BASIS, 97 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 98 * See the License for the specific language governing permissions and 99 * limitations under the License. 100 */ 101 102 public class Main { 103 public static int num_errors = 0; 104 105 public static void reportError(String message) { 106 if (num_errors == 10) { 107 System.out.println("Omitting other error messages..."); 108 } else if (num_errors < 10) { 109 System.out.println(message); 110 } 111 num_errors += 1; 112 } 113 %s 114 %s 115 116 public static void intCheckAll(int x) {%s 117 } 118 119 public static void longCheckAll(long x) {%s 120 } 121 122 public static void main(String[] args) { 123 int i; 124 long l; 125 126 System.out.println("Begin"); 127 128 System.out.println("Int: checking some equally spaced dividends..."); 129 for (i = -1000; i < 1000; i += 300) { 130 intCheckAll(i); 131 intCheckAll(-i); 132 } 133 134 System.out.println("Int: checking small dividends..."); 135 for (i = 1; i < 100; i += 1) { 136 intCheckAll(i); 137 intCheckAll(-i); 138 } 139 140 System.out.println("Int: checking big dividends..."); 141 for (i = 0; i < 100; i += 1) { 142 intCheckAll(Integer.MAX_VALUE - i); 143 intCheckAll(Integer.MIN_VALUE + i); 144 } 145 146 System.out.println("Long: checking some equally spaced dividends..."); 147 for (l = 0l; l < 1000000000000l; l += 300000000000l) { 148 longCheckAll(l); 149 longCheckAll(-l); 150 } 151 152 System.out.println("Long: checking small dividends..."); 153 for (l = 1l; l < 100l; l += 1l) { 154 longCheckAll(l); 155 longCheckAll(-l); 156 } 157 158 System.out.println("Long: checking big dividends..."); 159 for (l = 0l; l < 100l; l += 1l) { 160 longCheckAll(Long.MAX_VALUE - l); 161 longCheckAll(Long.MIN_VALUE + l); 162 } 163 164 System.out.println("End"); 165 } 166 } 167 ''' % (checkers, decls, calls['int'], calls['long']) 168 169 with open('src/Main.java', 'w') as f: 170 f.write(code) 171