Skip to content

Commit b5378cf

Browse files
committed
Fix bugs in Parser
* Fix `Parser` incorrectly recognizing values as pointers when `const` is placed after type (issue #173) * Add `Parser` support for C++11 `using` declarations that act as `typedef` (issue #169) * Let `Parser` accept variables initialized with parentheses (issue #179) * Fix `Parser` confusion between attributes and namespace-less templates (issue #181)
1 parent 89e91f1 commit b5378cf

File tree

3 files changed

+41
-10
lines changed

3 files changed

+41
-10
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11

2+
* Fix `Parser` incorrectly recognizing values as pointers when `const` is placed after type ([issue #173](https://github.com/bytedeco/javacpp/issues/173))
3+
* Add `Parser` support for C++11 `using` declarations that act as `typedef` ([issue #169](https://github.com/bytedeco/javacpp/issues/169))
4+
* Let `Parser` accept variables initialized with parentheses ([issue #179](https://github.com/bytedeco/javacpp/issues/179))
5+
* Fix `Parser` confusion between attributes and namespace-less templates ([issue #181](https://github.com/bytedeco/javacpp/issues/181))
26
* Fix issue with `Loader.getCallerClass()` when a `SecurityManager` cannot be created ([issue #176](https://github.com/bytedeco/javacpp/issues/176))
37
* Make it possible to rename enumerators of C++ `enum class` ([issue #180](https://github.com/bytedeco/javacpp/issues/180))
48
* Make the arbitrary resources available to process executed with `Builder.buildCommand` via the `BUILD_PATH` environment variable

src/main/java/org/bytedeco/javacpp/tools/Generator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3213,10 +3213,10 @@ String[] cppCastTypeName(Class<?> type, Annotation ... annotations) {
32133213
}
32143214
typeName = cppTypeName(type);
32153215
boolean[] b = ((Const)a).value();
3216-
if (b.length > 1 && b[1]) {
3216+
if (b.length > 1 && b[1] && !typeName[0].endsWith(" const *")) {
32173217
typeName[0] = valueTypeName(typeName) + " const *";
32183218
}
3219-
if (b.length > 0 && b[0]) {
3219+
if (b.length > 0 && b[0] && !typeName[0].startsWith("const ")) {
32203220
typeName[0] = "const " + typeName[0];
32213221
}
32223222
Annotation by = by(annotations);

src/main/java/org/bytedeco/javacpp/tools/Parser.java

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2013-2016 Samuel Audet
2+
* Copyright (C) 2013-2017 Samuel Audet
33
*
44
* Licensed either under the Apache License, Version 2.0, or (at your option)
55
* under the terms of the GNU General Public License as published by
@@ -451,7 +451,9 @@ Type type(Context context) throws ParserException {
451451
}
452452
type.cppName += type.cppName.endsWith(">") ? " >" : ">";
453453
} else if (token.match(Token.CONST, Token.CONSTEXPR)) {
454-
if (type.cppName.length() == 0) {
454+
int template = type.cppName.lastIndexOf('<');
455+
String simpleName = template >= 0 ? type.cppName.substring(0, template) : type.cppName;
456+
if (!simpleName.trim().contains(" ") || type.simple) {
455457
type.constValue = true;
456458
} else {
457459
type.constPointer = true;
@@ -1003,8 +1005,8 @@ Declarator declarator(Context context, String defaultName, int infoNumber, boole
10031005
needCast |= info.cast && !type.cppName.equals(type.javaName);
10041006
}
10051007

1006-
if (!valueType) {
1007-
if (dcl.indirections == 0 && !dcl.reference) {
1008+
if (!valueType || context.virtualize) {
1009+
if (!valueType && dcl.indirections == 0 && !dcl.reference) {
10081010
type.annotations += "@ByVal ";
10091011
} else if (dcl.indirections == 0 && dcl.reference) {
10101012
if (type.javaName.contains("@ByPtrPtr ")) {
@@ -1389,7 +1391,8 @@ String commentAfter() throws ParserException {
13891391
}
13901392

13911393
Attribute attribute() throws ParserException {
1392-
if (!tokens.get().match(Token.IDENTIFIER)) {
1394+
// attributes might have arguments that start with '(', but not '<'
1395+
if (!tokens.get().match(Token.IDENTIFIER) || tokens.get(1).match('<')) {
13931396
return null;
13941397
}
13951398
Attribute attr = new Attribute();
@@ -1555,6 +1558,12 @@ Parameters parameters(Context context, int infoNumber, boolean useDefaults) thro
15551558
tokens.next();
15561559
}
15571560
}
1561+
if (dcls.size() == 1 && (dcls.get(0) == null || dcls.get(0).type == null
1562+
|| dcls.get(0).type.cppName == null || dcls.get(0).type.cppName.length() == 0)) {
1563+
// this looks more like a variable initialization
1564+
tokens.index = backIndex;
1565+
return null;
1566+
}
15581567
params.declarators = dcls.toArray(new Declarator[dcls.size()]);
15591568
return params;
15601569
}
@@ -1828,7 +1837,7 @@ boolean variable(Context context, DeclarationList declList) throws ParserExcepti
18281837
Declaration decl = new Declaration();
18291838
String cppName = dcl.cppName;
18301839
String javaName = dcl.javaName;
1831-
if (javaName == null || !tokens.get().match('[', '=', ',', ':', ';')) {
1840+
if (javaName == null || !tokens.get().match('(', '[', '=', ',', ':', ';')) {
18321841
tokens.index = backIndex;
18331842
return false;
18341843
} else if (!dcl.type.staticMember && context.javaName != null) {
@@ -2138,11 +2147,22 @@ boolean macro(Context context, DeclarationList declList) throws ParserException
21382147

21392148
boolean typedef(Context context, DeclarationList declList) throws ParserException {
21402149
String spacing = tokens.get().spacing;
2141-
if (!tokens.get().match(Token.TYPEDEF)) {
2150+
// the "using" token can also act as a "typedef"
2151+
String usingDefName = tokens.get().match(Token.USING) && tokens.get(1).match(Token.IDENTIFIER)
2152+
&& tokens.get(2).match('=') ? tokens.get(1).value : null;
2153+
if (!tokens.get().match(Token.TYPEDEF) && usingDefName == null) {
21422154
return false;
21432155
}
21442156
Declaration decl = new Declaration();
2157+
if (usingDefName != null) {
2158+
tokens.next().expect(Token.IDENTIFIER);
2159+
tokens.next().expect('=');
2160+
tokens.next();
2161+
}
21452162
Declarator dcl = declarator(context, null, 0, false, 0, true, false);
2163+
if (usingDefName != null) {
2164+
dcl.cppName = usingDefName;
2165+
}
21462166
tokens.next();
21472167

21482168
String typeName = dcl.type.cppName, defName = dcl.cppName;
@@ -2210,7 +2230,14 @@ boolean typedef(Context context, DeclarationList declList) throws ParserExceptio
22102230
info.pointerTypes(typeName);
22112231
}
22122232
if (info.annotations == null) {
2213-
info.cast(!dcl.cppName.equals(info.pointerTypes[0]));
2233+
if (dcl.type.annotations != null && dcl.type.annotations.length() > 0
2234+
&& !dcl.type.annotations.startsWith("@ByVal ")
2235+
&& !dcl.type.annotations.startsWith("@Cast(")
2236+
&& !dcl.type.annotations.startsWith("@Const ")) {
2237+
info.annotations(dcl.type.annotations.trim());
2238+
} else {
2239+
info.cast(!dcl.cppName.equals(info.pointerTypes[0]));
2240+
}
22142241
}
22152242
infoMap.put(info);
22162243
}

0 commit comments

Comments
 (0)