KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > swt > tools > internal > NativesGenerator


1 /*******************************************************************************
2  * Copyright (c) 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.swt.tools.internal;
12
13 import java.lang.reflect.*;
14 import java.util.HashSet JavaDoc;
15 import java.util.Iterator JavaDoc;
16
17 public class NativesGenerator extends JNIGenerator {
18
19 boolean enterExitMacro;
20
21 public NativesGenerator() {
22     enterExitMacro = true;
23 }
24
25 public void generateCopyright() {
26     generateMetaData("swt_copyright");
27 }
28
29 public void generateIncludes() {
30     String JavaDoc outputName = getOutputName();
31     outputln("#include \"swt.h\"");
32     output("#include \"");
33     output(outputName);
34     outputln("_structs.h\"");
35     output("#include \"");
36     output(outputName);
37     outputln("_stats.h\"");
38     outputln();
39 }
40
41 public void generate(Class JavaDoc clazz, String JavaDoc methodName) {
42     Method[] methods = clazz.getDeclaredMethods();
43     int count = 0;
44     for (int i = 0; i < methods.length; i++) {
45         if (methods[i].getName().startsWith(methodName)) count++;
46     }
47     Method[] result = new Method[count];
48     count = 0;
49     for (int i = 0; i < methods.length; i++) {
50         if (methods[i].getName().startsWith(methodName)) result[count++] = methods[i];
51     }
52     generate(result);
53 }
54
55 public void generate(Class JavaDoc clazz) {
56     Method[] methods = clazz.getDeclaredMethods();
57     int i = 0;
58     for (; i < methods.length; i++) {
59         Method method = methods[i];
60         if ((method.getModifiers() & Modifier.NATIVE) != 0) break;
61     }
62     if (i == methods.length) return;
63     sort(methods);
64     if (isCPP) {
65         outputln("extern \"C\" {");
66         outputln();
67     }
68     generateNativeMacro(clazz);
69     generateExcludes(methods);
70     generate(methods);
71     if (isCPP) {
72         outputln("}");
73     }
74 }
75
76 public void generate(Method[] methods) {
77     sort(methods);
78     for (int i = 0; i < methods.length; i++) {
79         Method method = methods[i];
80         if ((method.getModifiers() & Modifier.NATIVE) == 0) continue;
81         generate(method);
82         if (progress != null) progress.step();
83     }
84 }
85
86 public void generate(Method method) {
87     MethodData methodData = getMetaData().getMetaData(method);
88     if (methodData.getFlag("no_gen")) return;
89     Class JavaDoc returnType = method.getReturnType();
90     Class JavaDoc[] paramTypes = method.getParameterTypes();
91     String JavaDoc function = getFunctionName(method);
92     
93     if (!(returnType == Void.TYPE || returnType.isPrimitive() || isSystemClass(returnType) || returnType == String JavaDoc.class)) {
94         output("Warning: bad return type. :");
95         outputln(method.toString());
96         return;
97     }
98     
99     generateSourceStart(function);
100     generateFunctionPrototype(method, function, paramTypes, returnType);
101     generateFunctionBody(method, methodData, function, paramTypes, returnType);
102     generateSourceEnd(function);
103     outputln();
104 }
105
106 public void setEnterExitMacro(boolean enterExitMacro) {
107     this.enterExitMacro = enterExitMacro;
108 }
109
110 void generateExcludes(Method[] methods) {
111     HashSet JavaDoc excludes = new HashSet JavaDoc();
112     for (int i = 0; i < methods.length; i++) {
113         Method method = methods[i];
114         if ((method.getModifiers() & Modifier.NATIVE) == 0) continue;
115         MethodData methodData = getMetaData().getMetaData(method);
116         String JavaDoc exclude = methodData.getExclude();
117         if (exclude.length() != 0) {
118             excludes.add(exclude);
119         }
120     }
121     for (Iterator JavaDoc iter = excludes.iterator(); iter.hasNext();) {
122         String JavaDoc exclude = (String JavaDoc)iter.next();
123         outputln(exclude);
124         for (int i = 0; i < methods.length; i++) {
125             Method method = methods[i];
126             if ((method.getModifiers() & Modifier.NATIVE) == 0) continue;
127             MethodData methodData = getMetaData().getMetaData(method);
128             String JavaDoc methodExclude = methodData.getExclude();
129             if (exclude.equals(methodExclude)) {
130                 output("#define NO_");
131                 outputln(getFunctionName(method));
132             }
133         }
134         outputln("#endif");
135         outputln();
136     }
137 }
138
139 void generateNativeMacro(Class JavaDoc clazz) {
140     output("#define ");
141     output(getClassName(clazz));
142     output("_NATIVE(func) Java_");
143     output(toC(clazz.getName()));
144     outputln("_##func");
145     outputln();
146 }
147
148 boolean generateGetParameter(Method method, int i, Class JavaDoc paramType, ParameterData paramData, boolean critical, int indent) {
149     if (paramType.isPrimitive() || isSystemClass(paramType)) return false;
150     String JavaDoc iStr = String.valueOf(i);
151     for (int j = 0; j < indent; j++) output("\t");
152     output("if (arg");
153     output(iStr);
154     output(") if ((lparg");
155     output(iStr);
156     output(" = ");
157     if (paramType.isArray()) {
158         Class JavaDoc componentType = paramType.getComponentType();
159         if (componentType.isPrimitive()) {
160             if (critical) {
161                 if (isCPP) {
162                     output("env->GetPrimitiveArrayCritical(arg");
163                 } else {
164                     output("(*env)->GetPrimitiveArrayCritical(env, arg");
165                 }
166                 output(iStr);
167                 output(", NULL)");
168             } else {
169                 if (isCPP) {
170                     output("env->Get");
171                 } else {
172                     output("(*env)->Get");
173                 }
174                 output(getTypeSignature1(componentType));
175                 if (isCPP) {
176                     output("ArrayElements(arg");
177                 } else {
178                     output("ArrayElements(env, arg");
179                 }
180                 output(iStr);
181                 output(", NULL)");
182             }
183         } else {
184             throw new Error JavaDoc("not done");
185         }
186     } else if (paramType == String JavaDoc.class) {
187         if (paramData.getFlag("unicode")) {
188             if (isCPP) {
189                 output("env->GetStringChars(arg");
190             } else {
191                 output("(*env)->GetStringChars(env, arg");
192             }
193             output(iStr);
194             output(", NULL)");
195         } else {
196             if (isCPP) {
197                 output("env->GetStringUTFChars(arg");
198             } else {
199                 output("(*env)->GetStringUTFChars(env, arg");
200             }
201             output(iStr);
202             output(", NULL)");
203         }
204     } else {
205         if (paramData.getFlag("no_in")) {
206             output("&_arg");
207             output(iStr);
208         } else {
209             output("get");
210             output(getClassName(paramType));
211             output("Fields(env, arg");
212             output(iStr);
213             output(", &_arg");
214             output(iStr);
215             output(")");
216         }
217     }
218     outputln(") == NULL) goto fail;");
219     return true;
220 }
221
222 void generateSetParameter(int i, Class JavaDoc paramType, ParameterData paramData, boolean critical) {
223     if (paramType.isPrimitive() || isSystemClass(paramType)) return;
224     String JavaDoc iStr = String.valueOf(i);
225     if (paramType.isArray()) {
226         output("\tif (arg");
227         output(iStr);
228         output(" && lparg");
229         output(iStr);
230         output(") ");
231         Class JavaDoc componentType = paramType.getComponentType();
232         if (componentType.isPrimitive()) {
233             if (critical) {
234                 if (isCPP) {
235                     output("env->ReleasePrimitiveArrayCritical(arg");
236                 } else {
237                     output("(*env)->ReleasePrimitiveArrayCritical(env, arg");
238                 }
239                 output(iStr);
240             } else {
241                 if (isCPP) {
242                     output("env->Release");
243                 } else {
244                     output("(*env)->Release");
245                 }
246                 output(getTypeSignature1(componentType));
247                 if (isCPP) {
248                     output("ArrayElements(arg");
249                 } else {
250                     output("ArrayElements(env, arg");
251                 }
252                 output(iStr);
253             }
254             output(", lparg");
255             output(iStr);
256             output(", ");
257             if (paramData.getFlag("no_out")) {
258                 output("JNI_ABORT");
259             } else {
260                 output("0");
261             }
262             output(");");
263         } else {
264             throw new Error JavaDoc("not done");
265         }
266         outputln();
267     } else if (paramType == String JavaDoc.class) {
268         output("\tif (arg");
269         output(iStr);
270         output(" && lparg");
271         output(iStr);
272         output(") ");
273         if (paramData.getFlag("unicode")) {
274             if (isCPP) {
275                 output("env->ReleaseStringChars(arg");
276             } else {
277                 output("(*env)->ReleaseStringChars(env, arg");
278             }
279         } else {
280             if (isCPP) {
281                 output("env->ReleaseStringUTFChars(arg");
282             } else {
283                 output("(*env)->ReleaseStringUTFChars(env, arg");
284             }
285         }
286         output(iStr);
287         output(", lparg");
288         output(iStr);
289         outputln(");");
290     } else {
291         if (!paramData.getFlag("no_out")) {
292             output("\tif (arg");
293             output(iStr);
294             output(" && lparg");
295             output(iStr);
296             output(") ");
297             output("set");
298             output(getClassName(paramType));
299             output("Fields(env, arg");
300             output(iStr);
301             output(", lparg");
302             output(iStr);
303             outputln(");");
304         }
305     }
306 }
307
308 void generateExitMacro(Method method, String JavaDoc function) {
309     if (!enterExitMacro) return;
310     output("\t");
311     output(getClassName(method.getDeclaringClass()));
312     output("_NATIVE_EXIT(env, that, ");
313     output(function);
314     outputln("_FUNC);");
315 }
316
317 void generateEnterMacro(Method method, String JavaDoc function) {
318     if (!enterExitMacro) return;
319     output("\t");
320     output(getClassName(method.getDeclaringClass()));
321     output("_NATIVE_ENTER(env, that, ");
322     output(function);
323     outputln("_FUNC);");
324 }
325
326 boolean generateLocalVars(Method method, Class JavaDoc[] paramTypes, Class JavaDoc returnType) {
327     boolean needsReturn = enterExitMacro;
328     for (int i = 0; i < paramTypes.length; i++) {
329         Class JavaDoc paramType = paramTypes[i];
330         if (paramType.isPrimitive() || isSystemClass(paramType)) continue;
331         ParameterData paramData = getMetaData().getMetaData(method, i);
332         output("\t");
333         if (paramType.isArray()) {
334             Class JavaDoc componentType = paramType.getComponentType();
335             if (componentType.isPrimitive()) {
336                 output(getTypeSignature2(componentType));
337                 output(" *lparg" + i);
338                 output("=NULL;");
339             } else {
340                 throw new Error JavaDoc("not done");
341             }
342         } else if (paramType == String JavaDoc.class) {
343             if (paramData.getFlag("unicode")) {
344                 output("const jchar *lparg" + i);
345             } else {
346                 output("const char *lparg" + i);
347             }
348             output("= NULL;");
349         } else {
350             output(getClassName(paramType));
351             output(" _arg" + i);
352             if (paramData.getFlag("init")) output("={0}");
353             output(", *lparg" + i);
354             output("=NULL;");
355         }
356         outputln();
357         needsReturn = true;
358     }
359     if (needsReturn) {
360         if (returnType != Void.TYPE) {
361             output("\t");
362             output(getTypeSignature2(returnType));
363             outputln(" rc = 0;");
364         }
365     }
366     return needsReturn;
367 }
368
369 boolean generateGetters(Method method, Class JavaDoc[] paramTypes) {
370     boolean genFailTag = false;
371     int criticalCount = 0;
372     for (int i = 0; i < paramTypes.length; i++) {
373         Class JavaDoc paramType = paramTypes[i];
374         ParameterData paramData = getMetaData().getMetaData(method, i);
375         if (!isCritical(paramType, paramData)) {
376             genFailTag |= generateGetParameter(method, i, paramType, paramData, false, 1);
377         } else {
378             criticalCount++;
379         }
380     }
381     if (criticalCount != 0) {
382         outputln("#ifdef JNI_VERSION_1_2");
383         outputln("\tif (IS_JNI_1_2) {");
384         for (int i = 0; i < paramTypes.length; i++) {
385             Class JavaDoc paramType = paramTypes[i];
386             ParameterData paramData = getMetaData().getMetaData(method, i);
387             if (isCritical(paramType, paramData)) {
388                 genFailTag |= generateGetParameter(method, i, paramType, paramData, true, 2);
389             }
390         }
391         outputln("\t} else");
392         outputln("#endif");
393         outputln("\t{");
394         for (int i = 0; i < paramTypes.length; i++) {
395             Class JavaDoc paramType = paramTypes[i];
396             ParameterData paramData = getMetaData().getMetaData(method, i);
397             if (isCritical(paramType, paramData)) {
398                 genFailTag |= generateGetParameter(method, i, paramType, paramData, false, 2);
399             }
400         }
401         outputln("\t}");
402     }
403     return genFailTag;
404 }
405
406 void generateSetters(Method method, Class JavaDoc[] paramTypes) {
407     int criticalCount = 0;
408     for (int i = paramTypes.length - 1; i >= 0; i--) {
409         Class JavaDoc paramType = paramTypes[i];
410         ParameterData paramData = getMetaData().getMetaData(method, i);
411         if (isCritical(paramType, paramData)) {
412             criticalCount++;
413         }
414     }
415     if (criticalCount != 0) {
416         outputln("#ifdef JNI_VERSION_1_2");
417         outputln("\tif (IS_JNI_1_2) {");
418         for (int i = paramTypes.length - 1; i >= 0; i--) {
419             Class JavaDoc paramType = paramTypes[i];
420             ParameterData paramData = getMetaData().getMetaData(method, i);
421             if (isCritical(paramType, paramData)) {
422                 output("\t");
423                 generateSetParameter(i, paramType, paramData, true);
424             }
425         }
426         outputln("\t} else");
427         outputln("#endif");
428         outputln("\t{");
429         for (int i = paramTypes.length - 1; i >= 0; i--) {
430             Class JavaDoc paramType = paramTypes[i];
431             ParameterData paramData = getMetaData().getMetaData(method, i);
432             if (isCritical(paramType, paramData)) {
433                 output("\t");
434                 generateSetParameter(i, paramType, paramData, false);
435             }
436         }
437         outputln("\t}");
438     }
439     for (int i = paramTypes.length - 1; i >= 0; i--) {
440         Class JavaDoc paramType = paramTypes[i];
441         ParameterData paramData = getMetaData().getMetaData(method, i);
442         if (!isCritical(paramType, paramData)) {
443             generateSetParameter(i, paramType, paramData, false);
444         }
445     }
446 }
447
448 void generateDynamicFunctionCall(Method method, MethodData methodData, Class JavaDoc[] paramTypes, Class JavaDoc returnType, boolean needsReturn) {
449     outputln("/*");
450     generateFunctionCall(method, methodData, paramTypes, returnType, needsReturn);
451     outputln("*/");
452     outputln("\t{");
453
454     String JavaDoc name = method.getName();
455     if (name.startsWith("_")) name = name.substring(1);
456     if (getPlatform().equals("win32")) {
457         outputln("\t\tstatic int initialized = 0;");
458         outputln("\t\tstatic HMODULE hm = NULL;");
459         outputln("\t\tstatic FARPROC fp = NULL;");
460         if (returnType != Void.TYPE) {
461             if (needsReturn) {
462                 outputln("\t\trc = 0;");
463             }
464         }
465         outputln("\t\tif (!initialized) {");
466         output("\t\t\tif (!hm) hm = LoadLibrary(");
467         output(name);
468         outputln("_LIB);");
469         output("\t\t\tif (hm) fp = GetProcAddress(hm, \"");
470         output(name);
471         outputln("\");");
472         outputln("\t\t\tinitialized = 1;");
473         outputln("\t\t}");
474         outputln("\t\tif (fp) {");
475         output("\t\t");
476         generateFunctionCallLeftSide(method, methodData, returnType, needsReturn);
477         output("fp");
478         generateFunctionCallRightSide(method, methodData, paramTypes, 0);
479         outputln();
480         outputln("\t\t}");
481     } else if (getPlatform().equals("carbon")) {
482         outputln("\t\tstatic int initialized = 0;");
483         outputln("\t\tstatic CFBundleRef bundle = NULL;");
484         output("\t\ttypedef ");
485         output(getTypeSignature2(returnType));
486         output(" (*FPTR)(");
487         for (int i = 0; i < paramTypes.length; i++) {
488             if (i != 0) output(", ");
489             Class JavaDoc paramType = paramTypes[i];
490             ParameterData paramData = getMetaData().getMetaData(method, i);
491             String JavaDoc cast = paramData.getCast();
492             if (cast.length() > 2) {
493                 output(cast.substring(1, cast.length() - 1));
494             } else {
495                 output(getTypeSignature4(paramType));
496             }
497         }
498         outputln(");");
499         outputln("\t\tstatic FPTR fptr;");
500         if (returnType != Void.TYPE) {
501             if (needsReturn) {
502                 outputln("\t\trc = 0;");
503             }
504         }
505         outputln("\t\tif (!initialized) {");
506         output("\t\t\tif (!bundle) bundle = CFBundleGetBundleWithIdentifier(CFSTR(");
507         output(name);
508         outputln("_LIB));");
509         output("\t\t\tif (bundle) fptr = (FPTR)CFBundleGetFunctionPointerForName(bundle, CFSTR(\"");
510         output(name);
511         outputln("\"));");
512         outputln("\t\t\tinitialized = 1;");
513         outputln("\t\t}");
514         outputln("\t\tif (fptr) {");
515         output("\t\t");
516         generateFunctionCallLeftSide(method, methodData, returnType, needsReturn);
517         output("(*fptr)");
518         generateFunctionCallRightSide(method, methodData, paramTypes, 0);
519         outputln();
520         outputln("\t\t}");
521     } else {
522         outputln("\t\tstatic int initialized = 0;");
523         outputln("\t\tstatic void *handle = NULL;");
524         output("\t\ttypedef ");
525         output(getTypeSignature2(returnType));
526         output(" (*FPTR)(");
527         for (int i = 0; i < paramTypes.length; i++) {
528             if (i != 0) output(", ");
529             Class JavaDoc paramType = paramTypes[i];
530             ParameterData paramData = getMetaData().getMetaData(method, i);
531             String JavaDoc cast = paramData.getCast();
532             if (cast.length() > 2) {
533                 output(cast.substring(1, cast.length() - 1));
534             } else {
535                 output(getTypeSignature4(paramType));
536             }
537         }
538         outputln(");");
539         outputln("\t\tstatic FPTR fptr;");
540         if (returnType != Void.TYPE) {
541             if (needsReturn) {
542                 outputln("\t\trc = 0;");
543             }
544         }
545         outputln("\t\tif (!initialized) {");
546         output("\t\t\tif (!handle) handle = dlopen(");
547         output(name);
548         outputln("_LIB, RTLD_LAZY);");
549         output("\t\t\tif (handle) fptr = (FPTR)dlsym(handle, \"");
550         output(name);
551         outputln("\");");
552         outputln("\t\t\tinitialized = 1;");
553         outputln("\t\t}");
554         outputln("\t\tif (fptr) {");
555         output("\t\t");
556         generateFunctionCallLeftSide(method, methodData, returnType, needsReturn);
557         output("(*fptr)");
558         generateFunctionCallRightSide(method, methodData, paramTypes, 0);
559         outputln();
560         outputln("\t\t}");
561     }
562
563     outputln("\t}");
564 }
565
566 void generateFunctionCallLeftSide(Method method, MethodData methodData, Class JavaDoc returnType, boolean needsReturn) {
567     output("\t");
568     if (returnType != Void.TYPE) {
569         if (needsReturn) {
570             output("rc = ");
571         } else {
572             output("return ");
573         }
574         output("(");
575         output(getTypeSignature2(returnType));
576         output(")");
577     }
578     if (methodData.getFlag("address")) {
579         output("&");
580     }
581     if (methodData.getFlag("jni")) {
582         output(isCPP ? "env->" : "(*env)->");
583     }
584 }
585
586 void generateFunctionCallRightSide(Method method, MethodData methodData, Class JavaDoc[] paramTypes, int paramStart) {
587     if (!methodData.getFlag("const")) {
588         output("(");
589         if (methodData.getFlag("jni")) {
590             if (!isCPP) output("env, ");
591         }
592         for (int i = paramStart; i < paramTypes.length; i++) {
593             Class JavaDoc paramType = paramTypes[i];
594             ParameterData paramData = getMetaData().getMetaData(method, i);
595             if (i != paramStart) output(", ");
596             if (paramData.getFlag("struct")) output("*");
597             output(paramData.getCast());
598             if (!paramType.isPrimitive() && !isSystemClass(paramType)) output("lp");
599             output("arg" + i);
600         }
601         output(")");
602     }
603     output(";");
604 }
605
606 void generateFunctionCall(Method method, MethodData methodData, Class JavaDoc[] paramTypes, Class JavaDoc returnType, boolean needsReturn) {
607     String JavaDoc copy = (String JavaDoc)methodData.getParam("copy");
608     boolean makeCopy = copy.length() != 0 && isCPP && returnType != Void.TYPE;
609     if (makeCopy) {
610         output("\t");
611         output(copy);
612         output(" temp = ");
613     } else {
614         generateFunctionCallLeftSide(method, methodData, returnType, needsReturn);
615     }
616     int paramStart = 0;
617     String JavaDoc name = method.getName();
618     if (name.startsWith("_")) name = name.substring(1);
619     if (name.equalsIgnoreCase("call")) {
620         output("(");
621         ParameterData paramData = getMetaData().getMetaData(method, 0);
622         String JavaDoc cast = paramData.getCast();
623         if (cast.length() != 0 && !cast.equals("()")) {
624             output(cast);
625         } else {
626             output("(");
627             output(getTypeSignature2(returnType));
628             output(" (*)())");
629         }
630         output("arg0)");
631         paramStart = 1;
632     } else if (name.startsWith("VtblCall")) {
633         output("((");
634         output(getTypeSignature2(returnType));
635         output(" (STDMETHODCALLTYPE *)(");
636         for (int i = 1; i < paramTypes.length; i++) {
637             if (i != 1) output(", ");
638             Class JavaDoc paramType = paramTypes[i];
639             output(getTypeSignature4(paramType));
640         }
641         output("))(*(");
642         output(getTypeSignature4(paramTypes[1]));
643         output(" **)arg1)[arg0])");
644         paramStart = 1;
645     } else if (methodData.getFlag("cpp")) {
646         output("(");
647         ParameterData paramData = getMetaData().getMetaData(method, 0);
648         if (paramData.getFlag("struct")) output("*");
649         String JavaDoc cast = paramData.getCast();
650         if (cast.length() != 0 && !cast.equals("()")) {
651             output(cast);
652         }
653         output("arg0)->");
654         String JavaDoc accessor = methodData.getAccessor();
655         if (accessor.length() != 0) {
656             output(accessor);
657         } else {
658             int index = -1;
659             if ((index = name.indexOf('_')) != -1) {
660                 output(name.substring(index + 1, name.length()));
661             } else {
662                 output(name);
663             }
664         }
665         paramStart = 1;
666     } else if (methodData.getFlag("new")) {
667         output("new ");
668         String JavaDoc accessor = methodData.getAccessor();
669         if (accessor.length() != 0) {
670             output(accessor);
671         } else {
672             int index = -1;
673             if ((index = name.indexOf('_')) != -1) {
674                 output(name.substring(0, index));
675             } else {
676                 output(name);
677             }
678         }
679     } else if (methodData.getFlag("delete")) {
680         output("delete ");
681         ParameterData paramData = getMetaData().getMetaData(method, 0);
682         String JavaDoc cast = paramData.getCast();
683         if (cast.length() != 0 && !cast.equals("()")) {
684             output(cast);
685         } else {
686             output("(");
687             output(name.substring(0, name.indexOf("_")));
688             output(" *)");
689         }
690         outputln("arg0;");
691         return;
692     } else {
693         String JavaDoc accessor = methodData.getAccessor();
694         if (accessor.length() != 0) {
695             output(accessor);
696         } else {
697             output(name);
698         }
699     }
700     generateFunctionCallRightSide(method, methodData, paramTypes, paramStart);
701     outputln();
702     if (makeCopy) {
703         outputln("\t{");
704         output("\t\t");
705         output(copy);
706         output("* copy = new ");
707         output(copy);
708         outputln("();");
709         outputln("\t\t*copy = temp;");
710         output("\t\trc = ");
711         output("(");
712         output(getTypeSignature2(returnType));
713         output(")");
714         outputln("copy;");
715         outputln("\t}");
716     }
717 }
718
719 void generateReturn(Method method, Class JavaDoc returnType, boolean needsReturn) {
720     if (needsReturn && returnType != Void.TYPE) {
721         outputln("\treturn rc;");
722     }
723 }
724
725 void generateGTKmemmove(Method method, String JavaDoc function, Class JavaDoc[] paramTypes) {
726     generateEnterMacro(method, function);
727     output("\t");
728     boolean get = paramTypes[0].isPrimitive();
729     String JavaDoc className = getClassName(paramTypes[get ? 1 : 0]);
730     output(get ? "if (arg1) get" : "if (arg0) set");
731     output(className);
732     output(get ? "Fields(env, arg1, (" : "Fields(env, arg0, (");
733     output(className);
734     output(get ? " *)arg0)" : " *)arg1)");
735     outputln(";");
736     generateExitMacro(method, function);
737 }
738
739 void generateFunctionBody(Method method, MethodData methodData, String JavaDoc function, Class JavaDoc[] paramTypes, Class JavaDoc returnType) {
740     outputln("{");
741     
742     /* Custom GTK memmoves. */
743     String JavaDoc name = method.getName();
744     if (name.startsWith("_")) name = name.substring(1);
745     boolean isGTKmemove = name.equals("memmove") && paramTypes.length == 2 && returnType == Void.TYPE;
746     if (isGTKmemove) {
747         generateGTKmemmove(method, function, paramTypes);
748     } else {
749         boolean needsReturn = generateLocalVars(method, paramTypes, returnType);
750         generateEnterMacro(method, function);
751         boolean genFailTag = generateGetters(method, paramTypes);
752         if (methodData.getFlag("dynamic")) {
753             generateDynamicFunctionCall(method, methodData, paramTypes, returnType, needsReturn);
754         } else {
755             generateFunctionCall(method, methodData, paramTypes, returnType, needsReturn);
756         }
757         if (genFailTag) outputln("fail:");
758         generateSetters(method, paramTypes);
759         generateExitMacro(method, function);
760         generateReturn(method, returnType, needsReturn);
761     }
762     
763     outputln("}");
764 }
765
766 void generateFunctionPrototype(Method method, String JavaDoc function, Class JavaDoc[] paramTypes, Class JavaDoc returnType) {
767     output("JNIEXPORT ");
768     output(getTypeSignature2(returnType));
769     output(" JNICALL ");
770     output(getClassName(method.getDeclaringClass()));
771     output("_NATIVE(");
772     output(function);
773     outputln(")");
774     output("\t(JNIEnv *env, ");
775     if ((method.getModifiers() & Modifier.STATIC) != 0) {
776         output("jclass");
777     } else {
778         output("jobject");
779     }
780     output(" that");
781     for (int i = 0; i < paramTypes.length; i++) {
782         Class JavaDoc paramType = paramTypes[i];
783         output(", ");
784         output(getTypeSignature2(paramType));
785         output(" arg" + i);
786     }
787     outputln(")");
788 }
789
790 void generateSourceStart(String JavaDoc function) {
791     output("#ifndef NO_");
792     outputln(function);
793 }
794
795 void generateSourceEnd(String JavaDoc function) {
796     outputln("#endif");
797 }
798
799 boolean isCritical(Class JavaDoc paramType, ParameterData paramData) {
800     return paramType.isArray() && paramType.getComponentType().isPrimitive() && paramData.getFlag("critical");
801 }
802
803 boolean isSystemClass(Class JavaDoc type) {
804     return type == Object JavaDoc.class || type == Class JavaDoc.class;
805 }
806
807 public static void main(String JavaDoc[] args) {
808 // args = new String[]{"org.eclipse.swt.internal.win32.OS"};
809
if (args.length < 1) {
810         System.out.println("Usage: java NativesGenerator <className1> <className2>");
811         return;
812     }
813     try {
814         NativesGenerator gen = new NativesGenerator();
815         for (int i = 0; i < args.length; i++) {
816             String JavaDoc clazzName = args[i];
817             Class JavaDoc clazz = Class.forName(clazzName);
818             gen.generate(clazz);
819 // gen.generate(clazz, "CommandBar_Destroy");
820
}
821     } catch (Exception JavaDoc e) {
822         System.out.println("Problem");
823         e.printStackTrace(System.out);
824     }
825 }
826
827 }
828
Popular Tags