Skip to content

Commit 5229c0f

Browse files
author
jantje
committed
Do the lookup of the extern C the CDT way
Changed from a regex search function to a query AST to find wether a #incllude statement is in a extern "C" tag Thanks natan :-)
1 parent fcee2b6 commit 5229c0f

File tree

1 file changed

+54
-38
lines changed

1 file changed

+54
-38
lines changed

io.sloeber.core/src/io/sloeber/core/tools/PdePreprocessor.java

Lines changed: 54 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,14 @@
2222
import java.io.ByteArrayInputStream;
2323
import java.text.SimpleDateFormat;
2424
import java.util.Date;
25+
import java.util.HashMap;
2526
import java.util.List;
2627

2728
import org.eclipse.cdt.core.CCorePlugin;
29+
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
2830
import org.eclipse.cdt.core.dom.ast.IASTNode;
2931
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
32+
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
3033
import org.eclipse.cdt.core.index.IIndex;
3134
import org.eclipse.cdt.core.model.CoreModel;
3235
import org.eclipse.cdt.core.model.ICElement;
@@ -43,24 +46,22 @@
4346
import org.eclipse.core.runtime.IPath;
4447
import org.eclipse.core.runtime.Path;
4548

46-
import io.sloeber.common.Const;
47-
48-
@SuppressWarnings("restriction")
49+
@SuppressWarnings({ "nls", "restriction" })
4950
public class PdePreprocessor {
50-
private static String tempFile = ".ino.cpp"; //$NON-NLS-1$
51-
private static final String DEFINE_IN_ECLIPSE = "__IN_ECLIPSE__"; //$NON-NLS-1$
51+
private static String tempFile = ".ino.cpp";
52+
private static final String DEFINE_IN_ECLIPSE = "__IN_ECLIPSE__";
5253

5354
public static void processProject(IProject iProject) throws CoreException {
5455
// first write some standard bla bla
55-
final String NEWLINE = Const.NEWLINE;
56+
final String NEWLINE = "\n";
5657
String body = new String();
57-
String includeHeaderPart = "#include \"Arduino.h\"" + NEWLINE; //$NON-NLS-1$
58+
String includeHeaderPart = "#include \"Arduino.h\"" + NEWLINE;
5859
String includeCodePart = NEWLINE;
59-
String header = "//This is a automatic generated file" + NEWLINE; //$NON-NLS-1$
60-
header += "//Please do not modify this file" + NEWLINE; //$NON-NLS-1$
61-
header += "//If you touch this file your change will be overwritten during the next build" + NEWLINE; //$NON-NLS-1$
62-
header += "//This file has been generated on "; //$NON-NLS-1$
63-
header += new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); //$NON-NLS-1$
60+
String header = "//This is a automatic generated file" + NEWLINE;
61+
header += "//Please do not modify this file" + NEWLINE;
62+
header += "//If you touch this file your change will be overwritten during the next build" + NEWLINE;
63+
header += "//This file has been generated on ";
64+
header += new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
6465
header += NEWLINE;
6566
header += NEWLINE;
6667
ICProject tt = CoreModel.getDefault().create(iProject);
@@ -76,23 +77,23 @@ public static void processProject(IProject iProject) throws CoreException {
7677
}
7778

7879
// take all the files in the project
79-
IResource allResources[] = iProject.members(0);// .getFolder("").members(0);
80+
IResource allResources[] = iProject.members(0);
8081
int numInoFiles = 0;
8182
for (IResource curResource : allResources) {
8283
String extension = curResource.getFileExtension();
8384
// only process .pde and .ino files
84-
if (extension != null && ((extension.equals("pde") || extension.equals("ino")))) { //$NON-NLS-1$ //$NON-NLS-2$
85+
if (extension != null && ((extension.equals("pde") || extension.equals("ino")))) {
8586
numInoFiles++;
8687
String addLine;
8788
if (curResource.isLinked()) {
88-
addLine = "#include \"" + curResource.getLocation() + "\"" + NEWLINE; //$NON-NLS-1$ //$NON-NLS-2$
89+
addLine = "#include \"" + curResource.getLocation() + "\"" + NEWLINE;
8990
} else {
90-
addLine = "#include \"" + curResource.getName() + "\"" + NEWLINE; //$NON-NLS-1$ //$NON-NLS-2$
91+
addLine = "#include \"" + curResource.getName() + "\"" + NEWLINE;
9192
}
9293
// if the name of the ino/pde file matches the project put
9394
// the file in front
9495
// Otherwise add it to the end
95-
if (curResource.getName().equals(iProject.getName() + "." + extension)) { //$NON-NLS-1$
96+
if (curResource.getName().equals(iProject.getName() + "." + extension)) {
9697
includeCodePart = addLine + includeCodePart;
9798
} else {
9899
includeCodePart += addLine;
@@ -107,12 +108,11 @@ public static void processProject(IProject iProject) throws CoreException {
107108
// the indexer is not properly configured so drop a
108109
// error in the file
109110
body += NEWLINE;
110-
body += "#error the file: " + curResource.getName() //$NON-NLS-1$
111-
+ " is not found in the indexer though it exists on the file system." //$NON-NLS-1$
112-
+ NEWLINE;
113-
body += "#error this is probably due to a bad eclipse configuration : ino and pde are not marked as c++ file." //$NON-NLS-1$
111+
body += "#error the file: " + curResource.getName()
112+
+ " is not found in the indexer though it exists on the file system." + NEWLINE;
113+
body += "#error this is probably due to a bad eclipse configuration : ino and pde are not marked as c++ file."
114114
+ NEWLINE;
115-
body += "#error please check whether *.ino and *.pde are marked as C++ source code in windows->preferences->C/C++->file types." //$NON-NLS-1$
115+
body += "#error please check whether *.ino and *.pde are marked as C++ source code in windows->preferences->C/C++->file types."
116116
+ NEWLINE;
117117
} else {
118118
// add declarations made in ino files.
@@ -122,12 +122,12 @@ public static void processProject(IProject iProject) throws CoreException {
122122
for (IASTNode astNode : astNodes) {
123123
if (astNode instanceof CPPASTFunctionDefinition) {
124124
String addString = astNode.getRawSignature();
125-
addString = addString.replaceAll("\r\n", NEWLINE); //$NON-NLS-1$
126-
addString = addString.replaceAll("\r", NEWLINE); //$NON-NLS-1$
127-
addString = addString.replaceAll("//[^\n]+\n", " "); //$NON-NLS-1$ //$NON-NLS-2$
128-
addString = addString.replaceAll("\n", " "); //$NON-NLS-1$ //$NON-NLS-2$
129-
addString = addString.replaceAll("\\{.+\\}", ""); //$NON-NLS-1$//$NON-NLS-2$
130-
if (addString.contains("=") || addString.contains("::")) { //$NON-NLS-1$ //$NON-NLS-2$
125+
addString = addString.replaceAll("\r\n", NEWLINE);
126+
addString = addString.replaceAll("\r", NEWLINE);
127+
addString = addString.replaceAll("//[^\n]+\n", " ");
128+
addString = addString.replaceAll("\n", " ");
129+
addString = addString.replaceAll("\\{.+\\}", "");
130+
if (addString.contains("=") || addString.contains("::")) {
131131
// ignore when there are assignments in the
132132
// declaration
133133
// or when it is a class function
@@ -138,9 +138,30 @@ public static void processProject(IProject iProject) throws CoreException {
138138
}
139139
}
140140

141+
// Locate All lines that are extern "C"
142+
HashMap<Integer, Integer> externCLines = new HashMap<>();
143+
IASTTranslationUnit astTuTest = tu.getAST(index, 0);
144+
IASTDeclaration[] topDeclaratons = astTuTest.getDeclarations();
145+
for (IASTDeclaration curTopDeclaration : topDeclaratons) {
146+
147+
ICPPASTLinkageSpecification test = curTopDeclaration instanceof ICPPASTLinkageSpecification
148+
? (ICPPASTLinkageSpecification) curTopDeclaration : null;
149+
if (test != null) {
150+
if (test.getLiteral().equals("\"C\"")) {
151+
Path curFile = new Path(curTopDeclaration.getContainingFilename());
152+
if (curFile.equals(file.getLocation())) {
153+
int startLine = test.getFileLocation().getStartingLineNumber();
154+
int endLine = test.getFileLocation().getEndingLineNumber();
155+
for (int curline = startLine; curline <= endLine; curline++) {
156+
externCLines.put(new Integer(curline), null);
157+
}
158+
}
159+
}
160+
}
161+
}
162+
141163
// find all the macro's
142164
List<ICElement> theMacros = tu.getChildrenOfType(ICElement.C_MACRO);
143-
String fileContent = new String(tu.getContents());
144165

145166
// list all includes found in the source files.
146167
IInclude includes[] = tu.getIncludes();
@@ -155,24 +176,19 @@ public static void processProject(IProject iProject) throws CoreException {
155176

156177
if ((curMacroLine < curHeaderLine) && (prefHeaderLine < curMacroLine)) {
157178
includeHeaderPart += curMacro.getSource() + NEWLINE;
158-
159179
}
160180
}
161181

162182
prefHeaderLine = curHeaderLine;
163-
String regex = "extern\\s\"C\"\\s?\\{[^\\}]*" + include.getSource(); //$NON-NLS-1$
164-
String[] parts = fileContent.split(regex);
165-
if (parts.length > 1) {
166-
includeHeaderPart += "extern \"C\" {" + NEWLINE; //$NON-NLS-1$
183+
if (externCLines.containsKey(new Integer(curHeaderLine))) {
184+
includeHeaderPart += "extern \"C\" {" + NEWLINE;
167185
includeHeaderPart += include.getSource() + NEWLINE;
168-
includeHeaderPart += "}" + NEWLINE; //$NON-NLS-1$
186+
includeHeaderPart += "}" + NEWLINE;
169187
} else {
170188
includeHeaderPart += include.getSource();
171189
includeHeaderPart += NEWLINE;
172190
}
173-
174191
}
175-
176192
}
177193
}
178194
}
@@ -190,7 +206,7 @@ public static void processProject(IProject iProject) throws CoreException {
190206
// concatenate the parts and make the .ino.cpp file
191207
String output = header + includeHeaderPart + body + includeCodePart;
192208
// Make sure the file is not procesed by Arduino IDE
193-
output = "#ifdef " + DEFINE_IN_ECLIPSE + NEWLINE + output + NEWLINE + "#endif" + NEWLINE; //$NON-NLS-1$ //$NON-NLS-2$
209+
output = "#ifdef " + DEFINE_IN_ECLIPSE + NEWLINE + output + NEWLINE + "#endif" + NEWLINE;
194210
Helpers.addFileToProject(iProject, new Path(tempFile), new ByteArrayInputStream(output.getBytes()),
195211
null, true);
196212
}

0 commit comments

Comments
 (0)