Home | History | Annotate | Download | only in 701-easy-div-rem
      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