MetaPragma.java revision 608:7e06bf1dcb09
1/* 2 * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25/* 26 * COMPONENT_NAME: shasta 27 * 28 * ORIGINS: 27 29 * 30 * Licensed Materials - Property of IBM 31 * 5639-D57 (C) COPYRIGHT International Business Machines Corp. 1997,1998,1999 32 * RMI-IIOP v1.0 33 * 34 */ 35 36package com.sun.tools.corba.se.idl.som.idlemit; 37import java.util.Vector; 38import com.sun.tools.corba.se.idl.som.cff.Messages; 39/** 40 * This is an implementation that handles 41 * #pragma meta scoped_name string 42 * where 43 * <UL> 44 * <LI> scoped_name == "::" separated scoped name 45 * <LI> string == separated identifiers, such as "localonly", 46 * "abstract", or "init". 47 * D59407: NOTE: any non-white-space is grouped 48 * as part of the identifier. 49 * </UL> 50 * 51 * This pragma handler places a vector of Strings into the dynamicVariable() 52 * part of the SymtabEntry. The key to access the dynamicVariable() 53 * is com.sun.tools.corba.se.idl.som.idlemit.MetaPragma.metaKey 54 * 55 * It is possible to associate a meta pragma with a forward entry. 56 * At some point after the parser has completed, 57 * the method processForward(ForwardEntry entry) should be called 58 * for each ForwardEntry so that the meta information can be folded from 59 * the ForwardEntry into the corresponding InterfaceEntry. 60 */ 61public class MetaPragma extends com.sun.tools.corba.se.idl.PragmaHandler { 62 /* Class variables */ 63 64 /* key to access the Cached meta info in com.sun.tools.corba.se.idl.SymtabEntry */ 65 public static int metaKey = com.sun.tools.corba.se.idl.SymtabEntry.getVariableKey(); 66 67 68 /** 69 * Main entry point for the MetaPragma handler 70 * @param pragma string for pragma name 71 * @param currentToken next token in the input stream. 72 * @return true if this is a meta pragma. 73 */ 74 public boolean process(String pragma, String currentToken) { 75 if ( !pragma.equals("meta")) 76 return false; 77 78 com.sun.tools.corba.se.idl.SymtabEntry entry ; 79 String msg; 80 try { 81 entry = scopedName(); 82 if ( entry == null){ 83 /* scoped name not found */ 84 parseException(Messages.msg("idlemit.MetaPragma.scopedNameNotFound")); 85 skipToEOL(); 86 } 87 else { 88 msg = (currentToken()+ getStringToEOL()); 89// System.out.println(entry + ": " + msg); 90 Vector v; 91 v = (Vector) entry.dynamicVariable(metaKey); 92 if ( v== null){ 93 v = new Vector(); 94 entry.dynamicVariable(metaKey, v); 95 } 96 parseMsg(v, msg); 97 } 98 } catch(Exception e){ 99// System.out.println("exception in MetaPragma"); 100 } 101 return true; 102 } 103 104 105 /** 106 * Fold the meta info from the forward entry into its corresponding 107 * interface entry. 108 * @param forwardEntry the forward entry to process 109 */ 110 static public void processForward(com.sun.tools.corba.se.idl.ForwardEntry forwardEntry){ 111 112 Vector forwardMeta; 113 try { 114 forwardMeta = (Vector)forwardEntry.dynamicVariable(metaKey); 115 } catch (Exception e){ 116 forwardMeta = null; 117 } 118 com.sun.tools.corba.se.idl.SymtabEntry forwardInterface = forwardEntry.type(); 119 if (forwardMeta != null && forwardInterface!= null) { 120 Vector interfaceMeta; 121 try { 122 interfaceMeta= (Vector)forwardInterface.dynamicVariable(metaKey); 123 } catch ( Exception e){ 124 interfaceMeta = null; 125 } 126 127 if ( interfaceMeta == null) { 128 /* set */ 129 try { 130 forwardInterface.dynamicVariable(MetaPragma.metaKey, forwardMeta); 131 } catch(Exception e){}; 132 } 133 else if (interfaceMeta != forwardMeta) { 134 /* The above check is needed because sometimes 135 a forward entry is processed more the once. 136 Not sure why */ 137 /* merge */ 138 for (int i=0; i < forwardMeta.size(); i++){ 139 try { 140 Object obj = forwardMeta.elementAt(i); 141 interfaceMeta.addElement(obj); 142 } catch (Exception e){}; 143 } 144 } 145 } 146 } 147 148 /** 149 * parse pragma message and place into vector v. 150 * @param v: vector to add message 151 * @param msg: string of comma separated message, perhaps with comment. 152 * This is implemented as a state machine as follows: 153 * 154 * State token next action 155 * ----------------------------------------------------- 156 * initial whitespace initial 157 * initial SlashStar comment 158 * initial SlashSlash final 159 * initial no more final 160 * initial text text add to text buffer 161 * initial StarSlash initial 162 * comment StarSlash initial 163 * comment SlashStar comment 164 * comment whitespace comment 165 * comment SlashSlash comment 166 * comment text comment 167 * comment no more final 168 * text text text add to buffer 169 * text SlashStar comment put in vector 170 * text whitespace initial put in vector 171 * text SlashSlash final put in vector 172 * text StarSlash initial put in vector 173 * text no more final put in vector 174 * 175 */ 176 private static int initialState = 0; 177 private static int commentState = 1; 178 private static int textState = 2; 179 private static int finalState =3; 180 181 private void parseMsg(Vector v, String msg){ 182 int state = initialState; 183 String text = ""; 184 int index = 0; 185 while ( state != finalState ){ 186 boolean isNoMore = index >= msg.length(); 187 char ch = ' '; 188 boolean isSlashStar = false; 189 boolean isSlashSlash = false; 190 boolean isWhiteSpace = false; 191 boolean isStarSlash = false; 192 boolean isText = false; 193 if (!isNoMore ){ 194 ch = msg.charAt(index); 195 if (ch == '/' && index+1 < msg.length()){ 196 if (msg.charAt(index+1) == '/'){ 197 isSlashSlash = true; 198 index++; 199 } 200 else if (msg.charAt(index+1) == '*'){ 201 isSlashStar= true; 202 index++; 203 } else isText = true; 204 } 205 else if (ch == '*' && index+1 < msg.length() ){ 206 if (msg.charAt(index+1) == '/'){ 207 isStarSlash = true; 208 index++; 209 } else isText = true; 210 } 211 else if ( Character.isSpace(ch) || (ch == ',') // 59601 212 || (ch == ';') ) // 59683 213 isWhiteSpace = true; 214 else isText = true; 215 } 216 217 if (state == initialState){ 218 if (isSlashStar){ 219 state = commentState; 220 } 221 else if (isSlashSlash || isNoMore){ 222 state = finalState; 223 } 224 else if (isText){ 225 state = textState; 226 text = text+ ch; 227 } 228 } 229 else if (state == commentState){ 230 if (isNoMore){ 231 state = finalState; 232 } 233 else if ( isStarSlash){ 234 state = initialState; 235 } 236 } 237 else if (state == textState){ 238 if (isNoMore || isStarSlash || isSlashSlash || 239 isSlashStar || isWhiteSpace ){ 240 if (!text.equals("")) { 241 v.addElement(text); 242// System.err.println("adding " + text); 243 text = ""; 244 } 245 if (isNoMore) 246 state = finalState; 247 else if (isSlashStar) 248 state = commentState; 249 else state = initialState; 250 } 251 else if (isText){ 252 text = text+ch; 253 } 254 } 255 index++; 256 } 257 } 258 259} 260