22
22
import java .io .ByteArrayInputStream ;
23
23
import java .text .SimpleDateFormat ;
24
24
import java .util .Date ;
25
+ import java .util .HashMap ;
25
26
import java .util .List ;
26
27
27
28
import org .eclipse .cdt .core .CCorePlugin ;
29
+ import org .eclipse .cdt .core .dom .ast .IASTDeclaration ;
28
30
import org .eclipse .cdt .core .dom .ast .IASTNode ;
29
31
import org .eclipse .cdt .core .dom .ast .IASTTranslationUnit ;
32
+ import org .eclipse .cdt .core .dom .ast .cpp .ICPPASTLinkageSpecification ;
30
33
import org .eclipse .cdt .core .index .IIndex ;
31
34
import org .eclipse .cdt .core .model .CoreModel ;
32
35
import org .eclipse .cdt .core .model .ICElement ;
43
46
import org .eclipse .core .runtime .IPath ;
44
47
import org .eclipse .core .runtime .Path ;
45
48
46
- import io .sloeber .common .Const ;
47
-
48
- @ SuppressWarnings ("restriction" )
49
+ @ SuppressWarnings ({ "nls" , "restriction" })
49
50
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__" ;
52
53
53
54
public static void processProject (IProject iProject ) throws CoreException {
54
55
// first write some standard bla bla
55
- final String NEWLINE = Const . NEWLINE ;
56
+ final String NEWLINE = " \n " ;
56
57
String body = new String ();
57
- String includeHeaderPart = "#include \" Arduino.h\" " + NEWLINE ; //$NON-NLS-1$
58
+ String includeHeaderPart = "#include \" Arduino.h\" " + NEWLINE ;
58
59
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 ());
64
65
header += NEWLINE ;
65
66
header += NEWLINE ;
66
67
ICProject tt = CoreModel .getDefault ().create (iProject );
@@ -76,23 +77,23 @@ public static void processProject(IProject iProject) throws CoreException {
76
77
}
77
78
78
79
// take all the files in the project
79
- IResource allResources [] = iProject .members (0 );// .getFolder("").members(0);
80
+ IResource allResources [] = iProject .members (0 );
80
81
int numInoFiles = 0 ;
81
82
for (IResource curResource : allResources ) {
82
83
String extension = curResource .getFileExtension ();
83
84
// 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" )))) {
85
86
numInoFiles ++;
86
87
String addLine ;
87
88
if (curResource .isLinked ()) {
88
- addLine = "#include \" " + curResource .getLocation () + "\" " + NEWLINE ; //$NON-NLS-1$ //$NON-NLS-2$
89
+ addLine = "#include \" " + curResource .getLocation () + "\" " + NEWLINE ;
89
90
} else {
90
- addLine = "#include \" " + curResource .getName () + "\" " + NEWLINE ; //$NON-NLS-1$ //$NON-NLS-2$
91
+ addLine = "#include \" " + curResource .getName () + "\" " + NEWLINE ;
91
92
}
92
93
// if the name of the ino/pde file matches the project put
93
94
// the file in front
94
95
// 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 )) {
96
97
includeCodePart = addLine + includeCodePart ;
97
98
} else {
98
99
includeCodePart += addLine ;
@@ -107,12 +108,11 @@ public static void processProject(IProject iProject) throws CoreException {
107
108
// the indexer is not properly configured so drop a
108
109
// error in the file
109
110
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."
114
114
+ 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."
116
116
+ NEWLINE ;
117
117
} else {
118
118
// add declarations made in ino files.
@@ -122,12 +122,12 @@ public static void processProject(IProject iProject) throws CoreException {
122
122
for (IASTNode astNode : astNodes ) {
123
123
if (astNode instanceof CPPASTFunctionDefinition ) {
124
124
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 ("::" )) {
131
131
// ignore when there are assignments in the
132
132
// declaration
133
133
// or when it is a class function
@@ -138,9 +138,30 @@ public static void processProject(IProject iProject) throws CoreException {
138
138
}
139
139
}
140
140
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
+
141
163
// find all the macro's
142
164
List <ICElement > theMacros = tu .getChildrenOfType (ICElement .C_MACRO );
143
- String fileContent = new String (tu .getContents ());
144
165
145
166
// list all includes found in the source files.
146
167
IInclude includes [] = tu .getIncludes ();
@@ -155,24 +176,19 @@ public static void processProject(IProject iProject) throws CoreException {
155
176
156
177
if ((curMacroLine < curHeaderLine ) && (prefHeaderLine < curMacroLine )) {
157
178
includeHeaderPart += curMacro .getSource () + NEWLINE ;
158
-
159
179
}
160
180
}
161
181
162
182
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 ;
167
185
includeHeaderPart += include .getSource () + NEWLINE ;
168
- includeHeaderPart += "}" + NEWLINE ; //$NON-NLS-1$
186
+ includeHeaderPart += "}" + NEWLINE ;
169
187
} else {
170
188
includeHeaderPart += include .getSource ();
171
189
includeHeaderPart += NEWLINE ;
172
190
}
173
-
174
191
}
175
-
176
192
}
177
193
}
178
194
}
@@ -190,7 +206,7 @@ public static void processProject(IProject iProject) throws CoreException {
190
206
// concatenate the parts and make the .ino.cpp file
191
207
String output = header + includeHeaderPart + body + includeCodePart ;
192
208
// 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 ;
194
210
Helpers .addFileToProject (iProject , new Path (tempFile ), new ByteArrayInputStream (output .getBytes ()),
195
211
null , true );
196
212
}
0 commit comments