1 /*
   2  * @test  /nodynamiccopyright/
   3  * @bug 6827009
   4  * @summary Positive tests for strings in switch.
   5  * @author  Joseph D. Darcy
   6  */
   7 
   8 public class StringSwitches {
   9 
  10     public static void main(String... args) {
  11         int failures = 0;
  12 
  13         failures += testPileup();
  14         failures += testSwitchingTwoWays();
  15 
  16         if (failures > 0) {
  17             throw new RuntimeException();
  18         }
  19     }
  20 
  21     /*
  22      * A zero length string and all strings consisting only of the
  23      * zero character \u0000 have a hash code of zero.  This method
  24      * maps such strings to the number of times \u0000 appears for 0
  25      * through 6 occurrences.
  26      */
  27     private static int zeroHashes(String s) {
  28         int result = Integer.MAX_VALUE;
  29         switch(s) {
  30         case "":
  31             return 0;
  32 
  33         case "\u0000":
  34             result = 1; break;
  35 
  36         case "\u0000\u0000":
  37             return 2;
  38 
  39         case "\u0000\u0000\u0000":
  40             result = 3; break;
  41 
  42         case "\u0000\u0000\u0000\u0000":
  43             return 4;
  44 
  45         case "\u0000\u0000\u0000\u0000\u0000":
  46             result = 5; break;
  47 
  48         case "\u0000\u0000\u0000\u0000\u0000\u0000":
  49             return 6;
  50 
  51         default:
  52             result = -1;
  53         }
  54         return result;
  55     }
  56 
  57     private static int testPileup() {
  58         int failures = 0;
  59         String zero = "";
  60         for(int i = 0; i <= 6; i++, zero += "\u0000") {
  61             int result = zeroHashes(zero);
  62             if (result != i) {
  63                 failures++;
  64                 System.err.printf("For string \"%s\" unexpectedly got %d instead of %d%n.",
  65                                    zero, result, i);
  66             }
  67         }
  68 
  69         if (zeroHashes("foo") != -1) {
  70             failures++;
  71             System.err.println("Failed to get -1 for input string.");
  72         }
  73 
  74         return failures;
  75     }
  76 
  77     /**
  78      * Verify that a switch on an enum and a switch with the same
  79      * structure on the string name of an enum compute equivalent
  80      * values.
  81      */
  82     private static int testSwitchingTwoWays() {
  83         int failures = 0;
  84 
  85         for(MetaSynVar msv : MetaSynVar.values()) {
  86             int enumResult = enumSwitch(msv);
  87             int stringResult = stringSwitch(msv.name());
  88 
  89             if (enumResult != stringResult) {
  90                 failures++;
  91                 System.err.printf("One value %s, computed 0x%x with the enum switch " +
  92                                   "and 0x%x with the string one.%n",
  93                                   msv, enumResult, stringResult);
  94             }
  95         }
  96 
  97         return failures;
  98     }
  99 
 100     private static enum MetaSynVar {
 101         FOO,
 102         BAR,
 103         BAZ,
 104         QUX,
 105         QUUX,
 106         QUUUX,
 107         MUMBLE,
 108         FOOBAR;
 109     }
 110 
 111     private static int enumSwitch(MetaSynVar msv) {
 112         int result = 0;
 113         switch(msv) {
 114         case FOO:
 115             result |= (1<<0);
 116             // fallthrough:
 117 
 118         case BAR:
 119         case BAZ:
 120             result |= (1<<1);
 121             break;
 122 
 123         default:
 124             switch(msv) {
 125             case QUX:
 126                 result |= (1<<2);
 127                 break;
 128 
 129             case QUUX:
 130                 result |= (1<<3);
 131                 
 132             default:
 133                 result |= (1<<4);
 134             }
 135             break;
 136 
 137         case MUMBLE:
 138             result |= (1<<5);
 139             return result;
 140 
 141         case FOOBAR:
 142             result |= (1<<6);
 143             break;
 144         }
 145         return result;
 146     }
 147 
 148     private static int stringSwitch(String msvName) {
 149         int result = 0;
 150         switch(msvName) {
 151         case "FOO":
 152             result |= (1<<0);
 153             // fallthrough:
 154 
 155         case "BAR":
 156         case "BAZ":
 157             result |= (1<<1);
 158             break;
 159 
 160         default:
 161             switch(msvName) {
 162             case "QUX":
 163                 result |= (1<<2);
 164                 break;
 165 
 166             case "QUUX":
 167                 result |= (1<<3);
 168                 
 169             default:
 170                 result |= (1<<4);
 171             }
 172             break;
 173 
 174         case "MUMBLE":
 175             result |= (1<<5);
 176             return result;
 177 
 178         case "FOOBAR":
 179             result |= (1<<6);
 180             break;
 181         }
 182         return result;
 183     }
 184 }