Coverage Report - org.webmacro.parser.ParserBlockBuilder
 
Classes in this File Line Coverage Branch Coverage Complexity
ParserBlockBuilder
48%
56/115
46%
48/104
5.923
 
 1  
 /*
 2  
  * Copyright (C) 1998-2000 Semiotek Inc.  All Rights Reserved.
 3  
  *
 4  
  * Redistribution and use in source and binary forms, with or without
 5  
  * modification, are permitted under the terms of either of the following
 6  
  * Open Source licenses:
 7  
  *
 8  
  * The GNU General Public License, version 2, or any later version, as
 9  
  * published by the Free Software Foundation
 10  
  * (http://www.fsf.org/copyleft/gpl.html);
 11  
  *
 12  
  *  or
 13  
  *
 14  
  * The Semiotek Public License (http://webmacro.org/LICENSE.)
 15  
  *
 16  
  * This software is provided "as is", with NO WARRANTY, not even the
 17  
  * implied warranties of fitness to purpose, or merchantability. You
 18  
  * assume all risks and liabilities associated with its use.
 19  
  *
 20  
  * See www.webmacro.org for more information on the WebMacro project.
 21  
  */
 22  
 
 23  
 /**
 24  
  * @author Brian Goetz
 25  
  */
 26  
 
 27  
 package org.webmacro.parser;
 28  
 
 29  
 import org.webmacro.engine.BlockBuilder;
 30  
 
 31  
 /**
 32  
  * ParserBlockBuilder extends BlockBuilder, and should only be used by
 33  
  * the WMParser_impl parser.  It adds methods for eating trailing
 34  
  * <WHITESPACE>  or  <WHITESPACE> <NL> <WHITESPACE>  that precede directives.
 35  
  * It assumes that literal text will not span elements (true for the
 36  
  * current parser) so if the parser changes, this will need to change too.
 37  
  */
 38  
 
 39  
 
 40  
 public class ParserBlockBuilder extends BlockBuilder
 41  
 {
 42  
 
 43  1488
     private int literalMark = 0;
 44  
 
 45  
     public ParserBlockBuilder ()
 46  
     {
 47  0
         super();
 48  0
     }
 49  
 
 50  
     public ParserBlockBuilder (String name)
 51  
     {
 52  1488
         super(name);
 53  1488
     }
 54  
 
 55  
     /** Mark the last character in the block as being a literal (quoted
 56  
      * with backslash) so we don't eat trailing quoted whitespace.
 57  
      */
 58  
     final public void markLiteral ()
 59  
     {
 60  9292
         literalMark = size();
 61  9292
     }
 62  
 
 63  
     private final static boolean isSpaceChar (char c)
 64  
     {
 65  10964
         return (c == ' ' || c == '\t');
 66  
     }
 67  
 
 68  
     private final static int eatWs (String s, int pos)
 69  
     {
 70  10176
         while (pos >= 0 && isSpaceChar(s.charAt(pos)))
 71  2182
             pos--;
 72  7994
         return pos;
 73  
     }
 74  
 
 75  
     private final static int eatOneWs (String s, int pos)
 76  
     {
 77  1046
         if (pos >= 0 && isSpaceChar(s.charAt(pos)))
 78  546
             pos--;
 79  1046
         return pos;
 80  
     }
 81  
 
 82  
     private final static int eatNl (String s, int pos)
 83  
     {
 84  7994
         if (pos >= 0)
 85  
         {
 86  7736
             if (s.charAt(pos) == '\r')
 87  0
                 pos--;
 88  7736
             else if (s.charAt(pos) == '\n')
 89  
             {
 90  7720
                 pos--;
 91  7720
                 if (pos >= 0 && s.charAt(pos) == '\r')
 92  0
                     pos--;
 93  
             }
 94  
         }
 95  7994
         return pos;
 96  
     }
 97  
 
 98  
     final public void eatTrailingWs ()
 99  
     {
 100  
         int i, j;
 101  
 
 102  0
         i = size() - 1;
 103  0
         if (i < 0 || i + 1 == literalMark)
 104  0
             return;
 105  
 
 106  0
         Object o = elementAt(i);
 107  0
         if (!(o instanceof String))
 108  0
             return;
 109  0
         String s = (String) o;
 110  0
         j = eatWs(s, s.length() - 1);
 111  
 
 112  0
         if (j < 0)
 113  0
             remove(i);
 114  0
         else if (j < s.length() - 1)
 115  0
             setElementAt(s.substring(0, j + 1), i);
 116  0
         markLiteral();
 117  0
     }
 118  
 
 119  
 
 120  
     final public void eatTrailingWsNl ()
 121  
     {
 122  
         int i, j;
 123  
 
 124  8488
         i = size() - 1;
 125  8488
         if (i < 0 || i + 1 == literalMark)
 126  332
             return;
 127  
 
 128  8156
         Object o = elementAt(i);
 129  8156
         if (!(o instanceof String))
 130  162
             return;
 131  7994
         String s = (String) o;
 132  7994
         j = eatWs(s, s.length() - 1);
 133  7994
         j = eatNl(s, j);
 134  
 
 135  7994
         if (j < 0)
 136  7348
             remove(i);
 137  646
         else if (j < s.length() - 1)
 138  646
             setElementAt(s.substring(0, j + 1), i);
 139  7994
         markLiteral();
 140  7994
     }
 141  
 
 142  
     final public void eatTrailingWsNlWs ()
 143  
     {
 144  
         int i, j;
 145  
 
 146  0
         i = size() - 1;
 147  0
         if (i < 0 || i + 1 == literalMark)
 148  0
             return;
 149  
 
 150  0
         Object o = elementAt(i);
 151  0
         if (!(o instanceof String))
 152  0
             return;
 153  0
         String s = (String) o;
 154  0
         j = eatWs(s, s.length() - 1);
 155  0
         j = eatNl(s, j);
 156  0
         j = eatWs(s, j);
 157  
 
 158  0
         if (j < 0)
 159  0
             remove(i);
 160  0
         else if (j < s.length() - 1)
 161  0
             setElementAt(s.substring(0, j + 1), i);
 162  0
         markLiteral();
 163  0
     }
 164  
 
 165  
     final public void eatOneWs ()
 166  
     {
 167  
         int i, j;
 168  
 
 169  1246
         i = size() - 1;
 170  1246
         if (i < 0 || i + 1 == literalMark)
 171  0
             return;
 172  
 
 173  1246
         Object o = elementAt(i);
 174  1246
         if (!(o instanceof String))
 175  200
             return;
 176  1046
         String s = (String) o;
 177  1046
         j = eatOneWs(s, s.length() - 1);
 178  
 
 179  1046
         if (j < 0)
 180  8
             remove(i);
 181  1038
         else if (j < s.length() - 1)
 182  538
             setElementAt(s.substring(0, j + 1), i);
 183  1046
         markLiteral();
 184  1046
     }
 185  
 
 186  
     final public void eatLeadingWsNl ()
 187  
     {
 188  
         int i, j, l;
 189  
 
 190  0
         i = size() - 1;
 191  0
         if (i < 0 || i + 1 == literalMark)
 192  0
             return;
 193  
 
 194  0
         Object o = elementAt(i);
 195  0
         if (!(o instanceof String))
 196  0
             return;
 197  0
         String s = (String) o;
 198  0
         j = 0;
 199  0
         l = s.length();
 200  0
         while (j < l && isSpaceChar(s.charAt(j)))
 201  0
             j++;
 202  0
         if (j < l)
 203  
         {
 204  0
             if (s.charAt(j) == '\r')
 205  0
                 j++;
 206  0
             else if (s.charAt(j) == '\n')
 207  
             {
 208  0
                 j++;
 209  0
                 if (j < l && s.charAt(j) == '\r')
 210  0
                     j++;
 211  
             }
 212  
         }
 213  
 
 214  0
         if (j >= l)
 215  0
             remove(i);
 216  0
         else if (j > 0)
 217  0
             setElementAt(s.substring(j), i);
 218  0
         markLiteral();
 219  0
     }
 220  
 
 221  
     final public boolean directiveOk ()
 222  
     {
 223  8554
         if (size() == 0 || size() == literalMark)
 224  336
             return true;
 225  
         else
 226  
         {
 227  8218
             Object o = elementAt(size() - 1);
 228  
             
 229  
             // NOTE: the test for a zero length string in the following 'if' is 
 230  
             // a work-around for a bug parsing an explicit #begin followed 
 231  
             // immediately by another directive, eg, 
 232  
             // #if ($x) #begin #set $y=0 #end
 233  
             // This can be removed when/if this bug is fixed 
 234  
             // Keats 8-Aug-2003
 235  8218
             if (!(o instanceof String) || (((String)o).length() == 0))
 236  162
                 return true;
 237  
             else
 238  
             {
 239  8056
                 String s = (String) o;
 240  8056
                 char ch = s.charAt(s.length() - 1);
 241  8056
                 if (ch == '=' || ch == '\'' || ch == '\"' || ch == ':'
 242  
                         || Character.isLetterOrDigit(ch))
 243  62
                     return false;
 244  
             }
 245  
         }
 246  7994
         return true;
 247  
     }
 248  
 }