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