1 /*
   2  * Permission is hereby granted, free of charge, to any person obtaining a copy of
   3  * this software and associated documentation files (the "Software"), to deal in
   4  * the Software without restriction, including without limitation the rights to
   5  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
   6  * of the Software, and to permit persons to whom the Software is furnished to do
   7  * so, subject to the following conditions:
   8  *
   9  * The above copyright notice and this permission notice shall be included in all
  10  * copies or substantial portions of the Software.
  11  *
  12  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  15  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  16  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  17  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  18  * SOFTWARE.
  19  */
  20 package jdk.nashorn.internal.runtime.regexp.joni;
  21 
  22 import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsClear;
  23 
  24 import jdk.nashorn.internal.runtime.regexp.joni.ast.Node;
  25 import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
  26 import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
  27 
  28 public final class ScanEnvironment {
  29 
  30     private static final int SCANENV_MEMNODES_SIZE = 8;
  31 
  32     int option;
  33     final int caseFoldFlag;
  34     final public Syntax syntax;
  35     int captureHistory;
  36     int btMemStart;
  37     int btMemEnd;
  38     int backrefedMem;
  39 
  40     final public Regex reg;
  41 
  42     int numCall;
  43     UnsetAddrList unsetAddrList; // USE_SUBEXP_CALL
  44     public int numMem;
  45 
  46     int numNamed; // USE_NAMED_GROUP
  47 
  48     public Node memNodes[];
  49 
  50     // USE_COMBINATION_EXPLOSION_CHECK
  51     int numCombExpCheck;
  52     int combExpMaxRegNum;
  53     int currMaxRegNum;
  54     boolean hasRecursion;
  55 
  56     public ScanEnvironment(Regex regex, Syntax syntax) {
  57         this.reg = regex;
  58         option = regex.options;
  59         caseFoldFlag = regex.caseFoldFlag;
  60         this.syntax = syntax;
  61     }
  62 
  63     public void clear() {
  64         captureHistory = bsClear();
  65         btMemStart = bsClear();
  66         btMemEnd = bsClear();
  67         backrefedMem = bsClear();
  68 
  69         numCall = 0;
  70         numMem = 0;
  71 
  72         numNamed = 0;
  73 
  74         memNodes = null;
  75 
  76         numCombExpCheck = 0;
  77         combExpMaxRegNum = 0;
  78         currMaxRegNum = 0;
  79         hasRecursion = false;
  80     }
  81 
  82     public int addMemEntry() {
  83         if (numMem++ == 0) {
  84             memNodes = new Node[SCANENV_MEMNODES_SIZE];
  85         } else if (numMem >= memNodes.length) {
  86             Node[]tmp = new Node[memNodes.length << 1];
  87             System.arraycopy(memNodes, 0, tmp, 0, memNodes.length);
  88             memNodes = tmp;
  89         }
  90 
  91         return numMem;
  92     }
  93 
  94     public void setMemNode(int num, Node node) {
  95         if (numMem >= num) {
  96             memNodes[num] = node;
  97         } else {
  98             throw new InternalException(ErrorMessages.ERR_PARSER_BUG);
  99         }
 100     }
 101 
 102     public int convertBackslashValue(int c) {
 103         if (syntax.opEscControlChars()) {
 104             switch (c) {
 105             case 'n': return '\n';
 106             case 't': return '\t';
 107             case 'r': return '\r';
 108             case 'f': return '\f';
 109             case 'a': return '\007';
 110             case 'b': return '\010';
 111             case 'e': return '\033';
 112             case 'v':
 113                 if (syntax.op2EscVVtab()) return 11; // ???
 114                 break;
 115             default:
 116                 break;
 117             }
 118         }
 119         return c;
 120     }
 121 
 122     void ccEscWarn(String s) {
 123         if (Config.USE_WARN) {
 124             if (syntax.warnCCOpNotEscaped() && syntax.backSlashEscapeInCC()) {
 125                 reg.warnings.warn("character class has '" + s + "' without escape");
 126             }
 127         }
 128     }
 129 
 130     void closeBracketWithoutEscapeWarn(String s) {
 131         if (Config.USE_WARN) {
 132             if (syntax.warnCCOpNotEscaped()) {
 133                 reg.warnings.warn("regular expression has '" + s + "' without escape");
 134             }
 135         }
 136     }
 137 }