GlueGen v2.6.0-rc-20250712
GlueGen, Native Binding Generator for Java™ (public API).
ProcAddressConfiguration.java
Go to the documentation of this file.
1/*
2 * Copyright (c) 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * - Redistribution of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * - Redistribution in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * Neither the name of Sun Microsystems, Inc. or the names of
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * This software is provided "AS IS," without a warranty of any kind. ALL
20 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
21 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
22 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
23 * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
24 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
25 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
26 * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
27 * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
28 * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
29 * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
30 * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31 *
32 * You acknowledge that this software is not designed or intended for use
33 * in the design, construction, operation or maintenance of any nuclear
34 * facility.
35 *
36 * Sun gratefully acknowledges that this software was originally authored
37 * and developed by Kenneth Bradley Russell and Christopher John Kline.
38 */
39package com.jogamp.gluegen.procaddress;
40
41import static java.util.logging.Level.INFO;
42
43import com.jogamp.gluegen.JavaConfiguration;
44import com.jogamp.gluegen.cgram.types.AliasedSymbol;
45import com.jogamp.gluegen.cgram.types.FunctionSymbol;
46
47import java.io.*;
48import java.text.*;
49import java.util.*;
50
52
53 private boolean emitProcAddressTable = false;
54 private boolean forceProcAddressGen4All = false;
55
56 private String tableClassPackage;
57 private String tableClassName = "ProcAddressTable";
58 private String getProcAddressTableExpr;
59 private String localProcAddressCallingConvention4All = null;
60
61 private ConvNode procAddressNameConverter;
62 private final Set<String> skipProcAddressGen = new HashSet<String>();
63 private final List<String> forceProcAddressGen = new ArrayList<String>();
64 private final Set<String> forceProcAddressGenSet = new HashSet<String>();
65
66 // This is needed only on Windows. Ideally we would modify the
67 // HeaderParser and PCPP to automatically pick up the calling
68 // convention from the headers
69 private final Map<String, String> localProcAddressCallingConventionMap = new HashMap<String, String>();
70
71 @Override
72 protected void dispatch(final String cmd, final StringTokenizer tok, final File file, final String filename, final int lineNo) throws IOException {
73 if (cmd.equalsIgnoreCase("EmitProcAddressTable")) {
74 emitProcAddressTable = readBoolean("EmitProcAddressTable", tok, filename, lineNo).booleanValue();
75 } else if (cmd.equalsIgnoreCase("ProcAddressTablePackage")) {
76 tableClassPackage = readString("ProcAddressTablePackage", tok, filename, lineNo);
77 } else if (cmd.equalsIgnoreCase("ProcAddressTableClassName")) {
78 tableClassName = readString("ProcAddressTableClassName", tok, filename, lineNo);
79 } else if (cmd.equalsIgnoreCase("SkipProcAddressGen")) {
80 final String sym = readString("SkipProcAddressGen", tok, filename, lineNo);
81 skipProcAddressGen.add(sym);
82 } else if (cmd.equalsIgnoreCase("ForceProcAddressGen")) {
83 final String funcName = readString("ForceProcAddressGen", tok, filename, lineNo);
84 if (funcName.equals("__ALL__")) {
85 forceProcAddressGen4All = true;
86 } else {
87 addForceProcAddressGen(funcName);
88 }
89 } else if (cmd.equalsIgnoreCase("GetProcAddressTableExpr")) {
91 } else if (cmd.equalsIgnoreCase("ProcAddressNameExpr")) {
92 readProcAddressNameExpr(tok, filename, lineNo);
93 } else if (cmd.equalsIgnoreCase("LocalProcAddressCallingConvention")) {
94 readLocalProcAddressCallingConvention(tok, filename, lineNo);
95 } else {
96 super.dispatch(cmd, tok, file, filename, lineNo);
97 }
98 }
99
100 protected String readGetProcAddressTableExpr(final StringTokenizer tok, final String filename, final int lineNo) {
101 try {
102 final String restOfLine = tok.nextToken("\n\r\f");
103 return restOfLine.trim();
104 } catch (final NoSuchElementException e) {
105 throw new RuntimeException("Error parsing \"GetProcAddressTableExpr\" command at line " + lineNo
106 + " in file \"" + filename + "\"", e);
107 }
108 }
109
110 protected void setProcAddressNameExpr(final String expr) {
111 // Parse this into something allowing us to map from a function
112 // name to the typedef'ed function pointer name
113 final List<String> tokens = new ArrayList<String>();
114 final StringTokenizer tok1 = new StringTokenizer(expr);
115 while (tok1.hasMoreTokens()) {
116 final String sstr = tok1.nextToken();
117 final StringTokenizer tok2 = new StringTokenizer(sstr, "$()", true);
118 while (tok2.hasMoreTokens()) {
119 tokens.add(tok2.nextToken());
120 }
121 }
122
123 // Now that the string is flattened out, convert it to nodes
124 procAddressNameConverter = makeConverter(tokens.iterator());
125 if (procAddressNameConverter == null) {
126 throw new NoSuchElementException("Error creating converter from string");
127 }
128 }
129
130 protected void readProcAddressNameExpr(final StringTokenizer tok, final String filename, final int lineNo) {
131 try {
132 String restOfLine = tok.nextToken("\n\r\f");
133 restOfLine = restOfLine.trim();
134 setProcAddressNameExpr(restOfLine);
135 } catch (final NoSuchElementException e) {
136 throw new RuntimeException("Error parsing \"ProcAddressNameExpr\" command at line " + lineNo
137 + " in file \"" + filename + "\"", e);
138 }
139 }
140
141 protected void readLocalProcAddressCallingConvention(final StringTokenizer tok, final String filename, final int lineNo) throws IOException {
142 try {
143 final String functionName = tok.nextToken();
144 final String callingConvention = tok.nextToken();
145 if (functionName.equals("__ALL__")) {
146 localProcAddressCallingConvention4All = callingConvention;
147 } else {
148 localProcAddressCallingConventionMap.put(functionName, callingConvention);
149 }
150 } catch (final NoSuchElementException e) {
151 throw new RuntimeException("Error parsing \"LocalProcAddressCallingConvention\" command at line " + lineNo
152 + " in file \"" + filename + "\"", e);
153 }
154 }
155
156 private static ConvNode makeConverter(final Iterator<String> iter) {
157 final List<ConvNode> result = new ArrayList<ConvNode>();
158
159 while (iter.hasNext()) {
160 final String str = iter.next();
161 if (str.equals("$")) {
162 final String command = iter.next();
163 final String openParen = iter.next();
164 if (!openParen.equals("(")) {
165 throw new NoSuchElementException("Expected \"(\"");
166 }
167 boolean uppercase = false;
168 if (command.equalsIgnoreCase("UPPERCASE")) {
169 uppercase = true;
170 } else if (!command.equalsIgnoreCase("LOWERCASE")) {
171 throw new NoSuchElementException("Unknown ProcAddressNameExpr command \"" + command + "\"");
172 }
173 result.add(new CaseNode(uppercase, makeConverter(iter)));
174 } else if (str.equals(")")) {
175 // Fall through and return
176 } else if (str.indexOf('{') >= 0) {
177 result.add(new FormatNode(str));
178 } else {
179 result.add(new ConstStringNode(str));
180 }
181 }
182 if (result.isEmpty()) {
183 return null;
184 } else if (result.size() == 1) {
185 return result.get(0);
186 } else {
187 return new ConcatNode(result);
188 }
189 }
190
191 /** Helper class for converting a function name to the typedef'ed
192 function pointer name */
193 static abstract class ConvNode {
194 abstract String convert(String funcName);
195 }
196
197 static class FormatNode extends ConvNode {
198
199 private final MessageFormat msgFmt;
200
201 FormatNode(final String fmt) {
202 msgFmt = new MessageFormat(fmt);
203 }
204
205 @Override
206 String convert(final String funcName) {
207 final StringBuffer buf = new StringBuffer();
208 msgFmt.format(new Object[]{funcName}, buf, null);
209 return buf.toString();
210 }
211 }
212
213 static class ConstStringNode extends ConvNode {
214
215 private final String str;
216
217 ConstStringNode(final String str) {
218 this.str = str;
219 }
220
221 @Override
222 String convert(final String funcName) {
223 return str;
224 }
225 }
226
227 static class ConcatNode extends ConvNode {
228
229 private final List<ConvNode> children;
230
231 ConcatNode(final List<ConvNode> children) {
232 this.children = children;
233 }
234
235 @Override
236 String convert(final String funcName) {
237 final StringBuilder res = new StringBuilder();
238 for (final ConvNode node : children) {
239 res.append(node.convert(funcName));
240 }
241 return res.toString();
242 }
243 }
244
245 static class CaseNode extends ConvNode {
246
247 private final boolean upperCase;
248 private final ConvNode child;
249
250 CaseNode(final boolean upperCase, final ConvNode child) {
251 this.upperCase = upperCase;
252 this.child = child;
253 }
254
255 @Override
256 public String convert(final String funcName) {
257 if (upperCase) {
258 return child.convert(funcName).toUpperCase();
259 } else {
260 return child.convert(funcName).toLowerCase();
261 }
262 }
263 }
264
265 public boolean emitProcAddressTable() {
266 return emitProcAddressTable;
267 }
268
269 public String tableClassPackage() {
270 return tableClassPackage;
271 }
272
273 public String tableClassName() {
274 return tableClassName;
275 }
276
277 public boolean skipProcAddressGen(final FunctionSymbol symbol) {
278 if ( skipProcAddressGen.contains( symbol.getName() ) ||
279 oneInSet(skipProcAddressGen, symbol.getAliasedNames())
280 )
281 {
282 LOG.log(INFO, symbol.getASTLocusTag(), "Skip ProcAddress: {0}", symbol);
283 return true;
284 }
285 return false;
286 }
287
288 public boolean isForceProcAddressGen4All() {
289 return forceProcAddressGen4All;
290 }
291
292 public List<String> getForceProcAddressGen() {
293 return forceProcAddressGen;
294 }
295
296 public String getProcAddressTableExpr() {
297 if (getProcAddressTableExpr == null) {
298 throw new RuntimeException("GetProcAddressTableExpr was not defined in .cfg file");
299 }
300 return getProcAddressTableExpr;
301 }
302 protected void setProcAddressTableExpr(final String s) {
303 getProcAddressTableExpr = s;
304 }
305
306 public String convertToFunctionPointerName(final String funcName) {
307 if (procAddressNameConverter == null) {
308 throw new RuntimeException("ProcAddressNameExpr was not defined in .cfg file");
309 }
310 return procAddressNameConverter.convert(funcName);
311 }
312
313 public boolean forceProcAddressGen(final FunctionSymbol symbol) {
314 if( forceProcAddressGen4All ) {
315 if(!forceProcAddressGen4AllOnce) {
316 forceProcAddressGen4AllOnce = true;
317 LOG.log(INFO, symbol.getASTLocusTag(), "Force ALL ProcAddress");
318 }
319 return true;
320 }
321
322 if ( forceProcAddressGenSet.contains( symbol.getName() ) ||
323 oneInSet(forceProcAddressGenSet, symbol.getAliasedNames())
324 )
325 {
326 LOG.log(INFO, symbol.getASTLocusTag(), "Force ProcAddress: {0}", symbol);
327 return true;
328 }
329 return false;
330 }
331 private static boolean forceProcAddressGen4AllOnce = false;
332
333 public void addForceProcAddressGen(final String funcName) {
334 forceProcAddressGen.add(funcName);
335 forceProcAddressGenSet.add(funcName);
336 }
337
338 public void addLocalProcAddressCallingConvention(final String funcName, final String callingConvention) {
339 localProcAddressCallingConventionMap.put(funcName, callingConvention);
340 }
341
345 }
346 final String res = localProcAddressCallingConventionMap.get(symbol.getName());
347 if( null != res ) {
348 return res;
349 }
350 return oneInMap(localProcAddressCallingConventionMap, symbol.getAliasedNames());
351 }
352
354 return localProcAddressCallingConvention4All != null;
355 }
356
358 return localProcAddressCallingConvention4All;
359 }
360}
Parses and provides access to the contents of .cfg files for the JavaEmitter.
static< K, V > V oneInMap(final Map< K, V > map, final Set< K > symbols)
static< K > boolean oneInSet(final Set< K > set1, final Set< K > set2)
String readString(final String cmd, final StringTokenizer tok, final String filename, final int lineNo)
Boolean readBoolean(final String cmd, final StringTokenizer tok, final String filename, final int lineNo)
Set< String > getAliasedNames()
Return all aliases for this symbol, i.e.
String getName()
Return the current-name, which is the last renamed-name if issued, or the original-name.
Describes a function symbol, which includes the name and type.
ASTLocusTag getASTLocusTag()
Returns this instance's ASTLocusTag, if available, otherwise returns null.
void addLocalProcAddressCallingConvention(final String funcName, final String callingConvention)
String readGetProcAddressTableExpr(final StringTokenizer tok, final String filename, final int lineNo)
void readLocalProcAddressCallingConvention(final StringTokenizer tok, final String filename, final int lineNo)
String getLocalProcAddressCallingConvention(final FunctionSymbol symbol)
void readProcAddressNameExpr(final StringTokenizer tok, final String filename, final int lineNo)
void dispatch(final String cmd, final StringTokenizer tok, final File file, final String filename, final int lineNo)
void log(final Level level, final String msg)
See Logger#log(Level, String).